lazycodex-ai 5.1.62 → 5.1.64

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 (276) hide show
  1. package/dist/cli/index.js +1598 -284
  2. package/dist/cli/service-auth/closed-device-login.fixture.d.ts +1 -0
  3. package/dist/cli/service-auth/credential-lock.d.ts +8 -2
  4. package/dist/cli/service-auth/keychain-helper/access.d.ts +27 -0
  5. package/dist/cli/service-auth/keychain-helper/approval-cache.d.ts +51 -0
  6. package/dist/cli/service-auth/keychain-helper/client.d.ts +68 -0
  7. package/dist/cli/service-auth/keychain-helper/creator-handoff.d.ts +31 -0
  8. package/dist/cli/service-auth/keychain-helper/darwin-backend.d.ts +75 -0
  9. package/dist/cli/service-auth/keychain-helper/darwin-read.d.ts +46 -0
  10. package/dist/cli/service-auth/keychain-helper/darwin-store.d.ts +28 -0
  11. package/dist/cli/service-auth/keychain-helper/fake-keychain.test-support.d.ts +85 -0
  12. package/dist/cli/service-auth/keychain-helper/location.d.ts +28 -0
  13. package/dist/cli/service-auth/keychain-helper/migration.d.ts +20 -0
  14. package/dist/cli/service-auth/keychain-helper/owner-marker.d.ts +7 -0
  15. package/dist/cli/service-auth/keychain-helper/pin.d.ts +20 -0
  16. package/dist/cli/service-auth/keychain-helper/process-copy.test-support.d.ts +3 -0
  17. package/dist/cli/service-auth/keychain-helper/process-state.d.ts +19 -0
  18. package/dist/cli/service-auth/keychain-helper/prompt-lock.d.ts +14 -0
  19. package/dist/cli/service-auth/keychain-helper/recovery.d.ts +34 -0
  20. package/dist/cli/service-auth/keychain-helper/runtime-capabilities.d.ts +13 -0
  21. package/dist/cli/service-auth/keychain-helper/secrets-gate.d.ts +4 -0
  22. package/dist/cli/service-auth/keychain-helper/signature.d.ts +17 -0
  23. package/dist/cli/service-auth/keychain-helper/store-binding.d.ts +46 -0
  24. package/dist/cli/service-auth/keystore.d.ts +18 -3
  25. package/dist/cli/service-auth/session.d.ts +2 -2
  26. package/dist/cli-node/index.js +1598 -284
  27. package/package.json +1 -1
  28. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  29. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  30. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  31. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  32. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  33. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  34. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  35. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  36. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  37. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +2 -2
  38. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  39. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  40. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  41. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  42. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  43. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  44. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  45. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  46. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +2 -0
  47. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  48. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  49. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +1 -1
  50. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-unclear.md +2 -2
  51. package/packages/omo-codex/plugin/components/ultrawork/src/directive-content.ts +1 -1
  52. package/packages/omo-codex/plugin/components/ulw-execute-continuation/directive.md +1 -1
  53. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +1 -1
  54. package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
  55. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +2 -0
  56. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +5 -5
  57. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  58. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +1 -1
  59. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/define-goal.md +1 -1
  60. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +10 -10
  61. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  62. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  63. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  64. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  65. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  66. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  67. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  68. package/packages/omo-codex/plugin/hooks/post-tool-use-recording-spawn-admission.json +1 -1
  69. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  70. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  71. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  72. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  73. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  74. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  75. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  76. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
  77. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  78. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  79. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  80. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  81. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  82. package/packages/omo-codex/plugin/package-lock.json +12 -12
  83. package/packages/omo-codex/plugin/package.json +1 -1
  84. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +6 -3
  85. package/packages/omo-codex/plugin/skills/ast-grep/AGENTS.md +2 -2
  86. package/packages/omo-codex/plugin/skills/ast-grep/README.md +4 -4
  87. package/packages/omo-codex/plugin/skills/ast-grep/SKILL.md +10 -8
  88. package/packages/omo-codex/plugin/skills/ast-grep/references/cli.md +4 -3
  89. package/packages/omo-codex/plugin/skills/ast-grep/references/patterns.md +5 -5
  90. package/packages/omo-codex/plugin/skills/ast-grep/references/pitfalls.md +3 -3
  91. package/packages/omo-codex/plugin/skills/ast-grep/references/recipes.md +6 -4
  92. package/packages/omo-codex/plugin/skills/ast-grep/references/yaml-rules.md +3 -3
  93. package/packages/omo-codex/plugin/skills/ast-grep/scripts/ast_grep_helper.py +3 -3
  94. package/packages/omo-codex/plugin/skills/browser/SKILL.md +2 -3
  95. package/packages/omo-codex/plugin/skills/browser/runtime/omowright/manifest.json +1 -1
  96. package/packages/omo-codex/plugin/skills/coding-agent-sessions/AGENTS.md +1 -1
  97. package/packages/omo-codex/plugin/skills/coding-agent-sessions/SKILL.md +2 -1
  98. package/packages/omo-codex/plugin/skills/data-scientist/SKILL.md +8 -6
  99. package/packages/omo-codex/plugin/skills/data-scientist/references/placement.md +9 -5
  100. package/packages/omo-codex/plugin/skills/data-scientist/references/uv-setup.md +3 -3
  101. package/packages/omo-codex/plugin/skills/data-scientist/references/visualization.md +19 -4
  102. package/packages/omo-codex/plugin/skills/debugging/SKILL.md +5 -5
  103. package/packages/omo-codex/plugin/skills/debugging/references/methodology/02-investigate.md +2 -2
  104. package/packages/omo-codex/plugin/skills/debugging/references/methodology/06-fix.md +2 -0
  105. package/packages/omo-codex/plugin/skills/debugging/references/methodology/09-cleanup.md +2 -2
  106. package/packages/omo-codex/plugin/skills/debugging/references/methodology/partial-runtime-evidence.md +1 -1
  107. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/bundled-js-binary.md +1 -1
  108. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/native-binary.md +1 -1
  109. package/packages/omo-codex/plugin/skills/debugging/references/tools/browser-qa.md +1 -2
  110. package/packages/omo-codex/plugin/skills/frontend/SKILL.md +2 -2
  111. package/packages/omo-codex/plugin/skills/frontend/references/design/design-system-architecture.md +1 -1
  112. package/packages/omo-codex/plugin/skills/frontend/references/design/print-paged-media.md +1 -1
  113. package/packages/omo-codex/plugin/skills/frontend/references/perfection/README.md +0 -1
  114. package/packages/omo-codex/plugin/skills/frontend/references/perfection/react-perf-tooling.md +27 -8
  115. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/lighthouse-audit.py +0 -1
  116. package/packages/omo-codex/plugin/skills/git-master/SKILL.md +12 -2
  117. package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +1 -1
  118. package/packages/omo-codex/plugin/skills/lsp-setup/SKILL.md +24 -15
  119. package/packages/omo-codex/plugin/skills/lsp-setup/references/bash/README.md +3 -3
  120. package/packages/omo-codex/plugin/skills/lsp-setup/references/c-cpp/README.md +2 -2
  121. package/packages/omo-codex/plugin/skills/lsp-setup/references/csharp/README.md +2 -2
  122. package/packages/omo-codex/plugin/skills/lsp-setup/references/dart/README.md +2 -2
  123. package/packages/omo-codex/plugin/skills/lsp-setup/references/elixir/README.md +2 -2
  124. package/packages/omo-codex/plugin/skills/lsp-setup/references/go/README.md +2 -2
  125. package/packages/omo-codex/plugin/skills/lsp-setup/references/haskell/README.md +2 -2
  126. package/packages/omo-codex/plugin/skills/lsp-setup/references/java/README.md +3 -3
  127. package/packages/omo-codex/plugin/skills/lsp-setup/references/julia/README.md +3 -3
  128. package/packages/omo-codex/plugin/skills/lsp-setup/references/kotlin/README.md +4 -4
  129. package/packages/omo-codex/plugin/skills/lsp-setup/references/lua/README.md +2 -2
  130. package/packages/omo-codex/plugin/skills/lsp-setup/references/php/README.md +3 -3
  131. package/packages/omo-codex/plugin/skills/lsp-setup/references/python/README.md +13 -12
  132. package/packages/omo-codex/plugin/skills/lsp-setup/references/ruby/README.md +2 -2
  133. package/packages/omo-codex/plugin/skills/lsp-setup/references/rust/README.md +2 -2
  134. package/packages/omo-codex/plugin/skills/lsp-setup/references/swift/README.md +4 -4
  135. package/packages/omo-codex/plugin/skills/lsp-setup/references/terraform/README.md +2 -2
  136. package/packages/omo-codex/plugin/skills/lsp-setup/references/typescript/README.md +3 -3
  137. package/packages/omo-codex/plugin/skills/lsp-setup/references/yaml/README.md +2 -2
  138. package/packages/omo-codex/plugin/skills/lsp-setup/references/zig/README.md +2 -2
  139. package/packages/omo-codex/plugin/skills/lsp-setup/scripts/detect-lsp.ts +1 -1
  140. package/packages/omo-codex/plugin/skills/lsp-setup/scripts/lsp-server-table.ts +3 -2
  141. package/packages/omo-codex/plugin/skills/programming/SKILL.md +5 -5
  142. package/packages/omo-codex/plugin/skills/programming/references/code-smells.md +2 -2
  143. package/packages/omo-codex/plugin/skills/programming/references/go/README.md +3 -3
  144. package/packages/omo-codex/plugin/skills/programming/references/python/README.md +8 -8
  145. package/packages/omo-codex/plugin/skills/programming/references/python/data-processing.md +9 -9
  146. package/packages/omo-codex/plugin/skills/programming/references/rust-ub/README.md +3 -3
  147. package/packages/omo-codex/plugin/skills/programming/references/typescript/README.md +5 -5
  148. package/packages/omo-codex/plugin/skills/programming/scripts/typescript/new-project.ts +1 -1
  149. package/packages/omo-codex/plugin/skills/refactor/SKILL.md +35 -35
  150. package/packages/omo-codex/plugin/skills/remove-ai-slops/SKILL.md +6 -6
  151. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +2 -2
  152. package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +10 -7
  153. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/AGENTS.md +4 -4
  154. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/agent-reach/README.md +2 -2
  155. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/agent-reach/career.md +1 -1
  156. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/agent-reach/social.md +1 -1
  157. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/agent-reach/web.md +4 -4
  158. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/chrome-stealth.md +2 -1
  159. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/README.md +16 -17
  160. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/fallback.md +10 -6
  161. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/jina.md +12 -12
  162. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/naver.md +3 -3
  163. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/playwright.md +1 -1
  164. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/rss.md +1 -1
  165. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/tls-impersonate.md +12 -7
  166. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +2 -0
  167. package/packages/omo-codex/plugin/skills/ulw-execute/SKILL.md +9 -6
  168. package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +1 -1
  169. package/packages/omo-codex/plugin/skills/ulw-loop/references/define-goal.md +1 -1
  170. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +10 -10
  171. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +1 -1
  172. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-unclear.md +2 -2
  173. package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +2 -2
  174. package/packages/omo-codex/plugin/skills/ulw-research/references/deliverable-phase.md +5 -5
  175. package/packages/omo-codex/plugin/skills/ulw-research/references/report-visualization.md +2 -2
  176. package/packages/omo-codex/plugin/skills/ulw-research/references/research-collection.md +2 -2
  177. package/packages/omo-codex/plugin/skills/ulw-research/references/unit-rules.md +2 -2
  178. package/packages/omo-codex/plugin/skills/visual-qa/AGENTS.md +1 -1
  179. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +5 -5
  180. package/packages/omo-codex/plugin/skills/visual-qa/references/browser-setup.md +4 -2
  181. package/packages/omo-codex/plugin/test/sync-skills-codex-compatibility.test.mjs +2 -0
  182. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +7 -3
  183. package/packages/omo-codex/scripts/install-dist/install-local.mjs +2 -2
  184. package/packages/prompts-core/prompts/ultrawork/codex.md +2 -0
  185. package/packages/shared-skills/skills/ast-grep/AGENTS.md +2 -2
  186. package/packages/shared-skills/skills/ast-grep/README.md +4 -4
  187. package/packages/shared-skills/skills/ast-grep/SKILL.md +10 -8
  188. package/packages/shared-skills/skills/ast-grep/references/cli.md +4 -3
  189. package/packages/shared-skills/skills/ast-grep/references/patterns.md +5 -5
  190. package/packages/shared-skills/skills/ast-grep/references/pitfalls.md +3 -3
  191. package/packages/shared-skills/skills/ast-grep/references/recipes.md +6 -4
  192. package/packages/shared-skills/skills/ast-grep/references/yaml-rules.md +3 -3
  193. package/packages/shared-skills/skills/ast-grep/scripts/ast_grep_helper.py +3 -3
  194. package/packages/shared-skills/skills/browser/SKILL.md +2 -3
  195. package/packages/shared-skills/skills/browser/runtime/omowright/manifest.json +1 -1
  196. package/packages/shared-skills/skills/coding-agent-sessions/AGENTS.md +1 -1
  197. package/packages/shared-skills/skills/coding-agent-sessions/SKILL.md +2 -1
  198. package/packages/shared-skills/skills/data-scientist/SKILL.md +8 -6
  199. package/packages/shared-skills/skills/data-scientist/references/placement.md +9 -5
  200. package/packages/shared-skills/skills/data-scientist/references/uv-setup.md +3 -3
  201. package/packages/shared-skills/skills/data-scientist/references/visualization.md +19 -4
  202. package/packages/shared-skills/skills/debugging/SKILL.md +5 -5
  203. package/packages/shared-skills/skills/debugging/references/methodology/02-investigate.md +2 -2
  204. package/packages/shared-skills/skills/debugging/references/methodology/06-fix.md +2 -0
  205. package/packages/shared-skills/skills/debugging/references/methodology/09-cleanup.md +2 -2
  206. package/packages/shared-skills/skills/debugging/references/methodology/partial-runtime-evidence.md +1 -1
  207. package/packages/shared-skills/skills/debugging/references/runtimes/bundled-js-binary.md +1 -1
  208. package/packages/shared-skills/skills/debugging/references/runtimes/native-binary.md +1 -1
  209. package/packages/shared-skills/skills/debugging/references/tools/browser-qa.md +1 -2
  210. package/packages/shared-skills/skills/frontend/SKILL.md +2 -2
  211. package/packages/shared-skills/skills/frontend/references/design/design-system-architecture.md +1 -1
  212. package/packages/shared-skills/skills/frontend/references/design/print-paged-media.md +1 -1
  213. package/packages/shared-skills/skills/frontend/references/perfection/README.md +0 -1
  214. package/packages/shared-skills/skills/frontend/references/perfection/react-perf-tooling.md +27 -8
  215. package/packages/shared-skills/skills/frontend/scripts/perfection/lighthouse-audit.py +0 -1
  216. package/packages/shared-skills/skills/git-master/SKILL.md +12 -2
  217. package/packages/shared-skills/skills/init-deep/SKILL.md +1 -1
  218. package/packages/shared-skills/skills/lsp-setup/SKILL.md +24 -15
  219. package/packages/shared-skills/skills/lsp-setup/references/bash/README.md +3 -3
  220. package/packages/shared-skills/skills/lsp-setup/references/c-cpp/README.md +2 -2
  221. package/packages/shared-skills/skills/lsp-setup/references/csharp/README.md +2 -2
  222. package/packages/shared-skills/skills/lsp-setup/references/dart/README.md +2 -2
  223. package/packages/shared-skills/skills/lsp-setup/references/elixir/README.md +2 -2
  224. package/packages/shared-skills/skills/lsp-setup/references/go/README.md +2 -2
  225. package/packages/shared-skills/skills/lsp-setup/references/haskell/README.md +2 -2
  226. package/packages/shared-skills/skills/lsp-setup/references/java/README.md +3 -3
  227. package/packages/shared-skills/skills/lsp-setup/references/julia/README.md +3 -3
  228. package/packages/shared-skills/skills/lsp-setup/references/kotlin/README.md +4 -4
  229. package/packages/shared-skills/skills/lsp-setup/references/lua/README.md +2 -2
  230. package/packages/shared-skills/skills/lsp-setup/references/php/README.md +3 -3
  231. package/packages/shared-skills/skills/lsp-setup/references/python/README.md +13 -12
  232. package/packages/shared-skills/skills/lsp-setup/references/ruby/README.md +2 -2
  233. package/packages/shared-skills/skills/lsp-setup/references/rust/README.md +2 -2
  234. package/packages/shared-skills/skills/lsp-setup/references/swift/README.md +4 -4
  235. package/packages/shared-skills/skills/lsp-setup/references/terraform/README.md +2 -2
  236. package/packages/shared-skills/skills/lsp-setup/references/typescript/README.md +3 -3
  237. package/packages/shared-skills/skills/lsp-setup/references/yaml/README.md +2 -2
  238. package/packages/shared-skills/skills/lsp-setup/references/zig/README.md +2 -2
  239. package/packages/shared-skills/skills/lsp-setup/scripts/detect-lsp.ts +1 -1
  240. package/packages/shared-skills/skills/lsp-setup/scripts/lsp-server-table.ts +3 -2
  241. package/packages/shared-skills/skills/programming/SKILL.md +5 -5
  242. package/packages/shared-skills/skills/programming/references/code-smells.md +2 -2
  243. package/packages/shared-skills/skills/programming/references/go/README.md +3 -3
  244. package/packages/shared-skills/skills/programming/references/python/README.md +8 -8
  245. package/packages/shared-skills/skills/programming/references/python/data-processing.md +9 -9
  246. package/packages/shared-skills/skills/programming/references/rust-ub/README.md +3 -3
  247. package/packages/shared-skills/skills/programming/references/typescript/README.md +5 -5
  248. package/packages/shared-skills/skills/programming/scripts/typescript/new-project.ts +1 -1
  249. package/packages/shared-skills/skills/refactor/SKILL.md +35 -35
  250. package/packages/shared-skills/skills/remove-ai-slops/SKILL.md +6 -6
  251. package/packages/shared-skills/skills/review-work/SKILL.md +2 -2
  252. package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +10 -7
  253. package/packages/shared-skills/skills/ultimate-browsing/engine/AGENTS.md +4 -4
  254. package/packages/shared-skills/skills/ultimate-browsing/references/agent-reach/README.md +2 -2
  255. package/packages/shared-skills/skills/ultimate-browsing/references/agent-reach/career.md +1 -1
  256. package/packages/shared-skills/skills/ultimate-browsing/references/agent-reach/social.md +1 -1
  257. package/packages/shared-skills/skills/ultimate-browsing/references/agent-reach/web.md +4 -4
  258. package/packages/shared-skills/skills/ultimate-browsing/references/chrome-stealth.md +2 -1
  259. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/README.md +16 -17
  260. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/fallback.md +10 -6
  261. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/jina.md +12 -12
  262. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/naver.md +3 -3
  263. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/playwright.md +1 -1
  264. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/rss.md +1 -1
  265. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/tls-impersonate.md +12 -7
  266. package/packages/shared-skills/skills/ulw-execute/SKILL.md +9 -6
  267. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +1 -1
  268. package/packages/shared-skills/skills/ulw-plan/references/intent-unclear.md +2 -2
  269. package/packages/shared-skills/skills/ulw-research/SKILL.md +3 -3
  270. package/packages/shared-skills/skills/ulw-research/references/deliverable-phase.md +5 -5
  271. package/packages/shared-skills/skills/ulw-research/references/report-visualization.md +2 -2
  272. package/packages/shared-skills/skills/ulw-research/references/research-collection.md +2 -2
  273. package/packages/shared-skills/skills/ulw-research/references/unit-rules.md +2 -2
  274. package/packages/shared-skills/skills/visual-qa/AGENTS.md +1 -1
  275. package/packages/shared-skills/skills/visual-qa/SKILL.md +5 -5
  276. package/packages/shared-skills/skills/visual-qa/references/browser-setup.md +4 -2
