truecourse 0.6.0-next.0 → 0.6.0-next.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +171 -168
- package/cli.mjs +80 -160
- package/package.json +1 -1
- package/public/assets/{index-agCyYXoU.js → index-CkKIAyL2.js} +1 -1
- package/public/index.html +1 -1
- package/server.mjs +13 -2
package/cli.mjs
CHANGED
|
@@ -128242,7 +128242,7 @@ function readToolVersion() {
|
|
|
128242
128242
|
if (cachedVersion)
|
|
128243
128243
|
return cachedVersion;
|
|
128244
128244
|
if (true) {
|
|
128245
|
-
cachedVersion = "0.6.0-next.
|
|
128245
|
+
cachedVersion = "0.6.0-next.2";
|
|
128246
128246
|
return cachedVersion;
|
|
128247
128247
|
}
|
|
128248
128248
|
try {
|
|
@@ -146142,6 +146142,10 @@ async function filterByRelevance(repoRoot5, docs, opts = {}) {
|
|
|
146142
146142
|
const manualSet = new Set(opts.manualIncludes ?? []);
|
|
146143
146143
|
const runner = opts.runner ?? spawnRelevanceRunner({ model: opts.model, fallbackModel: opts.fallbackModel });
|
|
146144
146144
|
const concurrency = opts.concurrency ?? 4;
|
|
146145
|
+
const total = docs.length;
|
|
146146
|
+
let done = 0;
|
|
146147
|
+
const markDone = () => opts.onProgress?.(++done, total);
|
|
146148
|
+
opts.onProgress?.(0, total);
|
|
146145
146149
|
const verdicts = /* @__PURE__ */ new Map();
|
|
146146
146150
|
let cursor = 0;
|
|
146147
146151
|
let active = 0;
|
|
@@ -146151,6 +146155,7 @@ async function filterByRelevance(repoRoot5, docs, opts = {}) {
|
|
|
146151
146155
|
const doc = docs[cursor++];
|
|
146152
146156
|
if (manualSet.has(doc.path)) {
|
|
146153
146157
|
verdicts.set(doc.path, { path: doc.path, include: true, reason: "manual include" });
|
|
146158
|
+
markDone();
|
|
146154
146159
|
if (cursor >= docs.length && active === 0)
|
|
146155
146160
|
resolve9();
|
|
146156
146161
|
continue;
|
|
@@ -146165,6 +146170,7 @@ async function filterByRelevance(repoRoot5, docs, opts = {}) {
|
|
|
146165
146170
|
reason: "classification failed; defaulting to include"
|
|
146166
146171
|
});
|
|
146167
146172
|
}).finally(() => {
|
|
146173
|
+
markDone();
|
|
146168
146174
|
active--;
|
|
146169
146175
|
if (cursor >= docs.length && active === 0)
|
|
146170
146176
|
resolve9();
|
|
@@ -146551,7 +146557,8 @@ async function consolidate(repoRoot5, opts = {}) {
|
|
|
146551
146557
|
enabled: opts.disableRelevanceFilter !== true,
|
|
146552
146558
|
manualIncludes: decisions.manualIncludes ?? [],
|
|
146553
146559
|
model: models.relevance,
|
|
146554
|
-
fallbackModel
|
|
146560
|
+
fallbackModel,
|
|
146561
|
+
onProgress: opts.onRelevanceProgress
|
|
146555
146562
|
});
|
|
146556
146563
|
const docs = relevance.included;
|
|
146557
146564
|
const skippedDocs = relevance.skipped.map(({ doc, reason }) => ({ path: doc.path, reason }));
|
|
@@ -148586,6 +148593,10 @@ async function scanInProcess(repoRoot5, options = {}) {
|
|
|
148586
148593
|
disableLlmChainDetection: options.disableLlmChainDetection,
|
|
148587
148594
|
skipGit: options.skipGit,
|
|
148588
148595
|
models: resolveConsolidateModels(repoRoot5),
|
|
148596
|
+
onRelevanceProgress: (doneCount, total) => {
|
|
148597
|
+
if (total > 0)
|
|
148598
|
+
tracker?.detail("discover", `${doneCount}/${total} docs`);
|
|
148599
|
+
},
|
|
148589
148600
|
onDocStart: () => {
|
|
148590
148601
|
if (!extractStarted) {
|
|
148591
148602
|
tracker?.done("discover");
|
|
@@ -149330,12 +149341,18 @@ async function runSpecScan(opts = {}) {
|
|
|
149330
149341
|
O2.message("Open conflicts:");
|
|
149331
149342
|
for (const c2 of merge2.openConflicts.slice(0, 10)) {
|
|
149332
149343
|
O2.message(` \u2022 ${c2.subject} (${c2.candidates.length} candidates, default: ${c2.candidates[c2.defaultPick].claim.provenance.file})`);
|
|
149344
|
+
O2.message(` id: ${c2.id}`);
|
|
149333
149345
|
}
|
|
149334
149346
|
if (merge2.openConflicts.length > 10) {
|
|
149335
|
-
O2.message(` \u2026 (+${merge2.openConflicts.length - 10} more)`);
|
|
149347
|
+
O2.message(` \u2026 (+${merge2.openConflicts.length - 10} more \u2014 run \`truecourse spec conflicts list\`)`);
|
|
149336
149348
|
}
|
|
149337
149349
|
O2.message("");
|
|
149338
|
-
O2.message("Resolve
|
|
149350
|
+
O2.message("Resolve them:");
|
|
149351
|
+
O2.message(" \u2022 dashboard: truecourse dashboard (Spec tab)");
|
|
149352
|
+
O2.message(" \u2022 per conflict: truecourse spec conflicts show <id>");
|
|
149353
|
+
O2.message(" truecourse spec conflicts pick <id> <candidateIndex>");
|
|
149354
|
+
O2.message(' truecourse spec conflicts custom <id> --text "\u2026"');
|
|
149355
|
+
O2.message(" \u2022 accept defaults: truecourse spec resolve --all-defaults");
|
|
149339
149356
|
}
|
|
149340
149357
|
gt(merge2.openConflicts.length === 0 ? "No open conflicts." : `${merge2.openConflicts.length} open.`);
|
|
149341
149358
|
} catch (e) {
|
|
@@ -149514,7 +149531,7 @@ function decisionsRelPath(root) {
|
|
|
149514
149531
|
init_dist4();
|
|
149515
149532
|
init_progress();
|
|
149516
149533
|
var repoRoot2 = (opts) => opts.cwd ?? process.cwd();
|
|
149517
|
-
async function loadScan(root
|
|
149534
|
+
async function loadScan(root) {
|
|
149518
149535
|
const cached = readScanState(root);
|
|
149519
149536
|
if (cached) {
|
|
149520
149537
|
return {
|
|
@@ -149522,16 +149539,6 @@ async function loadScan(root, json2) {
|
|
|
149522
149539
|
decided: cached.decidedConflicts
|
|
149523
149540
|
};
|
|
149524
149541
|
}
|
|
149525
|
-
if (json2) {
|
|
149526
|
-
const { consolidate: consolidate2 } = await scanInProcess(root, {});
|
|
149527
|
-
return {
|
|
149528
|
-
open: consolidate2.merge.openConflicts,
|
|
149529
|
-
decided: consolidate2.merge.decidedConflicts.map((d3) => ({
|
|
149530
|
-
conflict: d3.conflict,
|
|
149531
|
-
decision: d3.decision
|
|
149532
|
-
}))
|
|
149533
|
-
};
|
|
149534
|
-
}
|
|
149535
149542
|
const renderer = createStdoutStepRenderer();
|
|
149536
149543
|
const tracker = new StepTracker(renderer.onProgress, SCAN_STEPS.map((s) => ({ ...s })));
|
|
149537
149544
|
try {
|
|
@@ -149551,45 +149558,30 @@ async function loadScan(root, json2) {
|
|
|
149551
149558
|
}
|
|
149552
149559
|
async function runSpecConflictsList(opts = {}) {
|
|
149553
149560
|
const root = repoRoot2(opts);
|
|
149554
|
-
const scan = await loadScan(root
|
|
149561
|
+
const scan = await loadScan(root);
|
|
149555
149562
|
const open = scan.open.map(serializeConflict);
|
|
149556
149563
|
const decided = scan.decided.map((d3) => ({
|
|
149557
149564
|
conflict: serializeConflict(d3.conflict),
|
|
149558
149565
|
decision: d3.decision
|
|
149559
149566
|
}));
|
|
149560
|
-
if (opts.json) {
|
|
149561
|
-
const payload = opts.all ? { openConflicts: open, decidedConflicts: decided } : opts.decided ? { decidedConflicts: decided } : { openConflicts: open };
|
|
149562
|
-
process.stdout.write(JSON.stringify(payload, null, 2) + "\n");
|
|
149563
|
-
return;
|
|
149564
|
-
}
|
|
149565
149567
|
mt("Conflicts");
|
|
149566
149568
|
const which = opts.all ? "all" : opts.decided ? "decided" : "open";
|
|
149567
149569
|
const list = opts.all ? [...open, ...decided.map((d3) => d3.conflict)] : opts.decided ? decided.map((d3) => d3.conflict) : open;
|
|
149568
149570
|
O2.step(`${list.length} ${which} conflicts`);
|
|
149569
149571
|
for (const c2 of list) {
|
|
149570
|
-
O2.message(` \u2022 ${c2.id
|
|
149572
|
+
O2.message(` \u2022 ${c2.id} [${c2.topic}] ${c2.subject} (${c2.candidates.length} candidates)`);
|
|
149571
149573
|
}
|
|
149572
|
-
gt("Use `truecourse spec conflicts show <id
|
|
149574
|
+
gt("Use `truecourse spec conflicts show <id>` for full detail.");
|
|
149573
149575
|
}
|
|
149574
149576
|
async function runSpecConflictsShow(conflictId2, opts = {}) {
|
|
149575
149577
|
const root = repoRoot2(opts);
|
|
149576
|
-
const scan = await loadScan(root
|
|
149578
|
+
const scan = await loadScan(root);
|
|
149577
149579
|
const conflict = scan.open.find((c2) => c2.id === conflictId2) ?? scan.decided.find((d3) => d3.conflict.id === conflictId2)?.conflict;
|
|
149578
149580
|
if (!conflict) {
|
|
149579
|
-
if (opts.json) {
|
|
149580
|
-
process.stdout.write(JSON.stringify({ ok: false, error: `conflict ${conflictId2} not found` }, null, 2) + "\n");
|
|
149581
|
-
process.exit(1);
|
|
149582
|
-
}
|
|
149583
149581
|
pt(`Conflict ${conflictId2} not found.`);
|
|
149584
149582
|
process.exit(1);
|
|
149585
149583
|
}
|
|
149586
|
-
|
|
149587
|
-
const payload = { ...serializeConflict(conflict) };
|
|
149588
|
-
if (opts.diff) payload.fieldDifferences = computeFieldDifferences(conflict);
|
|
149589
|
-
process.stdout.write(JSON.stringify(payload, null, 2) + "\n");
|
|
149590
|
-
return;
|
|
149591
|
-
}
|
|
149592
|
-
mt(`Conflict ${conflict.id.slice(0, 12)}\u2026 \u2014 ${conflict.subject}`);
|
|
149584
|
+
mt(`Conflict ${conflict.id} \u2014 ${conflict.subject}`);
|
|
149593
149585
|
O2.step(`topic: ${conflict.topic}`);
|
|
149594
149586
|
if (conflict.explanation) O2.message(conflict.explanation);
|
|
149595
149587
|
O2.step(`${conflict.candidates.length} candidates (default-pick: ${conflict.defaultPick})`);
|
|
@@ -149617,13 +149609,12 @@ async function runSpecConflictsShow(conflictId2, opts = {}) {
|
|
|
149617
149609
|
}
|
|
149618
149610
|
async function runSpecConflictsPick(conflictId2, candidateIndex, opts = {}) {
|
|
149619
149611
|
const root = repoRoot2(opts);
|
|
149620
|
-
const scan = await loadScan(root
|
|
149612
|
+
const scan = await loadScan(root);
|
|
149621
149613
|
const conflict = scan.open.find((c2) => c2.id === conflictId2) ?? scan.decided.find((d3) => d3.conflict.id === conflictId2)?.conflict;
|
|
149622
|
-
if (!conflict) return failNotFound(conflictId2
|
|
149614
|
+
if (!conflict) return failNotFound(conflictId2);
|
|
149623
149615
|
if (!Number.isInteger(candidateIndex) || candidateIndex < 0 || candidateIndex >= conflict.candidates.length) {
|
|
149624
149616
|
return fail(
|
|
149625
|
-
`candidateIndex ${candidateIndex} out of range (0..${conflict.candidates.length - 1})
|
|
149626
|
-
!!opts.json
|
|
149617
|
+
`candidateIndex ${candidateIndex} out of range (0..${conflict.candidates.length - 1})`
|
|
149627
149618
|
);
|
|
149628
149619
|
}
|
|
149629
149620
|
upsertDecision(root, {
|
|
@@ -149632,36 +149623,30 @@ async function runSpecConflictsPick(conflictId2, candidateIndex, opts = {}) {
|
|
|
149632
149623
|
candidateFingerprint: candidateFingerprint(conflict),
|
|
149633
149624
|
note: opts.note
|
|
149634
149625
|
});
|
|
149635
|
-
await refreshScan(root
|
|
149636
|
-
emitOk(`Picked candidate ${candidateIndex} on ${conflictId2.slice(0, 12)}\u2026
|
|
149637
|
-
conflictId: conflictId2,
|
|
149638
|
-
resolution: { kind: "pick", candidateIndex }
|
|
149639
|
-
});
|
|
149626
|
+
await refreshScan(root);
|
|
149627
|
+
emitOk(`Picked candidate ${candidateIndex} on ${conflictId2.slice(0, 12)}\u2026`);
|
|
149640
149628
|
}
|
|
149641
149629
|
async function runSpecConflictsCustom(conflictId2, text, opts = {}) {
|
|
149642
149630
|
const root = repoRoot2(opts);
|
|
149643
|
-
const scan = await loadScan(root
|
|
149631
|
+
const scan = await loadScan(root);
|
|
149644
149632
|
const conflict = scan.open.find((c2) => c2.id === conflictId2) ?? scan.decided.find((d3) => d3.conflict.id === conflictId2)?.conflict;
|
|
149645
|
-
if (!conflict) return failNotFound(conflictId2
|
|
149633
|
+
if (!conflict) return failNotFound(conflictId2);
|
|
149646
149634
|
if (!text || !text.trim()) {
|
|
149647
|
-
return fail("--text must be a non-empty string"
|
|
149635
|
+
return fail("--text must be a non-empty string");
|
|
149648
149636
|
}
|
|
149649
149637
|
upsertDecision(root, {
|
|
149650
149638
|
conflictId: conflictId2,
|
|
149651
149639
|
resolution: { kind: "custom", content: text },
|
|
149652
149640
|
candidateFingerprint: candidateFingerprint(conflict)
|
|
149653
149641
|
});
|
|
149654
|
-
await refreshScan(root
|
|
149655
|
-
emitOk(`Wrote custom answer for ${conflictId2.slice(0, 12)}\u2026
|
|
149656
|
-
conflictId: conflictId2,
|
|
149657
|
-
resolution: { kind: "custom" }
|
|
149658
|
-
});
|
|
149642
|
+
await refreshScan(root);
|
|
149643
|
+
emitOk(`Wrote custom answer for ${conflictId2.slice(0, 12)}\u2026`);
|
|
149659
149644
|
}
|
|
149660
149645
|
async function runSpecConflictsRevoke(conflictId2, opts = {}) {
|
|
149661
149646
|
const root = repoRoot2(opts);
|
|
149662
149647
|
revokeDecision(root, conflictId2);
|
|
149663
|
-
await refreshScan(root
|
|
149664
|
-
emitOk(`Revoked decision for ${conflictId2.slice(0, 12)}\u2026
|
|
149648
|
+
await refreshScan(root);
|
|
149649
|
+
emitOk(`Revoked decision for ${conflictId2.slice(0, 12)}\u2026`);
|
|
149665
149650
|
}
|
|
149666
149651
|
function serializeConflict(c2) {
|
|
149667
149652
|
return {
|
|
@@ -149669,30 +149654,18 @@ function serializeConflict(c2) {
|
|
|
149669
149654
|
candidateFingerprint: candidateFingerprint(c2)
|
|
149670
149655
|
};
|
|
149671
149656
|
}
|
|
149672
|
-
async function refreshScan(root
|
|
149673
|
-
if (json2) {
|
|
149674
|
-
await scanInProcess(root, {});
|
|
149675
|
-
return;
|
|
149676
|
-
}
|
|
149657
|
+
async function refreshScan(root) {
|
|
149677
149658
|
await scanInProcess(root, {});
|
|
149678
149659
|
}
|
|
149679
|
-
function emitOk(msg
|
|
149680
|
-
if (json2) {
|
|
149681
|
-
process.stdout.write(JSON.stringify({ ok: true, ...payload }, null, 2) + "\n");
|
|
149682
|
-
return;
|
|
149683
|
-
}
|
|
149660
|
+
function emitOk(msg) {
|
|
149684
149661
|
gt(msg);
|
|
149685
149662
|
}
|
|
149686
|
-
function fail(msg
|
|
149687
|
-
if (json2) {
|
|
149688
|
-
process.stdout.write(JSON.stringify({ ok: false, error: msg }, null, 2) + "\n");
|
|
149689
|
-
process.exit(1);
|
|
149690
|
-
}
|
|
149663
|
+
function fail(msg) {
|
|
149691
149664
|
pt(msg);
|
|
149692
149665
|
process.exit(1);
|
|
149693
149666
|
}
|
|
149694
|
-
function failNotFound(id
|
|
149695
|
-
return fail(`conflict ${id} not found
|
|
149667
|
+
function failNotFound(id) {
|
|
149668
|
+
return fail(`conflict ${id} not found`);
|
|
149696
149669
|
}
|
|
149697
149670
|
function computeFieldDifferences(conflict) {
|
|
149698
149671
|
const out = [];
|
|
@@ -149761,10 +149734,6 @@ async function runSpecChainsList(opts = {}) {
|
|
|
149761
149734
|
const root = repoRoot3(opts);
|
|
149762
149735
|
const decisions = readDecisions(root);
|
|
149763
149736
|
const manual = decisions.manualChains ?? [];
|
|
149764
|
-
if (opts.json) {
|
|
149765
|
-
process.stdout.write(JSON.stringify({ manual }, null, 2) + "\n");
|
|
149766
|
-
return;
|
|
149767
|
-
}
|
|
149768
149737
|
mt("Manual chains");
|
|
149769
149738
|
if (manual.length === 0) O2.step("(none)");
|
|
149770
149739
|
for (const c2 of manual) {
|
|
@@ -149774,35 +149743,21 @@ async function runSpecChainsList(opts = {}) {
|
|
|
149774
149743
|
}
|
|
149775
149744
|
async function runSpecChainsAdd(opts) {
|
|
149776
149745
|
const root = repoRoot3(opts);
|
|
149777
|
-
if (opts.older === opts.newer) return fail2("older and newer must be different docs"
|
|
149746
|
+
if (opts.older === opts.newer) return fail2("older and newer must be different docs");
|
|
149778
149747
|
addManualChain(root, { older: opts.older, newer: opts.newer, note: opts.note });
|
|
149779
149748
|
await scanInProcess(root, {});
|
|
149780
|
-
emitOk2(`Marked ${opts.older} as superseded by ${opts.newer}
|
|
149781
|
-
older: opts.older,
|
|
149782
|
-
newer: opts.newer
|
|
149783
|
-
});
|
|
149749
|
+
emitOk2(`Marked ${opts.older} as superseded by ${opts.newer}`);
|
|
149784
149750
|
}
|
|
149785
149751
|
async function runSpecChainsRemove(opts) {
|
|
149786
149752
|
const root = repoRoot3(opts);
|
|
149787
149753
|
removeManualChain(root, { older: opts.older, newer: opts.newer });
|
|
149788
149754
|
await scanInProcess(root, {});
|
|
149789
|
-
emitOk2(`Removed chain ${opts.older} \u2192 ${opts.newer}
|
|
149790
|
-
older: opts.older,
|
|
149791
|
-
newer: opts.newer
|
|
149792
|
-
});
|
|
149755
|
+
emitOk2(`Removed chain ${opts.older} \u2192 ${opts.newer}`);
|
|
149793
149756
|
}
|
|
149794
|
-
function emitOk2(msg
|
|
149795
|
-
if (json2) {
|
|
149796
|
-
process.stdout.write(JSON.stringify({ ok: true, ...payload }, null, 2) + "\n");
|
|
149797
|
-
return;
|
|
149798
|
-
}
|
|
149757
|
+
function emitOk2(msg) {
|
|
149799
149758
|
gt(msg);
|
|
149800
149759
|
}
|
|
149801
|
-
function fail2(msg
|
|
149802
|
-
if (json2) {
|
|
149803
|
-
process.stdout.write(JSON.stringify({ ok: false, error: msg }, null, 2) + "\n");
|
|
149804
|
-
process.exit(1);
|
|
149805
|
-
}
|
|
149760
|
+
function fail2(msg) {
|
|
149806
149761
|
pt(msg);
|
|
149807
149762
|
process.exit(1);
|
|
149808
149763
|
}
|
|
@@ -149816,10 +149771,6 @@ async function runSpecDocsSkipped(opts = {}) {
|
|
|
149816
149771
|
const decisions = readDecisions(root);
|
|
149817
149772
|
const skipped = scan?.skippedDocs ?? [];
|
|
149818
149773
|
const manualIncludes = decisions.manualIncludes ?? [];
|
|
149819
|
-
if (opts.json) {
|
|
149820
|
-
process.stdout.write(JSON.stringify({ skipped, manualIncludes }, null, 2) + "\n");
|
|
149821
|
-
return;
|
|
149822
|
-
}
|
|
149823
149774
|
mt("Skipped docs");
|
|
149824
149775
|
if (skipped.length === 0) O2.step("(none)");
|
|
149825
149776
|
for (const s of skipped) {
|
|
@@ -149835,30 +149786,22 @@ async function runSpecDocsSkipped(opts = {}) {
|
|
|
149835
149786
|
}
|
|
149836
149787
|
async function runSpecDocsInclude(docPath, opts = {}) {
|
|
149837
149788
|
const root = repoRoot4(opts);
|
|
149838
|
-
if (!docPath) return fail3("Missing doc path"
|
|
149789
|
+
if (!docPath) return fail3("Missing doc path");
|
|
149839
149790
|
addManualInclude(root, docPath);
|
|
149840
149791
|
await scanInProcess(root, {});
|
|
149841
|
-
emitOk3(`Force-include ${docPath}
|
|
149792
|
+
emitOk3(`Force-include ${docPath}`);
|
|
149842
149793
|
}
|
|
149843
149794
|
async function runSpecDocsUninclude(docPath, opts = {}) {
|
|
149844
149795
|
const root = repoRoot4(opts);
|
|
149845
|
-
if (!docPath) return fail3("Missing doc path"
|
|
149796
|
+
if (!docPath) return fail3("Missing doc path");
|
|
149846
149797
|
removeManualInclude(root, docPath);
|
|
149847
149798
|
await scanInProcess(root, {});
|
|
149848
|
-
emitOk3(`Removed force-include for ${docPath}
|
|
149799
|
+
emitOk3(`Removed force-include for ${docPath}`);
|
|
149849
149800
|
}
|
|
149850
|
-
function emitOk3(msg
|
|
149851
|
-
if (json2) {
|
|
149852
|
-
process.stdout.write(JSON.stringify({ ok: true, ...payload }, null, 2) + "\n");
|
|
149853
|
-
return;
|
|
149854
|
-
}
|
|
149801
|
+
function emitOk3(msg) {
|
|
149855
149802
|
gt(msg);
|
|
149856
149803
|
}
|
|
149857
|
-
function fail3(msg
|
|
149858
|
-
if (json2) {
|
|
149859
|
-
process.stdout.write(JSON.stringify({ ok: false, error: msg }, null, 2) + "\n");
|
|
149860
|
-
process.exit(1);
|
|
149861
|
-
}
|
|
149804
|
+
function fail3(msg) {
|
|
149862
149805
|
pt(msg);
|
|
149863
149806
|
process.exit(1);
|
|
149864
149807
|
}
|
|
@@ -149887,26 +149830,6 @@ var SOURCE_LABEL = {
|
|
|
149887
149830
|
async function runConfigLlmShow(options = {}) {
|
|
149888
149831
|
const repoRoot5 = options.cwd ?? process.cwd();
|
|
149889
149832
|
const { stages, fallbackModel } = describeStageResolutions(repoRoot5);
|
|
149890
|
-
if (options.json) {
|
|
149891
|
-
process.stdout.write(
|
|
149892
|
-
JSON.stringify(
|
|
149893
|
-
{
|
|
149894
|
-
repoRoot: path56.relative(process.cwd(), repoRoot5) || ".",
|
|
149895
|
-
stages: stages.map((s) => ({
|
|
149896
|
-
stageId: s.stageId,
|
|
149897
|
-
effectiveModel: s.effectiveModel,
|
|
149898
|
-
defaultModel: STAGE_DEFAULTS[s.stageId],
|
|
149899
|
-
source: s.source,
|
|
149900
|
-
envVar: s.envVar ?? null
|
|
149901
|
-
})),
|
|
149902
|
-
fallbackModel
|
|
149903
|
-
},
|
|
149904
|
-
null,
|
|
149905
|
-
2
|
|
149906
|
-
) + "\n"
|
|
149907
|
-
);
|
|
149908
|
-
return;
|
|
149909
|
-
}
|
|
149910
149833
|
mt("LLM model resolution");
|
|
149911
149834
|
O2.info(`repoRoot ${path56.relative(process.cwd(), repoRoot5) || "."}`);
|
|
149912
149835
|
O2.info(`fallback ${fallbackModel ?? "(not configured)"}`);
|
|
@@ -152828,7 +152751,7 @@ async function runHooksRun() {
|
|
|
152828
152751
|
|
|
152829
152752
|
// tools/cli/src/index.ts
|
|
152830
152753
|
var program2 = new Command();
|
|
152831
|
-
program2.name("truecourse").version("0.6.0-next.
|
|
152754
|
+
program2.name("truecourse").version("0.6.0-next.2").description("TrueCourse CLI \u2014 analyze your repository and open the dashboard");
|
|
152832
152755
|
var dashboardCmd = program2.command("dashboard").description("Start the TrueCourse dashboard and open it in your browser").option("--reconfigure", "Re-prompt for console vs background service mode").option("--service", "Run as a background service (skips mode prompt)").option("--console", "Run in this terminal (skips mode prompt)").action(async (options) => {
|
|
152833
152756
|
if (options.service && options.console) {
|
|
152834
152757
|
console.error("error: --service and --console are mutually exclusive");
|
|
@@ -152902,55 +152825,52 @@ specCmd.command("status").description("Summary of docs, claims, modules, and pen
|
|
|
152902
152825
|
await runSpecStatus();
|
|
152903
152826
|
});
|
|
152904
152827
|
var conflictsCmd = specCmd.command("conflicts").description("Inspect and resolve open / decided conflicts (agent-friendly)");
|
|
152905
|
-
conflictsCmd.command("list").description("List conflicts (open by default; --decided or --all to widen)").option("--
|
|
152906
|
-
await runSpecConflictsList({
|
|
152828
|
+
conflictsCmd.command("list").description("List conflicts (open by default; --decided or --all to widen)").option("--decided", "Show decided conflicts instead of open").option("--all", "Show both open and decided conflicts").action(async (opts) => {
|
|
152829
|
+
await runSpecConflictsList({ decided: !!opts.decided, all: !!opts.all });
|
|
152907
152830
|
});
|
|
152908
|
-
conflictsCmd.command("show <id>").description("Show full detail for one conflict").option(
|
|
152831
|
+
conflictsCmd.command("show <id>").description("Show full detail for one conflict").option(
|
|
152909
152832
|
"--diff",
|
|
152910
152833
|
"Include precomputed field-level diffs (paths + values) between candidates"
|
|
152911
152834
|
).action(async (id, opts) => {
|
|
152912
|
-
await runSpecConflictsShow(id, {
|
|
152835
|
+
await runSpecConflictsShow(id, { diff: !!opts.diff });
|
|
152913
152836
|
});
|
|
152914
|
-
conflictsCmd.command("pick <id> <candidateIndex>").description("Resolve a conflict by picking one of its candidates").option("--note <text>", "Optional human-readable rationale").
|
|
152837
|
+
conflictsCmd.command("pick <id> <candidateIndex>").description("Resolve a conflict by picking one of its candidates").option("--note <text>", "Optional human-readable rationale").action(async (id, idx, opts) => {
|
|
152915
152838
|
await runSpecConflictsPick(id, parseInt(idx, 10), {
|
|
152916
|
-
note: opts.note
|
|
152917
|
-
json: !!opts.json
|
|
152839
|
+
note: opts.note
|
|
152918
152840
|
});
|
|
152919
152841
|
});
|
|
152920
|
-
conflictsCmd.command("custom <id>").description("Resolve a conflict with a free-text custom answer").requiredOption("--text <text>", "The authoritative content for this subject").
|
|
152921
|
-
await runSpecConflictsCustom(id, opts.text
|
|
152842
|
+
conflictsCmd.command("custom <id>").description("Resolve a conflict with a free-text custom answer").requiredOption("--text <text>", "The authoritative content for this subject").action(async (id, opts) => {
|
|
152843
|
+
await runSpecConflictsCustom(id, opts.text);
|
|
152922
152844
|
});
|
|
152923
|
-
conflictsCmd.command("revoke <id>").description("Remove a previously-saved decision (the conflict re-opens)").
|
|
152924
|
-
await runSpecConflictsRevoke(id
|
|
152845
|
+
conflictsCmd.command("revoke <id>").description("Remove a previously-saved decision (the conflict re-opens)").action(async (id) => {
|
|
152846
|
+
await runSpecConflictsRevoke(id);
|
|
152925
152847
|
});
|
|
152926
152848
|
var chainsCmd = specCmd.command("chains").description("Manage manual version chains (supersession overrides)");
|
|
152927
|
-
chainsCmd.command("list").description("List manual chains").
|
|
152928
|
-
await runSpecChainsList(
|
|
152849
|
+
chainsCmd.command("list").description("List manual chains").action(async () => {
|
|
152850
|
+
await runSpecChainsList();
|
|
152929
152851
|
});
|
|
152930
|
-
chainsCmd.command("add").description("Mark `older` as superseded by `newer`").requiredOption("--older <path>", "Repo-relative path of the older doc").requiredOption("--newer <path>", "Repo-relative path of the newer doc").option("--note <text>", "Optional rationale").
|
|
152852
|
+
chainsCmd.command("add").description("Mark `older` as superseded by `newer`").requiredOption("--older <path>", "Repo-relative path of the older doc").requiredOption("--newer <path>", "Repo-relative path of the newer doc").option("--note <text>", "Optional rationale").action(async (opts) => {
|
|
152931
152853
|
await runSpecChainsAdd({
|
|
152932
152854
|
older: opts.older,
|
|
152933
152855
|
newer: opts.newer,
|
|
152934
|
-
note: opts.note
|
|
152935
|
-
json: !!opts.json
|
|
152856
|
+
note: opts.note
|
|
152936
152857
|
});
|
|
152937
152858
|
});
|
|
152938
|
-
chainsCmd.command("remove").description("Remove a manual chain").requiredOption("--older <path>", "Repo-relative path of the older doc").requiredOption("--newer <path>", "Repo-relative path of the newer doc").
|
|
152859
|
+
chainsCmd.command("remove").description("Remove a manual chain").requiredOption("--older <path>", "Repo-relative path of the older doc").requiredOption("--newer <path>", "Repo-relative path of the newer doc").action(async (opts) => {
|
|
152939
152860
|
await runSpecChainsRemove({
|
|
152940
152861
|
older: opts.older,
|
|
152941
|
-
newer: opts.newer
|
|
152942
|
-
json: !!opts.json
|
|
152862
|
+
newer: opts.newer
|
|
152943
152863
|
});
|
|
152944
152864
|
});
|
|
152945
152865
|
var docsCmd = specCmd.command("docs").description("Manage LLM relevance-filter overrides (skipped docs)");
|
|
152946
|
-
docsCmd.command("skipped").description("List docs the relevance filter excluded from extraction").
|
|
152947
|
-
await runSpecDocsSkipped(
|
|
152866
|
+
docsCmd.command("skipped").description("List docs the relevance filter excluded from extraction").action(async () => {
|
|
152867
|
+
await runSpecDocsSkipped();
|
|
152948
152868
|
});
|
|
152949
|
-
docsCmd.command("include <path>").description("Force-include a skipped doc and re-scan").
|
|
152950
|
-
await runSpecDocsInclude(docPath
|
|
152869
|
+
docsCmd.command("include <path>").description("Force-include a skipped doc and re-scan").action(async (docPath) => {
|
|
152870
|
+
await runSpecDocsInclude(docPath);
|
|
152951
152871
|
});
|
|
152952
|
-
docsCmd.command("uninclude <path>").description("Remove a force-include override").
|
|
152953
|
-
await runSpecDocsUninclude(docPath
|
|
152872
|
+
docsCmd.command("uninclude <path>").description("Remove a force-include override").action(async (docPath) => {
|
|
152873
|
+
await runSpecDocsUninclude(docPath);
|
|
152954
152874
|
});
|
|
152955
152875
|
program2.command("verify").description("Compare code against the canonical TC contracts").option("--code-dir <path>", "Override the code directory (default: auto-detect)").option("--diff", "Diff current drifts against the committed LATEST baseline").option("--stash", "Pre-approve stashing pending changes (verify committed state)").option("--no-stash", "Verify the working tree as-is without stashing").action(async (options) => {
|
|
152956
152876
|
await runVerify({ codeDir: options.codeDir, diff: options.diff, stash: options.stash });
|
|
@@ -152979,8 +152899,8 @@ rulesCmd.command("reset [ruleKey]").description("Clear per-rule overrides (one r
|
|
|
152979
152899
|
});
|
|
152980
152900
|
var configCmd = program2.command("config").description("Inspect per-repo TrueCourse configuration");
|
|
152981
152901
|
var configLlmCmd = configCmd.command("llm").description("LLM model configuration for the current repo");
|
|
152982
|
-
configLlmCmd.command("show").description("Print the effective model resolution for every pipeline stage").
|
|
152983
|
-
await runConfigLlmShow(
|
|
152902
|
+
configLlmCmd.command("show").description("Print the effective model resolution for every pipeline stage").action(async () => {
|
|
152903
|
+
await runConfigLlmShow();
|
|
152984
152904
|
});
|
|
152985
152905
|
var telemetryCmd = program2.command("telemetry").description("Manage anonymous usage telemetry");
|
|
152986
152906
|
telemetryCmd.command("enable").description("Enable anonymous usage telemetry").action(() => {
|