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/index.js CHANGED
@@ -2303,6 +2303,10 @@ var init_extension_provider_instance = __esm({
2303
2303
  // meta
2304
2304
  instanceId;
2305
2305
  ideType = "";
2306
+ chatId = null;
2307
+ chatTitle = null;
2308
+ agentName = "";
2309
+ extensionId = "";
2306
2310
  constructor(provider) {
2307
2311
  this.type = provider.type;
2308
2312
  this.provider = provider;
@@ -2329,8 +2333,8 @@ var init_extension_provider_instance = __esm({
2329
2333
  category: "extension",
2330
2334
  status: this.currentStatus,
2331
2335
  activeChat: this.messages.length > 0 ? {
2332
- id: `${this.type}_session`,
2333
- title: this.provider.name,
2336
+ id: this.chatId || this.instanceId,
2337
+ title: this.chatTitle || this.agentName || this.provider.name,
2334
2338
  status: this.currentStatus,
2335
2339
  messages: this.messages,
2336
2340
  activeModal: this.activeModal,
@@ -2352,6 +2356,10 @@ var init_extension_provider_instance = __esm({
2352
2356
  if (data?.activeModal !== void 0) this.activeModal = data.activeModal;
2353
2357
  if (data?.model) this.currentModel = data.model;
2354
2358
  if (data?.mode) this.currentMode = data.mode;
2359
+ if (typeof data?.sessionId === "string" && data.sessionId.trim()) this.chatId = data.sessionId;
2360
+ if (typeof data?.title === "string" && data.title.trim()) this.chatTitle = data.title;
2361
+ if (typeof data?.agentName === "string" && data.agentName.trim()) this.agentName = data.agentName;
2362
+ if (typeof data?.extensionId === "string" && data.extensionId.trim()) this.extensionId = data.extensionId;
2355
2363
  if (data?.status) {
2356
2364
  const newStatus = data.status;
2357
2365
  this.detectTransition(newStatus, data);
@@ -2371,11 +2379,6 @@ var init_extension_provider_instance = __esm({
2371
2379
  return this.instanceId;
2372
2380
  }
2373
2381
  // ─── status transition detect ──────────────────────────────
2374
- // NOTE: Extension transitions are TRACKED but NOT emitted as events.
2375
- // The parent IdeProviderInstance already emits identical events
2376
- // (generating_started, generating_completed, waiting_approval)
2377
- // via its own detectAgentTransitions(). Emitting here would cause
2378
- // duplicate toasts with slightly different content.
2379
2382
  detectTransition(newStatus, data) {
2380
2383
  const now = Date.now();
2381
2384
  const agentStatus = newStatus === "streaming" || newStatus === "generating" ? "generating" : newStatus === "waiting_approval" ? "waiting_approval" : "idle";
@@ -2384,7 +2387,40 @@ var init_extension_provider_instance = __esm({
2384
2387
  if (agentStatus !== this.lastAgentStatus) {
2385
2388
  if (this.lastAgentStatus === "idle" && agentStatus === "generating") {
2386
2389
  this.generatingStartedAt = now;
2390
+ this.pushEvent({
2391
+ event: "agent:generating_started",
2392
+ chatTitle: this.resolveChatTitle(data),
2393
+ timestamp: now,
2394
+ ideType: this.ideType || this.type,
2395
+ agentType: this.type,
2396
+ agentName: this.agentName || this.provider.name,
2397
+ extensionId: this.extensionId || this.type
2398
+ });
2399
+ } else if (agentStatus === "waiting_approval") {
2400
+ if (!this.generatingStartedAt) this.generatingStartedAt = now;
2401
+ this.pushEvent({
2402
+ event: "agent:waiting_approval",
2403
+ chatTitle: this.resolveChatTitle(data),
2404
+ timestamp: now,
2405
+ ideType: this.ideType || this.type,
2406
+ agentType: this.type,
2407
+ agentName: this.agentName || this.provider.name,
2408
+ extensionId: this.extensionId || this.type,
2409
+ modalMessage: data?.activeModal?.message,
2410
+ modalButtons: data?.activeModal?.buttons
2411
+ });
2387
2412
  } else if (agentStatus === "idle" && (this.lastAgentStatus === "generating" || this.lastAgentStatus === "waiting_approval")) {
2413
+ const duration3 = this.generatingStartedAt ? Math.round((now - this.generatingStartedAt) / 1e3) : 0;
2414
+ this.pushEvent({
2415
+ event: "agent:generating_completed",
2416
+ chatTitle: this.resolveChatTitle(data),
2417
+ duration: duration3,
2418
+ timestamp: now,
2419
+ ideType: this.ideType || this.type,
2420
+ agentType: this.type,
2421
+ agentName: this.agentName || this.provider.name,
2422
+ extensionId: this.extensionId || this.type
2423
+ });
2388
2424
  this.generatingStartedAt = 0;
2389
2425
  }
2390
2426
  this.lastAgentStatus = agentStatus;
@@ -2404,6 +2440,10 @@ var init_extension_provider_instance = __esm({
2404
2440
  this.events = [];
2405
2441
  return events;
2406
2442
  }
2443
+ resolveChatTitle(data) {
2444
+ const title = typeof data?.title === "string" && data.title.trim() ? data.title.trim() : this.chatTitle;
2445
+ return title || this.agentName || this.provider.name;
2446
+ }
2407
2447
  };
2408
2448
  }
2409
2449
  });
@@ -37802,7 +37842,13 @@ function forwardAgentStreamsToIdeInstance(instanceManager, ideType, streams) {
37802
37842
  status: stream.status || "idle",
37803
37843
  activeModal: stream.activeModal || null,
37804
37844
  model: stream.model || void 0,
37805
- mode: stream.mode || void 0
37845
+ mode: stream.mode || void 0,
37846
+ sessionId: stream.sessionId || stream.instanceId || void 0,
37847
+ title: stream.title || stream.agentName || void 0,
37848
+ agentType: stream.agentType || void 0,
37849
+ agentName: stream.agentName || void 0,
37850
+ extensionId: stream.extensionId || void 0,
37851
+ inputContent: stream.inputContent || ""
37806
37852
  });
37807
37853
  }
37808
37854
  }
@@ -37875,14 +37921,13 @@ var init_provider_instance_manager = __esm({
37875
37921
  try {
37876
37922
  const state = instance.getState();
37877
37923
  states.push(state);
37878
- for (const event of state.pendingEvents) {
37879
- for (const listener of this.eventListeners) {
37880
- listener({
37881
- ...event,
37882
- providerType: instance.type,
37883
- instanceId: state.instanceId,
37884
- targetSessionId: state.instanceId,
37885
- providerCategory: state.category
37924
+ this.emitPendingEvents(instance.type, state);
37925
+ if (state.category === "ide") {
37926
+ for (const childState of state.extensions) {
37927
+ this.emitPendingEvents(childState.type, childState, {
37928
+ targetSessionId: childState.instanceId,
37929
+ workspaceName: state.workspace || void 0,
37930
+ parentSessionId: state.instanceId
37886
37931
  });
37887
37932
  }
37888
37933
  }
@@ -37931,6 +37976,21 @@ var init_provider_instance_manager = __esm({
37931
37976
  onEvent(listener) {
37932
37977
  this.eventListeners.push(listener);
37933
37978
  }
37979
+ emitPendingEvents(providerType, state, extra = {}) {
37980
+ for (const event of state.pendingEvents) {
37981
+ for (const listener of this.eventListeners) {
37982
+ listener({
37983
+ ...event,
37984
+ providerType,
37985
+ instanceId: state.instanceId,
37986
+ targetSessionId: state.instanceId,
37987
+ providerCategory: state.category,
37988
+ workspaceName: state.workspace || void 0,
37989
+ ...extra
37990
+ });
37991
+ }
37992
+ }
37993
+ }
37934
37994
  /**
37935
37995
  * Forward event to specific Instance
37936
37996
  */
@@ -42104,6 +42164,40 @@ var init_server_connection = __esm({
42104
42164
  });
42105
42165
 
42106
42166
  // src/daemon-p2p.ts
42167
+ function normalizeSharePermission(permission) {
42168
+ if (!permission) return void 0;
42169
+ if (permission === "view") return "remote_view";
42170
+ if (permission === "control") return "remote_control";
42171
+ if (permission === "full") return "remote_full";
42172
+ return permission;
42173
+ }
42174
+ function canPeerStartScreenshots(permission) {
42175
+ if (!permission) return true;
42176
+ return permission === "remote_view" || permission === "remote_control" || permission === "remote_full";
42177
+ }
42178
+ function canPeerSendMessages(permission) {
42179
+ if (!permission) return true;
42180
+ return permission === "chat_control" || permission === "remote_control" || permission === "remote_full";
42181
+ }
42182
+ function canPeerUseRemoteInput(permission) {
42183
+ if (!permission) return true;
42184
+ return permission === "remote_full";
42185
+ }
42186
+ function canPeerUsePrivilegedShareCommand(commandType, permission) {
42187
+ if (!permission) return true;
42188
+ switch (commandType) {
42189
+ case "read_chat":
42190
+ case "list_chats":
42191
+ return true;
42192
+ case "send_chat":
42193
+ case "new_chat":
42194
+ case "switch_chat":
42195
+ case "resolve_action":
42196
+ return canPeerSendMessages(permission);
42197
+ default:
42198
+ return false;
42199
+ }
42200
+ }
42107
42201
  var fs11, path13, os16, import_node_module, esmRequire, logFile, log, logDebug, DaemonP2PSender;
42108
42202
  var init_daemon_p2p = __esm({
42109
42203
  "src/daemon-p2p.ts"() {
@@ -42316,7 +42410,7 @@ ${e?.stack || ""}`);
42316
42410
  }
42317
42411
  }
42318
42412
  /** P2P connect Start */
42319
- async initiateconnection(peerId) {
42413
+ async initiateconnection(peerId, sharePermission) {
42320
42414
  if (!this.nodeDatachannel) {
42321
42415
  log("Cannot initiate \u2014 node-datachannel not available");
42322
42416
  return;
@@ -42409,6 +42503,7 @@ ${e?.stack || ""}`);
42409
42503
  pc,
42410
42504
  dataChannel: null,
42411
42505
  state: "connecting",
42506
+ sharePermission: normalizeSharePermission(sharePermission),
42412
42507
  screenshotActive: false,
42413
42508
  connectedAt: Date.now(),
42414
42509
  pendingCandidates: [],
@@ -42530,10 +42625,15 @@ ${e?.stack || ""}`);
42530
42625
  }
42531
42626
  if (parsed.type === "screenshot_start") {
42532
42627
  const peer = this.peers.get(peerId);
42628
+ const permission = peer?.sharePermission;
42533
42629
  if (!parsed.ideType) {
42534
42630
  log(`screenshot_start: REJECTED \u2014 no ideType from peer ${peerId}`);
42535
42631
  return;
42536
42632
  }
42633
+ if (!canPeerStartScreenshots(permission)) {
42634
+ log(`screenshot_start: REJECTED \u2014 permission=${permission || "trusted"} peer=${peerId}`);
42635
+ return;
42636
+ }
42537
42637
  if (peer) {
42538
42638
  peer.screenshotActive = true;
42539
42639
  peer.screenshotIdeType = parsed.ideType;
@@ -42562,12 +42662,22 @@ ${e?.stack || ""}`);
42562
42662
  return;
42563
42663
  }
42564
42664
  if (parsed.type === "pty_input") {
42665
+ const permission = this.peers.get(peerId)?.sharePermission;
42666
+ if (permission) {
42667
+ log(`pty_input: REJECTED \u2014 permission=${permission} peer=${peerId}`);
42668
+ return;
42669
+ }
42565
42670
  if (this.ptyInputHandler && parsed.data) {
42566
42671
  this.ptyInputHandler(parsed.cliType || "", parsed.data);
42567
42672
  }
42568
42673
  return;
42569
42674
  }
42570
42675
  if (parsed.type === "pty_resize") {
42676
+ const permission = this.peers.get(peerId)?.sharePermission;
42677
+ if (permission) {
42678
+ log(`pty_resize: REJECTED \u2014 permission=${permission} peer=${peerId}`);
42679
+ return;
42680
+ }
42571
42681
  if (this.ptyResizeHandler && parsed.cols && parsed.rows) {
42572
42682
  this.ptyResizeHandler(parsed.cliType || "", parsed.cols, parsed.rows);
42573
42683
  }
@@ -42691,6 +42801,11 @@ ${e?.stack || ""}`);
42691
42801
  // ─── P2P command/input/file handling ────────────────
42692
42802
  async handleP2PCommand(peerId, msg) {
42693
42803
  const { id, commandType, data } = msg;
42804
+ const permission = this.peers.get(peerId)?.sharePermission;
42805
+ if (!canPeerUsePrivilegedShareCommand(commandType, permission)) {
42806
+ this.sendToPeer(peerId, { type: "command_result", id, success: false, error: "Permission denied" });
42807
+ return;
42808
+ }
42694
42809
  if (!this.commandHandler) {
42695
42810
  this.sendToPeer(peerId, { type: "command_result", id, success: false, error: "No handler" });
42696
42811
  return;
@@ -42704,6 +42819,11 @@ ${e?.stack || ""}`);
42704
42819
  }
42705
42820
  async handleInputEvent(peerId, msg) {
42706
42821
  const { id, action, params, instanceId } = msg;
42822
+ const permission = this.peers.get(peerId)?.sharePermission;
42823
+ if (!canPeerUseRemoteInput(permission)) {
42824
+ this.sendToPeer(peerId, { id, type: "response", success: false, error: "Permission denied" });
42825
+ return;
42826
+ }
42707
42827
  if (!this.inputHandler) {
42708
42828
  this.sendToPeer(peerId, { id, type: "response", success: false, error: "No input handler" });
42709
42829
  return;
@@ -42721,6 +42841,11 @@ ${e?.stack || ""}`);
42721
42841
  }
42722
42842
  }
42723
42843
  async handleFileRequest(peerId, req) {
42844
+ const permission = this.peers.get(peerId)?.sharePermission;
42845
+ if (permission) {
42846
+ this.sendToPeer(peerId, { id: req.id, success: false, error: "Permission denied" });
42847
+ return;
42848
+ }
42724
42849
  let response;
42725
42850
  if (this.fileRequestHandler) {
42726
42851
  try {
@@ -42746,7 +42871,7 @@ ${e?.stack || ""}`);
42746
42871
  const peerId = payload?.peerId;
42747
42872
  if (type === "p2p_ready") {
42748
42873
  log(`p2p_ready from peer ${peerId}`);
42749
- this.initiateconnection(peerId);
42874
+ this.initiateconnection(peerId, payload?.sharePermission);
42750
42875
  return;
42751
42876
  }
42752
42877
  if (type === "p2p_answer") {
@@ -42759,6 +42884,9 @@ ${e?.stack || ""}`);
42759
42884
  log(`p2p_answer for unknown peer ${peerId} \u2014 ignoring`);
42760
42885
  return;
42761
42886
  }
42887
+ if (payload?.sharePermission) {
42888
+ peer.sharePermission = normalizeSharePermission(payload.sharePermission);
42889
+ }
42762
42890
  if (peer.remoteDescriptionSet) {
42763
42891
  log(`p2p_answer ignored: already applied for peer ${peerId} (duplicate relay)`);
42764
42892
  return;
@@ -42795,6 +42923,9 @@ ${e?.stack || ""}`);
42795
42923
  }
42796
42924
  const peer = this.peers.get(peerId);
42797
42925
  if (peer?.pc && payload.candidate) {
42926
+ if (payload?.sharePermission) {
42927
+ peer.sharePermission = normalizeSharePermission(payload.sharePermission);
42928
+ }
42798
42929
  log(`p2p_ice received from peer ${peerId}: ${String(payload.candidate).substring(0, 80)}`);
42799
42930
  if (!peer.remoteDescriptionSet) {
42800
42931
  peer.pendingCandidates.push({
@@ -43134,7 +43265,7 @@ var init_adhdev_daemon = __esm({
43134
43265
  fs12 = __toESM(require("fs"));
43135
43266
  path14 = __toESM(require("path"));
43136
43267
  import_chalk2 = __toESM(require("chalk"));
43137
- pkgVersion = "0.7.5";
43268
+ pkgVersion = "0.7.6";
43138
43269
  if (pkgVersion === "unknown") {
43139
43270
  try {
43140
43271
  const possiblePaths = [