gentle-pi 2.4.0 → 2.5.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 (116) hide show
  1. package/README.md +170 -12
  2. package/assets/agents/gentle-ai-worker.md +9 -0
  3. package/assets/orchestrator-delegation.md +19 -9
  4. package/assets/orchestrator.md +5 -5
  5. package/docs/delegated-verification.md +25 -0
  6. package/docs/telemetry.md +38 -0
  7. package/extensions/ask-user-choice.ts +26 -20
  8. package/extensions/codegraph-tools.ts +94 -5
  9. package/extensions/gentle-agents.ts +588 -0
  10. package/extensions/gentle-ai.ts +898 -79
  11. package/extensions/gentle-shell.ts +547 -0
  12. package/extensions/gentle-todo.ts +199 -0
  13. package/extensions/quiet-tools.ts +1 -1
  14. package/lib/agents-config.ts +318 -0
  15. package/lib/agents-history.ts +80 -0
  16. package/lib/agents-protocol.ts +429 -0
  17. package/lib/agents-runner.ts +490 -0
  18. package/lib/agents-transcript.ts +87 -0
  19. package/lib/agents-view.ts +557 -0
  20. package/lib/agents-widget.ts +222 -0
  21. package/lib/gentle-ai-renderer.ts +142 -26
  22. package/lib/native-choice-list.ts +194 -0
  23. package/lib/native-fullscreen-interaction.ts +47 -0
  24. package/lib/native-pointer-region.ts +164 -0
  25. package/lib/native-review-cli.ts +88 -12
  26. package/lib/review-candidate-view-owner.ts +177 -0
  27. package/lib/review-candidate-view.ts +127 -35
  28. package/lib/review-consent-ui.ts +65 -0
  29. package/lib/review-integration-v2.ts +58 -8
  30. package/lib/review-last-event-controller.ts +1 -0
  31. package/lib/review-relay-contract.ts +11 -0
  32. package/lib/review-repository.ts +2 -2
  33. package/lib/review-risk-assessment.ts +339 -0
  34. package/lib/review-session-standing-permission-ipc.ts +309 -0
  35. package/lib/review-session-standing-permission.ts +219 -0
  36. package/lib/shell-bar.ts +138 -0
  37. package/lib/shell-card.ts +136 -0
  38. package/lib/shell-changes-view.ts +205 -0
  39. package/lib/shell-changes.ts +210 -0
  40. package/lib/shell-gauge.ts +40 -0
  41. package/lib/shell-prompt.ts +119 -0
  42. package/lib/shell-todo.ts +280 -0
  43. package/lib/shell-usage-view.ts +76 -0
  44. package/lib/shell-usage.ts +246 -0
  45. package/lib/telemetry-trigger.ts +151 -0
  46. package/package.json +4 -4
  47. package/runtime/native-review-cli.mjs +87 -11
  48. package/runtime/review-integration-v2.mjs +58 -8
  49. package/runtime/review-relay-contract.mjs +11 -0
  50. package/runtime/review-risk-assessment.mjs +340 -0
  51. package/runtime/telemetry-trigger.mjs +152 -0
  52. package/scripts/build-runtime-modules.mjs +2 -0
  53. package/scripts/gentle-ai-installer.mjs +10 -10
  54. package/scripts/test-packed-runner.mjs +22 -0
  55. package/scripts/verify-package-files.mjs +6 -2
  56. package/skills/_shared/review-ledger-contract.md +3 -1
  57. package/tests/agents-config.test.ts +143 -0
  58. package/tests/agents-fake-child.ts +52 -0
  59. package/tests/agents-history.test.ts +54 -0
  60. package/tests/agents-protocol.test.ts +153 -0
  61. package/tests/agents-runner-process.test.ts +111 -0
  62. package/tests/agents-runner.test.ts +402 -0
  63. package/tests/agents-transcript.test.ts +30 -0
  64. package/tests/agents-view.test.ts +274 -0
  65. package/tests/agents-widget.test.ts +111 -0
  66. package/tests/ask-user-choice.test.ts +157 -3
  67. package/tests/codegraph-tools.test.ts +110 -1
  68. package/tests/devbinary/native-review-parity.devtest.ts +108 -0
  69. package/tests/fixtures/agents-process-child.mjs +23 -0
  70. package/tests/gentle-agents.test.ts +741 -0
  71. package/tests/gentle-ai-binary.test.ts +1 -1
  72. package/tests/gentle-ai-installer.test.ts +47 -47
  73. package/tests/gentle-ai-renderer.test.ts +65 -0
  74. package/tests/gentle-ai.test.ts +28 -12
  75. package/tests/gentle-card-text.ts +35 -0
  76. package/tests/gentle-shell.test.ts +527 -0
  77. package/tests/gentle-todo.test.ts +182 -0
  78. package/tests/native-choice-list.test.ts +202 -0
  79. package/tests/native-fullscreen-interaction.test.ts +125 -0
  80. package/tests/native-pointer-region.test.ts +245 -0
  81. package/tests/native-review-capability-contract.test.ts +16 -1
  82. package/tests/native-review-cli.test.ts +40 -0
  83. package/tests/native-review-consent.test.ts +91 -0
  84. package/tests/native-review-parity-runtime.test.ts +8 -2
  85. package/tests/native-review-parity.test.ts +29 -22
  86. package/tests/orchestrator-budget.test.ts +69 -0
  87. package/tests/orchestrator-rdd-ownership.test.ts +9 -0
  88. package/tests/package-manifest.test.ts +17 -6
  89. package/tests/quiet-tool-rendering.test.ts +96 -37
  90. package/tests/rdd-aware-verification-contract.test.ts +216 -0
  91. package/tests/rdd-status-line.test.ts +286 -0
  92. package/tests/review-candidate-view.test.ts +452 -6
  93. package/tests/review-contract-prompt.test.ts +3 -0
  94. package/tests/review-controller-native-recovery.test.ts +29 -4
  95. package/tests/review-controller-native-routing.test.ts +321 -4
  96. package/tests/review-controller-workspace-root.test.ts +45 -2
  97. package/tests/review-controller.test.ts +25 -0
  98. package/tests/review-host-relay-routing.test.ts +20 -4
  99. package/tests/review-integration-v2.test.ts +112 -0
  100. package/tests/review-last-event-closure.test.ts +7 -2
  101. package/tests/review-relay-contract.test.ts +26 -0
  102. package/tests/review-repository.test.ts +28 -1
  103. package/tests/review-risk-assessment.test.ts +626 -0
  104. package/tests/review-session-standing-permission-controller.test.ts +608 -0
  105. package/tests/review-session-standing-permission-ipc.test.ts +233 -0
  106. package/tests/review-session-standing-permission-runtime.test.ts +212 -0
  107. package/tests/review-session-standing-permission.test.ts +126 -0
  108. package/tests/shell-bar.test.ts +176 -0
  109. package/tests/shell-card.test.ts +118 -0
  110. package/tests/shell-changes-view.test.ts +146 -0
  111. package/tests/shell-changes.test.ts +182 -0
  112. package/tests/shell-prompt.test.ts +118 -0
  113. package/tests/shell-todo.test.ts +170 -0
  114. package/tests/shell-usage-view.test.ts +62 -0
  115. package/tests/shell-usage.test.ts +197 -0
  116. package/tests/telemetry-trigger.test.ts +349 -0
