@jwilger/pi-development-system 0.10.6 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +9 -1
  2. package/agents/advisor.md +40 -0
  3. package/agents/architect.md +66 -0
  4. package/agents/coder.md +57 -0
  5. package/agents/implementer.md +47 -0
  6. package/agents/lens-cagan.md +54 -0
  7. package/agents/lens-perri.md +54 -0
  8. package/agents/lens-pichler.md +54 -0
  9. package/agents/lens-rumelt.md +54 -0
  10. package/agents/lens-torres.md +54 -0
  11. package/agents/researcher.md +70 -0
  12. package/agents/reviewer.md +57 -0
  13. package/agents/tasker.md +58 -0
  14. package/agents/writer.md +39 -0
  15. package/extensions/development-system.ts +4 -0
  16. package/package.json +5 -3
  17. package/skills/delegation/SKILL.md +66 -0
  18. package/src/core/models.ts +18 -0
  19. package/src/core/routing.ts +67 -0
  20. package/src/core/spawn-overrides.ts +59 -0
  21. package/src/jev/questions/route.ts +93 -0
  22. package/src/state/config.ts +2 -4
  23. package/src/state/route-task-tool.ts +74 -0
  24. package/src/subagents/VENDORED.md +40 -0
  25. package/src/subagents/index.ts +544 -0
  26. package/src/subagents/orch/inherited-tools.ts +85 -0
  27. package/src/subagents/orch/mailbox.ts +262 -0
  28. package/src/subagents/orch/manager.ts +778 -0
  29. package/src/subagents/orch/paths.ts +74 -0
  30. package/src/subagents/orch/prompt.ts +25 -0
  31. package/src/subagents/orch/runtime.ts +791 -0
  32. package/src/subagents/orch/tools.ts +177 -0
  33. package/src/subagents/orch/transcript.ts +187 -0
  34. package/src/subagents/prefs/agent-import.ts +246 -0
  35. package/src/subagents/prefs/config.ts +1029 -0
  36. package/src/subagents/prefs/import-discovery.ts +644 -0
  37. package/src/subagents/prefs/import-instructions.ts +157 -0
  38. package/src/subagents/prefs/models.ts +85 -0
  39. package/src/subagents/prefs/settings.ts +371 -0
  40. package/src/subagents/types.ts +209 -0
  41. package/src/subagents/ui/agent-navigation-editor.ts +210 -0
  42. package/src/subagents/ui/dialog.ts +651 -0
  43. package/src/subagents/ui/import-picker.ts +232 -0
  44. package/src/subagents/ui/live-agent-view.ts +572 -0
  45. package/src/subagents/ui/model-picker.ts +452 -0
  46. package/src/subagents/ui/settings-ui.ts +329 -0
  47. package/src/subagents/ui/status-ui.ts +545 -0
  48. package/src/subagents/ui/thread-tree.ts +135 -0
  49. package/src/subagents/ui/ui.ts +1507 -0
