@aiwg/cli 2026.10.5 → 2026.10.6

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 (212) 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 +3 -1
  6. package/dist/src/artifacts/browser-export.js +1 -0
  7. package/dist/src/artifacts/citation-parser.js +8 -1
  8. package/dist/src/artifacts/cli.js +57 -6
  9. package/dist/src/artifacts/fortemi-core-query-adapter.js +2 -0
  10. package/dist/src/artifacts/fortemi-core-sync.js +26 -8
  11. package/dist/src/artifacts/graph-query.js +18 -8
  12. package/dist/src/artifacts/index-adapters.js +339 -0
  13. package/dist/src/artifacts/index-builder.js +143 -14
  14. package/dist/src/artifacts/index-files.js +15 -4
  15. package/dist/src/artifacts/index-reader.js +44 -0
  16. package/dist/src/artifacts/index-refresh.js +114 -55
  17. package/dist/src/artifacts/index-status.js +20 -5
  18. package/dist/src/artifacts/memory-maintenance.js +503 -0
  19. package/dist/src/artifacts/prebuilt-relations.js +3 -1
  20. package/dist/src/artifacts/query-engine.js +263 -108
  21. package/dist/src/artifacts/relations-builder.js +2 -2
  22. package/dist/src/artifacts/source-graph.js +2 -2
  23. package/dist/src/artifacts/types.js +9 -1
  24. package/dist/src/cli/handlers/decision.js +19 -1
  25. package/dist/src/cli/handlers/guided-setup.js +470 -0
  26. package/dist/src/cli/handlers/help.js +2 -2
  27. package/dist/src/cli/handlers/housekeeper.js +1110 -0
  28. package/dist/src/cli/handlers/index.js +4 -2
  29. package/dist/src/cli/handlers/init.js +41 -6
  30. package/dist/src/cli/handlers/local-executor.js +5 -3
  31. package/dist/src/cli/handlers/mc.js +509 -53
  32. package/dist/src/cli/handlers/models.js +32 -2
  33. package/dist/src/cli/handlers/ralph-launcher.js +76 -4
  34. package/dist/src/cli/handlers/rules.js +1 -1
  35. package/dist/src/cli/handlers/script-runner.js +73 -2
  36. package/dist/src/cli/handlers/serve.js +5 -3
  37. package/dist/src/cli/handlers/sessions.js +1 -0
  38. package/dist/src/cli/handlers/setup.js +428 -1
  39. package/dist/src/cli/handlers/skill-lint.js +1 -1
  40. package/dist/src/cli/handlers/subcommands.js +118 -8
  41. package/dist/src/cli/handlers/use.js +279 -93
  42. package/dist/src/cli/handlers/workspace.js +3 -1
  43. package/dist/src/cli/prompt-utils.js +8 -0
  44. package/dist/src/cli/router.js +16 -1
  45. package/dist/src/config/aiwg-config.js +42 -0
  46. package/dist/src/config/cli.js +7 -3
  47. package/dist/src/config/decision-config.js +14 -1
  48. package/dist/src/config/native-sandbox-warnings.js +25 -0
  49. package/dist/src/contributors/validation.js +6 -5
  50. package/dist/src/decision/admission.js +7 -3
  51. package/dist/src/decision/benchmark.js +469 -0
  52. package/dist/src/decision/ledger.js +22 -3
  53. package/dist/src/decision/pricing.js +147 -0
  54. package/dist/src/decision/qualification/gate-evidence.js +18 -15
  55. package/dist/src/decision/qualification/load-staged.js +539 -0
  56. package/dist/src/decision/qualification/load.js +109 -33
  57. package/dist/src/decision/qualification/runner.js +5 -2
  58. package/dist/src/decision/review/service.js +6 -4
  59. package/dist/src/decision/review/validate.js +23 -2
  60. package/dist/src/decision/savings.js +8 -3
  61. package/dist/src/discovery/index.js +492 -0
  62. package/dist/src/discovery/interview.js +233 -0
  63. package/dist/src/discovery/plan-apply.js +571 -0
  64. package/dist/src/discovery/plan-store.js +171 -0
  65. package/dist/src/discovery/plan-types.js +2 -0
  66. package/dist/src/discovery/plan-validation.js +139 -0
  67. package/dist/src/discovery/types.js +2 -0
  68. package/dist/src/extensions/commands/definitions.js +49 -9
  69. package/dist/src/extensions/manifest.js +71 -44
  70. package/dist/src/extensions/project-local-discovery.js +1 -1
  71. package/dist/src/extensions/project-quickref.js +18 -17
  72. package/dist/src/extensions/validation.js +32 -29
  73. package/dist/src/housekeeper/daemon-config.js +148 -0
  74. package/dist/src/housekeeper/ipc.js +84 -0
  75. package/dist/src/housekeeper/lifecycle.js +148 -0
  76. package/dist/src/housekeeper/platform.js +35 -0
  77. package/dist/src/housekeeper/status.js +70 -0
  78. package/dist/src/housekeeper/units.js +114 -0
  79. package/dist/src/jobs/flow.js +22 -21
  80. package/dist/src/lint/rule-activation.js +20 -5
  81. package/dist/src/lint/runner.js +1 -1
  82. package/dist/src/mcp/cli.mjs +5 -6
  83. package/dist/src/mcp/config-file.mjs +6 -2
  84. package/dist/src/mcp/config-layers.mjs +23 -7
  85. package/dist/src/mcp/profiles.js +18 -31
  86. package/dist/src/mcp/profiles.mjs +18 -32
  87. package/dist/src/mcp/registry.js +7 -27
  88. package/dist/src/mcp/registry.mjs +7 -28
  89. package/dist/src/mcp/server.mjs +34 -1
  90. package/dist/src/mcp/tools/agentic-sandbox.mjs +8 -7
  91. package/dist/src/mcp/tools/command-run.mjs +3 -2
  92. package/dist/src/mcp/tools/decision.mjs +49 -48
  93. package/dist/src/mcp/tools/discovery.mjs +46 -21
  94. package/dist/src/mcp/tools/orchestration.mjs +22 -22
  95. package/dist/src/mcp/tools/subsystems.mjs +9 -8
  96. package/dist/src/mcp/tools/worker-invoke.mjs +17 -4
  97. package/dist/src/mcp/tools/writer-profiles.mjs +1 -1
  98. package/dist/src/memory/audit.js +719 -0
  99. package/dist/src/memory/canonical-context.js +392 -13
  100. package/dist/src/memory/canonical-maintenance.js +95 -0
  101. package/dist/src/memory/cli-result.js +22 -0
  102. package/dist/src/memory/cli.js +176 -0
  103. package/dist/src/memory/context-pack.js +57 -6
  104. package/dist/src/memory/cost.js +512 -0
  105. package/dist/src/memory/firewall-classification.d.mts +7 -0
  106. package/dist/src/memory/firewall-classification.mjs +32 -0
  107. package/dist/src/memory/index.js +8 -0
  108. package/dist/src/memory/line-maintenance.js +68 -0
  109. package/dist/src/memory/maintenance-cli.js +286 -0
  110. package/dist/src/memory/maintenance-contract.js +136 -0
  111. package/dist/src/memory/maintenance-index.js +18 -0
  112. package/dist/src/memory/maintenance-owner.js +2 -0
  113. package/dist/src/memory/maintenance-record.js +138 -0
  114. package/dist/src/memory/maintenance.js +254 -0
  115. package/dist/src/memory/provider-memory-adapter.js +154 -0
  116. package/dist/src/memory/recommend-cli.js +83 -0
  117. package/dist/src/memory/recommend.js +269 -0
  118. package/dist/src/memory/scheduled.js +81 -0
  119. package/dist/src/memory/taxonomy.js +44 -0
  120. package/dist/src/mission-protocol/codecs.js +19 -9
  121. package/dist/src/models/config-loader.js +11 -1
  122. package/dist/src/models/model-capabilities.v1.json +74 -50
  123. package/dist/src/models/provider-policy.js +125 -62
  124. package/dist/src/models/resolver.js +45 -8
  125. package/dist/src/models/worker-installation.d.mts +7 -0
  126. package/dist/src/models/worker-installation.mjs +169 -37
  127. package/dist/src/models/wrapper-route.js +1 -1
  128. package/dist/src/output-modes/registry.js +8 -7
  129. package/dist/src/plugin/metadata-validator.js +1 -1
  130. package/dist/src/providers/deploy-version.d.mts +1 -0
  131. package/dist/src/providers/deploy-version.mjs +17 -0
  132. package/dist/src/providers/provider-definitions.js +19 -16
  133. package/dist/src/providers/skill-ownership.d.mts +11 -2
  134. package/dist/src/providers/skill-ownership.mjs +35 -17
  135. package/dist/src/rules/activation.d.mts +11 -2
  136. package/dist/src/rules/activation.mjs +82 -6
  137. package/dist/src/rules/inventory.js +1 -1
  138. package/dist/src/rules/rule-frontmatter.schema.json +2 -0
  139. package/dist/src/schema/zod-validation.d.mts +6 -0
  140. package/dist/src/schema/zod-validation.mjs +50 -0
  141. package/dist/src/serve/executor-registry.js +297 -20
  142. package/dist/src/serve/executor-token.d.mts +1 -0
  143. package/dist/src/serve/executor-token.mjs +8 -0
  144. package/dist/src/serve/shared-host-scheduler.js +1102 -31
  145. package/dist/src/serve/worker-invocation.js +114 -15
  146. package/dist/src/sessions/adapters/claude.js +19 -18
  147. package/dist/src/sessions/adapters/codex.js +10 -9
  148. package/dist/src/sessions/adapters/copilot.js +14 -13
  149. package/dist/src/sessions/adapters/cursor.js +19 -18
  150. package/dist/src/sessions/adapters/deepseek-harness.js +9 -8
  151. package/dist/src/sessions/adapters/factory.js +11 -10
  152. package/dist/src/sessions/adapters/generic.js +32 -23
  153. package/dist/src/sessions/adapters/grokbot.js +35 -35
  154. package/dist/src/sessions/adapters/hermes.js +20 -19
  155. package/dist/src/sessions/adapters/muse.js +50 -49
  156. package/dist/src/sessions/adapters/omp.js +5 -4
  157. package/dist/src/sessions/adapters/openclaw.js +30 -29
  158. package/dist/src/sessions/adapters/opencode.js +26 -26
  159. package/dist/src/sessions/adapters/openhuman.js +24 -23
  160. package/dist/src/sessions/adapters/pi.js +5 -4
  161. package/dist/src/sessions/adapters/windsurf.js +8 -8
  162. package/dist/src/sessions/analytics.js +10 -9
  163. package/dist/src/sessions/candidates.js +7 -6
  164. package/dist/src/sessions/contracts.js +63 -53
  165. package/dist/src/sessions/output-registration.js +11 -10
  166. package/dist/src/sessions/workspace-discovery.js +3 -4
  167. package/dist/src/smiths/context-pipeline/aiwg-md.js +18 -1
  168. package/dist/src/smiths/context-pipeline/claude-hook.js +42 -6
  169. package/dist/src/smiths/context-pipeline/parallelism-section.js +72 -5
  170. package/dist/src/smiths/context-pipeline/workspace-context.js +106 -10
  171. package/dist/src/update/checker.d.mts +4 -0
  172. package/dist/src/update/checker.mjs +14 -0
  173. package/dist/src/writing/exemplar-selection.js +6 -6
  174. package/dist/src/writing/voice-evaluation.js +24 -23
  175. package/dist/src/writing/writer-migration.js +14 -13
  176. package/dist/src/writing/writer-profile.js +19 -18
  177. package/dist/src/writing/writing-brief.js +18 -17
  178. package/dist/src/writing/writing-receipt.js +47 -46
  179. package/package.json +5 -2
  180. package/schemas/decision/DecisionReview.schema.json +78 -1
  181. package/schemas/mission-v1.schema.json +3 -0
  182. package/tools/agents/deploy-agents.mjs +67 -39
  183. package/tools/agents/providers/antigravity.mjs +6 -1
  184. package/tools/agents/providers/base.mjs +19 -13
  185. package/tools/agents/providers/claude.mjs +1 -1
  186. package/tools/agents/providers/codex.mjs +50 -56
  187. package/tools/agents/providers/copilot.mjs +8 -2
  188. package/tools/agents/providers/cursor.mjs +1 -1
  189. package/tools/agents/providers/deepseek-harness.mjs +1 -1
  190. package/tools/agents/providers/factory.mjs +7 -1
  191. package/tools/agents/providers/grok-build.mjs +18 -2
  192. package/tools/agents/providers/grokbot.mjs +1 -1
  193. package/tools/agents/providers/hermes.mjs +7 -13
  194. package/tools/agents/providers/muse-hooks.mjs +21 -14
  195. package/tools/agents/providers/muse.mjs +7 -2
  196. package/tools/agents/providers/omp.mjs +28 -4
  197. package/tools/agents/providers/opencode.mjs +14 -5
  198. package/tools/agents/providers/openhuman.mjs +1 -1
  199. package/tools/agents/providers/pi.mjs +1 -1
  200. package/tools/agents/providers/provider-prepare-coordinator.mjs +29 -9
  201. package/tools/agents/providers/rule-delivery.mjs +263 -71
  202. package/tools/agents/providers/windsurf.mjs +7 -0
  203. package/tools/cli/workspace-status.mjs +5 -0
  204. package/tools/commands/deploy-prompts-codex.mjs +11 -8
  205. package/tools/ralph-external/lib/codex-adapter.mjs +6 -2
  206. package/tools/ralph-external/lib/muse-adapter.mjs +12 -2
  207. package/tools/ralph-external/lib/worker-health.mjs +1 -1
  208. package/tools/ralph-external/lib/worker-isolation.mjs +65 -9
  209. package/tools/ralph-external/process-monitor.mjs +7 -4
  210. package/tools/ralph-external/session-launcher.mjs +280 -32
  211. package/tools/skills/deploy-skills-codex.mjs +11 -7
  212. package/vscode-extension/schemas/aiwg.config.v1.json +11 -1
