codex-mobile-re 0.1.88 → 0.1.91

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.html CHANGED
@@ -12,8 +12,8 @@
12
12
  <link rel="icon" type="image/png" sizes="192x192" href="/icons/pwa-192x192.png" />
13
13
  <link rel="apple-touch-icon" sizes="180x180" href="/icons/apple-touch-icon.png" />
14
14
  <title>Codex Web</title>
15
- <script type="module" crossorigin src="/assets/index-BrpaGwQT.js"></script>
16
- <link rel="stylesheet" crossorigin href="/assets/index-8nj0j9KO.css">
15
+ <script type="module" crossorigin src="/assets/index-D7o45WlH.js"></script>
16
+ <link rel="stylesheet" crossorigin href="/assets/index-Dbxv7TvZ.css">
17
17
  </head>
18
18
  <body class="bg-slate-950">
19
19
  <div id="app"></div>
package/dist-cli/index.js CHANGED
@@ -4862,6 +4862,23 @@ var ExternalSessionTracker = class {
4862
4862
  }
4863
4863
  return active;
4864
4864
  }
4865
+ /**
4866
+ * Thread ids whose session_meta marks them as subagent sessions
4867
+ * (`thread_source` starts with "subagent"). Subagent sessions are materialized
4868
+ * by the app-server with an interactive `source` (e.g. "cli"), so they show up
4869
+ * in `thread/list`; callers that want a user-facing thread list can exclude them.
4870
+ */
4871
+ getSubagentThreadIds() {
4872
+ if (!this.enabled) return [];
4873
+ const ids = [];
4874
+ for (const session of this.sessionByThreadId.values()) {
4875
+ const source = (session.threadSource ?? "").toLowerCase();
4876
+ if (source.startsWith("subagent")) {
4877
+ ids.push(session.sessionId);
4878
+ }
4879
+ }
4880
+ return ids;
4881
+ }
4865
4882
  /** Run one discovery + parse + transition pass. Exposed for tests. */
4866
4883
  async tick() {
4867
4884
  if (!this.enabled || this.ticking || this.disposed) return;
@@ -5015,10 +5032,15 @@ var ExternalSessionTracker = class {
5015
5032
  const payload = asRecord6(record.payload);
5016
5033
  if (!payload) continue;
5017
5034
  const originator = readNonEmptyString(payload.originator);
5018
- if (!originator) continue;
5019
- session.originator = originator;
5020
- session.threadSource = readNonEmptyString(payload.thread_source) || null;
5021
- session.external = this.externalOrigins.has(originator);
5035
+ const threadSource = readNonEmptyString(payload.thread_source);
5036
+ if (!originator && !threadSource) continue;
5037
+ if (originator) {
5038
+ session.originator = originator;
5039
+ session.external = this.externalOrigins.has(originator);
5040
+ }
5041
+ if (threadSource) {
5042
+ session.threadSource = threadSource;
5043
+ }
5022
5044
  const sessionId = readNonEmptyString(payload.session_id) || readNonEmptyString(payload.id);
5023
5045
  if (sessionId) {
5024
5046
  session.sessionId = sessionId;
@@ -7680,6 +7702,16 @@ function mergeImportedThreadsIntoThreadListResult(result) {
7680
7702
  })
7681
7703
  };
7682
7704
  }
7705
+ function filterThreadListByIds(result, threadIdsToExclude) {
7706
+ const record = asRecord7(result);
7707
+ const data = Array.isArray(record?.data) ? record.data : null;
7708
+ if (!record || !data || threadIdsToExclude.size === 0) return result;
7709
+ const filtered = data.filter((row) => {
7710
+ const id = readNonEmptyString2(asRecord7(row)?.id);
7711
+ return !(id.length > 0 && threadIdsToExclude.has(id));
7712
+ });
7713
+ return filtered.length === data.length ? result : { ...record, data: filtered };
7714
+ }
7683
7715
  async function collectProjectChatZipEntries(projectRoot) {
7684
7716
  const canonicalProjectRoot = await realpath(projectRoot);
7685
7717
  const codexHome = getCodexHomeDir5();
@@ -9244,7 +9276,11 @@ function applyV4aDiff(fileContent, diffText) {
9244
9276
  }
9245
9277
  return result.join("\n");
9246
9278
  }
