@ccpocket/bridge 1.52.2 → 1.53.1
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/auto-rename.d.ts +2 -0
- package/dist/auto-rename.js +5 -1
- package/dist/auto-rename.js.map +1 -1
- package/dist/codex-process.d.ts +7 -1
- package/dist/codex-process.js +38 -6
- package/dist/codex-process.js.map +1 -1
- package/dist/parser.d.ts +4 -0
- package/dist/parser.js +5 -0
- package/dist/parser.js.map +1 -1
- package/dist/session.d.ts +7 -8
- package/dist/session.js +30 -38
- package/dist/session.js.map +1 -1
- package/dist/sessions-index.d.ts +2 -0
- package/dist/sessions-index.js +250 -2
- package/dist/sessions-index.js.map +1 -1
- package/dist/websocket.d.ts +4 -0
- package/dist/websocket.js +256 -29
- package/dist/websocket.js.map +1 -1
- package/package.json +1 -1
package/dist/sessions-index.js
CHANGED
|
@@ -3,6 +3,8 @@ import { createReadStream } from "node:fs";
|
|
|
3
3
|
import { createInterface } from "node:readline";
|
|
4
4
|
import { basename, join } from "node:path";
|
|
5
5
|
import { homedir } from "node:os";
|
|
6
|
+
import { isAutoRenamePromptText } from "./auto-rename.js";
|
|
7
|
+
import { CODEX_ASSIST_MODEL } from "./codex-assist.js";
|
|
6
8
|
function createRecentSessionsPerfStats() {
|
|
7
9
|
return {
|
|
8
10
|
claudeProjectDirs: 0,
|
|
@@ -119,6 +121,9 @@ const RE_SYSTEM_INJECTED = /^<(?:local-command-caveat|local-command-std(?:err|ou
|
|
|
119
121
|
function isSystemInjectedText(text) {
|
|
120
122
|
return RE_SYSTEM_INJECTED.test(text) || text.startsWith("Base directory for this skill:");
|
|
121
123
|
}
|
|
124
|
+
function isCodexAutoRenameSession(firstPrompt, model) {
|
|
125
|
+
return model === CODEX_ASSIST_MODEL && isAutoRenamePromptText(firstPrompt);
|
|
126
|
+
}
|
|
122
127
|
/** Extract user prompt text from a parsed JSONL entry. */
|
|
123
128
|
function extractUserPromptText(entry) {
|
|
124
129
|
const message = entry.message;
|
|
@@ -147,6 +152,7 @@ function parseFromChunks(sessionId, head, tail) {
|
|
|
147
152
|
let headFoundFirstPrompt = false;
|
|
148
153
|
let headFoundProjectPath = false;
|
|
149
154
|
let headFoundGitBranch = false;
|
|
155
|
+
let isInternalAutoRename = false;
|
|
150
156
|
// --- Scan head lines ---
|
|
151
157
|
const headLines = head.split("\n");
|
|
152
158
|
for (const line of headLines) {
|
|
@@ -200,6 +206,10 @@ function parseFromChunks(sessionId, head, tail) {
|
|
|
200
206
|
const entry = JSON.parse(line);
|
|
201
207
|
const text = extractUserPromptText(entry);
|
|
202
208
|
if (text && !isSystemInjectedText(text)) {
|
|
209
|
+
if (isAutoRenamePromptText(text)) {
|
|
210
|
+
isInternalAutoRename = true;
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
203
213
|
firstPrompt = text;
|
|
204
214
|
headFoundFirstPrompt = true;
|
|
205
215
|
}
|
|
@@ -207,6 +217,14 @@ function parseFromChunks(sessionId, head, tail) {
|
|
|
207
217
|
catch { /* skip */ }
|
|
208
218
|
}
|
|
209
219
|
}
|
|
220
|
+
if (isInternalAutoRename) {
|
|
221
|
+
return {
|
|
222
|
+
entry: null,
|
|
223
|
+
headFoundFirstPrompt,
|
|
224
|
+
headFoundProjectPath,
|
|
225
|
+
headFoundGitBranch,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
210
228
|
// --- Scan tail lines (if separate from head) ---
|
|
211
229
|
if (tail) {
|
|
212
230
|
const tailLines = tail.split("\n");
|
|
@@ -288,6 +306,14 @@ function parseFromChunks(sessionId, head, tail) {
|
|
|
288
306
|
headFoundGitBranch,
|
|
289
307
|
};
|
|
290
308
|
}
|
|
309
|
+
if (isAutoRenamePromptText(firstPrompt)) {
|
|
310
|
+
return {
|
|
311
|
+
entry: null,
|
|
312
|
+
headFoundFirstPrompt,
|
|
313
|
+
headFoundProjectPath,
|
|
314
|
+
headFoundGitBranch,
|
|
315
|
+
};
|
|
316
|
+
}
|
|
291
317
|
return {
|
|
292
318
|
entry: {
|
|
293
319
|
sessionId,
|
|
@@ -361,6 +387,9 @@ async function parseClaudeJsonlFileFast(sessionId, filePath) {
|
|
|
361
387
|
if (!result.firstPrompt && missing.firstPrompt) {
|
|
362
388
|
result.firstPrompt = missing.firstPrompt;
|
|
363
389
|
}
|
|
390
|
+
if (isAutoRenamePromptText(result.firstPrompt)) {
|
|
391
|
+
return null;
|
|
392
|
+
}
|
|
364
393
|
if (missing.projectPath) {
|
|
365
394
|
result.projectPath = missing.projectPath;
|
|
366
395
|
if (missing.rawCwd && missing.rawCwd !== missing.projectPath) {
|
|
@@ -377,6 +406,8 @@ async function parseClaudeJsonlFileFast(sessionId, filePath) {
|
|
|
377
406
|
return result;
|
|
378
407
|
}
|
|
379
408
|
async function hydrateClaudeIndexedEntry(dirPath, entry) {
|
|
409
|
+
if (isAutoRenamePromptText(entry.firstPrompt ?? ""))
|
|
410
|
+
return null;
|
|
380
411
|
const rawProjectPath = entry.projectPath ?? "";
|
|
381
412
|
const normalizedPath = normalizeWorktreePath(rawProjectPath);
|
|
382
413
|
const base = {
|
|
@@ -404,6 +435,8 @@ async function hydrateClaudeIndexedEntry(dirPath, entry) {
|
|
|
404
435
|
const parsed = await parseClaudeJsonlFileFast(entry.sessionId, fallbackPath);
|
|
405
436
|
if (!parsed)
|
|
406
437
|
return base;
|
|
438
|
+
if (isAutoRenamePromptText(parsed.firstPrompt))
|
|
439
|
+
return null;
|
|
407
440
|
return {
|
|
408
441
|
...base,
|
|
409
442
|
firstPrompt: base.firstPrompt || parsed.firstPrompt,
|
|
@@ -677,8 +710,11 @@ export async function getAllRecentSessions(options = {}) {
|
|
|
677
710
|
continue;
|
|
678
711
|
}
|
|
679
712
|
indexedIds.add(entry.sessionId);
|
|
680
|
-
|
|
681
|
-
|
|
713
|
+
const hydrated = await hydrateClaudeIndexedEntry(dirPath, entry);
|
|
714
|
+
if (hydrated) {
|
|
715
|
+
result.entries.push(hydrated);
|
|
716
|
+
result.indexEntries += 1;
|
|
717
|
+
}
|
|
682
718
|
}
|
|
683
719
|
if (!includeOnlyNamedClaude) {
|
|
684
720
|
const scanned = await scanJsonlDir(dirPath, {
|
|
@@ -981,6 +1017,8 @@ function parseCodexSessionJsonl(raw, fallbackSessionId) {
|
|
|
981
1017
|
}
|
|
982
1018
|
if (model === "codex-auto-review")
|
|
983
1019
|
return null;
|
|
1020
|
+
if (isCodexAutoRenameSession(firstPrompt, model))
|
|
1021
|
+
return null;
|
|
984
1022
|
if (!projectPath || !hasMessages)
|
|
985
1023
|
return null;
|
|
986
1024
|
summary = lastAssistantText || summary;
|
|
@@ -1348,6 +1386,216 @@ async function getAllRecentCodexSessions(options = {}) {
|
|
|
1348
1386
|
export function codexUserTurnUuid(ordinal) {
|
|
1349
1387
|
return `codex:user-turn:${ordinal}`;
|
|
1350
1388
|
}
|
|
1389
|
+
function numberToIsoTimestamp(value) {
|
|
1390
|
+
return typeof value === "number" && Number.isFinite(value)
|
|
1391
|
+
? new Date(value * 1000).toISOString()
|
|
1392
|
+
: undefined;
|
|
1393
|
+
}
|
|
1394
|
+
function stringValue(value) {
|
|
1395
|
+
return typeof value === "string" ? value : undefined;
|
|
1396
|
+
}
|
|
1397
|
+
function arrayValue(value) {
|
|
1398
|
+
return Array.isArray(value) ? value : [];
|
|
1399
|
+
}
|
|
1400
|
+
function codexToolResultContent(value) {
|
|
1401
|
+
if (value == null)
|
|
1402
|
+
return "";
|
|
1403
|
+
if (typeof value === "string")
|
|
1404
|
+
return value;
|
|
1405
|
+
try {
|
|
1406
|
+
return JSON.stringify(value, null, 2);
|
|
1407
|
+
}
|
|
1408
|
+
catch {
|
|
1409
|
+
return String(value);
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
function codexUserInputTextAndImages(content) {
|
|
1413
|
+
const textParts = [];
|
|
1414
|
+
let imageCount = 0;
|
|
1415
|
+
for (const entry of arrayValue(content)) {
|
|
1416
|
+
const item = asObject(entry);
|
|
1417
|
+
if (!item)
|
|
1418
|
+
continue;
|
|
1419
|
+
if (item.type === "text" && typeof item.text === "string") {
|
|
1420
|
+
textParts.push(item.text);
|
|
1421
|
+
}
|
|
1422
|
+
else if (item.type === "image" || item.type === "localImage") {
|
|
1423
|
+
imageCount += 1;
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
return { text: textParts.join("\n"), imageCount };
|
|
1427
|
+
}
|
|
1428
|
+
function appendCodexThinkingMessage(messages, text, timestamp) {
|
|
1429
|
+
const normalized = text.trim();
|
|
1430
|
+
if (!normalized)
|
|
1431
|
+
return;
|
|
1432
|
+
messages.push({
|
|
1433
|
+
role: "assistant",
|
|
1434
|
+
content: [{ type: "thinking", thinking: normalized }],
|
|
1435
|
+
...(timestamp ? { timestamp } : {}),
|
|
1436
|
+
});
|
|
1437
|
+
}
|
|
1438
|
+
function appendCodexOfficialToolResult(messages, id, name, content, timestamp) {
|
|
1439
|
+
appendToolResultMessage(messages, id, name, content, {
|
|
1440
|
+
...(timestamp ? { timestamp } : {}),
|
|
1441
|
+
});
|
|
1442
|
+
}
|
|
1443
|
+
export function codexThreadToSessionHistory(thread) {
|
|
1444
|
+
const messages = [];
|
|
1445
|
+
const turns = arrayValue(asObject(thread)?.turns);
|
|
1446
|
+
let userTurnOrdinal = 0;
|
|
1447
|
+
for (const rawTurn of turns) {
|
|
1448
|
+
const turn = asObject(rawTurn);
|
|
1449
|
+
if (!turn)
|
|
1450
|
+
continue;
|
|
1451
|
+
const turnStartedAt = numberToIsoTimestamp(turn.startedAt);
|
|
1452
|
+
const turnCompletedAt = numberToIsoTimestamp(turn.completedAt);
|
|
1453
|
+
for (const rawItem of arrayValue(turn.items)) {
|
|
1454
|
+
const item = asObject(rawItem);
|
|
1455
|
+
if (!item || typeof item.type !== "string")
|
|
1456
|
+
continue;
|
|
1457
|
+
const itemId = stringValue(item.id) ?? `codex-item-${messages.length}`;
|
|
1458
|
+
const itemTimestamp = turnCompletedAt ?? turnStartedAt;
|
|
1459
|
+
switch (item.type) {
|
|
1460
|
+
case "userMessage": {
|
|
1461
|
+
const { text, imageCount } = codexUserInputTextAndImages(item.content);
|
|
1462
|
+
const displayText = text.trim().length > 0
|
|
1463
|
+
? text
|
|
1464
|
+
: imageCount > 0
|
|
1465
|
+
? `[Image attached${imageCount > 1 ? ` x${imageCount}` : ""}]`
|
|
1466
|
+
: "";
|
|
1467
|
+
if (displayText.trim().length === 0)
|
|
1468
|
+
break;
|
|
1469
|
+
userTurnOrdinal += 1;
|
|
1470
|
+
messages.push({
|
|
1471
|
+
role: "user",
|
|
1472
|
+
uuid: codexUserTurnUuid(userTurnOrdinal),
|
|
1473
|
+
content: [{ type: "text", text: displayText }],
|
|
1474
|
+
...(imageCount > 0 ? { imageCount } : {}),
|
|
1475
|
+
...(turnStartedAt ? { timestamp: turnStartedAt } : {}),
|
|
1476
|
+
});
|
|
1477
|
+
break;
|
|
1478
|
+
}
|
|
1479
|
+
case "agentMessage": {
|
|
1480
|
+
appendTextMessage(messages, "assistant", stringValue(item.text) ?? "", itemTimestamp);
|
|
1481
|
+
break;
|
|
1482
|
+
}
|
|
1483
|
+
case "plan": {
|
|
1484
|
+
appendTextMessage(messages, "assistant", stringValue(item.text) ?? "", itemTimestamp);
|
|
1485
|
+
break;
|
|
1486
|
+
}
|
|
1487
|
+
case "reasoning": {
|
|
1488
|
+
const summary = arrayValue(item.summary)
|
|
1489
|
+
.filter((value) => typeof value === "string");
|
|
1490
|
+
const content = arrayValue(item.content)
|
|
1491
|
+
.filter((value) => typeof value === "string");
|
|
1492
|
+
appendCodexThinkingMessage(messages, [...summary, ...content].join("\n"), itemTimestamp);
|
|
1493
|
+
break;
|
|
1494
|
+
}
|
|
1495
|
+
case "commandExecution": {
|
|
1496
|
+
const command = stringValue(item.command) ?? "";
|
|
1497
|
+
appendToolUseMessage(messages, itemId, "Bash", {
|
|
1498
|
+
command,
|
|
1499
|
+
...(typeof item.cwd === "string" ? { cwd: item.cwd } : {}),
|
|
1500
|
+
});
|
|
1501
|
+
const outputParts = [];
|
|
1502
|
+
if (typeof item.status === "string") {
|
|
1503
|
+
outputParts.push(`status: ${item.status}`);
|
|
1504
|
+
}
|
|
1505
|
+
if (typeof item.exitCode === "number") {
|
|
1506
|
+
outputParts.push(`exitCode: ${item.exitCode}`);
|
|
1507
|
+
}
|
|
1508
|
+
if (typeof item.aggregatedOutput === "string") {
|
|
1509
|
+
outputParts.push(item.aggregatedOutput);
|
|
1510
|
+
}
|
|
1511
|
+
appendCodexOfficialToolResult(messages, itemId, "Bash", outputParts.join("\n").trim(), itemTimestamp);
|
|
1512
|
+
break;
|
|
1513
|
+
}
|
|
1514
|
+
case "fileChange": {
|
|
1515
|
+
appendToolUseMessage(messages, itemId, "FileChange", {
|
|
1516
|
+
changes: Array.isArray(item.changes) ? item.changes : [],
|
|
1517
|
+
...(typeof item.status === "string" ? { status: item.status } : {}),
|
|
1518
|
+
});
|
|
1519
|
+
break;
|
|
1520
|
+
}
|
|
1521
|
+
case "mcpToolCall": {
|
|
1522
|
+
const server = stringValue(item.server) ?? "mcp";
|
|
1523
|
+
const tool = stringValue(item.tool) ?? "tool";
|
|
1524
|
+
appendToolUseMessage(messages, itemId, `mcp:${server}/${tool}`, {
|
|
1525
|
+
arguments: item.arguments ?? {},
|
|
1526
|
+
...(typeof item.status === "string" ? { status: item.status } : {}),
|
|
1527
|
+
});
|
|
1528
|
+
if (item.result != null || item.error != null) {
|
|
1529
|
+
const normalized = normalizeCodexMcpResult(item.result ?? item.error);
|
|
1530
|
+
appendToolResultMessage(messages, itemId, `mcp:${server}/${tool}`, normalized.content, {
|
|
1531
|
+
imageBase64: normalized.imageBase64,
|
|
1532
|
+
...(itemTimestamp ? { timestamp: itemTimestamp } : {}),
|
|
1533
|
+
});
|
|
1534
|
+
}
|
|
1535
|
+
break;
|
|
1536
|
+
}
|
|
1537
|
+
case "dynamicToolCall": {
|
|
1538
|
+
const tool = stringValue(item.tool) ?? "tool";
|
|
1539
|
+
appendToolUseMessage(messages, itemId, tool, {
|
|
1540
|
+
arguments: item.arguments ?? {},
|
|
1541
|
+
...(typeof item.status === "string" ? { status: item.status } : {}),
|
|
1542
|
+
});
|
|
1543
|
+
const contentItems = arrayValue(item.contentItems);
|
|
1544
|
+
const resultText = contentItems
|
|
1545
|
+
.map((entry) => {
|
|
1546
|
+
const contentItem = asObject(entry);
|
|
1547
|
+
if (!contentItem)
|
|
1548
|
+
return "";
|
|
1549
|
+
if (contentItem.type === "inputText" &&
|
|
1550
|
+
typeof contentItem.text === "string") {
|
|
1551
|
+
return contentItem.text;
|
|
1552
|
+
}
|
|
1553
|
+
if (contentItem.type === "inputImage" &&
|
|
1554
|
+
typeof contentItem.imageUrl === "string") {
|
|
1555
|
+
return contentItem.imageUrl;
|
|
1556
|
+
}
|
|
1557
|
+
return codexToolResultContent(contentItem);
|
|
1558
|
+
})
|
|
1559
|
+
.filter(Boolean)
|
|
1560
|
+
.join("\n");
|
|
1561
|
+
appendCodexOfficialToolResult(messages, itemId, tool, resultText, itemTimestamp);
|
|
1562
|
+
break;
|
|
1563
|
+
}
|
|
1564
|
+
case "webSearch": {
|
|
1565
|
+
appendToolUseMessage(messages, itemId, "WebSearch", {
|
|
1566
|
+
query: stringValue(item.query) ?? "",
|
|
1567
|
+
...(item.action != null ? { action: item.action } : {}),
|
|
1568
|
+
});
|
|
1569
|
+
break;
|
|
1570
|
+
}
|
|
1571
|
+
case "imageGeneration": {
|
|
1572
|
+
appendToolUseMessage(messages, itemId, "ImageGeneration", {
|
|
1573
|
+
...(typeof item.status === "string" ? { status: item.status } : {}),
|
|
1574
|
+
...(typeof item.revisedPrompt === "string"
|
|
1575
|
+
? { revisedPrompt: item.revisedPrompt }
|
|
1576
|
+
: {}),
|
|
1577
|
+
});
|
|
1578
|
+
appendImageGenerationResult(messages, {
|
|
1579
|
+
id: itemId,
|
|
1580
|
+
status: item.status,
|
|
1581
|
+
revisedPrompt: item.revisedPrompt,
|
|
1582
|
+
savedPath: item.savedPath,
|
|
1583
|
+
result: item.result,
|
|
1584
|
+
}, itemId, itemTimestamp);
|
|
1585
|
+
break;
|
|
1586
|
+
}
|
|
1587
|
+
case "enteredReviewMode":
|
|
1588
|
+
case "exitedReviewMode": {
|
|
1589
|
+
appendTextMessage(messages, "assistant", stringValue(item.review) ?? "", itemTimestamp);
|
|
1590
|
+
break;
|
|
1591
|
+
}
|
|
1592
|
+
default:
|
|
1593
|
+
break;
|
|
1594
|
+
}
|
|
1595
|
+
}
|
|
1596
|
+
}
|
|
1597
|
+
return messages;
|
|
1598
|
+
}
|
|
1351
1599
|
function asObject(value) {
|
|
1352
1600
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
1353
1601
|
return null;
|