@agent-link/agent 0.1.338 → 0.1.339
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/backends/types.d.ts +58 -0
- package/dist/backends/types.js +15 -4
- package/dist/backends/types.js.map +1 -1
- package/dist/connection.js +231 -28
- package/dist/connection.js.map +1 -1
- package/dist/copilot-capabilities-offline.d.ts +254 -0
- package/dist/copilot-capabilities-offline.js +392 -0
- package/dist/copilot-capabilities-offline.js.map +1 -0
- package/dist/copilot-capabilities.d.ts +43 -0
- package/dist/copilot-capabilities.js +128 -0
- package/dist/copilot-capabilities.js.map +1 -0
- package/dist/copilot-capability-service.d.ts +24 -0
- package/dist/copilot-capability-service.js +116 -0
- package/dist/copilot-capability-service.js.map +1 -0
- package/dist/copilot-command-bridge.d.ts +184 -0
- package/dist/copilot-command-bridge.js +1800 -0
- package/dist/copilot-command-bridge.js.map +1 -0
- package/dist/copilot-compaction-barrier.d.ts +36 -0
- package/dist/copilot-compaction-barrier.js +152 -0
- package/dist/copilot-compaction-barrier.js.map +1 -0
- package/dist/copilot-compaction-lifecycle.d.ts +34 -0
- package/dist/copilot-compaction-lifecycle.js +88 -0
- package/dist/copilot-compaction-lifecycle.js.map +1 -0
- package/dist/copilot-compaction-policy.d.ts +5 -0
- package/dist/copilot-compaction-policy.js +7 -0
- package/dist/copilot-compaction-policy.js.map +1 -0
- package/dist/copilot-configuration.d.ts +63 -0
- package/dist/copilot-configuration.js +283 -0
- package/dist/copilot-configuration.js.map +1 -0
- package/dist/copilot-event-scope.d.ts +13 -0
- package/dist/copilot-event-scope.js +26 -0
- package/dist/copilot-event-scope.js.map +1 -0
- package/dist/copilot-fork-metadata.d.ts +9 -0
- package/dist/copilot-fork-metadata.js +86 -0
- package/dist/copilot-fork-metadata.js.map +1 -0
- package/dist/copilot-message-kind.d.ts +21 -0
- package/dist/copilot-message-kind.js +45 -0
- package/dist/copilot-message-kind.js.map +1 -0
- package/dist/copilot-plan-state.d.ts +19 -0
- package/dist/copilot-plan-state.js +180 -0
- package/dist/copilot-plan-state.js.map +1 -0
- package/dist/copilot-request-dispatch.d.ts +10 -0
- package/dist/copilot-request-dispatch.js +31 -0
- package/dist/copilot-request-dispatch.js.map +1 -0
- package/dist/copilot-review-documents.d.ts +17 -0
- package/dist/copilot-review-documents.js +162 -0
- package/dist/copilot-review-documents.js.map +1 -0
- package/dist/copilot-session-activity.d.ts +3 -0
- package/dist/copilot-session-activity.js +94 -0
- package/dist/copilot-session-activity.js.map +1 -0
- package/dist/copilot-sidecar.d.ts +2 -0
- package/dist/copilot-sidecar.js +17 -0
- package/dist/copilot-sidecar.js.map +1 -0
- package/dist/copilot-turn-journal.d.ts +36 -0
- package/dist/copilot-turn-journal.js +246 -0
- package/dist/copilot-turn-journal.js.map +1 -0
- package/dist/copilot-user-requests.d.ts +11 -0
- package/dist/copilot-user-requests.js +84 -0
- package/dist/copilot-user-requests.js.map +1 -0
- package/dist/copilot.d.ts +194 -9
- package/dist/copilot.js +5012 -240
- package/dist/copilot.js.map +1 -1
- package/dist/history-message-transform.d.ts +47 -1
- package/dist/history-message-transform.js +67 -0
- package/dist/history-message-transform.js.map +1 -1
- package/dist/history.d.ts +8 -0
- package/dist/history.js.map +1 -1
- package/dist/provider-command-discovery.d.ts +5 -0
- package/dist/provider-command-discovery.js +49 -1
- package/dist/provider-command-discovery.js.map +1 -1
- package/dist/provider-command-types.d.ts +5 -0
- package/dist/provider-command-types.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/dist/search-sessions.js +2 -1
- package/dist/search-sessions.js.map +1 -1
- package/package.json +3 -1
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { createHash, randomUUID } from 'crypto';
|
|
2
|
+
import { existsSync, readFileSync, statSync } from 'fs';
|
|
3
|
+
import { atomicWriteCopilotSidecar } from './copilot-sidecar.js';
|
|
4
|
+
import { join, resolve, sep } from 'path';
|
|
5
|
+
import { isCopilotChildEvent } from './copilot-event-scope.js';
|
|
6
|
+
export const COPILOT_PLAN_STATE_FILE = '.agentlink-plan-state.json';
|
|
7
|
+
const OPEN = '<agentlink_plan_control>';
|
|
8
|
+
const CLOSE = '</agentlink_plan_control>';
|
|
9
|
+
function statePath(root, sessionId) {
|
|
10
|
+
const base = resolve(root);
|
|
11
|
+
const session = resolve(base, sessionId);
|
|
12
|
+
if (session === base || !session.startsWith(base + sep))
|
|
13
|
+
throw new Error('Invalid Plan session');
|
|
14
|
+
return join(session, COPILOT_PLAN_STATE_FILE);
|
|
15
|
+
}
|
|
16
|
+
export function beginCopilotPlanState(root, sessionId) {
|
|
17
|
+
const path = statePath(root, sessionId);
|
|
18
|
+
const revision = randomUUID();
|
|
19
|
+
// Only existing Provider Session directories are writable; discovery never
|
|
20
|
+
// creates a directory as a side effect of this internal metadata mechanism.
|
|
21
|
+
if (existsSync(join(root, sessionId))) {
|
|
22
|
+
atomicWriteCopilotSidecar(path, JSON.stringify({ version: 1, revision, status: 'awaiting_input' }), 'utf8');
|
|
23
|
+
}
|
|
24
|
+
return revision;
|
|
25
|
+
}
|
|
26
|
+
export function readCopilotPlanState(root, sessionId, revision) {
|
|
27
|
+
try {
|
|
28
|
+
const value = JSON.parse(readFileSync(statePath(root, sessionId), 'utf8'));
|
|
29
|
+
return value.version === 1 && value.revision === revision
|
|
30
|
+
&& (value.status === 'ready' || value.status === 'awaiting_input') ? value.status : null;
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export function readCopilotPlanRevision(root, sessionId) {
|
|
37
|
+
try {
|
|
38
|
+
const value = JSON.parse(readFileSync(statePath(root, sessionId), 'utf8'));
|
|
39
|
+
return value.version === 1 && typeof value.revision === 'string' && value.revision ? value.revision : null;
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/** Recover only the latest completed main Plan, never a draft or a child artifact. */
|
|
46
|
+
export function findRecoverableCopilotPlan(root, sessionId) {
|
|
47
|
+
try {
|
|
48
|
+
const declarationPath = statePath(root, sessionId);
|
|
49
|
+
const declaration = JSON.parse(readFileSync(declarationPath, 'utf8'));
|
|
50
|
+
if (declaration.version !== 1 || declaration.status !== 'ready'
|
|
51
|
+
|| typeof declaration.revision !== 'string' || !declaration.revision)
|
|
52
|
+
return null;
|
|
53
|
+
const dir = join(root, sessionId);
|
|
54
|
+
const planPath = join(dir, 'plan.md');
|
|
55
|
+
const content = readFileSync(planPath, 'utf8').trim();
|
|
56
|
+
if (!content || stripCopilotPlanControl(content) !== content)
|
|
57
|
+
return null;
|
|
58
|
+
let mode = 'interactive';
|
|
59
|
+
let requestAt = NaN;
|
|
60
|
+
let exitSucceeded = false;
|
|
61
|
+
let failed = false;
|
|
62
|
+
let boundary;
|
|
63
|
+
const exitCalls = new Set();
|
|
64
|
+
for (const line of readFileSync(join(dir, 'events.jsonl'), 'utf8').split('\n')) {
|
|
65
|
+
if (!line.trim())
|
|
66
|
+
continue;
|
|
67
|
+
const event = JSON.parse(line);
|
|
68
|
+
if (isCopilotChildEvent(event))
|
|
69
|
+
continue;
|
|
70
|
+
const data = event.data || {};
|
|
71
|
+
if (event.type === 'user.message') {
|
|
72
|
+
// A later real request invalidates recovery, even if it has not ended.
|
|
73
|
+
requestAt = Date.parse(event.timestamp || '');
|
|
74
|
+
exitSucceeded = false;
|
|
75
|
+
failed = false;
|
|
76
|
+
boundary = undefined;
|
|
77
|
+
exitCalls.clear();
|
|
78
|
+
}
|
|
79
|
+
if (event.type === 'session.mode_changed')
|
|
80
|
+
mode = data.newMode;
|
|
81
|
+
if (mode === 'plan' && event.type === 'assistant.message') {
|
|
82
|
+
for (const tool of data.toolRequests || []) {
|
|
83
|
+
if (tool.name === 'exit_plan_mode' && typeof tool.toolCallId === 'string' && tool.toolCallId)
|
|
84
|
+
exitCalls.add(tool.toolCallId);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (mode === 'plan' && event.type === 'tool.execution_start' && data.toolName === 'exit_plan_mode'
|
|
88
|
+
&& typeof data.toolCallId === 'string' && data.toolCallId)
|
|
89
|
+
exitCalls.add(data.toolCallId);
|
|
90
|
+
if (event.type === 'tool.execution_complete' && exitCalls.has(data.toolCallId))
|
|
91
|
+
exitSucceeded = data.success === true;
|
|
92
|
+
if (event.type === 'abort' || event.type === 'session.error' || event.type === 'session.compaction_failed'
|
|
93
|
+
|| (event.type === 'session.compaction_complete' && data.success === false))
|
|
94
|
+
failed = true;
|
|
95
|
+
if (exitSucceeded && event.type === 'assistant.turn_end' && typeof event.id === 'string') {
|
|
96
|
+
boundary = { id: event.id, at: Date.parse(event.timestamp || ''), turnId: data.turnId };
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (!boundary || failed || !exitSucceeded || !Number.isFinite(requestAt) || !Number.isFinite(boundary.at))
|
|
100
|
+
return null;
|
|
101
|
+
const writtenAt = statSync(planPath).mtimeMs;
|
|
102
|
+
const declaredAt = statSync(declarationPath).mtimeMs;
|
|
103
|
+
// The current file must belong to that user request and predate its finish.
|
|
104
|
+
// A later edited artifact or a leftover old file must never become ready.
|
|
105
|
+
const sealed = declaration.planHash === createHash('sha256').update(content).digest('hex');
|
|
106
|
+
if (writtenAt < requestAt || writtenAt > boundary.at
|
|
107
|
+
|| (!sealed && (declaredAt < requestAt || declaredAt > boundary.at)))
|
|
108
|
+
return null;
|
|
109
|
+
return { content, revision: declaration.revision, boundaryEventId: boundary.id, ...(boundary.turnId ? { turnId: boundary.turnId } : {}) };
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
export function sealCopilotPlanState(root, sessionId, revision, plan, holdPlanMode = false) {
|
|
116
|
+
const path = statePath(root, sessionId);
|
|
117
|
+
if (!existsSync(join(root, sessionId)))
|
|
118
|
+
return;
|
|
119
|
+
atomicWriteCopilotSidecar(path, JSON.stringify({
|
|
120
|
+
version: 1, revision, status: 'ready', planHash: createHash('sha256').update(plan).digest('hex'),
|
|
121
|
+
...(holdPlanMode ? { holdPlanMode: true } : {}),
|
|
122
|
+
}), 'utf8');
|
|
123
|
+
}
|
|
124
|
+
export function holdsRecoveredCopilotPlanMode(root, sessionId) {
|
|
125
|
+
try {
|
|
126
|
+
return JSON.parse(readFileSync(statePath(root, sessionId), 'utf8')).holdPlanMode === true;
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
export function clearRecoveredCopilotPlanMode(root, sessionId) {
|
|
133
|
+
if (!holdsRecoveredCopilotPlanMode(root, sessionId))
|
|
134
|
+
return;
|
|
135
|
+
const path = statePath(root, sessionId);
|
|
136
|
+
const value = JSON.parse(readFileSync(path, 'utf8'));
|
|
137
|
+
atomicWriteCopilotSidecar(path, JSON.stringify({ ...value, holdPlanMode: false }), 'utf8');
|
|
138
|
+
}
|
|
139
|
+
export function copilotPlanStateAllowsImplementation(root, sessionId, plan) {
|
|
140
|
+
const path = statePath(root, sessionId);
|
|
141
|
+
if (!existsSync(path))
|
|
142
|
+
return true; // Legacy Plan snapshots.
|
|
143
|
+
try {
|
|
144
|
+
const value = JSON.parse(readFileSync(path, 'utf8'));
|
|
145
|
+
const currentPlan = readFileSync(join(root, sessionId, 'plan.md'), 'utf8').trim();
|
|
146
|
+
return value.version === 1 && value.status === 'ready'
|
|
147
|
+
&& currentPlan === plan.trim()
|
|
148
|
+
&& value.planHash === createHash('sha256').update(plan).digest('hex');
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
export function copilotPlanControlPrompt(root, sessionId, revision, deferred = [], nativeUserInput = false) {
|
|
155
|
+
const interaction = nativeUserInput
|
|
156
|
+
? 'The native ask_user tool is enabled in this SDK session. Whenever a decision requires the user answer, invoke ask_user with the question and concrete choices when applicable, and wait for its response before continuing this same Plan. Do not print a question or A/B choices as an ordinary assistant reply and pretend to be waiting: that does not open the inline interaction. Do not infer tool unavailability from earlier conversation text or past diagnostics. Asking through ask_user is a UI interaction, not reading or modifying project files. Do not duplicate native questions in an artifact confirmation section.'
|
|
157
|
+
: 'Collect unresolved immediate questions under ## Decisions needed in plan.md, one numbered question per item with indented bullet choices. AgentLink will collect those artifact questions and return the answers before planning continues.';
|
|
158
|
+
return `${OPEN}${JSON.stringify({
|
|
159
|
+
version: 1, kind: 'plan-readiness', revision,
|
|
160
|
+
statusFile: statePath(root, sessionId), deferred,
|
|
161
|
+
interaction: nativeUserInput ? 'native' : 'artifact',
|
|
162
|
+
instructions: `${interaction} Plan clarification may need multiple rounds. Answering one batch is not completion or implementation authorization. Re-evaluate all decisions after each answer. Preserve confirmed decisions and do not infer all enhancements from a broad choice. Write the full plan.md as plain Markdown without control tokens or status JSON. After updating plan.md, write the separate statusFile as {"version":1,"revision":"<the revision above>","status":"awaiting_input"} if decisions remain, otherwise status "ready". Deferred questions are not answered: move them to a final confirmation section and do not re-ask them. Do not implement or print this control envelope, its metadata, or the sidecar contents in your reply.`,
|
|
163
|
+
})}${CLOSE}`;
|
|
164
|
+
}
|
|
165
|
+
/** Strip only a well-formed, trailing AgentLink-owned control envelope. */
|
|
166
|
+
export function stripCopilotPlanControl(text) {
|
|
167
|
+
const trimmed = text.trimEnd();
|
|
168
|
+
const start = trimmed.lastIndexOf(OPEN);
|
|
169
|
+
if (start < 0 || !trimmed.endsWith(CLOSE))
|
|
170
|
+
return text;
|
|
171
|
+
try {
|
|
172
|
+
const value = JSON.parse(trimmed.slice(start + OPEN.length, -CLOSE.length));
|
|
173
|
+
if (value.version === 1 && value.kind === 'plan-readiness' && typeof value.revision === 'string'
|
|
174
|
+
&& /^[0-9a-f-]{36}$/i.test(value.revision))
|
|
175
|
+
return trimmed.slice(0, start).trimEnd();
|
|
176
|
+
}
|
|
177
|
+
catch { /* Ordinary user text/quoted examples are not control envelopes. */ }
|
|
178
|
+
return text;
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=copilot-plan-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilot-plan-state.js","sourceRoot":"","sources":["../src/copilot-plan-state.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
type CopilotSessionBinding = {
|
|
2
|
+
copilotSessionId?: string | null;
|
|
3
|
+
lastCopilotSessionId?: string | null;
|
|
4
|
+
};
|
|
5
|
+
export declare function resolveCopilotCommandResumeSessionId(requestedSessionId: unknown, conversation?: CopilotSessionBinding): string | undefined;
|
|
6
|
+
export declare function dispatchCopilotRequest(scope: {
|
|
7
|
+
conversationId: string;
|
|
8
|
+
providerId?: string;
|
|
9
|
+
}, execute: () => Promise<void>, send: (message: Record<string, unknown>) => void, hasActiveTurn: () => boolean): Promise<void>;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export function resolveCopilotCommandResumeSessionId(requestedSessionId, conversation) {
|
|
2
|
+
if (requestedSessionId !== undefined
|
|
3
|
+
&& (typeof requestedSessionId !== 'string' || !requestedSessionId.trim())) {
|
|
4
|
+
throw new Error('Invalid Copilot resumeSessionId. Reopen the intended conversation before sending.');
|
|
5
|
+
}
|
|
6
|
+
const boundSessionId = conversation?.copilotSessionId || conversation?.lastCopilotSessionId || undefined;
|
|
7
|
+
if (boundSessionId && requestedSessionId && boundSessionId !== requestedSessionId) {
|
|
8
|
+
throw new Error('Copilot conversation/session mismatch. Reopen the intended conversation before sending.');
|
|
9
|
+
}
|
|
10
|
+
return requestedSessionId ?? boundSessionId;
|
|
11
|
+
}
|
|
12
|
+
// WebSocket listeners cannot catch a detached Promise rejection with their
|
|
13
|
+
// synchronous try/catch. Reject this request without terminating the Agent or
|
|
14
|
+
// treating another still-running turn as failed.
|
|
15
|
+
export async function dispatchCopilotRequest(scope, execute, send, hasActiveTurn) {
|
|
16
|
+
let ownerWasActive = false;
|
|
17
|
+
try {
|
|
18
|
+
ownerWasActive = hasActiveTurn();
|
|
19
|
+
await execute();
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
send({
|
|
23
|
+
type: 'error',
|
|
24
|
+
operation: 'copilot_request',
|
|
25
|
+
...scope,
|
|
26
|
+
message: error instanceof Error ? error.message : String(error),
|
|
27
|
+
...(ownerWasActive && hasActiveTurn() ? { preserveActiveTurn: true } : {}),
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=copilot-request-dispatch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilot-request-dispatch.js","sourceRoot":"","sources":["../src/copilot-request-dispatch.ts"],"names":[],"mappings":"AAKA,MAAM,UAAU,oCAAoC,CAClD,kBAA2B,EAC3B,YAAoC;IAEpC,IAAI,kBAAkB,KAAK,SAAS;WAC/B,CAAC,OAAO,kBAAkB,KAAK,QAAQ,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;QAC5E,MAAM,IAAI,KAAK,CAAC,mFAAmF,CAAC,CAAC;IACvG,CAAC;IACD,MAAM,cAAc,GAAG,YAAY,EAAE,gBAAgB,IAAI,YAAY,EAAE,oBAAoB,IAAI,SAAS,CAAC;IACzG,IAAI,cAAc,IAAI,kBAAkB,IAAI,cAAc,KAAK,kBAAkB,EAAE,CAAC;QAClF,MAAM,IAAI,KAAK,CAAC,yFAAyF,CAAC,CAAC;IAC7G,CAAC;IACD,OAAQ,kBAAyC,IAAI,cAAc,CAAC;AACtE,CAAC;AAED,2EAA2E;AAC3E,8EAA8E;AAC9E,iDAAiD;AACjD,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,KAAsD,EACtD,OAA4B,EAC5B,IAAgD,EAChD,aAA4B;IAE5B,IAAI,cAAc,GAAG,KAAK,CAAC;IAC3B,IAAI,CAAC;QACH,cAAc,GAAG,aAAa,EAAE,CAAC;QACjC,MAAM,OAAO,EAAE,CAAC;IAClB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC;YACH,IAAI,EAAE,OAAO;YACb,SAAS,EAAE,iBAAiB;YAC5B,GAAG,KAAK;YACR,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;YAC/D,GAAG,CAAC,cAAc,IAAI,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC3E,CAAC,CAAC;IACL,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Presentation-only snapshots from successful file tools; never read project files. */
|
|
2
|
+
export interface CopilotReviewDocument {
|
|
3
|
+
path: string;
|
|
4
|
+
content: string;
|
|
5
|
+
}
|
|
6
|
+
/** Hide only tools whose actual targets are all internal; mixed patches stay visible. */
|
|
7
|
+
export declare function copilotVisibleFileTool(tool: string, input: unknown): {
|
|
8
|
+
hidden: boolean;
|
|
9
|
+
input: unknown;
|
|
10
|
+
};
|
|
11
|
+
export declare function copilotVisibleFileToolOutput(content: string | undefined): string | undefined;
|
|
12
|
+
export declare class CopilotReviewDocuments {
|
|
13
|
+
private pending;
|
|
14
|
+
private documents;
|
|
15
|
+
start(id: string, tool: string, input: unknown): void;
|
|
16
|
+
complete(id: string, success: boolean): CopilotReviewDocument[];
|
|
17
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
function normalizePath(path) {
|
|
2
|
+
return path.replace(/\\+/g, '/').toLowerCase();
|
|
3
|
+
}
|
|
4
|
+
function internalPlanPath(path) {
|
|
5
|
+
const normalized = normalizePath(path);
|
|
6
|
+
return normalized.includes('/.copilot/session-state/')
|
|
7
|
+
&& /\/(?:plan\.md|\.agentlink-plan-state\.json)$/.test(normalized);
|
|
8
|
+
}
|
|
9
|
+
function patchText(input) {
|
|
10
|
+
if (typeof input === 'string')
|
|
11
|
+
return input;
|
|
12
|
+
if (!input || typeof input !== 'object')
|
|
13
|
+
return undefined;
|
|
14
|
+
const record = input;
|
|
15
|
+
return [record.patch, record.input].find(value => typeof value === 'string');
|
|
16
|
+
}
|
|
17
|
+
function patchFiles(text) {
|
|
18
|
+
const files = [];
|
|
19
|
+
for (const line of text.replace(/\r\n/g, '\n').split('\n')) {
|
|
20
|
+
const header = line.match(/^\*\*\* (Add|Update|Delete) File: (.+)$/);
|
|
21
|
+
if (header)
|
|
22
|
+
files.push({ path: header[2].trim(), operation: header[1], lines: [] });
|
|
23
|
+
else if (files.length && line !== '*** End Patch')
|
|
24
|
+
files[files.length - 1].lines.push(line);
|
|
25
|
+
}
|
|
26
|
+
return files;
|
|
27
|
+
}
|
|
28
|
+
/** Hide only tools whose actual targets are all internal; mixed patches stay visible. */
|
|
29
|
+
export function copilotVisibleFileTool(tool, input) {
|
|
30
|
+
const text = patchText(input);
|
|
31
|
+
if (tool === 'apply_patch' && text) {
|
|
32
|
+
const files = patchFiles(text);
|
|
33
|
+
if (!files.length)
|
|
34
|
+
return { hidden: false, input };
|
|
35
|
+
const visible = files.filter(file => !internalPlanPath(file.path));
|
|
36
|
+
if (visible.length === files.length)
|
|
37
|
+
return { hidden: false, input };
|
|
38
|
+
if (!visible.length)
|
|
39
|
+
return { hidden: true, input: undefined };
|
|
40
|
+
const patch = ['*** Begin Patch', ...visible.flatMap(file => [
|
|
41
|
+
`*** ${file.operation} File: ${file.path}`, ...file.lines,
|
|
42
|
+
]), '*** End Patch'].join('\n');
|
|
43
|
+
if (typeof input === 'string')
|
|
44
|
+
return { hidden: false, input: patch };
|
|
45
|
+
const record = input;
|
|
46
|
+
return { hidden: false, input: { ...record, [typeof record.patch === 'string' ? 'patch' : 'input']: patch } };
|
|
47
|
+
}
|
|
48
|
+
if (input && typeof input === 'object') {
|
|
49
|
+
const record = input;
|
|
50
|
+
const path = record.path || record.file_path || record.filePath;
|
|
51
|
+
if (typeof path === 'string' && internalPlanPath(path))
|
|
52
|
+
return { hidden: true, input: undefined };
|
|
53
|
+
}
|
|
54
|
+
return { hidden: false, input };
|
|
55
|
+
}
|
|
56
|
+
export function copilotVisibleFileToolOutput(content) {
|
|
57
|
+
return content?.split(/\r?\n/).filter(line => !internalPlanPath(line.trim())).join('\n');
|
|
58
|
+
}
|
|
59
|
+
/** Reconstruct update hunks only when the complete prior version is known. */
|
|
60
|
+
function updateContent(previous, lines) {
|
|
61
|
+
if (previous === undefined || lines.some(line => line.startsWith('*** Move to:')))
|
|
62
|
+
return undefined;
|
|
63
|
+
let result = previous;
|
|
64
|
+
let cursor = 0;
|
|
65
|
+
const hunks = [];
|
|
66
|
+
for (const line of lines) {
|
|
67
|
+
if (line.startsWith('@@'))
|
|
68
|
+
hunks.push([]);
|
|
69
|
+
else if (/^[ +\-]/.test(line)) {
|
|
70
|
+
if (!hunks.length)
|
|
71
|
+
hunks.push([]);
|
|
72
|
+
hunks[hunks.length - 1].push(line);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
for (const hunk of hunks) {
|
|
76
|
+
const before = hunk.filter(line => !line.startsWith('+')).map(line => line.slice(1)).join('\n');
|
|
77
|
+
const after = hunk.filter(line => !line.startsWith('-')).map(line => line.slice(1)).join('\n');
|
|
78
|
+
if (!before)
|
|
79
|
+
return undefined;
|
|
80
|
+
const index = result.indexOf(before, cursor);
|
|
81
|
+
if (index < 0 || result.indexOf(before, index + 1) >= 0)
|
|
82
|
+
return undefined;
|
|
83
|
+
result = result.slice(0, index) + after + result.slice(index + before.length);
|
|
84
|
+
cursor = index + after.length;
|
|
85
|
+
}
|
|
86
|
+
return hunks.length ? result : undefined;
|
|
87
|
+
}
|
|
88
|
+
export class CopilotReviewDocuments {
|
|
89
|
+
pending = new Map();
|
|
90
|
+
documents = new Map();
|
|
91
|
+
start(id, tool, input) {
|
|
92
|
+
if (input === undefined)
|
|
93
|
+
return;
|
|
94
|
+
if (!['apply_patch', 'write', 'edit', 'create'].includes(tool))
|
|
95
|
+
return;
|
|
96
|
+
if (this.pending.size >= 64)
|
|
97
|
+
this.pending.delete(this.pending.keys().next().value);
|
|
98
|
+
this.pending.set(id, { tool, input });
|
|
99
|
+
}
|
|
100
|
+
complete(id, success) {
|
|
101
|
+
const pending = this.pending.get(id);
|
|
102
|
+
this.pending.delete(id);
|
|
103
|
+
if (!pending)
|
|
104
|
+
return [];
|
|
105
|
+
if (!success) {
|
|
106
|
+
// A failed writer may have left partial data; later hunks cannot validate it.
|
|
107
|
+
const text = patchText(pending.input);
|
|
108
|
+
if (pending.tool === 'apply_patch' && text) {
|
|
109
|
+
for (const file of patchFiles(text))
|
|
110
|
+
this.documents.delete(normalizePath(file.path));
|
|
111
|
+
}
|
|
112
|
+
else if (pending.input && typeof pending.input === 'object') {
|
|
113
|
+
const record = pending.input;
|
|
114
|
+
const path = record.path || record.file_path || record.filePath;
|
|
115
|
+
if (typeof path === 'string')
|
|
116
|
+
this.documents.delete(normalizePath(path));
|
|
117
|
+
}
|
|
118
|
+
return [];
|
|
119
|
+
}
|
|
120
|
+
const written = new Map();
|
|
121
|
+
const save = (path, content) => {
|
|
122
|
+
const key = normalizePath(path);
|
|
123
|
+
this.documents.delete(key);
|
|
124
|
+
written.delete(key);
|
|
125
|
+
// Bounded snapshots. Missing/partial contents must not masquerade as a full document.
|
|
126
|
+
if (content !== undefined && content.length <= 128_000 && /\.md$/i.test(path) && !internalPlanPath(path)) {
|
|
127
|
+
const snapshot = { path, content };
|
|
128
|
+
this.documents.set(key, snapshot);
|
|
129
|
+
written.set(key, snapshot);
|
|
130
|
+
if (this.documents.size > 16)
|
|
131
|
+
this.documents.delete(this.documents.keys().next().value);
|
|
132
|
+
if (written.size > 16)
|
|
133
|
+
written.delete(written.keys().next().value);
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
const text = patchText(pending.input);
|
|
137
|
+
if (pending.tool === 'apply_patch' && text) {
|
|
138
|
+
for (const file of patchFiles(text)) {
|
|
139
|
+
if (internalPlanPath(file.path))
|
|
140
|
+
continue;
|
|
141
|
+
const prior = this.documents.get(normalizePath(file.path))?.content;
|
|
142
|
+
const content = file.operation === 'Add'
|
|
143
|
+
? file.lines.filter(line => line.startsWith('+')).map(line => line.slice(1)).join('\n')
|
|
144
|
+
: file.operation === 'Update' ? updateContent(prior, file.lines) : undefined;
|
|
145
|
+
save(file.path, content);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
else if (pending.input && typeof pending.input === 'object') {
|
|
149
|
+
const record = pending.input;
|
|
150
|
+
const path = record.path || record.file_path || record.filePath;
|
|
151
|
+
if (typeof path !== 'string')
|
|
152
|
+
return [];
|
|
153
|
+
const content = record.content ?? record.file_text;
|
|
154
|
+
if (['write', 'create'].includes(pending.tool) && typeof content === 'string')
|
|
155
|
+
save(path, content);
|
|
156
|
+
else
|
|
157
|
+
save(path, undefined);
|
|
158
|
+
}
|
|
159
|
+
return [...written.values()];
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=copilot-review-documents.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilot-review-documents.js","sourceRoot":"","sources":["../src/copilot-review-documents.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { closeSync, openSync, readSync, statSync } from 'fs';
|
|
2
|
+
import { isCopilotChildEvent } from './copilot-event-scope.js';
|
|
3
|
+
const cache = new Map();
|
|
4
|
+
const activityTypes = new Set(['user.message', 'assistant.message', 'tool.execution_start',
|
|
5
|
+
'tool.execution_complete', 'session.task_complete']);
|
|
6
|
+
/** Sorting is conversation activity, not Provider maintenance. Native journals
|
|
7
|
+
* remain untouched. Read only appended bytes after the first reconstruction. */
|
|
8
|
+
export function copilotSessionActivity(path, fallback, createdAt) {
|
|
9
|
+
let fd;
|
|
10
|
+
try {
|
|
11
|
+
const stats = statSync(path);
|
|
12
|
+
let state = cache.get(path);
|
|
13
|
+
if (!state || stats.size < state.offset || stats.birthtimeMs !== state.birthtime
|
|
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
|
+
}
|
|
18
|
+
if (stats.size > state.offset) {
|
|
19
|
+
fd = openSync(path, 'r');
|
|
20
|
+
const chunk = Buffer.alloc(64 * 1024);
|
|
21
|
+
while (state.offset < stats.size) {
|
|
22
|
+
const read = readSync(fd, chunk, 0, Math.min(chunk.length, stats.size - state.offset), state.offset);
|
|
23
|
+
if (!read)
|
|
24
|
+
break;
|
|
25
|
+
state.offset += read;
|
|
26
|
+
const bytes = Buffer.concat([state.partial, chunk.subarray(0, read)]);
|
|
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));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
state.mtime = stats.mtimeMs;
|
|
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;
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
// A Provider flush/temporary lock must not replace confirmed conversation
|
|
86
|
+
// activity with the newer maintenance timestamp.
|
|
87
|
+
return cache.get(path)?.lastSort ?? fallback;
|
|
88
|
+
}
|
|
89
|
+
finally {
|
|
90
|
+
if (fd != null)
|
|
91
|
+
closeSync(fd);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=copilot-session-activity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilot-session-activity.js","sourceRoot":"","sources":["../src/copilot-session-activity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { renameSync, unlinkSync, writeFileSync } from 'fs';
|
|
2
|
+
import { randomUUID } from 'crypto';
|
|
3
|
+
/** Publish one complete sidecar without truncating the previous snapshot. */
|
|
4
|
+
export function atomicWriteCopilotSidecar(path, content, encoding = 'utf8') {
|
|
5
|
+
const temporary = `${path}.${randomUUID()}.tmp`;
|
|
6
|
+
try {
|
|
7
|
+
writeFileSync(temporary, content, { encoding, flag: 'wx', mode: 0o600 });
|
|
8
|
+
renameSync(temporary, path);
|
|
9
|
+
}
|
|
10
|
+
finally {
|
|
11
|
+
try {
|
|
12
|
+
unlinkSync(temporary);
|
|
13
|
+
}
|
|
14
|
+
catch { /* Renamed successfully, or never created. */ }
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=copilot-sidecar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilot-sidecar.js","sourceRoot":"","sources":["../src/copilot-sidecar.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEpC,6EAA6E;AAC7E,MAAM,UAAU,yBAAyB,CAAC,IAAY,EAAE,OAAe,EAAE,WAA2B,MAAM;IACxG,MAAM,SAAS,GAAG,GAAG,IAAI,IAAI,UAAU,EAAE,MAAM,CAAC;IAChD,IAAI,CAAC;QACH,aAAa,CAAC,SAAS,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACzE,UAAU,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC9B,CAAC;YAAS,CAAC;QACT,IAAI,CAAC;YAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,6CAA6C,CAAC,CAAC;IACxF,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
type NativeEvent = {
|
|
2
|
+
id?: string;
|
|
3
|
+
type?: string;
|
|
4
|
+
timestamp?: string;
|
|
5
|
+
agentId?: string;
|
|
6
|
+
parentToolCallId?: string;
|
|
7
|
+
data?: Record<string, any>;
|
|
8
|
+
};
|
|
9
|
+
/** Request-scoped, read-only reconciliation of the Provider's own event journal. */
|
|
10
|
+
export declare class CopilotTurnJournal {
|
|
11
|
+
private path;
|
|
12
|
+
private onEvent;
|
|
13
|
+
private offset;
|
|
14
|
+
private partial;
|
|
15
|
+
private seen;
|
|
16
|
+
private tasks;
|
|
17
|
+
private completedTasks;
|
|
18
|
+
private childRuns;
|
|
19
|
+
private childWrites;
|
|
20
|
+
private continuation;
|
|
21
|
+
private currentTurn;
|
|
22
|
+
private finalTurn;
|
|
23
|
+
private finalEnded;
|
|
24
|
+
private finalCheckpoint;
|
|
25
|
+
private compacting;
|
|
26
|
+
private pendingInputs;
|
|
27
|
+
complete: boolean;
|
|
28
|
+
constructor(path: string, onEvent: (event: NativeEvent) => void);
|
|
29
|
+
get pending(): boolean;
|
|
30
|
+
private get childrenPending();
|
|
31
|
+
private observeChildRuns;
|
|
32
|
+
private resetFinal;
|
|
33
|
+
read(): void;
|
|
34
|
+
observe(event: NativeEvent): void;
|
|
35
|
+
}
|
|
36
|
+
export {};
|