@creativeintelligence/abbie 0.1.5 → 0.1.7

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 (142) hide show
  1. package/bin/dev.js +1 -49
  2. package/bin/run.js +42 -49
  3. package/dist/cli/commands/login.js +26 -0
  4. package/dist/cli/commands/project/add.d.ts +0 -1
  5. package/dist/cli/commands/project/add.js +16 -52
  6. package/dist/cli/commands/project/list.js +13 -93
  7. package/dist/cli/commands/project/remove.d.ts +0 -2
  8. package/dist/cli/commands/project/remove.js +11 -28
  9. package/dist/cli/commands/session/list.js +3 -12
  10. package/dist/cli/commands/session/mark-done.js +1 -7
  11. package/dist/cli/commands/session/start.d.ts +0 -1
  12. package/dist/cli/commands/session/start.js +5 -7
  13. package/dist/lib/active-sessions.d.ts +0 -12
  14. package/dist/lib/active-sessions.js +6 -175
  15. package/dist/lib/project-path.d.ts +6 -0
  16. package/dist/lib/project-path.js +21 -0
  17. package/dist/lib.d.ts +1 -2
  18. package/dist/lib.js +2 -4
  19. package/oclif.manifest.json +2569 -6368
  20. package/package.json +1 -1
  21. package/dist/cli/commands/backlog/add.d.ts +0 -22
  22. package/dist/cli/commands/backlog/add.js +0 -65
  23. package/dist/cli/commands/backlog/claim.d.ts +0 -19
  24. package/dist/cli/commands/backlog/claim.js +0 -45
  25. package/dist/cli/commands/backlog/complete.d.ts +0 -18
  26. package/dist/cli/commands/backlog/complete.js +0 -42
  27. package/dist/cli/commands/backlog/list.d.ts +0 -20
  28. package/dist/cli/commands/backlog/list.js +0 -91
  29. package/dist/cli/commands/backlog/pick.d.ts +0 -18
  30. package/dist/cli/commands/backlog/pick.js +0 -42
  31. package/dist/cli/commands/backlog/sync.d.ts +0 -24
  32. package/dist/cli/commands/backlog/sync.js +0 -109
  33. package/dist/cli/commands/daemon.d.ts +0 -56
  34. package/dist/cli/commands/daemon.js +0 -1465
  35. package/dist/cli/commands/docs/lint.d.ts +0 -18
  36. package/dist/cli/commands/docs/lint.js +0 -82
  37. package/dist/cli/commands/docs/sync.d.ts +0 -19
  38. package/dist/cli/commands/docs/sync.js +0 -76
  39. package/dist/cli/commands/gc.d.ts +0 -29
  40. package/dist/cli/commands/gc.js +0 -211
  41. package/dist/cli/commands/index.d.ts +0 -36
  42. package/dist/cli/commands/index.js +0 -228
  43. package/dist/cli/commands/panes/broker.d.ts +0 -17
  44. package/dist/cli/commands/panes/broker.js +0 -57
  45. package/dist/cli/commands/panes/pipe-sink.d.ts +0 -17
  46. package/dist/cli/commands/panes/pipe-sink.js +0 -90
  47. package/dist/cli/commands/panes/snapshot.d.ts +0 -20
  48. package/dist/cli/commands/panes/snapshot.js +0 -125
  49. package/dist/cli/commands/preview/init.d.ts +0 -25
  50. package/dist/cli/commands/preview/init.js +0 -159
  51. package/dist/cli/commands/preview/sync.d.ts +0 -23
  52. package/dist/cli/commands/preview/sync.js +0 -144
  53. package/dist/cli/commands/preview/watch.d.ts +0 -24
  54. package/dist/cli/commands/preview/watch.js +0 -153
  55. package/dist/cli/commands/resource/acquire.d.ts +0 -21
  56. package/dist/cli/commands/resource/acquire.js +0 -90
  57. package/dist/cli/commands/resource/list.d.ts +0 -15
  58. package/dist/cli/commands/resource/list.js +0 -61
  59. package/dist/cli/commands/resource/release.d.ts +0 -18
  60. package/dist/cli/commands/resource/release.js +0 -50
  61. package/dist/cli/commands/resource/wait.d.ts +0 -21
  62. package/dist/cli/commands/resource/wait.js +0 -73
  63. package/dist/cli/commands/session/view.d.ts +0 -24
  64. package/dist/cli/commands/session/view.js +0 -145
  65. package/dist/cli/commands/start.d.ts +0 -37
  66. package/dist/cli/commands/start.js +0 -234
  67. package/dist/cli/commands/triage/claim.d.ts +0 -23
  68. package/dist/cli/commands/triage/claim.js +0 -186
  69. package/dist/cli/commands/triage/list.d.ts +0 -22
  70. package/dist/cli/commands/triage/list.js +0 -112
  71. package/dist/cli/commands/triage/next.d.ts +0 -18
  72. package/dist/cli/commands/triage/next.js +0 -63
  73. package/dist/cli/commands/triage/pull.d.ts +0 -19
  74. package/dist/cli/commands/triage/pull.js +0 -82
  75. package/dist/cli/commands/triage/stats.d.ts +0 -16
  76. package/dist/cli/commands/triage/stats.js +0 -69
  77. package/dist/cli/commands/tunnel/list.d.ts +0 -16
  78. package/dist/cli/commands/tunnel/list.js +0 -98
  79. package/dist/cli/commands/tunnel/start.d.ts +0 -24
  80. package/dist/cli/commands/tunnel/start.js +0 -107
  81. package/dist/cli/commands/tunnel/stop.d.ts +0 -20
  82. package/dist/cli/commands/tunnel/stop.js +0 -90
  83. package/dist/cli/commands/tunnel/url.d.ts +0 -21
  84. package/dist/cli/commands/tunnel/url.js +0 -70
  85. package/dist/cli/commands/windows/context.d.ts +0 -18
  86. package/dist/cli/commands/windows/context.js +0 -326
  87. package/dist/cli/commands/windows/focus.d.ts +0 -17
  88. package/dist/cli/commands/windows/focus.js +0 -103
  89. package/dist/cli/commands/windows/list.d.ts +0 -21
  90. package/dist/cli/commands/windows/list.js +0 -172
  91. package/dist/cli/commands/windows/map.d.ts +0 -17
  92. package/dist/cli/commands/windows/map.js +0 -168
  93. package/dist/cli/commands/windows/read.d.ts +0 -21
  94. package/dist/cli/commands/windows/read.js +0 -241
  95. package/dist/cli/commands/windows/search.d.ts +0 -24
  96. package/dist/cli/commands/windows/search.js +0 -171
  97. package/dist/cli/commands/windows/show.d.ts +0 -19
  98. package/dist/cli/commands/windows/show.js +0 -165
  99. package/dist/cli/commands/windows/watch.d.ts +0 -19
  100. package/dist/cli/commands/windows/watch.js +0 -241
  101. package/dist/lib/managed-session.d.ts +0 -27
  102. package/dist/lib/managed-session.js +0 -105
  103. package/dist/lib/panes/broker.d.ts +0 -130
  104. package/dist/lib/panes/broker.js +0 -97
  105. package/dist/lib/panes/index.d.ts +0 -2
  106. package/dist/lib/panes/index.js +0 -1
  107. package/dist/lib/panes/server.d.ts +0 -17
  108. package/dist/lib/panes/server.js +0 -308
  109. package/dist/lib/preview/manager.d.ts +0 -77
  110. package/dist/lib/preview/manager.js +0 -369
  111. package/dist/lib/preview/schema.d.ts +0 -2
  112. package/dist/lib/preview/schema.js +0 -32
  113. package/dist/lib/preview/sprite.d.ts +0 -85
  114. package/dist/lib/preview/sprite.js +0 -321
  115. package/dist/lib/preview/watcher.d.ts +0 -63
  116. package/dist/lib/preview/watcher.js +0 -185
  117. package/dist/lib/project-identity.d.ts +0 -16
  118. package/dist/lib/project-identity.js +0 -75
  119. package/dist/lib/tmux/bridge.d.ts +0 -133
  120. package/dist/lib/tmux/bridge.js +0 -315
  121. package/dist/lib/tmux/context.d.ts +0 -82
  122. package/dist/lib/tmux/context.js +0 -239
  123. package/dist/lib/tmux/index.d.ts +0 -8
  124. package/dist/lib/tmux/index.js +0 -11
  125. package/dist/lib/tmux/map.d.ts +0 -57
  126. package/dist/lib/tmux/map.js +0 -198
  127. package/dist/lib/tmux/panes.d.ts +0 -27
  128. package/dist/lib/tmux/panes.js +0 -151
  129. package/dist/lib/tmux/redaction.d.ts +0 -57
  130. package/dist/lib/tmux/redaction.js +0 -152
  131. package/dist/lib/web/analytics.d.ts +0 -63
  132. package/dist/lib/web/analytics.js +0 -168
  133. package/dist/lib/web/server.d.ts +0 -26
  134. package/dist/lib/web/server.js +0 -697
  135. package/dist/lib/web/tmux-bridge.d.ts +0 -7
  136. package/dist/lib/web/tmux-bridge.js +0 -7
  137. package/dist/lib/windows/index.d.ts +0 -3
  138. package/dist/lib/windows/index.js +0 -2
  139. package/dist/lib/windows/inventory.d.ts +0 -21
  140. package/dist/lib/windows/inventory.js +0 -263
  141. package/dist/lib/windows/types.d.ts +0 -46
  142. package/dist/lib/windows/types.js +0 -1