@@ -0,0 +1,74 @@
1
+ // @ts-nocheck: vendored upstream pi-subagent-manager 0.14.0 compiled under looser options; see src/subagents/VENDORED.md
2
+ import type { AgentMessage } from "@earendil-works/pi-agent-core";
3
+
4
+ const SEGMENT = /^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/;
5
+ export function canonicalPath(value: string, caller = "/root"): string {
6
+ if (!value || value !== value.trim())
7
+ throw new Error("Agent path must not be empty or contain surrounding whitespace");
8
+ const path = value.startsWith("/") ? value : `${caller}/${value}`;
9
+ const parts = path.slice(1).split("/");
10
+ if (!parts.every((part) => SEGMENT.test(part)) || parts.length > 32) {
11
+ throw new Error(
12
+ "Agent paths require slash-separated names (letters, digits, - or _); no dot segments, escapes, empty segments or trailing slash",
13
+ );
14
+ }
15
+ return path;
16
+ }
17
+ export function parentPath(path: string): string | null {
18
+ canonicalPath(path);
19
+ const last = path.lastIndexOf("/");
20
+ return last === 0 ? null : path.slice(0, last);
21
+ }
22
+ export function isDescendant(path: string, ancestor: string): boolean {
23
+ return path.startsWith(`${ancestor}/`);
24
+ }
25
+
26
+ /** Snapshot conversation, not the parent's prompt/loadout; retain only matched tool exchanges. */
27
+ export function inheritContext(messages: readonly AgentMessage[]): AgentMessage[] {
28
+ const copy = structuredClone(messages);
29
+ const matchedCalls = new Set<string>();
30
+ const matchedResults = new Set<number>();
31
+ const pending = new Map<string, { messageIndex: number; blockIndex: number }[]>();
32
+
33
+ for (const [messageIndex, message] of copy.entries()) {
34
+ if (message.role === "assistant") {
35
+ if (message.stopReason === "error" || message.stopReason === "aborted") continue;
36
+ for (const [blockIndex, block] of message.content.entries()) {
37
+ if (block.type !== "toolCall") continue;
38
+ const queue = pending.get(block.id);
39
+ const occurrence = { messageIndex, blockIndex };
40
+ if (queue) queue.push(occurrence);
41
+ else pending.set(block.id, [occurrence]);
42
+ }
43
+ continue;
44
+ }
45
+ if (message.role !== "toolResult") continue;
46
+ const queue = pending.get(message.toolCallId);
47
+ const occurrence = queue?.shift();
48
+ if (!occurrence) continue;
49
+ matchedCalls.add(`${occurrence.messageIndex}:${occurrence.blockIndex}`);
50
+ matchedResults.add(messageIndex);
51
+ if (queue && !queue.length) pending.delete(message.toolCallId);
52
+ }
53
+
54
+ return copy.flatMap((message, messageIndex): AgentMessage[] => {
55
+ // Only the system prompt/loadout is replaced; custom and shell messages are real conversation context.
56
+ if (message.role === "system") return [];
57
+ if (message.role === "assistant") {
58
+ if (message.stopReason === "error" || message.stopReason === "aborted") return [];
59
+ message.content = message.content.filter(
60
+ (block, blockIndex) =>
61
+ block.type !== "toolCall" || matchedCalls.has(`${messageIndex}:${blockIndex}`),
62
+ );
63
+ if (!message.content.length) return [];
64
+ // A tools-only assistant without remaining calls should not claim a toolUse stop.
65
+ if (
66
+ message.stopReason === "toolUse" &&
67
+ !message.content.some((block) => block.type === "toolCall")
68
+ )
69
+ message.stopReason = "stop";
70
+ }
71
+ if (message.role === "toolResult" && !matchedResults.has(messageIndex)) return [];
72
+ return [message];
73
+ });
74
+ }
@@ -0,0 +1,25 @@
1
+ // @ts-nocheck: vendored upstream pi-subagent-manager 0.14.0 compiled under looser options; see src/subagents/VENDORED.md
2
+ import type { ManagerSettings } from "../prefs/settings.ts";
3
+
4
+ /** Root-only guidance: child SDK sessions use their own worker prompt. */
5
+ export function subagentPrompt(settings: ManagerSettings): string | undefined {
6
+ if (settings.subagentMode === "off") return undefined;
7
+ const policy =
8
+ settings.subagentMode === "orchestration"
9
+ ? "Orchestration mode: /root only coordinates. Delegate every user task to subagents, even small or sequential tasks. Do not inspect/edit files, run commands, research, or execute task work yourself. Only plan, assign, monitor, clarify, and synthesize subagent results for the user. This restriction applies only to /root; subagents execute the work."
10
+ : "Opportunistic mode: do ordinary tasks yourself. Delegate only when work can be parallelized, is long-running, or is very large; do not spawn agents for small, quick, straightforward tasks.";
11
+ const waitingPolicy =
12
+ settings.subagentMode === "orchestration"
13
+ ? "As an orchestrator, you must NEVER be blocked waiting for subagents. ALWAYS start every subagent in async/background mode with wait:false, even for small or sequential tasks. NEVER call agent_wait or use a foreground spawn. End your turn after assigning work so you remain free to talk to the user while subagents work. Check agent_status and collect available results with agent_output without blocking; if results are not ready, report that and leave the conversation free."
14
+ : "For independent parallel work, spawn all siblings with wait:false before agent_wait. Only await synchronous tasks whose results are needed in the current turn. For long-running tasks, create background agents with wait:false and do not immediately call agent_wait; end your turn so you remain free to talk to the user while they work. Await background results when the user asks you to collect them.";
15
+ return [
16
+ "## pi-subagent",
17
+ "You are /root, the main conversation (L1).",
18
+ policy,
19
+ "Call agent_types before choosing a type. Use task-based kebab-case paths, not type names. Choose context via agent_spawn path: /root/task forks the lexical parent's conversation; /task starts fresh with no inherited history. Use fresh agents for adversarial review or clean-slate research; give them a self-contained task without the current thread's conclusions.",
20
+ waitingPolicy,
21
+ "Use agent_status to inspect and agent_output for full results. Detached notifications do not resume your turn.",
22
+ "Use agent_steer to send input or resume retained sessions. Paused agents have no final answer; completed agents hand back results. Both retain their session.",
23
+ `Maximum depth: ${settings.maxLevels} levels including L1. Shared concurrency: ${settings.maxConcurrent} active threads; waiting parents count.`,
24
+ ].join("\n");
25
+ }