codex-overleaf-link 2.4.1 → 2.5.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.
Files changed (397) hide show
  1. package/README.md +275 -305
  2. package/README.zh-CN.md +290 -320
  3. package/extension/bootstrap/background.js +99 -19
  4. package/extension/bootstrap/manifest.template.json +9 -4
  5. package/extension/bootstrap/popup.html +11 -16
  6. package/extension/bootstrap/popupFallback.js +55 -0
  7. package/extension/bootstrap/update.js +25 -2
  8. package/extension/bootstrap/updateStatus.js +1 -0
  9. package/extension/runtime-manifest.json +3 -1
  10. package/extension/src/background.js +234 -56
  11. package/extension/src/backgroundBootstrapMigration.js +181 -0
  12. package/extension/src/backgroundSharedSessions.js +440 -0
  13. package/extension/src/backgroundUpdateCoordinator.js +541 -381
  14. package/extension/src/backgroundUpdateSafety.js +173 -0
  15. package/extension/src/content/activeTurnControl.js +16 -2
  16. package/extension/src/content/applyResultFormatters.js +46 -73
  17. package/extension/src/content/assetTransferBroker.js +244 -12
  18. package/extension/src/content/changeHistoryView.js +175 -0
  19. package/extension/src/content/composerAttachments.js +117 -67
  20. package/extension/src/content/composerPanel.js +41 -8
  21. package/extension/src/content/contentRuntime.js +1084 -1099
  22. package/extension/src/content/diagnosticsController.js +122 -97
  23. package/extension/src/content/diagnosticsExport.js +236 -0
  24. package/extension/src/content/diagnosticsPanel.js +78 -19
  25. package/extension/src/content/diffReviewPanel.js +8 -5
  26. package/extension/src/content/directoryCleanupRecovery.js +54 -0
  27. package/extension/src/content/generated/content.bundle.js +14680 -3606
  28. package/extension/src/content/generated/content.bundle.meta.json +30 -3
  29. package/extension/src/content/globalPreferencesController.js +1 -1
  30. package/extension/src/content/legacyGlobalRegistry.js +25 -1
  31. package/extension/src/content/localSkillsPanel.js +141 -16
  32. package/extension/src/content/markdownDomRenderer.js +9 -4
  33. package/extension/src/content/markdownText.js +5 -6
  34. package/extension/src/content/modelPicker.js +8 -5
  35. package/extension/src/content/nativeCompatibilityController.js +45 -20
  36. package/extension/src/content/otWarmMirror.js +4 -5
  37. package/extension/src/content/otWarmMirrorController.js +17 -20
  38. package/extension/src/content/pageBridgeClient.js +33 -5
  39. package/extension/src/content/panelMaintenance.js +87 -132
  40. package/extension/src/content/panelRenderer.js +10 -0
  41. package/extension/src/content/pendingInputView.js +109 -76
  42. package/extension/src/content/projectProviderSelection.js +13 -4
  43. package/extension/src/content/projectSessionCleanup.js +109 -62
  44. package/extension/src/content/projectSettingsCoordinator.js +39 -2
  45. package/extension/src/content/providerSettingsCoordinator.js +63 -14
  46. package/extension/src/content/providerSettingsDialog.js +724 -113
  47. package/extension/src/content/recentProjects.js +21 -6
  48. package/extension/src/content/runActivitySummary.js +665 -0
  49. package/extension/src/content/runCompletionMeta.js +344 -0
  50. package/extension/src/content/runController.js +40 -15
  51. package/extension/src/content/runFailureNotice.js +34 -12
  52. package/extension/src/content/runGuidanceController.js +76 -30
  53. package/extension/src/content/runGuidanceView.js +59 -10
  54. package/extension/src/content/runPresence.js +306 -0
  55. package/extension/src/content/runQueueScheduler.js +150 -43
  56. package/extension/src/content/runRecoveryActions.js +146 -0
  57. package/extension/src/content/runResultActions.js +11 -8
  58. package/extension/src/content/runReviewController.js +574 -0
  59. package/extension/src/content/runScrollLayout.js +21 -2
  60. package/extension/src/content/runTimelineView.js +315 -290
  61. package/extension/src/content/scopedPersistencePanelState.js +51 -6
  62. package/extension/src/content/selectionContextView.js +300 -0
  63. package/extension/src/content/sensitivePreflight.js +140 -0
  64. package/extension/src/content/sessionForkController.js +80 -17
  65. package/extension/src/content/sessionManager.js +1 -1
  66. package/extension/src/content/sessionPersistence.js +6 -1
  67. package/extension/src/content/settingsPanel.js +84 -55
  68. package/extension/src/content/settingsWorkbench.js +379 -0
  69. package/extension/src/content/sharedSessionViewSync.js +109 -0
  70. package/extension/src/content/subagentActivityView.js +195 -0
  71. package/extension/src/content/trackedChangeCaptureController.js +7 -3
  72. package/extension/src/content/updateIdle.js +4 -1
  73. package/extension/src/content/updateNotice.js +179 -56
  74. package/extension/src/content/updateSafetyReceiver.js +58 -0
  75. package/extension/src/content/writebackController.js +308 -2
  76. package/extension/src/content/writebackOrchestrator.js +213 -199
  77. package/extension/src/content/writebackPlan.js +231 -0
  78. package/extension/src/content/writebackRecovery.js +122 -0
  79. package/extension/src/content/writingStyleSettings.js +600 -0
  80. package/extension/src/content/writtenChangesView.js +152 -0
  81. package/extension/src/page/binaryAssetUploader.js +223 -23
  82. package/extension/src/page/fileMover.js +256 -0
  83. package/extension/src/page/overleafProjectSnapshot.js +1 -0
  84. package/extension/src/page/ownedDirectoryCleanup.js +94 -0
  85. package/extension/src/page/referenceProjects.js +149 -0
  86. package/extension/src/page/reviewContext.js +113 -0
  87. package/extension/src/page/saveState.js +20 -6
  88. package/extension/src/page/snapshotRouter.js +124 -48
  89. package/extension/src/page/textCoordinates.js +102 -0
  90. package/extension/src/page/textFileCreator.js +442 -71
  91. package/extension/src/page/trackedChangeCapture.js +53 -57
  92. package/extension/src/page/trackedChangeOwnership.js +216 -0
  93. package/extension/src/page/trackedChangeReplay.js +184 -0
  94. package/extension/src/page/trackedChangesLifecycle.js +343 -339
  95. package/extension/src/page/treeOperations.js +33 -12
  96. package/extension/src/page/updateSafetyProbe.js +41 -0
  97. package/extension/src/page/writebackReceiptJournal.js +114 -0
  98. package/extension/src/page/writebackRouter.js +242 -201
  99. package/extension/src/pageBridge.js +73 -102
  100. package/extension/src/popup.js +261 -65
  101. package/extension/src/shared/agentTranscript.js +41 -4
  102. package/extension/src/shared/auditRecords.js +73 -0
  103. package/extension/src/shared/changeHistoryModel.js +94 -0
  104. package/extension/src/shared/compatibility.js +22 -6
  105. package/extension/src/shared/compileAdapter.js +101 -37
  106. package/extension/src/shared/composerAttachmentDraft.js +151 -0
  107. package/extension/src/shared/directoryCleanupProof.js +43 -0
  108. package/extension/src/shared/failureReasons.js +329 -3
  109. package/extension/src/shared/globalPreferences.js +31 -14
  110. package/extension/src/shared/governanceRules.js +4 -37
  111. package/extension/src/shared/i18n.js +389 -25
  112. package/extension/src/shared/managedUpdateProjection.js +8 -5
  113. package/extension/src/shared/nativeRequestIdentity.js +1 -0
  114. package/extension/src/shared/pageRpcContract.js +9 -2
  115. package/extension/src/shared/projectFiles.js +21 -44
  116. package/extension/src/shared/providerProfiles.js +114 -3
  117. package/extension/src/shared/runActivityModel.js +361 -0
  118. package/extension/src/shared/runExecutionSnapshot.js +8 -2
  119. package/extension/src/shared/runExecutionSnapshotCodec.js +16 -4
  120. package/extension/src/shared/runInputQueue.js +48 -5
  121. package/extension/src/shared/scopedPersistenceBrowserAdapter.js +6 -3
  122. package/extension/src/shared/selectionContext.js +37 -0
  123. package/extension/src/shared/sessionState.js +166 -30
  124. package/extension/src/shared/settlementFacts.js +10 -2
  125. package/extension/src/shared/sharedSessionBridge.js +311 -0
  126. package/extension/src/shared/sharedSessionTransfer.js +140 -0
  127. package/extension/src/shared/staleGuard.js +118 -13
  128. package/extension/src/shared/storageDb.js +77 -78
  129. package/extension/src/shared/storageMigration.js +74 -111
  130. package/extension/src/shared/storageRunActions.js +211 -22
  131. package/extension/src/shared/storageValuePruning.js +40 -0
  132. package/extension/src/shared/subagentActivityModel.js +174 -0
  133. package/extension/src/shared/undoOperations.js +216 -6
  134. package/extension/src/shared/updateConsent.js +42 -11
  135. package/extension/src/shared/updateRuntimeIdentity.js +1 -1
  136. package/extension/src/shared/writebackIntent.js +78 -0
  137. package/extension/src/shared/writebackOperationEvidence.js +4 -15
  138. package/extension/src/shared/writebackSettlement.js +67 -48
  139. package/extension/src/shared/writingStyle.js +33 -0
  140. package/extension/styles/panel.css +1987 -385
  141. package/extension/styles/popup.css +110 -0
  142. package/native-host/src/anthropicBridgeRequest.js +6 -3
  143. package/native-host/src/anthropicBridgeResponse.js +6 -2
  144. package/native-host/src/anthropicMessagesBridge.js +24 -16
  145. package/native-host/src/bootstrapMigration.js +296 -0
  146. package/native-host/src/bootstrapMigrationContract.js +101 -0
  147. package/native-host/src/bootstrapUpdate.js +233 -0
  148. package/native-host/src/bootstrapUpdateWatchdog.js +44 -0
  149. package/native-host/src/chatBridgeResponse.js +10 -0
  150. package/native-host/src/chatCompletionsBridge.js +21 -15
  151. package/native-host/src/codexConfigPaths.js +106 -0
  152. package/native-host/src/codexHome.js +66 -73
  153. package/native-host/src/codexHomeScope.js +124 -0
  154. package/native-host/src/codexInheritedAuth.js +90 -0
  155. package/native-host/src/codexLocalSkills.js +301 -0
  156. package/native-host/src/codexModelRecovery.js +107 -0
  157. package/native-host/src/codexPromptAssembly.js +33 -12
  158. package/native-host/src/codexProviderLaunch.js +3 -3
  159. package/native-host/src/codexProviderTest.js +24 -26
  160. package/native-host/src/codexRuntimeIdentity.js +1 -0
  161. package/native-host/src/codexSessionRunner.js +211 -318
  162. package/native-host/src/codexSessionTiming.js +21 -8
  163. package/native-host/src/codexSkillIsolation.js +170 -0
  164. package/native-host/src/codexThreadFork.js +19 -3
  165. package/native-host/src/index.js +19 -7
  166. package/native-host/src/managedInstall.js +115 -39
  167. package/native-host/src/managedInstallRecovery.js +140 -0
  168. package/native-host/src/managedRuntimeEvidence.js +57 -0
  169. package/native-host/src/mirrorWorkspace.js +92 -22
  170. package/native-host/src/nativeDoctor.js +15 -0
  171. package/native-host/src/nativeEnvironment.js +70 -0
  172. package/native-host/src/nativeHelperLifecycle.js +21 -0
  173. package/native-host/src/nativeHostRegistration.js +33 -0
  174. package/native-host/src/nativeQuotas.js +15 -8
  175. package/native-host/src/nativeRunLifecycle.js +71 -0
  176. package/native-host/src/overleafWorkspaceRules.js +16 -0
  177. package/native-host/src/processStopBarrier.js +115 -0
  178. package/native-host/src/projectPathPlatform.js +30 -0
  179. package/native-host/src/providerHttp.js +80 -0
  180. package/native-host/src/providerModelCatalog.js +4 -3
  181. package/native-host/src/providerProfile.js +17 -3
  182. package/native-host/src/providerReasoning.js +10 -11
  183. package/native-host/src/providerRuntime.js +1 -0
  184. package/native-host/src/providerStore.js +76 -14
  185. package/native-host/src/releaseTransport.js +14 -5
  186. package/native-host/src/responsesPassthroughBridge.js +266 -52
  187. package/native-host/src/runtimeInstaller.js +21 -1
  188. package/native-host/src/selectionScope.js +86 -0
  189. package/native-host/src/skills/parallel-subagents/SKILL.md +31 -3
  190. package/native-host/src/skills/writing-style-builder/SKILL.md +146 -0
  191. package/native-host/src/subagentAdmission.js +26 -0
  192. package/native-host/src/subagentBroker.js +176 -159
  193. package/native-host/src/subagentTelemetry.js +325 -0
  194. package/native-host/src/subagentWorkspace.js +103 -0
  195. package/native-host/src/subagentWorkspacePath.js +34 -0
  196. package/native-host/src/taskRunnerRuntime.js +130 -57
  197. package/native-host/src/tomlStatements.js +140 -0
  198. package/native-host/src/turnAttachments.js +113 -0
  199. package/native-host/src/updateManager.js +406 -38
  200. package/native-host/src/updateNetworkControl.js +75 -0
  201. package/native-host/src/updateTrust.js +21 -2
  202. package/native-host/src/vendor/pdfjs/LICENSE +177 -0
  203. package/native-host/src/vendor/pdfjs/SOURCE.txt +3 -0
  204. package/native-host/src/vendor/pdfjs/cmaps/78-EUC-H.bcmap +0 -0
  205. package/native-host/src/vendor/pdfjs/cmaps/78-EUC-V.bcmap +0 -0
  206. package/native-host/src/vendor/pdfjs/cmaps/78-H.bcmap +0 -0
  207. package/native-host/src/vendor/pdfjs/cmaps/78-RKSJ-H.bcmap +0 -0
  208. package/native-host/src/vendor/pdfjs/cmaps/78-RKSJ-V.bcmap +0 -0
  209. package/native-host/src/vendor/pdfjs/cmaps/78-V.bcmap +0 -0
  210. package/native-host/src/vendor/pdfjs/cmaps/78ms-RKSJ-H.bcmap +0 -0
  211. package/native-host/src/vendor/pdfjs/cmaps/78ms-RKSJ-V.bcmap +0 -0
  212. package/native-host/src/vendor/pdfjs/cmaps/83pv-RKSJ-H.bcmap +0 -0
  213. package/native-host/src/vendor/pdfjs/cmaps/90ms-RKSJ-H.bcmap +0 -0
  214. package/native-host/src/vendor/pdfjs/cmaps/90ms-RKSJ-V.bcmap +0 -0
  215. package/native-host/src/vendor/pdfjs/cmaps/90msp-RKSJ-H.bcmap +0 -0
  216. package/native-host/src/vendor/pdfjs/cmaps/90msp-RKSJ-V.bcmap +0 -0
  217. package/native-host/src/vendor/pdfjs/cmaps/90pv-RKSJ-H.bcmap +0 -0
  218. package/native-host/src/vendor/pdfjs/cmaps/90pv-RKSJ-V.bcmap +0 -0
  219. package/native-host/src/vendor/pdfjs/cmaps/Add-H.bcmap +0 -0
  220. package/native-host/src/vendor/pdfjs/cmaps/Add-RKSJ-H.bcmap +0 -0
  221. package/native-host/src/vendor/pdfjs/cmaps/Add-RKSJ-V.bcmap +0 -0
  222. package/native-host/src/vendor/pdfjs/cmaps/Add-V.bcmap +0 -0
  223. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-0.bcmap +0 -0
  224. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-1.bcmap +0 -0
  225. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-2.bcmap +0 -0
  226. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-3.bcmap +0 -0
  227. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-4.bcmap +0 -0
  228. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-5.bcmap +0 -0
  229. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-6.bcmap +0 -0
  230. package/native-host/src/vendor/pdfjs/cmaps/Adobe-CNS1-UCS2.bcmap +0 -0
  231. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-0.bcmap +0 -0
  232. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-1.bcmap +0 -0
  233. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-2.bcmap +0 -0
  234. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-3.bcmap +0 -0
  235. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-4.bcmap +0 -0
  236. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-5.bcmap +0 -0
  237. package/native-host/src/vendor/pdfjs/cmaps/Adobe-GB1-UCS2.bcmap +0 -0
  238. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-0.bcmap +0 -0
  239. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-1.bcmap +0 -0
  240. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-2.bcmap +0 -0
  241. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-3.bcmap +0 -0
  242. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-4.bcmap +0 -0
  243. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-5.bcmap +0 -0
  244. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-6.bcmap +0 -0
  245. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Japan1-UCS2.bcmap +0 -0
  246. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-0.bcmap +0 -0
  247. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-1.bcmap +0 -0
  248. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-2.bcmap +0 -0
  249. package/native-host/src/vendor/pdfjs/cmaps/Adobe-Korea1-UCS2.bcmap +0 -0
  250. package/native-host/src/vendor/pdfjs/cmaps/B5-H.bcmap +0 -0
  251. package/native-host/src/vendor/pdfjs/cmaps/B5-V.bcmap +0 -0
  252. package/native-host/src/vendor/pdfjs/cmaps/B5pc-H.bcmap +0 -0
  253. package/native-host/src/vendor/pdfjs/cmaps/B5pc-V.bcmap +0 -0
  254. package/native-host/src/vendor/pdfjs/cmaps/CNS-EUC-H.bcmap +0 -0
  255. package/native-host/src/vendor/pdfjs/cmaps/CNS-EUC-V.bcmap +0 -0
  256. package/native-host/src/vendor/pdfjs/cmaps/CNS1-H.bcmap +0 -0
  257. package/native-host/src/vendor/pdfjs/cmaps/CNS1-V.bcmap +0 -0
  258. package/native-host/src/vendor/pdfjs/cmaps/CNS2-H.bcmap +0 -0
  259. package/native-host/src/vendor/pdfjs/cmaps/CNS2-V.bcmap +3 -0
  260. package/native-host/src/vendor/pdfjs/cmaps/ETHK-B5-H.bcmap +0 -0
  261. package/native-host/src/vendor/pdfjs/cmaps/ETHK-B5-V.bcmap +0 -0
  262. package/native-host/src/vendor/pdfjs/cmaps/ETen-B5-H.bcmap +0 -0
  263. package/native-host/src/vendor/pdfjs/cmaps/ETen-B5-V.bcmap +0 -0
  264. package/native-host/src/vendor/pdfjs/cmaps/ETenms-B5-H.bcmap +3 -0
  265. package/native-host/src/vendor/pdfjs/cmaps/ETenms-B5-V.bcmap +0 -0
  266. package/native-host/src/vendor/pdfjs/cmaps/EUC-H.bcmap +0 -0
  267. package/native-host/src/vendor/pdfjs/cmaps/EUC-V.bcmap +0 -0
  268. package/native-host/src/vendor/pdfjs/cmaps/Ext-H.bcmap +0 -0
  269. package/native-host/src/vendor/pdfjs/cmaps/Ext-RKSJ-H.bcmap +0 -0
  270. package/native-host/src/vendor/pdfjs/cmaps/Ext-RKSJ-V.bcmap +0 -0
  271. package/native-host/src/vendor/pdfjs/cmaps/Ext-V.bcmap +0 -0
  272. package/native-host/src/vendor/pdfjs/cmaps/GB-EUC-H.bcmap +0 -0
  273. package/native-host/src/vendor/pdfjs/cmaps/GB-EUC-V.bcmap +0 -0
  274. package/native-host/src/vendor/pdfjs/cmaps/GB-H.bcmap +4 -0
  275. package/native-host/src/vendor/pdfjs/cmaps/GB-V.bcmap +0 -0
  276. package/native-host/src/vendor/pdfjs/cmaps/GBK-EUC-H.bcmap +0 -0
  277. package/native-host/src/vendor/pdfjs/cmaps/GBK-EUC-V.bcmap +0 -0
  278. package/native-host/src/vendor/pdfjs/cmaps/GBK2K-H.bcmap +0 -0
  279. package/native-host/src/vendor/pdfjs/cmaps/GBK2K-V.bcmap +0 -0
  280. package/native-host/src/vendor/pdfjs/cmaps/GBKp-EUC-H.bcmap +0 -0
  281. package/native-host/src/vendor/pdfjs/cmaps/GBKp-EUC-V.bcmap +0 -0
  282. package/native-host/src/vendor/pdfjs/cmaps/GBT-EUC-H.bcmap +0 -0
  283. package/native-host/src/vendor/pdfjs/cmaps/GBT-EUC-V.bcmap +0 -0
  284. package/native-host/src/vendor/pdfjs/cmaps/GBT-H.bcmap +0 -0
  285. package/native-host/src/vendor/pdfjs/cmaps/GBT-V.bcmap +0 -0
  286. package/native-host/src/vendor/pdfjs/cmaps/GBTpc-EUC-H.bcmap +0 -0
  287. package/native-host/src/vendor/pdfjs/cmaps/GBTpc-EUC-V.bcmap +0 -0
  288. package/native-host/src/vendor/pdfjs/cmaps/GBpc-EUC-H.bcmap +0 -0
  289. package/native-host/src/vendor/pdfjs/cmaps/GBpc-EUC-V.bcmap +0 -0
  290. package/native-host/src/vendor/pdfjs/cmaps/H.bcmap +0 -0
  291. package/native-host/src/vendor/pdfjs/cmaps/HKdla-B5-H.bcmap +0 -0
  292. package/native-host/src/vendor/pdfjs/cmaps/HKdla-B5-V.bcmap +0 -0
  293. package/native-host/src/vendor/pdfjs/cmaps/HKdlb-B5-H.bcmap +0 -0
  294. package/native-host/src/vendor/pdfjs/cmaps/HKdlb-B5-V.bcmap +0 -0
  295. package/native-host/src/vendor/pdfjs/cmaps/HKgccs-B5-H.bcmap +0 -0
  296. package/native-host/src/vendor/pdfjs/cmaps/HKgccs-B5-V.bcmap +0 -0
  297. package/native-host/src/vendor/pdfjs/cmaps/HKm314-B5-H.bcmap +0 -0
  298. package/native-host/src/vendor/pdfjs/cmaps/HKm314-B5-V.bcmap +0 -0
  299. package/native-host/src/vendor/pdfjs/cmaps/HKm471-B5-H.bcmap +0 -0
  300. package/native-host/src/vendor/pdfjs/cmaps/HKm471-B5-V.bcmap +0 -0
  301. package/native-host/src/vendor/pdfjs/cmaps/HKscs-B5-H.bcmap +0 -0
  302. package/native-host/src/vendor/pdfjs/cmaps/HKscs-B5-V.bcmap +0 -0
  303. package/native-host/src/vendor/pdfjs/cmaps/Hankaku.bcmap +0 -0
  304. package/native-host/src/vendor/pdfjs/cmaps/Hiragana.bcmap +0 -0
  305. package/native-host/src/vendor/pdfjs/cmaps/KSC-EUC-H.bcmap +0 -0
  306. package/native-host/src/vendor/pdfjs/cmaps/KSC-EUC-V.bcmap +0 -0
  307. package/native-host/src/vendor/pdfjs/cmaps/KSC-H.bcmap +0 -0
  308. package/native-host/src/vendor/pdfjs/cmaps/KSC-Johab-H.bcmap +0 -0
  309. package/native-host/src/vendor/pdfjs/cmaps/KSC-Johab-V.bcmap +0 -0
  310. package/native-host/src/vendor/pdfjs/cmaps/KSC-V.bcmap +0 -0
  311. package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-H.bcmap +0 -0
  312. package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-HW-H.bcmap +0 -0
  313. package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-HW-V.bcmap +0 -0
  314. package/native-host/src/vendor/pdfjs/cmaps/KSCms-UHC-V.bcmap +0 -0
  315. package/native-host/src/vendor/pdfjs/cmaps/KSCpc-EUC-H.bcmap +0 -0
  316. package/native-host/src/vendor/pdfjs/cmaps/KSCpc-EUC-V.bcmap +0 -0
  317. package/native-host/src/vendor/pdfjs/cmaps/Katakana.bcmap +0 -0
  318. package/native-host/src/vendor/pdfjs/cmaps/LICENSE +36 -0
  319. package/native-host/src/vendor/pdfjs/cmaps/NWP-H.bcmap +0 -0
  320. package/native-host/src/vendor/pdfjs/cmaps/NWP-V.bcmap +0 -0
  321. package/native-host/src/vendor/pdfjs/cmaps/RKSJ-H.bcmap +0 -0
  322. package/native-host/src/vendor/pdfjs/cmaps/RKSJ-V.bcmap +0 -0
  323. package/native-host/src/vendor/pdfjs/cmaps/Roman.bcmap +0 -0
  324. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UCS2-H.bcmap +0 -0
  325. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UCS2-V.bcmap +0 -0
  326. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF16-H.bcmap +0 -0
  327. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF16-V.bcmap +0 -0
  328. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF32-H.bcmap +0 -0
  329. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF32-V.bcmap +0 -0
  330. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF8-H.bcmap +0 -0
  331. package/native-host/src/vendor/pdfjs/cmaps/UniCNS-UTF8-V.bcmap +0 -0
  332. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UCS2-H.bcmap +0 -0
  333. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UCS2-V.bcmap +0 -0
  334. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF16-H.bcmap +0 -0
  335. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF16-V.bcmap +0 -0
  336. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF32-H.bcmap +0 -0
  337. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF32-V.bcmap +0 -0
  338. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF8-H.bcmap +0 -0
  339. package/native-host/src/vendor/pdfjs/cmaps/UniGB-UTF8-V.bcmap +0 -0
  340. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-H.bcmap +0 -0
  341. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-HW-H.bcmap +0 -0
  342. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-HW-V.bcmap +0 -0
  343. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UCS2-V.bcmap +0 -0
  344. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF16-H.bcmap +0 -0
  345. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF16-V.bcmap +0 -0
  346. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF32-H.bcmap +0 -0
  347. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF32-V.bcmap +0 -0
  348. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF8-H.bcmap +0 -0
  349. package/native-host/src/vendor/pdfjs/cmaps/UniJIS-UTF8-V.bcmap +0 -0
  350. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF16-H.bcmap +0 -0
  351. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF16-V.bcmap +0 -0
  352. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF32-H.bcmap +0 -0
  353. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF32-V.bcmap +0 -0
  354. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF8-H.bcmap +0 -0
  355. package/native-host/src/vendor/pdfjs/cmaps/UniJIS2004-UTF8-V.bcmap +0 -0
  356. package/native-host/src/vendor/pdfjs/cmaps/UniJISPro-UCS2-HW-V.bcmap +0 -0
  357. package/native-host/src/vendor/pdfjs/cmaps/UniJISPro-UCS2-V.bcmap +0 -0
  358. package/native-host/src/vendor/pdfjs/cmaps/UniJISPro-UTF8-V.bcmap +0 -0
  359. package/native-host/src/vendor/pdfjs/cmaps/UniJISX0213-UTF32-H.bcmap +0 -0
  360. package/native-host/src/vendor/pdfjs/cmaps/UniJISX0213-UTF32-V.bcmap +0 -0
  361. package/native-host/src/vendor/pdfjs/cmaps/UniJISX02132004-UTF32-H.bcmap +0 -0
  362. package/native-host/src/vendor/pdfjs/cmaps/UniJISX02132004-UTF32-V.bcmap +0 -0
  363. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UCS2-H.bcmap +0 -0
  364. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UCS2-V.bcmap +0 -0
  365. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF16-H.bcmap +0 -0
  366. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF16-V.bcmap +0 -0
  367. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF32-H.bcmap +0 -0
  368. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF32-V.bcmap +0 -0
  369. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF8-H.bcmap +0 -0
  370. package/native-host/src/vendor/pdfjs/cmaps/UniKS-UTF8-V.bcmap +0 -0
  371. package/native-host/src/vendor/pdfjs/cmaps/V.bcmap +0 -0
  372. package/native-host/src/vendor/pdfjs/cmaps/WP-Symbol.bcmap +0 -0
  373. package/native-host/src/vendor/pdfjs/pdf.mjs +26740 -0
  374. package/native-host/src/vendor/pdfjs/pdf.worker.mjs +62201 -0
  375. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitDingbats.pfb +0 -0
  376. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixed.pfb +0 -0
  377. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixedBold.pfb +0 -0
  378. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixedBoldItalic.pfb +0 -0
  379. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitFixedItalic.pfb +0 -0
  380. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerif.pfb +0 -0
  381. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerifBold.pfb +0 -0
  382. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerifBoldItalic.pfb +0 -0
  383. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSerifItalic.pfb +0 -0
  384. package/native-host/src/vendor/pdfjs/standard_fonts/FoxitSymbol.pfb +0 -0
  385. package/native-host/src/vendor/pdfjs/standard_fonts/LICENSE_FOXIT +27 -0
  386. package/native-host/src/vendor/pdfjs/standard_fonts/LICENSE_LIBERATION +102 -0
  387. package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-Bold.ttf +0 -0
  388. package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-BoldItalic.ttf +0 -0
  389. package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-Italic.ttf +0 -0
  390. package/native-host/src/vendor/pdfjs/standard_fonts/LiberationSans-Regular.ttf +0 -0
  391. package/native-host/src/writingStyleEvidence.js +102 -0
  392. package/native-host/src/writingStylePdfWorker.js +35 -0
  393. package/native-host/src/writingStyleProfile.js +165 -0
  394. package/native-host/src/writingStyleRuntime.js +475 -0
  395. package/native-host/src/writingStyleStore.js +73 -0
  396. package/package.json +1 -1
  397. package/scripts/install-managed.mjs +1 -0
