gsd-pi 2.66.1-dev.ca9a2f7 → 2.66.1-dev.e700a1b

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 (39) hide show
  1. package/dist/resources/extensions/ask-user-questions.js +79 -11
  2. package/dist/resources/extensions/remote-questions/manager.js +8 -0
  3. package/dist/web/standalone/.next/BUILD_ID +1 -1
  4. package/dist/web/standalone/.next/app-path-routes-manifest.json +20 -20
  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/server/app/_global-error.html +2 -2
  8. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  9. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  10. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  11. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  12. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  13. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  14. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  15. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  16. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  17. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  18. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  19. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  20. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  21. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  22. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  23. package/dist/web/standalone/.next/server/app/index.html +1 -1
  24. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  25. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  26. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  27. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  28. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  29. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  30. package/dist/web/standalone/.next/server/app-paths-manifest.json +20 -20
  31. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  32. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  33. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  34. package/package.json +1 -1
  35. package/src/resources/extensions/ask-user-questions.ts +103 -11
  36. package/src/resources/extensions/gsd/tests/remote-questions.test.ts +98 -0
  37. package/src/resources/extensions/remote-questions/manager.ts +9 -0
  38. /package/dist/web/standalone/.next/static/{qVa5q79snDPPTo1yyaeBm → TCMOrUQ1suscla6CiwNya}/_buildManifest.js +0 -0
  39. /package/dist/web/standalone/.next/static/{qVa5q79snDPPTo1yyaeBm → TCMOrUQ1suscla6CiwNya}/_ssgManifest.js +0 -0
@@ -760,6 +760,104 @@ test("ask-user-questions source-level: tryRemoteQuestions is called before the h
760
760
  );
761
761
  });
762
762
 
763
+ // ═══════════════════════════════════════════════════════════════════════════
764
+ // Race model tests (#3810) — local TUI races against remote channel
765
+ // ═══════════════════════════════════════════════════════════════════════════
766
+
767
+ test("ask-user-questions source-level: raceRemoteAndLocal function exists", () => {
768
+ const src = readFileSync(
769
+ join(__dirname, "..", "..", "ask-user-questions.ts"),
770
+ "utf-8",
771
+ );
772
+ assert.ok(
773
+ src.includes("async function raceRemoteAndLocal("),
774
+ "raceRemoteAndLocal helper should exist for racing local TUI against remote channel",
775
+ );
776
+ });
777
+
778
+ test("ask-user-questions source-level: race path uses isRemoteConfigured for routing", () => {
779
+ const src = readFileSync(
780
+ join(__dirname, "..", "..", "ask-user-questions.ts"),
781
+ "utf-8",
782
+ );
783
+ assert.ok(
784
+ src.includes("isRemoteConfigured()"),
785
+ "execute() should call isRemoteConfigured() for lightweight routing decision",
786
+ );
787
+ });
788
+
789
+ test("ask-user-questions source-level: race path checks both hasRemote and ctx.hasUI", () => {
790
+ // Regression: #3810 — the race should only activate when BOTH remote and local UI
791
+ // are available. Headless mode should still use remote-only, and no-remote should
792
+ // use local-only.
793
+ const src = readFileSync(
794
+ join(__dirname, "..", "..", "ask-user-questions.ts"),
795
+ "utf-8",
796
+ );
797
+ assert.ok(
798
+ src.includes("hasRemote && ctx.hasUI"),
799
+ "Race path should require both remote configured and local UI available",
800
+ );
801
+ assert.ok(
802
+ src.includes("hasRemote && !ctx.hasUI"),
803
+ "Headless path should handle remote-only when no local UI",
804
+ );
805
+ });
806
+
807
+ test("ask-user-questions source-level: race treats remote timeout as non-win", () => {
808
+ // Regression: the whole point of the race is that a remote timeout should NOT
809
+ // block the local TUI. The race helper must filter out timed_out results.
810
+ const src = readFileSync(
811
+ join(__dirname, "..", "..", "ask-user-questions.ts"),
812
+ "utf-8",
813
+ );
814
+ const raceFnStart = src.indexOf("async function raceRemoteAndLocal(");
815
+ const raceFnEnd = src.indexOf("\n}", raceFnStart);
816
+ const raceFnBody = src.slice(raceFnStart, raceFnEnd);
817
+ assert.ok(
818
+ raceFnBody.includes("timed_out"),
819
+ "raceRemoteAndLocal should check for timed_out in remote results",
820
+ );
821
+ assert.ok(
822
+ raceFnBody.includes("details?.error"),
823
+ "raceRemoteAndLocal should check for error in remote results",
824
+ );
825
+ });
826
+
827
+ test("ask-user-questions source-level: race uses AbortController to cancel loser", () => {
828
+ const src = readFileSync(
829
+ join(__dirname, "..", "..", "ask-user-questions.ts"),
830
+ "utf-8",
831
+ );
832
+ assert.ok(
833
+ src.includes("new AbortController()"),
834
+ "Race path should create an AbortController for cancellation",
835
+ );
836
+ assert.ok(
837
+ src.includes("controller.abort()"),
838
+ "raceRemoteAndLocal should abort the controller to cancel the losing side",
839
+ );
840
+ });
841
+
842
+ test("manager source-level: isRemoteConfigured export exists", () => {
843
+ const src = readFileSync(
844
+ join(__dirname, "..", "..", "remote-questions", "manager.ts"),
845
+ "utf-8",
846
+ );
847
+ assert.ok(
848
+ src.includes("export function isRemoteConfigured()"),
849
+ "manager.ts should export isRemoteConfigured for lightweight config checking",
850
+ );
851
+ // Must delegate to resolveRemoteConfig — no separate config parsing
852
+ const fnStart = src.indexOf("export function isRemoteConfigured()");
853
+ const fnEnd = src.indexOf("\n}", fnStart);
854
+ const fnBody = src.slice(fnStart, fnEnd);
855
+ assert.ok(
856
+ fnBody.includes("resolveRemoteConfig()"),
857
+ "isRemoteConfigured should delegate to resolveRemoteConfig",
858
+ );
859
+ });
860
+
763
861
  test("config source-level: removeProviderToken uses auth.remove not auth.set with empty key", () => {
764
862
  const commandSrc = readFileSync(
765
863
  join(__dirname, "..", "..", "remote-questions", "remote-command.ts"),
@@ -24,6 +24,15 @@ interface QuestionInput {
24
24
  allowMultiple?: boolean;
25
25
  }
26
26
 
27
+ /**
28
+ * Check whether a remote channel is configured without triggering any
29
+ * side effects (no HTTP requests, no prompt records). Used by the race
30
+ * logic to decide routing before committing to a remote dispatch.
31
+ */
32
+ export function isRemoteConfigured(): boolean {
33
+ return resolveRemoteConfig() !== null;
34
+ }
35
+
27
36
  export async function tryRemoteQuestions(
28
37
  questions: QuestionInput[],
29
38
  signal?: AbortSignal,