@inneranimalmedia/agentsam-sdk 2.6.7 → 2.6.8

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 (318) hide show
  1. package/README.md +37 -0
  2. package/docs/REPO_FILE_MAP.txt +132 -0
  3. package/migrations/d1/0018_goap_control_plane_remaster.sql +40 -0
  4. package/migrations/d1/0019_agentsam_agent_run_plan_todo.sql +14 -0
  5. package/migrations/d1/README_PORTABLE_CONTROL_PLANE.md +20 -9
  6. package/migrations/runtime/0002_goap_blackboard_v1.sql +15 -0
  7. package/migrations/runtime/0004_agent_run_plan_linkage.sql +8 -0
  8. package/native/agentsam-machine/cli/Cargo.toml +8 -1
  9. package/native/agentsam-machine/cli/README.md +21 -0
  10. package/native/agentsam-machine/core/Cargo.toml +7 -0
  11. package/native/agentsam-machine/core/README.md +14 -0
  12. package/native/agentsam-machine/core/build.rs +33 -0
  13. package/native/agentsam-machine/core/contracts/source-types.v1.json +353 -0
  14. package/native/agentsam-machine/core/src/lib.rs +6 -0
  15. package/native/agentsam-machine/core/src/source_types.rs +2 -2
  16. package/package.json +16 -6
  17. package/packages/agentsam-errors/package.json +1 -1
  18. package/packages/agentsam-errors/src/index.js +1 -0
  19. package/packages/agentsam-errors/src/tool.js +56 -0
  20. package/packages/agentsam-errors/test/tool.test.mjs +58 -0
  21. package/packages/agentsam-goap/README.md +52 -0
  22. package/packages/agentsam-goap/package.json +37 -0
  23. package/packages/agentsam-goap/src/adapters/d1-sqlite.js +570 -0
  24. package/packages/agentsam-goap/src/adapters/memory.js +199 -0
  25. package/packages/agentsam-goap/src/contracts.js +226 -0
  26. package/packages/agentsam-goap/src/control-plane.js +112 -0
  27. package/packages/agentsam-goap/src/errors.js +157 -0
  28. package/packages/agentsam-goap/src/index.js +5 -0
  29. package/packages/agentsam-goap/src/world.js +202 -0
  30. package/packages/agentsam-goap/test/goap-control-plane.test.mjs +245 -0
  31. package/packages/agentsam-goap/test/world.test.mjs +79 -0
  32. package/packages/agentsam-nav/dist/Nav.d.ts +43 -0
  33. package/packages/agentsam-nav/dist/NavCollapsible.d.ts +10 -0
  34. package/packages/agentsam-nav/dist/NavContent.d.ts +2 -0
  35. package/packages/agentsam-nav/dist/NavFooter.d.ts +2 -0
  36. package/packages/agentsam-nav/dist/NavGroup.d.ts +3 -0
  37. package/packages/agentsam-nav/dist/NavHeader.d.ts +2 -0
  38. package/packages/agentsam-nav/dist/NavMenu.d.ts +22 -0
  39. package/packages/agentsam-nav/dist/NavProvider.d.ts +35 -0
  40. package/packages/agentsam-nav/dist/NavTrigger.d.ts +2 -0
  41. package/packages/agentsam-nav/dist/Surfaces.d.ts +41 -0
  42. package/packages/agentsam-nav/dist/browser.d.ts +11 -0
  43. package/packages/agentsam-nav/dist/browser.global.js +135 -0
  44. package/packages/agentsam-nav/dist/browser.js +7290 -0
  45. package/packages/agentsam-nav/dist/contracts.d.ts +76 -0
  46. package/packages/agentsam-nav/dist/index.d.ts +11 -0
  47. package/packages/agentsam-nav/dist/index.js +7291 -0
  48. package/packages/agentsam-nav/dist/legacy.css +83 -0
  49. package/packages/agentsam-nav/dist/shell.css +113 -0
  50. package/packages/agentsam-nav/dist/theme.css +113 -0
  51. package/packages/agentsam-nav/dist/utils.d.ts +1 -0
  52. package/packages/agentsam-repository/src/goap.js +13 -14
  53. package/packages/agentsam-repository/src/goap.js.bak-20260922011251 +670 -0
  54. package/packages/agentsam-repository/src/tickets.js +15 -22
  55. package/packages/agentsam-repository/test/goap-tickets-workspace-state.test.mjs +19 -8
  56. package/packages/connectors/cloudflare/package.json +3 -1
  57. package/packages/identity/tests/lane1-packed-consumer.test.mjs +1 -1
  58. package/python/agentsam_sdk/repository/intelligence/discovery.py +27 -2
  59. package/python/agentsam_sdk/repository/intelligence/git.py +4 -0
  60. package/python/tests/test_repository_intelligence.py +30 -0
  61. package/src/cli/command-catalog.js +2 -1
  62. package/src/cli.js +10 -1
  63. package/src/commands/goap-world.js +134 -0
  64. package/src/commands/goap.js +11 -4
  65. package/src/commands/machine-binary.js +33 -27
  66. package/src/commands/machine-runtime.js +266 -0
  67. package/src/commands/machine.js +122 -51
  68. package/src/commands/package.js +530 -0
  69. package/src/commands/plan-ledger.js +370 -0
  70. package/src/commands/plan.js +183 -0
  71. package/src/commands/skill.js +78 -17
  72. package/src/knowledge/source.js +1 -1
  73. package/src/lib/slash-commands.js +1 -1
  74. package/src/local/runtime-store.js +24 -2
  75. package/src/local/sqlite.js +17 -0
  76. package/src/sam/operations/package-audit.js +41 -0
  77. package/src/sam/seed.js +2 -0
  78. package/skills/grok-auth/SKILL.md +0 -110
  79. package/skills/grok-auth/agentsam.skill.json +0 -25
  80. package/skills/grok-auth/references/grok-identity.md +0 -64
  81. package/skills/grok-auth/references/per-user-data.md +0 -49
  82. package/skills/grok-auth/references/prewired-and-env.md +0 -54
  83. package/skills/grok-auth/references/session-ui.md +0 -133
  84. package/skills/grok-auth/references/sign-in-methods.md +0 -55
  85. package/skills/grok-auth/references/wiring.md +0 -71
  86. package/skills/grok-building-games/SKILL.md +0 -213
  87. package/skills/grok-building-games/agentsam.skill.json +0 -25
  88. package/skills/grok-building-games/references/3d-libs.md +0 -64
  89. package/skills/grok-building-games/references/ai-pathfinding.md +0 -122
  90. package/skills/grok-building-games/references/audio.md +0 -129
  91. package/skills/grok-building-games/references/babylon.md +0 -202
  92. package/skills/grok-building-games/references/collision-physics.md +0 -122
  93. package/skills/grok-building-games/references/ecs-architecture.md +0 -111
  94. package/skills/grok-building-games/references/game-feel-juice.md +0 -110
  95. package/skills/grok-building-games/references/genres/board-card-chess.md +0 -89
  96. package/skills/grok-building-games/references/genres/endless-runner.md +0 -83
  97. package/skills/grok-building-games/references/genres/fps.md +0 -105
  98. package/skills/grok-building-games/references/genres/platformer-2d.md +0 -97
  99. package/skills/grok-building-games/references/genres/puzzle-match3-tetris.md +0 -131
  100. package/skills/grok-building-games/references/genres/racing-kart.md +0 -106
  101. package/skills/grok-building-games/references/genres/topdown-twin-stick.md +0 -97
  102. package/skills/grok-building-games/references/genres/tower-defense.md +0 -84
  103. package/skills/grok-building-games/references/genres/voxel-minecraft.md +0 -89
  104. package/skills/grok-building-games/references/input.md +0 -139
  105. package/skills/grok-building-games/references/phaser.md +0 -277
  106. package/skills/grok-building-games/references/procedural-generation.md +0 -141
  107. package/skills/grok-building-games/references/save-persistence.md +0 -108
  108. package/skills/grok-building-games/references/threejs-foundational.md +0 -148
  109. package/skills/grok-controls/SKILL.md +0 -274
  110. package/skills/grok-controls/agentsam.skill.json +0 -25
  111. package/skills/grok-design-ui/SKILL.md +0 -122
  112. package/skills/grok-design-ui/agentsam.skill.json +0 -25
  113. package/skills/grok-design-ui/references/animations.md +0 -379
  114. package/skills/grok-design-ui/references/performance.md +0 -88
  115. package/skills/grok-design-ui/references/refined-ui.md +0 -384
  116. package/skills/grok-design-ui/references/surfaces.md +0 -247
  117. package/skills/grok-design-ui/references/typography.md +0 -123
  118. package/skills/grok-game-animation-frames/SKILL.md +0 -84
  119. package/skills/grok-game-animation-frames/agentsam.skill.json +0 -25
  120. package/skills/grok-game-asset-core/SKILL.md +0 -69
  121. package/skills/grok-game-asset-core/agentsam.skill.json +0 -25
  122. package/skills/grok-game-character-consistency/SKILL.md +0 -69
  123. package/skills/grok-game-character-consistency/agentsam.skill.json +0 -25
  124. package/skills/grok-game-tilesets/SKILL.md +0 -65
  125. package/skills/grok-game-tilesets/agentsam.skill.json +0 -25
  126. package/skills/grok-game-ui-icons/SKILL.md +0 -56
  127. package/skills/grok-game-ui-icons/agentsam.skill.json +0 -25
  128. package/skills/grok-generate2dmap/LICENSE +0 -21
  129. package/skills/grok-generate2dmap/SKILL.md +0 -120
  130. package/skills/grok-generate2dmap/SOURCE.md +0 -6
  131. package/skills/grok-generate2dmap/agentsam.skill.json +0 -25
  132. package/skills/grok-generate2dmap/references/deliverables.md +0 -101
  133. package/skills/grok-generate2dmap/references/layered-map-contract.md +0 -209
  134. package/skills/grok-generate2dmap/references/map-strategies.md +0 -341
  135. package/skills/grok-generate2dmap/references/object-production-gate.md +0 -24
  136. package/skills/grok-generate2dmap/references/pipeline.md +0 -149
  137. package/skills/grok-generate2dmap/references/prop-pack-contract.md +0 -174
  138. package/skills/grok-generate2dmap/references/side-scroll-stages.md +0 -29
  139. package/skills/grok-generate2dmap/scripts/compose_layered_preview.py +0 -157
  140. package/skills/grok-generate2dmap/scripts/extract_prop_pack.py +0 -369
  141. package/skills/grok-generate2dsprite/LICENSE +0 -21
  142. package/skills/grok-generate2dsprite/SKILL.md +0 -313
  143. package/skills/grok-generate2dsprite/SOURCE.md +0 -6
  144. package/skills/grok-generate2dsprite/agentsam.skill.json +0 -25
  145. package/skills/grok-generate2dsprite/references/modes.md +0 -124
  146. package/skills/grok-generate2dsprite/references/prompt-rules.md +0 -315
  147. package/skills/grok-generate2dsprite/scripts/generate2dsprite.py +0 -1031
  148. package/skills/grok-generate2dsprite/scripts/make_layout_guide.py +0 -109
  149. package/skills/grok-imagine/SKILL.md +0 -201
  150. package/skills/grok-imagine/agentsam.skill.json +0 -25
  151. package/skills/grok-multiplayer-p2p/SKILL.md +0 -111
  152. package/skills/grok-multiplayer-p2p/agentsam.skill.json +0 -25
  153. package/skills/grok-multiplayer-p2p/references/react-binding.md +0 -144
  154. package/skills/grok-multiplayer-p2p/references/signaling-relay.md +0 -269
  155. package/skills/grok-neon/SKILL.md +0 -157
  156. package/skills/grok-neon/agentsam.skill.json +0 -25
  157. package/skills/grok-og/SKILL.md +0 -102
  158. package/skills/grok-og/agentsam.skill.json +0 -25
  159. package/skills/grok-og/references/brand-pass.md +0 -53
  160. package/skills/grok-og/references/custom-card.md +0 -107
  161. package/skills/grok-og/references/favicon-and-icons.md +0 -48
  162. package/skills/grok-og/references/og-type-contract.md +0 -18
  163. package/skills/grok-og/references/placeholder-card.md +0 -21
  164. package/skills/grok-og/references/x-banner.md +0 -41
  165. package/skills/grok-threejs/SKILL.md +0 -67
  166. package/skills/grok-threejs/agentsam.skill.json +0 -25
  167. package/skills/grok-threejs/references/llms-full.txt +0 -2780
  168. package/skills/grok-video2dsprite/LICENSE +0 -21
  169. package/skills/grok-video2dsprite/SKILL.md +0 -236
  170. package/skills/grok-video2dsprite/SOURCE.md +0 -6
  171. package/skills/grok-video2dsprite/agentsam.skill.json +0 -25
  172. package/skills/grok-video2dsprite/references/pipeline.md +0 -90
  173. package/skills/grok-video2dsprite/references/prompt-rules.md +0 -63
  174. package/skills/grok-video2dsprite/scripts/video2dsprite.py +0 -490
  175. package/skills/grok-xai-api/SKILL.md +0 -152
  176. package/skills/grok-xai-api/agentsam.skill.json +0 -25
  177. package/test/account-session.test.mjs +0 -101
  178. package/test/agent-capabilities.test.mjs +0 -67
  179. package/test/app-authority-context.test.mjs +0 -32
  180. package/test/app-building-skills.test.mjs +0 -61
  181. package/test/apps-scaffold-contract.test.mjs +0 -115
  182. package/test/blender-cad.test.mjs +0 -146
  183. package/test/cad-docker.test.mjs +0 -96
  184. package/test/capabilities.test.mjs +0 -133
  185. package/test/cli/api-key-env-whoami.test.mjs +0 -129
  186. package/test/cli/catalog-authority.test.mjs +0 -64
  187. package/test/cli/codebaseindex-plan-ux.test.mjs +0 -37
  188. package/test/cli/eval-live.test.mjs +0 -219
  189. package/test/cli/go.test.mjs +0 -128
  190. package/test/cli/local-vault-and-provider-setup.test.mjs +0 -268
  191. package/test/cli/machine-command.test.mjs +0 -34
  192. package/test/cli/mcp-client.test.mjs +0 -256
  193. package/test/cli/preferences-runtime.test.mjs +0 -11
  194. package/test/cli/runtime-persist.test.mjs +0 -56
  195. package/test/cli/runtime-ui.test.mjs +0 -141
  196. package/test/cli/rust-command.test.mjs +0 -21
  197. package/test/cli/skill-npm-and-env.test.mjs +0 -52
  198. package/test/cli/status-actions.test.mjs +0 -88
  199. package/test/cli/wireframes-go-registry.test.mjs +0 -139
  200. package/test/cli-preferences.test.mjs +0 -46
  201. package/test/cloudflare-connector.test.mjs +0 -93
  202. package/test/cloudflare-runtime.test.mjs +0 -82
  203. package/test/context.test.mjs +0 -159
  204. package/test/credentials-audit.test.mjs +0 -113
  205. package/test/deploy-health-scan.test.mjs +0 -95
  206. package/test/deploy-receipt.test.mjs +0 -91
  207. package/test/dockerize.test.mjs +0 -93
  208. package/test/error-diagnostics.test.mjs +0 -124
  209. package/test/eval-context.test.mjs +0 -37
  210. package/test/execution-approvals.test.mjs +0 -27
  211. package/test/fixtures/cad/courtyard-house.json +0 -208
  212. package/test/fixtures/knowledge-rpc-worker.mjs +0 -16
  213. package/test/fixtures/project-authority/customer-app/.agentsam/app.json +0 -5
  214. package/test/fixtures/project-authority/customer-app/apps/my-product/index.ts +0 -1
  215. package/test/fixtures/project-authority/customer-app/wrangler.toml +0 -17
  216. package/test/gcloud-auth.test.mjs +0 -111
  217. package/test/go/build-source-identity.test.mjs +0 -31
  218. package/test/go/cloudflare-probe.test.mjs +0 -317
  219. package/test/go/distribution.test.mjs +0 -28
  220. package/test/google-cloud-connection.test.mjs +0 -83
  221. package/test/google-cloud-inventory.test.mjs +0 -64
  222. package/test/indexing-provider.test.mjs +0 -29
  223. package/test/init-options.test.mjs +0 -35
  224. package/test/integration/ai-access-onboarding.test.mjs +0 -47
  225. package/test/integration/app-command.test.mjs +0 -85
  226. package/test/integration/autorag-project-authority.integration.test.mjs +0 -51
  227. package/test/integration/autorag-runtime-discovery.test.mjs +0 -107
  228. package/test/integration/cad-discovery.test.mjs +0 -158
  229. package/test/integration/cad-docker-executor.test.mjs +0 -249
  230. package/test/integration/cad-execution.test.mjs +0 -184
  231. package/test/integration/cad-project-app.test.mjs +0 -31
  232. package/test/integration/cad-project-d1.test.mjs +0 -25
  233. package/test/integration/cad-project-native.test.mjs +0 -24
  234. package/test/integration/cad-project-workflow.test.mjs +0 -9
  235. package/test/integration/cad-project.test.mjs +0 -85
  236. package/test/integration/cli-help.test.mjs +0 -41
  237. package/test/integration/cms-app-scaffold.test.mjs +0 -77
  238. package/test/integration/cms-site-tenancy-contract.test.mjs +0 -268
  239. package/test/integration/codebaseindex-ingest.test.mjs +0 -255
  240. package/test/integration/core-client.integration.test.mjs +0 -55
  241. package/test/integration/database-hosted-honesty.test.mjs +0 -49
  242. package/test/integration/desktop-keychain-boundary.test.mjs +0 -45
  243. package/test/integration/error-runtime-rpc.test.mjs +0 -71
  244. package/test/integration/features-resolve.test.mjs +0 -147
  245. package/test/integration/hosted-work-host-authority.test.mjs +0 -47
  246. package/test/integration/icon-registry.test.mjs +0 -67
  247. package/test/integration/ingest-discover-models.test.mjs +0 -30
  248. package/test/integration/inspect-path-cli.test.mjs +0 -46
  249. package/test/integration/install-script.test.mjs +0 -110
  250. package/test/integration/inventory-core.test.mjs +0 -53
  251. package/test/integration/inventory-eligibility.test.mjs +0 -59
  252. package/test/integration/inventory-evidence.test.mjs +0 -125
  253. package/test/integration/knowledge-rpc.test.mjs +0 -112
  254. package/test/integration/local-fs.test.mjs +0 -113
  255. package/test/integration/local-provider-bridge.test.mjs +0 -65
  256. package/test/integration/local-studio-settings-production.test.mjs +0 -40
  257. package/test/integration/lockfile-sync.test.mjs +0 -26
  258. package/test/integration/merkle-cli.test.mjs +0 -61
  259. package/test/integration/merkle-persistence-identity.test.mjs +0 -48
  260. package/test/integration/plugins-cloudflare.integration.test.mjs +0 -28
  261. package/test/integration/provider-env-cli.test.mjs +0 -60
  262. package/test/integration/provider-factory.test.mjs +0 -197
  263. package/test/integration/repository-company-graph.test.mjs +0 -90
  264. package/test/integration/runtime-migrations.test.mjs +0 -87
  265. package/test/integration/runtime-status.integration.test.mjs +0 -227
  266. package/test/integration/sam-activity-recovery.test.mjs +0 -147
  267. package/test/integration/sam-decision.test.mjs +0 -584
  268. package/test/integration/sam-kernel.test.mjs +0 -99
  269. package/test/integration/sam-planning-astar.test.mjs +0 -279
  270. package/test/integration/scaffold-cloudflare.test.mjs +0 -46
  271. package/test/integration/skill-runtime.test.mjs +0 -240
  272. package/test/integration/storage-architecture.test.mjs +0 -154
  273. package/test/integration/store-discovery.test.mjs +0 -44
  274. package/test/integration/studio-fs-pty-e2e.test.mjs +0 -294
  275. package/test/integration/terminal-exec.integration.test.mjs +0 -86
  276. package/test/integration/theme-package-registry.test.mjs +0 -31
  277. package/test/integration/tool-runtime.test.mjs +0 -124
  278. package/test/integration/tool-schema.test.mjs +0 -59
  279. package/test/jr-dev-skill.test.mjs +0 -26
  280. package/test/knowledge-context-pack.test.mjs +0 -19
  281. package/test/knowledge-postgres.test.mjs +0 -40
  282. package/test/knowledge-service.test.mjs +0 -110
  283. package/test/knowledge.test.mjs +0 -206
  284. package/test/live/terminal-transport.live.test.mjs +0 -24
  285. package/test/local-sessions.test.mjs +0 -57
  286. package/test/local-studio-deploy.test.mjs +0 -83
  287. package/test/loopback-oauth.test.mjs +0 -53
  288. package/test/merkle-render.test.mjs +0 -31
  289. package/test/mini.test.mjs +0 -140
  290. package/test/model-catalog.test.mjs +0 -70
  291. package/test/models.test.mjs +0 -309
  292. package/test/npm10-lock.test.mjs +0 -29
  293. package/test/ollama.test.mjs +0 -137
  294. package/test/open-url.test.mjs +0 -64
  295. package/test/openai-responses.test.mjs +0 -155
  296. package/test/portable-context.test.mjs +0 -94
  297. package/test/project-config.test.mjs +0 -81
  298. package/test/project-rules.test.mjs +0 -44
  299. package/test/provider-credentials.test.mjs +0 -106
  300. package/test/rehydrate.test.mjs +0 -25
  301. package/test/release-hygiene.test.mjs +0 -42
  302. package/test/repository-snapshot-view.test.mjs +0 -112
  303. package/test/responses-runner.test.mjs +0 -465
  304. package/test/runtime-activity.test.mjs +0 -98
  305. package/test/sdk-worker-contract.test.mjs +0 -72
  306. package/test/security.test.mjs +0 -266
  307. package/test/setup-planner.test.mjs +0 -74
  308. package/test/setup-runtime.test.mjs +0 -51
  309. package/test/shell.test.mjs +0 -281
  310. package/test/skills.test.mjs +0 -22
  311. package/test/smoke.mjs +0 -122
  312. package/test/telemetry.test.mjs +0 -79
  313. package/test/terminal/local-pty.mock.test.mjs +0 -153
  314. package/test/terminal-machine-identity.test.mjs +0 -88
  315. package/test/theme-portability.test.mjs +0 -14
  316. package/test/tools-search.test.mjs +0 -73
  317. package/test/unit/website-assets-bindings.test.mjs +0 -60
  318. package/test/whoami-resume.test.mjs +0 -157
