{"_id":"@capitalthought/anthropic","_rev":"6-3d132b31a59fab47e3ad2d48e549aa70","name":"@capitalthought/anthropic","dist-tags":{"latest":"0.4.0"},"versions":{"0.1.0":{"name":"@capitalthought/anthropic","version":"0.1.0","license":"UNLICENSED","_id":"@capitalthought/anthropic@0.1.0","maintainers":[{"name":"joshuabaer","email":"npmjs@joshspam.com"}],"homepage":"https://github.com/capitalthought/anthropic#readme","bugs":{"url":"https://github.com/capitalthought/anthropic/issues"},"dist":{"shasum":"9aaf196a272e981fb8df6ca1f7450fcdb7d20510","tarball":"https://registry.npmjs.org/@capitalthought/anthropic/-/anthropic-0.1.0.tgz","fileCount":31,"integrity":"sha512-PR5yf2U16g5KaDGyAh+fjI42IEJNw/cjEQyyoOsiNv1glDUrvEZc1sfDW4V58+E6bGNLN7u9MDJ9B+fjUWO0jA==","signatures":[{"sig":"MEUCIQDo/QlI8c2jb/R0lIB8J4p4RFP+lwXfG2lafMsFvUlBeQIgNVfRt3eBHwnqGc+Otg+r8F1aG7ZdJUe36lDve2oPDj4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":64023},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./adapters/kv":{"types":"./dist/adapters/kv.d.ts","import":"./dist/adapters/kv.js"},"./eslint-rules":{"require":"./eslint-rules/index.cjs"},"./adapters/memory":{"types":"./dist/adapters/memory.d.ts","import":"./dist/adapters/memory.js"},"./adapters/postgres":{"types":"./dist/adapters/postgres.d.ts","import":"./dist/adapters/postgres.js"}},"gitHead":"6a68d81d0d650edf560cd4212501e8a044ef57fe","scripts":{"test":"vitest run","build":"tsc","check":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"joshuabaer","email":"npmjs@joshspam.com"},"repository":{"url":"git+ssh://git@github.com/capitalthought/anthropic.git","type":"git"},"_npmVersion":"11.12.1","description":"Shared Anthropic SDK wrapper for Capital Thought projects — model registry, cost cap, agent harness, storage-adapter pattern.","directories":{},"_nodeVersion":"25.9.0","dependencies":{"@anthropic-ai/sdk":"^0.39.0"},"publishConfig":{"access":"restricted"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^10.3.0","vitest":"^2.0.0","typescript":"^5.6.0","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/anthropic_0.1.0_1777830035798_0.24561183348049442","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@capitalthought/anthropic","version":"0.2.0","license":"UNLICENSED","_id":"@capitalthought/anthropic@0.2.0","maintainers":[{"name":"joshuabaer","email":"npmjs@joshspam.com"}],"homepage":"https://github.com/capitalthought/anthropic#readme","bugs":{"url":"https://github.com/capitalthought/anthropic/issues"},"dist":{"shasum":"1c0658eff64dc5c061c22e96decec97d794b33a4","tarball":"https://registry.npmjs.org/@capitalthought/anthropic/-/anthropic-0.2.0.tgz","fileCount":31,"integrity":"sha512-hJIvoVsZrbQgHg32bghnYJizvYwMNE7nqAK6C/ba9o1M3NZTWNWekD58ihGB+HItNJWQ+W9Xq3myuvkCLIR97w==","signatures":[{"sig":"MEQCIAnxDKDyz7v97g2xO+RHTn95JgmTyiRsSSqrjr6NsemWAiBAXqAZ4ahDm+liC67uREuAPOuAl2QdF2oli+Mb0cByZg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":74396},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./adapters/kv":{"types":"./dist/adapters/kv.d.ts","import":"./dist/adapters/kv.js"},"./eslint-rules":{"require":"./eslint-rules/index.cjs"},"./adapters/memory":{"types":"./dist/adapters/memory.d.ts","import":"./dist/adapters/memory.js"},"./adapters/postgres":{"types":"./dist/adapters/postgres.d.ts","import":"./dist/adapters/postgres.js"}},"gitHead":"376d81cc5219cf6a6ad8a10bf43b966149898733","scripts":{"test":"vitest run","build":"tsc","check":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"joshuabaer","email":"npmjs@joshspam.com"},"repository":{"url":"git+ssh://git@github.com/capitalthought/anthropic.git","type":"git"},"_npmVersion":"11.12.1","description":"Shared Anthropic SDK wrapper for Capital Thought projects — model registry, cost cap, agent harness, storage-adapter pattern.","directories":{},"_nodeVersion":"25.9.0","dependencies":{"@anthropic-ai/sdk":"^0.39.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^10.3.0","vitest":"^2.0.0","typescript":"^5.6.0","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/anthropic_0.2.0_1777831886458_0.644824180686842","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@capitalthought/anthropic","version":"0.2.1","license":"UNLICENSED","_id":"@capitalthought/anthropic@0.2.1","maintainers":[{"name":"joshuabaer","email":"npmjs@joshspam.com"}],"homepage":"https://github.com/capitalthought/anthropic#readme","bugs":{"url":"https://github.com/capitalthought/anthropic/issues"},"dist":{"shasum":"4c405633ac2d969bb50597f4c8d6da98be751218","tarball":"https://registry.npmjs.org/@capitalthought/anthropic/-/anthropic-0.2.1.tgz","fileCount":31,"integrity":"sha512-Q6vZrULvaEw3GpEmyY3ausBfRedmMyMxEYlnWf6c2uAWyiWojqBIit5Im8Rnkt+pkV9QzwTM33F4sOqcPIL4nA==","signatures":[{"sig":"MEYCIQC8clGiDAf74zTHIxy1jScJ3HXJsDrIVrz1/o9S6yp2hwIhAI5ae9w7qEmP/fgGd59Lulf9QRrkegdI57+VCCKYRE0T","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":75407},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./adapters/kv":{"types":"./dist/adapters/kv.d.ts","import":"./dist/adapters/kv.js"},"./eslint-rules":{"require":"./eslint-rules/index.cjs"},"./adapters/memory":{"types":"./dist/adapters/memory.d.ts","import":"./dist/adapters/memory.js"},"./adapters/postgres":{"types":"./dist/adapters/postgres.d.ts","import":"./dist/adapters/postgres.js"}},"gitHead":"3e04ddc50987946038d95234f32b31b857d8e318","scripts":{"test":"vitest run","build":"tsc","check":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"joshuabaer","email":"npmjs@joshspam.com"},"repository":{"url":"git+ssh://git@github.com/capitalthought/anthropic.git","type":"git"},"_npmVersion":"11.12.1","description":"Shared Anthropic SDK wrapper for Capital Thought projects — model registry, cost cap, agent harness, storage-adapter pattern.","directories":{},"_nodeVersion":"25.9.0","dependencies":{"@anthropic-ai/sdk":"^0.39.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^10.3.0","vitest":"^2.0.0","typescript":"^5.6.0","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/anthropic_0.2.1_1777832294645_0.06308927524013197","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@capitalthought/anthropic","version":"0.3.0","license":"UNLICENSED","_id":"@capitalthought/anthropic@0.3.0","maintainers":[{"name":"joshuabaer","email":"npmjs@joshspam.com"}],"homepage":"https://github.com/capitalthought/anthropic#readme","bugs":{"url":"https://github.com/capitalthought/anthropic/issues"},"dist":{"shasum":"e4fcce6f45977444783f5545512e2320123cedfb","tarball":"https://registry.npmjs.org/@capitalthought/anthropic/-/anthropic-0.3.0.tgz","fileCount":31,"integrity":"sha512-dO1YKmxQAGXyMj5jhxCCEobLxHuRgYHQBqCAifcfiIejZI3NVrzZC++1G6wqINErkDCFj0jQ8diriYbZ8G0qWg==","signatures":[{"sig":"MEUCIEIubbjZRa+5NumW4XG/4jYuzavUhx10ak7Y8ind6P6qAiEA782wxdsMq4rRsyVm6jkc3K4i0kmMebgD+AN/tPPxTrA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":81608},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./adapters/kv":{"types":"./dist/adapters/kv.d.ts","import":"./dist/adapters/kv.js"},"./eslint-rules":{"require":"./eslint-rules/index.cjs"},"./adapters/memory":{"types":"./dist/adapters/memory.d.ts","import":"./dist/adapters/memory.js"},"./adapters/postgres":{"types":"./dist/adapters/postgres.d.ts","import":"./dist/adapters/postgres.js"}},"gitHead":"dcc02228c75a9301a8ebcea5016596644533f736","scripts":{"test":"vitest run","build":"tsc","check":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"joshuabaer","email":"npmjs@joshspam.com"},"repository":{"url":"git+ssh://git@github.com/capitalthought/anthropic.git","type":"git"},"_npmVersion":"11.12.1","description":"Shared Anthropic SDK wrapper for Capital Thought projects — model registry, cost cap, agent harness, storage-adapter pattern.","directories":{},"_nodeVersion":"25.9.0","dependencies":{"@anthropic-ai/sdk":"^0.39.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^10.3.0","vitest":"^2.0.0","typescript":"^5.6.0","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/anthropic_0.3.0_1778377160644_0.78785943981844","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@capitalthought/anthropic","version":"0.4.0","description":"Shared Anthropic SDK wrapper for Capital Thought projects — model registry, cost cap, agent harness, storage-adapter pattern.","license":"UNLICENSED","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"import":"./dist/index.js","types":"./dist/index.d.ts"},"./adapters/memory":{"import":"./dist/adapters/memory.js","types":"./dist/adapters/memory.d.ts"},"./adapters/postgres":{"import":"./dist/adapters/postgres.js","types":"./dist/adapters/postgres.d.ts"},"./adapters/kv":{"import":"./dist/adapters/kv.js","types":"./dist/adapters/kv.d.ts"},"./eslint-rules":{"require":"./eslint-rules/index.cjs"}},"scripts":{"build":"tsc","check":"tsc --noEmit","test":"vitest run","test:watch":"vitest"},"engines":{"node":">=20"},"dependencies":{"@anthropic-ai/sdk":"^0.39.0"},"devDependencies":{"@types/node":"^22.0.0","eslint":"^10.3.0","typescript":"^5.6.0","vitest":"^2.0.0"},"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+ssh://git@github.com/capitalthought/anthropic.git"},"gitHead":"73cbe381e81ccbee3e892022c6003cba68df8a5a","_id":"@capitalthought/anthropic@0.4.0","bugs":{"url":"https://github.com/capitalthought/anthropic/issues"},"homepage":"https://github.com/capitalthought/anthropic#readme","_nodeVersion":"26.0.0","_npmVersion":"11.12.1","dist":{"integrity":"sha512-k8+xBgl4N7Lkr7Axzo7BXkPt4SyOV9z3A313FTAvs9x+FjPJMJv3xs2ZCv+17braci/AM0ADxYa/D12H2mZUvg==","shasum":"f496ff29c32a1e91cb0c61df067bd870f720b18f","tarball":"https://registry.npmjs.org/@capitalthought/anthropic/-/anthropic-0.4.0.tgz","fileCount":31,"unpackedSize":81838,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQD9+jm7z0R7linQ+/fGk6l11iOZ1U1JtnVc6dM1xJvT4gIhAKTdLIiatbtP/9j8Nq+ANBtBRyMIe7H8v5nZvy5e0qhU"}]},"_npmUser":{"name":"joshuabaer","email":"npmjs@joshspam.com"},"directories":{},"maintainers":[{"name":"joshuabaer","email":"npmjs@joshspam.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/anthropic_0.4.0_1780328701748_0.6063060336886414"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-03T17:40:35.424Z","modified":"2026-06-01T15:45:01.985Z","0.1.0":"2026-05-03T17:40:35.928Z","0.2.0":"2026-05-03T18:11:26.598Z","0.2.1":"2026-05-03T18:18:14.797Z","0.3.0":"2026-05-10T01:39:20.839Z","0.4.0":"2026-06-01T15:45:01.879Z"},"bugs":{"url":"https://github.com/capitalthought/anthropic/issues"},"license":"UNLICENSED","homepage":"https://github.com/capitalthought/anthropic#readme","repository":{"type":"git","url":"git+ssh://git@github.com/capitalthought/anthropic.git"},"description":"Shared Anthropic SDK wrapper for Capital Thought projects — model registry, cost cap, agent harness, storage-adapter pattern.","maintainers":[{"name":"joshuabaer","email":"npmjs@joshspam.com"}],"readme":"# @capitalthought/anthropic\n\nShared Anthropic SDK wrapper for Capital Thought projects — model registry, cost cap, agent harness, storage-adapter pattern.\n\n## Why\n\nAcross the portfolio, the Anthropic SDK is currently wrapped (badly) in four different places. Each wrap is missing different parts of the playbook:\n\n| Repo | Has | Missing |\n|---|---|---|\n| `pitch2` | Cost tracker (`enforceAiCap` / `recordAiUsage`); tool-use agent harness; model registry | n/a — canonical impl |\n| `mikey` | Model registry (just shipped) + health check | Cost cap, agent harness |\n| `highfives` | Model registry + health check | Cost cap, agent harness |\n| `multipov`, `bpm`, `actualjob`, `doorman`, `personalize`, … | n/a | Bare `new Anthropic()` calls — no wrapper, no cost cap, no model registry |\n\nThis package consolidates the canonical patterns and exposes them via a storage-agnostic interface. Workers consumers and Vercel/Node consumers use the same API; the storage adapter at the seam is the only thing that differs per runtime.\n\n## Phase 1 — what's in this commit\n\nStubs + contracts + a working in-memory adapter for tests. No consumer changes yet. This phase commits zero runtime risk.\n\n| Module | Status |\n|---|---|\n| `models.ts` — `CLAUDE_MODELS` registry, `extendModels`, `getModel` | ✅ shipped |\n| `health.ts` — `checkClaudeModels()` health probe | ✅ shipped |\n| `cost-tracker.ts` — `createCostTracker()` (per-user + global caps) | ✅ shipped |\n| `agent.ts` — `runAgent()` tool-use harness | 🟡 contract defined, impl in Phase 2 |\n| `adapters/memory.ts` — in-memory cost adapter for tests | ✅ shipped |\n| `adapters/postgres.ts` — Postgres cost adapter (Vercel/pitch2) | 🟡 stub; impl in Phase 2 |\n| `adapters/kv.ts` — Cloudflare KV cost adapter (Workers) | 🟡 stub; impl in Phase 3 |\n\n## Migration phases\n\n1. **Phase 1 (this scaffold).** Create the package + contracts + memory adapter + tests. No consumer changes.\n2. **Phase 2.** Lift `pitch2/src/lib/ai-cost-tracker.ts` + `pitch2/src/lib/pitchbot/agent.ts` + `pitch2/src/lib/claude/models.ts` into the package. pitch2 becomes the package's first consumer (just imports from `@capitalthought/anthropic` instead of local files).\n3. **Phase 3.** Port the KV adapter for Workers. Migrate `mikey` to the package (drops `mikey/src/shared/claude-models.ts`, gains `enforceAiCap` for free → closes mikey's security review High #6 finding).\n4. **Phase 4.** Migrate `highfives`, `multipov`, `bpm`, `doorman`, `personalize`, etc.\n\nEach phase is a separate PR. Each consumer migrates on its own timeline.\n\n## Design decisions (2026-05-03)\n\n### Multi-tenant scoping (optional `orgId` — added 0.3.0)\n\nEvery cost bucket can optionally be scoped to a tenant identifier. Pass `orgId` on `recordAiUsage` and `enforceAiCap` so a user shared across two orgs (e.g. a fractional COO with one email in two tenants) gets isolated counters per tenant. Omit `orgId` and the historical per-user shape is preserved unchanged.\n\n```ts\nawait costs.recordAiUsage({\n  userId: \"user@example.com\",\n  orgId: \"org-uuid\",          // ← new, optional\n  route: \"responder\",\n  model: MIKEY_MODELS.RESPONDER,\n  inputTokens: 100,\n  outputTokens: 200,\n});\n\nconst cap = await costs.enforceAiCap({\n  userId: \"user@example.com\",\n  orgId: \"org-uuid\",          // ← new, optional; pair with orgId above\n  route: \"responder\",\n});\n```\n\nKV bucket shape becomes `<prefix>:<orgId>:<userId>:<YYYY-MM-DD>` when `orgId` is supplied. The Postgres adapter currently ignores `orgId` — pitch2 is single-tenant; multi-tenant Postgres consumers should add an `org_id text` column and PR a similar threading through `record()`'s insert + the two select predicates.\n\n### Per-app caps, not global cross-app\n\nPer-app caps for v1 — each consumer plugs in its own storage adapter and gets its own `$5/user-day`, `$50/user-month`, `$1000/day-app` ceiling. The \"shared cap across all apps\" benefit (a single `$1k/day-company` ceiling that applies to every app's calls combined) is deferred until any single app exhausts its per-app ceiling at scale — none do today.\n\nIf we ever need cross-app aggregation, the adapter pattern lets us point multiple consumers at one storage backend. The contract doesn't change.\n\n### Storage-adapter pattern\n\nThe package itself is storage-agnostic. Cost tracker requires a `CostStorageAdapter` at construction time — the adapter handles `record`, `perUserTotals`, `globalTotals`. Workers consumers wire up the KV adapter; Vercel/Postgres consumers wire up the Postgres adapter; tests use the in-memory adapter. Same package code runs everywhere.\n\n### Configurable agent caps with safe-by-default floors\n\n`runAgent()` defaults to **4 tool calls / 20s wall / 800 output tokens**. Each consumer can override (e.g. `mikey`'s responder might want `maxToolCalls: 0` = single-shot, no agent loop, while `pitchbot` runs the full 4-tool loop). Defaults set the safe-by-default floor; overrides are for when you genuinely know better.\n\n### Model registry pinning\n\n`HAIKU` is pinned to the dated snapshot (`claude-haiku-4-5-20251001`) per `~/icloud/Claude/Model Version Management.md`. The unpinned alias (`claude-haiku-4-5`) returns the latest snapshot which can shift between deploys. Test enforces this at `src/__tests__/models.test.ts`.\n\n`OPUS` and `SONNET` use the major.minor aliases (`claude-opus-4-7`, `claude-sonnet-4-6`) because Anthropic doesn't ship snapshot variants for them at present. Revisit if/when they do.\n\n## Usage (once Phase 2 lands)\n\n```ts\nimport {\n  CLAUDE_MODELS,\n  createCostTracker,\n  runAgent,\n  extendModels,\n} from \"@capitalthought/anthropic\";\nimport { createMemoryAdapter } from \"@capitalthought/anthropic/adapters/memory\";\nimport Anthropic from \"@anthropic-ai/sdk\";\n\nconst MIKEY_MODELS = extendModels({\n  CLASSIFIER: CLAUDE_MODELS.HAIKU,\n  RESPONDER: CLAUDE_MODELS.SONNET,\n});\n\nconst costs = createCostTracker({\n  adapter: createMemoryAdapter(), // or KV / Postgres in real consumers\n  // defaults: $5/user-day, $50/user-month, $1000/day-app\n});\n\nconst cap = await costs.enforceAiCap({ userId: \"u1\", route: \"responder\" });\nif (!cap.allowed) {\n  // bail with cap.reason: \"per_user_daily\" | \"per_user_monthly\" | \"global_daily_cap\"\n}\n\n// ... call Anthropic ...\n\nawait costs.recordAiUsage({\n  userId: \"u1\",\n  route: \"responder\",\n  model: MIKEY_MODELS.RESPONDER,\n  inputTokens: response.usage.input_tokens,\n  outputTokens: response.usage.output_tokens,\n});\n```\n\n## Scripts\n\n```bash\nnpm run check    # tsc --noEmit\nnpm run build    # tsc → dist/\nnpm run test     # vitest run\n```\n\n## Related\n\n- `~/icloud/Claude/Model Version Management.md` — pinning playbook\n- `pitch2/src/lib/ai-cost-tracker.ts` — canonical cost-tracker impl (lift target for Phase 2)\n- `pitch2/src/lib/pitchbot/agent.ts` — canonical tool-use agent harness (lift target for Phase 2)\n- `mikey/src/shared/claude-models.ts` — first port of the model registry pattern (drops in Phase 3)\n","readmeFilename":"README.md"}