@inneranimalmedia/agentsam-sdk 2.6.9 → 2.6.11

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 (392) hide show
  1. package/README.md +21 -0
  2. package/TRADEMARKS.md +22 -0
  3. package/apps/README.md +3 -0
  4. package/apps/cad-creator/LICENSE +21 -0
  5. package/apps/cad-creator/README.md +4 -1
  6. package/apps/cad-creator/shared/cad/package.json +1 -1
  7. package/apps/client-cms-editor/LICENSE +21 -0
  8. package/apps/client-cms-editor/README.md +3 -0
  9. package/apps/client-cms-editor/backend/package.json +3 -3
  10. package/apps/client-cms-editor/frontend/package.json +4 -4
  11. package/apps/client-cms-editor/package-lock.json +43 -43
  12. package/apps/client-cms-editor/package.json +3 -3
  13. package/apps/client-cms-editor/reference/harvest/HARVEST_RECEIPT.json +1 -1
  14. package/apps/client-cms-editor/reference/harvest/README.md +1 -1
  15. package/apps/client-cms-editor/reference/harvest/plans/ARCHIVE-INTAKE.md +1 -1
  16. package/apps/client-cms-editor/reference/harvest/plans/HARVEST-INDEX.md +1 -1
  17. package/apps/client-cms-editor/reference/harvest/plans/TOOLING-LAB.md +1 -1
  18. package/apps/client-cms-editor/shared/cms/package.json +2 -2
  19. package/docs/MINI.md +4 -2
  20. package/docs/REPO_FILE_MAP.txt +0 -1
  21. package/docs/SOURCE_ARCHITECTURE.md +1 -1
  22. package/docs/architecture/DUAL_ANALYTICS_PRODUCT.md +140 -0
  23. package/docs/architecture/HOOKS-MODELS-SELF-HOSTING-PLAN.md +199 -0
  24. package/docs/content-studio/REVISION_GATE_2026-09-27.md +1 -1
  25. package/docs/engineering/go-portability/01-product-project-deployment-authority.md +69 -0
  26. package/docs/engineering/provider-internal-renames/01-lane-initialization.md +20 -0
  27. package/docs/engineering/provider-internal-renames/01a-runtime-environment-contract.md +115 -0
  28. package/docs/engineering/provider-internal-renames/02-cfoa.md +57 -0
  29. package/docs/engineering/provider-internal-renames/03-gclioa.md +32 -0
  30. package/docs/engineering/provider-internal-renames/04-goaude.md +50 -0
  31. package/docs/engineering/provider-internal-renames/05-gdrv.md +33 -0
  32. package/docs/engineering/provider-internal-renames/06-verification.md +103 -0
  33. package/docs/engineering/provider-internal-renames/README.md +77 -0
  34. package/docs/engineering/provider-internal-renames/runtime-environment-contract.json +220 -0
  35. package/docs/engineering/test-diagnostics/go-cli-test-hang-20261003.md +49 -0
  36. package/docs/engineering/test-diagnostics/go-skip-deploy-docker-fix.md +90 -0
  37. package/docs/knowledge-service-verification.md +3 -3
  38. package/docs/plans/AGENTSAM-SUSPEND-QUEUE-KNOWLEDGE-RDP-2026-10-03.md +870 -0
  39. package/docs/plans/LOCAL-STUDIO-GRADUATION-2026-09-26.md +9 -9
  40. package/docs/plans/MACHINE-FIRST-APPS-TUI-2026-09-24.md +11 -11
  41. package/docs/plans/RECONCILIATION-2026-09-19.md +6 -6
  42. package/docs/plans/SAM_WORK_PROTOCOL.md +667 -0
  43. package/docs/plans/TOMORROW-EXTENSIVE-TODO-2026-09-26.md +2 -2
  44. package/docs/plans/UNIVERSAL-INGEST-MACHINE-FIRST-2026-09-24.md +3 -3
  45. package/examples/hyperspace-demo/index.html +16 -0
  46. package/examples/hyperspace-demo/package.json +21 -0
  47. package/examples/hyperspace-demo/src/main.tsx +277 -0
  48. package/examples/hyperspace-demo/tsconfig.json +9 -0
  49. package/examples/hyperspace-demo/vite.config.ts +24 -0
  50. package/migrations/d1/0020_agentsam_receipt_catalog.sql +35 -0
  51. package/migrations/runtime/0005_agentsam_hooks.sql +87 -0
  52. package/migrations/runtime/0006_agent_run_suspend_activity.sql +53 -0
  53. package/migrations/runtime/0007_queue_control.sql +40 -0
  54. package/migrations/runtime/0008_agent_run_dependencies.sql +24 -0
  55. package/migrations/runtime/0008_analytics_legacy_bootstrap.sql +43 -0
  56. package/migrations/runtime/0009_analytics_authority.sql +108 -0
  57. package/package.json +45 -14
  58. package/packages/agentsam-brand/README.md +3 -0
  59. package/packages/agentsam-brand/package.json +2 -2
  60. package/packages/agentsam-brand/src/core/v2/compile.js +1 -1
  61. package/packages/agentsam-brand/src/core/v2/schema.js +1 -1
  62. package/packages/agentsam-contracts/dist/adapter.d.ts +22 -0
  63. package/packages/agentsam-contracts/dist/adapter.js +0 -0
  64. package/packages/agentsam-contracts/dist/agent.d.ts +66 -0
  65. package/packages/agentsam-contracts/dist/agent.js +15 -0
  66. package/packages/agentsam-contracts/dist/artifacts.d.ts +70 -0
  67. package/packages/agentsam-contracts/dist/artifacts.js +0 -0
  68. package/packages/agentsam-contracts/dist/authority.d.ts +21 -0
  69. package/packages/agentsam-contracts/dist/authority.js +0 -0
  70. package/packages/agentsam-contracts/dist/context.d.ts +14 -0
  71. package/packages/agentsam-contracts/dist/context.js +0 -0
  72. package/packages/agentsam-contracts/dist/errors.d.ts +121 -0
  73. package/packages/agentsam-contracts/dist/errors.js +5 -0
  74. package/packages/agentsam-contracts/dist/events.d.ts +53 -0
  75. package/packages/agentsam-contracts/dist/events.js +0 -0
  76. package/packages/agentsam-contracts/dist/execution.d.ts +38 -0
  77. package/packages/agentsam-contracts/dist/execution.js +0 -0
  78. package/packages/agentsam-contracts/dist/hooks.d.ts +31 -0
  79. package/packages/agentsam-contracts/dist/hooks.js +0 -0
  80. package/packages/agentsam-contracts/dist/identity.d.ts +15 -0
  81. package/packages/agentsam-contracts/dist/identity.js +0 -0
  82. package/packages/agentsam-contracts/dist/index.d.ts +16 -0
  83. package/packages/agentsam-contracts/dist/index.js +164 -0
  84. package/packages/agentsam-contracts/dist/models.d.ts +9 -0
  85. package/packages/agentsam-contracts/dist/models.js +0 -0
  86. package/packages/agentsam-contracts/dist/providers.d.ts +27 -0
  87. package/packages/agentsam-contracts/dist/providers.js +0 -0
  88. package/packages/agentsam-contracts/dist/repository.d.ts +56 -0
  89. package/packages/agentsam-contracts/dist/repository.js +15 -0
  90. package/packages/agentsam-contracts/dist/run.d.ts +113 -0
  91. package/packages/agentsam-contracts/dist/run.js +132 -0
  92. package/packages/agentsam-contracts/dist/tools.d.ts +82 -0
  93. package/packages/agentsam-contracts/dist/tools.js +0 -0
  94. package/packages/agentsam-contracts/dist/widgets.d.ts +38 -0
  95. package/packages/agentsam-contracts/dist/widgets.js +0 -0
  96. package/packages/agentsam-contracts/package.json +9 -1
  97. package/packages/agentsam-contracts/scripts/build.mjs +1 -1
  98. package/packages/agentsam-contracts/src/agent.ts +78 -3
  99. package/packages/agentsam-contracts/src/errors.ts +19 -10
  100. package/packages/agentsam-contracts/src/index.ts +2 -0
  101. package/packages/agentsam-contracts/src/run.ts +320 -0
  102. package/packages/agentsam-contracts/src/widgets.ts +58 -0
  103. package/packages/agentsam-contracts/test/contracts.test.mjs +1 -1
  104. package/packages/agentsam-contracts/test/run-contract.test.mjs +94 -0
  105. package/packages/agentsam-errors/package.json +11 -3
  106. package/packages/agentsam-errors/protocol/agentsam.error.v2.schema.json +821 -0
  107. package/packages/agentsam-errors/protocol/error-catalog.json +3512 -0
  108. package/packages/agentsam-errors/src/envelope.js +63 -11
  109. package/packages/agentsam-errors/src/error.js +6 -0
  110. package/packages/agentsam-errors/src/fingerprint.js +9 -1
  111. package/packages/agentsam-errors/src/normalize.js +51 -6
  112. package/packages/agentsam-errors/src/recovery.js +9 -35
  113. package/packages/agentsam-errors/src/transport.js +6 -1
  114. package/packages/agentsam-errors/src/vocabulary.js +515 -126
  115. package/packages/agentsam-errors/test/catalog-v2.test.mjs +106 -0
  116. package/packages/agentsam-errors/types/index.d.ts +157 -0
  117. package/packages/agentsam-goap/README.md +3 -0
  118. package/packages/agentsam-goap/package.json +2 -2
  119. package/packages/agentsam-hooks/README.md +206 -0
  120. package/packages/agentsam-hooks/bin/agentsam-hooks.mjs +64 -0
  121. package/packages/agentsam-hooks/bindings/go/command.go +55 -0
  122. package/packages/agentsam-hooks/bindings/go/errors_generated.go +402 -0
  123. package/packages/agentsam-hooks/bindings/go/go.mod +3 -0
  124. package/packages/agentsam-hooks/bindings/go/hooks.go +285 -0
  125. package/packages/agentsam-hooks/bindings/go/hooks_test.go +48 -0
  126. package/packages/agentsam-hooks/bindings/rust/Cargo.toml +11 -0
  127. package/packages/agentsam-hooks/bindings/rust/src/errors_generated.rs +396 -0
  128. package/packages/agentsam-hooks/bindings/rust/src/lib.rs +397 -0
  129. package/packages/agentsam-hooks/package.json +69 -0
  130. package/packages/agentsam-hooks/schema/manifest.json +54 -0
  131. package/packages/agentsam-hooks/scripts/clean-protocol.mjs +17 -0
  132. package/packages/agentsam-hooks/scripts/sync-protocol.mjs +27 -0
  133. package/packages/agentsam-hooks/src/adapters/agents.js +108 -0
  134. package/packages/agentsam-hooks/src/adapters/callback.js +4 -0
  135. package/packages/agentsam-hooks/src/adapters/capability.js +122 -0
  136. package/packages/agentsam-hooks/src/adapters/command.js +104 -0
  137. package/packages/agentsam-hooks/src/adapters/composite.js +31 -0
  138. package/packages/agentsam-hooks/src/adapters/http.js +58 -0
  139. package/packages/agentsam-hooks/src/adapters/lsp.js +116 -0
  140. package/packages/agentsam-hooks/src/adapters/mcp.js +76 -0
  141. package/packages/agentsam-hooks/src/adapters/provider.js +129 -0
  142. package/packages/agentsam-hooks/src/config.js +143 -0
  143. package/packages/agentsam-hooks/src/contracts.js +284 -0
  144. package/packages/agentsam-hooks/src/errors-generated.js +2732 -0
  145. package/packages/agentsam-hooks/src/index.d.ts +209 -0
  146. package/packages/agentsam-hooks/src/index.js +14 -0
  147. package/packages/agentsam-hooks/src/policy.js +34 -0
  148. package/packages/agentsam-hooks/src/runtime.js +312 -0
  149. package/packages/agentsam-hooks/src/store.js +264 -0
  150. package/packages/agentsam-hooks/test/adapters.test.mjs +216 -0
  151. package/packages/agentsam-hooks/test/runtime.test.mjs +258 -0
  152. package/packages/agentsam-knowledge/package.json +1 -1
  153. package/packages/agentsam-knowledge/src/backends/index.js +1 -1
  154. package/packages/agentsam-merch/README.md +62 -0
  155. package/packages/agentsam-merch/bin/agentsam-merch.mjs +16 -0
  156. package/packages/agentsam-merch/package.json +65 -0
  157. package/packages/agentsam-merch/profiles/completeful/dtg-back-large.json +42 -0
  158. package/packages/agentsam-merch/profiles/completeful/laser-engraving.json +39 -0
  159. package/packages/agentsam-merch/profiles/generic/embroidery-digitization.json +22 -0
  160. package/packages/agentsam-merch/schemas/collection-candidate.schema.json +66 -0
  161. package/packages/agentsam-merch/schemas/manufacturing-profile.schema.json +221 -0
  162. package/packages/agentsam-merch/src/adapters-completeful.js +50 -0
  163. package/packages/agentsam-merch/src/cli.js +93 -0
  164. package/packages/agentsam-merch/src/collection-lab.js +60 -0
  165. package/packages/agentsam-merch/src/compatibility.js +501 -0
  166. package/packages/agentsam-merch/src/derivatives.js +112 -0
  167. package/packages/agentsam-merch/src/index.d.ts +316 -0
  168. package/packages/agentsam-merch/src/index.js +46 -0
  169. package/packages/agentsam-merch/src/node/index.d.ts +58 -0
  170. package/packages/agentsam-merch/src/node/index.js +6 -0
  171. package/packages/agentsam-merch/src/node/raster.js +142 -0
  172. package/packages/agentsam-merch/src/node/vector.js +239 -0
  173. package/packages/agentsam-merch/src/product-concepts.js +118 -0
  174. package/packages/agentsam-merch/src/profile-registry.js +104 -0
  175. package/packages/agentsam-merch/src/profile.js +158 -0
  176. package/packages/agentsam-merch/src/transforms.js +215 -0
  177. package/packages/agentsam-merch/test/merch.test.mjs +332 -0
  178. package/packages/agentsam-merch/test/node-transforms.test.mjs +149 -0
  179. package/packages/agentsam-nav/dist/Nav.d.ts +43 -0
  180. package/packages/agentsam-nav/dist/NavCollapsible.d.ts +10 -0
  181. package/packages/agentsam-nav/dist/NavContent.d.ts +2 -0
  182. package/packages/agentsam-nav/dist/NavFooter.d.ts +2 -0
  183. package/packages/agentsam-nav/dist/NavGroup.d.ts +3 -0
  184. package/packages/agentsam-nav/dist/NavHeader.d.ts +2 -0
  185. package/packages/agentsam-nav/dist/NavMenu.d.ts +22 -0
  186. package/packages/agentsam-nav/dist/NavProvider.d.ts +35 -0
  187. package/packages/agentsam-nav/dist/NavTrigger.d.ts +2 -0
  188. package/packages/agentsam-nav/dist/Surfaces.d.ts +41 -0
  189. package/packages/agentsam-nav/dist/browser.d.ts +11 -0
  190. package/packages/agentsam-nav/dist/browser.global.js +172 -0
  191. package/packages/agentsam-nav/dist/browser.js +9688 -0
  192. package/packages/agentsam-nav/dist/contracts.d.ts +76 -0
  193. package/packages/agentsam-nav/dist/index.d.ts +11 -0
  194. package/packages/agentsam-nav/dist/index.js +9689 -0
  195. package/packages/agentsam-nav/dist/legacy.css +83 -0
  196. package/packages/agentsam-nav/dist/shell.css +113 -0
  197. package/packages/agentsam-nav/dist/theme.css +113 -0
  198. package/packages/agentsam-nav/dist/utils.d.ts +1 -0
  199. package/packages/agentsam-nav/package.json +1 -1
  200. package/packages/agentsam-queue-control/README.md +4 -1
  201. package/packages/agentsam-queue-control/package.json +4 -3
  202. package/packages/agentsam-queue-control/schemas/job-envelope.schema.json +111 -11
  203. package/packages/agentsam-queue-control/src/adapters/cloudflare.js +34 -6
  204. package/packages/agentsam-queue-control/src/adapters/memory.js +11 -2
  205. package/packages/agentsam-queue-control/src/adapters/sqlite.js +259 -0
  206. package/packages/agentsam-queue-control/src/contracts.js +207 -3
  207. package/packages/agentsam-queue-control/src/control-plane.js +62 -2
  208. package/packages/agentsam-queue-control/src/index.js +1 -0
  209. package/packages/agentsam-queue-control/test/queue-control.test.mjs +310 -0
  210. package/packages/agentsam-queue-control/test/sqlite-adapter.test.mjs +91 -0
  211. package/packages/agentsam-rapid-rust/README.md +3 -0
  212. package/packages/agentsam-repository/README.md +3 -0
  213. package/packages/agentsam-repository/package.json +1 -1
  214. package/packages/agentsam-vault/package.json +1 -1
  215. package/packages/agentsam-workbench/README.md +43 -0
  216. package/packages/agentsam-workbench/package.json +14 -4
  217. package/packages/agentsam-workbench/src/agent/AgentConversationSurface.tsx +108 -0
  218. package/packages/agentsam-workbench/src/agent/AgentPanel.tsx +25 -8
  219. package/packages/agentsam-workbench/src/agent/AgentRuntimeField.tsx +152 -0
  220. package/packages/agentsam-workbench/src/agent/Composer.tsx +10 -1
  221. package/packages/agentsam-workbench/src/agent/RunMode.ts +26 -0
  222. package/packages/agentsam-workbench/src/agent/Thread.tsx +18 -3
  223. package/packages/agentsam-workbench/src/agent/index.ts +3 -0
  224. package/packages/agentsam-workbench/src/index.ts +4 -0
  225. package/packages/agentsam-workbench/src/manufacturing/PreflightIndicator.tsx +203 -0
  226. package/packages/agentsam-workbench/src/manufacturing/index.ts +2 -0
  227. package/packages/agentsam-workbench/src/manufacturing/loading.ts +147 -0
  228. package/packages/agentsam-workbench/src/widgets/BuiltinWidget.tsx +22 -0
  229. package/packages/agentsam-workbench/src/widgets/CountdownWidget.tsx +68 -0
  230. package/packages/agentsam-workbench/src/widgets/WidgetFrame.tsx +56 -0
  231. package/packages/agentsam-workbench/src/widgets/countdown.ts +25 -0
  232. package/packages/agentsam-workbench/src/widgets/index.ts +6 -0
  233. package/packages/agentsam-workbench/src/widgets/registry.ts +13 -0
  234. package/packages/agentsam-workbench/src/widgets/useCountdown.ts +128 -0
  235. package/packages/agentsam-workbench/src/widgets/widgets.css +102 -0
  236. package/packages/connectors/{cloudflare → cfoa}/package.json +3 -3
  237. package/packages/heuristic-theme/package.json +1 -1
  238. package/packages/identity/README.md +3 -0
  239. package/packages/identity/backend/README.md +3 -0
  240. package/packages/identity/package.json +2 -2
  241. package/packages/identity/src/frontend/auth-portal/README.md +3 -0
  242. package/packages/identity/src/index.js +1 -1
  243. package/packages/identity/src/oauth/README.md +4 -1
  244. package/packages/identity/src/oauth/credentials.js +1 -1
  245. package/packages/identity/src/server/worker-router.js +1 -1
  246. package/packages/identity/tests/google-desktop-identity-login.test.mjs +1 -1
  247. package/packages/identity/tests/lane1-packed-consumer.test.mjs +1 -1
  248. package/packages/identity/tests/oauth-presets-accounts-ssot.test.mjs +1 -1
  249. package/packages/providers/completeful/package.json +1 -1
  250. package/packages/theme-church-site/package.json +2 -2
  251. package/packages/theme-companions-site/package.json +2 -2
  252. package/packages/theme-floors-site/package.json +2 -2
  253. package/packages/theme-fuelnfree-site/package.json +2 -2
  254. package/packages/theme-handyman-site/package.json +2 -2
  255. package/packages/theme-insurance-site/package.json +2 -2
  256. package/packages/theme-scenes/package.json +1 -1
  257. package/packages/theme-shinshu-site/package.json +2 -2
  258. package/packages/work-graph/package.json +1 -1
  259. package/protocol/apps/agentsam.app.v1.schema.json +1 -1
  260. package/protocol/apps/agentsam.host-install.v1.schema.json +1 -1
  261. package/protocol/assets/asset-record.v1.schema.json +1 -1
  262. package/protocol/brand/brandpack.v1.schema.json +1 -1
  263. package/protocol/capabilities/capability-manifest.schema.json +1 -1
  264. package/protocol/capabilities/knowledge-search-input.schema.json +1 -0
  265. package/protocol/credentials/issue.v1.schema.json +1 -1
  266. package/protocol/database/agentsam.schema-pack.v1.schema.json +1 -1
  267. package/protocol/database/connection.v1.schema.json +1 -1
  268. package/protocol/embeddings/embedding-profile.v1.schema.json +1 -1
  269. package/protocol/errors/README.md +36 -0
  270. package/protocol/errors/agentsam.error.v2.schema.json +821 -0
  271. package/protocol/errors/error-catalog.json +3506 -158
  272. package/protocol/errors/error-envelope.schema.json +195 -52
  273. package/protocol/errors/recovery.v1.schema.json +1 -1
  274. package/protocol/features/agentsam.feature.v1.schema.json +1 -1
  275. package/protocol/hooks/README.md +18 -0
  276. package/protocol/hooks/agentsam.hook.output.v1.schema.json +27 -0
  277. package/protocol/hooks/agentsam.hook.receipt.v1.schema.json +61 -0
  278. package/protocol/hooks/agentsam.hook.v1.schema.json +35 -0
  279. package/protocol/hooks/agentsam.hooks.config.v1.schema.json +78 -0
  280. package/protocol/local-engine/benchmark.v1.schema.json +1 -1
  281. package/protocol/local-engine/engine.v1.schema.json +1 -1
  282. package/protocol/models/README.md +3 -0
  283. package/protocol/models/model-inventory-v2.schema.json +1 -1
  284. package/protocol/models/provider-model-snapshot.v1.schema.json +22 -0
  285. package/protocol/receipts/agentsam.receipt.v1.json +95 -0
  286. package/protocol/rpc/v1/errors.proto +1 -0
  287. package/protocol/runtime/agentsam.runtime.v1.schema.json +1 -1
  288. package/protocol/runtime/workspace-fs.v1.schema.json +1 -1
  289. package/protocol/sam/activity.v1.schema.json +1 -1
  290. package/protocol/sam/answer.v1.schema.json +1 -1
  291. package/protocol/sam/calibration.v1.schema.json +1 -1
  292. package/protocol/sam/decision-receipt.v1.schema.json +1 -1
  293. package/protocol/sam/evaluation.v1.schema.json +1 -1
  294. package/protocol/sam/operation.schema.json +1 -1
  295. package/protocol/sam/outcome.v1.schema.json +1 -1
  296. package/protocol/sam/question.v1.schema.json +1 -1
  297. package/protocol/sam/result.schema.json +1 -1
  298. package/protocol/sam/state.v1.schema.json +1 -1
  299. package/protocol/scoring/scorecard.v1.schema.json +1 -1
  300. package/protocol/skills/agentsam.interaction.v1.schema.json +1 -1
  301. package/protocol/skills/agentsam.skill.v1.schema.json +1 -1
  302. package/protocol/theme-refinery/product-metadata.schema.json +1 -1
  303. package/protocol/theme-refinery/receipts/products-registry-batch-20260924.json +6 -6
  304. package/protocol/theme-refinery/receipts/theme-harvest-20260924.json +6 -6
  305. package/protocol/theme-refinery/reconciliation-receipt.schema.json +1 -1
  306. package/protocol/ui/icon.v1.schema.json +1 -1
  307. package/python/README.md +20 -0
  308. package/python/agentsam_sdk/errors/__init__.py +4 -0
  309. package/python/agentsam_sdk/errors/vocabulary.py +2730 -0
  310. package/python/agentsam_sdk/hooks/__init__.py +32 -0
  311. package/python/agentsam_sdk/hooks/adapters.py +132 -0
  312. package/python/agentsam_sdk/hooks/contracts.py +121 -0
  313. package/python/agentsam_sdk/hooks/runtime.py +253 -0
  314. package/python/tests/test_hooks.py +115 -0
  315. package/skills/README.md +3 -0
  316. package/src/acp/agent-executor.js +106 -0
  317. package/src/acp/client.js +316 -0
  318. package/src/acp/dependencies.js +426 -0
  319. package/src/acp/http.js +207 -0
  320. package/src/acp/index.js +22 -0
  321. package/src/acp/runs.js +125 -0
  322. package/src/acp/runtime-selection.js +180 -0
  323. package/src/agent/responses-runner.js +145 -1
  324. package/src/cli/command-catalog.js +4 -0
  325. package/src/cli.js +33 -0
  326. package/src/commands/cheat-sheet.js +1 -0
  327. package/src/commands/cloudflare-login.js +1 -1
  328. package/src/commands/cloudflare.js +2 -2
  329. package/src/commands/connections.js +1 -1
  330. package/src/commands/go.js +76 -6
  331. package/src/commands/hooks.js +260 -0
  332. package/src/commands/merch.js +5 -0
  333. package/src/commands/mini.js +1 -1
  334. package/src/commands/models.js +1 -1
  335. package/src/commands/receipts.js +140 -0
  336. package/src/commands/run.js +253 -0
  337. package/src/commands/shell.js +114 -9
  338. package/src/errors/diagnostic.js +9 -9
  339. package/src/go/container.js +1 -1
  340. package/src/go/contract.js +61 -18
  341. package/src/go/discover.js +0 -4
  342. package/src/go/index.js +13 -1
  343. package/src/go/probe.js +109 -0
  344. package/src/go/{cloudflare.js → providers/cloudflare.js} +36 -136
  345. package/src/go/verify.js +1 -1
  346. package/src/index.js +32 -0
  347. package/src/indexing/ingest/inventory.js +1 -1
  348. package/src/knowledge/service/grpc-codec.js +2 -0
  349. package/src/lib/deploy/local-studio.js +2 -2
  350. package/src/lib/mini/scaffold.js +1 -1
  351. package/src/lib/slash-commands.js +1 -0
  352. package/src/lib/whoami-capabilities.js +1 -1
  353. package/src/local/runtime-store.js +54 -0
  354. package/src/mcp/cloudflare-bundles.js +1 -1
  355. package/src/models/catalog.js +0 -49
  356. package/src/models/inventory-core.js +69 -0
  357. package/src/plugins/index.js +9 -1
  358. package/src/plugins/registry.js +115 -6
  359. package/src/receipts/contract.js +68 -0
  360. package/src/receipts/index.js +20 -0
  361. package/src/receipts/prune.js +64 -0
  362. package/src/receipts/sinks.js +285 -0
  363. package/src/rpc/generated/errors_pb.js +49 -1
  364. package/src/tools/runtime.js +13 -5
  365. package/templates/mini/gadget/app.js +15 -40
  366. package/templates/mini/gadget/index.html +7 -7
  367. package/templates/mini/shared/style.css +1 -1
  368. /package/packages/connectors/{cloudflare → cfoa}/OAUTH_STORAGE_AUDIT.md +0 -0
  369. /package/packages/connectors/{cloudflare → cfoa}/src/api-client.js +0 -0
  370. /package/packages/connectors/{cloudflare → cfoa}/src/capabilities.js +0 -0
  371. /package/packages/connectors/{cloudflare → cfoa}/src/credential.js +0 -0
  372. /package/packages/connectors/{cloudflare → cfoa}/src/families/brand-protection.js +0 -0
  373. /package/packages/connectors/{cloudflare → cfoa}/src/families/keyless.js +0 -0
  374. /package/packages/connectors/{cloudflare → cfoa}/src/families/pages.js +0 -0
  375. /package/packages/connectors/{cloudflare → cfoa}/src/families/scanner.js +0 -0
  376. /package/packages/connectors/{cloudflare → cfoa}/src/families/snippets.js +0 -0
  377. /package/packages/connectors/{cloudflare → cfoa}/src/families/tag-gateway.js +0 -0
  378. /package/packages/connectors/{cloudflare → cfoa}/src/families/tags.js +0 -0
  379. /package/packages/connectors/{cloudflare → cfoa}/src/families/token-validation.js +0 -0
  380. /package/packages/connectors/{cloudflare → cfoa}/src/families/vectorize.js +0 -0
  381. /package/packages/connectors/{cloudflare → cfoa}/src/families/workflows.js +0 -0
  382. /package/packages/connectors/{cloudflare → cfoa}/src/index.js +0 -0
  383. /package/packages/connectors/{cloudflare → cfoa}/src/oauth-persist.js +0 -0
  384. /package/packages/connectors/{cloudflare → cfoa}/src/owner.js +0 -0
  385. /package/packages/connectors/{cloudflare → cfoa}/src/permission-options.js +0 -0
  386. /package/packages/connectors/{cloudflare → cfoa}/src/routes.js +0 -0
  387. /package/packages/connectors/{cloudflare → cfoa}/src/scope-catalog.js +0 -0
  388. /package/packages/connectors/{cloudflare → cfoa}/src/vault.js +0 -0
  389. /package/packages/connectors/{cloudflare → cfoa}/tests/capabilities.test.mjs +0 -0
  390. /package/packages/connectors/{cloudflare → cfoa}/tests/connector.test.mjs +0 -0
  391. /package/packages/connectors/{cloudflare → cfoa}/tests/oauth-persist.test.mjs +0 -0
  392. /package/packages/identity/src/oauth/{google-desktop-exchange.js → goaude.js} +0 -0
