lazycodex-ai 5.1.62 → 5.1.63

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
@@ -2133,7 +2133,7 @@ var package_default;
2133
2133
  var init_package = __esm(() => {
2134
2134
  package_default = {
2135
2135
  name: "oh-my-opencode",
2136
- version: "5.1.62",
2136
+ version: "5.1.63",
2137
2137
  description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
2138
2138
  main: "./dist/index.js",
2139
2139
  types: "dist/index.d.ts",
@@ -2385,18 +2385,18 @@ var init_package = __esm(() => {
2385
2385
  typescript: "^7.0.2"
2386
2386
  },
2387
2387
  optionalDependencies: {
2388
- "oh-my-opencode-darwin-arm64": "5.1.62",
2389
- "oh-my-opencode-darwin-x64": "5.1.62",
2390
- "oh-my-opencode-darwin-x64-baseline": "5.1.62",
2391
- "oh-my-opencode-linux-arm64": "5.1.62",
2392
- "oh-my-opencode-linux-arm64-musl": "5.1.62",
2393
- "oh-my-opencode-linux-x64": "5.1.62",
2394
- "oh-my-opencode-linux-x64-baseline": "5.1.62",
2395
- "oh-my-opencode-linux-x64-musl": "5.1.62",
2396
- "oh-my-opencode-linux-x64-musl-baseline": "5.1.62",
2397
- "oh-my-opencode-windows-arm64": "5.1.62",
2398
- "oh-my-opencode-windows-x64": "5.1.62",
2399
- "oh-my-opencode-windows-x64-baseline": "5.1.62"
2388
+ "oh-my-opencode-darwin-arm64": "5.1.63",
2389
+ "oh-my-opencode-darwin-x64": "5.1.63",
2390
+ "oh-my-opencode-darwin-x64-baseline": "5.1.63",
2391
+ "oh-my-opencode-linux-arm64": "5.1.63",
2392
+ "oh-my-opencode-linux-arm64-musl": "5.1.63",
2393
+ "oh-my-opencode-linux-x64": "5.1.63",
2394
+ "oh-my-opencode-linux-x64-baseline": "5.1.63",
2395
+ "oh-my-opencode-linux-x64-musl": "5.1.63",
2396
+ "oh-my-opencode-linux-x64-musl-baseline": "5.1.63",
2397
+ "oh-my-opencode-windows-arm64": "5.1.63",
2398
+ "oh-my-opencode-windows-x64": "5.1.63",
2399
+ "oh-my-opencode-windows-x64-baseline": "5.1.63"
2400
2400
  },
2401
2401
  overrides: {
2402
2402
  hono: "^4.13.8",
@@ -7340,7 +7340,34 @@ var init_which = __esm(() => {
7340
7340
  });
7341
7341
 
7342
7342
  // packages/utils/src/runtime/file.ts
7343
- var init_file = () => {};
7343
+ import { access, readFile, unlink, writeFile } from "node:fs/promises";
7344
+ function createNodeFile(path) {
7345
+ return {
7346
+ text() {
7347
+ return readFile(path, "utf8");
7348
+ },
7349
+ async arrayBuffer() {
7350
+ const buffer = await readFile(path);
7351
+ return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
7352
+ },
7353
+ exists() {
7354
+ return access(path).then(() => true, () => false);
7355
+ },
7356
+ delete() {
7357
+ return unlink(path);
7358
+ }
7359
+ };
7360
+ }
7361
+ function bunFile(path) {
7362
+ const bun = runtime3.Bun;
7363
+ if (bun)
7364
+ return bun.file(path);
7365
+ return createNodeFile(path);
7366
+ }
7367
+ var runtime3;
7368
+ var init_file = __esm(() => {
7369
+ runtime3 = globalThis;
7370
+ });
7344
7371
 
7345
7372
  // packages/utils/src/runtime/git-bash.ts
7346
7373
  import { execFileSync } from "node:child_process";
@@ -12284,7 +12311,9 @@ var init_zip_extractor = __esm(() => {
12284
12311
  });
12285
12312
 
12286
12313
  // packages/omo-opencode/src/shared/bun-file-shim.ts
12287
- var init_bun_file_shim = () => {};
12314
+ var init_bun_file_shim = __esm(() => {
12315
+ init_runtime();
12316
+ });
12288
12317
 
12289
12318
  // packages/omo-opencode/src/shared/binary-downloader.ts
12290
12319
  import { chmodSync, existsSync as existsSync9, mkdirSync as mkdirSync4, unlinkSync as unlinkSync3 } from "node:fs";
@@ -92789,7 +92818,7 @@ var package_default2;
92789
92818
  var init_package2 = __esm(() => {
92790
92819
  package_default2 = {
92791
92820
  name: "@oh-my-opencode/omo-codex",
92792
- version: "5.1.62",
92821
+ version: "5.1.63",
92793
92822
  type: "module",
92794
92823
  private: true,
92795
92824
  description: "Codex harness adapter for oh-my-openagent. Vendored Codex plugin namespace (omo) + TypeScript installer + telemetry.",
@@ -93405,7 +93434,7 @@ var init_check_for_update = __esm(() => {
93405
93434
  });
93406
93435
 
93407
93436
  // packages/omo-opencode/src/hooks/auto-update-checker/checker/sync-package-json.ts
93408
- import * as crypto from "node:crypto";
93437
+ import * as crypto2 from "node:crypto";
93409
93438
  import * as fs8 from "node:fs";
93410
93439
  import * as path11 from "node:path";
93411
93440
  function safeUnlink(filePath) {
@@ -93429,7 +93458,7 @@ function getPackageNameFromIntent(pluginInfo) {
93429
93458
  return ACCEPTED_PACKAGE_NAMES2.find((packageName) => pluginInfo.entry === packageName || pluginInfo.entry.startsWith(`${packageName}@`)) ?? PACKAGE_NAME3;
93430
93459
  }
93431
93460
  function writeCachePackageJson(cachePackageJsonPath, pkgJson) {
93432
- const tmpPath = `${cachePackageJsonPath}.${crypto.randomUUID()}`;
93461
+ const tmpPath = `${cachePackageJsonPath}.${crypto2.randomUUID()}`;
93433
93462
  try {
93434
93463
  fs8.mkdirSync(path11.dirname(cachePackageJsonPath), { recursive: true });
93435
93464
  fs8.writeFileSync(tmpPath, JSON.stringify(pkgJson, null, 2));
@@ -94350,7 +94379,7 @@ import { existsSync as existsSync27 } from "node:fs";
94350
94379
  import { homedir as homedir7 } from "node:os";
94351
94380
 
94352
94381
  // packages/omo-codex/src/install/codex-cache-bins.ts
94353
- import { chmod, lstat as lstat4, mkdir, readFile as readFile3, readdir as readdir2, readlink as readlink3, rm as rm3, stat as stat2, symlink, writeFile } from "node:fs/promises";
94382
+ 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 "node:fs/promises";
94354
94383
  import { basename as basename4, isAbsolute as isAbsolute2, join as join26, relative, resolve as resolve6, sep } from "node:path";
94355
94384
 
94356
94385
  // packages/omo-codex/src/install/codex-cache-command-shim.ts
@@ -94394,7 +94423,7 @@ function windowsCommandShim(targetPath) {
94394
94423
  }
94395
94424
 
94396
94425
  // packages/omo-codex/src/install/codex-cache-dangling-bins.ts
94397
- import { lstat as lstat2, readFile, readdir, readlink, rm, stat } from "node:fs/promises";
94426
+ import { lstat as lstat2, readFile as readFile2, readdir, readlink, rm, stat } from "node:fs/promises";
94398
94427
  import { dirname as dirname10, isAbsolute, join as join23, resolve as resolve5 } from "node:path";
94399
94428
 
94400
94429
  // packages/omo-codex/src/install/codex-cache-fs.ts
@@ -94456,7 +94485,7 @@ async function removeDanglingGeneratedCommandShim(linkPath) {
94456
94485
  const linkStat = await lstat2(linkPath);
94457
94486
  if (!linkStat.isFile())
94458
94487
  return;
94459
- const content = await readFile(linkPath, "utf8");
94488
+ const content = await readFile2(linkPath, "utf8");
94460
94489
  if (!content.includes(COMMAND_SHIM_MARKER))
94461
94490
  return;
94462
94491
  const target = extractCommandShimTarget(content);
@@ -94504,7 +94533,7 @@ function hasOmoCodexPluginPrefix(parts, endExclusive) {
94504
94533
  }
94505
94534
 
94506
94535
  // packages/omo-codex/src/install/codex-cache-legacy-bins.ts
94507
- import { lstat as lstat3, readFile as readFile2, readlink as readlink2, rm as rm2 } from "node:fs/promises";
94536
+ import { lstat as lstat3, readFile as readFile3, readlink as readlink2, rm as rm2 } from "node:fs/promises";
94508
94537
  import { join as join24 } from "node:path";
94509
94538
  var LEGACY_CODEX_COMPONENT_BINS = [
94510
94539
  { name: "omo", component: "ulw-loop" },
@@ -94539,7 +94568,7 @@ async function removeLegacyCodexComponentBin(linkPath, component, platform) {
94539
94568
  }
94540
94569
  if (!stat.isFile())
94541
94570
  return;
94542
- const content = await readFile2(linkPath, "utf8");
94571
+ const content = await readFile3(linkPath, "utf8");
94543
94572
  if (content.includes(COMMAND_SHIM_MARKER))
94544
94573
  await rm2(linkPath, { force: true });
94545
94574
  } catch (error) {
@@ -94776,7 +94805,7 @@ async function collectPackageBins(directory, root, links) {
94776
94805
  }
94777
94806
  }
94778
94807
  async function appendPackageBinLinks(packageJsonPath, packageRoot, root, links) {
94779
- const packageJson = JSON.parse(await readFile3(packageJsonPath, "utf8"));
94808
+ const packageJson = JSON.parse(await readFile4(packageJsonPath, "utf8"));
94780
94809
  if (!isPlainRecord4(packageJson))
94781
94810
  return;
94782
94811
  const packageName = packageJson.name;
@@ -94828,13 +94857,13 @@ async function replaceSymlink(linkPath, targetPath) {
94828
94857
  async function replaceCommandShim(linkPath, targetPath) {
94829
94858
  if (await existingNonShim(linkPath))
94830
94859
  throw new Error(`${linkPath} already exists and is not a command shim`);
94831
- await writeFile(linkPath, windowsCommandShim(targetPath));
94860
+ await writeFile2(linkPath, windowsCommandShim(targetPath));
94832
94861
  }
94833
94862
  async function replaceRuntimeWrapper(linkPath, content) {
94834
94863
  if (await existingNonRuntimeWrapper(linkPath))
94835
94864
  throw new Error(`${linkPath} already exists and is not a generated OMO runtime wrapper`);
94836
94865
  await rm3(linkPath, { force: true });
94837
- await writeFile(linkPath, content);
94866
+ await writeFile2(linkPath, content);
94838
94867
  }
94839
94868
  async function removeGeneratedRuntimeWrapper(path) {
94840
94869
  try {
@@ -94852,7 +94881,7 @@ async function removeGeneratedRuntimeWrapper(path) {
94852
94881
  }
94853
94882
  async function readGeneratedWrapperContent(path) {
94854
94883
  try {
94855
- return await readFile3(path, "utf8");
94884
+ return await readFile4(path, "utf8");
94856
94885
  } catch (error) {
94857
94886
  if (isNodeErrorWithCode(error) && (error.code === "ENOENT" || error.code === "EISDIR"))
94858
94887
  return "";
@@ -94866,7 +94895,7 @@ async function existingNonRuntimeWrapper(path) {
94866
94895
  return false;
94867
94896
  if (!stat.isFile())
94868
94897
  return true;
94869
- const content = await readFile3(path, "utf8");
94898
+ const content = await readFile4(path, "utf8");
94870
94899
  return !content.includes(RUNTIME_WRAPPER_MARKER);
94871
94900
  } catch (error) {
94872
94901
  if (isNodeErrorWithCode(error) && error.code === "ENOENT")
@@ -94879,7 +94908,7 @@ async function existingNonShim(path) {
94879
94908
  const stat = await lstat4(path);
94880
94909
  if (!stat.isFile())
94881
94910
  return true;
94882
- const content = await readFile3(path, "utf8");
94911
+ const content = await readFile4(path, "utf8");
94883
94912
  if (content.includes(COMMAND_SHIM_MARKER))
94884
94913
  return false;
94885
94914
  throw new Error(`${path} already exists and is not a generated command shim`);
@@ -94903,11 +94932,11 @@ async function existingNonSymlink(path) {
94903
94932
  }
94904
94933
  }
94905
94934
  // packages/omo-codex/src/install/codex-cache-install.ts
94906
- import { cp as cp3, mkdir as mkdir3, readFile as readFile8, readdir as readdir5, rename as rename2, rm as rm5 } from "node:fs/promises";
94935
+ import { cp as cp3, mkdir as mkdir3, readFile as readFile9, readdir as readdir5, rename as rename2, rm as rm5 } from "node:fs/promises";
94907
94936
  import { basename as basename5, dirname as dirname13, join as join33, sep as sep6 } from "node:path";
94908
94937
 
94909
94938
  // packages/omo-codex/src/install/codex-cache-bundled-mcps.ts
94910
- import { cp, mkdir as mkdir2, readFile as readFile4, stat as stat3 } from "node:fs/promises";
94939
+ import { cp, mkdir as mkdir2, readFile as readFile5, stat as stat3 } from "node:fs/promises";
94911
94940
  import { dirname as dirname11, join as join27, resolve as resolve7 } from "node:path";
94912
94941
  var BUNDLED_MCP_RUNTIMES = [
94913
94942
  {
@@ -94949,7 +94978,7 @@ async function copyBundledMcpRuntimeDist(pluginRoot, sourceRoot, runtime) {
94949
94978
  async function readSourceMcpArgs(path) {
94950
94979
  let parsed;
94951
94980
  try {
94952
- parsed = JSON.parse(await readFile4(path, "utf8"));
94981
+ parsed = JSON.parse(await readFile5(path, "utf8"));
94953
94982
  } catch (error) {
94954
94983
  if (error instanceof Error)
94955
94984
  return new Set;
@@ -94980,7 +95009,7 @@ async function isDirectory(path) {
94980
95009
 
94981
95010
  // packages/omo-codex/src/install/codex-cache-local-dependencies.ts
94982
95011
  import { realpathSync as realpathSync7 } from "node:fs";
94983
- import { readFile as readFile5, readdir as readdir3, writeFile as writeFile2 } from "node:fs/promises";
95012
+ import { readFile as readFile6, readdir as readdir3, writeFile as writeFile3 } from "node:fs/promises";
94984
95013
  import { dirname as dirname12, isAbsolute as isAbsolute4, join as join29, relative as relative3, resolve as resolve9, sep as sep2 } from "node:path";
94985
95014
 
94986
95015
  // packages/omo-codex/src/install/codex-cache-paths.ts
@@ -95046,7 +95075,7 @@ async function rewriteCachedPackageLocalFileDependencies(pluginRoot, sourceRoot)
95046
95075
  const packageLock = await readPackageLock(pluginRoot);
95047
95076
  let rewroteAnyPackageJson = false;
95048
95077
  for (const packageJsonPath of packageJsonPaths) {
95049
- const raw = await readFile5(packageJsonPath, "utf8");
95078
+ const raw = await readFile6(packageJsonPath, "utf8");
95050
95079
  const parsed = JSON.parse(raw);
95051
95080
  if (!isPlainRecord4(parsed))
95052
95081
  continue;
@@ -95081,20 +95110,20 @@ async function rewriteCachedPackageLocalFileDependencies(pluginRoot, sourceRoot)
95081
95110
  }
95082
95111
  }
95083
95112
  if (changed) {
95084
- await writeFile2(packageJsonPath, `${JSON.stringify(parsed, null, "\t")}
95113
+ await writeFile3(packageJsonPath, `${JSON.stringify(parsed, null, "\t")}
95085
95114
  `);
95086
95115
  rewroteAnyPackageJson = true;
95087
95116
  }
95088
95117
  }
95089
95118
  if (packageLock.changed)
95090
- await writeFile2(packageLock.path, `${JSON.stringify(packageLock.value, null, "\t")}
95119
+ await writeFile3(packageLock.path, `${JSON.stringify(packageLock.value, null, "\t")}
95091
95120
  `);
95092
95121
  return rewroteAnyPackageJson;
95093
95122
  }
95094
95123
  async function readPackageLock(pluginRoot) {
95095
95124
  const path = join29(pluginRoot, "package-lock.json");
95096
95125
  try {
95097
- const parsed = JSON.parse(await readFile5(path, "utf8"));
95126
+ const parsed = JSON.parse(await readFile6(path, "utf8"));
95098
95127
  return { path, value: isPlainRecord4(parsed) ? parsed : null, changed: false };
95099
95128
  } catch (error) {
95100
95129
  if (error instanceof Error && "code" in error && error.code === "ENOENT") {
@@ -95168,14 +95197,14 @@ async function collectPackageJsonPaths(directory, root, paths) {
95168
95197
  }
95169
95198
 
95170
95199
  // packages/omo-codex/src/install/codex-cache-mcp-manifest.ts
95171
- import { readFile as readFile6, writeFile as writeFile3 } from "node:fs/promises";
95200
+ import { readFile as readFile7, writeFile as writeFile4 } from "node:fs/promises";
95172
95201
  import { join as join30, sep as sep3 } from "node:path";
95173
95202
  var CONTEXT7_API_KEY_ENV = "CONTEXT7_API_KEY";
95174
95203
  async function rewriteCachedMcpManifest(pluginRoot, sourceRoot = pluginRoot) {
95175
95204
  const manifestPath = join30(pluginRoot, ".mcp.json");
95176
95205
  if (!await fileExistsStrict(manifestPath))
95177
95206
  return;
95178
- const raw = await readFile6(manifestPath, "utf8");
95207
+ const raw = await readFile7(manifestPath, "utf8");
95179
95208
  const parsed = JSON.parse(raw);
95180
95209
  if (!isPlainRecord4(parsed) || !isPlainRecord4(parsed.mcpServers))
95181
95210
  return;
@@ -95209,7 +95238,7 @@ async function rewriteCachedMcpManifest(pluginRoot, sourceRoot = pluginRoot) {
95209
95238
  }
95210
95239
  }
95211
95240
  if (changed)
95212
- await writeFile3(manifestPath, `${JSON.stringify(parsed, null, "\t")}
95241
+ await writeFile4(manifestPath, `${JSON.stringify(parsed, null, "\t")}
95213
95242
  `);
95214
95243
  }
95215
95244
  function sanitizeContext7Auth(server) {
@@ -95268,7 +95297,7 @@ async function rewriteCachedManifestRoot(pluginRoot, fromRoot, toRoot) {
95268
95297
  const manifestPath = join30(pluginRoot, ".mcp.json");
95269
95298
  if (!await fileExistsStrict(manifestPath))
95270
95299
  return;
95271
- const raw = await readFile6(manifestPath, "utf8");
95300
+ const raw = await readFile7(manifestPath, "utf8");
95272
95301
  const parsed = JSON.parse(raw);
95273
95302
  if (!isPlainRecord4(parsed) || !isPlainRecord4(parsed.mcpServers))
95274
95303
  return;
@@ -95295,7 +95324,7 @@ async function rewriteCachedManifestRoot(pluginRoot, fromRoot, toRoot) {
95295
95324
  }
95296
95325
  }
95297
95326
  if (changed)
95298
- await writeFile3(manifestPath, `${JSON.stringify(parsed, null, "\t")}
95327
+ await writeFile4(manifestPath, `${JSON.stringify(parsed, null, "\t")}
95299
95328
  `);
95300
95329
  }
95301
95330
 
@@ -95357,7 +95386,7 @@ async function unsupportedEntries(root, directory) {
95357
95386
  }
95358
95387
 
95359
95388
  // packages/omo-codex/src/install/codex-hook-targets.ts
95360
- import { readFile as readFile7 } from "node:fs/promises";
95389
+ import { readFile as readFile8 } from "node:fs/promises";
95361
95390
  import { join as join32, sep as sep5 } from "node:path";
95362
95391
  var PLUGIN_ROOT_TARGET_PATTERN = /\$\{PLUGIN_ROOT\}[\\/]+([^"']+)/g;
95363
95392
  async function findMissingHookCommandTargets(pluginRoot) {
@@ -95365,7 +95394,7 @@ async function findMissingHookCommandTargets(pluginRoot) {
95365
95394
  for (const manifestPath of await hookManifestPaths(pluginRoot)) {
95366
95395
  if (!await fileExistsStrict(manifestPath))
95367
95396
  continue;
95368
- const parsed = JSON.parse(await readFile7(manifestPath, "utf8"));
95397
+ const parsed = JSON.parse(await readFile8(manifestPath, "utf8"));
95369
95398
  collectCommands(parsed, commands);
95370
95399
  }
95371
95400
  const missing = [];
@@ -95389,7 +95418,7 @@ async function hookManifestPaths(pluginRoot) {
95389
95418
  const pluginManifestPath = join32(pluginRoot, ".codex-plugin", "plugin.json");
95390
95419
  if (!await fileExistsStrict(pluginManifestPath))
95391
95420
  return [join32(pluginRoot, "hooks", "hooks.json")];
95392
- const parsed = JSON.parse(await readFile7(pluginManifestPath, "utf8"));
95421
+ const parsed = JSON.parse(await readFile8(pluginManifestPath, "utf8"));
95393
95422
  if (!isPlainRecord4(parsed))
95394
95423
  return [];
95395
95424
  if (typeof parsed.hooks === "string" && parsed.hooks.trim() !== "") {
@@ -95476,7 +95505,7 @@ async function maybeRunNpmInstall(cwd, runCommand, env, args = ["install"]) {
95476
95505
  async function maybeRunNpmBuild(cwd, runCommand, env) {
95477
95506
  if (!await fileExistsStrict(join33(cwd, "package.json")))
95478
95507
  return;
95479
- const packageJson = JSON.parse(await readFile8(join33(cwd, "package.json"), "utf8"));
95508
+ const packageJson = JSON.parse(await readFile9(join33(cwd, "package.json"), "utf8"));
95480
95509
  if (!isPlainRecord4(packageJson))
95481
95510
  return;
95482
95511
  const scripts = packageJson.scripts;
@@ -95487,7 +95516,7 @@ async function maybeRunNpmBuild(cwd, runCommand, env) {
95487
95516
  async function maybeRunNpmSyncSkills(cwd, runCommand, env) {
95488
95517
  if (!await fileExistsStrict(join33(cwd, "package.json")))
95489
95518
  return;
95490
- const packageJson = JSON.parse(await readFile8(join33(cwd, "package.json"), "utf8"));
95519
+ const packageJson = JSON.parse(await readFile9(join33(cwd, "package.json"), "utf8"));
95491
95520
  if (!isPlainRecord4(packageJson))
95492
95521
  return;
95493
95522
  const scripts = packageJson.scripts;
@@ -95550,7 +95579,7 @@ var removedSparkshellPromptSurfaceFiles = new Set(["directive.md", "plugin.json"
95550
95579
  var removedSparkshellTextFilePattern = /\.(?:json|md|toml|ya?ml)$/i;
95551
95580
  async function assertNoRemovedSparkshellPromptReferences(pluginRoot) {
95552
95581
  for (const filePath of await listRemovedSparkshellPromptSurfaceFiles(pluginRoot, "")) {
95553
- const content = await readFile8(join33(pluginRoot, filePath), "utf8");
95582
+ const content = await readFile9(join33(pluginRoot, filePath), "utf8");
95554
95583
  if (!removedSparkshellReferencePattern.test(content))
95555
95584
  continue;
95556
95585
  throw new Error(`removed sparkshell reference found in Codex plugin prompt surface: ${filePath}`);
@@ -95699,7 +95728,7 @@ async function isBrokenCacheSymlink(path) {
95699
95728
  }
95700
95729
  }
95701
95730
  // packages/omo-codex/src/install/codex-cached-marketplace-manifest.ts
95702
- import { mkdir as mkdir4, rename as rename3, rm as rm7, stat as stat5, writeFile as writeFile4 } from "node:fs/promises";
95731
+ import { mkdir as mkdir4, rename as rename3, rm as rm7, stat as stat5, writeFile as writeFile5 } from "node:fs/promises";
95703
95732
  import { join as join35 } from "node:path";
95704
95733
  async function writeCachedMarketplaceManifest(input) {
95705
95734
  const marketplaceDir = join35(input.marketplaceRoot, ".agents", "plugins");
@@ -95712,7 +95741,7 @@ async function writeCachedMarketplaceManifest(input) {
95712
95741
  const manifestPath = join35(marketplaceDir, "marketplace.json");
95713
95742
  const tempPath = join35(marketplaceDir, `.marketplace.json.tmp-${process.pid}-${Date.now()}`);
95714
95743
  try {
95715
- await writeFile4(tempPath, `${JSON.stringify({
95744
+ await writeFile5(tempPath, `${JSON.stringify({
95716
95745
  name: input.marketplaceName,
95717
95746
  plugins: input.plugins.map((plugin) => ({
95718
95747
  name: plugin.name,
@@ -95738,7 +95767,7 @@ async function isDirectory2(path) {
95738
95767
 
95739
95768
  // packages/omo-codex/src/install/codex-package-layout.ts
95740
95769
  import { existsSync as existsSync24 } from "node:fs";
95741
- import { readFile as readFile9 } from "node:fs/promises";
95770
+ import { readFile as readFile10 } from "node:fs/promises";
95742
95771
  import { join as join36 } from "node:path";
95743
95772
  var PACKAGED_CODEX_INSTALLER_NAMES = new Set([
95744
95773
  "@code-yeongyu/lazycodex",
@@ -95754,14 +95783,14 @@ async function shouldBuildSourcePackages(repoRoot) {
95754
95783
  const packageJsonPath = join36(repoRoot, "package.json");
95755
95784
  if (!existsSync24(packageJsonPath))
95756
95785
  return true;
95757
- const packageJson = JSON.parse(await readFile9(packageJsonPath, "utf8"));
95786
+ const packageJson = JSON.parse(await readFile10(packageJsonPath, "utf8"));
95758
95787
  if (!isPlainRecord4(packageJson) || typeof packageJson.name !== "string")
95759
95788
  return true;
95760
95789
  return !PACKAGED_CODEX_INSTALLER_NAMES.has(packageJson.name);
95761
95790
  }
95762
95791
 
95763
95792
  // packages/omo-codex/src/install/codex-config-toml.ts
95764
- import { mkdir as mkdir5, readFile as readFile11 } from "node:fs/promises";
95793
+ import { mkdir as mkdir5, readFile as readFile12 } from "node:fs/promises";
95765
95794
  import { dirname as dirname16 } from "node:path";
95766
95795
 
95767
95796
  // packages/omo-codex/src/install/toml-section-editor.ts
@@ -96358,18 +96387,18 @@ function tomlKeySegment(value) {
96358
96387
  }
96359
96388
 
96360
96389
  // packages/omo-codex/src/install/codex-config-atomic-write.ts
96361
- import { lstat as lstat7, readlink as readlink4, realpath, rename as rename4, unlink, writeFile as writeFile5 } from "node:fs/promises";
96390
+ import { lstat as lstat7, readlink as readlink4, realpath, rename as rename4, unlink as unlink2, writeFile as writeFile6 } from "node:fs/promises";
96362
96391
  import { basename as basename6, dirname as dirname14, isAbsolute as isAbsolute5, join as join37, resolve as resolve10 } from "node:path";
96363
96392
  var RENAME_RETRY_DELAYS_MS = [10, 25, 50];
96364
96393
  var RETRIABLE_RENAME_CODES = new Set(["EPERM", "EBUSY"]);
96365
96394
  async function writeFileAtomic(targetPath, data) {
96366
96395
  const writeTarget = await resolveSymlinkTarget(targetPath);
96367
96396
  const temporaryPath = join37(dirname14(writeTarget), `.tmp-${basename6(writeTarget)}-${process.pid}-${Date.now()}`);
96368
- await writeFile5(temporaryPath, data);
96397
+ await writeFile6(temporaryPath, data);
96369
96398
  try {
96370
96399
  await renameWithRetry(temporaryPath, writeTarget);
96371
96400
  } catch (error) {
96372
- await unlink(temporaryPath).catch((unlinkError) => {
96401
+ await unlink2(temporaryPath).catch((unlinkError) => {
96373
96402
  if (unlinkError instanceof Error)
96374
96403
  return;
96375
96404
  return;
@@ -96864,7 +96893,7 @@ function isRootSetting(line, key) {
96864
96893
 
96865
96894
  // packages/omo-codex/src/install/codex-model-catalog.ts
96866
96895
  init_latest_models();
96867
- import { readFile as readFile10 } from "node:fs/promises";
96896
+ import { readFile as readFile11 } from "node:fs/promises";
96868
96897
  import { join as join38 } from "node:path";
96869
96898
  var FALLBACK_CODEX_MODEL_CATALOG = {
96870
96899
  current: {
@@ -96898,7 +96927,7 @@ var FALLBACK_CODEX_MODEL_CATALOG = {
96898
96927
  async function readCodexModelCatalog(codexPackageRoot) {
96899
96928
  const catalogPath = join38(codexPackageRoot, "plugin", "model-catalog.json");
96900
96929
  try {
96901
- const parsed = JSON.parse(await readFile10(catalogPath, "utf8"));
96930
+ const parsed = JSON.parse(await readFile11(catalogPath, "utf8"));
96902
96931
  return parseCodexModelCatalog(parsed) ?? FALLBACK_CODEX_MODEL_CATALOG;
96903
96932
  } catch (error) {
96904
96933
  if (error instanceof Error)
@@ -97123,7 +97152,7 @@ async function updateCodexConfig(input) {
97123
97152
  await mkdir5(dirname16(input.configPath), { recursive: true });
97124
97153
  let config;
97125
97154
  try {
97126
- config = await readFile11(input.configPath, "utf8");
97155
+ config = await readFile12(input.configPath, "utf8");
97127
97156
  } catch (error) {
97128
97157
  if (!isMissingFileError(error))
97129
97158
  throw error;
@@ -97171,7 +97200,7 @@ function isMissingFileError(error) {
97171
97200
 
97172
97201
  // packages/omo-codex/src/install/codex-hook-trust.ts
97173
97202
  import { createHash as createHash3 } from "node:crypto";
97174
- import { readFile as readFile12 } from "node:fs/promises";
97203
+ import { readFile as readFile13 } from "node:fs/promises";
97175
97204
  import { join as join40 } from "node:path";
97176
97205
  var EVENT_LABELS = new Map([
97177
97206
  ["PreToolUse", "pre_tool_use"],
@@ -97189,7 +97218,7 @@ async function trustedHookStatesForPlugin(input) {
97189
97218
  const manifestPath = join40(input.pluginRoot, ".codex-plugin", "plugin.json");
97190
97219
  if (!await exists(manifestPath))
97191
97220
  return [];
97192
- const manifest = JSON.parse(await readFile12(manifestPath, "utf8"));
97221
+ const manifest = JSON.parse(await readFile13(manifestPath, "utf8"));
97193
97222
  if (!isPlainRecord4(manifest))
97194
97223
  return [];
97195
97224
  const states = [];
@@ -97197,7 +97226,7 @@ async function trustedHookStatesForPlugin(input) {
97197
97226
  const hooksPath = join40(input.pluginRoot, hookPath);
97198
97227
  if (!await exists(hooksPath))
97199
97228
  continue;
97200
- const parsed = JSON.parse(await readFile12(hooksPath, "utf8"));
97229
+ const parsed = JSON.parse(await readFile13(hooksPath, "utf8"));
97201
97230
  if (!isPlainRecord4(parsed) || !isPlainRecord4(parsed.hooks))
97202
97231
  continue;
97203
97232
  states.push(...trustedHookStatesForHooksFile({
@@ -97280,7 +97309,7 @@ function stripDotSlash2(value) {
97280
97309
  }
97281
97310
  async function exists(path) {
97282
97311
  try {
97283
- await readFile12(path, "utf8");
97312
+ await readFile13(path, "utf8");
97284
97313
  return true;
97285
97314
  } catch (error) {
97286
97315
  if (error instanceof Error)
@@ -97380,7 +97409,7 @@ function recordAt2(value, key) {
97380
97409
  }
97381
97410
 
97382
97411
  // packages/omo-codex/src/install/codex-marketplace-snapshot.ts
97383
- import { cp as cp4, mkdir as mkdir6, rename as rename5, rm as rm8, writeFile as writeFile6 } from "node:fs/promises";
97412
+ import { cp as cp4, mkdir as mkdir6, rename as rename5, rm as rm8, writeFile as writeFile7 } from "node:fs/promises";
97384
97413
  import { join as join41, sep as sep7 } from "node:path";
97385
97414
  var INSTALLED_MARKETPLACES_DIR = ".tmp/marketplaces";
97386
97415
  async function writeInstalledMarketplaceSnapshot(input) {
@@ -97400,7 +97429,7 @@ async function writeMarketplaceManifest(marketplaceRoot, marketplace) {
97400
97429
  const manifestDir = join41(marketplaceRoot, ".agents", "plugins");
97401
97430
  await mkdir6(manifestDir, { recursive: true });
97402
97431
  const tempPath = join41(manifestDir, `.marketplace-${process.pid}-${Date.now()}.json.tmp`);
97403
- await writeFile6(tempPath, `${JSON.stringify(marketplace, null, "\t")}
97432
+ await writeFile7(tempPath, `${JSON.stringify(marketplace, null, "\t")}
97404
97433
  `);
97405
97434
  await rename5(tempPath, join41(manifestDir, "marketplace.json"));
97406
97435
  }
@@ -97429,15 +97458,15 @@ function shouldCopyMarketplaceSourcePath(path, root) {
97429
97458
  }
97430
97459
 
97431
97460
  // packages/omo-codex/src/install/link-cached-plugin-agents.ts
97432
- import { copyFile, lstat as lstat11, mkdir as mkdir7, readdir as readdir8, readFile as readFile17, rm as rm12, writeFile as writeFile9 } from "node:fs/promises";
97461
+ import { copyFile, lstat as lstat11, mkdir as mkdir7, readdir as readdir8, readFile as readFile18, rm as rm12, writeFile as writeFile10 } from "node:fs/promises";
97433
97462
  import { basename as basename7, join as join46 } from "node:path";
97434
97463
 
97435
97464
  // packages/omo-codex/src/install/agent-model-overrides.ts
97436
- import { readFile as readFile14, rm as rm9, writeFile as writeFile8 } from "node:fs/promises";
97465
+ import { readFile as readFile15, rm as rm9, writeFile as writeFile9 } from "node:fs/promises";
97437
97466
  import { join as join43 } from "node:path";
97438
97467
 
97439
97468
  // packages/omo-codex/src/install/preserved-agent-settings.ts
97440
- import { lstat as lstat8, readFile as readFile13, readdir as readdir7, writeFile as writeFile7 } from "node:fs/promises";
97469
+ import { lstat as lstat8, readFile as readFile14, readdir as readdir7, writeFile as writeFile8 } from "node:fs/promises";
97441
97470
  import { join as join42 } from "node:path";
97442
97471
 
97443
97472
  // packages/omo-codex/src/install/managed-agent-reasoning-defaults.ts
@@ -97672,7 +97701,7 @@ async function capturePreservedAgentServiceTier(input) {
97672
97701
  async function restorePreservedReasoning(input) {
97673
97702
  if (input.value === undefined)
97674
97703
  return;
97675
- const content = await readFile13(input.target, "utf8");
97704
+ const content = await readFile14(input.target, "utf8");
97676
97705
  const bundledEffort = extractReasoningEffort(content);
97677
97706
  const effort = resolveManagedAgentReasoning({
97678
97707
  agentName: input.agentName,
@@ -97685,33 +97714,33 @@ async function restorePreservedReasoning(input) {
97685
97714
  const replacement = replaceTopLevelStringSetting(content, "model_reasoning_effort", effort, { insertIfMissing: false });
97686
97715
  if (!replacement.replaced)
97687
97716
  return;
97688
- await writeFile7(input.linkPath, replacement.content);
97717
+ await writeFile8(input.linkPath, replacement.content);
97689
97718
  }
97690
97719
  async function restorePreservedServiceTier(input) {
97691
97720
  if (!input.preserved)
97692
97721
  return;
97693
- const content = await readFile13(input.linkPath, "utf8");
97722
+ const content = await readFile14(input.linkPath, "utf8");
97694
97723
  if (extractServiceTier(content) === input.value)
97695
97724
  return;
97696
97725
  const replacement = replaceTopLevelStringSetting(content, "service_tier", input.value, { insertIfMissing: true });
97697
97726
  if (!replacement.replaced)
97698
97727
  return;
97699
- await writeFile7(input.linkPath, replacement.content);
97728
+ await writeFile8(input.linkPath, replacement.content);
97700
97729
  }
97701
97730
  async function restorePreservedModel(input) {
97702
97731
  if (input.value === null)
97703
97732
  return;
97704
- const content = await readFile13(input.linkPath, "utf8");
97733
+ const content = await readFile14(input.linkPath, "utf8");
97705
97734
  if (extractModel(content) === input.value)
97706
97735
  return;
97707
97736
  const replacement = replaceTopLevelStringSetting(content, "model", input.value, { insertIfMissing: true });
97708
97737
  if (!replacement.replaced)
97709
97738
  return;
97710
- await writeFile7(input.linkPath, replacement.content);
97739
+ await writeFile8(input.linkPath, replacement.content);
97711
97740
  }
97712
97741
  async function readTextIfExists(path) {
97713
97742
  try {
97714
- return await readFile13(path, "utf8");
97743
+ return await readFile14(path, "utf8");
97715
97744
  } catch (error) {
97716
97745
  if (nodeErrorCode(error) === "ENOENT")
97717
97746
  return null;
@@ -97833,13 +97862,13 @@ async function writeAgentModelReceipts(codexHome, receipts) {
97833
97862
  await rm9(path, { force: true });
97834
97863
  return;
97835
97864
  }
97836
- await writeFile8(path, `${JSON.stringify(Object.fromEntries(receipts), null, "\t")}
97865
+ await writeFile9(path, `${JSON.stringify(Object.fromEntries(receipts), null, "\t")}
97837
97866
  `);
97838
97867
  }
97839
97868
  async function applyAgentOverride(input) {
97840
97869
  if (input.override === undefined)
97841
97870
  return;
97842
- let content = await readFile14(input.linkPath, "utf8");
97871
+ let content = await readFile15(input.linkPath, "utf8");
97843
97872
  if (input.override.model !== undefined) {
97844
97873
  content = replaceTopLevelStringSetting(content, "model", input.override.model, { insertIfMissing: true }).content;
97845
97874
  }
@@ -97848,7 +97877,7 @@ async function applyAgentOverride(input) {
97848
97877
  insertIfMissing: true
97849
97878
  }).content;
97850
97879
  }
97851
- await writeFile8(input.linkPath, content);
97880
+ await writeFile9(input.linkPath, content);
97852
97881
  }
97853
97882
  function receiptPath(codexHome) {
97854
97883
  return join43(codexHome, "agents", RECEIPT_FILE);
@@ -97883,7 +97912,7 @@ function handEditedAgentModel(installedModel, receipt) {
97883
97912
  }
97884
97913
 
97885
97914
  // packages/omo-codex/src/install/retired-managed-agent-purge.ts
97886
- import { lstat as lstat9, readFile as readFile15, rm as rm10 } from "node:fs/promises";
97915
+ import { lstat as lstat9, readFile as readFile16, rm as rm10 } from "node:fs/promises";
97887
97916
  import { join as join44 } from "node:path";
97888
97917
  var RETIRED_MANAGED_AGENT_FILES = [
97889
97918
  {
@@ -97917,7 +97946,7 @@ function hasRequiredMarkers(content, markers) {
97917
97946
  }
97918
97947
  async function readTextIfExists2(path) {
97919
97948
  try {
97920
- return await readFile15(path, "utf8");
97949
+ return await readFile16(path, "utf8");
97921
97950
  } catch (error) {
97922
97951
  if (nodeErrorCode2(error) === "ENOENT")
97923
97952
  return null;
@@ -97942,7 +97971,7 @@ function nodeErrorCode2(error) {
97942
97971
 
97943
97972
  // packages/omo-codex/src/install/default-agent-role.ts
97944
97973
  import { createHash as createHash4 } from "node:crypto";
97945
- import { lstat as lstat10, readFile as readFile16, rm as rm11 } from "node:fs/promises";
97974
+ import { lstat as lstat10, readFile as readFile17, rm as rm11 } from "node:fs/promises";
97946
97975
  import { join as join45 } from "node:path";
97947
97976
  var REGISTRATION = { name: "default", configFile: "./agents/default.toml" };
97948
97977
  async function installDefaultAgentRole(input) {
@@ -97979,7 +98008,7 @@ async function installDefaultAgentRole(input) {
97979
98008
  if (foreign || existing !== null && !owned) {
97980
98009
  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.");
97981
98010
  }
97982
- const worker = await readFile16(input.worker.path, "utf8");
98011
+ const worker = await readFile17(input.worker.path, "utf8");
97983
98012
  const content = worker.replace(/^name\s*=\s*["']lazycodex-worker-medium["']\s*$/m, 'name = "default"');
97984
98013
  if (content === worker)
97985
98014
  throw new Error("Cannot derive default: medium worker has no matching internal name");
@@ -97989,7 +98018,7 @@ async function installDefaultAgentRole(input) {
97989
98018
  }
97990
98019
  async function readIfPresent(path) {
97991
98020
  try {
97992
- return await readFile16(path, "utf8");
98021
+ return await readFile17(path, "utf8");
97993
98022
  } catch (error) {
97994
98023
  if (error instanceof Error && "code" in error && error.code === "ENOENT")
97995
98024
  return null;
@@ -98050,7 +98079,7 @@ async function syncAgentFile(input) {
98050
98079
  value: input.preservedServiceTier?.get(input.agentName) ?? null
98051
98080
  });
98052
98081
  await applyAgentOverride({ linkPath: input.linkPath, override });
98053
- const model = override?.model ?? extractModel(await readFile17(input.agentPath, "utf8"));
98082
+ const model = override?.model ?? extractModel(await readFile18(input.agentPath, "utf8"));
98054
98083
  return {
98055
98084
  ...model === null ? {} : { model },
98056
98085
  ...override?.reasoningEffort === undefined ? {} : { reasoningEffort: override.reasoningEffort }
@@ -98094,7 +98123,7 @@ async function prepareReplacement(linkPath) {
98094
98123
  async function writeManifest(pluginRoot, agentPaths) {
98095
98124
  const manifestPath = join46(pluginRoot, MANIFEST_FILE);
98096
98125
  const payload = { agents: [...agentPaths].sort() };
98097
- await writeFile9(manifestPath, `${JSON.stringify(payload, null, "\t")}
98126
+ await writeFile10(manifestPath, `${JSON.stringify(payload, null, "\t")}
98098
98127
  `);
98099
98128
  }
98100
98129
  function agentNameFromToml2(fileName) {
@@ -98163,12 +98192,12 @@ function agentNameFromToml3(fileName) {
98163
98192
  }
98164
98193
 
98165
98194
  // packages/omo-codex/src/install/codex-marketplace.ts
98166
- import { readFile as readFile18 } from "node:fs/promises";
98195
+ import { readFile as readFile19 } from "node:fs/promises";
98167
98196
  import { join as join47 } from "node:path";
98168
98197
  var DEFAULT_MARKETPLACE_PATH = "packages/omo-codex/marketplace.json";
98169
98198
  async function readMarketplace(repoRoot, options) {
98170
98199
  const marketplacePath = options?.marketplacePath ?? join47(repoRoot, DEFAULT_MARKETPLACE_PATH);
98171
- const raw = await readFile18(marketplacePath, "utf8");
98200
+ const raw = await readFile19(marketplacePath, "utf8");
98172
98201
  const parsed = JSON.parse(raw);
98173
98202
  if (!isPlainRecord4(parsed))
98174
98203
  throw new Error("marketplace.json must be an object");
@@ -98189,7 +98218,7 @@ function resolvePluginSource(repoRoot, plugin, options) {
98189
98218
  return join47(repoRoot, ...relativePath.split(/[\\/]/));
98190
98219
  }
98191
98220
  async function readPluginManifest(pluginRoot) {
98192
- const raw = await readFile18(join47(pluginRoot, ".codex-plugin", "plugin.json"), "utf8");
98221
+ const raw = await readFile19(join47(pluginRoot, ".codex-plugin", "plugin.json"), "utf8");
98193
98222
  const parsed = JSON.parse(raw);
98194
98223
  if (!isPlainRecord4(parsed))
98195
98224
  throw new Error(`${pluginRoot} plugin.json must be an object`);
@@ -98270,11 +98299,11 @@ function validateLocalSourcePath(path) {
98270
98299
  }
98271
98300
 
98272
98301
  // packages/omo-codex/src/install/lazycodex-version-stamp.ts
98273
- import { readdir as readdir9, readFile as readFile19, writeFile as writeFile10 } from "node:fs/promises";
98302
+ import { readdir as readdir9, readFile as readFile20, writeFile as writeFile11 } from "node:fs/promises";
98274
98303
  import { join as join48 } from "node:path";
98275
98304
  async function readDistributionManifest(repoRoot) {
98276
98305
  try {
98277
- const parsed = JSON.parse(await readFile19(join48(repoRoot, "package.json"), "utf8"));
98306
+ const parsed = JSON.parse(await readFile20(join48(repoRoot, "package.json"), "utf8"));
98278
98307
  if (!isPlainRecord4(parsed) || typeof parsed.version !== "string" || parsed.version.trim().length === 0)
98279
98308
  return;
98280
98309
  return {
@@ -98310,7 +98339,7 @@ async function stampLazyCodexPluginVersion(input) {
98310
98339
  async function writeLazyCodexInstallSnapshot(input) {
98311
98340
  if (input.distributionManifest === undefined)
98312
98341
  return;
98313
- await writeFile10(join48(input.pluginRoot, "lazycodex-install.json"), `${JSON.stringify({
98342
+ await writeFile11(join48(input.pluginRoot, "lazycodex-install.json"), `${JSON.stringify({
98314
98343
  packageName: input.distributionManifest.name,
98315
98344
  version: input.distributionManifest.version
98316
98345
  }, null, "\t")}
@@ -98318,11 +98347,11 @@ async function writeLazyCodexInstallSnapshot(input) {
98318
98347
  }
98319
98348
  async function stampJsonVersion(path, version) {
98320
98349
  try {
98321
- const parsed = JSON.parse(await readFile19(path, "utf8"));
98350
+ const parsed = JSON.parse(await readFile20(path, "utf8"));
98322
98351
  if (!isPlainRecord4(parsed))
98323
98352
  return;
98324
98353
  parsed.version = version;
98325
- await writeFile10(path, `${JSON.stringify(parsed, null, "\t")}
98354
+ await writeFile11(path, `${JSON.stringify(parsed, null, "\t")}
98326
98355
  `);
98327
98356
  } catch (error) {
98328
98357
  if (error instanceof Error)
@@ -98332,7 +98361,7 @@ async function stampJsonVersion(path, version) {
98332
98361
  }
98333
98362
  async function readPluginHookPaths(manifestPath) {
98334
98363
  try {
98335
- const parsed = JSON.parse(await readFile19(manifestPath, "utf8"));
98364
+ const parsed = JSON.parse(await readFile20(manifestPath, "utf8"));
98336
98365
  if (!isPlainRecord4(parsed))
98337
98366
  return [];
98338
98367
  if (typeof parsed.hooks === "string" && parsed.hooks.trim().length > 0)
@@ -98352,11 +98381,11 @@ function stripDotSlash3(path) {
98352
98381
  }
98353
98382
  async function stampHookStatusMessages(path, version) {
98354
98383
  try {
98355
- const parsed = JSON.parse(await readFile19(path, "utf8"));
98384
+ const parsed = JSON.parse(await readFile20(path, "utf8"));
98356
98385
  if (!isPlainRecord4(parsed))
98357
98386
  return;
98358
98387
  stampHookGroups(parsed.hooks, version);
98359
- await writeFile10(path, `${JSON.stringify(parsed, null, "\t")}
98388
+ await writeFile11(path, `${JSON.stringify(parsed, null, "\t")}
98360
98389
  `);
98361
98390
  } catch (error) {
98362
98391
  if (error instanceof Error)
@@ -98433,7 +98462,7 @@ var defaultRunCommand = async (command, args, options) => {
98433
98462
  };
98434
98463
 
98435
98464
  // packages/omo-codex/src/install/codex-project-local-cleanup.ts
98436
- import { copyFile as copyFile2, lstat as lstat12, readFile as readFile20, writeFile as writeFile11 } from "node:fs/promises";
98465
+ import { copyFile as copyFile2, lstat as lstat12, readFile as readFile21, writeFile as writeFile12 } from "node:fs/promises";
98437
98466
  import { dirname as dirname17, join as join49, resolve as resolve11 } from "node:path";
98438
98467
  var LEGACY_AGENT_CONFLICT_KEYS = ["max_threads"];
98439
98468
  var PROJECT_LOCAL_ARTIFACT_PATHS = [
@@ -98453,7 +98482,7 @@ async function repairNearestProjectLocalCodexArtifacts(input) {
98453
98482
  const artifacts = await collectProjectLocalArtifacts(project.artifactRoots);
98454
98483
  const configs = [];
98455
98484
  for (const configPath of project.configPaths) {
98456
- const original = await readFile20(configPath, "utf8");
98485
+ const original = await readFile21(configPath, "utf8");
98457
98486
  const repair = repairProjectLocalCodexConfigText(original);
98458
98487
  if (!repair.changed) {
98459
98488
  configs.push({
@@ -98466,7 +98495,7 @@ async function repairNearestProjectLocalCodexArtifacts(input) {
98466
98495
  }
98467
98496
  const backupPath = `${configPath}.backup-${formatBackupTimestamp(input.now?.() ?? new Date)}`;
98468
98497
  await copyFile2(configPath, backupPath);
98469
- await writeFile11(configPath, `${repair.config.trimEnd()}
98498
+ await writeFile12(configPath, `${repair.config.trimEnd()}
98470
98499
  `);
98471
98500
  configs.push({
98472
98501
  projectRoot: project.projectRoot,
@@ -98663,13 +98692,13 @@ function formatUnknownError(error) {
98663
98692
 
98664
98693
  // packages/omo-codex/src/install/lsp-daemon-reaper.ts
98665
98694
  import { createHash as createHash5 } from "node:crypto";
98666
- import { lstat as lstat13, readFile as readFile22, readdir as readdir11, rm as rm13 } from "node:fs/promises";
98695
+ import { lstat as lstat13, readFile as readFile23, readdir as readdir11, rm as rm13 } from "node:fs/promises";
98667
98696
  import { tmpdir as tmpdir4 } from "node:os";
98668
98697
  import { join as join50, posix as posix6 } from "node:path";
98669
98698
 
98670
98699
  // packages/omo-codex/src/install/lsp-daemon-reaper-attestation.ts
98671
98700
  import { execFile } from "node:child_process";
98672
- import { readFile as readFile21, readdir as readdir10, readlink as readlink5 } from "node:fs/promises";
98701
+ import { readFile as readFile22, readdir as readdir10, readlink as readlink5 } from "node:fs/promises";
98673
98702
  import { connect } from "node:net";
98674
98703
  import { basename as basename8 } from "node:path";
98675
98704
  var PROBE_TIMEOUT_MS = 500;
@@ -98711,7 +98740,7 @@ async function attestLegacyDaemonOwnership(input, deps = {}) {
98711
98740
  return false;
98712
98741
  }
98713
98742
  async function attestLinuxOwnership(input, deps) {
98714
- const readFileImpl = deps.readFile ?? readFile21;
98743
+ const readFileImpl = deps.readFile ?? readFile22;
98715
98744
  const readDirImpl = deps.readDir ?? readdir10;
98716
98745
  const readLinkImpl = deps.readLink ?? readlink5;
98717
98746
  const procNetUnix = await readText(readFileImpl, "/proc/net/unix");
@@ -98936,7 +98965,7 @@ async function readRegularTrimmedFile(path) {
98936
98965
  return null;
98937
98966
  if (!stats.isFile())
98938
98967
  return "non_regular";
98939
- const content = (await readFile22(path, "utf8")).trim();
98968
+ const content = (await readFile23(path, "utf8")).trim();
98940
98969
  return content.length > 0 ? content : null;
98941
98970
  }
98942
98971
  function shortDigest(value) {
@@ -98997,11 +99026,11 @@ function resolveCodexInstallerBinDir(input) {
98997
99026
  }
98998
99027
 
98999
99028
  // packages/omo-codex/src/install/codex-installed-bin-dir.ts
99000
- import { readFile as readFile23, readdir as readdir12, writeFile as writeFile12 } from "node:fs/promises";
99029
+ import { readFile as readFile24, readdir as readdir12, writeFile as writeFile13 } from "node:fs/promises";
99001
99030
  import { join as join52 } from "node:path";
99002
99031
  var INSTALLED_BIN_DIR_MANIFEST = ".installed-bin-dir.json";
99003
99032
  async function writeInstalledCodexBinDir(input) {
99004
- await writeFile12(join52(input.pluginRoot, INSTALLED_BIN_DIR_MANIFEST), `${JSON.stringify({ binDir: input.binDir }, null, 2)}
99033
+ await writeFile13(join52(input.pluginRoot, INSTALLED_BIN_DIR_MANIFEST), `${JSON.stringify({ binDir: input.binDir }, null, 2)}
99005
99034
  `);
99006
99035
  }
99007
99036
  async function readInstalledCodexBinDir(codexHome) {
@@ -99027,7 +99056,7 @@ async function installedBinDirManifestPaths(codexHome) {
99027
99056
  return paths;
99028
99057
  }
99029
99058
  async function readBinDirFromManifest(manifestPath) {
99030
- const raw = await readFile23(manifestPath, "utf8").catch(() => null);
99059
+ const raw = await readFile24(manifestPath, "utf8").catch(() => null);
99031
99060
  if (raw === null)
99032
99061
  return null;
99033
99062
  let parsed;
@@ -99045,7 +99074,7 @@ async function readBinDirFromManifest(manifestPath) {
99045
99074
  }
99046
99075
 
99047
99076
  // packages/omo-codex/src/install/codex-git-bash-hooks.ts
99048
- import { readFile as readFile24, writeFile as writeFile13 } from "node:fs/promises";
99077
+ import { readFile as readFile25, writeFile as writeFile14 } from "node:fs/promises";
99049
99078
  import { join as join53 } from "node:path";
99050
99079
  var WINDOWS_ONLY_GIT_BASH_HOOKS = new Set([
99051
99080
  "./hooks/pre-tool-use-recommending-git-bash-mcp.json",
@@ -99055,13 +99084,13 @@ async function removeGitBashHooksOffWindows(input) {
99055
99084
  if (input.platform === "win32")
99056
99085
  return;
99057
99086
  const manifestPath = join53(input.pluginRoot, ".codex-plugin", "plugin.json");
99058
- const parsed = JSON.parse(await readFile24(manifestPath, "utf8"));
99087
+ const parsed = JSON.parse(await readFile25(manifestPath, "utf8"));
99059
99088
  if (!isPlainRecord4(parsed) || !Array.isArray(parsed.hooks))
99060
99089
  return;
99061
99090
  const hooks = parsed.hooks.filter((hook) => typeof hook !== "string" || !WINDOWS_ONLY_GIT_BASH_HOOKS.has(hook));
99062
99091
  if (hooks.length === parsed.hooks.length)
99063
99092
  return;
99064
- await writeFile13(manifestPath, `${JSON.stringify({ ...parsed, hooks }, null, "\t")}
99093
+ await writeFile14(manifestPath, `${JSON.stringify({ ...parsed, hooks }, null, "\t")}
99065
99094
  `);
99066
99095
  }
99067
99096
 
@@ -99432,12 +99461,12 @@ function defaultRunCommand2(command, args) {
99432
99461
  });
99433
99462
  }
99434
99463
  // packages/omo-codex/src/install/codex-cleanup.ts
99435
- import { lstat as lstat16, readFile as readFile27, readdir as readdir14, rm as rm15, rmdir } from "node:fs/promises";
99464
+ import { lstat as lstat16, readFile as readFile28, readdir as readdir14, rm as rm15, rmdir } from "node:fs/promises";
99436
99465
  import { homedir as homedir9 } from "node:os";
99437
99466
  import { isAbsolute as isAbsolute11, join as join62, relative as relative7, resolve as resolve16 } from "node:path";
99438
99467
 
99439
99468
  // packages/omo-codex/src/install/codex-cleanup-bins.ts
99440
- import { lstat as lstat14, readFile as readFile25, readdir as readdir13, readlink as readlink6, rm as rm14 } from "node:fs/promises";
99469
+ import { lstat as lstat14, readFile as readFile26, readdir as readdir13, readlink as readlink6, rm as rm14 } from "node:fs/promises";
99441
99470
  import { dirname as dirname20, isAbsolute as isAbsolute9, join as join60, resolve as resolve14 } from "node:path";
99442
99471
  var ROOT_RUNTIME_BIN_NAME = "omo";
99443
99472
  var MANAGED_CODEX_BIN_NAMES = new Set([
@@ -99499,12 +99528,12 @@ async function isManagedCodexBin(linkPath, platform, binName) {
99499
99528
  }
99500
99529
  if (!entryStat.isFile())
99501
99530
  return false;
99502
- const content = await readFile25(linkPath, "utf8");
99531
+ const content = await readFile26(linkPath, "utf8");
99503
99532
  return content.includes(RUNTIME_WRAPPER_MARKER) || content.includes(COMMAND_SHIM_MARKER);
99504
99533
  }
99505
99534
 
99506
99535
  // packages/omo-codex/src/install/codex-cleanup-config.ts
99507
- import { lstat as lstat15, mkdir as mkdir8, readFile as readFile26, writeFile as writeFile14 } from "node:fs/promises";
99536
+ import { lstat as lstat15, mkdir as mkdir8, readFile as readFile27, writeFile as writeFile15 } from "node:fs/promises";
99508
99537
  import { dirname as dirname21 } from "node:path";
99509
99538
  var MANAGED_MARKETPLACES = ["sisyphuslabs", "lazycodex", "code-yeongyu-codex-plugins"];
99510
99539
  var LEGACY_MANAGED_CODEX_AGENT_NAMES_TO_PURGE2 = ["codex-ultrawork-reviewer"];
@@ -99537,14 +99566,14 @@ function cleanupCodexLightConfigText(config) {
99537
99566
  async function cleanupCodexConfig(configPath, now) {
99538
99567
  if (!await configExists(configPath))
99539
99568
  return { changed: false };
99540
- const original = await readFile26(configPath, "utf8");
99569
+ const original = await readFile27(configPath, "utf8");
99541
99570
  const next = cleanupCodexLightConfigText(original);
99542
99571
  if (next === original)
99543
99572
  return { changed: false };
99544
99573
  const backupPath = `${configPath}.backup-${formatBackupTimestamp2(now?.() ?? new Date)}`;
99545
99574
  await mkdir8(dirname21(configPath), { recursive: true });
99546
- await writeFile14(backupPath, original);
99547
- await writeFile14(configPath, `${next.trimEnd()}
99575
+ await writeFile15(backupPath, original);
99576
+ await writeFile15(configPath, `${next.trimEnd()}
99548
99577
  `);
99549
99578
  return { changed: true, backupPath };
99550
99579
  }
@@ -99821,13 +99850,13 @@ async function collectInstalledAgentPaths(codexHome, configPath) {
99821
99850
  async function readManagedAgentPathsFromConfig(codexHome, configPath) {
99822
99851
  if (!await exists6(configPath))
99823
99852
  return [];
99824
- const config = await readFile27(configPath, "utf8");
99853
+ const config = await readFile28(configPath, "utf8");
99825
99854
  return MANAGED_CODEX_AGENT_NAMES2.filter((agentName) => config.includes(`config_file = ${JSON.stringify(`./agents/${agentName}.toml`)}`)).map((agentName) => join62(codexHome, "agents", `${agentName}.toml`));
99826
99855
  }
99827
99856
  async function readInstalledAgentManifest(manifestPath) {
99828
99857
  if (!await exists6(manifestPath))
99829
99858
  return [];
99830
- const parsed = JSON.parse(await readFile27(manifestPath, "utf8"));
99859
+ const parsed = JSON.parse(await readFile28(manifestPath, "utf8"));
99831
99860
  if (!isPlainRecord4(parsed) || !Array.isArray(parsed.agents))
99832
99861
  return [];
99833
99862
  return parsed.agents.filter((path) => typeof path === "string");
@@ -100019,7 +100048,7 @@ node "%~dp0omo" %*\r
100019
100048
  // packages/omo-senpi/src/install/plugin-artifacts.ts
100020
100049
  import { createHash as createHash7 } from "node:crypto";
100021
100050
  import { constants as constants9 } from "node:fs";
100022
- import { access as access2, readFile as readFile29, stat as stat6 } from "node:fs/promises";
100051
+ import { access as access3, readFile as readFile30, stat as stat6 } from "node:fs/promises";
100023
100052
  import { dirname as dirname25, join as join66 } from "node:path";
100024
100053
 
100025
100054
  // packages/memory-core/src/personas/manifest.ts
@@ -100038,7 +100067,7 @@ var PERSONA_ASSET_FILES = [
100038
100067
 
100039
100068
  // packages/omo-senpi/src/install/senpi-settings.ts
100040
100069
  import { constants as constants8 } from "node:fs";
100041
- import { access, copyFile as copyFile3, mkdir as mkdir9, readFile as readFile28, rename as rename6, writeFile as writeFile15 } from "node:fs/promises";
100070
+ import { access as access2, copyFile as copyFile3, mkdir as mkdir9, readFile as readFile29, rename as rename6, writeFile as writeFile16 } from "node:fs/promises";
100042
100071
  import { basename as basename10, dirname as dirname24, join as join65, resolve as resolve19 } from "node:path";
100043
100072
  var OMO_SENPI_PACKAGE_NAME = "@code-yeongyu/omo-senpi";
100044
100073
  var GENERATED_PLUGIN_BASENAME = /^omo-senpi-cli-plugin-[A-Za-z0-9]{6}$/;
@@ -100049,7 +100078,7 @@ var LEGACY_BUILTIN_SHADOW_PACKAGES = [
100049
100078
  async function readSettings(settingsPath) {
100050
100079
  let raw;
100051
100080
  try {
100052
- raw = await readFile28(settingsPath, "utf8");
100081
+ raw = await readFile29(settingsPath, "utf8");
100053
100082
  } catch (error) {
100054
100083
  if (isErrno(error, "ENOENT"))
100055
100084
  return {};
@@ -100096,11 +100125,11 @@ async function writeSettingsAtomically(settingsPath, settings) {
100096
100125
  if (await fileExists(settingsPath)) {
100097
100126
  await copyFile3(settingsPath, backupPath);
100098
100127
  } else {
100099
- await writeFile15(backupPath, `{}
100128
+ await writeFile16(backupPath, `{}
100100
100129
  `, "utf8");
100101
100130
  }
100102
100131
  const tempPath = `${settingsPath}.${process.pid}.${Date.now()}.tmp`;
100103
- await writeFile15(tempPath, `${JSON.stringify(settings, null, 2)}
100132
+ await writeFile16(tempPath, `${JSON.stringify(settings, null, 2)}
100104
100133
  `, "utf8");
100105
100134
  await rename6(tempPath, settingsPath);
100106
100135
  return backupPath;
@@ -100123,7 +100152,7 @@ function isRecord15(value) {
100123
100152
  async function readPackageName(packagePath) {
100124
100153
  let raw;
100125
100154
  try {
100126
- raw = await readFile28(join65(packagePath, "package.json"), "utf8");
100155
+ raw = await readFile29(join65(packagePath, "package.json"), "utf8");
100127
100156
  } catch (error) {
100128
100157
  if (isErrno(error, "ENOENT") || isErrno(error, "ENOTDIR"))
100129
100158
  return;
@@ -100141,7 +100170,7 @@ async function readPackageName(packagePath) {
100141
100170
  }
100142
100171
  async function fileExists(path) {
100143
100172
  try {
100144
- await access(path, constants8.F_OK);
100173
+ await access2(path, constants8.F_OK);
100145
100174
  return true;
100146
100175
  } catch (error) {
100147
100176
  if (isErrno(error, "ENOENT"))
@@ -100204,6 +100233,7 @@ var REQUIRED_PLUGIN_ARTIFACTS = [
100204
100233
  join66("skills", "visual-qa", "SKILL.md"),
100205
100234
  join66("skills-conditional", "x-search", "SKILL.md"),
100206
100235
  join66("runtime", "agent-toolkit-sdk", "sdk.js"),
100236
+ join66("runtime", "bunshin-ts", "sdk.js"),
100207
100237
  join66("runtime", "thread-sdk", "sdk.js"),
100208
100238
  join66("runtime", "ast-grep-mcp", "cli.js"),
100209
100239
  join66("runtime", "lsp-daemon", "dist", "cli.js"),
@@ -100246,7 +100276,7 @@ async function verifyAstGrepRuntimeIntegrity(pluginPath, platform) {
100246
100276
  runtimeStat = await stat6(runtimeEntry);
100247
100277
  if (!runtimeStat.isFile())
100248
100278
  throw new Error("runtime is not a file");
100249
- await access2(runtimeEntry, constants9.R_OK | constants9.X_OK);
100279
+ await access3(runtimeEntry, constants9.R_OK | constants9.X_OK);
100250
100280
  } catch (error) {
100251
100281
  throw astGrepIntegrityError(runtimeEntry, `runtime is unreadable or non-executable: ${messageOf(error)}`);
100252
100282
  }
@@ -100255,7 +100285,7 @@ async function verifyAstGrepRuntimeIntegrity(pluginPath, platform) {
100255
100285
  }
100256
100286
  let manifest;
100257
100287
  try {
100258
- manifest = JSON.parse(await readFile29(manifestPath, "utf8"));
100288
+ manifest = JSON.parse(await readFile30(manifestPath, "utf8"));
100259
100289
  } catch (error) {
100260
100290
  throw astGrepIntegrityError(runtimeEntry, `manifest is unreadable or invalid JSON: ${messageOf(error)}`);
100261
100291
  }
@@ -100264,7 +100294,7 @@ async function verifyAstGrepRuntimeIntegrity(pluginPath, platform) {
100264
100294
  }
100265
100295
  let actualSha256;
100266
100296
  try {
100267
- actualSha256 = createHash7("sha256").update(await readFile29(runtimeEntry)).digest("hex");
100297
+ actualSha256 = createHash7("sha256").update(await readFile30(runtimeEntry)).digest("hex");
100268
100298
  } catch (error) {
100269
100299
  throw astGrepIntegrityError(runtimeEntry, `runtime hash could not be computed: ${messageOf(error)}`);
100270
100300
  }
@@ -100289,7 +100319,7 @@ function messageOf(error) {
100289
100319
  }
100290
100320
  async function fileExists2(path) {
100291
100321
  try {
100292
- await access2(path, constants9.F_OK);
100322
+ await access3(path, constants9.F_OK);
100293
100323
  return true;
100294
100324
  } catch (error) {
100295
100325
  if (isErrno2(error, "ENOENT"))
@@ -107982,7 +108012,7 @@ function getSuggestedInstallTag(currentVersion) {
107982
108012
  // packages/omo-opencode/src/cli/doctor/checks/system.ts
107983
108013
  init_jsonc_parser2();
107984
108014
  init_plugin_identity();
107985
- var runtime4 = globalThis;
108015
+ var runtime5 = globalThis;
107986
108016
  var defaultDeps5 = {
107987
108017
  findOpenCodeBinary,
107988
108018
  getOpenCodeVersion: getOpenCodeVersion3,
@@ -108043,7 +108073,7 @@ async function gatherSystemInfo(deps = defaultDeps5) {
108043
108073
  opencodePath: binaryInfo?.path ?? null,
108044
108074
  pluginVersion,
108045
108075
  loadedVersion: loadedInfo.loadedVersion,
108046
- bunVersion: runtime4.Bun?.version ?? "unavailable",
108076
+ bunVersion: runtime5.Bun?.version ?? "unavailable",
108047
108077
  configPath: pluginInfo.configPath,
108048
108078
  configValid: isConfigValid(pluginInfo.configPath, deps),
108049
108079
  isLocalDev: pluginInfo.isLocalDev
@@ -109522,7 +109552,7 @@ async function pathExists2(dir) {
109522
109552
  // packages/omo-opencode/src/cli/doctor/checks/codex.ts
109523
109553
  init_src();
109524
109554
  import { existsSync as existsSync61 } from "node:fs";
109525
- import { lstat as lstat17, readdir as readdir15, readFile as readFile30 } from "node:fs/promises";
109555
+ import { lstat as lstat17, readdir as readdir15, readFile as readFile31 } from "node:fs/promises";
109526
109556
  import { homedir as homedir26 } from "node:os";
109527
109557
  import { basename as basename13, join as join99, resolve as resolve27 } from "node:path";
109528
109558
  // packages/omo-opencode/package.json
@@ -109747,7 +109777,7 @@ async function readCodexConfigSummary(configPath) {
109747
109777
  companionLifecycleHookStateEvents: []
109748
109778
  };
109749
109779
  }
109750
- const content = await readFile30(configPath, "utf8");
109780
+ const content = await readFile31(configPath, "utf8");
109751
109781
  return {
109752
109782
  exists: true,
109753
109783
  marketplaceConfigured: content.includes("[marketplaces.sisyphuslabs]"),
@@ -109775,7 +109805,7 @@ async function readLinkedAgents(codexHome) {
109775
109805
  }
109776
109806
  async function readJson(path) {
109777
109807
  try {
109778
- const parsed = JSON.parse(await readFile30(path, "utf8"));
109808
+ const parsed = JSON.parse(await readFile31(path, "utf8"));
109779
109809
  return isPlainRecord(parsed) ? parsed : null;
109780
109810
  } catch (error) {
109781
109811
  if (error instanceof Error)
@@ -109899,7 +109929,7 @@ function resolveLatestVersion(input) {
109899
109929
 
109900
109930
  // packages/omo-opencode/src/cli/doctor/checks/codex-components.ts
109901
109931
  init_src();
109902
- import { readdir as readdir16, readFile as readFile31, stat as stat7 } from "node:fs/promises";
109932
+ import { readdir as readdir16, readFile as readFile32, stat as stat7 } from "node:fs/promises";
109903
109933
  import { homedir as homedir27 } from "node:os";
109904
109934
  import { dirname as dirname40, isAbsolute as isAbsolute15, join as join100, relative as relative10, resolve as resolve28, sep as sep11 } from "node:path";
109905
109935
  var CODEX_COMPONENTS_CHECK_ID = "codex-components";
@@ -110152,7 +110182,7 @@ function degradedDetailLines(entries) {
110152
110182
  }
110153
110183
  async function readJson2(path) {
110154
110184
  try {
110155
- const parsed = JSON.parse(await readFile31(path, "utf8"));
110185
+ const parsed = JSON.parse(await readFile32(path, "utf8"));
110156
110186
  return isRecord18(parsed) ? parsed : null;
110157
110187
  } catch (error) {
110158
110188
  if (error instanceof Error)
@@ -110180,7 +110210,7 @@ function isRecord18(value) {
110180
110210
 
110181
110211
  // packages/omo-opencode/src/cli/doctor/checks/codex-runtime-wrapper.ts
110182
110212
  import { existsSync as existsSync62 } from "node:fs";
110183
- import { readFile as readFile32 } from "node:fs/promises";
110213
+ import { readFile as readFile33 } from "node:fs/promises";
110184
110214
  import { homedir as homedir28 } from "node:os";
110185
110215
  import { join as join101, resolve as resolve29 } from "node:path";
110186
110216
  var RUNTIME_WRAPPER_MARKER2 = "OMO_GENERATED_RUNTIME_WRAPPER";
@@ -110225,7 +110255,7 @@ async function checkCodexRuntimeWrapper(deps = {}) {
110225
110255
  }
110226
110256
  async function readRuntimeWrapper(path) {
110227
110257
  try {
110228
- return await readFile32(path, "utf8");
110258
+ return await readFile33(path, "utf8");
110229
110259
  } catch (error) {
110230
110260
  if (error instanceof Error)
110231
110261
  return null;
@@ -112149,6 +112179,73 @@ async function loadDeviceKeyring(store) {
112149
112179
  import { execFile as execFile5 } from "node:child_process";
112150
112180
  import { homedir as homedir30 } from "node:os";
112151
112181
  import { join as join105 } from "node:path";
112182
+
112183
+ // packages/omo-opencode/src/shared/bun-ffi-shim.ts
112184
+ async function loadBunFfi() {
112185
+ return import("bun:ffi");
112186
+ }
112187
+
112188
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/process-state.ts
112189
+ var KEY = Symbol.for("omo.keychain-helper.process.v1");
112190
+ function keychainProcessState() {
112191
+ const holder = globalThis;
112192
+ holder[KEY] ??= {
112193
+ secretsQueue: Promise.resolve(),
112194
+ interactionSwitch: undefined,
112195
+ approvalCache: undefined,
112196
+ entryCandidates: [],
112197
+ helperAccess: undefined,
112198
+ heldPromptLocks: new Set,
112199
+ handOff: undefined
112200
+ };
112201
+ return holder[KEY];
112202
+ }
112203
+
112204
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/secrets-gate.ts
112205
+ async function loadInteractionSwitch() {
112206
+ const state = keychainProcessState();
112207
+ if (state.interactionSwitch !== undefined)
112208
+ return state.interactionSwitch;
112209
+ if (process.platform !== "darwin")
112210
+ return state.interactionSwitch = null;
112211
+ try {
112212
+ const { dlopen, FFIType } = await loadBunFfi();
112213
+ const security = dlopen("/System/Library/Frameworks/Security.framework/Security", {
112214
+ SecKeychainSetUserInteractionAllowed: { args: [FFIType.u8], returns: FFIType.i32 }
112215
+ });
112216
+ state.interactionSwitch = (allowed) => {
112217
+ security.symbols.SecKeychainSetUserInteractionAllowed(allowed ? 1 : 0);
112218
+ };
112219
+ } catch {
112220
+ state.interactionSwitch = null;
112221
+ }
112222
+ return state.interactionSwitch;
112223
+ }
112224
+ function gatedSecrets(run) {
112225
+ const state = keychainProcessState();
112226
+ const next = state.secretsQueue.then(run, run);
112227
+ state.secretsQueue = next.then(() => {
112228
+ return;
112229
+ }, () => {
112230
+ return;
112231
+ });
112232
+ return next;
112233
+ }
112234
+ function silentSecrets(run) {
112235
+ return gatedSecrets(async () => {
112236
+ const setInteraction = await loadInteractionSwitch();
112237
+ if (setInteraction === null)
112238
+ throw new Error("Keychain interaction cannot be switched off on this host.");
112239
+ setInteraction(false);
112240
+ try {
112241
+ return await run();
112242
+ } finally {
112243
+ setInteraction(true);
112244
+ }
112245
+ });
112246
+ }
112247
+
112248
+ // packages/omo-opencode/src/cli/account-keys/keystore.ts
112152
112249
  var DEFAULT_SERVICE = "omo-cli";
112153
112250
  function defaultRun(argv, input) {
112154
112251
  const [file, ...args] = argv;
@@ -112172,7 +112269,7 @@ function createOsKeyStore(name, platform = process.platform, run = defaultRun, s
112172
112269
  const resolved = secrets === undefined ? run === defaultRun && typeof Bun !== "undefined" ? Bun.secrets : null : secrets;
112173
112270
  switch (platform) {
112174
112271
  case "darwin":
112175
- return resolved !== null ? createBunSecretsKeyStore(name, resolved) : createMacOsKeychainKeyStore(name, run);
112272
+ return resolved !== null ? createBunSecretsKeyStore(name, gateRealSecrets(resolved)) : createMacOsKeychainKeyStore(name, run);
112176
112273
  case "linux":
112177
112274
  return resolved !== null ? createBunSecretsKeyStore(name, resolved) : createLibsecretKeyStore(name, run);
112178
112275
  case "win32":
@@ -112191,6 +112288,10 @@ async function guarded(run, fail, argv, input) {
112191
112288
  throw fail();
112192
112289
  }
112193
112290
  }
112291
+ var gateRealSecrets = (secrets) => typeof Bun !== "undefined" && secrets === Bun.secrets ? {
112292
+ get: (key) => gatedSecrets(() => secrets.get(key)),
112293
+ set: (entry) => gatedSecrets(() => secrets.set(entry))
112294
+ } : secrets;
112194
112295
  function createBunSecretsKeyStore(name, secrets) {
112195
112296
  const key = { service: DEFAULT_SERVICE, name };
112196
112297
  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.");
@@ -112728,64 +112829,705 @@ async function loginDevice(session, options) {
112728
112829
  }
112729
112830
 
112730
112831
  // packages/omo-opencode/src/cli/service-auth/keystore.ts
112731
- import { createHash as createHash12, randomUUID as randomUUID7 } from "node:crypto";
112732
- import { basename as basename15 } from "node:path";
112832
+ import { createHash as createHash12, randomUUID as randomUUID8 } from "node:crypto";
112833
+ import { basename as basename17 } from "node:path";
112733
112834
 
112734
- // packages/omo-opencode/src/cli/service-auth/secret-service-lock.ts
112735
- import { spawn as spawn5 } from "node:child_process";
112736
- var DEFAULT_COLLECTION = "/org/freedesktop/secrets/aliases/default";
112737
- var PROBE_TIMEOUT_MS2 = 1e4;
112738
- var parseLockedReply = (stdout) => {
112739
- const match = /<\s*(true|false)\s*>/.exec(stdout);
112740
- if (match === null)
112741
- return null;
112742
- return match[1] === "true" ? "locked" : "unlocked";
112835
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/darwin-backend.ts
112836
+ import { homedir as homedir31 } from "node:os";
112837
+ import { join as join109 } from "node:path";
112838
+
112839
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/client.ts
112840
+ init_zod();
112841
+ init_bun_spawn_shim();
112842
+ var MUTATING = new Set(["write", "stage", "retire", "promote", "remove"]);
112843
+ var helperReplySchema = object({
112844
+ owned: boolean2(),
112845
+ value: string2(),
112846
+ marker: boolean2(),
112847
+ cdat: number2(),
112848
+ mdat: number2(),
112849
+ partition: _enum(["ours", "other", "none", "unknown"]),
112850
+ present: object({ staging: boolean2(), old: boolean2(), oldSlots: array(number2().int().min(0).max(7)).optional() }).strict(),
112851
+ missing: boolean2(),
112852
+ recover: boolean2(),
112853
+ ok: boolean2(),
112854
+ created: boolean2(),
112855
+ skipped: boolean2(),
112856
+ slot: number2().int().min(0).max(7),
112857
+ error: _enum(["locked", "store", "not-owned", "exists", "missing", "denied", "refused"]),
112858
+ reason: string2(),
112859
+ status: number2()
112860
+ }).partial().strict();
112861
+
112862
+ class HelperProtocolError extends Error {
112863
+ }
112864
+ async function firstLine(stream) {
112865
+ const reader = stream.getReader();
112866
+ const decoder = new TextDecoder;
112867
+ let text = "";
112868
+ for (;; ) {
112869
+ const newline = text.indexOf(`
112870
+ `);
112871
+ if (newline !== -1)
112872
+ return text.slice(0, newline);
112873
+ const chunk = await reader.read();
112874
+ if (chunk.done)
112875
+ return null;
112876
+ text += decoder.decode(chunk.value, { stream: true });
112877
+ }
112878
+ }
112879
+ function isFlushable(stream) {
112880
+ return typeof stream.flush === "function";
112881
+ }
112882
+ var spawnDetachedHelper = (path) => {
112883
+ const child = spawn([path], {
112884
+ stdin: "pipe",
112885
+ stdout: "pipe",
112886
+ stderr: "ignore",
112887
+ detached: true,
112888
+ env: process.env.HOME === undefined ? {} : { HOME: process.env.HOME }
112889
+ });
112890
+ const pid = child.pid;
112891
+ if (pid === undefined)
112892
+ throw new HelperProtocolError("The keychain helper did not start.");
112893
+ const stdin = child.stdin;
112894
+ return {
112895
+ pid,
112896
+ send: (line) => {
112897
+ stdin.write(line);
112898
+ if (isFlushable(stdin))
112899
+ stdin.flush();
112900
+ },
112901
+ reply: firstLine(child.stdout),
112902
+ close: () => {
112903
+ stdin.end();
112904
+ }
112905
+ };
112743
112906
  };
112744
- var probeSecretServiceLock = () => new Promise((resolve) => {
112745
- const child = spawn5("gdbus", [
112746
- "call",
112747
- "--session",
112748
- "--dest",
112749
- "org.freedesktop.secrets",
112750
- "--object-path",
112751
- DEFAULT_COLLECTION,
112752
- "--method",
112753
- "org.freedesktop.DBus.Properties.Get",
112754
- "org.freedesktop.Secret.Collection",
112755
- "Locked"
112756
- ], { stdio: ["ignore", "pipe", "ignore"] });
112757
- let stdout = "";
112758
- const timer = setTimeout(() => {
112759
- child.kill();
112760
- resolve("unknown");
112761
- }, PROBE_TIMEOUT_MS2);
112762
- child.stdout.on("data", (chunk) => {
112763
- stdout += chunk.toString();
112907
+ async function callHelper(path, call, options = {}) {
112908
+ const mutates = MUTATING.has(call.verb);
112909
+ if (mutates && options.lease === undefined)
112910
+ throw new HelperProtocolError(`The ${call.verb} helper call needs the session lock.`);
112911
+ const helper = (options.spawn ?? spawnDetachedHelper)(path);
112912
+ let handedOver = false;
112913
+ try {
112914
+ if (mutates && options.lease !== undefined) {
112915
+ await options.lease.handOver(helper.pid);
112916
+ handedOver = true;
112917
+ }
112918
+ helper.send(`${JSON.stringify({ v: 1, verb: call.verb, account: call.account, ...call.value === undefined ? {} : { value: call.value } })}
112919
+ `);
112920
+ const line = await helper.reply;
112921
+ if (handedOver && options.lease !== undefined) {
112922
+ handedOver = false;
112923
+ await options.lease.restore();
112924
+ }
112925
+ if (line === null)
112926
+ throw new HelperProtocolError(`The keychain helper exited without answering ${call.verb}.`);
112927
+ let json;
112928
+ try {
112929
+ json = JSON.parse(line);
112930
+ } catch {
112931
+ throw new HelperProtocolError(`The keychain helper sent a ${call.verb} reply that is not JSON.`);
112932
+ }
112933
+ const parsed = helperReplySchema.safeParse(json);
112934
+ if (!parsed.success)
112935
+ throw new HelperProtocolError(`The keychain helper sent an unexpected ${call.verb} reply.`);
112936
+ return parsed.data;
112937
+ } catch (error) {
112938
+ if (handedOver && options.lease !== undefined) {
112939
+ try {
112940
+ await options.lease.restore();
112941
+ } catch (restoreError) {
112942
+ throw new AggregateError([error, restoreError], `The ${call.verb} helper call failed and the session lock could not be restored.`);
112943
+ }
112944
+ }
112945
+ throw error;
112946
+ } finally {
112947
+ helper.close();
112948
+ }
112949
+ }
112950
+
112951
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/location.ts
112952
+ import { dirname as dirname42, join as join106, posix as posix13 } from "node:path";
112953
+ import { fileURLToPath as fileURLToPath8 } from "node:url";
112954
+ function bundleCandidates(moduleUrl) {
112955
+ const root = dirname42(dirname42(dirname42(fileURLToPath8(moduleUrl))));
112956
+ return [join106(root, "bin", "darwin", "omo-keychain"), join106(root, "omo-keychain")];
112957
+ }
112958
+ function machineCandidates(home, arch = process.arch) {
112959
+ const runtimeArch = arch === "arm64" ? "arm64" : "x64";
112960
+ return [
112961
+ `/Applications/OmO.app/Contents/Resources/omo-runtime/darwin-${runtimeArch}/omo-keychain`,
112962
+ posix13.join(home, "Applications", "OmO.app", "Contents", "Resources", "omo-runtime", `darwin-${runtimeArch}`, "omo-keychain"),
112963
+ posix13.join(home, ".bun", "install", "global", "node_modules", "omo-ai", "bin", "darwin", "omo-keychain")
112964
+ ];
112965
+ }
112966
+ async function locateHelper(candidates, verify) {
112967
+ const rejected = [];
112968
+ for (const path of candidates) {
112969
+ const verdict = await verify(path);
112970
+ if (verdict === "valid")
112971
+ return { kind: "found", path };
112972
+ if (verdict === "invalid")
112973
+ rejected.push(path);
112974
+ }
112975
+ return rejected.length === 0 ? { kind: "missing" } : { kind: "invalid", rejected };
112976
+ }
112977
+
112978
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/pin.ts
112979
+ import { readdirSync as readdirSync14, rmSync as rmSync9 } from "node:fs";
112980
+ import { chmod as chmod2, copyFile as copyFile4, constants as constants13, mkdtemp as mkdtemp2, rm as rm16, stat as stat8 } from "node:fs/promises";
112981
+ import { tmpdir as tmpdir6 } from "node:os";
112982
+ import { basename as basename15, join as join107 } from "node:path";
112983
+ var DIR_PREFIX = "omo-keychain-";
112984
+ var OWNED_DIR = new RegExp(`^${DIR_PREFIX}(\\d+)-`);
112985
+ var isAlive = (pid) => {
112986
+ try {
112987
+ process.kill(pid, 0);
112988
+ return true;
112989
+ } catch (error) {
112990
+ return !(error instanceof Error && ("code" in error) && error.code === "ESRCH");
112991
+ }
112992
+ };
112993
+ function sweepDeadPinDirs(root = tmpdir6()) {
112994
+ const removed = [];
112995
+ let entries;
112996
+ try {
112997
+ entries = readdirSync14(root);
112998
+ } catch {
112999
+ return removed;
113000
+ }
113001
+ for (const entry of entries) {
113002
+ const owner = OWNED_DIR.exec(entry)?.[1];
113003
+ if (owner === undefined || Number(owner) === process.pid || isAlive(Number(owner)))
113004
+ continue;
113005
+ try {
113006
+ rmSync9(join107(root, entry), { recursive: true, force: true });
113007
+ } catch {
113008
+ continue;
113009
+ }
113010
+ removed.push(entry);
113011
+ }
113012
+ return removed;
113013
+ }
113014
+ var processDir;
113015
+ async function processPinDir() {
113016
+ if (processDir !== undefined)
113017
+ return processDir;
113018
+ sweepDeadPinDirs();
113019
+ const dir = await mkdtemp2(join107(tmpdir6(), `${DIR_PREFIX}${process.pid}-`));
113020
+ process.once("exit", () => rmSync9(dir, { recursive: true, force: true }));
113021
+ processDir = dir;
113022
+ return dir;
113023
+ }
113024
+ var pinned = new Map;
113025
+ async function sourceIdentity(source) {
113026
+ const info = await stat8(source);
113027
+ return `${source}\x00${info.dev}\x00${info.ino}\x00${info.size}\x00${info.mtimeMs}\x00${info.ctimeMs}`;
113028
+ }
113029
+ async function copyAndVerify(source, verify, dir) {
113030
+ const target = join107(dir, `${crypto.randomUUID()}-${basename15(source)}`);
113031
+ try {
113032
+ await copyFile4(source, target, constants13.COPYFILE_EXCL);
113033
+ await chmod2(target, 320);
113034
+ } catch (error) {
113035
+ await rm16(target, { force: true });
113036
+ return { kind: "unavailable", reason: error instanceof Error ? error.message : String(error) };
113037
+ }
113038
+ let verdict;
113039
+ try {
113040
+ verdict = await verify(target);
113041
+ } catch (error) {
113042
+ await rm16(target, { force: true });
113043
+ return { kind: "unavailable", reason: error instanceof Error ? error.message : String(error) };
113044
+ }
113045
+ if (verdict === "valid")
113046
+ return { kind: "pinned", path: target };
113047
+ await rm16(target, { force: true });
113048
+ return { kind: "invalid" };
113049
+ }
113050
+ async function pinVerifiedCopy(source, verify, dir) {
113051
+ let identity;
113052
+ try {
113053
+ identity = `${dir ?? ""}\x00${await sourceIdentity(source)}`;
113054
+ } catch (error) {
113055
+ return { kind: "unavailable", reason: error instanceof Error ? error.message : String(error) };
113056
+ }
113057
+ const known = pinned.get(identity);
113058
+ if (known !== undefined) {
113059
+ const result = await known;
113060
+ if (result.kind !== "pinned")
113061
+ return result;
113062
+ let verdict;
113063
+ try {
113064
+ verdict = await verify(result.path);
113065
+ } catch (error) {
113066
+ pinned.delete(identity);
113067
+ await rm16(result.path, { force: true });
113068
+ return { kind: "unavailable", reason: error instanceof Error ? error.message : String(error) };
113069
+ }
113070
+ if (verdict === "valid")
113071
+ return result;
113072
+ }
113073
+ const created = Promise.resolve(dir ?? processPinDir()).then((target) => copyAndVerify(source, verify, target), (error) => ({ kind: "unavailable", reason: error instanceof Error ? error.message : String(error) }));
113074
+ pinned.set(identity, created);
113075
+ const result = await created;
113076
+ if (result.kind !== "pinned")
113077
+ pinned.delete(identity);
113078
+ return result;
113079
+ }
113080
+
113081
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/signature.ts
113082
+ import { stat as stat9 } from "node:fs/promises";
113083
+ init_bun_spawn_shim();
113084
+ 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"';
113085
+ var STRICT_ALL_ARCHITECTURES = 1 << 4 | 1 << 0;
113086
+ var UTF8 = 134217984;
113087
+ var security;
113088
+ async function loadSecurity() {
113089
+ if (security !== undefined)
113090
+ return security;
113091
+ try {
113092
+ const { dlopen, FFIType, ptr } = await loadBunFfi();
113093
+ const cf = dlopen("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation", {
113094
+ CFStringCreateWithCString: { args: [FFIType.u64, FFIType.ptr, FFIType.u32], returns: FFIType.u64 },
113095
+ CFURLCreateFromFileSystemRepresentation: { args: [FFIType.u64, FFIType.ptr, FFIType.i64, FFIType.bool], returns: FFIType.u64 },
113096
+ CFRelease: { args: [FFIType.u64], returns: FFIType.void }
113097
+ });
113098
+ const sec = dlopen("/System/Library/Frameworks/Security.framework/Security", {
113099
+ SecStaticCodeCreateWithPath: { args: [FFIType.u64, FFIType.u32, FFIType.ptr], returns: FFIType.i32 },
113100
+ SecRequirementCreateWithString: { args: [FFIType.u64, FFIType.u32, FFIType.ptr], returns: FFIType.i32 },
113101
+ SecStaticCodeCheckValidityWithErrors: { args: [FFIType.u64, FFIType.u32, FFIType.u64, FFIType.u64], returns: FFIType.i32 }
113102
+ });
113103
+ const cString = (text) => Buffer.from(`${text}\x00`, "utf8");
113104
+ security = {
113105
+ check(path, requirement) {
113106
+ const pathBytes = Buffer.from(path, "utf8");
113107
+ const url = BigInt(cf.symbols.CFURLCreateFromFileSystemRepresentation(0n, ptr(pathBytes), pathBytes.length, false));
113108
+ const text = BigInt(cf.symbols.CFStringCreateWithCString(0n, ptr(cString(requirement)), UTF8));
113109
+ const codeOut = new BigUint64Array(1);
113110
+ const requirementOut = new BigUint64Array(1);
113111
+ try {
113112
+ if (url === 0n || text === 0n)
113113
+ return false;
113114
+ if (sec.symbols.SecStaticCodeCreateWithPath(url, 0, ptr(codeOut)) !== 0)
113115
+ return false;
113116
+ if (sec.symbols.SecRequirementCreateWithString(text, 0, ptr(requirementOut)) !== 0)
113117
+ return false;
113118
+ const code = codeOut[0] ?? 0n;
113119
+ const designated = requirementOut[0] ?? 0n;
113120
+ return sec.symbols.SecStaticCodeCheckValidityWithErrors(code, STRICT_ALL_ARCHITECTURES, designated, 0n) === 0;
113121
+ } finally {
113122
+ for (const ref of [url, text, codeOut[0] ?? 0n, requirementOut[0] ?? 0n])
113123
+ if (ref !== 0n)
113124
+ cf.symbols.CFRelease(ref);
113125
+ }
113126
+ }
113127
+ };
113128
+ } catch {
113129
+ security = null;
113130
+ }
113131
+ return security;
113132
+ }
113133
+ async function verifyWithCodesign(path, requirement) {
113134
+ const child = spawn(["/usr/bin/codesign", "--verify", "--strict", `-R=${requirement}`, path], {
113135
+ stdout: "ignore",
113136
+ stderr: "ignore",
113137
+ env: {}
112764
113138
  });
112765
- child.on("error", () => {
112766
- clearTimeout(timer);
112767
- resolve("unknown");
113139
+ return await child.exited === 0;
113140
+ }
113141
+ var verifyWithSecurityFramework = async (path, requirement) => {
113142
+ const loaded = await loadSecurity();
113143
+ return loaded === null ? verifyWithCodesign(path, requirement) : loaded.check(path, requirement);
113144
+ };
113145
+ async function fileIdentity(path) {
113146
+ try {
113147
+ const info = await stat9(path);
113148
+ if (!info.isFile())
113149
+ return null;
113150
+ return `${path}\x00${info.dev}\x00${info.ino}\x00${info.size}\x00${info.mtimeMs}\x00${info.ctimeMs}`;
113151
+ } catch {
113152
+ return null;
113153
+ }
113154
+ }
113155
+ function createSignatureChecker(check = verifyWithSecurityFramework, requirement = KEYCHAIN_HELPER_REQUIREMENT) {
113156
+ const verdicts = new Map;
113157
+ const checker = async (path) => {
113158
+ const before = await fileIdentity(path);
113159
+ if (before === null)
113160
+ return "missing";
113161
+ const known = verdicts.get(before);
113162
+ if (known !== undefined)
113163
+ return known;
113164
+ const passed = await check(path, requirement);
113165
+ if (await fileIdentity(path) !== before)
113166
+ return "invalid";
113167
+ const verdict = passed ? "valid" : "invalid";
113168
+ verdicts.set(before, verdict);
113169
+ return verdict;
113170
+ };
113171
+ return checker;
113172
+ }
113173
+ var processChecker;
113174
+ var processSignatureChecker = () => processChecker ??= createSignatureChecker();
113175
+
113176
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/access.ts
113177
+ async function resolveHelperAccess(candidates, options = {}) {
113178
+ const verify = options.verify ?? processSignatureChecker();
113179
+ let source;
113180
+ let pin;
113181
+ try {
113182
+ const location = await locateHelper(candidates, verify);
113183
+ if (location.kind !== "found")
113184
+ return location;
113185
+ source = location.path;
113186
+ pin = await (options.pin ?? pinVerifiedCopy)(source, verify);
113187
+ } catch (error) {
113188
+ return { kind: "unavailable", reason: error instanceof Error ? error.message : String(error) };
113189
+ }
113190
+ if (pin.kind === "invalid")
113191
+ return { kind: "invalid", rejected: [source] };
113192
+ if (pin.kind === "unavailable")
113193
+ return { kind: "unavailable", reason: pin.reason };
113194
+ const pinned = pin.path;
113195
+ const spawn = options.spawn ?? spawnDetachedHelper;
113196
+ return {
113197
+ kind: "ready",
113198
+ path: pinned,
113199
+ call: async (call, lease) => {
113200
+ const verdict = await verify(pinned).catch((error) => {
113201
+ throw new HelperProtocolError(`OmO's keychain helper could not be checked before it ran: ${error instanceof Error ? error.message : String(error)}`);
113202
+ });
113203
+ if (verdict !== "valid")
113204
+ throw new HelperProtocolError("OmO's keychain helper changed on disk and failed its signature check; it was not run.");
113205
+ return callHelper(pinned, call, { spawn, ...lease === undefined ? {} : { lease } });
113206
+ }
113207
+ };
113208
+ }
113209
+
113210
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/approval-cache.ts
113211
+ var systemClock = { nowSeconds: () => Date.now() / 1000, sleepMs: (ms) => new Promise((resolve) => setTimeout(resolve, ms)) };
113212
+ function isEntryValid(entry, current, nowSeconds) {
113213
+ if (nowSeconds < entry.readStartedAt)
113214
+ return false;
113215
+ return current.cdat === entry.cdat && current.mdat === entry.mdat && Math.floor(current.mdat) < Math.floor(entry.readStartedAt);
113216
+ }
113217
+ function createApprovalCache(clock = systemClock) {
113218
+ let entry = null;
113219
+ let deniedForBackground = false;
113220
+ let pending = null;
113221
+ return {
113222
+ consume(current) {
113223
+ if (entry === null)
113224
+ return null;
113225
+ if (!isEntryValid(entry, current, clock.nowSeconds())) {
113226
+ entry = null;
113227
+ return null;
113228
+ }
113229
+ return entry.value;
113230
+ },
113231
+ deniedForBackground: () => deniedForBackground,
113232
+ inFlight: () => pending,
113233
+ approve(run) {
113234
+ if (pending !== null)
113235
+ return pending;
113236
+ const readStartedAt = clock.nowSeconds();
113237
+ const started = run().then((answer) => {
113238
+ if (answer.kind === "approved") {
113239
+ entry = { value: answer.value, ...answer.attributes, readStartedAt };
113240
+ deniedForBackground = false;
113241
+ } else if (answer.kind === "denied")
113242
+ deniedForBackground = true;
113243
+ return answer;
113244
+ });
113245
+ const settled = () => {
113246
+ if (pending === started)
113247
+ pending = null;
113248
+ };
113249
+ started.then(settled, settled);
113250
+ pending = started;
113251
+ return started;
113252
+ },
113253
+ async afterOwnWrite(value, readAttributes) {
113254
+ if (entry === null)
113255
+ return;
113256
+ const written = await readAttributes();
113257
+ if (written === null) {
113258
+ entry = null;
113259
+ return;
113260
+ }
113261
+ while (Math.floor(clock.nowSeconds()) <= Math.floor(written.mdat)) {
113262
+ await clock.sleepMs(Math.max(1, Math.ceil((Math.floor(written.mdat) + 1 - clock.nowSeconds()) * 1000)));
113263
+ }
113264
+ const readStartedAt = clock.nowSeconds();
113265
+ const fresh = await readAttributes();
113266
+ entry = fresh === null ? null : { value, ...fresh, readStartedAt };
113267
+ },
113268
+ drop() {
113269
+ entry = null;
113270
+ }
113271
+ };
113272
+ }
113273
+ var processApprovalCache = () => {
113274
+ const state = keychainProcessState();
113275
+ state.approvalCache ??= createApprovalCache();
113276
+ return state.approvalCache;
113277
+ };
113278
+
113279
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/darwin-read.ts
113280
+ var ROW_8B_DEFAULT = "re-login";
113281
+
113282
+ class HelperReadError extends Error {
113283
+ failure;
113284
+ constructor(failure, message) {
113285
+ super(message);
113286
+ this.failure = failure;
113287
+ }
113288
+ }
113289
+ function failure2(reply) {
113290
+ if (reply.error === "locked")
113291
+ return new HelperReadError("locked", "The keychain is locked.");
113292
+ return new HelperReadError("store", `The keychain helper answered ${reply.error ?? "unexpectedly"}.`);
113293
+ }
113294
+ async function approveOnce(deps) {
113295
+ const running = deps.cache.inFlight();
113296
+ if (running !== null)
113297
+ return running;
113298
+ const release = await deps.takePromptLock();
113299
+ if (release === null)
113300
+ throw new HelperReadError("pending", "Another omo process is waiting for your keychain approval.");
113301
+ try {
113302
+ return await deps.cache.approve(async () => {
113303
+ const reply = await deps.access.call({ verb: "approve", account: deps.account });
113304
+ if (reply.missing === true)
113305
+ return { kind: "missing" };
113306
+ if (reply.error === "denied")
113307
+ return { kind: "denied" };
113308
+ if (reply.error !== undefined || reply.value === undefined || reply.cdat === undefined || reply.mdat === undefined)
113309
+ throw failure2(reply);
113310
+ return { kind: "approved", value: reply.value, attributes: { cdat: reply.cdat, mdat: reply.mdat } };
113311
+ });
113312
+ } finally {
113313
+ await release();
113314
+ }
113315
+ }
113316
+ async function readThroughHelper(deps, allowPrompt) {
113317
+ const reply = await deps.access.call({ verb: "read", account: deps.account });
113318
+ if (reply.error !== undefined)
113319
+ throw failure2(reply);
113320
+ if (reply.missing === true)
113321
+ return { kind: "missing", reply };
113322
+ if (reply.owned === true && reply.value !== undefined)
113323
+ return { kind: "value", value: reply.value, source: reply.marker === true || reply.recover === true ? "owned" : "owned-unmarked", reply };
113324
+ const own = await deps.ownSilentGet().catch(() => {
113325
+ return;
112768
113326
  });
112769
- child.on("close", (code) => {
112770
- clearTimeout(timer);
112771
- resolve(code === 0 ? parseLockedReply(stdout) ?? "absent" : "absent");
113327
+ if (typeof own === "string")
113328
+ return { kind: "value", value: own, source: "own-identity", reply };
113329
+ if (reply.cdat === undefined || reply.mdat === undefined)
113330
+ throw failure2(reply);
113331
+ const cached = deps.cache.consume({ cdat: reply.cdat, mdat: reply.mdat });
113332
+ if (cached !== null)
113333
+ return { kind: "value", value: cached, source: "approved", reply };
113334
+ const reloginInstead = reply.partition !== "ours" && reply.partition !== "none" && (deps.row8b ?? ROW_8B_DEFAULT) === "re-login";
113335
+ if (!allowPrompt) {
113336
+ if (reloginInstead)
113337
+ return { kind: "missing", reply };
113338
+ throw new HelperReadError("pending", "The keychain needs your approval; run an omo command in a terminal.");
113339
+ }
113340
+ if (deps.background && deps.cache.deniedForBackground())
113341
+ throw new HelperReadError("pending", "Keychain access was denied; run an omo command in a terminal to approve it.");
113342
+ if (reloginInstead)
113343
+ return { kind: "missing", reply };
113344
+ if (deps.noDialog === true)
113345
+ throw new HelperReadError("pending", "The keychain hand-off cannot show a dialog.");
113346
+ if (deps.handOff !== undefined && await deps.handOff()) {
113347
+ const after = await deps.access.call({ verb: "read", account: deps.account });
113348
+ if (after.owned === true && after.value !== undefined)
113349
+ return { kind: "value", value: after.value, source: "owned", reply: after };
113350
+ }
113351
+ const answer = await approveOnce(deps);
113352
+ if (answer.kind === "approved")
113353
+ return { kind: "value", value: answer.value, source: "approved", reply };
113354
+ if (answer.kind === "missing")
113355
+ return { kind: "missing", reply };
113356
+ throw new HelperReadError("denied", "Keychain access was denied.");
113357
+ }
113358
+
113359
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/recovery.ts
113360
+ var OLD_SLOT_COUNT = 8;
113361
+ var oldSlotName = (account, slot) => slot === 0 ? `${account}.old` : `${account}.old.${slot}`;
113362
+ function recoveryPlan(names) {
113363
+ if (!names.original && names.staging)
113364
+ return names.old ? ["promote", "delete-old"] : ["promote"];
113365
+ if (!names.original && names.old)
113366
+ return ["delete-old"];
113367
+ if (names.original && names.staging)
113368
+ return names.old ? ["remove-staging", "delete-old"] : ["remove-staging"];
113369
+ if (names.original && names.old)
113370
+ return ["delete-old"];
113371
+ return [];
113372
+ }
113373
+ function oldSlotsOf(reply) {
113374
+ return reply.present?.oldSlots ?? (reply.present?.old === true ? [0] : []);
113375
+ }
113376
+ function namesFromRead(reply) {
113377
+ const original = reply.owned === false || reply.owned === true && reply.recover !== true;
113378
+ return { original, staging: reply.present?.staging === true, old: reply.present?.old === true, oldSlots: oldSlotsOf(reply) };
113379
+ }
113380
+ async function deleteOld(name, helper, deleteOwn) {
113381
+ const removed = await helper({ verb: "remove", account: name }).catch(() => null);
113382
+ if (removed?.ok === true)
113383
+ return true;
113384
+ return deleteOwn(name).catch(() => false);
113385
+ }
113386
+ async function deleteOldSlots(account, slots, helper, deleteOwn) {
113387
+ let cleared = true;
113388
+ for (const slot of slots)
113389
+ if (!await deleteOld(oldSlotName(account, slot), helper, deleteOwn))
113390
+ cleared = false;
113391
+ return cleared;
113392
+ }
113393
+ async function runRecovery(account, names, helper, deleteOwnOld) {
113394
+ const applied = [];
113395
+ for (const step of recoveryPlan(names)) {
113396
+ 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);
113397
+ if (!ok && step !== "delete-old")
113398
+ return { applied, failed: step };
113399
+ if (ok)
113400
+ applied.push(step);
113401
+ }
113402
+ return { applied, failed: null };
113403
+ }
113404
+
113405
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/migration.ts
113406
+ var MIGRATABLE = new Set(["own-identity", "owned-unmarked", "approved"]);
113407
+ async function migrate(account, value, source, helper, deleteOwnOld) {
113408
+ if (!MIGRATABLE.has(source))
113409
+ return { kind: "skipped", reason: "not-migratable" };
113410
+ if ((await helper({ verb: "stage", account, value })).ok !== true)
113411
+ return { kind: "failed", step: "stage" };
113412
+ const retired = await helper({ verb: "retire", account });
113413
+ if (retired.error === "exists" && retired.reason === "old-slots-full" || retired.ok === true && retired.skipped === true) {
113414
+ await helper({ verb: "remove", account: `${account}.staging` });
113415
+ return { kind: "skipped", reason: "old-slots-full" };
113416
+ }
113417
+ if (retired.ok !== true)
113418
+ return { kind: "failed", step: "retire" };
113419
+ const slot = retired.slot ?? 0;
113420
+ if ((await helper({ verb: "promote", account })).ok !== true)
113421
+ return { kind: "failed", step: "promote" };
113422
+ return { kind: "migrated", oldDeleted: await deleteOld(oldSlotName(account, slot), helper, deleteOwnOld) };
113423
+ }
113424
+
113425
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/darwin-store.ts
113426
+ class HelperOldSlotsFull extends Error {
113427
+ }
113428
+ var ALL_OLD_SLOTS = Array.from({ length: OLD_SLOT_COUNT }, (_, slot) => slot);
113429
+ 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.';
113430
+ var failed = (reply, verb) => new HelperReadError(reply.error === "locked" ? "locked" : "store", `The keychain helper could not ${verb} the sign-in (${reply.error ?? "no answer"}).`);
113431
+ function lockedDarwinStore(deps, lease) {
113432
+ const helper = (call) => deps.access.call(call, lease);
113433
+ const deleteOwnOld = (name) => deps.ownDelete(name);
113434
+ let lastRead = null;
113435
+ const read = async () => {
113436
+ const result = await readThroughHelper(deps, false);
113437
+ lastRead = result.kind === "value" ? result : null;
113438
+ return result.kind === "value" ? result.value : null;
113439
+ };
113440
+ return {
113441
+ async recover() {
113442
+ const reply = await deps.access.call({ verb: "read", account: deps.account });
113443
+ if (reply.error === undefined)
113444
+ await runRecovery(deps.account, namesFromRead(reply), helper, deleteOwnOld);
113445
+ },
113446
+ read,
113447
+ async settle() {
113448
+ if (lastRead === null)
113449
+ return;
113450
+ const outcome = await migrate(deps.account, lastRead.value, lastRead.source, helper, deleteOwnOld);
113451
+ if (outcome.kind === "skipped" && outcome.reason === "old-slots-full")
113452
+ deps.notice(`omo: ${OLD_SLOTS_FULL_MESSAGE}`);
113453
+ if (outcome.kind === "failed")
113454
+ deps.notice(`omo: the macOS keychain item could not be moved to OmO's keychain helper (${outcome.step}); it keeps working as before.`);
113455
+ },
113456
+ async write(value, intent, beforeRetire) {
113457
+ const state = await deps.access.call({ verb: "read", account: deps.account });
113458
+ if (state.error !== undefined)
113459
+ throw failed(state, "check");
113460
+ if (state.owned === false) {
113461
+ const approved = state.cdat !== undefined && state.mdat !== undefined && deps.cache.consume({ cdat: state.cdat, mdat: state.mdat }) !== null;
113462
+ const readable = lastRead !== null || approved || await deps.ownSilentGet().catch(() => {
113463
+ return;
113464
+ }) !== undefined;
113465
+ if (readable || intent !== "fresh-sign-in") {
113466
+ await deps.ownOverwrite(value);
113467
+ if (lastRead?.source === "approved")
113468
+ await deps.cache.afterOwnWrite(value, async () => {
113469
+ const after = await deps.access.call({ verb: "read", account: deps.account });
113470
+ return after.cdat === undefined || after.mdat === undefined ? null : { cdat: after.cdat, mdat: after.mdat };
113471
+ });
113472
+ return;
113473
+ }
113474
+ await beforeRetire?.();
113475
+ const retired = await helper({ verb: "retire", account: deps.account });
113476
+ if (retired.reason === "old-slots-full" || retired.ok === true && retired.skipped === true)
113477
+ throw new HelperOldSlotsFull(OLD_SLOTS_FULL_MESSAGE);
113478
+ if (retired.ok !== true)
113479
+ throw failed(retired, "replace");
113480
+ }
113481
+ const written = await helper({ verb: "write", account: deps.account, value });
113482
+ if (written.ok !== true)
113483
+ throw failed(written, "save");
113484
+ lastRead = { kind: "value", value, source: "owned", reply: written };
113485
+ },
113486
+ async clear() {
113487
+ const removed = await helper({ verb: "remove", account: deps.account });
113488
+ if (removed.error === "not-owned")
113489
+ await deps.ownDelete(deps.account);
113490
+ else if (removed.ok !== true)
113491
+ throw failed(removed, "remove");
113492
+ await helper({ verb: "remove", account: `${deps.account}.staging` });
113493
+ const present = await helper({ verb: "read", account: deps.account });
113494
+ const slots = present.error === undefined ? oldSlotsOf(present) : ALL_OLD_SLOTS;
113495
+ await deleteOldSlots(deps.account, slots, helper, deleteOwnOld);
113496
+ lastRead = null;
113497
+ }
113498
+ };
113499
+ }
113500
+
113501
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/owner-marker.ts
113502
+ init_bun_spawn_shim();
113503
+ var MARKER_LINE = /^\s*"gena"<blob>="omo-owner\/1"\s*$/m;
113504
+ var ITEM_NOT_FOUND = 44;
113505
+ var probeOwnerMarker = async (service, account, keychain) => {
113506
+ const args = ["find-generic-password", "-s", service, "-a", account, ...keychain === undefined ? [] : [keychain]];
113507
+ const child = spawn(["/usr/bin/security", ...args], {
113508
+ stdout: "pipe",
113509
+ stderr: "ignore",
113510
+ env: process.env.HOME === undefined ? {} : { HOME: process.env.HOME }
112772
113511
  });
112773
- });
113512
+ const [stdout, code] = await Promise.all([new Response(child.stdout).text(), child.exited]);
113513
+ if (code === ITEM_NOT_FOUND)
113514
+ return "absent";
113515
+ if (code !== 0)
113516
+ return "unknown";
113517
+ return MARKER_LINE.test(stdout) ? "helper-owned" : "other";
113518
+ };
112774
113519
 
112775
- // packages/omo-opencode/src/cli/service-auth/credential-lock.ts
112776
- import { AsyncLocalStorage as AsyncLocalStorage3 } from "node:async_hooks";
112777
- import { createHash as createHash11 } from "node:crypto";
113520
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/prompt-lock.ts
112778
113521
  import { mkdir as mkdir11 } from "node:fs/promises";
112779
- import { homedir as homedir31 } from "node:os";
112780
- import { join as join106 } from "node:path";
113522
+ import { dirname as dirname45 } from "node:path";
112781
113523
 
112782
113524
  // packages/team-core/src/team-state-store/lock-publish.ts
112783
- import { access as access4, open as open3, unlink as unlink3 } from "node:fs/promises";
112784
- import { dirname as dirname42 } from "node:path";
113525
+ import { access as access5, open as open3, unlink as unlink4 } from "node:fs/promises";
113526
+ import { dirname as dirname43 } from "node:path";
112785
113527
 
112786
113528
  // packages/team-core/src/team-state-store/lock-record.ts
112787
113529
  import { randomUUID as randomUUID6 } from "node:crypto";
112788
- import { readFile as readFile34, stat as stat9 } from "node:fs/promises";
113530
+ import { readFile as readFile35, stat as stat11 } from "node:fs/promises";
112789
113531
 
112790
113532
  // packages/memory-core/src/locks/process-identity.ts
112791
113533
  import { execFile as execFile7 } from "node:child_process";
@@ -112883,23 +113625,23 @@ function rename8(from, to, admit) {
112883
113625
  }
112884
113626
  var sync = resilientNamespace(fsSync, "sync");
112885
113627
  var {
112886
- access: access3,
112887
- chmod: chmod2,
112888
- copyFile: copyFile4,
113628
+ access: access4,
113629
+ chmod: chmod3,
113630
+ copyFile: copyFile5,
112889
113631
  cp: cp5,
112890
113632
  link,
112891
113633
  lstat: lstat18,
112892
113634
  mkdir: mkdir10,
112893
- mkdtemp: mkdtemp2,
112894
- readFile: readFile33,
113635
+ mkdtemp: mkdtemp3,
113636
+ readFile: readFile34,
112895
113637
  readdir: readdir17,
112896
113638
  readlink: readlink7,
112897
113639
  realpath: realpath2,
112898
- rm: rm16,
113640
+ rm: rm17,
112899
113641
  rmdir: rmdir2,
112900
- stat: stat8,
113642
+ stat: stat10,
112901
113643
  statfs,
112902
- unlink: unlink2
113644
+ unlink: unlink3
112903
113645
  } = promises;
112904
113646
  var {
112905
113647
  accessSync: accessSync5,
@@ -112909,7 +113651,7 @@ var {
112909
113651
  lstatSync: lstatSync5,
112910
113652
  mkdirSync: mkdirSync19,
112911
113653
  readFileSync: readFileSync44,
112912
- readdirSync: readdirSync14,
113654
+ readdirSync: readdirSync15,
112913
113655
  realpathSync: realpathSync13,
112914
113656
  statSync: statSync8,
112915
113657
  unlinkSync: unlinkSync10,
@@ -113022,7 +113764,7 @@ async function execFileText(command, args) {
113022
113764
  }
113023
113765
  async function readLinuxStartIdentity(pid) {
113024
113766
  try {
113025
- const stat = await readFile33(`/proc/${pid}/stat`, "utf8");
113767
+ const stat = await readFile34(`/proc/${pid}/stat`, "utf8");
113026
113768
  const commandEnd = stat.lastIndexOf(")");
113027
113769
  if (commandEnd < 0)
113028
113770
  return null;
@@ -113261,14 +114003,17 @@ async function isWorkerLockReleased(incarnation, record) {
113261
114003
  // packages/team-core/src/team-state-store/lock-record.ts
113262
114004
  async function buildLockRecord(ownerTag) {
113263
114005
  await registerLockWorker();
113264
- const processStart = await getProcessStartIdentity(process.pid);
114006
+ const processStart = await lockProcessStartLine(process.pid);
113265
114007
  return `${ownerTag} ${randomUUID6()}
113266
114008
  ${process.pid}
113267
114009
  ${Date.now()}
113268
114010
  ${lockOwnerInstanceId}
113269
- ${processStart ?? "unavailable"}
114011
+ ${processStart}
113270
114012
  `;
113271
114013
  }
114014
+ async function lockProcessStartLine(pid) {
114015
+ return await getProcessStartIdentity(pid) ?? "unavailable";
114016
+ }
113272
114017
  function errorCode2(error) {
113273
114018
  if (!(error instanceof Error) || !("code" in error))
113274
114019
  return null;
@@ -113297,8 +114042,8 @@ function parseLockOwner(content) {
113297
114042
  }
113298
114043
  async function readLockRecord(lockPath) {
113299
114044
  try {
113300
- const content = await readFile34(lockPath, "utf8");
113301
- const { mtimeMs } = await stat9(lockPath);
114045
+ const content = await readFile35(lockPath, "utf8");
114046
+ const { mtimeMs } = await stat11(lockPath);
113302
114047
  return { content, modifiedAtEpochMs: mtimeMs };
113303
114048
  } catch (error) {
113304
114049
  if (!(error instanceof Error))
@@ -113329,7 +114074,7 @@ async function isLockRecordStale(record, staleAfterMs) {
113329
114074
 
113330
114075
  // packages/team-core/src/team-state-store/lock-publish.ts
113331
114076
  async function pathMayExist(path, deps = {}) {
113332
- const accessPath = deps.access ?? access4;
114077
+ const accessPath = deps.access ?? access5;
113333
114078
  try {
113334
114079
  await accessPath(path);
113335
114080
  return true;
@@ -113346,7 +114091,7 @@ async function assertRetryableLockOpenError(lockPath, error, deps) {
113346
114091
  if (code === "EPERM") {
113347
114092
  if (await pathMayExist(lockPath, deps))
113348
114093
  return;
113349
- if ((deps?.platform ?? process.platform) === "win32" && await pathMayExist(dirname42(lockPath), deps))
114094
+ if ((deps?.platform ?? process.platform) === "win32" && await pathMayExist(dirname43(lockPath), deps))
113350
114095
  return;
113351
114096
  }
113352
114097
  throw error;
@@ -113366,7 +114111,7 @@ async function publishLockRecord(lockPath, record) {
113366
114111
  } catch (error) {
113367
114112
  markLockRecordReleased(record);
113368
114113
  await fileHandle.close();
113369
- await unlink3(lockPath).catch(() => {
114114
+ await unlink4(lockPath).catch(() => {
113370
114115
  return;
113371
114116
  });
113372
114117
  throw error;
@@ -113375,9 +114120,14 @@ async function publishLockRecord(lockPath, record) {
113375
114120
  return true;
113376
114121
  }
113377
114122
 
114123
+ // packages/team-core/src/team-state-store/lock-lease.ts
114124
+ import { randomUUID as randomUUID7 } from "node:crypto";
114125
+ import { open as open4, readdir as readdir18, readFile as readFile36, rename as rename9, rm as rm18 } from "node:fs/promises";
114126
+ import { basename as basename16, dirname as dirname44, join as join108 } from "node:path";
114127
+
113378
114128
  // packages/team-core/src/team-state-store/lock-reclaim.ts
113379
114129
  import { createHash as createHash10 } from "node:crypto";
113380
- import { unlink as unlink4 } from "node:fs/promises";
114130
+ import { unlink as unlink5 } from "node:fs/promises";
113381
114131
  var RECLAIM_UNLINK_ATTEMPTS = 3;
113382
114132
  var RECLAIM_UNLINK_RETRY_MS = 25;
113383
114133
  function delay2(ms) {
@@ -113390,7 +114140,7 @@ function reclaimGuardPath(lockPath, record) {
113390
114140
  }
113391
114141
  async function unlinkWithRetry(path, deps) {
113392
114142
  const wait = deps.delay ?? delay2;
113393
- const unlinkFile = deps.unlink ?? unlink4;
114143
+ const unlinkFile = deps.unlink ?? unlink5;
113394
114144
  for (let attempt = 1;; attempt += 1) {
113395
114145
  try {
113396
114146
  await unlinkFile(path);
@@ -113408,6 +114158,19 @@ async function unlinkWithRetry(path, deps) {
113408
114158
  }
113409
114159
  }
113410
114160
  async function removeLockRecordIfUnchanged(lockPath, expectedRecord, staleAfterMs, deps = {}) {
114161
+ return withRecordGuard(lockPath, expectedRecord, staleAfterMs, deps, async () => {
114162
+ const current = await readLockRecord(lockPath);
114163
+ if (current === null)
114164
+ return "absent";
114165
+ if (current.content !== expectedRecord || !await isLockRecordStale(current, staleAfterMs))
114166
+ return "changed";
114167
+ const unlinked = await unlinkWithRetry(lockPath, deps);
114168
+ if (unlinked !== "stuck")
114169
+ forgetLockRecord(expectedRecord);
114170
+ return unlinked === "absent" ? "absent" : unlinked;
114171
+ });
114172
+ }
114173
+ async function withRecordGuard(lockPath, expectedRecord, staleAfterMs, deps, act) {
113411
114174
  const guardPath = reclaimGuardPath(lockPath, expectedRecord);
113412
114175
  const guardRecord = await buildLockRecord("lock-reclaim");
113413
114176
  if (!await publishLockRecord(guardPath, guardRecord)) {
@@ -113418,15 +114181,7 @@ async function removeLockRecordIfUnchanged(lockPath, expectedRecord, staleAfterM
113418
114181
  return "busy";
113419
114182
  }
113420
114183
  try {
113421
- const current = await readLockRecord(lockPath);
113422
- if (current === null)
113423
- return "absent";
113424
- if (current.content !== expectedRecord || !await isLockRecordStale(current, staleAfterMs))
113425
- return "changed";
113426
- const unlinked = await unlinkWithRetry(lockPath, deps);
113427
- if (unlinked !== "stuck")
113428
- forgetLockRecord(expectedRecord);
113429
- return unlinked === "absent" ? "absent" : unlinked;
114184
+ return await act();
113430
114185
  } finally {
113431
114186
  markLockRecordReleased(guardRecord);
113432
114187
  if (await unlinkWithRetry(guardPath, deps) !== "stuck")
@@ -113434,6 +114189,97 @@ async function removeLockRecordIfUnchanged(lockPath, expectedRecord, staleAfterM
113434
114189
  }
113435
114190
  }
113436
114191
 
114192
+ // packages/team-core/src/team-state-store/lock-lease.ts
114193
+ class LockLeaseLostError extends Error {
114194
+ constructor(lockPath) {
114195
+ super(`The lock at ${lockPath} changed while it was handed over; the critical section was aborted.`);
114196
+ this.name = "LockLeaseLostError";
114197
+ }
114198
+ }
114199
+ var leaseTempPrefix = (lockPath) => `.${basename16(lockPath)}.`;
114200
+ var LEASE_TEMP_SUFFIX = ".lease";
114201
+ var UUID2 = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}";
114202
+ var escapeRegExp2 = (text) => text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
114203
+ var leaseTempPattern = (lockPath) => new RegExp(`^\\.${escapeRegExp2(basename16(lockPath))}\\.${UUID2}\\.lease$`);
114204
+ async function replaceRecord(lockPath, content) {
114205
+ const temporary = join108(dirname44(lockPath), `${leaseTempPrefix(lockPath)}${randomUUID7()}${LEASE_TEMP_SUFFIX}`);
114206
+ try {
114207
+ const handle = await open4(temporary, "wx", 384);
114208
+ try {
114209
+ await handle.writeFile(content);
114210
+ } finally {
114211
+ await handle.close();
114212
+ }
114213
+ await rename9(temporary, lockPath);
114214
+ } catch (error) {
114215
+ await rm18(temporary, { force: true });
114216
+ throw error;
114217
+ }
114218
+ }
114219
+ async function removeLeftoverTemps(lockPath) {
114220
+ const pattern = leaseTempPattern(lockPath);
114221
+ let entries;
114222
+ try {
114223
+ entries = await readdir18(dirname44(lockPath));
114224
+ } catch (error) {
114225
+ if (error instanceof Error && "code" in error && error.code === "ENOENT")
114226
+ return;
114227
+ throw error;
114228
+ }
114229
+ for (const entry of entries) {
114230
+ if (pattern.test(entry))
114231
+ await rm18(join108(dirname44(lockPath), entry), { force: true });
114232
+ }
114233
+ }
114234
+ async function currentRecord(lockPath) {
114235
+ try {
114236
+ return await readFile36(lockPath, "utf8");
114237
+ } catch (error) {
114238
+ if (error instanceof Error && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR"))
114239
+ return null;
114240
+ throw error;
114241
+ }
114242
+ }
114243
+ function createLockLease(lockPath, ownerRecord, ownerTag, options = {}) {
114244
+ const staleAfterMs = options.staleAfterMs ?? Number.POSITIVE_INFINITY;
114245
+ let handedTo = null;
114246
+ return {
114247
+ async handOver(pid) {
114248
+ if (handedTo !== null)
114249
+ throw new Error("The lock is already handed over; restore it first.");
114250
+ if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid)
114251
+ throw new Error(`Cannot hand the lock to pid ${pid}.`);
114252
+ if (await currentRecord(lockPath) !== ownerRecord)
114253
+ throw new LockLeaseLostError(lockPath);
114254
+ await removeLeftoverTemps(lockPath);
114255
+ const processStart = await lockProcessStartLine(pid);
114256
+ const record = `${ownerTag} ${randomUUID7()}
114257
+ ${pid}
114258
+ ${Date.now()}
114259
+ ${randomUUID7()}
114260
+ ${processStart}
114261
+ `;
114262
+ await replaceRecord(lockPath, record);
114263
+ handedTo = record;
114264
+ },
114265
+ async restore() {
114266
+ if (handedTo === null)
114267
+ throw new Error("The lock is not handed over.");
114268
+ const expected = handedTo;
114269
+ handedTo = null;
114270
+ const outcome = await withRecordGuard(lockPath, expected, staleAfterMs, {}, async () => {
114271
+ if (await currentRecord(lockPath) !== expected)
114272
+ return "lost";
114273
+ await options.beforeRestoreRename?.();
114274
+ await replaceRecord(lockPath, ownerRecord);
114275
+ return "restored";
114276
+ });
114277
+ if (outcome !== "restored")
114278
+ throw new LockLeaseLostError(lockPath);
114279
+ }
114280
+ };
114281
+ }
114282
+
113437
114283
  // packages/team-core/src/team-state-store/locks.ts
113438
114284
  var LOCK_RETRY_MS = 50;
113439
114285
  var LOCK_WAIT_TIMEOUT_MS = 15000;
@@ -113463,7 +114309,7 @@ async function withLock(lockPath, fn, opts) {
113463
114309
  const ownerTag = opts?.ownerTag ?? "owner";
113464
114310
  const record = await acquireLock(lockPath, ownerTag, staleAfterMs);
113465
114311
  try {
113466
- return await fn();
114312
+ return await fn(createLockLease(lockPath, record, ownerTag, { staleAfterMs }));
113467
114313
  } finally {
113468
114314
  markLockRecordReleased(record);
113469
114315
  const outcome = await removeLockRecordIfUnchanged(lockPath, record, staleAfterMs);
@@ -113480,20 +114326,382 @@ async function reapStaleLock(lockPath, staleAfterMs = DEFAULT_STALE_AFTER_MS, de
113480
114326
  return await removeLockRecordIfUnchanged(lockPath, observed.content, staleAfterMs, deps);
113481
114327
  }
113482
114328
 
114329
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/prompt-lock.ts
114330
+ function promptLockAt(path, hooks = {}) {
114331
+ return async () => {
114332
+ const held = keychainProcessState().heldPromptLocks;
114333
+ if (held.has(path))
114334
+ return null;
114335
+ held.add(path);
114336
+ let granted = false;
114337
+ try {
114338
+ await mkdir11(dirname45(path), { recursive: true, mode: 448 });
114339
+ await hooks.beforePublish?.();
114340
+ for (let attempt = 0;attempt < 2; attempt++) {
114341
+ const record = await buildLockRecord("keychain-prompt");
114342
+ if (await publishLockRecord(path, record)) {
114343
+ granted = true;
114344
+ return async () => {
114345
+ markLockRecordReleased(record);
114346
+ try {
114347
+ await (hooks.removeRecord ?? ((target, owned) => removeLockRecordIfUnchanged(target, owned, Number.POSITIVE_INFINITY)))(path, record);
114348
+ } finally {
114349
+ held.delete(path);
114350
+ }
114351
+ };
114352
+ }
114353
+ if (await reapStaleLock(path, Number.POSITIVE_INFINITY) !== "removed")
114354
+ return null;
114355
+ }
114356
+ return null;
114357
+ } finally {
114358
+ if (!granted)
114359
+ held.delete(path);
114360
+ }
114361
+ };
114362
+ }
114363
+
114364
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/darwin-backend.ts
114365
+ var ROW_9B_DEFAULT = "reinstall-notice";
114366
+ var helperAccess = () => sharedHelperAccess(() => {
114367
+ const { entryCandidates } = keychainProcessState();
114368
+ return resolveHelperAccess([...entryCandidates, ...bundleCandidates(import.meta.url), ...machineCandidates(homedir31())]);
114369
+ });
114370
+ function sharedHelperAccess(resolve) {
114371
+ const state = keychainProcessState();
114372
+ if (state.helperAccess !== undefined)
114373
+ return state.helperAccess;
114374
+ const started = resolve();
114375
+ state.helperAccess = started;
114376
+ started.then((access) => {
114377
+ if (access.kind === "unavailable" && state.helperAccess === started)
114378
+ state.helperAccess = undefined;
114379
+ }, () => {
114380
+ if (state.helperAccess === started)
114381
+ state.helperAccess = undefined;
114382
+ });
114383
+ return started;
114384
+ }
114385
+
114386
+ class HelperMissingForOwnedItem extends Error {
114387
+ }
114388
+ function asKeystoreError(error, pending) {
114389
+ if (!(error instanceof HelperReadError))
114390
+ return error;
114391
+ if (error.failure === "pending")
114392
+ return pending(error.message);
114393
+ if (error.failure === "locked")
114394
+ return Object.assign(new Error(error.message), { code: "-25308" });
114395
+ return error;
114396
+ }
114397
+ function createDarwinBackend(options) {
114398
+ const silently = options.silently ?? silentSecrets;
114399
+ const key = { service: options.service, name: options.account };
114400
+ const deps = {
114401
+ account: options.account,
114402
+ access: options.access,
114403
+ cache: options.cache ?? processApprovalCache(),
114404
+ background: options.background,
114405
+ takePromptLock: promptLockAt(join109(options.home ?? homedir31(), ".omo", "session-locks", `${options.account}.keychain-prompt`)),
114406
+ ownSilentGet: () => silently(() => options.secrets.get(key)),
114407
+ ownOverwrite: (value) => silently(() => options.secrets.set({ ...key, value })),
114408
+ ownDelete: (name) => name === options.account ? gatedSecrets(() => options.secrets.delete({ ...key, name })) : silently(() => options.secrets.delete({ ...key, name })),
114409
+ notice: options.notice,
114410
+ ...options.row8b === undefined ? {} : { row8b: options.row8b },
114411
+ ...options.handOff === undefined ? {} : { handOff: options.handOff },
114412
+ noDialog: options.noDialog === true
114413
+ };
114414
+ let unowned = false;
114415
+ return {
114416
+ read: async () => {
114417
+ const result = await readThroughHelper(deps, true);
114418
+ unowned = result.kind === "value" && result.source !== "owned";
114419
+ return result.kind === "value" ? result.value : null;
114420
+ },
114421
+ underLock: (lease) => lockedDarwinStore(deps, lease),
114422
+ migrationPending: () => unowned
114423
+ };
114424
+ }
114425
+ async function guardHelperlessRead(service, account, choice = ROW_9B_DEFAULT, probe = probeOwnerMarker) {
114426
+ if (choice === "dialog")
114427
+ return;
114428
+ if (await probe(service, account) === "helper-owned")
114429
+ throw new HelperMissingForOwnedItem("OmO's keychain helper is missing or damaged on this Mac. Reinstall omo, then try again.");
114430
+ }
114431
+
114432
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/store-binding.ts
114433
+ import { homedir as homedir32 } from "node:os";
114434
+
114435
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/creator-handoff.ts
114436
+ init_bun_file_shim();
114437
+ init_bun_spawn_shim();
114438
+ import { dirname as dirname47, posix as posix14 } from "node:path";
114439
+
114440
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/runtime-capabilities.ts
114441
+ init_zod();
114442
+ import { readFile as readFile37 } from "node:fs/promises";
114443
+ import { dirname as dirname46, join as join110 } from "node:path";
114444
+ var RUNTIME_CAPABILITIES_FILE = "omo-runtime-capabilities.json";
114445
+ var RUNTIME_CAPABILITIES = { keychainHandoff: 1 };
114446
+ var capabilitiesSchema = object({ keychainHandoff: number2().int() }).passthrough();
114447
+ async function runtimeDeclaresKeychainHandoff(runtime) {
114448
+ const text = await readFile37(join110(dirname46(runtime), RUNTIME_CAPABILITIES_FILE), "utf8").catch(() => null);
114449
+ if (text === null)
114450
+ return false;
114451
+ try {
114452
+ const parsed = capabilitiesSchema.safeParse(JSON.parse(text));
114453
+ return parsed.success && parsed.data.keychainHandoff >= RUNTIME_CAPABILITIES.keychainHandoff;
114454
+ } catch {
114455
+ return false;
114456
+ }
114457
+ }
114458
+
114459
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/creator-handoff.ts
114460
+ 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"';
114461
+ var DESKTOP_RUNTIME_REQUIREMENT = `identifier "com.mengmota.omo-desktop-runtime" and ${DEVELOPER_ID_TEAM}`;
114462
+ var DESKTOP_APP_REQUIREMENT = DEVELOPER_ID_TEAM;
114463
+ var HANDOFF_ENV = "OMO_KEYCHAIN_HANDOFF";
114464
+ var HANDOFF_DEADLINE_MS = 45000;
114465
+ function desktopRuntimeCandidates(home, arch = process.arch) {
114466
+ const runtimeArch = arch === "arm64" ? "arm64" : "x64";
114467
+ return ["/Applications/OmO.app", posix14.join(home, "Applications", "OmO.app")].map((app) => ({
114468
+ app,
114469
+ runtime: posix14.join(app, "Contents", "Resources", "omo-runtime", `darwin-${runtimeArch}`, "omo")
114470
+ }));
114471
+ }
114472
+ var verifyBundle = async (app, requirement) => {
114473
+ const child = spawn(["/usr/bin/codesign", "--verify", "--deep", "--strict", `-R=${requirement}`, app], {
114474
+ stdin: "ignore",
114475
+ stdout: "ignore",
114476
+ stderr: "ignore"
114477
+ });
114478
+ return await child.exited === 0;
114479
+ };
114480
+ var runBounded = async (path, args, env, deadlineMs) => {
114481
+ const child = spawn([path, ...args], { cwd: dirname47(path), stdin: "ignore", stdout: "ignore", stderr: "ignore", env });
114482
+ let killed = false;
114483
+ const timer = setTimeout(() => {
114484
+ killed = true;
114485
+ child.kill("SIGKILL");
114486
+ }, deadlineMs);
114487
+ try {
114488
+ const code = await child.exited;
114489
+ return killed ? null : code;
114490
+ } finally {
114491
+ clearTimeout(timer);
114492
+ }
114493
+ };
114494
+ function createCreatorHandOff(options) {
114495
+ return async () => {
114496
+ const env = options.env ?? process.env;
114497
+ if (env[HANDOFF_ENV] === "1")
114498
+ return false;
114499
+ const checkRuntime = options.checkRuntime ?? verifyWithSecurityFramework;
114500
+ const checkBundle = options.checkBundle ?? verifyBundle;
114501
+ const declaresHandOff = options.declaresHandOff ?? runtimeDeclaresKeychainHandoff;
114502
+ const self = options.selfPath ?? process.execPath;
114503
+ for (const { app, runtime } of options.candidates) {
114504
+ if (runtime === self || !await bunFile(runtime).exists())
114505
+ continue;
114506
+ const verified = await Promise.resolve().then(async () => await checkBundle(app, DESKTOP_APP_REQUIREMENT) && await checkRuntime(runtime, DESKTOP_RUNTIME_REQUIREMENT) && await declaresHandOff(runtime)).catch(() => false);
114507
+ if (!verified)
114508
+ continue;
114509
+ const childEnv = { [HANDOFF_ENV]: "1" };
114510
+ if (env.HOME !== undefined)
114511
+ childEnv.HOME = env.HOME;
114512
+ const origin = options.origin ?? env.OMO_SERVICE_API_URL;
114513
+ if (origin !== undefined)
114514
+ childEnv.OMO_SERVICE_API_URL = origin;
114515
+ try {
114516
+ return await (options.run ?? runBounded)(runtime, ["account", "token"], childEnv, HANDOFF_DEADLINE_MS) === 0;
114517
+ } catch {
114518
+ return false;
114519
+ }
114520
+ }
114521
+ return false;
114522
+ };
114523
+ }
114524
+
114525
+ // packages/omo-opencode/src/cli/service-auth/keychain-helper/store-binding.ts
114526
+ var readers = new Map;
114527
+ var INJECTED_SECRETS = Symbol.for("omo.test.injectedSecrets");
114528
+ var isInjectedSecrets = (api) => api[INJECTED_SECRETS] === true;
114529
+ var backends = new Map;
114530
+ function processHandOff(origin) {
114531
+ return () => {
114532
+ const state = keychainProcessState();
114533
+ state.handOff ??= createCreatorHandOff({ candidates: desktopRuntimeCandidates(homedir32()), origin })();
114534
+ return state.handOff;
114535
+ };
114536
+ }
114537
+ function bindKeychainHelper(input) {
114538
+ const { secrets: real, key, options } = input;
114539
+ const eligible = input.platform === "darwin" && input.namespace === "omo-cli" && (options !== undefined || typeof Bun !== "undefined" && real === Bun.secrets && !isInjectedSecrets(real));
114540
+ const secrets = !eligible ? real : {
114541
+ get: (entry) => gatedSecrets(() => real.get(entry)),
114542
+ set: (entry) => gatedSecrets(() => real.set(entry)),
114543
+ delete: (entry) => gatedSecrets(() => real.delete(entry))
114544
+ };
114545
+ const cacheKey = `${key.service}
114546
+ ${key.name}
114547
+ ${input.background ? "bounded" : "interactive"}`;
114548
+ let own;
114549
+ const backend = () => {
114550
+ if (!eligible)
114551
+ return Promise.resolve(null);
114552
+ const known = options === undefined ? backends.get(cacheKey) : own;
114553
+ if (known !== undefined)
114554
+ return known;
114555
+ const created = (options?.access ?? helperAccess)().then((access) => access.kind !== "ready" ? null : createDarwinBackend({
114556
+ access,
114557
+ secrets: real,
114558
+ service: key.service,
114559
+ account: key.name,
114560
+ background: input.background,
114561
+ noDialog: options?.noDialog ?? process.env[HANDOFF_ENV] === "1",
114562
+ notice: input.notice,
114563
+ ...options?.home === undefined ? {} : { home: options.home },
114564
+ ...options?.row8b === undefined ? {} : { row8b: options.row8b },
114565
+ ...options?.silently === undefined ? {} : { silently: options.silently },
114566
+ ...options?.cache === undefined ? {} : { cache: options.cache },
114567
+ handOff: options === undefined ? processHandOff(input.origin) : options.handOff ?? (async () => false)
114568
+ }));
114569
+ if (options === undefined) {
114570
+ backends.set(cacheKey, created);
114571
+ created.then((found) => {
114572
+ if (found === null && backends.get(cacheKey) === created)
114573
+ backends.delete(cacheKey);
114574
+ });
114575
+ } else
114576
+ own = created;
114577
+ return created;
114578
+ };
114579
+ const reader = (helper) => {
114580
+ const known = readers.get(helper);
114581
+ if (known !== undefined)
114582
+ return known;
114583
+ const refuse = async () => {
114584
+ throw new Error("OmO's keychain helper changes the sign-in only under the session lock.");
114585
+ };
114586
+ const created = {
114587
+ get: async () => {
114588
+ try {
114589
+ return await helper.read();
114590
+ } catch (error) {
114591
+ throw asKeystoreError(error, (message) => input.pending(`${message} Credentials are never saved to a file.`));
114592
+ }
114593
+ },
114594
+ set: refuse,
114595
+ delete: refuse
114596
+ };
114597
+ readers.set(helper, created);
114598
+ return created;
114599
+ };
114600
+ return {
114601
+ secrets,
114602
+ eligible,
114603
+ backend,
114604
+ reader,
114605
+ isHelperReader: (api) => [...readers.values()].includes(api),
114606
+ guardHelperless: async () => {
114607
+ if (!eligible)
114608
+ return;
114609
+ if ((options?.noDialog ?? process.env[HANDOFF_ENV] === "1") === true)
114610
+ throw input.pending("The keychain hand-off cannot show a dialog.");
114611
+ await guardHelperlessRead(key.service, key.name, options?.row9b, options?.ownerMarker);
114612
+ }
114613
+ };
114614
+ }
114615
+ function lockedStoreView(helper, lease, codec, mapError, done) {
114616
+ const locked = helper.underLock(lease);
114617
+ const run = async (step) => {
114618
+ try {
114619
+ return await step();
114620
+ } catch (error) {
114621
+ throw mapError(error);
114622
+ } finally {
114623
+ done();
114624
+ }
114625
+ };
114626
+ return {
114627
+ read: () => run(async () => {
114628
+ const text = await locked.read();
114629
+ return text === null ? null : codec.parse(text);
114630
+ }),
114631
+ write: (value, intent = "update", beforeRetire) => run(async () => {
114632
+ const next = codec.amend === undefined ? value : codec.amend(await locked.read(), value);
114633
+ await locked.write(codec.serialize(next), intent, beforeRetire);
114634
+ }),
114635
+ clear: () => run(() => locked.clear()),
114636
+ recover: () => run(() => locked.recover()),
114637
+ settle: () => run(() => locked.settle())
114638
+ };
114639
+ }
114640
+
114641
+ // packages/omo-opencode/src/cli/service-auth/secret-service-lock.ts
114642
+ import { spawn as spawn5 } from "node:child_process";
114643
+ var DEFAULT_COLLECTION = "/org/freedesktop/secrets/aliases/default";
114644
+ var PROBE_TIMEOUT_MS2 = 1e4;
114645
+ var parseLockedReply = (stdout) => {
114646
+ const match = /<\s*(true|false)\s*>/.exec(stdout);
114647
+ if (match === null)
114648
+ return null;
114649
+ return match[1] === "true" ? "locked" : "unlocked";
114650
+ };
114651
+ var probeSecretServiceLock = () => new Promise((resolve) => {
114652
+ const child = spawn5("gdbus", [
114653
+ "call",
114654
+ "--session",
114655
+ "--dest",
114656
+ "org.freedesktop.secrets",
114657
+ "--object-path",
114658
+ DEFAULT_COLLECTION,
114659
+ "--method",
114660
+ "org.freedesktop.DBus.Properties.Get",
114661
+ "org.freedesktop.Secret.Collection",
114662
+ "Locked"
114663
+ ], { stdio: ["ignore", "pipe", "ignore"] });
114664
+ let stdout = "";
114665
+ const timer = setTimeout(() => {
114666
+ child.kill();
114667
+ resolve("unknown");
114668
+ }, PROBE_TIMEOUT_MS2);
114669
+ child.stdout.on("data", (chunk) => {
114670
+ stdout += chunk.toString();
114671
+ });
114672
+ child.on("error", () => {
114673
+ clearTimeout(timer);
114674
+ resolve("unknown");
114675
+ });
114676
+ child.on("close", (code) => {
114677
+ clearTimeout(timer);
114678
+ resolve(code === 0 ? parseLockedReply(stdout) ?? "absent" : "absent");
114679
+ });
114680
+ });
114681
+
113483
114682
  // packages/omo-opencode/src/cli/service-auth/credential-lock.ts
114683
+ import { AsyncLocalStorage as AsyncLocalStorage3 } from "node:async_hooks";
114684
+ import { createHash as createHash11 } from "node:crypto";
114685
+ import { mkdir as mkdir12 } from "node:fs/promises";
114686
+ import { homedir as homedir33 } from "node:os";
114687
+ import { join as join112 } from "node:path";
113484
114688
  var held = new AsyncLocalStorage3;
113485
- function credentialLockPaths(api, home = homedir31()) {
114689
+ function credentialLockPaths(api, home = homedir33()) {
113486
114690
  const id = createHash11("sha256").update(serviceOrigin(api)).digest("hex");
113487
- const directory = join106(home, ".omo", "session-locks");
113488
- return { directory, lock: join106(directory, `${id}.lock`), desktopRecord: join106(directory, `${id}.desktop-generation.json`) };
114691
+ const directory = join112(home, ".omo", "session-locks");
114692
+ return { directory, lock: join112(directory, `${id}.lock`), desktopRecord: join112(directory, `${id}.desktop-generation.json`) };
114693
+ }
114694
+ function heldCredentialLease(api, home = homedir33()) {
114695
+ return held.getStore()?.get(credentialLockPaths(api, home).lock);
113489
114696
  }
113490
- async function withCredentialLock(api, action, home = homedir31(), ownerTag = "cli-session") {
114697
+ async function withCredentialLock(api, action, home = homedir33(), ownerTag = "cli-session") {
113491
114698
  const { directory, lock } = credentialLockPaths(api, home);
113492
114699
  const owned = held.getStore();
113493
- if (owned?.has(lock))
113494
- return action();
113495
- await mkdir11(directory, { recursive: true, mode: 448 });
113496
- return withLock(lock, () => held.run(new Set([...owned ?? [], lock]), action), {
114700
+ const outer = owned?.get(lock);
114701
+ if (outer !== undefined)
114702
+ return action(outer);
114703
+ await mkdir12(directory, { recursive: true, mode: 448 });
114704
+ return withLock(lock, (lease) => held.run(new Map([...owned ?? [], [lock, lease]]), () => action(lease)), {
113497
114705
  ownerTag,
113498
114706
  staleAfterMs: Number.POSITIVE_INFINITY
113499
114707
  });
@@ -113545,17 +114753,51 @@ function createCredentialStore(api, options = {}) {
113545
114753
  return {
113546
114754
  ...value,
113547
114755
  ...accountId === undefined ? {} : { accountId },
113548
- credentialGeneration: sameIdentity ? current?.credentialGeneration ?? randomUUID7() : randomUUID7()
114756
+ credentialGeneration: sameIdentity ? current?.credentialGeneration ?? randomUUID8() : randomUUID8()
113549
114757
  };
113550
- });
114758
+ }, options.keychainHelper);
114759
+ const sections = new WeakMap;
114760
+ const underLock = (lease) => {
114761
+ const known = sections.get(lease);
114762
+ if (known !== undefined)
114763
+ return known;
114764
+ const view = (async () => {
114765
+ const opened = await store.underLock?.(lease) ?? null;
114766
+ await opened?.recover();
114767
+ return opened;
114768
+ })();
114769
+ sections.set(lease, view);
114770
+ return view;
114771
+ };
114772
+ const held = async () => {
114773
+ const lease = heldCredentialLease(api, options.home);
114774
+ return lease === undefined ? null : underLock(lease);
114775
+ };
114776
+ const locked = async (helper, plain) => {
114777
+ if (heldCredentialLease(api, options.home) === undefined)
114778
+ await store.prepare?.();
114779
+ await withCredentialLock(api, async (lease) => {
114780
+ const view = await underLock(lease);
114781
+ await (view === null ? plain() : helper(view));
114782
+ }, options.home);
114783
+ };
113551
114784
  return {
113552
- read: store.read,
113553
- readAuthoritative: store.readAuthoritative,
113554
- write: (value) => withCredentialLock(api, () => store.write(value), options.home),
113555
- clear: () => withCredentialLock(api, store.clear, options.home)
114785
+ read: async () => {
114786
+ const view = await held();
114787
+ return view === null ? store.read() : view.read();
114788
+ },
114789
+ readAuthoritative: async () => {
114790
+ const view = await held();
114791
+ return view === null ? store.readAuthoritative() : view.read();
114792
+ },
114793
+ write: (value, intent, beforeRetire) => locked((view) => view.write(value, intent, beforeRetire), () => store.write(value)),
114794
+ clear: () => locked((view) => view.clear(), store.clear),
114795
+ ...store.prepare === undefined ? {} : { prepare: store.prepare },
114796
+ underLock,
114797
+ ...store.migrationPending === undefined ? {} : { migrationPending: store.migrationPending }
113556
114798
  };
113557
114799
  }
113558
- function createSealedStore(api, namespace, schema, secrets = typeof Bun === "undefined" ? null : Bun.secrets, platform = process.platform, lockProbe = probeSecretServiceLock, notice = stderrNoticeOncePerProcess, wait = SESSION_READ_WAIT, amendWrite) {
114800
+ 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) {
113559
114801
  if (!secrets)
113560
114802
  throw new SignInError("OmO sign-in needs Bun 1.4 or newer with OS credential storage. No file fallback is available.");
113561
114803
  const platformName = platform === "darwin" ? "macOS Keychain" : platform === "linux" ? "Linux Secret Service (libsecret and an unlocked keyring)" : platform === "win32" ? "Windows Credential Manager" : null;
@@ -113564,6 +114806,18 @@ function createSealedStore(api, namespace, schema, secrets = typeof Bun === "und
113564
114806
  const key = { service: namespace, name: credentialId(api) };
113565
114807
  const slot = `${key.service}
113566
114808
  ${key.name}`;
114809
+ const helper = bindKeychainHelper({
114810
+ platform,
114811
+ namespace,
114812
+ secrets,
114813
+ key,
114814
+ background: wait.kind === "bounded",
114815
+ origin: api,
114816
+ notice,
114817
+ pending: (message) => new KeychainApprovalPendingError(message),
114818
+ ...keychainHelper === undefined ? {} : { options: keychainHelper }
114819
+ });
114820
+ secrets = helper.secrets;
113567
114821
  const readsOf = (api) => {
113568
114822
  const known = processReads.get(api);
113569
114823
  if (known !== undefined)
@@ -113589,17 +114843,19 @@ ${key.name}`;
113589
114843
  reads.set(slot, read);
113590
114844
  return read;
113591
114845
  };
113592
- 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`;
114846
+ 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`;
114847
+ const helperWaiting = `macOS Keychain is waiting for your approval: answer the "OmO's keychain helper wants to access key ${namespace}" dialog`;
113593
114848
  const answered = async (api, fresh = false) => {
114849
+ const waitingFor = helper.isHelperReader(api) ? helperWaiting : waiting;
113594
114850
  const read = fresh ? Promise.resolve().then(() => api.get(key)) : sharedRead(api);
113595
114851
  let timer;
113596
114852
  try {
113597
114853
  if (wait.kind === "interactive") {
113598
- timer = setTimeout(() => wait.notice(`omo: ${waiting}.`), wait.noticeAfterMs);
114854
+ timer = setTimeout(() => wait.notice(`omo: ${waitingFor}.`), wait.noticeAfterMs);
113599
114855
  return await read;
113600
114856
  }
113601
114857
  const expired = new Promise((_, reject) => {
113602
- timer = setTimeout(() => reject(new KeychainApprovalPendingError(`${waiting}, then try again. Credentials are never saved to a file.`)), wait.deadlineMs);
114858
+ timer = setTimeout(() => reject(new KeychainApprovalPendingError(`${waitingFor}, then try again. Credentials are never saved to a file.`)), wait.deadlineMs);
113603
114859
  });
113604
114860
  return await Promise.race([read, expired]);
113605
114861
  } finally {
@@ -113624,41 +114880,76 @@ ${key.name}`;
113624
114880
  notice("omo: could not check whether the keyring is locked (gdbus or the Secret Service did not answer); using libsecret directly.");
113625
114881
  }
113626
114882
  };
113627
- const parsedRead = async (fresh) => {
114883
+ const parseStored = (value) => {
114884
+ try {
114885
+ return schema.parse(JSON.parse(value));
114886
+ } catch {
114887
+ 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.");
114888
+ }
114889
+ };
114890
+ const previousOf = (raw) => {
114891
+ if (raw === null)
114892
+ return null;
114893
+ try {
114894
+ return schema.parse(JSON.parse(raw));
114895
+ } catch {
114896
+ return null;
114897
+ }
114898
+ };
114899
+ const rawRead = async (fresh) => {
113628
114900
  await assertUsable();
113629
- let value;
114901
+ const backend = await helper.backend();
113630
114902
  try {
113631
- value = await answered(secrets, fresh);
114903
+ if (backend === null)
114904
+ await helper.guardHelperless();
114905
+ return await answered(backend === null ? secrets : helper.reader(backend), fresh);
113632
114906
  } catch (error) {
113633
114907
  if (error instanceof KeychainApprovalPendingError)
113634
114908
  throw error;
114909
+ if (error instanceof HelperMissingForOwnedItem)
114910
+ throw new CredentialStoreError(error.message);
113635
114911
  throw unavailable(error);
113636
114912
  }
113637
- if (value === null)
113638
- return null;
113639
- try {
113640
- return schema.parse(JSON.parse(value));
113641
- } catch {
113642
- 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.");
113643
- }
114913
+ };
114914
+ const parsedRead = async (fresh) => {
114915
+ const value = await rawRead(fresh);
114916
+ return value === null ? null : parseStored(value);
114917
+ };
114918
+ const lockedFailure = (error) => {
114919
+ const mapped = asKeystoreError(error, (message) => new KeychainApprovalPendingError(message));
114920
+ if (error instanceof HelperOldSlotsFull)
114921
+ return new CredentialStoreError(error.message);
114922
+ if (mapped instanceof KeychainApprovalPendingError || mapped instanceof SignInError)
114923
+ return mapped;
114924
+ if (mapped instanceof Error && mapped.name === "LockLeaseLostError")
114925
+ return mapped;
114926
+ return unavailable(mapped);
113644
114927
  };
113645
114928
  return {
113646
114929
  read: () => parsedRead(false),
113647
114930
  readAuthoritative: () => parsedRead(true),
114931
+ async prepare() {
114932
+ if (await helper.backend() !== null)
114933
+ await rawRead(false);
114934
+ },
114935
+ async underLock(lease) {
114936
+ const backend = await helper.backend();
114937
+ if (backend === null)
114938
+ return null;
114939
+ const codec = {
114940
+ parse: parseStored,
114941
+ serialize: (value) => JSON.stringify(schema.parse(value)),
114942
+ ...amendWrite === undefined ? {} : { amend: (raw, next) => amendWrite(previousOf(raw), next) }
114943
+ };
114944
+ return lockedStoreView(backend, lease, codec, lockedFailure, () => forget(helper.reader(backend)));
114945
+ },
114946
+ migrationPending: async () => (await helper.backend())?.migrationPending() ?? false,
113648
114947
  async write(value) {
113649
114948
  await assertUsable();
114949
+ if (await helper.backend() !== null)
114950
+ throw new Error("OmO's keychain helper writes only under the session lock.");
113650
114951
  try {
113651
- let next = value;
113652
- if (amendWrite !== undefined) {
113653
- const raw = await answered(secrets, true);
113654
- let previous = null;
113655
- if (raw !== null) {
113656
- try {
113657
- previous = schema.parse(JSON.parse(raw));
113658
- } catch {}
113659
- }
113660
- next = amendWrite(previous, value);
113661
- }
114952
+ const next = amendWrite === undefined ? value : amendWrite(previousOf(await answered(secrets, true)), value);
113662
114953
  await secrets.set({ ...key, value: JSON.stringify(schema.parse(next)) });
113663
114954
  } catch (error) {
113664
114955
  throw unavailable(error);
@@ -113667,6 +114958,8 @@ ${key.name}`;
113667
114958
  },
113668
114959
  async clear() {
113669
114960
  await assertUsable();
114961
+ if (await helper.backend() !== null)
114962
+ throw new Error("OmO's keychain helper deletes only under the session lock.");
113670
114963
  try {
113671
114964
  await secrets.delete(key);
113672
114965
  } catch (error) {
@@ -113778,14 +115071,14 @@ async function loginLoopback(session, options) {
113778
115071
 
113779
115072
  // packages/memory-core/src/sync/device-retire.ts
113780
115073
  import { createHash as createHash14, randomBytes as randomBytes6 } from "node:crypto";
113781
- import { join as join109 } from "node:path";
115074
+ import { join as join115 } from "node:path";
113782
115075
 
113783
115076
  // packages/memory-core/src/identity/layout.ts
113784
- import { homedir as homedir32 } from "node:os";
113785
- import { join as join107, resolve as resolve31 } from "node:path";
115077
+ import { homedir as homedir34 } from "node:os";
115078
+ import { join as join113, resolve as resolve31 } from "node:path";
113786
115079
  var MEMORY_ROOT_ENV_VAR = "OMO_MEMORY_HOME";
113787
115080
  function defaultMemoryRoot() {
113788
- return join107(homedir32(), ".omo", "memory");
115081
+ return join113(homedir34(), ".omo", "memory");
113789
115082
  }
113790
115083
  function resolveMemoryRoot(env, cwd) {
113791
115084
  const override = env[MEMORY_ROOT_ENV_VAR];
@@ -113795,13 +115088,13 @@ function resolveMemoryRoot(env, cwd) {
113795
115088
  return resolve31(cwd, override);
113796
115089
  }
113797
115090
  // packages/memory-core/src/sync/pin-dir.ts
113798
- import { join as join108 } from "node:path";
113799
- var syncPinDir = (memoryRoot) => join108(memoryRoot, "sync-device");
115091
+ import { join as join114 } from "node:path";
115092
+ var syncPinDir = (memoryRoot) => join114(memoryRoot, "sync-device");
113800
115093
 
113801
115094
  // packages/memory-core/src/sync/device-retire.ts
113802
- var trustAnchorRoot = (pinDir) => join109(pinDir, "trust-anchor");
115095
+ var trustAnchorRoot = (pinDir) => join115(pinDir, "trust-anchor");
113803
115096
  var trustAnchorKey = (account) => createHash14("sha256").update(account, "utf8").digest("base64url");
113804
- var trustAnchorDir = (pinDir, account) => join109(trustAnchorRoot(pinDir), trustAnchorKey(account));
115097
+ var trustAnchorDir = (pinDir, account) => join115(trustAnchorRoot(pinDir), trustAnchorKey(account));
113805
115098
  var hasLiveTrustAnchor = async (pinDir) => {
113806
115099
  try {
113807
115100
  return (await readdir17(trustAnchorRoot(pinDir))).some((name) => !name.includes(".retired-"));
@@ -113822,16 +115115,16 @@ var retireSyncDevice = async (input) => {
113822
115115
  };
113823
115116
 
113824
115117
  // packages/omo-opencode/src/cli/service-auth/session.ts
113825
- import { homedir as homedir33 } from "node:os";
115118
+ import { homedir as homedir35 } from "node:os";
113826
115119
 
113827
115120
  // packages/omo-opencode/src/cli/service-auth/signed-out-marker.ts
113828
115121
  init_zod();
113829
- import { mkdir as mkdir12, readFile as readFile35, rename as rename9, rm as rm17, writeFile as writeFile17 } from "node:fs/promises";
113830
- import { dirname as dirname43, join as join110 } from "node:path";
115122
+ import { mkdir as mkdir13, readFile as readFile38, rename as rename10, rm as rm19, writeFile as writeFile18 } from "node:fs/promises";
115123
+ import { dirname as dirname48, join as join116 } from "node:path";
113831
115124
  var markerSchema = object({ device: string2().nullable(), at: string2() });
113832
- var signedOutMarkerPath = (home, credential) => join110(home, ".omo", "account-state", `${credential}.signed-out.json`);
115125
+ var signedOutMarkerPath = (home, credential) => join116(home, ".omo", "account-state", `${credential}.signed-out.json`);
113833
115126
  async function readSignedOutMarker(path) {
113834
- const text = await readFile35(path, "utf8").catch(() => null);
115127
+ const text = await readFile38(path, "utf8").catch(() => null);
113835
115128
  if (text === null)
113836
115129
  return null;
113837
115130
  let value;
@@ -113844,12 +115137,12 @@ async function readSignedOutMarker(path) {
113844
115137
  return parsed.success ? parsed.data : null;
113845
115138
  }
113846
115139
  async function writeSignedOutMarker(path, device) {
113847
- await mkdir12(dirname43(path), { recursive: true, mode: 448 });
115140
+ await mkdir13(dirname48(path), { recursive: true, mode: 448 });
113848
115141
  const staging = `${path}.${process.pid}.tmp`;
113849
- await writeFile17(staging, JSON.stringify({ device, at: new Date().toISOString() }), { mode: 384 });
113850
- await rename9(staging, path);
115142
+ await writeFile18(staging, JSON.stringify({ device, at: new Date().toISOString() }), { mode: 384 });
115143
+ await rename10(staging, path);
113851
115144
  }
113852
- var clearSignedOutMarker = (path) => rm17(path, { force: true });
115145
+ var clearSignedOutMarker = (path) => rm19(path, { force: true });
113853
115146
 
113854
115147
  // packages/omo-opencode/src/cli/service-auth/session.ts
113855
115148
  class SessionEnded extends SignInError {
@@ -113873,12 +115166,14 @@ function createSession(options) {
113873
115166
  const api = serviceOrigin(options.api);
113874
115167
  const now = options.now ?? Date.now;
113875
115168
  const { store, signal, beforeKeysDiscarded } = options;
113876
- const markerPath = signedOutMarkerPath(options.home ?? homedir33(), credentialId(api));
115169
+ const markerPath = signedOutMarkerPath(options.home ?? homedir35(), credentialId(api));
113877
115170
  async function locked(action) {
113878
115171
  signal?.throwIfAborted();
113879
- return withCredentialLock(api, async () => {
115172
+ if (heldCredentialLease(api, options.home) === undefined)
115173
+ await store.prepare?.();
115174
+ return withCredentialLock(api, async (lease) => {
113880
115175
  signal?.throwIfAborted();
113881
- return action();
115176
+ return action(await store.underLock?.(lease) ?? null);
113882
115177
  }, options.home);
113883
115178
  }
113884
115179
  const request = (path, init) => requestApi(api, path, init, signal);
@@ -113915,9 +115210,12 @@ function createSession(options) {
113915
115210
  }
113916
115211
  }
113917
115212
  async function snapshot() {
113918
- return locked(async () => {
115213
+ return locked(async (view) => {
113919
115214
  const current = await store.read();
113920
- return current === null ? null : refreshed(current);
115215
+ if (current === null)
115216
+ return null;
115217
+ await view?.settle();
115218
+ return refreshed(current);
113921
115219
  });
113922
115220
  }
113923
115221
  return {
@@ -113940,7 +115238,7 @@ function createSession(options) {
113940
115238
  }
113941
115239
  if (stored !== null && stored.device.id !== value.device.id)
113942
115240
  await beforeKeysDiscarded(discardedOf(stored, "replaced"));
113943
- await store.write(value);
115241
+ await store.write(value, "fresh-sign-in", () => beforeKeysDiscarded({ kind: "unreadable" }));
113944
115242
  await clearSignedOutMarker(markerPath);
113945
115243
  });
113946
115244
  },
@@ -114001,14 +115299,15 @@ function createSession(options) {
114001
115299
  signal?.throwIfAborted();
114002
115300
  const snapshot = await store.read();
114003
115301
  signal?.throwIfAborted();
114004
- if (snapshot !== null && snapshot.refreshState !== "uncertain" && snapshot.refreshAttempt === undefined && Date.parse(snapshot.accessTokenExpiresAt) > now() + 30000 && (expect === undefined || expect(snapshot)))
115302
+ if (snapshot !== null && snapshot.refreshState !== "uncertain" && snapshot.refreshAttempt === undefined && Date.parse(snapshot.accessTokenExpiresAt) > now() + 30000 && (expect === undefined || expect(snapshot)) && !await store.migrationPending?.())
114005
115303
  return snapshot.accessToken;
114006
- return locked(async () => {
115304
+ return locked(async (view) => {
114007
115305
  const current = await store.readAuthoritative();
114008
115306
  if (current === null)
114009
115307
  throw new SignInError(`Not signed in. ${signInHint("first")}`);
114010
115308
  if (expect !== undefined && !expect(current))
114011
115309
  throw new CredentialIdentityChanged;
115310
+ await view?.settle();
114012
115311
  return (await refreshed(current)).accessToken;
114013
115312
  });
114014
115313
  },
@@ -114156,6 +115455,10 @@ function refuseClosedServiceAuth() {
114156
115455
  }
114157
115456
  function configureClosedServiceAuthCommands(program) {
114158
115457
  for (const name of SERVICE_AUTH_COMMANDS) {
115458
+ if (name === "login") {
115459
+ configureClosedDeviceLogin(program);
115460
+ continue;
115461
+ }
114159
115462
  const command = program.command(name, { hidden: true }).helpOption(false).allowUnknownOption().allowExcessArguments().action(() => {
114160
115463
  console.error(SERVICE_ACCOUNTS_CLOSED_MESSAGE);
114161
115464
  process.exitCode = 1;
@@ -114163,6 +115466,17 @@ function configureClosedServiceAuthCommands(program) {
114163
115466
  command.help = refuseClosedServiceAuth;
114164
115467
  }
114165
115468
  }
115469
+ function configureClosedDeviceLogin(program) {
115470
+ const command = program.command("login", { hidden: true }).helpOption(false).allowUnknownOption().allowExcessArguments().option("--device").option("--no-browser").option("--api <url>").action((options) => {
115471
+ if (options.device !== true && options.browser !== false || command.args.length > 0) {
115472
+ console.error(SERVICE_ACCOUNTS_CLOSED_MESSAGE);
115473
+ process.exitCode = 1;
115474
+ return;
115475
+ }
115476
+ return run2("login", { ...options, device: true });
115477
+ });
115478
+ command.help = refuseClosedServiceAuth;
115479
+ }
114166
115480
  function configureServiceAuthCommands(program, open = serviceAccountsOpen()) {
114167
115481
  if (!open) {
114168
115482
  configureClosedServiceAuthCommands(program);
@@ -114364,11 +115678,11 @@ async function boulder(options) {
114364
115678
  // packages/omo-opencode/src/cli/codex-ulw-loop.ts
114365
115679
  import { spawn as spawn6 } from "node:child_process";
114366
115680
  import { existsSync as existsSync67, readFileSync as readFileSync45, realpathSync as realpathSync14 } from "node:fs";
114367
- import { homedir as homedir34 } from "node:os";
115681
+ import { homedir as homedir36 } from "node:os";
114368
115682
  var ULW_LOOP_DELEGATION_SENTINEL = "OMO_ULW_LOOP_DELEGATED";
114369
115683
  function resolveCodexUlwLoopCommand(input = {}) {
114370
115684
  const env = input.env ?? process.env;
114371
- const homeDir = input.homeDir ?? homedir34();
115685
+ const homeDir = input.homeDir ?? homedir36();
114372
115686
  const localComponentBin = resolveLocalUlwLoopBin(env, homeDir);
114373
115687
  if (localComponentBin !== null)
114374
115688
  return { executable: localComponentBin, argsPrefix: [] };
@@ -114611,7 +115925,7 @@ function linkedWorktrees(records) {
114611
115925
  }
114612
115926
  // packages/omo-opencode/src/cli/worktree-sweep/sweep.ts
114613
115927
  import { existsSync as existsSync68 } from "node:fs";
114614
- import { stat as stat10 } from "node:fs/promises";
115928
+ import { stat as stat12 } from "node:fs/promises";
114615
115929
  import os7 from "node:os";
114616
115930
  import { normalize as normalize2 } from "node:path";
114617
115931
 
@@ -114694,7 +116008,7 @@ async function isOlderThan(worktreePath, days, now) {
114694
116008
  if (days <= 0)
114695
116009
  return false;
114696
116010
  try {
114697
- const stats = await stat10(worktreePath);
116011
+ const stats = await stat12(worktreePath);
114698
116012
  return now - stats.mtimeMs > days * DAY_MS;
114699
116013
  } catch {
114700
116014
  return false;
@@ -114859,7 +116173,7 @@ prunes.
114859
116173
 
114860
116174
  // packages/omo-opencode/src/cli/config-migrate.ts
114861
116175
  init_startup_migration();
114862
- import { posix as posix13 } from "node:path";
116176
+ import { posix as posix15 } from "node:path";
114863
116177
  function reports(result) {
114864
116178
  return result.results.map((entry) => ({
114865
116179
  diagnostics: entry.diagnostics,
@@ -114893,7 +116207,7 @@ function runConfigMigrate(options = {}) {
114893
116207
  dryRun: options.dryRun ?? false,
114894
116208
  environment,
114895
116209
  ...homeDir === undefined ? {} : { env: { HOME: homeDir }, homeDir },
114896
- pathOperations: posix13
116210
+ pathOperations: posix15
114897
116211
  });
114898
116212
  const report = reports(result);
114899
116213
  const response = {