oh-my-opencode 4.7.5 → 4.8.0

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 (612) hide show
  1. package/.agents/command/get-unpublished-changes.md +35 -6
  2. package/.agents/command/omomomo.md +1 -1
  3. package/.agents/command/publish.md +13 -0
  4. package/.agents/command/security-research.md +0 -1
  5. package/.agents/skills/get-unpublished-changes/SKILL.md +21 -5
  6. package/.agents/skills/omomomo/SKILL.md +1 -2
  7. package/.agents/skills/opencode-qa/scripts/export-roundtrip.sh +57 -19
  8. package/.agents/skills/opencode-qa/scripts/lib/common.sh +19 -7
  9. package/.agents/skills/opencode-qa/scripts/sse-hook-probe.sh +3 -0
  10. package/.agents/skills/opencode-qa/scripts/tui-smoke.sh +1 -1
  11. package/.agents/skills/pre-publish-review/SKILL.md +24 -4
  12. package/.agents/skills/publish/SKILL.md +13 -0
  13. package/.agents/skills/remove-deadcode/SKILL.md +0 -1
  14. package/.agents/skills/security-research/SKILL.md +0 -1
  15. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/outputs/code-changes.md +1 -1
  16. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/outputs/code-changes.md +2 -2
  17. package/.agents/skills/work-with-pr-workspace/iteration-1/review.html +1 -1
  18. package/.opencode/command/get-unpublished-changes.md +35 -6
  19. package/.opencode/command/omomomo.md +1 -1
  20. package/.opencode/command/publish.md +13 -0
  21. package/.opencode/command/security-research.md +0 -1
  22. package/.opencode/skills/pre-publish-review/SKILL.md +24 -4
  23. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/outputs/code-changes.md +1 -1
  24. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/outputs/code-changes.md +2 -2
  25. package/.opencode/skills/work-with-pr-workspace/iteration-1/review.html +1 -1
  26. package/README.ja.md +7 -7
  27. package/README.ko.md +9 -7
  28. package/README.md +14 -8
  29. package/README.ru.md +5 -5
  30. package/README.zh-cn.md +7 -7
  31. package/bin/oh-my-opencode.js +24 -1
  32. package/bin/oh-my-opencode.test.ts +79 -20
  33. package/dist/agents/hephaestus/agent.d.ts +1 -1
  34. package/dist/agents/kimi-tool-loop-guard.d.ts +1 -0
  35. package/dist/agents/momus.d.ts +1 -1
  36. package/dist/agents/sisyphus-agent-config.d.ts +4 -0
  37. package/dist/agents/sisyphus-agent-factory.d.ts +6 -0
  38. package/dist/agents/sisyphus-dynamic-prompt-builder.d.ts +2 -0
  39. package/dist/agents/sisyphus-dynamic-prompt-execution.d.ts +2 -0
  40. package/dist/agents/sisyphus-dynamic-prompt-exploration.d.ts +2 -0
  41. package/dist/agents/sisyphus-dynamic-prompt-role.d.ts +2 -0
  42. package/dist/agents/sisyphus-dynamic-prompt-sections.d.ts +18 -0
  43. package/dist/agents/sisyphus-dynamic-prompt-style.d.ts +2 -0
  44. package/dist/agents/sisyphus-dynamic-prompt.d.ts +3 -0
  45. package/dist/agents/sisyphus-gemini-fallback-overrides.d.ts +1 -0
  46. package/dist/agents/sisyphus-junior/agent.d.ts +1 -1
  47. package/dist/agents/sisyphus-junior/index.d.ts +0 -1
  48. package/dist/agents/sisyphus.d.ts +1 -6
  49. package/dist/agents/types.d.ts +14 -3
  50. package/dist/cli/cli-program.d.ts +3 -0
  51. package/dist/cli/doctor/checks/codex.d.ts +11 -0
  52. package/dist/cli/doctor/checks/dependencies.d.ts +1 -0
  53. package/dist/cli/doctor/checks/index.d.ts +3 -0
  54. package/dist/cli/doctor/checks/system.d.ts +4 -0
  55. package/dist/cli/doctor/constants.d.ts +1 -0
  56. package/dist/cli/doctor/doctor-target.d.ts +2 -0
  57. package/dist/cli/doctor/index.d.ts +1 -0
  58. package/dist/cli/doctor/types.d.ts +26 -0
  59. package/dist/cli/index.js +4426 -2200
  60. package/dist/cli/install-codex/codex-cache-bins.d.ts +21 -0
  61. package/dist/cli/install-codex/codex-cache-fs.d.ts +3 -0
  62. package/dist/cli/install-codex/codex-cache-install.d.ts +13 -0
  63. package/dist/cli/install-codex/codex-cache-mcp-manifest.d.ts +2 -0
  64. package/dist/cli/install-codex/codex-cache-prune.d.ts +10 -0
  65. package/dist/cli/install-codex/codex-cache.d.ts +4 -32
  66. package/dist/cli/install-codex/codex-cached-marketplace-manifest.d.ts +6 -0
  67. package/dist/cli/install-codex/codex-config-agents.d.ts +3 -0
  68. package/dist/cli/install-codex/codex-config-features.d.ts +1 -0
  69. package/dist/cli/install-codex/codex-config-marketplaces.d.ts +6 -0
  70. package/dist/cli/install-codex/codex-config-plugins.d.ts +8 -0
  71. package/dist/cli/install-codex/codex-config-toml-sections.d.ts +9 -0
  72. package/dist/cli/install-codex/codex-process.d.ts +5 -0
  73. package/dist/cli/install-codex/index.d.ts +1 -1
  74. package/dist/cli/install-codex/lazycodex-version-stamp.d.ts +19 -0
  75. package/dist/cli/install-codex/link-cached-plugin-agents.d.ts +4 -0
  76. package/dist/cli/install-validators.d.ts +3 -0
  77. package/dist/cli/model-fallback-types.d.ts +3 -0
  78. package/dist/cli/run/event-handlers.d.ts +4 -11
  79. package/dist/cli/run/event-message-handlers.d.ts +5 -0
  80. package/dist/cli/run/event-session-handlers.d.ts +5 -0
  81. package/dist/cli/run/event-session-ids.d.ts +24 -0
  82. package/dist/cli/run/event-think-block.d.ts +3 -0
  83. package/dist/cli/run/event-toast-handlers.d.ts +3 -0
  84. package/dist/cli/run/event-tool-handlers.d.ts +4 -0
  85. package/dist/cli/run/event-tool-output.d.ts +2 -0
  86. package/dist/cli/run/on-complete-hook.d.ts +8 -1
  87. package/dist/cli/run/opencode-binary-resolver.d.ts +2 -1
  88. package/dist/cli/runtime-commands.d.ts +2 -0
  89. package/dist/cli/sparkshell-appserver-websocket.d.ts +4 -0
  90. package/dist/cli/sparkshell-appserver.d.ts +16 -0
  91. package/dist/cli/sparkshell-parse.d.ts +21 -0
  92. package/dist/cli/sparkshell.d.ts +26 -0
  93. package/dist/cli/types.d.ts +9 -0
  94. package/dist/config/schema/claude-code.d.ts +1 -0
  95. package/dist/config/schema/hooks.d.ts +1 -0
  96. package/dist/config/schema/oh-my-opencode-config.d.ts +1 -0
  97. package/dist/create-hooks.d.ts +1 -0
  98. package/dist/features/background-agent/concurrency.d.ts +6 -1
  99. package/dist/features/background-agent/constants.d.ts +1 -0
  100. package/dist/features/background-agent/empty-assistant-turn.d.ts +7 -0
  101. package/dist/features/background-agent/manager.d.ts +12 -0
  102. package/dist/features/background-agent/message-updated-parent-wake-output.d.ts +1 -0
  103. package/dist/features/background-agent/parent-wake-dedupe.d.ts +2 -0
  104. package/dist/features/background-agent/parent-wake-dispatched-tracker.d.ts +21 -0
  105. package/dist/features/background-agent/parent-wake-flush-runner.d.ts +24 -0
  106. package/dist/features/background-agent/parent-wake-history-state.d.ts +5 -0
  107. package/dist/features/background-agent/parent-wake-notifier-types.d.ts +50 -0
  108. package/dist/features/background-agent/parent-wake-notifier.d.ts +8 -50
  109. package/dist/features/background-agent/parent-wake-pending-queue.d.ts +22 -0
  110. package/dist/features/background-agent/parent-wake-prompt-dispatch.d.ts +19 -0
  111. package/dist/features/background-agent/parent-wake-session-history.d.ts +73 -0
  112. package/dist/features/background-agent/parent-wake-session-inspector.d.ts +35 -0
  113. package/dist/features/background-agent/parent-wake-timer-handle.d.ts +5 -0
  114. package/dist/features/background-agent/parent-wake-window-recovery.d.ts +13 -0
  115. package/dist/features/background-agent/process-cleanup.d.ts +2 -0
  116. package/dist/features/background-agent/process-cleanup.test-helpers.d.ts +3 -0
  117. package/dist/features/background-agent/session-stream-activity.d.ts +6 -0
  118. package/dist/features/background-agent/spawner/fallback-agent.d.ts +5 -0
  119. package/dist/features/background-agent/spawner/task-prompt-body.d.ts +34 -0
  120. package/dist/features/background-agent/spawner/task-record.d.ts +2 -0
  121. package/dist/features/background-agent/spawner.d.ts +2 -5
  122. package/dist/features/builtin-commands/templates/refactor-sections/codemap-and-tests.d.ts +1 -0
  123. package/dist/features/builtin-commands/templates/refactor-sections/intro-and-analysis.d.ts +1 -0
  124. package/dist/features/builtin-commands/templates/refactor-sections/plan-and-execution.d.ts +1 -0
  125. package/dist/features/builtin-commands/templates/refactor-sections/team-mode-addendum.d.ts +1 -0
  126. package/dist/features/builtin-commands/templates/refactor-sections/verification-and-tooling.d.ts +1 -0
  127. package/dist/features/builtin-commands/templates/refactor.d.ts +2 -2
  128. package/dist/features/builtin-skills/skills/agent-browser-skill.d.ts +2 -0
  129. package/dist/features/builtin-skills/skills/agent-browser-template.d.ts +2 -0
  130. package/dist/features/builtin-skills/skills/git-master-sections/commit-atomic-planning.d.ts +1 -0
  131. package/dist/features/builtin-skills/skills/git-master-sections/commit-context-analysis.d.ts +1 -0
  132. package/dist/features/builtin-skills/skills/git-master-sections/commit-execution-verification.d.ts +1 -0
  133. package/dist/features/builtin-skills/skills/git-master-sections/commit-workflow.d.ts +1 -1
  134. package/dist/features/builtin-skills/skills/index.d.ts +1 -0
  135. package/dist/features/builtin-skills/skills/playwright-mcp-skill.d.ts +2 -0
  136. package/dist/features/builtin-skills/skills/playwright.d.ts +2 -3
  137. package/dist/features/builtin-skills/skills/visual-qa.d.ts +2 -0
  138. package/dist/features/claude-code-agent-loader/agent-definitions-loader.d.ts +2 -2
  139. package/dist/features/claude-code-agent-loader/claude-model-mapper.d.ts +1 -1
  140. package/dist/features/claude-code-agent-loader/loader.d.ts +2 -2
  141. package/dist/features/claude-code-plugin-loader/agent-loader.d.ts +1 -1
  142. package/dist/features/claude-code-plugin-loader/discovery-core.d.ts +2 -0
  143. package/dist/features/claude-code-plugin-loader/discovery-paths.d.ts +3 -0
  144. package/dist/features/claude-code-plugin-loader/discovery.d.ts +3 -4
  145. package/dist/features/claude-code-plugin-loader/install-path-resolver.d.ts +1 -0
  146. package/dist/features/claude-code-plugin-loader/installed-plugin-database.d.ts +3 -0
  147. package/dist/features/claude-code-plugin-loader/loaded-plugin.d.ts +2 -0
  148. package/dist/features/claude-code-plugin-loader/plugin-key.d.ts +1 -0
  149. package/dist/features/claude-code-plugin-loader/plugin-manifest.d.ts +4 -0
  150. package/dist/features/claude-code-plugin-loader/plugin-settings.d.ts +3 -0
  151. package/dist/features/claude-code-plugin-loader/types.d.ts +1 -0
  152. package/dist/features/hook-message-injector/context-resolver.d.ts +6 -0
  153. package/dist/features/hook-message-injector/id-generation.d.ts +2 -0
  154. package/dist/features/hook-message-injector/index.d.ts +1 -1
  155. package/dist/features/hook-message-injector/injector.d.ts +7 -69
  156. package/dist/features/hook-message-injector/json-message-lookup.d.ts +3 -0
  157. package/dist/features/hook-message-injector/message-directory.d.ts +1 -0
  158. package/dist/features/hook-message-injector/message-injection.d.ts +2 -0
  159. package/dist/features/hook-message-injector/sdk-message-context.d.ts +6 -0
  160. package/dist/features/hook-message-injector/sdk-message-lookup.d.ts +28 -0
  161. package/dist/features/hook-message-injector/types.d.ts +9 -0
  162. package/dist/features/mcp-oauth/callback-server.d.ts +10 -2
  163. package/dist/features/opencode-runtime-skills/source-server.d.ts +1 -0
  164. package/dist/features/skill-mcp-manager/http-client.d.ts +2 -0
  165. package/dist/features/team-mode/deps.d.ts +8 -1
  166. package/dist/features/team-mode/team-layout-tmux/layout.d.ts +2 -0
  167. package/dist/features/team-mode/team-mailbox/send.d.ts +3 -0
  168. package/dist/features/team-mode/team-registry/paths.d.ts +17 -2
  169. package/dist/features/team-mode/team-runtime/shutdown.d.ts +1 -1
  170. package/dist/features/team-mode/team-runtime/unresolved-team-members.d.ts +3 -0
  171. package/dist/features/team-mode/team-state-store/active-resume.d.ts +5 -0
  172. package/dist/features/team-mode/team-state-store/creating-resume.d.ts +4 -0
  173. package/dist/features/team-mode/team-state-store/deleting-resume.d.ts +4 -0
  174. package/dist/features/team-mode/team-state-store/error-normalization.d.ts +2 -0
  175. package/dist/features/team-mode/team-state-store/reservation-reconciliation.d.ts +4 -0
  176. package/dist/features/team-mode/team-state-store/resume-report.d.ts +7 -0
  177. package/dist/features/team-mode/team-state-store/resume.d.ts +2 -7
  178. package/dist/features/team-mode/team-state-store/runtime-cleanup.d.ts +4 -0
  179. package/dist/features/team-mode/team-state-store/session-liveness.d.ts +9 -0
  180. package/dist/features/team-mode/team-state-store/worker-resume-status.d.ts +9 -0
  181. package/dist/features/team-mode/tools/lifecycle-create-tool.d.ts +17 -0
  182. package/dist/features/team-mode/tools/lifecycle-inline-spec.d.ts +19 -0
  183. package/dist/features/team-mode/tools/lifecycle-participant.d.ts +25 -0
  184. package/dist/features/team-mode/tools/lifecycle-shutdown-tools.d.ts +18 -0
  185. package/dist/features/team-mode/tools/lifecycle-test-fixture.d.ts +3 -3
  186. package/dist/features/team-mode/tools/lifecycle.d.ts +3 -37
  187. package/dist/features/team-mode/tools/messaging-live-delivery-client.d.ts +25 -0
  188. package/dist/features/team-mode/tools/messaging-live-delivery-recipient.d.ts +19 -0
  189. package/dist/features/team-mode/tools/messaging-live-delivery-reservation.d.ts +10 -0
  190. package/dist/features/team-mode/tools/messaging-live-delivery-state.d.ts +5 -0
  191. package/dist/features/team-mode/tools/messaging-live-delivery.d.ts +6 -0
  192. package/dist/features/team-mode/tools/messaging-runtime.d.ts +17 -0
  193. package/dist/features/team-mode/tools/messaging.d.ts +4 -29
  194. package/dist/features/tmux-subagent/manager.d.ts +20 -1
  195. package/dist/features/tmux-subagent/session-created-handler.d.ts +4 -0
  196. package/dist/features/tmux-subagent/types.d.ts +1 -0
  197. package/dist/hooks/anthropic-context-window-limit-recovery/message-builder.d.ts +1 -1
  198. package/dist/hooks/atlas/idle-completion-nudge.d.ts +10 -0
  199. package/dist/hooks/atlas/idle-constants.d.ts +4 -0
  200. package/dist/hooks/atlas/idle-continuation.d.ts +23 -0
  201. package/dist/hooks/atlas/idle-session-eligibility.d.ts +8 -0
  202. package/dist/hooks/atlas/tool-execute-after-direct-work.d.ts +9 -0
  203. package/dist/hooks/atlas/tool-execute-after-plan-tasks.d.ts +3 -0
  204. package/dist/hooks/atlas/tool-execute-after-subagent-completion.d.ts +14 -0
  205. package/dist/hooks/auto-update-checker/hook/background-update-check.d.ts +6 -0
  206. package/dist/hooks/auto-update-checker/hook/ignore-toast-error.d.ts +1 -0
  207. package/dist/hooks/hephaestus-agents-md-injector/hook.d.ts +37 -0
  208. package/dist/hooks/hephaestus-agents-md-injector/index.d.ts +1 -0
  209. package/dist/hooks/index.d.ts +1 -0
  210. package/dist/hooks/json-error-recovery/hook.d.ts +1 -1
  211. package/dist/hooks/ralph-loop/command-arguments.d.ts +1 -0
  212. package/dist/hooks/ralph-loop/event-handler-activity.d.ts +10 -0
  213. package/dist/hooks/ralph-loop/event-handler-completion.d.ts +9 -0
  214. package/dist/hooks/ralph-loop/event-handler-continuation.d.ts +16 -0
  215. package/dist/hooks/ralph-loop/event-handler-feedback.d.ts +16 -0
  216. package/dist/hooks/ralph-loop/event-handler-idle.d.ts +15 -0
  217. package/dist/hooks/ralph-loop/event-handler-impl.d.ts +10 -0
  218. package/dist/hooks/ralph-loop/event-handler-runtime-error.d.ts +4 -0
  219. package/dist/hooks/ralph-loop/event-handler-types.d.ts +20 -0
  220. package/dist/hooks/ralph-loop/loop-state-controller.d.ts +1 -0
  221. package/dist/hooks/ralph-loop/ralph-loop-event-handler.d.ts +4 -24
  222. package/dist/hooks/ralph-loop/ralph-loop-hook.d.ts +1 -0
  223. package/dist/hooks/read-image-resizer/png-chunks.d.ts +6 -0
  224. package/dist/hooks/read-image-resizer/png-constants.d.ts +1 -0
  225. package/dist/hooks/read-image-resizer/png-crc.d.ts +1 -0
  226. package/dist/hooks/read-image-resizer/png-decoder.d.ts +1 -0
  227. package/dist/hooks/read-image-resizer/png-encoder.d.ts +1 -0
  228. package/dist/hooks/read-image-resizer/png-filters.d.ts +1 -0
  229. package/dist/hooks/read-image-resizer/png-ihdr.d.ts +11 -0
  230. package/dist/hooks/read-image-resizer/png-nearest-neighbor.d.ts +1 -0
  231. package/dist/hooks/rules-injector/injection-output.d.ts +2 -0
  232. package/dist/hooks/rules-injector/injection-processor.d.ts +22 -0
  233. package/dist/hooks/rules-injector/injection-types.d.ts +43 -0
  234. package/dist/hooks/rules-injector/injector.d.ts +3 -47
  235. package/dist/hooks/rules-injector/match-decision-cache.d.ts +4 -0
  236. package/dist/hooks/rules-injector/parsed-rule-cache.d.ts +11 -0
  237. package/dist/hooks/rules-injector/path-resolution.d.ts +1 -0
  238. package/dist/hooks/rules-injector/rule-match-reason.d.ts +12 -0
  239. package/dist/hooks/rules-injector/transcript-hydration.d.ts +13 -2
  240. package/dist/hooks/runtime-fallback/auto-retry-abort.d.ts +2 -0
  241. package/dist/hooks/runtime-fallback/auto-retry-agent-context.d.ts +2 -0
  242. package/dist/hooks/runtime-fallback/auto-retry-cleanup.d.ts +2 -0
  243. package/dist/hooks/runtime-fallback/auto-retry-dispatch.d.ts +2 -0
  244. package/dist/hooks/runtime-fallback/auto-retry-metadata.d.ts +9 -0
  245. package/dist/hooks/runtime-fallback/auto-retry-timeout.d.ts +5 -0
  246. package/dist/hooks/runtime-fallback/fallback-bootstrap-model.d.ts +1 -1
  247. package/dist/hooks/runtime-fallback/fallback-state.d.ts +4 -1
  248. package/dist/hooks/runtime-fallback/normalize-model.d.ts +12 -0
  249. package/dist/hooks/session-notification-linux.d.ts +3 -0
  250. package/dist/hooks/session-notification-log.d.ts +2 -0
  251. package/dist/hooks/session-notification-macos.d.ts +3 -0
  252. package/dist/hooks/session-notification-platform.d.ts +3 -0
  253. package/dist/hooks/session-notification-runner.d.ts +9 -0
  254. package/dist/hooks/session-notification-send.d.ts +3 -0
  255. package/dist/hooks/session-notification-sender.d.ts +5 -6
  256. package/dist/hooks/session-notification-sound.d.ts +3 -0
  257. package/dist/hooks/session-notification-windows.d.ts +3 -0
  258. package/dist/hooks/session-recovery/error-recovery.d.ts +4 -0
  259. package/dist/hooks/session-recovery/hook-types.d.ts +22 -0
  260. package/dist/hooks/session-recovery/hook.d.ts +2 -19
  261. package/dist/hooks/session-recovery/interrupted-tool-results.d.ts +3 -0
  262. package/dist/hooks/session-recovery/message-state.d.ts +4 -0
  263. package/dist/hooks/session-recovery/storage/thinking-strip.d.ts +7 -1
  264. package/dist/hooks/start-work/context-info-builder.d.ts +9 -9
  265. package/dist/hooks/start-work/context-info-formatters.d.ts +21 -0
  266. package/dist/hooks/start-work/explicit-plan-context.d.ts +9 -0
  267. package/dist/hooks/start-work/plan-discovery-context.d.ts +25 -0
  268. package/dist/hooks/start-work/plan-selection.d.ts +4 -0
  269. package/dist/hooks/start-work/work-initializer.d.ts +17 -0
  270. package/dist/hooks/tool-pair-validator/hook.d.ts +1 -37
  271. package/dist/hooks/tool-pair-validator/message-transform.d.ts +2 -0
  272. package/dist/hooks/tool-pair-validator/tool-part-ids.d.ts +6 -0
  273. package/dist/hooks/tool-pair-validator/tool-result-repair.d.ts +4 -0
  274. package/dist/hooks/tool-pair-validator/types.d.ts +36 -0
  275. package/dist/index.js +12708 -9988
  276. package/dist/oh-my-opencode.schema.json +4 -0
  277. package/dist/openclaw/reply-listener-poll-loop.d.ts +3 -0
  278. package/dist/openclaw/reply-listener-signature.d.ts +2 -0
  279. package/dist/openclaw/reply-listener-sleep.d.ts +1 -0
  280. package/dist/openclaw/reply-listener-start.d.ts +9 -0
  281. package/dist/openclaw/reply-listener-status.d.ts +4 -0
  282. package/dist/openclaw/reply-listener-stop.d.ts +7 -0
  283. package/dist/openclaw/reply-listener.d.ts +5 -18
  284. package/dist/openclaw/session-registry-lock.d.ts +2 -0
  285. package/dist/openclaw/session-registry-paths.d.ts +9 -0
  286. package/dist/openclaw/session-registry-storage.d.ts +4 -0
  287. package/dist/openclaw/session-registry-types.d.ts +11 -0
  288. package/dist/openclaw/session-registry.d.ts +2 -11
  289. package/dist/plugin/chat-message/loop-commands.d.ts +9 -0
  290. package/dist/plugin/chat-message/model-cache-warning.d.ts +12 -0
  291. package/dist/plugin/chat-message/prompt-text.d.ts +2 -0
  292. package/dist/plugin/chat-message/session-model.d.ts +4 -0
  293. package/dist/plugin/chat-message/start-work-message.d.ts +5 -0
  294. package/dist/plugin/chat-message/types.d.ts +67 -0
  295. package/dist/plugin/chat-message.d.ts +3 -24
  296. package/dist/plugin/event-error-utils.d.ts +14 -0
  297. package/dist/plugin/event-hook-dispatcher.d.ts +5 -0
  298. package/dist/plugin/event-model-fallback-state.d.ts +30 -0
  299. package/dist/plugin/event-model-fallback.d.ts +39 -0
  300. package/dist/plugin/event-session-lifecycle.d.ts +49 -0
  301. package/dist/plugin/event-session-recovery.d.ts +9 -0
  302. package/dist/plugin/event-team-handlers.d.ts +13 -0
  303. package/dist/plugin/event-types.d.ts +78 -0
  304. package/dist/plugin/event.d.ts +3 -12
  305. package/dist/plugin/hooks/create-core-hooks.d.ts +1 -0
  306. package/dist/plugin/hooks/create-session-hooks.d.ts +2 -1
  307. package/dist/plugin/hooks/model-fallback-title-updater.d.ts +8 -0
  308. package/dist/plugin/session-compacting.d.ts +4 -1
  309. package/dist/plugin/system-transform.d.ts +1 -1
  310. package/dist/plugin/tool-execute-after.d.ts +2 -0
  311. package/dist/plugin/tool-registry-core-tools.d.ts +15 -0
  312. package/dist/plugin/tool-registry-factories.d.ts +36 -0
  313. package/dist/plugin/tool-registry-gated-tools.d.ts +16 -0
  314. package/dist/plugin/tool-registry-team-tools.d.ts +14 -0
  315. package/dist/plugin/tool-registry-trimming.d.ts +2 -0
  316. package/dist/plugin/tool-registry.d.ts +3 -38
  317. package/dist/plugin/ultrawork-db-model-override.d.ts +1 -1
  318. package/dist/plugin-config/agent-order-warnings.d.ts +1 -0
  319. package/dist/plugin-config/config-merger.d.ts +2 -0
  320. package/dist/plugin-config/layered-config-loader.d.ts +2 -0
  321. package/dist/plugin-config/single-config-loader.d.ts +4 -0
  322. package/dist/plugin-config.d.ts +3 -5
  323. package/dist/plugin-handlers/agent-config-assembly.d.ts +19 -0
  324. package/dist/plugin-handlers/agent-config-finalizer.d.ts +4 -0
  325. package/dist/plugin-handlers/agent-config-handler.d.ts +2 -11
  326. package/dist/plugin-handlers/agent-config-types.d.ts +30 -0
  327. package/dist/plugin-handlers/agent-skill-discovery.d.ts +3 -0
  328. package/dist/plugin-handlers/agent-source-loader.d.ts +2 -0
  329. package/dist/plugin-handlers/hook-config-handler.d.ts +0 -3
  330. package/dist/shared/context-window-usage.d.ts +7 -0
  331. package/dist/shared/dynamic-truncator-types.d.ts +17 -0
  332. package/dist/shared/dynamic-truncator.d.ts +8 -23
  333. package/dist/shared/migration/migrations-sidecar.d.ts +2 -2
  334. package/dist/shared/migration/model-versions.d.ts +7 -4
  335. package/dist/shared/model-availability.d.ts +1 -1
  336. package/dist/shared/opencode-version.d.ts +2 -2
  337. package/dist/shared/sparkshell-awareness.d.ts +5 -0
  338. package/dist/shared/spawn-with-windows-hide.d.ts +2 -0
  339. package/dist/shared/token-limit-truncator.d.ts +2 -0
  340. package/dist/testing/module-mock-lifecycle.d.ts +8 -0
  341. package/dist/tools/delegate-task/openai-categories.d.ts +0 -1
  342. package/dist/tools/delegate-task/subagent-agent-match.d.ts +3 -0
  343. package/dist/tools/delegate-task/subagent-model-resolution.d.ts +4 -0
  344. package/dist/tools/delegate-task/subagent-request-preflight.d.ts +3 -0
  345. package/dist/tools/delegate-task/subagent-resolution-types.d.ts +32 -0
  346. package/dist/tools/delegate-task/subagent-resolver.d.ts +3 -12
  347. package/dist/tools/delegate-task/sync-completion-message.d.ts +20 -0
  348. package/dist/tools/delegate-task/sync-poll-error-recovery.d.ts +1 -0
  349. package/dist/tools/delegate-task/sync-session-lifecycle.d.ts +12 -0
  350. package/dist/tools/delegate-task/sync-session-poller.d.ts +2 -0
  351. package/dist/tools/delegate-task/sync-spawn-reservation.d.ts +10 -0
  352. package/dist/tools/delegate-task/sync-task-metadata.d.ts +11 -0
  353. package/dist/tools/delegate-task/sync-task-runner.d.ts +30 -0
  354. package/dist/tools/delegate-task/sync-task.d.ts +2 -1
  355. package/dist/tools/hashline-edit/formatter-trigger.d.ts +2 -2
  356. package/package.json +15 -14
  357. package/packages/git-bash-mcp/dist/cli.js +29 -12
  358. package/packages/lsp-tools-mcp/dist/lsp/client-wrapper.d.ts +1 -1
  359. package/packages/lsp-tools-mcp/dist/lsp/client-wrapper.js +1 -1
  360. package/packages/lsp-tools-mcp/dist/lsp/config-loader.js +95 -30
  361. package/packages/lsp-tools-mcp/dist/lsp/server-installation.d.ts +1 -2
  362. package/packages/lsp-tools-mcp/dist/lsp/server-installation.js +1 -11
  363. package/packages/lsp-tools-mcp/dist/lsp/transport.d.ts +1 -0
  364. package/packages/lsp-tools-mcp/dist/lsp/transport.js +5 -10
  365. package/packages/lsp-tools-mcp/dist/lsp/workspace-edit.d.ts +4 -1
  366. package/packages/lsp-tools-mcp/dist/lsp/workspace-edit.js +84 -23
  367. package/packages/lsp-tools-mcp/dist/missing-dependency-result.d.ts +2 -0
  368. package/packages/lsp-tools-mcp/dist/missing-dependency-result.js +14 -0
  369. package/packages/lsp-tools-mcp/dist/tools.js +64 -80
  370. package/packages/lsp-tools-mcp/package.json +4 -4
  371. package/packages/omo-codex/lazycodex-repository/.github/workflows/pr-source-guidance.yml +36 -0
  372. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  373. package/packages/omo-codex/plugin/README.md +3 -1
  374. package/packages/omo-codex/plugin/components/comment-checker/src/apply-patch.ts +188 -0
  375. package/packages/omo-codex/plugin/components/comment-checker/src/core-values.ts +1 -0
  376. package/packages/omo-codex/plugin/components/comment-checker/src/core.ts +15 -361
  377. package/packages/omo-codex/plugin/components/comment-checker/src/hook-input.ts +19 -0
  378. package/packages/omo-codex/plugin/components/comment-checker/src/record.ts +11 -0
  379. package/packages/omo-codex/plugin/components/comment-checker/src/request-extractor.ts +102 -0
  380. package/packages/omo-codex/plugin/components/comment-checker/src/types.ts +51 -0
  381. package/packages/omo-codex/plugin/components/comment-checker/test/codex-hook.test.ts +145 -0
  382. package/packages/omo-codex/plugin/components/comment-checker/test/core.test.ts +200 -0
  383. package/packages/omo-codex/plugin/components/lsp/CHANGELOG.md +2 -2
  384. package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus.md +11 -5
  385. package/packages/omo-codex/plugin/components/rules/src/hook-output.ts +11 -1
  386. package/packages/omo-codex/plugin/components/rules/src/post-compact-budget.ts +0 -1
  387. package/packages/omo-codex/plugin/components/rules/src/rules/constants.ts +1 -4
  388. package/packages/omo-codex/plugin/components/rules/src/rules/engine-dynamic-cache.ts +87 -0
  389. package/packages/omo-codex/plugin/components/rules/src/rules/engine-dynamic-loader.ts +94 -0
  390. package/packages/omo-codex/plugin/components/rules/src/rules/engine-loader.ts +84 -0
  391. package/packages/omo-codex/plugin/components/rules/src/rules/engine-paths.ts +103 -0
  392. package/packages/omo-codex/plugin/components/rules/src/rules/engine-static-loader.ts +43 -0
  393. package/packages/omo-codex/plugin/components/rules/src/rules/engine-types.ts +45 -0
  394. package/packages/omo-codex/plugin/components/rules/src/rules/engine.ts +8 -419
  395. package/packages/omo-codex/plugin/components/rules/src/rules/formatter.ts +32 -5
  396. package/packages/omo-codex/plugin/components/rules/src/rules/parser-frontmatter.ts +39 -0
  397. package/packages/omo-codex/plugin/components/rules/src/rules/parser-yaml.ts +271 -0
  398. package/packages/omo-codex/plugin/components/rules/src/rules/parser.ts +3 -294
  399. package/packages/omo-codex/plugin/components/rules/src/sparkshell-awareness.ts +57 -0
  400. package/packages/omo-codex/plugin/components/rules/src/static-injection.ts +13 -2
  401. package/packages/omo-codex/plugin/components/rules/src/transcript-rule-filter.ts +17 -0
  402. package/packages/omo-codex/plugin/components/rules/test/bundled-rules-priority.test.ts +2 -1
  403. package/packages/omo-codex/plugin/components/rules/test/bundled-rules.test.ts +26 -11
  404. package/packages/omo-codex/plugin/components/rules/test/codex-hook-context-pressure.test.ts +104 -138
  405. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-budget.test.ts +5 -2
  406. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-context.test.ts +12 -5
  407. package/packages/omo-codex/plugin/components/rules/test/codex-hook.test.ts +10 -4
  408. package/packages/omo-codex/plugin/components/rules/test/engine.test.ts +65 -3
  409. package/packages/omo-codex/plugin/components/rules/test/formatter.test.ts +47 -2
  410. package/packages/omo-codex/plugin/components/rules/test/hook-output.test.ts +16 -0
  411. package/packages/omo-codex/plugin/components/rules/test/parser.test.ts +153 -0
  412. package/packages/omo-codex/plugin/components/rules/test/post-compact-budget.test.ts +12 -0
  413. package/packages/omo-codex/plugin/components/rules/test/sparkshell-awareness.test.ts +236 -0
  414. package/packages/omo-codex/plugin/components/rules/test/tool-paths.test.ts +28 -50
  415. package/packages/omo-codex/plugin/components/rules/test/windows-git-bash-bundled-rule.test.ts +6 -3
  416. package/packages/omo-codex/plugin/components/start-work-continuation/directive.md +13 -6
  417. package/packages/omo-codex/plugin/components/start-work-continuation/src/codex-hook.ts +21 -0
  418. package/packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts +64 -2
  419. package/packages/omo-codex/plugin/components/telemetry/README.md +11 -1
  420. package/packages/omo-codex/plugin/components/telemetry/biome.json +12 -0
  421. package/packages/omo-codex/plugin/components/telemetry/src/codex-hook.ts +30 -3
  422. package/packages/omo-codex/plugin/components/telemetry/src/diagnostics.ts +154 -0
  423. package/packages/omo-codex/plugin/components/telemetry/src/posthog-activity-state.ts +18 -2
  424. package/packages/omo-codex/plugin/components/telemetry/src/posthog.ts +36 -4
  425. package/packages/omo-codex/plugin/components/telemetry/test/codex-hook-diagnostics.test.ts +115 -0
  426. package/packages/omo-codex/plugin/components/telemetry/test/codex-hook.test.ts +16 -25
  427. package/packages/omo-codex/plugin/components/telemetry/test/diagnostics.test.ts +119 -0
  428. package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +1 -1
  429. package/packages/omo-codex/plugin/components/ultrawork/README.md +5 -5
  430. package/packages/omo-codex/plugin/components/ultrawork/agents/codex-ultrawork-reviewer.toml +2 -1
  431. package/packages/omo-codex/plugin/components/ultrawork/agents/explorer.toml +1 -0
  432. package/packages/omo-codex/plugin/components/ultrawork/agents/metis.toml +0 -1
  433. package/packages/omo-codex/plugin/components/ultrawork/agents/momus.toml +0 -1
  434. package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +1 -2
  435. package/packages/omo-codex/plugin/components/ultrawork/directive.md +97 -32
  436. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +65 -0
  437. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/agents/openai.yaml +7 -0
  438. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +131 -0
  439. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +38 -10
  440. package/packages/omo-codex/plugin/components/ultrawork/test/directive-contract.test.ts +18 -0
  441. package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +47 -0
  442. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  443. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +12 -8
  444. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +28 -21
  445. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +2 -3
  446. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-hook.ts +7 -7
  447. package/packages/omo-codex/plugin/components/ulw-loop/src/command-types.ts +36 -0
  448. package/packages/omo-codex/plugin/components/ulw-loop/src/constants.ts +64 -0
  449. package/packages/omo-codex/plugin/components/ulw-loop/src/domain-types.ts +98 -0
  450. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-crud.ts +17 -2
  451. package/packages/omo-codex/plugin/components/ulw-loop/src/runtime.ts +22 -0
  452. package/packages/omo-codex/plugin/components/ulw-loop/src/steering-types.ts +69 -0
  453. package/packages/omo-codex/plugin/components/ulw-loop/src/types.ts +5 -277
  454. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-commands.test.ts +35 -13
  455. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-complete-goals.test.ts +52 -0
  456. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-steering.test.ts +67 -111
  457. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-instruction.test.ts +2 -2
  458. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-hook.test.ts +31 -2
  459. package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +46 -9
  460. package/packages/omo-codex/plugin/components/ulw-loop/test/steering.test.ts +20 -29
  461. package/packages/omo-codex/plugin/model-catalog.json +5 -11
  462. package/packages/omo-codex/plugin/package-lock.json +1 -1
  463. package/packages/omo-codex/plugin/scripts/auto-update-state.mjs +78 -0
  464. package/packages/omo-codex/plugin/scripts/auto-update.mjs +166 -76
  465. package/packages/omo-codex/plugin/scripts/migrate-codex-config/catalog.mjs +71 -0
  466. package/packages/omo-codex/plugin/scripts/migrate-codex-config/config-paths.mjs +44 -0
  467. package/packages/omo-codex/plugin/scripts/migrate-codex-config/root-settings.mjs +74 -0
  468. package/packages/omo-codex/plugin/scripts/migrate-codex-config/state.mjs +29 -0
  469. package/packages/omo-codex/plugin/scripts/migrate-codex-config.mjs +14 -202
  470. package/packages/omo-codex/plugin/scripts/spawn-command.mjs +11 -0
  471. package/packages/omo-codex/plugin/scripts/sync-hook-status-messages.mjs +23 -9
  472. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +131 -28
  473. package/packages/omo-codex/plugin/skills/debugging/references/methodology/04-oracle-triple.md +3 -3
  474. package/packages/omo-codex/plugin/skills/git-master/SKILL.md +100 -0
  475. package/packages/omo-codex/plugin/skills/git-master/agents/openai.yaml +13 -0
  476. package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +9 -7
  477. package/packages/omo-codex/plugin/skills/lcx-contribute-bug-fix/SKILL.md +176 -0
  478. package/packages/omo-codex/plugin/skills/lcx-contribute-bug-fix/agents/openai.yaml +12 -0
  479. package/packages/omo-codex/plugin/skills/lcx-contribute-bug-fix/scripts/create-pr-body.mjs +107 -0
  480. package/packages/omo-codex/plugin/skills/lcx-report-bug/SKILL.md +119 -14
  481. package/packages/omo-codex/plugin/skills/lcx-report-bug/agents/openai.yaml +4 -2
  482. package/packages/omo-codex/plugin/skills/programming/references/go/concurrency.md +2 -2
  483. package/packages/omo-codex/plugin/skills/programming/references/python/async-anyio.md +6 -6
  484. package/packages/omo-codex/plugin/skills/programming/references/python/pydantic-ai.md +12 -12
  485. package/packages/omo-codex/plugin/skills/programming/references/typescript/backend-hono.md +7 -7
  486. package/packages/omo-codex/plugin/skills/refactor/SKILL.md +13 -11
  487. package/packages/omo-codex/plugin/skills/remove-ai-slops/SKILL.md +10 -8
  488. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +68 -33
  489. package/packages/omo-codex/plugin/skills/start-work/SKILL.md +86 -22
  490. package/packages/omo-codex/plugin/skills/ultraresearch/SKILL.md +770 -0
  491. package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +12 -8
  492. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +28 -21
  493. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +45 -379
  494. package/packages/omo-codex/plugin/skills/ulw-plan/agents/openai.yaml +7 -0
  495. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +131 -0
  496. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +237 -0
  497. package/packages/omo-codex/plugin/skills/visual-qa/scripts/ansi.ts +17 -0
  498. package/packages/omo-codex/plugin/skills/visual-qa/scripts/cli.ts +82 -0
  499. package/packages/omo-codex/plugin/skills/visual-qa/scripts/east-asian-width.ts +72 -0
  500. package/packages/omo-codex/plugin/skills/visual-qa/scripts/image-diff.ts +109 -0
  501. package/packages/omo-codex/plugin/skills/visual-qa/scripts/png-crc.ts +27 -0
  502. package/packages/omo-codex/plugin/skills/visual-qa/scripts/png-decode.ts +206 -0
  503. package/packages/omo-codex/plugin/skills/visual-qa/scripts/png-synth.ts +57 -0
  504. package/packages/omo-codex/plugin/skills/visual-qa/scripts/tui-grid.ts +88 -0
  505. package/packages/omo-codex/plugin/skills/visual-qa/scripts/types.ts +54 -0
  506. package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +55 -0
  507. package/packages/omo-codex/plugin/test/aggregate-build.test.mjs +38 -0
  508. package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +164 -0
  509. package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +73 -0
  510. package/packages/omo-codex/plugin/test/aggregate-mcp.test.mjs +69 -0
  511. package/packages/omo-codex/plugin/test/aggregate-model-catalog.test.mjs +53 -0
  512. package/packages/omo-codex/plugin/test/aggregate-plugin-fixture.mjs +83 -0
  513. package/packages/omo-codex/plugin/test/aggregate-skills.test.mjs +67 -0
  514. package/packages/omo-codex/plugin/test/aggregate.test.mjs +2 -514
  515. package/packages/omo-codex/plugin/test/auto-update-state-persistence.test.mjs +36 -0
  516. package/packages/omo-codex/plugin/test/auto-update.test.mjs +191 -29
  517. package/packages/omo-codex/plugin/test/component-bin-names.test.mjs +1 -1
  518. package/packages/omo-codex/plugin/test/global-review-debug-gate.test.mjs +29 -0
  519. package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +23 -10
  520. package/packages/omo-codex/plugin/test/lcx-bug-skills.test.mjs +81 -0
  521. package/packages/omo-codex/plugin/test/lcx-contribute-bug-fix-template.test.mjs +91 -0
  522. package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +165 -9
  523. package/packages/omo-codex/plugin/test/node-install-surface.test.mjs +0 -19
  524. package/packages/omo-codex/plugin/test/start-work-skill.test.mjs +107 -0
  525. package/packages/omo-codex/plugin/test/subagent-guidance.test.mjs +82 -7
  526. package/packages/omo-codex/plugin/test/sync-hook-status-messages.test.mjs +58 -6
  527. package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +152 -0
  528. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +158 -50
  529. package/packages/omo-codex/plugin/test/ulw-plan-skill.test.mjs +43 -0
  530. package/packages/omo-codex/scripts/install/agent-source-roots.mjs +13 -0
  531. package/packages/omo-codex/scripts/install/agents.mjs +84 -14
  532. package/packages/omo-codex/scripts/install/bin-links.mjs +239 -0
  533. package/packages/omo-codex/scripts/install/cache.mjs +152 -108
  534. package/packages/omo-codex/scripts/install/cached-marketplace-manifest.mjs +21 -0
  535. package/packages/omo-codex/scripts/install/cli-args.mjs +39 -2
  536. package/packages/omo-codex/scripts/install/config.mjs +7 -5
  537. package/packages/omo-codex/scripts/install/lazycodex-version-stamp.mjs +102 -0
  538. package/packages/omo-codex/scripts/install/legacy-bins.mjs +9 -1
  539. package/packages/omo-codex/scripts/install/model-catalog.mjs +9 -1
  540. package/packages/omo-codex/scripts/install/process.mjs +3 -1
  541. package/packages/omo-codex/scripts/install/project-local-cleanup.mjs +0 -1
  542. package/packages/omo-codex/scripts/install/snapshot.mjs +0 -1
  543. package/packages/omo-codex/scripts/install-agent-links.test.mjs +205 -11
  544. package/packages/omo-codex/scripts/install-bin-links.test.mjs +123 -1
  545. package/packages/omo-codex/scripts/install-cache-copy.test.mjs +129 -5
  546. package/packages/omo-codex/scripts/install-cli-args.test.mjs +82 -1
  547. package/packages/omo-codex/scripts/install-config-preservation.test.mjs +43 -0
  548. package/packages/omo-codex/scripts/install-config-reasoning.test.mjs +14 -1
  549. package/packages/omo-codex/scripts/install-config.test.mjs +49 -1
  550. package/packages/omo-codex/scripts/install-lazycodex-version-stamp.test.mjs +84 -0
  551. package/packages/omo-codex/scripts/install-local-entrypoint.test.mjs +51 -0
  552. package/packages/omo-codex/scripts/install-local.mjs +42 -40
  553. package/packages/omo-codex/scripts/install-local.test.mjs +17 -241
  554. package/packages/omo-codex/scripts/install-marketplace-cache.test.mjs +162 -0
  555. package/packages/omo-codex/scripts/install-packaged-local.test.mjs +10 -6
  556. package/packages/omo-codex/scripts/install-project-local-cleanup.test.mjs +73 -2
  557. package/packages/omo-codex/scripts/sync-telemetry-component.mjs +1 -0
  558. package/packages/shared-skills/skills/debugging/references/methodology/04-oracle-triple.md +3 -3
  559. package/packages/shared-skills/skills/git-master/SKILL.md +100 -0
  560. package/packages/shared-skills/skills/git-master/agents/openai.yaml +13 -0
  561. package/packages/shared-skills/skills/lcx-contribute-bug-fix/SKILL.md +176 -0
  562. package/packages/shared-skills/skills/lcx-contribute-bug-fix/agents/openai.yaml +12 -0
  563. package/packages/shared-skills/skills/lcx-contribute-bug-fix/scripts/create-pr-body.mjs +107 -0
  564. package/packages/shared-skills/skills/lcx-report-bug/SKILL.md +119 -14
  565. package/packages/shared-skills/skills/lcx-report-bug/agents/openai.yaml +4 -2
  566. package/packages/shared-skills/skills/programming/references/go/concurrency.md +2 -2
  567. package/packages/shared-skills/skills/programming/references/python/async-anyio.md +6 -6
  568. package/packages/shared-skills/skills/programming/references/python/pydantic-ai.md +12 -12
  569. package/packages/shared-skills/skills/programming/references/typescript/backend-hono.md +7 -7
  570. package/packages/shared-skills/skills/refactor/SKILL.md +4 -4
  571. package/packages/shared-skills/skills/remove-ai-slops/SKILL.md +1 -1
  572. package/packages/shared-skills/skills/review-work/SKILL.md +55 -33
  573. package/packages/shared-skills/skills/start-work/SKILL.md +76 -19
  574. package/packages/shared-skills/skills/ultraresearch/SKILL.md +770 -0
  575. package/packages/shared-skills/skills/visual-qa/SKILL.md +219 -0
  576. package/packages/shared-skills/skills/visual-qa/scripts/ansi.test.ts +45 -0
  577. package/packages/shared-skills/skills/visual-qa/scripts/ansi.ts +17 -0
  578. package/packages/shared-skills/skills/visual-qa/scripts/cli.test.ts +73 -0
  579. package/packages/shared-skills/skills/visual-qa/scripts/cli.ts +82 -0
  580. package/packages/shared-skills/skills/visual-qa/scripts/east-asian-width.test.ts +60 -0
  581. package/packages/shared-skills/skills/visual-qa/scripts/east-asian-width.ts +72 -0
  582. package/packages/shared-skills/skills/visual-qa/scripts/image-diff.test.ts +70 -0
  583. package/packages/shared-skills/skills/visual-qa/scripts/image-diff.ts +109 -0
  584. package/packages/shared-skills/skills/visual-qa/scripts/png-crc.ts +27 -0
  585. package/packages/shared-skills/skills/visual-qa/scripts/png-decode.test.ts +44 -0
  586. package/packages/shared-skills/skills/visual-qa/scripts/png-decode.ts +206 -0
  587. package/packages/shared-skills/skills/visual-qa/scripts/png-synth.ts +57 -0
  588. package/packages/shared-skills/skills/visual-qa/scripts/skill-prompt-contract.test.ts +83 -0
  589. package/packages/shared-skills/skills/visual-qa/scripts/tui-grid.test.ts +57 -0
  590. package/packages/shared-skills/skills/visual-qa/scripts/tui-grid.ts +88 -0
  591. package/packages/shared-skills/skills/visual-qa/scripts/types.ts +54 -0
  592. package/postinstall.mjs +24 -1
  593. package/dist/agents/custom-agent-summaries.d.ts +0 -8
  594. package/dist/agents/hephaestus/gpt-5-3-codex.d.ts +0 -20
  595. package/dist/agents/prometheus/gemini.d.ts +0 -1
  596. package/dist/agents/prometheus/gpt.d.ts +0 -1
  597. package/dist/agents/sisyphus-junior/gpt-5-3-codex.d.ts +0 -8
  598. package/dist/features/background-agent/session-route.d.ts +0 -12
  599. package/dist/features/background-agent/spawner/parent-directory-resolver.d.ts +0 -6
  600. package/dist/features/background-agent/state.d.ts +0 -35
  601. package/dist/features/claude-tasks/session-storage.d.ts +0 -9
  602. package/dist/features/mcp-oauth/resource-indicator.d.ts +0 -2
  603. package/dist/features/mcp-oauth/schema.d.ts +0 -6
  604. package/dist/features/opencode-skill-loader/async-loader.d.ts +0 -6
  605. package/dist/features/opencode-skill-loader/blocking.d.ts +0 -2
  606. package/dist/features/opencode-skill-loader/discover-worker.d.ts +0 -1
  607. package/dist/hooks/session-recovery/recover-empty-content-message-sdk.d.ts +0 -13
  608. package/dist/shared/bun-hash-shim.d.ts +0 -1
  609. package/dist/tools/delegate-task/resolve-call-id.d.ts +0 -2
  610. package/packages/shared-skills/skills/ulw-plan/SKILL.md +0 -383
  611. /package/packages/lsp-tools-mcp/dist/lsp/{utils.d.ts → startup-failure.d.ts} +0 -0
  612. /package/packages/lsp-tools-mcp/dist/lsp/{utils.js → startup-failure.js} +0 -0
