@aiwg/cli 2026.9.21 → 2026.9.24
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.
|
@@ -526,22 +526,21 @@ async function handleBuild(args) {
|
|
|
526
526
|
loadUserGraphConfigs(cwd);
|
|
527
527
|
loadGlobalGraphConfigs();
|
|
528
528
|
let jsonBuilt = false;
|
|
529
|
-
|
|
529
|
+
const builtGraphs = new Set();
|
|
530
530
|
if (graph) {
|
|
531
531
|
// --graph X: build the JSON graph if X is one; otherwise X may be a
|
|
532
532
|
// research-corpus markdown view, rendered below.
|
|
533
533
|
if (graph in GRAPH_CONFIGS) {
|
|
534
534
|
await buildIndex(cwd, { force, verbose, scope, graph, explicit: true });
|
|
535
535
|
jsonBuilt = true;
|
|
536
|
-
|
|
536
|
+
builtGraphs.add(graph);
|
|
537
537
|
}
|
|
538
538
|
}
|
|
539
539
|
else if (all) {
|
|
540
540
|
// Build all known graphs — user asked for everything, but don't hard-error on missing dirs
|
|
541
541
|
for (const [name] of orderedGraphEntries(Object.entries(GRAPH_CONFIGS))) {
|
|
542
542
|
await buildIndex(cwd, { force, verbose, graph: name, explicit: false });
|
|
543
|
-
|
|
544
|
-
projectGraphBuilt = true;
|
|
543
|
+
builtGraphs.add(name);
|
|
545
544
|
}
|
|
546
545
|
jsonBuilt = true;
|
|
547
546
|
}
|
|
@@ -550,8 +549,7 @@ async function handleBuild(args) {
|
|
|
550
549
|
for (const [name, config] of orderedGraphEntries(Object.entries(GRAPH_CONFIGS))) {
|
|
551
550
|
if (config.defaultBuild) {
|
|
552
551
|
await buildIndex(cwd, { force, verbose, scope: name === Object.keys(GRAPH_CONFIGS)[0] ? scope : undefined, graph: name, explicit: false });
|
|
553
|
-
|
|
554
|
-
projectGraphBuilt = true;
|
|
552
|
+
builtGraphs.add(name);
|
|
555
553
|
}
|
|
556
554
|
}
|
|
557
555
|
jsonBuilt = true;
|
|
@@ -583,21 +581,28 @@ async function handleBuild(args) {
|
|
|
583
581
|
if (viewResults.some((r) => r.status === 'unsupported')) {
|
|
584
582
|
process.exit(1);
|
|
585
583
|
}
|
|
586
|
-
if (
|
|
587
|
-
await
|
|
584
|
+
if (builtGraphs.size > 0) {
|
|
585
|
+
await syncFortemiCoreCachesAfterBuild(cwd, builtGraphs, verbose);
|
|
588
586
|
}
|
|
589
587
|
}
|
|
590
|
-
async function
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
588
|
+
async function syncFortemiCoreCachesAfterBuild(cwd, graphs, verbose) {
|
|
589
|
+
const { syncFortemiCoreIndex } = await import('./fortemi-core-sync.js');
|
|
590
|
+
const { loadGraphIndexFile } = await import('./index-reader.js');
|
|
591
|
+
for (const graph of graphs) {
|
|
592
|
+
// Some default-build graphs skip cleanly when their scan roots are absent.
|
|
593
|
+
// Only materialize a cache when this build left an actual source index.
|
|
594
|
+
if (!loadGraphIndexFile(cwd, 'metadata.json', graph))
|
|
595
|
+
continue;
|
|
596
|
+
try {
|
|
597
|
+
const manifest = syncFortemiCoreIndex(cwd, { graph });
|
|
598
|
+
if (verbose) {
|
|
599
|
+
console.log(`Fortemi Core ${graph} sync: ${manifest.status}, ${manifest.item_count} item(s) → ${manifest.export_path}`);
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
catch (err) {
|
|
603
|
+
console.error(`Warning: Fortemi Core ${graph} sync failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
604
|
+
console.error(`Run \`aiwg index sync --graph ${graph}\` before using Fortemi-backed commands for '${graph}' artifacts.`);
|
|
596
605
|
}
|
|
597
|
-
}
|
|
598
|
-
catch (err) {
|
|
599
|
-
console.error(`Warning: Fortemi Core project sync failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
600
|
-
console.error('Run `aiwg index sync --graph project` before using Fortemi-backed `aiwg discover` or `aiwg show` for project-local artifacts.');
|
|
601
606
|
}
|
|
602
607
|
}
|
|
603
608
|
/**
|
|
@@ -168,7 +168,11 @@ export function loadFortemiCoreExport(cwd, graph = "project", sourcePaths) {
|
|
|
168
168
|
}
|
|
169
169
|
}
|
|
170
170
|
let status = getFortemiCoreSyncStatus(cwd, graph);
|
|
171
|
-
|
|
171
|
+
// The packaged framework index is a bootstrap fallback for an absent shared
|
|
172
|
+
// cache. Once a shared cache exists, its stale state proves that the local
|
|
173
|
+
// source index is newer; silently replacing it with an older packaged index
|
|
174
|
+
// would hide newly authored capabilities.
|
|
175
|
+
if ((!status.optedIn || !status.built) && !status.stale && graph === "framework") {
|
|
172
176
|
const prebuilt = getFortemiCorePrebuiltStatus(graph);
|
|
173
177
|
if (prebuilt.optedIn && prebuilt.built && !prebuilt.stale) {
|
|
174
178
|
status = prebuilt;
|
|
@@ -182,7 +186,7 @@ export function loadFortemiCoreExport(cwd, graph = "project", sourcePaths) {
|
|
|
182
186
|
if (!status.built || status.stale) {
|
|
183
187
|
return {
|
|
184
188
|
reason: `${status.reason ??
|
|
185
|
-
`Fortemi Core static index for graph '${graph}' is stale or incomplete`}. Re-run 'aiwg index sync' or pass '--backend local' to use the legacy local index.`,
|
|
189
|
+
`Fortemi Core static index for graph '${graph}' is stale or incomplete`}. Re-run 'aiwg index sync${graph === "project" ? "" : ` --graph ${graph}`}' or pass '--backend local' to use the legacy local index.`,
|
|
186
190
|
};
|
|
187
191
|
}
|
|
188
192
|
try {
|
|
@@ -949,8 +949,12 @@ export async function discoverCapability(cwd, params) {
|
|
|
949
949
|
continue;
|
|
950
950
|
}
|
|
951
951
|
}
|
|
952
|
-
if (loaded.reason)
|
|
952
|
+
if (loaded.reason) {
|
|
953
953
|
unavailableReason ??= loaded.reason;
|
|
954
|
+
if (graph === 'framework' && !params.graph) {
|
|
955
|
+
console.error(`Warning: framework capabilities are unavailable: ${loaded.reason}`);
|
|
956
|
+
}
|
|
957
|
+
}
|
|
954
958
|
entries.push(...loaded.entries.map((entry) => withIndexProvenance(entry, graph)));
|
|
955
959
|
const discovered = await queryFortemiCoreAiwgDiscovery(cwd, {
|
|
956
960
|
graph,
|
|
@@ -1171,7 +1175,7 @@ export async function discoverCapability(cwd, params) {
|
|
|
1171
1175
|
// broader phrase / type filter, and a capability refresh via `aiwg use`.
|
|
1172
1176
|
const emptyResultHint = scored.length === 0
|
|
1173
1177
|
? backend === 'fortemi-core'
|
|
1174
|
-
? `No capability matched "${params.phrase}" among ${entries.length} Fortemi Core static-cache capabilities. Try a broader phrase or a \`--type\` filter. If the local index changed, refresh the cache with \`aiwg index sync\`, or pass \`--backend local\` to use the legacy local index.`
|
|
1178
|
+
? `No capability matched "${params.phrase}" among ${entries.length} Fortemi Core static-cache capabilities. Try a broader phrase or a \`--type\` filter. If the local index changed, refresh the cache with \`aiwg index sync ${params.graph ? `--graph ${params.graph}` : '--all'}\`, or pass \`--backend local\` to use the legacy local index.`
|
|
1175
1179
|
: `No capability matched "${params.phrase}" among ${entries.length} indexed capabilities. Try a broader phrase or a \`--type\` filter. If you just installed or authored capabilities, refresh discovery with \`aiwg use <framework>\` (or \`aiwg index build\`).`
|
|
1176
1180
|
: null;
|
|
1177
1181
|
const includePaths = params.includePaths ?? true;
|
|
@@ -1272,7 +1276,9 @@ export async function discoverCapability(cwd, params) {
|
|
|
1272
1276
|
}
|
|
1273
1277
|
if (scored.length === 0) {
|
|
1274
1278
|
console.log(`No discovery matches for "${params.phrase}" in types: ${types.join(',')}.`);
|
|
1275
|
-
console.log(
|
|
1279
|
+
console.log(backend === 'fortemi-core'
|
|
1280
|
+
? emptyResultHint
|
|
1281
|
+
: 'Try a broader phrase or a `--type` filter. If capabilities were just added, refresh with `aiwg use <framework>` (or `aiwg index build`).');
|
|
1276
1282
|
return;
|
|
1277
1283
|
}
|
|
1278
1284
|
const relaxedNote = relaxed ? ' — relaxed match (verbose query)' : '';
|
|
@@ -1410,8 +1416,12 @@ async function loadShowEntries(cwd, params) {
|
|
|
1410
1416
|
continue;
|
|
1411
1417
|
}
|
|
1412
1418
|
}
|
|
1413
|
-
if (loaded.reason)
|
|
1419
|
+
if (loaded.reason) {
|
|
1414
1420
|
unavailableReason ??= loaded.reason;
|
|
1421
|
+
if (graph === 'framework' && !params.graph) {
|
|
1422
|
+
console.error(`Warning: framework capabilities are unavailable: ${loaded.reason}`);
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1415
1425
|
entries.push(...loaded.entries.map((entry) => withIndexProvenance(entry, graph)));
|
|
1416
1426
|
}
|
|
1417
1427
|
if (entries.length === 0 && unavailableReason) {
|
|
@@ -226,11 +226,18 @@ export async function runDecisionLoadHarness(options) {
|
|
|
226
226
|
export function compareDecisionLoadBounds(manifest, observations, resources) {
|
|
227
227
|
const bounds = manifest.bounds;
|
|
228
228
|
const atMost = (bound, observed) => ({ bound, limit: bounds[bound], observed, pass: observed <= bounds[bound] });
|
|
229
|
+
// The wall-clock fallback is process-wide (runner plus sibling workers), so it
|
|
230
|
+
// cannot bound harness CPU: it fails conforming code on shared runners. The
|
|
231
|
+
// manifest CPU bound only gates isolated thread-CPU measurement. The observed
|
|
232
|
+
// value stays in resources for informational use.
|
|
233
|
+
const cpu = resources.cpuSource === 'thread'
|
|
234
|
+
? [atMost('maximumCpuPercentOneCore', resources.cpuPercentOneCore)]
|
|
235
|
+
: [];
|
|
229
236
|
return [
|
|
230
237
|
atMost('maximumActiveCalls', observations.maximumActiveCalls),
|
|
231
238
|
atMost('maximumQueuedCalls', observations.maximumQueuedCalls),
|
|
232
239
|
atMost('maximumHeapUsedMiB', resources.heapUsedMiB),
|
|
233
|
-
|
|
240
|
+
...cpu,
|
|
234
241
|
atMost('maximumEligibleLaneWaitMs', observations.maximumEligibleLaneWaitMs),
|
|
235
242
|
atMost('maximumRetryAmplificationRatio', observations.retryAmplificationRatio),
|
|
236
243
|
atMost('maximumCancellationLatencyMs', observations.maximumCancellationLatencyMs),
|