@aiwg/cli 2026.10.11 → 2026.10.12
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/model-catalog.v1.json +62 -12
- package/dist/src/artifacts/binding-target-identity.js +51 -0
- package/dist/src/artifacts/checksum-manifest.js +12 -0
- package/dist/src/artifacts/index-builder.js +11 -13
- package/dist/src/artifacts/query-engine.js +5 -11
- package/dist/src/cli/handlers/doctor-help.js +32 -0
- package/dist/src/cli/handlers/gates.js +19 -18
- package/dist/src/cli/handlers/models-help.js +7 -1
- package/dist/src/cli/handlers/models.js +3 -3
- package/dist/src/cli/handlers/script-runner.js +8 -5
- package/dist/src/cli/handlers/sessions-intake.js +104 -0
- package/dist/src/cli/handlers/sessions-tail.js +172 -0
- package/dist/src/cli/handlers/sessions.js +90 -17
- package/dist/src/cli/handlers/skill-lint.js +10 -3
- package/dist/src/cli/handlers/steward-format.js +100 -0
- package/dist/src/cli/handlers/steward-models.js +167 -0
- package/dist/src/cli/handlers/steward.js +14 -248
- package/dist/src/cli/handlers/use-bundle-counts.js +61 -0
- package/dist/src/cli/handlers/use.js +6 -24
- package/dist/src/cli/handlers/utilities.js +1 -24
- package/dist/src/config/aiwg-config.js +7 -0
- package/dist/src/config/authorization-cli.js +89 -0
- package/dist/src/config/cli-help.js +1 -0
- package/dist/src/config/cli.js +10 -1
- package/dist/src/decision/context-pruning.js +3 -2
- package/dist/src/decision/ensemble/contract.js +15 -4
- package/dist/src/decision/ensemble-study/artifacts.js +5 -0
- package/dist/src/decision/ensemble-study/score.js +4 -3
- package/dist/src/decision/feature-export.js +3 -9
- package/dist/src/decision/heldout/collector.js +2 -2
- package/dist/src/decision/issue-triage/runtime.js +3 -9
- package/dist/src/decision/qualification/gates.js +2 -1
- package/dist/src/decision/qualification/release.js +2 -3
- package/dist/src/decision/routing/report.js +2 -0
- package/dist/src/decision/sdlc-screening.js +3 -5
- package/dist/src/decision/sensitivity/comparative.js +5 -3
- package/dist/src/gates/driver.js +6 -77
- package/dist/src/gates/evaluate.js +4 -11
- package/dist/src/gates/floors.js +4 -4
- package/dist/src/gates/index.js +3 -3
- package/dist/src/gates/lattice.js +26 -0
- package/dist/src/gates/registry.js +2 -1
- package/dist/src/gates/report.js +19 -7
- package/dist/src/issues/audit-cli.js +120 -0
- package/dist/src/issues/audit-contract.js +64 -0
- package/dist/src/issues/audit-local.js +82 -0
- package/dist/src/issues/audit.js +220 -0
- package/dist/src/lint/rule-activation.js +15 -1
- package/dist/src/mission-protocol/canonical-codecs.js +270 -0
- package/dist/src/mission-protocol/codecs.js +22 -550
- package/dist/src/mission-protocol/health-trace-codecs.js +281 -0
- package/dist/src/mission-protocol/health-trace-types.js +43 -0
- package/dist/src/mission-protocol/types.js +2 -42
- package/dist/src/mission-protocol/worker-contract-json.js +10 -0
- package/dist/src/mission-protocol/worker-review-gate.js +100 -0
- package/dist/src/mission-protocol/worker-review-types.js +2 -0
- package/dist/src/models/catalog-policy.js +280 -0
- package/dist/src/models/index.js +1 -1
- package/dist/src/models/model-catalog.v1.json +62 -12
- package/dist/src/models/policy-resources.js +28 -0
- package/dist/src/models/provider-policy.js +10 -546
- package/dist/src/models/resolver.js +26 -8
- package/dist/src/models/router.js +15 -2
- package/dist/src/models/tiers.js +13 -0
- package/dist/src/models/types.js +0 -6
- package/dist/src/models/worker-ceilings.js +59 -0
- package/dist/src/models/worker-invocation-policy.js +243 -0
- package/dist/src/models/worker-plan.js +16 -20
- package/dist/src/models/worker-review-lineage.js +55 -0
- package/dist/src/models/worker-selection-policy.js +1 -1
- package/dist/src/models/wrapper-route.js +6 -3
- package/dist/src/policy/authorization.js +1 -0
- package/dist/src/policy/hitl-config.js +63 -0
- package/dist/src/policy/hitl-receipt.js +57 -0
- package/dist/src/policy/hitl-types.js +4 -0
- package/dist/src/policy/hitl-validation.js +39 -0
- package/dist/src/policy/hitl.js +117 -0
- package/dist/src/rules/activation.d.mts +1 -1
- package/dist/src/rules/activation.mjs +0 -2
- package/dist/src/rules/gate-coverage.js +51 -0
- package/dist/src/rules/gate-references.js +16 -0
- package/dist/src/rules/rule-frontmatter.schema.json +7 -1
- package/dist/src/serve/worker-command-request.js +21 -4
- package/dist/src/serve/worker-invocation-preparation.js +3 -1
- package/dist/src/serve/worker-invocation.js +21 -10
- package/dist/src/sessions/adapters/deepseek-harness.js +1 -0
- package/dist/src/sessions/adapters/grok-build-native.js +269 -0
- package/dist/src/sessions/adapters/grok-build.js +57 -15
- package/dist/src/sessions/adapters/hermes-state-db.js +252 -0
- package/dist/src/sessions/adapters/hermes.js +42 -3
- package/dist/src/sessions/adapters/warp.js +1 -1
- package/dist/src/sessions/batch-import.js +10 -0
- package/dist/src/sessions/contracts.js +1 -1
- package/dist/src/sessions/discovery-capability.js +38 -0
- package/dist/src/sessions/importer.js +8 -251
- package/dist/src/sessions/index.js +4 -0
- package/dist/src/sessions/intake-dir.js +71 -0
- package/dist/src/sessions/normalization.js +251 -0
- package/dist/src/sessions/tail.js +91 -0
- package/dist/src/sessions/workspace-discovery.js +83 -7
- package/dist/src/skills/agent-skill-sidecar.js +28 -0
- package/dist/src/skills/agent-skills.js +4 -23
- package/dist/src/skills/claude-surface-projection.js +25 -0
- package/dist/src/skills/deployer.js +8 -288
- package/dist/src/skills/deployment-policy.js +114 -0
- package/dist/src/skills/deployment-projection.js +152 -0
- package/dist/src/skills/deployment-types.js +20 -0
- package/dist/src/skills/exporter.js +8 -31
- package/dist/src/skills/provider-extensions.js +41 -0
- package/dist/src/skills/run.js +6 -0
- package/dist/src/skills/types.js +0 -8
- package/dist/src/skills/validator-resources.js +68 -0
- package/dist/src/skills/validator.js +6 -55
- package/dist/src/storage/cli-migrate-options.js +125 -0
- package/dist/src/storage/cli-migrate.js +111 -0
- package/dist/src/storage/cli.js +4 -279
- package/dist/src/storage/migration-adapter.js +79 -0
- package/dist/src/storage/migration-copy.js +108 -0
- package/dist/src/storage/migration-protocol.js +14 -197
- package/dist/src/storage/migration-records.js +186 -0
- package/dist/src/storage/migration-types.js +12 -0
- package/dist/src/tracker/forge-http.js +2 -1
- package/dist/src/tracker/issue-pages.js +110 -0
- package/package.json +1 -1
- package/schemas/mission-v1.schema.json +335 -0
- package/schemas/models/model-catalog.v1.schema.json +19 -1
- package/schemas/models/model-config-compatibility.v1.schema.json +3 -2
- package/schemas/models/model-policy.v1.schema.json +1 -1
- package/tools/agents/providers/provider-paths-staging.mjs +35 -0
- package/tools/agents/providers/rule-binding-targets.mjs +146 -0
- package/tools/agents/providers/rule-delivery.mjs +7 -126
- package/vscode-extension/schemas/aiwg.config.v1.json +177 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "../../../schemas/models/model-catalog.v1.schema.json",
|
|
3
3
|
"version": "1.0.0",
|
|
4
|
-
"refreshedAt": "2026-
|
|
4
|
+
"refreshedAt": "2026-10-27",
|
|
5
5
|
"staleAfterDays": 90,
|
|
6
6
|
"providers": {
|
|
7
7
|
"antigravity": {
|
|
@@ -28,44 +28,94 @@
|
|
|
28
28
|
"claude": {
|
|
29
29
|
"roles": {
|
|
30
30
|
"reasoning": {
|
|
31
|
-
"id": "claude-opus-5",
|
|
31
|
+
"id": "claude-opus-5-5",
|
|
32
32
|
"status": "active",
|
|
33
|
-
"observed":
|
|
33
|
+
"observed": true
|
|
34
34
|
},
|
|
35
35
|
"coding": {
|
|
36
|
-
"id": "claude-sonnet-5",
|
|
36
|
+
"id": "claude-sonnet-5-5",
|
|
37
37
|
"status": "active",
|
|
38
|
-
"observed":
|
|
38
|
+
"observed": true
|
|
39
39
|
},
|
|
40
40
|
"efficiency": {
|
|
41
|
-
"id": "claude-haiku-
|
|
41
|
+
"id": "claude-haiku-5-5",
|
|
42
42
|
"status": "active",
|
|
43
|
-
"observed":
|
|
43
|
+
"observed": true
|
|
44
44
|
}
|
|
45
45
|
},
|
|
46
46
|
"sourceUrl": "https://platform.claude.com/docs/en/about-claude/models/overview",
|
|
47
|
-
"verifiedAt": "2026-
|
|
47
|
+
"verifiedAt": "2026-10-27",
|
|
48
|
+
"tiers": {
|
|
49
|
+
"flagship": {
|
|
50
|
+
"id": "claude-fable-5-1",
|
|
51
|
+
"status": "active",
|
|
52
|
+
"observed": true,
|
|
53
|
+
"selection": "user-elected"
|
|
54
|
+
},
|
|
55
|
+
"premium": {
|
|
56
|
+
"id": "claude-opus-5-5",
|
|
57
|
+
"status": "active",
|
|
58
|
+
"observed": true
|
|
59
|
+
},
|
|
60
|
+
"standard": {
|
|
61
|
+
"id": "claude-sonnet-5-5",
|
|
62
|
+
"status": "active",
|
|
63
|
+
"observed": true
|
|
64
|
+
},
|
|
65
|
+
"economy": {
|
|
66
|
+
"id": "claude-haiku-5-5",
|
|
67
|
+
"status": "active",
|
|
68
|
+
"observed": true
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
"verified_at": "2026-10-27",
|
|
72
|
+
"evidence": "Conductor-verified Claude Code harness current model list, 2026-10-27."
|
|
48
73
|
},
|
|
49
74
|
"codex": {
|
|
50
75
|
"roles": {
|
|
51
76
|
"reasoning": {
|
|
52
|
-
"id": "gpt-
|
|
77
|
+
"id": "gpt-6.1-sol",
|
|
53
78
|
"status": "active",
|
|
54
79
|
"observed": true
|
|
55
80
|
},
|
|
56
81
|
"coding": {
|
|
57
|
-
"id": "gpt-
|
|
82
|
+
"id": "gpt-6.1-terra",
|
|
58
83
|
"status": "active",
|
|
59
84
|
"observed": true
|
|
60
85
|
},
|
|
61
86
|
"efficiency": {
|
|
62
|
-
"id": "gpt-
|
|
87
|
+
"id": "gpt-6-luna",
|
|
63
88
|
"status": "active",
|
|
64
89
|
"observed": true
|
|
65
90
|
}
|
|
66
91
|
},
|
|
67
92
|
"sourceUrl": "https://learn.chatgpt.com/docs/models",
|
|
68
|
-
"verifiedAt": "2026-
|
|
93
|
+
"verifiedAt": "2026-10-27",
|
|
94
|
+
"tiers": {
|
|
95
|
+
"flagship": {
|
|
96
|
+
"id": "gpt-6-astra",
|
|
97
|
+
"status": "active",
|
|
98
|
+
"observed": true,
|
|
99
|
+
"selection": "user-elected"
|
|
100
|
+
},
|
|
101
|
+
"premium": {
|
|
102
|
+
"id": "gpt-6.1-sol",
|
|
103
|
+
"status": "active",
|
|
104
|
+
"observed": true
|
|
105
|
+
},
|
|
106
|
+
"standard": {
|
|
107
|
+
"id": "gpt-6.1-terra",
|
|
108
|
+
"status": "active",
|
|
109
|
+
"observed": true
|
|
110
|
+
},
|
|
111
|
+
"economy": {
|
|
112
|
+
"id": "gpt-6-luna",
|
|
113
|
+
"status": "active",
|
|
114
|
+
"observed": true
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
"verified_at": "2026-10-27",
|
|
118
|
+
"evidence": "Conductor-verified Codex CLI local model cache on titan (codex-cli 0.165.0), plus ~/.cache/aiwg/model-catalog.v1.json, 2026-10-27; no network verification by this worker."
|
|
69
119
|
},
|
|
70
120
|
"copilot": {
|
|
71
121
|
"roles": {
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/** Resolve source aliases and bundle ownership before rule-target precedence. */
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
function realpath(file) {
|
|
5
|
+
try {
|
|
6
|
+
return fs.realpathSync(file);
|
|
7
|
+
}
|
|
8
|
+
catch {
|
|
9
|
+
return path.resolve(file);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
function sourcePath(file, options) {
|
|
13
|
+
const normalized = file.replace(/\\/g, '/');
|
|
14
|
+
const anchor = normalized.startsWith('agentic/code/') ? options.packageRoot : options.cwd;
|
|
15
|
+
return path.resolve(anchor ?? process.cwd(), normalized);
|
|
16
|
+
}
|
|
17
|
+
function identity(file, options) {
|
|
18
|
+
const absolute = sourcePath(file, options);
|
|
19
|
+
// Realpath handles symlinks; the supplied mapping handles materialized copies.
|
|
20
|
+
return realpath(options.logicalPath?.(realpath(absolute)) ?? absolute);
|
|
21
|
+
}
|
|
22
|
+
function inside(root, file) {
|
|
23
|
+
const relative = path.relative(root, file);
|
|
24
|
+
return relative === '' || (!path.isAbsolute(relative) && relative !== '..' && !relative.startsWith(`..${path.sep}`));
|
|
25
|
+
}
|
|
26
|
+
export function selectBindingTargetIdentities(entries, options = {}) {
|
|
27
|
+
const bundle = options.bundleRoot && identity(options.bundleRoot, options);
|
|
28
|
+
const snapshot = options.bundleRoot && sourcePath(options.bundleRoot, options);
|
|
29
|
+
const preferred = bundle && snapshot ? entries.filter(entry => inside(snapshot, sourcePath(entry.path, options)) || inside(bundle, identity(entry.path, options))) : [];
|
|
30
|
+
const candidates = preferred.length ? preferred : entries;
|
|
31
|
+
const unique = new Map();
|
|
32
|
+
for (const entry of candidates) {
|
|
33
|
+
const key = `${entry.type}:${identity(entry.path, options)}`;
|
|
34
|
+
const previous = unique.get(key);
|
|
35
|
+
// The projector must receive the entry in the bundle's current snapshot.
|
|
36
|
+
const inSnapshot = snapshot && inside(snapshot, sourcePath(entry.path, options));
|
|
37
|
+
if (!previous || inSnapshot)
|
|
38
|
+
unique.set(key, entry);
|
|
39
|
+
}
|
|
40
|
+
return [...unique.values()];
|
|
41
|
+
}
|
|
42
|
+
/** Retain the existing preference for canonical sources over packaged mirrors. */
|
|
43
|
+
export function preferCanonicalBindingTargets(matches) {
|
|
44
|
+
if (matches.length > 1) {
|
|
45
|
+
const canonical = matches.filter(entry => !/(^|\/)agentic\/code\/plugins\//.test(entry.path.replace(/\\/g, '/')));
|
|
46
|
+
if (canonical.length === 1)
|
|
47
|
+
return canonical;
|
|
48
|
+
}
|
|
49
|
+
return matches;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=binding-target-identity.js.map
|
|
@@ -89,4 +89,16 @@ export function pruneManifest(manifest, cwd) {
|
|
|
89
89
|
}
|
|
90
90
|
return removed;
|
|
91
91
|
}
|
|
92
|
+
/** Format change-detection diagnostics from the same counters returned to callers. */
|
|
93
|
+
export function formatManifestStats(stats) {
|
|
94
|
+
if (stats.checked === 0)
|
|
95
|
+
return [];
|
|
96
|
+
const messages = [
|
|
97
|
+
` Change detection: ${stats.checked} checked, ${stats.statSkipped} skipped via stat, ${stats.checked - stats.statSkipped} content-read, ${stats.reindexed} re-indexed`,
|
|
98
|
+
];
|
|
99
|
+
if (stats.pruned > 0) {
|
|
100
|
+
messages.push(` Pruned ${stats.pruned} stale manifest entries (files no longer on disk)`);
|
|
101
|
+
}
|
|
102
|
+
return messages;
|
|
103
|
+
}
|
|
92
104
|
//# sourceMappingURL=checksum-manifest.js.map
|
|
@@ -19,7 +19,7 @@ import { validateGateDocument } from '../gates/schema.js';
|
|
|
19
19
|
import { INDEX_EXTRACTOR_VERSION, INDEX_VERSION, INDEX_DIR, OPERATIONAL_DISCOVERY_TYPES, PHASE_DIRECTORIES, GRAPH_CONFIGS, TEMPLATE_INDEX_EXTENSIONS, resolveGraphScanDir, loadUserGraphConfigs, loadGlobalGraphConfigs, resolveGraphBackendType, } from './types.js';
|
|
20
20
|
import { parseCitationSidecar, citationResultToEdges, buildRefToPathMap } from './citation-parser.js';
|
|
21
21
|
import { writeIndexFile, resolveIndexDir, loadGraphIndexFile, publishIndexFiles } from './index-reader.js';
|
|
22
|
-
import { loadManifest, writeManifest, statMatches, makeEntry } from './checksum-manifest.js';
|
|
22
|
+
import { loadManifest, writeManifest, statMatches, makeEntry, formatManifestStats } from './checksum-manifest.js';
|
|
23
23
|
import { FRAMEWORK_RELATIONS_REVISION } from './framework-source-digest.js';
|
|
24
24
|
import { normalizeOperationalState } from './operational-state.js';
|
|
25
25
|
import { DEFAULT_PROJECT_AIWG_DIR, resolveProjectAiwgDir, } from '../config/project-artifacts.js';
|
|
@@ -963,6 +963,7 @@ function extractIndexArtifact(job, bindingOnly, warnings = []) {
|
|
|
963
963
|
};
|
|
964
964
|
return { checksum, entry };
|
|
965
965
|
}
|
|
966
|
+
/** Return change-detection counts for artifact builds; skipped/source builds return void. */
|
|
966
967
|
export async function buildIndex(cwd, options = {}) {
|
|
967
968
|
loadUserGraphConfigs(cwd);
|
|
968
969
|
loadGlobalGraphConfigs();
|
|
@@ -993,7 +994,7 @@ export async function buildIndex(cwd, options = {}) {
|
|
|
993
994
|
fs.mkdirSync(directory, { recursive: true });
|
|
994
995
|
return staging ??= fs.mkdtempSync(path.join(directory, '.build-'));
|
|
995
996
|
};
|
|
996
|
-
await buildIndexSnapshot(cwd, options, preparePublication, owned ? observation : undefined);
|
|
997
|
+
const stats = await buildIndexSnapshot(cwd, options, preparePublication, owned ? observation : undefined);
|
|
997
998
|
// A receipt hit verifies the existing snapshot directly against the scan's
|
|
998
999
|
// stats. There is no extraction interval to recheck. Real builds still probe
|
|
999
1000
|
// again after preparation so concurrent source changes remain pending.
|
|
@@ -1004,6 +1005,7 @@ export async function buildIndex(cwd, options = {}) {
|
|
|
1004
1005
|
recordIndexVerification(owned, cwd, { before: observation.before, after, wallMs: Date.now() - start }, staging);
|
|
1005
1006
|
if (staging)
|
|
1006
1007
|
publishIndexFiles(staging, directory);
|
|
1008
|
+
return stats;
|
|
1007
1009
|
}
|
|
1008
1010
|
catch (error) {
|
|
1009
1011
|
if (owned) {
|
|
@@ -1141,14 +1143,9 @@ async function buildIndexSnapshot(cwd, options, preparePublication, observation)
|
|
|
1141
1143
|
log(`Artifact index built in ${buildTimeMs}ms`);
|
|
1142
1144
|
log(` Indexed ${newCount} new, updated ${updatedCount}, unchanged ${unchangedCount}`);
|
|
1143
1145
|
log(` Total: ${total} artifacts`);
|
|
1144
|
-
if (!force
|
|
1145
|
-
const
|
|
1146
|
-
|
|
1147
|
-
log(` Change detection: ${manifestStats.checked} checked, ${fastPath} skipped via stat, ${slowPath} content-read, ${manifestStats.reindexed} re-indexed`);
|
|
1148
|
-
if (manifestStats.pruned > 0) {
|
|
1149
|
-
log(` Pruned ${manifestStats.pruned} stale manifest entries (files no longer on disk)`);
|
|
1150
|
-
}
|
|
1151
|
-
}
|
|
1146
|
+
if (!force)
|
|
1147
|
+
for (const message of formatManifestStats(manifestStats))
|
|
1148
|
+
log(message);
|
|
1152
1149
|
const displayDir = graph ? indexOutputDir : `${INDEX_DIR}/`;
|
|
1153
1150
|
log(` Output: ${displayDir}`);
|
|
1154
1151
|
};
|
|
@@ -1211,7 +1208,7 @@ async function buildIndexSnapshot(cwd, options, preparePublication, observation)
|
|
|
1211
1208
|
if (observation)
|
|
1212
1209
|
observation.unchanged = true;
|
|
1213
1210
|
reportBuild(buildTimeMs, files.length);
|
|
1214
|
-
return;
|
|
1211
|
+
return manifestStats;
|
|
1215
1212
|
}
|
|
1216
1213
|
}
|
|
1217
1214
|
const publicationDir = preparePublication();
|
|
@@ -1245,6 +1242,7 @@ async function buildIndexSnapshot(cwd, options, preparePublication, observation)
|
|
|
1245
1242
|
...(!force && existingEntries[relativePath] ? { existingChecksum: existingEntries[relativePath].checksum } : {}) });
|
|
1246
1243
|
}
|
|
1247
1244
|
const preparation = await runIndexPreparation(jobs, prepareIndexArtifact, import.meta.url, workers, options.onDiagnostic ?? (message => console.warn(`Index preparation: ${message}`)));
|
|
1245
|
+
manifestStats.reindexed = preparation.results.filter(result => result.entry !== undefined).length;
|
|
1248
1246
|
for (const result of preparation.results)
|
|
1249
1247
|
for (const warning of result.warnings ?? []) {
|
|
1250
1248
|
(options.onDiagnostic ?? (message => console.warn(`Index preparation: ${message}`)))(warning);
|
|
@@ -1313,7 +1311,6 @@ async function buildIndexSnapshot(cwd, options, preparePublication, observation)
|
|
|
1313
1311
|
log(` unchanged (checksum): ${relativePath}`);
|
|
1314
1312
|
continue;
|
|
1315
1313
|
}
|
|
1316
|
-
manifestStats.reindexed++;
|
|
1317
1314
|
nextManifestEntries[relativePath] = makeEntry(checksum, stat);
|
|
1318
1315
|
entry = prepared.entry;
|
|
1319
1316
|
}
|
|
@@ -1363,7 +1360,7 @@ async function buildIndexSnapshot(cwd, options, preparePublication, observation)
|
|
|
1363
1360
|
if (manifestStats.checksumSkipped > 0 || projectionNeedsRepair)
|
|
1364
1361
|
writeBuildManifest(nextManifestEntries);
|
|
1365
1362
|
reportBuild(buildTimeMs, total);
|
|
1366
|
-
return;
|
|
1363
|
+
return manifestStats;
|
|
1367
1364
|
}
|
|
1368
1365
|
}
|
|
1369
1366
|
// Apply metadata supplements if configured (enriches filename-metadata nodes from sidecars)
|
|
@@ -1563,5 +1560,6 @@ async function buildIndexSnapshot(cwd, options, preparePublication, observation)
|
|
|
1563
1560
|
writeBuildManifest(nextManifestEntries);
|
|
1564
1561
|
// Report
|
|
1565
1562
|
reportBuild(buildTimeMs, total);
|
|
1563
|
+
return manifestStats;
|
|
1566
1564
|
}
|
|
1567
1565
|
//# sourceMappingURL=index-builder.js.map
|
|
@@ -12,6 +12,7 @@ import { refreshFrameworkCapabilities, resolveFrameworkCorpusRoot, isCorpusBundl
|
|
|
12
12
|
import { resolveFrameworkIndexRoot } from './framework-index-paths.js';
|
|
13
13
|
import { ensureRelations, selectPrebuiltRelations, emptyRuleStats } from './relations.js';
|
|
14
14
|
import { minimatch } from 'minimatch';
|
|
15
|
+
import { selectBindingTargetIdentities, preferCanonicalBindingTargets } from './binding-target-identity.js';
|
|
15
16
|
import { inferRuleActivation } from '../rules/activation.mjs';
|
|
16
17
|
import * as fs from 'node:fs';
|
|
17
18
|
import * as path from 'node:path';
|
|
@@ -1624,7 +1625,7 @@ function findShowMatches(entries, types, needle) {
|
|
|
1624
1625
|
return matches;
|
|
1625
1626
|
}
|
|
1626
1627
|
/** Preselect exact candidates once; the canonical resolver still owns precedence and ambiguity. */
|
|
1627
|
-
export function createRuleBindingTargetResolver(entries) {
|
|
1628
|
+
export function createRuleBindingTargetResolver(entries, options = {}) {
|
|
1628
1629
|
const candidates = new Map();
|
|
1629
1630
|
for (const entry of entries) {
|
|
1630
1631
|
if (!['skill', 'agent', 'flow'].includes(entry.type))
|
|
@@ -1643,13 +1644,13 @@ export function createRuleBindingTargetResolver(entries) {
|
|
|
1643
1644
|
candidates.set(key, selected);
|
|
1644
1645
|
}
|
|
1645
1646
|
}
|
|
1646
|
-
return (type, id) => resolveRuleBindingTarget(candidates.get(`${type}\0${id}`) ?? [], type, id);
|
|
1647
|
+
return (type, id, bundleRoot = options.bundleRoot) => resolveRuleBindingTarget(candidates.get(`${type}\0${id}`) ?? [], type, id, { ...options, bundleRoot });
|
|
1647
1648
|
}
|
|
1648
1649
|
/** Resolve exact rule binding IDs using the same precedence and ambiguity as show.
|
|
1649
1650
|
* Canonical layout slugs remain valid when frontmatter names are display names.
|
|
1650
1651
|
* Titles and filesystem paths are deliberately excluded (#2938).
|
|
1651
1652
|
*/
|
|
1652
|
-
export function resolveRuleBindingTarget(entries, type, id) {
|
|
1653
|
+
export function resolveRuleBindingTarget(entries, type, id, options = {}) {
|
|
1653
1654
|
const exact = entries.filter(entry => {
|
|
1654
1655
|
if (entry.type !== type)
|
|
1655
1656
|
return false;
|
|
@@ -1660,14 +1661,7 @@ export function resolveRuleBindingTarget(entries, type, id) {
|
|
|
1660
1661
|
: basename.replace(/\.[^.]+$/, '');
|
|
1661
1662
|
return entry.name === id || discoveryIdForEntry(entry) === id || slug === id;
|
|
1662
1663
|
});
|
|
1663
|
-
|
|
1664
|
-
// Generated plugin copies (agentic/code/plugins/*) mirror canonical framework
|
|
1665
|
-
// and addon artifacts. Prefer the canonical source when it is unambiguous.
|
|
1666
|
-
if (matches.length > 1) {
|
|
1667
|
-
const canonical = matches.filter(entry => !/(^|\/)agentic\/code\/plugins\//.test(normalizeIndexedPath(entry.path)));
|
|
1668
|
-
if (canonical.length === 1)
|
|
1669
|
-
matches = canonical;
|
|
1670
|
-
}
|
|
1664
|
+
const matches = preferCanonicalBindingTargets(findShowMatches(selectBindingTargetIdentities(exact, options), [type], id));
|
|
1671
1665
|
if (matches.length === 0)
|
|
1672
1666
|
throw new Error(`Missing ${type} binding target: ${id}`);
|
|
1673
1667
|
if (matches.length > 1)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// Public doctor options and exit-status contract.
|
|
2
|
+
export const DOCTOR_HELP = `aiwg doctor — check AIWG installation health
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
aiwg doctor [options]
|
|
6
|
+
aiwg -doctor [options]
|
|
7
|
+
aiwg --doctor [options]
|
|
8
|
+
|
|
9
|
+
Options:
|
|
10
|
+
--deployment Verify configured provider deployments
|
|
11
|
+
--provider <name> Limit deployment verification to one provider
|
|
12
|
+
--bundle <name> Limit deployment verification to one bundle
|
|
13
|
+
--scope <scope> Verification scope: project or user
|
|
14
|
+
--user Alias for --scope user
|
|
15
|
+
--qualify With --probe-workers, record installation and configured model/role approval
|
|
16
|
+
--yes Confirm worker qualification without a terminal
|
|
17
|
+
--dry-run With --probe-workers, preview qualification without writes
|
|
18
|
+
--cli NAME Limit worker probes/qualification to one configured CLI
|
|
19
|
+
--decision-offload Show offline advisory decision readiness and adoption report
|
|
20
|
+
--probe-workers Run bounded worker CLI version probes (default: config-only, no subprocess)
|
|
21
|
+
--project-local Include project-local artifact diagnostics
|
|
22
|
+
--json Emit machine-readable output (with --probe-workers: one worker-probe record per CLI; with --deployment: deployment verification; with --decision-offload: offline snapshot)
|
|
23
|
+
--verbose, -v Include verbose diagnostics
|
|
24
|
+
--help, -h Show this help
|
|
25
|
+
|
|
26
|
+
Exit status:
|
|
27
|
+
0 Checks completed; ordinary doctor warnings are advisory.
|
|
28
|
+
1 Diagnostic errors, failed or partial explicit worker qualification, or blocked recorded invocations.
|
|
29
|
+
2 Invalid usage.
|
|
30
|
+
--qualify uses the same exit status in text and JSON output.
|
|
31
|
+
`;
|
|
32
|
+
//# sourceMappingURL=doctor-help.js.map
|
|
@@ -3,13 +3,14 @@ function jsonResult(value, exitCode = 0) {
|
|
|
3
3
|
}
|
|
4
4
|
function usage() {
|
|
5
5
|
return [
|
|
6
|
-
'Usage: aiwg gates <validate|evaluate|show|list> [options]',
|
|
6
|
+
'Usage: aiwg gates <validate|evaluate|show|list|coverage> [options]',
|
|
7
7
|
'',
|
|
8
8
|
'Commands:',
|
|
9
9
|
' validate <pack|binding|report> <path> [--pack-dir <dir>] [--aiwg-root <dir>]',
|
|
10
10
|
' evaluate --binding <file> --metrics <file> --holdout <file> [--upstream <file>] --now <iso> --trusted-binding-digest <sha256> [--pack-dir <dir>] [--aiwg-root <dir>]',
|
|
11
11
|
' show <id> [--pack-dir <dir>] [--aiwg-root <dir>]',
|
|
12
12
|
' list [--namespace <ns>] [--rule [<rule-id>]] [--pack-dir <dir>] [--aiwg-root <dir>]',
|
|
13
|
+
' coverage [--rule <rule-id>] [--json] [--pack-dir <dir>] [--aiwg-root <dir>]',
|
|
13
14
|
'',
|
|
14
15
|
'Packs live in <bundle>/gate-packs/*.gatepack.yaml|json and register as',
|
|
15
16
|
'aiwg:<bundle>/<name> (shipped).',
|
|
@@ -77,7 +78,7 @@ async function executeGates(ctx) {
|
|
|
77
78
|
try {
|
|
78
79
|
if (!command || command === '--help' || command === '-h')
|
|
79
80
|
return { exitCode: 0, message: usage(), rawOutput: true };
|
|
80
|
-
const { validateGateFile, evaluateGatesFromFiles, showGatePack, listGatePacks,
|
|
81
|
+
const { validateGateFile, evaluateGatesFromFiles, showGatePack, listGatePacks, } = await import('../../gates/driver.js');
|
|
81
82
|
const options = driverOptions(ctx);
|
|
82
83
|
if (command === 'validate') {
|
|
83
84
|
const args = positionals(ctx.args, 'validate');
|
|
@@ -115,27 +116,27 @@ async function executeGates(ctx) {
|
|
|
115
116
|
return { exitCode: 2, message: `gates show requires <id>\n\n${usage()}`, rawOutput: true };
|
|
116
117
|
return jsonResult(showGatePack(id, options), 0);
|
|
117
118
|
}
|
|
118
|
-
if (command === 'list') {
|
|
119
|
+
if (command === 'coverage' || command === 'list' && ctx.args.includes('--rule')) {
|
|
120
|
+
const { listRuleGateCoverage, formatRuleGateCoverage } = await import('../../rules/gate-coverage.js');
|
|
121
|
+
const value = takeOption(ctx.args, '--rule');
|
|
122
|
+
const rule = value && !value.startsWith('-') ? value : undefined;
|
|
123
|
+
const rules = listRuleGateCoverage(options, rule);
|
|
124
|
+
if (command === 'coverage') {
|
|
125
|
+
return ctx.args.includes('--json') ? jsonResult({ schema: 'aiwg-gates-coverage/v1', rules })
|
|
126
|
+
: { exitCode: 0, message: formatRuleGateCoverage(rules), rawOutput: true };
|
|
127
|
+
}
|
|
119
128
|
const namespace = takeOption(ctx.args, '--namespace');
|
|
120
|
-
const ruleIndex = ctx.args.indexOf('--rule');
|
|
121
|
-
const ruleValue = ruleIndex >= 0 ? ctx.args[ruleIndex + 1] : undefined;
|
|
122
|
-
const rule = ruleIndex >= 0 ? (ruleValue && !ruleValue.startsWith('-') ? ruleValue : null) : undefined;
|
|
123
129
|
const packs = listGatePacks({ ...options, ...(namespace ? { namespace } : {}) });
|
|
124
|
-
|
|
125
|
-
return jsonResult({ schema: 'aiwg-gates-list/v1', packs }, 0);
|
|
126
|
-
if (rule === null) {
|
|
127
|
-
return jsonResult({
|
|
128
|
-
schema: 'aiwg-gates-list/v1', packs,
|
|
129
|
-
enforcedBy: { status: 'stub', note: 'Rule enforcedBy coverage is tracked in #2839; rules without enforcedBy remain guidance.' },
|
|
130
|
-
}, 0);
|
|
131
|
-
}
|
|
132
|
-
const referenced = new Set(await packsReferencedByRule(rule, options));
|
|
130
|
+
const referenced = new Set(rules.flatMap(item => item.enforcedBy.map(reference => reference.split('#')[0])));
|
|
133
131
|
return jsonResult({
|
|
134
|
-
schema: 'aiwg-gates-list/v1', rule,
|
|
135
|
-
packs: packs.filter(pack => referenced.has(pack.id)),
|
|
136
|
-
enforcedBy: { status: 'stub', note: 'Rule enforcedBy coverage is tracked in #2839.' },
|
|
132
|
+
schema: 'aiwg-gates-list/v1', ...(rule ? { rule } : {}), rules,
|
|
133
|
+
packs: rule ? packs.filter(pack => referenced.has(pack.id)) : packs,
|
|
137
134
|
}, 0);
|
|
138
135
|
}
|
|
136
|
+
if (command === 'list') {
|
|
137
|
+
const namespace = takeOption(ctx.args, '--namespace');
|
|
138
|
+
return jsonResult({ schema: 'aiwg-gates-list/v1', packs: listGatePacks({ ...options, ...(namespace ? { namespace } : {}) }) });
|
|
139
|
+
}
|
|
139
140
|
return { exitCode: 2, message: usage(), rawOutput: true };
|
|
140
141
|
}
|
|
141
142
|
catch (error) {
|
|
@@ -27,7 +27,7 @@ Artifact selectors and options:
|
|
|
27
27
|
--drift Include catalog drift for sources/refresh
|
|
28
28
|
--url <url> Remote catalog URL for refresh
|
|
29
29
|
--help, -h Show this reference
|
|
30
|
-
TIER: economy | standard | premium | max-quality
|
|
30
|
+
TIER: economy | standard | premium | flagship (alias: max-quality)
|
|
31
31
|
|
|
32
32
|
Direct worker resolution (plans an invocation; does not launch it):
|
|
33
33
|
aiwg models resolve --role <role> --task <class> --group <group>
|
|
@@ -43,6 +43,12 @@ Direct worker resolution (plans an invocation; does not launch it):
|
|
|
43
43
|
--transport Must match group execution transport (default: shell)
|
|
44
44
|
--format JSON plan or POSIX shell command (default: json)
|
|
45
45
|
--json Alias for --format json
|
|
46
|
+
--max-attempts <count> Tighten total attempts, including the initial attempt
|
|
47
|
+
--timeout-ms <ms> Tighten the hard stop; positive multiple of 1000 (whole seconds)
|
|
48
|
+
--max-output-tokens <count> Tighten the existing task token budget (tokens)
|
|
49
|
+
--max-usd <amount> Tighten the task cost ceiling (costUsd)
|
|
50
|
+
Limits may only tighten resolved policy; larger values fail
|
|
51
|
+
JSON includes ceilings and their origins
|
|
46
52
|
--authorize-premium Authorize premium for this resolution only
|
|
47
53
|
Agents require explicit human confirmation of escalation
|
|
48
54
|
|
|
@@ -144,7 +144,7 @@ async function resolveDirect(ctx, services) {
|
|
|
144
144
|
return { exitCode: 2 };
|
|
145
145
|
}
|
|
146
146
|
}
|
|
147
|
-
const TIERS = new Set(['economy', 'standard', 'premium', 'max-quality']);
|
|
147
|
+
const TIERS = new Set(['economy', 'standard', 'premium', 'flagship', 'max-quality']);
|
|
148
148
|
const PROVIDERS = new Set(Object.keys(loadProviderModelCapabilities().providers));
|
|
149
149
|
function parseArgs(args) {
|
|
150
150
|
const [subcommand = 'help', ...rest] = args;
|
|
@@ -241,7 +241,7 @@ function select(artifacts, parsed, useTierSelector = true) {
|
|
|
241
241
|
&& (!framework || item.framework === framework)));
|
|
242
242
|
}
|
|
243
243
|
function normalizedTier(tier) {
|
|
244
|
-
return tier === 'max-quality' ? '
|
|
244
|
+
return tier === 'max-quality' ? 'flagship' : tier ?? 'standard';
|
|
245
245
|
}
|
|
246
246
|
function resolved(item, provider, catalog) {
|
|
247
247
|
const policy = {
|
|
@@ -331,7 +331,7 @@ async function execute(ctx, services = { load: loadWorkerInputs }) {
|
|
|
331
331
|
return { exitCode: 0 };
|
|
332
332
|
}
|
|
333
333
|
// Preserve artifact/native resolve when direct-only flags are absent.
|
|
334
|
-
if (ctx.args[0] === 'resolve' && ctx.args.slice(1).some(arg => /^--(?:task|group|brief|workdir|final-output|transport|format|authorize-premium)(?:=|$)/.test(arg))) {
|
|
334
|
+
if (ctx.args[0] === 'resolve' && ctx.args.slice(1).some(arg => /^--(?:task|group|brief|workdir|final-output|transport|format|authorize-premium|max-attempts|timeout-ms|max-output-tokens|max-usd)(?:=|$)/.test(arg))) {
|
|
335
335
|
return resolveDirect(ctx, services);
|
|
336
336
|
}
|
|
337
337
|
if (await handleWorkerAdoptionArgs(ctx.args, ctx.cwd, 'models', ctx.signal, ctx.dryRun))
|
|
@@ -120,11 +120,13 @@ export class DefaultScriptRunner {
|
|
|
120
120
|
clearTimeout(timeoutId);
|
|
121
121
|
if (killEscalationId)
|
|
122
122
|
clearTimeout(killEscalationId);
|
|
123
|
-
// On failure in capture mode, surface the captured stderr
|
|
124
|
-
|
|
123
|
+
// On failure in capture mode, surface the captured stderr. Every
|
|
124
|
+
// failure carries a message so callers never print an empty ERROR.
|
|
125
|
+
if (options.capture && code !== 0) {
|
|
126
|
+
const stderr = Buffer.concat(capturedStderr).toString().trim();
|
|
125
127
|
resolve({
|
|
126
128
|
exitCode: code ?? 1,
|
|
127
|
-
message:
|
|
129
|
+
message: stderr || `Script exited with code ${code ?? 1}: ${path.basename(fullPath)}`,
|
|
128
130
|
});
|
|
129
131
|
}
|
|
130
132
|
else {
|
|
@@ -183,8 +185,9 @@ export class DefaultScriptRunner {
|
|
|
183
185
|
// the runner still supports arbitrary scripts via its subprocess path.
|
|
184
186
|
const deployer = await import(pathToFileURL(fullPath).href);
|
|
185
187
|
const exitCode = (await deployer.main(args, { capture: options.capture === true })) ?? 0;
|
|
186
|
-
const message = Buffer.concat(diagnostics).toString().trim()
|
|
187
|
-
|
|
188
|
+
const message = Buffer.concat(diagnostics).toString().trim()
|
|
189
|
+
|| (exitCode ? `Deployment script exited with code ${exitCode}: ${path.basename(fullPath)}` : '');
|
|
190
|
+
return exitCode || message ? { exitCode, message } : { exitCode };
|
|
188
191
|
}
|
|
189
192
|
catch (error) {
|
|
190
193
|
const message = Buffer.concat(diagnostics).toString().trim()
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
// `aiwg sessions import --from-dir`: idempotent intake-directory batch import (#3168).
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { fingerprintSourceFile, intakeSourceId, isRecognisedIntakeFile, listIntakeDirFiles, summarizeIntakeReceipts, INTAKE_DIR_SCHEMA_VERSION, } from '../../sessions/index.js';
|
|
4
|
+
export async function importFromDir(ctx, args, dir, deps) {
|
|
5
|
+
const { assertSupportedImportProvider, normalizeWorkspaceId, isDryRun, preview, ok, openRepository, adapterVersionFor, importSource, importFailureReason, } = deps;
|
|
6
|
+
const provider = assertSupportedImportProvider(args.values.get('--provider') ?? 'generic');
|
|
7
|
+
const workspaceId = args.values.has('--workspace')
|
|
8
|
+
? normalizeWorkspaceId(ctx.cwd, args.values.get('--workspace'))
|
|
9
|
+
: 'default';
|
|
10
|
+
const prefix = args.values.get('--source-id');
|
|
11
|
+
const files = await listIntakeDirFiles(dir);
|
|
12
|
+
if (isDryRun(ctx, args)) {
|
|
13
|
+
return preview('import', {
|
|
14
|
+
fromDir: dir,
|
|
15
|
+
provider,
|
|
16
|
+
workspaceId,
|
|
17
|
+
sourceIdPrefix: prefix ?? null,
|
|
18
|
+
files: files.map((file) => {
|
|
19
|
+
const recognition = isRecognisedIntakeFile(provider, file);
|
|
20
|
+
return {
|
|
21
|
+
file,
|
|
22
|
+
sourceId: recognition.recognised ? intakeSourceId(prefix, file) : null,
|
|
23
|
+
recognised: recognition.recognised,
|
|
24
|
+
reason: recognition.reason ?? null,
|
|
25
|
+
};
|
|
26
|
+
}),
|
|
27
|
+
wouldPersist: false,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
const repository = openRepository(ctx, args);
|
|
31
|
+
try {
|
|
32
|
+
const interrupted = new Map();
|
|
33
|
+
const receipts = [];
|
|
34
|
+
for (const file of files) {
|
|
35
|
+
const recognition = isRecognisedIntakeFile(provider, file);
|
|
36
|
+
const input = join(dir, file);
|
|
37
|
+
if (!recognition.recognised) {
|
|
38
|
+
receipts.push({
|
|
39
|
+
file, sourceId: null, digest: null, status: 'skipped',
|
|
40
|
+
reason: recognition.reason ?? 'unrecognised file', sessionsInserted: 0, eventsInserted: 0,
|
|
41
|
+
});
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
const sourceId = intakeSourceId(prefix, file);
|
|
45
|
+
let digest = null;
|
|
46
|
+
try {
|
|
47
|
+
const fingerprint = await fingerprintSourceFile({ selectedPath: input, allowedRoots: [dir] });
|
|
48
|
+
digest = fingerprint.digest;
|
|
49
|
+
const checkpoint = repository.getCheckpoint(sourceId, adapterVersionFor(provider));
|
|
50
|
+
if (checkpoint?.prefixDigest === digest && checkpoint.sourceSize === fingerprint.size) {
|
|
51
|
+
receipts.push({
|
|
52
|
+
file, sourceId, digest, status: 'already-imported',
|
|
53
|
+
reason: 'content digest already imported', sessionsInserted: 0, eventsInserted: 0,
|
|
54
|
+
});
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
receipts.push({
|
|
60
|
+
file, sourceId, digest, status: 'rejected',
|
|
61
|
+
reason: importFailureReason(error), sessionsInserted: 0, eventsInserted: 0,
|
|
62
|
+
});
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
const fileValues = new Map(args.values);
|
|
66
|
+
fileValues.delete('--from-dir');
|
|
67
|
+
fileValues.set('--source-id', sourceId);
|
|
68
|
+
try {
|
|
69
|
+
const result = await importSource(ctx, {
|
|
70
|
+
command: 'import', positionals: [input], flags: new Set(args.flags),
|
|
71
|
+
values: fileValues, codexRoots: args.codexRoots, exclude: args.exclude,
|
|
72
|
+
});
|
|
73
|
+
const data = result.envelope.data;
|
|
74
|
+
for (const run of data.interruptedRuns ?? [])
|
|
75
|
+
interrupted.set(run.runId, run);
|
|
76
|
+
receipts.push({
|
|
77
|
+
file, sourceId, digest, status: 'imported', reason: null,
|
|
78
|
+
sessionsInserted: data.totals?.sessionsInserted ?? 0,
|
|
79
|
+
eventsInserted: data.totals?.eventsInserted ?? 0,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
receipts.push({
|
|
84
|
+
file, sourceId, digest, status: 'rejected',
|
|
85
|
+
reason: importFailureReason(error), sessionsInserted: 0, eventsInserted: 0,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return ok('import', {
|
|
90
|
+
fromDir: dir,
|
|
91
|
+
provider,
|
|
92
|
+
workspaceId,
|
|
93
|
+
sourceIdPrefix: prefix ?? null,
|
|
94
|
+
schemaVersion: INTAKE_DIR_SCHEMA_VERSION,
|
|
95
|
+
files: receipts,
|
|
96
|
+
summary: summarizeIntakeReceipts(receipts),
|
|
97
|
+
interruptedRuns: [...interrupted.values()],
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
finally {
|
|
101
|
+
repository.close();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=sessions-intake.js.map
|