@aiwg/cli 2026.10.4 → 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 (220) 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 +72 -9
  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 +146 -16
  14. package/dist/src/artifacts/index-files.js +15 -4
  15. package/dist/src/artifacts/index-preparation.js +91 -26
  16. package/dist/src/artifacts/index-reader.js +44 -0
  17. package/dist/src/artifacts/index-refresh.js +130 -56
  18. package/dist/src/artifacts/index-status.js +20 -5
  19. package/dist/src/artifacts/index-worker.mjs +9 -7
  20. package/dist/src/artifacts/memory-maintenance.js +503 -0
  21. package/dist/src/artifacts/prebuilt-relations.js +3 -1
  22. package/dist/src/artifacts/query-engine.js +263 -108
  23. package/dist/src/artifacts/relations-builder.js +2 -2
  24. package/dist/src/artifacts/source-graph.js +2 -2
  25. package/dist/src/artifacts/types.js +9 -1
  26. package/dist/src/cli/handlers/decision.js +19 -1
  27. package/dist/src/cli/handlers/guided-setup.js +470 -0
  28. package/dist/src/cli/handlers/help.js +2 -2
  29. package/dist/src/cli/handlers/housekeeper.js +1110 -0
  30. package/dist/src/cli/handlers/index.js +4 -2
  31. package/dist/src/cli/handlers/init.js +41 -6
  32. package/dist/src/cli/handlers/local-executor.js +5 -3
  33. package/dist/src/cli/handlers/mc.js +509 -53
  34. package/dist/src/cli/handlers/models.js +32 -2
  35. package/dist/src/cli/handlers/ralph-launcher.js +76 -4
  36. package/dist/src/cli/handlers/rules.js +1 -1
  37. package/dist/src/cli/handlers/script-runner.js +73 -2
  38. package/dist/src/cli/handlers/serve.js +5 -3
  39. package/dist/src/cli/handlers/sessions.js +40 -6
  40. package/dist/src/cli/handlers/setup.js +428 -1
  41. package/dist/src/cli/handlers/skill-lint.js +1 -1
  42. package/dist/src/cli/handlers/subcommands.js +118 -8
  43. package/dist/src/cli/handlers/use.js +279 -93
  44. package/dist/src/cli/handlers/workspace.js +3 -1
  45. package/dist/src/cli/prompt-utils.js +8 -0
  46. package/dist/src/cli/router.js +16 -1
  47. package/dist/src/config/aiwg-config.js +42 -0
  48. package/dist/src/config/cli.js +7 -3
  49. package/dist/src/config/decision-config.js +14 -1
  50. package/dist/src/config/native-sandbox-warnings.js +25 -0
  51. package/dist/src/contributors/validation.js +6 -5
  52. package/dist/src/decision/admission.js +7 -3
  53. package/dist/src/decision/benchmark.js +469 -0
  54. package/dist/src/decision/ledger.js +22 -3
  55. package/dist/src/decision/pricing.js +147 -0
  56. package/dist/src/decision/qualification/gate-evidence.js +18 -15
  57. package/dist/src/decision/qualification/load-staged.js +539 -0
  58. package/dist/src/decision/qualification/load.js +109 -33
  59. package/dist/src/decision/qualification/runner.js +5 -2
  60. package/dist/src/decision/review/service.js +6 -4
  61. package/dist/src/decision/review/validate.js +23 -2
  62. package/dist/src/decision/savings.js +8 -3
  63. package/dist/src/discovery/index.js +492 -0
  64. package/dist/src/discovery/interview.js +233 -0
  65. package/dist/src/discovery/plan-apply.js +571 -0
  66. package/dist/src/discovery/plan-store.js +171 -0
  67. package/dist/src/discovery/plan-types.js +2 -0
  68. package/dist/src/discovery/plan-validation.js +139 -0
  69. package/dist/src/discovery/types.js +2 -0
  70. package/dist/src/extensions/commands/definitions.js +49 -9
  71. package/dist/src/extensions/manifest.js +71 -44
  72. package/dist/src/extensions/project-local-discovery.js +1 -1
  73. package/dist/src/extensions/project-quickref.js +18 -17
  74. package/dist/src/extensions/validation.js +32 -29
  75. package/dist/src/housekeeper/daemon-config.js +148 -0
  76. package/dist/src/housekeeper/ipc.js +84 -0
  77. package/dist/src/housekeeper/lifecycle.js +148 -0
  78. package/dist/src/housekeeper/platform.js +35 -0
  79. package/dist/src/housekeeper/status.js +70 -0
  80. package/dist/src/housekeeper/units.js +114 -0
  81. package/dist/src/jobs/flow.js +22 -21
  82. package/dist/src/lint/rule-activation.js +20 -5
  83. package/dist/src/lint/runner.js +1 -1
  84. package/dist/src/mcp/cli.mjs +5 -6
  85. package/dist/src/mcp/config-file.mjs +6 -2
  86. package/dist/src/mcp/config-layers.mjs +23 -7
  87. package/dist/src/mcp/profiles.js +18 -31
  88. package/dist/src/mcp/profiles.mjs +18 -32
  89. package/dist/src/mcp/registry.js +7 -27
  90. package/dist/src/mcp/registry.mjs +7 -28
  91. package/dist/src/mcp/server.mjs +34 -1
  92. package/dist/src/mcp/tools/agentic-sandbox.mjs +8 -7
  93. package/dist/src/mcp/tools/command-run.mjs +3 -2
  94. package/dist/src/mcp/tools/decision.mjs +49 -48
  95. package/dist/src/mcp/tools/discovery.mjs +46 -21
  96. package/dist/src/mcp/tools/orchestration.mjs +22 -22
  97. package/dist/src/mcp/tools/subsystems.mjs +9 -8
  98. package/dist/src/mcp/tools/worker-invoke.mjs +17 -4
  99. package/dist/src/mcp/tools/writer-profiles.mjs +1 -1
  100. package/dist/src/memory/audit.js +719 -0
  101. package/dist/src/memory/canonical-context.js +392 -13
  102. package/dist/src/memory/canonical-maintenance.js +95 -0
  103. package/dist/src/memory/cli-result.js +22 -0
  104. package/dist/src/memory/cli.js +176 -0
  105. package/dist/src/memory/context-pack.js +57 -6
  106. package/dist/src/memory/cost.js +512 -0
  107. package/dist/src/memory/firewall-classification.d.mts +7 -0
  108. package/dist/src/memory/firewall-classification.mjs +32 -0
  109. package/dist/src/memory/index.js +8 -0
  110. package/dist/src/memory/line-maintenance.js +68 -0
  111. package/dist/src/memory/maintenance-cli.js +286 -0
  112. package/dist/src/memory/maintenance-contract.js +136 -0
  113. package/dist/src/memory/maintenance-index.js +18 -0
  114. package/dist/src/memory/maintenance-owner.js +2 -0
  115. package/dist/src/memory/maintenance-record.js +138 -0
  116. package/dist/src/memory/maintenance.js +254 -0
  117. package/dist/src/memory/provider-memory-adapter.js +154 -0
  118. package/dist/src/memory/recommend-cli.js +83 -0
  119. package/dist/src/memory/recommend.js +269 -0
  120. package/dist/src/memory/scheduled.js +81 -0
  121. package/dist/src/memory/taxonomy.js +44 -0
  122. package/dist/src/mission-protocol/codecs.js +19 -9
  123. package/dist/src/models/config-loader.js +11 -1
  124. package/dist/src/models/model-capabilities.v1.json +74 -50
  125. package/dist/src/models/provider-policy.js +125 -62
  126. package/dist/src/models/resolver.js +45 -8
  127. package/dist/src/models/worker-installation.d.mts +7 -0
  128. package/dist/src/models/worker-installation.mjs +169 -37
  129. package/dist/src/models/wrapper-route.js +1 -1
  130. package/dist/src/output-modes/registry.js +8 -7
  131. package/dist/src/plugin/metadata-validator.js +1 -1
  132. package/dist/src/providers/deploy-version.d.mts +1 -0
  133. package/dist/src/providers/deploy-version.mjs +17 -0
  134. package/dist/src/providers/provider-definitions.js +19 -16
  135. package/dist/src/providers/skill-ownership.d.mts +11 -2
  136. package/dist/src/providers/skill-ownership.mjs +35 -17
  137. package/dist/src/rules/activation.d.mts +11 -2
  138. package/dist/src/rules/activation.mjs +82 -6
  139. package/dist/src/rules/inventory.js +1 -1
  140. package/dist/src/rules/rule-frontmatter.schema.json +2 -0
  141. package/dist/src/schema/zod-validation.d.mts +6 -0
  142. package/dist/src/schema/zod-validation.mjs +50 -0
  143. package/dist/src/serve/executor-registry.js +297 -20
  144. package/dist/src/serve/executor-token.d.mts +1 -0
  145. package/dist/src/serve/executor-token.mjs +8 -0
  146. package/dist/src/serve/shared-host-scheduler.js +1102 -31
  147. package/dist/src/serve/worker-invocation.js +114 -15
  148. package/dist/src/sessions/adapters/claude.js +19 -18
  149. package/dist/src/sessions/adapters/codex.js +33 -19
  150. package/dist/src/sessions/adapters/copilot.js +14 -13
  151. package/dist/src/sessions/adapters/cursor.js +19 -18
  152. package/dist/src/sessions/adapters/deepseek-harness.js +9 -8
  153. package/dist/src/sessions/adapters/factory.js +11 -10
  154. package/dist/src/sessions/adapters/generic.js +32 -23
  155. package/dist/src/sessions/adapters/grokbot.js +35 -35
  156. package/dist/src/sessions/adapters/hermes.js +20 -19
  157. package/dist/src/sessions/adapters/muse.js +50 -49
  158. package/dist/src/sessions/adapters/omp.js +5 -4
  159. package/dist/src/sessions/adapters/openclaw.js +30 -29
  160. package/dist/src/sessions/adapters/opencode.js +26 -26
  161. package/dist/src/sessions/adapters/openhuman.js +24 -23
  162. package/dist/src/sessions/adapters/pi.js +5 -4
  163. package/dist/src/sessions/adapters/windsurf.js +8 -8
  164. package/dist/src/sessions/analytics.js +10 -9
  165. package/dist/src/sessions/batch-contracts.js +1 -1
  166. package/dist/src/sessions/batch-import.js +202 -2
  167. package/dist/src/sessions/candidates.js +7 -6
  168. package/dist/src/sessions/contracts.js +73 -54
  169. package/dist/src/sessions/coverage-preflight.js +26 -1
  170. package/dist/src/sessions/output-registration.js +11 -10
  171. package/dist/src/sessions/policy.js +18 -7
  172. package/dist/src/sessions/refresh.js +2 -3
  173. package/dist/src/sessions/repository.js +4 -2
  174. package/dist/src/sessions/workspace-discovery.js +92 -26
  175. package/dist/src/smiths/context-pipeline/aiwg-md.js +18 -1
  176. package/dist/src/smiths/context-pipeline/claude-hook.js +42 -6
  177. package/dist/src/smiths/context-pipeline/parallelism-section.js +72 -5
  178. package/dist/src/smiths/context-pipeline/workspace-context.js +106 -10
  179. package/dist/src/update/checker.d.mts +4 -0
  180. package/dist/src/update/checker.mjs +14 -0
  181. package/dist/src/writing/exemplar-selection.js +6 -6
  182. package/dist/src/writing/voice-evaluation.js +24 -23
  183. package/dist/src/writing/writer-migration.js +14 -13
  184. package/dist/src/writing/writer-profile.js +19 -18
  185. package/dist/src/writing/writing-brief.js +18 -17
  186. package/dist/src/writing/writing-receipt.js +47 -46
  187. package/package.json +5 -2
  188. package/schemas/decision/DecisionReview.schema.json +78 -1
  189. package/schemas/mission-v1.schema.json +3 -0
  190. package/tools/agents/deploy-agents.mjs +67 -39
  191. package/tools/agents/providers/antigravity.mjs +6 -1
  192. package/tools/agents/providers/base.mjs +19 -13
  193. package/tools/agents/providers/claude.mjs +1 -1
  194. package/tools/agents/providers/codex.mjs +50 -56
  195. package/tools/agents/providers/copilot.mjs +8 -2
  196. package/tools/agents/providers/cursor.mjs +1 -1
  197. package/tools/agents/providers/deepseek-harness.mjs +1 -1
  198. package/tools/agents/providers/factory.mjs +7 -1
  199. package/tools/agents/providers/grok-build.mjs +18 -2
  200. package/tools/agents/providers/grokbot.mjs +1 -1
  201. package/tools/agents/providers/hermes.mjs +7 -13
  202. package/tools/agents/providers/muse-hooks.mjs +21 -14
  203. package/tools/agents/providers/muse.mjs +7 -2
  204. package/tools/agents/providers/omp.mjs +28 -4
  205. package/tools/agents/providers/opencode.mjs +14 -5
  206. package/tools/agents/providers/openhuman.mjs +1 -1
  207. package/tools/agents/providers/pi.mjs +1 -1
  208. package/tools/agents/providers/provider-prepare-coordinator.mjs +29 -9
  209. package/tools/agents/providers/rule-delivery.mjs +263 -71
  210. package/tools/agents/providers/windsurf.mjs +7 -0
  211. package/tools/cli/workspace-status.mjs +5 -0
  212. package/tools/commands/deploy-prompts-codex.mjs +11 -8
  213. package/tools/ralph-external/lib/codex-adapter.mjs +6 -2
  214. package/tools/ralph-external/lib/muse-adapter.mjs +12 -2
  215. package/tools/ralph-external/lib/worker-health.mjs +1 -1
  216. package/tools/ralph-external/lib/worker-isolation.mjs +65 -9
  217. package/tools/ralph-external/process-monitor.mjs +7 -4
  218. package/tools/ralph-external/session-launcher.mjs +280 -32
  219. package/tools/skills/deploy-skills-codex.mjs +11 -7
  220. package/vscode-extension/schemas/aiwg.config.v1.json +11 -1
