pi-ui-extend 1.0.41 → 1.0.45
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 +50 -13
- package/dist/app/app.d.ts +13 -0
- package/dist/app/app.js +158 -8
- package/dist/app/cli/install.js +2 -2
- package/dist/app/commands/command-controller.d.ts +4 -0
- package/dist/app/commands/command-controller.js +11 -0
- package/dist/app/commands/command-git-actions.d.ts +25 -0
- package/dist/app/commands/command-git-actions.js +381 -0
- package/dist/app/commands/command-host.d.ts +4 -0
- package/dist/app/commands/command-host.js +5 -2
- package/dist/app/commands/command-model-actions.d.ts +1 -0
- package/dist/app/commands/command-model-actions.js +57 -35
- package/dist/app/commands/command-navigation-actions.d.ts +1 -0
- package/dist/app/commands/command-navigation-actions.js +16 -3
- package/dist/app/commands/command-registry.d.ts +2 -0
- package/dist/app/commands/command-registry.js +15 -1
- package/dist/app/commands/command-session-actions.js +9 -3
- package/dist/app/commands/reload-context-inventory.d.ts +11 -0
- package/dist/app/commands/reload-context-inventory.js +70 -0
- package/dist/app/extensions/extension-actions-controller.d.ts +1 -0
- package/dist/app/extensions/extension-actions-controller.js +6 -0
- package/dist/app/extensions/subagent-catalog-state.d.ts +9 -0
- package/dist/app/extensions/subagent-catalog-state.js +23 -0
- package/dist/app/input/autocomplete-controller.js +61 -34
- package/dist/app/input/input-action-controller.d.ts +2 -0
- package/dist/app/input/input-action-controller.js +8 -1
- package/dist/app/input/input-controller.d.ts +2 -1
- package/dist/app/input/input-controller.js +7 -2
- package/dist/app/input/prompt-enhancer-controller.js +53 -35
- package/dist/app/input/voice-controller.d.ts +41 -45
- package/dist/app/input/voice-controller.js +351 -419
- package/dist/app/model/model-usage-controller.js +17 -7
- package/dist/app/model/model-usage-status.d.ts +4 -1
- package/dist/app/model/model-usage-status.js +270 -46
- package/dist/app/popup/menu-items-controller.d.ts +13 -3
- package/dist/app/popup/menu-items-controller.js +37 -21
- package/dist/app/popup/popup-action-controller.d.ts +12 -2
- package/dist/app/popup/popup-action-controller.js +77 -24
- package/dist/app/popup/popup-menu-controller.d.ts +36 -14
- package/dist/app/popup/popup-menu-controller.js +239 -69
- package/dist/app/rendering/dcp-stats.d.ts +9 -4
- package/dist/app/rendering/dcp-stats.js +40 -425
- package/dist/app/rendering/editor-panels.js +10 -4
- package/dist/app/rendering/popup-menu-renderer.d.ts +3 -5
- package/dist/app/rendering/popup-menu-renderer.js +42 -37
- package/dist/app/rendering/render-controller.js +23 -2
- package/dist/app/rendering/status-line-renderer.d.ts +5 -0
- package/dist/app/rendering/status-line-renderer.js +41 -5
- package/dist/app/rendering/tab-line-renderer.js +26 -20
- package/dist/app/runtime.d.ts +12 -1
- package/dist/app/runtime.js +120 -12
- package/dist/app/screen/mouse-controller.d.ts +2 -0
- package/dist/app/screen/mouse-controller.js +17 -7
- package/dist/app/screen/status-controller.d.ts +4 -0
- package/dist/app/screen/status-controller.js +5 -0
- package/dist/app/session/lazy-session-manager.js +34 -0
- package/dist/app/session/session-event-controller.d.ts +1 -0
- package/dist/app/session/session-event-controller.js +10 -1
- package/dist/app/session/session-history.d.ts +1 -0
- package/dist/app/session/session-history.js +12 -1
- package/dist/app/session/session-lifecycle-controller.d.ts +7 -1
- package/dist/app/session/session-lifecycle-controller.js +16 -1
- package/dist/app/session/tabs-controller.d.ts +26 -1
- package/dist/app/session/tabs-controller.js +454 -147
- package/dist/app/subagents/subagents-files.js +60 -1
- package/dist/app/subagents/subagents-model.d.ts +1 -0
- package/dist/app/subagents/subagents-model.js +18 -2
- package/dist/app/subagents/subagents-widget-controller.d.ts +1 -0
- package/dist/app/subagents/subagents-widget-controller.js +6 -0
- package/dist/app/types.d.ts +16 -1
- package/dist/app/workspace/workspace-actions-controller.js +10 -2
- package/dist/app/workspace/workspace-undo.d.ts +1 -0
- package/dist/app/workspace/workspace-undo.js +1 -0
- package/dist/bundled-extensions/question/index.js +9 -1
- package/dist/bundled-extensions/question/remote.d.ts +4 -0
- package/dist/bundled-extensions/question/remote.js +33 -0
- package/dist/bundled-extensions/telegram-connector/bot.d.ts +43 -0
- package/dist/bundled-extensions/telegram-connector/bot.js +166 -0
- package/dist/bundled-extensions/telegram-connector/config.d.ts +8 -0
- package/dist/bundled-extensions/telegram-connector/config.js +87 -0
- package/dist/bundled-extensions/telegram-connector/coordinator.d.ts +66 -0
- package/dist/bundled-extensions/telegram-connector/coordinator.js +413 -0
- package/dist/bundled-extensions/telegram-connector/index.d.ts +3 -0
- package/dist/bundled-extensions/telegram-connector/index.js +195 -0
- package/dist/bundled-extensions/terminal-bell/index.d.ts +0 -8
- package/dist/bundled-extensions/terminal-bell/index.js +0 -76
- package/dist/bundled-extensions/workspace-undo/index.d.ts +26 -0
- package/dist/bundled-extensions/workspace-undo/index.js +191 -0
- package/dist/config.d.ts +21 -2
- package/dist/config.js +159 -32
- package/dist/default-pix-config.js +25 -5
- package/dist/schemas/index.d.ts +1 -0
- package/dist/schemas/index.js +1 -0
- package/dist/schemas/pi-tools-suite-schema.d.ts +88 -62
- package/dist/schemas/pi-tools-suite-schema.js +54 -83
- package/dist/schemas/pix-schema.d.ts +19 -2
- package/dist/schemas/pix-schema.js +47 -5
- package/dist/schemas/tasks-schema.d.ts +18 -0
- package/dist/schemas/tasks-schema.js +41 -0
- package/docs/concurrency.md +9 -1
- package/docs/desktop-mvp.md +22 -6
- package/docs/desktop-task-manager.md +148 -84
- package/docs/release.md +30 -6
- package/external/pi-tools-suite/README.md +197 -84
- package/external/pi-tools-suite/docs/evals.md +1 -1
- package/external/pi-tools-suite/docs/session-recovery.md +47 -14
- package/external/pi-tools-suite/docs/subagent-model-pools.md +48 -30
- package/external/pi-tools-suite/docs/ui-qa-subagent.md +440 -0
- package/external/pi-tools-suite/package.json +6 -1
- package/external/pi-tools-suite/src/antigravity-auth/auth-store.ts +2 -1
- package/external/pi-tools-suite/src/antigravity-auth/constants.ts +9 -3
- package/external/pi-tools-suite/src/antigravity-auth/headers.ts +41 -3
- package/external/pi-tools-suite/src/antigravity-auth/models.ts +94 -21
- package/external/pi-tools-suite/src/antigravity-auth/oauth.ts +5 -17
- package/external/pi-tools-suite/src/antigravity-auth/payload.ts +72 -7
- package/external/pi-tools-suite/src/antigravity-auth/stream.ts +13 -1
- package/external/pi-tools-suite/src/async-subagents/agents/frontier-review.md +23 -0
- package/external/pi-tools-suite/src/async-subagents/agents/implement.md +1 -1
- package/external/pi-tools-suite/src/async-subagents/agents/presets.jsonc +16 -0
- package/external/pi-tools-suite/src/async-subagents/agents/research.md +5 -3
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/backends/browser.mjs +346 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/backends/desktop.mjs +1038 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/backends/tui.mjs +759 -0
- package/external/pi-tools-suite/src/async-subagents/agents/{browser-qa → ui-qa/browser}/scripts/browser-qa-runner.mjs +32 -23
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/drivers/chrome-devtools/chrome-devtools-provider.mjs +895 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/drivers/linux/linux-atspi.py +494 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/drivers/macos/macos-accessibility.swift +1085 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/drivers/native-terminal/bridge-client.mjs +50 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/drivers/native-terminal/native-terminal-host.mjs +501 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/drivers/windows/windows-uia.ps1 +454 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/browser-auth.md +114 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/browser-chrome-devtools.md +91 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/browser-playwright.md +145 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/browser.md +82 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/desktop-linux.md +26 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/desktop-macos.md +29 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/desktop-windows.md +23 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/desktop.md +54 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/tui-native-terminal.md +59 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/tui-pty.md +37 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/tui.md +60 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/scripts/ui-qa-runner.mjs +535 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa.md +75 -0
- package/external/pi-tools-suite/src/async-subagents/commands.ts +15 -71
- package/external/pi-tools-suite/src/async-subagents/core/activity.ts +33 -0
- package/external/pi-tools-suite/src/async-subagents/core/agent-catalog.ts +5 -4
- package/external/pi-tools-suite/src/async-subagents/core/agent-strategy.ts +1 -1
- package/external/pi-tools-suite/src/async-subagents/core/agents-dir.ts +8 -5
- package/external/pi-tools-suite/src/async-subagents/core/browser-qa.ts +16 -2
- package/external/pi-tools-suite/src/async-subagents/core/config.ts +160 -327
- package/external/pi-tools-suite/src/async-subagents/core/model-selection.ts +2 -1
- package/external/pi-tools-suite/src/async-subagents/core/registry.ts +158 -33
- package/external/pi-tools-suite/src/async-subagents/core/routing.ts +21 -5
- package/external/pi-tools-suite/src/async-subagents/core/spawn.ts +40 -26
- package/external/pi-tools-suite/src/async-subagents/core/state.ts +40 -0
- package/external/pi-tools-suite/src/async-subagents/core/types.ts +7 -0
- package/external/pi-tools-suite/src/async-subagents/core/ultrawork-auto.ts +51 -45
- package/external/pi-tools-suite/src/async-subagents/index.ts +69 -5
- package/external/pi-tools-suite/src/async-subagents/lib.ts +16 -9
- package/external/pi-tools-suite/src/async-subagents/tools/spawn.ts +8 -5
- package/external/pi-tools-suite/src/async-subagents/tools/subagents.ts +5 -4
- package/external/pi-tools-suite/src/async-subagents/types.ts +1 -0
- package/external/pi-tools-suite/src/coding-discipline/index.ts +90 -59
- package/external/pi-tools-suite/src/config.ts +55 -1
- package/external/pi-tools-suite/src/context-gateway/accounting-log.ts +282 -0
- package/external/pi-tools-suite/src/context-gateway/config.ts +77 -3
- package/external/pi-tools-suite/src/context-gateway/efficiency.ts +414 -0
- package/external/pi-tools-suite/src/context-gateway/enforcement.ts +222 -0
- package/external/pi-tools-suite/src/context-gateway/index.ts +206 -19
- package/external/pi-tools-suite/src/context-gateway/storeless-capabilities.ts +7 -7
- package/external/pi-tools-suite/src/context-gateway/telemetry.ts +101 -28
- package/external/pi-tools-suite/src/context-gateway/types.ts +16 -3
- package/external/pi-tools-suite/src/context-inventory.ts +99 -0
- package/external/pi-tools-suite/src/dcp/auto-compress-budget.ts +39 -4
- package/external/pi-tools-suite/src/dcp/auto-compress.ts +128 -49
- package/external/pi-tools-suite/src/dcp/commands.ts +32 -156
- package/external/pi-tools-suite/src/dcp/compress-tool.ts +177 -46
- package/external/pi-tools-suite/src/dcp/compression-blocks.ts +6 -58
- package/external/pi-tools-suite/src/dcp/compression-preview.ts +9 -0
- package/external/pi-tools-suite/src/dcp/compression-progress.ts +22 -0
- package/external/pi-tools-suite/src/dcp/config.ts +114 -17
- package/external/pi-tools-suite/src/dcp/conversation-index.ts +36 -9
- package/external/pi-tools-suite/src/dcp/diagnostics.ts +41 -0
- package/external/pi-tools-suite/src/dcp/fresh-tool-results.ts +38 -0
- package/external/pi-tools-suite/src/dcp/index.ts +338 -66
- package/external/pi-tools-suite/src/dcp/journal.ts +126 -4
- package/external/pi-tools-suite/src/dcp/progress-controller.ts +2 -1
- package/external/pi-tools-suite/src/dcp/prompts.ts +83 -192
- package/external/pi-tools-suite/src/dcp/protected-continuity.ts +175 -0
- package/external/pi-tools-suite/src/dcp/pruner-candidates.ts +93 -3
- package/external/pi-tools-suite/src/dcp/pruner-message-ids.ts +6 -10
- package/external/pi-tools-suite/src/dcp/pruner-nudge.ts +36 -33
- package/external/pi-tools-suite/src/dcp/pruner-tools.ts +6 -3
- package/external/pi-tools-suite/src/dcp/pruner.ts +1 -0
- package/external/pi-tools-suite/src/dcp/routine-pressure.ts +86 -0
- package/external/pi-tools-suite/src/dcp/state.ts +9 -0
- package/external/pi-tools-suite/src/dcp/statistics.d.ts +8 -0
- package/external/pi-tools-suite/src/dcp/statistics.js +156 -0
- package/external/pi-tools-suite/src/default-pi-tools-suite-config.ts +78 -22
- package/external/pi-tools-suite/src/index.ts +7 -1
- package/external/pi-tools-suite/src/lib/project.ts +36 -1
- package/external/pi-tools-suite/src/model-tools/index.ts +10 -7
- package/external/pi-tools-suite/src/repo-discovery/index.ts +304 -4
- package/external/pi-tools-suite/src/resource-registry/index.ts +2551 -0
- package/external/pi-tools-suite/src/session-recovery/index.ts +17 -0
- package/external/pi-tools-suite/src/shell-command-policy.ts +219 -0
- package/external/pi-tools-suite/src/todo/index.ts +21 -0
- package/external/pi-tools-suite/src/todo/todo.ts +19 -1
- package/external/pi-tools-suite/src/tool-descriptions.ts +47 -19
- package/package.json +10 -9
- package/schemas/pi-tools-suite.json +466 -287
- package/schemas/pix.json +129 -11
- package/schemas/tasks.json +131 -0
- package/skills/simplify/SKILL.md +33 -5
- package/docs/desktop-markdown-media.md +0 -77
- package/external/pi-tools-suite/docs/browser-qa-subagent.md +0 -177
- package/external/pi-tools-suite/docs/dcp-emergency-current-turn.md +0 -102
- package/external/pi-tools-suite/src/async-subagents/agents/browser-qa.md +0 -598
- package/external/pi-tools-suite/src/async-subagents/async-subagents.sample.jsonc +0 -54
- package/external/pi-tools-suite/src/skill-installer/index.ts +0 -333
- package/skills/playwright-cli/SKILL.md +0 -420
- package/skills/playwright-cli/references/element-attributes.md +0 -23
- package/skills/playwright-cli/references/playwright-tests.md +0 -50
- package/skills/playwright-cli/references/request-mocking.md +0 -87
- package/skills/playwright-cli/references/running-code.md +0 -241
- package/skills/playwright-cli/references/session-management.md +0 -273
- package/skills/playwright-cli/references/spec-driven-testing.md +0 -311
- package/skills/playwright-cli/references/storage-state.md +0 -290
- package/skills/playwright-cli/references/test-generation.md +0 -142
- package/skills/playwright-cli/references/tracing.md +0 -154
- package/skills/playwright-cli/references/video-recording.md +0 -147
- package/skills/spec-lite/SKILL.md +0 -140
- /package/external/pi-tools-suite/src/async-subagents/agents/{browser-qa → ui-qa/browser}/examples/qa-auth.example.jsonc +0 -0
- /package/external/pi-tools-suite/src/async-subagents/agents/{browser-qa → ui-qa/browser}/examples/qa-flow.example.jsonc +0 -0
- /package/external/pi-tools-suite/src/async-subagents/agents/{browser-qa → ui-qa/browser}/vendor/fflate.LICENSE +0 -0
- /package/external/pi-tools-suite/src/async-subagents/agents/{browser-qa → ui-qa/browser}/vendor/fflate.mjs +0 -0
|
@@ -3,15 +3,12 @@ import * as fs from "node:fs";
|
|
|
3
3
|
import * as path from "node:path";
|
|
4
4
|
import { ignoreStaleExtensionContextError } from "../context-usage.js";
|
|
5
5
|
import {
|
|
6
|
-
copySubagentConfigSample,
|
|
7
6
|
ensureSessionFileLink,
|
|
8
|
-
existingSubagentConfigFiles,
|
|
9
7
|
findSubagentSessionByFile,
|
|
10
8
|
getActiveSubagentPresetName,
|
|
11
|
-
|
|
9
|
+
getBuiltinSubagentPresetsPath,
|
|
10
|
+
getProjectSubagentPresetsPath,
|
|
12
11
|
getSessionSubagentPresetOverride,
|
|
13
|
-
getSubagentConfigInitTargetPath,
|
|
14
|
-
getSubagentConfigSamplePath,
|
|
15
12
|
getSubagentPresetSelectionPath,
|
|
16
13
|
getRunState,
|
|
17
14
|
listRunDirs,
|
|
@@ -49,11 +46,10 @@ type MessageSender = ExtensionAPI & {
|
|
|
49
46
|
};
|
|
50
47
|
|
|
51
48
|
const CLEAR_ACTIVE_PRESET_LABEL = "Use no active preset";
|
|
52
|
-
const COPY_SAMPLE_CONFIG_LABEL = "Copy sample asyncSubagents config";
|
|
53
49
|
|
|
54
50
|
export const ULTRAWORK_PROMPT = `Run ultrawork mode for the current objective.
|
|
55
51
|
|
|
56
|
-
Use subagents when a lower-cost worker or isolation of noisy evidence helps, including one bounded sequential task. Pick subagentType from the effective catalog: research for reading/review, implement for code/docs/tests/UI changes, verify for running checks,
|
|
52
|
+
Use subagents when a lower-cost worker or isolation of noisy evidence helps, including one bounded sequential task. Pick subagentType from the effective catalog: research for reading/review, implement for code/docs/tests/UI changes, verify for running checks, ui-qa for real UI testing across browsers, TUIs, and desktop GUIs, and oracle only for a deliberate strong independent opinion. Prefer an appropriate project-local specialist. Keep decisions and integration in the parent; do not create agents just to assign a discipline.
|
|
57
53
|
|
|
58
54
|
Keep parent context lean: spawn for broad parallel work, read results only when needed, and finish unless genuinely blocked.`;
|
|
59
55
|
|
|
@@ -192,12 +188,10 @@ async function triggerOrchestrationPrompt(
|
|
|
192
188
|
|
|
193
189
|
function registerPresetCommands(pi: ExtensionAPI): void {
|
|
194
190
|
pi.registerCommand("subagent-preset", {
|
|
195
|
-
description: "Select a sub-agent preset
|
|
191
|
+
description: "Select a sub-agent model-pool preset, or run session <name> for a process-only override",
|
|
196
192
|
getArgumentCompletions: (prefix: string) => {
|
|
197
|
-
const names =
|
|
198
|
-
|
|
199
|
-
: [];
|
|
200
|
-
return [...names, ...names.map((name) => `session ${name}`), "list", "path", "config", "init", "clear", "session", "session-clear"]
|
|
193
|
+
const names = sortedPresetNames(loadSubagentConfig(process.cwd()).presets ?? {}, getActiveSubagentPresetName());
|
|
194
|
+
return [...names, ...names.map((name) => `session ${name}`), "list", "path", "clear", "session", "session-clear"]
|
|
201
195
|
.filter((name) => name.startsWith(prefix))
|
|
202
196
|
.map((name) => ({ value: name, label: name }));
|
|
203
197
|
},
|
|
@@ -209,28 +203,19 @@ function registerPresetCommands(pi: ExtensionAPI): void {
|
|
|
209
203
|
if (name === "session-clear") return clearSessionActiveSubagentPreset(ctx);
|
|
210
204
|
if (name === "list") return listSubagentPresets(ctx);
|
|
211
205
|
if (name === "path") return showSubagentPresetPaths(ctx);
|
|
212
|
-
if (name === "config") return showSubagentPresetConfigurator(ctx);
|
|
213
|
-
if (name === "init") return initSubagentConfigSample(ctx);
|
|
214
206
|
if (name === "clear") return clearActiveSubagentPreset(ctx);
|
|
215
|
-
if (existingSubagentConfigFiles(ctx.cwd).length === 0) return ctx.ui.notify(missingSubagentConfigMessage(ctx), "warning");
|
|
216
207
|
|
|
217
208
|
const config = loadSubagentConfig(ctx.cwd);
|
|
218
209
|
const preset = config.presets?.[name];
|
|
219
|
-
if (!preset) return ctx.ui.notify(`Unknown sub-agent preset "${name}".
|
|
210
|
+
if (!preset) return ctx.ui.notify(`Unknown sub-agent preset "${name}". Run /subagent-preset list to see available pools.`, "error");
|
|
220
211
|
setActiveSubagentPreset(name);
|
|
221
212
|
notifyActiveSubagentPreset(ctx, name, preset);
|
|
222
213
|
},
|
|
223
214
|
});
|
|
224
|
-
|
|
225
|
-
pi.registerCommand("subagent-preset-config", {
|
|
226
|
-
description: "Select sub-agent presets defined in asyncSubagents config",
|
|
227
|
-
handler: async (_args: string, ctx: CommandContext) => showSubagentPresetConfigurator(ctx),
|
|
228
|
-
});
|
|
229
215
|
}
|
|
230
216
|
|
|
231
217
|
async function showSubagentPresetSelector(ctx: CommandContext): Promise<void> {
|
|
232
218
|
if (!ctx.hasUI) return ctx.ui.notify("Sub-agent preset selector requires interactive UI. Use /subagent-preset <name>.", "warning");
|
|
233
|
-
if (existingSubagentConfigFiles(ctx.cwd).length === 0) return showMissingSubagentConfigSelector(ctx);
|
|
234
219
|
|
|
235
220
|
const config = loadSubagentConfig(ctx.cwd);
|
|
236
221
|
const activePreset = getActiveSubagentPresetName();
|
|
@@ -240,12 +225,12 @@ async function showSubagentPresetSelector(ctx: CommandContext): Promise<void> {
|
|
|
240
225
|
const labels = [...presetLabels];
|
|
241
226
|
if (activePreset) labels.push(CLEAR_ACTIVE_PRESET_LABEL);
|
|
242
227
|
if (labels.length === 0) {
|
|
243
|
-
ctx.ui.notify("No sub-agent presets are
|
|
228
|
+
ctx.ui.notify("No sub-agent model-pool presets are available.", "warning");
|
|
244
229
|
showSubagentPresetPaths(ctx);
|
|
245
230
|
return;
|
|
246
231
|
}
|
|
247
232
|
const labelToName = new Map(presetLabels.map((label, index) => [label, names[index]]));
|
|
248
|
-
const selected = await ctx.ui.select(
|
|
233
|
+
const selected = await ctx.ui.select("Select active sub-agent preset", labels);
|
|
249
234
|
if (!selected) return;
|
|
250
235
|
if (selected === CLEAR_ACTIVE_PRESET_LABEL) return clearActiveSubagentPreset(ctx);
|
|
251
236
|
|
|
@@ -254,69 +239,29 @@ async function showSubagentPresetSelector(ctx: CommandContext): Promise<void> {
|
|
|
254
239
|
setActiveSubagentPreset(name);
|
|
255
240
|
notifyActiveSubagentPreset(ctx, name, presets[name]);
|
|
256
241
|
}
|
|
257
|
-
|
|
258
|
-
async function showSubagentPresetConfigurator(ctx: CommandContext): Promise<void> {
|
|
259
|
-
if (!ctx.hasUI) return ctx.ui.notify("Sub-agent preset selector requires interactive UI.", "warning");
|
|
260
|
-
return showSubagentPresetSelector(ctx);
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
async function showMissingSubagentConfigSelector(ctx: CommandContext): Promise<void> {
|
|
264
|
-
const selected = await ctx.ui.select("No asyncSubagents config found", [COPY_SAMPLE_CONFIG_LABEL]);
|
|
265
|
-
if (selected === COPY_SAMPLE_CONFIG_LABEL) initSubagentConfigSample(ctx);
|
|
266
|
-
}
|
|
267
|
-
|
|
268
242
|
function listSubagentPresets(ctx: CommandContext): void {
|
|
269
|
-
if (existingSubagentConfigFiles(ctx.cwd).length === 0) {
|
|
270
|
-
ctx.ui.notify(missingSubagentConfigMessage(ctx), "warning");
|
|
271
|
-
return;
|
|
272
|
-
}
|
|
273
243
|
const config = loadSubagentConfig(ctx.cwd);
|
|
274
244
|
const activePreset = getActiveSubagentPresetName();
|
|
275
245
|
const presets = config.presets ?? {};
|
|
276
246
|
const names = sortedPresetNames(presets, activePreset);
|
|
277
|
-
if (names.length === 0) return ctx.ui.notify("No sub-agent presets are
|
|
247
|
+
if (names.length === 0) return ctx.ui.notify("No sub-agent model-pool presets are available.", "warning");
|
|
278
248
|
ctx.ui.notify([
|
|
279
|
-
"Sub-agent presets
|
|
249
|
+
"Sub-agent model-pool presets:",
|
|
280
250
|
...names.map((name) => `- ${subagentPresetLabel(name, presets[name], activePreset)}`),
|
|
281
251
|
].join("\n"), "info");
|
|
282
252
|
}
|
|
283
253
|
|
|
284
254
|
function showSubagentPresetPaths(ctx: CommandContext): void {
|
|
285
255
|
ctx.ui.notify([
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
`Sample config: ${getSubagentConfigSamplePath()}`,
|
|
290
|
-
`Copy sample target: ${getSubagentConfigInitTargetPath(ctx.cwd)}`,
|
|
256
|
+
`Bundled presets: ${getBuiltinSubagentPresetsPath()}`,
|
|
257
|
+
`Project preset override: ${getProjectSubagentPresetsPath(ctx.cwd)}`,
|
|
258
|
+
"Project presets are defined as model pools in .pi/agents/presets.jsonc; agent behavior stays in .pi/agents/*.md.",
|
|
291
259
|
`Active selection state: ${getSubagentPresetSelectionPath()}`,
|
|
292
260
|
`Session override: ${formatSessionPresetOverride()}`,
|
|
293
261
|
"Use /subagent-preset session <name> to override only the current Pi process; use /subagent-preset session-clear to clear that runtime override.",
|
|
294
|
-
"Run /subagent-preset init to copy the bundled sample only when no config exists.",
|
|
295
262
|
].join("\n"), "info");
|
|
296
263
|
}
|
|
297
264
|
|
|
298
|
-
function initSubagentConfigSample(ctx: CommandContext): void {
|
|
299
|
-
try {
|
|
300
|
-
const result = copySubagentConfigSample(ctx.cwd);
|
|
301
|
-
if (result.copied) {
|
|
302
|
-
ctx.ui.notify(`Copied sample asyncSubagents config:\n${result.samplePath}\n→ ${result.targetPath}`, "info");
|
|
303
|
-
return;
|
|
304
|
-
}
|
|
305
|
-
ctx.ui.notify(`AsyncSubagents config already exists; not overwriting:\n${result.existingFiles.join("\n") || result.targetPath}`, "warning");
|
|
306
|
-
} catch (error) {
|
|
307
|
-
ctx.ui.notify(error instanceof Error ? error.message : String(error), "error");
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
function missingSubagentConfigMessage(ctx: CommandContext): string {
|
|
312
|
-
return [
|
|
313
|
-
"No asyncSubagents config found in pi-tools-suite config.",
|
|
314
|
-
`Sample config: ${getSubagentConfigSamplePath()}`,
|
|
315
|
-
`Copy target: ${getSubagentConfigInitTargetPath(ctx.cwd)}`,
|
|
316
|
-
"Run /subagent-preset init to copy the bundled sample into the shared config.",
|
|
317
|
-
].join("\n");
|
|
318
|
-
}
|
|
319
|
-
|
|
320
265
|
function clearActiveSubagentPreset(ctx: CommandContext): void {
|
|
321
266
|
setActiveSubagentPreset(undefined);
|
|
322
267
|
const override = getSessionSubagentPresetOverride();
|
|
@@ -327,10 +272,9 @@ function clearActiveSubagentPreset(ctx: CommandContext): void {
|
|
|
327
272
|
|
|
328
273
|
function setSessionActiveSubagentPreset(ctx: CommandContext, name: string): void {
|
|
329
274
|
if (!name) return ctx.ui.notify("Usage: /subagent-preset session <name>", "warning");
|
|
330
|
-
if (existingSubagentConfigFiles(ctx.cwd).length === 0) return ctx.ui.notify(missingSubagentConfigMessage(ctx), "warning");
|
|
331
275
|
const config = loadSubagentConfig(ctx.cwd);
|
|
332
276
|
const preset = config.presets?.[name];
|
|
333
|
-
if (!preset) return ctx.ui.notify(`Unknown sub-agent preset "${name}".
|
|
277
|
+
if (!preset) return ctx.ui.notify(`Unknown sub-agent preset "${name}". Run /subagent-preset list to see available pools.`, "error");
|
|
334
278
|
setSessionSubagentPresetOverride(name);
|
|
335
279
|
ctx.ui.notify(`Session-only sub-agent preset "${name}": ${subagentPresetDescription(preset)}\nApplies to future sub-agent spawns only until this Pi process exits or /subagent-preset session-clear is run. Saved preset selection is unchanged.`, "info");
|
|
336
280
|
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { AgentActivity, RpcEventRecord } from "./types.js";
|
|
2
|
+
import { isRecord, isoNow } from "./utils.js";
|
|
3
|
+
|
|
4
|
+
export function activityFromRpcEvent(event: RpcEventRecord, at = isoNow()): AgentActivity | undefined {
|
|
5
|
+
if (event.type === "tool_execution_start") {
|
|
6
|
+
const toolName = nonEmptyString(event.toolName);
|
|
7
|
+
return toolName ? { label: toolName, at } : undefined;
|
|
8
|
+
}
|
|
9
|
+
if ((event.type === "message_start" || event.type === "message_end") && rpcMessageRole(event) === "assistant") {
|
|
10
|
+
return { label: "Thinking", at };
|
|
11
|
+
}
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function activityFromProgressRecord(value: unknown): AgentActivity | undefined {
|
|
16
|
+
if (!isRecord(value) || value.stage !== "rpc_event") return undefined;
|
|
17
|
+
const at = nonEmptyString(value.at);
|
|
18
|
+
if (!at) return undefined;
|
|
19
|
+
const toolName = nonEmptyString(value.toolName);
|
|
20
|
+
if (toolName) return { label: toolName, at };
|
|
21
|
+
if (value.type === "message_start" || value.type === "message_end") return { label: "Thinking", at };
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function rpcMessageRole(event: RpcEventRecord): string | undefined {
|
|
26
|
+
const directRole = nonEmptyString(event.role);
|
|
27
|
+
if (directRole) return directRole;
|
|
28
|
+
return isRecord(event.message) ? nonEmptyString(event.message.role) : undefined;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function nonEmptyString(value: unknown): string | undefined {
|
|
32
|
+
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
33
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { filterSubagentConfigForParentModel, type SubagentConfig } from "./config.js";
|
|
2
2
|
import { SUBAGENT_DELEGATION_GUIDANCE } from "./agent-strategy.js";
|
|
3
3
|
|
|
4
|
-
export const SUBAGENT_TYPE_SELECTION_GUIDANCE = "Choose and set subagentType from the available catalog when a role clearly matches, preferring a matching project-local specialist. Preserve a user-requested role. Omit subagentType only when unsure or when the user explicitly requests automatic routing; the LLM router handles omissions only. Model/thinking overrides are not substitutes for choosing a role.";
|
|
4
|
+
export const SUBAGENT_TYPE_SELECTION_GUIDANCE = "Choose and set subagentType from the available catalog when a role clearly matches, preferring a matching project-local specialist. Preserve a user-requested role when it is available in the current catalog. Omit subagentType only when unsure or when the user explicitly requests automatic routing; the LLM router handles omissions only. Model/thinking overrides are not substitutes for choosing a role.";
|
|
5
5
|
|
|
6
6
|
const MAX_DESCRIPTION_CHARS = 500;
|
|
7
7
|
|
|
@@ -10,8 +10,9 @@ const MAX_DESCRIPTION_CHARS = 500;
|
|
|
10
10
|
* The config has already merged built-ins, config files, and project-local
|
|
11
11
|
* `.pi/agents/*.md`, so this stays aligned with what spawn/routing can use.
|
|
12
12
|
*/
|
|
13
|
-
export function buildSubagentCatalogPrompt(config: SubagentConfig): string | undefined {
|
|
14
|
-
const
|
|
13
|
+
export function buildSubagentCatalogPrompt(config: SubagentConfig, parentModelRef?: string): string | undefined {
|
|
14
|
+
const effectiveConfig = filterSubagentConfigForParentModel(config, parentModelRef);
|
|
15
|
+
const entries = Object.entries(effectiveConfig.types).sort(([left], [right]) => left.localeCompare(right));
|
|
15
16
|
if (entries.length === 0) return undefined;
|
|
16
17
|
|
|
17
18
|
return [
|
|
@@ -7,7 +7,7 @@ export interface AgentStrategyOptions {
|
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
/** Shared by the strategy, tool description and role catalog. */
|
|
10
|
-
export const SUBAGENT_DELEGATION_GUIDANCE = "Delegate bounded work when a lower-cost worker can do it or noisy intermediate evidence should stay out of the parent context; one sequential task can qualify. Keep planning, decisions, integration and the final answer in the parent. Use research for evidence/review, implement for code/docs/tests/UI changes, verify for running checks,
|
|
10
|
+
export const SUBAGENT_DELEGATION_GUIDANCE = "Delegate bounded work when a lower-cost worker can do it or noisy intermediate evidence should stay out of the parent context; one sequential task can qualify. Keep planning, decisions, integration and the final answer in the parent. Use research for evidence/focused review questions, implement for code/docs/tests/UI changes, verify for running checks, ui-qa for real user-interface testing across browsers, TUIs, and desktop GUIs. When frontier-review is present in the current role catalog and substantive code changed, use it as the independent post-implementation review gate before finalizing; it is intentionally hidden for parent models excluded by its profile. Reserve oracle for a deliberate strong second opinion, not routine code review. Do trivial lookups/edits directly; redirect a noisy command to a log instead of spawning an LLM when no interpretation is needed.";
|
|
11
11
|
|
|
12
12
|
export function agentStrategyPrompt(options: AgentStrategyOptions = {}): string | undefined {
|
|
13
13
|
const env = options.env ?? process.env;
|
|
@@ -46,9 +46,10 @@ const KNOWN_FRONTMATTER_KEYS = new Set([
|
|
|
46
46
|
"model",
|
|
47
47
|
"fallbackModels",
|
|
48
48
|
"modelByParent",
|
|
49
|
+
"forParentModels",
|
|
50
|
+
"notForParentModels",
|
|
49
51
|
"thinking",
|
|
50
52
|
"tools",
|
|
51
|
-
"isolatedSkills",
|
|
52
53
|
"extraArgs",
|
|
53
54
|
"promptAppend",
|
|
54
55
|
"promptOverride",
|
|
@@ -62,7 +63,8 @@ const COMMA_SEPARATED_ARRAY_KEYS = new Set([
|
|
|
62
63
|
"tools",
|
|
63
64
|
"models",
|
|
64
65
|
"fallbackModels",
|
|
65
|
-
"
|
|
66
|
+
"forParentModels",
|
|
67
|
+
"notForParentModels",
|
|
66
68
|
"extraArgs",
|
|
67
69
|
"retryableExitCodes",
|
|
68
70
|
]);
|
|
@@ -72,7 +74,7 @@ const NUMERIC_PATTERN = /^[+-]?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?$/;
|
|
|
72
74
|
|
|
73
75
|
/** Discover and parse `.pi/agents/*.md` for the project containing `cwd`. */
|
|
74
76
|
export function readProjectAgentDefinitions(cwd: string): Record<string, ProjectAgentDefinition> {
|
|
75
|
-
const dir =
|
|
77
|
+
const dir = projectAgentsDir(cwd);
|
|
76
78
|
return dir ? readAgentDefinitionsFromDir(dir) : {};
|
|
77
79
|
}
|
|
78
80
|
|
|
@@ -94,7 +96,7 @@ export function readAgentDefinitionsFromDir(dir: string): Record<string, AgentDe
|
|
|
94
96
|
* deterministic merge order.
|
|
95
97
|
*/
|
|
96
98
|
export function projectAgentDefinitionFiles(cwd: string): string[] {
|
|
97
|
-
const dir =
|
|
99
|
+
const dir = projectAgentsDir(cwd);
|
|
98
100
|
return dir ? agentDefinitionFiles(dir) : [];
|
|
99
101
|
}
|
|
100
102
|
|
|
@@ -108,7 +110,8 @@ export function agentDefinitionFiles(dir: string): string[] {
|
|
|
108
110
|
.sort();
|
|
109
111
|
}
|
|
110
112
|
|
|
111
|
-
|
|
113
|
+
/** First project `.pi/agents` directory found walking up from cwd. */
|
|
114
|
+
export function projectAgentsDir(startDir: string): string | undefined {
|
|
112
115
|
let dir = path.resolve(startDir);
|
|
113
116
|
const root = path.parse(dir).root;
|
|
114
117
|
while (true) {
|
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
import { fileURLToPath } from "node:url";
|
|
2
2
|
|
|
3
|
-
/**
|
|
3
|
+
/** Canonical UI-QA role plus the pre-rename compatibility alias. */
|
|
4
|
+
export const UI_QA_TYPE = "ui-qa";
|
|
5
|
+
export const LEGACY_BROWSER_QA_TYPE = "browser-qa";
|
|
6
|
+
|
|
7
|
+
export function isUiQaType(value: string | undefined): boolean {
|
|
8
|
+
return value === UI_QA_TYPE || value === LEGACY_BROWSER_QA_TYPE;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/** Non-secret, launcher-owned path supplied only to UI-QA children. */
|
|
4
12
|
export const BROWSER_QA_RUNNER_ENV = "PI_BROWSER_QA_RUNNER";
|
|
13
|
+
export const UI_QA_RUNNER_ENV = "PI_UI_QA_RUNNER";
|
|
5
14
|
|
|
6
15
|
/** Resolve against the installed package, never the delegated project's cwd. */
|
|
7
16
|
export function getBrowserQaRunnerPath(): string {
|
|
8
|
-
return fileURLToPath(new URL("../agents/
|
|
17
|
+
return fileURLToPath(new URL("../agents/ui-qa/browser/scripts/browser-qa-runner.mjs", import.meta.url));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Resolve the capability-first UI-QA runner against the installed package. */
|
|
21
|
+
export function getUiQaRunnerPath(): string {
|
|
22
|
+
return fileURLToPath(new URL("../agents/ui-qa/scripts/ui-qa-runner.mjs", import.meta.url));
|
|
9
23
|
}
|