adhdev 0.9.35 → 0.9.37
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 +163 -37
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +163 -37
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -11420,27 +11420,86 @@ function sliceFromOffset(text, start) {
|
|
|
11420
11420
|
function hydrateCliParsedMessages(parsedMessages, options) {
|
|
11421
11421
|
const { committedMessages, scope, lastOutputAt } = options;
|
|
11422
11422
|
const referenceMessages = [...committedMessages];
|
|
11423
|
-
const referenceComparables = referenceMessages.
|
|
11423
|
+
const referenceComparables = new Array(referenceMessages.length);
|
|
11424
11424
|
const usedReferenceIndexes = /* @__PURE__ */ new Set();
|
|
11425
11425
|
const now = options.now ?? Date.now();
|
|
11426
|
-
|
|
11426
|
+
let exactReferenceIndexesByKey = null;
|
|
11427
|
+
const exactReferenceCursorByKey = /* @__PURE__ */ new Map();
|
|
11428
|
+
const hasFiniteTimestamp = (message) => typeof message?.timestamp === "number" && Number.isFinite(message.timestamp);
|
|
11429
|
+
const getReferenceComparable = (index) => {
|
|
11430
|
+
if (typeof referenceComparables[index] === "string") return referenceComparables[index] || "";
|
|
11431
|
+
const comparable = normalizeComparableMessageContent(referenceMessages[index]?.content || "");
|
|
11432
|
+
referenceComparables[index] = comparable;
|
|
11433
|
+
return comparable;
|
|
11434
|
+
};
|
|
11435
|
+
const messagesShareStableIdentity = (parsed, reference) => {
|
|
11436
|
+
if (!parsed || !reference) return false;
|
|
11437
|
+
const parsedId = typeof parsed.id === "string" ? parsed.id.trim() : "";
|
|
11438
|
+
const referenceId = typeof reference.id === "string" ? reference.id.trim() : "";
|
|
11439
|
+
if (parsedId && referenceId && parsedId === referenceId) return true;
|
|
11440
|
+
return typeof parsed.index === "number" && Number.isFinite(parsed.index) && typeof reference.index === "number" && Number.isFinite(reference.index) && parsed.index === reference.index;
|
|
11441
|
+
};
|
|
11442
|
+
const exactReferenceKey = (role, comparable) => `${role}\0${comparable}`;
|
|
11443
|
+
const ensureExactReferenceIndex = () => {
|
|
11444
|
+
if (exactReferenceIndexesByKey) return exactReferenceIndexesByKey;
|
|
11445
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
11446
|
+
for (let i = 0; i < referenceMessages.length; i++) {
|
|
11447
|
+
const candidate = referenceMessages[i];
|
|
11448
|
+
if (!candidate || candidate.role !== "user" && candidate.role !== "assistant" || !hasFiniteTimestamp(candidate)) continue;
|
|
11449
|
+
const comparable = getReferenceComparable(i);
|
|
11450
|
+
if (!comparable) continue;
|
|
11451
|
+
const key = exactReferenceKey(candidate.role, comparable);
|
|
11452
|
+
const indexes = byKey.get(key);
|
|
11453
|
+
if (indexes) {
|
|
11454
|
+
indexes.push(i);
|
|
11455
|
+
} else {
|
|
11456
|
+
byKey.set(key, [i]);
|
|
11457
|
+
}
|
|
11458
|
+
}
|
|
11459
|
+
exactReferenceIndexesByKey = byKey;
|
|
11460
|
+
return byKey;
|
|
11461
|
+
};
|
|
11462
|
+
const takeExactReferenceTimestamp = (role, normalizedContent) => {
|
|
11463
|
+
const key = exactReferenceKey(role, normalizedContent);
|
|
11464
|
+
const indexes = ensureExactReferenceIndex().get(key);
|
|
11465
|
+
if (!indexes) return void 0;
|
|
11466
|
+
let cursor = exactReferenceCursorByKey.get(key) || 0;
|
|
11467
|
+
while (cursor < indexes.length) {
|
|
11468
|
+
const candidateIndex = indexes[cursor];
|
|
11469
|
+
cursor += 1;
|
|
11470
|
+
if (usedReferenceIndexes.has(candidateIndex)) continue;
|
|
11471
|
+
const candidate = referenceMessages[candidateIndex];
|
|
11472
|
+
if (!candidate || candidate.role !== role || !hasFiniteTimestamp(candidate)) continue;
|
|
11473
|
+
usedReferenceIndexes.add(candidateIndex);
|
|
11474
|
+
exactReferenceCursorByKey.set(key, cursor);
|
|
11475
|
+
return candidate.timestamp;
|
|
11476
|
+
}
|
|
11477
|
+
exactReferenceCursorByKey.set(key, cursor);
|
|
11478
|
+
return void 0;
|
|
11479
|
+
};
|
|
11480
|
+
const findReferenceTimestamp = (message, role, content, parsedIndex) => {
|
|
11481
|
+
const sameIndex = referenceMessages[parsedIndex];
|
|
11482
|
+
if (sameIndex && !usedReferenceIndexes.has(parsedIndex) && sameIndex.role === role && hasFiniteTimestamp(sameIndex) && messagesShareStableIdentity(message, sameIndex)) {
|
|
11483
|
+
usedReferenceIndexes.add(parsedIndex);
|
|
11484
|
+
return sameIndex.timestamp;
|
|
11485
|
+
}
|
|
11427
11486
|
const normalizedContent = normalizeComparableMessageContent(content);
|
|
11428
11487
|
if (!normalizedContent) return void 0;
|
|
11429
|
-
|
|
11430
|
-
if (sameIndex && !usedReferenceIndexes.has(parsedIndex) && sameIndex.role === role && referenceComparables[parsedIndex] === normalizedContent && typeof sameIndex.timestamp === "number" && Number.isFinite(sameIndex.timestamp)) {
|
|
11488
|
+
if (sameIndex && !usedReferenceIndexes.has(parsedIndex) && sameIndex.role === role && getReferenceComparable(parsedIndex) === normalizedContent && hasFiniteTimestamp(sameIndex)) {
|
|
11431
11489
|
usedReferenceIndexes.add(parsedIndex);
|
|
11432
11490
|
return sameIndex.timestamp;
|
|
11433
11491
|
}
|
|
11492
|
+
const exactTimestamp = takeExactReferenceTimestamp(role, normalizedContent);
|
|
11493
|
+
if (typeof exactTimestamp === "number") return exactTimestamp;
|
|
11434
11494
|
for (let i = 0; i < referenceMessages.length; i++) {
|
|
11435
11495
|
if (usedReferenceIndexes.has(i)) continue;
|
|
11436
11496
|
const candidate = referenceMessages[i];
|
|
11437
11497
|
if (!candidate || candidate.role !== role) continue;
|
|
11438
|
-
const candidateContent =
|
|
11498
|
+
const candidateContent = getReferenceComparable(i);
|
|
11439
11499
|
if (!candidateContent) continue;
|
|
11440
|
-
const exactMatch = candidateContent === normalizedContent;
|
|
11441
11500
|
const fuzzyMatch = candidateContent.includes(normalizedContent) || normalizedContent.includes(candidateContent);
|
|
11442
|
-
if (!
|
|
11443
|
-
if (
|
|
11501
|
+
if (!fuzzyMatch) continue;
|
|
11502
|
+
if (hasFiniteTimestamp(candidate)) {
|
|
11444
11503
|
usedReferenceIndexes.add(i);
|
|
11445
11504
|
return candidate.timestamp;
|
|
11446
11505
|
}
|
|
@@ -11451,7 +11510,7 @@ function hydrateCliParsedMessages(parsedMessages, options) {
|
|
|
11451
11510
|
const role = message.role;
|
|
11452
11511
|
const content = typeof message.content === "string" ? message.content : String(message.content || "");
|
|
11453
11512
|
const parsedTimestamp = typeof message.timestamp === "number" && Number.isFinite(message.timestamp) ? message.timestamp : void 0;
|
|
11454
|
-
const referenceTimestamp = parsedTimestamp ?? findReferenceTimestamp(role, content, index);
|
|
11513
|
+
const referenceTimestamp = parsedTimestamp ?? findReferenceTimestamp(message, role, content, index);
|
|
11455
11514
|
const fallbackTimestamp = role === "user" ? scope?.startedAt || now : lastOutputAt || scope?.startedAt || now;
|
|
11456
11515
|
const timestamp = referenceTimestamp ?? fallbackTimestamp;
|
|
11457
11516
|
return {
|
|
@@ -11957,7 +12016,16 @@ var init_provider_cli_adapter = __esm({
|
|
|
11957
12016
|
if (baseMessages.length <= _ProviderCliAdapter.PARSE_MESSAGE_TAIL_LIMIT) return baseMessages;
|
|
11958
12017
|
return baseMessages.slice(-_ProviderCliAdapter.PARSE_MESSAGE_TAIL_LIMIT);
|
|
11959
12018
|
}
|
|
12019
|
+
messagesShareStableIdentity(left2, right2) {
|
|
12020
|
+
if (left2 === right2) return true;
|
|
12021
|
+
if (!left2 || !right2) return false;
|
|
12022
|
+
if ((left2.role || "") !== (right2.role || "")) return false;
|
|
12023
|
+
if (left2.id && right2.id && String(left2.id) === String(right2.id)) return true;
|
|
12024
|
+
if (typeof left2.index === "number" && typeof right2.index === "number" && left2.index === right2.index) return true;
|
|
12025
|
+
return false;
|
|
12026
|
+
}
|
|
11960
12027
|
messagesComparable(left2, right2) {
|
|
12028
|
+
if (this.messagesShareStableIdentity(left2, right2)) return true;
|
|
11961
12029
|
if (!left2 || !right2) return false;
|
|
11962
12030
|
if ((left2.role || "") !== (right2.role || "")) return false;
|
|
11963
12031
|
const leftText = normalizeComparableTranscriptText(left2.content);
|
|
@@ -13062,11 +13130,12 @@ var init_provider_cli_adapter = __esm({
|
|
|
13062
13130
|
};
|
|
13063
13131
|
}
|
|
13064
13132
|
// ─── Public API (CliAdapter) ───────────────────
|
|
13065
|
-
getStatus() {
|
|
13066
|
-
const
|
|
13133
|
+
getStatus(options = {}) {
|
|
13134
|
+
const allowParse = options.allowParse !== false;
|
|
13135
|
+
const startupModal = allowParse && this.startupParseGate ? this.runParseApproval(this.recentOutputBuffer) : null;
|
|
13067
13136
|
let effectiveStatus = this.projectEffectiveStatus(startupModal);
|
|
13068
13137
|
let effectiveModal = startupModal || this.activeModal;
|
|
13069
|
-
if (!startupModal && !effectiveModal && typeof this.cliScripts?.parseOutput === "function") {
|
|
13138
|
+
if (allowParse && !startupModal && !effectiveModal && typeof this.cliScripts?.parseOutput === "function") {
|
|
13070
13139
|
let parsed = this.getFreshParsedStatusCache();
|
|
13071
13140
|
if (!parsed && effectiveStatus !== "idle") {
|
|
13072
13141
|
const now = Date.now();
|
|
@@ -13108,6 +13177,69 @@ var init_provider_cli_adapter = __esm({
|
|
|
13108
13177
|
this.committedMessages = normalized;
|
|
13109
13178
|
this.syncMessageViews();
|
|
13110
13179
|
}
|
|
13180
|
+
getSharedCommittedPrefixLength(parsedMessages) {
|
|
13181
|
+
const committedMessages = this.committedMessages;
|
|
13182
|
+
const max = Math.min(parsedMessages.length, committedMessages.length);
|
|
13183
|
+
let index = 0;
|
|
13184
|
+
while (index < max && this.messagesShareStableIdentity(parsedMessages[index], committedMessages[index])) {
|
|
13185
|
+
index += 1;
|
|
13186
|
+
}
|
|
13187
|
+
return index;
|
|
13188
|
+
}
|
|
13189
|
+
hydrateCommittedPrefixForParsedStatus(parsedMessages) {
|
|
13190
|
+
const sharedPrefixLength = this.getSharedCommittedPrefixLength(parsedMessages);
|
|
13191
|
+
if (sharedPrefixLength !== this.committedMessages.length) return null;
|
|
13192
|
+
const committedHydratedMessages = this.committedMessages.map((message, index) => {
|
|
13193
|
+
const timestamp = typeof message.timestamp === "number" && Number.isFinite(message.timestamp) ? message.timestamp : this.lastOutputAt || this.currentTurnScope?.startedAt || Date.now();
|
|
13194
|
+
const contentValue = message.content;
|
|
13195
|
+
return {
|
|
13196
|
+
role: message.role,
|
|
13197
|
+
content: typeof contentValue === "string" ? contentValue : String(contentValue || ""),
|
|
13198
|
+
timestamp,
|
|
13199
|
+
receivedAt: typeof message.receivedAt === "number" && Number.isFinite(message.receivedAt) ? message.receivedAt : timestamp,
|
|
13200
|
+
kind: message.kind,
|
|
13201
|
+
id: message.id || `msg_${index}`,
|
|
13202
|
+
index: typeof message.index === "number" ? message.index : index,
|
|
13203
|
+
meta: message.meta,
|
|
13204
|
+
senderName: message.senderName
|
|
13205
|
+
};
|
|
13206
|
+
});
|
|
13207
|
+
const extraMessages = parsedMessages.slice(sharedPrefixLength);
|
|
13208
|
+
if (extraMessages.length === 0) return committedHydratedMessages;
|
|
13209
|
+
const extraHydratedMessages = hydrateCliParsedMessages(extraMessages, {
|
|
13210
|
+
committedMessages: [],
|
|
13211
|
+
scope: this.currentTurnScope,
|
|
13212
|
+
lastOutputAt: this.lastOutputAt
|
|
13213
|
+
}).map((message, offset) => ({
|
|
13214
|
+
...message,
|
|
13215
|
+
id: message.id || `msg_${sharedPrefixLength + offset}`,
|
|
13216
|
+
index: typeof message.index === "number" ? message.index : sharedPrefixLength + offset
|
|
13217
|
+
}));
|
|
13218
|
+
return [...committedHydratedMessages, ...extraHydratedMessages];
|
|
13219
|
+
}
|
|
13220
|
+
hydrateParsedMessagesForStatus(parsedMessages) {
|
|
13221
|
+
return this.hydrateCommittedPrefixForParsedStatus(parsedMessages) || hydrateCliParsedMessages(parsedMessages, {
|
|
13222
|
+
committedMessages: this.committedMessages,
|
|
13223
|
+
scope: this.currentTurnScope,
|
|
13224
|
+
lastOutputAt: this.lastOutputAt
|
|
13225
|
+
});
|
|
13226
|
+
}
|
|
13227
|
+
buildCommittedChatMessages() {
|
|
13228
|
+
return this.committedMessages.map((message, index) => {
|
|
13229
|
+
const contentValue = message.content;
|
|
13230
|
+
return buildChatMessage({
|
|
13231
|
+
role: message.role,
|
|
13232
|
+
content: typeof contentValue === "string" ? contentValue : String(contentValue || ""),
|
|
13233
|
+
timestamp: message.timestamp,
|
|
13234
|
+
kind: message.kind,
|
|
13235
|
+
meta: message.meta,
|
|
13236
|
+
senderName: message.senderName,
|
|
13237
|
+
id: message.id || `msg_${index}`,
|
|
13238
|
+
index: typeof message.index === "number" ? message.index : index,
|
|
13239
|
+
receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp
|
|
13240
|
+
});
|
|
13241
|
+
});
|
|
13242
|
+
}
|
|
13111
13243
|
/**
|
|
13112
13244
|
* Script-based full parse — returns ReadChatResult.
|
|
13113
13245
|
* Called by command handler / dashboard for rich content rendering.
|
|
@@ -13133,7 +13265,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
13133
13265
|
this.onStatusChange?.();
|
|
13134
13266
|
}
|
|
13135
13267
|
}
|
|
13136
|
-
if (parsed && Array.isArray(parsed.messages)) {
|
|
13268
|
+
if (parsed && Array.isArray(parsed.messages) && this.provider.allowInputDuringGeneration === true) {
|
|
13137
13269
|
const hydratedForCommit = normalizeCliParsedMessages(parsed.messages, {
|
|
13138
13270
|
committedMessages: this.committedMessages,
|
|
13139
13271
|
scope: this.currentTurnScope,
|
|
@@ -13152,21 +13284,21 @@ var init_provider_cli_adapter = __esm({
|
|
|
13152
13284
|
const shouldPreferCommittedMessages = !this.currentTurnScope && !this.activeModal && this.currentStatus === "idle";
|
|
13153
13285
|
let result;
|
|
13154
13286
|
if (parsed && Array.isArray(parsed.messages)) {
|
|
13155
|
-
const parsedHydratedMessages =
|
|
13156
|
-
committedMessages: this.committedMessages,
|
|
13157
|
-
scope: this.currentTurnScope,
|
|
13158
|
-
lastOutputAt: this.lastOutputAt
|
|
13159
|
-
});
|
|
13160
|
-
const committedHydratedMessages = this.committedMessages.map((message, index) => buildChatMessage({
|
|
13161
|
-
...message,
|
|
13162
|
-
id: message.id || `msg_${index}`,
|
|
13163
|
-
index: typeof message.index === "number" ? message.index : index,
|
|
13164
|
-
receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp
|
|
13165
|
-
}));
|
|
13287
|
+
const parsedHydratedMessages = this.hydrateParsedMessagesForStatus(parsed.messages);
|
|
13166
13288
|
const parsedLastAssistant = [...parsedHydratedMessages].reverse().find((message) => message.role === "assistant" && typeof message.content === "string" && message.content.trim());
|
|
13167
|
-
const shouldAdoptParsedIdleReplay = !this.currentTurnScope && !this.activeModal && !!parsedLastAssistant && parsedTranscriptIsRicherThanCommitted(parsedHydratedMessages,
|
|
13289
|
+
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");
|
|
13168
13290
|
if (shouldAdoptParsedIdleReplay) {
|
|
13169
|
-
this.committedMessages =
|
|
13291
|
+
this.committedMessages = this.getSharedCommittedPrefixLength(parsed.messages) === this.committedMessages.length ? parsedHydratedMessages.map((message) => ({
|
|
13292
|
+
role: message.role,
|
|
13293
|
+
content: typeof message.content === "string" ? message.content : String(message.content || ""),
|
|
13294
|
+
timestamp: message.timestamp,
|
|
13295
|
+
receivedAt: message.receivedAt,
|
|
13296
|
+
kind: message.kind,
|
|
13297
|
+
id: message.id,
|
|
13298
|
+
index: message.index,
|
|
13299
|
+
meta: message.meta,
|
|
13300
|
+
senderName: message.senderName
|
|
13301
|
+
})) : normalizeCliParsedMessages(parsed.messages, {
|
|
13170
13302
|
committedMessages: this.committedMessages,
|
|
13171
13303
|
scope: this.currentTurnScope,
|
|
13172
13304
|
lastOutputAt: this.lastOutputAt
|
|
@@ -13185,15 +13317,9 @@ var init_provider_cli_adapter = __esm({
|
|
|
13185
13317
|
this.onStatusChange?.();
|
|
13186
13318
|
}
|
|
13187
13319
|
}
|
|
13188
|
-
const
|
|
13189
|
-
...message,
|
|
13190
|
-
id: message.id || `msg_${index}`,
|
|
13191
|
-
index: typeof message.index === "number" ? message.index : index,
|
|
13192
|
-
receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp
|
|
13193
|
-
})) : committedHydratedMessages;
|
|
13194
|
-
const shouldPreferCommittedHistoryReplay = !this.currentTurnScope && !this.activeModal && effectiveCommittedHydratedMessages.length > parsedHydratedMessages.length;
|
|
13320
|
+
const shouldPreferCommittedHistoryReplay = !this.currentTurnScope && !this.activeModal && this.committedMessages.length > parsedHydratedMessages.length;
|
|
13195
13321
|
const shouldPreferCommittedIdleReplay = shouldPreferCommittedMessages && !shouldAdoptParsedIdleReplay;
|
|
13196
|
-
const hydratedMessages = shouldPreferCommittedIdleReplay || shouldPreferCommittedHistoryReplay ?
|
|
13322
|
+
const hydratedMessages = shouldPreferCommittedIdleReplay || shouldPreferCommittedHistoryReplay ? this.buildCommittedChatMessages() : parsedHydratedMessages;
|
|
13197
13323
|
result = {
|
|
13198
13324
|
id: parsed.id || "cli_session",
|
|
13199
13325
|
status: parsed.status || this.currentStatus,
|
|
@@ -14310,7 +14436,7 @@ var init_cli_provider_instance = __esm({
|
|
|
14310
14436
|
return this.presentationMode;
|
|
14311
14437
|
}
|
|
14312
14438
|
getHotChatSessionState() {
|
|
14313
|
-
const adapterStatus = this.adapter.getStatus();
|
|
14439
|
+
const adapterStatus = this.adapter.getStatus({ allowParse: false });
|
|
14314
14440
|
const autoApproveActive = adapterStatus.status === "waiting_approval" && this.shouldAutoApprove();
|
|
14315
14441
|
const visibleStatus = autoApproveActive ? "generating" : adapterStatus.status;
|
|
14316
14442
|
const runtime = this.adapter.getRuntimeMetadata();
|
|
@@ -56449,7 +56575,7 @@ var init_adhdev_daemon = __esm({
|
|
|
56449
56575
|
init_version();
|
|
56450
56576
|
init_src();
|
|
56451
56577
|
init_runtime_defaults();
|
|
56452
|
-
pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.
|
|
56578
|
+
pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.37" });
|
|
56453
56579
|
AdhdevDaemon = class _AdhdevDaemon {
|
|
56454
56580
|
localHttpServer = null;
|
|
56455
56581
|
localWss = null;
|
|
@@ -56466,7 +56592,7 @@ var init_adhdev_daemon = __esm({
|
|
|
56466
56592
|
p2pChatOutputActiveAt = /* @__PURE__ */ new Map();
|
|
56467
56593
|
p2pChatOutputFlushTimer = null;
|
|
56468
56594
|
hotChatSnapshotCache = null;
|
|
56469
|
-
static HOT_CHAT_SNAPSHOT_CACHE_TTL_MS =
|
|
56595
|
+
static HOT_CHAT_SNAPSHOT_CACHE_TTL_MS = 2400;
|
|
56470
56596
|
static CHAT_OUTPUT_ACTIVITY_HOT_MS = DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS;
|
|
56471
56597
|
static CHAT_OUTPUT_FLUSH_DEBOUNCE_MS = 700;
|
|
56472
56598
|
components = null;
|