@inneranimalmedia/agentsam-sdk 2.6.5 → 2.6.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (400) hide show
  1. package/AGENTSAM.md +29 -0
  2. package/README.md +37 -0
  3. package/apps/README.md +5 -0
  4. package/apps/cad-creator/README.md +4 -4
  5. package/apps/cad-creator/shared/cad/package.json +1 -1
  6. package/apps/client-cms-editor/AGENTS.md +12 -7
  7. package/apps/client-cms-editor/README.md +76 -48
  8. package/apps/client-cms-editor/agentsam.app.json +26 -9
  9. package/apps/client-cms-editor/backend/package.json +20 -3
  10. package/apps/client-cms-editor/backend/src/api/client.ts +134 -101
  11. package/apps/client-cms-editor/backend/src/index.ts +1 -1
  12. package/apps/client-cms-editor/backend/src/model.ts +11 -115
  13. package/apps/client-cms-editor/backend/src/preview/bridge.ts +1 -1
  14. package/apps/client-cms-editor/backend/tsconfig.json +6 -1
  15. package/apps/client-cms-editor/bin/agentsam-cms.js +262 -0
  16. package/apps/client-cms-editor/bin/agentsam-cms.mjs +2 -228
  17. package/apps/client-cms-editor/frontend/package.json +16 -7
  18. package/apps/client-cms-editor/frontend/src/AgentSamDrawer.tsx +9 -41
  19. package/apps/client-cms-editor/frontend/src/CmsAgentSurface.tsx +19 -174
  20. package/apps/client-cms-editor/frontend/src/adapters/heuristic.ts +29 -0
  21. package/apps/client-cms-editor/frontend/src/adapters/http.ts +628 -0
  22. package/apps/client-cms-editor/frontend/src/adapters/memory.ts +510 -0
  23. package/apps/client-cms-editor/frontend/src/editor/CmsEditor.tsx +213 -0
  24. package/apps/client-cms-editor/frontend/src/editor/CmsEditorProvider.tsx +20 -0
  25. package/apps/client-cms-editor/frontend/src/editor/canvas/PreviewCanvas.tsx +53 -0
  26. package/apps/client-cms-editor/frontend/src/{CmsEditor.tsx → editor/legacy/CmsEditorPrototype.tsx} +52 -23
  27. package/apps/client-cms-editor/frontend/src/editor/useCmsEditorController.ts +218 -0
  28. package/apps/client-cms-editor/frontend/src/index.ts +19 -5
  29. package/apps/client-cms-editor/frontend/src/lib/agent-host.ts +24 -0
  30. package/apps/client-cms-editor/frontend/src/main.tsx +82 -8
  31. package/apps/client-cms-editor/frontend/src/mount.tsx +92 -30
  32. package/apps/client-cms-editor/frontend/src/styles/agentsam-drawer.css +1 -1
  33. package/apps/client-cms-editor/frontend/src/styles/cmsShell.css +8 -8
  34. package/apps/client-cms-editor/frontend/src/styles/studio.css +55 -3
  35. package/apps/client-cms-editor/frontend/tsconfig.json +12 -1
  36. package/apps/client-cms-editor/frontend/vite.config.ts +12 -0
  37. package/apps/client-cms-editor/package-lock.json +973 -134
  38. package/apps/client-cms-editor/package.json +118 -6
  39. package/apps/client-cms-editor/reference/harvest/HARVEST_RECEIPT.json +201 -0
  40. package/apps/client-cms-editor/reference/harvest/PROVENANCE_HISTORY.txt +10 -0
  41. package/apps/client-cms-editor/reference/harvest/README.md +8 -0
  42. package/apps/client-cms-editor/reference/harvest/plans/ARCHIVE-INTAKE.md +135 -0
  43. package/apps/client-cms-editor/reference/harvest/plans/CHATGPT-IDENTITY-HARVEST.md +83 -0
  44. package/apps/client-cms-editor/reference/harvest/plans/CMS-EDITOR-HARVEST.md +166 -0
  45. package/apps/client-cms-editor/reference/harvest/plans/HARVEST-INDEX.md +196 -0
  46. package/apps/client-cms-editor/reference/harvest/plans/INNERANIMALS-CONTENT-001.md +137 -0
  47. package/apps/client-cms-editor/reference/harvest/plans/NO-IMPLICIT-SIDE-EFFECTS.md +87 -0
  48. package/apps/client-cms-editor/reference/harvest/plans/STOREFRONT-SURFACE-MAP.md +140 -0
  49. package/apps/client-cms-editor/reference/harvest/plans/THEME-INNERANIMALS-HARVEST.md +137 -0
  50. package/apps/client-cms-editor/reference/harvest/plans/TOOLING-LAB.md +63 -0
  51. package/apps/client-cms-editor/reference/harvest/plans/harvest-manifest.json +97 -0
  52. package/apps/client-cms-editor/reference/harvest/plans/local-cms-harvest-schema.sql +328 -0
  53. package/apps/client-cms-editor/shared/cms/package.json +17 -7
  54. package/apps/client-cms-editor/shared/cms/src/adapter.ts +204 -0
  55. package/apps/client-cms-editor/shared/cms/src/agent-context.ts +7 -5
  56. package/apps/client-cms-editor/shared/cms/src/editor-types.ts +32 -0
  57. package/apps/client-cms-editor/shared/cms/src/host.ts +82 -0
  58. package/apps/client-cms-editor/shared/cms/src/index.ts +4 -0
  59. package/apps/client-cms-editor/shared/cms/src/map.ts +115 -0
  60. package/apps/client-cms-editor/shared/cms/src/starter-pack.ts +158 -0
  61. package/contracts/source-types.v1.json +353 -0
  62. package/docs/CMS_CONTEXTUAL_COMPOSER.md +1 -1
  63. package/docs/PRODUCT_LIFECYCLE.md +566 -0
  64. package/docs/REPO_FILE_MAP.txt +132 -0
  65. package/docs/THEME_REFINERY.md +2 -2
  66. package/docs/architecture/AGENTSAM_RUNTIME_PROTOCOL.md +40 -20
  67. package/docs/content-studio/REVISION_GATE_2026-09-27.md +1 -1
  68. package/docs/plans/LOCAL_STUDIO_DESKTOP_RELEASE_2026-09-29.md +150 -0
  69. package/migrations/d1/0017_identity_native_oauth.sql +21 -0
  70. package/migrations/d1/0018_goap_control_plane_remaster.sql +40 -0
  71. package/migrations/d1/0019_agentsam_agent_run_plan_todo.sql +14 -0
  72. package/migrations/d1/README_PORTABLE_CONTROL_PLANE.md +20 -9
  73. package/migrations/runtime/0002_goap_blackboard_v1.sql +15 -0
  74. package/migrations/runtime/0004_agent_run_plan_linkage.sql +8 -0
  75. package/native/agentsam-machine/Cargo.lock +426 -0
  76. package/native/agentsam-machine/Cargo.toml +9 -0
  77. package/native/agentsam-machine/cli/Cargo.toml +21 -0
  78. package/native/agentsam-machine/cli/README.md +21 -0
  79. package/native/agentsam-machine/cli/src/main.rs +77 -0
  80. package/native/agentsam-machine/core/Cargo.toml +22 -0
  81. package/native/agentsam-machine/core/README.md +14 -0
  82. package/native/agentsam-machine/core/build.rs +33 -0
  83. package/native/agentsam-machine/core/contracts/source-types.v1.json +353 -0
  84. package/native/agentsam-machine/core/src/assets.rs +790 -0
  85. package/native/agentsam-machine/core/src/bound.rs +298 -0
  86. package/native/agentsam-machine/core/src/enrich.rs +706 -0
  87. package/native/agentsam-machine/core/src/frontend.rs +442 -0
  88. package/native/agentsam-machine/core/src/lib.rs +1092 -0
  89. package/native/agentsam-machine/core/src/liquid.rs +528 -0
  90. package/native/agentsam-machine/core/src/source_types.rs +78 -0
  91. package/package.json +64 -24
  92. package/packages/agentsam-brand/README.md +1 -1
  93. package/packages/agentsam-brand/package.json +4 -4
  94. package/packages/agentsam-brand/src/index.js +1 -1
  95. package/packages/agentsam-contracts/package.json +13 -3
  96. package/packages/agentsam-contracts/src/tools.ts +22 -0
  97. package/packages/agentsam-errors/package.json +13 -3
  98. package/packages/agentsam-errors/src/index.js +1 -0
  99. package/packages/agentsam-errors/src/tool.js +56 -0
  100. package/packages/agentsam-errors/test/tool.test.mjs +58 -0
  101. package/packages/agentsam-goap/README.md +52 -0
  102. package/packages/agentsam-goap/package.json +37 -0
  103. package/packages/agentsam-goap/src/adapters/d1-sqlite.js +570 -0
  104. package/packages/agentsam-goap/src/adapters/memory.js +199 -0
  105. package/packages/agentsam-goap/src/contracts.js +226 -0
  106. package/packages/agentsam-goap/src/control-plane.js +112 -0
  107. package/packages/agentsam-goap/src/errors.js +157 -0
  108. package/packages/agentsam-goap/src/index.js +5 -0
  109. package/packages/agentsam-goap/src/world.js +202 -0
  110. package/packages/agentsam-goap/test/goap-control-plane.test.mjs +245 -0
  111. package/packages/agentsam-goap/test/world.test.mjs +79 -0
  112. package/packages/agentsam-knowledge/package.json +18 -4
  113. package/packages/agentsam-knowledge/src/autorag/index.js +10 -3
  114. package/packages/agentsam-knowledge/src/backends/index.js +33 -1
  115. package/packages/agentsam-knowledge/test/autorag.test.mjs +60 -1
  116. package/packages/agentsam-nav/dist/browser.global.js +21 -18
  117. package/packages/agentsam-nav/dist/browser.js +6807 -130
  118. package/packages/agentsam-nav/dist/index.js +6799 -122
  119. package/packages/agentsam-nav/package.json +24 -6
  120. package/packages/agentsam-queue-control/README.md +1 -1
  121. package/packages/agentsam-queue-control/package.json +7 -2
  122. package/packages/agentsam-rapid-rust/src/main.rs +1 -1
  123. package/packages/agentsam-repository/package.json +13 -3
  124. package/packages/agentsam-repository/src/goap.js +13 -14
  125. package/packages/agentsam-repository/src/source-types.js +8 -0
  126. package/packages/agentsam-repository/src/tickets.js +15 -22
  127. package/packages/agentsam-repository/test/goap-tickets-workspace-state.test.mjs +19 -8
  128. package/packages/agentsam-vault/package.json +14 -4
  129. package/packages/agentsam-workbench/package.json +15 -4
  130. package/packages/agentsam-workbench/src/agent/ToolPermissionRequest.tsx +94 -0
  131. package/packages/agentsam-workbench/src/agent/index.ts +2 -0
  132. package/packages/agentsam-workbench/src/agent/tool-permission.css +134 -0
  133. package/packages/connectors/cloudflare/package.json +15 -3
  134. package/packages/connectors/cloudflare/src/api-client.js +3 -2
  135. package/packages/connectors/cloudflare/src/families/vectorize.js +127 -0
  136. package/packages/connectors/cloudflare/src/index.js +1 -0
  137. package/packages/heuristic-theme/README.md +2 -2
  138. package/packages/heuristic-theme/package.json +8 -3
  139. package/packages/heuristic-theme/src/registry.js +2 -2
  140. package/packages/heuristic-theme/src/theme.js +1 -1
  141. package/packages/heuristic-theme/test/theme.test.mjs +1 -1
  142. package/packages/identity/.agentsam/features/oauth-login-portal/agentsam.feature.json +1 -1
  143. package/packages/identity/.agentsam/features/oauth-login-portal/providers.json +27 -7
  144. package/packages/identity/README.md +2 -2
  145. package/packages/identity/migrations/D1_SCHEMA_MAPPING.md +18 -15
  146. package/packages/identity/migrations/apply-portable.js +109 -0
  147. package/packages/identity/migrations/sqlite/004_identity_oauth_consent_catalog.sql +1 -1
  148. package/packages/identity/migrations/sqlite/005_identity_company_native.sql +52 -0
  149. package/packages/identity/package.json +27 -6
  150. package/packages/identity/schema/agentsam.identity/manifest.json +101 -0
  151. package/packages/identity/scripts/local-identity-bridge.mjs +13 -7
  152. package/packages/identity/scripts/preview-auth-portal.mjs +6 -6
  153. package/packages/identity/src/adapters/cloudflare-d1/index.js +8 -401
  154. package/packages/identity/src/adapters/iam-compat/index.js +540 -0
  155. package/packages/identity/src/adapters/portable-d1/index.js +18 -0
  156. package/packages/identity/src/adapters/portable-store.js +479 -0
  157. package/packages/identity/src/adapters/sqlite/index.js +13 -312
  158. package/packages/identity/src/contracts/auth-config.js +0 -1
  159. package/packages/identity/src/contracts/identity-store.js +56 -5
  160. package/packages/identity/src/contracts/provider.js +1 -0
  161. package/packages/identity/src/contracts/sign-in-options.js +104 -0
  162. package/packages/identity/src/core/constants.js +1 -1
  163. package/packages/identity/src/core/session-policy.js +31 -0
  164. package/packages/identity/src/frontend/auth-portal/pages/login.html +6 -6
  165. package/packages/identity/src/frontend/auth-portal/pages/reset.html +5 -5
  166. package/packages/identity/src/frontend/auth-portal/pages/signup.html +5 -5
  167. package/packages/identity/src/frontend/auth-portal/shared/company-branding.js +1 -1
  168. package/packages/identity/src/frontend/auth-portal/shared/desktop-identity-bridge.js +6 -37
  169. package/packages/identity/src/index.js +28 -1
  170. package/packages/identity/src/migrations/README.md +23 -23
  171. package/packages/identity/src/oauth/README.md +1 -1
  172. package/packages/identity/src/oauth/credentials.js +10 -11
  173. package/packages/identity/src/oauth/google-desktop-exchange.js +195 -27
  174. package/packages/identity/src/oauth/iam-platform.js +21 -9
  175. package/packages/identity/src/oauth/native-handoff.js +136 -0
  176. package/packages/identity/src/providers/chatgpt/headers.js +65 -0
  177. package/packages/identity/src/providers/chatgpt/index.js +86 -0
  178. package/packages/identity/src/providers/chatgpt/mapper.js +43 -0
  179. package/packages/identity/src/providers/chatgpt/paths.js +45 -0
  180. package/packages/identity/src/providers/github/oauth.js +1 -2
  181. package/packages/identity/src/providers/github/profile.js +16 -2
  182. package/packages/identity/src/providers/index.js +11 -3
  183. package/packages/identity/src/server/identity-service.js +2 -1
  184. package/packages/identity/src/server/worker-router.js +71 -18
  185. package/packages/identity/tests/chatgpt-provider.test.mjs +75 -0
  186. package/packages/identity/tests/google-desktop-identity-login.test.mjs +210 -0
  187. package/packages/identity/tests/identity-init-scaffold.test.mjs +15 -4
  188. package/packages/identity/tests/lane1-identity-store-parity.test.mjs +527 -0
  189. package/packages/identity/tests/lane1-packed-consumer.test.mjs +175 -0
  190. package/packages/identity/tests/native-oauth-handoff.test.mjs +292 -0
  191. package/packages/identity/tests/oauth-credentials.test.mjs +4 -4
  192. package/packages/identity/tests/preview-auth-portal.test.mjs +4 -2
  193. package/packages/identity/tests/session-routes-policy.test.mjs +13 -1
  194. package/packages/identity/tests/worker-runtime-boundary.test.mjs +11 -0
  195. package/packages/providers/completeful/package.json +7 -2
  196. package/packages/theme-church-site/package.json +17 -6
  197. package/packages/theme-church-site/src/harvest.json +4 -2
  198. package/packages/theme-church-site/src/index.js +7 -3
  199. package/packages/theme-church-site/test/theme.test.mjs +4 -2
  200. package/packages/theme-companions-site/package.json +17 -6
  201. package/packages/theme-companions-site/src/harvest.json +4 -2
  202. package/packages/theme-companions-site/src/index.js +7 -3
  203. package/packages/theme-companions-site/test/theme.test.mjs +4 -2
  204. package/packages/theme-floors-site/package.json +17 -6
  205. package/packages/theme-floors-site/src/harvest.json +4 -2
  206. package/packages/theme-floors-site/src/index.js +7 -3
  207. package/packages/theme-floors-site/test/theme.test.mjs +4 -2
  208. package/packages/theme-fuelnfree-site/package.json +17 -6
  209. package/packages/theme-fuelnfree-site/src/harvest.json +4 -2
  210. package/packages/theme-fuelnfree-site/src/index.js +7 -3
  211. package/packages/theme-fuelnfree-site/test/theme.test.mjs +4 -2
  212. package/packages/theme-handyman-site/package.json +17 -6
  213. package/packages/theme-handyman-site/src/harvest.json +4 -2
  214. package/packages/theme-handyman-site/src/index.js +7 -3
  215. package/packages/theme-handyman-site/test/theme.test.mjs +4 -2
  216. package/packages/theme-insurance-site/package.json +17 -6
  217. package/packages/theme-insurance-site/src/harvest.json +4 -2
  218. package/packages/theme-insurance-site/src/index.js +7 -3
  219. package/packages/theme-insurance-site/test/theme.test.mjs +4 -2
  220. package/packages/theme-scenes/README.md +1 -1
  221. package/packages/theme-scenes/package.json +4 -3
  222. package/packages/theme-scenes/src/registry.js +187 -0
  223. package/packages/theme-shinshu-site/package.json +17 -6
  224. package/packages/theme-shinshu-site/src/harvest.json +4 -2
  225. package/packages/theme-shinshu-site/src/index.js +7 -3
  226. package/packages/theme-shinshu-site/test/theme.test.mjs +4 -2
  227. package/packages/work-graph/package.json +14 -4
  228. package/protocol/FILEMETA_V1.md +2 -2
  229. package/protocol/capabilities/manifest.json +1 -1
  230. package/protocol/database/agentsam.schema-pack.v1.schema.json +72 -0
  231. package/protocol/presets/catalog.json +2 -2
  232. package/protocol/theme-refinery/lineage-registry.json +105 -0
  233. package/protocol/theme-refinery/product-metadata.schema.json +21 -1
  234. package/python/agentsam_sdk/repository/intelligence/discovery.py +27 -2
  235. package/python/agentsam_sdk/repository/intelligence/git.py +4 -0
  236. package/python/tests/test_repository_intelligence.py +30 -0
  237. package/src/cli/command-catalog.js +48 -5
  238. package/src/cli/dispatch.js +1 -0
  239. package/src/cli.js +20 -1
  240. package/src/cloudflare/runtime-status.js +2 -1
  241. package/src/commands/autorag.js +67 -13
  242. package/src/commands/cheat-sheet.js +29 -4
  243. package/src/commands/codebaseindex.js +45 -2
  244. package/src/commands/goap-world.js +134 -0
  245. package/src/commands/goap.js +11 -4
  246. package/src/commands/knowledge.js +59 -2
  247. package/src/commands/machine-binary.js +109 -0
  248. package/src/commands/machine-runtime.js +266 -0
  249. package/src/commands/machine.js +208 -0
  250. package/src/commands/package.js +530 -0
  251. package/src/commands/plan-ledger.js +370 -0
  252. package/src/commands/plan.js +183 -0
  253. package/src/commands/security.js +67 -4
  254. package/src/commands/setup.js +33 -16
  255. package/src/commands/skill.js +78 -17
  256. package/src/commands/status.js +8 -1
  257. package/src/features/resolve.js +1 -0
  258. package/src/knowledge/engine.js +21 -2
  259. package/src/knowledge/runtime-discovery.js +127 -0
  260. package/src/knowledge/source.js +1 -1
  261. package/src/lib/identity-scaffold.js +53 -13
  262. package/src/lib/setup/recipes.js +1 -1
  263. package/src/lib/slash-commands.js +1 -1
  264. package/src/local/runtime-store.js +24 -2
  265. package/src/local/sqlite.js +17 -0
  266. package/src/models/discovery.js +40 -22
  267. package/src/models/inventory-core.d.ts +105 -0
  268. package/src/models/inventory-core.js +54 -6
  269. package/src/sam/operations/package-audit.js +41 -0
  270. package/src/sam/seed.js +2 -0
  271. package/src/security/logs.js +3 -0
  272. package/src/ui/cli/help.js +41 -0
  273. package/apps/client-cms-editor/backend/src/demo-bootstrap.ts +0 -145
  274. package/test/account-session.test.mjs +0 -101
  275. package/test/agent-capabilities.test.mjs +0 -67
  276. package/test/app-authority-context.test.mjs +0 -32
  277. package/test/app-building-skills.test.mjs +0 -61
  278. package/test/apps-scaffold-contract.test.mjs +0 -114
  279. package/test/blender-cad.test.mjs +0 -146
  280. package/test/cad-docker.test.mjs +0 -96
  281. package/test/capabilities.test.mjs +0 -133
  282. package/test/cli/api-key-env-whoami.test.mjs +0 -129
  283. package/test/cli/codebaseindex-plan-ux.test.mjs +0 -37
  284. package/test/cli/eval-live.test.mjs +0 -219
  285. package/test/cli/go.test.mjs +0 -128
  286. package/test/cli/local-vault-and-provider-setup.test.mjs +0 -268
  287. package/test/cli/mcp-client.test.mjs +0 -256
  288. package/test/cli/preferences-runtime.test.mjs +0 -11
  289. package/test/cli/runtime-persist.test.mjs +0 -56
  290. package/test/cli/runtime-ui.test.mjs +0 -141
  291. package/test/cli/rust-command.test.mjs +0 -21
  292. package/test/cli/skill-npm-and-env.test.mjs +0 -52
  293. package/test/cli/status-actions.test.mjs +0 -88
  294. package/test/cli/wireframes-go-registry.test.mjs +0 -139
  295. package/test/cli-preferences.test.mjs +0 -46
  296. package/test/cloudflare-connector.test.mjs +0 -93
  297. package/test/cloudflare-runtime.test.mjs +0 -82
  298. package/test/context.test.mjs +0 -159
  299. package/test/credentials-audit.test.mjs +0 -113
  300. package/test/deploy-health-scan.test.mjs +0 -95
  301. package/test/deploy-receipt.test.mjs +0 -91
  302. package/test/dockerize.test.mjs +0 -93
  303. package/test/error-diagnostics.test.mjs +0 -124
  304. package/test/eval-context.test.mjs +0 -37
  305. package/test/execution-approvals.test.mjs +0 -27
  306. package/test/fixtures/cad/courtyard-house.json +0 -208
  307. package/test/fixtures/knowledge-rpc-worker.mjs +0 -16
  308. package/test/gcloud-auth.test.mjs +0 -111
  309. package/test/go/build-source-identity.test.mjs +0 -31
  310. package/test/go/cloudflare-probe.test.mjs +0 -317
  311. package/test/go/distribution.test.mjs +0 -28
  312. package/test/google-cloud-connection.test.mjs +0 -83
  313. package/test/google-cloud-inventory.test.mjs +0 -64
  314. package/test/indexing-provider.test.mjs +0 -29
  315. package/test/init-options.test.mjs +0 -35
  316. package/test/integration/ai-access-onboarding.test.mjs +0 -47
  317. package/test/integration/app-command.test.mjs +0 -85
  318. package/test/integration/cad-discovery.test.mjs +0 -158
  319. package/test/integration/cad-docker-executor.test.mjs +0 -249
  320. package/test/integration/cad-execution.test.mjs +0 -184
  321. package/test/integration/cad-project-app.test.mjs +0 -31
  322. package/test/integration/cad-project-d1.test.mjs +0 -25
  323. package/test/integration/cad-project-native.test.mjs +0 -24
  324. package/test/integration/cad-project-workflow.test.mjs +0 -9
  325. package/test/integration/cad-project.test.mjs +0 -85
  326. package/test/integration/cli-help.test.mjs +0 -41
  327. package/test/integration/cms-app-scaffold.test.mjs +0 -71
  328. package/test/integration/cms-site-tenancy-contract.test.mjs +0 -257
  329. package/test/integration/codebaseindex-ingest.test.mjs +0 -214
  330. package/test/integration/core-client.integration.test.mjs +0 -55
  331. package/test/integration/error-runtime-rpc.test.mjs +0 -71
  332. package/test/integration/features-resolve.test.mjs +0 -147
  333. package/test/integration/icon-registry.test.mjs +0 -67
  334. package/test/integration/ingest-discover-models.test.mjs +0 -30
  335. package/test/integration/inspect-path-cli.test.mjs +0 -46
  336. package/test/integration/install-script.test.mjs +0 -110
  337. package/test/integration/inventory-core.test.mjs +0 -53
  338. package/test/integration/inventory-evidence.test.mjs +0 -125
  339. package/test/integration/knowledge-rpc.test.mjs +0 -112
  340. package/test/integration/local-fs.test.mjs +0 -113
  341. package/test/integration/merkle-cli.test.mjs +0 -61
  342. package/test/integration/merkle-persistence-identity.test.mjs +0 -48
  343. package/test/integration/plugins-cloudflare.integration.test.mjs +0 -28
  344. package/test/integration/provider-env-cli.test.mjs +0 -50
  345. package/test/integration/provider-factory.test.mjs +0 -197
  346. package/test/integration/repository-company-graph.test.mjs +0 -90
  347. package/test/integration/runtime-migrations.test.mjs +0 -87
  348. package/test/integration/runtime-status.integration.test.mjs +0 -212
  349. package/test/integration/sam-activity-recovery.test.mjs +0 -147
  350. package/test/integration/sam-decision.test.mjs +0 -584
  351. package/test/integration/sam-kernel.test.mjs +0 -99
  352. package/test/integration/sam-planning-astar.test.mjs +0 -279
  353. package/test/integration/scaffold-cloudflare.test.mjs +0 -46
  354. package/test/integration/skill-runtime.test.mjs +0 -240
  355. package/test/integration/storage-architecture.test.mjs +0 -154
  356. package/test/integration/store-discovery.test.mjs +0 -44
  357. package/test/integration/studio-fs-pty-e2e.test.mjs +0 -294
  358. package/test/integration/terminal-exec.integration.test.mjs +0 -86
  359. package/test/integration/tool-runtime.test.mjs +0 -124
  360. package/test/integration/tool-schema.test.mjs +0 -59
  361. package/test/jr-dev-skill.test.mjs +0 -26
  362. package/test/knowledge-context-pack.test.mjs +0 -19
  363. package/test/knowledge-postgres.test.mjs +0 -40
  364. package/test/knowledge-service.test.mjs +0 -110
  365. package/test/knowledge.test.mjs +0 -206
  366. package/test/live/terminal-transport.live.test.mjs +0 -24
  367. package/test/local-sessions.test.mjs +0 -57
  368. package/test/local-studio-deploy.test.mjs +0 -83
  369. package/test/loopback-oauth.test.mjs +0 -53
  370. package/test/merkle-render.test.mjs +0 -31
  371. package/test/mini.test.mjs +0 -140
  372. package/test/model-catalog.test.mjs +0 -70
  373. package/test/models.test.mjs +0 -309
  374. package/test/npm10-lock.test.mjs +0 -29
  375. package/test/ollama.test.mjs +0 -137
  376. package/test/open-url.test.mjs +0 -64
  377. package/test/openai-responses.test.mjs +0 -155
  378. package/test/portable-context.test.mjs +0 -94
  379. package/test/project-config.test.mjs +0 -81
  380. package/test/project-rules.test.mjs +0 -44
  381. package/test/provider-credentials.test.mjs +0 -106
  382. package/test/rehydrate.test.mjs +0 -25
  383. package/test/release-hygiene.test.mjs +0 -42
  384. package/test/repository-snapshot-view.test.mjs +0 -112
  385. package/test/responses-runner.test.mjs +0 -465
  386. package/test/runtime-activity.test.mjs +0 -98
  387. package/test/sdk-worker-contract.test.mjs +0 -72
  388. package/test/security.test.mjs +0 -252
  389. package/test/setup-planner.test.mjs +0 -74
  390. package/test/setup-runtime.test.mjs +0 -51
  391. package/test/shell.test.mjs +0 -281
  392. package/test/skills.test.mjs +0 -22
  393. package/test/smoke.mjs +0 -122
  394. package/test/telemetry.test.mjs +0 -79
  395. package/test/terminal/local-pty.mock.test.mjs +0 -153
  396. package/test/terminal-machine-identity.test.mjs +0 -88
  397. package/test/theme-portability.test.mjs +0 -14
  398. package/test/tools-search.test.mjs +0 -73
  399. package/test/unit/website-assets-bindings.test.mjs +0 -60
  400. package/test/whoami-resume.test.mjs +0 -157
