@inneranimalmedia/agentsam-sdk 2.6.8 → 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 (203) hide show
  1. package/README.md +18 -0
  2. package/apps/README.md +25 -0
  3. package/apps/cad-creator/shared/cad/package.json +1 -1
  4. package/apps/client-cms-editor/backend/package.json +5 -7
  5. package/apps/client-cms-editor/frontend/package.json +5 -7
  6. package/apps/client-cms-editor/frontend/tsconfig.json +27 -8
  7. package/apps/client-cms-editor/package-lock.json +8 -8
  8. package/apps/client-cms-editor/package.json +1 -1
  9. package/apps/client-cms-editor/shared/cms/package.json +3 -5
  10. package/docs/LOCAL_ENGINE_COMPUTE_AUDIT_PLAN.md +299 -0
  11. package/docs/architecture/HOOKS-MODELS-SELF-HOSTING-PLAN.md +199 -0
  12. package/examples/hyperspace-demo/index.html +16 -0
  13. package/examples/hyperspace-demo/package.json +21 -0
  14. package/examples/hyperspace-demo/src/main.tsx +160 -0
  15. package/examples/hyperspace-demo/tsconfig.json +9 -0
  16. package/examples/hyperspace-demo/vite.config.ts +24 -0
  17. package/migrations/runtime/0005_agentsam_hooks.sql +87 -0
  18. package/package.json +37 -10
  19. package/packages/agentsam-brand/package.json +1 -1
  20. package/packages/agentsam-brand/src/core/v2/compile.js +1 -1
  21. package/packages/agentsam-brand/src/core/v2/schema.js +1 -1
  22. package/packages/agentsam-contracts/package.json +71 -20
  23. package/packages/agentsam-contracts/scripts/build.mjs +18 -0
  24. package/packages/agentsam-contracts/src/errors.ts +19 -10
  25. package/packages/agentsam-contracts/test/contracts.test.mjs +4 -1
  26. package/packages/agentsam-contracts/test/repository.test.mjs +4 -1
  27. package/packages/agentsam-contracts/tsconfig.build.json +10 -0
  28. package/packages/agentsam-errors/package.json +13 -4
  29. package/packages/agentsam-errors/protocol/agentsam.error.v2.schema.json +821 -0
  30. package/packages/agentsam-errors/protocol/error-catalog.json +3512 -0
  31. package/packages/agentsam-errors/src/envelope.js +63 -11
  32. package/packages/agentsam-errors/src/error.js +6 -0
  33. package/packages/agentsam-errors/src/fingerprint.js +9 -1
  34. package/packages/agentsam-errors/src/normalize.js +51 -6
  35. package/packages/agentsam-errors/src/recovery.js +9 -35
  36. package/packages/agentsam-errors/src/transport.js +6 -1
  37. package/packages/agentsam-errors/src/vocabulary.js +515 -126
  38. package/packages/agentsam-errors/test/catalog-v2.test.mjs +106 -0
  39. package/packages/agentsam-errors/types/index.d.ts +157 -0
  40. package/packages/agentsam-goap/package.json +2 -2
  41. package/packages/agentsam-hooks/README.md +206 -0
  42. package/packages/agentsam-hooks/bin/agentsam-hooks.mjs +64 -0
  43. package/packages/agentsam-hooks/bindings/go/command.go +55 -0
  44. package/packages/agentsam-hooks/bindings/go/errors_generated.go +402 -0
  45. package/packages/agentsam-hooks/bindings/go/go.mod +3 -0
  46. package/packages/agentsam-hooks/bindings/go/hooks.go +285 -0
  47. package/packages/agentsam-hooks/bindings/go/hooks_test.go +48 -0
  48. package/packages/agentsam-hooks/bindings/rust/Cargo.toml +11 -0
  49. package/packages/agentsam-hooks/bindings/rust/src/errors_generated.rs +396 -0
  50. package/packages/agentsam-hooks/bindings/rust/src/lib.rs +397 -0
  51. package/packages/agentsam-hooks/package.json +69 -0
  52. package/packages/agentsam-hooks/schema/manifest.json +54 -0
  53. package/packages/agentsam-hooks/scripts/clean-protocol.mjs +17 -0
  54. package/packages/agentsam-hooks/scripts/sync-protocol.mjs +27 -0
  55. package/packages/agentsam-hooks/src/adapters/agents.js +82 -0
  56. package/packages/agentsam-hooks/src/adapters/callback.js +4 -0
  57. package/packages/agentsam-hooks/src/adapters/capability.js +122 -0
  58. package/packages/agentsam-hooks/src/adapters/command.js +104 -0
  59. package/packages/agentsam-hooks/src/adapters/composite.js +31 -0
  60. package/packages/agentsam-hooks/src/adapters/http.js +58 -0
  61. package/packages/agentsam-hooks/src/adapters/lsp.js +116 -0
  62. package/packages/agentsam-hooks/src/adapters/mcp.js +76 -0
  63. package/packages/agentsam-hooks/src/adapters/provider.js +129 -0
  64. package/packages/agentsam-hooks/src/config.js +143 -0
  65. package/packages/agentsam-hooks/src/contracts.js +284 -0
  66. package/packages/agentsam-hooks/src/errors-generated.js +2732 -0
  67. package/packages/agentsam-hooks/src/index.d.ts +193 -0
  68. package/packages/agentsam-hooks/src/index.js +14 -0
  69. package/packages/agentsam-hooks/src/policy.js +34 -0
  70. package/packages/agentsam-hooks/src/runtime.js +312 -0
  71. package/packages/agentsam-hooks/src/store.js +264 -0
  72. package/packages/agentsam-hooks/test/adapters.test.mjs +216 -0
  73. package/packages/agentsam-hooks/test/runtime.test.mjs +258 -0
  74. package/packages/agentsam-knowledge/package.json +3 -2
  75. package/packages/agentsam-nav/package.json +1 -1
  76. package/packages/agentsam-queue-control/package.json +1 -1
  77. package/packages/agentsam-rapid-rust/src/main.rs +1 -0
  78. package/packages/agentsam-repository/package.json +3 -2
  79. package/packages/agentsam-vault/package.json +8 -5
  80. package/packages/agentsam-workbench/package.json +45 -18
  81. package/packages/connectors/cloudflare/package.json +1 -1
  82. package/packages/heuristic-theme/package.json +1 -1
  83. package/packages/identity/package.json +3 -2
  84. package/packages/identity/tests/lane1-packed-consumer.test.mjs +9 -1
  85. package/packages/providers/completeful/package.json +1 -1
  86. package/packages/theme-church-site/README.md +2 -2
  87. package/packages/theme-church-site/package.json +2 -3
  88. package/packages/theme-church-site/src/index.js +1 -1
  89. package/packages/theme-church-site/test/theme.test.mjs +1 -1
  90. package/packages/theme-companions-site/README.md +2 -2
  91. package/packages/theme-companions-site/package.json +2 -3
  92. package/packages/theme-companions-site/src/index.js +1 -1
  93. package/packages/theme-companions-site/test/theme.test.mjs +1 -1
  94. package/packages/theme-floors-site/README.md +2 -2
  95. package/packages/theme-floors-site/package.json +2 -3
  96. package/packages/theme-floors-site/src/index.js +1 -1
  97. package/packages/theme-floors-site/test/theme.test.mjs +1 -1
  98. package/packages/theme-fuelnfree-site/README.md +2 -2
  99. package/packages/theme-fuelnfree-site/package.json +2 -3
  100. package/packages/theme-fuelnfree-site/src/index.js +1 -1
  101. package/packages/theme-fuelnfree-site/test/theme.test.mjs +1 -1
  102. package/packages/theme-handyman-site/README.md +2 -2
  103. package/packages/theme-handyman-site/package.json +2 -3
  104. package/packages/theme-handyman-site/src/index.js +1 -1
  105. package/packages/theme-handyman-site/test/theme.test.mjs +1 -1
  106. package/packages/theme-insurance-site/README.md +2 -2
  107. package/packages/theme-insurance-site/package.json +2 -3
  108. package/packages/theme-insurance-site/src/index.js +1 -1
  109. package/packages/theme-insurance-site/test/theme.test.mjs +1 -1
  110. package/packages/theme-scenes/package.json +1 -1
  111. package/packages/theme-shinshu-site/README.md +2 -2
  112. package/packages/theme-shinshu-site/package.json +2 -3
  113. package/packages/theme-shinshu-site/src/index.js +1 -1
  114. package/packages/theme-shinshu-site/test/theme.test.mjs +1 -1
  115. package/packages/work-graph/package.json +3 -2
  116. package/protocol/apps/agentsam.app.v1.schema.json +1 -1
  117. package/protocol/apps/agentsam.host-install.v1.schema.json +1 -1
  118. package/protocol/assets/asset-record.v1.schema.json +1 -1
  119. package/protocol/brand/brandpack.v1.schema.json +1 -1
  120. package/protocol/capabilities/capability-manifest.schema.json +1 -1
  121. package/protocol/capabilities/knowledge-search-input.schema.json +1 -0
  122. package/protocol/credentials/issue.v1.schema.json +1 -1
  123. package/protocol/database/agentsam.schema-pack.v1.schema.json +1 -1
  124. package/protocol/database/connection.v1.schema.json +1 -1
  125. package/protocol/embeddings/embedding-profile.v1.schema.json +1 -1
  126. package/protocol/errors/README.md +36 -0
  127. package/protocol/errors/agentsam.error.v2.schema.json +821 -0
  128. package/protocol/errors/error-catalog.json +3506 -158
  129. package/protocol/errors/error-envelope.schema.json +195 -52
  130. package/protocol/errors/recovery.v1.schema.json +1 -1
  131. package/protocol/features/agentsam.feature.v1.schema.json +1 -1
  132. package/protocol/hooks/README.md +18 -0
  133. package/protocol/hooks/agentsam.hook.output.v1.schema.json +27 -0
  134. package/protocol/hooks/agentsam.hook.receipt.v1.schema.json +61 -0
  135. package/protocol/hooks/agentsam.hook.v1.schema.json +35 -0
  136. package/protocol/hooks/agentsam.hooks.config.v1.schema.json +78 -0
  137. package/protocol/local-engine/benchmark.v1.schema.json +14 -0
  138. package/protocol/local-engine/engine.v1.schema.json +17 -0
  139. package/protocol/models/model-inventory-v2.schema.json +1 -1
  140. package/protocol/models/provider-model-snapshot.v1.schema.json +22 -0
  141. package/protocol/rpc/v1/errors.proto +1 -0
  142. package/protocol/runtime/agentsam.runtime.v1.schema.json +1 -1
  143. package/protocol/runtime/workspace-fs.v1.schema.json +1 -1
  144. package/protocol/sam/activity.v1.schema.json +1 -1
  145. package/protocol/sam/answer.v1.schema.json +1 -1
  146. package/protocol/sam/calibration.v1.schema.json +1 -1
  147. package/protocol/sam/decision-receipt.v1.schema.json +1 -1
  148. package/protocol/sam/evaluation.v1.schema.json +1 -1
  149. package/protocol/sam/operation.schema.json +1 -1
  150. package/protocol/sam/outcome.v1.schema.json +1 -1
  151. package/protocol/sam/question.v1.schema.json +1 -1
  152. package/protocol/sam/result.schema.json +1 -1
  153. package/protocol/sam/state.v1.schema.json +1 -1
  154. package/protocol/scoring/scorecard.v1.schema.json +1 -1
  155. package/protocol/skills/agentsam.interaction.v1.schema.json +1 -1
  156. package/protocol/skills/agentsam.skill.v1.schema.json +1 -1
  157. package/protocol/theme-refinery/product-metadata.schema.json +1 -1
  158. package/protocol/theme-refinery/reconciliation-receipt.schema.json +1 -1
  159. package/protocol/ui/icon.v1.schema.json +1 -1
  160. package/python/README.md +20 -0
  161. package/python/agentsam_sdk/errors/__init__.py +4 -0
  162. package/python/agentsam_sdk/errors/vocabulary.py +2730 -0
  163. package/python/agentsam_sdk/hooks/__init__.py +32 -0
  164. package/python/agentsam_sdk/hooks/adapters.py +132 -0
  165. package/python/agentsam_sdk/hooks/contracts.py +121 -0
  166. package/python/agentsam_sdk/hooks/runtime.py +253 -0
  167. package/python/tests/test_hooks.py +115 -0
  168. package/src/agent/responses-runner.js +145 -1
  169. package/src/cli/command-catalog.js +2 -0
  170. package/src/cli.js +19 -0
  171. package/src/commands/app.js +10 -0
  172. package/src/commands/cheat-sheet.js +1 -0
  173. package/src/commands/engine.js +10 -0
  174. package/src/commands/hooks.js +260 -0
  175. package/src/commands/machine.js +71 -38
  176. package/src/commands/models.js +1 -1
  177. package/src/commands/package.js +10 -3
  178. package/src/commands/runtime.js +25 -10
  179. package/src/commands/setup.js +30 -6
  180. package/src/commands/shell.js +114 -9
  181. package/src/commands/terminal.js +20 -8
  182. package/src/errors/contract.js +4 -4
  183. package/src/errors/diagnostic.js +10 -10
  184. package/src/errors/index.js +1 -1
  185. package/src/index.js +52 -0
  186. package/src/indexing/ingest/materials.js +237 -30
  187. package/src/knowledge/service/grpc-codec.js +2 -0
  188. package/src/lib/setup/runtime.js +4 -2
  189. package/src/lib/slash-commands.js +1 -0
  190. package/src/local/runtime-store.js +46 -0
  191. package/src/local-engine/assets.js +37 -0
  192. package/src/local-engine/audit.js +133 -0
  193. package/src/local-engine/benchmark.js +26 -0
  194. package/src/local-engine/contracts.js +101 -0
  195. package/src/local-engine/engines.js +142 -0
  196. package/src/local-engine/index.js +18 -0
  197. package/src/local-engine/runtime.js +39 -0
  198. package/src/models/catalog.js +0 -49
  199. package/src/models/inventory-core.js +69 -0
  200. package/src/plugins/index.js +8 -1
  201. package/src/plugins/registry.js +56 -0
  202. package/src/rpc/generated/errors_pb.js +49 -1
  203. package/src/tools/runtime.js +13 -5
