@adhdev/daemon-core 0.9.82-rc.27 → 0.9.82-rc.270
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/boot/daemon-lifecycle.d.ts +4 -0
- package/dist/boot/process-hardening.d.ts +50 -0
- package/dist/build-info.d.ts +37 -0
- package/dist/chat/source-machine.d.ts +166 -0
- package/dist/chat/source-resolver.d.ts +104 -0
- package/dist/chat/subscription-updates.d.ts +1 -0
- package/dist/cli-adapter-types.d.ts +23 -2
- package/dist/cli-adapters/cli-script-runner.d.ts +117 -0
- package/dist/cli-adapters/cli-state-engine.d.ts +198 -0
- package/dist/cli-adapters/provider-cli-adapter.d.ts +106 -63
- package/dist/cli-adapters/provider-cli-parse.d.ts +4 -0
- package/dist/cli-adapters/provider-cli-shared.d.ts +38 -0
- package/dist/cli-adapters/raw-terminal-io.d.ts +37 -0
- package/dist/cli-adapters/terminal-backends/ghostty-vt-backend.d.ts +6 -3
- package/dist/cli-adapters/terminal-backends/types.d.ts +10 -2
- package/dist/cli-adapters/terminal-screen.d.ts +4 -11
- package/dist/commands/cli-manager.d.ts +2 -1
- package/dist/commands/handler.d.ts +110 -0
- package/dist/commands/mesh-coordinator.d.ts +85 -1
- package/dist/commands/router.d.ts +160 -1
- package/dist/config/chat-history.d.ts +9 -0
- package/dist/config/config.d.ts +5 -0
- package/dist/config/mesh-config.d.ts +72 -1
- package/dist/git/git-commands.d.ts +9 -1
- package/dist/git/git-diff.d.ts +6 -0
- package/dist/git/git-status.d.ts +7 -0
- package/dist/git/git-types.d.ts +2 -50
- package/dist/index.d.ts +51 -12
- package/dist/index.js +33378 -12150
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +37922 -16795
- package/dist/index.mjs.map +1 -1
- package/dist/installer.d.ts +1 -4
- package/dist/ipc/local-ipc-server.d.ts +91 -0
- package/dist/launch.d.ts +1 -1
- package/dist/logging/async-batch-writer.d.ts +10 -0
- package/dist/mesh/contracts.d.ts +164 -0
- package/dist/mesh/coordinator-prompt.d.ts +36 -0
- package/dist/mesh/coordinator-registry.d.ts +59 -0
- package/dist/mesh/mesh-active-work.d.ts +108 -0
- package/dist/mesh/mesh-delivery-policy.d.ts +131 -0
- package/dist/mesh/mesh-events-coordinator.d.ts +152 -0
- package/dist/mesh/mesh-events-pending.d.ts +40 -0
- package/dist/mesh/mesh-events-stale.d.ts +40 -0
- package/dist/mesh/mesh-events-utils.d.ts +47 -0
- package/dist/mesh/mesh-events.d.ts +5 -49
- package/dist/mesh/mesh-fast-forward.d.ts +81 -0
- package/dist/mesh/mesh-host-ownership.d.ts +9 -0
- package/dist/mesh/mesh-ledger-reconciliation.d.ts +23 -3
- package/dist/mesh/mesh-ledger.d.ts +77 -1
- package/dist/mesh/mesh-missions.d.ts +58 -0
- package/dist/mesh/mesh-refine-batch.d.ts +68 -0
- package/dist/mesh/mesh-refine-status.d.ts +62 -0
- package/dist/mesh/mesh-review-inbox.d.ts +90 -0
- package/dist/mesh/mesh-routing.d.ts +70 -0
- package/dist/mesh/mesh-runtime-store.d.ts +333 -0
- package/dist/mesh/mesh-task-stats.d.ts +49 -0
- package/dist/mesh/mesh-work-queue.d.ts +166 -5
- package/dist/mesh/preview-freshness.d.ts +18 -0
- package/dist/mesh/refine-config.d.ts +215 -0
- package/dist/mesh/worktree-bootstrap-config.d.ts +135 -0
- package/dist/providers/acp-provider-instance.d.ts +2 -0
- package/dist/providers/approval-utils.d.ts +13 -0
- package/dist/providers/cli-provider-instance.d.ts +61 -3
- package/dist/providers/contracts.d.ts +130 -6
- package/dist/providers/external-sources.d.ts +71 -0
- package/dist/providers/native-history/antigravity-cli-transcript.d.ts +100 -0
- package/dist/providers/native-history/claude-cli-transcript.d.ts +70 -0
- package/dist/providers/native-history/codex-cli-transcript.d.ts +73 -0
- package/dist/providers/native-history/dispatcher.d.ts +27 -0
- package/dist/providers/native-history/hermes-cli-transcript.d.ts +30 -0
- package/dist/providers/native-history/index.d.ts +13 -0
- package/dist/providers/provider-instance-manager.d.ts +13 -0
- package/dist/providers/provider-instance.d.ts +13 -1
- package/dist/providers/provider-loader.d.ts +26 -4
- package/dist/providers/provider-trust.d.ts +31 -0
- package/dist/providers/read-chat-contract.d.ts +29 -0
- package/dist/providers/sdk/v1/builders/acp/detect-status.d.ts +68 -0
- package/dist/providers/sdk/v1/builders/cli/detect-status.d.ts +85 -0
- package/dist/providers/sdk/v1/builders/cli/parse-approval-squash.d.ts +59 -0
- package/dist/providers/sdk/v1/builders/cli/parse-approval.d.ts +65 -0
- package/dist/providers/sdk/v1/builders/cli/parse-session.d.ts +91 -0
- package/dist/providers/sdk/v1/builders/cli/visible-region.d.ts +42 -0
- package/dist/providers/sdk/v1/fixture-tooling/format.d.ts +126 -0
- package/dist/providers/sdk/v1/fixture-tooling/index.d.ts +8 -0
- package/dist/providers/sdk/v1/fixture-tooling/replay.d.ts +38 -0
- package/dist/providers/sdk/v1/index.d.ts +30 -0
- package/dist/providers/sdk/v1/sandbox/README-design.d.ts +193 -0
- package/dist/providers/sdk/v1/sandbox/require-whitelist.d.ts +74 -0
- package/dist/providers/sdk/v1/sandbox/script-runner.d.ts +98 -0
- package/dist/providers/sdk/v1/types/cli/index.d.ts +277 -0
- package/dist/providers/sdk/v1/types/common/index.d.ts +203 -0
- package/dist/providers/sdk/v1/validators/index.d.ts +5 -0
- package/dist/providers/sdk/v1/validators/manifest.d.ts +40 -0
- package/dist/providers/sdk/v1/validators/taint.d.ts +52 -0
- package/dist/providers/spec/adapter.d.ts +59 -0
- package/dist/providers/spec/cli-adapter.d.ts +140 -0
- package/dist/providers/spec/evaluator.d.ts +23 -0
- package/dist/providers/spec/fsm-driver.d.ts +278 -0
- package/dist/providers/spec/fsm-evaluator.d.ts +72 -0
- package/dist/providers/spec/fsm-loader.d.ts +14 -0
- package/dist/providers/spec/fsm-types.d.ts +106 -0
- package/dist/providers/spec/native-history-executor.d.ts +41 -0
- package/dist/providers/spec/route.d.ts +4 -0
- package/dist/providers/spec/types.d.ts +144 -0
- package/dist/providers/transcript-v2.d.ts +176 -0
- package/dist/providers/types/interactive-prompt.d.ts +48 -0
- package/dist/repo-mesh-types.d.ts +146 -13
- package/dist/sessions/registry.d.ts +6 -0
- package/dist/shared-types-extra.d.ts +2 -4
- package/dist/shared-types.d.ts +42 -1
- package/dist/status/normalize.d.ts +1 -1
- package/dist/status/normalize.js +1 -0
- package/dist/status/normalize.js.map +1 -1
- package/dist/status/normalize.mjs +1 -0
- package/dist/status/normalize.mjs.map +1 -1
- package/dist/status/reporter.d.ts +2 -0
- package/dist/status/snapshot.d.ts +1 -0
- package/dist/types.d.ts +5 -0
- package/package.json +7 -3
- package/src/agent-stream/poller.ts +2 -3
- package/src/boot/daemon-lifecycle.ts +30 -10
- package/src/boot/process-hardening.ts +89 -0
- package/src/build-info.ts +73 -0
- package/src/chat/source-machine.ts +534 -0
- package/src/chat/source-resolver.ts +0 -0
- package/src/chat/subscription-updates.ts +20 -1
- package/src/cli-adapter-types.d.ts +1 -0
- package/src/cli-adapter-types.ts +22 -2
- package/src/cli-adapters/cli-script-runner.ts +421 -0
- package/src/cli-adapters/cli-state-engine.ts +1215 -0
- package/src/cli-adapters/provider-cli-adapter.d.ts +1 -1
- package/src/cli-adapters/provider-cli-adapter.ts +674 -1139
- package/src/cli-adapters/provider-cli-parse.d.ts +1 -0
- package/src/cli-adapters/provider-cli-parse.ts +13 -0
- package/src/cli-adapters/provider-cli-runtime.ts +3 -1
- package/src/cli-adapters/provider-cli-shared.d.ts +2 -0
- package/src/cli-adapters/provider-cli-shared.ts +68 -11
- package/src/cli-adapters/raw-terminal-io.ts +252 -0
- package/src/cli-adapters/terminal-backends/ghostty-vt-backend.ts +53 -29
- package/src/cli-adapters/terminal-backends/types.ts +10 -3
- package/src/cli-adapters/terminal-screen.ts +16 -81
- package/src/commands/chat-commands.ts +1813 -60
- package/src/commands/cli-manager.ts +286 -14
- package/src/commands/handler.ts +809 -2
- package/src/commands/mesh-coordinator.ts +332 -122
- package/src/commands/router.ts +5730 -550
- package/src/config/chat-history.ts +229 -24
- package/src/config/config.ts +12 -0
- package/src/config/mesh-config.ts +303 -3
- package/src/config/recent-activity.ts +8 -2
- package/src/daemon/dev-auto-implement.ts +3 -2
- package/src/daemon/dev-cli-debug.ts +10 -1
- package/src/detection/ide-detector.ts +26 -16
- package/src/git/git-commands.ts +42 -12
- package/src/git/git-diff.ts +53 -0
- package/src/git/git-status.ts +198 -7
- package/src/git/git-types.ts +14 -62
- package/src/git/git-worktree.ts +8 -1
- package/src/index.ts +131 -11
- package/src/installer.d.ts +1 -1
- package/src/installer.ts +8 -6
- package/src/ipc/local-ipc-server.ts +278 -0
- package/src/launch.d.ts +1 -1
- package/src/launch.ts +37 -28
- package/src/logging/async-batch-writer.ts +55 -0
- package/src/logging/logger.ts +2 -1
- package/src/mesh/contracts.ts +329 -0
- package/src/mesh/coordinator-prompt.ts +219 -31
- package/src/mesh/coordinator-registry.ts +121 -0
- package/src/mesh/mesh-active-work.ts +468 -0
- package/src/mesh/mesh-delivery-policy.ts +315 -0
- package/src/mesh/mesh-events-coordinator.ts +1650 -0
- package/src/mesh/mesh-events-pending.ts +439 -0
- package/src/mesh/mesh-events-stale.ts +283 -0
- package/src/mesh/mesh-events-utils.ts +254 -0
- package/src/mesh/mesh-events.ts +26 -1035
- package/src/mesh/mesh-fast-forward.ts +839 -0
- package/src/mesh/mesh-host-ownership.ts +73 -0
- package/src/mesh/mesh-ledger-reconciliation.ts +12 -5
- package/src/mesh/mesh-ledger.ts +589 -102
- package/src/mesh/mesh-missions.ts +151 -0
- package/src/mesh/mesh-refine-batch.ts +197 -0
- package/src/mesh/mesh-refine-status.ts +231 -0
- package/src/mesh/mesh-review-inbox.ts +307 -0
- package/src/mesh/mesh-routing.ts +272 -0
- package/src/mesh/mesh-runtime-store.ts +1361 -0
- package/src/mesh/mesh-task-stats.ts +154 -0
- package/src/mesh/mesh-work-queue.ts +586 -145
- package/src/mesh/preview-freshness.ts +118 -0
- package/src/mesh/refine-config.ts +403 -0
- package/src/mesh/worktree-bootstrap-config.ts +326 -0
- package/src/providers/acp-provider-instance.ts +15 -1
- package/src/providers/approval-utils.d.ts +4 -0
- package/src/providers/approval-utils.ts +47 -5
- package/src/providers/chat-message-normalization.ts +4 -11
- package/src/providers/cli-provider-instance.ts +897 -81
- package/src/providers/contracts.d.ts +55 -0
- package/src/providers/contracts.ts +141 -6
- package/src/providers/external-sources.ts +218 -0
- package/src/providers/ide-provider-instance.ts +19 -5
- package/src/providers/native-history/antigravity-cli-transcript.ts +643 -0
- package/src/providers/native-history/claude-cli-transcript.ts +396 -0
- package/src/providers/native-history/codex-cli-transcript.ts +479 -0
- package/src/providers/native-history/dispatcher.ts +340 -0
- package/src/providers/native-history/hermes-cli-transcript.ts +230 -0
- package/src/providers/native-history/index.ts +30 -0
- package/src/providers/provider-instance-manager.ts +30 -0
- package/src/providers/provider-instance.ts +10 -1
- package/src/providers/provider-loader.ts +584 -50
- package/src/providers/provider-schema.ts +87 -14
- package/src/providers/provider-trust.ts +114 -0
- package/src/providers/read-chat-contract.ts +76 -16
- package/src/providers/sdk/README.md +49 -0
- package/src/providers/sdk/v1/builders/acp/detect-status.ts +144 -0
- package/src/providers/sdk/v1/builders/cli/detect-status.ts +262 -0
- package/src/providers/sdk/v1/builders/cli/parse-approval-squash.ts +158 -0
- package/src/providers/sdk/v1/builders/cli/parse-approval.ts +250 -0
- package/src/providers/sdk/v1/builders/cli/parse-session.ts +276 -0
- package/src/providers/sdk/v1/builders/cli/visible-region.ts +143 -0
- package/src/providers/sdk/v1/fixture-tooling/format.ts +130 -0
- package/src/providers/sdk/v1/fixture-tooling/index.ts +22 -0
- package/src/providers/sdk/v1/fixture-tooling/replay.ts +352 -0
- package/src/providers/sdk/v1/index.ts +152 -0
- package/src/providers/sdk/v1/sandbox/README-design.ts +195 -0
- package/src/providers/sdk/v1/sandbox/require-whitelist.ts +472 -0
- package/src/providers/sdk/v1/sandbox/script-runner.ts +150 -0
- package/src/providers/sdk/v1/schemas/cli/provider.schema.json +504 -0
- package/src/providers/sdk/v1/schemas/primitives/acp-session-protocol-v1.json +131 -0
- package/src/providers/sdk/v1/schemas/primitives/native-history-codex-rollout-v1.json +66 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-approval-squash-v1.json +91 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-assistant-block-v1.json +91 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-cue-ordering-v1.json +47 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-dispatch-order-v1.json +32 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-footer-chrome-v1.json +42 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-index-finder-v1.json +27 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-modal-v1.json +125 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-prompt-marker-v1.json +45 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-session-id-extraction-v1.json +46 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-settled-prompt-v1.json +71 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-spinner-v1.json +83 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-transcript-pty-v1.json +83 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-visible-region-v1.json +57 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-welcome-screen-v1.json +35 -0
- package/src/providers/sdk/v1/types/cli/index.ts +365 -0
- package/src/providers/sdk/v1/types/common/index.ts +229 -0
- package/src/providers/sdk/v1/validators/index.ts +19 -0
- package/src/providers/sdk/v1/validators/manifest.ts +110 -0
- package/src/providers/sdk/v1/validators/taint.ts +309 -0
- package/src/providers/spec/adapter.ts +155 -0
- package/src/providers/spec/cli-adapter.ts +730 -0
- package/src/providers/spec/evaluator.ts +345 -0
- package/src/providers/spec/fsm-driver.ts +868 -0
- package/src/providers/spec/fsm-evaluator.ts +255 -0
- package/src/providers/spec/fsm-loader.ts +102 -0
- package/src/providers/spec/fsm-types.ts +199 -0
- package/src/providers/spec/native-history-executor.ts +943 -0
- package/src/providers/spec/route.ts +51 -0
- package/src/providers/spec/types.ts +189 -0
- package/src/providers/transcript-v2.ts +567 -0
- package/src/providers/types/interactive-prompt.ts +446 -0
- package/src/providers/version-archive.ts +38 -20
- package/src/repo-mesh-types.ts +175 -13
- package/src/sessions/registry.ts +6 -0
- package/src/shared-types-extra.ts +2 -4
- package/src/shared-types.ts +45 -1
- package/src/status/builders.ts +26 -6
- package/src/status/normalize.ts +2 -0
- package/src/status/reporter.ts +15 -0
- package/src/status/snapshot.ts +84 -25
- package/src/system/host-memory.ts +29 -12
- package/src/types.ts +5 -0
- package/dist/cli-adapters/terminal-backends/xterm-backend.d.ts +0 -17
- package/dist/mesh/mesh-sync.d.ts +0 -53
- package/src/cli-adapters/terminal-backends/ghostty-vt-backend.d.ts +0 -16
- package/src/cli-adapters/terminal-backends/xterm-backend.ts +0 -97
- package/src/mesh/mesh-sync.ts +0 -111
|
@@ -58,6 +58,40 @@ const savedHistoryFileSummaryCache = new Map<string, SavedHistoryFileSummaryCach
|
|
|
58
58
|
const savedHistoryBackgroundRefresh = new Set<string>();
|
|
59
59
|
const savedHistoryRollupInFlight = new Set<string>();
|
|
60
60
|
|
|
61
|
+
// Bounded-tail read cache. The dashboard re-subscribes and polls hot sessions
|
|
62
|
+
// every ~2.5s; without a cache each poll re-reads/parses/sorts the whole
|
|
63
|
+
// conversation just to slice a small tail. We key on (type, sessionId,
|
|
64
|
+
// pagination args) plus the on-disk size+mtime signature so an UNCHANGED
|
|
65
|
+
// session returns the previously computed tail in O(1) and only re-reads when a
|
|
66
|
+
// new message is appended (signature changes). The map is bounded by a small
|
|
67
|
+
// LRU to keep memory flat regardless of how many sessions are touched.
|
|
68
|
+
interface BoundedTailCacheEntry {
|
|
69
|
+
signature: string;
|
|
70
|
+
result: { messages: HistoryMessage[]; hasMore: boolean };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const BOUNDED_TAIL_CACHE_MAX_ENTRIES = 64;
|
|
74
|
+
const boundedTailReadCache = new Map<string, BoundedTailCacheEntry>();
|
|
75
|
+
|
|
76
|
+
function readBoundedTailCache(key: string, signature: string): { messages: HistoryMessage[]; hasMore: boolean } | null {
|
|
77
|
+
const cached = boundedTailReadCache.get(key);
|
|
78
|
+
if (!cached || cached.signature !== signature) return null;
|
|
79
|
+
// Refresh LRU recency.
|
|
80
|
+
boundedTailReadCache.delete(key);
|
|
81
|
+
boundedTailReadCache.set(key, cached);
|
|
82
|
+
return cached.result;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function writeBoundedTailCache(key: string, signature: string, result: { messages: HistoryMessage[]; hasMore: boolean }): void {
|
|
86
|
+
boundedTailReadCache.delete(key);
|
|
87
|
+
boundedTailReadCache.set(key, { signature, result });
|
|
88
|
+
while (boundedTailReadCache.size > BOUNDED_TAIL_CACHE_MAX_ENTRIES) {
|
|
89
|
+
const oldest = boundedTailReadCache.keys().next().value;
|
|
90
|
+
if (oldest === undefined) break;
|
|
91
|
+
boundedTailReadCache.delete(oldest);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
61
95
|
interface HistoryMessage {
|
|
62
96
|
ts: string; // ISO timestamp
|
|
63
97
|
receivedAt: number; // epoch ms
|
|
@@ -1180,6 +1214,79 @@ function pageHistoryRecords(
|
|
|
1180
1214
|
return { messages: sliced, hasMore: startInclusive > 0 };
|
|
1181
1215
|
}
|
|
1182
1216
|
|
|
1217
|
+
// A finite tail request can be served by reading only the newest files instead
|
|
1218
|
+
// of the whole conversation. Treat very large limits (e.g. MAX_SAFE_INTEGER, or
|
|
1219
|
+
// anything past a generous ceiling) as a full-history request so restore/seed
|
|
1220
|
+
// callers keep their existing behavior.
|
|
1221
|
+
const BOUNDED_TAIL_MAX_LIMIT = 5_000;
|
|
1222
|
+
// Slack added to the requested window before sorting/dedup/collapse so the
|
|
1223
|
+
// boundary message at the top of the tail dedupes/collapses identically to a
|
|
1224
|
+
// full read. Modest and bounded — it only widens the parse window, not output.
|
|
1225
|
+
const BOUNDED_TAIL_SLACK = 50;
|
|
1226
|
+
|
|
1227
|
+
function isBoundedTailRequest(limit: number, offset: number, excludeRecentCount: number): boolean {
|
|
1228
|
+
const numericLimit = Number(limit);
|
|
1229
|
+
if (!Number.isFinite(numericLimit) || numericLimit <= 0) return false;
|
|
1230
|
+
if (numericLimit > BOUNDED_TAIL_MAX_LIMIT) return false;
|
|
1231
|
+
const numericOffset = Number(offset);
|
|
1232
|
+
const numericExclude = Number(excludeRecentCount);
|
|
1233
|
+
if (!Number.isFinite(numericOffset) || !Number.isFinite(numericExclude)) return false;
|
|
1234
|
+
return true;
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
// Read newest-first only as many files as needed to cover the requested window
|
|
1238
|
+
// plus slack. listHistoryFiles already returns files reversed (newest-first), so
|
|
1239
|
+
// we accumulate (de-duped) candidates from the end and stop once we have enough,
|
|
1240
|
+
// then hand the bounded window to pageHistoryRecords in chronological order.
|
|
1241
|
+
function readBoundedTailRecords(
|
|
1242
|
+
agentType: string,
|
|
1243
|
+
dir: string,
|
|
1244
|
+
files: string[],
|
|
1245
|
+
needed: number,
|
|
1246
|
+
): { records: HistoryMessage[]; readAllFiles: boolean } {
|
|
1247
|
+
const collected: HistoryMessage[] = [];
|
|
1248
|
+
const seen = new Set<string>();
|
|
1249
|
+
let readAllFiles = true;
|
|
1250
|
+
|
|
1251
|
+
for (let f = 0; f < files.length; f++) {
|
|
1252
|
+
const filePath = path.join(dir, files[f]);
|
|
1253
|
+
let content: string;
|
|
1254
|
+
try {
|
|
1255
|
+
content = fs.readFileSync(filePath, 'utf-8');
|
|
1256
|
+
} catch {
|
|
1257
|
+
continue;
|
|
1258
|
+
}
|
|
1259
|
+
const lines = content.trim().split('\n').filter(Boolean);
|
|
1260
|
+
// Walk this file's lines newest-first so we fill the tail window from the
|
|
1261
|
+
// bottom. seen-dedup keeps the same first-wins-by-newest semantics the
|
|
1262
|
+
// full read produced (files are processed newest-first there too).
|
|
1263
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
1264
|
+
try {
|
|
1265
|
+
const parsed = JSON.parse(lines[i]) as HistoryMessage;
|
|
1266
|
+
const sanitizedMessage = sanitizeHistoryMessage(agentType, parsed);
|
|
1267
|
+
if (!sanitizedMessage) continue;
|
|
1268
|
+
const hash = buildHistoryMessageHash(agentType, sanitizedMessage);
|
|
1269
|
+
if (seen.has(hash)) continue;
|
|
1270
|
+
seen.add(hash);
|
|
1271
|
+
collected.push(sanitizedMessage);
|
|
1272
|
+
} catch { /* skip invalid lines */ }
|
|
1273
|
+
}
|
|
1274
|
+
// Stop once we have the window AND there is at least one more file (so a
|
|
1275
|
+
// potential older boundary message exists). If this is the last file we
|
|
1276
|
+
// fall through and mark the whole history as read.
|
|
1277
|
+
if (collected.length >= needed && f < files.length - 1) {
|
|
1278
|
+
readAllFiles = false;
|
|
1279
|
+
break;
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1283
|
+
// collected is newest-first across the bounded window; restore chronological
|
|
1284
|
+
// (oldest-first) order before paging. pageHistoryRecords re-sorts by
|
|
1285
|
+
// receivedAt regardless, so this is purely for stable input ordering.
|
|
1286
|
+
collected.reverse();
|
|
1287
|
+
return { records: collected, readAllFiles };
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1183
1290
|
export function readChatHistory(
|
|
1184
1291
|
agentType: string,
|
|
1185
1292
|
offset: number = 0,
|
|
@@ -1196,6 +1303,33 @@ export function readChatHistory(
|
|
|
1196
1303
|
// JSONL file list — filter by persistent history key when specified
|
|
1197
1304
|
const files = listHistoryFiles(dir, historySessionId);
|
|
1198
1305
|
|
|
1306
|
+
const bounded = isBoundedTailRequest(limit, offset, excludeRecentCount);
|
|
1307
|
+
|
|
1308
|
+
if (bounded) {
|
|
1309
|
+
const fileSignatures = buildSavedHistoryFileSignatureMap(dir, files);
|
|
1310
|
+
const cacheKey = `${sanitized}\0${historySessionId || ''}\0${offset}\0${limit}\0${excludeRecentCount}\0${historyBehavior?.collapseConsecutiveAssistantTurns ? '1' : '0'}`;
|
|
1311
|
+
const signature = buildSavedHistoryCacheSignature(files, fileSignatures);
|
|
1312
|
+
const cached = readBoundedTailCache(cacheKey, signature);
|
|
1313
|
+
if (cached) return cached;
|
|
1314
|
+
|
|
1315
|
+
// Window large enough that the top boundary dedupes/collapses the same
|
|
1316
|
+
// as a full read. hasMore reflects whether older messages exist beyond
|
|
1317
|
+
// the window we actually read.
|
|
1318
|
+
const numericLimit = Math.max(1, Number(limit));
|
|
1319
|
+
const numericOffset = Math.max(0, Number(offset));
|
|
1320
|
+
const numericExclude = Math.max(0, Number(excludeRecentCount));
|
|
1321
|
+
const needed = numericLimit + numericOffset + numericExclude + Math.max(BOUNDED_TAIL_SLACK, numericLimit);
|
|
1322
|
+
const { records, readAllFiles } = readBoundedTailRecords(agentType, dir, files, needed);
|
|
1323
|
+
const result = pageHistoryRecords(agentType, records, offset, limit, excludeRecentCount, historyBehavior);
|
|
1324
|
+
// If we read every file, the conversation is fully represented in the
|
|
1325
|
+
// window and pageHistoryRecords' hasMore is authoritative. If we
|
|
1326
|
+
// stopped early there are older messages we never read, so hasMore
|
|
1327
|
+
// must stay true regardless of the in-window slice position.
|
|
1328
|
+
const boundedResult = readAllFiles ? result : { messages: result.messages, hasMore: true };
|
|
1329
|
+
writeBoundedTailCache(cacheKey, signature, boundedResult);
|
|
1330
|
+
return boundedResult;
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1199
1333
|
const allMessages: HistoryMessage[] = [];
|
|
1200
1334
|
const seen = new Set<string>();
|
|
1201
1335
|
|
|
@@ -1345,7 +1479,16 @@ function rewriteCanonicalSavedHistory(agentType: string, historySessionId: strin
|
|
|
1345
1479
|
|
|
1346
1480
|
export type ProviderNativeHistoryScripts = Record<string, ((input: any) => any) | undefined>;
|
|
1347
1481
|
|
|
1348
|
-
type ProviderNativeHistoryReadResult = {
|
|
1482
|
+
type ProviderNativeHistoryReadResult = {
|
|
1483
|
+
records: HistoryMessage[];
|
|
1484
|
+
sourcePath: string;
|
|
1485
|
+
sourceMtimeMs: number;
|
|
1486
|
+
providerSessionId?: string;
|
|
1487
|
+
workspace?: string;
|
|
1488
|
+
nativeHistoryCoverage?: string;
|
|
1489
|
+
partialReason?: string;
|
|
1490
|
+
unavailableReason?: string;
|
|
1491
|
+
};
|
|
1349
1492
|
|
|
1350
1493
|
function getNativeHistoryScriptName(canonicalHistory: ProviderCanonicalHistoryConfig | undefined, key: 'readSession' | 'listSessions'): string {
|
|
1351
1494
|
const configured = canonicalHistory?.scripts?.[key];
|
|
@@ -1367,19 +1510,42 @@ function normalizeProviderNativeHistoryRecords(agentType: string, historySession
|
|
|
1367
1510
|
if (!Array.isArray(records)) return [];
|
|
1368
1511
|
const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
|
|
1369
1512
|
return records
|
|
1370
|
-
.map((record: any) =>
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1513
|
+
.map((record: any) => {
|
|
1514
|
+
const base: HistoryMessage = {
|
|
1515
|
+
ts: typeof record?.ts === 'string' ? record.ts : new Date(Number(record?.receivedAt) || Date.now()).toISOString(),
|
|
1516
|
+
receivedAt: Number(record?.receivedAt) || Date.parse(record?.ts || '') || Date.now(),
|
|
1517
|
+
role: record?.role,
|
|
1518
|
+
content: String(record?.content || ''),
|
|
1519
|
+
kind: record?.kind || (record?.role === 'system' ? 'session_start' : 'standard'),
|
|
1520
|
+
senderName: record?.senderName,
|
|
1521
|
+
agent: agentType,
|
|
1522
|
+
instanceId: record?.instanceId,
|
|
1523
|
+
historySessionId: normalizeSavedHistorySessionId(record?.historySessionId || normalizedSessionId),
|
|
1524
|
+
sessionTitle: record?.sessionTitle,
|
|
1525
|
+
workspace: record?.workspace,
|
|
1526
|
+
} as HistoryMessage;
|
|
1527
|
+
// (A2.3 v2 identity passthrough) — if the producer (native_history.js)
|
|
1528
|
+
// emitted v2 stable identity, keep it across the sanitize layer so
|
|
1529
|
+
// downstream (chat-commands.ts normalizeNativeHistoryMessages) sees
|
|
1530
|
+
// the producer's contract output instead of recomputing from index
|
|
1531
|
+
// and content hash. v1 producers without these fields are unaffected.
|
|
1532
|
+
if (typeof record?.providerUnitKey === 'string' && record.providerUnitKey) {
|
|
1533
|
+
(base as any).providerUnitKey = record.providerUnitKey;
|
|
1534
|
+
}
|
|
1535
|
+
if (typeof record?.bubbleId === 'string' && record.bubbleId) {
|
|
1536
|
+
(base as any).bubbleId = record.bubbleId;
|
|
1537
|
+
}
|
|
1538
|
+
if (typeof record?.sequence === 'number' && Number.isFinite(record.sequence)) {
|
|
1539
|
+
(base as any).sequence = record.sequence;
|
|
1540
|
+
}
|
|
1541
|
+
if (typeof record?._turnKey === 'string' && record._turnKey) {
|
|
1542
|
+
(base as any)._turnKey = record._turnKey;
|
|
1543
|
+
}
|
|
1544
|
+
if (typeof record?.bubbleState === 'string' && record.bubbleState) {
|
|
1545
|
+
(base as any).bubbleState = record.bubbleState;
|
|
1546
|
+
}
|
|
1547
|
+
return sanitizeHistoryMessage(agentType, base);
|
|
1548
|
+
})
|
|
1383
1549
|
.filter(Boolean) as HistoryMessage[];
|
|
1384
1550
|
}
|
|
1385
1551
|
|
|
@@ -1387,27 +1553,41 @@ function callProviderNativeHistoryRead(
|
|
|
1387
1553
|
agentType: string,
|
|
1388
1554
|
canonicalHistory: ProviderCanonicalHistoryConfig | undefined,
|
|
1389
1555
|
scripts: ProviderNativeHistoryScripts | undefined,
|
|
1390
|
-
historySessionId: string,
|
|
1556
|
+
historySessionId: string | undefined,
|
|
1391
1557
|
workspace?: string,
|
|
1558
|
+
excludeInProgressTurn?: boolean,
|
|
1559
|
+
sessionStartedAtMs?: number,
|
|
1560
|
+
envOverrides?: Record<string, string>,
|
|
1561
|
+
forceRefresh?: boolean,
|
|
1392
1562
|
): ProviderNativeHistoryReadResult | null {
|
|
1393
1563
|
const fn = getProviderNativeHistoryScript(scripts, canonicalHistory, 'readSession');
|
|
1394
1564
|
if (!fn) return null;
|
|
1565
|
+
const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId || '');
|
|
1395
1566
|
const result = fn({
|
|
1396
1567
|
agentType,
|
|
1397
|
-
sessionId:
|
|
1398
|
-
historySessionId,
|
|
1568
|
+
sessionId: normalizedSessionId,
|
|
1569
|
+
historySessionId: normalizedSessionId,
|
|
1399
1570
|
workspace,
|
|
1400
1571
|
format: canonicalHistory?.format,
|
|
1401
1572
|
watchPath: canonicalHistory?.watchPath,
|
|
1402
|
-
|
|
1573
|
+
excludeInProgressTurn: excludeInProgressTurn === true,
|
|
1574
|
+
sessionStartedAtMs,
|
|
1575
|
+
envOverrides,
|
|
1576
|
+
forceRefresh: forceRefresh === true,
|
|
1577
|
+
args: { sessionId: normalizedSessionId, historySessionId: normalizedSessionId, workspace, excludeInProgressTurn: excludeInProgressTurn === true, sessionStartedAtMs, envOverrides, forceRefresh: forceRefresh === true },
|
|
1403
1578
|
});
|
|
1404
1579
|
if (!result || typeof result !== 'object') return null;
|
|
1405
|
-
const records = normalizeProviderNativeHistoryRecords(agentType,
|
|
1580
|
+
const records = normalizeProviderNativeHistoryRecords(agentType, normalizedSessionId, (result as any).messages || (result as any).records);
|
|
1406
1581
|
if (records.length === 0) return null;
|
|
1407
1582
|
return {
|
|
1408
1583
|
records,
|
|
1409
1584
|
sourcePath: typeof (result as any).sourcePath === 'string' ? (result as any).sourcePath : '',
|
|
1410
1585
|
sourceMtimeMs: Number((result as any).sourceMtimeMs) || 0,
|
|
1586
|
+
providerSessionId: typeof (result as any).providerSessionId === 'string' ? (result as any).providerSessionId.trim() : undefined,
|
|
1587
|
+
workspace: typeof (result as any).workspace === 'string' ? (result as any).workspace.trim() : undefined,
|
|
1588
|
+
nativeHistoryCoverage: typeof (result as any).nativeHistoryCoverage === 'string' ? (result as any).nativeHistoryCoverage.trim() : undefined,
|
|
1589
|
+
partialReason: typeof (result as any).partialReason === 'string' ? (result as any).partialReason.trim() : undefined,
|
|
1590
|
+
unavailableReason: typeof (result as any).unavailableReason === 'string' ? (result as any).unavailableReason.trim() : undefined,
|
|
1411
1591
|
};
|
|
1412
1592
|
}
|
|
1413
1593
|
|
|
@@ -1417,10 +1597,15 @@ function buildNativeHistoryReadResult(
|
|
|
1417
1597
|
scripts: ProviderNativeHistoryScripts | undefined,
|
|
1418
1598
|
historySessionId: string | undefined,
|
|
1419
1599
|
workspace?: string,
|
|
1600
|
+
excludeInProgressTurn?: boolean,
|
|
1601
|
+
sessionStartedAtMs?: number,
|
|
1602
|
+
envOverrides?: Record<string, string>,
|
|
1603
|
+
forceRefresh?: boolean,
|
|
1420
1604
|
): ProviderNativeHistoryReadResult | null {
|
|
1421
1605
|
const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId || '');
|
|
1422
|
-
|
|
1423
|
-
|
|
1606
|
+
const normalizedWorkspace = typeof workspace === 'string' ? workspace.trim() : '';
|
|
1607
|
+
if (!canonicalHistory || (!normalizedSessionId && !normalizedWorkspace) || !isNativeSourceCanonicalHistory(canonicalHistory)) return null;
|
|
1608
|
+
return callProviderNativeHistoryRead(agentType, canonicalHistory, scripts, normalizedSessionId, workspace, excludeInProgressTurn, sessionStartedAtMs, envOverrides, forceRefresh);
|
|
1424
1609
|
}
|
|
1425
1610
|
|
|
1426
1611
|
function materializeNativeHistoryToMirror(
|
|
@@ -1476,16 +1661,36 @@ export function readProviderChatHistory(
|
|
|
1476
1661
|
excludeRecentCount?: number;
|
|
1477
1662
|
historyBehavior?: ProviderHistoryBehavior;
|
|
1478
1663
|
scripts?: ProviderNativeHistoryScripts;
|
|
1664
|
+
excludeInProgressTurn?: boolean;
|
|
1665
|
+
sessionStartedAtMs?: number;
|
|
1666
|
+
envOverrides?: Record<string, string>;
|
|
1667
|
+
forceRefresh?: boolean;
|
|
1479
1668
|
} = {},
|
|
1480
|
-
): {
|
|
1481
|
-
|
|
1482
|
-
|
|
1669
|
+
): {
|
|
1670
|
+
messages: HistoryMessage[];
|
|
1671
|
+
hasMore: boolean;
|
|
1672
|
+
source: 'provider-native' | 'adhdev-mirror' | 'native-unavailable';
|
|
1673
|
+
sourcePath?: string;
|
|
1674
|
+
sourceMtimeMs?: number;
|
|
1675
|
+
providerSessionId?: string;
|
|
1676
|
+
workspace?: string;
|
|
1677
|
+
nativeHistoryCoverage?: string;
|
|
1678
|
+
partialReason?: string;
|
|
1679
|
+
unavailableReason?: string;
|
|
1680
|
+
} {
|
|
1681
|
+
if (isNativeSourceCanonicalHistory(options.canonicalHistory) && (options.historySessionId || options.workspace)) {
|
|
1682
|
+
const nativeResult = buildNativeHistoryReadResult(agentType, options.canonicalHistory, options.scripts, options.historySessionId, options.workspace, options.excludeInProgressTurn, options.sessionStartedAtMs, options.envOverrides, options.forceRefresh);
|
|
1483
1683
|
if (!nativeResult) return { messages: [], hasMore: false, source: 'native-unavailable' };
|
|
1484
1684
|
return {
|
|
1485
1685
|
...pageHistoryRecords(agentType, nativeResult.records, options.offset || 0, options.limit || 30, options.excludeRecentCount || 0, options.historyBehavior),
|
|
1486
1686
|
source: 'provider-native',
|
|
1487
1687
|
sourcePath: nativeResult.sourcePath,
|
|
1488
1688
|
sourceMtimeMs: nativeResult.sourceMtimeMs,
|
|
1689
|
+
providerSessionId: nativeResult.providerSessionId,
|
|
1690
|
+
workspace: nativeResult.workspace,
|
|
1691
|
+
nativeHistoryCoverage: nativeResult.nativeHistoryCoverage,
|
|
1692
|
+
partialReason: nativeResult.partialReason,
|
|
1693
|
+
unavailableReason: nativeResult.unavailableReason,
|
|
1489
1694
|
};
|
|
1490
1695
|
}
|
|
1491
1696
|
return {
|
package/src/config/config.ts
CHANGED
|
@@ -272,6 +272,18 @@ export function getConfigDir(): string {
|
|
|
272
272
|
return dir;
|
|
273
273
|
}
|
|
274
274
|
|
|
275
|
+
/**
|
|
276
|
+
* Get the daemon runtime data directory (~/.adhdev/daemon/).
|
|
277
|
+
* Distinct from the user-config dir so runtime state can be cleared independently.
|
|
278
|
+
*/
|
|
279
|
+
export function getDaemonDataDir(): string {
|
|
280
|
+
const dir = join(getConfigDir(), 'daemon');
|
|
281
|
+
if (!existsSync(dir)) {
|
|
282
|
+
mkdirSync(dir, { recursive: true });
|
|
283
|
+
}
|
|
284
|
+
return dir;
|
|
285
|
+
}
|
|
286
|
+
|
|
275
287
|
/**
|
|
276
288
|
* Get the config file path
|
|
277
289
|
*/
|