oh-my-opencode 5.1.51 → 5.1.55

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 (916) hide show
  1. package/dist/agents/atlas/agent.d.ts +5 -5
  2. package/dist/agents/dynamic-agent-core-sections.d.ts +0 -1
  3. package/dist/agents/dynamic-agent-prompt-builder.d.ts +1 -1
  4. package/dist/agents/gpt-apply-patch-guard.d.ts +0 -1
  5. package/dist/agents/hephaestus/agent.d.ts +3 -7
  6. package/dist/agents/hephaestus/model-support.d.ts +6 -0
  7. package/dist/agents/metis.d.ts +0 -15
  8. package/dist/agents/native-model-prompt.d.ts +9 -0
  9. package/dist/agents/native-prompt-frame.d.ts +20 -0
  10. package/dist/agents/native-tool-snippet.d.ts +6 -0
  11. package/dist/agents/sisyphus/default.d.ts +0 -1
  12. package/dist/agents/sisyphus-agent-factory.d.ts +2 -11
  13. package/dist/agents/sisyphus-junior/agent.d.ts +2 -20
  14. package/dist/agents/sisyphus-junior/index.d.ts +1 -11
  15. package/dist/agents/sisyphus-runtime-prompt-reconciler.d.ts +6 -0
  16. package/dist/agents/types.d.ts +2 -2
  17. package/dist/cli/index.js +1174 -394
  18. package/dist/cli/service-auth/credential-lock.d.ts +11 -0
  19. package/dist/cli/service-auth/credential-owner.d.ts +10 -0
  20. package/dist/cli/service-auth/index.d.ts +3 -1
  21. package/dist/cli/service-auth/keystore.d.ts +8 -1
  22. package/dist/cli/service-auth/owned-refresh.d.ts +21 -0
  23. package/dist/cli/service-auth/protocol-v2.d.ts +27 -0
  24. package/dist/cli/service-auth/protocol.d.ts +26 -2
  25. package/dist/cli/service-auth/recovery-clock.d.ts +7 -0
  26. package/dist/cli/service-auth/refresh-attempt.d.ts +34 -0
  27. package/dist/cli/service-auth/session.d.ts +9 -2
  28. package/dist/cli-node/index.js +1174 -394
  29. package/dist/config/schema/agent-overrides.d.ts +64 -0
  30. package/dist/config/schema/categories.d.ts +8 -0
  31. package/dist/config/schema/oh-my-opencode-config.d.ts +64 -0
  32. package/dist/hooks/native-edition-nudge/hook.d.ts +3 -4
  33. package/dist/index.js +15625 -8841
  34. package/dist/oh-my-opencode.schema.json +112 -0
  35. package/dist/plugin/session-tool-permissions.d.ts +10 -0
  36. package/dist/plugin/system-transform.d.ts +2 -1
  37. package/dist/plugin/tool-definition.d.ts +1 -0
  38. package/dist/shared/bun-ffi-shim.d.ts +29 -0
  39. package/dist/shared/json-file-cache-store.d.ts +11 -0
  40. package/dist/skills/browser/runtime/omowright/index.js +24 -33
  41. package/dist/skills/browser/runtime/omowright/manifest.json +3 -3
  42. package/dist/skills/frontend/ATTRIBUTION.md +104 -1
  43. package/dist/skills/frontend/SKILL.md +7 -3
  44. package/dist/skills/frontend/references/design/design-system-architecture.md +3 -3
  45. package/dist/skills/frontend/references/perfection/craft-floor.md +59 -0
  46. package/dist/skills/frontend/references/perfection/detect.md +52 -0
  47. package/dist/skills/frontend/scripts/detect/cli.ts +70 -0
  48. package/dist/skills/frontend/scripts/detect/config.test.ts +26 -0
  49. package/dist/skills/frontend/scripts/detect/config.ts +53 -0
  50. package/dist/skills/frontend/scripts/detect/core/characters.ts +2 -0
  51. package/dist/skills/frontend/scripts/detect/core/color.test.ts +29 -0
  52. package/dist/skills/frontend/scripts/detect/core/color.ts +150 -0
  53. package/dist/skills/frontend/scripts/detect/core/page.ts +84 -0
  54. package/dist/skills/frontend/scripts/detect/core/shadow.ts +40 -0
  55. package/dist/skills/frontend/scripts/detect/core/source.ts +33 -0
  56. package/dist/skills/frontend/scripts/detect/detect.ts +77 -0
  57. package/dist/skills/frontend/scripts/detect/index.ts +23 -0
  58. package/dist/skills/frontend/scripts/detect/lint.test.ts +27 -0
  59. package/dist/skills/frontend/scripts/detect/lint.ts +98 -0
  60. package/dist/skills/frontend/scripts/detect/render/probe-placement.test.ts +19 -0
  61. package/dist/skills/frontend/scripts/detect/render/probe-placement.ts +50 -0
  62. package/dist/skills/frontend/scripts/detect/render/renderer.ts +37 -0
  63. package/dist/skills/frontend/scripts/detect/render/webview.ts +71 -0
  64. package/dist/skills/frontend/scripts/detect/report.ts +29 -0
  65. package/dist/skills/frontend/scripts/detect/rule.ts +42 -0
  66. package/dist/skills/frontend/scripts/detect/rules/color/ai-color-palette.test.ts +74 -0
  67. package/dist/skills/frontend/scripts/detect/rules/color/ai-color-palette.ts +83 -0
  68. package/dist/skills/frontend/scripts/detect/rules/color/cream-palette.test.ts +24 -0
  69. package/dist/skills/frontend/scripts/detect/rules/color/cream-palette.ts +35 -0
  70. package/dist/skills/frontend/scripts/detect/rules/color/dark-glow.test.ts +47 -0
  71. package/dist/skills/frontend/scripts/detect/rules/color/dark-glow.ts +44 -0
  72. package/dist/skills/frontend/scripts/detect/rules/color/design-system-color.test.ts +26 -0
  73. package/dist/skills/frontend/scripts/detect/rules/color/design-system-color.ts +35 -0
  74. package/dist/skills/frontend/scripts/detect/rules/color/gradient-text.test.ts +24 -0
  75. package/dist/skills/frontend/scripts/detect/rules/color/gradient-text.ts +59 -0
  76. package/dist/skills/frontend/scripts/detect/rules/color/gray-on-color.test.ts +39 -0
  77. package/dist/skills/frontend/scripts/detect/rules/color/gray-on-color.ts +38 -0
  78. package/dist/skills/frontend/scripts/detect/rules/color/index.ts +15 -0
  79. package/dist/skills/frontend/scripts/detect/rules/color/low-contrast.test.ts +209 -0
  80. package/dist/skills/frontend/scripts/detect/rules/color/low-contrast.ts +57 -0
  81. package/dist/skills/frontend/scripts/detect/rules/color/placeholder-contrast.test.ts +62 -0
  82. package/dist/skills/frontend/scripts/detect/rules/color/radial-halo.test.ts +40 -0
  83. package/dist/skills/frontend/scripts/detect/rules/color/radial-halo.ts +31 -0
  84. package/dist/skills/frontend/scripts/detect/rules/color/radial-spotlight-glow.test.ts +27 -0
  85. package/dist/skills/frontend/scripts/detect/rules/color/radial-spotlight-glow.ts +33 -0
  86. package/dist/skills/frontend/scripts/detect/rules/color/support/animation-opacity.ts +78 -0
  87. package/dist/skills/frontend/scripts/detect/rules/color/support/color-path.ts +15 -0
  88. package/dist/skills/frontend/scripts/detect/rules/color/support/contrast-pairs.ts +54 -0
  89. package/dist/skills/frontend/scripts/detect/rules/color/support/contrast-role.ts +76 -0
  90. package/dist/skills/frontend/scripts/detect/rules/color/support/glow-forms.ts +56 -0
  91. package/dist/skills/frontend/scripts/detect/rules/color/support/gradient-samples.ts +134 -0
  92. package/dist/skills/frontend/scripts/detect/rules/color/support/gradients.ts +91 -0
  93. package/dist/skills/frontend/scripts/detect/rules/color/support/mockup-roots.ts +63 -0
  94. package/dist/skills/frontend/scripts/detect/rules/color/support/page-ignore.ts +7 -0
  95. package/dist/skills/frontend/scripts/detect/rules/color/support/painted-text.ts +141 -0
  96. package/dist/skills/frontend/scripts/detect/rules/color/support/palette-roles.ts +58 -0
  97. package/dist/skills/frontend/scripts/detect/rules/color/support/placeholder-contrast.ts +25 -0
  98. package/dist/skills/frontend/scripts/detect/rules/color/support/stock-accent.ts +31 -0
  99. package/dist/skills/frontend/scripts/detect/rules/color/support/text-colors.ts +80 -0
  100. package/dist/skills/frontend/scripts/detect/rules/copy/aphoristic-cadence.test.ts +18 -0
  101. package/dist/skills/frontend/scripts/detect/rules/copy/aphoristic-cadence.ts +20 -0
  102. package/dist/skills/frontend/scripts/detect/rules/copy/broken-image.test.ts +25 -0
  103. package/dist/skills/frontend/scripts/detect/rules/copy/broken-image.ts +17 -0
  104. package/dist/skills/frontend/scripts/detect/rules/copy/em-dash-overuse.test.ts +39 -0
  105. package/dist/skills/frontend/scripts/detect/rules/copy/em-dash-overuse.ts +46 -0
  106. package/dist/skills/frontend/scripts/detect/rules/copy/index.ts +15 -0
  107. package/dist/skills/frontend/scripts/detect/rules/copy/marketing-buzzword.test.ts +18 -0
  108. package/dist/skills/frontend/scripts/detect/rules/copy/marketing-buzzword.ts +33 -0
  109. package/dist/skills/frontend/scripts/detect/rules/copy/numbered-section-labels.test.ts +58 -0
  110. package/dist/skills/frontend/scripts/detect/rules/copy/numbered-section-labels.ts +34 -0
  111. package/dist/skills/frontend/scripts/detect/rules/copy/repeated-container-text.test.ts +43 -0
  112. package/dist/skills/frontend/scripts/detect/rules/copy/repeated-container-text.ts +56 -0
  113. package/dist/skills/frontend/scripts/detect/rules/copy/script-error.test.ts +48 -0
  114. package/dist/skills/frontend/scripts/detect/rules/copy/script-error.ts +38 -0
  115. package/dist/skills/frontend/scripts/detect/rules/copy/skipped-heading.test.ts +49 -0
  116. package/dist/skills/frontend/scripts/detect/rules/copy/skipped-heading.ts +81 -0
  117. package/dist/skills/frontend/scripts/detect/rules/copy/support/numbered-label.ts +94 -0
  118. package/dist/skills/frontend/scripts/detect/rules/copy/support/page-text.ts +37 -0
  119. package/dist/skills/frontend/scripts/detect/rules/copy/theater-slop-phrase.test.ts +17 -0
  120. package/dist/skills/frontend/scripts/detect/rules/copy/theater-slop-phrase.ts +21 -0
  121. package/dist/skills/frontend/scripts/detect/rules/decoration/blinking-cursor.test.ts +43 -0
  122. package/dist/skills/frontend/scripts/detect/rules/decoration/blinking-cursor.ts +48 -0
  123. package/dist/skills/frontend/scripts/detect/rules/decoration/border-accent-on-rounded.test.ts +33 -0
  124. package/dist/skills/frontend/scripts/detect/rules/decoration/border-accent-on-rounded.ts +14 -0
  125. package/dist/skills/frontend/scripts/detect/rules/decoration/bounce-easing.test.ts +72 -0
  126. package/dist/skills/frontend/scripts/detect/rules/decoration/bounce-easing.ts +83 -0
  127. package/dist/skills/frontend/scripts/detect/rules/decoration/buried-raster.test.ts +95 -0
  128. package/dist/skills/frontend/scripts/detect/rules/decoration/buried-raster.ts +72 -0
  129. package/dist/skills/frontend/scripts/detect/rules/decoration/codex-grid-background.test.ts +28 -0
  130. package/dist/skills/frontend/scripts/detect/rules/decoration/codex-grid-background.ts +34 -0
  131. package/dist/skills/frontend/scripts/detect/rules/decoration/design-system-radius.test.ts +37 -0
  132. package/dist/skills/frontend/scripts/detect/rules/decoration/design-system-radius.ts +31 -0
  133. package/dist/skills/frontend/scripts/detect/rules/decoration/gpt-thin-border-wide-shadow.test.ts +59 -0
  134. package/dist/skills/frontend/scripts/detect/rules/decoration/gpt-thin-border-wide-shadow.ts +66 -0
  135. package/dist/skills/frontend/scripts/detect/rules/decoration/hard-offset-shadow.test.ts +45 -0
  136. package/dist/skills/frontend/scripts/detect/rules/decoration/hard-offset-shadow.ts +31 -0
  137. package/dist/skills/frontend/scripts/detect/rules/decoration/hero-eyebrow-chip.test.ts +76 -0
  138. package/dist/skills/frontend/scripts/detect/rules/decoration/hero-eyebrow-chip.ts +19 -0
  139. package/dist/skills/frontend/scripts/detect/rules/decoration/icon-tile-stack.test.ts +67 -0
  140. package/dist/skills/frontend/scripts/detect/rules/decoration/icon-tile-stack.ts +92 -0
  141. package/dist/skills/frontend/scripts/detect/rules/decoration/index.ts +38 -0
  142. package/dist/skills/frontend/scripts/detect/rules/decoration/kicker-above-heading.test.ts +126 -0
  143. package/dist/skills/frontend/scripts/detect/rules/decoration/kicker-above-heading.ts +69 -0
  144. package/dist/skills/frontend/scripts/detect/rules/decoration/marquee.test.ts +63 -0
  145. package/dist/skills/frontend/scripts/detect/rules/decoration/marquee.ts +51 -0
  146. package/dist/skills/frontend/scripts/detect/rules/decoration/organic-clip-path.test.ts +67 -0
  147. package/dist/skills/frontend/scripts/detect/rules/decoration/organic-clip-path.ts +41 -0
  148. package/dist/skills/frontend/scripts/detect/rules/decoration/pulsing-dot.test.ts +58 -0
  149. package/dist/skills/frontend/scripts/detect/rules/decoration/pulsing-dot.ts +72 -0
  150. package/dist/skills/frontend/scripts/detect/rules/decoration/repeating-stripes-gradient.test.ts +26 -0
  151. package/dist/skills/frontend/scripts/detect/rules/decoration/repeating-stripes-gradient.ts +25 -0
  152. package/dist/skills/frontend/scripts/detect/rules/decoration/shape-assembled-illustration.test.ts +59 -0
  153. package/dist/skills/frontend/scripts/detect/rules/decoration/shape-assembled-illustration.ts +58 -0
  154. package/dist/skills/frontend/scripts/detect/rules/decoration/side-tab.test.ts +91 -0
  155. package/dist/skills/frontend/scripts/detect/rules/decoration/side-tab.ts +17 -0
  156. package/dist/skills/frontend/scripts/detect/rules/decoration/support/appearance.ts +110 -0
  157. package/dist/skills/frontend/scripts/detect/rules/decoration/support/assert-cases.ts +25 -0
  158. package/dist/skills/frontend/scripts/detect/rules/decoration/support/borders.ts +150 -0
  159. package/dist/skills/frontend/scripts/detect/rules/decoration/support/clip-geometry.ts +151 -0
  160. package/dist/skills/frontend/scripts/detect/rules/decoration/support/css-candidates.ts +66 -0
  161. package/dist/skills/frontend/scripts/detect/rules/decoration/support/curve-samples.ts +55 -0
  162. package/dist/skills/frontend/scripts/detect/rules/decoration/support/gradient-pattern.ts +40 -0
  163. package/dist/skills/frontend/scripts/detect/rules/decoration/support/keyframes.ts +134 -0
  164. package/dist/skills/frontend/scripts/detect/rules/decoration/support/labels.ts +85 -0
  165. package/dist/skills/frontend/scripts/detect/rules/decoration/support/raster-state.ts +51 -0
  166. package/dist/skills/frontend/scripts/detect/rules/index.ts +16 -0
  167. package/dist/skills/frontend/scripts/detect/rules/layout/body-text-viewport-edge.test.ts +64 -0
  168. package/dist/skills/frontend/scripts/detect/rules/layout/body-text-viewport-edge.ts +62 -0
  169. package/dist/skills/frontend/scripts/detect/rules/layout/clipped-overflow-container.test.ts +40 -0
  170. package/dist/skills/frontend/scripts/detect/rules/layout/clipped-overflow-container.ts +15 -0
  171. package/dist/skills/frontend/scripts/detect/rules/layout/content-hidden-at-rest.test.ts +62 -0
  172. package/dist/skills/frontend/scripts/detect/rules/layout/content-hidden-at-rest.ts +63 -0
  173. package/dist/skills/frontend/scripts/detect/rules/layout/cramped-padding.test.ts +61 -0
  174. package/dist/skills/frontend/scripts/detect/rules/layout/cramped-padding.ts +97 -0
  175. package/dist/skills/frontend/scripts/detect/rules/layout/edge-flush-cards.test.ts +43 -0
  176. package/dist/skills/frontend/scripts/detect/rules/layout/edge-flush-cards.ts +47 -0
  177. package/dist/skills/frontend/scripts/detect/rules/layout/first-viewport-column-overflow.test.ts +28 -0
  178. package/dist/skills/frontend/scripts/detect/rules/layout/first-viewport-column-overflow.ts +43 -0
  179. package/dist/skills/frontend/scripts/detect/rules/layout/heading-rhythm.test.ts +67 -0
  180. package/dist/skills/frontend/scripts/detect/rules/layout/heading-rhythm.ts +30 -0
  181. package/dist/skills/frontend/scripts/detect/rules/layout/index.ts +21 -0
  182. package/dist/skills/frontend/scripts/detect/rules/layout/monotonous-spacing.test.ts +19 -0
  183. package/dist/skills/frontend/scripts/detect/rules/layout/monotonous-spacing.ts +32 -0
  184. package/dist/skills/frontend/scripts/detect/rules/layout/nested-cards.test.ts +60 -0
  185. package/dist/skills/frontend/scripts/detect/rules/layout/nested-cards.ts +38 -0
  186. package/dist/skills/frontend/scripts/detect/rules/layout/straggler.test.ts +33 -0
  187. package/dist/skills/frontend/scripts/detect/rules/layout/straggler.ts +28 -0
  188. package/dist/skills/frontend/scripts/detect/rules/layout/support/cards.ts +114 -0
  189. package/dist/skills/frontend/scripts/detect/rules/layout/support/clipping.ts +71 -0
  190. package/dist/skills/frontend/scripts/detect/rules/layout/support/declared-mockups.ts +46 -0
  191. package/dist/skills/frontend/scripts/detect/rules/layout/support/geometry.ts +73 -0
  192. package/dist/skills/frontend/scripts/detect/rules/layout/support/hidden-interface.ts +35 -0
  193. package/dist/skills/frontend/scripts/detect/rules/layout/support/layout-cases.ts +23 -0
  194. package/dist/skills/frontend/scripts/detect/rules/layout/support/line-breaks.ts +32 -0
  195. package/dist/skills/frontend/scripts/detect/rules/layout/support/motion.ts +77 -0
  196. package/dist/skills/frontend/scripts/detect/rules/layout/support/padding.ts +93 -0
  197. package/dist/skills/frontend/scripts/detect/rules/layout/support/rhythm.ts +161 -0
  198. package/dist/skills/frontend/scripts/detect/rules/layout/text-occlusion.test.ts +37 -0
  199. package/dist/skills/frontend/scripts/detect/rules/layout/text-occlusion.ts +84 -0
  200. package/dist/skills/frontend/scripts/detect/rules/layout/text-overflow.test.ts +83 -0
  201. package/dist/skills/frontend/scripts/detect/rules/layout/text-overflow.ts +72 -0
  202. package/dist/skills/frontend/scripts/detect/rules/layout/unbalanced-heading.test.ts +22 -0
  203. package/dist/skills/frontend/scripts/detect/rules/layout/unbalanced-heading.ts +22 -0
  204. package/dist/skills/frontend/scripts/detect/rules/layout/viewport-reflow.test.ts +34 -0
  205. package/dist/skills/frontend/scripts/detect/rules/layout/viewport-reflow.ts +33 -0
  206. package/dist/skills/frontend/scripts/detect/rules/source/ai-color-palette.test.ts +13 -0
  207. package/dist/skills/frontend/scripts/detect/rules/source/ai-color-palette.ts +11 -0
  208. package/dist/skills/frontend/scripts/detect/rules/source/aphoristic-cadence.test.ts +12 -0
  209. package/dist/skills/frontend/scripts/detect/rules/source/aphoristic-cadence.ts +14 -0
  210. package/dist/skills/frontend/scripts/detect/rules/source/border-accent-on-rounded.test.ts +14 -0
  211. package/dist/skills/frontend/scripts/detect/rules/source/border-accent-on-rounded.ts +20 -0
  212. package/dist/skills/frontend/scripts/detect/rules/source/bounce-easing.test.ts +19 -0
  213. package/dist/skills/frontend/scripts/detect/rules/source/bounce-easing.ts +21 -0
  214. package/dist/skills/frontend/scripts/detect/rules/source/broken-image.test.ts +27 -0
  215. package/dist/skills/frontend/scripts/detect/rules/source/broken-image.ts +16 -0
  216. package/dist/skills/frontend/scripts/detect/rules/source/codex-grid-background.test.ts +11 -0
  217. package/dist/skills/frontend/scripts/detect/rules/source/codex-grid-background.ts +18 -0
  218. package/dist/skills/frontend/scripts/detect/rules/source/dark-glow.test.ts +15 -0
  219. package/dist/skills/frontend/scripts/detect/rules/source/dark-glow.ts +21 -0
  220. package/dist/skills/frontend/scripts/detect/rules/source/em-dash-overuse.test.ts +13 -0
  221. package/dist/skills/frontend/scripts/detect/rules/source/em-dash-overuse.ts +15 -0
  222. package/dist/skills/frontend/scripts/detect/rules/source/gradient-text.test.ts +12 -0
  223. package/dist/skills/frontend/scripts/detect/rules/source/gradient-text.ts +11 -0
  224. package/dist/skills/frontend/scripts/detect/rules/source/gray-on-color.test.ts +20 -0
  225. package/dist/skills/frontend/scripts/detect/rules/source/gray-on-color.ts +13 -0
  226. package/dist/skills/frontend/scripts/detect/rules/source/index.ts +19 -0
  227. package/dist/skills/frontend/scripts/detect/rules/source/marketing-buzzword.test.ts +12 -0
  228. package/dist/skills/frontend/scripts/detect/rules/source/marketing-buzzword.ts +17 -0
  229. package/dist/skills/frontend/scripts/detect/rules/source/marquee.test.ts +12 -0
  230. package/dist/skills/frontend/scripts/detect/rules/source/marquee.ts +12 -0
  231. package/dist/skills/frontend/scripts/detect/rules/source/monotonous-spacing.test.ts +13 -0
  232. package/dist/skills/frontend/scripts/detect/rules/source/monotonous-spacing.ts +22 -0
  233. package/dist/skills/frontend/scripts/detect/rules/source/overused-font.test.ts +21 -0
  234. package/dist/skills/frontend/scripts/detect/rules/source/overused-font.ts +16 -0
  235. package/dist/skills/frontend/scripts/detect/rules/source/radial-halo.test.ts +16 -0
  236. package/dist/skills/frontend/scripts/detect/rules/source/radial-halo.ts +14 -0
  237. package/dist/skills/frontend/scripts/detect/rules/source/side-tab.test.ts +29 -0
  238. package/dist/skills/frontend/scripts/detect/rules/source/side-tab.ts +58 -0
  239. package/dist/skills/frontend/scripts/detect/rules/source/support/accent-scans.ts +78 -0
  240. package/dist/skills/frontend/scripts/detect/rules/source/support/check-source.ts +6 -0
  241. package/dist/skills/frontend/scripts/detect/rules/source/support/corners.ts +105 -0
  242. package/dist/skills/frontend/scripts/detect/rules/source/support/css-effects.ts +81 -0
  243. package/dist/skills/frontend/scripts/detect/rules/source/support/css-scopes.ts +131 -0
  244. package/dist/skills/frontend/scripts/detect/rules/source/support/image-tags.ts +113 -0
  245. package/dist/skills/frontend/scripts/detect/rules/source/support/js-punctuation.ts +34 -0
  246. package/dist/skills/frontend/scripts/detect/rules/source/support/markup-scope.ts +44 -0
  247. package/dist/skills/frontend/scripts/detect/rules/source/support/source-color.ts +42 -0
  248. package/dist/skills/frontend/scripts/detect/rules/source/support/source-shadow.ts +15 -0
  249. package/dist/skills/frontend/scripts/detect/rules/source/support/source-text.ts +110 -0
  250. package/dist/skills/frontend/scripts/detect/rules/typography/all-caps-body.test.ts +24 -0
  251. package/dist/skills/frontend/scripts/detect/rules/typography/all-caps-body.ts +15 -0
  252. package/dist/skills/frontend/scripts/detect/rules/typography/design-system-font-size.test.ts +21 -0
  253. package/dist/skills/frontend/scripts/detect/rules/typography/design-system-font-size.ts +23 -0
  254. package/dist/skills/frontend/scripts/detect/rules/typography/design-system-font.test.ts +22 -0
  255. package/dist/skills/frontend/scripts/detect/rules/typography/design-system-font.ts +24 -0
  256. package/dist/skills/frontend/scripts/detect/rules/typography/extreme-negative-tracking.test.ts +23 -0
  257. package/dist/skills/frontend/scripts/detect/rules/typography/extreme-negative-tracking.ts +18 -0
  258. package/dist/skills/frontend/scripts/detect/rules/typography/flat-type-hierarchy.test.ts +33 -0
  259. package/dist/skills/frontend/scripts/detect/rules/typography/flat-type-hierarchy.ts +26 -0
  260. package/dist/skills/frontend/scripts/detect/rules/typography/index.ts +21 -0
  261. package/dist/skills/frontend/scripts/detect/rules/typography/italic-serif-display.test.ts +24 -0
  262. package/dist/skills/frontend/scripts/detect/rules/typography/italic-serif-display.ts +24 -0
  263. package/dist/skills/frontend/scripts/detect/rules/typography/justified-text.test.ts +31 -0
  264. package/dist/skills/frontend/scripts/detect/rules/typography/justified-text.ts +32 -0
  265. package/dist/skills/frontend/scripts/detect/rules/typography/line-length.test.ts +43 -0
  266. package/dist/skills/frontend/scripts/detect/rules/typography/line-length.ts +28 -0
  267. package/dist/skills/frontend/scripts/detect/rules/typography/oversized-h1.test.ts +26 -0
  268. package/dist/skills/frontend/scripts/detect/rules/typography/oversized-h1.ts +20 -0
  269. package/dist/skills/frontend/scripts/detect/rules/typography/overused-font.test.ts +35 -0
  270. package/dist/skills/frontend/scripts/detect/rules/typography/overused-font.ts +45 -0
  271. package/dist/skills/frontend/scripts/detect/rules/typography/support/drawn-enlargement.ts +48 -0
  272. package/dist/skills/frontend/scripts/detect/rules/typography/support/fading-text.ts +48 -0
  273. package/dist/skills/frontend/scripts/detect/rules/typography/support/flex-runs.ts +16 -0
  274. package/dist/skills/frontend/scripts/detect/rules/typography/support/font-family.ts +28 -0
  275. package/dist/skills/frontend/scripts/detect/rules/typography/support/painted-text.test.ts +63 -0
  276. package/dist/skills/frontend/scripts/detect/rules/typography/support/painted-text.ts +81 -0
  277. package/dist/skills/frontend/scripts/detect/rules/typography/support/svg-size.ts +57 -0
  278. package/dist/skills/frontend/scripts/detect/rules/typography/support/text-context.ts +112 -0
  279. package/dist/skills/frontend/scripts/detect/rules/typography/support/text-lines.ts +43 -0
  280. package/dist/skills/frontend/scripts/detect/rules/typography/support/type-hierarchy.ts +48 -0
  281. package/dist/skills/frontend/scripts/detect/rules/typography/tight-leading.test.ts +54 -0
  282. package/dist/skills/frontend/scripts/detect/rules/typography/tight-leading.ts +47 -0
  283. package/dist/skills/frontend/scripts/detect/rules/typography/tiny-text.test.ts +60 -0
  284. package/dist/skills/frontend/scripts/detect/rules/typography/tiny-text.ts +23 -0
  285. package/dist/skills/frontend/scripts/detect/rules/typography/undersized-ui-text.test.ts +98 -0
  286. package/dist/skills/frontend/scripts/detect/rules/typography/undersized-ui-text.ts +28 -0
  287. package/dist/skills/frontend/scripts/detect/rules/typography/wide-tracking.test.ts +26 -0
  288. package/dist/skills/frontend/scripts/detect/rules/typography/wide-tracking.ts +26 -0
  289. package/dist/skills/frontend/scripts/detect/snapshot/collect.ts +158 -0
  290. package/dist/skills/frontend/scripts/detect/snapshot/style-props.ts +25 -0
  291. package/dist/skills/frontend/scripts/detect/testing/build-snapshot.ts +78 -0
  292. package/dist/skills/frontend/scripts/detect/tsconfig.json +19 -0
  293. package/dist/skills/frontend/scripts/detect/types.ts +124 -0
  294. package/dist/skills/programming/SKILL.md +17 -74
  295. package/dist/skills/programming/references/go/README.md +1 -1
  296. package/dist/skills/programming/references/go/bootstrap.md +2 -2
  297. package/dist/skills/programming/references/python/README.md +4 -4
  298. package/dist/skills/programming/references/python/one-liners.md +5 -5
  299. package/dist/skills/programming/references/testing/README.md +82 -0
  300. package/dist/skills/programming/references/testing/junk-classes.md +56 -0
  301. package/dist/skills/programming/references/typescript/README.md +1 -2
  302. package/dist/skills/programming/scripts/go/new-project.ts +197 -0
  303. package/dist/skills/programming/scripts/python/new-project.ts +231 -0
  304. package/dist/skills/programming/scripts/python/new-script.ts +134 -0
  305. package/dist/skills/programming/scripts/rust/new-project.ts +215 -0
  306. package/dist/skills/programming/scripts/scaffolders.test.ts +96 -0
  307. package/dist/skills/programming/scripts/shared/run-tool.ts +19 -0
  308. package/dist/skills/programming/scripts/typescript/check-test-junk-rules.ts +140 -0
  309. package/dist/skills/programming/scripts/typescript/check-test-junk.test.ts +125 -0
  310. package/dist/skills/programming/scripts/typescript/check-test-junk.ts +148 -0
  311. package/dist/skills/programming/scripts/typescript/mutation-proof.test.ts +43 -0
  312. package/dist/skills/programming/scripts/typescript/mutation-proof.ts +179 -0
  313. package/dist/skills/remove-ai-slops/SKILL.md +32 -20
  314. package/dist/skills/ulw-research/scripts/source-commands.mjs +3 -1
  315. package/dist/skills/ulw-research/scripts/source-integrity.test.ts +39 -2
  316. package/dist/skills/visual-qa/SKILL.md +12 -1
  317. package/dist/tools/delegate-task/models-distribution.d.ts +1 -0
  318. package/dist/tui.js +142 -42
  319. package/package.json +22 -19
  320. package/packages/lsp-core/src/lsp/config-loader.ts +18 -2
  321. package/packages/lsp-core/src/lsp/host-js-runtime.test.ts +150 -0
  322. package/packages/lsp-core/src/lsp/host-js-runtime.ts +57 -0
  323. package/packages/lsp-core/src/lsp/server-definitions.ts +10 -0
  324. package/packages/lsp-core/src/lsp/server-resolution.ts +9 -1
  325. package/packages/lsp-core/src/lsp/typescript-server-defaults.test.ts +84 -0
  326. package/packages/lsp-daemon/dist/cli.js +81 -15
  327. package/packages/lsp-daemon/dist/client.js +74 -8
  328. package/packages/lsp-daemon/dist/index.js +76 -10
  329. package/packages/lsp-tools-mcp/dist/cli.js +74 -8
  330. package/packages/lsp-tools-mcp/dist/mcp.js +74 -8
  331. package/packages/lsp-tools-mcp/dist/tools.js +74 -8
  332. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  333. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +22 -4
  334. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  335. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  336. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  337. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  338. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  339. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  340. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  341. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  342. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +3 -3
  343. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +77 -13
  344. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  345. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  346. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  347. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  348. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  349. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  350. package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +34 -2
  351. package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +34 -2
  352. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  353. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  354. package/packages/omo-codex/plugin/components/telemetry/test/codex-hook.test.ts +14 -1
  355. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  356. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  357. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +1 -1
  358. package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
  359. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +5 -5
  360. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  361. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  362. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  363. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  364. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  365. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  366. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  367. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  368. package/packages/omo-codex/plugin/hooks/post-tool-use-recording-spawn-admission.json +1 -1
  369. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  370. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  371. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  372. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  373. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  374. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  375. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  376. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
  377. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  378. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  379. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  380. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  381. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  382. package/packages/omo-codex/plugin/package-lock.json +12 -12
  383. package/packages/omo-codex/plugin/package.json +1 -1
  384. package/packages/omo-codex/plugin/scripts/auto-update-plan.mjs +16 -1
  385. package/packages/omo-codex/plugin/skills/browser/runtime/omowright/index.js +24 -33
  386. package/packages/omo-codex/plugin/skills/browser/runtime/omowright/manifest.json +3 -3
  387. package/packages/omo-codex/plugin/skills/frontend/ATTRIBUTION.md +104 -1
  388. package/packages/omo-codex/plugin/skills/frontend/SKILL.md +7 -3
  389. package/packages/omo-codex/plugin/skills/frontend/references/design/design-system-architecture.md +3 -3
  390. package/packages/omo-codex/plugin/skills/frontend/references/perfection/craft-floor.md +59 -0
  391. package/packages/omo-codex/plugin/skills/frontend/references/perfection/detect.md +52 -0
  392. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/cli.ts +70 -0
  393. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/config.ts +53 -0
  394. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/core/characters.ts +2 -0
  395. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/core/color.ts +150 -0
  396. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/core/page.ts +84 -0
  397. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/core/shadow.ts +40 -0
  398. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/core/source.ts +33 -0
  399. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/detect.ts +77 -0
  400. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/index.ts +23 -0
  401. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/lint.ts +98 -0
  402. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/render/probe-placement.ts +50 -0
  403. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/render/renderer.ts +37 -0
  404. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/render/webview.ts +71 -0
  405. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/report.ts +29 -0
  406. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rule.ts +42 -0
  407. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/ai-color-palette.ts +83 -0
  408. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/cream-palette.ts +35 -0
  409. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/dark-glow.ts +44 -0
  410. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/design-system-color.ts +35 -0
  411. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/gradient-text.ts +59 -0
  412. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/gray-on-color.ts +38 -0
  413. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/index.ts +15 -0
  414. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/low-contrast.ts +57 -0
  415. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/radial-halo.ts +31 -0
  416. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/radial-spotlight-glow.ts +33 -0
  417. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/support/animation-opacity.ts +78 -0
  418. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/support/color-path.ts +15 -0
  419. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/support/contrast-pairs.ts +54 -0
  420. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/support/contrast-role.ts +76 -0
  421. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/support/glow-forms.ts +56 -0
  422. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/support/gradient-samples.ts +134 -0
  423. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/support/gradients.ts +91 -0
  424. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/support/mockup-roots.ts +63 -0
  425. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/support/page-ignore.ts +7 -0
  426. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/support/painted-text.ts +141 -0
  427. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/support/palette-roles.ts +58 -0
  428. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/support/placeholder-contrast.ts +25 -0
  429. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/support/stock-accent.ts +31 -0
  430. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/color/support/text-colors.ts +80 -0
  431. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/copy/aphoristic-cadence.ts +20 -0
  432. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/copy/broken-image.ts +17 -0
  433. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/copy/em-dash-overuse.ts +46 -0
  434. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/copy/index.ts +15 -0
  435. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/copy/marketing-buzzword.ts +33 -0
  436. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/copy/numbered-section-labels.ts +34 -0
  437. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/copy/repeated-container-text.ts +56 -0
  438. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/copy/script-error.ts +38 -0
  439. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/copy/skipped-heading.ts +81 -0
  440. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/copy/support/numbered-label.ts +94 -0
  441. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/copy/support/page-text.ts +37 -0
  442. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/copy/theater-slop-phrase.ts +21 -0
  443. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/blinking-cursor.ts +48 -0
  444. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/border-accent-on-rounded.ts +14 -0
  445. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/bounce-easing.ts +83 -0
  446. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/buried-raster.ts +72 -0
  447. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/codex-grid-background.ts +34 -0
  448. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/design-system-radius.ts +31 -0
  449. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/gpt-thin-border-wide-shadow.ts +66 -0
  450. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/hard-offset-shadow.ts +31 -0
  451. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/hero-eyebrow-chip.ts +19 -0
  452. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/icon-tile-stack.ts +92 -0
  453. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/index.ts +38 -0
  454. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/kicker-above-heading.ts +69 -0
  455. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/marquee.ts +51 -0
  456. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/organic-clip-path.ts +41 -0
  457. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/pulsing-dot.ts +72 -0
  458. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/repeating-stripes-gradient.ts +25 -0
  459. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/shape-assembled-illustration.ts +58 -0
  460. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/side-tab.ts +17 -0
  461. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/support/appearance.ts +110 -0
  462. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/support/assert-cases.ts +25 -0
  463. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/support/borders.ts +150 -0
  464. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/support/clip-geometry.ts +151 -0
  465. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/support/css-candidates.ts +66 -0
  466. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/support/curve-samples.ts +55 -0
  467. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/support/gradient-pattern.ts +40 -0
  468. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/support/keyframes.ts +134 -0
  469. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/support/labels.ts +85 -0
  470. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/decoration/support/raster-state.ts +51 -0
  471. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/index.ts +16 -0
  472. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/body-text-viewport-edge.ts +62 -0
  473. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/clipped-overflow-container.ts +15 -0
  474. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/content-hidden-at-rest.ts +63 -0
  475. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/cramped-padding.ts +97 -0
  476. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/edge-flush-cards.ts +47 -0
  477. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/first-viewport-column-overflow.ts +43 -0
  478. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/heading-rhythm.ts +30 -0
  479. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/index.ts +21 -0
  480. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/monotonous-spacing.ts +32 -0
  481. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/nested-cards.ts +38 -0
  482. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/straggler.ts +28 -0
  483. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/support/cards.ts +114 -0
  484. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/support/clipping.ts +71 -0
  485. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/support/declared-mockups.ts +46 -0
  486. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/support/geometry.ts +73 -0
  487. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/support/hidden-interface.ts +35 -0
  488. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/support/layout-cases.ts +23 -0
  489. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/support/line-breaks.ts +32 -0
  490. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/support/motion.ts +77 -0
  491. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/support/padding.ts +93 -0
  492. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/support/rhythm.ts +161 -0
  493. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/text-occlusion.ts +84 -0
  494. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/text-overflow.ts +72 -0
  495. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/unbalanced-heading.ts +22 -0
  496. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/layout/viewport-reflow.ts +33 -0
  497. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/ai-color-palette.ts +11 -0
  498. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/aphoristic-cadence.ts +14 -0
  499. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/border-accent-on-rounded.ts +20 -0
  500. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/bounce-easing.ts +21 -0
  501. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/broken-image.ts +16 -0
  502. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/codex-grid-background.ts +18 -0
  503. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/dark-glow.ts +21 -0
  504. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/em-dash-overuse.ts +15 -0
  505. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/gradient-text.ts +11 -0
  506. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/gray-on-color.ts +13 -0
  507. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/index.ts +19 -0
  508. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/marketing-buzzword.ts +17 -0
  509. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/marquee.ts +12 -0
  510. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/monotonous-spacing.ts +22 -0
  511. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/overused-font.ts +16 -0
  512. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/radial-halo.ts +14 -0
  513. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/side-tab.ts +58 -0
  514. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/support/accent-scans.ts +78 -0
  515. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/support/check-source.ts +6 -0
  516. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/support/corners.ts +105 -0
  517. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/support/css-effects.ts +81 -0
  518. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/support/css-scopes.ts +131 -0
  519. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/support/image-tags.ts +113 -0
  520. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/support/js-punctuation.ts +34 -0
  521. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/support/markup-scope.ts +44 -0
  522. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/support/source-color.ts +42 -0
  523. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/support/source-shadow.ts +15 -0
  524. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/source/support/source-text.ts +110 -0
  525. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/all-caps-body.ts +15 -0
  526. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/design-system-font-size.ts +23 -0
  527. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/design-system-font.ts +24 -0
  528. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/extreme-negative-tracking.ts +18 -0
  529. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/flat-type-hierarchy.ts +26 -0
  530. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/index.ts +21 -0
  531. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/italic-serif-display.ts +24 -0
  532. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/justified-text.ts +32 -0
  533. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/line-length.ts +28 -0
  534. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/oversized-h1.ts +20 -0
  535. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/overused-font.ts +45 -0
  536. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/support/drawn-enlargement.ts +48 -0
  537. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/support/fading-text.ts +48 -0
  538. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/support/flex-runs.ts +16 -0
  539. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/support/font-family.ts +28 -0
  540. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/support/painted-text.ts +81 -0
  541. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/support/svg-size.ts +57 -0
  542. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/support/text-context.ts +112 -0
  543. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/support/text-lines.ts +43 -0
  544. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/support/type-hierarchy.ts +48 -0
  545. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/tight-leading.ts +47 -0
  546. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/tiny-text.ts +23 -0
  547. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/undersized-ui-text.ts +28 -0
  548. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/rules/typography/wide-tracking.ts +26 -0
  549. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/snapshot/collect.ts +158 -0
  550. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/snapshot/style-props.ts +25 -0
  551. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/testing/build-snapshot.ts +78 -0
  552. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/tsconfig.json +19 -0
  553. package/packages/omo-codex/plugin/skills/frontend/scripts/detect/types.ts +124 -0
  554. package/packages/omo-codex/plugin/skills/programming/SKILL.md +17 -74
  555. package/packages/omo-codex/plugin/skills/programming/references/go/README.md +1 -1
  556. package/packages/omo-codex/plugin/skills/programming/references/go/bootstrap.md +2 -2
  557. package/packages/omo-codex/plugin/skills/programming/references/python/README.md +4 -4
  558. package/packages/omo-codex/plugin/skills/programming/references/python/one-liners.md +5 -5
  559. package/packages/omo-codex/plugin/skills/programming/references/testing/README.md +82 -0
  560. package/packages/omo-codex/plugin/skills/programming/references/testing/junk-classes.md +56 -0
  561. package/packages/omo-codex/plugin/skills/programming/references/typescript/README.md +1 -2
  562. package/packages/omo-codex/plugin/skills/programming/scripts/go/new-project.ts +197 -0
  563. package/packages/omo-codex/plugin/skills/programming/scripts/python/new-project.ts +231 -0
  564. package/packages/omo-codex/plugin/skills/programming/scripts/python/new-script.ts +134 -0
  565. package/packages/omo-codex/plugin/skills/programming/scripts/rust/new-project.ts +215 -0
  566. package/packages/omo-codex/plugin/skills/programming/scripts/shared/run-tool.ts +19 -0
  567. package/packages/omo-codex/plugin/skills/programming/scripts/typescript/check-test-junk-rules.ts +140 -0
  568. package/packages/omo-codex/plugin/skills/programming/scripts/typescript/check-test-junk.ts +148 -0
  569. package/packages/omo-codex/plugin/skills/programming/scripts/typescript/mutation-proof.ts +179 -0
  570. package/packages/omo-codex/plugin/skills/remove-ai-slops/SKILL.md +32 -20
  571. package/packages/omo-codex/plugin/skills/ulw-research/scripts/source-commands.mjs +3 -1
  572. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +12 -1
  573. package/packages/omo-codex/plugin/test/auto-update.test.mjs +62 -0
  574. package/packages/omo-codex/plugin/test/payload-equivalence.test.mjs +12 -2
  575. package/packages/omo-codex/scripts/install-dist/install-local.mjs +79 -10
  576. package/packages/shared-skills/skills/browser/runtime/omowright/index.js +24 -33
  577. package/packages/shared-skills/skills/browser/runtime/omowright/manifest.json +3 -3
  578. package/packages/shared-skills/skills/frontend/ATTRIBUTION.md +104 -1
  579. package/packages/shared-skills/skills/frontend/SKILL.md +7 -3
  580. package/packages/shared-skills/skills/frontend/references/design/design-system-architecture.md +3 -3
  581. package/packages/shared-skills/skills/frontend/references/perfection/craft-floor.md +59 -0
  582. package/packages/shared-skills/skills/frontend/references/perfection/detect.md +52 -0
  583. package/packages/shared-skills/skills/frontend/scripts/detect/cli.ts +70 -0
  584. package/packages/shared-skills/skills/frontend/scripts/detect/config.test.ts +26 -0
  585. package/packages/shared-skills/skills/frontend/scripts/detect/config.ts +53 -0
  586. package/packages/shared-skills/skills/frontend/scripts/detect/core/characters.ts +2 -0
  587. package/packages/shared-skills/skills/frontend/scripts/detect/core/color.test.ts +29 -0
  588. package/packages/shared-skills/skills/frontend/scripts/detect/core/color.ts +150 -0
  589. package/packages/shared-skills/skills/frontend/scripts/detect/core/page.ts +84 -0
  590. package/packages/shared-skills/skills/frontend/scripts/detect/core/shadow.ts +40 -0
  591. package/packages/shared-skills/skills/frontend/scripts/detect/core/source.ts +33 -0
  592. package/packages/shared-skills/skills/frontend/scripts/detect/detect.ts +77 -0
  593. package/packages/shared-skills/skills/frontend/scripts/detect/index.ts +23 -0
  594. package/packages/shared-skills/skills/frontend/scripts/detect/lint.test.ts +27 -0
  595. package/packages/shared-skills/skills/frontend/scripts/detect/lint.ts +98 -0
  596. package/packages/shared-skills/skills/frontend/scripts/detect/render/probe-placement.test.ts +19 -0
  597. package/packages/shared-skills/skills/frontend/scripts/detect/render/probe-placement.ts +50 -0
  598. package/packages/shared-skills/skills/frontend/scripts/detect/render/renderer.ts +37 -0
  599. package/packages/shared-skills/skills/frontend/scripts/detect/render/webview.ts +71 -0
  600. package/packages/shared-skills/skills/frontend/scripts/detect/report.ts +29 -0
  601. package/packages/shared-skills/skills/frontend/scripts/detect/rule.ts +42 -0
  602. package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/ai-color-palette.test.ts +74 -0
  603. package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/ai-color-palette.ts +83 -0
  604. package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/cream-palette.test.ts +24 -0
  605. package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/cream-palette.ts +35 -0
  606. package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/dark-glow.test.ts +47 -0
  607. package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/dark-glow.ts +44 -0
  608. package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/design-system-color.test.ts +26 -0
  609. package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/design-system-color.ts +35 -0
  610. package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/gradient-text.test.ts +24 -0
  611. package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/gradient-text.ts +59 -0
  612. package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/gray-on-color.test.ts +39 -0
  613. package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/gray-on-color.ts +38 -0
  614. package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/index.ts +15 -0
  615. package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/low-contrast.test.ts +209 -0
  616. package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/low-contrast.ts +57 -0
  617. package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/placeholder-contrast.test.ts +62 -0
  618. package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/radial-halo.test.ts +40 -0
  619. package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/radial-halo.ts +31 -0
  620. package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/radial-spotlight-glow.test.ts +27 -0
  621. package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/radial-spotlight-glow.ts +33 -0
  622. package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/support/animation-opacity.ts +78 -0
  623. package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/support/color-path.ts +15 -0
  624. package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/support/contrast-pairs.ts +54 -0
  625. package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/support/contrast-role.ts +76 -0
  626. package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/support/glow-forms.ts +56 -0
  627. package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/support/gradient-samples.ts +134 -0
  628. package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/support/gradients.ts +91 -0
  629. package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/support/mockup-roots.ts +63 -0
  630. package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/support/page-ignore.ts +7 -0
  631. package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/support/painted-text.ts +141 -0
  632. package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/support/palette-roles.ts +58 -0
  633. package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/support/placeholder-contrast.ts +25 -0
  634. package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/support/stock-accent.ts +31 -0
  635. package/packages/shared-skills/skills/frontend/scripts/detect/rules/color/support/text-colors.ts +80 -0
  636. package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/aphoristic-cadence.test.ts +18 -0
  637. package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/aphoristic-cadence.ts +20 -0
  638. package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/broken-image.test.ts +25 -0
  639. package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/broken-image.ts +17 -0
  640. package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/em-dash-overuse.test.ts +39 -0
  641. package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/em-dash-overuse.ts +46 -0
  642. package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/index.ts +15 -0
  643. package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/marketing-buzzword.test.ts +18 -0
  644. package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/marketing-buzzword.ts +33 -0
  645. package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/numbered-section-labels.test.ts +58 -0
  646. package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/numbered-section-labels.ts +34 -0
  647. package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/repeated-container-text.test.ts +43 -0
  648. package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/repeated-container-text.ts +56 -0
  649. package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/script-error.test.ts +48 -0
  650. package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/script-error.ts +38 -0
  651. package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/skipped-heading.test.ts +49 -0
  652. package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/skipped-heading.ts +81 -0
  653. package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/support/numbered-label.ts +94 -0
  654. package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/support/page-text.ts +37 -0
  655. package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/theater-slop-phrase.test.ts +17 -0
  656. package/packages/shared-skills/skills/frontend/scripts/detect/rules/copy/theater-slop-phrase.ts +21 -0
  657. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/blinking-cursor.test.ts +43 -0
  658. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/blinking-cursor.ts +48 -0
  659. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/border-accent-on-rounded.test.ts +33 -0
  660. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/border-accent-on-rounded.ts +14 -0
  661. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/bounce-easing.test.ts +72 -0
  662. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/bounce-easing.ts +83 -0
  663. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/buried-raster.test.ts +95 -0
  664. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/buried-raster.ts +72 -0
  665. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/codex-grid-background.test.ts +28 -0
  666. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/codex-grid-background.ts +34 -0
  667. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/design-system-radius.test.ts +37 -0
  668. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/design-system-radius.ts +31 -0
  669. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/gpt-thin-border-wide-shadow.test.ts +59 -0
  670. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/gpt-thin-border-wide-shadow.ts +66 -0
  671. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/hard-offset-shadow.test.ts +45 -0
  672. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/hard-offset-shadow.ts +31 -0
  673. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/hero-eyebrow-chip.test.ts +76 -0
  674. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/hero-eyebrow-chip.ts +19 -0
  675. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/icon-tile-stack.test.ts +67 -0
  676. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/icon-tile-stack.ts +92 -0
  677. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/index.ts +38 -0
  678. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/kicker-above-heading.test.ts +126 -0
  679. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/kicker-above-heading.ts +69 -0
  680. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/marquee.test.ts +63 -0
  681. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/marquee.ts +51 -0
  682. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/organic-clip-path.test.ts +67 -0
  683. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/organic-clip-path.ts +41 -0
  684. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/pulsing-dot.test.ts +58 -0
  685. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/pulsing-dot.ts +72 -0
  686. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/repeating-stripes-gradient.test.ts +26 -0
  687. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/repeating-stripes-gradient.ts +25 -0
  688. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/shape-assembled-illustration.test.ts +59 -0
  689. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/shape-assembled-illustration.ts +58 -0
  690. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/side-tab.test.ts +91 -0
  691. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/side-tab.ts +17 -0
  692. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/support/appearance.ts +110 -0
  693. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/support/assert-cases.ts +25 -0
  694. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/support/borders.ts +150 -0
  695. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/support/clip-geometry.ts +151 -0
  696. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/support/css-candidates.ts +66 -0
  697. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/support/curve-samples.ts +55 -0
  698. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/support/gradient-pattern.ts +40 -0
  699. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/support/keyframes.ts +134 -0
  700. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/support/labels.ts +85 -0
  701. package/packages/shared-skills/skills/frontend/scripts/detect/rules/decoration/support/raster-state.ts +51 -0
  702. package/packages/shared-skills/skills/frontend/scripts/detect/rules/index.ts +16 -0
  703. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/body-text-viewport-edge.test.ts +64 -0
  704. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/body-text-viewport-edge.ts +62 -0
  705. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/clipped-overflow-container.test.ts +40 -0
  706. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/clipped-overflow-container.ts +15 -0
  707. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/content-hidden-at-rest.test.ts +62 -0
  708. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/content-hidden-at-rest.ts +63 -0
  709. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/cramped-padding.test.ts +61 -0
  710. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/cramped-padding.ts +97 -0
  711. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/edge-flush-cards.test.ts +43 -0
  712. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/edge-flush-cards.ts +47 -0
  713. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/first-viewport-column-overflow.test.ts +28 -0
  714. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/first-viewport-column-overflow.ts +43 -0
  715. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/heading-rhythm.test.ts +67 -0
  716. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/heading-rhythm.ts +30 -0
  717. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/index.ts +21 -0
  718. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/monotonous-spacing.test.ts +19 -0
  719. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/monotonous-spacing.ts +32 -0
  720. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/nested-cards.test.ts +60 -0
  721. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/nested-cards.ts +38 -0
  722. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/straggler.test.ts +33 -0
  723. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/straggler.ts +28 -0
  724. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/support/cards.ts +114 -0
  725. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/support/clipping.ts +71 -0
  726. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/support/declared-mockups.ts +46 -0
  727. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/support/geometry.ts +73 -0
  728. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/support/hidden-interface.ts +35 -0
  729. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/support/layout-cases.ts +23 -0
  730. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/support/line-breaks.ts +32 -0
  731. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/support/motion.ts +77 -0
  732. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/support/padding.ts +93 -0
  733. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/support/rhythm.ts +161 -0
  734. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/text-occlusion.test.ts +37 -0
  735. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/text-occlusion.ts +84 -0
  736. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/text-overflow.test.ts +83 -0
  737. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/text-overflow.ts +72 -0
  738. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/unbalanced-heading.test.ts +22 -0
  739. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/unbalanced-heading.ts +22 -0
  740. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/viewport-reflow.test.ts +34 -0
  741. package/packages/shared-skills/skills/frontend/scripts/detect/rules/layout/viewport-reflow.ts +33 -0
  742. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/ai-color-palette.test.ts +13 -0
  743. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/ai-color-palette.ts +11 -0
  744. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/aphoristic-cadence.test.ts +12 -0
  745. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/aphoristic-cadence.ts +14 -0
  746. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/border-accent-on-rounded.test.ts +14 -0
  747. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/border-accent-on-rounded.ts +20 -0
  748. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/bounce-easing.test.ts +19 -0
  749. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/bounce-easing.ts +21 -0
  750. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/broken-image.test.ts +27 -0
  751. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/broken-image.ts +16 -0
  752. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/codex-grid-background.test.ts +11 -0
  753. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/codex-grid-background.ts +18 -0
  754. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/dark-glow.test.ts +15 -0
  755. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/dark-glow.ts +21 -0
  756. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/em-dash-overuse.test.ts +13 -0
  757. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/em-dash-overuse.ts +15 -0
  758. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/gradient-text.test.ts +12 -0
  759. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/gradient-text.ts +11 -0
  760. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/gray-on-color.test.ts +20 -0
  761. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/gray-on-color.ts +13 -0
  762. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/index.ts +19 -0
  763. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/marketing-buzzword.test.ts +12 -0
  764. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/marketing-buzzword.ts +17 -0
  765. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/marquee.test.ts +12 -0
  766. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/marquee.ts +12 -0
  767. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/monotonous-spacing.test.ts +13 -0
  768. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/monotonous-spacing.ts +22 -0
  769. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/overused-font.test.ts +21 -0
  770. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/overused-font.ts +16 -0
  771. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/radial-halo.test.ts +16 -0
  772. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/radial-halo.ts +14 -0
  773. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/side-tab.test.ts +29 -0
  774. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/side-tab.ts +58 -0
  775. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/support/accent-scans.ts +78 -0
  776. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/support/check-source.ts +6 -0
  777. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/support/corners.ts +105 -0
  778. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/support/css-effects.ts +81 -0
  779. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/support/css-scopes.ts +131 -0
  780. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/support/image-tags.ts +113 -0
  781. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/support/js-punctuation.ts +34 -0
  782. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/support/markup-scope.ts +44 -0
  783. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/support/source-color.ts +42 -0
  784. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/support/source-shadow.ts +15 -0
  785. package/packages/shared-skills/skills/frontend/scripts/detect/rules/source/support/source-text.ts +110 -0
  786. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/all-caps-body.test.ts +24 -0
  787. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/all-caps-body.ts +15 -0
  788. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/design-system-font-size.test.ts +21 -0
  789. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/design-system-font-size.ts +23 -0
  790. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/design-system-font.test.ts +22 -0
  791. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/design-system-font.ts +24 -0
  792. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/extreme-negative-tracking.test.ts +23 -0
  793. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/extreme-negative-tracking.ts +18 -0
  794. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/flat-type-hierarchy.test.ts +33 -0
  795. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/flat-type-hierarchy.ts +26 -0
  796. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/index.ts +21 -0
  797. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/italic-serif-display.test.ts +24 -0
  798. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/italic-serif-display.ts +24 -0
  799. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/justified-text.test.ts +31 -0
  800. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/justified-text.ts +32 -0
  801. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/line-length.test.ts +43 -0
  802. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/line-length.ts +28 -0
  803. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/oversized-h1.test.ts +26 -0
  804. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/oversized-h1.ts +20 -0
  805. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/overused-font.test.ts +35 -0
  806. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/overused-font.ts +45 -0
  807. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/support/drawn-enlargement.ts +48 -0
  808. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/support/fading-text.ts +48 -0
  809. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/support/flex-runs.ts +16 -0
  810. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/support/font-family.ts +28 -0
  811. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/support/painted-text.test.ts +63 -0
  812. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/support/painted-text.ts +81 -0
  813. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/support/svg-size.ts +57 -0
  814. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/support/text-context.ts +112 -0
  815. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/support/text-lines.ts +43 -0
  816. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/support/type-hierarchy.ts +48 -0
  817. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/tight-leading.test.ts +54 -0
  818. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/tight-leading.ts +47 -0
  819. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/tiny-text.test.ts +60 -0
  820. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/tiny-text.ts +23 -0
  821. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/undersized-ui-text.test.ts +98 -0
  822. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/undersized-ui-text.ts +28 -0
  823. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/wide-tracking.test.ts +26 -0
  824. package/packages/shared-skills/skills/frontend/scripts/detect/rules/typography/wide-tracking.ts +26 -0
  825. package/packages/shared-skills/skills/frontend/scripts/detect/snapshot/collect.ts +158 -0
  826. package/packages/shared-skills/skills/frontend/scripts/detect/snapshot/style-props.ts +25 -0
  827. package/packages/shared-skills/skills/frontend/scripts/detect/testing/build-snapshot.ts +78 -0
  828. package/packages/shared-skills/skills/frontend/scripts/detect/tsconfig.json +19 -0
  829. package/packages/shared-skills/skills/frontend/scripts/detect/types.ts +124 -0
  830. package/packages/shared-skills/skills/programming/SKILL.md +17 -74
  831. package/packages/shared-skills/skills/programming/references/go/README.md +1 -1
  832. package/packages/shared-skills/skills/programming/references/go/bootstrap.md +2 -2
  833. package/packages/shared-skills/skills/programming/references/python/README.md +4 -4
  834. package/packages/shared-skills/skills/programming/references/python/one-liners.md +5 -5
  835. package/packages/shared-skills/skills/programming/references/testing/README.md +82 -0
  836. package/packages/shared-skills/skills/programming/references/testing/junk-classes.md +56 -0
  837. package/packages/shared-skills/skills/programming/references/typescript/README.md +1 -2
  838. package/packages/shared-skills/skills/programming/scripts/go/new-project.ts +197 -0
  839. package/packages/shared-skills/skills/programming/scripts/python/new-project.ts +231 -0
  840. package/packages/shared-skills/skills/programming/scripts/python/new-script.ts +134 -0
  841. package/packages/shared-skills/skills/programming/scripts/rust/new-project.ts +215 -0
  842. package/packages/shared-skills/skills/programming/scripts/scaffolders.test.ts +96 -0
  843. package/packages/shared-skills/skills/programming/scripts/shared/run-tool.ts +19 -0
  844. package/packages/shared-skills/skills/programming/scripts/typescript/check-test-junk-rules.ts +140 -0
  845. package/packages/shared-skills/skills/programming/scripts/typescript/check-test-junk.test.ts +125 -0
  846. package/packages/shared-skills/skills/programming/scripts/typescript/check-test-junk.ts +148 -0
  847. package/packages/shared-skills/skills/programming/scripts/typescript/mutation-proof.test.ts +43 -0
  848. package/packages/shared-skills/skills/programming/scripts/typescript/mutation-proof.ts +179 -0
  849. package/packages/shared-skills/skills/remove-ai-slops/SKILL.md +32 -20
  850. package/packages/shared-skills/skills/ulw-research/scripts/source-commands.mjs +3 -1
  851. package/packages/shared-skills/skills/ulw-research/scripts/source-integrity.test.ts +39 -2
  852. package/packages/shared-skills/skills/visual-qa/SKILL.md +12 -1
  853. package/dist/agents/gpt-prompt-identity.d.ts +0 -3
  854. package/dist/agents/hephaestus/gpt-5-4.d.ts +0 -24
  855. package/dist/agents/hephaestus/gpt-5-5.d.ts +0 -2
  856. package/dist/agents/hephaestus/gpt-5-6.d.ts +0 -2
  857. package/dist/agents/kimi-tool-loop-guard.d.ts +0 -1
  858. package/dist/agents/sisyphus/claude-fable-5.d.ts +0 -19
  859. package/dist/agents/sisyphus/claude-opus-4-7.d.ts +0 -22
  860. package/dist/agents/sisyphus/claude-opus-4-8.d.ts +0 -19
  861. package/dist/agents/sisyphus/claude-opus-5.d.ts +0 -33
  862. package/dist/agents/sisyphus/gemini.d.ts +0 -20
  863. package/dist/agents/sisyphus/glm-5-2.d.ts +0 -4
  864. package/dist/agents/sisyphus/gpt-5-4.d.ts +0 -26
  865. package/dist/agents/sisyphus/gpt-5-5.d.ts +0 -6
  866. package/dist/agents/sisyphus/gpt-task-system-guide.d.ts +0 -1
  867. package/dist/agents/sisyphus/grok-4.d.ts +0 -21
  868. package/dist/agents/sisyphus/index.d.ts +0 -31
  869. package/dist/agents/sisyphus/kimi-k2-6.d.ts +0 -32
  870. package/dist/agents/sisyphus/kimi-k2-7.d.ts +0 -17
  871. package/dist/agents/sisyphus/kimi-k3-1.d.ts +0 -9
  872. package/dist/agents/sisyphus/kimi-k3.d.ts +0 -19
  873. package/dist/agents/sisyphus-dynamic-prompt-builder.d.ts +0 -2
  874. package/dist/agents/sisyphus-dynamic-prompt-execution.d.ts +0 -2
  875. package/dist/agents/sisyphus-dynamic-prompt-exploration.d.ts +0 -2
  876. package/dist/agents/sisyphus-dynamic-prompt-role.d.ts +0 -2
  877. package/dist/agents/sisyphus-dynamic-prompt-sections.d.ts +0 -18
  878. package/dist/agents/sisyphus-dynamic-prompt-style.d.ts +0 -2
  879. package/dist/agents/sisyphus-dynamic-prompt.d.ts +0 -3
  880. package/dist/agents/sisyphus-gemini-fallback-overrides.d.ts +0 -1
  881. package/dist/agents/sisyphus-junior/gemini.d.ts +0 -10
  882. package/dist/agents/sisyphus-junior/glm-5-2.d.ts +0 -1
  883. package/dist/agents/sisyphus-junior/gpt-5-4.d.ts +0 -11
  884. package/dist/agents/sisyphus-junior/gpt-5-5.d.ts +0 -5
  885. package/dist/agents/sisyphus-junior/gpt.d.ts +0 -9
  886. package/dist/agents/sisyphus-junior/kimi-k2-6.d.ts +0 -13
  887. package/dist/agents/sisyphus-junior/kimi-k2-7.d.ts +0 -11
  888. package/dist/agents/sisyphus-junior/kimi-k3-1.d.ts +0 -6
  889. package/dist/agents/sisyphus-junior/kimi-k3.d.ts +0 -12
  890. package/dist/features/claude-code-agent-loader/opencode-config-agents-reader.d.ts +0 -1
  891. package/dist/features/claude-code-command-loader/loader-cache.d.ts +0 -1
  892. package/dist/features/claude-code-command-loader/loader.d.ts +0 -1
  893. package/dist/features/opencode-skill-loader/config-source-discovery.d.ts +0 -1
  894. package/dist/features/opencode-skill-loader/merger/config-skill-entry-loader.d.ts +0 -1
  895. package/dist/features/opencode-skill-loader/opencode-config-skills-reader.d.ts +0 -1
  896. package/dist/features/team-mode/team-layout-tmux/resolve-caller-tmux-session.d.ts +0 -1
  897. package/dist/features/team-mode/team-registry/team-spec-input-normalizer.d.ts +0 -1
  898. package/dist/shared/git-worktree/collect-git-diff-stats.d.ts +0 -1
  899. package/dist/shared/git-worktree/parse-status-porcelain-line.d.ts +0 -1
  900. package/dist/shared/migration/agent-names.d.ts +0 -1
  901. package/dist/shared/migration/migrations-sidecar.d.ts +0 -1
  902. package/dist/shared/skill-path-resolver.d.ts +0 -1
  903. package/dist/shared/zip-entry-listing/powershell-zip-entry-listing.d.ts +0 -1
  904. package/dist/shared/zip-entry-listing/zipinfo-zip-entry-listing.d.ts +0 -1
  905. package/dist/skills/programming/scripts/go/new-project.py +0 -138
  906. package/dist/skills/programming/scripts/python/new-project.py +0 -172
  907. package/dist/skills/programming/scripts/python/new-script.py +0 -116
  908. package/dist/skills/programming/scripts/rust/new-project.py +0 -178
  909. package/packages/omo-codex/plugin/skills/programming/scripts/go/new-project.py +0 -138
  910. package/packages/omo-codex/plugin/skills/programming/scripts/python/new-project.py +0 -172
  911. package/packages/omo-codex/plugin/skills/programming/scripts/python/new-script.py +0 -116
  912. package/packages/omo-codex/plugin/skills/programming/scripts/rust/new-project.py +0 -178
  913. package/packages/shared-skills/skills/programming/scripts/go/new-project.py +0 -138
  914. package/packages/shared-skills/skills/programming/scripts/python/new-project.py +0 -172
  915. package/packages/shared-skills/skills/programming/scripts/python/new-script.py +0 -116
  916. package/packages/shared-skills/skills/programming/scripts/rust/new-project.py +0 -178