@@ -24,6 +24,75 @@ export const WORKERS_AI_CURATED_MODEL_IDS = Object.freeze([
24
24
  ]);
25
25
 
26
26
  const CURATED = new Set(WORKERS_AI_CURATED_MODEL_IDS);
27
+ export const PROVIDER_MODEL_SNAPSHOT_SCHEMA = 'agentsam.provider-model-snapshot.v1';
28
+
29
+ function modelSnapshotHash(modelIds) {
30
+ const source = modelIds.join('\n');
31
+ let hash = 2166136261;
32
+ for (let index = 0; index < source.length; index += 1) {
33
+ hash ^= source.charCodeAt(index);
34
+ hash = Math.imul(hash, 16777619);
35
+ }
36
+ return `fnv1a32:${(hash >>> 0).toString(16).padStart(8, '0')}`;
37
+ }
38
+
39
+ /**
40
+ * Compact credential-scoped availability evidence for an existing
41
+ * `agentsam_plugins` AI installation. The global catalog remains curated
42
+ * reference data; discovery never creates one model row per user.
43
+ */
44
+ export function createProviderModelSnapshot(provider, models = [], options = {}) {
45
+ const providerId = String(provider || '').trim().toLowerCase();
46
+ if (!providerId) throw new TypeError('provider_required');
47
+ const modelIds = [...new Set(models.map((row) => String(
48
+ typeof row === 'string' ? row : row?.provider_model_id || row?.model_id || '',
49
+ ).trim()).filter(Boolean))].sort();
50
+ const fetchedAtUnix = Number.isFinite(Number(options.fetchedAtUnix))
51
+ ? Math.max(0, Math.floor(Number(options.fetchedAtUnix)))
52
+ : Math.floor(Date.now() / 1000);
53
+ return Object.freeze({
54
+ schema: PROVIDER_MODEL_SNAPSHOT_SCHEMA,
55
+ provider: providerId,
56
+ model_ids: Object.freeze(modelIds),
57
+ model_count: modelIds.length,
58
+ models_hash: modelSnapshotHash(modelIds),
59
+ fetched_at_unix: fetchedAtUnix,
60
+ authority: 'credential_scoped_provider_discovery',
61
+ });
62
+ }
63
+
64
+ /**
65
+ * Produce fields for the existing `agentsam_plugins` row. Failed probes keep
66
+ * the last good snapshot while updating health evidence; no secret or model
67
+ * catalog rows are written.
68
+ */
69
+ export function createAiPluginProbePatch(previousMetadata = {}, discovery = {}, options = {}) {
70
+ const now = Number.isFinite(Number(options.fetchedAtUnix))
71
+ ? Math.max(0, Math.floor(Number(options.fetchedAtUnix)))
72
+ : Math.floor(Date.now() / 1000);
73
+ const metadata = previousMetadata && typeof previousMetadata === 'object' && !Array.isArray(previousMetadata)
74
+ ? { ...previousMetadata }
75
+ : {};
76
+ if (discovery.ok === true) {
77
+ metadata.model_snapshot = createProviderModelSnapshot(
78
+ options.provider || discovery.provider,
79
+ discovery.models || [],
80
+ { fetchedAtUnix: now },
81
+ );
82
+ }
83
+ const error = String(discovery.error || '').trim();
84
+ const authFailure = /\b(?:401|403)\b|unauthoriz|forbidden|invalid[_ -]?(?:api[_ -]?)?key|credential.*reject/i.test(error);
85
+ return Object.freeze({
86
+ metadata,
87
+ health_status: discovery.ok === true ? 'healthy' : authFailure ? 'auth_error' : 'unreachable',
88
+ last_health_at: now,
89
+ ...(discovery.ok === true ? { last_healthy_at: now, consecutive_failures: 0, last_error_code: null, last_error_message: null } : {
90
+ consecutive_failures_delta: 1,
91
+ last_error_code: authFailure ? 'provider_credential_rejected' : 'provider_discovery_failed',
92
+ last_error_message: authFailure ? 'Provider credential rejected' : 'Provider model discovery failed',
93
+ }),
94
+ });
95
+ }
27
96
 
