monomind 2.5.1 → 2.5.3

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 (324) hide show
  1. package/README.md +1 -1
  2. package/package.json +2 -1
  3. package/packages/@monomind/cli/.claude/agents/design/design-monodesign.md +6 -6
  4. package/packages/@monomind/cli/.claude/agents/github/repo-architect.md +3 -3
  5. package/packages/@monomind/cli/.claude/agents/github/sync-coordinator.md +2 -2
  6. package/packages/@monomind/cli/.claude/agents/specialists/integration-architect.md +4 -4
  7. package/packages/@monomind/cli/.claude/commands/github/repo-architect.md +4 -4
  8. package/packages/@monomind/cli/.claude/commands/github/sync-coordinator.md +2 -2
  9. package/packages/@monomind/cli/.claude/commands/mastermind/_repeat.md +4 -4
  10. package/packages/@monomind/cli/.claude/commands/mastermind/approvev1.md +4 -4
  11. package/packages/@monomind/cli/.claude/commands/mastermind/architect.md +6 -6
  12. package/packages/@monomind/cli/.claude/commands/mastermind/autodev.md +5 -5
  13. package/packages/@monomind/cli/.claude/commands/mastermind/brain.md +2 -2
  14. package/packages/@monomind/cli/.claude/commands/mastermind/build.md +6 -6
  15. package/packages/@monomind/cli/.claude/commands/mastermind/code-review.md +2 -2
  16. package/packages/@monomind/cli/.claude/commands/mastermind/content.md +6 -6
  17. package/packages/@monomind/cli/.claude/commands/mastermind/createorg.md +4 -4
  18. package/packages/@monomind/cli/.claude/commands/mastermind/createtask.md +3 -3
  19. package/packages/@monomind/cli/.claude/commands/mastermind/debug.md +5 -5
  20. package/packages/@monomind/cli/.claude/commands/mastermind/design.md +5 -5
  21. package/packages/@monomind/cli/.claude/commands/mastermind/do.md +2 -2
  22. package/packages/@monomind/cli/.claude/commands/mastermind/execute.md +5 -5
  23. package/packages/@monomind/cli/.claude/commands/mastermind/finance.md +6 -6
  24. package/packages/@monomind/cli/.claude/commands/mastermind/finish.md +5 -5
  25. package/packages/@monomind/cli/.claude/commands/mastermind/idea.md +6 -6
  26. package/packages/@monomind/cli/.claude/commands/mastermind/ideate.md +5 -5
  27. package/packages/@monomind/cli/.claude/commands/mastermind/improve.md +6 -6
  28. package/packages/@monomind/cli/.claude/commands/mastermind/marketing.md +6 -6
  29. package/packages/@monomind/cli/.claude/commands/mastermind/master.md +54 -54
  30. package/packages/@monomind/cli/.claude/commands/mastermind/ops.md +6 -6
  31. package/packages/@monomind/cli/.claude/commands/mastermind/orgs.md +2 -2
  32. package/packages/@monomind/cli/.claude/commands/mastermind/orgstatus.md +2 -2
  33. package/packages/@monomind/cli/.claude/commands/mastermind/plan.md +5 -5
  34. package/packages/@monomind/cli/.claude/commands/mastermind/receive-review.md +5 -5
  35. package/packages/@monomind/cli/.claude/commands/mastermind/release.md +6 -6
  36. package/packages/@monomind/cli/.claude/commands/mastermind/research.md +6 -6
  37. package/packages/@monomind/cli/.claude/commands/mastermind/review.md +6 -6
  38. package/packages/@monomind/cli/.claude/commands/mastermind/runorg.md +4 -4
  39. package/packages/@monomind/cli/.claude/commands/mastermind/runorgv1.md +5 -5
  40. package/packages/@monomind/cli/.claude/commands/mastermind/sales.md +6 -6
  41. package/packages/@monomind/cli/.claude/commands/mastermind/skill-builder.md +5 -5
  42. package/packages/@monomind/cli/.claude/commands/mastermind/stoporg.md +3 -3
  43. package/packages/@monomind/cli/.claude/commands/mastermind/taskdev.md +5 -5
  44. package/packages/@monomind/cli/.claude/commands/mastermind/tdd.md +5 -5
  45. package/packages/@monomind/cli/.claude/commands/mastermind/techport.md +5 -5
  46. package/packages/@monomind/cli/.claude/commands/mastermind/verify.md +5 -5
  47. package/packages/@monomind/cli/.claude/commands/mastermind/worktree.md +5 -5
  48. package/packages/@monomind/cli/.claude/helpers/control-start.cjs +30 -0
  49. package/packages/@monomind/cli/.claude/helpers/event-logger.cjs +2 -2
  50. package/packages/@monomind/cli/.claude/helpers/extras-registry.json +1 -1
  51. package/packages/@monomind/cli/.claude/helpers/handlers/agent-start-handler.cjs +2 -2
  52. package/packages/@monomind/cli/.claude/helpers/handlers/edit-handler.cjs +2 -2
  53. package/packages/@monomind/cli/.claude/helpers/handlers/gates-handler.cjs +1 -1
  54. package/packages/@monomind/cli/.claude/helpers/handlers/route-handler.cjs +1 -1
  55. package/packages/@monomind/cli/.claude/helpers/handlers/session-handler.cjs +1 -1
  56. package/packages/@monomind/cli/.claude/helpers/handlers/session-restore-handler.cjs +11 -11
  57. package/packages/@monomind/cli/.claude/helpers/handlers/task-handler.cjs +2 -2
  58. package/packages/@monomind/cli/.claude/helpers/hook-handler.cjs +8 -8
  59. package/packages/@monomind/cli/.claude/helpers/utils/monograph.cjs +44 -12
  60. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/access.md → mastermind-access/SKILL.md} +2 -2
  61. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/activity.md → mastermind-activity/SKILL.md} +2 -2
  62. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/adapter-manager.md → mastermind-adapter-manager/SKILL.md} +2 -2
  63. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/adapters.md → mastermind-adapters/SKILL.md} +2 -2
  64. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/agent-detail.md → mastermind-agent-detail/SKILL.md} +2 -2
  65. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/agents.md → mastermind-agents/SKILL.md} +2 -2
  66. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/approval-detail.md → mastermind-approval-detail/SKILL.md} +2 -2
  67. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/approvev1.md → mastermind-approvev1/SKILL.md} +2 -2
  68. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/architect.md → mastermind-architect/SKILL.md} +7 -7
  69. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/autodev.md → mastermind-autodev/SKILL.md} +10 -10
  70. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/backup.md → mastermind-backup/SKILL.md} +2 -2
  71. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/bootstrap.md → mastermind-bootstrap/SKILL.md} +2 -2
  72. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/budgets.md → mastermind-budgets/SKILL.md} +2 -2
  73. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/build.md → mastermind-build/SKILL.md} +5 -5
  74. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/companies.md → mastermind-companies/SKILL.md} +2 -2
  75. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/content.md → mastermind-content/SKILL.md} +5 -5
  76. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/costs.md → mastermind-costs/SKILL.md} +2 -2
  77. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/createorg.md → mastermind-createorg/SKILL.md} +3 -3
  78. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/debug.md → mastermind-debug/SKILL.md} +4 -4
  79. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/_delegation.md → mastermind-delegation/SKILL.md} +1 -1
  80. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/design.md → mastermind-design/SKILL.md} +9 -9
  81. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/diagnose.md → mastermind-diagnose/SKILL.md} +2 -2
  82. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/env.md → mastermind-env/SKILL.md} +2 -2
  83. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/environments.md → mastermind-environments/SKILL.md} +2 -2
  84. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/execute.md → mastermind-execute/SKILL.md} +10 -10
  85. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/export.md → mastermind-export/SKILL.md} +2 -2
  86. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/finance.md → mastermind-finance/SKILL.md} +5 -5
  87. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/goal-detail.md → mastermind-goal-detail/SKILL.md} +2 -2
  88. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/goals.md → mastermind-goals/SKILL.md} +2 -2
  89. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/heartbeatv1.md → mastermind-heartbeatv1/SKILL.md} +2 -2
  90. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/idea.md → mastermind-idea/SKILL.md} +7 -7
  91. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/import.md → mastermind-import/SKILL.md} +2 -2
  92. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/inbox.md → mastermind-inbox/SKILL.md} +2 -2
  93. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/instance.md → mastermind-instance/SKILL.md} +2 -2
  94. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/instance-settings.md → mastermind-instance-settings/SKILL.md} +2 -2
  95. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/invite-landing.md → mastermind-invite-landing/SKILL.md} +2 -2
  96. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/invites.md → mastermind-invites/SKILL.md} +2 -2
  97. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/issue-detail.md → mastermind-issue-detail/SKILL.md} +2 -2
  98. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/issues.md → mastermind-issues/SKILL.md} +2 -2
  99. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/join-queue.md → mastermind-join-queue/SKILL.md} +2 -2
  100. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/liveness.md → mastermind-liveness/SKILL.md} +2 -2
  101. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/marketing.md → mastermind-marketing/SKILL.md} +8 -8
  102. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/memory.md → mastermind-memory/SKILL.md} +2 -2
  103. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/monitor.md → mastermind-monitor/SKILL.md} +2 -2
  104. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/my-issues.md → mastermind-my-issues/SKILL.md} +2 -2
  105. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/new-agent.md → mastermind-new-agent/SKILL.md} +2 -2
  106. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/ops.md → mastermind-ops/SKILL.md} +5 -5
  107. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/org-chart.md → mastermind-org-chart/SKILL.md} +2 -2
  108. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/org-settings.md → mastermind-org-settings/SKILL.md} +2 -2
  109. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/orgs.md → mastermind-orgs/SKILL.md} +1 -1
  110. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/orgstatus.md → mastermind-orgstatus/SKILL.md} +2 -2
  111. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/plan.md → mastermind-plan/SKILL.md} +7 -7
  112. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/plan-to-tasks.md → mastermind-plan-to-tasks/SKILL.md} +2 -2
  113. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/plugin-manager.md → mastermind-plugin-manager/SKILL.md} +2 -2
  114. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/plugin-settings.md → mastermind-plugin-settings/SKILL.md} +2 -2
  115. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/plugins.md → mastermind-plugins/SKILL.md} +2 -2
  116. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/profile.md → mastermind-profile/SKILL.md} +2 -2
  117. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/project-detail.md → mastermind-project-detail/SKILL.md} +2 -2
  118. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/project-workspace.md → mastermind-project-workspace/SKILL.md} +2 -2
  119. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/projects.md → mastermind-projects/SKILL.md} +2 -2
  120. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/_protocol.md → mastermind-protocol/SKILL.md} +3 -3
  121. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/release.md → mastermind-release/SKILL.md} +5 -5
  122. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/_repeat.md → mastermind-repeat/SKILL.md} +2 -2
  123. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/research.md → mastermind-research/SKILL.md} +5 -5
  124. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/review.md → mastermind-review/SKILL.md} +5 -5
  125. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/routine-detail.md → mastermind-routine-detail/SKILL.md} +2 -2
  126. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/routines.md → mastermind-routines/SKILL.md} +2 -2
  127. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/runorgv1.md → mastermind-runorgv1/SKILL.md} +2 -2
  128. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/sales.md → mastermind-sales/SKILL.md} +5 -5
  129. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/search.md → mastermind-search/SKILL.md} +2 -2
  130. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/secrets.md → mastermind-secrets/SKILL.md} +2 -2
  131. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/skill-builder.md → mastermind-skill-builder/SKILL.md} +16 -14
  132. package/packages/@monomind/cli/.claude/skills/mastermind-skills/{skills.md → SKILL.md} +2 -2
  133. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/stoporg.md → mastermind-stoporg/SKILL.md} +2 -2
  134. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/taskdev.md → mastermind-taskdev/SKILL.md} +6 -6
  135. package/packages/@monomind/cli/.claude/skills/{mastermind-skills → mastermind-taskdev}/implementer-prompt.md +1 -1
  136. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/tasks.md → mastermind-tasks/SKILL.md} +2 -2
  137. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/tdd.md → mastermind-tdd/SKILL.md} +4 -4
  138. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/techport.md → mastermind-techport/SKILL.md} +6 -6
  139. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/threads.md → mastermind-threads/SKILL.md} +2 -2
  140. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/tree-control.md → mastermind-tree-control/SKILL.md} +2 -2
  141. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/verify.md → mastermind-verify/SKILL.md} +1 -1
  142. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/wiki.md → mastermind-wiki/SKILL.md} +2 -2
  143. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/workspace-detail.md → mastermind-workspace-detail/SKILL.md} +2 -2
  144. package/packages/@monomind/cli/.claude/skills/{mastermind-skills/workspaces.md → mastermind-workspaces/SKILL.md} +2 -2
  145. package/packages/@monomind/cli/.claude/skills/monodesign/SKILL.md +114 -190
  146. package/packages/@monomind/cli/.claude/skills/monodesign/adapt.md +1 -1
  147. package/packages/@monomind/cli/.claude/skills/monodesign/agents/monodesign-asset-producer.md +4 -4
  148. package/packages/@monomind/cli/.claude/skills/monodesign/agents/monodesign-manual-edit-applier.md +103 -0
  149. package/packages/@monomind/cli/.claude/skills/monodesign/audit.md +1 -1
  150. package/packages/@monomind/cli/.claude/skills/monodesign/craft.md +2 -2
  151. package/packages/@monomind/cli/.claude/skills/monodesign/critique.md +1 -1
  152. package/packages/@monomind/cli/.claude/skills/monodesign/init.md +30 -0
  153. package/packages/@monomind/cli/.claude/skills/monodesign/layout.md +36 -0
  154. package/packages/@monomind/cli/.claude/skills/monodesign/live.md +19 -44
  155. package/packages/@monomind/cli/.claude/skills/monodesign/reference/adapt.md +122 -0
  156. package/packages/@monomind/cli/.claude/skills/monodesign/reference/adapt.native.md +58 -0
  157. package/packages/@monomind/cli/.claude/skills/monodesign/reference/android.md +40 -0
  158. package/packages/@monomind/cli/.claude/skills/monodesign/reference/animate.md +39 -11
  159. package/packages/@monomind/cli/.claude/skills/monodesign/reference/antipatterns-catalog.md +67 -16
  160. package/packages/@monomind/cli/.claude/skills/monodesign/reference/audit.md +5 -3
  161. package/packages/@monomind/cli/.claude/skills/monodesign/reference/audit.native.md +139 -0
  162. package/packages/@monomind/cli/.claude/skills/monodesign/reference/bolder.md +71 -64
  163. package/packages/@monomind/cli/.claude/skills/monodesign/reference/brand.md +12 -18
  164. package/packages/@monomind/cli/.claude/skills/monodesign/reference/clarify.md +114 -0
  165. package/packages/@monomind/cli/.claude/skills/monodesign/reference/codex.md +4 -6
  166. package/packages/@monomind/cli/.claude/skills/monodesign/reference/colorize.md +108 -5
  167. package/packages/@monomind/cli/.claude/skills/monodesign/reference/craft.md +70 -143
  168. package/packages/@monomind/cli/.claude/skills/monodesign/reference/critique.md +635 -68
  169. package/packages/@monomind/cli/.claude/skills/monodesign/reference/delight.md +1 -1
  170. package/packages/@monomind/cli/.claude/skills/monodesign/reference/distill.md +1 -1
  171. package/packages/@monomind/cli/.claude/skills/monodesign/reference/document.md +24 -22
  172. package/packages/@monomind/cli/.claude/skills/monodesign/reference/extract.md +1 -1
  173. package/packages/@monomind/cli/.claude/skills/monodesign/reference/hooks.md +22 -29
  174. package/packages/@monomind/cli/.claude/skills/monodesign/reference/init.md +221 -0
  175. package/packages/@monomind/cli/.claude/skills/monodesign/reference/interaction-design.md +0 -6
  176. package/packages/@monomind/cli/.claude/skills/monodesign/reference/ios.md +45 -0
  177. package/packages/@monomind/cli/.claude/skills/monodesign/reference/layout.md +57 -13
  178. package/packages/@monomind/cli/.claude/skills/monodesign/reference/live.md +159 -71
  179. package/packages/@monomind/cli/.claude/skills/monodesign/reference/overdrive.md +1 -1
  180. package/packages/@monomind/cli/.claude/skills/monodesign/reference/personas.md +1 -1
  181. package/packages/@monomind/cli/.claude/skills/monodesign/reference/polish.md +16 -8
  182. package/packages/@monomind/cli/.claude/skills/monodesign/reference/pre-delivery-checklist.md +1 -1
  183. package/packages/@monomind/cli/.claude/skills/monodesign/reference/product.md +1 -3
  184. package/packages/@monomind/cli/.claude/skills/monodesign/reference/quieter.md +1 -1
  185. package/packages/@monomind/cli/.claude/skills/monodesign/reference/shape.md +27 -13
  186. package/packages/@monomind/cli/.claude/skills/monodesign/reference/teach.md +6 -152
  187. package/packages/@monomind/cli/.claude/skills/monodesign/reference/typeset.md +180 -3
  188. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/command-metadata.json +94 -0
  189. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/context-signals.mjs +260 -0
  190. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/context.mjs +1061 -0
  191. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/critique-storage.mjs +416 -0
  192. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/detect-csp.mjs +198 -0
  193. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/detect.mjs +33 -0
  194. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/detector/browser/injected/index.mjs +1962 -0
  195. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/detector/cli/main.mjs +321 -0
  196. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/detector/design-system.mjs +814 -0
  197. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/detector/detect-antipatterns-browser.js +5601 -0
  198. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/detector/detect-antipatterns.mjs +50 -0
  199. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/detector/engines/browser/detect-url.mjs +259 -0
  200. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/detector/engines/browser/drivers.mjs +258 -0
  201. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/detector/engines/regex/detect-text.mjs +636 -0
  202. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/detector/engines/static-html/css-cascade.mjs +1015 -0
  203. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/detector/engines/static-html/detect-html.mjs +253 -0
  204. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/detector/engines/visual/screenshot-contrast.mjs +198 -0
  205. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/detector/findings.mjs +12 -0
  206. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/detector/fix/css-regions.mjs +181 -0
  207. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/detector/fix/fixers.mjs +373 -0
  208. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/detector/fix/index.mjs +426 -0
  209. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/detector/node/file-system.mjs +198 -0
  210. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/detector/profile/profiler.mjs +166 -0
  211. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/detector/registry/antipatterns.mjs +563 -0
  212. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/detector/rules/checks.mjs +2995 -0
  213. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/detector/shared/color.mjs +124 -0
  214. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/detector/shared/constants.mjs +101 -0
  215. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/detector/shared/fonts.mjs +30 -0
  216. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/detector/shared/inline-ignores.mjs +148 -0
  217. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/detector/shared/page.mjs +7 -0
  218. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/hook-admin.mjs +661 -0
  219. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/hook-before-edit.mjs +516 -0
  220. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/hook-lib.mjs +1776 -0
  221. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/hook.mjs +61 -0
  222. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/lib/design-parser.mjs +842 -0
  223. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/lib/is-generated.mjs +69 -0
  224. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/lib/monodesign-config.mjs +640 -0
  225. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/lib/monodesign-paths.mjs +129 -0
  226. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/lib/provider.mjs +4 -0
  227. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/lib/target-args.mjs +42 -0
  228. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/live/browser-script-parts.mjs +50 -0
  229. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/live/completion.mjs +19 -0
  230. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/live/event-validation.mjs +137 -0
  231. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/live/insert-ui.mjs +458 -0
  232. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/live/manual-apply.mjs +939 -0
  233. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/live/manual-edit-routes.mjs +357 -0
  234. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/live/manual-edits-buffer.mjs +152 -0
  235. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/live/session-store.mjs +293 -0
  236. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/live/svelte-component.mjs +826 -0
  237. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/live/sveltekit-adapter.mjs +274 -0
  238. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/live/ui-core.mjs +180 -0
  239. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/live/vocabulary.mjs +36 -0
  240. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/live-accept.mjs +812 -0
  241. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/live-browser-dom.js +146 -0
  242. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/live-browser-session.js +123 -0
  243. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/live-browser.js +11240 -0
  244. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/live-commit-manual-edits.mjs +1241 -0
  245. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/live-complete.mjs +75 -0
  246. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/live-copy-edit-agent.mjs +683 -0
  247. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/live-discard-manual-edits.mjs +51 -0
  248. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/live-inject.mjs +583 -0
  249. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/live-insert.mjs +272 -0
  250. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/live-manual-edit-evidence.mjs +363 -0
  251. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/live-poll.mjs +384 -0
  252. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/live-resume.mjs +94 -0
  253. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/live-server.mjs +1137 -0
  254. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/live-status.mjs +61 -0
  255. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/live-target.mjs +30 -0
  256. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/live-wrap.mjs +894 -0
  257. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/live.mjs +297 -0
  258. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/modern-screenshot.umd.js +14 -0
  259. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/palette.mjs +633 -0
  260. package/packages/@monomind/cli/.claude/skills/monodesign/scripts/pin.mjs +221 -0
  261. package/packages/@monomind/cli/.claude/skills/monodesign/teach.md +7 -58
  262. package/packages/@monomind/cli/README.md +1 -1
  263. package/packages/@monomind/cli/dist/src/commands/design-detect.d.ts +7 -1
  264. package/packages/@monomind/cli/dist/src/commands/design-detect.js +131 -38
  265. package/packages/@monomind/cli/dist/src/commands/design-palette.d.ts +0 -1
  266. package/packages/@monomind/cli/dist/src/commands/design-palette.js +2 -3
  267. package/packages/@monomind/cli/dist/src/commands/doc.js +72 -15
  268. package/packages/@monomind/cli/dist/src/commands/doctor-project-checks.d.ts +5 -1
  269. package/packages/@monomind/cli/dist/src/commands/doctor-project-checks.js +24 -1
  270. package/packages/@monomind/cli/dist/src/commands/doctor.js +3 -3
  271. package/packages/@monomind/cli/dist/src/commands/hooks-workers.d.ts +1 -1
  272. package/packages/@monomind/cli/dist/src/commands/hooks-workers.js +8 -8
  273. package/packages/@monomind/cli/dist/src/commands/init.js +2 -2
  274. package/packages/@monomind/cli/dist/src/commands/org.js +109 -9
  275. package/packages/@monomind/cli/dist/src/index.d.ts +1 -1
  276. package/packages/@monomind/cli/dist/src/index.js +3 -3
  277. package/packages/@monomind/cli/dist/src/init/claudemd-generator.js +5 -5
  278. package/packages/@monomind/cli/dist/src/init/executor.js +17 -6
  279. package/packages/@monomind/cli/dist/src/knowledge/document-pipeline.d.ts +2 -0
  280. package/packages/@monomind/cli/dist/src/knowledge/document-pipeline.js +4 -1
  281. package/packages/@monomind/cli/dist/src/mcp-server.js +2 -2
  282. package/packages/@monomind/cli/dist/src/mcp-tools/hooks-intelligence.d.ts +1 -1
  283. package/packages/@monomind/cli/dist/src/mcp-tools/hooks-intelligence.js +1 -1
  284. package/packages/@monomind/cli/dist/src/mcp-tools/hooks-routing.js +2 -2
  285. package/packages/@monomind/cli/dist/src/mcp-tools/hooks-tools.js +1 -1
  286. package/packages/@monomind/cli/dist/src/mcp-tools/knowledge-tools.js +38 -7
  287. package/packages/@monomind/cli/dist/src/mcp-tools/memory-tools.d.ts +8 -3
  288. package/packages/@monomind/cli/dist/src/mcp-tools/memory-tools.js +193 -31
  289. package/packages/@monomind/cli/dist/src/memory/memory-bridge.d.ts +33 -0
  290. package/packages/@monomind/cli/dist/src/memory/memory-bridge.js +166 -17
  291. package/packages/@monomind/cli/dist/src/memory/memory-kg.d.ts +186 -0
  292. package/packages/@monomind/cli/dist/src/memory/memory-kg.js +450 -0
  293. package/packages/@monomind/cli/dist/src/memory/query-router.d.ts +44 -0
  294. package/packages/@monomind/cli/dist/src/memory/query-router.js +113 -0
  295. package/packages/@monomind/cli/dist/src/orgrt/daemon.d.ts +18 -0
  296. package/packages/@monomind/cli/dist/src/orgrt/daemon.js +249 -12
  297. package/packages/@monomind/cli/dist/src/orgrt/migrate.js +7 -0
  298. package/packages/@monomind/cli/dist/src/orgrt/policy.js +7 -0
  299. package/packages/@monomind/cli/dist/src/orgrt/session.d.ts +24 -1
  300. package/packages/@monomind/cli/dist/src/orgrt/session.js +18 -3
  301. package/packages/@monomind/cli/dist/src/orgrt/templates.d.ts +1 -0
  302. package/packages/@monomind/cli/dist/src/orgrt/templates.js +9 -4
  303. package/packages/@monomind/cli/dist/src/orgrt/types.d.ts +15 -0
  304. package/packages/@monomind/cli/dist/src/orgrt/types.js +2 -0
  305. package/packages/@monomind/cli/dist/src/routing/embed-worker.js +1 -1
  306. package/packages/@monomind/cli/dist/src/routing/llm-caller.js +1 -1
  307. package/packages/@monomind/cli/dist/src/routing/route-layer-factory.js +1 -1
  308. package/packages/@monomind/cli/dist/src/ui/dashboard.html +176 -26
  309. package/packages/@monomind/cli/dist/src/ui/orgs.html +24 -0
  310. package/packages/@monomind/cli/dist/src/ui/server.mjs +162 -12
  311. package/packages/@monomind/cli/dist/src/update/checker.js +3 -3
  312. package/packages/@monomind/cli/package.json +8 -6
  313. /package/packages/@monomind/cli/.claude/skills/{mastermind-skills/_agent-select.md → mastermind-agent-select/SKILL.md} +0 -0
  314. /package/packages/@monomind/cli/.claude/skills/{mastermind-skills/finish.md → mastermind-finish/SKILL.md} +0 -0
  315. /package/packages/@monomind/cli/.claude/skills/{mastermind-skills/_intake.md → mastermind-intake/SKILL.md} +0 -0
  316. /package/packages/@monomind/cli/.claude/skills/{mastermind-skills → mastermind-marketing}/references/copywriting-frameworks.md +0 -0
  317. /package/packages/@monomind/cli/.claude/skills/{mastermind-skills → mastermind-marketing}/references/persuasion-psychology.md +0 -0
  318. /package/packages/@monomind/cli/.claude/skills/{mastermind-skills/monotask.md → mastermind-monotask/SKILL.md} +0 -0
  319. /package/packages/@monomind/cli/.claude/skills/{mastermind-skills/receive-review.md → mastermind-receive-review/SKILL.md} +0 -0
  320. /package/packages/@monomind/cli/.claude/skills/{mastermind-skills/runorg.md → mastermind-runorg/SKILL.md} +0 -0
  321. /package/packages/@monomind/cli/.claude/skills/{mastermind-skills → mastermind-taskdev}/code-quality-reviewer-prompt.md +0 -0
  322. /package/packages/@monomind/cli/.claude/skills/{mastermind-skills → mastermind-taskdev}/final-reviewer-prompt.md +0 -0
  323. /package/packages/@monomind/cli/.claude/skills/{mastermind-skills → mastermind-taskdev}/spec-reviewer-prompt.md +0 -0
  324. /package/packages/@monomind/cli/.claude/skills/{mastermind-skills/worktree.md → mastermind-worktree/SKILL.md} +0 -0