@@ -0,0 +1,219 @@
1
+ ---
2
+ name: visual-qa
3
+ description: "Rigorous visual QA for any UI you built or changed, across BOTH web/page UIs and TUI/terminal UIs. MUST USE after building or changing any UI to verify it visually before declaring it done. Captures objective reference evidence with a bundled diff script (image-diff for screenshots, tui-check for terminal captures), then runs two parallel read-only oracle passes (design-system and functional integrity; visual fidelity and CJK precision) and synthesizes one good/bad verdict. Triggers: visual QA, visual regression, screenshot diff, pixel diff, image comparison, UI looks wrong, design system check, is this really a design system or just an image, alpha channel breakage, responsive check, CJK text, Korean/Japanese/Chinese text clipping, baseline drop, glyph drop, TUI alignment, terminal UI, tmux capture, box-drawing border misalignment, wide-character column drift. Use it even when the user does not say visual QA but asks whether a page, component, or terminal layout looks right."
4
+ ---
5
+
6
+ # Visual QA - Dual-Oracle Web and TUI Verification
7
+
8
+ Verify a rendered UI against intent using objective script evidence plus two parallel read-only oracle passes, then synthesize one good/bad verdict. The script numbers focus the reviewers. They are not the verdict.
9
+
10
+ ## Purpose and when to use
11
+
12
+ - Use after you build or change any UI, before calling it done. Covers web/page UIs and TUI/terminal UIs.
13
+ - Use when output must match a mock, a baseline, or a stated design intent; when you suspect a regression; when CJK (Korean/Japanese/Chinese) text may clip, misalign, or wrap awkwardly; when a claimed design system might actually be a flat image; when a terminal layout may overflow or its borders may break.
14
+ - Skip when there is no rendered surface (pure backend or library logic with no visual or terminal output). For broad post-implementation review use review-work; this skill is the visual specialist.
15
+
16
+ In the commands below, `$SKILL_DIR` is this skill's own directory (the folder containing this SKILL.md). The bundled script lives at `scripts/cli.ts` inside it.
17
+
18
+ ## Step 1 - Detect the surface
19
+
20
+ - Web/page UI: renders in a browser (HTML/CSS/JS, components, canvas, SVG). Evidence is screenshots.
21
+ - TUI/terminal UI: renders as text in a terminal (box-drawing, panes, status lines, REPL/TUI apps). Evidence is terminal captures.
22
+
23
+ If the change touches both, run both capture tracks and feed both into the passes.
24
+
25
+ ## Step 2 - Capture objective reference evidence
26
+
27
+ ### Web
28
+
29
+ 1. Capture a REFERENCE image: the user's mock/target, or a known-good baseline. Save as PNG.
30
+ 2. Capture the ACTUAL rendered screenshot at the same viewport size using the project's browser tooling (the playwright, agent-browser, or dev-browser skill). Save as PNG.
31
+ 3. Run the diff and keep the JSON:
32
+
33
+ ```
34
+ bun "$SKILL_DIR/scripts/cli.ts" image-diff <reference.png> <actual.png>
35
+ ```
36
+
37
+ Key fields: `dimensionsMatch`, `diffRatio` (0..1), `similarityScore` (0..100), `alphaChannelIntact`, `hotspots[]` (grid regions ranked by `diffRatio`).
38
+
39
+ ### TUI
40
+
41
+ 1. Capture plain text and an ANSI-preserving copy:
42
+
43
+ ```
44
+ tmux capture-pane -p > capture.txt
45
+ tmux capture-pane -e -p > capture-ansi.txt
46
+ ```
47
+
48
+ 2. Run the check with the REAL terminal width and keep the JSON:
49
+
50
+ ```
51
+ bun "$SKILL_DIR/scripts/cli.ts" tui-check capture.txt --cols <N>
52
+ ```
53
+
54
+ Key fields: `maxWidth`, `overflowLines[]`, `borderMisaligned`, `wideCharColumns[]`, `hasAnsi`.
55
+
56
+ This JSON (diff ratio, similarity score, hotspots or overflow lines, border alignment, wide-char columns, alpha) is REFERENCE evidence to aim the reviewers. It is not the verdict by itself.
57
+
58
+ ## Step 3 - Dispatch two read-only QA subagents in parallel
59
+
60
+ Send BOTH task calls in a single message so they run concurrently. Each oracle is read-only: it reviews and reports, it cannot modify files. Each returns PASS, REVISE, or FAIL with concrete, located findings. Pass A proves the surface is a real design-system implementation, not a mock-only or faked-image substitute. Pass B directly opens screenshots and inspects source/content for visual and CJK defects.
61
+
62
+ Paste evidence directly into each prompt: source code, the plain-text TUI captures, the script JSON, and the screenshot paths plus your described observations for web. The two passes differ in depth by charter, not by any model or effort setting, which cannot be pinned per call.
63
+
64
+ ### Pass A - Design-system and functional integrity (deeper, strict)
65
+
66
+ ```
67
+ task(subagent_type="oracle",
68
+ run_in_background=true,
69
+ load_skills=[],
70
+ description="Visual QA pass A: design-system and functional integrity",
71
+ prompt="""
72
+ REVIEW TYPE: DESIGN-SYSTEM AND FUNCTIONAL INTEGRITY (read-only)
73
+ TIER INTENT: Treat this as the deeper, stricter pass. Reason exhaustively before concluding. Assume a plausible-looking surface may be faked or mock-only until the source proves otherwise.
74
+
75
+ INTENT:
76
+ {What the user asked for, the mock or baseline, and the constraints.}
77
+
78
+ SURFACE: {web | tui | both}
79
+
80
+ SOURCE CODE:
81
+ {Full source of the UI: components, styles/tokens, layout, render code. Include neighboring files that show existing patterns.}
82
+
83
+ CAPTURES:
84
+ {Web: actual screenshot path(s) plus your described observations. TUI: paste capture.txt and capture-ansi.txt inline.}
85
+
86
+ SHARED SCRIPT EVIDENCE (reference, not verdict):
87
+ {Paste the image-diff or tui-check JSON. Use alphaChannelIntact for the transparency check.}
88
+
89
+ CHECK EACH:
90
+ 1. Real design system vs ad-hoc/mock-only: are styles driven by coherent design tokens and reused primitives, or one-off hardcoded values scattered per element? Treat mock-only screens, static compositions, or one-page hardcoded styling with no reusable system as BLOCKING unless the user explicitly requested a throwaway mock.
91
+ 2. Faked-with-an-image anti-pattern: is the UI a real DOM/component tree, or a pasted raster/screenshot or background-image standing in for live elements? For TUI: a real layout that reflows, or hardcoded pre-rendered text at fixed widths?
92
+ 3. Alpha and transparency: handled correctly, with no unexpected opaque or black fills and correct PNG/CSS alpha? Cross-check alphaChannelIntact.
93
+ 4. Code style and implementation quality.
94
+ 5. Responsive and resize behavior across viewport sizes (web) or terminal resize (TUI).
95
+ 6. Do the user-intended FEATURES actually work: interactions, states, navigation (web); input handling, resize, scroll (TUI)? Trace the code paths.
96
+
97
+ OUTPUT:
98
+ VERDICT: PASS | REVISE | FAIL
99
+ CONFIDENCE: HIGH | MEDIUM | LOW
100
+ SUMMARY: 1-3 sentences
101
+ FINDINGS: for each, [dimension] [severity] what is wrong, where (file/line or capture region), and the concrete fix
102
+ WHAT IS GOOD: correct aspects that must not regress
103
+ BLOCKING: items that must be fixed; empty if PASS
104
+ """
105
+ )
106
+ ```
107
+
108
+ ### Pass B - Visual fidelity and CJK precision (focused)
109
+
110
+ ```
111
+ task(subagent_type="oracle",
112
+ run_in_background=true,
113
+ load_skills=[],
114
+ description="Visual QA pass B: visual fidelity and CJK precision",
115
+ prompt="""
116
+ REVIEW TYPE: VISUAL FIDELITY AND CJK PRECISION (read-only)
117
+ TIER INTENT: Treat this as the focused visual pass. Directly open the screenshots with the available image-viewing tool (`view_image`, `look_at`, or browser inspection) before judging. Anchor every claim to the script evidence, source code, and captures.
118
+
119
+ INTENT:
120
+ {What the user requested and the mock or baseline to match.}
121
+
122
+ SURFACE: {web | tui | both}
123
+
124
+ CAPTURES:
125
+ {Web: actual and reference screenshot paths plus your described observations. TUI: paste capture.txt and capture-ansi.txt inline.}
126
+
127
+ SOURCE CODE:
128
+ {For web: include the rendered text/content, components, typography, layout, and style code. For TUI: include render code that controls wrapping, width, and wide-character handling.}
129
+
130
+ SCRIPT EVIDENCE (required, consume every field):
131
+ {Paste the image-diff or tui-check JSON.}
132
+
133
+ USE THE EVIDENCE:
134
+ - Web (image-diff): start from diffRatio and similarityScore, then directly open every screenshot path and inspect every hotspots[] entry (gridX, gridY, x, y, width, height, diffRatio). Explain the visual cause of each flagged region from the pixels and source/content together.
135
+ - TUI (tui-check): inspect maxWidth vs expectedColumns, every overflowLines[] entry, borderMisaligned, and wideCharColumns[].
136
+
137
+ CHECK:
138
+ 1. Does the rendered output match what the user requested: layout, spacing, color, type, alignment?
139
+ 2. CJK precision:
140
+ - Web: natural CJK line breaking for display and body text. Flag oversized headings that create orphaned one-character or final-syllable lines, split Korean/Japanese/Chinese semantic phrases unnaturally, detach labels such as `[Image #1]` from their content, clip baselines/descenders, drop glyphs (tofu), or show font metric mismatch. Treat the screenshot pattern `에이전트 오케스트 / 레이션 현황 및 미 / 래` as REVISE/FAIL, not acceptable wrapping.
141
+ - TUI: wide-character column drift (CJK cells counted as 1 instead of 2), box-drawing border misalignment, content overflowing past the terminal width.
142
+
143
+ OUTPUT:
144
+ VERDICT: PASS | REVISE | FAIL
145
+ CONFIDENCE: HIGH | MEDIUM | LOW
146
+ SUMMARY: 1-3 sentences
147
+ EVIDENCE TRACE: each hotspot or overflow line mapped to its visual cause
148
+ FINDINGS: for each, [severity] what is wrong, where (hotspot grid or capture line:col), and the concrete fix
149
+ BLOCKING: items that must be fixed; empty if PASS
150
+ """
151
+ )
152
+ ```
153
+
154
+ ## Step 4 - Synthesize one verdict
155
+
156
+ When both passes return, merge them into a single report. Per dimension, mark good or bad with evidence. For each bad item, state what is wrong, where (file/line, hotspot grid, or capture line), and the concrete fix. Call out what is genuinely good so it is not regressed later.
157
+
158
+ Completion gate: do not declare the UI done until both passes are satisfied, OR the remaining gaps are explicitly listed and accepted by the user. A high `similarityScore` with an open Pass A finding, for example a faked-image layout or a broken feature, is still a FAIL.
159
+
160
+ ```markdown
161
+ # Visual QA - Verdict: GOOD | NEEDS WORK
162
+
163
+ | Dimension | Pass | Verdict | Evidence |
164
+ |---|---|---|---|
165
+ | Design system real vs faked | A | good/bad | ... |
166
+ | Features work | A | good/bad | ... |
167
+ | Responsive / resize | A | good/bad | ... |
168
+ | Alpha / transparency | A+B | good/bad | ... |
169
+ | Visual fidelity to intent | B | good/bad | ... |
170
+ | CJK precision | B | good/bad | ... |
171
+
172
+ ## Must fix
173
+ [Blocking items, each with location and fix, in priority order]
174
+
175
+ ## Good, keep it
176
+ [Correct aspects that must not regress]
177
+
178
+ ## Completion gate
179
+ [Satisfied, or the exact remaining gaps and who accepted them]
180
+ ```
181
+
182
+ ## Reference evidence is not the verdict
183
+
184
+ The script quantifies pixels and columns. It cannot judge whether the result is a real design system, whether features work, or whether intent was met. A 99/100 `similarityScore` can still hide a pasted-image fake, a broken interaction, or clipped CJK descenders. Use the numbers to aim the oracles, then trust the synthesized review.
185
+
186
+ Illustrative output (locked field names):
187
+
188
+ ```json
189
+ {
190
+ "command": "image-diff",
191
+ "dimensionsMatch": true,
192
+ "reference": { "width": 1440, "height": 900 },
193
+ "actual": { "width": 1440, "height": 900 },
194
+ "totalPixels": 1296000,
195
+ "diffPixels": 38880,
196
+ "diffRatio": 0.03,
197
+ "similarityScore": 97,
198
+ "alphaChannelIntact": true,
199
+ "hotspots": [
200
+ { "gridX": 2, "gridY": 0, "x": 960, "y": 0, "width": 480, "height": 300, "diffRatio": 0.21 }
201
+ ],
202
+ "summary": "97/100 similarity; one hotspot in the top-right header region."
203
+ }
204
+ ```
205
+
206
+ ```json
207
+ {
208
+ "command": "tui-check",
209
+ "expectedColumns": 80,
210
+ "lineCount": 24,
211
+ "lineWidths": [80, 80, 82, 80],
212
+ "maxWidth": 82,
213
+ "overflowLines": [ { "line": 3, "width": 82 } ],
214
+ "borderMisaligned": true,
215
+ "wideCharColumns": [12, 13],
216
+ "hasAnsi": false,
217
+ "summary": "Line 3 overflows 80 cols by 2; borders misaligned at wide-char columns 12-13."
218
+ }
219
+ ```
@@ -0,0 +1,45 @@
1
+ import { describe, expect, test } from "bun:test"
2
+
3
+ import { hasAnsi, stripAnsi } from "./ansi"
4
+
5
+ const ESC = String.fromCharCode(0x1b)
6
+
7
+ describe("stripAnsi", () => {
8
+ test("#given an ANSI-wrapped string #when stripped #then escape codes are removed", () => {
9
+ // given
10
+ const input = `${ESC}[31mred${ESC}[0m`
11
+ // when
12
+ const stripped = stripAnsi(input)
13
+ // then
14
+ expect(stripped).toBe("red")
15
+ })
16
+
17
+ test("#given a plain string #when stripped #then it is unchanged", () => {
18
+ // given
19
+ const input = "plain text"
20
+ // when
21
+ const stripped = stripAnsi(input)
22
+ // then
23
+ expect(stripped).toBe("plain text")
24
+ })
25
+ })
26
+
27
+ describe("hasAnsi", () => {
28
+ test("#given a string with ANSI codes #when checked #then it is true", () => {
29
+ // given
30
+ const input = `${ESC}[1mbold${ESC}[0m`
31
+ // when
32
+ const detected = hasAnsi(input)
33
+ // then
34
+ expect(detected).toBe(true)
35
+ })
36
+
37
+ test("#given a plain string #when checked #then it is false", () => {
38
+ // given
39
+ const input = "no ansi here"
40
+ // when
41
+ const detected = hasAnsi(input)
42
+ // then
43
+ expect(detected).toBe(false)
44
+ })
45
+ })
@@ -0,0 +1,17 @@
1
+ const ESC = String.fromCharCode(0x1b)
2
+ const CSI = String.fromCharCode(0x9b)
3
+
4
+ // Matches CSI/escape sequences (colors, cursor moves) without embedding raw
5
+ // control characters in the regex source.
6
+ const ANSI_PATTERN = new RegExp(
7
+ `[${ESC}${CSI}][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]`,
8
+ "g",
9
+ )
10
+
11
+ export function stripAnsi(input: string): string {
12
+ return input.replace(ANSI_PATTERN, "")
13
+ }
14
+
15
+ export function hasAnsi(input: string): boolean {
16
+ return stripAnsi(input) !== input
17
+ }
@@ -0,0 +1,73 @@
1
+ import { describe, expect, test } from "bun:test"
2
+ import { mkdtempSync, writeFileSync } from "node:fs"
3
+ import { tmpdir } from "node:os"
4
+ import { join } from "node:path"
5
+
6
+ import { run, runImageDiff, runTuiCheck } from "./cli"
7
+ import { encodeRgbaPng, solidRgba } from "./png-synth"
8
+
9
+ function tempDir(): string {
10
+ return mkdtempSync(join(tmpdir(), "visual-qa-"))
11
+ }
12
+
13
+ describe("runImageDiff", () => {
14
+ test("#given two identical PNG files #when diffed #then similarity is 100", () => {
15
+ // given
16
+ const dir = tempDir()
17
+ const reference = join(dir, "reference.png")
18
+ const actual = join(dir, "actual.png")
19
+ writeFileSync(reference, encodeRgbaPng(2, 2, solidRgba(2, 2, [1, 2, 3, 255])))
20
+ writeFileSync(actual, encodeRgbaPng(2, 2, solidRgba(2, 2, [1, 2, 3, 255])))
21
+ // when
22
+ const result = runImageDiff([reference, actual])
23
+ // then
24
+ expect(result.command).toBe("image-diff")
25
+ expect(result.similarityScore).toBe(100)
26
+ expect(result.dimensionsMatch).toBe(true)
27
+ })
28
+
29
+ test("#given missing arguments #when diffed #then it throws a usage error", () => {
30
+ // given / when / then
31
+ expect(() => runImageDiff([])).toThrow("usage")
32
+ })
33
+ })
34
+
35
+ describe("runTuiCheck", () => {
36
+ test("#given a CJK capture file #when checked #then widths count wide characters", () => {
37
+ // given
38
+ const dir = tempDir()
39
+ const file = join(dir, "capture.txt")
40
+ writeFileSync(file, "가나\nhello")
41
+ // when
42
+ const result = runTuiCheck([file, "--cols", "40"])
43
+ // then
44
+ expect(result.command).toBe("tui-check")
45
+ expect(result.expectedColumns).toBe(40)
46
+ expect(result.lineWidths).toEqual([4, 5])
47
+ })
48
+ })
49
+
50
+ describe("run dispatch", () => {
51
+ test("#given an unknown command #when run #then it throws", () => {
52
+ // given / when / then
53
+ expect(() => run(["bogus"])).toThrow("unknown command")
54
+ })
55
+ })
56
+
57
+ describe("cli entry", () => {
58
+ test("#given the cli is spawned for image-diff #when it runs #then it prints JSON and exits zero", () => {
59
+ // given
60
+ const dir = tempDir()
61
+ const reference = join(dir, "reference.png")
62
+ const actual = join(dir, "actual.png")
63
+ writeFileSync(reference, encodeRgbaPng(2, 2, solidRgba(2, 2, [0, 0, 0, 255])))
64
+ writeFileSync(actual, encodeRgbaPng(2, 2, solidRgba(2, 2, [255, 255, 255, 255])))
65
+ // when
66
+ const proc = Bun.spawnSync(["bun", join(import.meta.dir, "cli.ts"), "image-diff", reference, actual])
67
+ // then
68
+ expect(proc.exitCode).toBe(0)
69
+ const parsed: Record<string, unknown> = JSON.parse(proc.stdout.toString())
70
+ expect(parsed["command"]).toBe("image-diff")
71
+ expect(parsed["similarityScore"]).toBe(0)
72
+ })
73
+ })
@@ -0,0 +1,82 @@
1
+ import { readFileSync } from "node:fs"
2
+
3
+ import { diffImages } from "./image-diff"
4
+ import { decodePng } from "./png-decode"
5
+ import { checkTui } from "./tui-grid"
6
+ import type { ImageDiffResult, TuiCheckResult } from "./types"
7
+
8
+ export class CliError extends Error {
9
+ readonly name = "CliError"
10
+ }
11
+
12
+ const DEFAULT_COLUMNS = 80
13
+ const COLS_FLAG = "--cols"
14
+
15
+ export function runImageDiff(args: readonly string[]): ImageDiffResult {
16
+ const referencePath = args[0]
17
+ const actualPath = args[1]
18
+ if (referencePath === undefined || actualPath === undefined) {
19
+ throw new CliError("usage: image-diff <reference.png> <actual.png>")
20
+ }
21
+ const reference = decodePng(readFileSync(referencePath))
22
+ const actual = decodePng(readFileSync(actualPath))
23
+ return diffImages(reference, actual)
24
+ }
25
+
26
+ function parseColumns(args: readonly string[]): number {
27
+ for (let index = 0; index < args.length; index++) {
28
+ const arg = args[index] ?? ""
29
+ if (arg === COLS_FLAG) {
30
+ const parsed = Number(args[index + 1])
31
+ if (!Number.isInteger(parsed) || parsed <= 0) {
32
+ throw new CliError(`${COLS_FLAG} requires a positive integer`)
33
+ }
34
+ return parsed
35
+ }
36
+ if (arg.startsWith(`${COLS_FLAG}=`)) {
37
+ const parsed = Number(arg.slice(COLS_FLAG.length + 1))
38
+ if (!Number.isInteger(parsed) || parsed <= 0) {
39
+ throw new CliError(`${COLS_FLAG} requires a positive integer`)
40
+ }
41
+ return parsed
42
+ }
43
+ }
44
+ return DEFAULT_COLUMNS
45
+ }
46
+
47
+ export function runTuiCheck(args: readonly string[]): TuiCheckResult {
48
+ const capturePath = args[0]
49
+ if (capturePath === undefined || capturePath.startsWith("--")) {
50
+ throw new CliError("usage: tui-check <capture.txt> [--cols N]")
51
+ }
52
+ const text = readFileSync(capturePath, "utf8")
53
+ return checkTui(text, parseColumns(args.slice(1)))
54
+ }
55
+
56
+ export function run(argv: readonly string[]): ImageDiffResult | TuiCheckResult {
57
+ const command = argv[0]
58
+ const rest = argv.slice(1)
59
+ switch (command) {
60
+ case "image-diff":
61
+ return runImageDiff(rest)
62
+ case "tui-check":
63
+ return runTuiCheck(rest)
64
+ default:
65
+ throw new CliError(`unknown command "${command ?? ""}"; expected "image-diff" or "tui-check"`)
66
+ }
67
+ }
68
+
69
+ function main(argv: readonly string[]): void {
70
+ try {
71
+ const result = run(argv)
72
+ process.stdout.write(`${JSON.stringify(result, null, 2)}\n`)
73
+ } catch (error) {
74
+ const message = error instanceof Error ? error.message : String(error)
75
+ process.stderr.write(`visual-qa error: ${message}\n`)
76
+ process.exitCode = 1
77
+ }
78
+ }
79
+
80
+ if (import.meta.main) {
81
+ main(process.argv.slice(2))
82
+ }
@@ -0,0 +1,60 @@
1
+ import { describe, expect, test } from "bun:test"
2
+
3
+ import { charWidth, stringWidth } from "./east-asian-width"
4
+
5
+ describe("charWidth", () => {
6
+ test("#given an ASCII letter #when measured #then it is one column", () => {
7
+ // given / when / then
8
+ expect(charWidth(0x61)).toBe(1)
9
+ })
10
+
11
+ test("#given a Hangul syllable #when measured #then it is two columns", () => {
12
+ expect(charWidth(0xac00)).toBe(2)
13
+ })
14
+
15
+ test("#given a CJK ideograph #when measured #then it is two columns", () => {
16
+ expect(charWidth(0x4e00)).toBe(2)
17
+ })
18
+
19
+ test("#given a fullwidth Latin letter #when measured #then it is two columns", () => {
20
+ expect(charWidth(0xff21)).toBe(2)
21
+ })
22
+
23
+ test("#given a halfwidth katakana #when measured #then it is one column", () => {
24
+ expect(charWidth(0xff71)).toBe(1)
25
+ })
26
+
27
+ test("#given a combining diacritic #when measured #then it is zero columns", () => {
28
+ expect(charWidth(0x0301)).toBe(0)
29
+ })
30
+
31
+ test("#given a zero-width space #when measured #then it is zero columns", () => {
32
+ expect(charWidth(0x200b)).toBe(0)
33
+ })
34
+
35
+ test("#given an emoji #when measured #then it is two columns", () => {
36
+ expect(charWidth(0x1f600)).toBe(2)
37
+ })
38
+ })
39
+
40
+ describe("stringWidth", () => {
41
+ test("#given an ASCII string #when measured #then width equals character count", () => {
42
+ expect(stringWidth("hello")).toBe(5)
43
+ })
44
+
45
+ test("#given Hangul text #when measured #then each syllable counts as two", () => {
46
+ expect(stringWidth("가나다")).toBe(6)
47
+ })
48
+
49
+ test("#given CJK text #when measured #then each ideograph counts as two", () => {
50
+ expect(stringWidth("日本語")).toBe(6)
51
+ })
52
+
53
+ test("#given a base letter plus a combining mark #when measured #then it is one column", () => {
54
+ expect(stringWidth("e\u0301")).toBe(1)
55
+ })
56
+
57
+ test("#given mixed ASCII and CJK #when measured #then widths add up", () => {
58
+ expect(stringWidth("AB가")).toBe(4)
59
+ })
60
+ })
@@ -0,0 +1,72 @@
1
+ interface CodePointRange {
2
+ readonly start: number
3
+ readonly end: number
4
+ }
5
+
6
+ // Combining marks and zero-width code points advance the cursor by 0 columns.
7
+ const ZERO_WIDTH_RANGES: readonly CodePointRange[] = [
8
+ { start: 0x0300, end: 0x036f }, // combining diacritical marks
9
+ { start: 0x0483, end: 0x0489 }, // combining Cyrillic
10
+ { start: 0x0591, end: 0x05bd }, // Hebrew points
11
+ { start: 0x0610, end: 0x061a }, // Arabic marks
12
+ { start: 0x064b, end: 0x065f }, // Arabic marks
13
+ { start: 0x0670, end: 0x0670 }, // Arabic superscript alef
14
+ { start: 0x06d6, end: 0x06dc }, // Arabic small high marks
15
+ { start: 0x1160, end: 0x11ff }, // Hangul Jamo medial/final (combining)
16
+ { start: 0x200b, end: 0x200f }, // zero-width space / directional marks
17
+ { start: 0x202a, end: 0x202e }, // bidi embeddings
18
+ { start: 0x2060, end: 0x2064 }, // word joiner / invisible operators
19
+ { start: 0x20d0, end: 0x20ff }, // combining marks for symbols
20
+ { start: 0xfe20, end: 0xfe2f }, // combining half marks
21
+ { start: 0xfeff, end: 0xfeff }, // zero-width no-break space (BOM)
22
+ ]
23
+
24
+ // East Asian Wide + Fullwidth code points advance the cursor by 2 columns.
25
+ const WIDE_RANGES: readonly CodePointRange[] = [
26
+ { start: 0x1100, end: 0x115f }, // Hangul Jamo (leading consonants)
27
+ { start: 0x231a, end: 0x231b }, // watch / hourglass
28
+ { start: 0x2e80, end: 0x303e }, // CJK radicals, Kangxi, CJK symbols
29
+ { start: 0x3041, end: 0x33ff }, // Kana, Bopomofo, CJK compatibility
30
+ { start: 0x3400, end: 0x4dbf }, // CJK Unified Ext A
31
+ { start: 0x4e00, end: 0x9fff }, // CJK Unified Ideographs
32
+ { start: 0xa000, end: 0xa4cf }, // Yi syllables
33
+ { start: 0xa960, end: 0xa97f }, // Hangul Jamo Ext-A
34
+ { start: 0xac00, end: 0xd7a3 }, // Hangul syllables
35
+ { start: 0xf900, end: 0xfaff }, // CJK compatibility ideographs
36
+ { start: 0xfe10, end: 0xfe19 }, // vertical forms
37
+ { start: 0xfe30, end: 0xfe6f }, // CJK compatibility / small forms
38
+ { start: 0xff00, end: 0xff60 }, // fullwidth forms (halfwidth starts at 0xff61)
39
+ { start: 0xffe0, end: 0xffe6 }, // fullwidth signs
40
+ { start: 0x1b000, end: 0x1b16f }, // Kana supplement / extended
41
+ { start: 0x1f200, end: 0x1f2ff }, // enclosed ideographic supplement
42
+ { start: 0x1f300, end: 0x1faff }, // emoji and pictographs
43
+ { start: 0x20000, end: 0x3fffd }, // CJK Unified Ext B and beyond
44
+ ]
45
+
46
+ function inRanges(codePoint: number, ranges: readonly CodePointRange[]): boolean {
47
+ for (const range of ranges) {
48
+ if (codePoint >= range.start && codePoint <= range.end) {
49
+ return true
50
+ }
51
+ }
52
+ return false
53
+ }
54
+
55
+ export function charWidth(codePoint: number): 0 | 1 | 2 {
56
+ if (codePoint === 0) return 0
57
+ if (codePoint < 0x20) return 0 // C0 control
58
+ if (codePoint >= 0x7f && codePoint <= 0x9f) return 0 // DEL and C1 control
59
+ if (inRanges(codePoint, ZERO_WIDTH_RANGES)) return 0
60
+ if (inRanges(codePoint, WIDE_RANGES)) return 2
61
+ return 1
62
+ }
63
+
64
+ export function stringWidth(text: string): number {
65
+ let total = 0
66
+ for (const char of text) {
67
+ const codePoint = char.codePointAt(0)
68
+ if (codePoint === undefined) continue
69
+ total += charWidth(codePoint)
70
+ }
71
+ return total
72
+ }
@@ -0,0 +1,70 @@
1
+ import { describe, expect, test } from "bun:test"
2
+
3
+ import { diffImages } from "./image-diff"
4
+ import { solidRgba } from "./png-synth"
5
+ import type { DecodedImage } from "./types"
6
+
7
+ function makeImage(width: number, height: number, rgba: Uint8Array, transparent = false): DecodedImage {
8
+ return { width, height, rgba, hasAlphaChannel: true, hasTransparentPixels: transparent }
9
+ }
10
+
11
+ describe("diffImages", () => {
12
+ test("#given two identical images #when diffed #then similarity is 100 with no hotspots", () => {
13
+ // given
14
+ const ref = makeImage(4, 4, solidRgba(4, 4, [10, 20, 30, 255]))
15
+ const act = makeImage(4, 4, solidRgba(4, 4, [10, 20, 30, 255]))
16
+ // when
17
+ const result = diffImages(ref, act)
18
+ // then
19
+ expect(result.diffPixels).toBe(0)
20
+ expect(result.similarityScore).toBe(100)
21
+ expect(result.hotspots.length).toBe(0)
22
+ expect(result.dimensionsMatch).toBe(true)
23
+ })
24
+
25
+ test("#given two fully different images #when diffed #then similarity is 0 with hotspots", () => {
26
+ // given
27
+ const ref = makeImage(4, 4, solidRgba(4, 4, [0, 0, 0, 255]))
28
+ const act = makeImage(4, 4, solidRgba(4, 4, [255, 255, 255, 255]))
29
+ // when
30
+ const result = diffImages(ref, act)
31
+ // then
32
+ expect(result.diffPixels).toBe(16)
33
+ expect(result.similarityScore).toBe(0)
34
+ expect(result.hotspots.length).toBeGreaterThan(0)
35
+ })
36
+
37
+ test("#given images of different sizes #when diffed #then dimensionsMatch is false", () => {
38
+ // given
39
+ const ref = makeImage(4, 4, solidRgba(4, 4, [0, 0, 0, 255]))
40
+ const act = makeImage(2, 2, solidRgba(2, 2, [0, 0, 0, 255]))
41
+ // when
42
+ const result = diffImages(ref, act)
43
+ // then
44
+ expect(result.dimensionsMatch).toBe(false)
45
+ })
46
+
47
+ test("#given a transparent reference and an opaque actual #when diffed #then alpha is flagged", () => {
48
+ // given
49
+ const ref = makeImage(2, 2, solidRgba(2, 2, [0, 0, 0, 128]), true)
50
+ const act = makeImage(2, 2, solidRgba(2, 2, [0, 0, 0, 255]), false)
51
+ // when
52
+ const result = diffImages(ref, act)
53
+ // then
54
+ expect(result.alphaChannelIntact).toBe(false)
55
+ })
56
+
57
+ test("#given a single changed pixel #when diffed #then one hotspot marks its grid cell", () => {
58
+ // given
59
+ const base = solidRgba(8, 8, [0, 0, 0, 255])
60
+ const changed = solidRgba(8, 8, [0, 0, 0, 255])
61
+ changed[0] = 255
62
+ // when
63
+ const result = diffImages(makeImage(8, 8, base), makeImage(8, 8, changed))
64
+ // then
65
+ expect(result.diffPixels).toBe(1)
66
+ expect(result.hotspots.length).toBe(1)
67
+ expect(result.hotspots[0]?.gridX).toBe(0)
68
+ expect(result.hotspots[0]?.gridY).toBe(0)
69
+ })
70
+ })