@ccpocket/bridge 1.48.0 → 1.49.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/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/parser.d.ts +51 -0
- package/dist/parser.js +82 -0
- package/dist/parser.js.map +1 -1
- package/dist/prompt-history-store.d.ts +82 -0
- package/dist/prompt-history-store.js +322 -0
- package/dist/prompt-history-store.js.map +1 -0
- package/dist/session.js +6 -7
- package/dist/session.js.map +1 -1
- package/dist/websocket.d.ts +5 -0
- package/dist/websocket.js +175 -5
- package/dist/websocket.js.map +1 -1
- package/package.json +1 -1
package/dist/websocket.js
CHANGED
|
@@ -38,6 +38,10 @@ const CODEX_MODELS = [
|
|
|
38
38
|
"gpt-5.3-codex",
|
|
39
39
|
"gpt-5.3-codex-spark",
|
|
40
40
|
];
|
|
41
|
+
const OPT_IN_SERVER_MESSAGES = new Set([
|
|
42
|
+
"conversation_queue",
|
|
43
|
+
"prompt_history_status",
|
|
44
|
+
]);
|
|
41
45
|
// ---- Codex mode mapping helpers ----
|
|
42
46
|
/** Map unified PermissionMode to Codex approval_policy.
|
|
43
47
|
* Only "bypassPermissions" maps to "never"; all others use "on-request". */
|
|
@@ -166,6 +170,7 @@ export class BridgeWebSocketServer {
|
|
|
166
170
|
worktreeStore;
|
|
167
171
|
pushRelay;
|
|
168
172
|
promptHistoryBackup;
|
|
173
|
+
promptHistoryStore;
|
|
169
174
|
recentSessionsRequestId = 0;
|
|
170
175
|
debugEvents = new Map();
|
|
171
176
|
notifiedPermissionToolUses = new Map();
|
|
@@ -181,7 +186,7 @@ export class BridgeWebSocketServer {
|
|
|
181
186
|
platform;
|
|
182
187
|
clientSupportedServerMessages = new WeakMap();
|
|
183
188
|
constructor(options) {
|
|
184
|
-
const { server, apiKey, allowedDirs, imageStore, galleryStore, projectHistory, debugTraceStore, recordingStore, firebaseAuth, promptHistoryBackup, platform, } = options;
|
|
189
|
+
const { server, apiKey, allowedDirs, imageStore, galleryStore, projectHistory, debugTraceStore, recordingStore, firebaseAuth, promptHistoryBackup, promptHistoryStore, platform, } = options;
|
|
185
190
|
this.apiKey = apiKey ?? null;
|
|
186
191
|
this.allowedDirs = allowedDirs ?? [];
|
|
187
192
|
this.imageStore = imageStore ?? null;
|
|
@@ -192,6 +197,7 @@ export class BridgeWebSocketServer {
|
|
|
192
197
|
this.worktreeStore = new WorktreeStore();
|
|
193
198
|
this.pushRelay = new PushRelayClient({ firebaseAuth });
|
|
194
199
|
this.promptHistoryBackup = promptHistoryBackup ?? null;
|
|
200
|
+
this.promptHistoryStore = promptHistoryStore ?? null;
|
|
195
201
|
this.platform = platform ?? process.platform;
|
|
196
202
|
this.archiveStore = new ArchiveStore();
|
|
197
203
|
void this.debugTraceStore.init().catch((err) => {
|
|
@@ -544,6 +550,7 @@ export class BridgeWebSocketServer {
|
|
|
544
550
|
async handleClientMessage(msg, ws) {
|
|
545
551
|
if (msg.type === "client_capabilities") {
|
|
546
552
|
this.clientSupportedServerMessages.set(ws, new Set(msg.supportedServerMessages ?? []));
|
|
553
|
+
this.sendPromptHistoryStatus(ws);
|
|
547
554
|
return;
|
|
548
555
|
}
|
|
549
556
|
const incomingSessionId = this.extractSessionIdFromClientMessage(msg);
|
|
@@ -3205,6 +3212,144 @@ export class BridgeWebSocketServer {
|
|
|
3205
3212
|
});
|
|
3206
3213
|
break;
|
|
3207
3214
|
}
|
|
3215
|
+
case "record_prompt_history": {
|
|
3216
|
+
if (!this.promptHistoryStore) {
|
|
3217
|
+
this.send(ws, {
|
|
3218
|
+
type: "prompt_history_mutation_result",
|
|
3219
|
+
success: false,
|
|
3220
|
+
error: "Prompt history store not available",
|
|
3221
|
+
});
|
|
3222
|
+
break;
|
|
3223
|
+
}
|
|
3224
|
+
try {
|
|
3225
|
+
const entry = await this.promptHistoryStore.record({
|
|
3226
|
+
text: msg.text,
|
|
3227
|
+
projectPath: msg.projectPath,
|
|
3228
|
+
clientId: msg.clientId,
|
|
3229
|
+
clientName: msg.clientName,
|
|
3230
|
+
sessionId: msg.sessionId,
|
|
3231
|
+
usedAt: msg.usedAt,
|
|
3232
|
+
});
|
|
3233
|
+
this.send(ws, {
|
|
3234
|
+
type: "prompt_history_mutation_result",
|
|
3235
|
+
success: true,
|
|
3236
|
+
bridgeInstanceId: this.promptHistoryStore.bridgeInstanceId,
|
|
3237
|
+
revision: this.promptHistoryStore.revision,
|
|
3238
|
+
entry,
|
|
3239
|
+
});
|
|
3240
|
+
this.broadcastPromptHistoryStatus();
|
|
3241
|
+
}
|
|
3242
|
+
catch (err) {
|
|
3243
|
+
this.send(ws, {
|
|
3244
|
+
type: "prompt_history_mutation_result",
|
|
3245
|
+
success: false,
|
|
3246
|
+
error: err instanceof Error ? err.message : String(err),
|
|
3247
|
+
});
|
|
3248
|
+
}
|
|
3249
|
+
break;
|
|
3250
|
+
}
|
|
3251
|
+
case "sync_prompt_history": {
|
|
3252
|
+
if (!this.promptHistoryStore) {
|
|
3253
|
+
this.send(ws, {
|
|
3254
|
+
type: "prompt_history_sync_result",
|
|
3255
|
+
success: false,
|
|
3256
|
+
error: "Prompt history store not available",
|
|
3257
|
+
});
|
|
3258
|
+
break;
|
|
3259
|
+
}
|
|
3260
|
+
try {
|
|
3261
|
+
if (msg.entries?.length) {
|
|
3262
|
+
await this.promptHistoryStore.mergeClientEntries(msg.entries);
|
|
3263
|
+
}
|
|
3264
|
+
this.send(ws, {
|
|
3265
|
+
type: "prompt_history_sync_result",
|
|
3266
|
+
success: true,
|
|
3267
|
+
bridgeInstanceId: this.promptHistoryStore.bridgeInstanceId,
|
|
3268
|
+
revision: this.promptHistoryStore.revision,
|
|
3269
|
+
syncedAt: new Date().toISOString(),
|
|
3270
|
+
fullSnapshot: true,
|
|
3271
|
+
entries: this.promptHistoryStore.list(msg.includeDeleted ?? true),
|
|
3272
|
+
});
|
|
3273
|
+
this.broadcastPromptHistoryStatus();
|
|
3274
|
+
}
|
|
3275
|
+
catch (err) {
|
|
3276
|
+
this.send(ws, {
|
|
3277
|
+
type: "prompt_history_sync_result",
|
|
3278
|
+
success: false,
|
|
3279
|
+
error: err instanceof Error ? err.message : String(err),
|
|
3280
|
+
});
|
|
3281
|
+
}
|
|
3282
|
+
break;
|
|
3283
|
+
}
|
|
3284
|
+
case "mutate_prompt_history": {
|
|
3285
|
+
if (!this.promptHistoryStore) {
|
|
3286
|
+
this.send(ws, {
|
|
3287
|
+
type: "prompt_history_mutation_result",
|
|
3288
|
+
success: false,
|
|
3289
|
+
error: "Prompt history store not available",
|
|
3290
|
+
});
|
|
3291
|
+
break;
|
|
3292
|
+
}
|
|
3293
|
+
try {
|
|
3294
|
+
const entry = await this.promptHistoryStore.mutate({
|
|
3295
|
+
id: msg.id,
|
|
3296
|
+
text: msg.text,
|
|
3297
|
+
projectPath: msg.projectPath,
|
|
3298
|
+
action: msg.action,
|
|
3299
|
+
isFavorite: msg.isFavorite,
|
|
3300
|
+
updatedAt: msg.updatedAt,
|
|
3301
|
+
});
|
|
3302
|
+
this.send(ws, {
|
|
3303
|
+
type: "prompt_history_mutation_result",
|
|
3304
|
+
success: entry != null,
|
|
3305
|
+
bridgeInstanceId: this.promptHistoryStore.bridgeInstanceId,
|
|
3306
|
+
revision: this.promptHistoryStore.revision,
|
|
3307
|
+
entry: entry ?? undefined,
|
|
3308
|
+
error: entry == null ? "Prompt not found" : undefined,
|
|
3309
|
+
});
|
|
3310
|
+
if (entry)
|
|
3311
|
+
this.broadcastPromptHistoryStatus();
|
|
3312
|
+
}
|
|
3313
|
+
catch (err) {
|
|
3314
|
+
this.send(ws, {
|
|
3315
|
+
type: "prompt_history_mutation_result",
|
|
3316
|
+
success: false,
|
|
3317
|
+
error: err instanceof Error ? err.message : String(err),
|
|
3318
|
+
});
|
|
3319
|
+
}
|
|
3320
|
+
break;
|
|
3321
|
+
}
|
|
3322
|
+
case "import_prompt_history_v1": {
|
|
3323
|
+
if (!this.promptHistoryStore) {
|
|
3324
|
+
this.send(ws, {
|
|
3325
|
+
type: "prompt_history_sync_result",
|
|
3326
|
+
success: false,
|
|
3327
|
+
error: "Prompt history store not available",
|
|
3328
|
+
});
|
|
3329
|
+
break;
|
|
3330
|
+
}
|
|
3331
|
+
try {
|
|
3332
|
+
const result = await this.promptHistoryStore.importEntries(msg.entries, msg.clientId, msg.clientName);
|
|
3333
|
+
this.send(ws, {
|
|
3334
|
+
type: "prompt_history_sync_result",
|
|
3335
|
+
success: true,
|
|
3336
|
+
bridgeInstanceId: this.promptHistoryStore.bridgeInstanceId,
|
|
3337
|
+
revision: this.promptHistoryStore.revision,
|
|
3338
|
+
syncedAt: new Date().toISOString(),
|
|
3339
|
+
fullSnapshot: true,
|
|
3340
|
+
entries: result.entries,
|
|
3341
|
+
});
|
|
3342
|
+
this.broadcastPromptHistoryStatus();
|
|
3343
|
+
}
|
|
3344
|
+
catch (err) {
|
|
3345
|
+
this.send(ws, {
|
|
3346
|
+
type: "prompt_history_sync_result",
|
|
3347
|
+
success: false,
|
|
3348
|
+
error: err instanceof Error ? err.message : String(err),
|
|
3349
|
+
});
|
|
3350
|
+
}
|
|
3351
|
+
break;
|
|
3352
|
+
}
|
|
3208
3353
|
case "rename_session": {
|
|
3209
3354
|
const name = msg.name || null;
|
|
3210
3355
|
await this.handleRenameSession(ws, msg.sessionId, name, msg);
|
|
@@ -3308,6 +3453,19 @@ export class BridgeWebSocketServer {
|
|
|
3308
3453
|
bridgeVersion: getPackageVersion(),
|
|
3309
3454
|
});
|
|
3310
3455
|
}
|
|
3456
|
+
sendPromptHistoryStatus(ws) {
|
|
3457
|
+
if (!this.promptHistoryStore)
|
|
3458
|
+
return;
|
|
3459
|
+
const entries = this.promptHistoryStore.list(true);
|
|
3460
|
+
const updatedAt = entries.reduce((latest, entry) => !latest || entry.updatedAt > latest ? entry.updatedAt : latest, undefined);
|
|
3461
|
+
this.send(ws, {
|
|
3462
|
+
type: "prompt_history_status",
|
|
3463
|
+
bridgeInstanceId: this.promptHistoryStore.bridgeInstanceId,
|
|
3464
|
+
revision: this.promptHistoryStore.revision,
|
|
3465
|
+
entryCount: entries.filter((entry) => !entry.deletedAt).length,
|
|
3466
|
+
updatedAt,
|
|
3467
|
+
});
|
|
3468
|
+
}
|
|
3311
3469
|
/** Broadcast session list to all connected clients. */
|
|
3312
3470
|
broadcastSessionList() {
|
|
3313
3471
|
this.pruneDebugEvents();
|
|
@@ -3323,6 +3481,19 @@ export class BridgeWebSocketServer {
|
|
|
3323
3481
|
bridgeVersion: getPackageVersion(),
|
|
3324
3482
|
});
|
|
3325
3483
|
}
|
|
3484
|
+
broadcastPromptHistoryStatus() {
|
|
3485
|
+
if (!this.promptHistoryStore)
|
|
3486
|
+
return;
|
|
3487
|
+
const entries = this.promptHistoryStore.list(true);
|
|
3488
|
+
const updatedAt = entries.reduce((latest, entry) => !latest || entry.updatedAt > latest ? entry.updatedAt : latest, undefined);
|
|
3489
|
+
this.broadcast({
|
|
3490
|
+
type: "prompt_history_status",
|
|
3491
|
+
bridgeInstanceId: this.promptHistoryStore.bridgeInstanceId,
|
|
3492
|
+
revision: this.promptHistoryStore.revision,
|
|
3493
|
+
entryCount: entries.filter((entry) => !entry.deletedAt).length,
|
|
3494
|
+
updatedAt,
|
|
3495
|
+
});
|
|
3496
|
+
}
|
|
3326
3497
|
broadcastSessionMessage(sessionId, msg) {
|
|
3327
3498
|
this.maybeSendPushNotification(sessionId, msg);
|
|
3328
3499
|
this.recordDebugEvent(sessionId, {
|
|
@@ -3681,11 +3852,10 @@ export class BridgeWebSocketServer {
|
|
|
3681
3852
|
}
|
|
3682
3853
|
}
|
|
3683
3854
|
shouldSendToClient(ws, msg) {
|
|
3684
|
-
|
|
3855
|
+
const type = typeof msg.type === "string" ? msg.type : "";
|
|
3856
|
+
if (!OPT_IN_SERVER_MESSAGES.has(type))
|
|
3685
3857
|
return true;
|
|
3686
|
-
return (this.clientSupportedServerMessages
|
|
3687
|
-
.get(ws)
|
|
3688
|
-
?.has("conversation_queue") ?? false);
|
|
3858
|
+
return (this.clientSupportedServerMessages.get(ws)?.has(type) ?? false);
|
|
3689
3859
|
}
|
|
3690
3860
|
hasInputConflictSince(sessionId, baseSeq) {
|
|
3691
3861
|
const delta = this.sessionManager.getHistorySince(sessionId, baseSeq);
|