@inneranimalmedia/agentsam-sdk 2.6.2 → 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 (497) 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/AUTORAG.md +58 -0
  17. package/docs/BRAND_INTELLIGENCE.md +30 -0
  18. package/docs/CLI_SHELL.md +4 -2
  19. package/docs/CMS_CONTEXTUAL_COMPOSER.md +38 -0
  20. package/docs/MERKLE.md +4 -0
  21. package/docs/PROJECT_CONFIG.md +3 -0
  22. package/docs/REPOSITORY_KNOWLEDGE.md +2 -0
  23. package/docs/THEME_REFINERY.md +120 -0
  24. package/docs/architecture/PROVIDER-TOOLS-AND-COMPACTION.md +60 -0
  25. package/docs/architecture/STORAGE.md +87 -0
  26. package/docs/cad-project-tools.md +69 -0
  27. package/docs/cms-scaffolding-pattern-reference.md +73 -0
  28. package/docs/plans/AGENTSAM-INTERACTIVE-UI-REQUIREMENTS-codex-tui-20260919.md +113 -0
  29. package/docs/plans/AGENTSAM-INTERACTIVE-UI-REQUIREMENTS.md +85 -0
  30. package/docs/plans/AGENTSAM-MCP-CLIENT-2026-09-19.md +181 -0
  31. package/docs/plans/ASBD-PORTABLE-WORKGRAPH-UI-DEFERRED.md +34 -0
  32. package/docs/plans/ASTRA-BRIEF-2026-09-18.md +258 -0
  33. package/docs/plans/MULTI-AGENT-SPRINTS-2026-09-19.md +373 -0
  34. package/docs/plans/NEXT-AGENT-HANDOFF.md +167 -0
  35. package/docs/plans/RECONCILIATION-2026-09-19.md +178 -0
  36. package/docs/plugins.md +43 -0
  37. package/docs/tools/README.md +57 -0
  38. package/docs/tools/agent-and-orchestration.md +49 -0
  39. package/docs/tools/browser-and-research.md +46 -0
  40. package/docs/tools/cloudflare-platform.md +32 -0
  41. package/docs/tools/cms.md +25 -0
  42. package/docs/tools/communications.md +41 -0
  43. package/docs/tools/database-and-storage.md +62 -0
  44. package/docs/tools/design-and-media.md +64 -0
  45. package/docs/tools/filesystem-and-code.md +55 -0
  46. package/docs/tools/github.md +56 -0
  47. package/docs/tools/integrations-and-misc.md +16 -0
  48. package/docs/tools/memory.md +21 -0
  49. package/docs/tools/terminal-and-execution.md +29 -0
  50. package/docs/tools/tickets-and-platform.md +30 -0
  51. package/migrations/d1/0001_agentsam_plugin_runtime.sql +177 -0
  52. package/migrations/d1/0002_agentsam_ticket_ownership.sql +8 -0
  53. package/migrations/d1/0002_dynamic_model_policies.sql +23 -0
  54. package/migrations/d1/0003_expand_tool_handler_families.sql +18 -0
  55. package/migrations/d1/0004_project_aware_retrieval_lanes.sql +24 -0
  56. package/migrations/d1/0005_portable_knowledge_identity.sql +104 -0
  57. package/migrations/d1/0006_repair_ops_trail_account_scope.sql +14 -0
  58. package/migrations/d1/0007_repair_ops_trail_agent_run_account.sql +13 -0
  59. package/migrations/d1/0008_backfill_knowledge_run_legacy_tenant.sql +14 -0
  60. package/migrations/d1/0009_normalize_cloudflare_plugin_installations.sql +137 -0
  61. package/migrations/runtime/0001_cli_runtime.sql +67 -0
  62. package/migrations/runtime/0002_project_sessions.sql +15 -0
  63. package/migrations/runtime/0003_provider_continuations.sql +8 -0
  64. package/package.json +92 -12
  65. package/packages/agentsam-brand/README.md +21 -0
  66. package/packages/agentsam-brand/package.json +22 -0
  67. package/packages/agentsam-brand/src/contract.js +59 -0
  68. package/packages/agentsam-brand/src/extract.js +126 -0
  69. package/packages/agentsam-brand/src/goap-actions.js +73 -0
  70. package/packages/agentsam-brand/src/index.js +48 -0
  71. package/packages/agentsam-brand/src/plan.js +115 -0
  72. package/packages/agentsam-brand/src/resolve.js +139 -0
  73. package/packages/agentsam-brand/src/scan.js +250 -0
  74. package/packages/agentsam-brand/test/brand-scan.test.mjs +106 -0
  75. package/packages/agentsam-contracts/README.md +23 -0
  76. package/packages/agentsam-contracts/package.json +32 -0
  77. package/packages/agentsam-contracts/src/adapter.ts +25 -0
  78. package/packages/agentsam-contracts/src/agent.ts +35 -0
  79. package/packages/agentsam-contracts/src/artifacts.ts +33 -0
  80. package/packages/agentsam-contracts/src/authority.ts +29 -0
  81. package/packages/agentsam-contracts/src/context.ts +16 -0
  82. package/packages/agentsam-contracts/src/errors.ts +46 -0
  83. package/packages/agentsam-contracts/src/events.ts +47 -0
  84. package/packages/agentsam-contracts/src/execution.ts +50 -0
  85. package/packages/agentsam-contracts/src/hooks.ts +40 -0
  86. package/packages/agentsam-contracts/src/identity.ts +16 -0
  87. package/packages/agentsam-contracts/src/index.ts +14 -0
  88. package/packages/agentsam-contracts/src/models.ts +9 -0
  89. package/packages/agentsam-contracts/src/providers.ts +33 -0
  90. package/packages/agentsam-contracts/src/repository.ts +64 -0
  91. package/packages/agentsam-contracts/src/tools.ts +98 -0
  92. package/packages/agentsam-contracts/test/contracts.test.mjs +16 -0
  93. package/packages/agentsam-contracts/test/errors-catalog.test.mjs +25 -0
  94. package/packages/agentsam-contracts/test/repository.test.mjs +18 -0
  95. package/packages/agentsam-contracts/tsconfig.json +12 -0
  96. package/packages/agentsam-errors/package.json +17 -0
  97. package/packages/agentsam-errors/src/adapters/anthropic.js +15 -0
  98. package/packages/agentsam-errors/src/adapters/cad.js +109 -0
  99. package/packages/agentsam-errors/src/adapters/cloudflare.js +21 -0
  100. package/packages/agentsam-errors/src/adapters/cursor.js +4 -0
  101. package/packages/agentsam-errors/src/adapters/device.js +38 -0
  102. package/packages/agentsam-errors/src/adapters/docker.js +28 -0
  103. package/packages/agentsam-errors/src/adapters/gcp.js +14 -0
  104. package/packages/agentsam-errors/src/adapters/github.js +22 -0
  105. package/packages/agentsam-errors/src/adapters/google.js +17 -0
  106. package/packages/agentsam-errors/src/adapters/index.js +55 -0
  107. package/packages/agentsam-errors/src/adapters/internal.js +40 -0
  108. package/packages/agentsam-errors/src/adapters/oauth.js +24 -0
  109. package/packages/agentsam-errors/src/adapters/openai.js +17 -0
  110. package/packages/agentsam-errors/src/adapters/process.js +35 -0
  111. package/packages/agentsam-errors/src/adapters/provider.js +114 -0
  112. package/packages/agentsam-errors/src/envelope.js +186 -0
  113. package/packages/agentsam-errors/src/error.js +24 -0
  114. package/packages/agentsam-errors/src/fingerprint.js +35 -0
  115. package/packages/agentsam-errors/src/index.js +10 -0
  116. package/packages/agentsam-errors/src/normalize.js +30 -0
  117. package/packages/agentsam-errors/src/redaction.js +52 -0
  118. package/packages/agentsam-errors/src/render.js +16 -0
  119. package/packages/agentsam-errors/src/retry.js +10 -0
  120. package/packages/agentsam-errors/src/transport.js +52 -0
  121. package/packages/agentsam-errors/src/vocabulary.js +320 -0
  122. package/packages/agentsam-errors/test/envelope.test.mjs +70 -0
  123. package/packages/agentsam-errors/test/providers.test.mjs +99 -0
  124. package/packages/agentsam-errors/test/redaction.test.mjs +21 -0
  125. package/packages/agentsam-errors/test/runtime-cad-device.test.mjs +76 -0
  126. package/packages/agentsam-errors/test/transport.test.mjs +46 -0
  127. package/packages/agentsam-knowledge/package.json +15 -0
  128. package/packages/agentsam-knowledge/src/autorag/index.js +64 -0
  129. package/packages/agentsam-knowledge/src/backends/index.js +26 -0
  130. package/packages/agentsam-knowledge/src/index.js +3 -0
  131. package/packages/agentsam-knowledge/src/providers/index.js +95 -0
  132. package/packages/agentsam-knowledge/test/autorag.test.mjs +42 -0
  133. package/packages/agentsam-nav/README.md +40 -0
  134. package/packages/agentsam-nav/dist/Nav.d.ts +43 -0
  135. package/packages/agentsam-nav/dist/NavCollapsible.d.ts +10 -0
  136. package/packages/agentsam-nav/dist/NavContent.d.ts +2 -0
  137. package/packages/agentsam-nav/dist/NavFooter.d.ts +2 -0
  138. package/packages/agentsam-nav/dist/NavGroup.d.ts +3 -0
  139. package/packages/agentsam-nav/dist/NavHeader.d.ts +2 -0
  140. package/packages/agentsam-nav/dist/NavMenu.d.ts +22 -0
  141. package/packages/agentsam-nav/dist/NavProvider.d.ts +35 -0
  142. package/packages/agentsam-nav/dist/NavTrigger.d.ts +2 -0
  143. package/packages/agentsam-nav/dist/Surfaces.d.ts +41 -0
  144. package/packages/agentsam-nav/dist/browser.d.ts +11 -0
  145. package/packages/agentsam-nav/dist/browser.global.js +132 -0
  146. package/packages/agentsam-nav/dist/browser.js +613 -0
  147. package/packages/agentsam-nav/dist/contracts.d.ts +76 -0
  148. package/packages/agentsam-nav/dist/index.d.ts +11 -0
  149. package/packages/agentsam-nav/dist/index.js +614 -0
  150. package/packages/agentsam-nav/dist/legacy.css +83 -0
  151. package/packages/agentsam-nav/dist/shell.css +113 -0
  152. package/packages/agentsam-nav/dist/theme.css +113 -0
  153. package/packages/agentsam-nav/dist/utils.d.ts +1 -0
  154. package/packages/agentsam-nav/package.json +43 -0
  155. package/packages/agentsam-queue-control/README.md +107 -0
  156. package/packages/agentsam-queue-control/package.json +31 -0
  157. package/packages/agentsam-queue-control/schemas/job-envelope.schema.json +56 -0
  158. package/packages/agentsam-queue-control/src/adapters/cloudflare.js +152 -0
  159. package/packages/agentsam-queue-control/src/adapters/memory.js +38 -0
  160. package/packages/agentsam-queue-control/src/contracts.js +130 -0
  161. package/packages/agentsam-queue-control/src/control-plane.js +141 -0
  162. package/packages/agentsam-queue-control/src/dispatch.js +43 -0
  163. package/packages/agentsam-queue-control/src/index.js +7 -0
  164. package/packages/agentsam-queue-control/src/policy.js +88 -0
  165. package/packages/agentsam-queue-control/src/topology.js +66 -0
  166. package/packages/agentsam-queue-control/test/queue-control.test.mjs +100 -0
  167. package/packages/agentsam-repository/src/goap.js +718 -0
  168. package/packages/agentsam-repository/src/goap.js.bak-20260922011251 +670 -0
  169. package/packages/agentsam-repository/src/index.js +5 -0
  170. package/packages/agentsam-repository/src/merkle/cloudflare-persistence.js +2 -2
  171. package/packages/agentsam-repository/src/tickets.js +184 -0
  172. package/packages/agentsam-repository/src/work-tracking.js +199 -0
  173. package/packages/agentsam-repository/src/workspace-state.js +176 -0
  174. package/packages/agentsam-repository/test/goap-tickets-workspace-state.test.mjs +152 -0
  175. package/packages/connectors/cloudflare/src/index.js +297 -15
  176. package/packages/connectors/cloudflare/src/owner.js +43 -40
  177. package/packages/connectors/cloudflare/src/routes.js +167 -26
  178. package/packages/connectors/cloudflare/tests/connector.test.mjs +112 -2
  179. package/packages/heuristic-theme/README.md +11 -0
  180. package/packages/heuristic-theme/package.json +25 -0
  181. package/packages/heuristic-theme/src/index.js +2 -0
  182. package/packages/heuristic-theme/src/registry.js +36 -0
  183. package/packages/heuristic-theme/src/theme.js +41 -0
  184. package/packages/heuristic-theme/test/theme.test.mjs +26 -0
  185. package/packages/identity/.agentsam/features/oauth-login-portal/agentsam.feature.json +64 -0
  186. package/packages/identity/.agentsam/features/oauth-login-portal/providers.json +96 -0
  187. package/packages/identity/.agentsam/features/oauth-login-portal/resources.json +47 -0
  188. package/packages/identity/.agentsam/features/oauth-login-portal/routes.json +74 -0
  189. package/packages/identity/.agentsam/features/oauth-login-portal/ui.json +35 -0
  190. package/packages/identity/package.json +3 -2
  191. package/packages/identity/src/adapters/cloudflare-d1/ids.js +4 -0
  192. package/packages/identity/src/adapters/cloudflare-d1/index.js +39 -1
  193. package/packages/identity/src/contracts/provider.js +3 -2
  194. package/packages/identity/src/frontend/auth-portal/pages/login.html +7 -0
  195. package/packages/identity/src/index.js +2 -0
  196. package/packages/identity/src/oauth/credentials.js +13 -0
  197. package/packages/identity/src/oauth/iam-platform.js +5 -5
  198. package/packages/identity/src/providers/cloudflare/index.js +19 -0
  199. package/packages/identity/src/providers/cloudflare/mapper.js +21 -0
  200. package/packages/identity/src/providers/cloudflare/oauth.js +48 -0
  201. package/packages/identity/src/providers/cloudflare/profile.js +28 -0
  202. package/packages/identity/src/providers/index.js +18 -2
  203. package/packages/identity/src/server/identity-service.js +13 -3
  204. package/packages/identity/src/server/worker-router.js +63 -8
  205. package/packages/identity/tests/identity-service.test.mjs +15 -0
  206. package/packages/providers/completeful/README.md +38 -0
  207. package/packages/providers/completeful/package.json +29 -0
  208. package/packages/providers/completeful/src/client.js +162 -0
  209. package/packages/providers/completeful/src/events.js +49 -0
  210. package/packages/providers/completeful/src/index.js +22 -0
  211. package/packages/providers/completeful/src/tools.js +579 -0
  212. package/packages/providers/completeful/src/webhooks.js +55 -0
  213. package/packages/providers/completeful/test/provider.test.mjs +196 -0
  214. package/packages/theme-church-site/README.md +10 -0
  215. package/packages/theme-church-site/package.json +30 -0
  216. package/packages/theme-church-site/src/harvest.json +14 -0
  217. package/packages/theme-church-site/src/index.js +84 -0
  218. package/packages/theme-church-site/test/theme.test.mjs +19 -0
  219. package/packages/theme-companions-site/README.md +10 -0
  220. package/packages/theme-companions-site/package.json +30 -0
  221. package/packages/theme-companions-site/src/harvest.json +12 -0
  222. package/packages/theme-companions-site/src/index.js +82 -0
  223. package/packages/theme-companions-site/test/theme.test.mjs +19 -0
  224. package/packages/theme-floors-site/README.md +10 -0
  225. package/packages/theme-floors-site/package.json +30 -0
  226. package/packages/theme-floors-site/src/harvest.json +14 -0
  227. package/packages/theme-floors-site/src/index.js +82 -0
  228. package/packages/theme-floors-site/test/theme.test.mjs +19 -0
  229. package/packages/theme-fuelnfree-site/README.md +10 -0
  230. package/packages/theme-fuelnfree-site/package.json +30 -0
  231. package/packages/theme-fuelnfree-site/src/harvest.json +13 -0
  232. package/packages/theme-fuelnfree-site/src/index.js +81 -0
  233. package/packages/theme-fuelnfree-site/test/theme.test.mjs +19 -0
  234. package/packages/theme-handyman-site/README.md +10 -0
  235. package/packages/theme-handyman-site/package.json +30 -0
  236. package/packages/theme-handyman-site/src/harvest.json +10 -0
  237. package/packages/theme-handyman-site/src/index.js +83 -0
  238. package/packages/theme-handyman-site/test/theme.test.mjs +19 -0
  239. package/packages/theme-insurance-site/README.md +10 -0
  240. package/packages/theme-insurance-site/package.json +30 -0
  241. package/packages/theme-insurance-site/src/harvest.json +10 -0
  242. package/packages/theme-insurance-site/src/index.js +83 -0
  243. package/packages/theme-insurance-site/test/theme.test.mjs +19 -0
  244. package/packages/theme-shinshu-site/README.md +10 -0
  245. package/packages/theme-shinshu-site/package.json +30 -0
  246. package/packages/theme-shinshu-site/src/harvest.json +12 -0
  247. package/packages/theme-shinshu-site/src/index.js +83 -0
  248. package/packages/theme-shinshu-site/test/theme.test.mjs +19 -0
  249. package/packages/work-graph/README.md +49 -0
  250. package/packages/work-graph/package.json +19 -0
  251. package/packages/work-graph/prototype/README.md +32 -0
  252. package/packages/work-graph/prototype/data/demo-workgraph.js +47 -0
  253. package/packages/work-graph/prototype/renderers/timeline-model.js +21 -0
  254. package/packages/work-graph/prototype/renderers/workgraph-runtime.js +38 -0
  255. package/packages/work-graph/prototype-gnantt.html +655 -0
  256. package/packages/work-graph/src/adapters/business/projects.js +23 -0
  257. package/packages/work-graph/src/adapters/engineering/git.js +22 -0
  258. package/packages/work-graph/src/adapters/engineering/mcp.js +22 -0
  259. package/packages/work-graph/src/index.js +76 -0
  260. package/packages/work-graph/src/renderers/gantt-model.js +11 -0
  261. package/packages/work-graph/src/renderers/timeline.js +16 -0
  262. package/packages/work-graph/test/work-graph.test.mjs +37 -0
  263. package/protocol/README.md +12 -0
  264. package/protocol/capabilities/cloudflare-cpu-audit-input.schema.json +30 -6
  265. package/protocol/capabilities/cloudflare-cpu-profile-input.schema.json +18 -4
  266. package/protocol/capabilities/cloudflare-wrangler-native-input.schema.json +59 -10
  267. package/protocol/capabilities/knowledge-search-input.schema.json +35 -0
  268. package/protocol/capabilities/manifest.json +163 -1
  269. package/protocol/capabilities/repository-audit-input.schema.json +39 -6
  270. package/protocol/capabilities/repository-snapshot-input.schema.json +15 -3
  271. package/protocol/capabilities/terminal-exec-input.schema.json +55 -0
  272. package/protocol/commerce/catalog.v1.json +50 -0
  273. package/protocol/errors/error-catalog.json +164 -0
  274. package/protocol/errors/error-envelope.schema.json +544 -0
  275. package/protocol/features/README.md +57 -0
  276. package/protocol/features/agentsam.feature.v1.schema.json +290 -0
  277. package/protocol/features/catalog.json +65 -0
  278. package/protocol/features/examples/provider-resend.feature.json +17 -0
  279. package/protocol/go/agentsam-go-runtime.v1.json +17 -0
  280. package/protocol/knowledge/LIFECYCLE.md +140 -0
  281. package/protocol/knowledge/README.md +4 -0
  282. package/protocol/presets/catalog.json +128 -19
  283. package/protocol/rpc/v1/errors.proto +24 -0
  284. package/protocol/theme-refinery/d1-reconciliation.md +48 -0
  285. package/protocol/theme-refinery/product-metadata.schema.json +27 -0
  286. package/protocol/theme-refinery/receipts/products-registry-batch-20260924.json +318 -0
  287. package/protocol/theme-refinery/receipts/theme-harvest-20260924.json +472 -0
  288. package/protocol/theme-refinery/reconciliation-receipt.schema.json +83 -0
  289. package/services/cad/server.py +249 -2
  290. package/src/agent/capability-adapter.js +15 -5
  291. package/src/agent/index.js +2 -1
  292. package/src/agent/model-turn.js +51 -0
  293. package/src/agent/responses-runner.js +304 -38
  294. package/src/capabilities/index.js +1 -0
  295. package/src/capabilities/terminal-exec.js +78 -0
  296. package/src/cli.js +117 -9
  297. package/src/cloudflare/index.js +6 -0
  298. package/src/cloudflare/runtime-status.js +393 -0
  299. package/src/cloudflare/wrangler.js +17 -1
  300. package/src/commands/app.js +106 -0
  301. package/src/commands/autorag.js +77 -0
  302. package/src/commands/brand.js +293 -0
  303. package/src/commands/cad.js +1 -0
  304. package/src/commands/connections.js +126 -29
  305. package/src/commands/context-economics.js +8 -0
  306. package/src/commands/db.js +7 -0
  307. package/src/commands/env.js +5 -4
  308. package/src/commands/eval.js +209 -14
  309. package/src/commands/go.js +365 -0
  310. package/src/commands/goap.js +176 -0
  311. package/src/commands/identity-init.js +27 -3
  312. package/src/commands/identity-protocol.js +195 -0
  313. package/src/commands/knowledge.js +64 -5
  314. package/src/commands/mcp.js +341 -0
  315. package/src/commands/merkle-persist.js +3 -1
  316. package/src/commands/merkle.js +18 -3
  317. package/src/commands/models.js +109 -23
  318. package/src/commands/plugins.js +175 -0
  319. package/src/commands/preferences.js +28 -8
  320. package/src/commands/product.js +53 -10
  321. package/src/commands/providers.js +118 -37
  322. package/src/commands/resume.js +9 -5
  323. package/src/commands/runtime-status.js +154 -0
  324. package/src/commands/shell.js +466 -55
  325. package/src/commands/status.js +82 -7
  326. package/src/commands/tunnel.js +228 -195
  327. package/src/commands/whoami.js +78 -6
  328. package/src/context/budget.js +6 -0
  329. package/src/context/index.js +2 -1
  330. package/src/context/project-card.js +75 -0
  331. package/src/errors/contract.js +34 -211
  332. package/src/errors/diagnostic.js +95 -51
  333. package/src/errors/index.js +6 -13
  334. package/src/eval/index.js +6 -0
  335. package/src/eval/live.js +439 -0
  336. package/src/features/resolve.js +242 -0
  337. package/src/go/build.js +108 -0
  338. package/src/go/cloudflare.js +207 -0
  339. package/src/go/contract.js +139 -0
  340. package/src/go/discover.js +96 -0
  341. package/src/go/index.js +13 -0
  342. package/src/go/receipts.js +77 -0
  343. package/src/go/registry.js +223 -0
  344. package/src/go/verify.js +31 -0
  345. package/src/index.js +100 -1
  346. package/src/knowledge/config.js +13 -5
  347. package/src/knowledge/engine.js +23 -8
  348. package/src/knowledge/index.js +1 -0
  349. package/src/knowledge/lane-registry.js +46 -0
  350. package/src/knowledge/providers/gemini.js +48 -8
  351. package/src/knowledge/service/client.js +13 -1
  352. package/src/knowledge/service/grpc-codec.js +156 -53
  353. package/src/knowledge/service/job-engine.js +133 -11
  354. package/src/knowledge/service/job-worker.js +34 -5
  355. package/src/knowledge/service/server.js +10 -1
  356. package/src/knowledge/store-discovery.js +77 -0
  357. package/src/lib/account-session.js +8 -2
  358. package/src/lib/agent-instructions.js +3 -0
  359. package/src/lib/auth.js +7 -3
  360. package/src/lib/cad/blender.js +42 -3
  361. package/src/lib/cad/d1-project-store.js +43 -0
  362. package/src/lib/cad/discovery.js +616 -0
  363. package/src/lib/cad/docker-executor.js +352 -0
  364. package/src/lib/cad/freecad.js +253 -0
  365. package/src/lib/cad/index.js +40 -0
  366. package/src/lib/cad/openscad.js +198 -0
  367. package/src/lib/cad/project-cli.d.ts +2 -0
  368. package/src/lib/cad/project-cli.js +21 -0
  369. package/src/lib/cad/project-contract.d.ts +3 -0
  370. package/src/lib/cad/project-contract.js +1 -0
  371. package/src/lib/cad/project-recipe.js +30 -0
  372. package/src/lib/cad/project-runtime.d.ts +2 -0
  373. package/src/lib/cad/project-runtime.js +53 -0
  374. package/src/lib/cad/project-store.js +25 -0
  375. package/src/lib/cad/project-workflows.js +31 -0
  376. package/src/lib/cad-docker.js +21 -2
  377. package/src/lib/cli-preferences.js +17 -2
  378. package/src/lib/core-client.js +37 -18
  379. package/src/lib/deploy/local-studio.js +6 -5
  380. package/src/lib/dockerize.js +3 -0
  381. package/src/lib/execution-approvals.js +1 -0
  382. package/src/lib/identity-scaffold.js +4 -1
  383. package/src/lib/knowledge-docker.js +9 -1
  384. package/src/lib/local-sessions.js +124 -34
  385. package/src/lib/local-status.js +35 -14
  386. package/src/lib/project-config.js +9 -0
  387. package/src/lib/provider-credentials.js +73 -11
  388. package/src/lib/scaffold/resolve-cloudflare-account.js +37 -0
  389. package/src/lib/scaffold/wizards/cms.js +2 -8
  390. package/src/lib/scaffold/wizards/worker-api.js +2 -8
  391. package/src/lib/slash-commands.js +9 -2
  392. package/src/local/migrations.js +109 -1
  393. package/src/local/runtime-store.js +31 -5
  394. package/src/local/sqlite.js +36 -1
  395. package/src/mcp/authority.js +348 -0
  396. package/src/mcp/client-adapters.js +431 -0
  397. package/src/mcp/client.js +172 -0
  398. package/src/mcp/index.js +47 -0
  399. package/src/mcp/telemetry.js +103 -0
  400. package/src/models/catalog.js +329 -51
  401. package/src/models/discovery.js +24 -4
  402. package/src/models/index.js +2 -0
  403. package/src/models/inventory-core.js +182 -0
  404. package/src/models/policy.js +20 -0
  405. package/src/plugins/cloudflare.js +103 -0
  406. package/src/plugins/completeful.js +69 -0
  407. package/src/plugins/contracts.js +86 -0
  408. package/src/plugins/index.js +11 -0
  409. package/src/plugins/registry.js +207 -0
  410. package/src/plugins/resource-scope.js +45 -0
  411. package/src/plugins/runtime.js +118 -0
  412. package/src/plugins/vectorize.js +31 -0
  413. package/src/progression/engine.js +171 -0
  414. package/src/progression/index.js +1 -0
  415. package/src/providers/cloudflare-chat.js +1 -1
  416. package/src/providers/gemini-generate-content.js +2 -1
  417. package/src/providers/openai-responses.js +45 -16
  418. package/src/providers/tool-schema.js +85 -0
  419. package/src/repository/index.js +29 -0
  420. package/src/rpc/generated/errors_pb.js +961 -1
  421. package/src/security/local-vault.js +415 -0
  422. package/src/security/process.js +20 -4
  423. package/src/status/actions.js +192 -0
  424. package/src/tools/hydrate.js +5 -1
  425. package/src/tools/index.js +7 -0
  426. package/src/tools/redact.js +64 -0
  427. package/src/tools/registry.js +83 -0
  428. package/src/tools/runtime.js +257 -0
  429. package/src/tools/search.js +21 -8
  430. package/src/ui/ansi.js +117 -3
  431. package/src/ui/cli/activity.js +76 -7
  432. package/src/ui/cli/footer.js +110 -9
  433. package/src/ui/cli/help.js +11 -4
  434. package/src/ui/wireframes.js +166 -0
  435. package/test/account-session.test.mjs +28 -0
  436. package/test/apps-scaffold-contract.test.mjs +16 -1
  437. package/test/capabilities.test.mjs +1 -1
  438. package/test/cli/eval-live.test.mjs +219 -0
  439. package/test/cli/go.test.mjs +71 -0
  440. package/test/cli/local-vault-and-provider-setup.test.mjs +268 -0
  441. package/test/cli/mcp-client.test.mjs +245 -0
  442. package/test/cli/runtime-ui.test.mjs +69 -2
  443. package/test/cli/status-actions.test.mjs +88 -0
  444. package/test/cli/wireframes-go-registry.test.mjs +54 -0
  445. package/test/cloudflare-connector.test.mjs +3 -6
  446. package/test/cloudflare-runtime.test.mjs +8 -1
  447. package/test/context.test.mjs +15 -0
  448. package/test/error-diagnostics.test.mjs +9 -0
  449. package/test/fixtures/cad/courtyard-house.json +208 -0
  450. package/test/go/cloudflare-probe.test.mjs +53 -0
  451. package/test/integration/app-command.test.mjs +55 -0
  452. package/test/integration/cad-discovery.test.mjs +158 -0
  453. package/test/integration/cad-docker-executor.test.mjs +249 -0
  454. package/test/integration/cad-execution.test.mjs +184 -0
  455. package/test/integration/cad-project-app.test.mjs +31 -0
  456. package/test/integration/cad-project-d1.test.mjs +25 -0
  457. package/test/integration/cad-project-native.test.mjs +24 -0
  458. package/test/integration/cad-project-workflow.test.mjs +9 -0
  459. package/test/integration/cad-project.test.mjs +82 -0
  460. package/test/integration/cli-help.test.mjs +4 -0
  461. package/test/integration/cms-site-tenancy-contract.test.mjs +256 -0
  462. package/test/integration/core-client.integration.test.mjs +55 -0
  463. package/test/integration/error-runtime-rpc.test.mjs +71 -0
  464. package/test/integration/features-resolve.test.mjs +128 -0
  465. package/test/integration/install-script.test.mjs +107 -0
  466. package/test/integration/inventory-core.test.mjs +53 -0
  467. package/test/integration/plugins-cloudflare.integration.test.mjs +28 -0
  468. package/test/integration/provider-env-cli.test.mjs +1 -1
  469. package/test/integration/runtime-migrations.test.mjs +6 -1
  470. package/test/integration/runtime-status.integration.test.mjs +211 -0
  471. package/test/integration/scaffold-cloudflare.test.mjs +46 -0
  472. package/test/integration/storage-architecture.test.mjs +154 -0
  473. package/test/integration/store-discovery.test.mjs +44 -0
  474. package/test/integration/terminal-exec.integration.test.mjs +86 -0
  475. package/test/integration/tool-runtime.test.mjs +124 -0
  476. package/test/integration/tool-schema.test.mjs +59 -0
  477. package/test/knowledge-service.test.mjs +4 -0
  478. package/test/local-sessions.test.mjs +11 -2
  479. package/test/local-studio-deploy.test.mjs +1 -1
  480. package/test/model-catalog.test.mjs +28 -1
  481. package/test/models.test.mjs +159 -5
  482. package/test/openai-responses.test.mjs +60 -0
  483. package/test/provider-credentials.test.mjs +15 -5
  484. package/test/responses-runner.test.mjs +321 -6
  485. package/test/shell.test.mjs +149 -4
  486. package/test/smoke.mjs +2 -2
  487. package/test/tools-search.test.mjs +33 -0
  488. package/test/unit/website-assets-bindings.test.mjs +60 -0
  489. package/test/whoami-resume.test.mjs +82 -3
  490. package/examples/gorilla-shell/README.md +0 -15
  491. package/src/lib/gorilla-template.js +0 -54
  492. package/templates/gorilla-shell/App.tsx +0 -639
  493. package/templates/gorilla-shell/README.md +0 -34
  494. package/templates/gorilla-shell/index.html +0 -15
  495. package/templates/gorilla-shell/main.jsx +0 -9
  496. package/templates/gorilla-shell/package.json +0 -19
  497. package/templates/gorilla-shell/vite.config.js +0 -21
