gsd-pi 2.36.0-dev.d612764 → 2.36.0-dev.f887f4e

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 (46) hide show
  1. package/dist/resources/extensions/gsd/auto-dashboard.js +104 -334
  2. package/dist/resources/extensions/gsd/auto-loop.js +0 -11
  3. package/dist/resources/extensions/gsd/auto.js +0 -16
  4. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +1 -1
  5. package/dist/resources/extensions/gsd/commands.js +1 -51
  6. package/dist/resources/extensions/gsd/docs/preferences-reference.md +0 -25
  7. package/dist/resources/extensions/gsd/index.js +0 -5
  8. package/dist/resources/extensions/gsd/notifications.js +1 -10
  9. package/dist/resources/extensions/gsd/preferences-types.js +0 -2
  10. package/dist/resources/extensions/gsd/preferences-validation.js +0 -29
  11. package/dist/resources/extensions/gsd/preferences.js +0 -3
  12. package/dist/resources/extensions/gsd/prompts/research-milestone.md +3 -4
  13. package/dist/resources/extensions/gsd/prompts/research-slice.md +2 -3
  14. package/dist/resources/extensions/gsd/templates/preferences.md +0 -6
  15. package/dist/resources/extensions/search-the-web/native-search.js +4 -45
  16. package/dist/resources/extensions/shared/terminal.js +0 -5
  17. package/dist/resources/extensions/subagent/index.js +60 -180
  18. package/package.json +1 -1
  19. package/packages/pi-tui/dist/terminal-image.d.ts.map +1 -1
  20. package/packages/pi-tui/dist/terminal-image.js +0 -4
  21. package/packages/pi-tui/dist/terminal-image.js.map +1 -1
  22. package/packages/pi-tui/src/terminal-image.ts +0 -5
  23. package/src/resources/extensions/gsd/auto-dashboard.ts +116 -363
  24. package/src/resources/extensions/gsd/auto-loop.ts +0 -42
  25. package/src/resources/extensions/gsd/auto.ts +0 -21
  26. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +1 -1
  27. package/src/resources/extensions/gsd/commands.ts +1 -54
  28. package/src/resources/extensions/gsd/docs/preferences-reference.md +0 -25
  29. package/src/resources/extensions/gsd/index.ts +0 -8
  30. package/src/resources/extensions/gsd/notifications.ts +1 -10
  31. package/src/resources/extensions/gsd/preferences-types.ts +0 -13
  32. package/src/resources/extensions/gsd/preferences-validation.ts +0 -26
  33. package/src/resources/extensions/gsd/preferences.ts +0 -4
  34. package/src/resources/extensions/gsd/prompts/research-milestone.md +3 -4
  35. package/src/resources/extensions/gsd/prompts/research-slice.md +2 -3
  36. package/src/resources/extensions/gsd/templates/preferences.md +0 -6
  37. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +0 -2
  38. package/src/resources/extensions/gsd/tests/preferences.test.ts +0 -23
  39. package/src/resources/extensions/search-the-web/native-search.ts +4 -50
  40. package/src/resources/extensions/shared/terminal.ts +0 -5
  41. package/src/resources/extensions/subagent/index.ts +79 -236
  42. package/dist/resources/extensions/cmux/index.js +0 -321
  43. package/dist/resources/extensions/gsd/commands-cmux.js +0 -120
  44. package/src/resources/extensions/cmux/index.ts +0 -384
  45. package/src/resources/extensions/gsd/commands-cmux.ts +0 -143
  46. package/src/resources/extensions/gsd/tests/cmux.test.ts +0 -98