9247
- async function applyTurnFileChanges(cwd, turnInfos, allowedPatchIds) {
9279
+ function pathSetMatchesChange(allowedFilePaths, filePath, movedToPath) {
9280
+ const candidates = movedToPath ? [filePath, movedToPath] : [filePath];
9281
+ return candidates.some((candidate) => allowedFilePaths.has(candidate));
9282
+ }
9283
+ async function applyTurnFileChanges(cwd, turnInfos, allowedPatchIds, allowedFilePaths) {
9248
9284
  if (turnInfos.size === 0) return { applied: 0, errors: [], appliedPatchIds: [] };
9249
9285
  let applied = 0;
9250
9286
  const errors = [];
@@ -9257,6 +9293,7 @@ async function applyTurnFileChanges(cwd, turnInfos, allowedPatchIds) {
9257
9293
  for (const change of changes) {
9258
9294
  const filePath = isAbsolute2(change.path) ? change.path : join8(cwd, change.path);
9259
9295
  const movedToPath = change.movedToPath ? isAbsolute2(change.movedToPath) ? change.movedToPath : join8(cwd, change.movedToPath) : null;
9296
+ if (allowedFilePaths && !pathSetMatchesChange(allowedFilePaths, filePath, movedToPath)) continue;
9260
9297
  try {
9261
9298
  if (change.operation === "add") {
9262
9299
  await mkdir4(dirname3(filePath), { recursive: true });
@@ -9311,7 +9348,7 @@ async function applyTurnFileChanges(cwd, turnInfos, allowedPatchIds) {
9311
9348
  }
9312
9349
  return { applied, errors, appliedPatchIds };
9313
9350
  }
9314
- async function revertTurnFileChanges(cwd, turnInfos, allowedPatchIds) {
9351
+ async function revertTurnFileChanges(cwd, turnInfos, allowedPatchIds, allowedFilePaths) {
9315
9352
  if (turnInfos.size === 0) return { reverted: 0, errors: [], revertedPatchIds: [] };
9316
9353
  let reverted = 0;
9317
9354
  const errors = [];
@@ -9345,6 +9382,7 @@ async function revertTurnFileChanges(cwd, turnInfos, allowedPatchIds) {
9345
9382
  const change = changes[ci];
9346
9383
  const filePath = isAbsolute2(change.path) ? change.path : join8(cwd, change.path);
9347
9384
  const movedToPath = change.movedToPath ? isAbsolute2(change.movedToPath) ? change.movedToPath : join8(cwd, change.movedToPath) : null;
9385
+ if (allowedFilePaths && !pathSetMatchesChange(allowedFilePaths, filePath, movedToPath)) continue;
9348
9386
  try {
9349
9387
  if (change.operation === "add") {
9350
9388
  const fileStat = await stat5(filePath).catch(() => null);
@@ -9462,29 +9500,42 @@ function mergeSessionCommandsIntoTurns(turns, sessionLogRaw) {
9462
9500
  const slots = orderByTurnId.get(turnId);
9463
9501
  if (!slots || slots.length === 0) return turn;
9464
9502
  const existingItems = Array.isArray(turnRecord.items) ? turnRecord.items : [];
9465
- if (existingItems.some((it) => typeof it.id === "string" && it.id.startsWith("session-"))) return turn;
9466
9503
  const agentMessages = existingItems.filter((it) => it.type === "agentMessage");
9467
9504
  const userMessages = existingItems.filter((it) => it.type === "userMessage");
9468
- let agentIdx = 0;
9505
+ const agentSlotCount = slots.filter((slot) => slot.type === "agentMessage").length;
9469
9506
  const interleaved = [...userMessages];
9470
9507
  const recoveredIds = /* @__PURE__ */ new Set();
9471
- for (const slot of slots) {
9472
- if (slot.type === "agentMessage") {
9473
- if (agentIdx < agentMessages.length) {
9474
- interleaved.push(agentMessages[agentIdx]);
9475
- agentIdx++;
9508
+ if (agentMessages.length < agentSlotCount) {
9509
+ for (const slot of slots) {
9510
+ if (slot.type === "commandExecution" && slot.command) {
9511
+ interleaved.push(slot.command);
9512
+ recoveredIds.add(slot.command.id);
9513
+ } else if (slot.type === "fileChange" && slot.fileChange) {
9514
+ interleaved.push(slot.fileChange);
9515
+ recoveredIds.add(slot.fileChange.id);
9476
9516
  }
9477
- } else if (slot.type === "commandExecution" && slot.command) {
9478
- interleaved.push(slot.command);
9479
- recoveredIds.add(slot.command.id);
9480
- } else if (slot.type === "fileChange" && slot.fileChange) {
9481
- interleaved.push(slot.fileChange);
9482
- recoveredIds.add(slot.fileChange.id);
9483
9517
  }
9484
- }
9485
- while (agentIdx < agentMessages.length) {
9486
- interleaved.push(agentMessages[agentIdx]);
9487
- agentIdx++;
9518
+ interleaved.push(...agentMessages);
9519
+ } else {
9520
+ let agentIdx = 0;
9521
+ for (const slot of slots) {
9522
+ if (slot.type === "agentMessage") {
9523
+ if (agentIdx < agentMessages.length) {
9524
+ interleaved.push(agentMessages[agentIdx]);
9525
+ agentIdx++;
9526
+ }
9527
+ } else if (slot.type === "commandExecution" && slot.command) {
9528
+ interleaved.push(slot.command);
9529
+ recoveredIds.add(slot.command.id);
9530
+ } else if (slot.type === "fileChange" && slot.fileChange) {
9531
+ interleaved.push(slot.fileChange);
9532
+ recoveredIds.add(slot.fileChange.id);
9533
+ }
9534
+ }
9535
+ while (agentIdx < agentMessages.length) {
9536
+ interleaved.push(agentMessages[agentIdx]);
9537
+ agentIdx++;
9538
+ }
9488
9539
  }
9489
9540
  const hasRecoveredWorkItems = recoveredIds.size > 0;
9490
9541
  for (const item of existingItems) {
@@ -12491,6 +12542,9 @@ function createCodexBridgeMiddleware() {
12491
12542
  });
12492
12543
  return changed ? { ...record, data } : result;
12493
12544
  }
12545
+ function filterSubagentThreadsFromThreadListResult(result) {
12546
+ return filterThreadListByIds(result, new Set(externalSessionTracker.getSubagentThreadIds()));
12547
+ }
12494
12548
  function overlayExternalSessionOnThreadResult(result) {
12495
12549
  const record = asRecord7(result);
12496
12550
  const thread = asRecord7(record?.thread);
@@ -12968,7 +13022,8 @@ function createCodexBridgeMiddleware() {
12968
13022
  const trimmedResult = trimThreadTurnsInRpcResult(body.method, rpcResult);
12969
13023
  const errorMergedResult = THREAD_METHODS_WITH_TURNS.has(body.method) ? mergeStreamTurnErrorsIntoThreadResult(appServer, trimmedResult) : trimmedResult;
12970
13024
  const listMergedResult = body.method === "thread/list" ? mergeImportedThreadsIntoThreadListResult(errorMergedResult) : errorMergedResult;
12971
- const sanitizedResult = await sanitizeThreadTurnsInlinePayloads(body.method, listMergedResult);
13025
+ const subagentFilteredResult = body.method === "thread/list" ? filterSubagentThreadsFromThreadListResult(listMergedResult) : listMergedResult;
13026
+ const sanitizedResult = await sanitizeThreadTurnsInlinePayloads(body.method, subagentFilteredResult);
12972
13027
  const skillMergedResult = THREAD_METHODS_WITH_TURNS.has(body.method) ? await mergeSessionSkillInputsIntoThreadResult(sanitizedResult) : sanitizedResult;
12973
13028
  const result = THREAD_METHODS_WITH_TURNS.has(body.method) ? await mergeSessionCommandsIntoThreadResult(skillMergedResult) : skillMergedResult;
12974
13029
  if (THREAD_METHODS_WITH_THREAD_SNAPSHOT.has(body.method)) {
@@ -13182,6 +13237,7 @@ function createCodexBridgeMiddleware() {
13182
13237
  const action = readNonEmptyString2(body?.action) === "redo" ? "redo" : "undo";
13183
13238
  const scope = readNonEmptyString2(body?.scope) === "single_turn" ? "single_turn" : "turn_and_later";
13184
13239
  const patchIds = Array.isArray(body?.patchIds) ? new Set(body.patchIds.filter((value) => typeof value === "string" && value.length > 0)) : void 0;
13240
+ const filePaths = Array.isArray(body?.filePaths) ? new Set(body.filePaths.filter((value) => typeof value === "string" && value.length > 0).map((value) => isAbsolute2(value) ? value : join8(cwd, value))) : void 0;
13185
13241
  if (!threadId || !turnId || !cwd) {
13186
13242
  setJson4(res, 400, { error: "Missing threadId, turnId, or cwd" });
13187
13243
  return;
@@ -13225,11 +13281,11 @@ function createCodexBridgeMiddleware() {
13225
13281
  return;
13226
13282
  }
13227
13283
  if (action === "redo") {
13228
- const result2 = await applyTurnFileChanges(cwd, turnInfos, patchIds);
13284
+ const result2 = await applyTurnFileChanges(cwd, turnInfos, patchIds, filePaths);
13229
13285
  setJson4(res, 200, { ...result2, changed: result2.applied, message: `Reapplied ${result2.applied} file change(s)` });
13230
13286
  return;
13231
13287
  }
13232
- const result = await revertTurnFileChanges(cwd, turnInfos, patchIds);
13288
+ const result = await revertTurnFileChanges(cwd, turnInfos, patchIds, filePaths);
13233
13289
  setJson4(res, 200, { ...result, changed: result.reverted, message: `Reverted ${result.reverted} file change(s)` });
13234
13290
  } catch (error) {
13235
13291
  setJson4(res, 500, { error: getErrorMessage6(error, "Failed to revert file changes") });