gsd-pi 2.70.1-dev.3e19108 → 2.70.1-dev.ec24142

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 (77) hide show
  1. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +127 -30
  2. package/dist/resources/extensions/get-secrets-from-user.js +17 -1
  3. package/dist/web/standalone/.next/BUILD_ID +1 -1
  4. package/dist/web/standalone/.next/app-path-routes-manifest.json +12 -12
  5. package/dist/web/standalone/.next/build-manifest.json +2 -2
  6. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  7. package/dist/web/standalone/.next/required-server-files.json +1 -1
  8. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  9. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  10. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  11. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  12. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  13. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  14. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  15. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  16. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  17. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  18. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  19. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  20. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  21. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  22. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  23. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  24. package/dist/web/standalone/.next/server/app/index.html +1 -1
  25. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  26. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  27. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  28. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  29. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  30. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  31. package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
  32. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  33. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  34. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  35. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  36. package/dist/web/standalone/server.js +1 -1
  37. package/package.json +1 -1
  38. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +54 -0
  39. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  40. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +2 -0
  41. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  42. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  43. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-input.d.ts +1 -0
  44. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
  45. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-input.js +1 -0
  46. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-input.js.map +1 -1
  47. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  48. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +27 -7
  49. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  50. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +1 -1
  51. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  52. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +1 -1
  53. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
  54. package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts +1 -0
  55. package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  56. package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.js.map +1 -1
  57. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +68 -0
  58. package/packages/pi-coding-agent/src/core/extensions/types.ts +2 -0
  59. package/packages/pi-coding-agent/src/modes/interactive/components/extension-input.ts +2 -0
  60. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +32 -13
  61. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +1 -1
  62. package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +1 -1
  63. package/packages/pi-coding-agent/src/modes/rpc/rpc-types.ts +1 -0
  64. package/packages/pi-tui/dist/components/__tests__/input.test.js +9 -0
  65. package/packages/pi-tui/dist/components/__tests__/input.test.js.map +1 -1
  66. package/packages/pi-tui/dist/components/input.d.ts +2 -0
  67. package/packages/pi-tui/dist/components/input.d.ts.map +1 -1
  68. package/packages/pi-tui/dist/components/input.js +7 -4
  69. package/packages/pi-tui/dist/components/input.js.map +1 -1
  70. package/packages/pi-tui/src/components/__tests__/input.test.ts +11 -0
  71. package/packages/pi-tui/src/components/input.ts +7 -4
  72. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +164 -31
  73. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +112 -0
  74. package/src/resources/extensions/get-secrets-from-user.ts +24 -1
  75. package/src/resources/extensions/gsd/tests/secure-env-collect.test.ts +45 -0
  76. /package/dist/web/standalone/.next/static/{cHCEWiRJM5bXJa9HkP1QU → 20e8bFnNjxQJflHNodEve}/_buildManifest.js +0 -0
  77. /package/dist/web/standalone/.next/static/{cHCEWiRJM5bXJa9HkP1QU → 20e8bFnNjxQJflHNodEve}/_ssgManifest.js +0 -0
@@ -11,6 +11,7 @@ import {
11
11
  extractToolResultsFromSdkUserMessage,
12
12
  getClaudeLookupCommand,
13
13
  parseAskUserQuestionsElicitation,
14
+ parseTextInputElicitation,
14
15
  parseClaudeLookupOutput,
15
16
  roundResultToElicitationContent,
16
17
  } from "../stream-adapter.ts";
@@ -514,6 +515,117 @@ describe("stream-adapter — MCP elicitation bridge", () => {
514
515
  },
515
516
  });
516
517
  });
518
+
519
+ test("parseTextInputElicitation recognizes secure free-text MCP forms", () => {
520
+ const request = {
521
+ serverName: "gsd-workflow",
522
+ message: "Enter values for environment variables.",
523
+ mode: "form" as const,
524
+ requestedSchema: {
525
+ type: "object" as const,
526
+ properties: {
527
+ TEST_PASSWORD: {
528
+ type: "string",
529
+ title: "TEST_PASSWORD",
530
+ description: "Format: min 8 characters\nLeave empty to skip.",
531
+ },
532
+ PROJECT_NAME: {
533
+ type: "string",
534
+ title: "PROJECT_NAME",
535
+ description: "Human-readable project name.",
536
+ },
537
+ },
538
+ },
539
+ };
540
+
541
+ const parsed = parseTextInputElicitation(request as any);
542
+ assert.deepEqual(parsed, [
543
+ {
544
+ id: "TEST_PASSWORD",
545
+ title: "TEST_PASSWORD",
546
+ description: "Format: min 8 characters\nLeave empty to skip.",
547
+ required: false,
548
+ secure: true,
549
+ },
550
+ {
551
+ id: "PROJECT_NAME",
552
+ title: "PROJECT_NAME",
553
+ description: "Human-readable project name.",
554
+ required: false,
555
+ secure: false,
556
+ },
557
+ ]);
558
+ });
559
+
560
+ test("parseTextInputElicitation accepts legacy keys schema and skips unsupported fields", () => {
561
+ const request = {
562
+ serverName: "gsd-workflow",
563
+ message: "Enter secure values",
564
+ mode: "form" as const,
565
+ requestedSchema: {
566
+ type: "object" as const,
567
+ keys: {
568
+ API_TOKEN: {
569
+ type: "string",
570
+ title: "API_TOKEN",
571
+ description: "Leave empty to skip.",
572
+ },
573
+ META: {
574
+ type: "object",
575
+ title: "metadata",
576
+ },
577
+ },
578
+ },
579
+ };
580
+
581
+ const parsed = parseTextInputElicitation(request as any);
582
+ assert.deepEqual(parsed, [
583
+ {
584
+ id: "API_TOKEN",
585
+ title: "API_TOKEN",
586
+ description: "Leave empty to skip.",
587
+ required: false,
588
+ secure: true,
589
+ },
590
+ ]);
591
+ });
592
+
593
+ test("createClaudeCodeElicitationHandler collects secure_env_collect fields through input dialogs", async () => {
594
+ const secureRequest = {
595
+ serverName: "gsd-workflow",
596
+ message: "Enter values for environment variables.",
597
+ mode: "form" as const,
598
+ requestedSchema: {
599
+ type: "object" as const,
600
+ properties: {
601
+ TEST_PASSWORD: {
602
+ type: "string",
603
+ title: "TEST_PASSWORD",
604
+ description: "Format: Your secure testing password\nLeave empty to skip.",
605
+ },
606
+ },
607
+ },
608
+ };
609
+
610
+ const inputCalls: Array<{ opts?: { secure?: boolean } }> = [];
611
+ const handler = createClaudeCodeElicitationHandler({
612
+ input: async (_title: string, _placeholder?: string, opts?: { secure?: boolean }) => {
613
+ inputCalls.push({ opts });
614
+ return "super-secret";
615
+ },
616
+ } as any);
617
+ assert.ok(handler);
618
+
619
+ const result = await handler!(secureRequest as any, { signal: new AbortController().signal });
620
+ assert.deepEqual(result, {
621
+ action: "accept",
622
+ content: {
623
+ TEST_PASSWORD: "super-secret",
624
+ },
625
+ });
626
+ assert.equal(inputCalls.length, 1);
627
+ assert.equal(inputCalls[0]?.opts?.secure, true, "secure_env_collect fields should request secure input");
628
+ });
517
629
  });
