File DA-005 View as Markdown
CLI
npx @doubleagent-so/cli init # keyless install, prints the claim URL
npx @doubleagent-so/cli init --email you@company.com # create account + site, install its pk
npx @doubleagent-so/cli init --key pk_live_xxx # install with an existing public key
npx @doubleagent-so/cli init --yes --json # for coding agents
npx @doubleagent-so/cli verify https://SITE [--api <origin>] [--json]
npx @doubleagent-so/cli login | logout [--all]
npx @doubleagent-so/cli sites
npx @doubleagent-so/cli keys [list|create|rotate|revoke] [key_id] [--site st_…] [--kind pk|sk] [--env live|test]
npx @doubleagent-so/cli verify-domain shop.example.com --method dns|meta|file|script [--site st_…]
Node 18+, no runtime dependencies. npm package: doubleagent.
init
| Flag | |
|---|---|
| none | Keyless. Prints Installed without a key. Claim <domain> at https://app.doubleagent.so/claim?domain=<domain> to see the data (everything collected until then is kept). Domain from --domain, package.json homepage or CNAME. --portal or $DOUBLEAGENT_PORTAL changes the portal. |
--key pk_… | Adds data-key; re-running on a keyless install adds it in place. sk_… is refused. |
--email you@x.com [--domain] [--name] [--test] | POST /v1/accounts, solves the proof-of-work, installs the pk, prints sk_test once |
--profile, --cwd, --dry-run, --yes/-y, --json | As named. --dry-run never creates an account. |
| Stack | Where the snippet goes |
|---|---|
| Next.js App Router | app/layout.* (next/script) |
| Next.js Pages Router | pages/_document.* <Head>, created if missing |
| Vite, React, Vue (Lovable, Bolt, v0) | index.html <head> |
| Static HTML | Every root *.html, or public/index.html |
| Astro | src/layouts/*.astro, is:inline |
| Nuxt | nuxt.config app.head.script, or plugins/doubleagent.client.* |
| SvelteKit | src/app.html, before %sveltekit.head% |
| Remix / React Router | app/root.* <head> |
| WordPress theme | header.php, before wp_head() |
| Shopify theme | No edits. Use the app embed. |
{ "stack": "next-app", "status": "install", "dry_run": false, "keyless": true, "key": null,
"domain": "shop.example.com", "claim_url": "https://app.doubleagent.so/claim?domain=shop.example.com",
"account": null, "files_changed": ["app/layout.tsx"], "integrations": ["ga4"], "next_steps": ["…"], "diff": "…" }
Exit codes: 0 ok, 1 error or aborted, 2 unsupported stack.
login, sites, keys, verify-domain
loginuses the device flow: approve the code atapp.doubleagent.so/device. Credentials go to~/.config/doubleagent/credentials.json(mode 0600).sites,keysandverify-domaintake--json.keysdefaults to your only site and prints a new or rotatedskonce.verify-domainadds the domain if needed, verifies it, prints the claimed session count; otherwise prints what to publish and exits1.
verify
Checks the server HTML for the script, the stub and (optional) key, then calls GET /v1/install-check. A keyless script passes. Exit 0 only if all pass.