@rol1n/pi-kit 0.0.0-stage → 0.1.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.
Files changed (120) hide show
  1. package/README.md +73 -2
  2. package/ask-u-questions/README.md +26 -0
  3. package/ask-u-questions/dialog-ui.ts +80 -0
  4. package/ask-u-questions/index.ts +92 -0
  5. package/ask-u-questions/multi-choice.ts +258 -0
  6. package/ask-u-questions/single-choice.ts +180 -0
  7. package/ask-u-questions/tool-renderers.ts +67 -0
  8. package/ask-u-questions/types.ts +192 -0
  9. package/continue-signal/README.md +20 -0
  10. package/continue-signal/index.ts +69 -0
  11. package/custom-providers/README.md +20 -0
  12. package/custom-providers/asr/handlers/dashscope.ts +154 -0
  13. package/custom-providers/asr/index.ts +37 -0
  14. package/custom-providers/asr/models.ts +18 -0
  15. package/custom-providers/asr/types.ts +20 -0
  16. package/custom-providers/chat/index.ts +33 -0
  17. package/custom-providers/chat/magpie.ts +258 -0
  18. package/custom-providers/chat/models.ts +111 -0
  19. package/custom-providers/classifier/index.ts +6 -0
  20. package/custom-providers/classifier/models.ts +1 -0
  21. package/custom-providers/image/handlers/dashscope.ts +240 -0
  22. package/custom-providers/image/handlers/openrouter.ts +185 -0
  23. package/custom-providers/image/index.ts +96 -0
  24. package/custom-providers/image/models.ts +71 -0
  25. package/custom-providers/image/types.ts +22 -0
  26. package/custom-providers/index.ts +64 -0
  27. package/custom-providers/types.ts +17 -0
  28. package/image-generate/README.md +25 -0
  29. package/image-generate/files.ts +49 -0
  30. package/image-generate/index.ts +220 -0
  31. package/image-generate/model-selector.ts +150 -0
  32. package/memory-log/README.md +54 -0
  33. package/memory-log/agent/consolidator/prompt.ts +47 -0
  34. package/memory-log/agent/consolidator/tools.ts +160 -0
  35. package/memory-log/agent/cost.ts +32 -0
  36. package/memory-log/agent/index.ts +42 -0
  37. package/memory-log/agent/observer/prompt.ts +73 -0
  38. package/memory-log/agent/observer/tool.ts +73 -0
  39. package/memory-log/commands/compact.ts +35 -0
  40. package/memory-log/commands/consolidate.ts +47 -0
  41. package/memory-log/commands/status.ts +50 -0
  42. package/memory-log/config.ts +253 -0
  43. package/memory-log/debug-log.ts +76 -0
  44. package/memory-log/hooks/compaction-hook.ts +161 -0
  45. package/memory-log/hooks/compaction-trigger.ts +160 -0
  46. package/memory-log/hooks/consolidator-trigger.ts +143 -0
  47. package/memory-log/hooks/observer-trigger.ts +176 -0
  48. package/memory-log/ids.ts +78 -0
  49. package/memory-log/index.ts +149 -0
  50. package/memory-log/ledger/fold.ts +77 -0
  51. package/memory-log/ledger/index.ts +7 -0
  52. package/memory-log/ledger/pool.ts +38 -0
  53. package/memory-log/ledger/progress.ts +181 -0
  54. package/memory-log/ledger/projection.ts +115 -0
  55. package/memory-log/ledger/render.ts +38 -0
  56. package/memory-log/ledger/serialize.ts +161 -0
  57. package/memory-log/ledger/types.ts +201 -0
  58. package/memory-log/memory/index-render.ts +45 -0
  59. package/memory-log/memory/paths.ts +120 -0
  60. package/memory-log/memory/session.ts +64 -0
  61. package/memory-log/runtime.ts +127 -0
  62. package/memory-log/spawn/launch.ts +133 -0
  63. package/memory-log/spawn/runs.ts +83 -0
  64. package/memory-log/tokens.ts +66 -0
  65. package/memory-log/ui/status-controller.ts +225 -0
  66. package/memory-log/ui/timeline.ts +103 -0
  67. package/model-vision/README.md +22 -0
  68. package/multi-harness/README.md +63 -0
  69. package/multi-harness/adapters.mjs +72 -0
  70. package/multi-harness/harness-done.mjs +14 -0
  71. package/multi-harness/index.ts +375 -0
  72. package/multi-harness/ipc.mjs +37 -0
  73. package/multi-harness/opencode-plugin.mjs +99 -0
  74. package/multi-harness/process-runner.mjs +115 -0
  75. package/multi-harness/turn-hook.mjs +29 -0
  76. package/multi-harness/worker-bridge.ts +52 -0
  77. package/oai-subquota/README.md +22 -0
  78. package/oai-subquota/index.ts +286 -0
  79. package/oai-subquota/snapshot.ts +293 -0
  80. package/oai-subquota/ui.ts +183 -0
  81. package/package.json +92 -4
  82. package/prompt-snipaste/README.md +27 -0
  83. package/prompt-snipaste/index.ts +143 -0
  84. package/prompt-snipaste/menu.ts +159 -0
  85. package/prompt-snipaste/prompts/ask-questions.md +8 -0
  86. package/prompt-snipaste/prompts/delegate-exploration.md +7 -0
  87. package/prompt-snipaste/prompts/diagnose-report.md +7 -0
  88. package/prompt-snipaste/prompts/frontend-tech-preset.md +18 -0
  89. package/prompt-snipaste/prompts/orchestrator-mode.md +7 -0
  90. package/prompt-snipaste/prompts/session-kickoff.md +7 -0
  91. package/prompt-snipaste/prompts/verify-not-assume.md +7 -0
  92. package/prompt-snipaste/renderers.ts +87 -0
  93. package/prompt-snipaste/snippets.ts +206 -0
  94. package/prompt-snipaste/types.ts +18 -0
  95. package/screenshot/README.md +14 -0
  96. package/srp-theme/README.md +18 -0
  97. package/srp-theme/footer.ts +193 -0
  98. package/srp-theme/index.ts +172 -0
  99. package/srp-theme/tps-meter.ts +441 -0
  100. package/subagent/README.md +35 -0
  101. package/subagent/bridge.ts +171 -0
  102. package/subagent/index.ts +590 -0
  103. package/subagent/mux.ts +621 -0
  104. package/subagent/session.ts +166 -0
  105. package/subagent/ui.ts +100 -0
  106. package/tui-asr/README.md +21 -0
  107. package/tui-asr/dictation.ts +272 -0
  108. package/tui-asr/index.ts +181 -0
  109. package/tui-asr/input.ts +87 -0
  110. package/tui-asr/model-selector.ts +163 -0
  111. package/tui-asr/status.ts +79 -0
  112. package/web-reach/README.md +19 -0
  113. package/web-reach/html.ts +83 -0
  114. package/web-reach/index.ts +82 -0
  115. package/web-reach/page.ts +214 -0
  116. package/web-reach/rsc.ts +161 -0
  117. package/web-reach/search.ts +85 -0
  118. package/web-reach/transport.ts +35 -0
  119. package/windows-wheel-fix/README.md +12 -0
  120. package/windows-wheel-fix/index.ts +44 -0