@@ -0,0 +1,101 @@
1
+ 'use strict';
2
+
3
+ const crypto = require('node:crypto');
4
+ const fs = require('node:fs');
5
+ const path = require('node:path');
6
+
7
+ // Exact bytes from the published v2.5.0 Bootstrap. Unknown local modifications
8
+ // are never converted into a migration source simply because versions agree.
9
+ const BOOTSTRAP_MIGRATION_BASELINE = Object.freeze({
10
+ "bootstrap/background.js": "5e15d208f07668f96cb94a84642d5fd9ad2dd921991bb3bd5bf67cc43037c87a",
11
+ "bootstrap/popup.css": "0709a4b8aba5e59e95fd07afec4d29ba441bde46fae48863133a170ad12cbe58",
12
+ "bootstrap/popup.html": "7cbcead701cb03a4006bbd682a744aeca30d613eb8315a194f2ba751b6fd9e55",
13
+ "bootstrap/popup.js": "24f7171045ad7de9431d24e0e4a7d15237620f4217dd5e68772dbdf52b8ce4d8",
14
+ "bootstrap/popupFallback.js": null,
15
+ "bootstrap/runtimeContext.js": "ac04d9bb28308015ecfe296f152996521398dc0bb018416e34abe8424734a21b",
16
+ "bootstrap/update.css": "43a0d4345f6f35a30c792a6fd67227776ec85ba710f89cae9c167b453de72342",
17
+ "bootstrap/update.html": "7ce092eabcdf51564f994d8f72c474285f07777bd7a5a205eca8e5a0931964ab",
18
+ "bootstrap/update.js": "ee67a23d89d435f05d3e4c1ec1f9c5a7f0bdcef4449e13be4d7acbbcf182413c",
19
+ "bootstrap/updateStatus.js": "d2ad90e78c50367a5489bb6f5c27c7248112047aca9f05d2ad868ac3b5266b24"
20
+ });
21
+ const BOOTSTRAP_MIGRATION_FILES = Object.freeze(Object.keys(BOOTSTRAP_MIGRATION_BASELINE));
22
+ const BOOTSTRAP_MIGRATION_TARGET_VERSION = '2.5.1';
23
+ const BOOTSTRAP_MIGRATION_REVISION = '3.1';
24
+ const BOOTSTRAP_MIGRATION_IMPLEMENTATION_FILES = Object.freeze([
25
+ 'native-host/src/bootstrapMigrationContract.js',
26
+ 'native-host/src/bootstrapMigration.js',
27
+ 'native-host/src/bootstrapUpdate.js',
28
+ 'native-host/src/bootstrapUpdateWatchdog.js',
29
+ 'extension/src/backgroundBootstrapMigration.js'
30
+ ]);
31
+ const BOOTSTRAP_MANIFEST_SHAPE_SHA256 = '85c2d3875196ff9b334b40bb115a42fe4b8cab4e9c37609fb65e8834284c8fbe';
32
+
33
+ function isBootstrapMigrationRelease(version) {
34
+ return version === BOOTSTRAP_MIGRATION_TARGET_VERSION;
35
+ }
36
+
37
+ function buildBootstrapMigrationDescriptor({ packageRoot, version } = {}) {
38
+ if (!isBootstrapMigrationRelease(version)) return null;
39
+ assertBootstrapManifestShape(JSON.parse(fs.readFileSync(path.join(packageRoot,
40
+ 'extension/bootstrap/manifest.template.json'), 'utf8')), { version });
41
+ const files = BOOTSTRAP_MIGRATION_FILES.map(relativePath => ({
42
+ path: relativePath,
43
+ sourceSha256: BOOTSTRAP_MIGRATION_BASELINE[relativePath],
44
+ targetSha256: sha256(fs.readFileSync(path.join(packageRoot, 'extension', relativePath)))
45
+ }));
46
+ return validateBootstrapMigrationDescriptor({
47
+ schemaVersion: 1,
48
+ id: 'bootstrap-v3.1-from-2.5.0',
49
+ bootstrapProtocol: 3,
50
+ sourceVersions: ['2.5.0'],
51
+ targetVersion: version,
52
+ targetRevision: BOOTSTRAP_MIGRATION_REVISION,
53
+ files
54
+ }, { targetVersion: version });
55
+ }
56
+
57
+ function validateBootstrapMigrationDescriptor(descriptor, { targetVersion } = {}) {
58
+ if (!descriptor || descriptor.schemaVersion !== 1 || descriptor.id !== 'bootstrap-v3.1-from-2.5.0'
59
+ || descriptor.bootstrapProtocol !== 3 || descriptor.targetRevision !== BOOTSTRAP_MIGRATION_REVISION
60
+ || descriptor.targetVersion !== BOOTSTRAP_MIGRATION_TARGET_VERSION
61
+ || (targetVersion && descriptor.targetVersion !== targetVersion)
62
+ || JSON.stringify(descriptor.sourceVersions) !== JSON.stringify(['2.5.0'])
63
+ || !Array.isArray(descriptor.files) || descriptor.files.length !== BOOTSTRAP_MIGRATION_FILES.length) {
64
+ throw new Error('Unsupported Bootstrap migration descriptor.');
65
+ }
66
+ const seen = new Set();
67
+ for (const file of descriptor.files) {
68
+ if (!file || !Object.hasOwn(BOOTSTRAP_MIGRATION_BASELINE, file.path) || seen.has(file.path)
69
+ || file.sourceSha256 !== BOOTSTRAP_MIGRATION_BASELINE[file.path]
70
+ || !/^[0-9a-f]{64}$/.test(file.targetSha256 || '')) {
71
+ throw new Error('Bootstrap migration file identity is invalid.');
72
+ }
73
+ seen.add(file.path);
74
+ }
75
+ return descriptor;
76
+ }
77
+
78
+ function assertBootstrapManifestShape(manifest, { version } = {}) {
79
+ if (!manifest || (version && manifest.version !== version)
80
+ || sha256(Buffer.from(stableJson({ ...manifest, version: '<release-version>' }))) !== BOOTSTRAP_MANIFEST_SHAPE_SHA256) {
81
+ throw new Error('Bootstrap migration cannot change the extension manifest shape or permissions.');
82
+ }
83
+ return manifest;
84
+ }
85
+
86
+ function stableJson(value) {
87
+ if (Array.isArray(value)) return '[' + value.map(stableJson).join(',') + ']';
88
+ if (value && typeof value === 'object') return '{' + Object.keys(value).sort()
89
+ .map(key => JSON.stringify(key) + ':' + stableJson(value[key])).join(',') + '}';
90
+ return JSON.stringify(value);
91
+ }
92
+
93
+ function sha256(bytes) {
94
+ return crypto.createHash('sha256').update(bytes).digest('hex');
95
+ }
96
+
97
+ module.exports = {
98
+ BOOTSTRAP_MIGRATION_BASELINE, BOOTSTRAP_MIGRATION_FILES, BOOTSTRAP_MIGRATION_TARGET_VERSION,
99
+ BOOTSTRAP_MIGRATION_REVISION, isBootstrapMigrationRelease, buildBootstrapMigrationDescriptor,
100
+ BOOTSTRAP_MIGRATION_IMPLEMENTATION_FILES, validateBootstrapMigrationDescriptor, assertBootstrapManifestShape
101
+ };
@@ -0,0 +1,233 @@
1
+ 'use strict';
2
+
3
+ // Coordination for the one compatible 2.5.0 -> 2.5.1 Bootstrap revision.
4
+ // All mutations run under updateManager's existing cross-process lock.
5
+ const fs = require('node:fs');
6
+ const path = require('node:path');
7
+ const crypto = require('node:crypto');
8
+ const vm = require('node:vm');
9
+ const { spawn } = require('node:child_process');
10
+ const Files = require('./bootstrapMigration');
11
+ const Contract = require('./bootstrapMigrationContract');
12
+ const { updateError } = require('./updateTrust');
13
+
14
+ const BOOTSTRAP_DEADLINE_MS = 120000;
15
+ const BOOTSTRAP_STATES = new Set(['bootstrap_pending', 'bootstrap_rolling_back']);
16
+ const backupRoot = context => path.join(context.updatesRoot, 'bootstrap-migrations');
17
+ const hash = bytes => crypto.createHash('sha256').update(bytes).digest('hex');
18
+
19
+ function migrationHint(context, journal) {
20
+ if (!journal || !['awaiting_health', ...BOOTSTRAP_STATES].includes(journal.state)) return null;
21
+ if (journal.bootstrapMigration) return journal.bootstrapMigration;
22
+ if (journal.sourceVersion !== '2.5.0' || journal.targetVersion !== '2.5.1') return null;
23
+ // This exact release pair requires migration even when discovery data was
24
+ // lost. Missing evidence must not downgrade an update into a false success.
25
+ return { phase: 'pending', targetRevision: '3.1' };
26
+ }
27
+
28
+ function bindBootstrapMigration(context, journal, deps) {
29
+ if (journal?.state !== 'awaiting_health' || journal.bootstrapMigration || !migrationHint(context, journal)) return journal;
30
+ const candidate = readJson(path.join(context.updatesRoot, 'candidate.json'));
31
+ let verificationError = '';
32
+ try { deps.assertAuthorization(journal); verifiedDescriptor(journal, candidate, deps); }
33
+ catch (error) { verificationError = error.code || 'update_bootstrap_manifest_mismatch'; }
34
+ const next = { ...journal, state: 'bootstrap_pending', bootstrapMigration: {
35
+ phase: 'pending', targetRevision: '3.1', reloadCount: 0, verificationError,
36
+ manifestBase64: candidate?.manifestBase64 || '', signatureBase64: candidate?.signatureBase64 || ''
37
+ }, updatedAt: new Date().toISOString() };
38
+ deps.writeJournal(next);
39
+ return next;
40
+ }
41
+
42
+ function verifiedDescriptor(journal, evidence, deps) {
43
+ const bytes = Buffer.from(evidence?.manifestBase64 || '', 'base64');
44
+ if (!journal.manifestSha256 || hash(bytes) !== journal.manifestSha256) {
45
+ throw updateError('update_bootstrap_manifest_mismatch', 'Bootstrap migration does not match the applied release.');
46
+ }
47
+ const manifest = deps.verifyManifest(bytes, Buffer.from(evidence?.signatureBase64 || '', 'base64'));
48
+ if (manifest.version !== journal.targetVersion || manifest.updateBundle?.sha256 !== journal.bundleSha256
49
+ || manifest.updateBundle?.size !== journal.bundleSize) {
50
+ throw updateError('update_bootstrap_manifest_mismatch', 'Bootstrap migration does not match the update archive.');
51
+ }
52
+ const descriptor = Contract.validateBootstrapMigrationDescriptor(manifest.bootstrapMigration, { targetVersion: journal.targetVersion });
53
+ if (!descriptor.sourceVersions.includes(journal.sourceVersion)) {
54
+ throw updateError('update_bootstrap_source_version_mismatch', 'This installation has no compatible Bootstrap migration.');
55
+ }
56
+ return descriptor;
57
+ }
58
+
59
+ function payloadRootFor(context, journal) {
60
+ return path.join(context.nativeRoot, 'versions', journal.targetVersion, 'native-host', 'bootstrap-payload');
61
+ }
62
+
63
+ function loadPlan(context, journal) {
64
+ const root = backupRoot(context);
65
+ if (!fs.existsSync(path.join(root, journal.id, 'state.json'))) return null;
66
+ const plan = Files.loadBootstrapMigration({ backupRoot: root, transactionId: journal.id });
67
+ if (plan.extensionRoot !== context.extensionRoot || plan.payloadRoot !== payloadRootFor(context, journal)
68
+ || plan.sourceVersion !== journal.sourceVersion || plan.targetVersion !== journal.targetVersion) {
69
+ throw updateError('update_bootstrap_transaction_mismatch', 'Bootstrap recovery belongs to a different installation.');
70
+ }
71
+ return plan;
72
+ }
73
+
74
+ async function advanceBootstrapMigration(context, journal, params, deps, options = {}) {
75
+ if (!journal || !migrationHint(context, journal)) return { state: 'not_required' };
76
+ if (params.transactionId !== journal.id) throw updateError('update_transaction_mismatch', 'Bootstrap update transaction changed.');
77
+ journal = bindBootstrapMigration(context, journal, deps);
78
+ if (journal.state !== 'bootstrap_pending') {
79
+ throw updateError('update_transaction_state_changed', 'Bootstrap migration is no longer waiting to continue.');
80
+ }
81
+ if (deps.runningVersion !== journal.targetVersion) {
82
+ throw updateError('update_bootstrap_native_restart_required', 'The target Native Host must start before updating Bootstrap.');
83
+ }
84
+ deps.assertAuthorization(journal);
85
+ const descriptor = verifiedDescriptor(journal, journal.bootstrapMigration, deps);
86
+ const payloadRoot = payloadRootFor(context, journal);
87
+ Contract.assertBootstrapManifestShape(JSON.parse(fs.readFileSync(path.join(context.extensionRoot, 'manifest.json'), 'utf8')),
88
+ { version: journal.targetVersion });
89
+ Contract.assertBootstrapManifestShape(JSON.parse(fs.readFileSync(path.join(payloadRoot, 'manifest.template.json'), 'utf8')),
90
+ { version: journal.targetVersion });
91
+ // A syntax failure must be found before changing the only background entry.
92
+ for (const file of descriptor.files) {
93
+ const bytes = fs.readFileSync(path.join(payloadRoot, file.path));
94
+ if (hash(bytes) !== file.targetSha256) throw updateError('update_bootstrap_payload_mismatch', 'Bootstrap payload changed after verification.');
95
+ if (file.path.endsWith('.js')) new vm.Script(bytes.toString('utf8'), { filename: file.path });
96
+ }
97
+ deps.verifyArchive(journal);
98
+ let plan = loadPlan(context, journal);
99
+ if (!plan) plan = Files.prepareBootstrapMigration({
100
+ descriptor, payloadRoot, extensionRoot: context.extensionRoot, backupRoot: backupRoot(context),
101
+ transactionId: journal.id, sourceVersion: journal.sourceVersion, targetVersion: journal.targetVersion
102
+ });
103
+ if (plan.descriptorSha256 !== hash(JSON.stringify(descriptor))) {
104
+ throw updateError('update_bootstrap_manifest_mismatch', 'Bootstrap recovery material does not match the signed release.');
105
+ }
106
+ let migration = { ...journal.bootstrapMigration, phase: plan.state === 'applied' ? 'applied' : 'prepared',
107
+ targetDigest: plan.targetDigest, sourceDigest: plan.sourceDigest,
108
+ deadline: journal.bootstrapMigration.deadline || Date.now() + BOOTSTRAP_DEADLINE_MS };
109
+ if (Date.now() >= migration.deadline) throw updateError('update_bootstrap_health_timeout', 'Bootstrap update did not finish within its health window.');
110
+ journal = { ...journal, bootstrapMigration: migration };
111
+ deps.writeJournal(journal);
112
+ // A new connection always establishes a new monitor handshake. PID reuse
113
+ // alone can never authorize writing the only browser background entry.
114
+ {
115
+ const token = crypto.randomUUID();
116
+ migration = { ...migration, watchdogToken: token, watchdogPid: null };
117
+ journal = { ...journal, bootstrapMigration: migration };
118
+ deps.writeJournal(journal);
119
+ const pid = await (options.startWatchdog || startWatchdog)(context, journal, token);
120
+ migration = { ...migration, watchdogPid: pid };
121
+ journal = { ...journal, bootstrapMigration: migration };
122
+ deps.writeJournal(journal);
123
+ }
124
+ Files.applyBootstrapMigration(plan, options.fileHooks);
125
+ const observed = Files.verifyBootstrapMigration(plan);
126
+ migration = { ...migration, phase: 'applied', targetDigest: observed.digest };
127
+ if (params.bootstrapRevision === descriptor.targetRevision) {
128
+ migration = { ...migration, phase: 'loaded', loadedAt: new Date().toISOString() };
129
+ deps.writeJournal({ ...journal, state: 'awaiting_health', bootstrapMigration: migration });
130
+ return { state: 'awaiting_health', transactionId: journal.id, targetVersion: journal.targetVersion,
131
+ bootstrapRevision: descriptor.targetRevision };
132
+ }
133
+ if (migration.reloadCount >= 2) throw updateError('update_bootstrap_reload_failed', 'The new Bootstrap did not load after extension restart.');
134
+ migration.reloadCount += 1;
135
+ deps.writeJournal({ ...journal, bootstrapMigration: migration });
136
+ return { state: 'reload_required', transactionId: journal.id, targetVersion: journal.targetVersion,
137
+ bootstrapRevision: descriptor.targetRevision };
138
+ }
139
+
140
+ function assertBootstrapConfirmation(context, journal, params) {
141
+ if (!journal.bootstrapMigration) {
142
+ if (migrationHint(context, journal)) throw updateError('update_bootstrap_confirmation_pending', 'Bootstrap migration is still pending.');
143
+ return;
144
+ }
145
+ if (journal.bootstrapMigration.phase !== 'loaded' || params.bootstrapRevision !== journal.bootstrapMigration.targetRevision) {
146
+ throw updateError('update_bootstrap_confirmation_pending', 'The loaded Bootstrap did not confirm the target revision.');
147
+ }
148
+ const plan = loadPlan(context, journal);
149
+ if (!plan || Files.verifyBootstrapMigration(plan).digest !== journal.bootstrapMigration.targetDigest) {
150
+ throw updateError('update_bootstrap_target_mismatch', 'The confirmed Bootstrap bytes no longer match the target.');
151
+ }
152
+ }
153
+
154
+ function restoreBootstrap(context, journal) {
155
+ const plan = loadPlan(context, journal);
156
+ if (!plan) {
157
+ if (journal.bootstrapMigration && journal.bootstrapMigration.phase !== 'pending') {
158
+ throw updateError('update_bootstrap_record_missing', 'Bootstrap recovery material is missing.');
159
+ }
160
+ if (journal.bootstrapMigration) return assertSourceBootstrap(context, journal);
161
+ }
162
+ return plan ? Files.restoreBootstrapMigration(plan) : null;
163
+ }
164
+
165
+ function bootstrapEvidence(context, journal, expected) {
166
+ const plan = loadPlan(context, journal);
167
+ if (!plan && journal.bootstrapMigration) {
168
+ if (expected !== 'source' || !(journal.bootstrapMigration.phase === 'pending'
169
+ || journal.bootstrapMigration.phase === 'restored' && journal.bootstrapMigration.sourceUnchanged === true)) {
170
+ throw updateError('update_bootstrap_record_missing', 'Bootstrap recovery material is missing.');
171
+ }
172
+ return assertSourceBootstrap(context, journal);
173
+ }
174
+ return plan ? Files.verifyBootstrapMigration(plan, { expected }) : null;
175
+ }
176
+
177
+ function assertSourceBootstrap(context, journal) {
178
+ for (const [relative, expected] of Object.entries(Contract.BOOTSTRAP_MIGRATION_BASELINE)) {
179
+ const filename = path.join(context.extensionRoot, relative);
180
+ if (expected === null ? fs.existsSync(filename)
181
+ : !fs.existsSync(filename) || !fs.lstatSync(filename).isFile() || hash(fs.readFileSync(filename)) !== expected) {
182
+ throw updateError('update_bootstrap_source_mismatch', 'Bootstrap source bytes cannot be confirmed.');
183
+ }
184
+ }
185
+ const entries = Object.entries(Contract.BOOTSTRAP_MIGRATION_BASELINE).sort((a, b) => a[0].localeCompare(b[0]));
186
+ return { transactionId: journal.id, migrationId: 'bootstrap-v3.1-from-2.5.0',
187
+ state: 'restored', expected: 'source', digest: hash(JSON.stringify(entries)), unmodified: true };
188
+ }
189
+
190
+ function bootstrapExpired(journal, { recoveryRequested = false, context } = {}) {
191
+ const migration = journal?.bootstrapMigration;
192
+ if (!migration || !['bootstrap_pending', 'bootstrap_rolling_back', 'awaiting_health'].includes(journal.state)) return false;
193
+ return journal.state === 'bootstrap_rolling_back'
194
+ || (migration.deadline && Date.now() >= migration.deadline)
195
+ || (recoveryRequested && migration.phase !== 'pending' && !watchdogAlive(migration, context, journal));
196
+ }
197
+
198
+ function watchdogAlive(migration, context, journal) {
199
+ if (!Number.isInteger(migration?.watchdogPid) || migration.watchdogPid < 1) return false;
200
+ const heartbeat = context && journal && readJson(path.join(backupRoot(context), journal.id, 'watchdog.json'));
201
+ if (!heartbeat || heartbeat.token !== migration.watchdogToken || heartbeat.pid !== migration.watchdogPid
202
+ || heartbeat.transactionId !== journal.id || Date.now() - heartbeat.at > 2500 || heartbeat.at > Date.now() + 1000) return false;
203
+ try { process.kill(migration.watchdogPid, 0); return true; } catch (error) { return error.code === 'EPERM'; }
204
+ }
205
+
206
+ function startWatchdog(context, journal, token) {
207
+ return new Promise((resolve, reject) => {
208
+ const child = spawn(process.execPath, [path.join(__dirname, 'bootstrapUpdateWatchdog.js'),
209
+ context.nativeRoot, context.extensionRoot, journal.id, token], {
210
+ env: { ...context.env }, detached: true, windowsHide: true, stdio: ['ignore', 'ignore', 'ignore', 'ipc']
211
+ });
212
+ const timer = setTimeout(() => fail(new Error('Bootstrap recovery monitor did not become ready.')), 5000);
213
+ let settled = false;
214
+ function fail(error) {
215
+ if (settled) return;
216
+ settled = true; clearTimeout(timer);
217
+ try { child.kill(); } catch (_) { /* A failed child may already be gone. */ }
218
+ reject(Object.assign(error, { code: 'update_bootstrap_monitor_unavailable' }));
219
+ }
220
+ child.on('error', fail);
221
+ child.on('exit', () => { if (!settled) fail(new Error('Bootstrap recovery monitor exited before readiness.')); });
222
+ child.on('message', message => {
223
+ if (settled || message?.type !== 'ready' || message.token !== token || message.pid !== child.pid) return;
224
+ settled = true; clearTimeout(timer); child.disconnect(); child.unref(); resolve(child.pid);
225
+ });
226
+ });
227
+ }
228
+
229
+ function readJson(filename) { try { return JSON.parse(fs.readFileSync(filename, 'utf8')); } catch (_) { return null; } }
230
+
231
+ module.exports = { BOOTSTRAP_DEADLINE_MS, BOOTSTRAP_STATES, migrationHint, bindBootstrapMigration,
232
+ advanceBootstrapMigration, assertBootstrapConfirmation, restoreBootstrap, bootstrapEvidence,
233
+ bootstrapExpired, watchdogAlive };
@@ -0,0 +1,44 @@
1
+ 'use strict';
2
+
3
+ // Independent of the browser worker being replaced. The Native update lock
4
+ // serializes timeout recovery with normal health confirmation.
5
+ const fs = require('node:fs');
6
+ const path = require('node:path');
7
+ const [nativeRoot, extensionRoot, transactionId, token] = process.argv.slice(2);
8
+ const { recoverBootstrapTransaction } = require('./updateManager');
9
+ if (typeof recoverBootstrapTransaction !== 'function') throw new Error('Bootstrap recovery entry is unavailable.');
10
+ const env = { ...process.env, CODEX_OVERLEAF_MANAGED: '1',
11
+ CODEX_OVERLEAF_MANAGED_NATIVE_ROOT: nativeRoot, CODEX_OVERLEAF_MANAGED_EXTENSION_ROOT: extensionRoot };
12
+ let busy = false;
13
+ let failures = 0;
14
+ function heartbeat() {
15
+ const directory = path.join(nativeRoot, 'updates', 'bootstrap-migrations', transactionId);
16
+ const temporary = path.join(directory, 'watchdog-' + process.pid + '.tmp');
17
+ fs.writeFileSync(temporary, JSON.stringify({ transactionId, token, pid: process.pid, at: Date.now() }), { mode: 0o600 });
18
+ fs.renameSync(temporary, path.join(directory, 'watchdog.json'));
19
+ }
20
+ const timer = setInterval(async () => {
21
+ if (busy) return;
22
+ busy = true;
23
+ try {
24
+ const journal = JSON.parse(fs.readFileSync(path.join(nativeRoot, 'updates', 'transaction.json'), 'utf8'));
25
+ if (journal.id !== transactionId || journal.bootstrapMigration?.watchdogToken !== token
26
+ || ['committed', 'superseded'].includes(journal.state)
27
+ || journal.state === 'rolled_back' && !journal.sourceActivationPending) {
28
+ clearInterval(timer); return;
29
+ }
30
+ heartbeat();
31
+ if (journal.sourceActivationPending || journal.bootstrapMigration?.deadline && Date.now() >= journal.bootstrapMigration.deadline) {
32
+ await recoverBootstrapTransaction({ env }, transactionId, token);
33
+ clearInterval(timer);
34
+ }
35
+ } catch (_) {
36
+ // Retry boundedly if a filesystem/lock is temporarily unavailable. Recovery
37
+ // material remains durable for the next Native start or popup recovery probe.
38
+ if (++failures >= 20) clearInterval(timer);
39
+ } finally { busy = false; }
40
+ }, 500);
41
+ const initial = JSON.parse(fs.readFileSync(path.join(nativeRoot, 'updates', 'transaction.json'), 'utf8'));
42
+ if (initial.id !== transactionId || initial.bootstrapMigration?.watchdogToken !== token) throw new Error('Bootstrap recovery identity changed.');
43
+ heartbeat();
44
+ process.send?.({ type: 'ready', token, pid: process.pid });
@@ -295,6 +295,7 @@ function completeMessage(state, res) {
295
295
  }
