@inneranimalmedia/agentsam-sdk 2.6.7 → 2.6.9

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 (371) hide show
  1. package/README.md +37 -0
  2. package/apps/README.md +25 -0
  3. package/apps/cad-creator/shared/cad/package.json +1 -1
  4. package/apps/client-cms-editor/backend/package.json +4 -6
  5. package/apps/client-cms-editor/frontend/package.json +6 -8
  6. package/apps/client-cms-editor/frontend/tsconfig.json +27 -8
  7. package/apps/client-cms-editor/package.json +1 -1
  8. package/apps/client-cms-editor/shared/cms/package.json +4 -6
  9. package/docs/LOCAL_ENGINE_COMPUTE_AUDIT_PLAN.md +299 -0
  10. package/docs/REPO_FILE_MAP.txt +132 -0
  11. package/migrations/d1/0018_goap_control_plane_remaster.sql +40 -0
  12. package/migrations/d1/0019_agentsam_agent_run_plan_todo.sql +14 -0
  13. package/migrations/d1/README_PORTABLE_CONTROL_PLANE.md +20 -9
  14. package/migrations/runtime/0002_goap_blackboard_v1.sql +15 -0
  15. package/migrations/runtime/0004_agent_run_plan_linkage.sql +8 -0
  16. package/native/agentsam-machine/cli/Cargo.toml +8 -1
  17. package/native/agentsam-machine/cli/README.md +21 -0
  18. package/native/agentsam-machine/core/Cargo.toml +7 -0
  19. package/native/agentsam-machine/core/README.md +14 -0
  20. package/native/agentsam-machine/core/build.rs +33 -0
  21. package/native/agentsam-machine/core/contracts/source-types.v1.json +353 -0
  22. package/native/agentsam-machine/core/src/lib.rs +6 -0
  23. package/native/agentsam-machine/core/src/source_types.rs +2 -2
  24. package/package.json +31 -10
  25. package/packages/agentsam-brand/package.json +1 -1
  26. package/packages/agentsam-contracts/package.json +71 -20
  27. package/packages/agentsam-contracts/scripts/build.mjs +18 -0
  28. package/packages/agentsam-contracts/test/contracts.test.mjs +4 -1
  29. package/packages/agentsam-contracts/test/repository.test.mjs +4 -1
  30. package/packages/agentsam-contracts/tsconfig.build.json +10 -0
  31. package/packages/agentsam-errors/package.json +3 -2
  32. package/packages/agentsam-errors/src/index.js +1 -0
  33. package/packages/agentsam-errors/src/tool.js +56 -0
  34. package/packages/agentsam-errors/test/tool.test.mjs +58 -0
  35. package/packages/agentsam-goap/README.md +52 -0
  36. package/packages/agentsam-goap/package.json +37 -0
  37. package/packages/agentsam-goap/src/adapters/d1-sqlite.js +570 -0
  38. package/packages/agentsam-goap/src/adapters/memory.js +199 -0
  39. package/packages/agentsam-goap/src/contracts.js +226 -0
  40. package/packages/agentsam-goap/src/control-plane.js +112 -0
  41. package/packages/agentsam-goap/src/errors.js +157 -0
  42. package/packages/agentsam-goap/src/index.js +5 -0
  43. package/packages/agentsam-goap/src/world.js +202 -0
  44. package/packages/agentsam-goap/test/goap-control-plane.test.mjs +245 -0
  45. package/packages/agentsam-goap/test/world.test.mjs +79 -0
  46. package/packages/agentsam-knowledge/package.json +3 -2
  47. package/packages/agentsam-nav/package.json +1 -1
  48. package/packages/agentsam-queue-control/package.json +1 -1
  49. package/packages/agentsam-rapid-rust/src/main.rs +1 -0
  50. package/packages/agentsam-repository/package.json +3 -2
  51. package/packages/agentsam-repository/src/goap.js +13 -14
  52. package/packages/agentsam-repository/src/tickets.js +15 -22
  53. package/packages/agentsam-repository/test/goap-tickets-workspace-state.test.mjs +19 -8
  54. package/packages/agentsam-vault/package.json +8 -5
  55. package/packages/agentsam-workbench/package.json +44 -17
  56. package/packages/connectors/cloudflare/package.json +4 -2
  57. package/packages/heuristic-theme/package.json +1 -1
  58. package/packages/identity/package.json +4 -3
  59. package/packages/identity/tests/lane1-packed-consumer.test.mjs +10 -2
  60. package/packages/providers/completeful/package.json +1 -1
  61. package/packages/theme-church-site/README.md +2 -2
  62. package/packages/theme-church-site/package.json +3 -4
  63. package/packages/theme-church-site/src/index.js +1 -1
  64. package/packages/theme-church-site/test/theme.test.mjs +1 -1
  65. package/packages/theme-companions-site/README.md +2 -2
  66. package/packages/theme-companions-site/package.json +3 -4
  67. package/packages/theme-companions-site/src/index.js +1 -1
  68. package/packages/theme-companions-site/test/theme.test.mjs +1 -1
  69. package/packages/theme-floors-site/README.md +2 -2
  70. package/packages/theme-floors-site/package.json +3 -4
  71. package/packages/theme-floors-site/src/index.js +1 -1
  72. package/packages/theme-floors-site/test/theme.test.mjs +1 -1
  73. package/packages/theme-fuelnfree-site/README.md +2 -2
  74. package/packages/theme-fuelnfree-site/package.json +3 -4
  75. package/packages/theme-fuelnfree-site/src/index.js +1 -1
  76. package/packages/theme-fuelnfree-site/test/theme.test.mjs +1 -1
  77. package/packages/theme-handyman-site/README.md +2 -2
  78. package/packages/theme-handyman-site/package.json +3 -4
  79. package/packages/theme-handyman-site/src/index.js +1 -1
  80. package/packages/theme-handyman-site/test/theme.test.mjs +1 -1
  81. package/packages/theme-insurance-site/README.md +2 -2
  82. package/packages/theme-insurance-site/package.json +3 -4
  83. package/packages/theme-insurance-site/src/index.js +1 -1
  84. package/packages/theme-insurance-site/test/theme.test.mjs +1 -1
  85. package/packages/theme-scenes/package.json +1 -1
  86. package/packages/theme-shinshu-site/README.md +2 -2
  87. package/packages/theme-shinshu-site/package.json +3 -4
  88. package/packages/theme-shinshu-site/src/index.js +1 -1
  89. package/packages/theme-shinshu-site/test/theme.test.mjs +1 -1
  90. package/packages/work-graph/package.json +3 -2
  91. package/protocol/local-engine/benchmark.v1.schema.json +14 -0
  92. package/protocol/local-engine/engine.v1.schema.json +17 -0
  93. package/python/agentsam_sdk/repository/intelligence/discovery.py +27 -2
  94. package/python/agentsam_sdk/repository/intelligence/git.py +4 -0
  95. package/python/tests/test_repository_intelligence.py +30 -0
  96. package/src/cli/command-catalog.js +3 -1
  97. package/src/cli.js +20 -1
  98. package/src/commands/app.js +10 -0
  99. package/src/commands/engine.js +10 -0
  100. package/src/commands/goap-world.js +134 -0
  101. package/src/commands/goap.js +11 -4
  102. package/src/commands/machine-binary.js +33 -27
  103. package/src/commands/machine-runtime.js +266 -0
  104. package/src/commands/machine.js +155 -51
  105. package/src/commands/package.js +537 -0
  106. package/src/commands/plan-ledger.js +370 -0
  107. package/src/commands/plan.js +183 -0
  108. package/src/commands/runtime.js +25 -10
  109. package/src/commands/setup.js +30 -6
  110. package/src/commands/skill.js +78 -17
  111. package/src/commands/terminal.js +20 -8
  112. package/src/errors/contract.js +4 -4
  113. package/src/errors/diagnostic.js +1 -1
  114. package/src/errors/index.js +1 -1
  115. package/src/index.js +20 -0
  116. package/src/indexing/ingest/materials.js +237 -30
  117. package/src/knowledge/source.js +1 -1
  118. package/src/lib/setup/runtime.js +4 -2
  119. package/src/lib/slash-commands.js +1 -1
  120. package/src/local/runtime-store.js +24 -2
  121. package/src/local/sqlite.js +17 -0
  122. package/src/local-engine/assets.js +37 -0
  123. package/src/local-engine/audit.js +133 -0
  124. package/src/local-engine/benchmark.js +26 -0
  125. package/src/local-engine/contracts.js +101 -0
  126. package/src/local-engine/engines.js +142 -0
  127. package/src/local-engine/index.js +18 -0
  128. package/src/local-engine/runtime.js +39 -0
  129. package/src/sam/operations/package-audit.js +41 -0
  130. package/src/sam/seed.js +2 -0
  131. package/skills/grok-auth/SKILL.md +0 -110
  132. package/skills/grok-auth/agentsam.skill.json +0 -25
  133. package/skills/grok-auth/references/grok-identity.md +0 -64
  134. package/skills/grok-auth/references/per-user-data.md +0 -49
  135. package/skills/grok-auth/references/prewired-and-env.md +0 -54
  136. package/skills/grok-auth/references/session-ui.md +0 -133
  137. package/skills/grok-auth/references/sign-in-methods.md +0 -55
  138. package/skills/grok-auth/references/wiring.md +0 -71
  139. package/skills/grok-building-games/SKILL.md +0 -213
  140. package/skills/grok-building-games/agentsam.skill.json +0 -25
  141. package/skills/grok-building-games/references/3d-libs.md +0 -64
  142. package/skills/grok-building-games/references/ai-pathfinding.md +0 -122
  143. package/skills/grok-building-games/references/audio.md +0 -129
  144. package/skills/grok-building-games/references/babylon.md +0 -202
  145. package/skills/grok-building-games/references/collision-physics.md +0 -122
  146. package/skills/grok-building-games/references/ecs-architecture.md +0 -111
  147. package/skills/grok-building-games/references/game-feel-juice.md +0 -110
  148. package/skills/grok-building-games/references/genres/board-card-chess.md +0 -89
  149. package/skills/grok-building-games/references/genres/endless-runner.md +0 -83
  150. package/skills/grok-building-games/references/genres/fps.md +0 -105
  151. package/skills/grok-building-games/references/genres/platformer-2d.md +0 -97
  152. package/skills/grok-building-games/references/genres/puzzle-match3-tetris.md +0 -131
  153. package/skills/grok-building-games/references/genres/racing-kart.md +0 -106
  154. package/skills/grok-building-games/references/genres/topdown-twin-stick.md +0 -97
  155. package/skills/grok-building-games/references/genres/tower-defense.md +0 -84
  156. package/skills/grok-building-games/references/genres/voxel-minecraft.md +0 -89
  157. package/skills/grok-building-games/references/input.md +0 -139
  158. package/skills/grok-building-games/references/phaser.md +0 -277
  159. package/skills/grok-building-games/references/procedural-generation.md +0 -141
  160. package/skills/grok-building-games/references/save-persistence.md +0 -108
  161. package/skills/grok-building-games/references/threejs-foundational.md +0 -148
  162. package/skills/grok-controls/SKILL.md +0 -274
  163. package/skills/grok-controls/agentsam.skill.json +0 -25
  164. package/skills/grok-design-ui/SKILL.md +0 -122
  165. package/skills/grok-design-ui/agentsam.skill.json +0 -25
  166. package/skills/grok-design-ui/references/animations.md +0 -379
  167. package/skills/grok-design-ui/references/performance.md +0 -88
  168. package/skills/grok-design-ui/references/refined-ui.md +0 -384
  169. package/skills/grok-design-ui/references/surfaces.md +0 -247
  170. package/skills/grok-design-ui/references/typography.md +0 -123
  171. package/skills/grok-game-animation-frames/SKILL.md +0 -84
  172. package/skills/grok-game-animation-frames/agentsam.skill.json +0 -25
  173. package/skills/grok-game-asset-core/SKILL.md +0 -69
  174. package/skills/grok-game-asset-core/agentsam.skill.json +0 -25
  175. package/skills/grok-game-character-consistency/SKILL.md +0 -69
  176. package/skills/grok-game-character-consistency/agentsam.skill.json +0 -25
  177. package/skills/grok-game-tilesets/SKILL.md +0 -65
  178. package/skills/grok-game-tilesets/agentsam.skill.json +0 -25
  179. package/skills/grok-game-ui-icons/SKILL.md +0 -56
  180. package/skills/grok-game-ui-icons/agentsam.skill.json +0 -25
  181. package/skills/grok-generate2dmap/LICENSE +0 -21
  182. package/skills/grok-generate2dmap/SKILL.md +0 -120
  183. package/skills/grok-generate2dmap/SOURCE.md +0 -6
  184. package/skills/grok-generate2dmap/agentsam.skill.json +0 -25
  185. package/skills/grok-generate2dmap/references/deliverables.md +0 -101
  186. package/skills/grok-generate2dmap/references/layered-map-contract.md +0 -209
  187. package/skills/grok-generate2dmap/references/map-strategies.md +0 -341
  188. package/skills/grok-generate2dmap/references/object-production-gate.md +0 -24
  189. package/skills/grok-generate2dmap/references/pipeline.md +0 -149
  190. package/skills/grok-generate2dmap/references/prop-pack-contract.md +0 -174
  191. package/skills/grok-generate2dmap/references/side-scroll-stages.md +0 -29
  192. package/skills/grok-generate2dmap/scripts/compose_layered_preview.py +0 -157
  193. package/skills/grok-generate2dmap/scripts/extract_prop_pack.py +0 -369
  194. package/skills/grok-generate2dsprite/LICENSE +0 -21
  195. package/skills/grok-generate2dsprite/SKILL.md +0 -313
  196. package/skills/grok-generate2dsprite/SOURCE.md +0 -6
  197. package/skills/grok-generate2dsprite/agentsam.skill.json +0 -25
  198. package/skills/grok-generate2dsprite/references/modes.md +0 -124
  199. package/skills/grok-generate2dsprite/references/prompt-rules.md +0 -315
  200. package/skills/grok-generate2dsprite/scripts/generate2dsprite.py +0 -1031
  201. package/skills/grok-generate2dsprite/scripts/make_layout_guide.py +0 -109
  202. package/skills/grok-imagine/SKILL.md +0 -201
  203. package/skills/grok-imagine/agentsam.skill.json +0 -25
  204. package/skills/grok-multiplayer-p2p/SKILL.md +0 -111
  205. package/skills/grok-multiplayer-p2p/agentsam.skill.json +0 -25
  206. package/skills/grok-multiplayer-p2p/references/react-binding.md +0 -144
  207. package/skills/grok-multiplayer-p2p/references/signaling-relay.md +0 -269
  208. package/skills/grok-neon/SKILL.md +0 -157
  209. package/skills/grok-neon/agentsam.skill.json +0 -25
  210. package/skills/grok-og/SKILL.md +0 -102
  211. package/skills/grok-og/agentsam.skill.json +0 -25
  212. package/skills/grok-og/references/brand-pass.md +0 -53
  213. package/skills/grok-og/references/custom-card.md +0 -107
  214. package/skills/grok-og/references/favicon-and-icons.md +0 -48
  215. package/skills/grok-og/references/og-type-contract.md +0 -18
  216. package/skills/grok-og/references/placeholder-card.md +0 -21
  217. package/skills/grok-og/references/x-banner.md +0 -41
  218. package/skills/grok-threejs/SKILL.md +0 -67
  219. package/skills/grok-threejs/agentsam.skill.json +0 -25
  220. package/skills/grok-threejs/references/llms-full.txt +0 -2780
  221. package/skills/grok-video2dsprite/LICENSE +0 -21
  222. package/skills/grok-video2dsprite/SKILL.md +0 -236
  223. package/skills/grok-video2dsprite/SOURCE.md +0 -6
  224. package/skills/grok-video2dsprite/agentsam.skill.json +0 -25
  225. package/skills/grok-video2dsprite/references/pipeline.md +0 -90
  226. package/skills/grok-video2dsprite/references/prompt-rules.md +0 -63
  227. package/skills/grok-video2dsprite/scripts/video2dsprite.py +0 -490
  228. package/skills/grok-xai-api/SKILL.md +0 -152
  229. package/skills/grok-xai-api/agentsam.skill.json +0 -25
  230. package/test/account-session.test.mjs +0 -101
  231. package/test/agent-capabilities.test.mjs +0 -67
  232. package/test/app-authority-context.test.mjs +0 -32
  233. package/test/app-building-skills.test.mjs +0 -61
  234. package/test/apps-scaffold-contract.test.mjs +0 -115
  235. package/test/blender-cad.test.mjs +0 -146
  236. package/test/cad-docker.test.mjs +0 -96
  237. package/test/capabilities.test.mjs +0 -133
  238. package/test/cli/api-key-env-whoami.test.mjs +0 -129
  239. package/test/cli/catalog-authority.test.mjs +0 -64
  240. package/test/cli/codebaseindex-plan-ux.test.mjs +0 -37
  241. package/test/cli/eval-live.test.mjs +0 -219
  242. package/test/cli/go.test.mjs +0 -128
  243. package/test/cli/local-vault-and-provider-setup.test.mjs +0 -268
  244. package/test/cli/machine-command.test.mjs +0 -34
  245. package/test/cli/mcp-client.test.mjs +0 -256
  246. package/test/cli/preferences-runtime.test.mjs +0 -11
  247. package/test/cli/runtime-persist.test.mjs +0 -56
  248. package/test/cli/runtime-ui.test.mjs +0 -141
  249. package/test/cli/rust-command.test.mjs +0 -21
  250. package/test/cli/skill-npm-and-env.test.mjs +0 -52
  251. package/test/cli/status-actions.test.mjs +0 -88
  252. package/test/cli/wireframes-go-registry.test.mjs +0 -139
  253. package/test/cli-preferences.test.mjs +0 -46
  254. package/test/cloudflare-connector.test.mjs +0 -93
  255. package/test/cloudflare-runtime.test.mjs +0 -82
  256. package/test/context.test.mjs +0 -159
  257. package/test/credentials-audit.test.mjs +0 -113
  258. package/test/deploy-health-scan.test.mjs +0 -95
  259. package/test/deploy-receipt.test.mjs +0 -91
  260. package/test/dockerize.test.mjs +0 -93
  261. package/test/error-diagnostics.test.mjs +0 -124
  262. package/test/eval-context.test.mjs +0 -37
  263. package/test/execution-approvals.test.mjs +0 -27
  264. package/test/fixtures/cad/courtyard-house.json +0 -208
  265. package/test/fixtures/knowledge-rpc-worker.mjs +0 -16
  266. package/test/fixtures/project-authority/customer-app/.agentsam/app.json +0 -5
  267. package/test/fixtures/project-authority/customer-app/apps/my-product/index.ts +0 -1
  268. package/test/fixtures/project-authority/customer-app/wrangler.toml +0 -17
  269. package/test/gcloud-auth.test.mjs +0 -111
  270. package/test/go/build-source-identity.test.mjs +0 -31
  271. package/test/go/cloudflare-probe.test.mjs +0 -317
  272. package/test/go/distribution.test.mjs +0 -28
  273. package/test/google-cloud-connection.test.mjs +0 -83
  274. package/test/google-cloud-inventory.test.mjs +0 -64
  275. package/test/indexing-provider.test.mjs +0 -29
  276. package/test/init-options.test.mjs +0 -35
  277. package/test/integration/ai-access-onboarding.test.mjs +0 -47
  278. package/test/integration/app-command.test.mjs +0 -85
  279. package/test/integration/autorag-project-authority.integration.test.mjs +0 -51
  280. package/test/integration/autorag-runtime-discovery.test.mjs +0 -107
  281. package/test/integration/cad-discovery.test.mjs +0 -158
  282. package/test/integration/cad-docker-executor.test.mjs +0 -249
  283. package/test/integration/cad-execution.test.mjs +0 -184
  284. package/test/integration/cad-project-app.test.mjs +0 -31
  285. package/test/integration/cad-project-d1.test.mjs +0 -25
  286. package/test/integration/cad-project-native.test.mjs +0 -24
  287. package/test/integration/cad-project-workflow.test.mjs +0 -9
  288. package/test/integration/cad-project.test.mjs +0 -85
  289. package/test/integration/cli-help.test.mjs +0 -41
  290. package/test/integration/cms-app-scaffold.test.mjs +0 -77
  291. package/test/integration/cms-site-tenancy-contract.test.mjs +0 -268
  292. package/test/integration/codebaseindex-ingest.test.mjs +0 -255
  293. package/test/integration/core-client.integration.test.mjs +0 -55
  294. package/test/integration/database-hosted-honesty.test.mjs +0 -49
  295. package/test/integration/desktop-keychain-boundary.test.mjs +0 -45
  296. package/test/integration/error-runtime-rpc.test.mjs +0 -71
  297. package/test/integration/features-resolve.test.mjs +0 -147
  298. package/test/integration/hosted-work-host-authority.test.mjs +0 -47
  299. package/test/integration/icon-registry.test.mjs +0 -67
  300. package/test/integration/ingest-discover-models.test.mjs +0 -30
  301. package/test/integration/inspect-path-cli.test.mjs +0 -46
  302. package/test/integration/install-script.test.mjs +0 -110
  303. package/test/integration/inventory-core.test.mjs +0 -53
  304. package/test/integration/inventory-eligibility.test.mjs +0 -59
  305. package/test/integration/inventory-evidence.test.mjs +0 -125
  306. package/test/integration/knowledge-rpc.test.mjs +0 -112
  307. package/test/integration/local-fs.test.mjs +0 -113
  308. package/test/integration/local-provider-bridge.test.mjs +0 -65
  309. package/test/integration/local-studio-settings-production.test.mjs +0 -40
  310. package/test/integration/lockfile-sync.test.mjs +0 -26
  311. package/test/integration/merkle-cli.test.mjs +0 -61
  312. package/test/integration/merkle-persistence-identity.test.mjs +0 -48
  313. package/test/integration/plugins-cloudflare.integration.test.mjs +0 -28
  314. package/test/integration/provider-env-cli.test.mjs +0 -60
  315. package/test/integration/provider-factory.test.mjs +0 -197
  316. package/test/integration/repository-company-graph.test.mjs +0 -90
  317. package/test/integration/runtime-migrations.test.mjs +0 -87
  318. package/test/integration/runtime-status.integration.test.mjs +0 -227
  319. package/test/integration/sam-activity-recovery.test.mjs +0 -147
  320. package/test/integration/sam-decision.test.mjs +0 -584
  321. package/test/integration/sam-kernel.test.mjs +0 -99
  322. package/test/integration/sam-planning-astar.test.mjs +0 -279
  323. package/test/integration/scaffold-cloudflare.test.mjs +0 -46
  324. package/test/integration/skill-runtime.test.mjs +0 -240
  325. package/test/integration/storage-architecture.test.mjs +0 -154
  326. package/test/integration/store-discovery.test.mjs +0 -44
  327. package/test/integration/studio-fs-pty-e2e.test.mjs +0 -294
  328. package/test/integration/terminal-exec.integration.test.mjs +0 -86
  329. package/test/integration/theme-package-registry.test.mjs +0 -31
  330. package/test/integration/tool-runtime.test.mjs +0 -124
  331. package/test/integration/tool-schema.test.mjs +0 -59
  332. package/test/jr-dev-skill.test.mjs +0 -26
  333. package/test/knowledge-context-pack.test.mjs +0 -19
  334. package/test/knowledge-postgres.test.mjs +0 -40
  335. package/test/knowledge-service.test.mjs +0 -110
  336. package/test/knowledge.test.mjs +0 -206
  337. package/test/live/terminal-transport.live.test.mjs +0 -24
  338. package/test/local-sessions.test.mjs +0 -57
  339. package/test/local-studio-deploy.test.mjs +0 -83
  340. package/test/loopback-oauth.test.mjs +0 -53
  341. package/test/merkle-render.test.mjs +0 -31
  342. package/test/mini.test.mjs +0 -140
  343. package/test/model-catalog.test.mjs +0 -70
  344. package/test/models.test.mjs +0 -309
  345. package/test/npm10-lock.test.mjs +0 -29
  346. package/test/ollama.test.mjs +0 -137
  347. package/test/open-url.test.mjs +0 -64
  348. package/test/openai-responses.test.mjs +0 -155
  349. package/test/portable-context.test.mjs +0 -94
  350. package/test/project-config.test.mjs +0 -81
  351. package/test/project-rules.test.mjs +0 -44
  352. package/test/provider-credentials.test.mjs +0 -106
  353. package/test/rehydrate.test.mjs +0 -25
  354. package/test/release-hygiene.test.mjs +0 -42
  355. package/test/repository-snapshot-view.test.mjs +0 -112
  356. package/test/responses-runner.test.mjs +0 -465
  357. package/test/runtime-activity.test.mjs +0 -98
  358. package/test/sdk-worker-contract.test.mjs +0 -72
  359. package/test/security.test.mjs +0 -266
  360. package/test/setup-planner.test.mjs +0 -74
  361. package/test/setup-runtime.test.mjs +0 -51
  362. package/test/shell.test.mjs +0 -281
  363. package/test/skills.test.mjs +0 -22
  364. package/test/smoke.mjs +0 -122
  365. package/test/telemetry.test.mjs +0 -79
  366. package/test/terminal/local-pty.mock.test.mjs +0 -153
  367. package/test/terminal-machine-identity.test.mjs +0 -88
  368. package/test/theme-portability.test.mjs +0 -14
  369. package/test/tools-search.test.mjs +0 -73
  370. package/test/unit/website-assets-bindings.test.mjs +0 -60
  371. package/test/whoami-resume.test.mjs +0 -157