@@ -0,0 +1,426 @@
1
+ /**
2
+ * Auto-fix engine: detect -> apply safe codemods -> re-detect -> report.
3
+ *
4
+ * Single-pass by design: every fixer is idempotent and lands values on the
5
+ * safe side of its detector threshold, so the re-detect step only verifies —
6
+ * it never triggers another round of edits (no oscillation).
7
+ *
8
+ * Honors the same filter pipeline as `detect`: project config ignores
9
+ * (.monodesign/config.json), inline monodesign-disable* directives, and file
10
+ * ignores — an ignored finding is never "fixed".
11
+ */
12
+
13
+ import fs from 'node:fs';
14
+ import path from 'node:path';
15
+
16
+ import { loadDesignSystemForCwd } from '../design-system.mjs';
17
+ import { detectHtml } from '../engines/static-html/detect-html.mjs';
18
+ import { detectText } from '../engines/regex/detect-text.mjs';
19
+ import {
20
+ filterDetectionFindings,
21
+ readDetectionConfig,
22
+ shouldIgnoreDetectionFile,
23
+ } from '../../lib/monodesign-config.mjs';
24
+ import { HTML_EXTENSIONS, walkDir } from '../node/file-system.mjs';
25
+ import { UNFIXABLE_REASONS, getFixer, fixableRuleIds, FIXERS } from './fixers.mjs';
26
+
27
+ // ---------------------------------------------------------------------------
28
+ // Edit application
29
+ // ---------------------------------------------------------------------------
30
+
31
+ /** Apply edits to content. Edits are sorted; overlapping edits are dropped
32
+ * (first wins). Returns { content, applied } — applied lists the edits used. */
33
+ function applyEdits(content, edits) {
34
+ const sorted = [...edits].sort((a, b) => a.start - b.start || a.end - b.end);
35
+ const kept = [];
36
+ let lastEnd = -1;
37
+ for (const edit of sorted) {
38
+ if (edit.start < lastEnd) continue; // overlap — first edit wins
39
+ kept.push(edit);
40
+ lastEnd = Math.max(edit.end, edit.start);
41
+ }
42
+ let result = content;
43
+ for (let i = kept.length - 1; i >= 0; i--) {
44
+ const { start, end, replacement } = kept[i];
45
+ result = result.slice(0, start) + replacement + result.slice(end);
46
+ }
47
+ return { content: result, applied: kept };
48
+ }
49
+
50
+ /** Atomic write: temp file in the same directory, then rename over target. */
51
+ function writeFileAtomic(filePath, content) {
52
+ const tmp = path.join(
53
+ path.dirname(filePath),
54
+ `.${path.basename(filePath)}.${process.pid}.monodesign-tmp`,
55
+ );
56
+ fs.writeFileSync(tmp, content, 'utf-8');
57
+ fs.renameSync(tmp, filePath);
58
+ }
59
+
60
+ // ---------------------------------------------------------------------------
61
+ // Unified diff (minimal single-hunk implementation for --dry-run)
62
+ // ---------------------------------------------------------------------------
63
+
64
+ function unifiedDiff(oldText, newText, label) {
65
+ if (oldText === newText) return '';
66
+ const a = oldText.split('\n');
67
+ const b = newText.split('\n');
68
+ let p = 0;
69
+ while (p < a.length && p < b.length && a[p] === b[p]) p++;
70
+ let s = 0;
71
+ while (s < a.length - p && s < b.length - p && a[a.length - 1 - s] === b[b.length - 1 - s]) s++;
72
+ const aEnd = a.length - s;
73
+ const bEnd = b.length - s;
74
+ const ctxStart = Math.max(0, p - 3);
75
+ const ctxEnd = Math.min(a.length, aEnd + 3);
76
+ const oldLen = ctxEnd - ctxStart;
77
+ const newLen = (p - ctxStart) + (bEnd - p) + (ctxEnd - aEnd);
78
+ const lines = [`--- a/${label}`, `+++ b/${label}`, `@@ -${ctxStart + 1},${oldLen} +${ctxStart + 1},${newLen} @@`];
79
+ for (let i = ctxStart; i < p; i++) lines.push(` ${a[i]}`);
80
+ for (let i = p; i < aEnd; i++) lines.push(`-${a[i]}`);
81
+ for (let i = p; i < bEnd; i++) lines.push(`+${b[i]}`);
82
+ for (let i = aEnd; i < ctxEnd; i++) lines.push(` ${a[i]}`);
83
+ return lines.join('\n');
84
+ }
85
+
86
+ // ---------------------------------------------------------------------------
87
+ // Linked stylesheet resolution (HTML findings whose declaration lives in CSS)
88
+ // ---------------------------------------------------------------------------
89
+
90
+ function extractLinkedStylesheets(html, htmlPath) {
91
+ const out = [];
92
+ const linkRe = /<link\b[^>]*>/gi;
93
+ let m;
94
+ while ((m = linkRe.exec(html)) !== null) {
95
+ const tag = m[0];
96
+ if (!/rel\s*=\s*["']?stylesheet/i.test(tag)) continue;
97
+ const href = tag.match(/href\s*=\s*["']([^"']+)["']/i)?.[1];
98
+ if (!href || /^(?:https?:)?\/\//i.test(href) || href.startsWith('data:')) continue;
99
+ const resolved = path.resolve(path.dirname(htmlPath), href.split(/[?#]/)[0]);
100
+ if (fs.existsSync(resolved)) out.push(resolved);
101
+ }
102
+ return out;
103
+ }
104
+
105
+ // ---------------------------------------------------------------------------
106
+ // Fix run
107
+ // ---------------------------------------------------------------------------
108
+
109
+ function groupByRule(findings) {
110
+ const byRule = new Map();
111
+ for (const f of findings) {
112
+ if (!byRule.has(f.antipattern)) byRule.set(f.antipattern, []);
113
+ byRule.get(f.antipattern).push(f);
114
+ }
115
+ return byRule;
116
+ }
117
+
118
+ /**
119
+ * Run the fix loop over file/directory targets.
120
+ *
121
+ * options:
122
+ * cwd — project root for config + design-system loading
123
+ * dryRun — compute edits and diffs; write nothing
124
+ * rules — restrict fixing to these rule ids
125
+ * noConfig — skip project config + inline-ignore filtering
126
+ *
127
+ * Returns a report:
128
+ * { dryRun, fixed, remaining, skipped, filesChanged, diffs, warnings }
129
+ */
130
+ async function runFix(targets, options = {}) {
131
+ const cwd = options.cwd || process.cwd();
132
+ const dryRun = Boolean(options.dryRun);
133
+ const ruleFilter = options.rules && options.rules.length ? new Set(options.rules) : null;
134
+ const config = options.noConfig
135
+ ? { ignoreRules: [], ignoreFiles: [], ignoreValues: [] }
136
+ : readDetectionConfig(cwd);
137
+ const designSystemEnabled = !options.noConfig && config.designSystem?.enabled !== false;
138
+ const designSystem = designSystemEnabled ? loadDesignSystemForCwd(cwd) : null;
139
+ const scanOptions = { providers: [], inlineIgnores: !options.noConfig };
140
+ if (designSystem) scanOptions.designSystem = designSystem;
141
+
142
+ const warnings = [];
143
+ const files = [];
144
+ for (const target of targets) {
145
+ if (/^https?:\/\//i.test(target)) {
146
+ warnings.push(`Skipping URL target ${target}: fix operates on local files only.`);
147
+ continue;
148
+ }
149
+ const resolved = path.resolve(cwd, target);
150
+ let stat;
151
+ try { stat = fs.statSync(resolved); }
152
+ catch { warnings.push(`Warning: cannot access ${target}`); continue; }
153
+ if (stat.isDirectory()) {
154
+ files.push(...walkDir(resolved).filter(f => !shouldIgnoreDetectionFile(f, cwd, config)));
155
+ } else if (!shouldIgnoreDetectionFile(resolved, cwd, config)) {
156
+ files.push(resolved);
157
+ }
158
+ }
159
+ const uniqueFiles = [...new Set(files)];
160
+
161
+ const detectFile = async (file) => {
162
+ const ext = path.extname(file).toLowerCase();
163
+ const found = HTML_EXTENSIONS.has(ext)
164
+ ? await detectHtml(file, scanOptions)
165
+ : detectText(fs.readFileSync(file, 'utf-8'), file, scanOptions);
166
+ return filterDetectionFindings(found, config);
167
+ };
168
+
169
+ // 1. Detect
170
+ const findingsByFile = new Map();
171
+ for (const file of uniqueFiles) {
172
+ const found = await detectFile(file);
173
+ if (found.length > 0) findingsByFile.set(file, found);
174
+ }
175
+
176
+ // 2. Plan + apply fixes in memory. Buffers exist only for files that carry
177
+ // findings (or are stylesheets linked from such a file) — files with no
178
+ // findings are never touched.
179
+ const buffers = new Map(); // path -> { original, content, changed, parents:Set }
180
+ const loadBuffer = (file) => {
181
+ let buf = buffers.get(file);
182
+ if (!buf) {
183
+ const original = fs.readFileSync(file, 'utf-8');
184
+ buf = { original, content: original, changed: false, parents: new Set() };
185
+ buffers.set(file, buf);
186
+ }
187
+ return buf;
188
+ };
189
+
190
+ const skipped = []; // { file, antipattern, count, reason }
191
+ const attempts = []; // { file, antipattern, before, notes, targetFile }
192
+
193
+ for (const [file, findings] of findingsByFile) {
194
+ const ext = path.extname(file).toLowerCase();
195
+ for (const [rule, ruleFindings] of groupByRule(findings)) {
196
+ const count = ruleFindings.length;
197
+ if (ruleFilter && !ruleFilter.has(rule)) {
198
+ skipped.push({ file, antipattern: rule, count, reason: 'excluded by --rule' });
199
+ continue;
200
+ }
201
+ const fixer = getFixer(rule);
202
+ if (!fixer) {
203
+ skipped.push({
204
+ file,
205
+ antipattern: rule,
206
+ count,
207
+ reason: UNFIXABLE_REASONS[rule] || 'no deterministic safe fix exists for this rule',
208
+ });
209
+ continue;
210
+ }
211
+ const buf = loadBuffer(file);
212
+ let edits = fixer.fix(buf.content, ext);
213
+ let targetFile = file;
214
+ if (edits.length === 0 && HTML_EXTENSIONS.has(ext)) {
215
+ // The offending declaration may live in a linked stylesheet — the
216
+ // detector cascades linked CSS into HTML findings.
217
+ for (const cssPath of extractLinkedStylesheets(buf.original, file)) {
218
+ const cssBuf = loadBuffer(cssPath);
219
+ const cssEdits = fixer.fix(cssBuf.content, path.extname(cssPath).toLowerCase());
220
+ if (cssEdits.length > 0) {
221
+ edits = cssEdits;
222
+ targetFile = cssPath;
223
+ cssBuf.parents.add(file);
224
+ break;
225
+ }
226
+ }
227
+ }
228
+ if (edits.length === 0) {
229
+ skipped.push({
230
+ file,
231
+ antipattern: rule,
232
+ count,
233
+ reason: 'no safely rewritable declaration found in source',
234
+ });
235
+ continue;
236
+ }
237
+ const targetBuf = loadBuffer(targetFile);
238
+ const { content, applied } = applyEdits(targetBuf.content, edits);
239
+ if (content !== targetBuf.content) {
240
+ targetBuf.content = content;
241
+ targetBuf.changed = true;
242
+ }
243
+ attempts.push({
244
+ file,
245
+ antipattern: rule,
246
+ before: count,
247
+ targetFile,
248
+ notes: applied.map(e => e.note).filter(Boolean),
249
+ });
250
+ }
251
+ }
252
+
253
+ const changedFiles = [...buffers.entries()].filter(([, b]) => b.changed);
254
+ const filesChanged = changedFiles.map(([p]) => p);
255
+
256
+ // 3. Write (atomic) or diff (dry-run)
257
+ const diffs = [];
258
+ if (dryRun) {
259
+ for (const [p, b] of changedFiles) {
260
+ diffs.push({ file: p, diff: unifiedDiff(b.original, b.content, path.relative(cwd, p) || p) });
261
+ }
262
+ } else {
263
+ for (const [p, b] of changedFiles) writeFileAtomic(p, b.content);
264
+ }
265
+
266
+ // 4. Re-detect touched files to verify (skip in dry-run — nothing changed
267
+ // on disk). Linked-CSS edits are verified through their parent HTML.
268
+ const remaining = [];
269
+ if (!dryRun && changedFiles.length > 0) {
270
+ const recheck = new Set();
271
+ for (const [p, b] of changedFiles) {
272
+ if (findingsByFile.has(p)) recheck.add(p);
273
+ for (const parent of b.parents) recheck.add(parent);
274
+ }
275
+ const after = new Map();
276
+ for (const p of recheck) after.set(p, await detectFile(p));
277
+ for (const attempt of attempts) {
278
+ const afterFindings = after.get(attempt.file) || [];
279
+ const stillThere = afterFindings.filter(f => f.antipattern === attempt.antipattern).length;
280
+ attempt.after = stillThere;
281
+ attempt.fixed = Math.max(0, attempt.before - stillThere);
282
+ if (stillThere > 0) {
283
+ remaining.push({ file: attempt.file, antipattern: attempt.antipattern, count: stillThere });
284
+ }
285
+ }
286
+ } else {
287
+ for (const attempt of attempts) {
288
+ attempt.after = dryRun ? null : attempt.before;
289
+ attempt.fixed = dryRun ? attempt.before : 0;
290
+ }
291
+ }
292
+
293
+ return {
294
+ dryRun,
295
+ fixed: attempts.map(a => ({
296
+ file: a.file,
297
+ antipattern: a.antipattern,
298
+ before: a.before,
299
+ after: a.after,
300
+ fixed: a.fixed,
301
+ targetFile: a.targetFile,
302
+ notes: a.notes,
303
+ })),
304
+ remaining,
305
+ skipped,
306
+ filesChanged,
307
+ diffs,
308
+ warnings,
309
+ };
310
+ }
311
+
312
+ // ---------------------------------------------------------------------------
313
+ // CLI
314
+ // ---------------------------------------------------------------------------
315
+
316
+ function printFixUsage() {
317
+ console.log(`Usage: monodesign fix [options] <file-or-dir...>
318
+
319
+ Auto-fix detector findings where a deterministic, safe codemod exists.
320
+ Runs detect, applies fixes, re-detects to verify, and reports
321
+ fixed / remaining / skipped findings. Files without findings are never touched.
322
+
323
+ Options:
324
+ --dry-run Print unified diffs of would-be changes; write nothing
325
+ --json Output the fix report as JSON
326
+ --rule <id,...> Only fix the given rule ids
327
+ --no-config Skip project config and inline-ignore filtering
328
+ --help Show this help message
329
+
330
+ Fixable rules:
331
+ ${Object.entries(FIXERS).map(([id, f]) => ` ${id.padEnd(26)} ${f.description}`).join('\n')}
332
+
333
+ Everything else is reported as skipped with a reason (e.g. broken-image:
334
+ choosing a real image is a content decision, not a codemod).
335
+
336
+ Examples:
337
+ monodesign fix src/
338
+ monodesign fix --dry-run index.html
339
+ monodesign fix --rule tight-leading,tiny-text styles.css`);
340
+ }
341
+
342
+ function formatFixReport(report, jsonMode) {
343
+ if (jsonMode) return JSON.stringify(report, null, 2);
344
+ const out = [];
345
+ if (report.dryRun) {
346
+ for (const { diff } of report.diffs) {
347
+ if (diff) out.push(diff, '');
348
+ }
349
+ }
350
+ const verb = report.dryRun ? 'would fix' : 'fixed';
351
+ for (const item of report.fixed) {
352
+ const where = item.targetFile && item.targetFile !== item.file
353
+ ? `${item.file} (edited ${item.targetFile})`
354
+ : item.file;
355
+ out.push(`${verb} [${item.antipattern}] ${item.fixed}/${item.before} in ${where}`);
356
+ }
357
+ for (const item of report.remaining) {
358
+ out.push(`remaining [${item.antipattern}] ${item.count} in ${item.file}`);
359
+ }
360
+ for (const item of report.skipped) {
361
+ out.push(`skipped [${item.antipattern}] ${item.count} in ${item.file} — ${item.reason}`);
362
+ }
363
+ const fixedTotal = report.fixed.reduce((n, f) => n + (f.fixed || 0), 0);
364
+ const remainingTotal = report.remaining.reduce((n, f) => n + f.count, 0);
365
+ const skippedTotal = report.skipped.reduce((n, f) => n + f.count, 0);
366
+ out.push(`\n${report.dryRun ? 'Would fix' : 'Fixed'} ${fixedTotal}, remaining ${remainingTotal}, skipped ${skippedTotal}. ${report.filesChanged.length} file${report.filesChanged.length === 1 ? '' : 's'} ${report.dryRun ? 'would change' : 'changed'}.`);
367
+ return out.join('\n');
368
+ }
369
+
370
+ async function runFixCli(args) {
371
+ const targets = [];
372
+ const options = { dryRun: false, rules: null, noConfig: false };
373
+ let jsonMode = false;
374
+ for (let i = 0; i < args.length; i++) {
375
+ const arg = args[i];
376
+ if (arg === '--help' || arg === '-h') { printFixUsage(); process.exit(0); }
377
+ else if (arg === '--dry-run') options.dryRun = true;
378
+ else if (arg === '--json') jsonMode = true;
379
+ else if (arg === '--no-config') options.noConfig = true;
380
+ else if (arg === '--rule' || arg.startsWith('--rule=')) {
381
+ const value = arg.startsWith('--rule=') ? arg.slice('--rule='.length) : args[++i];
382
+ if (!value || value.startsWith('--')) {
383
+ process.stderr.write('Error: --rule requires a comma-separated list of rule ids.\n');
384
+ process.exit(1);
385
+ }
386
+ options.rules = [...(options.rules || []), ...value.split(',').map(s => s.trim()).filter(Boolean)];
387
+ } else if (arg.startsWith('--')) {
388
+ process.stderr.write(`Error: unknown option ${arg}\n\nRun: monodesign fix --help\n`);
389
+ process.exit(1);
390
+ } else {
391
+ targets.push(arg);
392
+ }
393
+ }
394
+
395
+ if (options.rules) {
396
+ const fixable = new Set(fixableRuleIds());
397
+ const unknown = options.rules.filter(r => !fixable.has(r));
398
+ if (unknown.length > 0) {
399
+ process.stderr.write(`Error: no fixer for rule(s): ${unknown.join(', ')}.\nFixable rules: ${fixableRuleIds().join(', ')}\n`);
400
+ process.exit(1);
401
+ }
402
+ }
403
+
404
+ if (targets.length === 0) {
405
+ process.stderr.write('Error: fix requires at least one file or directory target.\n\nRun: monodesign fix --help\n');
406
+ process.exit(1);
407
+ }
408
+
409
+ const report = await runFix(targets, options);
410
+ for (const warning of report.warnings) process.stderr.write(`${warning}\n`);
411
+ const formatted = formatFixReport(report, jsonMode);
412
+ if (jsonMode || report.dryRun) process.stdout.write(formatted + '\n');
413
+ else process.stderr.write(formatted + '\n');
414
+ process.exit(!report.dryRun && report.remaining.length > 0 ? 2 : 0);
415
+ }
416
+
417
+ export {
418
+ runFix,
419
+ runFixCli,
420
+ applyEdits,
421
+ unifiedDiff,
422
+ writeFileAtomic,
423
+ extractLinkedStylesheets,
424
+ printFixUsage,
425
+ formatFixReport,
426
+ };
@@ -0,0 +1,198 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+
4
+ // ---------------------------------------------------------------------------
5
+ // File walker
6
+ // ---------------------------------------------------------------------------
7
+
8
+ const SKIP_DIRS = new Set([
9
+ 'node_modules', '.git', 'dist', 'build', '.next', '.nuxt', '.output',
10
+ '.svelte-kit', '__pycache__', '.turbo', '.vercel',
11
+ ]);
12
+
13
+ const SCANNABLE_EXTENSIONS = new Set([
14
+ '.html', '.htm', '.css', '.scss', '.sass', '.less',
15
+ '.jsx', '.tsx', '.js', '.ts',
16
+ '.vue', '.svelte', '.astro',
17
+ ]);
18
+
19
+ const HTML_EXTENSIONS = new Set(['.html', '.htm']);
20
+
21
+ function walkDir(dir) {
22
+ const files = [];
23
+ let entries;
24
+ try { entries = fs.readdirSync(dir, { withFileTypes: true }); } catch { return files; }
25
+ for (const entry of entries) {
26
+ if (SKIP_DIRS.has(entry.name)) continue;
27
+ const full = path.join(dir, entry.name);
28
+ if (entry.isDirectory()) files.push(...walkDir(full));
29
+ else if (SCANNABLE_EXTENSIONS.has(path.extname(entry.name).toLowerCase())) files.push(full);
30
+ }
31
+ return files;
32
+ }
33
+
34
+
35
+ // ---------------------------------------------------------------------------
36
+ // Import graph (multi-file awareness)
37
+ // ---------------------------------------------------------------------------
38
+
39
+ function resolveImport(specifier, fromDir, fileSet) {
40
+ if (!/^[./]/.test(specifier)) return null; // skip bare specifiers
41
+ const base = path.resolve(fromDir, specifier);
42
+ if (fileSet.has(base)) return base;
43
+ for (const ext of SCANNABLE_EXTENSIONS) {
44
+ const withExt = base + ext;
45
+ if (fileSet.has(withExt)) return withExt;
46
+ }
47
+ // index file convention
48
+ for (const ext of SCANNABLE_EXTENSIONS) {
49
+ const indexFile = path.join(base, 'index' + ext);
50
+ if (fileSet.has(indexFile)) return indexFile;
51
+ }
52
+ return null;
53
+ }
54
+
55
+ function buildImportGraph(files) {
56
+ const fileSet = new Set(files);
57
+ const graph = new Map();
58
+
59
+ for (const file of files) {
60
+ const content = fs.readFileSync(file, 'utf-8');
61
+ const dir = path.dirname(file);
62
+ const imports = new Set();
63
+
64
+ // ES imports: import ... from '...' and import '...'
65
+ const esRe = /import\s+(?:[\s\S]*?from\s+)?['"]([^'"]+)['"]/g;
66
+ let m;
67
+ while ((m = esRe.exec(content)) !== null) {
68
+ const resolved = resolveImport(m[1], dir, fileSet);
69
+ if (resolved) imports.add(resolved);
70
+ }
71
+
72
+ // CSS @import
73
+ const cssRe = /@import\s+(?:url\(\s*)?['"]?([^'");\s]+)['"]?\s*\)?/g;
74
+ while ((m = cssRe.exec(content)) !== null) {
75
+ const resolved = resolveImport(m[1], dir, fileSet);
76
+ if (resolved) imports.add(resolved);
77
+ }
78
+
79
+ // SCSS @use / @forward
80
+ const scssRe = /@(?:use|forward)\s+['"]([^'"]+)['"]/g;
81
+ while ((m = scssRe.exec(content)) !== null) {
82
+ const resolved = resolveImport(m[1], dir, fileSet);
83
+ if (resolved) imports.add(resolved);
84
+ }
85
+
86
+ graph.set(file, imports);
87
+ }
88
+ return graph;
89
+ }
90
+
91
+ // ---------------------------------------------------------------------------
92
+ // Framework dev server detection
93
+ // ---------------------------------------------------------------------------
94
+
95
+ const FRAMEWORK_CONFIGS = [
96
+ { name: 'Next.js', files: ['next.config.js', 'next.config.mjs', 'next.config.ts'], defaultPort: 3000,
97
+ portRe: /port\s*[:=]\s*(\d+)/,
98
+ fingerprint: { header: 'x-powered-by', value: /next/i } },
99
+ { name: 'SvelteKit', files: ['svelte.config.js', 'svelte.config.ts'], defaultPort: 5173,
100
+ portRe: /port\s*[:=]\s*(\d+)/,
101
+ fingerprint: { header: 'x-sveltekit-page', value: null } },
102
+ { name: 'Nuxt', files: ['nuxt.config.js', 'nuxt.config.ts'], defaultPort: 3000,
103
+ portRe: /port\s*[:=]\s*(\d+)/,
104
+ fingerprint: { header: 'x-powered-by', value: /nuxt/i } },
105
+ { name: 'Vite', files: ['vite.config.js', 'vite.config.ts', 'vite.config.mjs'], defaultPort: 5173,
106
+ portRe: /port\s*[:=]\s*(\d+)/,
107
+ fingerprint: { body: /@vite\/client/ } },
108
+ { name: 'Astro', files: ['astro.config.js', 'astro.config.ts', 'astro.config.mjs'], defaultPort: 4321,
109
+ portRe: /port\s*[:=]\s*(\d+)/,
110
+ fingerprint: { body: /astro/i } },
111
+ { name: 'Angular', files: ['angular.json'], defaultPort: 4200,
112
+ portRe: /"port"\s*:\s*(\d+)/,
113
+ fingerprint: { body: /ng-version/i } },
114
+ { name: 'Remix', files: ['remix.config.js', 'remix.config.ts'], defaultPort: 3000,
115
+ portRe: /port\s*[:=]\s*(\d+)/,
116
+ fingerprint: { header: 'x-powered-by', value: /remix/i } },
117
+ ];
118
+
119
+ function detectFrameworkConfig(dir) {
120
+ let entries;
121
+ try { entries = fs.readdirSync(dir); } catch { return null; }
122
+ const entrySet = new Set(entries);
123
+
124
+ for (const cfg of FRAMEWORK_CONFIGS) {
125
+ const match = cfg.files.find(f => entrySet.has(f));
126
+ if (!match) continue;
127
+
128
+ const configPath = path.join(dir, match);
129
+ let port = cfg.defaultPort;
130
+ try {
131
+ const content = fs.readFileSync(configPath, 'utf-8');
132
+ const portMatch = content.match(cfg.portRe);
133
+ if (portMatch) port = parseInt(portMatch[1], 10);
134
+ } catch { /* use default */ }
135
+
136
+ return { name: cfg.name, port, configPath, fingerprint: cfg.fingerprint };
137
+ }
138
+ return null;
139
+ }
140
+
141
+ /**
142
+ * Check if a port is listening and optionally verify it matches the expected framework.
143
+ * Returns { listening: true, matched: true/false } or { listening: false }.
144
+ */
145
+ async function isPortListening(port, fingerprint = null) {
146
+ if (!fingerprint) {
147
+ // Simple TCP probe fallback
148
+ const net = await import('node:net');
149
+ return new Promise((resolve) => {
150
+ const sock = net.default.createConnection({ port, host: '127.0.0.1' });
151
+ sock.setTimeout(500);
152
+ sock.on('connect', () => { sock.destroy(); resolve({ listening: true, matched: true }); });
153
+ sock.on('error', () => resolve({ listening: false }));
154
+ sock.on('timeout', () => { sock.destroy(); resolve({ listening: false }); });
155
+ });
156
+ }
157
+
158
+ // HTTP probe with fingerprint matching
159
+ try {
160
+ const controller = new AbortController();
161
+ const timeout = setTimeout(() => controller.abort(), 2000);
162
+ const res = await fetch(`http://localhost:${port}/`, { signal: controller.signal, redirect: 'follow' });
163
+ clearTimeout(timeout);
164
+
165
+ // Check header fingerprint
166
+ if (fingerprint.header) {
167
+ const val = res.headers.get(fingerprint.header);
168
+ if (val && (!fingerprint.value || fingerprint.value.test(val))) {
169
+ return { listening: true, matched: true };
170
+ }
171
+ }
172
+
173
+ // Check body fingerprint
174
+ if (fingerprint.body) {
175
+ const body = await res.text();
176
+ if (fingerprint.body.test(body)) {
177
+ return { listening: true, matched: true };
178
+ }
179
+ }
180
+
181
+ // Port is listening but doesn't match the expected framework
182
+ return { listening: true, matched: false };
183
+ } catch {
184
+ return { listening: false };
185
+ }
186
+ }
187
+
188
+ export {
189
+ SKIP_DIRS,
190
+ SCANNABLE_EXTENSIONS,
191
+ HTML_EXTENSIONS,
192
+ walkDir,
193
+ resolveImport,
194
+ buildImportGraph,
195
+ FRAMEWORK_CONFIGS,
196
+ detectFrameworkConfig,
197
+ isPortListening,
198
+ };