adhdev 0.7.41 → 0.7.42

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.
package/dist/index.js CHANGED
@@ -34,7 +34,6 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
34
34
  // ../../oss/packages/daemon-core/src/config/config.ts
35
35
  var config_exports = {};
36
36
  __export(config_exports, {
37
- generateConnectionToken: () => generateConnectionToken,
38
37
  generateMachineId: () => generateMachineId,
39
38
  getConfigDir: () => getConfigDir,
40
39
  isSetupComplete: () => isSetupComplete,
@@ -45,6 +44,57 @@ __export(config_exports, {
45
44
  saveConfig: () => saveConfig,
46
45
  updateConfig: () => updateConfig
47
46
  });
47
+ function isPlainObject(value) {
48
+ return !!value && typeof value === "object" && !Array.isArray(value);
49
+ }
50
+ function asStringArray(value) {
51
+ if (!Array.isArray(value)) return [];
52
+ return value.filter((item) => typeof item === "string");
53
+ }
54
+ function asNullableString(value) {
55
+ return typeof value === "string" ? value : null;
56
+ }
57
+ function asOptionalString(value) {
58
+ return typeof value === "string" && value.trim() ? value : void 0;
59
+ }
60
+ function asBoolean(value, fallback) {
61
+ return typeof value === "boolean" ? value : fallback;
62
+ }
63
+ function normalizeConfig(raw) {
64
+ const parsed = isPlainObject(raw) ? raw : {};
65
+ const legacySessionReads = isPlainObject(parsed.recentSessionReads) ? parsed.recentSessionReads : {};
66
+ const sessionReads = isPlainObject(parsed.sessionReads) ? parsed.sessionReads : {};
67
+ const mergedSessionReads = Object.fromEntries(
68
+ Object.entries({ ...legacySessionReads, ...sessionReads }).filter(([, value]) => typeof value === "number" && Number.isFinite(value))
69
+ );
70
+ const sessionReadMarkers = Object.fromEntries(
71
+ Object.entries(isPlainObject(parsed.sessionReadMarkers) ? parsed.sessionReadMarkers : {}).filter(([, value]) => typeof value === "string")
72
+ );
73
+ return {
74
+ serverUrl: typeof parsed.serverUrl === "string" && parsed.serverUrl.trim() ? parsed.serverUrl : DEFAULT_CONFIG.serverUrl,
75
+ selectedIde: asNullableString(parsed.selectedIde),
76
+ configuredIdes: asStringArray(parsed.configuredIdes),
77
+ installedExtensions: asStringArray(parsed.installedExtensions),
78
+ userEmail: asNullableString(parsed.userEmail),
79
+ userName: asNullableString(parsed.userName),
80
+ setupCompleted: asBoolean(parsed.setupCompleted, DEFAULT_CONFIG.setupCompleted),
81
+ setupDate: asNullableString(parsed.setupDate),
82
+ enabledIdes: asStringArray(parsed.enabledIdes),
83
+ workspaces: Array.isArray(parsed.workspaces) ? parsed.workspaces : [],
84
+ defaultWorkspaceId: asNullableString(parsed.defaultWorkspaceId) ?? asNullableString(parsed.activeWorkspaceId),
85
+ recentActivity: Array.isArray(parsed.recentActivity) ? parsed.recentActivity : [],
86
+ sessionReads: mergedSessionReads,
87
+ sessionReadMarkers,
88
+ machineNickname: asNullableString(parsed.machineNickname),
89
+ machineId: asOptionalString(parsed.machineId),
90
+ machineSecret: parsed.machineSecret === null ? null : asOptionalString(parsed.machineSecret),
91
+ registeredMachineId: asOptionalString(parsed.registeredMachineId),
92
+ providerSettings: isPlainObject(parsed.providerSettings) ? parsed.providerSettings : {},
93
+ ideSettings: isPlainObject(parsed.ideSettings) ? parsed.ideSettings : {},
94
+ disableUpstream: asBoolean(parsed.disableUpstream, DEFAULT_CONFIG.disableUpstream ?? false),
95
+ providerDir: asOptionalString(parsed.providerDir)
96
+ };
97
+ }
48
98
  function generateMachineId() {
49
99
  return `${MACHINE_ID_PREFIX}${(0, import_crypto.randomUUID)().replace(/-/g, "")}`;
50
100
  }
@@ -88,14 +138,10 @@ function loadConfig() {
88
138
  try {
89
139
  const raw = (0, import_fs.readFileSync)(configPath, "utf-8");
90
140
  const parsed = JSON.parse(raw);
91
- const merged = { ...DEFAULT_CONFIG, ...parsed };
92
- if (merged.defaultWorkspaceId == null && merged.activeWorkspaceId != null) {
93
- merged.defaultWorkspaceId = merged.activeWorkspaceId;
94
- }
95
- delete merged.activeWorkspaceId;
96
- const ensured = ensureMachineId(merged);
141
+ const normalizedInput = normalizeConfig(parsed);
142
+ const ensured = ensureMachineId(normalizedInput);
97
143
  const normalized = ensured.config;
98
- if (ensured.changed) {
144
+ if (ensured.changed || JSON.stringify(parsed) !== JSON.stringify(normalized)) {
99
145
  try {
100
146
  saveConfig(normalized);
101
147
  } catch {
@@ -110,10 +156,11 @@ function loadConfig() {
110
156
  function saveConfig(config2) {
111
157
  const configPath = getConfigPath();
112
158
  const dir = getConfigDir();
159
+ const normalized = normalizeConfig(config2);
113
160
  if (!(0, import_fs.existsSync)(dir)) {
114
161
  (0, import_fs.mkdirSync)(dir, { recursive: true, mode: 448 });
115
162
  }
116
- (0, import_fs.writeFileSync)(configPath, JSON.stringify(config2, null, 2), { encoding: "utf-8", mode: 384 });
163
+ (0, import_fs.writeFileSync)(configPath, JSON.stringify(normalized, null, 2), { encoding: "utf-8", mode: 384 });
117
164
  try {
118
165
  (0, import_fs.chmodSync)(configPath, 384);
119
166
  } catch {
@@ -142,14 +189,6 @@ function isSetupComplete() {
142
189
  function resetConfig() {
143
190
  saveConfig({ ...DEFAULT_CONFIG });
144
191
  }
145
- function generateConnectionToken() {
146
- const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
147
- let token = "db_";
148
- for (let i = 0; i < 32; i++) {
149
- token += chars.charAt(Math.floor(Math.random() * chars.length));
150
- }
151
- return token;
152
- }
153
192
  var import_os, import_path, import_fs, import_crypto, DEFAULT_CONFIG, MACHINE_ID_PREFIX;
154
193
  var init_config = __esm({
155
194
  "../../oss/packages/daemon-core/src/config/config.ts"() {
@@ -160,18 +199,13 @@ var init_config = __esm({
160
199
  import_crypto = require("crypto");
161
200
  DEFAULT_CONFIG = {
162
201
  serverUrl: "https://api.adhf.dev",
163
- apiToken: null,
164
- connectionToken: null,
165
202
  selectedIde: null,
166
203
  configuredIdes: [],
167
204
  installedExtensions: [],
168
- autoConnect: true,
169
- notifications: true,
170
205
  userEmail: null,
171
206
  userName: null,
172
207
  setupCompleted: false,
173
208
  setupDate: null,
174
- configuredCLIs: [],
175
209
  enabledIdes: [],
176
210
  workspaces: [],
177
211
  defaultWorkspaceId: null,
@@ -2338,6 +2372,8 @@ var init_extension_provider_instance = __esm({
2338
2372
  this.detectTransition(newStatus, data);
2339
2373
  this.currentStatus = newStatus;
2340
2374
  }
2375
+ } else if (event === "stream_reset") {
2376
+ this.resetStreamState();
2341
2377
  } else if (event === "extension_connected") {
2342
2378
  this.ideType = data?.ideType || "";
2343
2379
  }
@@ -2417,6 +2453,30 @@ var init_extension_provider_instance = __esm({
2417
2453
  const title = typeof data?.title === "string" && data.title.trim() ? data.title.trim() : this.chatTitle;
2418
2454
  return title || this.agentName || this.provider.name;
2419
2455
  }
2456
+ resetStreamState() {
2457
+ if (this.currentStatus !== "idle") {
2458
+ this.detectTransition("idle", {
2459
+ title: this.chatTitle,
2460
+ agentName: this.agentName,
2461
+ extensionId: this.extensionId,
2462
+ messages: this.messages
2463
+ });
2464
+ }
2465
+ this.agentStreams = [];
2466
+ this.messages = [];
2467
+ this.activeModal = null;
2468
+ this.currentModel = "";
2469
+ this.currentMode = "";
2470
+ this.controlValues = {};
2471
+ this.currentStatus = "idle";
2472
+ this.chatId = null;
2473
+ this.chatTitle = null;
2474
+ this.agentName = "";
2475
+ this.extensionId = "";
2476
+ this.lastAgentStatus = "idle";
2477
+ this.generatingStartedAt = 0;
2478
+ this.monitor.reset();
2479
+ }
2420
2480
  };
2421
2481
  }
2422
2482
  });
@@ -2715,11 +2775,23 @@ var init_ide_provider_instance = __esm({
2715
2775
  } else if (event === "cdp_disconnected") {
2716
2776
  this.cachedChat = null;
2717
2777
  this.currentStatus = "idle";
2778
+ for (const ext of this.extensions.values()) {
2779
+ ext.onEvent("stream_reset");
2780
+ }
2718
2781
  } else if (event === "stream_update") {
2719
2782
  const extType = data?.extensionType;
2720
2783
  if (extType && this.extensions.has(extType)) {
2721
2784
  this.extensions.get(extType).onEvent("stream_update", data);
2722
2785
  }
2786
+ } else if (event === "stream_reset") {
2787
+ const extType = data?.extensionType;
2788
+ if (extType && this.extensions.has(extType)) {
2789
+ this.extensions.get(extType).onEvent("stream_reset");
2790
+ }
2791
+ } else if (event === "stream_reset_all") {
2792
+ for (const ext of this.extensions.values()) {
2793
+ ext.onEvent("stream_reset");
2794
+ }
2723
2795
  }
2724
2796
  }
2725
2797
  dispose() {
@@ -3251,6 +3323,55 @@ var init_initializer = __esm({
3251
3323
  });
3252
3324
 
3253
3325
  // ../../oss/packages/daemon-core/src/status/normalize.ts
3326
+ function truncateString(value, maxChars) {
3327
+ if (value.length <= maxChars) return value;
3328
+ if (maxChars <= 12) return value.slice(0, Math.max(0, maxChars));
3329
+ return `${value.slice(0, maxChars - 12)}...[truncated]`;
3330
+ }
3331
+ function truncateStringTail(value, maxChars) {
3332
+ if (value.length <= maxChars) return value;
3333
+ if (maxChars <= 12) return value.slice(value.length - Math.max(0, maxChars));
3334
+ return `...[truncated]${value.slice(value.length - (maxChars - 12))}`;
3335
+ }
3336
+ function trimStructuredStrings(value, maxChars) {
3337
+ if (typeof value === "string") return truncateString(value, maxChars);
3338
+ if (Array.isArray(value)) return value.map((item) => trimStructuredStrings(item, maxChars));
3339
+ if (!value || typeof value !== "object") return value;
3340
+ return Object.fromEntries(
3341
+ Object.entries(value).map(([key, nested]) => [key, trimStructuredStrings(nested, maxChars)])
3342
+ );
3343
+ }
3344
+ function estimateBytes(value) {
3345
+ try {
3346
+ return JSON.stringify(value).length;
3347
+ } catch {
3348
+ return String(value ?? "").length;
3349
+ }
3350
+ }
3351
+ function trimMessageForStatus(message, stringLimit) {
3352
+ if (!message || typeof message !== "object") return message;
3353
+ return trimStructuredStrings(message, stringLimit);
3354
+ }
3355
+ function trimMessagesForStatus(messages) {
3356
+ if (!Array.isArray(messages) || messages.length === 0) return [];
3357
+ const recent = messages.slice(-STATUS_ACTIVE_CHAT_MESSAGE_LIMIT);
3358
+ const kept = [];
3359
+ let totalBytes = 0;
3360
+ for (let i = recent.length - 1; i >= 0; i -= 1) {
3361
+ let normalized = trimMessageForStatus(recent[i], STATUS_ACTIVE_CHAT_STRING_LIMIT);
3362
+ let size = estimateBytes(normalized);
3363
+ if (size > STATUS_ACTIVE_CHAT_TOTAL_BYTES_LIMIT) {
3364
+ normalized = trimMessageForStatus(recent[i], STATUS_ACTIVE_CHAT_FALLBACK_STRING_LIMIT);
3365
+ size = estimateBytes(normalized);
3366
+ }
3367
+ if (kept.length > 0 && totalBytes + size > STATUS_ACTIVE_CHAT_TOTAL_BYTES_LIMIT) {
3368
+ continue;
3369
+ }
3370
+ kept.push(normalized);
3371
+ totalBytes += size;
3372
+ }
3373
+ return kept.reverse();
3374
+ }
3254
3375
  function hasApprovalButtons(activeModal) {
3255
3376
  return (activeModal?.buttons?.length ?? 0) > 0;
3256
3377
  }
@@ -3271,10 +3392,19 @@ function normalizeActiveChatData(activeChat) {
3271
3392
  if (!activeChat) return activeChat;
3272
3393
  return {
3273
3394
  ...activeChat,
3274
- status: normalizeManagedStatus(activeChat.status, { activeModal: activeChat.activeModal })
3395
+ status: normalizeManagedStatus(activeChat.status, { activeModal: activeChat.activeModal }),
3396
+ messages: trimMessagesForStatus(activeChat.messages),
3397
+ activeModal: activeChat.activeModal ? {
3398
+ message: truncateString(activeChat.activeModal.message || "", STATUS_MODAL_MESSAGE_LIMIT),
3399
+ buttons: (activeChat.activeModal.buttons || []).map(
3400
+ (button) => truncateString(String(button || ""), STATUS_MODAL_BUTTON_LIMIT)
3401
+ )
3402
+ } : activeChat.activeModal,
3403
+ terminalHistory: activeChat.terminalHistory ? truncateStringTail(activeChat.terminalHistory, STATUS_TERMINAL_HISTORY_LIMIT) : activeChat.terminalHistory,
3404
+ inputContent: activeChat.inputContent ? truncateString(activeChat.inputContent, STATUS_INPUT_CONTENT_LIMIT) : activeChat.inputContent
3275
3405
  };
3276
3406
  }
3277
- var WORKING_STATUSES;
3407
+ var WORKING_STATUSES, STATUS_ACTIVE_CHAT_MESSAGE_LIMIT, STATUS_ACTIVE_CHAT_TOTAL_BYTES_LIMIT, STATUS_ACTIVE_CHAT_STRING_LIMIT, STATUS_ACTIVE_CHAT_FALLBACK_STRING_LIMIT, STATUS_TERMINAL_HISTORY_LIMIT, STATUS_INPUT_CONTENT_LIMIT, STATUS_MODAL_MESSAGE_LIMIT, STATUS_MODAL_BUTTON_LIMIT;
3278
3408
  var init_normalize = __esm({
3279
3409
  "../../oss/packages/daemon-core/src/status/normalize.ts"() {
3280
3410
  "use strict";
@@ -3286,6 +3416,14 @@ var init_normalize = __esm({
3286
3416
  "thinking",
3287
3417
  "active"
3288
3418
  ]);
3419
+ STATUS_ACTIVE_CHAT_MESSAGE_LIMIT = 60;
3420
+ STATUS_ACTIVE_CHAT_TOTAL_BYTES_LIMIT = 96 * 1024;
3421
+ STATUS_ACTIVE_CHAT_STRING_LIMIT = 4 * 1024;
3422
+ STATUS_ACTIVE_CHAT_FALLBACK_STRING_LIMIT = 1024;
3423
+ STATUS_TERMINAL_HISTORY_LIMIT = 8 * 1024;
3424
+ STATUS_INPUT_CONTENT_LIMIT = 2 * 1024;
3425
+ STATUS_MODAL_MESSAGE_LIMIT = 2 * 1024;
3426
+ STATUS_MODAL_BUTTON_LIMIT = 120;
3289
3427
  }
3290
3428
  });
3291
3429
 
@@ -3427,11 +3565,10 @@ function buildCliSession(state) {
3427
3565
  runtimeWorkspaceLabel: state.runtime?.workspaceLabel,
3428
3566
  runtimeWriteOwner: state.runtime?.writeOwner || null,
3429
3567
  runtimeAttachedClients: state.runtime?.attachedClients || [],
3430
- launchMode: state.launchMode,
3431
3568
  mode: state.mode,
3432
3569
  resume: state.resume,
3433
3570
  activeChat,
3434
- capabilities: PTY_SESSION_CAPABILITIES,
3571
+ capabilities: state.mode === "terminal" ? PTY_SESSION_CAPABILITIES : CLI_CHAT_SESSION_CAPABILITIES,
3435
3572
  controlValues: state.controlValues,
3436
3573
  providerControls: buildFallbackControls(
3437
3574
  state.providerControls
@@ -3501,7 +3638,7 @@ function buildSessionEntries(allStates, cdpManagers) {
3501
3638
  }
3502
3639
  return sessions;
3503
3640
  }
3504
- var IDE_SESSION_CAPABILITIES, EXTENSION_SESSION_CAPABILITIES, PTY_SESSION_CAPABILITIES, ACP_SESSION_CAPABILITIES;
3641
+ var IDE_SESSION_CAPABILITIES, EXTENSION_SESSION_CAPABILITIES, PTY_SESSION_CAPABILITIES, CLI_CHAT_SESSION_CAPABILITIES, ACP_SESSION_CAPABILITIES;
3505
3642
  var init_builders = __esm({
3506
3643
  "../../oss/packages/daemon-core/src/status/builders.ts"() {
3507
3644
  "use strict";
@@ -3534,6 +3671,11 @@ var init_builders = __esm({
3534
3671
  "terminal_io",
3535
3672
  "resize_terminal"
3536
3673
  ];
3674
+ CLI_CHAT_SESSION_CAPABILITIES = [
3675
+ "read_chat",
3676
+ "send_message",
3677
+ "resolve_action"
3678
+ ];
3537
3679
  ACP_SESSION_CAPABILITIES = [
3538
3680
  "read_chat",
3539
3681
  "send_message",
@@ -4658,6 +4800,13 @@ var init_cdp_commands = __esm({
4658
4800
  });
4659
4801
 
4660
4802
  // ../../oss/packages/daemon-core/src/commands/stream-commands.ts
4803
+ function getCliPresentationMode(h, targetSessionId) {
4804
+ if (!targetSessionId) return null;
4805
+ const instance = h.ctx.instanceManager?.getInstance(targetSessionId);
4806
+ if (instance?.category !== "cli") return null;
4807
+ const mode = instance.getPresentationMode?.();
4808
+ return mode === "chat" || mode === "terminal" ? mode : null;
4809
+ }
4661
4810
  async function handleFocusSession(h, args) {
4662
4811
  if (!h.agentStream || !h.getCdp()) return { success: false, error: "AgentStream or CDP not available" };
4663
4812
  const sessionId = args?.targetSessionId || h.currentSession?.sessionId;
@@ -4668,6 +4817,9 @@ async function handleFocusSession(h, args) {
4668
4817
  function handlePtyInput(h, args) {
4669
4818
  const { cliType, data, targetSessionId } = args || {};
4670
4819
  if (!data) return { success: false, error: "data required" };
4820
+ if (getCliPresentationMode(h, targetSessionId) === "chat") {
4821
+ return { success: false, error: "CLI session is in chat mode", code: "CLI_VIEW_MODE_NOT_TERMINAL" };
4822
+ }
4671
4823
  const adapter = h.getCliAdapter(targetSessionId || cliType);
4672
4824
  if (!adapter || typeof adapter.writeRaw !== "function") {
4673
4825
  return { success: false, error: `CLI adapter not found: ${targetSessionId || cliType || "unknown"}` };
@@ -4678,6 +4830,9 @@ function handlePtyInput(h, args) {
4678
4830
  function handlePtyResize(h, args) {
4679
4831
  const { cliType, cols, rows, force, targetSessionId } = args || {};
4680
4832
  if (!cols || !rows) return { success: false, error: "cols and rows required" };
4833
+ if (getCliPresentationMode(h, targetSessionId) === "chat") {
4834
+ return { success: false, error: "CLI session is in chat mode", code: "CLI_VIEW_MODE_NOT_TERMINAL" };
4835
+ }
4681
4836
  const adapter = h.getCliAdapter(targetSessionId || cliType);
4682
4837
  if (!adapter || typeof adapter.resize !== "function") {
4683
4838
  return { success: false, error: `CLI adapter not found: ${targetSessionId || cliType || "unknown"}` };
@@ -18210,6 +18365,7 @@ var init_router = __esm({
18210
18365
  // ─── CLI / ACP commands ───
18211
18366
  case "launch_cli":
18212
18367
  case "stop_cli":
18368
+ case "set_cli_view_mode":
18213
18369
  case "agent_command": {
18214
18370
  return this.deps.cliManager.handleCliCommand(cmd, args);
18215
18371
  }
@@ -18562,6 +18718,20 @@ var init_reporter = __esm({
18562
18718
  ts() {
18563
18719
  return (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
18564
18720
  }
18721
+ summarizeLargePayloadSessions(payload) {
18722
+ const sessions = Array.isArray(payload.sessions) ? payload.sessions : [];
18723
+ return sessions.map((session) => ({
18724
+ id: String(session?.id || ""),
18725
+ providerType: String(session?.providerType || ""),
18726
+ bytes: (() => {
18727
+ try {
18728
+ return JSON.stringify(session).length;
18729
+ } catch {
18730
+ return 0;
18731
+ }
18732
+ })()
18733
+ })).sort((a, b2) => b2.bytes - a.bytes).slice(0, 3).map((session) => `${session.providerType || "unknown"}:${session.id}=${session.bytes}b`).join(", ");
18734
+ }
18565
18735
  async sendUnifiedStatusReport(opts) {
18566
18736
  const { serverConn, p2p } = this.deps;
18567
18737
  if (!serverConn?.isConnected()) return;
@@ -18614,9 +18784,16 @@ var init_reporter = __esm({
18614
18784
  screenshotUsage: this.deps.getScreenshotUsage?.() || null,
18615
18785
  connectedExtensions: []
18616
18786
  };
18787
+ const payloadBytes = JSON.stringify(payload).length;
18617
18788
  const p2pSent = this.sendP2PPayload(payload);
18618
18789
  if (p2pSent) {
18619
- LOG.debug("P2P", `sent (${JSON.stringify(payload).length} bytes)`);
18790
+ LOG.debug("P2P", `sent (${payloadBytes} bytes)`);
18791
+ if (payloadBytes > 256 * 1024) {
18792
+ LOG.warn(
18793
+ "P2P",
18794
+ `large status payload (${payloadBytes} bytes) top sessions: ${this.summarizeLargePayloadSessions(payload) || "n/a"}`
18795
+ );
18796
+ }
18620
18797
  }
18621
18798
  if (opts?.p2pOnly) return;
18622
18799
  const wsPayload = {
@@ -18646,7 +18823,9 @@ var init_reporter = __esm({
18646
18823
  acpModes: session.acpModes
18647
18824
  })),
18648
18825
  p2p: payload.p2p,
18649
- timestamp: now
18826
+ timestamp: now,
18827
+ detectedIdes: payload.detectedIdes,
18828
+ availableProviders: payload.availableProviders
18650
18829
  };
18651
18830
  serverConn.sendMessage("status_report", wsPayload);
18652
18831
  LOG.debug("Server", `sent status_report (${JSON.stringify(wsPayload).length} bytes)`);
@@ -19018,6 +19197,13 @@ var init_provider_cli_adapter = __esm({
19018
19197
  this.messages = [...this.committedMessages];
19019
19198
  this.structuredMessages = [...this.committedMessages];
19020
19199
  }
19200
+ normalizeParsedMessages(parsedMessages) {
19201
+ return parsedMessages.filter((message) => message && (message.role === "user" || message.role === "assistant")).map((message) => ({
19202
+ role: message.role,
19203
+ content: typeof message.content === "string" ? message.content : String(message.content || ""),
19204
+ timestamp: typeof message.timestamp === "number" && Number.isFinite(message.timestamp) ? message.timestamp : Date.now()
19205
+ }));
19206
+ }
19021
19207
  sliceFromOffset(text, start) {
19022
19208
  if (!text) return "";
19023
19209
  if (!Number.isFinite(start) || start <= 0) return text;
@@ -19414,6 +19600,15 @@ var init_provider_cli_adapter = __esm({
19414
19600
  this.onStatusChange?.();
19415
19601
  }
19416
19602
  commitCurrentTranscript() {
19603
+ const parsed = this.parseCurrentTranscript(
19604
+ this.committedMessages,
19605
+ this.responseBuffer,
19606
+ this.currentTurnScope
19607
+ );
19608
+ if (parsed && Array.isArray(parsed.messages)) {
19609
+ this.committedMessages = this.normalizeParsedMessages(parsed.messages);
19610
+ this.syncMessageViews();
19611
+ }
19417
19612
  }
19418
19613
  // ─── Script Execution ──────────────────────────
19419
19614
  runDetectStatus(text) {
@@ -19458,6 +19653,21 @@ var init_provider_cli_adapter = __esm({
19458
19653
  * Called by command handler / dashboard for rich content rendering.
19459
19654
  */
19460
19655
  getScriptParsedStatus() {
19656
+ const parsed = this.parseCurrentTranscript(
19657
+ this.committedMessages,
19658
+ this.responseBuffer,
19659
+ this.currentTurnScope
19660
+ );
19661
+ if (parsed && Array.isArray(parsed.messages)) {
19662
+ return {
19663
+ id: parsed.id || "cli_session",
19664
+ status: parsed.status || this.currentStatus,
19665
+ title: parsed.title || this.cliName,
19666
+ terminalHistory: this.terminalHistory,
19667
+ messages: parsed.messages,
19668
+ activeModal: parsed.activeModal ?? this.activeModal
19669
+ };
19670
+ }
19461
19671
  const messages = [...this.committedMessages];
19462
19672
  return {
19463
19673
  id: "cli_session",
@@ -19897,14 +20107,13 @@ var init_cli_provider_instance = __esm({
19897
20107
  init_chat_history();
19898
20108
  init_logger();
19899
20109
  CliProviderInstance = class {
19900
- constructor(provider, workingDir, cliArgs = [], instanceId, transportFactory, launchModeId) {
20110
+ constructor(provider, workingDir, cliArgs = [], instanceId, transportFactory) {
19901
20111
  this.provider = provider;
19902
20112
  this.workingDir = workingDir;
19903
20113
  this.cliArgs = cliArgs;
19904
20114
  this.type = provider.type;
19905
20115
  this.instanceId = instanceId || crypto3.randomUUID();
19906
- this.launchMode = launchModeId && provider.launchModes?.find((m) => m.id === launchModeId) || null;
19907
- this.resolvedOutputFormat = this.resolveOutputFormat();
20116
+ this.presentationMode = "terminal";
19908
20117
  this.adapter = new ProviderCliAdapter(provider, workingDir, cliArgs, transportFactory);
19909
20118
  this.monitor = new StatusMonitor();
19910
20119
  this.historyWriter = new ChatHistoryWriter();
@@ -19923,26 +20132,7 @@ var init_cli_provider_instance = __esm({
19923
20132
  lastApprovalEventAt = 0;
19924
20133
  historyWriter;
19925
20134
  instanceId;
19926
- launchMode;
19927
- resolvedOutputFormat;
19928
- /**
19929
- * Determine output rendering format from:
19930
- * 1. launchMode.outputFormat (explicit override)
19931
- * 2. launchOptions[].outputFormatMap — check actual args for matching values
19932
- * 3. Default: 'terminal'
19933
- */
19934
- resolveOutputFormat() {
19935
- if (this.launchMode?.outputFormat) return this.launchMode.outputFormat;
19936
- if (this.provider.launchOptions?.length) {
19937
- for (const opt of this.provider.launchOptions) {
19938
- if (!opt.outputFormatMap) continue;
19939
- for (const [val, fmt] of Object.entries(opt.outputFormatMap)) {
19940
- if (this.cliArgs.includes(val)) return fmt;
19941
- }
19942
- }
19943
- }
19944
- return "terminal";
19945
- }
20135
+ presentationMode;
19946
20136
  // ─── Lifecycle ─────────────────────────────────
19947
20137
  async init(context) {
19948
20138
  this.context = context;
@@ -19967,6 +20157,7 @@ var init_cli_provider_instance = __esm({
19967
20157
  }
19968
20158
  getState() {
19969
20159
  const adapterStatus = this.adapter.getStatus();
20160
+ const parsedStatus = this.adapter.getScriptParsedStatus?.() || null;
19970
20161
  const runtime = this.adapter.getRuntimeMetadata();
19971
20162
  const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
19972
20163
  if (adapterStatus.terminalHistory?.trim()) {
@@ -19982,14 +20173,13 @@ var init_cli_provider_instance = __esm({
19982
20173
  name: this.provider.name,
19983
20174
  category: "cli",
19984
20175
  status: adapterStatus.status,
19985
- mode: this.resolvedOutputFormat === "stream-json" ? "chat" : "terminal",
19986
- launchMode: this.launchMode?.id,
20176
+ mode: this.presentationMode,
19987
20177
  activeChat: {
19988
20178
  id: `${this.type}_${this.workingDir}`,
19989
- title: `${this.provider.name} \xB7 ${dirName}`,
19990
- status: adapterStatus.status,
19991
- messages: [],
19992
- activeModal: adapterStatus.activeModal,
20179
+ title: parsedStatus?.title || `${this.provider.name} \xB7 ${dirName}`,
20180
+ status: parsedStatus?.status || adapterStatus.status,
20181
+ messages: Array.isArray(parsedStatus?.messages) ? parsedStatus.messages : [],
20182
+ activeModal: parsedStatus?.activeModal ?? adapterStatus.activeModal,
19993
20183
  terminalHistory: adapterStatus.terminalHistory,
19994
20184
  inputContent: ""
19995
20185
  },
@@ -20012,6 +20202,13 @@ var init_cli_provider_instance = __esm({
20012
20202
  providerControls: this.provider.controls
20013
20203
  };
20014
20204
  }
20205
+ setPresentationMode(mode) {
20206
+ if (this.presentationMode === mode) return;
20207
+ this.presentationMode = mode;
20208
+ }
20209
+ getPresentationMode() {
20210
+ return this.presentationMode;
20211
+ }
20015
20212
  onEvent(event, data) {
20016
20213
  if (event === "send_message" && data?.text) {
20017
20214
  void this.adapter.sendMessage(data.text).catch((e) => {
@@ -20272,7 +20469,7 @@ __export(util_exports, {
20272
20469
  getSizableOrigin: () => getSizableOrigin,
20273
20470
  hexToUint8Array: () => hexToUint8Array,
20274
20471
  isObject: () => isObject,
20275
- isPlainObject: () => isPlainObject,
20472
+ isPlainObject: () => isPlainObject2,
20276
20473
  issue: () => issue,
20277
20474
  joinValues: () => joinValues,
20278
20475
  jsonStringifyReplacer: () => jsonStringifyReplacer,
@@ -20441,7 +20638,7 @@ function slugify(input) {
20441
20638
  function isObject(data) {
20442
20639
  return typeof data === "object" && data !== null && !Array.isArray(data);
20443
20640
  }
20444
- function isPlainObject(o) {
20641
+ function isPlainObject2(o) {
20445
20642
  if (isObject(o) === false)
20446
20643
  return false;
20447
20644
  const ctor = o.constructor;
@@ -20458,7 +20655,7 @@ function isPlainObject(o) {
20458
20655
  return true;
20459
20656
  }
20460
20657
  function shallowClone(o) {
20461
- if (isPlainObject(o))
20658
+ if (isPlainObject2(o))
20462
20659
  return { ...o };
20463
20660
  if (Array.isArray(o))
20464
20661
  return [...o];
@@ -20594,7 +20791,7 @@ function omit(schema, mask) {
20594
20791
  return clone(schema, def);
20595
20792
  }
20596
20793
  function extend(schema, shape) {
20597
- if (!isPlainObject(shape)) {
20794
+ if (!isPlainObject2(shape)) {
20598
20795
  throw new Error("Invalid input to extend: expected a plain object");
20599
20796
  }
20600
20797
  const checks = schema._zod.def.checks;
@@ -20617,7 +20814,7 @@ function extend(schema, shape) {
20617
20814
  return clone(schema, def);
20618
20815
  }
20619
20816
  function safeExtend(schema, shape) {
20620
- if (!isPlainObject(shape)) {
20817
+ if (!isPlainObject2(shape)) {
20621
20818
  throw new Error("Invalid input to safeExtend: expected a plain object");
20622
20819
  }
20623
20820
  const def = mergeDefs(schema._zod.def, {
@@ -22100,7 +22297,7 @@ function mergeValues(a, b2) {
22100
22297
  if (a instanceof Date && b2 instanceof Date && +a === +b2) {
22101
22298
  return { valid: true, data: a };
22102
22299
  }
22103
- if (isPlainObject(a) && isPlainObject(b2)) {
22300
+ if (isPlainObject2(a) && isPlainObject2(b2)) {
22104
22301
  const bKeys = Object.keys(b2);
22105
22302
  const sharedKeys = Object.keys(a).filter((key) => bKeys.indexOf(key) !== -1);
22106
22303
  const newObj = { ...a, ...b2 };
@@ -23295,7 +23492,7 @@ var init_schemas = __esm({
23295
23492
  $ZodType.init(inst, def);
23296
23493
  inst._zod.parse = (payload, ctx) => {
23297
23494
  const input = payload.value;
23298
- if (!isPlainObject(input)) {
23495
+ if (!isPlainObject2(input)) {
23299
23496
  payload.issues.push({
23300
23497
  expected: "record",
23301
23498
  code: "invalid_type",
@@ -37399,6 +37596,15 @@ var init_cli_manager = __esm({
37399
37596
  const hash2 = require("crypto").createHash("md5").update(require("path").resolve(dir)).digest("hex").slice(0, 8);
37400
37597
  return `${cliType}_${hash2}`;
37401
37598
  }
37599
+ getSessionPresentationMode(sessionId) {
37600
+ if (!sessionId) return null;
37601
+ const instance = this.deps.getInstanceManager()?.getInstance(sessionId);
37602
+ const mode = instance?.category === "cli" ? instance.getPresentationMode?.() : null;
37603
+ return mode === "chat" || mode === "terminal" ? mode : null;
37604
+ }
37605
+ isTerminalSession(sessionId) {
37606
+ return this.getSessionPresentationMode(sessionId) === "terminal";
37607
+ }
37402
37608
  persistRecentActivity(entry) {
37403
37609
  try {
37404
37610
  saveConfig(appendRecentActivity(loadConfig(), entry));
@@ -37454,12 +37660,12 @@ var init_cli_manager = __esm({
37454
37660
  }
37455
37661
  }, 3e3);
37456
37662
  }
37457
- async registerCliInstance(key, normalizedType, cliType, resolvedDir, cliArgs, provider, settings, attachExisting = false, launchModeId) {
37663
+ async registerCliInstance(key, normalizedType, cliType, resolvedDir, cliArgs, provider, settings, attachExisting = false) {
37458
37664
  const instanceManager = this.deps.getInstanceManager();
37459
37665
  const sessionRegistry = this.deps.getSessionRegistry?.() || null;
37460
37666
  if (!instanceManager) throw new Error("InstanceManager not available");
37461
37667
  const transportFactory = this.getTransportFactory(key, normalizedType, resolvedDir, cliArgs, attachExisting);
37462
- const cliInstance = new CliProviderInstance(provider, resolvedDir, cliArgs, key, transportFactory, launchModeId);
37668
+ const cliInstance = new CliProviderInstance(provider, resolvedDir, cliArgs, key, transportFactory);
37463
37669
  try {
37464
37670
  await instanceManager.addInstance(key, cliInstance, {
37465
37671
  serverConn: this.deps.getServerConn(),
@@ -37485,7 +37691,7 @@ var init_cli_manager = __esm({
37485
37691
  this.startCliExitMonitor(key, cliType);
37486
37692
  }
37487
37693
  // ─── Session start/management ──────────────────────────────
37488
- async startSession(cliType, workingDir, cliArgs, initialModel, launchMode, launchOptionValues) {
37694
+ async startSession(cliType, workingDir, cliArgs, initialModel) {
37489
37695
  const trimmed = (workingDir || "").trim();
37490
37696
  if (!trimmed) throw new Error("working directory required");
37491
37697
  const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os14.homedir()) : path10.resolve(trimmed);
@@ -37577,29 +37783,7 @@ ${installInfo}`
37577
37783
  if (provider) {
37578
37784
  console.log(colorize("cyan", ` \u{1F4E6} Using provider: ${provider.name} (${provider.type})`));
37579
37785
  }
37580
- let resolvedCliArgs = cliArgs;
37581
- let resolvedLaunchMode = launchMode;
37582
- const activeMode = provider?.launchModes?.length ? launchMode ? provider.launchModes.find((m) => m.id === launchMode) : provider.launchModes.find((m) => m.default) : void 0;
37583
- if (activeMode) {
37584
- resolvedLaunchMode = activeMode.id;
37585
- }
37586
- if (provider?.launchArgBuilder) {
37587
- const defaults = {};
37588
- for (const opt of provider.launchOptions || []) {
37589
- if (opt.default !== void 0) defaults[opt.id] = opt.default;
37590
- }
37591
- const modeOptions = activeMode?.options || {};
37592
- const userOptions = launchOptionValues || {};
37593
- const merged = { ...defaults, ...modeOptions, ...userOptions };
37594
- const extraArgs = provider.launchArgBuilder(merged);
37595
- if (extraArgs.length) {
37596
- resolvedCliArgs = [...cliArgs || [], ...extraArgs];
37597
- console.log(colorize("cyan", ` \u{1F680} Launch options applied: ${extraArgs.join(" ")}`));
37598
- }
37599
- } else if (activeMode?.extraArgs?.length) {
37600
- resolvedCliArgs = [...cliArgs || [], ...activeMode.extraArgs];
37601
- console.log(colorize("cyan", ` \u{1F680} Launch mode '${activeMode.name}': appending args ${activeMode.extraArgs.join(" ")}`));
37602
- }
37786
+ const resolvedCliArgs = cliArgs;
37603
37787
  const instanceManager = this.deps.getInstanceManager();
37604
37788
  if (provider && instanceManager) {
37605
37789
  const resolvedProvider = this.providerLoader.resolve(cliType, { version: cliInfo.version }) || provider;
@@ -37611,8 +37795,7 @@ ${installInfo}`
37611
37795
  resolvedCliArgs,
37612
37796
  resolvedProvider,
37613
37797
  {},
37614
- false,
37615
- resolvedLaunchMode
37798
+ false
37616
37799
  );
37617
37800
  console.log(colorize("green", ` \u2713 CLI started: ${cliInfo.displayName} v${cliInfo.version || "unknown"} in ${resolvedDir}`));
37618
37801
  } else {
@@ -37724,8 +37907,7 @@ ${installInfo}`
37724
37907
  record2.cliArgs,
37725
37908
  resolvedProvider,
37726
37909
  {},
37727
- true,
37728
- record2.launchMode
37910
+ true
37729
37911
  );
37730
37912
  restored += 1;
37731
37913
  LOG.info("CLI", `\u267B Restored hosted runtime: ${record2.runtimeKey || record2.runtimeId} (${record2.displayName || record2.workspace})`);
@@ -37767,6 +37949,14 @@ ${installInfo}`
37767
37949
  }
37768
37950
  return null;
37769
37951
  }
37952
+ findAdapterBySessionId(instanceKey) {
37953
+ if (!instanceKey) return null;
37954
+ let ik = instanceKey;
37955
+ const colonIdx = ik.lastIndexOf(":");
37956
+ if (colonIdx >= 0) ik = ik.substring(colonIdx + 1);
37957
+ const adapter = this.adapters.get(ik);
37958
+ return adapter ? { adapter, key: ik } : null;
37959
+ }
37770
37960
  // ─── CLI command handling ────────────────────────────
37771
37961
  async handleCliCommand(cmd, args) {
37772
37962
  switch (cmd) {
@@ -37795,7 +37985,7 @@ ${installInfo}`
37795
37985
  const dir = resolved.path;
37796
37986
  const launchSource = resolved.source;
37797
37987
  if (!cliType) throw new Error("cliType required");
37798
- await this.startSession(cliType, dir, args?.cliArgs, args?.initialModel, args?.launchMode, args?.launchOptionValues);
37988
+ await this.startSession(cliType, dir, args?.cliArgs, args?.initialModel);
37799
37989
  let newKey = null;
37800
37990
  for (const [k, adapter] of this.adapters) {
37801
37991
  if (adapter.cliType === cliType && adapter.workingDir === dir) {
@@ -37817,6 +38007,23 @@ ${installInfo}`
37817
38007
  }
37818
38008
  return { success: true, cliType, dir, stopped: true, mode };
37819
38009
  }
38010
+ case "set_cli_view_mode": {
38011
+ const mode = args?.mode === "chat" ? "chat" : "terminal";
38012
+ const targetSessionId = typeof args?.targetSessionId === "string" ? args.targetSessionId : "";
38013
+ const cliType = args?.cliType || args?.agentType || "";
38014
+ const dir = args?.dir || "";
38015
+ const found = this.findAdapterBySessionId(targetSessionId) || (cliType ? this.findAdapter(cliType, { instanceKey: targetSessionId, dir }) : null);
38016
+ if (!found) {
38017
+ return { success: false, error: "CLI session not found", code: "CLI_SESSION_NOT_FOUND" };
38018
+ }
38019
+ const instance = this.deps.getInstanceManager()?.getInstance(found.key);
38020
+ if (!(instance instanceof CliProviderInstance)) {
38021
+ return { success: false, error: "CLI instance not found", code: "CLI_INSTANCE_NOT_FOUND" };
38022
+ }
38023
+ instance.setPresentationMode(mode);
38024
+ this.deps.onStatusChange();
38025
+ return { success: true, id: found.key, mode };
38026
+ }
37820
38027
  case "restart_session": {
37821
38028
  const cliType = args?.cliType || args?.agentType || args?.ideType;
37822
38029
  const cfg = loadConfig();
@@ -38467,7 +38674,12 @@ var init_poller = __esm({
38467
38674
  } catch {
38468
38675
  }
38469
38676
  }
38470
- if (!resolvedActiveSessionId || !parentSessionId) continue;
38677
+ if (!resolvedActiveSessionId || !parentSessionId) {
38678
+ if (parentSessionId) {
38679
+ this.deps.onStreamsUpdated?.(ideType, []);
38680
+ }
38681
+ continue;
38682
+ }
38471
38683
  try {
38472
38684
  await agentStreamManager.syncActiveSession(cdp, parentSessionId);
38473
38685
  const stream = await agentStreamManager.collectActiveSession(cdp, parentSessionId);
@@ -38495,7 +38707,11 @@ var init_agent_stream = __esm({
38495
38707
  function forwardAgentStreamsToIdeInstance(instanceManager, ideType, streams) {
38496
38708
  const ideInstance = instanceManager.getInstance(`ide:${ideType}`);
38497
38709
  if (!ideInstance?.onEvent) return;
38710
+ const seenExtensionTypes = /* @__PURE__ */ new Set();
38498
38711
  for (const stream of streams) {
38712
+ if (typeof stream.agentType === "string" && stream.agentType) {
38713
+ seenExtensionTypes.add(stream.agentType);
38714
+ }
38499
38715
  ideInstance.onEvent("stream_update", {
38500
38716
  extensionType: stream.agentType,
38501
38717
  streams: [stream],
@@ -38512,6 +38728,16 @@ function forwardAgentStreamsToIdeInstance(instanceManager, ideType, streams) {
38512
38728
  inputContent: stream.inputContent || ""
38513
38729
  });
38514
38730
  }
38731
+ const extensionTypes = ideInstance.getExtensionTypes?.() || [];
38732
+ if (streams.length === 0) {
38733
+ ideInstance.onEvent("stream_reset_all");
38734
+ return;
38735
+ }
38736
+ for (const extensionType of extensionTypes) {
38737
+ if (!seenExtensionTypes.has(extensionType)) {
38738
+ ideInstance.onEvent("stream_reset", { extensionType });
38739
+ }
38740
+ }
38515
38741
  }
38516
38742
  var init_forward = __esm({
38517
38743
  "../../oss/packages/daemon-core/src/agent-stream/forward.ts"() {
@@ -43992,13 +44218,8 @@ var init_server_connection = __esm({
43992
44218
  LOG.info("Server", `[ServerConn] Run 'adhdev setup' to re-authenticate.`);
43993
44219
  this.setState("disconnected");
43994
44220
  try {
43995
- const path18 = require("path");
43996
- const fs16 = require("fs");
43997
- const configPath = path18.join(process.env.HOME || process.env.USERPROFILE || "", ".adhdev", "config.json");
43998
- if (fs16.existsSync(configPath)) {
43999
- fs16.unlinkSync(configPath);
44000
- LOG.info("Server", `[ServerConn] Config file removed. Re-run 'adhdev setup'.`);
44001
- }
44221
+ resetConfig();
44222
+ LOG.info("Server", `[ServerConn] Config reset. Re-run 'adhdev setup'.`);
44002
44223
  } catch {
44003
44224
  }
44004
44225
  return;
@@ -44267,10 +44488,9 @@ ${e?.stack || ""}`);
44267
44488
  async fetchTurnCredentials() {
44268
44489
  try {
44269
44490
  const serverUrl = process.env.ADHDEV_SERVER_URL || "https://api.adhf.dev";
44270
- const configPath = path15.join(os18.homedir(), ".adhdev", "config.json");
44271
44491
  let token = "";
44272
44492
  try {
44273
- const config2 = JSON.parse(fs13.readFileSync(configPath, "utf-8"));
44493
+ const config2 = loadConfig();
44274
44494
  token = config2.machineSecret || "";
44275
44495
  } catch {
44276
44496
  }
@@ -44569,8 +44789,9 @@ ${e?.stack || ""}`);
44569
44789
  log(`pty_input: REJECTED \u2014 permission=${permission} peer=${peerId}`);
44570
44790
  return;
44571
44791
  }
44572
- if (this.ptyInputHandler && parsed.data) {
44573
- this.ptyInputHandler(parsed.cliType || "", parsed.data);
44792
+ const sessionId = parsed.sessionId || parsed.cliId || parsed.cliType || "";
44793
+ if (this.ptyInputHandler && parsed.data && sessionId) {
44794
+ this.ptyInputHandler(sessionId, parsed.data);
44574
44795
  }
44575
44796
  return;
44576
44797
  }
@@ -44580,8 +44801,9 @@ ${e?.stack || ""}`);
44580
44801
  log(`pty_resize: REJECTED \u2014 permission=${permission} peer=${peerId}`);
44581
44802
  return;
44582
44803
  }
44583
- if (this.ptyResizeHandler && parsed.cols && parsed.rows) {
44584
- this.ptyResizeHandler(parsed.cliType || "", parsed.cols, parsed.rows);
44804
+ const sessionId = parsed.sessionId || parsed.cliId || parsed.cliType || "";
44805
+ if (this.ptyResizeHandler && parsed.cols && parsed.rows && sessionId) {
44806
+ this.ptyResizeHandler(sessionId, parsed.cols, parsed.rows);
44585
44807
  }
44586
44808
  return;
44587
44809
  }
@@ -44609,8 +44831,8 @@ ${e?.stack || ""}`);
44609
44831
  return sentAny;
44610
44832
  }
44611
44833
  /** Broadcast PTY output to all connected peers */
44612
- broadcastPtyOutput(cliType, data) {
44613
- const msg = JSON.stringify({ type: "pty_output", cliType, data });
44834
+ broadcastPtyOutput(sessionId, data) {
44835
+ const msg = JSON.stringify({ type: "pty_output", sessionId, data });
44614
44836
  let sentAny = false;
44615
44837
  for (const peer of this.peers.values()) {
44616
44838
  if (peer.state !== "connected" || !peer.dataChannel) continue;
@@ -45191,7 +45413,7 @@ var init_adhdev_daemon = __esm({
45191
45413
  fs15 = __toESM(require("fs"));
45192
45414
  path17 = __toESM(require("path"));
45193
45415
  import_chalk2 = __toESM(require("chalk"));
45194
- pkgVersion = "0.7.41";
45416
+ pkgVersion = "0.7.42";
45195
45417
  if (pkgVersion === "unknown") {
45196
45418
  try {
45197
45419
  const possiblePaths = [
@@ -45236,6 +45458,16 @@ var init_adhdev_daemon = __esm({
45236
45458
  constructor() {
45237
45459
  this.localPort = 19222;
45238
45460
  }
45461
+ getCliPresentationMode(sessionId) {
45462
+ if (!sessionId || !this.components) return null;
45463
+ const instance = this.components.instanceManager.getInstance(sessionId);
45464
+ if (instance?.category !== "cli") return null;
45465
+ const mode = instance.getPresentationMode?.();
45466
+ return mode === "chat" || mode === "terminal" ? mode : null;
45467
+ }
45468
+ isTerminalCliSession(sessionId) {
45469
+ return this.getCliPresentationMode(sessionId) === "terminal";
45470
+ }
45239
45471
  async start(options = {}) {
45240
45472
  try {
45241
45473
  const { installGlobalInterceptor: installGlobalInterceptor2 } = require("./logging/logger");
@@ -45265,9 +45497,6 @@ ${err?.stack || ""}`);
45265
45497
  const authToken = config2.machineSecret;
45266
45498
  if (!authToken) {
45267
45499
  console.log(import_chalk2.default.red("\n\u2717 No machine secret found."));
45268
- if (config2.connectionToken) {
45269
- console.log(import_chalk2.default.yellow(" Legacy connectionToken detected \u2014 please re-run setup."));
45270
- }
45271
45500
  console.log(import_chalk2.default.gray(" Run `adhdev setup` first.\n"));
45272
45501
  process.exit(1);
45273
45502
  }
@@ -45277,7 +45506,12 @@ ${err?.stack || ""}`);
45277
45506
  providerLogFn: LOG.forComponent("Provider").asLogFn(),
45278
45507
  cliManagerDeps: {
45279
45508
  getServerConn: () => this.serverConn,
45280
- getP2p: () => this.p2p,
45509
+ getP2p: () => ({
45510
+ broadcastPtyOutput: (key, data) => {
45511
+ if (!this.isTerminalCliSession(key)) return;
45512
+ this.p2p?.broadcastPtyOutput(key, data);
45513
+ }
45514
+ }),
45281
45515
  onStatusChange: () => this.statusReporter?.onStatusChange(),
45282
45516
  removeAgentTracking: (key) => this.statusReporter?.removeAgentTracking(key),
45283
45517
  createPtyTransportFactory: ({ runtimeId, providerType, workspace, cliArgs, attachExisting }) => new SessionHostPtyTransportFactory({
@@ -45354,14 +45588,16 @@ ${err?.stack || ""}`);
45354
45588
  return { id: req.id, success: result.success, entries: result.files, error: result.error };
45355
45589
  }
45356
45590
  });
45357
- this.p2p.onPtyInput((cliId, data) => {
45358
- const found = this.components.cliManager.findAdapter(cliId, { instanceKey: cliId });
45591
+ this.p2p.onPtyInput((sessionId, data) => {
45592
+ if (!this.isTerminalCliSession(sessionId)) return;
45593
+ const found = this.components.cliManager.findAdapter(sessionId, { instanceKey: sessionId });
45359
45594
  if (found && typeof found.adapter.writeRaw === "function") {
45360
45595
  found.adapter.writeRaw(data);
45361
45596
  }
45362
45597
  });
45363
- this.p2p.onPtyResize((cliId, cols, rows) => {
45364
- const found = this.components.cliManager.findAdapter(cliId, { instanceKey: cliId });
45598
+ this.p2p.onPtyResize((sessionId, cols, rows) => {
45599
+ if (!this.isTerminalCliSession(sessionId)) return;
45600
+ const found = this.components.cliManager.findAdapter(sessionId, { instanceKey: sessionId });
45365
45601
  if (found && typeof found.adapter.resize === "function") {
45366
45602
  found.adapter.resize(cols, rows);
45367
45603
  }
@@ -45537,6 +45773,9 @@ ${err?.stack || ""}`);
45537
45773
  case "get_runtime_snapshot": {
45538
45774
  const sessionId = typeof data.sessionId === "string" ? data.sessionId : "";
45539
45775
  if (!sessionId) return { success: false, error: "sessionId is required" };
45776
+ if (!this.isTerminalCliSession(sessionId)) {
45777
+ return { success: false, error: "CLI session is not in terminal mode", code: "CLI_VIEW_MODE_NOT_TERMINAL" };
45778
+ }
45540
45779
  if (!this.sessionHostEndpoint) return { success: false, error: "Session host unavailable" };
45541
45780
  const client = new SessionHostClient({ endpoint: this.sessionHostEndpoint });
45542
45781
  try {