@@ -49,25 +49,86 @@ function looksLikeNpmPackage(source) {
49
49
  * Download an npm package tarball and return the extracted package root
50
50
  * that contains agentsam.skill.json (or package root for relative resolve).
51
51
  */
52
+
53
+ function buildNpmPackEnv(baseEnv = process.env) {
54
+ const env = { ...baseEnv };
55
+
56
+ // resolveNpmSkillPackage requires a physical tarball.
57
+ // Parent npm lifecycle flags such as `npm publish --dry-run`
58
+ // must not change the semantics of this nested npm invocation.
59
+ for (const key of Object.keys(env)) {
60
+ if (/^npm_config_dry[_-]?run$/i.test(key)) {
61
+ delete env[key];
62
+ }
63
+ }
64
+
65
+ return env;
66
+ }
67
+
52
68
  export function resolveNpmSkillPackage(spec, options = {}) {
53
69
  const spawn = options.spawnSyncImpl || spawnSync;
54
- const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'agentsam-skill-npm-'));
55
- const pack = spawn('npm', ['pack', spec, '--pack-destination', tmp], {
56
- encoding: 'utf8',
57
- cwd: options.cwd || process.cwd(),
58
- env: options.env || process.env,
59
- });
60
- if ((pack.status ?? 1) !== 0) {
61
- throw new Error(`npm_pack_failed:${spec}:${String(pack.stderr || pack.stdout || '').trim() || 'unknown'}`);
62
- }
63
- const tgzName = String(pack.stdout || '')
64
- .trim()
65
- .split(/\r?\n/)
66
- .filter(Boolean)
67
- .pop();
68
- if (!tgzName) throw new Error(`npm_pack_empty:${spec}`);
69
- const tgzPath = path.join(tmp, path.basename(tgzName));
70
- if (!fs.existsSync(tgzPath)) throw new Error(`npm_pack_missing:${tgzPath}`);
70
+ const maxPackAttempts = 2;
71
+
72
+ let tmp = null;
73
+ let tgzPath = null;
74
+ let lastExpectedPath = null;
75
+
76
+ for (let attempt = 1; attempt <= maxPackAttempts; attempt += 1) {
77
+ tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'agentsam-skill-npm-'));
78
+
79
+ const pack = spawn('npm', ['pack', spec, '--json', '--pack-destination', tmp], {
80
+ encoding: 'utf8',
81
+ cwd: options.cwd || process.cwd(),
82
+ env: buildNpmPackEnv(options.env || process.env),
83
+ });
84
+
85
+ if ((pack.status ?? 1) !== 0) {
86
+ throw new Error(
87
+ `npm_pack_failed:${spec}:${String(pack.stderr || pack.stdout || '').trim() || 'unknown'}`,
88
+ );
89
+ }
90
+
91
+ let tgzName = null;
92
+
93
+ try {
94
+ const payload = JSON.parse(String(pack.stdout || ''));
95
+ const entry = Array.isArray(payload) ? payload[0] : payload;
96
+ if (entry?.filename) tgzName = path.basename(String(entry.filename));
97
+ } catch {
98
+ // Fall through to filesystem discovery.
99
+ }
100
+
101
+ const packed = fs.readdirSync(tmp)
102
+ .filter((name) => name.endsWith('.tgz'))
103
+ .sort();
104
+
105
+ if (!tgzName && packed.length === 1) {
106
+ tgzName = packed[0];
107
+ }
108
+
109
+ if (tgzName) {
110
+ const expected = path.join(tmp, tgzName);
111
+ lastExpectedPath = expected;
112
+
113
+ if (fs.existsSync(expected)) {
114
+ tgzPath = expected;
115
+ break;
116
+ }
117
+ }
118
+
119
+ // npm occasionally reports success before producing no artifact.
120
+ // Treat only that narrow condition as transient and retry once.
121
+ if (attempt < maxPackAttempts) {
122
+ fs.rmSync(tmp, { recursive: true, force: true });
123
+ tmp = null;
124
+ }
125
+ }
126
+
127
+ if (!tmp || !tgzPath || !fs.existsSync(tgzPath)) {
128
+ throw new Error(
129
+ `npm_pack_missing:${lastExpectedPath || spec}:attempts=${maxPackAttempts}`,
130
+ );
131
+ }
71
132
 
