@ferris1225/pi-subagents 4.3.2 → 4.3.3
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/CHANGELOG.md +13 -0
- package/README.md +88 -49
- package/agents/artisan.md +7 -5
- package/agents/scout.md +5 -3
- package/agents/sentinel.md +16 -0
- package/agents/steward.md +9 -8
- package/package.json +2 -2
- package/src/agents.ts +1 -1
- package/src/announcements.ts +1 -1
- package/src/config.ts +63 -14
- package/src/dispatch.ts +9 -8
- package/src/prompt.ts +15 -9
- package/src/setup.ts +277 -280
- package/src/thread-lifecycle.ts +4 -2
- package/src/ui.ts +66 -154
- package/src/widget.ts +14 -13
package/src/dispatch.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The `subagent` tool: dispatches
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* The `subagent` tool: dispatches enabled scout, artisan, steward, sentinel,
|
|
3
|
+
* and custom roles as isolated pi child processes, single or parallel.
|
|
4
|
+
* Owns the public dispatch contract and
|
|
5
5
|
* per-run status tracking. Stable thread generations, final integration, and
|
|
6
6
|
* completion ownership live in thread-lifecycle.ts.
|
|
7
7
|
*/
|
|
@@ -11,7 +11,7 @@ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
|
11
11
|
import { Text } from "@earendil-works/pi-tui";
|
|
12
12
|
import { join, resolve } from "node:path";
|
|
13
13
|
import { Type } from "typebox";
|
|
14
|
-
import { discoverAgents,
|
|
14
|
+
import { discoverAgents, resolveAgentTools, type AgentConfig } from "./agents.ts";
|
|
15
15
|
import { loadConfig } from "./config.ts";
|
|
16
16
|
import { formatCompletionBlock, formatUsage, queuedResult } from "./format.ts";
|
|
17
17
|
import {
|
|
@@ -39,6 +39,7 @@ import {
|
|
|
39
39
|
} from "./spawn.ts";
|
|
40
40
|
import {
|
|
41
41
|
createBackgroundDispatcher,
|
|
42
|
+
isWorktreeCapableAgent,
|
|
42
43
|
projectResultsRoot,
|
|
43
44
|
resolveDispatchModelRoute,
|
|
44
45
|
runInManagedRepositoryLane,
|
|
@@ -47,7 +48,7 @@ import {
|
|
|
47
48
|
} from "./thread-lifecycle.ts";
|
|
48
49
|
import type { IsolationMode } from "./worktree.ts";
|
|
49
50
|
|
|
50
|
-
export { isWorktreeCapableAgent, runInManagedRepositoryLane }
|
|
51
|
+
export { isWorktreeCapableAgent, runInManagedRepositoryLane };
|
|
51
52
|
|
|
52
53
|
const NON_BLANK_TASK_OPTIONS = { minLength: 1, pattern: "\\S" } as const;
|
|
53
54
|
|
|
@@ -88,7 +89,7 @@ const SubagentParams = Type.Object({
|
|
|
88
89
|
|
|
89
90
|
/** Roles that default to worktree isolation in parallel dispatches even when
|
|
90
91
|
* the live catalog cannot be consulted (render-only call sites). Custom
|
|
91
|
-
*
|
|
92
|
+
* worktree-capable agents join them via the live catalog on the execute path. */
|
|
92
93
|
const WORKTREE_DEFAULT_AGENTS = new Set(["artisan", "steward"]);
|
|
93
94
|
|
|
94
95
|
/** Resolve the default isolation for a dispatch. Precedence: an explicit
|
|
@@ -467,7 +468,7 @@ export function registerSubagentTool(pi: ExtensionAPI, runtime: SubagentRuntime)
|
|
|
467
468
|
"parallel",
|
|
468
469
|
item.agent,
|
|
469
470
|
item.isolation as IsolationMode | undefined,
|
|
470
|
-
catalogAgent ?
|
|
471
|
+
catalogAgent ? isWorktreeCapableAgent(catalogAgent) : undefined,
|
|
471
472
|
catalogAgent?.isolation,
|
|
472
473
|
),
|
|
473
474
|
{ deliveryRoute: params.wait ? "await" : "background" },
|
|
@@ -522,7 +523,7 @@ export function registerSubagentTool(pi: ExtensionAPI, runtime: SubagentRuntime)
|
|
|
522
523
|
"single",
|
|
523
524
|
params.agent as string,
|
|
524
525
|
params.isolation as IsolationMode | undefined,
|
|
525
|
-
singleCatalogAgent ?
|
|
526
|
+
singleCatalogAgent ? isWorktreeCapableAgent(singleCatalogAgent) : undefined,
|
|
526
527
|
singleCatalogAgent?.isolation,
|
|
527
528
|
),
|
|
528
529
|
{ deliveryRoute: params.wait ? "await" : "background" },
|
package/src/prompt.ts
CHANGED
|
@@ -34,8 +34,9 @@ function bullets(lines: readonly string[]): string {
|
|
|
34
34
|
|
|
35
35
|
function phaseForAgent(agentName: string): string {
|
|
36
36
|
if (agentName === "scout") return "broad reconnaissance";
|
|
37
|
-
if (agentName === "artisan") return "
|
|
37
|
+
if (agentName === "artisan") return "primary change";
|
|
38
38
|
if (agentName === "steward") return "pre-commit cleanup and cross-cutting docs";
|
|
39
|
+
if (agentName === "sentinel") return "post-cleanup adversarial review";
|
|
39
40
|
return "delegated scope";
|
|
40
41
|
}
|
|
41
42
|
|
|
@@ -104,16 +105,21 @@ export function buildDelegationDirective(
|
|
|
104
105
|
const hasScout = agents.some((agent) => agent.name === "scout");
|
|
105
106
|
const hasArtisan = agents.some((agent) => agent.name === "artisan");
|
|
106
107
|
const hasSteward = agents.some((agent) => agent.name === "steward");
|
|
108
|
+
const hasSentinel = agents.some((agent) => agent.name === "sentinel");
|
|
107
109
|
|
|
108
110
|
const dispatchRules = [
|
|
109
|
-
|
|
110
|
-
"Keep atomic lookups, focused edits, known answers, and context-heavy work in main. Cluster related reconnaissance into one scout brief.",
|
|
111
|
-
...(hasScout ? ["`scout`: broad or
|
|
112
|
-
...(hasArtisan ? ["`artisan`: substantial
|
|
113
|
-
...(hasSteward ? ["`steward`:
|
|
114
|
-
"
|
|
115
|
-
|
|
116
|
-
|
|
111
|
+
`Main owns routing, architecture, integration, the final gate, and release. Each child starts a paid context; delegate only when handoff saves more than it costs${hasSentinel ? ", except required sentinel review before commit" : ""}.`,
|
|
112
|
+
"Keep atomic lookups, focused edits, known answers, and context-heavy work in main. Cluster related reconnaissance into one scout brief, including external research.",
|
|
113
|
+
...(hasScout ? ["`scout`: read-only broad code mapping or external research; return file/source citations as leads, not proof."] : []),
|
|
114
|
+
...(hasArtisan ? ["`artisan`: one substantial primary change; own root cause, implementation, affected tests/docs, and targeted checks."] : []),
|
|
115
|
+
...(hasSteward ? ["`steward`: final cleanup/docs sync for a completed broad or multi-writer diff; keep focused hygiene inline."] : []),
|
|
116
|
+
...(hasSentinel ? ["`sentinel`: read-only post-cleanup review; use matching skills and report only evidenced defects."] : []),
|
|
117
|
+
...(hasSentinel
|
|
118
|
+
? [`Before every commit: cleanup -> sentinel review. ${hasSteward ? "Use steward once only for broad or multi-writer diffs" : "Keep cleanup inline"}. Then dispatch sentinel on the final diff and check evidence. After review fixes, clean and review once more; findings block commit.`]
|
|
119
|
+
: []),
|
|
120
|
+
"One owner per phase; dependent phases wait. A launch leases that phase: main may inspect its result, citations, diff, and checks, not redo the phase; main still runs the final gate.",
|
|
121
|
+
"Parallelize only independent, disjoint scopes. Brief goal, paths, constraints, and expected output; resume with `subagent_control`.",
|
|
122
|
+
"`wait: true` only when the result is the immediate dependency; otherwise continue disjoint work. Never sleep or poll, and never finish while a run is active.",
|
|
117
123
|
"Inspect the integrated diff and actual check output. Never report an unrun check as passed.",
|
|
118
124
|
];
|
|
119
125
|
|