@inneranimalmedia/agentsam-sdk 2.6.9 → 2.6.10

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 (176) hide show
  1. package/README.md +18 -0
  2. package/apps/cad-creator/shared/cad/package.json +1 -1
  3. package/apps/client-cms-editor/backend/package.json +3 -3
  4. package/apps/client-cms-editor/frontend/package.json +4 -4
  5. package/apps/client-cms-editor/package-lock.json +8 -8
  6. package/apps/client-cms-editor/package.json +1 -1
  7. package/apps/client-cms-editor/shared/cms/package.json +2 -2
  8. package/docs/architecture/HOOKS-MODELS-SELF-HOSTING-PLAN.md +199 -0
  9. package/examples/hyperspace-demo/index.html +16 -0
  10. package/examples/hyperspace-demo/package.json +21 -0
  11. package/examples/hyperspace-demo/src/main.tsx +160 -0
  12. package/examples/hyperspace-demo/tsconfig.json +9 -0
  13. package/examples/hyperspace-demo/vite.config.ts +24 -0
  14. package/migrations/runtime/0005_agentsam_hooks.sql +87 -0
  15. package/package.json +23 -7
  16. package/packages/agentsam-brand/package.json +1 -1
  17. package/packages/agentsam-brand/src/core/v2/compile.js +1 -1
  18. package/packages/agentsam-brand/src/core/v2/schema.js +1 -1
  19. package/packages/agentsam-contracts/package.json +1 -1
  20. package/packages/agentsam-contracts/src/errors.ts +19 -10
  21. package/packages/agentsam-errors/package.json +11 -3
  22. package/packages/agentsam-errors/protocol/agentsam.error.v2.schema.json +821 -0
  23. package/packages/agentsam-errors/protocol/error-catalog.json +3512 -0
  24. package/packages/agentsam-errors/src/envelope.js +63 -11
  25. package/packages/agentsam-errors/src/error.js +6 -0
  26. package/packages/agentsam-errors/src/fingerprint.js +9 -1
  27. package/packages/agentsam-errors/src/normalize.js +51 -6
  28. package/packages/agentsam-errors/src/recovery.js +9 -35
  29. package/packages/agentsam-errors/src/transport.js +6 -1
  30. package/packages/agentsam-errors/src/vocabulary.js +515 -126
  31. package/packages/agentsam-errors/test/catalog-v2.test.mjs +106 -0
  32. package/packages/agentsam-errors/types/index.d.ts +157 -0
  33. package/packages/agentsam-goap/package.json +2 -2
  34. package/packages/agentsam-hooks/README.md +206 -0
  35. package/packages/agentsam-hooks/bin/agentsam-hooks.mjs +64 -0
  36. package/packages/agentsam-hooks/bindings/go/command.go +55 -0
  37. package/packages/agentsam-hooks/bindings/go/errors_generated.go +402 -0
  38. package/packages/agentsam-hooks/bindings/go/go.mod +3 -0
  39. package/packages/agentsam-hooks/bindings/go/hooks.go +285 -0
  40. package/packages/agentsam-hooks/bindings/go/hooks_test.go +48 -0
  41. package/packages/agentsam-hooks/bindings/rust/Cargo.toml +11 -0
  42. package/packages/agentsam-hooks/bindings/rust/src/errors_generated.rs +396 -0
  43. package/packages/agentsam-hooks/bindings/rust/src/lib.rs +397 -0
  44. package/packages/agentsam-hooks/package.json +69 -0
  45. package/packages/agentsam-hooks/schema/manifest.json +54 -0
  46. package/packages/agentsam-hooks/scripts/clean-protocol.mjs +17 -0
  47. package/packages/agentsam-hooks/scripts/sync-protocol.mjs +27 -0
  48. package/packages/agentsam-hooks/src/adapters/agents.js +82 -0
  49. package/packages/agentsam-hooks/src/adapters/callback.js +4 -0
  50. package/packages/agentsam-hooks/src/adapters/capability.js +122 -0
  51. package/packages/agentsam-hooks/src/adapters/command.js +104 -0
  52. package/packages/agentsam-hooks/src/adapters/composite.js +31 -0
  53. package/packages/agentsam-hooks/src/adapters/http.js +58 -0
  54. package/packages/agentsam-hooks/src/adapters/lsp.js +116 -0
  55. package/packages/agentsam-hooks/src/adapters/mcp.js +76 -0
  56. package/packages/agentsam-hooks/src/adapters/provider.js +129 -0
  57. package/packages/agentsam-hooks/src/config.js +143 -0
  58. package/packages/agentsam-hooks/src/contracts.js +284 -0
  59. package/packages/agentsam-hooks/src/errors-generated.js +2732 -0
  60. package/packages/agentsam-hooks/src/index.d.ts +193 -0
  61. package/packages/agentsam-hooks/src/index.js +14 -0
  62. package/packages/agentsam-hooks/src/policy.js +34 -0
  63. package/packages/agentsam-hooks/src/runtime.js +312 -0
  64. package/packages/agentsam-hooks/src/store.js +264 -0
  65. package/packages/agentsam-hooks/test/adapters.test.mjs +216 -0
  66. package/packages/agentsam-hooks/test/runtime.test.mjs +258 -0
  67. package/packages/agentsam-knowledge/package.json +1 -1
  68. package/packages/agentsam-nav/dist/Nav.d.ts +43 -0
  69. package/packages/agentsam-nav/dist/NavCollapsible.d.ts +10 -0
  70. package/packages/agentsam-nav/dist/NavContent.d.ts +2 -0
  71. package/packages/agentsam-nav/dist/NavFooter.d.ts +2 -0
  72. package/packages/agentsam-nav/dist/NavGroup.d.ts +3 -0
  73. package/packages/agentsam-nav/dist/NavHeader.d.ts +2 -0
  74. package/packages/agentsam-nav/dist/NavMenu.d.ts +22 -0
  75. package/packages/agentsam-nav/dist/NavProvider.d.ts +35 -0
  76. package/packages/agentsam-nav/dist/NavTrigger.d.ts +2 -0
  77. package/packages/agentsam-nav/dist/Surfaces.d.ts +41 -0
  78. package/packages/agentsam-nav/dist/browser.d.ts +11 -0
  79. package/packages/agentsam-nav/dist/browser.global.js +135 -0
  80. package/packages/agentsam-nav/dist/browser.js +7290 -0
  81. package/packages/agentsam-nav/dist/contracts.d.ts +76 -0
  82. package/packages/agentsam-nav/dist/index.d.ts +11 -0
  83. package/packages/agentsam-nav/dist/index.js +7291 -0
  84. package/packages/agentsam-nav/dist/legacy.css +83 -0
  85. package/packages/agentsam-nav/dist/shell.css +113 -0
  86. package/packages/agentsam-nav/dist/theme.css +113 -0
  87. package/packages/agentsam-nav/dist/utils.d.ts +1 -0
  88. package/packages/agentsam-nav/package.json +1 -1
  89. package/packages/agentsam-queue-control/package.json +1 -1
  90. package/packages/agentsam-repository/package.json +1 -1
  91. package/packages/agentsam-repository/src/goap.js.bak-20260922011251 +670 -0
  92. package/packages/agentsam-vault/package.json +1 -1
  93. package/packages/agentsam-workbench/package.json +3 -3
  94. package/packages/connectors/cloudflare/package.json +1 -1
  95. package/packages/heuristic-theme/package.json +1 -1
  96. package/packages/identity/package.json +2 -2
  97. package/packages/providers/completeful/package.json +1 -1
  98. package/packages/theme-church-site/package.json +2 -2
  99. package/packages/theme-companions-site/package.json +2 -2
  100. package/packages/theme-floors-site/package.json +2 -2
  101. package/packages/theme-fuelnfree-site/package.json +2 -2
  102. package/packages/theme-handyman-site/package.json +2 -2
  103. package/packages/theme-insurance-site/package.json +2 -2
  104. package/packages/theme-scenes/package.json +1 -1
  105. package/packages/theme-shinshu-site/package.json +2 -2
  106. package/packages/work-graph/package.json +1 -1
  107. package/protocol/apps/agentsam.app.v1.schema.json +1 -1
  108. package/protocol/apps/agentsam.host-install.v1.schema.json +1 -1
  109. package/protocol/assets/asset-record.v1.schema.json +1 -1
  110. package/protocol/brand/brandpack.v1.schema.json +1 -1
  111. package/protocol/capabilities/capability-manifest.schema.json +1 -1
  112. package/protocol/capabilities/knowledge-search-input.schema.json +1 -0
  113. package/protocol/credentials/issue.v1.schema.json +1 -1
  114. package/protocol/database/agentsam.schema-pack.v1.schema.json +1 -1
  115. package/protocol/database/connection.v1.schema.json +1 -1
  116. package/protocol/embeddings/embedding-profile.v1.schema.json +1 -1
  117. package/protocol/errors/README.md +36 -0
  118. package/protocol/errors/agentsam.error.v2.schema.json +821 -0
  119. package/protocol/errors/error-catalog.json +3506 -158
  120. package/protocol/errors/error-envelope.schema.json +195 -52
  121. package/protocol/errors/recovery.v1.schema.json +1 -1
  122. package/protocol/features/agentsam.feature.v1.schema.json +1 -1
  123. package/protocol/hooks/README.md +18 -0
  124. package/protocol/hooks/agentsam.hook.output.v1.schema.json +27 -0
  125. package/protocol/hooks/agentsam.hook.receipt.v1.schema.json +61 -0
  126. package/protocol/hooks/agentsam.hook.v1.schema.json +35 -0
  127. package/protocol/hooks/agentsam.hooks.config.v1.schema.json +78 -0
  128. package/protocol/local-engine/benchmark.v1.schema.json +1 -1
  129. package/protocol/local-engine/engine.v1.schema.json +1 -1
  130. package/protocol/models/model-inventory-v2.schema.json +1 -1
  131. package/protocol/models/provider-model-snapshot.v1.schema.json +22 -0
  132. package/protocol/rpc/v1/errors.proto +1 -0
  133. package/protocol/runtime/agentsam.runtime.v1.schema.json +1 -1
  134. package/protocol/runtime/workspace-fs.v1.schema.json +1 -1
  135. package/protocol/sam/activity.v1.schema.json +1 -1
  136. package/protocol/sam/answer.v1.schema.json +1 -1
  137. package/protocol/sam/calibration.v1.schema.json +1 -1
  138. package/protocol/sam/decision-receipt.v1.schema.json +1 -1
  139. package/protocol/sam/evaluation.v1.schema.json +1 -1
  140. package/protocol/sam/operation.schema.json +1 -1
  141. package/protocol/sam/outcome.v1.schema.json +1 -1
  142. package/protocol/sam/question.v1.schema.json +1 -1
  143. package/protocol/sam/result.schema.json +1 -1
  144. package/protocol/sam/state.v1.schema.json +1 -1
  145. package/protocol/scoring/scorecard.v1.schema.json +1 -1
  146. package/protocol/skills/agentsam.interaction.v1.schema.json +1 -1
  147. package/protocol/skills/agentsam.skill.v1.schema.json +1 -1
  148. package/protocol/theme-refinery/product-metadata.schema.json +1 -1
  149. package/protocol/theme-refinery/reconciliation-receipt.schema.json +1 -1
  150. package/protocol/ui/icon.v1.schema.json +1 -1
  151. package/python/README.md +20 -0
  152. package/python/agentsam_sdk/errors/__init__.py +4 -0
  153. package/python/agentsam_sdk/errors/vocabulary.py +2730 -0
  154. package/python/agentsam_sdk/hooks/__init__.py +32 -0
  155. package/python/agentsam_sdk/hooks/adapters.py +132 -0
  156. package/python/agentsam_sdk/hooks/contracts.py +121 -0
  157. package/python/agentsam_sdk/hooks/runtime.py +253 -0
  158. package/python/tests/test_hooks.py +115 -0
  159. package/src/agent/responses-runner.js +145 -1
  160. package/src/cli/command-catalog.js +1 -0
  161. package/src/cli.js +9 -0
  162. package/src/commands/cheat-sheet.js +1 -0
  163. package/src/commands/hooks.js +260 -0
  164. package/src/commands/models.js +1 -1
  165. package/src/commands/shell.js +114 -9
  166. package/src/errors/diagnostic.js +9 -9
  167. package/src/index.js +32 -0
  168. package/src/knowledge/service/grpc-codec.js +2 -0
  169. package/src/lib/slash-commands.js +1 -0
  170. package/src/local/runtime-store.js +46 -0
  171. package/src/models/catalog.js +0 -49
  172. package/src/models/inventory-core.js +69 -0
  173. package/src/plugins/index.js +8 -1
  174. package/src/plugins/registry.js +56 -0
  175. package/src/rpc/generated/errors_pb.js +49 -1
  176. package/src/tools/runtime.js +13 -5