package/dist/cli/index.js CHANGED
@@ -2132,7 +2132,7 @@ var package_default;
2132
2132
  var init_package = __esm(() => {
2133
2133
  package_default = {
2134
2134
  name: "oh-my-opencode",
2135
- version: "5.1.51",
2135
+ version: "5.1.55",
2136
2136
  description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
2137
2137
  main: "./dist/index.js",
2138
2138
  types: "dist/index.d.ts",
@@ -2156,6 +2156,7 @@ var init_package = __esm(() => {
2156
2156
  "packages/openclaw-core",
2157
2157
  "packages/boulder-state",
2158
2158
  "packages/memory-core",
2159
+ "packages/device-service-core",
2159
2160
  "packages/isolation-core",
2160
2161
  "packages/telemetry-core",
2161
2162
  "packages/claude-code-compat-core",
@@ -2274,14 +2275,15 @@ var init_package = __esm(() => {
2274
2275
  prepublishOnly: "bun run clean && bun run build:lsp-tools-mcp && bun run build:lsp-daemon && bun run build",
2275
2276
  "test:model-capabilities": "bun test --timeout 20000 packages/model-core/src/model-capability-aliases.test.ts packages/model-core/src/model-capability-guardrails.test.ts packages/model-core/src/model-capabilities.test.ts packages/omo-opencode/src/cli/doctor/checks/model-resolution.test.ts --bail",
2276
2277
  "check:copy": "bun script/check-copy.ts",
2277
- typecheck: "bun run check:copy && tsgo --noEmit && bun run typecheck:script && bun run typecheck:packages",
2278
- "typecheck:packages": "tsgo --noEmit -p packages/rules-engine/tsconfig.json && tsgo --noEmit -p packages/delegate-core/tsconfig.json && tsgo --noEmit -p packages/mcp-stdio-core/tsconfig.json && tsgo --noEmit -p packages/mcp-client-core/tsconfig.json && tsgo --noEmit -p packages/git-bash-mcp/tsconfig.json && tsgo --noEmit -p packages/ast-grep-mcp/tsconfig.json && tsgo --noEmit -p packages/lsp-core/tsconfig.json && tsgo --noEmit -p packages/utils/tsconfig.json && tsgo --noEmit -p packages/model-core/tsconfig.json && tsgo --noEmit -p packages/omo-config-core/tsconfig.json && tsgo --noEmit -p packages/prompts-core/tsconfig.json && tsgo --noEmit -p packages/comment-checker-core/tsconfig.json && tsgo --noEmit -p packages/hashline-core/tsconfig.json && tsgo --noEmit -p packages/tmux-core/tsconfig.json && tsgo --noEmit -p packages/team-core/tsconfig.json && tsgo --noEmit -p packages/openclaw-core/tsconfig.json && tsgo --noEmit -p packages/boulder-state/tsconfig.json && tsgo --noEmit -p packages/isolation-core/tsconfig.json && tsgo --noEmit -p packages/memory-core/tsconfig.json && tsgo --noEmit -p packages/telemetry-core/tsconfig.json && tsgo --noEmit -p packages/claude-code-compat-core/tsconfig.json && tsgo --noEmit -p packages/skills-loader-core/tsconfig.json && tsgo --noEmit -p packages/agents-md-core/tsconfig.json && tsgo --noEmit -p packages/omo-codex/plugin/shared/tsconfig.json && tsgo --noEmit -p packages/omo-codex/tsconfig.json && tsgo --noEmit -p packages/omo-senpi/tsconfig.json && tsgo --noEmit -p packages/senpi-task/tsconfig.json && tsgo --noEmit -p packages/omo-opencode/tsconfig.json && tsgo --noEmit -p packages/omo-native/tsconfig.json && tsgo --noEmit -p packages/senpi-desktop-protocol/tsconfig.json && tsgo --noEmit -p packages/senpi-desktop-engine/tsconfig.json && tsgo --noEmit -p packages/senpi-desktop-prelude/tsconfig.json && tsgo --noEmit -p packages/senpi-desktop-service/tsconfig.json && tsgo --noEmit -p packages/senpi-desktop-tool/tsconfig.json",
2279
- "typecheck:script": "tsgo --noEmit -p script/tsconfig.json",
2278
+ typecheck: "bun run check:copy && bun check --no-script --all -p tsconfig.json && bun run typecheck:script && bun run typecheck:packages && bun run typecheck:skill-scripts",
2279
+ "typecheck:skill-scripts": "bun check --no-script --all -p packages/shared-skills/skills/frontend/scripts/detect/tsconfig.json",
2280
+ "typecheck:packages": "bun check --no-script --all -p packages/rules-engine/tsconfig.json && bun check --no-script --all -p packages/delegate-core/tsconfig.json && bun check --no-script --all -p packages/mcp-stdio-core/tsconfig.json && bun check --no-script --all -p packages/mcp-client-core/tsconfig.json && bun check --no-script --all -p packages/git-bash-mcp/tsconfig.json && bun check --no-script --all -p packages/ast-grep-mcp/tsconfig.json && bun check --no-script --all -p packages/lsp-core/tsconfig.json && bun check --no-script --all -p packages/utils/tsconfig.json && bun check --no-script --all -p packages/device-service-core/tsconfig.json && bun check --no-script --all -p packages/model-core/tsconfig.json && bun check --no-script --all -p packages/omo-config-core/tsconfig.json && bun check --no-script --all -p packages/prompts-core/tsconfig.json && bun check --no-script --all -p packages/comment-checker-core/tsconfig.json && bun check --no-script --all -p packages/hashline-core/tsconfig.json && bun check --no-script --all -p packages/tmux-core/tsconfig.json && bun check --no-script --all -p packages/team-core/tsconfig.json && bun check --no-script --all -p packages/openclaw-core/tsconfig.json && bun check --no-script --all -p packages/boulder-state/tsconfig.json && bun check --no-script --all -p packages/isolation-core/tsconfig.json && bun check --no-script --all -p packages/memory-core/tsconfig.json && bun check --no-script --all -p packages/telemetry-core/tsconfig.json && bun check --no-script --all -p packages/claude-code-compat-core/tsconfig.json && bun check --no-script --all -p packages/skills-loader-core/tsconfig.json && bun check --no-script --all -p packages/agents-md-core/tsconfig.json && bun check --no-script --all -p packages/omo-codex/plugin/shared/tsconfig.json && bun check --no-script --all -p packages/omo-codex/tsconfig.json && bun check --no-script --all -p packages/omo-senpi/tsconfig.json && bun check --no-script --all -p packages/senpi-task/tsconfig.json && bun check --no-script --all -p packages/omo-opencode/tsconfig.json && bun check --no-script --all -p packages/omo-native/tsconfig.json && bun check --no-script --all -p packages/senpi-desktop-protocol/tsconfig.json && bun check --no-script --all -p packages/senpi-desktop-engine/tsconfig.json && bun check --no-script --all -p packages/senpi-desktop-prelude/tsconfig.json && bun check --no-script --all -p packages/senpi-desktop-service/tsconfig.json && bun check --no-script --all -p packages/senpi-desktop-tool/tsconfig.json",
2281
+ "typecheck:script": "bun check --no-script --all -p script/tsconfig.json",
2280
2282
  test: "bun test --timeout 20000",
2281
2283
  "changelog:section": "bun script/changelog-section.ts",
2282
2284
  "test:codex": "bun run build:codex-install && bun run build:git-bash-mcp && bun run build:lsp-tools-mcp && bun run build:lsp-daemon && npm --prefix packages/lsp-tools-mcp test && npm --prefix packages/omo-codex/plugin ci && npm --prefix packages/omo-codex/plugin/components/ulw-loop test && bun run --cwd packages/omo-codex/plugin build && node scripts/check-third-party-notices.mjs --ship && bun test --timeout 20000 packages/omo-opencode/src/cli/cli-installer.platform.test.ts packages/omo-codex/src/install/codex-cache.test.ts packages/omo-codex/src/install/codex-cleanup.test.ts packages/omo-codex/src/install/codex-config-agent-cleanup.test.ts packages/omo-codex/src/install/codex-config-autonomous-features.test.ts packages/omo-codex/src/install/codex-config-reasoning.test.ts packages/omo-codex/src/install/codex-config-toml.test.ts packages/omo-codex/src/install/codex-project-local-cleanup.test.ts packages/omo-codex/src/install/install-codex-project-local-cleanup.test.ts packages/omo-codex/src/install/install-codex.test.ts packages/omo-codex/src/install/install-codex-packaged.test.ts packages/omo-codex/src/install/link-cached-plugin-agents.test.ts packages/omo-codex/src/**/*.test.ts packages/utils/src/jsonc-parser.test.ts packages/utils/src/frontmatter.test.ts packages/hashline-core/src/hash-computation.test.ts packages/hashline-core/src/smoke-untested-modules.test.ts packages/rules-engine/src/index.test.ts packages/rules-engine/src/security-boundary.test.ts packages/agents-md-core/src/injector.test.ts packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts && node --test packages/omo-codex/plugin/test/*.test.mjs packages/omo-codex/scripts/install-cache-copy.test.mjs packages/omo-codex/scripts/install-cli-args.test.mjs packages/omo-codex/scripts/install-delegated-command.test.mjs packages/omo-codex/scripts/install-config-autonomous-features.test.mjs packages/omo-codex/scripts/install-config-autonomous.test.mjs packages/omo-codex/scripts/install-config-reasoning.test.mjs packages/omo-codex/scripts/install-config.test.mjs packages/omo-codex/scripts/install-hook-targets.test.mjs packages/omo-codex/scripts/install-project-local-cleanup.test.mjs packages/omo-codex/scripts/install-lazycodex-version-stamp.test.mjs packages/omo-codex/scripts/install-local-entrypoint.test.mjs packages/omo-codex/scripts/install-local-git-bash-preflight.test.mjs packages/omo-codex/scripts/install-local.test.mjs packages/omo-codex/scripts/install-marketplace-cache.test.mjs packages/omo-codex/scripts/install-mcp-context7-runtime.test.mjs packages/omo-codex/scripts/install-mcp-runtime.test.mjs packages/omo-codex/scripts/install-packaged-local.test.mjs packages/omo-codex/scripts/install-generated-bundle.test.mjs packages/omo-codex/scripts/install-agent-links.test.mjs packages/omo-codex/scripts/install-bin-links.test.mjs",
2283
2285
  "test:fast": "bun run script/test-fast.ts",
2284
- "test:senpi": "bun run build:senpi-plugin && tsgo --noEmit -p packages/omo-senpi/tsconfig.json && bun test --timeout 20000 packages/omo-senpi && bun test ./.agents/skills/senpi-qa/scripts/resolve-evidence-dir.test.mjs",
2286
+ "test:senpi": "bun run build:senpi-plugin && bun check --no-script --all -p packages/omo-senpi/tsconfig.json && bun test --timeout 20000 packages/omo-senpi && bun test ./.agents/skills/senpi-qa/scripts/resolve-evidence-dir.test.mjs",
2285
2287
  "test:windows-codex": "bun run test:codex",
2286
2288
  "build:git-bash-mcp": "bun run --cwd packages/git-bash-mcp build",
2287
2289
  "build:ast-grep-mcp": "bun run --cwd packages/ast-grep-mcp build",
@@ -2317,11 +2319,12 @@ var init_package = __esm(() => {
2317
2319
  },
2318
2320
  devDependencies: {
2319
2321
  "@clack/prompts": "^1.8.1",
2320
- "@code-yeongyu/senpi": "2026.10.27-1",
2322
+ "@code-yeongyu/senpi": "2026.10.30-1",
2321
2323
  "@modelcontextprotocol/sdk": "^1.30.0",
2322
2324
  "@oh-my-opencode/agents-md-core": "workspace:*",
2323
2325
  "@oh-my-opencode/ast-grep-mcp": "workspace:*",
2324
2326
  "@oh-my-opencode/boulder-state": "workspace:*",
2327
+ "@oh-my-opencode/device-service-core": "workspace:*",
2325
2328
  "@oh-my-opencode/claude-code-compat-core": "workspace:*",
2326
2329
  "@oh-my-opencode/comment-checker-core": "workspace:*",
2327
2330
  "@oh-my-opencode/delegate-core": "workspace:*",
@@ -2371,7 +2374,7 @@ var init_package = __esm(() => {
2371
2374
  "jsonc-parser": "^3.3.1",
2372
2375
  knip: "6.43.0",
2373
2376
  "node-pty": "^1.1.0",
2374
- omowright: "github:code-yeongyu/omowright#f87ef4d63fe7b56fe117dbab246c8ad88dd8a780",
2377
+ omowright: "github:code-yeongyu/omowright#c06d20337ad942b09dea8757a45f6c848008a68d",
2375
2378
  "oxc-parser": "0.148.0",
2376
2379
  oxlint: "1.89.0",
2377
2380
  picocolors: "^1.1.1",
@@ -2381,18 +2384,18 @@ var init_package = __esm(() => {
2381
2384
  typescript: "^7.0.2"
2382
2385
  },
2383
2386
  optionalDependencies: {
2384
- "oh-my-opencode-darwin-arm64": "5.1.51",
2385
- "oh-my-opencode-darwin-x64": "5.1.51",
2386
- "oh-my-opencode-darwin-x64-baseline": "5.1.51",
2387
- "oh-my-opencode-linux-arm64": "5.1.51",
2388
- "oh-my-opencode-linux-arm64-musl": "5.1.51",
2389
- "oh-my-opencode-linux-x64": "5.1.51",
2390
- "oh-my-opencode-linux-x64-baseline": "5.1.51",
2391
- "oh-my-opencode-linux-x64-musl": "5.1.51",
2392
- "oh-my-opencode-linux-x64-musl-baseline": "5.1.51",
2393
- "oh-my-opencode-windows-arm64": "5.1.51",
2394
- "oh-my-opencode-windows-x64": "5.1.51",
2395
- "oh-my-opencode-windows-x64-baseline": "5.1.51"
2387
+ "oh-my-opencode-darwin-arm64": "5.1.55",
2388
+ "oh-my-opencode-darwin-x64": "5.1.55",
2389
+ "oh-my-opencode-darwin-x64-baseline": "5.1.55",
2390
+ "oh-my-opencode-linux-arm64": "5.1.55",
2391
+ "oh-my-opencode-linux-arm64-musl": "5.1.55",
2392
+ "oh-my-opencode-linux-x64": "5.1.55",
2393
+ "oh-my-opencode-linux-x64-baseline": "5.1.55",
2394
+ "oh-my-opencode-linux-x64-musl": "5.1.55",
2395
+ "oh-my-opencode-linux-x64-musl-baseline": "5.1.55",
2396
+ "oh-my-opencode-windows-arm64": "5.1.55",
2397
+ "oh-my-opencode-windows-x64": "5.1.55",
2398
+ "oh-my-opencode-windows-x64-baseline": "5.1.55"
2396
2399
  },
2397
2400
  overrides: {
2398
2401
  hono: "^4.13.8",
@@ -8055,7 +8058,8 @@ var init_latest_models = __esm(() => {
8055
8058
  gptLunaFast: "gpt-6-luna-fast",
8056
8059
  glm: "glm-5.3",
8057
8060
  glmFlash: "glm-5.3-flash",
8058
- kimi: "kimi-k3",
8061
+ kimi: "kimi-k3.1-pro",
8062
+ kimiK3: "kimi-k3",
8059
8063
  geminiPro: "gemini-4-argon"
8060
8064
  };
8061
8065
  });
@@ -9378,9 +9382,13 @@ var init_agent_model_requirements = __esm(() => {
9378
9382
  variant: "max"
9379
9383
  },
9380
9384
  {
9381
- providers: ["opencode-go", "kimi-for-coding", "moonshotai", "opencode", "bailian-coding-plan", "moonshotai-cn", "firmware", "ollama-cloud", "aihubmix"],
9385
+ providers: ["opencode-go", "kimi-for-coding", "moonshotai", "moonshotai-cn"],
9382
9386
  model: LATEST_MODEL_BY_FAMILY.kimi
9383
9387
  },
9388
+ {
9389
+ providers: ["opencode", "bailian-coding-plan", "firmware", "ollama-cloud", "aihubmix"],
9390
+ model: LATEST_MODEL_BY_FAMILY.kimiK3
9391
+ },
9384
9392
  {
9385
9393
  providers: ["openai", "chatgpt-subscription", "github-copilot", "opencode"],
9386
9394
  model: "gpt-5.6-sol",
@@ -9475,10 +9483,11 @@ var init_agent_model_requirements = __esm(() => {
9475
9483
  variant: "max"
9476
9484
  },
9477
9485
  {
9478
- providers: ["opencode-go", "kimi-for-coding", "moonshotai", "opencode"],
9486
+ providers: ["opencode-go", "kimi-for-coding", "moonshotai"],
9479
9487
  model: LATEST_MODEL_BY_FAMILY.kimi,
9480
9488
  variant: "max"
9481
- }
9489
+ },
9490
+ { providers: ["opencode"], model: LATEST_MODEL_BY_FAMILY.kimiK3, variant: "max" }
9482
9491
  ])
9483
9492
  },
9484
9493
  metis: {
@@ -9499,10 +9508,11 @@ var init_agent_model_requirements = __esm(() => {
9499
9508
  variant: "max"
9500
9509
  },
9501
9510
  {
9502
- providers: ["opencode-go", "kimi-for-coding", "moonshotai", "opencode"],
9511
+ providers: ["opencode-go", "kimi-for-coding", "moonshotai"],
9503
9512
  model: LATEST_MODEL_BY_FAMILY.kimi,
9504
9513
  variant: "max"
9505
- }
9514
+ },
9515
+ { providers: ["opencode"], model: LATEST_MODEL_BY_FAMILY.kimiK3, variant: "max" }
9506
9516
  ])
9507
9517
  },
9508
9518
  momus: {
@@ -9585,10 +9595,11 @@ var init_category_model_requirements = __esm(() => {
9585
9595
  variant: "max"
9586
9596
  },
9587
9597
  {
9588
- providers: ["kimi-for-coding", "moonshotai", "opencode-go", "opencode"],
9598
+ providers: ["kimi-for-coding", "moonshotai", "opencode-go"],
9589
9599
  model: LATEST_MODEL_BY_FAMILY.kimi,
9590
9600
  variant: "max"
9591
- }
9601
+ },
9602
+ { providers: ["opencode"], model: LATEST_MODEL_BY_FAMILY.kimiK3, variant: "max" }
9592
9603
  ])
9593
9604
  },
9594
9605
  ultrabrain: {
@@ -9640,10 +9651,11 @@ var init_category_model_requirements = __esm(() => {
9640
9651
  variant: "max"
9641
9652
  },
9642
9653
  {
9643
- providers: ["kimi-for-coding", "moonshotai", "opencode-go", "opencode"],
9654
+ providers: ["kimi-for-coding", "moonshotai", "opencode-go"],
9644
9655
  model: LATEST_MODEL_BY_FAMILY.kimi,
9645
9656
  variant: "max"
9646
- }
9657
+ },
9658
+ { providers: ["opencode"], model: LATEST_MODEL_BY_FAMILY.kimiK3, variant: "max" }
9647
9659
  ])
9648
9660
  },
9649
9661
  quick: {
@@ -9706,10 +9718,11 @@ var init_category_model_requirements = __esm(() => {
9706
9718
  },
9707
9719
  { providers: ["zai-coding-plan", "opencode-go"], model: LATEST_MODEL_BY_FAMILY.glm, variant: "max" },
9708
9720
  {
9709
- providers: ["kimi-for-coding", "moonshotai", "opencode-go", "opencode"],
9721
+ providers: ["kimi-for-coding", "moonshotai", "opencode-go"],
9710
9722
  model: LATEST_MODEL_BY_FAMILY.kimi,
9711
9723
  variant: "max"
9712
- }
9724
+ },
9725
+ { providers: ["opencode"], model: LATEST_MODEL_BY_FAMILY.kimiK3, variant: "max" }
9713
9726
  ]
9714
9727
  },
9715
9728
  writing: {
@@ -10273,7 +10286,7 @@ function transformModelForProviderDisplay(provider, model) {
10273
10286
  var CLAUDE_VERSION_DOT, GEMINI_31_PRO_PREVIEW, GEMINI_3_FLASH_PREVIEW;
10274
10287
  var init_provider_model_id_transform = __esm(() => {
10275
10288
  CLAUDE_VERSION_DOT = /claude-(\w+)-(\d+)-(\d+)/g;
10276
- GEMINI_31_PRO_PREVIEW = /gemini-3\.1-pro(?!-)/g;
10289
+ GEMINI_31_PRO_PREVIEW = /(?<!antigravity-)gemini-3\.1-pro(?!-)/g;
10277
10290
  GEMINI_3_FLASH_PREVIEW = /(?<!antigravity-)gemini-3-flash(?!-)/g;
10278
10291
  });
10279
10292
 
@@ -10347,6 +10360,36 @@ var init_supplemental_entries = __esm(() => {
10347
10360
  output: 262144
10348
10361
  }
10349
10362
  },
10363
+ "kimi-k3.1-pro": {
10364
+ id: "kimi-k3.1-pro",
10365
+ family: "kimi",
10366
+ reasoning: true,
10367
+ temperature: true,
10368
+ toolCall: true,
10369
+ modalities: {
10370
+ input: ["text", "image", "video"],
10371
+ output: ["text"]
10372
+ },
10373
+ limit: {
10374
+ context: 1048576,
10375
+ output: 1048576
10376
+ }
10377
+ },
10378
+ "kimi-k3.1-pro-highspeed": {
10379
+ id: "kimi-k3.1-pro-highspeed",
10380
+ family: "kimi",
10381
+ reasoning: true,
10382
+ temperature: true,
10383
+ toolCall: true,
10384
+ modalities: {
10385
+ input: ["text", "image", "video"],
10386
+ output: ["text"]
10387
+ },
10388
+ limit: {
10389
+ context: 1048576,
10390
+ output: 1048576
10391
+ }
10392
+ },
10350
10393
  "kimi-k2.6": {
10351
10394
  id: "kimi-k2.6",
10352
10395
  family: "kimi",
@@ -12431,6 +12474,33 @@ function createJsonFileCacheStore(options) {
12431
12474
  });
12432
12475
  }
12433
12476
  }
12477
+ function writeIfChanged(value) {
12478
+ ensureCacheDir();
12479
+ const cacheFile = getCacheFilePath();
12480
+ const serialized = options.serialize?.(value) ?? JSON.stringify(value, null, 2);
12481
+ try {
12482
+ const existing = existsSync10(cacheFile) ? readFileSync3(cacheFile, "utf-8") : undefined;
12483
+ const unchanged = existing !== undefined && (existing === serialized || options.comparable !== undefined && JSON.stringify(options.comparable(JSON.parse(existing))) === JSON.stringify(options.comparable(value)));
12484
+ if (unchanged) {
12485
+ memoryValue = value;
12486
+ writtenInCurrentProcess = true;
12487
+ log2(`[${options.logPrefix}] ${options.cacheLabel} unchanged; skipped write`, options.describe(value));
12488
+ return false;
12489
+ }
12490
+ } catch {}
12491
+ try {
12492
+ writeFileSync4(cacheFile, serialized);
12493
+ memoryValue = value;
12494
+ writtenInCurrentProcess = true;
12495
+ log2(`[${options.logPrefix}] ${options.cacheLabel} written`, options.describe(value));
12496
+ return true;
12497
+ } catch (error) {
12498
+ log2(`[${options.logPrefix}] Error writing ${toLogLabel(options.cacheLabel)}`, {
12499
+ error: String(error)
12500
+ });
12501
+ return false;
12502
+ }
12503
+ }
12434
12504
  function resetMemory() {
12435
12505
  memoryValue = undefined;
12436
12506
  writtenInCurrentProcess = false;
@@ -12439,6 +12509,7 @@ function createJsonFileCacheStore(options) {
12439
12509
  read,
12440
12510
  has,
12441
12511
  write,
12512
+ writeIfChanged,
12442
12513
  resetMemory
12443
12514
  };
12444
12515
  }
@@ -67503,7 +67574,8 @@ function createModelCapabilitiesCacheStore(getCacheDir = getOmoOpenCodeCacheDir)
67503
67574
  generatedAt: snapshot.generatedAt
67504
67575
  }),
67505
67576
  serialize: (snapshot) => `${JSON.stringify(snapshot, null, 2)}
67506
- `
67577
+ `,
67578
+ comparable: ({ generatedAt: _generatedAt, ...catalog }) => catalog
67507
67579
  });
67508
67580
  function readModelCapabilitiesCache() {
67509
67581
  return snapshotCacheStore.read();
@@ -67516,7 +67588,7 @@ function createModelCapabilitiesCacheStore(getCacheDir = getOmoOpenCodeCacheDir)
67516
67588
  }
67517
67589
  async function refreshModelCapabilitiesCache(args = {}) {
67518
67590
  const snapshot = await fetchModelCapabilitiesSnapshot(args);
67519
- writeModelCapabilitiesCache(snapshot);
67591
+ snapshotCacheStore.writeIfChanged(snapshot);
67520
67592
  return snapshot;
67521
67593
  }
67522
67594
  return {
@@ -76883,6 +76955,7 @@ var init_agent = __esm(() => {
76883
76955
  prompt: string2().optional(),
76884
76956
  model: string2().optional(),
76885
76957
  models: array(OmoAgentModelEntrySchema).optional(),
76958
+ models_distribution: _enum(["sequential", "round_robin"]).optional(),
76886
76959
  reasoning: OmoReasoningSchema.optional(),
76887
76960
  variant: string2().optional(),
76888
76961
  reasoningEffort: OmoReasoningEffortSchema.optional(),
@@ -76915,6 +76988,7 @@ var init_category = __esm(() => {
76915
76988
  description: string2().optional(),
76916
76989
  model: string2().optional(),
76917
76990
  models: array(union([string2(), OmoFallbackModelObjectSchema])).optional(),
76991
+ models_distribution: _enum(["sequential", "round_robin"]).optional(),
76918
76992
  reasoning: OmoReasoningSchema.optional(),
76919
76993
  temperature: number2().min(0).max(2).optional(),
76920
76994
  top_p: number2().min(0).max(1).optional(),
@@ -77153,8 +77227,8 @@ var init_memory = __esm(() => {
77153
77227
  enabled: boolean2().optional()
77154
77228
  }).strict();
77155
77229
  OmoMemoryProjectionSchema = object({
77156
- max_entries_per_directory: number2().int().min(0).default(40),
77157
- max_bytes: number2().int().min(0).default(24576)
77230
+ max_entries_per_directory: number2().int().min(0).default(0),
77231
+ max_bytes: number2().int().min(0).default(40960)
77158
77232
  }).strict();
77159
77233
  OmoMemoryProjectionLayerSchema = object({
77160
77234
  max_entries_per_directory: number2().int().min(0).optional(),
@@ -77218,7 +77292,7 @@ var init_memory = __esm(() => {
77218
77292
  query_expansion: false
77219
77293
  }),
77220
77294
  project_scope: OmoMemoryProjectScopeSchema.default({ nudge: true, recall: true }),
77221
- projection: OmoMemoryProjectionSchema.default({ max_entries_per_directory: 40, max_bytes: 24576 }),
77295
+ projection: OmoMemoryProjectionSchema.default({ max_entries_per_directory: 0, max_bytes: 40960 }),
77222
77296
  compile_warn_tokens: number2().int().positive().default(30000),
77223
77297
  agents: record(string2(), OmoMemoryAgentOverridesSchema).default({})
77224
77298
  }).strict();
@@ -77266,6 +77340,21 @@ var init_model_catalog = __esm(() => {
77266
77340
  OmoModelCatalogLayerSchema = record(string2(), OmoModelCatalogEntryLayerSchema);
77267
77341
  });
77268
77342
 
77343
+ // packages/omo-config-core/src/schema/model-pad.ts
77344
+ var OmoModelPadLabelsSchema, OmoModelPadSchema;
77345
+ var init_model_pad = __esm(() => {
77346
+ init_zod();
77347
+ OmoModelPadLabelsSchema = object({
77348
+ daily: string2().optional(),
77349
+ geeky: string2().optional(),
77350
+ normal: string2().optional(),
77351
+ heavy: string2().optional()
77352
+ }).strict();
77353
+ OmoModelPadSchema = object({
77354
+ labels: OmoModelPadLabelsSchema.optional()
77355
+ }).strict();
77356
+ });
77357
+
77269
77358
  // packages/omo-config-core/src/schema/model-profile.ts
77270
77359
  function isRecord8(value) {
77271
77360
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -77586,6 +77675,7 @@ var init_config = __esm(() => {
77586
77675
  init_git_master();
77587
77676
  init_memory();
77588
77677
  init_model_catalog();
77678
+ init_model_pad();
77589
77679
  init_model_profile();
77590
77680
  init_side_panel();
77591
77681
  init_task();
@@ -77607,6 +77697,7 @@ var init_config = __esm(() => {
77607
77697
  models: OmoModelCatalogLayerSchema.optional(),
77608
77698
  model_profiles: OmoModelProfilesLayerSchema.optional(),
77609
77699
  model_profile: string2().optional(),
77700
+ model_pad: OmoModelPadSchema.optional(),
77610
77701
  memory: OmoMemorySettingsLayerSchema.optional(),
77611
77702
  telemetry: OmoTelemetrySettingsLayerSchema.optional(),
77612
77703
  side_panel: OmoSidePanelSettingsLayerSchema.optional(),
@@ -77625,6 +77716,7 @@ var init_config = __esm(() => {
77625
77716
  models: OmoModelCatalogLayerSchema.optional(),
77626
77717
  model_profiles: OmoModelProfilesLayerSchema.optional(),
77627
77718
  model_profile: string2().optional(),
77719
+ model_pad: OmoModelPadSchema.optional(),
77628
77720
  memory: OmoMemorySettingsLayerSchema.optional(),
77629
77721
  telemetry: OmoTelemetrySettingsLayerSchema.optional(),
77630
77722
  side_panel: OmoSidePanelSettingsLayerSchema.optional(),
@@ -77648,6 +77740,7 @@ var init_config = __esm(() => {
77648
77740
  models: OmoModelCatalogSchema.optional(),
77649
77741
  model_profiles: OmoModelProfilesSchema.optional(),
77650
77742
  model_profile: string2().optional(),
77743
+ model_pad: OmoModelPadSchema.optional(),
77651
77744
  memory: OmoMemorySettingsSchema.optional(),
77652
77745
  telemetry: OmoTelemetrySettingsSchema.optional(),
77653
77746
  side_panel: OmoSidePanelSettingsSchema.optional(),
@@ -77674,6 +77767,7 @@ var init_config = __esm(() => {
77674
77767
  models: OmoModelCatalogLayerSchema.optional(),
77675
77768
  model_profiles: OmoModelProfilesLayerSchema.optional(),
77676
77769
  model_profile: string2().optional(),
77770
+ model_pad: OmoModelPadSchema.optional(),
77677
77771
  memory: OmoMemorySettingsLayerSchema.optional(),
77678
77772
  telemetry: OmoTelemetrySettingsLayerSchema.optional(),
77679
77773
  side_panel: OmoSidePanelSettingsLayerSchema.optional(),
@@ -77819,6 +77913,7 @@ var init_schema = __esm(() => {
77819
77913
  init_legacy_harness_names();
77820
77914
  init_memory();
77821
77915
  init_model_catalog();
77916
+ init_model_pad();
77822
77917
  init_model_profile();
77823
77918
  init_model_ref();
77824
77919
  init_provenance();
@@ -78737,9 +78832,13 @@ function resolveModelReferences(view) {
78737
78832
  }
78738
78833
  var init_model_reference_resolution = () => {};
78739
78834
 
78835
+ // packages/omo-config-core/src/models/models-distribution.ts
78836
+ var init_models_distribution = () => {};
78837
+
78740
78838
  // packages/omo-config-core/src/models/index.ts
78741
78839
  var init_models = __esm(() => {
78742
78840
  init_model_reference_resolution();
78841
+ init_models_distribution();
78743
78842
  });
78744
78843
 
78745
78844
  // packages/omo-config-core/src/writer/types.ts
@@ -82839,6 +82938,37 @@ function getDefaultTelemetryOsProvider() {
82839
82938
  }
82840
82939
  var init_machine_id = () => {};
82841
82940
 
82941
+ // packages/telemetry-core/src/terminal-program.ts
82942
+ function isKnownTerminalProgram(value) {
82943
+ return KNOWN_TERMINAL_PROGRAMS.some((known) => known === value);
82944
+ }
82945
+ function toTelemetryTerminalProgram(termProgram) {
82946
+ if (termProgram === undefined || termProgram === "")
82947
+ return;
82948
+ return isKnownTerminalProgram(termProgram) ? termProgram : "other";
82949
+ }
82950
+ var KNOWN_TERMINAL_PROGRAMS;
82951
+ var init_terminal_program = __esm(() => {
82952
+ KNOWN_TERMINAL_PROGRAMS = [
82953
+ "Apple_Terminal",
82954
+ "iTerm.app",
82955
+ "vscode",
82956
+ "cursor",
82957
+ "windsurf",
82958
+ "zed",
82959
+ "WezTerm",
82960
+ "ghostty",
82961
+ "tmux",
82962
+ "Hyper",
82963
+ "WarpTerminal",
82964
+ "kitty",
82965
+ "alacritty",
82966
+ "Tabby",
82967
+ "rio",
82968
+ "mintty"
82969
+ ];
82970
+ });
82971
+
82842
82972
  // packages/telemetry-core/src/injected-client.ts
82843
82973
  function isTelemetryClientEnabled(input) {
82844
82974
  const env = input.env ?? process.env;
@@ -82941,12 +83071,16 @@ function getSharedProperties(input) {
82941
83071
  total_memory_gb: Math.round(osProvider.totalmem() / 1024 / 1024 / 1024),
82942
83072
  locale: Intl.DateTimeFormat().resolvedOptions().locale,
82943
83073
  timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
82944
- shell: process.env.SHELL,
83074
+ shell: getShellName(process.env.SHELL),
82945
83075
  ci: Boolean(process.env.CI),
82946
- terminal: process.env.TERM_PROGRAM,
83076
+ terminal: toTelemetryTerminalProgram(process.env.TERM_PROGRAM),
82947
83077
  ...input.product.additionalProperties
82948
83078
  };
82949
83079
  }
83080
+ function getShellName(shellPath) {
83081
+ const name = shellPath?.split(/[\\/]/).pop()?.replace(/\.exe$/i, "");
83082
+ return name ? name : undefined;
83083
+ }
82950
83084
  function getSafeCpuInfo(osProvider, input) {
82951
83085
  try {
82952
83086
  const cpuInfo = osProvider.cpus();
@@ -82971,6 +83105,7 @@ var NO_OP_CLIENT;
82971
83105
  var init_injected_client = __esm(() => {
82972
83106
  init_env();
82973
83107
  init_machine_id();
83108
+ init_terminal_program();
82974
83109
  NO_OP_CLIENT = {
82975
83110
  enabled: false,
82976
83111
  trackActive: () => {
@@ -92550,7 +92685,7 @@ var package_default2;
92550
92685
  var init_package2 = __esm(() => {
92551
92686
  package_default2 = {
92552
92687
  name: "@oh-my-opencode/omo-codex",
92553
- version: "5.1.51",
92688
+ version: "5.1.55",
92554
92689
  type: "module",
92555
92690
  private: true,
92556
92691
  description: "Codex harness adapter for oh-my-openagent. Vendored Codex plugin namespace (omo) + TypeScript installer + telemetry.",
@@ -93758,11 +93893,22 @@ init_commander();
93758
93893
  // packages/omo-opencode/src/cli/install.ts
93759
93894
  init_package();
93760
93895
 
93896
+ // packages/omo-opencode/src/cli/cli-installer.ts
93897
+ import { createInterface as createInterface2 } from "readline/promises";
93898
+
93899
+ // packages/telemetry-core/src/install-disclosure.ts
93900
+ var TELEMETRY_PRIVACY_POLICY_URL = "https://github.com/code-yeongyu/oh-my-openagent/blob/dev/docs/legal/privacy-policy.md";
93901
+ var TELEMETRY_INSTALL_DISCLOSURE_LINES = [
93902
+ "OmO sends anonymous usage telemetry (no prompts, code, file paths, or account data) to improve the product.",
93903
+ "The data goes to PostHog in the United States.",
93904
+ "Turn it off with DO_NOT_TRACK=1 (or OMO_DISABLE_TELEMETRY=1).",
93905
+ `Details: ${TELEMETRY_PRIVACY_POLICY_URL}`
93906
+ ];
93907
+
93761
93908
  // packages/omo-opencode/src/cli/cli-installer.ts
93762
93909
  init_shared();
93763
93910
  init_config_manager();
93764
93911
  var import_picocolors3 = __toESM(require_picocolors(), 1);
93765
- import { createInterface as createInterface2 } from "readline/promises";
93766
93912
 
93767
93913
  // packages/omo-opencode/src/cli/install-validators.ts
93768
93914
  var import_picocolors = __toESM(require_picocolors(), 1);
@@ -99923,6 +100069,7 @@ var REQUIRED_PLUGIN_ARTIFACTS = [
99923
100069
  join66("extensions", "omo-thread-client.js"),
99924
100070
  join66("extensions", "omo-telemetry-recovery.js"),
99925
100071
  join66("extensions", "omo-feedback.js"),
100072
+ join66("extensions", "omo-desktop-toolkit.js"),
99926
100073
  join66("extensions", "omo-claim-receipt.js"),
99927
100074
  join66("extensions", "assets.generated.json"),
99928
100075
  join66("extensions", "omo-member.js"),
@@ -101201,8 +101348,8 @@ async function runCliInstaller(args, version) {
101201
101348
  }
101202
101349
  console.log();
101203
101350
  }
101204
- printInfo("Anonymous telemetry is enabled by default. Disable it with OMO_SEND_ANONYMOUS_TELEMETRY=0 or OMO_DISABLE_POSTHOG=1.");
101205
- printInfo("Docs: docs/legal/privacy-policy.md and docs/legal/terms-of-service.md");
101351
+ for (const line of TELEMETRY_INSTALL_DISCLOSURE_LINES)
101352
+ printInfo(line);
101206
101353
  console.log();
101207
101354
  printBox(`${import_picocolors3.default.bold("Pro Tip:")} Include ${import_picocolors3.default.cyan("ultrawork")} (or ${import_picocolors3.default.cyan("ulw")}) in your prompt.
101208
101355
  ` + `All features work like magic-parallel agents, background tasks,
@@ -102498,7 +102645,7 @@ async function promptInstallConfig(detected, platform, codexAutonomousOverride)
102498
102645
  message: "Do you have a Kimi For Coding subscription?",
102499
102646
  options: [
102500
102647
  { value: "no", label: "No", hint: "Will use other configured providers" },
102501
- { value: "yes", label: "Yes", hint: "Kimi K3 for Sisyphus/Prometheus fallback" }
102648
+ { value: "yes", label: "Yes", hint: "Kimi K3.1 Pro for Sisyphus/Prometheus fallback" }
102502
102649
  ],
102503
102650
  initialValue: initial.kimiForCoding
102504
102651
  });
