@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,59 +0,0 @@
1
- import test from 'node:test';
2
- import assert from 'node:assert/strict';
3
-
4
- import { discoverOpenAIModels, discoverGeminiModels, discoverCursorModels } from '../../src/models/discovery.js';
5
- import { sanitizeInventoryForClient } from '../../src/models/inventory-core.js';
6
-
7
- function json(body) {
8
- return new Response(JSON.stringify(body), { status: 200, headers: { 'content-type': 'application/json' } });
9
- }
10
-
11
- function sanitized(models) {
12
- return sanitizeInventoryForClient({
13
- providers: [],
14
- discovery: {},
15
- availableModels: models,
16
- }).availableModels;
17
- }
18
-
19
- test('known OpenAI Responses reference is selectable while unknown live models stay visible', async () => {
20
- const result = await discoverOpenAIModels('user-key', async () => json({
21
- data: [{ id: 'gpt-5.6-sol' }, { id: 'brand-new-unclassified-model' }],
22
- }));
23
- const rows = sanitized(result.models);
24
- assert.equal(rows.length, 2);
25
- assert.equal(rows.find((row) => row.model_id === 'gpt-5.6-sol')?.chat_eligible, true);
26
- const unknown = rows.find((row) => row.model_id === 'brand-new-unclassified-model');
27
- assert.equal(unknown?.chat_eligible, false);
28
- assert.equal(unknown?.eligibility_reason, 'capability_unknown');
29
- });
30
-
31
- test('Cursor inventory is preserved but reports adapter unavailability', async () => {
32
- const result = await discoverCursorModels('cursor-key', async () => json({
33
- items: [{ id: 'gpt-5.6-sol', displayName: 'GPT-5.6 Sol', parameters: [] }],
34
- }));
35
- const [row] = sanitized(result.models);
36
- assert.equal(row.provider, 'cursor');
37
- assert.equal(row.model_id, 'gpt-5.6-sol');
38
- assert.equal(row.chat_eligible, false);
39
- assert.equal(row.eligibility_reason, 'provider_adapter_unavailable');
40
- });
41
-
42
- test('Gemini provider description keeps TTS visible outside the chat picker', async () => {
43
- const result = await discoverGeminiModels('gemini-key', async () => json({
44
- models: [{
45
- name: 'models/gemini-tts-fixture',
46
- baseModelId: 'gemini-tts-fixture',
47
- displayName: 'Voice fixture',
48
- description: 'Preview Text-to-Speech model',
49
- supportedGenerationMethods: ['generateContent'],
50
- inputTokenLimit: 8192,
51
- outputTokenLimit: 8192,
52
- }],
53
- }));
54
- const [row] = sanitized(result.models);
55
- assert.equal(row.model_id, 'gemini-tts-fixture');
56
- assert.equal(row.chat_eligible, false);
57
- assert.equal(row.eligibility_reason, 'specialized_output_model');
58
- assert.equal(row.eligibility_source, 'provider_api');
59
- });
@@ -1,125 +0,0 @@
1
- import { describe, it } 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 { execFileSync } from 'node:child_process';
7
- import { buildInventory } from '../../src/indexing/ingest/inventory.js';
8
- import {
9
- extractStyleEvidence,
10
- finalizeStyleEvidence,
11
- mergeStyleEvidence,
12
- } from '../../src/indexing/ingest/style-evidence.js';
13
- import { inventory as knowledgeInventory } from '../../src/knowledge/source.js';
14
-
15
- function write(root, rel, text = '') {
16
- const abs = path.join(root, rel);
17
- fs.mkdirSync(path.dirname(abs), { recursive: true });
18
- fs.writeFileSync(abs, text);
19
- }
20
-
21
- describe('inventory classifies by evidence', () => {
22
- it('uses dominant evidence, root files, tooling LOC, and git ignore state', () => {
23
- const root = fs.mkdtempSync(path.join(os.tmpdir(), 'inv-evidence-'));
24
- try {
25
- execFileSync('git', ['init', '-q'], { cwd: root });
26
- write(root, '.gitignore', '.sites-runtime/\n');
27
-
28
- write(root, 'app/page.tsx', Array.from({ length: 30 }, (_, i) => `export const x${i} = ${i};`).join('\n'));
29
- write(root, 'db/schema.sql', 'create table t (id integer);\n');
30
- write(root, 'drizzle/meta/_journal.json', '{"version":"1"}\n');
31
- for (let i = 1; i <= 9; i += 1) write(root, `plans/p${i}.md`, `# plan ${i}\ntext\n`);
32
- write(root, 'plans/schema.sql', 'create table plan (id integer);\n');
33
- write(root, 'public/logo.png', 'x');
34
- write(root, 'scripts/harvest.py', Array.from({ length: 80 }, (_, i) => `x_${i} = ${i}`).join('\n'));
35
- write(root, '.sites-runtime/cache/blob.bin', 'x'.repeat(2048));
36
-
37
- write(root, 'package.json', '{"name":"fixture"}\n');
38
- write(root, 'wrangler.jsonc', '{}\n');
39
- write(root, 'drizzle.config.ts', 'export default {};\n');
40
- write(root, 'README.md', '# Fixture\n');
41
- write(root, 'entry.ts', 'export const root = true;\n');
42
- write(root, 'package-lock.json', '{"lockfileVersion":3}\n');
43
- write(root, '.env', 'SECRET=do-not-index\n');
44
- write(root, '.dev.vars', 'TOKEN=do-not-index\n');
45
- write(root, 'tls.pem', 'private material\n');
46
-
47
- execFileSync('git', ['add', '.'], { cwd: root });
48
-
49
- const inventory = buildInventory({ root });
50
- const categories = inventory.categories;
51
-
52
- assert.ok(categories.source.includes('app'));
53
- assert.ok(categories.source.includes('db'));
54
- assert.ok(categories.docs.includes('plans'), '9 markdown + 1 SQL is dominantly docs');
55
- assert.ok(categories.data.includes('drizzle'), 'JSON-only drizzle metadata is data');
56
- assert.ok(categories.assets.includes('public'));
57
- assert.ok(categories.operational.includes('.sites-runtime'));
58
- assert.ok(categories.tooling.includes('scripts'));
59
- assert.deepEqual(categories.unknown, []);
60
-
61
- assert.ok(inventory.suggested.include.includes('scripts'), 'tracked top-2 language tooling is promoted');
62
- assert.ok(inventory.top_level_details.scripts.loc >= 80);
63
- assert.equal(inventory.top_level_details.scripts.dominant_language, 'Python');
64
-
65
- assert.ok(inventory.root_files.manifest.includes('package.json'));
66
- assert.ok(inventory.root_files.manifest.includes('wrangler.jsonc'));
67
- assert.ok(inventory.root_files.manifest.includes('drizzle.config.ts'));
68
- assert.ok(inventory.root_files.docs.includes('README.md'));
69
- assert.ok(inventory.root_files.source.includes('entry.ts'));
70
- assert.ok(inventory.root_files.lockfile.includes('package-lock.json'));
71
- assert.ok(inventory.root_files.secret.includes('.env'));
72
- assert.ok(inventory.root_files.secret.includes('.dev.vars'));
73
- assert.ok(inventory.root_files.secret.includes('tls.pem'));
74
-
75
- for (const wanted of ['package.json', 'wrangler.jsonc', 'drizzle.config.ts', 'README.md', 'entry.ts']) {
76
- assert.ok(inventory.suggested.include_files.includes(wanted), wanted);
77
- }
78
- for (const forbidden of ['package-lock.json', '.env', '.dev.vars', 'tls.pem']) {
79
- assert.ok(!inventory.suggested.include_files.includes(forbidden), forbidden);
80
- }
81
-
82
- const files = knowledgeInventory(root, { include: ['.'], exclude: [] });
83
- assert.ok(files.includes('entry.ts'));
84
- assert.ok(!files.includes('.env'));
85
- assert.ok(!files.includes('.dev.vars'));
86
- assert.ok(!files.includes('tls.pem'));
87
- assert.ok(!files.includes('package-lock.json'));
88
- } finally {
89
- fs.rmSync(root, { recursive: true, force: true });
90
- }
91
- });
92
-
93
- it('detects coherent theme signatures from markup and CSS evidence', () => {
94
- const evidence = extractStyleEvidence(`
95
- <html data-theme-preset="fuel-free-time" data-header-preset="adaptive-bar">
96
- <link rel="stylesheet" href="/css/heuristic-theme.css">
97
- <body>
98
- <header class="fnf-header fnf-header--adaptive-bar">
99
- <a class="fnf-logo"></a>
100
- <nav class="fnf-primary"></nav>
101
- </header>
102
- </body>
103
- </html>
104
- <style>
105
- :root { --fnf-accent: #ff4d00; --fnf-logo-height: 58px; }
106
- .fnf-header { color: var(--fnf-accent); }
107
- .fnf-logo { height: var(--fnf-logo-height); }
108
- </style>
109
- `);
110
-
111
- assert.equal(evidence.theme_presets['fuel-free-time'], 1);
112
- assert.equal(evidence.header_presets['adaptive-bar'], 1);
113
- assert.equal(evidence.stylesheets['/css/heuristic-theme.css'], 1);
114
- const fnf = evidence.namespaces.find((row) => row.prefix === 'fnf');
115
- assert.ok(fnf);
116
- assert.ok(fnf.signal_kinds >= 2);
117
- assert.ok(fnf.signals.class_tokens >= 3);
118
- assert.ok(fnf.signals.custom_properties >= 2);
119
-
120
- const final = finalizeStyleEvidence(mergeStyleEvidence(null, evidence));
121
- const finalFnf = final.namespaces.find((row) => row.prefix === 'fnf');
122
- assert.equal(final.theme_candidate, true);
123
- assert.equal(finalFnf?.candidate, true);
124
- });
125
- });
@@ -1,112 +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 { fileURLToPath } from 'node:url';
7
- import { defaultConfig } from '../../src/knowledge/config.js';
8
- import { createKnowledgeJobEngine } from '../../src/knowledge/service/job-engine.js';
9
- import { startKnowledgeHttpServer } from '../../src/knowledge/service/server.js';
10
- import { startKnowledgeGrpcServer } from '../../src/knowledge/service/grpc-server.js';
11
- import { createKnowledgeServiceClient } from '../../src/knowledge/service/client.js';
12
- import { createKnowledgeGrpcClient } from '../../src/knowledge/service/grpc-client.js';
13
- import { grpc } from '../../src/knowledge/service/grpc-codec.js';
14
-
15
- const fixtureWorker = fileURLToPath(new URL('../fixtures/knowledge-rpc-worker.mjs', import.meta.url));
16
- const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
17
-
18
- async function waitFor(client, id, wanted = new Set(['completed', 'failed'])) {
19
- for (let i = 0; i < 200; i++) {
20
- const job = await client.job(id);
21
- if (wanted.has(job.status)) return job;
22
- await sleep(10);
23
- }
24
- throw new Error(`Job ${id} did not reach ${[...wanted].join('/')}.`);
25
- }
26
-
27
- async function collect(stream) {
28
- const events = [];
29
- for await (const event of stream) events.push(event);
30
- return events;
31
- }
32
-
33
- test('knowledge HTTP and gRPC adapters share auth, validation, idempotency, lifecycle, cancellation, and durable jobs', async t => {
34
- const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'agentsam-rpc-'));
35
- t.after(() => fs.rmSync(tmp, { recursive: true, force: true }));
36
- const root = path.join(tmp, 'repo');
37
- const stateDir = path.join(tmp, 'state');
38
- fs.mkdirSync(path.join(root, 'src'), { recursive: true });
39
- fs.writeFileSync(path.join(root, 'src', 'sample.js'), 'export const sample = true;\n');
40
- const config = defaultConfig({ include: ['src'] });
41
- const repositories = { sample: { root, config } };
42
- const token = 'r'.repeat(64);
43
- const engine = createKnowledgeJobEngine({ stateDir, repositories, workerPath: fixtureWorker, jobTimeoutMs: 2_000 });
44
- const http = await startKnowledgeHttpServer({ engine, token, port: 0 });
45
- const rpcServer = await startKnowledgeGrpcServer({ engine, token, port: 0 });
46
- const httpClient = createKnowledgeServiceClient({ baseUrl: `http://127.0.0.1:${http.address.port}`, token });
47
- const rpc = createKnowledgeGrpcClient({ target: rpcServer.target, token });
48
- const unauthorized = createKnowledgeGrpcClient({ target: rpcServer.target, token: 'x'.repeat(64) });
49
- t.after(async () => {
50
- unauthorized.close();
51
- rpc.close();
52
- await rpcServer.close();
53
- await http.close();
54
- await engine.close();
55
- });
56
-
57
- const repos = await rpc.repositories();
58
- assert.deepEqual(repos.repositories, ['sample']);
59
- assert.equal(repos.repository_details[0].repository_id, config.repository_id);
60
- assert.equal(repos.embeddings_enabled, false);
61
- await assert.rejects(unauthorized.repositories(), error => error.status === 401 && error.grpcCode === grpc.status.UNAUTHENTICATED);
62
- await assert.rejects(
63
- rpc.submit({ repository: 'sample', operation: 'bogus' }),
64
- error => error.status === 400 && error.grpcCode === grpc.status.INVALID_ARGUMENT,
65
- );
66
-
67
- const request = { repository: 'sample', operation: 'index', generation_id: 'equivalent' };
68
- const fromHttp = await httpClient.submit(request, 'cross-transport');
69
- const fromGrpc = await rpc.submit(request, 'cross-transport');
70
- assert.equal(fromGrpc.id, fromHttp.id);
71
- await assert.rejects(
72
- rpc.submit({ ...request, scope: 'different' }, 'cross-transport'),
73
- error => error.status === 409 && error.grpcCode === grpc.status.ABORTED,
74
- );
75
- const completed = await waitFor(rpc, fromGrpc.id);
76
- assert.equal(completed.status, 'completed');
77
- assert.equal((await httpClient.job(fromGrpc.id)).result.repository_id, completed.result.repository_id);
78
-
79
- const blocker = await rpc.submit({ repository: 'sample', operation: 'index', generation_id: 'slow' }, 'blocker');
80
- await waitFor(rpc, blocker.id, new Set(['running']));
81
- const watched = await rpc.submit({ repository: 'sample', operation: 'index', generation_id: 'watch' }, 'watched');
82
- const lifecycle = await collect(rpc.watch(watched.id));
83
- assert.deepEqual(lifecycle.map(event => event.job.status), ['queued', 'running', 'completed']);
84
- assert.deepEqual(lifecycle.map(event => event.sequence), [1, 2, 3]);
85
-
86
- const failed = await rpc.submit({ repository: 'sample', operation: 'index', generation_id: 'fail' }, 'failed');
87
- const failureEvents = await collect(rpc.watch(failed.id));
88
- assert.equal(failureEvents.at(-1).job.status, 'failed');
89
- assert.match(failureEvents.at(-1).job.error, /fixture knowledge failure/);
90
-
91
- const cancellable = await rpc.submit({ repository: 'sample', operation: 'index', generation_id: 'slow' }, 'cancel-watch');
92
- const controller = new AbortController();
93
- const iterator = rpc.watch(cancellable.id, { signal: controller.signal })[Symbol.asyncIterator]();
94
- const first = await iterator.next();
95
- assert.equal(first.done, false);
96
- controller.abort();
97
- const afterAbort = await iterator.next();
98
- assert.equal(afterAbort.done, true);
99
- assert.equal((await waitFor(rpc, cancellable.id)).status, 'completed');
100
-
101
- const deadlineJob = await rpc.submit({ repository: 'sample', operation: 'index', generation_id: 'slow' }, 'deadline-watch');
102
- let deadlineError = null;
103
- try {
104
- await collect(rpc.watch(deadlineJob.id, { timeoutMs: 15 }));
105
- } catch (error) {
106
- deadlineError = error;
107
- }
108
- assert.ok(deadlineError);
109
- assert.equal(deadlineError.grpcCode, grpc.status.DEADLINE_EXCEEDED);
110
- assert.equal(deadlineError.status, 504);
111
- assert.equal((await waitFor(rpc, deadlineJob.id)).status, 'completed');
112
- });
@@ -1,113 +0,0 @@
1
- import assert from 'node:assert/strict';
2
- import fs from 'node:fs';
3
- import path from 'node:path';
4
- import { describe, it, before, after } from 'node:test';
5
- import {
6
- createLocalFilesystem,
7
- createTempWorkspaceRoot,
8
- LOCAL_FS_ENGINE,
9
- } from '../../src/local-fs/index.js';
10
- import { resolveContainedPath } from '../../src/local-fs/paths.js';
11
-
12
- describe('local-fs path containment', () => {
13
- /** @type {string} */
14
- let root;
15
- before(() => {
16
- root = createTempWorkspaceRoot();
17
- fs.writeFileSync(path.join(root, 'ok.txt'), 'hello\n');
18
- fs.mkdirSync(path.join(root, 'sub'));
19
- });
20
- after(() => {
21
- fs.rmSync(root, { recursive: true, force: true });
22
- });
23
-
24
- it('resolves relative paths inside root', () => {
25
- const r = resolveContainedPath(root, 'ok.txt');
26
- assert.equal(r.ok, true);
27
- assert.equal(r.rel, 'ok.txt');
28
- });
29
-
30
- it('rejects traversal', () => {
31
- const r = resolveContainedPath(root, '../outside.txt');
32
- assert.equal(r.ok, false);
33
- assert.equal(r.code, 'path_escape');
34
- });
35
-
36
- it('rejects NUL', () => {
37
- const r = resolveContainedPath(root, 'a\0b.txt');
38
- assert.equal(r.ok, false);
39
- assert.equal(r.code, 'invalid_path');
40
- });
41
-
42
- it('rejects symlink escape when possible', () => {
43
- const outside = createTempWorkspaceRoot('agentsam-fs-out-');
44
- try {
45
- fs.writeFileSync(path.join(outside, 'secret.txt'), 'nope');
46
- const link = path.join(root, 'escape-link');
47
- try {
48
- fs.symlinkSync(path.join(outside, 'secret.txt'), link);
49
- } catch {
50
- // Windows may lack symlink privilege — skip
51
- return;
52
- }
53
- const r = resolveContainedPath(root, 'escape-link');
54
- assert.equal(r.ok, false);
55
- assert.equal(r.code, 'path_escape');
56
- } finally {
57
- fs.rmSync(outside, { recursive: true, force: true });
58
- }
59
- });
60
- });
61
-
62
- describe('local-fs operations', () => {
63
- /** @type {string} */
64
- let root;
65
- /** @type {ReturnType<typeof createLocalFilesystem>} */
66
- let fsApi;
67
-
68
- before(() => {
69
- root = createTempWorkspaceRoot();
70
- fsApi = createLocalFilesystem(root);
71
- });
72
- after(() => {
73
- fs.rmSync(root, { recursive: true, force: true });
74
- });
75
-
76
- it('create / read / write with version conflict detection', () => {
77
- assert.equal(fsApi.engine, LOCAL_FS_ENGINE);
78
- const created = fsApi.create('README.md', '# one\n');
79
- assert.equal(created.ok, true);
80
- const v1 = created.version;
81
-
82
- const read1 = fsApi.read('README.md');
83
- assert.equal(read1.ok, true);
84
- assert.equal(read1.content, '# one\n');
85
- assert.equal(read1.version, v1);
86
-
87
- const conflict = fsApi.write('README.md', '# stale\n', { expectedVersion: 'sha256:dead' });
88
- assert.equal(conflict.ok, false);
89
- assert.equal(conflict.code, 'version_conflict');
90
-
91
- const wrote = fsApi.write('README.md', '# two\n', { expectedVersion: v1 });
92
- assert.equal(wrote.ok, true);
93
- assert.notEqual(wrote.version, v1);
94
- assert.equal(fs.readFileSync(path.join(root, 'README.md'), 'utf8'), '# two\n');
95
- });
96
-
97
- it('list / rename / remove', () => {
98
- fsApi.create('a.txt', 'a');
99
- fsApi.mkdir('dir');
100
- const listed = fsApi.list('.');
101
- assert.equal(listed.ok, true);
102
- assert.ok(listed.entries.some((e) => e.path === 'a.txt'));
103
-
104
- const renamed = fsApi.rename('a.txt', 'b.txt');
105
- assert.equal(renamed.ok, true);
106
- assert.ok(fs.existsSync(path.join(root, 'b.txt')));
107
- assert.equal(fs.existsSync(path.join(root, 'a.txt')), false);
108
-
109
- const removed = fsApi.remove('b.txt');
110
- assert.equal(removed.ok, true);
111
- assert.equal(fs.existsSync(path.join(root, 'b.txt')), false);
112
- });
113
- });
@@ -1,65 +0,0 @@
1
- import test from 'node:test';
2
- import assert from 'node:assert/strict';
3
- import { executeLocalProviderBridge } from '../../packages/agentsam-desktop-shell/scripts/local-provider-bridge.mjs';
4
-
5
- const CANARY = 'sk-test-CANARY-123456';
6
-
7
- function json(body, status = 200) {
8
- return new Response(JSON.stringify(body), { status, headers: { 'content-type': 'application/json' } });
9
- }
10
-
11
- function openAiFetch(url, init = {}) {
12
- assert.equal(init.headers?.authorization, `Bearer ${CANARY}`);
13
- if (String(url).endsWith('/v1/models')) {
14
- return Promise.resolve(json({ data: [{ id: 'gpt-5.6-sol', object: 'model' }] }));
15
- }
16
- if (String(url).endsWith('/v1/responses')) {
17
- return Promise.resolve(json({
18
- id: 'resp_local_fixture',
19
- status: 'completed',
20
- output_text: 'offline bridge works',
21
- output: [],
22
- usage: { input_tokens: 3, output_tokens: 4 },
23
- }));
24
- }
25
- throw new Error(`unexpected_url:${url}`);
26
- }
27
-
28
- test('device OpenAI credential discovers live inventory without leaking the key', async () => {
29
- const result = await executeLocalProviderBridge({
30
- operation: 'inventory',
31
- credentials: { openai: CANARY },
32
- }, { fetchImpl: openAiFetch });
33
- assert.equal(result.ok, true);
34
- assert.equal(result.credential_plane, 'device_keychain');
35
- assert.equal(result.providers.find((row) => row.id === 'openai')?.configured, true);
36
- assert.equal(result.availableModels.some((row) => row.provider === 'openai' && row.model_id === 'gpt-5.6-sol'), true);
37
- assert.equal(JSON.stringify(result).includes(CANARY), false);
38
- });
39
-
40
- test('device OpenAI credential chats through canonical Responses adapter without leaking the key', async () => {
41
- const result = await executeLocalProviderBridge({
42
- operation: 'chat',
43
- provider: 'openai',
44
- model_id: 'gpt-5.6-sol',
45
- messages: [{ role: 'user', content: 'hello' }],
46
- credentials: { openai: CANARY },
47
- }, { fetchImpl: openAiFetch });
48
- assert.deepEqual(result, {
49
- ok: true,
50
- provider: 'openai',
51
- model_id: 'gpt-5.6-sol',
52
- text: 'offline bridge works',
53
- });
54
- assert.equal(JSON.stringify(result).includes(CANARY), false);
55
- });
56
-
57
- test('provider rejection is sanitized and never echoes credential material', async () => {
58
- const result = await executeLocalProviderBridge({
59
- operation: 'inventory',
60
- credentials: { openai: CANARY },
61
- }, {
62
- fetchImpl: async () => json({ error: { message: `bad ${CANARY}` } }, 401),
63
- });
64
- assert.equal(JSON.stringify(result).includes(CANARY), false);
65
- });
@@ -1,40 +0,0 @@
1
- import test from 'node:test';
2
- import assert from 'node:assert/strict';
3
- import { readFileSync } from 'node:fs';
4
-
5
- function read(path) {
6
- return readFileSync(new URL(`../../${path}`, import.meta.url), 'utf8');
7
- }
8
-
9
- const settingsPage = read('apps/local-studio/frontend/src/components/settings/LocalStudioSettingsPage.tsx');
10
- const settingsHost = read('apps/local-studio/frontend/src/components/settings/localStudioSettingsHost.ts');
11
- const shell = read('apps/local-studio/frontend/agentsam/AgentSamShell.tsx');
12
- const keysPage = read('apps/local-studio/frontend/src/components/settings/LiveKeysSettingsPage.tsx');
13
- const apiKeys = read('apps/local-studio/frontend/src/components/settings/ApiKeysTable.tsx');
14
- const settingsFrontend = read('packages/agentsam-settings/src/frontend/index.tsx');
15
-
16
- test('production Settings never mounts fixture data', () => {
17
- assert.doesNotMatch(settingsPage, /createFixtureSettingsHost|getSettingsFixture|SettingsFixtureName/);
18
- assert.doesNotMatch(settingsHost, /demo-app|Demo Org|health:\s*["']healthy["']/i);
19
- assert.match(settingsHost, /repositoryLabel:\s*["']Not connected["']/);
20
- assert.match(settingsHost, /browser:\s*["']Not checked["']/);
21
- assert.match(settingsHost, /health:\s*["']unknown["']/);
22
- assert.doesNotMatch(settingsFrontend, /demo-app|Demo Org/);
23
- });
24
-
25
- test('Settings route suppresses the outer application sidenav', () => {
26
- assert.match(shell, /const isSettings = pathname === ['"]\/settings['"] \|\| pathname\.startsWith\(['"]\/settings\/['"]\)/);
27
- assert.match(shell, /!isSettings \? <Nav\.Sidenav \/> : null/);
28
- });
29
-
30
- test('Keys page has a visible explicit AgentSam key trigger', () => {
31
- assert.match(keysPage, /variant="secondary"/);
32
- assert.match(keysPage, /Create AgentSam key/);
33
- });
34
-
35
- test('account provider rows show live discovery trust status', () => {
36
- assert.match(apiKeys, /accountInventoryRequest/);
37
- assert.match(apiKeys, /Connected · \$\{count\} model/);
38
- assert.match(apiKeys, /rejected this key/);
39
- assert.match(apiKeys, /Not selected/);
40
- });
@@ -1,26 +0,0 @@
1
- import { test } from 'node:test';
2
- import assert from 'node:assert/strict';
3
- import fs from 'node:fs';
4
- import path from 'node:path';
5
- import { fileURLToPath } from 'node:url';
6
-
7
- const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..');
8
-
9
- test('every workspace and link path in package-lock.json exists on disk', () => {
10
- const lock = JSON.parse(fs.readFileSync(path.join(root, 'package-lock.json'), 'utf8'));
11
- const paths = new Set();
12
- for (const [key, value] of Object.entries(lock.packages)) {
13
- if (key && !key.includes('node_modules/')) paths.add(key);
14
- if (value.link && value.resolved) paths.add(value.resolved);
15
- }
16
- const missing = [...paths].filter((p) => !fs.existsSync(path.join(root, p)));
17
- assert.deepEqual(missing, []);
18
- });
19
-
20
- test('package.json bin map matches package-lock packages[""].bin', () => {
21
- const pkg = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf8'));
22
- const lock = JSON.parse(fs.readFileSync(path.join(root, 'package-lock.json'), 'utf8'));
23
- const pkgBin = pkg.bin || {};
24
- const lockBin = (lock.packages && lock.packages[''] && lock.packages[''].bin) || {};
25
- assert.deepEqual(lockBin, pkgBin);
26
- });
@@ -1,61 +0,0 @@
1
- import assert from 'node:assert/strict';
2
- import { test } from 'node:test';
3
- import fs from 'node:fs/promises';
4
- import os from 'node:os';
5
- import path from 'node:path';
6
- import { spawnSync } from 'node:child_process';
7
- import { fileURLToPath } from 'node:url';
8
-
9
- const cli = fileURLToPath(new URL('../../src/cli.js', import.meta.url));
10
-
11
- async function fixture(t) {
12
- const root = await fs.mkdtemp(path.join(os.tmpdir(), 'agentsam-merkle-cli-test-'));
13
- t.after(() => fs.rm(root, { recursive: true, force: true }));
14
- return root;
15
- }
16
-
17
- async function write(root, name, content = name) {
18
- await fs.mkdir(path.dirname(path.join(root, name)), { recursive: true });
19
- await fs.writeFile(path.join(root, name), content);
20
- }
21
-
22
- function run(args, cwd) {
23
- return spawnSync(process.execPath, [cli, 'merkle', ...args], {
24
- cwd,
25
- encoding: 'utf8',
26
- timeout: 15000,
27
- });
28
- }
29
-
30
- test('CLI snapshot/verify/diff supports JSON, moved roots, and distinct mismatch/error exit codes', async (t) => {
31
- const root = await fixture(t), moved = await fixture(t);
32
- await write(root, 'a.txt', 'hello');
33
- await write(moved, 'a.txt', 'hello');
34
-
35
- const saved = run(['snapshot', '.', '--json'], root);
36
- assert.equal(saved.status, 0, saved.stderr);
37
- const manifest = JSON.parse(saved.stdout);
38
- assert.ok(manifest.output.endsWith('merkle.json'));
39
-
40
- const matching = run(['verify', manifest.output, '--root', moved, '--json'], root);
41
- assert.equal(matching.status, 0, matching.stderr);
42
- assert.equal(JSON.parse(matching.stdout).equal, true);
43
-
44
- await write(moved, 'a.txt', 'changed');
45
- await write(moved, 'b.txt', 'new');
46
- const changed = run(['verify', manifest.output, '--root', moved, '--json'], root);
47
- assert.equal(changed.status, 1, changed.stderr);
48
- assert.deepEqual(JSON.parse(changed.stdout).stats, { unchanged: 0, modified: 1, added: 1, removed: 0 });
49
-
50
- const diff = run(['diff', root, moved, '--json'], root);
51
- assert.equal(diff.status, 1, diff.stderr);
52
-
53
- const invalid = run(['root', '.', '--typo', '--json'], root);
54
- assert.equal(invalid.status, 2);
55
- assert.equal(invalid.stdout, '');
56
- assert.match(JSON.parse(invalid.stderr).error, /Unknown option/);
57
-
58
- const piped = run(['inspect', '.', '--tui'], root);
59
- assert.equal(piped.status, 0, piped.stderr);
60
- assert.ok(!piped.stdout.includes('\x1b'));
61
- });
@@ -1,48 +0,0 @@
1
- import assert from 'node:assert/strict';
2
- import fs from 'node:fs/promises';
3
- import os from 'node:os';
4
- import path from 'node:path';
5
- import { execFileSync } from 'node:child_process';
6
- import { test } from 'node:test';
7
- import { resolveMerklePersistenceIdentity } from '../../src/commands/merkle-persist.js';
8
-
9
- async function gitFixture(t, remote = null) {
10
- const root = await fs.mkdtemp(path.join(os.tmpdir(), 'agentsam-merkle-identity-'));
11
- t.after(() => fs.rm(root, { recursive: true, force: true }));
12
- execFileSync('git', ['init', '-q', root]);
13
- if (remote) execFileSync('git', ['-C', root, 'remote', 'add', 'origin', remote]);
14
- return root;
15
- }
16
-
17
- test('Merkle persistence identity uses authenticated session + Git provider identity', async (t) => {
18
- const root = await gitFixture(t, 'git@github.com:SamPrimeaux/agentsam-sdk.git');
19
- const identity = resolveMerklePersistenceIdentity(root, {
20
- session: { account_id: 'au_test' },
21
- projectConfig: { repository: { id: 'local:should-not-win' } },
22
- });
23
- assert.deepEqual(identity, {
24
- accountId: 'au_test',
25
- repositoryId: 'github:samprimeaux/agentsam-sdk',
26
- repositoryIdentitySource: 'git',
27
- });
28
- });
29
-
30
- test('local repositories fall back to committed project identity', async (t) => {
31
- const root = await gitFixture(t);
32
- const identity = resolveMerklePersistenceIdentity(root, {
33
- session: { account_id: 'au_test' },
34
- projectConfig: { repository: { id: 'local:fixture-repository' } },
35
- });
36
- assert.equal(identity.repositoryId, 'local:fixture-repository');
37
- assert.equal(identity.repositoryIdentitySource, 'project_manifest');
38
- });
39
-
40
- test('Merkle persistence refuses unauthenticated ownership', async (t) => {
41
- const root = await gitFixture(t, 'https://github.com/SamPrimeaux/agentsam-sdk.git');
42
- assert.throws(() => resolveMerklePersistenceIdentity(root, { session: null }), /agentsam_login_required_for_merkle_persistence/);
43
- });
44
-
45
- test('Merkle persistence CLI has no account/repository ownership env shortcuts', async () => {
46
- const source = await fs.readFile(new URL('../../src/commands/merkle-persist.js', import.meta.url), 'utf8');
47
- assert.doesNotMatch(source, /AGENTSAM_ACCOUNT_ID|AGENTSAM_REPOSITORY_ID|--account-id|--repository-id/);
48
- });