296
296
 
297
297
  function completeTool(state, res, tool) {
298
+ assertCompleteToolArguments(tool.arguments);
298
299
  if (!tool.opened) openTool(state, res, tool);
299
300
  tool.item.status = 'completed';
300
301
  if (tool.kind === 'custom') {
@@ -419,6 +420,7 @@ function normalizeToolCalls(values, toolKinds) {
419
420
  const name = normalizeText(value?.function?.name) || 'tool';
420
421
  const callId = normalizeText(value?.id) || randomId('call');
421
422
  const argumentsText = normalizeText(value?.function?.arguments) || '{}';
423
+ assertCompleteToolArguments(argumentsText);
422
424
  const spec = toolKinds?.get(name);
423
425
  const kind = (typeof spec === 'object' ? spec.kind : spec) === 'custom' ? 'custom' : 'function';
424
426
  const originalName = typeof spec === 'object' ? spec.name || name : name;
@@ -533,6 +535,14 @@ function unwrapCustomArguments(value) {
533
535
  }
534
536
  }
535
537
 
538
+ function assertCompleteToolArguments(value) {
539
+ try {
540
+ JSON.parse(value || '{}');
541
+ } catch (_error) {
542
+ throw responseError('The provider returned incomplete or invalid JSON tool arguments.');
543
+ }
544
+ }
545
+
536
546
  function reserveItem(state, item) {
537
547
  const index = state.items.length;
538
548
  state.items.push(item);
@@ -11,6 +11,7 @@ const {
11
11
  const { requiresReasoningContentReplay } = require('./providerReasoning');
12
12
  const { classifyResponsesRoute } = require('./providerBridgeRoutes');
13
13
  const { providerError } = require('./providerProfile');
14
+ const { fetchProvider, readProviderText, readProviderJson } = require('./providerHttp');
14
15
  const { sanitizeProviderMessage } = require('./providerRedaction');
15
16
  const { logDebug } = require('./debugLog');
16
17
  const {
@@ -118,15 +119,19 @@ async function handleRequest({
118
119
  const startedAt = Date.now();
119
120
  const previousResponseId = String(requestBody.previous_response_id || '');
120
121
  const previous = history.get(previousResponseId);
121
- const fallbackAnchor = previous
122
+ const fallbackAllowed = !previousResponseId || previousResponseId === continuationState.responseId;
123
+ const fallbackAnchor = previous || !fallbackAllowed
122
124
  ? []
123
125
  : continuationState.anchorMessages;
126
+ const continuationAttempts = previous
127
+ ? Number(previous.continuationAttempts) || 0
128
+ : fallbackAllowed ? continuationState.attempts : 0;
124
129
  const translated = buildChatRequest({
125
130
  requestBody,
126
131
  launch,
127
132
  historyMessages: previous?.messages || fallbackAnchor
128
133
  });
129
- assertReasoningContinuationBudget(translated.messages, continuationState.attempts);
134
+ assertReasoningContinuationBudget(translated.messages, continuationAttempts);
130
135
  const idleTimeoutMs = resolveProviderIdleTimeoutMs(launch);
131
136
  const totalTimeoutMs = resolveProviderTotalTimeoutMs(launch, idleTimeoutMs);
132
137
  logDebug('provider.bridge.request', {
@@ -141,7 +146,7 @@ async function handleRequest({
141
146
  usedFallbackAnchor: fallbackAnchor.length > 0,
142
147
  inputItemCount: Array.isArray(requestBody.input) ? requestBody.input.length : requestBody.input ? 1 : 0,
143
148
  messageCount: translated.messages.length,
144
- continuationAttempts: continuationState.attempts,
149
+ continuationAttempts,
145
150
  idleTimeoutMs,
146
151
  totalTimeoutMs
147
152
  });
@@ -161,15 +166,15 @@ async function handleRequest({
161
166
  res.on('close', onClientClose);
162
167
  lifecycle.start();
163
168
  try {
164
- const upstream = await fetch(buildChatCompletionsUrl(launch.baseUrl, launch), {
169
+ const upstream = await fetchProvider(buildChatCompletionsUrl(launch.baseUrl, launch), {
165
170
  method: 'POST',
166
171
  headers: buildUpstreamHeaders(launch),
167
172
  body: JSON.stringify(translated.body),
168
173
  signal: controller.signal
169
- });
174
+ }, launch);
170
175
  lifecycle.touch();
171
176
  if (!upstream.ok) {
172
- await forwardUpstreamError(upstream, res, launch.apiKey);
177
+ await forwardUpstreamError(upstream, res, launch.apiKey, lifecycle.touch);
173
178
  return;
174
179
  }
175
180
  const context = {
@@ -193,7 +198,7 @@ async function handleRequest({
193
198
  : 0;
194
199
  if (anchored) {
195
200
  continuationState.anchorMessages = continuation;
196
- continuationState.attempts += 1;
201
+ continuationState.attempts = continuationAttempts + 1;
197
202
  continuationState.responseId = converted.response.id;
198
203
  } else {
199
204
  continuationState.anchorMessages = [];
@@ -217,7 +222,7 @@ async function handleRequest({
217
222
  rememberHistory(history, converted.response.id, [
218
223
  ...translated.messages,
219
224
  ...continuation
220
- ]);
225
+ ], { continuationAttempts: anchored ? continuationAttempts + 1 : 0 });
221
226
  };
222
227
  if (requestBody.stream !== false) {
223
228
  const contentType = String(upstream.headers.get('content-type') || '').toLowerCase();
@@ -231,11 +236,11 @@ async function handleRequest({
231
236
  recoverInterrupted: lifecycle.recoverInterrupted
232
237
  });
233
238
  } else {
234
- const converted = convertChatResponse(await upstream.json(), context);
239
+ const converted = convertChatResponse(await readProviderJson(upstream, lifecycle.touch), context);
235
240
  writeConvertedResponseAsSse(res, converted, context, remember);
236
241
  }
237
242
  } else {
238
- const converted = convertChatResponse(await upstream.json(), context);
243
+ const converted = convertChatResponse(await readProviderJson(upstream, lifecycle.touch), context);
239
244
  remember(converted);
240
245
  sendJson(res, 200, converted.response);
241
246
  }
@@ -376,7 +381,8 @@ function normalizeBridgeErrorCode(value) {
376
381
  'provider_agent_tools_incompatible',
377
382
  'provider_reasoning_continuation_exhausted',
378
383
  'provider_stream_tool_parse_failed',
379
- 'provider_protocol_incompatible'
384
+ 'provider_protocol_incompatible',
385
+ 'provider_upstream_error'
380
386
  ].includes(value) ? value : 'provider_bridge_failed';
381
387
  }
382
388
 
@@ -386,8 +392,8 @@ function bridgeErrorMessage(code) {
386
392
  : 'The local provider bridge failed.';
387
393
  }
388
394
 
389
- async function forwardUpstreamError(upstream, res, apiKey) {
390
- const text = (await upstream.text()).slice(0, MAX_ERROR_BYTES);
395
+ async function forwardUpstreamError(upstream, res, apiKey, onActivity) {
396
+ const text = (await readProviderText(upstream, onActivity)).slice(0, MAX_ERROR_BYTES);
391
397
  let message = `Provider returned HTTP ${upstream.status}.`;
392
398
  try {
393
399
  const parsed = JSON.parse(text);
@@ -396,9 +402,9 @@ async function forwardUpstreamError(upstream, res, apiKey) {
396
402
  sendJsonError(res, upstream.status, 'provider_upstream_error', sanitizeProviderMessage(message, [apiKey]));
397
403
  }
398
404
 
399
- function rememberHistory(history, responseId, messages) {
405
+ function rememberHistory(history, responseId, messages, metadata = {}) {
400
406
  history.delete(responseId);
401
- history.set(responseId, { messages });
407
+ history.set(responseId, { messages, ...metadata });
402
408
  while (history.size > MAX_HISTORY_ENTRIES) {
403
409
  history.delete(history.keys().next().value);
404
410
  }
@@ -0,0 +1,106 @@
1
+ 'use strict';
2
+
3
+ const path = require('node:path');
4
+ const { splitTomlStatements, readTomlStatementPath } = require('./tomlStatements');
5
+
6
+ // These fields are paths resolved against the defining configuration layer by
7
+ // Codex. Moving that layer into an execution scope must preserve its old anchor.
8
+ const ROOT_PATHS = new Set(['sqlite_home', 'log_dir', 'model_catalog_json', 'model_instructions_file', 'experimental_compact_prompt_file']);
9
+ const PROFILE_PATHS = new Set(['model_catalog_json', 'model_instructions_file', 'experimental_compact_prompt_file']);
10
+ const TLS_PATHS = new Set(['ca-certificate', 'client-certificate', 'client-private-key']);
11
+
12
+ function isConfigPath(keys) {
13
+ if (keys.length === 1 && ROOT_PATHS.has(keys[0])) return true;
14
+ if (keys.length === 3 && keys[0] === 'profiles' && PROFILE_PATHS.has(keys[2])) return true;
15
+ if (keys.length === 3 && keys[0] === 'agents' && keys[2] === 'config_file') return true;
16
+ if (keys.length === 3 && keys[0] === 'skills' && keys[1] === 'config' && keys[2] === 'path') return true;
17
+ if (keys.length === 2 && keys[0] === 'sandbox_workspace_write' && keys[1] === 'writable_roots') return true;
18
+ if (keys.length === 4 && keys[0] === 'model_providers' && keys[2] === 'auth' && keys[3] === 'cwd') return true;
19
+ return keys[0] === 'otel' && keys.includes('tls') && TLS_PATHS.has(keys.at(-1));
20
+ }
21
+
22
+ function rebaseCodexConfigPaths(content, originalDirectory) {
23
+ let section = [];
24
+ return splitTomlStatements(content).map(statement => {
25
+ const parsed = readTomlStatementPath(statement);
26
+ if (!parsed) return statement;
27
+ if (parsed.table) { section = parsed.keys; return statement; }
28
+ const edits = [];
29
+ visitValue(statement, parsed.valueStart, [...section, ...parsed.keys], edits, originalDirectory);
30
+ for (const edit of edits.reverse()) statement = statement.slice(0, edit.start) + edit.text + statement.slice(edit.end);
31
+ return statement;
32
+ }).join('');
33
+ }
34
+
35
+ function skipTrivia(text, position) {
36
+ while (position < text.length) {
37
+ if (/\s/.test(text[position])) { position++; continue; }
38
+ if (text[position] !== '#') break;
39
+ while (position < text.length && text[position] !== '\n') position++;
40
+ }
41
+ return position;
42
+ }
43
+
44
+ function visitValue(text, start, keys, edits, directory) {
45
+ start = skipTrivia(text, start);
46
+ if (text[start] === '"' || text[start] === "'") {
47
+ const value = readString(text, start);
48
+ if (isConfigPath(keys) && !path.isAbsolute(value.value) && !/^~(?:[/\\]|$)/.test(value.value) && !/^[a-z][a-z\d+.-]*:\/\//i.test(value.value)) {
49
+ edits.push({ start, end: value.end, text: JSON.stringify(path.resolve(directory, value.value)) });
50
+ }
51
+ return value.end;
52
+ }
53
+ if (text[start] === '[' || text[start] === '{') {
54
+ const table = text[start] === '{', end = table ? '}' : ']';
55
+ let cursor = start + 1;
56
+ while ((cursor = skipTrivia(text, cursor)) < text.length && text[cursor] !== end) {
57
+ let childKeys = keys;
58
+ if (table) {
59
+ const key = readTomlStatementPath(text.slice(cursor));
60
+ if (!key || key.table) throw new Error('Codex configuration contains an invalid inline TOML key.');
61
+ childKeys = [...keys, ...key.keys]; cursor += key.valueStart;
62
+ }
63
+ const next = visitValue(text, cursor, childKeys, edits, directory);
64
+ if (next <= cursor) break;
65
+ cursor = skipTrivia(text, next);
66
+ if (text[cursor] === ',') cursor++;
67
+ }
68
+ return cursor + 1;
69
+ }
70
+ let end = start;
71
+ while (end < text.length && ![',', ']', '}', '#', '\n'].includes(text[end])) end++;
72
+ return end;
73
+ }
74
+
75
+ function readString(text, start) {
76
+ const quote = text[start], triple = text.slice(start, start + 3) === quote.repeat(3);
77
+ let cursor = start + (triple ? 3 : 1), raw = '';
78
+ if (triple && text[cursor] === '\n') cursor++;
79
+ while (cursor < text.length) {
80
+ if (text[cursor] === quote && (!triple || text.slice(cursor, cursor + 3) === quote.repeat(3))) {
81
+ let count = triple ? 3 : 1;
82
+ if (triple) while (count < 5 && text[cursor + count] === quote) count++;
83
+ raw += triple ? quote.repeat(count - 3) : '';
84
+ return { value: raw, end: cursor + count };
85
+ }
86
+ const char = text[cursor++];
87
+ if (quote !== '"' || char !== '\\') { raw += char; continue; }
88
+ const escaped = text[cursor++];
89
+ if (triple && /\s/.test(escaped)) {
90
+ while (/\s/.test(text[cursor] || '') && cursor < text.length) cursor++;
91
+ continue;
92
+ }
93
+ const simple = { b: '\b', t: '\t', n: '\n', f: '\f', r: '\r', '"': '"', '\\': '\\' };
94
+ if (Object.prototype.hasOwnProperty.call(simple, escaped)) { raw += simple[escaped]; continue; }
95
+ const count = escaped === 'u' ? 4 : escaped === 'U' ? 8 : 0;
96
+ const hex = text.slice(cursor, cursor + count);
97
+ const point = Number.parseInt(hex, 16);
98
+ if (!count || !/^[\da-f]+$/i.test(hex) || hex.length !== count || point > 0x10ffff || (point >= 0xd800 && point <= 0xdfff)) {
99
+ throw new Error('Codex configuration contains an invalid TOML string escape.');
100
+ }
101
+ raw += String.fromCodePoint(point); cursor += count;
102
+ }
103
+ throw new Error('Codex configuration contains an unterminated TOML string.');
104
+ }
105
+
106
+ module.exports = { rebaseCodexConfigPaths };