@@ -102757,8 +102904,8 @@ async function runTuiInstaller(args, version) {
102757
102904
  if (config.hasOpenCode) {
102758
102905
  log4.message(`Run ${import_picocolors4.default.cyan("opencode")} to start!`);
102759
102906
  }
102760
- log4.info("Anonymous telemetry is enabled by default. Disable it with OMO_SEND_ANONYMOUS_TELEMETRY=0 or OMO_DISABLE_POSTHOG=1.");
102761
- log4.info("Docs: docs/legal/privacy-policy.md and docs/legal/terms-of-service.md");
102907
+ log4.info(TELEMETRY_INSTALL_DISCLOSURE_LINES.join(`
102908
+ `));
102762
102909
  note(`Include ${import_picocolors4.default.cyan("ultrawork")} (or ${import_picocolors4.default.cyan("ulw")}) in your prompt.
102763
102910
  ` + `All features work like magic-parallel agents, background tasks,
102764
102911
  ` + `deep exploration, and relentless execution until completion.`, "The Magic Word");
@@ -103991,11 +104138,11 @@ function recordFields(value, fields) {
103991
104138
  }
103992
104139
  function modelInput(view) {
103993
104140
  const agents = isPlainRecord(view.agents) ? Object.fromEntries(Object.entries(view.agents).flatMap(([name, definition]) => {
103994
- const fields = recordFields(definition, ["description", "prompt", "model", "models", "variant", "reasoningEffort", "tools", "temperature", "disable"]);
104141
+ const fields = recordFields(definition, ["description", "prompt", "model", "models", "models_distribution", "variant", "reasoningEffort", "tools", "temperature", "disable"]);
103995
104142
  return fields === undefined ? [] : [[name, fields]];
103996
104143
  })) : undefined;
103997
104144
  const categories = isPlainRecord(view.categories) ? Object.fromEntries(Object.entries(view.categories).flatMap(([name, definition]) => {
103998
- const fields = recordFields(definition, ["description", "model", "fallback_models", "variant", "temperature", "top_p", "maxTokens", "thinking", "reasoningEffort", "textVerbosity", "tools", "prompt_append", "max_prompt_tokens", "is_unstable_agent", "disable"]);
104145
+ const fields = recordFields(definition, ["description", "model", "models", "models_distribution", "fallback_models", "variant", "temperature", "top_p", "maxTokens", "thinking", "reasoningEffort", "textVerbosity", "tools", "prompt_append", "max_prompt_tokens", "is_unstable_agent", "disable"]);
103999
104146
  return fields === undefined ? [] : [[name, fields]];
104000
104147
  })) : undefined;
104001
104148
  return {
@@ -104269,6 +104416,7 @@ var AgentPermissionSchema = object({
104269
104416
  var AgentOverrideConfigSchema = object({
104270
104417
  model: string2().optional(),
104271
104418
  models: array(union([string2(), FallbackModelObjectSchema])).optional(),
104419
+ models_distribution: _enum(["sequential", "round_robin"]).optional(),
104272
104420
  fallback_models: FallbackModelsSchema.optional(),
104273
104421
  reasoning: OmoReasoningSchema.optional(),
104274
104422
  variant: string2().optional(),
@@ -104369,6 +104517,7 @@ var CategoryConfigSchema = object({
104369
104517
  description: string2().optional(),
104370
104518
  model: string2().optional(),
104371
104519
  models: array(union([string2(), FallbackModelObjectSchema])).optional(),
104520
+ models_distribution: _enum(["sequential", "round_robin"]).optional(),
104372
104521
  fallback_models: FallbackModelsSchema.optional(),
104373
104522
  reasoning: OmoReasoningSchema.optional(),
104374
104523
  variant: string2().optional(),
@@ -104932,7 +105081,8 @@ function materializeAgentModelChains(config) {
104932
105081
  return [name, {
104933
105082
  ...rest,
104934
105083
  ...primarySettings,
104935
- fallback_models: fallbacks
105084
+ fallback_models: fallbacks,
105085
+ ...agent.models_distribution === "round_robin" ? { models: agent.models } : {}
104936
105086
  }];
104937
105087
  }));
104938
105088
  return changed ? { ...config, agents } : config;
@@ -109295,6 +109445,8 @@ var package_default3 = {
109295
109445
  },
109296
109446
  dependencies: {
109297
109447
  "@clack/prompts": "^1.8.1",
109448
+ "@code-yeongyu/senpi": "2026.10.30-1",
109449
+ "@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.10.30-1",
109298
109450
  "@modelcontextprotocol/sdk": "^1.30.0",
109299
109451
  "@oh-my-opencode/agents-md-core": "workspace:*",
109300
109452
  "@oh-my-opencode/boulder-state": "workspace:*",
@@ -110603,6 +110755,8 @@ function isOAuthTokenData(value) {
110603
110755
  if (typeof value !== "object" || value === null || Array.isArray(value))
110604
110756
  return false;
110605
110757
  const record = value;
110758
+ if (record["issuer"] !== undefined && typeof record["issuer"] !== "string")
110759
+ return false;
110606
110760
  if (typeof record["accessToken"] !== "string")
110607
110761
  return false;
110608
110762
  const refreshToken = record["refreshToken"];
@@ -110617,6 +110771,8 @@ function isOAuthTokenData(value) {
110617
110771
  if (typeof clientInfo !== "object" || clientInfo === null || Array.isArray(clientInfo))
110618
110772
  return false;
110619
110773
  const clientRecord = clientInfo;
110774
+ if (clientRecord["issuer"] !== undefined && typeof clientRecord["issuer"] !== "string")
110775
+ return false;
110620
110776
  if (typeof clientRecord["clientId"] !== "string")
110621
110777
  return false;
110622
110778
  const clientSecret = clientRecord["clientSecret"];
@@ -110685,7 +110841,9 @@ function deleteToken(serverHost, resource) {
110685
110841
  return deleteLegacyToken(serverHost, resource);
110686
110842
  try {
110687
110843
  unlinkSync9(filePath);
110688
- return deleteTokenIndexEntry(getMcpOauthStorageDir(), getMcpOauthServerHash(serverHost, resource));
110844
+ const indexDeleted = deleteTokenIndexEntry(getMcpOauthStorageDir(), getMcpOauthServerHash(serverHost, resource));
110845
+ const legacyDeleted = deleteLegacyToken(serverHost, resource);
110846
+ return indexDeleted && legacyDeleted;
110689
110847
  } catch (deleteError) {
110690
110848
  if (!(deleteError instanceof Error))
110691
110849
  throw deleteError;
@@ -110795,19 +110953,26 @@ async function fetchMetadata(url) {
110795
110953
  }
110796
110954
  return { ok: true, json };
110797
110955
  }
110798
- function parseMetadataFields(json, resource) {
110956
+ function parseMetadataFields(json, resource, expectedIssuer) {
110957
+ const issuer = readStringField(json, "issuer");
110958
+ parseHttpsUrl(issuer, "issuer");
110959
+ if (issuer !== expectedIssuer) {
110960
+ throw new Error("OAuth metadata issuer mismatch");
110961
+ }
110799
110962
  const authorizationEndpoint = parseHttpsUrl(readStringField(json, "authorization_endpoint"), "authorization_endpoint").toString();
110800
110963
  const tokenEndpoint = parseHttpsUrl(readStringField(json, "token_endpoint"), "token_endpoint").toString();
110801
110964
  const registrationEndpointValue = json.registration_endpoint;
110802
110965
  const registrationEndpoint = typeof registrationEndpointValue === "string" && registrationEndpointValue.length > 0 ? parseHttpsUrl(registrationEndpointValue, "registration_endpoint").toString() : undefined;
110803
110966
  return {
110967
+ issuer,
110968
+ ...json.authorization_response_iss_parameter_supported === true ? { authorizationResponseIssParameterSupported: true } : {},
110804
110969
  authorizationEndpoint,
110805
110970
  tokenEndpoint,
110806
110971
  registrationEndpoint,
110807
110972
  resource
110808
110973
  };
110809
110974
  }
110810
- async function fetchAuthorizationServerMetadata(issuer, resource) {
110975
+ async function fetchAuthorizationServerMetadata(issuer, resource, allowOriginFallback = false) {
110811
110976
  const issuerUrl = parseHttpsUrl(issuer, "Authorization server URL");
110812
110977
  const issuerPath = issuerUrl.pathname.replace(/\/+$/, "");
110813
110978
  const metadataUrl = new URL(`/.well-known/oauth-authorization-server${issuerPath}`, issuerUrl).toString();
@@ -110817,7 +110982,7 @@ async function fetchAuthorizationServerMetadata(issuer, resource) {
110817
110982
  const rootMetadataUrl = new URL("/.well-known/oauth-authorization-server", issuerUrl).toString();
110818
110983
  const rootMetadata = await fetchMetadata(rootMetadataUrl);
110819
110984
  if (rootMetadata.ok) {
110820
- return parseMetadataFields(rootMetadata.json, resource);
110985
+ return parseMetadataFields(rootMetadata.json, resource, allowOriginFallback ? issuerUrl.origin : issuer);
110821
110986
  }
110822
110987
  }
110823
110988
  if (metadata.status === 404) {
@@ -110825,7 +110990,7 @@ async function fetchAuthorizationServerMetadata(issuer, resource) {
110825
110990
  }
110826
110991
  throw new Error(`OAuth authorization server metadata fetch failed (${metadata.status})`);
110827
110992
  }
110828
- return parseMetadataFields(metadata.json, resource);
110993
+ return parseMetadataFields(metadata.json, resource, issuer);
110829
110994
  }
110830
110995
  function parseAuthorizationServers(metadata) {
110831
110996
  const servers = metadata.authorization_servers;
@@ -110833,11 +110998,11 @@ function parseAuthorizationServers(metadata) {
110833
110998
  return [];
110834
110999
  return servers.filter((server) => typeof server === "string" && server.length > 0);
110835
111000
  }
110836
- async function discoverOAuthServerMetadata(resource) {
111001
+ async function discoverOAuthServerMetadata(resource, forceRefresh = false) {
110837
111002
  const resourceUrl = parseHttpsUrl(resource, "Resource server URL");
110838
111003
  const resourceKey = resourceUrl.toString();
110839
111004
  const cached = discoveryCache.get(resourceKey);
110840
- if (cached)
111005
+ if (cached && !forceRefresh)
110841
111006
  return cached;
110842
111007
  const pending = pendingDiscovery.get(resourceKey);
110843
111008
  if (pending)
@@ -110855,7 +111020,7 @@ async function discoverOAuthServerMetadata(resource) {
110855
111020
  if (prmResponse.status !== 404) {
110856
111021
  throw new Error(`OAuth protected resource metadata fetch failed (${prmResponse.status})`);
110857
111022
  }
110858
- return fetchAuthorizationServerMetadata(resourceKey, resource);
111023
+ return fetchAuthorizationServerMetadata(resource.replace(/\/+$/, ""), resource, true);
110859
111024
  })();
110860
111025
  pendingDiscovery.set(resourceKey, discoveryPromise);
110861
111026
  try {
@@ -110879,6 +111044,10 @@ async function getOrRegisterClient(options) {
110879
111044
  }
110880
111045
  const fetchImpl = options.fetch ?? globalThis.fetch;
110881
111046
  const request = {
111047
+ application_type: options.redirectUris.some((uri) => {
111048
+ const url = new URL(uri);
111049
+ return (url.protocol === "http:" || url.protocol === "https:") && !["127.0.0.1", "localhost", "[::1]"].includes(url.hostname);
111050
+ }) ? "web" : "native",
110882
111051
  redirect_uris: options.redirectUris,
110883
111052
  client_name: options.clientName,
110884
111053
  grant_types: ["authorization_code", "refresh_token"],
@@ -110955,12 +111124,20 @@ function buildAuthorizationUrl(authorizationEndpoint, options) {
110955
111124
  return url.toString();
110956
111125
  }
110957
111126
  var CALLBACK_TIMEOUT_MS = 5 * 60 * 1000;
110958
- function startCallbackServer(port) {
111127
+ function startCallbackServer(port, validation) {
110959
111128
  return new Promise((resolve, reject) => {
110960
111129
  let timeoutId;
110961
111130
  const server = createServer2((request, response) => {
110962
111131
  clearTimeout(timeoutId);
110963
111132
  const requestUrl = new URL(request.url ?? "/", `http://localhost:${port}`);
111133
+ const issuer = requestUrl.searchParams.get("iss");
111134
+ if (validation && (issuer !== null && issuer !== validation.issuer || issuer === null && validation.authorizationResponseIssParameterSupported)) {
111135
+ response.writeHead(400, { "content-type": "text/html" });
111136
+ response.end("<html><body><h1>Authorization failed</h1></body></html>");
111137
+ server.close();
111138
+ reject(new Error("OAuth authorization response issuer mismatch or missing issuer"));
111139
+ return;
111140
+ }
110964
111141
  const code = requestUrl.searchParams.get("code");
110965
111142
  const state = requestUrl.searchParams.get("state");
110966
111143
  const error = requestUrl.searchParams.get("error");
@@ -111030,7 +111207,7 @@ async function runAuthorizationCodeRedirect(options) {
111030
111207
  scopes: options.scopes,
111031
111208
  resource: options.resource
111032
111209
  });
111033
- const callbackPromise = startCallbackServer(options.callbackPort);
111210
+ const callbackPromise = startCallbackServer(options.callbackPort, options);
111034
111211
  openBrowser(authorizationUrl);
111035
111212
  const result = await callbackPromise;
111036
111213
  if (result.state !== state) {
@@ -111065,10 +111242,12 @@ function buildOAuthTokenData(tokenData, clientInfo, fallbackRefreshToken) {
111065
111242
  throw new Error("Token response missing access_token");
111066
111243
  }
111067
111244
  return {
111245
+ ...clientInfo.issuer ? { issuer: clientInfo.issuer } : {},
111068
111246
  accessToken,
111069
111247
  refreshToken: typeof tokenData["refresh_token"] === "string" ? tokenData["refresh_token"] : fallbackRefreshToken,
111070
111248
  expiresAt: typeof tokenData["expires_in"] === "number" ? Math.floor(Date.now() / 1000) + tokenData["expires_in"] : undefined,
111071
111249
  clientInfo: {
111250
+ ...clientInfo.issuer ? { issuer: clientInfo.issuer } : {},
111072
111251
  clientId: clientInfo.clientId,
111073
111252
  ...clientInfo.clientSecret ? { clientSecret: clientInfo.clientSecret } : {}
111074
111253
  }
@@ -111082,6 +111261,7 @@ class McpOAuthProvider {
111082
111261
  storedCodeVerifier = null;
111083
111262
  storedClientInfo = null;
111084
111263
  callbackPort = null;
111264
+ issuer;
111085
111265
  constructor(options) {
111086
111266
  this.serverUrl = options.serverUrl;
111087
111267
  this.configClientId = options.clientId;
@@ -111091,7 +111271,32 @@ class McpOAuthProvider {
111091
111271
  return loadToken(this.serverUrl, this.serverUrl);
111092
111272
  }
111093
111273
  saveTokens(tokenData) {
111094
- return saveToken(this.serverUrl, this.serverUrl, tokenData);
111274
+ const issuer = tokenData.issuer ?? this.issuer;
111275
+ return saveToken(this.serverUrl, this.serverUrl, issuer ? {
111276
+ ...tokenData,
111277
+ issuer,
111278
+ ...tokenData.clientInfo ? { clientInfo: { ...tokenData.clientInfo, issuer: tokenData.clientInfo.issuer ?? issuer } } : {}
111279
+ } : tokenData);
111280
+ }
111281
+ bindIssuer(issuer) {
111282
+ const token = this.tokens();
111283
+ const stamps = [token?.issuer, token?.clientInfo?.issuer, this.storedClientInfo?.issuer, this.issuer];
111284
+ const changed = stamps.some((stamp) => stamp !== undefined && stamp !== issuer);
111285
+ if (changed) {
111286
+ this.storedClientInfo = null;
111287
+ this.storedCodeVerifier = null;
111288
+ if (!deleteToken(this.serverUrl, this.serverUrl)) {
111289
+ throw new Error("Unable to discard credentials for the previous OAuth issuer");
111290
+ }
111291
+ }
111292
+ this.issuer = issuer;
111293
+ if (!changed && token && !this.saveTokens(token)) {
111294
+ throw new Error("Unable to stamp stored OAuth credentials with their issuer");
111295
+ }
111296
+ const clientInfo = this.clientInformation();
111297
+ if (clientInfo)
111298
+ this.storedClientInfo = { ...clientInfo, issuer };
111299
+ return changed;
111095
111300
  }
111096
111301
  clientInformation() {
111097
111302
  if (this.storedClientInfo)
@@ -111121,6 +111326,8 @@ class McpOAuthProvider {
111121
111326
  this.callbackPort = await findAvailablePort2();
111122
111327
  }
111123
111328
  const result = await runAuthorizationCodeRedirect({
111329
+ issuer: metadata.issuer,
111330
+ authorizationResponseIssParameterSupported: metadata.authorizationResponseIssParameterSupported,
111124
111331
  authorizationEndpoint: metadata.authorizationEndpoint,
111125
111332
  callbackPort: this.callbackPort,
111126
111333
  clientId: clientInfo.clientId,
@@ -111132,16 +111339,19 @@ class McpOAuthProvider {
111132
111339
  return { code: result.code };
111133
111340
  }
111134
111341
  async login() {
111135
- const metadata = await discoverOAuthServerMetadata(this.serverUrl);
111342
+ const metadata = await discoverOAuthServerMetadata(this.serverUrl, true);
111343
+ this.bindIssuer(metadata.issuer);
111344
+ if (this.callbackPort === null)
111345
+ this.callbackPort = await findAvailablePort2();
111136
111346
  const clientRegistrationStorage = {
111137
111347
  getClientRegistration: () => this.storedClientInfo,
111138
111348
  setClientRegistration: (_serverIdentifier, credentials) => {
111139
- this.storedClientInfo = credentials;
111349
+ this.storedClientInfo = { ...credentials, issuer: metadata.issuer };
111140
111350
  }
111141
111351
  };
111142
111352
  const clientInfo = await getOrRegisterClient({
111143
111353
  ...metadata.registrationEndpoint ? { registrationEndpoint: metadata.registrationEndpoint } : {},
111144
- serverIdentifier: this.serverUrl,
111354
+ serverIdentifier: metadata.issuer,
111145
111355
  clientName: PLUGIN_NAME4,
111146
111356
  redirectUris: [this.redirectUrl()],
111147
111357
  tokenEndpointAuthMethod: "none",
@@ -111151,7 +111361,7 @@ class McpOAuthProvider {
111151
111361
  if (!clientInfo) {
111152
111362
  throw new Error("Failed to obtain client credentials. Provide a clientId or ensure the server supports DCR.");
111153
111363
  }
111154
- this.storedClientInfo = clientInfo;
111364
+ this.storedClientInfo = { ...clientInfo, issuer: metadata.issuer };
111155
111365
  const { code } = await this.redirectToAuthorization(metadata);
111156
111366
  const verifier = this.codeVerifier();
111157
111367
  if (!verifier) {
@@ -111170,12 +111380,14 @@ class McpOAuthProvider {
111170
111380
  }).toString()
111171
111381
  });
111172
111382
  const tokenData = await parseTokenResponse(tokenResponse);
111173
- const oauthTokenData = buildOAuthTokenData(tokenData, clientInfo);
111383
+ const oauthTokenData = buildOAuthTokenData(tokenData, { ...clientInfo, issuer: metadata.issuer });
111174
111384
  this.saveTokens(oauthTokenData);
111175
111385
  return oauthTokenData;
111176
111386
  }
111177
111387
  async refresh(refreshToken) {
111178
- const metadata = await discoverOAuthServerMetadata(this.serverUrl);
111388
+ const metadata = await discoverOAuthServerMetadata(this.serverUrl, true);
111389
+ if (this.bindIssuer(metadata.issuer))
111390
+ return this.login();
111179
111391
  const clientInfo = this.clientInformation();
111180
111392
  const clientId = clientInfo?.clientId ?? this.configClientId;
111181
111393
  if (!clientId) {
@@ -111195,6 +111407,7 @@ class McpOAuthProvider {
111195
111407
  const tokenData = await parseTokenResponse(tokenResponse);
111196
111408
  const oauthTokenData = buildOAuthTokenData(tokenData, {
111197
111409
  clientId,
111410
+ issuer: metadata.issuer,
111198
111411
  ...clientInfo?.clientSecret ? { clientSecret: clientInfo.clientSecret } : {}
111199
111412
  }, refreshToken);
111200
111413
  this.saveTokens(oauthTokenData);
@@ -112042,6 +112255,17 @@ import { hostname } from "os";
112042
112255
  // packages/omo-opencode/src/cli/service-auth/protocol.ts
112043
112256
  init_zod();
112044
112257
 
112258
+ // packages/omo-opencode/src/cli/service-auth/credential-owner.ts
112259
+ init_zod();
112260
+ var identity = string2().regex(/^[A-Za-z0-9_-]{1,128}$/);
112261
+ var credentialOwnerSchema = object({
112262
+ accountId: identity,
112263
+ deviceId: identity,
112264
+ familyId: identity,
112265
+ generation: number2().int().positive().safe(),
112266
+ ownerHandle: string2().regex(/^[\x21-\x7e]{1,4096}$/)
112267
+ });
112268
+
112045
112269
  // packages/omo-opencode/src/cli/service-auth/terminal-text.ts
112046
112270
  import { stripVTControlCharacters as stripVTControlCharacters4 } from "util";
112047
112271
  function terminalText(value) {
@@ -112060,9 +112284,19 @@ class SignInError extends Error {
112060
112284
 
112061
112285
  class RequestFailure extends SignInError {
112062
112286
  notSent;
112063
- constructor(notSent) {
112287
+ responseStatus;
112288
+ constructor(notSent, responseStatus) {
112064
112289
  super("Unable to complete the service request. Check the connection and retry.", true);
112065
112290
  this.notSent = notSent;
112291
+ this.responseStatus = responseStatus;
112292
+ }
112293
+ }
112294
+
112295
+ class InvalidApiResponse extends SignInError {
112296
+ status;
112297
+ constructor(status) {
112298
+ super("The service returned an invalid error response.");
112299
+ this.status = status;
112066
112300
  }
112067
112301
  }
112068
112302
  var platformSchema = _enum(["macos", "linux", "windows"]);
@@ -112075,12 +112309,18 @@ var tokenSchema = object({
112075
112309
  });
112076
112310
  var grantSchema = tokenSchema.extend({
112077
112311
  device: object({ id: nonempty, name: nonempty }),
112078
- offlineGrant: nonempty.optional()
112312
+ offlineGrant: nonempty.optional(),
112313
+ owner: credentialOwnerSchema.optional(),
112314
+ writerFloor: union([literal(1), literal(2)]).optional(),
112315
+ freshAuthorizationProof: nonempty.optional()
112079
112316
  });
112080
112317
  var credentialSchema = grantSchema.extend({
112081
112318
  signingPrivateKey: nonempty,
112082
112319
  sealingPrivateKey: nonempty,
112083
- refreshState: literal("uncertain").optional()
112320
+ refreshState: literal("uncertain").optional(),
112321
+ credentialGeneration: nonempty.optional(),
112322
+ accountId: nonempty.optional(),
112323
+ refreshAttempt: unknown().optional()
112084
112324
  });
112085
112325
  var deviceCodeSchema = object({
112086
112326
  deviceCode: string2().regex(/^dc\.[A-Za-z0-9_-]{43}$/),
@@ -112108,6 +112348,9 @@ var limitSchema = object({
112108
112348
  var deviceListSchema = object({
112109
112349
  devices: array(object({ id: nonempty, name: nonempty, revokedAt: timestamp.nullable() }))
112110
112350
  });
112351
+ var currentDeviceListSchema = object({
112352
+ devices: array(object({ id: nonempty, current: boolean2(), revokedAt: timestamp.nullable() }))
112353
+ });
112111
112354
  var REFUSAL_CODES = [
112112
112355
  "unauthorized",
112113
112356
  "account_deleted",
@@ -112124,7 +112367,11 @@ var REFUSAL_CODES = [
112124
112367
  "unavailable",
112125
112368
  "forbidden",
112126
112369
  "invalid_request",
112127
- "not_found"
112370
+ "not_found",
112371
+ "client_upgrade_required",
112372
+ "writer_floor_mismatch",
112373
+ "service_upgrade_required",
112374
+ "refresh_recovery_expired"
112128
112375
  ];
112129
112376
  var isKnownRefusal = (code) => REFUSAL_CODES.includes(code);
112130
112377
  function refusalGuidance(code, status) {
@@ -112151,6 +112398,10 @@ function refusalGuidance(code, status) {
112151
112398
  case "access_denied":
112152
112399
  case "authorization_pending":
112153
112400
  return "account_refused";
112401
+ case "client_upgrade_required":
112402
+ case "writer_floor_mismatch":
112403
+ case "service_upgrade_required":
112404
+ case "refresh_recovery_expired":
112154
112405
  case "unknown":
112155
112406
  if (status === 401)
112156
112407
  return "sign_in_again";
@@ -112261,13 +112512,13 @@ async function requestApi(api, path, init, signal) {
112261
112512
  try {
112262
112513
  body = await response.json();
112263
112514
  } catch {
112264
- throw new RequestFailure(false);
112515
+ throw new RequestFailure(false, response.status);
112265
112516
  }
112266
112517
  if (response.ok)
112267
112518
  return body;
112268
112519
  const envelope = envelopeSchema.safeParse(body);
112269
112520
  if (!envelope.success)
112270
- throw new SignInError("The service returned an invalid error response.");
112521
+ throw new InvalidApiResponse(response.status);
112271
112522
  const error = envelope.data.error;
112272
112523
  const detail = limitSchema.safeParse(error.detail);
112273
112524
  throw new ApiRefusal(error.code, response.status, error.code === "entitlement_required" && detail.success ? detail.data : undefined, response.headers.get("retry-after"));
@@ -112371,7 +112622,7 @@ async function loginDevice(session, options) {
112371
112622
  }
112372
112623
 
112373
112624
  // packages/omo-opencode/src/cli/service-auth/keystore.ts
112374
- import { createHash as createHash10 } from "crypto";
112625
+ import { createHash as createHash12, randomUUID as randomUUID7 } from "crypto";
112375
112626
  import { basename as basename15 } from "path";
112376
112627
 
112377
112628
  // packages/omo-opencode/src/cli/service-auth/secret-service-lock.ts
@@ -112415,289 +112666,490 @@ var probeSecretServiceLock = () => new Promise((resolve) => {
112415
112666
  });
112416
112667
  });
112417
112668
 
112418
- // packages/omo-opencode/src/cli/service-auth/keystore.ts
112419
- class CredentialStoreError extends SignInError {
112420
- }
112669
+ // packages/omo-opencode/src/cli/service-auth/credential-lock.ts
112670
+ import { AsyncLocalStorage as AsyncLocalStorage3 } from "async_hooks";
112671
+ import { createHash as createHash11 } from "crypto";
112672
+ import { mkdir as mkdir11 } from "fs/promises";
112673
+ import { homedir as homedir31 } from "os";
112674
+ import { join as join106 } from "path";
112421
112675
 
112422
- class KeychainLockedError extends CredentialStoreError {
112676
+ // packages/team-core/src/team-state-store/lock-publish.ts
112677
+ import { access as access4, open as open3, unlink as unlink3 } from "fs/promises";
112678
+ import { dirname as dirname42 } from "path";
112679
+
112680
+ // packages/team-core/src/team-state-store/lock-record.ts
112681
+ import { randomUUID as randomUUID6 } from "crypto";
112682
+ import { readFile as readFile34, stat as stat9 } from "fs/promises";
112683
+
112684
+ // packages/memory-core/src/locks/process-identity.ts
112685
+ import { execFile as execFile7 } from "child_process";
112686
+
112687
+ // packages/memory-core/src/fs/resilient.ts
112688
+ import * as fsSync from "fs";
112689
+ import * as fsp from "fs/promises";
112690
+
112691
+ // packages/memory-core/src/fs/retry.ts
112692
+ var EINTR_RETRY_CAP = 128;
112693
+ function fsErrorCode(error) {
112694
+ if (!(error instanceof Error) || !("code" in error))
112695
+ return;
112696
+ return typeof error.code === "string" ? error.code : undefined;
112423
112697
  }
112424
- class InvalidCredentialState extends SignInError {
112698
+ async function retryOnEintr(operation) {
112699
+ for (let attempt = 0;; attempt += 1) {
112700
+ try {
112701
+ return await operation();
112702
+ } catch (error) {
112703
+ if (fsErrorCode(error) !== "EINTR" || attempt >= EINTR_RETRY_CAP)
112704
+ throw error;
112705
+ }
112706
+ }
112707
+ }
112708
+ function retryOnEintrSync(operation) {
112709
+ for (let attempt = 0;; attempt += 1) {
112710
+ try {
112711
+ return operation();
112712
+ } catch (error) {
112713
+ if (fsErrorCode(error) !== "EINTR" || attempt >= EINTR_RETRY_CAP)
112714
+ throw error;
112715
+ }
112716
+ }
112425
112717
  }
112426
112718
 
112427
- class KeychainApprovalPendingError extends CredentialStoreError {
112719
+ // packages/memory-core/src/fs/rename-contention.ts
112720
+ var CONTENTION_CODES = new Set(["EPERM", "EBUSY", "EACCES"]);
112721
+
112722
+ // packages/memory-core/src/fs/resilient.ts
112723
+ function isFunction2(value) {
112724
+ return typeof value === "function";
112428
112725
  }
112429
- var SESSION_READ_WAIT = { kind: "bounded", deadlineMs: 5000 };
112430
- var INTERACTIVE_READ_WAIT = {
112431
- kind: "interactive",
112432
- noticeAfterMs: 2000,
112433
- notice: (message) => process.stderr.write(`${message}
112434
- `)
112435
- };
112436
- var processReads = new WeakMap;
112437
- var LOCKED = /-25308|errSecInteractionNotAllowed|interaction is not allowed|locked collection/i;
112438
- var UNLOCKED_REUSE_MS = 30000;
112439
- var fallbackNoticed = false;
112440
- var stderrNoticeOncePerProcess = (message) => {
112441
- if (fallbackNoticed)
112726
+ function withAsyncRetry(operation) {
112727
+ return (...args) => retryOnEintr(async () => operation(...args));
112728
+ }
112729
+ function withSyncRetry(operation) {
112730
+ return (...args) => retryOnEintrSync(() => operation(...args));
112731
+ }
112732
+ function resilientNamespace(namespace, kind) {
112733
+ const wrapFunction = kind === "async" ? withAsyncRetry : withSyncRetry;
112734
+ const cache = new Map;
112735
+ return new Proxy(namespace, {
112736
+ get(target, property) {
112737
+ if (cache.has(property))
112738
+ return cache.get(property);
112739
+ const value = Reflect.get(target, property);
112740
+ if (!isFunction2(value))
112741
+ return value;
112742
+ const wrapped = wrapFunction(value);
112743
+ const native = Reflect.get(value, "native");
112744
+ if (isFunction2(native))
112745
+ Object.assign(wrapped, { native: wrapFunction(native) });
112746
+ cache.set(property, wrapped);
112747
+ return wrapped;
112748
+ }
112749
+ });
112750
+ }
112751
+ var IDEMPOTENT_HANDLE_METHODS = new Set(["stat", "sync", "datasync", "chmod", "chown", "utimes", "truncate"]);
112752
+ var promises = resilientNamespace(fsp, "async");
112753
+ var sync = resilientNamespace(fsSync, "sync");
112754
+ var {
112755
+ access: access3,
112756
+ chmod: chmod2,
112757
+ copyFile: copyFile4,
112758
+ cp: cp5,
112759
+ link,
112760
+ lstat: lstat18,
112761
+ mkdir: mkdir10,
112762
+ mkdtemp: mkdtemp2,
112763
+ readFile: readFile33,
112764
+ readdir: readdir17,
112765
+ readlink: readlink7,
112766
+ realpath: realpath2,
112767
+ rm: rm16,
112768
+ rmdir: rmdir2,
112769
+ stat: stat8,
112770
+ statfs,
112771
+ unlink: unlink2
112772
+ } = promises;
112773
+ var {
112774
+ accessSync: accessSync5,
112775
+ chmodSync: chmodSync7,
112776
+ fsyncSync: fsyncSync3,
112777
+ linkSync,
112778
+ lstatSync: lstatSync5,
112779
+ mkdirSync: mkdirSync19,
112780
+ readFileSync: readFileSync44,
112781
+ readdirSync: readdirSync14,
112782
+ realpathSync: realpathSync13,
112783
+ statSync: statSync8,
112784
+ unlinkSync: unlinkSync10,
112785
+ writeFileSync: writeFileSync17,
112786
+ writeSync
112787
+ } = sync;
112788
+
112789
+ // packages/memory-core/src/locks/process-start-time.ts
112790
+ var PROC_PIDTBSDINFO = 3;
112791
+ var PROC_BSDINFO_SIZE = 136;
112792
+ var START_TVSEC_OFFSET = 120;
112793
+ var procPidInfoLookup = null;
112794
+ async function openProcPidInfo() {
112795
+ if (process.platform !== "darwin")
112796
+ return null;
112797
+ try {
112798
+ const { dlopen, FFIType } = await import("bun:ffi");
112799
+ const library = dlopen("/usr/lib/libSystem.B.dylib", {
112800
+ proc_pidinfo: {
112801
+ args: [FFIType.i32, FFIType.i32, FFIType.u64, FFIType.ptr, FFIType.i32],
112802
+ returns: FFIType.i32
112803
+ }
112804
+ });
112805
+ return (pid, flavor, arg, buffer, size) => Number(library.symbols.proc_pidinfo(pid, flavor, arg, buffer, size));
112806
+ } catch {
112807
+ return null;
112808
+ }
112809
+ }
112810
+ function loadProcPidInfo() {
112811
+ procPidInfoLookup ??= openProcPidInfo();
112812
+ return procPidInfoLookup;
112813
+ }
112814
+ async function readDarwinProcessStartSeconds(pid) {
112815
+ if (process.platform !== "darwin")
112816
+ return null;
112817
+ if (!Number.isSafeInteger(pid) || pid <= 0)
112818
+ return null;
112819
+ const procPidInfo = await loadProcPidInfo();
112820
+ if (procPidInfo === null)
112821
+ return null;
112822
+ const buffer = new Uint8Array(PROC_BSDINFO_SIZE);
112823
+ let written = 0;
112824
+ try {
112825
+ written = procPidInfo(pid, PROC_PIDTBSDINFO, 0n, buffer, PROC_BSDINFO_SIZE);
112826
+ } catch {
112827
+ return null;
112828
+ }
112829
+ if (written !== PROC_BSDINFO_SIZE)
112830
+ return null;
112831
+ const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
112832
+ const startSeconds = Number(view.getBigUint64(START_TVSEC_OFFSET, true));
112833
+ return startSeconds > 0 ? startSeconds : null;
112834
+ }
112835
+ var PROCESS_QUERY_LIMITED_INFORMATION = 4096;
112836
+ var kernel32Lookup = null;
112837
+ async function openKernel32() {
112838
+ if (process.platform !== "win32")
112839
+ return null;
112840
+ try {
112841
+ const { dlopen, FFIType } = await import("bun:ffi");
112842
+ const library = dlopen("kernel32.dll", {
112843
+ OpenProcess: { args: [FFIType.u32, FFIType.i32, FFIType.u32], returns: FFIType.ptr },
112844
+ GetProcessTimes: { args: [FFIType.ptr, FFIType.ptr, FFIType.ptr, FFIType.ptr, FFIType.ptr], returns: FFIType.i32 },
112845
+ CloseHandle: { args: [FFIType.ptr], returns: FFIType.i32 }
112846
+ });
112847
+ return library.symbols;
112848
+ } catch {
112849
+ return null;
112850
+ }
112851
+ }
112852
+ async function readWin32ProcessCreationFiletime(pid) {
112853
+ if (process.platform !== "win32")
112854
+ return null;
112855
+ if (!Number.isSafeInteger(pid) || pid <= 0)
112856
+ return null;
112857
+ kernel32Lookup ??= openKernel32();
112858
+ const kernel32 = await kernel32Lookup;
112859
+ if (kernel32 === null)
112860
+ return null;
112861
+ const handle = kernel32.OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, 0, pid);
112862
+ if (handle === null || handle === 0 || handle === 0n)
112863
+ return null;
112864
+ try {
112865
+ const creation = new BigUint64Array(1);
112866
+ const ok = kernel32.GetProcessTimes(handle, creation, new BigUint64Array(1), new BigUint64Array(1), new BigUint64Array(1));
112867
+ const filetime = creation[0] ?? 0n;
112868
+ return ok === 0 || filetime === 0n ? null : filetime;
112869
+ } finally {
112870
+ kernel32.CloseHandle(handle);
112871
+ }
112872
+ }
112873
+
112874
+ // packages/memory-core/src/locks/process-identity.ts
112875
+ function errorCode(error) {
112876
+ if (!(error instanceof Error) || !("code" in error))
112442
112877
  return;
112443
- fallbackNoticed = true;
112444
- process.stderr.write(`${message}
112445
- `);
112446
- };
112447
- var isLocked = (error) => error instanceof Error && (LOCKED.test(error.message) || LOCKED.test(String(error.code ?? "")));
112448
- function credentialId(api) {
112449
- return createHash10("sha256").update(serviceOrigin(api)).digest("hex");
112878
+ return typeof error.code === "string" ? error.code : undefined;
112450
112879
  }
112451
- function createCredentialStore(api, options = {}) {
112452
- return createSealedStore(api, "omo-cli", credentialSchema, options.secrets, options.platform, options.lockProbe, options.notice, options.wait);
112880
+ async function execFileText(command, args) {
112881
+ return await new Promise((resolve) => {
112882
+ execFile7(command, args, { encoding: "utf8", timeout: 2000, windowsHide: true }, (error, stdout) => {
112883
+ if (error !== null) {
112884
+ resolve(null);
112885
+ return;
112886
+ }
112887
+ const value = stdout.trim();
112888
+ resolve(value.length > 0 ? value : null);
112889
+ });
112890
+ });
112453
112891
  }
112454
- function createSealedStore(api, namespace, schema, secrets = typeof Bun === "undefined" ? null : Bun.secrets, platform = process.platform, lockProbe = probeSecretServiceLock, notice = stderrNoticeOncePerProcess, wait = SESSION_READ_WAIT) {
112455
- if (!secrets)
112456
- throw new SignInError("OmO sign-in needs Bun 1.4 or newer with OS credential storage. No file fallback is available.");
112457
- const platformName = platform === "darwin" ? "macOS Keychain" : platform === "linux" ? "Linux Secret Service (libsecret and an unlocked keyring)" : platform === "win32" ? "Windows Credential Manager" : null;
112458
- if (platformName === null)
112459
- throw new SignInError("This platform has no supported OS credential store.");
112460
- const key = { service: namespace, name: credentialId(api) };
112461
- const slot = `${key.service}
112462
- ${key.name}`;
112463
- const readsOf = (api) => {
112464
- const known = processReads.get(api);
112465
- if (known !== undefined)
112466
- return known;
112467
- const created = new Map;
112468
- processReads.set(api, created);
112469
- return created;
112470
- };
112471
- const forget = (api) => {
112472
- readsOf(api).delete(slot);
112473
- };
112474
- const sharedRead = (api) => {
112475
- const reads = readsOf(api);
112476
- const pending = reads.get(slot);
112477
- if (pending !== undefined)
112478
- return pending;
112479
- const read = Promise.resolve().then(() => api.get(key));
112480
- const done = () => {
112481
- if (reads.get(slot) === read)
112482
- reads.delete(slot);
112483
- };
112484
- read.then(done, done);
112485
- reads.set(slot, read);
112486
- return read;
112892
+ async function readLinuxStartIdentity(pid) {
112893
+ try {
112894
+ const stat = await readFile33(`/proc/${pid}/stat`, "utf8");
112895
+ const commandEnd = stat.lastIndexOf(")");
112896
+ if (commandEnd < 0)
112897
+ return null;
112898
+ const fieldsAfterCommand = stat.slice(commandEnd + 2).trim().split(/\s+/);
112899
+ const startTicks = fieldsAfterCommand[19];
112900
+ return startTicks === undefined ? null : `linux-proc-start-ticks:${startTicks}`;
112901
+ } catch {
112902
+ return null;
112903
+ }
112904
+ }
112905
+ async function readWin32StartIdentity(pid) {
112906
+ if (getPidLiveness(pid) === "dead")
112907
+ return null;
112908
+ const creationFiletime = await readWin32ProcessCreationFiletime(pid);
112909
+ if (creationFiletime !== null)
112910
+ return `win32-creation-filetime:${creationFiletime}`;
112911
+ const value = await execFileText("powershell.exe", [
112912
+ "-NoProfile",
112913
+ "-Command",
112914
+ `(Get-Process -Id ${pid} -ErrorAction SilentlyContinue).StartTime.ToUniversalTime().ToString('o')`
112915
+ ]);
112916
+ return value === null ? null : `win32-creation-date:${value}`;
112917
+ }
112918
+ function createProcessStartIdentityReader(read, ownPid) {
112919
+ let ownIdentity;
112920
+ return (pid) => {
112921
+ if (pid !== ownPid)
112922
+ return read(pid);
112923
+ ownIdentity ??= read(pid).then((identity) => {
112924
+ if (identity === null)
112925
+ ownIdentity = undefined;
112926
+ return identity;
112927
+ }, (error) => {
112928
+ ownIdentity = undefined;
112929
+ throw error;
112930
+ });
112931
+ return ownIdentity;
112487
112932
  };
112488
- 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`;
112489
- const answered = async (api) => {
112490
- const read = sharedRead(api);
112491
- let timer;
112492
- try {
112493
- if (wait.kind === "interactive") {
112494
- timer = setTimeout(() => wait.notice(`omo: ${waiting}.`), wait.noticeAfterMs);
112495
- return await read;
112496
- }
112497
- const expired = new Promise((_, reject) => {
112498
- timer = setTimeout(() => reject(new KeychainApprovalPendingError(`${waiting}, then try again. Credentials are never saved to a file.`)), wait.deadlineMs);
112499
- });
112500
- return await Promise.race([read, expired]);
112501
- } finally {
112502
- clearTimeout(timer);
112503
- }
112933
+ }
112934
+ var getProcessStartIdentity = createProcessStartIdentityReader(readProcessStartIdentity, process.pid);
112935
+ async function readProcessStartIdentity(pid) {
112936
+ if (process.platform === "linux")
112937
+ return await readLinuxStartIdentity(pid);
112938
+ if (process.platform === "darwin" || process.platform === "freebsd") {
112939
+ if (getPidLiveness(pid) === "dead")
112940
+ return null;
112941
+ const startSeconds = await readDarwinProcessStartSeconds(pid);
112942
+ if (startSeconds !== null)
112943
+ return `proc-start-epoch:${startSeconds}`;
112944
+ const value = await execFileText("/bin/ps", ["-o", "lstart=", "-p", String(pid)]);
112945
+ return value === null ? null : `ps-lstart:${value.replace(/\s+/g, " ")}`;
112946
+ }
112947
+ if (process.platform === "win32")
112948
+ return await readWin32StartIdentity(pid);
112949
+ return null;
112950
+ }
112951
+ function identityScheme(identity) {
112952
+ const separator = identity.indexOf(":");
112953
+ return separator <= 0 ? null : identity.slice(0, separator);
112954
+ }
112955
+ function startIdentitiesConflict(recorded, actual) {
112956
+ const recordedScheme = identityScheme(recorded);
112957
+ if (recordedScheme === null || recordedScheme !== identityScheme(actual))
112958
+ return false;
112959
+ return recorded !== actual;
112960
+ }
112961
+ function getPidLiveness(pid) {
112962
+ try {
112963
+ process.kill(pid, 0);
112964
+ return "alive";
112965
+ } catch (error) {
112966
+ const code = errorCode(error);
112967
+ if (code === "ESRCH")
112968
+ return "dead";
112969
+ if (code === "EPERM")
112970
+ return "alive";
112971
+ return "unknown";
112972
+ }
112973
+ }
112974
+
112975
+ // packages/team-core/src/team-state-store/lock-worker-lifetime.ts
112976
+ init_zod();
112977
+ import { randomUUID as randomUUID5 } from "crypto";
112978
+ import { BroadcastChannel, parentPort, threadId } from "worker_threads";
112979
+ var Registration = object({
112980
+ kind: literal("omo-team-lock-register-v1"),
112981
+ incarnation: string2(),
112982
+ challenge: string2()
112983
+ });
112984
+ var Message = discriminatedUnion("kind", [
112985
+ object({ kind: literal("query"), id: string2(), incarnation: string2(), record: string2() }),
112986
+ object({ kind: literal("answer"), id: string2(), released: boolean2() }),
112987
+ object({ kind: literal("hello"), threadId: number2() }),
112988
+ object({ kind: literal("register"), threadId: number2(), challenge: string2() })
112989
+ ]);
112990
+ function createState() {
112991
+ const channel = new BroadcastChannel(`omo-team-lock-lifetime-v1-${process.pid}`);
112992
+ channel.unref();
112993
+ const state = {
112994
+ incarnation: randomUUID5(),
112995
+ records: new Map,
112996
+ exited: new Set,
112997
+ observed: new WeakSet,
112998
+ observing: new Map,
112999
+ pending: new Map,
113000
+ channel,
113001
+ installed: false,
113002
+ registered: parentPort === null,
113003
+ registration: undefined,
113004
+ onRegistered: undefined
112504
113005
  };
112505
- const unavailable = (error) => isLocked(error) ? new KeychainLockedError(`${platformName} is locked. Unlock it, then try again. Credentials are never saved to a file.`) : new CredentialStoreError(`Cannot access ${platformName}. Unlock or enable the OS credential store and try again. Credentials are never saved to a file.`);
112506
- let unlockedUntil = 0;
112507
- let noticed = false;
112508
- const assertUsable = async () => {
112509
- if (platform !== "linux" || Date.now() < unlockedUntil)
112510
- return;
112511
- const lock = await lockProbe();
112512
- if (lock === "locked")
112513
- throw new KeychainLockedError(`${platformName} is locked. Unlock it, then try again. Credentials are never saved to a file.`);
112514
- if (lock === "unlocked") {
112515
- unlockedUntil = Date.now() + UNLOCKED_REUSE_MS;
113006
+ channel.onmessage = (event) => {
113007
+ const parsed = Message.safeParse(event.data);
113008
+ if (!parsed.success)
112516
113009
  return;
112517
- }
112518
- if (!noticed) {
112519
- noticed = true;
112520
- notice("omo: could not check whether the keyring is locked (gdbus or the Secret Service did not answer); using libsecret directly.");
112521
- }
112522
- };
112523
- return {
112524
- async read() {
112525
- await assertUsable();
112526
- let value;
112527
- try {
112528
- value = await answered(secrets);
112529
- } catch (error) {
112530
- if (error instanceof KeychainApprovalPendingError)
112531
- throw error;
112532
- throw unavailable(error);
112533
- }
112534
- if (value === null)
112535
- return null;
112536
- try {
112537
- return schema.parse(JSON.parse(value));
112538
- } catch {
112539
- throw new InvalidCredentialState(signInRoute() === "cli" ? "Stored sign-in data is invalid. Run omo logout, then omo login." : "The OmO sign-in saved on this computer can't be read, and it can't be reset from the terminal yet.");
113010
+ const message = parsed.data;
113011
+ switch (message.kind) {
113012
+ case "hello": {
113013
+ const observed = state.observing.get(message.threadId);
113014
+ if (observed !== undefined) {
113015
+ channel.postMessage({ kind: "register", threadId: message.threadId, challenge: observed.challenge });
113016
+ }
113017
+ return;
112540
113018
  }
112541
- },
112542
- async write(value) {
112543
- await assertUsable();
112544
- try {
112545
- await secrets.set({ ...key, value: JSON.stringify(schema.parse(value)) });
112546
- } catch (error) {
112547
- throw unavailable(error);
113019
+ case "register":
113020
+ if (message.threadId === threadId) {
113021
+ parentPort?.postMessage({
113022
+ kind: "omo-team-lock-register-v1",
113023
+ incarnation: state.incarnation,
113024
+ challenge: message.challenge
113025
+ });
113026
+ state.registered = true;
113027
+ state.onRegistered?.();
113028
+ }
113029
+ return;
113030
+ case "answer":
113031
+ state.pending.get(message.id)?.(message.released);
113032
+ return;
113033
+ case "query": {
113034
+ const status = message.incarnation === state.incarnation ? state.records.get(message.record) : undefined;
113035
+ if (status !== undefined || state.exited.has(message.incarnation)) {
113036
+ channel.postMessage({
113037
+ kind: "answer",
113038
+ id: message.id,
113039
+ released: status === "released" || state.exited.has(message.incarnation)
113040
+ });
113041
+ }
113042
+ return;
112548
113043
  }
112549
- forget(secrets);
112550
- },
112551
- async clear() {
112552
- await assertUsable();
112553
- try {
112554
- await secrets.delete(key);
112555
- } catch (error) {
112556
- throw unavailable(error);
113044
+ default: {
113045
+ const unexpected = message;
113046
+ throw new Error(`Unexpected lock lifetime message: ${unexpected}`);
112557
113047
  }
112558
- forget(secrets);
112559
113048
  }
112560
113049
  };
113050
+ return state;
112561
113051
  }
112562
-
112563
- // packages/omo-opencode/src/cli/service-auth/loopback.ts
112564
- import { createHash as createHash11, randomBytes as randomBytes5, timingSafeEqual } from "crypto";
112565
- import { createServer as createServer3 } from "http";
112566
- class BrowserUnavailable extends SignInError {
112567
- }
112568
- async function authorize(options) {
112569
- const verifier = randomBytes5(32).toString("base64url");
112570
- const state = randomBytes5(32).toString("base64url");
112571
- const answer = Promise.withResolvers();
112572
- const abort = () => answer.reject(new SignInError("Browser sign-in cancelled or timed out."));
112573
- let accepted = false;
112574
- let origin = "";
112575
- const server = createServer3((request, response) => {
112576
- response.setHeader("cache-control", "no-store");
112577
- response.setHeader("referrer-policy", "no-referrer");
112578
- response.setHeader("content-type", "text/plain; charset=utf-8");
112579
- const url = new URL(request.url ?? "/", origin);
112580
- if (request.method !== "GET" || request.headers.host !== new URL(origin).host || url.origin !== origin || url.pathname !== "/callback" || request.headers.forwarded || request.headers["x-forwarded-for"]) {
112581
- response.writeHead(404).end("Not found");
112582
- return;
112583
- }
112584
- const code = url.searchParams.get("code");
112585
- const suppliedState = Buffer.from(url.searchParams.get("state") ?? "");
112586
- const expectedState = Buffer.from(state);
112587
- if (accepted || url.searchParams.getAll("state").length !== 1 || suppliedState.length !== expectedState.length || !timingSafeEqual(suppliedState, expectedState) || url.searchParams.getAll("code").length !== 1 || !code) {
112588
- response.writeHead(400).end("Invalid sign-in response");
113052
+ var state2 = globalThis.__omoTeamLockLifetimeV1 ??= createState();
113053
+ var lockOwnerInstanceId = state2.incarnation;
113054
+ function attachWorker(worker) {
113055
+ if (state2.observed.has(worker))
113056
+ return;
113057
+ state2.observed.add(worker);
113058
+ const id = worker.threadId;
113059
+ const challenge = randomUUID5();
113060
+ state2.observing.set(id, { worker, challenge });
113061
+ const incarnations = new Set;
113062
+ let exited = false;
113063
+ worker.on("message", (message) => {
113064
+ const parsed = Registration.safeParse(message);
113065
+ if (!parsed.success || parsed.data.challenge !== challenge)
112589
113066
  return;
112590
- }
112591
- accepted = true;
112592
- response.writeHead(200).end("Return to the terminal to finish signing in.");
112593
- answer.resolve(code);
113067
+ incarnations.add(parsed.data.incarnation);
113068
+ if (exited)
113069
+ state2.exited.add(parsed.data.incarnation);
112594
113070
  });
112595
- try {
112596
- await new Promise((resolve, reject) => {
112597
- server.once("error", reject);
112598
- server.listen(0, "127.0.0.1", () => {
112599
- server.off("error", reject);
112600
- resolve();
112601
- });
112602
- });
112603
- const address = server.address();
112604
- if (!address || typeof address === "string")
112605
- throw new SignInError("Unable to start the sign-in callback.");
112606
- origin = `http://127.0.0.1:${address.port}`;
112607
- const url = new URL(serviceOrigin(options.accounts));
112608
- url.search = new URLSearchParams({
112609
- redirect_uri: `${origin}/callback`,
112610
- code_challenge: createHash11("sha256").update(verifier).digest("base64url"),
112611
- code_challenge_method: "S256",
112612
- state
112613
- }).toString();
112614
- const timer = setTimeout(abort, 5 * 60000);
112615
- options.signal?.addEventListener("abort", abort, { once: true });
112616
- try {
112617
- options.signal?.throwIfAborted();
112618
- const openerFailed = () => {
112619
- if (!accepted)
112620
- throw new BrowserUnavailable("No browser is available; use device sign-in.");
112621
- };
112622
- const [code] = await Promise.all([
112623
- answer.promise,
112624
- options.open(url.href).then((opened) => {
112625
- if (!opened)
112626
- openerFailed();
112627
- }, openerFailed)
112628
- ]);
112629
- return { code, codeVerifier: verifier };
112630
- } finally {
113071
+ worker.once("exit", () => {
113072
+ exited = true;
113073
+ if (state2.observing.get(id)?.worker === worker)
113074
+ state2.observing.delete(id);
113075
+ for (const incarnation of incarnations)
113076
+ state2.exited.add(incarnation);
113077
+ });
113078
+ }
113079
+ function installLockWorkerObserver() {
113080
+ if (state2.installed)
113081
+ return;
113082
+ state2.installed = true;
113083
+ process.on("worker", attachWorker);
113084
+ state2.channel.postMessage({ kind: "hello", threadId });
113085
+ }
113086
+ installLockWorkerObserver();
113087
+ async function registerLockWorker() {
113088
+ if (state2.registered)
113089
+ return;
113090
+ state2.registration ??= new Promise((resolve) => {
113091
+ const finish = () => {
112631
113092
  clearTimeout(timer);
112632
- options.signal?.removeEventListener("abort", abort);
112633
- }
112634
- } finally {
112635
- server.closeAllConnections();
112636
- await new Promise((resolve) => server.close(() => resolve()));
112637
- }
113093
+ state2.onRegistered = undefined;
113094
+ resolve();
113095
+ };
113096
+ const timer = setTimeout(finish, 250);
113097
+ state2.onRegistered = finish;
113098
+ state2.channel.postMessage({ kind: "hello", threadId });
113099
+ });
113100
+ await state2.registration;
112638
113101
  }
112639
- async function loginLoopback(session, options) {
112640
- await session.ready();
112641
- const keys = generateDeviceKeys();
112642
- for (;; ) {
112643
- const authorization = await authorize({ accounts: options.accounts, open: options.open, signal: session.signal });
112644
- try {
112645
- const grant = parseReply(grantSchema, await session.request("/v1/session/exchange", jsonRequest({
112646
- ...authorization,
112647
- kind: "cli",
112648
- deviceName: options.name,
112649
- platform: options.platform,
112650
- ...keys.public
112651
- })));
112652
- await session.save({ ...grant, ...keys.private });
112653
- return;
112654
- } catch (error) {
112655
- if (await session.removeForLimit(error, options.chooseDevice))
112656
- continue;
112657
- throw new SignInError("Sign-in cancelled. No device was removed.");
112658
- }
112659
- }
113102
+ function markLockRecordHeld(record) {
113103
+ state2.records.set(record, "held");
113104
+ }
113105
+ function markLockRecordReleased(record) {
113106
+ if (state2.records.has(record))
113107
+ state2.records.set(record, "released");
113108
+ }
113109
+ function forgetLockRecord(record) {
113110
+ state2.records.delete(record);
113111
+ }
113112
+ async function isWorkerLockReleased(incarnation, record) {
113113
+ if (state2.exited.has(incarnation))
113114
+ return true;
113115
+ if (incarnation === state2.incarnation)
113116
+ return state2.records.get(record) === "released";
113117
+ const id = randomUUID5();
113118
+ return await new Promise((resolve) => {
113119
+ const finish = (released) => {
113120
+ clearTimeout(timer);
113121
+ state2.pending.delete(id);
113122
+ resolve(released);
113123
+ };
113124
+ const timer = setTimeout(() => finish(false), 250);
113125
+ state2.pending.set(id, finish);
113126
+ state2.channel.postMessage({ kind: "query", id, incarnation, record });
113127
+ });
112660
113128
  }
112661
-
112662
- // packages/omo-opencode/src/cli/service-auth/session.ts
112663
- import { mkdir as mkdir11 } from "fs/promises";
112664
- import { homedir as homedir31 } from "os";
112665
- import { join as join107 } from "path";
112666
-
112667
- // packages/team-core/src/team-state-store/lock-publish.ts
112668
- import { access as access3, open as open2, unlink as unlink2 } from "fs/promises";
112669
- import { dirname as dirname42 } from "path";
112670
113129
 
112671
113130
  // packages/team-core/src/team-state-store/lock-record.ts
112672
- import { randomUUID as randomUUID5 } from "crypto";
112673
- import { readFile as readFile33, stat as stat8 } from "fs/promises";
112674
- var lockOwnerInstanceId = randomUUID5();
112675
- var heldLockRecords = new Set;
112676
- function buildLockRecord(ownerTag) {
112677
- return `${ownerTag} ${randomUUID5()}
113131
+ async function buildLockRecord(ownerTag) {
113132
+ await registerLockWorker();
113133
+ const processStart = await getProcessStartIdentity(process.pid);
113134
+ return `${ownerTag} ${randomUUID6()}
112678
113135
  ${process.pid}
112679
113136
  ${Date.now()}
112680
113137
  ${lockOwnerInstanceId}
113138
+ ${processStart ?? "unavailable"}
112681
113139
  `;
112682
113140
  }
112683
- function markLockRecordHeld(content) {
112684
- heldLockRecords.add(content);
112685
- }
112686
- function markLockRecordReleased(content) {
112687
- heldLockRecords.delete(content);
112688
- }
112689
- function errorCode(error) {
113141
+ function errorCode2(error) {
112690
113142
  if (!(error instanceof Error) || !("code" in error))
112691
113143
  return null;
112692
113144
  return typeof error.code === "string" ? error.code : null;
112693
113145
  }
112694
113146
  function isPathAbsenceError(error) {
112695
- const code = errorCode(error);
113147
+ const code = errorCode2(error);
112696
113148
  return code === "ENOENT" || code === "ENOTDIR";
112697
113149
  }
112698
113150
  function parseLockOwner(content) {
112699
113151
  const lines = content.split(/\r?\n/).filter((line) => line.length > 0);
112700
- if (lines.length !== 3 && lines.length !== 4)
113152
+ if (lines.length !== 3 && lines.length !== 4 && lines.length !== 5)
112701
113153
  return null;
112702
113154
  const ownerPid = Number.parseInt(lines[1] ?? "", 10);
112703
113155
  const acquiredAtEpochMs = Number.parseInt(lines[2] ?? "", 10);
@@ -112708,24 +113160,14 @@ function parseLockOwner(content) {
112708
113160
  return {
112709
113161
  ownerPid,
112710
113162
  acquiredAtEpochMs,
112711
- instanceId: lines.length === 4 ? lines[3] ?? null : null
113163
+ instanceId: lines[3] ?? null,
113164
+ processStart: lines[4] ?? null
112712
113165
  };
112713
113166
  }
112714
- function isPidAlive(pid) {
112715
- try {
112716
- process.kill(pid, 0);
112717
- return true;
112718
- } catch (error) {
112719
- if (!(error instanceof Error)) {
112720
- throw error;
112721
- }
112722
- return false;
112723
- }
112724
- }
112725
113167
  async function readLockRecord(lockPath) {
112726
113168
  try {
112727
- const content = await readFile33(lockPath, "utf8");
112728
- const { mtimeMs } = await stat8(lockPath);
113169
+ const content = await readFile34(lockPath, "utf8");
113170
+ const { mtimeMs } = await stat9(lockPath);
112729
113171
  return { content, modifiedAtEpochMs: mtimeMs };
112730
113172
  } catch (error) {
112731
113173
  if (!(error instanceof Error))
@@ -112733,23 +113175,30 @@ async function readLockRecord(lockPath) {
112733
113175
  return null;
112734
113176
  }
112735
113177
  }
112736
- function isLockRecordStale(record, staleAfterMs) {
113178
+ async function isLockRecordStale(record, staleAfterMs) {
112737
113179
  const owner = parseLockOwner(record.content);
112738
113180
  if (owner === null)
112739
113181
  return Date.now() - record.modifiedAtEpochMs > staleAfterMs;
112740
- if (owner.instanceId !== null && owner.ownerPid === process.pid) {
112741
- return owner.instanceId !== lockOwnerInstanceId || !heldLockRecords.has(record.content);
113182
+ const liveness = getPidLiveness(owner.ownerPid);
113183
+ if (liveness === "dead") {
113184
+ return owner.instanceId !== null || Date.now() - owner.acquiredAtEpochMs > staleAfterMs;
112742
113185
  }
112743
- if (isPidAlive(owner.ownerPid))
113186
+ if (liveness === "unknown")
112744
113187
  return false;
112745
- if (owner.instanceId !== null)
112746
- return true;
112747
- return Date.now() - owner.acquiredAtEpochMs > staleAfterMs;
113188
+ if (owner.processStart !== null) {
113189
+ const actual = await getProcessStartIdentity(owner.ownerPid);
113190
+ if (actual !== null && startIdentitiesConflict(owner.processStart, actual))
113191
+ return true;
113192
+ }
113193
+ if (owner.instanceId !== null && owner.ownerPid === process.pid) {
113194
+ return await isWorkerLockReleased(owner.instanceId, record.content);
113195
+ }
113196
+ return false;
112748
113197
  }
112749
113198
 
112750
113199
  // packages/team-core/src/team-state-store/lock-publish.ts
112751
113200
  async function pathMayExist(path, deps = {}) {
112752
- const accessPath = deps.access ?? access3;
113201
+ const accessPath = deps.access ?? access4;
112753
113202
  try {
112754
113203
  await accessPath(path);
112755
113204
  return true;
@@ -112760,7 +113209,7 @@ async function pathMayExist(path, deps = {}) {
112760
113209
  }
112761
113210
  }
112762
113211
  async function assertRetryableLockOpenError(lockPath, error, deps) {
112763
- const code = errorCode(error);
113212
+ const code = errorCode2(error);
112764
113213
  if (code === "EEXIST")
112765
113214
  return;
112766
113215
  if (code === "EPERM") {
@@ -112775,9 +113224,9 @@ async function publishLockRecord(lockPath, record) {
112775
113224
  markLockRecordHeld(record);
112776
113225
  let fileHandle;
112777
113226
  try {
112778
- fileHandle = await open2(lockPath, "wx");
113227
+ fileHandle = await open3(lockPath, "wx");
112779
113228
  } catch (error) {
112780
- markLockRecordReleased(record);
113229
+ forgetLockRecord(record);
112781
113230
  await assertRetryableLockOpenError(lockPath, error);
112782
113231
  return false;
112783
113232
  }
@@ -112786,7 +113235,7 @@ async function publishLockRecord(lockPath, record) {
112786
113235
  } catch (error) {
112787
113236
  markLockRecordReleased(record);
112788
113237
  await fileHandle.close();
112789
- await unlink2(lockPath).catch(() => {
113238
+ await unlink3(lockPath).catch(() => {
112790
113239
  return;
112791
113240
  });
112792
113241
  throw error;
@@ -112796,8 +113245,8 @@ async function publishLockRecord(lockPath, record) {
112796
113245
  }
112797
113246
 
112798
113247
  // packages/team-core/src/team-state-store/lock-reclaim.ts
112799
- import { createHash as createHash12 } from "crypto";
112800
- import { unlink as unlink3 } from "fs/promises";
113248
+ import { createHash as createHash10 } from "crypto";
113249
+ import { unlink as unlink4 } from "fs/promises";
112801
113250
  var RECLAIM_UNLINK_ATTEMPTS = 3;
112802
113251
  var RECLAIM_UNLINK_RETRY_MS = 25;
112803
113252
  function delay2(ms) {
@@ -112806,11 +113255,11 @@ function delay2(ms) {
112806
113255
  });
112807
113256
  }
112808
113257
  function reclaimGuardPath(lockPath, record) {
112809
- return `${lockPath}.reclaim-${createHash12("sha256").update(record).digest("hex").slice(0, 16)}`;
113258
+ return `${lockPath}.reclaim-${createHash10("sha256").update(record).digest("hex").slice(0, 16)}`;
112810
113259
  }
112811
113260
  async function unlinkWithRetry(path, deps) {
112812
113261
  const wait = deps.delay ?? delay2;
112813
- const unlinkFile = deps.unlink ?? unlink3;
113262
+ const unlinkFile = deps.unlink ?? unlink4;
112814
113263
  for (let attempt = 1;; attempt += 1) {
112815
113264
  try {
112816
113265
  await unlinkFile(path);
@@ -112820,7 +113269,7 @@ async function unlinkWithRetry(path, deps) {
112820
113269
  throw error;
112821
113270
  if (isPathAbsenceError(error))
112822
113271
  return "absent";
112823
- const code = errorCode(error);
113272
+ const code = errorCode2(error);
112824
113273
  if (code !== "EPERM" && code !== "EBUSY" || attempt === RECLAIM_UNLINK_ATTEMPTS)
112825
113274
  return "stuck";
112826
113275
  await wait(RECLAIM_UNLINK_RETRY_MS);
@@ -112829,10 +113278,10 @@ async function unlinkWithRetry(path, deps) {
112829
113278
  }
112830
113279
  async function removeLockRecordIfUnchanged(lockPath, expectedRecord, staleAfterMs, deps = {}) {
112831
113280
  const guardPath = reclaimGuardPath(lockPath, expectedRecord);
112832
- const guardRecord = buildLockRecord("lock-reclaim");
113281
+ const guardRecord = await buildLockRecord("lock-reclaim");
112833
113282
  if (!await publishLockRecord(guardPath, guardRecord)) {
112834
113283
  const guard = await readLockRecord(guardPath);
112835
- if (guard !== null && isLockRecordStale(guard, staleAfterMs)) {
113284
+ if (guard !== null && await isLockRecordStale(guard, staleAfterMs)) {
112836
113285
  await removeLockRecordIfUnchanged(guardPath, guard.content, staleAfterMs, deps);
112837
113286
  }
112838
113287
  return "busy";
@@ -112841,13 +113290,16 @@ async function removeLockRecordIfUnchanged(lockPath, expectedRecord, staleAfterM
112841
113290
  const current = await readLockRecord(lockPath);
112842
113291
  if (current === null)
112843
113292
  return "absent";
112844
- if (current.content !== expectedRecord || !isLockRecordStale(current, staleAfterMs))
113293
+ if (current.content !== expectedRecord || !await isLockRecordStale(current, staleAfterMs))
112845
113294
  return "changed";
112846
113295
  const unlinked = await unlinkWithRetry(lockPath, deps);
113296
+ if (unlinked !== "stuck")
113297
+ forgetLockRecord(expectedRecord);
112847
113298
  return unlinked === "absent" ? "absent" : unlinked;
112848
113299
  } finally {
112849
113300
  markLockRecordReleased(guardRecord);
112850
- await unlinkWithRetry(guardPath, deps);
113301
+ if (await unlinkWithRetry(guardPath, deps) !== "stuck")
113302
+ forgetLockRecord(guardRecord);
112851
113303
  }
112852
113304
  }
112853
113305
 
@@ -112866,7 +113318,7 @@ async function acquireLock(lockPath, ownerTag, staleAfterMs) {
112866
113318
  if (Date.now() - startedAt > LOCK_WAIT_TIMEOUT_MS) {
112867
113319
  throw new Error(`Timed out acquiring lock: ${lockPath}`);
112868
113320
  }
112869
- const record = buildLockRecord(ownerTag);
113321
+ const record = await buildLockRecord(ownerTag);
112870
113322
  if (await publishLockRecord(lockPath, record))
112871
113323
  return record;
112872
113324
  const outcome = await reapStaleLock(lockPath, staleAfterMs);
@@ -112883,26 +113335,327 @@ async function withLock(lockPath, fn, opts) {
112883
113335
  return await fn();
112884
113336
  } finally {
112885
113337
  markLockRecordReleased(record);
112886
- await removeLockRecordIfUnchanged(lockPath, record, staleAfterMs);
113338
+ const outcome = await removeLockRecordIfUnchanged(lockPath, record, staleAfterMs);
113339
+ if (outcome === "removed" || outcome === "absent" || outcome === "changed")
113340
+ forgetLockRecord(record);
112887
113341
  }
112888
113342
  }
112889
113343
  async function reapStaleLock(lockPath, staleAfterMs = DEFAULT_STALE_AFTER_MS, deps = {}) {
112890
113344
  const observed = await readLockRecord(lockPath);
112891
113345
  if (observed === null)
112892
113346
  return "absent";
112893
- if (!isLockRecordStale(observed, staleAfterMs))
113347
+ if (!await isLockRecordStale(observed, staleAfterMs))
112894
113348
  return "changed";
112895
113349
  return await removeLockRecordIfUnchanged(lockPath, observed.content, staleAfterMs, deps);
112896
113350
  }
112897
113351
 
113352
+ // packages/omo-opencode/src/cli/service-auth/credential-lock.ts
113353
+ var held = new AsyncLocalStorage3;
113354
+ function credentialLockPaths(api, home = homedir31()) {
113355
+ const id = createHash11("sha256").update(serviceOrigin(api)).digest("hex");
113356
+ const directory = join106(home, ".omo", "session-locks");
113357
+ return { directory, lock: join106(directory, `${id}.lock`), desktopRecord: join106(directory, `${id}.desktop-generation.json`) };
113358
+ }
113359
+ async function withCredentialLock(api, action, home = homedir31(), ownerTag = "cli-session") {
113360
+ const { directory, lock } = credentialLockPaths(api, home);
113361
+ const owned = held.getStore();
113362
+ if (owned?.has(lock))
113363
+ return action();
113364
+ await mkdir11(directory, { recursive: true, mode: 448 });
113365
+ return withLock(lock, () => held.run(new Set([...owned ?? [], lock]), action), {
113366
+ ownerTag,
113367
+ staleAfterMs: Number.POSITIVE_INFINITY
113368
+ });
113369
+ }
113370
+
113371
+ // packages/omo-opencode/src/cli/service-auth/keystore.ts
113372
+ class CredentialStoreError extends SignInError {
113373
+ }
113374
+
113375
+ class KeychainLockedError extends CredentialStoreError {
113376
+ }
113377
+ class InvalidCredentialState extends SignInError {
113378
+ }
113379
+
113380
+ class CredentialIdentityChanged extends Error {
113381
+ constructor() {
113382
+ super("The stored sign-in changed; the captured account is no longer current.");
113383
+ }
113384
+ }
113385
+
113386
+ class KeychainApprovalPendingError extends CredentialStoreError {
113387
+ }
113388
+ var SESSION_READ_WAIT = { kind: "bounded", deadlineMs: 5000 };
113389
+ var INTERACTIVE_READ_WAIT = {
113390
+ kind: "interactive",
113391
+ noticeAfterMs: 2000,
113392
+ notice: (message) => process.stderr.write(`${message}
113393
+ `)
113394
+ };
113395
+ var processReads = new WeakMap;
113396
+ var LOCKED = /-25308|errSecInteractionNotAllowed|interaction is not allowed|locked collection/i;
113397
+ var UNLOCKED_REUSE_MS = 30000;
113398
+ var fallbackNoticed = false;
113399
+ var stderrNoticeOncePerProcess = (message) => {
113400
+ if (fallbackNoticed)
113401
+ return;
113402
+ fallbackNoticed = true;
113403
+ process.stderr.write(`${message}
113404
+ `);
113405
+ };
113406
+ var isLocked = (error) => error instanceof Error && (LOCKED.test(error.message) || LOCKED.test(String(error.code ?? "")));
113407
+ function credentialId(api) {
113408
+ return createHash12("sha256").update(serviceOrigin(api)).digest("hex");
113409
+ }
113410
+ function createCredentialStore(api, options = {}) {
113411
+ const store = createSealedStore(api, "omo-cli", credentialSchema, options.secrets, options.platform, options.lockProbe, options.notice, options.wait, (current, value) => {
113412
+ const sameIdentity = current !== null && current.device.id === value.device.id && current.signingPrivateKey === value.signingPrivateKey && current.sealingPrivateKey === value.sealingPrivateKey && (value.accountId === undefined || current.accountId === undefined || current.accountId === value.accountId);
113413
+ const accountId = value.accountId ?? (sameIdentity ? current?.accountId : undefined);
113414
+ return {
113415
+ ...value,
113416
+ ...accountId === undefined ? {} : { accountId },
113417
+ credentialGeneration: sameIdentity ? current?.credentialGeneration ?? randomUUID7() : randomUUID7()
113418
+ };
113419
+ });
113420
+ return {
113421
+ read: store.read,
113422
+ readAuthoritative: store.readAuthoritative,
113423
+ write: (value) => withCredentialLock(api, () => store.write(value), options.home),
113424
+ clear: () => withCredentialLock(api, store.clear, options.home)
113425
+ };
113426
+ }
113427
+ function createSealedStore(api, namespace, schema, secrets = typeof Bun === "undefined" ? null : Bun.secrets, platform = process.platform, lockProbe = probeSecretServiceLock, notice = stderrNoticeOncePerProcess, wait = SESSION_READ_WAIT, amendWrite) {
113428
+ if (!secrets)
113429
+ throw new SignInError("OmO sign-in needs Bun 1.4 or newer with OS credential storage. No file fallback is available.");
113430
+ const platformName = platform === "darwin" ? "macOS Keychain" : platform === "linux" ? "Linux Secret Service (libsecret and an unlocked keyring)" : platform === "win32" ? "Windows Credential Manager" : null;
113431
+ if (platformName === null)
113432
+ throw new SignInError("This platform has no supported OS credential store.");
113433
+ const key = { service: namespace, name: credentialId(api) };
113434
+ const slot = `${key.service}
113435
+ ${key.name}`;
113436
+ const readsOf = (api) => {
113437
+ const known = processReads.get(api);
113438
+ if (known !== undefined)
113439
+ return known;
113440
+ const created = new Map;
113441
+ processReads.set(api, created);
113442
+ return created;
113443
+ };
113444
+ const forget = (api) => {
113445
+ readsOf(api).delete(slot);
113446
+ };
113447
+ const sharedRead = (api) => {
113448
+ const reads = readsOf(api);
113449
+ const pending = reads.get(slot);
113450
+ if (pending !== undefined)
113451
+ return pending;
113452
+ const read = Promise.resolve().then(() => api.get(key));
113453
+ const done = () => {
113454
+ if (reads.get(slot) === read)
113455
+ reads.delete(slot);
113456
+ };
113457
+ read.then(done, done);
113458
+ reads.set(slot, read);
113459
+ return read;
113460
+ };
113461
+ 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`;
113462
+ const answered = async (api, fresh = false) => {
113463
+ const read = fresh ? Promise.resolve().then(() => api.get(key)) : sharedRead(api);
113464
+ let timer;
113465
+ try {
113466
+ if (wait.kind === "interactive") {
113467
+ timer = setTimeout(() => wait.notice(`omo: ${waiting}.`), wait.noticeAfterMs);
113468
+ return await read;
113469
+ }
113470
+ const expired = new Promise((_, reject) => {
113471
+ timer = setTimeout(() => reject(new KeychainApprovalPendingError(`${waiting}, then try again. Credentials are never saved to a file.`)), wait.deadlineMs);
113472
+ });
113473
+ return await Promise.race([read, expired]);
113474
+ } finally {
113475
+ clearTimeout(timer);
113476
+ }
113477
+ };
113478
+ const unavailable = (error) => isLocked(error) ? new KeychainLockedError(`${platformName} is locked. Unlock it, then try again. Credentials are never saved to a file.`) : new CredentialStoreError(`Cannot access ${platformName}. Unlock or enable the OS credential store and try again. Credentials are never saved to a file.`);
113479
+ let unlockedUntil = 0;
113480
+ let noticed = false;
113481
+ const assertUsable = async () => {
113482
+ if (platform !== "linux" || Date.now() < unlockedUntil)
113483
+ return;
113484
+ const lock = await lockProbe();
113485
+ if (lock === "locked")
113486
+ throw new KeychainLockedError(`${platformName} is locked. Unlock it, then try again. Credentials are never saved to a file.`);
113487
+ if (lock === "unlocked") {
113488
+ unlockedUntil = Date.now() + UNLOCKED_REUSE_MS;
113489
+ return;
113490
+ }
113491
+ if (!noticed) {
113492
+ noticed = true;
113493
+ notice("omo: could not check whether the keyring is locked (gdbus or the Secret Service did not answer); using libsecret directly.");
113494
+ }
113495
+ };
113496
+ const parsedRead = async (fresh) => {
113497
+ await assertUsable();
113498
+ let value;
113499
+ try {
113500
+ value = await answered(secrets, fresh);
113501
+ } catch (error) {
113502
+ if (error instanceof KeychainApprovalPendingError)
113503
+ throw error;
113504
+ throw unavailable(error);
113505
+ }
113506
+ if (value === null)
113507
+ return null;
113508
+ try {
113509
+ return schema.parse(JSON.parse(value));
113510
+ } catch {
113511
+ 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.");
113512
+ }
113513
+ };
113514
+ return {
113515
+ read: () => parsedRead(false),
113516
+ readAuthoritative: () => parsedRead(true),
113517
+ async write(value) {
113518
+ await assertUsable();
113519
+ try {
113520
+ let next = value;
113521
+ if (amendWrite !== undefined) {
113522
+ const raw = await answered(secrets, true);
113523
+ let previous = null;
113524
+ if (raw !== null) {
113525
+ try {
113526
+ previous = schema.parse(JSON.parse(raw));
113527
+ } catch {}
113528
+ }
113529
+ next = amendWrite(previous, value);
113530
+ }
113531
+ await secrets.set({ ...key, value: JSON.stringify(schema.parse(next)) });
113532
+ } catch (error) {
113533
+ throw unavailable(error);
113534
+ }
113535
+ forget(secrets);
113536
+ },
113537
+ async clear() {
113538
+ await assertUsable();
113539
+ try {
113540
+ await secrets.delete(key);
113541
+ } catch (error) {
113542
+ throw unavailable(error);
113543
+ }
113544
+ forget(secrets);
113545
+ }
113546
+ };
113547
+ }
113548
+
113549
+ // packages/omo-opencode/src/cli/service-auth/loopback.ts
113550
+ import { createHash as createHash13, randomBytes as randomBytes5, timingSafeEqual } from "crypto";
113551
+ import { createServer as createServer3 } from "http";
113552
+ class BrowserUnavailable extends SignInError {
113553
+ }
113554
+ async function authorize(options) {
113555
+ const verifier = randomBytes5(32).toString("base64url");
113556
+ const state = randomBytes5(32).toString("base64url");
113557
+ const answer = Promise.withResolvers();
113558
+ const abort = () => answer.reject(new SignInError("Browser sign-in cancelled or timed out."));
113559
+ let accepted = false;
113560
+ let origin = "";
113561
+ const server = createServer3((request, response) => {
113562
+ response.setHeader("cache-control", "no-store");
113563
+ response.setHeader("referrer-policy", "no-referrer");
113564
+ response.setHeader("content-type", "text/plain; charset=utf-8");
113565
+ const url = new URL(request.url ?? "/", origin);
113566
+ if (request.method !== "GET" || request.headers.host !== new URL(origin).host || url.origin !== origin || url.pathname !== "/callback" || request.headers.forwarded || request.headers["x-forwarded-for"]) {
113567
+ response.writeHead(404).end("Not found");
113568
+ return;
113569
+ }
113570
+ const code = url.searchParams.get("code");
113571
+ const suppliedState = Buffer.from(url.searchParams.get("state") ?? "");
113572
+ const expectedState = Buffer.from(state);
113573
+ if (accepted || url.searchParams.getAll("state").length !== 1 || suppliedState.length !== expectedState.length || !timingSafeEqual(suppliedState, expectedState) || url.searchParams.getAll("code").length !== 1 || !code) {
113574
+ response.writeHead(400).end("Invalid sign-in response");
113575
+ return;
113576
+ }
113577
+ accepted = true;
113578
+ response.writeHead(200).end("Return to the terminal to finish signing in.");
113579
+ answer.resolve(code);
113580
+ });
113581
+ try {
113582
+ await new Promise((resolve, reject) => {
113583
+ server.once("error", reject);
113584
+ server.listen(0, "127.0.0.1", () => {
113585
+ server.off("error", reject);
113586
+ resolve();
113587
+ });
113588
+ });
113589
+ const address = server.address();
113590
+ if (!address || typeof address === "string")
113591
+ throw new SignInError("Unable to start the sign-in callback.");
113592
+ origin = `http://127.0.0.1:${address.port}`;
113593
+ const url = new URL(serviceOrigin(options.accounts));
113594
+ url.search = new URLSearchParams({
113595
+ redirect_uri: `${origin}/callback`,
113596
+ code_challenge: createHash13("sha256").update(verifier).digest("base64url"),
113597
+ code_challenge_method: "S256",
113598
+ state
113599
+ }).toString();
113600
+ const timer = setTimeout(abort, 5 * 60000);
113601
+ options.signal?.addEventListener("abort", abort, { once: true });
113602
+ try {
113603
+ options.signal?.throwIfAborted();
113604
+ const openerFailed = () => {
113605
+ if (!accepted)
113606
+ throw new BrowserUnavailable("No browser is available; use device sign-in.");
113607
+ };
113608
+ const [code] = await Promise.all([
113609
+ answer.promise,
113610
+ options.open(url.href).then((opened) => {
113611
+ if (!opened)
113612
+ openerFailed();
113613
+ }, openerFailed)
113614
+ ]);
113615
+ return { code, codeVerifier: verifier };
113616
+ } finally {
113617
+ clearTimeout(timer);
113618
+ options.signal?.removeEventListener("abort", abort);
113619
+ }
113620
+ } finally {
113621
+ server.closeAllConnections();
113622
+ await new Promise((resolve) => server.close(() => resolve()));
113623
+ }
113624
+ }
113625
+ async function loginLoopback(session, options) {
113626
+ await session.ready();
113627
+ const keys = generateDeviceKeys();
113628
+ for (;; ) {
113629
+ const authorization = await authorize({ accounts: options.accounts, open: options.open, signal: session.signal });
113630
+ try {
113631
+ const grant = parseReply(grantSchema, await session.request("/v1/session/exchange", jsonRequest({
113632
+ ...authorization,
113633
+ kind: "cli",
113634
+ deviceName: options.name,
113635
+ platform: options.platform,
113636
+ ...keys.public
113637
+ })));
113638
+ await session.save({ ...grant, ...keys.private });
113639
+ return;
113640
+ } catch (error) {
113641
+ if (await session.removeForLimit(error, options.chooseDevice))
113642
+ continue;
113643
+ throw new SignInError("Sign-in cancelled. No device was removed.");
113644
+ }
113645
+ }
113646
+ }
113647
+
113648
+ // packages/omo-opencode/src/cli/service-auth/session.ts
113649
+ import { homedir as homedir32 } from "os";
113650
+
112898
113651
  // packages/omo-opencode/src/cli/service-auth/signed-out-marker.ts
112899
113652
  init_zod();
112900
- import { mkdir as mkdir10, readFile as readFile34, rename as rename7, rm as rm16, writeFile as writeFile16 } from "fs/promises";
112901
- import { dirname as dirname43, join as join106 } from "path";
113653
+ import { mkdir as mkdir12, readFile as readFile35, rename as rename8, rm as rm17, writeFile as writeFile17 } from "fs/promises";
113654
+ import { dirname as dirname43, join as join107 } from "path";
112902
113655
  var markerSchema = object({ device: string2().nullable(), at: string2() });
112903
- var signedOutMarkerPath = (home, credential) => join106(home, ".omo", "account-state", `${credential}.signed-out.json`);
113656
+ var signedOutMarkerPath = (home, credential) => join107(home, ".omo", "account-state", `${credential}.signed-out.json`);
112904
113657
  async function readSignedOutMarker(path) {
112905
- const text = await readFile34(path, "utf8").catch(() => null);
113658
+ const text = await readFile35(path, "utf8").catch(() => null);
112906
113659
  if (text === null)
112907
113660
  return null;
112908
113661
  let value;
@@ -112915,12 +113668,12 @@ async function readSignedOutMarker(path) {
112915
113668
  return parsed.success ? parsed.data : null;
112916
113669
  }
112917
113670
  async function writeSignedOutMarker(path, device) {
112918
- await mkdir10(dirname43(path), { recursive: true, mode: 448 });
113671
+ await mkdir12(dirname43(path), { recursive: true, mode: 448 });
112919
113672
  const staging = `${path}.${process.pid}.tmp`;
112920
- await writeFile16(staging, JSON.stringify({ device, at: new Date().toISOString() }), { mode: 384 });
112921
- await rename7(staging, path);
113673
+ await writeFile17(staging, JSON.stringify({ device, at: new Date().toISOString() }), { mode: 384 });
113674
+ await rename8(staging, path);
112922
113675
  }
112923
- var clearSignedOutMarker = (path) => rm16(path, { force: true });
113676
+ var clearSignedOutMarker = (path) => rm17(path, { force: true });
112924
113677
 
112925
113678
  // packages/omo-opencode/src/cli/service-auth/session.ts
112926
113679
  class SessionEnded extends SignInError {
@@ -112935,30 +113688,29 @@ class SessionEnded extends SignInError {
112935
113688
  var DEVICE_REVOKING_REFUSALS = new Set(["account_deleted", "reauth_required", "device_revoked"]);
112936
113689
  function createSession(options) {
112937
113690
  const api = serviceOrigin(options.api);
113691
+ const now = options.now ?? Date.now;
112938
113692
  const { store, signal } = options;
112939
- const directory = join107(options.home ?? homedir31(), ".omo", "session-locks");
112940
- const lockPath = join107(directory, `${credentialId(api)}.lock`);
112941
- const markerPath = signedOutMarkerPath(options.home ?? homedir31(), credentialId(api));
113693
+ const markerPath = signedOutMarkerPath(options.home ?? homedir32(), credentialId(api));
112942
113694
  async function locked(action) {
112943
- await mkdir11(directory, { recursive: true, mode: 448 });
112944
113695
  signal?.throwIfAborted();
112945
- return withLock(lockPath, async () => {
113696
+ return withCredentialLock(api, async () => {
112946
113697
  signal?.throwIfAborted();
112947
113698
  return action();
112948
- }, { ownerTag: "cli-session", staleAfterMs: Number.POSITIVE_INFINITY });
113699
+ }, options.home);
112949
113700
  }
112950
113701
  const request = (path, init) => requestApi(api, path, init, signal);
112951
- const uncertain = () => new SignInError(`The refresh outcome is unknown. Saved credentials and keys were retained, but this refresh token will not be sent again. ${signInHint("again")}`, true);
112952
- async function refreshedAccess(current) {
112953
- if (current.refreshState === "uncertain")
112954
- throw uncertain();
112955
- if (Date.parse(current.accessTokenExpiresAt) > Date.now() + 30000)
112956
- return current.accessToken;
113702
+ async function refreshed(current) {
113703
+ if (current.refreshState === "uncertain" || current.refreshAttempt !== undefined) {
113704
+ throw new SessionEnded(`Refresh recovery can no longer be proved safe. ${signInHint("again")}`, false, "refresh_recovery_expired");
113705
+ }
113706
+ if (Date.parse(current.accessTokenExpiresAt) > now() + 30000)
113707
+ return current;
112957
113708
  await store.write({ ...current, refreshState: "uncertain" });
112958
113709
  try {
112959
113710
  const tokens = parseReply(tokenSchema, await request("/v1/session/refresh", jsonRequest({ refreshToken: current.refreshToken })));
112960
- await store.write({ ...current, ...tokens });
112961
- return tokens.accessToken;
113711
+ const successor = { ...current, ...tokens };
113712
+ await store.write(successor);
113713
+ return successor;
112962
113714
  } catch (error) {
112963
113715
  if (error instanceof CredentialStoreError)
112964
113716
  throw error;
@@ -112970,12 +113722,19 @@ function createSession(options) {
112970
113722
  await store.write(current);
112971
113723
  throw error;
112972
113724
  }
112973
- throw uncertain();
113725
+ throw new SessionEnded(`The refresh outcome is unknown. Saved credentials and keys were retained. ${signInHint("again")}`, false, "refresh_recovery_expired");
112974
113726
  }
112975
113727
  }
113728
+ async function snapshot() {
113729
+ return locked(async () => {
113730
+ const current = await store.read();
113731
+ return current === null ? null : refreshed(current);
113732
+ });
113733
+ }
112976
113734
  return {
112977
113735
  request,
112978
113736
  signal,
113737
+ transaction: locked,
112979
113738
  async ready() {
112980
113739
  await store.read();
112981
113740
  },
@@ -112987,18 +113746,32 @@ function createSession(options) {
112987
113746
  },
112988
113747
  signedOutMarker: () => readSignedOutMarker(markerPath),
112989
113748
  clearSignedOutMarker: () => clearSignedOutMarker(markerPath),
112990
- async update(action) {
112991
- return locked(async () => action(await store.read()));
113749
+ async update(action, options = {}) {
113750
+ return locked(async () => {
113751
+ let current;
113752
+ try {
113753
+ current = await store.readAuthoritative();
113754
+ } catch (error) {
113755
+ if (!options.replaceInvalid || !(error instanceof InvalidCredentialState))
113756
+ throw error;
113757
+ current = null;
113758
+ }
113759
+ return action(current);
113760
+ });
112992
113761
  },
113762
+ async forget() {
113763
+ await locked(() => store.clear());
113764
+ },
113765
+ accessSnapshot: snapshot,
112993
113766
  async logout() {
112994
113767
  return locked(async () => {
112995
113768
  let current = null;
112996
113769
  try {
112997
- current = await store.read();
113770
+ current = await store.readAuthoritative();
112998
113771
  if (current !== null) {
112999
113772
  if (current.refreshState === "uncertain")
113000
113773
  return false;
113001
- const access = Date.parse(current.accessTokenExpiresAt) <= Date.now() ? await refreshedAccess(current) : current.accessToken;
113774
+ const access = Date.parse(current.accessTokenExpiresAt) <= now() ? (await refreshed(current)).accessToken : current.accessToken;
113002
113775
  await request(`/v1/devices/${encodeURIComponent(current.device.id)}`, {
113003
113776
  method: "DELETE",
113004
113777
  headers: { authorization: `Bearer ${access}` }
@@ -113017,12 +113790,19 @@ function createSession(options) {
113017
113790
  }
113018
113791
  });
113019
113792
  },
113020
- async accessToken() {
113793
+ async accessToken(expect) {
113794
+ signal?.throwIfAborted();
113795
+ const snapshot = await store.read();
113796
+ signal?.throwIfAborted();
113797
+ if (snapshot !== null && snapshot.refreshState !== "uncertain" && snapshot.refreshAttempt === undefined && Date.parse(snapshot.accessTokenExpiresAt) > now() + 30000 && (expect === undefined || expect(snapshot)))
113798
+ return snapshot.accessToken;
113021
113799
  return locked(async () => {
113022
- const current = await store.read();
113800
+ const current = await store.readAuthoritative();
113023
113801
  if (current === null)
113024
113802
  throw new SignInError(`Not signed in. ${signInHint("first")}`);
113025
- return refreshedAccess(current);
113803
+ if (expect !== undefined && !expect(current))
113804
+ throw new CredentialIdentityChanged;
113805
+ return (await refreshed(current)).accessToken;
113026
113806
  });
113027
113807
  },
113028
113808
  async removeForLimit(error, choose) {
@@ -113351,12 +114131,12 @@ async function boulder(options) {
113351
114131
  }
113352
114132
  // packages/omo-opencode/src/cli/codex-ulw-loop.ts
113353
114133
  import { spawn as spawn6 } from "child_process";
113354
- import { existsSync as existsSync67, readFileSync as readFileSync44, realpathSync as realpathSync13 } from "fs";
113355
- import { homedir as homedir32 } from "os";
114134
+ import { existsSync as existsSync67, readFileSync as readFileSync45, realpathSync as realpathSync14 } from "fs";
114135
+ import { homedir as homedir33 } from "os";
113356
114136
  var ULW_LOOP_DELEGATION_SENTINEL = "OMO_ULW_LOOP_DELEGATED";
113357
114137
  function resolveCodexUlwLoopCommand(input = {}) {
113358
114138
  const env = input.env ?? process.env;
113359
- const homeDir = input.homeDir ?? homedir32();
114139
+ const homeDir = input.homeDir ?? homedir33();
113360
114140
  const localComponentBin = resolveLocalUlwLoopBin(env, homeDir);
113361
114141
  if (localComponentBin !== null)
113362
114142
  return { executable: localComponentBin, argsPrefix: [] };
@@ -113401,7 +114181,7 @@ function resolveLegacyLocalOmoBin(env, homeDir, currentExecutablePaths) {
113401
114181
  }
113402
114182
  function isGeneratedRuntimeWrapper(candidate) {
113403
114183
  try {
113404
- return readFileSync44(candidate, "utf8").includes(RUNTIME_WRAPPER_MARKER);
114184
+ return readFileSync45(candidate, "utf8").includes(RUNTIME_WRAPPER_MARKER);
113405
114185
  } catch (error) {
113406
114186
  if (error instanceof Error)
113407
114187
  return false;
@@ -113414,7 +114194,7 @@ function isCurrentExecutable(candidate, currentExecutablePaths) {
113414
114194
  }
113415
114195
  function realpathOrSelf2(path) {
113416
114196
  try {
113417
- return realpathSync13(path);
114197
+ return realpathSync14(path);
113418
114198
  } catch (error) {
113419
114199
  if (error instanceof Error)
113420
114200
  return path;
@@ -113599,7 +114379,7 @@ function linkedWorktrees(records) {
113599
114379
  }
113600
114380
  // packages/omo-opencode/src/cli/worktree-sweep/sweep.ts
113601
114381
  import { existsSync as existsSync68 } from "fs";
113602
- import { stat as stat9 } from "fs/promises";
114382
+ import { stat as stat10 } from "fs/promises";
113603
114383
  import os7 from "os";
113604
114384
  import { normalize as normalize2 } from "path";
113605
114385
 
@@ -113682,7 +114462,7 @@ async function isOlderThan(worktreePath, days, now) {
113682
114462
  if (days <= 0)
113683
114463
  return false;
113684
114464
  try {
113685
- const stats = await stat9(worktreePath);
114465
+ const stats = await stat10(worktreePath);
113686
114466
  return now - stats.mtimeMs > days * DAY_MS;
113687
114467
  } catch {
113688
114468
  return false;
@@ -113929,7 +114709,7 @@ Model Providers (Priority: Native > Copilot > OpenCode Zen > Z.ai > Kimi > Baili
113929
114709
  Copilot github-copilot/ models (fallback)
113930
114710
  OpenCode Zen opencode/ models (opencode/claude-opus-5, etc.)
113931
114711
  Z.ai zai-coding-plan/glm-5.2 (visual-engineering fallback)
113932
- Kimi kimi-for-coding/kimi-k3 (Sisyphus/Prometheus fallback)
114712
+ Kimi kimi-for-coding/kimi-k3.1-pro (Sisyphus/Prometheus fallback)
113933
114713
  Bailian bailian-coding-plan/ models (Qwen, GLM, Kimi fallback)
113934
114714
  MiniMax minimax-coding-plan/MiniMax-M3 (utility fallback)
113935
114715
  MiniMax CN minimax-cn-coding-plan/MiniMax-M3 (utility fallback)