518
630
 
519
631
  describe("stream-adapter — Windows Claude path lookup (#3770)", () => {
@@ -126,7 +126,7 @@ async function collectOneSecret(
126
126
  ): Promise<string | null> {
127
127
  if (!ctx.hasUI) return null;
128
128
 
129
- return ctx.ui.custom((tui: any, theme: any, _kb: any, done: (r: string | null) => void) => {
129
+ const customResult = await ctx.ui.custom((tui: any, theme: any, _kb: any, done: (r: string | null) => void) => {
130
130
  let value = "";
131
131
  let cachedLines: string[] | undefined;
132
132
 
@@ -223,6 +223,29 @@ async function collectOneSecret(
223
223
  handleInput,
224
224
  };
225
225
  });
226
+
227
+ // RPC/web surfaces may not implement ctx.ui.custom(). Fall back to a
228
+ // standard input prompt so users can still provide the secret.
229
+ if (customResult !== undefined) {
230
+ return customResult;
231
+ }
232
+
233
+ if (typeof ctx.ui?.input !== "function") {
234
+ return null;
235
+ }
236
+
237
+ const inputTitle = `Secure value for ${keyName} (${pageIndex + 1}/${totalPages})`;
238
+ const inputPlaceholder = hint || "Enter secret value";
239
+ const inputResult = await ctx.ui.input(
240
+ inputTitle,
241
+ inputPlaceholder,
242
+ { secure: true },
243
+ );
244
+ if (typeof inputResult !== "string") {
245
+ return null;
246
+ }
247
+ const trimmed = inputResult.trim();
248
+ return trimmed.length > 0 ? trimmed : null;
226
249
  }
227
250
 
228
251
  /**
@@ -317,3 +317,48 @@ test("secure_env_collect #2997: null from ctx.ui.custom() is still treated as sk
317
317
  "Key returning null must NOT be in applied list",
318
318
  );
319
319
  });
320
+
321
+ test("secure_env_collect: falls back to secure input prompt when custom UI is unavailable", async (t) => {
322
+ const { collectSecretsFromManifest } = await loadOrchestrator();
323
+
324
+ const tmp = makeTempDir("sec-input-fallback-test");
325
+ t.after(() => {
326
+ rmSync(tmp, { recursive: true, force: true });
327
+ });
328
+
329
+ const manifest = makeManifest([
330
+ { key: "SECRET_FROM_INPUT_FALLBACK", status: "pending", formatHint: "starts with sk-" },
331
+ ]);
332
+ await writeManifestFile(tmp, manifest);
333
+
334
+ let callIndex = 0;
335
+ const inputCalls: Array<{ title: string; placeholder?: string; opts?: { secure?: boolean } }> = [];
336
+ const mockCtx = {
337
+ cwd: tmp,
338
+ hasUI: true,
339
+ ui: {
340
+ custom: async (_factory: any) => {
341
+ callIndex++;
342
+ if (callIndex <= 1) return null; // summary screen dismiss
343
+ return undefined; // collect screen unavailable on this surface
344
+ },
345
+ input: async (title: string, placeholder?: string, opts?: { secure?: boolean }) => {
346
+ inputCalls.push({ title, placeholder, opts });
347
+ return " sk-test-fallback-value ";
348
+ },
349
+ },
350
+ };
351
+
352
+ const result = await collectSecretsFromManifest(tmp, "M001", mockCtx as any);
353
+
354
+ assert.ok(
355
+ result.applied.includes("SECRET_FROM_INPUT_FALLBACK"),
356
+ "Fallback input should collect and apply the key",
357
+ );
358
+ assert.ok(
359
+ !result.skipped.includes("SECRET_FROM_INPUT_FALLBACK"),
360
+ "Fallback input should not mark the key as skipped",
361
+ );
362
+ assert.equal(inputCalls.length, 1, "Fallback input should be requested once");
363
+ assert.equal(inputCalls[0]?.opts?.secure, true, "Fallback input should request secure entry when supported");
364
+ });