Initial commit: pygenium as git submodule

This commit is contained in:
2026-08-07 14:54:45 -04:00
commit 581436ed23
61 changed files with 9331 additions and 0 deletions

83
src/phases.ts Normal file
View File

@@ -0,0 +1,83 @@
/**
* phases.ts — phase-strip status UI helper.
*
* Renders the active phase of a check run into pi's footer status bar and
* forwards plain-text progress lines to stdout (so `print` mode `-p` also
* shows progress). The strip is a small, self-contained adapter over
* `ExtensionUIContext.setStatus` — simplified from piolium's phase-strip
* command UI to the subset pygienium needs: a status key, the current phase,
* and a clear on completion.
*
* @module pygienium/phases
*/
import type { ExtensionUIContext } from "@earendil-works/pi-coding-agent";
/** Phase display metadata for a check run's phases. */
export const PHASE_LABELS: Record<string, string> = {
recon: "Recon",
analysis: "Scanning",
fix: "Fixing",
verify: "Verifying",
cleanup: "Cleaning up",
};
export interface PhaseStripOptions {
/** Footer status key (defaults to "pygienium"). */
statusKey?: string;
/** Check label shown alongside the phase, e.g. "comments". */
checkLabel?: string;
/** Whether dialog-capable UI is available. */
hasUI?: boolean;
/** UI context to drive the footer status bar. */
ui?: ExtensionUIContext;
}
/**
* A handle that renders phase progress and clears on completion. Created by
* {@link createPhaseStrip}; pass the result to the check-runner.
*/
export interface PhaseStrip {
/** Set the current phase id (e.g. "analysis"). */
setPhase(phaseId: string): void;
/** Append a plain-text progress line (forwarded to stdout). */
log(line: string): void;
/** Clear the footer status bar. Call once the run is terminal. */
done(): void;
}
/** Create a phase-strip UI adapter. */
export function createPhaseStrip(opts: PhaseStripOptions): PhaseStrip {
const statusKey = opts.statusKey ?? "pygienium";
const ui = opts.ui;
const hasUI = opts.hasUI ?? false;
const checkLabel = opts.checkLabel;
function render(phaseId: string): string {
const label = PHASE_LABELS[phaseId] ?? phaseId;
return checkLabel
? `pygienium ${checkLabel}: ${label}`
: `pygienium: ${label}`;
}
return {
setPhase(phaseId) {
const text = render(phaseId);
if (hasUI && ui?.setStatus) {
ui.setStatus(statusKey, text);
}
// In print/json modes (no TUI) write progress to stdout. In TUI mode
// the status bar is the render surface — raw stdout writes would splice
// into the ink renderer, so they are suppressed.
if (!hasUI) process.stdout.write(`${text}\n`);
},
log(line) {
if (!hasUI) process.stdout.write(`${line}\n`);
},
done() {
if (hasUI && ui?.setStatus) {
ui.setStatus(statusKey, undefined);
}
},
};
}