@inneranimalmedia/agentsam-sdk 2.6.1 → 2.6.3

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 (507) hide show
  1. package/AGENTSAM.md +45 -1
  2. package/README.md +80 -0
  3. package/apps/README.md +34 -0
  4. package/apps/cad-creator/README.md +728 -0
  5. package/apps/cad-creator/shared/cad/package.json +19 -0
  6. package/apps/cad-creator/shared/cad/src/domain/operations.ts +7 -0
  7. package/apps/cad-creator/shared/cad/src/domain/project-contract.d.ts +3 -0
  8. package/apps/cad-creator/shared/cad/src/domain/project-contract.js +75 -0
  9. package/apps/cad-creator/shared/cad/src/domain/project-tools.d.ts +1 -0
  10. package/apps/cad-creator/shared/cad/src/domain/project-tools.js +24 -0
  11. package/apps/cad-creator/shared/cad/src/domain/validation.ts +191 -0
  12. package/apps/cad-creator/shared/cad/src/index.ts +4 -0
  13. package/apps/cad-creator/shared/cad/src/robotics/types.ts +232 -0
  14. package/apps/cad-creator/shared/cad/src/types.ts +507 -0
  15. package/apps/cad-creator/shared/cad/tsconfig.json +14 -0
  16. package/docs/AUTH_IDENTITY_CONTRACT.md +25 -27
  17. package/docs/AUTORAG.md +58 -0
  18. package/docs/BRAND_INTELLIGENCE.md +30 -0
  19. package/docs/CLI_SHELL.md +4 -2
  20. package/docs/CMS_CONTEXTUAL_COMPOSER.md +38 -0
  21. package/docs/MERKLE.md +4 -0
  22. package/docs/PROJECT_CONFIG.md +3 -0
  23. package/docs/REPOSITORY_KNOWLEDGE.md +2 -0
  24. package/docs/SDK_WORKER.md +4 -3
  25. package/docs/THEME_REFINERY.md +120 -0
  26. package/docs/architecture/PROVIDER-TOOLS-AND-COMPACTION.md +60 -0
  27. package/docs/architecture/STORAGE.md +87 -0
  28. package/docs/cad-project-tools.md +69 -0
  29. package/docs/cms-scaffolding-pattern-reference.md +73 -0
  30. package/docs/plans/AGENTSAM-INTERACTIVE-UI-REQUIREMENTS-codex-tui-20260919.md +113 -0
  31. package/docs/plans/AGENTSAM-INTERACTIVE-UI-REQUIREMENTS.md +85 -0
  32. package/docs/plans/AGENTSAM-MCP-CLIENT-2026-09-19.md +181 -0
  33. package/docs/plans/ASBD-PORTABLE-WORKGRAPH-UI-DEFERRED.md +34 -0
  34. package/docs/plans/ASTRA-BRIEF-2026-09-18.md +258 -0
  35. package/docs/plans/MULTI-AGENT-SPRINTS-2026-09-19.md +373 -0
  36. package/docs/plans/NEXT-AGENT-HANDOFF.md +167 -0
  37. package/docs/plans/RECONCILIATION-2026-09-19.md +178 -0
  38. package/docs/plugins.md +43 -0
  39. package/docs/tools/README.md +57 -0
  40. package/docs/tools/agent-and-orchestration.md +49 -0
  41. package/docs/tools/browser-and-research.md +46 -0
  42. package/docs/tools/cloudflare-platform.md +32 -0
  43. package/docs/tools/cms.md +25 -0
  44. package/docs/tools/communications.md +41 -0
  45. package/docs/tools/database-and-storage.md +62 -0
  46. package/docs/tools/design-and-media.md +64 -0
  47. package/docs/tools/filesystem-and-code.md +55 -0
  48. package/docs/tools/github.md +56 -0
  49. package/docs/tools/integrations-and-misc.md +16 -0
  50. package/docs/tools/memory.md +21 -0
  51. package/docs/tools/terminal-and-execution.md +29 -0
  52. package/docs/tools/tickets-and-platform.md +30 -0
  53. package/migrations/d1/0001_agentsam_plugin_runtime.sql +177 -0
  54. package/migrations/d1/0002_agentsam_ticket_ownership.sql +8 -0
  55. package/migrations/d1/0002_dynamic_model_policies.sql +23 -0
  56. package/migrations/d1/0003_expand_tool_handler_families.sql +18 -0
  57. package/migrations/d1/0004_project_aware_retrieval_lanes.sql +24 -0
  58. package/migrations/d1/0005_portable_knowledge_identity.sql +104 -0
  59. package/migrations/d1/0006_repair_ops_trail_account_scope.sql +14 -0
  60. package/migrations/d1/0007_repair_ops_trail_agent_run_account.sql +13 -0
  61. package/migrations/d1/0008_backfill_knowledge_run_legacy_tenant.sql +14 -0
  62. package/migrations/d1/0009_normalize_cloudflare_plugin_installations.sql +137 -0
  63. package/migrations/runtime/0001_cli_runtime.sql +67 -0
  64. package/migrations/runtime/0002_project_sessions.sql +15 -0
  65. package/migrations/runtime/0003_provider_continuations.sql +8 -0
  66. package/package.json +92 -12
  67. package/packages/agentsam-brand/README.md +21 -0
  68. package/packages/agentsam-brand/package.json +22 -0
  69. package/packages/agentsam-brand/src/contract.js +59 -0
  70. package/packages/agentsam-brand/src/extract.js +126 -0
  71. package/packages/agentsam-brand/src/goap-actions.js +73 -0
  72. package/packages/agentsam-brand/src/index.js +48 -0
  73. package/packages/agentsam-brand/src/plan.js +115 -0
  74. package/packages/agentsam-brand/src/resolve.js +139 -0
  75. package/packages/agentsam-brand/src/scan.js +250 -0
  76. package/packages/agentsam-brand/test/brand-scan.test.mjs +106 -0
  77. package/packages/agentsam-contracts/README.md +23 -0
  78. package/packages/agentsam-contracts/package.json +32 -0
  79. package/packages/agentsam-contracts/src/adapter.ts +25 -0
  80. package/packages/agentsam-contracts/src/agent.ts +35 -0
  81. package/packages/agentsam-contracts/src/artifacts.ts +33 -0
  82. package/packages/agentsam-contracts/src/authority.ts +29 -0
  83. package/packages/agentsam-contracts/src/context.ts +16 -0
  84. package/packages/agentsam-contracts/src/errors.ts +46 -0
  85. package/packages/agentsam-contracts/src/events.ts +47 -0
  86. package/packages/agentsam-contracts/src/execution.ts +50 -0
  87. package/packages/agentsam-contracts/src/hooks.ts +40 -0
  88. package/packages/agentsam-contracts/src/identity.ts +16 -0
  89. package/packages/agentsam-contracts/src/index.ts +14 -0
  90. package/packages/agentsam-contracts/src/models.ts +9 -0
  91. package/packages/agentsam-contracts/src/providers.ts +33 -0
  92. package/packages/agentsam-contracts/src/repository.ts +64 -0
  93. package/packages/agentsam-contracts/src/tools.ts +98 -0
  94. package/packages/agentsam-contracts/test/contracts.test.mjs +16 -0
  95. package/packages/agentsam-contracts/test/errors-catalog.test.mjs +25 -0
  96. package/packages/agentsam-contracts/test/repository.test.mjs +18 -0
  97. package/packages/agentsam-contracts/tsconfig.json +12 -0
  98. package/packages/agentsam-errors/package.json +17 -0
  99. package/packages/agentsam-errors/src/adapters/anthropic.js +15 -0
  100. package/packages/agentsam-errors/src/adapters/cad.js +109 -0
  101. package/packages/agentsam-errors/src/adapters/cloudflare.js +21 -0
  102. package/packages/agentsam-errors/src/adapters/cursor.js +4 -0
  103. package/packages/agentsam-errors/src/adapters/device.js +38 -0
  104. package/packages/agentsam-errors/src/adapters/docker.js +28 -0
  105. package/packages/agentsam-errors/src/adapters/gcp.js +14 -0
  106. package/packages/agentsam-errors/src/adapters/github.js +22 -0
  107. package/packages/agentsam-errors/src/adapters/google.js +17 -0
  108. package/packages/agentsam-errors/src/adapters/index.js +55 -0
  109. package/packages/agentsam-errors/src/adapters/internal.js +40 -0
  110. package/packages/agentsam-errors/src/adapters/oauth.js +24 -0
  111. package/packages/agentsam-errors/src/adapters/openai.js +17 -0
  112. package/packages/agentsam-errors/src/adapters/process.js +35 -0
  113. package/packages/agentsam-errors/src/adapters/provider.js +114 -0
  114. package/packages/agentsam-errors/src/envelope.js +186 -0
  115. package/packages/agentsam-errors/src/error.js +24 -0
  116. package/packages/agentsam-errors/src/fingerprint.js +35 -0
  117. package/packages/agentsam-errors/src/index.js +10 -0
  118. package/packages/agentsam-errors/src/normalize.js +30 -0
  119. package/packages/agentsam-errors/src/redaction.js +52 -0
  120. package/packages/agentsam-errors/src/render.js +16 -0
  121. package/packages/agentsam-errors/src/retry.js +10 -0
  122. package/packages/agentsam-errors/src/transport.js +52 -0
  123. package/packages/agentsam-errors/src/vocabulary.js +320 -0
  124. package/packages/agentsam-errors/test/envelope.test.mjs +70 -0
  125. package/packages/agentsam-errors/test/providers.test.mjs +99 -0
  126. package/packages/agentsam-errors/test/redaction.test.mjs +21 -0
  127. package/packages/agentsam-errors/test/runtime-cad-device.test.mjs +76 -0
  128. package/packages/agentsam-errors/test/transport.test.mjs +46 -0
  129. package/packages/agentsam-knowledge/package.json +15 -0
  130. package/packages/agentsam-knowledge/src/autorag/index.js +64 -0
  131. package/packages/agentsam-knowledge/src/backends/index.js +26 -0
  132. package/packages/agentsam-knowledge/src/index.js +3 -0
  133. package/packages/agentsam-knowledge/src/providers/index.js +95 -0
  134. package/packages/agentsam-knowledge/test/autorag.test.mjs +42 -0
  135. package/packages/agentsam-nav/README.md +40 -0
  136. package/packages/agentsam-nav/dist/Nav.d.ts +43 -0
  137. package/packages/agentsam-nav/dist/NavCollapsible.d.ts +10 -0
  138. package/packages/agentsam-nav/dist/NavContent.d.ts +2 -0
  139. package/packages/agentsam-nav/dist/NavFooter.d.ts +2 -0
  140. package/packages/agentsam-nav/dist/NavGroup.d.ts +3 -0
  141. package/packages/agentsam-nav/dist/NavHeader.d.ts +2 -0
  142. package/packages/agentsam-nav/dist/NavMenu.d.ts +22 -0
  143. package/packages/agentsam-nav/dist/NavProvider.d.ts +35 -0
  144. package/packages/agentsam-nav/dist/NavTrigger.d.ts +2 -0
  145. package/packages/agentsam-nav/dist/Surfaces.d.ts +41 -0
  146. package/packages/agentsam-nav/dist/browser.d.ts +11 -0
  147. package/packages/agentsam-nav/dist/browser.global.js +132 -0
  148. package/packages/agentsam-nav/dist/browser.js +613 -0
  149. package/packages/agentsam-nav/dist/contracts.d.ts +76 -0
  150. package/packages/agentsam-nav/dist/index.d.ts +11 -0
  151. package/packages/agentsam-nav/dist/index.js +614 -0
  152. package/packages/agentsam-nav/dist/legacy.css +83 -0
  153. package/packages/agentsam-nav/dist/shell.css +113 -0
  154. package/packages/agentsam-nav/dist/theme.css +113 -0
  155. package/packages/agentsam-nav/dist/utils.d.ts +1 -0
  156. package/packages/agentsam-nav/package.json +43 -0
  157. package/packages/agentsam-queue-control/README.md +107 -0
  158. package/packages/agentsam-queue-control/package.json +31 -0
  159. package/packages/agentsam-queue-control/schemas/job-envelope.schema.json +56 -0
  160. package/packages/agentsam-queue-control/src/adapters/cloudflare.js +152 -0
  161. package/packages/agentsam-queue-control/src/adapters/memory.js +38 -0
  162. package/packages/agentsam-queue-control/src/contracts.js +130 -0
  163. package/packages/agentsam-queue-control/src/control-plane.js +141 -0
  164. package/packages/agentsam-queue-control/src/dispatch.js +43 -0
  165. package/packages/agentsam-queue-control/src/index.js +7 -0
  166. package/packages/agentsam-queue-control/src/policy.js +88 -0
  167. package/packages/agentsam-queue-control/src/topology.js +66 -0
  168. package/packages/agentsam-queue-control/test/queue-control.test.mjs +100 -0
  169. package/packages/agentsam-repository/src/goap.js +718 -0
  170. package/packages/agentsam-repository/src/goap.js.bak-20260922011251 +670 -0
  171. package/packages/agentsam-repository/src/index.js +5 -0
  172. package/packages/agentsam-repository/src/merkle/cloudflare-persistence.js +2 -2
  173. package/packages/agentsam-repository/src/tickets.js +184 -0
  174. package/packages/agentsam-repository/src/work-tracking.js +199 -0
  175. package/packages/agentsam-repository/src/workspace-state.js +176 -0
  176. package/packages/agentsam-repository/test/goap-tickets-workspace-state.test.mjs +152 -0
  177. package/packages/connectors/cloudflare/src/index.js +297 -15
  178. package/packages/connectors/cloudflare/src/owner.js +43 -40
  179. package/packages/connectors/cloudflare/src/routes.js +167 -26
  180. package/packages/connectors/cloudflare/tests/connector.test.mjs +112 -2
  181. package/packages/heuristic-theme/README.md +11 -0
  182. package/packages/heuristic-theme/package.json +25 -0
  183. package/packages/heuristic-theme/src/index.js +2 -0
  184. package/packages/heuristic-theme/src/registry.js +36 -0
  185. package/packages/heuristic-theme/src/theme.js +41 -0
  186. package/packages/heuristic-theme/test/theme.test.mjs +26 -0
  187. package/packages/identity/.agentsam/features/oauth-login-portal/agentsam.feature.json +64 -0
  188. package/packages/identity/.agentsam/features/oauth-login-portal/providers.json +96 -0
  189. package/packages/identity/.agentsam/features/oauth-login-portal/resources.json +47 -0
  190. package/packages/identity/.agentsam/features/oauth-login-portal/routes.json +74 -0
  191. package/packages/identity/.agentsam/features/oauth-login-portal/ui.json +35 -0
  192. package/packages/identity/package.json +4 -3
  193. package/packages/identity/src/adapters/cloudflare-d1/ids.js +4 -0
  194. package/packages/identity/src/adapters/cloudflare-d1/index.js +39 -1
  195. package/packages/identity/src/contracts/auth-config.js +23 -40
  196. package/packages/identity/src/contracts/provider.js +3 -2
  197. package/packages/identity/src/frontend/auth-portal/pages/login.html +7 -0
  198. package/packages/identity/src/index.js +2 -0
  199. package/packages/identity/src/oauth/credentials.js +13 -0
  200. package/packages/identity/src/oauth/iam-platform.js +5 -5
  201. package/packages/identity/src/providers/cloudflare/index.js +19 -0
  202. package/packages/identity/src/providers/cloudflare/mapper.js +21 -0
  203. package/packages/identity/src/providers/cloudflare/oauth.js +48 -0
  204. package/packages/identity/src/providers/cloudflare/profile.js +28 -0
  205. package/packages/identity/src/providers/index.js +18 -2
  206. package/packages/identity/src/server/identity-service.js +13 -3
  207. package/packages/identity/src/server/worker-router.js +63 -8
  208. package/packages/identity/tests/auth-config.test.mjs +14 -23
  209. package/packages/identity/tests/identity-service.test.mjs +15 -0
  210. package/packages/providers/completeful/README.md +38 -0
  211. package/packages/providers/completeful/package.json +29 -0
  212. package/packages/providers/completeful/src/client.js +162 -0
  213. package/packages/providers/completeful/src/events.js +49 -0
  214. package/packages/providers/completeful/src/index.js +22 -0
  215. package/packages/providers/completeful/src/tools.js +579 -0
  216. package/packages/providers/completeful/src/webhooks.js +55 -0
  217. package/packages/providers/completeful/test/provider.test.mjs +196 -0
  218. package/packages/theme-church-site/README.md +10 -0
  219. package/packages/theme-church-site/package.json +30 -0
  220. package/packages/theme-church-site/src/harvest.json +14 -0
  221. package/packages/theme-church-site/src/index.js +84 -0
  222. package/packages/theme-church-site/test/theme.test.mjs +19 -0
  223. package/packages/theme-companions-site/README.md +10 -0
  224. package/packages/theme-companions-site/package.json +30 -0
  225. package/packages/theme-companions-site/src/harvest.json +12 -0
  226. package/packages/theme-companions-site/src/index.js +82 -0
  227. package/packages/theme-companions-site/test/theme.test.mjs +19 -0
  228. package/packages/theme-floors-site/README.md +10 -0
  229. package/packages/theme-floors-site/package.json +30 -0
  230. package/packages/theme-floors-site/src/harvest.json +14 -0
  231. package/packages/theme-floors-site/src/index.js +82 -0
  232. package/packages/theme-floors-site/test/theme.test.mjs +19 -0
  233. package/packages/theme-fuelnfree-site/README.md +10 -0
  234. package/packages/theme-fuelnfree-site/package.json +30 -0
  235. package/packages/theme-fuelnfree-site/src/harvest.json +13 -0
  236. package/packages/theme-fuelnfree-site/src/index.js +81 -0
  237. package/packages/theme-fuelnfree-site/test/theme.test.mjs +19 -0
  238. package/packages/theme-handyman-site/README.md +10 -0
  239. package/packages/theme-handyman-site/package.json +30 -0
  240. package/packages/theme-handyman-site/src/harvest.json +10 -0
  241. package/packages/theme-handyman-site/src/index.js +83 -0
  242. package/packages/theme-handyman-site/test/theme.test.mjs +19 -0
  243. package/packages/theme-insurance-site/README.md +10 -0
  244. package/packages/theme-insurance-site/package.json +30 -0
  245. package/packages/theme-insurance-site/src/harvest.json +10 -0
  246. package/packages/theme-insurance-site/src/index.js +83 -0
  247. package/packages/theme-insurance-site/test/theme.test.mjs +19 -0
  248. package/packages/theme-shinshu-site/README.md +10 -0
  249. package/packages/theme-shinshu-site/package.json +30 -0
  250. package/packages/theme-shinshu-site/src/harvest.json +12 -0
  251. package/packages/theme-shinshu-site/src/index.js +83 -0
  252. package/packages/theme-shinshu-site/test/theme.test.mjs +19 -0
  253. package/packages/work-graph/README.md +49 -0
  254. package/packages/work-graph/package.json +19 -0
  255. package/packages/work-graph/prototype/README.md +32 -0
  256. package/packages/work-graph/prototype/data/demo-workgraph.js +47 -0
  257. package/packages/work-graph/prototype/renderers/timeline-model.js +21 -0
  258. package/packages/work-graph/prototype/renderers/workgraph-runtime.js +38 -0
  259. package/packages/work-graph/prototype-gnantt.html +655 -0
  260. package/packages/work-graph/src/adapters/business/projects.js +23 -0
  261. package/packages/work-graph/src/adapters/engineering/git.js +22 -0
  262. package/packages/work-graph/src/adapters/engineering/mcp.js +22 -0
  263. package/packages/work-graph/src/index.js +76 -0
  264. package/packages/work-graph/src/renderers/gantt-model.js +11 -0
  265. package/packages/work-graph/src/renderers/timeline.js +16 -0
  266. package/packages/work-graph/test/work-graph.test.mjs +37 -0
  267. package/protocol/README.md +12 -0
  268. package/protocol/capabilities/cloudflare-cpu-audit-input.schema.json +30 -6
  269. package/protocol/capabilities/cloudflare-cpu-profile-input.schema.json +18 -4
  270. package/protocol/capabilities/cloudflare-wrangler-native-input.schema.json +59 -10
  271. package/protocol/capabilities/knowledge-search-input.schema.json +35 -0
  272. package/protocol/capabilities/manifest.json +163 -1
  273. package/protocol/capabilities/repository-audit-input.schema.json +39 -6
  274. package/protocol/capabilities/repository-snapshot-input.schema.json +15 -3
  275. package/protocol/capabilities/terminal-exec-input.schema.json +55 -0
  276. package/protocol/commerce/catalog.v1.json +50 -0
  277. package/protocol/errors/error-catalog.json +164 -0
  278. package/protocol/errors/error-envelope.schema.json +544 -0
  279. package/protocol/features/README.md +57 -0
  280. package/protocol/features/agentsam.feature.v1.schema.json +290 -0
  281. package/protocol/features/catalog.json +65 -0
  282. package/protocol/features/examples/provider-resend.feature.json +17 -0
  283. package/protocol/go/agentsam-go-runtime.v1.json +17 -0
  284. package/protocol/knowledge/LIFECYCLE.md +140 -0
  285. package/protocol/knowledge/README.md +4 -0
  286. package/protocol/presets/catalog.json +128 -19
  287. package/protocol/rpc/v1/errors.proto +24 -0
  288. package/protocol/theme-refinery/d1-reconciliation.md +48 -0
  289. package/protocol/theme-refinery/product-metadata.schema.json +27 -0
  290. package/protocol/theme-refinery/receipts/products-registry-batch-20260924.json +318 -0
  291. package/protocol/theme-refinery/receipts/theme-harvest-20260924.json +472 -0
  292. package/protocol/theme-refinery/reconciliation-receipt.schema.json +83 -0
  293. package/services/cad/server.py +249 -2
  294. package/src/agent/capability-adapter.js +15 -5
  295. package/src/agent/index.js +2 -1
  296. package/src/agent/model-turn.js +51 -0
  297. package/src/agent/responses-runner.js +304 -38
  298. package/src/capabilities/index.js +1 -0
  299. package/src/capabilities/terminal-exec.js +78 -0
  300. package/src/cli.js +129 -31
  301. package/src/cloudflare/index.js +6 -0
  302. package/src/cloudflare/runtime-status.js +393 -0
  303. package/src/cloudflare/wrangler.js +17 -1
  304. package/src/commands/account-auth.js +1 -1
  305. package/src/commands/app.js +106 -0
  306. package/src/commands/autorag.js +77 -0
  307. package/src/commands/brand.js +293 -0
  308. package/src/commands/cad.js +1 -0
  309. package/src/commands/connections.js +126 -29
  310. package/src/commands/context-economics.js +8 -0
  311. package/src/commands/db.js +7 -0
  312. package/src/commands/deploy.js +2 -2
  313. package/src/commands/env.js +5 -4
  314. package/src/commands/eval.js +209 -14
  315. package/src/commands/go.js +365 -0
  316. package/src/commands/goap.js +176 -0
  317. package/src/commands/identity-init.js +27 -3
  318. package/src/commands/identity-protocol.js +195 -0
  319. package/src/commands/knowledge.js +64 -5
  320. package/src/commands/mcp.js +341 -0
  321. package/src/commands/merkle-persist.js +3 -1
  322. package/src/commands/merkle.js +18 -3
  323. package/src/commands/models.js +109 -23
  324. package/src/commands/plugins.js +175 -0
  325. package/src/commands/preferences.js +28 -8
  326. package/src/commands/product.js +53 -10
  327. package/src/commands/providers.js +389 -0
  328. package/src/commands/resume.js +9 -5
  329. package/src/commands/runtime-status.js +154 -0
  330. package/src/commands/shell.js +469 -54
  331. package/src/commands/status.js +82 -7
  332. package/src/commands/tunnel.js +228 -195
  333. package/src/commands/whoami.js +115 -22
  334. package/src/context/budget.js +6 -0
  335. package/src/context/index.js +2 -1
  336. package/src/context/project-card.js +75 -0
  337. package/src/errors/contract.js +34 -211
  338. package/src/errors/diagnostic.js +95 -50
  339. package/src/errors/index.js +6 -13
  340. package/src/eval/index.js +6 -0
  341. package/src/eval/live.js +439 -0
  342. package/src/features/resolve.js +242 -0
  343. package/src/go/build.js +108 -0
  344. package/src/go/cloudflare.js +207 -0
  345. package/src/go/contract.js +139 -0
  346. package/src/go/discover.js +96 -0
  347. package/src/go/index.js +13 -0
  348. package/src/go/receipts.js +77 -0
  349. package/src/go/registry.js +223 -0
  350. package/src/go/verify.js +31 -0
  351. package/src/index.js +100 -1
  352. package/src/knowledge/config.js +13 -5
  353. package/src/knowledge/engine.js +23 -8
  354. package/src/knowledge/index.js +1 -0
  355. package/src/knowledge/lane-registry.js +46 -0
  356. package/src/knowledge/providers/gemini.js +48 -8
  357. package/src/knowledge/service/client.js +13 -1
  358. package/src/knowledge/service/grpc-codec.js +156 -53
  359. package/src/knowledge/service/job-engine.js +133 -11
  360. package/src/knowledge/service/job-worker.js +34 -5
  361. package/src/knowledge/service/server.js +10 -1
  362. package/src/knowledge/store-discovery.js +77 -0
  363. package/src/lib/account-session.js +100 -25
  364. package/src/lib/agent-instructions.js +3 -0
  365. package/src/lib/auth.js +318 -51
  366. package/src/lib/cad/blender.js +42 -3
  367. package/src/lib/cad/d1-project-store.js +43 -0
  368. package/src/lib/cad/discovery.js +616 -0
  369. package/src/lib/cad/docker-executor.js +352 -0
  370. package/src/lib/cad/freecad.js +253 -0
  371. package/src/lib/cad/index.js +40 -0
  372. package/src/lib/cad/openscad.js +198 -0
  373. package/src/lib/cad/project-cli.d.ts +2 -0
  374. package/src/lib/cad/project-cli.js +21 -0
  375. package/src/lib/cad/project-contract.d.ts +3 -0
  376. package/src/lib/cad/project-contract.js +1 -0
  377. package/src/lib/cad/project-recipe.js +30 -0
  378. package/src/lib/cad/project-runtime.d.ts +2 -0
  379. package/src/lib/cad/project-runtime.js +53 -0
  380. package/src/lib/cad/project-store.js +25 -0
  381. package/src/lib/cad/project-workflows.js +31 -0
  382. package/src/lib/cad-docker.js +21 -2
  383. package/src/lib/cli-preferences.js +17 -2
  384. package/src/lib/core-client.js +97 -33
  385. package/src/lib/deploy/local-studio.js +6 -5
  386. package/src/lib/detect-context.js +14 -16
  387. package/src/lib/dockerize.js +3 -0
  388. package/src/lib/execution-approvals.js +1 -0
  389. package/src/lib/identity-scaffold.js +4 -1
  390. package/src/lib/knowledge-docker.js +9 -1
  391. package/src/lib/local-sessions.js +124 -34
  392. package/src/lib/local-status.js +35 -14
  393. package/src/lib/project-config.js +9 -0
  394. package/src/lib/provider-credentials.js +233 -55
  395. package/src/lib/scaffold/resolve-cloudflare-account.js +37 -0
  396. package/src/lib/scaffold/wizards/cms.js +2 -8
  397. package/src/lib/scaffold/wizards/worker-api.js +2 -8
  398. package/src/lib/slash-commands.js +10 -2
  399. package/src/local/migrations.js +109 -1
  400. package/src/local/runtime-store.js +31 -5
  401. package/src/local/sqlite.js +36 -1
  402. package/src/mcp/authority.js +348 -0
  403. package/src/mcp/client-adapters.js +431 -0
  404. package/src/mcp/client.js +172 -0
  405. package/src/mcp/index.js +47 -0
  406. package/src/mcp/telemetry.js +103 -0
  407. package/src/models/catalog.js +329 -51
  408. package/src/models/discovery.js +59 -4
  409. package/src/models/index.js +2 -0
  410. package/src/models/inventory-core.js +182 -0
  411. package/src/models/policy.js +20 -0
  412. package/src/plugins/cloudflare.js +103 -0
  413. package/src/plugins/completeful.js +69 -0
  414. package/src/plugins/contracts.js +86 -0
  415. package/src/plugins/index.js +11 -0
  416. package/src/plugins/registry.js +207 -0
  417. package/src/plugins/resource-scope.js +45 -0
  418. package/src/plugins/runtime.js +118 -0
  419. package/src/plugins/vectorize.js +31 -0
  420. package/src/progression/engine.js +171 -0
  421. package/src/progression/index.js +1 -0
  422. package/src/providers/cloudflare-chat.js +1 -1
  423. package/src/providers/gemini-generate-content.js +2 -1
  424. package/src/providers/openai-responses.js +45 -16
  425. package/src/providers/tool-schema.js +85 -0
  426. package/src/repository/index.js +29 -0
  427. package/src/rpc/generated/errors_pb.js +961 -1
  428. package/src/security/local-vault.js +415 -0
  429. package/src/security/process.js +20 -4
  430. package/src/status/actions.js +192 -0
  431. package/src/tools/hydrate.js +5 -1
  432. package/src/tools/index.js +7 -0
  433. package/src/tools/redact.js +64 -0
  434. package/src/tools/registry.js +83 -0
  435. package/src/tools/runtime.js +257 -0
  436. package/src/tools/search.js +21 -8
  437. package/src/ui/ansi.js +117 -3
  438. package/src/ui/cli/activity.js +76 -7
  439. package/src/ui/cli/footer.js +110 -9
  440. package/src/ui/cli/help.js +14 -5
  441. package/src/ui/wireframes.js +166 -0
  442. package/test/account-session.test.mjs +76 -11
  443. package/test/apps-scaffold-contract.test.mjs +58 -0
  444. package/test/capabilities.test.mjs +1 -1
  445. package/test/cli/eval-live.test.mjs +219 -0
  446. package/test/cli/go.test.mjs +71 -0
  447. package/test/cli/local-vault-and-provider-setup.test.mjs +268 -0
  448. package/test/cli/mcp-client.test.mjs +245 -0
  449. package/test/cli/runtime-ui.test.mjs +69 -2
  450. package/test/cli/status-actions.test.mjs +88 -0
  451. package/test/cli/wireframes-go-registry.test.mjs +54 -0
  452. package/test/cloudflare-connector.test.mjs +3 -6
  453. package/test/cloudflare-runtime.test.mjs +8 -1
  454. package/test/context.test.mjs +15 -0
  455. package/test/error-diagnostics.test.mjs +9 -0
  456. package/test/fixtures/cad/courtyard-house.json +208 -0
  457. package/test/go/cloudflare-probe.test.mjs +53 -0
  458. package/test/integration/app-command.test.mjs +55 -0
  459. package/test/integration/cad-discovery.test.mjs +158 -0
  460. package/test/integration/cad-docker-executor.test.mjs +249 -0
  461. package/test/integration/cad-execution.test.mjs +184 -0
  462. package/test/integration/cad-project-app.test.mjs +31 -0
  463. package/test/integration/cad-project-d1.test.mjs +25 -0
  464. package/test/integration/cad-project-native.test.mjs +24 -0
  465. package/test/integration/cad-project-workflow.test.mjs +9 -0
  466. package/test/integration/cad-project.test.mjs +82 -0
  467. package/test/integration/cli-help.test.mjs +4 -0
  468. package/test/integration/cms-site-tenancy-contract.test.mjs +256 -0
  469. package/test/integration/core-client.integration.test.mjs +55 -0
  470. package/test/integration/error-runtime-rpc.test.mjs +71 -0
  471. package/test/integration/features-resolve.test.mjs +128 -0
  472. package/test/integration/install-script.test.mjs +107 -0
  473. package/test/integration/inventory-core.test.mjs +53 -0
  474. package/test/integration/plugins-cloudflare.integration.test.mjs +28 -0
  475. package/test/integration/provider-env-cli.test.mjs +1 -1
  476. package/test/integration/runtime-migrations.test.mjs +6 -1
  477. package/test/integration/runtime-status.integration.test.mjs +211 -0
  478. package/test/integration/scaffold-cloudflare.test.mjs +46 -0
  479. package/test/integration/storage-architecture.test.mjs +154 -0
  480. package/test/integration/store-discovery.test.mjs +44 -0
  481. package/test/integration/terminal-exec.integration.test.mjs +86 -0
  482. package/test/integration/tool-runtime.test.mjs +124 -0
  483. package/test/integration/tool-schema.test.mjs +59 -0
  484. package/test/knowledge-service.test.mjs +4 -0
  485. package/test/local-sessions.test.mjs +11 -2
  486. package/test/local-studio-deploy.test.mjs +1 -1
  487. package/test/model-catalog.test.mjs +28 -1
  488. package/test/models.test.mjs +159 -5
  489. package/test/openai-responses.test.mjs +60 -0
  490. package/test/provider-credentials.test.mjs +15 -5
  491. package/test/responses-runner.test.mjs +321 -6
  492. package/test/sdk-worker-contract.test.mjs +5 -1
  493. package/test/shell.test.mjs +149 -4
  494. package/test/smoke.mjs +4 -3
  495. package/test/tools-search.test.mjs +33 -0
  496. package/test/unit/website-assets-bindings.test.mjs +60 -0
  497. package/test/whoami-resume.test.mjs +87 -7
  498. package/examples/gorilla-shell/README.md +0 -15
  499. package/src/lib/gorilla-template.js +0 -54
  500. package/src/lib/prompt-byok.js +0 -57
  501. package/src/lib/save-sdk-token.js +0 -19
  502. package/templates/gorilla-shell/App.tsx +0 -639
  503. package/templates/gorilla-shell/README.md +0 -34
  504. package/templates/gorilla-shell/index.html +0 -15
  505. package/templates/gorilla-shell/main.jsx +0 -9
  506. package/templates/gorilla-shell/package.json +0 -19
  507. package/templates/gorilla-shell/vite.config.js +0 -21
