gentle-pi 3.2.1 → 3.3.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 (71) hide show
  1. package/docs/gentle-shell.md +27 -14
  2. package/docs/readme-reference.md +41 -7
  3. package/docs/review-integration.md +22 -17
  4. package/extensions/gentle-agents.ts +85 -17
  5. package/extensions/gentle-ai.ts +123 -21
  6. package/extensions/gentle-shell.ts +379 -31
  7. package/extensions/gentle-todo.ts +19 -1
  8. package/lib/agents-view.ts +41 -14
  9. package/lib/agents-widget.ts +84 -13
  10. package/lib/command-palette-catalog.ts +1 -0
  11. package/lib/double-esc-cancel-policy.ts +138 -0
  12. package/lib/inprocess-reviewer.ts +260 -0
  13. package/lib/native-review-cli.ts +14 -0
  14. package/lib/odd-runtime-delegation-gate.ts +88 -0
  15. package/lib/review-host-relay.ts +246 -171
  16. package/lib/review-integration-v2.ts +110 -26
  17. package/lib/shell-bar.ts +150 -75
  18. package/lib/shell-card.ts +19 -9
  19. package/lib/shell-changes-view.ts +43 -5
  20. package/lib/shell-changes.ts +92 -5
  21. package/lib/shell-hover.ts +39 -0
  22. package/lib/shell-prompt.ts +10 -1
  23. package/lib/shell-sidebar-layout.ts +111 -15
  24. package/lib/shell-sidebar.ts +16 -0
  25. package/lib/shell-todo.ts +7 -1
  26. package/lib/shell-usage-view.ts +98 -10
  27. package/package.json +1 -1
  28. package/runtime/native-review-cli.mjs +14 -0
  29. package/runtime/review-integration-v2.mjs +110 -26
  30. package/scripts/gentle-ai-installer.mjs +10 -10
  31. package/scripts/maintainer/provider-relay-matrix.mjs +118 -47
  32. package/scripts/verify-package-files.mjs +3 -3
  33. package/tests/agents-grouping.test.ts +75 -18
  34. package/tests/agents-view.test.ts +28 -18
  35. package/tests/agents-widget.test.ts +100 -12
  36. package/tests/command-palette.test.ts +1 -0
  37. package/tests/devbinary/pi-host-relay.devtest.ts +176 -138
  38. package/tests/double-esc-cancel-policy.test.ts +194 -0
  39. package/tests/gentle-agents.test.ts +528 -5
  40. package/tests/gentle-ai-binary.test.ts +1 -1
  41. package/tests/gentle-ai-installer.test.ts +47 -47
  42. package/tests/gentle-ai.test.ts +69 -5
  43. package/tests/gentle-shell.test.ts +795 -23
  44. package/tests/gentle-todo.test.ts +17 -4
  45. package/tests/inprocess-reviewer.test.ts +368 -0
  46. package/tests/maintainer/provider-relay.maintest.ts +101 -143
  47. package/tests/native-review-capability-contract.test.ts +19 -1
  48. package/tests/odd-runtime-delegation-gate.test.ts +212 -0
  49. package/tests/orchestrator-rdd-ownership.test.ts +3 -3
  50. package/tests/package-manifest.test.ts +6 -6
  51. package/tests/review-host-relay-routing.test.ts +77 -0
  52. package/tests/review-host-relay.test.ts +277 -300
  53. package/tests/review-integration-v2-forward.test.ts +61 -0
  54. package/tests/review-integration-v2.test.ts +116 -1
  55. package/tests/review-relay-transport-agent.test.ts +22 -24
  56. package/tests/runtime-harness.mjs +11 -0
  57. package/tests/session-changes-shell.test.ts +27 -0
  58. package/tests/session-worktree-registry.test.ts +41 -0
  59. package/tests/shell-bar.test.ts +192 -124
  60. package/tests/shell-card.test.ts +5 -3
  61. package/tests/shell-changes-view.test.ts +47 -0
  62. package/tests/shell-changes.test.ts +177 -0
  63. package/tests/shell-hover.test.ts +19 -0
  64. package/tests/shell-prompt.test.ts +20 -0
  65. package/tests/shell-sidebar-fullscreen.test.ts +59 -0
  66. package/tests/shell-sidebar-layout.test.ts +243 -5
  67. package/tests/shell-sidebar.test.ts +25 -1
  68. package/tests/shell-todo.test.ts +36 -0
  69. package/tests/shell-usage-view.test.ts +120 -1
  70. package/lib/opaque-pi-reviewer-adapter.ts +0 -404
  71. package/tests/opaque-pi-reviewer-adapter.test.ts +0 -410
@@ -155,6 +155,38 @@ function providerRefuterRequiredStatus(lineageId: string): ReviewStatusV3 {
155
155
  };
156
156
  }
157
157
 
