@leing2021/super-pi 0.22.1 → 0.23.0

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 +253 -211
  2. package/extensions/ce-core/index.ts +190 -7
  3. package/extensions/ce-core/tools/parallel-subagent.ts +3 -3
  4. package/extensions/ce-core/tools/subagent.ts +2 -2
  5. package/package.json +4 -20
  6. package/rules/common/naming.md +154 -0
  7. package/skills/02-plan/SKILL.md +3 -2
  8. package/skills/03-work/SKILL.md +9 -6
  9. package/skills/04-review/SKILL.md +3 -2
  10. package/skills/06-next/SKILL.md +38 -10
  11. package/skills/06-next/references/recommendation-logic.md +2 -2
  12. package/skills/07-worktree/SKILL.md +9 -8
  13. package/skills/{09-help → 08-help}/SKILL.md +3 -3
  14. package/skills/{09-help → 08-help}/references/workflow-sequence.md +2 -1
  15. package/skills/references/language-detection.md +44 -0
  16. package/LICENSE +0 -21
  17. package/THIRD-PARTY-NOTICES.md +0 -35
  18. package/extensions/subagent/__tests__/async-job-tracker.test.ts +0 -21
  19. package/extensions/subagent/__tests__/execution-activity.test.ts +0 -15
  20. package/extensions/subagent/__tests__/parallel-render-stress.test.ts +0 -82
  21. package/extensions/subagent/__tests__/render-dedup.test.ts +0 -98
  22. package/extensions/subagent/__tests__/render-widget.test.ts +0 -28
  23. package/extensions/subagent/__tests__/throttle.test.ts +0 -90
  24. package/extensions/subagent/agent-management.ts +0 -596
  25. package/extensions/subagent/agent-manager-chain-detail.ts +0 -163
  26. package/extensions/subagent/agent-manager-detail.ts +0 -232
  27. package/extensions/subagent/agent-manager-edit.ts +0 -391
  28. package/extensions/subagent/agent-manager-list.ts +0 -279
  29. package/extensions/subagent/agent-manager-parallel.ts +0 -305
  30. package/extensions/subagent/agent-manager.ts +0 -706
  31. package/extensions/subagent/agent-scope.ts +0 -9
  32. package/extensions/subagent/agent-selection.ts +0 -26
  33. package/extensions/subagent/agent-serializer.ts +0 -124
  34. package/extensions/subagent/agent-templates.ts +0 -63
  35. package/extensions/subagent/agents/context-builder.md +0 -37
  36. package/extensions/subagent/agents/delegate.md +0 -9
  37. package/extensions/subagent/agents/oracle.md +0 -73
  38. package/extensions/subagent/agents/planner.md +0 -52
  39. package/extensions/subagent/agents/researcher.md +0 -50
  40. package/extensions/subagent/agents/reviewer.md +0 -38
  41. package/extensions/subagent/agents/scout.md +0 -48
  42. package/extensions/subagent/agents/worker.md +0 -52
  43. package/extensions/subagent/agents.ts +0 -762
  44. package/extensions/subagent/artifacts.ts +0 -101
  45. package/extensions/subagent/async-execution.ts +0 -521
  46. package/extensions/subagent/async-job-tracker.ts +0 -240
  47. package/extensions/subagent/async-status.ts +0 -242
  48. package/extensions/subagent/chain-clarify.ts +0 -1365
  49. package/extensions/subagent/chain-execution.ts +0 -854
  50. package/extensions/subagent/chain-serializer.ts +0 -127
  51. package/extensions/subagent/completion-dedupe.ts +0 -66
  52. package/extensions/subagent/doctor.ts +0 -201
  53. package/extensions/subagent/execution.ts +0 -748
  54. package/extensions/subagent/file-coalescer.ts +0 -43
  55. package/extensions/subagent/fork-context.ts +0 -64
  56. package/extensions/subagent/formatters.ts +0 -123
  57. package/extensions/subagent/frontmatter.ts +0 -32
  58. package/extensions/subagent/index.ts +0 -586
  59. package/extensions/subagent/intercom-bridge.ts +0 -241
  60. package/extensions/subagent/jsonl-writer.ts +0 -84
  61. package/extensions/subagent/model-fallback.ts +0 -109
  62. package/extensions/subagent/notify.ts +0 -111
  63. package/extensions/subagent/parallel-utils.ts +0 -109
  64. package/extensions/subagent/pi-args.ts +0 -139
  65. package/extensions/subagent/pi-spawn.ts +0 -101
  66. package/extensions/subagent/post-exit-stdio-guard.ts +0 -88
  67. package/extensions/subagent/prompt-template-bridge.ts +0 -400
  68. package/extensions/subagent/prompts/gather-context-and-clarify.md +0 -13
  69. package/extensions/subagent/prompts/parallel-cleanup.md +0 -42
  70. package/extensions/subagent/prompts/parallel-research.md +0 -50
  71. package/extensions/subagent/prompts/parallel-review.md +0 -40
  72. package/extensions/subagent/render-helpers.ts +0 -83
  73. package/extensions/subagent/render.ts +0 -908
  74. package/extensions/subagent/result-intercom.ts +0 -238
  75. package/extensions/subagent/result-watcher.ts +0 -172
  76. package/extensions/subagent/run-history.ts +0 -58
  77. package/extensions/subagent/run-status.ts +0 -137
  78. package/extensions/subagent/schemas.ts +0 -165
  79. package/extensions/subagent/session-tokens.ts +0 -51
  80. package/extensions/subagent/settings.ts +0 -368
  81. package/extensions/subagent/single-output.ts +0 -98
  82. package/extensions/subagent/skills.ts +0 -627
  83. package/extensions/subagent/slash-bridge.ts +0 -177
  84. package/extensions/subagent/slash-commands.ts +0 -304
  85. package/extensions/subagent/slash-live-state.ts +0 -295
  86. package/extensions/subagent/subagent-control.ts +0 -151
  87. package/extensions/subagent/subagent-executor.ts +0 -1915
  88. package/extensions/subagent/subagent-prompt-runtime.ts +0 -76
  89. package/extensions/subagent/subagent-runner.ts +0 -1471
  90. package/extensions/subagent/subagents-status.ts +0 -473
  91. package/extensions/subagent/text-editor.ts +0 -273
  92. package/extensions/subagent/throttle.ts +0 -77
  93. package/extensions/subagent/top-level-async.ts +0 -16
  94. package/extensions/subagent/types.ts +0 -624
  95. package/extensions/subagent/utils.ts +0 -457
  96. package/extensions/subagent/worktree.ts +0 -580
  97. package/extensions/super-pi-extension/agents/ce-oracle.md +0 -109
  98. package/extensions/super-pi-extension/agents/ce-planner.md +0 -116
  99. package/extensions/super-pi-extension/agents/ce-reviewer.md +0 -99
  100. package/extensions/super-pi-extension/agents/ce-scout.md +0 -80
  101. package/extensions/super-pi-extension/agents/ce-worker.md +0 -78
  102. package/extensions/super-pi-extension/chains/ce-parallel-review.chain.md +0 -34
  103. package/extensions/super-pi-extension/chains/ce-review-only.chain.md +0 -12
  104. package/extensions/super-pi-extension/chains/ce-standard.chain.md +0 -28
  105. package/extensions/super-pi-extension/index.ts +0 -129
  106. package/extensions/super-pi-extension/model-sync.ts +0 -204
  107. package/skills/08-status/SKILL.md +0 -41
  108. package/skills/08-status/references/artifact-locations.md +0 -10
  109. package/skills/10-rules/SKILL.md +0 -76
  110. package/skills/pi-subagents/SKILL.md +0 -566
