pi-orchestrator-config 4.1.5

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 (175) hide show
  1. package/README.md +808 -0
  2. package/agents/api-documenter.md +32 -0
  3. package/agents/bash-expert.md +53 -0
  4. package/agents/code-reviewer-docs.md +145 -0
  5. package/agents/code-reviewer-guidelines.md +97 -0
  6. package/agents/code-reviewer-quality.md +142 -0
  7. package/agents/code-reviewer-security.md +107 -0
  8. package/agents/code-reviewer-spec.md +164 -0
  9. package/agents/debugger.md +63 -0
  10. package/agents/docker-expert.md +40 -0
  11. package/agents/docs-fetcher.md +48 -0
  12. package/agents/git-expert.md +63 -0
  13. package/agents/github-expert.md +83 -0
  14. package/agents/go-expert.md +62 -0
  15. package/agents/issue-reviewer-feasibility.md +60 -0
  16. package/agents/issue-reviewer-scope.md +63 -0
  17. package/agents/issue-reviewer-spec.md +77 -0
  18. package/agents/java-expert.md +31 -0
  19. package/agents/jenkins-expert.md +38 -0
  20. package/agents/kubernetes-expert.md +40 -0
  21. package/agents/planner.md +42 -0
  22. package/agents/python-expert.md +61 -0
  23. package/agents/reviewer.md +26 -0
  24. package/agents/scout.md +40 -0
  25. package/agents/security-auditor.md +254 -0
  26. package/agents/technical-documentation-writer.md +37 -0
  27. package/agents/test-automator.md +55 -0
  28. package/agents/test-runner.md +47 -0
  29. package/agents/ts-expert.md +23 -0
  30. package/agents/worker.md +30 -0
  31. package/extensions/acpx-provider/index.ts +104 -0
  32. package/extensions/acpx-provider/load-runtime.ts +99 -0
  33. package/extensions/acpx-provider/runtime-models.ts +40 -0
  34. package/extensions/cli-provider/agents/claude.ts +128 -0
  35. package/extensions/cli-provider/agents/cursor.ts +84 -0
  36. package/extensions/cli-provider/agents/gemini.ts +100 -0
  37. package/extensions/cli-provider/discover.ts +77 -0
  38. package/extensions/cli-provider/index.ts +57 -0
  39. package/extensions/cli-provider/parsers.ts +304 -0
  40. package/extensions/cli-provider/providers.ts +58 -0
  41. package/extensions/cli-provider/runner.ts +225 -0
  42. package/extensions/cli-provider/runtime-models.ts +32 -0
  43. package/extensions/cli-provider/session-reaper.ts +122 -0
  44. package/extensions/cli-provider/sessions.ts +533 -0
  45. package/extensions/cli-provider/shared/discover-cache.ts +235 -0
  46. package/extensions/cli-provider/types.ts +48 -0
  47. package/extensions/coms/coms-net-server.ts +1642 -0
  48. package/extensions/coms/coms-net-wrapper.ts +521 -0
  49. package/extensions/coms/coms-net.ts +1589 -0
  50. package/extensions/coms/coms-p2p.ts +1879 -0
  51. package/extensions/coms/coms-shared.ts +510 -0
  52. package/extensions/coms/coms-wrapper.ts +138 -0
  53. package/extensions/coms/index.ts +20 -0
  54. package/extensions/coms/themeMap.ts +147 -0
  55. package/extensions/image-gen/image-gen.ts +332 -0
  56. package/extensions/image-gen/index.ts +14 -0
  57. package/extensions/orchestrator/agents.ts +134 -0
  58. package/extensions/orchestrator/ask-user.ts +293 -0
  59. package/extensions/orchestrator/async-agents.ts +1037 -0
  60. package/extensions/orchestrator/async-capability.ts +129 -0
  61. package/extensions/orchestrator/async-runner.ts +324 -0
  62. package/extensions/orchestrator/async-status-parse.ts +31 -0
  63. package/extensions/orchestrator/async-status-ui.ts +201 -0
  64. package/extensions/orchestrator/async-wait.ts +36 -0
  65. package/extensions/orchestrator/btw.ts +210 -0
  66. package/extensions/orchestrator/cron-status-format.ts +126 -0
  67. package/extensions/orchestrator/cron-status-ui.ts +132 -0
  68. package/extensions/orchestrator/cron.ts +730 -0
  69. package/extensions/orchestrator/dreaming.ts +355 -0
  70. package/extensions/orchestrator/enforcement-helpers.ts +530 -0
  71. package/extensions/orchestrator/enforcement-rules.ts +329 -0
  72. package/extensions/orchestrator/enforcement.ts +828 -0
  73. package/extensions/orchestrator/extended-autocomplete.ts +593 -0
  74. package/extensions/orchestrator/git-helpers.ts +420 -0
  75. package/extensions/orchestrator/github-autocomplete.ts +250 -0
  76. package/extensions/orchestrator/icons.ts +17 -0
  77. package/extensions/orchestrator/index.ts +100 -0
  78. package/extensions/orchestrator/memory-embeddings.ts +281 -0
  79. package/extensions/orchestrator/memory-promotion.ts +449 -0
  80. package/extensions/orchestrator/memory-provenance.ts +80 -0
  81. package/extensions/orchestrator/memory-query-class.ts +90 -0
  82. package/extensions/orchestrator/memory-scoring.ts +434 -0
  83. package/extensions/orchestrator/memory-tools.ts +883 -0
  84. package/extensions/orchestrator/memory-tree.ts +212 -0
  85. package/extensions/orchestrator/nvim.ts +169 -0
  86. package/extensions/orchestrator/overlay-dashboard-utils.ts +25 -0
  87. package/extensions/orchestrator/overlay-dashboard.ts +512 -0
  88. package/extensions/orchestrator/pi-config-review-state.ts +303 -0
  89. package/extensions/orchestrator/preference-extractor.ts +106 -0
  90. package/extensions/orchestrator/project-settings.ts +468 -0
  91. package/extensions/orchestrator/promotion-queue.ts +311 -0
  92. package/extensions/orchestrator/resolve-agent-model.ts +32 -0
  93. package/extensions/orchestrator/review-ui.ts +204 -0
  94. package/extensions/orchestrator/rule-placeholders.ts +12 -0
  95. package/extensions/orchestrator/rules.ts +481 -0
  96. package/extensions/orchestrator/session-search.ts +243 -0
  97. package/extensions/orchestrator/session-validation.ts +374 -0
  98. package/extensions/orchestrator/situation-report.ts +370 -0
  99. package/extensions/orchestrator/status-bar.ts +31 -0
  100. package/extensions/orchestrator/status-line.ts +192 -0
  101. package/extensions/orchestrator/status.ts +110 -0
  102. package/extensions/orchestrator/subagent-tool.ts +1748 -0
  103. package/extensions/orchestrator/task-lifecycle.ts +88 -0
  104. package/extensions/orchestrator/utils.ts +227 -0
  105. package/extensions/pidash/index.ts +15 -0
  106. package/extensions/pidash/pidash.ts +941 -0
  107. package/extensions/pidiff/index.ts +13 -0
  108. package/extensions/pidiff/pidiff.ts +369 -0
  109. package/extensions/providers/acpx-driver.ts +479 -0
  110. package/extensions/providers/built-in-drivers.ts +52 -0
  111. package/extensions/providers/claude-driver.ts +319 -0
  112. package/extensions/providers/cursor-acpx-driver.ts +398 -0
  113. package/extensions/providers/cursor-cli-driver.ts +484 -0
  114. package/extensions/providers/gemini-driver.ts +302 -0
  115. package/extensions/providers/index.ts +513 -0
  116. package/extensions/shared/build-system-prompt.ts +57 -0
  117. package/extensions/shared/create-runtime-provider.ts +190 -0
  118. package/extensions/shared/daemon-manager.ts +248 -0
  119. package/extensions/shared/file-logger.ts +115 -0
  120. package/extensions/shared/managed-refresh.ts +211 -0
  121. package/extensions/shared/provider-driver.ts +295 -0
  122. package/extensions/shared/provider-errors.ts +305 -0
  123. package/extensions/shared/provider-registry.ts +388 -0
  124. package/extensions/shared/stream-builder.ts +275 -0
  125. package/extensions/shared/types.ts +20 -0
  126. package/extensions/shared/ui/README.md +10 -0
  127. package/extensions/shared/ui/badge.tsx +52 -0
  128. package/extensions/shared/ui/button.tsx +58 -0
  129. package/extensions/shared/ui/collapsible.tsx +21 -0
  130. package/extensions/shared/ui/dropdown-menu.tsx +266 -0
  131. package/extensions/shared/ui/input.tsx +20 -0
  132. package/extensions/shared/ui/popover.tsx +114 -0
  133. package/extensions/shared/ui/resizable.tsx +48 -0
  134. package/extensions/shared/ui/scroll-area.tsx +53 -0
  135. package/extensions/shared/ui/select.tsx +201 -0
  136. package/extensions/shared/ui/separator.tsx +25 -0
  137. package/extensions/shared/ui/tooltip.tsx +64 -0
  138. package/extensions/shared/ws-client.ts +74 -0
  139. package/package.json +59 -0
  140. package/prompts/coderabbit-rate-limit.md +95 -0
  141. package/prompts/create-coms-feature-manager.md +186 -0
  142. package/prompts/create-skill.md +128 -0
  143. package/prompts/domain-model.md +109 -0
  144. package/prompts/external-ai.md +665 -0
  145. package/prompts/implement-and-review.md +25 -0
  146. package/prompts/implement.md +26 -0
  147. package/prompts/issue-review.md +256 -0
  148. package/prompts/pr-review.md +753 -0
  149. package/prompts/query-db.md +154 -0
  150. package/prompts/refine-review.md +208 -0
  151. package/prompts/release.md +235 -0
  152. package/prompts/remember.md +33 -0
  153. package/prompts/review-handler-status.md +27 -0
  154. package/prompts/review-handler.md +677 -0
  155. package/prompts/review-local.md +159 -0
  156. package/prompts/scout-and-plan.md +21 -0
  157. package/rules/00-orchestrator-core.md +42 -0
  158. package/rules/05-issue-first-workflow.md +119 -0
  159. package/rules/10-agent-routing.md +58 -0
  160. package/rules/15-mcp-launchpad.md +46 -0
  161. package/rules/20-code-review-loop.md +234 -0
  162. package/rules/25-documentation-updates.md +15 -0
  163. package/rules/30-prompt-templates.md +19 -0
  164. package/rules/35-memory.md +240 -0
  165. package/rules/40-critical-rules.md +124 -0
  166. package/rules/45-file-preview.md +29 -0
  167. package/rules/50-agent-bug-reporting.md +90 -0
  168. package/rules/55-coms-protocol.md +63 -0
  169. package/rules/60-task-tracking.md +66 -0
  170. package/skills/conflict-resolver/SKILL.md +213 -0
  171. package/skills/skill-creator/SKILL.md +85 -0
  172. package/skills/systematic-debugging/SKILL.md +353 -0
  173. package/skills/test-driven-development/SKILL.md +335 -0
  174. package/skills/update-agents-md/SKILL.md +282 -0
  175. package/templates/coms-feature-manager-prompt.md +313 -0