@@ -0,0 +1,415 @@
1
+ import fs from 'node:fs';
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+ import crypto from 'node:crypto';
5
+ import { spawnSync } from 'node:child_process';
6
+ import { normalizeProviderId, PROVIDER_CREDENTIALS } from '../lib/provider-credentials.js';
7
+
8
+ function homeDirectory(options = {}) {
9
+ return path.resolve(
10
+ options.home ||
11
+ options.env?.HOME ||
12
+ options.env?.USERPROFILE ||
13
+ os.homedir()
14
+ );
15
+ }
16
+
17
+ export function localVaultDirectory(options = {}) {
18
+ return path.join(homeDirectory(options), '.agentsam', 'vault');
19
+ }
20
+
21
+ export function localVaultPath(options = {}) {
22
+ return path.join(localVaultDirectory(options), 'credentials.enc');
23
+ }
24
+
25
+ export function localVaultSaltPath(options = {}) {
26
+ return path.join(localVaultDirectory(options), '.salt');
27
+ }
28
+
29
+ function ensureVaultDirectory(options = {}) {
30
+ const dir = localVaultDirectory(options);
31
+ if (!fs.existsSync(dir)) {
32
+ fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
33
+ if (process.platform !== 'win32') {
34
+ try { fs.chmodSync(dir, 0o700); } catch { /* ignore */ }
35
+ }
36
+ }
37
+ return dir;
38
+ }
39
+
40
+ function getMachineFingerprint() {
41
+ const parts = [
42
+ os.hostname(),
43
+ os.userInfo?.()?.username || process.env.USER || process.env.USERNAME || 'unknown-user',
44
+ os.homedir(),
45
+ process.arch,
46
+ process.platform,
47
+ ];
48
+ return parts.join(':');
49
+ }
50
+
51
+ function getOrCreateSalt(options = {}) {
52
+ ensureVaultDirectory(options);
53
+ const saltFile = localVaultSaltPath(options);
54
+ if (fs.existsSync(saltFile)) {
55
+ try {
56
+ const raw = fs.readFileSync(saltFile);
57
+ if (raw.length === 32) return raw;
58
+ } catch {
59
+ // re-create if unreadable
60
+ }
61
+ }
62
+ const salt = crypto.randomBytes(32);
63
+ fs.writeFileSync(saltFile, salt, { mode: 0o600 });
64
+ if (process.platform !== 'win32') {
65
+ try { fs.chmodSync(saltFile, 0o600); } catch { /* ignore */ }
66
+ }
67
+ return salt;
68
+ }
69
+
70
+ function deriveKey(options = {}) {
71
+ const salt = getOrCreateSalt(options);
72
+ const fingerprint = getMachineFingerprint();
73
+ return crypto.pbkdf2Sync(fingerprint, salt, 100_000, 32, 'sha256');
74
+ }
75
+
76
+ function encryptAes256Gcm(plaintext, aad, key) {
77
+ const iv = crypto.randomBytes(12);
78
+ const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
79
+ cipher.setAAD(Buffer.from(aad, 'utf8'));
80
+ const encrypted = Buffer.concat([cipher.update(Buffer.from(plaintext, 'utf8')), cipher.final()]);
81
+ const tag = cipher.getAuthTag();
82
+ return {
83
+ iv: iv.toString('hex'),
84
+ tag: tag.toString('hex'),
85
+ data: encrypted.toString('hex'),
86
+ };
87
+ }
88
+
89
+ function decryptAes256Gcm(payload, aad, key) {
90
+ if (!payload?.iv || !payload?.tag || !payload?.data) return null;
91
+ const iv = Buffer.from(payload.iv, 'hex');
92
+ const tag = Buffer.from(payload.tag, 'hex');
93
+ const data = Buffer.from(payload.data, 'hex');
94
+ const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);
95
+ decipher.setAAD(Buffer.from(aad, 'utf8'));
96
+ decipher.setAuthTag(tag);
97
+ const decrypted = Buffer.concat([decipher.update(data), decipher.final()]);
98
+ return decrypted.toString('utf8');
99
+ }
100
+
101
+ // --------------------------------------------------------------------------
102
+ // OS Credential Store Adapters
103
+ // --------------------------------------------------------------------------
104
+
105
+ function osStoreReadDarwin(provider) {
106
+ try {
107
+ const res = spawnSync('/usr/bin/security', ['find-generic-password', '-a', `agentsam:${provider}`, '-s', 'agentsam', '-w'], {
108
+ encoding: 'utf8',
109
+ stdio: ['ignore', 'pipe', 'ignore'],
110
+ });
111
+ if (res.status === 0 && res.stdout) {
112
+ const val = res.stdout.trim();
113
+ if (val) return val;
114
+ }
115
+ } catch { /* fallback to local encrypted store */ }
116
+ return null;
117
+ }
118
+
119
+ function osStoreWriteDarwin(provider, secret) {
120
+ try {
121
+ const res = spawnSync('/usr/bin/security', ['add-generic-password', '-a', `agentsam:${provider}`, '-s', 'agentsam', '-w', secret, '-U'], {
122
+ stdio: 'ignore',
123
+ });
124
+ return res.status === 0;
125
+ } catch { return false; }
126
+ }
127
+
128
+ function osStoreDeleteDarwin(provider) {
129
+ try {
130
+ const res = spawnSync('/usr/bin/security', ['delete-generic-password', '-a', `agentsam:${provider}`, '-s', 'agentsam'], {
131
+ stdio: 'ignore',
132
+ });
133
+ return res.status === 0;
134
+ } catch { return false; }
135
+ }
136
+
137
+ function osStoreReadWin32(provider, options = {}) {
138
+ const file = path.join(localVaultDirectory(options), `${provider}.dpapi`);
139
+ if (!fs.existsSync(file)) return null;
140
+ try {
141
+ const script = `
142
+ $bytes = [System.IO.File]::ReadAllBytes('${file.replace(/'/g, "''")}');
143
+ $dec = [System.Security.Cryptography.ProtectedData]::Unprotect($bytes, $null, [System.Security.Cryptography.DataProtectionScope]::CurrentUser);
144
+ [System.Text.Encoding]::UTF8.GetString($dec);
145
+ `;
146
+ const res = spawnSync('powershell.exe', ['-NoProfile', '-NonInteractive', '-Command', script], {
147
+ encoding: 'utf8',
148
+ stdio: ['ignore', 'pipe', 'ignore'],
149
+ });
150
+ if (res.status === 0 && res.stdout) {
151
+ const val = res.stdout.trim();
152
+ if (val) return val;
153
+ }
154
+ } catch { /* fallback */ }
155
+ return null;
156
+ }
157
+
158
+ function osStoreWriteWin32(provider, secret, options = {}) {
159
+ ensureVaultDirectory(options);
160
+ const file = path.join(localVaultDirectory(options), `${provider}.dpapi`);
161
+ try {
162
+ const b64 = Buffer.from(secret, 'utf8').toString('base64');
163
+ const script = `
164
+ $bytes = [System.Convert]::FromBase64String('${b64}');
165
+ $enc = [System.Security.Cryptography.ProtectedData]::Protect($bytes, $null, [System.Security.Cryptography.DataProtectionScope]::CurrentUser);
166
+ [System.IO.File]::WriteAllBytes('${file.replace(/'/g, "''")}', $enc);
167
+ `;
168
+ const res = spawnSync('powershell.exe', ['-NoProfile', '-NonInteractive', '-Command', script], {
169
+ stdio: 'ignore',
170
+ });
171
+ return res.status === 0;
172
+ } catch { return false; }
173
+ }
174
+
175
+ function osStoreDeleteWin32(provider, options = {}) {
176
+ const file = path.join(localVaultDirectory(options), `${provider}.dpapi`);
177
+ if (fs.existsSync(file)) {
178
+ try { fs.unlinkSync(file); return true; } catch { return false; }
179
+ }
180
+ return false;
181
+ }
182
+
183
+ function osStoreReadLinux(provider) {
184
+ try {
185
+ const res = spawnSync('secret-tool', ['lookup', 'service', 'agentsam', 'provider', provider], {
186
+ encoding: 'utf8',
187
+ stdio: ['ignore', 'pipe', 'ignore'],
188
+ });
189
+ if (res.status === 0 && res.stdout) {
190
+ const val = res.stdout.trim();
191
+ if (val) return val;
192
+ }
193
+ } catch { /* fallback */ }
194
+ return null;
195
+ }
196
+
197
+ function osStoreWriteLinux(provider, secret) {
198
+ try {
199
+ const res = spawnSync('secret-tool', ['store', `--label=AgentSam ${provider}`, 'service', 'agentsam', 'provider', provider], {
200
+ input: secret,
201
+ encoding: 'utf8',
202
+ stdio: ['pipe', 'ignore', 'ignore'],
203
+ });
204
+ return res.status === 0;
205
+ } catch { return false; }
206
+ }
207
+
208
+ function osStoreDeleteLinux(provider) {
209
+ try {
210
+ const res = spawnSync('secret-tool', ['clear', 'service', 'agentsam', 'provider', provider], {
211
+ stdio: 'ignore',
212
+ });
213
+ return res.status === 0;
214
+ } catch { return false; }
215
+ }
216
+
217
+ // --------------------------------------------------------------------------
218
+ // Encrypted Local File Store (AES-256-GCM)
219
+ // --------------------------------------------------------------------------
220
+
221
+ function readEncryptedStore(options = {}) {
222
+ const encFile = localVaultPath(options);
223
+ if (!fs.existsSync(encFile)) return { version: 1, secrets: {} };
224
+ try {
225
+ const content = fs.readFileSync(encFile, 'utf8');
226
+ const parsed = JSON.parse(content);
227
+ if (parsed && typeof parsed === 'object' && parsed.secrets) return parsed;
228
+ } catch { /* re-initialize on corrupt file */ }
229
+ return { version: 1, secrets: {} };
230
+ }
231
+
232
+ function writeEncryptedStore(store, options = {}) {
233
+ ensureVaultDirectory(options);
234
+ const encFile = localVaultPath(options);
235
+ const tempFile = `${encFile}.${process.pid}.${Date.now()}.tmp`;
236
+ const json = JSON.stringify({
237
+ version: 1,
238
+ updated_at: new Date().toISOString(),
239
+ secrets: store.secrets || {},
240
+ }, null, 2);
241
+
242
+ fs.writeFileSync(tempFile, json, { mode: 0o600 });
243
+ if (process.platform !== 'win32') {
244
+ try { fs.chmodSync(tempFile, 0o600); } catch { /* ignore */ }
245
+ }
246
+ fs.renameSync(tempFile, encFile);
247
+ if (process.platform !== 'win32') {
248
+ try { fs.chmodSync(encFile, 0o600); } catch { /* ignore */ }
249
+ }
250
+ }
251
+
252
+ // --------------------------------------------------------------------------
253
+ // Public API
254
+ // --------------------------------------------------------------------------
255
+
256
+ /**
257
+ * Retrieve a provider credential from OS keychain or local AES-256-GCM vault.
258
+ * Returns { value: string, accountId?: string, source: string } or null.
259
+ */
260
+ export function getSecureProviderKey(provider, options = {}) {
261
+ const id = normalizeProviderId(provider);
262
+ if (!id) return null;
263
+
264
+ // 1. Try OS Credential Store if enabled/available
265
+ if (options.disableOsStore !== true) {
266
+ let osSecret = null;
267
+ if (process.platform === 'darwin') {
268
+ osSecret = osStoreReadDarwin(id);
269
+ } else if (process.platform === 'win32') {
270
+ osSecret = osStoreReadWin32(id, options);
271
+ } else if (process.platform === 'linux') {
272
+ osSecret = osStoreReadLinux(id);
273
+ }
274
+ if (osSecret) {
275
+ try {
276
+ const parsed = JSON.parse(osSecret);
277
+ if (parsed && typeof parsed === 'object' && parsed.value) {
278
+ return { value: parsed.value, accountId: parsed.accountId || null, source: 'os_keychain' };
279
+ }
280
+ } catch {
281
+ return { value: osSecret, accountId: null, source: 'os_keychain' };
282
+ }
283
+ }
284
+ }
285
+
286
+ // 2. Encrypted Local Store (AES-256-GCM)
287
+ try {
288
+ const store = readEncryptedStore(options);
289
+ const entry = store.secrets?.[id];
290
+ if (!entry) return null;
291
+
292
+ const key = deriveKey(options);
293
+ const plaintext = decryptAes256Gcm(entry, `provider:${id}`, key);
294
+ if (!plaintext) return null;
295
+
296
+ try {
297
+ const parsed = JSON.parse(plaintext);
298
+ if (parsed && typeof parsed === 'object' && parsed.value) {
299
+ return { value: parsed.value, accountId: parsed.accountId || null, source: 'local_vault' };
300
+ }
301
+ } catch {
302
+ return { value: plaintext, accountId: null, source: 'local_vault' };
303
+ }
304
+ } catch {
305
+ return null;
306
+ }
307
+
308
+ return null;
309
+ }
310
+
311
+ /**
312
+ * Store a provider credential into OS keychain and local AES-256-GCM vault.
313
+ */
314
+ export function setSecureProviderKey(provider, credential, options = {}) {
315
+ const id = normalizeProviderId(provider);
316
+ if (!id) throw new Error('provider_required');
317
+
318
+ let value = '';
319
+ let accountId = null;
320
+ if (typeof credential === 'object' && credential !== null) {
321
+ value = String(credential.value || credential.secret || '').trim();
322
+ accountId = credential.accountId ? String(credential.accountId).trim() : null;
323
+ } else {
324
+ value = String(credential || '').trim();
325
+ if (options.accountId) accountId = String(options.accountId).trim();
326
+ }
327
+
328
+ if (!value) throw new Error('credential_value_required');
329
+
330
+ const payloadString = JSON.stringify({ value, accountId });
331
+
332
+ // 1. Mirror into OS Credential Store (best-effort)
333
+ let osStoreSuccess = false;
334
+ if (options.disableOsStore !== true) {
335
+ if (process.platform === 'darwin') {
336
+ osStoreSuccess = osStoreWriteDarwin(id, payloadString);
337
+ } else if (process.platform === 'win32') {
338
+ osStoreSuccess = osStoreWriteWin32(id, payloadString, options);
339
+ } else if (process.platform === 'linux') {
340
+ osStoreSuccess = osStoreWriteLinux(id, payloadString);
341
+ }
342
+ }
343
+
344
+ // 2. Encrypt with AES-256-GCM into local store
345
+ const key = deriveKey(options);
346
+ const encrypted = encryptAes256Gcm(payloadString, `provider:${id}`, key);
347
+
348
+ const store = readEncryptedStore(options);
349
+ store.secrets[id] = {
350
+ ...encrypted,
351
+ updated_at: new Date().toISOString(),
352
+ };
353
+ writeEncryptedStore(store, options);
354
+
355
+ return {
356
+ provider: id,
357
+ stored: true,
358
+ os_keychain: osStoreSuccess,
359
+ local_vault: true,
360
+ };
361
+ }
362
+
363
+ /**
364
+ * Delete a provider credential from OS keychain and local AES-256-GCM vault.
365
+ */
366
+ export function deleteSecureProviderKey(provider, options = {}) {
367
+ const id = normalizeProviderId(provider);
368
+ if (!id) return false;
369
+
370
+ if (options.disableOsStore !== true) {
371
+ if (process.platform === 'darwin') osStoreDeleteDarwin(id);
372
+ else if (process.platform === 'win32') osStoreDeleteWin32(id, options);
373
+ else if (process.platform === 'linux') osStoreDeleteLinux(id);
374
+ }
375
+
376
+ const store = readEncryptedStore(options);
377
+ if (store.secrets?.[id]) {
378
+ delete store.secrets[id];
379
+ writeEncryptedStore(store, options);
380
+ return true;
381
+ }
382
+ return false;
383
+ }
384
+
385
+ /**
386
+ * List all providers that currently have credentials in the secure local vault.
387
+ */
388
+ export function listSecureConfiguredProviders(options = {}) {
389
+ const store = readEncryptedStore(options);
390
+ return Object.keys(store.secrets || {});
391
+ }
392
+
393
+ /**
394
+ * Hydrates environment variables from the secure vault for any unconfigured providers.
395
+ * Loads into `env` (defaults to process.env).
396
+ */
397
+ export function hydrateSecureCredentials(env = process.env, options = {}) {
398
+ const hydrated = [];
399
+ for (const [providerId, spec] of Object.entries(PROVIDER_CREDENTIALS)) {
400
+ if (env[spec.env]) continue;
401
+ try {
402
+ const cred = getSecureProviderKey(providerId, options);
403
+ if (cred?.value) {
404
+ env[spec.env] = cred.value;
405
+ if (providerId === 'cloudflare' && cred.accountId) {
406
+ if (!env.CLOUDFLARE_ACCOUNT_ID) env.CLOUDFLARE_ACCOUNT_ID = cred.accountId;
407
+ }
408
+ hydrated.push(providerId);
409
+ }
410
+ } catch {
411
+ // best-effort
412
+ }
413
+ }
414
+ return hydrated;
415
+ }
@@ -1,13 +1,29 @@
1
1
  import { spawn } from 'node:child_process';