@@ -1,97 +0,0 @@
1
- import { randomUUID } from "node:crypto";
2
- import { mkdirSync } from "node:fs";
3
- import { createConnection } from "node:net";
4
- import { homedir } from "node:os";
5
- import { dirname, join } from "node:path";
6
- export function getDefaultPanesBrokerSocketPath() {
7
- const runtimeDir = process.env.XDG_RUNTIME_DIR;
8
- if (runtimeDir)
9
- return join(runtimeDir, "abbie-panes-broker.sock");
10
- const home = homedir() || process.env.HOME || "~";
11
- return join(home, ".abbie", "run", "panes-broker.sock");
12
- }
13
- function ensureSocketDir(path) {
14
- const dir = dirname(path);
15
- mkdirSync(dir, { recursive: true });
16
- }
17
- function nowIso() {
18
- return new Date().toISOString();
19
- }
20
- export function createNdjsonLineParser() {
21
- let buf = "";
22
- let onMessageFn = null;
23
- let onErrorFn = null;
24
- return {
25
- pushChunk(chunk) {
26
- buf += chunk.toString();
27
- for (;;) {
28
- const idx = buf.indexOf("\n");
29
- if (idx === -1)
30
- break;
31
- const line = buf.slice(0, idx).trimEnd();
32
- buf = buf.slice(idx + 1);
33
- if (!line)
34
- continue;
35
- try {
36
- const msg = JSON.parse(line);
37
- onMessageFn?.(msg);
38
- }
39
- catch (err) {
40
- onErrorFn?.(new Error(err instanceof Error ? err.message : "Failed to parse NDJSON line"));
41
- }
42
- }
43
- },
44
- onMessage(fn) {
45
- onMessageFn = fn;
46
- },
47
- onError(fn) {
48
- onErrorFn = fn;
49
- },
50
- };
51
- }
52
- export function connectPanesBroker(opts = {}, handlers) {
53
- const socketPath = opts.socketPath ?? getDefaultPanesBrokerSocketPath();
54
- ensureSocketDir(socketPath);
55
- const socket = createConnection({ path: socketPath });
56
- const parser = createNdjsonLineParser();
57
- parser.onMessage((msg) => handlers?.onMessage?.(msg));
58
- parser.onError((err) => handlers?.onError?.(err));
59
- socket.on("data", (chunk) => parser.pushChunk(chunk));
60
- socket.on("error", (err) => handlers?.onError?.(err instanceof Error ? err : new Error(String(err))));
61
- socket.on("close", () => handlers?.onClose?.());
62
- const clientId = randomUUID();
63
- const send = (msg) => {
64
- socket.write(`${JSON.stringify(msg)}\n`);
65
- };
66
- // Send hello immediately; server can ignore if not required.
67
- send({
68
- type: "client.hello",
69
- at: nowIso(),
70
- clientId,
71
- version: 1,
72
- pid: process.pid,
73
- });
74
- const subscribe = (sub) => {
75
- const requestId = sub.requestId ?? randomUUID();
76
- send({
77
- type: "panes.subscribe",
78
- at: nowIso(),
79
- requestId,
80
- target: sub.target,
81
- redaction: sub.redaction ?? "raw",
82
- encoding: sub.encoding ?? "text",
83
- history: sub.history,
84
- follow: sub.follow ?? true,
85
- });
86
- return requestId;
87
- };
88
- const unsubscribe = (requestId) => {
89
- send({ type: "panes.unsubscribe", at: nowIso(), requestId });
90
- };
91
- const ping = () => {
92
- const nonce = randomUUID();
93
- send({ type: "client.ping", at: nowIso(), nonce });
94
- return nonce;
95
- };
96
- return { socket, clientId, send, subscribe, unsubscribe, ping };
97
- }
@@ -1,2 +0,0 @@
1
- export * from "./broker.js";
2
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- export * from "./broker.js";
@@ -1,17 +0,0 @@
1
- import { type Server } from "node:net";
2
- type BrokerOptions = {
3
- socketPath?: string;
4
- fps?: number;
5
- forcePipe?: boolean;
6
- };
7
- export declare function startPanesBroker(opts: BrokerOptions, ctx: {
8
- agentsBinPath: string;
9
- logInfo: (msg: string) => void;
10
- logWarn: (msg: string) => void;
11
- }): Promise<{
12
- socketPath: string;
13
- server: Server;
14
- stop: () => Promise<void>;
15
- }>;
16
- export {};
17
- //# sourceMappingURL=server.d.ts.map
@@ -1,308 +0,0 @@
1
- import { existsSync, mkdirSync, unlinkSync } from "node:fs";
2
- import { createServer } from "node:net";
3
- import { dirname } from "node:path";
4
- import { capturePaneScreen, ensurePipePane, getPaneMetrics } from "../tmux/panes.js";
5
- import * as windows from "../windows/index.js";
6
- import { createNdjsonLineParser, getDefaultPanesBrokerSocketPath, } from "./broker.js";
7
- function nowIso() {
8
- return new Date().toISOString();
9
- }
10
- function ensureDirForSocket(socketPath) {
11
- mkdirSync(dirname(socketPath), { recursive: true });
12
- }
13
- function safeUnlinkSocket(socketPath) {
14
- try {
15
- if (existsSync(socketPath))
16
- unlinkSync(socketPath);
17
- }
18
- catch {
19
- // ignore
20
- }
21
- }
22
- function send(socket, msg) {
23
- socket.write(`${JSON.stringify(msg)}\n`);
24
- }
25
- function getRefFromTarget(target) {
26
- if (typeof target !== "object" || target === null)
27
- return null;
28
- const record = target;
29
- return typeof record.ref === "string" ? record.ref : null;
30
- }
31
- function parseTargetToPaneId(target) {
32
- if (typeof target !== "object" || target === null)
33
- return { error: "Invalid target" };
34
- const maybe = target;
35
- const paneId = typeof maybe.paneId === "string" ? maybe.paneId : undefined;
36
- const ref = typeof maybe.ref === "string" ? maybe.ref : undefined;
37
- if (paneId)
38
- return { paneId };
39
- if (!ref)
40
- return { error: "Missing target.paneId or target.ref" };
41
- if (ref.startsWith("%"))
42
- return { paneId: ref };
43
- return { paneId: undefined, error: "Ref must be a pane id (e.g. %3) or resolved via windows" };
44
- }
45
- export async function startPanesBroker(opts, ctx) {
46
- const socketPath = opts.socketPath ?? getDefaultPanesBrokerSocketPath();
47
- ensureDirForSocket(socketPath);
48
- safeUnlinkSocket(socketPath);
49
- const clients = new Map();
50
- const subs = new Map();
51
- const panes = new Map();
52
- const fps = Math.max(1, Math.min(60, opts.fps ?? 30));
53
- const frameMs = Math.floor(1000 / fps);
54
- const server = createServer((socket) => {
55
- const clientId = `c_${Math.random().toString(16).slice(2)}`;
56
- const client = { socket, id: clientId, kind: "ui" };
57
- clients.set(clientId, client);
58
- const hello = {
59
- type: "broker.hello",
60
- at: nowIso(),
61
- version: 1,
62
- pid: process.pid,
63
- };
64
- send(socket, hello);
65
- const parser = createNdjsonLineParser();
66
- socket.on("data", (chunk) => parser.pushChunk(chunk));
67
- socket.on("close", () => {
68
- // Drop subscriptions
69
- for (const [requestId, sub] of subs) {
70
- if (sub.clientId !== clientId)
71
- continue;
72
- subs.delete(requestId);
73
- const pane = panes.get(sub.paneId);
74
- pane?.subs.delete(requestId);
75
- }
76
- // If pipe client, detach
77
- if (client.kind === "pipe" && client.paneId) {
78
- const pane = panes.get(client.paneId);
79
- if (pane?.pipeClientId === clientId)
80
- pane.pipeClientId = undefined;
81
- if (pane?.controllerClientId === clientId)
82
- pane.controllerClientId = undefined;
83
- }
84
- clients.delete(clientId);
85
- });
86
- parser.onMessage(async (msg) => {
87
- const type = typeof msg.type === "string" ? msg.type : "";
88
- if (type === "client.ping") {
89
- const nonce = typeof msg.nonce === "string" ? msg.nonce : "";
90
- send(socket, { type: "broker.pong", at: nowIso(), nonce });
91
- return;
92
- }
93
- if (type === "client.hello") {
94
- return;
95
- }
96
- if (type === "panes.pipe.hello") {
97
- const paneId = typeof msg.paneId === "string" ? msg.paneId : undefined;
98
- if (!paneId)
99
- return;
100
- client.kind = "pipe";
101
- client.paneId = paneId;
102
- const pane = panes.get(paneId) ?? { paneId, dirty: true, lastEmitAt: 0, subs: new Set() };
103
- pane.pipeClientId = clientId;
104
- panes.set(paneId, pane);
105
- return;
106
- }
107
- if (type === "panes.pipe.chunk") {
108
- const paneId = typeof msg.paneId === "string" ? msg.paneId : undefined;
109
- if (!paneId)
110
- return;
111
- const pane = panes.get(paneId) ?? { paneId, dirty: true, lastEmitAt: 0, subs: new Set() };
112
- pane.dirty = true;
113
- panes.set(paneId, pane);
114
- return;
115
- }
116
- if (type === "panes.subscribe") {
117
- const requestId = typeof msg.requestId === "string" ? msg.requestId : undefined;
118
- const target = msg.target;
119
- if (!requestId)
120
- return;
121
- // Resolve paneId
122
- let paneId;
123
- const parsed = parseTargetToPaneId(target);
124
- paneId = parsed.paneId;
125
- // If we got a non-pane-id ref (session:window.pane), resolve via windows inventory.
126
- const ref = getRefFromTarget(target);
127
- if (!paneId && ref) {
128
- const state = await windows.getWindowState(ref, {
129
- includeNvim: false,
130
- includeAgent: false,
131
- includeBuffers: false,
132
- });
133
- paneId = state?.window.paneId ?? undefined;
134
- }
135
- if (!paneId) {
136
- const status = {
137
- type: "panes.status",
138
- at: nowIso(),
139
- requestId,
140
- level: "error",
141
- message: parsed.error ?? "Failed to resolve paneId",
142
- };
143
- send(socket, status);
144
- return;
145
- }
146
- const encoding = msg.encoding === "ansi" ? "ansi" : "text";
147
- const redaction = msg.redaction === "default" ? "default" : "raw";
148
- const follow = msg.follow !== false;
149
- subs.set(requestId, {
150
- requestId,
151
- clientId,
152
- paneId,
153
- encoding,
154
- redaction,
155
- follow,
156
- active: true,
157
- });
158
- const pane = panes.get(paneId) ?? { paneId, dirty: true, lastEmitAt: 0, subs: new Set() };
159
- pane.subs.add(requestId);
160
- panes.set(paneId, pane);
161
- // Ensure pipe-pane is attached (best-effort). The pipe-sink provides
162
- // event-driven invalidation + raw input injection (bidirectional pipe).
163
- const sinkCommand = `${ctx.agentsBinPath} panes pipe-sink --pane ${paneId} --sock ${socketPath}`;
164
- const attached = await ensurePipePane(paneId, sinkCommand, {
165
- onlyIfUnset: !opts.forcePipe,
166
- bidirectional: true,
167
- });
168
- if (!attached.attached) {
169
- ctx.logWarn(`pipe-pane attach failed for ${paneId}: ${attached.error ?? "unknown"}`);
170
- }
171
- // Send an initial snapshot immediately.
172
- pane.dirty = true;
173
- await emitSnapshotForPane(paneId);
174
- return;
175
- }
176
- if (type === "panes.unsubscribe") {
177
- const requestId = typeof msg.requestId === "string" ? msg.requestId : undefined;
178
- if (!requestId)
179
- return;
180
- const sub = subs.get(requestId);
181
- if (!sub)
182
- return;
183
- subs.delete(requestId);
184
- panes.get(sub.paneId)?.subs.delete(requestId);
185
- return;
186
- }
187
- if (type === "panes.control.claim") {
188
- const paneId = typeof msg.paneId === "string" ? msg.paneId : undefined;
189
- if (!paneId)
190
- return;
191
- const pane = panes.get(paneId) ?? { paneId, dirty: false, lastEmitAt: 0, subs: new Set() };
192
- panes.set(paneId, pane);
193
- if (pane.controllerClientId && pane.controllerClientId !== clientId) {
194
- send(socket, {
195
- type: "panes.status",
196
- at: nowIso(),
197
- paneId,
198
- level: "warn",
199
- message: "Control already claimed by another client",
200
- });
201
- return;
202
- }
203
- pane.controllerClientId = clientId;
204
- send(socket, { type: "panes.status", at: nowIso(), paneId, level: "info", message: "ok" });
205
- return;
206
- }
207
- if (type === "panes.control.release") {
208
- const paneId = typeof msg.paneId === "string" ? msg.paneId : undefined;
209
- if (!paneId)
210
- return;
211
- const pane = panes.get(paneId);
212
- if (pane?.controllerClientId === clientId)
213
- pane.controllerClientId = undefined;
214
- return;
215
- }
216
- if (type === "panes.input") {
217
- const paneId = typeof msg.paneId === "string" ? msg.paneId : undefined;
218
- const data = typeof msg.data === "string" ? msg.data : undefined;
219
- if (!paneId || !data)
220
- return;
221
- const pane = panes.get(paneId);
222
- if (pane?.controllerClientId && pane.controllerClientId !== clientId)
223
- return;
224
- if (!pane?.pipeClientId)
225
- return;
226
- const pipeClient = clients.get(pane.pipeClientId);
227
- if (!pipeClient)
228
- return;
229
- send(pipeClient.socket, { type: "panes.pipe.input", at: nowIso(), paneId, data });
230
- return;
231
- }
232
- });
233
- parser.onError(() => {
234
- // ignore parse errors
235
- });
236
- });
237
- const emitSnapshotForPane = async (paneId) => {
238
- const pane = panes.get(paneId);
239
- if (!pane)
240
- return;
241
- if (pane.subs.size === 0)
242
- return;
243
- const metrics = await getPaneMetrics(paneId);
244
- const rows = metrics?.rows ?? 24;
245
- const cols = metrics?.cols ?? 80;
246
- // Use the first subscription's encoding as the capture mode; if there are
247
- // mixed encodings, we will send snapshots per-sub below.
248
- const byRequest = [];
249
- for (const requestId of pane.subs) {
250
- const sub = subs.get(requestId);
251
- if (sub?.active)
252
- byRequest.push(sub);
253
- }
254
- if (byRequest.length === 0)
255
- return;
256
- const captureAnsi = byRequest.some((s) => s.encoding === "ansi");
257
- const screen = await capturePaneScreen(paneId, {
258
- ansi: captureAnsi,
259
- rows,
260
- cursor: metrics
261
- ? { x: metrics.cursorX, y: metrics.cursorY, visible: metrics.cursorFlag !== 0 }
262
- : undefined,
263
- });
264
- // biome-ignore lint/complexity/useRegexLiterals: Regex literal with \u001b triggers Biome control-char lint.
265
- const sgrRegex = new RegExp("\\u001b\\[[0-9;]*m", "g");
266
- for (const sub of byRequest) {
267
- const client = clients.get(sub.clientId);
268
- if (!client)
269
- continue;
270
- const content = sub.encoding === "ansi" ? screen : screen.replace(sgrRegex, "");
271
- const snapshot = {
272
- type: "panes.snapshot",
273
- at: nowIso(),
274
- requestId: sub.requestId,
275
- paneId,
276
- encoding: sub.encoding,
277
- redaction: sub.redaction,
278
- cols,
279
- rows,
280
- content,
281
- };
282
- send(client.socket, snapshot);
283
- }
284
- };
285
- const interval = setInterval(async () => {
286
- const now = Date.now();
287
- for (const pane of panes.values()) {
288
- if (!pane.dirty)
289
- continue;
290
- if (now - pane.lastEmitAt < frameMs)
291
- continue;
292
- pane.dirty = false;
293
- pane.lastEmitAt = now;
294
- await emitSnapshotForPane(pane.paneId);
295
- }
296
- }, Math.max(10, Math.floor(frameMs / 2)));
297
- await new Promise((resolve, reject) => {
298
- server.once("error", reject);
299
- server.listen(socketPath, () => resolve());
300
- });
301
- ctx.logInfo(`panes broker listening: ${socketPath} (${fps}fps)`);
302
- const stop = async () => {
303
- clearInterval(interval);
304
- await new Promise((resolve) => server.close(() => resolve()));
305
- safeUnlinkSocket(socketPath);
306
- };
307
- return { socketPath, server, stop };
308
- }
@@ -1,77 +0,0 @@
1
- import { Database } from "bun:sqlite";
2
- export type DeploymentStatus = "pending" | "syncing" | "installing" | "starting" | "running" | "stopped" | "failed";
3
- export interface SpriteRecord {
4
- id: number;
5
- project_name: string;
6
- project_path: string;
7
- sprite_name: string;
8
- sprite_url: string | null;
9
- doppler_project: string | null;
10
- dev_command: string;
11
- port: number;
12
- created_at: string;
13
- updated_at: string;
14
- }
15
- export interface DeploymentRecord {
16
- id: number;
17
- sprite_id: number;
18
- status: DeploymentStatus;
19
- preview_url: string | null;
20
- screenshot_path: string | null;
21
- started_at: string;
22
- stopped_at: string | null;
23
- error: string | null;
24
- sync_duration_ms: number | null;
25
- install_duration_ms: number | null;
26
- start_duration_ms: number | null;
27
- }
28
- export interface RegisterSpriteOptions {
29
- spriteUrl?: string;
30
- dopplerProject?: string;
31
- devCommand?: string;
32
- port?: number;
33
- }
34
- export interface RecordDeploymentOptions {
35
- previewUrl?: string;
36
- screenshotPath?: string;
37
- error?: string;
38
- syncDurationMs?: number;
39
- installDurationMs?: number;
40
- startDurationMs?: number;
41
- }
42
- export interface UpdateDeploymentOptions {
43
- status?: DeploymentStatus;
44
- previewUrl?: string;
45
- screenshotPath?: string;
46
- stoppedAt?: string;
47
- error?: string;
48
- syncDurationMs?: number;
49
- installDurationMs?: number;
50
- startDurationMs?: number;
51
- }
52
- export declare class PreviewManager {
53
- private dataDir;
54
- private dbPath;
55
- constructor(options?: {
56
- dataDir?: string;
57
- });
58
- private openDb;
59
- ensureSchema(db?: Database): void;
60
- private rowToSprite;
61
- private rowToDeployment;
62
- registerSprite(projectName: string, projectPath: string, spriteName: string, options?: RegisterSpriteOptions): SpriteRecord;
63
- getSprite(projectName: string): SpriteRecord | null;
64
- getSpriteById(id: number): SpriteRecord | null;
65
- listSprites(): SpriteRecord[];
66
- updateSprite(projectName: string, updates: Partial<Pick<RegisterSpriteOptions, "devCommand" | "dopplerProject" | "port">>): SpriteRecord | null;
67
- deleteSprite(projectName: string): boolean;
68
- recordDeployment(spriteId: number, status: DeploymentStatus, options?: RecordDeploymentOptions): DeploymentRecord;
69
- updateDeployment(id: number, updates: UpdateDeploymentOptions): DeploymentRecord | null;
70
- getDeployment(id: number): DeploymentRecord | null;
71
- getLatestDeployment(spriteId: number): DeploymentRecord | null;
72
- listDeployments(spriteId: number, limit?: number): DeploymentRecord[];
73
- getActiveDeployments(): Array<DeploymentRecord & {
74
- sprite: SpriteRecord;
75
- }>;
76
- }
77
- //# sourceMappingURL=manager.d.ts.map