@@ -0,0 +1,293 @@
1
+ /**
2
+ * ask_user tool — presents questions to the user with selectable options.
3
+ */
4
+
5
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
6
+ import {
7
+ Container,
8
+ Input,
9
+ type SelectItem,
10
+ SelectList,
11
+ Spacer,
12
+ Text,
13
+ fuzzyFilter,
14
+ } from "@earendil-works/pi-tui";
15
+ import { DynamicBorder } from "@earendil-works/pi-coding-agent";
16
+ import { Type } from "typebox";
17
+
18
+ export function registerAskUser(
19
+ pi: ExtensionAPI,
20
+ terminalNotify: (title: string, body: string) => void,
21
+ ): void {
22
+ pi.registerTool({
23
+ name: "ask_user",
24
+ label: "Ask User",
25
+ description:
26
+ "Present a question to the user with selectable options. Returns the user's choice or free-text input. Use this whenever a workflow needs user input — never ask via plain text.",
27
+ promptSnippet: "Ask the user a question with selectable options",
28
+ promptGuidelines: [
29
+ "Use ask_user when you need user input during a workflow (approvals, selections, confirmations).",
30
+ "Do NOT ask users questions via plain text — always use this tool for structured choices.",
31
+ "Provide clear, concise options. Include a 'no' or 'cancel' option when appropriate.",
32
+ ],
33
+ parameters: Type.Object({
34
+ question: Type.String({
35
+ description: "The question to display to the user",
36
+ }),
37
+ options: Type.Optional(
38
+ Type.Array(Type.String(), {
39
+ description:
40
+ "List of selectable options. If omitted, only free-text input is shown.",
41
+ }),
42
+ ),
43
+ }),
44
+
45
+ async execute(_id, params, _signal, _onUpdate, ctx) {
46
+ if (!ctx.hasUI) {
47
+ return {
48
+ content: [
49
+ { type: "text", text: "No UI available for user interaction" },
50
+ ],
51
+ isError: true,
52
+ };
53
+ }
54
+
55
+ terminalNotify("pi", "Action required");
56
+
57
+ // Emit ask request for pidash browser clients
58
+ const askId = `ask-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
59
+ pi.events.emit("pidash:ui-request", {
60
+ id: askId,
61
+ type: "extension_ui_request",
62
+ method: params.options?.length ? "select" : "input",
63
+ title: params.question,
64
+ options: params.options,
65
+ });
66
+
67
+ // Track if resolved (from TUI or browser)
68
+ let externalDone: ((value: string | null) => void) | null = null;
69
+
70
+ // Listen for browser response
71
+ const unsubscribe = pi.events.on("pidash:ui-response", (data: unknown) => {
72
+ const resp = data as any;
73
+ if (resp.id === askId && externalDone) {
74
+ if (resp.cancelled) externalDone(null);
75
+ else if (resp.value) externalDone(resp.value);
76
+ else if (resp.confirmed !== undefined) externalDone(resp.confirmed ? "Yes" : "No");
77
+ }
78
+ });
79
+
80
+ const result = await ctx.ui.custom<string | null>(
81
+ (tui, theme, _kb, done) => {
82
+ // Allow browser to resolve this dialog
83
+ externalDone = done;
84
+
85
+ let mode: "select" | "input" = params.options?.length
86
+ ? "select"
87
+ : "input";
88
+ let resolved = false;
89
+
90
+ const resolve = (value: string | null) => {
91
+ if (resolved) return;
92
+ resolved = true;
93
+ externalDone = null;
94
+ // Dismiss browser dialog if TUI answered
95
+ pi.events.emit("pidash:ui-dismiss", { type: "ui-dismiss", id: askId });
96
+ done(value);
97
+ };
98
+
99
+ // Override externalDone to use resolve (prevents double-resolve)
100
+ externalDone = resolve;
101
+
102
+ // Free-text input with built-in callbacks
103
+ const input = new Input();
104
+ input.onSubmit = (value: string) => {
105
+ const text = value.trim();
106
+ if (text) resolve(text);
107
+ };
108
+ input.onEscape = () => {
109
+ if (selectList) {
110
+ mode = "select";
111
+ tui.requestRender();
112
+ } else {
113
+ resolve(null);
114
+ }
115
+ };
116
+
117
+ const inputLabel = new Text(
118
+ theme.fg("dim", "Type your response • enter submit • esc back"),
119
+ 1,
120
+ 0,
121
+ );
122
+
123
+ // SelectList (only if options provided)
124
+ let selectList: SelectList | null = null;
125
+ let allItems: SelectItem[] = [];
126
+ const selectTheme = {
127
+ selectedPrefix: (t: string) => theme.fg("accent", t),
128
+ selectedText: (t: string) => theme.fg("accent", t),
129
+ description: (t: string) => theme.fg("muted", t),
130
+ scrollInfo: (t: string) => theme.fg("dim", t),
131
+ noMatch: (t: string) => theme.fg("warning", t),
132
+ };
133
+
134
+ const makeSelectList = (items: SelectItem[]) => {
135
+ const sl = new SelectList(items, Math.min(items.length + 1, 15), selectTheme);
136
+ sl.onSelect = (item: SelectItem) => {
137
+ if (item.value === "__no_match__") {
138
+ // Ignore — not a real option
139
+ } else if (item.value === "__free_input__") {
140
+ mode = "input";
141
+ searchInput.setValue("");
142
+ tui.requestRender();
143
+ } else {
144
+ resolve(item.value);
145
+ }
146
+ };
147
+ sl.onCancel = () => resolve(null);
148
+ return sl;
149
+ };
150
+
151
+ if (params.options && params.options.length > 0) {
152
+ allItems = [
153
+ ...params.options.map((opt: string) => ({
154
+ value: opt,
155
+ label: opt,
156
+ })),
157
+ {
158
+ value: "__free_input__",
159
+ label: "✎ Other (type custom answer)",
160
+ description: "free-text",
161
+ },
162
+ ];
163
+ selectList = makeSelectList(allItems);
164
+ }
165
+
166
+ // Search input for fuzzy filtering the select list
167
+ const searchInput = new Input();
168
+ searchInput.onSubmit = () => {
169
+ if (selectList) {
170
+ const selected = selectList.getSelectedItem();
171
+ if (selected) {
172
+ if (selected.value === "__no_match__") {
173
+ // Ignore
174
+ } else if (selected.value === "__free_input__") {
175
+ mode = "input";
176
+ searchInput.setValue("");
177
+ } else {
178
+ resolve(selected.value);
179
+ }
180
+ }
181
+ }
182
+ };
183
+ searchInput.onEscape = () => resolve(null);
184
+
185
+ const selectHelp = new Text(
186
+ theme.fg("dim", "type to filter • ↑↓ navigate • enter select • esc cancel"),
187
+ 1,
188
+ 0,
189
+ );
190
+ const topBorder = new DynamicBorder((s: string) =>
191
+ theme.fg("accent", s),
192
+ );
193
+ const bottomBorder = new DynamicBorder((s: string) =>
194
+ theme.fg("accent", s),
195
+ );
196
+
197
+ // Build container — question is already in the main chat,
198
+ // overlay shows only the selectable options / input
199
+ const buildContainer = () => {
200
+ const c = new Container();
201
+ c.addChild(topBorder);
202
+ if (mode === "select" && selectList) {
203
+ c.addChild(searchInput);
204
+ c.addChild(selectList);
205
+ c.addChild(selectHelp);
206
+ } else {
207
+ c.addChild(input);
208
+ c.addChild(inputLabel);
209
+ }
210
+ c.addChild(bottomBorder);
211
+ return c;
212
+ };
213
+
214
+ let container = buildContainer();
215
+
216
+ let _focused = false;
217
+
218
+ return {
219
+ // Focusable interface — propagate to active Input for IME cursor positioning
220
+ set focused(value: boolean) {
221
+ _focused = value;
222
+ input.focused = value;
223
+ searchInput.focused = value;
224
+ },
225
+ get focused(): boolean {
226
+ return _focused;
227
+ },
228
+
229
+ render: (w: number) => {
230
+ container = buildContainer();
231
+ return container.render(w);
232
+ },
233
+ invalidate: () => container.invalidate(),
234
+ handleInput: (data: string) => {
235
+ if (resolved) return;
236
+ if (mode === "select" && selectList) {
237
+ // Arrow keys and enter/escape go to selectList
238
+ // Printable chars go to searchInput for filtering
239
+ const isNavKey = data === "\x1b[A" || data === "\x1b[B" // up/down
240
+ || data === "\r" || data === "\n" // enter
241
+ || data === "\x1b" // escape
242
+ || data === "\x1b[5~" || data === "\x1b[6~"; // page up/down
243
+ if (isNavKey) {
244
+ selectList.handleInput(data);
245
+ } else {
246
+ searchInput.handleInput(data);
247
+ const query = searchInput.getValue();
248
+ if (query) {
249
+ const filtered = fuzzyFilter(allItems, query, (item) => `${item.label} ${item.description || ""}`);
250
+ selectList = makeSelectList(filtered.length > 0 ? filtered : [{ value: "__no_match__", label: "No matches", description: "clear search to see all" }]);
251
+ } else {
252
+ selectList = makeSelectList(allItems);
253
+ }
254
+ }
255
+ } else {
256
+ input.handleInput(data);
257
+ }
258
+ tui.requestRender();
259
+ },
260
+ };
261
+ },
262
+
263
+ );
264
+
265
+ unsubscribe();
266
+
267
+ if (result === null) {
268
+ return { content: [{ type: "text", text: "User cancelled" }], terminate: true };
269
+ }
270
+ return { content: [{ type: "text", text: result }] };
271
+ },
272
+
273
+ renderCall(args, theme) {
274
+ let t =
275
+ theme.fg("toolTitle", theme.bold("ask_user ")) +
276
+ theme.fg("accent", args.question || "...");
277
+ if (args.options?.length > 0) {
278
+ t += `\n ${theme.fg("dim", args.options.join(" • "))}`;
279
+ }
280
+ return new Text(t, 0, 0);
281
+ },
282
+
283
+ renderResult(result, _options, theme) {
284
+ const text = result.content[0];
285
+ const value = text?.type === "text" ? text.text : "(no response)";
286
+ const icon =
287
+ value === "User cancelled"
288
+ ? theme.fg("warning", "✗")
289
+ : theme.fg("success", "✓");
290
+ return new Text(`${icon} ${theme.fg("toolOutput", value)}`, 0, 0);
291
+ },
292
+ });
293
+ }