@inneranimalmedia/agentsam-sdk 2.6.3 → 2.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (233) hide show
  1. package/AGENTSAM.md +6 -0
  2. package/README.md +16 -1
  3. package/bin/agentsam +16 -1
  4. package/docs/BRAND_INTELLIGENCE.md +1 -1
  5. package/docs/architecture/AGENTSAM_DISTRIBUTION_OWNERSHIP.md +176 -0
  6. package/docs/architecture/AGENTSAM_GO_RUNTIME.md +282 -0
  7. package/docs/architecture/CODEBASEINDEX_GUIDED_PATH.md +202 -0
  8. package/docs/architecture/FS_E2E_CLOSURE_RECEIPT.md +59 -0
  9. package/docs/architecture/LOCAL_FS_AUTHORITY.md +38 -0
  10. package/docs/architecture/LOCAL_STUDIO_CLOUDFLARE_OAUTH.md +28 -0
  11. package/docs/architecture/PLAN_CLI_AND_LOCAL_STUDIO_DESKTOP.md +96 -0
  12. package/docs/architecture/SAM_ACTIVITY_RECOVERY_RECEIPT.md +39 -0
  13. package/docs/architecture/SAM_DECISION_WORK_RECEIPT.md +54 -0
  14. package/docs/architecture/SAM_KERNEL.md +181 -0
  15. package/docs/architecture/SAM_MACHINE_NORMALIZATION_PRECOMMIT_REPORT.md +208 -0
  16. package/docs/architecture/SLASH_SKILLS_PORTABLE.md +116 -0
  17. package/docs/architecture/fs-e2e-receipt.latest.json +42 -0
  18. package/docs/architecture/previews/codebaseindex-guided-path/CODEBASEINDEX_GUIDED_PATH.md +202 -0
  19. package/docs/architecture/previews/codebaseindex-guided-path/index.html +321 -0
  20. package/migrations/d1/0010_portable_tickets_memory.sql +140 -0
  21. package/migrations/d1/0011_agentsam_skill_v2.sql +185 -0
  22. package/migrations/d1/0011b_agentsam_skill_v2_cutover.sql +22 -0
  23. package/migrations/d1/0011c_agentsam_skill_v2_backfill.sql +76 -0
  24. package/migrations/d1/0011d_agentsam_skill_v2_retrieval_revisions.sql +50 -0
  25. package/migrations/d1/0012_agentsam_tools_required_seed.sql +67 -0
  26. package/migrations/d1/0013_identity_oauth_states.sql +15 -0
  27. package/migrations/d1/0014_auth_event_log.sql +20 -0
  28. package/migrations/d1/0015_identity_oauth_state_app_id.sql +3 -0
  29. package/migrations/d1/README_PORTABLE_CONTROL_PLANE.md +16 -0
  30. package/migrations/sqlite/agentsam_skill_retrieval.portable.sql +42 -0
  31. package/package.json +19 -4
  32. package/packages/agentsam-contracts/src/errors.ts +16 -0
  33. package/packages/agentsam-errors/src/envelope.js +53 -0
  34. package/packages/agentsam-errors/src/index.js +1 -0
  35. package/packages/agentsam-errors/src/recovery.js +301 -0
  36. package/packages/agentsam-knowledge/src/providers/index.js +18 -6
  37. package/packages/connectors/cloudflare/src/routes.js +9 -0
  38. package/packages/connectors/cloudflare/tests/connector.test.mjs +26 -1
  39. package/packages/identity/.agentsam/features/oauth-login-portal/agentsam.feature.json +1 -1
  40. package/packages/identity/.agentsam/features/oauth-login-portal/routes.json +11 -2
  41. package/packages/identity/docs/PORTABLE_IDENTITY_ARCHITECTURE.md +50 -0
  42. package/packages/identity/migrations/D1_SCHEMA_MAPPING.md +31 -0
  43. package/packages/identity/migrations/sqlite/001_identity_core.sql +99 -0
  44. package/packages/identity/migrations/sqlite/002_identity_oauth_client.sql +38 -0
  45. package/packages/identity/migrations/sqlite/003_identity_oauth_server.sql +64 -0
  46. package/packages/identity/package.json +2 -2
  47. package/packages/identity/src/adapters/cloudflare-d1/index.js +122 -22
  48. package/packages/identity/src/adapters/sqlite/index.js +319 -0
  49. package/packages/identity/src/app/verify-app.js +95 -0
  50. package/packages/identity/src/contracts/identity-store.js +115 -0
  51. package/packages/identity/src/contracts/route-ids.js +30 -0
  52. package/packages/identity/src/contracts/route-projection.js +218 -0
  53. package/packages/identity/src/contracts/routes.js +11 -0
  54. package/packages/identity/src/core/browser-paths.js +4 -5
  55. package/packages/identity/src/core/constants.js +13 -8
  56. package/packages/identity/src/core/session-policy.js +32 -0
  57. package/packages/identity/src/frontend/auth-portal/pages/login.html +10 -10
  58. package/packages/identity/src/frontend/auth-portal/pages/reset.html +3 -3
  59. package/packages/identity/src/frontend/auth-portal/pages/signup.html +3 -3
  60. package/packages/identity/src/frontend/auth-portal/preview/dashboard-stub.html +1 -1
  61. package/packages/identity/src/index.js +25 -0
  62. package/packages/identity/src/oauth/README.md +10 -4
  63. package/packages/identity/src/oauth/credentials.js +20 -13
  64. package/packages/identity/src/oauth/finalize-inbound.js +1 -1
  65. package/packages/identity/src/oauth/iam-platform.js +8 -7
  66. package/packages/identity/src/oauth/redirect-paths.js +27 -36
  67. package/packages/identity/src/server/identity-service.js +30 -13
  68. package/packages/identity/src/server/mount-policy.js +30 -0
  69. package/packages/identity/src/server/post-auth.js +79 -0
  70. package/packages/identity/src/server/worker-router.js +104 -72
  71. package/packages/identity/tests/finalize-inbound-oauth.test.mjs +6 -6
  72. package/packages/identity/tests/iam-provider.test.mjs +1 -1
  73. package/packages/identity/tests/identity-service.test.mjs +36 -5
  74. package/packages/identity/tests/oauth-credentials.test.mjs +3 -1
  75. package/packages/identity/tests/portable-identity-architecture.test.mjs +157 -0
  76. package/packages/identity/tests/session-routes-policy.test.mjs +21 -0
  77. package/packages/theme-church-site/package.json +2 -1
  78. package/packages/theme-church-site/src/index.js +1 -0
  79. package/packages/theme-companions-site/package.json +2 -1
  80. package/packages/theme-companions-site/src/index.js +1 -0
  81. package/packages/theme-floors-site/package.json +2 -1
  82. package/packages/theme-floors-site/src/index.js +1 -0
  83. package/packages/theme-fuelnfree-site/package.json +2 -1
  84. package/packages/theme-fuelnfree-site/src/index.js +1 -0
  85. package/packages/theme-handyman-site/package.json +2 -1
  86. package/packages/theme-handyman-site/src/index.js +1 -0
  87. package/packages/theme-insurance-site/package.json +2 -1
  88. package/packages/theme-insurance-site/src/index.js +1 -0
  89. package/packages/theme-shinshu-site/package.json +2 -1
  90. package/packages/theme-shinshu-site/src/index.js +1 -0
  91. package/protocol/apps/agentsam.app.v1.schema.json +51 -0
  92. package/protocol/brand/brandpack.v1.schema.json +43 -0
  93. package/protocol/credentials/issue.v1.schema.json +38 -0
  94. package/protocol/database/connection.v1.schema.json +41 -0
  95. package/protocol/embeddings/embedding-profile.v1.schema.json +20 -0
  96. package/protocol/errors/error-envelope.schema.json +135 -1
  97. package/protocol/errors/recovery.v1.schema.json +50 -0
  98. package/protocol/runtime/workspace-fs.v1.schema.json +71 -0
  99. package/protocol/sam/activity.v1.schema.json +48 -0
  100. package/protocol/sam/answer.v1.schema.json +35 -0
  101. package/protocol/sam/calibration.v1.schema.json +21 -0
  102. package/protocol/sam/decision-receipt.v1.schema.json +29 -0
  103. package/protocol/sam/evaluation.v1.schema.json +19 -0
  104. package/protocol/sam/operation.schema.json +66 -0
  105. package/protocol/sam/outcome.v1.schema.json +36 -0
  106. package/protocol/sam/question.v1.schema.json +26 -0
  107. package/protocol/sam/registry.seed.json +153 -0
  108. package/protocol/sam/result.schema.json +53 -0
  109. package/protocol/sam/state.v1.schema.json +23 -0
  110. package/protocol/skills/agentsam.interaction.v1.schema.json +50 -0
  111. package/protocol/skills/agentsam.skill.v1.schema.json +57 -0
  112. package/protocol/ui/icon-registry.mjs +226 -0
  113. package/protocol/ui/icon.v1.schema.json +51 -0
  114. package/skills/README.md +22 -9
  115. package/skills/agentsam-codebaseindex/SKILL.md +225 -0
  116. package/skills/catalog.json +14 -0
  117. package/src/cli/command-catalog.js +130 -0
  118. package/src/cli/dispatch.js +48 -0
  119. package/src/cli.js +43 -1
  120. package/src/commands/api-key.js +244 -0
  121. package/src/commands/app.js +60 -28
  122. package/src/commands/brand.js +17 -19
  123. package/src/commands/codebaseindex.js +688 -0
  124. package/src/commands/env.js +152 -25
  125. package/src/commands/go.js +366 -53
  126. package/src/commands/interaction-clack.js +115 -0
  127. package/src/commands/models.js +1 -1
  128. package/src/commands/providers.js +62 -14
  129. package/src/commands/shell.js +43 -2
  130. package/src/commands/skill.js +248 -0
  131. package/src/commands/skills.js +1 -1
  132. package/src/commands/start-local.js +4 -0
  133. package/src/commands/whoami.js +90 -18
  134. package/src/go/build.js +229 -39
  135. package/src/go/cloudflare.js +506 -105
  136. package/src/go/container.js +120 -0
  137. package/src/go/contract.js +9 -4
  138. package/src/go/discover.js +149 -33
  139. package/src/go/index.js +15 -3
  140. package/src/go/native-probe-runner.mjs +119 -0
  141. package/src/go/{registry.js → official-registry.js} +64 -7
  142. package/src/go/official-release.js +10 -0
  143. package/src/go/receipts.js +77 -10
  144. package/src/go/verify.js +9 -2
  145. package/src/index.js +27 -0
  146. package/src/indexing/ingest/discover-models.js +298 -0
  147. package/src/indexing/ingest/inventory.js +243 -0
  148. package/src/indexing/ingest/job-graph.js +181 -0
  149. package/src/indexing/ingest/materials.js +210 -0
  150. package/src/lib/provider-credentials.js +63 -21
  151. package/src/lib/slash-commands.js +1 -0
  152. package/src/local-fs/capability.js +121 -0
  153. package/src/local-fs/freshness.js +75 -0
  154. package/src/local-fs/index.js +385 -0
  155. package/src/local-fs/paths.js +100 -0
  156. package/src/local-pty/server.js +295 -19
  157. package/src/mcp/client.js +2 -2
  158. package/src/models/ai-access-onboarding.js +112 -0
  159. package/src/models/discovery.js +10 -2
  160. package/src/models/inventory-core.js +9 -1
  161. package/src/sam/activity/index.js +183 -0
  162. package/src/sam/client.js +252 -0
  163. package/src/sam/decision/calibration.js +109 -0
  164. package/src/sam/decision/confidence.js +126 -0
  165. package/src/sam/decision/evaluate.js +157 -0
  166. package/src/sam/decision/evaluators/deterministic.js +341 -0
  167. package/src/sam/decision/evaluators/heuristic.js +61 -0
  168. package/src/sam/decision/evaluators/select.js +50 -0
  169. package/src/sam/decision/evaluators/semantic.js +149 -0
  170. package/src/sam/decision/hierarchical.js +61 -0
  171. package/src/sam/decision/index.js +53 -0
  172. package/src/sam/decision/policy.js +86 -0
  173. package/src/sam/decision/questions.js +120 -0
  174. package/src/sam/decision/receipt.js +148 -0
  175. package/src/sam/decision/state.js +117 -0
  176. package/src/sam/decision/types.js +22 -0
  177. package/src/sam/decision/validate.js +200 -0
  178. package/src/sam/define.js +51 -0
  179. package/src/sam/index.js +65 -0
  180. package/src/sam/operations/brand-scan.js +62 -0
  181. package/src/sam/operations/cad-blender-inspect.js +36 -0
  182. package/src/sam/operations/codebaseindex-ingest.js +49 -0
  183. package/src/sam/operations/decision-evaluate.js +59 -0
  184. package/src/sam/operations/planning-astar.js +77 -0
  185. package/src/sam/operations/planning-goap.js +60 -0
  186. package/src/sam/operations/repository-inspect.js +72 -0
  187. package/src/sam/operations/security-scan.js +33 -0
  188. package/src/sam/operations/terminal-exec.js +29 -0
  189. package/src/sam/planning/astar.js +311 -0
  190. package/src/sam/planning/goap.js +177 -0
  191. package/src/sam/planning/index.js +21 -0
  192. package/src/sam/planning/state.js +84 -0
  193. package/src/sam/registry.js +48 -0
  194. package/src/sam/result.js +77 -0
  195. package/src/sam/seed.js +44 -0
  196. package/src/sam/types.js +91 -0
  197. package/src/skills/catalog.js +64 -0
  198. package/src/skills/content-resolver.js +124 -0
  199. package/src/skills/hosted-store.js +37 -0
  200. package/src/skills/index.js +29 -64
  201. package/src/skills/interaction.js +102 -0
  202. package/src/skills/local-store.js +228 -0
  203. package/src/skills/manifest.js +104 -0
  204. package/src/skills/metrics.js +31 -0
  205. package/src/skills/registry.js +184 -0
  206. package/src/skills/runtime.js +287 -0
  207. package/src/skills/slash.js +44 -0
  208. package/src/ui/cli/help.js +94 -101
  209. package/test/cli/api-key-env-whoami.test.mjs +129 -0
  210. package/test/cli/codebaseindex-plan-ux.test.mjs +37 -0
  211. package/test/cli/go.test.mjs +62 -5
  212. package/test/cli/skill-npm-and-env.test.mjs +52 -0
  213. package/test/cli/wireframes-go-registry.test.mjs +87 -2
  214. package/test/go/build-source-identity.test.mjs +31 -0
  215. package/test/go/cloudflare-probe.test.mjs +274 -10
  216. package/test/go/distribution.test.mjs +28 -0
  217. package/test/integration/ai-access-onboarding.test.mjs +47 -0
  218. package/test/integration/cli-help.test.mjs +1 -1
  219. package/test/integration/cms-site-tenancy-contract.test.mjs +6 -6
  220. package/test/integration/codebaseindex-ingest.test.mjs +166 -0
  221. package/test/integration/icon-registry.test.mjs +67 -0
  222. package/test/integration/ingest-discover-models.test.mjs +30 -0
  223. package/test/integration/install-script.test.mjs +12 -9
  224. package/test/integration/local-fs.test.mjs +113 -0
  225. package/test/integration/provider-env-cli.test.mjs +2 -1
  226. package/test/integration/sam-activity-recovery.test.mjs +147 -0
  227. package/test/integration/sam-decision.test.mjs +584 -0
  228. package/test/integration/sam-kernel.test.mjs +99 -0
  229. package/test/integration/sam-planning-astar.test.mjs +279 -0
  230. package/test/integration/skill-runtime.test.mjs +240 -0
  231. package/test/integration/studio-fs-pty-e2e.test.mjs +294 -0
  232. package/test/models.test.mjs +14 -7
  233. package/test/shell.test.mjs +4 -4