72
133
  const extractDir = path.join(tmp, 'pkg');
73
134
  fs.mkdirSync(extractDir, { recursive: true });
@@ -30,6 +30,21 @@ function printIdentity(identity, write) {
30
30
  write(`hw_model: ${identity.model || 'unknown'}`);
31
31
  }
32
32
 
33
+ function terminalUsage() {
34
+ return [
35
+ 'agentsam terminal — device identity and ExecOS enrollment',
36
+ '',
37
+ 'Usage:',
38
+ ' agentsam terminal identity [--json]',
39
+ ' agentsam terminal enroll --instance <id> [--endpoint <url>] [--pair] [--json]',
40
+ ' agentsam terminal --help',
41
+ '',
42
+ 'Identity lanes:',
43
+ ' AGENTSAM_API_KEY account/CLI identity used to mint enrollment',
44
+ ' AGENTSAM_BRIDGE_KEY one terminal_connection credential written by --pair',
45
+ ].join('\n');
46
+ }
47
+
33
48
  function defaultExecosEnrollBin() {
34
49
  return path.join(homedir(), 'ExecOS', 'bin', 'enroll.mjs');
35
50
  }
@@ -52,6 +67,10 @@ function pairWithExecos(enrollmentToken, options = {}) {
52
67
 
53
68
  export async function runTerminal(argv = [], options = {}) {
54
69
  const write = options.write || ((line) => console.log(line));
70
+ if (argv.includes('--help') || argv.includes('-h') || argv.includes('help')) {
71
+ write(terminalUsage());
72
+ return { ok: true, help: true };
73
+ }
55
74
  const sub = argv[0] && !argv[0].startsWith('--') ? argv[0] : 'identity';
56
75
  const json = argv.includes('--json') || options.json === true;
57
76
  const pair = argv.includes('--pair') || options.pair === true;
@@ -70,14 +89,7 @@ export async function runTerminal(argv = [], options = {}) {
70
89
  }
71
90
 
72
91
  if (sub !== 'enroll') {
73
- write([
74
- 'Usage: agentsam terminal identity [--json]',
75
- ' agentsam terminal enroll --instance <id> [--endpoint <url>] [--pair] [--json]',
76
- '',
77
- 'Lanes:',
78
- ' AGENTSAM_API_KEY account (CLI / whoami / mint enrollment) — required for this command',
79
- ' AGENTSAM_BRIDGE_KEY one terminal_connection secret (written by --pair into ExecOS profile)',
80
- ].join('\n'));
92
+ write(terminalUsage());
81
93
  return { ok: false, error: 'terminal_usage' };
82
94
  }
83
95
 
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  ERROR_CODE,
4
4
  ERROR_REASON,
5
- } from '../../packages/agentsam-errors/src/vocabulary.js';
6
- import { canonicalCodeFromHttpStatus } from '../../packages/agentsam-errors/src/envelope.js';
5
+ } from '@inneranimalmedia/agentsam-errors';
6
+ import { canonicalCodeFromHttpStatus } from '@inneranimalmedia/agentsam-errors';
7
7
 
