@adhdev/daemon-core 0.9.34 → 0.9.36

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.mjs CHANGED
@@ -2084,6 +2084,8 @@ var init_provider_cli_adapter = __esm({
2084
2084
  messages = [];
2085
2085
  committedMessages = [];
2086
2086
  structuredMessages = [];
2087
+ committedMessagesActivitySignature = "";
2088
+ committedMessagesChangedAt = 0;
2087
2089
  currentStatus = "starting";
2088
2090
  onStatusChange = null;
2089
2091
  responseBuffer = "";
@@ -2165,10 +2167,35 @@ var init_provider_cli_adapter = __esm({
2165
2167
  providerResolutionMeta;
2166
2168
  static FINISH_RETRY_DELAY_MS = 300;
2167
2169
  static MAX_FINISH_RETRIES = 2;
2170
+ buildCommittedMessagesActivitySignature() {
2171
+ const last = this.committedMessages[this.committedMessages.length - 1];
2172
+ return [
2173
+ String(this.committedMessages.length),
2174
+ String(last?.role || ""),
2175
+ String(last?.kind || ""),
2176
+ String(last?.senderName || ""),
2177
+ String(last?.timestamp || ""),
2178
+ String(last?.receivedAt || ""),
2179
+ normalizeComparableMessageContent(last?.content || "").slice(-240)
2180
+ ].join("|");
2181
+ }
2168
2182
  syncMessageViews() {
2183
+ const signature = this.buildCommittedMessagesActivitySignature();
2184
+ if (signature !== this.committedMessagesActivitySignature) {
2185
+ this.committedMessagesActivitySignature = signature;
2186
+ this.committedMessagesChangedAt = Date.now();
2187
+ }
2169
2188
  this.messages = [...this.committedMessages];
2170
2189
  this.structuredMessages = [...this.committedMessages];
2171
2190
  }
2191
+ getLastCommittedMessageActivityAt() {
2192
+ const last = this.committedMessages[this.committedMessages.length - 1];
2193
+ const messageTime = Math.max(
2194
+ typeof last?.receivedAt === "number" && Number.isFinite(last.receivedAt) ? last.receivedAt : 0,
2195
+ typeof last?.timestamp === "number" && Number.isFinite(last.timestamp) ? last.timestamp : 0
2196
+ );
2197
+ return Math.max(messageTime, this.committedMessagesChangedAt || 0);
2198
+ }
2172
2199
  readTerminalScreenText(now = Date.now()) {
2173
2200
  const screenText = this.terminalScreen.getText() || "";
2174
2201
  this.lastScreenText = screenText;
@@ -2197,7 +2224,16 @@ var init_provider_cli_adapter = __esm({
2197
2224
  if (baseMessages.length <= _ProviderCliAdapter.PARSE_MESSAGE_TAIL_LIMIT) return baseMessages;
2198
2225
  return baseMessages.slice(-_ProviderCliAdapter.PARSE_MESSAGE_TAIL_LIMIT);
2199
2226
  }
2227
+ messagesShareStableIdentity(left, right) {
2228
+ if (left === right) return true;
2229
+ if (!left || !right) return false;
2230
+ if ((left.role || "") !== (right.role || "")) return false;
2231
+ if (left.id && right.id && String(left.id) === String(right.id)) return true;
2232
+ if (typeof left.index === "number" && typeof right.index === "number" && left.index === right.index) return true;
2233
+ return false;
2234
+ }
2200
2235
  messagesComparable(left, right) {
2236
+ if (this.messagesShareStableIdentity(left, right)) return true;
2201
2237
  if (!left || !right) return false;
2202
2238
  if ((left.role || "") !== (right.role || "")) return false;
2203
2239
  const leftText = normalizeComparableTranscriptText(left.content);
@@ -2308,9 +2344,16 @@ var init_provider_cli_adapter = __esm({
2308
2344
  /** Inject CLI scripts after construction (e.g. when resolved by ProviderLoader) */
2309
2345
  setCliScripts(scripts) {
2310
2346
  this.cliScripts = scripts;
2347
+ this.parsedStatusCache = null;
2348
+ this.parseErrorMessage = null;
2311
2349
  const scriptNames = listCliScriptNames(scripts);
2312
2350
  LOG.info("CLI", `[${this.cliType}] CLI scripts injected: [${scriptNames.join(", ")}]`);
2313
2351
  }
2352
+ /** Refresh provider scripts/config used by this adapter without restarting the PTY runtime. */
2353
+ refreshProviderDefinition(provider) {
2354
+ this.provider = provider;
2355
+ this.setCliScripts(provider.scripts || {});
2356
+ }
2314
2357
  updateRuntimeSettings(settings) {
2315
2358
  this.runtimeSettings = { ...settings };
2316
2359
  }
@@ -3341,6 +3384,69 @@ var init_provider_cli_adapter = __esm({
3341
3384
  this.committedMessages = normalized;
3342
3385
  this.syncMessageViews();
3343
3386
  }
3387
+ getSharedCommittedPrefixLength(parsedMessages) {
3388
+ const committedMessages = this.committedMessages;
3389
+ const max = Math.min(parsedMessages.length, committedMessages.length);
3390
+ let index = 0;
3391
+ while (index < max && this.messagesShareStableIdentity(parsedMessages[index], committedMessages[index])) {
3392
+ index += 1;
3393
+ }
3394
+ return index;
3395
+ }
3396
+ hydrateCommittedPrefixForParsedStatus(parsedMessages) {
3397
+ const sharedPrefixLength = this.getSharedCommittedPrefixLength(parsedMessages);
3398
+ if (sharedPrefixLength !== this.committedMessages.length) return null;
3399
+ const committedHydratedMessages = this.committedMessages.map((message, index) => {
3400
+ const timestamp = typeof message.timestamp === "number" && Number.isFinite(message.timestamp) ? message.timestamp : this.lastOutputAt || this.currentTurnScope?.startedAt || Date.now();
3401
+ const contentValue = message.content;
3402
+ return {
3403
+ role: message.role,
3404
+ content: typeof contentValue === "string" ? contentValue : String(contentValue || ""),
3405
+ timestamp,
3406
+ receivedAt: typeof message.receivedAt === "number" && Number.isFinite(message.receivedAt) ? message.receivedAt : timestamp,
3407
+ kind: message.kind,
3408
+ id: message.id || `msg_${index}`,
3409
+ index: typeof message.index === "number" ? message.index : index,
3410
+ meta: message.meta,
3411
+ senderName: message.senderName
3412
+ };
3413
+ });
3414
+ const extraMessages = parsedMessages.slice(sharedPrefixLength);
3415
+ if (extraMessages.length === 0) return committedHydratedMessages;
3416
+ const extraHydratedMessages = hydrateCliParsedMessages(extraMessages, {
3417
+ committedMessages: [],
3418
+ scope: this.currentTurnScope,
3419
+ lastOutputAt: this.lastOutputAt
3420
+ }).map((message, offset) => ({
3421
+ ...message,
3422
+ id: message.id || `msg_${sharedPrefixLength + offset}`,
3423
+ index: typeof message.index === "number" ? message.index : sharedPrefixLength + offset
3424
+ }));
3425
+ return [...committedHydratedMessages, ...extraHydratedMessages];
3426
+ }
3427
+ hydrateParsedMessagesForStatus(parsedMessages) {
3428
+ return this.hydrateCommittedPrefixForParsedStatus(parsedMessages) || hydrateCliParsedMessages(parsedMessages, {
3429
+ committedMessages: this.committedMessages,
3430
+ scope: this.currentTurnScope,
3431
+ lastOutputAt: this.lastOutputAt
3432
+ });
3433
+ }
3434
+ buildCommittedChatMessages() {
3435
+ return this.committedMessages.map((message, index) => {
3436
+ const contentValue = message.content;
3437
+ return buildChatMessage({
3438
+ role: message.role,
3439
+ content: typeof contentValue === "string" ? contentValue : String(contentValue || ""),
3440
+ timestamp: message.timestamp,
3441
+ kind: message.kind,
3442
+ meta: message.meta,
3443
+ senderName: message.senderName,
3444
+ id: message.id || `msg_${index}`,
3445
+ index: typeof message.index === "number" ? message.index : index,
3446
+ receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp
3447
+ });
3448
+ });
3449
+ }
3344
3450
  /**
3345
3451
  * Script-based full parse — returns ReadChatResult.
3346
3452
  * Called by command handler / dashboard for rich content rendering.
@@ -3366,7 +3472,7 @@ var init_provider_cli_adapter = __esm({
3366
3472
  this.onStatusChange?.();
3367
3473
  }
3368
3474
  }
3369
- if (parsed && Array.isArray(parsed.messages)) {
3475
+ if (parsed && Array.isArray(parsed.messages) && this.provider.allowInputDuringGeneration === true) {
3370
3476
  const hydratedForCommit = normalizeCliParsedMessages(parsed.messages, {
3371
3477
  committedMessages: this.committedMessages,
3372
3478
  scope: this.currentTurnScope,
@@ -3385,21 +3491,21 @@ var init_provider_cli_adapter = __esm({
3385
3491
  const shouldPreferCommittedMessages = !this.currentTurnScope && !this.activeModal && this.currentStatus === "idle";
3386
3492
  let result;
3387
3493
  if (parsed && Array.isArray(parsed.messages)) {
3388
- const parsedHydratedMessages = hydrateCliParsedMessages(parsed.messages, {
3389
- committedMessages: this.committedMessages,
3390
- scope: this.currentTurnScope,
3391
- lastOutputAt: this.lastOutputAt
3392
- });
3393
- const committedHydratedMessages = this.committedMessages.map((message, index) => buildChatMessage({
3394
- ...message,
3395
- id: message.id || `msg_${index}`,
3396
- index: typeof message.index === "number" ? message.index : index,
3397
- receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp
3398
- }));
3494
+ const parsedHydratedMessages = this.hydrateParsedMessagesForStatus(parsed.messages);
3399
3495
  const parsedLastAssistant = [...parsedHydratedMessages].reverse().find((message) => message.role === "assistant" && typeof message.content === "string" && message.content.trim());
3400
- const shouldAdoptParsedIdleReplay = !this.currentTurnScope && !this.activeModal && !!parsedLastAssistant && parsedTranscriptIsRicherThanCommitted(parsedHydratedMessages, committedHydratedMessages) && (this.currentStatus === "idle" || this.currentStatus === "generating" && this.isWaitingForResponse && parsed.status === "idle" && this.runDetectStatus(this.recentOutputBuffer) === "idle");
3496
+ const shouldAdoptParsedIdleReplay = !this.currentTurnScope && !this.activeModal && !!parsedLastAssistant && parsedTranscriptIsRicherThanCommitted(parsedHydratedMessages, this.committedMessages) && (this.currentStatus === "idle" || this.currentStatus === "generating" && this.isWaitingForResponse && parsed.status === "idle" && this.runDetectStatus(this.recentOutputBuffer) === "idle");
3401
3497
  if (shouldAdoptParsedIdleReplay) {
3402
- this.committedMessages = normalizeCliParsedMessages(parsed.messages, {
3498
+ this.committedMessages = this.getSharedCommittedPrefixLength(parsed.messages) === this.committedMessages.length ? parsedHydratedMessages.map((message) => ({
3499
+ role: message.role,
3500
+ content: typeof message.content === "string" ? message.content : String(message.content || ""),
3501
+ timestamp: message.timestamp,
3502
+ receivedAt: message.receivedAt,
3503
+ kind: message.kind,
3504
+ id: message.id,
3505
+ index: message.index,
3506
+ meta: message.meta,
3507
+ senderName: message.senderName
3508
+ })) : normalizeCliParsedMessages(parsed.messages, {
3403
3509
  committedMessages: this.committedMessages,
3404
3510
  scope: this.currentTurnScope,
3405
3511
  lastOutputAt: this.lastOutputAt
@@ -3418,15 +3524,9 @@ var init_provider_cli_adapter = __esm({
3418
3524
  this.onStatusChange?.();
3419
3525
  }
3420
3526
  }
3421
- const effectiveCommittedHydratedMessages = shouldAdoptParsedIdleReplay ? this.committedMessages.map((message, index) => buildChatMessage({
3422
- ...message,
3423
- id: message.id || `msg_${index}`,
3424
- index: typeof message.index === "number" ? message.index : index,
3425
- receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp
3426
- })) : committedHydratedMessages;
3427
- const shouldPreferCommittedHistoryReplay = !this.currentTurnScope && !this.activeModal && effectiveCommittedHydratedMessages.length > parsedHydratedMessages.length;
3527
+ const shouldPreferCommittedHistoryReplay = !this.currentTurnScope && !this.activeModal && this.committedMessages.length > parsedHydratedMessages.length;
3428
3528
  const shouldPreferCommittedIdleReplay = shouldPreferCommittedMessages && !shouldAdoptParsedIdleReplay;
3429
- const hydratedMessages = shouldPreferCommittedIdleReplay || shouldPreferCommittedHistoryReplay ? effectiveCommittedHydratedMessages : parsedHydratedMessages;
3529
+ const hydratedMessages = shouldPreferCommittedIdleReplay || shouldPreferCommittedHistoryReplay ? this.buildCommittedChatMessages() : parsedHydratedMessages;
3430
3530
  result = {
3431
3531
  id: parsed.id || "cli_session",
3432
3532
  status: parsed.status || this.currentStatus,
@@ -12825,7 +12925,14 @@ var DaemonCommandHandler = class {
12825
12925
  await this._ctx.providerLoader.fetchLatest().catch(() => {
12826
12926
  });
12827
12927
  this._ctx.providerLoader.reload();
12828
- return { success: true };
12928
+ this._ctx.providerLoader.registerToDetector();
12929
+ const refreshedInstances = this._ctx.instanceManager ? this._ctx.instanceManager.refreshProviderDefinitions((providerType) => this._ctx.providerLoader.resolve(providerType)) : 0;
12930
+ const providers = this._ctx.providerLoader.getAll().map((provider) => ({
12931
+ type: provider.type,
12932
+ name: provider.name,
12933
+ category: provider.category
12934
+ }));
12935
+ return { success: true, refreshedInstances, providers };
12829
12936
  }
12830
12937
  return { success: false, error: "ProviderLoader not initialized" };
12831
12938
  }
@@ -13080,6 +13187,11 @@ var CliProviderInstance = class {
13080
13187
  launchMode;
13081
13188
  startedAt = Date.now();
13082
13189
  onProviderSessionResolved;
13190
+ refreshProviderDefinition(provider) {
13191
+ if (provider.type !== this.type || provider.category !== "cli") return;
13192
+ this.provider = provider;
13193
+ this.adapter.refreshProviderDefinition(provider);
13194
+ }
13083
13195
  // ─── Lifecycle ─────────────────────────────────
13084
13196
  async init(context) {
13085
13197
  this.context = context;
@@ -13290,9 +13402,11 @@ var CliProviderInstance = class {
13290
13402
  const autoApproveActive = adapterStatus.status === "waiting_approval" && this.shouldAutoApprove();
13291
13403
  const visibleStatus = autoApproveActive ? "generating" : adapterStatus.status;
13292
13404
  const runtime = this.adapter.getRuntimeMetadata();
13405
+ const lastCommittedMessageActivityAt = typeof this.adapter.getLastCommittedMessageActivityAt === "function" ? this.adapter.getLastCommittedMessageActivityAt() : 0;
13293
13406
  return {
13294
13407
  id: this.instanceId,
13295
13408
  status: visibleStatus,
13409
+ lastMessageAt: lastCommittedMessageActivityAt || void 0,
13296
13410
  runtimeLifecycle: runtime?.lifecycle ?? null,
13297
13411
  runtimeSurfaceKind: runtime?.surfaceKind,
13298
13412
  runtimeRestoredFromStorage: runtime?.restoredFromStorage === true,
@@ -20784,6 +20898,9 @@ function projectHotChatSessionStatesFromProviderState(state) {
20784
20898
  const project = (item) => ({
20785
20899
  id: item.instanceId,
20786
20900
  status: item.activeChat?.status || item.status,
20901
+ unread: item.unread,
20902
+ inboxBucket: item.inboxBucket,
20903
+ lastMessageAt: item.lastMessageAt ?? item.activeChat?.lastMessageAt,
20787
20904
  runtimeLifecycle: item.runtime?.lifecycle ?? null,
20788
20905
  runtimeSurfaceKind: item.runtime?.surfaceKind,
20789
20906
  runtimeRestoredFromStorage: item.runtime?.restoredFromStorage === true,
@@ -20991,6 +21108,17 @@ var ProviderInstanceManager = class {
20991
21108
  }
20992
21109
  return updated;
20993
21110
  }
21111
+ refreshProviderDefinitions(resolveProvider) {
21112
+ let refreshed = 0;
21113
+ for (const instance of this.instances.values()) {
21114
+ if (typeof instance.refreshProviderDefinition !== "function") continue;
21115
+ const provider = resolveProvider(instance.type);
21116
+ if (!provider || typeof provider !== "object") continue;
21117
+ instance.refreshProviderDefinition(provider);
21118
+ refreshed += 1;
21119
+ }
21120
+ return refreshed;
21121
+ }
20994
21122
  // ─── cleanup ──────────────────────────────────────
20995
21123
  /**
20996
21124
  * All terminate
@@ -25235,20 +25363,7 @@ var DevServer = class _DevServer {
25235
25363
  async handleReload(_req, res) {
25236
25364
  try {
25237
25365
  this.providerLoader.reload();
25238
- let refreshedInstances = 0;
25239
- if (this.instanceManager) {
25240
- for (const id of this.instanceManager.listInstanceIds()) {
25241
- const instance = this.instanceManager.getInstance(id);
25242
- const providerType = typeof instance?.type === "string" ? instance.type : "";
25243
- if (!providerType) continue;
25244
- const resolved = this.providerLoader.resolve(providerType);
25245
- if (!resolved) continue;
25246
- if (instance && typeof instance === "object" && "provider" in instance) {
25247
- instance.provider = resolved;
25248
- refreshedInstances += 1;
25249
- }
25250
- }
25251
- }
25366
+ const refreshedInstances = this.instanceManager ? this.instanceManager.refreshProviderDefinitions((providerType) => this.providerLoader.resolve(providerType)) : 0;
25252
25367
  const providers = this.providerLoader.getAll().map((p) => ({
25253
25368
  type: p.type,
25254
25369
  name: p.name,