@@ -5,23 +5,83 @@ import { fork } from 'node:child_process';
5
5
  import { DatabaseSync } from 'node:sqlite';
6
6
  import { fileURLToPath } from 'node:url';
7
7
  import { fingerprint, validateConfig } from '../config.js';
8
+ import {
9
+ AgentSamError,
10
+ ERROR_CODE,
11
+ ERROR_REASON,
12
+ createErrorEnvelope,
13
+ normalizeError,
14
+ parseError,
15
+ } from '../../errors/index.js';
8
16
 
9
17
  const defaultWorkerPath = fileURLToPath(new URL('./job-worker.js', import.meta.url));
10
18
  const TERMINAL_STATUSES = new Set(['completed', 'failed']);
11
19
 
20
+ function serviceReason(code) {
21
+ switch (code) {
22
+ case ERROR_CODE.UNAUTHENTICATED: return ERROR_REASON.AUTH_INVALID;
23
+ case ERROR_CODE.PERMISSION_DENIED: return ERROR_REASON.PERMISSION_DENIED;
24
+ case ERROR_CODE.NOT_FOUND: return ERROR_REASON.TARGET_NOT_FOUND;
25
+ case ERROR_CODE.ABORTED: return ERROR_REASON.CONFLICT;
26
+ case ERROR_CODE.RESOURCE_EXHAUSTED: return ERROR_REASON.CAPACITY_EXHAUSTED;
27
+ case ERROR_CODE.UNAVAILABLE: return ERROR_REASON.TRANSPORT_UNREACHABLE;
28
+ case ERROR_CODE.DEADLINE_EXCEEDED: return ERROR_REASON.DEADLINE_EXCEEDED;
29
+ case ERROR_CODE.INVALID_ARGUMENT: return ERROR_REASON.INPUT_INVALID;
30
+ default: return ERROR_REASON.INTERNAL;
31
+ }
32
+ }
33
+
12
34
  export function serviceError(status, message, code) {
13
- return Object.assign(new Error(message), { status, code });
35
+ const canonical = code === 'CONFLICT' ? ERROR_CODE.ABORTED : (Object.values(ERROR_CODE).includes(code) ? code : ERROR_CODE.INTERNAL);
36
+ const envelope = createErrorEnvelope({
37
+ code: canonical,
38
+ reason: serviceReason(canonical),
39
+ message,
40
+ http_status: status,
41
+ retryable: [429, 503, 504].includes(Number(status)),
42
+ source: { kind: 'agentsam', name: 'agentsam-knowledge', service: 'job_engine' },
43
+ resolution_owner: canonical === ERROR_CODE.UNAVAILABLE ? 'agentsam' : undefined,
44
+ domain: 'knowledge',
45
+ stage: 'request',
46
+ });
47
+ return new AgentSamError(envelope);
48
+ }
49
+
50
+ function decodeFailure(row) {
51
+ if (row?.failure_json) {
52
+ try { return parseError(row.failure_json); }
53
+ catch {
54
+ return createErrorEnvelope({
55
+ reason: ERROR_REASON.INTERNAL_CONTRACT_VIOLATION,
56
+ message: 'Stored knowledge failure could not be decoded.',
57
+ source: { kind: 'agentsam', name: 'agentsam-knowledge', service: 'job_engine' },
58
+ domain: 'knowledge',
59
+ stage: 'persistence',
60
+ });
61
+ }
62
+ }
63
+ if (!row?.error) return null;
64
+ return createErrorEnvelope({
65
+ reason: ERROR_REASON.EXECUTION_FAILED,
66
+ message: row.error,
67
+ source: { kind: 'agentsam', name: 'agentsam-knowledge', service: 'legacy_job_row' },
68
+ domain: 'knowledge',
69
+ stage: 'execute',
70
+ });
14
71
  }
