@aiwg/cli 2026.10.5 → 2026.10.7

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 (263) hide show
  1. package/agentic/code/addons/composition-engine/lib/runtime.mjs +1401 -0
  2. package/agentic/code/addons/composition-engine/lib/validator.mjs +513 -0
  3. package/agentic/code/addons/composition-engine/schemas/flow-graph.schema.json +372 -0
  4. package/agentic/code/providers/model-capabilities.v1.json +74 -50
  5. package/bin/aiwg.mjs +7 -3
  6. package/dist/src/a2a/agent-card.js +11 -0
  7. package/dist/src/api/index.d.ts +1 -0
  8. package/dist/src/api/index.js +1 -0
  9. package/dist/src/artifacts/browser-export.js +1 -0
  10. package/dist/src/artifacts/citation-parser.js +8 -1
  11. package/dist/src/artifacts/cli.js +57 -6
  12. package/dist/src/artifacts/fortemi-core-query-adapter.js +2 -0
  13. package/dist/src/artifacts/fortemi-core-sync.js +26 -8
  14. package/dist/src/artifacts/fortemi-shard-contract/2.2.0/contract.json +103 -0
  15. package/dist/src/artifacts/fortemi-shard-contract/2.2.0/full-v1-embedding-config.schema.json +212 -0
  16. package/dist/src/artifacts/fortemi-shard-contract/2.2.0/full-v1-embedding-set.schema.json +240 -0
  17. package/dist/src/artifacts/fortemi-shard-contract/2.2.0/full-v1-manifest.schema.json +451 -0
  18. package/dist/src/artifacts/fortemi-shard-export.js +284 -0
  19. package/dist/src/artifacts/graph-query.js +18 -8
  20. package/dist/src/artifacts/index-adapters.js +339 -0
  21. package/dist/src/artifacts/index-builder.js +143 -14
  22. package/dist/src/artifacts/index-files.js +15 -4
  23. package/dist/src/artifacts/index-preparation.js +2 -0
  24. package/dist/src/artifacts/index-reader.js +44 -0
  25. package/dist/src/artifacts/index-refresh.js +114 -55
  26. package/dist/src/artifacts/index-status.js +20 -5
  27. package/dist/src/artifacts/memory-maintenance.js +503 -0
  28. package/dist/src/artifacts/prebuilt-relations.js +3 -1
  29. package/dist/src/artifacts/query-engine.js +263 -108
  30. package/dist/src/artifacts/relations-builder.js +2 -2
  31. package/dist/src/artifacts/source-graph.js +2 -2
  32. package/dist/src/artifacts/types.js +9 -1
  33. package/dist/src/auth/client.js +5 -1
  34. package/dist/src/auth/credential-store.js +5 -1
  35. package/dist/src/auth/sensitive-input.js +151 -0
  36. package/dist/src/channel/manager.mjs +3 -0
  37. package/dist/src/cli/handlers/agentcard.js +47 -25
  38. package/dist/src/cli/handlers/auth.js +22 -2
  39. package/dist/src/cli/handlers/decision.js +22 -3
  40. package/dist/src/cli/handlers/effect.js +4 -84
  41. package/dist/src/cli/handlers/guided-setup.js +470 -0
  42. package/dist/src/cli/handlers/help.js +2 -2
  43. package/dist/src/cli/handlers/housekeeper.js +1110 -0
  44. package/dist/src/cli/handlers/index.js +4 -2
  45. package/dist/src/cli/handlers/init.js +41 -6
  46. package/dist/src/cli/handlers/install.js +6 -0
  47. package/dist/src/cli/handlers/local-executor.js +5 -3
  48. package/dist/src/cli/handlers/marketplace.js +15 -4
  49. package/dist/src/cli/handlers/mc.js +509 -53
  50. package/dist/src/cli/handlers/models.js +32 -2
  51. package/dist/src/cli/handlers/ralph-launcher.js +76 -4
  52. package/dist/src/cli/handlers/rules.js +1 -1
  53. package/dist/src/cli/handlers/script-runner.js +73 -2
  54. package/dist/src/cli/handlers/serve.js +5 -3
  55. package/dist/src/cli/handlers/sessions.js +1 -0
  56. package/dist/src/cli/handlers/setup.js +432 -1
  57. package/dist/src/cli/handlers/skill-lint.js +1 -1
  58. package/dist/src/cli/handlers/subcommands.js +118 -8
  59. package/dist/src/cli/handlers/use.js +335 -107
  60. package/dist/src/cli/handlers/workspace.js +3 -1
  61. package/dist/src/cli/prompt-utils.js +81 -0
  62. package/dist/src/cli/router.js +16 -1
  63. package/dist/src/config/aiwg-config.js +42 -0
  64. package/dist/src/config/cli.js +7 -3
  65. package/dist/src/config/decision-config.js +14 -1
  66. package/dist/src/config/gitignore.js +4 -0
  67. package/dist/src/config/native-sandbox-warnings.js +25 -0
  68. package/dist/src/config/workspace.js +2 -1
  69. package/dist/src/contributors/validation.js +6 -5
  70. package/dist/src/decision/adapters/jev.js +20 -31
  71. package/dist/src/decision/admission.js +7 -3
  72. package/dist/src/decision/ask.js +6 -1
  73. package/dist/src/decision/benchmark.js +482 -0
  74. package/dist/src/decision/ledger.js +22 -3
  75. package/dist/src/decision/pricing.js +147 -0
  76. package/dist/src/decision/qualification/gate-evidence.js +23 -18
  77. package/dist/src/decision/qualification/load-staged.js +576 -0
  78. package/dist/src/decision/qualification/load.js +109 -33
  79. package/dist/src/decision/qualification/runner.js +12 -5
  80. package/dist/src/decision/review/service.js +6 -4
  81. package/dist/src/decision/review/validate.js +23 -2
  82. package/dist/src/decision/savings.js +8 -3
  83. package/dist/src/discovery/index.js +492 -0
  84. package/dist/src/discovery/interview.js +238 -0
  85. package/dist/src/discovery/plan-apply.js +567 -0
  86. package/dist/src/discovery/plan-store.js +171 -0
  87. package/dist/src/discovery/plan-types.js +2 -0
  88. package/dist/src/discovery/plan-validation.js +139 -0
  89. package/dist/src/discovery/types.js +2 -0
  90. package/dist/src/effects/host.js +91 -0
  91. package/dist/src/extensions/commands/definitions.js +49 -9
  92. package/dist/src/extensions/manifest.js +71 -44
  93. package/dist/src/extensions/project-local-discovery.js +1 -1
  94. package/dist/src/extensions/project-local-gitignore.js +2 -0
  95. package/dist/src/extensions/project-quickref.js +18 -17
  96. package/dist/src/extensions/validation.js +32 -29
  97. package/dist/src/housekeeper/daemon-config.js +148 -0
  98. package/dist/src/housekeeper/ipc.js +84 -0
  99. package/dist/src/housekeeper/lifecycle.js +148 -0
  100. package/dist/src/housekeeper/platform.js +35 -0
  101. package/dist/src/housekeeper/status.js +70 -0
  102. package/dist/src/housekeeper/units.js +114 -0
  103. package/dist/src/issues/cli.js +16 -5
  104. package/dist/src/issues/live.js +44 -12
  105. package/dist/src/jobs/flow.js +22 -21
  106. package/dist/src/lint/rule-activation.js +20 -5
  107. package/dist/src/lint/runner.js +1 -1
  108. package/dist/src/marketplace/exchange.js +18 -6
  109. package/dist/src/marketplace/provenance.js +3 -2
  110. package/dist/src/mcp/adapters/codex-runtime.js +46 -76
  111. package/dist/src/mcp/cli.mjs +22 -96
  112. package/dist/src/mcp/config-file.mjs +6 -2
  113. package/dist/src/mcp/config-layers.mjs +23 -7
  114. package/dist/src/mcp/grok-build-config.mjs +2 -1
  115. package/dist/src/mcp/muse-native-config.mjs +2 -1
  116. package/dist/src/mcp/profiles.js +18 -31
  117. package/dist/src/mcp/profiles.mjs +18 -32
  118. package/dist/src/mcp/registry.js +7 -27
  119. package/dist/src/mcp/registry.mjs +7 -28
  120. package/dist/src/mcp/server.mjs +34 -1
  121. package/dist/src/mcp/tools/agentic-sandbox.mjs +8 -7
  122. package/dist/src/mcp/tools/command-run.mjs +3 -2
  123. package/dist/src/mcp/tools/decision.mjs +49 -48
  124. package/dist/src/mcp/tools/discovery.mjs +46 -21
  125. package/dist/src/mcp/tools/orchestration.mjs +22 -22
  126. package/dist/src/mcp/tools/subsystems.mjs +9 -8
  127. package/dist/src/mcp/tools/worker-invoke.mjs +30 -6
  128. package/dist/src/mcp/tools/writer-profiles.mjs +1 -1
  129. package/dist/src/memory/audit.js +719 -0
  130. package/dist/src/memory/canonical-context.js +392 -13
  131. package/dist/src/memory/canonical-maintenance.js +95 -0
  132. package/dist/src/memory/cli-result.js +22 -0
  133. package/dist/src/memory/cli.js +176 -0
  134. package/dist/src/memory/context-pack.js +57 -6
  135. package/dist/src/memory/cost.js +512 -0
  136. package/dist/src/memory/firewall-classification.d.mts +7 -0
  137. package/dist/src/memory/firewall-classification.mjs +32 -0
  138. package/dist/src/memory/index.js +8 -0
  139. package/dist/src/memory/line-maintenance.js +68 -0
  140. package/dist/src/memory/maintenance-cli.js +286 -0
  141. package/dist/src/memory/maintenance-contract.js +136 -0
  142. package/dist/src/memory/maintenance-index.js +18 -0
  143. package/dist/src/memory/maintenance-owner.js +2 -0
  144. package/dist/src/memory/maintenance-record.js +138 -0
  145. package/dist/src/memory/maintenance.js +254 -0
  146. package/dist/src/memory/project-registry.js +2 -1
  147. package/dist/src/memory/provider-memory-adapter.js +154 -0
  148. package/dist/src/memory/recommend-cli.js +83 -0
  149. package/dist/src/memory/recommend.js +269 -0
  150. package/dist/src/memory/scheduled.js +81 -0
  151. package/dist/src/memory/taxonomy.js +44 -0
  152. package/dist/src/mission-protocol/codecs.js +19 -9
  153. package/dist/src/mission-protocol/worker-status.js +91 -1
  154. package/dist/src/models/config-loader.js +11 -1
  155. package/dist/src/models/model-capabilities.v1.json +74 -50
  156. package/dist/src/models/provider-policy.js +125 -62
  157. package/dist/src/models/resolver.js +45 -8
  158. package/dist/src/models/worker-installation.d.mts +8 -1
  159. package/dist/src/models/worker-installation.mjs +231 -38
  160. package/dist/src/models/wrapper-route.js +1 -1
  161. package/dist/src/output-modes/registry.js +8 -7
  162. package/dist/src/packages/adapters/git.js +99 -23
  163. package/dist/src/packages/adapters/gitea.js +8 -27
  164. package/dist/src/packages/adapters/github.js +7 -25
  165. package/dist/src/packages/registry.js +4 -4
  166. package/dist/src/plugin/metadata-validator.js +1 -1
  167. package/dist/src/process/cli-command.d.mts +5 -0
  168. package/dist/src/process/cli-command.mjs +42 -0
  169. package/dist/src/providers/deploy-version.d.mts +1 -0
  170. package/dist/src/providers/deploy-version.mjs +17 -0
  171. package/dist/src/providers/provider-definitions.js +19 -16
  172. package/dist/src/providers/skill-ownership.d.mts +11 -2
  173. package/dist/src/providers/skill-ownership.mjs +35 -17
  174. package/dist/src/rules/activation.d.mts +11 -2
  175. package/dist/src/rules/activation.mjs +82 -6
  176. package/dist/src/rules/inventory.js +1 -1
  177. package/dist/src/rules/rule-frontmatter.schema.json +2 -0
  178. package/dist/src/schema/zod-validation.d.mts +6 -0
  179. package/dist/src/schema/zod-validation.mjs +50 -0
  180. package/dist/src/serve/executor-registry.js +297 -20
  181. package/dist/src/serve/executor-token.d.mts +1 -0
  182. package/dist/src/serve/executor-token.mjs +8 -0
  183. package/dist/src/serve/shared-host-scheduler.js +1102 -31
  184. package/dist/src/serve/worker-invocation.js +124 -15
  185. package/dist/src/sessions/adapters/claude.js +19 -18
  186. package/dist/src/sessions/adapters/codex.js +10 -9
  187. package/dist/src/sessions/adapters/copilot.js +14 -13
  188. package/dist/src/sessions/adapters/cursor.js +19 -18
  189. package/dist/src/sessions/adapters/deepseek-harness.js +9 -8
  190. package/dist/src/sessions/adapters/factory.js +11 -10
  191. package/dist/src/sessions/adapters/generic.js +32 -23
  192. package/dist/src/sessions/adapters/grokbot.js +35 -35
  193. package/dist/src/sessions/adapters/hermes.js +20 -19
  194. package/dist/src/sessions/adapters/muse.js +50 -49
  195. package/dist/src/sessions/adapters/omp.js +5 -4
  196. package/dist/src/sessions/adapters/openclaw.js +30 -29
  197. package/dist/src/sessions/adapters/opencode.js +26 -26
  198. package/dist/src/sessions/adapters/openhuman.js +24 -23
  199. package/dist/src/sessions/adapters/pi.js +5 -4
  200. package/dist/src/sessions/adapters/windsurf.js +8 -8
  201. package/dist/src/sessions/analytics.js +10 -9
  202. package/dist/src/sessions/candidates.js +7 -6
  203. package/dist/src/sessions/contracts.js +63 -53
  204. package/dist/src/sessions/output-registration.js +11 -10
  205. package/dist/src/sessions/workspace-discovery.js +3 -4
  206. package/dist/src/smiths/context-pipeline/aiwg-md.js +18 -1
  207. package/dist/src/smiths/context-pipeline/claude-hook.js +46 -10
  208. package/dist/src/smiths/context-pipeline/context-file-safety.js +330 -9
  209. package/dist/src/smiths/context-pipeline/finalization.js +3 -2
  210. package/dist/src/smiths/context-pipeline/generator.js +7 -19
  211. package/dist/src/smiths/context-pipeline/legacy-inject.js +3 -10
  212. package/dist/src/smiths/context-pipeline/managed-hook.js +5 -5
  213. package/dist/src/smiths/context-pipeline/parallelism-section.js +72 -5
  214. package/dist/src/smiths/context-pipeline/workspace-context.js +110 -22
  215. package/dist/src/tracker/project-inputs.js +2 -0
  216. package/dist/src/update/checker.d.mts +4 -0
  217. package/dist/src/update/checker.mjs +14 -0
  218. package/dist/src/update/notifier.mjs +2 -4
  219. package/dist/src/writing/exemplar-selection.js +6 -6
  220. package/dist/src/writing/voice-evaluation.js +24 -23
  221. package/dist/src/writing/writer-migration.js +14 -13
  222. package/dist/src/writing/writer-profile.js +19 -18
  223. package/dist/src/writing/writing-brief.js +18 -17
  224. package/dist/src/writing/writing-receipt.js +47 -46
  225. package/package.json +5 -2
  226. package/schemas/decision/DecisionReview.schema.json +78 -1
  227. package/schemas/mission-v1.schema.json +3 -0
  228. package/tools/agents/deploy-agents.mjs +67 -39
  229. package/tools/agents/providers/antigravity.mjs +6 -1
  230. package/tools/agents/providers/base.mjs +24 -14
  231. package/tools/agents/providers/claude.mjs +6 -3
  232. package/tools/agents/providers/codex.mjs +54 -57
  233. package/tools/agents/providers/context-write.mjs +28 -0
  234. package/tools/agents/providers/copilot.mjs +13 -4
  235. package/tools/agents/providers/cursor.mjs +1 -1
  236. package/tools/agents/providers/deepseek-harness.mjs +1 -1
  237. package/tools/agents/providers/factory.mjs +7 -1
  238. package/tools/agents/providers/grok-build.mjs +18 -2
  239. package/tools/agents/providers/grokbot.mjs +1 -1
  240. package/tools/agents/providers/hermes.mjs +12 -15
  241. package/tools/agents/providers/muse-hooks.mjs +21 -14
  242. package/tools/agents/providers/muse.mjs +7 -2
  243. package/tools/agents/providers/omp.mjs +31 -5
  244. package/tools/agents/providers/opencode.mjs +14 -5
  245. package/tools/agents/providers/openhuman.mjs +1 -1
  246. package/tools/agents/providers/pi.mjs +1 -1
  247. package/tools/agents/providers/provider-prepare-coordinator.mjs +29 -9
  248. package/tools/agents/providers/rule-delivery.mjs +289 -80
  249. package/tools/agents/providers/warp.mjs +4 -1
  250. package/tools/agents/providers/windsurf.mjs +13 -3
  251. package/tools/cli/workspace-status.mjs +5 -0
  252. package/tools/commands/deploy-prompts-codex.mjs +11 -8
  253. package/tools/ralph-external/lib/codex-adapter.mjs +6 -2
  254. package/tools/ralph-external/lib/consecutive-failure-circuit-breaker.mjs +26 -0
  255. package/tools/ralph-external/lib/launcher-recovery-evidence.mjs +7 -1
  256. package/tools/ralph-external/lib/muse-adapter.mjs +12 -2
  257. package/tools/ralph-external/lib/recovery-probe.mjs +14 -4
  258. package/tools/ralph-external/lib/worker-health.mjs +1 -1
  259. package/tools/ralph-external/lib/worker-isolation.mjs +65 -9
  260. package/tools/ralph-external/process-monitor.mjs +49 -8
  261. package/tools/ralph-external/session-launcher.mjs +405 -35
  262. package/tools/skills/deploy-skills-codex.mjs +11 -7
  263. package/vscode-extension/schemas/aiwg.config.v1.json +11 -1