8
8
  export {
9
9
  ERROR_SCHEMA_VERSION,
@@ -15,7 +15,7 @@ export {
15
15
  ERROR_DOMAIN,
16
16
  REMEDIATION_ACTION,
17
17
  GRPC_STATUS,
18
- } from '../../packages/agentsam-errors/src/vocabulary.js';
18
+ } from '@inneranimalmedia/agentsam-errors';
19
19
 
20
20
  export {
21
21
  canonicalCodeFromHttpStatus,
@@ -27,7 +27,7 @@ export {
27
27
  assertErrorEnvelope,
28
28
  serializeError,
29
29
  parseError,
30
- } from '../../packages/agentsam-errors/src/envelope.js';
30
+ } from '@inneranimalmedia/agentsam-errors';
31
31
 
32
32
  // Legacy compact classifier shapes remain public here; richer envelope classifiers
33
33
  // live in packages/agentsam-errors and are available via the other adapter exports.
@@ -6,7 +6,7 @@ import {
6
6
  normalizeError,
7
7
  redactErrorValue,
8
8
  redactString,
9
- } from '../../packages/agentsam-errors/src/index.js';
9
+ } from '@inneranimalmedia/agentsam-errors';
10
10
 
11
11
  const DEFAULT_MAX_DETAIL_CHARS = 12_000;