15
72
 
16
73
  function decode(row) {
17
- return row && {
74
+ if (!row) return null;
75
+ const failure = decodeFailure(row);
76
+ return {
18
77
  id: row.id,
19
78
  status: row.status,
20
79
  attempts: row.attempts,
21
80
  created_at: row.created_at,
22
81
  updated_at: row.updated_at,
23
82
  result: row.result ? JSON.parse(row.result) : null,
24
- error: row.error,
83
+ failure,
84
+ error: failure?.message || row.error || null,
25
85
  };
26
86
  }
27
87
 
@@ -100,10 +160,22 @@ export function createKnowledgeJobEngine({
100
160
  db.exec(`PRAGMA journal_mode=WAL; PRAGMA busy_timeout=5000;
101
161
  CREATE TABLE IF NOT EXISTS jobs (id TEXT PRIMARY KEY, idem TEXT UNIQUE, digest TEXT NOT NULL,
102
162
  payload TEXT NOT NULL, status TEXT NOT NULL, attempts INTEGER NOT NULL DEFAULT 0,
103
- created_at TEXT NOT NULL, updated_at TEXT NOT NULL, result TEXT, error TEXT);
163
+ created_at TEXT NOT NULL, updated_at TEXT NOT NULL, result TEXT, error TEXT, failure_json TEXT);
104
164
  CREATE INDEX IF NOT EXISTS jobs_pending ON jobs(status, created_at);`);
165
+ const columns = new Set(db.prepare('PRAGMA table_info(jobs)').all().map(row => row.name));
166
+ if (!columns.has('failure_json')) db.exec('ALTER TABLE jobs ADD COLUMN failure_json TEXT');
105
167
  fs.chmodSync(jobsFile, 0o600);
106
- db.prepare("UPDATE jobs SET status=CASE WHEN attempts>=3 THEN 'failed' ELSE 'queued' END, error=CASE WHEN attempts>=3 THEN 'Interrupted three times; submit a new job after investigation.' ELSE NULL END WHERE status='running'").run();
168
+ const interruptedFailure = createErrorEnvelope({
169
+ reason: ERROR_REASON.EXECUTION_FAILED,
170
+ message: 'Interrupted three times; submit a new job after investigation.',
171
+ source: { kind: 'agentsam', name: 'agentsam-knowledge', service: 'job_engine' },
172
+ domain: 'knowledge',
173
+ stage: 'recovery',
174
+ });
175
+ db.prepare("UPDATE jobs SET status=CASE WHEN attempts>=3 THEN 'failed' ELSE 'queued' END, error=CASE WHEN attempts>=3 THEN ? ELSE NULL END, failure_json=CASE WHEN attempts>=3 THEN ? ELSE NULL END WHERE status='running'").run(
176
+ interruptedFailure.message,
177
+ JSON.stringify(interruptedFailure),
178
+ );
107
179
 
108
180
  let child = null;
109
181
  let closing = false;
@@ -120,11 +192,17 @@ export function createKnowledgeJobEngine({
120
192
  }
121
193
  if (TERMINAL_STATUSES.has(job.status)) watchers.delete(job.id);
122
194
  };
123
- const updateStatus = (id, status, { result = null, error = null } = {}) => {
124
- db.prepare('UPDATE jobs SET status=?,result=?,error=?,updated_at=? WHERE id=?').run(
195
+ const updateStatus = (id, status, { result = null, failure = null, error = null } = {}) => {
196
+ const normalizedFailure = failure
197
+ ? normalizeError(failure, { source: { kind: 'agentsam', name: 'agentsam-knowledge', service: 'job_engine' }, domain: 'knowledge', stage: 'execute' })
198
+ : error
199
+ ? createErrorEnvelope({ reason: ERROR_REASON.EXECUTION_FAILED, message: error, source: { kind: 'agentsam', name: 'agentsam-knowledge', service: 'job_engine' }, domain: 'knowledge', stage: 'execute' })
200
+ : null;
201
+ db.prepare('UPDATE jobs SET status=?,result=?,error=?,failure_json=?,updated_at=? WHERE id=?').run(
125
202
  status,
126
203
  result === null ? null : JSON.stringify(result),
127
- error,
204
+ normalizedFailure?.message || null,
205
+ normalizedFailure ? JSON.stringify(normalizedFailure) : null,
128
206
  new Date().toISOString(),
129
207
  id,
130
208
  );
@@ -145,15 +223,49 @@ export function createKnowledgeJobEngine({
145
223
  child = fork(workerPath, [], { execArgv: [], stdio: ['ignore', 'ignore', 'ignore', 'ipc'], env: { ...process.env, GIT_OPTIONAL_LOCKS: '0' } });
146
224
  const timer = setTimeout(() => { timedOut = true; child?.kill('SIGKILL'); }, jobTimeoutMs);
147
225
  child.once('message', value => { response = value; });
148
- child.once('error', () => { response = { ok: false, error: 'Could not start indexing process.' }; });
226
+ child.once('error', (cause) => {
227
+ response = {
228
+ ok: false,
229
+ failure: createErrorEnvelope({
230
+ reason: ERROR_REASON.INTERNAL_DEPENDENCY_FAILED,
231
+ message: 'Could not start indexing process.',
232
+ source: { kind: 'agentsam', name: 'agentsam-knowledge', service: 'job_worker' },
233
+ domain: 'knowledge',
234
+ stage: 'spawn',
235
+ native: { code: cause?.code || null, exception_type: cause?.name || null, stack: cause?.stack || null },
236
+ }),
237
+ };
238
+ });
149
239
  child.once('close', () => {
150
240
  clearTimeout(timer);
151
241
  child = null;
152
242
  if (!closing) {
153
243
  const ok = response?.ok && !timedOut;
244
+ let failure = null;
245
+ if (!ok) {
246
+ if (timedOut) {
247
+ failure = createErrorEnvelope({
248
+ reason: ERROR_REASON.EXECUTION_TIMEOUT,
249
+ message: 'Knowledge job exceeded its time limit; narrow the scope and retry.',
250
+ source: { kind: 'runtime', name: 'agentsam-knowledge-worker' },
251
+ domain: 'knowledge',
252
+ stage: 'execute',
253
+ });
254
+ } else if (response?.failure) {
255
+ failure = normalizeError(response.failure, { source: { kind: 'agentsam', name: 'agentsam-knowledge', service: 'job_worker' }, domain: 'knowledge', stage: 'execute' });
256
+ } else {
257
+ failure = createErrorEnvelope({
258
+ reason: ERROR_REASON.EXECUTION_FAILED,
259
+ message: response?.error || 'Indexing process exited unexpectedly.',
260
+ source: { kind: 'agentsam', name: 'agentsam-knowledge', service: 'job_worker' },
261
+ domain: 'knowledge',
262
+ stage: 'execute',
263
+ });
264
+ }
265
+ }
154
266
  updateStatus(row.id, ok ? 'completed' : 'failed', {
155
267
  result: ok ? response.result : null,
156
- error: ok ? null : timedOut ? 'Job exceeded its time limit; narrow the scope.' : response?.error || 'Indexing process exited unexpectedly.',
268
+ failure,
157
269
  });
158
270
  }
159
271
  pumping = false;
@@ -162,7 +274,17 @@ export function createKnowledgeJobEngine({
162
274
  const payload = JSON.parse(row.payload);
163
275
  const registered = registry[payload.request.repository];
164
276
  if (!registered || registered.config.repository_id !== payload.config.repository_id || fingerprint(registered.config.scope) !== payload.registered_scope || (!allowEmbeddings && ((payload.request.embed && payload.request.operation !== 'plan') || payload.request.semantic))) {
165
- response = { ok: false, error: 'Repository registration changed; resubmit this job.' };
277
+ response = {
278
+ ok: false,
279
+ failure: createErrorEnvelope({
280
+ reason: ERROR_REASON.REPOSITORY_CHANGED,
281
+ message: 'Repository registration changed; resubmit this job.',
282
+ source: { kind: 'agentsam', name: 'agentsam-knowledge', service: 'repository_registry' },
283
+ domain: 'repository',
284
+ stage: 'execute',
285
+ resource: { type: 'repository', id: payload.config.repository_id || null },
286
+ }),
287
+ };
166
288
  child.kill();
167
289
  return;
168
290
  }
@@ -3,12 +3,27 @@ import { openSqliteStore } from '../stores/sqlite.js';
3
3
  import { createGeminiEmbedder } from '../providers/gemini.js';
4
4
  import { inventory } from '../source.js';
5
5
  import { scopeKey } from '../config.js';
6
+ import {
7
+ AgentSamError,
8
+ ERROR_REASON,
9
+ createErrorEnvelope,
10
+ normalizeError,
11
+ } from '../../errors/index.js';
6
12
 
7
13
  // Parsing and vector ranking run in a child process, keeping HTTP acceptance responsive.
8
14
  process.once('message', async ({ root, config, filename, request, maxFiles }) => {
9
15
  let store;
10
16
  try {
11
- if (request.operation !== 'search' && inventory(root, config.scope).length > maxFiles) throw new Error(`Scope exceeds ${maxFiles} files; choose a smaller include set.`);
17
+ if (request.operation !== 'search' && inventory(root, config.scope).length > maxFiles) throw new AgentSamError(createErrorEnvelope({
18
+ reason: ERROR_REASON.INPUT_OUT_OF_RANGE,
19
+ message: `Scope exceeds ${maxFiles} files; choose a smaller include set.`,
20
+ source: { kind: 'user', name: 'knowledge_request' },
21
+ resolution_owner: 'user',
22
+ domain: 'knowledge',
23
+ stage: 'inventory',
24
+ remediation: { action: 'reduce_scope', message: 'Narrow the repository include scope and retry.' },
25
+ resource: { type: 'repository', id: config.repository_id || null },
26
+ }));
12
27
  store = await openSqliteStore(filename);
13
28
  const embedder = request.operation !== 'plan' && (request.embed || request.semantic) ? createGeminiEmbedder({ apiKey: process.env.GEMINI_API_KEY }) : undefined;
14
29
  let result;
@@ -18,7 +33,15 @@ process.once('message', async ({ root, config, filename, request, maxFiles }) =>
18
33
  const generation = request.generation_id ? await store.getGeneration(scopeKey(config), request.generation_id) : await store.active(scopeKey(config));
19
34
  const under = (file, selection) => selection === '.' || file === selection || file.startsWith(selection + '/');
20
35
  if (generation?.files.some(file => !config.scope.include.some(p => under(file.path, p)) || config.scope.exclude.some(p => under(file.path, p)))) {
21
- throw new Error('Generation exceeds the requested scope; select a matching scope or reindex.');
36
+ throw new AgentSamError(createErrorEnvelope({
37
+ reason: ERROR_REASON.PRECONDITION_FAILED,
38
+ message: 'Generation exceeds the requested scope; select a matching scope or reindex.',
39
+ source: { kind: 'user', name: 'knowledge_request' },
40
+ domain: 'knowledge',
41
+ stage: 'search',
42
+ remediation: { action: 'change_configuration', message: 'Select a matching indexed scope or reindex the requested scope.' },
43
+ resource: { type: 'repository', id: config.repository_id || null },
44
+ }));
22
45
  }
23
46
  result = await retrieve({ store, config, text: request.query, semantic: request.semantic, embedder,
24
47
  topK: request.top_k, tokenBudget: request.token_budget, generationId: request.generation_id });
@@ -27,8 +50,14 @@ process.once('message', async ({ root, config, filename, request, maxFiles }) =>
27
50
  process.send({ ok: true, result }, () => process.exit(0));
28
51
  } catch (error) {
29
52
  await store?.close();
30
- // Provider error strings may include sensitive request details. Never persist them.
31
- const message = request.embed || request.semantic ? 'Embedding job failed; check provider configuration, budgets, and availability.' : String(error.message).slice(0, 500);
32
- process.send({ ok: false, error: message }, () => process.exit(1));
53
+ const failure = normalizeError(error, {
54
+ source: { kind: 'agentsam', name: 'agentsam-knowledge', service: 'job_worker' },
55
+ domain: 'knowledge',
56
+ stage: request.embed || request.semantic ? 'embedding' : request.operation || 'execute',
57
+ message: request.embed || request.semantic
58
+ ? 'Embedding job failed; inspect the canonical failure for provider/configuration details.'
59
+ : undefined,
60
+ });
61
+ process.send({ ok: false, failure }, () => process.exit(1));
33
62
  }
34
63
  });
@@ -4,6 +4,7 @@ import path from 'node:path';
4
4
  import { fileURLToPath } from 'node:url';
5
5
  import { createBearerTokenVerifier } from './auth.js';
6
6
  import { createKnowledgeJobEngine, serviceError } from './job-engine.js';
7
+ import { normalizeError, toHttpError } from '../../errors/index.js';
7
8
 
8
9
  async function readBody(req) {
9
10
  const chunks = [];
@@ -44,7 +45,15 @@ export async function startKnowledgeHttpServer({ engine, token, verifyToken, por
44
45
  const { job, created } = engine.submitJob(await readBody(req), { idempotencyKey: req.headers['idempotency-key'] });
45
46
  return send(created ? 202 : 200, job);
46
47
  } catch (error) {
47
- if (!res.writableEnded) send(error.status || 500, { error: error.status ? error.message : 'Service request failed.' });
48
+ if (!res.writableEnded) {
49
+ const envelope = normalizeError(error, {
50
+ source: { kind: 'agentsam', name: 'agentsam-knowledge', service: 'http_server' },
51
+ domain: 'knowledge',
52
+ stage: 'request',
53
+ });
54
+ const httpError = toHttpError(envelope);
55
+ send(httpError.status, httpError.body);
56
+ }
48
57
  }
49
58
  });
50
59
  server.requestTimeout = 15000;
@@ -0,0 +1,77 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { CONFIG_PATH, readConfig, validateConfig, defaultConfig } from './config.js';
4
+ import { findCliProjectRoot } from '../lib/cli-preferences.js';
5
+ import { runtimeDatabasePath } from '../local/runtime-store.js';
6
+ import { getRepositoryId, portableRepositoryIdFromGit, tryReadProjectConfig } from '../lib/project-config.js';
7
+
8
+ // Configuration evidence only. No connection probes, credential reads, or schema writes.
9
+ export async function discoverProjectStores(cwd, env = process.env) {
10
+ const root = findCliProjectRoot(cwd);
11
+ const config = fs.existsSync(path.join(root, CONFIG_PATH)) ? readConfig(root) : null;
12
+ const candidates = [
13
+ { id: 'runtime:sqlite', driver: 'sqlite', role: 'runtime', path: runtimeDatabasePath(root), selected: true },
14
+ { id: 'knowledge:sqlite', driver: 'sqlite', role: 'knowledge', path: path.join(root, '.agentsam/knowledge/index.sqlite'), selected: !config || config.storage.driver === 'sqlite', selectable: true },
15
+ ];
16
+ const envNames = new Set(['AGENTSAM_DATABASE_URL', 'DATABASE_URL', 'POSTGRES_URL', config?.storage?.connection_env].filter(Boolean));
17
+ for (const name of envNames) {
18
+ if (!Object.hasOwn(env, name) && name !== config?.storage?.connection_env) continue;
19
+ candidates.push({ id: `knowledge:postgres:${name}`, driver: 'postgres', role: 'knowledge', connection_env: name, configured: Boolean(env[name]), selected: config?.storage?.driver === 'postgres' && config.storage.connection_env === name, selectable: true });
20
+ }
21
+ const warnings = [];
22
+ let visited = 0;
23
+ const skip = new Set(['node_modules', '.git', '.agentsam', '.output', 'dist', 'build', 'vendor', '.wrangler']);
24
+ const configs = [];
25
+ function scan(dir, depth) {
26
+ if (depth > 5 || visited >= 4000) return;
27
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
28
+ if (++visited >= 4000) break;
29
+ if (entry.isSymbolicLink() || skip.has(entry.name)) continue;
30
+ const file = path.join(dir, entry.name);
31
+ if (entry.isDirectory()) scan(file, depth + 1);
32
+ else if (['wrangler.json', 'wrangler.jsonc'].includes(entry.name)) configs.push(file);
33
+ else if (entry.name === 'wrangler.toml') warnings.push(`${path.relative(root, file)}: TOML discovery is not implemented; inspect this configuration explicitly.`);
34
+ }
35
+ }
36
+ scan(root, 0);
37
+ if (visited >= 4000) warnings.push('Discovery reached its 4000-entry bound; inspect additional config paths explicitly.');
38
+ if (configs.length) {
39
+ const { parseConfigFileTextToJson } = await import('typescript');
40
+ for (const file of configs) {
41
+ const source = path.relative(root, file);
42
+ if (fs.statSync(file).size > 1024 * 1024) { warnings.push(`${source}: configuration too large`); continue; }
43
+ const parsed = parseConfigFileTextToJson(file, fs.readFileSync(file, 'utf8'));
44
+ if (parsed.error) { warnings.push(`${source}: invalid JSONC`); continue; }
45
+ const add = (cfg, environment = null) => {
46
+ for (const [key, driver, label] of [['d1_databases', 'd1', 'database_name'], ['hyperdrive', 'postgres-hyperdrive', 'id'], ['r2_buckets', 'r2', 'bucket_name']]) {
47
+ for (const binding of Array.isArray(cfg?.[key]) ? cfg[key] : []) {
48
+ candidates.push({ id: `${source}:${environment || 'default'}:${binding.binding}`, driver, role: 'application', binding: binding.binding, name: binding[label], source, environment, selectable: false, status: 'declared; connectivity not verified' });
49
+ }
50
+ }
51
+ };
52
+ add(parsed.config);
53
+ for (const [environment, cfg] of Object.entries(parsed.config?.env || {})) add(cfg, environment);
54
+ }
55
+ }
56
+ return { root, candidates, warnings, knowledge_config: CONFIG_PATH };
57
+ }
58
+
59
+ export function selectKnowledgeStore(cwd, driver, connectionEnv) {
60
+ const root = findCliProjectRoot(cwd);
61
+ if (!['sqlite', 'postgres'].includes(driver)) throw new Error('knowledge_store_adapter_unavailable: choose sqlite or postgres; D1 application bindings retain their existing authority');
62
+ const filename = path.join(root, CONFIG_PATH);
63
+ let config;
64
+ if (fs.existsSync(filename)) config = readConfig(root);
65
+ else {
66
+ const repositoryId = getRepositoryId(tryReadProjectConfig(root)) || portableRepositoryIdFromGit(root);
67
+ if (!repositoryId) throw new Error('repository_identity_required: run agentsam init . --yes first');
68
+ config = defaultConfig({ repositoryId });
69
+ }
70
+ config.storage = driver === 'sqlite' ? { driver } : { driver, connection_env: connectionEnv || 'AGENTSAM_DATABASE_URL' };
71
+ config = validateConfig(config);
72
+ fs.mkdirSync(path.dirname(filename), { recursive: true, mode: 0o700 });
73
+ const temp = `${filename}.${process.pid}.tmp`;
74
+ fs.writeFileSync(temp, JSON.stringify(config, null, 2) + '\n', { mode: 0o600 });
75
+ fs.renameSync(temp, filename);
76
+ return { storage: config.storage, config: CONFIG_PATH, next: driver === 'sqlite' ? 'agentsam index run' : 'agentsam index setup-store', note: 'Selection saved. Existing data remains in its original store; no migration or connection probe ran.' };
77
+ }
@@ -1,14 +1,28 @@
1
1
  import fs from 'node:fs';
2
2
  import os from 'node:os';
3
3
  import path from 'node:path';
4
- import { resolveSdkKey } from '../../packages/identity/src/contracts/auth-config.js';
4
+ import { isApiKey, resolveApiKey } from '../../packages/identity/src/contracts/auth-config.js';
5
5
 
6
- export const ACCOUNT_SESSION_SCHEMA = 'agentsam-account-session-v1';
6
+ export const ACCOUNT_SESSION_SCHEMA = 'agentsam-account-session-v3';
7
+ const LEGACY_ACCOUNT_SESSION_SCHEMA = 'agentsam-account-session-v2';
7
8
 
8
9
  function clean(value) { return value == null ? '' : String(value).trim(); }
9
10
  function homeDirectory(options = {}) {
10
11
  return path.resolve(clean(options.home) || clean(options.env?.HOME) || clean(options.env?.USERPROFILE) || os.homedir());
11
12
  }
13
+ function isoOrNull(value) {
14
+ const raw = clean(value);
15
+ if (!raw) return null;
16
+ const ms = Date.parse(raw);
17
+ return Number.isFinite(ms) ? new Date(ms).toISOString() : null;
18
+ }
19
+ function expiresAtFrom(session = {}, nowMs = Date.now()) {
20
+ const explicit = isoOrNull(session.expires_at);
21
+ if (explicit) return explicit;
22
+ const expiresIn = Number(session.expires_in);
23
+ if (!Number.isFinite(expiresIn) || expiresIn <= 0) return null;
24
+ return new Date(nowMs + (expiresIn * 1000)).toISOString();
25
+ }
12
26
 
13
27
  export function accountSessionPath(options = {}) {
14
28
  return path.join(homeDirectory(options), '.agentsam', 'auth', 'session.json');
@@ -22,17 +36,24 @@ export function readAccountSession(options = {}) {
22
36
  if (!stat.isFile()) return null;
23
37
  if (process.platform !== 'win32' && (stat.mode & 0o077) !== 0) return null;
24
38
  const parsed = JSON.parse(fs.readFileSync(filename, 'utf8'));
25
- if (parsed?.schema_version !== ACCOUNT_SESSION_SCHEMA) return null;
26
- const token = clean(parsed.sdk_key);
27
- if (!token.startsWith('sdk_')) return null;
39
+ if (![ACCOUNT_SESSION_SCHEMA, LEGACY_ACCOUNT_SESSION_SCHEMA].includes(parsed?.schema_version)) return null;
40
+ const accessToken = clean(parsed.access_token);
41
+ const refreshToken = clean(parsed.refresh_token);
42
+ if (!accessToken || isApiKey(accessToken) || (refreshToken && isApiKey(refreshToken))) return null;
28
43
  return {
29
44
  schema_version: ACCOUNT_SESSION_SCHEMA,
30
- sdk_key: token,
45
+ access_token: accessToken,
46
+ refresh_token: refreshToken || null,
47
+ token_type: clean(parsed.token_type) || 'Bearer',
48
+ scope: clean(parsed.scope) || null,
49
+ expires_at: isoOrNull(parsed.expires_at),
50
+ client_id: clean(parsed.client_id) || null,
31
51
  user_id: clean(parsed.user_id) || null,
32
52
  account_id: clean(parsed.account_id) || null,
33
53
  email: clean(parsed.email) || null,
34
- created_at: clean(parsed.created_at) || null,
35
- updated_at: clean(parsed.updated_at) || null,
54
+ created_at: isoOrNull(parsed.created_at),
55
+ updated_at: isoOrNull(parsed.updated_at),
56
+ migrated_from: parsed.schema_version === LEGACY_ACCOUNT_SESSION_SCHEMA ? LEGACY_ACCOUNT_SESSION_SCHEMA : null,
36
57
  };
37
58
  } catch {
38
59
  return null;
@@ -40,25 +61,38 @@ export function readAccountSession(options = {}) {
40
61
  }
41
62
 
42
63
  export function saveAccountSession(session = {}, options = {}) {
43
- const token = clean(session.sdk_key || session.access_token);
44
- if (!token.startsWith('sdk_')) throw new Error('account_session_sdk_key_required');
64
+ const accessToken = clean(session.access_token);
65
+ const suppliedRefresh = clean(session.refresh_token);
66
+ if (!accessToken || isApiKey(accessToken) || (suppliedRefresh && isApiKey(suppliedRefresh))) {
67
+ throw new Error('account_browser_oauth_session_required');
68
+ }
69
+
45
70
  const filename = accountSessionPath(options);
46
71
  const dir = path.dirname(filename);
47
72
  fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
48
73
  if (process.platform !== 'win32') {
49
74
  try { fs.chmodSync(dir, 0o700); } catch { /* best effort */ }
50
75
  }
76
+
51
77
  const previous = readAccountSession(options);
52
- const now = new Date().toISOString();
78
+ const nowMs = Number.isFinite(Number(options.nowMs)) ? Number(options.nowMs) : Date.now();
79
+ const now = new Date(nowMs).toISOString();
80
+ const preserveRefreshToken = options.preserveRefreshToken !== false;
53
81
  const value = {
54
82
  schema_version: ACCOUNT_SESSION_SCHEMA,
55
- sdk_key: token,
83
+ access_token: accessToken,
84
+ refresh_token: suppliedRefresh || (preserveRefreshToken ? previous?.refresh_token : null) || null,
85
+ token_type: clean(session.token_type) || previous?.token_type || 'Bearer',
86
+ scope: clean(session.scope) || previous?.scope || null,
87
+ expires_at: expiresAtFrom(session, nowMs),
88
+ client_id: clean(session.client_id) || previous?.client_id || null,
56
89
  user_id: clean(session.user_id) || previous?.user_id || null,
57
90
  account_id: clean(session.account_id) || previous?.account_id || null,
58
91
  email: clean(session.email) || previous?.email || null,
59
92
  created_at: previous?.created_at || now,
60
93
  updated_at: now,
61
94
  };
95
+
62
96
  const temp = `${filename}.${process.pid}.tmp`;
63
97
  fs.writeFileSync(temp, `${JSON.stringify(value, null, 2)}\n`, { mode: 0o600 });
64
98
  if (process.platform !== 'win32') {
@@ -75,24 +109,65 @@ export function clearAccountSession(options = {}) {
75
109
  return true;
76
110
  }
77
111
 
78
- export function resolveAccountSdkKey(options = {}) {
112
+ export function isBrowserSessionExpired(session, options = {}) {
113
+ const expiresAt = Date.parse(clean(session?.expires_at));
114
+ if (!Number.isFinite(expiresAt)) return false;
115
+ const nowMs = Number.isFinite(Number(options.nowMs)) ? Number(options.nowMs) : Date.now();
116
+ const skewMs = Number.isFinite(Number(options.skewMs)) ? Number(options.skewMs) : 60_000;
117
+ return expiresAt <= (nowMs + Math.max(0, skewMs));
118
+ }
119
+
120
+ export function resolveAccountApiKey(options = {}) {
79
121
  const env = options.env || process.env;
80
122
  const explicit = clean(options.explicit);
81
- const fromEnv = resolveSdkKey(env, explicit);
82
- if (fromEnv) return { value: fromEnv, source: explicit ? 'explicit' : 'environment' };
83
- const session = readAccountSession({ ...options, env });
84
- return session?.sdk_key
85
- ? { value: session.sdk_key, source: 'agentsam_account_session', session }
86
- : { value: '', source: null, session: null };
123
+ const value = resolveApiKey(env, explicit);
124
+ if (!value) return { value: '', source: null, kind: null };
125
+ if (!isApiKey(value)) return { value: '', source: explicit ? 'explicit' : 'environment', kind: 'api_key', error: 'invalid_api_key_prefix' };
126
+ return { value, source: explicit ? 'explicit' : 'environment', kind: 'api_key' };
127
+ }
128
+
129
+ export function resolveBrowserSessionCredential(options = {}) {
130
+ const session = readAccountSession(options);
131
+ if (!session?.access_token) return { value: '', source: null, kind: null, session: null, expired: false };
132
+ const expired = isBrowserSessionExpired(session, options);
133
+ return {
134
+ value: expired ? '' : session.access_token,
135
+ source: 'agentsam_browser_oauth',
136
+ kind: 'browser_oauth',
137
+ session,
138
+ expired,
139
+ error: expired ? 'browser_oauth_session_expired' : null,
140
+ };
141
+ }
142
+
143
+ /**
144
+ * Synchronous authority snapshot kept for low-level compatibility.
145
+ * Runtime SDK calls should use resolveAccountAuthority() from auth.js so expired
146
+ * OAuth sessions can refresh before a request is sent.
147
+ */
148
+ export function resolveAccountAuth(options = {}) {
149
+ const apiKey = resolveAccountApiKey(options);
150
+ if (apiKey.value) return apiKey;
151
+ if (clean(options.explicit) && apiKey.error) return apiKey;
152
+ const browser = resolveBrowserSessionCredential(options);
153
+ if (browser.value) {
154
+ return apiKey.error ? { ...browser, fallback_error: apiKey.error } : browser;
155
+ }
156
+ if (browser.error) return browser;
157
+ return apiKey.error ? apiKey : browser;
87
158
  }
88
159
 
89
160
  export function describeAccountSession(options = {}) {
90
- const resolved = resolveAccountSdkKey(options);
161
+ const session = readAccountSession(options);
91
162
  return {
92
- configured: Boolean(resolved.value),
93
- source: resolved.source,
94
- user_id: resolved.session?.user_id || null,
95
- account_id: resolved.session?.account_id || null,
96
- email: resolved.session?.email || null,
163
+ configured: Boolean(session?.access_token),
164
+ source: session?.access_token ? 'agentsam_browser_oauth' : null,
165
+ kind: session?.access_token ? 'browser_oauth' : null,
166
+ refreshable: Boolean(session?.refresh_token),
167
+ expires_at: session?.expires_at || null,
168
+ expired: session ? isBrowserSessionExpired(session, options) : false,
169
+ user_id: session?.user_id || null,
170
+ account_id: session?.account_id || null,
171
+ email: session?.email || null,
97
172
  };
98
173
  }
@@ -6,6 +6,9 @@ import { findProjectRules } from './project-rules.js';
6
6
  export const AGENT_RUNTIME_FILENAME = 'AGENTSAM.md';
7
7
  export const AGENT_INSTRUCTION_PRECEDENCE = Object.freeze(['AGENTSAM.md', '.agentsamrules']);
8
8
 
9
+ /** Provider/editor adapters that must redirect to AGENTSAM.md — never compiled as policy. */
10
+ export const AGENT_INSTRUCTION_COMPAT_SHIMS = Object.freeze(['AGENTS.md', 'CLAUDE.md']);
11
+
9
12
  function sha256(value) {
10
13
  return `sha256:${createHash('sha256').update(value).digest('hex')}`;
11
14
  }