pi-sage 0.2.10 → 0.2.11

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.
@@ -848,19 +848,89 @@ async function runSettingsTestCall(ctx: ExtensionContext, settings: SageSettings
848
848
  return;
849
849
  }
850
850
 
851
- try {
852
- const result = await runSageSingleShot({
853
- cwd: ctx.cwd,
854
- model: resolvedModel,
855
- reasoningLevel: settings.reasoningLevel,
856
- timeoutMs: Math.min(settings.timeoutMs, 45_000),
857
- question: "Reply with 'Sage test OK' and one short sentence.",
858
- toolPolicy: settings.toolPolicy
859
- });
851
+ type TestOutcome = { status: "ok" | "error" | "cancelled"; message: string };
852
+
853
+ const outcome = await ctx.ui.custom<TestOutcome | undefined>((tui, theme, _keybindings, done) => {
854
+ const controller = new AbortController();
855
+ const container = new Container();
856
+
857
+ container.addChild(new DynamicBorder((s: string) => theme.fg("accent", s)));
858
+ container.addChild(new Text(theme.fg("accent", "Sage test call"), 1, 0));
859
+ container.addChild(new Text(theme.fg("dim", `Model: ${resolvedModel}`), 1, 0));
860
+ container.addChild(new Text("", 0, 0));
861
+
862
+ const spinnerFrames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
863
+ let spinnerIndex = 0;
864
+ const statusLine = new Text(theme.fg("muted", `${spinnerFrames[spinnerIndex]} Running test...`), 1, 0);
865
+ container.addChild(statusLine);
866
+
867
+ container.addChild(new Text("", 0, 0));
868
+ container.addChild(new Text(theme.fg("dim", "Esc to cancel"), 1, 0));
869
+ container.addChild(new DynamicBorder((s: string) => theme.fg("accent", s)));
870
+
871
+ let finished = false;
872
+ const finish = (result: TestOutcome): void => {
873
+ if (finished) return;
874
+ finished = true;
875
+ clearInterval(spinnerTimer);
876
+ done(result);
877
+ };
878
+
879
+ const spinnerTimer = setInterval(() => {
880
+ if (finished) return;
881
+ spinnerIndex = (spinnerIndex + 1) % spinnerFrames.length;
882
+ statusLine.setText(theme.fg("muted", `${spinnerFrames[spinnerIndex]} Running test...`));
883
+ tui.requestRender();
884
+ }, 120);
885
+
886
+ void (async () => {
887
+ try {
888
+ const result = await runSageSingleShot({
889
+ cwd: ctx.cwd,
890
+ model: resolvedModel,
891
+ reasoningLevel: settings.reasoningLevel,
892
+ timeoutMs: Math.min(settings.timeoutMs, 45_000),
893
+ question: "Reply with 'Sage test OK' and one short sentence.",
894
+ toolPolicy: settings.toolPolicy,
895
+ signal: controller.signal
896
+ });
860
897
 
861
- ctx.ui.notify(`Sage test succeeded (${result.latencyMs}ms)`, "info");
862
- } catch (error) {
863
- const message = error instanceof Error ? error.message : "Unknown test failure";
864
- ctx.ui.notify(`Sage test failed: ${message}`, "error");
898
+ finish({ status: "ok", message: `Sage test succeeded (${result.latencyMs}ms)` });
899
+ } catch (error) {
900
+ if (controller.signal.aborted) {
901
+ finish({ status: "cancelled", message: "Sage test cancelled" });
902
+ return;
903
+ }
904
+
905
+ const message = error instanceof Error ? error.message : "Unknown test failure";
906
+ finish({ status: "error", message: `Sage test failed: ${message}` });
907
+ }
908
+ })();
909
+
910
+ return {
911
+ render: (width: number) => container.render(width),
912
+ invalidate: () => container.invalidate(),
913
+ handleInput: (data: string) => {
914
+ if (data === "\u001b") {
915
+ controller.abort();
916
+ finish({ status: "cancelled", message: "Sage test cancelled" });
917
+ return;
918
+ }
919
+ }
920
+ };
921
+ });
922
+
923
+ if (!outcome) return;
924
+
925
+ if (outcome.status === "ok") {
926
+ ctx.ui.notify(outcome.message, "info");
927
+ return;
865
928
  }
929
+
930
+ if (outcome.status === "cancelled") {
931
+ ctx.ui.notify(outcome.message, "warning");
932
+ return;
933
+ }
934
+
935
+ ctx.ui.notify(outcome.message, "error");
866
936
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-sage",
3
- "version": "0.2.10",
3
+ "version": "0.2.11",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Interactive-only advisory Sage extension for Pi",