adhdev 0.7.5 → 0.7.6

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/cli/index.js CHANGED
@@ -2310,6 +2310,10 @@ var init_extension_provider_instance = __esm({
2310
2310
  // meta
2311
2311
  instanceId;
2312
2312
  ideType = "";
2313
+ chatId = null;
2314
+ chatTitle = null;
2315
+ agentName = "";
2316
+ extensionId = "";
2313
2317
  constructor(provider) {
2314
2318
  this.type = provider.type;
2315
2319
  this.provider = provider;
@@ -2336,8 +2340,8 @@ var init_extension_provider_instance = __esm({
2336
2340
  category: "extension",
2337
2341
  status: this.currentStatus,
2338
2342
  activeChat: this.messages.length > 0 ? {
2339
- id: `${this.type}_session`,
2340
- title: this.provider.name,
2343
+ id: this.chatId || this.instanceId,
2344
+ title: this.chatTitle || this.agentName || this.provider.name,
2341
2345
  status: this.currentStatus,
2342
2346
  messages: this.messages,
2343
2347
  activeModal: this.activeModal,
@@ -2359,6 +2363,10 @@ var init_extension_provider_instance = __esm({
2359
2363
  if (data?.activeModal !== void 0) this.activeModal = data.activeModal;
2360
2364
  if (data?.model) this.currentModel = data.model;
2361
2365
  if (data?.mode) this.currentMode = data.mode;
2366
+ if (typeof data?.sessionId === "string" && data.sessionId.trim()) this.chatId = data.sessionId;
2367
+ if (typeof data?.title === "string" && data.title.trim()) this.chatTitle = data.title;
2368
+ if (typeof data?.agentName === "string" && data.agentName.trim()) this.agentName = data.agentName;
2369
+ if (typeof data?.extensionId === "string" && data.extensionId.trim()) this.extensionId = data.extensionId;
2362
2370
  if (data?.status) {
2363
2371
  const newStatus = data.status;
2364
2372
  this.detectTransition(newStatus, data);
@@ -2378,11 +2386,6 @@ var init_extension_provider_instance = __esm({
2378
2386
  return this.instanceId;
2379
2387
  }
2380
2388
  // ─── status transition detect ──────────────────────────────
2381
- // NOTE: Extension transitions are TRACKED but NOT emitted as events.
2382
- // The parent IdeProviderInstance already emits identical events
2383
- // (generating_started, generating_completed, waiting_approval)
2384
- // via its own detectAgentTransitions(). Emitting here would cause
2385
- // duplicate toasts with slightly different content.
2386
2389
  detectTransition(newStatus, data) {
2387
2390
  const now = Date.now();
2388
2391
  const agentStatus = newStatus === "streaming" || newStatus === "generating" ? "generating" : newStatus === "waiting_approval" ? "waiting_approval" : "idle";
@@ -2391,7 +2394,40 @@ var init_extension_provider_instance = __esm({
2391
2394
  if (agentStatus !== this.lastAgentStatus) {
2392
2395
  if (this.lastAgentStatus === "idle" && agentStatus === "generating") {
2393
2396
  this.generatingStartedAt = now;
2397
+ this.pushEvent({
2398
+ event: "agent:generating_started",
2399
+ chatTitle: this.resolveChatTitle(data),
2400
+ timestamp: now,
2401
+ ideType: this.ideType || this.type,
2402
+ agentType: this.type,
2403
+ agentName: this.agentName || this.provider.name,
2404
+ extensionId: this.extensionId || this.type
2405
+ });
2406
+ } else if (agentStatus === "waiting_approval") {
2407
+ if (!this.generatingStartedAt) this.generatingStartedAt = now;
2408
+ this.pushEvent({
2409
+ event: "agent:waiting_approval",
2410
+ chatTitle: this.resolveChatTitle(data),
2411
+ timestamp: now,
2412
+ ideType: this.ideType || this.type,
2413
+ agentType: this.type,
2414
+ agentName: this.agentName || this.provider.name,
2415
+ extensionId: this.extensionId || this.type,
2416
+ modalMessage: data?.activeModal?.message,
2417
+ modalButtons: data?.activeModal?.buttons
2418
+ });
2394
2419
  } else if (agentStatus === "idle" && (this.lastAgentStatus === "generating" || this.lastAgentStatus === "waiting_approval")) {
2420
+ const duration3 = this.generatingStartedAt ? Math.round((now - this.generatingStartedAt) / 1e3) : 0;
2421
+ this.pushEvent({
2422
+ event: "agent:generating_completed",
2423
+ chatTitle: this.resolveChatTitle(data),
2424
+ duration: duration3,
2425
+ timestamp: now,
2426
+ ideType: this.ideType || this.type,
2427
+ agentType: this.type,
2428
+ agentName: this.agentName || this.provider.name,
2429
+ extensionId: this.extensionId || this.type
2430
+ });
2395
2431
  this.generatingStartedAt = 0;
2396
2432
  }
2397
2433
  this.lastAgentStatus = agentStatus;
@@ -2411,6 +2447,10 @@ var init_extension_provider_instance = __esm({
2411
2447
  this.events = [];
2412
2448
  return events;
2413
2449
  }
2450
+ resolveChatTitle(data) {
2451
+ const title = typeof data?.title === "string" && data.title.trim() ? data.title.trim() : this.chatTitle;
2452
+ return title || this.agentName || this.provider.name;
2453
+ }
2414
2454
  };
2415
2455
  }
2416
2456
  });
@@ -38005,7 +38045,13 @@ function forwardAgentStreamsToIdeInstance(instanceManager, ideType, streams) {
38005
38045
  status: stream.status || "idle",
38006
38046
  activeModal: stream.activeModal || null,
38007
38047
  model: stream.model || void 0,
38008
- mode: stream.mode || void 0
38048
+ mode: stream.mode || void 0,
38049
+ sessionId: stream.sessionId || stream.instanceId || void 0,
38050
+ title: stream.title || stream.agentName || void 0,
38051
+ agentType: stream.agentType || void 0,
38052
+ agentName: stream.agentName || void 0,
38053
+ extensionId: stream.extensionId || void 0,
38054
+ inputContent: stream.inputContent || ""
38009
38055
  });
38010
38056
  }
38011
38057
  }
@@ -38078,14 +38124,13 @@ var init_provider_instance_manager = __esm({
38078
38124
  try {
38079
38125
  const state = instance.getState();
38080
38126
  states.push(state);
38081
- for (const event of state.pendingEvents) {
38082
- for (const listener of this.eventListeners) {
38083
- listener({
38084
- ...event,
38085
- providerType: instance.type,
38086
- instanceId: state.instanceId,
38087
- targetSessionId: state.instanceId,
38088
- providerCategory: state.category
38127
+ this.emitPendingEvents(instance.type, state);
38128
+ if (state.category === "ide") {
38129
+ for (const childState of state.extensions) {
38130
+ this.emitPendingEvents(childState.type, childState, {
38131
+ targetSessionId: childState.instanceId,
38132
+ workspaceName: state.workspace || void 0,
38133
+ parentSessionId: state.instanceId
38089
38134
  });
38090
38135
  }
38091
38136
  }
@@ -38134,6 +38179,21 @@ var init_provider_instance_manager = __esm({
38134
38179
  onEvent(listener) {
38135
38180
  this.eventListeners.push(listener);
38136
38181
  }
38182
+ emitPendingEvents(providerType, state, extra = {}) {
38183
+ for (const event of state.pendingEvents) {
38184
+ for (const listener of this.eventListeners) {
38185
+ listener({
38186
+ ...event,
38187
+ providerType,
38188
+ instanceId: state.instanceId,
38189
+ targetSessionId: state.instanceId,
38190
+ providerCategory: state.category,
38191
+ workspaceName: state.workspace || void 0,
38192
+ ...extra
38193
+ });
38194
+ }
38195
+ }
38196
+ }
38137
38197
  /**
38138
38198
  * Forward event to specific Instance
38139
38199
  */
@@ -42566,6 +42626,40 @@ var init_server_connection = __esm({
42566
42626
  });
42567
42627
 
42568
42628
  // src/daemon-p2p.ts
42629
+ function normalizeSharePermission(permission) {
42630
+ if (!permission) return void 0;
42631
+ if (permission === "view") return "remote_view";
42632
+ if (permission === "control") return "remote_control";
42633
+ if (permission === "full") return "remote_full";
42634
+ return permission;
42635
+ }
42636
+ function canPeerStartScreenshots(permission) {
42637
+ if (!permission) return true;
42638
+ return permission === "remote_view" || permission === "remote_control" || permission === "remote_full";
42639
+ }
42640
+ function canPeerSendMessages(permission) {
42641
+ if (!permission) return true;
42642
+ return permission === "chat_control" || permission === "remote_control" || permission === "remote_full";
42643
+ }
42644
+ function canPeerUseRemoteInput(permission) {
42645
+ if (!permission) return true;
42646
+ return permission === "remote_full";
42647
+ }
42648
+ function canPeerUsePrivilegedShareCommand(commandType, permission) {
42649
+ if (!permission) return true;
42650
+ switch (commandType) {
42651
+ case "read_chat":
42652
+ case "list_chats":
42653
+ return true;
42654
+ case "send_chat":
42655
+ case "new_chat":
42656
+ case "switch_chat":
42657
+ case "resolve_action":
42658
+ return canPeerSendMessages(permission);
42659
+ default:
42660
+ return false;
42661
+ }
42662
+ }
42569
42663
  var fs11, path13, os16, import_node_module, esmRequire, logFile, log, logDebug, DaemonP2PSender;
42570
42664
  var init_daemon_p2p = __esm({
42571
42665
  "src/daemon-p2p.ts"() {
@@ -42778,7 +42872,7 @@ ${e?.stack || ""}`);
42778
42872
  }
42779
42873
  }
42780
42874
  /** P2P connect Start */
42781
- async initiateconnection(peerId) {
42875
+ async initiateconnection(peerId, sharePermission) {
42782
42876
  if (!this.nodeDatachannel) {
42783
42877
  log("Cannot initiate \u2014 node-datachannel not available");
42784
42878
  return;
@@ -42871,6 +42965,7 @@ ${e?.stack || ""}`);
42871
42965
  pc,
42872
42966
  dataChannel: null,
42873
42967
  state: "connecting",
42968
+ sharePermission: normalizeSharePermission(sharePermission),
42874
42969
  screenshotActive: false,
42875
42970
  connectedAt: Date.now(),
42876
42971
  pendingCandidates: [],
@@ -42992,10 +43087,15 @@ ${e?.stack || ""}`);
42992
43087
  }
42993
43088
  if (parsed.type === "screenshot_start") {
42994
43089
  const peer = this.peers.get(peerId);
43090
+ const permission = peer?.sharePermission;
42995
43091
  if (!parsed.ideType) {
42996
43092
  log(`screenshot_start: REJECTED \u2014 no ideType from peer ${peerId}`);
42997
43093
  return;
42998
43094
  }
43095
+ if (!canPeerStartScreenshots(permission)) {
43096
+ log(`screenshot_start: REJECTED \u2014 permission=${permission || "trusted"} peer=${peerId}`);
43097
+ return;
43098
+ }
42999
43099
  if (peer) {
43000
43100
  peer.screenshotActive = true;
43001
43101
  peer.screenshotIdeType = parsed.ideType;
@@ -43024,12 +43124,22 @@ ${e?.stack || ""}`);
43024
43124
  return;
43025
43125
  }
43026
43126
  if (parsed.type === "pty_input") {
43127
+ const permission = this.peers.get(peerId)?.sharePermission;
43128
+ if (permission) {
43129
+ log(`pty_input: REJECTED \u2014 permission=${permission} peer=${peerId}`);
43130
+ return;
43131
+ }
43027
43132
  if (this.ptyInputHandler && parsed.data) {
43028
43133
  this.ptyInputHandler(parsed.cliType || "", parsed.data);
43029
43134
  }
43030
43135
  return;
43031
43136
  }
43032
43137
  if (parsed.type === "pty_resize") {
43138
+ const permission = this.peers.get(peerId)?.sharePermission;
43139
+ if (permission) {
43140
+ log(`pty_resize: REJECTED \u2014 permission=${permission} peer=${peerId}`);
43141
+ return;
43142
+ }
43033
43143
  if (this.ptyResizeHandler && parsed.cols && parsed.rows) {
43034
43144
  this.ptyResizeHandler(parsed.cliType || "", parsed.cols, parsed.rows);
43035
43145
  }
@@ -43153,6 +43263,11 @@ ${e?.stack || ""}`);
43153
43263
  // ─── P2P command/input/file handling ────────────────
43154
43264
  async handleP2PCommand(peerId, msg) {
43155
43265
  const { id, commandType, data } = msg;
43266
+ const permission = this.peers.get(peerId)?.sharePermission;
43267
+ if (!canPeerUsePrivilegedShareCommand(commandType, permission)) {
43268
+ this.sendToPeer(peerId, { type: "command_result", id, success: false, error: "Permission denied" });
43269
+ return;
43270
+ }
43156
43271
  if (!this.commandHandler) {
43157
43272
  this.sendToPeer(peerId, { type: "command_result", id, success: false, error: "No handler" });
43158
43273
  return;
@@ -43166,6 +43281,11 @@ ${e?.stack || ""}`);
43166
43281
  }
43167
43282
  async handleInputEvent(peerId, msg) {
43168
43283
  const { id, action, params, instanceId } = msg;
43284
+ const permission = this.peers.get(peerId)?.sharePermission;
43285
+ if (!canPeerUseRemoteInput(permission)) {
43286
+ this.sendToPeer(peerId, { id, type: "response", success: false, error: "Permission denied" });
43287
+ return;
43288
+ }
43169
43289
  if (!this.inputHandler) {
43170
43290
  this.sendToPeer(peerId, { id, type: "response", success: false, error: "No input handler" });
43171
43291
  return;
@@ -43183,6 +43303,11 @@ ${e?.stack || ""}`);
43183
43303
  }
43184
43304
  }
43185
43305
  async handleFileRequest(peerId, req) {
43306
+ const permission = this.peers.get(peerId)?.sharePermission;
43307
+ if (permission) {
43308
+ this.sendToPeer(peerId, { id: req.id, success: false, error: "Permission denied" });
43309
+ return;
43310
+ }
43186
43311
  let response;
43187
43312
  if (this.fileRequestHandler) {
43188
43313
  try {
@@ -43208,7 +43333,7 @@ ${e?.stack || ""}`);
43208
43333
  const peerId = payload?.peerId;
43209
43334
  if (type === "p2p_ready") {
43210
43335
  log(`p2p_ready from peer ${peerId}`);
43211
- this.initiateconnection(peerId);
43336
+ this.initiateconnection(peerId, payload?.sharePermission);
43212
43337
  return;
43213
43338
  }
43214
43339
  if (type === "p2p_answer") {
@@ -43221,6 +43346,9 @@ ${e?.stack || ""}`);
43221
43346
  log(`p2p_answer for unknown peer ${peerId} \u2014 ignoring`);
43222
43347
  return;
43223
43348
  }
43349
+ if (payload?.sharePermission) {
43350
+ peer.sharePermission = normalizeSharePermission(payload.sharePermission);
43351
+ }
43224
43352
  if (peer.remoteDescriptionSet) {
43225
43353
  log(`p2p_answer ignored: already applied for peer ${peerId} (duplicate relay)`);
43226
43354
  return;
@@ -43257,6 +43385,9 @@ ${e?.stack || ""}`);
43257
43385
  }
43258
43386
  const peer = this.peers.get(peerId);
43259
43387
  if (peer?.pc && payload.candidate) {
43388
+ if (payload?.sharePermission) {
43389
+ peer.sharePermission = normalizeSharePermission(payload.sharePermission);
43390
+ }
43260
43391
  log(`p2p_ice received from peer ${peerId}: ${String(payload.candidate).substring(0, 80)}`);
43261
43392
  if (!peer.remoteDescriptionSet) {
43262
43393
  peer.pendingCandidates.push({
@@ -43596,7 +43727,7 @@ var init_adhdev_daemon = __esm({
43596
43727
  fs12 = __toESM(require("fs"));
43597
43728
  path14 = __toESM(require("path"));
43598
43729
  import_chalk2 = __toESM(require("chalk"));
43599
- pkgVersion = "0.7.5";
43730
+ pkgVersion = "0.7.6";
43600
43731
  if (pkgVersion === "unknown") {
43601
43732
  try {
43602
43733
  const possiblePaths = [