158
+ // gentle-pi#311 P3: gentle-ai's v9 contract renders the refuter and
159
+ // targeted-validator role captures host-mediated, exactly like a lens
160
+ // materialize slot, instead of the self-contained --execute=true vector
161
+ // `providerRefuterRequiredStatus` above models.
162
+ function roleBindingArguments(lineageId: string, revision = SHA): ReviewCollectInputV3["arguments"] {
163
+ return [
164
+ { name: "lineage", value: lineageId, token: `--lineage=${lineageId}` },
165
+ { name: "expected-revision", value: revision, token: `--expected-revision=${revision}` },
166
+ { name: "target", value: SHA, token: `--target=${SHA}` },
167
+ { name: "repository-context", value: `rctx1_${"e".repeat(64)}`, token: `--repository-context=rctx1_${"e".repeat(64)}` },
168
+ ];
169
+ }
170
+
171
+ function hostMediatedRefuterCollectInput(lineageId: string, revision = SHA): ReviewCollectInputV3 {
172
+ const bindingTokens = roleBindingArguments(lineageId, revision).map((argument) => argument.token!);
173
+ return {
174
+ name: "provider_refuter",
175
+ schema: "https://gentle-ai.dev/schema/review/refuter/v1",
176
+ captureOperation: "review.capture-refuter",
177
+ arguments: [
178
+ ...roleBindingArguments(lineageId, revision),
179
+ { name: "agent", value: "pi", token: "--agent=pi" },
180
+ { name: "materialize", value: "true", token: "--materialize=true" },
181
+ ],
182
+ submission: {
183
+ operationToken: "capture-refuter",
184
+ argumentTokens: [...bindingTokens, "--agent=pi", "--input={{value}}"],
185
+ values: [{ slot: "provider_refuter", domain: "artifact_path_or_stdin", substitutionLocation: bindingTokens.length + 1 }],
186
+ },
187
+ };
188
+ }
189
+
158
190
  interface RoutingHarness {
159
191
  statusQueue: ReviewStatusV3[];
160
192
  statusCalls: Array<{ cwd: string; lineageId?: string; agent?: "pi" }>;
@@ -216,6 +248,51 @@ test("one materialize binding routes exactly one provider slot through the host
216
248
  assert.equal((result.host_relay as { transport: string }).transport, "pi_host_relay");
217
249
  });
218
250
 
251
+ // gentle-pi#311 P3: a v9 host-mediated refuter/targeted-validator slot reuses
252
+ // this exact relay machinery — the only role-specific part reachable from
253
+ // here is the fixed routing key it resolves through, since it carries no
254
+ // per-slot lens identity.
255
+ test("a v9 host-mediated refuter slot routes through the host relay with its fixed routing key", async (t) => {
256
+ t.after(() => __testing.setReviewHostRelayRunnerForTesting());
257
+ const cwd = repository(t);
258
+ const lineageId = "relay-role-lineage";
259
+ const input = hostMediatedRefuterCollectInput(lineageId);
260
+ const harness = nativeHarness([finalizeStatus(lineageId, [input])]);
261
+ const relayed: ReviewHostRelayRequest[] = [];
262
+ __testing.setReviewHostRelayRunnerForTesting(async (request: ReviewHostRelayRequest) => {
263
+ relayed.push(request);
264
+ return { promptByteLength: 64, resultByteLength: 32, submission: '{"admission_decision":"completed"}' };
265
+ });
266
+
267
+ const result = await runCapture(cwd, harness, lineageId);
268
+
269
+ assert.equal(relayed.length, 1);
270
+ assert.equal(relayed[0]!.routingKey, "review-refuter");
271
+ assert.deepEqual(relayed[0]!.captureArgumentTokens, input.arguments.map((argument) => argument.token));
272
+ assert.deepEqual(relayed[0]!.submission, input.submission);
273
+ assert.equal(harness.statusCalls.length, 1, "a nonterminal capture does not auto-follow STATUS");
274
+ assert.equal(result.status, "captured");
275
+ assert.equal((result.host_relay as { transport: string }).transport, "pi_host_relay");
276
+ });
277
+
278
+ // The reviewer selection is validated before any process launches (the same
279
+ // discipline a lens slot already has): a routing config with no
280
+ // review-refuter entry is refused typed, naming that exact key, never a
281
+ // mid-relay transport failure.
282
+ test("a missing review-refuter routing model is refused typed, naming the key, before any relay launch", async (t) => {
283
+ const cwd = repository(t);
284
+ const lineageId = "relay-role-missing-model";
285
+ const input = hostMediatedRefuterCollectInput(lineageId);
286
+ const harness = nativeHarness([finalizeStatus(lineageId, [input])]);
287
+
288
+ const result = await runCapture(cwd, harness, lineageId);
289
+
290
+ assert.equal(result.status, "blocked");
291
+ const failure = result.failure as { kind?: string } | undefined;
292
+ assert.equal(failure?.kind, "reviewer-config-invalid");
293
+ assert.match(String(result.reason), /review-refuter/);
294
+ });
295
+
219
296
  test("Pi-authored review documents are rejected at the capture input boundary", async (t) => {
220
297
  // The narrow capture schema rejects a caller-authored reviewer document
221
298
  // before any relay launch or native call.