@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.
- package/agentic/code/addons/composition-engine/lib/runtime.mjs +1401 -0
- package/agentic/code/addons/composition-engine/lib/validator.mjs +513 -0
- package/agentic/code/addons/composition-engine/schemas/flow-graph.schema.json +372 -0
- package/agentic/code/providers/model-capabilities.v1.json +74 -50
- package/bin/aiwg.mjs +7 -3
- package/dist/src/a2a/agent-card.js +11 -0
- package/dist/src/api/index.d.ts +1 -0
- package/dist/src/api/index.js +1 -0
- package/dist/src/artifacts/browser-export.js +1 -0
- package/dist/src/artifacts/citation-parser.js +8 -1
- package/dist/src/artifacts/cli.js +57 -6
- package/dist/src/artifacts/fortemi-core-query-adapter.js +2 -0
- package/dist/src/artifacts/fortemi-core-sync.js +26 -8
- package/dist/src/artifacts/fortemi-shard-contract/2.2.0/contract.json +103 -0
- package/dist/src/artifacts/fortemi-shard-contract/2.2.0/full-v1-embedding-config.schema.json +212 -0
- package/dist/src/artifacts/fortemi-shard-contract/2.2.0/full-v1-embedding-set.schema.json +240 -0
- package/dist/src/artifacts/fortemi-shard-contract/2.2.0/full-v1-manifest.schema.json +451 -0
- package/dist/src/artifacts/fortemi-shard-export.js +284 -0
- package/dist/src/artifacts/graph-query.js +18 -8
- package/dist/src/artifacts/index-adapters.js +339 -0
- package/dist/src/artifacts/index-builder.js +143 -14
- package/dist/src/artifacts/index-files.js +15 -4
- package/dist/src/artifacts/index-preparation.js +2 -0
- package/dist/src/artifacts/index-reader.js +44 -0
- package/dist/src/artifacts/index-refresh.js +114 -55
- package/dist/src/artifacts/index-status.js +20 -5
- package/dist/src/artifacts/memory-maintenance.js +503 -0
- package/dist/src/artifacts/prebuilt-relations.js +3 -1
- package/dist/src/artifacts/query-engine.js +263 -108
- package/dist/src/artifacts/relations-builder.js +2 -2
- package/dist/src/artifacts/source-graph.js +2 -2
- package/dist/src/artifacts/types.js +9 -1
- package/dist/src/auth/client.js +5 -1
- package/dist/src/auth/credential-store.js +5 -1
- package/dist/src/auth/sensitive-input.js +151 -0
- package/dist/src/channel/manager.mjs +3 -0
- package/dist/src/cli/handlers/agentcard.js +47 -25
- package/dist/src/cli/handlers/auth.js +22 -2
- package/dist/src/cli/handlers/decision.js +22 -3
- package/dist/src/cli/handlers/effect.js +4 -84
- package/dist/src/cli/handlers/guided-setup.js +470 -0
- package/dist/src/cli/handlers/help.js +2 -2
- package/dist/src/cli/handlers/housekeeper.js +1110 -0
- package/dist/src/cli/handlers/index.js +4 -2
- package/dist/src/cli/handlers/init.js +41 -6
- package/dist/src/cli/handlers/install.js +6 -0
- package/dist/src/cli/handlers/local-executor.js +5 -3
- package/dist/src/cli/handlers/marketplace.js +15 -4
- package/dist/src/cli/handlers/mc.js +509 -53
- package/dist/src/cli/handlers/models.js +32 -2
- package/dist/src/cli/handlers/ralph-launcher.js +76 -4
- package/dist/src/cli/handlers/rules.js +1 -1
- package/dist/src/cli/handlers/script-runner.js +73 -2
- package/dist/src/cli/handlers/serve.js +5 -3
- package/dist/src/cli/handlers/sessions.js +1 -0
- package/dist/src/cli/handlers/setup.js +432 -1
- package/dist/src/cli/handlers/skill-lint.js +1 -1
- package/dist/src/cli/handlers/subcommands.js +118 -8
- package/dist/src/cli/handlers/use.js +335 -107
- package/dist/src/cli/handlers/workspace.js +3 -1
- package/dist/src/cli/prompt-utils.js +81 -0
- package/dist/src/cli/router.js +16 -1
- package/dist/src/config/aiwg-config.js +42 -0
- package/dist/src/config/cli.js +7 -3
- package/dist/src/config/decision-config.js +14 -1
- package/dist/src/config/gitignore.js +4 -0
- package/dist/src/config/native-sandbox-warnings.js +25 -0
- package/dist/src/config/workspace.js +2 -1
- package/dist/src/contributors/validation.js +6 -5
- package/dist/src/decision/adapters/jev.js +20 -31
- package/dist/src/decision/admission.js +7 -3
- package/dist/src/decision/ask.js +6 -1
- package/dist/src/decision/benchmark.js +482 -0
- package/dist/src/decision/ledger.js +22 -3
- package/dist/src/decision/pricing.js +147 -0
- package/dist/src/decision/qualification/gate-evidence.js +23 -18
- package/dist/src/decision/qualification/load-staged.js +576 -0
- package/dist/src/decision/qualification/load.js +109 -33
- package/dist/src/decision/qualification/runner.js +12 -5
- package/dist/src/decision/review/service.js +6 -4
- package/dist/src/decision/review/validate.js +23 -2
- package/dist/src/decision/savings.js +8 -3
- package/dist/src/discovery/index.js +492 -0
- package/dist/src/discovery/interview.js +238 -0
- package/dist/src/discovery/plan-apply.js +567 -0
- package/dist/src/discovery/plan-store.js +171 -0
- package/dist/src/discovery/plan-types.js +2 -0
- package/dist/src/discovery/plan-validation.js +139 -0
- package/dist/src/discovery/types.js +2 -0
- package/dist/src/effects/host.js +91 -0
- package/dist/src/extensions/commands/definitions.js +49 -9
- package/dist/src/extensions/manifest.js +71 -44
- package/dist/src/extensions/project-local-discovery.js +1 -1
- package/dist/src/extensions/project-local-gitignore.js +2 -0
- package/dist/src/extensions/project-quickref.js +18 -17
- package/dist/src/extensions/validation.js +32 -29
- package/dist/src/housekeeper/daemon-config.js +148 -0
- package/dist/src/housekeeper/ipc.js +84 -0
- package/dist/src/housekeeper/lifecycle.js +148 -0
- package/dist/src/housekeeper/platform.js +35 -0
- package/dist/src/housekeeper/status.js +70 -0
- package/dist/src/housekeeper/units.js +114 -0
- package/dist/src/issues/cli.js +16 -5
- package/dist/src/issues/live.js +44 -12
- package/dist/src/jobs/flow.js +22 -21
- package/dist/src/lint/rule-activation.js +20 -5
- package/dist/src/lint/runner.js +1 -1
- package/dist/src/marketplace/exchange.js +18 -6
- package/dist/src/marketplace/provenance.js +3 -2
- package/dist/src/mcp/adapters/codex-runtime.js +46 -76
- package/dist/src/mcp/cli.mjs +22 -96
- package/dist/src/mcp/config-file.mjs +6 -2
- package/dist/src/mcp/config-layers.mjs +23 -7
- package/dist/src/mcp/grok-build-config.mjs +2 -1
- package/dist/src/mcp/muse-native-config.mjs +2 -1
- package/dist/src/mcp/profiles.js +18 -31
- package/dist/src/mcp/profiles.mjs +18 -32
- package/dist/src/mcp/registry.js +7 -27
- package/dist/src/mcp/registry.mjs +7 -28
- package/dist/src/mcp/server.mjs +34 -1
- package/dist/src/mcp/tools/agentic-sandbox.mjs +8 -7
- package/dist/src/mcp/tools/command-run.mjs +3 -2
- package/dist/src/mcp/tools/decision.mjs +49 -48
- package/dist/src/mcp/tools/discovery.mjs +46 -21
- package/dist/src/mcp/tools/orchestration.mjs +22 -22
- package/dist/src/mcp/tools/subsystems.mjs +9 -8
- package/dist/src/mcp/tools/worker-invoke.mjs +30 -6
- package/dist/src/mcp/tools/writer-profiles.mjs +1 -1
- package/dist/src/memory/audit.js +719 -0
- package/dist/src/memory/canonical-context.js +392 -13
- package/dist/src/memory/canonical-maintenance.js +95 -0
- package/dist/src/memory/cli-result.js +22 -0
- package/dist/src/memory/cli.js +176 -0
- package/dist/src/memory/context-pack.js +57 -6
- package/dist/src/memory/cost.js +512 -0
- package/dist/src/memory/firewall-classification.d.mts +7 -0
- package/dist/src/memory/firewall-classification.mjs +32 -0
- package/dist/src/memory/index.js +8 -0
- package/dist/src/memory/line-maintenance.js +68 -0
- package/dist/src/memory/maintenance-cli.js +286 -0
- package/dist/src/memory/maintenance-contract.js +136 -0
- package/dist/src/memory/maintenance-index.js +18 -0
- package/dist/src/memory/maintenance-owner.js +2 -0
- package/dist/src/memory/maintenance-record.js +138 -0
- package/dist/src/memory/maintenance.js +254 -0
- package/dist/src/memory/project-registry.js +2 -1
- package/dist/src/memory/provider-memory-adapter.js +154 -0
- package/dist/src/memory/recommend-cli.js +83 -0
- package/dist/src/memory/recommend.js +269 -0
- package/dist/src/memory/scheduled.js +81 -0
- package/dist/src/memory/taxonomy.js +44 -0
- package/dist/src/mission-protocol/codecs.js +19 -9
- package/dist/src/mission-protocol/worker-status.js +91 -1
- package/dist/src/models/config-loader.js +11 -1
- package/dist/src/models/model-capabilities.v1.json +74 -50
- package/dist/src/models/provider-policy.js +125 -62
- package/dist/src/models/resolver.js +45 -8
- package/dist/src/models/worker-installation.d.mts +8 -1
- package/dist/src/models/worker-installation.mjs +231 -38
- package/dist/src/models/wrapper-route.js +1 -1
- package/dist/src/output-modes/registry.js +8 -7
- package/dist/src/packages/adapters/git.js +99 -23
- package/dist/src/packages/adapters/gitea.js +8 -27
- package/dist/src/packages/adapters/github.js +7 -25
- package/dist/src/packages/registry.js +4 -4
- package/dist/src/plugin/metadata-validator.js +1 -1
- package/dist/src/process/cli-command.d.mts +5 -0
- package/dist/src/process/cli-command.mjs +42 -0
- package/dist/src/providers/deploy-version.d.mts +1 -0
- package/dist/src/providers/deploy-version.mjs +17 -0
- package/dist/src/providers/provider-definitions.js +19 -16
- package/dist/src/providers/skill-ownership.d.mts +11 -2
- package/dist/src/providers/skill-ownership.mjs +35 -17
- package/dist/src/rules/activation.d.mts +11 -2
- package/dist/src/rules/activation.mjs +82 -6
- package/dist/src/rules/inventory.js +1 -1
- package/dist/src/rules/rule-frontmatter.schema.json +2 -0
- package/dist/src/schema/zod-validation.d.mts +6 -0
- package/dist/src/schema/zod-validation.mjs +50 -0
- package/dist/src/serve/executor-registry.js +297 -20
- package/dist/src/serve/executor-token.d.mts +1 -0
- package/dist/src/serve/executor-token.mjs +8 -0
- package/dist/src/serve/shared-host-scheduler.js +1102 -31
- package/dist/src/serve/worker-invocation.js +124 -15
- package/dist/src/sessions/adapters/claude.js +19 -18
- package/dist/src/sessions/adapters/codex.js +10 -9
- package/dist/src/sessions/adapters/copilot.js +14 -13
- package/dist/src/sessions/adapters/cursor.js +19 -18
- package/dist/src/sessions/adapters/deepseek-harness.js +9 -8
- package/dist/src/sessions/adapters/factory.js +11 -10
- package/dist/src/sessions/adapters/generic.js +32 -23
- package/dist/src/sessions/adapters/grokbot.js +35 -35
- package/dist/src/sessions/adapters/hermes.js +20 -19
- package/dist/src/sessions/adapters/muse.js +50 -49
- package/dist/src/sessions/adapters/omp.js +5 -4
- package/dist/src/sessions/adapters/openclaw.js +30 -29
- package/dist/src/sessions/adapters/opencode.js +26 -26
- package/dist/src/sessions/adapters/openhuman.js +24 -23
- package/dist/src/sessions/adapters/pi.js +5 -4
- package/dist/src/sessions/adapters/windsurf.js +8 -8
- package/dist/src/sessions/analytics.js +10 -9
- package/dist/src/sessions/candidates.js +7 -6
- package/dist/src/sessions/contracts.js +63 -53
- package/dist/src/sessions/output-registration.js +11 -10
- package/dist/src/sessions/workspace-discovery.js +3 -4
- package/dist/src/smiths/context-pipeline/aiwg-md.js +18 -1
- package/dist/src/smiths/context-pipeline/claude-hook.js +46 -10
- package/dist/src/smiths/context-pipeline/context-file-safety.js +330 -9
- package/dist/src/smiths/context-pipeline/finalization.js +3 -2
- package/dist/src/smiths/context-pipeline/generator.js +7 -19
- package/dist/src/smiths/context-pipeline/legacy-inject.js +3 -10
- package/dist/src/smiths/context-pipeline/managed-hook.js +5 -5
- package/dist/src/smiths/context-pipeline/parallelism-section.js +72 -5
- package/dist/src/smiths/context-pipeline/workspace-context.js +110 -22
- package/dist/src/tracker/project-inputs.js +2 -0
- package/dist/src/update/checker.d.mts +4 -0
- package/dist/src/update/checker.mjs +14 -0
- package/dist/src/update/notifier.mjs +2 -4
- package/dist/src/writing/exemplar-selection.js +6 -6
- package/dist/src/writing/voice-evaluation.js +24 -23
- package/dist/src/writing/writer-migration.js +14 -13
- package/dist/src/writing/writer-profile.js +19 -18
- package/dist/src/writing/writing-brief.js +18 -17
- package/dist/src/writing/writing-receipt.js +47 -46
- package/package.json +5 -2
- package/schemas/decision/DecisionReview.schema.json +78 -1
- package/schemas/mission-v1.schema.json +3 -0
- package/tools/agents/deploy-agents.mjs +67 -39
- package/tools/agents/providers/antigravity.mjs +6 -1
- package/tools/agents/providers/base.mjs +24 -14
- package/tools/agents/providers/claude.mjs +6 -3
- package/tools/agents/providers/codex.mjs +54 -57
- package/tools/agents/providers/context-write.mjs +28 -0
- package/tools/agents/providers/copilot.mjs +13 -4
- package/tools/agents/providers/cursor.mjs +1 -1
- package/tools/agents/providers/deepseek-harness.mjs +1 -1
- package/tools/agents/providers/factory.mjs +7 -1
- package/tools/agents/providers/grok-build.mjs +18 -2
- package/tools/agents/providers/grokbot.mjs +1 -1
- package/tools/agents/providers/hermes.mjs +12 -15
- package/tools/agents/providers/muse-hooks.mjs +21 -14
- package/tools/agents/providers/muse.mjs +7 -2
- package/tools/agents/providers/omp.mjs +31 -5
- package/tools/agents/providers/opencode.mjs +14 -5
- package/tools/agents/providers/openhuman.mjs +1 -1
- package/tools/agents/providers/pi.mjs +1 -1
- package/tools/agents/providers/provider-prepare-coordinator.mjs +29 -9
- package/tools/agents/providers/rule-delivery.mjs +289 -80
- package/tools/agents/providers/warp.mjs +4 -1
- package/tools/agents/providers/windsurf.mjs +13 -3
- package/tools/cli/workspace-status.mjs +5 -0
- package/tools/commands/deploy-prompts-codex.mjs +11 -8
- package/tools/ralph-external/lib/codex-adapter.mjs +6 -2
- package/tools/ralph-external/lib/consecutive-failure-circuit-breaker.mjs +26 -0
- package/tools/ralph-external/lib/launcher-recovery-evidence.mjs +7 -1
- package/tools/ralph-external/lib/muse-adapter.mjs +12 -2
- package/tools/ralph-external/lib/recovery-probe.mjs +14 -4
- package/tools/ralph-external/lib/worker-health.mjs +1 -1
- package/tools/ralph-external/lib/worker-isolation.mjs +65 -9
- package/tools/ralph-external/process-monitor.mjs +49 -8
- package/tools/ralph-external/session-launcher.mjs +405 -35
- package/tools/skills/deploy-skills-codex.mjs +11 -7
- package/vscode-extension/schemas/aiwg.config.v1.json +11 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { importImpl } from '../../_resolve-impl.mjs';
|
|
1
2
|
/**
|
|
2
3
|
* OpenAI Codex Provider
|
|
3
4
|
*
|
|
@@ -35,6 +36,7 @@ const staticModelCatalog = _require('../../../agentic/code/providers/model-catal
|
|
|
35
36
|
import path from 'path';
|
|
36
37
|
import os from 'os';
|
|
37
38
|
import { spawn } from 'child_process';
|
|
39
|
+
import { pathToFileURL } from 'node:url';
|
|
38
40
|
import { load as loadYaml } from 'js-yaml';
|
|
39
41
|
import { classifyModelRole, modelForRole } from './model-role.mjs';
|
|
40
42
|
import {
|
|
@@ -66,7 +68,8 @@ import {
|
|
|
66
68
|
parseFrontmatter,
|
|
67
69
|
resolveAiwgRoot
|
|
68
70
|
} from './base.mjs';
|
|
69
|
-
|
|
71
|
+
|
|
72
|
+
import { writeContextFileSync } from './context-write.mjs';
|
|
70
73
|
|
|
71
74
|
function resolveCodexHelperRoot(srcRoot) {
|
|
72
75
|
const resolved = resolveAiwgRoot(srcRoot);
|
|
@@ -101,7 +104,6 @@ export const kernelSkillsPath = '.agents/skills/';
|
|
|
101
104
|
// Legacy home-dir skills location written by AIWG versions prior to the #766
|
|
102
105
|
// regression fix. Pruned on every codex skill deploy so codex-rs stops listing
|
|
103
106
|
// each AIWG skill twice. Never touches non-AIWG (unmarked) skills.
|
|
104
|
-
const legacyHomeSkillsDir = path.join(os.homedir(), '.codex', 'skills');
|
|
105
107
|
|
|
106
108
|
export const support = {
|
|
107
109
|
agents: 'native',
|
|
@@ -125,6 +127,7 @@ export const capabilities = {
|
|
|
125
127
|
* Map model shorthand to OpenAI/GPT format
|
|
126
128
|
*/
|
|
127
129
|
export function mapModel(originalModel, modelCfg, modelsConfig) {
|
|
130
|
+
const modelCatalog = modelCfg.modelCatalog || loadRuntimeModelCatalog(staticModelCatalog);
|
|
128
131
|
const gptModels = {
|
|
129
132
|
'opus': modelCatalog.providers.codex.roles.reasoning.id,
|
|
130
133
|
'sonnet': modelCatalog.providers.codex.roles.coding.id,
|
|
@@ -204,7 +207,7 @@ export function renderAgentToml(srcPath, content, models) {
|
|
|
204
207
|
*/
|
|
205
208
|
export function transformAgent(srcPath, content, opts) {
|
|
206
209
|
const { reasoningModel, codingModel, efficiencyModel } = opts;
|
|
207
|
-
const catalogModels = modelCatalog.providers.codex.roles;
|
|
210
|
+
const catalogModels = (opts.modelCatalog || loadRuntimeModelCatalog(staticModelCatalog)).providers.codex.roles;
|
|
208
211
|
|
|
209
212
|
const models = {
|
|
210
213
|
reasoning: reasoningModel || catalogModels.reasoning.id,
|
|
@@ -239,6 +242,27 @@ export function deployAgents(agentFiles, targetDir, opts) {
|
|
|
239
242
|
}, transformAgent);
|
|
240
243
|
}
|
|
241
244
|
|
|
245
|
+
/** Run the helper in this pass; retain process isolation for troubleshooting. */
|
|
246
|
+
async function runCodexDeployer(scriptPath, args, helperRoot, opts) {
|
|
247
|
+
if (process.env.AIWG_DEPLOY_SUBPROCESS !== '1') {
|
|
248
|
+
const deployer = await import(pathToFileURL(scriptPath).href);
|
|
249
|
+
await deployer.main(args, { homeDir: opts.deploymentHome || os.homedir() });
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
await new Promise((resolve, reject) => {
|
|
253
|
+
const child = spawn('node', [scriptPath, ...args], {
|
|
254
|
+
stdio: 'inherit',
|
|
255
|
+
cwd: helperRoot,
|
|
256
|
+
env: opts.deploymentHome ? { ...process.env, HOME: opts.deploymentHome } : process.env,
|
|
257
|
+
});
|
|
258
|
+
child.on('close', code => {
|
|
259
|
+
if (code === 0) resolve();
|
|
260
|
+
else reject(new Error(`${path.basename(scriptPath)} exited with code ${code}`));
|
|
261
|
+
});
|
|
262
|
+
child.on('error', reject);
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
|
|
242
266
|
/**
|
|
243
267
|
* Deploy commands via external script
|
|
244
268
|
*
|
|
@@ -257,30 +281,16 @@ export async function deployCommands(targetDir, srcRoot, opts) {
|
|
|
257
281
|
|
|
258
282
|
console.log('Delegating command deployment to deploy-prompts-codex.mjs (~/.codex/prompts/)...');
|
|
259
283
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
const child = spawn('node', [scriptPath, ...args], {
|
|
272
|
-
stdio: 'inherit',
|
|
273
|
-
cwd: helperRoot,
|
|
274
|
-
env: opts.deploymentHome ? { ...process.env, HOME: opts.deploymentHome } : process.env
|
|
275
|
-
});
|
|
276
|
-
|
|
277
|
-
child.on('close', (code) => {
|
|
278
|
-
if (code === 0) resolve();
|
|
279
|
-
else reject(new Error(`deploy-prompts-codex.mjs exited with code ${code}`));
|
|
280
|
-
});
|
|
281
|
-
|
|
282
|
-
child.on('error', reject);
|
|
283
|
-
});
|
|
284
|
+
// NOTE: Do NOT pass --target - Codex prompts belong in ~/.codex/prompts/ (home)
|
|
285
|
+
const args = ['--source', srcRoot];
|
|
286
|
+
if (opts.dryRun) args.push('--dry-run');
|
|
287
|
+
if (opts.force) args.push('--force');
|
|
288
|
+
if (opts.mode) args.push('--mode', opts.mode);
|
|
289
|
+
if (opts.copyStandardSkills === true) args.push('--copy-all');
|
|
290
|
+
// A copy-all the deployer forced on the caller's behalf (project-local
|
|
291
|
+
// bundles) still honors the startup listing cap (#2561).
|
|
292
|
+
if (opts.listingBudget === true) args.push('--listing-budget');
|
|
293
|
+
await runCodexDeployer(scriptPath, args, helperRoot, opts);
|
|
284
294
|
}
|
|
285
295
|
|
|
286
296
|
/**
|
|
@@ -305,37 +315,23 @@ export async function deploySkills(targetDir, srcRoot, opts) {
|
|
|
305
315
|
const crossAgentSkillsDir = path.join(targetDir, '.agents', 'skills');
|
|
306
316
|
console.log(`Deploying skills to ${crossAgentSkillsDir} (.agents/skills — codex-scanned path)...`);
|
|
307
317
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
const child = spawn('node', [scriptPath, ...args], {
|
|
322
|
-
stdio: 'inherit',
|
|
323
|
-
cwd: helperRoot,
|
|
324
|
-
env: opts.deploymentHome ? { ...process.env, HOME: opts.deploymentHome } : process.env
|
|
325
|
-
});
|
|
326
|
-
|
|
327
|
-
child.on('close', (code) => {
|
|
328
|
-
if (code === 0) resolve();
|
|
329
|
-
else reject(new Error(`deploy-skills-codex.mjs exited with code ${code}`));
|
|
330
|
-
});
|
|
331
|
-
|
|
332
|
-
child.on('error', reject);
|
|
333
|
-
});
|
|
318
|
+
const args = ['--source', srcRoot, '--target', crossAgentSkillsDir];
|
|
319
|
+
// Overflow past Codex's startup listing cap lands here instead of being
|
|
320
|
+
// deployed over the cap (#2561); the index still reaches these skills.
|
|
321
|
+
args.push('--standard-target', path.join(targetDir, ...paths.skills.split('/').filter(Boolean)));
|
|
322
|
+
if (opts.dryRun) args.push('--dry-run');
|
|
323
|
+
if (opts.force) args.push('--force');
|
|
324
|
+
if (opts.mode) args.push('--mode', opts.mode);
|
|
325
|
+
if (opts.copyStandardSkills === true) args.push('--copy-all');
|
|
326
|
+
// A copy-all the deployer forced on the caller's behalf (project-local
|
|
327
|
+
// bundles) still honors the startup listing cap (#2561).
|
|
328
|
+
if (opts.listingBudget === true) args.push('--listing-budget');
|
|
329
|
+
await runCodexDeployer(scriptPath, args, helperRoot, opts);
|
|
334
330
|
|
|
335
331
|
// Self-heal: prune AIWG-managed skill dirs left behind in the legacy
|
|
336
332
|
// ~/.codex/skills/ home location by pre-fix versions, so codex-rs stops
|
|
337
333
|
// listing each skill twice.
|
|
338
|
-
pruneLegacyCodexSkills(opts, opts.legacyCodexSkills ||
|
|
334
|
+
pruneLegacyCodexSkills(opts, opts.legacyCodexSkills || path.join(os.homedir(), '.codex', 'skills'));
|
|
339
335
|
}
|
|
340
336
|
|
|
341
337
|
/**
|
|
@@ -346,7 +342,7 @@ export async function deploySkills(targetDir, srcRoot, opts) {
|
|
|
346
342
|
* the `.aiwg-managed` marker are removed — user-authored skills are never
|
|
347
343
|
* touched. The now-empty legacy dir is removed if AIWG owned everything in it.
|
|
348
344
|
*/
|
|
349
|
-
export function pruneLegacyCodexSkills(opts = {}, legacyDir =
|
|
345
|
+
export function pruneLegacyCodexSkills(opts = {}, legacyDir = path.join(os.homedir(), '.codex', 'skills')) {
|
|
350
346
|
let entries;
|
|
351
347
|
try {
|
|
352
348
|
entries = fs.readdirSync(legacyDir, { withFileTypes: true });
|
|
@@ -401,6 +397,7 @@ export function deployRules(ruleFiles, targetDir, opts) {
|
|
|
401
397
|
* Aggregate agents to single AGENTS.md file
|
|
402
398
|
*/
|
|
403
399
|
export function aggregateToAgentsMd(agentFiles, destPath, opts) {
|
|
400
|
+
if (opts.contextFiles === false) return 0;
|
|
404
401
|
const lines = ['# AIWG agent definitions', '', 'Read the selected definition before invoking an agent.', ''];
|
|
405
402
|
for (const file of agentFiles) {
|
|
406
403
|
const { metadata } = parseFrontmatter(fs.readFileSync(file, 'utf8'));
|
|
@@ -409,7 +406,7 @@ export function aggregateToAgentsMd(agentFiles, destPath, opts) {
|
|
|
409
406
|
}
|
|
410
407
|
const out = `${lines.join('\n')}\n`;
|
|
411
408
|
if (opts.dryRun) console.log(`[dry-run] write ${destPath}`);
|
|
412
|
-
else
|
|
409
|
+
else writeContextFileSync(destPath, out, 'utf8');
|
|
413
410
|
|
|
414
411
|
}
|
|
415
412
|
|
|
@@ -518,7 +515,7 @@ export async function postDeploy(targetDir, opts) {
|
|
|
518
515
|
initializeFrameworkWorkspace(targetDir, opts.mode, opts.dryRun, opts.srcRoot);
|
|
519
516
|
|
|
520
517
|
if (opts.createAgentsMd) {
|
|
521
|
-
createAgentsMd(targetDir, opts.srcRoot, opts.dryRun);
|
|
518
|
+
if (opts.contextFiles !== false) createAgentsMd(targetDir, opts.srcRoot, opts.dryRun);
|
|
522
519
|
}
|
|
523
520
|
}
|
|
524
521
|
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context-file writes for deployment providers (#3037).
|
|
3
|
+
*
|
|
4
|
+
* The journaled writer lives in compiled TypeScript. In source-resolution
|
|
5
|
+
* mode (AIWG_RESOLVE_IMPL_FROM=src without a TS loader) it cannot load, and
|
|
6
|
+
* read-only consumers of provider modules (for example the remotes topology
|
|
7
|
+
* block) must still import cleanly. Writes then fail closed with the original
|
|
8
|
+
* load error, so nothing ever writes context files without the safety layer.
|
|
9
|
+
*/
|
|
10
|
+
import { importImpl } from '../../_resolve-impl.mjs';
|
|
11
|
+
|
|
12
|
+
// Mirrors CONTEXT_STAGE_ENV in src/smiths/context-pipeline/context-file-safety.ts.
|
|
13
|
+
export const CONTEXT_STAGE_ENV = 'AIWG_CONTEXT_STAGE_LOG';
|
|
14
|
+
|
|
15
|
+
let loadError = null;
|
|
16
|
+
let writer = null;
|
|
17
|
+
try {
|
|
18
|
+
writer = await importImpl(import.meta.url, 'smiths/context-pipeline/context-file-safety.js');
|
|
19
|
+
} catch (error) {
|
|
20
|
+
loadError = error;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function writeContextFileSync(file, content, encoding) {
|
|
24
|
+
if (!writer) {
|
|
25
|
+
throw new Error(`Context-file safety layer is unavailable; refusing to write ${file}`, { cause: loadError });
|
|
26
|
+
}
|
|
27
|
+
return writer.writeContextFileSync(file, content, encoding);
|
|
28
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { importImpl } from '../../_resolve-impl.mjs';
|
|
1
2
|
/**
|
|
2
3
|
* GitHub Copilot Provider
|
|
3
4
|
*
|
|
@@ -27,6 +28,7 @@ let fs;
|
|
|
27
28
|
try { const gfs = _require('graceful-fs'); gfs.gracefulify(realFs); fs = realFs; } catch { fs = realFs; }
|
|
28
29
|
import path from 'path';
|
|
29
30
|
import {
|
|
31
|
+
withRuleDeployment,
|
|
30
32
|
ensureDir,
|
|
31
33
|
listMdFiles,
|
|
32
34
|
listMdFilesRecursive,
|
|
@@ -53,6 +55,8 @@ import {
|
|
|
53
55
|
deploySoulCompanions,
|
|
54
56
|
loadRuntimeModelCatalog
|
|
55
57
|
} from './base.mjs';
|
|
58
|
+
|
|
59
|
+
import { writeContextFileSync } from './context-write.mjs';
|
|
56
60
|
const modelCatalog = loadRuntimeModelCatalog(staticModelCatalog);
|
|
57
61
|
|
|
58
62
|
// ============================================================================
|
|
@@ -429,6 +433,7 @@ export function deploySkills(skillDirs, targetDir, opts) {
|
|
|
429
433
|
* Deploy rules to .github/instructions/ as .instructions.md files
|
|
430
434
|
*/
|
|
431
435
|
export function deployRules(ruleFiles, targetDir, opts) {
|
|
436
|
+
if (opts.ruleDelivery) return [];
|
|
432
437
|
const destDir = path.join(targetDir, paths.rules);
|
|
433
438
|
ensureDir(destDir, opts.dryRun);
|
|
434
439
|
cleanupOldRuleFiles(destDir, opts);
|
|
@@ -475,14 +480,14 @@ export function createCopilotInstructions(target, srcRoot, dryRun) {
|
|
|
475
480
|
if (dryRun) {
|
|
476
481
|
console.log(`[dry-run] Would update existing copilot-instructions.md with AIWG section`);
|
|
477
482
|
} else {
|
|
478
|
-
|
|
483
|
+
writeContextFileSync(destPath, combined, 'utf8');
|
|
479
484
|
console.log('Updated copilot-instructions.md with AIWG SDLC framework section');
|
|
480
485
|
}
|
|
481
486
|
} else {
|
|
482
487
|
if (dryRun) {
|
|
483
488
|
console.log(`[dry-run] Would create copilot-instructions.md from template`);
|
|
484
489
|
} else {
|
|
485
|
-
|
|
490
|
+
writeContextFileSync(destPath, template, 'utf8');
|
|
486
491
|
console.log('Created copilot-instructions.md from template');
|
|
487
492
|
}
|
|
488
493
|
}
|
|
@@ -495,8 +500,8 @@ export function createCopilotInstructions(target, srcRoot, dryRun) {
|
|
|
495
500
|
export async function postDeploy(targetDir, opts) {
|
|
496
501
|
initializeFrameworkWorkspace(targetDir, opts.mode, opts.dryRun, opts.srcRoot);
|
|
497
502
|
|
|
498
|
-
//
|
|
499
|
-
createCopilotInstructions(targetDir, opts.srcRoot, opts.dryRun);
|
|
503
|
+
// copilot-instructions.md is Copilot's context file: --no-context-files leaves it alone.
|
|
504
|
+
if (opts.contextFiles !== false) createCopilotInstructions(targetDir, opts.srcRoot, opts.dryRun);
|
|
500
505
|
}
|
|
501
506
|
|
|
502
507
|
// ============================================================================
|
|
@@ -517,6 +522,10 @@ export function getFileExtension(type) {
|
|
|
517
522
|
// ============================================================================
|
|
518
523
|
|
|
519
524
|
export async function deploy(opts) {
|
|
525
|
+
return withRuleDeployment(opts, { name, paths, kernelSkillsPath }, deploySelected);
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
async function deploySelected(opts) {
|
|
520
529
|
const {
|
|
521
530
|
srcRoot,
|
|
522
531
|
target,
|
|
@@ -414,7 +414,7 @@ export async function postDeploy(targetDir, opts) {
|
|
|
414
414
|
initializeFrameworkWorkspace(targetDir, opts.mode, opts.dryRun, opts.srcRoot);
|
|
415
415
|
|
|
416
416
|
if (opts.createAgentsMd) {
|
|
417
|
-
createAgentsMd(targetDir, opts.srcRoot, opts.dryRun);
|
|
417
|
+
if (opts.contextFiles !== false) createAgentsMd(targetDir, opts.srcRoot, opts.dryRun);
|
|
418
418
|
}
|
|
419
419
|
|
|
420
420
|
// PUW-019 (#1120): wire environment.json + worktrees.json templates.
|
|
@@ -46,7 +46,7 @@ export function deployCordisPatch(target, opts) {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
export async function postDeploy(target, opts) {
|
|
49
|
-
if (opts.createAgentsMd || (!opts.commandsOnly && !opts.skillsOnly && !opts.rulesOnly)) createAgentsMd(target, opts.srcRoot, opts.dryRun);
|
|
49
|
+
if (opts.contextFiles !== false && (opts.createAgentsMd || (!opts.commandsOnly && !opts.skillsOnly && !opts.rulesOnly))) createAgentsMd(target, opts.srcRoot, opts.dryRun);
|
|
50
50
|
if (!opts.quiet) console.log('DeepSeek Harness: runtime credentials remain environment-only; use a reviewed ephemeral route patch.');
|
|
51
51
|
}
|
|
52
52
|
|
|
@@ -25,6 +25,7 @@ let fs;
|
|
|
25
25
|
try { const gfs = _require('graceful-fs'); gfs.gracefulify(realFs); fs = realFs; } catch { fs = realFs; }
|
|
26
26
|
import path from 'path';
|
|
27
27
|
import {
|
|
28
|
+
withRuleDeployment,
|
|
28
29
|
ensureDir,
|
|
29
30
|
listMdFiles,
|
|
30
31
|
listMdFilesRecursive,
|
|
@@ -576,6 +577,7 @@ export function deploySkills(skillDirs, targetDir, opts) {
|
|
|
576
577
|
* Deploy rules to .factory/rules/
|
|
577
578
|
*/
|
|
578
579
|
export function deployRules(ruleFiles, targetDir, opts) {
|
|
580
|
+
if (opts.ruleDelivery) return [];
|
|
579
581
|
const destDir = path.join(targetDir, paths.rules);
|
|
580
582
|
ensureDir(destDir, opts.dryRun);
|
|
581
583
|
cleanupOldRuleFiles(destDir, opts);
|
|
@@ -816,7 +818,7 @@ export async function postDeploy(targetDir, opts) {
|
|
|
816
818
|
|
|
817
819
|
// Create/update AGENTS.md if requested
|
|
818
820
|
if (opts.createAgentsMd) {
|
|
819
|
-
createAgentsMd(targetDir, opts.srcRoot, opts.dryRun);
|
|
821
|
+
if (opts.contextFiles !== false) createAgentsMd(targetDir, opts.srcRoot, opts.dryRun);
|
|
820
822
|
}
|
|
821
823
|
}
|
|
822
824
|
|
|
@@ -945,6 +947,10 @@ export function getFileExtension(type) {
|
|
|
945
947
|
* Main deployment function for Factory provider
|
|
946
948
|
*/
|
|
947
949
|
export async function deploy(opts) {
|
|
950
|
+
return withRuleDeployment(opts, { name, paths, kernelSkillsPath, transformSkillMd: transformSkillFrontmatter }, deploySelected);
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
async function deploySelected(opts) {
|
|
948
954
|
const {
|
|
949
955
|
srcRoot,
|
|
950
956
|
target,
|
|
@@ -16,6 +16,8 @@ import fs from 'node:fs';
|
|
|
16
16
|
import { createHash, randomUUID } from 'node:crypto';
|
|
17
17
|
import yaml from 'js-yaml';
|
|
18
18
|
import {
|
|
19
|
+
withRuleDeployment,
|
|
20
|
+
replaceBoundRulesBlock,
|
|
19
21
|
createAgentsMdFromTemplate,
|
|
20
22
|
deploySkillsWithKernelRouting,
|
|
21
23
|
collectFrameworkArtifacts,
|
|
@@ -224,7 +226,17 @@ function matchesSkillSource(source, target) {
|
|
|
224
226
|
if (relative.endsWith(path.sep)) return true;
|
|
225
227
|
let content = fs.readFileSync(path.join(source, relative), 'utf8');
|
|
226
228
|
if (relative === 'SKILL.md') content = injectPlatformInContent(content, 'grok-build');
|
|
227
|
-
|
|
229
|
+
const deployed = fs.readFileSync(path.join(target, relative), 'utf8');
|
|
230
|
+
if (content === deployed) return true;
|
|
231
|
+
if (relative !== 'SKILL.md' || !deployed.includes('<!-- AIWG:bound-rules:start -->')) return false;
|
|
232
|
+
// Activation projection appends generated bindings. Verify the complete
|
|
233
|
+
// deployed bytes against the receipt before comparing the authored body;
|
|
234
|
+
// an operator edit (including inside the binding block) must survive.
|
|
235
|
+
const receipt = JSON.parse(fs.readFileSync(path.join(target, '.aiwg-manifest.json'), 'utf8'));
|
|
236
|
+
const digest = `sha256:${createHash('sha256').update(deployed).digest('hex')}`;
|
|
237
|
+
return receipt.skillSource === path.resolve(source)
|
|
238
|
+
&& receipt.managed?.[relative]?.hash === digest
|
|
239
|
+
&& replaceBoundRulesBlock(content, []).trimEnd() === replaceBoundRulesBlock(deployed, []).trimEnd();
|
|
228
240
|
});
|
|
229
241
|
} catch { return false; }
|
|
230
242
|
}
|
|
@@ -326,7 +338,7 @@ export function uninstall(target, opts = {}) {
|
|
|
326
338
|
|
|
327
339
|
export async function postDeploy(target, opts = {}) {
|
|
328
340
|
if (opts.createAgentsMd || (!opts.commandsOnly && !opts.skillsOnly && !opts.rulesOnly)) {
|
|
329
|
-
createAgentsMd(target, opts.srcRoot, opts.dryRun);
|
|
341
|
+
if (opts.contextFiles !== false) createAgentsMd(target, opts.srcRoot, opts.dryRun);
|
|
330
342
|
}
|
|
331
343
|
if (!opts.quiet) {
|
|
332
344
|
const home = resolveGrokHome(opts.env || process.env);
|
|
@@ -344,6 +356,10 @@ export function getFileExtension() {
|
|
|
344
356
|
}
|
|
345
357
|
|
|
346
358
|
export async function deploy(opts) {
|
|
359
|
+
return withRuleDeployment(opts, { name, paths, kernelSkillsPath }, deploySelected);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
async function deploySelected(opts) {
|
|
347
363
|
const mode = normalizeDeploymentMode(opts.mode);
|
|
348
364
|
if (opts.createAgentsMd || (!opts.commandsOnly && !opts.skillsOnly && !opts.rulesOnly)) {
|
|
349
365
|
assertSafeAgentsMd(opts.target);
|
|
@@ -171,7 +171,7 @@ export async function postDeploy(targetDir, opts = {}) {
|
|
|
171
171
|
opts.createAgentsMd ||
|
|
172
172
|
(!opts.commandsOnly && !opts.skillsOnly && !opts.rulesOnly)
|
|
173
173
|
) {
|
|
174
|
-
createAgentsMd(targetDir, opts.srcRoot, opts.dryRun);
|
|
174
|
+
if (opts.contextFiles !== false) createAgentsMd(targetDir, opts.srcRoot, opts.dryRun);
|
|
175
175
|
}
|
|
176
176
|
if (!opts.quiet) {
|
|
177
177
|
const root = resolveGrokbotSkillsDir(opts.env || process.env);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { importImpl } from '../../_resolve-impl.mjs';
|
|
1
2
|
/**
|
|
2
3
|
* Hermes Agent Provider
|
|
3
4
|
*
|
|
@@ -41,6 +42,8 @@ import {
|
|
|
41
42
|
stripPlatformsFromContent,
|
|
42
43
|
} from './base.mjs';
|
|
43
44
|
|
|
45
|
+
import { writeContextFileSync } from './context-write.mjs';
|
|
46
|
+
|
|
44
47
|
// ============================================================================
|
|
45
48
|
// Hermes home resolution (HERMES_HOME) — #2119
|
|
46
49
|
// ============================================================================
|
|
@@ -224,9 +227,9 @@ export function assertContextBudget(content, name = 'AGENTS.md', rules = []) {
|
|
|
224
227
|
* priming on every Hermes turn (#1318 / S7; skill-discovery added #1347).
|
|
225
228
|
*
|
|
226
229
|
* The full rule bodies are reachable without MCP via `aiwg discover` and
|
|
227
|
-
* `aiwg show rule <name
|
|
230
|
+
* `aiwg show rule <name> --body`; MCP exposes the same path through `rule-list` and
|
|
228
231
|
* `rule-show` when configured (#1320). The bodies exceed Hermes's 20K context
|
|
229
|
-
* cap if inlined verbatim (anti-laziness alone
|
|
232
|
+
* cap if inlined verbatim (anti-laziness alone was 32K chars; it now ships as a compact core body, #3450), so we inline
|
|
230
233
|
* compressed directives only and point to CLI/MCP for the full text.
|
|
231
234
|
*
|
|
232
235
|
* Selection criteria: rules tagged CRITICAL/HIGH enforcement level whose
|
|
@@ -240,7 +243,7 @@ const CRITICAL_RULE_DIRECTIVES = `## CRITICAL Rules (always apply)
|
|
|
240
243
|
These are the highest-enforcement AIWG rules. Full bodies are reachable without
|
|
241
244
|
MCP:
|
|
242
245
|
- Find rules: \`aiwg discover "rule <topic>" --type rule\`
|
|
243
|
-
- Fetch a rule: \`aiwg show rule <name
|
|
246
|
+
- Fetch a rule: \`aiwg show rule <name> --body\`
|
|
244
247
|
|
|
245
248
|
If the optional MCP sidecar is configured, the same surface is available through
|
|
246
249
|
\`mcp_aiwg_rule_list\` and \`mcp_aiwg_rule_show\`.
|
|
@@ -260,13 +263,6 @@ Never add AI-tool attribution to commits, PRs, code, or docs. No \`Co-Authored-B
|
|
|
260
263
|
no "Generated with", no "Written by [AI tool]". The AI is a tool; tools don't sign
|
|
261
264
|
their output. Applies to ALL platforms (Claude, Codex, Copilot, Cursor, etc.).
|
|
262
265
|
|
|
263
|
-
### Rule: anti-laziness
|
|
264
|
-
Never delete tests to make them pass. Never skip/disable tests. Never remove
|
|
265
|
-
features instead of fixing them. Never weaken assertions to be meaningless.
|
|
266
|
-
Never suppress CI/pipeline signals (\`continue-on-error\`, \`|| true\`, \`set +e\`).
|
|
267
|
-
If stuck after 3 honest attempts: escalate with full context, don't shortcut.
|
|
268
|
-
Within scope: leave nothing half-done — code + tests + docs + verification.
|
|
269
|
-
|
|
270
266
|
### Rule: citation-policy
|
|
271
267
|
Never fabricate citations, DOIs, URLs, or page numbers. Only cite sources that
|
|
272
268
|
exist in the research corpus (.aiwg/research/sources/). Match claim strength
|
|
@@ -331,6 +327,7 @@ function mergeHermesContext(file, generated, kind) {
|
|
|
331
327
|
}
|
|
332
328
|
|
|
333
329
|
export function generateAgentsMd(agentCount, skillCount, targetDir, opts) {
|
|
330
|
+
if (opts.contextFiles === false) return;
|
|
334
331
|
const { dryRun } = opts;
|
|
335
332
|
|
|
336
333
|
// Startup is reserved for rule contracts. Workflow routing, artifact catalogs,
|
|
@@ -339,7 +336,7 @@ export function generateAgentsMd(agentCount, skillCount, targetDir, opts) {
|
|
|
339
336
|
const header = `# AIWG Integration
|
|
340
337
|
|
|
341
338
|
Skills: \`$HERMES_HOME/skills/\` (kernel), \`$HERMES_HOME/skills/.aiwg/\` (standard).
|
|
342
|
-
Find: \`aiwg discover "rule <topic>" --type rule\`. Fetch: \`aiwg show rule <name
|
|
339
|
+
Find: \`aiwg discover "rule <topic>" --type rule\`. Fetch: \`aiwg show rule <name> --body\`.
|
|
343
340
|
MCP is optional; \`mcp_aiwg_rule_show\` exposes the same rule catalog.
|
|
344
341
|
`;
|
|
345
342
|
|
|
@@ -361,7 +358,7 @@ MCP is optional; \`mcp_aiwg_rule_show\` exposes the same rule catalog.
|
|
|
361
358
|
if (dryRun) {
|
|
362
359
|
console.log(`[dry-run] Would write AGENTS.md (${output.length} chars, ${Math.round(output.length / 4)} tokens estimated)`);
|
|
363
360
|
} else {
|
|
364
|
-
|
|
361
|
+
writeContextFileSync(destPath, output, 'utf8');
|
|
365
362
|
const charCount = output.length;
|
|
366
363
|
const tokenEstimate = Math.round(charCount / 4);
|
|
367
364
|
let budgetNote;
|
|
@@ -403,7 +400,7 @@ when the full AIWG project context is needed.
|
|
|
403
400
|
if (dryRun) {
|
|
404
401
|
console.log(`[dry-run] Would write .hermes.md (${body.length} chars)`);
|
|
405
402
|
} else {
|
|
406
|
-
|
|
403
|
+
writeContextFileSync(destPath, mergeHermesContext(destPath, body, 'routing'), 'utf8');
|
|
407
404
|
console.log(` Created .hermes.md (${body.length} chars)`);
|
|
408
405
|
}
|
|
409
406
|
return 1;
|
|
@@ -533,7 +530,7 @@ async function deploySelected(opts) {
|
|
|
533
530
|
// Generate AGENTS.md (with inlined CRITICAL rule priming, #1318/#1532)
|
|
534
531
|
// AND .hermes.md thin pointer (resolves #1319 doc-debt, was claimed in
|
|
535
532
|
// CHANGELOG but not previously implemented).
|
|
536
|
-
if (!skillsOnly && !opts.commandsOnly && !opts.rulesOnly) {
|
|
533
|
+
if (opts.contextFiles !== false && !skillsOnly && !opts.commandsOnly && !opts.rulesOnly) {
|
|
537
534
|
const artifacts = collectFrameworkArtifacts(srcRoot, normalizedMode, {
|
|
538
535
|
includeAgents: true,
|
|
539
536
|
includeCommands: false,
|
|
@@ -560,7 +557,7 @@ async function deploySelected(opts) {
|
|
|
560
557
|
if (!opts.quiet) {
|
|
561
558
|
console.log('');
|
|
562
559
|
console.log(`Skills root: ${kernelSkillsPath}`);
|
|
563
|
-
console.log('Rules are in AGENTS.md as compressed directives; full bodies via `aiwg show rule <name
|
|
560
|
+
console.log('Rules are in AGENTS.md as compressed directives; full bodies via `aiwg show rule <name> --body`.');
|
|
564
561
|
console.log('Optional: configure config.yaml to connect AIWG MCP server.');
|
|
565
562
|
console.log('See: docs/integrations/hermes-quickstart.md (optional MCP setup)');
|
|
566
563
|
}
|
|
@@ -43,9 +43,7 @@
|
|
|
43
43
|
* Servers inherit the operator's process environment; pass `MUSE_SESSION_ID`
|
|
44
44
|
* through at runtime instead of hardcoding a session id into `env`.
|
|
45
45
|
*
|
|
46
|
-
*
|
|
47
|
-
* muse-paths.mjs only) so provider-policy-style import graphs never pull it
|
|
48
|
-
* in transitively.
|
|
46
|
+
* MCP writes use the shared config writer, resolved for source and packaged installs.
|
|
49
47
|
*
|
|
50
48
|
* @issue #228
|
|
51
49
|
*/
|
|
@@ -53,9 +51,13 @@
|
|
|
53
51
|
import fs from 'node:fs';
|
|
54
52
|
import os from 'node:os';
|
|
55
53
|
import path from 'node:path';
|
|
54
|
+
import { randomUUID } from 'node:crypto';
|
|
55
|
+
import { importImpl } from '../../_resolve-impl.mjs';
|
|
56
56
|
import { stripJsonComments } from './base.mjs';
|
|
57
57
|
import { resolveMuseXdgSkillsDir, museXdgSkillsDirRemediation } from './muse-paths.mjs';
|
|
58
58
|
|
|
59
|
+
const { assertConfigDestination, writeConfigAtomic, writeConfigTransaction } = await importImpl(import.meta.url, 'mcp/config-file.mjs');
|
|
60
|
+
|
|
59
61
|
// ---------------------------------------------------------------------------
|
|
60
62
|
// Shared JSON helpers
|
|
61
63
|
// ---------------------------------------------------------------------------
|
|
@@ -631,7 +633,7 @@ export function mergeMcpProfile(existingDoc, opts = {}) {
|
|
|
631
633
|
* preserving unknown keys, timestamped backup before writing, atomic write,
|
|
632
634
|
* dry-run diff with zero writes, fail closed on unparseable settings.
|
|
633
635
|
*/
|
|
634
|
-
export function deployMuseMcp(opts = {}) {
|
|
636
|
+
export async function deployMuseMcp(opts = {}) {
|
|
635
637
|
const { dryRun = false, quiet = false, mcp = false, env = process.env, userHome = os.homedir() } = opts;
|
|
636
638
|
const log = quiet ? () => {} : (msg) => console.log(msg);
|
|
637
639
|
|
|
@@ -642,6 +644,8 @@ export function deployMuseMcp(opts = {}) {
|
|
|
642
644
|
|
|
643
645
|
const settingsPath = assertMuseUserSettingsPath(env, userHome);
|
|
644
646
|
const configDir = path.dirname(settingsPath);
|
|
647
|
+
await assertConfigDestination(settingsPath);
|
|
648
|
+
await assertConfigDestination(path.join(configDir, MUSE_MCP_SIDECAR_NAME));
|
|
645
649
|
const { doc: existingDoc, raw: existingRaw, existed } = readSettingsDoc(settingsPath);
|
|
646
650
|
const sidecar = readMcpSidecar(configDir);
|
|
647
651
|
const profile = aiwgMcpServerProfile();
|
|
@@ -680,14 +684,15 @@ export function deployMuseMcp(opts = {}) {
|
|
|
680
684
|
return { settingsPath, changed: true, plan, wrote: false, warnings };
|
|
681
685
|
}
|
|
682
686
|
|
|
683
|
-
fs.mkdirSync(configDir, { recursive: true });
|
|
684
687
|
let backupPath = null;
|
|
685
688
|
if (existed) {
|
|
686
|
-
backupPath = `${settingsPath}.aiwg-backup-${new Date().toISOString().replace(/[:.]/g, '-')}`;
|
|
687
|
-
|
|
689
|
+
backupPath = `${settingsPath}.aiwg-backup-${new Date().toISOString().replace(/[:.]/g, '-')}-${randomUUID()}`;
|
|
690
|
+
await writeConfigAtomic(backupPath, existingRaw, { userScope: true });
|
|
688
691
|
}
|
|
689
|
-
|
|
690
|
-
|
|
692
|
+
await writeConfigTransaction([
|
|
693
|
+
{ file: settingsPath, content: afterText, options: { userScope: true } },
|
|
694
|
+
{ file: sidecar.path, content: canonicalJson({ version: 1, servers: ['aiwg'] }), options: { userScope: true } },
|
|
695
|
+
]);
|
|
691
696
|
|
|
692
697
|
log(`Muse MCP: merged AIWG stdio profile into ${settingsPath}`);
|
|
693
698
|
for (const step of plan) log(` ${step}`);
|
|
@@ -700,11 +705,13 @@ export function deployMuseMcp(opts = {}) {
|
|
|
700
705
|
* Removal path: drop the AIWG-managed `aiwg` server key (only when recorded
|
|
701
706
|
* in the sidecar) and delete the sidecar. Operator servers are never touched.
|
|
702
707
|
*/
|
|
703
|
-
export function pruneMuseMcp(opts = {}) {
|
|
708
|
+
export async function pruneMuseMcp(opts = {}) {
|
|
704
709
|
const { dryRun = false, quiet = false, env = process.env, userHome = os.homedir() } = opts;
|
|
705
710
|
const log = quiet ? () => {} : (msg) => console.log(msg);
|
|
706
711
|
const settingsPath = assertMuseUserSettingsPath(env, userHome);
|
|
707
712
|
const configDir = path.dirname(settingsPath);
|
|
713
|
+
await assertConfigDestination(settingsPath);
|
|
714
|
+
await assertConfigDestination(path.join(configDir, MUSE_MCP_SIDECAR_NAME));
|
|
708
715
|
|
|
709
716
|
if (!fs.existsSync(settingsPath)) {
|
|
710
717
|
log(`Muse MCP: no ${settingsPath}; nothing to prune.`);
|
|
@@ -731,10 +738,10 @@ export function pruneMuseMcp(opts = {}) {
|
|
|
731
738
|
return { settingsPath, pruned: true, wrote: false };
|
|
732
739
|
}
|
|
733
740
|
|
|
734
|
-
const backupPath = `${settingsPath}.aiwg-backup-${new Date().toISOString().replace(/[:.]/g, '-')}`;
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
if (
|
|
741
|
+
const backupPath = `${settingsPath}.aiwg-backup-${new Date().toISOString().replace(/[:.]/g, '-')}-${randomUUID()}`;
|
|
742
|
+
await writeConfigAtomic(backupPath, existingRaw, { userScope: true });
|
|
743
|
+
await writeConfigAtomic(settingsPath, canonicalJson(merged), { userScope: true });
|
|
744
|
+
if (await assertConfigDestination(sidecar.path)) fs.unlinkSync(sidecar.path);
|
|
738
745
|
log(`Muse MCP: removed mcp_servers.aiwg from ${settingsPath} (backup: ${backupPath}).`);
|
|
739
746
|
return { settingsPath, pruned: true, wrote: true, backupPath };
|
|
740
747
|
}
|
|
@@ -35,6 +35,7 @@ import fs from 'node:fs';
|
|
|
35
35
|
import os from 'node:os';
|
|
36
36
|
import path from 'node:path';
|
|
37
37
|
import {
|
|
38
|
+
withRuleDeployment,
|
|
38
39
|
collectFrameworkArtifacts,
|
|
39
40
|
createAgentsMdFromTemplate,
|
|
40
41
|
deploySkillsWithKernelRouting,
|
|
@@ -226,7 +227,7 @@ export async function postDeploy(targetDir, opts = {}) {
|
|
|
226
227
|
// bridge, managed hooks, and an opted-in MCP profile must not be skipped.
|
|
227
228
|
const fullDeploy = !opts.commandsOnly && !opts.rulesOnly && (!opts.skillsOnly || opts.kernelOnly === true);
|
|
228
229
|
if (opts.createAgentsMd || fullDeploy) {
|
|
229
|
-
createAgentsMd(targetDir, opts.srcRoot, opts.dryRun);
|
|
230
|
+
if (opts.contextFiles !== false) createAgentsMd(targetDir, opts.srcRoot, opts.dryRun);
|
|
230
231
|
}
|
|
231
232
|
|
|
232
233
|
// #228 — managed project hooks (.muse/hooks.json). Default on, mirroring
|
|
@@ -240,7 +241,7 @@ export async function postDeploy(targetDir, opts = {}) {
|
|
|
240
241
|
// #228 — optional MCP settings profile. Explicit opt-in only (--mcp);
|
|
241
242
|
// default `aiwg use --provider muse` never touches user settings.
|
|
242
243
|
if (fullDeploy && opts.mcp === true) {
|
|
243
|
-
deployMuseMcp(opts);
|
|
244
|
+
await deployMuseMcp(opts);
|
|
244
245
|
}
|
|
245
246
|
|
|
246
247
|
if (!opts.quiet) {
|
|
@@ -265,6 +266,10 @@ export async function postDeploy(targetDir, opts = {}) {
|
|
|
265
266
|
}
|
|
266
267
|
|
|
267
268
|
export async function deploy(opts = {}) {
|
|
269
|
+
return withRuleDeployment(opts, { name, paths, kernelSkillsPath }, deploySelected);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
async function deploySelected(opts) {
|
|
268
273
|
const {
|
|
269
274
|
srcRoot,
|
|
270
275
|
target,
|