2
2
  import { createProcessDiagnosticError } from '../errors/index.js';
3
3
 
4
- export function runProcess(command, args, { cwd, timeoutMs = 300_000, signal, env = process.env, maxBytes = 8 * 1024 * 1024 } = {}) {
4
+ export function resolveExecutableCommand(command, platform = process.platform) {
5
+ if (platform !== 'win32' || !command) return { command: String(command || ''), shell: false };
6
+ const str = String(command).trim();
7
+ const lower = str.toLowerCase();
8
+ if (lower === 'npx') return { command: 'npx.cmd', shell: true };
9
+ if (lower === 'npm') return { command: 'npm.cmd', shell: true };
10
+ if (lower === 'wrangler') return { command: 'wrangler.cmd', shell: true };
11
+ if (lower === 'pnpm') return { command: 'pnpm.cmd', shell: true };
12
+ if (lower === 'yarn') return { command: 'yarn.cmd', shell: true };
13
+ if (lower.endsWith('.cmd') || lower.endsWith('.bat')) return { command: str, shell: true };
14
+ return { command: str, shell: false };
15
+ }
16
+
17
+ export function runProcess(command, args, { cwd, timeoutMs = 300_000, signal, env = process.env, maxBytes = 8 * 1024 * 1024, shell } = {}) {
5
18
  return new Promise((resolve, reject) => {
6
19
  const safeArgs = Array.isArray(args) ? args : [];
20
+ const resolved = resolveExecutableCommand(command);
21
+ const useShell = shell ?? resolved.shell;
22
+ const finalCommand = resolved.command;
7
23
  const diagnostic = (code, message, extra = {}) => createProcessDiagnosticError({
8
24
  code,
9
25
  message,
10
- command,
26
+ command: finalCommand,
11
27
  args: safeArgs,
12
28
  cwd,
13
29
  stdout,
@@ -15,8 +31,8 @@ export function runProcess(command, args, { cwd, timeoutMs = 300_000, signal, en
15
31
  ...extra,
16
32
  });
17
33
  let stdout = '', stderr = '', size = 0, failure, hardKill;
18
- if (signal?.aborted) return reject(createProcessDiagnosticError({ code: 'process_cancelled', message: 'Command cancelled', command, args: safeArgs, cwd }));
19
- const child = spawn(command, safeArgs, { cwd, env, shell: false, detached: process.platform !== 'win32', stdio: ['ignore', 'pipe', 'pipe'] });
34
+ if (signal?.aborted) return reject(createProcessDiagnosticError({ code: 'process_cancelled', message: 'Command cancelled', command: finalCommand, args: safeArgs, cwd }));
35
+ const child = spawn(finalCommand, safeArgs, { cwd, env, shell: useShell, detached: process.platform !== 'win32', stdio: ['ignore', 'pipe', 'pipe'] });
20
36
  function kill(sig) {
21
37
  try { process.kill(process.platform === 'win32' ? child.pid : -child.pid, sig); } catch { /* already exited */ }
22
38
  }
@@ -0,0 +1,192 @@
1
+ import pc from 'picocolors';
2
+
3
+ function clean(value) {
4
+ return value == null ? '' : String(value).trim();
5
+ }
6
+
7
+ function healthUrl(status) {
8
+ return clean(
9
+ status?.cloudflare?.health?.url ||
10
+ status?.cloudflare?.contract?.health_url ||
11
+ status?.local?.live?.url
12
+ );
13
+ }
14
+
15
+ function liveAppUrl(status) {
16
+ const explicit = clean(
17
+ status?.cloudflare?.public_url ||
18
+ status?.cloudflare?.contract?.public_url
19
+ );
20
+ if (explicit) return explicit;
21
+
22
+ const health = healthUrl(status);
23
+ if (!health) return '';
24
+
25
+ return health.replace(/\/(?:api\/)?health\/?$/i, '');
26
+ }
27
+
28
+ export function buildStatusActionPlan(status = {}) {
29
+ const actions = [];
30
+ const tips = [];
31
+ const checks = status.checks || {};
32
+ const cloudflare = status.cloudflare || {};
33
+ const liveOk = cloudflare.configured === true && cloudflare.health?.ok === true;
34
+ const liveHealth = healthUrl(status);
35
+ const liveApp = liveAppUrl(status);
36
+ const localApiOnline = status.local?.api?.online === true;
37
+ const deployTarget = clean(
38
+ status.local?.deployTarget || status.local?.deploy_target
39
+ );
40
+
41
+ if (!checks.account) {
42
+ actions.push({
43
+ id: 'auth_login',
44
+ label: 'Sign in to IAM',
45
+ command: 'agentsam login',
46
+ why: 'Account auth is required for connected models, terminal authority, and deploy receipts.',
47
+ kind: 'auth',
48
+ });
49
+ tips.push('Not signed in — run agentsam login, or use AGENTSAM_API_KEY for headless access.');
50
+ } else {
51
+ actions.push({
52
+ id: 'whoami',
53
+ label: 'Inspect account / auth source',
54
+ command: 'agentsam whoami',
55
+ why: 'See which AgentSam credential is currently authoritative.',
56
+ kind: 'inspect',
57
+ });
58
+ }
59
+
60
+ if (cloudflare.configured) {
61
+ if (liveOk && liveApp) {
62
+ actions.push({
63
+ id: 'open_health',
64
+ label: `Open live app (${liveApp})`,
65
+ command: liveApp,
66
+ why: 'Open the healthy deployed project rather than localhost.',
67
+ kind: 'deploy',
68
+ });
69
+ }
70
+
71
+ actions.push({
72
+ id: 'cf_status',
73
+ label: 'Inspect Cloudflare Worker + bindings',
74
+ command: 'agentsam cloudflare status',
75
+ why: 'Inspect the active Worker version, routes, bindings, and deployment evidence.',
76
+ kind: 'inspect',
77
+ });
78
+
79
+ if (!liveOk) {
80
+ tips.push(
81
+ cloudflare.health?.error
82
+ ? `Live health failed: ${cloudflare.health.error}`
83
+ : 'Cloudflare deployment is configured but live health is not verified.',
84
+ );
85
+ actions.push({
86
+ id: 'deploy',
87
+ label: 'Deploy / refresh Cloudflare Worker',
88
+ command: 'agentsam deploy',
89
+ why: 'Bring live health and bindings back in sync with this repository.',
90
+ kind: 'deploy',
91
+ });
92
+ } else {
93
+ tips.push(`Live API healthy · ${liveHealth || cloudflare.worker_name}`);
94
+ }
95
+ } else if (deployTarget === 'cloudflare') {
96
+ tips.push('Cloudflare is the deploy target but its deployment contract is incomplete.');
97
+ actions.push({
98
+ id: 'cf_wire',
99
+ label: 'Inspect Cloudflare deployment contract',
100
+ command: 'agentsam cloudflare status',
101
+ why: 'Resolve Worker/config/health URL before recommending localhost.',
102
+ kind: 'fix',
103
+ });
104
+ } else if (!localApiOnline) {
105
+ tips.push('No live deployment contract is active; localhost is optional.');
106
+ actions.push({
107
+ id: 'local_dev',
108
+ label: 'Start local API',
109
+ command: 'npm run dev',
110
+ why: 'Use only for local-first projects without a healthy hosted deployment.',
111
+ kind: 'local',
112
+ });
113
+ }
114
+
115
+ if (!checks.models) {
116
+ actions.push({
117
+ id: 'models',
118
+ label: 'Inspect models',
119
+ command: 'agentsam models',
120
+ why: 'Inspect account-visible and local models.',
121
+ kind: 'fix',
122
+ });
123
+ }
124
+
125
+ if (!checks.terminal) {
126
+ actions.push({
127
+ id: 'terminal',
128
+ label: 'Inspect terminal authority',
129
+ command: 'agentsam status --json',
130
+ why: 'Inspect local PTY and enrolled execution connections.',
131
+ kind: 'inspect',
132
+ });
133
+ }
134
+
135
+ if (status.local?.db?.ready === false && status.local?.db?.exists === false) {
136
+ actions.push({
137
+ id: 'db_init',
138
+ label: 'Initialize AgentSam SQLite',
139
+ command: 'agentsam db init',
140
+ why: 'Initialize the project-local runtime state database.',
141
+ kind: 'local',
142
+ });
143
+ }
144
+
145
+ actions.push({
146
+ id: 'inspect',
147
+ label: 'Inspect repository',
148
+ command: 'agentsam inspect',
149
+ why: 'Capture repository identity and structural evidence.',
150
+ kind: 'inspect',
151
+ });
152
+
153
+ actions.push({
154
+ id: 'refresh',
155
+ label: 'Refresh status',
156
+ command: 'agentsam status',
157
+ why: 'Re-probe account, models, terminal, and deployment health.',
158
+ kind: 'inspect',
159
+ });
160
+
161
+ let headline = 'Project awareness';
162
+ if (status.ready) headline = liveOk ? 'Live project healthy' : 'Ready';
163
+ else if (!checks.account) headline = 'Sign in to unlock connected features';
164
+ else if (cloudflare.configured && !liveOk) headline = 'Deploy / health needs attention';
165
+ else headline = 'Setup remaining';
166
+
167
+ return { headline, tips, actions };
168
+ }
169
+
170
+ export function formatStatusNextSteps(plan) {
171
+ const lines = ['', ` ${pc.bold('next')} ${plan.headline}`];
172
+
173
+ for (const tip of plan.tips.slice(0, 4)) {
174
+ lines.push(` ${pc.dim('•')} ${tip}`);
175
+ }
176
+
177
+ const primary = plan.actions.filter((action) => action.kind !== 'inspect').slice(0, 3);
178
+ const inspect = plan.actions.filter((action) => action.kind === 'inspect').slice(0, 2);
179
+
180
+ for (const action of [...primary, ...inspect].slice(0, 5)) {
181
+ const command = action.id === 'open_health'
182
+ ? `open ${action.command}`
183
+ : action.command;
184
+
185
+ lines.push(` ${pc.cyan('$')} ${command}`);
186
+ lines.push(` ${pc.dim(action.why)}`);
187
+ }
188
+
189
+ lines.push(` ${pc.dim('Interactive menu: agentsam status -i')}`);
190
+
191
+ return lines.join('\n');
192
+ }
@@ -1,12 +1,16 @@
1
1
  function clean(value) { return value == null ? '' : String(value).trim(); }
2
2
 
3
+ function toolName(tool) {
4
+ return clean(tool?.toolKey || tool?.tool || tool?.name);
5
+ }
6
+
3
7
  export function hydrateToolSchemas(catalog = [], selected = [], options = {}) {
4
8
  if (!Array.isArray(catalog)) throw new TypeError('catalog must be an array');
5
9
  if (!Array.isArray(selected)) throw new TypeError('selected must be an array');
6
10
  const maxTools = Number.isInteger(options.maxTools) && options.maxTools > 0 ? options.maxTools : 8;
7
11
  const maxChars = Number.isInteger(options.maxChars) && options.maxChars > 0 ? options.maxChars : 40_000;
8
12
  const wanted = [...new Set(selected.map(clean).filter(Boolean))].slice(0, maxTools);
9
- const byName = new Map(catalog.map((tool) => [clean(tool.tool || tool.name), tool]).filter(([name]) => name));
13
+ const byName = new Map(catalog.map((tool) => [toolName(tool), tool]).filter(([name]) => name));
10
14
  const tools = [];
11
15
  const missing = [];
12
16
  const deferred = [];
@@ -1,2 +1,9 @@
1
1
  export { searchToolCards, toToolCard } from './search.js';
2
2
  export { hydrateToolSchemas } from './hydrate.js';
3
+ export { createToolRegistry } from './registry.js';
4
+ export { createToolExecutor } from './runtime.js';
5
+ export {
6
+ AGENTSAM_REDACTED_VALUE,
7
+ receiptPayload,
8
+ redactToolValue,
9
+ } from './redact.js';