package/README.md CHANGED
@@ -95,6 +95,23 @@ Portal-hosted OAuth (Cloudflare’s own consent on `*.mcp.cloudflare.com`) is se
95
95
  from AgentSam’s CF connection token. Keep tokens in each client’s credential store;
96
96
  do not commit them.
97
97
 
98
+ ## Lifecycle hooks and portable agent adapters
99
+
100
+ `@inneranimalmedia/agentsam-hooks` and the SDK `/hooks` export provide a
101
+ provider-neutral `agentsam.hook.v1` lifecycle boundary. In-process JavaScript and
102
+ TypeScript callbacks use the same JSON envelope as Python, Go, Rust, command, and
103
+ HTTP hooks. Pre-tool/model policy fails closed by default; observational hooks
104
+ fail open with bounded, value-free receipts.
105
+
106
+ The package also supplies composable host ports for model providers, capabilities,
107
+ MCP tools, LSP requests, and bounded sub-agent delegation. `runAgentSamTurn({ hooks })`
108
+ instruments the existing autonomous tool loop directly, including capped
109
+ `agent_stop` continuation. No hook config depends on a particular username, home
110
+ directory plugin, model vendor, or operator account. `agentsam hooks status|list|executions`
111
+ shows code, project-config, and stored hooks through one ordered contract. The optional
112
+ schema pack uses opaque owner/scope keys rather than tenant/workspace dependencies. See
113
+ [`packages/agentsam-hooks/README.md`](packages/agentsam-hooks/README.md).
114
+
98
115
  ## Index an existing repository
