@ai-devkit/agent-manager 0.33.0 → 0.34.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/AgentManager.d.ts +11 -2
- package/dist/AgentManager.d.ts.map +1 -1
- package/dist/AgentManager.js +37 -6
- package/dist/AgentManager.js.map +1 -1
- package/dist/__tests__/AgentManager.test.js +212 -5
- package/dist/__tests__/AgentManager.test.js.map +1 -1
- package/dist/__tests__/capacity/codex.test.js +2 -1
- package/dist/__tests__/capacity/codex.test.js.map +1 -1
- package/dist/__tests__/capacity/index.test.js +6 -3
- package/dist/__tests__/capacity/index.test.js.map +1 -1
- package/dist/__tests__/capacity/zai.test.js +213 -0
- package/dist/__tests__/capacity/zai.test.js.map +1 -0
- package/dist/__tests__/{adapters → providers/copilot}/CopilotAdapter.test.js +19 -14
- package/dist/__tests__/providers/copilot/CopilotAdapter.test.js.map +1 -0
- package/dist/__tests__/{adapters → providers/gemini}/GeminiCliAdapter.test.js +37 -29
- package/dist/__tests__/providers/gemini/GeminiCliAdapter.test.js.map +1 -0
- package/dist/__tests__/providers/opencode/OpenCodeAdapter.test.js +189 -0
- package/dist/__tests__/providers/opencode/OpenCodeAdapter.test.js.map +1 -0
- package/dist/__tests__/providers/opencode/OpenCodeAgentMapper.test.js +89 -0
- package/dist/__tests__/providers/opencode/OpenCodeAgentMapper.test.js.map +1 -0
- package/dist/__tests__/providers/opencode/OpenCodeSessionLocator.test.js +94 -0
- package/dist/__tests__/providers/opencode/OpenCodeSessionLocator.test.js.map +1 -0
- package/dist/__tests__/providers/opencode/OpenCodeSessionParser.test.js +147 -0
- package/dist/__tests__/providers/opencode/OpenCodeSessionParser.test.js.map +1 -0
- package/dist/__tests__/runtime/HerdrAgentDiscovery.test.js +164 -0
- package/dist/__tests__/runtime/HerdrAgentDiscovery.test.js.map +1 -0
- package/dist/__tests__/runtime/HerdrAgentRuntime.test.js +37 -1
- package/dist/__tests__/runtime/HerdrAgentRuntime.test.js.map +1 -1
- package/dist/__tests__/utils/AgentRegistry.test.js +20 -13
- package/dist/__tests__/utils/AgentRegistry.test.js.map +1 -1
- package/dist/adapters/index.d.ts +3 -3
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/index.js +3 -3
- package/dist/adapters/index.js.map +1 -1
- package/dist/capacity/codex.d.ts +1 -0
- package/dist/capacity/codex.d.ts.map +1 -1
- package/dist/capacity/codex.js +9 -4
- package/dist/capacity/codex.js.map +1 -1
- package/dist/capacity/index.d.ts +8 -0
- package/dist/capacity/index.d.ts.map +1 -1
- package/dist/capacity/index.js +10 -9
- package/dist/capacity/index.js.map +1 -1
- package/dist/capacity/types.d.ts +8 -0
- package/dist/capacity/types.d.ts.map +1 -1
- package/dist/capacity/types.js.map +1 -1
- package/dist/capacity/zai.d.ts +14 -0
- package/dist/capacity/zai.d.ts.map +1 -0
- package/dist/capacity/zai.js +203 -0
- package/dist/capacity/zai.js.map +1 -0
- package/dist/index.d.ts +8 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -4
- package/dist/index.js.map +1 -1
- package/dist/{adapters → providers/copilot}/CopilotAdapter.d.ts +11 -25
- package/dist/providers/copilot/CopilotAdapter.d.ts.map +1 -0
- package/dist/providers/copilot/CopilotAdapter.js +108 -0
- package/dist/providers/copilot/CopilotAdapter.js.map +1 -0
- package/dist/providers/copilot/CopilotAgentMapper.d.ts +9 -0
- package/dist/providers/copilot/CopilotAgentMapper.d.ts.map +1 -0
- package/dist/providers/copilot/CopilotAgentMapper.js +37 -0
- package/dist/providers/copilot/CopilotAgentMapper.js.map +1 -0
- package/dist/providers/copilot/CopilotSessionLocator.d.ts +19 -0
- package/dist/providers/copilot/CopilotSessionLocator.d.ts.map +1 -0
- package/dist/providers/copilot/CopilotSessionLocator.js +41 -0
- package/dist/providers/copilot/CopilotSessionLocator.js.map +1 -0
- package/dist/providers/copilot/CopilotSessionParser.d.ts +30 -0
- package/dist/providers/copilot/CopilotSessionParser.d.ts.map +1 -0
- package/dist/providers/copilot/CopilotSessionParser.js +181 -0
- package/dist/providers/copilot/CopilotSessionParser.js.map +1 -0
- package/dist/providers/gemini/GeminiAgentMapper.d.ts +9 -0
- package/dist/providers/gemini/GeminiAgentMapper.d.ts.map +1 -0
- package/dist/providers/gemini/GeminiAgentMapper.js +37 -0
- package/dist/providers/gemini/GeminiAgentMapper.js.map +1 -0
- package/dist/providers/gemini/GeminiCliAdapter.d.ts +52 -0
- package/dist/providers/gemini/GeminiCliAdapter.d.ts.map +1 -0
- package/dist/providers/gemini/GeminiCliAdapter.js +188 -0
- package/dist/providers/gemini/GeminiCliAdapter.js.map +1 -0
- package/dist/providers/gemini/GeminiSessionLocator.d.ts +30 -0
- package/dist/providers/gemini/GeminiSessionLocator.d.ts.map +1 -0
- package/dist/providers/gemini/GeminiSessionLocator.js +142 -0
- package/dist/providers/gemini/GeminiSessionLocator.js.map +1 -0
- package/dist/providers/gemini/GeminiSessionParser.d.ts +94 -0
- package/dist/providers/gemini/GeminiSessionParser.d.ts.map +1 -0
- package/dist/providers/gemini/GeminiSessionParser.js +166 -0
- package/dist/providers/gemini/GeminiSessionParser.js.map +1 -0
- package/dist/{adapters → providers/opencode}/OpenCodeAdapter.d.ts +6 -12
- package/dist/providers/opencode/OpenCodeAdapter.d.ts.map +1 -0
- package/dist/providers/opencode/OpenCodeAdapter.js +86 -0
- package/dist/providers/opencode/OpenCodeAdapter.js.map +1 -0
- package/dist/providers/opencode/OpenCodeAgentMapper.d.ts +11 -0
- package/dist/providers/opencode/OpenCodeAgentMapper.d.ts.map +1 -0
- package/dist/providers/opencode/OpenCodeAgentMapper.js +50 -0
- package/dist/providers/opencode/OpenCodeAgentMapper.js.map +1 -0
- package/dist/providers/opencode/OpenCodeSessionLocator.d.ts +21 -0
- package/dist/providers/opencode/OpenCodeSessionLocator.d.ts.map +1 -0
- package/dist/providers/opencode/OpenCodeSessionLocator.js +99 -0
- package/dist/providers/opencode/OpenCodeSessionLocator.js.map +1 -0
- package/dist/providers/opencode/OpenCodeSessionParser.d.ts +18 -0
- package/dist/providers/opencode/OpenCodeSessionParser.d.ts.map +1 -0
- package/dist/providers/opencode/OpenCodeSessionParser.js +104 -0
- package/dist/providers/opencode/OpenCodeSessionParser.js.map +1 -0
- package/dist/runtime/herdr/HerdrAgentDiscovery.d.ts +18 -0
- package/dist/runtime/herdr/HerdrAgentDiscovery.d.ts.map +1 -0
- package/dist/runtime/herdr/HerdrAgentDiscovery.js +183 -0
- package/dist/runtime/herdr/HerdrAgentDiscovery.js.map +1 -0
- package/dist/runtime/herdr/HerdrAgentRuntime.d.ts +5 -0
- package/dist/runtime/herdr/HerdrAgentRuntime.d.ts.map +1 -1
- package/dist/runtime/herdr/HerdrAgentRuntime.js +26 -8
- package/dist/runtime/herdr/HerdrAgentRuntime.js.map +1 -1
- package/dist/runtime/herdr/HerdrResponseParsers.d.ts +2 -0
- package/dist/runtime/herdr/HerdrResponseParsers.d.ts.map +1 -1
- package/dist/runtime/herdr/HerdrResponseParsers.js +12 -1
- package/dist/runtime/herdr/HerdrResponseParsers.js.map +1 -1
- package/dist/utils/AgentRegistry.d.ts.map +1 -1
- package/dist/utils/AgentRegistry.js +5 -5
- package/dist/utils/AgentRegistry.js.map +1 -1
- package/package.json +1 -1
- package/src/AgentManager.ts +67 -5
- package/src/__tests__/AgentManager.test.ts +231 -5
- package/src/__tests__/capacity/codex.test.ts +94 -26
- package/src/__tests__/capacity/fixtures/zai-auth.json +6 -0
- package/src/__tests__/capacity/fixtures/zai-quota-invalid.json +7 -0
- package/src/__tests__/capacity/fixtures/zai-quota.json +38 -0
- package/src/__tests__/capacity/index.test.ts +10 -3
- package/src/__tests__/capacity/zai.test.ts +186 -0
- package/src/__tests__/{adapters → providers/copilot}/CopilotAdapter.test.ts +13 -16
- package/src/__tests__/{adapters → providers/gemini}/GeminiCliAdapter.test.ts +39 -31
- package/src/__tests__/providers/opencode/OpenCodeAdapter.test.ts +197 -0
- package/src/__tests__/providers/opencode/OpenCodeAgentMapper.test.ts +83 -0
- package/src/__tests__/providers/opencode/OpenCodeSessionLocator.test.ts +84 -0
- package/src/__tests__/providers/opencode/OpenCodeSessionParser.test.ts +148 -0
- package/src/__tests__/runtime/HerdrAgentDiscovery.test.ts +131 -0
- package/src/__tests__/runtime/HerdrAgentRuntime.test.ts +20 -1
- package/src/__tests__/utils/AgentRegistry.test.ts +20 -10
- package/src/adapters/index.ts +3 -3
- package/src/capacity/codex.ts +96 -28
- package/src/capacity/index.ts +29 -11
- package/src/capacity/types.ts +8 -0
- package/src/capacity/zai.ts +237 -0
- package/src/index.ts +18 -6
- package/src/providers/copilot/CopilotAdapter.ts +145 -0
- package/src/providers/copilot/CopilotAgentMapper.ts +36 -0
- package/src/providers/copilot/CopilotSessionLocator.ts +57 -0
- package/src/providers/copilot/CopilotSessionParser.ts +289 -0
- package/src/providers/gemini/GeminiAgentMapper.ts +36 -0
- package/src/providers/gemini/GeminiCliAdapter.ts +266 -0
- package/src/providers/gemini/GeminiSessionLocator.ts +183 -0
- package/src/providers/gemini/GeminiSessionParser.ts +271 -0
- package/src/providers/opencode/OpenCodeAdapter.ts +112 -0
- package/src/providers/opencode/OpenCodeAgentMapper.ts +61 -0
- package/src/providers/opencode/OpenCodeSessionLocator.ts +123 -0
- package/src/providers/opencode/OpenCodeSessionParser.ts +145 -0
- package/src/runtime/herdr/HerdrAgentDiscovery.ts +178 -0
- package/src/runtime/herdr/HerdrAgentRuntime.ts +33 -7
- package/src/runtime/herdr/HerdrResponseParsers.ts +11 -1
- package/src/utils/AgentRegistry.ts +8 -6
- package/dist/__tests__/adapters/CopilotAdapter.test.js.map +0 -1
- package/dist/__tests__/adapters/GeminiCliAdapter.test.js.map +0 -1
- package/dist/__tests__/adapters/OpenCodeAdapter.test.js +0 -635
- package/dist/__tests__/adapters/OpenCodeAdapter.test.js.map +0 -1
- package/dist/adapters/CopilotAdapter.d.ts.map +0 -1
- package/dist/adapters/CopilotAdapter.js +0 -329
- package/dist/adapters/CopilotAdapter.js.map +0 -1
- package/dist/adapters/GeminiCliAdapter.d.ts +0 -98
- package/dist/adapters/GeminiCliAdapter.d.ts.map +0 -1
- package/dist/adapters/GeminiCliAdapter.js +0 -513
- package/dist/adapters/GeminiCliAdapter.js.map +0 -1
- package/dist/adapters/OpenCodeAdapter.d.ts.map +0 -1
- package/dist/adapters/OpenCodeAdapter.js +0 -286
- package/dist/adapters/OpenCodeAdapter.js.map +0 -1
- package/src/__tests__/adapters/OpenCodeAdapter.test.ts +0 -543
- package/src/adapters/CopilotAdapter.ts +0 -483
- package/src/adapters/GeminiCliAdapter.ts +0 -699
- package/src/adapters/OpenCodeAdapter.ts +0 -369
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenCode Adapter
|
|
3
|
+
*
|
|
4
|
+
* Detects running OpenCode agents by:
|
|
5
|
+
* 1. Filtering OpenCode processes from a shared asynchronous process snapshot
|
|
6
|
+
* 2. Using snapshot CWD and start-time enrichment
|
|
7
|
+
* 3. Querying OpenCode's SQLite DB (~/.local/share/opencode/opencode.db) to
|
|
8
|
+
* find the session matching each process's CWD and read status from message.time.completed
|
|
9
|
+
*
|
|
10
|
+
* sessionFilePath encodes "<dbPath>::<sessionId>" so getConversation() can open the right
|
|
11
|
+
* DB row without extending the AgentAdapter interface.
|
|
12
|
+
*/ import { captureProcessSnapshot, executableBasename, filterByProcessNames } from "../../utils/process.js";
|
|
13
|
+
import { OpenCodeAgentMapper } from "./OpenCodeAgentMapper.js";
|
|
14
|
+
import { OpenCodeSessionLocator } from "./OpenCodeSessionLocator.js";
|
|
15
|
+
import { OpenCodeSessionParser } from "./OpenCodeSessionParser.js";
|
|
16
|
+
const SESSION_REF_SEP = "::";
|
|
17
|
+
function decodeSessionRef(ref) {
|
|
18
|
+
const idx = ref.lastIndexOf(SESSION_REF_SEP);
|
|
19
|
+
if (idx === -1) return null;
|
|
20
|
+
return {
|
|
21
|
+
sessionId: ref.slice(idx + SESSION_REF_SEP.length)
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export class OpenCodeAdapter {
|
|
25
|
+
type = "opencode";
|
|
26
|
+
processNames = [
|
|
27
|
+
"opencode"
|
|
28
|
+
];
|
|
29
|
+
parser;
|
|
30
|
+
locator;
|
|
31
|
+
mapper;
|
|
32
|
+
cleanup = ()=>this.close();
|
|
33
|
+
constructor(dbPath){
|
|
34
|
+
this.parser = new OpenCodeSessionParser();
|
|
35
|
+
this.locator = new OpenCodeSessionLocator(dbPath, this.parser);
|
|
36
|
+
this.mapper = new OpenCodeAgentMapper(this.locator.dbFilePath);
|
|
37
|
+
process.once("exit", this.cleanup);
|
|
38
|
+
process.once("SIGINT", this.cleanup);
|
|
39
|
+
process.once("SIGTERM", this.cleanup);
|
|
40
|
+
}
|
|
41
|
+
close() {
|
|
42
|
+
process.off("exit", this.cleanup);
|
|
43
|
+
process.off("SIGINT", this.cleanup);
|
|
44
|
+
process.off("SIGTERM", this.cleanup);
|
|
45
|
+
this.locator.close();
|
|
46
|
+
}
|
|
47
|
+
canHandle(processInfo) {
|
|
48
|
+
const base = executableBasename(processInfo.command);
|
|
49
|
+
return base === "opencode" || base === "opencode.exe";
|
|
50
|
+
}
|
|
51
|
+
async detectAgents(context) {
|
|
52
|
+
const snapshot = context?.processes ?? await captureProcessSnapshot(this.processNames);
|
|
53
|
+
const relevant = filterByProcessNames(snapshot, this.processNames);
|
|
54
|
+
const processes = relevant.filter((process1)=>this.canHandle(process1));
|
|
55
|
+
if (processes.length === 0) return [];
|
|
56
|
+
const db = this.locator.openDb();
|
|
57
|
+
if (!db) return processes.map((process1)=>this.mapper.mapProcessOnlyAgent(process1));
|
|
58
|
+
const agents = [];
|
|
59
|
+
for (const proc of processes){
|
|
60
|
+
if (!proc.cwd) {
|
|
61
|
+
agents.push(this.mapper.mapProcessOnlyAgent(proc));
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
const session = this.locator.findSessionForDirectory(db, proc.cwd);
|
|
65
|
+
if (!session) {
|
|
66
|
+
agents.push(this.mapper.mapProcessOnlyAgent(proc));
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
const stats = this.parser.getSessionStats(db, session.sessionId);
|
|
70
|
+
agents.push(this.mapper.mapSessionToAgent(session, stats, proc));
|
|
71
|
+
}
|
|
72
|
+
return agents;
|
|
73
|
+
}
|
|
74
|
+
getConversation(sessionFilePath, options) {
|
|
75
|
+
const ref = decodeSessionRef(sessionFilePath);
|
|
76
|
+
if (!ref) return [];
|
|
77
|
+
const db = this.locator.openDb();
|
|
78
|
+
if (!db) return [];
|
|
79
|
+
return this.parser.getConversation(db, ref.sessionId, options);
|
|
80
|
+
}
|
|
81
|
+
async listSessions(opts) {
|
|
82
|
+
return this.locator.listSessions(opts);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
//# sourceMappingURL=OpenCodeAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/providers/opencode/OpenCodeAdapter.ts"],"sourcesContent":["/**\n * OpenCode Adapter\n *\n * Detects running OpenCode agents by:\n * 1. Filtering OpenCode processes from a shared asynchronous process snapshot\n * 2. Using snapshot CWD and start-time enrichment\n * 3. Querying OpenCode's SQLite DB (~/.local/share/opencode/opencode.db) to\n * find the session matching each process's CWD and read status from message.time.completed\n *\n * sessionFilePath encodes \"<dbPath>::<sessionId>\" so getConversation() can open the right\n * DB row without extending the AgentAdapter interface.\n */\n\nimport type {\n AgentAdapter,\n AgentInfo,\n ProcessInfo,\n ConversationMessage,\n SessionSummary,\n ListSessionsOptions,\n AgentDetectionContext,\n} from \"../../adapters/AgentAdapter.js\";\nimport {\n captureProcessSnapshot,\n executableBasename,\n filterByProcessNames,\n} from \"../../utils/process.js\";\nimport { OpenCodeAgentMapper } from \"./OpenCodeAgentMapper.js\";\nimport { OpenCodeSessionLocator } from \"./OpenCodeSessionLocator.js\";\nimport { OpenCodeSessionParser } from \"./OpenCodeSessionParser.js\";\n\nconst SESSION_REF_SEP = \"::\";\n\nfunction decodeSessionRef(ref: string): { sessionId: string } | null {\n const idx = ref.lastIndexOf(SESSION_REF_SEP);\n if (idx === -1) return null;\n return { sessionId: ref.slice(idx + SESSION_REF_SEP.length) };\n}\n\nexport class OpenCodeAdapter implements AgentAdapter {\n readonly type = \"opencode\" as const;\n readonly processNames = [\"opencode\"] as const;\n\n private readonly parser: OpenCodeSessionParser;\n private readonly locator: OpenCodeSessionLocator;\n private readonly mapper: OpenCodeAgentMapper;\n private readonly cleanup = (): void => this.close();\n\n constructor(dbPath?: string) {\n this.parser = new OpenCodeSessionParser();\n this.locator = new OpenCodeSessionLocator(dbPath, this.parser);\n this.mapper = new OpenCodeAgentMapper(this.locator.dbFilePath);\n process.once(\"exit\", this.cleanup);\n process.once(\"SIGINT\", this.cleanup);\n process.once(\"SIGTERM\", this.cleanup);\n }\n\n close(): void {\n process.off(\"exit\", this.cleanup);\n process.off(\"SIGINT\", this.cleanup);\n process.off(\"SIGTERM\", this.cleanup);\n this.locator.close();\n }\n\n canHandle(processInfo: ProcessInfo): boolean {\n const base = executableBasename(processInfo.command);\n return base === \"opencode\" || base === \"opencode.exe\";\n }\n\n async detectAgents(context?: AgentDetectionContext): Promise<AgentInfo[]> {\n const snapshot = context?.processes ?? (await captureProcessSnapshot(this.processNames));\n const relevant = filterByProcessNames(snapshot, this.processNames);\n const processes = relevant.filter((process) => this.canHandle(process));\n if (processes.length === 0) return [];\n\n const db = this.locator.openDb();\n if (!db) return processes.map((process) => this.mapper.mapProcessOnlyAgent(process));\n\n const agents: AgentInfo[] = [];\n for (const proc of processes) {\n if (!proc.cwd) {\n agents.push(this.mapper.mapProcessOnlyAgent(proc));\n continue;\n }\n\n const session = this.locator.findSessionForDirectory(db, proc.cwd);\n if (!session) {\n agents.push(this.mapper.mapProcessOnlyAgent(proc));\n continue;\n }\n\n const stats = this.parser.getSessionStats(db, session.sessionId);\n agents.push(this.mapper.mapSessionToAgent(session, stats, proc));\n }\n\n return agents;\n }\n\n getConversation(sessionFilePath: string, options?: { verbose?: boolean }): ConversationMessage[] {\n const ref = decodeSessionRef(sessionFilePath);\n if (!ref) return [];\n\n const db = this.locator.openDb();\n if (!db) return [];\n\n return this.parser.getConversation(db, ref.sessionId, options);\n }\n\n async listSessions(opts?: ListSessionsOptions): Promise<SessionSummary[]> {\n return this.locator.listSessions(opts);\n }\n}\n"],"names":["captureProcessSnapshot","executableBasename","filterByProcessNames","OpenCodeAgentMapper","OpenCodeSessionLocator","OpenCodeSessionParser","SESSION_REF_SEP","decodeSessionRef","ref","idx","lastIndexOf","sessionId","slice","length","OpenCodeAdapter","type","processNames","parser","locator","mapper","cleanup","close","dbPath","dbFilePath","process","once","off","canHandle","processInfo","base","command","detectAgents","context","snapshot","processes","relevant","filter","db","openDb","map","mapProcessOnlyAgent","agents","proc","cwd","push","session","findSessionForDirectory","stats","getSessionStats","mapSessionToAgent","getConversation","sessionFilePath","options","listSessions","opts"],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { AgentInfo, ProcessInfo } from "../../adapters/AgentAdapter.js";
|
|
2
|
+
import type { OpenCodeSession } from "./OpenCodeSessionLocator.js";
|
|
3
|
+
import type { OpenCodeSessionStats } from "./OpenCodeSessionParser.js";
|
|
4
|
+
export declare class OpenCodeAgentMapper {
|
|
5
|
+
private readonly dbPath;
|
|
6
|
+
constructor(dbPath: string);
|
|
7
|
+
mapSessionToAgent(session: OpenCodeSession, stats: OpenCodeSessionStats, proc: ProcessInfo): AgentInfo;
|
|
8
|
+
mapProcessOnlyAgent(proc: ProcessInfo): AgentInfo;
|
|
9
|
+
private determineStatus;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=OpenCodeAgentMapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OpenCodeAgentMapper.d.ts","sourceRoot":"","sources":["../../../src/providers/opencode/OpenCodeAgentMapper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAG7E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AASvE,qBAAa,mBAAmB;IAClB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,MAAM;IAE3C,iBAAiB,CACf,OAAO,EAAE,eAAe,EACxB,KAAK,EAAE,oBAAoB,EAC3B,IAAI,EAAE,WAAW,GAChB,SAAS;IAiBZ,mBAAmB,CAAC,IAAI,EAAE,WAAW,GAAG,SAAS;IAajD,OAAO,CAAC,eAAe;CAUxB"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { AgentStatus } from "../../adapters/AgentAdapter.js";
|
|
2
|
+
import { generateAgentName } from "../../utils/matching.js";
|
|
3
|
+
const SESSION_REF_SEP = "::";
|
|
4
|
+
const IDLE_THRESHOLD_MINUTES = 5;
|
|
5
|
+
function encodeSessionRef(dbPath, sessionId) {
|
|
6
|
+
return `${dbPath}${SESSION_REF_SEP}${sessionId}`;
|
|
7
|
+
}
|
|
8
|
+
export class OpenCodeAgentMapper {
|
|
9
|
+
dbPath;
|
|
10
|
+
constructor(dbPath){
|
|
11
|
+
this.dbPath = dbPath;
|
|
12
|
+
}
|
|
13
|
+
mapSessionToAgent(session, stats, proc) {
|
|
14
|
+
const lastActive = stats.lastTimeUpdated > 0 ? new Date(stats.lastTimeUpdated) : new Date(session.timeCreated);
|
|
15
|
+
return {
|
|
16
|
+
name: generateAgentName(session.directory || proc.cwd || "", proc.pid),
|
|
17
|
+
type: "opencode",
|
|
18
|
+
status: this.determineStatus(stats, lastActive),
|
|
19
|
+
summary: stats.summary || "OpenCode session active",
|
|
20
|
+
pid: proc.pid,
|
|
21
|
+
projectPath: session.directory || proc.cwd || "",
|
|
22
|
+
sessionId: session.sessionId,
|
|
23
|
+
lastActive,
|
|
24
|
+
sessionFilePath: encodeSessionRef(this.dbPath, session.sessionId)
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
mapProcessOnlyAgent(proc) {
|
|
28
|
+
return {
|
|
29
|
+
name: generateAgentName(proc.cwd || "", proc.pid),
|
|
30
|
+
type: "opencode",
|
|
31
|
+
status: AgentStatus.RUNNING,
|
|
32
|
+
summary: "OpenCode process running",
|
|
33
|
+
pid: proc.pid,
|
|
34
|
+
projectPath: proc.cwd || "",
|
|
35
|
+
sessionId: `pid-${proc.pid}`,
|
|
36
|
+
lastActive: new Date()
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
determineStatus(stats, lastActive) {
|
|
40
|
+
const ageMin = (Date.now() - lastActive.getTime()) / 60000;
|
|
41
|
+
if (ageMin > IDLE_THRESHOLD_MINUTES) return AgentStatus.IDLE;
|
|
42
|
+
if (stats.lastRole === "assistant" && !stats.lastAssistantCompleted) {
|
|
43
|
+
return AgentStatus.RUNNING;
|
|
44
|
+
}
|
|
45
|
+
if (stats.lastRole === "assistant") return AgentStatus.WAITING;
|
|
46
|
+
return AgentStatus.RUNNING;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
//# sourceMappingURL=OpenCodeAgentMapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/providers/opencode/OpenCodeAgentMapper.ts"],"sourcesContent":["import type { AgentInfo, ProcessInfo } from \"../../adapters/AgentAdapter.js\";\nimport { AgentStatus } from \"../../adapters/AgentAdapter.js\";\nimport { generateAgentName } from \"../../utils/matching.js\";\nimport type { OpenCodeSession } from \"./OpenCodeSessionLocator.js\";\nimport type { OpenCodeSessionStats } from \"./OpenCodeSessionParser.js\";\n\nconst SESSION_REF_SEP = \"::\";\nconst IDLE_THRESHOLD_MINUTES = 5;\n\nfunction encodeSessionRef(dbPath: string, sessionId: string): string {\n return `${dbPath}${SESSION_REF_SEP}${sessionId}`;\n}\n\nexport class OpenCodeAgentMapper {\n constructor(private readonly dbPath: string) {}\n\n mapSessionToAgent(\n session: OpenCodeSession,\n stats: OpenCodeSessionStats,\n proc: ProcessInfo,\n ): AgentInfo {\n const lastActive =\n stats.lastTimeUpdated > 0 ? new Date(stats.lastTimeUpdated) : new Date(session.timeCreated);\n\n return {\n name: generateAgentName(session.directory || proc.cwd || \"\", proc.pid),\n type: \"opencode\",\n status: this.determineStatus(stats, lastActive),\n summary: stats.summary || \"OpenCode session active\",\n pid: proc.pid,\n projectPath: session.directory || proc.cwd || \"\",\n sessionId: session.sessionId,\n lastActive,\n sessionFilePath: encodeSessionRef(this.dbPath, session.sessionId),\n };\n }\n\n mapProcessOnlyAgent(proc: ProcessInfo): AgentInfo {\n return {\n name: generateAgentName(proc.cwd || \"\", proc.pid),\n type: \"opencode\",\n status: AgentStatus.RUNNING,\n summary: \"OpenCode process running\",\n pid: proc.pid,\n projectPath: proc.cwd || \"\",\n sessionId: `pid-${proc.pid}`,\n lastActive: new Date(),\n };\n }\n\n private determineStatus(stats: OpenCodeSessionStats, lastActive: Date): AgentStatus {\n const ageMin = (Date.now() - lastActive.getTime()) / 60000;\n if (ageMin > IDLE_THRESHOLD_MINUTES) return AgentStatus.IDLE;\n\n if (stats.lastRole === \"assistant\" && !stats.lastAssistantCompleted) {\n return AgentStatus.RUNNING;\n }\n if (stats.lastRole === \"assistant\") return AgentStatus.WAITING;\n return AgentStatus.RUNNING;\n }\n}\n"],"names":["AgentStatus","generateAgentName","SESSION_REF_SEP","IDLE_THRESHOLD_MINUTES","encodeSessionRef","dbPath","sessionId","OpenCodeAgentMapper","mapSessionToAgent","session","stats","proc","lastActive","lastTimeUpdated","Date","timeCreated","name","directory","cwd","pid","type","status","determineStatus","summary","projectPath","sessionFilePath","mapProcessOnlyAgent","RUNNING","ageMin","now","getTime","IDLE","lastRole","lastAssistantCompleted","WAITING"],"mappings":"AACA,SAASA,WAAW,QAAQ,iCAAiC;AAC7D,SAASC,iBAAiB,QAAQ,0BAA0B;AAI5D,MAAMC,kBAAkB;AACxB,MAAMC,yBAAyB;AAE/B,SAASC,iBAAiBC,MAAc,EAAEC,SAAiB;IACzD,OAAO,GAAGD,SAASH,kBAAkBI,WAAW;AAClD;AAEA,OAAO,MAAMC;;IACX,YAAY,AAAiBF,MAAc,CAAE;aAAhBA,SAAAA;IAAiB;IAE9CG,kBACEC,OAAwB,EACxBC,KAA2B,EAC3BC,IAAiB,EACN;QACX,MAAMC,aACJF,MAAMG,eAAe,GAAG,IAAI,IAAIC,KAAKJ,MAAMG,eAAe,IAAI,IAAIC,KAAKL,QAAQM,WAAW;QAE5F,OAAO;YACLC,MAAMf,kBAAkBQ,QAAQQ,SAAS,IAAIN,KAAKO,GAAG,IAAI,IAAIP,KAAKQ,GAAG;YACrEC,MAAM;YACNC,QAAQ,IAAI,CAACC,eAAe,CAACZ,OAAOE;YACpCW,SAASb,MAAMa,OAAO,IAAI;YAC1BJ,KAAKR,KAAKQ,GAAG;YACbK,aAAaf,QAAQQ,SAAS,IAAIN,KAAKO,GAAG,IAAI;YAC9CZ,WAAWG,QAAQH,SAAS;YAC5BM;YACAa,iBAAiBrB,iBAAiB,IAAI,CAACC,MAAM,EAAEI,QAAQH,SAAS;QAClE;IACF;IAEAoB,oBAAoBf,IAAiB,EAAa;QAChD,OAAO;YACLK,MAAMf,kBAAkBU,KAAKO,GAAG,IAAI,IAAIP,KAAKQ,GAAG;YAChDC,MAAM;YACNC,QAAQrB,YAAY2B,OAAO;YAC3BJ,SAAS;YACTJ,KAAKR,KAAKQ,GAAG;YACbK,aAAab,KAAKO,GAAG,IAAI;YACzBZ,WAAW,CAAC,IAAI,EAAEK,KAAKQ,GAAG,EAAE;YAC5BP,YAAY,IAAIE;QAClB;IACF;IAEQQ,gBAAgBZ,KAA2B,EAAEE,UAAgB,EAAe;QAClF,MAAMgB,SAAS,AAACd,CAAAA,KAAKe,GAAG,KAAKjB,WAAWkB,OAAO,EAAC,IAAK;QACrD,IAAIF,SAASzB,wBAAwB,OAAOH,YAAY+B,IAAI;QAE5D,IAAIrB,MAAMsB,QAAQ,KAAK,eAAe,CAACtB,MAAMuB,sBAAsB,EAAE;YACnE,OAAOjC,YAAY2B,OAAO;QAC5B;QACA,IAAIjB,MAAMsB,QAAQ,KAAK,aAAa,OAAOhC,YAAYkC,OAAO;QAC9D,OAAOlC,YAAY2B,OAAO;IAC5B;AACF"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import Database from "better-sqlite3";
|
|
2
|
+
import type { ListSessionsOptions, SessionSummary } from "../../adapters/AgentAdapter.js";
|
|
3
|
+
import { OpenCodeSessionParser } from "./OpenCodeSessionParser.js";
|
|
4
|
+
export interface OpenCodeSession {
|
|
5
|
+
sessionId: string;
|
|
6
|
+
directory: string;
|
|
7
|
+
timeCreated: number;
|
|
8
|
+
}
|
|
9
|
+
export declare class OpenCodeSessionLocator {
|
|
10
|
+
private readonly parser;
|
|
11
|
+
private readonly dbPath;
|
|
12
|
+
private db;
|
|
13
|
+
constructor(dbPath?: string, parser?: OpenCodeSessionParser);
|
|
14
|
+
static resolveDbPath(): string;
|
|
15
|
+
openDb(): Database.Database | null;
|
|
16
|
+
close(): void;
|
|
17
|
+
findSessionForDirectory(db: Database.Database, directory: string): OpenCodeSession | null;
|
|
18
|
+
listSessions(opts?: ListSessionsOptions): SessionSummary[];
|
|
19
|
+
get dbFilePath(): string;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=OpenCodeSessionLocator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OpenCodeSessionLocator.d.ts","sourceRoot":"","sources":["../../../src/providers/opencode/OpenCodeSessionLocator.ts"],"names":[],"mappings":"AAEA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAC1F,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAQnE,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,sBAAsB;IAM/B,OAAO,CAAC,QAAQ,CAAC,MAAM;IALzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,EAAE,CAAkC;gBAG1C,MAAM,SAAyC,EAC9B,MAAM,GAAE,qBAAmD;IAK9E,MAAM,CAAC,aAAa,IAAI,MAAM;IAO9B,MAAM,IAAI,QAAQ,CAAC,QAAQ,GAAG,IAAI;IAYlC,KAAK,IAAI,IAAI;IAWb,uBAAuB,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI;IAmBzF,YAAY,CAAC,IAAI,CAAC,EAAE,mBAAmB,GAAG,cAAc,EAAE;IAyC1D,IAAI,UAAU,IAAI,MAAM,CAEvB;CACF"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
import Database from "better-sqlite3";
|
|
4
|
+
import { OpenCodeSessionParser } from "./OpenCodeSessionParser.js";
|
|
5
|
+
const SESSION_REF_SEP = "::";
|
|
6
|
+
function encodeOpenCodeSessionRef(dbPath, sessionId) {
|
|
7
|
+
return `${dbPath}${SESSION_REF_SEP}${sessionId}`;
|
|
8
|
+
}
|
|
9
|
+
export class OpenCodeSessionLocator {
|
|
10
|
+
parser;
|
|
11
|
+
dbPath;
|
|
12
|
+
db = null;
|
|
13
|
+
constructor(dbPath = OpenCodeSessionLocator.resolveDbPath(), parser = new OpenCodeSessionParser()){
|
|
14
|
+
this.parser = parser;
|
|
15
|
+
this.dbPath = dbPath;
|
|
16
|
+
}
|
|
17
|
+
static resolveDbPath() {
|
|
18
|
+
const xdg = process.env.XDG_DATA_HOME;
|
|
19
|
+
const home = process.env.HOME || process.env.USERPROFILE || "";
|
|
20
|
+
const base = xdg || path.join(home, ".local", "share");
|
|
21
|
+
return path.join(base, "opencode", "opencode.db");
|
|
22
|
+
}
|
|
23
|
+
openDb() {
|
|
24
|
+
if (this.db) return this.db;
|
|
25
|
+
if (!fs.existsSync(this.dbPath)) return null;
|
|
26
|
+
try {
|
|
27
|
+
this.db = new Database(this.dbPath, {
|
|
28
|
+
readonly: true
|
|
29
|
+
});
|
|
30
|
+
return this.db;
|
|
31
|
+
} catch {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
close() {
|
|
36
|
+
if (this.db) {
|
|
37
|
+
try {
|
|
38
|
+
this.db.close();
|
|
39
|
+
} catch {
|
|
40
|
+
/* ignore */ }
|
|
41
|
+
this.db = null;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
findSessionForDirectory(db, directory) {
|
|
45
|
+
try {
|
|
46
|
+
const row = db.prepare(`
|
|
47
|
+
SELECT id, directory, time_created
|
|
48
|
+
FROM session
|
|
49
|
+
WHERE directory = ?
|
|
50
|
+
ORDER BY time_created DESC
|
|
51
|
+
LIMIT 1
|
|
52
|
+
`).get(directory);
|
|
53
|
+
if (!row) return null;
|
|
54
|
+
return {
|
|
55
|
+
sessionId: row.id,
|
|
56
|
+
directory: row.directory,
|
|
57
|
+
timeCreated: row.time_created
|
|
58
|
+
};
|
|
59
|
+
} catch {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
listSessions(opts) {
|
|
64
|
+
const db = this.openDb();
|
|
65
|
+
if (!db) return [];
|
|
66
|
+
try {
|
|
67
|
+
const rows = db.prepare(`
|
|
68
|
+
SELECT id, directory, time_created AS timeCreated
|
|
69
|
+
FROM session
|
|
70
|
+
ORDER BY time_created DESC
|
|
71
|
+
`).all();
|
|
72
|
+
const summaries = [];
|
|
73
|
+
for (const row of rows){
|
|
74
|
+
if (opts?.cwd !== undefined && row.directory !== opts.cwd) continue;
|
|
75
|
+
const stats = this.parser.getSessionStats(db, row.id);
|
|
76
|
+
const lastActive = stats.lastTimeUpdated > 0 ? new Date(stats.lastTimeUpdated) : new Date(row.timeCreated);
|
|
77
|
+
const startedAt = new Date(row.timeCreated);
|
|
78
|
+
summaries.push({
|
|
79
|
+
type: "opencode",
|
|
80
|
+
sessionId: row.id,
|
|
81
|
+
cwd: row.directory,
|
|
82
|
+
firstUserMessage: stats.summary,
|
|
83
|
+
lastActive,
|
|
84
|
+
startedAt,
|
|
85
|
+
sessionFilePath: encodeOpenCodeSessionRef(this.dbPath, row.id)
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
return summaries;
|
|
89
|
+
} catch {
|
|
90
|
+
this.close();
|
|
91
|
+
return [];
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
get dbFilePath() {
|
|
95
|
+
return this.dbPath;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
//# sourceMappingURL=OpenCodeSessionLocator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/providers/opencode/OpenCodeSessionLocator.ts"],"sourcesContent":["import * as fs from \"fs\";\nimport * as path from \"path\";\nimport Database from \"better-sqlite3\";\nimport type { ListSessionsOptions, SessionSummary } from \"../../adapters/AgentAdapter.js\";\nimport { OpenCodeSessionParser } from \"./OpenCodeSessionParser.js\";\n\nconst SESSION_REF_SEP = \"::\";\n\nfunction encodeOpenCodeSessionRef(dbPath: string, sessionId: string): string {\n return `${dbPath}${SESSION_REF_SEP}${sessionId}`;\n}\n\nexport interface OpenCodeSession {\n sessionId: string;\n directory: string;\n timeCreated: number;\n}\n\nexport class OpenCodeSessionLocator {\n private readonly dbPath: string;\n private db: Database.Database | null = null;\n\n constructor(\n dbPath = OpenCodeSessionLocator.resolveDbPath(),\n private readonly parser: OpenCodeSessionParser = new OpenCodeSessionParser(),\n ) {\n this.dbPath = dbPath;\n }\n\n static resolveDbPath(): string {\n const xdg = process.env.XDG_DATA_HOME;\n const home = process.env.HOME || process.env.USERPROFILE || \"\";\n const base = xdg || path.join(home, \".local\", \"share\");\n return path.join(base, \"opencode\", \"opencode.db\");\n }\n\n openDb(): Database.Database | null {\n if (this.db) return this.db;\n if (!fs.existsSync(this.dbPath)) return null;\n\n try {\n this.db = new Database(this.dbPath, { readonly: true });\n return this.db;\n } catch {\n return null;\n }\n }\n\n close(): void {\n if (this.db) {\n try {\n this.db.close();\n } catch {\n /* ignore */\n }\n this.db = null;\n }\n }\n\n findSessionForDirectory(db: Database.Database, directory: string): OpenCodeSession | null {\n try {\n const row = db\n .prepare<[string], { id: string; directory: string; time_created: number }>(`\n SELECT id, directory, time_created\n FROM session\n WHERE directory = ?\n ORDER BY time_created DESC\n LIMIT 1\n `)\n .get(directory);\n\n if (!row) return null;\n return { sessionId: row.id, directory: row.directory, timeCreated: row.time_created };\n } catch {\n return null;\n }\n }\n\n listSessions(opts?: ListSessionsOptions): SessionSummary[] {\n const db = this.openDb();\n if (!db) return [];\n\n try {\n const rows = db\n .prepare<[], { id: string; directory: string; timeCreated: number }>(`\n SELECT id, directory, time_created AS timeCreated\n FROM session\n ORDER BY time_created DESC\n `)\n .all();\n\n const summaries: SessionSummary[] = [];\n\n for (const row of rows) {\n if (opts?.cwd !== undefined && row.directory !== opts.cwd) continue;\n\n const stats = this.parser.getSessionStats(db, row.id);\n const lastActive =\n stats.lastTimeUpdated > 0 ? new Date(stats.lastTimeUpdated) : new Date(row.timeCreated);\n const startedAt = new Date(row.timeCreated);\n\n summaries.push({\n type: \"opencode\",\n sessionId: row.id,\n cwd: row.directory,\n firstUserMessage: stats.summary,\n lastActive,\n startedAt,\n sessionFilePath: encodeOpenCodeSessionRef(this.dbPath, row.id),\n });\n }\n\n return summaries;\n } catch {\n this.close();\n return [];\n }\n }\n\n get dbFilePath(): string {\n return this.dbPath;\n }\n}\n"],"names":["fs","path","Database","OpenCodeSessionParser","SESSION_REF_SEP","encodeOpenCodeSessionRef","dbPath","sessionId","OpenCodeSessionLocator","db","resolveDbPath","parser","xdg","process","env","XDG_DATA_HOME","home","HOME","USERPROFILE","base","join","openDb","existsSync","readonly","close","findSessionForDirectory","directory","row","prepare","get","id","timeCreated","time_created","listSessions","opts","rows","all","summaries","cwd","undefined","stats","getSessionStats","lastActive","lastTimeUpdated","Date","startedAt","push","type","firstUserMessage","summary","sessionFilePath","dbFilePath"],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ConversationMessage } from "../../adapters/AgentAdapter.js";
|
|
2
|
+
import type Database from "better-sqlite3";
|
|
3
|
+
export interface OpenCodeSessionStats {
|
|
4
|
+
lastRole: string | null;
|
|
5
|
+
lastTimeUpdated: number;
|
|
6
|
+
/** OpenCode writes `time.completed` on the assistant message only when the turn finishes. */
|
|
7
|
+
lastAssistantCompleted: boolean;
|
|
8
|
+
lastAssistantErrored: boolean;
|
|
9
|
+
summary: string;
|
|
10
|
+
}
|
|
11
|
+
export declare class OpenCodeSessionParser {
|
|
12
|
+
getConversation(db: Database.Database, sessionId: string, options?: {
|
|
13
|
+
verbose?: boolean;
|
|
14
|
+
}): ConversationMessage[];
|
|
15
|
+
getSessionStats(db: Database.Database, sessionId: string): OpenCodeSessionStats;
|
|
16
|
+
private parsePartData;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=OpenCodeSessionParser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OpenCodeSessionParser.d.ts","sourceRoot":"","sources":["../../../src/providers/opencode/OpenCodeSessionParser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAC1E,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAE3C,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,6FAA6F;IAC7F,sBAAsB,EAAE,OAAO,CAAC;IAChC,oBAAoB,EAAE,OAAO,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;CACjB;AAiBD,qBAAa,qBAAqB;IAChC,eAAe,CACb,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,GAC9B,mBAAmB,EAAE;IAyCxB,eAAe,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,oBAAoB;IAgE/E,OAAO,CAAC,aAAa;CAOtB"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
const EMPTY_STATS = {
|
|
2
|
+
lastRole: null,
|
|
3
|
+
lastTimeUpdated: 0,
|
|
4
|
+
lastAssistantCompleted: false,
|
|
5
|
+
lastAssistantErrored: false,
|
|
6
|
+
summary: ""
|
|
7
|
+
};
|
|
8
|
+
export class OpenCodeSessionParser {
|
|
9
|
+
getConversation(db, sessionId, options) {
|
|
10
|
+
const verbose = options?.verbose ?? false;
|
|
11
|
+
try {
|
|
12
|
+
const rows = db.prepare(`
|
|
13
|
+
SELECT json_extract(m.data, '$.role') AS role,
|
|
14
|
+
p.data AS partData,
|
|
15
|
+
p.time_created AS timeCreated
|
|
16
|
+
FROM part p
|
|
17
|
+
JOIN message m ON p.message_id = m.id
|
|
18
|
+
WHERE p.session_id = ?
|
|
19
|
+
ORDER BY p.time_created ASC
|
|
20
|
+
`).all(sessionId);
|
|
21
|
+
const messages = [];
|
|
22
|
+
for (const row of rows){
|
|
23
|
+
const partData = this.parsePartData(row.partData);
|
|
24
|
+
if (!partData) continue;
|
|
25
|
+
const role = row.role === "user" ? "user" : "assistant";
|
|
26
|
+
if (partData.type === "text" && partData.text) {
|
|
27
|
+
messages.push({
|
|
28
|
+
role,
|
|
29
|
+
content: partData.text
|
|
30
|
+
});
|
|
31
|
+
} else if (partData.type === "reasoning" && verbose) {
|
|
32
|
+
const text = partData.reasoning || partData.text || "";
|
|
33
|
+
if (text) messages.push({
|
|
34
|
+
role: "assistant",
|
|
35
|
+
content: `[thinking] ${text}`
|
|
36
|
+
});
|
|
37
|
+
} else if (partData.type === "tool" && verbose) {
|
|
38
|
+
const toolName = partData.tool || "tool";
|
|
39
|
+
messages.push({
|
|
40
|
+
role: "assistant",
|
|
41
|
+
content: `[tool: ${toolName}]`
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return messages;
|
|
46
|
+
} catch {
|
|
47
|
+
return [];
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
getSessionStats(db, sessionId) {
|
|
51
|
+
try {
|
|
52
|
+
// Order by time_created — time_updated can lag when OpenCode appends
|
|
53
|
+
// metadata (e.g. summary diffs) to user messages after a turn finishes.
|
|
54
|
+
const last = db.prepare(`
|
|
55
|
+
SELECT json_extract(data, '$.role') AS role,
|
|
56
|
+
time_updated AS timeUpdated
|
|
57
|
+
FROM message
|
|
58
|
+
WHERE session_id = ?
|
|
59
|
+
ORDER BY time_created DESC
|
|
60
|
+
LIMIT 1
|
|
61
|
+
`).get(sessionId);
|
|
62
|
+
const heartbeat = db.prepare(`
|
|
63
|
+
SELECT MAX(time_updated) AS maxUpdated FROM message WHERE session_id = ?
|
|
64
|
+
`).get(sessionId);
|
|
65
|
+
const lastAssistant = db.prepare(`
|
|
66
|
+
SELECT json_extract(data, '$.time.completed') AS completed,
|
|
67
|
+
json_extract(data, '$.time.error') AS errored
|
|
68
|
+
FROM message
|
|
69
|
+
WHERE session_id = ? AND json_extract(data, '$.role') = 'assistant'
|
|
70
|
+
ORDER BY time_created DESC
|
|
71
|
+
LIMIT 1
|
|
72
|
+
`).get(sessionId);
|
|
73
|
+
const first = db.prepare(`
|
|
74
|
+
SELECT json_extract(p.data, '$.text') AS text
|
|
75
|
+
FROM part p
|
|
76
|
+
JOIN message m ON p.message_id = m.id
|
|
77
|
+
WHERE p.session_id = ?
|
|
78
|
+
AND json_extract(m.data, '$.role') = 'user'
|
|
79
|
+
AND json_extract(p.data, '$.type') = 'text'
|
|
80
|
+
AND json_extract(p.data, '$.text') IS NOT NULL
|
|
81
|
+
ORDER BY p.time_created ASC
|
|
82
|
+
LIMIT 1
|
|
83
|
+
`).get(sessionId);
|
|
84
|
+
return {
|
|
85
|
+
lastRole: last?.role ?? null,
|
|
86
|
+
lastTimeUpdated: heartbeat?.maxUpdated ?? last?.timeUpdated ?? 0,
|
|
87
|
+
lastAssistantCompleted: lastAssistant?.completed != null,
|
|
88
|
+
lastAssistantErrored: lastAssistant?.errored != null,
|
|
89
|
+
summary: first?.text?.trim() ?? ""
|
|
90
|
+
};
|
|
91
|
+
} catch {
|
|
92
|
+
return EMPTY_STATS;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
parsePartData(partData) {
|
|
96
|
+
try {
|
|
97
|
+
return JSON.parse(partData);
|
|
98
|
+
} catch {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
//# sourceMappingURL=OpenCodeSessionParser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/providers/opencode/OpenCodeSessionParser.ts"],"sourcesContent":["import type { ConversationMessage } from \"../../adapters/AgentAdapter.js\";\nimport type Database from \"better-sqlite3\";\n\nexport interface OpenCodeSessionStats {\n lastRole: string | null;\n lastTimeUpdated: number;\n /** OpenCode writes `time.completed` on the assistant message only when the turn finishes. */\n lastAssistantCompleted: boolean;\n lastAssistantErrored: boolean;\n summary: string;\n}\n\ninterface OpenCodePartData {\n type?: string;\n text?: string;\n reasoning?: string;\n tool?: string;\n}\n\nconst EMPTY_STATS: OpenCodeSessionStats = {\n lastRole: null,\n lastTimeUpdated: 0,\n lastAssistantCompleted: false,\n lastAssistantErrored: false,\n summary: \"\",\n};\n\nexport class OpenCodeSessionParser {\n getConversation(\n db: Database.Database,\n sessionId: string,\n options?: { verbose?: boolean },\n ): ConversationMessage[] {\n const verbose = options?.verbose ?? false;\n\n try {\n const rows = db\n .prepare<[string], { role: string; partData: string; timeCreated: number }>(`\n SELECT json_extract(m.data, '$.role') AS role,\n p.data AS partData,\n p.time_created AS timeCreated\n FROM part p\n JOIN message m ON p.message_id = m.id\n WHERE p.session_id = ?\n ORDER BY p.time_created ASC\n `)\n .all(sessionId);\n\n const messages: ConversationMessage[] = [];\n\n for (const row of rows) {\n const partData = this.parsePartData(row.partData);\n if (!partData) continue;\n\n const role = row.role === \"user\" ? \"user\" : \"assistant\";\n\n if (partData.type === \"text\" && partData.text) {\n messages.push({ role, content: partData.text });\n } else if (partData.type === \"reasoning\" && verbose) {\n const text = partData.reasoning || partData.text || \"\";\n if (text) messages.push({ role: \"assistant\", content: `[thinking] ${text}` });\n } else if (partData.type === \"tool\" && verbose) {\n const toolName = partData.tool || \"tool\";\n messages.push({ role: \"assistant\", content: `[tool: ${toolName}]` });\n }\n }\n\n return messages;\n } catch {\n return [];\n }\n }\n\n getSessionStats(db: Database.Database, sessionId: string): OpenCodeSessionStats {\n try {\n // Order by time_created — time_updated can lag when OpenCode appends\n // metadata (e.g. summary diffs) to user messages after a turn finishes.\n const last = db\n .prepare<[string], { role: string; timeUpdated: number }>(`\n SELECT json_extract(data, '$.role') AS role,\n time_updated AS timeUpdated\n FROM message\n WHERE session_id = ?\n ORDER BY time_created DESC\n LIMIT 1\n `)\n .get(sessionId);\n\n const heartbeat = db\n .prepare<[string], { maxUpdated: number }>(`\n SELECT MAX(time_updated) AS maxUpdated FROM message WHERE session_id = ?\n `)\n .get(sessionId);\n\n const lastAssistant = db\n .prepare<\n [string],\n {\n completed: number | null;\n errored: number | null;\n }\n >(`\n SELECT json_extract(data, '$.time.completed') AS completed,\n json_extract(data, '$.time.error') AS errored\n FROM message\n WHERE session_id = ? AND json_extract(data, '$.role') = 'assistant'\n ORDER BY time_created DESC\n LIMIT 1\n `)\n .get(sessionId);\n\n const first = db\n .prepare<[string], { text: string }>(`\n SELECT json_extract(p.data, '$.text') AS text\n FROM part p\n JOIN message m ON p.message_id = m.id\n WHERE p.session_id = ?\n AND json_extract(m.data, '$.role') = 'user'\n AND json_extract(p.data, '$.type') = 'text'\n AND json_extract(p.data, '$.text') IS NOT NULL\n ORDER BY p.time_created ASC\n LIMIT 1\n `)\n .get(sessionId);\n\n return {\n lastRole: last?.role ?? null,\n lastTimeUpdated: heartbeat?.maxUpdated ?? last?.timeUpdated ?? 0,\n lastAssistantCompleted: lastAssistant?.completed != null,\n lastAssistantErrored: lastAssistant?.errored != null,\n summary: first?.text?.trim() ?? \"\",\n };\n } catch {\n return EMPTY_STATS;\n }\n }\n\n private parsePartData(partData: string): OpenCodePartData | null {\n try {\n return JSON.parse(partData) as OpenCodePartData;\n } catch {\n return null;\n }\n }\n}\n"],"names":["EMPTY_STATS","lastRole","lastTimeUpdated","lastAssistantCompleted","lastAssistantErrored","summary","OpenCodeSessionParser","getConversation","db","sessionId","options","verbose","rows","prepare","all","messages","row","partData","parsePartData","role","type","text","push","content","reasoning","toolName","tool","getSessionStats","last","get","heartbeat","lastAssistant","first","maxUpdated","timeUpdated","completed","errored","trim","JSON","parse"],"mappings":"AAmBA,MAAMA,cAAoC;IACxCC,UAAU;IACVC,iBAAiB;IACjBC,wBAAwB;IACxBC,sBAAsB;IACtBC,SAAS;AACX;AAEA,OAAO,MAAMC;IACXC,gBACEC,EAAqB,EACrBC,SAAiB,EACjBC,OAA+B,EACR;QACvB,MAAMC,UAAUD,SAASC,WAAW;QAEpC,IAAI;YACF,MAAMC,OAAOJ,GACVK,OAAO,CAAoE,CAAC;;;;;;;;YAQzE,CAAC,EACJC,GAAG,CAACL;YAEP,MAAMM,WAAkC,EAAE;YAE1C,KAAK,MAAMC,OAAOJ,KAAM;gBACtB,MAAMK,WAAW,IAAI,CAACC,aAAa,CAACF,IAAIC,QAAQ;gBAChD,IAAI,CAACA,UAAU;gBAEf,MAAME,OAAOH,IAAIG,IAAI,KAAK,SAAS,SAAS;gBAE5C,IAAIF,SAASG,IAAI,KAAK,UAAUH,SAASI,IAAI,EAAE;oBAC7CN,SAASO,IAAI,CAAC;wBAAEH;wBAAMI,SAASN,SAASI,IAAI;oBAAC;gBAC/C,OAAO,IAAIJ,SAASG,IAAI,KAAK,eAAeT,SAAS;oBACnD,MAAMU,OAAOJ,SAASO,SAAS,IAAIP,SAASI,IAAI,IAAI;oBACpD,IAAIA,MAAMN,SAASO,IAAI,CAAC;wBAAEH,MAAM;wBAAaI,SAAS,CAAC,WAAW,EAAEF,MAAM;oBAAC;gBAC7E,OAAO,IAAIJ,SAASG,IAAI,KAAK,UAAUT,SAAS;oBAC9C,MAAMc,WAAWR,SAASS,IAAI,IAAI;oBAClCX,SAASO,IAAI,CAAC;wBAAEH,MAAM;wBAAaI,SAAS,CAAC,OAAO,EAAEE,SAAS,CAAC,CAAC;oBAAC;gBACpE;YACF;YAEA,OAAOV;QACT,EAAE,OAAM;YACN,OAAO,EAAE;QACX;IACF;IAEAY,gBAAgBnB,EAAqB,EAAEC,SAAiB,EAAwB;QAC9E,IAAI;YACF,qEAAqE;YACrE,wEAAwE;YACxE,MAAMmB,OAAOpB,GACVK,OAAO,CAAkD,CAAC;;;;;;;YAOvD,CAAC,EACJgB,GAAG,CAACpB;YAEP,MAAMqB,YAAYtB,GACfK,OAAO,CAAmC,CAAC;;YAExC,CAAC,EACJgB,GAAG,CAACpB;YAEP,MAAMsB,gBAAgBvB,GACnBK,OAAO,CAMN,CAAC;;;;;;;YAOC,CAAC,EACJgB,GAAG,CAACpB;YAEP,MAAMuB,QAAQxB,GACXK,OAAO,CAA6B,CAAC;;;;;;;;;;YAUlC,CAAC,EACJgB,GAAG,CAACpB;YAEP,OAAO;gBACLR,UAAU2B,MAAMT,QAAQ;gBACxBjB,iBAAiB4B,WAAWG,cAAcL,MAAMM,eAAe;gBAC/D/B,wBAAwB4B,eAAeI,aAAa;gBACpD/B,sBAAsB2B,eAAeK,WAAW;gBAChD/B,SAAS2B,OAAOX,MAAMgB,UAAU;YAClC;QACF,EAAE,OAAM;YACN,OAAOrC;QACT;IACF;IAEQkB,cAAcD,QAAgB,EAA2B;QAC/D,IAAI;YACF,OAAOqB,KAAKC,KAAK,CAACtB;QACpB,EAAE,OAAM;YACN,OAAO;QACT;IACF;AACF"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { AgentInfo } from "../../adapters/AgentAdapter.js";
|
|
2
|
+
import { type HerdrCommandRunner } from "./HerdrCliClient.js";
|
|
3
|
+
import type { HerdrRuntimeRef } from "./HerdrRuntimeRef.js";
|
|
4
|
+
export interface HerdrAgentPane {
|
|
5
|
+
agent: string;
|
|
6
|
+
agentSessionId?: string;
|
|
7
|
+
cwd?: string;
|
|
8
|
+
paneId: string;
|
|
9
|
+
workspaceId?: string;
|
|
10
|
+
tabId?: string;
|
|
11
|
+
foregroundPids?: number[];
|
|
12
|
+
shellPid?: number;
|
|
13
|
+
}
|
|
14
|
+
export declare function fetchHerdrAgentPanes(runner?: HerdrCommandRunner): Promise<HerdrAgentPane[]>;
|
|
15
|
+
export declare function extractHerdrAgentPanes(value: unknown): HerdrAgentPane[];
|
|
16
|
+
export declare function findMatchingHerdrPane(agent: Pick<AgentInfo, "type" | "projectPath" | "sessionId" | "pid">, panes: readonly HerdrAgentPane[]): HerdrAgentPane | null;
|
|
17
|
+
export declare function herdrPaneToRuntimeRef(pane: HerdrAgentPane, agentName: string): HerdrRuntimeRef;
|
|
18
|
+
//# sourceMappingURL=HerdrAgentDiscovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HerdrAgentDiscovery.d.ts","sourceRoot":"","sources":["../../../src/runtime/herdr/HerdrAgentDiscovery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAa,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EAAkB,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE5D,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,oBAAoB,CAAC,MAAM,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAIjG;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,EAAE,CA8BvE;AAED,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,GAAG,WAAW,GAAG,KAAK,CAAC,EACpE,KAAK,EAAE,SAAS,cAAc,EAAE,GAC/B,cAAc,GAAG,IAAI,CAmBvB;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,GAAG,eAAe,CAQ9F"}
|