@@ -1,7 +1,7 @@
1
1
  import { execFile, execFileSync } from "node:child_process";
2
- import { lstatSync, realpathSync } from "node:fs";
2
+ import { existsSync, lstatSync, readFileSync, realpathSync, statSync } from "node:fs";
3
3
  import { homedir, tmpdir } from "node:os";
4
- import { join } from "node:path";
4
+ import { dirname, join } from "node:path";
5
5
  import { promisify } from "node:util";
6
6
  import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
7
7
 
@@ -177,13 +177,102 @@ function codeGraphFailureMessage(status: CodeGraphStatus): string {
177
177
  : `CodeGraph failed to run. ${FALLBACK_INSTRUCTIONS}`;
178
178
  }
179
179
 
180
+ function isEnoent(error: unknown): boolean {
181
+ return (
182
+ typeof error === "object" &&
183
+ error !== null &&
184
+ "code" in error &&
185
+ (error as { code?: unknown }).code === "ENOENT"
186
+ );
187
+ }
188
+
189
+ /** Find `codegraph.cmd` shims in Windows PATH order. */
190
+ function* codeGraphCmdPathsOnPath(): Iterable<string> {
191
+ const pathEnv = process.env.Path ?? process.env.PATH ?? "";
192
+ for (const entry of pathEnv.split(";")) {
193
+ const dir = entry.length >= 2 && entry.startsWith('"') && entry.endsWith('"')
194
+ ? entry.slice(1, -1)
195
+ : entry;
196
+ if (!dir) continue;
197
+ const candidate = join(dir, "codegraph.cmd");
198
+ if (existsSync(candidate)) yield candidate;
199
+ }
200
+ }
201
+
202
+ /**
203
+ * Resolve the actual JS entry of the `@colbymchenry/codegraph` package from the
204
+ * npm global bin dir (sibling of the `codegraph.cmd` shim) and run it with the
205
+ * current Node executable. No shell involvement, so args are never interpreted.
206
+ */
207
+ export function codeGraphNodeScript(cmdPath: string): string | undefined {
208
+ const binDir = dirname(cmdPath);
209
+ const pkgRoot = join(binDir, "node_modules", "@colbymchenry", "codegraph");
210
+ const pkgJsonPath = join(pkgRoot, "package.json");
211
+ if (!existsSync(pkgJsonPath)) return undefined;
212
+ try {
213
+ const pkg = JSON.parse(readFileSync(pkgJsonPath, "utf8")) as { bin?: unknown };
214
+ const bin = pkg.bin;
215
+ const target =
216
+ typeof bin === "string"
217
+ ? bin
218
+ : bin &&
219
+ typeof bin === "object" &&
220
+ "codegraph" in bin &&
221
+ typeof (bin as Record<string, unknown>).codegraph === "string"
222
+ ? (bin as Record<string, string>).codegraph
223
+ : undefined;
224
+ if (typeof target !== "string" || !target) return undefined;
225
+ const script = join(pkgRoot, target);
226
+ return statSync(script).isFile() ? script : undefined;
227
+ } catch {
228
+ return undefined;
229
+ }
230
+ }
231
+
232
+ function* codeGraphNodeScriptsOnPath(): Iterable<string> {
233
+ for (const cmdPath of codeGraphCmdPathsOnPath()) {
234
+ const script = codeGraphNodeScript(cmdPath);
235
+ if (script) yield script;
236
+ }
237
+ }
238
+
239
+ /** Resolve the first valid CodeGraph npm entry point in Windows PATH order. */
240
+ export function findCodeGraphNodeScriptOnPath(): string | undefined {
241
+ return codeGraphNodeScriptsOnPath().next().value;
242
+ }
243
+
180
244
  const runCodeGraphCommand: CodeGraphRunner = async (args, options) => {
181
- const result = await execFileAsync("codegraph", [...args], {
245
+ const runOptions = {
182
246
  cwd: options.cwd,
183
247
  signal: options.signal,
184
248
  maxBuffer: options.maxBuffer,
185
- });
186
- return { stdout: result.stdout, stderr: result.stderr };
249
+ };
250
+ let unavailableError: unknown;
251
+
252
+ try {
253
+ const result = await execFileAsync("codegraph", [...args], runOptions);
254
+ return { stdout: result.stdout, stderr: result.stderr };
255
+ } catch (error) {
256
+ // Windows npm installs only shims (codegraph.cmd/.ps1 and a shell script)
257
+ // with no codegraph.exe, so plain execFile (CreateProcess, no shell)
258
+ // always fails with ENOENT even when the shim is on PATH.
259
+ if (process.platform !== "win32" || !isEnoent(error)) throw error;
260
+ unavailableError = error;
261
+ }
262
+
263
+ // Resolve the real package script from each npm global bin directory in PATH
264
+ // order and run it through the current Node executable. This remains
265
+ // shell-free, so argument boundaries are never interpreted by a shell.
266
+ for (const script of codeGraphNodeScriptsOnPath()) {
267
+ try {
268
+ const result = await execFileAsync(process.execPath, [script, ...args], runOptions);
269
+ return { stdout: result.stdout, stderr: result.stderr };
270
+ } catch (innerError) {
271
+ if (!isEnoent(innerError)) throw innerError;
272
+ }
273
+ }
274
+
275
+ throw unavailableError;
187
276
  };
188
277
 
189
278
  export function createCodeGraphTool(runner: CodeGraphRunner = runCodeGraphCommand) {