@vitos-pizza/vitos-pizza 0.1.0 → 0.2.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.
- package/AGENTS.md +158 -158
- package/CHANGELOG.md +42 -24
- package/LICENSE +21 -21
- package/README.md +237 -234
- package/assets/logo.svg +28 -28
- package/node_modules/@vitos-pizza/agent-mode/extensions/index.ts +138 -117
- package/node_modules/@vitos-pizza/agent-mode/package.json +3 -3
- package/node_modules/@vitos-pizza/agent-mode/src/apply-mode.ts +60 -60
- package/node_modules/@vitos-pizza/agent-mode/src/mode-events.ts +102 -102
- package/node_modules/@vitos-pizza/agent-mode/src/modes.ts +43 -43
- package/node_modules/@vitos-pizza/agent-mode/src/plan-instructions.ts +85 -44
- package/node_modules/@vitos-pizza/agent-mode/tests/apply-mode.test.ts +36 -36
- package/node_modules/@vitos-pizza/agent-mode/tests/mode-events.test.ts +22 -22
- package/node_modules/@vitos-pizza/agent-mode/tests/modes.test.ts +38 -38
- package/node_modules/@vitos-pizza/agent-mode/tests/plan-instructions.test.ts +68 -45
- package/node_modules/@vitos-pizza/agent-mode/tsconfig.json +13 -13
- package/node_modules/@vitos-pizza/agent-mode/vitest.config.ts +8 -8
- package/node_modules/@vitos-pizza/keybindings/extensions/index.ts +104 -104
- package/node_modules/@vitos-pizza/keybindings/package.json +1 -1
- package/node_modules/@vitos-pizza/keybindings/presets/shortcuts.json +3 -3
- package/node_modules/@vitos-pizza/keybindings/src/bind.ts +57 -57
- package/node_modules/@vitos-pizza/keybindings/src/config.ts +84 -84
- package/node_modules/@vitos-pizza/keybindings/src/registry.ts +43 -43
- package/node_modules/@vitos-pizza/keybindings/src/types.ts +54 -54
- package/node_modules/@vitos-pizza/keybindings/tests/config.test.ts +83 -83
- package/node_modules/@vitos-pizza/keybindings/tests/registry.test.ts +142 -142
- package/node_modules/@vitos-pizza/keybindings/tsconfig.json +13 -13
- package/node_modules/@vitos-pizza/keybindings/vitest.config.ts +8 -8
- package/node_modules/@vitos-pizza/permission-system/extensions/index.ts +162 -162
- package/node_modules/@vitos-pizza/permission-system/package.json +2 -2
- package/node_modules/@vitos-pizza/permission-system/src/bash/matcher.ts +54 -51
- package/node_modules/@vitos-pizza/permission-system/src/bash/parser.ts +40 -40
- package/node_modules/@vitos-pizza/permission-system/src/config-paths.ts +23 -23
- package/node_modules/@vitos-pizza/permission-system/src/detect-preset-mode.ts +61 -61
- package/node_modules/@vitos-pizza/permission-system/src/expand-home.ts +12 -12
- package/node_modules/@vitos-pizza/permission-system/src/forwarding/forwarder.ts +224 -224
- package/node_modules/@vitos-pizza/permission-system/src/forwarding/subagent-registry.ts +61 -61
- package/node_modules/@vitos-pizza/permission-system/src/gates/path-utils.ts +66 -66
- package/node_modules/@vitos-pizza/permission-system/src/gates/pipeline.ts +151 -155
- package/node_modules/@vitos-pizza/permission-system/src/handlers/before-agent-start.ts +86 -65
- package/node_modules/@vitos-pizza/permission-system/src/handlers/skill-input.ts +1 -1
- package/node_modules/@vitos-pizza/permission-system/src/handlers/tool-call-gate.ts +204 -199
- package/node_modules/@vitos-pizza/permission-system/src/mode-api.ts +44 -44
- package/node_modules/@vitos-pizza/permission-system/src/permission-evaluator.ts +233 -216
- package/node_modules/@vitos-pizza/permission-system/src/permission-session.ts +62 -62
- package/node_modules/@vitos-pizza/permission-system/src/policy-loader.ts +211 -211
- package/node_modules/@vitos-pizza/permission-system/src/sanitizers/skill-prompt.ts +99 -99
- package/node_modules/@vitos-pizza/permission-system/src/sanitizers/system-prompt.ts +221 -221
- package/node_modules/@vitos-pizza/permission-system/src/service.ts +66 -66
- package/node_modules/@vitos-pizza/permission-system/src/session-approvals.ts +4 -1
- package/node_modules/@vitos-pizza/permission-system/src/types.ts +80 -80
- package/node_modules/@vitos-pizza/permission-system/src/ui/approval-summary.ts +43 -43
- package/node_modules/@vitos-pizza/permission-system/src/ui/config-modal.ts +36 -36
- package/node_modules/@vitos-pizza/permission-system/src/ui/permission-dialog.ts +52 -52
- package/node_modules/@vitos-pizza/permission-system/src/wildcard-matcher.ts +81 -81
- package/node_modules/@vitos-pizza/permission-system/src/yaml-frontmatter.ts +84 -84
- package/node_modules/@vitos-pizza/permission-system/src/yolo/runtime-api.ts +49 -49
- package/node_modules/@vitos-pizza/permission-system/tests/bash-parser.test.ts +32 -32
- package/node_modules/@vitos-pizza/permission-system/tests/before-agent-start.test.ts +61 -0
- package/node_modules/@vitos-pizza/permission-system/tests/detect-preset-mode.test.ts +68 -68
- package/node_modules/@vitos-pizza/permission-system/tests/forwarder.test.ts +55 -55
- package/node_modules/@vitos-pizza/permission-system/tests/gates.test.ts +170 -61
- package/node_modules/@vitos-pizza/permission-system/tests/path-utils.test.ts +68 -68
- package/node_modules/@vitos-pizza/permission-system/tests/permission-evaluator.test.ts +82 -55
- package/node_modules/@vitos-pizza/permission-system/tests/policy-loader.test.ts +25 -25
- package/node_modules/@vitos-pizza/permission-system/tests/system-prompt-sanitizer.test.ts +22 -22
- package/node_modules/@vitos-pizza/permission-system/tests/wildcard-matcher.test.ts +27 -27
- package/node_modules/@vitos-pizza/permission-system/tsconfig.json +13 -13
- package/node_modules/@vitos-pizza/permission-system/vitest.config.ts +8 -8
- package/node_modules/@vitos-pizza/question/package.json +1 -1
- package/node_modules/@vitos-pizza/question/src/question-ui.ts +5 -1
- package/node_modules/@vitos-pizza/question/src/register-tool.ts +1 -4
- package/node_modules/@vitos-pizza/question/tests/question-ui-width-cache.test.ts +45 -0
- package/node_modules/@vitos-pizza/question/tests/register-tool-render.test.ts +48 -45
- package/node_modules/@vitos-pizza/session-title/extensions/index.ts +137 -137
- package/node_modules/@vitos-pizza/session-title/package.json +3 -3
- package/node_modules/@vitos-pizza/session-title/src/build-title-prompt.ts +16 -16
- package/node_modules/@vitos-pizza/session-title/src/extract-title-context.ts +55 -55
- package/node_modules/@vitos-pizza/session-title/src/fast-rules.ts +48 -48
- package/node_modules/@vitos-pizza/session-title/src/load-settings.ts +70 -70
- package/node_modules/@vitos-pizza/session-title/src/normalize-title.ts +20 -20
- package/node_modules/@vitos-pizza/session-title/src/parse-title-response.ts +6 -6
- package/node_modules/@vitos-pizza/session-title/src/resolve-title-model.ts +33 -33
- package/node_modules/@vitos-pizza/session-title/src/schedule-title-job.ts +53 -53
- package/node_modules/@vitos-pizza/session-title/src/should-schedule.ts +30 -30
- package/node_modules/@vitos-pizza/session-title/src/title-agent.ts +60 -60
- package/node_modules/@vitos-pizza/session-title/src/truncate-input.ts +10 -10
- package/node_modules/@vitos-pizza/session-title/src/types.ts +29 -29
- package/node_modules/@vitos-pizza/session-title/tests/build-title-prompt.test.ts +34 -34
- package/node_modules/@vitos-pizza/session-title/tests/extension.test.ts +198 -198
- package/node_modules/@vitos-pizza/session-title/tests/extract-title-context.test.ts +48 -48
- package/node_modules/@vitos-pizza/session-title/tests/fast-rules.test.ts +43 -43
- package/node_modules/@vitos-pizza/session-title/tests/parse-title-response.test.ts +34 -34
- package/node_modules/@vitos-pizza/session-title/tests/should-schedule.test.ts +30 -30
- package/node_modules/@vitos-pizza/session-title/tests/title-agent.test.ts +154 -154
- package/node_modules/@vitos-pizza/session-title/tests/truncate-input.test.ts +15 -15
- package/node_modules/@vitos-pizza/session-title/tsconfig.json +13 -13
- package/node_modules/@vitos-pizza/session-title/vitest.config.ts +8 -8
- package/node_modules/@vitos-pizza/subagents/agents/planner.md +46 -43
- package/node_modules/@vitos-pizza/subagents/agents/scout.md +40 -40
- package/node_modules/@vitos-pizza/subagents/agents/title.md +13 -13
- package/node_modules/@vitos-pizza/subagents/agents/worker.md +36 -36
- package/node_modules/@vitos-pizza/subagents/extensions/index.ts +164 -164
- package/node_modules/@vitos-pizza/subagents/package.json +1 -1
- package/node_modules/@vitos-pizza/subagents/skills/subagents/SKILL.md +86 -80
- package/node_modules/@vitos-pizza/subagents/src/agents.ts +166 -166
- package/node_modules/@vitos-pizza/subagents/src/async/job-tracker.ts +71 -71
- package/node_modules/@vitos-pizza/subagents/src/async/spawn-async.ts +220 -220
- package/node_modules/@vitos-pizza/subagents/src/async/storage.ts +57 -57
- package/node_modules/@vitos-pizza/subagents/src/env.ts +4 -4
- package/node_modules/@vitos-pizza/subagents/src/execute-subagent.ts +285 -285
- package/node_modules/@vitos-pizza/subagents/src/progress.ts +187 -187
- package/node_modules/@vitos-pizza/subagents/src/render-animation.ts +40 -40
- package/node_modules/@vitos-pizza/subagents/src/render.ts +428 -428
- package/node_modules/@vitos-pizza/subagents/src/rpc/channels.ts +21 -21
- package/node_modules/@vitos-pizza/subagents/src/rpc/client.ts +144 -144
- package/node_modules/@vitos-pizza/subagents/src/rpc/server.ts +11 -11
- package/node_modules/@vitos-pizza/subagents/src/run-agent.ts +313 -313
- package/node_modules/@vitos-pizza/subagents/src/runtime.ts +102 -102
- package/node_modules/@vitos-pizza/subagents/src/schema.ts +62 -62
- package/node_modules/@vitos-pizza/subagents/src/spawn.ts +104 -104
- package/node_modules/@vitos-pizza/subagents/src/types.ts +92 -92
- package/node_modules/@vitos-pizza/subagents/src/utils.ts +100 -100
- package/node_modules/@vitos-pizza/subagents/src/wait.ts +159 -159
- package/node_modules/@vitos-pizza/subagents/tests/agents.test.ts +19 -19
- package/node_modules/@vitos-pizza/subagents/tests/execute-subagent.test.ts +96 -96
- package/node_modules/@vitos-pizza/subagents/tests/extension.test.ts +42 -42
- package/node_modules/@vitos-pizza/subagents/tests/progress.test.ts +206 -206
- package/node_modules/@vitos-pizza/subagents/tests/rpc.test.ts +74 -74
- package/node_modules/@vitos-pizza/subagents/tsconfig.json +13 -13
- package/node_modules/@vitos-pizza/subagents/vitest.config.ts +8 -8
- package/node_modules/@vitos-pizza/ui-enhancements/package.json +1 -1
- package/node_modules/@vitos-pizza/ui-enhancements/src/chrome/agent-mode-badge.ts +60 -60
- package/node_modules/@vitos-pizza/ui-enhancements/src/chrome/border-status.ts +14 -1
- package/node_modules/@vitos-pizza/ui-enhancements/src/chrome/resize-recovery.ts +63 -0
- package/node_modules/@vitos-pizza/ui-enhancements/tests/agent-mode-badge.test.ts +35 -35
- package/node_modules/@vitos-pizza/ui-enhancements/tests/resize-recovery.test.ts +135 -0
- package/node_modules/@vitos-pizza/websearch/package.json +1 -1
- package/node_modules/node-addon-api/tools/conversion.js +0 -0
- package/node_modules/node-gyp-build/bin.js +0 -0
- package/node_modules/node-gyp-build/build-test.js +0 -0
- package/node_modules/node-gyp-build/optional.js +0 -0
- package/package.json +11 -9
- package/packages/agent-mode/extensions/index.ts +138 -117
- package/packages/agent-mode/package.json +3 -3
- package/packages/agent-mode/src/apply-mode.ts +60 -60
- package/packages/agent-mode/src/mode-events.ts +102 -102
- package/packages/agent-mode/src/modes.ts +43 -43
- package/packages/agent-mode/src/plan-instructions.ts +85 -44
- package/packages/agent-mode/tsconfig.json +13 -13
- package/packages/agent-mode/vitest.config.ts +8 -8
- package/packages/keybindings/extensions/index.ts +104 -104
- package/packages/keybindings/package.json +1 -1
- package/packages/keybindings/presets/shortcuts.json +3 -3
- package/packages/keybindings/src/bind.ts +57 -57
- package/packages/keybindings/src/config.ts +84 -84
- package/packages/keybindings/src/registry.ts +43 -43
- package/packages/keybindings/src/types.ts +54 -54
- package/packages/keybindings/tsconfig.json +13 -13
- package/packages/keybindings/vitest.config.ts +8 -8
- package/packages/permission-system/extensions/index.ts +162 -162
- package/packages/permission-system/node_modules/web-tree-sitter/debug/tree-sitter.wasm +0 -0
- package/packages/permission-system/node_modules/web-tree-sitter/tree-sitter.wasm +0 -0
- package/packages/permission-system/package.json +2 -2
- package/packages/permission-system/src/bash/matcher.ts +54 -51
- package/packages/permission-system/src/bash/parser.ts +40 -40
- package/packages/permission-system/src/config-paths.ts +23 -23
- package/packages/permission-system/src/detect-preset-mode.ts +61 -61
- package/packages/permission-system/src/expand-home.ts +12 -12
- package/packages/permission-system/src/forwarding/forwarder.ts +224 -224
- package/packages/permission-system/src/forwarding/subagent-registry.ts +61 -61
- package/packages/permission-system/src/gates/path-utils.ts +66 -66
- package/packages/permission-system/src/gates/pipeline.ts +151 -155
- package/packages/permission-system/src/handlers/before-agent-start.ts +86 -65
- package/packages/permission-system/src/handlers/skill-input.ts +1 -1
- package/packages/permission-system/src/handlers/tool-call-gate.ts +204 -199
- package/packages/permission-system/src/mode-api.ts +44 -44
- package/packages/permission-system/src/permission-evaluator.ts +233 -216
- package/packages/permission-system/src/permission-session.ts +62 -62
- package/packages/permission-system/src/policy-loader.ts +211 -211
- package/packages/permission-system/src/sanitizers/skill-prompt.ts +99 -99
- package/packages/permission-system/src/sanitizers/system-prompt.ts +221 -221
- package/packages/permission-system/src/service.ts +66 -66
- package/packages/permission-system/src/session-approvals.ts +4 -1
- package/packages/permission-system/src/types.ts +80 -80
- package/packages/permission-system/src/ui/approval-summary.ts +43 -43
- package/packages/permission-system/src/ui/config-modal.ts +36 -36
- package/packages/permission-system/src/ui/permission-dialog.ts +52 -52
- package/packages/permission-system/src/wildcard-matcher.ts +81 -81
- package/packages/permission-system/src/yaml-frontmatter.ts +84 -84
- package/packages/permission-system/src/yolo/runtime-api.ts +49 -49
- package/packages/permission-system/tsconfig.json +13 -13
- package/packages/permission-system/vitest.config.ts +8 -8
- package/packages/question/package.json +1 -1
- package/packages/question/src/question-ui.ts +5 -1
- package/packages/question/src/register-tool.ts +1 -4
- package/packages/session-title/extensions/index.ts +137 -137
- package/packages/session-title/package.json +3 -3
- package/packages/session-title/src/build-title-prompt.ts +16 -16
- package/packages/session-title/src/extract-title-context.ts +55 -55
- package/packages/session-title/src/fast-rules.ts +48 -48
- package/packages/session-title/src/load-settings.ts +70 -70
- package/packages/session-title/src/normalize-title.ts +20 -20
- package/packages/session-title/src/parse-title-response.ts +6 -6
- package/packages/session-title/src/resolve-title-model.ts +33 -33
- package/packages/session-title/src/schedule-title-job.ts +53 -53
- package/packages/session-title/src/should-schedule.ts +30 -30
- package/packages/session-title/src/title-agent.ts +60 -60
- package/packages/session-title/src/truncate-input.ts +10 -10
- package/packages/session-title/src/types.ts +29 -29
- package/packages/session-title/tsconfig.json +13 -13
- package/packages/session-title/vitest.config.ts +8 -8
- package/packages/subagents/agents/planner.md +46 -43
- package/packages/subagents/agents/scout.md +40 -40
- package/packages/subagents/agents/title.md +13 -13
- package/packages/subagents/agents/worker.md +36 -36
- package/packages/subagents/extensions/index.ts +164 -164
- package/packages/subagents/package.json +1 -1
- package/packages/subagents/skills/subagents/SKILL.md +86 -80
- package/packages/subagents/src/agents.ts +166 -166
- package/packages/subagents/src/async/job-tracker.ts +71 -71
- package/packages/subagents/src/async/spawn-async.ts +220 -220
- package/packages/subagents/src/async/storage.ts +57 -57
- package/packages/subagents/src/env.ts +4 -4
- package/packages/subagents/src/execute-subagent.ts +285 -285
- package/packages/subagents/src/progress.ts +187 -187
- package/packages/subagents/src/render-animation.ts +40 -40
- package/packages/subagents/src/render.ts +428 -428
- package/packages/subagents/src/rpc/channels.ts +21 -21
- package/packages/subagents/src/rpc/client.ts +144 -144
- package/packages/subagents/src/rpc/server.ts +11 -11
- package/packages/subagents/src/run-agent.ts +313 -313
- package/packages/subagents/src/runtime.ts +102 -102
- package/packages/subagents/src/schema.ts +62 -62
- package/packages/subagents/src/spawn.ts +104 -104
- package/packages/subagents/src/types.ts +92 -92
- package/packages/subagents/src/utils.ts +100 -100
- package/packages/subagents/src/wait.ts +159 -159
- package/packages/subagents/tsconfig.json +13 -13
- package/packages/subagents/vitest.config.ts +8 -8
- package/packages/todoist/extensions/index.ts +163 -0
- package/packages/todoist/package.json +34 -0
- package/packages/todoist/src/events.ts +7 -0
- package/packages/todoist/src/silent-render.ts +8 -0
- package/packages/todoist/src/state.ts +147 -0
- package/packages/todoist/src/tools.ts +175 -0
- package/packages/todoist/src/types.ts +34 -0
- package/packages/todoist/src/widget.ts +109 -0
- package/packages/todoist/tsconfig.json +13 -0
- package/packages/todoist/vitest.config.ts +8 -0
- package/packages/ui-enhancements/package.json +1 -1
- package/packages/ui-enhancements/src/chrome/agent-mode-badge.ts +60 -60
- package/packages/ui-enhancements/src/chrome/border-status.ts +14 -1
- package/packages/ui-enhancements/src/chrome/resize-recovery.ts +63 -0
- package/packages/websearch/package.json +1 -1
- package/scripts/sync-pi-manifest.mjs +1 -1
- package/packages/permission-system/node_modules/web-tree-sitter/lib/tree-sitter.cjs +0 -2988
- package/packages/permission-system/node_modules/web-tree-sitter/lib/tree-sitter.wasm +0 -0
- package/packages/permission-system/node_modules/web-tree-sitter/lib/tree-sitter.wasm.map +0 -1
|
@@ -1,102 +1,102 @@
|
|
|
1
|
-
import type { AgentToolResult } from "@earendil-works/pi-agent-core";
|
|
2
|
-
import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
3
|
-
import { createAsyncJobTracker } from "./async/job-tracker.ts";
|
|
4
|
-
import type { SubagentEventBus } from "./async/job-tracker.ts";
|
|
5
|
-
import { restoreAsyncJobs, spawnAsyncRun } from "./async/spawn-async.ts";
|
|
6
|
-
import { executeSubagent } from "./execute-subagent.ts";
|
|
7
|
-
import type {
|
|
8
|
-
ExecuteSubagentInput,
|
|
9
|
-
SubagentDetails,
|
|
10
|
-
WaitInput,
|
|
11
|
-
WaitResult,
|
|
12
|
-
} from "./types.ts";
|
|
13
|
-
import { waitForSubagents } from "./wait.ts";
|
|
14
|
-
|
|
15
|
-
export interface SubagentRuntimeDeps {
|
|
16
|
-
getContext: () => ExtensionContext | null;
|
|
17
|
-
events?: SubagentEventBus;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface SubagentRuntime {
|
|
21
|
-
execute(
|
|
22
|
-
input: ExecuteSubagentInput,
|
|
23
|
-
options?: {
|
|
24
|
-
signal?: AbortSignal;
|
|
25
|
-
onUpdate?: (partial: AgentToolResult<SubagentDetails>) => void;
|
|
26
|
-
},
|
|
27
|
-
): Promise<AgentToolResult<SubagentDetails>>;
|
|
28
|
-
wait(input?: WaitInput, options?: { signal?: AbortSignal }): Promise<WaitResult>;
|
|
29
|
-
listAsync(): ReturnType<ReturnType<typeof createAsyncJobTracker>["list"]>;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export function createSubagentRuntime(deps: SubagentRuntimeDeps): SubagentRuntime {
|
|
33
|
-
const tracker = createAsyncJobTracker();
|
|
34
|
-
|
|
35
|
-
return {
|
|
36
|
-
async execute(input, options = {}) {
|
|
37
|
-
const ctx = deps.getContext();
|
|
38
|
-
if (!ctx) {
|
|
39
|
-
return {
|
|
40
|
-
content: [
|
|
41
|
-
{
|
|
42
|
-
type: "text",
|
|
43
|
-
text: "Subagent runtime is not bound to an active session.",
|
|
44
|
-
},
|
|
45
|
-
],
|
|
46
|
-
details: {
|
|
47
|
-
mode: "single",
|
|
48
|
-
agentScope: "both",
|
|
49
|
-
projectAgentsDir: null,
|
|
50
|
-
results: [],
|
|
51
|
-
},
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const parentSessionId = ctx.sessionManager.getSessionId?.() ?? null;
|
|
56
|
-
const sessionFile = ctx.sessionManager.getSessionFile?.() ?? null;
|
|
57
|
-
|
|
58
|
-
if (input.async) {
|
|
59
|
-
const { result } = spawnAsyncRun({
|
|
60
|
-
params: input,
|
|
61
|
-
cwd: ctx.cwd,
|
|
62
|
-
parentSessionId,
|
|
63
|
-
sessionFile,
|
|
64
|
-
tracker,
|
|
65
|
-
events: deps.events,
|
|
66
|
-
signal: options.signal,
|
|
67
|
-
});
|
|
68
|
-
return result;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return executeSubagent(input, {
|
|
72
|
-
cwd: ctx.cwd,
|
|
73
|
-
parentSessionId,
|
|
74
|
-
signal: options.signal,
|
|
75
|
-
onUpdate: options.onUpdate
|
|
76
|
-
? (details, text) =>
|
|
77
|
-
options.onUpdate?.({
|
|
78
|
-
content: [{ type: "text", text }],
|
|
79
|
-
details,
|
|
80
|
-
})
|
|
81
|
-
: undefined,
|
|
82
|
-
});
|
|
83
|
-
},
|
|
84
|
-
|
|
85
|
-
async wait(input = {}, _options = {}) {
|
|
86
|
-
const ctx = deps.getContext();
|
|
87
|
-
return waitForSubagents(input, {
|
|
88
|
-
tracker,
|
|
89
|
-
sessionFile: ctx?.sessionManager.getSessionFile?.() ?? null,
|
|
90
|
-
events: deps.events,
|
|
91
|
-
});
|
|
92
|
-
},
|
|
93
|
-
|
|
94
|
-
listAsync() {
|
|
95
|
-
return tracker.list();
|
|
96
|
-
},
|
|
97
|
-
|
|
98
|
-
_restore(sessionFile: string | null) {
|
|
99
|
-
restoreAsyncJobs(sessionFile, tracker);
|
|
100
|
-
},
|
|
101
|
-
} as SubagentRuntime & { _restore(sessionFile: string | null): void };
|
|
102
|
-
}
|
|
1
|
+
import type { AgentToolResult } from "@earendil-works/pi-agent-core";
|
|
2
|
+
import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
3
|
+
import { createAsyncJobTracker } from "./async/job-tracker.ts";
|
|
4
|
+
import type { SubagentEventBus } from "./async/job-tracker.ts";
|
|
5
|
+
import { restoreAsyncJobs, spawnAsyncRun } from "./async/spawn-async.ts";
|
|
6
|
+
import { executeSubagent } from "./execute-subagent.ts";
|
|
7
|
+
import type {
|
|
8
|
+
ExecuteSubagentInput,
|
|
9
|
+
SubagentDetails,
|
|
10
|
+
WaitInput,
|
|
11
|
+
WaitResult,
|
|
12
|
+
} from "./types.ts";
|
|
13
|
+
import { waitForSubagents } from "./wait.ts";
|
|
14
|
+
|
|
15
|
+
export interface SubagentRuntimeDeps {
|
|
16
|
+
getContext: () => ExtensionContext | null;
|
|
17
|
+
events?: SubagentEventBus;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface SubagentRuntime {
|
|
21
|
+
execute(
|
|
22
|
+
input: ExecuteSubagentInput,
|
|
23
|
+
options?: {
|
|
24
|
+
signal?: AbortSignal;
|
|
25
|
+
onUpdate?: (partial: AgentToolResult<SubagentDetails>) => void;
|
|
26
|
+
},
|
|
27
|
+
): Promise<AgentToolResult<SubagentDetails>>;
|
|
28
|
+
wait(input?: WaitInput, options?: { signal?: AbortSignal }): Promise<WaitResult>;
|
|
29
|
+
listAsync(): ReturnType<ReturnType<typeof createAsyncJobTracker>["list"]>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function createSubagentRuntime(deps: SubagentRuntimeDeps): SubagentRuntime {
|
|
33
|
+
const tracker = createAsyncJobTracker();
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
async execute(input, options = {}) {
|
|
37
|
+
const ctx = deps.getContext();
|
|
38
|
+
if (!ctx) {
|
|
39
|
+
return {
|
|
40
|
+
content: [
|
|
41
|
+
{
|
|
42
|
+
type: "text",
|
|
43
|
+
text: "Subagent runtime is not bound to an active session.",
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
details: {
|
|
47
|
+
mode: "single",
|
|
48
|
+
agentScope: "both",
|
|
49
|
+
projectAgentsDir: null,
|
|
50
|
+
results: [],
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const parentSessionId = ctx.sessionManager.getSessionId?.() ?? null;
|
|
56
|
+
const sessionFile = ctx.sessionManager.getSessionFile?.() ?? null;
|
|
57
|
+
|
|
58
|
+
if (input.async) {
|
|
59
|
+
const { result } = spawnAsyncRun({
|
|
60
|
+
params: input,
|
|
61
|
+
cwd: ctx.cwd,
|
|
62
|
+
parentSessionId,
|
|
63
|
+
sessionFile,
|
|
64
|
+
tracker,
|
|
65
|
+
events: deps.events,
|
|
66
|
+
signal: options.signal,
|
|
67
|
+
});
|
|
68
|
+
return result;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return executeSubagent(input, {
|
|
72
|
+
cwd: ctx.cwd,
|
|
73
|
+
parentSessionId,
|
|
74
|
+
signal: options.signal,
|
|
75
|
+
onUpdate: options.onUpdate
|
|
76
|
+
? (details, text) =>
|
|
77
|
+
options.onUpdate?.({
|
|
78
|
+
content: [{ type: "text", text }],
|
|
79
|
+
details,
|
|
80
|
+
})
|
|
81
|
+
: undefined,
|
|
82
|
+
});
|
|
83
|
+
},
|
|
84
|
+
|
|
85
|
+
async wait(input = {}, _options = {}) {
|
|
86
|
+
const ctx = deps.getContext();
|
|
87
|
+
return waitForSubagents(input, {
|
|
88
|
+
tracker,
|
|
89
|
+
sessionFile: ctx?.sessionManager.getSessionFile?.() ?? null,
|
|
90
|
+
events: deps.events,
|
|
91
|
+
});
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
listAsync() {
|
|
95
|
+
return tracker.list();
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
_restore(sessionFile: string | null) {
|
|
99
|
+
restoreAsyncJobs(sessionFile, tracker);
|
|
100
|
+
},
|
|
101
|
+
} as SubagentRuntime & { _restore(sessionFile: string | null): void };
|
|
102
|
+
}
|
|
@@ -1,62 +1,62 @@
|
|
|
1
|
-
import { StringEnum } from "@earendil-works/pi-ai";
|
|
2
|
-
import { Type, type TSchema } from "typebox";
|
|
3
|
-
|
|
4
|
-
const TaskItem = Type.Object({
|
|
5
|
-
agent: Type.String({ description: "Name of the agent to invoke" }),
|
|
6
|
-
task: Type.String({ description: "Task to delegate to the agent" }),
|
|
7
|
-
cwd: Type.Optional(Type.String({ description: "Working directory for the agent process" })),
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
const ChainItem = Type.Object({
|
|
11
|
-
agent: Type.String({ description: "Name of the agent to invoke" }),
|
|
12
|
-
task: Type.String({
|
|
13
|
-
description:
|
|
14
|
-
"Task with optional {previous} placeholder for prior step output",
|
|
15
|
-
}),
|
|
16
|
-
cwd: Type.Optional(Type.String({ description: "Working directory for the agent process" })),
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
const AgentScopeSchema = StringEnum(["user", "project", "both"] as const, {
|
|
20
|
-
description: 'Which agent directories to use. Default: "both".',
|
|
21
|
-
default: "both",
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
export const SubagentParams: TSchema = Type.Object({
|
|
25
|
-
agent: Type.Optional(Type.String({ description: "Agent name (single mode)" })),
|
|
26
|
-
task: Type.Optional(Type.String({ description: "Task to delegate (single mode)" })),
|
|
27
|
-
tasks: Type.Optional(
|
|
28
|
-
Type.Array(TaskItem, { description: "Parallel tasks array" }),
|
|
29
|
-
),
|
|
30
|
-
chain: Type.Optional(
|
|
31
|
-
Type.Array(ChainItem, { description: "Sequential chain steps" }),
|
|
32
|
-
),
|
|
33
|
-
agentScope: Type.Optional(AgentScopeSchema),
|
|
34
|
-
concurrency: Type.Optional(
|
|
35
|
-
Type.Integer({
|
|
36
|
-
minimum: 1,
|
|
37
|
-
description: "Parallel mode max concurrency (default 4)",
|
|
38
|
-
}),
|
|
39
|
-
),
|
|
40
|
-
cwd: Type.Optional(Type.String({ description: "Working directory (single mode)" })),
|
|
41
|
-
async: Type.Optional(
|
|
42
|
-
Type.Boolean({ description: "Run in background; returns run id immediately" }),
|
|
43
|
-
),
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
export const WaitParams: TSchema = Type.Object({
|
|
47
|
-
id: Type.Optional(
|
|
48
|
-
Type.String({ description: "Run id or prefix to wait for one specific run" }),
|
|
49
|
-
),
|
|
50
|
-
all: Type.Optional(
|
|
51
|
-
Type.Boolean({
|
|
52
|
-
description:
|
|
53
|
-
"Wait for all active runs. Default false: return when the first run completes.",
|
|
54
|
-
}),
|
|
55
|
-
),
|
|
56
|
-
timeoutMs: Type.Optional(
|
|
57
|
-
Type.Integer({
|
|
58
|
-
minimum: 1,
|
|
59
|
-
description: "Timeout in milliseconds (default 30 minutes)",
|
|
60
|
-
}),
|
|
61
|
-
),
|
|
62
|
-
});
|
|
1
|
+
import { StringEnum } from "@earendil-works/pi-ai";
|
|
2
|
+
import { Type, type TSchema } from "typebox";
|
|
3
|
+
|
|
4
|
+
const TaskItem = Type.Object({
|
|
5
|
+
agent: Type.String({ description: "Name of the agent to invoke" }),
|
|
6
|
+
task: Type.String({ description: "Task to delegate to the agent" }),
|
|
7
|
+
cwd: Type.Optional(Type.String({ description: "Working directory for the agent process" })),
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
const ChainItem = Type.Object({
|
|
11
|
+
agent: Type.String({ description: "Name of the agent to invoke" }),
|
|
12
|
+
task: Type.String({
|
|
13
|
+
description:
|
|
14
|
+
"Task with optional {previous} placeholder for prior step output",
|
|
15
|
+
}),
|
|
16
|
+
cwd: Type.Optional(Type.String({ description: "Working directory for the agent process" })),
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
const AgentScopeSchema = StringEnum(["user", "project", "both"] as const, {
|
|
20
|
+
description: 'Which agent directories to use. Default: "both".',
|
|
21
|
+
default: "both",
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
export const SubagentParams: TSchema = Type.Object({
|
|
25
|
+
agent: Type.Optional(Type.String({ description: "Agent name (single mode)" })),
|
|
26
|
+
task: Type.Optional(Type.String({ description: "Task to delegate (single mode)" })),
|
|
27
|
+
tasks: Type.Optional(
|
|
28
|
+
Type.Array(TaskItem, { description: "Parallel tasks array" }),
|
|
29
|
+
),
|
|
30
|
+
chain: Type.Optional(
|
|
31
|
+
Type.Array(ChainItem, { description: "Sequential chain steps" }),
|
|
32
|
+
),
|
|
33
|
+
agentScope: Type.Optional(AgentScopeSchema),
|
|
34
|
+
concurrency: Type.Optional(
|
|
35
|
+
Type.Integer({
|
|
36
|
+
minimum: 1,
|
|
37
|
+
description: "Parallel mode max concurrency (default 4)",
|
|
38
|
+
}),
|
|
39
|
+
),
|
|
40
|
+
cwd: Type.Optional(Type.String({ description: "Working directory (single mode)" })),
|
|
41
|
+
async: Type.Optional(
|
|
42
|
+
Type.Boolean({ description: "Run in background; returns run id immediately" }),
|
|
43
|
+
),
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
export const WaitParams: TSchema = Type.Object({
|
|
47
|
+
id: Type.Optional(
|
|
48
|
+
Type.String({ description: "Run id or prefix to wait for one specific run" }),
|
|
49
|
+
),
|
|
50
|
+
all: Type.Optional(
|
|
51
|
+
Type.Boolean({
|
|
52
|
+
description:
|
|
53
|
+
"Wait for all active runs. Default false: return when the first run completes.",
|
|
54
|
+
}),
|
|
55
|
+
),
|
|
56
|
+
timeoutMs: Type.Optional(
|
|
57
|
+
Type.Integer({
|
|
58
|
+
minimum: 1,
|
|
59
|
+
description: "Timeout in milliseconds (default 30 minutes)",
|
|
60
|
+
}),
|
|
61
|
+
),
|
|
62
|
+
});
|
|
@@ -1,104 +1,104 @@
|
|
|
1
|
-
import * as fs from "node:fs";
|
|
2
|
-
import * as path from "node:path";
|
|
3
|
-
|
|
4
|
-
export interface PiSpawnDeps {
|
|
5
|
-
platform?: NodeJS.Platform;
|
|
6
|
-
execPath?: string;
|
|
7
|
-
argv1?: string;
|
|
8
|
-
existsSync?: (filePath: string) => boolean;
|
|
9
|
-
readFileSync?: (filePath: string, encoding: "utf-8") => string;
|
|
10
|
-
env?: NodeJS.ProcessEnv;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export interface PiSpawnCommand {
|
|
14
|
-
command: string;
|
|
15
|
-
args: string[];
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const PI_CODING_AGENT_PACKAGE = "@earendil-works/pi-coding-agent";
|
|
19
|
-
|
|
20
|
-
function isRunnableNodeScript(
|
|
21
|
-
filePath: string,
|
|
22
|
-
existsSync: (filePath: string) => boolean,
|
|
23
|
-
): boolean {
|
|
24
|
-
if (!existsSync(filePath)) return false;
|
|
25
|
-
return /\.(?:mjs|cjs|js)$/i.test(filePath);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function findPiPackageRootFromEntry(entryPoint: string): string | undefined {
|
|
29
|
-
let dir = path.dirname(entryPoint);
|
|
30
|
-
while (dir !== path.dirname(dir)) {
|
|
31
|
-
const packageJsonPath = path.join(dir, "package.json");
|
|
32
|
-
if (fs.existsSync(packageJsonPath)) {
|
|
33
|
-
const pkg = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8")) as {
|
|
34
|
-
name?: unknown;
|
|
35
|
-
};
|
|
36
|
-
if (pkg.name === PI_CODING_AGENT_PACKAGE) return dir;
|
|
37
|
-
}
|
|
38
|
-
dir = path.dirname(dir);
|
|
39
|
-
}
|
|
40
|
-
return undefined;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function resolvePiPackageRoot(): string | undefined {
|
|
44
|
-
try {
|
|
45
|
-
const entry = process.argv[1];
|
|
46
|
-
return entry
|
|
47
|
-
? findPiPackageRootFromEntry(fs.realpathSync(entry))
|
|
48
|
-
: undefined;
|
|
49
|
-
} catch {
|
|
50
|
-
return undefined;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export function resolveWindowsPiCliScript(deps: PiSpawnDeps = {}): string | undefined {
|
|
55
|
-
const existsSync = deps.existsSync ?? fs.existsSync;
|
|
56
|
-
const readFileSync =
|
|
57
|
-
deps.readFileSync ??
|
|
58
|
-
((filePath, encoding) => fs.readFileSync(filePath, encoding));
|
|
59
|
-
const argv1 = deps.argv1 ?? process.argv[1];
|
|
60
|
-
|
|
61
|
-
if (argv1) {
|
|
62
|
-
const argvPath = path.isAbsolute(argv1) ? argv1 : path.resolve(argv1);
|
|
63
|
-
if (isRunnableNodeScript(argvPath, existsSync)) return argvPath;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
try {
|
|
67
|
-
const root = resolvePiPackageRoot();
|
|
68
|
-
if (!root) return undefined;
|
|
69
|
-
const packageJsonPath = path.join(root, "package.json");
|
|
70
|
-
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8")) as {
|
|
71
|
-
bin?: string | Record<string, string>;
|
|
72
|
-
};
|
|
73
|
-
const binField = packageJson.bin;
|
|
74
|
-
const binPath =
|
|
75
|
-
typeof binField === "string"
|
|
76
|
-
? binField
|
|
77
|
-
: (binField?.pi ?? Object.values(binField ?? {})[0]);
|
|
78
|
-
if (!binPath) return undefined;
|
|
79
|
-
const candidate = path.resolve(path.dirname(packageJsonPath), binPath);
|
|
80
|
-
if (isRunnableNodeScript(candidate, existsSync)) return candidate;
|
|
81
|
-
} catch {
|
|
82
|
-
return undefined;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return undefined;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export function getPiSpawnCommand(
|
|
89
|
-
args: string[],
|
|
90
|
-
deps: PiSpawnDeps = {},
|
|
91
|
-
): PiSpawnCommand {
|
|
92
|
-
const platform = deps.platform ?? process.platform;
|
|
93
|
-
if (platform === "win32") {
|
|
94
|
-
const piCliPath = resolveWindowsPiCliScript(deps);
|
|
95
|
-
if (piCliPath) {
|
|
96
|
-
return {
|
|
97
|
-
command: deps.execPath ?? process.execPath,
|
|
98
|
-
args: [piCliPath, ...args],
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
return { command: "pi", args };
|
|
104
|
-
}
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
|
|
4
|
+
export interface PiSpawnDeps {
|
|
5
|
+
platform?: NodeJS.Platform;
|
|
6
|
+
execPath?: string;
|
|
7
|
+
argv1?: string;
|
|
8
|
+
existsSync?: (filePath: string) => boolean;
|
|
9
|
+
readFileSync?: (filePath: string, encoding: "utf-8") => string;
|
|
10
|
+
env?: NodeJS.ProcessEnv;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface PiSpawnCommand {
|
|
14
|
+
command: string;
|
|
15
|
+
args: string[];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const PI_CODING_AGENT_PACKAGE = "@earendil-works/pi-coding-agent";
|
|
19
|
+
|
|
20
|
+
function isRunnableNodeScript(
|
|
21
|
+
filePath: string,
|
|
22
|
+
existsSync: (filePath: string) => boolean,
|
|
23
|
+
): boolean {
|
|
24
|
+
if (!existsSync(filePath)) return false;
|
|
25
|
+
return /\.(?:mjs|cjs|js)$/i.test(filePath);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function findPiPackageRootFromEntry(entryPoint: string): string | undefined {
|
|
29
|
+
let dir = path.dirname(entryPoint);
|
|
30
|
+
while (dir !== path.dirname(dir)) {
|
|
31
|
+
const packageJsonPath = path.join(dir, "package.json");
|
|
32
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
33
|
+
const pkg = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8")) as {
|
|
34
|
+
name?: unknown;
|
|
35
|
+
};
|
|
36
|
+
if (pkg.name === PI_CODING_AGENT_PACKAGE) return dir;
|
|
37
|
+
}
|
|
38
|
+
dir = path.dirname(dir);
|
|
39
|
+
}
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function resolvePiPackageRoot(): string | undefined {
|
|
44
|
+
try {
|
|
45
|
+
const entry = process.argv[1];
|
|
46
|
+
return entry
|
|
47
|
+
? findPiPackageRootFromEntry(fs.realpathSync(entry))
|
|
48
|
+
: undefined;
|
|
49
|
+
} catch {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function resolveWindowsPiCliScript(deps: PiSpawnDeps = {}): string | undefined {
|
|
55
|
+
const existsSync = deps.existsSync ?? fs.existsSync;
|
|
56
|
+
const readFileSync =
|
|
57
|
+
deps.readFileSync ??
|
|
58
|
+
((filePath, encoding) => fs.readFileSync(filePath, encoding));
|
|
59
|
+
const argv1 = deps.argv1 ?? process.argv[1];
|
|
60
|
+
|
|
61
|
+
if (argv1) {
|
|
62
|
+
const argvPath = path.isAbsolute(argv1) ? argv1 : path.resolve(argv1);
|
|
63
|
+
if (isRunnableNodeScript(argvPath, existsSync)) return argvPath;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
const root = resolvePiPackageRoot();
|
|
68
|
+
if (!root) return undefined;
|
|
69
|
+
const packageJsonPath = path.join(root, "package.json");
|
|
70
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8")) as {
|
|
71
|
+
bin?: string | Record<string, string>;
|
|
72
|
+
};
|
|
73
|
+
const binField = packageJson.bin;
|
|
74
|
+
const binPath =
|
|
75
|
+
typeof binField === "string"
|
|
76
|
+
? binField
|
|
77
|
+
: (binField?.pi ?? Object.values(binField ?? {})[0]);
|
|
78
|
+
if (!binPath) return undefined;
|
|
79
|
+
const candidate = path.resolve(path.dirname(packageJsonPath), binPath);
|
|
80
|
+
if (isRunnableNodeScript(candidate, existsSync)) return candidate;
|
|
81
|
+
} catch {
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return undefined;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function getPiSpawnCommand(
|
|
89
|
+
args: string[],
|
|
90
|
+
deps: PiSpawnDeps = {},
|
|
91
|
+
): PiSpawnCommand {
|
|
92
|
+
const platform = deps.platform ?? process.platform;
|
|
93
|
+
if (platform === "win32") {
|
|
94
|
+
const piCliPath = resolveWindowsPiCliScript(deps);
|
|
95
|
+
if (piCliPath) {
|
|
96
|
+
return {
|
|
97
|
+
command: deps.execPath ?? process.execPath,
|
|
98
|
+
args: [piCliPath, ...args],
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return { command: "pi", args };
|
|
104
|
+
}
|