@ccpocket/bridge 1.86.0 → 1.86.2

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.
@@ -211,6 +211,7 @@ export declare class CodexProcess extends EventEmitter<CodexProcessEvents> {
211
211
  * Sends thread/name/set which persists to ~/.codex/session_index.jsonl.
212
212
  */
213
213
  renameThread(name: string): Promise<void>;
214
+ private goalLookup;
214
215
  /** Read the persisted goal attached to this Codex thread. */
215
216
  getGoal(timeoutMs?: number): Promise<CodexGoal | null>;
216
217
  /** Create or update the persisted goal attached to this Codex thread. */
@@ -240,13 +240,21 @@ export class CodexProcess extends EventEmitter {
240
240
  name,
241
241
  });
242
242
  }
243
+ goalLookup;
243
244
  /** Read the persisted goal attached to this Codex thread. */
244
245
  async getGoal(timeoutMs = 3_000) {
245
246
  if (!this._threadId) {
246
247
  throw new Error("No thread ID available for goal lookup");
247
248
  }
248
- const response = (await this.request("thread/goal/get", { threadId: this._threadId }, timeoutMs));
249
- return response.goal == null ? null : parseCodexGoal(response.goal);
249
+ if (!this.goalLookup) {
250
+ this.goalLookup = this.request("thread/goal/get", { threadId: this._threadId }, timeoutMs).then((value) => {
251
+ const response = value;
252
+ return response.goal == null ? null : parseCodexGoal(response.goal);
253
+ }).finally(() => {
254
+ this.goalLookup = undefined;
255
+ });
256
+ }
257
+ return this.goalLookup;
250
258
  }
251
259
  /** Create or update the persisted goal attached to this Codex thread. */
252
260
  async setGoal(update) {
@@ -1126,7 +1134,7 @@ export class CodexProcess extends EventEmitter {
1126
1134
  }
1127
1135
  async bootstrap(projectPath, options) {
1128
1136
  try {
1129
- await this.initializeRpcConnection();
1137
+ const supportsPermissionProfiles = await this.initializeRpcConnection();
1130
1138
  const autoReviewDisabled = options?.autoReviewDisabledByPolicy === null
1131
1139
  ? (await this.readConfigRequirements()).autoReviewDisabled
1132
1140
  : options?.autoReviewDisabledByPolicy === true;
@@ -1178,7 +1186,19 @@ export class CodexProcess extends EventEmitter {
1178
1186
  threadParams.approvalsReviewer = requestedApprovalsReviewer;
1179
1187
  }
1180
1188
  if (requestedSandboxMode) {
1181
- threadParams.sandbox = requestedSandboxMode;
1189
+ // A legacy sandbox override does not persist the selected built-in
1190
+ // profile. Desktop can restore its configured sandbox on resume.
1191
+ // Keep legacy requests for older/unknown servers, which may silently
1192
+ // ignore the new field. Never send permissions together with sandbox.
1193
+ if (supportsPermissionProfiles &&
1194
+ effectiveCodexPermissionsMode === "fullAccess" &&
1195
+ !options?.profile &&
1196
+ requestedSandboxMode === "danger-full-access") {
1197
+ threadParams.permissions = ":danger-full-access";
1198
+ }
1199
+ else {
1200
+ threadParams.sandbox = requestedSandboxMode;
1201
+ }
1182
1202
  }
1183
1203
  const threadConfig = {};
1184
1204
  const requestedModel = sanitizeCodexModel(options?.model);
@@ -1193,7 +1213,8 @@ export class CodexProcess extends EventEmitter {
1193
1213
  // not the top-level thread/start payload.
1194
1214
  threadConfig.model_reasoning_effort = requestedReasoningEffort;
1195
1215
  }
1196
- if (options?.networkAccessEnabled !== undefined) {
1216
+ if (options?.networkAccessEnabled !== undefined &&
1217
+ threadParams.permissions === undefined) {
1197
1218
  threadParams.sandboxPolicy = {
1198
1219
  type: normalizeSandboxMode(options?.sandboxMode ?? "workspace-write"),
1199
1220
  networkAccess: options.networkAccessEnabled,
@@ -1345,7 +1366,7 @@ export class CodexProcess extends EventEmitter {
1345
1366
  return extractPermissionsFromConfigRead(response, projectLookupPaths, this.platform, profile);
1346
1367
  }
1347
1368
  async initializeRpcConnection(timeoutMs) {
1348
- await this.request("initialize", {
1369
+ const response = (await this.request("initialize", {
1349
1370
  clientInfo: {
1350
1371
  name: "ccpocket_bridge",
1351
1372
  version: "1.0.0",
@@ -1354,8 +1375,12 @@ export class CodexProcess extends EventEmitter {
1354
1375
  capabilities: {
1355
1376
  experimentalApi: true,
1356
1377
  },
1357
- }, timeoutMs);
1378
+ }, timeoutMs));
1358
1379
  this.notify("initialized", {});
1380
+ // 0.157.0 is the oldest version verified for built-in permission profiles.
1381
+ const version = response.userAgent?.match(/^\S+\/(\d+)\.(\d+)\.(\d+)(?=\s|$)/);
1382
+ return (version != null &&
1383
+ (Number(version[1]) > 0 || Number(version[2]) >= 157));
1359
1384
  }
1360
1385
  async readProfileConfig(cwd) {
1361
1386
  const response = (await this.request("config/read", {