@@ -0,0 +1,510 @@
1
+ import {
2
+ CmsCapabilityError,
3
+ type CmsAsset,
4
+ type CmsEditorAdapter,
5
+ type CmsPublicationSnapshot,
6
+ type CmsRevision,
7
+ } from '../../../shared/cms/src/adapter';
8
+ import type {
9
+ CmsEditorBlock,
10
+ CmsEditorPage,
11
+ CmsEditorSection,
12
+ CmsEditorSite,
13
+ CmsSiteCreateInput,
14
+ CmsSiteRecord,
15
+ CmsSiteUpdatePatch,
16
+ } from '../../../shared/cms/src/editor-types';
17
+
18
+ function id(prefix: string) {
19
+ return `${prefix}_${crypto.randomUUID().slice(0, 8)}`;
20
+ }
21
+
22
+ function cloneSite(site: CmsEditorSite): CmsEditorSite {
23
+ return structuredClone(site);
24
+ }
25
+
26
+ function siteRecordFrom(site: CmsEditorSite): CmsSiteRecord {
27
+ const { pages: _pages, ...record } = site;
28
+ return structuredClone(record);
29
+ }
30
+
31
+ function buildSiteRecord(input: CmsSiteCreateInput & { id: string }): CmsSiteRecord {
32
+ const name = input.name.trim() || 'Untitled';
33
+ return {
34
+ id: input.id,
35
+ name,
36
+ initials:
37
+ input.initials?.trim() ||
38
+ name
39
+ .split(/\s+/)
40
+ .filter(Boolean)
41
+ .slice(0, 2)
42
+ .map((part) => part[0])
43
+ .join('')
44
+ .toUpperCase() ||
45
+ 'CMS',
46
+ domain: input.domain ?? '',
47
+ edited: 'just now',
48
+ color: input.color ?? '#1e6a6f',
49
+ theme: input.theme ? structuredClone(input.theme) : undefined,
50
+ schemas: input.schemas ? structuredClone(input.schemas) : undefined,
51
+ };
52
+ }
53
+
54
+ type SiteStore = {
55
+ meta: CmsSiteRecord;
56
+ pages: CmsEditorPage[];
57
+ revisions: Map<string, CmsRevision[]>;
58
+ published: Map<string, CmsPublicationSnapshot>;
59
+ assets: CmsAsset[];
60
+ };
61
+
62
+ /**
63
+ * Explicit in-memory adapter for sandboxes/tests/preview.
64
+ * Temporary adapter authority — never pretend to be durable SQLite/D1/HTTP persistence.
65
+ */
66
+ export class MemoryCmsAdapter implements CmsEditorAdapter {
67
+ /** True when this adapter is not durable across reloads/processes. */
68
+ readonly temporary = true;
69
+ private sites = new Map<string, SiteStore>();
70
+
71
+ /** Genuinely empty store — use installStarterPack / createSite to populate. */
72
+ static createEmpty() {
73
+ return new MemoryCmsAdapter();
74
+ }
75
+
76
+ /** Convenience: empty adapter + one site shell (tests only — not required for starter install). */
77
+ static async withSite(siteId: string, name = 'Untitled') {
78
+ const adapter = MemoryCmsAdapter.createEmpty();
79
+ await adapter.createSite({ id: siteId, name, domain: '' });
80
+ return adapter;
81
+ }
82
+
83
+ /** @deprecated Prefer createEmpty() + installStarterPack() or createSite(). */
84
+ static empty(siteId: string, name = 'Untitled') {
85
+ const adapter = new MemoryCmsAdapter();
86
+ const meta = buildSiteRecord({ id: siteId, name, domain: '' });
87
+ adapter.sites.set(siteId, {
88
+ meta,
89
+ pages: [],
90
+ revisions: new Map(),
91
+ published: new Map(),
92
+ assets: [],
93
+ });
94
+ return adapter;
95
+ }
96
+
97
+ static fromSite(site: CmsEditorSite) {
98
+ const adapter = new MemoryCmsAdapter();
99
+ adapter.sites.set(site.id, {
100
+ meta: siteRecordFrom(site),
101
+ pages: structuredClone(site.pages),
102
+ revisions: new Map(),
103
+ published: new Map(),
104
+ assets: [],
105
+ });
106
+ return adapter;
107
+ }
108
+
109
+ private storeOrThrow(siteId: string) {
110
+ const store = this.sites.get(siteId);
111
+ if (!store) {
112
+ throw new CmsCapabilityError('getSite', `site_not_found:${siteId}`, 'cms_source_not_found');
113
+ }
114
+ return store;
115
+ }
116
+
117
+ private pageOrThrow(siteId: string, pageId: string) {
118
+ const store = this.storeOrThrow(siteId);
119
+ const page = store.pages.find((p) => p.id === pageId);
120
+ if (!page) throw new CmsCapabilityError('getPage', `page_not_found:${pageId}`, 'cms_source_not_found');
121
+ return { store, page };
122
+ }
123
+
124
+ private findPage(pageId: string) {
125
+ for (const [siteId, store] of this.sites) {
126
+ const page = store.pages.find((p) => p.id === pageId);
127
+ if (page) return { siteId, store, page };
128
+ }
129
+ throw new CmsCapabilityError('getPage', `page_not_found:${pageId}`, 'cms_source_not_found');
130
+ }
131
+
132
+ private sectionOrThrow(sectionId: string) {
133
+ for (const [siteId, store] of this.sites) {
134
+ for (const page of store.pages) {
135
+ const section = page.sections.find((s) => s.id === sectionId);
136
+ if (section) return { siteId, store, page, section };
137
+ }
138
+ }
139
+ throw new CmsCapabilityError('getSection', `section_not_found:${sectionId}`, 'cms_source_not_found');
140
+ }
141
+
142
+ private blockOrThrow(blockId: string) {
143
+ for (const [siteId, store] of this.sites) {
144
+ for (const page of store.pages) {
145
+ for (const section of page.sections) {
146
+ const block = section.blocks.find((b) => b.id === blockId);
147
+ if (block) return { siteId, store, page, section, block };
148
+ }
149
+ }
150
+ }
151
+ throw new CmsCapabilityError('getBlock', `block_not_found:${blockId}`, 'cms_source_not_found');
152
+ }
153
+
154
+ async listSites(): Promise<CmsSiteRecord[]> {
155
+ return [...this.sites.values()].map((store) => structuredClone(store.meta));
156
+ }
157
+
158
+ async getSite(siteId: string): Promise<CmsSiteRecord> {
159
+ return structuredClone(this.storeOrThrow(siteId).meta);
160
+ }
161
+
162
+ async createSite(input: CmsSiteCreateInput): Promise<CmsSiteRecord> {
163
+ const siteId = String(input.id || id('site')).trim();
164
+ if (!siteId) throw new Error('cms_site_id_required');
165
+ if (this.sites.has(siteId)) {
166
+ throw new CmsCapabilityError('createSite', `site_exists:${siteId}`, 'cms_capability_unsupported');
167
+ }
168
+ const meta = buildSiteRecord({ ...input, id: siteId });
169
+ this.sites.set(siteId, {
170
+ meta,
171
+ pages: [],
172
+ revisions: new Map(),
173
+ published: new Map(),
174
+ assets: [],
175
+ });
176
+ return structuredClone(meta);
177
+ }
178
+
179
+ async updateSite(siteId: string, patch: CmsSiteUpdatePatch): Promise<CmsSiteRecord> {
180
+ const store = this.storeOrThrow(siteId);
181
+ store.meta = {
182
+ ...store.meta,
183
+ ...patch,
184
+ id: siteId,
185
+ theme: patch.theme !== undefined ? structuredClone(patch.theme) : store.meta.theme,
186
+ schemas: patch.schemas !== undefined ? structuredClone(patch.schemas) : store.meta.schemas,
187
+ };
188
+ if (patch.name || patch.initials || patch.color) {
189
+ store.meta.edited = 'just now';
190
+ }
191
+ return structuredClone(store.meta);
192
+ }
193
+
194
+ async deleteSite(siteId: string): Promise<void> {
195
+ if (!this.sites.delete(siteId)) {
196
+ throw new CmsCapabilityError('deleteSite', `site_not_found:${siteId}`, 'cms_source_not_found');
197
+ }
198
+ }
199
+
200
+ async loadSite(siteId: string): Promise<CmsEditorSite> {
201
+ const store = this.storeOrThrow(siteId);
202
+ return cloneSite({
203
+ ...store.meta,
204
+ pages: structuredClone(store.pages),
205
+ });
206
+ }
207
+
208
+ async listPages(siteId: string) {
209
+ return structuredClone(this.storeOrThrow(siteId).pages);
210
+ }
211
+
212
+ async getPage(pageId: string) {
213
+ const { page } = this.findPage(pageId);
214
+ return structuredClone(page);
215
+ }
216
+
217
+ async createPage(siteId: string, input: Partial<CmsEditorPage> & { title: string; slug: string }) {
218
+ const store = this.storeOrThrow(siteId);
219
+ const page: CmsEditorPage = {
220
+ id: id('page'),
221
+ title: input.title,
222
+ slug: input.slug.startsWith('/') ? input.slug : `/${input.slug}`,
223
+ status: 'draft',
224
+ type: input.type || 'Interior',
225
+ sections: [],
226
+ metaTitle: input.metaTitle || input.title,
227
+ metaDescription: input.metaDescription || '',
228
+ };
229
+ store.pages.push(page);
230
+ store.meta.edited = 'just now';
231
+ return structuredClone(page);
232
+ }
233
+
234
+ async updatePage(pageId: string, patch: Partial<CmsEditorPage>) {
235
+ const { store, page } = this.findPage(pageId);
236
+ Object.assign(page, patch, { id: page.id, sections: patch.sections ?? page.sections });
237
+ store.meta.edited = 'just now';
238
+ return structuredClone(page);
239
+ }
240
+
241
+ async deletePage(pageId: string) {
242
+ const { store } = this.findPage(pageId);
243
+ store.pages = store.pages.filter((p) => p.id !== pageId);
244
+ store.revisions.delete(pageId);
245
+ store.published.delete(pageId);
246
+ store.meta.edited = 'just now';
247
+ }
248
+
249
+ async listSections(pageId: string) {
250
+ const { page } = this.findPage(pageId);
251
+ return structuredClone(page.sections);
252
+ }
253
+
254
+ async getSection(sectionId: string) {
255
+ return structuredClone(this.sectionOrThrow(sectionId).section);
256
+ }
257
+
258
+ async createSection(pageId: string, input: Partial<CmsEditorSection> & { name: string }) {
259
+ const { store, page } = this.findPage(pageId);
260
+ const section: CmsEditorSection = {
261
+ id: id('sec'),
262
+ name: input.name,
263
+ type: input.type || input.name.toLowerCase().replace(/\s+/g, '-'),
264
+ zone: input.zone || 'BODY',
265
+ visible: input.visible !== false,
266
+ color: input.color || '#111115',
267
+ fields: input.fields || {},
268
+ css: input.css || {},
269
+ blocks: input.blocks || [],
270
+ };
271
+ page.sections.push(section);
272
+ store.meta.edited = 'just now';
273
+ return structuredClone(section);
274
+ }
275
+
276
+ async updateSection(sectionId: string, patch: Partial<CmsEditorSection>) {
277
+ const { store, section } = this.sectionOrThrow(sectionId);
278
+ Object.assign(section, patch, { id: section.id, blocks: patch.blocks ?? section.blocks });
279
+ store.meta.edited = 'just now';
280
+ return structuredClone(section);
281
+ }
282
+
283
+ async deleteSection(sectionId: string) {
284
+ const { store, page } = this.sectionOrThrow(sectionId);
285
+ page.sections = page.sections.filter((s) => s.id !== sectionId);
286
+ store.meta.edited = 'just now';
287
+ }
288
+
289
+ async reorderSections(pageId: string, sectionIds: string[]) {
290
+ const { store, page } = this.findPage(pageId);
291
+ const byId = new Map(page.sections.map((s) => [s.id, s]));
292
+ page.sections = sectionIds.map((sid) => byId.get(sid)).filter(Boolean) as CmsEditorSection[];
293
+ store.meta.edited = 'just now';
294
+ }
295
+
296
+ async setSectionVisibility(sectionId: string, visible: boolean) {
297
+ const { store, section } = this.sectionOrThrow(sectionId);
298
+ section.visible = visible;
299
+ store.meta.edited = 'just now';
300
+ }
301
+
302
+ async listBlocks(sectionId: string) {
303
+ return structuredClone(this.sectionOrThrow(sectionId).section.blocks);
304
+ }
305
+
306
+ async getBlock(blockId: string) {
307
+ return structuredClone(this.blockOrThrow(blockId).block);
308
+ }
309
+
310
+ async createBlock(sectionId: string, input: Partial<CmsEditorBlock> & { type: string }) {
311
+ const { store, section } = this.sectionOrThrow(sectionId);
312
+ const block: CmsEditorBlock = {
313
+ id: id('blk'),
314
+ sectionId,
315
+ type: input.type,
316
+ visible: input.visible !== false,
317
+ data: input.data || {},
318
+ sortOrder: input.sortOrder ?? (section.blocks.length + 1) * 10,
319
+ };
320
+ section.blocks.push(block);
321
+ store.meta.edited = 'just now';
322
+ return structuredClone(block);
323
+ }
324
+
325
+ async updateBlock(blockId: string, patch: Partial<CmsEditorBlock>) {
326
+ const { store, block } = this.blockOrThrow(blockId);
327
+ Object.assign(block, patch, { id: block.id });
328
+ store.meta.edited = 'just now';
329
+ return structuredClone(block);
330
+ }
331
+
332
+ async deleteBlock(blockId: string) {
333
+ const { store, section } = this.blockOrThrow(blockId);
334
+ section.blocks = section.blocks.filter((b) => b.id !== blockId);
335
+ store.meta.edited = 'just now';
336
+ }
337
+
338
+ async reorderBlocks(sectionId: string, blockIds: string[]) {
339
+ const { store, section } = this.sectionOrThrow(sectionId);
340
+ const byId = new Map(section.blocks.map((b) => [b.id, b]));
341
+ section.blocks = blockIds
342
+ .map((bid, index) => {
343
+ const block = byId.get(bid);
344
+ if (!block) return null;
345
+ block.sortOrder = (index + 1) * 10;
346
+ return block;
347
+ })
348
+ .filter(Boolean) as CmsEditorBlock[];
349
+ store.meta.edited = 'just now';
350
+ }
351
+
352
+ private applyDraftPayload(siteId: string, pageId: string, payload: unknown) {
353
+ const store = this.storeOrThrow(siteId);
354
+ const page = store.pages.find((p) => p.id === pageId);
355
+ if (!page || !payload || typeof payload !== 'object') return;
356
+ const body = payload as Record<string, unknown>;
357
+ if (Array.isArray(body.sections)) {
358
+ page.sections = structuredClone(body.sections as CmsEditorSection[]);
359
+ }
360
+ if (body.theme && typeof body.theme === 'object') {
361
+ store.meta.theme = structuredClone(body.theme as CmsSiteRecord['theme']);
362
+ }
363
+ if (body.schemas && typeof body.schemas === 'object') {
364
+ store.meta.schemas = structuredClone(body.schemas as CmsSiteRecord['schemas']);
365
+ }
366
+ }
367
+
368
+ async saveDraft(pageId: string, payload: unknown) {
369
+ const { siteId, store, page } = this.findPage(pageId);
370
+ this.applyDraftPayload(siteId, pageId, payload);
371
+ const revision: CmsRevision = {
372
+ id: id('rev'),
373
+ pageId,
374
+ kind: 'draft',
375
+ createdAt: new Date().toISOString(),
376
+ snapshot: structuredClone({ ...page, theme: store.meta.theme, schemas: store.meta.schemas }),
377
+ };
378
+ const list = store.revisions.get(pageId) || [];
379
+ list.push(revision);
380
+ store.revisions.set(pageId, list);
381
+ store.meta.edited = 'just now';
382
+ return structuredClone(revision);
383
+ }
384
+
385
+ async getRevision(revisionId: string) {
386
+ for (const store of this.sites.values()) {
387
+ for (const list of store.revisions.values()) {
388
+ const hit = list.find((r) => r.id === revisionId);
389
+ if (hit) return structuredClone(hit);
390
+ }
391
+ }
392
+ throw new CmsCapabilityError('getRevision', `revision_not_found:${revisionId}`, 'cms_source_not_found');
393
+ }
394
+
395
+ async listRevisions(pageId: string) {
396
+ const { store } = this.findPage(pageId);
397
+ return structuredClone(store.revisions.get(pageId) || []);
398
+ }
399
+
400
+ async restoreRevision(pageId: string, revisionId: string) {
401
+ const revision = await this.getRevision(revisionId);
402
+ const { siteId, store } = this.findPage(pageId);
403
+ const snap = revision.snapshot as CmsEditorPage & {
404
+ theme?: CmsSiteRecord['theme'];
405
+ schemas?: CmsSiteRecord['schemas'];
406
+ };
407
+ const idx = store.pages.findIndex((p) => p.id === pageId);
408
+ if (idx < 0) throw new CmsCapabilityError('restoreRevision', `page_not_found:${pageId}`, 'cms_source_not_found');
409
+ store.pages[idx] = structuredClone(snap);
410
+ if (snap.theme) store.meta.theme = structuredClone(snap.theme);
411
+ if (snap.schemas) store.meta.schemas = structuredClone(snap.schemas);
412
+ store.meta.edited = 'just now';
413
+ return structuredClone(store.pages[idx]);
414
+ }
415
+
416
+ async previewDraft(pageId: string) {
417
+ const { page } = this.findPage(pageId);
418
+ return { snapshot: structuredClone(page) };
419
+ }
420
+
421
+ async publish(pageId: string, options?: { revisionId?: string }) {
422
+ const { siteId, store } = this.findPage(pageId);
423
+ let page = store.pages.find((p) => p.id === pageId)!;
424
+ if (options?.revisionId) {
425
+ page = await this.restoreRevision(pageId, options.revisionId);
426
+ }
427
+ page.status = 'live';
428
+ const snapshot: CmsPublicationSnapshot = {
429
+ publicationId: id('pub'),
430
+ route: page.slug,
431
+ revision: (store.revisions.get(pageId)?.length || 0) + 1,
432
+ theme: 'default',
433
+ sections: page.sections.map((section) => ({
434
+ type: section.type,
435
+ props: { ...section.fields, name: section.name, blocks: section.blocks },
436
+ })),
437
+ publishedAt: new Date().toISOString(),
438
+ };
439
+ store.published.set(pageId, snapshot);
440
+ const revision: CmsRevision = {
441
+ id: id('rev'),
442
+ pageId,
443
+ kind: 'publication',
444
+ createdAt: snapshot.publishedAt!,
445
+ snapshot: structuredClone(page),
446
+ };
447
+ const list = store.revisions.get(pageId) || [];
448
+ list.push(revision);
449
+ store.revisions.set(pageId, list);
450
+ store.meta.edited = 'just now';
451
+ return structuredClone(snapshot);
452
+ }
453
+
454
+ async getPublishedRevision(pageId: string) {
455
+ const { store } = this.findPage(pageId);
456
+ const hit = store.published.get(pageId);
457
+ return hit ? structuredClone(hit) : null;
458
+ }
459
+
460
+ async listAssets(siteId: string) {
461
+ return structuredClone(this.storeOrThrow(siteId).assets);
462
+ }
463
+
464
+ async getAsset(assetId: string) {
465
+ for (const store of this.sites.values()) {
466
+ const hit = store.assets.find((a) => a.id === assetId);
467
+ if (hit) return structuredClone(hit);
468
+ }
469
+ throw new CmsCapabilityError('getAsset', `asset_not_found:${assetId}`, 'cms_source_not_found');
470
+ }
471
+
472
+ async uploadAsset(siteId: string, file: Blob, meta?: { name?: string; metadata?: Record<string, unknown> }) {
473
+ const store = this.storeOrThrow(siteId);
474
+ const asset: CmsAsset = {
475
+ id: id('asset'),
476
+ name: meta?.name || 'upload',
477
+ mimeType: file.type,
478
+ size: file.size,
479
+ createdAt: new Date().toISOString(),
480
+ metadata: meta?.metadata,
481
+ };
482
+ store.assets.push(asset);
483
+ store.meta.edited = 'just now';
484
+ return structuredClone(asset);
485
+ }
486
+
487
+ async updateAsset(assetId: string, patch: Partial<Pick<CmsAsset, 'name' | 'metadata' | 'url' | 'key'>>) {
488
+ for (const store of this.sites.values()) {
489
+ const idx = store.assets.findIndex((a) => a.id === assetId);
490
+ if (idx >= 0) {
491
+ store.assets[idx] = { ...store.assets[idx], ...patch };
492
+ store.meta.edited = 'just now';
493
+ return structuredClone(store.assets[idx]);
494
+ }
495
+ }
496
+ throw new CmsCapabilityError('getAsset', `asset_not_found:${assetId}`, 'cms_source_not_found');
497
+ }
498
+
499
+ async deleteAsset(assetId: string) {
500
+ for (const store of this.sites.values()) {
501
+ const before = store.assets.length;
502
+ store.assets = store.assets.filter((a) => a.id !== assetId);
503
+ if (store.assets.length !== before) {
504
+ store.meta.edited = 'just now';
505
+ return;
506
+ }
507
+ }
508
+ throw new CmsCapabilityError('deleteAsset', `asset_not_found:${assetId}`, 'cms_source_not_found');
509
+ }
510
+ }