claude-simple 0.2.6 → 0.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/app.0.2.8.min.js +1080 -0
- package/dist/index.html +2 -2
- package/dist/style.0.2.8.min.css +1598 -0
- package/gateway.js +0 -0
- package/package.json +1 -1
- package/public/addon-fit.min.js +0 -0
- package/public/agent-panel.js +245 -1
- package/public/api.js +4 -0
- package/public/app.js +0 -0
- package/public/base.css +0 -0
- package/public/cache.js +0 -0
- package/public/chat.js +118 -17
- package/public/files.js +0 -0
- package/public/git.js +0 -0
- package/public/icons/icon-180.png +0 -0
- package/public/icons/icon-192.png +0 -0
- package/public/icons/icon-512.png +0 -0
- package/public/icons/icon-maskable-512.png +0 -0
- package/public/index.html +2 -2
- package/public/lib.js +0 -0
- package/public/manifest.webmanifest +0 -0
- package/public/mobile.js +0 -0
- package/public/notifications.js +215 -0
- package/public/offline.html +0 -0
- package/public/pwa.js +0 -0
- package/public/router.js +0 -0
- package/public/settings.js +0 -0
- package/public/shell/boot.js +0 -0
- package/public/shell/dashboard.js +72 -23
- package/public/shell/hub.js +0 -0
- package/public/shell/layout.js +41 -12
- package/public/shell/notes.js +0 -0
- package/public/shell/session-context.js +0 -0
- package/public/shell/session-list.js +27 -28
- package/public/shell/session-nav.js +36 -1
- package/public/shell/templates.js +45 -7
- package/public/shell/util.js +0 -0
- package/public/shell.js +56 -7
- package/public/state.js +53 -13
- package/public/style.css +100 -6
- package/public/sw.js +2 -2
- package/public/terminal.js +77 -3
- package/public/wake-lock.js +0 -0
- package/public/xterm.min.css +0 -0
- package/public/xterm.min.js +0 -0
- package/src/agents/claude.js +1 -1
- package/src/agents/codex.js +1 -0
- package/src/agents/grok.js +180 -298
- package/src/agents/meta-agent.js +332 -1
- package/src/agents/models.js +0 -0
- package/src/agents/sessions.js +106 -26
- package/src/agents/stream-batch.js +0 -0
- package/src/app.js +88 -11
- package/src/auto-update.js +0 -0
- package/src/runtime/approvals.js +0 -0
- package/src/runtime/outbox.js +0 -0
- package/src/runtime/protocol.js +0 -0
- package/dist/app.0.2.6.min.js +0 -953
- package/dist/style.0.2.6.min.css +0 -1504
package/src/app.js
CHANGED
|
@@ -18,6 +18,8 @@ import {
|
|
|
18
18
|
scanAllSessions,
|
|
19
19
|
loadSessionMessages,
|
|
20
20
|
loadSessionMemory,
|
|
21
|
+
readSessionMemoryFile,
|
|
22
|
+
loadSessionJsonl,
|
|
21
23
|
loadSessionUsage,
|
|
22
24
|
searchActivity,
|
|
23
25
|
groupByProject,
|
|
@@ -1008,19 +1010,37 @@ export function createApp() {
|
|
|
1008
1010
|
codexHome: CODEX_HOME,
|
|
1009
1011
|
grokHome: GROK_HOME,
|
|
1010
1012
|
};
|
|
1011
|
-
|
|
1013
|
+
// A selected session already knows its agent. Do not fall back to another
|
|
1014
|
+
// agent's account-level memory (especially Codex) when that session has none.
|
|
1015
|
+
const order = preferred
|
|
1016
|
+
? [preferred]
|
|
1017
|
+
: [...new Set([...ENABLED_AGENTS, 'claude', 'codex', 'grok'])];
|
|
1012
1018
|
let memory = null;
|
|
1013
1019
|
for (const a of order) {
|
|
1014
1020
|
memory = await loadSessionMemory(sessionId, a, opts);
|
|
1015
1021
|
if (memory) break;
|
|
1016
1022
|
}
|
|
1017
|
-
|
|
1018
|
-
res.json(memory || { index: null, files: [] });
|
|
1023
|
+
res.json(memory || { agent: preferred || null, files: [] });
|
|
1019
1024
|
} catch (e) {
|
|
1020
1025
|
res.status(500).json({ error: e.message });
|
|
1021
1026
|
}
|
|
1022
1027
|
});
|
|
1023
1028
|
|
|
1029
|
+
app.get('/api/sessions/:sessionId/memory/file', authMiddleware, async (req, res) => {
|
|
1030
|
+
try {
|
|
1031
|
+
const { sessionId } = req.params;
|
|
1032
|
+
const agent = typeof req.query.agent === 'string' ? req.query.agent : 'claude';
|
|
1033
|
+
const file = typeof req.query.file === 'string' ? req.query.file : '';
|
|
1034
|
+
if (!/^[0-9a-f-]{36}$/i.test(sessionId)) return res.status(400).json({ error: 'Invalid session id' });
|
|
1035
|
+
const row = await readSessionMemoryFile(sessionId, agent, file, {
|
|
1036
|
+
claudeConfigDirs: CLAUDE_CONFIG_DIRS, codexHome: CODEX_HOME, grokHome: GROK_HOME,
|
|
1037
|
+
});
|
|
1038
|
+
if (!row) return res.status(404).json({ error: 'Memory file not found' });
|
|
1039
|
+
res.setHeader('Cache-Control', 'private, max-age=30');
|
|
1040
|
+
res.json(row);
|
|
1041
|
+
} catch (e) { res.status(500).json({ error: e.message }); }
|
|
1042
|
+
});
|
|
1043
|
+
|
|
1024
1044
|
app.get('/api/projects/:id/git/log', authMiddleware, async (req, res) => {
|
|
1025
1045
|
try {
|
|
1026
1046
|
const projectPath = resolveProjectRoot(req);
|
|
@@ -1044,10 +1064,12 @@ export function createApp() {
|
|
|
1044
1064
|
listSessions,
|
|
1045
1065
|
searchActivity,
|
|
1046
1066
|
loadSessionMessages,
|
|
1067
|
+
loadSessionJsonl,
|
|
1047
1068
|
groupByProject,
|
|
1048
1069
|
toClientSession,
|
|
1049
1070
|
getProjectNotesStore: loadProjectNotes,
|
|
1050
1071
|
saveProjectNotesStore: saveProjectNotes,
|
|
1072
|
+
getSessionMetaStore: loadSessionMeta,
|
|
1051
1073
|
normalizeProjectEntry,
|
|
1052
1074
|
git,
|
|
1053
1075
|
isGitRepo,
|
|
@@ -1122,6 +1144,50 @@ export function createApp() {
|
|
|
1122
1144
|
}
|
|
1123
1145
|
});
|
|
1124
1146
|
|
|
1147
|
+
app.get('/api/ai/notes', authMiddleware, async (req, res) => {
|
|
1148
|
+
try {
|
|
1149
|
+
const limit = Math.min(parseInt(req.query.limit || '30', 10) || 30, 200);
|
|
1150
|
+
const scope = typeof req.query.scope === 'string' ? req.query.scope : 'all';
|
|
1151
|
+
const q = typeof req.query.q === 'string' ? req.query.q : '';
|
|
1152
|
+
const cwd = typeof req.query.cwd === 'string' ? req.query.cwd : '';
|
|
1153
|
+
const sessionId = typeof req.query.sessionId === 'string' ? req.query.sessionId : '';
|
|
1154
|
+
const agent = typeof req.query.agent === 'string' ? req.query.agent : '';
|
|
1155
|
+
res.json({
|
|
1156
|
+
notes: await meta.listMetaNotes({ limit, scope, q, cwd, sessionId, agent }),
|
|
1157
|
+
});
|
|
1158
|
+
} catch (e) {
|
|
1159
|
+
res.status(500).json({ error: e.message });
|
|
1160
|
+
}
|
|
1161
|
+
});
|
|
1162
|
+
|
|
1163
|
+
app.get('/api/ai/notes/:id', authMiddleware, async (req, res) => {
|
|
1164
|
+
try {
|
|
1165
|
+
const note = await meta.getMetaNote(req.params.id);
|
|
1166
|
+
if (!note) return res.status(404).json({ error: 'not found' });
|
|
1167
|
+
res.json(note);
|
|
1168
|
+
} catch (e) {
|
|
1169
|
+
res.status(500).json({ error: e.message });
|
|
1170
|
+
}
|
|
1171
|
+
});
|
|
1172
|
+
|
|
1173
|
+
app.post('/api/ai/notes', authMiddleware, async (req, res) => {
|
|
1174
|
+
try {
|
|
1175
|
+
const note = await meta.saveMetaNote(req.body || {});
|
|
1176
|
+
res.json(note);
|
|
1177
|
+
} catch (e) {
|
|
1178
|
+
res.status(500).json({ error: e.message });
|
|
1179
|
+
}
|
|
1180
|
+
});
|
|
1181
|
+
|
|
1182
|
+
app.delete('/api/ai/notes/:id', authMiddleware, async (req, res) => {
|
|
1183
|
+
try {
|
|
1184
|
+
const result = await meta.deleteMetaNote(req.params.id);
|
|
1185
|
+
res.json(result);
|
|
1186
|
+
} catch (e) {
|
|
1187
|
+
res.status(500).json({ error: e.message });
|
|
1188
|
+
}
|
|
1189
|
+
});
|
|
1190
|
+
|
|
1125
1191
|
// SSE: generate work report
|
|
1126
1192
|
app.post('/api/ai/report', authMiddleware, async (req, res) => {
|
|
1127
1193
|
res.setHeader('Content-Type', 'text/event-stream; charset=utf-8');
|
|
@@ -1392,24 +1458,35 @@ export function createApp() {
|
|
|
1392
1458
|
if (cmd.sessionId) options.sessionId = cmd.sessionId;
|
|
1393
1459
|
if (cmd.cwd) options.cwd = cmd.cwd;
|
|
1394
1460
|
if (options.sessionId) client.sessionId = options.sessionId;
|
|
1395
|
-
|
|
1461
|
+
// A socket may subscribe to another session while this agent is still
|
|
1462
|
+
// streaming. Keep this run's delivery target in its own closure rather
|
|
1463
|
+
// than consulting mutable client.sessionId in the shared socket outbox.
|
|
1464
|
+
let runSessionId = options.sessionId || client.sessionId || null;
|
|
1465
|
+
const runOutbox = createOutbox((data) => {
|
|
1466
|
+
broadcastChat(runSessionId, data, ws);
|
|
1467
|
+
}, {
|
|
1468
|
+
maxWait: 48,
|
|
1469
|
+
maxDeltaChars: 720,
|
|
1470
|
+
maxBatchItems: 10,
|
|
1471
|
+
maxBatchBytes: 10_000,
|
|
1472
|
+
});
|
|
1473
|
+
const agentSend = createAgentSend(runOutbox, agent);
|
|
1396
1474
|
const runSend = (data) => {
|
|
1475
|
+
if (data?.sessionId) runSessionId = data.sessionId;
|
|
1397
1476
|
if (data?.type === 'result' || data?.type === 'complete' || data?.type === 'error') {
|
|
1398
|
-
markSessionIdle(data.sessionId ||
|
|
1399
|
-
|
|
1477
|
+
markSessionIdle(data.sessionId || runSessionId, options.sessionId);
|
|
1478
|
+
runOutbox.flush();
|
|
1400
1479
|
}
|
|
1401
|
-
if (data?.sessionId) client.sessionId = data.sessionId;
|
|
1402
|
-
if (data?.type === 'session-created' && data.sessionId) client.sessionId = data.sessionId;
|
|
1403
1480
|
// permission_request bypasses map filter double-pass carefully
|
|
1404
1481
|
if (data?.type === 'permission_request' || data?.type === 'permission_resolved') {
|
|
1405
|
-
|
|
1406
|
-
|
|
1482
|
+
runOutbox.send(data);
|
|
1483
|
+
runOutbox.flush();
|
|
1407
1484
|
return;
|
|
1408
1485
|
}
|
|
1409
1486
|
agentSend(data);
|
|
1410
1487
|
};
|
|
1411
1488
|
await dispatchAgent(agent, cmd.command || '', options, runSend);
|
|
1412
|
-
|
|
1489
|
+
runOutbox.flush();
|
|
1413
1490
|
return;
|
|
1414
1491
|
}
|
|
1415
1492
|
|
package/src/auto-update.js
CHANGED
|
File without changes
|
package/src/runtime/approvals.js
CHANGED
|
File without changes
|
package/src/runtime/outbox.js
CHANGED
|
File without changes
|
package/src/runtime/protocol.js
CHANGED
|
File without changes
|