@axhub/genie 0.2.6 → 0.2.7
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/assets/App-BWSqiXAT.js +220 -0
- package/dist/assets/App-DrlLKa8f.css +1 -0
- package/dist/assets/ReviewApp-nz3mbArg.js +1 -0
- package/dist/assets/{_basePickBy-DkiHsp3X.js → _basePickBy-C19AekOu.js} +1 -1
- package/dist/assets/{_baseUniq-7ElXb2sX.js → _baseUniq-JsnevLw_.js} +1 -1
- package/dist/assets/{arc-CEsS3MdK.js → arc-BLpcuBlf.js} +1 -1
- package/dist/assets/architectureDiagram-2XIMDMQ5-CarjBOOv.js +36 -0
- package/dist/assets/{blockDiagram-WCTKOSBZ-Cza6M6Ht.js → blockDiagram-WCTKOSBZ-DQBLwsUS.js} +3 -3
- package/dist/assets/c4Diagram-IC4MRINW-CGobwBIj.js +10 -0
- package/dist/assets/channel-DkFNxV_H.js +1 -0
- package/dist/assets/{chunk-4BX2VUAB--HkodwbY.js → chunk-4BX2VUAB-De63kbgc.js} +1 -1
- package/dist/assets/{chunk-55IACEB6-CyBuez4e.js → chunk-55IACEB6-DtTDDdM9.js} +1 -1
- package/dist/assets/{chunk-FMBD7UC4-CuzG4iAl.js → chunk-FMBD7UC4-DHuwd8tw.js} +1 -1
- package/dist/assets/{chunk-JSJVCQXG-BNi8S861.js → chunk-JSJVCQXG-BgytFtmO.js} +1 -1
- package/dist/assets/{chunk-KX2RTZJC-D817O-GT.js → chunk-KX2RTZJC-nZdp86aN.js} +1 -1
- package/dist/assets/chunk-NQ4KR5QH-CMH6EDP2.js +220 -0
- package/dist/assets/{chunk-QZHKN3VN-VMEn-zxh.js → chunk-QZHKN3VN-DvUQ3mnO.js} +1 -1
- package/dist/assets/chunk-WL4C6EOR-Dn7db_6t.js +189 -0
- package/dist/assets/classDiagram-VBA2DB6C-DtwCEe8S.js +1 -0
- package/dist/assets/classDiagram-v2-RAHNMMFH-DtwCEe8S.js +1 -0
- package/dist/assets/clone-C0lCEIEO.js +1 -0
- package/dist/assets/cose-bilkent-S5V4N54A-DD_nzqsz.js +1 -0
- package/dist/assets/cytoscape.esm-5J0xJHOV.js +321 -0
- package/dist/assets/{dagre-KLK3FWXG-Bqp7DjEa.js → dagre-KLK3FWXG-CHYIvW47.js} +1 -1
- package/dist/assets/diagram-E7M64L7V-TVdvHtGc.js +24 -0
- package/dist/assets/{diagram-IFDJBPK2--fHfW6V2.js → diagram-IFDJBPK2-Dzsiln_C.js} +1 -1
- package/dist/assets/{diagram-P4PSJMXO-D1kQI5RB.js → diagram-P4PSJMXO-DKnGbUpE.js} +1 -1
- package/dist/assets/erDiagram-INFDFZHY-5Kw0bByo.js +70 -0
- package/dist/assets/{flowDiagram-PKNHOUZH-DWeNr4yg.js → flowDiagram-PKNHOUZH-BAZ2-jKp.js} +4 -4
- package/dist/assets/ganttDiagram-A5KZAMGK-CsADFkcq.js +292 -0
- package/dist/assets/{gitGraphDiagram-K3NZZRJ6-B5a8UWjN.js → gitGraphDiagram-K3NZZRJ6-BflpyjGy.js} +1 -1
- package/dist/assets/{graph-Cw1rYoD9.js → graph-suelaXFh.js} +1 -1
- package/dist/assets/highlighted-body-OFNGDK62-CZrBMazC.js +1 -0
- package/dist/assets/index-B01NxbUv.css +1 -0
- package/dist/assets/index-DW5pGgQ_.js +2 -0
- package/dist/assets/{infoDiagram-LFFYTUFH-D2u70rhN.js → infoDiagram-LFFYTUFH-pfD1FA3p.js} +1 -1
- package/dist/assets/ishikawaDiagram-PHBUUO56-ndm9snwO.js +70 -0
- package/dist/assets/journeyDiagram-4ABVD52K-HgF2t7z5.js +139 -0
- package/dist/assets/{kanban-definition-K7BYSVSG-DbVt0v29.js → kanban-definition-K7BYSVSG-FWinmur1.js} +5 -5
- package/dist/assets/{layout-W_tRx4UV.js → layout-vcz43XvZ.js} +1 -1
- package/dist/assets/{linear-CcMb2ay-.js → linear-le4gc0vx.js} +1 -1
- package/dist/assets/mermaid-GHXKKRXX-CK8m3lad.js +870 -0
- package/dist/assets/mindmap-definition-YRQLILUH-CNq9SKj4.js +68 -0
- package/dist/assets/{pieDiagram-SKSYHLDU-CDyJaACv.js → pieDiagram-SKSYHLDU-C7PKDh3b.js} +2 -2
- package/dist/assets/quadrantDiagram-337W2JSQ-B7FnztNO.js +7 -0
- package/dist/assets/requirementDiagram-Z7DCOOCP-Bl_BM2Th.js +73 -0
- package/dist/assets/{sankeyDiagram-WA2Y5GQK-Di1ShaMF.js → sankeyDiagram-WA2Y5GQK-4gulcOP4.js} +3 -3
- package/dist/assets/sequenceDiagram-2WXFIKYE-VEuJDwyJ.js +145 -0
- package/dist/assets/{stateDiagram-RAJIS63D-CVZYMqyW.js → stateDiagram-RAJIS63D-CB4Vl7qM.js} +1 -1
- package/dist/assets/stateDiagram-v2-FVOUBMTO-C85ucl39.js +1 -0
- package/dist/assets/timeline-definition-YZTLITO2-BPGKhi7f.js +61 -0
- package/dist/assets/{treemap-KZPCXAKY-CGG4gx3C.js → treemap-KZPCXAKY-DZSEE6Hz.js} +58 -58
- package/dist/assets/vendor-codemirror-CyOKkaQZ.js +31 -0
- package/dist/assets/vendor-react-CP4yFTs7.js +8 -0
- package/dist/assets/vendor-xterm-DfcmCpbH.js +66 -0
- package/dist/assets/{vennDiagram-LZ73GAT5-Dds37L2k.js → vennDiagram-LZ73GAT5-8E_G06fI.js} +4 -4
- package/dist/assets/xychartDiagram-JWTSCODW-CbBk50-O.js +7 -0
- package/dist/index.html +4 -4
- package/package.json +2 -1
- package/server/_legacy-providers/README.md +30 -0
- package/server/_legacy-providers/claude-sdk.js +956 -0
- package/server/_legacy-providers/gemini-cli.js +368 -0
- package/server/_legacy-providers/openai-codex.js +705 -0
- package/server/_legacy-providers/opencode-cli.js +674 -0
- package/server/acp-runtime/client.js +1805 -0
- package/server/acp-runtime/client.test.js +688 -0
- package/server/acp-runtime/index.js +419 -0
- package/server/acp-runtime/registry.js +45 -0
- package/server/acp-runtime/session-store.js +254 -0
- package/server/acp-runtime/session-store.test.js +89 -0
- package/server/channels/runtime/AgentRuntimeAdapter.js +21 -70
- package/server/claude-sdk.js +24 -944
- package/server/cli.js +4 -2
- package/server/external-agent/service.js +52 -63
- package/server/gemini-cli.js +23 -360
- package/server/index.js +47 -44
- package/server/openai-codex.js +24 -698
- package/server/opencode-cli.js +70 -640
- package/server/routes/agent.js +2 -0
- package/server/routes/git.js +3 -20
- package/server/routes/session-core.js +44 -10
- package/server/session-core/abortSession.js +2 -18
- package/server/session-core/eventStore.js +5 -1
- package/server/session-core/providerAdapters.js +98 -10
- package/server/session-core/runtimeState.js +16 -17
- package/server/session-core/runtimeWriter.js +19 -12
- package/shared/conversationEvents.js +347 -10
- package/shared/conversationEvents.test.js +403 -0
- package/dist/assets/App-CYTE30Cf.js +0 -484
- package/dist/assets/App-qxJ8_QYu.css +0 -32
- package/dist/assets/ReviewApp-BEicSBzW.js +0 -1
- package/dist/assets/architectureDiagram-2XIMDMQ5-BubZ7T3U.js +0 -36
- package/dist/assets/c4Diagram-IC4MRINW-jhjtOQ12.js +0 -10
- package/dist/assets/channel-RmqTALN0.js +0 -1
- package/dist/assets/chunk-NQ4KR5QH-DyujyOvx.js +0 -220
- package/dist/assets/chunk-WL4C6EOR-CQHHFLvx.js +0 -189
- package/dist/assets/classDiagram-VBA2DB6C-wvVV1ggz.js +0 -1
- package/dist/assets/classDiagram-v2-RAHNMMFH-wvVV1ggz.js +0 -1
- package/dist/assets/clone-oT5aWXpf.js +0 -1
- package/dist/assets/cose-bilkent-S5V4N54A-qykDd54p.js +0 -1
- package/dist/assets/cytoscape.esm-2ZfV8NB5.js +0 -331
- package/dist/assets/diagram-E7M64L7V-BKtx468K.js +0 -24
- package/dist/assets/erDiagram-INFDFZHY-DT9YzdNw.js +0 -70
- package/dist/assets/ganttDiagram-A5KZAMGK--IgwcUhI.js +0 -292
- package/dist/assets/highlighted-body-TPN3WLV5-BCxJHuqY.js +0 -1
- package/dist/assets/index-CBuAXA5S.js +0 -2
- package/dist/assets/index-CyLWKyxy.css +0 -1
- package/dist/assets/ishikawaDiagram-PHBUUO56-Cl8yrezU.js +0 -70
- package/dist/assets/journeyDiagram-4ABVD52K-ddP0AMU9.js +0 -139
- package/dist/assets/mermaid-O7DHMXV3-BBJqt8pT.js +0 -988
- package/dist/assets/mindmap-definition-YRQLILUH-BGhZa7Na.js +0 -68
- package/dist/assets/quadrantDiagram-337W2JSQ-BSYuqf0Q.js +0 -7
- package/dist/assets/requirementDiagram-Z7DCOOCP-Cfi9YX9H.js +0 -73
- package/dist/assets/sequenceDiagram-2WXFIKYE-CYTTG38e.js +0 -145
- package/dist/assets/stateDiagram-v2-FVOUBMTO-Bbl0b4-i.js +0 -1
- package/dist/assets/timeline-definition-YZTLITO2-B1sdb5mK.js +0 -61
- package/dist/assets/vendor-codemirror-Dz7_EqNA.js +0 -39
- package/dist/assets/vendor-react-Cpt6D04s.js +0 -59
- package/dist/assets/vendor-xterm-DfaPXD3y.js +0 -66
- package/dist/assets/xychartDiagram-JWTSCODW-C8QKSyRR.js +0 -7
package/server/routes/agent.js
CHANGED
|
@@ -97,6 +97,7 @@ router.post('/abort', validateExternalApiKey, async (req, res) => {
|
|
|
97
97
|
return res.json({
|
|
98
98
|
success: false,
|
|
99
99
|
aborted: false,
|
|
100
|
+
runtime: 'acp',
|
|
100
101
|
sessionId: normalized.sessionId,
|
|
101
102
|
provider: normalized.provider,
|
|
102
103
|
error: 'Active session not found'
|
|
@@ -106,6 +107,7 @@ router.post('/abort', validateExternalApiKey, async (req, res) => {
|
|
|
106
107
|
return res.json({
|
|
107
108
|
success: true,
|
|
108
109
|
aborted: true,
|
|
110
|
+
runtime: 'acp',
|
|
109
111
|
sessionId: normalized.sessionId,
|
|
110
112
|
provider: normalized.provider,
|
|
111
113
|
message: 'Session aborted'
|
package/server/routes/git.js
CHANGED
|
@@ -610,26 +610,9 @@ Generate the commit message:`;
|
|
|
610
610
|
const parsed = typeof data === 'string' ? JSON.parse(data) : data;
|
|
611
611
|
console.log('🔍 Writer received message type:', parsed.type);
|
|
612
612
|
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
if (parsed.type === '
|
|
616
|
-
const message = parsed.data.message || parsed.data;
|
|
617
|
-
console.log('📦 Claude response message:', JSON.stringify(message, null, 2).substring(0, 500));
|
|
618
|
-
if (message.content && Array.isArray(message.content)) {
|
|
619
|
-
// Extract text from content array
|
|
620
|
-
for (const item of message.content) {
|
|
621
|
-
if (item.type === 'text' && item.text) {
|
|
622
|
-
console.log('✅ Extracted text chunk:', item.text.substring(0, 100));
|
|
623
|
-
responseText += item.text;
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
}
|
|
628
|
-
else if (parsed.type === 'claude-response' && parsed.data?.type === 'content_block_delta' && parsed.data?.delta?.text) {
|
|
629
|
-
responseText += parsed.data.delta.text;
|
|
630
|
-
}
|
|
631
|
-
// Also handle direct text messages
|
|
632
|
-
else if (parsed.type === 'text' && parsed.text) {
|
|
613
|
+
if (parsed.type === 'conversation-event' && parsed.event?.kind === 'assistant_text_delta' && parsed.event?.payload?.text) {
|
|
614
|
+
responseText += parsed.event.payload.text;
|
|
615
|
+
} else if (parsed.type === 'text' && parsed.text) {
|
|
633
616
|
console.log('✅ Direct text:', parsed.text.substring(0, 100));
|
|
634
617
|
responseText += parsed.text;
|
|
635
618
|
}
|
|
@@ -2,10 +2,17 @@ import express from 'express';
|
|
|
2
2
|
import { getProjects } from '../projects.js';
|
|
3
3
|
import { discoverAllProviders, discoverProvider } from '../session-core/providerDiscovery.js';
|
|
4
4
|
import { getProviderAdapter } from '../session-core/providerAdapters.js';
|
|
5
|
+
import { listAcpSessions } from '../acp-runtime/session-store.js';
|
|
5
6
|
|
|
6
7
|
const router = express.Router();
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
router.use((req, res, next) => {
|
|
10
|
+
res.setHeader('X-Runtime-Engine', 'acp');
|
|
11
|
+
next();
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
async function flattenProjectSessions(project) {
|
|
15
|
+
const projectPath = project.fullPath || project.path || null;
|
|
9
16
|
const groups = [
|
|
10
17
|
{ provider: 'claude', items: project.sessions || [] },
|
|
11
18
|
{ provider: 'codex', items: project.codexSessions || [] },
|
|
@@ -13,7 +20,12 @@ function flattenProjectSessions(project) {
|
|
|
13
20
|
{ provider: 'opencode', items: project.opencodeSessions || [] }
|
|
14
21
|
];
|
|
15
22
|
|
|
16
|
-
|
|
23
|
+
const acpSessions = await listAcpSessions({ projectPath });
|
|
24
|
+
|
|
25
|
+
return [
|
|
26
|
+
...groups.flatMap(({ provider, items }) => items.map((item) => ({ ...item, provider, __provider: provider, source: item?.source || 'legacy' }))),
|
|
27
|
+
...acpSessions.map((item) => ({ ...item, provider: item.provider, __provider: item.provider, source: 'acp' }))
|
|
28
|
+
]
|
|
17
29
|
.sort((a, b) => new Date(b.lastActivity || b.updated_at || b.createdAt || 0) - new Date(a.lastActivity || a.updated_at || a.createdAt || 0));
|
|
18
30
|
}
|
|
19
31
|
|
|
@@ -42,7 +54,15 @@ router.get('/projects/:projectName/history-index', async (req, res) => {
|
|
|
42
54
|
if (!project) {
|
|
43
55
|
return res.status(404).json({ success: false, error: 'Project not found' });
|
|
44
56
|
}
|
|
45
|
-
res.json({
|
|
57
|
+
res.json({
|
|
58
|
+
success: true,
|
|
59
|
+
project: {
|
|
60
|
+
name: project.name,
|
|
61
|
+
fullPath: project.fullPath || project.path,
|
|
62
|
+
displayName: project.displayName || project.name
|
|
63
|
+
},
|
|
64
|
+
sessions: await flattenProjectSessions(project)
|
|
65
|
+
});
|
|
46
66
|
} catch (error) {
|
|
47
67
|
res.status(500).json({ success: false, error: error.message });
|
|
48
68
|
}
|
|
@@ -66,19 +86,26 @@ router.get('/sessions/:sessionId/resolve', async (req, res) => {
|
|
|
66
86
|
'opencode'
|
|
67
87
|
].filter((provider, index, all) => provider && all.indexOf(provider) === index);
|
|
68
88
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
89
|
+
let directProjectMatch = null;
|
|
90
|
+
let directMatchSessions = [];
|
|
91
|
+
|
|
92
|
+
for (const project of projects) {
|
|
93
|
+
const flattened = await flattenProjectSessions(project);
|
|
94
|
+
if (flattened.some((session) => session.id === requestedSessionId)) {
|
|
95
|
+
directProjectMatch = project;
|
|
96
|
+
directMatchSessions = flattened;
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
73
100
|
|
|
74
101
|
if (directProjectMatch) {
|
|
75
|
-
const
|
|
76
|
-
const matchedSession = flattened.find((session) => session.id === requestedSessionId);
|
|
102
|
+
const matchedSession = directMatchSessions.find((session) => session.id === requestedSessionId);
|
|
77
103
|
|
|
78
104
|
return res.json({
|
|
79
105
|
success: true,
|
|
80
106
|
found: true,
|
|
81
107
|
provider: matchedSession.provider,
|
|
108
|
+
source: matchedSession.source || 'legacy',
|
|
82
109
|
session: matchedSession,
|
|
83
110
|
project: {
|
|
84
111
|
name: directProjectMatch.name,
|
|
@@ -97,7 +124,12 @@ router.get('/sessions/:sessionId/resolve', async (req, res) => {
|
|
|
97
124
|
|
|
98
125
|
try {
|
|
99
126
|
if (provider === 'claude') {
|
|
100
|
-
const result = await adapter.listSessions({
|
|
127
|
+
const result = await adapter.listSessions({
|
|
128
|
+
projectName: project.name,
|
|
129
|
+
projectPath: project.fullPath || project.path,
|
|
130
|
+
limit: 1000,
|
|
131
|
+
offset: 0
|
|
132
|
+
});
|
|
101
133
|
sessions = Array.isArray(result) ? result : [];
|
|
102
134
|
} else {
|
|
103
135
|
sessions = await adapter.listSessions({ projectPath: project.fullPath || project.path, limit: 0 });
|
|
@@ -115,6 +147,7 @@ router.get('/sessions/:sessionId/resolve', async (req, res) => {
|
|
|
115
147
|
success: true,
|
|
116
148
|
found: true,
|
|
117
149
|
provider,
|
|
150
|
+
source: matchedSession.source || 'legacy',
|
|
118
151
|
session: matchedSession,
|
|
119
152
|
project: {
|
|
120
153
|
name: project.name,
|
|
@@ -157,6 +190,7 @@ router.get('/sessions/:provider/:sessionId/events', async (req, res) => {
|
|
|
157
190
|
success: true,
|
|
158
191
|
provider: req.params.provider,
|
|
159
192
|
sessionId: req.params.sessionId,
|
|
193
|
+
source: result?.source || 'legacy',
|
|
160
194
|
events,
|
|
161
195
|
total,
|
|
162
196
|
hasMore,
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { abortCodexSession } from '../openai-codex.js';
|
|
3
|
-
import { abortGeminiSession } from '../gemini-cli.js';
|
|
4
|
-
import { abortOpencodeSession } from '../opencode-cli.js';
|
|
1
|
+
import { abortAgentSession as abortAcpAgentSession } from '../acp-runtime/index.js';
|
|
5
2
|
|
|
6
3
|
export const ABORTABLE_AGENT_PROVIDERS = ['claude', 'codex', 'gemini', 'opencode'];
|
|
7
4
|
|
|
@@ -11,20 +8,7 @@ export function isAbortableAgentProvider(provider) {
|
|
|
11
8
|
|
|
12
9
|
export async function abortAgentSession(provider, sessionId) {
|
|
13
10
|
const normalizedProvider = String(provider || 'claude').trim().toLowerCase();
|
|
14
|
-
|
|
15
|
-
if (normalizedProvider === 'codex') {
|
|
16
|
-
return abortCodexSession(sessionId);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
if (normalizedProvider === 'gemini') {
|
|
20
|
-
return abortGeminiSession(sessionId);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
if (normalizedProvider === 'opencode') {
|
|
24
|
-
return abortOpencodeSession(sessionId);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return abortClaudeSDKSession(sessionId);
|
|
11
|
+
return abortAcpAgentSession(normalizedProvider, sessionId);
|
|
28
12
|
}
|
|
29
13
|
|
|
30
14
|
export async function abortAgentSessionWithWriter({ provider = 'claude', sessionId, writer }) {
|
|
@@ -24,7 +24,11 @@ function normalizePersistedEvents(events = []) {
|
|
|
24
24
|
return events.filter((event) => (
|
|
25
25
|
isConversationEvent(event) &&
|
|
26
26
|
event.sessionId &&
|
|
27
|
-
|
|
27
|
+
(
|
|
28
|
+
event.extensions?.runtimeSource === 'acp' ||
|
|
29
|
+
event.rawRef?.runtime === 'acp' ||
|
|
30
|
+
PERSISTED_EVENT_KINDS.has(event.kind)
|
|
31
|
+
)
|
|
28
32
|
));
|
|
29
33
|
}
|
|
30
34
|
|
|
@@ -10,6 +10,10 @@ import {
|
|
|
10
10
|
getOpencodeSessions,
|
|
11
11
|
getGeminiSessions
|
|
12
12
|
} from '../projects.js';
|
|
13
|
+
import {
|
|
14
|
+
findAcpSessionRecord,
|
|
15
|
+
listAcpSessions
|
|
16
|
+
} from '../acp-runtime/session-store.js';
|
|
13
17
|
|
|
14
18
|
async function flattenLegacyMessages(result) {
|
|
15
19
|
if (Array.isArray(result)) return result;
|
|
@@ -28,47 +32,131 @@ async function normalizeLegacyLoadResult(result, provider, sessionId) {
|
|
|
28
32
|
|
|
29
33
|
return {
|
|
30
34
|
...result,
|
|
31
|
-
events
|
|
35
|
+
events,
|
|
36
|
+
source: 'legacy'
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function mergeSessionLists(legacySessions = [], acpSessions = []) {
|
|
41
|
+
const merged = new Map();
|
|
42
|
+
|
|
43
|
+
legacySessions.forEach((session) => {
|
|
44
|
+
if (session?.id) {
|
|
45
|
+
merged.set(session.id, session);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
acpSessions.forEach((session) => {
|
|
50
|
+
if (session?.id) {
|
|
51
|
+
merged.set(session.id, session);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
return Array.from(merged.values()).sort((left, right) => {
|
|
56
|
+
const leftTime = new Date(left?.lastActivity || left?.updatedAt || left?.createdAt || 0).getTime();
|
|
57
|
+
const rightTime = new Date(right?.lastActivity || right?.updatedAt || right?.createdAt || 0).getTime();
|
|
58
|
+
return rightTime - leftTime;
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async function loadAcpEvents(provider, sessionId) {
|
|
63
|
+
const record = await findAcpSessionRecord(sessionId, provider);
|
|
64
|
+
if (!record) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const events = await readMirroredConversationEvents(provider, sessionId);
|
|
69
|
+
return {
|
|
70
|
+
events,
|
|
71
|
+
total: events.length,
|
|
72
|
+
hasMore: false,
|
|
73
|
+
offset: 0,
|
|
74
|
+
limit: null,
|
|
75
|
+
source: 'acp'
|
|
32
76
|
};
|
|
33
77
|
}
|
|
34
78
|
|
|
35
79
|
const PROVIDER_ADAPTERS = {
|
|
36
80
|
claude: {
|
|
37
|
-
async listSessions({ projectName, limit = 50, offset = 0 }) {
|
|
38
|
-
const result = await
|
|
39
|
-
|
|
81
|
+
async listSessions({ projectName, projectPath, limit = 50, offset = 0 }) {
|
|
82
|
+
const [result, acpSessions] = await Promise.all([
|
|
83
|
+
getSessions(projectName, limit, offset),
|
|
84
|
+
listAcpSessions({ provider: 'claude', projectPath: projectPath || null })
|
|
85
|
+
]);
|
|
86
|
+
return mergeSessionLists(
|
|
87
|
+
(result?.sessions || []).map((session) => ({ ...session, provider: 'claude', source: 'legacy' })),
|
|
88
|
+
acpSessions
|
|
89
|
+
);
|
|
40
90
|
},
|
|
41
91
|
async loadEvents({ projectName, sessionId, limit = null, offset = 0 }) {
|
|
92
|
+
const acpResult = await loadAcpEvents('claude', sessionId);
|
|
93
|
+
if (acpResult) {
|
|
94
|
+
return acpResult;
|
|
95
|
+
}
|
|
96
|
+
|
|
42
97
|
const rawMessages = await getSessionMessages(projectName, sessionId, limit, offset);
|
|
43
98
|
return normalizeLegacyLoadResult(rawMessages, 'claude', sessionId);
|
|
44
99
|
}
|
|
45
100
|
},
|
|
46
101
|
codex: {
|
|
47
102
|
async listSessions({ projectPath, limit = 50 }) {
|
|
48
|
-
const sessions = await
|
|
49
|
-
|
|
103
|
+
const [sessions, acpSessions] = await Promise.all([
|
|
104
|
+
getCodexSessions(projectPath, { limit }),
|
|
105
|
+
listAcpSessions({ provider: 'codex', projectPath: projectPath || null })
|
|
106
|
+
]);
|
|
107
|
+
return mergeSessionLists(
|
|
108
|
+
sessions.map((session) => ({ ...session, provider: 'codex', source: 'legacy' })),
|
|
109
|
+
acpSessions
|
|
110
|
+
);
|
|
50
111
|
},
|
|
51
112
|
async loadEvents({ sessionId, limit = null, offset = 0 }) {
|
|
113
|
+
const acpResult = await loadAcpEvents('codex', sessionId);
|
|
114
|
+
if (acpResult) {
|
|
115
|
+
return acpResult;
|
|
116
|
+
}
|
|
117
|
+
|
|
52
118
|
const rawMessages = await getCodexSessionMessages(sessionId, limit, offset);
|
|
53
119
|
return normalizeLegacyLoadResult(rawMessages, 'codex', sessionId);
|
|
54
120
|
}
|
|
55
121
|
},
|
|
56
122
|
gemini: {
|
|
57
123
|
async listSessions({ projectPath, limit = 50 }) {
|
|
58
|
-
const sessions = await
|
|
59
|
-
|
|
124
|
+
const [sessions, acpSessions] = await Promise.all([
|
|
125
|
+
getGeminiSessions(projectPath, { limit }),
|
|
126
|
+
listAcpSessions({ provider: 'gemini', projectPath: projectPath || null })
|
|
127
|
+
]);
|
|
128
|
+
return mergeSessionLists(
|
|
129
|
+
sessions.map((session) => ({ ...session, provider: 'gemini', source: 'legacy' })),
|
|
130
|
+
acpSessions
|
|
131
|
+
);
|
|
60
132
|
},
|
|
61
133
|
async loadEvents({ sessionId, limit = null, offset = 0 }) {
|
|
134
|
+
const acpResult = await loadAcpEvents('gemini', sessionId);
|
|
135
|
+
if (acpResult) {
|
|
136
|
+
return acpResult;
|
|
137
|
+
}
|
|
138
|
+
|
|
62
139
|
const rawMessages = await getGeminiSessionMessages(sessionId, limit, offset);
|
|
63
140
|
return normalizeLegacyLoadResult(rawMessages, 'gemini', sessionId);
|
|
64
141
|
}
|
|
65
142
|
},
|
|
66
143
|
opencode: {
|
|
67
144
|
async listSessions({ projectPath, limit = 50 }) {
|
|
68
|
-
const sessions = await
|
|
69
|
-
|
|
145
|
+
const [sessions, acpSessions] = await Promise.all([
|
|
146
|
+
getOpencodeSessions(projectPath, { limit }),
|
|
147
|
+
listAcpSessions({ provider: 'opencode', projectPath: projectPath || null })
|
|
148
|
+
]);
|
|
149
|
+
return mergeSessionLists(
|
|
150
|
+
sessions.map((session) => ({ ...session, provider: 'opencode', source: 'legacy' })),
|
|
151
|
+
acpSessions
|
|
152
|
+
);
|
|
70
153
|
},
|
|
71
154
|
async loadEvents({ sessionId, limit = null, offset = 0 }) {
|
|
155
|
+
const acpResult = await loadAcpEvents('opencode', sessionId);
|
|
156
|
+
if (acpResult) {
|
|
157
|
+
return acpResult;
|
|
158
|
+
}
|
|
159
|
+
|
|
72
160
|
const rawMessages = await getOpencodeSessionMessages(sessionId, limit, offset);
|
|
73
161
|
return normalizeLegacyLoadResult(rawMessages, 'opencode', sessionId);
|
|
74
162
|
}
|
|
@@ -7,10 +7,8 @@ import {
|
|
|
7
7
|
} from './eventStore.js';
|
|
8
8
|
import { getProviderAdapter } from './providerAdapters.js';
|
|
9
9
|
import { getProjects } from '../projects.js';
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import { isGeminiSessionActive } from '../gemini-cli.js';
|
|
13
|
-
import { isOpencodeSessionActive } from '../opencode-cli.js';
|
|
10
|
+
import { findAcpSessionRecord } from '../acp-runtime/session-store.js';
|
|
11
|
+
import { isAgentSessionActive } from '../acp-runtime/index.js';
|
|
14
12
|
|
|
15
13
|
export const AGENT_RUNTIME_PHASES = {
|
|
16
14
|
IDLE: 'idle',
|
|
@@ -86,6 +84,18 @@ async function resolveSessionProjectContext(provider, sessionId) {
|
|
|
86
84
|
return null;
|
|
87
85
|
}
|
|
88
86
|
|
|
87
|
+
const acpRecord = await findAcpSessionRecord(normalizedSessionId, normalizedProvider);
|
|
88
|
+
if (acpRecord) {
|
|
89
|
+
return {
|
|
90
|
+
projectName: null,
|
|
91
|
+
projectPath: acpRecord.projectPath || null,
|
|
92
|
+
session: {
|
|
93
|
+
id: normalizedSessionId,
|
|
94
|
+
source: 'acp'
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
89
99
|
const projects = await getProjects();
|
|
90
100
|
|
|
91
101
|
for (const project of projects) {
|
|
@@ -149,19 +159,7 @@ function isSessionActive(provider, sessionId) {
|
|
|
149
159
|
return false;
|
|
150
160
|
}
|
|
151
161
|
|
|
152
|
-
|
|
153
|
-
return Boolean(isCodexSessionActive(normalizedSessionId));
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
if (normalizedProvider === 'gemini') {
|
|
157
|
-
return Boolean(isGeminiSessionActive(normalizedSessionId));
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
if (normalizedProvider === 'opencode') {
|
|
161
|
-
return Boolean(isOpencodeSessionActive(normalizedSessionId));
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
return Boolean(isClaudeSDKSessionActive(normalizedSessionId));
|
|
162
|
+
return Boolean(isAgentSessionActive(normalizedProvider, normalizedSessionId));
|
|
165
163
|
}
|
|
166
164
|
|
|
167
165
|
function inferPhaseFromEvents(events = []) {
|
|
@@ -204,6 +202,7 @@ function inferPhaseFromEvents(events = []) {
|
|
|
204
202
|
event.kind === CONVERSATION_EVENT_KINDS.TOOL_CALL_INPUT ||
|
|
205
203
|
event.kind === CONVERSATION_EVENT_KINDS.TOOL_CALL_END ||
|
|
206
204
|
event.kind === CONVERSATION_EVENT_KINDS.TOOL_RESULT ||
|
|
205
|
+
event.kind === CONVERSATION_EVENT_KINDS.PLAN_UPDATE ||
|
|
207
206
|
event.kind === CONVERSATION_EVENT_KINDS.SYSTEM_NOTICE
|
|
208
207
|
) {
|
|
209
208
|
inferredPhase = AGENT_RUNTIME_PHASES.STREAMING;
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
isConversationEvent,
|
|
3
|
+
normalizeRealtimePayloadToConversationEvents
|
|
4
|
+
} from '../../shared/conversationEvents.js';
|
|
2
5
|
import { appendMirroredConversationEvents } from './eventStore.js';
|
|
3
6
|
import { publishSessionRuntimeStateChanges } from './runtimeState.js';
|
|
4
7
|
|
|
@@ -18,19 +21,23 @@ export class SessionEventMirrorWriter {
|
|
|
18
21
|
|
|
19
22
|
this.writer.send(data);
|
|
20
23
|
|
|
21
|
-
const normalizedEvents =
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
const normalizedEvents = data?.type === 'conversation-event' && isConversationEvent(data?.event)
|
|
25
|
+
? [data.event]
|
|
26
|
+
: normalizeRealtimePayloadToConversationEvents({
|
|
27
|
+
...data,
|
|
28
|
+
provider: data?.provider || this.provider,
|
|
29
|
+
sessionId: data?.sessionId || this.sessionId
|
|
30
|
+
}, this.provider);
|
|
26
31
|
|
|
27
32
|
normalizedEvents.forEach((event) => {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
if (!(data?.type === 'conversation-event' && data?.event?.eventId === event.eventId)) {
|
|
34
|
+
this.writer.send({
|
|
35
|
+
type: 'conversation-event',
|
|
36
|
+
provider: event.provider,
|
|
37
|
+
sessionId: event.sessionId,
|
|
38
|
+
event
|
|
39
|
+
});
|
|
40
|
+
}
|
|
34
41
|
});
|
|
35
42
|
|
|
36
43
|
if (normalizedEvents.length > 0) {
|