paseo-acp-agy 1.2.7 → 1.2.8
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/native-sessions.d.ts +4 -0
- package/dist/native-sessions.js +170 -0
- package/dist/session.d.ts +2 -0
- package/dist/session.js +40 -9
- package/package.json +1 -1
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { SessionInfo } from "./protocol.js";
|
|
2
|
+
export declare function getAgyAppDataDir(): string;
|
|
3
|
+
export declare function loadNativeAntigravitySessions(cwd?: string): SessionInfo[];
|
|
4
|
+
export declare function getNativeAntigravitySession(conversationId: string): SessionInfo | null;
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import { createRequire } from "node:module";
|
|
5
|
+
import { logger } from "./logger.js";
|
|
6
|
+
const require = createRequire(import.meta.url);
|
|
7
|
+
export function getAgyAppDataDir() {
|
|
8
|
+
if (process.env.AGY_APP_DATA_DIR) {
|
|
9
|
+
return process.env.AGY_APP_DATA_DIR;
|
|
10
|
+
}
|
|
11
|
+
if (process.env.AGY_BRAIN_DIR) {
|
|
12
|
+
return path.dirname(process.env.AGY_BRAIN_DIR);
|
|
13
|
+
}
|
|
14
|
+
return path.join(os.homedir(), ".gemini", "antigravity-cli");
|
|
15
|
+
}
|
|
16
|
+
export function loadNativeAntigravitySessions(cwd) {
|
|
17
|
+
const results = [];
|
|
18
|
+
const appDataDir = getAgyAppDataDir();
|
|
19
|
+
const dbPath = path.join(appDataDir, "conversation_summaries.db");
|
|
20
|
+
const normalizedTargetCwd = cwd ? path.resolve(cwd).toLowerCase() : undefined;
|
|
21
|
+
if (fs.existsSync(dbPath)) {
|
|
22
|
+
let DatabaseSync = null;
|
|
23
|
+
try {
|
|
24
|
+
DatabaseSync = require("node:sqlite")?.DatabaseSync;
|
|
25
|
+
}
|
|
26
|
+
catch { }
|
|
27
|
+
if (DatabaseSync) {
|
|
28
|
+
try {
|
|
29
|
+
const db = new DatabaseSync(dbPath, { readOnly: true });
|
|
30
|
+
const rows = db
|
|
31
|
+
.prepare(`SELECT conversation_id, title, preview, last_modified_time, workspace_uris
|
|
32
|
+
FROM conversation_summaries
|
|
33
|
+
ORDER BY last_modified_time DESC
|
|
34
|
+
LIMIT 200`)
|
|
35
|
+
.all();
|
|
36
|
+
for (const row of rows) {
|
|
37
|
+
if (!row.conversation_id)
|
|
38
|
+
continue;
|
|
39
|
+
let primaryCwd = process.cwd();
|
|
40
|
+
let matchesCwd = false;
|
|
41
|
+
if (row.workspace_uris) {
|
|
42
|
+
try {
|
|
43
|
+
const uris = JSON.parse(row.workspace_uris);
|
|
44
|
+
if (Array.isArray(uris) && uris.length > 0) {
|
|
45
|
+
const filePaths = uris
|
|
46
|
+
.map((u) => u.replace(/^file:\/\//i, ""))
|
|
47
|
+
.filter(Boolean);
|
|
48
|
+
if (filePaths.length > 0) {
|
|
49
|
+
primaryCwd = filePaths[0];
|
|
50
|
+
}
|
|
51
|
+
if (normalizedTargetCwd) {
|
|
52
|
+
matchesCwd = filePaths.some((p) => path.resolve(p).toLowerCase() === normalizedTargetCwd);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch { }
|
|
57
|
+
}
|
|
58
|
+
if (normalizedTargetCwd && !matchesCwd) {
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
const rawDate = row.last_modified_time;
|
|
62
|
+
const dateIso = rawDate ? new Date(rawDate).toISOString() : undefined;
|
|
63
|
+
results.push({
|
|
64
|
+
sessionId: row.conversation_id,
|
|
65
|
+
cwd: primaryCwd,
|
|
66
|
+
title: (row.title && row.title.trim()) ||
|
|
67
|
+
(row.preview && row.preview.trim()) ||
|
|
68
|
+
"Antigravity Session",
|
|
69
|
+
updatedAt: dateIso,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
logger.debug("Failed to read native conversation summaries from sqlite", {
|
|
75
|
+
error: err.message,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Fallback: Also scan brainDir for any conversation not in DB
|
|
81
|
+
try {
|
|
82
|
+
const brainDir = path.join(appDataDir, "brain");
|
|
83
|
+
if (fs.existsSync(brainDir)) {
|
|
84
|
+
const entries = fs.readdirSync(brainDir, { withFileTypes: true });
|
|
85
|
+
for (const entry of entries) {
|
|
86
|
+
if (!entry.isDirectory())
|
|
87
|
+
continue;
|
|
88
|
+
const convId = entry.name;
|
|
89
|
+
if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(convId)) {
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
if (results.some((r) => r.sessionId === convId))
|
|
93
|
+
continue;
|
|
94
|
+
const transcriptPath = path.join(brainDir, convId, ".system_generated", "logs", "transcript.jsonl");
|
|
95
|
+
if (fs.existsSync(transcriptPath)) {
|
|
96
|
+
const stat = fs.statSync(transcriptPath);
|
|
97
|
+
results.push({
|
|
98
|
+
sessionId: convId,
|
|
99
|
+
cwd: process.cwd(),
|
|
100
|
+
title: "Antigravity Session",
|
|
101
|
+
updatedAt: stat.mtime.toISOString(),
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
catch { }
|
|
108
|
+
return results;
|
|
109
|
+
}
|
|
110
|
+
export function getNativeAntigravitySession(conversationId) {
|
|
111
|
+
if (!conversationId)
|
|
112
|
+
return null;
|
|
113
|
+
const appDataDir = getAgyAppDataDir();
|
|
114
|
+
const dbPath = path.join(appDataDir, "conversation_summaries.db");
|
|
115
|
+
if (fs.existsSync(dbPath)) {
|
|
116
|
+
let DatabaseSync = null;
|
|
117
|
+
try {
|
|
118
|
+
DatabaseSync = require("node:sqlite")?.DatabaseSync;
|
|
119
|
+
}
|
|
120
|
+
catch { }
|
|
121
|
+
if (DatabaseSync) {
|
|
122
|
+
try {
|
|
123
|
+
const db = new DatabaseSync(dbPath, { readOnly: true });
|
|
124
|
+
const row = db
|
|
125
|
+
.prepare(`SELECT conversation_id, title, preview, last_modified_time, workspace_uris
|
|
126
|
+
FROM conversation_summaries
|
|
127
|
+
WHERE conversation_id = ?`)
|
|
128
|
+
.get(conversationId);
|
|
129
|
+
if (row) {
|
|
130
|
+
let primaryCwd = process.cwd();
|
|
131
|
+
if (row.workspace_uris) {
|
|
132
|
+
try {
|
|
133
|
+
const uris = JSON.parse(row.workspace_uris);
|
|
134
|
+
if (Array.isArray(uris) && uris.length > 0) {
|
|
135
|
+
const p = uris[0].replace(/^file:\/\//i, "");
|
|
136
|
+
if (p)
|
|
137
|
+
primaryCwd = p;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
catch { }
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
sessionId: row.conversation_id,
|
|
144
|
+
cwd: primaryCwd,
|
|
145
|
+
title: (row.title && row.title.trim()) ||
|
|
146
|
+
(row.preview && row.preview.trim()) ||
|
|
147
|
+
"Antigravity Session",
|
|
148
|
+
updatedAt: row.last_modified_time
|
|
149
|
+
? new Date(row.last_modified_time).toISOString()
|
|
150
|
+
: undefined,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
catch { }
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// Fallback check transcript file
|
|
158
|
+
const brainDir = path.join(appDataDir, "brain", conversationId);
|
|
159
|
+
const transcriptPath = path.join(brainDir, ".system_generated", "logs", "transcript.jsonl");
|
|
160
|
+
if (fs.existsSync(transcriptPath)) {
|
|
161
|
+
const stat = fs.statSync(transcriptPath);
|
|
162
|
+
return {
|
|
163
|
+
sessionId: conversationId,
|
|
164
|
+
cwd: process.cwd(),
|
|
165
|
+
title: "Antigravity Session",
|
|
166
|
+
updatedAt: stat.mtime.toISOString(),
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
return null;
|
|
170
|
+
}
|
package/dist/session.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export interface SessionOptions {
|
|
|
11
11
|
permission?: string;
|
|
12
12
|
conversationId?: string;
|
|
13
13
|
usage?: SessionUsageState;
|
|
14
|
+
updatedAt?: string;
|
|
14
15
|
sandbox?: boolean;
|
|
15
16
|
dangerouslySkipPermissions?: boolean;
|
|
16
17
|
env?: Record<string, string>;
|
|
@@ -27,6 +28,7 @@ export declare class Session {
|
|
|
27
28
|
permission: string;
|
|
28
29
|
readonly createdAt: Date;
|
|
29
30
|
lastActivity: Date;
|
|
31
|
+
updatedAt: string;
|
|
30
32
|
isCancelled: boolean;
|
|
31
33
|
process: AntigravityProcess;
|
|
32
34
|
usage: SessionUsageState;
|
package/dist/session.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import crypto from "node:crypto";
|
|
2
|
+
import fs from "node:fs";
|
|
2
3
|
import path from "node:path";
|
|
3
4
|
import { AntigravityProcess } from "./antigravity-process.js";
|
|
4
5
|
import { logger } from "./logger.js";
|
|
5
6
|
import { resolvePermissionSettings } from "./permissions.js";
|
|
6
7
|
import { calculateUsageCostUsd, getModelContextWindow } from "./protocol.js";
|
|
7
8
|
import { sessionStore, } from "./session-store.js";
|
|
9
|
+
import { resolveConversationBrainDir } from "./transcript.js";
|
|
10
|
+
import { loadNativeAntigravitySessions, getNativeAntigravitySession, } from "./native-sessions.js";
|
|
8
11
|
export class Session {
|
|
9
12
|
id;
|
|
10
13
|
cwd;
|
|
@@ -15,6 +18,7 @@ export class Session {
|
|
|
15
18
|
permission;
|
|
16
19
|
createdAt;
|
|
17
20
|
lastActivity;
|
|
21
|
+
updatedAt;
|
|
18
22
|
isCancelled = false;
|
|
19
23
|
process;
|
|
20
24
|
usage;
|
|
@@ -32,6 +36,7 @@ export class Session {
|
|
|
32
36
|
(options.sandbox ? "sandbox" : options.dangerouslySkipPermissions ? "bypass" : "default");
|
|
33
37
|
this.createdAt = new Date();
|
|
34
38
|
this.lastActivity = new Date();
|
|
39
|
+
this.updatedAt = options.updatedAt || new Date().toISOString();
|
|
35
40
|
this.store = options.store || sessionStore;
|
|
36
41
|
const maxTokens = getModelContextWindow(this.model);
|
|
37
42
|
this.usage = options.usage
|
|
@@ -82,7 +87,7 @@ export class Session {
|
|
|
82
87
|
mode: this.mode,
|
|
83
88
|
permission: this.permission,
|
|
84
89
|
usage: this.usage,
|
|
85
|
-
updatedAt:
|
|
90
|
+
updatedAt: this.updatedAt,
|
|
86
91
|
};
|
|
87
92
|
}
|
|
88
93
|
setTitle(title) {
|
|
@@ -199,10 +204,13 @@ export class Session {
|
|
|
199
204
|
}
|
|
200
205
|
}
|
|
201
206
|
this.usage.contextWindowUsedTokens = Math.min(activeContextTokens, executingMaxTokens);
|
|
207
|
+
this.lastActivity = new Date();
|
|
208
|
+
this.updatedAt = this.lastActivity.toISOString();
|
|
202
209
|
this.persist();
|
|
203
210
|
}
|
|
204
211
|
touch() {
|
|
205
212
|
this.lastActivity = new Date();
|
|
213
|
+
this.updatedAt = this.lastActivity.toISOString();
|
|
206
214
|
}
|
|
207
215
|
cancelTurn() {
|
|
208
216
|
const processCancelled = this.process.cancelCurrentTurn();
|
|
@@ -228,20 +236,26 @@ export class SessionManager {
|
|
|
228
236
|
}
|
|
229
237
|
createSession(options = {}) {
|
|
230
238
|
const persisted = options.id ? this.store.load(options.id) : null;
|
|
231
|
-
|
|
239
|
+
const native = options.id ? getNativeAntigravitySession(options.id) : null;
|
|
240
|
+
const brainDir = options.id ? resolveConversationBrainDir(options.id) : null;
|
|
241
|
+
const hasBrainDir = Boolean(brainDir && fs.existsSync(brainDir));
|
|
242
|
+
if (options.id && !persisted && !native && !hasBrainDir) {
|
|
232
243
|
throw new Error(`Cannot restore unknown ACP session: ${options.id}`);
|
|
233
244
|
}
|
|
234
245
|
const session = new Session({
|
|
235
246
|
id: options.id,
|
|
236
247
|
binaryPath: options.binaryPath || this.defaultBinaryPath,
|
|
237
|
-
cwd: options.cwd || persisted?.cwd,
|
|
238
|
-
title: options.title || persisted?.title,
|
|
248
|
+
cwd: options.cwd || persisted?.cwd || (native?.cwd ?? undefined),
|
|
249
|
+
title: options.title || persisted?.title || (native?.title ?? undefined),
|
|
239
250
|
model: options.model || persisted?.model,
|
|
240
251
|
effort: options.effort || persisted?.effort,
|
|
241
252
|
mode: options.mode || persisted?.mode,
|
|
242
253
|
permission: options.permission || persisted?.permission,
|
|
243
|
-
conversationId: options.conversationId ||
|
|
254
|
+
conversationId: options.conversationId ||
|
|
255
|
+
persisted?.conversationId ||
|
|
256
|
+
(options.id && (hasBrainDir || native) ? options.id : undefined),
|
|
244
257
|
usage: options.usage || persisted?.usage,
|
|
258
|
+
updatedAt: options.updatedAt || persisted?.updatedAt || (native?.updatedAt ?? undefined),
|
|
245
259
|
sandbox: options.sandbox,
|
|
246
260
|
dangerouslySkipPermissions: options.dangerouslySkipPermissions,
|
|
247
261
|
env: options.env,
|
|
@@ -280,16 +294,32 @@ export class SessionManager {
|
|
|
280
294
|
return Array.from(this.sessions.values());
|
|
281
295
|
}
|
|
282
296
|
listSessions(cwd) {
|
|
283
|
-
const persisted = this.store.list(cwd);
|
|
284
297
|
const sessionMap = new Map();
|
|
298
|
+
// 1. Add native Antigravity conversations
|
|
299
|
+
const nativeSessions = loadNativeAntigravitySessions(cwd);
|
|
300
|
+
const nativeByConvId = new Map();
|
|
301
|
+
for (const n of nativeSessions) {
|
|
302
|
+
nativeByConvId.set(n.sessionId, n);
|
|
303
|
+
sessionMap.set(n.sessionId, n);
|
|
304
|
+
}
|
|
305
|
+
// 2. Add persisted ACP sessions
|
|
306
|
+
const persisted = this.store.list(cwd);
|
|
285
307
|
for (const p of persisted) {
|
|
308
|
+
const nativeMatch = p.conversationId ? nativeByConvId.get(p.conversationId) : undefined;
|
|
309
|
+
const realTitle = p.title || nativeMatch?.title || (p.cwd ? path.basename(p.cwd) : "Antigravity Session");
|
|
310
|
+
const realUpdatedAt = nativeMatch?.updatedAt || p.updatedAt;
|
|
311
|
+
// If an ACP session wraps a native conversation, remove the raw native entry to prevent duplicates
|
|
312
|
+
if (p.conversationId && sessionMap.has(p.conversationId)) {
|
|
313
|
+
sessionMap.delete(p.conversationId);
|
|
314
|
+
}
|
|
286
315
|
sessionMap.set(p.sessionId, {
|
|
287
316
|
sessionId: p.sessionId,
|
|
288
317
|
cwd: p.cwd,
|
|
289
|
-
title:
|
|
290
|
-
updatedAt:
|
|
318
|
+
title: realTitle,
|
|
319
|
+
updatedAt: realUpdatedAt,
|
|
291
320
|
});
|
|
292
321
|
}
|
|
322
|
+
// 3. Active in-memory sessions
|
|
293
323
|
for (const active of this.sessions.values()) {
|
|
294
324
|
if (cwd) {
|
|
295
325
|
const targetCwd = path.resolve(cwd).toLowerCase();
|
|
@@ -297,10 +327,11 @@ export class SessionManager {
|
|
|
297
327
|
if (targetCwd !== activeCwd)
|
|
298
328
|
continue;
|
|
299
329
|
}
|
|
330
|
+
const existing = sessionMap.get(active.id);
|
|
300
331
|
sessionMap.set(active.id, {
|
|
301
332
|
sessionId: active.id,
|
|
302
333
|
cwd: active.cwd,
|
|
303
|
-
title: active.title || (active.cwd ? path.basename(active.cwd) : "Antigravity Session"),
|
|
334
|
+
title: active.title || existing?.title || (active.cwd ? path.basename(active.cwd) : "Antigravity Session"),
|
|
304
335
|
updatedAt: active.lastActivity.toISOString(),
|
|
305
336
|
});
|
|
306
337
|
}
|