@agentclientprotocol/claude-agent-acp 0.88.1-preview.6 → 0.89.0
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/acp-agent.d.ts +26 -1
- package/dist/acp-agent.d.ts.map +1 -1
- package/dist/acp-agent.js +91 -17
- package/dist/air-extension.d.ts +23 -0
- package/dist/air-extension.d.ts.map +1 -1
- package/dist/air-extension.js +23 -0
- package/dist/diff.d.ts +2 -0
- package/dist/diff.d.ts.map +1 -1
- package/dist/diff.js +37 -1
- package/dist/mcp-command.d.ts.map +1 -1
- package/dist/mcp-command.js +5 -0
- package/dist/session-index/activity.d.ts +56 -0
- package/dist/session-index/activity.d.ts.map +1 -0
- package/dist/session-index/activity.js +96 -0
- package/dist/session-index/archive-title.d.ts +52 -0
- package/dist/session-index/archive-title.d.ts.map +1 -0
- package/dist/session-index/archive-title.js +77 -0
- package/dist/session-index/connection.d.ts +152 -0
- package/dist/session-index/connection.d.ts.map +1 -0
- package/dist/session-index/connection.js +310 -0
- package/dist/session-index/dir-listing.d.ts +30 -0
- package/dist/session-index/dir-listing.d.ts.map +1 -0
- package/dist/session-index/dir-listing.js +110 -0
- package/dist/session-index/explicit-title.d.ts +34 -0
- package/dist/session-index/explicit-title.d.ts.map +1 -0
- package/dist/session-index/explicit-title.js +65 -0
- package/dist/session-index/first-prompt.d.ts +37 -0
- package/dist/session-index/first-prompt.d.ts.map +1 -0
- package/dist/session-index/first-prompt.js +195 -0
- package/dist/session-index/list-subscriptions.d.ts +190 -0
- package/dist/session-index/list-subscriptions.d.ts.map +1 -0
- package/dist/session-index/list-subscriptions.js +1163 -0
- package/dist/session-index/live-registry.d.ts +72 -0
- package/dist/session-index/live-registry.d.ts.map +1 -0
- package/dist/session-index/live-registry.js +240 -0
- package/dist/session-index/project-dirs.d.ts +45 -0
- package/dist/session-index/project-dirs.d.ts.map +1 -0
- package/dist/session-index/project-dirs.js +122 -0
- package/dist/session-index/service.d.ts +158 -0
- package/dist/session-index/service.d.ts.map +1 -0
- package/dist/session-index/service.js +546 -0
- package/dist/session-index/session-index.d.ts +201 -0
- package/dist/session-index/session-index.d.ts.map +1 -0
- package/dist/session-index/session-index.js +740 -0
- package/dist/session-index/session-info.d.ts +16 -0
- package/dist/session-index/session-info.d.ts.map +1 -0
- package/dist/session-index/session-info.js +51 -0
- package/dist/session-index/transcript-scan.d.ts +137 -0
- package/dist/session-index/transcript-scan.d.ts.map +1 -0
- package/dist/session-index/transcript-scan.js +545 -0
- package/dist/session-index/worktrees.d.ts +25 -0
- package/dist/session-index/worktrees.d.ts.map +1 -0
- package/dist/session-index/worktrees.js +128 -0
- package/dist/session-titles.d.ts +21 -0
- package/dist/session-titles.d.ts.map +1 -1
- package/dist/session-titles.js +101 -5
- package/dist/utils.d.ts +31 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +60 -2
- package/package.json +1 -1
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A session index row as the client sees it: the `SessionInfo` of
|
|
3
|
+
* `session/list` and of `_session/list/changes`, with the flat row fields of
|
|
4
|
+
* the RFDs in `_meta.jetbrains.air`.
|
|
5
|
+
*/
|
|
6
|
+
import type { SessionInfo } from "@agentclientprotocol/sdk";
|
|
7
|
+
import { type OwnSessionState } from "./activity.js";
|
|
8
|
+
import type { LiveRecord } from "./live-registry.js";
|
|
9
|
+
import type { IndexRow } from "./session-index.js";
|
|
10
|
+
/** The `SessionInfo` of `row`. `own` is what this connection knows of a
|
|
11
|
+
* session it runs, `live` the registry record of the session. */
|
|
12
|
+
export declare function sessionInfoOf(row: IndexRow, own: OwnSessionState | undefined, live: LiveRecord | undefined, now: number): SessionInfo;
|
|
13
|
+
/** What a change of the row is compared by: everything but `updatedAt`,
|
|
14
|
+
* which alone is no change. */
|
|
15
|
+
export declare function changeSignature(info: SessionInfo): string;
|
|
16
|
+
//# sourceMappingURL=session-info.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-info.d.ts","sourceRoot":"","sources":["../../src/session-index/session-info.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE5D,OAAO,EAA8B,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AACjF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAMnD;kEACkE;AAClE,wBAAgB,aAAa,CAC3B,GAAG,EAAE,QAAQ,EACb,GAAG,EAAE,eAAe,GAAG,SAAS,EAChC,IAAI,EAAE,UAAU,GAAG,SAAS,EAC5B,GAAG,EAAE,MAAM,GACV,WAAW,CAgCb;AAED;gCACgC;AAChC,wBAAgB,eAAe,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAEzD"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A session index row as the client sees it: the `SessionInfo` of
|
|
3
|
+
* `session/list` and of `_session/list/changes`, with the flat row fields of
|
|
4
|
+
* the RFDs in `_meta.jetbrains.air`.
|
|
5
|
+
*/
|
|
6
|
+
import { withAirMeta } from "../air-extension.js";
|
|
7
|
+
import { deriveActivity, selectCost } from "./activity.js";
|
|
8
|
+
function iso(ms) {
|
|
9
|
+
return ms === undefined || !Number.isFinite(ms) ? undefined : new Date(ms).toISOString();
|
|
10
|
+
}
|
|
11
|
+
/** The `SessionInfo` of `row`. `own` is what this connection knows of a
|
|
12
|
+
* session it runs, `live` the registry record of the session. */
|
|
13
|
+
export function sessionInfoOf(row, own, live, now) {
|
|
14
|
+
const activity = deriveActivity({
|
|
15
|
+
own,
|
|
16
|
+
live,
|
|
17
|
+
facts: row.facts,
|
|
18
|
+
transcriptMtimeMs: row.mtimeMs,
|
|
19
|
+
now,
|
|
20
|
+
});
|
|
21
|
+
const cost = selectCost(own);
|
|
22
|
+
const { facts } = row;
|
|
23
|
+
// The row fields of the session list extensions RFD and RFD #2161, flat;
|
|
24
|
+
// each is omitted when unknown, except `archived`.
|
|
25
|
+
const fields = {
|
|
26
|
+
archived: row.archived,
|
|
27
|
+
lastPromptAt: iso(facts.lastPromptAt),
|
|
28
|
+
model: facts.model,
|
|
29
|
+
forkedFrom: facts.forkedFrom,
|
|
30
|
+
state: activity?.state,
|
|
31
|
+
lastTurnEndedAt: activity?.lastTurnEndedAt,
|
|
32
|
+
cost: cost === undefined ? undefined : { amount: cost, currency: "USD" },
|
|
33
|
+
};
|
|
34
|
+
let meta;
|
|
35
|
+
for (const [key, value] of Object.entries(fields)) {
|
|
36
|
+
if (value !== undefined)
|
|
37
|
+
meta = withAirMeta(meta, key, value);
|
|
38
|
+
}
|
|
39
|
+
return {
|
|
40
|
+
sessionId: row.sessionId,
|
|
41
|
+
cwd: row.cwd,
|
|
42
|
+
title: row.title,
|
|
43
|
+
updatedAt: new Date(row.updatedAtMs).toISOString(),
|
|
44
|
+
_meta: meta,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/** What a change of the row is compared by: everything but `updatedAt`,
|
|
48
|
+
* which alone is no change. */
|
|
49
|
+
export function changeSignature(info) {
|
|
50
|
+
return JSON.stringify([info.sessionId, info.cwd, info.title, info._meta ?? null]);
|
|
51
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the session list needs from a transcript beyond the SDK metadata.
|
|
3
|
+
*
|
|
4
|
+
* One open reads the first and the last {@link CHUNK_SIZE} bytes, the same
|
|
5
|
+
* window that the SDK reads. The tail gives the time of the last message, the
|
|
6
|
+
* end of the last turn. The head and the tail give the `cwd` candidates.
|
|
7
|
+
*
|
|
8
|
+
* A last message longer than the tail window leaves no message in it: then
|
|
9
|
+
* the tail window grows, up to {@link MAX_TAIL_SIZE}, until it holds one.
|
|
10
|
+
*/
|
|
11
|
+
import * as fs from "node:fs/promises";
|
|
12
|
+
export type TurnState = "finished" | "unfinished";
|
|
13
|
+
export type TranscriptFacts = {
|
|
14
|
+
/** Time of the last user or assistant message in the tail, epoch ms. */
|
|
15
|
+
lastMessageAt?: number;
|
|
16
|
+
/** Whether the last turn in the tail ended. Undefined when the tail shows
|
|
17
|
+
* no turn at all. */
|
|
18
|
+
turnState?: TurnState;
|
|
19
|
+
/** Time the last ended turn ended, epoch ms. */
|
|
20
|
+
lastTurnEndedAt?: number;
|
|
21
|
+
/** The last turn ended with an API error (an `isApiErrorMessage`
|
|
22
|
+
* assistant record), not a user interrupt, and nothing came after it. */
|
|
23
|
+
lastTurnError?: boolean;
|
|
24
|
+
/** The first `cwd` of the head. */
|
|
25
|
+
headCwd?: string;
|
|
26
|
+
/** The last `cwd` of the tail. */
|
|
27
|
+
tailCwd?: string;
|
|
28
|
+
/** Time of the last real user prompt in the tail (not a tool result, a
|
|
29
|
+
* meta record or a slash command), epoch ms. */
|
|
30
|
+
lastPromptAt?: number;
|
|
31
|
+
/** Whether `lastPromptAt` is final: the prompt was found, or the tail
|
|
32
|
+
* window searched up to {@link MAX_TAIL_SIZE} holds none. */
|
|
33
|
+
promptSearched?: boolean;
|
|
34
|
+
/** The model of the last assistant message in the tail. */
|
|
35
|
+
model?: string;
|
|
36
|
+
/** The session this one was forked from: the `forkedFrom.sessionId` that
|
|
37
|
+
* the SDK and CLI fork write on every copied record. */
|
|
38
|
+
forkedFrom?: string;
|
|
39
|
+
/** Whether the head or the tail holds a user or an assistant message. A
|
|
40
|
+
* transcript without one is a metadata-only stub. */
|
|
41
|
+
hasMessages: boolean;
|
|
42
|
+
};
|
|
43
|
+
export type HeadTail = {
|
|
44
|
+
head: string;
|
|
45
|
+
tail: string;
|
|
46
|
+
};
|
|
47
|
+
/** Facts that an earlier scan may have found before the tail window. */
|
|
48
|
+
declare const INHERITED_FACTS: readonly ["model", "tailCwd", "lastTurnEndedAt"];
|
|
49
|
+
/** What an earlier scan of the same file found, at `size`. */
|
|
50
|
+
export type PreviousScan = {
|
|
51
|
+
size: number;
|
|
52
|
+
} & Pick<TranscriptFacts, "lastPromptAt" | "promptSearched" | (typeof INHERITED_FACTS)[number]>;
|
|
53
|
+
/** The first and the last 64 KB of the first `size` bytes of `filePath`:
|
|
54
|
+
* what was appended after the file was stat'ed is not read, so the result
|
|
55
|
+
* matches the size it is cached by. The tail is the head for a file that
|
|
56
|
+
* fits in one chunk. */
|
|
57
|
+
export declare function readHeadTail(filePath: string, size: number): Promise<HeadTail>;
|
|
58
|
+
/** {@link readHeadTail} of a file that is open already. */
|
|
59
|
+
export declare function readHeadTailOf(handle: fs.FileHandle, size: number): Promise<HeadTail>;
|
|
60
|
+
/**
|
|
61
|
+
* The facts of `filePath`, from its head and tail. When the transcript has
|
|
62
|
+
* messages but the tail window lacks the last message or the last user
|
|
63
|
+
* prompt (a long answer or tool output follows it), the window grows,
|
|
64
|
+
* reading only the new range each step, until it holds both or reaches
|
|
65
|
+
* {@link MAX_TAIL_SIZE}. The result of a full search is kept per
|
|
66
|
+
* `(path, size)`.
|
|
67
|
+
*
|
|
68
|
+
* `previous` is what an earlier scan of the same file found: when the file
|
|
69
|
+
* only grew by less than the tail window, and the tail holds no prompt, the
|
|
70
|
+
* appended bytes hold none either, so the earlier `lastPromptAt` stands.
|
|
71
|
+
*/
|
|
72
|
+
export declare function scanTranscriptFile(filePath: string, size: number, headTail?: HeadTail, previous?: PreviousScan,
|
|
73
|
+
/** Tells a file replaced by another of the same size apart (its inode). */
|
|
74
|
+
identity?: number): Promise<TranscriptFacts>;
|
|
75
|
+
/** The cwd of the last `relocated` record of the tail: where the session
|
|
76
|
+
* was moved, whatever cwd its earlier messages carry. */
|
|
77
|
+
export declare function relocatedCwd(tail: string): string | undefined;
|
|
78
|
+
/** The cwd a transcript belongs to, as the SDK reads it: the last
|
|
79
|
+
* `relocated` record of the tail, else the first cwd of the head. */
|
|
80
|
+
export declare function transcriptProjectCwd({ head, tail }: HeadTail): string | undefined;
|
|
81
|
+
type Entry = Record<string, unknown>;
|
|
82
|
+
/**
|
|
83
|
+
* How a main-chain record bears on the end of the turn: `finished` for a
|
|
84
|
+
* record that ends a turn (an assistant `end_turn`, an API error, a user
|
|
85
|
+
* interrupt, the CLI's turn-end system records), `unfinished` for a record of
|
|
86
|
+
* a turn in progress, and undefined for a record that says nothing.
|
|
87
|
+
*/
|
|
88
|
+
export declare function turnEffect(entry: Entry): TurnState | undefined;
|
|
89
|
+
/** The facts of a transcript, from its head and its tail. */
|
|
90
|
+
export declare function scanTranscript({ head, tail }: HeadTail, options?: {
|
|
91
|
+
wide?: boolean;
|
|
92
|
+
known?: {
|
|
93
|
+
model?: string;
|
|
94
|
+
tailCwd?: string;
|
|
95
|
+
};
|
|
96
|
+
}): TranscriptFacts;
|
|
97
|
+
/** Whether the first record of the transcript is a sidechain one, which the
|
|
98
|
+
* SDK never lists. */
|
|
99
|
+
export declare function isSidechainTranscript(head: string): boolean;
|
|
100
|
+
/** The last `customTitle` of the tail, as the SDK reads it. */
|
|
101
|
+
export declare function tailCustomTitle(tail: string): string | undefined;
|
|
102
|
+
/** The last agent name of a transcript, as AIR's native Claude provider
|
|
103
|
+
* reads it: the top-level `agentName` of any record, from the tail, else
|
|
104
|
+
* from the head. */
|
|
105
|
+
export declare function transcriptAgentName({ head, tail }: HeadTail): string | undefined;
|
|
106
|
+
/** What the SDK reports as the titles of a session. */
|
|
107
|
+
export type SdkTitles = {
|
|
108
|
+
/** `SDKSessionInfo.customTitle`: the title the CLI or a client set. */
|
|
109
|
+
customTitle?: string;
|
|
110
|
+
/** `SDKSessionInfo.summary`: the custom title, else a generated one. */
|
|
111
|
+
summary?: string;
|
|
112
|
+
};
|
|
113
|
+
/**
|
|
114
|
+
* The titles the SDK gives a transcript, from its own head and tail, in the
|
|
115
|
+
* SDK's order: custom title (tail, the sidecar, head), AI title, then
|
|
116
|
+
* {@link generatedTitle}. For a transcript that the SDK `getSessionInfo`
|
|
117
|
+
* does not read (another copy of the session comes first in its search).
|
|
118
|
+
* The sidecar title counts only when the tail has no custom title.
|
|
119
|
+
*/
|
|
120
|
+
export declare function sdkTitles({ head, tail }: HeadTail, sidecarTitle?: string): SdkTitles;
|
|
121
|
+
/** The title of a transcript without a custom title, in the SDK's order: AI
|
|
122
|
+
* title, last prompt, summary, first prompt. */
|
|
123
|
+
export declare function generatedTitle({ head, tail }: HeadTail): string | undefined;
|
|
124
|
+
/** The time of the last `"timestamp"` in the last 64 KB of a file, cut
|
|
125
|
+
* line included, epoch ms: a record longer than that still ends with it. */
|
|
126
|
+
export declare function lastTimestamp(filePath: string, size: number): Promise<number | undefined>;
|
|
127
|
+
/**
|
|
128
|
+
* The session this transcript was continued in, as the SDK list reads it: the
|
|
129
|
+
* last `continued-in` record of the tail, unless a completed turn follows it
|
|
130
|
+
* (the session was resumed here again).
|
|
131
|
+
*/
|
|
132
|
+
export declare function continuedInSessionId(tail: string): string | undefined;
|
|
133
|
+
/** Whether the transcript at `filePath` holds conversation history (a record
|
|
134
|
+
* with a `parentUuid`), as the SDK checks a continuation's successor. */
|
|
135
|
+
export declare function hasHistory(filePath: string): Promise<boolean>;
|
|
136
|
+
export {};
|
|
137
|
+
//# sourceMappingURL=transcript-scan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transcript-scan.d.ts","sourceRoot":"","sources":["../../src/session-index/transcript-scan.ts"],"names":[],"mappings":"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"}
|