@aiwg/cli 2026.10.4 → 2026.10.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +3 -1
- package/dist/src/artifacts/browser-export.js +1 -0
- package/dist/src/artifacts/citation-parser.js +8 -1
- package/dist/src/artifacts/cli.js +72 -9
- 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/graph-query.js +18 -8
- package/dist/src/artifacts/index-adapters.js +339 -0
- package/dist/src/artifacts/index-builder.js +146 -16
- package/dist/src/artifacts/index-files.js +15 -4
- package/dist/src/artifacts/index-preparation.js +91 -26
- package/dist/src/artifacts/index-reader.js +44 -0
- package/dist/src/artifacts/index-refresh.js +130 -56
- package/dist/src/artifacts/index-status.js +20 -5
- package/dist/src/artifacts/index-worker.mjs +9 -7
- 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/cli/handlers/decision.js +19 -1
- 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/local-executor.js +5 -3
- 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 +40 -6
- package/dist/src/cli/handlers/setup.js +428 -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 +279 -93
- package/dist/src/cli/handlers/workspace.js +3 -1
- package/dist/src/cli/prompt-utils.js +8 -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/native-sandbox-warnings.js +25 -0
- package/dist/src/contributors/validation.js +6 -5
- package/dist/src/decision/admission.js +7 -3
- package/dist/src/decision/benchmark.js +469 -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 +18 -15
- package/dist/src/decision/qualification/load-staged.js +539 -0
- package/dist/src/decision/qualification/load.js +109 -33
- package/dist/src/decision/qualification/runner.js +5 -2
- 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 +233 -0
- package/dist/src/discovery/plan-apply.js +571 -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/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-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/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/mcp/cli.mjs +5 -6
- package/dist/src/mcp/config-file.mjs +6 -2
- package/dist/src/mcp/config-layers.mjs +23 -7
- 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 +17 -4
- 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/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/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 +7 -0
- package/dist/src/models/worker-installation.mjs +169 -37
- package/dist/src/models/wrapper-route.js +1 -1
- package/dist/src/output-modes/registry.js +8 -7
- package/dist/src/plugin/metadata-validator.js +1 -1
- 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 +114 -15
- package/dist/src/sessions/adapters/claude.js +19 -18
- package/dist/src/sessions/adapters/codex.js +33 -19
- 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/batch-contracts.js +1 -1
- package/dist/src/sessions/batch-import.js +202 -2
- package/dist/src/sessions/candidates.js +7 -6
- package/dist/src/sessions/contracts.js +73 -54
- package/dist/src/sessions/coverage-preflight.js +26 -1
- package/dist/src/sessions/output-registration.js +11 -10
- package/dist/src/sessions/policy.js +18 -7
- package/dist/src/sessions/refresh.js +2 -3
- package/dist/src/sessions/repository.js +4 -2
- package/dist/src/sessions/workspace-discovery.js +92 -26
- package/dist/src/smiths/context-pipeline/aiwg-md.js +18 -1
- package/dist/src/smiths/context-pipeline/claude-hook.js +42 -6
- package/dist/src/smiths/context-pipeline/parallelism-section.js +72 -5
- package/dist/src/smiths/context-pipeline/workspace-context.js +106 -10
- package/dist/src/update/checker.d.mts +4 -0
- package/dist/src/update/checker.mjs +14 -0
- 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 +19 -13
- package/tools/agents/providers/claude.mjs +1 -1
- package/tools/agents/providers/codex.mjs +50 -56
- package/tools/agents/providers/copilot.mjs +8 -2
- 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 +7 -13
- package/tools/agents/providers/muse-hooks.mjs +21 -14
- package/tools/agents/providers/muse.mjs +7 -2
- package/tools/agents/providers/omp.mjs +28 -4
- 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 +263 -71
- package/tools/agents/providers/windsurf.mjs +7 -0
- 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/muse-adapter.mjs +12 -2
- 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 +7 -4
- package/tools/ralph-external/session-launcher.mjs +280 -32
- package/tools/skills/deploy-skills-codex.mjs +11 -7
- package/vscode-extension/schemas/aiwg.config.v1.json +11 -1
|
@@ -8,7 +8,7 @@ import { isDeepStrictEqual } from 'node:util';
|
|
|
8
8
|
import path from 'node:path';
|
|
9
9
|
import { glob } from 'glob';
|
|
10
10
|
import { load as loadYaml } from 'js-yaml';
|
|
11
|
-
import { compileModelPolicy, validateCanonicalModelPolicy, validateUserProjectModelConfig, loadProviderModelCapabilities, WorkerPolicyError, } from '../../models/provider-policy.js';
|
|
11
|
+
import { compileModelPolicy, validateCanonicalModelPolicy, validateUserProjectModelConfig, loadProviderModelCapabilities, WorkerPolicyError, assertWorkerRoleEffort, } from '../../models/provider-policy.js';
|
|
12
12
|
import { resolveGrokBuildRoleModel } from '../../models/grok-build-models.js';
|
|
13
13
|
import { readAiwgConfig, emptyConfig } from '../../config/aiwg-config.js';
|
|
14
14
|
import { ConfigLoader } from '../../models/config-loader.js';
|
|
@@ -39,8 +39,38 @@ export async function loadWorkerInputs(ctx) {
|
|
|
39
39
|
return { snapshot: { config, models, modelDigests: loader.getInputDigests(), catalog,
|
|
40
40
|
registry, installations: {} }, drivers: {} };
|
|
41
41
|
}
|
|
42
|
+
// Explain missing policy before a recorded approval's digest check can
|
|
43
|
+
// mask it. The host owner first preserves its missing-installation errors.
|
|
44
|
+
const parallelism = config.parallelism;
|
|
45
|
+
const precheckPolicy = () => {
|
|
46
|
+
if (!ctx.args.some(arg => arg === '--role' || arg.startsWith('--role=')))
|
|
47
|
+
return;
|
|
48
|
+
const request = parseWorkerCommandArgs(ctx.args.slice(1));
|
|
49
|
+
const members = Object.entries(parallelism.groups ?? {})
|
|
50
|
+
.filter(([id]) => !request.group || request.group === id)
|
|
51
|
+
.flatMap(([, group]) => group.members).filter(member => member.enabled !== false
|
|
52
|
+
&& parallelism.clis?.[member.cli]?.enabled !== false && member.roles.includes(request.role));
|
|
53
|
+
const requiresExplicit = members.length > 0 && members.every(member => {
|
|
54
|
+
// Health metadata can identify the provider before an operator has
|
|
55
|
+
// qualified its dispatch adapter. It grants no dispatch authority.
|
|
56
|
+
const [namespace, id] = (parallelism.clis?.[member.cli]?.adapter ?? `providers:${member.cli}`).split(':');
|
|
57
|
+
const provider = namespace === 'providers' ? registry.providers[id] : undefined;
|
|
58
|
+
const adapter = namespace === 'workerAdapters' ? registry.workerAdapters?.[id]
|
|
59
|
+
: provider?.workerAdapter ?? provider?.workerHealthAdapter;
|
|
60
|
+
const observation = (catalog.discovery?.instances?.[member.cli]
|
|
61
|
+
?? catalog.discovery?.providers?.[adapter?.provider ?? id])?.models.find(row => row.id === member.model)?.worker;
|
|
62
|
+
if (observation?.effortSupport === 'explicit')
|
|
63
|
+
return true;
|
|
64
|
+
if (observation?.effortSupport === 'not-applicable')
|
|
65
|
+
return false;
|
|
66
|
+
return adapter?.capabilities.effort === 'explicit';
|
|
67
|
+
});
|
|
68
|
+
// With no matching worker, do not invent policy needs.
|
|
69
|
+
if (members.length)
|
|
70
|
+
assertWorkerRoleEffort(models.defaults.workerSelection, request.role, requiresExplicit);
|
|
71
|
+
};
|
|
42
72
|
const { registry: qualifiedRegistry, installations, drivers, observations } = await loadRecordedWorkerInstallations({
|
|
43
|
-
registry, cwd: ctx.cwd, policy: models.defaults.workerSelection, parallelism: config.parallelism,
|
|
73
|
+
registry, cwd: ctx.cwd, policy: models.defaults.workerSelection, parallelism: config.parallelism, precheckPolicy,
|
|
44
74
|
});
|
|
45
75
|
catalog.discovery ??= { source: 'static', fetchedAt: new Date().toISOString(), providers: {} };
|
|
46
76
|
catalog.discovery.instances = { ...catalog.discovery.instances };
|
|
@@ -62,6 +62,13 @@ export function generateLoopId(objective) {
|
|
|
62
62
|
* Build command-line arguments for the external Ralph process
|
|
63
63
|
*/
|
|
64
64
|
export function buildArgs(options) {
|
|
65
|
+
if (options.managedWorker) {
|
|
66
|
+
if (!options.managedAdmission)
|
|
67
|
+
throw new Error('Managed worker execution requires admission');
|
|
68
|
+
return ['--launch-worker', '--invocation', options.managedWorker.invocationPath,
|
|
69
|
+
'--run-dir', options.managedWorker.runDir, '--managed-request', options.managedAdmission.requestId,
|
|
70
|
+
'--managed-generation', String(options.managedAdmission.generation)];
|
|
71
|
+
}
|
|
65
72
|
const args = [options.objective];
|
|
66
73
|
args.push('--completion', options.completionCriteria);
|
|
67
74
|
if (options.maxIterations) {
|
|
@@ -175,7 +182,9 @@ export async function assertRalphParallelismCap(projectRoot) {
|
|
|
175
182
|
* Launch the external Ralph process as a detached daemon
|
|
176
183
|
*/
|
|
177
184
|
export async function launchExternalRalph(frameworkRoot, projectRoot, options) {
|
|
178
|
-
const orchestratorPath =
|
|
185
|
+
const orchestratorPath = options.managedWorker
|
|
186
|
+
? join(frameworkRoot, 'tools', 'ralph-external', 'session-launcher.mjs')
|
|
187
|
+
: getOrchestratorPath(frameworkRoot);
|
|
179
188
|
if (!existsSync(orchestratorPath)) {
|
|
180
189
|
throw new AiwgError({
|
|
181
190
|
code: 'ERR_RALPH_ORCHESTRATOR_MISSING',
|
|
@@ -191,6 +200,9 @@ export async function launchExternalRalph(frameworkRoot, projectRoot, options) {
|
|
|
191
200
|
// surprising. Tell the operator what's running and how to lift the cap.
|
|
192
201
|
await assertRalphParallelismCap(projectRoot);
|
|
193
202
|
const loopId = options.loopId || generateLoopId(options.objective);
|
|
203
|
+
if (loadLauncherRegistry(projectRoot).loops[loopId]?.managedAdmission) {
|
|
204
|
+
throw new Error('Managed loop identity cannot be relaunched before admission reconciliation');
|
|
205
|
+
}
|
|
194
206
|
const loopDir = join(registryDir, 'loops', loopId);
|
|
195
207
|
mkdirSync(loopDir, { recursive: true });
|
|
196
208
|
// Create output file for the detached process
|
|
@@ -200,6 +212,17 @@ export async function launchExternalRalph(frameworkRoot, projectRoot, options) {
|
|
|
200
212
|
const promptFile = join(loopDir, 'prompts', '001-prompt.md');
|
|
201
213
|
// Build arguments
|
|
202
214
|
const args = buildArgs(options);
|
|
215
|
+
if (options.managedAdmission) {
|
|
216
|
+
const registry = loadLauncherRegistry(projectRoot);
|
|
217
|
+
registry.loops[loopId] = { loopId, pid: 0, objective: options.objective,
|
|
218
|
+
completionCriteria: options.completionCriteria, status: 'running',
|
|
219
|
+
startedAt: new Date().toISOString(), lastUpdate: new Date().toISOString(),
|
|
220
|
+
iteration: 0, maxIterations: options.managedWorker ? 1 : options.maxIterations || 5, outputFile,
|
|
221
|
+
sessionStdoutFile, sessionStderrFile, promptFile, provider: options.provider,
|
|
222
|
+
managedAdmission: { ...options.managedAdmission },
|
|
223
|
+
...(options.managedWorker ? { managedWorker: { ...options.managedWorker } } : {}) };
|
|
224
|
+
saveLauncherRegistry(projectRoot, registry);
|
|
225
|
+
}
|
|
203
226
|
// Create output file descriptors
|
|
204
227
|
const { openSync, closeSync } = await import('fs');
|
|
205
228
|
const outFd = openSync(outputFile, 'w');
|
|
@@ -232,6 +255,25 @@ export async function launchExternalRalph(frameworkRoot, projectRoot, options) {
|
|
|
232
255
|
exitCode: EXIT_CODES.GENERAL,
|
|
233
256
|
});
|
|
234
257
|
}
|
|
258
|
+
let managedAdmission;
|
|
259
|
+
if (options.managedAdmission) {
|
|
260
|
+
const { sampleWorkerIdentity, createWorkerIdentityCapture } = await import(join(frameworkRoot, 'tools', 'ralph-external', 'process-monitor.mjs'));
|
|
261
|
+
const capture = createWorkerIdentityCapture({ timeoutMs: 250 });
|
|
262
|
+
const identityDeadline = process.hrtime.bigint() + 250000000n;
|
|
263
|
+
let identity;
|
|
264
|
+
while (!identity && process.hrtime.bigint() < identityDeadline) {
|
|
265
|
+
if ((child.exitCode !== null && child.exitCode !== undefined) || child.signalCode)
|
|
266
|
+
break;
|
|
267
|
+
identity = capture.observe(sampleWorkerIdentity(pid));
|
|
268
|
+
if (!identity)
|
|
269
|
+
await new Promise(resolve => setTimeout(resolve, 10));
|
|
270
|
+
}
|
|
271
|
+
if (!identity?.bootId || !identity.startTicks || !Number.isSafeInteger(identity.uid)) {
|
|
272
|
+
throw new Error('managed Ralph execution identity unavailable; reconcile uncertain launch');
|
|
273
|
+
}
|
|
274
|
+
managedAdmission = { ...options.managedAdmission,
|
|
275
|
+
execution: { pid, startedAt: `${identity.bootId}:${identity.startTicks}:${identity.uid}` }, processIdentity: identity };
|
|
276
|
+
}
|
|
235
277
|
// Record the loop in our launcher registry (backup to the external-multi-loop-state-manager)
|
|
236
278
|
const launcherRegistry = loadLauncherRegistry(projectRoot);
|
|
237
279
|
launcherRegistry.loops[loopId] = {
|
|
@@ -243,12 +285,14 @@ export async function launchExternalRalph(frameworkRoot, projectRoot, options) {
|
|
|
243
285
|
startedAt: new Date().toISOString(),
|
|
244
286
|
lastUpdate: new Date().toISOString(),
|
|
245
287
|
iteration: 0,
|
|
246
|
-
maxIterations: options.maxIterations || 5,
|
|
288
|
+
maxIterations: options.managedWorker ? 1 : options.maxIterations || 5,
|
|
247
289
|
outputFile,
|
|
248
290
|
sessionStdoutFile,
|
|
249
291
|
sessionStderrFile,
|
|
250
292
|
promptFile,
|
|
251
293
|
provider: options.provider,
|
|
294
|
+
...(managedAdmission ? { managedAdmission } : {}),
|
|
295
|
+
...(options.managedWorker ? { managedWorker: { ...options.managedWorker } } : {}),
|
|
252
296
|
};
|
|
253
297
|
saveLauncherRegistry(projectRoot, launcherRegistry);
|
|
254
298
|
return {
|
|
@@ -257,6 +301,7 @@ export async function launchExternalRalph(frameworkRoot, projectRoot, options) {
|
|
|
257
301
|
pid,
|
|
258
302
|
message: `agent loop started (${loopId}). Check status: aiwg ralph-status`,
|
|
259
303
|
registryPath: getRegistryPath(projectRoot),
|
|
304
|
+
...(managedAdmission ? { execution: managedAdmission.execution } : {}),
|
|
260
305
|
};
|
|
261
306
|
}
|
|
262
307
|
/**
|
|
@@ -341,7 +386,7 @@ export function getLoopStatuses(projectRoot, options = {}) {
|
|
|
341
386
|
entry.stale = true;
|
|
342
387
|
}
|
|
343
388
|
// Auto-clean completed entries if requested
|
|
344
|
-
if (options.autoCleanCompleted && (entry.status === 'completed')) {
|
|
389
|
+
if (options.autoCleanCompleted && !entry.managedAdmission && (entry.status === 'completed')) {
|
|
345
390
|
cleanupCompletedLoop(projectRoot, loopId);
|
|
346
391
|
registryDirty = true;
|
|
347
392
|
continue; // Don't include in statuses
|
|
@@ -372,6 +417,8 @@ export function abortLoop(projectRoot, loopId) {
|
|
|
372
417
|
if (!entry) {
|
|
373
418
|
return { success: false, message: `Loop not found: ${loopId}` };
|
|
374
419
|
}
|
|
420
|
+
if (entry.managedAdmission)
|
|
421
|
+
return { success: false, message: 'Managed loop cancellation requires its current admission generation' };
|
|
375
422
|
if (!isProcessAlive(entry.pid)) {
|
|
376
423
|
entry.status = 'aborted';
|
|
377
424
|
saveLauncherRegistry(projectRoot, registry);
|
|
@@ -391,6 +438,26 @@ export function abortLoop(projectRoot, loopId) {
|
|
|
391
438
|
};
|
|
392
439
|
}
|
|
393
440
|
}
|
|
441
|
+
/** Signal only the birth identity bound to this current managed reservation.
|
|
442
|
+
* Native Ralph exit/status cannot prove descendant termination, so cancellation
|
|
443
|
+
* always leaves its admission reservation uncertain for explicit reconciliation.
|
|
444
|
+
*/
|
|
445
|
+
export async function cancelManagedRalph(frameworkRoot, projectRoot, loopId, binding) {
|
|
446
|
+
const entry = loadLauncherRegistry(projectRoot).loops[loopId];
|
|
447
|
+
const owned = entry?.managedAdmission;
|
|
448
|
+
if (!owned?.execution || !owned.processIdentity || owned.requestId !== binding.requestId || owned.generation !== binding.generation
|
|
449
|
+
|| owned.execution.pid !== binding.execution.pid || owned.execution.startedAt !== binding.execution.startedAt) {
|
|
450
|
+
return { state: 'uncertain', signalled: false };
|
|
451
|
+
}
|
|
452
|
+
const { sampleWorkerIdentity } = await import(join(frameworkRoot, 'tools', 'ralph-external', 'process-monitor.mjs'));
|
|
453
|
+
const identity = sampleWorkerIdentity(owned.execution.pid);
|
|
454
|
+
const expected = owned.processIdentity;
|
|
455
|
+
if (!identity || ['pid', 'uid', 'bootId', 'startTicks', 'executable', 'pgid', 'sessionId']
|
|
456
|
+
.some(key => identity[key] !== expected[key]))
|
|
457
|
+
return { state: 'uncertain', signalled: false };
|
|
458
|
+
const { signalOwnedWorker } = await import(join(frameworkRoot, 'tools', 'ralph-external', 'session-launcher.mjs'));
|
|
459
|
+
return { state: 'uncertain', signalled: signalOwnedWorker(identity, 'SIGTERM') };
|
|
460
|
+
}
|
|
394
461
|
/**
|
|
395
462
|
* Resume an interrupted agent loop
|
|
396
463
|
*/
|
|
@@ -438,6 +505,8 @@ export async function resumeLoop(frameworkRoot, projectRoot, loopId, overrides)
|
|
|
438
505
|
exitCode: EXIT_CODES.USAGE,
|
|
439
506
|
});
|
|
440
507
|
}
|
|
508
|
+
if (entry.managedAdmission)
|
|
509
|
+
throw new Error('Managed loops require policy and admission reconciliation before resume');
|
|
441
510
|
const loopDir = join(registryDir, 'loops', targetLoopId);
|
|
442
511
|
const outputFile = join(loopDir, 'daemon-output.log');
|
|
443
512
|
// Create output file descriptor
|
|
@@ -494,6 +563,9 @@ export function cleanupCompletedLoop(projectRoot, loopId, options = {}) {
|
|
|
494
563
|
const registryDir = getRegistryDir(projectRoot);
|
|
495
564
|
const loopDir = join(registryDir, 'loops', loopId);
|
|
496
565
|
const preserved = [];
|
|
566
|
+
if (loadLauncherRegistry(projectRoot).loops[loopId]?.managedAdmission) {
|
|
567
|
+
return { success: false, message: 'Managed loop artifacts require admission reconciliation before cleanup', preserved };
|
|
568
|
+
}
|
|
497
569
|
// Preserve completion reports before deleting the loop directory
|
|
498
570
|
if (existsSync(loopDir)) {
|
|
499
571
|
try {
|
|
@@ -616,7 +688,7 @@ export function cleanupRegistry(projectRoot, keepDays = 7) {
|
|
|
616
688
|
const cutoff = Date.now() - keepDays * 24 * 60 * 60 * 1000;
|
|
617
689
|
let cleaned = 0;
|
|
618
690
|
for (const [loopId, entry] of Object.entries(registry.loops)) {
|
|
619
|
-
if (entry.status !== 'running') {
|
|
691
|
+
if (entry.status !== 'running' && !entry.managedAdmission) {
|
|
620
692
|
const lastUpdate = new Date(entry.lastUpdate).getTime();
|
|
621
693
|
if (lastUpdate < cutoff) {
|
|
622
694
|
delete registry.loops[loopId];
|
|
@@ -68,7 +68,7 @@ export const rulesHandler = {
|
|
|
68
68
|
throw new Error('Invalid inventory scope');
|
|
69
69
|
const activation = list('--activation');
|
|
70
70
|
const tier = list('--tier');
|
|
71
|
-
if (activation?.some(value => !['kernel', 'summary', 'bound', 'paths', 'on-demand'].includes(value)))
|
|
71
|
+
if (activation?.some(value => !['core', 'kernel', 'summary', 'bound', 'paths', 'on-demand'].includes(value)))
|
|
72
72
|
throw new Error('Invalid activation filter');
|
|
73
73
|
if (tier?.some(value => !['critical', 'high', 'medium', 'low'].includes(value)))
|
|
74
74
|
throw new Error('Invalid tier filter');
|
|
@@ -11,10 +11,17 @@
|
|
|
11
11
|
import { signalChild } from '../../process/signal-child.mjs';
|
|
12
12
|
import { spawn } from 'child_process';
|
|
13
13
|
import path from 'path';
|
|
14
|
+
import { pathToFileURL } from 'node:url';
|
|
15
|
+
import { Console } from 'node:console';
|
|
16
|
+
import { Writable } from 'node:stream';
|
|
17
|
+
import { writeSync } from 'node:fs';
|
|
18
|
+
// Embedded deployers use process-wide console/environment APIs. Serialize the
|
|
19
|
+
// complete invocation (including import), and restore them even after failure.
|
|
20
|
+
let deploymentQueue = Promise.resolve();
|
|
14
21
|
/**
|
|
15
22
|
* Default script runner implementation
|
|
16
23
|
*
|
|
17
|
-
*
|
|
24
|
+
* Embeds repeatable agent deployment passes; runs other scripts in a child.
|
|
18
25
|
*/
|
|
19
26
|
export class DefaultScriptRunner {
|
|
20
27
|
frameworkRoot;
|
|
@@ -30,12 +37,26 @@ export class DefaultScriptRunner {
|
|
|
30
37
|
*/
|
|
31
38
|
async run(scriptPath, args = [], options = {}) {
|
|
32
39
|
const fullPath = path.join(this.frameworkRoot, scriptPath);
|
|
40
|
+
if (scriptPath === 'tools/agents/deploy-agents.mjs'
|
|
41
|
+
&& process.env.AIWG_DEPLOY_SUBPROCESS !== '1'
|
|
42
|
+
&& options.env?.AIWG_DEPLOY_SUBPROCESS !== '1'
|
|
43
|
+
&& !options.timeout
|
|
44
|
+
&& (!options.cwd || path.resolve(options.cwd) === process.cwd())
|
|
45
|
+
// Other environment overrides can affect module initialization. Keep
|
|
46
|
+
// those callers isolated; AIWG_ROOT is resolved afresh by each pass.
|
|
47
|
+
&& Object.keys(options.env ?? {}).every(key => key === 'AIWG_ROOT')) {
|
|
48
|
+
const invocation = deploymentQueue.then(() => this.runDeployment(fullPath, args, options));
|
|
49
|
+
deploymentQueue = invocation.catch(() => { });
|
|
50
|
+
return invocation;
|
|
51
|
+
}
|
|
33
52
|
return new Promise((resolve) => {
|
|
34
53
|
// When capture mode is enabled, stdout/stderr are piped so that
|
|
35
54
|
// quiet-mode callers can suppress output. When not
|
|
36
55
|
// capturing, stdio: 'inherit' lets subprocess output flow directly to
|
|
37
56
|
// the terminal (verbose mode).
|
|
38
|
-
const stdio = options.capture
|
|
57
|
+
const stdio = options.capture
|
|
58
|
+
? ['pipe', options.stdoutFd ?? 'pipe', 'pipe']
|
|
59
|
+
: 'inherit';
|
|
39
60
|
const child = spawn('node', [fullPath, ...args], {
|
|
40
61
|
stdio,
|
|
41
62
|
cwd: options.cwd || process.cwd(),
|
|
@@ -122,6 +143,56 @@ export class DefaultScriptRunner {
|
|
|
122
143
|
});
|
|
123
144
|
});
|
|
124
145
|
}
|
|
146
|
+
async runDeployment(fullPath, args, options) {
|
|
147
|
+
const previousConsole = globalThis.console;
|
|
148
|
+
const previousRoot = process.env.AIWG_ROOT;
|
|
149
|
+
const stderrLimit = 1024 * 1024;
|
|
150
|
+
const diagnostics = [];
|
|
151
|
+
let diagnosticBytes = 0;
|
|
152
|
+
try {
|
|
153
|
+
if (options.env?.AIWG_ROOT !== undefined)
|
|
154
|
+
process.env.AIWG_ROOT = options.env.AIWG_ROOT;
|
|
155
|
+
if (options.capture) {
|
|
156
|
+
const stdout = new Writable({ write(chunk, _encoding, done) {
|
|
157
|
+
try {
|
|
158
|
+
if (options.stdoutFd !== undefined)
|
|
159
|
+
writeSync(options.stdoutFd, chunk);
|
|
160
|
+
done();
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
done(error);
|
|
164
|
+
}
|
|
165
|
+
} });
|
|
166
|
+
const stderr = new Writable({ write(chunk, _encoding, done) {
|
|
167
|
+
const retained = chunk.subarray(0, stderrLimit - diagnosticBytes);
|
|
168
|
+
if (retained.length) {
|
|
169
|
+
diagnostics.push(Buffer.from(retained));
|
|
170
|
+
diagnosticBytes += retained.length;
|
|
171
|
+
}
|
|
172
|
+
done();
|
|
173
|
+
} });
|
|
174
|
+
globalThis.console = new Console({ stdout, stderr });
|
|
175
|
+
}
|
|
176
|
+
// Runtime loading follows the provider preparation coordinator precedent;
|
|
177
|
+
// the runner still supports arbitrary scripts via its subprocess path.
|
|
178
|
+
const deployer = await import(pathToFileURL(fullPath).href);
|
|
179
|
+
const exitCode = (await deployer.main(args, { capture: options.capture === true })) ?? 0;
|
|
180
|
+
const message = Buffer.concat(diagnostics).toString().trim();
|
|
181
|
+
return exitCode && message ? { exitCode, message } : { exitCode };
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
const message = Buffer.concat(diagnostics).toString().trim()
|
|
185
|
+
|| (error instanceof Error ? error.message : String(error));
|
|
186
|
+
return { exitCode: 1, message };
|
|
187
|
+
}
|
|
188
|
+
finally {
|
|
189
|
+
globalThis.console = previousConsole;
|
|
190
|
+
if (previousRoot === undefined)
|
|
191
|
+
delete process.env.AIWG_ROOT;
|
|
192
|
+
else
|
|
193
|
+
process.env.AIWG_ROOT = previousRoot;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
125
196
|
}
|
|
126
197
|
/**
|
|
127
198
|
* Create a script runner for the given framework root
|
|
@@ -735,9 +735,11 @@ export async function startServer(opts) {
|
|
|
735
735
|
if (!valid) {
|
|
736
736
|
return c.json({ error: `Invalid register payload: ${errors}` }, 400);
|
|
737
737
|
}
|
|
738
|
-
const
|
|
739
|
-
|
|
740
|
-
|
|
738
|
+
const authHeader = c.req.header('authorization') ?? '';
|
|
739
|
+
const token = authHeader.startsWith('Bearer ') ? authHeader.slice(7) : '';
|
|
740
|
+
const result = executorRegistry.register(body, token);
|
|
741
|
+
if ('status' in result) {
|
|
742
|
+
return c.json({ error: result.error }, result.status);
|
|
741
743
|
}
|
|
742
744
|
// Emit telemetry (reuse agent.spawn as closest match for executor registration)
|
|
743
745
|
const resp = result;
|
|
@@ -2,6 +2,7 @@ import { existsSync, linkSync, mkdirSync, readFileSync, realpathSync, renameSync
|
|
|
2
2
|
import { randomUUID } from 'node:crypto';
|
|
3
3
|
import { basename, dirname, isAbsolute, join, resolve, } from 'node:path';
|
|
4
4
|
import { pathToFileURL } from 'node:url';
|
|
5
|
+
import { providerScopeWarnings } from '../../sessions/coverage-preflight.js';
|
|
5
6
|
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
7
|
import { resolveImportExclusions } from '../../sessions/import-exclusions.js';
|
|
7
8
|
import { resolveImportLimits } from '../../sessions/import-limits.js';
|
|
@@ -58,7 +59,7 @@ Commands:
|
|
|
58
59
|
audit --workspace <id> Read content-free mutation events
|
|
59
60
|
analytics <view> --workspace <id> Summary, tool-calls, escalations, or HITL
|
|
60
61
|
forensics <view> --workspace <id> Authorized timeline, indicators, or evidence
|
|
61
|
-
doctor Check catalog
|
|
62
|
+
doctor Check catalog integrity and configured provider scope
|
|
62
63
|
|
|
63
64
|
Options:
|
|
64
65
|
--json Emit the versioned JSON contract
|
|
@@ -70,10 +71,12 @@ Options:
|
|
|
70
71
|
Catalog defaults to <project-or-cwd>/.aiwg/sessions/catalog.sqlite
|
|
71
72
|
Imports for other workspaces stay in the selected catalog;
|
|
72
73
|
use --db to read that catalog from another directory
|
|
73
|
-
--expected-providers <ids>
|
|
74
|
+
--expected-providers <ids> Explicit scope for this invocation; refresh re-reads workspace config
|
|
75
|
+
--carry-forward <catalog> Rebuild from sources plus re-redacted stored history (import-discovered)
|
|
74
76
|
--manifest <path> Override the discovery manifest path
|
|
75
77
|
--provider-home <path> Override the provider home root (testing/portable homes)
|
|
76
78
|
--codex-root <path> Authorize a shared Codex sessions/export root (repeatable)
|
|
79
|
+
Adds to defaults separately authorized by --provider-home
|
|
77
80
|
--omp-root <path> Explicitly authorize an OMP profile sessions root
|
|
78
81
|
--muse-root <path> Explicitly authorize a Muse Code sessions root
|
|
79
82
|
--dsh-root <path> Explicitly authorize a DeepSeek Harness sessions root
|
|
@@ -725,12 +728,22 @@ async function executeCommand(ctx, args) {
|
|
|
725
728
|
providerLogsModified: false,
|
|
726
729
|
});
|
|
727
730
|
}
|
|
728
|
-
case 'doctor':
|
|
731
|
+
case 'doctor': {
|
|
732
|
+
const workspacePath = resolve(ctx.cwd, args.values.get('--workspace') ?? ctx.cwd);
|
|
733
|
+
const workspace = existsSync(workspacePath) ? realpathSync(workspacePath) : workspacePath;
|
|
734
|
+
const config = await readAiwgConfig(workspace);
|
|
735
|
+
const manifestPath = resolve(ctx.cwd, args.values.get('--manifest') ?? defaultDiscoveryManifestPath(workspace));
|
|
736
|
+
const preflight = existsSync(manifestPath)
|
|
737
|
+
? (await readDiscoveryManifest(manifestPath)).preflight
|
|
738
|
+
: repository.getCoverage(workspace).preflight;
|
|
739
|
+
const warnings = providerScopeWarnings(config?.providers ?? [], preflight?.expectedProviders ?? [], preflight?.scopeWarnings);
|
|
729
740
|
return ok(command, {
|
|
730
741
|
database: redactSourceLocator(databasePath(ctx, args)),
|
|
731
742
|
health: repository.doctor(),
|
|
743
|
+
warnings,
|
|
732
744
|
jsonContractVersion: JSON_CONTRACT_VERSION,
|
|
733
745
|
});
|
|
746
|
+
}
|
|
734
747
|
default:
|
|
735
748
|
throw new CliError('UNKNOWN_COMMAND', `unknown sessions command: ${command}`, EXIT.usage);
|
|
736
749
|
}
|
|
@@ -1283,6 +1296,7 @@ async function discoverWorkspace(ctx, args) {
|
|
|
1283
1296
|
],
|
|
1284
1297
|
});
|
|
1285
1298
|
const data = {
|
|
1299
|
+
warnings: manifest.preflight?.scopeWarnings ?? [],
|
|
1286
1300
|
manifest: publicDiscoveryManifest(manifest),
|
|
1287
1301
|
manifestPath: redactSourceLocator(manifestPath),
|
|
1288
1302
|
exactManifestRequiredForImport: true,
|
|
@@ -1304,7 +1318,20 @@ async function importDiscovered(ctx, args) {
|
|
|
1304
1318
|
if (manifest.workspaceId !== canonicalWorkspace) {
|
|
1305
1319
|
throw new CliError('MANIFEST_WORKSPACE_MISMATCH', 'discovery manifest does not belong to the explicitly authorized workspace', EXIT.contract);
|
|
1306
1320
|
}
|
|
1321
|
+
const carryPath = args.values.has('--carry-forward')
|
|
1322
|
+
? resolve(ctx.cwd, args.values.get('--carry-forward')) : undefined;
|
|
1323
|
+
if (carryPath) {
|
|
1324
|
+
const sourceStat = statSync(carryPath);
|
|
1325
|
+
const target = databasePath(ctx, args);
|
|
1326
|
+
if (existsSync(target)) {
|
|
1327
|
+
const targetStat = statSync(target);
|
|
1328
|
+
if (sourceStat.dev === targetStat.dev && sourceStat.ino === targetStat.ino) {
|
|
1329
|
+
throw new CliError('INVALID_ARGUMENT', 'carry-forward requires a separate destination catalog', EXIT.usage);
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1307
1333
|
const expected = requestedProviders(args);
|
|
1334
|
+
const warnings = providerScopeWarnings(config?.providers ?? [], manifest.preflight?.expectedProviders ?? [], manifest.preflight?.scopeWarnings);
|
|
1308
1335
|
if (expected && JSON.stringify(expected) !== JSON.stringify(manifest.preflight?.expectedProviders)) {
|
|
1309
1336
|
throw new SessionContractError('INVALID_ARGUMENT', 'expected provider scope differs from the saved manifest; rediscover with --expected-providers');
|
|
1310
1337
|
}
|
|
@@ -1320,22 +1347,27 @@ async function importDiscovered(ctx, args) {
|
|
|
1320
1347
|
// A preview can still describe the exact manifest before a catalog exists.
|
|
1321
1348
|
}
|
|
1322
1349
|
return preview('import-discovered', {
|
|
1350
|
+
warnings,
|
|
1323
1351
|
manifest: publicDiscoveryManifest(manifest),
|
|
1324
1352
|
receipt: previewDiscoveryImport(manifest, existing, new Date(), exclude),
|
|
1325
1353
|
confirmationRequired: !isDryRun(ctx, args),
|
|
1326
1354
|
wouldPersist: false,
|
|
1355
|
+
...(carryPath ? { carryForward: redactSourceLocator(carryPath) } : {}),
|
|
1327
1356
|
});
|
|
1328
1357
|
}
|
|
1329
1358
|
const lease = await acquireImportLease(databasePath(ctx, args), sha256(['discovered-import', manifest.manifestId, manifest.workspaceId].join('\0')), {
|
|
1330
1359
|
waitMs: boundedInteger(args.values.get('--lock-wait-ms'), 5_000, 0, 300_000, '--lock-wait-ms'),
|
|
1331
1360
|
});
|
|
1332
1361
|
try {
|
|
1333
|
-
const
|
|
1362
|
+
const previous = carryPath ? new SessionRepository(carryPath, { readonly: true }) : undefined;
|
|
1363
|
+
let repository;
|
|
1334
1364
|
try {
|
|
1365
|
+
repository = openRepository(ctx, args);
|
|
1335
1366
|
const interruptedRuns = repository.interruptRunningBatchImports();
|
|
1336
1367
|
const receipt = await importDiscoveryManifest({
|
|
1337
1368
|
manifest,
|
|
1338
1369
|
repository,
|
|
1370
|
+
carryForward: previous,
|
|
1339
1371
|
limits,
|
|
1340
1372
|
exclude,
|
|
1341
1373
|
signal: ctx.signal,
|
|
@@ -1343,6 +1375,7 @@ async function importDiscovered(ctx, args) {
|
|
|
1343
1375
|
});
|
|
1344
1376
|
receipt.interruptedRuns = interruptedRuns;
|
|
1345
1377
|
return ok('import-discovered', {
|
|
1378
|
+
warnings,
|
|
1346
1379
|
manifestId: manifest.manifestId,
|
|
1347
1380
|
receipt,
|
|
1348
1381
|
resumable: receipt.run.status !== 'complete',
|
|
@@ -1354,7 +1387,8 @@ async function importDiscovered(ctx, args) {
|
|
|
1354
1387
|
});
|
|
1355
1388
|
}
|
|
1356
1389
|
finally {
|
|
1357
|
-
repository
|
|
1390
|
+
repository?.close();
|
|
1391
|
+
previous?.close();
|
|
1358
1392
|
}
|
|
1359
1393
|
}
|
|
1360
1394
|
finally {
|
|
@@ -1710,7 +1744,7 @@ function parseArgs(argv) {
|
|
|
1710
1744
|
'--entity', '--sensitivity', '--extraction-state', '--page-size', '--max-documents',
|
|
1711
1745
|
'--state', '--reviewer', '--reason', '--policy-version', '--min-confidence',
|
|
1712
1746
|
'--consumer', '--actor-class', '--reason-code', '--dependent-action', '--basis',
|
|
1713
|
-
'--manifest', '--provider-home', '--codex-root', '--omp-root', '--muse-root', '--dsh-root', '--grokbot-root', '--lock-wait-ms', '--min-coverage', '--gap',
|
|
1747
|
+
'--carry-forward', '--manifest', '--provider-home', '--codex-root', '--omp-root', '--muse-root', '--dsh-root', '--grokbot-root', '--lock-wait-ms', '--min-coverage', '--gap',
|
|
1714
1748
|
'--inactivity-threshold', '--expected-providers', '--exclude', '--max-record-bytes', '--max-source-bytes',
|
|
1715
1749
|
'--control-events',
|
|
1716
1750
|
'--session', '--status', '--actor', '--group-by',
|