28
97
  const SERVICE_TO_PROVIDER = Object.freeze({
29
98
  openai: 'openai',
@@ -5,7 +5,15 @@ export {
5
5
  INNERANIMALMEDIA_CLOUDFLARE_OAUTH_PLUGIN_MANIFEST,
6
6
  } from './cloudflare.js';
7
7
  export { COMPLETEFUL_PLUGIN_MANIFEST } from './completeful.js';
8
- export { installPlugin, listPlugins, listPluginTools, recordPluginHealthCheck, recordToolCall } from './registry.js';
8
+ export {
9
+ installPlugin,
10
+ listPlugins,
11
+ listPluginTools,
12
+ updatePluginPreferences,
13
+ recordPluginHealthCheck,
14
+ recordAiPluginModelDiscovery,
15
+ recordToolCall,
16
+ } from './registry.js';
9
17
  export { createPluginRuntime, createPluginCapabilityAdapter, executeAgentSamTool } from './runtime.js';
10
18
  export { resolveProjectPluginScope, resolveProjectPluginResources, resolveProjectRuntimeResources, resolveProjectVectorizeScope } from './resource-scope.js';
11
19
  export { resolveVectorizeConfig, executeVectorizeTool } from './vectorize.js';
@@ -1,4 +1,5 @@
1
1
  import { normalizePluginManifest } from './contracts.js';
2
+ import { createAiPluginProbePatch } from '../models/inventory-core.js';
2
3
 
3
4
  function clean(value) { return value == null ? '' : String(value).trim(); }
4
5
  function json(value, fallback) { try { return JSON.parse(String(value ?? '')); } catch { return fallback; } }
@@ -41,9 +42,11 @@ export async function installPlugin(db, options = {}) {
41
42
  provider_key=?, plugin_kind=?, category=?, display_name=?, short_name=?, description=?, mention_aliases_json=?,
42
43
  endpoint_url=?, transport=?, auth_type=?, secret_ref=?, oauth_connect_url=?, capabilities_json=?, tool_lanes_json=?,
43
44
  resource_scope_json=?, config_json=?, metadata_json=?, icon_url=?, icon_dark_url=?, icon_alt=?, icon_fit=?,
44
- composer_visible=?, settings_visible=?, sort_priority=?, health_strategy=?, is_enabled=1, updated_at=unixepoch()
45
+ composer_visible=?, settings_visible=?, sort_priority=?, health_strategy=?,
46
+ is_enabled=CASE WHEN ? THEN is_enabled ELSE 1 END,
47
+ updated_at=unixepoch()
45
48
  WHERE id=?
46
- `, [...values, pluginId]);
49
+ `, [...values, options.preserveEnabled === true ? 1 : 0, pluginId]);
47
50
  } else {
48
51
  await runMutation(db, `
49
52
  INSERT INTO agentsam_plugins (
@@ -121,11 +124,13 @@ export async function installPlugin(db, options = {}) {
121
124
  export async function listPlugins(db, options = {}) {
122
125
  const accountId = clean(options.accountId);
123
126
  const environment = clean(options.environment || 'production');
127
+ const includeDisabled = options.includeDisabled === true;
124
128
  const result = await db.prepare(`
125
129
  SELECT * FROM agentsam_plugins
126
- WHERE account_id = ? AND environment = ? AND is_enabled = 1
130
+ WHERE account_id = ? AND environment = ?
131
+ AND (? = 1 OR is_enabled = 1)
127
132
  ORDER BY sort_priority, display_name
128
- `).bind(accountId, environment).all();
133
+ `).bind(accountId, environment, includeDisabled ? 1 : 0).all();
129
134
  return (result?.results || []).map((row) => ({
130
135
  ...row,
131
136
  mention_aliases: json(row.mention_aliases_json, []), capabilities: json(row.capabilities_json, []),
@@ -136,18 +141,67 @@ export async function listPlugins(db, options = {}) {
136
141
 
137
142
  export async function listPluginTools(db, options = {}) {
138
143
  const accountId = clean(options.accountId);
144
+ const includeDisabledPlugins = options.includeDisabledPlugins === true;
139
145
  const result = await db.prepare(`
140
146
  SELECT t.* FROM agentsam_tools t
141
147
  JOIN agentsam_plugins p ON p.id = t.plugin_id
142
- WHERE t.account_id = ? AND t.is_active = 1 AND p.is_enabled = 1
148
+ WHERE t.account_id = ? AND t.is_active = 1
149
+ AND (? = 1 OR p.is_enabled = 1)
143
150
  ORDER BY t.connector_priority, t.sort_priority, t.tool_name
144
- `).bind(accountId).all();
151
+ `).bind(accountId, includeDisabledPlugins ? 1 : 0).all();
145
152
  return (result?.results || []).map((row) => ({
146
153
  ...row, input_schema: json(row.input_schema, {}), output_schema: json(row.output_schema, null),
147
154
  handler_config: json(row.handler_config, {}), intent_tags: json(row.intent_tags, []),
148
155
  }));
149
156
  }
150
157
 
158
+
159
+ export async function updatePluginPreferences(db, options = {}) {
160
+ if (!db?.prepare) throw new TypeError('D1-compatible database binding required');
161
+ const accountId = clean(options.accountId);
162
+ const pluginId = clean(options.pluginId);
163
+ if (!accountId) throw new Error('plugin_account_id_required');
164
+ if (!pluginId) throw new Error('plugin_id_required');
165
+
166
+ const fields = [];
167
+ const values = [];
168
+ if (typeof options.enabled === 'boolean') {
169
+ fields.push('is_enabled=?');
170
+ values.push(options.enabled ? 1 : 0);
171
+ }
172
+ if (typeof options.composerVisible === 'boolean') {
173
+ fields.push('composer_visible=?');
174
+ values.push(options.composerVisible ? 1 : 0);
175
+ }
176
+ if (typeof options.settingsVisible === 'boolean') {
177
+ fields.push('settings_visible=?');
178
+ values.push(options.settingsVisible ? 1 : 0);
179
+ }
180
+ if (!fields.length) throw new Error('plugin_preferences_empty');
181
+
182
+ await runMutation(db, `
183
+ UPDATE agentsam_plugins
184
+ SET ${fields.join(', ')}, updated_at=unixepoch()
185
+ WHERE id=? AND account_id=?
186
+ `, [...values, pluginId, accountId]);
187
+
188
+ const row = await db.prepare(`
189
+ SELECT * FROM agentsam_plugins
190
+ WHERE id=? AND account_id=?
191
+ LIMIT 1
192
+ `).bind(pluginId, accountId).first();
193
+ if (!row) throw new Error('plugin_not_found');
194
+ return {
195
+ ...row,
196
+ mention_aliases: json(row.mention_aliases_json, []),
197
+ capabilities: json(row.capabilities_json, []),
198
+ tool_lanes: json(row.tool_lanes_json, []),
199
+ resource_scope: json(row.resource_scope_json, {}),
200
+ config: json(row.config_json, {}),
201
+ metadata: json(row.metadata_json, {}),
202
+ };
203
+ }
204
+
151
205
  export async function recordPluginHealthCheck(db, value = {}) {
152
206
  const startedAt = Number(value.startedAt || Math.floor(Date.now() / 1000));
153
207
  const completedAt = Number(value.completedAt || Math.floor(Date.now() / 1000));
@@ -188,6 +242,61 @@ export async function recordPluginHealthCheck(db, value = {}) {
188
242
  return { id: checkId, status: value.status };
189
243
  }
190
244
 
245
+ /**
246
+ * Persist credential-verified AI model availability in the existing plugin
247
+ * installation metadata. A failed probe records health evidence but preserves
248
+ * the last successful model snapshot.
249
+ */
250
+ export async function recordAiPluginModelDiscovery(db, value = {}) {
251
+ if (!db?.prepare) throw new TypeError('D1-compatible database binding required');
252
+ const pluginId = clean(value.pluginId);
253
+ const accountId = clean(value.accountId);
254
+ if (!pluginId) throw new Error('plugin_id_required');
255
+ if (!accountId) throw new Error('plugin_account_id_required');
256
+ const plugin = await db.prepare(`
257
+ SELECT id, plugin_key, provider_key, environment, plugin_kind, metadata_json
258
+ FROM agentsam_plugins WHERE id = ? AND account_id = ? LIMIT 1
259
+ `).bind(pluginId, accountId).first();
260
+ if (!plugin) throw new Error(`plugin_not_found:${pluginId}`);
261
+ if (clean(plugin.plugin_kind) !== 'ai') throw new Error(`plugin_not_ai:${pluginId}`);
262
+
263
+ const probe = createAiPluginProbePatch(json(plugin.metadata_json, {}), value.discovery || {}, {
264
+ provider: value.provider || plugin.provider_key,
265
+ fetchedAtUnix: value.completedAt,
266
+ });
267
+ await runMutation(db, `
268
+ UPDATE agentsam_plugins SET metadata_json = ?, updated_at = unixepoch()
269
+ WHERE id = ? AND account_id = ?
270
+ `, [JSON.stringify(probe.metadata), pluginId, accountId]);
271
+
272
+ const snapshot = probe.metadata.model_snapshot || null;
273
+ const health = await recordPluginHealthCheck(db, {
274
+ pluginId,
275
+ pluginKey: plugin.plugin_key,
276
+ accountId,
277
+ environment: plugin.environment,
278
+ checkKind: 'model_inventory',
279
+ checkSource: value.checkSource || 'provider_discovery',
280
+ status: probe.health_status,
281
+ startedAt: value.startedAt,
282
+ completedAt: probe.last_health_at,
283
+ latencyMs: value.latencyMs,
284
+ httpStatus: value.httpStatus,
285
+ providerRequestId: value.providerRequestId,
286
+ errorCode: probe.last_error_code,
287
+ errorMessage: probe.last_error_message,
288
+ details: snapshot ? {
289
+ schema: snapshot.schema,
290
+ provider: snapshot.provider,
291
+ model_count: snapshot.model_count,
292
+ models_hash: snapshot.models_hash,
293
+ fetched_at_unix: snapshot.fetched_at_unix,
294
+ ...(value.discovery?.ok === true ? {} : { snapshot_preserved: true }),
295
+ } : { provider: clean(value.provider || plugin.provider_key), snapshot_preserved: true },
296
+ });
297
+ return Object.freeze({ ...health, plugin_id: pluginId, health_status: probe.health_status, model_snapshot: snapshot });
298
+ }
299
+
191
300
  export async function recordToolCall(db, value = {}) {
192
301
  const callId = clean(value.id) || id('atcl');
193
302
  await runMutation(db, `
@@ -0,0 +1,68 @@
1
+ export const RECEIPT_ENVELOPE_SCHEMA = "agentsam.receipt.v1";
2
+ export const SCHEMA_BASE_URL = "https://schemas.inneranimalmedia.com";
3
+ export const SCHEMAS_BUCKET_NAME = "inneranimalmedia-schemas";
4
+ export const RECEIPT_SCHEMA_URL =
5
+ `${SCHEMA_BASE_URL}/agentsam/schemas/agentsam.receipt.v1.json`;
6
+ export const RECEIPT_R2_PREFIX = "agentsam/runtime/receipts/v1";
7
+ export const BLOB_R2_PREFIX = "agentsam/runtime/blobs/sha256";
8
+
9
+ export function validateReceiptEnvelope(receipt) {
10
+ const errors = [];
11
+ if (!receipt || typeof receipt !== "object") {
12
+ return { ok: false, errors: ["receipt must be an object"] };
13
+ }
14
+ if (receipt.schema !== RECEIPT_ENVELOPE_SCHEMA) {
15
+ errors.push(`schema must be ${RECEIPT_ENVELOPE_SCHEMA}`);
16
+ }
17
+ if (!receipt.receipt_id) errors.push("receipt_id is required");
18
+ if (!receipt.kind) errors.push("kind is required");
19
+ if (!["passed", "failed", "skipped"].includes(receipt.status)) {
20
+ errors.push("status must be passed, failed, or skipped");
21
+ }
22
+ if (
23
+ !["ephemeral_success", "failure_bundle", "release_proof"].includes(
24
+ receipt.retention_class,
25
+ )
26
+ ) {
27
+ errors.push("retention_class is invalid");
28
+ }
29
+ if (!receipt.identity?.account_id) {
30
+ errors.push("identity.account_id is required");
31
+ }
32
+ if (!Number.isFinite(Number(receipt.metrics?.created_at_unix))) {
33
+ errors.push("metrics.created_at_unix is required");
34
+ }
35
+ for (const artifact of receipt.evidence?.artifacts || []) {
36
+ if (
37
+ artifact.r2_key &&
38
+ !String(artifact.r2_key).startsWith(`${BLOB_R2_PREFIX}/`)
39
+ ) {
40
+ errors.push(
41
+ `artifact r2_key must start with ${BLOB_R2_PREFIX}/`,
42
+ );
43
+ }
44
+ }
45
+ return Object.freeze({ ok: errors.length === 0, errors: Object.freeze(errors) });
46
+ }
47
+
48
+ export function receiptDatePrefix(receipt) {
49
+ const unix = Number(receipt?.metrics?.created_at_unix);
50
+ if (!Number.isFinite(unix) || unix < 0) {
51
+ throw new TypeError("receipt.metrics.created_at_unix is required");
52
+ }
53
+ return new Date(unix * 1000).toISOString().slice(0, 10).replace(/-/g, "/");
54
+ }
55
+
56
+ export function receiptR2Key(receipt) {
57
+ return `${RECEIPT_R2_PREFIX}/${receiptDatePrefix(receipt)}/${receipt.receipt_id}.json`;
58
+ }
59
+
60
+ export function retentionExpiresAt(receipt, nowUnix = Math.floor(Date.now() / 1000)) {
61
+ if (receipt.retention_class === "ephemeral_success") {
62
+ return nowUnix + 7 * 86400;
63
+ }
64
+ if (receipt.retention_class === "failure_bundle") {
65
+ return nowUnix + 60 * 86400;
66
+ }
67
+ return null;
68
+ }
@@ -0,0 +1,20 @@
1
+ export {
2
+ BLOB_R2_PREFIX,
3
+ RECEIPT_ENVELOPE_SCHEMA,
4
+ RECEIPT_R2_PREFIX,
5
+ RECEIPT_SCHEMA_URL,
6
+ SCHEMA_BASE_URL,
7
+ SCHEMAS_BUCKET_NAME,
8
+ receiptDatePrefix,
9
+ receiptR2Key,
10
+ retentionExpiresAt,
11
+ validateReceiptEnvelope,
12
+ } from "./contract.js";
13
+ export {
14
+ CompositeReceiptSink,
15
+ D1ReceiptCatalog,
16
+ LocalReceiptSink,
17
+ R2ReceiptSink,
18
+ ReceiptCatalogReader,
19
+ } from "./sinks.js";
20
+ export { pruneLocalWorkspaces } from "./prune.js";
@@ -0,0 +1,64 @@
1
+ import { readdir, rm, stat } from "node:fs/promises";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+
5
+ async function directorySize(root) {
6
+ let total = 0;
7
+ const entries = await readdir(root, { withFileTypes: true }).catch(() => []);
8
+ for (const entry of entries) {
9
+ const full = path.join(root, entry.name);
10
+ if (entry.isDirectory()) total += await directorySize(full);
11
+ else if (entry.isFile()) total += (await stat(full)).size;
12
+ }
13
+ return total;
14
+ }
15
+
16
+ export async function pruneLocalWorkspaces({
17
+ maxTmpGb = 1,
18
+ tmpDir = os.tmpdir(),
19
+ prefix = "agentsam-",
20
+ dryRun = false,
21
+ detailLimit = 100,
22
+ } = {}) {
23
+ const maxBytes = Math.max(0, Number(maxTmpGb)) * 1024 * 1024 * 1024;
24
+ const entries = await readdir(tmpDir, { withFileTypes: true });
25
+ const targets = [];
26
+
27
+ for (const entry of entries) {
28
+ if (!entry.isDirectory() || !entry.name.startsWith(prefix)) continue;
29
+ const fullPath = path.join(tmpDir, entry.name);
30
+ const info = await stat(fullPath);
31
+ const byteSize = await directorySize(fullPath);
32
+ targets.push({ path: fullPath, mtime: info.mtimeMs, byteSize });
33
+ }
34
+
35
+ targets.sort((a, b) => a.mtime - b.mtime);
36
+ let remainingBytes = targets.reduce((sum, target) => sum + target.byteSize, 0);
37
+ const purged = [];
38
+
39
+ for (const target of targets) {
40
+ if (remainingBytes <= maxBytes) break;
41
+ if (!dryRun) {
42
+ await rm(target.path, { recursive: true, force: true });
43
+ }
44
+ remainingBytes -= target.byteSize;
45
+ purged.push(target);
46
+ }
47
+
48
+ const boundedDetailLimit = Math.max(0, Math.min(1000, Number(detailLimit) || 0));
49
+ const purgeDetails = purged
50
+ .slice(0, boundedDetailLimit)
51
+ .map((item) => Object.freeze({ ...item }));
52
+
53
+ return Object.freeze({
54
+ maxBytes,
55
+ scannedCount: targets.length,
56
+ purgedCount: purged.length,
57
+ purgedBytes: purged.reduce((sum, item) => sum + item.byteSize, 0),
58
+ remainingBytes: Math.max(0, remainingBytes),
59
+ dryRun,
60
+ purged: Object.freeze(purgeDetails),
61
+ purgedDetailLimit: boundedDetailLimit,
62
+ purgedDetailsTruncated: purged.length > purgeDetails.length,
63
+ });
64
+ }