@axhub/genie 0.2.8 → 0.2.9
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/LICENSE +21 -675
- package/dist/api-docs.html +2 -2
- package/dist/assets/App-GBcTeeUS.js +460 -0
- package/dist/assets/ReviewApp-C9K--AQE.js +1 -0
- package/dist/assets/{_basePickBy-CqJbRZ9y.js → _basePickBy-DR_8uFCo.js} +1 -1
- package/dist/assets/{_baseUniq-BS8YH8jO.js → _baseUniq-D0njlQ_7.js} +1 -1
- package/dist/assets/{arc-BBmKEN-S.js → arc-CKlr_Rec.js} +1 -1
- package/dist/assets/{architectureDiagram-2XIMDMQ5-N5lcb82R.js → architectureDiagram-2XIMDMQ5-BmO_uLUH.js} +1 -1
- package/dist/assets/{blockDiagram-WCTKOSBZ-DTMwHuLn.js → blockDiagram-WCTKOSBZ-DhAeO-56.js} +1 -1
- package/dist/assets/{c4Diagram-IC4MRINW-BTKlkXI9.js → c4Diagram-IC4MRINW-C67kFoXx.js} +1 -1
- package/dist/assets/channel-V3MBjKys.js +1 -0
- package/dist/assets/{chunk-4BX2VUAB-DUdoTxAc.js → chunk-4BX2VUAB-mLLagvJi.js} +1 -1
- package/dist/assets/{chunk-55IACEB6-Bm_92xe4.js → chunk-55IACEB6-Lx-hOjlM.js} +1 -1
- package/dist/assets/{chunk-FMBD7UC4-CGW0g62g.js → chunk-FMBD7UC4-Bt-XmVUV.js} +1 -1
- package/dist/assets/{chunk-JSJVCQXG-DYkTH3w1.js → chunk-JSJVCQXG-Cya6gaDV.js} +1 -1
- package/dist/assets/{chunk-KX2RTZJC-C9oTlISU.js → chunk-KX2RTZJC-Bd7Ig6tF.js} +1 -1
- package/dist/assets/{chunk-NQ4KR5QH-CM50ygWP.js → chunk-NQ4KR5QH-5UAE0Vg-.js} +1 -1
- package/dist/assets/{chunk-QZHKN3VN-7dzpYeNJ.js → chunk-QZHKN3VN-BAxZ8m7w.js} +1 -1
- package/dist/assets/{chunk-WL4C6EOR-Cm9nQrsr.js → chunk-WL4C6EOR-DjDPvUUP.js} +1 -1
- package/dist/assets/classDiagram-VBA2DB6C-C790yYiY.js +1 -0
- package/dist/assets/classDiagram-v2-RAHNMMFH-C790yYiY.js +1 -0
- package/dist/assets/clone-BbMGfZwt.js +1 -0
- package/dist/assets/{cose-bilkent-S5V4N54A-Ccp_p0JZ.js → cose-bilkent-S5V4N54A-D-60XrkJ.js} +1 -1
- package/dist/assets/{dagre-KLK3FWXG-fBwTLUp9.js → dagre-KLK3FWXG-bqu3ZS4K.js} +1 -1
- package/dist/assets/{diagram-E7M64L7V-CeNVmFUp.js → diagram-E7M64L7V-BueeqoYm.js} +1 -1
- package/dist/assets/{diagram-IFDJBPK2-CtavyLGa.js → diagram-IFDJBPK2-D4fDv2E7.js} +1 -1
- package/dist/assets/{diagram-P4PSJMXO-CpQTjQwc.js → diagram-P4PSJMXO-WqipY3fN.js} +1 -1
- package/dist/assets/{erDiagram-INFDFZHY-B8R5vwhd.js → erDiagram-INFDFZHY-D0oVnO-x.js} +1 -1
- package/dist/assets/{flowDiagram-PKNHOUZH-BvkVVwIQ.js → flowDiagram-PKNHOUZH-DzbGyxrr.js} +1 -1
- package/dist/assets/{ganttDiagram-A5KZAMGK-DOu3hSNa.js → ganttDiagram-A5KZAMGK-BwhbbgCP.js} +1 -1
- package/dist/assets/{gitGraphDiagram-K3NZZRJ6-C7zT67YE.js → gitGraphDiagram-K3NZZRJ6-DZgAh_KM.js} +1 -1
- package/dist/assets/{graph-D11wiwHo.js → graph-DzKos-N0.js} +1 -1
- package/dist/assets/{highlighted-body-TPN3WLV5-Babpthg-.js → highlighted-body-TPN3WLV5-CKDMgz3X.js} +1 -1
- package/dist/assets/{index-DFxzgWoO.js → index-DiQlHzGj.js} +2 -2
- package/dist/assets/index-Drat2nB9.css +1 -0
- package/dist/assets/{infoDiagram-LFFYTUFH-BmA7IpQG.js → infoDiagram-LFFYTUFH-BFicZbTf.js} +1 -1
- package/dist/assets/{ishikawaDiagram-PHBUUO56-BEquZd3E.js → ishikawaDiagram-PHBUUO56-CtihxDxl.js} +1 -1
- package/dist/assets/{journeyDiagram-4ABVD52K-BfemGz7f.js → journeyDiagram-4ABVD52K-Du00J8_d.js} +1 -1
- package/dist/assets/{kanban-definition-K7BYSVSG-CWja3mln.js → kanban-definition-K7BYSVSG-BJi9S0iQ.js} +1 -1
- package/dist/assets/{layout-BLUNf-PJ.js → layout-B80Sityu.js} +1 -1
- package/dist/assets/{linear-DukIV_Xv.js → linear-sRQLOf5H.js} +1 -1
- package/dist/assets/{mermaid-O7DHMXV3-SgtM28qI.js → mermaid-O7DHMXV3-CBuVs4eJ.js} +6 -6
- package/dist/assets/{mindmap-definition-YRQLILUH-4UjqXITU.js → mindmap-definition-YRQLILUH-C5IL_xi-.js} +1 -1
- package/dist/assets/{pieDiagram-SKSYHLDU-8AxqJd0M.js → pieDiagram-SKSYHLDU-CeTwlJ8z.js} +1 -1
- package/dist/assets/{quadrantDiagram-337W2JSQ-D60m8V8r.js → quadrantDiagram-337W2JSQ-COfUcLWt.js} +1 -1
- package/dist/assets/{requirementDiagram-Z7DCOOCP-zqh9jBVf.js → requirementDiagram-Z7DCOOCP-DSb-CJ5B.js} +1 -1
- package/dist/assets/{sankeyDiagram-WA2Y5GQK-CDZILTLI.js → sankeyDiagram-WA2Y5GQK-8jtuVb45.js} +1 -1
- package/dist/assets/{sequenceDiagram-2WXFIKYE-7BReFd0L.js → sequenceDiagram-2WXFIKYE-C2VpkMwA.js} +1 -1
- package/dist/assets/{stateDiagram-RAJIS63D-HPTVdIG4.js → stateDiagram-RAJIS63D-fmwMqxxc.js} +1 -1
- package/dist/assets/stateDiagram-v2-FVOUBMTO-9GGXVWrR.js +1 -0
- package/dist/assets/{timeline-definition-YZTLITO2-CTVllFgr.js → timeline-definition-YZTLITO2-Dx1hP5lg.js} +1 -1
- package/dist/assets/{treemap-KZPCXAKY-BtyxboJZ.js → treemap-KZPCXAKY-CkLOdYCZ.js} +1 -1
- package/dist/assets/{vendor-codemirror-Dz7_EqNA.js → vendor-codemirror-BxPY6emf.js} +1 -1
- package/dist/assets/{vendor-react-Cpt6D04s.js → vendor-react-xmA_f8ig.js} +1 -1
- package/dist/assets/{vennDiagram-LZ73GAT5-D96ZI6Mg.js → vennDiagram-LZ73GAT5-D6KWcnln.js} +1 -1
- package/dist/assets/{xychartDiagram-JWTSCODW-eRk-39YO.js → xychartDiagram-JWTSCODW-6fh6qmzN.js} +1 -1
- package/dist/index.html +5 -5
- package/package.json +3 -3
- package/server/acp-runtime/client.js +9 -2
- package/server/acp-runtime/session-store.js +4 -4
- package/server/cli.js +23 -2
- package/server/external-agent/service.js +24 -6
- package/server/external-agent/ws.js +63 -3
- package/server/index.js +34 -5
- package/server/projects.js +536 -161
- package/server/routes/session-core.js +149 -86
- package/server/session-core/eventStore.js +45 -18
- package/server/session-core/providerAdapters.js +50 -13
- package/server/session-core/runtimeState.js +8 -0
- package/shared/conversationEvents.js +78 -14
- package/dist/assets/App-CTKZtqB1.js +0 -460
- package/dist/assets/ReviewApp-DM6BNAzR.js +0 -1
- package/dist/assets/channel-1oJBvF-0.js +0 -1
- package/dist/assets/classDiagram-VBA2DB6C-d5TeKFM4.js +0 -1
- package/dist/assets/classDiagram-v2-RAHNMMFH-d5TeKFM4.js +0 -1
- package/dist/assets/clone-CinxIlEu.js +0 -1
- package/dist/assets/index-YCFGDVKw.css +0 -1
- package/dist/assets/stateDiagram-v2-FVOUBMTO-DTUf5_gC.js +0 -1
- package/server/_legacy-providers/README.md +0 -30
- package/server/_legacy-providers/claude-sdk.js +0 -956
- package/server/_legacy-providers/gemini-cli.js +0 -368
- package/server/_legacy-providers/openai-codex.js +0 -705
- package/server/_legacy-providers/opencode-cli.js +0 -674
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
import {
|
|
13
13
|
buildSessionRuntimeSnapshot,
|
|
14
14
|
createSessionRuntimeSubscriptionKey,
|
|
15
|
+
seedSessionRuntimeSubscriptionSnapshot,
|
|
15
16
|
subscribeToSessionRuntimeStateChanges
|
|
16
17
|
} from '../session-core/runtimeState.js';
|
|
17
18
|
import { SUPPORTED_PROVIDERS } from '../../shared/conversationEvents.js';
|
|
@@ -24,6 +25,7 @@ const INTEGRATION_PING_TIMEOUT_MS = 1500;
|
|
|
24
25
|
const INTEGRATION_EDITOR_REQUEST_TIMEOUT_MS = 15000;
|
|
25
26
|
const INTEGRATION_EDITOR_TYPE_PREFIX = 'integration.editor.';
|
|
26
27
|
const INTEGRATION_EDITOR_RESULT_SUFFIX = '.result';
|
|
28
|
+
const VALID_EDITING_STATES = Object.freeze(['editing', 'idle', 'completed', 'error']);
|
|
27
29
|
const INTEGRATION_EDITOR_CAPABILITIES = Object.freeze({
|
|
28
30
|
'integration.editor.snapshot.get': 'editor.snapshot',
|
|
29
31
|
'integration.editor.nodes.list': 'editor.nodes.list',
|
|
@@ -38,6 +40,35 @@ const pendingIntegrationPings = new Map();
|
|
|
38
40
|
const sessionStateSubscriptionsByWs = new Map();
|
|
39
41
|
const sessionStateSubscribersByKey = new Map();
|
|
40
42
|
|
|
43
|
+
// Editing state cache for resilience across connection drops
|
|
44
|
+
const recentEditingStates = new Map();
|
|
45
|
+
const EDITING_STATE_TTL_MS = 30 * 60 * 1000;
|
|
46
|
+
const EDITING_STATE_CLEANUP_INTERVAL_MS = 5 * 60 * 1000;
|
|
47
|
+
|
|
48
|
+
function cacheEditingState(channel, targetClientId, elementKey, state, taskRef) {
|
|
49
|
+
const key = `${channel}::${targetClientId}::${elementKey}`;
|
|
50
|
+
recentEditingStates.set(key, {
|
|
51
|
+
channel,
|
|
52
|
+
targetClientId,
|
|
53
|
+
elementKey,
|
|
54
|
+
state,
|
|
55
|
+
taskRef: taskRef || null,
|
|
56
|
+
updatedAt: Date.now(),
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function cleanupExpiredEditingStates() {
|
|
61
|
+
const now = Date.now();
|
|
62
|
+
for (const [key, entry] of recentEditingStates.entries()) {
|
|
63
|
+
if (now - entry.updatedAt > EDITING_STATE_TTL_MS) {
|
|
64
|
+
recentEditingStates.delete(key);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const editingStateCleanupTimer = setInterval(cleanupExpiredEditingStates, EDITING_STATE_CLEANUP_INTERVAL_MS);
|
|
70
|
+
editingStateCleanupTimer.unref?.();
|
|
71
|
+
|
|
41
72
|
function sendJson(ws, payload) {
|
|
42
73
|
if (ws.readyState === WebSocket.OPEN) {
|
|
43
74
|
ws.send(JSON.stringify(payload));
|
|
@@ -258,6 +289,7 @@ async function handleAgentStateSubscribe(ws, data) {
|
|
|
258
289
|
}
|
|
259
290
|
|
|
260
291
|
const subscriptionKey = createSessionRuntimeSubscriptionKey(normalized.provider, normalized.sessionId);
|
|
292
|
+
seedSessionRuntimeSubscriptionSnapshot(subscriptionKey, snapshot);
|
|
261
293
|
addSessionStateSubscription(ws, subscriptionKey);
|
|
262
294
|
|
|
263
295
|
sendJson(ws, {
|
|
@@ -369,6 +401,7 @@ function buildEditorClientSummary(meta) {
|
|
|
369
401
|
return {
|
|
370
402
|
channel: meta.channel,
|
|
371
403
|
clientId: meta.clientId,
|
|
404
|
+
source: meta.source || null,
|
|
372
405
|
sessionId: meta.sessionId || null,
|
|
373
406
|
pageUrl: meta.pageUrl || null,
|
|
374
407
|
lastSeenAt: meta.lastSeenAt || null,
|
|
@@ -565,6 +598,7 @@ function validateIntegrationConnectPayload(payload) {
|
|
|
565
598
|
role,
|
|
566
599
|
channel,
|
|
567
600
|
clientId,
|
|
601
|
+
source: normalizeNonEmptyString(payload.source) || null,
|
|
568
602
|
pageUrl: normalizeNonEmptyString(payload.pageUrl) || null,
|
|
569
603
|
sessionId: normalizeNonEmptyString(payload.sessionId) || null,
|
|
570
604
|
capabilities: Array.isArray(payload.capabilities)
|
|
@@ -948,8 +982,12 @@ function validateEditorEditingSetPayload(payload) {
|
|
|
948
982
|
}
|
|
949
983
|
|
|
950
984
|
const state = normalizeNonEmptyString(payload.state);
|
|
951
|
-
if (state
|
|
952
|
-
return {
|
|
985
|
+
if (!VALID_EDITING_STATES.includes(state)) {
|
|
986
|
+
return {
|
|
987
|
+
ok: false,
|
|
988
|
+
code: 'INVALID_PAYLOAD',
|
|
989
|
+
message: `state must be one of: ${VALID_EDITING_STATES.join(', ')}`
|
|
990
|
+
};
|
|
953
991
|
}
|
|
954
992
|
|
|
955
993
|
return validateEditorTargetPayload(payload, {
|
|
@@ -1137,6 +1175,24 @@ async function forwardIntegrationResponseToOrigin(data) {
|
|
|
1137
1175
|
outgoingData?.type === 'integration.error'
|
|
1138
1176
|
|| isEditorResultMessageType(outgoingData?.type)
|
|
1139
1177
|
|| (outgoingData?.type === 'integration.ack' && pendingRequest.awaitResult !== true);
|
|
1178
|
+
|
|
1179
|
+
// Cache successful editing state changes for resilience
|
|
1180
|
+
if (
|
|
1181
|
+
outgoingData?.type === 'integration.editor.editing.result'
|
|
1182
|
+
&& isPlainObject(outgoingData?.payload)
|
|
1183
|
+
&& outgoingData.payload.applied === true
|
|
1184
|
+
&& pendingRequest.requestPayload
|
|
1185
|
+
) {
|
|
1186
|
+
const rp = pendingRequest.requestPayload;
|
|
1187
|
+
cacheEditingState(
|
|
1188
|
+
rp.channel,
|
|
1189
|
+
rp.targetClientId,
|
|
1190
|
+
outgoingData.payload.elementKey || rp.elementKey,
|
|
1191
|
+
outgoingData.payload.state,
|
|
1192
|
+
outgoingData.payload.taskRef || rp.taskRef,
|
|
1193
|
+
);
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1140
1196
|
if (isTerminal) {
|
|
1141
1197
|
clearPendingIntegrationRequest(requestId);
|
|
1142
1198
|
}
|
|
@@ -1173,7 +1229,11 @@ class ExternalAgentWebSocketWriter {
|
|
|
1173
1229
|
requestId: this.requestId,
|
|
1174
1230
|
provider: payload.provider || this.provider,
|
|
1175
1231
|
sessionId,
|
|
1176
|
-
...buildSessionNavigation(
|
|
1232
|
+
...buildSessionNavigation({
|
|
1233
|
+
provider: payload.provider || this.provider,
|
|
1234
|
+
sessionId,
|
|
1235
|
+
projectPath: payload.projectPath || null
|
|
1236
|
+
})
|
|
1177
1237
|
});
|
|
1178
1238
|
return;
|
|
1179
1239
|
}
|
package/server/index.js
CHANGED
|
@@ -96,7 +96,7 @@ async function getPty() {
|
|
|
96
96
|
import fetch from 'node-fetch';
|
|
97
97
|
import mime from 'mime-types';
|
|
98
98
|
|
|
99
|
-
import { getProjects, getSessions, getSessionMessages, renameProject, deleteSession, deleteProject, addProjectManually, extractProjectDirectory, clearProjectDirectoryCache, clearProviderSessionLookupCaches, getGeminiSessionMessages } from './projects.js';
|
|
99
|
+
import { getProjects, getProjectsList, getProjectDetails, getSessions, getSessionMessages, renameProject, deleteSession, deleteProject, addProjectManually, extractProjectDirectory, clearProjectDirectoryCache, clearProviderSessionLookupCaches, getGeminiSessionMessages } from './projects.js';
|
|
100
100
|
import {
|
|
101
101
|
executeAgentPrompt,
|
|
102
102
|
getActiveAgentSessions,
|
|
@@ -333,8 +333,8 @@ async function setupProjectsWatcher() {
|
|
|
333
333
|
clearProjectDirectoryCache();
|
|
334
334
|
clearProviderSessionLookupCaches();
|
|
335
335
|
|
|
336
|
-
// Get updated projects list
|
|
337
|
-
const updatedProjects = await
|
|
336
|
+
// Get updated lightweight projects list
|
|
337
|
+
const updatedProjects = await getProjectsList(broadcastProgress);
|
|
338
338
|
|
|
339
339
|
// Notify all connected clients about the project changes
|
|
340
340
|
const changedProvider = filePath.startsWith(codexSessionsPath)
|
|
@@ -343,14 +343,21 @@ async function setupProjectsWatcher() {
|
|
|
343
343
|
const changedFileRoot = changedProvider === 'codex'
|
|
344
344
|
? codexSessionsPath
|
|
345
345
|
: claudeProjectsPath;
|
|
346
|
+
const normalizedRelativePath = path.relative(changedFileRoot, filePath);
|
|
347
|
+
const changedPathSegments = normalizedRelativePath.split(path.sep).filter(Boolean);
|
|
348
|
+
const affectedProjectName = changedProvider === 'claude'
|
|
349
|
+
? (changedPathSegments[0] || null)
|
|
350
|
+
: null;
|
|
346
351
|
const updateMessage = JSON.stringify({
|
|
347
352
|
type: 'projects_updated',
|
|
348
353
|
projects: updatedProjects,
|
|
349
354
|
timestamp: new Date().toISOString(),
|
|
350
355
|
changeType: eventType,
|
|
351
|
-
changedFile:
|
|
356
|
+
changedFile: normalizedRelativePath,
|
|
352
357
|
changedProvider,
|
|
353
|
-
changedSessionId: extractSessionIdFromChangedFile(filePath)
|
|
358
|
+
changedSessionId: extractSessionIdFromChangedFile(filePath),
|
|
359
|
+
affectedProjectName,
|
|
360
|
+
requiresDetailsRefresh: Boolean(affectedProjectName)
|
|
354
361
|
});
|
|
355
362
|
|
|
356
363
|
connectedClients.forEach(client => {
|
|
@@ -647,6 +654,7 @@ app.post('/api/system/update', authenticateToken, async (req, res) => {
|
|
|
647
654
|
|
|
648
655
|
app.get('/api/projects', authenticateToken, async (req, res) => {
|
|
649
656
|
try {
|
|
657
|
+
res.setHeader('Deprecation', 'true');
|
|
650
658
|
const projects = await getProjects(broadcastProgress);
|
|
651
659
|
res.json(projects);
|
|
652
660
|
} catch (error) {
|
|
@@ -654,6 +662,27 @@ app.get('/api/projects', authenticateToken, async (req, res) => {
|
|
|
654
662
|
}
|
|
655
663
|
});
|
|
656
664
|
|
|
665
|
+
app.get('/api/projects/list', authenticateToken, async (req, res) => {
|
|
666
|
+
try {
|
|
667
|
+
const projects = await getProjectsList(broadcastProgress);
|
|
668
|
+
res.json(projects);
|
|
669
|
+
} catch (error) {
|
|
670
|
+
res.status(500).json({ error: error.message });
|
|
671
|
+
}
|
|
672
|
+
});
|
|
673
|
+
|
|
674
|
+
app.get('/api/projects/:projectName/details', authenticateToken, async (req, res) => {
|
|
675
|
+
try {
|
|
676
|
+
const project = await getProjectDetails(req.params.projectName);
|
|
677
|
+
res.json(project);
|
|
678
|
+
} catch (error) {
|
|
679
|
+
if (/Project not found/i.test(error.message)) {
|
|
680
|
+
return res.status(404).json({ error: error.message });
|
|
681
|
+
}
|
|
682
|
+
res.status(500).json({ error: error.message });
|
|
683
|
+
}
|
|
684
|
+
});
|
|
685
|
+
|
|
657
686
|
app.get('/api/projects/:projectName/sessions', authenticateToken, async (req, res) => {
|
|
658
687
|
try {
|
|
659
688
|
const { limit = 5, offset = 0 } = req.query;
|