@adhdev/daemon-core 0.9.82-rc.474 → 0.9.82-rc.475
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/config/chat-history.d.ts +1 -0
- package/dist/index.js +41 -15
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +41 -15
- package/dist/index.mjs.map +1 -1
- package/dist/providers/cli-provider-instance.d.ts +15 -3
- package/package.json +3 -3
- package/src/commands/chat-commands-read.ts +14 -0
- package/src/config/chat-history.ts +19 -3
- package/src/providers/cli-provider-instance.ts +16 -4
|
@@ -287,9 +287,21 @@ export declare class CliProviderInstance implements ProviderInstance {
|
|
|
287
287
|
private pruneRecentUserInputAcks;
|
|
288
288
|
/**
|
|
289
289
|
* Owner token for this session in the antigravity conversation-claim
|
|
290
|
-
* registry.
|
|
291
|
-
*
|
|
292
|
-
*
|
|
290
|
+
* registry. Keyed on the daemon instance id — the SAME value the session
|
|
291
|
+
* registry stores as this session's `sessionId` (see cli-manager
|
|
292
|
+
* `sessionRegistry.register({ sessionId: cliInstance.instanceId })`) and the
|
|
293
|
+
* read side hands the dispatcher as `instanceId`. Both sides therefore
|
|
294
|
+
* derive the identical `iid:<instanceId>` token, so the claims the
|
|
295
|
+
* dispatcher records under this session are exactly the ones dispose()
|
|
296
|
+
* releases.
|
|
297
|
+
*
|
|
298
|
+
* This must NOT be derived from a spawn timestamp: the instance's
|
|
299
|
+
* `startedAt`, the adapter's `spawnedAtMs`, and the session registry's
|
|
300
|
+
* `spawnedAtMs` are three INDEPENDENT `Date.now()` samples for the one
|
|
301
|
+
* session, so a workspace+spawn-time token computed here would never equal
|
|
302
|
+
* the read side's — the claim isolation then silently collapses and two
|
|
303
|
+
* concurrent antigravity sessions cross-bind each other's conversation .db
|
|
304
|
+
* (coordinator+worker chat crosswire).
|
|
293
305
|
*/
|
|
294
306
|
private antigravityClaimOwner;
|
|
295
307
|
dispose(): void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adhdev/daemon-core",
|
|
3
|
-
"version": "0.9.82-rc.
|
|
3
|
+
"version": "0.9.82-rc.475",
|
|
4
4
|
"description": "ADHDev daemon core — CDP, IDE detection, providers, command execution",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -47,8 +47,8 @@
|
|
|
47
47
|
"author": "vilmire",
|
|
48
48
|
"license": "AGPL-3.0-or-later",
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@adhdev/mesh-shared": "0.9.82-rc.
|
|
51
|
-
"@adhdev/session-host-core": "0.9.82-rc.
|
|
50
|
+
"@adhdev/mesh-shared": "0.9.82-rc.475",
|
|
51
|
+
"@adhdev/session-host-core": "0.9.82-rc.475",
|
|
52
52
|
"@agentclientprotocol/sdk": "^0.16.1",
|
|
53
53
|
"ajv": "^8.20.0",
|
|
54
54
|
"ajv-formats": "^3.0.1",
|
|
@@ -1095,6 +1095,13 @@ function readCliProviderNativeHistory(agentStr: string, args: {
|
|
|
1095
1095
|
// the downstream hasSafeNativeHistoryMapping workspace-overlap gate. Only the
|
|
1096
1096
|
// read_chat path opts in, and only with a concrete workspace.
|
|
1097
1097
|
allowWorkspaceLatestFallback?: boolean;
|
|
1098
|
+
// ADHDev session id of the reading session (== the session registry's
|
|
1099
|
+
// sessionId == the provider instance's instanceId). Threaded to the
|
|
1100
|
+
// native-history dispatcher so antigravity's conversation-claim owner token
|
|
1101
|
+
// is keyed on this stable identity and matches the instance-side token —
|
|
1102
|
+
// without it two concurrent antigravity sessions cross-bind each other's
|
|
1103
|
+
// conversation .db.
|
|
1104
|
+
instanceId?: string;
|
|
1098
1105
|
}): ReturnType<typeof readProviderChatHistory> & { lookup: 'session' | 'workspace' } {
|
|
1099
1106
|
const canBindFromLiveSession = !args.historySessionId
|
|
1100
1107
|
&& typeof args.sessionStartedAtMs === 'number'
|
|
@@ -1146,6 +1153,7 @@ function readCliProviderNativeHistory(agentStr: string, args: {
|
|
|
1146
1153
|
excludeInProgressTurn: args.excludeInProgressTurn,
|
|
1147
1154
|
sessionStartedAtMs: args.sessionStartedAtMs,
|
|
1148
1155
|
envOverrides: args.envOverrides,
|
|
1156
|
+
instanceId: args.instanceId,
|
|
1149
1157
|
});
|
|
1150
1158
|
const boundProviderSessionId = typeof (sessionHistory as any)?.providerSessionId === 'string'
|
|
1151
1159
|
? (sessionHistory as any).providerSessionId.trim()
|
|
@@ -1541,6 +1549,7 @@ export async function handleChatHistory(h: CommandHelpers, args: any): Promise<C
|
|
|
1541
1549
|
scripts: provider?.scripts as any,
|
|
1542
1550
|
sessionStartedAtMs: sessionStartedAtMsFromRegistry(h, args?.targetSessionId),
|
|
1543
1551
|
envOverrides: sessionSpawnEnvFromAdapter(h, args?.targetSessionId),
|
|
1552
|
+
instanceId: typeof args?.targetSessionId === 'string' ? args.targetSessionId : undefined,
|
|
1544
1553
|
pinnedProviderSessionId: getBoundProviderSessionIdPin(args?.targetSessionId),
|
|
1545
1554
|
})
|
|
1546
1555
|
: readProviderChatHistory(agentStr, {
|
|
@@ -1772,6 +1781,9 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
1772
1781
|
excludeInProgressTurn: returnedStatus === 'waiting_approval',
|
|
1773
1782
|
sessionStartedAtMs: sessionStartedAtMsFromRegistry(h, args?.targetSessionId),
|
|
1774
1783
|
envOverrides: sessionSpawnEnvFromAdapter(h, args?.targetSessionId),
|
|
1784
|
+
// Stable per-session identity for antigravity's conversation-claim
|
|
1785
|
+
// owner token (== session registry sessionId == instance instanceId).
|
|
1786
|
+
instanceId: typeof args?.targetSessionId === 'string' ? args.targetSessionId : undefined,
|
|
1775
1787
|
pinnedProviderSessionId: getBoundProviderSessionIdPin(targetSessionId),
|
|
1776
1788
|
// Last-resort only when no pin was ever recorded for this
|
|
1777
1789
|
// session; the downstream workspace-overlap safety gate
|
|
@@ -1847,6 +1859,7 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
1847
1859
|
excludeInProgressTurn: returnedStatus === 'waiting_approval',
|
|
1848
1860
|
sessionStartedAtMs,
|
|
1849
1861
|
envOverrides: sessionSpawnEnvFromAdapter(h, args?.targetSessionId),
|
|
1862
|
+
instanceId: typeof args?.targetSessionId === 'string' ? args.targetSessionId : undefined,
|
|
1850
1863
|
});
|
|
1851
1864
|
nativeHistoryError = undefined;
|
|
1852
1865
|
nativeMessages = nativeHistory && Array.isArray(nativeHistory.messages)
|
|
@@ -2145,6 +2158,7 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
2145
2158
|
scripts: provider?.scripts as any,
|
|
2146
2159
|
sessionStartedAtMs: sessionStartedAtMsFromRegistry(h, args?.targetSessionId),
|
|
2147
2160
|
envOverrides: sessionSpawnEnvFromAdapter(h, args?.targetSessionId),
|
|
2161
|
+
instanceId: typeof args?.targetSessionId === 'string' ? args.targetSessionId : undefined,
|
|
2148
2162
|
pinnedProviderSessionId: pinnedProviderSessionIdForHistory,
|
|
2149
2163
|
// Last-resort only when no pin was ever recorded AND the
|
|
2150
2164
|
// runtime fallback did not resolve a real provider session.
|
|
@@ -1813,10 +1813,12 @@ function callProviderNativeHistoryRead(
|
|
|
1813
1813
|
sessionStartedAtMs?: number,
|
|
1814
1814
|
envOverrides?: Record<string, string>,
|
|
1815
1815
|
forceRefresh?: boolean,
|
|
1816
|
+
instanceId?: string,
|
|
1816
1817
|
): ProviderNativeHistoryReadResult | null {
|
|
1817
1818
|
const fn = getProviderNativeHistoryScript(scripts, canonicalHistory, 'readSession');
|
|
1818
1819
|
if (!fn) return null;
|
|
1819
1820
|
const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId || '');
|
|
1821
|
+
const normalizedInstanceId = typeof instanceId === 'string' ? instanceId.trim() : '';
|
|
1820
1822
|
const result = fn({
|
|
1821
1823
|
agentType,
|
|
1822
1824
|
sessionId: normalizedSessionId,
|
|
@@ -1831,6 +1833,12 @@ function callProviderNativeHistoryRead(
|
|
|
1831
1833
|
// which leaves the guard disarmed so discovery still works.
|
|
1832
1834
|
providerSessionId: normalizedSessionId,
|
|
1833
1835
|
historySessionId: normalizedSessionId,
|
|
1836
|
+
// Stable per-session owner key for the antigravity conversation-claim
|
|
1837
|
+
// registry (see dispatcher.resolveAntigravityPath / antigravityOwnerToken).
|
|
1838
|
+
// Equals the session registry's sessionId and the provider instance's
|
|
1839
|
+
// instanceId, so read side and instance side derive the identical claim
|
|
1840
|
+
// owner token and two concurrent antigravity sessions never cross-bind.
|
|
1841
|
+
instanceId: normalizedInstanceId || undefined,
|
|
1834
1842
|
workspace,
|
|
1835
1843
|
format: canonicalHistory?.format,
|
|
1836
1844
|
watchPath: canonicalHistory?.watchPath,
|
|
@@ -1838,7 +1846,7 @@ function callProviderNativeHistoryRead(
|
|
|
1838
1846
|
sessionStartedAtMs,
|
|
1839
1847
|
envOverrides,
|
|
1840
1848
|
forceRefresh: forceRefresh === true,
|
|
1841
|
-
args: { sessionId: normalizedSessionId, historySessionId: normalizedSessionId, workspace, excludeInProgressTurn: excludeInProgressTurn === true, sessionStartedAtMs, envOverrides, forceRefresh: forceRefresh === true },
|
|
1849
|
+
args: { sessionId: normalizedSessionId, historySessionId: normalizedSessionId, instanceId: normalizedInstanceId || undefined, workspace, excludeInProgressTurn: excludeInProgressTurn === true, sessionStartedAtMs, envOverrides, forceRefresh: forceRefresh === true },
|
|
1842
1850
|
});
|
|
1843
1851
|
if (!result || typeof result !== 'object') return null;
|
|
1844
1852
|
const records = normalizeProviderNativeHistoryRecords(agentType, normalizedSessionId, (result as any).messages || (result as any).records);
|
|
@@ -1865,11 +1873,12 @@ function buildNativeHistoryReadResult(
|
|
|
1865
1873
|
sessionStartedAtMs?: number,
|
|
1866
1874
|
envOverrides?: Record<string, string>,
|
|
1867
1875
|
forceRefresh?: boolean,
|
|
1876
|
+
instanceId?: string,
|
|
1868
1877
|
): ProviderNativeHistoryReadResult | null {
|
|
1869
1878
|
const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId || '');
|
|
1870
1879
|
const normalizedWorkspace = typeof workspace === 'string' ? workspace.trim() : '';
|
|
1871
1880
|
if (!canonicalHistory || (!normalizedSessionId && !normalizedWorkspace) || !isNativeSourceCanonicalHistory(canonicalHistory)) return null;
|
|
1872
|
-
return callProviderNativeHistoryRead(agentType, canonicalHistory, scripts, normalizedSessionId, workspace, excludeInProgressTurn, sessionStartedAtMs, envOverrides, forceRefresh);
|
|
1881
|
+
return callProviderNativeHistoryRead(agentType, canonicalHistory, scripts, normalizedSessionId, workspace, excludeInProgressTurn, sessionStartedAtMs, envOverrides, forceRefresh, instanceId);
|
|
1873
1882
|
}
|
|
1874
1883
|
|
|
1875
1884
|
function materializeNativeHistoryToMirror(
|
|
@@ -1929,6 +1938,13 @@ export function readProviderChatHistory(
|
|
|
1929
1938
|
sessionStartedAtMs?: number;
|
|
1930
1939
|
envOverrides?: Record<string, string>;
|
|
1931
1940
|
forceRefresh?: boolean;
|
|
1941
|
+
// Daemon instance id of the reading session (== the session registry's
|
|
1942
|
+
// sessionId). Threaded to the native-history dispatcher so the
|
|
1943
|
+
// antigravity conversation-claim owner token is keyed on this stable
|
|
1944
|
+
// per-session identity — identical to the token the provider instance
|
|
1945
|
+
// derives — instead of a spawn timestamp that differs across sample
|
|
1946
|
+
// sites and silently breaks claim isolation.
|
|
1947
|
+
instanceId?: string;
|
|
1932
1948
|
} = {},
|
|
1933
1949
|
): {
|
|
1934
1950
|
messages: HistoryMessage[];
|
|
@@ -1943,7 +1959,7 @@ export function readProviderChatHistory(
|
|
|
1943
1959
|
unavailableReason?: string;
|
|
1944
1960
|
} {
|
|
1945
1961
|
if (isNativeSourceCanonicalHistory(options.canonicalHistory) && (options.historySessionId || options.workspace)) {
|
|
1946
|
-
const nativeResult = buildNativeHistoryReadResult(agentType, options.canonicalHistory, options.scripts, options.historySessionId, options.workspace, options.excludeInProgressTurn, options.sessionStartedAtMs, options.envOverrides, options.forceRefresh);
|
|
1962
|
+
const nativeResult = buildNativeHistoryReadResult(agentType, options.canonicalHistory, options.scripts, options.historySessionId, options.workspace, options.excludeInProgressTurn, options.sessionStartedAtMs, options.envOverrides, options.forceRefresh, options.instanceId);
|
|
1947
1963
|
if (!nativeResult) return { messages: [], hasMore: false, source: 'native-unavailable' };
|
|
1948
1964
|
return {
|
|
1949
1965
|
...pageHistoryRecords(agentType, nativeResult.records, options.offset || 0, options.limit || 30, options.excludeRecentCount || 0, options.historyBehavior),
|
|
@@ -1089,12 +1089,24 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
1089
1089
|
|
|
1090
1090
|
/**
|
|
1091
1091
|
* Owner token for this session in the antigravity conversation-claim
|
|
1092
|
-
* registry.
|
|
1093
|
-
*
|
|
1094
|
-
*
|
|
1092
|
+
* registry. Keyed on the daemon instance id — the SAME value the session
|
|
1093
|
+
* registry stores as this session's `sessionId` (see cli-manager
|
|
1094
|
+
* `sessionRegistry.register({ sessionId: cliInstance.instanceId })`) and the
|
|
1095
|
+
* read side hands the dispatcher as `instanceId`. Both sides therefore
|
|
1096
|
+
* derive the identical `iid:<instanceId>` token, so the claims the
|
|
1097
|
+
* dispatcher records under this session are exactly the ones dispose()
|
|
1098
|
+
* releases.
|
|
1099
|
+
*
|
|
1100
|
+
* This must NOT be derived from a spawn timestamp: the instance's
|
|
1101
|
+
* `startedAt`, the adapter's `spawnedAtMs`, and the session registry's
|
|
1102
|
+
* `spawnedAtMs` are three INDEPENDENT `Date.now()` samples for the one
|
|
1103
|
+
* session, so a workspace+spawn-time token computed here would never equal
|
|
1104
|
+
* the read side's — the claim isolation then silently collapses and two
|
|
1105
|
+
* concurrent antigravity sessions cross-bind each other's conversation .db
|
|
1106
|
+
* (coordinator+worker chat crosswire).
|
|
1095
1107
|
*/
|
|
1096
1108
|
private antigravityClaimOwner(): string {
|
|
1097
|
-
return antigravityOwnerToken(this.workingDir, this.startedAt);
|
|
1109
|
+
return antigravityOwnerToken(this.workingDir, this.startedAt, this.instanceId);
|
|
1098
1110
|
}
|
|
1099
1111
|
|
|
1100
1112
|
dispose(): void {
|