@@ -1,11 +1,12 @@
1
1
  import { z } from 'zod';
2
+ import { integer } from '../../schema/zod-validation.mjs';
2
3
  import { schemaRejectionDetail, schemaIssueDetail, SessionContractError, assertSupportedSchemaMajor, } from '../contracts.js';
3
4
  import { streamBoundedJsonLines } from '../readers.js';
4
5
  export const GENERIC_INTERCHANGE_KIND = 'aiwg.session-interchange';
5
6
  export const GENERIC_ADAPTER_VERSION = '1.0.0';
6
7
  const Rfc3339Schema = z.string().refine((value) => /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/.test(value)
7
8
  && !Number.isNaN(Date.parse(value)), 'timestamp must be RFC 3339 with an explicit UTC offset');
8
- export const GenericInterchangeHeaderSchema = z.object({
9
+ export const GenericInterchangeHeaderSchema = z.looseObject({
9
10
  type: z.literal(GENERIC_INTERCHANGE_KIND),
10
11
  schemaVersion: z.string().regex(/^\d+\.\d+\.\d+$/),
11
12
  product: z.string().min(1),
@@ -14,24 +15,24 @@ export const GenericInterchangeHeaderSchema = z.object({
14
15
  exportedAt: Rfc3339Schema,
15
16
  consistency: z.enum(['provisional', 'consistent-snapshot', 'complete']),
16
17
  lifecycle: z.enum(['active', 'complete', 'archived']),
17
- workspace: z.object({
18
+ workspace: z.looseObject({
18
19
  id: z.string().min(1),
19
20
  name: z.string().min(1).optional(),
20
21
  repository: z.string().min(1).optional(),
21
22
  branch: z.string().min(1).optional(),
22
- }).passthrough(),
23
- provenance: z.object({
23
+ }),
24
+ provenance: z.looseObject({
24
25
  exporter: z.string().min(1),
25
26
  exporterVersion: z.string().min(1),
26
27
  sourceClass: z.string().min(1),
27
- }).passthrough(),
28
- extensions: z.record(z.unknown()).default({}),
29
- }).passthrough();
30
- export const GenericInterchangeEventSchema = z.object({
28
+ }),
29
+ extensions: z.record(z.string(), z.unknown()).prefault({}),
30
+ });
31
+ export const GenericInterchangeEventSchema = z.looseObject({
31
32
  type: z.literal('event'),
32
33
  sessionId: z.string().min(1),
33
34
  eventId: z.string().min(1),
34
- sequence: z.number().int().nonnegative(),
35
+ sequence: integer().nonnegative(),
35
36
  kind: z.string().min(1),
36
37
  role: z.string().min(1).optional(),
37
38
  participant: z.string().min(1).optional(),
@@ -43,8 +44,8 @@ export const GenericInterchangeEventSchema = z.object({
43
44
  occurredAt: Rfc3339Schema.optional(),
44
45
  text: z.string(),
45
46
  lifecycle: z.enum(['active', 'complete', 'archived']),
46
- extensions: z.record(z.unknown()).default({}),
47
- }).passthrough();
47
+ extensions: z.record(z.string(), z.unknown()).prefault({}),
48
+ });
48
49
  export class GenericSessionInterchangeAdapter {
49
50
  limits;
50
51
  provider = 'generic';
@@ -207,7 +208,7 @@ function parseHeader(value) {
207
208
  if (!isDeclaredInterchange(value)) {
208
209
  throw new SessionContractError('MALFORMED_SOURCE', 'input is not a declared AIWG generic session interchange', schemaRejectionDetail(result.error));
209
210
  }
210
- throw new SessionContractError('MALFORMED_SOURCE', `generic interchange header ${describeIssue(result.error, true)}`, schemaRejectionDetail(result.error));
211
+ throw new SessionContractError('MALFORMED_SOURCE', `generic interchange header ${describeIssue(result.error, true, value)}`, schemaRejectionDetail(result.error));
211
212
  }
212
213
  function parseEvent(value) {
213
214
  const result = GenericInterchangeEventSchema.safeParse(value);
@@ -218,7 +219,7 @@ function parseEvent(value) {
218
219
  }
219
220
  // Event values can carry transcript content, so name the field and the
220
221
  // expected shape without echoing the received value.
221
- throw new SessionContractError('MALFORMED_SOURCE', `generic interchange event is malformed: ${describeIssue(result.error, false)}`, schemaRejectionDetail(result.error));
222
+ throw new SessionContractError('MALFORMED_SOURCE', `generic interchange event is malformed: ${describeIssue(result.error, false, value)}`, schemaRejectionDetail(result.error));
222
223
  }
223
224
  function isDeclaredInterchange(value) {
224
225
  return typeof value === 'object' && value !== null
@@ -228,20 +229,28 @@ function quoteValue(value) {
228
229
  const text = typeof value === 'string' ? value : JSON.stringify(value) ?? String(value);
229
230
  return JSON.stringify(text.length > 64 ? `${text.slice(0, 64)}…` : text);
230
231
  }
231
- function describeIssue(error, echoReceived) {
232
+ function describeIssue(error, echoReceived, value) {
232
233
  const issue = error.issues[0];
233
234
  const field = issue.path.length > 0 ? `field "${issue.path.join('.')}"` : 'record';
234
- if (issue.code === z.ZodIssueCode.invalid_enum_value) {
235
- const received = echoReceived ? ` (got ${quoteValue(issue.received)})` : '';
236
- return `${field} must be one of ${issue.options.join('|')}${received}`;
235
+ // Read only the failing field, retaining the existing policy that header
236
+ // enums may echo values while event transcript values are never echoed.
237
+ let input = value;
238
+ for (const key of issue.path) {
239
+ input = input !== null && typeof input === 'object'
240
+ ? input[key] : undefined;
237
241
  }
238
- if (issue.code === z.ZodIssueCode.invalid_type) {
239
- return issue.received === 'undefined'
240
- ? `${field} is required (${issue.expected})`
241
- : `${field} must be ${issue.expected} (got ${issue.received})`;
242
+ if (issue.code === 'invalid_value') {
243
+ if (issue.values.length === 1)
244
+ return `${field} must be ${quoteValue(issue.values[0])}`;
245
+ const received = echoReceived ? ` (got ${quoteValue(input)})` : '';
246
+ return `${field} must be one of ${issue.values.join('|')}${received}`;
242
247
  }
243
- if (issue.code === z.ZodIssueCode.invalid_literal) {
244
- return `${field} must be ${quoteValue(issue.expected)}`;
248
+ if (issue.code === 'invalid_type') {
249
+ const received = input === null ? 'null' : Array.isArray(input) ? 'array' : typeof input;
250
+ const expected = issue.expected === 'int' ? 'integer' : issue.expected;
251
+ return received === 'undefined'
252
+ ? `${field} is required (${expected})`
253
+ : `${field} must be ${expected} (got ${received})`;
245
254
  }
246
255
  return `${field} is invalid: ${issue.message}`;
247
256
  }
@@ -55,6 +55,7 @@
55
55
  import { opendir } from 'node:fs/promises';
56
56
  import { resolve } from 'node:path';
57
57
  import { z } from 'zod';
58
+ import { integer, number } from '../../schema/zod-validation.mjs';
58
59
  import { schemaRejectionDetail, schemaIssueDetail, SessionContractError, assertSupportedSchemaMajor, } from '../contracts.js';
59
60
  import { readBoundedJson } from '../readers.js';
60
61
  import { GenericSessionInterchangeAdapter, } from './generic.js';
@@ -65,60 +66,59 @@ export const GROKBOT_NATIVE_SCHEMA_VERSION = '1.0.0';
65
66
  export const GROKBOT_NATIVE_SCHEMA_MAJOR = 1;
66
67
  export const GROKBOT_LOCATOR_CLASS = 'manual-export';
67
68
  export const GROKBOT_NATIVE_REPLICA_LOCATOR_CLASS = 'grokbot-native-transcript-replica';
68
- const GrokbotEntryBaseSchema = z.object({
69
+ const GrokbotEntryBaseSchema = z.looseObject({
69
70
  kind: z.string().min(1),
70
71
  id: z.string().min(1),
71
- timestampMs: z.number().int().nonnegative(),
72
+ timestampMs: integer().nonnegative(),
72
73
  requestId: z.string().optional(),
73
- seq: z.number().int().nonnegative(),
74
- }).passthrough();
74
+ seq: integer().nonnegative(),
75
+ });
75
76
  const SendMessageEntrySchema = GrokbotEntryBaseSchema.extend({
76
77
  kind: z.literal('send-message'),
77
78
  respondedValue: z.unknown().optional(),
78
79
  secretProvided: z.boolean().optional(),
79
80
  message: z.discriminatedUnion('type', [
80
- z.object({ type: z.literal('text'), content: z.string() }).passthrough(),
81
- z.object({
81
+ z.looseObject({ type: z.literal('text'), content: z.string() }),
82
+ z.looseObject({
82
83
  type: z.literal('widget'),
83
- widget: z.object({ prompt: z.string() }).passthrough(),
84
- }).passthrough(),
85
- z.object({
84
+ widget: z.looseObject({ prompt: z.string() }),
85
+ }),
86
+ z.looseObject({
86
87
  type: z.literal('email-draft'),
87
- draft: z.object({ subject: z.string().optional(), body: z.string() }).passthrough(),
88
- }).passthrough(),
89
- z.object({
88
+ draft: z.looseObject({ subject: z.string().optional(), body: z.string() }),
89
+ }),
90
+ z.looseObject({
90
91
  type: z.literal('slack-draft'),
91
- draft: z.object({ target: z.string().optional(), body: z.string() }).passthrough(),
92
- }).passthrough(),
93
- z.object({
92
+ draft: z.looseObject({ target: z.string().optional(), body: z.string() }),
93
+ }),
94
+ z.looseObject({
94
95
  type: z.literal('attachment'),
95
96
  url: z.string(),
96
97
  file_name: z.string(),
97
- }).passthrough(),
98
- z.object({
98
+ }),
99
+ z.looseObject({
99
100
  type: z.literal('user-form'),
100
- formRequest: z.object({ title: z.string() }).passthrough(),
101
- }).passthrough(),
102
- z.object({
101
+ formRequest: z.looseObject({ title: z.string() }),
102
+ }),
103
+ z.looseObject({
103
104
  type: z.literal('secret-request'),
104
- secretRequest: z.object({ label: z.string() }).passthrough(),
105
- }).passthrough(),
105
+ secretRequest: z.looseObject({ label: z.string() }),
106
+ }),
106
107
  ]),
107
108
  });
108
109
  const MessageEntrySchema = GrokbotEntryBaseSchema.extend({
109
110
  kind: z.literal('message'),
110
111
  role: z.enum(['user', 'assistant']),
111
112
  content: z.string(),
112
- fromAgent: z.object({ id: z.string().optional(), name: z.string().optional() })
113
- .passthrough().optional(),
113
+ fromAgent: z.looseObject({ id: z.string().optional(), name: z.string().optional() }).optional(),
114
114
  });
115
115
  const UserAttachmentEntrySchema = GrokbotEntryBaseSchema.extend({
116
116
  kind: z.literal('user-attachment'),
117
117
  file_name: z.string(),
118
118
  file_path: z.string().optional(),
119
- width: z.number().optional(),
120
- height: z.number().optional(),
121
- byteSize: z.number().optional(),
119
+ width: number().optional(),
120
+ height: number().optional(),
121
+ byteSize: number().optional(),
122
122
  });
123
123
  const EventEntrySchema = GrokbotEntryBaseSchema.extend({
124
124
  kind: z.literal('event'),
@@ -128,17 +128,17 @@ const NoticeEntrySchema = GrokbotEntryBaseSchema.extend({
128
128
  kind: z.literal('notice'),
129
129
  text: z.string(),
130
130
  });
131
- const GrokbotReplicaValueSchema = z.object({
131
+ const GrokbotReplicaValueSchema = z.looseObject({
132
132
  entries: z.array(GrokbotEntryBaseSchema),
133
133
  epochHint: z.string().nullish(),
134
- acceptedSequenceHint: z.number().int().nonnegative().nullish(),
135
- persistedAt: z.number().int().nonnegative().nullish(),
136
- precedingTimestampMs: z.number().int().nonnegative().nullish(),
137
- }).passthrough();
138
- const GrokbotReplicaDocumentSchema = z.object({
139
- schemaVersion: z.number().int().nonnegative(),
134
+ acceptedSequenceHint: integer().nonnegative().nullish(),
135
+ persistedAt: integer().nonnegative().nullish(),
136
+ precedingTimestampMs: integer().nonnegative().nullish(),
137
+ });
138
+ const GrokbotReplicaDocumentSchema = z.looseObject({
139
+ schemaVersion: integer().nonnegative(),
140
140
  value: GrokbotReplicaValueSchema,
141
- }).passthrough();
141
+ });
142
142
  export class GrokbotSessionAdapter {
143
143
  limits;
144
144
  maxFiles;
@@ -1,4 +1,5 @@
1
1
  import { z } from 'zod';
2
+ import { number } from '../../schema/zod-validation.mjs';
2
3
  import { schemaRejectionDetail, schemaIssueDetail, SessionContractError, assertSupportedSchemaMajor, } from '../contracts.js';
3
4
  import { streamBoundedJsonLines, } from '../readers.js';
4
5
  export const HERMES_ADAPTER_VERSION = '1.0.0';
@@ -9,26 +10,26 @@ const sqliteBoolean = z.union([z.boolean(), z.literal(0), z.literal(1)])
9
10
  function nullableOptional(schema) {
10
11
  return z.preprocess((value) => value === null ? undefined : value, schema.optional());
11
12
  }
12
- const MessageSchema = z.object({
13
- id: z.union([z.string(), z.number()]),
13
+ const MessageSchema = z.looseObject({
14
+ id: z.union([z.string(), number()]),
14
15
  role: z.string().min(1),
15
16
  content: z.unknown().optional(),
16
17
  tool_call_id: nullableOptional(z.string()),
17
18
  tool_calls: z.unknown().optional(),
18
19
  tool_name: nullableOptional(z.string()),
19
- timestamp: z.number().optional(),
20
- token_count: nullableOptional(z.number()),
20
+ timestamp: number().optional(),
21
+ token_count: nullableOptional(number()),
21
22
  finish_reason: nullableOptional(z.string()),
22
23
  reasoning: nullableOptional(z.string()),
23
24
  reasoning_content: nullableOptional(z.string()),
24
25
  reasoning_details: z.unknown().optional(),
25
26
  codex_reasoning_items: z.unknown().optional(),
26
- }).passthrough();
27
- const ExportSchema = z.object({
27
+ });
28
+ const ExportSchema = z.looseObject({
28
29
  // Hermes CLI exports currently omit a schema marker. They use the same
29
30
  // schema-23 record shape that the adapter already validates; explicit
30
31
  // markers still pass through the major-version gate below.
31
- schemaVersion: z.union([z.string(), z.number()]).default(HERMES_NATIVE_SCHEMA_VERSION),
32
+ schemaVersion: z.union([z.string(), number()]).default(HERMES_NATIVE_SCHEMA_VERSION),
32
33
  id: z.string().min(1),
33
34
  source: z.string().min(1),
34
35
  user_id: z.string().nullable().optional(),
@@ -36,27 +37,27 @@ const ExportSchema = z.object({
36
37
  model_config: z.unknown().optional(),
37
38
  parent_session_id: z.string().nullable().optional(),
38
39
  compressed_from_session_id: z.string().nullable().optional(),
39
- started_at: z.number(),
40
- ended_at: z.number().nullable().optional(),
40
+ started_at: number(),
41
+ ended_at: number().nullable().optional(),
41
42
  end_reason: z.string().nullable().optional(),
42
43
  archived: sqliteBoolean.optional(),
43
44
  inactive: sqliteBoolean.optional(),
44
45
  cwd: z.string().nullable().optional(),
45
46
  git_branch: z.string().nullable().optional(),
46
47
  routing_key: z.string().nullable().optional(),
47
- input_tokens: z.number().optional(),
48
- output_tokens: z.number().optional(),
49
- cache_read_tokens: z.number().optional(),
50
- cache_write_tokens: z.number().optional(),
51
- reasoning_tokens: z.number().optional(),
52
- estimated_cost_usd: z.number().nullable().optional(),
53
- actual_cost_usd: z.number().nullable().optional(),
48
+ input_tokens: number().optional(),
49
+ output_tokens: number().optional(),
50
+ cache_read_tokens: number().optional(),
51
+ cache_write_tokens: number().optional(),
52
+ reasoning_tokens: number().optional(),
53
+ estimated_cost_usd: number().nullable().optional(),
54
+ actual_cost_usd: number().nullable().optional(),
54
55
  billing_provider: z.string().nullable().optional(),
55
56
  messages: z.array(MessageSchema),
56
- export_deleted_at: z.number().nullable().optional(),
57
- provider_deleted_at: z.number().nullable().optional(),
57
+ export_deleted_at: number().nullable().optional(),
58
+ provider_deleted_at: number().nullable().optional(),
58
59
  snapshotConsistency: z.enum(['sqlite-backup']).optional(),
59
- }).passthrough();
60
+ });
60
61
  export class HermesSessionAdapter {
61
62
  limits;
62
63
  localApi;
@@ -42,6 +42,7 @@
42
42
  import { opendir } from 'node:fs/promises';
43
43
  import { resolve } from 'node:path';
44
44
  import { z } from 'zod';
45
+ import { integer, number } from '../../schema/zod-validation.mjs';
45
46
  import { matchSessionWorkspace, WORKSPACE_MATCH_KINDS } from '../workspace-matching.js';
46
47
  import { schemaRejectionDetail, schemaIssueDetail, SessionContractError, SessionErrorCodeSchema, SessionRejectionDetailSchema, assertSupportedSchemaMajor, } from '../contracts.js';
47
48
  import { readBoundedJson, streamBoundedJsonLines, } from '../readers.js';
@@ -64,28 +65,28 @@ const Rfc3339Schema = z.string().refine((value) => /^\d{4}-\d{2}-\d{2}T\d{2}:\d{
64
65
  * `stream: {kind, id}` block on every record envelope; gap markers carry
65
66
  * `"envelope": null` instead.
66
67
  */
67
- const MuseStreamSchema = z.object({
68
+ const MuseStreamSchema = z.looseObject({
68
69
  kind: z.string().optional(),
69
70
  id: z.string().optional(),
70
- }).passthrough();
71
- const MuseEnvelopeSchema = z.object({
72
- sequence: z.number().int().nonnegative(),
71
+ });
72
+ const MuseEnvelopeSchema = z.looseObject({
73
+ sequence: integer().nonnegative(),
73
74
  id: z.string().optional(),
74
75
  causation_id: z.string().nullish(),
75
- schema_version: z.union([z.number(), z.string()]).optional(),
76
- payload_schema_version: z.union([z.number(), z.string()]).optional(),
76
+ schema_version: z.union([number(), z.string()]).optional(),
77
+ payload_schema_version: z.union([number(), z.string()]).optional(),
77
78
  stream: MuseStreamSchema.optional(),
78
79
  // Muse Code 1.4.0 exports epoch microseconds; RFC 3339 strings stay valid.
79
- recorded_at: z.union([z.string(), z.number().int().nonnegative()]).optional(),
80
+ recorded_at: z.union([z.string(), integer().nonnegative()]).optional(),
80
81
  record_type: z.string().optional(),
81
82
  durability: z.string().optional(),
82
83
  payload_type: z.string().optional(),
83
- payload: z.object({
84
+ payload: z.looseObject({
84
85
  // Muse Code 1.4.3 runtime.session mode records carry an event without a
85
86
  // kind; eventKindOf() falls back to payload_type for those.
86
- event: z.object({ kind: z.string().min(1).optional() }).passthrough().optional(),
87
- }).passthrough().optional(),
88
- }).passthrough();
87
+ event: z.looseObject({ kind: z.string().min(1).optional() }).optional(),
88
+ }).optional(),
89
+ });
89
90
  /**
90
91
  * Record events carry a record envelope, validated strictly. Every other
91
92
  * event kind is an audit marker: `gap` carries `"envelope": null`, and
@@ -93,67 +94,67 @@ const MuseEnvelopeSchema = z.object({
93
94
  * (`children`, `transaction_id`, `content_sha256`) instead of a record.
94
95
  * Markers are never fabricated into provider records.
95
96
  */
96
- const MuseRecordEventSchema = z.object({
97
+ const MuseRecordEventSchema = z.looseObject({
97
98
  kind: z.literal('record'),
98
99
  envelope: MuseEnvelopeSchema,
99
- }).passthrough();
100
- const MuseMarkerEventSchema = z.object({
100
+ });
101
+ const MuseMarkerEventSchema = z.looseObject({
101
102
  kind: z.string().min(1).refine((kind) => kind !== 'record'),
102
103
  envelope: z.record(z.string(), z.unknown()).nullish(),
103
- }).passthrough();
104
+ });
104
105
  const MuseExportEventSchema = z.union([MuseRecordEventSchema, MuseMarkerEventSchema]);
105
- const MuseAcceptedSpawnSchema = z.object({
106
+ const MuseAcceptedSpawnSchema = z.looseObject({
106
107
  subagent_id: z.string().optional(),
107
108
  agent_path: z.string().optional(),
108
109
  role: z.string().optional(),
109
110
  parent_session_id: z.string().optional(),
110
- }).passthrough();
111
- const MuseSessionSummarySchema = z.object({
111
+ });
112
+ const MuseSessionSummarySchema = z.looseObject({
112
113
  session_id: z.string().min(1),
113
- turn_count: z.number().int().nonnegative().optional(),
114
- step_count: z.number().int().nonnegative().optional(),
114
+ turn_count: integer().nonnegative().optional(),
115
+ step_count: integer().nonnegative().optional(),
115
116
  // Live evidence: one summary per exported parent session; subagents appear
116
117
  // only here, as spawn handles (subagent_id), never as extra summaries.
117
118
  accepted_spawns: z.array(MuseAcceptedSpawnSchema).optional(),
118
- session_end: z.object({
119
+ session_end: z.looseObject({
119
120
  exit_reason: z.string().optional(),
120
- uptime_ms: z.number().nonnegative().optional(),
121
- }).passthrough().optional(),
122
- }).passthrough();
123
- const MuseDiagnosticsSchema = z.object({
124
- unparseable_lines: z.number().int().nonnegative().optional(),
125
- unknown_payload_kinds: z.number().int().nonnegative().optional(),
126
- gaps: z.number().int().nonnegative().optional(),
127
- omitted_live_only: z.number().int().nonnegative().optional(),
128
- omitted_records: z.number().int().nonnegative().optional(),
129
- duplicate_records: z.number().int().nonnegative().optional(),
130
- retained_frames: z.number().int().nonnegative().optional(),
131
- retained_frame_children: z.number().int().nonnegative().optional(),
132
- }).passthrough();
133
- const MuseTrajectorySchema = z.object({
134
- export_schema_version: z.number().int().nonnegative(),
121
+ uptime_ms: number().check(z.gte(0)).meta({ type: 'number', minimum: 0 }).optional(),
122
+ }).optional(),
123
+ });
124
+ const MuseDiagnosticsSchema = z.looseObject({
125
+ unparseable_lines: integer().nonnegative().optional(),
126
+ unknown_payload_kinds: integer().nonnegative().optional(),
127
+ gaps: integer().nonnegative().optional(),
128
+ omitted_live_only: integer().nonnegative().optional(),
129
+ omitted_records: integer().nonnegative().optional(),
130
+ duplicate_records: integer().nonnegative().optional(),
131
+ retained_frames: integer().nonnegative().optional(),
132
+ retained_frame_children: integer().nonnegative().optional(),
133
+ });
134
+ const MuseTrajectorySchema = z.looseObject({
135
+ export_schema_version: integer().nonnegative(),
135
136
  redaction: z.string().optional(),
136
- exporter_version: z.object({ display: z.string() }).passthrough().optional(),
137
- session_build: z.object({ display: z.string() }).passthrough().optional(),
137
+ exporter_version: z.looseObject({ display: z.string() }).optional(),
138
+ session_build: z.looseObject({ display: z.string() }).optional(),
138
139
  session_terminated_abnormally: z.boolean().optional(),
139
140
  sessions: z.array(MuseSessionSummarySchema).min(1),
140
141
  events: z.array(MuseExportEventSchema),
141
142
  diagnostics: MuseDiagnosticsSchema.optional(),
142
- }).passthrough();
143
+ });
143
144
  function isRecordEvent(event) {
144
145
  return event.kind === 'record';
145
146
  }
146
- const MuseRetainedFrameSchema = z.object({
147
+ const MuseRetainedFrameSchema = z.looseObject({
147
148
  retained_frame: z.string().min(1),
148
- frame_schema_version: z.number().int().nonnegative().optional(),
149
- outer_log_ordinal: z.number().int().nonnegative().optional(),
149
+ frame_schema_version: integer().nonnegative().optional(),
150
+ outer_log_ordinal: integer().nonnegative().optional(),
150
151
  transaction_id: z.string().optional(),
151
152
  content_sha256: z.string().optional(),
152
- children: z.array(z.object({
153
- child_index: z.number().int().nonnegative().optional(),
153
+ children: z.array(z.looseObject({
154
+ child_index: integer().nonnegative().optional(),
154
155
  record_json: z.string().min(1),
155
- }).passthrough()),
156
- }).passthrough();
156
+ })),
157
+ });
157
158
  export class MuseSessionAdapter {
158
159
  limits;
159
160
  maxFiles;
@@ -513,12 +514,12 @@ export const MuseWorkspaceInspectionSchema = z.object({
513
514
  attribution: z.enum(['matched', 'mismatch', 'unattributed']),
514
515
  matchKind: z.enum(WORKSPACE_MATCH_KINDS).optional(),
515
516
  reasonCode: z.string().nullable(),
516
- recordsInspected: z.number().int().nonnegative(),
517
- bytesInspected: z.number().int().nonnegative(),
517
+ recordsInspected: integer().nonnegative(),
518
+ bytesInspected: integer().nonnegative(),
518
519
  completeInspection: z.boolean(),
519
520
  limit: z.object({
520
521
  name: z.enum(['maxRecords', 'maxRecordBytes', 'maxTotalBytes', 'maxNestingDepth']),
521
- value: z.number().int().positive(),
522
+ value: integer().positive(),
522
523
  }).optional(),
523
524
  fallback: z.literal('bounded-tail').optional(),
524
525
  detail: SessionRejectionDetailSchema.optional(),
@@ -1,15 +1,16 @@
1
1
  import { opendir } from 'node:fs/promises';
2
2
  import { resolve } from 'node:path';
3
3
  import { z } from 'zod';
4
+ import { integer, dateTime } from '../../schema/zod-validation.mjs';
4
5
  import { schemaRejectionDetail, schemaIssueDetail, SessionContractError, } from '../contracts.js';
5
6
  import { streamBoundedJsonLines } from '../readers.js';
6
7
  export const OMP_ADAPTER_VERSION = '1.0.0';
7
8
  export const OMP_SOURCE_SCHEMA_VERSION = '3.0.0';
8
9
  const Title = z.object({ type: z.literal('title'), v: z.literal(1), title: z.string(), source: z.enum(['auto', 'user']).optional(), updatedAt: z.string(), pad: z.string() });
9
- const Header = z.object({ type: z.literal('session'), version: z.number().int(), id: z.string().min(1),
10
- timestamp: z.string().datetime({ offset: true }), cwd: z.string(), parentSession: z.string().optional() }).passthrough();
11
- const Entry = z.object({ type: z.string().min(1), id: z.string().min(1),
12
- parentId: z.string().nullable(), timestamp: z.string().datetime({ offset: true }) }).passthrough();
10
+ const Header = z.looseObject({ type: z.literal('session'), version: integer(), id: z.string().min(1),
11
+ timestamp: dateTime({ offset: true }), cwd: z.string(), parentSession: z.string().optional() });
12
+ const Entry = z.looseObject({ type: z.string().min(1), id: z.string().min(1),
13
+ parentId: z.string().nullable(), timestamp: dateTime({ offset: true }) });
13
14
  export class OmpSessionAdapter {
14
15
  limits;
15
16
  maxFiles;
@@ -1,69 +1,70 @@
1
1
  import { z } from 'zod';
2
+ import { integer, number } from '../../schema/zod-validation.mjs';
2
3
  import { schemaRejectionDetail, schemaIssueDetail, SessionContractError, assertSupportedSchemaMajor, } from '../contracts.js';
3
4
  import { streamBoundedJsonLines, } from '../readers.js';
4
5
  export const OPENCLAW_ADAPTER_VERSION = '1.0.0';
5
6
  export const OPENCLAW_SOURCE_SCHEMA_VERSION = '1.0.0';
6
7
  export const OPENCLAW_NATIVE_SCHEMA_VERSION = '16.0.0';
7
8
  export const OPENCLAW_EVENT_VERSION = '3.0.0';
8
- const LineageSchema = z.object({
9
+ const LineageSchema = z.looseObject({
9
10
  kind: z.enum(['reset', 'fork', 'rewind', 'compaction']),
10
11
  fromSessionId: z.string().optional(),
11
12
  checkpointId: z.string().optional(),
12
13
  reason: z.string().optional(),
13
- }).passthrough();
14
- const EventSchema = z.object({
14
+ });
15
+ const EventSchema = z.looseObject({
15
16
  id: z.string().min(1),
16
17
  parentId: z.string().nullable().optional(),
17
18
  type: z.string().min(1),
18
- timestamp: z.union([z.string(), z.number()]).optional(),
19
+ timestamp: z.union([z.string(), number()]).optional(),
19
20
  role: z.string().optional(),
20
21
  text: z.string().optional(),
21
- model: z.record(z.unknown()).optional(),
22
- tool: z.record(z.unknown()).optional(),
23
- media: z.record(z.unknown()).optional(),
24
- usage: z.record(z.unknown()).optional(),
22
+ model: z.record(z.string(), z.unknown()).optional(),
23
+ tool: z.record(z.string(), z.unknown()).optional(),
24
+ media: z.record(z.string(), z.unknown()).optional(),
25
+ usage: z.record(z.string(), z.unknown()).optional(),
25
26
  lineage: LineageSchema.optional(),
26
27
  opaque: z.unknown().optional(),
27
28
  idempotencyKey: z.string().optional(),
28
- }).passthrough();
29
- const SessionSchema = z.object({
29
+ });
30
+ const SessionSchema = z.looseObject({
30
31
  id: z.string().min(1),
31
32
  sessionKey: z.string().min(1),
32
33
  conversationId: z.string().optional(),
33
34
  agentId: z.string().optional(),
34
35
  identityKey: z.string().optional(),
35
- stateVersion: z.number().int().nonnegative().optional(),
36
- startedAt: z.union([z.string(), z.number()]).optional(),
37
- updatedAt: z.union([z.string(), z.number()]).optional(),
38
- archivedAt: z.union([z.string(), z.number()]).nullable().optional(),
36
+ stateVersion: integer().nonnegative().optional(),
37
+ startedAt: z.union([z.string(), number()]).optional(),
38
+ updatedAt: z.union([z.string(), number()]).optional(),
39
+ archivedAt: z.union([z.string(), number()]).nullable().optional(),
39
40
  recovered: z.boolean().optional(),
40
41
  active: z.boolean().optional(),
41
- window: z.object({
42
- firstSequence: z.number().int().nonnegative().optional(),
43
- lastSequence: z.number().int().nonnegative().optional(),
42
+ window: z.looseObject({
43
+ firstSequence: integer().nonnegative().optional(),
44
+ lastSequence: integer().nonnegative().optional(),
44
45
  historyGap: z.boolean().optional(),
45
- }).passthrough().optional(),
46
+ }).optional(),
46
47
  events: z.array(EventSchema),
47
- }).passthrough();
48
- const SnapshotSchema = z.object({
49
- schemaVersion: z.union([z.string(), z.number()]),
50
- eventVersion: z.union([z.string(), z.number()]),
48
+ });
49
+ const SnapshotSchema = z.looseObject({
50
+ schemaVersion: z.union([z.string(), number()]),
51
+ eventVersion: z.union([z.string(), number()]),
51
52
  snapshotConsistency: z.enum(['sqlite-backup']).optional(),
52
- gateway: z.object({
53
+ gateway: z.looseObject({
53
54
  mode: z.enum(['local', 'remote']).optional(),
54
55
  hostId: z.string().optional(),
55
56
  expectedHostId: z.string().optional(),
56
- }).passthrough().optional(),
57
+ }).optional(),
57
58
  incognito: z.boolean().optional(),
58
- projection: z.object({
59
+ projection: z.looseObject({
59
60
  kind: z.enum(['canonical', 'bounded-history', 'html', 'trajectory']),
60
61
  complete: z.boolean(),
61
- omittedBefore: z.union([z.string(), z.number()]).optional(),
62
+ omittedBefore: z.union([z.string(), number()]).optional(),
62
63
  limitation: z.string().optional(),
63
- }).passthrough().optional(),
64
+ }).optional(),
64
65
  sessions: z.array(SessionSchema),
65
- providerDeletedAt: z.union([z.string(), z.number()]).nullable().optional(),
66
- }).passthrough();
66
+ providerDeletedAt: z.union([z.string(), number()]).nullable().optional(),
67
+ });
67
68
  export class OpenClawSessionAdapter {
68
69
  limits;
69
70
  gateway;