@creativeintelligence/abbie 0.1.6 → 0.1.8

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 (141) hide show
  1. package/bin/dev.js +1 -49
  2. package/bin/run.js +42 -49
  3. package/dist/cli/commands/project/add.d.ts +0 -1
  4. package/dist/cli/commands/project/add.js +16 -52
  5. package/dist/cli/commands/project/list.js +13 -93
  6. package/dist/cli/commands/project/remove.d.ts +0 -2
  7. package/dist/cli/commands/project/remove.js +11 -28
  8. package/dist/cli/commands/session/list.js +3 -12
  9. package/dist/cli/commands/session/mark-done.js +1 -7
  10. package/dist/cli/commands/session/start.d.ts +0 -1
  11. package/dist/cli/commands/session/start.js +5 -7
  12. package/dist/lib/active-sessions.d.ts +0 -12
  13. package/dist/lib/active-sessions.js +6 -175
  14. package/dist/lib/project-path.d.ts +6 -0
  15. package/dist/lib/project-path.js +21 -0
  16. package/dist/lib.d.ts +1 -2
  17. package/dist/lib.js +2 -4
  18. package/oclif.manifest.json +2569 -6368
  19. package/package.json +21 -10
  20. package/dist/cli/commands/backlog/add.d.ts +0 -22
  21. package/dist/cli/commands/backlog/add.js +0 -65
  22. package/dist/cli/commands/backlog/claim.d.ts +0 -19
  23. package/dist/cli/commands/backlog/claim.js +0 -45
  24. package/dist/cli/commands/backlog/complete.d.ts +0 -18
  25. package/dist/cli/commands/backlog/complete.js +0 -42
  26. package/dist/cli/commands/backlog/list.d.ts +0 -20
  27. package/dist/cli/commands/backlog/list.js +0 -91
  28. package/dist/cli/commands/backlog/pick.d.ts +0 -18
  29. package/dist/cli/commands/backlog/pick.js +0 -42
  30. package/dist/cli/commands/backlog/sync.d.ts +0 -24
  31. package/dist/cli/commands/backlog/sync.js +0 -109
  32. package/dist/cli/commands/daemon.d.ts +0 -56
  33. package/dist/cli/commands/daemon.js +0 -1465
  34. package/dist/cli/commands/docs/lint.d.ts +0 -18
  35. package/dist/cli/commands/docs/lint.js +0 -82
  36. package/dist/cli/commands/docs/sync.d.ts +0 -19
  37. package/dist/cli/commands/docs/sync.js +0 -76
  38. package/dist/cli/commands/gc.d.ts +0 -29
  39. package/dist/cli/commands/gc.js +0 -211
  40. package/dist/cli/commands/index.d.ts +0 -36
  41. package/dist/cli/commands/index.js +0 -228
  42. package/dist/cli/commands/panes/broker.d.ts +0 -17
  43. package/dist/cli/commands/panes/broker.js +0 -57
  44. package/dist/cli/commands/panes/pipe-sink.d.ts +0 -17
  45. package/dist/cli/commands/panes/pipe-sink.js +0 -90
  46. package/dist/cli/commands/panes/snapshot.d.ts +0 -20
  47. package/dist/cli/commands/panes/snapshot.js +0 -125
  48. package/dist/cli/commands/preview/init.d.ts +0 -25
  49. package/dist/cli/commands/preview/init.js +0 -159
  50. package/dist/cli/commands/preview/sync.d.ts +0 -23
  51. package/dist/cli/commands/preview/sync.js +0 -144
  52. package/dist/cli/commands/preview/watch.d.ts +0 -24
  53. package/dist/cli/commands/preview/watch.js +0 -153
  54. package/dist/cli/commands/resource/acquire.d.ts +0 -21
  55. package/dist/cli/commands/resource/acquire.js +0 -90
  56. package/dist/cli/commands/resource/list.d.ts +0 -15
  57. package/dist/cli/commands/resource/list.js +0 -61
  58. package/dist/cli/commands/resource/release.d.ts +0 -18
  59. package/dist/cli/commands/resource/release.js +0 -50
  60. package/dist/cli/commands/resource/wait.d.ts +0 -21
  61. package/dist/cli/commands/resource/wait.js +0 -73
  62. package/dist/cli/commands/session/view.d.ts +0 -24
  63. package/dist/cli/commands/session/view.js +0 -145
  64. package/dist/cli/commands/start.d.ts +0 -37
  65. package/dist/cli/commands/start.js +0 -234
  66. package/dist/cli/commands/triage/claim.d.ts +0 -23
  67. package/dist/cli/commands/triage/claim.js +0 -186
  68. package/dist/cli/commands/triage/list.d.ts +0 -22
  69. package/dist/cli/commands/triage/list.js +0 -112
  70. package/dist/cli/commands/triage/next.d.ts +0 -18
  71. package/dist/cli/commands/triage/next.js +0 -63
  72. package/dist/cli/commands/triage/pull.d.ts +0 -19
  73. package/dist/cli/commands/triage/pull.js +0 -82
  74. package/dist/cli/commands/triage/stats.d.ts +0 -16
  75. package/dist/cli/commands/triage/stats.js +0 -69
  76. package/dist/cli/commands/tunnel/list.d.ts +0 -16
  77. package/dist/cli/commands/tunnel/list.js +0 -98
  78. package/dist/cli/commands/tunnel/start.d.ts +0 -24
  79. package/dist/cli/commands/tunnel/start.js +0 -107
  80. package/dist/cli/commands/tunnel/stop.d.ts +0 -20
  81. package/dist/cli/commands/tunnel/stop.js +0 -90
  82. package/dist/cli/commands/tunnel/url.d.ts +0 -21
  83. package/dist/cli/commands/tunnel/url.js +0 -70
  84. package/dist/cli/commands/windows/context.d.ts +0 -18
  85. package/dist/cli/commands/windows/context.js +0 -326
  86. package/dist/cli/commands/windows/focus.d.ts +0 -17
  87. package/dist/cli/commands/windows/focus.js +0 -103
  88. package/dist/cli/commands/windows/list.d.ts +0 -21
  89. package/dist/cli/commands/windows/list.js +0 -172
  90. package/dist/cli/commands/windows/map.d.ts +0 -17
  91. package/dist/cli/commands/windows/map.js +0 -168
  92. package/dist/cli/commands/windows/read.d.ts +0 -21
  93. package/dist/cli/commands/windows/read.js +0 -241
  94. package/dist/cli/commands/windows/search.d.ts +0 -24
  95. package/dist/cli/commands/windows/search.js +0 -171
  96. package/dist/cli/commands/windows/show.d.ts +0 -19
  97. package/dist/cli/commands/windows/show.js +0 -165
  98. package/dist/cli/commands/windows/watch.d.ts +0 -19
  99. package/dist/cli/commands/windows/watch.js +0 -241
  100. package/dist/lib/managed-session.d.ts +0 -27
  101. package/dist/lib/managed-session.js +0 -105
  102. package/dist/lib/panes/broker.d.ts +0 -130
  103. package/dist/lib/panes/broker.js +0 -97
  104. package/dist/lib/panes/index.d.ts +0 -2
  105. package/dist/lib/panes/index.js +0 -1
  106. package/dist/lib/panes/server.d.ts +0 -17
  107. package/dist/lib/panes/server.js +0 -308
  108. package/dist/lib/preview/manager.d.ts +0 -77
  109. package/dist/lib/preview/manager.js +0 -369
  110. package/dist/lib/preview/schema.d.ts +0 -2
  111. package/dist/lib/preview/schema.js +0 -32
  112. package/dist/lib/preview/sprite.d.ts +0 -85
  113. package/dist/lib/preview/sprite.js +0 -321
  114. package/dist/lib/preview/watcher.d.ts +0 -63
  115. package/dist/lib/preview/watcher.js +0 -185
  116. package/dist/lib/project-identity.d.ts +0 -16
  117. package/dist/lib/project-identity.js +0 -75
  118. package/dist/lib/tmux/bridge.d.ts +0 -133
  119. package/dist/lib/tmux/bridge.js +0 -315
  120. package/dist/lib/tmux/context.d.ts +0 -82
  121. package/dist/lib/tmux/context.js +0 -239
  122. package/dist/lib/tmux/index.d.ts +0 -8
  123. package/dist/lib/tmux/index.js +0 -11
  124. package/dist/lib/tmux/map.d.ts +0 -57
  125. package/dist/lib/tmux/map.js +0 -198
  126. package/dist/lib/tmux/panes.d.ts +0 -27
  127. package/dist/lib/tmux/panes.js +0 -151
  128. package/dist/lib/tmux/redaction.d.ts +0 -57
  129. package/dist/lib/tmux/redaction.js +0 -152
  130. package/dist/lib/web/analytics.d.ts +0 -63
  131. package/dist/lib/web/analytics.js +0 -168
  132. package/dist/lib/web/server.d.ts +0 -26
  133. package/dist/lib/web/server.js +0 -697
  134. package/dist/lib/web/tmux-bridge.d.ts +0 -7
  135. package/dist/lib/web/tmux-bridge.js +0 -7
  136. package/dist/lib/windows/index.d.ts +0 -3
  137. package/dist/lib/windows/index.js +0 -2
  138. package/dist/lib/windows/inventory.d.ts +0 -21
  139. package/dist/lib/windows/inventory.js +0 -263
  140. package/dist/lib/windows/types.d.ts +0 -46
  141. package/dist/lib/windows/types.js +0 -1
