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
@@ -2,7 +2,12 @@
2
2
 
3
3
  const { buildCodexRuntimeEvent } = require('./codexRuntimeIdentity');
4
4
 
5
+ const { runOwnedNativeHelper } = require('./nativeHelperLifecycle');
6
+ const { stopCodexAppServer, throwIfAborted } = require('./codexSessionTiming');
5
7
  const { spawn } = require('node:child_process');
8
+ const { normalizeSafeProjectPath } = require('../../extension/src/shared/projectFiles');
9
+ const { createHash } = require('node:crypto');
10
+ const NativeRequestIdentity = require('../../extension/src/shared/nativeRequestIdentity');
6
11
  const { buildOperationSummary, splitDeletePlan } = require('../../extension/src/shared/summary');
7
12
  const {
8
13
  MIN_COMPATIBLE_EXTENSION_VERSION,
@@ -10,6 +15,7 @@ const {
10
15
  SUPPORTED_NATIVE_PROTOCOL
11
16
  } = require('../../extension/src/shared/compatibility');
12
17
  const { runCodexSession } = require('./codexSessionRunner');
18
+ const WritingStyleRuntime = require('./writingStyleRuntime');
13
19
  const { resolveCodexModels } = require('./codexModels');
14
20
  const {
15
21
  handleProviderRequest,
@@ -23,7 +29,8 @@ const { forkCodexThread } = require('./codexThreadFork');
23
29
  const { readAssetChunk, releaseAsset } = require('./nativeAssetTransfer');
24
30
  const { logDebug, truncateText } = require('./debugLog');
25
31
  const { HOST_NAME } = require('./manifest');
26
- const { getNativeRuntimePlatform, summarizeNativeEnvironment } = require('./nativeEnvironment');
32
+ const { getNativeRuntimePlatform, summarizeNativeEnvironment, refreshCodexRuntimeEnv } = require('./nativeEnvironment');
33
+ const { formatModelUpgradeError } = require('./codexModelRecovery');
27
34
  const {
28
35
  NATIVE_REQUEST_QUOTAS,
29
36
  firstQuotaViolation,
@@ -33,6 +40,8 @@ const {
33
40
  } = require('./nativeTransportEnvelope');
34
41
  const { version: PACKAGE_VERSION } = require('../../package.json');
35
42
 
43
+ const processStopBarrier = require('./processStopBarrier');
44
+ const runLifecycle = require('./nativeRunLifecycle');
36
45
  const activeProjectLocks = new Map();
37
46
  const activeRunControllers = new Map();
38
47
  const activeRunEntries = new Map();
@@ -41,7 +50,7 @@ const activeRunEntries = new Map();
41
50
  // Overleaf tab was reloaded — the requestId lived in content-side JS state
42
51
  // and is gone, but the native-host-side controller is still running).
43
52
  const activeRunByProject = new Map();
44
- const CODEX_RUN_PASSTHROUGH_ERROR_CODES = new Set(['thread_resume_failed', 'codex_no_usable_result']);
53
+ const CODEX_RUN_PASSTHROUGH_ERROR_CODES = new Set(['thread_resume_failed', 'codex_no_usable_result', 'codex_process_stop_unconfirmed', 'selected_context_unresolved', 'codex_local_skill_unavailable']);
45
54
 
46
55
  async function handleRequest(request, env = process.env, emit = () => {}) {
47
56
  if (!request || typeof request !== 'object') {
@@ -53,19 +62,29 @@ async function handleRequest(request, env = process.env, emit = () => {}) {
53
62
  return quotaErrorResponse(request.id, quotaError);
54
63
  }
55
64
 
65
+ if (['bridge.ping', 'codex.run', 'codex.models', 'codex.thread.fork'].includes(request.method)) {
66
+ env = refreshCodexRuntimeEnv(env);
67
+ }
68
+
56
69
  if (request.method === 'bridge.ping') {
57
70
  return okResponse(request.id, {
58
71
  host: HOST_NAME,
59
72
  platform: getNativeRuntimePlatform({ env }),
60
73
  protocolVersion: 2,
61
74
  supportedProtocol: { ...SUPPORTED_NATIVE_PROTOCOL },
62
- capabilities: Object.fromEntries(REQUIRED_CAPABILITIES.map(capability => [capability, true])),
75
+ capabilities: { ...Object.fromEntries(REQUIRED_CAPABILITIES.map(capability => [capability, true])), literalProjectPaths: true },
63
76
  minExtensionVersion: MIN_COMPATIBLE_EXTENSION_VERSION,
64
77
  version: PACKAGE_VERSION,
65
78
  environment: summarizeNativeEnvironment(env)
66
79
  });
67
80
  }
68
81
 
82
+ if (['codex.run', 'mirror.sync', 'mirror.patchFiles', 'mirror.confirmWriteback'].includes(request.method)
83
+ && processStopBarrier.isBlocked(resolveProjectKey(request.params || {}), env.CODEX_OVERLEAF_MIRROR_ROOT)) {
84
+ return errorResponse(request.id, 'codex_process_stop_unconfirmed',
85
+ 'The previous Codex process has not exited. This project remains isolated until exit is confirmed.');
86
+ }
87
+
69
88
  if (request.method === 'mirror.sync') {
70
89
  return handleMirrorSync(request, env);
71
90
  }
@@ -115,7 +134,7 @@ async function handleRequest(request, env = process.env, emit = () => {}) {
115
134
  }
116
135
 
117
136
  if (request.method === 'codex.cancel') {
118
- return handleCodexCancel(request);
137
+ return handleCodexCancel(request, env);
119
138
  }
120
139
 
121
140
  if (request.method === 'codex.history.clearPlugin') {
@@ -142,6 +161,18 @@ async function handleRequest(request, env = process.env, emit = () => {}) {
142
161
  return okResponse(request.id, releaseAsset(request.params || {}));
143
162
  }
144
163
 
164
+ if (request.method === 'writing-style.get' || request.method === 'writing-style.set') {
165
+ try {
166
+ const params = request.params || {};
167
+ const result = request.method === 'writing-style.get'
168
+ ? await WritingStyleRuntime.get(params, env, id => activeRunEntries.has(id))
169
+ : await WritingStyleRuntime.set(params, env);
170
+ return okResponse(request.id, result);
171
+ } catch (error) {
172
+ return errorResponse(request.id, error.code || 'writing_style_failed', error.message);
173
+ }
174
+ }
175
+
145
176
  if (request.method === 'skills.list') {
146
177
  return handleSkillsList(request, env);
147
178
  }
@@ -179,7 +210,22 @@ function quotaErrorResponse(id, violation) {
179
210
  }
180
211
 
181
212
  async function handleCodexRun(request, env, emit) {
213
+ const identity = NativeRequestIdentity.validate(request.id);
214
+ if (!identity.ok) return errorResponse(request.id, identity.error.code, identity.error.message, identity.error.details);
182
215
  let params = request.params || {};
216
+ if (params.writingStyleBuild != null) {
217
+ if (typeof params.writingStyleBuild !== 'object' || Array.isArray(params.writingStyleBuild)) {
218
+ return errorResponse(request.id, 'writing_style_invalid_build', 'Writing style build settings must be an object.');
219
+ }
220
+ params = {
221
+ ...params,
222
+ mode: 'ask',
223
+ useExistingMirror: false,
224
+ fileOverlays: [],
225
+ writingStyle: null,
226
+ writingStyleBuild: { ...params.writingStyleBuild, requestId: String(request.id) }
227
+ };
228
+ }
183
229
  if (isCodexMissing(env)) {
184
230
  return errorResponse(
185
231
  request.id,
@@ -198,17 +244,16 @@ async function handleCodexRun(request, env, emit) {
198
244
  return errorResponse(request.id, 'project_locked', `Project ${projectKey} is currently in use by codex.run`);
199
245
  }
200
246
  const abortController = new AbortController();
247
+ const lifetime = runLifecycle.register({ controller: abortController, projectKey, rootDir: env.CODEX_OVERLEAF_MIRROR_ROOT });
201
248
  const activeEntry = {
202
- id: request.id || '',
249
+ id: request.id,
203
250
  projectKey,
204
251
  controller: abortController,
205
252
  control: null
206
253
  };
207
- if (request.id) {
208
- activeRunControllers.set(request.id, abortController);
209
- activeRunEntries.set(request.id, activeEntry);
210
- activeRunByProject.set(projectKey, activeEntry);
211
- }
254
+ activeRunControllers.set(request.id, abortController);
255
+ activeRunEntries.set(request.id, activeEntry);
256
+ activeRunByProject.set(projectKey, activeEntry);
212
257
  let providerResolution;
213
258
  try {
214
259
  try {
@@ -226,6 +271,7 @@ async function handleCodexRun(request, env, emit) {
226
271
  return providerErrorResponse(request.id, error);
227
272
  }
228
273
 
274
+ abortController.signal.throwIfAborted();
229
275
  if (params.useExistingMirror) {
230
276
  const { getMirrorStatus, applyFileOverlays } = require('./mirrorWorkspace');
231
277
  const rootDir = env.CODEX_OVERLEAF_MIRROR_ROOT;
@@ -250,10 +296,12 @@ async function handleCodexRun(request, env, emit) {
250
296
  );
251
297
  }
252
298
 
253
- if (Array.isArray(params.fileOverlays) && params.fileOverlays.length) {
299
+ // OT overlays prove that the current page agrees with the trusted OT
300
+ // baseline; they must not rewrite it or supply a replacement hash.
301
+ if (!isOtWarmMirrorReuseRequest(params) && Array.isArray(params.fileOverlays) && params.fileOverlays.length) {
254
302
  await applyFileOverlays({ projectId: projectKey, overlays: params.fileOverlays, rootDir });
255
303
  }
256
- } else if (!isSnapshotlessSkillInstallerRun(params) && !hasRunnableProjectSnapshotEvidence(params)) {
304
+ } else if (!params.writingStyleBuild && !isSnapshotlessSkillInstallerRun(params) && !hasRunnableProjectSnapshotEvidence(params)) {
257
305
  return errorResponse(
258
306
  request.id,
259
307
  'codex_run_requires_snapshot_evidence',
@@ -267,6 +315,8 @@ async function handleCodexRun(request, env, emit) {
267
315
  emit,
268
316
  rootDir: env.CODEX_OVERLEAF_MIRROR_ROOT,
269
317
  providerLaunch: providerResolution.providerLaunch,
318
+ onStopUnconfirmed: error => processStopBarrier.record(projectKey, env.CODEX_OVERLEAF_MIRROR_ROOT, error),
319
+ onProcessStarted: lifetime.trackProcess,
270
320
  onControlReady: control => {
271
321
  activeEntry.control = control;
272
322
  },
@@ -285,6 +335,13 @@ async function handleCodexRun(request, env, emit) {
285
335
  });
286
336
  return errorResponse(request.id, 'codex_cancelled', 'Codex run was cancelled by the user');
287
337
  }
338
+ const modelUpgradeError = formatModelUpgradeError(error, env, {
339
+ model: params.model, locale: params.locale
340
+ });
341
+ if (modelUpgradeError) {
342
+ logDebug('codex.run.model_version_rejected', modelUpgradeError.details);
343
+ return errorResponse(request.id, modelUpgradeError.code, modelUpgradeError.message, modelUpgradeError.details);
344
+ }
288
345
  if (shouldPassthroughCodexRunError(error)) {
289
346
  logDebug('codex.run.passthrough_failed', {
290
347
  code: error.code,
@@ -300,16 +357,17 @@ async function handleCodexRun(request, env, emit) {
300
357
  });
301
358
  return errorResponse(request.id, 'codex_run_failed', truncateText(error.message, 12000));
302
359
  } finally {
303
- if (request.id && activeRunControllers.get(request.id) === abortController) {
360
+ if (activeRunControllers.get(request.id) === abortController) {
304
361
  activeRunControllers.delete(request.id);
305
362
  }
306
- if (request.id && activeRunEntries.get(request.id) === activeEntry) {
363
+ if (activeRunEntries.get(request.id) === activeEntry) {
307
364
  activeRunEntries.delete(request.id);
308
365
  }
309
366
  if (activeRunByProject.get(projectKey)?.controller === abortController) {
310
367
  activeRunByProject.delete(projectKey);
311
368
  }
312
369
  releaseProjectLock(projectKey, lockToken);
370
+ lifetime.complete();
313
371
  }
314
372
  }
315
373
 
@@ -354,8 +412,8 @@ async function handleCodexSteer(request) {
354
412
  }
355
413
 
356
414
  function findActiveRunEntry(params = {}) {
357
- const targetId = String(params.requestId || params.id || '');
358
- if (targetId && activeRunEntries.has(targetId)) {
415
+ const targetId = params.requestId ?? params.id;
416
+ if (activeRunEntries.has(targetId)) {
359
417
  return activeRunEntries.get(targetId);
360
418
  }
361
419
  const projectKey = String(params.projectKey || '');
@@ -372,13 +430,13 @@ function findActiveRunEntry(params = {}) {
372
430
  // the user otherwise has no way to recover short of restarting Chrome.
373
431
  // Only fires when `force: true` is explicitly set so accidental calls
374
432
  // can't punch through a real live run.
375
- function handleCodexCancel(request) {
433
+ function handleCodexCancel(request, env = process.env) {
376
434
  const params = request.params || {};
377
- const targetId = params.requestId || params.id;
435
+ const targetId = params.requestId ?? params.id;
378
436
  const projectKey = typeof params.projectKey === 'string' ? params.projectKey : '';
379
437
  const force = params.force === true;
380
438
 
381
- if (targetId && activeRunControllers.has(targetId)) {
439
+ if (activeRunControllers.has(targetId)) {
382
440
  activeRunControllers.get(targetId).abort(createCancellationError());
383
441
  return okResponse(request.id, {
384
442
  cancelled: true,
@@ -393,9 +451,13 @@ function handleCodexCancel(request) {
393
451
  return okResponse(request.id, {
394
452
  cancelled: true,
395
453
  projectKey,
396
- requestId: entry.id || ''
454
+ requestId: entry.id
397
455
  });
398
456
  }
457
+ if (processStopBarrier.isBlocked(projectKey, env.CODEX_OVERLEAF_MIRROR_ROOT)) {
458
+ return errorResponse(request.id, 'codex_process_stop_unconfirmed',
459
+ 'Cancellation was requested, but process exit is not yet confirmed.');
460
+ }
399
461
  if (force && activeProjectLocks.has(projectKey)) {
400
462
  activeProjectLocks.delete(projectKey);
401
463
  activeRunByProject.delete(projectKey);
@@ -423,8 +485,10 @@ function handleCodexHistoryClear(request, env) {
423
485
  }
424
486
  }
425
487
 
426
- function handleSkillsList(request, env) {
488
+ async function handleSkillsList(request, env) {
427
489
  try {
490
+ if (request.params?.scope === 'codex-local') return okResponse(request.id,
491
+ await require('./codexLocalSkills').listCodexLocalSkills({ env }));
428
492
  const { CODEX_OVERLEAF_SKILL_SCOPE, listCodexOverleafSkills, listProjectSkills } = require('./localSkills');
429
493
  if (request.params?.scope === CODEX_OVERLEAF_SKILL_SCOPE) {
430
494
  // Install/restore official skills before listing so newly shipped ones
@@ -443,9 +507,9 @@ function handleSkillsList(request, env) {
443
507
  return errorResponse(request.id, 'skills_list_failed', error.message);
444
508
  }
445
509
  }
446
-
447
510
  function handleSkillsInstall(request, env) {
448
511
  try {
512
+ if (request.params?.scope === 'codex-local') throw new Error('Local Codex skills are managed by Codex.');
449
513
  const { CODEX_OVERLEAF_SKILL_SCOPE, installCodexOverleafSkill, installProjectSkill } = require('./localSkills');
450
514
  if (request.params?.scope === CODEX_OVERLEAF_SKILL_SCOPE) {
451
515
  return okResponse(request.id, installCodexOverleafSkill({
@@ -464,9 +528,9 @@ function handleSkillsInstall(request, env) {
464
528
  return errorResponse(request.id, 'skills_install_failed', error.message);
465
529
  }
466
530
  }
467
-
468
531
  function handleSkillsRemove(request, env) {
469
532
  try {
533
+ if (request.params?.scope === 'codex-local') throw new Error('Local Codex skills are managed by Codex.');
470
534
  const { CODEX_OVERLEAF_SKILL_SCOPE, removeCodexOverleafSkill, removeProjectSkill } = require('./localSkills');
471
535
  if (request.params?.scope === CODEX_OVERLEAF_SKILL_SCOPE) {
472
536
  return okResponse(request.id, removeCodexOverleafSkill({
@@ -494,13 +558,13 @@ function hasRunnableProjectSnapshotEvidence(params = {}) {
494
558
  if (params.restrictToFocusFiles !== true) {
495
559
  return false;
496
560
  }
497
- const normalizedFocusFiles = normalizeSnapshotEvidencePaths(params.focusFiles);
561
+ const normalizedFocusFiles = normalizeSnapshotEvidencePaths(params.focusFiles, params.focusFilesAreLiteral === true);
498
562
  if (!normalizedFocusFiles.length || !Array.isArray(params.project?.files)) {
499
563
  return false;
500
564
  }
501
565
  const evidenceFiles = new Map();
502
566
  for (const file of params.project.files) {
503
- const filePath = normalizeSnapshotEvidencePath(file?.path);
567
+ const filePath = normalizeSafeProjectPath(file?.path);
504
568
  if (!filePath || !isUsableSnapshotEvidenceContent(file?.content)) {
505
569
  continue;
506
570
  }
@@ -511,19 +575,14 @@ function hasRunnableProjectSnapshotEvidence(params = {}) {
511
575
 
512
576
  function isSnapshotlessSkillInstallerRun(params = {}) {
513
577
  return params.skipMirrorSync === true
514
- && String(params.skillInvocation?.id || '').trim() === 'skill-installer';
578
+ && String(params.skillInvocation?.id || '').trim() === 'skill-installer'
579
+ && (!params.skillInvocation?.scope || params.skillInvocation.scope === 'builtin');
515
580
  }
516
581
 
517
582
  function validateOtFocusedWarmMirrorReuse(params = {}, status = {}) {
518
583
  if (!isOtWarmMirrorReuseRequest(params)) {
519
584
  return { ok: false };
520
585
  }
521
- if (Array.isArray(params.fileOverlays) && params.fileOverlays.length) {
522
- return {
523
- ok: false,
524
- message: 'OT warm mirror reuse does not accept file overlays'
525
- };
526
- }
527
586
  if (status?.exists !== true) {
528
587
  return {
529
588
  ok: false,
@@ -536,7 +595,7 @@ function validateOtFocusedWarmMirrorReuse(params = {}, status = {}) {
536
595
  message: 'OT warm mirror reuse requires restrictToFocusFiles=true'
537
596
  };
538
597
  }
539
- const normalizedFocusFiles = normalizeSnapshotEvidencePaths(params.focusFiles);
598
+ const normalizedFocusFiles = normalizeSnapshotEvidencePaths(params.focusFiles, params.focusFilesAreLiteral === true);
540
599
  if (!normalizedFocusFiles.length) {
541
600
  return {
542
601
  ok: false,
@@ -544,14 +603,14 @@ function validateOtFocusedWarmMirrorReuse(params = {}, status = {}) {
544
603
  };
545
604
  }
546
605
 
547
- const freshFiles = new Set();
606
+ const freshFiles = new Map();
548
607
  for (const file of Array.isArray(status.otFreshFiles) ? status.otFreshFiles : []) {
549
608
  if (file?.state !== 'fresh') {
550
609
  continue;
551
610
  }
552
- const filePath = normalizeSnapshotEvidencePath(file.path);
611
+ const filePath = normalizeSafeProjectPath(file.path);
553
612
  if (filePath) {
554
- freshFiles.add(filePath);
613
+ freshFiles.set(filePath, file);
555
614
  }
556
615
  }
557
616
  const missingFiles = normalizedFocusFiles.filter(filePath => !freshFiles.has(filePath));
@@ -562,6 +621,22 @@ function validateOtFocusedWarmMirrorReuse(params = {}, status = {}) {
562
621
  };
563
622
  }
564
623
 
624
+ if (Array.isArray(params.fileOverlays) && params.fileOverlays.length) {
625
+ const overlays = new Set();
626
+ for (const overlay of params.fileOverlays) {
627
+ const filePath = normalizeSafeProjectPath(overlay?.path);
628
+ if (!normalizedFocusFiles.includes(filePath) || overlays.has(filePath)
629
+ || typeof overlay?.content !== 'string' || !/^[a-f0-9]{64}$/i.test(freshFiles.get(filePath)?.sha256 || '')
630
+ || createHash('sha256').update(overlay.content).digest('hex') !== freshFiles.get(filePath).sha256.toLowerCase()) {
631
+ return { ok: false, message: 'OT warm mirror overlay does not match the current focused OT baseline' };
632
+ }
633
+ overlays.add(filePath);
634
+ }
635
+ if (normalizedFocusFiles.some(filePath => !overlays.has(filePath))) {
636
+ return { ok: false, message: 'OT warm mirror overlays do not cover all focused files' };
637
+ }
638
+ }
639
+
565
640
  return { ok: true };
566
641
  }
567
642
 
@@ -577,11 +652,11 @@ function isUsableSnapshotEvidenceContent(content) {
577
652
  return Boolean(text) && !/^(loading|loading\.{3}|loading…)$/i.test(text);
578
653
  }
579
654
 
580
- function normalizeSnapshotEvidencePaths(value) {
655
+ function normalizeSnapshotEvidencePaths(value, literal = false) {
581
656
  const seen = new Set();
582
657
  const paths = [];
583
658
  for (const item of Array.isArray(value) ? value : []) {
584
- const filePath = normalizeSnapshotEvidencePath(item);
659
+ const filePath = literal ? normalizeSafeProjectPath(item) : normalizeSnapshotEvidencePath(item);
585
660
  if (!filePath || seen.has(filePath)) {
586
661
  continue;
587
662
  }
@@ -606,6 +681,7 @@ function createCancellationError() {
606
681
  }
607
682
 
608
683
  function isCancellationError(error = {}) {
684
+ if (['codex_turn_failed', 'codex_turn_status_invalid'].includes(error.code)) return false;
609
685
  return error.code === 'codex_cancelled'
610
686
  || error.name === 'AbortError'
611
687
  || /cancelled by the user|was cancelled/i.test(error.message || '');
@@ -703,6 +779,7 @@ async function handleMirrorConfirmWriteback(request, env) {
703
779
  const result = await confirmWritebackFiles({
704
780
  projectId,
705
781
  paths: params.paths,
782
+ expectedFiles: params.expectedFiles,
706
783
  rootDir
707
784
  });
708
785
  return okResponse(request.id, result);
@@ -1077,10 +1154,12 @@ function parseAgentArgsJson(value) {
1077
1154
  }
1078
1155
 
1079
1156
  function runExternalAgent(agentSpec, params, emit = () => {}, options = {}) {
1080
- return new Promise((resolve, reject) => {
1157
+ return runOwnedNativeHelper(signal => new Promise((resolve, reject) => {
1158
+ throwIfAborted(signal);
1081
1159
  const child = spawn(agentSpec.file, agentSpec.args || [], {
1082
1160
  env: options.env || process.env,
1083
1161
  shell: false,
1162
+ detached: process.platform !== 'win32',
1084
1163
  stdio: ['pipe', 'pipe', 'pipe']
1085
1164
  });
1086
1165
  const timeoutMs = parseOptionalPositiveInteger(options.timeoutMs);
@@ -1090,6 +1169,8 @@ function runExternalAgent(agentSpec, params, emit = () => {}, options = {}) {
1090
1169
  let stderrRemainder = '';
1091
1170
  let outputBytes = 0;
1092
1171
  let settled = false;
1172
+ const onAbort = () => fail(signal.reason);
1173
+ signal.addEventListener('abort', onAbort, { once: true });
1093
1174
 
1094
1175
  const timeout = timeoutMs
1095
1176
  ? setTimeout(() => {
@@ -1114,10 +1195,8 @@ function runExternalAgent(agentSpec, params, emit = () => {}, options = {}) {
1114
1195
  if (timeout) {
1115
1196
  clearTimeout(timeout);
1116
1197
  }
1117
- if (child.exitCode === null && !child.killed) {
1118
- child.kill('SIGTERM');
1119
- }
1120
- reject(error);
1198
+ signal.removeEventListener('abort', onAbort);
1199
+ stopCodexAppServer(child, { processGroup: process.platform !== 'win32', reason: error }).then(() => reject(error), reject);
1121
1200
  }
1122
1201
 
1123
1202
  function succeed(result) {
@@ -1128,7 +1207,8 @@ function runExternalAgent(agentSpec, params, emit = () => {}, options = {}) {
1128
1207
  if (timeout) {
1129
1208
  clearTimeout(timeout);
1130
1209
  }
1131
- resolve(result);
1210
+ signal.removeEventListener('abort', onAbort);
1211
+ stopCodexAppServer(child, { processGroup: process.platform !== 'win32' }).then(() => resolve(result), reject);
1132
1212
  }
1133
1213
 
1134
1214
  child.stdout.setEncoding('utf8');
@@ -1150,6 +1230,7 @@ function runExternalAgent(agentSpec, params, emit = () => {}, options = {}) {
1150
1230
  emitTaskEvent(emit, event.type || 'agent.progress', event.title || event.type || 'Agent progress', event.detail || {}, event.status || 'running');
1151
1231
  }
1152
1232
  });
1233
+ child.stdin.on('error', fail);
1153
1234
  child.on('error', fail);
1154
1235
  child.on('close', code => {
1155
1236
  if (settled) {
@@ -1176,7 +1257,7 @@ function runExternalAgent(agentSpec, params, emit = () => {}, options = {}) {
1176
1257
  });
1177
1258
 
1178
1259
  child.stdin.end(JSON.stringify(params));
1179
- });
1260
+ }));
1180
1261
  }
1181
1262
 
1182
1263
  function parsePositiveInteger(value, fallback) {
@@ -1249,27 +1330,19 @@ function errorResponse(id, code, message, details = {}) {
1249
1330
  };
1250
1331
  }
1251
1332
 
1252
- function getActiveNativeWorkState() {
1333
+ function getActiveNativeWorkState(env = process.env) {
1253
1334
  return {
1254
1335
  projectLocks: activeProjectLocks.size,
1336
+ processStopBarriers: processStopBarrier.getBlockedProjectCount(env.CODEX_OVERLEAF_MIRROR_ROOT, { env }),
1255
1337
  runControllers: activeRunControllers.size,
1256
1338
  activeTurnControls: Array.from(activeRunEntries.values()).filter(entry => entry.control).length
1257
1339
  };
1258
1340
  }
1259
1341
 
1260
- function abortAllActiveOperations(reason = 'Native messaging transport disconnected.') {
1261
- const error = new Error(String(reason || 'Native messaging transport disconnected.'));
1262
- error.code = 'native_transport_closed';
1263
- for (const controller of activeRunControllers.values()) {
1264
- if (controller && !controller.signal?.aborted) {
1265
- controller.abort(error);
1266
- }
1267
- }
1268
- }
1269
-
1270
1342
  module.exports = {
1271
1343
  NATIVE_REQUEST_QUOTAS,
1272
- abortAllActiveOperations,
1344
+ abortAllActiveOperations: runLifecycle.abortAllActiveOperations,
1345
+ quarantineActiveOperations: runLifecycle.quarantineActiveOperations,
1273
1346
  buildDefaultTaskResult,
1274
1347
  getActiveNativeWorkState,
1275
1348
  handleRequest,
@@ -0,0 +1,140 @@
1
+ 'use strict';
2
+
3
+ // Preserve TOML source text while finding complete logical statements. This is
4
+ // a lexical boundary scanner, not a TOML value/schema parser. Filters must never
5
+ // treat an apparent key or table header inside a multiline value as syntax.
6
+ function splitTomlStatements(content) {
7
+ const text = String(content || '').replace(/\r\n/g, '\n');
8
+ const statements = [];
9
+ const containers = [];
10
+ let start = 0;
11
+ let quote = '';
12
+ let multiline = false;
13
+ let comment = false;
14
+
15
+ for (let index = 0; index < text.length; index++) {
16
+ const char = text[index];
17
+ if (comment) {
18
+ if (char !== '\n') continue;
19
+ comment = false;
20
+ }
21
+ if (quote) {
22
+ if (quote === '"' && char === '\\') {
23
+ // Basic strings escape the next character, including the first quote
24
+ // of a potential delimiter. Literal strings have no escape syntax.
25
+ index++;
26
+ } else if (char === quote) {
27
+ if (!multiline) {
28
+ quote = '';
29
+ } else if (text.slice(index, index + 3) === quote.repeat(3)) {
30
+ // A legal closing delimiter can have one or two literal quotes just
31
+ // before it: consume all four/five instead of opening another string.
32
+ let count = 3;
33
+ while (count < 5 && text[index + count] === quote) count++;
34
+ index += count - 1;
35
+ quote = '';
36
+ }
37
+ }
38
+ continue;
39
+ }
40
+ if (char === '#') {
41
+ comment = true;
42
+ } else if (char === '"' || char === "'") {
43
+ quote = char;
44
+ multiline = text.slice(index, index + 3) === char.repeat(3);
45
+ if (multiline) index += 2;
46
+ } else if (char === '[' || char === '{') {
47
+ containers.push(char);
48
+ } else if (char === ']' || char === '}') {
49
+ const opener = char === ']' ? '[' : '{';
50
+ if (containers.pop() !== opener) throw incompleteValue();
51
+ } else if (char === '\n' && containers.length === 0) {
52
+ statements.push(text.slice(start, index + 1));
53
+ start = index + 1;
54
+ }
55
+ }
56
+
57
+ // Do not silently remove the remaining config if a selected value is broken.
58
+ // The caller prepares the full string before writing the destination file.
59
+ if (quote || containers.length) throw incompleteValue();
60
+ if (start < text.length) statements.push(text.slice(start));
61
+ return statements;
62
+ }
63
+
64
+ function incompleteValue() {
65
+ return new Error('Codex configuration contains an unterminated or mismatched TOML value.');
66
+ }
67
+
68
+ // Parse only a statement's key path, leaving its value and original formatting
69
+ // untouched. A quoted dot belongs to a key; an unquoted dot separates keys.
70
+ function readTomlStatementPath(statement) {
71
+ const text = String(statement || '');
72
+ let index = 0;
73
+ const whitespace = () => { while (text[index] === ' ' || text[index] === '\t') index++; };
74
+ whitespace();
75
+ if (!text[index] || text[index] === '#' || text[index] === '\n') return null;
76
+ const table = text[index] === '[';
77
+ let brackets = 0;
78
+ if (table) {
79
+ brackets = text[index + 1] === '[' ? 2 : 1;
80
+ index += brackets;
81
+ }
82
+ const keys = [];
83
+ while (true) {
84
+ whitespace();
85
+ let key = '';
86
+ const quote = text[index];
87
+ if (quote === '"' || quote === "'") {
88
+ index++;
89
+ while (index < text.length && text[index] !== quote) {
90
+ const char = text[index++];
91
+ if (char === '\n' || char === '\r') throw invalidKey();
92
+ if (quote !== '"' || char !== '\\') { key += char; continue; }
93
+ const escape = text[index++];
94
+ const simple = { b: '\b', t: '\t', n: '\n', f: '\f', r: '\r', '"': '"', '\\': '\\' };
95
+ if (Object.prototype.hasOwnProperty.call(simple, escape)) { key += simple[escape]; continue; }
96
+ const count = escape === 'u' ? 4 : escape === 'U' ? 8 : 0;
97
+ const hex = text.slice(index, index + count);
98
+ if (!count || hex.length !== count || !/^[0-9a-f]+$/i.test(hex)) throw invalidKey();
99
+ const point = Number.parseInt(hex, 16);
100
+ if (point > 0x10ffff || (point >= 0xd800 && point <= 0xdfff)) throw invalidKey();
101
+ key += String.fromCodePoint(point);
102
+ index += count;
103
+ }
104
+ if (text[index++] !== quote) throw invalidKey();
105
+ } else {
106
+ const match = text.slice(index).match(/^[A-Za-z0-9_-]+/);
107
+ if (!match) return null;
108
+ key = match[0]; index += key.length;
109
+ }
110
+ keys.push(key);
111
+ whitespace();
112
+ if (text[index] !== '.') break;
113
+ index++;
114
+ }
115
+ if (table) {
116
+ if (text.slice(index, index + brackets) !== ']'.repeat(brackets)) return null;
117
+ index += brackets; whitespace();
118
+ if (text[index] && text[index] !== '#' && text[index] !== '\n') return null;
119
+ } else if (text[index] !== '=') return null;
120
+ return { table, keys, ...(table ? {} : { valueStart: index + 1 }) };
121
+ }
122
+
123
+ function filterTomlRootKeys(content, excludedKeys) {
124
+ const excluded = new Set(excludedKeys);
125
+ const output = [];
126
+ let section = [];
127
+ for (const statement of splitTomlStatements(content)) {
128
+ const parsed = readTomlStatementPath(statement);
129
+ if (parsed?.table) section = parsed.keys;
130
+ const root = section.length ? section[0] : parsed?.keys[0];
131
+ if (!excluded.has(root)) output.push(statement);
132
+ }
133
+ return output.join('');
134
+ }
135
+
136
+ function invalidKey() {
137
+ return new Error('Codex configuration contains an invalid TOML key.');
138
+ }
139
+
140
+ module.exports = { splitTomlStatements, filterTomlRootKeys, readTomlStatementPath };