@@ -31,7 +31,11 @@ export function createTicketId() {
31
31
  }
32
32
 
33
33
  /**
34
- * Generate SQL for ticket creation with mandatory agentsam_agent_run when active.
34
+ * Generate SQL for ticket creation.
35
+ *
36
+ * Goal state and execution state are separate nouns. Creating/activating a
37
+ * ticket must not fabricate an agentsam_agent_run. Callers may link an
38
+ * already-created real run explicitly via agentRunId.
35
39
  */
36
40
  export function generateTicketCreateSql({
37
41
  accountId,
@@ -59,16 +63,7 @@ export function generateTicketCreateSql({
59
63
  if (!tTitle) throw new Error('title_required');
60
64
 
61
65
  const statements = [];
62
- let runId = clean(agentRunId);
63
-
64
- if (status === 'active' && !runId) {
65
- runId = createAgentRunId();
66
- statements.push(`INSERT INTO agentsam_agent_run (
67
- id, account_id, mode, status, started_at_unix, created_at_unix, updated_at_unix
68
- ) VALUES (
69
- ${sqlText(runId)}, ${sqlText(account)}, 'agent', 'running', ${sqlInt(now)}, ${sqlInt(now)}, ${sqlInt(now)}
70
- );`);
71
- }
66
+ const runId = clean(agentRunId);
72
67
 
73
68
  statements.push(`INSERT INTO agentsam_tickets (
74
69
  id, title, description, status, status_reason, project, subsystem,
@@ -98,12 +93,15 @@ export function generateTicketCreateSql({
98
93
  }
99
94
 
100
95
  /**
101
- * Generate SQL to activate a ticket and wire a real agentsam_agent_run row.
96
+ * Generate SQL to activate a ticket.
97
+ *
98
+ * agentRunId is optional and must reference a run created by the execution
99
+ * subsystem. Activation itself never creates a run.
102
100
  */
103
101
  export function generateTicketActivationSql({
104
102
  accountId,
105
103
  ticketId,
106
- agentRunId = createAgentRunId(),
104
+ agentRunId = null,
107
105
  statusReason = null,
108
106
  now = Math.floor(Date.now() / 1000),
109
107
  }) {
@@ -111,18 +109,13 @@ export function generateTicketActivationSql({
111
109
  const tid = clean(ticketId);
112
110
  if (!account) throw new Error('account_id_required');
113
111
  if (!tid) throw new Error('ticket_id_required');
114
- const runId = clean(agentRunId) || createAgentRunId();
112
+ const runId = clean(agentRunId);
115
113
 
116
114
  const statements = [
117
- `INSERT INTO agentsam_agent_run (
118
- id, account_id, mode, status, started_at_unix, created_at_unix, updated_at_unix
119
- ) VALUES (
120
- ${sqlText(runId)}, ${sqlText(account)}, 'agent', 'running', ${sqlInt(now)}, ${sqlInt(now)}, ${sqlInt(now)}
121
- );`,
122
115
  `UPDATE agentsam_tickets SET
123
116
  status = 'active',
124
117
  status_reason = ${sqlText(statusReason)},
125
- agent_run_id = COALESCE(agent_run_id, ${sqlText(runId)}),
118
+ agent_run_id = COALESCE(${sqlText(runId || null)}, agent_run_id),
126
119
  updated_at = ${sqlInt(now)},
127
120
  closed_at = NULL
128
121
  WHERE id = ${sqlText(tid)};`,
@@ -130,14 +123,14 @@ WHERE id = ${sqlText(tid)};`,
130
123
  id, ticket_id, event_type, from_status, to_status, detail, actor_type, created_at
131
124
  ) VALUES (
132
125
  'tke_' || lower(hex(randomblob(8))), ${sqlText(tid)}, 'status_change', 'backlog', 'active',
133
- 'activated_with_agent_run', 'agentsam_sdk', ${sqlInt(now)}
126
+ 'activated', 'agentsam_sdk', ${sqlInt(now)}
134
127
  );`,
135
128
  ];
136
129
 
137
130
  return {
138
131
  sql: statements.join('\n\n'),
139
132
  ticketId: tid,
140
- agentRunId: runId,
133
+ agentRunId: runId || null,
141
134
  };
142
135
  }
143
136
 
@@ -30,7 +30,7 @@ test('generateTicketCreateSql requires account_id and title', () => {
30
30
  assert.throws(() => generateTicketCreateSql({ accountId: 'acc_1' }), /title_required/);
31
31
  });
32
32
 
33
- test('generateTicketCreateSql with status=active mints an agent_run and links it on the ticket insert', () => {
33
+ test('generateTicketCreateSql with status=active does not fabricate an agent run', () => {
34
34
  const { sql, ticketId, agentRunId } = generateTicketCreateSql({
35
35
  accountId: 'acc_1',
36
36
  title: 'Wire GOAP planner',
@@ -38,12 +38,10 @@ test('generateTicketCreateSql with status=active mints an agent_run and links it
38
38
  now: 1000,
39
39
  });
40
40
  assert.ok(ticketId.startsWith('tkt_'));
41
- assert.ok(agentRunId && agentRunId.startsWith('arun_'));
42
- assert.match(sql, /INSERT INTO agentsam_agent_run/);
41
+ assert.equal(agentRunId, null);
42
+ assert.doesNotMatch(sql, /INSERT INTO agentsam_agent_run/);
43
43
  assert.match(sql, /INSERT INTO agentsam_tickets/);
44
44
  assert.match(sql, /INSERT INTO agentsam_ticket_events/);
45
- const runOccurrences = sql.split(agentRunId).length - 1;
46
- assert.ok(runOccurrences >= 2, 'agent_run id should appear in both the run insert and the ticket insert');
47
45
  });
48
46
 
49
47
  test('generateTicketCreateSql with status=backlog does not mint an agent_run', () => {
@@ -83,16 +81,29 @@ test('generateTicketActivationSql requires account and ticket id', () => {
83
81
  assert.throws(() => generateTicketActivationSql({ accountId: 'a' }), /ticket_id_required/);
84
82
  });
85
83
 
86
- test('generateTicketActivationSql wires a fresh agent_run and clears closed_at', () => {
84
+ test('generateTicketActivationSql changes focus without fabricating an agent run', () => {
87
85
  const { sql, agentRunId } = generateTicketActivationSql({
88
86
  accountId: 'acc_1',
89
87
  ticketId: 'tkt_abc',
90
88
  now: 1000,
91
89
  });
92
- assert.ok(agentRunId.startsWith('arun_'));
90
+ assert.equal(agentRunId, null);
91
+ assert.doesNotMatch(sql, /INSERT INTO agentsam_agent_run/);
93
92
  assert.match(sql, /status = 'active'/);
94
93
  assert.match(sql, /closed_at = NULL/);
95
- assert.match(sql, /COALESCE\(agent_run_id,/);
94
+ assert.match(sql, /agent_run_id = COALESCE\(NULL, agent_run_id\)/);
95
+ });
96
+
97
+ test('generateTicketActivationSql can link a run created by the execution subsystem', () => {
98
+ const { sql, agentRunId } = generateTicketActivationSql({
99
+ accountId: 'acc_1',
100
+ ticketId: 'tkt_abc',
101
+ agentRunId: 'arun_real',
102
+ now: 1000,
103
+ });
104
+ assert.equal(agentRunId, 'arun_real');
105
+ assert.doesNotMatch(sql, /INSERT INTO agentsam_agent_run/);
106
+ assert.match(sql, /agent_run_id = COALESCE\('arun_real', agent_run_id\)/);
96
107
  });
97
108
 
98
109
  test('generateTicketCloseSql maps shipped -> completed and abandoned/blocked -> failed run status', () => {
@@ -18,5 +18,7 @@
18
18
  },
19
19
  "files": [
20
20
  "src"
21
- ]
21
+ ],
22
+ "description": "Portable Cloudflare capability connector for AgentSam applications and SDK consumers.",
23
+ "license": "MIT"
22
24
  }
@@ -18,7 +18,7 @@ function run(cmd, args, cwd) {
18
18
  // for nested project installs. Strip that inherited allowance in the child only.
19
19
  const env = { ...process.env };
20
20
  for (const key of Object.keys(env)) {
21
- if (/^npm_config_allow[_-]scripts$/i.test(key)) delete env[key];
21
+ if (/^npm_config_(?:allow[_-]?scripts|dry[_-]?run)$/i.test(key)) delete env[key];
22
22
  }
23
23
  return execFileSync(cmd, args, {
24
24
  cwd,
@@ -10,6 +10,11 @@ DEFAULT_FALLBACK_EXCLUDE_DIRS = frozenset(
10
10
  {
11
11
  ".git",
12
12
  "node_modules",
13
+ "python_modules",
14
+ ".agentsam",
15
+ ".wrangler",
16
+ "vendor",
17
+ "target",
13
18
  "dist",
14
19
  "build",
15
20
  "coverage",
@@ -21,6 +26,25 @@ DEFAULT_FALLBACK_EXCLUDE_DIRS = frozenset(
21
26
  }
22
27
  )
23
28
 
29
+
30
+
31
+ DEFAULT_EVIDENCE_NOISE_DIRS = frozenset(DEFAULT_FALLBACK_EXCLUDE_DIRS)
32
+ DEFAULT_EVIDENCE_NOISE_SUFFIXES = (".min.js", ".bundle.js", ".map")
33
+
34
+
35
+ def is_default_evidence_noise_path(value: str) -> bool:
36
+ path = str(value or "").replace("\\", "/").strip("/")
37
+ if not path:
38
+ return False
39
+ parts = path.split("/")
40
+ if any(part in DEFAULT_EVIDENCE_NOISE_DIRS for part in parts[:-1]):
41
+ return True
42
+ name = parts[-1]
43
+ if name in DEFAULT_EVIDENCE_NOISE_DIRS:
44
+ return True
45
+ lowered = name.lower()
46
+ return lowered.endswith(DEFAULT_EVIDENCE_NOISE_SUFFIXES)
47
+
24
48
  LANGUAGE_BY_EXT = {
25
49
  ".js": "JavaScript", ".mjs": "JavaScript", ".cjs": "JavaScript", ".jsx": "JavaScript",
26
50
  ".ts": "TypeScript", ".tsx": "TypeScript", ".py": "Python", ".go": "Go",
@@ -79,8 +103,9 @@ def active_paths(
79
103
  """Return active paths and discovery source (`git` or `filesystem`)."""
80
104
  paths = _git_paths(repo_root)
81
105
  if paths:
82
- return paths, "git"
83
- return _walk_paths(repo_root, fallback_exclude_dir_names), "filesystem"
106
+ return [path for path in paths if not is_default_evidence_noise_path(path)], "git"
107
+ walked = _walk_paths(repo_root, fallback_exclude_dir_names)
108
+ return [path for path in walked if not is_default_evidence_noise_path(path)], "filesystem"
84
109
 
85
110
 
86
111
  def _line_count(path: Path) -> int | None:
@@ -6,6 +6,8 @@ from collections import Counter, defaultdict
6
6
  from pathlib import Path
7
7
  from typing import Any
8
8
 
9
+ from .discovery import is_default_evidence_noise_path
10
+
9
11
 
10
12
  def run_git(repo_root: Path, *args: str) -> str:
11
13
  try:
@@ -56,6 +58,8 @@ def git_churn(repo_root: Path, *, days: int = 30) -> dict[str, dict[str, int]]:
56
58
  if len(parts) != 3:
57
59
  continue
58
60
  added_raw, deleted_raw, path = parts
61
+ if is_default_evidence_noise_path(path):
62
+ continue
59
63
  if added_raw == "-" or deleted_raw == "-":
60
64
  continue
61
65
  try:
@@ -65,5 +65,35 @@ class TestRepositoryIntelligence(unittest.TestCase):
65
65
  self.assertTrue(any(row["path"] == "src/a.py" for row in snapshot["hot_files"]))
66
66
 
67
67
 
68
+ def test_default_evidence_noise_never_becomes_architecture_pressure(self):
69
+ with tempfile.TemporaryDirectory() as tmp:
70
+ root = Path(tmp)
71
+ subprocess.run(["git", "init"], cwd=root, check=True, capture_output=True)
72
+ subprocess.run(["git", "config", "user.email", "fixture@example.com"], cwd=root, check=True)
73
+ subprocess.run(["git", "config", "user.name", "Fixture"], cwd=root, check=True)
74
+ (root / "src").mkdir()
75
+ (root / "python_modules").mkdir()
76
+ (root / ".agentsam" / "machine").mkdir(parents=True)
77
+ (root / "dist").mkdir()
78
+ (root / "src" / "app.js").write_text("export const app = 1;\n", encoding="utf-8")
79
+ (root / "python_modules" / "vendor.py").write_text("x = 1\n" * 100, encoding="utf-8")
80
+ (root / ".agentsam" / "machine" / "receipt.json").write_text("{}", encoding="utf-8")
81
+ (root / "dist" / "app.bundle.js").write_text("x" * 5000, encoding="utf-8")
82
+ subprocess.run(["git", "add", "-f", "."], cwd=root, check=True)
83
+ subprocess.run(["git", "commit", "-m", "fixture"], cwd=root, check=True, capture_output=True)
84
+
85
+ paths, _ = active_paths(root)
86
+ self.assertIn("src/app.js", paths)
87
+ self.assertNotIn("python_modules/vendor.py", paths)
88
+ self.assertNotIn(".agentsam/machine/receipt.json", paths)
89
+ self.assertNotIn("dist/app.bundle.js", paths)
90
+
91
+ snapshot = build_snapshot(root, churn_days=30, top=20)
92
+ pressure = {row["path"] for row in snapshot["pressure_points"]}
93
+ self.assertFalse(any(path.startswith("python_modules") for path in pressure))
94
+ self.assertFalse(any(path.startswith(".agentsam") for path in pressure))
95
+ self.assertFalse(any(path.startswith("dist") for path in pressure))
96
+
97
+
68
98
  if __name__ == "__main__":
69
99
  unittest.main()
@@ -14,6 +14,7 @@ export const CLI_COMMAND_CATALOG = Object.freeze([
14
14
  { id: 'dev', summary: 'Run this project’s npm dev script', topic: 'work', skill: 'agentsam-app-fundamentals' },
15
15
  { id: 'inspect', summary: 'Bounded repository inspect / authority view', topic: 'work', skill: 'agentsam-app-fundamentals', operation: 'repository.inspect', common: true },
16
16
  { id: 'machine', summary: 'Deterministic local machine perception (inspect / asset discovery)', topic: 'work', skill: 'agentsam-app-fundamentals', operation: 'machine.inspect', common: true },
17
+ { id: 'package', summary: 'Audit, verify, and plan publication of distributable packages', topic: 'work', skill: 'agentsam-progression-guard', operation: 'package.audit', common: true, usage: ['agentsam package audit [--public] [--offline] [--json]', 'agentsam package status <name> [--offline] [--json]', 'agentsam package verify <name> [--offline] [--json]', 'agentsam package publish-plan [--offline] [--json]'] },
17
18
  { id: 'capabilities', summary: 'Inspect capability contracts', topic: 'create', skill: 'agentsam-app-fundamentals' },
18
19
  {
19
20
  id: 'setup',
@@ -93,7 +94,7 @@ export const CLI_COMMAND_CATALOG = Object.freeze([
93
94
  { id: 'init', summary: 'Knowledge setup or local scaffold', topic: 'create', skill: 'agentsam-app-fundamentals' },
94
95
  { id: 'codebaseindex', aliases: ['ingest', 'codebase-index'], summary: 'Guided codebase ingest: materials, allowlist, embeddings, storage', topic: 'work', skill: 'agentsam-codebaseindex', operation: 'codebaseindex.ingest', common: true },
95
96
  { id: 'brand', summary: 'Deterministic brand intelligence', topic: 'work', skill: 'agentsam-app-fundamentals', operation: 'brand.scan' },
96
- { id: 'plan', summary: 'Composable plans (e.g. brand)', topic: 'work', skill: 'agentsam-app-fundamentals' },
97
+ { id: 'plan', summary: 'Durable project-local work plans + domain plans', topic: 'work', skill: 'agentsam-app-fundamentals' },
97
98
  { id: 'security', aliases: ['sca'], summary: 'Dependency + trust-boundary scan', topic: 'work', skill: 'agentsam-progression-guard', operation: 'security.scan', common: true },
98
99
  { id: 'merkle', summary: 'File integrity snapshots and explorer', topic: 'work', skill: 'agentsam-app-fundamentals' },
99
100
  { id: 'cad', summary: 'Blender/OpenSCAD/FreeCAD CAD tools', topic: 'work', skill: 'agentsam-app-fundamentals', operation: 'cad.blender.inspect' },
package/src/cli.js CHANGED
@@ -25,12 +25,14 @@ import { runStatus } from './commands/status.js';
25
25
  import { runInteractive } from './commands/interactive.js';
26
26
  import { runShell } from './commands/shell.js';
27
27
  import { runGoap } from './commands/goap.js';
28
- import { runBrand, runPlan } from './commands/brand.js';
28
+ import { runBrand } from './commands/brand.js';
29
+ import { runPlan } from './commands/plan.js';
29
30
  import { runDockerize } from './commands/dockerize.js';
30
31
  import { runMini } from './commands/mini.js';
31
32
  import { runMerkle } from './commands/merkle.js';
32
33
  import { runDeployReceipt } from './commands/deploy-receipt.js';
33
34
  import { runSecurity } from './commands/security.js';
35
+ import { runPackage } from './commands/package.js';
34
36
  import { runRecon } from './commands/recon.js';
35
37
  import { runCad } from './commands/cad.js';
36
38
  import { runMachine } from './commands/machine.js';
@@ -728,6 +730,13 @@ if (command === '--version' || command === '-v') {
728
730
  reportCliError(e);
729
731
  process.exitCode = 1;
730
732
  }
733
+ } else if (command === 'package') {
734
+ try {
735
+ await runPackage(rest);
736
+ } catch (e) {
737
+ reportCliError(e);
738
+ process.exitCode = 1;
739
+ }
731
740
  } else if (command === 'security' || command === 'sca') {
732
741
  await runSecurity(rest);
733
742
  } else if (command === 'skills') {
@@ -0,0 +1,134 @@
1
+ import { buildRepositoryAuditPacket } from '../agent/repository-audit.js';
2
+ import { repositorySnapshot } from '../capabilities/repository-snapshot.js';
3
+ import { getNextPlanStep, getPlan, openPlanLedger } from './plan-ledger.js';
4
+ import { projectGoapWorld } from '../../packages/agentsam-goap/src/world.js';
5
+
6
+ const PRIORITY_TO_TICKET = Object.freeze({
7
+ critical: 'P0',
8
+ high: 'P1',
9
+ medium: 'P2',
10
+ low: 'P3',
11
+ });
12
+
13
+ function stableJson(value) {
14
+ if (Array.isArray(value)) return '[' + value.map(stableJson).join(',') + ']';
15
+ if (value && typeof value === 'object') {
16
+ return '{' + Object.keys(value).sort().map((key) => JSON.stringify(key) + ':' + stableJson(value[key])).join(',') + '}';
17
+ }
18
+ return JSON.stringify(value);
19
+ }
20
+
21
+ export function knowledgeFreshness(snapshot = {}) {
22
+ const knowledge = snapshot.knowledge || {};
23
+ if (!knowledge.configured) return { status: 'not_configured', reason: 'knowledge_config_missing' };
24
+ if (!knowledge.indexed) return { status: 'not_indexed', reason: 'active_generation_missing' };
25
+ const receipt = knowledge.receipt || {};
26
+ if (receipt.scope && knowledge.scope && stableJson(receipt.scope) !== stableJson(knowledge.scope)) {
27
+ return { status: 'stale', reason: 'scope_policy_changed' };
28
+ }
29
+ if (receipt.merkle_root && snapshot.tree?.merkle_root && receipt.merkle_root !== snapshot.tree.merkle_root) {
30
+ return { status: 'stale', reason: 'repository_merkle_changed' };
31
+ }
32
+ return { status: 'current', reason: 'active_generation_matches_world' };
33
+ }
34
+
35
+ export async function buildLocalGoapState({ cwd = process.cwd(), snapshot = null } = {}) {
36
+ const ctx = openPlanLedger(cwd);
37
+ try {
38
+ const plan = getPlan(ctx, 'current');
39
+ if (!plan) return null;
40
+
41
+ const running = (plan.tasks || []).find((task) => task.status === 'running') || null;
42
+ const next = running ? null : getNextPlanStep(ctx, { planId: plan.id });
43
+ const step = running || next?.step || null;
44
+ const world = snapshot || await repositorySnapshot({ cwd: ctx.root });
45
+ const packet = buildRepositoryAuditPacket({
46
+ snapshot: world,
47
+ focus: [plan.title, step?.title].filter(Boolean),
48
+ requestedSections: ['repository', 'tree', 'knowledge', 'packages'],
49
+ evidenceBudget: 6000,
50
+ });
51
+ const freshness = knowledgeFreshness(world);
52
+ const projectedWorld = projectGoapWorld({
53
+ repository: {
54
+ ...world.repository,
55
+ merkle_root: world.tree?.merkle_root || null,
56
+ },
57
+ plan,
58
+ activeTodo: step,
59
+ knowledge: {
60
+ ...freshness,
61
+ generation_id: world.knowledge?.generation_id || null,
62
+ },
63
+ evidence: packet,
64
+ updatedAt: step?.updated_at_unix || plan.updated_at_unix || null,
65
+ });
66
+ const run = step?.agent_run_id
67
+ ? ctx.db.prepare('SELECT * FROM agentsam_agent_run WHERE id = ? LIMIT 1').get(step.agent_run_id) || null
68
+ : null;
69
+
70
+ const git = {
71
+ root: ctx.root,
72
+ repoFullName: world.repository?.full_name || ctx.git?.repoFullName || null,
73
+ revisionSha: world.repository?.revision_sha || ctx.git?.revisionSha || null,
74
+ branch: world.repository?.branch || ctx.git?.branch || null,
75
+ dirty: world.repository?.dirty ?? ctx.git?.dirty ?? null,
76
+ };
77
+ const activeTicket = step ? {
78
+ id: step.id,
79
+ title: step.title,
80
+ status: step.status,
81
+ priority: PRIORITY_TO_TICKET[step.priority] || 'P2',
82
+ subsystem: step.metadata?.kind || 'work',
83
+ surface: 'local',
84
+ status_reason: 'selected_from_project_local_plan',
85
+ description: step.description || null,
86
+ agent_run_id: step.agent_run_id || null,
87
+ } : {
88
+ id: plan.id,
89
+ title: plan.title,
90
+ status: plan.tasks_done === plan.tasks_total ? 'complete' : 'active',
91
+ priority: 'P2',
92
+ subsystem: 'plan',
93
+ surface: 'local',
94
+ status_reason: 'plan_has_no_open_executable_step',
95
+ agent_run_id: null,
96
+ };
97
+
98
+ return {
99
+ ok: true,
100
+ source: 'local_world',
101
+ repositoryId: world.repository?.repository_id || ctx.repositoryId,
102
+ git,
103
+ workspaceState: {
104
+ current_task_id: step?.id || null,
105
+ locked_by: 'project_local_plan',
106
+ checkpoint_sha: plan.metadata?.revision || null,
107
+ last_agent_action: 'world_snapshot_projected',
108
+ updated_at: step?.updated_at_unix || plan.updated_at_unix || null,
109
+ },
110
+ activeTicket,
111
+ agentRun: run,
112
+ recentCommits: [],
113
+ checkpoint: null,
114
+ cursor: {},
115
+ steps: plan.tasks || [],
116
+ stepsUnavailable: false,
117
+ localPlan: plan,
118
+ localStep: step,
119
+ worldSnapshot: {
120
+ snapshot_id: world.snapshot_id,
121
+ content_hash: world.content_hash,
122
+ merkle_root: world.tree?.merkle_root || null,
123
+ knowledge_generation_id: world.knowledge?.generation_id || null,
124
+ knowledge_freshness: freshness,
125
+ repository: world.repository,
126
+ actions: projectedWorld.actions,
127
+ },
128
+ boundedEvidence: packet,
129
+ canonicalWorld: projectedWorld,
130
+ };
131
+ } finally {
132
+ ctx.close();
133
+ }
134
+ }
@@ -11,6 +11,7 @@ import {
11
11
  renderGoapPlan,
12
12
  } from '../../packages/agentsam-repository/src/goap.js';
13
13
  import { readAccountSession } from '../lib/account-session.js';
14
+ import { buildLocalGoapState } from './goap-world.js';
14
15
 
15
16
  function parseArgs(args = []) {
16
17
  const flags = { _: [] };
@@ -102,7 +103,7 @@ export async function runGoap(subcommand = 'status', options = {}) {
102
103
  console.log(`Successfully created and activated GOAP goal: ${res.ticketId}`);
103
104
  console.log(` Title: ${res.title}`);
104
105
  console.log(` Priority: ${res.priority} [Subsystem: ${res.subsystem}]`);
105
- console.log(` Agent Run: ${res.agentRunId}`);
106
+ if (res.agentRunId) console.log(` Agent Run: ${res.agentRunId}`);
106
107
  return;
107
108
  }
108
109
 
@@ -147,9 +148,15 @@ export async function runGoap(subcommand = 'status', options = {}) {
147
148
  return;
148
149
  }
149
150
 
150
- const state = await readGoapState({ cwd, accountId });
151
- if (!state.ok) {
152
- console.error(`Error reading GOAP state: ${state.error || 'unknown error'}`);
151
+ let state = null;
152
+ try {
153
+ state = await buildLocalGoapState({ cwd });
154
+ } catch (error) {
155
+ if (jsonMode && options.debug) console.error(error?.stack || error);
156
+ }
157
+ if (!state && accountId) state = await readGoapState({ cwd, accountId });
158
+ if (!state?.ok) {
159
+ console.error(`Error reading GOAP state: ${state?.error || 'no local plan or remote GOAP state available'}`);
153
160
  return;
154
161
  }
155
162
 
@@ -1,16 +1,18 @@
1
1
  /**
2
2
  * Resolve the agentsam-machine native binary.
3
3
  * Preference order:
4
- * 1. AGENTSAM_MACHINE_BIN
5
- * 2. agentsam-machine on PATH
6
- * 3. Built binary under native/agentsam-machine/target/{release,debug}
7
- * 4. cargo run --manifest-path … (dev fallback inside the SDK repo)
4
+ * 1. AgentSam-managed user runtime under ~/.agentsam/runtimes/machine
5
+ * 2. AGENTSAM_MACHINE_BIN explicit override
6
+ * 3. agentsam-machine on PATH
7
+ * 4. Built binary under native/agentsam-machine/target/{release,debug}
8
+ * 5. cargo run --manifest-path (SDK contributor fallback)
8
9
  */
9
10
 
10
11
  import fs from 'node:fs';
11
12
  import path from 'node:path';
12
13
  import { fileURLToPath } from 'node:url';
13
14
  import { spawnSync } from 'node:child_process';
15
+ import { findExecutable, managedMachineResolution } from './machine-runtime.js';
14
16
 
15
17
  const here = path.dirname(fileURLToPath(import.meta.url));
16
18
  const sdkRoot = path.resolve(here, '../..');
@@ -18,7 +20,7 @@ const machineCrate = path.join(sdkRoot, 'native/agentsam-machine');
18
20
  const machineManifest = path.join(machineCrate, 'Cargo.toml');
19
21
 
20
22
  /**
21
- * @typedef {{ kind: 'binary', path: string, source: string } | { kind: 'cargo', manifest: string, source: string } | { kind: 'missing', tried: string[] }} MachineBinaryResolution
23
+ * @typedef {{ kind: 'binary', path: string, source: string, version?: string } | { kind: 'cargo', manifest: string, source: string } | { kind: 'missing', tried: string[] }} MachineBinaryResolution
22
24
  */
23
25
 
24
26
  /**
@@ -27,6 +29,17 @@ const machineManifest = path.join(machineCrate, 'Cargo.toml');
27
29
  export function resolveMachineBinary(env = process.env) {
28
30
  const tried = [];
29
31
 
32
+ const managed = managedMachineResolution(env);
33
+ tried.push(...managed.tried);
34
+ if (managed.available) {
35
+ return {
36
+ kind: 'binary',
37
+ path: managed.path,
38
+ source: 'managed-runtime',
39
+ version: managed.state.current_version,
40
+ };
41
+ }
42
+
30
43
  const explicit = String(env.AGENTSAM_MACHINE_BIN || '').trim();
31
44
  if (explicit) {
32
45
  tried.push(explicit);
@@ -35,25 +48,25 @@ export function resolveMachineBinary(env = process.env) {
35
48
  }
36
49
  }
37
50
 
38
- const pathHit = which('agentsam-machine');
39
- if (pathHit) {
40
- return { kind: 'binary', path: pathHit, source: 'PATH' };
41
- }
51
+ const pathHit = findExecutable('agentsam-machine', env);
52
+ if (pathHit) return { kind: 'binary', path: pathHit, source: 'PATH' };
42
53
  tried.push('PATH:agentsam-machine');
43
54
 
44
55
  for (const rel of ['target/release/agentsam-machine', 'target/debug/agentsam-machine']) {
45
56
  const candidate = path.join(machineCrate, rel);
46
57
  tried.push(candidate);
47
58
  if (fs.existsSync(candidate) && fs.statSync(candidate).isFile()) {
48
- return { kind: 'binary', path: candidate, source: rel.includes('release') ? 'crate-release' : 'crate-debug' };
59
+ return {
60
+ kind: 'binary',
61
+ path: candidate,
62
+ source: rel.includes('release') ? 'crate-release' : 'crate-debug',
63
+ };
49
64
  }
50
65
  }
51
66
 
52
67
  if (fs.existsSync(machineManifest)) {
53
- const cargo = which('cargo');
54
- if (cargo) {
55
- return { kind: 'cargo', manifest: machineManifest, source: 'cargo-run' };
56
- }
68
+ const cargo = findExecutable('cargo', env);
69
+ if (cargo) return { kind: 'cargo', manifest: machineManifest, source: 'cargo-run' };
57
70
  tried.push('cargo');
58
71
  }
59
72
 
@@ -62,7 +75,7 @@ export function resolveMachineBinary(env = process.env) {
62
75
 
63
76
  /**
64
77
  * @param {MachineBinaryResolution} resolution
65
- * @param {string[]} machineArgv args after `agentsam machine` (e.g. ['inspect', './site', '--json'])
78
+ * @param {string[]} machineArgv
66
79
  * @param {{ stdio?: import('node:child_process').StdioOptions, env?: NodeJS.ProcessEnv }} [options]
67
80
  */
68
81
  export function spawnMachine(resolution, machineArgv, options = {}) {
@@ -73,6 +86,7 @@ export function spawnMachine(resolution, machineArgv, options = {}) {
73
86
  if (resolution.kind === 'binary') {
74
87
  return spawnSync(resolution.path, machineArgv, { stdio, env, encoding: 'utf8', maxBuffer });
75
88
  }
89
+
76
90
  if (resolution.kind === 'cargo') {
77
91
  return spawnSync(
78
92
  'cargo',
@@ -80,24 +94,16 @@ export function spawnMachine(resolution, machineArgv, options = {}) {
80
94
  { stdio, env, encoding: 'utf8', maxBuffer },
81
95
  );
82
96
  }
97
+
83
98
  const err = new Error(
84
- `agentsam-machine binary not found. Tried: ${(resolution.tried || []).join(', ') || '(none)'}. Build with: cargo build --manifest-path native/agentsam-machine/Cargo.toml --release`,
99
+ 'agentsam-machine is not installed. Run: agentsam machine install. ' +
100
+ 'Standalone Cargo users can run: cargo install agentsam-machine-cli. ' +
101
+ 'Tried: ' + ((resolution.tried || []).join(', ') || '(none)'),
85
102
  );
86
103
  err.code = 'AGENTSAM_MACHINE_BINARY_MISSING';
87
104
  throw err;
88
105
  }
89
106
 
90
- function which(cmd) {
91
- const probe = process.platform === 'win32' ? ['where', [cmd]] : ['which', [cmd]];
92
- const result = spawnSync(probe[0], probe[1], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] });
93
- if (result.status !== 0) return null;
94
- const line = String(result.stdout || '')
95
- .split(/\r?\n/)
96
- .map((s) => s.trim())
97
- .find(Boolean);
98
- return line || null;
99
- }
100
-
101
107
  export function machineSdkRoot() {
102
108
  return sdkRoot;
103
109
  }