@@ -1,326 +0,0 @@
1
- import { Flags } from "@oclif/core";
2
- import { getBufferLines, getCurrentBufferInfo, getVisibleRange } from "../../../lib/nvim/remote.js";
3
- import { isRunning } from "../../../lib/tmux/index.js";
4
- import { redactContent } from "../../../lib/tmux/redaction.js";
5
- import * as windows from "../../../lib/windows/index.js";
6
- import { BaseCommand } from "../../base-command.js";
7
- function abbreviateHome(path) {
8
- const home = process.env.HOME;
9
- if (!home)
10
- return path;
11
- if (path === home)
12
- return "~";
13
- if (path.startsWith(`${home}/`))
14
- return `~/${path.slice(home.length + 1)}`;
15
- return path;
16
- }
17
- function paneRef(window) {
18
- return `${window.session}:${window.window}.${window.pane}`;
19
- }
20
- function formatPathForDisplay(path, cwd) {
21
- if (!path)
22
- return path;
23
- const normalizedCwd = cwd.endsWith("/") ? cwd : `${cwd}/`;
24
- if (path.startsWith(normalizedCwd)) {
25
- return path.slice(normalizedCwd.length);
26
- }
27
- return abbreviateHome(path);
28
- }
29
- function escapeXml(str) {
30
- return str
31
- .replace(/&/g, "&")
32
- .replace(/</g, "&lt;")
33
- .replace(/>/g, "&gt;")
34
- .replace(/"/g, "&quot;")
35
- .replace(/'/g, "&apos;");
36
- }
37
- function truncateToBytes(str, maxBytes) {
38
- const buf = Buffer.from(str, "utf-8");
39
- if (buf.length <= maxBytes) {
40
- return str;
41
- }
42
- let low = 0;
43
- let high = str.length;
44
- while (low < high) {
45
- const mid = Math.ceil((low + high) / 2);
46
- const slice = str.slice(0, mid);
47
- if (Buffer.byteLength(slice, "utf-8") <= maxBytes) {
48
- low = mid;
49
- }
50
- else {
51
- high = mid - 1;
52
- }
53
- }
54
- return str.slice(0, low);
55
- }
56
- function bytesForLine(line) {
57
- return Buffer.byteLength(`${line}\n`, "utf-8");
58
- }
59
- function buildWindowXmlLines(w, maxBytes) {
60
- const baseLines = [];
61
- baseLines.push(` <window id="${escapeXml(w.id)}" session="${escapeXml(w.session)}" window="${w.window}" pane="${w.pane}" active="${w.active}">`);
62
- baseLines.push(` <cwd>${escapeXml(w.cwd)}</cwd>`);
63
- baseLines.push(` <cmd>${escapeXml(w.cmd)}</cmd>`);
64
- if (w.nvim) {
65
- const attrs = [
66
- `available="${w.nvim.available}"`,
67
- w.nvim.pid !== null ? `pid="${w.nvim.pid}"` : null,
68
- w.nvim.server ? `server="${escapeXml(w.nvim.server)}"` : null,
69
- w.nvim.discoveryMethod ? `discovery="${w.nvim.discoveryMethod}"` : null,
70
- ].filter(Boolean);
71
- baseLines.push(` <nvim ${attrs.join(" ")}>`);
72
- if (w.nvim.buffer) {
73
- const bufAttrs = [
74
- `path="${escapeXml(w.nvim.buffer.path)}"`,
75
- `filetype="${escapeXml(w.nvim.buffer.filetype)}"`,
76
- `modified="${w.nvim.buffer.modified}"`,
77
- w.nvim.buffer.cursor ? `cursor="${escapeXml(w.nvim.buffer.cursor)}"` : null,
78
- ].filter(Boolean);
79
- baseLines.push(` <buffer ${bufAttrs.join(" ")} />`);
80
- }
81
- baseLines.push(" </nvim>");
82
- }
83
- if (w.agent) {
84
- const attrs = [
85
- `type="${w.agent.type}"`,
86
- `pid="${w.agent.pid}"`,
87
- w.agent.sessionId ? `session="${escapeXml(w.agent.sessionId)}"` : null,
88
- w.agent.issue ? `issue="${escapeXml(w.agent.issue)}"` : null,
89
- ].filter(Boolean);
90
- baseLines.push(` <agent ${attrs.join(" ")} />`);
91
- }
92
- baseLines.push(" </window>");
93
- const baseBytes = baseLines.reduce((sum, line) => sum + bytesForLine(line), 0);
94
- if (baseBytes > maxBytes)
95
- return null;
96
- const excerpt = w.nvim?.excerpt;
97
- if (!excerpt || excerpt.lines.length === 0) {
98
- return { lines: baseLines, truncated: false };
99
- }
100
- const insertAt = baseLines.indexOf(" </nvim>");
101
- if (insertAt === -1) {
102
- return { lines: baseLines, truncated: false };
103
- }
104
- const excerptOpen = ` <excerpt scope="${excerpt.scope}" start_line="${excerpt.startLine}" end_line="${excerpt.endLine}" redacted="${excerpt.redacted}">`;
105
- const excerptClose = " </excerpt>";
106
- const skeleton = [...baseLines];
107
- skeleton.splice(insertAt, 0, excerptOpen, excerptClose);
108
- const skeletonBytes = skeleton.reduce((sum, line) => sum + bytesForLine(line), 0);
109
- if (skeletonBytes > maxBytes) {
110
- return { lines: baseLines, truncated: true };
111
- }
112
- const remainingForContent = maxBytes - skeletonBytes;
113
- const contentLines = [];
114
- let used = 0;
115
- let truncated = false;
116
- for (const rawLine of excerpt.lines) {
117
- const escaped = escapeXml(rawLine);
118
- const line = ` ${escaped}`;
119
- const lineBytes = bytesForLine(line);
120
- if (used + lineBytes <= remainingForContent) {
121
- contentLines.push(line);
122
- used += lineBytes;
123
- continue;
124
- }
125
- const remaining = remainingForContent - used;
126
- const indentBytes = bytesForLine(" ");
127
- if (remaining > indentBytes + 8) {
128
- const availableForContent = remaining - indentBytes;
129
- const clipped = truncateToBytes(escaped, Math.max(0, availableForContent));
130
- contentLines.push(` ${clipped}`);
131
- }
132
- truncated = true;
133
- break;
134
- }
135
- const finalLines = [...baseLines];
136
- finalLines.splice(insertAt, 0, excerptOpen, ...contentLines, excerptClose);
137
- return { lines: finalLines, truncated };
138
- }
139
- function toXml(context, maxBytes) {
140
- const lines = [];
141
- let bytes = 0;
142
- let truncated = false;
143
- const closeRoot = "</workspace_context>";
144
- const closeRootBytes = bytesForLine(closeRoot);
145
- const root = `<workspace_context generated_at="${escapeXml(context.generatedAt)}" tmux_running="${context.tmuxRunning}">`;
146
- lines.push(root);
147
- bytes += bytesForLine(root);
148
- for (const w of context.windows) {
149
- const remaining = maxBytes - bytes - closeRootBytes;
150
- if (remaining <= 0) {
151
- truncated = true;
152
- break;
153
- }
154
- const built = buildWindowXmlLines(w, remaining);
155
- if (!built) {
156
- truncated = true;
157
- break;
158
- }
159
- const windowBytes = built.lines.reduce((sum, line) => sum + bytesForLine(line), 0);
160
- if (bytes + windowBytes + closeRootBytes > maxBytes) {
161
- truncated = true;
162
- break;
163
- }
164
- lines.push(...built.lines);
165
- bytes += windowBytes;
166
- if (built.truncated) {
167
- truncated = true;
168
- }
169
- }
170
- lines.push(closeRoot);
171
- return { xml: lines.join("\n"), truncated };
172
- }
173
- export default class WindowsContextCommand extends BaseCommand {
174
- static summary = "Generate workspace context from windows inventory";
175
- static hidden = false;
176
- static examples = [
177
- "$ abbie windows context",
178
- "$ abbie windows context --focus",
179
- "$ abbie windows context --json",
180
- "$ abbie windows context --no-with-buffers",
181
- "$ abbie windows context --max-bytes 100000",
182
- "$ abbie windows context --no-redact",
183
- ];
184
- static flags = {
185
- ...BaseCommand.baseFlags,
186
- focus: Flags.boolean({
187
- description: "Only include the focused window",
188
- default: false,
189
- }),
190
- "with-buffers": Flags.boolean({
191
- description: "Include buffer excerpts (visible range)",
192
- default: true,
193
- allowNo: true,
194
- }),
195
- "max-bytes": Flags.integer({
196
- description: "Maximum output size in bytes",
197
- default: 200000,
198
- }),
199
- redact: Flags.boolean({
200
- description: "Enable redaction",
201
- default: true,
202
- allowNo: true,
203
- }),
204
- };
205
- async execute() {
206
- const { flags } = await this.parse(WindowsContextCommand);
207
- this.parsedFlags = flags;
208
- const generatedAt = new Date().toISOString();
209
- const tmuxRunning = await isRunning();
210
- if (!tmuxRunning) {
211
- const context = {
212
- generatedAt,
213
- tmuxRunning: false,
214
- truncated: false,
215
- windows: [],
216
- };
217
- if (this.jsonEnabled?.()) {
218
- return context;
219
- }
220
- const xml = toXml(context, flags["max-bytes"]);
221
- context.truncated = xml.truncated;
222
- const output = flags.format === "json" ? JSON.stringify(context, null, 2) : xml.xml;
223
- this.log(output);
224
- return context;
225
- }
226
- let states = await windows.inventory({
227
- includeNvim: true,
228
- includeAgent: true,
229
- includeBuffers: false,
230
- });
231
- // Filter to focused window if requested
232
- if (flags.focus) {
233
- const focused = await windows.getFocusedWindow({ includeNvim: true, includeAgent: true });
234
- states = focused ? [focused] : [];
235
- }
236
- const sorted = states.sort((a, b) => {
237
- if (a.window.session !== b.window.session)
238
- return a.window.session.localeCompare(b.window.session);
239
- if (a.window.window !== b.window.window)
240
- return a.window.window - b.window.window;
241
- return a.window.pane - b.window.pane;
242
- });
243
- const ctxWindows = [];
244
- for (const state of sorted) {
245
- const id = state.window.paneId || paneRef(state.window);
246
- const ref = paneRef(state.window);
247
- let buffer = null;
248
- let excerpt = null;
249
- if (state.nvim?.available && state.nvim.serverAddr) {
250
- const info = await getCurrentBufferInfo(state.nvim.serverAddr);
251
- if (info) {
252
- const cursor = info.cursor ? `${info.cursor.line}:${info.cursor.col}` : null;
253
- buffer = {
254
- path: formatPathForDisplay(info.name, state.window.cwd),
255
- filetype: info.filetype,
256
- modified: info.modified,
257
- cursor,
258
- };
259
- if (flags["with-buffers"]) {
260
- const visible = await getVisibleRange(state.nvim.serverAddr, info.bufnr);
261
- if (visible) {
262
- const raw = await getBufferLines(state.nvim.serverAddr, info.bufnr, visible.topLine, visible.bottomLine);
263
- if (raw) {
264
- const joined = raw.join("\n");
265
- const redaction = flags.redact
266
- ? redactContent(joined, "balanced")
267
- : { content: joined, wasRedacted: false };
268
- const lines = redaction.content.split("\n");
269
- excerpt = {
270
- scope: "visible",
271
- startLine: visible.topLine,
272
- endLine: visible.bottomLine,
273
- redacted: flags.redact && redaction.wasRedacted,
274
- lines,
275
- };
276
- }
277
- }
278
- }
279
- }
280
- }
281
- ctxWindows.push({
282
- id,
283
- ref,
284
- session: state.window.session,
285
- window: state.window.window,
286
- windowName: state.window.windowName,
287
- pane: state.window.pane,
288
- active: state.window.active,
289
- cwd: abbreviateHome(state.window.cwd),
290
- cmd: state.window.title,
291
- nvim: state.nvim
292
- ? {
293
- available: state.nvim.available,
294
- pid: state.nvim.pid,
295
- server: state.nvim.serverAddr,
296
- discoveryMethod: state.nvim.discoveryMethod,
297
- buffer,
298
- excerpt,
299
- }
300
- : null,
301
- agent: state.agent
302
- ? {
303
- type: state.agent.type,
304
- pid: state.agent.pid,
305
- sessionId: state.agent.sessionId,
306
- issue: state.agent.issue,
307
- }
308
- : null,
309
- });
310
- }
311
- const context = {
312
- generatedAt,
313
- tmuxRunning: true,
314
- truncated: false,
315
- windows: ctxWindows,
316
- };
317
- if (this.jsonEnabled?.()) {
318
- return context;
319
- }
320
- const xml = toXml(context, flags["max-bytes"]);
321
- context.truncated = xml.truncated;
322
- const output = flags.format === "json" ? JSON.stringify(context, null, 2) : xml.xml;
323
- this.log(output);
324
- return context;
325
- }
326
- }
@@ -1,17 +0,0 @@
1
- import { BaseCommand } from "../../base-command.js";
2
- export default class WindowsFocusCommand extends BaseCommand {
3
- static summary: string;
4
- static hidden: boolean;
5
- static examples: string[];
6
- static flags: {
7
- "with-nvim": import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
- "with-buffers": import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
- format: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
- quiet: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
- "json-errors": import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
- ndjson: import("@oclif/core/interfaces").BooleanFlag<boolean>;
13
- };
14
- execute(): Promise<unknown>;
15
- private printText;
16
- }
17
- //# sourceMappingURL=focus.d.ts.map
@@ -1,103 +0,0 @@
1
- import { Flags } from "@oclif/core";
2
- import { isRunning } from "../../../lib/tmux/index.js";
3
- import * as windows from "../../../lib/windows/index.js";
4
- import { BaseCommand } from "../../base-command.js";
5
- function abbreviateHome(path) {
6
- const home = process.env.HOME;
7
- if (!home)
8
- return path;
9
- if (path === home)
10
- return "~";
11
- if (path.startsWith(`${home}/`))
12
- return `~/${path.slice(home.length + 1)}`;
13
- return path;
14
- }
15
- function windowLabel(window) {
16
- return `${window.window}:${window.windowName}`;
17
- }
18
- export default class WindowsFocusCommand extends BaseCommand {
19
- static summary = "Show focused window";
20
- static hidden = false;
21
- static examples = [
22
- "$ abbie windows focus",
23
- "$ abbie windows focus --no-with-nvim",
24
- "$ abbie windows focus --with-buffers",
25
- "$ abbie windows focus --json",
26
- ];
27
- static flags = {
28
- ...BaseCommand.baseFlags,
29
- "with-nvim": Flags.boolean({
30
- description: "Include nvim details",
31
- default: true,
32
- allowNo: true,
33
- }),
34
- "with-buffers": Flags.boolean({
35
- description: "Include buffer list",
36
- default: false,
37
- }),
38
- };
39
- async execute() {
40
- const { flags } = await this.parse(WindowsFocusCommand);
41
- this.parsedFlags = flags;
42
- const tmuxRunning = await isRunning();
43
- if (!tmuxRunning) {
44
- const result = { tmuxRunning: false, window: null };
45
- if (!this.jsonEnabled?.()) {
46
- this.log("tmux is not running");
47
- }
48
- return result;
49
- }
50
- const includeNvim = flags["with-nvim"] || flags["with-buffers"];
51
- const includeBuffers = flags["with-buffers"];
52
- const state = await windows.getFocusedWindow({
53
- includeNvim,
54
- includeAgent: true,
55
- includeBuffers,
56
- });
57
- const result = { tmuxRunning: true, window: state };
58
- if (!this.jsonEnabled?.()) {
59
- this.printText(result, flags);
60
- }
61
- return result;
62
- }
63
- printText(result, flags) {
64
- if (!result.window) {
65
- this.log("No focused window");
66
- return;
67
- }
68
- const { window, nvim, agent, buffers } = result.window;
69
- this.log("FOCUSED WINDOW");
70
- this.log(`Session: ${window.session}`);
71
- this.log(`Window: ${windowLabel(window)}`);
72
- this.log(`Pane: ${window.paneId || `${window.pane}`} (${window.active ? "active" : "inactive"})`);
73
- this.log(`CWD: ${abbreviateHome(window.cwd)}`);
74
- this.log(`CMD: ${window.title}`);
75
- if (agent) {
76
- this.log(`Agent: ${agent.type} (pid: ${agent.pid}${agent.sessionId ? `, session: ${agent.sessionId}` : ""})`);
77
- }
78
- if (flags["with-nvim"]) {
79
- this.log("");
80
- this.log("NVIM");
81
- if (nvim?.available) {
82
- this.log(`PID: ${nvim.pid ?? "-"}`);
83
- this.log(`Server: ${nvim.serverAddr ?? "-"}${nvim.discoveryMethod ? ` (${nvim.discoveryMethod})` : ""}`);
84
- }
85
- else {
86
- this.log("Not available");
87
- }
88
- }
89
- if (flags["with-buffers"]) {
90
- this.log("");
91
- this.log("BUFFERS");
92
- if (buffers.length === 0) {
93
- this.log("No buffers");
94
- }
95
- else {
96
- for (const buf of buffers) {
97
- const mod = buf.modified ? " [modified]" : "";
98
- this.log(`- ${buf.name || buf.path} (${buf.filetype || "unknown"})${mod}`);
99
- }
100
- }
101
- }
102
- }
103
- }
@@ -1,21 +0,0 @@
1
- import { BaseCommand } from "../../base-command.js";
2
- export default class WindowsListCommand extends BaseCommand {
3
- static summary: string;
4
- static hidden: boolean;
5
- static examples: string[];
6
- static flags: {
7
- session: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
- active: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
- "with-nvim": import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
- "with-agent": import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
- sync: import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
- format: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
- quiet: import("@oclif/core/interfaces").BooleanFlag<boolean>;
14
- "json-errors": import("@oclif/core/interfaces").BooleanFlag<boolean>;
15
- ndjson: import("@oclif/core/interfaces").BooleanFlag<boolean>;
16
- };
17
- execute(): Promise<unknown>;
18
- private syncToConvex;
19
- private printText;
20
- }
21
- //# sourceMappingURL=list.d.ts.map
@@ -1,172 +0,0 @@
1
- import { api, getHttpClient, isConvexConfigured } from "@creativeintelligence/sdk/convex";
2
- import { Flags } from "@oclif/core";
3
- import { getDeviceId } from "../../../lib/device.js";
4
- import { isRunning } from "../../../lib/tmux/index.js";
5
- import * as windows from "../../../lib/windows/index.js";
6
- import { BaseCommand } from "../../base-command.js";
7
- function abbreviateHome(path) {
8
- const home = process.env.HOME;
9
- if (!home)
10
- return path;
11
- if (path === home)
12
- return "~";
13
- if (path.startsWith(`${home}/`))
14
- return `~/${path.slice(home.length + 1)}`;
15
- return path;
16
- }
17
- function paneRef(window) {
18
- return `${window.session}:${window.window}.${window.pane}`;
19
- }
20
- function windowLabel(window) {
21
- return `${window.window}:${window.windowName}`;
22
- }
23
- function pad(value, width) {
24
- if (value.length >= width)
25
- return value;
26
- return value + " ".repeat(width - value.length);
27
- }
28
- function formatRow(state) {
29
- const id = state.window.paneId || paneRef(state.window);
30
- return {
31
- id,
32
- session: state.window.session,
33
- window: windowLabel(state.window),
34
- cmd: state.window.title,
35
- cwd: abbreviateHome(state.window.cwd),
36
- nvim: state.nvim?.available ? "✓" : "-",
37
- agent: state.agent?.type ?? "-",
38
- };
39
- }
40
- export default class WindowsListCommand extends BaseCommand {
41
- static summary = "List workspace windows (tmux panes)";
42
- static hidden = false;
43
- static examples = [
44
- "$ abbie windows list",
45
- "$ abbie windows list --session work",
46
- "$ abbie windows list --active",
47
- "$ abbie windows list --no-with-nvim",
48
- "$ abbie windows list --no-with-agent",
49
- "$ abbie windows list --sync",
50
- "$ abbie windows list --json",
51
- ];
52
- static flags = {
53
- ...BaseCommand.baseFlags,
54
- session: Flags.string({
55
- char: "s",
56
- description: "Filter to specific tmux session",
57
- }),
58
- active: Flags.boolean({
59
- description: "Only show active panes",
60
- default: false,
61
- }),
62
- "with-nvim": Flags.boolean({
63
- description: "Include nvim state",
64
- default: true,
65
- allowNo: true,
66
- }),
67
- "with-agent": Flags.boolean({
68
- description: "Include agent detection",
69
- default: true,
70
- allowNo: true,
71
- }),
72
- sync: Flags.boolean({
73
- description: "Sync windows to Convex for cross-device visibility",
74
- default: false,
75
- }),
76
- };
77
- async execute() {
78
- const { flags } = await this.parse(WindowsListCommand);
79
- this.parsedFlags = flags;
80
- const tmuxRunning = await isRunning();
81
- if (!tmuxRunning) {
82
- const result = { tmuxRunning: false, windows: [] };
83
- if (!this.jsonEnabled?.()) {
84
- this.log("tmux is not running");
85
- }
86
- return result;
87
- }
88
- const states = await windows.inventory({
89
- session: flags.session,
90
- includeNvim: flags["with-nvim"],
91
- includeAgent: flags["with-agent"],
92
- includeBuffers: false,
93
- });
94
- const filtered = (flags.active ? states.filter((s) => s.window.active) : states).sort((a, b) => {
95
- if (a.window.session !== b.window.session)
96
- return a.window.session.localeCompare(b.window.session);
97
- if (a.window.window !== b.window.window)
98
- return a.window.window - b.window.window;
99
- return a.window.pane - b.window.pane;
100
- });
101
- const result = { tmuxRunning: true, windows: filtered };
102
- // Sync to Convex if requested
103
- if (flags.sync) {
104
- await this.syncToConvex(filtered);
105
- }
106
- if (!this.jsonEnabled?.()) {
107
- this.printText(result);
108
- }
109
- return result;
110
- }
111
- async syncToConvex(states) {
112
- if (!isConvexConfigured()) {
113
- if (!this.jsonEnabled?.()) {
114
- this.warn("Convex not configured, skipping sync");
115
- }
116
- return;
117
- }
118
- const deviceId = getDeviceId();
119
- const windowData = states.map((state) => ({
120
- paneId: state.window.paneId ||
121
- `${state.window.session}:${state.window.window}.${state.window.pane}`,
122
- tmuxSession: state.window.session,
123
- windowIndex: state.window.window,
124
- windowName: state.window.windowName,
125
- paneIndex: state.window.pane,
126
- cwd: state.window.cwd || "",
127
- title: state.window.title || undefined,
128
- isActive: state.window.active,
129
- cols: state.window.size.cols,
130
- rows: state.window.size.rows,
131
- hasNvim: state.nvim?.available ?? false,
132
- nvimPid: state.nvim?.pid ?? undefined,
133
- nvimServerAddr: state.nvim?.serverAddr ?? undefined,
134
- agentType: state.agent?.type ?? undefined,
135
- agentPid: state.agent?.pid ?? undefined,
136
- }));
137
- try {
138
- const client = getHttpClient();
139
- const syncResult = await client.mutation(api.windows.sync, {
140
- deviceId,
141
- windows: windowData,
142
- });
143
- if (!this.jsonEnabled?.()) {
144
- this.log(`Synced ${syncResult.synced} windows to Convex`);
145
- }
146
- }
147
- catch (error) {
148
- if (!this.jsonEnabled?.()) {
149
- this.warn(`Failed to sync to Convex: ${error instanceof Error ? error.message : "Unknown error"}`);
150
- }
151
- }
152
- }
153
- printText(result) {
154
- if (result.windows.length === 0) {
155
- this.log("No windows found");
156
- return;
157
- }
158
- const rows = result.windows.map(formatRow);
159
- const widths = {
160
- id: Math.max(2, ...rows.map((r) => r.id.length), "ID".length),
161
- session: Math.max(2, ...rows.map((r) => r.session.length), "SESSION".length),
162
- window: Math.max(2, ...rows.map((r) => r.window.length), "WINDOW".length),
163
- cmd: Math.max(2, ...rows.map((r) => r.cmd.length), "CMD".length),
164
- cwd: Math.max(2, ...rows.map((r) => r.cwd.length), "CWD".length),
165
- };
166
- this.log("WINDOWS");
167
- this.log(`${pad("ID", widths.id)} ${pad("SESSION", widths.session)} ${pad("WINDOW", widths.window)} ${pad("CMD", widths.cmd)} ${pad("CWD", widths.cwd)} NVIM AGENT`);
168
- for (const row of rows) {
169
- this.log(`${pad(row.id, widths.id)} ${pad(row.session, widths.session)} ${pad(row.window, widths.window)} ${pad(row.cmd, widths.cmd)} ${pad(row.cwd, widths.cwd)} ${pad(row.nvim, 4)} ${row.agent}`);
170
- }
171
- }
172
- }
@@ -1,17 +0,0 @@
1
- import { BaseCommand } from "../../base-command.js";
2
- export default class WindowsMapCommand extends BaseCommand {
3
- static summary: string;
4
- static hidden: boolean;
5
- static examples: string[];
6
- static flags: {
7
- orphans: import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
- unmapped: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
- format: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
- quiet: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
- "json-errors": import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
- ndjson: import("@oclif/core/interfaces").BooleanFlag<boolean>;
13
- };
14
- execute(): Promise<unknown>;
15
- private printText;
16
- }
17
- //# sourceMappingURL=map.d.ts.map