@duckmind/dm-darwin-x64 0.33.0 → 0.33.1

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 +93 -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,418 +0,0 @@
1
- import { el, state } from "./state.js";
2
- import {
3
- assistantParts,
4
- contentToText,
5
- countImages,
6
- escapeAttribute,
7
- escapeHtml,
8
- formatTimestamp,
9
- toDetailString,
10
- stripTerminalControlSequences,
11
- } from "./formatters.js";
12
- import { renderMarkdownLite } from "./markdown.js";
13
- import { renderRichToolContent } from "./tool-rendering.js";
14
- import { scrollMessagesToBottom, showToast, updateJumpToLatestButton } from "./ui.js";
15
-
16
- const INLINE_USER_CUSTOM_TYPES = new Set(["phone-inline-user-message"]);
17
-
18
- function userContentDisplayText(content) {
19
- const imageCount = countImages(content);
20
- if (!Array.isArray(content)) return contentToText(content);
21
-
22
- const text = content
23
- .filter((part) => part?.type === "text")
24
- .map((part) => part.text || "")
25
- .join("")
26
- .trim();
27
-
28
- if (text) return text;
29
- if (imageCount === 1) return "[1 image attached]";
30
- if (imageCount > 1) return `[${imageCount} images attached]`;
31
- return contentToText(content);
32
- }
33
-
34
- function imageSource(part) {
35
- if (!part || part.type !== "image") return "";
36
- if (typeof part.previewUrl === "string" && part.previewUrl) return part.previewUrl;
37
- if (typeof part.url === "string" && part.url) return part.url;
38
- if (typeof part.data === "string" && part.data && typeof part.mimeType === "string" && part.mimeType) {
39
- return `data:${escapeAttribute(part.mimeType)};base64,${escapeAttribute(part.data)}`;
40
- }
41
- return "";
42
- }
43
-
44
- function renderUserContent(content, fallbackText = "") {
45
- if (!Array.isArray(content)) {
46
- return {
47
- html: renderMarkdownLite(typeof content === "string" ? content : fallbackText),
48
- renderedImages: 0,
49
- };
50
- }
51
-
52
- const blocks = [];
53
- let imageIndex = 0;
54
-
55
- for (const part of content) {
56
- if (part?.type === "text") {
57
- const text = String(part.text || "");
58
- if (text.trim()) {
59
- blocks.push(`<div class="user-message-text-block">${renderMarkdownLite(text)}</div>`);
60
- }
61
- continue;
62
- }
63
-
64
- if (part?.type !== "image") continue;
65
- const src = imageSource(part);
66
- if (!src) continue;
67
- imageIndex += 1;
68
- const alt = part.name || `Attached image ${imageIndex}`;
69
- blocks.push(`
70
- <div class="user-message-image-wrap">
71
- <img class="user-message-image" src="${src}" alt="${escapeAttribute(alt)}" loading="lazy" />
72
- </div>
73
- `);
74
- }
75
-
76
- if (!blocks.length) {
77
- return {
78
- html: renderMarkdownLite(fallbackText),
79
- renderedImages: 0,
80
- };
81
- }
82
-
83
- return {
84
- html: `<div class="user-message-inline-content">${blocks.join("")}</div>`,
85
- renderedImages: imageIndex,
86
- };
87
- }
88
-
89
- export function transformMessage(message, index) {
90
- if (!message || typeof message !== "object") return [];
91
-
92
- if (message.role === "user") {
93
- return [{
94
- id: `user-${message.timestamp || index}`,
95
- kind: "user",
96
- meta: formatTimestamp(message.timestamp),
97
- text: userContentDisplayText(message.content),
98
- rawContent: message.content,
99
- imageCount: countImages(message.content),
100
- }];
101
- }
102
-
103
- if (message.role === "assistant") {
104
- const parts = assistantParts(message.content);
105
- return [{
106
- id: `assistant-${message.timestamp || index}`,
107
- kind: "assistant",
108
- meta: [message.model, formatTimestamp(message.timestamp)].filter(Boolean).join(" · "),
109
- text: parts.text,
110
- thinking: parts.thinking,
111
- toolCalls: parts.toolCalls,
112
- details: message.usage || message.stopReason ? {
113
- usage: message.usage,
114
- stopReason: message.stopReason,
115
- } : undefined,
116
- }];
117
- }
118
-
119
- if (message.role === "toolResult") {
120
- return [{
121
- id: `tool-${message.toolCallId || message.timestamp || index}`,
122
- kind: "tool",
123
- toolCallId: message.toolCallId,
124
- toolName: message.toolName || "tool",
125
- title: message.toolName || "tool",
126
- status: message.isError ? "error" : "done",
127
- text: contentToText(message.content),
128
- rawContent: message.content,
129
- meta: formatTimestamp(message.timestamp),
130
- details: message.details,
131
- }];
132
- }
133
-
134
- if (message.role === "bashExecution") {
135
- return [{
136
- id: `bash-${message.timestamp || index}`,
137
- kind: "tool",
138
- toolName: "bash",
139
- title: `bash · ${message.command || ""}`,
140
- command: message.command || "",
141
- args: { command: message.command || "" },
142
- status: message.cancelled ? "cancelled" : "done",
143
- text: message.output || "",
144
- meta: formatTimestamp(message.timestamp),
145
- details: {
146
- exitCode: message.exitCode,
147
- truncated: message.truncated,
148
- fullOutputPath: message.fullOutputPath,
149
- },
150
- }];
151
- }
152
-
153
- if (message.role === "custom") {
154
- if (message.display === false) return [];
155
-
156
- if (INLINE_USER_CUSTOM_TYPES.has(message.customType || "")) {
157
- return [{
158
- id: `custom-user-${message.timestamp || index}`,
159
- kind: "user",
160
- meta: formatTimestamp(message.timestamp),
161
- text: userContentDisplayText(message.content),
162
- rawContent: message.content,
163
- imageCount: countImages(message.content),
164
- }];
165
- }
166
-
167
- return [{
168
- id: `custom-${message.timestamp || index}`,
169
- kind: "custom",
170
- title: message.customType || "extension",
171
- text: contentToText(message.content),
172
- meta: formatTimestamp(message.timestamp),
173
- details: message.details,
174
- imageCount: countImages(message.content),
175
- }];
176
- }
177
-
178
- if (message.role === "branchSummary") {
179
- return [{
180
- id: `branch-summary-${message.timestamp || index}`,
181
- kind: "summary",
182
- title: "Branch summary",
183
- text: message.summary || "",
184
- meta: formatTimestamp(message.timestamp),
185
- details: { fromId: message.fromId },
186
- }];
187
- }
188
-
189
- if (message.role === "compactionSummary") {
190
- return [{
191
- id: `compaction-summary-${message.timestamp || index}`,
192
- kind: "summary",
193
- title: `Compaction summary${message.tokensBefore ? ` · ${message.tokensBefore.toLocaleString()} tokens` : ""}`,
194
- text: message.summary || "",
195
- meta: formatTimestamp(message.timestamp),
196
- }];
197
- }
198
-
199
- return [];
200
- }
201
-
202
- function renderMessageMeta(item, options = {}) {
203
- const pills = [];
204
- if (item.imageCount && !options.suppressImageCount) {
205
- pills.push(`<span class="inline-pill">${item.imageCount} image${item.imageCount === 1 ? "" : "s"}</span>`);
206
- }
207
- if (item.status) pills.push(`<span class="inline-pill">${escapeHtml(item.status)}</span>`);
208
- return pills.join("");
209
- }
210
-
211
- function renderDetailSection(title, value, options = {}) {
212
- if (!value) return "";
213
-
214
- const body = options.markdown
215
- ? `<div class="detail-content detail-markdown">${renderMarkdownLite(value)}</div>`
216
- : `<pre class="detail-pre">${escapeHtml(value)}</pre>`;
217
-
218
- return `
219
- <details>
220
- <summary>${escapeHtml(title)}</summary>
221
- ${body}
222
- </details>
223
- `;
224
- }
225
-
226
- function renderAssistantDetails(item) {
227
- const sections = [];
228
- if (item.thinking) sections.push(renderDetailSection("Thinking", item.thinking, { markdown: true }));
229
-
230
- if (item.toolCalls?.length) {
231
- sections.push(renderDetailSection("Tool calls", JSON.stringify(item.toolCalls, null, 2)));
232
- }
233
-
234
- if (item.details) {
235
- sections.push(renderDetailSection("Details", toDetailString(item.details)));
236
- }
237
-
238
- return sections.join("");
239
- }
240
-
241
- function toolDetailsForSecondarySection(item) {
242
- if (!item.details) return null;
243
-
244
- if (String(item.toolName || item.title || "").trim().split(" · ")[0].toLowerCase() !== "edit") {
245
- return item.details;
246
- }
247
-
248
- const details = item.details && typeof item.details === "object" && !Array.isArray(item.details) ? item.details : null;
249
- if (!details) return item.details;
250
-
251
- const { diff, firstChangedLine, ...rest } = details;
252
- return Object.keys(rest).length ? rest : null;
253
- }
254
-
255
- function renderMessage(item) {
256
- const richTool = item.kind === "tool" ? renderRichToolContent(item) : "";
257
- const roleLabel = {
258
- assistant: "DM",
259
- custom: item.title || "Extension",
260
- summary: item.title || "Summary",
261
- system: "System",
262
- tool: richTool ? "Tool" : item.title || "Tool",
263
- user: "You",
264
- }[item.kind] || "Message";
265
-
266
- const renderedUser = item.kind === "user"
267
- ? renderUserContent(item.rawContent, item.text || "")
268
- : { html: "", renderedImages: 0 };
269
-
270
- const bodyMain = richTool || (item.kind === "tool"
271
- ? `<pre>${escapeHtml(item.text || "")}</pre>`
272
- : item.kind === "user"
273
- ? renderedUser.html
274
- : renderMarkdownLite(item.text || ""));
275
-
276
- const detailValue = item.kind === "tool" ? toolDetailsForSecondarySection(item) : item.details;
277
- const extraDetails = item.kind === "assistant"
278
- ? renderAssistantDetails(item)
279
- : detailValue
280
- ? renderDetailSection("Details", toDetailString(detailValue))
281
- : "";
282
-
283
- return `
284
- <article class="message ${item.kind}">
285
- <div class="message-header">
286
- <div class="role-badge">${escapeHtml(roleLabel)}${item.live ? " · live" : ""}</div>
287
- <div class="meta">${escapeHtml(item.meta || "")}</div>
288
- </div>
289
- <div class="message-body">
290
- ${bodyMain}
291
- ${richTool ? "" : renderMessageMeta(item, { suppressImageCount: renderedUser.renderedImages > 0 })}
292
- ${extraDetails}
293
- </div>
294
- </article>
295
- `;
296
- }
297
-
298
- function enrichToolItems(items) {
299
- const toolCalls = new Map();
300
-
301
- for (const item of items) {
302
- if (item.kind !== "assistant" || !Array.isArray(item.toolCalls)) continue;
303
- for (const toolCall of item.toolCalls) {
304
- if (!toolCall?.id) continue;
305
- toolCalls.set(toolCall.id, toolCall);
306
- }
307
- }
308
-
309
- return items.map((item) => {
310
- if (item.kind !== "tool" || item.args || !item.toolCallId) return item;
311
- const linked = toolCalls.get(item.toolCallId);
312
- if (!linked) return item;
313
- return { ...item, args: linked.arguments || {} };
314
- });
315
- }
316
-
317
- function currentItems() {
318
- const items = [...state.messages];
319
- for (const tool of state.liveTools.values()) items.push(tool);
320
- if (state.liveAssistant) items.push(state.liveAssistant);
321
- return enrichToolItems(items);
322
- }
323
-
324
- function hasLiveItems() {
325
- if (state.liveAssistant?.live) return true;
326
- for (const tool of state.liveTools.values()) {
327
- if (tool?.live) return true;
328
- }
329
- return false;
330
- }
331
-
332
- export function clearTransientState() {
333
- state.liveAssistant = null;
334
- state.liveTools.clear();
335
- }
336
-
337
- export function clearSnapshotView() {
338
- state.snapshotState = null;
339
- state.snapshotWorkerId = null;
340
- state.messages = [];
341
- clearTransientState();
342
- }
343
-
344
- export function handleAssistantEvent(event) {
345
- if (!event) return;
346
- if (!state.liveAssistant) {
347
- state.liveAssistant = {
348
- id: "assistant-live",
349
- kind: "assistant",
350
- live: true,
351
- text: "",
352
- thinking: "",
353
- toolCalls: [],
354
- meta: "Streaming…",
355
- };
356
- }
357
-
358
- if (event.type === "text_delta") state.liveAssistant.text += stripTerminalControlSequences(event.delta || "");
359
- if (event.type === "thinking_delta") state.liveAssistant.thinking += stripTerminalControlSequences(event.delta || "");
360
- if (event.type === "toolcall_end" && event.toolCall) {
361
- state.liveAssistant.toolCalls.push({ id: event.toolCall.id || "", name: event.toolCall.name || "tool", arguments: event.toolCall.arguments || {} });
362
- }
363
- if (event.type === "error") showToast(event.message || "Agent error", "error");
364
- renderMessages();
365
- }
366
-
367
- export function upsertLiveTool(toolId, value) {
368
- state.liveTools.set(toolId, value);
369
- renderMessages();
370
- }
371
-
372
- export function renderMessages({ forceScroll = false, streaming = hasLiveItems() } = {}) {
373
- const items = currentItems();
374
- if (!items.length) {
375
- el.messages.innerHTML = `
376
- <article class="message system">
377
- <div class="message-header"><div class="role-badge">Ready</div></div>
378
- <div class="message-body">
379
- <p>This phone UI now exposes much more of DM: commands, models, thinking, sessions, tree history, custom extension messages, and image upload.</p>
380
- </div>
381
- </article>
382
- `;
383
- updateJumpToLatestButton();
384
- return;
385
- }
386
-
387
- el.messages.innerHTML = items.map(renderMessage).join("");
388
- updateJumpToLatestButton();
389
- scrollMessagesToBottom({ force: forceScroll, streaming, behavior: "smooth" });
390
- }
391
-
392
- export function renderWidgets() {
393
- const widgets = [...state.widgets.entries()];
394
- if (!widgets.length && !state.footerStatus) {
395
- el.widgetStack.classList.add("hidden");
396
- el.widgetStack.innerHTML = "";
397
- return;
398
- }
399
-
400
- const cards = widgets.map(([key, lines]) => `
401
- <article class="widget-card">
402
- <h3>${escapeHtml(key)}</h3>
403
- <ul>${lines.map((line) => `<li>${escapeHtml(line)}</li>`).join("")}</ul>
404
- </article>
405
- `);
406
-
407
- if (state.footerStatus) {
408
- cards.unshift(`
409
- <article class="widget-card">
410
- <h3>Extension status</h3>
411
- <div>${escapeHtml(state.footerStatus)}</div>
412
- </article>
413
- `);
414
- }
415
-
416
- el.widgetStack.innerHTML = cards.join("");
417
- el.widgetStack.classList.remove("hidden");
418
- }
@@ -1,113 +0,0 @@
1
- import { renderCommandSuggestions } from "./autocomplete-controller.js";
2
- import {
3
- handleInsertOnlyLocalCommand,
4
- insertSlashCommand,
5
- prepareParentSessionNew,
6
- prepareSessionSelection,
7
- prepareSessionSpawn,
8
- tryHandleLocalCommand,
9
- } from "./commands.js";
10
- import { el, state } from "./state.js";
11
- import { closeSheet, openSheet } from "./sheet-navigation.js";
12
- import { refreshAll, sendRpc } from "./transport.js";
13
- import { autoResizeTextarea } from "./ui.js";
14
-
15
- export function sheetButtonActionKey(button) {
16
- return [
17
- button.getAttribute("data-sheet-action") || "",
18
- button.getAttribute("data-active-session-id") || "",
19
- button.getAttribute("data-session-path") || "",
20
- button.getAttribute("data-open-branch-entry") || "",
21
- button.getAttribute("data-fork-entry") || "",
22
- button.getAttribute("data-run-command") || "",
23
- button.getAttribute("data-run-local-command") || "",
24
- ].join("|");
25
- }
26
-
27
- export function handleSheetButtonAction(button) {
28
- const action = button.getAttribute("data-sheet-action");
29
- if (action === "refresh") return refreshSheet(), true;
30
- if (action === "new-session") return sendRpc({ type: "new_session" }), true;
31
- if (action === "compact") return sendRpc({ type: "compact" }), true;
32
- if (action === "stats") return sendRpc({ type: "get_session_stats" }), true;
33
- if (action === "models") return openSheet("models"), true;
34
- if (action === "thinking") return openSheet("thinking"), true;
35
- if (action === "commands") return openSheet("commands"), true;
36
- if (action === "sessions") return openSheet("sessions"), true;
37
- if (action === "new-parent-session") return handleNewParentSession(), true;
38
- if (action === "new-parallel-session") return handleSpawnActiveSession(), true;
39
- if (action === "tree") return openSheet("tree"), true;
40
-
41
- const thinkingLevel = button.getAttribute("data-thinking-level");
42
- if (thinkingLevel) return sendRpc({ type: "set_thinking_level", level: thinkingLevel }), true;
43
-
44
- const modelProvider = button.getAttribute("data-model-provider");
45
- const modelId = button.getAttribute("data-model-id");
46
- if (modelProvider && modelId) return sendRpc({ type: "set_model", provider: modelProvider, modelId }), true;
47
-
48
- const runLocalCommand = button.getAttribute("data-run-local-command");
49
- if (runLocalCommand) return handleRunLocalCommand(runLocalCommand), true;
50
-
51
- const runCommand = button.getAttribute("data-run-command");
52
- if (runCommand) return handleInsertRunCommand(runCommand), true;
53
-
54
- const activeSessionId = button.getAttribute("data-active-session-id");
55
- if (activeSessionId) return handleSelectActiveSession(activeSessionId), true;
56
-
57
- const sessionPath = button.getAttribute("data-session-path");
58
- if (sessionPath) return sendRpc({ type: "switch_session", sessionPath }), true;
59
-
60
- const openBranchEntry = button.getAttribute("data-open-branch-entry");
61
- if (openBranchEntry) return sendRpc({ type: "phone_open_branch_path", entryId: openBranchEntry }), true;
62
-
63
- const forkEntry = button.getAttribute("data-fork-entry");
64
- if (forkEntry) return sendRpc({ type: "fork", entryId: forkEntry }), true;
65
-
66
- return false;
67
- }
68
-
69
- function refreshSheet() {
70
- refreshAll();
71
- }
72
-
73
- function handleNewParentSession() {
74
- if (!prepareParentSessionNew()) return;
75
- closeSheet();
76
- }
77
-
78
- function handleSpawnActiveSession() {
79
- if (!prepareSessionSpawn()) return;
80
- closeSheet();
81
- }
82
-
83
- function handleRunLocalCommand(runLocalCommand) {
84
- if (handleInsertOnlyLocalCommand(runLocalCommand)) {
85
- closeSheet();
86
- return;
87
- }
88
-
89
- const result = tryHandleLocalCommand(`/${runLocalCommand}`, { hasAttachments: state.attachments.length > 0 });
90
- if (result === "handled") {
91
- el.promptInput.value = "";
92
- autoResizeTextarea();
93
- renderCommandSuggestions();
94
- }
95
- }
96
-
97
- function handleInsertRunCommand(runCommand) {
98
- const commandName = runCommand.replace(/^\//, "").trim();
99
- if (commandName) {
100
- insertSlashCommand(commandName);
101
- } else {
102
- el.promptInput.value = `${runCommand} `;
103
- autoResizeTextarea();
104
- renderCommandSuggestions();
105
- el.promptInput.focus();
106
- }
107
- closeSheet();
108
- }
109
-
110
- function handleSelectActiveSession(activeSessionId) {
111
- if (!prepareSessionSelection(activeSessionId)) return showToast("Not connected to DM.", "error");
112
- closeSheet();
113
- }
@@ -1,19 +0,0 @@
1
- import { renderSheet } from "./sheets-view.js";
2
- import { el, state } from "./state.js";
3
- import { sendRpc } from "./transport.js";
4
-
5
- export function openSheet(mode = "actions") {
6
- state.sheetMode = mode;
7
- el.sheetModal.classList.remove("hidden");
8
- renderSheet();
9
-
10
- if (mode === "actions") sendRpc({ type: "get_session_stats" });
11
- if (mode === "models") sendRpc({ type: "get_available_models" });
12
- if (mode === "commands") sendRpc({ type: "get_commands" });
13
- if (mode === "sessions") sendRpc({ type: "phone_list_sessions" });
14
- if (mode === "tree") sendRpc({ type: "phone_get_tree" });
15
- }
16
-
17
- export function closeSheet() {
18
- el.sheetModal.classList.add("hidden");
19
- }