@@ -2,12 +2,13 @@ import { createHash, randomUUID } from 'node:crypto';
2
2
  import { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';
3
3
  import { dirname, join } from 'node:path';
4
4
  import { z } from 'zod';
5
+ import { integer, dateTime } from '../schema/zod-validation.mjs';
5
6
  import { redactStructured } from '../governance/redaction.js';
6
7
  import { resolveProjectAiwgDirForWrite } from '../config/project-artifacts.js';
7
8
  const sha = z.string().regex(/^[a-f0-9]{64}$/);
8
9
  const id = z.string().min(1).max(120).regex(/^[a-zA-Z0-9][a-zA-Z0-9._:-]*$/);
9
10
  const stableId = z.string().min(1).max(120).regex(/^[a-z0-9][a-z0-9.-]*$/).refine(value => !value.includes('..'));
10
- const isoDate = z.string().datetime();
11
+ const isoDate = dateTime();
11
12
  const hash = (text) => createHash('sha256').update(text, 'utf8').digest('hex');
12
13
  function canonicalize(value) {
13
14
  if (Array.isArray(value))
@@ -28,105 +29,105 @@ function rejectSensitiveReceipt(value) {
28
29
  if (redacted.sensitivity !== 'none')
29
30
  throw new Error('Writing receipt contains a known secret or credential field');
30
31
  }
31
- const budgetSchema = z.object({
32
- limit: z.number().int().nonnegative(),
33
- used: z.number().int().nonnegative(),
32
+ const budgetSchema = z.strictObject({
33
+ limit: integer().nonnegative(),
34
+ used: integer().nonnegative(),
34
35
  unit: z.enum(['tokens', 'utf8-bytes', 'characters']),
35
36
  measurement: z.enum(['exact', 'upper-bound', 'estimated']),
36
37
  tokenizerId: z.string().min(1).max(120),
37
38
  tokenizerVersion: z.string().min(1).max(120),
38
- }).strict().refine(value => value.used <= value.limit, 'Budget use cannot exceed limit');
39
- const operationConfigSchema = z.object({
39
+ }).refine(value => value.used <= value.limit, 'Budget use cannot exceed limit');
40
+ const operationConfigSchema = z.strictObject({
40
41
  action: z.enum(['plan', 'proofread', 'draft', 'edit', 'continue']),
41
- correctionIds: z.array(id).default([]),
42
+ correctionIds: z.array(id).prefault([]),
42
43
  channel: z.enum(['article', 'social', 'email', 'engineering', 'conversation']).optional(),
43
44
  configSha256: sha.optional(),
44
- }).strict();
45
- const receiptInputBaseSchema = z.object({
45
+ });
46
+ const receiptInputBaseSchema = z.strictObject({
46
47
  schemaVersion: z.literal('aiwg.writing-receipt.v1').default('aiwg.writing-receipt.v1'),
47
48
  id: stableId.optional(),
48
49
  createdAt: isoDate.default(() => new Date().toISOString()),
49
50
  operation: z.enum(['draft-from-notes', 'edit-existing', 'proofread-only', 'continue-author-text']),
50
- profile: z.object({
51
+ profile: z.strictObject({
51
52
  id: stableId,
52
53
  version: z.string().regex(/^\d+\.\d+\.\d+$/),
53
- revision: z.number().int().positive(),
54
- cacheEpoch: z.number().int().nonnegative(),
54
+ revision: integer().positive(),
55
+ cacheEpoch: integer().nonnegative(),
55
56
  compiledModeSha256: sha.optional(),
56
57
  fallback: z.boolean(),
57
- }).strict(),
58
- examples: z.object({
58
+ }),
59
+ examples: z.strictObject({
59
60
  receiptSha256: sha.optional(),
60
61
  cacheKey: sha.optional(),
61
- selections: z.array(z.object({ sampleId: id, sha256: sha }).strict()).default([]),
62
+ selections: z.array(z.strictObject({ sampleId: id, sha256: sha })).prefault([]),
62
63
  budget: budgetSchema.optional(),
63
64
  fallback: z.boolean().default(false),
64
- }).strict().optional(),
65
- modes: z.array(z.object({
65
+ }).optional(),
66
+ modes: z.array(z.strictObject({
66
67
  id: stableId,
67
68
  version: z.string().min(1).max(120),
68
69
  profileSha256: sha.optional(),
69
- }).strict()).default([]),
70
- state: z.object({
71
- selected: z.array(stableId).default([]),
72
- delivered: z.array(stableId).default([]),
73
- applied: z.array(stableId).default([]),
74
- validated: z.array(stableId).default([]),
70
+ })).prefault([]),
71
+ state: z.strictObject({
72
+ selected: z.array(stableId).prefault([]),
73
+ delivered: z.array(stableId).prefault([]),
74
+ applied: z.array(stableId).prefault([]),
75
+ validated: z.array(stableId).prefault([]),
75
76
  deliveredTo: z.enum(['local-transform-callback', 'none']),
76
77
  fallback: z.enum(['none', 'unaltered']),
77
- }).strict().optional(),
78
- modelPrompt: z.object({
78
+ }).optional(),
79
+ modelPrompt: z.strictObject({
79
80
  execution: z.enum(['none', 'local-callback', 'hosted']).default('none'),
80
81
  provider: z.string().min(1).max(120).optional(),
81
82
  model: z.string().min(1).max(120).optional(),
82
83
  promptSha256: sha,
83
84
  templateSha256: sha.optional(),
84
- decoding: z.object({
85
+ decoding: z.strictObject({
85
86
  temperature: z.number().finite().min(0).max(2).optional(),
86
87
  topP: z.number().finite().min(0).max(1).optional(),
87
- maxOutputTokens: z.number().int().positive().optional(),
88
- seed: z.number().int().optional(),
88
+ maxOutputTokens: integer().positive().optional(),
89
+ seed: integer().optional(),
89
90
  stopSha256: sha.optional(),
90
- }).strict().optional(),
91
+ }).optional(),
91
92
  promptConfigSha256: sha.optional(),
92
- hostedVersion: z.object({
93
+ hostedVersion: z.strictObject({
93
94
  attested: z.literal(false),
94
95
  reason: z.literal('Hosted provider prompt/version cannot be attested from this local receipt.'),
95
- }).strict().optional(),
96
- }).strict(),
97
- inputs: z.array(z.object({
96
+ }).optional(),
97
+ }),
98
+ inputs: z.array(z.strictObject({
98
99
  id,
99
100
  role: z.enum(['source', 'author-notes', 'existing-draft', 'brief', 'configuration']),
100
101
  sha256: sha,
101
- }).strict()).min(1),
102
+ })).min(1),
102
103
  operationConfig: operationConfigSchema.optional(),
103
- output: z.object({
104
+ output: z.strictObject({
104
105
  sha256: sha,
105
106
  path: z.string().min(1).max(2000).optional(),
106
- }).strict().optional(),
107
+ }).optional(),
107
108
  budget: budgetSchema,
108
- fallback: z.object({
109
+ fallback: z.strictObject({
109
110
  applied: z.boolean(),
110
111
  reason: z.string().min(1).max(400).optional(),
111
- }).strict(),
112
- validators: z.array(z.object({
112
+ }),
113
+ validators: z.array(z.strictObject({
113
114
  id,
114
115
  version: z.string().min(1).max(120),
115
116
  sha256: sha.optional(),
116
117
  outcome: z.enum(['pass', 'fail', 'uncertain', 'not-run']),
117
- }).strict()).default([]),
118
- evaluation: z.array(z.object({
118
+ })).prefault([]),
119
+ evaluation: z.array(z.strictObject({
119
120
  id,
120
121
  method: z.string().min(1).max(120),
121
122
  sha256: sha,
122
123
  outcome: z.enum(['pass', 'fail', 'uncertain', 'not-established']),
123
- }).strict()).default([]),
124
- authorAcceptance: z.object({
124
+ })).prefault([]),
125
+ authorAcceptance: z.strictObject({
125
126
  status: z.enum(['accepted', 'pending', 'rejected', 'not-required']),
126
127
  acceptedAt: isoDate.optional(),
127
128
  acceptedBy: z.string().min(1).max(120).optional(),
128
- }).strict(),
129
- }).strict();
129
+ }),
130
+ });
130
131
  const enforceReceiptRules = (value, ctx) => {
131
132
  if (new Set(value.inputs.map(input => input.id)).size !== value.inputs.length) {
132
133
  ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Input IDs must be unique' });
@@ -176,7 +177,7 @@ const enforceReceiptRules = (value, ctx) => {
176
177
  }
177
178
  };
178
179
  const receiptInputSchema = receiptInputBaseSchema.superRefine(enforceReceiptRules);
179
- export const writingReceiptSchema = receiptInputBaseSchema.extend({ id: stableId, operationConfig: operationConfigSchema, receiptSha256: sha }).strict().superRefine(enforceReceiptRules);
180
+ export const writingReceiptSchema = receiptInputBaseSchema.extend({ id: stableId, operationConfig: operationConfigSchema, receiptSha256: sha }).superRefine(enforceReceiptRules);
180
181
  export function createWritingReceipt(input) {
181
182
  const parsed = receiptInputSchema.parse(input);
182
183
  const defaultAction = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiwg/cli",
3
- "version": "2026.10.4",
3
+ "version": "2026.10.6",
4
4
  "description": "Lightweight AIWG CLI for signed, versioned web-backed resources.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -27,6 +27,9 @@
27
27
  "THIRD_PARTY_NOTICES.md",
28
28
  "bin/",
29
29
  "agentic/code/providers/",
30
+ "agentic/code/addons/composition-engine/lib/runtime.mjs",
31
+ "agentic/code/addons/composition-engine/lib/validator.mjs",
32
+ "agentic/code/addons/composition-engine/schemas/flow-graph.schema.json",
30
33
  "schemas/security/",
31
34
  "schemas/decision/",
32
35
  "schemas/dataset/",
@@ -115,7 +118,7 @@
115
118
  "semver": "^7.8.5",
116
119
  "toml-eslint-parser": "0.10.0",
117
120
  "yaml": "^2.9.0",
118
- "zod": "^3.25.0"
121
+ "zod": "^4.6.6"
119
122
  },
120
123
  "optionalDependencies": {
121
124
  "@hono/node-server": "2.0.11",
@@ -17,12 +17,89 @@
17
17
  "lifecycle": { "type": "object", "additionalProperties": false, "required": ["legalHold"], "properties": { "legalHold": { "type": "boolean" }, "tombstonedAtEpochMs": { "type": "integer", "minimum": 0 }, "tombstoneReason": { "type": "string" } } }
18
18
  },
19
19
  "$defs": {
20
+ "evaluation": {
21
+ "type": "object",
22
+ "additionalProperties": false,
23
+ "description": "Observed evaluator provenance and evidence. Agreement does not establish independent errors or proof.",
24
+ "properties": {
25
+ "evaluatorModel": {
26
+ "type": "string",
27
+ "minLength": 1,
28
+ "maxLength": 8192,
29
+ "pattern": "\\S"
30
+ },
31
+ "evaluatorVendor": {
32
+ "type": "string",
33
+ "minLength": 1,
34
+ "maxLength": 8192,
35
+ "pattern": "\\S"
36
+ },
37
+ "evaluatorFamily": {
38
+ "type": "string",
39
+ "minLength": 1,
40
+ "maxLength": 8192,
41
+ "pattern": "\\S",
42
+ "description": "Observed model family; unknown remains unknown. CLI names are not model families."
43
+ },
44
+ "acceptanceCriteriaRef": {
45
+ "type": "string",
46
+ "minLength": 1,
47
+ "maxLength": 8192,
48
+ "pattern": "\\S"
49
+ },
50
+ "reReviewOf": {
51
+ "type": "string",
52
+ "minLength": 1,
53
+ "maxLength": 8192,
54
+ "pattern": "\\S",
55
+ "description": "Reference to the previous review/decision, recorded on a re-review after material fixes."
56
+ },
57
+ "disagreements": {
58
+ "type": "array",
59
+ "items": {
60
+ "type": "object",
61
+ "additionalProperties": false,
62
+ "required": [
63
+ "claimRef",
64
+ "generatorPosition",
65
+ "evaluatorPosition"
66
+ ],
67
+ "properties": {
68
+ "claimRef": {
69
+ "type": "string",
70
+ "minLength": 1,
71
+ "maxLength": 8192,
72
+ "pattern": "\\S"
73
+ },
74
+ "generatorPosition": {
75
+ "type": "string",
76
+ "minLength": 1,
77
+ "maxLength": 8192,
78
+ "pattern": "\\S"
79
+ },
80
+ "evaluatorPosition": {
81
+ "type": "string",
82
+ "minLength": 1,
83
+ "maxLength": 8192,
84
+ "pattern": "\\S"
85
+ },
86
+ "resolutionRef": {
87
+ "type": "string",
88
+ "minLength": 1,
89
+ "maxLength": 8192,
90
+ "pattern": "\\S"
91
+ }
92
+ }
93
+ }
94
+ }
95
+ }
96
+ },
20
97
  "digest": { "type": "string", "pattern": "^sha256:[a-f0-9]{64}$" },
21
98
  "actor": { "type": "object", "additionalProperties": false, "required": ["id", "roles", "authorityContext"], "properties": { "id": { "type": "string", "minLength": 1 }, "roles": { "type": "array", "items": { "type": "string" } }, "authorityContext": { "type": "string" } } },
22
99
  "pin": { "type": "object", "additionalProperties": false, "required": ["id", "version", "digest"], "properties": { "id": { "type": "string" }, "version": { "type": "string" }, "digest": { "$ref": "#/$defs/digest" } } },
23
100
  "sourceReceipt": { "type": "object", "additionalProperties": false, "required": ["id", "digest"], "properties": { "id": { "type": "string" }, "digest": { "$ref": "#/$defs/digest" } } },
24
101
  "proposal": { "type": "object", "additionalProperties": false, "required": ["version", "action", "actionDigest", "createdAtEpochMs", "editor", "rationale"], "properties": { "version": { "type": "integer", "minimum": 1 }, "action": {}, "actionDigest": { "$ref": "#/$defs/digest" }, "createdAtEpochMs": { "type": "integer" }, "editor": { "$ref": "#/$defs/actor" }, "rationale": { "type": "string" } } },
25
- "decision": { "type": "object", "additionalProperties": false, "required": ["reviewer", "proposalVersion", "decision", "rationale", "atEpochMs"], "properties": { "reviewer": { "$ref": "#/$defs/actor" }, "proposalVersion": { "type": "integer" }, "decision": { "enum": ["approve", "reject"] }, "rationale": { "type": "string" }, "atEpochMs": { "type": "integer" } } },
102
+ "decision": { "type": "object", "additionalProperties": false, "required": ["reviewer", "proposalVersion", "decision", "rationale", "atEpochMs"], "properties": { "reviewer": { "$ref": "#/$defs/actor" }, "proposalVersion": { "type": "integer" }, "decision": { "enum": ["approve", "reject"] }, "rationale": { "type": "string" }, "atEpochMs": { "type": "integer" }, "evaluation": { "$ref": "#/$defs/evaluation" } } },
26
103
  "event": { "type": "object", "additionalProperties": false, "required": ["sequence", "type", "atEpochMs", "actor", "proposalVersion", "rationale"], "properties": { "sequence": { "type": "integer" }, "type": { "enum": ["created", "claimed", "approved", "rejected", "edited", "expired", "escalated", "canceled", "resumed", "execution-completed", "execution-failed", "legal-hold-placed", "legal-hold-released", "tombstoned", "authorization-denied", "sensitive-view-accessed"] }, "atEpochMs": { "type": "integer" }, "actor": { "$ref": "#/$defs/actor" }, "proposalVersion": { "type": "integer" }, "rationale": { "type": "string" }, "operatorDecisionEventId": { "type": "string", "minLength": 1 }, "data": { "type": "object" } } },
27
104
  "effect": { "type": "object", "additionalProperties": false, "required": ["effectId", "continuationId", "proposalVersion", "completedAtEpochMs", "result"], "properties": { "effectId": { "type": "string" }, "continuationId": { "type": "string" }, "proposalVersion": { "type": "integer" }, "completedAtEpochMs": { "type": "integer" }, "result": {} } }
28
105
  }
@@ -1643,6 +1643,9 @@
1643
1643
  "type": "object",
1644
1644
  "additionalProperties": false,
1645
1645
  "properties": {
1646
+ "isolation": {
1647
+ "enum": ["systemd-unit", "native-sandbox"]
1648
+ },
1646
1649
  "version": {
1647
1650
  "const": 1
1648
1651
  },
@@ -32,6 +32,7 @@
32
32
  * --model-tier <tier> Override all artifacts with economy|standard|premium
33
33
  * --as-agents-md Aggregate to single AGENTS.md (OpenAI/Codex)
34
34
  * --create-agents-md Create/update AGENTS.md template
35
+ --no-context-files Preserve WORKSPACE.md, AIWG.md and AGENTS.md (including managed blocks)
35
36
  * --skip-commands-migration Skip deleting the commands directory (warns about duplicate TUI entries) (Factory/Codex/OpenCode/Cursor)
36
37
  * --deploy-source <name> Managed-marker source for deployed artifacts (default: bundled)
37
38
  * --deploy-version <version> Managed-marker version for deployed artifacts (default: source package.json)
@@ -75,6 +76,8 @@ const staticModelCatalog = _require('../../agentic/code/providers/model-catalog.
75
76
  let fs;
76
77
  try { const gfs = _require('graceful-fs'); gfs.gracefulify(realFs); fs = realFs; } catch { fs = realFs; }
77
78
  import path from 'path';
79
+ import { importImpl } from '../_resolve-impl.mjs';
80
+ const { resolveDeployVersion } = await importImpl(import.meta.url, 'providers/deploy-version.mjs');
78
81
  import os from 'os';
79
82
  import readline from 'readline';
80
83
  import { fileURLToPath } from 'url';
@@ -96,20 +99,6 @@ import {
96
99
  resolveAiwgRoot,
97
100
  updateSidecarManifest,
98
101
  } from './providers/base.mjs';
99
- const modelCatalog = loadRuntimeModelCatalog(staticModelCatalog);
100
-
101
- /**
102
- * Read version from package.json at the source root.
103
- * Falls back to 'unknown' if unavailable.
104
- */
105
- function getDeployVersion(srcRoot) {
106
- try {
107
- const pkg = JSON.parse(fs.readFileSync(path.join(srcRoot, 'package.json'), 'utf8'));
108
- return pkg.version || 'unknown';
109
- } catch {
110
- return 'unknown';
111
- }
112
- }
113
102
 
114
103
  // ============================================================================
115
104
  // Provider Registry
@@ -421,10 +410,8 @@ function pruneStaleAiwgArtifacts(provider, target, srcRoot, opts, explicitSource
421
410
  }
422
411
 
423
412
  if (opts.kernelOnly) {
424
- // A kernel-only run deploys skills and nothing else (deployCommands /
425
- // deployRules / deployBehaviors are all forced false above), so it has no
426
- // basis for judging any flat artifact stale. The empty desired set below
427
- // exists for one narrow migration: clearing agents/commands/rules left by
413
+ // Kernel-only delivers skills and rules. The empty desired set below
414
+ // applies only to bulk agents/commands left by
428
415
  // the pre-#152 bulk default, when the bulk install is the only thing this
429
416
  // project ever deployed.
430
417
  //
@@ -438,7 +425,7 @@ function pruneStaleAiwgArtifacts(provider, target, srcRoot, opts, explicitSource
438
425
  }
439
426
  return;
440
427
  }
441
- for (const type of ['agents', 'commands', 'rules']) {
428
+ for (const type of ['agents', 'commands']) {
442
429
  const relPath = provider.paths?.[type];
443
430
  if (!relPath || relPath.endsWith('.md')) continue;
444
431
  const destDir = path.isAbsolute(relPath) ? relPath : path.join(target, relPath);
@@ -499,6 +486,8 @@ export function parseArgs(args = process.argv.slice(2)) {
499
486
  efficiencyModel: null,
500
487
  asAgentsMd: false,
501
488
  createAgentsMd: false,
489
+ contextFiles: true,
490
+ projectScope: false,
502
491
  deployCommands: false,
503
492
  deploySkills: false,
504
493
  deployRules: false,
@@ -509,6 +498,8 @@ export function parseArgs(args = process.argv.slice(2)) {
509
498
  strict: false,
510
499
  reportOnly: true,
511
500
  kernelOnly: false,
501
+ deferRuleProjection: false,
502
+ additionalSources: [],
512
503
  filter: null, // Glob pattern for agent names
513
504
  filterRole: null, // Filter by role: reasoning|coding|efficiency
514
505
  save: false, // Save model config to project models.json
@@ -532,6 +523,11 @@ export function parseArgs(args = process.argv.slice(2)) {
532
523
  for (let i = 0; i < args.length; i++) {
533
524
  const a = args[i];
534
525
  if (a === '--source' && args[i + 1]) cfg.source = path.resolve(args[++i]);
526
+ else if (a === '--additional-source') {
527
+ const source = args[++i];
528
+ if (!source || source.startsWith('--')) throw new Error('--additional-source requires a source directory');
529
+ cfg.additionalSources.push(path.resolve(source));
530
+ }
535
531
  else if (a === '--target' && args[i + 1]) cfg.target = path.resolve(args[++i]);
536
532
  else if (a === '--mode' && args[i + 1]) cfg.mode = String(args[++i]).toLowerCase();
537
533
  else if (a === '--scope') {
@@ -540,6 +536,7 @@ export function parseArgs(args = process.argv.slice(2)) {
540
536
  throw new Error(`--scope expected 'user' or 'project', got '${scope ?? '(missing)'}'`);
541
537
  }
542
538
  cfg.userScope = scope === 'user';
539
+ cfg.projectScope = scope === 'project';
543
540
  }
544
541
  else if (a === '--user') cfg.userScope = true;
545
542
  else if (a === '--dry-run') cfg.dryRun = true;
@@ -563,6 +560,8 @@ export function parseArgs(args = process.argv.slice(2)) {
563
560
  else if (a === '--allow-over-budget') cfg.allowOverBudget = true;
564
561
  else if (a === '--report-only') cfg.reportOnly = true;
565
562
  else if (a === '--kernel-only') cfg.kernelOnly = true;
563
+ // Internal use orchestration: the final source owns rule presentation.
564
+ else if (a === '--defer-rule-projection') cfg.deferRuleProjection = true;
566
565
  else if (a === '--deploy-behaviors') cfg.deployBehaviors = true;
567
566
  else if (a === '--filter' && args[i + 1]) cfg.filter = args[++i];
568
567
  else if (a === '--filter-role' && args[i + 1]) cfg.filterRole = args[++i];
@@ -579,12 +578,12 @@ export function parseArgs(args = process.argv.slice(2)) {
579
578
  // managed-hooks opt-out (default on, mirroring the Claude autoInstall policy).
580
579
  else if (a === '--mcp') cfg.mcp = true;
581
580
  else if (a === '--no-hooks') cfg.hooks = false;
581
+ else if (a === '--no-context-files') cfg.contextFiles = false;
582
582
  else if (a === '--deploy-source' && args[i + 1]) cfg.deploySource = String(args[++i]);
583
583
  else if (a === '--listing-budget') cfg.listingBudget = true;
584
584
  else if (a === '--deploy-version' && args[i + 1]) cfg.deployVersion = String(args[++i]);
585
585
  else if (a === '--help' || a === '-h') {
586
- printHelp();
587
- process.exit(0);
586
+ cfg.help = true;
588
587
  }
589
588
  }
590
589
  return cfg;
@@ -610,7 +609,7 @@ Options:
610
609
  --commands-only Deploy only commands (skip agents)
611
610
  --skills-only Deploy only skills (skip agents)
612
611
  --rules-only Deploy only rules (skip agents)
613
- --kernel-only Deploy kernel skills only and prune managed bulk artifacts
612
+ --kernel-only Deploy kernel skills and rules; prune managed bulk agents/commands
614
613
  --dry-run Show what would be deployed without writing
615
614
  --force Overwrite existing files
616
615
  --provider <name> Target provider (see below)
@@ -630,6 +629,7 @@ Options:
630
629
  (.muse/hooks.json; installed by default)
631
630
  --as-agents-md Aggregate to single AGENTS.md (Codex)
632
631
  --create-agents-md Create/update AGENTS.md template
632
+ --no-context-files Preserve WORKSPACE.md, AIWG.md and AGENTS.md (including managed blocks)
633
633
  --skip-commands-migration Skip deleting the commands directory before skills deployment
634
634
  --listing-budget Honor the provider startup-listing cap even with --copy-all
635
635
  --deploy-source <name> Managed-marker source stamped into deployed artifacts.
@@ -743,7 +743,7 @@ function resolveProvider(name) {
743
743
  console.error('');
744
744
  for (const line of UNSUPPORTED_PROVIDER_HINTS[candidate]) console.error(line);
745
745
  }
746
- process.exit(1);
746
+ throw new Error(`Unknown provider: ${name}`);
747
747
  }
748
748
  return resolved;
749
749
  }
@@ -753,14 +753,17 @@ function resolveProvider(name) {
753
753
  */
754
754
  async function loadProvider(providerName) {
755
755
  const resolved = resolveProvider(providerName);
756
- const providerPath = `./providers/${resolved}.mjs`;
756
+ // Resolve against this module, not the caller's cwd: in-process callers
757
+ // (including module runners such as Vitest) cannot resolve a bare relative
758
+ // specifier held in a variable.
759
+ const providerUrl = new URL(`./providers/${resolved}.mjs`, import.meta.url).href;
757
760
 
758
761
  try {
759
- const provider = await import(providerPath);
762
+ const provider = await import(providerUrl);
760
763
  return provider.default || provider;
761
764
  } catch (err) {
762
765
  console.error(`Failed to load provider '${resolved}':`, err.message);
763
- process.exit(1);
766
+ throw err;
764
767
  }
765
768
  }
766
769
 
@@ -896,7 +899,7 @@ function deepMerge(target, source) {
896
899
  * @param {string} targetDir - Resolved target directory
897
900
  * @returns {Promise<boolean>} true = proceed with migration, false = skip
898
901
  */
899
- async function promptCommandsMigration(cfg, provider, targetDir) {
902
+ async function promptCommandsMigration(cfg, provider, targetDir, interactive = process.stdout.isTTY) {
900
903
  // Home-directory providers share commands across projects — do not delete.
901
904
  if (provider.capabilities?.homeDirectoryDeploy) return false;
902
905
  // Some providers intentionally expose both surfaces with different runtime
@@ -914,7 +917,7 @@ async function promptCommandsMigration(cfg, provider, targetDir) {
914
917
  if (entries.length === 0) return false;
915
918
 
916
919
  // Non-interactive context: migrate silently.
917
- if (cfg.quiet || !process.stdout.isTTY) return true;
920
+ if (cfg.quiet || !interactive) return true;
918
921
 
919
922
  const rel = path.relative(process.cwd(), commandsDir);
920
923
  console.log(`\n⚠ Commands → Skills Migration`);
@@ -948,6 +951,8 @@ async function promptCommandsMigration(cfg, provider, targetDir) {
948
951
 
949
952
  export async function main(args = process.argv.slice(2), internal = {}) {
950
953
  const cfg = parseArgs(args);
954
+ if (cfg.help) { printHelp(); return 0; }
955
+ const modelCatalog = loadRuntimeModelCatalog(staticModelCatalog);
951
956
 
952
957
  // Resolve source directory (default to repo root relative to this script)
953
958
  const __filename = fileURLToPath(import.meta.url);
@@ -956,8 +961,7 @@ export async function main(args = process.argv.slice(2), internal = {}) {
956
961
 
957
962
  // Validate source directory
958
963
  if (!fs.existsSync(srcRoot)) {
959
- console.error(`Source directory not found: ${srcRoot}`);
960
- process.exit(1);
964
+ throw new Error(`Source directory not found: ${srcRoot}`);
961
965
  }
962
966
 
963
967
  // Validate target directory
@@ -1020,6 +1024,10 @@ export async function main(args = process.argv.slice(2), internal = {}) {
1020
1024
 
1021
1025
  // Load provider module
1022
1026
  const provider = await loadProvider(cfg.provider);
1027
+ if (cfg.additionalSources.length && provider.name !== 'omp') throw new Error('--additional-source requires the OMP provider');
1028
+ for (const source of cfg.additionalSources) {
1029
+ if (!fs.statSync(source).isDirectory()) throw new Error(`Additional source is not a directory: ${source}`);
1030
+ }
1023
1031
  if (!cfg.quiet) console.log(`\nLoaded provider: ${provider.name}`);
1024
1032
 
1025
1033
  // Build options for provider
@@ -1038,11 +1046,15 @@ export async function main(args = process.argv.slice(2), internal = {}) {
1038
1046
  codingModel: cfg.codingModel,
1039
1047
  efficiencyModel: cfg.efficiencyModel,
1040
1048
  modelsConfig,
1049
+ modelCatalog,
1050
+ // Warnings belong to this pass, just as they do in an isolated CLI run.
1051
+ warnedCommandsDirs: new Set(),
1041
1052
  asAgentsMd: cfg.asAgentsMd,
1042
- createAgentsMd: cfg.createAgentsMd,
1053
+ createAgentsMd: cfg.contextFiles && cfg.createAgentsMd,
1054
+ contextFiles: cfg.contextFiles,
1043
1055
  deployCommands: cfg.kernelOnly ? false : cfg.deployCommands,
1044
1056
  deploySkills: cfg.kernelOnly ? true : cfg.deploySkills,
1045
- deployRules: cfg.kernelOnly ? false : cfg.deployRules,
1057
+ deployRules: !cfg.deferRuleProjection && (cfg.kernelOnly || cfg.deployRules),
1046
1058
  deployBehaviors: cfg.kernelOnly ? false : cfg.deployBehaviors,
1047
1059
  commandsOnly: cfg.commandsOnly,
1048
1060
  skillsOnly: cfg.skillsOnly || cfg.kernelOnly,
@@ -1051,6 +1063,8 @@ export async function main(args = process.argv.slice(2), internal = {}) {
1051
1063
  reportOnly: cfg.reportOnly,
1052
1064
  allowOverBudget: cfg.allowOverBudget === true,
1053
1065
  kernelOnly: cfg.kernelOnly,
1066
+ deferRuleProjection: cfg.deferRuleProjection,
1067
+ additionalSources: cfg.additionalSources,
1054
1068
  filter: cfg.filter,
1055
1069
  filterRole: cfg.filterRole,
1056
1070
  save: cfg.save,
@@ -1070,17 +1084,23 @@ export async function main(args = process.argv.slice(2), internal = {}) {
1070
1084
  mcp: cfg.mcp === true,
1071
1085
  hooks: cfg.hooks !== false,
1072
1086
  listingBudget: cfg.listingBudget === true,
1073
- deployVersion: cfg.deployVersion || getDeployVersion(srcRoot),
1087
+ deployVersion: resolveDeployVersion(resolveAiwgRoot(srcRoot) || srcRoot, cfg.deployVersion),
1074
1088
  deploySource: cfg.deploySource || 'bundled',
1075
1089
  };
1076
- const { isRuleDeploymentPreparationActive } = await import('./providers/rule-delivery.mjs');
1077
- const preparationActive = isRuleDeploymentPreparationActive();
1090
+ if (provider.name === 'hermes' && cfg.projectScope && !cfg.userScope) {
1091
+ throw new Error('Hermes does not support --scope project: skills are discovered only under HERMES_HOME/skills (default ~/.hermes/skills). Use --scope user or an isolated HERMES_HOME profile shared with Hermes.');
1092
+ }
1093
+ // Deferred kernel source passes must not load the projection dependency
1094
+ // graph. Preparation still owns their staged deployment when a hook is active.
1095
+ const preparationActive = cfg.kernelOnly && cfg.deferRuleProjection
1096
+ ? Boolean(globalThis[Symbol.for('aiwg.provider-preparation-hook.v1')])
1097
+ : (await import('./providers/rule-delivery.mjs')).isRuleDeploymentPreparationActive();
1078
1098
 
1079
1099
  // Commands → Skills migration: prompt then delete the commands directory
1080
1100
  // so stale command files don't create duplicates in the provider TUI.
1081
1101
  if (!preparationActive && !internal.finalizeOnly) {
1082
1102
  if (!cfg.dryRun && !cfg.skipCommandsMigration) {
1083
- const doMigrate = await promptCommandsMigration(cfg, provider, cfg.target);
1103
+ const doMigrate = await promptCommandsMigration(cfg, provider, cfg.target, internal.capture ? false : process.stdout.isTTY);
1084
1104
  if (doMigrate) {
1085
1105
  const commandsRelPath = provider.paths?.commands;
1086
1106
  if (commandsRelPath) {
@@ -1106,7 +1126,13 @@ export async function main(args = process.argv.slice(2), internal = {}) {
1106
1126
 
1107
1127
  // Delegate to provider
1108
1128
  try {
1109
- if (!internal.finalizeOnly) await provider.deploy(opts);
1129
+ if (!internal.finalizeOnly) {
1130
+ if (cfg.kernelOnly && (!cfg.deferRuleProjection || preparationActive)
1131
+ && !['claude', 'codex', 'cursor', 'hermes', 'warp', 'openclaw', 'pi', 'copilot', 'factory', 'opencode', 'windsurf', 'antigravity', 'muse', 'omp', 'grok-build'].includes(provider.name)) {
1132
+ const { deployWithRuleDelivery } = await import('./providers/rule-delivery.mjs');
1133
+ await deployWithRuleDelivery(opts, provider, staged => provider.deploy(staged));
1134
+ } else await provider.deploy(opts);
1135
+ }
1110
1136
  if (preparationActive) return;
1111
1137
 
1112
1138
  const mirroredCommandCount = mirrorSkillsAsCommands(provider, cfg.target, srcRoot, opts);
@@ -1138,11 +1164,13 @@ export async function main(args = process.argv.slice(2), internal = {}) {
1138
1164
  if (cfg.dryRun) {
1139
1165
  console.error('(dry-run mode - no files were modified)');
1140
1166
  }
1141
- process.exit(1);
1167
+ return 1;
1142
1168
  }
1169
+ return 0;
1143
1170
  }
1144
1171
 
1145
1172
  const invokedPath = process.argv[1] ? path.resolve(process.argv[1]) : null;
1146
1173
  if (invokedPath === fileURLToPath(import.meta.url)) {
1147
- await main();
1174
+ try { process.exitCode = (await main()) ?? 0; }
1175
+ catch (error) { console.error(error.message); process.exitCode = 1; }
1148
1176
  }
@@ -2,6 +2,7 @@
2
2
  import fs from 'node:fs';
3
3
  import path from 'node:path';
4
4
  import {
5
+ withRuleDeployment,
5
6
  collectFrameworkArtifacts,
6
7
  createAgentsMdFromTemplate,
7
8
  deployFiles,
@@ -96,7 +97,7 @@ export async function postDeploy(target, opts) {
96
97
  throw new Error('Antigravity global skill deployment is disabled: official 1.1.26 path documentation conflicts');
97
98
  }
98
99
  if (opts.createAgentsMd || (!opts.commandsOnly && !opts.skillsOnly && !opts.rulesOnly)) {
99
- createAgentsMd(target, opts.srcRoot, opts.dryRun);
100
+ if (opts.contextFiles !== false) createAgentsMd(target, opts.srcRoot, opts.dryRun);
100
101
  }
101
102
  if (!opts.quiet) {
102
103
  console.log('Antigravity resources are project scoped. Restart agy after resource changes; authenticate with the provider separately.');
@@ -106,6 +107,10 @@ export async function postDeploy(target, opts) {
106
107
  export function getFileExtension() { return '.md'; }
107
108
 
108
109
  export async function deploy(opts) {
110
+ return withRuleDeployment(opts, { name, paths, kernelSkillsPath }, deploySelected);
111
+ }
112
+
113
+ async function deploySelected(opts) {
109
114
  if (opts.global || opts.user || opts.scope === 'user') {
110
115
  throw new Error('Antigravity global skill deployment is disabled: official 1.1.26 path documentation conflicts');
111
116
  }