@@ -25,7 +25,6 @@ import type {
25
25
  import type { DispatchAction } from "./auto-dispatch.js";
26
26
  import type { WorktreeResolver } from "./worktree-resolver.js";
27
27
  import { debugLog } from "./debug-logger.js";
28
- import type { CmuxLogLevel } from "../cmux/index.js";
29
28
 
30
29
  /**
31
30
  * Maximum total loop iterations before forced stop. Prevents runaway loops
@@ -277,12 +276,6 @@ export interface LoopDeps {
277
276
  unitId: string,
278
277
  state: GSDState,
279
278
  ) => void;
280
- syncCmuxSidebar: (preferences: GSDPreferences | undefined, state: GSDState) => void;
281
- logCmuxEvent: (
282
- preferences: GSDPreferences | undefined,
283
- message: string,
284
- level?: CmuxLogLevel,
285
- ) => void;
286
279
 
287
280
  // State and cache functions
288
281
  invalidateAllCaches: () => void;
@@ -616,7 +609,6 @@ export async function autoLoop(
616
609
 
617
610
  // Derive state
618
611
  let state = await deps.deriveState(s.basePath);
619
- deps.syncCmuxSidebar(deps.loadEffectiveGSDPreferences()?.preferences, state);
620
612
  let mid = state.activeMilestone?.id;
621
613
  let midTitle = state.activeMilestone?.title;
622
614
  debugLog("autoLoop", {
@@ -638,11 +630,6 @@ export async function autoLoop(
638
630
  "success",
639
631
  "milestone",
640
632
  );
641
- deps.logCmuxEvent(
642
- deps.loadEffectiveGSDPreferences()?.preferences,
643
- `Milestone ${s.currentMilestoneId} complete. Advancing to ${mid}.`,
644
- "success",
645
- );
646
633
 
647
634
  const vizPrefs = deps.loadEffectiveGSDPreferences()?.preferences;
648
635
  if (vizPrefs?.auto_visualize) {
@@ -780,18 +767,12 @@ export async function autoLoop(
780
767
  "success",
781
768
  "milestone",
782
769
  );
783
- deps.logCmuxEvent(
784
- deps.loadEffectiveGSDPreferences()?.preferences,
785
- "All milestones complete.",
786
- "success",
787
- );
788
770
  await deps.stopAuto(ctx, pi, "All milestones complete");
789
771
  } else if (state.phase === "blocked") {
790
772
  const blockerMsg = `Blocked: ${state.blockers.join(", ")}`;
791
773
  await deps.stopAuto(ctx, pi, blockerMsg);
792
774
  ctx.ui.notify(`${blockerMsg}. Fix and run /gsd auto.`, "warning");
793
775
  deps.sendDesktopNotification("GSD", blockerMsg, "error", "attention");
794
- deps.logCmuxEvent(deps.loadEffectiveGSDPreferences()?.preferences, blockerMsg, "error");
795
776
  } else {
796
777
  const ids = incomplete.map((m: { id: string }) => m.id).join(", ");
797
778
  const diag = `basePath=${s.basePath}, milestones=[${state.registry.map((m: { id: string; status: string }) => `${m.id}:${m.status}`).join(", ")}], phase=${state.phase}`;
@@ -869,11 +850,6 @@ export async function autoLoop(
869
850
  "success",
870
851
  "milestone",
871
852
  );
872
- deps.logCmuxEvent(
873
- deps.loadEffectiveGSDPreferences()?.preferences,
874
- `Milestone ${mid} complete.`,
875
- "success",
876
- );
877
853
  await deps.stopAuto(ctx, pi, `Milestone ${mid} complete`);
878
854
  debugLog("autoLoop", { phase: "exit", reason: "milestone-complete" });
879
855
  break;
@@ -895,7 +871,6 @@ export async function autoLoop(
895
871
  await deps.stopAuto(ctx, pi, blockerMsg);
896
872
  ctx.ui.notify(`${blockerMsg}. Fix and run /gsd auto.`, "warning");
897
873
  deps.sendDesktopNotification("GSD", blockerMsg, "error", "attention");
898
- deps.logCmuxEvent(deps.loadEffectiveGSDPreferences()?.preferences, blockerMsg, "error");
899
874
  debugLog("autoLoop", { phase: "exit", reason: "blocked" });
900
875
  break;
901
876
  }
@@ -939,14 +914,12 @@ export async function autoLoop(
939
914
  "warning",
940
915
  );
941
916
  deps.sendDesktopNotification("GSD", msg, "warning", "budget");
942
- deps.logCmuxEvent(prefs, msg, "warning");
943
917
  await deps.pauseAuto(ctx, pi);
944
918
  debugLog("autoLoop", { phase: "exit", reason: "budget-pause" });
945
919
  break;
946
920
  }
947
921
  ctx.ui.notify(`${msg} Continuing (enforcement: warn).`, "warning");
948
922
  deps.sendDesktopNotification("GSD", msg, "warning", "budget");
949
- deps.logCmuxEvent(prefs, msg, "warning");
950
923
  } else if (newBudgetAlertLevel === 90) {
951
924
  s.lastBudgetAlertLevel =
952
925
  newBudgetAlertLevel as AutoSession["lastBudgetAlertLevel"];
@@ -960,11 +933,6 @@ export async function autoLoop(
960
933
  "warning",
961
934
  "budget",
962
935
  );
963
- deps.logCmuxEvent(
964
- prefs,
965
- `Budget 90%: ${deps.formatCost(totalCost)} / ${deps.formatCost(budgetCeiling)}`,
966
- "warning",
967
- );
968
936
  } else if (newBudgetAlertLevel === 80) {
969
937
  s.lastBudgetAlertLevel =
970
938
  newBudgetAlertLevel as AutoSession["lastBudgetAlertLevel"];
@@ -978,11 +946,6 @@ export async function autoLoop(
978
946
  "warning",
979
947
  "budget",
980
948
  );
981
- deps.logCmuxEvent(
982
- prefs,
983
- `Budget 80%: ${deps.formatCost(totalCost)} / ${deps.formatCost(budgetCeiling)}`,
984
- "warning",
985
- );
986
949
  } else if (newBudgetAlertLevel === 75) {
987
950
  s.lastBudgetAlertLevel =
988
951
  newBudgetAlertLevel as AutoSession["lastBudgetAlertLevel"];
@@ -996,11 +959,6 @@ export async function autoLoop(
996
959
  "info",
997
960
  "budget",
998
961
  );
999
- deps.logCmuxEvent(
1000
- prefs,
1001
- `Budget 75%: ${deps.formatCost(totalCost)} / ${deps.formatCost(budgetCeiling)}`,
1002
- "progress",
1003
- );
1004
962
  } else if (budgetAlertLevel === 0) {
1005
963
  s.lastBudgetAlertLevel = 0;
1006
964
  }
@@ -184,7 +184,6 @@ import {
184
184
  } from "./auto-supervisor.js";
185
185
  import { isDbAvailable } from "./gsd-db.js";
186
186
  import { countPendingCaptures } from "./captures.js";
187
- import { clearCmuxSidebar, logCmuxEvent, syncCmuxSidebar } from "../cmux/index.js";
188
187
 
189
188
  // ── Extracted modules ──────────────────────────────────────────────────────
190
189
  import { startUnitSupervision } from "./auto-timers.js";
@@ -467,7 +466,6 @@ function handleLostSessionLock(ctx?: ExtensionContext): void {
467
466
  s.paused = false;
468
467
  clearUnitTimeout();
469
468
  deregisterSigtermHandler();
470
- clearCmuxSidebar(loadEffectiveGSDPreferences()?.preferences);
471
469
  ctx?.ui.notify(
472
470
  "Session lock lost — another GSD process appears to have taken over. Stopping gracefully.",
473
471
  "error",
@@ -483,7 +481,6 @@ export async function stopAuto(
483
481
  reason?: string,
484
482
  ): Promise<void> {
485
483
  if (!s.active && !s.paused) return;
486
- const loadedPreferences = loadEffectiveGSDPreferences()?.preferences;
487
484
  const reasonSuffix = reason ? ` — ${reason}` : "";
488
485
  clearUnitTimeout();
489
486
  if (lockBase()) clearLock(lockBase());
@@ -546,13 +543,6 @@ export async function stopAuto(
546
543
  }
547
544
  }
548
545
 
549
- clearCmuxSidebar(loadedPreferences);
550
- logCmuxEvent(
551
- loadedPreferences,
552
- `Auto-mode stopped${reasonSuffix || ""}.`,
553
- reason?.startsWith("Blocked:") ? "warning" : "info",
554
- );
555
-
556
546
  if (isDebugEnabled()) {
557
547
  const logPath = writeDebugSummary();
558
548
  if (logPath) {
@@ -718,8 +708,6 @@ function buildLoopDeps(): LoopDeps {
718
708
  pauseAuto,
719
709
  clearUnitTimeout,
720
710
  updateProgressWidget,
721
- syncCmuxSidebar,
722
- logCmuxEvent,
723
711
 
724
712
  // State and cache
725
713
  invalidateAllCaches,
@@ -902,7 +890,6 @@ export async function startAuto(
902
890
  restoreHookState(s.basePath);
903
891
  try {
904
892
  await rebuildState(s.basePath);
905
- syncCmuxSidebar(loadEffectiveGSDPreferences()?.preferences, await deriveState(s.basePath));
906
893
  } catch (e) {
907
894
  debugLog("resume-rebuild-state-failed", {
908
895
  error: e instanceof Error ? e.message : String(e),
@@ -954,7 +941,6 @@ export async function startAuto(
954
941
  s.currentMilestoneId ?? "unknown",
955
942
  s.completedUnits.length,
956
943
  );
957
- logCmuxEvent(loadEffectiveGSDPreferences()?.preferences, s.stepMode ? "Step-mode resumed." : "Auto-mode resumed.", "progress");
958
944
 
959
945
  await autoLoop(ctx, pi, s, buildLoopDeps());
960
946
  return;
@@ -979,13 +965,6 @@ export async function startAuto(
979
965
  );
980
966
  if (!ready) return;
981
967
 
982
- try {
983
- syncCmuxSidebar(loadEffectiveGSDPreferences()?.preferences, await deriveState(s.basePath));
984
- } catch {
985
- // Best-effort only — sidebar sync must never block auto-mode startup
986
- }
987
- logCmuxEvent(loadEffectiveGSDPreferences()?.preferences, requestedStepMode ? "Step-mode started." : "Auto-mode started.", "progress");
988
-
989
968
  // Dispatch the first unit
990
969
  await autoLoop(ctx, pi, s, buildLoopDeps());
991
970
  }
@@ -740,7 +740,7 @@ export function serializePreferencesToFrontmatter(prefs: Record<string, unknown>
740
740
  "skill_rules", "custom_instructions", "models", "skill_discovery",
741
741
  "skill_staleness_days", "auto_supervisor", "uat_dispatch", "unique_milestone_ids",
742
742
  "budget_ceiling", "budget_enforcement", "context_pause_threshold",
743
- "notifications", "cmux", "remote_questions", "git",
743
+ "notifications", "remote_questions", "git",
744
744
  "post_unit_hooks", "pre_dispatch_hooks",
745
745
  "dynamic_routing", "token_profile", "phases", "parallel",
746
746
  "auto_visualize", "auto_report",
@@ -49,7 +49,6 @@ import { runEnvironmentChecks } from "./doctor-environment.js";
49
49
  import { handleLogs } from "./commands-logs.js";
50
50
  import { handleStart, handleTemplates, getTemplateCompletions } from "./commands-workflow-templates.js";
51
51
  import { readSessionLockData, isSessionLockProcessAlive } from "./session-lock.js";
52
- import { handleCmux } from "./commands-cmux.js";
53
52
 
54
53
 
55
54
  /** Resolve the effective project root, accounting for worktree paths. */
@@ -106,7 +105,7 @@ function notifyRemoteAutoActive(ctx: ExtensionCommandContext, basePath: string):
106
105
 
107
106
  export function registerGSDCommand(pi: ExtensionAPI): void {
108
107
  pi.registerCommand("gsd", {
109
- description: "GSD — Get Shit Done: /gsd help|start|templates|next|auto|stop|pause|status|visualize|queue|quick|capture|triage|dispatch|history|undo|skip|export|cleanup|mode|prefs|config|keys|hooks|run-hook|skill-health|doctor|forensics|changelog|migrate|remote|steer|knowledge|new-milestone|parallel|cmux|update",
108
+ description: "GSD — Get Shit Done: /gsd help|start|templates|next|auto|stop|pause|status|visualize|queue|quick|capture|triage|dispatch|history|undo|skip|export|cleanup|mode|prefs|config|keys|hooks|run-hook|skill-health|doctor|forensics|changelog|migrate|remote|steer|knowledge|new-milestone|parallel|update",
110
109
  getArgumentCompletions: (prefix: string) => {
111
110
  const subcommands = [
112
111
  { cmd: "help", desc: "Categorized command reference with descriptions" },
@@ -115,7 +114,6 @@ export function registerGSDCommand(pi: ExtensionAPI): void {
115
114
  { cmd: "stop", desc: "Stop auto mode gracefully" },
116
115
  { cmd: "pause", desc: "Pause auto-mode (preserves state, /gsd auto to resume)" },
117
116
  { cmd: "status", desc: "Progress dashboard" },
118
- { cmd: "widget", desc: "Cycle widget: full → small → min → off" },
119
117
  { cmd: "visualize", desc: "Open 10-tab workflow visualizer (progress, timeline, deps, metrics, health, agent, changes, knowledge, captures, export)" },
120
118
  { cmd: "queue", desc: "Queue and reorder future milestones" },
121
119
  { cmd: "quick", desc: "Execute a quick task without full planning overhead" },
@@ -149,7 +147,6 @@ export function registerGSDCommand(pi: ExtensionAPI): void {
149
147
  { cmd: "knowledge", desc: "Add persistent project knowledge (rule, pattern, or lesson)" },
150
148
  { cmd: "new-milestone", desc: "Create a milestone from a specification document (headless)" },
151
149
  { cmd: "parallel", desc: "Parallel milestone orchestration (start, status, stop, merge)" },
152
- { cmd: "cmux", desc: "Manage cmux integration (status, sidebar, notifications, splits)" },
153
150
  { cmd: "park", desc: "Park a milestone — skip without deleting" },
154
151
  { cmd: "unpark", desc: "Reactivate a parked milestone" },
155
152
  { cmd: "update", desc: "Update GSD to the latest version" },
@@ -206,38 +203,6 @@ export function registerGSDCommand(pi: ExtensionAPI): void {
206
203
  .map((s) => ({ value: `parallel ${s.cmd}`, label: s.cmd, description: s.desc }));
207
204
  }
208
205
 
209
- if (parts[0] === "cmux") {
210
- if (parts.length <= 2) {
211
- const subPrefix = parts[1] ?? "";
212
- const subs = [
213
- { cmd: "status", desc: "Show cmux detection, prefs, and capabilities" },
214
- { cmd: "on", desc: "Enable cmux integration" },
215
- { cmd: "off", desc: "Disable cmux integration" },
216
- { cmd: "notifications", desc: "Toggle cmux desktop notifications" },
217
- { cmd: "sidebar", desc: "Toggle cmux sidebar metadata" },
218
- { cmd: "splits", desc: "Toggle cmux visual subagent splits" },
219
- { cmd: "browser", desc: "Toggle future browser integration flag" },
220
- ];
221
- return subs
222
- .filter((s) => s.cmd.startsWith(subPrefix))
223
- .map((s) => ({ value: `cmux ${s.cmd}`, label: s.cmd, description: s.desc }));
224
- }
225
-
226
- if (parts.length <= 3 && ["notifications", "sidebar", "splits", "browser"].includes(parts[1])) {
227
- const togglePrefix = parts[2] ?? "";
228
- return [
229
- { cmd: "on", desc: "Enable this cmux area" },
230
- { cmd: "off", desc: "Disable this cmux area" },
231
- ]
232
- .filter((item) => item.cmd.startsWith(togglePrefix))
233
- .map((item) => ({
234
- value: `cmux ${parts[1]} ${item.cmd}`,
235
- label: item.cmd,
236
- description: item.desc,
237
- }));
238
- }
239
- }
240
-
241
206
  if (parts[0] === "setup" && parts.length <= 2) {
242
207
  const subPrefix = parts[1] ?? "";
243
208
  const subs = [
@@ -509,18 +474,6 @@ export async function handleGSDCommand(
509
474
  return;
510
475
  }
511
476
 
512
- if (trimmed === "widget" || trimmed.startsWith("widget ")) {
513
- const { cycleWidgetMode, setWidgetMode, getWidgetMode } = await import("./auto-dashboard.js");
514
- const arg = trimmed.replace(/^widget\s*/, "").trim();
515
- if (arg === "full" || arg === "small" || arg === "min" || arg === "off") {
516
- setWidgetMode(arg);
517
- } else {
518
- cycleWidgetMode();
519
- }
520
- ctx.ui.notify(`Widget: ${getWidgetMode()}`, "info");
521
- return;
522
- }
523
-
524
477
  if (trimmed === "visualize") {
525
478
  await handleVisualize(ctx);
526
479
  return;
@@ -540,11 +493,6 @@ export async function handleGSDCommand(
540
493
  return;
541
494
  }
542
495
 
543
- if (trimmed === "cmux" || trimmed.startsWith("cmux ")) {
544
- await handleCmux(trimmed.replace(/^cmux\s*/, "").trim(), ctx);
545
- return;
546
- }
547
-
548
496
  if (trimmed === "init") {
549
497
  const { detectProjectState } = await import("./detection.js");
550
498
  const { showProjectInit, handleReinit } = await import("./init-wizard.js");
@@ -1048,7 +996,6 @@ function showHelp(ctx: ExtensionCommandContext): void {
1048
996
  " /gsd setup Global setup status [llm|search|remote|keys|prefs]",
1049
997
  " /gsd mode Set workflow mode (solo/team) [global|project]",
1050
998
  " /gsd prefs Manage preferences [global|project|status|wizard|setup|import-claude]",
1051
- " /gsd cmux Manage cmux integration [status|on|off|notifications|sidebar|splits|browser]",
1052
999
  " /gsd config Set API keys for external tools",
1053
1000
  " /gsd keys API key manager [list|add|remove|test|rotate|doctor]",
1054
1001
  " /gsd hooks Show post-unit hook configuration",
@@ -173,13 +173,6 @@ Setting `prefer_skills: []` does **not** disable skill discovery — it just mea
173
173
  - `on_milestone`: boolean — notify when a milestone finishes. Default: `true`.
174
174
  - `on_attention`: boolean — notify when manual attention is needed. Default: `true`.
175
175
 
176
- - `cmux`: configures cmux terminal integration when GSD is running inside a cmux workspace. Keys:
177
- - `enabled`: boolean — master toggle for cmux integration. Default: `false`.
178
- - `notifications`: boolean — route desktop notifications through cmux. Default: `true` when enabled.
179
- - `sidebar`: boolean — publish status, progress, and log metadata to the cmux sidebar. Default: `true` when enabled.
180
- - `splits`: boolean — run supported subagent work in visible cmux splits. Default: `false`.
181
- - `browser`: boolean — reserve the future browser integration flag. Default: `false`.
182
-
183
176
  - `dynamic_routing`: configures the dynamic model router that adjusts model selection based on task complexity. Keys:
184
177
  - `enabled`: boolean — enable dynamic routing. Default: `false`.
185
178
  - `tier_models`: object — model overrides per complexity tier. Keys: `light`, `standard`, `heavy`. Values are model ID strings.
@@ -484,24 +477,6 @@ Disables per-unit completion notifications (noisy in long runs) while keeping er
484
477
 
485
478
  ---
486
479
 
487
- ## cmux Example
488
-
489
- ```yaml
490
- ---
491
- version: 1
492
- cmux:
493
- enabled: true
494
- notifications: true
495
- sidebar: true
496
- splits: true
497
- browser: false
498
- ---
499
- ```
500
-
501
- Enables cmux-aware notifications, sidebar metadata, and visible subagent splits when GSD is running inside a cmux terminal.
502
-
503
- ---
504
-
505
480
  ## Post-Unit Hooks Example
506
481
 
507
482
  ```yaml
@@ -65,7 +65,6 @@ import { pauseAutoForProviderError, classifyProviderError } from "./provider-err
65
65
  import { toPosixPath } from "../shared/mod.js";
66
66
  import { isParallelActive, shutdownParallel } from "./parallel-orchestrator.js";
67
67
  import { DEFAULT_BASH_TIMEOUT_SECS } from "./constants.js";
68
- import { markCmuxPromptShown, shouldPromptToEnableCmux } from "../cmux/index.js";
69
68
 
70
69
  // ── Agent Instructions (DEPRECATED) ──────────────────────────────────────
71
70
  // agent-instructions.md is deprecated. Use AGENTS.md or CLAUDE.md instead.
@@ -624,13 +623,6 @@ export default function (pi: ExtensionAPI) {
624
623
  const stopContextTimer = debugTime("context-inject");
625
624
  const systemContent = loadPrompt("system");
626
625
  const loadedPreferences = loadEffectiveGSDPreferences();
627
- if (shouldPromptToEnableCmux(loadedPreferences?.preferences)) {
628
- markCmuxPromptShown();
629
- ctx.ui.notify(
630
- "cmux detected. Run /gsd cmux on to enable sidebar metadata, notifications, and visual subagent splits for this project.",
631
- "info",
632
- );
633
- }
634
626
  let preferenceBlock = "";
635
627
  if (loadedPreferences) {
636
628
  const cwd = process.cwd();
@@ -4,7 +4,6 @@
4
4
  import { execFileSync } from "node:child_process";
5
5
  import type { NotificationPreferences } from "./types.js";
6
6
  import { loadEffectiveGSDPreferences } from "./preferences.js";
7
- import { CmuxClient, emitOsc777Notification, resolveCmuxConfig } from "../cmux/index.js";
8
7
 
9
8
  export type NotifyLevel = "info" | "success" | "warning" | "error";
10
9
  export type NotificationKind = "complete" | "error" | "budget" | "milestone" | "attention";
@@ -24,15 +23,7 @@ export function sendDesktopNotification(
24
23
  level: NotifyLevel = "info",
25
24
  kind: NotificationKind = "complete",
26
25
  ): void {
27
- const loaded = loadEffectiveGSDPreferences()?.preferences;
28
- if (!shouldSendDesktopNotification(kind, loaded?.notifications)) return;
29
-
30
- const cmux = resolveCmuxConfig(loaded);
31
- if (cmux.notifications) {
32
- const delivered = CmuxClient.fromPreferences(loaded).notify(title, message);
33
- if (delivered) return;
34
- emitOsc777Notification(title, message);
35
- }
26
+ if (!shouldSendDesktopNotification(kind)) return;
36
27
 
37
28
  try {
38
29
  const command = buildDesktopNotificationCommand(process.platform, title, message, level);
@@ -68,7 +68,6 @@ export const KNOWN_PREFERENCE_KEYS = new Set<string>([
68
68
  "budget_enforcement",
69
69
  "context_pause_threshold",
70
70
  "notifications",
71
- "cmux",
72
71
  "remote_questions",
73
72
  "git",
74
73
  "post_unit_hooks",
@@ -85,7 +84,6 @@ export const KNOWN_PREFERENCE_KEYS = new Set<string>([
85
84
  "search_provider",
86
85
  "compression_strategy",
87
86
  "context_selection",
88
- "widget_mode",
89
87
  ]);
90
88
 
91
89
  /** Canonical list of all dispatch unit types. */
@@ -166,14 +164,6 @@ export interface RemoteQuestionsConfig {
166
164
  poll_interval_seconds?: number; // clamped to 2-30
167
165
  }
168
166
 
169
- export interface CmuxPreferences {
170
- enabled?: boolean;
171
- notifications?: boolean;
172
- sidebar?: boolean;
173
- splits?: boolean;
174
- browser?: boolean;
175
- }
176
-
177
167
  export interface GSDPreferences {
178
168
  version?: number;
179
169
  mode?: WorkflowMode;
@@ -192,7 +182,6 @@ export interface GSDPreferences {
192
182
  budget_enforcement?: BudgetEnforcementMode;
193
183
  context_pause_threshold?: number;
194
184
  notifications?: NotificationPreferences;
195
- cmux?: CmuxPreferences;
196
185
  remote_questions?: RemoteQuestionsConfig;
197
186
  git?: GitPreferences;
198
187
  post_unit_hooks?: PostUnitHookConfig[];
@@ -213,8 +202,6 @@ export interface GSDPreferences {
213
202
  compression_strategy?: CompressionStrategy;
214
203
  /** Context selection mode for file inlining. "full" inlines entire files, "smart" uses semantic chunking. Default derived from token profile. */
215
204
  context_selection?: ContextSelectionMode;
216
- /** Default widget display mode for auto-mode dashboard. "full" | "small" | "min" | "off". Default: "full". */
217
- widget_mode?: "full" | "small" | "min" | "off";
218
205
  }
219
206
 
220
207
  export interface LoadedGSDPreferences {
@@ -242,32 +242,6 @@ export function validatePreferences(preferences: GSDPreferences): {
242
242
  }
243
243
  }
244
244
 
245
- // ─── Cmux ───────────────────────────────────────────────────────────────
246
- if (preferences.cmux !== undefined) {
247
- if (preferences.cmux && typeof preferences.cmux === "object") {
248
- const cmux = preferences.cmux as Record<string, unknown>;
249
- const validatedCmux: NonNullable<GSDPreferences["cmux"]> = {};
250
- if (cmux.enabled !== undefined) validatedCmux.enabled = !!cmux.enabled;
251
- if (cmux.notifications !== undefined) validatedCmux.notifications = !!cmux.notifications;
252
- if (cmux.sidebar !== undefined) validatedCmux.sidebar = !!cmux.sidebar;
253
- if (cmux.splits !== undefined) validatedCmux.splits = !!cmux.splits;
254
- if (cmux.browser !== undefined) validatedCmux.browser = !!cmux.browser;
255
-
256
- const knownCmuxKeys = new Set(["enabled", "notifications", "sidebar", "splits", "browser"]);
257
- for (const key of Object.keys(cmux)) {
258
- if (!knownCmuxKeys.has(key)) {
259
- warnings.push(`unknown cmux key "${key}" — ignored`);
260
- }
261
- }
262
-
263
- if (Object.keys(validatedCmux).length > 0) {
264
- validated.cmux = validatedCmux;
265
- }
266
- } else {
267
- errors.push("cmux must be an object");
268
- }
269
- }
270
-
271
245
  // ─── Remote Questions ───────────────────────────────────────────────
272
246
  if (preferences.remote_questions !== undefined) {
273
247
  if (preferences.remote_questions && typeof preferences.remote_questions === "object") {
@@ -45,7 +45,6 @@ export type {
45
45
  SkillDiscoveryMode,
46
46
  AutoSupervisorConfig,
47
47
  RemoteQuestionsConfig,
48
- CmuxPreferences,
49
48
  GSDPreferences,
50
49
  LoadedGSDPreferences,
51
50
  SkillResolution,
@@ -242,9 +241,6 @@ function mergePreferences(base: GSDPreferences, override: GSDPreferences): GSDPr
242
241
  notifications: (base.notifications || override.notifications)
243
242
  ? { ...(base.notifications ?? {}), ...(override.notifications ?? {}) }
244
243
  : undefined,
245
- cmux: (base.cmux || override.cmux)
246
- ? { ...(base.cmux ?? {}), ...(override.cmux ?? {}) }
247
- : undefined,
248
244
  remote_questions: override.remote_questions
249
245
  ? { ...(base.remote_questions ?? {}), ...override.remote_questions }
250
246
  : base.remote_questions,
@@ -25,10 +25,9 @@ Then research the codebase and relevant technologies. Narrate key findings and s
25
25
  2. **Skill Discovery ({{skillDiscoveryMode}}):**{{skillDiscoveryInstructions}}
26
26
  3. Explore relevant code. For small/familiar codebases, use `rg`, `find`, and targeted reads. For large or unfamiliar codebases, use `scout` to build a broad map efficiently before diving in.
27
27
  4. Use `resolve_library` / `get_library_docs` for unfamiliar libraries — skip this for libraries already used in the codebase
28
- 5. **Web search budget:** You have a limited budget of web searches (max ~15 per session). Use them strategically prefer `resolve_library` / `get_library_docs` for library documentation. Do NOT repeat the same or similar queries. If a search didn't find what you need, rephrase once or move on. Target 3-5 total web searches for a typical research unit.
29
- 6. Use the **Research** output template from the inlined context above include only sections that have real content
30
- 7. If `.gsd/REQUIREMENTS.md` exists, research against it. Identify which Active requirements are table stakes, likely omissions, overbuilt risks, or domain-standard behaviors the user may or may not want.
31
- 8. Write `{{outputPath}}`
28
+ 5. Use the **Research** output template from the inlined context above include only sections that have real content
29
+ 6. If `.gsd/REQUIREMENTS.md` exists, research against it. Identify which Active requirements are table stakes, likely omissions, overbuilt risks, or domain-standard behaviors the user may or may not want.
30
+ 7. Write `{{outputPath}}`
32
31
 
33
32
  ## Strategic Questions to Answer
34
33
 
@@ -46,9 +46,8 @@ Research what this slice needs. Narrate key findings and surprises as you go —
46
46
  2. **Skill Discovery ({{skillDiscoveryMode}}):**{{skillDiscoveryInstructions}}
47
47
  3. Explore relevant code for this slice's scope. For targeted exploration, use `rg`, `find`, and reads. For broad or unfamiliar subsystems, use `scout` to map the relevant area first.
48
48
  4. Use `resolve_library` / `get_library_docs` for unfamiliar libraries — skip this for libraries already used in the codebase
49
- 5. **Web search budget:** You have a limited budget of web searches (max ~15 per session). Use them strategically prefer `resolve_library` / `get_library_docs` for library documentation. Do NOT repeat the same or similar queries. If a search didn't find what you need, rephrase once or move on. Target 3-5 total web searches for a typical research unit.
50
- 6. Use the **Research** output template from the inlined context above — include only sections that have real content. The template is already inlined above; do NOT attempt to read any template file from disk (there is no `templates/SLICE-RESEARCH.md` — the correct template is already present in this prompt).
51
- 7. Write `{{outputPath}}`
49
+ 5. Use the **Research** output template from the inlined context aboveinclude only sections that have real content. The template is already inlined above; do NOT attempt to read any template file from disk (there is no `templates/SLICE-RESEARCH.md` the correct template is already present in this prompt).
50
+ 6. Write `{{outputPath}}`
52
51
 
53
52
  The slice directory already exists at `{{slicePath}}/`. Do NOT mkdir — just write the file.
54
53
 
@@ -57,12 +57,6 @@ notifications:
57
57
  on_budget:
58
58
  on_milestone:
59
59
  on_attention:
60
- cmux:
61
- enabled:
62
- notifications:
63
- sidebar:
64
- splits:
65
- browser:
66
60
  remote_questions:
67
61
  channel:
68
62
  channel_id:
@@ -317,8 +317,6 @@ function makeMockDeps(
317
317
  },
318
318
  clearUnitTimeout: () => {},
319
319
  updateProgressWidget: () => {},
320
- syncCmuxSidebar: () => {},
321
- logCmuxEvent: () => {},
322
320
  invalidateAllCaches: () => {
323
321
  callLog.push("invalidateAllCaches");
324
322
  },
@@ -171,29 +171,6 @@ test("notification fields validate correctly", () => {
171
171
  assert.equal(preferences.notifications?.on_complete, false);
172
172
  });
173
173
 
174
- test("cmux fields validate correctly", () => {
175
- const { preferences, errors } = validatePreferences({
176
- cmux: {
177
- enabled: true,
178
- notifications: true,
179
- sidebar: false,
180
- splits: true,
181
- browser: false,
182
- },
183
- });
184
- assert.equal(errors.length, 0);
185
- assert.equal(preferences.cmux?.enabled, true);
186
- assert.equal(preferences.cmux?.sidebar, false);
187
- assert.equal(preferences.cmux?.splits, true);
188
- });
189
-
190
- test("cmux unknown keys produce warnings", () => {
191
- const { warnings } = validatePreferences({
192
- cmux: { enabled: true, strange_mode: true } as any,
193
- });
194
- assert.ok(warnings.some((warning) => warning.includes('unknown cmux key "strange_mode"')));
195
- });
196
-
197
174
  test("git fields comprehensive validation", () => {
198
175
  const { preferences, errors } = validatePreferences({
199
176
  git: {