@getbourdon/participants 0.2.0 → 0.2.2
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/index.cjs +3194 -29
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +327 -5
- package/dist/index.d.ts +970 -33
- package/dist/index.js +6509 -41
- package/dist/index.js.map +1 -1
- package/package.json +6 -5
- package/dist/base.d.ts +0 -88
- package/dist/base.js +0 -52
- package/dist/network-base.d.ts +0 -108
- package/dist/network-base.js +0 -248
- package/dist/readers/cascade.d.ts +0 -49
- package/dist/readers/cascade.js +0 -428
- package/dist/readers/claude-code.d.ts +0 -33
- package/dist/readers/claude-code.js +0 -552
- package/dist/readers/copilot-cli.d.ts +0 -45
- package/dist/readers/copilot-cli.js +0 -416
- package/dist/readers/copilot.d.ts +0 -59
- package/dist/readers/copilot.js +0 -413
- package/dist/readers/cursor.d.ts +0 -50
- package/dist/readers/cursor.js +0 -670
- package/dist/readers/github-copilot.d.ts +0 -34
- package/dist/readers/github-copilot.js +0 -242
- package/dist/readers/hermes.d.ts +0 -37
- package/dist/readers/hermes.js +0 -426
- package/dist/readers/openclaw.d.ts +0 -78
- package/dist/readers/openclaw.js +0 -386
- package/dist/registry.d.ts +0 -40
- package/dist/registry.js +0 -85
- package/dist/sqlite-base.d.ts +0 -65
- package/dist/sqlite-base.js +0 -163
|
@@ -1,416 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* GitHub Copilot CLI participant — normalize the `copilot` terminal agent's
|
|
3
|
-
* SQLite session store into L5. Port of `participants/copilot_cli.py`.
|
|
4
|
-
*
|
|
5
|
-
* Copilot CLI stores session history in a SQLite database at
|
|
6
|
-
* `~/.copilot/session-store.db` (override `$COPILOT_CLI_HOME`). This is distinct
|
|
7
|
-
* from:
|
|
8
|
-
* - the VS Code Copilot Chat extension (`github-copilot` network reader)
|
|
9
|
-
* - the `~/.copilot-bourdon/memory.md` convention-file participant (`copilot`)
|
|
10
|
-
* - GitHub-embedded Copilot (no local state)
|
|
11
|
-
*
|
|
12
|
-
* The schema (schema_version 4) carries `sessions` / `turns` / `checkpoints`
|
|
13
|
-
* plus `session_files` / `session_refs` / `dynamic_context_items`. The reader
|
|
14
|
-
* opens the DB read-only (`mode=ro` via {@link tryOpenReadonly}) so a live
|
|
15
|
-
* writer's lock can never block the export, probes each table defensively (a
|
|
16
|
-
* missing table degrades to "no rows" rather than raising), redacts every native
|
|
17
|
-
* string, applies the visibility filter BEFORE emission, and is deterministic.
|
|
18
|
-
* `healthCheck` never throws.
|
|
19
|
-
*/
|
|
20
|
-
import { statSync } from "node:fs";
|
|
21
|
-
import { homedir, hostname } from "node:os";
|
|
22
|
-
import { dirname, join } from "node:path";
|
|
23
|
-
import { Visibility, filterForFederation, makeAgentInfo, makeEntity, makeManifest, makeSession, makeVisibilityPolicy, } from "@getbourdon/l5";
|
|
24
|
-
import { redactText } from "@getbourdon/redaction";
|
|
25
|
-
import { ParticipantDiscoveryError, SPEC_VERSION, } from "../base.js";
|
|
26
|
-
import { tryOpenReadonly } from "../sqlite-base.js";
|
|
27
|
-
const AGENT_ID = "copilot-cli";
|
|
28
|
-
const AGENT_TYPE = "code-assistant";
|
|
29
|
-
const DISPLAY_NAME = "GitHub Copilot CLI";
|
|
30
|
-
const ROLE_NARRATIVE = "Terminal-native Copilot agent with full filesystem + tool access. " +
|
|
31
|
-
"Runs multi-turn sessions with checkpoints, file edits, and git " +
|
|
32
|
-
"operations. The CLI surface has the deepest tool integration of " +
|
|
33
|
-
"all Copilot surfaces — shell, grep, edit, git — and persists " +
|
|
34
|
-
"rich session history locally in SQLite.";
|
|
35
|
-
const DEFAULT_POLICY = makeVisibilityPolicy({
|
|
36
|
-
default: Visibility.TEAM,
|
|
37
|
-
private_tags: ["personal", "financial", "credential", "health", "family", "legal"],
|
|
38
|
-
team_tags: ["copilot-cli", "copilot", "terminal", "workspace"],
|
|
39
|
-
});
|
|
40
|
-
const DB_FILENAME = "session-store.db";
|
|
41
|
-
const COPILOT_DIR_NAME = ".copilot";
|
|
42
|
-
const MAX_SUMMARY_CHARS = 260;
|
|
43
|
-
const MAX_KEY_ACTIONS = 6;
|
|
44
|
-
const MAX_KEY_ACTION_CHARS = 280;
|
|
45
|
-
// -- Path resolution ----------------------------------------------------------
|
|
46
|
-
/**
|
|
47
|
-
* Conventional `~/.copilot/` directory. Respects the `COPILOT_CLI_HOME`
|
|
48
|
-
* environment-variable override (mirrors `default_copilot_cli_dir`).
|
|
49
|
-
*/
|
|
50
|
-
export function defaultCopilotCliDir() {
|
|
51
|
-
const env = process.env.COPILOT_CLI_HOME;
|
|
52
|
-
if (env)
|
|
53
|
-
return env;
|
|
54
|
-
return join(homedir(), COPILOT_DIR_NAME);
|
|
55
|
-
}
|
|
56
|
-
/** Path to `session-store.db` under the given (or conventional) copilot dir. */
|
|
57
|
-
function defaultCopilotCliDbPath(copilotDir) {
|
|
58
|
-
return join(copilotDir ?? defaultCopilotCliDir(), DB_FILENAME);
|
|
59
|
-
}
|
|
60
|
-
function isFile(p) {
|
|
61
|
-
try {
|
|
62
|
-
return statSync(p).isFile();
|
|
63
|
-
}
|
|
64
|
-
catch {
|
|
65
|
-
return false;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
function isDir(p) {
|
|
69
|
-
try {
|
|
70
|
-
return statSync(p).isDirectory();
|
|
71
|
-
}
|
|
72
|
-
catch {
|
|
73
|
-
return false;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
// -- Text helpers -------------------------------------------------------------
|
|
77
|
-
/** Redact secrets + clamp to the native-memory limit (`_safe_native_memory_text`). */
|
|
78
|
-
function safeNativeMemoryText(value, limit = 180) {
|
|
79
|
-
return redactText(value, limit);
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Collapse whitespace and clamp with a single-char ellipsis (mirrors the
|
|
83
|
-
* oracle's `_bounded`). NOTE: distinct from {@link redactText}'s `...` clamp —
|
|
84
|
-
* this one uses `…` (U+2026) and does no redaction.
|
|
85
|
-
*/
|
|
86
|
-
function bounded(value, limit) {
|
|
87
|
-
const normalized = value.split(/\s+/).filter(Boolean).join(" ");
|
|
88
|
-
if (normalized.length <= limit)
|
|
89
|
-
return normalized;
|
|
90
|
-
return normalized.slice(0, limit - 1).replace(/\s+$/, "") + "…";
|
|
91
|
-
}
|
|
92
|
-
// -- SQLite (read-only) -------------------------------------------------------
|
|
93
|
-
/** Run a query and return rows as plain objects. Never raises (a missing table
|
|
94
|
-
* or any SQLite error degrades to `[]`, matching the oracle's `_query_db`). */
|
|
95
|
-
function queryDb(db, sql, params = []) {
|
|
96
|
-
try {
|
|
97
|
-
return db.prepare(sql).all(...params);
|
|
98
|
-
}
|
|
99
|
-
catch {
|
|
100
|
-
return [];
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
function extractSessions(db, since) {
|
|
104
|
-
let sql = "SELECT id, cwd, repository, branch, summary, created_at, updated_at FROM sessions";
|
|
105
|
-
const params = [];
|
|
106
|
-
if (since) {
|
|
107
|
-
sql += " WHERE created_at >= ?";
|
|
108
|
-
params.push(since);
|
|
109
|
-
}
|
|
110
|
-
sql += " ORDER BY created_at DESC LIMIT 200";
|
|
111
|
-
return queryDb(db, sql, params);
|
|
112
|
-
}
|
|
113
|
-
function extractSessionFiles(db, sessionId) {
|
|
114
|
-
const rows = queryDb(db, "SELECT file_path FROM session_files WHERE session_id = ? LIMIT 20", [sessionId]);
|
|
115
|
-
const out = [];
|
|
116
|
-
for (const r of rows) {
|
|
117
|
-
const fp = r["file_path"];
|
|
118
|
-
if (fp)
|
|
119
|
-
out.push(String(fp));
|
|
120
|
-
}
|
|
121
|
-
return out;
|
|
122
|
-
}
|
|
123
|
-
function extractSessionRefs(db, sessionId) {
|
|
124
|
-
const rows = queryDb(db, "SELECT ref_type, ref_value FROM session_refs WHERE session_id = ?", [sessionId]);
|
|
125
|
-
return rows.map((r) => ({
|
|
126
|
-
ref_type: String(r["ref_type"] ?? ""),
|
|
127
|
-
ref_value: String(r["ref_value"] ?? ""),
|
|
128
|
-
}));
|
|
129
|
-
}
|
|
130
|
-
function extractCheckpoints(db, sessionId) {
|
|
131
|
-
return queryDb(db, "SELECT checkpoint_number, title, overview FROM checkpoints " +
|
|
132
|
-
"WHERE session_id = ? ORDER BY checkpoint_number", [sessionId]);
|
|
133
|
-
}
|
|
134
|
-
function extractDynamicContext(db) {
|
|
135
|
-
return queryDb(db, "SELECT repository, branch, src, name, description, content, read_count, count " +
|
|
136
|
-
"FROM dynamic_context_items ORDER BY count DESC LIMIT 50");
|
|
137
|
-
}
|
|
138
|
-
function extractTurnCount(db, sessionId) {
|
|
139
|
-
const rows = queryDb(db, "SELECT COUNT(*) as cnt FROM turns WHERE session_id = ?", [sessionId]);
|
|
140
|
-
const first = rows[0];
|
|
141
|
-
return first ? Number(first["cnt"] ?? 0) || 0 : 0;
|
|
142
|
-
}
|
|
143
|
-
// -- Conversion to Bourdon types ----------------------------------------------
|
|
144
|
-
function sessionToBourdon(raw, files, refs, checkpoints, turnCount) {
|
|
145
|
-
const created = raw["created_at"] ? String(raw["created_at"]) : "";
|
|
146
|
-
const dateStr = created ? created.slice(0, 10) : "";
|
|
147
|
-
const keyActions = [];
|
|
148
|
-
if (raw["summary"]) {
|
|
149
|
-
keyActions.push(bounded(safeNativeMemoryText(String(raw["summary"])), MAX_KEY_ACTION_CHARS));
|
|
150
|
-
}
|
|
151
|
-
for (const cp of checkpoints.slice(0, 3)) {
|
|
152
|
-
if (cp["title"]) {
|
|
153
|
-
keyActions.push(bounded(`checkpoint: ${safeNativeMemoryText(String(cp["title"]))}`, MAX_KEY_ACTION_CHARS));
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
if (turnCount) {
|
|
157
|
-
keyActions.push(`turns: ${turnCount}`);
|
|
158
|
-
}
|
|
159
|
-
for (const ref of refs.slice(0, 3)) {
|
|
160
|
-
const refLabel = `${ref.ref_type}: ${ref.ref_value}`;
|
|
161
|
-
keyActions.push(bounded(refLabel, MAX_KEY_ACTION_CHARS));
|
|
162
|
-
}
|
|
163
|
-
const projectFocus = [];
|
|
164
|
-
if (raw["repository"])
|
|
165
|
-
projectFocus.push(String(raw["repository"]));
|
|
166
|
-
return makeSession({
|
|
167
|
-
date: dateStr,
|
|
168
|
-
cwd: raw["cwd"] ? String(raw["cwd"]) : undefined,
|
|
169
|
-
project_focus: projectFocus,
|
|
170
|
-
key_actions: keyActions.slice(0, MAX_KEY_ACTIONS),
|
|
171
|
-
files_touched: files.slice(0, 20),
|
|
172
|
-
visibility: Visibility.TEAM,
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
function entitiesFromSessionsAndContext(sessions, dynamicContext) {
|
|
176
|
-
const entities = new Map();
|
|
177
|
-
// Repositories as project entities.
|
|
178
|
-
for (const raw of sessions) {
|
|
179
|
-
const repo = raw["repository"] ? String(raw["repository"]) : "";
|
|
180
|
-
if (repo && !entities.has(repo)) {
|
|
181
|
-
const created = raw["created_at"] ? String(raw["created_at"]) : "";
|
|
182
|
-
const lastTouched = created.slice(0, 10) || null;
|
|
183
|
-
entities.set(repo, makeEntity({
|
|
184
|
-
name: repo,
|
|
185
|
-
type: "project",
|
|
186
|
-
summary: "Repository worked on via Copilot CLI.",
|
|
187
|
-
last_touched: lastTouched ?? undefined,
|
|
188
|
-
tags: ["copilot-cli", "project"],
|
|
189
|
-
visibility: Visibility.TEAM,
|
|
190
|
-
}));
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
// Dynamic context items as knowledge entities.
|
|
194
|
-
for (const ctx of dynamicContext) {
|
|
195
|
-
const name = ctx["name"] ? String(ctx["name"]) : "";
|
|
196
|
-
if (!name || entities.has(name))
|
|
197
|
-
continue;
|
|
198
|
-
const desc = ctx["description"] ? String(ctx["description"]) : "";
|
|
199
|
-
const content = ctx["content"] ? String(ctx["content"]) : "";
|
|
200
|
-
let summaryText = desc || content;
|
|
201
|
-
if (summaryText) {
|
|
202
|
-
summaryText = bounded(safeNativeMemoryText(summaryText), MAX_SUMMARY_CHARS);
|
|
203
|
-
}
|
|
204
|
-
entities.set(name, makeEntity({
|
|
205
|
-
name,
|
|
206
|
-
type: "dynamic-context",
|
|
207
|
-
summary: summaryText || undefined,
|
|
208
|
-
last_touched: undefined,
|
|
209
|
-
tags: ["copilot-cli", "dynamic-context", ctx["src"] ? String(ctx["src"]) : "unknown"],
|
|
210
|
-
visibility: Visibility.TEAM,
|
|
211
|
-
}));
|
|
212
|
-
}
|
|
213
|
-
return [...entities.values()];
|
|
214
|
-
}
|
|
215
|
-
/** UTC ISO datetime with `+00:00` offset (matching Python `isoformat`). */
|
|
216
|
-
function toUtcIso(d) {
|
|
217
|
-
return d.toISOString().replace(/\.\d{3}Z$/, "+00:00").replace(/Z$/, "+00:00");
|
|
218
|
-
}
|
|
219
|
-
// -- Participant --------------------------------------------------------------
|
|
220
|
-
/**
|
|
221
|
-
* External participant for GitHub Copilot CLI (`~/.copilot/session-store.db`).
|
|
222
|
-
* Reads the SQLite database read-only (never locks the live db).
|
|
223
|
-
*/
|
|
224
|
-
export class CopilotCliParticipant {
|
|
225
|
-
agentId = AGENT_ID;
|
|
226
|
-
agentType = AGENT_TYPE;
|
|
227
|
-
displayName = DISPLAY_NAME;
|
|
228
|
-
nativePath;
|
|
229
|
-
copilotDir;
|
|
230
|
-
/** Conventional `~/.copilot` dir used by the setup wizard's detection. */
|
|
231
|
-
static defaultNativePath(home) {
|
|
232
|
-
if (home)
|
|
233
|
-
return join(home, COPILOT_DIR_NAME);
|
|
234
|
-
return defaultCopilotCliDir();
|
|
235
|
-
}
|
|
236
|
-
constructor(copilotDir) {
|
|
237
|
-
this.copilotDir = copilotDir ?? null;
|
|
238
|
-
this.nativePath = this.copilotDir ?? defaultCopilotCliDir();
|
|
239
|
-
}
|
|
240
|
-
// -- Protocol surface -------------------------------------------------------
|
|
241
|
-
discover() {
|
|
242
|
-
const dbPath = defaultCopilotCliDbPath(this.copilotDir);
|
|
243
|
-
if (!isFile(dbPath)) {
|
|
244
|
-
throw new ParticipantDiscoveryError(`Copilot CLI session-store.db not found at ${dbPath}. ` +
|
|
245
|
-
"The Copilot CLI agent must be run at least once to create this database.");
|
|
246
|
-
}
|
|
247
|
-
let dbSize = 0;
|
|
248
|
-
try {
|
|
249
|
-
dbSize = statSync(dbPath).size;
|
|
250
|
-
}
|
|
251
|
-
catch {
|
|
252
|
-
dbSize = 0;
|
|
253
|
-
}
|
|
254
|
-
return {
|
|
255
|
-
path: dirname(dbPath),
|
|
256
|
-
version: "schema-v4",
|
|
257
|
-
metadata: { db_path: dbPath, db_size_bytes: dbSize },
|
|
258
|
-
};
|
|
259
|
-
}
|
|
260
|
-
exportSessions(since, limit = 100) {
|
|
261
|
-
const dbPath = defaultCopilotCliDbPath(this.copilotDir);
|
|
262
|
-
const db = tryOpenReadonly(dbPath);
|
|
263
|
-
if (!db)
|
|
264
|
-
return [];
|
|
265
|
-
try {
|
|
266
|
-
const sinceIso = since ? toUtcIso(since) : null;
|
|
267
|
-
const rawSessions = extractSessions(db, sinceIso);
|
|
268
|
-
const sessions = [];
|
|
269
|
-
for (const raw of rawSessions.slice(0, limit)) {
|
|
270
|
-
const sid = String(raw["id"]);
|
|
271
|
-
const files = extractSessionFiles(db, sid);
|
|
272
|
-
const refs = extractSessionRefs(db, sid);
|
|
273
|
-
const checkpoints = extractCheckpoints(db, sid);
|
|
274
|
-
const turnCount = extractTurnCount(db, sid);
|
|
275
|
-
sessions.push(sessionToBourdon(raw, files, refs, checkpoints, turnCount));
|
|
276
|
-
}
|
|
277
|
-
return sessions;
|
|
278
|
-
}
|
|
279
|
-
finally {
|
|
280
|
-
db.close();
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
exportL5(since) {
|
|
284
|
-
const dbPath = defaultCopilotCliDbPath(this.copilotDir);
|
|
285
|
-
const db = tryOpenReadonly(dbPath);
|
|
286
|
-
if (!db)
|
|
287
|
-
return this.emptyManifest();
|
|
288
|
-
try {
|
|
289
|
-
const sinceIso = since ? toUtcIso(since) : null;
|
|
290
|
-
const rawSessions = extractSessions(db, sinceIso);
|
|
291
|
-
const dynamicContext = extractDynamicContext(db);
|
|
292
|
-
const sessions = [];
|
|
293
|
-
for (const raw of rawSessions.slice(0, 100)) {
|
|
294
|
-
const sid = String(raw["id"]);
|
|
295
|
-
const files = extractSessionFiles(db, sid);
|
|
296
|
-
const refs = extractSessionRefs(db, sid);
|
|
297
|
-
const checkpoints = extractCheckpoints(db, sid);
|
|
298
|
-
const turnCount = extractTurnCount(db, sid);
|
|
299
|
-
sessions.push(sessionToBourdon(raw, files, refs, checkpoints, turnCount));
|
|
300
|
-
}
|
|
301
|
-
const entities = entitiesFromSessionsAndContext(rawSessions, dynamicContext);
|
|
302
|
-
const visibleEntities = filterForFederation(entities, DEFAULT_POLICY);
|
|
303
|
-
return makeManifest({
|
|
304
|
-
spec_version: SPEC_VERSION,
|
|
305
|
-
agent: makeAgentInfo({
|
|
306
|
-
id: AGENT_ID,
|
|
307
|
-
type: AGENT_TYPE,
|
|
308
|
-
instance: hostname() || "unknown",
|
|
309
|
-
spec_version_compat: `>=${SPEC_VERSION}`,
|
|
310
|
-
role_narrative: ROLE_NARRATIVE,
|
|
311
|
-
}),
|
|
312
|
-
last_updated: new Date().toISOString(),
|
|
313
|
-
capabilities: [
|
|
314
|
-
"terminal-agent",
|
|
315
|
-
"file-edit",
|
|
316
|
-
"shell-execution",
|
|
317
|
-
"git-operations",
|
|
318
|
-
"multi-turn-sessions",
|
|
319
|
-
"checkpoints",
|
|
320
|
-
"dynamic-context",
|
|
321
|
-
],
|
|
322
|
-
recent_sessions: sessions,
|
|
323
|
-
known_entities: visibleEntities,
|
|
324
|
-
visibility_policy: DEFAULT_POLICY,
|
|
325
|
-
});
|
|
326
|
-
}
|
|
327
|
-
finally {
|
|
328
|
-
db.close();
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
healthCheck() {
|
|
332
|
-
try {
|
|
333
|
-
const copilotDir = this.copilotDir ?? defaultCopilotCliDir();
|
|
334
|
-
if (!isDir(copilotDir)) {
|
|
335
|
-
return {
|
|
336
|
-
status: "blocked",
|
|
337
|
-
reason: `Copilot CLI directory not found at ${copilotDir}.`,
|
|
338
|
-
details: { expected_path: copilotDir },
|
|
339
|
-
proposedFix: "Run the Copilot CLI agent (`copilot` or `gh copilot`) at least once " +
|
|
340
|
-
"to create the session store.",
|
|
341
|
-
};
|
|
342
|
-
}
|
|
343
|
-
const dbPath = defaultCopilotCliDbPath(copilotDir);
|
|
344
|
-
if (!isFile(dbPath)) {
|
|
345
|
-
return {
|
|
346
|
-
status: "blocked",
|
|
347
|
-
reason: `session-store.db not found at ${dbPath}.`,
|
|
348
|
-
details: { expected_db: dbPath },
|
|
349
|
-
proposedFix: "Run the Copilot CLI agent at least once. The session-store.db is " +
|
|
350
|
-
"created on first use.",
|
|
351
|
-
};
|
|
352
|
-
}
|
|
353
|
-
const db = tryOpenReadonly(dbPath);
|
|
354
|
-
if (!db) {
|
|
355
|
-
return {
|
|
356
|
-
status: "degraded",
|
|
357
|
-
reason: "Cannot copy session-store.db for reading.",
|
|
358
|
-
details: { db_path: dbPath },
|
|
359
|
-
proposedFix: "Check file permissions on the session-store.db.",
|
|
360
|
-
};
|
|
361
|
-
}
|
|
362
|
-
try {
|
|
363
|
-
const rawSessions = extractSessions(db);
|
|
364
|
-
const dynamicContext = extractDynamicContext(db);
|
|
365
|
-
const totalTurns = queryDb(db, "SELECT COUNT(*) as cnt FROM turns");
|
|
366
|
-
const first = totalTurns[0];
|
|
367
|
-
let dbSize = 0;
|
|
368
|
-
try {
|
|
369
|
-
dbSize = statSync(dbPath).size;
|
|
370
|
-
}
|
|
371
|
-
catch {
|
|
372
|
-
dbSize = 0;
|
|
373
|
-
}
|
|
374
|
-
return {
|
|
375
|
-
status: "ok",
|
|
376
|
-
details: {
|
|
377
|
-
db_path: dbPath,
|
|
378
|
-
db_size_bytes: dbSize,
|
|
379
|
-
session_count: rawSessions.length,
|
|
380
|
-
total_turns: first ? Number(first["cnt"] ?? 0) || 0 : 0,
|
|
381
|
-
dynamic_context_items: dynamicContext.length,
|
|
382
|
-
},
|
|
383
|
-
};
|
|
384
|
-
}
|
|
385
|
-
finally {
|
|
386
|
-
db.close();
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
catch (err) {
|
|
390
|
-
// healthCheck must NEVER raise (contract).
|
|
391
|
-
return {
|
|
392
|
-
status: "degraded",
|
|
393
|
-
reason: `unexpected error: ${String(err)}`,
|
|
394
|
-
details: {},
|
|
395
|
-
};
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
// -- Internal ---------------------------------------------------------------
|
|
399
|
-
emptyManifest() {
|
|
400
|
-
return makeManifest({
|
|
401
|
-
spec_version: SPEC_VERSION,
|
|
402
|
-
agent: makeAgentInfo({
|
|
403
|
-
id: AGENT_ID,
|
|
404
|
-
type: AGENT_TYPE,
|
|
405
|
-
instance: hostname() || "unknown",
|
|
406
|
-
spec_version_compat: `>=${SPEC_VERSION}`,
|
|
407
|
-
role_narrative: ROLE_NARRATIVE,
|
|
408
|
-
}),
|
|
409
|
-
last_updated: new Date().toISOString(),
|
|
410
|
-
capabilities: [],
|
|
411
|
-
recent_sessions: [],
|
|
412
|
-
known_entities: [],
|
|
413
|
-
visibility_policy: DEFAULT_POLICY,
|
|
414
|
-
});
|
|
415
|
-
}
|
|
416
|
-
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* GitHub Copilot (local convention) participant — reads the convention-based
|
|
3
|
-
* memory file at `~/.copilot-bourdon/memory.md`. Port of `participants/copilot.py`.
|
|
4
|
-
*
|
|
5
|
-
* Copilot has no accessible local session index (its reasoning is cloud-side and
|
|
6
|
-
* its native memory is not exposed on disk), so — like the Codex pre-distillation
|
|
7
|
-
* fallback — this reader normalizes a user-maintained convention file into a
|
|
8
|
-
* Bourdon L5 manifest. The file is YAML front-matter (structured `entities:` /
|
|
9
|
-
* `sessions:`) followed by an optional freeform markdown body that Copilot Chat
|
|
10
|
-
* reads as plain context but this reader ignores.
|
|
11
|
-
*
|
|
12
|
-
* NOT the cloud GitHub-Copilot network adapter ({@link GitHubCopilotParticipant})
|
|
13
|
-
* and NOT the Copilot CLI SQLite reader.
|
|
14
|
-
*
|
|
15
|
-
* Paths checked (in order):
|
|
16
|
-
* 1. `COPILOT_BOURDON_HOME` env-var override
|
|
17
|
-
* 2. `~/.copilot-bourdon/` (default convention path)
|
|
18
|
-
*
|
|
19
|
-
* Defensive throughout: a missing convention directory raises
|
|
20
|
-
* {@link ParticipantDiscoveryError} from `discover()`; malformed YAML degrades to
|
|
21
|
-
* an empty manifest rather than raising; `healthCheck` never throws.
|
|
22
|
-
*/
|
|
23
|
-
import { type L5ManifestModel, type SessionModel } from "@getbourdon/l5";
|
|
24
|
-
import { type AgentStore, type BourdonParticipant, type HealthStatus } from "../base.js";
|
|
25
|
-
/**
|
|
26
|
-
* Return the conventional `~/.copilot-bourdon/` directory path. Respects the
|
|
27
|
-
* `COPILOT_BOURDON_HOME` env-var override (returned verbatim, even if absent;
|
|
28
|
-
* the directory is not created here).
|
|
29
|
-
*/
|
|
30
|
-
export declare function defaultCopilotBourdonDir(): string;
|
|
31
|
-
/** Return the path to the convention memory file. */
|
|
32
|
-
export declare function defaultCopilotMemoryPath(copilotDir?: string | null): string;
|
|
33
|
-
/** Diagnostic summary of the copilot-bourdon memory file (`bourdon copilot
|
|
34
|
-
* doctor`). Never raises. */
|
|
35
|
-
export declare function inspectCopilotMemory(copilotDir?: string | null): Record<string, unknown>;
|
|
36
|
-
/**
|
|
37
|
-
* External participant for GitHub Copilot via `~/.copilot-bourdon/memory.md`.
|
|
38
|
-
* Implements {@link BourdonParticipant} structurally.
|
|
39
|
-
*/
|
|
40
|
-
export declare class CopilotParticipant implements BourdonParticipant {
|
|
41
|
-
agentId: string;
|
|
42
|
-
agentType: string;
|
|
43
|
-
displayName: string;
|
|
44
|
-
nativePath: string;
|
|
45
|
-
/** Conventional `~/.copilot-bourdon` dir used by the setup wizard's detection. */
|
|
46
|
-
static defaultNativePath(home?: string): string;
|
|
47
|
-
private readonly copilotDir;
|
|
48
|
-
constructor(copilotDir?: string | null);
|
|
49
|
-
discover(): AgentStore;
|
|
50
|
-
exportSessions(since?: Date, limit?: number): SessionModel[];
|
|
51
|
-
exportL5(since?: Date): L5ManifestModel;
|
|
52
|
-
healthCheck(): HealthStatus;
|
|
53
|
-
private read;
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Create `~/.copilot-bourdon/memory.md` with a starter template. Returns the
|
|
57
|
-
* written path. Throws when the file already exists unless `force` is true.
|
|
58
|
-
*/
|
|
59
|
-
export declare function initMemoryFile(copilotDir?: string | null, force?: boolean): string;
|