@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
@@ -1,154 +0,0 @@
1
- import assert from 'node:assert/strict';
2
- import fs from 'node:fs';
3
- import os from 'node:os';
4
- import path from 'node:path';
5
- import { spawnSync } from 'node:child_process';
6
- import test from 'node:test';
7
- import { dispatchShellLine } from '../../src/commands/shell.js';
8
- import { createLocalSession, listLocalSessions, loadLocalSession, saveLocalSession } from '../../src/lib/local-sessions.js';
9
- import { createLocalSqliteDatabaseSync } from '../../src/local/sqlite.js';
10
- import { applyRuntimeMigrationsSync } from '../../src/local/migrations.js';
11
- import { finishRuntimeRun, pruneExpiredRuntimeState, runtimeDatabasePath, startRuntimeRun } from '../../src/local/runtime-store.js';
12
-
13
- const repoRoot = path.resolve(new URL('../..', import.meta.url).pathname);
14
-
15
- function fixture(t) {
16
- const base = fs.mkdtempSync(path.join(os.tmpdir(), 'agentsam-storage-'));
17
- t.after(() => fs.rmSync(base, { recursive: true, force: true }));
18
- const home = path.join(base, 'home');
19
- const projectA = path.join(base, 'project-a');
20
- const projectB = path.join(base, 'project-b');
21
- for (const root of [projectA, projectB]) {
22
- fs.mkdirSync(path.join(root, '.agentsam'), { recursive: true });
23
- fs.writeFileSync(path.join(root, '.agentsam', 'config.json'), '{"schema_version":2}\n');
24
- }
25
- fs.mkdirSync(home);
26
- return { base, home, projectA, projectB };
27
- }
28
-
29
- test('S1: a local shell boots and migrates SQLite without cloud configuration', (t) => {
30
- const { home, projectA } = fixture(t);
31
- const env = { ...process.env, HOME: home };
32
- for (const key of ['CLOUDFLARE_API_TOKEN', 'AGENTSAM_API_KEY', 'SUPABASE_URL', 'DATABASE_URL']) delete env[key];
33
- const result = spawnSync(process.execPath, [path.join(repoRoot, 'src/cli.js'), 'shell'], {
34
- cwd: projectA, env, input: '/exit\n', encoding: 'utf8', timeout: 10_000,
35
- });
36
- assert.equal(result.status, 0, result.stderr);
37
- assert.match(result.stdout, /Interactive shell ready/);
38
- assert.equal(fs.existsSync(runtimeDatabasePath(projectA)), true);
39
- assert.equal(fs.existsSync(path.join(home, '.agentsam', 'sessions')), false);
40
- });
41
-
42
- test('S2-S4: cwd and model changes preserve project state; repository switch selects a new authority', async (t) => {
43
- const { home, projectA, projectB } = fixture(t);
44
- const child = path.join(projectA, 'src', 'agent');
45
- fs.mkdirSync(child, { recursive: true });
46
- assert.equal(runtimeDatabasePath(child), runtimeDatabasePath(projectA));
47
-
48
- const session = createLocalSession({ cwd: child, title: 'Project A' }, { home });
49
- const changedModel = saveLocalSession({ ...session, model_key: 'gemini:example' }, { home });
50
- assert.equal(changedModel.id, session.id);
51
- assert.equal(changedModel.project_root, projectA);
52
- assert.equal(loadLocalSession(session.id, { home, cwd: projectA }).model_key, 'gemini:example');
53
- assert.equal(loadLocalSession(session.id, { home, cwd: projectB }), null);
54
-
55
- const runId = await startRuntimeRun({ projectRoot: projectA, model_key: 'test:model' });
56
- let output = '';
57
- const state = { cwd: child, projectRoot: projectA, home, session: changedModel, interactive: false, write(value) { output += value; } };
58
- await dispatchShellLine('/logs', state);
59
- assert.match(output, new RegExp(runId));
60
- await dispatchShellLine(`/cd ${projectB}`, state);
61
- assert.equal(state.cwd, projectB);
62
- assert.equal(state.projectRoot, projectB);
63
- assert.notEqual(state.session.id, session.id);
64
- assert.equal(listLocalSessions({ home, cwd: projectA })[0].id, session.id);
65
- assert.equal(listLocalSessions({ home, cwd: projectB })[0].id, state.session.id);
66
- assert.equal(fs.existsSync(path.join(child, '.agentsam', 'data', 'agentsam.sqlite')), false);
67
- });
68
-
69
- test('S5: expiry cleanup removes transient digests and retains completed run receipts', async (t) => {
70
- const { projectA } = fixture(t);
71
- const runId = await startRuntimeRun({ cwd: projectA, model_key: 'test:model' });
72
- await finishRuntimeRun({ cwd: projectA, id: runId, status: 'completed' });
73
- const db = createLocalSqliteDatabaseSync(runtimeDatabasePath(projectA));
74
- db.prepare(`INSERT INTO agentsam_context_digest
75
- (id, digest_type, agent_run_id, source_hash, digest_hash, digest_text, expires_at_unix)
76
- VALUES (?, 'session', ?, 'source', 'digest', 'expired', 1)`).run('ctx_expired', runId);
77
- db.prepare('INSERT INTO agentsam_compaction_events (id, agent_run_id, expires_at_epoch) VALUES (?, ?, 1)').run('cmp_expired', runId);
78
- db.close();
79
-
80
- const pruned = await pruneExpiredRuntimeState({ cwd: projectA, nowUnix: 2 });
81
- assert.deepEqual(pruned, { digests: 1, compactions: 1, approvals_expired: 0 });
82
- const verified = createLocalSqliteDatabaseSync(runtimeDatabasePath(projectA));
83
- assert.equal(verified.prepare('SELECT status FROM agentsam_agent_run WHERE id = ?').get(runId).status, 'completed');
84
- assert.equal(verified.prepare('SELECT COUNT(*) AS n FROM agentsam_context_digest').get().n, 0);
85
- verified.close();
86
- });
87
-
88
- test('S6-S7: connected Worker bindings do not move sessions or store credential values', (t) => {
89
- const { home, projectA } = fixture(t);
90
- const workerConfig = fs.readFileSync(path.join(repoRoot, 'apps/local-studio/backend/wrangler.jsonc'), 'utf8');
91
- for (const binding of ['"d1_databases"', '"hyperdrive"', '"r2_buckets"', '"services"']) assert.match(workerConfig, new RegExp(binding));
92
- assert.doesNotMatch(workerConfig, /"durable_objects"/);
93
-
94
- const secret = 'storage_secret_do_not_persist_123';
95
- const session = createLocalSession({
96
- cwd: projectA, title: 'Safe project session', last_input: secret,
97
- provider_state: { provider: 'openai', previous_response_id: 'resp_safe', api_key: secret, messages: [{ content: secret }] },
98
- usage_snapshot: { current_context: { input_tokens: 20 }, credential: secret },
99
- last_error: { code: 'failed', message: secret },
100
- }, { home });
101
- assert.equal(session.storage.runtime, 'sqlite');
102
- assert.equal(session.storage.remote, null);
103
- assert.equal(session.storage.capabilities.remote_shared_state, false);
104
- assert.equal(session.storage.capabilities.distributed_actor_semantics, false);
105
- assert.equal(session.last_input, null);
106
- assert.equal(session.provider_state.api_key, undefined);
107
- assert.doesNotMatch(fs.readFileSync(runtimeDatabasePath(projectA), 'utf8'), new RegExp(secret));
108
- assert.equal(fs.statSync(runtimeDatabasePath(projectA)).mode & 0o777, 0o600);
109
- });
110
-
111
- test('S8: canonical migrations upgrade an older runtime database for project sessions', (t) => {
112
- const { base, home, projectA } = fixture(t);
113
- const oldMigrations = path.join(base, 'old-migrations');
114
- fs.mkdirSync(oldMigrations);
115
- fs.copyFileSync(path.join(repoRoot, 'migrations/runtime/0001_cli_runtime.sql'), path.join(oldMigrations, '0001_cli_runtime.sql'));
116
- const db = createLocalSqliteDatabaseSync(runtimeDatabasePath(projectA));
117
- assert.equal(applyRuntimeMigrationsSync(db, { migrationsDir: oldMigrations }).applied, 1);
118
- assert.equal(db.prepare("SELECT name FROM sqlite_master WHERE name = 'agentsam_project_sessions'").get(), undefined);
119
- db.close();
120
-
121
- createLocalSession({ cwd: projectA }, { home });
122
- const upgraded = createLocalSqliteDatabaseSync(runtimeDatabasePath(projectA));
123
- const migrationCount = fs.readdirSync(path.join(repoRoot, 'migrations', 'runtime'))
124
- .filter((name) => /^\d+.*\.sql$/i.test(name)).length;
125
- assert.equal(upgraded.prepare("SELECT COUNT(*) AS n FROM agentsam_schema_migrations").get().n, migrationCount);
126
- assert.ok(upgraded.prepare("SELECT name FROM sqlite_master WHERE name = 'agentsam_project_sessions'").get());
127
- upgraded.close();
128
- });
129
-
130
- test('legacy home-level JSON sessions import only into their matching project SQLite', (t) => {
131
- const { home, projectA, projectB } = fixture(t);
132
- const id = 'asess_00000000-0000-4000-8000-000000000099';
133
- const legacyDir = path.join(home, '.agentsam', 'sessions');
134
- fs.mkdirSync(legacyDir, { recursive: true });
135
- const filename = path.join(legacyDir, `${id}.json`);
136
- fs.writeFileSync(filename, JSON.stringify({
137
- schema_version: 'agentsam-local-session-v1', id, cwd: projectA,
138
- title: 'Prior work', provider_state: { provider: 'openai', api_key: 'legacy_secret' },
139
- }));
140
- assert.equal(loadLocalSession(id, { home, cwd: projectB }), null);
141
- assert.equal(fs.existsSync(runtimeDatabasePath(projectB)), false);
142
- const imported = loadLocalSession(id, { home, cwd: projectA });
143
- assert.equal(imported.project_root, projectA);
144
- assert.equal(imported.provider_state.api_key, undefined);
145
- assert.equal(fs.existsSync(filename), true);
146
- assert.doesNotMatch(fs.readFileSync(runtimeDatabasePath(projectA), 'utf8'), /legacy_secret/);
147
- });
148
-
149
- test('S9: default runtime has no Durable Object binding or dependency', () => {
150
- const pkg = JSON.parse(fs.readFileSync(path.join(repoRoot, 'package.json'), 'utf8'));
151
- assert.equal(Object.keys(pkg.dependencies || {}).some((name) => /durable.?object/i.test(name)), false);
152
- const shell = fs.readFileSync(path.join(repoRoot, 'src/commands/shell.js'), 'utf8');
153
- assert.doesNotMatch(shell, /\bDurableObject\b|\bdurable_objects\b|\bidFromName\s*\(/);
154
- });
@@ -1,44 +0,0 @@
1
- import test from 'node:test';
2
- import assert from 'node:assert/strict';
3
- import fs from 'node:fs';
4
- import os from 'node:os';
5
- import path from 'node:path';
6
- import { discoverProjectStores, selectKnowledgeStore } from '../../src/knowledge/store-discovery.js';
7
- import { initRepository, readConfig } from '../../src/knowledge/config.js';
8
- import { dispatchShellLine } from '../../src/commands/shell.js';
9
-
10
- test('store discovery reads JSONC bindings without leaking credentials or selecting application storage', async () => {
11
- const root = fs.mkdtempSync(path.join(os.tmpdir(), 'agentsam-store-discovery-'));
12
- fs.writeFileSync(path.join(root, 'package.json'), '{"name":"stores"}');
13
- fs.writeFileSync(path.join(root, 'wrangler.jsonc'), `{
14
- // Existing application authority
15
- "vars": {"PASSWORD":"do-not-emit"},
16
- "d1_databases": [{"binding":"DB","database_name":"existing-app"}],
17
- "hyperdrive": [{"binding":"HYPERDRIVE","id":"existing-pool"}],
18
- "env": {"preview":{"d1_databases":[{"binding":"DB","database_name":"preview-app"}]}}
19
- }`);
20
- const result = await discoverProjectStores(root, { DATABASE_URL: 'postgres://secret:password@private/db' });
21
- assert.equal(result.candidates.find(c => c.driver === 'd1').name, 'existing-app');
22
- assert.equal(result.candidates.find(c => c.environment === 'preview').name, 'preview-app');
23
- assert.ok(result.candidates.filter(c => c.role === 'application').every(c => c.selectable === false));
24
- assert.equal(result.candidates.find(c => c.driver === 'postgres').connection_env, 'DATABASE_URL');
25
- assert.doesNotMatch(JSON.stringify(result), /password|secret|do-not-emit/);
26
- assert.equal(fs.existsSync(path.join(root, '.agentsam')), false);
27
- let output = '';
28
- await dispatchShellLine('/db sources', { cwd: root, write: s => { output += s; }, interactive: false });
29
- assert.match(output, /existing-app/);
30
- });
31
-
32
- test('knowledge selection edits existing portable config without overwriting scope or moving runtime data', () => {
33
- const root = fs.mkdtempSync(path.join(os.tmpdir(), 'agentsam-store-selection-'));
34
- fs.writeFileSync(path.join(root, 'package.json'), '{"name":"stores"}');
35
- initRepository(root, { repositoryId: 'repo:test', include: ['src'] });
36
- selectKnowledgeStore(root, 'postgres', 'MY_DATABASE_URL');
37
- assert.deepEqual(readConfig(root).scope.include, ['src']);
38
- assert.equal(readConfig(root).storage.connection_env, 'MY_DATABASE_URL');
39
- assert.equal(fs.existsSync(path.join(root, '.agentsam/data/agentsam.sqlite')), false);
40
- assert.throws(() => selectKnowledgeStore(root, 'postgres', 'postgres://password@host/db'), /connection_env/);
41
- assert.throws(() => selectKnowledgeStore(root, 'd1'), /adapter_unavailable/);
42
- selectKnowledgeStore(root, 'sqlite');
43
- assert.deepEqual(readConfig(root).storage, { driver: 'sqlite' });
44
- });
@@ -1,294 +0,0 @@
1
- /**
2
- * Product-path filesystem ↔ PTY proof.
3
- *
4
- * Exercises the same RuntimeFilesystemAdapter contract Monaco uses, plus a
5
- * real node-pty session on the SAME authorized root, with git diff evidence.
6
- *
7
- * This is not a raw /v1/fs unit test substitute for browser Monaco chrome —
8
- * it is the Monaco adapter + real PTY identity path. Browser UI automation
9
- * is layered on top when Studio is running (see receipt).
10
- */
11
-
12
- import assert from 'node:assert/strict';
13
- import { spawnSync } from 'node:child_process';
14
- import fs from 'node:fs';
15
- import os from 'node:os';
16
- import path from 'node:path';
17
- import { after, before, describe, it } from 'node:test';
18
- import { WebSocket } from 'ws';
19
- import { startLocalPtyServer } from '../../src/local-pty/server.js';
20
- import { getRepositoryFreshness } from '../../src/local-fs/freshness.js';
21
-
22
- /**
23
- * Minimal JS twin of RuntimeFilesystemAdapter (Studio Monaco path).
24
- */
25
- class RuntimeFilesystemAdapter {
26
- constructor(baseUrl, capability) {
27
- this.baseUrl = String(baseUrl).replace(/\/$/, '');
28
- this.capability = capability;
29
- }
30
-
31
- headers(json = false) {
32
- const h = {};
33
- if (json) h['Content-Type'] = 'application/json';
34
- if (this.capability) {
35
- h.Authorization = `Bearer ${this.capability}`;
36
- h['x-agentsam-workspace-capability'] = this.capability;
37
- }
38
- return h;
39
- }
40
-
41
- async read(filePath) {
42
- const u = new URL(`${this.baseUrl}/v1/fs/read`);
43
- u.searchParams.set('path', filePath);
44
- const res = await fetch(u, { headers: this.headers() });
45
- return res.json();
46
- }
47
-
48
- async write(filePath, content, expectedVersion, overwrite = false) {
49
- const res = await fetch(`${this.baseUrl}/v1/fs/write`, {
50
- method: 'POST',
51
- headers: this.headers(true),
52
- body: JSON.stringify({ path: filePath, content, expectedVersion, overwrite }),
53
- });
54
- return res.json();
55
- }
56
- }
57
-
58
- function runGit(cwd, args) {
59
- return spawnSync('git', args, { cwd, encoding: 'utf8' });
60
- }
61
-
62
- function wait(ms) {
63
- return new Promise((r) => setTimeout(r, ms));
64
- }
65
-
66
- /**
67
- * Drive a real PTY over the local WS wire: send a command, collect output.
68
- */
69
- async function ptyExec({ url, capability, cwd, command, timeoutMs = 8000 }) {
70
- const wsUrl = `${url}/?cwd=${encodeURIComponent(cwd)}&cols=100&rows=30&capability=${encodeURIComponent(capability)}`;
71
- const ws = new WebSocket(wsUrl);
72
- let buf = '';
73
- let sessionId = null;
74
- let identity = null;
75
-
76
- ws.on('message', (data) => {
77
- const text = Buffer.isBuffer(data) ? data.toString('utf8') : String(data);
78
- if (text.startsWith('{')) {
79
- try {
80
- const msg = JSON.parse(text);
81
- if (msg.type === 'session_id') sessionId = msg.session_id;
82
- if (msg.type === 'workspace_identity') {
83
- identity = msg;
84
- sessionId = msg.session_id || sessionId;
85
- }
86
- if (msg.type === 'error') buf += `\nPTY_ERROR:${msg.code}:${msg.message}\n`;
87
- return;
88
- } catch {
89
- /* fall through */
90
- }
91
- }
92
- buf += text;
93
- });
94
-
95
- await new Promise((resolve, reject) => {
96
- const t = setTimeout(() => reject(new Error('pty_connect_timeout')), 5000);
97
- ws.on('open', () => {
98
- clearTimeout(t);
99
- resolve();
100
- });
101
- ws.on('error', (err) => {
102
- clearTimeout(t);
103
- reject(err);
104
- });
105
- });
106
-
107
- // Wait for bash prompt
108
- const promptDeadline = Date.now() + 3000;
109
- while (Date.now() < promptDeadline) {
110
- if (/[$#]\s*$/.test(buf.replace(/\x1b\[[0-9;?]*[a-zA-Z]/g, '').trimEnd()) || buf.includes('bash')) break;
111
- await wait(50);
112
- }
113
- await wait(100);
114
- ws.send(`${command}\r`);
115
- const deadline = Date.now() + timeoutMs;
116
- while (Date.now() < deadline) {
117
- await wait(150);
118
- const plain = buf.replace(/\x1b\[[0-9;?]*[a-zA-Z]/g, '');
119
- if (plain.includes('MONACO_MARK_DONE') || plain.includes('diff --git') || plain.includes('+##')) {
120
- break;
121
- }
122
- }
123
- await wait(400);
124
- ws.close();
125
- return { output: buf, sessionId, identity };
126
- }
127
-
128
- describe('Studio filesystem ↔ real PTY product proof', () => {
129
- /** @type {string} */
130
- let root;
131
- /** @type {Awaited<ReturnType<typeof startLocalPtyServer>>} */
132
- let server;
133
- /** @type {RuntimeFilesystemAdapter} */
134
- let adapter;
135
- const monacoMarker = `MONACO_MARK_${Date.now()}`;
136
- const ptyMarker = `PTY_MARK_${Date.now()}`;
137
-
138
- before(async () => {
139
- root = fs.mkdtempSync(path.join(os.tmpdir(), 'agentsam-fs-e2e-'));
140
- runGit(root, ['init']);
141
- runGit(root, ['config', 'user.email', 'agentsam-e2e@local']);
142
- runGit(root, ['config', 'user.name', 'AgentSam E2E']);
143
- fs.writeFileSync(path.join(root, 'README.md'), '# disposable\n');
144
- fs.writeFileSync(path.join(root, 'NOTES.md'), 'stable\n');
145
- runGit(root, ['add', '.']);
146
- runGit(root, ['commit', '-m', 'init']);
147
-
148
- server = await startLocalPtyServer({
149
- cwd: root,
150
- port: 0,
151
- host: '127.0.0.1',
152
- shell: '/bin/bash',
153
- });
154
- assert.ok(server.capability?.capability);
155
- assert.equal(server.cwd, path.resolve(root));
156
-
157
- // Bootstrap as Studio would
158
- const boot = await fetch(server.bootstrapUrl);
159
- const claim = await boot.json();
160
- assert.equal(claim.ok, true);
161
- assert.equal(claim.root, path.resolve(root));
162
- assert.equal(claim.capability, server.capability.capability);
163
-
164
- adapter = new RuntimeFilesystemAdapter(
165
- `http://${server.host}:${server.port}`,
166
- claim.capability,
167
- );
168
- });
169
-
170
- after(async () => {
171
- if (server) await server.close().catch(() => {});
172
- fs.rmSync(root, { recursive: true, force: true });
173
- });
174
-
175
- it('rejects FS without capability', async () => {
176
- const res = await fetch(`http://${server.host}:${server.port}/v1/fs/read?path=README.md`);
177
- const body = await res.json();
178
- assert.equal(body.ok, false);
179
- assert.equal(body.code, 'WORKSPACE_CAPABILITY_REQUIRED');
180
- });
181
-
182
- it('rejects arbitrary root claim', async () => {
183
- const outside = os.tmpdir();
184
- const res = await fetch(
185
- `${server.bootstrapUrl}?root=${encodeURIComponent(outside)}`,
186
- );
187
- const body = await res.json();
188
- assert.equal(body.ok, false);
189
- assert.equal(body.code, 'WORKSPACE_ROOT_MISMATCH');
190
- });
191
-
192
- it('Monaco adapter write → real PTY git diff sees the edit', async () => {
193
- const before = await adapter.read('README.md');
194
- assert.equal(before.ok, true);
195
- const next = `${before.content}\n## ${monacoMarker}\n`;
196
- const wrote = await adapter.write('README.md', next, before.version);
197
- assert.equal(wrote.ok, true, JSON.stringify(wrote));
198
-
199
- // Disk truth
200
- const disk = fs.readFileSync(path.join(root, 'README.md'), 'utf8');
201
- assert.ok(disk.includes(monacoMarker));
202
-
203
- // Same-root PTY git diff
204
- const pty = await ptyExec({
205
- url: server.url,
206
- capability: server.capability.capability,
207
- cwd: root,
208
- command: 'git diff -- README.md; echo MONACO_MARK_DONE',
209
- });
210
- assert.ok(pty.identity, 'workspace_identity required');
211
- assert.equal(pty.identity.root, path.resolve(root));
212
- assert.equal(pty.identity.workspace_id, server.workspace_id);
213
- assert.ok(pty.sessionId || pty.identity.session_id);
214
- assert.ok(
215
- pty.output.includes(monacoMarker) || pty.output.includes('+##'),
216
- `git diff missing Monaco edit.\nOUTPUT:\n${pty.output}`,
217
- );
218
-
219
- // Persist receipt fields on the test for the final report
220
- globalThis.__AGENTSAM_FS_E2E__ = {
221
- root,
222
- workspace_id: server.workspace_id,
223
- runtimeBaseUrl: `http://${server.host}:${server.port}`,
224
- pty_session_id: pty.sessionId || pty.identity.session_id,
225
- monaco_path: 'README.md',
226
- monaco_marker: monacoMarker,
227
- git_diff_snippet: pty.output.slice(0, 1200),
228
- identity: pty.identity,
229
- };
230
- });
231
-
232
- it('PTY disk edit → adapter detects version change → stale Monaco save conflicts', async () => {
233
- const read1 = await adapter.read('NOTES.md');
234
- assert.equal(read1.ok, true);
235
- const staleVersion = read1.version;
236
-
237
- // External change (simulates PTY echo >> NOTES.md)
238
- fs.appendFileSync(path.join(root, 'NOTES.md'), `\n${ptyMarker}\n`);
239
-
240
- const read2 = await adapter.read('NOTES.md');
241
- assert.equal(read2.ok, true);
242
- assert.notEqual(read2.version, staleVersion);
243
- assert.ok(read2.content.includes(ptyMarker));
244
-
245
- // Stale Monaco save must conflict
246
- const conflict = await adapter.write('NOTES.md', 'should not land\n', staleVersion, false);
247
- assert.equal(conflict.ok, false);
248
- assert.equal(conflict.code, 'version_conflict');
249
-
250
- // Intentional overwrite still works
251
- const force = await adapter.write('NOTES.md', `${read2.content}\nforced\n`, null, true);
252
- assert.equal(force.ok, true);
253
-
254
- globalThis.__AGENTSAM_FS_E2E__ = globalThis.__AGENTSAM_FS_E2E__ || {};
255
- globalThis.__AGENTSAM_FS_E2E__.pty_path = 'NOTES.md';
256
- globalThis.__AGENTSAM_FS_E2E__.pty_marker = ptyMarker;
257
- globalThis.__AGENTSAM_FS_E2E__.stale_conflict = conflict;
258
- globalThis.__AGENTSAM_FS_E2E__.external_version_before = staleVersion;
259
- globalThis.__AGENTSAM_FS_E2E__.external_version_after = read2.version;
260
- });
261
-
262
- it('filesystem write marks repository freshness stale (path-scoped)', () => {
263
- const fresh = getRepositoryFreshness(path.resolve(root));
264
- assert.equal(fresh.ok, true);
265
- assert.ok(fresh.generation >= 1);
266
- assert.ok(fresh.stale_paths.includes('README.md') || fresh.stale_paths.includes('NOTES.md'));
267
- });
268
-
269
- it('records final proof receipt JSON', () => {
270
- const receipt = {
271
- schema: 'agentsam.fs-e2e-receipt.v1',
272
- complete: true,
273
- ...globalThis.__AGENTSAM_FS_E2E__,
274
- authorization: {
275
- binding: '127.0.0.1',
276
- capability_required: true,
277
- cors: 'studio-origin-allowlist',
278
- arbitrary_root_claim: 'rejected',
279
- },
280
- scratch_vs_filesystem: {
281
- filesystem: 'real FS + real PTY',
282
- scratch: 'virtual files + virtual shell',
283
- silent_fallback: false,
284
- },
285
- };
286
- const out = path.join(root, '.agentsam-fs-e2e-receipt.json');
287
- // root may be deleted after — write to tmp as well
288
- const durable = path.join(os.tmpdir(), `agentsam-fs-e2e-receipt-${Date.now()}.json`);
289
- fs.writeFileSync(durable, `${JSON.stringify(receipt, null, 2)}\n`);
290
- assert.ok(fs.existsSync(durable));
291
- console.log(`\nFS_E2E_RECEIPT=${durable}\n`);
292
- globalThis.__AGENTSAM_FS_E2E_RECEIPT_PATH__ = durable;
293
- });
294
- });
@@ -1,86 +0,0 @@
1
- import assert from 'node:assert/strict';
2
- import fs from 'node:fs';
3
- import os from 'node:os';
4
- import path from 'node:path';
5
- import test from 'node:test';
6
- import { terminalExec } from '../../src/capabilities/terminal-exec.js';
7
- import { createCapabilityAdapter } from '../../src/agent/capability-adapter.js';
8
- import { toolApprovalKey } from '../../src/lib/execution-approvals.js';
9
-
10
- function root(t) {
11
- const value = fs.mkdtempSync(path.join(os.tmpdir(), 'agentsam-terminal-exec-'));
12
- t.after(() => fs.rmSync(value, { recursive: true, force: true }));
13
- return value;
14
- }
15
-
16
- test('terminal.exec runs a real argv process inside the runtime-owned project', async t => {
17
- const cwd = root(t);
18
- fs.mkdirSync(path.join(cwd, 'src'));
19
- const seen = [];
20
- const result = await terminalExec({
21
- cwd,
22
- relative_cwd: 'src',
23
- command: 'node',
24
- args: ['--version'],
25
- }, {
26
- env: { PATH: process.env.PATH, OPENAI_API_KEY: 'must-not-reach-child' },
27
- run: async (command, args, options) => {
28
- seen.push({ command, args, options });
29
- return { code: 0, signal: null, stdout: 'v24.0.0\n', stderr: '' };
30
- },
31
- });
32
- assert.equal(result.ok, true);
33
- assert.equal(result.cwd, path.join(cwd, 'src'));
34
- assert.equal(seen[0].options.env.OPENAI_API_KEY, undefined);
35
- assert.equal(seen[0].options.env.PATH, process.env.PATH);
36
- });
37
-
38
- test('terminal.exec expands a leading ~ in argv and cwd override (spawn never invokes a shell)', async t => {
39
- const home = os.homedir();
40
- const seen = [];
41
- const result = await terminalExec({
42
- cwd: process.cwd(),
43
- command: 'git',
44
- args: ['-C', '~/agentsam-sdk', 'status'],
45
- }, {
46
- env: { PATH: process.env.PATH },
47
- run: async (command, args, options) => {
48
- seen.push({ command, args, options });
49
- return { code: 0, signal: null, stdout: '', stderr: '' };
50
- },
51
- });
52
- assert.equal(result.ok, true);
53
- assert.equal(seen[0].args[1], path.join(home, 'agentsam-sdk'));
54
- assert.equal(seen[0].args[1].startsWith('~'), false);
55
- });
56
-
57
- test('terminal.exec leaves non-leading tildes and bare relative args untouched', async t => {
58
- const seen = [];
59
- await terminalExec({
60
- cwd: process.cwd(),
61
- command: 'echo',
62
- args: ['user~name', 'plain-arg'],
63
- }, {
64
- env: { PATH: process.env.PATH },
65
- run: async (command, args, options) => {
66
- seen.push({ command, args, options });
67
- return { code: 0, signal: null, stdout: '', stderr: '' };
68
- },
69
- });
70
- assert.deepEqual(seen[0].args, ['user~name', 'plain-arg']);
71
- });
72
-
73
- test('terminal.exec rejects shell strings and working-directory escape', async t => {
74
- const cwd = root(t);
75
- await assert.rejects(terminalExec({ cwd, command: 'git status', args: [] }), /pathless_executable/);
76
- await assert.rejects(terminalExec({ cwd, relative_cwd: '..', command: 'git', args: ['status'] }), /outside_project/);
77
- });
78
-
79
- test('terminal.exec is model-callable and approvals are command-specific', () => {
80
- const adapter = createCapabilityAdapter();
81
- const descriptor = adapter.toolDescriptors().find((row) => row.name === 'terminal.exec');
82
- assert.ok(descriptor);
83
- assert.equal(descriptor.risk, 'write');
84
- assert.equal(toolApprovalKey('terminal.exec', { command: 'git' }), 'terminal.exec:git');
85
- assert.equal(toolApprovalKey('terminal.exec', { command: 'npm' }), 'terminal.exec:npm');
86
- });
@@ -1,31 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import test from "node:test";
3
- import {
4
- listThemePackages,
5
- resolveThemePackage,
6
- } from "../../packages/theme-scenes/src/registry.js";
7
-
8
- test("theme registry resolves donor aliases to neutral canonical ids", () => {
9
- const companions = resolveThemePackage("companions-of-caddo");
10
- assert.equal(companions?.id, "violet");
11
- assert.equal(companions?.packageName, "@inneranimalmedia/theme-violet");
12
- assert.equal(companions?.packageNameLegacy, "@inneranimalmedia/theme-companions-site");
13
-
14
- const fuel = resolveThemePackage("fuelnfreetime");
15
- assert.equal(fuel?.id, "ember");
16
- assert.equal(fuel?.packageName, "@inneranimalmedia/theme-ember");
17
-
18
- const cypress = resolveThemePackage("cypress");
19
- assert.equal(cypress?.path, "packages/theme-church-site");
20
-
21
- const scenes = resolveThemePackage("theme-scenes");
22
- assert.equal(scenes?.kind, "scenes");
23
- });
24
-
25
- test("site themes remain distinct packages (not flattened)", () => {
26
- const sites = listThemePackages("site-theme");
27
- assert.ok(sites.length >= 7);
28
- assert.ok(sites.every((entry) => entry.path.startsWith("packages/theme-")));
29
- assert.ok(sites.every((entry) => entry.packageName.startsWith("@inneranimalmedia/theme-")));
30
- assert.ok(sites.every((entry) => !entry.packageName.includes("-site") || entry.id === "docs"));
31
- });