@ccpocket/bridge 1.33.3 → 1.34.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/codex-process.d.ts +32 -6
- package/dist/codex-process.js +120 -43
- package/dist/codex-process.js.map +1 -1
- package/dist/parser.d.ts +17 -0
- package/dist/parser.js +18 -0
- package/dist/parser.js.map +1 -1
- package/dist/session.d.ts +2 -0
- package/dist/session.js +19 -11
- package/dist/session.js.map +1 -1
- package/dist/websocket.js +38 -9
- package/dist/websocket.js.map +1 -1
- package/package.json +1 -1
package/dist/codex-process.d.ts
CHANGED
|
@@ -27,6 +27,15 @@ export interface CodexSkillMetadata {
|
|
|
27
27
|
defaultPrompt?: string;
|
|
28
28
|
brandColor?: string;
|
|
29
29
|
}
|
|
30
|
+
/** App / connector metadata returned by the Codex `app/list` RPC. */
|
|
31
|
+
export interface CodexAppMetadata {
|
|
32
|
+
id: string;
|
|
33
|
+
name: string;
|
|
34
|
+
description: string;
|
|
35
|
+
installUrl?: string;
|
|
36
|
+
isAccessible: boolean;
|
|
37
|
+
isEnabled: boolean;
|
|
38
|
+
}
|
|
30
39
|
export interface CodexThreadSummary {
|
|
31
40
|
id: string;
|
|
32
41
|
preview: string;
|
|
@@ -64,10 +73,17 @@ export declare class CodexProcess extends EventEmitter<CodexProcessEvents> {
|
|
|
64
73
|
private lastTokenUsage;
|
|
65
74
|
/** Full skill metadata from the last `skills/list` response. */
|
|
66
75
|
private _skills;
|
|
76
|
+
/** Full app metadata from the last `app/list` response. */
|
|
77
|
+
private _apps;
|
|
67
78
|
/** Project path stored for re-fetching skills on `skills/changed`. */
|
|
68
79
|
private _projectPath;
|
|
80
|
+
/** Prevent redundant completion fetch storms from repeated change notifications. */
|
|
81
|
+
private _completionFetchInFlight;
|
|
82
|
+
private _completionFetchQueued;
|
|
83
|
+
private _lastCompletionEntitiesSignature;
|
|
69
84
|
/** Expose skill metadata so session/websocket can access it. */
|
|
70
85
|
get skills(): CodexSkillMetadata[];
|
|
86
|
+
get apps(): CodexAppMetadata[];
|
|
71
87
|
private rpcSeq;
|
|
72
88
|
private pendingRpc;
|
|
73
89
|
private stdoutBuffer;
|
|
@@ -135,6 +151,20 @@ export declare class CodexProcess extends EventEmitter<CodexProcessEvents> {
|
|
|
135
151
|
name: string;
|
|
136
152
|
path: string;
|
|
137
153
|
}): void;
|
|
154
|
+
sendInputStructured(text: string, options?: {
|
|
155
|
+
images?: Array<{
|
|
156
|
+
base64: string;
|
|
157
|
+
mimeType: string;
|
|
158
|
+
}>;
|
|
159
|
+
skills?: Array<{
|
|
160
|
+
name: string;
|
|
161
|
+
path: string;
|
|
162
|
+
}>;
|
|
163
|
+
mentions?: Array<{
|
|
164
|
+
name: string;
|
|
165
|
+
path: string;
|
|
166
|
+
}>;
|
|
167
|
+
}): void;
|
|
138
168
|
approve(toolUseId?: string, _updatedInput?: Record<string, unknown>): void;
|
|
139
169
|
approveAlways(toolUseId?: string): void;
|
|
140
170
|
reject(toolUseId?: string, _message?: string): void;
|
|
@@ -158,12 +188,8 @@ export declare class CodexProcess extends EventEmitter<CodexProcessEvents> {
|
|
|
158
188
|
private handlePlanRejected;
|
|
159
189
|
private bootstrap;
|
|
160
190
|
private initializeRpcConnection;
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
* as a `supported_commands` system message so the Flutter client can display
|
|
164
|
-
* skill entries alongside built-in slash commands.
|
|
165
|
-
*/
|
|
166
|
-
private fetchSkills;
|
|
191
|
+
private fetchCompletionEntities;
|
|
192
|
+
private _fetchCompletionEntitiesInternal;
|
|
167
193
|
private runInputLoop;
|
|
168
194
|
private handleStdoutChunk;
|
|
169
195
|
private handleRpcEnvelope;
|
package/dist/codex-process.js
CHANGED
|
@@ -45,12 +45,21 @@ export class CodexProcess extends EventEmitter {
|
|
|
45
45
|
lastTokenUsage = null;
|
|
46
46
|
/** Full skill metadata from the last `skills/list` response. */
|
|
47
47
|
_skills = [];
|
|
48
|
+
/** Full app metadata from the last `app/list` response. */
|
|
49
|
+
_apps = [];
|
|
48
50
|
/** Project path stored for re-fetching skills on `skills/changed`. */
|
|
49
51
|
_projectPath = null;
|
|
52
|
+
/** Prevent redundant completion fetch storms from repeated change notifications. */
|
|
53
|
+
_completionFetchInFlight = null;
|
|
54
|
+
_completionFetchQueued = false;
|
|
55
|
+
_lastCompletionEntitiesSignature = null;
|
|
50
56
|
/** Expose skill metadata so session/websocket can access it. */
|
|
51
57
|
get skills() {
|
|
52
58
|
return this._skills;
|
|
53
59
|
}
|
|
60
|
+
get apps() {
|
|
61
|
+
return this._apps;
|
|
62
|
+
}
|
|
54
63
|
rpcSeq = 1;
|
|
55
64
|
pendingRpc = new Map();
|
|
56
65
|
stdoutBuffer = "";
|
|
@@ -273,13 +282,21 @@ export class CodexProcess extends EventEmitter {
|
|
|
273
282
|
resolve({ text, images });
|
|
274
283
|
}
|
|
275
284
|
sendInputWithSkill(text, skill) {
|
|
285
|
+
this.sendInputStructured(text, { skills: [skill] });
|
|
286
|
+
}
|
|
287
|
+
sendInputStructured(text, options) {
|
|
276
288
|
if (!this.inputResolve) {
|
|
277
|
-
console.error("[codex-process] No pending input resolver for
|
|
289
|
+
console.error("[codex-process] No pending input resolver for sendInputStructured");
|
|
278
290
|
return;
|
|
279
291
|
}
|
|
280
292
|
const resolve = this.inputResolve;
|
|
281
293
|
this.inputResolve = null;
|
|
282
|
-
resolve({
|
|
294
|
+
resolve({
|
|
295
|
+
text,
|
|
296
|
+
images: options?.images,
|
|
297
|
+
skills: options?.skills,
|
|
298
|
+
mentions: options?.mentions,
|
|
299
|
+
});
|
|
283
300
|
}
|
|
284
301
|
approve(toolUseId, _updatedInput) {
|
|
285
302
|
// Check if this is a plan completion approval
|
|
@@ -369,7 +386,7 @@ export class CodexProcess extends EventEmitter {
|
|
|
369
386
|
return undefined;
|
|
370
387
|
return {
|
|
371
388
|
toolUseId: pendingAsk.toolUseId,
|
|
372
|
-
toolName:
|
|
389
|
+
toolName: pendingAsk.toolName,
|
|
373
390
|
input: { ...pendingAsk.input },
|
|
374
391
|
};
|
|
375
392
|
}
|
|
@@ -526,9 +543,13 @@ export class CodexProcess extends EventEmitter {
|
|
|
526
543
|
: {}),
|
|
527
544
|
});
|
|
528
545
|
this.setStatus("idle");
|
|
529
|
-
// Fetch skills in background (non-blocking)
|
|
546
|
+
// Fetch skills/apps in background (non-blocking)
|
|
530
547
|
this._projectPath = projectPath;
|
|
531
|
-
|
|
548
|
+
setTimeout(() => {
|
|
549
|
+
if (!this.stopped) {
|
|
550
|
+
void this.fetchCompletionEntities(projectPath);
|
|
551
|
+
}
|
|
552
|
+
}, 25);
|
|
532
553
|
await this.runInputLoop(options);
|
|
533
554
|
}
|
|
534
555
|
catch (err) {
|
|
@@ -560,58 +581,101 @@ export class CodexProcess extends EventEmitter {
|
|
|
560
581
|
});
|
|
561
582
|
this.notify("initialized", {});
|
|
562
583
|
}
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
584
|
+
async fetchCompletionEntities(projectPath) {
|
|
585
|
+
if (this._completionFetchInFlight) {
|
|
586
|
+
this._completionFetchQueued = true;
|
|
587
|
+
return this._completionFetchInFlight;
|
|
588
|
+
}
|
|
589
|
+
this._completionFetchInFlight = this._fetchCompletionEntitiesInternal(projectPath);
|
|
590
|
+
try {
|
|
591
|
+
await this._completionFetchInFlight;
|
|
592
|
+
}
|
|
593
|
+
finally {
|
|
594
|
+
this._completionFetchInFlight = null;
|
|
595
|
+
if (this._completionFetchQueued && !this.stopped && this._projectPath) {
|
|
596
|
+
this._completionFetchQueued = false;
|
|
597
|
+
void this.fetchCompletionEntities(this._projectPath);
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
async _fetchCompletionEntitiesInternal(projectPath) {
|
|
569
602
|
const TIMEOUT_MS = 10_000;
|
|
570
603
|
try {
|
|
571
|
-
const
|
|
604
|
+
const skillsResult = (await Promise.race([
|
|
572
605
|
this.request("skills/list", { cwds: [projectPath] }),
|
|
573
606
|
new Promise((resolve) => setTimeout(() => resolve(null), TIMEOUT_MS)),
|
|
574
607
|
]));
|
|
575
|
-
|
|
576
|
-
|
|
608
|
+
const appsResult = (await Promise.race([
|
|
609
|
+
this.request("app/list", {
|
|
610
|
+
cursor: null,
|
|
611
|
+
limit: 100,
|
|
612
|
+
threadId: this._threadId ?? undefined,
|
|
613
|
+
forceRefetch: false,
|
|
614
|
+
}),
|
|
615
|
+
new Promise((resolve) => setTimeout(() => resolve(null), TIMEOUT_MS)),
|
|
616
|
+
]));
|
|
577
617
|
const skills = [];
|
|
578
|
-
const slashCommands = [];
|
|
579
618
|
const skillMetadata = [];
|
|
580
|
-
|
|
581
|
-
for (const
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
619
|
+
if (skillsResult?.data) {
|
|
620
|
+
for (const entry of skillsResult.data) {
|
|
621
|
+
for (const skill of entry.skills) {
|
|
622
|
+
if (skill.enabled) {
|
|
623
|
+
skills.push(skill.name);
|
|
624
|
+
skillMetadata.push({
|
|
625
|
+
name: skill.name,
|
|
626
|
+
path: skill.path,
|
|
627
|
+
description: skill.description,
|
|
628
|
+
shortDescription: skill.shortDescription ??
|
|
629
|
+
skill.interface?.shortDescription ??
|
|
630
|
+
undefined,
|
|
631
|
+
enabled: skill.enabled,
|
|
632
|
+
scope: skill.scope,
|
|
633
|
+
displayName: skill.interface?.displayName ?? undefined,
|
|
634
|
+
defaultPrompt: skill.interface?.defaultPrompt ?? undefined,
|
|
635
|
+
brandColor: skill.interface?.brandColor ?? undefined,
|
|
636
|
+
});
|
|
637
|
+
}
|
|
598
638
|
}
|
|
599
639
|
}
|
|
600
640
|
}
|
|
601
641
|
this._skills = skillMetadata;
|
|
602
|
-
|
|
603
|
-
|
|
642
|
+
const appMetadata = (appsResult?.data ?? [])
|
|
643
|
+
.filter((app) => (app.isAccessible ?? true) && (app.isEnabled ?? true))
|
|
644
|
+
.map((app) => ({
|
|
645
|
+
id: app.id,
|
|
646
|
+
name: app.name,
|
|
647
|
+
description: app.description,
|
|
648
|
+
installUrl: app.installUrl ?? undefined,
|
|
649
|
+
isAccessible: app.isAccessible ?? true,
|
|
650
|
+
isEnabled: app.isEnabled ?? true,
|
|
651
|
+
}));
|
|
652
|
+
this._apps = appMetadata;
|
|
653
|
+
if (this.stopped)
|
|
654
|
+
return;
|
|
655
|
+
const signature = JSON.stringify({
|
|
656
|
+
skills,
|
|
657
|
+
skillMetadata,
|
|
658
|
+
apps: appMetadata.map((app) => app.id),
|
|
659
|
+
appMetadata,
|
|
660
|
+
});
|
|
661
|
+
if (signature === this._lastCompletionEntitiesSignature) {
|
|
662
|
+
return;
|
|
663
|
+
}
|
|
664
|
+
this._lastCompletionEntitiesSignature = signature;
|
|
665
|
+
if (skills.length > 0 || appMetadata.length > 0) {
|
|
666
|
+
console.log(`[codex-process] completion entities loaded: ${skills.length} skills, ${appMetadata.length} apps`);
|
|
604
667
|
this.emitMessage({
|
|
605
668
|
type: "system",
|
|
606
669
|
subtype: "supported_commands",
|
|
607
|
-
slashCommands,
|
|
608
670
|
skills,
|
|
609
671
|
skillMetadata,
|
|
672
|
+
apps: appMetadata.map((app) => app.id),
|
|
673
|
+
appMetadata,
|
|
610
674
|
});
|
|
611
675
|
}
|
|
612
676
|
}
|
|
613
677
|
catch (err) {
|
|
614
|
-
console.log(`[codex-process]
|
|
678
|
+
console.log(`[codex-process] completion entity fetch failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`);
|
|
615
679
|
}
|
|
616
680
|
}
|
|
617
681
|
async runInputLoop(options) {
|
|
@@ -997,9 +1061,15 @@ export class CodexProcess extends EventEmitter {
|
|
|
997
1061
|
break;
|
|
998
1062
|
}
|
|
999
1063
|
case "skills/changed": {
|
|
1000
|
-
// Re-fetch skills when Codex notifies us of changes
|
|
1064
|
+
// Re-fetch skills/apps when Codex notifies us of changes
|
|
1001
1065
|
if (this._projectPath) {
|
|
1002
|
-
void this.
|
|
1066
|
+
void this.fetchCompletionEntities(this._projectPath);
|
|
1067
|
+
}
|
|
1068
|
+
break;
|
|
1069
|
+
}
|
|
1070
|
+
case "app/list/updated": {
|
|
1071
|
+
if (this._projectPath) {
|
|
1072
|
+
void this.fetchCompletionEntities(this._projectPath);
|
|
1003
1073
|
}
|
|
1004
1074
|
break;
|
|
1005
1075
|
}
|
|
@@ -1367,12 +1437,19 @@ export class CodexProcess extends EventEmitter {
|
|
|
1367
1437
|
async toRpcInput(pendingInput) {
|
|
1368
1438
|
const input = [];
|
|
1369
1439
|
const tempPaths = [];
|
|
1370
|
-
// Prepend
|
|
1371
|
-
|
|
1440
|
+
// Prepend structured input items before the free-form text body.
|
|
1441
|
+
for (const skill of pendingInput.skills ?? []) {
|
|
1372
1442
|
input.push({
|
|
1373
1443
|
type: "skill",
|
|
1374
|
-
name:
|
|
1375
|
-
path:
|
|
1444
|
+
name: skill.name,
|
|
1445
|
+
path: skill.path,
|
|
1446
|
+
});
|
|
1447
|
+
}
|
|
1448
|
+
for (const mention of pendingInput.mentions ?? []) {
|
|
1449
|
+
input.push({
|
|
1450
|
+
type: "mention",
|
|
1451
|
+
name: mention.name,
|
|
1452
|
+
path: mention.path,
|
|
1376
1453
|
});
|
|
1377
1454
|
}
|
|
1378
1455
|
input.push({ type: "text", text: pendingInput.text });
|