@selesai/code 0.1.19 → 0.2.1
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/dist/agents/architect.md +4 -3
- package/dist/agents/builder.md +5 -4
- package/dist/agents/commentator.md +3 -2
- package/dist/agents/explorer.md +4 -4
- package/dist/agents/recapper.md +4 -3
- package/dist/config.d.ts +6 -7
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +7 -9
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +3 -1
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +18 -24
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +2 -0
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/types.d.ts +8 -1
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +25 -11
- package/dist/core/skills.js.map +1 -1
- package/dist/defaults/models.json +143 -39
- package/dist/defaults/settings.json +2 -29
- package/dist/extensions/package.json +5 -4
- package/dist/extensions/pi-intercom/index.ts +12 -5
- package/dist/extensions/pi-powerline-footer/index.ts +4 -1
- package/dist/extensions/pi-powerline-footer/tps.ts +286 -0
- package/dist/extensions/pi-powerline-footer/welcome.ts +47 -46
- package/dist/extensions/pi-subagents/README.md +12 -5
- package/dist/extensions/pi-subagents/agents/context-builder.md +2 -2
- package/dist/extensions/pi-subagents/agents/researcher.md +4 -5
- package/dist/extensions/pi-subagents/package.json +8 -5
- package/dist/extensions/pi-subagents/prompts/parallel-context-build.md +1 -1
- package/dist/extensions/pi-subagents/prompts/parallel-handoff-plan.md +1 -1
- package/dist/extensions/pi-subagents/src/agents/agent-management.ts +1 -1
- package/dist/extensions/pi-subagents/src/agents/agents.ts +3 -3
- package/dist/extensions/pi-subagents/src/extension/control-notices.ts +1 -1
- package/dist/extensions/pi-subagents/src/extension/doctor.ts +3 -3
- package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +1 -1
- package/dist/extensions/pi-subagents/src/extension/index.ts +29 -2
- package/dist/extensions/pi-subagents/src/profiles/profiles.ts +2 -2
- package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +72 -13
- package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +1 -1
- package/dist/extensions/pi-subagents/src/runs/background/notify.ts +1 -1
- package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +85 -41
- package/dist/extensions/pi-subagents/src/runs/foreground/chain-clarify.ts +1 -1
- package/dist/extensions/pi-subagents/src/runs/foreground/chain-execution.ts +1 -1
- package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +46 -3
- package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +2 -2
- package/dist/extensions/pi-subagents/src/runs/shared/completion-guard.ts +1 -3
- package/dist/extensions/pi-subagents/src/runs/shared/nested-events.ts +2 -2
- package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +18 -18
- package/dist/extensions/pi-subagents/src/runs/shared/pi-spawn.ts +24 -24
- package/dist/extensions/pi-subagents/src/runs/shared/spawn-timing.ts +46 -0
- package/dist/extensions/pi-subagents/src/runs/shared/structured-output.ts +2 -2
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +4 -4
- package/dist/extensions/pi-subagents/src/shared/fork-context.ts +1 -1
- package/dist/extensions/pi-subagents/src/shared/types.ts +6 -6
- package/dist/extensions/pi-subagents/src/shared/utils.ts +3 -3
- package/dist/extensions/pi-subagents/src/slash/slash-bridge.ts +1 -1
- package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +1 -1
- package/dist/extensions/pi-subagents/src/tui/render-helpers.ts +1 -1
- package/dist/extensions/pi-subagents/src/tui/render.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/spawn-timing.test.ts +45 -0
- package/dist/extensions/pi-subagents/tsconfig.runner.json +17 -0
- package/dist/extensions/pi-web-agent/package.json +31 -0
- package/dist/extensions/pi-web-agent/src/backends/config.ts +205 -0
- package/dist/extensions/pi-web-agent/src/backends/doctor.ts +136 -0
- package/dist/extensions/pi-web-agent/src/backends/factory.ts +152 -0
- package/dist/extensions/pi-web-agent/src/backends/settings-reader.ts +25 -0
- package/dist/extensions/pi-web-agent/src/cache/ttl-cache.ts +28 -0
- package/dist/extensions/pi-web-agent/src/changelog-notice.ts +133 -0
- package/dist/extensions/pi-web-agent/src/commands/web-agent-config.ts +946 -0
- package/dist/extensions/pi-web-agent/src/extension.ts +126 -0
- package/dist/extensions/pi-web-agent/src/extract/readability.ts +118 -0
- package/dist/extensions/pi-web-agent/src/fetch/browser-resolution.ts +199 -0
- package/dist/extensions/pi-web-agent/src/fetch/firecrawl-fetch.ts +100 -0
- package/dist/extensions/pi-web-agent/src/fetch/headless-fetch.ts +117 -0
- package/dist/extensions/pi-web-agent/src/fetch/http-fetch.ts +67 -0
- package/dist/extensions/pi-web-agent/src/orchestration/answer-synthesizer.ts +60 -0
- package/dist/extensions/pi-web-agent/src/orchestration/candidate-selector.ts +50 -0
- package/dist/extensions/pi-web-agent/src/orchestration/direct-url.ts +52 -0
- package/dist/extensions/pi-web-agent/src/orchestration/evidence-quality.ts +105 -0
- package/dist/extensions/pi-web-agent/src/orchestration/evidence-ranker.ts +45 -0
- package/dist/extensions/pi-web-agent/src/orchestration/index.ts +28 -0
- package/dist/extensions/pi-web-agent/src/orchestration/query-planner.ts +47 -0
- package/dist/extensions/pi-web-agent/src/orchestration/research-orchestrator.ts +376 -0
- package/dist/extensions/pi-web-agent/src/orchestration/research-types.ts +64 -0
- package/dist/extensions/pi-web-agent/src/orchestration/research-worker.ts +181 -0
- package/dist/extensions/pi-web-agent/src/orchestration/source-profile.ts +101 -0
- package/dist/extensions/pi-web-agent/src/orchestration/stop-decider.ts +81 -0
- package/dist/extensions/pi-web-agent/src/presentation/config-store.ts +208 -0
- package/dist/extensions/pi-web-agent/src/presentation/config.ts +75 -0
- package/dist/extensions/pi-web-agent/src/presentation/explore-presentation.ts +61 -0
- package/dist/extensions/pi-web-agent/src/presentation/fetch-presentation.ts +54 -0
- package/dist/extensions/pi-web-agent/src/presentation/search-presentation.ts +41 -0
- package/dist/extensions/pi-web-agent/src/presentation/select-view.ts +20 -0
- package/dist/extensions/pi-web-agent/src/presentation/types.ts +63 -0
- package/dist/extensions/pi-web-agent/src/search/brave.ts +114 -0
- package/dist/extensions/pi-web-agent/src/search/duckduckgo.ts +72 -0
- package/dist/extensions/pi-web-agent/src/search/searxng.ts +96 -0
- package/dist/extensions/pi-web-agent/src/tools/web-explore.ts +71 -0
- package/dist/extensions/pi-web-agent/src/tools/web-fetch-headless.ts +31 -0
- package/dist/extensions/pi-web-agent/src/tools/web-fetch.ts +31 -0
- package/dist/extensions/pi-web-agent/src/tools/web-search.ts +157 -0
- package/dist/extensions/pi-web-agent/src/types.ts +88 -0
- package/dist/extensions/ponytail/index.js +189 -0
- package/dist/extensions/ponytail/package.json +8 -0
- package/dist/extensions/ponytail/ponytail-config.cjs +122 -0
- package/dist/extensions/ponytail/ponytail-instructions.cjs +94 -0
- package/dist/extensions/ponytail/test/extension.test.js +167 -0
- package/dist/extensions/ponytail/test/helpers.test.js +92 -0
- package/dist/extensions/question/constants.ts +38 -0
- package/dist/extensions/question/dialog-adapter.ts +74 -0
- package/dist/extensions/question/helpers.ts +102 -0
- package/dist/extensions/question/index.ts +671 -0
- package/dist/extensions/question/navigation.ts +14 -0
- package/dist/extensions/question/package.json +18 -0
- package/dist/extensions/question/question-list.ts +498 -0
- package/dist/extensions/question/row-layout.ts +162 -0
- package/dist/extensions/question/schemas.ts +69 -0
- package/dist/extensions/question/selection-mode.ts +49 -0
- package/dist/extensions/question/shortcuts.ts +53 -0
- package/dist/extensions/question/tests/helpers.test.ts +178 -0
- package/dist/extensions/question/tests/question-list.test.ts +230 -0
- package/dist/extensions/question/tests/row-layout.test.ts +136 -0
- package/dist/extensions/question/tests/shortcuts.test.ts +85 -0
- package/dist/extensions/question/tests/ui-protocol.test.ts +143 -0
- package/dist/extensions/question/tui-adapter.ts +33 -0
- package/dist/extensions/question/types.ts +102 -0
- package/dist/extensions/question/ui-protocol.ts +46 -0
- package/dist/extensions/tokenin-onboarding.ts +265 -2
- package/dist/extensions/web-agent-onboarding.ts +222 -0
- package/dist/extensions/workflow/adapter.ts +588 -0
- package/dist/extensions/workflow/extension.ts +24 -0
- package/dist/extensions/workflow/modes/prototype.ts +156 -0
- package/dist/extensions/workflow/modes/quick.ts +138 -0
- package/dist/extensions/workflow/package.json +17 -0
- package/dist/extensions/workflow/state-machine.ts +386 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +2 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +57 -13
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/utils/mime.d.ts.map +1 -1
- package/dist/utils/mime.js +24 -1
- package/dist/utils/mime.js.map +1 -1
- package/docs/docs.json +4 -0
- package/docs/workflows.md +206 -0
- package/package.json +5 -1
- package/README.md +0 -198
|
@@ -22,12 +22,13 @@ export interface LoadedCounts {
|
|
|
22
22
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
23
23
|
|
|
24
24
|
const PI_LOGO = [
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
25
|
+
"███ ███ █ ███ ███ ███ █",
|
|
26
|
+
"█ █ █ █ █ █ █ █",
|
|
27
|
+
"█ █ █ █ █ █ █ █",
|
|
28
|
+
"███ ███ █ ███ ███ ███ █",
|
|
29
|
+
" █ █ █ █ █ █ █ █",
|
|
30
|
+
" █ █ █ █ █ █ █ █",
|
|
31
|
+
"███ ███ ███ ███ ███ █ █ █",
|
|
31
32
|
];
|
|
32
33
|
|
|
33
34
|
const GRADIENT_COLORS = [
|
|
@@ -89,7 +90,7 @@ interface WelcomeData {
|
|
|
89
90
|
|
|
90
91
|
function buildLeftColumn(data: WelcomeData, colWidth: number): string[] {
|
|
91
92
|
const logoColored = PI_LOGO.map((line) => gradientLine(line));
|
|
92
|
-
|
|
93
|
+
|
|
93
94
|
return [
|
|
94
95
|
"",
|
|
95
96
|
centerText(bold("Welcome back!"), colWidth),
|
|
@@ -104,7 +105,7 @@ function buildLeftColumn(data: WelcomeData, colWidth: number): string[] {
|
|
|
104
105
|
function buildRightColumn(data: WelcomeData, colWidth: number): string[] {
|
|
105
106
|
const hChar = "─";
|
|
106
107
|
const separator = ` ${dim(hChar.repeat(colWidth - 2))}`;
|
|
107
|
-
|
|
108
|
+
|
|
108
109
|
// Session lines
|
|
109
110
|
const sessionLines: string[] = [];
|
|
110
111
|
if (data.recentSessions.length === 0) {
|
|
@@ -116,12 +117,12 @@ function buildRightColumn(data: WelcomeData, colWidth: number): string[] {
|
|
|
116
117
|
);
|
|
117
118
|
}
|
|
118
119
|
}
|
|
119
|
-
|
|
120
|
+
|
|
120
121
|
// Loaded counts lines
|
|
121
122
|
const countLines: string[] = [];
|
|
122
123
|
const { contextFiles, extensions, skills, promptTemplates } = data.loadedCounts;
|
|
123
124
|
const itemPrefix = dim("- ");
|
|
124
|
-
|
|
125
|
+
|
|
125
126
|
if (contextFiles > 0 || extensions > 0 || skills > 0 || promptTemplates > 0) {
|
|
126
127
|
if (contextFiles > 0) {
|
|
127
128
|
countLines.push(` ${itemPrefix}${fgOnly("gitClean", `${contextFiles}`)} context file${contextFiles !== 1 ? "s" : ""}`);
|
|
@@ -138,7 +139,7 @@ function buildRightColumn(data: WelcomeData, colWidth: number): string[] {
|
|
|
138
139
|
} else {
|
|
139
140
|
countLines.push(` ${dim("No extensions loaded")}`);
|
|
140
141
|
}
|
|
141
|
-
|
|
142
|
+
|
|
142
143
|
return [
|
|
143
144
|
` ${bold(fgOnly("accent", "Tips"))}`,
|
|
144
145
|
` ${dim("/")} for commands`,
|
|
@@ -155,46 +156,46 @@ function buildRightColumn(data: WelcomeData, colWidth: number): string[] {
|
|
|
155
156
|
}
|
|
156
157
|
|
|
157
158
|
function renderWelcomeBox(
|
|
158
|
-
data: WelcomeData,
|
|
159
|
-
termWidth: number,
|
|
159
|
+
data: WelcomeData,
|
|
160
|
+
termWidth: number,
|
|
160
161
|
bottomLine: string,
|
|
161
162
|
): string[] {
|
|
162
163
|
// Minimum width for two-column layout: leftCol(26) + separator(3) + minRightCol(15) = 44
|
|
163
164
|
const minLayoutWidth = 44;
|
|
164
|
-
|
|
165
|
+
|
|
165
166
|
// If terminal is too narrow for the layout, return empty (skip welcome box)
|
|
166
167
|
if (termWidth < minLayoutWidth) {
|
|
167
168
|
return [];
|
|
168
169
|
}
|
|
169
|
-
|
|
170
|
+
|
|
170
171
|
const minWidth = 76;
|
|
171
172
|
const maxWidth = 96;
|
|
172
173
|
// Clamp to termWidth to prevent crash on narrow terminals
|
|
173
174
|
const boxWidth = Math.min(termWidth, Math.max(minWidth, Math.min(termWidth - 2, maxWidth)));
|
|
174
175
|
const leftCol = 26;
|
|
175
176
|
const rightCol = Math.max(1, boxWidth - leftCol - 3); // Ensure rightCol is at least 1
|
|
176
|
-
|
|
177
|
+
|
|
177
178
|
const hChar = "─";
|
|
178
179
|
const v = dim("│");
|
|
179
180
|
const tl = dim("╭");
|
|
180
181
|
const tr = dim("╮");
|
|
181
182
|
const bl = dim("╰");
|
|
182
183
|
const br = dim("╯");
|
|
183
|
-
|
|
184
|
+
|
|
184
185
|
const leftLines = buildLeftColumn(data, leftCol);
|
|
185
186
|
const rightLines = buildRightColumn(data, rightCol);
|
|
186
|
-
|
|
187
|
+
|
|
187
188
|
const lines: string[] = [];
|
|
188
|
-
|
|
189
|
+
|
|
189
190
|
// Top border with title
|
|
190
|
-
const title = "
|
|
191
|
+
const title = "SelesaiCode";
|
|
191
192
|
const titlePrefix = dim(hChar.repeat(3));
|
|
192
193
|
const titleStyled = titlePrefix + fgOnly("model", title);
|
|
193
194
|
const titleVisLen = 3 + visibleWidth(title);
|
|
194
195
|
const afterTitle = boxWidth - 2 - titleVisLen;
|
|
195
196
|
const afterTitleText = afterTitle > 0 ? dim(hChar.repeat(afterTitle)) : "";
|
|
196
197
|
lines.push(tl + titleStyled + afterTitleText + tr);
|
|
197
|
-
|
|
198
|
+
|
|
198
199
|
// Content rows
|
|
199
200
|
const maxRows = Math.max(leftLines.length, rightLines.length);
|
|
200
201
|
for (let i = 0; i < maxRows; i++) {
|
|
@@ -202,10 +203,10 @@ function renderWelcomeBox(
|
|
|
202
203
|
const right = fitToWidth(rightLines[i] ?? "", rightCol);
|
|
203
204
|
lines.push(v + left + v + right + v);
|
|
204
205
|
}
|
|
205
|
-
|
|
206
|
+
|
|
206
207
|
// Bottom border
|
|
207
208
|
lines.push(bl + bottomLine + br);
|
|
208
|
-
|
|
209
|
+
|
|
209
210
|
return lines;
|
|
210
211
|
}
|
|
211
212
|
|
|
@@ -214,7 +215,7 @@ function renderWelcomeBox(
|
|
|
214
215
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
215
216
|
|
|
216
217
|
/**
|
|
217
|
-
* Welcome overlay component for
|
|
218
|
+
* Welcome overlay component for SelesaiCode.
|
|
218
219
|
* Displays a branded splash screen with logo, tips, and loaded counts.
|
|
219
220
|
*/
|
|
220
221
|
export class WelcomeComponent implements Component {
|
|
@@ -242,12 +243,12 @@ export class WelcomeComponent implements Component {
|
|
|
242
243
|
if (termWidth < minLayoutWidth) {
|
|
243
244
|
return [];
|
|
244
245
|
}
|
|
245
|
-
|
|
246
|
+
|
|
246
247
|
const minWidth = 76;
|
|
247
248
|
const maxWidth = 96;
|
|
248
249
|
// Clamp to termWidth to prevent crash on narrow terminals
|
|
249
250
|
const boxWidth = Math.min(termWidth, Math.max(minWidth, Math.min(termWidth - 2, maxWidth)));
|
|
250
|
-
|
|
251
|
+
|
|
251
252
|
// Bottom line with countdown
|
|
252
253
|
const countdownText = ` Press any key to continue (${this.countdown}s) `;
|
|
253
254
|
const countdownStyled = dim(countdownText);
|
|
@@ -256,10 +257,10 @@ export class WelcomeComponent implements Component {
|
|
|
256
257
|
const leftPad = Math.floor((bottomContentWidth - countdownVisLen) / 2);
|
|
257
258
|
const rightPad = bottomContentWidth - countdownVisLen - leftPad;
|
|
258
259
|
const hChar = "─";
|
|
259
|
-
const bottomLine = dim(hChar.repeat(Math.max(0, leftPad))) +
|
|
260
|
-
countdownStyled +
|
|
260
|
+
const bottomLine = dim(hChar.repeat(Math.max(0, leftPad))) +
|
|
261
|
+
countdownStyled +
|
|
261
262
|
dim(hChar.repeat(Math.max(0, rightPad)));
|
|
262
|
-
|
|
263
|
+
|
|
263
264
|
return renderWelcomeBox(this.data, termWidth, bottomLine);
|
|
264
265
|
}
|
|
265
266
|
}
|
|
@@ -288,18 +289,18 @@ export class WelcomeHeader implements Component {
|
|
|
288
289
|
if (termWidth < minLayoutWidth) {
|
|
289
290
|
return [];
|
|
290
291
|
}
|
|
291
|
-
|
|
292
|
+
|
|
292
293
|
const minWidth = 76;
|
|
293
294
|
const maxWidth = 96;
|
|
294
295
|
// Clamp to termWidth to prevent crash on narrow terminals
|
|
295
296
|
const boxWidth = Math.min(termWidth, Math.max(minWidth, Math.min(termWidth - 2, maxWidth)));
|
|
296
297
|
const hChar = "─";
|
|
297
|
-
|
|
298
|
+
|
|
298
299
|
// Bottom line with column separator (leftCol=26, rightCol=boxWidth-29)
|
|
299
300
|
const leftCol = 26;
|
|
300
301
|
const rightCol = Math.max(1, boxWidth - leftCol - 3);
|
|
301
302
|
const bottomLine = dim(hChar.repeat(leftCol)) + dim("┴") + dim(hChar.repeat(rightCol));
|
|
302
|
-
|
|
303
|
+
|
|
303
304
|
const lines = renderWelcomeBox(this.data, termWidth, bottomLine);
|
|
304
305
|
if (lines.length > 0) {
|
|
305
306
|
lines.push(""); // Add empty line for spacing only if we rendered content
|
|
@@ -335,7 +336,7 @@ function logDiscoveryError(scope: string, error: unknown): void {
|
|
|
335
336
|
export function discoverLoadedCounts(): LoadedCounts {
|
|
336
337
|
const homeDir = process.env.HOME || process.env.USERPROFILE || osHomedir();
|
|
337
338
|
const cwd = process.cwd();
|
|
338
|
-
|
|
339
|
+
|
|
339
340
|
let contextFiles = 0;
|
|
340
341
|
let extensions = 0;
|
|
341
342
|
let skills = 0;
|
|
@@ -348,7 +349,7 @@ export function discoverLoadedCounts(): LoadedCounts {
|
|
|
348
349
|
join(cwd, ".pi", "AGENTS.md"),
|
|
349
350
|
join(cwd, ".claude", "AGENTS.md"),
|
|
350
351
|
];
|
|
351
|
-
|
|
352
|
+
|
|
352
353
|
for (const path of agentsMdPaths) {
|
|
353
354
|
if (existsSync(path)) contextFiles++;
|
|
354
355
|
}
|
|
@@ -463,9 +464,9 @@ export function discoverLoadedCounts(): LoadedCounts {
|
|
|
463
464
|
join(cwd, ".pi", "skills"),
|
|
464
465
|
join(cwd, "skills"),
|
|
465
466
|
];
|
|
466
|
-
|
|
467
|
+
|
|
467
468
|
const countedSkills = new Set<string>();
|
|
468
|
-
|
|
469
|
+
|
|
469
470
|
for (const dir of skillDirs) {
|
|
470
471
|
if (existsSync(dir)) {
|
|
471
472
|
try {
|
|
@@ -497,9 +498,9 @@ export function discoverLoadedCounts(): LoadedCounts {
|
|
|
497
498
|
join(cwd, ".pi", "commands"),
|
|
498
499
|
join(cwd, ".claude", "commands"),
|
|
499
500
|
];
|
|
500
|
-
|
|
501
|
+
|
|
501
502
|
const countedTemplates = new Set<string>();
|
|
502
|
-
|
|
503
|
+
|
|
503
504
|
function countTemplatesInDir(dir: string) {
|
|
504
505
|
if (!existsSync(dir)) return;
|
|
505
506
|
try {
|
|
@@ -525,7 +526,7 @@ export function discoverLoadedCounts(): LoadedCounts {
|
|
|
525
526
|
logDiscoveryError(`Failed to scan prompt template dir ${dir}`, error);
|
|
526
527
|
}
|
|
527
528
|
}
|
|
528
|
-
|
|
529
|
+
|
|
529
530
|
for (const dir of templateDirs) {
|
|
530
531
|
countTemplatesInDir(dir);
|
|
531
532
|
}
|
|
@@ -538,14 +539,14 @@ export function discoverLoadedCounts(): LoadedCounts {
|
|
|
538
539
|
*/
|
|
539
540
|
export function getRecentSessions(maxCount: number = 3): RecentSession[] {
|
|
540
541
|
const homeDir = process.env.HOME || process.env.USERPROFILE || osHomedir();
|
|
541
|
-
|
|
542
|
+
|
|
542
543
|
const sessionsDirs = [
|
|
543
544
|
join(homeDir, ".pi", "agent", "sessions"),
|
|
544
545
|
join(homeDir, ".pi", "sessions"),
|
|
545
546
|
];
|
|
546
|
-
|
|
547
|
+
|
|
547
548
|
const sessions: { name: string; mtime: number }[] = [];
|
|
548
|
-
|
|
549
|
+
|
|
549
550
|
function scanDir(dir: string) {
|
|
550
551
|
if (!existsSync(dir)) return;
|
|
551
552
|
try {
|
|
@@ -573,15 +574,15 @@ export function getRecentSessions(maxCount: number = 3): RecentSession[] {
|
|
|
573
574
|
logDiscoveryError(`Failed to scan sessions dir ${dir}`, error);
|
|
574
575
|
}
|
|
575
576
|
}
|
|
576
|
-
|
|
577
|
+
|
|
577
578
|
for (const sessionsDir of sessionsDirs) {
|
|
578
579
|
scanDir(sessionsDir);
|
|
579
580
|
}
|
|
580
|
-
|
|
581
|
+
|
|
581
582
|
if (sessions.length === 0) return [];
|
|
582
|
-
|
|
583
|
+
|
|
583
584
|
sessions.sort((a, b) => b.mtime - a.mtime);
|
|
584
|
-
|
|
585
|
+
|
|
585
586
|
const seen = new Set<string>();
|
|
586
587
|
const uniqueSessions: typeof sessions = [];
|
|
587
588
|
for (const s of sessions) {
|
|
@@ -523,11 +523,7 @@ Project discovery also reads legacy `.agents/**/*.md` files. Nested subdirectori
|
|
|
523
523
|
|
|
524
524
|
Builtin agents load at the lowest priority, so a user or project agent with the same name overrides them. They do not pin a provider model; they inherit your current Pi default model unless you set `subagents.agentOverrides.<name>.model`. `oracle` is an advisory reviewer that critiques direction and proposes an execution prompt without editing files. `worker` is the implementation agent for normal tasks and approved oracle handoffs.
|
|
525
525
|
|
|
526
|
-
The `researcher`
|
|
527
|
-
|
|
528
|
-
```bash
|
|
529
|
-
pi install npm:pi-web-access
|
|
530
|
-
```
|
|
526
|
+
The `researcher` and `context-builder` builtins use `web_explore`, provided by the bundled [`pi-web-agent`](https://github.com/demigodmode/pi-web-agent) extension (`src/extensions/pi-web-agent`) — no external install is required. Brave Search is optional: on first run you will be prompted for a Brave API key (get one at <https://api.dashboard.search.brave.com/app/keys>), or you can set `webAgent.braveApiKey` in `~/.selesai/agent/settings.json` directly. If you skip Brave, `web_explore` falls back to the default DuckDuckGo backend (no key needed).
|
|
531
527
|
|
|
532
528
|
### Builtin overrides
|
|
533
529
|
|
|
@@ -1235,6 +1231,16 @@ export PI_SUBAGENT_MAX_DEPTH=0
|
|
|
1235
1231
|
|
|
1236
1232
|
`PI_SUBAGENT_DEPTH` is internal and propagated automatically. Do not set it manually.
|
|
1237
1233
|
|
|
1234
|
+
## Building the async runner
|
|
1235
|
+
|
|
1236
|
+
The async runner can be pre-transpiled to JavaScript so background runs do not pay the jiti TypeScript JIT cost. To build it:
|
|
1237
|
+
|
|
1238
|
+
```bash
|
|
1239
|
+
npm run build:runner
|
|
1240
|
+
```
|
|
1241
|
+
|
|
1242
|
+
This writes `dist/runner/runs/background/subagent-runner.js` and its dependencies. The launch path automatically prefers the compiled runner when it exists and falls back to the previous `node jiti subagent-runner.ts` path otherwise. Set `SELESAI_SUBAGENT_RUNNER_USE_JITI=1` to force the old jiti path for troubleshooting.
|
|
1243
|
+
|
|
1238
1244
|
## Events
|
|
1239
1245
|
|
|
1240
1246
|
Async events:
|
|
@@ -1285,6 +1291,7 @@ The main runtime files are:
|
|
|
1285
1291
|
| `src/runs/foreground/chain-execution.ts` / `src/agents/chain-serializer.ts` | Chain orchestration and `.chain.md` parsing. |
|
|
1286
1292
|
| `src/shared/settings.ts` | Chain behavior, instructions, and config helpers. |
|
|
1287
1293
|
| `src/runs/shared/worktree.ts` | Git worktree isolation. |
|
|
1294
|
+
| `src/runs/shared/spawn-timing.ts` | Spawn latency timing probes. |
|
|
1288
1295
|
| `src/intercom/intercom-bridge.ts` | Runtime intercom bridge instructions and diagnostics. |
|
|
1289
1296
|
| `src/extension/schemas.ts` / `src/shared/types.ts` | Tool schemas, shared types, and event constants. |
|
|
1290
1297
|
| `test/unit/` / `test/integration/` | Unit and loader-based integration tests. |
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: context-builder
|
|
3
3
|
description: Analyzes requirements and codebase, generates context and meta-prompt
|
|
4
|
-
tools: read, grep, find, ls, bash, write,
|
|
4
|
+
tools: read, grep, find, ls, bash, write, web_explore, intercom
|
|
5
5
|
thinking: medium
|
|
6
6
|
systemPromptMode: replace
|
|
7
7
|
inheritProjectContext: true
|
|
@@ -18,7 +18,7 @@ Working rules:
|
|
|
18
18
|
- Search the codebase for relevant files, patterns, dependencies, and constraints.
|
|
19
19
|
- Read every file needed to fully understand the issue, not just the first matching symbol. Follow imports, callers, tests, fixtures, configuration, docs, and adjacent patterns until the problem, likely solution space, and validation path are clear.
|
|
20
20
|
- If a referenced URL, issue, PR, plan, design doc, or local file is part of the request, read or fetch it before writing the handoff.
|
|
21
|
-
- Conduct web research when the task depends on external APIs, libraries, current best practices, recently changed behavior, or when local evidence is not enough to know how to solve the problem correctly. Use `
|
|
21
|
+
- Conduct web research when the task depends on external APIs, libraries, current best practices, recently changed behavior, or when local evidence is not enough to know how to solve the problem correctly. Use `web_explore` (it handles search, fetch, and source ranking internally; call again with a narrower query for follow-ups).
|
|
22
22
|
- Keep searching or researching until you can state the likely implementation approach, risks, and validation with evidence. If a gap remains, call it out explicitly instead of implying certainty.
|
|
23
23
|
- Write the requested output files clearly and concretely.
|
|
24
24
|
- Prefer distilled, high-signal context over exhaustive dumps, but do not omit a relevant file or source just to keep the handoff short.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: researcher
|
|
3
3
|
description: Autonomous web researcher — searches, evaluates, and synthesizes a focused research brief
|
|
4
|
-
tools: read, write,
|
|
4
|
+
tools: read, write, web_explore, intercom
|
|
5
5
|
thinking: medium
|
|
6
6
|
systemPromptMode: replace
|
|
7
7
|
inheritProjectContext: true
|
|
@@ -16,12 +16,11 @@ Given a question or topic, run focused web research and produce a concise, well-
|
|
|
16
16
|
|
|
17
17
|
Working rules:
|
|
18
18
|
- Break the problem into 2-4 distinct research angles.
|
|
19
|
-
- Use `
|
|
20
|
-
-
|
|
21
|
-
- Read the search results first. Then fetch full content only for the most promising source URLs.
|
|
19
|
+
- Use `web_explore` for each angle; it handles search, fetch, source ranking, and headless escalation internally. One call covers search + fetch + ranking.
|
|
20
|
+
- For follow-ups or gaps after the first pass, call `web_explore` again with a narrower query instead of fetching URLs manually.
|
|
22
21
|
- Prefer primary sources, official docs, specs, benchmarks, and direct evidence over commentary.
|
|
23
22
|
- Drop stale, redundant, or SEO-heavy sources.
|
|
24
|
-
- If the first
|
|
23
|
+
- If the first explore pass leaves important gaps, explore again with tighter follow-up queries.
|
|
25
24
|
|
|
26
25
|
Search strategy:
|
|
27
26
|
- direct answer query
|
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
"keywords": [
|
|
17
17
|
"pi-package",
|
|
18
18
|
"pi",
|
|
19
|
-
"
|
|
19
|
+
"selesai",
|
|
20
|
+
"selesai-code",
|
|
20
21
|
"subagents",
|
|
21
22
|
"ai",
|
|
22
23
|
"agents",
|
|
@@ -27,6 +28,7 @@
|
|
|
27
28
|
},
|
|
28
29
|
"files": [
|
|
29
30
|
"src/**/*.ts",
|
|
31
|
+
"dist/runner/**/*",
|
|
30
32
|
"*.mjs",
|
|
31
33
|
"agents/",
|
|
32
34
|
"skills/**/*",
|
|
@@ -38,7 +40,8 @@
|
|
|
38
40
|
"test": "npm run test:unit",
|
|
39
41
|
"test:unit": "node --experimental-strip-types --test test/unit/*.test.ts",
|
|
40
42
|
"test:integration": "node --experimental-transform-types --import ./test/support/register-loader.mjs --test test/integration/*.test.ts",
|
|
41
|
-
"test:all": "npm run test:unit && npm run test:integration"
|
|
43
|
+
"test:all": "npm run test:unit && npm run test:integration",
|
|
44
|
+
"build:runner": "tsc -p tsconfig.runner.json"
|
|
42
45
|
},
|
|
43
46
|
"pi": {
|
|
44
47
|
"extensions": [
|
|
@@ -57,7 +60,7 @@
|
|
|
57
60
|
"peerDependencies": {
|
|
58
61
|
"@earendil-works/pi-agent-core": "*",
|
|
59
62
|
"@earendil-works/pi-ai": "*",
|
|
60
|
-
"@
|
|
63
|
+
"@selesai/code": "*"
|
|
61
64
|
},
|
|
62
65
|
"peerDependenciesMeta": {
|
|
63
66
|
"@earendil-works/pi-agent-core": {
|
|
@@ -66,7 +69,7 @@
|
|
|
66
69
|
"@earendil-works/pi-ai": {
|
|
67
70
|
"optional": true
|
|
68
71
|
},
|
|
69
|
-
"@
|
|
72
|
+
"@selesai/code": {
|
|
70
73
|
"optional": true
|
|
71
74
|
}
|
|
72
75
|
},
|
|
@@ -78,6 +81,6 @@
|
|
|
78
81
|
"devDependencies": {
|
|
79
82
|
"@earendil-works/pi-agent-core": "0.74.0",
|
|
80
83
|
"@earendil-works/pi-ai": "0.74.0",
|
|
81
|
-
"@
|
|
84
|
+
"@selesai/code": "0.74.0"
|
|
82
85
|
}
|
|
83
86
|
}
|
|
@@ -34,7 +34,7 @@ Choose two or three strong builders based on the request. Prefer three only when
|
|
|
34
34
|
Adapt the angles when the request calls for it:
|
|
35
35
|
- Issue or PR URL: include issue requirements, acceptance criteria, linked discussion, and likely affected files.
|
|
36
36
|
- Plan file: include plan consistency, missing context, implementation sequence, and validation readiness.
|
|
37
|
-
- External API/library work: include current docs or primary sources through `
|
|
37
|
+
- External API/library work: include current docs or primary sources through `web_explore` when needed.
|
|
38
38
|
- Large refactor: include module boundaries, dependency direction, migration/cutover risks, and testability.
|
|
39
39
|
- UI/product work: include user flow, accessibility, copy, visual constraints, and implementation touchpoints.
|
|
40
40
|
|
|
@@ -34,7 +34,7 @@ Role guidance:
|
|
|
34
34
|
External reference researcher:
|
|
35
35
|
- Study linked projects, docs, issues, examples, source code, or prompt guidance.
|
|
36
36
|
- Identify the behavior, API, implementation files, constraints, and transferable ideas.
|
|
37
|
-
- Conduct web research if needed. Use `
|
|
37
|
+
- Conduct web research if needed. Use `web_explore` (it handles search, fetch, and source ranking internally; call again with a narrower query for follow-ups).
|
|
38
38
|
- Return source links, repo paths, key evidence, risks, and what matters for this implementation.
|
|
39
39
|
|
|
40
40
|
Local context-builder:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
import type { AgentToolResult } from "@earendil-works/pi-agent-core";
|
|
4
|
-
import type { ExtensionContext } from "@
|
|
4
|
+
import type { ExtensionContext } from "@selesai/code";
|
|
5
5
|
import {
|
|
6
6
|
type AgentConfig,
|
|
7
7
|
type AgentScope,
|
|
@@ -1217,10 +1217,10 @@ function resolveNearestProjectChainDirs(cwd: string): { readDirs: string[]; pref
|
|
|
1217
1217
|
}
|
|
1218
1218
|
const BUILTIN_AGENTS_DIR = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "..", "agents");
|
|
1219
1219
|
|
|
1220
|
-
export const EXTRA_AGENT_DIRS_ENV = "
|
|
1220
|
+
export const EXTRA_AGENT_DIRS_ENV = "SELESAI_SUBAGENT_EXTRA_AGENT_DIRS";
|
|
1221
1221
|
|
|
1222
1222
|
// Additional read-only directories to scan for agent definitions, supplied by the
|
|
1223
|
-
// launcher via
|
|
1223
|
+
// launcher via SELESAI_SUBAGENT_EXTRA_AGENT_DIRS (PATH-style, split on os/path delimiter).
|
|
1224
1224
|
// Lets a hermetic wrapper (e.g. a Nix-store install) expose bundled agents without
|
|
1225
1225
|
// copying or symlinking them into the writable agent dir. Loaded as "user" source,
|
|
1226
1226
|
// at lower precedence than agents the user placed in their own agent dir.
|
|
@@ -1373,7 +1373,7 @@ export function discoverAgentsAll(cwd: string): {
|
|
|
1373
1373
|
...projectChainDiagnostics,
|
|
1374
1374
|
];
|
|
1375
1375
|
|
|
1376
|
-
const userDir = process.env.
|
|
1376
|
+
const userDir = process.env.SELESAI_CODING_AGENT_DIR ? userDirOld : fs.existsSync(userDirNew) ? userDirNew : userDirOld;
|
|
1377
1377
|
|
|
1378
1378
|
return { builtin, package: packageAgents, user, project, chains, chainDiagnostics, userDir, projectDir, userChainDir, projectChainDir, userSettingsPath, projectSettingsPath };
|
|
1379
1379
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ExtensionAPI } from "@
|
|
1
|
+
import type { ExtensionAPI } from "@selesai/code";
|
|
2
2
|
import { controlNotificationKey, formatControlNoticeMessage } from "../runs/shared/subagent-control.ts";
|
|
3
3
|
import type { ControlEvent, SubagentState } from "../shared/types.ts";
|
|
4
4
|
|
|
@@ -170,15 +170,15 @@ function formatIntercomDiagnostic(diagnostic: IntercomBridgeDiagnostic, context:
|
|
|
170
170
|
|
|
171
171
|
function formatPermissionSystemSection(): string[] {
|
|
172
172
|
const lines: string[] = [];
|
|
173
|
-
const parentSession = process.env["
|
|
173
|
+
const parentSession = process.env["SELESAI_SUBAGENT_PARENT_SESSION"] ?? "";
|
|
174
174
|
const trimmed = parentSession.trim();
|
|
175
175
|
if (trimmed) {
|
|
176
176
|
lines.push(`- parent session: set (${trimmed})`);
|
|
177
177
|
} else {
|
|
178
178
|
lines.push("- parent session: not set — ask forwarding from subprocess children will not reach a parent UI");
|
|
179
179
|
}
|
|
180
|
-
const isChild = process.env["
|
|
181
|
-
lines.push(`- subagent process: ${isChild ? "yes (
|
|
180
|
+
const isChild = process.env["SELESAI_SUBAGENT_CHILD"] === "1";
|
|
181
|
+
lines.push(`- subagent process: ${isChild ? "yes (SELESAI_SUBAGENT_CHILD=1)" : "no"}`);
|
|
182
182
|
// Whether pi-permission-system is installed and where it stores config is
|
|
183
183
|
// outside pi-subagents' control, so we only report the forwarding signal we
|
|
184
184
|
// own. Run `pi list` to confirm the permission extension is installed.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as os from "node:os";
|
|
3
3
|
import * as path from "node:path";
|
|
4
|
-
import type { ExtensionAPI, ToolDefinition } from "@
|
|
4
|
+
import type { ExtensionAPI, ToolDefinition } from "@selesai/code";
|
|
5
5
|
import { discoverAgents } from "../agents/agents.ts";
|
|
6
6
|
import { getArtifactsDir } from "../shared/artifacts.ts";
|
|
7
7
|
import { createSubagentExecutor, type SubagentParamsLike } from "../runs/foreground/subagent-executor.ts";
|
|
@@ -15,8 +15,9 @@
|
|
|
15
15
|
import * as fs from "node:fs";
|
|
16
16
|
import * as os from "node:os";
|
|
17
17
|
import * as path from "node:path";
|
|
18
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
18
19
|
import type { AgentToolResult } from "@earendil-works/pi-agent-core";
|
|
19
|
-
import { type ExtensionAPI, type ExtensionContext, type ToolDefinition } from "@
|
|
20
|
+
import { type ExtensionAPI, type ExtensionContext, type ToolDefinition } from "@selesai/code";
|
|
20
21
|
import { Box, Container, Spacer, Text, truncateToWidth, visibleWidth, wrapTextWithAnsi, type Component } from "@earendil-works/pi-tui";
|
|
21
22
|
import { discoverAgents } from "../agents/agents.ts";
|
|
22
23
|
import { cleanupAllArtifactDirs, cleanupOldArtifacts, getArtifactsDir } from "../shared/artifacts.ts";
|
|
@@ -59,6 +60,32 @@ import {
|
|
|
59
60
|
|
|
60
61
|
export { loadConfig } from "./config.ts";
|
|
61
62
|
|
|
63
|
+
function resolveRunnerScript(): string {
|
|
64
|
+
const srcDir = path.dirname(fileURLToPath(import.meta.url));
|
|
65
|
+
const candidates = [
|
|
66
|
+
path.join(srcDir, "..", "runs", "background", "subagent-runner.js"),
|
|
67
|
+
path.join(srcDir, "..", "..", "dist", "runner", "runs", "background", "subagent-runner.js"),
|
|
68
|
+
path.join(srcDir, "..", "runs", "background", "subagent-runner.ts"),
|
|
69
|
+
];
|
|
70
|
+
for (const candidate of candidates) {
|
|
71
|
+
if (fs.existsSync(candidate)) return candidate;
|
|
72
|
+
}
|
|
73
|
+
throw new Error("Could not resolve subagent-runner script");
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const runnerConfigPath = process.env.SELESAI_SUBAGENT_RUNNER_CONFIG;
|
|
77
|
+
if (runnerConfigPath) {
|
|
78
|
+
(async () => {
|
|
79
|
+
const runnerScript = resolveRunnerScript();
|
|
80
|
+
const runnerModule = await import(pathToFileURL(runnerScript).href);
|
|
81
|
+
await runnerModule.runSubagentFromConfigFile(runnerConfigPath);
|
|
82
|
+
process.exit(0);
|
|
83
|
+
})().catch((error) => {
|
|
84
|
+
console.error("Subagent runner hook failed:", error);
|
|
85
|
+
process.exit(1);
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
62
89
|
/**
|
|
63
90
|
* Derive subagent session base directory from parent session file.
|
|
64
91
|
* If parent session is ~/.pi/agent/sessions/abc123.jsonl,
|
|
@@ -564,7 +591,7 @@ DIAGNOSTICS:
|
|
|
564
591
|
const resetSessionState = (ctx: ExtensionContext) => {
|
|
565
592
|
state.baseCwd = ctx.cwd;
|
|
566
593
|
state.currentSessionId = resolveCurrentSessionId(ctx.sessionManager);
|
|
567
|
-
// Set
|
|
594
|
+
// Set SELESAI_SUBAGENT_PARENT_SESSION for permission-system forwarding.
|
|
568
595
|
// Only set in the root session (the interactive UI session), not in
|
|
569
596
|
// child subagent processes — children inherit the parent's value
|
|
570
597
|
// through the process environment at spawn time and must not overwrite
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as os from "node:os";
|
|
3
3
|
import * as path from "node:path";
|
|
4
|
-
import type { ExtensionAPI, ExtensionContext } from "@
|
|
4
|
+
import type { ExtensionAPI, ExtensionContext } from "@selesai/code";
|
|
5
5
|
import { BUILTIN_AGENT_NAMES } from "../agents/agents.ts";
|
|
6
6
|
import { findModelInfo, getSupportedThinkingLevels, splitKnownThinkingSuffix, toModelInfo } from "../shared/model-info.ts";
|
|
7
7
|
import { getAgentDir } from "../shared/utils.ts";
|
|
@@ -323,7 +323,7 @@ async function probeModel(
|
|
|
323
323
|
if (typeof pi.exec !== "function") {
|
|
324
324
|
return { status: "skipped", message: "pi.exec is unavailable in this runtime." };
|
|
325
325
|
}
|
|
326
|
-
const result = await pi.exec("
|
|
326
|
+
const result = await pi.exec("selesai", ["-p", "--model", fullId, "--no-tools", 'Reply with exactly "OK".'], {
|
|
327
327
|
cwd: os.tmpdir(),
|
|
328
328
|
timeout: 45_000,
|
|
329
329
|
} as Record<string, unknown>);
|