@@ -1,273 +0,0 @@
1
- // SPDX-FileCopyrightText: 2025 Nico Bailon
2
- // SPDX-License-Identifier: MIT
3
- // Source: https://github.com/nicobailon/pi-subagents
4
- import { matchesKey } from "@mariozechner/pi-tui";
5
-
6
- export interface TextEditorState {
7
- buffer: string;
8
- cursor: number;
9
- viewportOffset: number;
10
- }
11
-
12
- export interface TextEditorOptions {
13
- multiLine?: boolean;
14
- }
15
-
16
- export function createEditorState(initial = ""): TextEditorState {
17
- return {
18
- buffer: initial,
19
- cursor: 0,
20
- viewportOffset: 0,
21
- };
22
- }
23
-
24
- export function wrapText(text: string, width: number): { lines: string[]; starts: number[] } {
25
- const lines: string[] = [];
26
- const starts: number[] = [];
27
-
28
- if (width <= 0) {
29
- return { lines: [text], starts: [0] };
30
- }
31
-
32
- if (text.length === 0) {
33
- return { lines: [""], starts: [0] };
34
- }
35
-
36
- const segments = text.split("\n");
37
- let offset = 0;
38
-
39
- for (let i = 0; i < segments.length; i++) {
40
- const segment = segments[i] ?? "";
41
- if (segment.length === 0) {
42
- starts.push(offset);
43
- lines.push("");
44
- } else {
45
- let pos = 0;
46
- while (pos < segment.length) {
47
- starts.push(offset + pos);
48
- lines.push(segment.slice(pos, pos + width));
49
- pos += width;
50
- }
51
- }
52
-
53
- offset += segment.length;
54
- if (i < segments.length - 1) {
55
- offset += 1;
56
- }
57
- }
58
-
59
- const endsWithNewline = text.endsWith("\n");
60
- if (!endsWithNewline) {
61
- const lastLine = lines[lines.length - 1] ?? "";
62
- if (text.length > 0 && lastLine.length === width) {
63
- starts.push(text.length);
64
- lines.push("");
65
- }
66
- }
67
-
68
- return { lines, starts };
69
- }
70
-
71
- export function getCursorDisplayPos(cursor: number, starts: number[]): { line: number; col: number } {
72
- for (let i = starts.length - 1; i >= 0; i--) {
73
- if (cursor >= starts[i]) {
74
- return { line: i, col: cursor - starts[i] };
75
- }
76
- }
77
- return { line: 0, col: 0 };
78
- }
79
-
80
- export function ensureCursorVisible(cursorLine: number, viewportHeight: number, currentOffset: number): number {
81
- let offset = currentOffset;
82
-
83
- if (cursorLine < offset) {
84
- offset = cursorLine;
85
- } else if (cursorLine >= offset + viewportHeight) {
86
- offset = cursorLine - viewportHeight + 1;
87
- }
88
-
89
- return Math.max(0, offset);
90
- }
91
-
92
- function isWordChar(ch: string): boolean {
93
- const code = ch.charCodeAt(0);
94
- return (code >= 48 && code <= 57) || (code >= 65 && code <= 90) || (code >= 97 && code <= 122) || code === 95;
95
- }
96
-
97
- function wordBackward(buffer: string, cursor: number): number {
98
- let pos = cursor;
99
- while (pos > 0 && !isWordChar(buffer[pos - 1]!)) pos--;
100
- while (pos > 0 && isWordChar(buffer[pos - 1]!)) pos--;
101
- return pos;
102
- }
103
-
104
- function wordForward(buffer: string, cursor: number): number {
105
- const len = buffer.length;
106
- let pos = cursor;
107
- while (pos < len && isWordChar(buffer[pos]!)) pos++;
108
- while (pos < len && !isWordChar(buffer[pos]!)) pos++;
109
- return pos;
110
- }
111
-
112
- function normalizeInsertText(data: string, multiLine: boolean): string | null {
113
- let text = data;
114
-
115
- text = text.split("\x1b[200~").join("");
116
- text = text.split("\x1b[201~").join("");
117
- text = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
118
-
119
- if (!multiLine) {
120
- const nl = text.indexOf("\n");
121
- if (nl !== -1) text = text.slice(0, nl);
122
- }
123
-
124
- text = text.replace(/\t/g, " ");
125
- if (text.length === 0) return null;
126
-
127
- for (let i = 0; i < text.length; i++) {
128
- const code = text.charCodeAt(i);
129
- if (code < 32) {
130
- if (multiLine && text[i] === "\n") continue;
131
- return null;
132
- }
133
- }
134
-
135
- return text;
136
- }
137
-
138
- export function handleEditorInput(
139
- state: TextEditorState,
140
- data: string,
141
- textWidth: number,
142
- options?: TextEditorOptions,
143
- ): TextEditorState | null {
144
- const multiLine = options?.multiLine === true;
145
-
146
- if (matchesKey(data, "escape") || matchesKey(data, "ctrl+c")) {
147
- return null;
148
- }
149
-
150
- if (matchesKey(data, "return")) {
151
- if (!multiLine) return null;
152
- const buffer = state.buffer.slice(0, state.cursor) + "\n" + state.buffer.slice(state.cursor);
153
- return { ...state, buffer, cursor: state.cursor + 1 };
154
- }
155
-
156
- const { lines: wrapped, starts } = wrapText(state.buffer, textWidth);
157
- const cursorPos = getCursorDisplayPos(state.cursor, starts);
158
-
159
- if (matchesKey(data, "alt+left") || matchesKey(data, "ctrl+left")) {
160
- return { ...state, cursor: wordBackward(state.buffer, state.cursor) };
161
- }
162
-
163
- if (matchesKey(data, "alt+right") || matchesKey(data, "ctrl+right")) {
164
- return { ...state, cursor: wordForward(state.buffer, state.cursor) };
165
- }
166
-
167
- if (matchesKey(data, "left")) {
168
- if (state.cursor > 0) return { ...state, cursor: state.cursor - 1 };
169
- return state;
170
- }
171
-
172
- if (matchesKey(data, "right")) {
173
- if (state.cursor < state.buffer.length) return { ...state, cursor: state.cursor + 1 };
174
- return state;
175
- }
176
-
177
- if (matchesKey(data, "up")) {
178
- if (cursorPos.line > 0) {
179
- const targetLine = cursorPos.line - 1;
180
- const targetCol = Math.min(cursorPos.col, wrapped[targetLine]?.length ?? 0);
181
- return { ...state, cursor: starts[targetLine] + targetCol };
182
- }
183
- return state;
184
- }
185
-
186
- if (matchesKey(data, "down")) {
187
- if (cursorPos.line < wrapped.length - 1) {
188
- const targetLine = cursorPos.line + 1;
189
- const targetCol = Math.min(cursorPos.col, wrapped[targetLine]?.length ?? 0);
190
- return { ...state, cursor: starts[targetLine] + targetCol };
191
- }
192
- return state;
193
- }
194
-
195
- if (matchesKey(data, "home")) {
196
- return { ...state, cursor: starts[cursorPos.line] };
197
- }
198
-
199
- if (matchesKey(data, "end")) {
200
- return { ...state, cursor: starts[cursorPos.line] + (wrapped[cursorPos.line]?.length ?? 0) };
201
- }
202
-
203
- if (matchesKey(data, "ctrl+home")) {
204
- return { ...state, cursor: 0 };
205
- }
206
-
207
- if (matchesKey(data, "ctrl+end")) {
208
- return { ...state, cursor: state.buffer.length };
209
- }
210
-
211
- if (matchesKey(data, "alt+backspace")) {
212
- const target = wordBackward(state.buffer, state.cursor);
213
- if (target === state.cursor) return state;
214
- const buffer = state.buffer.slice(0, target) + state.buffer.slice(state.cursor);
215
- return { ...state, buffer, cursor: target };
216
- }
217
-
218
- if (matchesKey(data, "backspace")) {
219
- if (state.cursor > 0) {
220
- const buffer = state.buffer.slice(0, state.cursor - 1) + state.buffer.slice(state.cursor);
221
- return { ...state, buffer, cursor: state.cursor - 1 };
222
- }
223
- return state;
224
- }
225
-
226
- if (matchesKey(data, "delete")) {
227
- if (state.cursor < state.buffer.length) {
228
- const buffer = state.buffer.slice(0, state.cursor) + state.buffer.slice(state.cursor + 1);
229
- return { ...state, buffer };
230
- }
231
- return state;
232
- }
233
-
234
- const insert = normalizeInsertText(data, multiLine);
235
- if (insert) {
236
- const buffer = state.buffer.slice(0, state.cursor) + insert + state.buffer.slice(state.cursor);
237
- return { ...state, buffer, cursor: state.cursor + insert.length };
238
- }
239
-
240
- return null;
241
- }
242
-
243
- function renderWithCursor(text: string, cursorPos: number): string {
244
- const before = text.slice(0, cursorPos);
245
- const cursorChar = text[cursorPos] ?? " ";
246
- const after = text.slice(cursorPos + 1);
247
- return `${before}\x1b[7m${cursorChar}\x1b[27m${after}`;
248
- }
249
-
250
- export function renderEditor(
251
- state: TextEditorState,
252
- width: number,
253
- viewportHeight: number,
254
- ): string[] {
255
- const { lines: wrapped, starts } = wrapText(state.buffer, width);
256
- const cursorPos = getCursorDisplayPos(state.cursor, starts);
257
- const lines: string[] = [];
258
-
259
- for (let i = 0; i < viewportHeight; i++) {
260
- const lineIdx = state.viewportOffset + i;
261
- if (lineIdx < wrapped.length) {
262
- let content = wrapped[lineIdx] ?? "";
263
- if (lineIdx === cursorPos.line) {
264
- content = renderWithCursor(content, cursorPos.col);
265
- }
266
- lines.push(content);
267
- } else {
268
- lines.push("");
269
- }
270
- }
271
-
272
- return lines;
273
- }
@@ -1,77 +0,0 @@
1
- /**
2
- * Throttle utility for subagent event streams.
3
- * Prevents render storms by coalescing high-frequency onUpdate calls.
4
- */
5
-
6
- /**
7
- * Resolve the throttle interval based on parallel task count.
8
- * Returns 0 for single task (no throttling needed).
9
- */
10
- export function resolveThrottleInterval(taskCount: number): number {
11
- if (taskCount <= 1) return 0;
12
- if (taskCount <= 4) return 200;
13
- if (taskCount <= 8) return 500;
14
- return 1000;
15
- }
16
-
17
- /**
18
- * Create a throttled version of a function.
19
- *
20
- * - First call executes immediately.
21
- * - Subsequent calls within `intervalMs` are coalesced; only the latest args are kept.
22
- * - After `intervalMs`, if there was a pending call, it fires with the latest args.
23
- * - `flush()` immediately executes any pending call.
24
- * - `dispose()` cancels the timer and prevents future trailing calls.
25
- */
26
- export function createThrottle<T extends (...args: any[]) => void>(
27
- fn: T,
28
- intervalMs: number,
29
- ): T & { flush(): void; dispose(): void } {
30
- let pendingArgs: any[] | null = null;
31
- let timer: ReturnType<typeof setTimeout> | null = null;
32
-
33
- function execute(args: any[]) {
34
- pendingArgs = null;
35
- timer = null;
36
- fn(...args);
37
- }
38
-
39
- const throttled = function (this: unknown, ...args: any[]) {
40
- if (timer === null) {
41
- // First call — execute immediately
42
- execute(args);
43
- timer = setTimeout(() => {
44
- if (pendingArgs !== null) {
45
- execute(pendingArgs);
46
- } else {
47
- timer = null;
48
- }
49
- }, intervalMs);
50
- if (timer && typeof timer === "object" && "unref" in timer) {
51
- (timer as ReturnType<typeof setTimeout> & { unref(): void }).unref();
52
- }
53
- } else {
54
- // Within interval — save latest args
55
- pendingArgs = args;
56
- }
57
- } as T & { flush(): void; dispose(): void };
58
-
59
- throttled.flush = () => {
60
- if (pendingArgs !== null) {
61
- if (timer !== null) {
62
- clearTimeout(timer);
63
- }
64
- execute(pendingArgs);
65
- }
66
- };
67
-
68
- throttled.dispose = () => {
69
- if (timer !== null) {
70
- clearTimeout(timer);
71
- timer = null;
72
- }
73
- pendingArgs = null;
74
- };
75
-
76
- return throttled;
77
- }
@@ -1,16 +0,0 @@
1
- // SPDX-FileCopyrightText: 2025 Nico Bailon
2
- // SPDX-License-Identifier: MIT
3
- // Source: https://github.com/nicobailon/pi-subagents
4
- export interface AsyncOverrideParams {
5
- async?: boolean;
6
- clarify?: boolean;
7
- }
8
-
9
- export function applyForceTopLevelAsyncOverride<T extends AsyncOverrideParams>(
10
- params: T,
11
- depth: number,
12
- forceTopLevelAsync: boolean,
13
- ): T {
14
- if (!(depth === 0 && forceTopLevelAsync)) return params;
15
- return { ...params, async: true, clarify: false };
16
- }