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.
Files changed (110) hide show
  1. package/README.md +205 -0
  2. package/agents/auditor.md +45 -0
  3. package/agents/worker.md +44 -0
  4. package/dist/index.d.ts +9 -0
  5. package/dist/index.d.ts.map +1 -0
  6. package/dist/index.js +526 -0
  7. package/dist/index.js.map +1 -0
  8. package/dist/state.d.ts +265 -0
  9. package/dist/state.d.ts.map +1 -0
  10. package/dist/state.js +474 -0
  11. package/dist/state.js.map +1 -0
  12. package/dist/tools/add-phase.d.ts +28 -0
  13. package/dist/tools/add-phase.d.ts.map +1 -0
  14. package/dist/tools/add-phase.js +69 -0
  15. package/dist/tools/add-phase.js.map +1 -0
  16. package/dist/tools/add-task.d.ts +30 -0
  17. package/dist/tools/add-task.d.ts.map +1 -0
  18. package/dist/tools/add-task.js +85 -0
  19. package/dist/tools/add-task.js.map +1 -0
  20. package/dist/tools/index.d.ts +13 -0
  21. package/dist/tools/index.d.ts.map +1 -0
  22. package/dist/tools/index.js +16 -0
  23. package/dist/tools/index.js.map +1 -0
  24. package/dist/tools/init.d.ts +34 -0
  25. package/dist/tools/init.d.ts.map +1 -0
  26. package/dist/tools/init.js +75 -0
  27. package/dist/tools/init.js.map +1 -0
  28. package/dist/tools/mission-complete.d.ts +30 -0
  29. package/dist/tools/mission-complete.d.ts.map +1 -0
  30. package/dist/tools/mission-complete.js +85 -0
  31. package/dist/tools/mission-complete.js.map +1 -0
  32. package/dist/tools/mission-resume.d.ts +35 -0
  33. package/dist/tools/mission-resume.d.ts.map +1 -0
  34. package/dist/tools/mission-resume.js +87 -0
  35. package/dist/tools/mission-resume.js.map +1 -0
  36. package/dist/tools/scaffold.d.ts +24 -0
  37. package/dist/tools/scaffold.d.ts.map +1 -0
  38. package/dist/tools/scaffold.js +129 -0
  39. package/dist/tools/scaffold.js.map +1 -0
  40. package/dist/tools/update-phase.d.ts +33 -0
  41. package/dist/tools/update-phase.d.ts.map +1 -0
  42. package/dist/tools/update-phase.js +101 -0
  43. package/dist/tools/update-phase.js.map +1 -0
  44. package/dist/tools/update-task.d.ts +34 -0
  45. package/dist/tools/update-task.d.ts.map +1 -0
  46. package/dist/tools/update-task.js +104 -0
  47. package/dist/tools/update-task.js.map +1 -0
  48. package/dist/tui/dashboard.d.ts +146 -0
  49. package/dist/tui/dashboard.d.ts.map +1 -0
  50. package/dist/tui/dashboard.js +381 -0
  51. package/dist/tui/dashboard.js.map +1 -0
  52. package/dist/tui/header.d.ts +39 -0
  53. package/dist/tui/header.d.ts.map +1 -0
  54. package/dist/tui/header.js +62 -0
  55. package/dist/tui/header.js.map +1 -0
  56. package/dist/tui/idle-view.d.ts +44 -0
  57. package/dist/tui/idle-view.d.ts.map +1 -0
  58. package/dist/tui/idle-view.js +87 -0
  59. package/dist/tui/idle-view.js.map +1 -0
  60. package/dist/tui/index.d.ts +13 -0
  61. package/dist/tui/index.d.ts.map +1 -0
  62. package/dist/tui/index.js +15 -0
  63. package/dist/tui/index.js.map +1 -0
  64. package/dist/tui/past-runs.d.ts +49 -0
  65. package/dist/tui/past-runs.d.ts.map +1 -0
  66. package/dist/tui/past-runs.js +207 -0
  67. package/dist/tui/past-runs.js.map +1 -0
  68. package/dist/tui/phases-panel.d.ts +46 -0
  69. package/dist/tui/phases-panel.d.ts.map +1 -0
  70. package/dist/tui/phases-panel.js +161 -0
  71. package/dist/tui/phases-panel.js.map +1 -0
  72. package/dist/tui/progress-bar.d.ts +37 -0
  73. package/dist/tui/progress-bar.d.ts.map +1 -0
  74. package/dist/tui/progress-bar.js +123 -0
  75. package/dist/tui/progress-bar.js.map +1 -0
  76. package/dist/tui/styles.d.ts +8 -0
  77. package/dist/tui/styles.d.ts.map +1 -0
  78. package/dist/tui/styles.js +22 -0
  79. package/dist/tui/styles.js.map +1 -0
  80. package/dist/tui/tasks-panel.d.ts +48 -0
  81. package/dist/tui/tasks-panel.d.ts.map +1 -0
  82. package/dist/tui/tasks-panel.js +191 -0
  83. package/dist/tui/tasks-panel.js.map +1 -0
  84. package/package.json +42 -0
  85. package/skills/mission-memory/SKILL.md +88 -0
  86. package/skills/mission-orchestrator/SKILL.md +167 -0
  87. package/skills/mission-pm/SKILL.md +83 -0
  88. package/skills/mission-research/SKILL.md +66 -0
  89. package/skills/mission-tech-lead/SKILL.md +68 -0
  90. package/src/index.ts +659 -0
  91. package/src/state.ts +623 -0
  92. package/src/tools/add-phase.ts +98 -0
  93. package/src/tools/add-task.ts +121 -0
  94. package/src/tools/index.ts +18 -0
  95. package/src/tools/init.ts +109 -0
  96. package/src/tools/mission-complete.ts +118 -0
  97. package/src/tools/mission-resume.ts +119 -0
  98. package/src/tools/scaffold.ts +167 -0
  99. package/src/tools/update-phase.ts +140 -0
  100. package/src/tools/update-task.ts +145 -0
  101. package/src/tui/dashboard.ts +441 -0
  102. package/src/tui/header.ts +85 -0
  103. package/src/tui/idle-view.ts +114 -0
  104. package/src/tui/index.ts +20 -0
  105. package/src/tui/past-runs.ts +261 -0
  106. package/src/tui/phases-panel.ts +199 -0
  107. package/src/tui/progress-bar.ts +152 -0
  108. package/src/tui/styles.ts +27 -0
  109. package/src/tui/tasks-panel.ts +228 -0
  110. 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.