@siuver/omp-debug-mode 0.1.3 → 0.1.4
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/CHANGELOG.md +7 -0
- package/README.md +133 -94
- package/package.json +3 -3
- package/src/debug-mode.ts +215 -105
- package/src/evidence.ts +196 -0
- package/src/gate.ts +32 -14
- package/src/methodology.ts +80 -32
- package/src/state.ts +96 -3
- package/src/tools.ts +58 -0
- package/src/ui.ts +41 -16
- package/src/review-actions.ts +0 -22
package/src/ui.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import type { ExtensionContext } from "@oh-my-pi/pi-coding-agent";
|
|
2
2
|
import { PROCEED_REMINDER } from "./methodology";
|
|
3
|
-
import type { DebugState } from "./state";
|
|
3
|
+
import type { DebugState, EvidenceRequest } from "./state";
|
|
4
|
+
import { pendingEvidenceRequests } from "./state";
|
|
4
5
|
|
|
5
|
-
/** `setWidget` caps string-array widgets at 10 lines. */
|
|
6
6
|
export const WIDGET_MAX_LINES = 10;
|
|
7
|
-
const WIDGET_MAX_STEPS = 6;
|
|
8
7
|
const WIDGET_MAX_WIDTH = 90;
|
|
9
8
|
|
|
10
9
|
export type WidgetTone = "accent" | "dim";
|
|
@@ -24,6 +23,13 @@ function clip(text: string): string {
|
|
|
24
23
|
return text.length > WIDGET_MAX_WIDTH ? `${text.slice(0, WIDGET_MAX_WIDTH - 1)}…` : text;
|
|
25
24
|
}
|
|
26
25
|
|
|
26
|
+
/** The command surface is the only interaction path at the gate. */
|
|
27
|
+
const COMMAND_LINES = [
|
|
28
|
+
"/debug-proceed [details]",
|
|
29
|
+
"/debug-evidence <request-id> <path>",
|
|
30
|
+
"/debug-done · /debug-abort · /debug-status",
|
|
31
|
+
] as const;
|
|
32
|
+
|
|
27
33
|
function plural(count: number, singular: string): string {
|
|
28
34
|
return `${count} ${singular}${count === 1 ? "" : "s"}`;
|
|
29
35
|
}
|
|
@@ -33,27 +39,46 @@ function logEntries(count: number): string {
|
|
|
33
39
|
}
|
|
34
40
|
|
|
35
41
|
/**
|
|
36
|
-
* Reproduction-gate widget: the call to action,
|
|
37
|
-
* reproduction
|
|
38
|
-
*
|
|
42
|
+
* Reproduction-gate widget: the call to action, pending user evidence,
|
|
43
|
+
* reproduction-step context, the command surface, and the live evidence
|
|
44
|
+
* counter. Commands are the only interaction path — there is no menu. The
|
|
45
|
+
* live log counter is always the final line within the host's line budget.
|
|
39
46
|
*/
|
|
40
|
-
export function waitingWidgetLines(
|
|
47
|
+
export function waitingWidgetLines(
|
|
48
|
+
state: DebugState,
|
|
49
|
+
logCount: number,
|
|
50
|
+
pendingEvidence: EvidenceRequest[] = pendingEvidenceRequests(state, state.round),
|
|
51
|
+
): WidgetLine[] {
|
|
41
52
|
const lines: WidgetLine[] = [{ text: PROCEED_REMINDER, tone: "accent" }];
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
53
|
+
for (const request of pendingEvidence.slice(0, 2)) {
|
|
54
|
+
lines.push({ text: clip(`↪ ${request.id} ${request.title}: ${request.instructions[0] ?? ""}`), tone: "accent" });
|
|
55
|
+
}
|
|
56
|
+
for (const command of COMMAND_LINES) lines.push({ text: command, tone: "accent" });
|
|
57
|
+
|
|
58
|
+
// Reproduction details are useful context, but command discoverability and
|
|
59
|
+
// the live log counter must survive the host's ten-line widget limit.
|
|
60
|
+
const reserved = lines.length + 2;
|
|
61
|
+
const stepBudget = Math.max(0, WIDGET_MAX_LINES - reserved);
|
|
62
|
+
if (stepBudget > 0 && state.reproductionSteps.length > 0) {
|
|
63
|
+
const showMoreLine = state.reproductionSteps.length > stepBudget;
|
|
64
|
+
const shownCount = showMoreLine ? Math.max(0, stepBudget - 1) : stepBudget;
|
|
65
|
+
for (const step of state.reproductionSteps.slice(0, shownCount)) {
|
|
66
|
+
lines.push({ text: clip(step), tone: "dim" });
|
|
67
|
+
}
|
|
68
|
+
const hidden = state.reproductionSteps.length - shownCount;
|
|
69
|
+
if (hidden > 0) lines.push({ text: `… +${plural(hidden, "more step")} in the transcript`, tone: "dim" });
|
|
70
|
+
}
|
|
46
71
|
lines.push({
|
|
47
|
-
text:
|
|
72
|
+
text: `evidence: ${plural(pendingEvidence.length, "pending request")}, ${plural(state.evidenceArtifacts.length, "attached artifact")}`,
|
|
73
|
+
tone: pendingEvidence.length > 0 || state.evidenceArtifacts.length > 0 ? "accent" : "dim",
|
|
74
|
+
});
|
|
75
|
+
lines.push({
|
|
76
|
+
text: `run ${state.runId ?? "none"} — ${logEntries(logCount)}`,
|
|
48
77
|
tone: logCount > 0 ? "accent" : "dim",
|
|
49
78
|
});
|
|
50
79
|
return lines.slice(0, WIDGET_MAX_LINES);
|
|
51
80
|
}
|
|
52
81
|
|
|
53
|
-
export function reviewMenuTitle(round: number, logCount: number, probeCount: number): string {
|
|
54
|
-
return `Review debug round ${round} · ${logEntries(logCount)} · ${plural(probeCount, "probe")}`;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
82
|
/**
|
|
58
83
|
* Render the status entry and the reproduction widget. `getLogCount` is only
|
|
59
84
|
* consulted at the reproduction gate so idle phases do not touch the log files.
|
package/src/review-actions.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
export const REVIEW_MARK_FIXED = "Mark as fixed";
|
|
2
|
-
export const REVIEW_PROCEED = "Proceed";
|
|
3
|
-
export const REVIEW_ADD_DETAILS = "Add reproduction details";
|
|
4
|
-
export const REVIEW_ABORT = "Abort debug mode";
|
|
5
|
-
|
|
6
|
-
export const REVIEW_OPTIONS = [
|
|
7
|
-
REVIEW_MARK_FIXED,
|
|
8
|
-
REVIEW_PROCEED,
|
|
9
|
-
REVIEW_ADD_DETAILS,
|
|
10
|
-
REVIEW_ABORT,
|
|
11
|
-
] as const;
|
|
12
|
-
|
|
13
|
-
export const REVIEW_DESCRIPTIONS: Record<string, string> = {
|
|
14
|
-
[REVIEW_MARK_FIXED]: "Remove every probe and summarize the root cause",
|
|
15
|
-
[REVIEW_PROCEED]: "Read the captured logs, judge each hypothesis, continue",
|
|
16
|
-
[REVIEW_ADD_DETAILS]: "Describe what you observed before continuing",
|
|
17
|
-
[REVIEW_ABORT]: "Stop debugging and delete the logs; code changes stay",
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
export function reviewMenuOptions(): { label: string; description: string }[] {
|
|
21
|
-
return REVIEW_OPTIONS.map(label => ({ label, description: REVIEW_DESCRIPTIONS[label] ?? "" }));
|
|
22
|
-
}
|