@@ -1,16 +1,20 @@
1
1
  import path from 'node:path';
2
- import { cancel, intro, isCancel, outro, select } from '@clack/prompts';
2
+ import { cancel, confirm, intro, isCancel, outro, select } from '@clack/prompts';
3
3
  import pc from 'picocolors';
4
4
  import {
5
5
  DEFAULT_PRODUCT,
6
6
  discoverGoRuntime,
7
7
  resolveProductRoot,
8
+ resolveGoStateRoot,
8
9
  ensureProductContract,
9
10
  preflightToolchain,
10
11
  buildGoProduct,
11
12
  deployGoCloudflare,
13
+ resolveWranglerIdentity,
14
+ verifyGoContainer,
12
15
  verifyGoProduct,
13
16
  readLatestStatus,
17
+ innerAnimalMediaOfficialReleaseEnabled,
14
18
  runGoTests,
15
19
  runGoVet,
16
20
  runGoBuild,
@@ -27,6 +31,9 @@ function parse(argv = []) {
27
31
  dryRun: false,
28
32
  skipDeploy: false,
29
33
  skipRegistry: false,
34
+ accountId: null,
35
+ officialRelease: false,
36
+ yes: false,
30
37
  help: false,
31
38
  positionals: [],
32
39
  };
@@ -38,6 +45,9 @@ function parse(argv = []) {
38
45
  else if (arg === '--dry-run') out.dryRun = true;
39
46
  else if (arg === '--skip-deploy') out.skipDeploy = true;
40
47
  else if (arg === '--skip-registry') out.skipRegistry = true;
48
+ else if (arg === '--official-release') out.officialRelease = true;
49
+ else if (arg === '--yes' || arg === '-y') out.yes = true;
50
+ else if (arg === '--account') out.accountId = String(argv[++i] || '').trim() || null;
41
51
  else if (arg === '--cwd') out.cwd = path.resolve(argv[++i] || out.cwd);
42
52
  else if (arg === '--cloudflare') {
43
53
  out.cloudflare = true;
@@ -72,27 +82,88 @@ function parse(argv = []) {
72
82
 
73
83
  const HELP = `Agent Sam · Go
74
84
 
85
+ Normal AgentSam use does not require deploying this service.
86
+ This command is for maintainers, contributors, and advanced self-hosters.
87
+
75
88
  agentsam go Interactive status / actions (TTY)
76
- agentsam go status [--json] Runtime + product status
89
+ agentsam go status [--json] Runtime + service status
77
90
  agentsam go explore Architecture + operation wireframes (ANSI)
78
- agentsam go inspect [--json] Discover Go source / toolchain
91
+ agentsam go inspect [--json] Discover packaged/development Go source
79
92
  agentsam go test go test ./...
80
- agentsam go build go build + build receipt
93
+ agentsam go build go build + local build receipt
81
94
  agentsam go verify [name] [--json] Local tests + optional live probe
82
- agentsam go --cloudflare [name] Discover → build → validate → deploy → probe → D1 → receipt
95
+ agentsam go --cloudflare [name] Self-host in YOUR explicit Cloudflare account
83
96
  agentsam go deploy [name] --cloudflare
84
97
 
85
- First happy path:
86
- agentsam go --cloudflare agentsam-go-worker
98
+ Self-host dry-run:
99
+ agentsam go --cloudflare agentsam-go-worker --dry-run --account <account-id>
100
+
101
+ Live self-host:
102
+ agentsam go --cloudflare agentsam-go-worker --account <account-id> --yes
103
+
104
+ InnerAnimalMedia official release only:
105
+ AGENTSAM_INNERANIMALMEDIA_OFFICIAL_RELEASE=1 agentsam go --cloudflare agentsam-go-worker --official-release --account <account-id> --yes
87
106
 
88
107
  Flags:
89
- --json Machine-readable output
90
- --dry-run Validate and print plan without deploying
91
- --skip-deploy Build/test/receipt only (no Wrangler deploy)
92
- --skip-registry Skip remote D1 agentsam_products upsert
93
- --cwd <path> Repository root override
108
+ --account <id> Explicit Cloudflare account target
109
+ --yes, -y Confirm a live non-interactive deployment
110
+ --json Machine-readable output
111
+ --dry-run Build/probe + Wrangler dry-run; no live deploy or InnerAnimalMedia registry write
112
+ --skip-deploy Build/test/receipt only
113
+ --skip-registry Official-release escape hatch; self-host is isolated by default
114
+ --official-release InnerAnimalMedia maintainer mode; guarded and never the self-host default
115
+ --cwd <path> Caller project/repository root
94
116
  `;
95
117
 
118
+ function portableStatusPath(value, root) {
119
+ if (!value) return null;
120
+ const absolute = path.resolve(value);
121
+ const base = root ? path.resolve(root) : null;
122
+
123
+ if (base) {
124
+ const rel = path.relative(base, absolute);
125
+ if (
126
+ rel
127
+ && rel !== '..'
128
+ && !rel.startsWith('..' + path.sep)
129
+ && !path.isAbsolute(rel)
130
+ ) {
131
+ return rel.split(path.sep).join('/');
132
+ }
133
+ }
134
+
135
+ return path.basename(absolute);
136
+ }
137
+
138
+ function publicBuildReceipt(receipt) {
139
+ if (!receipt) return null;
140
+ const out = JSON.parse(JSON.stringify(receipt));
141
+
142
+ if (out.probe && 'origin' in out.probe) {
143
+ delete out.probe.origin;
144
+ }
145
+
146
+ return out;
147
+ }
148
+
149
+ function publicBuildResult(result, root) {
150
+ if (!result) return null;
151
+ const out = JSON.parse(JSON.stringify(result));
152
+
153
+ out.receipt = publicBuildReceipt(result.receipt);
154
+ out.receiptPath = portableStatusPath(result.receiptPath, root);
155
+
156
+ if (out.build?.binary) {
157
+ out.build.binary = portableStatusPath(result.build.binary, root);
158
+ }
159
+
160
+ if (out.probe && 'origin' in out.probe) {
161
+ delete out.probe.origin;
162
+ }
163
+
164
+ return out;
165
+ }
166
+
96
167
  function writeHumanSteps(lines, write) {
97
168
  write('\n Agent Sam · Go\n\n');
98
169
  for (const line of lines) write(` ${line}\n`);
@@ -109,14 +180,17 @@ export async function runGo(argv = [], options = {}) {
109
180
 
110
181
  const discovery = discoverGoRuntime(args.cwd);
111
182
  const productRoot = resolveProductRoot(discovery, args.product);
183
+ const stateRoot = options.stateRoot
184
+ ? path.resolve(options.stateRoot)
185
+ : resolveGoStateRoot(discovery, args.cwd);
112
186
  const runtimeRoot = discovery.runtime?.runtimeRoot || path.join(productRoot, 'runtime');
113
187
 
114
188
  if (args.subcommand === 'menu' && process.stdout.isTTY && !args.json) {
115
- return runInteractiveMenu({ discovery, productRoot, runtimeRoot, args, write });
189
+ return runInteractiveMenu({ discovery, productRoot, stateRoot, runtimeRoot, args, write });
116
190
  }
117
191
 
118
192
  if (args.subcommand === 'inspect' || args.subcommand === 'runtime') {
119
- const payload = { ok: true, discovery, productRoot, runtimeRoot };
193
+ const payload = { ok: true, discovery, productRoot, stateRoot, runtimeRoot };
120
194
  write(args.json ? `${JSON.stringify(payload)}\n` : `${JSON.stringify(payload, null, 2)}\n`);
121
195
  return payload;
122
196
  }
@@ -125,8 +199,8 @@ export async function runGo(argv = [], options = {}) {
125
199
  const scenery = renderGoShipScenery({
126
200
  product: args.product,
127
201
  discovery,
128
- deploy: { url: readLatestStatus(productRoot).deployment?.url, receipt: readLatestStatus(productRoot).deployment, probes: { ok: readLatestStatus(productRoot).deployment?.health === 'healthy' } },
129
- build: { receipt: readLatestStatus(productRoot).build },
202
+ deploy: { url: readLatestStatus(stateRoot).deployment?.url, receipt: readLatestStatus(stateRoot).deployment, probes: { ok: readLatestStatus(stateRoot).deployment?.health === 'healthy' } },
203
+ build: { receipt: readLatestStatus(stateRoot).build },
130
204
  });
131
205
  if (args.json) {
132
206
  write(`${JSON.stringify({ ok: true, scenery: 'ansi', product: args.product })}\n`);
@@ -138,20 +212,103 @@ export async function runGo(argv = [], options = {}) {
138
212
  }
139
213
 
140
214
  if (args.subcommand === 'status' || args.subcommand === 'products') {
141
- const latest = readLatestStatus(productRoot);
215
+ const latest = readLatestStatus(stateRoot);
216
+
217
+ const production = (
218
+ latest.deployment
219
+ && latest.deployment.dry_run !== true
220
+ && latest.deployment.deployed_at
221
+ )
222
+ ? {
223
+ provider: latest.deployment.provider || null,
224
+ target: 'cloudflare',
225
+ canonical_url: latest.deployment.url || null,
226
+ account_id: latest.deployment.cloudflare?.account_id || null,
227
+ deployment_id: latest.deployment.worker_deployment_id || null,
228
+ version_id: latest.deployment.worker_version_id || null,
229
+ container_image_digest: latest.deployment.container_image_digest || null,
230
+ deployed_at: latest.deployment.deployed_at || null,
231
+ health: latest.deployment.health || null,
232
+ probe: {
233
+ origin: latest.deployment.url || null,
234
+ status: latest.deployment.probes?.skipped
235
+ ? 'pending'
236
+ : latest.deployment.probes?.ok
237
+ ? 'passed'
238
+ : 'failed',
239
+ },
240
+ }
241
+ : null;
242
+
142
243
  const status = {
143
244
  ok: true,
144
245
  product: args.product,
145
246
  discovery: {
146
247
  go: discovery.go,
147
248
  runtime: discovery.runtime
148
- ? { module: discovery.runtime.module, runtimeRoot: discovery.runtime.runtimeRoot, entry: discovery.runtime.entry }
249
+ ? {
250
+ module: discovery.runtime.module,
251
+ runtimeRoot: portableStatusPath(
252
+ discovery.runtime.runtimeRoot,
253
+ discovery.repository_root || args.cwd,
254
+ ),
255
+ entry: portableStatusPath(
256
+ discovery.runtime.entry,
257
+ discovery.repository_root || args.cwd,
258
+ ),
259
+ }
149
260
  : null,
150
261
  product_exists: discovery.product_exists,
151
262
  },
152
- build: latest.build,
263
+ source: {
264
+ repository_id:
265
+ latest.product?.row?.repository_id
266
+ || latest.build?.source?.repository_id
267
+ || null,
268
+ commit:
269
+ latest.deployment?.source_commit
270
+ || latest.build?.source?.commit
271
+ || null,
272
+ identity:
273
+ latest.deployment?.source_identity
274
+ || latest.build?.source?.identity
275
+ || null,
276
+ package:
277
+ latest.deployment?.source_package
278
+ || latest.build?.source?.package_name
279
+ || null,
280
+ version:
281
+ latest.deployment?.source_package_version
282
+ || latest.build?.source?.package_version
283
+ || null,
284
+ },
285
+ verification: {
286
+ local_native_probe: {
287
+ target: 'local',
288
+ status: latest.build?.probe?.ok
289
+ ? 'passed'
290
+ : latest.build
291
+ ? 'failed'
292
+ : 'unknown',
293
+ },
294
+ container: {
295
+ target: 'linux/amd64',
296
+ status: latest.deployment?.container_image_digest
297
+ ? 'passed'
298
+ : 'unknown',
299
+ },
300
+ },
301
+ production,
302
+ build: publicBuildReceipt(latest.build),
153
303
  deployment: latest.deployment,
154
- registry: latest.product,
304
+ registry: latest.product
305
+ ? {
306
+ ...latest.product,
307
+ authority: latest.deployment?.official_release
308
+ ? 'inneranimalmedia'
309
+ : 'local',
310
+ }
311
+ : null,
155
312
  };
156
313
  if (args.json) write(`${JSON.stringify(status)}\n`);
157
314
  else {
@@ -184,15 +341,25 @@ export async function runGo(argv = [], options = {}) {
184
341
  productRoot,
185
342
  runtimeRoot,
186
343
  repositoryRoot: discovery.repository_root,
344
+ stateRoot,
187
345
  dryRun: args.dryRun,
188
346
  });
189
- write(args.json ? `${JSON.stringify(result)}\n` : `✓ build receipt · ${result.receiptPath}\n`);
347
+ const publicResult = publicBuildResult(
348
+ result,
349
+ discovery.repository_root || args.cwd,
350
+ );
351
+ write(
352
+ args.json
353
+ ? `${JSON.stringify(publicResult)}\n`
354
+ : `✓ build receipt · ${publicResult.receiptPath}\n`,
355
+ );
190
356
  return result;
191
357
  }
192
358
 
193
359
  if (args.subcommand === 'verify') {
194
360
  const result = await verifyGoProduct({
195
361
  productRoot,
362
+ stateRoot,
196
363
  runtimeRoot,
197
364
  skipLive: args.dryRun || args.skipDeploy,
198
365
  });
@@ -206,33 +373,124 @@ export async function runGo(argv = [], options = {}) {
206
373
  }
207
374
 
208
375
  if (args.subcommand === 'deploy' || args.subcommand === 'cloudflare-ship') {
209
- return shipCloudflare({ discovery, productRoot, runtimeRoot, args, write });
376
+ return shipCloudflare({ discovery, productRoot, stateRoot, runtimeRoot, args, write, options });
210
377
  }
211
378
 
212
379
  write(HELP);
213
380
  return { ok: true, help: true };
214
381
  }
215
382
 
216
- async function shipCloudflare({ discovery, productRoot, runtimeRoot, args, write }) {
383
+ async function shipCloudflare({ discovery, productRoot, stateRoot, runtimeRoot, args, write, options = {} }) {
217
384
  const steps = [];
218
385
  const note = (line) => {
219
386
  steps.push(line);
220
- if (!args.json) write(` ${line}\n`);
387
+ if (!args.json) write(' ' + line + '\n');
221
388
  };
222
389
 
223
390
  if (!args.json) write('\n Agent Sam · Go\n\n');
224
391
 
225
392
  note(discovery.runtime ? '✓ existing AgentSam Go runtime discovered' : '✗ Go runtime missing');
226
393
  if (!discovery.runtime) throw new Error('go_runtime_not_found');
394
+ note('✓ source · ' + (discovery.distribution?.origin || discovery.runtime.origin || 'unknown')
395
+ + (discovery.distribution?.package_name
396
+ ? ' · ' + discovery.distribution.package_name + '@' + discovery.distribution.package_version
397
+ : ''));
227
398
  note(discovery.go?.ok ? '✓ go toolchain' : '✗ go toolchain');
228
399
  if (!discovery.go?.ok) throw new Error('go_toolchain_missing');
229
400
 
401
+ if (args.officialRelease) {
402
+ if (!innerAnimalMediaOfficialReleaseEnabled()) {
403
+ const err = new Error('inneranimalmedia_official_release_guard_missing');
404
+ err.code = 'inneranimalmedia_official_release_guard_missing';
405
+ err.legacy_code = 'iam_official_release_guard_missing';
406
+ err.hint = 'Set AGENTSAM_INNERANIMALMEDIA_OFFICIAL_RELEASE=1 only in the authorized InnerAnimalMedia maintainer release flow.';
407
+ throw err;
408
+ }
409
+ if (
410
+ String(process.env.CI || '').toLowerCase() === 'true'
411
+ && process.env.AGENTSAM_ALLOW_CI_OFFICIAL_RELEASE !== '1'
412
+ ) {
413
+ const err = new Error('inneranimalmedia_official_release_ci_guard_missing');
414
+ err.hint = 'Official production deployment is disabled in CI unless AGENTSAM_ALLOW_CI_OFFICIAL_RELEASE=1 is explicitly set by a manual release workflow.';
415
+ throw err;
416
+ }
417
+ if (discovery.runtime?.origin !== 'repository' && discovery.runtime?.origin !== 'sdk_development_tree') {
418
+ const err = new Error('inneranimalmedia_official_release_requires_maintainer_source');
419
+ err.code = 'inneranimalmedia_official_release_requires_maintainer_source';
420
+ err.legacy_code = 'iam_official_release_requires_maintainer_source';
421
+ err.hint = 'Official InnerAnimalMedia releases must originate from the AgentSam SDK maintainer source tree.';
422
+ throw err;
423
+ }
424
+ note('✓ release mode · InnerAnimalMedia official');
425
+ } else {
426
+ note('✓ release mode · self-host · InnerAnimalMedia D1 isolated');
427
+ }
428
+
429
+ let cfIdentity = null;
430
+ if (!args.skipDeploy) {
431
+ cfIdentity = resolveWranglerIdentity(productRoot, {
432
+ requestedAccountId: args.accountId,
433
+ });
434
+
435
+ if (!cfIdentity.ok && cfIdentity.error === 'cloudflare_account_ambiguous' && !args.json && process.stdout.isTTY) {
436
+ const selectImpl = options.selectImpl || select;
437
+ const chosen = await selectImpl({
438
+ message: 'Cloudflare account',
439
+ options: cfIdentity.accounts.map((account) => ({
440
+ value: account.id,
441
+ label: account.name || account.id,
442
+ hint: account.id,
443
+ })),
444
+ });
445
+ if (isCancel(chosen)) {
446
+ cancel('Cloudflare deployment cancelled.');
447
+ return { ok: false, cancelled: true };
448
+ }
449
+ args.accountId = String(chosen);
450
+ cfIdentity = resolveWranglerIdentity(productRoot, {
451
+ requestedAccountId: args.accountId,
452
+ });
453
+ }
454
+
455
+ if (!cfIdentity.ok || !cfIdentity.account?.id) {
456
+ const err = new Error(cfIdentity.error || 'cloudflare_identity_unavailable');
457
+ err.detail = cfIdentity;
458
+ err.hint = cfIdentity.error === 'cloudflare_account_ambiguous'
459
+ ? 'Pass --account <account-id> so the deployment target is explicit.'
460
+ : 'Authenticate Wrangler with your Cloudflare account before self-hosting.';
461
+ throw err;
462
+ }
463
+
464
+ args.accountId = cfIdentity.account.id;
465
+ note('✓ Cloudflare identity · ' + (cfIdentity.auth_type || 'authenticated'));
466
+ note('✓ Cloudflare account · ' + (cfIdentity.account.name || 'unnamed') + ' · ' + cfIdentity.account.id);
467
+
468
+ if (!args.dryRun && !args.yes) {
469
+ if (args.json || !process.stdout.isTTY) {
470
+ const err = new Error('cloudflare_deploy_confirmation_required');
471
+ err.hint = 'Re-run with --yes after reviewing the resolved Cloudflare account target.';
472
+ throw err;
473
+ }
474
+ const confirmImpl = options.confirmImpl || confirm;
475
+ const approved = await confirmImpl({
476
+ message: 'Deploy ' + args.product + ' to ' + (cfIdentity.account.name || cfIdentity.account.id)
477
+ + ' (' + cfIdentity.account.id + ')?',
478
+ initialValue: false,
479
+ });
480
+ if (isCancel(approved) || approved !== true) {
481
+ cancel('Cloudflare deployment cancelled.');
482
+ return { ok: false, cancelled: true };
483
+ }
484
+ }
485
+ }
486
+
230
487
  const preflight = preflightToolchain({
231
- requireDocker: !(args.dryRun || args.skipDeploy),
488
+ requireDocker: !args.skipDeploy,
232
489
  productRoot,
233
490
  });
234
491
  for (const check of preflight.checks) {
235
- note(`${check.ok ? '✓' : '·'} ${check.id}${check.detail ? ` · ${String(check.detail).slice(0, 80)}` : ''}`);
492
+ note((check.ok ? '✓' : '·') + ' ' + check.id
493
+ + (check.detail ? ' · ' + String(check.detail).slice(0, 80) : ''));
236
494
  }
237
495
 
238
496
  const contract = ensureProductContract(productRoot);
@@ -240,9 +498,10 @@ async function shipCloudflare({ discovery, productRoot, runtimeRoot, args, write
240
498
  note('✓ deployment contract · cloudflare worker-container');
241
499
 
242
500
  if (!args.json) {
243
- write(`\n Product\n ${args.product}\n`);
501
+ write('\n Product\n ' + args.product + '\n');
244
502
  write(' Target\n cloudflare\n');
245
- write(' Runtime\n go/native + worker edge\n\n');
503
+ write(' Runtime\n go/native + worker edge\n');
504
+ write(' State\n ' + stateRoot + '\n\n');
246
505
  }
247
506
 
248
507
  if (!args.json) write(' Building\n');
@@ -250,63 +509,114 @@ async function shipCloudflare({ discovery, productRoot, runtimeRoot, args, write
250
509
  productRoot,
251
510
  runtimeRoot,
252
511
  repositoryRoot: discovery.repository_root,
253
- dryRun: args.dryRun,
512
+ stateRoot,
513
+ dryRun: false,
254
514
  });
515
+ note('✓ source identity · ' + build.receipt.source.identity);
255
516
  note('✓ go test ./...');
256
517
  note('✓ go vet ./...');
257
- note(build.build.binary ? `✓ Go binary · ${path.basename(build.build.binary)}` : '✓ Go build skipped (dry-run)');
518
+ note('✓ Go binary · ' + path.basename(build.build.binary) + ' · ' + build.receipt.artifact.digest);
519
+ note('✓ native runtime boot/probe/shutdown');
520
+
521
+ let container = null;
522
+ if (!args.skipDeploy) {
523
+ if (!args.json) write('\n Container\n');
524
+ container = await verifyGoContainer({
525
+ productRoot,
526
+ product: args.product,
527
+ expectedSource: build.receipt.source.identity,
528
+ expectedSourceCommit: build.receipt.source.commit,
529
+ expectedBuiltAt: build.receipt.built_at,
530
+ });
531
+ note('✓ linux/' + container.architecture + ' · ' + container.user);
532
+ note('✓ container runtime probe · ' + container.image_digest);
533
+ }
258
534
 
259
535
  if (!args.json) write('\n Deploying\n');
260
536
  const deploy = await deployGoCloudflare({
261
537
  productRoot,
538
+ stateRoot,
262
539
  product: args.product,
263
540
  dryRun: args.dryRun,
264
541
  skipDeploy: args.skipDeploy,
265
542
  skipRegistry: args.skipRegistry,
543
+ officialRelease: args.officialRelease,
544
+ accountId: args.accountId,
545
+ cloudflareIdentity: cfIdentity,
546
+ source: build.receipt.source,
547
+ builtAt: build.receipt.built_at,
548
+ artifactDigest: build.receipt.artifact.digest,
549
+ containerDigest: container?.image_digest || null,
266
550
  });
267
- if (deploy.deployed) note(`✓ ${args.product}`);
268
- else if (args.dryRun) note('· dry-run · deploy skipped');
551
+
552
+ if (deploy.deployed) note('✓ ' + args.product + ' · ' + deploy.deploymentId + ' · ' + deploy.versionId);
553
+ else if (args.dryRun && deploy.dryRunValidated) note('✓ Wrangler dry-run validated Worker + Container config');
269
554
  else if (args.skipDeploy) note('· skip-deploy · local receipts only');
270
555
  else note('· deploy not completed');
271
556
 
272
- if (deploy.url && !args.json) write(`\n Live\n ${deploy.url}\n`);
557
+ if (deploy.url && !args.json) write('\n Live\n ' + deploy.url + '\n');
273
558
  if (!args.json) write('\n Validation\n');
274
559
  if (deploy.probes?.results) {
275
560
  for (const [key, value] of Object.entries(deploy.probes.results)) {
276
- note(`${value.ok ? '✓' : '✗'} ${key}`);
561
+ // The raw malformed request is expected to return HTTP 400. Its
562
+ // correctness is represented by malformed_rejected/error_envelope.
563
+ if (key === 'malformed') continue;
564
+
565
+ const label = key === 'malformed_rejected'
566
+ ? 'malformed input rejected'
567
+ : key;
568
+
569
+ note((value.ok ? '✓' : '✗') + ' ' + label);
277
570
  }
278
571
  } else {
279
572
  note('· live probes skipped');
280
573
  }
281
574
 
282
- if (!args.json) write('\n Registered\n');
283
- if (deploy.registry?.remote) note('✓ agentsam_products · remote D1 upsert');
284
- else if (deploy.registry?.skipped) note(`· agentsam_products · ${deploy.registry.reason || 'local only'}`);
285
- else note('✓ agentsam_products (local projection)');
286
- if (deploy.registry?.remote) note('✓ asset_relationships · remote D1 upsert');
287
- else note('✓ asset relationships (local metadata)');
575
+ if (!args.json) write('\n Registry\n');
576
+ if (deploy.registry?.remote) {
577
+ note('✓ InnerAnimalMedia agentsam_products + asset_relationships · official release');
578
+ } else if (!args.officialRelease) {
579
+ note('✓ local AgentSam registry · InnerAnimalMedia D1 isolated');
580
+ } else {
581
+ note('· InnerAnimalMedia registry · ' + (deploy.registry?.reason || 'not written'));
582
+ }
288
583
  note('✓ deployment receipt');
289
584
 
585
+ const buildOk = Boolean(
586
+ build.receipt.tests.go_test
587
+ && build.receipt.tests.go_vet
588
+ && build.receipt.tests.runtime_probe
589
+ && build.receipt.artifact.digest
590
+ && build.receipt.source.identity,
591
+ );
592
+ const containerOk = args.skipDeploy ? true : Boolean(container?.ok && container?.image_digest);
593
+ const deploymentOk = args.skipDeploy
594
+ ? true
595
+ : (args.dryRun ? Boolean(deploy.dryRunValidated) : Boolean(deploy.deployed && deploy.probes?.ok));
596
+ const registryOk = !args.officialRelease
597
+ ? deploy.registry?.reason === 'self_host_registry_isolated'
598
+ : (args.skipRegistry || args.dryRun || args.skipDeploy ? true : Boolean(deploy.registry?.remote));
599
+
290
600
  const payload = {
291
- ok: Boolean(build && (args.dryRun || args.skipDeploy || deploy.probes?.ok || deploy.deployed)),
601
+ ok: buildOk && containerOk && deploymentOk && registryOk,
602
+ mode: args.officialRelease ? 'inneranimalmedia_official_release' : 'self_host',
292
603
  product: args.product,
604
+ state_root: stateRoot,
605
+ cloudflare: deploy.cloudflare,
293
606
  existing_product: contract.existing,
294
607
  scaffold_changes_required: contract.created.length > 0,
295
608
  discovery,
296
609
  contract,
297
610
  build: build.receipt,
611
+ container,
298
612
  deploy,
299
613
  steps,
300
614
  };
301
615
 
302
- // Idempotent success: second run with healthy prior deploy still ok even if live probe skipped.
303
- if (args.dryRun || args.skipDeploy) payload.ok = true;
304
- if (deploy.deployed && deploy.probes && !deploy.probes.skipped) payload.ok = deploy.probes.ok;
305
-
306
- if (args.json) write(`${JSON.stringify(payload)}\n`);
616
+ if (args.json) write(JSON.stringify(payload) + '\n');
307
617
  else {
308
- write(`\n${renderGoShipScenery({ product: args.product, discovery, deploy, build })}\n`);
309
- write(`\n ${payload.ok ? 'ready' : 'incomplete'} · ${args.product}\n`);
618
+ write('\n' + renderGoShipScenery({ product: args.product, discovery, deploy, build }) + '\n');
619
+ write('\n ' + (payload.ok ? 'ready' : 'incomplete') + ' · ' + args.product + '\n');
310
620
  if (contract.existing && !contract.created.length) {
311
621
  write(' ✓ existing product · update/redeploy path (no sibling scaffold)\n');
312
622
  }
@@ -322,9 +632,9 @@ async function shipCloudflare({ discovery, productRoot, runtimeRoot, args, write
322
632
  return payload;
323
633
  }
324
634
 
325
- async function runInteractiveMenu({ discovery, productRoot, runtimeRoot, args, write }) {
635
+ async function runInteractiveMenu({ discovery, productRoot, stateRoot, runtimeRoot, args, write }) {
326
636
  intro(pc.bgCyan(pc.black(' Agent Sam · Go ')));
327
- const status = readLatestStatus(productRoot);
637
+ const status = readLatestStatus(stateRoot);
328
638
  write(`\n Runtime\n`);
329
639
  write(` ${discovery.go?.ok ? '✓' : '✗'} Go ${discovery.go?.goversion || ''}\n`);
330
640
  write(` ${discovery.runtime ? '✓' : '✗'} AgentSam Go source discovered\n`);
@@ -339,7 +649,7 @@ async function runInteractiveMenu({ discovery, productRoot, runtimeRoot, args, w
339
649
  package: args.product,
340
650
  owns: 'Go runtime + CF container edge',
341
651
  runtime: 'go/native + worker',
342
- imported_by: 'CLI · deploy adapter · D1 registry',
652
+ imported_by: 'CLI · deploy adapter · local registry · InnerAnimalMedia official registry',
343
653
  files: 'main.go · wrangler · Dockerfile',
344
654
  },
345
655
  })}\n\n`);
@@ -351,7 +661,7 @@ async function runInteractiveMenu({ discovery, productRoot, runtimeRoot, args, w
351
661
  { value: 'build', label: 'Build' },
352
662
  { value: 'test', label: 'Test' },
353
663
  { value: 'inspect', label: 'Inspect' },
354
- { value: 'cloudflare-ship', label: 'Deploy to Cloudflare' },
664
+ { value: 'deploy', label: 'Self-host on Cloudflare' },
355
665
  { value: 'verify', label: 'Verify deployment' },
356
666
  { value: 'status', label: 'Show runtime' },
357
667
  ],
@@ -361,5 +671,8 @@ async function runInteractiveMenu({ discovery, productRoot, runtimeRoot, args, w
361
671
  return { ok: false, cancelled: true };
362
672
  }
363
673
  outro(`Running ${action}`);
364
- return runGo([action, args.product, ...(args.json ? ['--json'] : [])], { write });
674
+ const forwarded = [action, args.product, '--cwd', args.cwd];
675
+ if (action === 'deploy') forwarded.push('--cloudflare');
676
+ if (args.json) forwarded.push('--json');
677
+ return runGo(forwarded, { write });
365
678
  }