@molecule/api-agent-transcript-copilot-chat 1.0.0 → 1.0.1
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/README.md +126 -0
- package/dist/export.d.ts +53 -0
- package/dist/export.d.ts.map +1 -0
- package/dist/export.js +173 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +42 -0
- package/dist/provider.d.ts +11 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +22 -0
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
AUTO-GENERATED — DO NOT EDIT THIS FILE.
|
|
3
|
+
Generated by `mlcl sync-docs` from the package's src/index.ts JSDoc + mlcl/registry.json.
|
|
4
|
+
Edits here are overwritten on the next commit (molecule's pre-commit hook regenerates).
|
|
5
|
+
To change this document, edit the module-level JSDoc in src/index.ts.
|
|
6
|
+
Generated: 2026-09-29T16:49:57.282Z
|
|
7
|
+
-->
|
|
8
|
+
|
|
9
|
+
# @molecule/api-agent-transcript-copilot-chat
|
|
10
|
+
|
|
11
|
+
> **Auto-generated, AI-first package reference** for the [molecule.dev](https://molecule.dev) ecosystem.
|
|
12
|
+
> It is written to be read by coding agents as much as by people, and is generated from this
|
|
13
|
+
> package's source — edit `src/index.ts` JSDoc, not this file.
|
|
14
|
+
|
|
15
|
+
GitHub Copilot Chat transcript reader for `@molecule/api-agent-transcript`.
|
|
16
|
+
|
|
17
|
+
Reads the `chat.json` VS Code saves from "Chat: Export Chat…" (Command
|
|
18
|
+
Palette, or the chat view's ⋯ menu) into a normalized `AgentSession`: each
|
|
19
|
+
request as you typed it, each response's markdown, the model that answered,
|
|
20
|
+
and the files the response edited.
|
|
21
|
+
|
|
22
|
+
## Quick Start
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import { readFileSync } from 'node:fs'
|
|
26
|
+
import { readTranscript, setProvider } from '@molecule/api-agent-transcript'
|
|
27
|
+
import { provider } from '@molecule/api-agent-transcript-copilot-chat'
|
|
28
|
+
|
|
29
|
+
setProvider(provider)
|
|
30
|
+
const file = 'chat.json'
|
|
31
|
+
const session = readTranscript({ text: readFileSync(file, 'utf8'), fileName: file })
|
|
32
|
+
console.log(session.harness, session.model) // 'GitHub Copilot Chat', 'copilot/…'
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Type
|
|
36
|
+
|
|
37
|
+
`provider`
|
|
38
|
+
|
|
39
|
+
## Installation
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npm install @molecule/api-agent-transcript-copilot-chat @molecule/api-agent-transcript
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## API
|
|
46
|
+
|
|
47
|
+
### Functions
|
|
48
|
+
|
|
49
|
+
#### `looksLikeChatExport(text)`
|
|
50
|
+
|
|
51
|
+
Whether a text is a VS Code chat export.
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
function looksLikeChatExport(text: string): boolean
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
- `text` — The file's text.
|
|
58
|
+
|
|
59
|
+
**Returns:** True on a positive match.
|
|
60
|
+
|
|
61
|
+
#### `readChatExport(text)`
|
|
62
|
+
|
|
63
|
+
Read a VS Code chat export.
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
function readChatExport(text: string): AgentSession
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
- `text` — The export's text.
|
|
70
|
+
|
|
71
|
+
**Returns:** The normalized session.
|
|
72
|
+
|
|
73
|
+
### Constants
|
|
74
|
+
|
|
75
|
+
#### `provider`
|
|
76
|
+
|
|
77
|
+
Reads the JSON VS Code's "Chat: Export Chat…" saves.
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
const provider: AgentTranscriptReader
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Core Interface
|
|
84
|
+
|
|
85
|
+
Implements `@molecule/api-agent-transcript` interface.
|
|
86
|
+
|
|
87
|
+
## Bond Wiring
|
|
88
|
+
|
|
89
|
+
Setup function to register this provider with the core interface:
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
import { setProvider } from '@molecule/api-agent-transcript'
|
|
93
|
+
import { provider } from '@molecule/api-agent-transcript-copilot-chat'
|
|
94
|
+
|
|
95
|
+
export function setupAgentTranscriptCopilotChat(): void {
|
|
96
|
+
setProvider(provider)
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Injection Notes
|
|
101
|
+
|
|
102
|
+
### Requirements
|
|
103
|
+
|
|
104
|
+
Peer dependencies:
|
|
105
|
+
|
|
106
|
+
- `@molecule/api-agent-transcript` ^1.0.0
|
|
107
|
+
|
|
108
|
+
### Runtime Dependencies
|
|
109
|
+
|
|
110
|
+
- `@molecule/api-agent-transcript`
|
|
111
|
+
|
|
112
|
+
- **The export is VS Code's, not Copilot's**, so any chat participant's
|
|
113
|
+
export reads the same way. `harness` is `GitHub Copilot Chat` when the
|
|
114
|
+
responder is Copilot, otherwise `VS Code Chat (<responder>)`.
|
|
115
|
+
- `model` on each reply is the request's `modelId` as VS Code records it
|
|
116
|
+
(e.g. `copilot/gpt-5.3`); the session's `model` is set when every reply
|
|
117
|
+
used the same one.
|
|
118
|
+
- Reply text is the response's markdown with inline file references
|
|
119
|
+
written as `` `name` ``; thinking, tool-invocation and progress parts are
|
|
120
|
+
not prose.
|
|
121
|
+
- Files: each `textEditGroup` part is an edit, its text the inserted text
|
|
122
|
+
of every edit in the group. Requests VS Code started itself
|
|
123
|
+
(`isSystemInitiated`) contribute their reply but no user turn; requests
|
|
124
|
+
hidden from the transcript are skipped.
|
|
125
|
+
- Format verified 2026-09-29 against the VS Code source
|
|
126
|
+
(`chatImportExport.ts`, `chatModel.ts` `toExport()`).
|
package/dist/export.d.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VS Code's chat export — the JSON "Chat: Export Chat…" saves
|
|
3
|
+
* (`chat.json`) from GitHub Copilot Chat or any other chat participant.
|
|
4
|
+
* Verified 2026-09-29 against microsoft/vscode `main`:
|
|
5
|
+
* `src/vs/workbench/contrib/chat/browser/actions/chatImportExport.ts`
|
|
6
|
+
* (writes `JSON.stringify(model.toExport())`) and
|
|
7
|
+
* `src/vs/workbench/contrib/chat/common/model/chatModel.ts`
|
|
8
|
+
* (`IExportableChatData`, `ISerializableChatRequestData`, `toExport()`).
|
|
9
|
+
*
|
|
10
|
+
* ```json
|
|
11
|
+
* {
|
|
12
|
+
* "initialLocation": "panel",
|
|
13
|
+
* "responderUsername": "GitHub Copilot",
|
|
14
|
+
* "requests": [
|
|
15
|
+
* {
|
|
16
|
+
* "requestId": "request_…",
|
|
17
|
+
* "message": { "text": "the message as typed", "parts": [ … ] },
|
|
18
|
+
* "timestamp": 1790582400000,
|
|
19
|
+
* "modelId": "copilot/gpt-5.3",
|
|
20
|
+
* "response": [
|
|
21
|
+
* { "value": "markdown…" },
|
|
22
|
+
* { "kind": "inlineReference", "inlineReference": { "path": "/src/app.ts", … }, "name"?: "…" },
|
|
23
|
+
* { "kind": "textEditGroup", "uri": { "path": "/src/app.ts", … }, "edits": [[{ "range": …, "text": "…" }]] },
|
|
24
|
+
* { "kind": "toolInvocationSerialized", … }
|
|
25
|
+
* ]
|
|
26
|
+
* }
|
|
27
|
+
* ]
|
|
28
|
+
* }
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* A response is a list of parts: markdown is written as a bare
|
|
32
|
+
* `IMarkdownString` (`{ value }`, no `kind`), everything else keeps its
|
|
33
|
+
* `kind`. Older exports stored `message` as a plain string.
|
|
34
|
+
*
|
|
35
|
+
* @module
|
|
36
|
+
*/
|
|
37
|
+
import type { AgentSession } from '@molecule/api-agent-transcript';
|
|
38
|
+
/**
|
|
39
|
+
* Whether a text is a VS Code chat export.
|
|
40
|
+
*
|
|
41
|
+
* @param text - The file's text.
|
|
42
|
+
* @returns True on a positive match.
|
|
43
|
+
*/
|
|
44
|
+
export declare function looksLikeChatExport(text: string): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Read a VS Code chat export.
|
|
47
|
+
*
|
|
48
|
+
* @param text - The export's text.
|
|
49
|
+
* @returns The normalized session.
|
|
50
|
+
* @throws {Error} When the text is not an export.
|
|
51
|
+
*/
|
|
52
|
+
export declare function readChatExport(text: string): AgentSession;
|
|
53
|
+
//# sourceMappingURL=export.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../src/export.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,KAAK,EAAkB,YAAY,EAAa,MAAM,gCAAgC,CAAA;AAoD7F;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEzD;AA0DD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAuCzD"}
|
package/dist/export.js
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VS Code's chat export — the JSON "Chat: Export Chat…" saves
|
|
3
|
+
* (`chat.json`) from GitHub Copilot Chat or any other chat participant.
|
|
4
|
+
* Verified 2026-09-29 against microsoft/vscode `main`:
|
|
5
|
+
* `src/vs/workbench/contrib/chat/browser/actions/chatImportExport.ts`
|
|
6
|
+
* (writes `JSON.stringify(model.toExport())`) and
|
|
7
|
+
* `src/vs/workbench/contrib/chat/common/model/chatModel.ts`
|
|
8
|
+
* (`IExportableChatData`, `ISerializableChatRequestData`, `toExport()`).
|
|
9
|
+
*
|
|
10
|
+
* ```json
|
|
11
|
+
* {
|
|
12
|
+
* "initialLocation": "panel",
|
|
13
|
+
* "responderUsername": "GitHub Copilot",
|
|
14
|
+
* "requests": [
|
|
15
|
+
* {
|
|
16
|
+
* "requestId": "request_…",
|
|
17
|
+
* "message": { "text": "the message as typed", "parts": [ … ] },
|
|
18
|
+
* "timestamp": 1790582400000,
|
|
19
|
+
* "modelId": "copilot/gpt-5.3",
|
|
20
|
+
* "response": [
|
|
21
|
+
* { "value": "markdown…" },
|
|
22
|
+
* { "kind": "inlineReference", "inlineReference": { "path": "/src/app.ts", … }, "name"?: "…" },
|
|
23
|
+
* { "kind": "textEditGroup", "uri": { "path": "/src/app.ts", … }, "edits": [[{ "range": …, "text": "…" }]] },
|
|
24
|
+
* { "kind": "toolInvocationSerialized", … }
|
|
25
|
+
* ]
|
|
26
|
+
* }
|
|
27
|
+
* ]
|
|
28
|
+
* }
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* A response is a list of parts: markdown is written as a bare
|
|
32
|
+
* `IMarkdownString` (`{ value }`, no `kind`), everything else keeps its
|
|
33
|
+
* `kind`. Older exports stored `message` as a plain string.
|
|
34
|
+
*
|
|
35
|
+
* @module
|
|
36
|
+
*/
|
|
37
|
+
/**
|
|
38
|
+
* The export, when the text is one.
|
|
39
|
+
*
|
|
40
|
+
* @param text - The file's text.
|
|
41
|
+
* @returns The export, or `null`.
|
|
42
|
+
*/
|
|
43
|
+
function parse(text) {
|
|
44
|
+
const trimmed = text.trim();
|
|
45
|
+
if (!trimmed.startsWith('{'))
|
|
46
|
+
return null;
|
|
47
|
+
let v;
|
|
48
|
+
try {
|
|
49
|
+
v = JSON.parse(trimmed);
|
|
50
|
+
}
|
|
51
|
+
catch (_error) {
|
|
52
|
+
// Not JSON: not an export.
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
const e = v;
|
|
56
|
+
if (!e || typeof e.responderUsername !== 'string' || !Array.isArray(e.requests))
|
|
57
|
+
return null;
|
|
58
|
+
const ok = e.requests.every((r) => r &&
|
|
59
|
+
typeof r === 'object' &&
|
|
60
|
+
(typeof r.message === 'string' || (typeof r.message === 'object' && r.message !== null)) &&
|
|
61
|
+
(r.response === undefined || r.response === null || Array.isArray(r.response)));
|
|
62
|
+
return ok ? e : null;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Whether a text is a VS Code chat export.
|
|
66
|
+
*
|
|
67
|
+
* @param text - The file's text.
|
|
68
|
+
* @returns True on a positive match.
|
|
69
|
+
*/
|
|
70
|
+
export function looksLikeChatExport(text) {
|
|
71
|
+
return parse(text) !== null;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* The path a serialized URI (or location) points at.
|
|
75
|
+
*
|
|
76
|
+
* @param v - The URI, or a `{ uri, range }` location.
|
|
77
|
+
* @returns The path, or ''.
|
|
78
|
+
*/
|
|
79
|
+
function pathOf(v) {
|
|
80
|
+
const u = v;
|
|
81
|
+
if (!u || typeof u !== 'object')
|
|
82
|
+
return '';
|
|
83
|
+
if (u.uri)
|
|
84
|
+
return pathOf(u.uri);
|
|
85
|
+
return u.fsPath ?? u.path ?? '';
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* The prose and files of one response.
|
|
89
|
+
*
|
|
90
|
+
* @param parts - The response parts.
|
|
91
|
+
* @returns The reply's text and writes.
|
|
92
|
+
*/
|
|
93
|
+
function readResponse(parts) {
|
|
94
|
+
let text = '';
|
|
95
|
+
const files = [];
|
|
96
|
+
for (const raw of parts) {
|
|
97
|
+
const p = raw;
|
|
98
|
+
if (!p || typeof p !== 'object')
|
|
99
|
+
continue;
|
|
100
|
+
if (p.kind === undefined && typeof p.value === 'string') {
|
|
101
|
+
text += p.value;
|
|
102
|
+
}
|
|
103
|
+
else if (p.kind === 'inlineReference') {
|
|
104
|
+
const path = pathOf(p.inlineReference);
|
|
105
|
+
const label = p.name ?? path.split('/').pop() ?? '';
|
|
106
|
+
if (label)
|
|
107
|
+
text += `\`${label}\``;
|
|
108
|
+
}
|
|
109
|
+
else if (p.kind === 'textEditGroup') {
|
|
110
|
+
const path = pathOf(p.uri);
|
|
111
|
+
const groups = Array.isArray(p.edits) ? p.edits : [];
|
|
112
|
+
const inserted = groups
|
|
113
|
+
.flatMap((g) => (Array.isArray(g) ? g : []))
|
|
114
|
+
.map((e) => e && typeof e.text === 'string'
|
|
115
|
+
? e.text
|
|
116
|
+
: '')
|
|
117
|
+
.filter(Boolean);
|
|
118
|
+
if (path && inserted.length)
|
|
119
|
+
files.push({ path, kind: 'edit', text: inserted.join('\n'), complete: true });
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return { text: text.trim(), files };
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Read a VS Code chat export.
|
|
126
|
+
*
|
|
127
|
+
* @param text - The export's text.
|
|
128
|
+
* @returns The normalized session.
|
|
129
|
+
* @throws {Error} When the text is not an export.
|
|
130
|
+
*/
|
|
131
|
+
export function readChatExport(text) {
|
|
132
|
+
const e = parse(text);
|
|
133
|
+
if (!e)
|
|
134
|
+
throw new Error('Not a VS Code chat export.');
|
|
135
|
+
const turns = [];
|
|
136
|
+
const iso = (ms) => typeof ms === 'number' ? new Date(ms).toISOString() : undefined;
|
|
137
|
+
for (const r of e.requests) {
|
|
138
|
+
if (r.hiddenFromTranscript)
|
|
139
|
+
continue;
|
|
140
|
+
const said = (typeof r.message === 'string' ? r.message : (r.message?.text ?? '')).trim();
|
|
141
|
+
if (said && !r.isSystemInitiated) {
|
|
142
|
+
turns.push({ role: 'user', text: said, timestamp: iso(r.timestamp), files: [] });
|
|
143
|
+
}
|
|
144
|
+
const { text: reply, files } = readResponse(r.response ?? []);
|
|
145
|
+
if (reply || files.length) {
|
|
146
|
+
const last = turns[turns.length - 1];
|
|
147
|
+
if (last && last.role === 'assistant') {
|
|
148
|
+
last.text = [last.text, reply].filter(Boolean).join('\n\n');
|
|
149
|
+
last.files.push(...files);
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
turns.push({
|
|
153
|
+
role: 'assistant',
|
|
154
|
+
text: reply,
|
|
155
|
+
timestamp: iso(r.timestamp),
|
|
156
|
+
model: r.modelId,
|
|
157
|
+
files,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
const copilot = /copilot/i.test(e.responderUsername);
|
|
163
|
+
const session = {
|
|
164
|
+
format: 'copilot-chat',
|
|
165
|
+
harness: copilot ? 'GitHub Copilot Chat' : `VS Code Chat (${e.responderUsername})`,
|
|
166
|
+
startedAt: turns[0]?.timestamp,
|
|
167
|
+
turns,
|
|
168
|
+
};
|
|
169
|
+
const models = new Set(turns.map((t) => t.model).filter(Boolean));
|
|
170
|
+
if (models.size === 1)
|
|
171
|
+
session.model = [...models][0];
|
|
172
|
+
return session;
|
|
173
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub Copilot Chat transcript reader for `@molecule/api-agent-transcript`.
|
|
3
|
+
*
|
|
4
|
+
* Reads the `chat.json` VS Code saves from "Chat: Export Chat…" (Command
|
|
5
|
+
* Palette, or the chat view's ⋯ menu) into a normalized `AgentSession`: each
|
|
6
|
+
* request as you typed it, each response's markdown, the model that answered,
|
|
7
|
+
* and the files the response edited.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { readFileSync } from 'node:fs'
|
|
12
|
+
* import { readTranscript, setProvider } from '@molecule/api-agent-transcript'
|
|
13
|
+
* import { provider } from '@molecule/api-agent-transcript-copilot-chat'
|
|
14
|
+
*
|
|
15
|
+
* setProvider(provider)
|
|
16
|
+
* const file = 'chat.json'
|
|
17
|
+
* const session = readTranscript({ text: readFileSync(file, 'utf8'), fileName: file })
|
|
18
|
+
* console.log(session.harness, session.model) // 'GitHub Copilot Chat', 'copilot/…'
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* @remarks
|
|
22
|
+
* - **The export is VS Code's, not Copilot's**, so any chat participant's
|
|
23
|
+
* export reads the same way. `harness` is `GitHub Copilot Chat` when the
|
|
24
|
+
* responder is Copilot, otherwise `VS Code Chat (<responder>)`.
|
|
25
|
+
* - `model` on each reply is the request's `modelId` as VS Code records it
|
|
26
|
+
* (e.g. `copilot/gpt-5.3`); the session's `model` is set when every reply
|
|
27
|
+
* used the same one.
|
|
28
|
+
* - Reply text is the response's markdown with inline file references
|
|
29
|
+
* written as `` `name` ``; thinking, tool-invocation and progress parts are
|
|
30
|
+
* not prose.
|
|
31
|
+
* - Files: each `textEditGroup` part is an edit, its text the inserted text
|
|
32
|
+
* of every edit in the group. Requests VS Code started itself
|
|
33
|
+
* (`isSystemInitiated`) contribute their reply but no user turn; requests
|
|
34
|
+
* hidden from the transcript are skipped.
|
|
35
|
+
* - Format verified 2026-09-29 against the VS Code source
|
|
36
|
+
* (`chatImportExport.ts`, `chatModel.ts` `toExport()`).
|
|
37
|
+
*
|
|
38
|
+
* @module
|
|
39
|
+
*/
|
|
40
|
+
export * from './browser-guard.js';
|
|
41
|
+
export * from './export.js';
|
|
42
|
+
export * from './provider.js';
|
|
43
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,cAAc,oBAAoB,CAAA;AAClC,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub Copilot Chat transcript reader for `@molecule/api-agent-transcript`.
|
|
3
|
+
*
|
|
4
|
+
* Reads the `chat.json` VS Code saves from "Chat: Export Chat…" (Command
|
|
5
|
+
* Palette, or the chat view's ⋯ menu) into a normalized `AgentSession`: each
|
|
6
|
+
* request as you typed it, each response's markdown, the model that answered,
|
|
7
|
+
* and the files the response edited.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { readFileSync } from 'node:fs'
|
|
12
|
+
* import { readTranscript, setProvider } from '@molecule/api-agent-transcript'
|
|
13
|
+
* import { provider } from '@molecule/api-agent-transcript-copilot-chat'
|
|
14
|
+
*
|
|
15
|
+
* setProvider(provider)
|
|
16
|
+
* const file = 'chat.json'
|
|
17
|
+
* const session = readTranscript({ text: readFileSync(file, 'utf8'), fileName: file })
|
|
18
|
+
* console.log(session.harness, session.model) // 'GitHub Copilot Chat', 'copilot/…'
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* @remarks
|
|
22
|
+
* - **The export is VS Code's, not Copilot's**, so any chat participant's
|
|
23
|
+
* export reads the same way. `harness` is `GitHub Copilot Chat` when the
|
|
24
|
+
* responder is Copilot, otherwise `VS Code Chat (<responder>)`.
|
|
25
|
+
* - `model` on each reply is the request's `modelId` as VS Code records it
|
|
26
|
+
* (e.g. `copilot/gpt-5.3`); the session's `model` is set when every reply
|
|
27
|
+
* used the same one.
|
|
28
|
+
* - Reply text is the response's markdown with inline file references
|
|
29
|
+
* written as `` `name` ``; thinking, tool-invocation and progress parts are
|
|
30
|
+
* not prose.
|
|
31
|
+
* - Files: each `textEditGroup` part is an edit, its text the inserted text
|
|
32
|
+
* of every edit in the group. Requests VS Code started itself
|
|
33
|
+
* (`isSystemInitiated`) contribute their reply but no user turn; requests
|
|
34
|
+
* hidden from the transcript are skipped.
|
|
35
|
+
* - Format verified 2026-09-29 against the VS Code source
|
|
36
|
+
* (`chatImportExport.ts`, `chatModel.ts` `toExport()`).
|
|
37
|
+
*
|
|
38
|
+
* @module
|
|
39
|
+
*/
|
|
40
|
+
export * from './browser-guard.js';
|
|
41
|
+
export * from './export.js';
|
|
42
|
+
export * from './provider.js';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The GitHub Copilot Chat (VS Code chat export) transcript reader.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import type { AgentTranscriptReader } from '@molecule/api-agent-transcript';
|
|
7
|
+
/**
|
|
8
|
+
* Reads the JSON VS Code's "Chat: Export Chat…" saves.
|
|
9
|
+
*/
|
|
10
|
+
export declare const provider: AgentTranscriptReader;
|
|
11
|
+
//# sourceMappingURL=provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAEV,qBAAqB,EAEtB,MAAM,gCAAgC,CAAA;AAIvC;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,qBActB,CAAA"}
|
package/dist/provider.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The GitHub Copilot Chat (VS Code chat export) transcript reader.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import { looksLikeChatExport, readChatExport } from './export.js';
|
|
7
|
+
/**
|
|
8
|
+
* Reads the JSON VS Code's "Chat: Export Chat…" saves.
|
|
9
|
+
*/
|
|
10
|
+
export const provider = {
|
|
11
|
+
format: 'copilot-chat',
|
|
12
|
+
label: 'GitHub Copilot Chat',
|
|
13
|
+
detect(input) {
|
|
14
|
+
return looksLikeChatExport(input.text);
|
|
15
|
+
},
|
|
16
|
+
read(input) {
|
|
17
|
+
if (!looksLikeChatExport(input.text)) {
|
|
18
|
+
throw new Error(`Not a GitHub Copilot Chat transcript${input.fileName ? ` (${input.fileName})` : ''}: expected the chat.json VS Code's "Export Chat…" saves.`);
|
|
19
|
+
}
|
|
20
|
+
return readChatExport(input.text);
|
|
21
|
+
},
|
|
22
|
+
};
|
package/package.json
CHANGED