fix(headless-triage): --run takes precedence over --json/--list
Discovered via dogfood: \`sf headless triage --run --json\` short- circuited to the candidate-list JSON before reaching the dispatch path, so the run never happened. --run is the action; --json/--list describe output format. Restructure so --run always dispatches; --json then controls whether the run result is JSON vs human text. Without --run, --json/--list still emit the candidate digest as before. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
65c1914b1f
commit
a6c36a4b6b
1 changed files with 38 additions and 30 deletions
|
|
@ -156,41 +156,49 @@ export async function handleTriage(
|
|||
return { exitCode: 0 };
|
||||
}
|
||||
|
||||
if (options.json) {
|
||||
process.stdout.write(
|
||||
`${JSON.stringify({
|
||||
ok: true,
|
||||
count: candidates.length,
|
||||
candidates: candidates.map((c) => ({
|
||||
id: c.id,
|
||||
kind: c.kind,
|
||||
severity: c.severity,
|
||||
summary: c.summary,
|
||||
ts: c.ts,
|
||||
impact: c.impactScore ?? null,
|
||||
effort: c.effortEstimate ?? null,
|
||||
})),
|
||||
})}\n`,
|
||||
);
|
||||
return { exitCode: 0 };
|
||||
}
|
||||
|
||||
if (options.list) {
|
||||
process.stdout.write(
|
||||
`${candidates.length} candidate${candidates.length === 1 ? "" : "s"} (priority: impact↓ effort↑ ts↑)\n\n`,
|
||||
);
|
||||
for (const c of candidates) {
|
||||
const impact = c.impactScore != null ? `i${c.impactScore}` : "i?";
|
||||
const effort = c.effortEstimate != null ? `e${c.effortEstimate}` : "e?";
|
||||
// --run takes precedence over --json/--list because they describe the
|
||||
// OUTPUT FORMAT, not the action. With --run, --json controls whether
|
||||
// the run-result is JSON vs. human text. Without --run, --json emits
|
||||
// the candidate digest as JSON (the inspect path).
|
||||
if (!options.run) {
|
||||
if (options.json) {
|
||||
process.stdout.write(
|
||||
` [${c.severity}] ${impact} ${effort} ${c.id} ${c.kind}\n`,
|
||||
`${JSON.stringify({
|
||||
ok: true,
|
||||
count: candidates.length,
|
||||
candidates: candidates.map((c) => ({
|
||||
id: c.id,
|
||||
kind: c.kind,
|
||||
severity: c.severity,
|
||||
summary: c.summary,
|
||||
ts: c.ts,
|
||||
impact: c.impactScore ?? null,
|
||||
effort: c.effortEstimate ?? null,
|
||||
})),
|
||||
})}\n`,
|
||||
);
|
||||
process.stdout.write(` ${c.summary}\n`);
|
||||
return { exitCode: 0 };
|
||||
}
|
||||
|
||||
if (options.list) {
|
||||
process.stdout.write(
|
||||
`${candidates.length} candidate${candidates.length === 1 ? "" : "s"} (priority: impact↓ effort↑ ts↑)\n\n`,
|
||||
);
|
||||
for (const c of candidates) {
|
||||
const impact = c.impactScore != null ? `i${c.impactScore}` : "i?";
|
||||
const effort =
|
||||
c.effortEstimate != null ? `e${c.effortEstimate}` : "e?";
|
||||
process.stdout.write(
|
||||
` [${c.severity}] ${impact} ${effort} ${c.id} ${c.kind}\n`,
|
||||
);
|
||||
process.stdout.write(` ${c.summary}\n`);
|
||||
}
|
||||
return { exitCode: 0 };
|
||||
}
|
||||
return { exitCode: 0 };
|
||||
}
|
||||
|
||||
// Default: emit the canonical triage prompt for piping into a model.
|
||||
// Render the canonical triage prompt (used by both the default
|
||||
// pipe-to-model output and the --run dispatch path below).
|
||||
let prompt: string;
|
||||
try {
|
||||
prompt = drainModule.buildInlineFixPrompt(candidates);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue