@duckmind/dm-darwin-x64 0.33.0 → 0.33.2

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 (81) hide show
  1. package/dm +0 -0
  2. package/extensions/.dm-extensions.json +1 -76
  3. package/package.json +1 -1
  4. package/theme/theme-alps.json +84 -0
  5. package/extensions/dm-chime/README.md +0 -11
  6. package/extensions/dm-chime/docs/protocols.md +0 -107
  7. package/extensions/dm-chime/index.ts +0 -205
  8. package/extensions/dm-chime/package.json +0 -33
  9. package/extensions/dm-phone/README.md +0 -24
  10. package/extensions/dm-phone/index.ts +0 -12
  11. package/extensions/dm-phone/node_modules/.package-lock.json +0 -29
  12. package/extensions/dm-phone/node_modules/ws/LICENSE +0 -20
  13. package/extensions/dm-phone/node_modules/ws/README.md +0 -548
  14. package/extensions/dm-phone/node_modules/ws/browser.js +0 -8
  15. package/extensions/dm-phone/node_modules/ws/index.js +0 -22
  16. package/extensions/dm-phone/node_modules/ws/lib/buffer-util.js +0 -131
  17. package/extensions/dm-phone/node_modules/ws/lib/constants.js +0 -19
  18. package/extensions/dm-phone/node_modules/ws/lib/event-target.js +0 -292
  19. package/extensions/dm-phone/node_modules/ws/lib/extension.js +0 -203
  20. package/extensions/dm-phone/node_modules/ws/lib/limiter.js +0 -55
  21. package/extensions/dm-phone/node_modules/ws/lib/permessage-deflate.js +0 -528
  22. package/extensions/dm-phone/node_modules/ws/lib/receiver.js +0 -760
  23. package/extensions/dm-phone/node_modules/ws/lib/sender.js +0 -607
  24. package/extensions/dm-phone/node_modules/ws/lib/stream.js +0 -161
  25. package/extensions/dm-phone/node_modules/ws/lib/subprotocol.js +0 -62
  26. package/extensions/dm-phone/node_modules/ws/lib/validation.js +0 -152
  27. package/extensions/dm-phone/node_modules/ws/lib/websocket-server.js +0 -562
  28. package/extensions/dm-phone/node_modules/ws/lib/websocket.js +0 -1407
  29. package/extensions/dm-phone/node_modules/ws/package.json +0 -70
  30. package/extensions/dm-phone/node_modules/ws/wrapper.mjs +0 -21
  31. package/extensions/dm-phone/package-lock.json +0 -66
  32. package/extensions/dm-phone/package.json +0 -35
  33. package/extensions/dm-phone/phone-session-pool.ts +0 -8
  34. package/extensions/dm-phone/public/app/attachments.js +0 -233
  35. package/extensions/dm-phone/public/app/autocomplete-controller.js +0 -81
  36. package/extensions/dm-phone/public/app/autocomplete.js +0 -135
  37. package/extensions/dm-phone/public/app/bindings.js +0 -178
  38. package/extensions/dm-phone/public/app/command-catalog.js +0 -76
  39. package/extensions/dm-phone/public/app/commands.js +0 -376
  40. package/extensions/dm-phone/public/app/constants.js +0 -60
  41. package/extensions/dm-phone/public/app/formatters.js +0 -131
  42. package/extensions/dm-phone/public/app/handlers.js +0 -442
  43. package/extensions/dm-phone/public/app/main.js +0 -6
  44. package/extensions/dm-phone/public/app/markdown.js +0 -105
  45. package/extensions/dm-phone/public/app/messages.js +0 -418
  46. package/extensions/dm-phone/public/app/sheet-actions.js +0 -113
  47. package/extensions/dm-phone/public/app/sheet-navigation.js +0 -19
  48. package/extensions/dm-phone/public/app/sheets-view.js +0 -287
  49. package/extensions/dm-phone/public/app/state.js +0 -95
  50. package/extensions/dm-phone/public/app/tool-rendering.js +0 -562
  51. package/extensions/dm-phone/public/app/transport.js +0 -176
  52. package/extensions/dm-phone/public/app/ui.js +0 -417
  53. package/extensions/dm-phone/public/app.js +0 -1
  54. package/extensions/dm-phone/public/icon.svg +0 -15
  55. package/extensions/dm-phone/public/index.html +0 -146
  56. package/extensions/dm-phone/public/manifest.webmanifest +0 -17
  57. package/extensions/dm-phone/public/styles.css +0 -1139
  58. package/extensions/dm-phone/public/sw.js +0 -78
  59. package/extensions/dm-phone/src/extension/duckmind-models.js +0 -264
  60. package/extensions/dm-phone/src/extension/phone-args.ts +0 -121
  61. package/extensions/dm-phone/src/extension/phone-paths.ts +0 -250
  62. package/extensions/dm-phone/src/extension/phone-quota.ts +0 -188
  63. package/extensions/dm-phone/src/extension/phone-runtime.ts +0 -154
  64. package/extensions/dm-phone/src/extension/phone-server-runtime.ts +0 -1217
  65. package/extensions/dm-phone/src/extension/phone-sessions.ts +0 -139
  66. package/extensions/dm-phone/src/extension/phone-static.ts +0 -30
  67. package/extensions/dm-phone/src/extension/phone-tailscale.ts +0 -148
  68. package/extensions/dm-phone/src/extension/phone-theme.ts +0 -85
  69. package/extensions/dm-phone/src/extension/register-phone-child-extension.ts +0 -112
  70. package/extensions/dm-phone/src/extension/register-phone-extension.ts +0 -106
  71. package/extensions/dm-phone/src/extension/types.ts +0 -73
  72. package/extensions/dm-phone/src/session-pool/parent-session-worker.ts +0 -882
  73. package/extensions/dm-phone/src/session-pool/session-pool.ts +0 -470
  74. package/extensions/dm-phone/src/session-pool/session-worker.ts +0 -739
  75. package/extensions/dm-phone/src/session-pool/types.ts +0 -111
  76. package/extensions/dm-phone/src/session-pool/utils.ts +0 -23
  77. package/extensions/dm-phone/test/duckmind-models.test.js +0 -147
  78. package/extensions/dm-thinking-timer/LICENSE +0 -21
  79. package/extensions/dm-thinking-timer/README.md +0 -7
  80. package/extensions/dm-thinking-timer/package.json +0 -20
  81. package/extensions/dm-thinking-timer/thinking-timer.ts +0 -250
