Developers · Go SDK + CLI
One-line AgentSmack from Go, GitHub Actions, or any CI pipeline.
go install …/cmd/agentsmack ships the typed client + standalone CLI in one repo. Wire-compatible with the TypeScript SDK and the Python SDK — same shapes, same verb names, same exit codes. Swap languages without changing your pipeline.
Install
# cli binary
go install github.com/shivemind/agentsmack/packages/sdk-go/cmd/agentsmack@latest
# library
go get github.com/shivemind/agentsmack/packages/sdk-go@latest
# homebrew (planned)
brew install shivemind/tap/agentsmack # planned
Go 1.22+. Tested against 1.22 - 1.26 on Linux, macOS, and Windows. Ships cmd/agentsmack as the CLI entry point and the top-level package as the library.
What it gives you
agentsmack.Client
Wraps POST /api/submissions + GET /api/submissions/[slug] with typed Go structs, header injection, and polling. No interface{} at the boundary.
Three submission modes
Structured paste, raw text (any of JSON/YAML/Markdown), or a public URL — populate AnalyzeRequest.SystemPrompt / Text / URL respectively.
Offline pack verification
Pure-Go crypto/ed25519 + content-address re-derivation. Cross-language deterministic — a pack signed by the TS or Python SDK verifies in Go byte-for-byte (and vice versa).
CI/CD friendly
`agentsmack analyze --wait --fail-on critical` returns non-zero so your pipeline fails the build on triggered probes. Same exit codes as the TS + Python CLIs.
Deterministic
Injectable http.RoundTripper + injectable polling Sleep. Pin the SDK in your replay tests — same input, same call sequence, byte-for-byte.
Type-safe
Typed errors (HTTPError, NetworkError, PollingTimeoutError, FindingsExceededError) with `errors.As`. `go vet ./...` clean. ed25519 verify is constant-time per the stdlib contract.
SDK quickstart
package main
import (
"context"
"fmt"
"os"
agentsmack "github.com/shivemind/agentsmack/packages/sdk-go"
)
func main() {
c := agentsmack.NewClient(os.Getenv("AGENTSMACK_API_KEY"), "")
// (api key is optional — anonymous submissions are allowed.)
ctx := context.Background()
result, err := c.Analyze(ctx, agentsmack.AnalyzeRequest{
SystemPrompt: "You are a helpful assistant.",
ToolList: []agentsmack.ToolDefinition{
{Name: "search_web", Description: "Search the web"},
},
Model: "gpt-4o",
})
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
fmt.Println(result.PublicReportURL)
// Block until honeypot + underground probes finish:
final, err := c.WaitForCompletion(ctx, result.PublicSlug, agentsmack.PollingOptions{})
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
fmt.Printf("honeypot blocked: %d/%d\n",
final.Probes.Honeypot.Blocked, final.Probes.Honeypot.Total)
}Fail the build on findings
Client.AnalyzeAndWait returns a typed *FindingsExceededError when any honeypot triggers or underground probe breaches at the chosen severity. Drop it into your CI step and the pipeline fails for you.
package main
import (
"context"
"errors"
"fmt"
"os"
agentsmack "github.com/shivemind/agentsmack/packages/sdk-go"
)
func main() {
c := agentsmack.NewClient("", "")
_, err := c.AnalyzeAndWait(context.Background(), agentsmack.AnalyzeAndWaitOptions{
Request: agentsmack.AnalyzeRequest{SystemPrompt: "..."},
Wait: true,
FailOn: agentsmack.SeverityHigh,
})
var findingsErr *agentsmack.FindingsExceededError
if errors.As(err, &findingsErr) {
fmt.Fprintf(os.Stderr, "Triggered %d probe(s) at %s\n",
findingsErr.TriggeredCount, findingsErr.Threshold)
os.Exit(1)
}
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}Offline pack verification
Every paid-tier submission produces a signed governance pack (content-addressed packId + Ed25519 signature). The Go verifier is cross-language deterministic — a pack signed by the TS or Python SDK verifies in Go and vice versa, byte-for-byte. The cross-language anchor lives at packages/sdk-go/tests/cross_language_pin_test.go.
package main
import (
"fmt"
"os"
agentsmack "github.com/shivemind/agentsmack/packages/sdk-go"
)
func main() {
packBytes, _ := os.ReadFile("pack.json")
sigHex, _ := os.ReadFile("pack.sig")
pubHex, _ := os.ReadFile("workspace.pub")
verdict := agentsmack.VerifyPack(agentsmack.VerifyPackInput{
PackJSON: packBytes,
SignatureHex: string(sigHex),
PublicKeyHex: string(pubHex),
})
if !verdict.Valid {
fmt.Fprintf(os.Stderr, "AgentSmack pack invalid: %s\n", verdict.Reason)
os.Exit(1)
}
fmt.Println(verdict.PackID, verdict.BundleDigest)
}CLI
Same module, single static binary. The exit-code matrix matches the TS + Python CLIs exactly so a pipeline switching languages keeps the same gating logic. Credentials live in the same ~/.agentsmack/config.json file — log in once with any SDK, use all three.
Login
agentsmack login --api-key "$AGENTSMACK_API_KEY"Analyze a local file
agentsmack analyze ./agent.jsonCI/CD — fail the build
agentsmack analyze ./agent.json \
--wait --fail-on highRead from stdin
cat .cursorrules | agentsmack analyze -Verify a downloaded governance pack
agentsmack verify ./pack.json \
--signature-file ./pack.sig \
--public-key-file ./workspace.pubNext
- /developers/sdk — same SDK in TypeScript / Node. Wire-compatible with this one.
- /developers/sdk-python — same SDK in Python. Wire-compatible with this one.
- /developers/mcp — register AgentSmack as an MCP server in Claude Desktop / Cursor.
- /pricing — Pro-tier features include signed governance packs and the full honeypot battery.