@aiwg/cli 2026.10.3 → 2026.10.4
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/README.md +2 -2
- package/agentic/code/providers/model-capabilities.v1.json +96 -4
- package/bin/aiwg.mjs +50 -27
- package/dist/src/agents/grounding/knowledge-base.js +54 -6
- package/dist/src/artifacts/browser-export.js +6 -0
- package/dist/src/artifacts/checksum-manifest.js +1 -0
- package/dist/src/artifacts/citation-parser.js +173 -92
- package/dist/src/artifacts/citation-table-schema.js +59 -0
- package/dist/src/artifacts/cli.js +57 -18
- package/dist/src/artifacts/corpus-tools/snapshot.js +1 -1
- package/dist/src/artifacts/corpus-tools/vision-extract.js +2 -0
- package/dist/src/artifacts/corpus-views/ref-parser.js +3 -1
- package/dist/src/artifacts/corpus-views/renderers.js +3 -3
- package/dist/src/artifacts/discovery-eval.js +6 -4
- package/dist/src/artifacts/fortemi-core-query-adapter.js +36 -3
- package/dist/src/artifacts/fortemi-core-sync.js +166 -40
- package/dist/src/artifacts/framework-capabilities.js +171 -0
- package/dist/src/artifacts/framework-index-paths.js +73 -0
- package/dist/src/artifacts/framework-source-digest.js +75 -0
- package/dist/src/artifacts/index-builder.js +285 -131
- package/dist/src/artifacts/index-files.js +132 -18
- package/dist/src/artifacts/index-preparation.js +65 -0
- package/dist/src/artifacts/index-refresh.js +576 -0
- package/dist/src/artifacts/index-worker.mjs +9 -0
- package/dist/src/artifacts/prebuilt-build-lock.js +47 -4
- package/dist/src/artifacts/prebuilt-deployment.js +46 -0
- package/dist/src/artifacts/prebuilt-relations.js +80 -0
- package/dist/src/artifacts/query-engine.js +410 -88
- package/dist/src/artifacts/relations-builder.js +168 -0
- package/dist/src/artifacts/relations.js +148 -0
- package/dist/src/artifacts/stats.js +5 -2
- package/dist/src/artifacts/types.js +30 -10
- package/dist/src/artifacts/watcher.js +1 -1
- package/dist/src/auth/credential-store.js +2 -1
- package/dist/src/catalog/cli.d.mts +5 -0
- package/dist/src/channel/manager.d.mts +20 -0
- package/dist/src/channel/manager.mjs +19 -2
- package/dist/src/cli/command-log.js +2 -3
- package/dist/src/cli/handlers/artifacts.js +3 -0
- package/dist/src/cli/handlers/auth.js +3 -0
- package/dist/src/cli/handlers/decision.js +19 -12
- package/dist/src/cli/handlers/diagnose.js +4 -3
- package/dist/src/cli/handlers/effect.js +4 -2
- package/dist/src/cli/handlers/evidence.js +3 -0
- package/dist/src/cli/handlers/help.js +1 -0
- package/dist/src/cli/handlers/index.js +3 -1
- package/dist/src/cli/handlers/init.js +4 -1
- package/dist/src/cli/handlers/lint.js +5 -0
- package/dist/src/cli/handlers/models.js +104 -8
- package/dist/src/cli/handlers/ralph-launcher.js +2 -0
- package/dist/src/cli/handlers/refresh.js +12 -0
- package/dist/src/cli/handlers/resource-versions.js +3 -0
- package/dist/src/cli/handlers/rules.js +195 -0
- package/dist/src/cli/handlers/run.js +4 -0
- package/dist/src/cli/handlers/runtime-info.js +1 -2
- package/dist/src/cli/handlers/script-runner.js +3 -2
- package/dist/src/cli/handlers/session.js +19 -9
- package/dist/src/cli/handlers/sessions.js +98 -37
- package/dist/src/cli/handlers/setup-manifest.js +39 -44
- package/dist/src/cli/handlers/setup.js +41 -0
- package/dist/src/cli/handlers/steward.js +11 -0
- package/dist/src/cli/handlers/subcommands.js +57 -2
- package/dist/src/cli/handlers/uhp.js +3 -0
- package/dist/src/cli/handlers/use.js +294 -55
- package/dist/src/cli/handlers/utilities.js +26 -10
- package/dist/src/cli/handlers/version.js +8 -0
- package/dist/src/cli/router.js +15 -1
- package/dist/src/cli/services/deployment-verification.js +19 -9
- package/dist/src/cli/services/provider-prepare-coordinator.js +24 -0
- package/dist/src/cli/skill-usage.js +2 -3
- package/dist/src/config/aiwg-config.js +87 -37
- package/dist/src/config/cli.js +111 -5
- package/dist/src/config/decision-config.js +106 -0
- package/dist/src/config/dispatch-thresholds-runtime.d.mts +8 -0
- package/dist/src/config/gitignore.js +50 -0
- package/dist/src/config/index-graph-overrides.js +36 -0
- package/dist/src/config/project-artifacts-health.d.mts +37 -0
- package/dist/src/config/project-artifacts-runtime.d.mts +16 -0
- package/dist/src/config/user-config-dir.d.mts +9 -0
- package/dist/src/config/user-config.js +2 -1
- package/dist/src/config/user-registry.js +23 -15
- package/dist/src/config/user-state.js +7 -0
- package/dist/src/decision/ask.js +203 -43
- package/dist/src/decision/context-live-qualification.js +2 -2
- package/dist/src/decision/driver.js +13 -8
- package/dist/src/decision/ensemble/aggregate.js +23 -10
- package/dist/src/decision/ensemble-study/multifact-study.js +6 -2
- package/dist/src/decision/entry.js +2 -15
- package/dist/src/decision/graph-live-qualification.js +1 -1
- package/dist/src/decision/graph-run.js +9 -0
- package/dist/src/decision/heldout/collector.js +5 -13
- package/dist/src/decision/heldout/contract.js +30 -7
- package/dist/src/decision/jev-credentials.js +15 -1
- package/dist/src/decision/ledger.js +131 -28
- package/dist/src/decision/offload-activation.js +137 -0
- package/dist/src/decision/offload.js +550 -0
- package/dist/src/decision/qualification/load.js +4 -6
- package/dist/src/decision/savings.js +28 -0
- package/dist/src/effects/types.js +5 -1
- package/dist/src/effects/verifiers/git.js +2 -1
- package/dist/src/effects/verifiers/tracker.js +26 -14
- package/dist/src/extensions/commands/definitions.js +19 -0
- package/dist/src/extensions/project-local-remove.js +36 -1
- package/dist/src/gates/providers/loader.js +61 -17
- package/dist/src/installation/manager-command.d.mts +18 -0
- package/dist/src/installation/manager-command.mjs +14 -2
- package/dist/src/installation/manager.d.mts +49 -0
- package/dist/src/installation/manager.mjs +78 -3
- package/dist/src/issues/cli.js +4 -4
- package/dist/src/issues/local.js +24 -5
- package/dist/src/jobs/runner.js +1 -1
- package/dist/src/lint/cli.js +27 -1
- package/dist/src/lint/loader.js +2 -1
- package/dist/src/lint/reporters.js +25 -1
- package/dist/src/lint/rule-activation.js +43 -0
- package/dist/src/lint/runner.js +137 -62
- package/dist/src/mcp/adapters/codex-runtime.js +7 -1
- package/dist/src/mcp/claude-install.d.mts +4 -0
- package/dist/src/mcp/claude-install.mjs +41 -0
- package/dist/src/mcp/cli.d.mts +1 -0
- package/dist/src/mcp/cli.mjs +36 -11
- package/dist/src/mcp/config-file.d.mts +28 -0
- package/dist/src/mcp/config-layers.d.mts +36 -0
- package/dist/src/mcp/credentials.d.mts +51 -0
- package/dist/src/mcp/grok-build-config.d.mts +6 -0
- package/dist/src/mcp/grok-build-config.mjs +1 -1
- package/dist/src/mcp/helpers.mjs +3 -2
- package/dist/src/mcp/muse-native-config.d.mts +13 -0
- package/dist/src/mcp/muse-native-config.mjs +1 -0
- package/dist/src/mcp/omp-config.d.mts +4 -0
- package/dist/src/mcp/registry.js +3 -93
- package/dist/src/mcp/registry.mjs +3 -87
- package/dist/src/mcp/server-config.d.mts +3 -0
- package/dist/src/mcp/server-config.mjs +89 -0
- package/dist/src/mcp/server.mjs +37 -375
- package/dist/src/mcp/test-simple.mjs +2 -1
- package/dist/src/mcp/toml-editor.d.mts +4 -0
- package/dist/src/mcp/toml-string.d.mts +1 -0
- package/dist/src/mcp/toml-strip-mcp.d.mts +1 -0
- package/dist/src/mcp/tool-filters.d.mts +46 -0
- package/dist/src/mcp/tools/decision.mjs +12 -11
- package/dist/src/mcp/tools/discovery.mjs +62 -55
- package/dist/src/mcp/tools/orchestration.mjs +12 -2
- package/dist/src/mcp/tools/worker-invoke.mjs +1340 -23
- package/dist/src/mcp/tools/worker-shell-control.mjs +52 -21
- package/dist/src/mcp/tools/worker-stdin-runtime.mjs +3 -3
- package/dist/src/mission-protocol/codecs.js +8 -0
- package/dist/src/models/config-loader.js +7 -2
- package/dist/src/models/model-capabilities.v1.json +96 -4
- package/dist/src/models/model-discovery.js +76 -11
- package/dist/src/models/provider-policy.js +101 -7
- package/dist/src/models/qualification-digest.d.mts +2 -0
- package/dist/src/models/resolver.js +12 -10
- package/dist/src/models/worker-direct-readiness.js +65 -44
- package/dist/src/models/worker-dispatch-offer.js +3 -3
- package/dist/src/models/worker-health-readiness.js +16 -3
- package/dist/src/models/worker-installation.d.mts +39 -0
- package/dist/src/models/worker-installation.mjs +135 -28
- package/dist/src/process/bounded-child-process.d.mts +84 -0
- package/dist/src/process/bounded-child-process.mjs +43 -0
- package/dist/src/process/cli-command.d.mts +16 -0
- package/dist/src/process/signal-child.d.mts +6 -0
- package/dist/src/process/signal-child.mjs +7 -0
- package/dist/src/providers/deployed-skill-roots.js +20 -0
- package/dist/src/providers/grok-build-acp.js +3 -2
- package/dist/src/providers/grok-build-headless.js +12 -4
- package/dist/src/providers/grok-build-inspect.js +1 -0
- package/dist/src/providers/omp-agent.d.mts +8 -0
- package/dist/src/providers/omp-diagnostics.d.mts +1 -0
- package/dist/src/providers/omp-paths.d.mts +13 -0
- package/dist/src/providers/skill-ownership.d.mts +9 -0
- package/dist/src/providers/skill-ownership.mjs +88 -0
- package/dist/src/rules/activation.d.mts +21 -0
- package/dist/src/rules/activation.mjs +62 -0
- package/dist/src/rules/inline-budget.d.mts +26 -0
- package/dist/src/rules/inline-budget.mjs +66 -0
- package/dist/src/rules/inventory.js +129 -0
- package/dist/src/rules/pin-state.js +73 -0
- package/dist/src/rules/pins.d.mts +14 -0
- package/dist/src/rules/pins.mjs +112 -0
- package/dist/src/rules/rule-frontmatter.schema.json +197 -0
- package/dist/src/serve/mission-conductor.js +38 -12
- package/dist/src/serve/worker-invocation.js +30 -10
- package/dist/src/serve/worker-stdin-frame.d.mts +10 -0
- package/dist/src/sessions/adapter-registry.js +23 -19
- package/dist/src/sessions/adapters/claude.js +39 -54
- package/dist/src/sessions/adapters/codex.js +82 -67
- package/dist/src/sessions/adapters/copilot.js +4 -4
- package/dist/src/sessions/adapters/cursor.js +40 -57
- package/dist/src/sessions/adapters/deepseek-harness.js +15 -12
- package/dist/src/sessions/adapters/factory.js +31 -27
- package/dist/src/sessions/adapters/generic.js +10 -10
- package/dist/src/sessions/adapters/grok-build.js +11 -11
- package/dist/src/sessions/adapters/grokbot.js +24 -13
- package/dist/src/sessions/adapters/hermes.js +27 -29
- package/dist/src/sessions/adapters/muse-workspace-scan.js +31 -11
- package/dist/src/sessions/adapters/muse.js +150 -93
- package/dist/src/sessions/adapters/omp.js +28 -14
- package/dist/src/sessions/adapters/openclaw.js +89 -79
- package/dist/src/sessions/adapters/opencode.js +27 -24
- package/dist/src/sessions/adapters/openhuman.js +18 -60
- package/dist/src/sessions/adapters/pi.js +29 -14
- package/dist/src/sessions/adapters/warp.js +3 -3
- package/dist/src/sessions/adapters/windsurf.js +19 -48
- package/dist/src/sessions/batch-contracts.js +16 -8
- package/dist/src/sessions/batch-import.js +51 -11
- package/dist/src/sessions/contracts.js +40 -2
- package/dist/src/sessions/coverage-preflight.js +1 -1
- package/dist/src/sessions/export-plan.js +4 -3
- package/dist/src/sessions/import-exclusions.js +72 -0
- package/dist/src/sessions/import-lease.js +34 -18
- package/dist/src/sessions/import-limits.js +37 -0
- package/dist/src/sessions/importer.js +60 -38
- package/dist/src/sessions/lifecycle.js +45 -0
- package/dist/src/sessions/policy.js +133 -25
- package/dist/src/sessions/readers.js +106 -53
- package/dist/src/sessions/refresh.js +106 -0
- package/dist/src/sessions/repository.js +147 -52
- package/dist/src/sessions/workspace-discovery.js +221 -56
- package/dist/src/sessions/workspace-matching.js +107 -0
- package/dist/src/skills/importer.js +1 -0
- package/dist/src/smiths/context-pipeline/aiwg-md.js +11 -0
- package/dist/src/smiths/context-pipeline/claude-hook.js +3 -26
- package/dist/src/smiths/context-pipeline/finalization.js +6 -5
- package/dist/src/smiths/context-pipeline/generator.js +21 -4
- package/dist/src/smiths/context-pipeline/parallelism-section.js +7 -15
- package/dist/src/smiths/mcpsmith/generator.js +1 -1
- package/dist/src/smiths/toolsmith/runtime-discovery.d.mts +10 -0
- package/dist/src/smiths/toolsmith/runtime-discovery.mjs +76 -18
- package/dist/src/storage/backends/fs.js +18 -76
- package/dist/src/storage/backends/obsidian.js +1 -0
- package/dist/src/tracker/forge-http.js +2 -1
- package/dist/src/update/checker.d.mts +2 -0
- package/dist/src/update/service.d.mts +22 -0
- package/dist/src/utils/contained-filesystem.d.mts +37 -0
- package/dist/src/utils/contained-filesystem.mjs +683 -0
- package/dist/src/utils/temporary-directory.js +36 -0
- package/dist/src/writing/example-generator.js +1 -1
- package/package.json +15 -2
- package/schemas/models/model-catalog.v1.schema.json +1 -1
- package/schemas/models/provider-model-capabilities.v1.schema.json +6 -0
- package/tools/_resolve-impl.mjs +13 -15
- package/tools/agents/deploy-agents.mjs +49 -21
- package/tools/agents/providers/base.mjs +104 -134
- package/tools/agents/providers/claude.mjs +8 -24
- package/tools/agents/providers/codex.mjs +18 -11
- package/tools/agents/providers/cursor.mjs +19 -18
- package/tools/agents/providers/grok-build.mjs +3 -1
- package/tools/agents/providers/hermes.mjs +57 -47
- package/tools/agents/providers/openclaw.mjs +9 -4
- package/tools/agents/providers/pi.mjs +5 -0
- package/tools/agents/providers/provider-prepare-channel.mjs +5 -0
- package/tools/agents/providers/provider-prepare-coordinator.mjs +247 -0
- package/tools/agents/providers/provider-prepare-worker.mjs +84 -0
- package/tools/agents/providers/rule-delivery.mjs +1270 -0
- package/tools/agents/providers/warp.mjs +20 -26
- package/tools/cli/decision-offload-report.mjs +40 -0
- package/tools/cli/workspace-status.mjs +862 -0
- package/tools/plugin/package-plugins.mjs +186 -8
- package/tools/plugin/plugin-links.mjs +114 -0
- package/tools/providers/antigravity-transport.mjs +3 -1
- package/tools/providers/deepseek-harness-transport.mjs +6 -4
- package/tools/providers/omp-transport.mjs +4 -2
- package/tools/ralph-external/lib/consecutive-failure-circuit-breaker.mjs +1748 -0
- package/tools/ralph-external/lib/launcher-recovery-evidence.mjs +55 -0
- package/tools/ralph-external/lib/omp-adapter.mjs +1 -1
- package/tools/ralph-external/lib/pi-adapter.mjs +0 -4
- package/tools/ralph-external/lib/provider-adapter.mjs +59 -1
- package/tools/ralph-external/lib/recovery-probe.mjs +72 -0
- package/tools/ralph-external/lib/session-environment.mjs +28 -0
- package/tools/ralph-external/lib/systemd-client.mjs +49 -0
- package/tools/ralph-external/lib/worker-health.mjs +1 -1
- package/tools/ralph-external/lib/worker-isolation.mjs +717 -0
- package/tools/ralph-external/lib/worker-overflow.mjs +50 -0
- package/tools/ralph-external/process-monitor.mjs +1017 -0
- package/tools/ralph-external/session-launcher.mjs +5057 -0
- package/tools/scripts/resource-preflight.mjs +541 -0
- package/tools/skills/deploy-skills-codex.mjs +2 -1
- package/vscode-extension/schemas/aiwg.config.v1.json +1194 -231
|
@@ -202,8 +202,7 @@ async function handleRuntimeInfo(args, cwd = process.cwd()) {
|
|
|
202
202
|
const { RuntimeDiscovery } = await import('../../smiths/toolsmith/runtime-discovery.mjs');
|
|
203
203
|
const discovery = new RuntimeDiscovery();
|
|
204
204
|
if (hasDiscover) {
|
|
205
|
-
|
|
206
|
-
const catalog = await discovery.discover();
|
|
205
|
+
const catalog = await discovery.discover({ force: args.includes('--force') });
|
|
207
206
|
if (hasJson) {
|
|
208
207
|
console.log(JSON.stringify(catalog, null, 2));
|
|
209
208
|
}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* @source @src/cli/router.ts
|
|
9
9
|
* @issue #33
|
|
10
10
|
*/
|
|
11
|
+
import { signalChild } from '../../process/signal-child.mjs';
|
|
11
12
|
import { spawn } from 'child_process';
|
|
12
13
|
import path from 'path';
|
|
13
14
|
/**
|
|
@@ -73,12 +74,12 @@ export class DefaultScriptRunner {
|
|
|
73
74
|
// does not exit within the deadline. Both kill() calls are wrapped
|
|
74
75
|
// because they can throw ESRCH on an already-exited child.
|
|
75
76
|
try {
|
|
76
|
-
child
|
|
77
|
+
signalChild(child, 'SIGTERM');
|
|
77
78
|
}
|
|
78
79
|
catch { /* already exited */ }
|
|
79
80
|
killEscalationId = setTimeout(() => {
|
|
80
81
|
try {
|
|
81
|
-
child
|
|
82
|
+
signalChild(child, 'SIGKILL');
|
|
82
83
|
}
|
|
83
84
|
catch { /* already exited */ }
|
|
84
85
|
}, killDeadlineMs);
|
|
@@ -32,10 +32,9 @@
|
|
|
32
32
|
*/
|
|
33
33
|
import { spawnSync } from 'child_process';
|
|
34
34
|
import { readFile } from 'node:fs/promises';
|
|
35
|
-
import { mkdtempSync, rmSync, writeFileSync } from 'node:fs';
|
|
36
|
-
import { tmpdir } from 'node:os';
|
|
35
|
+
import { mkdtempSync, rmSync, writeFileSync, realpathSync, statSync } from 'node:fs';
|
|
37
36
|
import { join } from 'node:path';
|
|
38
|
-
import { boundedSpawnSync } from '../../process/bounded-child-process.mjs';
|
|
37
|
+
import { boundedSpawn, boundedSpawnSync } from '../../process/bounded-child-process.mjs';
|
|
39
38
|
import { existsSync } from 'node:fs';
|
|
40
39
|
import { ensureRuntimeHome, writeProfileConfig, launchWithProfile } from '../../mcp/adapters/codex-runtime.js';
|
|
41
40
|
import { getFrameworkRoot } from '../../channel/manager.mjs';
|
|
@@ -314,8 +313,8 @@ function buildHeadlessLaunch(provider, binaryArgs, prompt) {
|
|
|
314
313
|
}
|
|
315
314
|
// File transport (opencode): the prompt never touches argv or stdin — it
|
|
316
315
|
// is written to a private temp file only this process can read, passed
|
|
317
|
-
// by path. `mkdtemp()` under the system temp
|
|
318
|
-
//
|
|
316
|
+
// by path. `mkdtemp()` under the independently verified system temp
|
|
317
|
+
// directory gives the
|
|
319
318
|
// directory itself a private, unpredictable name owned by this process;
|
|
320
319
|
// the file within it additionally gets an explicit `0600` mode via an
|
|
321
320
|
// exclusive create (`flag: 'wx'` — fails rather than silently
|
|
@@ -328,7 +327,15 @@ function buildHeadlessLaunch(provider, binaryArgs, prompt) {
|
|
|
328
327
|
// `launchProvider()`, keyed off `plan.tempDir`) handles the ordinary
|
|
329
328
|
// "launch ran, now clean up" path; this one exists only for the write
|
|
330
329
|
// itself failing before a `plan` is ever returned to that caller.
|
|
331
|
-
|
|
330
|
+
// os.tmpdir() trusts TMPDIR/TEMP/TMP, which can point into the project.
|
|
331
|
+
// Select and validate the OS location independently of those overrides.
|
|
332
|
+
const systemTemp = realpathSync(process.platform === 'win32' ? join(process.env.SystemRoot ?? 'C:/Windows', 'Temp') : '/tmp');
|
|
333
|
+
const info = statSync(systemTemp);
|
|
334
|
+
if (!info.isDirectory() || (process.platform !== 'win32'
|
|
335
|
+
&& (info.uid !== 0 && info.uid !== process.getuid?.() || (info.mode & 0o022) !== 0 && (info.mode & 0o1000) === 0))) {
|
|
336
|
+
throw new Error('Unsafe system temporary directory for session prompt');
|
|
337
|
+
}
|
|
338
|
+
const tempDir = mkdtempSync(join(systemTemp, 'aiwg-session-prompt-'));
|
|
332
339
|
try {
|
|
333
340
|
const promptPath = join(tempDir, 'prompt.txt');
|
|
334
341
|
writeFileSync(promptPath, prompt, { encoding: 'utf-8', mode: 0o600, flag: 'wx' });
|
|
@@ -355,7 +362,7 @@ function buildHeadlessLaunch(provider, binaryArgs, prompt) {
|
|
|
355
362
|
* and without a terminal, this refuses before spawning anything that would
|
|
356
363
|
* hang.
|
|
357
364
|
*/
|
|
358
|
-
function launchProvider(provider, mcpInjected, mcpConfigPath, profile, settingsPath, prompt, interactive) {
|
|
365
|
+
async function launchProvider(provider, mcpInjected, mcpConfigPath, profile, settingsPath, prompt, interactive) {
|
|
359
366
|
const cfg = getProviderConfig(provider);
|
|
360
367
|
if (!isSpawnableProvider(provider)) {
|
|
361
368
|
// Not spawnable — a prompt can never be delivered to a binary that does
|
|
@@ -424,11 +431,14 @@ ${cfg.guidanceMessage ?? `Open ${cfg.name} in your project directory to begin.`}
|
|
|
424
431
|
// 8); stdin-transport providers get it via `input` (never inherited
|
|
425
432
|
// from the parent), file-transport providers get it via a private
|
|
426
433
|
// temp file path already baked into `plan.args`.
|
|
427
|
-
const
|
|
434
|
+
const launchOptions = {
|
|
428
435
|
stdio: plan.input !== undefined ? ['pipe', 'inherit', 'inherit'] : ['ignore', 'inherit', 'inherit'],
|
|
429
436
|
env: process.env,
|
|
430
437
|
...(plan.input !== undefined ? { input: plan.input } : {}),
|
|
431
|
-
}
|
|
438
|
+
};
|
|
439
|
+
const result = plan.tempDir
|
|
440
|
+
? await boundedSpawn(cfg.binary, plan.args, 'long', { ...launchOptions, stdio: ['ignore', 'inherit', 'inherit'] }, () => rmSync(plan.tempDir, { recursive: true, force: true }))
|
|
441
|
+
: boundedSpawnSync(cfg.binary, plan.args, 'long', launchOptions);
|
|
432
442
|
const { exitCode, message } = exitCodeForSpawnResult(result, cfg.binary);
|
|
433
443
|
return message ? { exitCode, message } : { exitCode };
|
|
434
444
|
}
|
|
@@ -3,7 +3,10 @@ import { randomUUID } from 'node:crypto';
|
|
|
3
3
|
import { basename, dirname, isAbsolute, join, resolve, } from 'node:path';
|
|
4
4
|
import { pathToFileURL } from 'node:url';
|
|
5
5
|
import { CLAUDE_ADAPTER_VERSION, ClaudeSessionAdapter, CODEX_ADAPTER_VERSION, CodexSessionAdapter, COPILOT_ADAPTER_VERSION, CopilotSessionAdapter, CURSOR_ADAPTER_VERSION, CursorSessionAdapter, FACTORY_ADAPTER_VERSION, FactorySessionAdapter, HERMES_ADAPTER_VERSION, HermesSessionAdapter, OPENCODE_ADAPTER_VERSION, OpenCodeSessionAdapter, OPENCLAW_ADAPTER_VERSION, OpenClawSessionAdapter, OPENHUMAN_ADAPTER_VERSION, OpenHumanSessionAdapter, GROKBOT_ADAPTER_VERSION, GROKBOT_NATIVE_REPLICA_LOCATOR_CLASS, GrokbotSessionAdapter, GROK_BUILD_ADAPTER_VERSION, GROK_BUILD_CLI_EXPORT_LOCATOR_CLASS, GrokBuildSessionAdapter, grokBuildList, grokBuildSearch, grokBuildExport, grokHeadlessSessionIdFromFile, MUSE_ADAPTER_VERSION, MuseSessionAdapter, PI_ADAPTER_VERSION, PiSessionAdapter, DEEPSEEK_HARNESS_ADAPTER_VERSION, DeepSeekHarnessSessionAdapter, OmpSessionAdapter, OMP_ADAPTER_VERSION, WARP_ADAPTER_VERSION, WarpSessionAdapter, DEVIN_DESKTOP_ADAPTER_VERSION, DevinDesktopSessionAdapter, CandidateExtractionService, GENERIC_ADAPTER_VERSION, GenericSessionInterchangeAdapter, IncrementalSessionImporter, ImportLeaseContentionError, FilesystemMemoryDestination, FilesystemPromotionDispositionCoordinator, MemoryPromotionGateway, SESSION_CONTRACT_VERSION, SessionContractError, SessionRepository, SessionSourceSchema, StructuralCandidateExtractor, resolveMemoryConsumerManifest, assertSessionProviderId, acquireImportLease, defaultDiscoveryManifestPath, discoverWorkspaceHistories, createSessionAdapterRegistry, coveragePreflight, expectedSessionProviders, deriveSessionTimeline, importDiscoveryManifest, previewDiscoveryImport, publicDiscoveryManifest, readDiscoveryManifest, redactSourceLocator, sha256, parseTimelineGap, writeDiscoveryManifest, buildSessionExportPlan, reverifySessionExportPlan, buildSessionAiwgFortemiIndexExport, recoverAiwgFortemiIndexFromFullV1Shard, embedAttachmentsInFullV1Shard, recoverEmbeddedAttachments, SESSION_EXPORT_PLAN_SCHEMA_VERSION, } from '../../sessions/index.js';
|
|
6
|
+
import { resolveImportExclusions } from '../../sessions/import-exclusions.js';
|
|
7
|
+
import { resolveImportLimits } from '../../sessions/import-limits.js';
|
|
6
8
|
import { classifyGrokbotBlobName } from '../../sessions/adapters/grokbot-locator.js';
|
|
9
|
+
import { readAiwgConfig } from '../../config/aiwg-config.js';
|
|
7
10
|
const JSON_CONTRACT_VERSION = '1.0.0';
|
|
8
11
|
async function createLineMemoryPromotionDestination(projectRoot, manifestPath) {
|
|
9
12
|
const modulePath = resolve(dirname(manifestPath), 'commands', 'line-memory.mjs');
|
|
@@ -48,7 +51,7 @@ Commands:
|
|
|
48
51
|
promote <id> <version> Preview promotion; use --confirm to write
|
|
49
52
|
tag <session-id> <tag> Add a catalog tag
|
|
50
53
|
relocate <source-id> <file> Update AIWG source-location metadata
|
|
51
|
-
reindex
|
|
54
|
+
reindex --workspace <path-or-id> | --all-workspaces Rebuild catalog indexes
|
|
52
55
|
delete <session-id> Preview deletion; use --confirm to tombstone
|
|
53
56
|
restore <session-id> Restore a reversible catalog tombstone
|
|
54
57
|
purge <session-id> Preview terminal AIWG-copy purge
|
|
@@ -60,6 +63,7 @@ Commands:
|
|
|
60
63
|
Options:
|
|
61
64
|
--json Emit the versioned JSON contract
|
|
62
65
|
--dry-run Preview a mutation without changing state
|
|
66
|
+
--all-workspaces Reindex every workspace in the selected catalog (reindex only)
|
|
63
67
|
--db <path> Select a catalog; relative paths resolve from cwd
|
|
64
68
|
--workspace <path-or-id> Select the workspace within that catalog for reads
|
|
65
69
|
(default: current project, matching cwd, or sole catalog workspace)
|
|
@@ -69,7 +73,7 @@ Options:
|
|
|
69
73
|
--expected-providers <ids> Comma-separated authorized scope, independent of runtime inventory
|
|
70
74
|
--manifest <path> Override the discovery manifest path
|
|
71
75
|
--provider-home <path> Override the provider home root (testing/portable homes)
|
|
72
|
-
--codex-root <path>
|
|
76
|
+
--codex-root <path> Authorize a shared Codex sessions/export root (repeatable)
|
|
73
77
|
--omp-root <path> Explicitly authorize an OMP profile sessions root
|
|
74
78
|
--muse-root <path> Explicitly authorize a Muse Code sessions root
|
|
75
79
|
--dsh-root <path> Explicitly authorize a DeepSeek Harness sessions root
|
|
@@ -78,6 +82,10 @@ Options:
|
|
|
78
82
|
(default: grok on PATH, then $GROK_HOME/bin/grok)
|
|
79
83
|
--confirm, --yes Confirm a persistent discovered batch import
|
|
80
84
|
--lock-wait-ms <n> Maximum import-lease wait (default 5000)
|
|
85
|
+
--exclude <id-or-glob> Skip a session ID or absolute path glob (repeatable); adds to sessions.import.exclude and AIWG_SESSIONS_IMPORT_EXCLUDE
|
|
86
|
+
--max-record-bytes <n> Import record limit (default 67108864); overrides AIWG_SESSIONS_IMPORT_MAX_RECORD_BYTES and sessions.import.max_record_bytes
|
|
87
|
+
--max-source-bytes <n> Import source limit (default 1073741824, 1 GiB; 0 unlimited); overrides AIWG_SESSIONS_IMPORT_MAX_SOURCE_BYTES and sessions.import.max_source_bytes
|
|
88
|
+
Import limit precedence: CLI flag > env var > workspace config > default.
|
|
81
89
|
--inactivity-threshold <duration> Historical inactivity threshold (default 24h)
|
|
82
90
|
--min-coverage <0..1> Fail list/report commands below a coverage ratio
|
|
83
91
|
--provider <id> Filter list or select an import adapter
|
|
@@ -110,9 +118,9 @@ Analytics / forensics:
|
|
|
110
118
|
--group-by tool|session|provider, --limit <1..5000>
|
|
111
119
|
--authorize-forensics Required for each authorized forensic invocation
|
|
112
120
|
--markdown Render a sanitized forensic timeline table`;
|
|
113
|
-
function printHelp(ctx, exitCode = EXIT.ok) {
|
|
121
|
+
async function printHelp(ctx, exitCode = EXIT.ok) {
|
|
114
122
|
if (ctx.args.includes('--json'))
|
|
115
|
-
emit(envelope('sessions.help', 'ok', { usage: HELP }, null));
|
|
123
|
+
await emit(envelope('sessions.help', 'ok', { usage: HELP }, null));
|
|
116
124
|
else
|
|
117
125
|
console.log(HELP);
|
|
118
126
|
return { exitCode };
|
|
@@ -136,7 +144,7 @@ export const sessionsHandler = {
|
|
|
136
144
|
const normalized = normalizeError(error);
|
|
137
145
|
const output = envelope('sessions', 'error', null, normalized.error);
|
|
138
146
|
if (json)
|
|
139
|
-
emit(output);
|
|
147
|
+
await emit(output);
|
|
140
148
|
else
|
|
141
149
|
console.error(`${normalized.error.code}: ${normalized.error.message}`);
|
|
142
150
|
return { exitCode: normalized.exitCode, message: normalized.error.message };
|
|
@@ -148,7 +156,7 @@ export const sessionsHandler = {
|
|
|
148
156
|
try {
|
|
149
157
|
const result = await executeCommand(ctx, parsed);
|
|
150
158
|
if (json)
|
|
151
|
-
emit(result.envelope);
|
|
159
|
+
await emit(result.envelope);
|
|
152
160
|
else
|
|
153
161
|
printHuman(result.envelope);
|
|
154
162
|
return { exitCode: result.exitCode };
|
|
@@ -157,7 +165,7 @@ export const sessionsHandler = {
|
|
|
157
165
|
const normalized = normalizeError(error);
|
|
158
166
|
const output = envelope(`sessions.${parsed.command}`, 'error', null, normalized.error);
|
|
159
167
|
if (json)
|
|
160
|
-
emit(output);
|
|
168
|
+
await emit(output);
|
|
161
169
|
else
|
|
162
170
|
console.error(`${normalized.error.code}: ${normalized.error.message}`);
|
|
163
171
|
return { exitCode: normalized.exitCode, message: normalized.error.message };
|
|
@@ -590,11 +598,22 @@ async function executeCommand(ctx, args) {
|
|
|
590
598
|
return ok(command, { sourceId, redactedLocator });
|
|
591
599
|
}
|
|
592
600
|
case 'reindex': {
|
|
593
|
-
const
|
|
601
|
+
const allWorkspaces = args.flags.has('--all-workspaces');
|
|
602
|
+
if (allWorkspaces && args.values.has('--workspace')) {
|
|
603
|
+
throw new CliError('INVALID_ARGUMENT', '--all-workspaces cannot be combined with --workspace', EXIT.usage);
|
|
604
|
+
}
|
|
605
|
+
const workspaceId = allWorkspaces
|
|
606
|
+
? undefined
|
|
607
|
+
: authorizationContext(ctx, args, command).workspaceId;
|
|
608
|
+
const data = {
|
|
609
|
+
operation: 'reindex',
|
|
610
|
+
allWorkspaces,
|
|
611
|
+
workspaceIds: allWorkspaces ? repository.listWorkspaceIds() : [workspaceId],
|
|
612
|
+
};
|
|
594
613
|
if (isDryRun(ctx, args))
|
|
595
|
-
return preview(command,
|
|
614
|
+
return preview(command, data);
|
|
596
615
|
repository.reindex(workspaceId);
|
|
597
|
-
return ok(command,
|
|
616
|
+
return ok(command, data);
|
|
598
617
|
}
|
|
599
618
|
case 'audit': {
|
|
600
619
|
const { workspaceId } = readAuthorizationContext(ctx, args, command, repository);
|
|
@@ -721,6 +740,7 @@ async function executeCommand(ctx, args) {
|
|
|
721
740
|
}
|
|
722
741
|
}
|
|
723
742
|
async function importSource(ctx, args) {
|
|
743
|
+
const limits = await configuredImportLimits(ctx, args);
|
|
724
744
|
const input = resolve(ctx.cwd, requiredPositional(args, 0, 'file'));
|
|
725
745
|
const providerInput = args.values.get('--provider') ?? 'generic';
|
|
726
746
|
const provider = assertSessionProviderId(providerInput);
|
|
@@ -753,37 +773,37 @@ async function importSource(ctx, args) {
|
|
|
753
773
|
const isDsh = provider === 'deepseek-harness';
|
|
754
774
|
const isWarp = provider === 'warp';
|
|
755
775
|
const isDevinDesktop = provider === 'devin-desktop';
|
|
756
|
-
const adapter = isDsh ? new DeepSeekHarnessSessionAdapter() : isOmp ? new OmpSessionAdapter() : isClaude
|
|
757
|
-
? new ClaudeSessionAdapter()
|
|
776
|
+
const adapter = isDsh ? new DeepSeekHarnessSessionAdapter(limits) : isOmp ? new OmpSessionAdapter(limits) : isClaude
|
|
777
|
+
? new ClaudeSessionAdapter(limits)
|
|
758
778
|
: isCodex
|
|
759
|
-
? new CodexSessionAdapter()
|
|
779
|
+
? new CodexSessionAdapter(limits)
|
|
760
780
|
: isCopilot
|
|
761
|
-
? new CopilotSessionAdapter()
|
|
781
|
+
? new CopilotSessionAdapter(limits)
|
|
762
782
|
: isCursor
|
|
763
|
-
? new CursorSessionAdapter()
|
|
783
|
+
? new CursorSessionAdapter(limits)
|
|
764
784
|
: isFactory
|
|
765
|
-
? new FactorySessionAdapter()
|
|
785
|
+
? new FactorySessionAdapter(limits)
|
|
766
786
|
: isHermes
|
|
767
|
-
? new HermesSessionAdapter()
|
|
787
|
+
? new HermesSessionAdapter(limits)
|
|
768
788
|
: isOpenCode
|
|
769
|
-
? new OpenCodeSessionAdapter()
|
|
789
|
+
? new OpenCodeSessionAdapter(limits)
|
|
770
790
|
: isOpenClaw
|
|
771
|
-
? new OpenClawSessionAdapter()
|
|
791
|
+
? new OpenClawSessionAdapter(limits)
|
|
772
792
|
: isOpenHuman
|
|
773
|
-
? new OpenHumanSessionAdapter()
|
|
793
|
+
? new OpenHumanSessionAdapter(limits)
|
|
774
794
|
: isGrokbot
|
|
775
|
-
? new GrokbotSessionAdapter()
|
|
795
|
+
? new GrokbotSessionAdapter(limits)
|
|
776
796
|
: isGrokBuild
|
|
777
|
-
? new GrokBuildSessionAdapter()
|
|
797
|
+
? new GrokBuildSessionAdapter(limits)
|
|
778
798
|
: isMuse
|
|
779
|
-
? new MuseSessionAdapter()
|
|
799
|
+
? new MuseSessionAdapter(limits)
|
|
780
800
|
: isPi
|
|
781
|
-
? new PiSessionAdapter()
|
|
801
|
+
? new PiSessionAdapter(limits)
|
|
782
802
|
: isWarp
|
|
783
|
-
? new WarpSessionAdapter()
|
|
803
|
+
? new WarpSessionAdapter(limits)
|
|
784
804
|
: isDevinDesktop
|
|
785
|
-
? new DevinDesktopSessionAdapter()
|
|
786
|
-
: new GenericSessionInterchangeAdapter();
|
|
805
|
+
? new DevinDesktopSessionAdapter(limits)
|
|
806
|
+
: new GenericSessionInterchangeAdapter(limits);
|
|
787
807
|
const locatorClass = isDsh ? 'deepseek-harness-session-v2-jsonl' : isOmp ? 'omp-session-v3-jsonl' : isClaude
|
|
788
808
|
? claudeLocatorClass(input)
|
|
789
809
|
: isCodex
|
|
@@ -932,8 +952,9 @@ async function importSource(ctx, args) {
|
|
|
932
952
|
try {
|
|
933
953
|
const repository = openRepository(ctx, args);
|
|
934
954
|
try {
|
|
955
|
+
const interruptedRuns = repository.interruptRunningBatchImports();
|
|
935
956
|
const receipts = await new IncrementalSessionImporter(repository).import({
|
|
936
|
-
source, selectedSource, adapter, workspaceId, policyVersion: '1.0.0',
|
|
957
|
+
source, selectedSource, adapter, workspaceId, policyVersion: '1.0.0', limits,
|
|
937
958
|
inactivityThresholdMs: inactivityThreshold(args.values.get('--inactivity-threshold')),
|
|
938
959
|
});
|
|
939
960
|
for (const warning of workspaceReport.warnings)
|
|
@@ -942,6 +963,7 @@ async function importSource(ctx, args) {
|
|
|
942
963
|
sourceId,
|
|
943
964
|
...workspaceReport,
|
|
944
965
|
receipts,
|
|
966
|
+
interruptedRuns,
|
|
945
967
|
totals: {
|
|
946
968
|
sessionsInserted: receipts.reduce((sum, item) => sum + item.sessionsInserted, 0),
|
|
947
969
|
eventsInserted: receipts.reduce((sum, item) => sum + item.eventsInserted, 0),
|
|
@@ -1234,8 +1256,15 @@ async function exportUnpack(ctx, args, command) {
|
|
|
1234
1256
|
}
|
|
1235
1257
|
async function discoverWorkspace(ctx, args) {
|
|
1236
1258
|
const workspace = resolve(ctx.cwd, requiredValue(args, '--workspace'));
|
|
1259
|
+
const config = await readAiwgConfig(workspace);
|
|
1260
|
+
const canonicalWorkspace = realpathSync(workspace);
|
|
1261
|
+
const manifestPath = resolve(ctx.cwd, args.values.get('--manifest') ?? defaultDiscoveryManifestPath(canonicalWorkspace));
|
|
1262
|
+
const exclude = resolveImportExclusions(config?.sessions?.import, args.exclude);
|
|
1263
|
+
const previous = exclude.length > 0 && existsSync(manifestPath) ? await readDiscoveryManifest(manifestPath) : undefined;
|
|
1237
1264
|
const manifest = await discoverWorkspaceHistories({
|
|
1238
1265
|
workspace,
|
|
1266
|
+
knownSources: previous?.workspaceId === canonicalWorkspace ? previous.sources : undefined,
|
|
1267
|
+
exclude,
|
|
1239
1268
|
expectedProviders: requestedProviders(args),
|
|
1240
1269
|
providerHome: args.values.has('--provider-home')
|
|
1241
1270
|
? resolve(ctx.cwd, args.values.get('--provider-home'))
|
|
@@ -1248,11 +1277,11 @@ async function discoverWorkspace(ctx, args) {
|
|
|
1248
1277
|
? resolve(ctx.cwd, args.values.get('--dsh-root')) : undefined,
|
|
1249
1278
|
grokbotRoot: args.values.has('--grokbot-root')
|
|
1250
1279
|
? resolve(ctx.cwd, args.values.get('--grokbot-root')) : undefined,
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1280
|
+
codexRoots: [
|
|
1281
|
+
...(config?.sessions?.codex_roots ?? []).map((root) => resolve(workspace, root)),
|
|
1282
|
+
...args.codexRoots.map((root) => resolve(ctx.cwd, root)),
|
|
1283
|
+
],
|
|
1254
1284
|
});
|
|
1255
|
-
const manifestPath = resolve(ctx.cwd, args.values.get('--manifest') ?? defaultDiscoveryManifestPath(manifest.workspacePath));
|
|
1256
1285
|
const data = {
|
|
1257
1286
|
manifest: publicDiscoveryManifest(manifest),
|
|
1258
1287
|
manifestPath: redactSourceLocator(manifestPath),
|
|
@@ -1267,6 +1296,9 @@ async function discoverWorkspace(ctx, args) {
|
|
|
1267
1296
|
async function importDiscovered(ctx, args) {
|
|
1268
1297
|
const workspace = resolve(ctx.cwd, requiredValue(args, '--workspace'));
|
|
1269
1298
|
const canonicalWorkspace = realpathSync(workspace);
|
|
1299
|
+
const limits = await configuredImportLimits(ctx, args, canonicalWorkspace);
|
|
1300
|
+
const config = await readAiwgConfig(canonicalWorkspace);
|
|
1301
|
+
const exclude = resolveImportExclusions(config?.sessions?.import, args.exclude);
|
|
1270
1302
|
const manifestPath = resolve(ctx.cwd, args.values.get('--manifest') ?? defaultDiscoveryManifestPath(canonicalWorkspace));
|
|
1271
1303
|
const manifest = await readDiscoveryManifest(manifestPath);
|
|
1272
1304
|
if (manifest.workspaceId !== canonicalWorkspace) {
|
|
@@ -1289,7 +1321,7 @@ async function importDiscovered(ctx, args) {
|
|
|
1289
1321
|
}
|
|
1290
1322
|
return preview('import-discovered', {
|
|
1291
1323
|
manifest: publicDiscoveryManifest(manifest),
|
|
1292
|
-
receipt: previewDiscoveryImport(manifest, existing),
|
|
1324
|
+
receipt: previewDiscoveryImport(manifest, existing, new Date(), exclude),
|
|
1293
1325
|
confirmationRequired: !isDryRun(ctx, args),
|
|
1294
1326
|
wouldPersist: false,
|
|
1295
1327
|
});
|
|
@@ -1300,12 +1332,16 @@ async function importDiscovered(ctx, args) {
|
|
|
1300
1332
|
try {
|
|
1301
1333
|
const repository = openRepository(ctx, args);
|
|
1302
1334
|
try {
|
|
1335
|
+
const interruptedRuns = repository.interruptRunningBatchImports();
|
|
1303
1336
|
const receipt = await importDiscoveryManifest({
|
|
1304
1337
|
manifest,
|
|
1305
1338
|
repository,
|
|
1339
|
+
limits,
|
|
1340
|
+
exclude,
|
|
1306
1341
|
signal: ctx.signal,
|
|
1307
1342
|
inactivityThresholdMs: inactivityThreshold(args.values.get('--inactivity-threshold')),
|
|
1308
1343
|
});
|
|
1344
|
+
receipt.interruptedRuns = interruptedRuns;
|
|
1309
1345
|
return ok('import-discovered', {
|
|
1310
1346
|
manifestId: manifest.manifestId,
|
|
1311
1347
|
receipt,
|
|
@@ -1648,9 +1684,25 @@ function catalogScope(ctx, args, repository, workspaceId) {
|
|
|
1648
1684
|
: null,
|
|
1649
1685
|
};
|
|
1650
1686
|
}
|
|
1687
|
+
async function configuredImportLimits(ctx, args, workspace) {
|
|
1688
|
+
const selectedWorkspace = workspace ?? (args.values.has('--workspace')
|
|
1689
|
+
? resolve(ctx.cwd, args.values.get('--workspace')) : ctx.cwd);
|
|
1690
|
+
try {
|
|
1691
|
+
const config = await readAiwgConfig(selectedWorkspace);
|
|
1692
|
+
return resolveImportLimits(config?.sessions?.import, {
|
|
1693
|
+
maxRecordBytes: args.values.get('--max-record-bytes'),
|
|
1694
|
+
maxSourceBytes: args.values.get('--max-source-bytes'),
|
|
1695
|
+
});
|
|
1696
|
+
}
|
|
1697
|
+
catch (error) {
|
|
1698
|
+
throw new CliError('INVALID_ARGUMENT', error instanceof Error ? error.message : String(error), EXIT.usage);
|
|
1699
|
+
}
|
|
1700
|
+
}
|
|
1651
1701
|
function parseArgs(argv) {
|
|
1652
1702
|
const flags = new Set();
|
|
1653
1703
|
const values = new Map();
|
|
1704
|
+
const codexRoots = [];
|
|
1705
|
+
const exclude = [];
|
|
1654
1706
|
const positionals = [];
|
|
1655
1707
|
const valueFlags = new Set([
|
|
1656
1708
|
'--db', '--provider', '--workspace', '--tag', '--limit', '--cursor', '--source-id',
|
|
@@ -1659,7 +1711,7 @@ function parseArgs(argv) {
|
|
|
1659
1711
|
'--state', '--reviewer', '--reason', '--policy-version', '--min-confidence',
|
|
1660
1712
|
'--consumer', '--actor-class', '--reason-code', '--dependent-action', '--basis',
|
|
1661
1713
|
'--manifest', '--provider-home', '--codex-root', '--omp-root', '--muse-root', '--dsh-root', '--grokbot-root', '--lock-wait-ms', '--min-coverage', '--gap',
|
|
1662
|
-
'--inactivity-threshold', '--expected-providers',
|
|
1714
|
+
'--inactivity-threshold', '--expected-providers', '--exclude', '--max-record-bytes', '--max-source-bytes',
|
|
1663
1715
|
'--control-events',
|
|
1664
1716
|
'--session', '--status', '--actor', '--group-by',
|
|
1665
1717
|
'--out', '--plan', '--input', '--shard-name', '--max-attachment-bytes', '--format', '--grok-bin',
|
|
@@ -1673,6 +1725,10 @@ function parseArgs(argv) {
|
|
|
1673
1725
|
throw new CliError('MISSING_OPTION_VALUE', `missing value for ${arg}`, EXIT.usage);
|
|
1674
1726
|
}
|
|
1675
1727
|
values.set(arg, value);
|
|
1728
|
+
if (arg === '--codex-root')
|
|
1729
|
+
codexRoots.push(value);
|
|
1730
|
+
if (arg === '--exclude')
|
|
1731
|
+
exclude.push(value);
|
|
1676
1732
|
index += 1;
|
|
1677
1733
|
}
|
|
1678
1734
|
else if (arg.startsWith('-')) {
|
|
@@ -1685,7 +1741,7 @@ function parseArgs(argv) {
|
|
|
1685
1741
|
positionals.push(arg);
|
|
1686
1742
|
}
|
|
1687
1743
|
}
|
|
1688
|
-
return { command, positionals, flags, values };
|
|
1744
|
+
return { command, positionals, flags, values, codexRoots, exclude };
|
|
1689
1745
|
}
|
|
1690
1746
|
function requestedProviders(args) {
|
|
1691
1747
|
const value = args.values.get('--expected-providers');
|
|
@@ -1961,8 +2017,13 @@ function preview(command, data) {
|
|
|
1961
2017
|
function envelope(command, status, data, error) {
|
|
1962
2018
|
return { contractVersion: JSON_CONTRACT_VERSION, command, status, data, error };
|
|
1963
2019
|
}
|
|
1964
|
-
function emit(value) {
|
|
2020
|
+
async function emit(value) {
|
|
1965
2021
|
console.log(JSON.stringify(value, null, 2));
|
|
2022
|
+
// The launcher and router may force exit after the handler returns. A write
|
|
2023
|
+
// callback waits for the JSON already queued on stdout, including on pipes.
|
|
2024
|
+
await new Promise((resolve, reject) => {
|
|
2025
|
+
process.stdout.write('', (error) => error ? reject(error) : resolve());
|
|
2026
|
+
});
|
|
1966
2027
|
}
|
|
1967
2028
|
function printHuman(value) {
|
|
1968
2029
|
if (value.status === 'preview')
|
|
@@ -2015,7 +2076,7 @@ function normalizeError(error) {
|
|
|
2015
2076
|
}
|
|
2016
2077
|
if (error instanceof SessionContractError) {
|
|
2017
2078
|
const exitCode = error.code === 'UNSUPPORTED_OPERATION' ? EXIT.unsupported : EXIT.contract;
|
|
2018
|
-
return { error: { code: error.code, message: error.message }, exitCode };
|
|
2079
|
+
return { error: { code: error.code, message: error.message, ...(error.detail ? { details: error.detail } : {}) }, exitCode };
|
|
2019
2080
|
}
|
|
2020
2081
|
if (error instanceof ImportLeaseContentionError) {
|
|
2021
2082
|
return {
|
|
@@ -8,7 +8,7 @@ import { isInteractive } from '../env.js';
|
|
|
8
8
|
import { boundedSpawnSync } from '../../process/bounded-child-process.mjs';
|
|
9
9
|
import { sha256 } from '../../security/artifact-trust.js';
|
|
10
10
|
import { artifactVerifyHandler } from './artifact-verify.js';
|
|
11
|
-
import { requireFlagValue, MissingFlagValueError } from '../flag-parsing.js';
|
|
11
|
+
import { requireFlagValue, MissingFlagValueError, collectFlagValues, hasPositionalOrSwitch, argsTerminatorIndex, valueTokenIndexes } from '../flag-parsing.js';
|
|
12
12
|
import { exitCodeForSpawnResult } from '../child-process-result.js';
|
|
13
13
|
import { askString, createPromptInterface } from '../prompt-utils.js';
|
|
14
14
|
const SETUP_SCHEMA_REL = 'agentic/code/addons/agentic-installer/schemas/v1/setup-manifest.schema.json';
|
|
@@ -76,9 +76,8 @@ Safety:
|
|
|
76
76
|
Headless input steps (#3062):
|
|
77
77
|
A 'type: ask' step resolves its declared 'params' the same way a 'script'
|
|
78
78
|
step's env vars do (--param/--params-file/env/default); if every declared
|
|
79
|
-
param is already resolved it runs headless
|
|
80
|
-
|
|
81
|
-
mechanism for 'ask' steps, with or without a terminal. A step marked
|
|
79
|
+
param is already resolved it runs headless; otherwise a terminal prompts
|
|
80
|
+
for missing values. Without a terminal it refuses and names the missing params. A step marked
|
|
82
81
|
'interactive: true' runs an arbitrary script whose questions cannot be
|
|
83
82
|
enumerated; without a terminal it is refused outright. Every selected
|
|
84
83
|
step (including nested 'platform-route' steps) is preflighted for both
|
|
@@ -96,40 +95,17 @@ Headless input steps (#3062):
|
|
|
96
95
|
function flagValue(args, name) {
|
|
97
96
|
return requireFlagValue(args, {}, name);
|
|
98
97
|
}
|
|
98
|
+
const VALUE_FLAGS = [
|
|
99
|
+
'--manifest', '--schema', '--platform', '--distro', '--params-file', '--param', '--set',
|
|
100
|
+
'--step', '--skip', '--type', '--output', '--name', '--attestation', '--policy', '--state',
|
|
101
|
+
'--asset-type', '--namespace', '--channel',
|
|
102
|
+
];
|
|
99
103
|
function hasFlag(args, ...names) {
|
|
100
|
-
return
|
|
104
|
+
return names.some(name => hasPositionalOrSwitch(args, name, VALUE_FLAGS));
|
|
101
105
|
}
|
|
102
106
|
function positionalManifest(args) {
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
'--schema',
|
|
106
|
-
'--platform',
|
|
107
|
-
'--distro',
|
|
108
|
-
'--params-file',
|
|
109
|
-
'--param',
|
|
110
|
-
'--set',
|
|
111
|
-
'--step',
|
|
112
|
-
'--skip',
|
|
113
|
-
'--type',
|
|
114
|
-
'--output',
|
|
115
|
-
'--name',
|
|
116
|
-
'--attestation',
|
|
117
|
-
'--policy',
|
|
118
|
-
'--state',
|
|
119
|
-
'--asset-type',
|
|
120
|
-
'--namespace',
|
|
121
|
-
'--channel',
|
|
122
|
-
]);
|
|
123
|
-
for (let i = 0; i < args.length; i += 1) {
|
|
124
|
-
const arg = args[i];
|
|
125
|
-
if (valueFlags.has(arg)) {
|
|
126
|
-
i += 1;
|
|
127
|
-
continue;
|
|
128
|
-
}
|
|
129
|
-
if (!arg.startsWith('-'))
|
|
130
|
-
return arg;
|
|
131
|
-
}
|
|
132
|
-
return undefined;
|
|
107
|
+
const consumed = valueTokenIndexes(args, VALUE_FLAGS);
|
|
108
|
+
return args.slice(0, argsTerminatorIndex(args)).find((arg, index) => !consumed.has(index) && !arg.startsWith('-'));
|
|
133
109
|
}
|
|
134
110
|
function resolveSchemaPath(frameworkRoot, cwd, override) {
|
|
135
111
|
if (override)
|
|
@@ -472,15 +448,12 @@ function renderValidationText(result) {
|
|
|
472
448
|
}
|
|
473
449
|
function parseParamValues(args) {
|
|
474
450
|
const values = {};
|
|
475
|
-
for (
|
|
476
|
-
if (args[i] !== '--param' && args[i] !== '--set')
|
|
477
|
-
continue;
|
|
478
|
-
const raw = args[i + 1] ?? '';
|
|
451
|
+
for (const raw of collectFlagValues(args, {}, '--param', '--set')) {
|
|
479
452
|
const eq = raw.indexOf('=');
|
|
480
|
-
if (eq <= 0)
|
|
481
|
-
throw new
|
|
453
|
+
if (eq <= 0 || !raw.slice(0, eq).trim())
|
|
454
|
+
throw new MissingFlagValueError('--param KEY=VALUE');
|
|
455
|
+
// An empty parameter value is supported (e.g. explicitly clearing a default).
|
|
482
456
|
values[raw.slice(0, eq)] = raw.slice(eq + 1);
|
|
483
|
-
i += 1;
|
|
484
457
|
}
|
|
485
458
|
return values;
|
|
486
459
|
}
|
|
@@ -1068,10 +1041,21 @@ export async function runSetupManifest(options) {
|
|
|
1068
1041
|
return { exitCode: 1, message: `setup-run: platform ${target.os}${target.distro ? `/${target.distro}` : ''}/${target.arch}/${target.shell} is not declared in the manifest` };
|
|
1069
1042
|
}
|
|
1070
1043
|
const params = resolveParams(manifest, options);
|
|
1071
|
-
|
|
1044
|
+
const steps = selectedSteps(manifest, options);
|
|
1045
|
+
const askSteps = [];
|
|
1046
|
+
const collectAsks = (selected) => {
|
|
1047
|
+
for (const step of selected) {
|
|
1048
|
+
if (step.type === 'ask')
|
|
1049
|
+
askSteps.push(step);
|
|
1050
|
+
if (step.type === 'platform-route')
|
|
1051
|
+
collectAsks(step.routes?.find(route => route.platform === target.os)?.steps ?? []);
|
|
1052
|
+
}
|
|
1053
|
+
};
|
|
1054
|
+
collectAsks(steps);
|
|
1055
|
+
const promptable = new Set(isInteractive() ? askSteps.flatMap(askStepParams) : []);
|
|
1056
|
+
if (params.missing.some(name => !promptable.has(name))) {
|
|
1072
1057
|
return { exitCode: 1, message: `setup-run: required params missing before execution: ${params.missing.join(', ')}` };
|
|
1073
1058
|
}
|
|
1074
|
-
const steps = selectedSteps(manifest, options);
|
|
1075
1059
|
if (options.step && steps.length === 0)
|
|
1076
1060
|
return { exitCode: 1, message: `setup-run: step '${options.step}' not found` };
|
|
1077
1061
|
if (options.dryRun) {
|
|
@@ -1095,6 +1079,17 @@ export async function runSetupManifest(options) {
|
|
|
1095
1079
|
message: `setup-run: refusing before executing any step:\n${blockers.map((b) => ` - ${b}`).join('\n')}`,
|
|
1096
1080
|
};
|
|
1097
1081
|
}
|
|
1082
|
+
// Resolve required ask inputs before any scripts can consume them.
|
|
1083
|
+
for (const step of askSteps) {
|
|
1084
|
+
const missing = missingAskParams(step, params.values).filter(name => params.missing.includes(name));
|
|
1085
|
+
if (!missing.length)
|
|
1086
|
+
continue;
|
|
1087
|
+
Object.assign(params.values, await promptForAskStep(step, missing));
|
|
1088
|
+
}
|
|
1089
|
+
const checked = resolveParams(manifest, { ...options, paramValues: { ...options.paramValues, ...params.values } });
|
|
1090
|
+
if (checked.missing.length)
|
|
1091
|
+
return { exitCode: 1, message: `setup-run: required params missing before execution: ${checked.missing.join(', ')}` };
|
|
1092
|
+
Object.assign(params.values, checked.values);
|
|
1098
1093
|
for (const step of steps) {
|
|
1099
1094
|
const result = await runStep(step, manifest, validation.manifestDir, params.values, target.os, options.yes);
|
|
1100
1095
|
if (!result.ok) {
|
|
@@ -476,6 +476,45 @@ export const setupHandler = {
|
|
|
476
476
|
description: 'CLI helper for agent-led repository policy and tracker setup',
|
|
477
477
|
category: 'project',
|
|
478
478
|
aliases: [],
|
|
479
|
+
async help() {
|
|
480
|
+
return {
|
|
481
|
+
exitCode: 0,
|
|
482
|
+
rawOutput: true,
|
|
483
|
+
message: `Usage: aiwg setup project [options]
|
|
484
|
+
|
|
485
|
+
Options:
|
|
486
|
+
--target <dir> Project directory
|
|
487
|
+
--yes Confirm writes without prompting
|
|
488
|
+
--dry-run Preview the setup plan
|
|
489
|
+
--non-interactive Disable prompts
|
|
490
|
+
--json Emit the plan as JSON
|
|
491
|
+
--primary <remote> Primary repository remote
|
|
492
|
+
--issue-tracker <remote> Internal issue tracker remote
|
|
493
|
+
--customer-issue-tracker <remote> Customer issue tracker remote
|
|
494
|
+
--ci <remote> CI remote
|
|
495
|
+
--issue-provider <provider> Internal tracker provider
|
|
496
|
+
--customer-issue-provider <provider> Customer tracker provider
|
|
497
|
+
--delivery-mode <mode> Delivery policy
|
|
498
|
+
--default-branch <branch> Default branch
|
|
499
|
+
--require-ci-green <boolean> Require passing CI
|
|
500
|
+
--auto-close-issues <boolean> Close delivered issues
|
|
501
|
+
--issue-comment-on-cycle <boolean> Report issue cycles
|
|
502
|
+
--force-push-policy <policy> Force-push policy
|
|
503
|
+
--require-signed-commits <boolean> Require signed commits
|
|
504
|
+
--committer-name <name> Committer identity
|
|
505
|
+
--committer-email <email> Committer email
|
|
506
|
+
--signing-format <format> Signing format
|
|
507
|
+
--signing-key <key> Signing key
|
|
508
|
+
--signing-enforce <commits|tags|all> Signing enforcement
|
|
509
|
+
--tracker-actor-login <login> Internal tracker actor
|
|
510
|
+
--tracker-actor-via <via> Internal tracker access method
|
|
511
|
+
--customer-tracker-actor-login <login> Customer tracker actor
|
|
512
|
+
--customer-tracker-actor-via <via> Customer tracker access method
|
|
513
|
+
--worker-dispatch <choice> Worker dispatch policy
|
|
514
|
+
--providers <ids> Comma-separated provider IDs
|
|
515
|
+
`,
|
|
516
|
+
};
|
|
517
|
+
},
|
|
479
518
|
async execute(ctx) {
|
|
480
519
|
const [subcommand] = ctx.args;
|
|
481
520
|
if (subcommand && subcommand !== 'project' && !subcommand.startsWith('--')) {
|
|
@@ -560,6 +599,8 @@ export const setupHandler = {
|
|
|
560
599
|
}
|
|
561
600
|
else {
|
|
562
601
|
printPlan(plan);
|
|
602
|
+
if (options.workerDispatchChoice === 'enable')
|
|
603
|
+
ui.info('Next: aiwg doctor --probe-workers --qualify.');
|
|
563
604
|
if (plan.workerDispatchOffer.shouldOffer) {
|
|
564
605
|
ui.info(workerDispatchOfferHintWithArg(plan.workerDispatchOffer.detected));
|
|
565
606
|
}
|
|
@@ -204,6 +204,7 @@ async function handleSteward(args, ctx) {
|
|
|
204
204
|
aiwg steward — Provider capability awareness and command routing
|
|
205
205
|
|
|
206
206
|
Usage:
|
|
207
|
+
aiwg steward decision-offload [--json] Offline advisory readiness and adoption report
|
|
207
208
|
aiwg steward capabilities --provider <name> Capabilities for a specific provider
|
|
208
209
|
aiwg steward capabilities --feature <name> Provider support matrix for a feature
|
|
209
210
|
aiwg steward capabilities --all Full matrix (all providers x features)
|
|
@@ -231,6 +232,16 @@ async function handleSteward(args, ctx) {
|
|
|
231
232
|
`);
|
|
232
233
|
return;
|
|
233
234
|
}
|
|
235
|
+
if (subcommand === 'decision-offload') {
|
|
236
|
+
const unknown = args.slice(1).filter(arg => arg !== '--json');
|
|
237
|
+
if (unknown.length)
|
|
238
|
+
throw new AiwgError({ code: 'ERR_USAGE_UNKNOWN_ARGUMENT',
|
|
239
|
+
message: `Unknown decision-offload argument: ${unknown[0]}`, exitCode: EXIT_CODES.USAGE });
|
|
240
|
+
const { buildDecisionOffloadSnapshot } = await import('../../decision/offload.js');
|
|
241
|
+
const decisionOffload = await buildDecisionOffloadSnapshot({ projectRoot: ctx?.cwd ?? process.cwd(), frameworkRoot: ctx?.frameworkRoot });
|
|
242
|
+
console.log(JSON.stringify(args.includes('--json') ? { decisionOffload } : decisionOffload, null, 2));
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
234
245
|
if (subcommand === 'permissions') {
|
|
235
246
|
const operation = args[1];
|
|
236
247
|
// `<namespace> --help` must reach the same usage block bare invocation prints (#2533).
|