@gigaflow/gmux 0.15.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 (229) hide show
  1. package/CHANGELOG.md +654 -0
  2. package/LICENSE +21 -0
  3. package/README.md +351 -0
  4. package/dist/adapters/claude-code.d.ts +52 -0
  5. package/dist/adapters/claude-code.js +315 -0
  6. package/dist/adapters/claude-code.js.map +1 -0
  7. package/dist/adapters/codex.d.ts +39 -0
  8. package/dist/adapters/codex.js +233 -0
  9. package/dist/adapters/codex.js.map +1 -0
  10. package/dist/adapters/jsonl.d.ts +40 -0
  11. package/dist/adapters/jsonl.js +92 -0
  12. package/dist/adapters/jsonl.js.map +1 -0
  13. package/dist/adapters/registry.d.ts +11 -0
  14. package/dist/adapters/registry.js +21 -0
  15. package/dist/adapters/registry.js.map +1 -0
  16. package/dist/adapters/types.d.ts +43 -0
  17. package/dist/adapters/types.js +2 -0
  18. package/dist/adapters/types.js.map +1 -0
  19. package/dist/cli/border-client.d.ts +8 -0
  20. package/dist/cli/border-client.js +11 -0
  21. package/dist/cli/border-client.js.map +1 -0
  22. package/dist/cli/commands/__ask-cancel.d.ts +35 -0
  23. package/dist/cli/commands/__ask-cancel.js +91 -0
  24. package/dist/cli/commands/__ask-cancel.js.map +1 -0
  25. package/dist/cli/commands/__ask-refresh.d.ts +40 -0
  26. package/dist/cli/commands/__ask-refresh.js +54 -0
  27. package/dist/cli/commands/__ask-refresh.js.map +1 -0
  28. package/dist/cli/commands/__ask-run.d.ts +43 -0
  29. package/dist/cli/commands/__ask-run.js +126 -0
  30. package/dist/cli/commands/__ask-run.js.map +1 -0
  31. package/dist/cli/commands/__ask-send.d.ts +50 -0
  32. package/dist/cli/commands/__ask-send.js +138 -0
  33. package/dist/cli/commands/__ask-send.js.map +1 -0
  34. package/dist/cli/commands/__preview-card.d.ts +31 -0
  35. package/dist/cli/commands/__preview-card.js +72 -0
  36. package/dist/cli/commands/__preview-card.js.map +1 -0
  37. package/dist/cli/commands/ask.d.ts +50 -0
  38. package/dist/cli/commands/ask.js +240 -0
  39. package/dist/cli/commands/ask.js.map +1 -0
  40. package/dist/cli/commands/auto.d.ts +12 -0
  41. package/dist/cli/commands/auto.js +28 -0
  42. package/dist/cli/commands/auto.js.map +1 -0
  43. package/dist/cli/commands/cockpit.d.ts +14 -0
  44. package/dist/cli/commands/cockpit.js +52 -0
  45. package/dist/cli/commands/cockpit.js.map +1 -0
  46. package/dist/cli/commands/daemon.d.ts +75 -0
  47. package/dist/cli/commands/daemon.js +258 -0
  48. package/dist/cli/commands/daemon.js.map +1 -0
  49. package/dist/cli/commands/doctor.d.ts +6 -0
  50. package/dist/cli/commands/doctor.js +159 -0
  51. package/dist/cli/commands/doctor.js.map +1 -0
  52. package/dist/cli/commands/grep.d.ts +2 -0
  53. package/dist/cli/commands/grep.js +52 -0
  54. package/dist/cli/commands/grep.js.map +1 -0
  55. package/dist/cli/commands/index-cmd.d.ts +2 -0
  56. package/dist/cli/commands/index-cmd.js +29 -0
  57. package/dist/cli/commands/index-cmd.js.map +1 -0
  58. package/dist/cli/commands/ls.d.ts +30 -0
  59. package/dist/cli/commands/ls.js +95 -0
  60. package/dist/cli/commands/ls.js.map +1 -0
  61. package/dist/cli/commands/overlay.d.ts +26 -0
  62. package/dist/cli/commands/overlay.js +216 -0
  63. package/dist/cli/commands/overlay.js.map +1 -0
  64. package/dist/cli/commands/pick.d.ts +59 -0
  65. package/dist/cli/commands/pick.js +254 -0
  66. package/dist/cli/commands/pick.js.map +1 -0
  67. package/dist/cli/commands/picker-rows.d.ts +17 -0
  68. package/dist/cli/commands/picker-rows.js +47 -0
  69. package/dist/cli/commands/picker-rows.js.map +1 -0
  70. package/dist/cli/commands/resume.d.ts +25 -0
  71. package/dist/cli/commands/resume.js +88 -0
  72. package/dist/cli/commands/resume.js.map +1 -0
  73. package/dist/cli/commands/run.d.ts +13 -0
  74. package/dist/cli/commands/run.js +78 -0
  75. package/dist/cli/commands/run.js.map +1 -0
  76. package/dist/cli/commands/setup.d.ts +37 -0
  77. package/dist/cli/commands/setup.js +200 -0
  78. package/dist/cli/commands/setup.js.map +1 -0
  79. package/dist/cli/commands/show.d.ts +2 -0
  80. package/dist/cli/commands/show.js +24 -0
  81. package/dist/cli/commands/show.js.map +1 -0
  82. package/dist/cli/commands/summarize.d.ts +2 -0
  83. package/dist/cli/commands/summarize.js +59 -0
  84. package/dist/cli/commands/summarize.js.map +1 -0
  85. package/dist/cli/commands/tmux.d.ts +11 -0
  86. package/dist/cli/commands/tmux.js +90 -0
  87. package/dist/cli/commands/tmux.js.map +1 -0
  88. package/dist/cli/commands/watch.d.ts +2 -0
  89. package/dist/cli/commands/watch.js +76 -0
  90. package/dist/cli/commands/watch.js.map +1 -0
  91. package/dist/cli/format.d.ts +74 -0
  92. package/dist/cli/format.js +242 -0
  93. package/dist/cli/format.js.map +1 -0
  94. package/dist/cli/gmux-render.d.ts +11 -0
  95. package/dist/cli/gmux-render.js +60 -0
  96. package/dist/cli/gmux-render.js.map +1 -0
  97. package/dist/cli/main.d.ts +8 -0
  98. package/dist/cli/main.js +145 -0
  99. package/dist/cli/main.js.map +1 -0
  100. package/dist/cli/overlay-ask.d.ts +13 -0
  101. package/dist/cli/overlay-ask.js +32 -0
  102. package/dist/cli/overlay-ask.js.map +1 -0
  103. package/dist/cli/overlay.d.ts +26 -0
  104. package/dist/cli/overlay.js +149 -0
  105. package/dist/cli/overlay.js.map +1 -0
  106. package/dist/cli/picker.d.ts +308 -0
  107. package/dist/cli/picker.js +642 -0
  108. package/dist/cli/picker.js.map +1 -0
  109. package/dist/cli/preview.d.ts +87 -0
  110. package/dist/cli/preview.js +292 -0
  111. package/dist/cli/preview.js.map +1 -0
  112. package/dist/cli/tmux-label.d.ts +50 -0
  113. package/dist/cli/tmux-label.js +146 -0
  114. package/dist/cli/tmux-label.js.map +1 -0
  115. package/dist/core/errors.d.ts +54 -0
  116. package/dist/core/errors.js +91 -0
  117. package/dist/core/errors.js.map +1 -0
  118. package/dist/core/fingerprint.d.ts +21 -0
  119. package/dist/core/fingerprint.js +59 -0
  120. package/dist/core/fingerprint.js.map +1 -0
  121. package/dist/core/gmux-types.d.ts +102 -0
  122. package/dist/core/gmux-types.js +13 -0
  123. package/dist/core/gmux-types.js.map +1 -0
  124. package/dist/core/pane-state.d.ts +5 -0
  125. package/dist/core/pane-state.js +15 -0
  126. package/dist/core/pane-state.js.map +1 -0
  127. package/dist/core/paths.d.ts +68 -0
  128. package/dist/core/paths.js +106 -0
  129. package/dist/core/paths.js.map +1 -0
  130. package/dist/core/proc-tree.d.ts +9 -0
  131. package/dist/core/proc-tree.js +33 -0
  132. package/dist/core/proc-tree.js.map +1 -0
  133. package/dist/core/text.d.ts +34 -0
  134. package/dist/core/text.js +126 -0
  135. package/dist/core/text.js.map +1 -0
  136. package/dist/core/types.d.ts +322 -0
  137. package/dist/core/types.js +10 -0
  138. package/dist/core/types.js.map +1 -0
  139. package/dist/services/ask-transcript.d.ts +256 -0
  140. package/dist/services/ask-transcript.js +544 -0
  141. package/dist/services/ask-transcript.js.map +1 -0
  142. package/dist/services/ask.d.ts +54 -0
  143. package/dist/services/ask.js +161 -0
  144. package/dist/services/ask.js.map +1 -0
  145. package/dist/services/auto-summarize.d.ts +188 -0
  146. package/dist/services/auto-summarize.js +415 -0
  147. package/dist/services/auto-summarize.js.map +1 -0
  148. package/dist/services/concurrency.d.ts +2 -0
  149. package/dist/services/concurrency.js +16 -0
  150. package/dist/services/concurrency.js.map +1 -0
  151. package/dist/services/config.d.ts +131 -0
  152. package/dist/services/config.js +325 -0
  153. package/dist/services/config.js.map +1 -0
  154. package/dist/services/daemon-client.d.ts +9 -0
  155. package/dist/services/daemon-client.js +34 -0
  156. package/dist/services/daemon-client.js.map +1 -0
  157. package/dist/services/daemon-socket.d.ts +30 -0
  158. package/dist/services/daemon-socket.js +76 -0
  159. package/dist/services/daemon-socket.js.map +1 -0
  160. package/dist/services/daemon.d.ts +43 -0
  161. package/dist/services/daemon.js +106 -0
  162. package/dist/services/daemon.js.map +1 -0
  163. package/dist/services/distill.d.ts +39 -0
  164. package/dist/services/distill.js +93 -0
  165. package/dist/services/distill.js.map +1 -0
  166. package/dist/services/guardian.d.ts +26 -0
  167. package/dist/services/guardian.js +71 -0
  168. package/dist/services/guardian.js.map +1 -0
  169. package/dist/services/index-store.d.ts +36 -0
  170. package/dist/services/index-store.js +125 -0
  171. package/dist/services/index-store.js.map +1 -0
  172. package/dist/services/log-rotation.d.ts +3 -0
  173. package/dist/services/log-rotation.js +28 -0
  174. package/dist/services/log-rotation.js.map +1 -0
  175. package/dist/services/pane-links.d.ts +10 -0
  176. package/dist/services/pane-links.js +47 -0
  177. package/dist/services/pane-links.js.map +1 -0
  178. package/dist/services/pane-process.d.ts +95 -0
  179. package/dist/services/pane-process.js +183 -0
  180. package/dist/services/pane-process.js.map +1 -0
  181. package/dist/services/pane-registry.d.ts +24 -0
  182. package/dist/services/pane-registry.js +40 -0
  183. package/dist/services/pane-registry.js.map +1 -0
  184. package/dist/services/provider-process.d.ts +37 -0
  185. package/dist/services/provider-process.js +105 -0
  186. package/dist/services/provider-process.js.map +1 -0
  187. package/dist/services/providers.d.ts +76 -0
  188. package/dist/services/providers.js +104 -0
  189. package/dist/services/providers.js.map +1 -0
  190. package/dist/services/resolve.d.ts +3 -0
  191. package/dist/services/resolve.js +18 -0
  192. package/dist/services/resolve.js.map +1 -0
  193. package/dist/services/resources.d.ts +17 -0
  194. package/dist/services/resources.js +113 -0
  195. package/dist/services/resources.js.map +1 -0
  196. package/dist/services/search.d.ts +29 -0
  197. package/dist/services/search.js +135 -0
  198. package/dist/services/search.js.map +1 -0
  199. package/dist/services/semantic-gate.d.ts +13 -0
  200. package/dist/services/semantic-gate.js +23 -0
  201. package/dist/services/semantic-gate.js.map +1 -0
  202. package/dist/services/semantic.d.ts +113 -0
  203. package/dist/services/semantic.js +216 -0
  204. package/dist/services/semantic.js.map +1 -0
  205. package/dist/services/sensors.d.ts +92 -0
  206. package/dist/services/sensors.js +246 -0
  207. package/dist/services/sensors.js.map +1 -0
  208. package/dist/services/summarize.d.ts +84 -0
  209. package/dist/services/summarize.js +230 -0
  210. package/dist/services/summarize.js.map +1 -0
  211. package/dist/services/tmux-gateway.d.ts +17 -0
  212. package/dist/services/tmux-gateway.js +10 -0
  213. package/dist/services/tmux-gateway.js.map +1 -0
  214. package/dist/services/tmux-resolve.d.ts +54 -0
  215. package/dist/services/tmux-resolve.js +0 -0
  216. package/dist/services/tmux-resolve.js.map +1 -0
  217. package/dist/services/tmux.d.ts +32 -0
  218. package/dist/services/tmux.js +107 -0
  219. package/dist/services/tmux.js.map +1 -0
  220. package/dist/services/views.d.ts +7 -0
  221. package/dist/services/views.js +18 -0
  222. package/dist/services/views.js.map +1 -0
  223. package/dist/services/watch.d.ts +36 -0
  224. package/dist/services/watch.js +98 -0
  225. package/dist/services/watch.js.map +1 -0
  226. package/dist/services/workspace.d.ts +19 -0
  227. package/dist/services/workspace.js +88 -0
  228. package/dist/services/workspace.js.map +1 -0
  229. package/package.json +64 -0
