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/cli/index.js
CHANGED
|
@@ -12376,27 +12376,86 @@ function sliceFromOffset(text, start) {
|
|
|
12376
12376
|
function hydrateCliParsedMessages(parsedMessages, options) {
|
|
12377
12377
|
const { committedMessages, scope, lastOutputAt } = options;
|
|
12378
12378
|
const referenceMessages = [...committedMessages];
|
|
12379
|
-
const referenceComparables = referenceMessages.
|
|
12379
|
+
const referenceComparables = new Array(referenceMessages.length);
|
|
12380
12380
|
const usedReferenceIndexes = /* @__PURE__ */ new Set();
|
|
12381
12381
|
const now = options.now ?? Date.now();
|
|
12382
|
-
|
|
12382
|
+
let exactReferenceIndexesByKey = null;
|
|
12383
|
+
const exactReferenceCursorByKey = /* @__PURE__ */ new Map();
|
|
12384
|
+
const hasFiniteTimestamp = (message) => typeof message?.timestamp === "number" && Number.isFinite(message.timestamp);
|
|
12385
|
+
const getReferenceComparable = (index) => {
|
|
12386
|
+
if (typeof referenceComparables[index] === "string") return referenceComparables[index] || "";
|
|
12387
|
+
const comparable = normalizeComparableMessageContent(referenceMessages[index]?.content || "");
|
|
12388
|
+
referenceComparables[index] = comparable;
|
|
12389
|
+
return comparable;
|
|
12390
|
+
};
|
|
12391
|
+
const messagesShareStableIdentity = (parsed, reference) => {
|
|
12392
|
+
if (!parsed || !reference) return false;
|
|
12393
|
+
const parsedId = typeof parsed.id === "string" ? parsed.id.trim() : "";
|
|
12394
|
+
const referenceId = typeof reference.id === "string" ? reference.id.trim() : "";
|
|
12395
|
+
if (parsedId && referenceId && parsedId === referenceId) return true;
|
|
12396
|
+
return typeof parsed.index === "number" && Number.isFinite(parsed.index) && typeof reference.index === "number" && Number.isFinite(reference.index) && parsed.index === reference.index;
|
|
12397
|
+
};
|
|
12398
|
+
const exactReferenceKey = (role, comparable) => `${role}\0${comparable}`;
|
|
12399
|
+
const ensureExactReferenceIndex = () => {
|
|
12400
|
+
if (exactReferenceIndexesByKey) return exactReferenceIndexesByKey;
|
|
12401
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
12402
|
+
for (let i = 0; i < referenceMessages.length; i++) {
|
|
12403
|
+
const candidate = referenceMessages[i];
|
|
12404
|
+
if (!candidate || candidate.role !== "user" && candidate.role !== "assistant" || !hasFiniteTimestamp(candidate)) continue;
|
|
12405
|
+
const comparable = getReferenceComparable(i);
|
|
12406
|
+
if (!comparable) continue;
|
|
12407
|
+
const key = exactReferenceKey(candidate.role, comparable);
|
|
12408
|
+
const indexes = byKey.get(key);
|
|
12409
|
+
if (indexes) {
|
|
12410
|
+
indexes.push(i);
|
|
12411
|
+
} else {
|
|
12412
|
+
byKey.set(key, [i]);
|
|
12413
|
+
}
|
|
12414
|
+
}
|
|
12415
|
+
exactReferenceIndexesByKey = byKey;
|
|
12416
|
+
return byKey;
|
|
12417
|
+
};
|
|
12418
|
+
const takeExactReferenceTimestamp = (role, normalizedContent) => {
|
|
12419
|
+
const key = exactReferenceKey(role, normalizedContent);
|
|
12420
|
+
const indexes = ensureExactReferenceIndex().get(key);
|
|
12421
|
+
if (!indexes) return void 0;
|
|
12422
|
+
let cursor = exactReferenceCursorByKey.get(key) || 0;
|
|
12423
|
+
while (cursor < indexes.length) {
|
|
12424
|
+
const candidateIndex = indexes[cursor];
|
|
12425
|
+
cursor += 1;
|
|
12426
|
+
if (usedReferenceIndexes.has(candidateIndex)) continue;
|
|
12427
|
+
const candidate = referenceMessages[candidateIndex];
|
|
12428
|
+
if (!candidate || candidate.role !== role || !hasFiniteTimestamp(candidate)) continue;
|
|
12429
|
+
usedReferenceIndexes.add(candidateIndex);
|
|
12430
|
+
exactReferenceCursorByKey.set(key, cursor);
|
|
12431
|
+
return candidate.timestamp;
|
|
12432
|
+
}
|
|
12433
|
+
exactReferenceCursorByKey.set(key, cursor);
|
|
12434
|
+
return void 0;
|
|
12435
|
+
};
|
|
12436
|
+
const findReferenceTimestamp = (message, role, content, parsedIndex) => {
|
|
12437
|
+
const sameIndex = referenceMessages[parsedIndex];
|
|
12438
|
+
if (sameIndex && !usedReferenceIndexes.has(parsedIndex) && sameIndex.role === role && hasFiniteTimestamp(sameIndex) && messagesShareStableIdentity(message, sameIndex)) {
|
|
12439
|
+
usedReferenceIndexes.add(parsedIndex);
|
|
12440
|
+
return sameIndex.timestamp;
|
|
12441
|
+
}
|
|
12383
12442
|
const normalizedContent = normalizeComparableMessageContent(content);
|
|
12384
12443
|
if (!normalizedContent) return void 0;
|
|
12385
|
-
|
|
12386
|
-
if (sameIndex && !usedReferenceIndexes.has(parsedIndex) && sameIndex.role === role && referenceComparables[parsedIndex] === normalizedContent && typeof sameIndex.timestamp === "number" && Number.isFinite(sameIndex.timestamp)) {
|
|
12444
|
+
if (sameIndex && !usedReferenceIndexes.has(parsedIndex) && sameIndex.role === role && getReferenceComparable(parsedIndex) === normalizedContent && hasFiniteTimestamp(sameIndex)) {
|
|
12387
12445
|
usedReferenceIndexes.add(parsedIndex);
|
|
12388
12446
|
return sameIndex.timestamp;
|
|
12389
12447
|
}
|
|
12448
|
+
const exactTimestamp = takeExactReferenceTimestamp(role, normalizedContent);
|
|
12449
|
+
if (typeof exactTimestamp === "number") return exactTimestamp;
|
|
12390
12450
|
for (let i = 0; i < referenceMessages.length; i++) {
|
|
12391
12451
|
if (usedReferenceIndexes.has(i)) continue;
|
|
12392
12452
|
const candidate = referenceMessages[i];
|
|
12393
12453
|
if (!candidate || candidate.role !== role) continue;
|
|
12394
|
-
const candidateContent =
|
|
12454
|
+
const candidateContent = getReferenceComparable(i);
|
|
12395
12455
|
if (!candidateContent) continue;
|
|
12396
|
-
const exactMatch = candidateContent === normalizedContent;
|
|
12397
12456
|
const fuzzyMatch = candidateContent.includes(normalizedContent) || normalizedContent.includes(candidateContent);
|
|
12398
|
-
if (!
|
|
12399
|
-
if (
|
|
12457
|
+
if (!fuzzyMatch) continue;
|
|
12458
|
+
if (hasFiniteTimestamp(candidate)) {
|
|
12400
12459
|
usedReferenceIndexes.add(i);
|
|
12401
12460
|
return candidate.timestamp;
|
|
12402
12461
|
}
|
|
@@ -12407,7 +12466,7 @@ function hydrateCliParsedMessages(parsedMessages, options) {
|
|
|
12407
12466
|
const role = message.role;
|
|
12408
12467
|
const content = typeof message.content === "string" ? message.content : String(message.content || "");
|
|
12409
12468
|
const parsedTimestamp = typeof message.timestamp === "number" && Number.isFinite(message.timestamp) ? message.timestamp : void 0;
|
|
12410
|
-
const referenceTimestamp = parsedTimestamp ?? findReferenceTimestamp(role, content, index);
|
|
12469
|
+
const referenceTimestamp = parsedTimestamp ?? findReferenceTimestamp(message, role, content, index);
|
|
12411
12470
|
const fallbackTimestamp = role === "user" ? scope?.startedAt || now : lastOutputAt || scope?.startedAt || now;
|
|
12412
12471
|
const timestamp = referenceTimestamp ?? fallbackTimestamp;
|
|
12413
12472
|
return {
|
|
@@ -12913,7 +12972,16 @@ var init_provider_cli_adapter = __esm({
|
|
|
12913
12972
|
if (baseMessages.length <= _ProviderCliAdapter.PARSE_MESSAGE_TAIL_LIMIT) return baseMessages;
|
|
12914
12973
|
return baseMessages.slice(-_ProviderCliAdapter.PARSE_MESSAGE_TAIL_LIMIT);
|
|
12915
12974
|
}
|
|
12975
|
+
messagesShareStableIdentity(left2, right2) {
|
|
12976
|
+
if (left2 === right2) return true;
|
|
12977
|
+
if (!left2 || !right2) return false;
|
|
12978
|
+
if ((left2.role || "") !== (right2.role || "")) return false;
|
|
12979
|
+
if (left2.id && right2.id && String(left2.id) === String(right2.id)) return true;
|
|
12980
|
+
if (typeof left2.index === "number" && typeof right2.index === "number" && left2.index === right2.index) return true;
|
|
12981
|
+
return false;
|
|
12982
|
+
}
|
|
12916
12983
|
messagesComparable(left2, right2) {
|
|
12984
|
+
if (this.messagesShareStableIdentity(left2, right2)) return true;
|
|
12917
12985
|
if (!left2 || !right2) return false;
|
|
12918
12986
|
if ((left2.role || "") !== (right2.role || "")) return false;
|
|
12919
12987
|
const leftText = normalizeComparableTranscriptText(left2.content);
|
|
@@ -14018,11 +14086,12 @@ var init_provider_cli_adapter = __esm({
|
|
|
14018
14086
|
};
|
|
14019
14087
|
}
|
|
14020
14088
|
// ─── Public API (CliAdapter) ───────────────────
|
|
14021
|
-
getStatus() {
|
|
14022
|
-
const
|
|
14089
|
+
getStatus(options = {}) {
|
|
14090
|
+
const allowParse = options.allowParse !== false;
|
|
14091
|
+
const startupModal = allowParse && this.startupParseGate ? this.runParseApproval(this.recentOutputBuffer) : null;
|
|
14023
14092
|
let effectiveStatus = this.projectEffectiveStatus(startupModal);
|
|
14024
14093
|
let effectiveModal = startupModal || this.activeModal;
|
|
14025
|
-
if (!startupModal && !effectiveModal && typeof this.cliScripts?.parseOutput === "function") {
|
|
14094
|
+
if (allowParse && !startupModal && !effectiveModal && typeof this.cliScripts?.parseOutput === "function") {
|
|
14026
14095
|
let parsed = this.getFreshParsedStatusCache();
|
|
14027
14096
|
if (!parsed && effectiveStatus !== "idle") {
|
|
14028
14097
|
const now = Date.now();
|
|
@@ -14064,6 +14133,69 @@ var init_provider_cli_adapter = __esm({
|
|
|
14064
14133
|
this.committedMessages = normalized;
|
|
14065
14134
|
this.syncMessageViews();
|
|
14066
14135
|
}
|
|
14136
|
+
getSharedCommittedPrefixLength(parsedMessages) {
|
|
14137
|
+
const committedMessages = this.committedMessages;
|
|
14138
|
+
const max = Math.min(parsedMessages.length, committedMessages.length);
|
|
14139
|
+
let index = 0;
|
|
14140
|
+
while (index < max && this.messagesShareStableIdentity(parsedMessages[index], committedMessages[index])) {
|
|
14141
|
+
index += 1;
|
|
14142
|
+
}
|
|
14143
|
+
return index;
|
|
14144
|
+
}
|
|
14145
|
+
hydrateCommittedPrefixForParsedStatus(parsedMessages) {
|
|
14146
|
+
const sharedPrefixLength = this.getSharedCommittedPrefixLength(parsedMessages);
|
|
14147
|
+
if (sharedPrefixLength !== this.committedMessages.length) return null;
|
|
14148
|
+
const committedHydratedMessages = this.committedMessages.map((message, index) => {
|
|
14149
|
+
const timestamp = typeof message.timestamp === "number" && Number.isFinite(message.timestamp) ? message.timestamp : this.lastOutputAt || this.currentTurnScope?.startedAt || Date.now();
|
|
14150
|
+
const contentValue = message.content;
|
|
14151
|
+
return {
|
|
14152
|
+
role: message.role,
|
|
14153
|
+
content: typeof contentValue === "string" ? contentValue : String(contentValue || ""),
|
|
14154
|
+
timestamp,
|
|
14155
|
+
receivedAt: typeof message.receivedAt === "number" && Number.isFinite(message.receivedAt) ? message.receivedAt : timestamp,
|
|
14156
|
+
kind: message.kind,
|
|
14157
|
+
id: message.id || `msg_${index}`,
|
|
14158
|
+
index: typeof message.index === "number" ? message.index : index,
|
|
14159
|
+
meta: message.meta,
|
|
14160
|
+
senderName: message.senderName
|
|
14161
|
+
};
|
|
14162
|
+
});
|
|
14163
|
+
const extraMessages = parsedMessages.slice(sharedPrefixLength);
|
|
14164
|
+
if (extraMessages.length === 0) return committedHydratedMessages;
|
|
14165
|
+
const extraHydratedMessages = hydrateCliParsedMessages(extraMessages, {
|
|
14166
|
+
committedMessages: [],
|
|
14167
|
+
scope: this.currentTurnScope,
|
|
14168
|
+
lastOutputAt: this.lastOutputAt
|
|
14169
|
+
}).map((message, offset) => ({
|
|
14170
|
+
...message,
|
|
14171
|
+
id: message.id || `msg_${sharedPrefixLength + offset}`,
|
|
14172
|
+
index: typeof message.index === "number" ? message.index : sharedPrefixLength + offset
|
|
14173
|
+
}));
|
|
14174
|
+
return [...committedHydratedMessages, ...extraHydratedMessages];
|
|
14175
|
+
}
|
|
14176
|
+
hydrateParsedMessagesForStatus(parsedMessages) {
|
|
14177
|
+
return this.hydrateCommittedPrefixForParsedStatus(parsedMessages) || hydrateCliParsedMessages(parsedMessages, {
|
|
14178
|
+
committedMessages: this.committedMessages,
|
|
14179
|
+
scope: this.currentTurnScope,
|
|
14180
|
+
lastOutputAt: this.lastOutputAt
|
|
14181
|
+
});
|
|
14182
|
+
}
|
|
14183
|
+
buildCommittedChatMessages() {
|
|
14184
|
+
return this.committedMessages.map((message, index) => {
|
|
14185
|
+
const contentValue = message.content;
|
|
14186
|
+
return buildChatMessage({
|
|
14187
|
+
role: message.role,
|
|
14188
|
+
content: typeof contentValue === "string" ? contentValue : String(contentValue || ""),
|
|
14189
|
+
timestamp: message.timestamp,
|
|
14190
|
+
kind: message.kind,
|
|
14191
|
+
meta: message.meta,
|
|
14192
|
+
senderName: message.senderName,
|
|
14193
|
+
id: message.id || `msg_${index}`,
|
|
14194
|
+
index: typeof message.index === "number" ? message.index : index,
|
|
14195
|
+
receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp
|
|
14196
|
+
});
|
|
14197
|
+
});
|
|
14198
|
+
}
|
|
14067
14199
|
/**
|
|
14068
14200
|
* Script-based full parse — returns ReadChatResult.
|
|
14069
14201
|
* Called by command handler / dashboard for rich content rendering.
|
|
@@ -14089,7 +14221,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
14089
14221
|
this.onStatusChange?.();
|
|
14090
14222
|
}
|
|
14091
14223
|
}
|
|
14092
|
-
if (parsed && Array.isArray(parsed.messages)) {
|
|
14224
|
+
if (parsed && Array.isArray(parsed.messages) && this.provider.allowInputDuringGeneration === true) {
|
|
14093
14225
|
const hydratedForCommit = normalizeCliParsedMessages(parsed.messages, {
|
|
14094
14226
|
committedMessages: this.committedMessages,
|
|
14095
14227
|
scope: this.currentTurnScope,
|
|
@@ -14108,21 +14240,21 @@ var init_provider_cli_adapter = __esm({
|
|
|
14108
14240
|
const shouldPreferCommittedMessages = !this.currentTurnScope && !this.activeModal && this.currentStatus === "idle";
|
|
14109
14241
|
let result;
|
|
14110
14242
|
if (parsed && Array.isArray(parsed.messages)) {
|
|
14111
|
-
const parsedHydratedMessages =
|
|
14112
|
-
committedMessages: this.committedMessages,
|
|
14113
|
-
scope: this.currentTurnScope,
|
|
14114
|
-
lastOutputAt: this.lastOutputAt
|
|
14115
|
-
});
|
|
14116
|
-
const committedHydratedMessages = this.committedMessages.map((message, index) => buildChatMessage({
|
|
14117
|
-
...message,
|
|
14118
|
-
id: message.id || `msg_${index}`,
|
|
14119
|
-
index: typeof message.index === "number" ? message.index : index,
|
|
14120
|
-
receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp
|
|
14121
|
-
}));
|
|
14243
|
+
const parsedHydratedMessages = this.hydrateParsedMessagesForStatus(parsed.messages);
|
|
14122
14244
|
const parsedLastAssistant = [...parsedHydratedMessages].reverse().find((message) => message.role === "assistant" && typeof message.content === "string" && message.content.trim());
|
|
14123
|
-
const shouldAdoptParsedIdleReplay = !this.currentTurnScope && !this.activeModal && !!parsedLastAssistant && parsedTranscriptIsRicherThanCommitted(parsedHydratedMessages,
|
|
14245
|
+
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");
|
|
14124
14246
|
if (shouldAdoptParsedIdleReplay) {
|
|
14125
|
-
this.committedMessages =
|
|
14247
|
+
this.committedMessages = this.getSharedCommittedPrefixLength(parsed.messages) === this.committedMessages.length ? parsedHydratedMessages.map((message) => ({
|
|
14248
|
+
role: message.role,
|
|
14249
|
+
content: typeof message.content === "string" ? message.content : String(message.content || ""),
|
|
14250
|
+
timestamp: message.timestamp,
|
|
14251
|
+
receivedAt: message.receivedAt,
|
|
14252
|
+
kind: message.kind,
|
|
14253
|
+
id: message.id,
|
|
14254
|
+
index: message.index,
|
|
14255
|
+
meta: message.meta,
|
|
14256
|
+
senderName: message.senderName
|
|
14257
|
+
})) : normalizeCliParsedMessages(parsed.messages, {
|
|
14126
14258
|
committedMessages: this.committedMessages,
|
|
14127
14259
|
scope: this.currentTurnScope,
|
|
14128
14260
|
lastOutputAt: this.lastOutputAt
|
|
@@ -14141,15 +14273,9 @@ var init_provider_cli_adapter = __esm({
|
|
|
14141
14273
|
this.onStatusChange?.();
|
|
14142
14274
|
}
|
|
14143
14275
|
}
|
|
14144
|
-
const
|
|
14145
|
-
...message,
|
|
14146
|
-
id: message.id || `msg_${index}`,
|
|
14147
|
-
index: typeof message.index === "number" ? message.index : index,
|
|
14148
|
-
receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp
|
|
14149
|
-
})) : committedHydratedMessages;
|
|
14150
|
-
const shouldPreferCommittedHistoryReplay = !this.currentTurnScope && !this.activeModal && effectiveCommittedHydratedMessages.length > parsedHydratedMessages.length;
|
|
14276
|
+
const shouldPreferCommittedHistoryReplay = !this.currentTurnScope && !this.activeModal && this.committedMessages.length > parsedHydratedMessages.length;
|
|
14151
14277
|
const shouldPreferCommittedIdleReplay = shouldPreferCommittedMessages && !shouldAdoptParsedIdleReplay;
|
|
14152
|
-
const hydratedMessages = shouldPreferCommittedIdleReplay || shouldPreferCommittedHistoryReplay ?
|
|
14278
|
+
const hydratedMessages = shouldPreferCommittedIdleReplay || shouldPreferCommittedHistoryReplay ? this.buildCommittedChatMessages() : parsedHydratedMessages;
|
|
14153
14279
|
result = {
|
|
14154
14280
|
id: parsed.id || "cli_session",
|
|
14155
14281
|
status: parsed.status || this.currentStatus,
|
|
@@ -15266,7 +15392,7 @@ var init_cli_provider_instance = __esm({
|
|
|
15266
15392
|
return this.presentationMode;
|
|
15267
15393
|
}
|
|
15268
15394
|
getHotChatSessionState() {
|
|
15269
|
-
const adapterStatus = this.adapter.getStatus();
|
|
15395
|
+
const adapterStatus = this.adapter.getStatus({ allowParse: false });
|
|
15270
15396
|
const autoApproveActive = adapterStatus.status === "waiting_approval" && this.shouldAutoApprove();
|
|
15271
15397
|
const visibleStatus = autoApproveActive ? "generating" : adapterStatus.status;
|
|
15272
15398
|
const runtime = this.adapter.getRuntimeMetadata();
|
|
@@ -88169,7 +88295,7 @@ var init_adhdev_daemon = __esm({
|
|
|
88169
88295
|
init_version();
|
|
88170
88296
|
init_src();
|
|
88171
88297
|
init_runtime_defaults();
|
|
88172
|
-
pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.
|
|
88298
|
+
pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.37" });
|
|
88173
88299
|
AdhdevDaemon = class _AdhdevDaemon {
|
|
88174
88300
|
localHttpServer = null;
|
|
88175
88301
|
localWss = null;
|
|
@@ -88186,7 +88312,7 @@ var init_adhdev_daemon = __esm({
|
|
|
88186
88312
|
p2pChatOutputActiveAt = /* @__PURE__ */ new Map();
|
|
88187
88313
|
p2pChatOutputFlushTimer = null;
|
|
88188
88314
|
hotChatSnapshotCache = null;
|
|
88189
|
-
static HOT_CHAT_SNAPSHOT_CACHE_TTL_MS =
|
|
88315
|
+
static HOT_CHAT_SNAPSHOT_CACHE_TTL_MS = 2400;
|
|
88190
88316
|
static CHAT_OUTPUT_ACTIVITY_HOT_MS = DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS;
|
|
88191
88317
|
static CHAT_OUTPUT_FLUSH_DEBOUNCE_MS = 700;
|
|
88192
88318
|
components = null;
|