package/dist/cli/index.js CHANGED
@@ -2132,7 +2132,7 @@ var package_default;
2132
2132
  var init_package = __esm(() => {
2133
2133
  package_default = {
2134
2134
  name: "oh-my-opencode",
2135
- version: "5.1.62",
2135
+ version: "5.1.64",
2136
2136
  description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
2137
2137
  main: "./dist/index.js",
2138
2138
  types: "dist/index.d.ts",
@@ -2384,18 +2384,18 @@ var init_package = __esm(() => {
2384
2384
  typescript: "^7.0.2"
2385
2385
  },
2386
2386
  optionalDependencies: {
2387
- "oh-my-opencode-darwin-arm64": "5.1.62",
2388
- "oh-my-opencode-darwin-x64": "5.1.62",
2389
- "oh-my-opencode-darwin-x64-baseline": "5.1.62",
2390
- "oh-my-opencode-linux-arm64": "5.1.62",
2391
- "oh-my-opencode-linux-arm64-musl": "5.1.62",
2392
- "oh-my-opencode-linux-x64": "5.1.62",
2393
- "oh-my-opencode-linux-x64-baseline": "5.1.62",
2394
- "oh-my-opencode-linux-x64-musl": "5.1.62",
2395
- "oh-my-opencode-linux-x64-musl-baseline": "5.1.62",
2396
- "oh-my-opencode-windows-arm64": "5.1.62",
2397
- "oh-my-opencode-windows-x64": "5.1.62",
2398
- "oh-my-opencode-windows-x64-baseline": "5.1.62"
2387
+ "oh-my-opencode-darwin-arm64": "5.1.64",
2388
+ "oh-my-opencode-darwin-x64": "5.1.64",
2389
+ "oh-my-opencode-darwin-x64-baseline": "5.1.64",
2390
+ "oh-my-opencode-linux-arm64": "5.1.64",
2391
+ "oh-my-opencode-linux-arm64-musl": "5.1.64",
2392
+ "oh-my-opencode-linux-x64": "5.1.64",
2393
+ "oh-my-opencode-linux-x64-baseline": "5.1.64",
2394
+ "oh-my-opencode-linux-x64-musl": "5.1.64",
2395
+ "oh-my-opencode-linux-x64-musl-baseline": "5.1.64",
2396
+ "oh-my-opencode-windows-arm64": "5.1.64",
2397
+ "oh-my-opencode-windows-x64": "5.1.64",
2398
+ "oh-my-opencode-windows-x64-baseline": "5.1.64"
2399
2399
  },
2400
2400
  overrides: {
2401
2401
  hono: "^4.13.8",
@@ -7339,7 +7339,34 @@ var init_which = __esm(() => {
7339
7339
  });
7340
7340
 
7341
7341
  // packages/utils/src/runtime/file.ts
7342
- var init_file = () => {};
7342
+ import { access, readFile, unlink, writeFile } from "fs/promises";
7343
+ function createNodeFile(path) {
7344
+ return {
7345
+ text() {
7346
+ return readFile(path, "utf8");
7347
+ },
7348
+ async arrayBuffer() {
7349
+ const buffer = await readFile(path);
7350
+ return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
7351
+ },
7352
+ exists() {
7353
+ return access(path).then(() => true, () => false);
7354
+ },
7355
+ delete() {
7356
+ return unlink(path);
7357
+ }
7358
+ };
7359
+ }
7360
+ function bunFile(path) {
7361
+ const bun = runtime3.Bun;
7362
+ if (bun)
7363
+ return bun.file(path);
7364
+ return createNodeFile(path);
7365
+ }
7366
+ var runtime3;
7367
+ var init_file = __esm(() => {
7368
+ runtime3 = globalThis;
7369
+ });
7343
7370
 
7344
7371
  // packages/utils/src/runtime/git-bash.ts
7345
7372
  import { execFileSync } from "child_process";
@@ -12283,7 +12310,9 @@ var init_zip_extractor = __esm(() => {
12283
12310
  });
12284
12311
 
12285
12312
  // packages/omo-opencode/src/shared/bun-file-shim.ts
12286
- var init_bun_file_shim = () => {};
12313
+ var init_bun_file_shim = __esm(() => {
12314
+ init_runtime();
12315
+ });
12287
12316
 
12288
12317
  // packages/omo-opencode/src/shared/binary-downloader.ts
12289
12318
  import { chmodSync, existsSync as existsSync9, mkdirSync as mkdirSync4, unlinkSync as unlinkSync3 } from "fs";
@@ -92710,7 +92739,7 @@ var package_default2;
92710
92739
  var init_package2 = __esm(() => {
92711
92740
  package_default2 = {
92712
92741
  name: "@oh-my-opencode/omo-codex",
92713
- version: "5.1.62",
92742
+ version: "5.1.64",
92714
92743
  type: "module",
92715
92744
  private: true,
92716
92745
  description: "Codex harness adapter for oh-my-openagent. Vendored Codex plugin namespace (omo) + TypeScript installer + telemetry.",
@@ -93326,7 +93355,7 @@ var init_check_for_update = __esm(() => {
93326
93355
  });
93327
93356
 
93328
93357
  // packages/omo-opencode/src/hooks/auto-update-checker/checker/sync-package-json.ts
93329
- import * as crypto from "crypto";
93358
+ import * as crypto2 from "crypto";
93330
93359
  import * as fs8 from "fs";
93331
93360
  import * as path11 from "path";
93332
93361
  function safeUnlink(filePath) {
@@ -93350,7 +93379,7 @@ function getPackageNameFromIntent(pluginInfo) {
93350
93379
  return ACCEPTED_PACKAGE_NAMES2.find((packageName) => pluginInfo.entry === packageName || pluginInfo.entry.startsWith(`${packageName}@`)) ?? PACKAGE_NAME3;
93351
93380
  }
93352
93381
  function writeCachePackageJson(cachePackageJsonPath, pkgJson) {
93353
- const tmpPath = `${cachePackageJsonPath}.${crypto.randomUUID()}`;
93382
+ const tmpPath = `${cachePackageJsonPath}.${crypto2.randomUUID()}`;
93354
93383
  try {
93355
93384
  fs8.mkdirSync(path11.dirname(cachePackageJsonPath), { recursive: true });
93356
93385
  fs8.writeFileSync(tmpPath, JSON.stringify(pkgJson, null, 2));
@@ -94271,7 +94300,7 @@ import { existsSync as existsSync27 } from "fs";
94271
94300
  import { homedir as homedir7 } from "os";
94272
94301
 
94273
94302
  // packages/omo-codex/src/install/codex-cache-bins.ts
94274
- import { chmod, lstat as lstat4, mkdir, readFile as readFile3, readdir as readdir2, readlink as readlink3, rm as rm3, stat as stat2, symlink, writeFile } from "fs/promises";
94303
+ import { chmod, lstat as lstat4, mkdir, readFile as readFile4, readdir as readdir2, readlink as readlink3, rm as rm3, stat as stat2, symlink, writeFile as writeFile2 } from "fs/promises";
94275
94304
  import { basename as basename4, isAbsolute as isAbsolute2, join as join26, relative, resolve as resolve6, sep } from "path";
94276
94305
 
94277
94306
  // packages/omo-codex/src/install/codex-cache-command-shim.ts
@@ -94315,7 +94344,7 @@ function windowsCommandShim(targetPath) {
94315
94344
  }
94316
94345
 
94317
94346
  // packages/omo-codex/src/install/codex-cache-dangling-bins.ts
94318
- import { lstat as lstat2, readFile, readdir, readlink, rm, stat } from "fs/promises";
94347
+ import { lstat as lstat2, readFile as readFile2, readdir, readlink, rm, stat } from "fs/promises";
94319
94348
  import { dirname as dirname10, isAbsolute, join as join23, resolve as resolve5 } from "path";
94320
94349
 
94321
94350
  // packages/omo-codex/src/install/codex-cache-fs.ts
@@ -94377,7 +94406,7 @@ async function removeDanglingGeneratedCommandShim(linkPath) {
94377
94406
  const linkStat = await lstat2(linkPath);
94378
94407
  if (!linkStat.isFile())
94379
94408
  return;
94380
- const content = await readFile(linkPath, "utf8");
94409
+ const content = await readFile2(linkPath, "utf8");
94381
94410
  if (!content.includes(COMMAND_SHIM_MARKER))
94382
94411
  return;
94383
94412
  const target = extractCommandShimTarget(content);
@@ -94425,7 +94454,7 @@ function hasOmoCodexPluginPrefix(parts, endExclusive) {
94425
94454
  }
94426
94455
 
94427
94456
  // packages/omo-codex/src/install/codex-cache-legacy-bins.ts
94428
- import { lstat as lstat3, readFile as readFile2, readlink as readlink2, rm as rm2 } from "fs/promises";
94457
+ import { lstat as lstat3, readFile as readFile3, readlink as readlink2, rm as rm2 } from "fs/promises";
94429
94458
  import { join as join24 } from "path";
94430
94459
  var LEGACY_CODEX_COMPONENT_BINS = [
94431
94460
  { name: "omo", component: "ulw-loop" },
@@ -94460,7 +94489,7 @@ async function removeLegacyCodexComponentBin(linkPath, component, platform) {
94460
94489
  }
94461
94490
  if (!stat.isFile())
94462
94491
  return;
94463
- const content = await readFile2(linkPath, "utf8");
94492
+ const content = await readFile3(linkPath, "utf8");
94464
94493
  if (content.includes(COMMAND_SHIM_MARKER))
94465
94494
  await rm2(linkPath, { force: true });
94466
94495
  } catch (error) {
@@ -94697,7 +94726,7 @@ async function collectPackageBins(directory, root, links) {
94697
94726
  }
94698
94727
  }
94699
94728
  async function appendPackageBinLinks(packageJsonPath, packageRoot, root, links) {
94700
- const packageJson = JSON.parse(await readFile3(packageJsonPath, "utf8"));
94729
+ const packageJson = JSON.parse(await readFile4(packageJsonPath, "utf8"));
94701
94730
  if (!isPlainRecord4(packageJson))
94702
94731
  return;
94703
94732
  const packageName = packageJson.name;
@@ -94749,13 +94778,13 @@ async function replaceSymlink(linkPath, targetPath) {
94749
94778
  async function replaceCommandShim(linkPath, targetPath) {
94750
94779
  if (await existingNonShim(linkPath))
94751
94780
  throw new Error(`${linkPath} already exists and is not a command shim`);
94752
- await writeFile(linkPath, windowsCommandShim(targetPath));
94781
+ await writeFile2(linkPath, windowsCommandShim(targetPath));
94753
94782
  }
94754
94783
  async function replaceRuntimeWrapper(linkPath, content) {
94755
94784
  if (await existingNonRuntimeWrapper(linkPath))
94756
94785
  throw new Error(`${linkPath} already exists and is not a generated OMO runtime wrapper`);
94757
94786
  await rm3(linkPath, { force: true });
94758
- await writeFile(linkPath, content);
94787
+ await writeFile2(linkPath, content);
94759
94788
  }
94760
94789
  async function removeGeneratedRuntimeWrapper(path) {
94761
94790
  try {
@@ -94773,7 +94802,7 @@ async function removeGeneratedRuntimeWrapper(path) {
94773
94802
  }
94774
94803
  async function readGeneratedWrapperContent(path) {
94775
94804
  try {
94776
- return await readFile3(path, "utf8");
94805
+ return await readFile4(path, "utf8");
94777
94806
  } catch (error) {
94778
94807
  if (isNodeErrorWithCode(error) && (error.code === "ENOENT" || error.code === "EISDIR"))
94779
94808
  return "";
@@ -94787,7 +94816,7 @@ async function existingNonRuntimeWrapper(path) {
94787
94816
  return false;
94788
94817
  if (!stat.isFile())
94789
94818
  return true;
94790
- const content = await readFile3(path, "utf8");
94819
+ const content = await readFile4(path, "utf8");
94791
94820
  return !content.includes(RUNTIME_WRAPPER_MARKER);
94792
94821
  } catch (error) {
94793
94822
  if (isNodeErrorWithCode(error) && error.code === "ENOENT")
@@ -94800,7 +94829,7 @@ async function existingNonShim(path) {
94800
94829
  const stat = await lstat4(path);
94801
94830
  if (!stat.isFile())
94802
94831
  return true;
94803
- const content = await readFile3(path, "utf8");
94832
+ const content = await readFile4(path, "utf8");
94804
94833
  if (content.includes(COMMAND_SHIM_MARKER))
94805
94834
  return false;
94806
94835
  throw new Error(`${path} already exists and is not a generated command shim`);
@@ -94824,11 +94853,11 @@ async function existingNonSymlink(path) {
94824
94853
  }
94825
94854
  }
94826
94855
  // packages/omo-codex/src/install/codex-cache-install.ts
94827
- import { cp as cp3, mkdir as mkdir3, readFile as readFile8, readdir as readdir5, rename as rename2, rm as rm5 } from "fs/promises";
94856
+ import { cp as cp3, mkdir as mkdir3, readFile as readFile9, readdir as readdir5, rename as rename2, rm as rm5 } from "fs/promises";
94828
94857
  import { basename as basename5, dirname as dirname13, join as join33, sep as sep6 } from "path";
94829
94858
 
94830
94859
  // packages/omo-codex/src/install/codex-cache-bundled-mcps.ts
94831
- import { cp, mkdir as mkdir2, readFile as readFile4, stat as stat3 } from "fs/promises";
94860
+ import { cp, mkdir as mkdir2, readFile as readFile5, stat as stat3 } from "fs/promises";
94832
94861
  import { dirname as dirname11, join as join27, resolve as resolve7 } from "path";
94833
94862
  var BUNDLED_MCP_RUNTIMES = [
94834
94863
  {
@@ -94870,7 +94899,7 @@ async function copyBundledMcpRuntimeDist(pluginRoot, sourceRoot, runtime) {
94870
94899
  async function readSourceMcpArgs(path) {
94871
94900
  let parsed;
94872
94901
  try {
94873
- parsed = JSON.parse(await readFile4(path, "utf8"));
94902
+ parsed = JSON.parse(await readFile5(path, "utf8"));
94874
94903
  } catch (error) {
94875
94904
  if (error instanceof Error)
94876
94905
  return new Set;
@@ -94901,7 +94930,7 @@ async function isDirectory(path) {
94901
94930
 
94902
94931
  // packages/omo-codex/src/install/codex-cache-local-dependencies.ts
94903
94932
  import { realpathSync as realpathSync7 } from "fs";
94904
- import { readFile as readFile5, readdir as readdir3, writeFile as writeFile2 } from "fs/promises";
94933
+ import { readFile as readFile6, readdir as readdir3, writeFile as writeFile3 } from "fs/promises";
94905
94934
  import { dirname as dirname12, isAbsolute as isAbsolute4, join as join29, relative as relative3, resolve as resolve9, sep as sep2 } from "path";
94906
94935
 
94907
94936
  // packages/omo-codex/src/install/codex-cache-paths.ts
@@ -94967,7 +94996,7 @@ async function rewriteCachedPackageLocalFileDependencies(pluginRoot, sourceRoot)
94967
94996
  const packageLock = await readPackageLock(pluginRoot);
94968
94997
  let rewroteAnyPackageJson = false;
94969
94998
  for (const packageJsonPath of packageJsonPaths) {
94970
- const raw = await readFile5(packageJsonPath, "utf8");
94999
+ const raw = await readFile6(packageJsonPath, "utf8");
94971
95000
  const parsed = JSON.parse(raw);
94972
95001
  if (!isPlainRecord4(parsed))
94973
95002
  continue;
@@ -95002,20 +95031,20 @@ async function rewriteCachedPackageLocalFileDependencies(pluginRoot, sourceRoot)
95002
95031
  }
95003
95032
  }
95004
95033
  if (changed) {
95005
- await writeFile2(packageJsonPath, `${JSON.stringify(parsed, null, "\t")}
95034
+ await writeFile3(packageJsonPath, `${JSON.stringify(parsed, null, "\t")}
95006
95035
  `);
95007
95036
  rewroteAnyPackageJson = true;
95008
95037
  }
95009
95038
  }
95010
95039
  if (packageLock.changed)
95011
- await writeFile2(packageLock.path, `${JSON.stringify(packageLock.value, null, "\t")}
95040
+ await writeFile3(packageLock.path, `${JSON.stringify(packageLock.value, null, "\t")}
95012
95041
  `);
95013
95042
  return rewroteAnyPackageJson;
95014
95043
  }
95015
95044
  async function readPackageLock(pluginRoot) {
95016
95045
  const path = join29(pluginRoot, "package-lock.json");
95017
95046
  try {
95018
- const parsed = JSON.parse(await readFile5(path, "utf8"));
95047
+ const parsed = JSON.parse(await readFile6(path, "utf8"));
95019
95048
  return { path, value: isPlainRecord4(parsed) ? parsed : null, changed: false };
95020
95049
  } catch (error) {
95021
95050
  if (error instanceof Error && "code" in error && error.code === "ENOENT") {
@@ -95089,14 +95118,14 @@ async function collectPackageJsonPaths(directory, root, paths) {
95089
95118
  }
95090
95119
 
95091
95120
  // packages/omo-codex/src/install/codex-cache-mcp-manifest.ts
95092
- import { readFile as readFile6, writeFile as writeFile3 } from "fs/promises";
95121
+ import { readFile as readFile7, writeFile as writeFile4 } from "fs/promises";
95093
95122
  import { join as join30, sep as sep3 } from "path";
95094
95123
  var CONTEXT7_API_KEY_ENV = "CONTEXT7_API_KEY";
95095
95124
  async function rewriteCachedMcpManifest(pluginRoot, sourceRoot = pluginRoot) {
95096
95125
  const manifestPath = join30(pluginRoot, ".mcp.json");
95097
95126
  if (!await fileExistsStrict(manifestPath))
95098
95127
  return;
95099
- const raw = await readFile6(manifestPath, "utf8");
95128
+ const raw = await readFile7(manifestPath, "utf8");
95100
95129
  const parsed = JSON.parse(raw);
95101
95130
  if (!isPlainRecord4(parsed) || !isPlainRecord4(parsed.mcpServers))
95102
95131
  return;
@@ -95130,7 +95159,7 @@ async function rewriteCachedMcpManifest(pluginRoot, sourceRoot = pluginRoot) {
95130
95159
  }
95131
95160
  }
95132
95161
  if (changed)
95133
- await writeFile3(manifestPath, `${JSON.stringify(parsed, null, "\t")}
95162
+ await writeFile4(manifestPath, `${JSON.stringify(parsed, null, "\t")}
95134
95163
  `);
95135
95164
  }
95136
95165
  function sanitizeContext7Auth(server) {
@@ -95189,7 +95218,7 @@ async function rewriteCachedManifestRoot(pluginRoot, fromRoot, toRoot) {
95189
95218
  const manifestPath = join30(pluginRoot, ".mcp.json");
95190
95219
  if (!await fileExistsStrict(manifestPath))
95191
95220
  return;
95192
- const raw = await readFile6(manifestPath, "utf8");
95221
+ const raw = await readFile7(manifestPath, "utf8");
95193
95222
  const parsed = JSON.parse(raw);
95194
95223
  if (!isPlainRecord4(parsed) || !isPlainRecord4(parsed.mcpServers))
95195
95224
  return;
@@ -95216,7 +95245,7 @@ async function rewriteCachedManifestRoot(pluginRoot, fromRoot, toRoot) {
95216
95245
  }
95217
95246
  }
95218
95247
  if (changed)
95219
- await writeFile3(manifestPath, `${JSON.stringify(parsed, null, "\t")}
95248
+ await writeFile4(manifestPath, `${JSON.stringify(parsed, null, "\t")}
95220
95249
  `);
95221
95250
  }
95222
95251
 
@@ -95278,7 +95307,7 @@ async function unsupportedEntries(root, directory) {
95278
95307
  }
95279
95308
 
95280
95309
  // packages/omo-codex/src/install/codex-hook-targets.ts
95281
- import { readFile as readFile7 } from "fs/promises";
95310
+ import { readFile as readFile8 } from "fs/promises";
95282
95311
  import { join as join32, sep as sep5 } from "path";
95283
95312
  var PLUGIN_ROOT_TARGET_PATTERN = /\$\{PLUGIN_ROOT\}[\\/]+([^"']+)/g;
95284
95313
  async function findMissingHookCommandTargets(pluginRoot) {
@@ -95286,7 +95315,7 @@ async function findMissingHookCommandTargets(pluginRoot) {
95286
95315
  for (const manifestPath of await hookManifestPaths(pluginRoot)) {
95287
95316
  if (!await fileExistsStrict(manifestPath))
95288
95317
  continue;
95289
- const parsed = JSON.parse(await readFile7(manifestPath, "utf8"));
95318
+ const parsed = JSON.parse(await readFile8(manifestPath, "utf8"));
95290
95319
  collectCommands(parsed, commands);
95291
95320
  }
95292
95321
  const missing = [];
@@ -95310,7 +95339,7 @@ async function hookManifestPaths(pluginRoot) {
95310
95339
  const pluginManifestPath = join32(pluginRoot, ".codex-plugin", "plugin.json");
95311
95340
  if (!await fileExistsStrict(pluginManifestPath))
95312
95341
  return [join32(pluginRoot, "hooks", "hooks.json")];
95313
- const parsed = JSON.parse(await readFile7(pluginManifestPath, "utf8"));
95342
+ const parsed = JSON.parse(await readFile8(pluginManifestPath, "utf8"));
95314
95343
  if (!isPlainRecord4(parsed))
95315
95344
  return [];
95316
95345
  if (typeof parsed.hooks === "string" && parsed.hooks.trim() !== "") {
@@ -95397,7 +95426,7 @@ async function maybeRunNpmInstall(cwd, runCommand, env, args = ["install"]) {
95397
95426
  async function maybeRunNpmBuild(cwd, runCommand, env) {
95398
95427
  if (!await fileExistsStrict(join33(cwd, "package.json")))
95399
95428
  return;
95400
- const packageJson = JSON.parse(await readFile8(join33(cwd, "package.json"), "utf8"));
95429
+ const packageJson = JSON.parse(await readFile9(join33(cwd, "package.json"), "utf8"));
95401
95430
  if (!isPlainRecord4(packageJson))
95402
95431
  return;
95403
95432
  const scripts = packageJson.scripts;
@@ -95408,7 +95437,7 @@ async function maybeRunNpmBuild(cwd, runCommand, env) {
95408
95437
  async function maybeRunNpmSyncSkills(cwd, runCommand, env) {
95409
95438
  if (!await fileExistsStrict(join33(cwd, "package.json")))
95410
95439
  return;
95411
- const packageJson = JSON.parse(await readFile8(join33(cwd, "package.json"), "utf8"));
95440
+ const packageJson = JSON.parse(await readFile9(join33(cwd, "package.json"), "utf8"));
95412
95441
  if (!isPlainRecord4(packageJson))
95413
95442
  return;
95414
95443
  const scripts = packageJson.scripts;
@@ -95471,7 +95500,7 @@ var removedSparkshellPromptSurfaceFiles = new Set(["directive.md", "plugin.json"
95471
95500
  var removedSparkshellTextFilePattern = /\.(?:json|md|toml|ya?ml)$/i;
95472
95501
  async function assertNoRemovedSparkshellPromptReferences(pluginRoot) {
95473
95502
  for (const filePath of await listRemovedSparkshellPromptSurfaceFiles(pluginRoot, "")) {
95474
- const content = await readFile8(join33(pluginRoot, filePath), "utf8");
95503
+ const content = await readFile9(join33(pluginRoot, filePath), "utf8");
95475
95504
  if (!removedSparkshellReferencePattern.test(content))
95476
95505
  continue;
95477
95506
  throw new Error(`removed sparkshell reference found in Codex plugin prompt surface: ${filePath}`);
@@ -95620,7 +95649,7 @@ async function isBrokenCacheSymlink(path) {
95620
95649
  }
95621
95650
  }
95622
95651
  // packages/omo-codex/src/install/codex-cached-marketplace-manifest.ts
95623
- import { mkdir as mkdir4, rename as rename3, rm as rm7, stat as stat5, writeFile as writeFile4 } from "fs/promises";
95652
+ import { mkdir as mkdir4, rename as rename3, rm as rm7, stat as stat5, writeFile as writeFile5 } from "fs/promises";
95624
95653
  import { join as join35 } from "path";
95625
95654
  async function writeCachedMarketplaceManifest(input) {
95626
95655
  const marketplaceDir = join35(input.marketplaceRoot, ".agents", "plugins");
@@ -95633,7 +95662,7 @@ async function writeCachedMarketplaceManifest(input) {
95633
95662
  const manifestPath = join35(marketplaceDir, "marketplace.json");
95634
95663
  const tempPath = join35(marketplaceDir, `.marketplace.json.tmp-${process.pid}-${Date.now()}`);
95635
95664
  try {
95636
- await writeFile4(tempPath, `${JSON.stringify({
95665
+ await writeFile5(tempPath, `${JSON.stringify({
95637
95666
  name: input.marketplaceName,
95638
95667
  plugins: input.plugins.map((plugin) => ({
95639
95668
  name: plugin.name,
@@ -95659,7 +95688,7 @@ async function isDirectory2(path) {
95659
95688
 
95660
95689
  // packages/omo-codex/src/install/codex-package-layout.ts
95661
95690
  import { existsSync as existsSync24 } from "fs";
95662
- import { readFile as readFile9 } from "fs/promises";
95691
+ import { readFile as readFile10 } from "fs/promises";
95663
95692
  import { join as join36 } from "path";
95664
95693
  var PACKAGED_CODEX_INSTALLER_NAMES = new Set([
95665
95694
  "@code-yeongyu/lazycodex",
@@ -95675,14 +95704,14 @@ async function shouldBuildSourcePackages(repoRoot) {
95675
95704
  const packageJsonPath = join36(repoRoot, "package.json");
95676
95705
  if (!existsSync24(packageJsonPath))
95677
95706
  return true;
95678
- const packageJson = JSON.parse(await readFile9(packageJsonPath, "utf8"));
95707
+ const packageJson = JSON.parse(await readFile10(packageJsonPath, "utf8"));
95679
95708
  if (!isPlainRecord4(packageJson) || typeof packageJson.name !== "string")
95680
95709
  return true;
95681
95710
  return !PACKAGED_CODEX_INSTALLER_NAMES.has(packageJson.name);
95682
95711
  }
95683
95712
 
95684
95713
  // packages/omo-codex/src/install/codex-config-toml.ts
95685
- import { mkdir as mkdir5, readFile as readFile11 } from "fs/promises";
95714
+ import { mkdir as mkdir5, readFile as readFile12 } from "fs/promises";
95686
95715
  import { dirname as dirname16 } from "path";
95687
95716
 
95688
95717
  // packages/omo-codex/src/install/toml-section-editor.ts
@@ -96279,18 +96308,18 @@ function tomlKeySegment(value) {
96279
96308
  }
96280
96309
 
96281
96310
  // packages/omo-codex/src/install/codex-config-atomic-write.ts
96282
- import { lstat as lstat7, readlink as readlink4, realpath, rename as rename4, unlink, writeFile as writeFile5 } from "fs/promises";
96311
+ import { lstat as lstat7, readlink as readlink4, realpath, rename as rename4, unlink as unlink2, writeFile as writeFile6 } from "fs/promises";
96283
96312
  import { basename as basename6, dirname as dirname14, isAbsolute as isAbsolute5, join as join37, resolve as resolve10 } from "path";
96284
96313
  var RENAME_RETRY_DELAYS_MS = [10, 25, 50];
96285
96314
  var RETRIABLE_RENAME_CODES = new Set(["EPERM", "EBUSY"]);
96286
96315
  async function writeFileAtomic(targetPath, data) {
96287
96316
  const writeTarget = await resolveSymlinkTarget(targetPath);
96288
96317
  const temporaryPath = join37(dirname14(writeTarget), `.tmp-${basename6(writeTarget)}-${process.pid}-${Date.now()}`);
96289
- await writeFile5(temporaryPath, data);
96318
+ await writeFile6(temporaryPath, data);
96290
96319
  try {
96291
96320
  await renameWithRetry(temporaryPath, writeTarget);
96292
96321
  } catch (error) {
96293
- await unlink(temporaryPath).catch((unlinkError) => {
96322
+ await unlink2(temporaryPath).catch((unlinkError) => {
96294
96323
  if (unlinkError instanceof Error)
96295
96324
  return;
96296
96325
  return;
@@ -96785,7 +96814,7 @@ function isRootSetting(line, key) {
96785
96814
 
96786
96815
  // packages/omo-codex/src/install/codex-model-catalog.ts
96787
96816
  init_latest_models();
96788
- import { readFile as readFile10 } from "fs/promises";
96817
+ import { readFile as readFile11 } from "fs/promises";
96789
96818
  import { join as join38 } from "path";
96790
96819
  var FALLBACK_CODEX_MODEL_CATALOG = {
96791
96820
  current: {
@@ -96819,7 +96848,7 @@ var FALLBACK_CODEX_MODEL_CATALOG = {
96819
96848
  async function readCodexModelCatalog(codexPackageRoot) {
96820
96849
  const catalogPath = join38(codexPackageRoot, "plugin", "model-catalog.json");
96821
96850
  try {
96822
- const parsed = JSON.parse(await readFile10(catalogPath, "utf8"));
96851
+ const parsed = JSON.parse(await readFile11(catalogPath, "utf8"));
96823
96852
  return parseCodexModelCatalog(parsed) ?? FALLBACK_CODEX_MODEL_CATALOG;
96824
96853
  } catch (error) {
96825
96854
  if (error instanceof Error)
@@ -97044,7 +97073,7 @@ async function updateCodexConfig(input) {
97044
97073
  await mkdir5(dirname16(input.configPath), { recursive: true });
97045
97074
  let config;
97046
97075
  try {
97047
- config = await readFile11(input.configPath, "utf8");
97076
+ config = await readFile12(input.configPath, "utf8");
97048
97077
  } catch (error) {
97049
97078
  if (!isMissingFileError(error))
97050
97079
  throw error;
@@ -97092,7 +97121,7 @@ function isMissingFileError(error) {
97092
97121
 
97093
97122
  // packages/omo-codex/src/install/codex-hook-trust.ts
97094
97123
  import { createHash as createHash3 } from "crypto";
97095
- import { readFile as readFile12 } from "fs/promises";
97124
+ import { readFile as readFile13 } from "fs/promises";
97096
97125
  import { join as join40 } from "path";
97097
97126
  var EVENT_LABELS = new Map([
97098
97127
  ["PreToolUse", "pre_tool_use"],
@@ -97110,7 +97139,7 @@ async function trustedHookStatesForPlugin(input) {
97110
97139
  const manifestPath = join40(input.pluginRoot, ".codex-plugin", "plugin.json");
97111
97140
  if (!await exists(manifestPath))
97112
97141
  return [];
97113
- const manifest = JSON.parse(await readFile12(manifestPath, "utf8"));
97142
+ const manifest = JSON.parse(await readFile13(manifestPath, "utf8"));
97114
97143
  if (!isPlainRecord4(manifest))
97115
97144
  return [];
97116
97145
  const states = [];
@@ -97118,7 +97147,7 @@ async function trustedHookStatesForPlugin(input) {
97118
97147
  const hooksPath = join40(input.pluginRoot, hookPath);
97119
97148
  if (!await exists(hooksPath))
97120
97149
  continue;
97121
- const parsed = JSON.parse(await readFile12(hooksPath, "utf8"));
97150
+ const parsed = JSON.parse(await readFile13(hooksPath, "utf8"));
97122
97151
  if (!isPlainRecord4(parsed) || !isPlainRecord4(parsed.hooks))
97123
97152
  continue;
97124
97153
  states.push(...trustedHookStatesForHooksFile({
@@ -97201,7 +97230,7 @@ function stripDotSlash2(value) {
97201
97230
  }
97202
97231
  async function exists(path) {
97203
97232
  try {
97204
- await readFile12(path, "utf8");
97233
+ await readFile13(path, "utf8");
97205
97234
  return true;
97206
97235
  } catch (error) {
97207
97236
  if (error instanceof Error)
@@ -97301,7 +97330,7 @@ function recordAt2(value, key) {
97301
97330
  }
97302
97331
 
97303
97332
  // packages/omo-codex/src/install/codex-marketplace-snapshot.ts
97304
- import { cp as cp4, mkdir as mkdir6, rename as rename5, rm as rm8, writeFile as writeFile6 } from "fs/promises";
97333
+ import { cp as cp4, mkdir as mkdir6, rename as rename5, rm as rm8, writeFile as writeFile7 } from "fs/promises";
97305
97334
  import { join as join41, sep as sep7 } from "path";
97306
97335
  var INSTALLED_MARKETPLACES_DIR = ".tmp/marketplaces";
97307
97336
  async function writeInstalledMarketplaceSnapshot(input) {
@@ -97321,7 +97350,7 @@ async function writeMarketplaceManifest(marketplaceRoot, marketplace) {
97321
97350
  const manifestDir = join41(marketplaceRoot, ".agents", "plugins");
97322
97351
  await mkdir6(manifestDir, { recursive: true });
97323
97352
  const tempPath = join41(manifestDir, `.marketplace-${process.pid}-${Date.now()}.json.tmp`);
97324
- await writeFile6(tempPath, `${JSON.stringify(marketplace, null, "\t")}
97353
+ await writeFile7(tempPath, `${JSON.stringify(marketplace, null, "\t")}
97325
97354
  `);
97326
97355
  await rename5(tempPath, join41(manifestDir, "marketplace.json"));
97327
97356
  }
@@ -97350,15 +97379,15 @@ function shouldCopyMarketplaceSourcePath(path, root) {
97350
97379
  }
97351
97380
 
97352
97381
  // packages/omo-codex/src/install/link-cached-plugin-agents.ts
97353
- import { copyFile, lstat as lstat11, mkdir as mkdir7, readdir as readdir8, readFile as readFile17, rm as rm12, writeFile as writeFile9 } from "fs/promises";
97382
+ import { copyFile, lstat as lstat11, mkdir as mkdir7, readdir as readdir8, readFile as readFile18, rm as rm12, writeFile as writeFile10 } from "fs/promises";
97354
97383
  import { basename as basename7, join as join46 } from "path";
97355
97384
 
97356
97385
  // packages/omo-codex/src/install/agent-model-overrides.ts
97357
- import { readFile as readFile14, rm as rm9, writeFile as writeFile8 } from "fs/promises";
97386
+ import { readFile as readFile15, rm as rm9, writeFile as writeFile9 } from "fs/promises";
97358
97387
  import { join as join43 } from "path";
97359
97388
 
97360
97389
  // packages/omo-codex/src/install/preserved-agent-settings.ts
97361
- import { lstat as lstat8, readFile as readFile13, readdir as readdir7, writeFile as writeFile7 } from "fs/promises";
97390
+ import { lstat as lstat8, readFile as readFile14, readdir as readdir7, writeFile as writeFile8 } from "fs/promises";
97362
97391
  import { join as join42 } from "path";
97363
97392
 
97364
97393
  // packages/omo-codex/src/install/managed-agent-reasoning-defaults.ts
@@ -97593,7 +97622,7 @@ async function capturePreservedAgentServiceTier(input) {
97593
97622
  async function restorePreservedReasoning(input) {
97594
97623
  if (input.value === undefined)
97595
97624
  return;
97596
- const content = await readFile13(input.target, "utf8");
97625
+ const content = await readFile14(input.target, "utf8");
97597
97626
  const bundledEffort = extractReasoningEffort(content);
97598
97627
  const effort = resolveManagedAgentReasoning({
97599
97628
  agentName: input.agentName,
@@ -97606,33 +97635,33 @@ async function restorePreservedReasoning(input) {
97606
97635
  const replacement = replaceTopLevelStringSetting(content, "model_reasoning_effort", effort, { insertIfMissing: false });
97607
97636
  if (!replacement.replaced)
97608
97637
  return;
97609
- await writeFile7(input.linkPath, replacement.content);
97638
+ await writeFile8(input.linkPath, replacement.content);
97610
97639
  }
97611
97640
  async function restorePreservedServiceTier(input) {
97612
97641
  if (!input.preserved)
97613
97642
  return;
97614
- const content = await readFile13(input.linkPath, "utf8");
97643
+ const content = await readFile14(input.linkPath, "utf8");
97615
97644
  if (extractServiceTier(content) === input.value)
97616
97645
  return;
97617
97646
  const replacement = replaceTopLevelStringSetting(content, "service_tier", input.value, { insertIfMissing: true });
97618
97647
  if (!replacement.replaced)
97619
97648
  return;
97620
- await writeFile7(input.linkPath, replacement.content);
97649
+ await writeFile8(input.linkPath, replacement.content);
97621
97650
  }
97622
97651
  async function restorePreservedModel(input) {
97623
97652
  if (input.value === null)
97624
97653
  return;
97625
- const content = await readFile13(input.linkPath, "utf8");
97654
+ const content = await readFile14(input.linkPath, "utf8");
97626
97655
  if (extractModel(content) === input.value)
97627
97656
  return;
97628
97657
  const replacement = replaceTopLevelStringSetting(content, "model", input.value, { insertIfMissing: true });
97629
97658
  if (!replacement.replaced)
97630
97659
  return;
97631
- await writeFile7(input.linkPath, replacement.content);
97660
+ await writeFile8(input.linkPath, replacement.content);
97632
97661
  }
97633
97662
  async function readTextIfExists(path) {
97634
97663
  try {
97635
- return await readFile13(path, "utf8");
97664
+ return await readFile14(path, "utf8");
97636
97665
  } catch (error) {
97637
97666
  if (nodeErrorCode(error) === "ENOENT")
97638
97667
  return null;
@@ -97754,13 +97783,13 @@ async function writeAgentModelReceipts(codexHome, receipts) {
97754
97783
  await rm9(path, { force: true });
97755
97784
  return;
97756
97785
  }
97757
- await writeFile8(path, `${JSON.stringify(Object.fromEntries(receipts), null, "\t")}
97786
+ await writeFile9(path, `${JSON.stringify(Object.fromEntries(receipts), null, "\t")}
97758
97787
  `);
97759
97788
  }
97760
97789
  async function applyAgentOverride(input) {
97761
97790
  if (input.override === undefined)
97762
97791
  return;
97763
- let content = await readFile14(input.linkPath, "utf8");
97792
+ let content = await readFile15(input.linkPath, "utf8");
97764
97793
  if (input.override.model !== undefined) {
97765
97794
  content = replaceTopLevelStringSetting(content, "model", input.override.model, { insertIfMissing: true }).content;
97766
97795
  }
@@ -97769,7 +97798,7 @@ async function applyAgentOverride(input) {
97769
97798
  insertIfMissing: true
97770
97799
  }).content;
97771
97800
  }
97772
- await writeFile8(input.linkPath, content);
97801
+ await writeFile9(input.linkPath, content);
97773
97802
  }
97774
97803
  function receiptPath(codexHome) {
97775
97804
  return join43(codexHome, "agents", RECEIPT_FILE);
@@ -97804,7 +97833,7 @@ function handEditedAgentModel(installedModel, receipt) {
97804
97833
  }
97805
97834
 
97806
97835
  // packages/omo-codex/src/install/retired-managed-agent-purge.ts
97807
- import { lstat as lstat9, readFile as readFile15, rm as rm10 } from "fs/promises";
97836
+ import { lstat as lstat9, readFile as readFile16, rm as rm10 } from "fs/promises";
97808
97837
  import { join as join44 } from "path";
97809
97838
  var RETIRED_MANAGED_AGENT_FILES = [
97810
97839
  {
@@ -97838,7 +97867,7 @@ function hasRequiredMarkers(content, markers) {
97838
97867
  }
97839
97868
  async function readTextIfExists2(path) {
97840
97869
  try {
97841
- return await readFile15(path, "utf8");
97870
+ return await readFile16(path, "utf8");
97842
97871
  } catch (error) {
97843
97872
  if (nodeErrorCode2(error) === "ENOENT")
97844
97873
  return null;
@@ -97863,7 +97892,7 @@ function nodeErrorCode2(error) {
97863
97892
 
97864
97893
  // packages/omo-codex/src/install/default-agent-role.ts
97865
97894
  import { createHash as createHash4 } from "crypto";
97866
- import { lstat as lstat10, readFile as readFile16, rm as rm11 } from "fs/promises";
97895
+ import { lstat as lstat10, readFile as readFile17, rm as rm11 } from "fs/promises";
97867
97896
  import { join as join45 } from "path";
97868
97897
  var REGISTRATION = { name: "default", configFile: "./agents/default.toml" };
97869
97898
  async function installDefaultAgentRole(input) {
@@ -97900,7 +97929,7 @@ async function installDefaultAgentRole(input) {
97900
97929
  if (foreign || existing !== null && !owned) {
97901
97930
  throw new Error("Preserved user-owned agents.default / agents/default.toml. Move it aside to install the LazyCodex fallback, or set [codex].agents.default.disable = true in omo.jsonc. Explicit LazyCodex roles remain required.");
97902
97931
  }
97903
- const worker = await readFile16(input.worker.path, "utf8");
97932
+ const worker = await readFile17(input.worker.path, "utf8");
97904
97933
  const content = worker.replace(/^name\s*=\s*["']lazycodex-worker-medium["']\s*$/m, 'name = "default"');
97905
97934
  if (content === worker)
97906
97935
  throw new Error("Cannot derive default: medium worker has no matching internal name");
@@ -97910,7 +97939,7 @@ async function installDefaultAgentRole(input) {
97910
97939
  }
97911
97940
  async function readIfPresent(path) {
97912
97941
  try {
97913
- return await readFile16(path, "utf8");
97942
+ return await readFile17(path, "utf8");
97914
97943
  } catch (error) {
97915
97944
  if (error instanceof Error && "code" in error && error.code === "ENOENT")
97916
97945
  return null;
@@ -97971,7 +98000,7 @@ async function syncAgentFile(input) {
97971
98000
  value: input.preservedServiceTier?.get(input.agentName) ?? null
97972
98001
  });
97973
98002
  await applyAgentOverride({ linkPath: input.linkPath, override });
97974
- const model = override?.model ?? extractModel(await readFile17(input.agentPath, "utf8"));
98003
+ const model = override?.model ?? extractModel(await readFile18(input.agentPath, "utf8"));
97975
98004
  return {
97976
98005
  ...model === null ? {} : { model },
97977
98006
  ...override?.reasoningEffort === undefined ? {} : { reasoningEffort: override.reasoningEffort }
@@ -98015,7 +98044,7 @@ async function prepareReplacement(linkPath) {
98015
98044
  async function writeManifest(pluginRoot, agentPaths) {
98016
98045
  const manifestPath = join46(pluginRoot, MANIFEST_FILE);
98017
98046
  const payload = { agents: [...agentPaths].sort() };
98018
- await writeFile9(manifestPath, `${JSON.stringify(payload, null, "\t")}
98047
+ await writeFile10(manifestPath, `${JSON.stringify(payload, null, "\t")}
98019
98048
  `);
98020
98049
  }
98021
98050
  function agentNameFromToml2(fileName) {
@@ -98084,12 +98113,12 @@ function agentNameFromToml3(fileName) {
98084
98113
  }
98085
98114
 
98086
98115
  // packages/omo-codex/src/install/codex-marketplace.ts
98087
- import { readFile as readFile18 } from "fs/promises";
98116
+ import { readFile as readFile19 } from "fs/promises";
98088
98117
  import { join as join47 } from "path";
98089
98118
  var DEFAULT_MARKETPLACE_PATH = "packages/omo-codex/marketplace.json";
98090
98119
  async function readMarketplace(repoRoot, options) {
98091
98120
  const marketplacePath = options?.marketplacePath ?? join47(repoRoot, DEFAULT_MARKETPLACE_PATH);
98092
- const raw = await readFile18(marketplacePath, "utf8");
98121
+ const raw = await readFile19(marketplacePath, "utf8");
98093
98122
  const parsed = JSON.parse(raw);
98094
98123
  if (!isPlainRecord4(parsed))
98095
98124
  throw new Error("marketplace.json must be an object");
@@ -98110,7 +98139,7 @@ function resolvePluginSource(repoRoot, plugin, options) {
98110
98139
  return join47(repoRoot, ...relativePath.split(/[\\/]/));
98111
98140
  }
98112
98141
  async function readPluginManifest(pluginRoot) {
98113
- const raw = await readFile18(join47(pluginRoot, ".codex-plugin", "plugin.json"), "utf8");
98142
+ const raw = await readFile19(join47(pluginRoot, ".codex-plugin", "plugin.json"), "utf8");
98114
98143
  const parsed = JSON.parse(raw);
98115
98144
  if (!isPlainRecord4(parsed))
98116
98145
  throw new Error(`${pluginRoot} plugin.json must be an object`);
@@ -98191,11 +98220,11 @@ function validateLocalSourcePath(path) {
98191
98220
  }
98192
98221
 
98193
98222
  // packages/omo-codex/src/install/lazycodex-version-stamp.ts
98194
- import { readdir as readdir9, readFile as readFile19, writeFile as writeFile10 } from "fs/promises";
98223
+ import { readdir as readdir9, readFile as readFile20, writeFile as writeFile11 } from "fs/promises";
98195
98224
  import { join as join48 } from "path";
98196
98225
  async function readDistributionManifest(repoRoot) {
98197
98226
  try {
98198
- const parsed = JSON.parse(await readFile19(join48(repoRoot, "package.json"), "utf8"));
98227
+ const parsed = JSON.parse(await readFile20(join48(repoRoot, "package.json"), "utf8"));
98199
98228
  if (!isPlainRecord4(parsed) || typeof parsed.version !== "string" || parsed.version.trim().length === 0)
98200
98229
  return;
98201
98230
  return {
@@ -98231,7 +98260,7 @@ async function stampLazyCodexPluginVersion(input) {
98231
98260
  async function writeLazyCodexInstallSnapshot(input) {
98232
98261
  if (input.distributionManifest === undefined)
98233
98262
  return;
98234
- await writeFile10(join48(input.pluginRoot, "lazycodex-install.json"), `${JSON.stringify({
98263
+ await writeFile11(join48(input.pluginRoot, "lazycodex-install.json"), `${JSON.stringify({
98235
98264
  packageName: input.distributionManifest.name,
98236
98265
  version: input.distributionManifest.version
98237
98266
  }, null, "\t")}
@@ -98239,11 +98268,11 @@ async function writeLazyCodexInstallSnapshot(input) {
98239
98268
  }
98240
98269
  async function stampJsonVersion(path, version) {
98241
98270
  try {
98242
- const parsed = JSON.parse(await readFile19(path, "utf8"));
98271
+ const parsed = JSON.parse(await readFile20(path, "utf8"));
98243
98272
  if (!isPlainRecord4(parsed))
98244
98273
  return;
98245
98274
  parsed.version = version;
98246
- await writeFile10(path, `${JSON.stringify(parsed, null, "\t")}
98275
+ await writeFile11(path, `${JSON.stringify(parsed, null, "\t")}
98247
98276
  `);
98248
98277
  } catch (error) {
98249
98278
  if (error instanceof Error)
@@ -98253,7 +98282,7 @@ async function stampJsonVersion(path, version) {
98253
98282
  }
98254
98283
  async function readPluginHookPaths(manifestPath) {
98255
98284
  try {
98256
- const parsed = JSON.parse(await readFile19(manifestPath, "utf8"));
98285
+ const parsed = JSON.parse(await readFile20(manifestPath, "utf8"));
98257
98286
  if (!isPlainRecord4(parsed))
98258
98287
  return [];
98259
98288
  if (typeof parsed.hooks === "string" && parsed.hooks.trim().length > 0)
@@ -98273,11 +98302,11 @@ function stripDotSlash3(path) {
98273
98302
  }
98274
98303
  async function stampHookStatusMessages(path, version) {
98275
98304
  try {
98276
- const parsed = JSON.parse(await readFile19(path, "utf8"));
98305
+ const parsed = JSON.parse(await readFile20(path, "utf8"));
98277
98306
  if (!isPlainRecord4(parsed))
98278
98307
  return;
98279
98308
  stampHookGroups(parsed.hooks, version);
98280
- await writeFile10(path, `${JSON.stringify(parsed, null, "\t")}
98309
+ await writeFile11(path, `${JSON.stringify(parsed, null, "\t")}
98281
98310
  `);
98282
98311
  } catch (error) {
98283
98312
  if (error instanceof Error)
@@ -98354,7 +98383,7 @@ var defaultRunCommand = async (command, args, options) => {
98354
98383
  };
98355
98384
 
98356
98385
  // packages/omo-codex/src/install/codex-project-local-cleanup.ts
98357
- import { copyFile as copyFile2, lstat as lstat12, readFile as readFile20, writeFile as writeFile11 } from "fs/promises";
98386
+ import { copyFile as copyFile2, lstat as lstat12, readFile as readFile21, writeFile as writeFile12 } from "fs/promises";
98358
98387
  import { dirname as dirname17, join as join49, resolve as resolve11 } from "path";
98359
98388
  var LEGACY_AGENT_CONFLICT_KEYS = ["max_threads"];
98360
98389
  var PROJECT_LOCAL_ARTIFACT_PATHS = [
@@ -98374,7 +98403,7 @@ async function repairNearestProjectLocalCodexArtifacts(input) {
98374
98403
  const artifacts = await collectProjectLocalArtifacts(project.artifactRoots);
98375
98404
  const configs = [];
98376
98405
  for (const configPath of project.configPaths) {
98377
- const original = await readFile20(configPath, "utf8");
98406
+ const original = await readFile21(configPath, "utf8");
98378
98407
  const repair = repairProjectLocalCodexConfigText(original);
98379
98408
  if (!repair.changed) {
98380
98409
  configs.push({
@@ -98387,7 +98416,7 @@ async function repairNearestProjectLocalCodexArtifacts(input) {
98387
98416
  }
98388
98417
  const backupPath = `${configPath}.backup-${formatBackupTimestamp(input.now?.() ?? new Date)}`;
98389
98418
  await copyFile2(configPath, backupPath);
98390
- await writeFile11(configPath, `${repair.config.trimEnd()}
98419
+ await writeFile12(configPath, `${repair.config.trimEnd()}
98391
98420
  `);
98392
98421
  configs.push({
98393
98422
  projectRoot: project.projectRoot,
@@ -98584,13 +98613,13 @@ function formatUnknownError(error) {
98584
98613
 
98585
98614
  // packages/omo-codex/src/install/lsp-daemon-reaper.ts
98586
98615
  import { createHash as createHash5 } from "crypto";
98587
- import { lstat as lstat13, readFile as readFile22, readdir as readdir11, rm as rm13 } from "fs/promises";
98616
+ import { lstat as lstat13, readFile as readFile23, readdir as readdir11, rm as rm13 } from "fs/promises";
98588
98617
  import { tmpdir as tmpdir4 } from "os";
98589
98618
  import { join as join50, posix as posix6 } from "path";
98590
98619
 
98591
98620
  // packages/omo-codex/src/install/lsp-daemon-reaper-attestation.ts
98592
98621
  import { execFile } from "child_process";
98593
- import { readFile as readFile21, readdir as readdir10, readlink as readlink5 } from "fs/promises";
98622
+ import { readFile as readFile22, readdir as readdir10, readlink as readlink5 } from "fs/promises";
98594
98623
  import { connect } from "net";
98595
98624
  import { basename as basename8 } from "path";
98596
98625
  var PROBE_TIMEOUT_MS = 500;
@@ -98632,7 +98661,7 @@ async function attestLegacyDaemonOwnership(input, deps = {}) {
98632
98661
  return false;
98633
98662
  }
98634
98663
  async function attestLinuxOwnership(input, deps) {
98635
- const readFileImpl = deps.readFile ?? readFile21;
98664
+ const readFileImpl = deps.readFile ?? readFile22;
98636
98665
  const readDirImpl = deps.readDir ?? readdir10;
98637
98666
  const readLinkImpl = deps.readLink ?? readlink5;
98638
98667
  const procNetUnix = await readText(readFileImpl, "/proc/net/unix");
@@ -98857,7 +98886,7 @@ async function readRegularTrimmedFile(path) {
98857
98886
  return null;
98858
98887
  if (!stats.isFile())
98859
98888
  return "non_regular";
98860
- const content = (await readFile22(path, "utf8")).trim();
98889
+ const content = (await readFile23(path, "utf8")).trim();
98861
98890
  return content.length > 0 ? content : null;
98862
98891
  }
98863
98892
  function shortDigest(value) {
@@ -98918,11 +98947,11 @@ function resolveCodexInstallerBinDir(input) {
98918
98947
  }
98919
98948
 
98920
98949
  // packages/omo-codex/src/install/codex-installed-bin-dir.ts
98921
- import { readFile as readFile23, readdir as readdir12, writeFile as writeFile12 } from "fs/promises";
98950
+ import { readFile as readFile24, readdir as readdir12, writeFile as writeFile13 } from "fs/promises";
98922
98951
  import { join as join52 } from "path";
98923
98952
  var INSTALLED_BIN_DIR_MANIFEST = ".installed-bin-dir.json";
98924
98953
  async function writeInstalledCodexBinDir(input) {
98925
- await writeFile12(join52(input.pluginRoot, INSTALLED_BIN_DIR_MANIFEST), `${JSON.stringify({ binDir: input.binDir }, null, 2)}
98954
+ await writeFile13(join52(input.pluginRoot, INSTALLED_BIN_DIR_MANIFEST), `${JSON.stringify({ binDir: input.binDir }, null, 2)}
98926
98955
  `);
98927
98956
  }
98928
98957
  async function readInstalledCodexBinDir(codexHome) {
@@ -98948,7 +98977,7 @@ async function installedBinDirManifestPaths(codexHome) {
98948
98977
  return paths;
98949
98978
  }
98950
98979
  async function readBinDirFromManifest(manifestPath) {
98951
- const raw = await readFile23(manifestPath, "utf8").catch(() => null);
98980
+ const raw = await readFile24(manifestPath, "utf8").catch(() => null);
98952
98981
  if (raw === null)
98953
98982
  return null;
98954
98983
  let parsed;
@@ -98966,7 +98995,7 @@ async function readBinDirFromManifest(manifestPath) {
98966
98995
  }
98967
98996
 
98968
98997
  // packages/omo-codex/src/install/codex-git-bash-hooks.ts
98969
- import { readFile as readFile24, writeFile as writeFile13 } from "fs/promises";
98998
+ import { readFile as readFile25, writeFile as writeFile14 } from "fs/promises";
98970
98999
  import { join as join53 } from "path";
98971
99000
  var WINDOWS_ONLY_GIT_BASH_HOOKS = new Set([
98972
99001
  "./hooks/pre-tool-use-recommending-git-bash-mcp.json",
@@ -98976,13 +99005,13 @@ async function removeGitBashHooksOffWindows(input) {
98976
99005
  if (input.platform === "win32")
98977
99006
  return;
98978
99007
  const manifestPath = join53(input.pluginRoot, ".codex-plugin", "plugin.json");
98979
- const parsed = JSON.parse(await readFile24(manifestPath, "utf8"));
99008
+ const parsed = JSON.parse(await readFile25(manifestPath, "utf8"));
98980
99009
  if (!isPlainRecord4(parsed) || !Array.isArray(parsed.hooks))
98981
99010
  return;
98982
99011
  const hooks = parsed.hooks.filter((hook) => typeof hook !== "string" || !WINDOWS_ONLY_GIT_BASH_HOOKS.has(hook));
98983
99012
  if (hooks.length === parsed.hooks.length)
98984
99013
  return;
98985
- await writeFile13(manifestPath, `${JSON.stringify({ ...parsed, hooks }, null, "\t")}
99014
+ await writeFile14(manifestPath, `${JSON.stringify({ ...parsed, hooks }, null, "\t")}
98986
99015
  `);
98987
99016
  }
98988
99017
 
@@ -99353,12 +99382,12 @@ function defaultRunCommand2(command, args) {
99353
99382
  });
99354
99383
  }
99355
99384
  // packages/omo-codex/src/install/codex-cleanup.ts
99356
- import { lstat as lstat16, readFile as readFile27, readdir as readdir14, rm as rm15, rmdir } from "fs/promises";
99385
+ import { lstat as lstat16, readFile as readFile28, readdir as readdir14, rm as rm15, rmdir } from "fs/promises";
99357
99386
  import { homedir as homedir9 } from "os";
99358
99387
  import { isAbsolute as isAbsolute11, join as join62, relative as relative7, resolve as resolve16 } from "path";
99359
99388
 
99360
99389
  // packages/omo-codex/src/install/codex-cleanup-bins.ts
99361
- import { lstat as lstat14, readFile as readFile25, readdir as readdir13, readlink as readlink6, rm as rm14 } from "fs/promises";
99390
+ import { lstat as lstat14, readFile as readFile26, readdir as readdir13, readlink as readlink6, rm as rm14 } from "fs/promises";
99362
99391
  import { dirname as dirname20, isAbsolute as isAbsolute9, join as join60, resolve as resolve14 } from "path";
99363
99392
  var ROOT_RUNTIME_BIN_NAME = "omo";
99364
99393
  var MANAGED_CODEX_BIN_NAMES = new Set([
@@ -99420,12 +99449,12 @@ async function isManagedCodexBin(linkPath, platform, binName) {
99420
99449
  }
99421
99450
  if (!entryStat.isFile())
99422
99451
  return false;
99423
- const content = await readFile25(linkPath, "utf8");
99452
+ const content = await readFile26(linkPath, "utf8");
99424
99453
  return content.includes(RUNTIME_WRAPPER_MARKER) || content.includes(COMMAND_SHIM_MARKER);
99425
99454
  }
99426
99455
 
99427
99456
  // packages/omo-codex/src/install/codex-cleanup-config.ts
99428
- import { lstat as lstat15, mkdir as mkdir8, readFile as readFile26, writeFile as writeFile14 } from "fs/promises";
99457
+ import { lstat as lstat15, mkdir as mkdir8, readFile as readFile27, writeFile as writeFile15 } from "fs/promises";
99429
99458
  import { dirname as dirname21 } from "path";
99430
99459
  var MANAGED_MARKETPLACES = ["sisyphuslabs", "lazycodex", "code-yeongyu-codex-plugins"];
99431
99460
  var LEGACY_MANAGED_CODEX_AGENT_NAMES_TO_PURGE2 = ["codex-ultrawork-reviewer"];
@@ -99458,14 +99487,14 @@ function cleanupCodexLightConfigText(config) {
99458
99487
  async function cleanupCodexConfig(configPath, now) {
99459
99488
  if (!await configExists(configPath))
99460
99489
  return { changed: false };
99461
- const original = await readFile26(configPath, "utf8");
99490
+ const original = await readFile27(configPath, "utf8");
99462
99491
  const next = cleanupCodexLightConfigText(original);
99463
99492
  if (next === original)
99464
99493
  return { changed: false };
99465
99494
  const backupPath = `${configPath}.backup-${formatBackupTimestamp2(now?.() ?? new Date)}`;
99466
99495
  await mkdir8(dirname21(configPath), { recursive: true });
99467
- await writeFile14(backupPath, original);
99468
- await writeFile14(configPath, `${next.trimEnd()}
99496
+ await writeFile15(backupPath, original);
99497
+ await writeFile15(configPath, `${next.trimEnd()}
99469
99498
  `);
99470
99499
  return { changed: true, backupPath };
99471
99500
  }
@@ -99742,13 +99771,13 @@ async function collectInstalledAgentPaths(codexHome, configPath) {
99742
99771
  async function readManagedAgentPathsFromConfig(codexHome, configPath) {
99743
99772
  if (!await exists6(configPath))
99744
99773
  return [];
99745
- const config = await readFile27(configPath, "utf8");
99774
+ const config = await readFile28(configPath, "utf8");
99746
99775
  return MANAGED_CODEX_AGENT_NAMES2.filter((agentName) => config.includes(`config_file = ${JSON.stringify(`./agents/${agentName}.toml`)}`)).map((agentName) => join62(codexHome, "agents", `${agentName}.toml`));
99747
99776
  }
99748
99777
  async function readInstalledAgentManifest(manifestPath) {
99749
99778
  if (!await exists6(manifestPath))
99750
99779
  return [];
99751
- const parsed = JSON.parse(await readFile27(manifestPath, "utf8"));
99780
+ const parsed = JSON.parse(await readFile28(manifestPath, "utf8"));
99752
99781
  if (!isPlainRecord4(parsed) || !Array.isArray(parsed.agents))
99753
99782
  return [];
99754
99783
  return parsed.agents.filter((path) => typeof path === "string");
@@ -99940,7 +99969,7 @@ node "%~dp0omo" %*\r
99940
99969
  // packages/omo-senpi/src/install/plugin-artifacts.ts
99941
99970
  import { createHash as createHash7 } from "crypto";
99942
99971
  import { constants as constants9 } from "fs";
99943
- import { access as access2, readFile as readFile29, stat as stat6 } from "fs/promises";
99972
+ import { access as access3, readFile as readFile30, stat as stat6 } from "fs/promises";
99944
99973
  import { dirname as dirname25, join as join66 } from "path";
99945
99974
 
99946
99975
  // packages/memory-core/src/personas/manifest.ts
@@ -99959,7 +99988,7 @@ var PERSONA_ASSET_FILES = [
99959
99988
 
99960
99989
  // packages/omo-senpi/src/install/senpi-settings.ts
99961
99990
  import { constants as constants8 } from "fs";
99962
- import { access, copyFile as copyFile3, mkdir as mkdir9, readFile as readFile28, rename as rename6, writeFile as writeFile15 } from "fs/promises";
99991
+ import { access as access2, copyFile as copyFile3, mkdir as mkdir9, readFile as readFile29, rename as rename6, writeFile as writeFile16 } from "fs/promises";
99963
99992
  import { basename as basename10, dirname as dirname24, join as join65, resolve as resolve19 } from "path";
99964
99993
  var OMO_SENPI_PACKAGE_NAME = "@code-yeongyu/omo-senpi";
99965
99994
  var GENERATED_PLUGIN_BASENAME = /^omo-senpi-cli-plugin-[A-Za-z0-9]{6}$/;
@@ -99970,7 +99999,7 @@ var LEGACY_BUILTIN_SHADOW_PACKAGES = [
99970
99999
  async function readSettings(settingsPath) {
99971
100000
  let raw;
99972
100001
  try {
99973
- raw = await readFile28(settingsPath, "utf8");
100002
+ raw = await readFile29(settingsPath, "utf8");
99974
100003
  } catch (error) {
99975
100004
  if (isErrno(error, "ENOENT"))
99976
100005
  return {};
@@ -100017,11 +100046,11 @@ async function writeSettingsAtomically(settingsPath, settings) {
100017
100046
  if (await fileExists(settingsPath)) {
100018
100047
  await copyFile3(settingsPath, backupPath);
100019
100048
  } else {
100020
- await writeFile15(backupPath, `{}
100049
+ await writeFile16(backupPath, `{}
100021
100050
  `, "utf8");
100022
100051
  }
100023
100052
  const tempPath = `${settingsPath}.${process.pid}.${Date.now()}.tmp`;
100024
- await writeFile15(tempPath, `${JSON.stringify(settings, null, 2)}
100053
+ await writeFile16(tempPath, `${JSON.stringify(settings, null, 2)}
100025
100054
  `, "utf8");
100026
100055
  await rename6(tempPath, settingsPath);
100027
100056
  return backupPath;
@@ -100044,7 +100073,7 @@ function isRecord15(value) {
100044
100073
  async function readPackageName(packagePath) {
100045
100074
  let raw;
100046
100075
  try {
100047
- raw = await readFile28(join65(packagePath, "package.json"), "utf8");
100076
+ raw = await readFile29(join65(packagePath, "package.json"), "utf8");
100048
100077
  } catch (error) {
100049
100078
  if (isErrno(error, "ENOENT") || isErrno(error, "ENOTDIR"))
100050
100079
  return;
@@ -100062,7 +100091,7 @@ async function readPackageName(packagePath) {
100062
100091
  }
100063
100092
  async function fileExists(path) {
100064
100093
  try {
100065
- await access(path, constants8.F_OK);
100094
+ await access2(path, constants8.F_OK);
100066
100095
  return true;
100067
100096
  } catch (error) {
100068
100097
  if (isErrno(error, "ENOENT"))
@@ -100125,6 +100154,7 @@ var REQUIRED_PLUGIN_ARTIFACTS = [
100125
100154
  join66("skills", "visual-qa", "SKILL.md"),
100126
100155
  join66("skills-conditional", "x-search", "SKILL.md"),
100127
100156
  join66("runtime", "agent-toolkit-sdk", "sdk.js"),
100157
+ join66("runtime", "bunshin-ts", "sdk.js"),
100128
100158
  join66("runtime", "thread-sdk", "sdk.js"),
100129
100159
  join66("runtime", "ast-grep-mcp", "cli.js"),
100130
100160
  join66("runtime", "lsp-daemon", "dist", "cli.js"),
@@ -100167,7 +100197,7 @@ async function verifyAstGrepRuntimeIntegrity(pluginPath, platform) {
100167
100197
  runtimeStat = await stat6(runtimeEntry);
100168
100198
  if (!runtimeStat.isFile())
100169
100199
  throw new Error("runtime is not a file");
100170
- await access2(runtimeEntry, constants9.R_OK | constants9.X_OK);
100200
+ await access3(runtimeEntry, constants9.R_OK | constants9.X_OK);
100171
100201
  } catch (error) {
100172
100202
  throw astGrepIntegrityError(runtimeEntry, `runtime is unreadable or non-executable: ${messageOf(error)}`);
100173
100203
  }
@@ -100176,7 +100206,7 @@ async function verifyAstGrepRuntimeIntegrity(pluginPath, platform) {
100176
100206
  }
100177
100207
  let manifest;
100178
100208
  try {
100179
- manifest = JSON.parse(await readFile29(manifestPath, "utf8"));
100209
+ manifest = JSON.parse(await readFile30(manifestPath, "utf8"));
100180
100210
  } catch (error) {
100181
100211
  throw astGrepIntegrityError(runtimeEntry, `manifest is unreadable or invalid JSON: ${messageOf(error)}`);
100182
100212
  }
@@ -100185,7 +100215,7 @@ async function verifyAstGrepRuntimeIntegrity(pluginPath, platform) {
100185
100215
  }
100186
100216
  let actualSha256;
100187
100217
  try {
100188
- actualSha256 = createHash7("sha256").update(await readFile29(runtimeEntry)).digest("hex");
100218
+ actualSha256 = createHash7("sha256").update(await readFile30(runtimeEntry)).digest("hex");
100189
100219
  } catch (error) {
100190
100220
  throw astGrepIntegrityError(runtimeEntry, `runtime hash could not be computed: ${messageOf(error)}`);
100191
100221
  }
@@ -100210,7 +100240,7 @@ function messageOf(error) {
100210
100240
  }
100211
100241
  async function fileExists2(path) {
100212
100242
  try {
100213
- await access2(path, constants9.F_OK);
100243
+ await access3(path, constants9.F_OK);
100214
100244
  return true;
100215
100245
  } catch (error) {
100216
100246
  if (isErrno2(error, "ENOENT"))
@@ -107903,7 +107933,7 @@ function getSuggestedInstallTag(currentVersion) {
107903
107933
  // packages/omo-opencode/src/cli/doctor/checks/system.ts
107904
107934
  init_jsonc_parser2();
107905
107935
  init_plugin_identity();
107906
- var runtime4 = globalThis;
107936
+ var runtime5 = globalThis;
107907
107937
  var defaultDeps5 = {
107908
107938
  findOpenCodeBinary,
107909
107939
  getOpenCodeVersion: getOpenCodeVersion3,
@@ -107964,7 +107994,7 @@ async function gatherSystemInfo(deps = defaultDeps5) {
107964
107994
  opencodePath: binaryInfo?.path ?? null,
107965
107995
  pluginVersion,
107966
107996
  loadedVersion: loadedInfo.loadedVersion,
107967
- bunVersion: runtime4.Bun?.version ?? "unavailable",
107997
+ bunVersion: runtime5.Bun?.version ?? "unavailable",
107968
107998
  configPath: pluginInfo.configPath,
107969
107999
  configValid: isConfigValid(pluginInfo.configPath, deps),
107970
108000
  isLocalDev: pluginInfo.isLocalDev
@@ -109443,7 +109473,7 @@ async function pathExists2(dir) {
109443
109473
  // packages/omo-opencode/src/cli/doctor/checks/codex.ts
109444
109474
  init_src();
109445
109475
  import { existsSync as existsSync61 } from "fs";
109446
- import { lstat as lstat17, readdir as readdir15, readFile as readFile30 } from "fs/promises";
109476
+ import { lstat as lstat17, readdir as readdir15, readFile as readFile31 } from "fs/promises";
109447
109477
  import { homedir as homedir26 } from "os";
109448
109478
  import { basename as basename13, join as join99, resolve as resolve27 } from "path";
109449
109479
  // packages/omo-opencode/package.json
@@ -109668,7 +109698,7 @@ async function readCodexConfigSummary(configPath) {
109668
109698
  companionLifecycleHookStateEvents: []
109669
109699
  };
109670
109700
  }
109671
- const content = await readFile30(configPath, "utf8");
109701
+ const content = await readFile31(configPath, "utf8");
109672
109702
  return {
109673
109703
  exists: true,
109674
109704
  marketplaceConfigured: content.includes("[marketplaces.sisyphuslabs]"),
@@ -109696,7 +109726,7 @@ async function readLinkedAgents(codexHome) {
109696
109726
  }
109697
109727
  async function readJson(path) {
109698
109728
  try {
109699
- const parsed = JSON.parse(await readFile30(path, "utf8"));
109729
+ const parsed = JSON.parse(await readFile31(path, "utf8"));
109700
109730
  return isPlainRecord(parsed) ? parsed : null;
109701
109731
  } catch (error) {
109702
109732
  if (error instanceof Error)
@@ -109820,7 +109850,7 @@ function resolveLatestVersion(input) {
109820
109850
 
109821
109851
  // packages/omo-opencode/src/cli/doctor/checks/codex-components.ts
109822
109852
  init_src();
109823
- import { readdir as readdir16, readFile as readFile31, stat as stat7 } from "fs/promises";
109853
+ import { readdir as readdir16, readFile as readFile32, stat as stat7 } from "fs/promises";
109824
109854
  import { homedir as homedir27 } from "os";
109825
109855
  import { dirname as dirname40, isAbsolute as isAbsolute15, join as join100, relative as relative10, resolve as resolve28, sep as sep11 } from "path";
109826
109856
  var CODEX_COMPONENTS_CHECK_ID = "codex-components";
@@ -110073,7 +110103,7 @@ function degradedDetailLines(entries) {
110073
110103
  }
110074
110104
  async function readJson2(path) {
110075
110105
  try {
110076
- const parsed = JSON.parse(await readFile31(path, "utf8"));
110106
+ const parsed = JSON.parse(await readFile32(path, "utf8"));
110077
110107
  return isRecord18(parsed) ? parsed : null;
110078
110108
  } catch (error) {
110079
110109
  if (error instanceof Error)
@@ -110101,7 +110131,7 @@ function isRecord18(value) {
110101
110131
 
110102
110132
  // packages/omo-opencode/src/cli/doctor/checks/codex-runtime-wrapper.ts
110103
110133
  import { existsSync as existsSync62 } from "fs";
110104
- import { readFile as readFile32 } from "fs/promises";
110134
+ import { readFile as readFile33 } from "fs/promises";
110105
110135
  import { homedir as homedir28 } from "os";
110106
110136
  import { join as join101, resolve as resolve29 } from "path";
110107
110137
  var RUNTIME_WRAPPER_MARKER2 = "OMO_GENERATED_RUNTIME_WRAPPER";
@@ -110146,7 +110176,7 @@ async function checkCodexRuntimeWrapper(deps = {}) {
110146
110176
  }
110147
110177
  async function readRuntimeWrapper(path) {
110148
110178
  try {
110149
- return await readFile32(path, "utf8");
110179
+ return await readFile33(path, "utf8");
110150
110180
  } catch (error) {
110151
110181
  if (error instanceof Error)
110152
110182
  return null;
@@ -112070,6 +112100,73 @@ async function loadDeviceKeyring(store) {
112070
112100
  import { execFile as execFile5 } from "child_process";
112071
112101
  import { homedir as homedir30 } from "os";
112072
112102
  import { join as join105 } from "path";
112103
+
112104
+ // packages/omo-opencode/src/shared/bun-ffi-shim.ts
112105
+ async function loadBunFfi() {
112106
+ return import("bun:ffi");
112107
+ }
112108
+
112109
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/process-state.ts
112110
+ var KEY = Symbol.for("omo.keychain-helper.process.v1");
112111
+ function keychainProcessState() {
112112
+ const holder = globalThis;
112113
+ holder[KEY] ??= {
112114
+ secretsQueue: Promise.resolve(),
112115
+ interactionSwitch: undefined,
112116
+ approvalCache: undefined,
112117
+ entryCandidates: [],
112118
+ helperAccess: undefined,
112119
+ heldPromptLocks: new Set,
112120
+ handOff: undefined
112121
+ };
112122
+ return holder[KEY];
112123
+ }
112124
+
112125
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/secrets-gate.ts
112126
+ async function loadInteractionSwitch() {
112127
+ const state = keychainProcessState();
112128
+ if (state.interactionSwitch !== undefined)
112129
+ return state.interactionSwitch;
112130
+ if (process.platform !== "darwin")
112131
+ return state.interactionSwitch = null;
112132
+ try {
112133
+ const { dlopen, FFIType } = await loadBunFfi();
112134
+ const security = dlopen("/System/Library/Frameworks/Security.framework/Security", {
112135
+ SecKeychainSetUserInteractionAllowed: { args: [FFIType.u8], returns: FFIType.i32 }
112136
+ });
112137
+ state.interactionSwitch = (allowed) => {
112138
+ security.symbols.SecKeychainSetUserInteractionAllowed(allowed ? 1 : 0);
112139
+ };
112140
+ } catch {
112141
+ state.interactionSwitch = null;
112142
+ }
112143
+ return state.interactionSwitch;
112144
+ }
112145
+ function gatedSecrets(run) {
112146
+ const state = keychainProcessState();
112147
+ const next = state.secretsQueue.then(run, run);
112148
+ state.secretsQueue = next.then(() => {
112149
+ return;
112150
+ }, () => {
112151
+ return;
112152
+ });
112153
+ return next;
112154
+ }
112155
+ function silentSecrets(run) {
112156
+ return gatedSecrets(async () => {
112157
+ const setInteraction = await loadInteractionSwitch();
112158
+ if (setInteraction === null)
112159
+ throw new Error("Keychain interaction cannot be switched off on this host.");
112160
+ setInteraction(false);
112161
+ try {
112162
+ return await run();
112163
+ } finally {
112164
+ setInteraction(true);
112165
+ }
112166
+ });
112167
+ }
112168
+
112169
+ // packages/omo-opencode/src/cli/account-keys/keystore.ts
112073
112170
  var DEFAULT_SERVICE = "omo-cli";
112074
112171
  function defaultRun(argv, input) {
112075
112172
  const [file, ...args] = argv;
@@ -112093,7 +112190,7 @@ function createOsKeyStore(name, platform = process.platform, run = defaultRun, s
112093
112190
  const resolved = secrets === undefined ? run === defaultRun && typeof Bun !== "undefined" ? Bun.secrets : null : secrets;
112094
112191
  switch (platform) {
112095
112192
  case "darwin":
112096
- return resolved !== null ? createBunSecretsKeyStore(name, resolved) : createMacOsKeychainKeyStore(name, run);
112193
+ return resolved !== null ? createBunSecretsKeyStore(name, gateRealSecrets(resolved)) : createMacOsKeychainKeyStore(name, run);
112097
112194
  case "linux":
112098
112195
  return resolved !== null ? createBunSecretsKeyStore(name, resolved) : createLibsecretKeyStore(name, run);
112099
112196
  case "win32":
@@ -112112,6 +112209,10 @@ async function guarded(run, fail, argv, input) {
112112
112209
  throw fail();
112113
112210
  }
112114
112211
  }
112212
+ var gateRealSecrets = (secrets) => typeof Bun !== "undefined" && secrets === Bun.secrets ? {
112213
+ get: (key) => gatedSecrets(() => secrets.get(key)),
112214
+ set: (entry) => gatedSecrets(() => secrets.set(entry))
112215
+ } : secrets;
112115
112216
  function createBunSecretsKeyStore(name, secrets) {
112116
112217
  const key = { service: DEFAULT_SERVICE, name };
112117
112218
  const unavailable = () => new Error("omo account keys: cannot access the OS credential store. Unlock the login keychain (macOS), the Secret Service keyring (Linux), or DPAPI (Windows), then try again. " + "Private keys are only ever stored through the OS credential facility.");
@@ -112649,64 +112750,705 @@ async function loginDevice(session, options) {
112649
112750
  }
112650
112751
 
112651
112752
  // packages/omo-opencode/src/cli/service-auth/keystore.ts
112652
- import { createHash as createHash12, randomUUID as randomUUID7 } from "crypto";
112653
- import { basename as basename15 } from "path";
112753
+ import { createHash as createHash12, randomUUID as randomUUID8 } from "crypto";
112754
+ import { basename as basename17 } from "path";
112654
112755
 
112655
- // packages/omo-opencode/src/cli/service-auth/secret-service-lock.ts
112656
- import { spawn as spawn5 } from "child_process";
112657
- var DEFAULT_COLLECTION = "/org/freedesktop/secrets/aliases/default";
112658
- var PROBE_TIMEOUT_MS2 = 1e4;
112659
- var parseLockedReply = (stdout) => {
112660
- const match = /<\s*(true|false)\s*>/.exec(stdout);
112661
- if (match === null)
112662
- return null;
112663
- return match[1] === "true" ? "locked" : "unlocked";
112756
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/darwin-backend.ts
112757
+ import { homedir as homedir31 } from "os";
112758
+ import { join as join109 } from "path";
112759
+
112760
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/client.ts
112761
+ init_zod();
112762
+ init_bun_spawn_shim();
112763
+ var MUTATING = new Set(["write", "stage", "retire", "promote", "remove"]);
112764
+ var helperReplySchema = object({
112765
+ owned: boolean2(),
112766
+ value: string2(),
112767
+ marker: boolean2(),
112768
+ cdat: number2(),
112769
+ mdat: number2(),
112770
+ partition: _enum(["ours", "other", "none", "unknown"]),
112771
+ present: object({ staging: boolean2(), old: boolean2(), oldSlots: array(number2().int().min(0).max(7)).optional() }).strict(),
112772
+ missing: boolean2(),
112773
+ recover: boolean2(),
112774
+ ok: boolean2(),
112775
+ created: boolean2(),
112776
+ skipped: boolean2(),
112777
+ slot: number2().int().min(0).max(7),
112778
+ error: _enum(["locked", "store", "not-owned", "exists", "missing", "denied", "refused"]),
112779
+ reason: string2(),
112780
+ status: number2()
112781
+ }).partial().strict();
112782
+
112783
+ class HelperProtocolError extends Error {
112784
+ }
112785
+ async function firstLine(stream) {
112786
+ const reader = stream.getReader();
112787
+ const decoder = new TextDecoder;
112788
+ let text = "";
112789
+ for (;; ) {
112790
+ const newline = text.indexOf(`
112791
+ `);
112792
+ if (newline !== -1)
112793
+ return text.slice(0, newline);
112794
+ const chunk = await reader.read();
112795
+ if (chunk.done)
112796
+ return null;
112797
+ text += decoder.decode(chunk.value, { stream: true });
112798
+ }
112799
+ }
112800
+ function isFlushable(stream) {
112801
+ return typeof stream.flush === "function";
112802
+ }
112803
+ var spawnDetachedHelper = (path) => {
112804
+ const child = spawn([path], {
112805
+ stdin: "pipe",
112806
+ stdout: "pipe",
112807
+ stderr: "ignore",
112808
+ detached: true,
112809
+ env: process.env.HOME === undefined ? {} : { HOME: process.env.HOME }
112810
+ });
112811
+ const pid = child.pid;
112812
+ if (pid === undefined)
112813
+ throw new HelperProtocolError("The keychain helper did not start.");
112814
+ const stdin = child.stdin;
112815
+ return {
112816
+ pid,
112817
+ send: (line) => {
112818
+ stdin.write(line);
112819
+ if (isFlushable(stdin))
112820
+ stdin.flush();
112821
+ },
112822
+ reply: firstLine(child.stdout),
112823
+ close: () => {
112824
+ stdin.end();
112825
+ }
112826
+ };
112664
112827
  };
112665
- var probeSecretServiceLock = () => new Promise((resolve) => {
112666
- const child = spawn5("gdbus", [
112667
- "call",
112668
- "--session",
112669
- "--dest",
112670
- "org.freedesktop.secrets",
112671
- "--object-path",
112672
- DEFAULT_COLLECTION,
112673
- "--method",
112674
- "org.freedesktop.DBus.Properties.Get",
112675
- "org.freedesktop.Secret.Collection",
112676
- "Locked"
112677
- ], { stdio: ["ignore", "pipe", "ignore"] });
112678
- let stdout = "";
112679
- const timer = setTimeout(() => {
112680
- child.kill();
112681
- resolve("unknown");
112682
- }, PROBE_TIMEOUT_MS2);
112683
- child.stdout.on("data", (chunk) => {
112684
- stdout += chunk.toString();
112828
+ async function callHelper(path, call, options = {}) {
112829
+ const mutates = MUTATING.has(call.verb);
112830
+ if (mutates && options.lease === undefined)
112831
+ throw new HelperProtocolError(`The ${call.verb} helper call needs the session lock.`);
112832
+ const helper = (options.spawn ?? spawnDetachedHelper)(path);
112833
+ let handedOver = false;
112834
+ try {
112835
+ if (mutates && options.lease !== undefined) {
112836
+ await options.lease.handOver(helper.pid);
112837
+ handedOver = true;
112838
+ }
112839
+ helper.send(`${JSON.stringify({ v: 1, verb: call.verb, account: call.account, ...call.value === undefined ? {} : { value: call.value } })}
112840
+ `);
112841
+ const line = await helper.reply;
112842
+ if (handedOver && options.lease !== undefined) {
112843
+ handedOver = false;
112844
+ await options.lease.restore();
112845
+ }
112846
+ if (line === null)
112847
+ throw new HelperProtocolError(`The keychain helper exited without answering ${call.verb}.`);
112848
+ let json;
112849
+ try {
112850
+ json = JSON.parse(line);
112851
+ } catch {
112852
+ throw new HelperProtocolError(`The keychain helper sent a ${call.verb} reply that is not JSON.`);
112853
+ }
112854
+ const parsed = helperReplySchema.safeParse(json);
112855
+ if (!parsed.success)
112856
+ throw new HelperProtocolError(`The keychain helper sent an unexpected ${call.verb} reply.`);
112857
+ return parsed.data;
112858
+ } catch (error) {
112859
+ if (handedOver && options.lease !== undefined) {
112860
+ try {
112861
+ await options.lease.restore();
112862
+ } catch (restoreError) {
112863
+ throw new AggregateError([error, restoreError], `The ${call.verb} helper call failed and the session lock could not be restored.`);
112864
+ }
112865
+ }
112866
+ throw error;
112867
+ } finally {
112868
+ helper.close();
112869
+ }
112870
+ }
112871
+
112872
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/location.ts
112873
+ import { dirname as dirname42, join as join106, posix as posix13 } from "path";
112874
+ import { fileURLToPath as fileURLToPath8 } from "url";
112875
+ function bundleCandidates(moduleUrl) {
112876
+ const root = dirname42(dirname42(dirname42(fileURLToPath8(moduleUrl))));
112877
+ return [join106(root, "bin", "darwin", "omo-keychain"), join106(root, "omo-keychain")];
112878
+ }
112879
+ function machineCandidates(home, arch = process.arch) {
112880
+ const runtimeArch = arch === "arm64" ? "arm64" : "x64";
112881
+ return [
112882
+ `/Applications/OmO.app/Contents/Resources/omo-runtime/darwin-${runtimeArch}/omo-keychain`,
112883
+ posix13.join(home, "Applications", "OmO.app", "Contents", "Resources", "omo-runtime", `darwin-${runtimeArch}`, "omo-keychain"),
112884
+ posix13.join(home, ".bun", "install", "global", "node_modules", "omo-ai", "bin", "darwin", "omo-keychain")
112885
+ ];
112886
+ }
112887
+ async function locateHelper(candidates, verify) {
112888
+ const rejected = [];
112889
+ for (const path of candidates) {
112890
+ const verdict = await verify(path);
112891
+ if (verdict === "valid")
112892
+ return { kind: "found", path };
112893
+ if (verdict === "invalid")
112894
+ rejected.push(path);
112895
+ }
112896
+ return rejected.length === 0 ? { kind: "missing" } : { kind: "invalid", rejected };
112897
+ }
112898
+
112899
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/pin.ts
112900
+ import { readdirSync as readdirSync14, rmSync as rmSync9 } from "fs";
112901
+ import { chmod as chmod2, copyFile as copyFile4, constants as constants13, mkdtemp as mkdtemp2, rm as rm16, stat as stat8 } from "fs/promises";
112902
+ import { tmpdir as tmpdir6 } from "os";
112903
+ import { basename as basename15, join as join107 } from "path";
112904
+ var DIR_PREFIX = "omo-keychain-";
112905
+ var OWNED_DIR = new RegExp(`^${DIR_PREFIX}(\\d+)-`);
112906
+ var isAlive = (pid) => {
112907
+ try {
112908
+ process.kill(pid, 0);
112909
+ return true;
112910
+ } catch (error) {
112911
+ return !(error instanceof Error && ("code" in error) && error.code === "ESRCH");
112912
+ }
112913
+ };
112914
+ function sweepDeadPinDirs(root = tmpdir6()) {
112915
+ const removed = [];
112916
+ let entries;
112917
+ try {
112918
+ entries = readdirSync14(root);
112919
+ } catch {
112920
+ return removed;
112921
+ }
112922
+ for (const entry of entries) {
112923
+ const owner = OWNED_DIR.exec(entry)?.[1];
112924
+ if (owner === undefined || Number(owner) === process.pid || isAlive(Number(owner)))
112925
+ continue;
112926
+ try {
112927
+ rmSync9(join107(root, entry), { recursive: true, force: true });
112928
+ } catch {
112929
+ continue;
112930
+ }
112931
+ removed.push(entry);
112932
+ }
112933
+ return removed;
112934
+ }
112935
+ var processDir;
112936
+ async function processPinDir() {
112937
+ if (processDir !== undefined)
112938
+ return processDir;
112939
+ sweepDeadPinDirs();
112940
+ const dir = await mkdtemp2(join107(tmpdir6(), `${DIR_PREFIX}${process.pid}-`));
112941
+ process.once("exit", () => rmSync9(dir, { recursive: true, force: true }));
112942
+ processDir = dir;
112943
+ return dir;
112944
+ }
112945
+ var pinned = new Map;
112946
+ async function sourceIdentity(source) {
112947
+ const info = await stat8(source);
112948
+ return `${source}\x00${info.dev}\x00${info.ino}\x00${info.size}\x00${info.mtimeMs}\x00${info.ctimeMs}`;
112949
+ }
112950
+ async function copyAndVerify(source, verify, dir) {
112951
+ const target = join107(dir, `${crypto.randomUUID()}-${basename15(source)}`);
112952
+ try {
112953
+ await copyFile4(source, target, constants13.COPYFILE_EXCL);
112954
+ await chmod2(target, 320);
112955
+ } catch (error) {
112956
+ await rm16(target, { force: true });
112957
+ return { kind: "unavailable", reason: error instanceof Error ? error.message : String(error) };
112958
+ }
112959
+ let verdict;
112960
+ try {
112961
+ verdict = await verify(target);
112962
+ } catch (error) {
112963
+ await rm16(target, { force: true });
112964
+ return { kind: "unavailable", reason: error instanceof Error ? error.message : String(error) };
112965
+ }
112966
+ if (verdict === "valid")
112967
+ return { kind: "pinned", path: target };
112968
+ await rm16(target, { force: true });
112969
+ return { kind: "invalid" };
112970
+ }
112971
+ async function pinVerifiedCopy(source, verify, dir) {
112972
+ let identity;
112973
+ try {
112974
+ identity = `${dir ?? ""}\x00${await sourceIdentity(source)}`;
112975
+ } catch (error) {
112976
+ return { kind: "unavailable", reason: error instanceof Error ? error.message : String(error) };
112977
+ }
112978
+ const known = pinned.get(identity);
112979
+ if (known !== undefined) {
112980
+ const result = await known;
112981
+ if (result.kind !== "pinned")
112982
+ return result;
112983
+ let verdict;
112984
+ try {
112985
+ verdict = await verify(result.path);
112986
+ } catch (error) {
112987
+ pinned.delete(identity);
112988
+ await rm16(result.path, { force: true });
112989
+ return { kind: "unavailable", reason: error instanceof Error ? error.message : String(error) };
112990
+ }
112991
+ if (verdict === "valid")
112992
+ return result;
112993
+ }
112994
+ const created = Promise.resolve(dir ?? processPinDir()).then((target) => copyAndVerify(source, verify, target), (error) => ({ kind: "unavailable", reason: error instanceof Error ? error.message : String(error) }));
112995
+ pinned.set(identity, created);
112996
+ const result = await created;
112997
+ if (result.kind !== "pinned")
112998
+ pinned.delete(identity);
112999
+ return result;
113000
+ }
113001
+
113002
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/signature.ts
113003
+ import { stat as stat9 } from "fs/promises";
113004
+ init_bun_spawn_shim();
113005
+ var KEYCHAIN_HELPER_REQUIREMENT = 'identifier "com.mengmota.omo-keychain-helper" and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] ' + 'and certificate leaf[field.1.2.840.113635.100.6.1.13] and certificate leaf[subject.OU] = "523JNR86LZ"';
113006
+ var STRICT_ALL_ARCHITECTURES = 1 << 4 | 1 << 0;
113007
+ var UTF8 = 134217984;
113008
+ var security;
113009
+ async function loadSecurity() {
113010
+ if (security !== undefined)
113011
+ return security;
113012
+ try {
113013
+ const { dlopen, FFIType, ptr } = await loadBunFfi();
113014
+ const cf = dlopen("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation", {
113015
+ CFStringCreateWithCString: { args: [FFIType.u64, FFIType.ptr, FFIType.u32], returns: FFIType.u64 },
113016
+ CFURLCreateFromFileSystemRepresentation: { args: [FFIType.u64, FFIType.ptr, FFIType.i64, FFIType.bool], returns: FFIType.u64 },
113017
+ CFRelease: { args: [FFIType.u64], returns: FFIType.void }
113018
+ });
113019
+ const sec = dlopen("/System/Library/Frameworks/Security.framework/Security", {
113020
+ SecStaticCodeCreateWithPath: { args: [FFIType.u64, FFIType.u32, FFIType.ptr], returns: FFIType.i32 },
113021
+ SecRequirementCreateWithString: { args: [FFIType.u64, FFIType.u32, FFIType.ptr], returns: FFIType.i32 },
113022
+ SecStaticCodeCheckValidityWithErrors: { args: [FFIType.u64, FFIType.u32, FFIType.u64, FFIType.u64], returns: FFIType.i32 }
113023
+ });
113024
+ const cString = (text) => Buffer.from(`${text}\x00`, "utf8");
113025
+ security = {
113026
+ check(path, requirement) {
113027
+ const pathBytes = Buffer.from(path, "utf8");
113028
+ const url = BigInt(cf.symbols.CFURLCreateFromFileSystemRepresentation(0n, ptr(pathBytes), pathBytes.length, false));
113029
+ const text = BigInt(cf.symbols.CFStringCreateWithCString(0n, ptr(cString(requirement)), UTF8));
113030
+ const codeOut = new BigUint64Array(1);
113031
+ const requirementOut = new BigUint64Array(1);
113032
+ try {
113033
+ if (url === 0n || text === 0n)
113034
+ return false;
113035
+ if (sec.symbols.SecStaticCodeCreateWithPath(url, 0, ptr(codeOut)) !== 0)
113036
+ return false;
113037
+ if (sec.symbols.SecRequirementCreateWithString(text, 0, ptr(requirementOut)) !== 0)
113038
+ return false;
113039
+ const code = codeOut[0] ?? 0n;
113040
+ const designated = requirementOut[0] ?? 0n;
113041
+ return sec.symbols.SecStaticCodeCheckValidityWithErrors(code, STRICT_ALL_ARCHITECTURES, designated, 0n) === 0;
113042
+ } finally {
113043
+ for (const ref of [url, text, codeOut[0] ?? 0n, requirementOut[0] ?? 0n])
113044
+ if (ref !== 0n)
113045
+ cf.symbols.CFRelease(ref);
113046
+ }
113047
+ }
113048
+ };
113049
+ } catch {
113050
+ security = null;
113051
+ }
113052
+ return security;
113053
+ }
113054
+ async function verifyWithCodesign(path, requirement) {
113055
+ const child = spawn(["/usr/bin/codesign", "--verify", "--strict", `-R=${requirement}`, path], {
113056
+ stdout: "ignore",
113057
+ stderr: "ignore",
113058
+ env: {}
112685
113059
  });
112686
- child.on("error", () => {
112687
- clearTimeout(timer);
112688
- resolve("unknown");
113060
+ return await child.exited === 0;
113061
+ }
113062
+ var verifyWithSecurityFramework = async (path, requirement) => {
113063
+ const loaded = await loadSecurity();
113064
+ return loaded === null ? verifyWithCodesign(path, requirement) : loaded.check(path, requirement);
113065
+ };
113066
+ async function fileIdentity(path) {
113067
+ try {
113068
+ const info = await stat9(path);
113069
+ if (!info.isFile())
113070
+ return null;
113071
+ return `${path}\x00${info.dev}\x00${info.ino}\x00${info.size}\x00${info.mtimeMs}\x00${info.ctimeMs}`;
113072
+ } catch {
113073
+ return null;
113074
+ }
113075
+ }
113076
+ function createSignatureChecker(check = verifyWithSecurityFramework, requirement = KEYCHAIN_HELPER_REQUIREMENT) {
113077
+ const verdicts = new Map;
113078
+ const checker = async (path) => {
113079
+ const before = await fileIdentity(path);
113080
+ if (before === null)
113081
+ return "missing";
113082
+ const known = verdicts.get(before);
113083
+ if (known !== undefined)
113084
+ return known;
113085
+ const passed = await check(path, requirement);
113086
+ if (await fileIdentity(path) !== before)
113087
+ return "invalid";
113088
+ const verdict = passed ? "valid" : "invalid";
113089
+ verdicts.set(before, verdict);
113090
+ return verdict;
113091
+ };
113092
+ return checker;
113093
+ }
113094
+ var processChecker;
113095
+ var processSignatureChecker = () => processChecker ??= createSignatureChecker();
113096
+
113097
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/access.ts
113098
+ async function resolveHelperAccess(candidates, options = {}) {
113099
+ const verify = options.verify ?? processSignatureChecker();
113100
+ let source;
113101
+ let pin;
113102
+ try {
113103
+ const location = await locateHelper(candidates, verify);
113104
+ if (location.kind !== "found")
113105
+ return location;
113106
+ source = location.path;
113107
+ pin = await (options.pin ?? pinVerifiedCopy)(source, verify);
113108
+ } catch (error) {
113109
+ return { kind: "unavailable", reason: error instanceof Error ? error.message : String(error) };
113110
+ }
113111
+ if (pin.kind === "invalid")
113112
+ return { kind: "invalid", rejected: [source] };
113113
+ if (pin.kind === "unavailable")
113114
+ return { kind: "unavailable", reason: pin.reason };
113115
+ const pinned = pin.path;
113116
+ const spawn = options.spawn ?? spawnDetachedHelper;
113117
+ return {
113118
+ kind: "ready",
113119
+ path: pinned,
113120
+ call: async (call, lease) => {
113121
+ const verdict = await verify(pinned).catch((error) => {
113122
+ throw new HelperProtocolError(`OmO's keychain helper could not be checked before it ran: ${error instanceof Error ? error.message : String(error)}`);
113123
+ });
113124
+ if (verdict !== "valid")
113125
+ throw new HelperProtocolError("OmO's keychain helper changed on disk and failed its signature check; it was not run.");
113126
+ return callHelper(pinned, call, { spawn, ...lease === undefined ? {} : { lease } });
113127
+ }
113128
+ };
113129
+ }
113130
+
113131
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/approval-cache.ts
113132
+ var systemClock = { nowSeconds: () => Date.now() / 1000, sleepMs: (ms) => new Promise((resolve) => setTimeout(resolve, ms)) };
113133
+ function isEntryValid(entry, current, nowSeconds) {
113134
+ if (nowSeconds < entry.readStartedAt)
113135
+ return false;
113136
+ return current.cdat === entry.cdat && current.mdat === entry.mdat && Math.floor(current.mdat) < Math.floor(entry.readStartedAt);
113137
+ }
113138
+ function createApprovalCache(clock = systemClock) {
113139
+ let entry = null;
113140
+ let deniedForBackground = false;
113141
+ let pending = null;
113142
+ return {
113143
+ consume(current) {
113144
+ if (entry === null)
113145
+ return null;
113146
+ if (!isEntryValid(entry, current, clock.nowSeconds())) {
113147
+ entry = null;
113148
+ return null;
113149
+ }
113150
+ return entry.value;
113151
+ },
113152
+ deniedForBackground: () => deniedForBackground,
113153
+ inFlight: () => pending,
113154
+ approve(run) {
113155
+ if (pending !== null)
113156
+ return pending;
113157
+ const readStartedAt = clock.nowSeconds();
113158
+ const started = run().then((answer) => {
113159
+ if (answer.kind === "approved") {
113160
+ entry = { value: answer.value, ...answer.attributes, readStartedAt };
113161
+ deniedForBackground = false;
113162
+ } else if (answer.kind === "denied")
113163
+ deniedForBackground = true;
113164
+ return answer;
113165
+ });
113166
+ const settled = () => {
113167
+ if (pending === started)
113168
+ pending = null;
113169
+ };
113170
+ started.then(settled, settled);
113171
+ pending = started;
113172
+ return started;
113173
+ },
113174
+ async afterOwnWrite(value, readAttributes) {
113175
+ if (entry === null)
113176
+ return;
113177
+ const written = await readAttributes();
113178
+ if (written === null) {
113179
+ entry = null;
113180
+ return;
113181
+ }
113182
+ while (Math.floor(clock.nowSeconds()) <= Math.floor(written.mdat)) {
113183
+ await clock.sleepMs(Math.max(1, Math.ceil((Math.floor(written.mdat) + 1 - clock.nowSeconds()) * 1000)));
113184
+ }
113185
+ const readStartedAt = clock.nowSeconds();
113186
+ const fresh = await readAttributes();
113187
+ entry = fresh === null ? null : { value, ...fresh, readStartedAt };
113188
+ },
113189
+ drop() {
113190
+ entry = null;
113191
+ }
113192
+ };
113193
+ }
113194
+ var processApprovalCache = () => {
113195
+ const state = keychainProcessState();
113196
+ state.approvalCache ??= createApprovalCache();
113197
+ return state.approvalCache;
113198
+ };
113199
+
113200
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/darwin-read.ts
113201
+ var ROW_8B_DEFAULT = "re-login";
113202
+
113203
+ class HelperReadError extends Error {
113204
+ failure;
113205
+ constructor(failure, message) {
113206
+ super(message);
113207
+ this.failure = failure;
113208
+ }
113209
+ }
113210
+ function failure2(reply) {
113211
+ if (reply.error === "locked")
113212
+ return new HelperReadError("locked", "The keychain is locked.");
113213
+ return new HelperReadError("store", `The keychain helper answered ${reply.error ?? "unexpectedly"}.`);
113214
+ }
113215
+ async function approveOnce(deps) {
113216
+ const running = deps.cache.inFlight();
113217
+ if (running !== null)
113218
+ return running;
113219
+ const release = await deps.takePromptLock();
113220
+ if (release === null)
113221
+ throw new HelperReadError("pending", "Another omo process is waiting for your keychain approval.");
113222
+ try {
113223
+ return await deps.cache.approve(async () => {
113224
+ const reply = await deps.access.call({ verb: "approve", account: deps.account });
113225
+ if (reply.missing === true)
113226
+ return { kind: "missing" };
113227
+ if (reply.error === "denied")
113228
+ return { kind: "denied" };
113229
+ if (reply.error !== undefined || reply.value === undefined || reply.cdat === undefined || reply.mdat === undefined)
113230
+ throw failure2(reply);
113231
+ return { kind: "approved", value: reply.value, attributes: { cdat: reply.cdat, mdat: reply.mdat } };
113232
+ });
113233
+ } finally {
113234
+ await release();
113235
+ }
113236
+ }
113237
+ async function readThroughHelper(deps, allowPrompt) {
113238
+ const reply = await deps.access.call({ verb: "read", account: deps.account });
113239
+ if (reply.error !== undefined)
113240
+ throw failure2(reply);
113241
+ if (reply.missing === true)
113242
+ return { kind: "missing", reply };
113243
+ if (reply.owned === true && reply.value !== undefined)
113244
+ return { kind: "value", value: reply.value, source: reply.marker === true || reply.recover === true ? "owned" : "owned-unmarked", reply };
113245
+ const own = await deps.ownSilentGet().catch(() => {
113246
+ return;
112689
113247
  });
112690
- child.on("close", (code) => {
112691
- clearTimeout(timer);
112692
- resolve(code === 0 ? parseLockedReply(stdout) ?? "absent" : "absent");
113248
+ if (typeof own === "string")
113249
+ return { kind: "value", value: own, source: "own-identity", reply };
113250
+ if (reply.cdat === undefined || reply.mdat === undefined)
113251
+ throw failure2(reply);
113252
+ const cached = deps.cache.consume({ cdat: reply.cdat, mdat: reply.mdat });
113253
+ if (cached !== null)
113254
+ return { kind: "value", value: cached, source: "approved", reply };
113255
+ const reloginInstead = reply.partition !== "ours" && reply.partition !== "none" && (deps.row8b ?? ROW_8B_DEFAULT) === "re-login";
113256
+ if (!allowPrompt) {
113257
+ if (reloginInstead)
113258
+ return { kind: "missing", reply };
113259
+ throw new HelperReadError("pending", "The keychain needs your approval; run an omo command in a terminal.");
113260
+ }
113261
+ if (deps.background && deps.cache.deniedForBackground())
113262
+ throw new HelperReadError("pending", "Keychain access was denied; run an omo command in a terminal to approve it.");
113263
+ if (reloginInstead)
113264
+ return { kind: "missing", reply };
113265
+ if (deps.noDialog === true)
113266
+ throw new HelperReadError("pending", "The keychain hand-off cannot show a dialog.");
113267
+ if (deps.handOff !== undefined && await deps.handOff()) {
113268
+ const after = await deps.access.call({ verb: "read", account: deps.account });
113269
+ if (after.owned === true && after.value !== undefined)
113270
+ return { kind: "value", value: after.value, source: "owned", reply: after };
113271
+ }
113272
+ const answer = await approveOnce(deps);
113273
+ if (answer.kind === "approved")
113274
+ return { kind: "value", value: answer.value, source: "approved", reply };
113275
+ if (answer.kind === "missing")
113276
+ return { kind: "missing", reply };
113277
+ throw new HelperReadError("denied", "Keychain access was denied.");
113278
+ }
113279
+
113280
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/recovery.ts
113281
+ var OLD_SLOT_COUNT = 8;
113282
+ var oldSlotName = (account, slot) => slot === 0 ? `${account}.old` : `${account}.old.${slot}`;
113283
+ function recoveryPlan(names) {
113284
+ if (!names.original && names.staging)
113285
+ return names.old ? ["promote", "delete-old"] : ["promote"];
113286
+ if (!names.original && names.old)
113287
+ return ["delete-old"];
113288
+ if (names.original && names.staging)
113289
+ return names.old ? ["remove-staging", "delete-old"] : ["remove-staging"];
113290
+ if (names.original && names.old)
113291
+ return ["delete-old"];
113292
+ return [];
113293
+ }
113294
+ function oldSlotsOf(reply) {
113295
+ return reply.present?.oldSlots ?? (reply.present?.old === true ? [0] : []);
113296
+ }
113297
+ function namesFromRead(reply) {
113298
+ const original = reply.owned === false || reply.owned === true && reply.recover !== true;
113299
+ return { original, staging: reply.present?.staging === true, old: reply.present?.old === true, oldSlots: oldSlotsOf(reply) };
113300
+ }
113301
+ async function deleteOld(name, helper, deleteOwn) {
113302
+ const removed = await helper({ verb: "remove", account: name }).catch(() => null);
113303
+ if (removed?.ok === true)
113304
+ return true;
113305
+ return deleteOwn(name).catch(() => false);
113306
+ }
113307
+ async function deleteOldSlots(account, slots, helper, deleteOwn) {
113308
+ let cleared = true;
113309
+ for (const slot of slots)
113310
+ if (!await deleteOld(oldSlotName(account, slot), helper, deleteOwn))
113311
+ cleared = false;
113312
+ return cleared;
113313
+ }
113314
+ async function runRecovery(account, names, helper, deleteOwnOld) {
113315
+ const applied = [];
113316
+ for (const step of recoveryPlan(names)) {
113317
+ const ok = step === "promote" ? (await helper({ verb: "promote", account })).ok === true : step === "remove-staging" ? (await helper({ verb: "remove", account: `${account}.staging` })).ok === true : await deleteOldSlots(account, names.oldSlots, helper, deleteOwnOld);
113318
+ if (!ok && step !== "delete-old")
113319
+ return { applied, failed: step };
113320
+ if (ok)
113321
+ applied.push(step);
113322
+ }
113323
+ return { applied, failed: null };
113324
+ }
113325
+
113326
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/migration.ts
113327
+ var MIGRATABLE = new Set(["own-identity", "owned-unmarked", "approved"]);
113328
+ async function migrate(account, value, source, helper, deleteOwnOld) {
113329
+ if (!MIGRATABLE.has(source))
113330
+ return { kind: "skipped", reason: "not-migratable" };
113331
+ if ((await helper({ verb: "stage", account, value })).ok !== true)
113332
+ return { kind: "failed", step: "stage" };
113333
+ const retired = await helper({ verb: "retire", account });
113334
+ if (retired.error === "exists" && retired.reason === "old-slots-full" || retired.ok === true && retired.skipped === true) {
113335
+ await helper({ verb: "remove", account: `${account}.staging` });
113336
+ return { kind: "skipped", reason: "old-slots-full" };
113337
+ }
113338
+ if (retired.ok !== true)
113339
+ return { kind: "failed", step: "retire" };
113340
+ const slot = retired.slot ?? 0;
113341
+ if ((await helper({ verb: "promote", account })).ok !== true)
113342
+ return { kind: "failed", step: "promote" };
113343
+ return { kind: "migrated", oldDeleted: await deleteOld(oldSlotName(account, slot), helper, deleteOwnOld) };
113344
+ }
113345
+
113346
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/darwin-store.ts
113347
+ class HelperOldSlotsFull extends Error {
113348
+ }
113349
+ var ALL_OLD_SLOTS = Array.from({ length: OLD_SLOT_COUNT }, (_, slot) => slot);
113350
+ var OLD_SLOTS_FULL_MESSAGE = 'The macOS keychain holds 8 earlier OmO sign-ins that cannot be removed automatically. Open Keychain Access, delete the items whose account name ends in ".old" or ".old.1" to ".old.7" for OmO, then sign in again.';
113351
+ var failed = (reply, verb) => new HelperReadError(reply.error === "locked" ? "locked" : "store", `The keychain helper could not ${verb} the sign-in (${reply.error ?? "no answer"}).`);
113352
+ function lockedDarwinStore(deps, lease) {
113353
+ const helper = (call) => deps.access.call(call, lease);
113354
+ const deleteOwnOld = (name) => deps.ownDelete(name);
113355
+ let lastRead = null;
113356
+ const read = async () => {
113357
+ const result = await readThroughHelper(deps, false);
113358
+ lastRead = result.kind === "value" ? result : null;
113359
+ return result.kind === "value" ? result.value : null;
113360
+ };
113361
+ return {
113362
+ async recover() {
113363
+ const reply = await deps.access.call({ verb: "read", account: deps.account });
113364
+ if (reply.error === undefined)
113365
+ await runRecovery(deps.account, namesFromRead(reply), helper, deleteOwnOld);
113366
+ },
113367
+ read,
113368
+ async settle() {
113369
+ if (lastRead === null)
113370
+ return;
113371
+ const outcome = await migrate(deps.account, lastRead.value, lastRead.source, helper, deleteOwnOld);
113372
+ if (outcome.kind === "skipped" && outcome.reason === "old-slots-full")
113373
+ deps.notice(`omo: ${OLD_SLOTS_FULL_MESSAGE}`);
113374
+ if (outcome.kind === "failed")
113375
+ deps.notice(`omo: the macOS keychain item could not be moved to OmO's keychain helper (${outcome.step}); it keeps working as before.`);
113376
+ },
113377
+ async write(value, intent, beforeRetire) {
113378
+ const state = await deps.access.call({ verb: "read", account: deps.account });
113379
+ if (state.error !== undefined)
113380
+ throw failed(state, "check");
113381
+ if (state.owned === false) {
113382
+ const approved = state.cdat !== undefined && state.mdat !== undefined && deps.cache.consume({ cdat: state.cdat, mdat: state.mdat }) !== null;
113383
+ const readable = lastRead !== null || approved || await deps.ownSilentGet().catch(() => {
113384
+ return;
113385
+ }) !== undefined;
113386
+ if (readable || intent !== "fresh-sign-in") {
113387
+ await deps.ownOverwrite(value);
113388
+ if (lastRead?.source === "approved")
113389
+ await deps.cache.afterOwnWrite(value, async () => {
113390
+ const after = await deps.access.call({ verb: "read", account: deps.account });
113391
+ return after.cdat === undefined || after.mdat === undefined ? null : { cdat: after.cdat, mdat: after.mdat };
113392
+ });
113393
+ return;
113394
+ }
113395
+ await beforeRetire?.();
113396
+ const retired = await helper({ verb: "retire", account: deps.account });
113397
+ if (retired.reason === "old-slots-full" || retired.ok === true && retired.skipped === true)
113398
+ throw new HelperOldSlotsFull(OLD_SLOTS_FULL_MESSAGE);
113399
+ if (retired.ok !== true)
113400
+ throw failed(retired, "replace");
113401
+ }
113402
+ const written = await helper({ verb: "write", account: deps.account, value });
113403
+ if (written.ok !== true)
113404
+ throw failed(written, "save");
113405
+ lastRead = { kind: "value", value, source: "owned", reply: written };
113406
+ },
113407
+ async clear() {
113408
+ const removed = await helper({ verb: "remove", account: deps.account });
113409
+ if (removed.error === "not-owned")
113410
+ await deps.ownDelete(deps.account);
113411
+ else if (removed.ok !== true)
113412
+ throw failed(removed, "remove");
113413
+ await helper({ verb: "remove", account: `${deps.account}.staging` });
113414
+ const present = await helper({ verb: "read", account: deps.account });
113415
+ const slots = present.error === undefined ? oldSlotsOf(present) : ALL_OLD_SLOTS;
113416
+ await deleteOldSlots(deps.account, slots, helper, deleteOwnOld);
113417
+ lastRead = null;
113418
+ }
113419
+ };
113420
+ }
113421
+
113422
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/owner-marker.ts
113423
+ init_bun_spawn_shim();
113424
+ var MARKER_LINE = /^\s*"gena"<blob>="omo-owner\/1"\s*$/m;
113425
+ var ITEM_NOT_FOUND = 44;
113426
+ var probeOwnerMarker = async (service, account, keychain) => {
113427
+ const args = ["find-generic-password", "-s", service, "-a", account, ...keychain === undefined ? [] : [keychain]];
113428
+ const child = spawn(["/usr/bin/security", ...args], {
113429
+ stdout: "pipe",
113430
+ stderr: "ignore",
113431
+ env: process.env.HOME === undefined ? {} : { HOME: process.env.HOME }
112693
113432
  });
112694
- });
113433
+ const [stdout, code] = await Promise.all([new Response(child.stdout).text(), child.exited]);
113434
+ if (code === ITEM_NOT_FOUND)
113435
+ return "absent";
113436
+ if (code !== 0)
113437
+ return "unknown";
113438
+ return MARKER_LINE.test(stdout) ? "helper-owned" : "other";
113439
+ };
112695
113440
 
112696
- // packages/omo-opencode/src/cli/service-auth/credential-lock.ts
112697
- import { AsyncLocalStorage as AsyncLocalStorage3 } from "async_hooks";
112698
- import { createHash as createHash11 } from "crypto";
113441
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/prompt-lock.ts
112699
113442
  import { mkdir as mkdir11 } from "fs/promises";
112700
- import { homedir as homedir31 } from "os";
112701
- import { join as join106 } from "path";
113443
+ import { dirname as dirname45 } from "path";
112702
113444
 
112703
113445
  // packages/team-core/src/team-state-store/lock-publish.ts
112704
- import { access as access4, open as open3, unlink as unlink3 } from "fs/promises";
112705
- import { dirname as dirname42 } from "path";
113446
+ import { access as access5, open as open3, unlink as unlink4 } from "fs/promises";
113447
+ import { dirname as dirname43 } from "path";
112706
113448
 
112707
113449
  // packages/team-core/src/team-state-store/lock-record.ts
112708
113450
  import { randomUUID as randomUUID6 } from "crypto";
112709
- import { readFile as readFile34, stat as stat9 } from "fs/promises";
113451
+ import { readFile as readFile35, stat as stat11 } from "fs/promises";
112710
113452
 
112711
113453
  // packages/memory-core/src/locks/process-identity.ts
112712
113454
  import { execFile as execFile7 } from "child_process";
@@ -112804,23 +113546,23 @@ function rename8(from, to, admit) {
112804
113546
  }
112805
113547
  var sync = resilientNamespace(fsSync, "sync");
112806
113548
  var {
112807
- access: access3,
112808
- chmod: chmod2,
112809
- copyFile: copyFile4,
113549
+ access: access4,
113550
+ chmod: chmod3,
113551
+ copyFile: copyFile5,
112810
113552
  cp: cp5,
112811
113553
  link,
112812
113554
  lstat: lstat18,
112813
113555
  mkdir: mkdir10,
112814
- mkdtemp: mkdtemp2,
112815
- readFile: readFile33,
113556
+ mkdtemp: mkdtemp3,
113557
+ readFile: readFile34,
112816
113558
  readdir: readdir17,
112817
113559
  readlink: readlink7,
112818
113560
  realpath: realpath2,
112819
- rm: rm16,
113561
+ rm: rm17,
112820
113562
  rmdir: rmdir2,
112821
- stat: stat8,
113563
+ stat: stat10,
112822
113564
  statfs,
112823
- unlink: unlink2
113565
+ unlink: unlink3
112824
113566
  } = promises;
112825
113567
  var {
112826
113568
  accessSync: accessSync5,
@@ -112830,7 +113572,7 @@ var {
112830
113572
  lstatSync: lstatSync5,
112831
113573
  mkdirSync: mkdirSync19,
112832
113574
  readFileSync: readFileSync44,
112833
- readdirSync: readdirSync14,
113575
+ readdirSync: readdirSync15,
112834
113576
  realpathSync: realpathSync13,
112835
113577
  statSync: statSync8,
112836
113578
  unlinkSync: unlinkSync10,
@@ -112943,7 +113685,7 @@ async function execFileText(command, args) {
112943
113685
  }
112944
113686
  async function readLinuxStartIdentity(pid) {
112945
113687
  try {
112946
- const stat = await readFile33(`/proc/${pid}/stat`, "utf8");
113688
+ const stat = await readFile34(`/proc/${pid}/stat`, "utf8");
112947
113689
  const commandEnd = stat.lastIndexOf(")");
112948
113690
  if (commandEnd < 0)
112949
113691
  return null;
@@ -113182,14 +113924,17 @@ async function isWorkerLockReleased(incarnation, record) {
113182
113924
  // packages/team-core/src/team-state-store/lock-record.ts
113183
113925
  async function buildLockRecord(ownerTag) {
113184
113926
  await registerLockWorker();
113185
- const processStart = await getProcessStartIdentity(process.pid);
113927
+ const processStart = await lockProcessStartLine(process.pid);
113186
113928
  return `${ownerTag} ${randomUUID6()}
113187
113929
  ${process.pid}
113188
113930
  ${Date.now()}
113189
113931
  ${lockOwnerInstanceId}
113190
- ${processStart ?? "unavailable"}
113932
+ ${processStart}
113191
113933
  `;
113192
113934
  }
113935
+ async function lockProcessStartLine(pid) {
113936
+ return await getProcessStartIdentity(pid) ?? "unavailable";
113937
+ }
113193
113938
  function errorCode2(error) {
113194
113939
  if (!(error instanceof Error) || !("code" in error))
113195
113940
  return null;
@@ -113218,8 +113963,8 @@ function parseLockOwner(content) {
113218
113963
  }
113219
113964
  async function readLockRecord(lockPath) {
113220
113965
  try {
113221
- const content = await readFile34(lockPath, "utf8");
113222
- const { mtimeMs } = await stat9(lockPath);
113966
+ const content = await readFile35(lockPath, "utf8");
113967
+ const { mtimeMs } = await stat11(lockPath);
113223
113968
  return { content, modifiedAtEpochMs: mtimeMs };
113224
113969
  } catch (error) {
113225
113970
  if (!(error instanceof Error))
@@ -113250,7 +113995,7 @@ async function isLockRecordStale(record, staleAfterMs) {
113250
113995
 
113251
113996
  // packages/team-core/src/team-state-store/lock-publish.ts
113252
113997
  async function pathMayExist(path, deps = {}) {
113253
- const accessPath = deps.access ?? access4;
113998
+ const accessPath = deps.access ?? access5;
113254
113999
  try {
113255
114000
  await accessPath(path);
113256
114001
  return true;
@@ -113267,7 +114012,7 @@ async function assertRetryableLockOpenError(lockPath, error, deps) {
113267
114012
  if (code === "EPERM") {
113268
114013
  if (await pathMayExist(lockPath, deps))
113269
114014
  return;
113270
- if ((deps?.platform ?? process.platform) === "win32" && await pathMayExist(dirname42(lockPath), deps))
114015
+ if ((deps?.platform ?? process.platform) === "win32" && await pathMayExist(dirname43(lockPath), deps))
113271
114016
  return;
113272
114017
  }
113273
114018
  throw error;
@@ -113287,7 +114032,7 @@ async function publishLockRecord(lockPath, record) {
113287
114032
  } catch (error) {
113288
114033
  markLockRecordReleased(record);
113289
114034
  await fileHandle.close();
113290
- await unlink3(lockPath).catch(() => {
114035
+ await unlink4(lockPath).catch(() => {
113291
114036
  return;
113292
114037
  });
113293
114038
  throw error;
@@ -113296,9 +114041,14 @@ async function publishLockRecord(lockPath, record) {
113296
114041
  return true;
113297
114042
  }
113298
114043
 
114044
+ // packages/team-core/src/team-state-store/lock-lease.ts
114045
+ import { randomUUID as randomUUID7 } from "crypto";
114046
+ import { open as open4, readdir as readdir18, readFile as readFile36, rename as rename9, rm as rm18 } from "fs/promises";
114047
+ import { basename as basename16, dirname as dirname44, join as join108 } from "path";
114048
+
113299
114049
  // packages/team-core/src/team-state-store/lock-reclaim.ts
113300
114050
  import { createHash as createHash10 } from "crypto";
113301
- import { unlink as unlink4 } from "fs/promises";
114051
+ import { unlink as unlink5 } from "fs/promises";
113302
114052
  var RECLAIM_UNLINK_ATTEMPTS = 3;
113303
114053
  var RECLAIM_UNLINK_RETRY_MS = 25;
113304
114054
  function delay2(ms) {
@@ -113311,7 +114061,7 @@ function reclaimGuardPath(lockPath, record) {
113311
114061
  }
113312
114062
  async function unlinkWithRetry(path, deps) {
113313
114063
  const wait = deps.delay ?? delay2;
113314
- const unlinkFile = deps.unlink ?? unlink4;
114064
+ const unlinkFile = deps.unlink ?? unlink5;
113315
114065
  for (let attempt = 1;; attempt += 1) {
113316
114066
  try {
113317
114067
  await unlinkFile(path);
@@ -113329,6 +114079,19 @@ async function unlinkWithRetry(path, deps) {
113329
114079
  }
113330
114080
  }
113331
114081
  async function removeLockRecordIfUnchanged(lockPath, expectedRecord, staleAfterMs, deps = {}) {
114082
+ return withRecordGuard(lockPath, expectedRecord, staleAfterMs, deps, async () => {
114083
+ const current = await readLockRecord(lockPath);
114084
+ if (current === null)
114085
+ return "absent";
114086
+ if (current.content !== expectedRecord || !await isLockRecordStale(current, staleAfterMs))
114087
+ return "changed";
114088
+ const unlinked = await unlinkWithRetry(lockPath, deps);
114089
+ if (unlinked !== "stuck")
114090
+ forgetLockRecord(expectedRecord);
114091
+ return unlinked === "absent" ? "absent" : unlinked;
114092
+ });
114093
+ }
114094
+ async function withRecordGuard(lockPath, expectedRecord, staleAfterMs, deps, act) {
113332
114095
  const guardPath = reclaimGuardPath(lockPath, expectedRecord);
113333
114096
  const guardRecord = await buildLockRecord("lock-reclaim");
113334
114097
  if (!await publishLockRecord(guardPath, guardRecord)) {
@@ -113339,15 +114102,7 @@ async function removeLockRecordIfUnchanged(lockPath, expectedRecord, staleAfterM
113339
114102
  return "busy";
113340
114103
  }
113341
114104
  try {
113342
- const current = await readLockRecord(lockPath);
113343
- if (current === null)
113344
- return "absent";
113345
- if (current.content !== expectedRecord || !await isLockRecordStale(current, staleAfterMs))
113346
- return "changed";
113347
- const unlinked = await unlinkWithRetry(lockPath, deps);
113348
- if (unlinked !== "stuck")
113349
- forgetLockRecord(expectedRecord);
113350
- return unlinked === "absent" ? "absent" : unlinked;
114105
+ return await act();
113351
114106
  } finally {
113352
114107
  markLockRecordReleased(guardRecord);
113353
114108
  if (await unlinkWithRetry(guardPath, deps) !== "stuck")
@@ -113355,6 +114110,97 @@ async function removeLockRecordIfUnchanged(lockPath, expectedRecord, staleAfterM
113355
114110
  }
113356
114111
  }
113357
114112
 
114113
+ // packages/team-core/src/team-state-store/lock-lease.ts
114114
+ class LockLeaseLostError extends Error {
114115
+ constructor(lockPath) {
114116
+ super(`The lock at ${lockPath} changed while it was handed over; the critical section was aborted.`);
114117
+ this.name = "LockLeaseLostError";
114118
+ }
114119
+ }
114120
+ var leaseTempPrefix = (lockPath) => `.${basename16(lockPath)}.`;
114121
+ var LEASE_TEMP_SUFFIX = ".lease";
114122
+ var UUID2 = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}";
114123
+ var escapeRegExp2 = (text) => text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
114124
+ var leaseTempPattern = (lockPath) => new RegExp(`^\\.${escapeRegExp2(basename16(lockPath))}\\.${UUID2}\\.lease$`);
114125
+ async function replaceRecord(lockPath, content) {
114126
+ const temporary = join108(dirname44(lockPath), `${leaseTempPrefix(lockPath)}${randomUUID7()}${LEASE_TEMP_SUFFIX}`);
114127
+ try {
114128
+ const handle = await open4(temporary, "wx", 384);
114129
+ try {
114130
+ await handle.writeFile(content);
114131
+ } finally {
114132
+ await handle.close();
114133
+ }
114134
+ await rename9(temporary, lockPath);
114135
+ } catch (error) {
114136
+ await rm18(temporary, { force: true });
114137
+ throw error;
114138
+ }
114139
+ }
114140
+ async function removeLeftoverTemps(lockPath) {
114141
+ const pattern = leaseTempPattern(lockPath);
114142
+ let entries;
114143
+ try {
114144
+ entries = await readdir18(dirname44(lockPath));
114145
+ } catch (error) {
114146
+ if (error instanceof Error && "code" in error && error.code === "ENOENT")
114147
+ return;
114148
+ throw error;
114149
+ }
114150
+ for (const entry of entries) {
114151
+ if (pattern.test(entry))
114152
+ await rm18(join108(dirname44(lockPath), entry), { force: true });
114153
+ }
114154
+ }
114155
+ async function currentRecord(lockPath) {
114156
+ try {
114157
+ return await readFile36(lockPath, "utf8");
114158
+ } catch (error) {
114159
+ if (error instanceof Error && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR"))
114160
+ return null;
114161
+ throw error;
114162
+ }
114163
+ }
114164
+ function createLockLease(lockPath, ownerRecord, ownerTag, options = {}) {
114165
+ const staleAfterMs = options.staleAfterMs ?? Number.POSITIVE_INFINITY;
114166
+ let handedTo = null;
114167
+ return {
114168
+ async handOver(pid) {
114169
+ if (handedTo !== null)
114170
+ throw new Error("The lock is already handed over; restore it first.");
114171
+ if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid)
114172
+ throw new Error(`Cannot hand the lock to pid ${pid}.`);
114173
+ if (await currentRecord(lockPath) !== ownerRecord)
114174
+ throw new LockLeaseLostError(lockPath);
114175
+ await removeLeftoverTemps(lockPath);
114176
+ const processStart = await lockProcessStartLine(pid);
114177
+ const record = `${ownerTag} ${randomUUID7()}
114178
+ ${pid}
114179
+ ${Date.now()}
114180
+ ${randomUUID7()}
114181
+ ${processStart}
114182
+ `;
114183
+ await replaceRecord(lockPath, record);
114184
+ handedTo = record;
114185
+ },
114186
+ async restore() {
114187
+ if (handedTo === null)
114188
+ throw new Error("The lock is not handed over.");
114189
+ const expected = handedTo;
114190
+ handedTo = null;
114191
+ const outcome = await withRecordGuard(lockPath, expected, staleAfterMs, {}, async () => {
114192
+ if (await currentRecord(lockPath) !== expected)
114193
+ return "lost";
114194
+ await options.beforeRestoreRename?.();
114195
+ await replaceRecord(lockPath, ownerRecord);
114196
+ return "restored";
114197
+ });
114198
+ if (outcome !== "restored")
114199
+ throw new LockLeaseLostError(lockPath);
114200
+ }
114201
+ };
114202
+ }
114203
+
113358
114204
  // packages/team-core/src/team-state-store/locks.ts
113359
114205
  var LOCK_RETRY_MS = 50;
113360
114206
  var LOCK_WAIT_TIMEOUT_MS = 15000;
@@ -113384,7 +114230,7 @@ async function withLock(lockPath, fn, opts) {
113384
114230
  const ownerTag = opts?.ownerTag ?? "owner";
113385
114231
  const record = await acquireLock(lockPath, ownerTag, staleAfterMs);
113386
114232
  try {
113387
- return await fn();
114233
+ return await fn(createLockLease(lockPath, record, ownerTag, { staleAfterMs }));
113388
114234
  } finally {
113389
114235
  markLockRecordReleased(record);
113390
114236
  const outcome = await removeLockRecordIfUnchanged(lockPath, record, staleAfterMs);
@@ -113401,20 +114247,382 @@ async function reapStaleLock(lockPath, staleAfterMs = DEFAULT_STALE_AFTER_MS, de
113401
114247
  return await removeLockRecordIfUnchanged(lockPath, observed.content, staleAfterMs, deps);
113402
114248
  }
113403
114249
 
114250
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/prompt-lock.ts
114251
+ function promptLockAt(path, hooks = {}) {
114252
+ return async () => {
114253
+ const held = keychainProcessState().heldPromptLocks;
114254
+ if (held.has(path))
114255
+ return null;
114256
+ held.add(path);
114257
+ let granted = false;
114258
+ try {
114259
+ await mkdir11(dirname45(path), { recursive: true, mode: 448 });
114260
+ await hooks.beforePublish?.();
114261
+ for (let attempt = 0;attempt < 2; attempt++) {
114262
+ const record = await buildLockRecord("keychain-prompt");
114263
+ if (await publishLockRecord(path, record)) {
114264
+ granted = true;
114265
+ return async () => {
114266
+ markLockRecordReleased(record);
114267
+ try {
114268
+ await (hooks.removeRecord ?? ((target, owned) => removeLockRecordIfUnchanged(target, owned, Number.POSITIVE_INFINITY)))(path, record);
114269
+ } finally {
114270
+ held.delete(path);
114271
+ }
114272
+ };
114273
+ }
114274
+ if (await reapStaleLock(path, Number.POSITIVE_INFINITY) !== "removed")
114275
+ return null;
114276
+ }
114277
+ return null;
114278
+ } finally {
114279
+ if (!granted)
114280
+ held.delete(path);
114281
+ }
114282
+ };
114283
+ }
114284
+
114285
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/darwin-backend.ts
114286
+ var ROW_9B_DEFAULT = "reinstall-notice";
114287
+ var helperAccess = () => sharedHelperAccess(() => {
114288
+ const { entryCandidates } = keychainProcessState();
114289
+ return resolveHelperAccess([...entryCandidates, ...bundleCandidates(import.meta.url), ...machineCandidates(homedir31())]);
114290
+ });
114291
+ function sharedHelperAccess(resolve) {
114292
+ const state = keychainProcessState();
114293
+ if (state.helperAccess !== undefined)
114294
+ return state.helperAccess;
114295
+ const started = resolve();
114296
+ state.helperAccess = started;
114297
+ started.then((access) => {
114298
+ if (access.kind === "unavailable" && state.helperAccess === started)
114299
+ state.helperAccess = undefined;
114300
+ }, () => {
114301
+ if (state.helperAccess === started)
114302
+ state.helperAccess = undefined;
114303
+ });
114304
+ return started;
114305
+ }
114306
+
114307
+ class HelperMissingForOwnedItem extends Error {
114308
+ }
114309
+ function asKeystoreError(error, pending) {
114310
+ if (!(error instanceof HelperReadError))
114311
+ return error;
114312
+ if (error.failure === "pending")
114313
+ return pending(error.message);
114314
+ if (error.failure === "locked")
114315
+ return Object.assign(new Error(error.message), { code: "-25308" });
114316
+ return error;
114317
+ }
114318
+ function createDarwinBackend(options) {
114319
+ const silently = options.silently ?? silentSecrets;
114320
+ const key = { service: options.service, name: options.account };
114321
+ const deps = {
114322
+ account: options.account,
114323
+ access: options.access,
114324
+ cache: options.cache ?? processApprovalCache(),
114325
+ background: options.background,
114326
+ takePromptLock: promptLockAt(join109(options.home ?? homedir31(), ".omo", "session-locks", `${options.account}.keychain-prompt`)),
114327
+ ownSilentGet: () => silently(() => options.secrets.get(key)),
114328
+ ownOverwrite: (value) => silently(() => options.secrets.set({ ...key, value })),
114329
+ ownDelete: (name) => name === options.account ? gatedSecrets(() => options.secrets.delete({ ...key, name })) : silently(() => options.secrets.delete({ ...key, name })),
114330
+ notice: options.notice,
114331
+ ...options.row8b === undefined ? {} : { row8b: options.row8b },
114332
+ ...options.handOff === undefined ? {} : { handOff: options.handOff },
114333
+ noDialog: options.noDialog === true
114334
+ };
114335
+ let unowned = false;
114336
+ return {
114337
+ read: async () => {
114338
+ const result = await readThroughHelper(deps, true);
114339
+ unowned = result.kind === "value" && result.source !== "owned";
114340
+ return result.kind === "value" ? result.value : null;
114341
+ },
114342
+ underLock: (lease) => lockedDarwinStore(deps, lease),
114343
+ migrationPending: () => unowned
114344
+ };
114345
+ }
114346
+ async function guardHelperlessRead(service, account, choice = ROW_9B_DEFAULT, probe = probeOwnerMarker) {
114347
+ if (choice === "dialog")
114348
+ return;
114349
+ if (await probe(service, account) === "helper-owned")
114350
+ throw new HelperMissingForOwnedItem("OmO's keychain helper is missing or damaged on this Mac. Reinstall omo, then try again.");
114351
+ }
114352
+
114353
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/store-binding.ts
114354
+ import { homedir as homedir32 } from "os";
114355
+
114356
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/creator-handoff.ts
114357
+ init_bun_file_shim();
114358
+ init_bun_spawn_shim();
114359
+ import { dirname as dirname47, posix as posix14 } from "path";
114360
+
114361
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/runtime-capabilities.ts
114362
+ init_zod();
114363
+ import { readFile as readFile37 } from "fs/promises";
114364
+ import { dirname as dirname46, join as join110 } from "path";
114365
+ var RUNTIME_CAPABILITIES_FILE = "omo-runtime-capabilities.json";
114366
+ var RUNTIME_CAPABILITIES = { keychainHandoff: 1 };
114367
+ var capabilitiesSchema = object({ keychainHandoff: number2().int() }).passthrough();
114368
+ async function runtimeDeclaresKeychainHandoff(runtime) {
114369
+ const text = await readFile37(join110(dirname46(runtime), RUNTIME_CAPABILITIES_FILE), "utf8").catch(() => null);
114370
+ if (text === null)
114371
+ return false;
114372
+ try {
114373
+ const parsed = capabilitiesSchema.safeParse(JSON.parse(text));
114374
+ return parsed.success && parsed.data.keychainHandoff >= RUNTIME_CAPABILITIES.keychainHandoff;
114375
+ } catch {
114376
+ return false;
114377
+ }
114378
+ }
114379
+
114380
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/creator-handoff.ts
114381
+ var DEVELOPER_ID_TEAM = 'anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] and certificate leaf[field.1.2.840.113635.100.6.1.13] and certificate leaf[subject.OU] = "523JNR86LZ"';
114382
+ var DESKTOP_RUNTIME_REQUIREMENT = `identifier "com.mengmota.omo-desktop-runtime" and ${DEVELOPER_ID_TEAM}`;
114383
+ var DESKTOP_APP_REQUIREMENT = DEVELOPER_ID_TEAM;
114384
+ var HANDOFF_ENV = "OMO_KEYCHAIN_HANDOFF";
114385
+ var HANDOFF_DEADLINE_MS = 45000;
114386
+ function desktopRuntimeCandidates(home, arch = process.arch) {
114387
+ const runtimeArch = arch === "arm64" ? "arm64" : "x64";
114388
+ return ["/Applications/OmO.app", posix14.join(home, "Applications", "OmO.app")].map((app) => ({
114389
+ app,
114390
+ runtime: posix14.join(app, "Contents", "Resources", "omo-runtime", `darwin-${runtimeArch}`, "omo")
114391
+ }));
114392
+ }
114393
+ var verifyBundle = async (app, requirement) => {
114394
+ const child = spawn(["/usr/bin/codesign", "--verify", "--deep", "--strict", `-R=${requirement}`, app], {
114395
+ stdin: "ignore",
114396
+ stdout: "ignore",
114397
+ stderr: "ignore"
114398
+ });
114399
+ return await child.exited === 0;
114400
+ };
114401
+ var runBounded = async (path, args, env, deadlineMs) => {
114402
+ const child = spawn([path, ...args], { cwd: dirname47(path), stdin: "ignore", stdout: "ignore", stderr: "ignore", env });
114403
+ let killed = false;
114404
+ const timer = setTimeout(() => {
114405
+ killed = true;
114406
+ child.kill("SIGKILL");
114407
+ }, deadlineMs);
114408
+ try {
114409
+ const code = await child.exited;
114410
+ return killed ? null : code;
114411
+ } finally {
114412
+ clearTimeout(timer);
114413
+ }
114414
+ };
114415
+ function createCreatorHandOff(options) {
114416
+ return async () => {
114417
+ const env = options.env ?? process.env;
114418
+ if (env[HANDOFF_ENV] === "1")
114419
+ return false;
114420
+ const checkRuntime = options.checkRuntime ?? verifyWithSecurityFramework;
114421
+ const checkBundle = options.checkBundle ?? verifyBundle;
114422
+ const declaresHandOff = options.declaresHandOff ?? runtimeDeclaresKeychainHandoff;
114423
+ const self = options.selfPath ?? process.execPath;
114424
+ for (const { app, runtime } of options.candidates) {
114425
+ if (runtime === self || !await bunFile(runtime).exists())
114426
+ continue;
114427
+ const verified = await Promise.resolve().then(async () => await checkBundle(app, DESKTOP_APP_REQUIREMENT) && await checkRuntime(runtime, DESKTOP_RUNTIME_REQUIREMENT) && await declaresHandOff(runtime)).catch(() => false);
114428
+ if (!verified)
114429
+ continue;
114430
+ const childEnv = { [HANDOFF_ENV]: "1" };
114431
+ if (env.HOME !== undefined)
114432
+ childEnv.HOME = env.HOME;
114433
+ const origin = options.origin ?? env.OMO_SERVICE_API_URL;
114434
+ if (origin !== undefined)
114435
+ childEnv.OMO_SERVICE_API_URL = origin;
114436
+ try {
114437
+ return await (options.run ?? runBounded)(runtime, ["account", "token"], childEnv, HANDOFF_DEADLINE_MS) === 0;
114438
+ } catch {
114439
+ return false;
114440
+ }
114441
+ }
114442
+ return false;
114443
+ };
114444
+ }
114445
+
114446
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/store-binding.ts
114447
+ var readers = new Map;
114448
+ var INJECTED_SECRETS = Symbol.for("omo.test.injectedSecrets");
114449
+ var isInjectedSecrets = (api) => api[INJECTED_SECRETS] === true;
114450
+ var backends = new Map;
114451
+ function processHandOff(origin) {
114452
+ return () => {
114453
+ const state = keychainProcessState();
114454
+ state.handOff ??= createCreatorHandOff({ candidates: desktopRuntimeCandidates(homedir32()), origin })();
114455
+ return state.handOff;
114456
+ };
114457
+ }
114458
+ function bindKeychainHelper(input) {
114459
+ const { secrets: real, key, options } = input;
114460
+ const eligible = input.platform === "darwin" && input.namespace === "omo-cli" && (options !== undefined || typeof Bun !== "undefined" && real === Bun.secrets && !isInjectedSecrets(real));
114461
+ const secrets = !eligible ? real : {
114462
+ get: (entry) => gatedSecrets(() => real.get(entry)),
114463
+ set: (entry) => gatedSecrets(() => real.set(entry)),
114464
+ delete: (entry) => gatedSecrets(() => real.delete(entry))
114465
+ };
114466
+ const cacheKey = `${key.service}
114467
+ ${key.name}
114468
+ ${input.background ? "bounded" : "interactive"}`;
114469
+ let own;
114470
+ const backend = () => {
114471
+ if (!eligible)
114472
+ return Promise.resolve(null);
114473
+ const known = options === undefined ? backends.get(cacheKey) : own;
114474
+ if (known !== undefined)
114475
+ return known;
114476
+ const created = (options?.access ?? helperAccess)().then((access) => access.kind !== "ready" ? null : createDarwinBackend({
114477
+ access,
114478
+ secrets: real,
114479
+ service: key.service,
114480
+ account: key.name,
114481
+ background: input.background,
114482
+ noDialog: options?.noDialog ?? process.env[HANDOFF_ENV] === "1",
114483
+ notice: input.notice,
114484
+ ...options?.home === undefined ? {} : { home: options.home },
114485
+ ...options?.row8b === undefined ? {} : { row8b: options.row8b },
114486
+ ...options?.silently === undefined ? {} : { silently: options.silently },
114487
+ ...options?.cache === undefined ? {} : { cache: options.cache },
114488
+ handOff: options === undefined ? processHandOff(input.origin) : options.handOff ?? (async () => false)
114489
+ }));
114490
+ if (options === undefined) {
114491
+ backends.set(cacheKey, created);
114492
+ created.then((found) => {
114493
+ if (found === null && backends.get(cacheKey) === created)
114494
+ backends.delete(cacheKey);
114495
+ });
114496
+ } else
114497
+ own = created;
114498
+ return created;
114499
+ };
114500
+ const reader = (helper) => {
114501
+ const known = readers.get(helper);
114502
+ if (known !== undefined)
114503
+ return known;
114504
+ const refuse = async () => {
114505
+ throw new Error("OmO's keychain helper changes the sign-in only under the session lock.");
114506
+ };
114507
+ const created = {
114508
+ get: async () => {
114509
+ try {
114510
+ return await helper.read();
114511
+ } catch (error) {
114512
+ throw asKeystoreError(error, (message) => input.pending(`${message} Credentials are never saved to a file.`));
114513
+ }
114514
+ },
114515
+ set: refuse,
114516
+ delete: refuse
114517
+ };
114518
+ readers.set(helper, created);
114519
+ return created;
114520
+ };
114521
+ return {
114522
+ secrets,
114523
+ eligible,
114524
+ backend,
114525
+ reader,
114526
+ isHelperReader: (api) => [...readers.values()].includes(api),
114527
+ guardHelperless: async () => {
114528
+ if (!eligible)
114529
+ return;
114530
+ if ((options?.noDialog ?? process.env[HANDOFF_ENV] === "1") === true)
114531
+ throw input.pending("The keychain hand-off cannot show a dialog.");
114532
+ await guardHelperlessRead(key.service, key.name, options?.row9b, options?.ownerMarker);
114533
+ }
114534
+ };
114535
+ }
114536
+ function lockedStoreView(helper, lease, codec, mapError, done) {
114537
+ const locked = helper.underLock(lease);
114538
+ const run = async (step) => {
114539
+ try {
114540
+ return await step();
114541
+ } catch (error) {
114542
+ throw mapError(error);
114543
+ } finally {
114544
+ done();
114545
+ }
114546
+ };
114547
+ return {
114548
+ read: () => run(async () => {
114549
+ const text = await locked.read();
114550
+ return text === null ? null : codec.parse(text);
114551
+ }),
114552
+ write: (value, intent = "update", beforeRetire) => run(async () => {
114553
+ const next = codec.amend === undefined ? value : codec.amend(await locked.read(), value);
114554
+ await locked.write(codec.serialize(next), intent, beforeRetire);
114555
+ }),
114556
+ clear: () => run(() => locked.clear()),
114557
+ recover: () => run(() => locked.recover()),
114558
+ settle: () => run(() => locked.settle())
114559
+ };
114560
+ }
114561
+
114562
+ // packages/omo-opencode/src/cli/service-auth/secret-service-lock.ts
114563
+ import { spawn as spawn5 } from "child_process";
114564
+ var DEFAULT_COLLECTION = "/org/freedesktop/secrets/aliases/default";
114565
+ var PROBE_TIMEOUT_MS2 = 1e4;
114566
+ var parseLockedReply = (stdout) => {
114567
+ const match = /<\s*(true|false)\s*>/.exec(stdout);
114568
+ if (match === null)
114569
+ return null;
114570
+ return match[1] === "true" ? "locked" : "unlocked";
114571
+ };
114572
+ var probeSecretServiceLock = () => new Promise((resolve) => {
114573
+ const child = spawn5("gdbus", [
114574
+ "call",
114575
+ "--session",
114576
+ "--dest",
114577
+ "org.freedesktop.secrets",
114578
+ "--object-path",
114579
+ DEFAULT_COLLECTION,
114580
+ "--method",
114581
+ "org.freedesktop.DBus.Properties.Get",
114582
+ "org.freedesktop.Secret.Collection",
114583
+ "Locked"
114584
+ ], { stdio: ["ignore", "pipe", "ignore"] });
114585
+ let stdout = "";
114586
+ const timer = setTimeout(() => {
114587
+ child.kill();
114588
+ resolve("unknown");
114589
+ }, PROBE_TIMEOUT_MS2);
114590
+ child.stdout.on("data", (chunk) => {
114591
+ stdout += chunk.toString();
114592
+ });
114593
+ child.on("error", () => {
114594
+ clearTimeout(timer);
114595
+ resolve("unknown");
114596
+ });
114597
+ child.on("close", (code) => {
114598
+ clearTimeout(timer);
114599
+ resolve(code === 0 ? parseLockedReply(stdout) ?? "absent" : "absent");
114600
+ });
114601
+ });
114602
+
113404
114603
  // packages/omo-opencode/src/cli/service-auth/credential-lock.ts
114604
+ import { AsyncLocalStorage as AsyncLocalStorage3 } from "async_hooks";
114605
+ import { createHash as createHash11 } from "crypto";
114606
+ import { mkdir as mkdir12 } from "fs/promises";
114607
+ import { homedir as homedir33 } from "os";
114608
+ import { join as join112 } from "path";
113405
114609
  var held = new AsyncLocalStorage3;
113406
- function credentialLockPaths(api, home = homedir31()) {
114610
+ function credentialLockPaths(api, home = homedir33()) {
113407
114611
  const id = createHash11("sha256").update(serviceOrigin(api)).digest("hex");
113408
- const directory = join106(home, ".omo", "session-locks");
113409
- return { directory, lock: join106(directory, `${id}.lock`), desktopRecord: join106(directory, `${id}.desktop-generation.json`) };
114612
+ const directory = join112(home, ".omo", "session-locks");
114613
+ return { directory, lock: join112(directory, `${id}.lock`), desktopRecord: join112(directory, `${id}.desktop-generation.json`) };
114614
+ }
114615
+ function heldCredentialLease(api, home = homedir33()) {
114616
+ return held.getStore()?.get(credentialLockPaths(api, home).lock);
113410
114617
  }
113411
- async function withCredentialLock(api, action, home = homedir31(), ownerTag = "cli-session") {
114618
+ async function withCredentialLock(api, action, home = homedir33(), ownerTag = "cli-session") {
113412
114619
  const { directory, lock } = credentialLockPaths(api, home);
113413
114620
  const owned = held.getStore();
113414
- if (owned?.has(lock))
113415
- return action();
113416
- await mkdir11(directory, { recursive: true, mode: 448 });
113417
- return withLock(lock, () => held.run(new Set([...owned ?? [], lock]), action), {
114621
+ const outer = owned?.get(lock);
114622
+ if (outer !== undefined)
114623
+ return action(outer);
114624
+ await mkdir12(directory, { recursive: true, mode: 448 });
114625
+ return withLock(lock, (lease) => held.run(new Map([...owned ?? [], [lock, lease]]), () => action(lease)), {
113418
114626
  ownerTag,
113419
114627
  staleAfterMs: Number.POSITIVE_INFINITY
113420
114628
  });
@@ -113466,17 +114674,51 @@ function createCredentialStore(api, options = {}) {
113466
114674
  return {
113467
114675
  ...value,
113468
114676
  ...accountId === undefined ? {} : { accountId },
113469
- credentialGeneration: sameIdentity ? current?.credentialGeneration ?? randomUUID7() : randomUUID7()
114677
+ credentialGeneration: sameIdentity ? current?.credentialGeneration ?? randomUUID8() : randomUUID8()
113470
114678
  };
113471
- });
114679
+ }, options.keychainHelper);
114680
+ const sections = new WeakMap;
114681
+ const underLock = (lease) => {
114682
+ const known = sections.get(lease);
114683
+ if (known !== undefined)
114684
+ return known;
114685
+ const view = (async () => {
114686
+ const opened = await store.underLock?.(lease) ?? null;
114687
+ await opened?.recover();
114688
+ return opened;
114689
+ })();
114690
+ sections.set(lease, view);
114691
+ return view;
114692
+ };
114693
+ const held = async () => {
114694
+ const lease = heldCredentialLease(api, options.home);
114695
+ return lease === undefined ? null : underLock(lease);
114696
+ };
114697
+ const locked = async (helper, plain) => {
114698
+ if (heldCredentialLease(api, options.home) === undefined)
114699
+ await store.prepare?.();
114700
+ await withCredentialLock(api, async (lease) => {
114701
+ const view = await underLock(lease);
114702
+ await (view === null ? plain() : helper(view));
114703
+ }, options.home);
114704
+ };
113472
114705
  return {
113473
- read: store.read,
113474
- readAuthoritative: store.readAuthoritative,
113475
- write: (value) => withCredentialLock(api, () => store.write(value), options.home),
113476
- clear: () => withCredentialLock(api, store.clear, options.home)
114706
+ read: async () => {
114707
+ const view = await held();
114708
+ return view === null ? store.read() : view.read();
114709
+ },
114710
+ readAuthoritative: async () => {
114711
+ const view = await held();
114712
+ return view === null ? store.readAuthoritative() : view.read();
114713
+ },
114714
+ write: (value, intent, beforeRetire) => locked((view) => view.write(value, intent, beforeRetire), () => store.write(value)),
114715
+ clear: () => locked((view) => view.clear(), store.clear),
114716
+ ...store.prepare === undefined ? {} : { prepare: store.prepare },
114717
+ underLock,
114718
+ ...store.migrationPending === undefined ? {} : { migrationPending: store.migrationPending }
113477
114719
  };
113478
114720
  }
113479
- function createSealedStore(api, namespace, schema, secrets = typeof Bun === "undefined" ? null : Bun.secrets, platform = process.platform, lockProbe = probeSecretServiceLock, notice = stderrNoticeOncePerProcess, wait = SESSION_READ_WAIT, amendWrite) {
114721
+ function createSealedStore(api, namespace, schema, secrets = typeof Bun === "undefined" ? null : Bun.secrets, platform = process.platform, lockProbe = probeSecretServiceLock, notice = stderrNoticeOncePerProcess, wait = SESSION_READ_WAIT, amendWrite, keychainHelper) {
113480
114722
  if (!secrets)
113481
114723
  throw new SignInError("OmO sign-in needs Bun 1.4 or newer with OS credential storage. No file fallback is available.");
113482
114724
  const platformName = platform === "darwin" ? "macOS Keychain" : platform === "linux" ? "Linux Secret Service (libsecret and an unlocked keyring)" : platform === "win32" ? "Windows Credential Manager" : null;
@@ -113485,6 +114727,18 @@ function createSealedStore(api, namespace, schema, secrets = typeof Bun === "und
113485
114727
  const key = { service: namespace, name: credentialId(api) };
113486
114728
  const slot = `${key.service}
113487
114729
  ${key.name}`;
114730
+ const helper = bindKeychainHelper({
114731
+ platform,
114732
+ namespace,
114733
+ secrets,
114734
+ key,
114735
+ background: wait.kind === "bounded",
114736
+ origin: api,
114737
+ notice,
114738
+ pending: (message) => new KeychainApprovalPendingError(message),
114739
+ ...keychainHelper === undefined ? {} : { options: keychainHelper }
114740
+ });
114741
+ secrets = helper.secrets;
113488
114742
  const readsOf = (api) => {
113489
114743
  const known = processReads.get(api);
113490
114744
  if (known !== undefined)
@@ -113510,17 +114764,19 @@ ${key.name}`;
113510
114764
  reads.set(slot, read);
113511
114765
  return read;
113512
114766
  };
113513
- const waiting = platform === "darwin" ? `macOS Keychain is waiting for your approval: answer the "${basename15(process.execPath)} wants to access key ${namespace}" dialog ("Always Allow" stops it asking again)` : `${platformName} has not answered; it may be waiting for your approval or an unlock in a system dialog`;
114767
+ const waiting = platform === "darwin" ? `macOS Keychain is waiting for your approval: answer the "${basename17(process.execPath)} wants to access key ${namespace}" dialog ("Always Allow" stops it asking again)` : `${platformName} has not answered; it may be waiting for your approval or an unlock in a system dialog`;
114768
+ const helperWaiting = `macOS Keychain is waiting for your approval: answer the "OmO's keychain helper wants to access key ${namespace}" dialog`;
113514
114769
  const answered = async (api, fresh = false) => {
114770
+ const waitingFor = helper.isHelperReader(api) ? helperWaiting : waiting;
113515
114771
  const read = fresh ? Promise.resolve().then(() => api.get(key)) : sharedRead(api);
113516
114772
  let timer;
113517
114773
  try {
113518
114774
  if (wait.kind === "interactive") {
113519
- timer = setTimeout(() => wait.notice(`omo: ${waiting}.`), wait.noticeAfterMs);
114775
+ timer = setTimeout(() => wait.notice(`omo: ${waitingFor}.`), wait.noticeAfterMs);
113520
114776
  return await read;
113521
114777
  }
113522
114778
  const expired = new Promise((_, reject) => {
113523
- timer = setTimeout(() => reject(new KeychainApprovalPendingError(`${waiting}, then try again. Credentials are never saved to a file.`)), wait.deadlineMs);
114779
+ timer = setTimeout(() => reject(new KeychainApprovalPendingError(`${waitingFor}, then try again. Credentials are never saved to a file.`)), wait.deadlineMs);
113524
114780
  });
113525
114781
  return await Promise.race([read, expired]);
113526
114782
  } finally {
@@ -113545,41 +114801,76 @@ ${key.name}`;
113545
114801
  notice("omo: could not check whether the keyring is locked (gdbus or the Secret Service did not answer); using libsecret directly.");
113546
114802
  }
113547
114803
  };
113548
- const parsedRead = async (fresh) => {
114804
+ const parseStored = (value) => {
114805
+ try {
114806
+ return schema.parse(JSON.parse(value));
114807
+ } catch {
114808
+ throw new InvalidCredentialState(signInRoute() === "cli" ? "Stored sign-in data is invalid. Run omo account forget, then omo login." : "The OmO sign-in saved on this computer can't be read. Run omo account forget to remove it, then sign in again in the desktop app.");
114809
+ }
114810
+ };
114811
+ const previousOf = (raw) => {
114812
+ if (raw === null)
114813
+ return null;
114814
+ try {
114815
+ return schema.parse(JSON.parse(raw));
114816
+ } catch {
114817
+ return null;
114818
+ }
114819
+ };
114820
+ const rawRead = async (fresh) => {
113549
114821
  await assertUsable();
113550
- let value;
114822
+ const backend = await helper.backend();
113551
114823
  try {
113552
- value = await answered(secrets, fresh);
114824
+ if (backend === null)
114825
+ await helper.guardHelperless();
114826
+ return await answered(backend === null ? secrets : helper.reader(backend), fresh);
113553
114827
  } catch (error) {
113554
114828
  if (error instanceof KeychainApprovalPendingError)
113555
114829
  throw error;
114830
+ if (error instanceof HelperMissingForOwnedItem)
114831
+ throw new CredentialStoreError(error.message);
113556
114832
  throw unavailable(error);
113557
114833
  }
113558
- if (value === null)
113559
- return null;
113560
- try {
113561
- return schema.parse(JSON.parse(value));
113562
- } catch {
113563
- throw new InvalidCredentialState(signInRoute() === "cli" ? "Stored sign-in data is invalid. Run omo account forget, then omo login." : "The OmO sign-in saved on this computer can't be read. Run omo account forget to remove it, then sign in again in the desktop app.");
113564
- }
114834
+ };
114835
+ const parsedRead = async (fresh) => {
114836
+ const value = await rawRead(fresh);
114837
+ return value === null ? null : parseStored(value);
114838
+ };
114839
+ const lockedFailure = (error) => {
114840
+ const mapped = asKeystoreError(error, (message) => new KeychainApprovalPendingError(message));
114841
+ if (error instanceof HelperOldSlotsFull)
114842
+ return new CredentialStoreError(error.message);
114843
+ if (mapped instanceof KeychainApprovalPendingError || mapped instanceof SignInError)
114844
+ return mapped;
114845
+ if (mapped instanceof Error && mapped.name === "LockLeaseLostError")
114846
+ return mapped;
114847
+ return unavailable(mapped);
113565
114848
  };
113566
114849
  return {
113567
114850
  read: () => parsedRead(false),
113568
114851
  readAuthoritative: () => parsedRead(true),
114852
+ async prepare() {
114853
+ if (await helper.backend() !== null)
114854
+ await rawRead(false);
114855
+ },
114856
+ async underLock(lease) {
114857
+ const backend = await helper.backend();
114858
+ if (backend === null)
114859
+ return null;
114860
+ const codec = {
114861
+ parse: parseStored,
114862
+ serialize: (value) => JSON.stringify(schema.parse(value)),
114863
+ ...amendWrite === undefined ? {} : { amend: (raw, next) => amendWrite(previousOf(raw), next) }
114864
+ };
114865
+ return lockedStoreView(backend, lease, codec, lockedFailure, () => forget(helper.reader(backend)));
114866
+ },
114867
+ migrationPending: async () => (await helper.backend())?.migrationPending() ?? false,
113569
114868
  async write(value) {
113570
114869
  await assertUsable();
114870
+ if (await helper.backend() !== null)
114871
+ throw new Error("OmO's keychain helper writes only under the session lock.");
113571
114872
  try {
113572
- let next = value;
113573
- if (amendWrite !== undefined) {
113574
- const raw = await answered(secrets, true);
113575
- let previous = null;
113576
- if (raw !== null) {
113577
- try {
113578
- previous = schema.parse(JSON.parse(raw));
113579
- } catch {}
113580
- }
113581
- next = amendWrite(previous, value);
113582
- }
114873
+ const next = amendWrite === undefined ? value : amendWrite(previousOf(await answered(secrets, true)), value);
113583
114874
  await secrets.set({ ...key, value: JSON.stringify(schema.parse(next)) });
113584
114875
  } catch (error) {
113585
114876
  throw unavailable(error);
@@ -113588,6 +114879,8 @@ ${key.name}`;
113588
114879
  },
113589
114880
  async clear() {
113590
114881
  await assertUsable();
114882
+ if (await helper.backend() !== null)
114883
+ throw new Error("OmO's keychain helper deletes only under the session lock.");
113591
114884
  try {
113592
114885
  await secrets.delete(key);
113593
114886
  } catch (error) {
@@ -113699,14 +114992,14 @@ async function loginLoopback(session, options) {
113699
114992
 
113700
114993
  // packages/memory-core/src/sync/device-retire.ts
113701
114994
  import { createHash as createHash14, randomBytes as randomBytes6 } from "crypto";
113702
- import { join as join109 } from "path";
114995
+ import { join as join115 } from "path";
113703
114996
 
113704
114997
  // packages/memory-core/src/identity/layout.ts
113705
- import { homedir as homedir32 } from "os";
113706
- import { join as join107, resolve as resolve31 } from "path";
114998
+ import { homedir as homedir34 } from "os";
114999
+ import { join as join113, resolve as resolve31 } from "path";
113707
115000
  var MEMORY_ROOT_ENV_VAR = "OMO_MEMORY_HOME";
113708
115001
  function defaultMemoryRoot() {
113709
- return join107(homedir32(), ".omo", "memory");
115002
+ return join113(homedir34(), ".omo", "memory");
113710
115003
  }
113711
115004
  function resolveMemoryRoot(env, cwd) {
113712
115005
  const override = env[MEMORY_ROOT_ENV_VAR];
@@ -113716,13 +115009,13 @@ function resolveMemoryRoot(env, cwd) {
113716
115009
  return resolve31(cwd, override);
113717
115010
  }
113718
115011
  // packages/memory-core/src/sync/pin-dir.ts
113719
- import { join as join108 } from "path";
113720
- var syncPinDir = (memoryRoot) => join108(memoryRoot, "sync-device");
115012
+ import { join as join114 } from "path";
115013
+ var syncPinDir = (memoryRoot) => join114(memoryRoot, "sync-device");
113721
115014
 
113722
115015
  // packages/memory-core/src/sync/device-retire.ts
113723
- var trustAnchorRoot = (pinDir) => join109(pinDir, "trust-anchor");
115016
+ var trustAnchorRoot = (pinDir) => join115(pinDir, "trust-anchor");
113724
115017
  var trustAnchorKey = (account) => createHash14("sha256").update(account, "utf8").digest("base64url");
113725
- var trustAnchorDir = (pinDir, account) => join109(trustAnchorRoot(pinDir), trustAnchorKey(account));
115018
+ var trustAnchorDir = (pinDir, account) => join115(trustAnchorRoot(pinDir), trustAnchorKey(account));
113726
115019
  var hasLiveTrustAnchor = async (pinDir) => {
113727
115020
  try {
113728
115021
  return (await readdir17(trustAnchorRoot(pinDir))).some((name) => !name.includes(".retired-"));
@@ -113743,16 +115036,16 @@ var retireSyncDevice = async (input) => {
113743
115036
  };
113744
115037
 
113745
115038
  // packages/omo-opencode/src/cli/service-auth/session.ts
113746
- import { homedir as homedir33 } from "os";
115039
+ import { homedir as homedir35 } from "os";
113747
115040
 
113748
115041
  // packages/omo-opencode/src/cli/service-auth/signed-out-marker.ts
113749
115042
  init_zod();
113750
- import { mkdir as mkdir12, readFile as readFile35, rename as rename9, rm as rm17, writeFile as writeFile17 } from "fs/promises";
113751
- import { dirname as dirname43, join as join110 } from "path";
115043
+ import { mkdir as mkdir13, readFile as readFile38, rename as rename10, rm as rm19, writeFile as writeFile18 } from "fs/promises";
115044
+ import { dirname as dirname48, join as join116 } from "path";
113752
115045
  var markerSchema = object({ device: string2().nullable(), at: string2() });
113753
- var signedOutMarkerPath = (home, credential) => join110(home, ".omo", "account-state", `${credential}.signed-out.json`);
115046
+ var signedOutMarkerPath = (home, credential) => join116(home, ".omo", "account-state", `${credential}.signed-out.json`);
113754
115047
  async function readSignedOutMarker(path) {
113755
- const text = await readFile35(path, "utf8").catch(() => null);
115048
+ const text = await readFile38(path, "utf8").catch(() => null);
113756
115049
  if (text === null)
113757
115050
  return null;
113758
115051
  let value;
@@ -113765,12 +115058,12 @@ async function readSignedOutMarker(path) {
113765
115058
  return parsed.success ? parsed.data : null;
113766
115059
  }
113767
115060
  async function writeSignedOutMarker(path, device) {
113768
- await mkdir12(dirname43(path), { recursive: true, mode: 448 });
115061
+ await mkdir13(dirname48(path), { recursive: true, mode: 448 });
113769
115062
  const staging = `${path}.${process.pid}.tmp`;
113770
- await writeFile17(staging, JSON.stringify({ device, at: new Date().toISOString() }), { mode: 384 });
113771
- await rename9(staging, path);
115063
+ await writeFile18(staging, JSON.stringify({ device, at: new Date().toISOString() }), { mode: 384 });
115064
+ await rename10(staging, path);
113772
115065
  }
113773
- var clearSignedOutMarker = (path) => rm17(path, { force: true });
115066
+ var clearSignedOutMarker = (path) => rm19(path, { force: true });
113774
115067
 
113775
115068
  // packages/omo-opencode/src/cli/service-auth/session.ts
113776
115069
  class SessionEnded extends SignInError {
@@ -113794,12 +115087,14 @@ function createSession(options) {
113794
115087
  const api = serviceOrigin(options.api);
113795
115088
  const now = options.now ?? Date.now;
113796
115089
  const { store, signal, beforeKeysDiscarded } = options;
113797
- const markerPath = signedOutMarkerPath(options.home ?? homedir33(), credentialId(api));
115090
+ const markerPath = signedOutMarkerPath(options.home ?? homedir35(), credentialId(api));
113798
115091
  async function locked(action) {
113799
115092
  signal?.throwIfAborted();
113800
- return withCredentialLock(api, async () => {
115093
+ if (heldCredentialLease(api, options.home) === undefined)
115094
+ await store.prepare?.();
115095
+ return withCredentialLock(api, async (lease) => {
113801
115096
  signal?.throwIfAborted();
113802
- return action();
115097
+ return action(await store.underLock?.(lease) ?? null);
113803
115098
  }, options.home);
113804
115099
  }
113805
115100
  const request = (path, init) => requestApi(api, path, init, signal);
@@ -113836,9 +115131,12 @@ function createSession(options) {
113836
115131
  }
113837
115132
  }
113838
115133
  async function snapshot() {
113839
- return locked(async () => {
115134
+ return locked(async (view) => {
113840
115135
  const current = await store.read();
113841
- return current === null ? null : refreshed(current);
115136
+ if (current === null)
115137
+ return null;
115138
+ await view?.settle();
115139
+ return refreshed(current);
113842
115140
  });
113843
115141
  }
113844
115142
  return {
@@ -113861,7 +115159,7 @@ function createSession(options) {
113861
115159
  }
113862
115160
  if (stored !== null && stored.device.id !== value.device.id)
113863
115161
  await beforeKeysDiscarded(discardedOf(stored, "replaced"));
113864
- await store.write(value);
115162
+ await store.write(value, "fresh-sign-in", () => beforeKeysDiscarded({ kind: "unreadable" }));
113865
115163
  await clearSignedOutMarker(markerPath);
113866
115164
  });
113867
115165
  },
@@ -113922,14 +115220,15 @@ function createSession(options) {
113922
115220
  signal?.throwIfAborted();
113923
115221
  const snapshot = await store.read();
113924
115222
  signal?.throwIfAborted();
113925
- if (snapshot !== null && snapshot.refreshState !== "uncertain" && snapshot.refreshAttempt === undefined && Date.parse(snapshot.accessTokenExpiresAt) > now() + 30000 && (expect === undefined || expect(snapshot)))
115223
+ if (snapshot !== null && snapshot.refreshState !== "uncertain" && snapshot.refreshAttempt === undefined && Date.parse(snapshot.accessTokenExpiresAt) > now() + 30000 && (expect === undefined || expect(snapshot)) && !await store.migrationPending?.())
113926
115224
  return snapshot.accessToken;
113927
- return locked(async () => {
115225
+ return locked(async (view) => {
113928
115226
  const current = await store.readAuthoritative();
113929
115227
  if (current === null)
113930
115228
  throw new SignInError(`Not signed in. ${signInHint("first")}`);
113931
115229
  if (expect !== undefined && !expect(current))
113932
115230
  throw new CredentialIdentityChanged;
115231
+ await view?.settle();
113933
115232
  return (await refreshed(current)).accessToken;
113934
115233
  });
113935
115234
  },
@@ -114077,6 +115376,10 @@ function refuseClosedServiceAuth() {
114077
115376
  }
114078
115377
  function configureClosedServiceAuthCommands(program) {
114079
115378
  for (const name of SERVICE_AUTH_COMMANDS) {
115379
+ if (name === "login") {
115380
+ configureClosedDeviceLogin(program);
115381
+ continue;
115382
+ }
114080
115383
  const command = program.command(name, { hidden: true }).helpOption(false).allowUnknownOption().allowExcessArguments().action(() => {
114081
115384
  console.error(SERVICE_ACCOUNTS_CLOSED_MESSAGE);
114082
115385
  process.exitCode = 1;
@@ -114084,6 +115387,17 @@ function configureClosedServiceAuthCommands(program) {
114084
115387
  command.help = refuseClosedServiceAuth;
114085
115388
  }
114086
115389
  }
115390
+ function configureClosedDeviceLogin(program) {
115391
+ const command = program.command("login", { hidden: true }).helpOption(false).allowUnknownOption().allowExcessArguments().option("--device").option("--no-browser").option("--api <url>").action((options) => {
115392
+ if (options.device !== true && options.browser !== false || command.args.length > 0) {
115393
+ console.error(SERVICE_ACCOUNTS_CLOSED_MESSAGE);
115394
+ process.exitCode = 1;
115395
+ return;
115396
+ }
115397
+ return run2("login", { ...options, device: true });
115398
+ });
115399
+ command.help = refuseClosedServiceAuth;
115400
+ }
114087
115401
  function configureServiceAuthCommands(program, open = serviceAccountsOpen()) {
114088
115402
  if (!open) {
114089
115403
  configureClosedServiceAuthCommands(program);
@@ -114285,11 +115599,11 @@ async function boulder(options) {
114285
115599
  // packages/omo-opencode/src/cli/codex-ulw-loop.ts
114286
115600
  import { spawn as spawn6 } from "child_process";
114287
115601
  import { existsSync as existsSync67, readFileSync as readFileSync45, realpathSync as realpathSync14 } from "fs";
114288
- import { homedir as homedir34 } from "os";
115602
+ import { homedir as homedir36 } from "os";
114289
115603
  var ULW_LOOP_DELEGATION_SENTINEL = "OMO_ULW_LOOP_DELEGATED";
114290
115604
  function resolveCodexUlwLoopCommand(input = {}) {
114291
115605
  const env = input.env ?? process.env;
114292
- const homeDir = input.homeDir ?? homedir34();
115606
+ const homeDir = input.homeDir ?? homedir36();
114293
115607
  const localComponentBin = resolveLocalUlwLoopBin(env, homeDir);
114294
115608
  if (localComponentBin !== null)
114295
115609
  return { executable: localComponentBin, argsPrefix: [] };
@@ -114532,7 +115846,7 @@ function linkedWorktrees(records) {
114532
115846
  }
114533
115847
  // packages/omo-opencode/src/cli/worktree-sweep/sweep.ts
114534
115848
  import { existsSync as existsSync68 } from "fs";
114535
- import { stat as stat10 } from "fs/promises";
115849
+ import { stat as stat12 } from "fs/promises";
114536
115850
  import os7 from "os";
114537
115851
  import { normalize as normalize2 } from "path";
114538
115852
 
@@ -114615,7 +115929,7 @@ async function isOlderThan(worktreePath, days, now) {
114615
115929
  if (days <= 0)
114616
115930
  return false;
114617
115931
  try {
114618
- const stats = await stat10(worktreePath);
115932
+ const stats = await stat12(worktreePath);
114619
115933
  return now - stats.mtimeMs > days * DAY_MS;
114620
115934
  } catch {
114621
115935
  return false;
@@ -114780,7 +116094,7 @@ prunes.
114780
116094
 
114781
116095
  // packages/omo-opencode/src/cli/config-migrate.ts
114782
116096
  init_startup_migration();
114783
- import { posix as posix13 } from "path";
116097
+ import { posix as posix15 } from "path";
114784
116098
  function reports(result) {
114785
116099
  return result.results.map((entry) => ({
114786
116100
  diagnostics: entry.diagnostics,
@@ -114814,7 +116128,7 @@ function runConfigMigrate(options = {}) {
114814
116128
  dryRun: options.dryRun ?? false,
114815
116129
  environment,
114816
116130
  ...homeDir === undefined ? {} : { env: { HOME: homeDir }, homeDir },
114817
- pathOperations: posix13
116131
+ pathOperations: posix15
114818
116132
  });
114819
116133
  const report = reports(result);
114820
116134
  const response = {