@@ -10,6 +10,7 @@
10
10
 
11
11
  import { readFile, stat } from 'node:fs/promises';
12
12
  import { z } from 'zod';
13
+ import { integer, dateTime } from '../../schema/zod-validation.mjs';
13
14
  import { assertNoWorkerBinding, mcpError, mcpJson } from '../helpers.mjs';
14
15
 
15
16
  const FLEET_VERSION = 'agentic-orchestration/v1';
@@ -173,15 +174,15 @@ const scopeSchema = {
173
174
  instance_id: z.string().min(1).max(255).regex(/^[^\r\n]+$/),
174
175
  agent_id: z.string().min(1).max(255).regex(/^[^\r\n]+$/),
175
176
  };
176
- const activityFilterSchema = z.object({
177
+ const activityFilterSchema = z.strictObject({
177
178
  event_name: z.string().min(1).max(255).optional(), collector: z.string().min(1).max(255).optional(),
178
179
  trust: z.string().min(1).max(255).optional(), plane: z.string().min(1).max(255).optional(),
179
180
  outcome: z.string().min(1).max(255).optional(), session_id: z.string().min(1).max(255).optional(),
180
181
  mission_id: z.string().min(1).max(255).optional(), task_id: z.string().min(1).max(255).optional(),
181
182
  tool_call_id: z.string().min(1).max(255).optional(), command_id: z.string().min(1).max(255).optional(),
182
183
  process_id: z.string().min(1).max(255).optional(), trace_id: z.string().regex(/^[0-9a-f]{32}$/).optional(),
183
- since: z.string().datetime().optional(), until: z.string().datetime().optional(), limit: z.number().int().min(1).max(1000).optional(),
184
- }).strict().optional();
184
+ since: dateTime().optional(), until: dateTime().optional(), limit: integer().min(1).max(1000).optional(),
185
+ }).optional();
185
186
 