@@ -2,7 +2,9 @@
2
2
  * agentsam machine — deterministic native Machine lifecycle + perception.
3
3
  */
4
4
 
5
+ import os from 'node:os';
5
6
  import path from 'node:path';
7
+ import pc from 'picocolors';
6
8
  import { resolveMachineBinary, spawnMachine } from './machine-binary.js';
7
9
  import {
8
10
  installManagedMachine,
@@ -12,23 +14,35 @@ import {
12
14
  } from './machine-runtime.js';
13
15
 
14
16
  function usage() {
15
- return 'agentsam machine — deterministic local perception (native engine)\n\n' +
16
- 'Usage:\n' +
17
- ' agentsam machine status [--json]\n' +
18
- ' agentsam machine doctor [--json]\n' +
19
- ' agentsam machine install [--version <semver>] [--force] [--json]\n' +
20
- ' agentsam machine update [--force] [--json]\n' +
21
- ' agentsam machine inspect <path> [--json] [--run-id <id>] [--include-generated]\n' +
22
- ' agentsam machine --help\n\n' +
23
- 'Runtime authority:\n' +
24
- ' AgentSam manages one user-level Machine runtime under ~/.agentsam/runtimes/machine/.\n' +
25
- ' Every repository uses that managed runtime first; PATH and SDK source are fallbacks only.\n' +
26
- ' Install/update are explicit and never run merely because you entered a repository.\n\n' +
27
- 'Notes:\n' +
28
- ' Default inspect is read-only and network-free.\n' +
29
- ' Large detail is externalized under <target>/.agentsam/machine/runs/<run_id>/.\n' +
30
- ' Generated/cache trees are summarized unless --include-generated is set.\n' +
31
- ' Current registry distribution uses crates.io and therefore requires Cargo for install/update.\n';
17
+ return [
18
+ `${pc.bold('agentsam machine')} — deterministic local perception (native engine)`,
19
+ '',
20
+ pc.bold('Usage'),
21
+ ` ${pc.cyan('agentsam machine status')} Show the active runtime`,
22
+ ` ${pc.cyan('agentsam machine doctor')} Diagnose runtime resolution`,
23
+ ` ${pc.cyan('agentsam machine install')} [--version <semver>] Install the managed runtime`,
24
+ ` ${pc.cyan('agentsam machine update')} Update the managed runtime`,
25
+ ` ${pc.cyan('agentsam machine inspect <path>')} Inspect a repository or directory`,
26
+ '',
27
+ pc.bold('Options'),
28
+ ` ${pc.dim('--json')} Machine-readable output`,
29
+ ` ${pc.dim('--force')} Replace an existing managed version`,
30
+ ` ${pc.dim('--run-id <id>')} Reuse an externalized inspection run`,
31
+ ` ${pc.dim('--include-generated')} Include generated and cache trees`,
32
+ ` ${pc.dim('--help')} Show this help`,
33
+ '',
34
+ pc.bold('Runtime authority'),
35
+ ' AgentSam manages one user-level Machine runtime under ~/.agentsam/runtimes/machine/.',
36
+ ' Resolution order: managed runtime → explicit override → PATH → SDK source.',
37
+ ' Install and update are explicit; entering a repository never changes the host.',
38
+ '',
39
+ pc.bold('Behavior'),
40
+ ' Inspect is read-only and network-free by default.',
41
+ ' Large detail is externalized under <target>/.agentsam/machine/runs/<run_id>/.',
42
+ ' Generated and cache trees are summarized unless --include-generated is set.',
43
+ ' Install/update use the crates.io distribution and require Cargo.',
44
+ '',
45
+ ].join('\n');
32
46
  }
33
47
 
34
48
  function parseArgs(argv = []) {
@@ -86,44 +100,63 @@ function statusPayload() {
86
100
  };
87
101
  }
88
102
 
103
+ function compactPath(value) {
104
+ const raw = String(value || '—');
105
+ const home = os.homedir();
106
+ return home && (raw === home || raw.startsWith(home + path.sep))
107
+ ? '~' + raw.slice(home.length)
108
+ : raw;
109
+ }
110
+
111
+ function stateLabel(installed) {
112
+ return installed ? pc.green('installed') : pc.yellow('not installed');
113
+ }
114
+
89
115
  function printTextStatus(payload) {
90
- console.log('AgentSam Machine');
116
+ const managed = payload.managed;
117
+ const effective = payload.effective;
118
+ console.log(pc.bold('AgentSam Machine'));
119
+ console.log(pc.dim('Deterministic local perception · native runtime'));
120
+ console.log('');
121
+ console.log(pc.bold('Managed runtime'));
122
+ console.log(` status ${stateLabel(managed.installed)}`);
123
+ console.log(` version ${managed.current_version || pc.dim('—')}`);
124
+ console.log(` runtime ${compactPath(managed.runtime_root)}`);
125
+ console.log(` binary ${compactPath(managed.binary)}`);
91
126
  console.log('');
92
- console.log(' managed ' + (payload.managed.installed ? 'installed' : 'not installed'));
93
- console.log(' version ' + (payload.managed.current_version || '—'));
94
- console.log(' binary ' + (payload.managed.binary || '—'));
95
- console.log(' runtime ' + payload.managed.runtime_root);
96
- console.log(' effective ' + payload.effective.source);
97
- console.log(' effective v ' + (payload.effective.version || 'unknown'));
98
- console.log(' cargo ' + (payload.managed.cargo.available ? payload.managed.cargo.path : 'not found'));
99
- if (!payload.managed.installed) {
127
+ console.log(pc.bold('Active resolution'));
128
+ console.log(` source ${effective.source || pc.dim('unavailable')}`);
129
+ console.log(` version ${effective.version || pc.dim('unknown')}`);
130
+ console.log(` cargo ${managed.cargo.available ? compactPath(managed.cargo.path) : pc.dim('not found')}`);
131
+ if (!managed.installed) {
100
132
  console.log('');
101
- console.log(' Run agentsam machine install to adopt the user-managed runtime.');
133
+ console.log(` ${pc.yellow('Next step')} agentsam machine install`);
102
134
  }
103
135
  }
104
136
 
105
137
  function printTextDoctor(payload) {
106
138
  printTextStatus(payload);
107
139
  console.log('');
140
+ console.log(pc.bold('Doctor'));
108
141
  if (payload.effective.kind === 'missing') {
109
- console.log(' ✕ Machine unavailable');
110
- console.log(' tried ' + (payload.effective.tried || []).join(', '));
142
+ console.log(` ${pc.red('✕')} Machine unavailable`);
143
+ console.log(` tried ${(payload.effective.tried || []).map(compactPath).join(', ') || pc.dim('none')}`);
111
144
  } else if (payload.managed.installed) {
112
- console.log(' ✓ managed Machine runtime is available');
145
+ console.log(` ${pc.green('✓')} Managed Machine runtime is available`);
113
146
  } else {
114
- console.log(' ○ Machine works through fallback source: ' + payload.effective.source);
115
- console.log(' ○ install the managed runtime to make resolution consistent across repositories');
147
+ console.log(` ${pc.yellow('○')} Fallback runtime is active: ${payload.effective.source}`);
148
+ console.log(' install the managed runtime for consistent resolution across repositories');
116
149
  }
117
150
  }
118
151
 
119
152
  function printInstallResult(action, result) {
120
- console.log('AgentSam Machine ' + action);
153
+ console.log(pc.bold(`AgentSam Machine · ${action}`));
121
154
  console.log('');
122
- console.log(' version ' + result.version);
123
- console.log(' binary ' + result.binary);
124
- console.log(' alias ' + result.alias);
125
- console.log(' source ' + result.source);
126
- console.log(' changed ' + (result.changed ? 'yes' : 'no'));
155
+ console.log(` ${pc.green('✓')} Runtime ${result.changed ? 'installed' : 'already current'}`);
156
+ console.log(` version ${result.version}`);
157
+ console.log(` source ${result.source}`);
158
+ console.log(` binary ${compactPath(result.binary)}`);
159
+ console.log(` alias ${compactPath(result.alias)}`);
127
160
  }
128
161
 
129
162
  export async function runMachine(argv = []) {
@@ -17,7 +17,7 @@ export const API_PROVIDERS = Object.freeze([
17
17
  { id: 'openai', label: 'OpenAI', credential: 'OPENAI_API_KEY' },
18
18
  { id: 'anthropic', label: 'Anthropic', credential: 'ANTHROPIC_API_KEY' },
19
19
  { id: 'gemini', label: 'Gemini', credential: 'GEMINI_API_KEY' },
20
- { id: 'grok', label: 'Grok / xAI', credential: 'XAI_API_KEY' },
20
+ { id: 'xai', label: 'Grok / xAI', credential: 'XAI_API_KEY' },
21
21
  { id: 'cursor', label: 'Cursor', credential: 'CURSOR_API_KEY' },
22
22
  { id: 'cloudflare', label: 'Cloudflare', credential: 'CLOUDFLARE_API_TOKEN' },
23
23
  ]);
@@ -3,6 +3,7 @@ import path from 'node:path';
3
3
  import { execFile, spawnSync } from 'node:child_process';
4
4
  import { promisify } from 'node:util';
5
5
  import { fileURLToPath } from 'node:url';
6
+ import { findCliProjectRoot } from '../lib/cli-preferences.js';
6
7
 
7
8
  const execFileAsync = promisify(execFile);
8
9
  const SDK_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..');
@@ -403,6 +404,10 @@ function parseArgs(argv) {
403
404
  return { positional, flags };
404
405
  }
405
406
 
407
+ export function resolvePackageRoot(cwd = process.cwd()) {
408
+ return findCliProjectRoot(cwd);
409
+ }
410
+
406
411
  function printHelp() {
407
412
  console.log(`agentsam package — audit and graduate distributable packages
408
413
 
@@ -474,6 +479,7 @@ export async function runPackage(argv = []) {
474
479
  const sub = positional[0];
475
480
  const json = flags.has('--json');
476
481
  const offline = flags.has('--offline');
482
+ const root = resolvePackageRoot(process.cwd());
477
483
 
478
484
  if (!sub || flags.has('--help') || flags.has('-h')) {
479
485
  printHelp();
@@ -482,6 +488,7 @@ export async function runPackage(argv = []) {
482
488
 
483
489
  if (sub === 'audit') {
484
490
  const report = await auditPackages({
491
+ root,
485
492
  publicOnly: flags.has('--public'),
486
493
  offline,
487
494
  });
@@ -495,7 +502,7 @@ export async function runPackage(argv = []) {
495
502
  const name = positional[1];
496
503
  if (!name) throw new Error('package status requires a package name');
497
504
 
498
- const pkg = collectPackageManifests().find((item) => item.name === name);
505
+ const pkg = collectPackageManifests(root).find((item) => item.name === name);
499
506
  if (!pkg) throw new Error(`Unknown @inneranimalmedia package: ${name}`);
500
507
 
501
508
  const status = classifyPackage(pkg, await registryLookup(pkg, offline));
@@ -509,7 +516,7 @@ export async function runPackage(argv = []) {
509
516
  const name = positional[1];
510
517
  if (!name) throw new Error('package verify requires a package name');
511
518
 
512
- const report = await verifyPackage(name, { offline });
519
+ const report = await verifyPackage(name, { root, offline });
513
520
 
514
521
  if (json) console.log(JSON.stringify(report, null, 2));
515
522
  else printVerify(report);
@@ -519,7 +526,7 @@ export async function runPackage(argv = []) {
519
526
  }
520
527
 
521
528
  if (sub === 'publish-plan') {
522
- const plan = await buildPublishPlan({ offline });
529
+ const plan = await buildPublishPlan({ root, offline });
523
530
 
524
531
  if (json) console.log(JSON.stringify(plan, null, 2));
525
532
  else printPlan(plan);
@@ -101,6 +101,15 @@ async function probeAgentsamd() {
101
101
  }
102
102
  }
103
103
 
104
+ async function waitForAgentsamd({ attempts = 8, delayMs = 250 } = {}) {
105
+ let last = await probeAgentsamd();
106
+ for (let attempt = 1; attempt < attempts && !last.ok; attempt += 1) {
107
+ await new Promise((resolve) => setTimeout(resolve, delayMs));
108
+ last = await probeAgentsamd();
109
+ }
110
+ return last;
111
+ }
112
+
104
113
  async function startAgentsamd(home, write) {
105
114
  const bin = agentsamdPath(home);
106
115
  if (!fs.existsSync(bin)) throw new Error('agentsamd_not_installed');
@@ -109,8 +118,7 @@ async function startAgentsamd(home, write) {
109
118
  try {
110
119
  await startWindowsScheduledTask();
111
120
  writeLine(write, ` Started Scheduled Task · ${listenAddr()}`);
112
- await new Promise((r) => setTimeout(r, 600));
113
- return probeAgentsamd();
121
+ return waitForAgentsamd();
114
122
  } catch (err) {
115
123
  writeLine(write, ` ○ Scheduled Task start failed (${err.message || err}); falling back to spawn`);
116
124
  }
@@ -122,8 +130,7 @@ async function startAgentsamd(home, write) {
122
130
  const boot = await bootstrapDarwinLaunchAgent(plist);
123
131
  if (boot.ok) {
124
132
  writeLine(write, ` Loaded LaunchAgent ${DARWIN_LAUNCH_LABEL}`);
125
- await new Promise((r) => setTimeout(r, 400));
126
- return probeAgentsamd();
133
+ return waitForAgentsamd();
127
134
  }
128
135
  }
129
136
  }
@@ -138,8 +145,7 @@ async function startAgentsamd(home, write) {
138
145
  ensureRuntimeStateDir(home);
139
146
  fs.writeFileSync(pidPath(home), String(child.pid));
140
147
  writeLine(write, ` Started agentsamd pid ${child.pid} · ${listenAddr()}`);
141
- await new Promise((r) => setTimeout(r, 400));
142
- return probeAgentsamd();
148
+ return waitForAgentsamd();
143
149
  }
144
150
 
145
151
  async function stopAgentsamd(home, write) {
@@ -218,12 +224,21 @@ export async function runRuntime(argv = [], options = {}) {
218
224
  writeLine(write, ` Impl ${probe.body.implementation}`);
219
225
  }
220
226
  writeLine(write, '');
221
- writeLine(write, ' Next');
222
- writeLine(write, ' agentsam setup runtime');
223
- writeLine(write, ' agentsam runtime install --yes');
227
+ if (probe.ok) {
228
+ writeLine(write, sub === 'doctor' ? ' Doctor ✓ healthy; no repair needed' : ' State ✓ ready');
229
+ writeLine(write, ' Next agentsam terminal --help');
230
+ } else if (facts.agentsamd.installed) {
231
+ writeLine(write, ' Repair');
232
+ writeLine(write, ' agentsam runtime start');
233
+ writeLine(write, ' agentsam runtime install --yes # rebuild only if start still fails');
234
+ } else {
235
+ writeLine(write, ' Next');
236
+ writeLine(write, ' agentsam setup runtime');
237
+ writeLine(write, ' agentsam runtime install --yes');
238
+ }
224
239
  writeLine(write, '');
225
240
  }
226
- return probe.ok || facts.agentsamd.installed ? 0 : (sub === 'doctor' ? 2 : 0);
241
+ return sub === 'doctor' ? (probe.ok ? 0 : 2) : 0;
227
242
  }
228
243
 
229
244
  if (sub === 'probe') {
@@ -139,7 +139,7 @@ async function runSetupRuntime(argv = [], options = {}) {
139
139
  if (dryRun || !yes) {
140
140
  writeLine(write, ` Plan receipt ${planPath}`);
141
141
  if (!yes) {
142
- writeLine(write, ' Pass --yes to install agentsamd (when profile needs it) and write install receipt.');
142
+ writeLine(write, ' Pass --yes to apply the selected runtime profile; healthy agentsamd installs are reused.');
143
143
  }
144
144
  writeLine(write, '');
145
145
  return 0;
@@ -154,9 +154,26 @@ async function runSetupRuntime(argv = [], options = {}) {
154
154
 
155
155
  let installResult = null;
156
156
  if (recommended.target.runtime_adapter === 'agentsamd') {
157
- const code = await runRuntime(['install', '--yes'], { write, home });
158
- installResult = { code, adapter: 'agentsamd' };
159
- if (code !== 0) return code;
157
+ if (plan.facts.agentsamd.installed) {
158
+ const doctorCode = await runRuntime(['doctor', '--json'], { write: () => {}, home });
159
+ if (doctorCode === 0) {
160
+ installResult = { code: 0, adapter: 'agentsamd', skipped: true, reason: 'already_installed_healthy' };
161
+ writeLine(write, ' ✓ agentsamd already installed and healthy; reusing current runtime');
162
+ } else {
163
+ const startCode = await runRuntime(['start'], { write, home });
164
+ if (startCode === 0) {
165
+ installResult = { code: 0, adapter: 'agentsamd', skipped: true, reason: 'existing_runtime_restarted' };
166
+ } else {
167
+ const code = await runRuntime(['install', '--yes'], { write, home });
168
+ installResult = { code, adapter: 'agentsamd', repaired: true };
169
+ if (code !== 0) return code;
170
+ }
171
+ }
172
+ } else {
173
+ const code = await runRuntime(['install', '--yes'], { write, home });
174
+ installResult = { code, adapter: 'agentsamd' };
175
+ if (code !== 0) return code;
176
+ }
160
177
  }
161
178
 
162
179
  const receiptPath = writeRuntimeInstallReceipt({
@@ -164,7 +181,12 @@ async function runSetupRuntime(argv = [], options = {}) {
164
181
  profile_id: recommended.profile.id,
165
182
  target: recommended.target,
166
183
  goap: recommended.goap,
167
- install: installResult,
184
+ goap_execution: {
185
+ status: 'planned_only',
186
+ executed_action_ids: [],
187
+ pending_action_ids: recommended.goap.action_ids || [],
188
+ },
189
+ adapter_apply: installResult,
168
190
  plan_receipt: planPath,
169
191
  }, home);
170
192
 
@@ -175,7 +197,9 @@ async function runSetupRuntime(argv = [], options = {}) {
175
197
  plan,
176
198
  plan_receipt: planPath,
177
199
  install_receipt: receiptPath,
178
- executed: true,
200
+ adapter_applied: true,
201
+ goap_execution: 'planned_only',
202
+ executed: false,
179
203
  }, null, 2) + '\n');
180
204
  }
181
205
  return 0;
@@ -33,6 +33,7 @@ import { grantExecutionApproval, isExecutionApproved, toolApprovalKey } from '..
33
33
  import { runWhoami } from './whoami.js';
34
34
  import { runCredentials } from './credentials.js';
35
35
  import { runCheatSheet } from './cheat-sheet.js';
36
+ import { createProjectHookRuntime, runHooks } from './hooks.js';
36
37
  import pkg from '../../package.json' with { type: 'json' };
37
38
  import { runLogin, runLogout } from './account-auth.js';
38
39
  import { runHelp } from '../ui/cli/help.js';
@@ -262,21 +263,48 @@ function spawnGit(cwd, args) {
262
263
  if (result.status !== 0) throw new Error(`git exited ${result.status}`);
263
264
  }
264
265
 
265
- function selectedModel(cwd) {
266
- const preferences = readCliPreferences(cwd) || {};
267
- const snapshot = preferences.modelSnapshot?.model_key === preferences.modelPreference
268
- ? mergeModelReference(preferences.modelSnapshot)
266
+ function selectedModel(cwd, state = null) {
267
+ const saved = readCliPreferences(cwd) || {};
268
+ const sessionConfig = state?.hookEffectiveConfig || {};
269
+ const preferences = {
270
+ ...saved,
271
+ ...(sessionConfig.model_key ? { modelPreference: sessionConfig.model_key } : {}),
272
+ ...(sessionConfig.reasoning_effort ? { reasoningEffort: sessionConfig.reasoning_effort } : {}),
273
+ ...(sessionConfig.requested_service_tier ? { serviceTier: sessionConfig.requested_service_tier } : {}),
274
+ };
275
+ const snapshot = saved.modelSnapshot?.model_key === preferences.modelPreference
276
+ ? mergeModelReference(saved.modelSnapshot)
269
277
  : null;
270
278
  let model = snapshot || getModelRecord(preferences.modelPreference);
279
+ if (!model && sessionConfig.model_key && sessionConfig.model_key.includes(':')) {
280
+ const [provider, ...modelParts] = sessionConfig.model_key.split(':');
281
+ const providerModelId = modelParts.join(':');
282
+ if (provider && providerModelId) {
283
+ model = {
284
+ model_key: sessionConfig.model_key,
285
+ provider,
286
+ provider_model_id: providerModelId,
287
+ label: providerModelId,
288
+ context_window: null,
289
+ context_window_source: 'unknown',
290
+ max_output_tokens: null,
291
+ max_output_tokens_source: 'unknown',
292
+ reasoning_efforts: ['auto'],
293
+ default_reasoning_effort: null,
294
+ service_tiers: ['default'],
295
+ capabilities: {},
296
+ };
297
+ }
298
+ }
271
299
  if (!model && (preferences.modelPreference === 'auto' || !preferences.modelPreference)) {
272
- model = mergeModelReference(preferences.modelSnapshot) || listModelCatalog()[0];
300
+ model = mergeModelReference(saved.modelSnapshot) || listModelCatalog()[0];
273
301
  }
274
302
  if (!model) throw new Error('Select an exact provider-verified model with /model first so Agent Sam can verify supported runtime controls.');
275
303
  return { preferences, model };
276
304
  }
277
305
 
278
306
  async function resolveModelForTurn(cwd, state) {
279
- const selected = selectedModel(cwd);
307
+ const selected = selectedModel(cwd, state);
280
308
  const { preferences } = selected;
281
309
  let model = selected.model;
282
310
 
@@ -291,7 +319,7 @@ async function resolveModelForTurn(cwd, state) {
291
319
  capabilities: { ...(model.capabilities || {}), local_runtime: true, ...(Object.fromEntries((probe.capabilities || []).map((name) => [name, true]))) },
292
320
  };
293
321
  updateCliPreferences(cwd, { modelPreference: model.model_key, modelSnapshot: model });
294
- return { preferences: readCliPreferences(cwd) || preferences, model, credential: null, verification: 'local_runtime' };
322
+ return { preferences: { ...(readCliPreferences(cwd) || preferences), reasoningEffort: preferences.reasoningEffort, serviceTier: preferences.serviceTier }, model, credential: null, verification: 'local_runtime' };
295
323
  }
296
324
 
297
325
  const credential = resolveProviderCredential(model.provider, { home: state.home });
@@ -305,7 +333,7 @@ async function resolveModelForTurn(cwd, state) {
305
333
  if (!live) throw new Error(`selected_model_not_available_for_credential:${model.provider}:${model.provider_model_id}`);
306
334
  model = live;
307
335
  updateCliPreferences(cwd, { modelPreference: live.model_key, modelSnapshot: live });
308
- return { preferences: readCliPreferences(cwd) || preferences, model, credential, verification: 'provider_api' };
336
+ return { preferences: { ...(readCliPreferences(cwd) || preferences), reasoningEffort: preferences.reasoningEffort, serviceTier: preferences.serviceTier }, model, credential, verification: 'provider_api' };
309
337
  }
310
338
 
311
339
  if (preferences.modelSnapshot?.availability === 'available') {
@@ -595,7 +623,47 @@ function checkpointCompaction(state, model, result) {
595
623
  return receipt;
596
624
  }
597
625
 
626
+ async function ensureShellHookExperience(state) {
627
+ if (state.hookExperience) return state.hookExperience;
628
+ const experience = await createProjectHookRuntime({
629
+ cwd: state.cwd,
630
+ projectRoot: state.projectRoot,
631
+ home: state.home,
632
+ sessionId: state.session?.id,
633
+ conversationId: state.session?.conversation_id,
634
+ hooks: state.codeHooks,
635
+ });
636
+ state.hookExperience = experience;
637
+ if (!state.hookSessionStarted) {
638
+ const config = {
639
+ model_key: state.session?.model_key || null,
640
+ reasoning_effort: state.session?.reasoning_effort || null,
641
+ requested_service_tier: state.session?.requested_service_tier || 'default',
642
+ auto_compact: state.session?.auto_compact !== false,
643
+ };
644
+ const started = await experience.runtime.dispatch('session_start', {
645
+ config,
646
+ project_root: state.projectRoot,
647
+ cwd: state.cwd,
648
+ }, {
649
+ session_id: state.session?.id,
650
+ source: 'agentsam-cli',
651
+ }, { cwd: state.cwd });
652
+ const modified = started.input.config || config;
653
+ const allowed = {};
654
+ for (const key of ['model_key', 'reasoning_effort', 'requested_service_tier', 'auto_compact']) {
655
+ if (modified[key] !== undefined) allowed[key] = modified[key];
656
+ }
657
+ state.hookEffectiveConfig = { ...config, ...allowed };
658
+ if (state.session && Object.keys(allowed).length) persistSession(state, allowed);
659
+ state.hookSessionContext = started.output.additional_context || null;
660
+ state.hookSessionStarted = true;
661
+ }
662
+ return experience;
663
+ }
664
+
598
665
  async function runInteractiveModelTurn(prompt, state) {
666
+ const hookExperience = await ensureShellHookExperience(state);
599
667
  const resolved = await resolveModelForTurn(state.cwd, state);
600
668
  const { preferences, model, credential } = resolved;
601
669
  const provider = createProviderAdapter({
@@ -660,7 +728,13 @@ async function runInteractiveModelTurn(prompt, state) {
660
728
  autoCompact: state.session?.auto_compact !== false,
661
729
  onCompaction: result => { if (state.session) checkpointCompaction(state, model, result); },
662
730
  promptCacheKey: state.session?.id || undefined,
731
+ hookRuntime: hookExperience.runtime,
732
+ sessionId: state.session?.id || undefined,
663
733
  runId: runtimeRunId || state.session?.id || undefined,
734
+ source: 'agentsam-cli',
735
+ ...(state.hookSessionContext ? {
736
+ contextItems: [{ kind: 'hook', ref: 'hook://session-start/context', priority: 96, content: state.hookSessionContext }],
737
+ } : {}),
664
738
  beforeRequest: (preflight) => approveModelRequest(preflight, state),
665
739
  beforeTool: (request) => approveToolExecution(request, state),
666
740
  emit(event) {
@@ -793,7 +867,7 @@ export async function dispatchShellLine(line, state = {}) {
793
867
  'help', 'exit', 'quit', 'clear', 'status', 'models', 'model',
794
868
  'whoami', 'cf', 'cloudflare', 'db', 'tunnel', 'connections',
795
869
  'connect', 'usage', 'session', 'providers', 'credentials', 'cheatsheet',
796
- 'settings', 'logs',
870
+ 'settings', 'logs', 'hooks', 'hook',
797
871
  'git', 'diff', 'pwd', 'cd', 'fast', 'flex', 'standard', 'reasoning',
798
872
  ];
799
873
  if (commonVerbs.includes(bare)) {
@@ -862,6 +936,22 @@ export async function dispatchShellLine(line, state = {}) {
862
936
  state.rl?.resume?.();
863
937
  }
864
938
  break;
939
+ case '/hooks':
940
+ case '/hook': {
941
+ const hookCommand = args[0] || 'status';
942
+ await runHooks(args.length ? args : ['status'], { cwd: state.cwd, write, home: state.home, hooks: state.codeHooks });
943
+ if (['init', 'enable', 'disable'].includes(hookCommand)) {
944
+ if (state.hookExperience && state.hookSessionStarted) {
945
+ await state.hookExperience.runtime.dispatch('session_end', {
946
+ status: 'reloading_hooks',
947
+ elapsed_ms: state.session ? localSessionElapsedMs(state.session) : 0,
948
+ }, { session_id: state.session?.id, source: 'agentsam-cli' }, { cwd: state.cwd });
949
+ }
950
+ state.hookExperience = null;
951
+ state.hookSessionStarted = false;
952
+ }
953
+ break;
954
+ }
865
955
  case '/providers':
866
956
  state.rl?.pause?.();
867
957
  try {
@@ -1113,6 +1203,7 @@ export async function runShell(argv = [], options = {}) {
1113
1203
  session: options.session || null,
1114
1204
  home: options.home,
1115
1205
  providerFetchImpl: options.providerFetchImpl,
1206
+ codeHooks: options.hooks || null,
1116
1207
  persistFooter: options.persistFooter === true,
1117
1208
  };
1118
1209
  const sub = argv[0] || '';
@@ -1201,6 +1292,20 @@ export async function runShell(argv = [], options = {}) {
1201
1292
  restorePaste();
1202
1293
  state.rl = null;
1203
1294
  }
1295
+ if (state.hookExperience && state.hookSessionStarted) {
1296
+ try {
1297
+ await state.hookExperience.runtime.dispatch('session_end', {
1298
+ status: interrupted ? 'interrupted' : 'paused',
1299
+ elapsed_ms: state.session ? localSessionElapsedMs(state.session) : 0,
1300
+ cumulative_usage: state.session?.cumulative_usage || {},
1301
+ }, {
1302
+ session_id: state.session?.id,
1303
+ source: 'agentsam-cli',
1304
+ }, { cwd: state.cwd });
1305
+ } catch (error) {
1306
+ writeLine(write, ` Hook cleanup warning: ${error?.message || error}`);
1307
+ }
1308
+ }
1204
1309
  if (state.session) {
1205
1310
  const activeElapsedMs = localSessionElapsedMs(state.session);
1206
1311
  persistSession(state, {
@@ -30,6 +30,21 @@ function printIdentity(identity, write) {
30
30
  write(`hw_model: ${identity.model || 'unknown'}`);
31
31
  }
32
32
 
33
+ function terminalUsage() {
34
+ return [
35
+ 'agentsam terminal — device identity and ExecOS enrollment',
36
+ '',
37
+ 'Usage:',
38
+ ' agentsam terminal identity [--json]',
39
+ ' agentsam terminal enroll --instance <id> [--endpoint <url>] [--pair] [--json]',
40
+ ' agentsam terminal --help',
41
+ '',
42
+ 'Identity lanes:',
43
+ ' AGENTSAM_API_KEY account/CLI identity used to mint enrollment',
44
+ ' AGENTSAM_BRIDGE_KEY one terminal_connection credential written by --pair',
45
+ ].join('\n');
46
+ }
47
+
33
48
  function defaultExecosEnrollBin() {
34
49
  return path.join(homedir(), 'ExecOS', 'bin', 'enroll.mjs');
35
50
  }
@@ -52,6 +67,10 @@ function pairWithExecos(enrollmentToken, options = {}) {
52
67
 
53
68
  export async function runTerminal(argv = [], options = {}) {
54
69
  const write = options.write || ((line) => console.log(line));
70
+ if (argv.includes('--help') || argv.includes('-h') || argv.includes('help')) {
71
+ write(terminalUsage());
72
+ return { ok: true, help: true };
73
+ }
55
74
  const sub = argv[0] && !argv[0].startsWith('--') ? argv[0] : 'identity';
56
75
  const json = argv.includes('--json') || options.json === true;
57
76
  const pair = argv.includes('--pair') || options.pair === true;
@@ -70,14 +89,7 @@ export async function runTerminal(argv = [], options = {}) {
70
89
  }
71
90
 
72
91
  if (sub !== 'enroll') {
73
- write([
74
- 'Usage: agentsam terminal identity [--json]',
75
- ' agentsam terminal enroll --instance <id> [--endpoint <url>] [--pair] [--json]',
76
- '',
77
- 'Lanes:',
78
- ' AGENTSAM_API_KEY account (CLI / whoami / mint enrollment) — required for this command',
79
- ' AGENTSAM_BRIDGE_KEY one terminal_connection secret (written by --pair into ExecOS profile)',
80
- ].join('\n'));
92
+ write(terminalUsage());
81
93
  return { ok: false, error: 'terminal_usage' };
82
94
  }
83
95
 
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  ERROR_CODE,
4
4
  ERROR_REASON,
5
- } from '../../packages/agentsam-errors/src/vocabulary.js';
6
- import { canonicalCodeFromHttpStatus } from '../../packages/agentsam-errors/src/envelope.js';
5
+ } from '@inneranimalmedia/agentsam-errors';
6
+ import { canonicalCodeFromHttpStatus } from '@inneranimalmedia/agentsam-errors';
7
7
 
8
8
  export {
9
9
  ERROR_SCHEMA_VERSION,
@@ -15,7 +15,7 @@ export {
15
15
  ERROR_DOMAIN,
16
16
  REMEDIATION_ACTION,
17
17
  GRPC_STATUS,
18
- } from '../../packages/agentsam-errors/src/vocabulary.js';
18
+ } from '@inneranimalmedia/agentsam-errors';
19
19
 
20
20
  export {
21
21
  canonicalCodeFromHttpStatus,
@@ -27,7 +27,7 @@ export {
27
27
  assertErrorEnvelope,
28
28
  serializeError,
29
29
  parseError,
30
- } from '../../packages/agentsam-errors/src/envelope.js';
30
+ } from '@inneranimalmedia/agentsam-errors';
31
31
 
32
32
  // Legacy compact classifier shapes remain public here; richer envelope classifiers
33
33
  // live in packages/agentsam-errors and are available via the other adapter exports.