@@ -0,0 +1,52 @@
1
+ import { SCHEMA_VERSION } from "../../core/types.js";
2
+ import { relativeAge } from "../../core/text.js";
3
+ import { loadRecords } from "../../services/views.js";
4
+ import { searchSessions } from "../../services/search.js";
5
+ import { bold, cyan, dim, jsonEnvelope, sessionLabel } from "../format.js";
6
+ import { toFilters } from "./ls.js";
7
+ export function registerGrep(program) {
8
+ program
9
+ .command("grep <query>")
10
+ .description("search the full text of every transcript, grouped by session")
11
+ .option("--harness <id>", "only this harness")
12
+ .option("-p, --project <name>", "only sessions whose project matches")
13
+ .option("-s, --since <when>", "only sessions newer than this (3d, 12h, 2w)")
14
+ .option("-n, --limit <count>", "max sessions to report", "20")
15
+ .option("-e, --regex", "treat the query as a regular expression")
16
+ .option("-C, --case-sensitive", "match case")
17
+ .option("--include-sidechains", "include subagent transcripts")
18
+ .option("--include-automated", "include non-interactive runs (claude -p, codex exec)")
19
+ .option("--json", "emit JSON for scripts and agents")
20
+ .action(async (query, options) => {
21
+ // Search every session the filters allow, then cap the *results*, not the
22
+ // corpus — capping the corpus first would silently hide matches.
23
+ const filters = toFilters(options, 0);
24
+ delete filters.limit;
25
+ const records = await loadRecords(filters);
26
+ const limit = options.limit ? Number.parseInt(options.limit, 10) : 20;
27
+ const hits = await searchSessions({
28
+ records,
29
+ query,
30
+ regex: options.regex === true,
31
+ caseSensitive: options.caseSensitive === true,
32
+ maxSessions: limit,
33
+ });
34
+ if (options.json) {
35
+ process.stdout.write(`${jsonEnvelope(SCHEMA_VERSION, hits)}\n`);
36
+ return;
37
+ }
38
+ if (hits.length === 0) {
39
+ process.stdout.write(`${dim(`No session mentions "${query}".`)}\n`);
40
+ return;
41
+ }
42
+ for (const hit of hits) {
43
+ const { session } = hit;
44
+ process.stdout.write(`${bold(cyan(sessionLabel(session)))} ${dim(session.sessionId.slice(0, 8))} ${dim(`${relativeAge(session.updatedAt)} ago · ${hit.matchCount} match${hit.matchCount === 1 ? "" : "es"}`)}\n`);
45
+ for (const snippet of hit.snippets)
46
+ process.stdout.write(` ${dim("…")}${snippet}\n`);
47
+ process.stdout.write("\n");
48
+ }
49
+ process.stdout.write(`${dim(`${hits.length} session${hits.length === 1 ? "" : "s"}. Open one with: gmux show <id>`)}\n`);
50
+ });
51
+ }
52
+ //# sourceMappingURL=grep.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grep.js","sourceRoot":"","sources":["../../../src/cli/commands/grep.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerIndex(program: Command): void;
@@ -0,0 +1,29 @@
1
+ import { SCHEMA_VERSION } from "../../core/types.js";
2
+ import { indexPath } from "../../core/paths.js";
3
+ import { refreshIndex } from "../../services/index-store.js";
4
+ import { dim, green, jsonEnvelope } from "../format.js";
5
+ export function registerIndex(program) {
6
+ program
7
+ .command("index")
8
+ .description("refresh the session index (normally automatic)")
9
+ .option("--rebuild", "re-parse every session, ignoring the cache")
10
+ .option("--json", "emit JSON for scripts and agents")
11
+ .action(async (options) => {
12
+ const started = Date.now();
13
+ const result = await refreshIndex({ force: options.rebuild === true });
14
+ const elapsedMs = Date.now() - started;
15
+ const stats = {
16
+ sessions: result.records.length,
17
+ parsed: result.parsed,
18
+ servedFromCache: result.cached,
19
+ elapsedMs,
20
+ indexPath: indexPath(),
21
+ };
22
+ if (options.json) {
23
+ process.stdout.write(`${jsonEnvelope(SCHEMA_VERSION, stats)}\n`);
24
+ return;
25
+ }
26
+ process.stdout.write(`${green(`✓ ${stats.sessions} sessions indexed`)} ${dim(`(${stats.parsed} parsed, ${stats.servedFromCache} cached, ${elapsedMs}ms)`)}\n${dim(stats.indexPath)}\n`);
27
+ });
28
+ }
29
+ //# sourceMappingURL=index-cmd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-cmd.js","sourceRoot":"","sources":["../../../src/cli/commands/index-cmd.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAExD,MAAM,UAAU,aAAa,CAAC,OAAgB;IAC5C,OAAO;SACJ,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,gDAAgD,CAAC;SAC7D,MAAM,CAAC,WAAW,EAAE,4CAA4C,CAAC;SACjE,MAAM,CAAC,QAAQ,EAAE,kCAAkC,CAAC;SACpD,MAAM,CAAC,KAAK,EAAE,OAA8C,EAAE,EAAE;QAC/D,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC,CAAC;QACvE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC;QAEvC,MAAM,KAAK,GAAG;YACZ,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM;YAC/B,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,eAAe,EAAE,MAAM,CAAC,MAAM;YAC9B,SAAS;YACT,SAAS,EAAE,SAAS,EAAE;SACvB,CAAC;QAEF,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,YAAY,CAAC,cAAc,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YACjE,OAAO;QACT,CAAC;QAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,GAAG,KAAK,CAAC,KAAK,KAAK,CAAC,QAAQ,mBAAmB,CAAC,IAAI,GAAG,CACrD,IAAI,KAAK,CAAC,MAAM,YAAY,KAAK,CAAC,eAAe,YAAY,SAAS,KAAK,CAC5E,KAAK,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAC/B,CAAC;IACJ,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,30 @@
1
+ import type { Command } from "commander";
2
+ import { type ListFilters } from "../../core/types.js";
3
+ export interface LsOptions {
4
+ harness?: string;
5
+ project?: string;
6
+ branch?: string;
7
+ since?: string;
8
+ limit?: string;
9
+ includeSidechains?: boolean;
10
+ includeAutomated?: boolean;
11
+ json?: boolean;
12
+ autoSummarize?: boolean;
13
+ resumeInWindow?: boolean;
14
+ }
15
+ /**
16
+ * Whether `--no-auto-summarize` was passed.
17
+ *
18
+ * MUST be read with `optsWithGlobals`. `--no-auto-summarize` is declared on the
19
+ * ROOT program, and commander does not copy root options into a subcommand's
20
+ * own `opts()` — reading `options.autoSummarize` there yields `undefined`
21
+ * forever, so `undefined !== false` is always true and the flag silently does
22
+ * nothing. That is exactly what `gmux --no-auto-summarize ls` did before this
23
+ * existed: it spent tokens the user had explicitly declined.
24
+ *
25
+ * Shared by `ls`, `pick` and `__picker-rows` so the three cannot drift apart.
26
+ */
27
+ export declare function autoSummarizeRequested(command: Command): boolean;
28
+ /** Shared by `ls` and the picker so both filter identically. */
29
+ export declare function toFilters(options: LsOptions, fallbackLimit: number): ListFilters;
30
+ export declare function registerLs(program: Command): void;
@@ -0,0 +1,95 @@
1
+ import { SCHEMA_VERSION } from "../../core/types.js";
2
+ import { parseSince } from "../../core/text.js";
3
+ import { GmuxError } from "../../core/errors.js";
4
+ import { loadViews } from "../../services/views.js";
5
+ import { inProgressIds, maybeAutoSummarize } from "../../services/auto-summarize.js";
6
+ import { dim, formatLegend, formatRowLines, jsonEnvelope, terminalWidth } from "../format.js";
7
+ /**
8
+ * Whether `--no-auto-summarize` was passed.
9
+ *
10
+ * MUST be read with `optsWithGlobals`. `--no-auto-summarize` is declared on the
11
+ * ROOT program, and commander does not copy root options into a subcommand's
12
+ * own `opts()` — reading `options.autoSummarize` there yields `undefined`
13
+ * forever, so `undefined !== false` is always true and the flag silently does
14
+ * nothing. That is exactly what `gmux --no-auto-summarize ls` did before this
15
+ * existed: it spent tokens the user had explicitly declined.
16
+ *
17
+ * Shared by `ls`, `pick` and `__picker-rows` so the three cannot drift apart.
18
+ */
19
+ export function autoSummarizeRequested(command) {
20
+ return command.optsWithGlobals()["autoSummarize"] !== false;
21
+ }
22
+ /** Shared by `ls` and the picker so both filter identically. */
23
+ export function toFilters(options, fallbackLimit) {
24
+ const filters = {
25
+ includeSidechains: options.includeSidechains === true,
26
+ includeAutomated: options.includeAutomated === true,
27
+ limit: options.limit ? Number.parseInt(options.limit, 10) : fallbackLimit,
28
+ };
29
+ if (options.harness)
30
+ filters.harness = options.harness;
31
+ if (options.project)
32
+ filters.project = options.project;
33
+ if (options.branch)
34
+ filters.branch = options.branch;
35
+ if (options.since) {
36
+ const cutoff = parseSince(options.since);
37
+ if (!cutoff) {
38
+ throw new GmuxError(`Could not understand --since "${options.since}".`, {
39
+ fix: "Use a duration like `3d`, `12h`, `2w`, or an ISO date like `2026-07-01`.",
40
+ exitCode: 2,
41
+ });
42
+ }
43
+ filters.since = cutoff;
44
+ }
45
+ return filters;
46
+ }
47
+ export function registerLs(program) {
48
+ program
49
+ .command("ls")
50
+ .description("list recent sessions, most recent first")
51
+ .option("--harness <id>", "only this harness (claude-code, codex)")
52
+ .option("-p, --project <name>", "only sessions whose project matches")
53
+ .option("-b, --branch <name>", "only sessions whose git branch matches")
54
+ .option("-s, --since <when>", "only sessions newer than this (3d, 12h, 2w, or a date)")
55
+ .option("-n, --limit <count>", "how many to show", "20")
56
+ .option("--include-sidechains", "include subagent transcripts")
57
+ .option("--include-automated", "include non-interactive runs (claude -p, codex exec)")
58
+ .option("--json", "emit JSON for scripts and agents")
59
+ .action(async (options, command) => {
60
+ const views = await loadViews(toFilters(options, 20));
61
+ if (options.json) {
62
+ process.stdout.write(`${jsonEnvelope(SCHEMA_VERSION, views)}\n`);
63
+ return;
64
+ }
65
+ if (views.length === 0) {
66
+ process.stdout.write(`${dim("No sessions matched.")}\n`);
67
+ return;
68
+ }
69
+ // Kick the background pass off BEFORE rendering, over exactly the sessions
70
+ // we are about to show — so `gmux ls -n 50` summarizes all fifty, and the
71
+ // rows it just picked up can be marked ◐ on this very run rather than the
72
+ // next one. Deciding costs a lock write and a spawn; the model calls all
73
+ // happen in the detached child.
74
+ const started = await maybeAutoSummarize({
75
+ records: views.map((v) => v.record),
76
+ enabled: autoSummarizeRequested(command),
77
+ notify: (message) => process.stderr.write(`${dim(message)}\n`),
78
+ });
79
+ // Rows already in flight from an earlier run count too.
80
+ const inProgress = new Set([...(await inProgressIds()), ...started.targetIds]);
81
+ // Wrap to the terminal so a long summary is readable in full. When piped,
82
+ // stay one line per session so `gmux ls | grep` still works.
83
+ const width = process.stdout.isTTY ? terminalWidth() : Number.POSITIVE_INFINITY;
84
+ const now = new Date();
85
+ for (const view of views) {
86
+ for (const line of formatRowLines(view, now, width, inProgress)) {
87
+ process.stdout.write(`${line}\n`);
88
+ }
89
+ }
90
+ const legend = formatLegend(views, inProgress);
91
+ if (legend !== "")
92
+ process.stdout.write(`\n${legend}\n`);
93
+ });
94
+ }
95
+ //# sourceMappingURL=ls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ls.js","sourceRoot":"","sources":["../../../src/cli/commands/ls.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { Command } from "commander";
2
+ import type { SessionView } from "../../core/types.js";
3
+ import { type ResolvedPane } from "../../services/tmux-resolve.js";
4
+ import { type OverlayCell } from "../overlay.js";
5
+ /** A question broadcast to every pane, and the per-session answers as they land. */
6
+ export interface AskBroadcast {
7
+ question: string;
8
+ answers: Map<string, string>;
9
+ }
10
+ /**
11
+ * Pair each resolved pane with its summary view and the in-flight refresh set —
12
+ * and, when a question has been broadcast, this pane's own answer (or the
13
+ * `asking…` state until it lands). Pure, so the pairing is tested without a terminal.
14
+ */
15
+ export declare function buildCells(resolved: readonly ResolvedPane[], views: readonly SessionView[], refreshingIds: ReadonlySet<string>, ask?: AskBroadcast | null): OverlayCell[];
16
+ /**
17
+ * The keys that dismiss the overlay.
18
+ *
19
+ * ctrl-g (`\x07`) is here so the same key that opens the popup also closes it —
20
+ * a toggle, which is what a peek key should feel like. Since the ask box landed
21
+ * every other key types into it, so a close key has to be spelled out; without
22
+ * ctrl-g listed it would fall through and be swallowed as un-printable input.
23
+ * Esc, ctrl-c and ctrl-d are the long-standing exits, kept exactly.
24
+ */
25
+ export declare function isCloseKey(s: string): boolean;
26
+ export declare function registerOverlay(program: Command): void;
@@ -0,0 +1,216 @@
1
+ import { buildAskContext, buildAskPrompt, defaultAskProvider } from "../../services/ask.js";
2
+ import { inProgressIds, maybeAutoSummarize } from "../../services/auto-summarize.js";
3
+ import { mapLimit } from "../../services/concurrency.js";
4
+ import { prunePaneLinks } from "../../services/pane-links.js";
5
+ import { defaultSummaryProvider, summarizeBatch } from "../../services/summarize.js";
6
+ import { listAllPanes, listPanes } from "../../services/tmux.js";
7
+ import { resolvePanesLive } from "../../services/tmux-resolve.js";
8
+ import { attachSummaries, loadCachedRecords, loadRecords } from "../../services/views.js";
9
+ import { renderOverlay } from "../overlay.js";
10
+ import { ASK_BOX_HEIGHT, askBoxLines, askCursorColumn } from "../overlay-ask.js";
11
+ /** How often the overlay repaints while it waits, to fold in landed refreshes. */
12
+ const REPAINT_MS = 1000;
13
+ const CLEAR = "\x1b[2J\x1b[H";
14
+ /**
15
+ * Pair each resolved pane with its summary view and the in-flight refresh set —
16
+ * and, when a question has been broadcast, this pane's own answer (or the
17
+ * `asking…` state until it lands). Pure, so the pairing is tested without a terminal.
18
+ */
19
+ export function buildCells(resolved, views, refreshingIds, ask) {
20
+ const bySession = new Map(views.map((v) => [v.record.sessionId, v]));
21
+ return resolved.map(({ pane, record }) => {
22
+ const cell = {
23
+ pane,
24
+ view: record ? bySession.get(record.sessionId) ?? { record, summary: null } : null,
25
+ refreshing: record ? refreshingIds.has(record.sessionId) : false,
26
+ };
27
+ if (ask && record) {
28
+ cell.answer = ask.answers.get(record.sessionId) ?? null;
29
+ cell.asking = cell.answer == null;
30
+ }
31
+ return cell;
32
+ });
33
+ }
34
+ /**
35
+ * The keys that dismiss the overlay.
36
+ *
37
+ * ctrl-g (`\x07`) is here so the same key that opens the popup also closes it —
38
+ * a toggle, which is what a peek key should feel like. Since the ask box landed
39
+ * every other key types into it, so a close key has to be spelled out; without
40
+ * ctrl-g listed it would fall through and be swallowed as un-printable input.
41
+ * Esc, ctrl-c and ctrl-d are the long-standing exits, kept exactly.
42
+ */
43
+ export function isCloseKey(s) {
44
+ return s === "\x1b" || s === "\x03" || s === "\x04" || s === "\x07";
45
+ }
46
+ const rows = () => process.stdout.rows || 24;
47
+ const cols = () => process.stdout.columns || 80;
48
+ /** The card frame for the resolved panes — re-reads only the (small) summaries. */
49
+ async function cardsFrame(resolved, ask, forcing) {
50
+ const present = resolved
51
+ .map((r) => r.record)
52
+ .filter((r) => r !== null);
53
+ const views = await attachSummaries(present);
54
+ const refreshing = new Set([...(await inProgressIds()), ...forcing]);
55
+ return renderOverlay(buildCells(resolved, views, refreshing, ask));
56
+ }
57
+ /**
58
+ * Resolve the window's panes with GLOBAL de-duplication, so a fresh pane can't
59
+ * claim a session another window's pane already owns. Resolves every pane in the
60
+ * server, then keeps just this window's.
61
+ */
62
+ async function resolveWindow(windowId, records) {
63
+ const all = await listAllPanes();
64
+ const links = await prunePaneLinks(all.map((p) => p.paneId));
65
+ const windowPaneIds = new Set((await listPanes(windowId)).map((p) => p.paneId));
66
+ const resolvedAll = await resolvePanesLive(all, records, links);
67
+ return resolvedAll.filter((r) => windowPaneIds.has(r.pane.paneId));
68
+ }
69
+ /** The ask box drawn across the bottom rows, with the cursor left in the field. */
70
+ function boxFrame(input) {
71
+ const top = rows() - ASK_BOX_HEIGHT + 1; // 1-based first box row
72
+ let out = "";
73
+ askBoxLines(input, cols()).forEach((line, i) => {
74
+ out += `\x1b[${top + i};1H${line}`;
75
+ });
76
+ out += `\x1b[${top + 1};${askCursorColumn(input, cols())}H`; // cursor into the input line
77
+ return out;
78
+ }
79
+ /** One concise answer per session — asked in parallel, but bounded. */
80
+ const ASK_CONCURRENCY = 6;
81
+ async function runOverlay(windowId) {
82
+ // A peek must feel instant. We reach this command only because `display-popup`
83
+ // launched it, which already proves tmux >= 3.2. Resolve ONCE from the cache;
84
+ // repaints re-read only summaries, so an open overlay is not re-scanning
85
+ // thousands of files every second.
86
+ let resolved = await resolveWindow(windowId, await loadCachedRecords());
87
+ const state = { input: "", ask: null };
88
+ const forcing = new Set(); // sessions being force-regenerated right now (ctrl-r)
89
+ let busy = false; // a broadcast is in flight
90
+ let provider = null;
91
+ void defaultAskProvider()
92
+ .then((p) => (provider = p))
93
+ .catch(() => { });
94
+ // Always cards (with any per-pane answers) above, the ask box below.
95
+ const drawAll = async () => {
96
+ process.stdout.write(CLEAR + (await cardsFrame(resolved, state.ask, forcing)) + boxFrame(state.input));
97
+ };
98
+ await drawAll();
99
+ // Off the critical path: upgrade to the full index, re-resolve, and kick stale
100
+ // cards to refresh in the background — targeting exactly the panes on screen.
101
+ void (async () => {
102
+ resolved = await resolveWindow(windowId, await loadRecords());
103
+ if (!state.ask && !busy)
104
+ await drawAll();
105
+ const present = resolved.map((r) => r.record).filter((r) => r !== null);
106
+ await maybeAutoSummarize({ records: present, force: true });
107
+ })().catch(() => { });
108
+ // Repaint the cards while browsing (not while a broadcast owns the screen).
109
+ const timer = setInterval(() => {
110
+ if (!state.ask && !busy)
111
+ void drawAll().catch(() => { });
112
+ }, REPAINT_MS);
113
+ /** Broadcast the question to every pane's session, answering each on its card. */
114
+ const broadcast = async (question) => {
115
+ const present = resolved.map((r) => r.record).filter((r) => r !== null);
116
+ const views = await attachSummaries(present);
117
+ const byId = new Map(views.map((v) => [v.record.sessionId, v]));
118
+ const answers = new Map();
119
+ state.ask = { question, answers };
120
+ if (!provider) {
121
+ for (const r of present)
122
+ answers.set(r.sessionId, "No model configured — run `gmux setup`.");
123
+ await drawAll();
124
+ return;
125
+ }
126
+ busy = true;
127
+ await drawAll(); // every card shows "asking…"
128
+ await mapLimit(present, ASK_CONCURRENCY, async (record) => {
129
+ try {
130
+ const view = byId.get(record.sessionId);
131
+ const context = buildAskContext(view ? [view] : [], record.sessionId, 1);
132
+ const answer = await provider.ask(buildAskPrompt(context, [], question));
133
+ answers.set(record.sessionId, answer.trim());
134
+ }
135
+ catch (error) {
136
+ answers.set(record.sessionId, `ask failed: ${error.message}`);
137
+ }
138
+ await drawAll(); // this card fills in as its answer lands
139
+ });
140
+ busy = false;
141
+ await drawAll();
142
+ };
143
+ /** ctrl-r: regenerate every visible pane's summary now, ignoring the divergence gate. */
144
+ const forceRefresh = async () => {
145
+ const present = resolved.map((r) => r.record).filter((r) => r !== null);
146
+ if (present.length === 0)
147
+ return;
148
+ present.forEach((r) => forcing.add(r.sessionId));
149
+ await drawAll(); // cards show refreshing…
150
+ try {
151
+ const summaryProvider = await defaultSummaryProvider();
152
+ if (summaryProvider && (await summaryProvider.isAvailable())) {
153
+ await summarizeBatch(present, summaryProvider, { force: true });
154
+ }
155
+ }
156
+ finally {
157
+ present.forEach((r) => forcing.delete(r.sessionId));
158
+ await drawAll();
159
+ }
160
+ };
161
+ const stdin = process.stdin;
162
+ if (stdin.isTTY)
163
+ stdin.setRawMode(true);
164
+ stdin.resume();
165
+ await new Promise((done) => {
166
+ stdin.on("data", (buf) => {
167
+ void (async () => {
168
+ const s = buf.toString();
169
+ if (isCloseKey(s))
170
+ return done(); // Esc / ctrl-c / ctrl-d / ctrl-g
171
+ if (s.startsWith("\x1b"))
172
+ return; // an arrow or other escape sequence — ignore
173
+ if (s === "\x12")
174
+ return void forceRefresh(); // ctrl-r: force a summary refresh now
175
+ if (busy)
176
+ return; // a broadcast is landing; ignore keys (Esc handled above)
177
+ if (s === "\r" || s === "\n") {
178
+ const question = state.input.trim();
179
+ state.input = "";
180
+ if (!question) {
181
+ // Empty Enter clears the answers, returning the cards to their summaries.
182
+ if (state.ask) {
183
+ state.ask = null;
184
+ await drawAll();
185
+ }
186
+ return;
187
+ }
188
+ await broadcast(question);
189
+ return;
190
+ }
191
+ if (s === "\x7f" || s === "\b") {
192
+ state.input = state.input.slice(0, -1);
193
+ process.stdout.write(boxFrame(state.input));
194
+ return;
195
+ }
196
+ const printable = [...s].filter((c) => c >= " " && c <= "~").join("");
197
+ if (printable) {
198
+ state.input += printable;
199
+ process.stdout.write(boxFrame(state.input));
200
+ }
201
+ })().catch(() => { });
202
+ });
203
+ });
204
+ clearInterval(timer);
205
+ process.stdout.write("\x1b[2J\x1b[H");
206
+ process.exit(0);
207
+ }
208
+ export function registerOverlay(program) {
209
+ program
210
+ .command("overlay <window>")
211
+ .description("draw every pane's summary in place (used by the tmux ctrl-g binding)")
212
+ .action(async (windowId) => {
213
+ await runOverlay(windowId);
214
+ });
215
+ }
216
+ //# sourceMappingURL=overlay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overlay.js","sourceRoot":"","sources":["../../../src/cli/commands/overlay.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ import type { Command } from "commander";
2
+ import { type LsOptions } from "./ls.js";
3
+ /** The hidden command fzf's ctrl-r binding runs. Not a thing a person runs. */
4
+ export declare const PICKER_ROWS_COMMAND = "__picker-rows";
5
+ export interface PickerRowsOptions extends LsOptions {
6
+ /** The parent's measured list width. The reload child's own stdout is a pipe. */
7
+ width?: string;
8
+ }
9
+ /**
10
+ * The filter flags this picker was opened with, as argv.
11
+ *
12
+ * One copy, because every command the picker spawns must describe the *same*
13
+ * window. A filter that drifts in one of several copies is the silent
14
+ * wrong-window bug the `pickerAskArgs` comment below exists to warn about —
15
+ * nothing errors, the answers are just about other sessions.
16
+ *
17
+ * Values are NOT quoted here — the caller joins and quotes, because argv and a
18
+ * shell command string want different escaping.
19
+ */
20
+ export declare function filterArgs(options: LsOptions): string[];
21
+ /**
22
+ * The argv behind ctrl-o, reproducing this picker's filter set for `gmux ask`.
23
+ *
24
+ * Pure, and separate from `pickerReloadArgs` only because the two target
25
+ * different commands — they carry the same filters for the same reason.
26
+ *
27
+ * THE FILTERS ARE THE POINT. `gmux ask` builds its own window; left to its
28
+ * defaults it takes the 20 most recent sessions across every project, which for
29
+ * `gmux pick -p webshop` (or any pick past the 20th row) does not contain the
30
+ * session you are highlighting. `--focus` then finds nothing, resolves to null,
31
+ * and the chat answers about sessions you were not looking at — with no sign
32
+ * anything went wrong.
33
+ *
34
+ * `-n` is forwarded too: the window ask reasons over should be the list you are
35
+ * looking at, not a shorter one it chose for itself.
36
+ *
37
+ * `--focus {1}` is NOT added here. fzf substitutes that token, so it is appended
38
+ * unquoted by the picker; a shell-quoted `{1}` would arrive as a literal.
39
+ */
40
+ export declare function pickerAskArgs(options: LsOptions): string[];
41
+ /**
42
+ * The argv that reproduces this picker's filter set, for fzf's reload binding.
43
+ *
44
+ * Pure, so the thing a refresh actually runs is testable without spawning fzf.
45
+ *
46
+ * `--width` is passed explicitly: the reload child's stdout is a pipe, so it
47
+ * cannot measure the terminal and would fall back to a default width, reflowing
48
+ * every row on refresh. Only the parent, inside fzf, knows the real width.
49
+ */
50
+ export declare function pickerReloadArgs(options: LsOptions, width: number, autoSummarize?: boolean): string[];
51
+ /**
52
+ * The bare `gmux` command: pick a recent session, then resume it.
53
+ * This is the whole point of the tool — everything else is in service of it.
54
+ *
55
+ * Registered as commander's *default* command rather than as options on the root
56
+ * program. Hanging `-n`/`-p` off the root would shadow the identically-named
57
+ * flags on `gmux ls`, so `gmux ls -n 8` would silently ignore the 8.
58
+ */
59
+ export declare function registerPick(program: Command): void;