186
187
  function scopeHeaders(args) {
187
188
  return Object.fromEntries(Object.entries(SCOPE_HEADERS).map(([key, header]) => [header, args[key]]));
@@ -206,17 +207,17 @@ export function registerAgenticSandboxToolset(server, { client = new AgenticSand
206
207
  () => client.request('/api/v2/fleet/workloads', { validate: requireInventory }));
207
208
  register('sandbox-fleet-get', { title: 'Get Agentic Sandbox fleet workload', description: 'Read one revisioned fleet workload by child identity.', inputSchema: { contract_version: z.literal(FLEET_VERSION).default(FLEET_VERSION), child_id: z.string().min(1).max(255) }, annotations: { readOnlyHint: true, destructiveHint: false } },
208
209
  ({ child_id }) => client.request(`/api/v2/fleet/workloads/${encodeURIComponent(child_id)}`, { validate: requireFleetRecord }));
209
- register('sandbox-fleet-reconcile-preview', { title: 'Preview fleet reconciliation', description: 'Compute a read-only reconciliation preview from inventory; never calls POST /reconcile.', inputSchema: { contract_version: z.literal(FLEET_VERSION).default(FLEET_VERSION), before_revision: z.number().int().min(0), child_ids: z.array(z.string().min(1).max(255)).max(1000) }, annotations: { readOnlyHint: true, destructiveHint: false } },
210
+ register('sandbox-fleet-reconcile-preview', { title: 'Preview fleet reconciliation', description: 'Compute a read-only reconciliation preview from inventory; never calls POST /reconcile.', inputSchema: { contract_version: z.literal(FLEET_VERSION).default(FLEET_VERSION), before_revision: integer().min(0), child_ids: z.array(z.string().min(1).max(255)).max(1000) }, annotations: { readOnlyHint: true, destructiveHint: false } },
210
211
  async ({ before_revision, child_ids }) => client.request('/api/v2/fleet/workloads', { validate: (value) => {
211
212
  const inventory = requireInventory(value);
212
213
  const byId = new Map(inventory.records.map((record) => [record.lineage.child_id, record]));
213
214
  return { document_type: 'reconciliation-preview', api_version: FLEET_VERSION, before_revision, inventory_revision: inventory.inventory_revision, stale: before_revision !== inventory.inventory_revision, rows: child_ids.map((child_id) => ({ child_id, present: byId.has(child_id), observed_state: byId.get(child_id)?.status?.observed_state ?? 'unknown', revision: byId.get(child_id)?.status?.revision ?? null })) };
214
215
  } }));
215
- register('sandbox-fleet-admit', { title: 'Admit Agentic Sandbox fleet workload', description: 'Mutating fleet admission; requires an exact v1 workload and confirmed=true.', inputSchema: { contract_version: z.literal(FLEET_VERSION).default(FLEET_VERSION), workload: z.record(z.unknown()), confirmed: z.boolean().default(false) }, annotations: { readOnlyHint: false, destructiveHint: true } },
216
+ register('sandbox-fleet-admit', { title: 'Admit Agentic Sandbox fleet workload', description: 'Mutating fleet admission; requires an exact v1 workload and confirmed=true.', inputSchema: { contract_version: z.literal(FLEET_VERSION).default(FLEET_VERSION), workload: z.record(z.string(), z.unknown()), confirmed: z.boolean().default(false) }, annotations: { readOnlyHint: false, destructiveHint: true } },
216
217
  ({ workload, confirmed }) => confirmed ? client.request('/api/v2/fleet/workloads', { method: 'POST', body: requireFleetRecord(workload), validate: (value) => ({ replayed: value?.replayed === true, workload: requireFleetRecord(value?.workload) }) }) : confirmationError('sandbox-fleet-admit'));
217
- register('sandbox-fleet-observe', { title: 'Record fleet workload observation', description: 'Mutating monotonic observation update; requires confirmed=true and expected revision.', inputSchema: { contract_version: z.literal(FLEET_VERSION).default(FLEET_VERSION), child_id: z.string().min(1).max(255), expected_revision: z.number().int().min(0), status: z.record(z.unknown()), runtime_identity: z.object({ session_id: z.string().optional(), task_id: z.string().optional(), command_id: z.string().optional() }).strict().optional(), confirmed: z.boolean().default(false) }, annotations: { readOnlyHint: false, destructiveHint: true } },
218
+ register('sandbox-fleet-observe', { title: 'Record fleet workload observation', description: 'Mutating monotonic observation update; requires confirmed=true and expected revision.', inputSchema: { contract_version: z.literal(FLEET_VERSION).default(FLEET_VERSION), child_id: z.string().min(1).max(255), expected_revision: integer().min(0), status: z.record(z.string(), z.unknown()), runtime_identity: z.strictObject({ session_id: z.string().optional(), task_id: z.string().optional(), command_id: z.string().optional() }).optional(), confirmed: z.boolean().default(false) }, annotations: { readOnlyHint: false, destructiveHint: true } },
218
219
  ({ child_id, expected_revision, status, runtime_identity, confirmed }) => confirmed ? client.request(`/api/v2/fleet/workloads/${encodeURIComponent(child_id)}/observations`, { method: 'POST', body: requireSafePayload({ expected_revision, status, ...(runtime_identity ? { runtime_identity } : {}) }, 'fleet observation'), validate: requireFleetRecord }) : confirmationError('sandbox-fleet-observe'));
219
- register('sandbox-fleet-reconcile', { title: 'Reconcile fleet workloads', description: 'Mutating restart reconciliation; requires confirmed=true.', inputSchema: { contract_version: z.literal(FLEET_VERSION).default(FLEET_VERSION), before_revision: z.number().int().min(0), child_ids: z.array(z.string().min(1).max(255)).max(1000), confirmed: z.boolean().default(false) }, annotations: { readOnlyHint: false, destructiveHint: true } },
220
+ register('sandbox-fleet-reconcile', { title: 'Reconcile fleet workloads', description: 'Mutating restart reconciliation; requires confirmed=true.', inputSchema: { contract_version: z.literal(FLEET_VERSION).default(FLEET_VERSION), before_revision: integer().min(0), child_ids: z.array(z.string().min(1).max(255)).max(1000), confirmed: z.boolean().default(false) }, annotations: { readOnlyHint: false, destructiveHint: true } },
220
221
  ({ before_revision, child_ids, confirmed }) => confirmed ? client.request('/api/v2/fleet/reconcile', { method: 'POST', body: { before_revision, child_ids }, validate: requireReconciliation }) : confirmationError('sandbox-fleet-reconcile'));
221
222
 
222
223
  for (const [kind, eventsRequired] of [['coverage', false], ['timeline', true]]) {
@@ -17,6 +17,7 @@
17
17
  */
18
18
 
19
19
  import { z } from 'zod';
20
+ import { integer } from '../../schema/zod-validation.mjs';
20
21
  import {
21
22
  runAiwgCli,
22
23
  loadCommandAllowList,
@@ -31,10 +32,10 @@ export function registerCommandRunTool(server) {
31
32
  description: 'Dispatch to any allow-listed AIWG CLI command (`aiwg <command> [args...]`). The full surface of ~94 commands is reachable. Destructive commands require `confirmed: true`.',
32
33
  inputSchema: {
33
34
  command: z.string().describe('Command name from `command-list` (e.g. "use", "discover", "doctor")'),
34
- args: z.array(z.string()).default([]).describe('Argument array (never shell-interpreted)'),
35
+ args: z.array(z.string()).prefault([]).describe('Argument array (never shell-interpreted)'),
35
36
  project_dir: z.string().optional().describe('Working directory for the command'),
36
37
  confirmed: z.boolean().default(false).describe('Required for destructive commands (true to proceed)'),
37
- timeout_ms: z.number().int().min(1000).max(600_000).default(120_000).describe('Timeout (1s–10min, default 2min)'),
38
+ timeout_ms: integer().min(1000).max(600_000).default(120_000).describe('Timeout (1s–10min, default 2min)'),
38
39
  },
39
40
  annotations: {
40
41
  destructiveHint: true, // conservative default; many subcommands are read-only but the surface is broad
@@ -1,102 +1,103 @@
1
1
  import { z } from 'zod';
2
+ import { integer, number } from '../../schema/zod-validation.mjs';
2
3
  import { mcpError, mcpJson } from '../helpers.mjs';
3
4
 
4
5
  const STATUS = z.enum(['success', 'abstained', 'denied', 'unavailable', 'error', 'cancelled']);
5
- const ENVELOPE = z.object({ schema: z.string() }).passthrough();
6
- const LIVE_PLAN = z.object({ mode: z.literal('live'), status: z.enum(['ready', 'skipped', 'denied']), reason: z.string(), executes: z.literal(false) }).passthrough();
7
- const PATTERN_SUMMARY = z.object({
6
+ const ENVELOPE = z.looseObject({ schema: z.string() });
7
+ const LIVE_PLAN = z.looseObject({ mode: z.literal('live'), status: z.enum(['ready', 'skipped', 'denied']), reason: z.string(), executes: z.literal(false) });
8
+ const PATTERN_SUMMARY = z.looseObject({
8
9
  id: z.string(),
9
10
  version: z.string(),
10
11
  status: z.string(),
11
12
  primitive: z.string().optional(),
12
- }).passthrough();
13
- const PATTERN_LIST = z.object({
13
+ });
14
+ const PATTERN_LIST = z.looseObject({
14
15
  schema: z.literal('aiwg-decision-pattern-list/v1'),
15
16
  patterns: z.array(PATTERN_SUMMARY),
16
- }).passthrough();
17
- const PATTERN_SHOW = z.object({
17
+ });
18
+ const PATTERN_SHOW = z.looseObject({
18
19
  schema: z.literal('aiwg-decision-pattern-show/v1'),
19
20
  pack: PATTERN_SUMMARY,
20
- inputSchema: z.unknown(),
21
- outputSchema: z.unknown(),
21
+ inputSchema: z.unknown().optional(),
22
+ outputSchema: z.unknown().optional(),
22
23
  livePlan: LIVE_PLAN,
23
- }).passthrough();
24
- const COMPACT_EVALUATION = z.object({
24
+ });
25
+ const COMPACT_EVALUATION = z.looseObject({
25
26
  status: STATUS,
26
27
  reason: z.string(),
27
- attempts: z.number(),
28
- value: z.unknown().nullable(),
29
- }).passthrough();
30
- const COMPACT_RESULT = z.object({
28
+ attempts: number(),
29
+ value: z.unknown().nullable().optional(),
30
+ });
31
+ const COMPACT_RESULT = z.looseObject({
31
32
  status: STATUS,
32
33
  rulesetStatus: z.string(),
33
34
  reason: z.string(),
34
35
  matchedRules: z.array(z.string()),
35
36
  evaluations: z.record(z.string(), COMPACT_EVALUATION),
36
- outcome: z.unknown().nullable(),
37
- }).passthrough();
38
- const EVALUATE = z.object({
37
+ outcome: z.unknown().nullable().optional(),
38
+ });
39
+ const EVALUATE = z.looseObject({
39
40
  schema: z.literal('aiwg-decision-evaluate/v1'),
40
41
  status: STATUS,
41
42
  reason: z.string(),
42
- exitCode: z.number(),
43
+ exitCode: number(),
43
44
  compact: COMPACT_RESULT.nullable().optional(),
44
- result: z.unknown().nullable(),
45
- }).passthrough();
46
- const VALIDATION = z.object({
45
+ result: z.unknown().nullable().optional(),
46
+ });
47
+ const VALIDATION = z.looseObject({
47
48
  schema: z.literal('aiwg-decision-validation/v1'),
48
49
  target: z.enum(['request', 'definition', 'ruleset', 'binding']),
49
50
  valid: z.boolean(),
50
- summary: z.object({
51
+ summary: z.looseObject({
51
52
  kind: z.string().nullable().optional(),
52
53
  apiVersion: z.string().nullable().optional(),
53
54
  id: z.string().nullable().optional(),
54
55
  version: z.string().nullable().optional(),
55
- }).passthrough(),
56
+ }),
56
57
  errors: z.array(z.string()),
57
- }).passthrough();
58
- const CAPABILITIES = z.object({
58
+ });
59
+ const CAPABILITIES = z.looseObject({
59
60
  schema: z.literal('aiwg-decision-driver-capabilities/v1'),
60
61
  enabled: z.boolean(),
61
62
  offlineReady: z.boolean(),
62
63
  primitives: z.array(z.string()),
63
- backend: z.object({ configured: z.boolean(), probed: z.boolean(), status: z.literal('not-probed') }).passthrough(),
64
- }).passthrough();
65
- const OFFLINE_RUN = z.object({
64
+ backend: z.looseObject({ configured: z.boolean(), probed: z.boolean(), status: z.literal('not-probed') }),
65
+ });
66
+ const OFFLINE_RUN = z.looseObject({
66
67
  schema: z.literal('aiwg-decision-offline-run/v1'),
67
68
  status: STATUS,
68
69
  route: z.enum(['accept', 'review', 'deny']),
69
70
  reason: z.string(),
70
- evaluations: z.array(z.object({
71
+ evaluations: z.array(z.looseObject({
71
72
  alias: z.string(),
72
73
  primitive: z.string(),
73
74
  status: z.string(),
74
75
  reason: z.string(),
75
- attempts: z.number(),
76
- value: z.unknown(),
77
- }).passthrough()),
76
+ attempts: number(),
77
+ value: z.unknown().optional(),
78
+ })),
78
79
  checks: z.array(z.unknown()),
79
- }).passthrough();
80
- const SYNTHETIC_SETUP = z.object({
80
+ });
81
+ const SYNTHETIC_SETUP = z.looseObject({
81
82
  schema: z.literal('aiwg-decision-synthetic-setup/v1'),
82
- pattern: z.object({ id: z.string(), version: z.string() }).passthrough(),
83
+ pattern: z.looseObject({ id: z.string(), version: z.string() }),
83
84
  files: z.record(z.string(), z.unknown()),
84
- }).passthrough();
85
- const ASK = z.object({
85
+ });
86
+ const ASK = z.looseObject({
86
87
  schema: z.literal('aiwg-decision-ask/v1'),
87
88
  status: z.enum(['answered', 'fallback']),
88
- answer: z.union([z.string(), z.boolean(), z.number()]).nullable(),
89
+ answer: z.union([z.string(), z.boolean(), number()]).nullable(),
89
90
  confidence: z.number().min(0).max(1).nullable(),
90
91
  probability: z.number().min(0).max(1).optional(),
91
92
  fallback: z.enum(['llm']).nullable(),
92
93
  reason: z.string(),
93
94
  model: z.string().nullable(),
94
95
  usage: z.object({
95
- inputTokens: z.number().int().nonnegative().nullable(),
96
- outputTokens: z.number().int().nonnegative().nullable(),
96
+ inputTokens: integer().nonnegative().nullable(),
97
+ outputTokens: integer().nonnegative().nullable(),
97
98
  }).nullable(),
98
- latencyMs: z.number().nonnegative(),
99
- }).passthrough();
99
+ latencyMs: number().check(z.gte(0)).meta({ type: 'number', minimum: 0 }),
100
+ });
100
101
 
101
102
  let driverPromise;
102
103
 
@@ -176,7 +177,7 @@ export function registerDecisionToolset(server) {
176
177
  description: 'Validate a request, definition, ruleset or binding without importing modules or resolving secrets.',
177
178
  inputSchema: {
178
179
  target: z.enum(['request', 'definition', 'ruleset', 'binding']),
179
- document: z.unknown().describe('Inline decision document or dispatcher request object'),
180
+ document: z.unknown().optional().describe('Inline decision document or dispatcher request object'),
180
181
  },
181
182
  annotations: { readOnlyHint: true },
182
183
  }, async ({ target, document }) => (await driver()).validateDecisionValue(target, document, 'mcp-inline'), VALIDATION);
@@ -198,12 +199,12 @@ export function registerDecisionToolset(server) {
198
199
  question: z.string().min(1),
199
200
  yes_no: z.boolean().default(false),
200
201
  choices: z.array(z.string()).min(2).max(255).optional().describe('Choice ids, each optionally written as id=description so Jev knows what the option means'),
201
- scale: z.object({ low: z.number().int(), high: z.number().int() }).optional(),
202
+ scale: z.object({ low: integer(), high: integer() }).optional(),
202
203
  context: z.string().optional(),
203
204
  threshold: z.number().min(0).max(1).default(0.8),
204
- timeout_ms: z.number().int().positive().default(15000),
205
- passes: z.number().int().positive().optional(),
206
- escalation_passes: z.number().int().positive().optional(),
205
+ timeout_ms: integer().positive().default(15000),
206
+ passes: integer().positive().optional(),
207
+ escalation_passes: integer().positive().optional(),
207
208
  caller: z.string().optional().describe('Optional decision-point attribution tag, recorded in the decision ledger (#2946)'),
208
209
  },
209
210
  annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: true },
@@ -6,12 +6,12 @@
6
6
  *
7
7
  * - discover (cross-type ranked search)
8
8
  * - skill-list (enumerate canonical skill corpus)
9
- * - skill-show (fetch SKILL.md body)
9
+ * - skill-show (metadata card + drill-ins)
10
10
  * - command-list (enumerate CLI commands)
11
- * - command-show (fetch command definition)
11
+ * - command-show (metadata card + drill-ins)
12
12
  * - rule-list (enumerate rules)
13
- * - rule-show (fetch rule body)
14
- * - agent-show (fetch agent definition; agent-list pre-exists)
13
+ * - rule-show (metadata card + drill-ins)
14
+ * - agent-show (metadata card + drill-ins; agent-list pre-exists)
15
15
  * - template-list (enumerate templates)
16
16
  * - template-show (fetch raw template body)
17
17
  *
@@ -22,10 +22,33 @@
22
22
  */
23
23
 
24
24
  import { z } from 'zod';
25
+ import { integer } from '../../schema/zod-validation.mjs';
25
26
  import { runAiwgCli, mcpError, mcpJson, AIWG_ROOT } from '../helpers.mjs';
26
27
  import path from 'node:path';
27
28
  import { pinContainedRoot, readContainedFile, listContainedFiles, validateContainedPath } from '../../utils/contained-filesystem.mjs';
28
29
 
30
+ /** Shared CLI/MCP drill-in vocabulary for all discovery cards. */
31
+ export const showDrillInSchema = {
32
+ body: z.boolean().optional().describe('Fetch the full authored body'),
33
+ section: z.array(z.string()).optional().describe('Exact headings (case-insensitive fallback); repeatable'),
34
+ rules: z.boolean().optional().describe('Show governing rule summaries and required checks'),
35
+ with_rule_bodies: z.boolean().optional().describe('Include full governing rule bodies'),
36
+ bound_rule_bodies: z.boolean().optional().describe('Legacy alias for with_rule_bodies'),
37
+ resources: z.boolean().optional().describe('List companion resources'),
38
+ resource: z.string().optional().describe('Fetch one resource path from the card'),
39
+ };
40
+ export function showDrillInArgs(input) {
41
+ return [
42
+ ...(input.body ? ['--body'] : []),
43
+ ...(input.section ?? []).flatMap(heading => ['--section', heading]),
44
+ ...(input.rules ? ['--rules'] : []),
45
+ ...(input.with_rule_bodies ? ['--with-rule-bodies'] : []),
46
+ ...(input.bound_rule_bodies ? ['--bound-rule-bodies'] : []),
47
+ ...(input.resources ? ['--resources'] : []),
48
+ ...(input.resource ? ['--resource', input.resource] : []),
49
+ ];
50
+ }
51
+
29
52
  /**
30
53
  * Register discovery tools on the MCP server.
31
54
  *
@@ -42,7 +65,7 @@ export function registerDiscoveryTools(server, { corpusStore } = {}) {
42
65
  inputSchema: {
43
66
  phrase: z.string().describe('Natural-language capability description (e.g. "create intake form")'),
44
67
  type: z.enum(['skill', 'agent', 'command', 'rule', 'flow', 'runbook', 'template', 'behavior']).optional().describe('Restrict to one artifact type'),
45
- limit: z.number().int().min(1).max(50).default(5).describe('Maximum results (default 5)'),
68
+ limit: integer().min(1).max(50).default(5).describe('Maximum results (default 5)'),
46
69
  },
47
70
  annotations: { readOnlyHint: true, openWorldHint: false },
48
71
  }, async ({ phrase, type, limit }) => {
@@ -67,7 +90,7 @@ export function registerDiscoveryTools(server, { corpusStore } = {}) {
67
90
  description: 'Enumerate available AIWG skills from the canonical corpus. Optional filter by name pattern.',
68
91
  inputSchema: {
69
92
  filter: z.string().optional().describe('Substring or glob filter on skill name'),
70
- limit: z.number().int().min(1).max(500).default(50).describe('Maximum results'),
93
+ limit: integer().min(1).max(500).default(50).describe('Maximum results'),
71
94
  },
72
95
  annotations: { readOnlyHint: true },
73
96
  }, async ({ filter, limit }) => {
@@ -83,15 +106,15 @@ export function registerDiscoveryTools(server, { corpusStore } = {}) {
83
106
 
84
107
  server.registerTool('skill-show', {
85
108
  title: 'Show AIWG Skill',
86
- description: 'Fetch the full body of an AIWG SKILL.md by name. Returns path + content envelope.',
109
+ description: 'Return the AIWG metadata card with governing rules, outline, resources, and drill-in guidance. Use body/section for authored content.',
87
110
  inputSchema: {
88
- bound_rule_bodies: z.boolean().optional().describe('Include full bound rule bodies'),
111
+ ...showDrillInSchema,
89
112
  name: z.string().describe('Skill name (slug; e.g. "intake-wizard")'),
90
113
  },
91
114
  annotations: { readOnlyHint: true },
92
- }, async ({ name, bound_rule_bodies }) => {
115
+ }, async ({ name, ...drillIn }) => {
93
116
  try {
94
- const { stdout, code, stderr } = await runAiwgCli(['show', 'skill', name, '--json', ...(bound_rule_bodies ? ['--bound-rule-bodies'] : [])]);
117
+ const { stdout, code, stderr } = await runAiwgCli(['show', 'skill', name, '--json', ...showDrillInArgs(drillIn)]);
95
118
  if (code !== 0) return mcpError(`skill-show failed: ${stderr}`);
96
119
  return mcpJson(stdout);
97
120
  } catch (err) {
@@ -122,14 +145,15 @@ export function registerDiscoveryTools(server, { corpusStore } = {}) {
122
145
 
123
146
  server.registerTool('command-show', {
124
147
  title: 'Show AIWG CLI Command Definition',
125
- description: 'Fetch the full spec/help text for a specific `aiwg` CLI command.',
148
+ description: 'Return the AIWG metadata card with governing rules, outline, resources, and drill-in guidance. Use body/section for authored content.',
126
149
  inputSchema: {
150
+ ...showDrillInSchema,
127
151
  name: z.string().describe('Command name (e.g. "use", "discover", "ralph")'),
128
152
  },
129
153
  annotations: { readOnlyHint: true },
130
- }, async ({ name }) => {
154
+ }, async ({ name, ...drillIn }) => {
131
155
  try {
132
- const { stdout, code, stderr } = await runAiwgCli(['show', 'command', name, '--json']);
156
+ const { stdout, code, stderr } = await runAiwgCli(['show', 'command', name, '--json', ...showDrillInArgs(drillIn)]);
133
157
  if (code !== 0) return mcpError(`command-show failed: ${stderr}`);
134
158
  return mcpJson(stdout);
135
159
  } catch (err) {
@@ -166,7 +190,7 @@ export function registerDiscoveryTools(server, { corpusStore } = {}) {
166
190
  description: 'Enumerate AIWG enforcement rules (e.g. skill-discovery, no-attribution, anti-laziness, citation-policy). Top-7 CRITICAL/HIGH rules are inlined into Hermes AGENTS.md priming (skill-discovery added #1347); this tool reaches the rest.',
167
191
  inputSchema: {
168
192
  filter: z.string().optional().describe('Substring filter on rule name'),
169
- limit: z.number().int().min(1).max(200).default(50),
193
+ limit: integer().min(1).max(200).default(50),
170
194
  },
171
195
  annotations: { readOnlyHint: true },
172
196
  }, async ({ filter, limit }) => {
@@ -182,14 +206,15 @@ export function registerDiscoveryTools(server, { corpusStore } = {}) {
182
206
 
183
207
  server.registerTool('rule-show', {
184
208
  title: 'Show AIWG Rule',
185
- description: 'Fetch the full body of a specific AIWG rule by name.',
209
+ description: 'Return the AIWG metadata card with governing rules, outline, resources, and drill-in guidance. Use body/section for authored content.',
186
210
  inputSchema: {
211
+ ...showDrillInSchema,
187
212
  name: z.string().describe('Rule name (e.g. "no-attribution", "anti-laziness")'),
188
213
  },
189
214
  annotations: { readOnlyHint: true },
190
- }, async ({ name }) => {
215
+ }, async ({ name, ...drillIn }) => {
191
216
  try {
192
- const { stdout, code, stderr } = await runAiwgCli(['show', 'rule', name, '--json']);
217
+ const { stdout, code, stderr } = await runAiwgCli(['show', 'rule', name, '--json', ...showDrillInArgs(drillIn)]);
193
218
  if (code !== 0) return mcpError(`rule-show failed: ${stderr}`);
194
219
  return mcpJson(stdout);
195
220
  } catch (err) {
@@ -202,15 +227,15 @@ export function registerDiscoveryTools(server, { corpusStore } = {}) {
202
227
  // ============================================================
203
228
  server.registerTool('agent-show', {
204
229
  title: 'Show AIWG Agent Definition',
205
- description: 'Fetch the full agent definition (system prompt + frontmatter) by name.',
230
+ description: 'Return the AIWG metadata card with governing rules, outline, resources, and drill-in guidance. Use body/section for authored content.',
206
231
  inputSchema: {
207
- bound_rule_bodies: z.boolean().optional().describe('Include full bound rule bodies'),
232
+ ...showDrillInSchema,
208
233
  name: z.string().describe('Agent name (e.g. "test-engineer", "security-auditor")'),
209
234
  },
210
235
  annotations: { readOnlyHint: true },
211
- }, async ({ name, bound_rule_bodies }) => {
236
+ }, async ({ name, ...drillIn }) => {
212
237
  try {
213
- const { stdout, code, stderr } = await runAiwgCli(['show', 'agent', name, '--json', ...(bound_rule_bodies ? ['--bound-rule-bodies'] : [])]);
238
+ const { stdout, code, stderr } = await runAiwgCli(['show', 'agent', name, '--json', ...showDrillInArgs(drillIn)]);
214
239
  if (code !== 0) return mcpError(`agent-show failed: ${stderr}`);
215
240
  return mcpJson(stdout);
216
241
  } catch (err) {
@@ -9,6 +9,8 @@
9
9
  */
10
10
 
11
11
  import { z } from 'zod';
12
+ import { integer } from '../../schema/zod-validation.mjs';
13
+ import { showDrillInSchema, showDrillInArgs } from './discovery.mjs';
12
14
  import { parse as parseYaml } from 'yaml';
13
15
  import fs from 'node:fs/promises';
14
16
  import path from 'node:path';
@@ -157,28 +159,23 @@ export function registerFlowToolset(server) {
157
159
 
158
160
  server.registerTool('flow-show', {
159
161
  title: 'Show AIWG Flow',
160
- description: 'Fetch a declarative Flow playbook by name, including parsed step summary and the wrapper skill path when present.',
162
+ description: 'Return the same metadata card as aiwg show flow, with optional body, section, rules, and resource drill-ins.',
161
163
  inputSchema: {
164
+ ...showDrillInSchema,
162
165
  name: z.string().describe('Flow name or playbook file name (e.g. flow-release)'),
163
- bound_rule_bodies: z.boolean().optional().describe('Include full bound rule bodies'),
164
166
  framework: z.string().optional().describe('Optional framework disambiguator'),
165
167
  },
166
168
  annotations: { readOnlyHint: true, openWorldHint: false },
167
- }, async ({ name, framework, bound_rule_bodies }) => {
169
+ }, async ({ name, framework, ...drillIn }) => {
168
170
  try {
169
- const flow = await findFlow(name, framework);
170
- if (!flow) return mcpError(`flow-show: flow not found: ${name}`);
171
- flow.wrapper_skill.exists = await pathExists(flow.wrapper_skill.path);
171
+ const flow = framework ? await findFlow(name, framework) : null;
172
+ if (framework && !flow) return mcpError(`flow-show: flow not found: ${name}`);
172
173
  const { stdout, stderr, code } = await runAiwgCli([
173
- 'show', 'flow', flow.path, '--json',
174
- ...(bound_rule_bodies ? ['--bound-rule-bodies'] : []),
174
+ 'show', 'flow', flow?.path ?? name, '--json',
175
+ ...showDrillInArgs(drillIn),
175
176
  ]);
176
- if (code !== 0) return mcpError(`flow-show binding lookup failed: ${stderr}`);
177
- const shown = JSON.parse(stdout);
178
- return mcpJson({ ...flow, ...(shown.bound_rules ? { bound_rules: shown.bound_rules,
179
- ...(shown.required_rule_checks ? { required_rule_checks: shown.required_rule_checks } : {}),
180
- ...(shown.rule_stats ? { rule_stats: shown.rule_stats } : {}),
181
- ...(shown.rule_check_obligation ? { rule_check_obligation: shown.rule_check_obligation } : {}) } : {}) });
177
+ if (code !== 0) return mcpError(`flow-show lookup failed: ${stderr}`);
178
+ return mcpJson(stdout);
182
179
  } catch (err) {
183
180
  return mcpError(`flow-show: ${err.message}`);
184
181
  }
@@ -191,7 +188,7 @@ export function registerFlowToolset(server) {
191
188
  name: z.string().describe('Flow name (e.g. flow-release)'),
192
189
  framework: z.string().optional().describe('Optional framework disambiguator'),
193
190
  project_dir: z.string().optional().describe('Project directory where the Flow should operate'),
194
- args: z.array(z.string()).default([]).describe('Operator arguments to pass conceptually to the wrapper skill'),
191
+ args: z.array(z.string()).prefault([]).describe('Operator arguments to pass conceptually to the wrapper skill'),
195
192
  confirmed: z.boolean().default(false).describe('Required because Flows can run shell commands and write artifacts'),
196
193
  },
197
194
  annotations: { destructiveHint: true, openWorldHint: true },
@@ -246,15 +243,16 @@ export function registerMissionToolset(server) {
246
243
  session_id: z.string().describe('Existing Mission Control session id from mc-start / mc-list'),
247
244
  objective: z.string().describe('Mission objective'),
248
245
  completion: z.string().describe('Measurable completion criterion'),
249
- max_iterations: z.number().int().positive().max(Number.MAX_SAFE_INTEGER).optional().describe('Ralph iteration cap'),
250
- max_total_tokens: z.number().int().positive().max(Number.MAX_SAFE_INTEGER).optional().describe('Hard cumulative token ceiling'),
251
- max_output_tokens: z.number().int().positive().max(Number.MAX_SAFE_INTEGER).optional().describe('Hard cumulative output-token ceiling'),
252
- max_tool_calls: z.number().int().positive().max(Number.MAX_SAFE_INTEGER).optional().describe('Hard cumulative tool-call ceiling'),
246
+ max_iterations: integer().positive().max(Number.MAX_SAFE_INTEGER).optional().describe('Ralph iteration cap'),
247
+ max_total_tokens: integer().positive().max(Number.MAX_SAFE_INTEGER).optional().describe('Hard cumulative token ceiling'),
248
+ max_output_tokens: integer().positive().max(Number.MAX_SAFE_INTEGER).optional().describe('Hard cumulative output-token ceiling'),
249
+ max_tool_calls: integer().positive().max(Number.MAX_SAFE_INTEGER).optional().describe('Hard cumulative tool-call ceiling'),
253
250
  max_total_cost: z.number().positive().finite().optional().describe('Hard cumulative provider-reported spend ceiling'),
254
251
  max_wall_clock_minutes: z.number().positive().finite().optional().describe('Hard cumulative runtime ceiling'),
255
- exploration_quota: z.number().int().positive().max(Number.MAX_SAFE_INTEGER).optional().describe('Require structural variant after this many flat cycles (off unless declared; no default K)'),
252
+ exploration_quota: integer().positive().max(Number.MAX_SAFE_INTEGER).optional().describe('Require structural variant after this many flat cycles (off unless declared; no default K)'),
256
253
  budget_stop_policy: z.enum(['completion-wins', 'budget-wins']).optional().describe('Stop semantics when the completing iteration crosses a ceiling (default: completion-wins)'),
257
254
  project_dir: z.string().optional().describe('Project directory for CLI dispatch'),
255
+ worker_dispatch: z.string().optional().describe('Absolute prepared managed worker dispatch JSON path inside the project'),
258
256
  confirmed: z.boolean().default(false).describe('Required for durable/long-running mission dispatch'),
259
257
  },
260
258
  annotations: { destructiveHint: true, openWorldHint: true },
@@ -270,6 +268,7 @@ export function registerMissionToolset(server) {
270
268
  max_wall_clock_minutes,
271
269
  exploration_quota,
272
270
  budget_stop_policy,
271
+ worker_dispatch,
273
272
  project_dir,
274
273
  confirmed,
275
274
  }) => {
@@ -289,6 +288,7 @@ export function registerMissionToolset(server) {
289
288
  if (max_wall_clock_minutes) cliArgs.push('--max-wall-clock-minutes', String(max_wall_clock_minutes));
290
289
  if (exploration_quota) cliArgs.push('--exploration-quota', String(exploration_quota));
291
290
  if (budget_stop_policy) cliArgs.push('--budget-stop-policy', budget_stop_policy);
291
+ if (worker_dispatch) cliArgs.push('--worker-dispatch', worker_dispatch);
292
292
  const { stdout, stderr, code } = await runAiwgCli(
293
293
  cliArgs,
294
294
  { cwd: project_dir, timeoutMs: 30_000 },
@@ -335,7 +335,7 @@ export function registerWorkerResolveTool(server) {
335
335
  server.registerTool('worker-resolve', {
336
336
  title: 'Resolve Worker Invocation',
337
337
  description: 'Resolve a nonlaunching qualified worker plan without Mission or MC state.',
338
- inputSchema: z.object({
338
+ inputSchema: z.strictObject({
339
339
  role: z.enum(['efficiency', 'coding', 'reasoning']),
340
340
  task: z.string().min(1),
341
341
  group: z.string().min(1).regex(/^[a-z][a-z0-9-]{0,62}$/),
@@ -345,7 +345,7 @@ export function registerWorkerResolveTool(server) {
345
345
  transport: z.enum(['shell', 'mcp']).default('shell'),
346
346
  format: z.enum(['shell', 'json']).optional(),
347
347
  project_dir: z.string().min(1).optional(),
348
- }).strict(),
348
+ }),
349
349
  annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: false },
350
350
  }, async input => {
351
351
  try {
@@ -15,6 +15,7 @@
15
15
  */
16
16
 
17
17
  import { z } from 'zod';
18
+ import { integer } from '../../schema/zod-validation.mjs';
18
19
  import { runAiwgCli, mcpError, mcpJson } from '../helpers.mjs';
19
20
  import { registerFlowToolset, registerMissionToolset } from './orchestration.mjs';
20
21
  import { registerWorkerInvokeToolset, WORKERS_TOOLSET_NAME } from './worker-invoke.mjs';
@@ -187,7 +188,7 @@ function registerActivityLogToolset(server) {
187
188
  inputSchema: {
188
189
  since: z.string().optional().describe('Filter by date YYYY-MM-DD'),
189
190
  operation: z.string().optional().describe('Filter by operation token (e.g. "create", "deploy")'),
190
- limit: z.number().int().min(1).max(1000).default(100),
191
+ limit: integer().min(1).max(1000).default(100),
191
192
  },
192
193
  readOnly: true,
193
194
  buildArgs: ({ since, operation, limit }) => {
@@ -256,7 +257,7 @@ function registerIndexToolset(server) {
256
257
  inputSchema: {
257
258
  keyword: z.string().optional().describe('Keyword query'),
258
259
  type: z.string().optional().describe('Artifact type filter'),
259
- limit: z.number().int().min(1).max(500).default(50),
260
+ limit: integer().min(1).max(500).default(50),
260
261
  },
261
262
  readOnly: true,
262
263
  buildArgs: ({ keyword, type, limit }) => {
@@ -310,7 +311,7 @@ function registerRalphToolset(server) {
310
311
  inputSchema: {
311
312
  task: z.string().describe('Task description'),
312
313
  completion: z.string().describe('Measurable completion criteria (verification command)'),
313
- max_cycles: z.number().int().min(1).max(500).default(20),
314
+ max_cycles: integer().min(1).max(500).default(20),
314
315
  confirmed: z.boolean().default(false).describe('Required (Ralph is long-running)'),
315
316
  },
316
317
  annotations: { destructiveHint: true },
@@ -415,13 +416,13 @@ function registerMcToolset(server) {
415
416
  session_id: z.string().describe('Session id'),
416
417
  objective: z.string().describe('Mission objective'),
417
418
  completion: z.string().optional().describe('Completion criteria'),
418
- max_iterations: z.number().int().positive().max(Number.MAX_SAFE_INTEGER).optional().describe('Ralph iteration cap'),
419
- max_total_tokens: z.number().int().positive().max(Number.MAX_SAFE_INTEGER).optional().describe('Hard cumulative token ceiling'),
420
- max_output_tokens: z.number().int().positive().max(Number.MAX_SAFE_INTEGER).optional().describe('Hard cumulative output-token ceiling'),
421
- max_tool_calls: z.number().int().positive().max(Number.MAX_SAFE_INTEGER).optional().describe('Hard cumulative tool-call ceiling'),
419
+ max_iterations: integer().positive().max(Number.MAX_SAFE_INTEGER).optional().describe('Ralph iteration cap'),
420
+ max_total_tokens: integer().positive().max(Number.MAX_SAFE_INTEGER).optional().describe('Hard cumulative token ceiling'),
421
+ max_output_tokens: integer().positive().max(Number.MAX_SAFE_INTEGER).optional().describe('Hard cumulative output-token ceiling'),
422
+ max_tool_calls: integer().positive().max(Number.MAX_SAFE_INTEGER).optional().describe('Hard cumulative tool-call ceiling'),
422
423
  max_total_cost: z.number().positive().finite().optional().describe('Hard cumulative provider-reported spend ceiling'),
423
424
  max_wall_clock_minutes: z.number().positive().finite().optional().describe('Hard cumulative runtime ceiling'),
424
- exploration_quota: z.number().int().positive().max(Number.MAX_SAFE_INTEGER).optional().describe('Require structural variant after this many flat cycles (off unless declared; no default K)'),
425
+ exploration_quota: integer().positive().max(Number.MAX_SAFE_INTEGER).optional().describe('Require structural variant after this many flat cycles (off unless declared; no default K)'),
425
426
  budget_stop_policy: z.enum(['completion-wins', 'budget-wins']).optional().describe('Stop semantics when the completing iteration crosses a ceiling (default: completion-wins)'),
426
427
  },
427
428
  buildArgs: ({