@@ -0,0 +1,171 @@
1
+ /**
2
+ * subagent/bridge.ts — Subagent Worker Bridge
3
+ *
4
+ * Loaded exclusively inside the spawned worker Pi process via `-e <bridgePath>`.
5
+ * - Grants the worker an `ask_question` tool to consult the parent orchestrator.
6
+ * - Handles auto-exit on task completion (calling ctx.shutdown() so the pane closes cleanly).
7
+ * - Suppresses auto-exit while waiting for the parent's answer to `ask_question`.
8
+ * - Prevents recursive subagent spawning.
9
+ */
10
+
11
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
12
+ import { Box, Text } from "@earendil-works/pi-tui";
13
+ import { Type } from "typebox";
14
+ import { existsSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
15
+
16
+ export default function subagentBridge(pi: ExtensionAPI) {
17
+ if (process.env.PI_SUBAGENT_ACTIVE !== "1") {
18
+ return;
19
+ }
20
+
21
+ const workerName = process.env.PI_SUBAGENT_NAME || "worker";
22
+ const sessionFile = process.env.PI_SUBAGENT_SESSION;
23
+
24
+ let awaitingAnswer = false;
25
+
26
+ // Render a minimal indicator in the child worker's terminal
27
+ pi.on("session_start", (_event, ctx) => {
28
+ ctx.ui.setWidget(
29
+ "subagent-worker-banner",
30
+ (_tui, theme) => {
31
+ const box = new Box(1, 0, (text: string) => {
32
+ try {
33
+ return theme.bg("toolSuccessBg", text);
34
+ } catch {
35
+ return text;
36
+ }
37
+ });
38
+ const badge = theme.bold(theme.fg("accent", `[Worker: ${workerName}]`));
39
+ const hint = theme.fg("dim", " · Full Pi worker · ask_question available");
40
+ box.addChild(new Text(`${badge}${hint}`, 0, 0));
41
+ return box;
42
+ },
43
+ { placement: "aboveEditor" },
44
+ );
45
+ });
46
+
47
+ // When input arrives (e.g. parent reply or manual steer), answer is received
48
+ pi.on("input", () => {
49
+ awaitingAnswer = false;
50
+ });
51
+
52
+ pi.on("agent_start", () => {
53
+ awaitingAnswer = false;
54
+ });
55
+
56
+ pi.on("agent_end", (event, ctx) => {
57
+ if (awaitingAnswer) {
58
+ // Park in waiting state, do not exit
59
+ return;
60
+ }
61
+
62
+ const messages = (event as any).messages as any[] | undefined;
63
+ let errorMessage: string | undefined;
64
+
65
+ if (messages && messages.length > 0) {
66
+ for (let i = messages.length - 1; i >= 0; i--) {
67
+ const msg = messages[i];
68
+ if (msg?.role === "assistant") {
69
+ if (msg.stopReason === "error") {
70
+ errorMessage = typeof msg.errorMessage === "string" ? msg.errorMessage : "Agent ended with error";
71
+ }
72
+ break;
73
+ }
74
+ }
75
+ }
76
+
77
+ if (sessionFile) {
78
+ try {
79
+ writeFileSync(
80
+ `${sessionFile}.exit`,
81
+ JSON.stringify({
82
+ type: errorMessage ? "error" : "done",
83
+ ...(errorMessage ? { errorMessage } : {}),
84
+ }),
85
+ );
86
+ } catch {
87
+ // best effort
88
+ }
89
+ }
90
+
91
+ ctx.shutdown();
92
+ });
93
+
94
+ // Register `ask_question` tool
95
+ pi.registerTool({
96
+ name: "ask_question",
97
+ label: "Ask Orchestrator",
98
+ description:
99
+ "Ask the orchestrator (the parent agent that spawned you) a clarifying question and pause until they reply. " +
100
+ "Use when requirements are ambiguous, a critical decision needs confirmation, or you are blocked. " +
101
+ "Your session stays open while you wait — the answer will arrive as your next turn message.",
102
+ parameters: Type.Object({
103
+ question: Type.String({
104
+ description: "The question for the parent orchestrator. Include enough context for them to decide.",
105
+ }),
106
+ }),
107
+ async execute(_toolCallId, params, signal) {
108
+ if (!sessionFile) {
109
+ throw new Error("ask_question is only available within a managed subagent session.");
110
+ }
111
+
112
+ awaitingAnswer = true;
113
+ const askFile = `${sessionFile}.ask`;
114
+ const replyFile = `${sessionFile}.reply`;
115
+
116
+ const askData = {
117
+ name: workerName,
118
+ question: params.question,
119
+ timestamp: new Date().toISOString(),
120
+ };
121
+
122
+ writeFileSync(askFile, JSON.stringify(askData));
123
+
124
+ try {
125
+ while (!existsSync(replyFile)) {
126
+ if (signal?.aborted) {
127
+ throw new Error("Cancelled while waiting for parent reply");
128
+ }
129
+ await new Promise<void>((resolve, reject) => {
130
+ const timer = setTimeout(resolve, 200);
131
+ if (signal) {
132
+ const onAbort = () => {
133
+ clearTimeout(timer);
134
+ signal.removeEventListener("abort", onAbort);
135
+ reject(new Error("Cancelled while waiting for parent reply"));
136
+ };
137
+ signal.addEventListener("abort", onAbort, { once: true });
138
+ }
139
+ });
140
+ }
141
+
142
+ const reply = readFileSync(replyFile, "utf-8");
143
+ try {
144
+ unlinkSync(replyFile);
145
+ } catch {}
146
+ awaitingAnswer = false;
147
+
148
+ return {
149
+ content: [
150
+ {
151
+ type: "text",
152
+ text: `Orchestrator answer:\n\n${reply}`,
153
+ },
154
+ ],
155
+ details: { question: params.question, reply },
156
+ };
157
+ } finally {
158
+ awaitingAnswer = false;
159
+ try {
160
+ if (existsSync(askFile)) unlinkSync(askFile);
161
+ } catch {}
162
+ }
163
+ },
164
+ renderCall(args, theme) {
165
+ const text =
166
+ theme.fg("toolTitle", theme.bold("ask_question ")) +
167
+ theme.fg("muted", String((args as any).question ?? ""));
168
+ return new Text(text, 0, 0);
169
+ },
170
+ });
171
+ }