12
12
  function clean(value) { return value == null ? '' : String(value).trim(); }
@@ -1,4 +1,4 @@
1
- export * from '../../packages/agentsam-errors/src/index.js';
1
+ export * from '@inneranimalmedia/agentsam-errors';
2
2
 
3
3
  export {
4
4
  AgentSamDiagnosticError,
package/src/index.js CHANGED
@@ -77,6 +77,26 @@ export {
77
77
  terminalExec,
78
78
  } from './capabilities/index.js';
79
79
  export { getPreset, listPresets, resolvePreset, getAddon, listAddons } from './presets/index.js';
80
+ export {
81
+ LOCAL_ENGINE_SCHEMA,
82
+ LOCAL_ENGINE_BENCHMARK_SCHEMA,
83
+ ENGINE_CAPABILITIES,
84
+ LocalEngineRegistry,
85
+ createLocalEngineRegistry,
86
+ createOllamaEngine,
87
+ createMlxLmEngine,
88
+ createLlamaCppEngine,
89
+ auditLocalCompute,
90
+ auditHost,
91
+ auditAppleHost,
92
+ auditTools,
93
+ auditAssets,
94
+ adoptAsset,
95
+ readAssetManifest,
96
+ assetManifestPath,
97
+ benchmarkEngine,
98
+ validateStructuredOutput,
99
+ } from './local-engine/index.js';
80
100
  export {
81
101
  COMPANY_REPOSITORY_GRAPH_SCHEMA_VERSION,
82
102
  REPOSITORY_STATUSES,
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Material intake for codebaseindex.ingest — paths pasted/dropped into the CLI.
3
- * Handles archives (tar/zip), sites/builds, HTML, images, GLB, and mixed trees.
3
+ * Archives are inspected first and selectively mined instead of blindly unpacked.
4
4
  */
5
5
 
6
6
  import fs from 'node:fs';
@@ -12,6 +12,20 @@ import { isCodeSourceExtension, isDocumentSourceExtension } from '../../../packa
12
12
  const ARCHIVE_EXT = new Set(['.zip', '.tar', '.tgz', '.gz', '.tar.gz', '.tbz2', '.tar.bz2']);
13
13
  const IMAGE_EXT = new Set(['.png', '.jpg', '.jpeg', '.gif', '.webp', '.svg', '.ico', '.bmp', '.avif']);
14
14
  const MODEL_3D_EXT = new Set(['.glb', '.gltf', '.obj', '.fbx', '.stl', '.usdz']);
15
+ const VIDEO_EXT = new Set(['.mp4', '.mov', '.m4v', '.webm', '.mkv', '.avi', '.mpeg', '.mpg']);
16
+ const AUDIO_EXT = new Set(['.mp3', '.wav', '.m4a', '.aac', '.ogg', '.flac']);
17
+ const TEXT_BASENAMES = new Set([
18
+ 'readme', 'license', 'licence', 'dockerfile', 'makefile', 'procfile', 'gemfile', 'rakefile',
19
+ 'cargo.lock', 'package-lock.json', 'pnpm-lock.yaml', 'yarn.lock', '.gitignore', '.npmrc', '.editorconfig',
20
+ ]);
21
+ const DEFAULT_ARCHIVE_POLICY = Object.freeze({
22
+ maxEntries: 10_000,
23
+ maxFiles: 2_000,
24
+ maxEntryBytes: 8 * 1024 * 1024,
25
+ maxTotalBytes: 128 * 1024 * 1024,
26
+ includeAssets: false,
27
+ });
28
+
15
29
  function clean(value) {
16
30
  return value == null ? '' : String(value).trim();
17
31
  }
@@ -43,9 +57,7 @@ export function parsePastedPaths(text) {
43
57
  return [...new Set(paths)];
44
58
  }
45
59
 
46
- /**
47
- * @param {string} filePath
48
- */
60
+ /** @param {string} filePath */
49
61
  export function classifyMaterial(filePath) {
50
62
  const resolved = path.resolve(filePath);
51
63
  const ext = extOf(resolved);
@@ -79,37 +91,237 @@ function hashFile(filePath) {
79
91
 
80
92
  function hasBin(name) {
81
93
  const result = spawnSync(name, ['--help'], { stdio: 'ignore' });
82
- // Some tools exit non-zero on --help; presence of spawn failure matters more.
83
94
  return result.error == null;
84
95
  }
85
96
 
97
+ function archiveFormat(archivePath) {
98
+ const lower = archivePath.toLowerCase();
99
+ if (lower.endsWith('.zip')) return 'zip';
100
+ if (lower.endsWith('.tar') || lower.endsWith('.tar.gz') || lower.endsWith('.tgz')
101
+ || lower.endsWith('.tar.bz2') || lower.endsWith('.tbz2')) return 'tar';
102
+ if (lower.endsWith('.gz')) return 'gzip';
103
+ return null;
104
+ }
105
+
106
+ function archiveEntryKind(entryPath) {
107
+ const normalized = String(entryPath || '').replace(/\\/g, '/');
108
+ const ext = path.posix.extname(normalized.toLowerCase());
109
+ const base = path.posix.basename(normalized).toLowerCase();
110
+ if (IMAGE_EXT.has(ext)) return 'image';
111
+ if (MODEL_3D_EXT.has(ext)) return 'model3d';
112
+ if (VIDEO_EXT.has(ext)) return 'video';
113
+ if (AUDIO_EXT.has(ext)) return 'audio';
114
+ if (isDocumentSourceExtension(ext) || TEXT_BASENAMES.has(base)) return 'document';
115
+ if (isCodeSourceExtension(ext)) return 'code';
116
+ return 'file';
117
+ }
118
+
119
+ function isSafeArchivePath(entryPath) {
120
+ const raw = String(entryPath || '').replace(/\\/g, '/');
121
+ if (!raw || raw.includes('\0') || raw.startsWith('/') || /^[a-zA-Z]:\//.test(raw)) return false;
122
+ const parts = raw.split('/').filter((part) => part && part !== '.');
123
+ return !parts.includes('..');
124
+ }
125
+
126
+ function shouldMineArchiveEntry(entry, policy) {
127
+ if (!entry.safe) return { selected: false, reason: 'unsafe_path' };
128
+ if (entry.link) return { selected: false, reason: 'link_entry' };
129
+ if (entry.directory) return { selected: false, reason: 'directory' };
130
+ if (Number.isFinite(entry.bytes) && entry.bytes > policy.maxEntryBytes) {
131
+ return { selected: false, reason: 'entry_too_large' };
132
+ }
133
+ if (entry.kind === 'code' || entry.kind === 'document') return { selected: true, reason: 'indexable_text' };
134
+ if (policy.includeAssets && ['image', 'model3d'].includes(entry.kind)) return { selected: true, reason: 'requested_asset' };
135
+ return { selected: false, reason: ['image', 'model3d', 'video', 'audio'].includes(entry.kind) ? 'asset_inventory_only' : 'non_indexable' };
136
+ }
137
+
138
+ function commandText(command, args, maxBuffer = 16 * 1024 * 1024) {
139
+ return execFileSync(command, args, {
140
+ encoding: 'utf8',
141
+ maxBuffer,
142
+ env: { ...process.env, LC_ALL: 'C' },
143
+ stdio: ['ignore', 'pipe', 'pipe'],
144
+ });
145
+ }
146
+
147
+ function zipSizeMap(archivePath) {
148
+ if (!hasBin('zipinfo')) return new Map();
149
+ const map = new Map();
150
+ const lines = commandText('zipinfo', ['-l', archivePath], 32 * 1024 * 1024).split(/\r?\n/);
151
+ for (const line of lines) {
152
+ const match = line.match(/^(\S+)\s+\S+\s+\S+\s+(\d+)\s+\S+\s+\d+\s+\S+\s+\S+\s+\S+\s+(.*)$/);
153
+ if (!match) continue;
154
+ map.set(match[3], { bytes: Number(match[2]), link: match[1].startsWith('l') });
155
+ }
156
+ return map;
157
+ }
158
+
86
159
  /**
87
- * Extract archive into destDir. Uses host tar/unzip (no extra npm deps).
160
+ * Inspect an archive without expanding it to disk.
161
+ * @param {string} archivePath
162
+ * @param {Partial<typeof DEFAULT_ARCHIVE_POLICY>} [options]
163
+ */
164
+ export function inspectArchive(archivePath, options = {}) {
165
+ const resolved = path.resolve(archivePath);
166
+ const policy = { ...DEFAULT_ARCHIVE_POLICY, ...options };
167
+ const format = archiveFormat(resolved);
168
+ if (!format) throw new Error(`unsupported_archive:${path.basename(resolved)}`);
169
+ if (!fs.existsSync(resolved)) throw new Error(`archive_missing:${resolved}`);
170
+
171
+ let names = [];
172
+ let zipMeta = new Map();
173
+ let tarLinks = new Set();
174
+ if (format === 'zip') {
175
+ if (!hasBin('unzip')) throw new Error('unzip_unavailable: install unzip to inspect .zip materials');
176
+ names = commandText('unzip', ['-Z1', resolved], 32 * 1024 * 1024).split(/\r?\n/).filter(Boolean);
177
+ zipMeta = zipSizeMap(resolved);
178
+ } else if (format === 'tar') {
179
+ if (!hasBin('tar')) throw new Error('tar_unavailable: install tar to inspect tar materials');
180
+ names = commandText('tar', ['-tf', resolved], 32 * 1024 * 1024).split(/\r?\n/).filter(Boolean);
181
+ const verbose = commandText('tar', ['-tvf', resolved], 32 * 1024 * 1024).split(/\r?\n/);
182
+ for (const line of verbose) {
183
+ if (!(line.startsWith('l') || line.startsWith('h'))) continue;
184
+ const marker = line.includes(' -> ') ? line.split(' -> ')[0] : line;
185
+ const name = names.find((candidate) => marker.endsWith(candidate));
186
+ if (name) tarLinks.add(name);
187
+ }
188
+ } else {
189
+ if (!hasBin('gzip')) throw new Error('gzip_unavailable: install gzip to inspect .gz materials');
190
+ names = [path.basename(resolved, '.gz') || 'payload'];
191
+ }
192
+
193
+ if (names.length > policy.maxEntries) {
194
+ const error = new Error(`archive_entry_limit_exceeded:${names.length}>${policy.maxEntries}`);
195
+ error.code = 'AGENTSAM_ARCHIVE_ENTRY_LIMIT';
196
+ throw error;
197
+ }
198
+
199
+ const entries = names.map((name) => {
200
+ const meta = zipMeta.get(name) || {};
201
+ const directory = name.endsWith('/');
202
+ const entry = {
203
+ path: name,
204
+ bytes: Number.isFinite(meta.bytes) ? meta.bytes : null,
205
+ kind: directory ? 'directory' : archiveEntryKind(name),
206
+ directory,
207
+ link: Boolean(meta.link || tarLinks.has(name)),
208
+ safe: isSafeArchivePath(name),
209
+ };
210
+ return { ...entry, ...shouldMineArchiveEntry(entry, policy) };
211
+ });
212
+
213
+ const unsafe = entries.filter((entry) => !entry.safe);
214
+ if (unsafe.length) {
215
+ const error = new Error(`archive_unsafe_paths:${unsafe.slice(0, 5).map((entry) => entry.path).join(',')}`);
216
+ error.code = 'AGENTSAM_ARCHIVE_UNSAFE_PATH';
217
+ throw error;
218
+ }
219
+
220
+ const selected = entries.filter((entry) => entry.selected);
221
+ const selectedKnownBytes = selected.reduce((sum, entry) => sum + (entry.bytes || 0), 0);
222
+ const byKind = {};
223
+ for (const entry of entries) byKind[entry.kind] = (byKind[entry.kind] || 0) + 1;
224
+
225
+ return {
226
+ schema: 'agentsam.archive.inspect.v1',
227
+ archive: resolved,
228
+ format,
229
+ compressed_bytes: fs.statSync(resolved).size,
230
+ entries_total: entries.length,
231
+ selected_total: selected.length,
232
+ selected_known_bytes: selectedKnownBytes,
233
+ by_kind: byKind,
234
+ policy,
235
+ entries,
236
+ };
237
+ }
238
+
239
+ function readArchiveEntry(archivePath, format, entry, maxBytes) {
240
+ const maxBuffer = Math.max(1024 * 1024, maxBytes + 1);
241
+ if (format === 'zip') {
242
+ return execFileSync('unzip', ['-p', archivePath, entry], { encoding: null, maxBuffer, stdio: ['ignore', 'pipe', 'pipe'] });
243
+ }
244
+ if (format === 'tar') {
245
+ return execFileSync('tar', ['-xOf', archivePath, entry], { encoding: null, maxBuffer, stdio: ['ignore', 'pipe', 'pipe'] });
246
+ }
247
+ return execFileSync('gzip', ['-dc', archivePath], { encoding: null, maxBuffer, stdio: ['ignore', 'pipe', 'pipe'] });
248
+ }
249
+
250
+ /**
251
+ * Selectively mine indexable content from an archive into destDir.
252
+ * Large/binary/media members remain represented in the receipt but are not copied.
88
253
  * @param {string} archivePath
89
254
  * @param {string} destDir
255
+ * @param {Partial<typeof DEFAULT_ARCHIVE_POLICY>} [options]
90
256
  */
91
- export function extractArchive(archivePath, destDir) {
257
+ export function extractArchive(archivePath, destDir, options = {}) {
258
+ const policy = { ...DEFAULT_ARCHIVE_POLICY, ...options };
259
+ const inspection = inspectArchive(archivePath, policy);
260
+ fs.rmSync(destDir, { recursive: true, force: true });
92
261
  fs.mkdirSync(destDir, { recursive: true });
93
- const lower = archivePath.toLowerCase();
94
- if (lower.endsWith('.zip')) {
95
- if (!hasBin('unzip')) throw new Error('unzip_unavailable: install unzip to extract .zip materials');
96
- execFileSync('unzip', ['-q', '-o', archivePath, '-d', destDir], { stdio: ['ignore', 'pipe', 'pipe'] });
97
- return { tool: 'unzip', dest: destDir };
98
- }
99
- if (lower.endsWith('.tar') || lower.endsWith('.tar.gz') || lower.endsWith('.tgz')
100
- || lower.endsWith('.tar.bz2') || lower.endsWith('.tbz2') || lower.endsWith('.gz')) {
101
- if (!hasBin('tar')) throw new Error('tar_unavailable: install tar to extract archive materials');
102
- execFileSync('tar', ['-xf', archivePath, '-C', destDir], { stdio: ['ignore', 'pipe', 'pipe'] });
103
- return { tool: 'tar', dest: destDir };
262
+
263
+ const selected = inspection.entries.filter((entry) => entry.selected);
264
+ const mined = [];
265
+ const skipped = inspection.entries.filter((entry) => !entry.selected).map((entry) => ({
266
+ path: entry.path, kind: entry.kind, bytes: entry.bytes, reason: entry.reason,
267
+ }));
268
+ let totalBytes = 0;
269
+
270
+ for (const entry of selected) {
271
+ if (mined.length >= policy.maxFiles) {
272
+ skipped.push({ path: entry.path, kind: entry.kind, bytes: entry.bytes, reason: 'file_limit' });
273
+ continue;
274
+ }
275
+ if (Number.isFinite(entry.bytes) && totalBytes + entry.bytes > policy.maxTotalBytes) {
276
+ skipped.push({ path: entry.path, kind: entry.kind, bytes: entry.bytes, reason: 'total_byte_limit' });
277
+ continue;
278
+ }
279
+
280
+ let payload;
281
+ try {
282
+ payload = readArchiveEntry(inspection.archive, inspection.format, entry.path, policy.maxEntryBytes);
283
+ } catch (cause) {
284
+ skipped.push({ path: entry.path, kind: entry.kind, bytes: entry.bytes, reason: 'extract_error', error: String(cause?.message || cause).slice(0, 240) });
285
+ continue;
286
+ }
287
+ if (payload.length > policy.maxEntryBytes || totalBytes + payload.length > policy.maxTotalBytes) {
288
+ skipped.push({ path: entry.path, kind: entry.kind, bytes: payload.length, reason: payload.length > policy.maxEntryBytes ? 'entry_too_large' : 'total_byte_limit' });
289
+ continue;
290
+ }
291
+
292
+ const normalized = entry.path.replace(/\\/g, '/').replace(/^\.\//, '');
293
+ const output = path.resolve(destDir, ...normalized.split('/'));
294
+ const root = path.resolve(destDir);
295
+ if (!(output === root || output.startsWith(`${root}${path.sep}`))) {
296
+ throw new Error(`archive_unsafe_output:${entry.path}`);
297
+ }
298
+ fs.mkdirSync(path.dirname(output), { recursive: true });
299
+ fs.writeFileSync(output, payload);
300
+ totalBytes += payload.length;
301
+ mined.push({ path: entry.path, kind: entry.kind, bytes: payload.length });
104
302
  }
105
- throw new Error(`unsupported_archive:${path.basename(archivePath)}`);
303
+
304
+ return {
305
+ schema: 'agentsam.archive.mine.v1',
306
+ format: inspection.format,
307
+ dest: destDir,
308
+ entries_total: inspection.entries_total,
309
+ mined_files: mined.length,
310
+ mined_bytes: totalBytes,
311
+ skipped_files: skipped.length,
312
+ by_kind: inspection.by_kind,
313
+ policy,
314
+ mined,
315
+ skipped: skipped.slice(0, 200),
316
+ skipped_truncated: skipped.length > 200,
317
+ };
106
318
  }
107
319
 
108
320
  /**
109
321
  * Stage pasted/dropped materials under `.agentsam/ingest/<id>/`.
110
- * Archives are extracted; files/dirs are copied or linked by relative include paths.
322
+ * Archives are inspected + selectively mined; files/dirs are copied or linked by relative include paths.
111
323
  *
112
- * @param {{ root: string, materials: string[], ingestId?: string }} opts
324
+ * @param {{ root: string, materials: string[], ingestId?: string, archivePolicy?: object }} opts
113
325
  */
114
326
  export function stageMaterials(opts) {
115
327
  const root = path.resolve(opts.root);
@@ -117,11 +329,8 @@ export function stageMaterials(opts) {
117
329
  const stageRoot = path.join(root, '.agentsam', 'ingest', ingestId);
118
330
  fs.mkdirSync(stageRoot, { recursive: true });
119
331
 
120
- /** @type {object[]} */
121
332
  const items = [];
122
- /** @type {string[]} */
123
333
  const include = [];
124
- /** @type {object[]} */
125
334
  const assets = [];
126
335
 
127
336
  for (const raw of opts.materials) {
@@ -133,11 +342,10 @@ export function stageMaterials(opts) {
133
342
 
134
343
  if (classified.kind === 'archive') {
135
344
  const dest = path.join(stageRoot, 'archives', path.basename(classified.path, classified.ext) || 'archive');
136
- fs.mkdirSync(dest, { recursive: true });
137
- const extracted = extractArchive(classified.path, dest);
345
+ const extracted = extractArchive(classified.path, dest, opts.archivePolicy || {});
138
346
  const rel = path.relative(root, dest);
139
- include.push(rel);
140
- items.push({ ...classified, status: 'extracted', stage: dest, extract: extracted });
347
+ if (extracted.mined_files > 0) include.push(rel);
348
+ items.push({ ...classified, status: 'mined', stage: dest, extract: extracted });
141
349
  continue;
142
350
  }
143
351
 
@@ -158,7 +366,6 @@ export function stageMaterials(opts) {
158
366
  continue;
159
367
  }
160
368
 
161
- // Single file
162
369
  const destDir = path.join(stageRoot, classified.kind === 'image' ? 'images'
163
370
  : classified.kind === 'model3d' ? 'models3d'
164
371
  : classified.kind === 'document' ? 'documents'
@@ -180,7 +387,7 @@ export function stageMaterials(opts) {
180
387
 
181
388
  const uniqueInclude = [...new Set(include.map((p) => p.replace(/\\/g, '/').replace(/\/$/, '') || '.'))].sort();
182
389
  const manifest = {
183
- schema: 'agentsam.ingest.materials.v1',
390
+ schema: 'agentsam.ingest.materials.v2',
184
391
  ingest_id: ingestId,
185
392
  staged_at: new Date().toISOString(),
186
393
  stage_root: path.relative(root, stageRoot),
@@ -7,7 +7,7 @@ import { isKnowledgeSourcePath } from '../../packages/agentsam-repository/src/so
7
7
  import { fingerprint } from './config.js';
8
8
 
9
9
  export const PARSER = `typescript:${ts.version}:agentsam-1`;
10
- const OMIT = /(^|\/)(?:\.git|\.agentsam|node_modules|dist|build|coverage|vendor|\.next|\.wrangler|\.venv|__pycache__)(\/|$)|(^|\/)(?:\.env[^/]*|\.dev\.vars[^/]*|package-lock\.json|npm-shrinkwrap\.json|pnpm-lock\.yaml|yarn\.lock|bun\.lockb?|Cargo\.lock|poetry\.lock|uv\.lock|[^/]*\.(?:pem|key|p12|pfx|min\.js|map))$/i;
10
+ const OMIT = /(^|\/)(?:\.git|\.agentsam|node_modules|python_modules|dist|build|target|coverage|vendor|\.next|\.wrangler|\.venv|__pycache__)(\/|$)|(^|\/)(?:\.env[^/]*|\.dev\.vars[^/]*|package-lock\.json|npm-shrinkwrap\.json|pnpm-lock\.yaml|yarn\.lock|bun\.lockb?|Cargo\.lock|poetry\.lock|uv\.lock|[^/]*\.(?:pem|key|p12|pfx|min\.js|bundle\.js|map))$/i;
11
11
  const under = (file, scope) => scope === '.' || file === scope || file.startsWith(scope + '/');
12
12
  export function inventory(root, scope) {
13
13
  let files;
@@ -380,14 +380,16 @@ export function renderRuntimePlan(plan) {
380
380
  lines.push(` missing tools: ${c.constraints.missing_tools.join(', ')}`);
381
381
  }
382
382
  } else if (c.goap.action_ids.length) {
383
- lines.push(` plan: ${c.goap.action_ids.join(' → ')}`);
383
+ lines.push(` target plan: ${c.goap.action_ids.join(' → ')}`);
384
384
  }
385
385
  }
386
386
  lines.push('');
387
387
  if (plan.recommended) {
388
388
  lines.push(` Recommended ${plan.recommended.profile.label} (${plan.recommended.profile.id})`);
389
389
  lines.push(` Next agentsam setup runtime --profile ${plan.recommended.profile.id} --yes`);
390
- lines.push(` agentsam runtime install`);
390
+ lines.push(plan.facts.agentsamd.installed
391
+ ? ' agentsam runtime status'
392
+ : ' agentsam runtime install');
391
393
  }
392
394
  lines.push('');
393
395
  return `${lines.join('\n')}\n`;
@@ -32,7 +32,7 @@ export const SLASH_COMMANDS = [
32
32
  { cmd: '/agent', description: 'Send a goal to the configured local Agent Sam runtime', lane: 'agent' },
33
33
  { cmd: '/goap', description: 'Inspect and manage GOAP blackboard: /goap [status|goal|why|plan|list|new|switch|close]', lane: 'agent' },
34
34
  { cmd: '/brand', description: 'Brand intelligence: /brand [scan|resolve|plan|inspect]', lane: 'product' },
35
- { cmd: '/plan', description: 'Composable plans: /plan brand', lane: 'product' },
35
+ { cmd: '/plan', description: 'Durable local plans: /plan [new|list|show|add|start|done|block|complete|brand]', lane: 'product' },
36
36
  { cmd: '/next', description: 'Suggested next actions from session progression', lane: 'product' },
37
37
  { cmd: '/logs', description: 'Show local Agent Sam execution events', lane: 'observability' },
38
38
  { cmd: '/deploy', description: 'Add a cloud adapter and deploy intentionally', lane: 'deploy' },
@@ -43,14 +43,36 @@ export function createRuntimeRunId() {
43
43
  export async function startRuntimeRun(value = {}) {
44
44
  const id = clean(value.id) || createRuntimeRunId();
45
45
  await withStore(value.projectRoot || value.cwd, async (db) => {
46
+ const activeStep = (!clean(value.plan_id) || !clean(value.todo_id))
47
+ ? await db.prepare(`
48
+ SELECT t.id AS todo_id, t.plan_id
49
+ FROM agentsam_todo t
50
+ JOIN agentsam_plans p ON p.id = t.plan_id
51
+ WHERE t.status = 'running' AND p.status = 'active'
52
+ ORDER BY t.updated_at_unix DESC, t.created_at_unix DESC
53
+ LIMIT 1
54
+ `).first()
55
+ : null;
56
+ const activePlan = !clean(value.plan_id) && !activeStep?.plan_id
57
+ ? await db.prepare(`
58
+ SELECT id AS plan_id FROM agentsam_plans
59
+ WHERE status = 'active'
60
+ ORDER BY updated_at_unix DESC, created_at_unix DESC
61
+ LIMIT 1
62
+ `).first()
63
+ : null;
64
+ const planId = clean(value.plan_id) || clean(activeStep?.plan_id) || clean(activePlan?.plan_id) || null;
65
+ const todoId = clean(value.todo_id) || clean(activeStep?.todo_id) || null;
46
66
  await db.prepare(`
47
67
  INSERT INTO agentsam_agent_run (
48
- id, account_id, source_client, surface, mode, model_key,
68
+ id, account_id, plan_id, todo_id, source_client, surface, mode, model_key,
49
69
  reasoning_effort, requested_service_tier, status, started_at_unix, updated_at_unix
50
- ) VALUES (?, ?, 'agentsam-cli', 'cli', ?, ?, ?, ?, 'running', unixepoch(), unixepoch())
70
+ ) VALUES (?, ?, ?, ?, 'agentsam-cli', 'cli', ?, ?, ?, ?, 'running', unixepoch(), unixepoch())
51
71
  `).bind(
52
72
  id,
53
73
  clean(value.account_id) || null,
74
+ planId,
75
+ todoId,
54
76
  clean(value.mode) || 'agent',
55
77
  clean(value.model_key) || null,
56
78
  clean(value.reasoning_effort) || null,