@creativeintelligence/abbie 0.1.6 → 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 (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 +1 -1
  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,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