@agent-link/agent 0.1.339 → 0.1.341
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/connection.d.ts +2 -1
- package/dist/connection.js +49 -21
- package/dist/connection.js.map +1 -1
- package/dist/copilot-capabilities.d.ts +1 -1
- package/dist/copilot-capabilities.js +1 -1
- package/dist/copilot-capabilities.js.map +1 -1
- package/dist/copilot-command-bridge.js +4 -0
- package/dist/copilot-command-bridge.js.map +1 -1
- package/dist/copilot-session-activity.d.ts +3 -2
- package/dist/copilot-session-activity.js +161 -70
- package/dist/copilot-session-activity.js.map +1 -1
- package/dist/copilot.d.ts +8 -0
- package/dist/copilot.js +144 -39
- package/dist/copilot.js.map +1 -1
- package/dist/file-cache.d.ts +6 -1
- package/dist/file-cache.js +62 -1
- package/dist/file-cache.js.map +1 -1
- package/dist/runtime.d.ts +1 -1
- package/dist/runtime.js +1 -1
- package/dist/runtime.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,94 +1,185 @@
|
|
|
1
1
|
import { closeSync, openSync, readSync, statSync } from 'fs';
|
|
2
|
+
import { open, stat } from 'fs/promises';
|
|
3
|
+
import { setImmediate as yieldScan } from 'timers/promises';
|
|
2
4
|
import { isCopilotChildEvent } from './copilot-event-scope.js';
|
|
3
5
|
const cache = new Map();
|
|
6
|
+
const inFlight = new Map();
|
|
7
|
+
const MAX_CACHE_ENTRIES = 10000;
|
|
8
|
+
const MAX_CACHE_BYTES = 8 * 1024 * 1024;
|
|
9
|
+
let cacheBytes = 0;
|
|
10
|
+
const entryBytes = (path) => Buffer.byteLength(path) + 192;
|
|
4
11
|
const activityTypes = new Set(['user.message', 'assistant.message', 'tool.execution_start',
|
|
5
12
|
'tool.execution_complete', 'session.task_complete']);
|
|
6
|
-
|
|
7
|
-
|
|
13
|
+
function activityState(path, stats) {
|
|
14
|
+
const state = cache.get(path);
|
|
15
|
+
if (!state || stats.size < state.size || stats.birthtimeMs !== state.birthtime || stats.ino !== state.ino
|
|
16
|
+
|| (stats.size === state.size && stats.mtimeMs !== state.mtime)) {
|
|
17
|
+
return { offset: 0, size: 0, mtime: 0, birthtime: stats.birthtimeMs, ino: stats.ino,
|
|
18
|
+
compacting: false, hasCompaction: false };
|
|
19
|
+
}
|
|
20
|
+
return { ...state };
|
|
21
|
+
}
|
|
22
|
+
function consumeEvent(state, line) {
|
|
23
|
+
let event;
|
|
24
|
+
try {
|
|
25
|
+
event = JSON.parse(line);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (!event || typeof event !== 'object')
|
|
31
|
+
return;
|
|
32
|
+
const child = isCopilotChildEvent(event);
|
|
33
|
+
const type = event.type;
|
|
34
|
+
if (type === 'session.compaction_start') {
|
|
35
|
+
state.hasCompaction = true;
|
|
36
|
+
if (!child)
|
|
37
|
+
state.compacting = true;
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (type === 'session.compaction_complete' || type === 'session.compaction_failed') {
|
|
41
|
+
state.hasCompaction = true;
|
|
42
|
+
if (!child)
|
|
43
|
+
state.compacting = false;
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const data = event.data || {};
|
|
47
|
+
if (child || (typeof data.source === 'string' && data.source.startsWith('agent-')))
|
|
48
|
+
return;
|
|
49
|
+
if (type === 'user.message') {
|
|
50
|
+
if (/^\s*\/compact(?:\s|$)/i.test(data.content || ''))
|
|
51
|
+
return;
|
|
52
|
+
state.compacting = false;
|
|
53
|
+
}
|
|
54
|
+
if (type === 'abort') {
|
|
55
|
+
state.compacting = false;
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
// A real final answer may overlap the native background compactor.
|
|
59
|
+
if ((state.compacting && !(type === 'assistant.message' && data.phase === 'final_answer'))
|
|
60
|
+
|| !activityTypes.has(type))
|
|
61
|
+
return;
|
|
62
|
+
const at = Date.parse(event.timestamp || '');
|
|
63
|
+
if (Number.isFinite(at))
|
|
64
|
+
state.lastActivity = Math.max(state.lastActivity ?? 0, at);
|
|
65
|
+
}
|
|
66
|
+
function activityReader(state) {
|
|
67
|
+
let parts = [];
|
|
68
|
+
let length = 0;
|
|
69
|
+
return (chunk) => {
|
|
70
|
+
let start = 0;
|
|
71
|
+
for (let end = chunk.indexOf(10); end >= 0; end = chunk.indexOf(10, start)) {
|
|
72
|
+
const tail = chunk.subarray(start, end);
|
|
73
|
+
const line = parts.length ? Buffer.concat([...parts, tail], length + tail.length) : tail;
|
|
74
|
+
consumeEvent(state, line.toString('utf8'));
|
|
75
|
+
state.offset += length + tail.length + 1;
|
|
76
|
+
parts = [];
|
|
77
|
+
length = 0;
|
|
78
|
+
start = end + 1;
|
|
79
|
+
}
|
|
80
|
+
if (start < chunk.length) {
|
|
81
|
+
const remaining = Buffer.from(chunk.subarray(start));
|
|
82
|
+
parts.push(remaining);
|
|
83
|
+
length += remaining.length;
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function saveActivity(path, state, stats, fallback, createdAt) {
|
|
88
|
+
state.mtime = stats.mtimeMs;
|
|
89
|
+
state.size = stats.size;
|
|
90
|
+
state.lastSort = state.hasCompaction
|
|
91
|
+
? state.lastActivity ?? createdAt ?? fallback
|
|
92
|
+
: Math.max(state.lastActivity ?? 0, fallback);
|
|
93
|
+
if (cache.delete(path))
|
|
94
|
+
cacheBytes -= entryBytes(path);
|
|
95
|
+
cache.set(path, state);
|
|
96
|
+
cacheBytes += entryBytes(path);
|
|
97
|
+
while (cache.size > MAX_CACHE_ENTRIES || cacheBytes > MAX_CACHE_BYTES) {
|
|
98
|
+
const oldest = cache.keys().next().value;
|
|
99
|
+
cache.delete(oldest);
|
|
100
|
+
cacheBytes -= entryBytes(oldest);
|
|
101
|
+
}
|
|
102
|
+
return state.lastSort;
|
|
103
|
+
}
|
|
104
|
+
function readFailure(path, fallback, error) {
|
|
105
|
+
if (error.code !== 'ENOENT') {
|
|
106
|
+
console.warn(`[Copilot] Unable to read session activity ${path}: ${String(error)}`);
|
|
107
|
+
}
|
|
108
|
+
// A temporary Provider lock must not promote maintenance over confirmed activity.
|
|
109
|
+
return cache.get(path)?.lastSort ?? fallback;
|
|
110
|
+
}
|
|
111
|
+
/** Cached state contains no journal text. An unfinished record is reread on the
|
|
112
|
+
* next request, so a large native record cannot consume the cache's memory budget. */
|
|
8
113
|
export function copilotSessionActivity(path, fallback, createdAt) {
|
|
9
114
|
let fd;
|
|
10
115
|
try {
|
|
11
116
|
const stats = statSync(path);
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|| (stats.size === state.offset && stats.mtimeMs !== state.mtime)) {
|
|
15
|
-
state = { offset: 0, partial: Buffer.alloc(0), mtime: 0, birthtime: stats.birthtimeMs,
|
|
16
|
-
compacting: false, hasCompaction: false };
|
|
17
|
-
}
|
|
117
|
+
const state = activityState(path, stats);
|
|
118
|
+
const consume = activityReader(state);
|
|
18
119
|
if (stats.size > state.offset) {
|
|
19
120
|
fd = openSync(path, 'r');
|
|
20
121
|
const chunk = Buffer.alloc(64 * 1024);
|
|
21
|
-
|
|
22
|
-
|
|
122
|
+
let position = state.offset;
|
|
123
|
+
while (position < stats.size) {
|
|
124
|
+
const read = readSync(fd, chunk, 0, Math.min(chunk.length, stats.size - position), position);
|
|
23
125
|
if (!read)
|
|
24
126
|
break;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
let start = 0;
|
|
28
|
-
for (let end = bytes.indexOf(10); end >= 0; end = bytes.indexOf(10, start)) {
|
|
29
|
-
const line = bytes.subarray(start, end).toString('utf8');
|
|
30
|
-
start = end + 1;
|
|
31
|
-
try {
|
|
32
|
-
const event = JSON.parse(line);
|
|
33
|
-
const child = isCopilotChildEvent(event);
|
|
34
|
-
const type = event.type;
|
|
35
|
-
if (type === 'session.compaction_start') {
|
|
36
|
-
state.hasCompaction = true;
|
|
37
|
-
if (!child)
|
|
38
|
-
state.compacting = true;
|
|
39
|
-
continue;
|
|
40
|
-
}
|
|
41
|
-
if (type === 'session.compaction_complete' || type === 'session.compaction_failed') {
|
|
42
|
-
state.hasCompaction = true;
|
|
43
|
-
if (!child)
|
|
44
|
-
state.compacting = false;
|
|
45
|
-
continue;
|
|
46
|
-
}
|
|
47
|
-
// A new real request also bounds an abandoned compression after restart.
|
|
48
|
-
const data = event.data || {};
|
|
49
|
-
if (child || (typeof data.source === 'string' && data.source.startsWith('agent-')))
|
|
50
|
-
continue;
|
|
51
|
-
if (type === 'user.message') {
|
|
52
|
-
if (/^\s*\/compact(?:\s|$)/i.test(data.content || ''))
|
|
53
|
-
continue;
|
|
54
|
-
state.compacting = false;
|
|
55
|
-
}
|
|
56
|
-
if (type === 'abort') {
|
|
57
|
-
state.compacting = false;
|
|
58
|
-
continue;
|
|
59
|
-
}
|
|
60
|
-
// A native background compactor can overlap the real final answer.
|
|
61
|
-
// That explicitly identified answer is activity, not maintenance.
|
|
62
|
-
if ((state.compacting && !(type === 'assistant.message' && data.phase === 'final_answer'))
|
|
63
|
-
|| !activityTypes.has(type))
|
|
64
|
-
continue;
|
|
65
|
-
const at = Date.parse(event.timestamp || '');
|
|
66
|
-
if (Number.isFinite(at))
|
|
67
|
-
state.lastActivity = Math.max(state.lastActivity ?? 0, at);
|
|
68
|
-
}
|
|
69
|
-
catch { /* Ignore incomplete/legacy native records, never rewrite them. */ }
|
|
70
|
-
}
|
|
71
|
-
state.partial = Buffer.from(bytes.subarray(start));
|
|
127
|
+
position += read;
|
|
128
|
+
consume(chunk.subarray(0, read));
|
|
72
129
|
}
|
|
73
130
|
}
|
|
74
|
-
state
|
|
75
|
-
state.lastSort = state.hasCompaction
|
|
76
|
-
? state.lastActivity ?? createdAt ?? fallback
|
|
77
|
-
: Math.max(state.lastActivity ?? 0, fallback);
|
|
78
|
-
cache.delete(path);
|
|
79
|
-
cache.set(path, state);
|
|
80
|
-
if (cache.size > 256)
|
|
81
|
-
cache.delete(cache.keys().next().value);
|
|
82
|
-
return state.lastSort;
|
|
131
|
+
return saveActivity(path, state, stats, fallback, createdAt);
|
|
83
132
|
}
|
|
84
|
-
catch {
|
|
85
|
-
|
|
86
|
-
// activity with the newer maintenance timestamp.
|
|
87
|
-
return cache.get(path)?.lastSort ?? fallback;
|
|
133
|
+
catch (error) {
|
|
134
|
+
return readFailure(path, fallback, error);
|
|
88
135
|
}
|
|
89
136
|
finally {
|
|
90
137
|
if (fd != null)
|
|
91
138
|
closeSync(fd);
|
|
92
139
|
}
|
|
93
140
|
}
|
|
141
|
+
export async function copilotSessionActivityAsync(path, fallback, createdAt) {
|
|
142
|
+
// Serialize a journal's readers without mixing their metadata fallbacks.
|
|
143
|
+
const previous = inFlight.get(path);
|
|
144
|
+
const reading = previous
|
|
145
|
+
? previous.then(() => readActivityAsync(path, fallback, createdAt))
|
|
146
|
+
: readActivityAsync(path, fallback, createdAt);
|
|
147
|
+
inFlight.set(path, reading);
|
|
148
|
+
try {
|
|
149
|
+
return await reading;
|
|
150
|
+
}
|
|
151
|
+
finally {
|
|
152
|
+
if (inFlight.get(path) === reading)
|
|
153
|
+
inFlight.delete(path);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
async function readActivityAsync(path, fallback, createdAt) {
|
|
157
|
+
try {
|
|
158
|
+
const stats = await stat(path);
|
|
159
|
+
const state = activityState(path, stats);
|
|
160
|
+
const consume = activityReader(state);
|
|
161
|
+
if (stats.size > state.offset) {
|
|
162
|
+
const file = await open(path, 'r');
|
|
163
|
+
try {
|
|
164
|
+
const chunk = Buffer.alloc(64 * 1024);
|
|
165
|
+
let position = state.offset;
|
|
166
|
+
while (position < stats.size) {
|
|
167
|
+
const { bytesRead } = await file.read(chunk, 0, Math.min(chunk.length, stats.size - position), position);
|
|
168
|
+
if (!bytesRead)
|
|
169
|
+
break;
|
|
170
|
+
position += bytesRead;
|
|
171
|
+
consume(chunk.subarray(0, bytesRead));
|
|
172
|
+
await yieldScan();
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
finally {
|
|
176
|
+
await file.close();
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return saveActivity(path, state, stats, fallback, createdAt);
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
return readFailure(path, fallback, error);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
94
185
|
//# sourceMappingURL=copilot-session-activity.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"copilot-session-activity.js","sourceRoot":"","sources":["../src/copilot-session-activity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"copilot-session-activity.js","sourceRoot":"","sources":["../src/copilot-session-activity.ts"],"names":[],"mappings":"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"}
|
package/dist/copilot.d.ts
CHANGED
|
@@ -280,6 +280,10 @@ interface CopilotGlobalSessionPage {
|
|
|
280
280
|
nextCursor?: string;
|
|
281
281
|
indexState: 'ready';
|
|
282
282
|
}
|
|
283
|
+
export declare function listCopilotSessionsPageAsync(workDir: string, options?: {
|
|
284
|
+
limit?: number;
|
|
285
|
+
cursor?: string;
|
|
286
|
+
}): Promise<CopilotSessionPage>;
|
|
283
287
|
export declare function listCopilotSessions(workDir: string, options?: {
|
|
284
288
|
strictReadErrors?: boolean;
|
|
285
289
|
}): SessionInfo[];
|
|
@@ -309,6 +313,10 @@ export declare function listAllCopilotSessionsPage(options?: {
|
|
|
309
313
|
limit?: number;
|
|
310
314
|
cursor?: string;
|
|
311
315
|
}): CopilotGlobalSessionPage;
|
|
316
|
+
export declare function listAllCopilotSessionsPageAsync(options?: {
|
|
317
|
+
limit?: number;
|
|
318
|
+
cursor?: string;
|
|
319
|
+
}): Promise<CopilotGlobalSessionPage>;
|
|
312
320
|
export declare function renameCopilotSession(_workDir: string, sessionId: string, newTitle: string): boolean;
|
|
313
321
|
export declare function moveCopilotSession(_fromWorkDir: string, toWorkDir: string, sessionId: string): boolean;
|
|
314
322
|
export declare function deleteCopilotSession(_workDir: string, sessionId: string): Promise<boolean>;
|
package/dist/copilot.js
CHANGED
|
@@ -9,7 +9,9 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { spawn } from 'child_process';
|
|
11
11
|
import { createInterface } from 'readline';
|
|
12
|
-
import { closeSync, existsSync, mkdirSync, openSync, readFileSync, readSync, readdirSync, rmSync, statSync, writeFileSync } from 'fs';
|
|
12
|
+
import { closeSync, createReadStream, existsSync, mkdirSync, openSync, readFileSync, readSync, readdirSync, rmSync, statSync, writeFileSync } from 'fs';
|
|
13
|
+
import { readFile, readdir } from 'fs/promises';
|
|
14
|
+
import { setImmediate as yieldSessionScan } from 'timers/promises';
|
|
13
15
|
import { atomicWriteCopilotSidecar } from './copilot-sidecar.js';
|
|
14
16
|
import { basename, dirname, extname, join, resolve } from 'path';
|
|
15
17
|
import { homedir, platform } from 'os';
|
|
@@ -21,7 +23,7 @@ import { readCopilotUserRequests, saveCopilotUserRequest, mergeCopilotUserReques
|
|
|
21
23
|
import { copilotChildScope, copilotParentToolCallId, isCopilotChildEvent } from './copilot-event-scope.js';
|
|
22
24
|
import { CopilotCompactionBarrier, compactionFencePath, readCompactionFences, compactionPublicationHidden } from './copilot-compaction-barrier.js';
|
|
23
25
|
import { CopilotCompactionLifecycle } from './copilot-compaction-lifecycle.js';
|
|
24
|
-
import { copilotSessionActivity } from './copilot-session-activity.js';
|
|
26
|
+
import { copilotSessionActivity, copilotSessionActivityAsync } from './copilot-session-activity.js';
|
|
25
27
|
import { copilotPlanStateAllowsImplementation, stripCopilotPlanControl, readCopilotPlanRevision, findRecoverableCopilotPlan, sealCopilotPlanState, holdsRecoveredCopilotPlanMode, clearRecoveredCopilotPlanMode } from './copilot-plan-state.js';
|
|
26
28
|
import * as acp from '@agentclientprotocol/sdk';
|
|
27
29
|
import { getForkHistoryTitle, processUserMessage } from './history-message-transform.js';
|
|
@@ -4604,8 +4606,8 @@ function hasCopilotForkOrigin(sessionId) {
|
|
|
4604
4606
|
}
|
|
4605
4607
|
return false;
|
|
4606
4608
|
}
|
|
4607
|
-
function
|
|
4608
|
-
const yaml = parseSimpleYaml(
|
|
4609
|
+
function copilotWorkspaceMetadata(filePath, content) {
|
|
4610
|
+
const yaml = parseSimpleYaml(content);
|
|
4609
4611
|
const sourceDir = filePath.replace(/\\/g, '/').split('/').slice(-2, -1)[0] || '';
|
|
4610
4612
|
const cwd = yaml.cwd || '';
|
|
4611
4613
|
const updatedAt = yaml.updated_at ? new Date(yaml.updated_at).getTime() : 0;
|
|
@@ -4627,45 +4629,14 @@ function parseCopilotWorkspaceYaml(filePath, stats) {
|
|
|
4627
4629
|
console.warn(`[Copilot] Fork numbering unavailable for ${sessionId}: ${String(error)}`);
|
|
4628
4630
|
}
|
|
4629
4631
|
}
|
|
4630
|
-
|
|
4632
|
+
const recoverTitle = title.includes(AGENCY_LONG_CONTEXT_BOOTSTRAP_MARKER) || forkTitle !== null;
|
|
4633
|
+
if (recoverTitle)
|
|
4631
4634
|
title = forkTitle || (forkTitle !== null ? 'Forked conversation' : 'Untitled');
|
|
4632
|
-
|
|
4633
|
-
if (existsSync(eventsPath)) {
|
|
4634
|
-
try {
|
|
4635
|
-
for (const line of readFileSync(eventsPath, 'utf8').split(/\r?\n/)) {
|
|
4636
|
-
if (!line.trim())
|
|
4637
|
-
continue;
|
|
4638
|
-
let event;
|
|
4639
|
-
try {
|
|
4640
|
-
event = JSON.parse(line);
|
|
4641
|
-
}
|
|
4642
|
-
catch {
|
|
4643
|
-
continue;
|
|
4644
|
-
}
|
|
4645
|
-
if (event.parentToolCallId || event.data?.parentToolCallId || event.data?.source?.startsWith('agent-'))
|
|
4646
|
-
continue;
|
|
4647
|
-
const content = event.type === 'user.message' && typeof event.data?.content === 'string'
|
|
4648
|
-
? stripAgencyPlanInteractionGuidance(event.data.content).trim()
|
|
4649
|
-
: '';
|
|
4650
|
-
if (!content || content.includes(AGENCY_LONG_CONTEXT_BOOTSTRAP_MARKER))
|
|
4651
|
-
continue;
|
|
4652
|
-
const recoveredForkTitle = getForkHistoryTitle(content);
|
|
4653
|
-
if (recoveredForkTitle === '')
|
|
4654
|
-
continue;
|
|
4655
|
-
title = recoveredForkTitle ?? content;
|
|
4656
|
-
break;
|
|
4657
|
-
}
|
|
4658
|
-
}
|
|
4659
|
-
catch {
|
|
4660
|
-
// Keep the hidden initializer untitled until Provider history is readable.
|
|
4661
|
-
}
|
|
4662
|
-
}
|
|
4663
|
-
}
|
|
4664
|
-
return {
|
|
4635
|
+
const session = {
|
|
4665
4636
|
sessionId,
|
|
4666
4637
|
title,
|
|
4667
4638
|
preview: title.length > 60 ? title.substring(0, 60) + '...' : title,
|
|
4668
|
-
lastModified:
|
|
4639
|
+
lastModified: updatedAt,
|
|
4669
4640
|
projectPath: cwd,
|
|
4670
4641
|
projectFolder: folderName,
|
|
4671
4642
|
sourcePath: filePath,
|
|
@@ -4674,10 +4645,88 @@ function parseCopilotWorkspaceYaml(filePath, stats) {
|
|
|
4674
4645
|
...(forkMetadata ? { forkNumber: forkMetadata.number,
|
|
4675
4646
|
...(forkMetadata.sourceSessionId ? { forkSourceSessionId: forkMetadata.sourceSessionId } : {}) } : {}),
|
|
4676
4647
|
};
|
|
4648
|
+
return { session, recoverTitle, createdAt: yaml.created_at ? Date.parse(yaml.created_at) || undefined : undefined };
|
|
4649
|
+
}
|
|
4650
|
+
function copilotWorkspaceTitle(line) {
|
|
4651
|
+
if (!line.trim())
|
|
4652
|
+
return;
|
|
4653
|
+
let event;
|
|
4654
|
+
try {
|
|
4655
|
+
event = JSON.parse(line);
|
|
4656
|
+
}
|
|
4657
|
+
catch {
|
|
4658
|
+
return;
|
|
4659
|
+
}
|
|
4660
|
+
if (!event || typeof event !== 'object')
|
|
4661
|
+
return;
|
|
4662
|
+
if (event.parentToolCallId || event.data?.parentToolCallId || event.data?.source?.startsWith('agent-'))
|
|
4663
|
+
return;
|
|
4664
|
+
const content = event.type === 'user.message' && typeof event.data?.content === 'string'
|
|
4665
|
+
? stripAgencyPlanInteractionGuidance(event.data.content).trim() : '';
|
|
4666
|
+
if (!content || content.includes(AGENCY_LONG_CONTEXT_BOOTSTRAP_MARKER))
|
|
4667
|
+
return;
|
|
4668
|
+
const forkTitle = getForkHistoryTitle(content);
|
|
4669
|
+
return forkTitle === '' ? undefined : forkTitle ?? content;
|
|
4670
|
+
}
|
|
4671
|
+
function parseCopilotWorkspaceYaml(filePath, stats) {
|
|
4672
|
+
const { session, recoverTitle, createdAt } = copilotWorkspaceMetadata(filePath, readFileSync(filePath, 'utf8'));
|
|
4673
|
+
const eventsPath = join(dirname(filePath), 'events.jsonl');
|
|
4674
|
+
if (recoverTitle && existsSync(eventsPath)) {
|
|
4675
|
+
try {
|
|
4676
|
+
for (const line of readFileSync(eventsPath, 'utf8').split(/\r?\n/)) {
|
|
4677
|
+
const title = copilotWorkspaceTitle(line);
|
|
4678
|
+
if (title !== undefined) {
|
|
4679
|
+
session.title = title;
|
|
4680
|
+
break;
|
|
4681
|
+
}
|
|
4682
|
+
}
|
|
4683
|
+
}
|
|
4684
|
+
catch (error) {
|
|
4685
|
+
console.warn(`[Copilot] Unable to recover session title ${filePath}: ${String(error)}`);
|
|
4686
|
+
}
|
|
4687
|
+
}
|
|
4688
|
+
session.preview = session.title.length > 60 ? session.title.substring(0, 60) + '...' : session.title;
|
|
4689
|
+
session.lastModified = copilotSessionActivity(eventsPath, session.lastModified || stats.mtimeMs, createdAt);
|
|
4690
|
+
return session;
|
|
4691
|
+
}
|
|
4692
|
+
async function parseCopilotWorkspaceYamlAsync(filePath, stats) {
|
|
4693
|
+
const { session, recoverTitle, createdAt } = copilotWorkspaceMetadata(filePath, await readFile(filePath, 'utf8'));
|
|
4694
|
+
const eventsPath = join(dirname(filePath), 'events.jsonl');
|
|
4695
|
+
if (recoverTitle) {
|
|
4696
|
+
const input = createReadStream(eventsPath, { encoding: 'utf8', highWaterMark: 64 * 1024 });
|
|
4697
|
+
const lines = createInterface({ input, crlfDelay: Infinity });
|
|
4698
|
+
try {
|
|
4699
|
+
let lastYield = performance.now();
|
|
4700
|
+
for await (const line of lines) {
|
|
4701
|
+
const title = copilotWorkspaceTitle(line);
|
|
4702
|
+
if (title !== undefined) {
|
|
4703
|
+
session.title = title;
|
|
4704
|
+
break;
|
|
4705
|
+
}
|
|
4706
|
+
if (performance.now() - lastYield >= 8) {
|
|
4707
|
+
await yieldSessionScan();
|
|
4708
|
+
lastYield = performance.now();
|
|
4709
|
+
}
|
|
4710
|
+
}
|
|
4711
|
+
}
|
|
4712
|
+
catch (error) {
|
|
4713
|
+
if (error.code !== 'ENOENT') {
|
|
4714
|
+
console.warn(`[Copilot] Unable to recover session title ${filePath}: ${String(error)}`);
|
|
4715
|
+
}
|
|
4716
|
+
}
|
|
4717
|
+
finally {
|
|
4718
|
+
lines.close();
|
|
4719
|
+
input.destroy();
|
|
4720
|
+
}
|
|
4721
|
+
}
|
|
4722
|
+
session.preview = session.title.length > 60 ? session.title.substring(0, 60) + '...' : session.title;
|
|
4723
|
+
session.lastModified = await copilotSessionActivityAsync(eventsPath, session.lastModified || stats.mtimeMs, createdAt);
|
|
4724
|
+
return session;
|
|
4677
4725
|
}
|
|
4678
4726
|
const copilotWorkspaceCache = new FileCache({
|
|
4679
4727
|
name: 'copilot-workspace',
|
|
4680
4728
|
compute: parseCopilotWorkspaceYaml,
|
|
4729
|
+
computeAsync: parseCopilotWorkspaceYamlAsync,
|
|
4681
4730
|
maxEntries: 10000,
|
|
4682
4731
|
ttlMs: 0,
|
|
4683
4732
|
debug: false,
|
|
@@ -4755,11 +4804,61 @@ function getCopilotSessionEntries(workDir, strictReadErrors = false) {
|
|
|
4755
4804
|
entries.sort((a, b) => compareCursorSortKeys(a.sortKey, b.sortKey));
|
|
4756
4805
|
return entries;
|
|
4757
4806
|
}
|
|
4807
|
+
async function getCopilotSessionEntriesAsync(workDir) {
|
|
4808
|
+
const normalizedWorkDir = workDir ? normalizeCursorPath(workDir) : '';
|
|
4809
|
+
const entries = [];
|
|
4810
|
+
let dirs;
|
|
4811
|
+
try {
|
|
4812
|
+
dirs = await readdir(COPILOT_SESSION_DIR, { withFileTypes: true });
|
|
4813
|
+
}
|
|
4814
|
+
catch (error) {
|
|
4815
|
+
if (error.code === 'ENOENT')
|
|
4816
|
+
return entries;
|
|
4817
|
+
throw error;
|
|
4818
|
+
}
|
|
4819
|
+
for (const dir of dirs) {
|
|
4820
|
+
if (!dir.isDirectory())
|
|
4821
|
+
continue;
|
|
4822
|
+
const wsPath = join(COPILOT_SESSION_DIR, dir.name, 'workspace.yaml');
|
|
4823
|
+
const parsed = await copilotWorkspaceCache.getAsync(wsPath);
|
|
4824
|
+
if (!parsed)
|
|
4825
|
+
continue;
|
|
4826
|
+
if (workDir !== undefined && (!parsed.projectPath || normalizeCursorPath(parsed.projectPath) !== normalizedWorkDir))
|
|
4827
|
+
continue;
|
|
4828
|
+
const lastModified = await copilotSessionActivityAsync(join(dirname(wsPath), 'events.jsonl'), parsed.lastModified);
|
|
4829
|
+
entries.push({ session: { ...parsed, lastModified }, sortKey: {
|
|
4830
|
+
lastModified, sessionId: parsed.sessionId, tieBreaker: normalizeCursorPath(wsPath),
|
|
4831
|
+
} });
|
|
4832
|
+
await yieldSessionScan();
|
|
4833
|
+
}
|
|
4834
|
+
entries.sort((a, b) => compareCursorSortKeys(a.sortKey, b.sortKey));
|
|
4835
|
+
return entries;
|
|
4836
|
+
}
|
|
4837
|
+
const inFlightCopilotPages = new Map();
|
|
4838
|
+
const inFlightGlobalCopilotPages = new Map();
|
|
4839
|
+
async function copilotPageAsync(pendingPages, workDir, options, paginate) {
|
|
4840
|
+
const key = JSON.stringify([workDir === undefined ? null : normalizeCursorPath(workDir), normalizeSessionLimit(options.limit), options.cursor || '']);
|
|
4841
|
+
let pending = pendingPages.get(key);
|
|
4842
|
+
if (!pending) {
|
|
4843
|
+
pending = getCopilotSessionEntriesAsync(workDir).then(paginate);
|
|
4844
|
+
pendingPages.set(key, pending);
|
|
4845
|
+
const release = () => { if (pendingPages.get(key) === pending)
|
|
4846
|
+
pendingPages.delete(key); };
|
|
4847
|
+
pending.then(release, release);
|
|
4848
|
+
}
|
|
4849
|
+
return structuredClone(await pending);
|
|
4850
|
+
}
|
|
4851
|
+
export function listCopilotSessionsPageAsync(workDir, options = {}) {
|
|
4852
|
+
return copilotPageAsync(inFlightCopilotPages, workDir, options, entries => copilotSessionsPage(entries, workDir, options));
|
|
4853
|
+
}
|
|
4758
4854
|
export function listCopilotSessions(workDir, options = {}) {
|
|
4759
4855
|
return listCopilotSessionsPage(workDir, { ...options, limit: Number.POSITIVE_INFINITY }).sessions;
|
|
4760
4856
|
}
|
|
4761
4857
|
export function listCopilotSessionsPage(workDir, options = {}) {
|
|
4762
4858
|
const entries = getCopilotSessionEntries(workDir, options.strictReadErrors);
|
|
4859
|
+
return copilotSessionsPage(entries, workDir, options);
|
|
4860
|
+
}
|
|
4861
|
+
function copilotSessionsPage(entries, workDir, options) {
|
|
4763
4862
|
const limit = normalizeSessionLimit(options.limit);
|
|
4764
4863
|
let startIndex = 0;
|
|
4765
4864
|
if (options.cursor) {
|
|
@@ -5811,6 +5910,12 @@ export function listAllCopilotSessions(limit = 500) {
|
|
|
5811
5910
|
}
|
|
5812
5911
|
export function listAllCopilotSessionsPage(options = {}) {
|
|
5813
5912
|
const entries = getCopilotSessionEntries();
|
|
5913
|
+
return allCopilotSessionsPage(entries, options);
|
|
5914
|
+
}
|
|
5915
|
+
export function listAllCopilotSessionsPageAsync(options = {}) {
|
|
5916
|
+
return copilotPageAsync(inFlightGlobalCopilotPages, undefined, options, entries => allCopilotSessionsPage(entries, options));
|
|
5917
|
+
}
|
|
5918
|
+
function allCopilotSessionsPage(entries, options) {
|
|
5814
5919
|
const limit = normalizeSessionLimit(options.limit);
|
|
5815
5920
|
let startIndex = 0;
|
|
5816
5921
|
if (options.cursor) {
|