@@ -1,470 +0,0 @@
1
- import type { WebSocket } from "ws";
2
- import type {
3
- ClientState,
4
- PhoneSessionPoolOptions,
5
- SessionController,
6
- SessionSnapshot,
7
- SessionSummary,
8
- } from "./types";
9
-
10
- export class PhoneSessionPool {
11
- private readonly options: PhoneSessionPoolOptions;
12
- private readonly workers = new Map<string, SessionController>();
13
- private readonly clients = new Map<WebSocket, ClientState>();
14
- private readonly statusSignatures = new Map<WebSocket, string>();
15
- private readonly catalogSignatures = new Map<WebSocket, string>();
16
- private defaultWorkerId: string | null = null;
17
- private defaultWorkerPromise: Promise<SessionController> | null = null;
18
-
19
- constructor(options: PhoneSessionPoolOptions) {
20
- this.options = options;
21
- }
22
-
23
- setCwd(cwd: string) {
24
- this.options.cwd = cwd;
25
- this.broadcastStatus();
26
- }
27
-
28
- get clientCount() {
29
- return this.clients.size;
30
- }
31
-
32
- getClients() {
33
- return [...this.clients.keys()];
34
- }
35
-
36
- getSelectedSessionId() {
37
- return this.defaultWorkerId;
38
- }
39
-
40
- getSession(sessionId: string | null | undefined) {
41
- if (!sessionId) return null;
42
- return this.workers.get(sessionId) || null;
43
- }
44
-
45
- getSessions() {
46
- return [...this.workers.values()];
47
- }
48
-
49
- private attachSession(session: SessionController) {
50
- this.workers.set(session.id, session);
51
- return session;
52
- }
53
-
54
- private createDefaultSession() {
55
- const session = this.options.createDefaultSession();
56
- return this.attachSession(session);
57
- }
58
-
59
- private createParallelSession(sessionFile: string | null = null) {
60
- const session = this.options.createParallelSession(sessionFile);
61
- return this.attachSession(session);
62
- }
63
-
64
- private sortedWorkers() {
65
- return [...this.workers.values()].sort((left, right) => right.lastActivityAt - left.lastActivityAt);
66
- }
67
-
68
- private serializeSessions() {
69
- return this.sortedWorkers().map((worker) => worker.getSummary());
70
- }
71
-
72
- async ensureDefaultWorker() {
73
- const existing = this.defaultWorkerId ? this.workers.get(this.defaultWorkerId) : this.sortedWorkers()[0];
74
- if (existing) {
75
- this.defaultWorkerId = existing.id;
76
- return existing;
77
- }
78
-
79
- if (this.defaultWorkerPromise) {
80
- return this.defaultWorkerPromise;
81
- }
82
-
83
- this.defaultWorkerPromise = (async () => {
84
- const worker = this.createDefaultSession();
85
- this.defaultWorkerId = worker.id;
86
-
87
- try {
88
- await worker.ensureStarted();
89
- await worker.refreshCachedSnapshot(5000).catch(() => {});
90
- this.broadcastCatalog();
91
- this.broadcastStatus();
92
- return worker;
93
- } catch (error) {
94
- this.workers.delete(worker.id);
95
- if (this.defaultWorkerId === worker.id) {
96
- this.defaultWorkerId = null;
97
- }
98
- throw error;
99
- }
100
- })().finally(() => {
101
- this.defaultWorkerPromise = null;
102
- });
103
-
104
- return this.defaultWorkerPromise;
105
- }
106
-
107
- private async getWorkerForClient(ws: WebSocket) {
108
- const client = this.clients.get(ws);
109
- if (!client) {
110
- const worker = await this.ensureDefaultWorker();
111
- this.clients.set(ws, { activeSessionId: worker.id });
112
- return worker;
113
- }
114
-
115
- const activeWorker = client.activeSessionId ? this.workers.get(client.activeSessionId) : null;
116
- if (activeWorker) {
117
- return activeWorker;
118
- }
119
-
120
- const fallback = await this.ensureDefaultWorker();
121
- client.activeSessionId = fallback.id;
122
- return fallback;
123
- }
124
-
125
- async getActiveWorker(ws: WebSocket) {
126
- return this.getWorkerForClient(ws);
127
- }
128
-
129
- private buildBaseStatus() {
130
- const meta = this.options.buildStatusMeta();
131
- return {
132
- ...meta,
133
- connectedClients: this.clients.size,
134
- sessionCount: this.workers.size,
135
- isRunning: Boolean((meta as any).serverRunning),
136
- };
137
- }
138
-
139
- private normalizeStatusSignature(status: Record<string, unknown>) {
140
- const { lastActivityAt: _ignored, ...rest } = status;
141
- return JSON.stringify(rest);
142
- }
143
-
144
- private normalizeCatalogSignature(data: { activeSessionId: string | null; sessions: SessionSummary[] }) {
145
- return JSON.stringify({
146
- activeSessionId: data.activeSessionId,
147
- sessions: data.sessions.map(({ lastActivityAt: _ignored, ...session }) => session),
148
- });
149
- }
150
-
151
- private handleWorkerStateChange(_worker: SessionController) {
152
- this.broadcastCatalog();
153
- this.broadcastStatus();
154
- }
155
-
156
- buildOverallStatus() {
157
- const worker = this.defaultWorkerId ? this.workers.get(this.defaultWorkerId) : this.sortedWorkers()[0] || null;
158
- return {
159
- ...this.buildBaseStatus(),
160
- ...(worker ? worker.getStatus() : {
161
- childRunning: false,
162
- isStreaming: false,
163
- isCompacting: false,
164
- lastError: "",
165
- childPid: null,
166
- sessionWorkerId: null,
167
- sessionKind: "parallel",
168
- }),
169
- };
170
- }
171
-
172
- private buildClientStatus(ws: WebSocket) {
173
- const client = this.clients.get(ws);
174
- const worker = client?.activeSessionId ? this.workers.get(client.activeSessionId) : null;
175
- return {
176
- ...this.buildBaseStatus(),
177
- ...(worker ? worker.getStatus() : {
178
- childRunning: false,
179
- isStreaming: false,
180
- isCompacting: false,
181
- lastError: "",
182
- childPid: null,
183
- sessionWorkerId: null,
184
- sessionKind: "parallel",
185
- }),
186
- activeSessionId: client?.activeSessionId || null,
187
- };
188
- }
189
-
190
- private sendStatus(ws: WebSocket, options: { force?: boolean } = {}) {
191
- const data = this.buildClientStatus(ws);
192
- const signature = this.normalizeStatusSignature(data);
193
- if (!options.force && this.statusSignatures.get(ws) === signature) {
194
- return;
195
- }
196
-
197
- this.statusSignatures.set(ws, signature);
198
- this.options.send(ws, { channel: "server", event: "status", data });
199
- }
200
-
201
- private sendSnapshot(ws: WebSocket, worker: SessionController, snapshot: SessionSnapshot) {
202
- this.options.send(ws, {
203
- channel: "snapshot",
204
- sessionWorkerId: worker.id,
205
- state: snapshot.state,
206
- messages: snapshot.messages || [],
207
- commands: snapshot.commands || [],
208
- liveAssistantMessage: snapshot.liveAssistantMessage || null,
209
- liveTools: snapshot.liveTools || [],
210
- });
211
- }
212
-
213
- broadcastStatus() {
214
- for (const ws of this.clients.keys()) {
215
- this.sendStatus(ws);
216
- }
217
- }
218
-
219
- sendCatalog(ws: WebSocket, options: { force?: boolean } = {}) {
220
- const client = this.clients.get(ws);
221
- const data = {
222
- activeSessionId: client?.activeSessionId || null,
223
- sessions: this.serializeSessions(),
224
- };
225
- const signature = this.normalizeCatalogSignature(data);
226
- if (!options.force && this.catalogSignatures.get(ws) === signature) {
227
- return;
228
- }
229
-
230
- this.catalogSignatures.set(ws, signature);
231
- this.options.send(ws, {
232
- channel: "sessions",
233
- event: "catalog",
234
- data,
235
- });
236
- }
237
-
238
- broadcastCatalog() {
239
- for (const ws of this.clients.keys()) {
240
- this.sendCatalog(ws);
241
- }
242
- }
243
-
244
- private forwardEnvelope(worker: SessionController, envelope: any) {
245
- for (const [ws, client] of this.clients.entries()) {
246
- if (client.activeSessionId === worker.id) {
247
- this.options.send(ws, envelope);
248
- }
249
- }
250
- }
251
-
252
- async addClient(ws: WebSocket) {
253
- const worker = await this.ensureDefaultWorker();
254
- this.clients.set(ws, { activeSessionId: this.defaultWorkerId || worker.id });
255
- this.sendStatus(ws, { force: true });
256
- this.sendCatalog(ws, { force: true });
257
- await this.refreshActiveSnapshot(ws);
258
- }
259
-
260
- removeClient(ws: WebSocket) {
261
- this.clients.delete(ws);
262
- this.statusSignatures.delete(ws);
263
- this.catalogSignatures.delete(ws);
264
- this.broadcastStatus();
265
- }
266
-
267
- async refreshActiveSnapshot(ws: WebSocket) {
268
- const worker = await this.getWorkerForClient(ws);
269
- const requestedWorkerId = worker.id;
270
-
271
- try {
272
- const snapshot = await worker.getSnapshot();
273
- const client = this.clients.get(ws);
274
- if (client?.activeSessionId !== requestedWorkerId) {
275
- return;
276
- }
277
-
278
- this.sendSnapshot(ws, worker, snapshot);
279
- this.sendStatus(ws);
280
- if (worker.pendingUiRequest) {
281
- this.options.send(ws, { channel: "rpc", payload: worker.pendingUiRequest });
282
- }
283
- } catch (error) {
284
- const client = this.clients.get(ws);
285
- if (client?.activeSessionId !== requestedWorkerId) {
286
- return;
287
- }
288
-
289
- this.options.send(ws, {
290
- channel: "server",
291
- event: "snapshot-error",
292
- data: { message: error instanceof Error ? error.message : String(error) },
293
- });
294
- }
295
- }
296
-
297
- async broadcastSnapshots() {
298
- await Promise.all(this.getClients().map(async (ws) => this.refreshActiveSnapshot(ws)));
299
- }
300
-
301
- async selectSession(ws: WebSocket, sessionId: string) {
302
- const worker = this.workers.get(sessionId);
303
- if (!worker) {
304
- this.options.send(ws, { channel: "server", event: "client-error", data: { message: "That session no longer exists." } });
305
- return;
306
- }
307
-
308
- const client = this.clients.get(ws);
309
- if (!client) {
310
- this.clients.set(ws, { activeSessionId: sessionId });
311
- } else {
312
- client.activeSessionId = sessionId;
313
- }
314
-
315
- this.defaultWorkerId = worker.id;
316
-
317
- this.sendCatalog(ws, { force: true });
318
- this.sendStatus(ws, { force: true });
319
- this.sendSnapshot(ws, worker, worker.getCachedSnapshot());
320
- await this.refreshActiveSnapshot(ws);
321
- }
322
-
323
- async spawnSession(ws: WebSocket, sessionFile: string | null = null) {
324
- const worker = this.createParallelSession(sessionFile);
325
- let added = false;
326
- const existingClient = this.clients.get(ws);
327
- const previousActiveSessionId = existingClient?.activeSessionId || null;
328
-
329
- try {
330
- added = true;
331
- this.defaultWorkerId = worker.id;
332
-
333
- if (existingClient) {
334
- existingClient.activeSessionId = worker.id;
335
- } else {
336
- this.clients.set(ws, { activeSessionId: worker.id });
337
- }
338
-
339
- this.sendCatalog(ws, { force: true });
340
- this.sendStatus(ws, { force: true });
341
- this.sendSnapshot(ws, worker, worker.getCachedSnapshot());
342
-
343
- await worker.ensureStarted();
344
- await worker.refreshCachedSnapshot(5000).catch(() => {});
345
- this.broadcastCatalog();
346
- this.broadcastStatus();
347
- await this.refreshActiveSnapshot(ws);
348
- return worker;
349
- } catch (error) {
350
- if (added) {
351
- this.workers.delete(worker.id);
352
- }
353
- const fallbackWorker = previousActiveSessionId ? this.workers.get(previousActiveSessionId) : this.sortedWorkers()[0] || null;
354
- if (this.defaultWorkerId === worker.id) {
355
- this.defaultWorkerId = fallbackWorker?.id || null;
356
- }
357
-
358
- const client = this.clients.get(ws);
359
- if (client) {
360
- client.activeSessionId = fallbackWorker?.id || null;
361
- }
362
-
363
- await worker.dispose().catch(() => {});
364
- this.sendCatalog(ws, { force: true });
365
- this.sendStatus(ws, { force: true });
366
- if (fallbackWorker) {
367
- this.sendSnapshot(ws, fallbackWorker, fallbackWorker.getCachedSnapshot());
368
- await this.refreshActiveSnapshot(ws).catch(() => {});
369
- }
370
- this.broadcastCatalog();
371
- this.broadcastStatus();
372
- throw error;
373
- }
374
- }
375
-
376
- async removeSession(sessionId: string, options: { dispose?: boolean; fallbackSessionId?: string | null } = {}) {
377
- const worker = this.workers.get(sessionId);
378
- if (!worker) return false;
379
-
380
- const { dispose = true } = options;
381
- this.workers.delete(sessionId);
382
-
383
- let fallbackWorker = options.fallbackSessionId ? this.workers.get(options.fallbackSessionId) || null : null;
384
- if (!fallbackWorker) {
385
- fallbackWorker = this.defaultWorkerId && this.defaultWorkerId !== sessionId
386
- ? this.workers.get(this.defaultWorkerId) || null
387
- : null;
388
- }
389
- if (!fallbackWorker) {
390
- fallbackWorker = this.sortedWorkers()[0] || null;
391
- }
392
-
393
- if (this.defaultWorkerId === sessionId) {
394
- this.defaultWorkerId = fallbackWorker?.id || null;
395
- }
396
-
397
- for (const client of this.clients.values()) {
398
- if (client.activeSessionId === sessionId) {
399
- client.activeSessionId = fallbackWorker?.id || null;
400
- }
401
- }
402
-
403
- if (dispose) {
404
- await worker.dispose().catch(() => {});
405
- }
406
-
407
- this.broadcastCatalog();
408
- this.broadcastStatus();
409
- await Promise.all(this.getClients().map(async (ws) => {
410
- const client = this.clients.get(ws);
411
- if (!client?.activeSessionId) return;
412
- await this.refreshActiveSnapshot(ws).catch(() => {});
413
- }));
414
-
415
- return true;
416
- }
417
-
418
- setDefaultWorker(sessionId: string | null) {
419
- this.defaultWorkerId = sessionId && this.workers.has(sessionId) ? sessionId : this.sortedWorkers()[0]?.id || null;
420
- for (const client of this.clients.values()) {
421
- if (!client.activeSessionId || !this.workers.has(client.activeSessionId)) {
422
- client.activeSessionId = this.defaultWorkerId;
423
- }
424
- }
425
- this.broadcastCatalog();
426
- this.broadcastStatus();
427
- }
428
-
429
- bindExternalSession(session: SessionController) {
430
- this.attachSession(session);
431
- if (!this.defaultWorkerId) {
432
- this.defaultWorkerId = session.id;
433
- }
434
- }
435
-
436
- notifySessionStateChanged(session: SessionController) {
437
- this.handleWorkerStateChange(session);
438
- }
439
-
440
- forwardSessionEnvelope(session: SessionController, envelope: any) {
441
- this.forwardEnvelope(session, envelope);
442
- }
443
-
444
- async closeAllClients(options: { payload?: unknown; code?: number; reason?: string } = {}) {
445
- const { payload, code = 1000, reason = "closing" } = options;
446
- const sockets = this.getClients();
447
- this.clients.clear();
448
- this.statusSignatures.clear();
449
- this.catalogSignatures.clear();
450
-
451
- for (const ws of sockets) {
452
- if (payload) {
453
- this.options.send(ws, payload);
454
- }
455
- try {
456
- ws.close(code, reason);
457
- } catch {
458
- // ignore
459
- }
460
- }
461
- }
462
-
463
- async dispose() {
464
- await this.closeAllClients();
465
- await Promise.all([...this.workers.values()].map(async (worker) => worker.dispose().catch(() => {})));
466
- this.workers.clear();
467
- this.defaultWorkerId = null;
468
- this.defaultWorkerPromise = null;
469
- }
470
- }