@aiwg/cli 2026.10.1 → 2026.10.3
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/providers/capability-matrix.yaml +270 -0
- package/agentic/code/providers/model-capabilities.v1.json +3091 -24
- package/bin/aiwg.mjs +86 -21
- package/dist/src/a2a/codecs.js +9 -0
- package/dist/src/artifacts/corpus-tools/vision-extract.js +105 -15
- package/dist/src/artifacts/repair.js +9 -4
- package/dist/src/channel/manager.mjs +59 -10
- package/dist/src/cli/child-process-result.js +40 -0
- package/dist/src/cli/env.js +38 -16
- package/dist/src/cli/flag-parsing.js +236 -0
- package/dist/src/cli/handlers/decision.js +210 -4
- package/dist/src/cli/handlers/diagnose.js +9 -2
- package/dist/src/cli/handlers/feedback.js +14 -5
- package/dist/src/cli/handlers/init.js +245 -30
- package/dist/src/cli/handlers/mc.js +23 -0
- package/dist/src/cli/handlers/models.js +69 -6
- package/dist/src/cli/handlers/ralph.js +3 -0
- package/dist/src/cli/handlers/refresh.js +16 -0
- package/dist/src/cli/handlers/regenerate.js +14 -0
- package/dist/src/cli/handlers/runtime-info.js +24 -9
- package/dist/src/cli/handlers/script-runner.js +16 -6
- package/dist/src/cli/handlers/session.js +396 -62
- package/dist/src/cli/handlers/sessions.js +146 -40
- package/dist/src/cli/handlers/setup-manifest.js +439 -39
- package/dist/src/cli/handlers/setup.js +139 -39
- package/dist/src/cli/handlers/subcommands.js +3 -1
- package/dist/src/cli/handlers/team.js +18 -8
- package/dist/src/cli/handlers/use.js +13 -0
- package/dist/src/cli/handlers/utilities.js +106 -23
- package/dist/src/cli/prompt-utils.js +72 -0
- package/dist/src/cli/provider-resolution.js +11 -0
- package/dist/src/config/aiwg-config.js +268 -4
- package/dist/src/config/cli.js +146 -19
- package/dist/src/config/dispatch-thresholds-runtime.mjs +38 -0
- package/dist/src/config/project-artifacts-health.mjs +14 -3
- package/dist/src/config/user-config.js +36 -10
- package/dist/src/decision/adapters/jev.js +75 -27
- package/dist/src/decision/driver.js +3 -1
- package/dist/src/decision/entry.js +38 -6
- package/dist/src/decision/heldout/collector.js +10 -1
- package/dist/src/decision/index.js +1 -0
- package/dist/src/decision/interop.js +60 -8
- package/dist/src/decision/ledger.js +839 -0
- package/dist/src/decision/validate.js +6 -3
- package/dist/src/effects/dispatch-verifier.js +252 -0
- package/dist/src/effects/index.js +1 -0
- package/dist/src/features/installer.js +2 -2
- package/dist/src/flow/graph-metadata.js +5 -0
- package/dist/src/gates/providers/loader.js +3 -1
- package/dist/src/installation/manager-command.mjs +1 -1
- package/dist/src/installation/manager.mjs +17 -2
- package/dist/src/lint/runner.js +2 -2
- package/dist/src/mcp/adapters/codex-runtime.js +360 -56
- package/dist/src/mcp/cli.mjs +587 -77
- package/dist/src/mcp/config-file.mjs +279 -0
- package/dist/src/mcp/config-layers.mjs +348 -0
- package/dist/src/mcp/credentials.mjs +484 -0
- package/dist/src/mcp/grok-build-config.mjs +16 -26
- package/dist/src/mcp/helpers.mjs +106 -2
- package/dist/src/mcp/omp-config.mjs +50 -29
- package/dist/src/mcp/profiles.js +97 -23
- package/dist/src/mcp/profiles.mjs +99 -27
- package/dist/src/mcp/registry.js +264 -57
- package/dist/src/mcp/registry.mjs +198 -45
- package/dist/src/mcp/server.mjs +403 -20
- package/dist/src/mcp/toml-string.mjs +9 -0
- package/dist/src/mcp/toml-strip-mcp.mjs +135 -0
- package/dist/src/mcp/tool-filters.mjs +357 -0
- package/dist/src/mcp/tools/agentic-sandbox.mjs +3 -1
- package/dist/src/mcp/tools/decision.mjs +21 -3
- package/dist/src/mcp/tools/orchestration.mjs +38 -0
- package/dist/src/mcp/tools/subsystems.mjs +39 -8
- package/dist/src/mcp/tools/worker-invoke.mjs +1539 -0
- package/dist/src/mcp/tools/worker-shell-control.mjs +258 -0
- package/dist/src/mcp/tools/worker-stdin-runtime.mjs +79 -0
- package/dist/src/memory/project-registry.js +2 -2
- package/dist/src/mission-protocol/codecs.js +639 -1
- package/dist/src/mission-protocol/types.js +110 -0
- package/dist/src/mission-protocol/worker-status.js +2 -0
- package/dist/src/models/config-loader.js +70 -13
- package/dist/src/models/grok-build-models.js +93 -41
- package/dist/src/models/model-capabilities.v1.json +3091 -24
- package/dist/src/models/model-discovery.js +862 -63
- package/dist/src/models/provider-policy.js +625 -11
- package/dist/src/models/qualification-digest.mjs +17 -0
- package/dist/src/models/resolver.js +259 -0
- package/dist/src/models/worker-direct-readiness.js +529 -0
- package/dist/src/models/worker-dispatch-offer.js +169 -0
- package/dist/src/models/worker-health-readiness.js +131 -0
- package/dist/src/models/worker-installation.mjs +879 -0
- package/dist/src/models/wrapper-route.js +18 -0
- package/dist/src/ops/registry.js +9 -14
- package/dist/src/plugins/standalone-packager.js +4 -3
- package/dist/src/process/bounded-child-process.mjs +387 -0
- package/dist/src/process/cli-command.mjs +75 -0
- package/dist/src/providers/capability-matrix.js +8 -0
- package/dist/src/providers/capability-matrix.yaml +270 -0
- package/dist/src/providers/grok-build-headless.js +43 -21
- package/dist/src/providers/provider-definitions.js +9 -1
- package/dist/src/providers/provider-definitions.mjs +9 -2
- package/dist/src/serve/executor-registry.js +16 -24
- package/dist/src/serve/fleet-mission-conductor.js +9 -0
- package/dist/src/serve/mission-conductor.js +9 -0
- package/dist/src/serve/shared-host-scheduler.js +2 -0
- package/dist/src/serve/worker-invocation.js +538 -0
- package/dist/src/serve/worker-stdin-frame.mjs +107 -0
- package/dist/src/sessions/adapter-registry.js +45 -0
- package/dist/src/sessions/adapters/generic.js +37 -3
- package/dist/src/sessions/adapters/grokbot-locator.js +111 -0
- package/dist/src/sessions/adapters/grokbot.js +423 -24
- package/dist/src/sessions/adapters/muse-workspace-scan.js +108 -0
- package/dist/src/sessions/adapters/muse.js +68 -29
- package/dist/src/sessions/adapters/pi.js +1 -0
- package/dist/src/sessions/batch-contracts.js +13 -1
- package/dist/src/sessions/batch-import.js +23 -42
- package/dist/src/sessions/candidates.js +47 -11
- package/dist/src/sessions/contracts.js +35 -0
- package/dist/src/sessions/coverage-preflight.js +134 -0
- package/dist/src/sessions/discovery.js +3 -0
- package/dist/src/sessions/grok-build-cli.js +67 -5
- package/dist/src/sessions/importer.js +24 -8
- package/dist/src/sessions/index.js +2 -0
- package/dist/src/sessions/repository.js +54 -13
- package/dist/src/sessions/workspace-discovery.js +99 -37
- package/dist/src/skills/adapters/clawhub.js +10 -8
- package/dist/src/skills/adapters/openclaw.js +10 -7
- package/dist/src/smiths/context-pipeline/parallelism-section.js +192 -3
- package/dist/src/smiths/context-pipeline/workspace-context.js +116 -9
- package/dist/src/smiths/hook-bridge/codex-translator.js +6 -5
- package/dist/src/smiths/mcpsmith/example.js +1 -1
- package/dist/src/smiths/toolsmith/runtime-discovery.mjs +10 -14
- package/dist/src/storage/backends/logseq.js +68 -7
- package/dist/src/storage/fortemi-qualification-receipt.js +2 -2
- package/dist/src/testing/generators/test-code-generator.js +57 -30
- package/dist/src/uhp/client.js +11 -1
- package/dist/src/uhp/mission.js +5 -0
- package/dist/src/update/checker.mjs +5 -5
- package/dist/src/update/notifier.mjs +54 -2
- package/dist/src/writing/fidelity.js +18 -1
- package/package.json +18 -1
- package/schemas/mission-v1.schema.json +2429 -0
- package/schemas/models/model-catalog.v1.schema.json +301 -0
- package/schemas/models/model-config-compatibility.v1.schema.json +281 -0
- package/schemas/models/model-policy.v1.schema.json +14 -0
- package/schemas/models/provider-model-capabilities.v1.schema.json +1066 -0
- package/tools/_resolve-impl.mjs +39 -0
- package/tools/agents/deploy-agents.mjs +15 -2
- package/tools/agents/providers/base.mjs +49 -32
- package/tools/agents/providers/grokbot.mjs +11 -12
- package/tools/agents/providers/hermes.mjs +6 -3
- package/tools/agents/providers/omp.mjs +5 -2
- package/tools/agents/providers/openclaw-translator.mjs +19 -5
- package/tools/providers/deepseek-harness-transport.mjs +358 -0
- package/tools/providers/omp-transport.mjs +192 -0
- package/tools/ralph-external/lib/claude-adapter.mjs +389 -0
- package/tools/ralph-external/lib/codex-adapter.mjs +432 -0
- package/tools/ralph-external/lib/deepseek-harness-adapter.mjs +397 -0
- package/tools/ralph-external/lib/factory-adapter.mjs +503 -0
- package/tools/ralph-external/lib/muse-adapter.mjs +364 -0
- package/tools/ralph-external/lib/omp-adapter.mjs +315 -0
- package/tools/ralph-external/lib/opencode-adapter.mjs +575 -0
- package/tools/ralph-external/lib/openhuman-adapter.mjs +75 -0
- package/tools/ralph-external/lib/pi-adapter.mjs +333 -0
- package/tools/ralph-external/lib/provider-adapter.mjs +690 -0
- package/tools/ralph-external/lib/worker-health.mjs +439 -0
- package/vscode-extension/schemas/aiwg.config.v1.json +1953 -0
|
@@ -42,8 +42,9 @@
|
|
|
42
42
|
import { opendir } from 'node:fs/promises';
|
|
43
43
|
import { resolve } from 'node:path';
|
|
44
44
|
import { z } from 'zod';
|
|
45
|
-
import { SessionContractError, assertSupportedSchemaMajor, } from '../contracts.js';
|
|
45
|
+
import { SessionContractError, SessionErrorCodeSchema, assertSupportedSchemaMajor, } from '../contracts.js';
|
|
46
46
|
import { readBoundedJson, readBoundedJsonLines, } from '../readers.js';
|
|
47
|
+
import { MUSE_WORKSPACE_SCAN_LIMITS, museWorkspaceScanLines, parseMuseScanJson, } from './muse-workspace-scan.js';
|
|
47
48
|
export const MUSE_ADAPTER_VERSION = '1.0.0';
|
|
48
49
|
export const MUSE_EXPORT_SCHEMA_VERSION = '1.0.0';
|
|
49
50
|
export const MUSE_EXPORT_SCHEMA_MAJOR = 1;
|
|
@@ -79,7 +80,9 @@ const MuseEnvelopeSchema = z.object({
|
|
|
79
80
|
durability: z.string().optional(),
|
|
80
81
|
payload_type: z.string().optional(),
|
|
81
82
|
payload: z.object({
|
|
82
|
-
|
|
83
|
+
// Muse Code 1.4.3 runtime.session mode records carry an event without a
|
|
84
|
+
// kind; eventKindOf() falls back to payload_type for those.
|
|
85
|
+
event: z.object({ kind: z.string().min(1).optional() }).passthrough().optional(),
|
|
83
86
|
}).passthrough().optional(),
|
|
84
87
|
}).passthrough();
|
|
85
88
|
/**
|
|
@@ -495,44 +498,80 @@ async function* museNativeSessionLogs(root) {
|
|
|
495
498
|
}
|
|
496
499
|
}
|
|
497
500
|
}
|
|
498
|
-
export
|
|
499
|
-
|
|
501
|
+
export const MuseWorkspaceInspectionSchema = z.object({
|
|
502
|
+
outcome: z.enum(['matched', 'mismatch', 'inconclusive']),
|
|
503
|
+
reasonCode: z.string().nullable(),
|
|
504
|
+
recordsInspected: z.number().int().nonnegative(),
|
|
505
|
+
bytesInspected: z.number().int().nonnegative(),
|
|
506
|
+
completeInspection: z.boolean(),
|
|
507
|
+
});
|
|
508
|
+
/** Positive metadata evidence selects a source; import validates its full history. */
|
|
509
|
+
export async function inspectMuseNativeWorkspace(source, workspacePath, limitsInput) {
|
|
510
|
+
const limits = { ...MUSE_WORKSPACE_SCAN_LIMITS, ...limitsInput };
|
|
511
|
+
const progress = { recordsInspected: 0, bytesInspected: 0 };
|
|
512
|
+
let sawWorkspaceEvidence = false;
|
|
513
|
+
let retainedChildren = 0;
|
|
514
|
+
const receipt = (outcome, reasonCode, completeInspection = false) => ({ outcome, reasonCode, ...progress, completeInspection });
|
|
500
515
|
try {
|
|
501
|
-
|
|
516
|
+
if (Object.values(limits).some((limit) => !Number.isSafeInteger(limit) || limit <= 0)) {
|
|
517
|
+
throw new SessionContractError('INVALID_ARGUMENT', 'Muse inspection limits must be positive safe integers');
|
|
518
|
+
}
|
|
519
|
+
for await (const value of museWorkspaceScanLines({ selectedPath: source.locator, allowedRoots: source.authorizedScope.allowedRoots }, limits, progress)) {
|
|
520
|
+
const envelopes = nativeEnvelopesFromLine(value, limits, (count) => {
|
|
521
|
+
retainedChildren += count;
|
|
522
|
+
if (retainedChildren > limits.maxRecords) {
|
|
523
|
+
throw new SessionContractError('RESOURCE_LIMIT_EXCEEDED', 'Muse retained child inspection limit exceeded');
|
|
524
|
+
}
|
|
525
|
+
});
|
|
526
|
+
for (const envelope of envelopes) {
|
|
527
|
+
const candidate = workspaceEvidenceOf(envelope);
|
|
528
|
+
if (!candidate)
|
|
529
|
+
continue;
|
|
530
|
+
sawWorkspaceEvidence = true;
|
|
531
|
+
if (workspacePathEquals(candidate, workspacePath))
|
|
532
|
+
return receipt('matched', null);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
return sawWorkspaceEvidence
|
|
536
|
+
? receipt('mismatch', 'MUSE_WORKSPACE_MISMATCH', true)
|
|
537
|
+
: receipt('inconclusive', 'MUSE_WORKSPACE_EVIDENCE_ABSENT', true);
|
|
502
538
|
}
|
|
503
|
-
catch {
|
|
504
|
-
return
|
|
539
|
+
catch (error) {
|
|
540
|
+
return receipt('inconclusive', error instanceof SessionContractError
|
|
541
|
+
? error.code : 'MUSE_SOURCE_UNREADABLE');
|
|
505
542
|
}
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
return true;
|
|
513
|
-
}
|
|
543
|
+
}
|
|
544
|
+
export async function museNativeSourceMatchesWorkspace(source, workspacePath) {
|
|
545
|
+
const result = await inspectMuseNativeWorkspace(source, workspacePath);
|
|
546
|
+
if (result.outcome === 'inconclusive') {
|
|
547
|
+
const code = SessionErrorCodeSchema.safeParse(result.reasonCode);
|
|
548
|
+
throw new SessionContractError(code.success ? code.data : 'SCHEMA_DRIFT', `Muse workspace inspection inconclusive: ${result.reasonCode}`);
|
|
514
549
|
}
|
|
515
|
-
return
|
|
550
|
+
return result.outcome === 'matched';
|
|
516
551
|
}
|
|
517
|
-
function nativeEnvelopesFromLine(value) {
|
|
552
|
+
function nativeEnvelopesFromLine(value, limits, countChildren) {
|
|
518
553
|
if (isOmissionMarker(value))
|
|
519
554
|
return [];
|
|
520
|
-
const event = recordEventFromEnvelope(value);
|
|
521
|
-
if (event)
|
|
522
|
-
return [event.envelope];
|
|
523
555
|
const retained = MuseRetainedFrameSchema.safeParse(value);
|
|
524
|
-
if (!retained.success)
|
|
525
|
-
|
|
556
|
+
if (!retained.success) {
|
|
557
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value)) {
|
|
558
|
+
throw new SessionContractError('MALFORMED_SOURCE', 'Muse inspection encountered a non-object native record');
|
|
559
|
+
}
|
|
560
|
+
// Native logs carry record kinds the envelope schema does not model (for
|
|
561
|
+
// example runtime.session mode changes without payload.event.kind). They
|
|
562
|
+
// hold no workspace evidence, so skip them rather than fail the source.
|
|
563
|
+
const event = recordEventFromEnvelope(value);
|
|
564
|
+
return event ? [event.envelope] : [];
|
|
565
|
+
}
|
|
566
|
+
countChildren(retained.data.children.length);
|
|
526
567
|
const envelopes = [];
|
|
527
568
|
for (const child of retained.data.children) {
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
if (childEvent)
|
|
531
|
-
envelopes.push(childEvent.envelope);
|
|
532
|
-
}
|
|
533
|
-
catch {
|
|
534
|
-
return [];
|
|
569
|
+
if (Buffer.byteLength(child.record_json) > limits.maxRecordBytes) {
|
|
570
|
+
throw new SessionContractError('RESOURCE_LIMIT_EXCEEDED', 'Muse retained child inspection byte limit exceeded');
|
|
535
571
|
}
|
|
572
|
+
const childEvent = recordEventFromEnvelope(parseMuseScanJson(child.record_json, limits.maxNestingDepth));
|
|
573
|
+
if (childEvent)
|
|
574
|
+
envelopes.push(childEvent.envelope);
|
|
536
575
|
}
|
|
537
576
|
return envelopes;
|
|
538
577
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { reconcileCoveragePreflight } from './coverage-preflight.js';
|
|
1
2
|
export const BATCH_IMPORT_VERSION = '1.0.0';
|
|
2
3
|
export const COVERAGE_VERSION = '1.0.0';
|
|
3
4
|
export function coverageFromBatchRun(run, now = new Date(), staleAfterMs = 24 * 60 * 60 * 1_000) {
|
|
@@ -18,7 +19,10 @@ export function coverageFromBatchRun(run, now = new Date(), staleAfterMs = 24 *
|
|
|
18
19
|
const notChecked = providerNames(run, 'not-checked');
|
|
19
20
|
const manifestAgeMs = Math.max(0, now.getTime() - Date.parse(run.manifestCreatedAt));
|
|
20
21
|
const isStale = manifestAgeMs > staleAfterMs;
|
|
21
|
-
const
|
|
22
|
+
const preflight = run.preflight ? reconcileCoveragePreflight(run.preflight, run.sources) : undefined;
|
|
23
|
+
const incomplete = !preflight || preflight.status !== 'complete'
|
|
24
|
+
|| unavailable.length > 0 || accepted + duplicated + previouslyCommitted === 0
|
|
25
|
+
|| rejected > 0 || pending > 0 || skipped > 0
|
|
22
26
|
|| exportRequired.length > 0 || notChecked.length > 0;
|
|
23
27
|
const rejectionCounts = {};
|
|
24
28
|
for (const source of run.sources) {
|
|
@@ -36,6 +40,9 @@ export function coverageFromBatchRun(run, now = new Date(), staleAfterMs = 24 *
|
|
|
36
40
|
.map((source) => source.updatedAt)
|
|
37
41
|
.sort();
|
|
38
42
|
const remediation = [
|
|
43
|
+
...(preflight?.ledger.flatMap((entry) => entry.remediation ? [entry.remediation] : []) ?? ['Legacy receipt lacks provider/runtime preflight; rediscover with --expected-providers.']),
|
|
44
|
+
...(preflight && ['mismatch', 'stale', 'unknown'].includes(preflight.runtime.installationState)
|
|
45
|
+
? ['Inspect the recorded runtime identity and deliberately select a compatible installation; then rediscover. No automatic switch is performed.'] : []),
|
|
39
46
|
...(rejected > 0
|
|
40
47
|
? ['Run `aiwg sessions import-discovered --resume --confirm` after correcting rejected sources.']
|
|
41
48
|
: []),
|
|
@@ -47,6 +54,9 @@ export function coverageFromBatchRun(run, now = new Date(), staleAfterMs = 24 *
|
|
|
47
54
|
return {
|
|
48
55
|
schemaVersion: COVERAGE_VERSION,
|
|
49
56
|
status: isStale ? 'stale' : incomplete ? 'partial' : 'complete',
|
|
57
|
+
acquisitionStatus: incomplete ? 'partial' : 'complete',
|
|
58
|
+
preflight,
|
|
59
|
+
semanticReview: 'not-assessed',
|
|
50
60
|
workspaceId: run.workspaceId,
|
|
51
61
|
manifestId: run.manifestId,
|
|
52
62
|
batchRunId: run.runId,
|
|
@@ -89,6 +99,8 @@ function unknownCoverage() {
|
|
|
89
99
|
return {
|
|
90
100
|
schemaVersion: COVERAGE_VERSION,
|
|
91
101
|
status: 'unknown',
|
|
102
|
+
acquisitionStatus: 'unknown',
|
|
103
|
+
semanticReview: 'not-assessed',
|
|
92
104
|
workspaceId: '',
|
|
93
105
|
manifestId: null,
|
|
94
106
|
batchRunId: null,
|
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
import { OmpSessionAdapter, OMP_ADAPTER_VERSION } from './adapters/omp.js';
|
|
2
|
-
import { DeepSeekHarnessSessionAdapter, DEEPSEEK_HARNESS_ADAPTER_VERSION } from './adapters/deepseek-harness.js';
|
|
3
1
|
import { stat } from 'node:fs/promises';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { CURSOR_ADAPTER_VERSION, CursorSessionAdapter, } from './adapters/cursor.js';
|
|
7
|
-
import { FACTORY_ADAPTER_VERSION, FactorySessionAdapter, } from './adapters/factory.js';
|
|
8
|
-
import { MUSE_ADAPTER_VERSION, MuseSessionAdapter, } from './adapters/muse.js';
|
|
2
|
+
import { createSessionAdapterRegistry } from './adapter-registry.js';
|
|
3
|
+
import { coveragePreflight, sessionRuntimeIdentity } from './coverage-preflight.js';
|
|
9
4
|
import { SESSION_CONTRACT_VERSION, SessionContractError, SessionSourceSchema, sha256, } from './contracts.js';
|
|
10
5
|
import { BATCH_IMPORT_VERSION, coverageFromBatchRun, } from './batch-contracts.js';
|
|
11
6
|
import { IncrementalSessionImporter, SessionImportFailure } from './importer.js';
|
|
@@ -22,6 +17,12 @@ export async function importDiscoveryManifest(options) {
|
|
|
22
17
|
if (run.runId !== runId) {
|
|
23
18
|
throw new SessionContractError('IMPORT_CONFLICT', 'discovery manifest is already associated with a different batch run');
|
|
24
19
|
}
|
|
20
|
+
run.preflight = coveragePreflight({
|
|
21
|
+
expectedProviders: options.manifest.preflight?.expectedProviders,
|
|
22
|
+
expectedProviderBasis: options.manifest.preflight?.expectedProviderBasis ?? 'legacy',
|
|
23
|
+
runtime: options.runtime ?? sessionRuntimeIdentity(),
|
|
24
|
+
reports: options.manifest.providers,
|
|
25
|
+
});
|
|
25
26
|
run.status = 'running';
|
|
26
27
|
run.updatedAt = now().toISOString();
|
|
27
28
|
run.completedAt = null;
|
|
@@ -100,7 +101,7 @@ export async function importDiscoveryManifest(options) {
|
|
|
100
101
|
}
|
|
101
102
|
const rejected = run.sources.some((source) => source.status === 'rejected');
|
|
102
103
|
const pending = run.sources.some((source) => source.status === 'pending' || source.status === 'running');
|
|
103
|
-
const providerGap = run
|
|
104
|
+
const providerGap = coverageFromBatchRun(run, now()).acquisitionStatus !== 'complete';
|
|
104
105
|
const publishable = run.sources
|
|
105
106
|
.filter((source) => isAccepted(source.status))
|
|
106
107
|
.map((source) => source.sourceId);
|
|
@@ -129,7 +130,14 @@ function injectFault(options, run, boundary, sourceId) {
|
|
|
129
130
|
}
|
|
130
131
|
export function previewDiscoveryImport(manifest, existing, now = new Date()) {
|
|
131
132
|
const run = existing ?? newBatchRun(manifest, sha256(['workspace-import-v1', manifest.manifestId, manifest.workspaceId].join('\0')), now);
|
|
132
|
-
return receiptFor(
|
|
133
|
+
return receiptFor({
|
|
134
|
+
...run,
|
|
135
|
+
preflight: coveragePreflight({
|
|
136
|
+
expectedProviders: manifest.preflight?.expectedProviders,
|
|
137
|
+
expectedProviderBasis: manifest.preflight?.expectedProviderBasis ?? 'legacy',
|
|
138
|
+
reports: manifest.providers,
|
|
139
|
+
}),
|
|
140
|
+
}, now);
|
|
133
141
|
}
|
|
134
142
|
function newBatchRun(manifest, runId, now) {
|
|
135
143
|
const timestamp = now.toISOString();
|
|
@@ -143,6 +151,8 @@ function newBatchRun(manifest, runId, now) {
|
|
|
143
151
|
startedAt: timestamp,
|
|
144
152
|
updatedAt: timestamp,
|
|
145
153
|
completedAt: null,
|
|
154
|
+
preflight: manifest.preflight,
|
|
155
|
+
discoveryRuntime: manifest.preflight?.runtime,
|
|
146
156
|
providers: manifest.providers,
|
|
147
157
|
sources: manifest.sources.map((source) => ({
|
|
148
158
|
sourceId: source.sourceId,
|
|
@@ -200,21 +210,7 @@ async function assertManifestSourceUnchanged(source) {
|
|
|
200
210
|
}
|
|
201
211
|
}
|
|
202
212
|
function adapterFor(provider) {
|
|
203
|
-
|
|
204
|
-
return new DeepSeekHarnessSessionAdapter();
|
|
205
|
-
if (provider === 'omp')
|
|
206
|
-
return new OmpSessionAdapter();
|
|
207
|
-
if (provider === 'claude')
|
|
208
|
-
return new ClaudeSessionAdapter();
|
|
209
|
-
if (provider === 'codex')
|
|
210
|
-
return new CodexSessionAdapter();
|
|
211
|
-
if (provider === 'cursor')
|
|
212
|
-
return new CursorSessionAdapter();
|
|
213
|
-
if (provider === 'factory')
|
|
214
|
-
return new FactorySessionAdapter();
|
|
215
|
-
if (provider === 'muse')
|
|
216
|
-
return new MuseSessionAdapter();
|
|
217
|
-
throw new SessionContractError('UNSUPPORTED_OPERATION', `batch discovery import is not implemented for ${provider}`);
|
|
213
|
+
return createSessionAdapterRegistry().get(provider);
|
|
218
214
|
}
|
|
219
215
|
async function sessionSource(selected, adapter) {
|
|
220
216
|
const probe = await adapter.inspect(selected);
|
|
@@ -225,7 +221,7 @@ async function sessionSource(selected, adapter) {
|
|
|
225
221
|
providerProfile: providerProfile(selected.provider, selected.locatorClass),
|
|
226
222
|
locatorClass: selected.locatorClass,
|
|
227
223
|
redactedLocator: '<discovered-session-source>',
|
|
228
|
-
adapterVersion: adapterVersion
|
|
224
|
+
adapterVersion: adapter.adapterVersion,
|
|
229
225
|
sourceSchemaVersion: probe.sourceSchemaVersion,
|
|
230
226
|
disposition: 'implemented',
|
|
231
227
|
operationalState: probe.operationalState,
|
|
@@ -234,23 +230,6 @@ async function sessionSource(selected, adapter) {
|
|
|
234
230
|
extensions: { [`native.${selected.provider}`]: {} },
|
|
235
231
|
});
|
|
236
232
|
}
|
|
237
|
-
function adapterVersion(provider) {
|
|
238
|
-
if (provider === 'deepseek-harness')
|
|
239
|
-
return DEEPSEEK_HARNESS_ADAPTER_VERSION;
|
|
240
|
-
if (provider === 'omp')
|
|
241
|
-
return OMP_ADAPTER_VERSION;
|
|
242
|
-
if (provider === 'claude')
|
|
243
|
-
return CLAUDE_ADAPTER_VERSION;
|
|
244
|
-
if (provider === 'codex')
|
|
245
|
-
return CODEX_ADAPTER_VERSION;
|
|
246
|
-
if (provider === 'cursor')
|
|
247
|
-
return CURSOR_ADAPTER_VERSION;
|
|
248
|
-
if (provider === 'factory')
|
|
249
|
-
return FACTORY_ADAPTER_VERSION;
|
|
250
|
-
if (provider === 'muse')
|
|
251
|
-
return MUSE_ADAPTER_VERSION;
|
|
252
|
-
return '1.0.0';
|
|
253
|
-
}
|
|
254
233
|
function providerProfile(provider, locatorClass) {
|
|
255
234
|
if (provider === 'deepseek-harness')
|
|
256
235
|
return 'native-session-v2-jsonl';
|
|
@@ -269,6 +248,8 @@ function providerProfile(provider, locatorClass) {
|
|
|
269
248
|
return 'documented-project-jsonl';
|
|
270
249
|
if (provider === 'muse')
|
|
271
250
|
return 'muse-native-session-log-v1';
|
|
251
|
+
if (provider === 'grokbot')
|
|
252
|
+
return 'grokbot-native-transcript-replica-v1';
|
|
272
253
|
return 'manual-interchange';
|
|
273
254
|
}
|
|
274
255
|
function importErrorCode(error) {
|
|
@@ -103,17 +103,21 @@ export class StructuralCandidateExtractor {
|
|
|
103
103
|
const drafts = [];
|
|
104
104
|
for (const item of evidence) {
|
|
105
105
|
let offset = 0;
|
|
106
|
-
for (const
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
106
|
+
for (const rawLine of item.text.split(/\n/)) {
|
|
107
|
+
const line = rawLine.endsWith('\r') ? rawLine.slice(0, -1) : rawLine;
|
|
108
|
+
const separator = line.indexOf(':');
|
|
109
|
+
const label = line.slice(0, separator).normalize('NFKC').toLowerCase();
|
|
110
|
+
const remainder = line.slice(separator + 1);
|
|
111
|
+
const content = remainder.trimStart();
|
|
112
|
+
if (separator >= 0 && Object.hasOwn(STRUCTURAL_TYPES, label)
|
|
113
|
+
&& remainder.length > 0 && !/[\r\u2028\u2029]/u.test(content || remainder.slice(-1))) {
|
|
114
|
+
const assertion = content.trim();
|
|
115
|
+
const start = offset + separator + 1 + remainder.length - content.length;
|
|
112
116
|
const type = STRUCTURAL_TYPES[label];
|
|
113
117
|
const relationship = type === 'relationship'
|
|
114
118
|
? parseRelationship(assertion)
|
|
115
119
|
: { subject: null, predicate: null, object: null };
|
|
116
|
-
if (type && (type !== 'relationship' || relationship.subject)) {
|
|
120
|
+
if (type && assertion && (type !== 'relationship' || relationship.subject)) {
|
|
117
121
|
drafts.push({
|
|
118
122
|
type,
|
|
119
123
|
assertion,
|
|
@@ -125,7 +129,7 @@ export class StructuralCandidateExtractor {
|
|
|
125
129
|
});
|
|
126
130
|
}
|
|
127
131
|
}
|
|
128
|
-
offset +=
|
|
132
|
+
offset += rawLine.length + 1;
|
|
129
133
|
}
|
|
130
134
|
}
|
|
131
135
|
return drafts;
|
|
@@ -134,7 +138,6 @@ export class StructuralCandidateExtractor {
|
|
|
134
138
|
const SECURITY_POLICY_VERSION = '1.0.0';
|
|
135
139
|
const INSTRUCTION_PATTERN = /\b(?:ignore|override|disregard)\b.{0,40}\b(?:instruction|prompt|policy|rule)s?\b|\b(?:system|developer)\s+(?:message|instruction|prompt)\b|\b(?:execute|invoke|run)\b.{0,30}\b(?:tool|command|shell|script)\b/i;
|
|
136
140
|
const SECRET_PATTERN = /\b(?:api[_-]?key|access[_-]?token|password|passwd|private[_-]?key|authorization|cookie|secret)\b\s*(?:[:=]|\bis\b)/i;
|
|
137
|
-
const STRUCTURE_PATTERN = /(?:^|\n)\s*(?:---|\.\.\.)\s*(?:\n|$)|```|~~~|<[/!?A-Za-z]|!\[[^\]]*\]\(|\[[^\]]+\]\([^)]*\)|\{\{|\{%/;
|
|
138
141
|
const CONTROL_PATTERN = /[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f-\u009f]/;
|
|
139
142
|
const BIDI_PATTERN = /[\u061c\u200e\u200f\u202a-\u202e\u2066-\u2069]/u;
|
|
140
143
|
const LATIN_PATTERN = /\p{Script=Latin}/u;
|
|
@@ -146,7 +149,7 @@ export function classifyCandidateSecurity(input) {
|
|
|
146
149
|
const warnings = [];
|
|
147
150
|
if (INSTRUCTION_PATTERN.test(text))
|
|
148
151
|
warnings.push('instruction-like');
|
|
149
|
-
if (
|
|
152
|
+
if (hasStructureBreakingContent(text))
|
|
150
153
|
warnings.push('structure-breaking');
|
|
151
154
|
if (CONTROL_PATTERN.test(text))
|
|
152
155
|
warnings.push('control-character');
|
|
@@ -175,7 +178,40 @@ function evidenceSupportsAssertion(assertion, quote) {
|
|
|
175
178
|
const quoteTokens = tokens(quote);
|
|
176
179
|
return [...assertionTokens].some((token) => quoteTokens.has(token));
|
|
177
180
|
}
|
|
178
|
-
|
|
181
|
+
function hasStructureBreakingContent(text) {
|
|
182
|
+
if (/```|~~~|<[/!?A-Za-z]|\{\{|\{%/.test(text))
|
|
183
|
+
return true;
|
|
184
|
+
for (const line of text.split('\n')) {
|
|
185
|
+
const trimmed = line.trim();
|
|
186
|
+
if (trimmed === '---' || trimmed === '...')
|
|
187
|
+
return true;
|
|
188
|
+
}
|
|
189
|
+
let bracket = -1;
|
|
190
|
+
let image = false;
|
|
191
|
+
let link = false;
|
|
192
|
+
for (let index = 0; index < text.length; index++) {
|
|
193
|
+
if (text[index] === '[') {
|
|
194
|
+
if (bracket < 0)
|
|
195
|
+
bracket = index;
|
|
196
|
+
if (index > 0 && text[index - 1] === '!')
|
|
197
|
+
image = true;
|
|
198
|
+
}
|
|
199
|
+
else if (text[index] === ']') {
|
|
200
|
+
if (text[index + 1] === '(') {
|
|
201
|
+
if (image)
|
|
202
|
+
return true;
|
|
203
|
+
if (bracket >= 0 && index > bracket + 1)
|
|
204
|
+
link = true;
|
|
205
|
+
}
|
|
206
|
+
bracket = -1;
|
|
207
|
+
image = false;
|
|
208
|
+
}
|
|
209
|
+
else if (text[index] === ')' && link) {
|
|
210
|
+
return true;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
179
215
|
const STRUCTURAL_TYPES = {
|
|
180
216
|
decision: 'decision',
|
|
181
217
|
requirement: 'requirement',
|
|
@@ -6,6 +6,41 @@ export const SESSION_PROVIDER_IDS = [
|
|
|
6
6
|
'opencode', 'openclaw', 'openhuman', 'grokbot', 'grok-build', 'pi', 'omp', 'deepseek-harness', 'warp', 'devin-desktop', 'muse', 'generic',
|
|
7
7
|
];
|
|
8
8
|
export const SessionProviderIdSchema = z.enum(SESSION_PROVIDER_IDS);
|
|
9
|
+
// Expected scope must also represent providers unknown to this runtime.
|
|
10
|
+
export const ExpectedSessionProviderSchema = z.string().regex(/^[a-z][a-z0-9-]*$/);
|
|
11
|
+
export const SessionRuntimeIdentitySchema = z.object({
|
|
12
|
+
packageName: z.string(),
|
|
13
|
+
version: z.string(),
|
|
14
|
+
packageRoot: z.string(),
|
|
15
|
+
executable: z.string(),
|
|
16
|
+
nodeVersion: z.string(),
|
|
17
|
+
installationMethod: z.string(),
|
|
18
|
+
installationState: z.enum(['aligned', 'mismatch', 'stale', 'unrecorded', 'unknown']),
|
|
19
|
+
canonicalRoot: z.string().nullable(),
|
|
20
|
+
diagnostics: z.array(z.string()),
|
|
21
|
+
});
|
|
22
|
+
export const SessionCoveragePreflightSchema = z.object({
|
|
23
|
+
expectedProviders: z.array(ExpectedSessionProviderSchema).min(1),
|
|
24
|
+
expectedProviderBasis: z.enum(['explicit', 'declared-default', 'legacy']),
|
|
25
|
+
supportedProviders: z.array(ExpectedSessionProviderSchema),
|
|
26
|
+
runtime: SessionRuntimeIdentitySchema,
|
|
27
|
+
status: z.enum(['partial', 'complete']),
|
|
28
|
+
unresolvedProviders: z.array(ExpectedSessionProviderSchema),
|
|
29
|
+
ledger: z.array(z.object({
|
|
30
|
+
provider: ExpectedSessionProviderSchema,
|
|
31
|
+
disposition: z.enum([
|
|
32
|
+
'missing-adapter', 'unsupported', 'authorization-required', 'export-required',
|
|
33
|
+
'unavailable', 'no-sources', 'not-checked', 'pending-import', 'import-incomplete',
|
|
34
|
+
'scope-incomplete', 'acquired',
|
|
35
|
+
]),
|
|
36
|
+
adapterVersion: z.string().nullable(),
|
|
37
|
+
supportedOperations: z.array(z.string()),
|
|
38
|
+
acquisitionModes: z.array(z.string()),
|
|
39
|
+
sourceCount: z.number().int().nonnegative(),
|
|
40
|
+
boundaries: z.array(z.string()),
|
|
41
|
+
remediation: z.string().nullable(),
|
|
42
|
+
})),
|
|
43
|
+
});
|
|
9
44
|
export const SESSION_PROVIDER_ALIASES = Object.freeze({
|
|
10
45
|
windsurf: 'devin-desktop',
|
|
11
46
|
dsh: 'deepseek-harness',
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { readFileSync, realpathSync } from 'node:fs';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { findPackageRoot } from '../cli/find-package-root.js';
|
|
5
|
+
import { inspectInstallation } from '../installation/manager.mjs';
|
|
6
|
+
import { ExpectedSessionProviderSchema, SESSION_PROVIDER_ALIASES, SESSION_PROVIDER_IDS, SessionContractError, SessionCoveragePreflightSchema, SessionRuntimeIdentitySchema, } from './contracts.js';
|
|
7
|
+
import { createSessionAdapterRegistry } from './adapter-registry.js';
|
|
8
|
+
export function expectedSessionProviders(values) {
|
|
9
|
+
const providers = values.map((value) => {
|
|
10
|
+
const canonical = SESSION_PROVIDER_ALIASES[value.trim()]
|
|
11
|
+
?? value.trim();
|
|
12
|
+
if (!ExpectedSessionProviderSchema.safeParse(canonical).success) {
|
|
13
|
+
throw new SessionContractError('INVALID_ARGUMENT', `invalid expected provider: ${value}`);
|
|
14
|
+
}
|
|
15
|
+
return canonical;
|
|
16
|
+
});
|
|
17
|
+
if (providers.length === 0) {
|
|
18
|
+
throw new SessionContractError('INVALID_ARGUMENT', 'expected providers must not be empty');
|
|
19
|
+
}
|
|
20
|
+
return [...new Set(providers)].sort();
|
|
21
|
+
}
|
|
22
|
+
/** Resolve the code actually loaded, independently of cwd, AIWG_ROOT and corpus redirects. */
|
|
23
|
+
export function sessionRuntimeIdentity() {
|
|
24
|
+
const packageRoot = findPackageRoot(dirname(fileURLToPath(import.meta.url)));
|
|
25
|
+
if (!packageRoot)
|
|
26
|
+
throw new SessionContractError('INVALID_ARGUMENT', 'cannot locate the running AIWG package');
|
|
27
|
+
const pkg = JSON.parse(readFileSync(join(packageRoot, 'package.json'), 'utf8'));
|
|
28
|
+
const executable = process.argv[1] ?? process.execPath;
|
|
29
|
+
const base = {
|
|
30
|
+
packageName: pkg.name, version: pkg.version, packageRoot: realpathSync(packageRoot),
|
|
31
|
+
executable, nodeVersion: process.version,
|
|
32
|
+
};
|
|
33
|
+
try {
|
|
34
|
+
const installation = inspectInstallation({ actualRoot: packageRoot, createIfMissing: false });
|
|
35
|
+
return SessionRuntimeIdentitySchema.parse({
|
|
36
|
+
...base,
|
|
37
|
+
installationMethod: installation.actualMethod,
|
|
38
|
+
installationState: installation.state,
|
|
39
|
+
canonicalRoot: installation.identity?.root ?? null,
|
|
40
|
+
diagnostics: [
|
|
41
|
+
...installation.drift,
|
|
42
|
+
...(['mismatch', 'stale'].includes(installation.state)
|
|
43
|
+
? ['Deliberately select a compatible runtime, inspect `aiwg installation show`, and rediscover. No automatic upgrade or installation switch is performed.'] : []),
|
|
44
|
+
],
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
return SessionRuntimeIdentitySchema.parse({
|
|
49
|
+
...base, installationMethod: 'unknown', installationState: 'unknown', canonicalRoot: null,
|
|
50
|
+
diagnostics: [
|
|
51
|
+
error instanceof Error ? error.message : String(error),
|
|
52
|
+
'Inspect `aiwg installation show` and deliberately select a compatible runtime before claiming complete coverage.',
|
|
53
|
+
],
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
export function coveragePreflight(options = {}) {
|
|
58
|
+
const expectedProviders = expectedSessionProviders(options.expectedProviders ?? SESSION_PROVIDER_IDS);
|
|
59
|
+
const adapters = (options.registry ?? createSessionAdapterRegistry()).list();
|
|
60
|
+
const runtime = options.runtime ?? sessionRuntimeIdentity();
|
|
61
|
+
const ledger = expectedProviders.map((provider) => {
|
|
62
|
+
const adapter = adapters.find((item) => item.provider === provider);
|
|
63
|
+
const report = options.reports?.find((item) => item.provider === provider);
|
|
64
|
+
const entry = {
|
|
65
|
+
provider, disposition: 'not-checked', adapterVersion: adapter?.adapterVersion ?? null,
|
|
66
|
+
supportedOperations: [...(adapter?.supportedOperations ?? [])],
|
|
67
|
+
acquisitionModes: [...(adapter?.acquisitionModes ?? [])],
|
|
68
|
+
sourceCount: report?.sourceCount ?? 0, boundaries: [],
|
|
69
|
+
remediation: report?.remediation ?? 'Run authorized workspace discovery or select a supported export.',
|
|
70
|
+
};
|
|
71
|
+
if (!adapter) {
|
|
72
|
+
entry.disposition = 'missing-adapter';
|
|
73
|
+
entry.remediation = `Running ${runtime.packageName} ${runtime.version} at ${runtime.packageRoot} has no ${provider} adapter. Deliberately select a compatible runtime or use an explicitly authorized supported export; no installation is switched automatically.`;
|
|
74
|
+
}
|
|
75
|
+
else if (adapter.disposition === 'unsupported' || !adapter.supportedOperations.includes('stream')) {
|
|
76
|
+
entry.disposition = 'unsupported';
|
|
77
|
+
}
|
|
78
|
+
else if (report?.reasonCode === 'SHARED_ROOT_AUTHORIZATION_REQUIRED') {
|
|
79
|
+
entry.disposition = 'authorization-required';
|
|
80
|
+
}
|
|
81
|
+
else if (report?.status === 'export-required' || !adapter.supportedOperations.includes('discover')) {
|
|
82
|
+
entry.disposition = 'export-required';
|
|
83
|
+
}
|
|
84
|
+
else if (report?.status === 'unavailable') {
|
|
85
|
+
entry.disposition = 'unavailable';
|
|
86
|
+
}
|
|
87
|
+
else if (report?.reasonCode === 'MUSE_SOURCE_INSPECTION_INCOMPLETE') {
|
|
88
|
+
entry.disposition = report.sourceCount > 0 ? 'pending-import' : 'not-checked';
|
|
89
|
+
entry.boundaries.push('Some Muse sources could not be fully inspected; see museSourceInspections in the discovery manifest.');
|
|
90
|
+
entry.remediation = report.remediation;
|
|
91
|
+
}
|
|
92
|
+
else if (report?.status === 'checked') {
|
|
93
|
+
entry.disposition = report.sourceCount > 0 ? 'pending-import' : 'no-sources';
|
|
94
|
+
entry.remediation = report.sourceCount > 0
|
|
95
|
+
? 'Import the exact authorized manifest and inspect source dispositions.'
|
|
96
|
+
: 'Zero matching sources does not establish no activity; verify scope, authorization and export availability.';
|
|
97
|
+
}
|
|
98
|
+
if (provider === 'muse') {
|
|
99
|
+
entry.boundaries.push('Native discovery includes parent session.jsonl logs only; nested subagent logs and approval-review scope are not established.');
|
|
100
|
+
}
|
|
101
|
+
return entry;
|
|
102
|
+
});
|
|
103
|
+
return SessionCoveragePreflightSchema.parse({
|
|
104
|
+
expectedProviders,
|
|
105
|
+
expectedProviderBasis: options.expectedProviderBasis ?? (options.expectedProviders ? 'explicit' : 'declared-default'),
|
|
106
|
+
supportedProviders: adapters.map((adapter) => adapter.provider), runtime,
|
|
107
|
+
status: 'partial', unresolvedProviders: expectedProviders, ledger,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
export function reconcileCoveragePreflight(preflight, sources) {
|
|
111
|
+
const accepted = new Set(['committed', 'duplicate', 'previously-committed']);
|
|
112
|
+
const ledger = preflight.ledger.map((entry) => {
|
|
113
|
+
if (!['pending-import', 'import-incomplete', 'scope-incomplete', 'acquired'].includes(entry.disposition))
|
|
114
|
+
return entry;
|
|
115
|
+
const selected = sources.filter((source) => source.provider === entry.provider);
|
|
116
|
+
const imported = selected.length === entry.sourceCount && selected.length > 0
|
|
117
|
+
&& selected.every((source) => accepted.has(source.status) && source.eventsAccepted > 0);
|
|
118
|
+
return {
|
|
119
|
+
...entry,
|
|
120
|
+
disposition: !imported ? 'import-incomplete'
|
|
121
|
+
: entry.boundaries.length > 0 ? 'scope-incomplete' : 'acquired',
|
|
122
|
+
remediation: !imported ? 'Resolve pending, rejected, skipped or empty imports before claiming acquisition coverage.'
|
|
123
|
+
: entry.boundaries.length > 0 ? 'Declare the parent-only boundary and separately authorize supported exports for omitted scope.' : null,
|
|
124
|
+
};
|
|
125
|
+
});
|
|
126
|
+
const unresolvedProviders = ledger.filter((entry) => entry.disposition !== 'acquired').map((entry) => entry.provider);
|
|
127
|
+
const runtimeGap = ['mismatch', 'stale', 'unknown'].includes(preflight.runtime.installationState);
|
|
128
|
+
return {
|
|
129
|
+
...preflight, ledger, unresolvedProviders,
|
|
130
|
+
status: unresolvedProviders.length > 0 || runtimeGap || preflight.expectedProviderBasis !== 'explicit'
|
|
131
|
+
? 'partial' : 'complete',
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=coverage-preflight.js.map
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { SessionContractError, assertSessionProviderId, } from './contracts.js';
|
|
2
2
|
export class SessionSourceAdapterRegistry {
|
|
3
3
|
adapters = new Map();
|
|
4
|
+
list() {
|
|
5
|
+
return [...this.adapters.values()].sort((a, b) => a.provider.localeCompare(b.provider));
|
|
6
|
+
}
|
|
4
7
|
register(adapter) {
|
|
5
8
|
const provider = assertSessionProviderId(adapter.provider);
|
|
6
9
|
if (this.adapters.has(provider))
|