99
116
 
100
117
  ```sh
@@ -161,6 +178,7 @@ read-only `repository.snapshot` composition primitive. See [Capabilities and pre
161
178
  | --- | --- | --- |
162
179
  | Capability registry + presets | `agentsam capabilities`, `/capabilities`, `/presets` | [Capabilities](docs/CAPABILITIES.md) |
163
180
  | Portable AgentSam skills | `agentsam skills`; `/skills` | [Skills](skills/README.md) |
181
+ | Lifecycle hooks + MCP/LSP/sub-agent adapters | `/hooks`; `agentsam-hooks` | [AgentSam Hooks](packages/agentsam-hooks/README.md) |
164
182
  | Canonical repository snapshot | `agentsam inspect --json`; `/repository` | [Capabilities](docs/CAPABILITIES.md) |
165
183
  | Git context and bridge client | `agentsam context --json`; `/git-context`, `/bridge-client` | [Portable context](docs/PORTABLE_CONTEXT.md) |
166
184
  | Identity contracts and adapters | `/identity`; `agentsam identity init` | [Identity](packages/identity/README.md) |
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inneranimalmedia/agentsam-cad-shared",
3
- "version": "2.6.9",
3
+ "version": "2.6.10",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@inneranimalmedia/agentsam-cms-backend",
3
- "version": "2.6.9",
4
- "description": "Internal CMS backend bridge (bundled into @inneranimalmedia/client-cms-editor \u2014 not published separately).",
3
+ "version": "2.6.10",
4
+ "description": "Internal CMS backend bridge (bundled into @inneranimalmedia/client-cms-editor — not published separately).",
5
5
  "type": "module",
6
6
  "exports": {
7
7
  ".": "./src/index.ts",
@@ -14,7 +14,7 @@
14
14
  "typecheck": "tsc --noEmit -p tsconfig.json"
15
15
  },
16
16
  "dependencies": {
17
- "@inneranimalmedia/agentsam-cms-shared": "2.6.9"
17
+ "@inneranimalmedia/agentsam-cms-shared": "2.6.10"
18
18
  },
19
19
  "devDependencies": {
20
20
  "typescript": "^5.9.3"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@inneranimalmedia/agentsam-cms-frontend",
3
- "version": "2.6.9",
4
- "description": "Internal CMS frontend (bundled into @inneranimalmedia/client-cms-editor \u2014 not published separately).",
3
+ "version": "2.6.10",
4
+ "description": "Internal CMS frontend (bundled into @inneranimalmedia/client-cms-editor — not published separately).",
5
5
  "type": "module",
6
6
  "exports": {
7
7
  ".": "./src/index.ts",
@@ -15,8 +15,8 @@
15
15
  "test": "vitest run --passWithNoTests"
16
16
  },
17
17
  "dependencies": {
18
- "@inneranimalmedia/agentsam-cms-backend": "2.6.9",
19
- "@inneranimalmedia/agentsam-cms-shared": "2.6.9",
18
+ "@inneranimalmedia/agentsam-cms-backend": "2.6.10",
19
+ "@inneranimalmedia/agentsam-cms-shared": "2.6.10",
20
20
  "react": "^19.2.0",
21
21
  "react-dom": "^19.2.0"
22
22
  },
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@inneranimalmedia/client-cms-editor",
3
- "version": "0.1.0-alpha.0",
3
+ "version": "2.6.10",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@inneranimalmedia/client-cms-editor",
9
- "version": "0.1.0-alpha.0",
9
+ "version": "2.6.10",
10
10
  "license": "UNLICENSED",
11
11
  "workspaces": [
12
12
  "frontend",
@@ -37,9 +37,9 @@
37
37
  },
38
38
  "backend": {
39
39
  "name": "@inneranimalmedia/agentsam-cms-backend",
40
- "version": "0.1.0-alpha.0",
40
+ "version": "2.6.10",
41
41
  "dependencies": {
42
- "@inneranimalmedia/agentsam-cms-shared": "0.1.0-alpha.0"
42
+ "@inneranimalmedia/agentsam-cms-shared": "2.6.10"
43
43
  },
44
44
  "devDependencies": {
45
45
  "typescript": "^5.9.3"
@@ -47,10 +47,10 @@
47
47
  },
48
48
  "frontend": {
49
49
  "name": "@inneranimalmedia/agentsam-cms-frontend",
50
- "version": "0.1.0-alpha.0",
50
+ "version": "2.6.10",
51
51
  "dependencies": {
52
- "@inneranimalmedia/agentsam-cms-backend": "0.1.0-alpha.0",
53
- "@inneranimalmedia/agentsam-cms-shared": "0.1.0-alpha.0",
52
+ "@inneranimalmedia/agentsam-cms-backend": "2.6.10",
53
+ "@inneranimalmedia/agentsam-cms-shared": "2.6.10",
54
54
  "react": "^19.2.0",
55
55
  "react-dom": "^19.2.0"
56
56
  },
@@ -4662,7 +4662,7 @@
4662
4662
  },
4663
4663
  "shared/cms": {
4664
4664
  "name": "@inneranimalmedia/agentsam-cms-shared",
4665
- "version": "0.1.0-alpha.0",
4665
+ "version": "2.6.10",
4666
4666
  "devDependencies": {
4667
4667
  "typescript": "^5.9.3"
4668
4668
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inneranimalmedia/client-cms-editor",
3
- "version": "2.6.9",
3
+ "version": "2.6.10",
4
4
  "private": false,
5
5
  "description": "Reusable full-stack website + CMS kit with multi-page public sites, a protected authoring dashboard, local SQLite, starter/theme import, and pluggable auth, storage, and deployment adapters.",
6
6
  "type": "module",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@inneranimalmedia/agentsam-cms-shared",
3
- "version": "2.6.9",
4
- "description": "Internal CMS shared contracts (bundled into @inneranimalmedia/client-cms-editor \u2014 not published separately).",
3
+ "version": "2.6.10",
4
+ "description": "Internal CMS shared contracts (bundled into @inneranimalmedia/client-cms-editor — not published separately).",
5
5
  "type": "module",
6
6
  "exports": {
7
7
  ".": "./src/index.ts",
@@ -0,0 +1,199 @@
1
+ # Hooks, model inventory, and self-hosting plan
2
+
3
+ Status: active implementation plan (2026-10-02)
4
+
5
+ ## Decisions
6
+
7
+ ### Hooks are one runtime concept
8
+
9
+ AgentSam has one lifecycle event catalog, one output merge algorithm, and one
10
+ receipt format. It has multiple **authoring sources**, not multiple kinds of
11
+ hook:
12
+
13
+ | Source | Authored in | Dashboard/CLI behavior | Durable definition row |
14
+ |---|---|---|---|
15
+ | `code` | SDK registration | visible, read-only | no |
16
+ | `config` | `agentsam.hooks.json` or `.agentsam/hooks.json` | visible, file-owned | no |
17
+ | `stored` | CLI/API/dashboard | visible and mutable | `agentsam_hook` |
18
+ | `system` | AgentSam runtime | visible, read-only | only when a host intentionally materializes it |
19
+
20
+ React hooks (`useAgentHooks`, `useHookList`) are UI implementation details and
21
+ must never be called lifecycle hooks in product copy.
22
+
23
+ Dispatch order is priority, then hook key. Source does not create a second
24
+ semantics path. A source badge answers where to edit a definition. Execution
25
+ receipts from all sources go to the same `agentsam_hook_execution` projection.
26
+
27
+ ### Portable ownership is owner + optional scope
28
+
29
+ The portable hook schema deliberately has no `tenant_id`, `workspace_id`,
30
+ `user_id`, `person_uuid`, or installation-specific foreign keys.
31
+
32
+ - `owner_id` is an opaque host/account/local owner key.
33
+ - `scope_type` is `global`, `account`, `repository`, `project`, or `session`.
34
+ - `scope_ref` contains the corresponding opaque id/path when needed.
35
+ - `agent_run_id`, `session_id`, and `conversation_id` are the common execution
36
+ correlations.
37
+ - Rare correlations (plan, todo, workflow run, command run, route) belong in
38
+ `correlation_json`, not a permanently sparse column set.
39
+ - `workflow_id` is a soft reference on the definition. The hook pack remains
40
+ installable without a workflow table family.
41
+ - Handler credentials are references resolved by the host. They are never
42
+ values in `handler_config_json`.
43
+
44
+ The canonical fresh-install SQL is
45
+ `migrations/runtime/0005_agentsam_hooks.sql`. The standalone hooks package
46
+ ships a generated byte-identical copy plus `schema/manifest.json`.
47
+
48
+ Existing hosted tables with required `user_id` or tenant/workspace columns are
49
+ **not** silently rebuilt. The hosted owner must inspect references and run an
50
+ explicit copy/verify/swap migration. Portable initialization is idempotent and
51
+ will not guess that `user_id` equals an account owner.
52
+
53
+ ### The existing model surfaces keep their jobs
54
+
55
+ No new per-model-per-user table is introduced.
56
+
57
+ | Existing surface | Authority |
58
+ |---|---|
59
+ | `src/models/catalog.js` / hosted `agentsam_model_catalog` | curated provider-qualified reference capabilities; never credential availability |
60
+ | `agentsam_model_pricing` | global/versioned reference pricing |
61
+ | `agentsam_plugins` with `plugin_kind='ai'` | one installation per account/environment/provider/credential reference; health and last good credential-scoped model snapshot |
62
+ | `user_secrets` / machine vault | provider secret material; never model metadata |
63
+ | `agentsam_api_credentials` | authentication to AgentSam itself; never provider keys |
64
+ | `agentsam_model_eval_observations` | eval evidence; not a portable customer model catalog |
65
+
66
+ A successful provider probe writes a compact
67
+ `agentsam.provider-model-snapshot.v1` object into the AI plugin row's
68
+ `metadata_json.model_snapshot`. It contains sorted model ids, count, hash, and
69
+ fetch time. `recordAiPluginModelDiscovery` writes it through the existing
70
+ plugin registry and health-check log. A failed probe updates health evidence
71
+ but preserves the last good snapshot. Secret values and hashes of secret values
72
+ are never included.
73
+
74
+ The provider API remains the availability authority at use time. A snapshot is
75
+ stale-while-revalidate evidence for UI convenience, not an authorization gate.
76
+ Reference catalog enrichment is never an availability claim. Unknown models
77
+ continue to work with unknown/reference capabilities where the adapter can use
78
+ them.
79
+
80
+ Provider/model identity is the pair `(provider, provider_model_id)`. The SDK's
81
+ `model_key` already encodes that pair (`openai:gpt-…`, `cursor:…`). Hosted SQL
82
+ must use `UNIQUE(provider, model_key)` (or a provider-qualified `model_key`),
83
+ not global `UNIQUE(model_key)`. Provider ids should match SDK canonical ids:
84
+ `openai`, `anthropic`, `gemini`, `xai`, `cursor`, `cloudflare`, and `ollama`.
85
+ Display names are not ids.
86
+
87
+ ## Product and CLI experience
88
+
89
+ `agentsam hooks` and `/hooks` are the factual control surface:
90
+
91
+ - `status` — source counts, project config, and stored registry health.
92
+ - `list` — merged dispatch order with source, handler, state, and priority.
93
+ - `executions` — recent value-free receipts and redacted failures.
94
+ - `validate` — portable config validation.
95
+ - `init` — idempotently creates `.agentsam/hooks.json`.
96
+ - `enable` / `disable` — toggles stored definitions only.
97
+
98
+ The dashboard should consume the same status/list/execution projection. It must
99
+ not maintain a second event list or merge algorithm. Code rows are read-only;
100
+ config rows link to their source file; stored rows expose full editing. A future
101
+ priority/disable override for code hooks must be an explicit overlay keyed by
102
+ `(owner_id, source_kind, hook_key)`, not a copied code definition.
103
+
104
+ The model picker follows a similar provenance rule:
105
+
106
+ 1. show models discovered for the selected plugin/credential installation;
107
+ 2. enrich from the global catalog when a provider-qualified match exists;
108
+ 3. label every limit/capability as provider, reference, or unknown;
109
+ 4. keep pinned/default visibility in the AI plugin's `config_json`;
110
+ 5. never write discovered ids into the global catalog.
111
+
112
+ ## Dogfooding matrix
113
+
114
+ | Runtime point | Hook event | Current owner |
115
+ |---|---|---|
116
+ | interactive shell open/close | `session_start`, `session_end` | CLI shell |
117
+ | submitted/transformed input | `user_prompt_submitted`, `user_prompt_transformed` | provider-neutral runner |
118
+ | paid inference boundaries | `pre_model_use`, `post_model_use` | provider adapter |
119
+ | capability side effects | `pre_tool_use`, `post_tool_use`, `post_tool_use_failure` | capability adapter |
120
+ | provider/tool failures | `error_occurred` | provider/capability adapters |
121
+ | autonomous continuation | `agent_stop` | runner with bounded continuation count |
122
+ | delegated work | `subagent_start`, `subagent_stop` | delegated-agent adapter |
123
+
124
+ The interactive CLI loads code, project config, and active stored hooks into the
125
+ same runtime. `session_start.modified_config` may override the session's model,
126
+ reasoning, service tier, and compaction preference; arbitrary process or path
127
+ configuration is not applied. Session context is injected through normal
128
+ context items. Every invocation uses the same receipt observer and local
129
+ execution table.
130
+
131
+ `session_end` remains best effort. Handlers must be idempotent, and durable
132
+ cleanup must eventually be backed by an idle-session sweeper rather than an
133
+ assumption that a process always exits normally.
134
+
135
+ ## Delivery sequence
136
+
137
+ ### Phase 1 — portable core (implemented in this change)
138
+
139
+ - Canonical portable hook tables and schema-pack manifest.
140
+ - Generic injected-SQL hook store for SQLite/D1-shaped adapters.
141
+ - Stored/config/code source merging.
142
+ - CLI `/hooks` discovery and value-free execution history.
143
+ - Actual shell/runner dogfooding, including session and transformed-prompt
144
+ events.
145
+ - Compact AI plugin model snapshot contract and existing-plugin persistence API with last-good preservation.
146
+
147
+ ### Phase 2 — hosted compatibility migration
148
+
149
+ 1. Inventory every FK/view/query referencing hosted `agentsam_hook` and
150
+ `agentsam_hook_execution`.
151
+ 2. Create `_v2` tables from the portable columns plus host-required indexes.
152
+ 3. Map `owner_id` from the hosted account authority; do not infer it from a
153
+ tenant/workspace label.
154
+ 4. Move legacy handler fields into `handler_config_json` and legacy correlation
155
+ fields into `correlation_json`.
156
+ 5. Validate row counts, active definitions, orphan references, JSON validity,
157
+ and sampled execution history.
158
+ 6. Swap in one transaction where supported; retain a rollback table until
159
+ production verification completes.
160
+ 7. Add the dashboard API only after ownership checks are enforced by the host.
161
+
162
+ ### Phase 3 — shared dashboard projection
163
+
164
+ - Expose merged definitions and receipts through an injected HookRegistry API.
165
+ - Add source badges, event filters, dry-run input, and last-failure state.
166
+ - Add stored-hook create/edit with handler-specific forms.
167
+ - Add explicit code-hook overrides without copying handler definitions.
168
+ - Reuse the protocol conformance fixtures in UI/API integration tests.
169
+
170
+ ### Phase 4 — model snapshot persistence
171
+
172
+ - Apply `createAiPluginProbePatch` in the hosted provider probe transaction.
173
+ - Compare `models_hash`; avoid writes when the snapshot is unchanged.
174
+ - Refresh stale snapshots in the background and through `agentsam models
175
+ --refresh` without blocking startup.
176
+ - Keep last good ids on auth/network failures and expose health separately.
177
+ - Add retention only to probe history, not the last good plugin snapshot.
178
+
179
+ ### Phase 5 — lifecycle reliability
180
+
181
+ - Add stale-session sweep and idempotent cleanup jobs.
182
+ - Add execution retention/compaction policy.
183
+ - Add local↔remote receipt sync by immutable execution id where explicitly
184
+ enabled; never sync secrets or full prompt/tool values.
185
+ - Run JSON conformance fixtures in JavaScript, Python, Go, and Rust CI.
186
+
187
+ ## Acceptance checks
188
+
189
+ - Fresh SQLite and D1-shaped installs produce the same hook tables.
190
+ - No portable hook query requires tenant/workspace/user tables.
191
+ - A prompt value or tool result value cannot be found in a hook receipt row.
192
+ - Config and stored hooks execute in one deterministic priority order.
193
+ - The CLI lists every active source that can affect a turn.
194
+ - A provider probe with 1,000 model ids produces one AI plugin metadata update,
195
+ not 1,000 catalog rows.
196
+ - Failed model refreshes preserve the last successful model id list.
197
+ - A catalog miss never blocks a provider-verified model solely because the
198
+ reference package is older.
199
+ - Provider and AgentSam credentials remain separate authorities.
@@ -0,0 +1,16 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
6
+ <title>AgentSam — Computational Hyperspace</title>
7
+ <style>
8
+ html, body, #root { margin: 0; height: 100%; background: #000; }
9
+ * { box-sizing: border-box; }
10
+ </style>
11
+ </head>
12
+ <body>
13
+ <div id="root"></div>
14
+ <script type="module" src="/src/main.tsx"></script>
15
+ </body>
16
+ </html>
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "hyperspace-demo",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build": "vite build"
9
+ },
10
+ "dependencies": {
11
+ "@inneranimalmedia/agentsam-loading-scene": "*",
12
+ "react": "^19.2.0",
13
+ "react-dom": "^19.2.0"
14
+ },
15
+ "devDependencies": {
16
+ "@types/react": "^19.2.0",
17
+ "@types/react-dom": "^19.2.0",
18
+ "@vitejs/plugin-react": "^5.2.0",
19
+ "vite": "^8.2.0"
20
+ }
21
+ }
@@ -0,0 +1,160 @@
1
+ import { StrictMode, useEffect, useMemo, useState } from "react";
2
+ import { createRoot } from "react-dom/client";
3
+ import {
4
+ LoadingSceneController,
5
+ computationalHyperspace,
6
+ adaptAgentSamEvent,
7
+ } from "@inneranimalmedia/agentsam-loading-scene";
8
+ import {
9
+ LoadingScene,
10
+ LoadingSceneStatus,
11
+ LoadingSceneDevtools,
12
+ } from "@inneranimalmedia/agentsam-loading-scene/react";
13
+
14
+ const preset = computationalHyperspace;
15
+
16
+ /**
17
+ * Simulated "create a site" run: realistic runtime events flow through
18
+ * the adapter → controller, exactly as a real CMS app would wire it.
19
+ * The renderer never sees any of these names.
20
+ */
21
+ function simulateSiteCreation(controller: LoadingSceneController, onDone: () => void) {
22
+ const timeline: Array<[number, () => void]> = [];
23
+ const at = (ms: number, fn: () => void) => timeline.push([ms, fn]);
24
+ const ev = (raw: Parameters<typeof adaptAgentSamEvent>[0]) =>
25
+ controller.handle(adaptAgentSamEvent(raw));
26
+
27
+ at(0, () => ev({ type: "agent.session.started", operationId: "session", label: "Starting up" }));
28
+ at(900, () => controller.complete("session"));
29
+
30
+ at(1000, () => ev({ type: "context.workspace.loading", operationId: "ctx", label: "Gathering context" }));
31
+ // 19 rapid file reads — coalesced, no flicker
32
+ for (let i = 0; i < 19; i++) {
33
+ at(1200 + i * 60, () => ev({ type: "file.read", label: "Understanding your project" }));
34
+ }
35
+ at(2600, () => controller.complete("ctx"));
36
+
37
+ at(2700, () => ev({ type: "model.planning", operationId: "plan", label: "Planning your site" }));
38
+ at(5200, () => controller.complete("plan"));
39
+
40
+ // parallel tools + asset generation blending
41
+ at(5300, () => ev({ type: "tool.invoke", operationId: "t1", label: "Laying out pages" }));
42
+ at(5450, () => ev({ type: "tool.invoke", operationId: "t2", label: "Writing copy" }));
43
+ at(5600, () => ev({ type: "tool.image.generate", operationId: "hero", label: "Generating hero artwork" }));
44
+ at(9400, () => controller.complete("t1"));
45
+ at(10200, () => controller.complete("t2"));
46
+ at(12500, () => ev({ type: "content.asset.generated", operationId: "hero", label: "Hero artwork ready" }));
47
+
48
+ at(12800, () => ev({ type: "catalog.indexing", operationId: "idx", label: "Organizing your content" }));
49
+ at(15200, () => controller.complete("idx"));
50
+
51
+ at(15400, () => ev({ type: "site.build", operationId: "build", label: "Building your site", progress: 0 }));
52
+ at(16500, () => ev({ type: "site.build", operationId: "build", progress: 0.35 }));
53
+ at(17800, () => ev({ type: "site.build", operationId: "build", progress: 0.8 }));
54
+ at(18900, () => controller.complete("build"));
55
+
56
+ at(19000, () => ev({ type: "output.verify", operationId: "verify", label: "Checking everything" }));
57
+ at(21500, () => controller.complete("verify"));
58
+
59
+ at(21700, () => ev({ type: "site.deploy", operationId: "deploy", label: "Publishing" }));
60
+ at(24800, () => {
61
+ controller.complete("deploy");
62
+ onDone();
63
+ });
64
+
65
+ const ids = timeline.map(([ms, fn]) => window.setTimeout(fn, ms));
66
+ return () => ids.forEach((id) => window.clearTimeout(id));
67
+ }
68
+
69
+ function EditorSurface() {
70
+ return (
71
+ <div
72
+ style={{
73
+ height: "100%",
74
+ display: "grid",
75
+ gridTemplateRows: "56px 1fr",
76
+ color: "#d5d7e0",
77
+ fontFamily: "system-ui, sans-serif",
78
+ }}
79
+ >
80
+ <header
81
+ style={{
82
+ borderBottom: "1px solid rgba(255,255,255,0.08)",
83
+ display: "flex",
84
+ alignItems: "center",
85
+ padding: "0 20px",
86
+ gap: 16,
87
+ fontSize: 13,
88
+ letterSpacing: "0.06em",
89
+ }}
90
+ >
91
+ <strong style={{ color: "#8b7db7" }}>AgentSam</strong>
92
+ <span style={{ opacity: 0.5 }}>Fuel N Free Time — Home</span>
93
+ <span style={{ marginLeft: "auto", opacity: 0.4, fontSize: 12 }}>Draft saved</span>
94
+ </header>
95
+ <main style={{ padding: 32, display: "grid", gap: 20, alignContent: "start" }}>
96
+ <div style={{ height: 220, borderRadius: 10, background: "linear-gradient(135deg, rgba(139,125,183,0.18), rgba(104,117,173,0.1))", border: "1px solid rgba(255,255,255,0.07)", display: "flex", alignItems: "center", justifyContent: "center", fontSize: 14, opacity: 0.8 }}>
97
+ Hero section — generated artwork placed here
98
+ </div>
99
+ <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(180px, 1fr))", gap: 16 }}>
100
+ {["Collection grid", "Countdown banner", "Newsletter"].map((s) => (
101
+ <div key={s} style={{ height: 110, borderRadius: 8, border: "1px solid rgba(255,255,255,0.07)", background: "rgba(255,255,255,0.02)", display: "flex", alignItems: "center", justifyContent: "center", fontSize: 13, opacity: 0.65 }}>
102
+ {s}
103
+ </div>
104
+ ))}
105
+ </div>
106
+ </main>
107
+ </div>
108
+ );
109
+ }
110
+
111
+ function App() {
112
+ const controller = useMemo(() => new LoadingSceneController(preset), []);
113
+ const [run, setRun] = useState(0);
114
+ const debug = new URLSearchParams(window.location.search).get("debugRuntimeVisuals") === "1";
115
+
116
+ useEffect(() => {
117
+ if (debug) return; // devtools drive the controller instead
118
+ return simulateSiteCreation(controller, () => undefined);
119
+ }, [controller, run, debug]);
120
+
121
+ return (
122
+ <div style={{ position: "fixed", inset: 0 }}>
123
+ <LoadingScene controller={controller} preset={preset} style={{ width: "100%", height: "100%" }}>
124
+ <EditorSurface />
125
+ </LoadingScene>
126
+ <div style={{ position: "fixed", left: 24, bottom: 24, pointerEvents: "none" }}>
127
+ <LoadingSceneStatus controller={controller} preset={preset} />
128
+ </div>
129
+ {!debug && (
130
+ <button
131
+ onClick={() => {
132
+ controller.reset();
133
+ setRun((r) => r + 1);
134
+ }}
135
+ style={{
136
+ position: "fixed",
137
+ top: 16,
138
+ right: 16,
139
+ background: "rgba(255,255,255,0.05)",
140
+ border: "1px solid rgba(255,255,255,0.12)",
141
+ borderRadius: 6,
142
+ color: "#9ea1b0",
143
+ padding: "6px 12px",
144
+ fontSize: 12,
145
+ cursor: "pointer",
146
+ }}
147
+ >
148
+ Replay
149
+ </button>
150
+ )}
151
+ <LoadingSceneDevtools controller={controller} enabled={debug} />
152
+ </div>
153
+ );
154
+ }
155
+
156
+ createRoot(document.getElementById("root")!).render(
157
+ <StrictMode>
158
+ <App />
159
+ </StrictMode>,
160
+ );
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "noEmit": true,
5
+ "jsx": "react-jsx",
6
+ "lib": ["ES2022", "DOM", "DOM.Iterable"]
7
+ },
8
+ "include": ["src"]
9
+ }
@@ -0,0 +1,24 @@
1
+ import { defineConfig } from "vite";
2
+ import react from "@vitejs/plugin-react";
3
+ import path from "node:path";
4
+
5
+ export default defineConfig({
6
+ plugins: [react()],
7
+ server: {
8
+ host: "0.0.0.0",
9
+ port: 5181,
10
+ allowedHosts: true,
11
+ },
12
+ resolve: {
13
+ alias: {
14
+ "@inneranimalmedia/agentsam-loading-scene/react": path.resolve(
15
+ __dirname,
16
+ "../../packages/agentsam-loading-scene/src/react/index.ts",
17
+ ),
18
+ "@inneranimalmedia/agentsam-loading-scene": path.resolve(
19
+ __dirname,
20
+ "../../packages/agentsam-loading-scene/src/index.ts",
21
+ ),
22
+ },
23
+ },
24
+ });