pi-mission-control 0.0.0-dev
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 +205 -0
- package/agents/auditor.md +45 -0
- package/agents/worker.md +44 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +526 -0
- package/dist/index.js.map +1 -0
- package/dist/state.d.ts +265 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +474 -0
- package/dist/state.js.map +1 -0
- package/dist/tools/add-phase.d.ts +28 -0
- package/dist/tools/add-phase.d.ts.map +1 -0
- package/dist/tools/add-phase.js +69 -0
- package/dist/tools/add-phase.js.map +1 -0
- package/dist/tools/add-task.d.ts +30 -0
- package/dist/tools/add-task.d.ts.map +1 -0
- package/dist/tools/add-task.js +85 -0
- package/dist/tools/add-task.js.map +1 -0
- package/dist/tools/index.d.ts +13 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +16 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/init.d.ts +34 -0
- package/dist/tools/init.d.ts.map +1 -0
- package/dist/tools/init.js +75 -0
- package/dist/tools/init.js.map +1 -0
- package/dist/tools/mission-complete.d.ts +30 -0
- package/dist/tools/mission-complete.d.ts.map +1 -0
- package/dist/tools/mission-complete.js +85 -0
- package/dist/tools/mission-complete.js.map +1 -0
- package/dist/tools/mission-resume.d.ts +35 -0
- package/dist/tools/mission-resume.d.ts.map +1 -0
- package/dist/tools/mission-resume.js +87 -0
- package/dist/tools/mission-resume.js.map +1 -0
- package/dist/tools/scaffold.d.ts +24 -0
- package/dist/tools/scaffold.d.ts.map +1 -0
- package/dist/tools/scaffold.js +129 -0
- package/dist/tools/scaffold.js.map +1 -0
- package/dist/tools/update-phase.d.ts +33 -0
- package/dist/tools/update-phase.d.ts.map +1 -0
- package/dist/tools/update-phase.js +101 -0
- package/dist/tools/update-phase.js.map +1 -0
- package/dist/tools/update-task.d.ts +34 -0
- package/dist/tools/update-task.d.ts.map +1 -0
- package/dist/tools/update-task.js +104 -0
- package/dist/tools/update-task.js.map +1 -0
- package/dist/tui/dashboard.d.ts +146 -0
- package/dist/tui/dashboard.d.ts.map +1 -0
- package/dist/tui/dashboard.js +381 -0
- package/dist/tui/dashboard.js.map +1 -0
- package/dist/tui/header.d.ts +39 -0
- package/dist/tui/header.d.ts.map +1 -0
- package/dist/tui/header.js +62 -0
- package/dist/tui/header.js.map +1 -0
- package/dist/tui/idle-view.d.ts +44 -0
- package/dist/tui/idle-view.d.ts.map +1 -0
- package/dist/tui/idle-view.js +87 -0
- package/dist/tui/idle-view.js.map +1 -0
- package/dist/tui/index.d.ts +13 -0
- package/dist/tui/index.d.ts.map +1 -0
- package/dist/tui/index.js +15 -0
- package/dist/tui/index.js.map +1 -0
- package/dist/tui/past-runs.d.ts +49 -0
- package/dist/tui/past-runs.d.ts.map +1 -0
- package/dist/tui/past-runs.js +207 -0
- package/dist/tui/past-runs.js.map +1 -0
- package/dist/tui/phases-panel.d.ts +46 -0
- package/dist/tui/phases-panel.d.ts.map +1 -0
- package/dist/tui/phases-panel.js +161 -0
- package/dist/tui/phases-panel.js.map +1 -0
- package/dist/tui/progress-bar.d.ts +37 -0
- package/dist/tui/progress-bar.d.ts.map +1 -0
- package/dist/tui/progress-bar.js +123 -0
- package/dist/tui/progress-bar.js.map +1 -0
- package/dist/tui/styles.d.ts +8 -0
- package/dist/tui/styles.d.ts.map +1 -0
- package/dist/tui/styles.js +22 -0
- package/dist/tui/styles.js.map +1 -0
- package/dist/tui/tasks-panel.d.ts +48 -0
- package/dist/tui/tasks-panel.d.ts.map +1 -0
- package/dist/tui/tasks-panel.js +191 -0
- package/dist/tui/tasks-panel.js.map +1 -0
- package/package.json +42 -0
- package/skills/mission-memory/SKILL.md +88 -0
- package/skills/mission-orchestrator/SKILL.md +167 -0
- package/skills/mission-pm/SKILL.md +83 -0
- package/skills/mission-research/SKILL.md +66 -0
- package/skills/mission-tech-lead/SKILL.md +68 -0
- package/src/index.ts +659 -0
- package/src/state.ts +623 -0
- package/src/tools/add-phase.ts +98 -0
- package/src/tools/add-task.ts +121 -0
- package/src/tools/index.ts +18 -0
- package/src/tools/init.ts +109 -0
- package/src/tools/mission-complete.ts +118 -0
- package/src/tools/mission-resume.ts +119 -0
- package/src/tools/scaffold.ts +167 -0
- package/src/tools/update-phase.ts +140 -0
- package/src/tools/update-task.ts +145 -0
- package/src/tui/dashboard.ts +441 -0
- package/src/tui/header.ts +85 -0
- package/src/tui/idle-view.ts +114 -0
- package/src/tui/index.ts +20 -0
- package/src/tui/past-runs.ts +261 -0
- package/src/tui/phases-panel.ts +199 -0
- package/src/tui/progress-bar.ts +152 -0
- package/src/tui/styles.ts +27 -0
- package/src/tui/tasks-panel.ts +228 -0
- package/templates/state.json +5 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mission Control TUI Progress Bar
|
|
3
|
+
*
|
|
4
|
+
* Bottom bar displaying:
|
|
5
|
+
* - Visual progress bar using block characters
|
|
6
|
+
* - Percentage completion
|
|
7
|
+
* - Task count (completed/total)
|
|
8
|
+
*
|
|
9
|
+
* Block characters for progress bar:
|
|
10
|
+
* - Full: \u2588 (█)
|
|
11
|
+
* - Empty: \u2591 (░)
|
|
12
|
+
*/
|
|
13
|
+
import { truncateToWidth } from "@mariozechner/pi-tui";
|
|
14
|
+
// Block characters for progress bar
|
|
15
|
+
const BLOCK_FULL = "\u2588"; // █
|
|
16
|
+
const BLOCK_EMPTY = "\u2591"; // ░
|
|
17
|
+
/**
|
|
18
|
+
* Count completed and total tasks across all phases
|
|
19
|
+
*/
|
|
20
|
+
function countTasks(run) {
|
|
21
|
+
let completed = 0;
|
|
22
|
+
let total = 0;
|
|
23
|
+
let phaseCompleted = 0;
|
|
24
|
+
let phaseTotal = run.phases.length;
|
|
25
|
+
for (const phase of run.phases) {
|
|
26
|
+
if (phase.status === "done") {
|
|
27
|
+
phaseCompleted++;
|
|
28
|
+
}
|
|
29
|
+
for (const task of phase.tasks) {
|
|
30
|
+
if (task.status === "removed")
|
|
31
|
+
continue;
|
|
32
|
+
total++;
|
|
33
|
+
if (task.status === "done") {
|
|
34
|
+
completed++;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return { completed, total, phaseCompleted, phaseTotal };
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Render a progress bar string
|
|
42
|
+
*/
|
|
43
|
+
function renderProgressBar(percent, width) {
|
|
44
|
+
if (width < 3)
|
|
45
|
+
return "";
|
|
46
|
+
const filled = Math.round((percent / 100) * width);
|
|
47
|
+
const empty = width - filled;
|
|
48
|
+
return BLOCK_FULL.repeat(filled) + BLOCK_EMPTY.repeat(empty);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Render the progress bar component
|
|
52
|
+
*/
|
|
53
|
+
export function renderProgressBarComponent(width, props, theme) {
|
|
54
|
+
const { run } = props;
|
|
55
|
+
const lines = [];
|
|
56
|
+
if (!run || run.phases.length === 0) {
|
|
57
|
+
const suffix = "[0/0 Tasks]";
|
|
58
|
+
const progressBar = renderProgressBar(0, Math.max(0, width - suffix.length - 4));
|
|
59
|
+
lines.push(truncateToWidth(theme.fg("muted", `[${progressBar}] ${suffix}`), width));
|
|
60
|
+
return lines;
|
|
61
|
+
}
|
|
62
|
+
// Count tasks
|
|
63
|
+
const { completed, total } = countTasks(run);
|
|
64
|
+
const percent = total > 0 ? Math.round((completed / total) * 100) : 0;
|
|
65
|
+
const suffix = `[${completed}/${total} Tasks]`;
|
|
66
|
+
const barWidth = Math.max(0, width - suffix.length - 4);
|
|
67
|
+
const progressBar = renderProgressBar(percent, barWidth);
|
|
68
|
+
lines.push(truncateToWidth(theme.fg("accent", `[${progressBar}] ${suffix}`), width));
|
|
69
|
+
return lines;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Progress bar component class
|
|
73
|
+
*/
|
|
74
|
+
export class ProgressBarComponent {
|
|
75
|
+
props;
|
|
76
|
+
cachedWidth;
|
|
77
|
+
cachedLines;
|
|
78
|
+
constructor(run = null, statusMessage = "") {
|
|
79
|
+
this.props = { run, statusMessage };
|
|
80
|
+
}
|
|
81
|
+
update(run, statusMessage) {
|
|
82
|
+
this.props.run = run;
|
|
83
|
+
if (statusMessage !== undefined) {
|
|
84
|
+
this.props.statusMessage = statusMessage;
|
|
85
|
+
}
|
|
86
|
+
this.invalidate();
|
|
87
|
+
}
|
|
88
|
+
updateStatus(message) {
|
|
89
|
+
this.props.statusMessage = message;
|
|
90
|
+
this.invalidate();
|
|
91
|
+
}
|
|
92
|
+
getCompletionPercent() {
|
|
93
|
+
const { run } = this.props;
|
|
94
|
+
if (!run)
|
|
95
|
+
return 0;
|
|
96
|
+
let completed = 0;
|
|
97
|
+
let total = 0;
|
|
98
|
+
for (const phase of run.phases) {
|
|
99
|
+
for (const task of phase.tasks) {
|
|
100
|
+
if (task.status === "removed")
|
|
101
|
+
continue;
|
|
102
|
+
total++;
|
|
103
|
+
if (task.status === "done") {
|
|
104
|
+
completed++;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return total > 0 ? Math.round((completed / total) * 100) : 0;
|
|
109
|
+
}
|
|
110
|
+
render(width, theme) {
|
|
111
|
+
if (this.cachedLines && this.cachedWidth === width) {
|
|
112
|
+
return this.cachedLines;
|
|
113
|
+
}
|
|
114
|
+
this.cachedLines = renderProgressBarComponent(width, this.props, theme);
|
|
115
|
+
this.cachedWidth = width;
|
|
116
|
+
return this.cachedLines;
|
|
117
|
+
}
|
|
118
|
+
invalidate() {
|
|
119
|
+
this.cachedWidth = undefined;
|
|
120
|
+
this.cachedLines = undefined;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=progress-bar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress-bar.js","sourceRoot":"","sources":["../../src/tui/progress-bar.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mission Control TUI custom styles.
|
|
3
|
+
* Uses stronger dark orange / dark green tones than the default theme tokens.
|
|
4
|
+
*/
|
|
5
|
+
export declare function missionSuccess(text: string): string;
|
|
6
|
+
export declare function missionWarning(text: string): string;
|
|
7
|
+
export declare function strike(text: string): string;
|
|
8
|
+
//# sourceMappingURL=styles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../src/tui/styles.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAaH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE3C"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mission Control TUI custom styles.
|
|
3
|
+
* Uses stronger dark orange / dark green tones than the default theme tokens.
|
|
4
|
+
*/
|
|
5
|
+
const ANSI_FG_RESET = "\x1b[39m";
|
|
6
|
+
const ANSI_STRIKE_ON = "\x1b[9m";
|
|
7
|
+
const ANSI_STRIKE_OFF = "\x1b[29m";
|
|
8
|
+
const DARK_GREEN = { r: 46, g: 125, b: 50 }; // #2E7D32
|
|
9
|
+
const DARK_ORANGE = { r: 198, g: 94, b: 0 }; // #C65E00
|
|
10
|
+
function rgb(text, color) {
|
|
11
|
+
return `\x1b[38;2;${color.r};${color.g};${color.b}m${text}${ANSI_FG_RESET}`;
|
|
12
|
+
}
|
|
13
|
+
export function missionSuccess(text) {
|
|
14
|
+
return rgb(text, DARK_GREEN);
|
|
15
|
+
}
|
|
16
|
+
export function missionWarning(text) {
|
|
17
|
+
return rgb(text, DARK_ORANGE);
|
|
18
|
+
}
|
|
19
|
+
export function strike(text) {
|
|
20
|
+
return `${ANSI_STRIKE_ON}${text}${ANSI_STRIKE_OFF}`;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=styles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles.js","sourceRoot":"","sources":["../../src/tui/styles.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,aAAa,GAAG,UAAU,CAAC;AACjC,MAAM,cAAc,GAAG,SAAS,CAAC;AACjC,MAAM,eAAe,GAAG,UAAU,CAAC;AAEnC,MAAM,UAAU,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAG,UAAU;AACzD,MAAM,WAAW,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAG,UAAU;AAEzD,SAAS,GAAG,CAAC,IAAY,EAAE,KAA0C;IACnE,OAAO,aAAa,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,IAAI,GAAG,aAAa,EAAE,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,GAAG,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,GAAG,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,IAAY;IACjC,OAAO,GAAG,cAAc,GAAG,IAAI,GAAG,eAAe,EAAE,CAAC;AACtD,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mission Control TUI Tasks Panel
|
|
3
|
+
*
|
|
4
|
+
* Right panel displaying:
|
|
5
|
+
* - Tasks for the selected phase
|
|
6
|
+
* - Status icons including spinner for in-progress
|
|
7
|
+
* - Navigation indicator
|
|
8
|
+
*
|
|
9
|
+
* Icons (Nerd Font):
|
|
10
|
+
* - Done: \uf058 () check
|
|
11
|
+
* - In Progress: \uf1ce () spinner/sync
|
|
12
|
+
* - Pending: \uf096 () empty box
|
|
13
|
+
* - Failed: \uf057 () times
|
|
14
|
+
*/
|
|
15
|
+
import type { Theme } from "@mariozechner/pi-coding-agent";
|
|
16
|
+
import type { Task, Phase } from "../state.js";
|
|
17
|
+
export interface TasksPanelProps {
|
|
18
|
+
phase: Phase | null;
|
|
19
|
+
tasks: Task[];
|
|
20
|
+
selectedIndex: number;
|
|
21
|
+
focused: boolean;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Render the tasks panel
|
|
25
|
+
*/
|
|
26
|
+
export declare function renderTasksPanel(width: number, height: number, props: TasksPanelProps, theme: Theme): string[];
|
|
27
|
+
/**
|
|
28
|
+
* Tasks panel component class
|
|
29
|
+
* Tracks per-phase selection state to avoid auto-selecting when switching phases
|
|
30
|
+
*/
|
|
31
|
+
export declare class TasksPanelComponent {
|
|
32
|
+
private props;
|
|
33
|
+
private cachedWidth?;
|
|
34
|
+
private cachedHeight?;
|
|
35
|
+
private cachedLines?;
|
|
36
|
+
private phaseSelections;
|
|
37
|
+
constructor(phase?: Phase | null, focused?: boolean);
|
|
38
|
+
update(phase: Phase | null, selectedIndex?: number): void;
|
|
39
|
+
setFocused(focused: boolean): void;
|
|
40
|
+
isFocused(): boolean;
|
|
41
|
+
getSelectedIndex(): number;
|
|
42
|
+
getSelectedTask(): Task | undefined;
|
|
43
|
+
navigateUp(): void;
|
|
44
|
+
navigateDown(): void;
|
|
45
|
+
render(width: number, height: number, theme: Theme): string[];
|
|
46
|
+
invalidate(): void;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=tasks-panel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tasks-panel.d.ts","sourceRoot":"","sources":["../../src/tui/tasks-panel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAI/C,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;CAClB;AAwCD;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,eAAe,EACtB,KAAK,EAAE,KAAK,GACX,MAAM,EAAE,CA0CV;AAED;;;GAGG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,KAAK,CAAkB;IAC/B,OAAO,CAAC,WAAW,CAAC,CAAS;IAC7B,OAAO,CAAC,YAAY,CAAC,CAAS;IAC9B,OAAO,CAAC,WAAW,CAAC,CAAW;IAC/B,OAAO,CAAC,eAAe,CAAkC;gBAE7C,KAAK,GAAE,KAAK,GAAG,IAAW,EAAE,OAAO,UAAQ;IASvD,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI;IA4BzD,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IASlC,SAAS,IAAI,OAAO;IAIpB,gBAAgB,IAAI,MAAM;IAI1B,eAAe,IAAI,IAAI,GAAG,SAAS;IAKnC,UAAU,IAAI,IAAI;IAYlB,YAAY,IAAI,IAAI;IAYpB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,EAAE;IAW7D,UAAU,IAAI,IAAI;CAKnB"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mission Control TUI Tasks Panel
|
|
3
|
+
*
|
|
4
|
+
* Right panel displaying:
|
|
5
|
+
* - Tasks for the selected phase
|
|
6
|
+
* - Status icons including spinner for in-progress
|
|
7
|
+
* - Navigation indicator
|
|
8
|
+
*
|
|
9
|
+
* Icons (Nerd Font):
|
|
10
|
+
* - Done: \uf058 () check
|
|
11
|
+
* - In Progress: \uf1ce () spinner/sync
|
|
12
|
+
* - Pending: \uf096 () empty box
|
|
13
|
+
* - Failed: \uf057 () times
|
|
14
|
+
*/
|
|
15
|
+
import { truncateToWidth } from "@mariozechner/pi-tui";
|
|
16
|
+
import { missionSuccess, missionWarning, strike } from "./styles.js";
|
|
17
|
+
/**
|
|
18
|
+
* Render a single task line
|
|
19
|
+
* Styling: selected=white bold, running=orange/warning, unselected non-running=gray/muted
|
|
20
|
+
*/
|
|
21
|
+
function renderTaskLine(task, index, selectedIndex, width, theme, focused) {
|
|
22
|
+
const isSelected = focused && index === selectedIndex;
|
|
23
|
+
const isRunning = task.status === "in_progress";
|
|
24
|
+
const baseText = `Task ${index + 1}: ${task.name}`;
|
|
25
|
+
// Apply styling based on selection and running state
|
|
26
|
+
let styled;
|
|
27
|
+
if (task.status === "removed") {
|
|
28
|
+
const removedText = strike(baseText);
|
|
29
|
+
styled = isSelected
|
|
30
|
+
? theme.fg("text", theme.bold(removedText))
|
|
31
|
+
: theme.fg("muted", removedText);
|
|
32
|
+
}
|
|
33
|
+
else if (isSelected) {
|
|
34
|
+
styled = theme.fg("text", theme.bold(baseText));
|
|
35
|
+
}
|
|
36
|
+
else if (isRunning) {
|
|
37
|
+
styled = missionWarning(baseText);
|
|
38
|
+
}
|
|
39
|
+
else if (task.status === "done") {
|
|
40
|
+
styled = missionSuccess(baseText);
|
|
41
|
+
}
|
|
42
|
+
else if (task.status === "failed") {
|
|
43
|
+
styled = theme.fg("error", baseText);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
styled = theme.fg("muted", baseText);
|
|
47
|
+
}
|
|
48
|
+
return truncateToWidth(styled, width);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Render the tasks panel
|
|
52
|
+
*/
|
|
53
|
+
export function renderTasksPanel(width, height, props, theme) {
|
|
54
|
+
const { phase, tasks, selectedIndex, focused } = props;
|
|
55
|
+
const lines = [];
|
|
56
|
+
const header = theme.fg("text", theme.bold("TASKS"));
|
|
57
|
+
lines.push(truncateToWidth(header, width));
|
|
58
|
+
if (tasks.length === 0) {
|
|
59
|
+
const emptyMsg = phase
|
|
60
|
+
? theme.fg("muted", " No tasks in this phase")
|
|
61
|
+
: theme.fg("muted", " Select a phase to view tasks");
|
|
62
|
+
lines.push(truncateToWidth(emptyMsg, width));
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
// Calculate visible range
|
|
66
|
+
const availableHeight = height - 1;
|
|
67
|
+
let startIdx = 0;
|
|
68
|
+
let endIdx = tasks.length;
|
|
69
|
+
if (tasks.length > availableHeight) {
|
|
70
|
+
const halfHeight = Math.floor(availableHeight / 2);
|
|
71
|
+
startIdx = Math.max(0, selectedIndex - halfHeight);
|
|
72
|
+
endIdx = Math.min(tasks.length, startIdx + availableHeight);
|
|
73
|
+
if (endIdx - startIdx < availableHeight) {
|
|
74
|
+
startIdx = Math.max(0, endIdx - availableHeight);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Render visible tasks
|
|
78
|
+
for (let i = startIdx; i < endIdx; i++) {
|
|
79
|
+
const task = tasks[i];
|
|
80
|
+
const line = renderTaskLine(task, i, selectedIndex, width, theme, focused);
|
|
81
|
+
lines.push(line);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// Pad to height
|
|
85
|
+
while (lines.length < height) {
|
|
86
|
+
lines.push("");
|
|
87
|
+
}
|
|
88
|
+
return lines.slice(0, height);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Tasks panel component class
|
|
92
|
+
* Tracks per-phase selection state to avoid auto-selecting when switching phases
|
|
93
|
+
*/
|
|
94
|
+
export class TasksPanelComponent {
|
|
95
|
+
props;
|
|
96
|
+
cachedWidth;
|
|
97
|
+
cachedHeight;
|
|
98
|
+
cachedLines;
|
|
99
|
+
phaseSelections = new Map(); // phase id -> selected index
|
|
100
|
+
constructor(phase = null, focused = false) {
|
|
101
|
+
this.props = {
|
|
102
|
+
phase,
|
|
103
|
+
tasks: phase?.tasks ?? [],
|
|
104
|
+
selectedIndex: -1,
|
|
105
|
+
focused
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
update(phase, selectedIndex) {
|
|
109
|
+
const prevPhaseId = this.props.phase?.id;
|
|
110
|
+
// Save current selection for previous phase
|
|
111
|
+
if (prevPhaseId && this.props.tasks.length > 0) {
|
|
112
|
+
this.phaseSelections.set(prevPhaseId, this.props.selectedIndex);
|
|
113
|
+
}
|
|
114
|
+
this.props.phase = phase;
|
|
115
|
+
this.props.tasks = phase?.tasks ?? [];
|
|
116
|
+
if (selectedIndex !== undefined) {
|
|
117
|
+
this.props.selectedIndex = Math.max(-1, Math.min(selectedIndex, this.props.tasks.length - 1));
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
const phaseId = phase?.id;
|
|
121
|
+
if (phaseId && this.phaseSelections.has(phaseId)) {
|
|
122
|
+
const savedIndex = this.phaseSelections.get(phaseId);
|
|
123
|
+
this.props.selectedIndex = Math.max(-1, Math.min(savedIndex, this.props.tasks.length - 1));
|
|
124
|
+
}
|
|
125
|
+
else if (this.props.focused && this.props.tasks.length > 0) {
|
|
126
|
+
const inProgressIdx = this.props.tasks.findIndex(t => t.status === "in_progress");
|
|
127
|
+
this.props.selectedIndex = inProgressIdx !== -1 ? inProgressIdx : 0;
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
this.props.selectedIndex = -1;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
this.invalidate();
|
|
134
|
+
}
|
|
135
|
+
setFocused(focused) {
|
|
136
|
+
this.props.focused = focused;
|
|
137
|
+
if (focused && this.props.selectedIndex < 0 && this.props.tasks.length > 0) {
|
|
138
|
+
const inProgressIdx = this.props.tasks.findIndex(t => t.status === "in_progress");
|
|
139
|
+
this.props.selectedIndex = inProgressIdx !== -1 ? inProgressIdx : 0;
|
|
140
|
+
}
|
|
141
|
+
this.invalidate();
|
|
142
|
+
}
|
|
143
|
+
isFocused() {
|
|
144
|
+
return this.props.focused;
|
|
145
|
+
}
|
|
146
|
+
getSelectedIndex() {
|
|
147
|
+
return this.props.selectedIndex;
|
|
148
|
+
}
|
|
149
|
+
getSelectedTask() {
|
|
150
|
+
if (this.props.selectedIndex < 0)
|
|
151
|
+
return undefined;
|
|
152
|
+
return this.props.tasks[this.props.selectedIndex];
|
|
153
|
+
}
|
|
154
|
+
navigateUp() {
|
|
155
|
+
if (this.props.selectedIndex < 0 && this.props.tasks.length > 0) {
|
|
156
|
+
this.props.selectedIndex = 0;
|
|
157
|
+
this.invalidate();
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
if (this.props.selectedIndex > 0) {
|
|
161
|
+
this.props.selectedIndex--;
|
|
162
|
+
this.invalidate();
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
navigateDown() {
|
|
166
|
+
if (this.props.selectedIndex < 0 && this.props.tasks.length > 0) {
|
|
167
|
+
this.props.selectedIndex = 0;
|
|
168
|
+
this.invalidate();
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
if (this.props.selectedIndex < this.props.tasks.length - 1) {
|
|
172
|
+
this.props.selectedIndex++;
|
|
173
|
+
this.invalidate();
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
render(width, height, theme) {
|
|
177
|
+
if (this.cachedLines && this.cachedWidth === width && this.cachedHeight === height) {
|
|
178
|
+
return this.cachedLines;
|
|
179
|
+
}
|
|
180
|
+
this.cachedLines = renderTasksPanel(width, height, this.props, theme);
|
|
181
|
+
this.cachedWidth = width;
|
|
182
|
+
this.cachedHeight = height;
|
|
183
|
+
return this.cachedLines;
|
|
184
|
+
}
|
|
185
|
+
invalidate() {
|
|
186
|
+
this.cachedWidth = undefined;
|
|
187
|
+
this.cachedHeight = undefined;
|
|
188
|
+
this.cachedLines = undefined;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=tasks-panel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tasks-panel.js","sourceRoot":"","sources":["../../src/tui/tasks-panel.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pi-mission-control",
|
|
3
|
+
"version": "0.0.0-dev",
|
|
4
|
+
"description": "Visual mission orchestration extension for pi with agent hierarchy and durable state",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"pi-package"
|
|
7
|
+
],
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"author": "",
|
|
10
|
+
"type": "module",
|
|
11
|
+
"main": "dist/index.js",
|
|
12
|
+
"types": "dist/index.d.ts",
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc",
|
|
15
|
+
"dev": "tsc --watch",
|
|
16
|
+
"typecheck": "tsc --noEmit"
|
|
17
|
+
},
|
|
18
|
+
"peerDependencies": {
|
|
19
|
+
"@mariozechner/pi-agent-core": "*",
|
|
20
|
+
"@mariozechner/pi-ai": "*",
|
|
21
|
+
"@mariozechner/pi-coding-agent": "*",
|
|
22
|
+
"@mariozechner/pi-tui": "*",
|
|
23
|
+
"@sinclair/typebox": "*"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@types/node": "^20.19.39",
|
|
27
|
+
"typescript": "^5.9.3"
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"src",
|
|
31
|
+
"dist",
|
|
32
|
+
"agents",
|
|
33
|
+
"skills",
|
|
34
|
+
"templates",
|
|
35
|
+
"README.md"
|
|
36
|
+
],
|
|
37
|
+
"pi": {
|
|
38
|
+
"extensions": [
|
|
39
|
+
"./src/index.ts"
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mission-memory
|
|
3
|
+
description: |
|
|
4
|
+
Distill learnings from a completed mission into persistent long-term memory.
|
|
5
|
+
Use when a mission finishes or when significant knowledge should be preserved
|
|
6
|
+
between tasks and phases.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Mission Memory
|
|
10
|
+
|
|
11
|
+
## Overview
|
|
12
|
+
You are responsible for knowledge management. Distill learnings from the
|
|
13
|
+
current mission into persistent memory that future missions can benefit from.
|
|
14
|
+
|
|
15
|
+
## When to Use
|
|
16
|
+
- A mission has completed (called by mission-orchestrator)
|
|
17
|
+
- After each phase completes (to capture intermediate learnings)
|
|
18
|
+
- When significant knowledge is discovered that should persist
|
|
19
|
+
|
|
20
|
+
## Memory Architecture
|
|
21
|
+
|
|
22
|
+
### Short-term memory (per run)
|
|
23
|
+
- File: `short_term_memory.md` in the run directory
|
|
24
|
+
- Written by the orchestrator during execution
|
|
25
|
+
- Contains: granular run-specific details, what worked, what didn't, deviations
|
|
26
|
+
- Lifecycle: exists only for the duration of the run
|
|
27
|
+
|
|
28
|
+
### Long-term memory (cross-run)
|
|
29
|
+
- File: `memory/long_term.md` in .pi/mission-control/
|
|
30
|
+
- Written by this skill at mission closeout
|
|
31
|
+
- Contains: distilled rules, conventions, patterns, anti-patterns
|
|
32
|
+
- Lifecycle: persists across all missions, loaded at mission-research start
|
|
33
|
+
|
|
34
|
+
### Memory flow between tasks
|
|
35
|
+
After each task completes, the orchestrator should:
|
|
36
|
+
1. Write observations to `short_term_memory.md`
|
|
37
|
+
2. Note any deviations from the contract
|
|
38
|
+
3. Record tooling quirks discovered
|
|
39
|
+
|
|
40
|
+
### Memory flow between phases
|
|
41
|
+
After each phase completes, the orchestrator should:
|
|
42
|
+
1. Summarize what the phase accomplished
|
|
43
|
+
2. Note any patterns that could help later phases
|
|
44
|
+
3. Record any gotchas discovered
|
|
45
|
+
|
|
46
|
+
### Final distillation (this skill)
|
|
47
|
+
At mission closeout, read all short-term memory and distill into long-term.
|
|
48
|
+
|
|
49
|
+
## Workflow
|
|
50
|
+
|
|
51
|
+
### Final Distillation (called at mission end)
|
|
52
|
+
1. Read `short_term_memory.md` from the run directory
|
|
53
|
+
2. Read all `auditor-report.md` files — what failed, why, how it was resolved
|
|
54
|
+
3. Read all `worker-output.md` files — deviations and workarounds
|
|
55
|
+
4. Categorize learnings:
|
|
56
|
+
- **Repo conventions**: "use single quotes for imports", "test files go in __tests__/"
|
|
57
|
+
- **Tooling quirks**: "test runner needs --detectOpenHandles", "build fails if X"
|
|
58
|
+
- **Architecture decisions**: what patterns worked, what didn't
|
|
59
|
+
- **Common failures**: recurring issues and their solutions
|
|
60
|
+
- **Performance notes**: slow tests, large files, hot paths
|
|
61
|
+
5. Read existing `memory/long_term.md`
|
|
62
|
+
6. Merge new learnings into long_term.md:
|
|
63
|
+
- Do NOT overwrite — append or merge
|
|
64
|
+
- Remove contradictory entries (new learning supersedes old)
|
|
65
|
+
- Keep entries concise (one line per rule)
|
|
66
|
+
- Organize by category
|
|
67
|
+
7. Confirm with user what will be persisted using `ask_user`
|
|
68
|
+
- Use multiple-choice options with typed fallback
|
|
69
|
+
- Keep wording clean with no emojis
|
|
70
|
+
- Ask for confirmation only on the distilled learnings that matter
|
|
71
|
+
8. After confirmation, the mission is complete—no further skills to load
|
|
72
|
+
|
|
73
|
+
## File Map
|
|
74
|
+
| File | Action | Purpose |
|
|
75
|
+
|------|--------|---------|
|
|
76
|
+
| `.pi/mission-control/runs/<run_id>/short_term_memory.md` | Read | Run-specific notes |
|
|
77
|
+
| `.pi/mission-control/runs/<run_id>/tasks/*/auditor-report.md` | Read | Failure patterns |
|
|
78
|
+
| `.pi/mission-control/runs/<run_id>/tasks/*/worker-output.md` | Read | Deviations |
|
|
79
|
+
| `.pi/mission-control/memory/long_term.md` | Read + Write | Distilled knowledge |
|
|
80
|
+
|
|
81
|
+
## Anti-patterns
|
|
82
|
+
- Do NOT dump raw logs into long_term.md — distill to rules
|
|
83
|
+
- Do NOT overwrite long_term.md — merge
|
|
84
|
+
- Do NOT skip user confirmation — use `ask_user` to confirm what to persist
|
|
85
|
+
- Do NOT save task-specific details — only patterns that generalize
|
|
86
|
+
|
|
87
|
+
## Next
|
|
88
|
+
No next skill. Mission is complete. State the final summary to the user.
|