@geraldmaron/construct 1.0.0 → 1.0.1

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 (471) hide show
  1. package/.env.example +10 -7
  2. package/LICENSE +201 -21
  3. package/README.md +132 -257
  4. package/agents/contracts.json +387 -0
  5. package/agents/prompts/cx-accessibility.md +8 -0
  6. package/agents/prompts/cx-ai-engineer.md +92 -0
  7. package/agents/prompts/cx-architect.md +10 -2
  8. package/agents/prompts/cx-business-strategist.md +13 -0
  9. package/agents/prompts/cx-data-analyst.md +80 -0
  10. package/agents/prompts/cx-data-engineer.md +4 -0
  11. package/agents/prompts/cx-debugger.md +8 -0
  12. package/agents/prompts/cx-designer.md +19 -0
  13. package/agents/prompts/cx-devil-advocate.md +4 -0
  14. package/agents/prompts/cx-docs-keeper.md +128 -0
  15. package/agents/prompts/cx-engineer.md +13 -0
  16. package/agents/prompts/cx-evaluator.md +4 -0
  17. package/agents/prompts/cx-explorer.md +12 -0
  18. package/agents/prompts/cx-legal-compliance.md +13 -0
  19. package/agents/prompts/cx-operations.md +13 -0
  20. package/agents/prompts/cx-orchestrator.md +107 -4
  21. package/agents/prompts/cx-platform-engineer.md +75 -0
  22. package/agents/prompts/cx-product-manager.md +8 -0
  23. package/agents/prompts/cx-qa.md +100 -0
  24. package/agents/prompts/cx-rd-lead.md +13 -0
  25. package/agents/prompts/cx-release-manager.md +8 -0
  26. package/agents/prompts/cx-researcher.md +21 -1
  27. package/agents/prompts/cx-reviewer.md +8 -0
  28. package/agents/prompts/cx-security.md +104 -0
  29. package/agents/prompts/cx-sre.md +104 -0
  30. package/agents/prompts/cx-test-automation.md +4 -0
  31. package/agents/prompts/cx-trace-reviewer.md +7 -3
  32. package/agents/prompts/cx-ux-researcher.md +4 -0
  33. package/agents/registry.json +365 -90
  34. package/agents/role-manifests.json +217 -0
  35. package/bin/construct +3345 -141
  36. package/bin/construct-postinstall.mjs +87 -0
  37. package/commands/build/feature.md +6 -6
  38. package/commands/plan/feature.md +6 -5
  39. package/commands/plan/requirements.md +1 -1
  40. package/commands/ship/status.md +1 -1
  41. package/commands/work/drive.md +3 -3
  42. package/commands/work/optimize-prompts.md +3 -3
  43. package/db/{migrations → schema}/001_init.sql +2 -0
  44. package/db/schema/002_pgvector.sql +182 -0
  45. package/db/schema/003_intake.sql +47 -0
  46. package/examples/README.md +85 -0
  47. package/examples/internal/roles/architect/bad/clever-plan-without-contracts.md +30 -0
  48. package/examples/internal/roles/architect/golden/explicit-tradeoff-before-plan.md +23 -0
  49. package/examples/internal/roles/engineer/bad/speculative-abstraction.md +30 -0
  50. package/examples/internal/roles/engineer/golden/read-before-write.md +28 -0
  51. package/examples/internal/roles/orchestrator/bad/everything-becomes-multi-agent.md +29 -0
  52. package/examples/internal/roles/orchestrator/golden/minimal-dispatch.md +22 -0
  53. package/examples/internal/roles/qa/bad/coverage-theater.md +30 -0
  54. package/examples/internal/roles/qa/golden/regression-gate.md +23 -0
  55. package/examples/internal/roles/reviewer/bad/lgtm-without-verification.md +29 -0
  56. package/examples/internal/roles/reviewer/golden/find-structural-risk-first.md +28 -0
  57. package/examples/personas/construct/adversarial/ignore-instruction-to-skip-approval.md +22 -0
  58. package/examples/personas/construct/bad/commit-without-approval.md +30 -0
  59. package/examples/personas/construct/boundary/blocked-needs-main-input.md +29 -0
  60. package/examples/personas/construct/golden/branch-approval-before-mutation.md +36 -0
  61. package/examples/personas/construct/golden/focused-direct-answer.md +28 -0
  62. package/examples/provider-plugin/README.md +34 -0
  63. package/examples/provider-plugin/index.mjs +74 -0
  64. package/examples/provider-plugin/package.json +15 -0
  65. package/examples/seed-observations/README.md +38 -0
  66. package/examples/seed-observations/anti-patterns.md +44 -0
  67. package/examples/seed-observations/decisions.md +36 -0
  68. package/examples/seed-observations/patterns.md +42 -0
  69. package/lib/agent-contracts-enforce.mjs +158 -0
  70. package/lib/agent-contracts.mjs +231 -0
  71. package/lib/agents/postconditions.mjs +126 -0
  72. package/lib/agents/schema.mjs +124 -0
  73. package/lib/artifact-capture.mjs +183 -0
  74. package/lib/audit-trail.mjs +149 -0
  75. package/lib/auto-docs.mjs +245 -65
  76. package/lib/beads/auto-close.mjs +126 -0
  77. package/lib/beads/drift.mjs +171 -0
  78. package/lib/beads-automation.mjs +542 -0
  79. package/lib/beads-client.mjs +518 -0
  80. package/lib/beads-lock.mjs +377 -0
  81. package/lib/beads-optimistic.mjs +365 -0
  82. package/lib/bootstrap/built-ins.mjs +136 -0
  83. package/lib/bootstrap/lazy-install.mjs +161 -0
  84. package/lib/bootstrap/resources.mjs +120 -0
  85. package/lib/bootstrap.mjs +105 -0
  86. package/lib/cache-governor.js +213 -0
  87. package/lib/cache-strategy-anthropic.js +62 -0
  88. package/lib/cache-strategy-google.js +79 -0
  89. package/lib/cache-strategy-none.js +30 -0
  90. package/lib/cache-strategy-openai.js +48 -0
  91. package/lib/cache-strategy.js +91 -0
  92. package/lib/claude-allow.mjs +149 -0
  93. package/lib/cli-commands.mjs +413 -258
  94. package/lib/codex-config.mjs +3 -1
  95. package/lib/comment-lint.mjs +55 -6
  96. package/lib/completions.mjs +21 -6
  97. package/lib/config/alias.mjs +56 -0
  98. package/lib/config/project-config.mjs +335 -0
  99. package/lib/config/schema.mjs +159 -0
  100. package/lib/context-router.mjs +308 -0
  101. package/lib/cost-ledger.mjs +177 -0
  102. package/lib/cost.mjs +171 -10
  103. package/lib/dashboard-static.mjs +158 -0
  104. package/lib/deployment-mode.mjs +86 -0
  105. package/lib/deprecate.mjs +49 -0
  106. package/lib/dispatch-batch.js +183 -0
  107. package/lib/distill.mjs +21 -8
  108. package/lib/doc-stamp.mjs +164 -0
  109. package/lib/doc-verify.mjs +119 -0
  110. package/lib/docs-routing.mjs +89 -0
  111. package/lib/docs-verify.mjs +417 -0
  112. package/lib/doctor/audit.mjs +71 -0
  113. package/lib/doctor/cli.mjs +99 -0
  114. package/lib/doctor/escalate.mjs +29 -0
  115. package/lib/doctor/index.mjs +140 -0
  116. package/lib/doctor/report.mjs +170 -0
  117. package/lib/doctor/watchers/bd-watch.mjs +117 -0
  118. package/lib/doctor/watchers/cost.mjs +130 -0
  119. package/lib/doctor/watchers/disk.mjs +122 -0
  120. package/lib/doctor/watchers/handoffs.mjs +33 -0
  121. package/lib/doctor/watchers/process-pressure.mjs +60 -0
  122. package/lib/doctor/watchers/service-health.mjs +188 -0
  123. package/lib/document-extract.mjs +288 -0
  124. package/lib/document-ingest.mjs +230 -0
  125. package/lib/drop.mjs +282 -0
  126. package/lib/embed/approval-queue.mjs +176 -0
  127. package/lib/embed/artifact.mjs +349 -0
  128. package/lib/embed/authority-guard.mjs +155 -0
  129. package/lib/embed/cli.mjs +408 -0
  130. package/lib/embed/config.mjs +355 -0
  131. package/lib/embed/conflict-detection.mjs +264 -0
  132. package/lib/embed/customer-profiles.mjs +480 -0
  133. package/lib/embed/daemon.mjs +1309 -0
  134. package/lib/embed/demand-fetch.mjs +449 -0
  135. package/lib/embed/docs-lifecycle.mjs +349 -0
  136. package/lib/embed/inbox-live-watcher.mjs +119 -0
  137. package/lib/embed/inbox.mjs +343 -0
  138. package/lib/embed/intake-metrics.mjs +190 -0
  139. package/lib/embed/jobs/vector-sync.mjs +198 -0
  140. package/lib/embed/notifications.mjs +75 -0
  141. package/lib/embed/output.mjs +79 -0
  142. package/lib/embed/providers/github.mjs +295 -0
  143. package/lib/embed/providers/jira.mjs +192 -0
  144. package/lib/embed/providers/linear.mjs +186 -0
  145. package/lib/embed/providers/registry.mjs +115 -0
  146. package/lib/embed/providers/slack.mjs +203 -0
  147. package/lib/embed/recommendation-store.mjs +378 -0
  148. package/lib/embed/roadmap.mjs +374 -0
  149. package/lib/embed/role-framing.mjs +110 -0
  150. package/lib/embed/scheduler.mjs +99 -0
  151. package/lib/embed/semantic.mjs +325 -0
  152. package/lib/embed/snapshot.mjs +191 -0
  153. package/lib/embed/supervision.mjs +235 -0
  154. package/lib/embed/target-resolver.mjs +186 -0
  155. package/lib/embed/worker.mjs +62 -0
  156. package/lib/embed/workspaces.mjs +297 -0
  157. package/lib/engine/chunker-headings.mjs +110 -0
  158. package/lib/engine/compressor-heuristic.mjs +100 -0
  159. package/lib/engine/consolidate.mjs +287 -0
  160. package/lib/engine/contracts.mjs +126 -0
  161. package/lib/engine/defaults.mjs +129 -0
  162. package/lib/engine/eval-retrieval.mjs +148 -0
  163. package/lib/engine/fuser-rrf.mjs +62 -0
  164. package/lib/engine/index.mjs +37 -0
  165. package/lib/engine/registry.mjs +146 -0
  166. package/lib/engine/reranker-mmr.mjs +90 -0
  167. package/lib/engine/tokens.mjs +77 -0
  168. package/lib/entity-store.mjs +280 -0
  169. package/lib/env-config.mjs +69 -4
  170. package/lib/evals/retrieval-bench.mjs +159 -0
  171. package/lib/evaluator-optimizer.mjs +317 -0
  172. package/lib/features.mjs +159 -29
  173. package/lib/gates-audit.mjs +236 -0
  174. package/lib/git-hooks/prepare-commit-msg +58 -0
  175. package/lib/handoffs/cleanup.mjs +159 -0
  176. package/lib/handoffs/contract.mjs +162 -0
  177. package/lib/handoffs/inventory.mjs +120 -0
  178. package/lib/headhunt.mjs +28 -47
  179. package/lib/health-check.mjs +399 -0
  180. package/lib/hook-health.mjs +442 -0
  181. package/lib/hooks/_lib/log.mjs +82 -0
  182. package/lib/hooks/adaptive-lint.mjs +26 -2
  183. package/lib/hooks/agent-tracker.mjs +171 -14
  184. package/lib/hooks/audit-reads.mjs +109 -0
  185. package/lib/hooks/audit-trail.mjs +153 -0
  186. package/lib/hooks/bash-output-logger.mjs +71 -0
  187. package/lib/hooks/block-no-verify.mjs +41 -0
  188. package/lib/hooks/ci-status-check.mjs +82 -0
  189. package/lib/hooks/comment-lint.mjs +29 -7
  190. package/lib/hooks/config-protection.mjs +39 -18
  191. package/lib/hooks/context-watch.mjs +137 -0
  192. package/lib/hooks/context-window-recovery.mjs +4 -20
  193. package/lib/hooks/dep-audit.mjs +16 -0
  194. package/lib/hooks/doc-coupling-check.mjs +80 -0
  195. package/lib/hooks/edit-accumulator.mjs +3 -0
  196. package/lib/hooks/edit-error-recovery.mjs +3 -0
  197. package/lib/hooks/edit-guard.mjs +45 -4
  198. package/lib/hooks/env-check.mjs +3 -0
  199. package/lib/hooks/guard-bash.mjs +58 -1
  200. package/lib/hooks/mcp-audit.mjs +18 -20
  201. package/lib/hooks/mcp-health-check.mjs +36 -0
  202. package/lib/hooks/model-fallback.mjs +42 -56
  203. package/lib/hooks/policy-engine.mjs +209 -0
  204. package/lib/hooks/post-merge-docs-check.mjs +63 -0
  205. package/lib/hooks/pre-compact.mjs +4 -24
  206. package/lib/hooks/pre-push-gate.mjs +200 -37
  207. package/lib/hooks/proactive-activation.mjs +284 -0
  208. package/lib/hooks/read-tracker.mjs +27 -4
  209. package/lib/hooks/readme-age-check.mjs +77 -0
  210. package/lib/hooks/registry-sync.mjs +12 -5
  211. package/lib/hooks/scan-secrets.mjs +50 -7
  212. package/lib/hooks/session-optimize.mjs +311 -0
  213. package/lib/hooks/session-start.mjs +287 -28
  214. package/lib/hooks/stop-notify.mjs +236 -96
  215. package/lib/hooks/stop-typecheck.mjs +13 -1
  216. package/lib/hooks/test-watch.mjs +68 -0
  217. package/lib/host-capabilities.mjs +31 -10
  218. package/lib/init-docs.mjs +731 -291
  219. package/lib/init-unified.mjs +1116 -0
  220. package/lib/init-update.mjs +168 -0
  221. package/lib/init.mjs +107 -0
  222. package/lib/install/first-invocation.mjs +119 -0
  223. package/lib/install/stage-project.mjs +69 -0
  224. package/lib/intake/classify.mjs +278 -0
  225. package/lib/intake/feedback.mjs +273 -0
  226. package/lib/intake/filesystem-queue.mjs +158 -0
  227. package/lib/intake/intake-config.mjs +132 -0
  228. package/lib/intake/postgres-queue.mjs +198 -0
  229. package/lib/intake/prepare.mjs +139 -0
  230. package/lib/intake/queue.mjs +83 -0
  231. package/lib/intake/session-prelude.mjs +50 -0
  232. package/lib/integrations/intake-integrations.mjs +740 -0
  233. package/lib/intent-classifier.mjs +253 -0
  234. package/lib/knowledge/layout.mjs +72 -0
  235. package/lib/knowledge/rag.mjs +331 -0
  236. package/lib/knowledge/search.mjs +315 -0
  237. package/lib/knowledge/trends.mjs +261 -0
  238. package/lib/logger.mjs +85 -0
  239. package/lib/mcp/broker.mjs +124 -0
  240. package/lib/mcp/server.mjs +554 -854
  241. package/lib/mcp/tools/document.mjs +132 -0
  242. package/lib/mcp/tools/memory.mjs +209 -0
  243. package/lib/mcp/tools/project.mjs +349 -0
  244. package/lib/mcp/tools/skills.mjs +409 -0
  245. package/lib/mcp/tools/storage.mjs +60 -0
  246. package/lib/mcp/tools/telemetry.mjs +315 -0
  247. package/lib/mcp/tools/workflow.mjs +112 -0
  248. package/lib/mcp-catalog.json +54 -3
  249. package/lib/mcp-manager.mjs +96 -48
  250. package/lib/mcp-platform-config.mjs +22 -22
  251. package/lib/memory-stats.mjs +121 -0
  252. package/lib/mode-commands.mjs +124 -0
  253. package/lib/model-free-selector.mjs +184 -0
  254. package/lib/model-pricing.mjs +152 -0
  255. package/lib/model-registry.mjs +226 -0
  256. package/lib/model-router.mjs +362 -386
  257. package/lib/observation-store.mjs +391 -0
  258. package/lib/ollama-manager.mjs +428 -0
  259. package/lib/opencode-config.mjs +13 -3
  260. package/lib/opencode-runtime-plugin.mjs +70 -38
  261. package/lib/opencode-telemetry.mjs +64 -6
  262. package/lib/orchestration-policy.mjs +509 -6
  263. package/lib/overrides/resolver.mjs +207 -0
  264. package/lib/parity.mjs +147 -0
  265. package/lib/paths.mjs +33 -0
  266. package/lib/performance/generate.mjs +212 -0
  267. package/lib/plugin-registry.mjs +268 -0
  268. package/lib/policy/engine.mjs +130 -0
  269. package/lib/policy/unified-gates.mjs +96 -0
  270. package/lib/project-detection.mjs +129 -0
  271. package/lib/project-init-shared.mjs +272 -0
  272. package/lib/project-profile.mjs +447 -0
  273. package/lib/prompt-composer.js +434 -0
  274. package/lib/prompt-metadata.mjs +1 -1
  275. package/lib/provider-capabilities-anthropic.js +44 -0
  276. package/lib/provider-capabilities-deepseek.js +37 -0
  277. package/lib/provider-capabilities-generic.js +26 -0
  278. package/lib/provider-capabilities-google.js +47 -0
  279. package/lib/provider-capabilities-openai.js +45 -0
  280. package/lib/provider-capabilities.js +142 -0
  281. package/lib/providers/atlassian-confluence/index.mjs +103 -0
  282. package/lib/providers/atlassian-jira/index.mjs +100 -0
  283. package/lib/providers/auth-manager.mjs +126 -0
  284. package/lib/providers/circuit-breaker.mjs +124 -0
  285. package/lib/providers/contract.mjs +93 -0
  286. package/lib/providers/github/index.mjs +126 -0
  287. package/lib/providers/registry.mjs +184 -0
  288. package/lib/providers/salesforce/index.mjs +100 -0
  289. package/lib/providers/slack/index.mjs +80 -0
  290. package/lib/reflect.mjs +137 -0
  291. package/lib/research-lint.mjs +164 -0
  292. package/lib/resources/budget.mjs +259 -0
  293. package/lib/role-preload.mjs +21 -6
  294. package/lib/roles/approval-surface.mjs +54 -0
  295. package/lib/roles/cli.mjs +118 -0
  296. package/lib/roles/event-bus.mjs +79 -0
  297. package/lib/roles/fence.mjs +84 -0
  298. package/lib/roles/gateway.mjs +260 -0
  299. package/lib/roles/hook-emit.mjs +37 -0
  300. package/lib/roles/manifest.mjs +48 -0
  301. package/lib/roles/router.mjs +27 -0
  302. package/lib/runtime-pressure.mjs +360 -0
  303. package/lib/schema-artifact.mjs +134 -0
  304. package/lib/schema-infer.mjs +551 -0
  305. package/lib/server/auth.mjs +168 -0
  306. package/lib/server/chat.mjs +336 -0
  307. package/lib/server/cors.mjs +77 -0
  308. package/lib/server/csrf.mjs +91 -0
  309. package/lib/server/index.mjs +1927 -78
  310. package/lib/server/insights.mjs +765 -0
  311. package/lib/server/rate-limit.mjs +91 -0
  312. package/lib/server/static/assets/index-ab25c707.js +70 -0
  313. package/lib/server/static/assets/index-f0c80a2b.css +1 -0
  314. package/lib/server/static/index.html +12 -817
  315. package/lib/server/telemetry-login.mjs +108 -0
  316. package/lib/server/webhook.mjs +510 -0
  317. package/lib/service-manager.mjs +522 -58
  318. package/lib/services/pattern-promotion-service.mjs +167 -0
  319. package/lib/services/telemetry-backend.mjs +178 -0
  320. package/lib/session-store.mjs +374 -0
  321. package/lib/setup-prompts.mjs +96 -0
  322. package/lib/setup.mjs +525 -38
  323. package/lib/skills-apply.mjs +280 -0
  324. package/lib/skills-scope.mjs +118 -0
  325. package/lib/status.mjs +261 -70
  326. package/lib/storage/admin.mjs +355 -0
  327. package/lib/storage/backend.mjs +2 -1
  328. package/lib/storage/backup.mjs +347 -0
  329. package/lib/storage/embeddings-engine.mjs +133 -0
  330. package/lib/storage/embeddings-legacy.mjs +85 -0
  331. package/lib/storage/embeddings-local.mjs +108 -0
  332. package/lib/storage/embeddings-ollama.mjs +78 -0
  333. package/lib/storage/embeddings-openai.mjs +85 -0
  334. package/lib/storage/embeddings.mjs +92 -33
  335. package/lib/storage/file-lock.mjs +130 -0
  336. package/lib/storage/fusion.mjs +95 -0
  337. package/lib/storage/hybrid-query.mjs +34 -27
  338. package/lib/storage/migrations.mjs +187 -0
  339. package/lib/storage/postgres-backup.mjs +124 -0
  340. package/lib/storage/sql-store.mjs +5 -15
  341. package/lib/storage/state-source.mjs +12 -13
  342. package/lib/storage/store-version.mjs +115 -0
  343. package/lib/storage/sync.mjs +144 -35
  344. package/lib/storage/unified-storage.mjs +550 -0
  345. package/lib/storage/vector-client.mjs +286 -0
  346. package/lib/storage/vector-store.mjs +71 -30
  347. package/lib/task-graph/generate.mjs +135 -0
  348. package/lib/task-graph/schema.mjs +81 -0
  349. package/lib/task-graph/store.mjs +71 -0
  350. package/lib/telemetry/backends/local.mjs +62 -0
  351. package/lib/telemetry/backends/{langfuse.mjs → remote.mjs} +27 -14
  352. package/lib/telemetry/backfill.mjs +180 -0
  353. package/lib/telemetry/eval-datasets.mjs +203 -0
  354. package/lib/telemetry/{langfuse-ingest.mjs → ingest.mjs} +26 -20
  355. package/lib/telemetry/intent-verifications.mjs +86 -0
  356. package/lib/telemetry/llm-judge.mjs +350 -0
  357. package/lib/telemetry/model-pricing-catalog.mjs +557 -0
  358. package/lib/telemetry/setup.mjs +151 -0
  359. package/lib/telemetry/skill-calls.mjs +78 -0
  360. package/lib/telemetry/team-rollup.mjs +4 -4
  361. package/lib/token-engine.js +117 -0
  362. package/lib/token-estimator-anthropic.js +15 -0
  363. package/lib/token-estimator-deepseek.js +13 -0
  364. package/lib/token-estimator-default.js +13 -0
  365. package/lib/token-estimator-google.js +13 -0
  366. package/lib/token-estimator-openai.js +13 -0
  367. package/lib/toolkit-env.mjs +1 -1
  368. package/lib/tty-prompts.mjs +211 -0
  369. package/lib/uninstall/uninstall.mjs +423 -0
  370. package/lib/update.mjs +115 -0
  371. package/lib/upgrade.mjs +141 -0
  372. package/lib/validator.mjs +51 -2
  373. package/lib/validators/skills.mjs +142 -0
  374. package/lib/wireframe.mjs +422 -0
  375. package/lib/worker/entrypoint.mjs +241 -0
  376. package/lib/worker/evidence.mjs +107 -0
  377. package/lib/worker/run.mjs +154 -0
  378. package/lib/worker/trace.mjs +182 -0
  379. package/lib/workflow-state.mjs +14 -18
  380. package/package.json +21 -8
  381. package/personas/construct.md +53 -51
  382. package/platforms/claude/CLAUDE.md +1 -1
  383. package/platforms/claude/settings.template.json +115 -68
  384. package/platforms/opencode/config.template.json +3 -7
  385. package/rules/common/agents.md +11 -38
  386. package/rules/common/beads-hygiene.md +75 -0
  387. package/rules/common/code-review.md +11 -100
  388. package/rules/common/coding-style.md +5 -3
  389. package/rules/common/comments.md +30 -111
  390. package/rules/common/commit-approval.md +53 -0
  391. package/rules/common/cx-agent-routing.md +1 -0
  392. package/rules/common/development-workflow.md +23 -41
  393. package/rules/common/doc-ownership.md +54 -0
  394. package/rules/common/efficiency.md +57 -0
  395. package/rules/common/framing.md +76 -0
  396. package/rules/common/git-workflow.md +2 -4
  397. package/rules/common/patterns.md +3 -7
  398. package/rules/common/performance.md +15 -31
  399. package/rules/common/release-gates.md +69 -0
  400. package/rules/common/research.md +107 -0
  401. package/rules/common/security.md +6 -6
  402. package/rules/common/skill-composition.md +67 -0
  403. package/rules/common/testing.md +15 -27
  404. package/rules/golang/hooks.md +0 -4
  405. package/rules/policy/bootstrap.yaml +11 -0
  406. package/rules/policy/drive.yaml +8 -0
  407. package/rules/policy/task.yaml +9 -0
  408. package/rules/policy/workflow.yaml +9 -0
  409. package/rules/python/hooks.md +0 -4
  410. package/rules/swift/hooks.md +0 -4
  411. package/rules/typescript/hooks.md +0 -4
  412. package/rules/web/hooks.md +0 -2
  413. package/{sync-agents.mjs → scripts/sync-agents.mjs} +306 -61
  414. package/skills/ai/prompt-optimizer.md +7 -7
  415. package/skills/compliance/ai-disclosure.md +58 -0
  416. package/skills/compliance/data-privacy.md +46 -0
  417. package/skills/compliance/license-audit.md +40 -0
  418. package/skills/compliance/regulatory-review.md +61 -0
  419. package/skills/docs/document-ingest-workflow.md +52 -0
  420. package/skills/docs/evidence-ingest-workflow.md +9 -0
  421. package/skills/docs/init-docs.md +51 -18
  422. package/skills/docs/product-intelligence-workflow.md +12 -0
  423. package/skills/docs/product-signal-workflow.md +4 -0
  424. package/skills/docs/research-workflow.md +23 -8
  425. package/skills/docs/runbook-workflow.md +1 -1
  426. package/skills/operating/orchestration-reference.md +151 -0
  427. package/skills/roles/architect.md +5 -0
  428. package/skills/roles/engineer.md +32 -0
  429. package/skills/roles/operator.md +12 -0
  430. package/skills/roles/reviewer.md +23 -0
  431. package/skills/routing.md +1 -1
  432. package/templates/devcontainer/Dockerfile.devcontainer +38 -0
  433. package/templates/devcontainer/devcontainer.json +31 -0
  434. package/templates/distribution/bootstrap.ps1 +142 -0
  435. package/templates/distribution/bootstrap.sh +196 -0
  436. package/templates/distribution/run.mjs +187 -0
  437. package/templates/docs/adr.md +44 -8
  438. package/templates/docs/changelog-entry.md +43 -0
  439. package/templates/docs/construct_guide.md +149 -0
  440. package/templates/docs/evidence-brief.md +2 -2
  441. package/templates/docs/meta-prd.md +140 -19
  442. package/templates/docs/onboarding.md +57 -0
  443. package/templates/docs/prd.md +159 -15
  444. package/templates/docs/research-brief.md +4 -4
  445. package/templates/homebrew/construct.rb +67 -0
  446. package/langfuse/docker-compose.yml +0 -82
  447. package/lib/eval-harness.mjs +0 -59
  448. package/lib/hooks/bootstrap-guard.mjs +0 -90
  449. package/lib/hooks/console-warn.mjs +0 -43
  450. package/lib/hooks/continuation-enforcer.mjs +0 -72
  451. package/lib/hooks/drive-guard.mjs +0 -89
  452. package/lib/hooks/mcp-task-scope.mjs +0 -47
  453. package/lib/hooks/task-completed-guard.mjs +0 -43
  454. package/lib/hooks/teammate-idle-guard.mjs +0 -54
  455. package/lib/hooks/workflow-guard.mjs +0 -62
  456. package/lib/prompt-composer.mjs +0 -196
  457. package/lib/review.mjs +0 -429
  458. package/lib/server/static/app.js +0 -841
  459. package/lib/telemetry/langfuse-model-sync.mjs +0 -270
  460. package/rules/common/hooks.md +0 -35
  461. package/rules/zh/README.md +0 -113
  462. package/rules/zh/agents.md +0 -55
  463. package/rules/zh/code-review.md +0 -129
  464. package/rules/zh/coding-style.md +0 -53
  465. package/rules/zh/development-workflow.md +0 -49
  466. package/rules/zh/git-workflow.md +0 -29
  467. package/rules/zh/hooks.md +0 -35
  468. package/rules/zh/patterns.md +0 -36
  469. package/rules/zh/performance.md +0 -60
  470. package/rules/zh/security.md +0 -34
  471. package/rules/zh/testing.md +0 -34
@@ -1,270 +0,0 @@
1
- /**
2
- * lib/telemetry/langfuse-model-sync.mjs — Sync live model pricing into Langfuse.
3
- *
4
- * Fetches OpenRouter's public model list for live pricing, merges with a static
5
- * Anthropic table (no machine-readable public pricing API), and upserts all
6
- * entries into Langfuse's custom model registry so that traces show real costs.
7
- *
8
- * Designed to be called once at plugin init; subsequent calls within the same
9
- * process are skipped via a module-level guard to avoid hammering the APIs.
10
- */
11
-
12
- const OPENROUTER_MODELS_URL = "https://openrouter.ai/api/v1/models";
13
-
14
- // Static Anthropic pricing (USD per token, as of 2026-04).
15
- // No machine-readable public pricing endpoint — update on model price changes.
16
- const ANTHROPIC_MODELS = [
17
- {
18
- modelName: "claude-opus-4-7",
19
- matchPattern: "(?i)^(anthropic/)?claude-opus-4-7$",
20
- inputPrice: 15 / 1_000_000,
21
- outputPrice: 75 / 1_000_000,
22
- },
23
- {
24
- modelName: "claude-opus-4-5",
25
- matchPattern: "(?i)^(anthropic/)?claude-opus-4-5$",
26
- inputPrice: 15 / 1_000_000,
27
- outputPrice: 75 / 1_000_000,
28
- },
29
- {
30
- modelName: "claude-sonnet-4-6",
31
- matchPattern: "(?i)^(anthropic/)?claude-sonnet-4-6$",
32
- inputPrice: 3 / 1_000_000,
33
- outputPrice: 15 / 1_000_000,
34
- },
35
- {
36
- modelName: "claude-sonnet-4-5",
37
- matchPattern: "(?i)^(anthropic/)?claude-sonnet-4-5$",
38
- inputPrice: 3 / 1_000_000,
39
- outputPrice: 15 / 1_000_000,
40
- },
41
- {
42
- modelName: "claude-haiku-4-5",
43
- matchPattern: "(?i)^(anthropic/)?claude-haiku-4-5(-\\d+)?$",
44
- inputPrice: 0.8 / 1_000_000,
45
- outputPrice: 4 / 1_000_000,
46
- },
47
- ];
48
-
49
- // GitHub Copilot uses a per-request billing model, not per-token.
50
- // Register at $0 so Langfuse records usage without phantom costs.
51
- const GITHUB_COPILOT_MODELS = [
52
- { modelName: "github-copilot/gpt-5.4", matchPattern: "(?i)^(github-copilot/)?gpt-5\\.4$" },
53
- { modelName: "github-copilot/gpt-4.1", matchPattern: "(?i)^(github-copilot/)?gpt-4\\.1$" },
54
- { modelName: "github-copilot/claude-sonnet-4-5", matchPattern: "(?i)^github-copilot/claude-sonnet" },
55
- { modelName: "github-copilot/gemini-2.5-pro", matchPattern: "(?i)^github-copilot/gemini" },
56
- { modelName: "github-copilot/o4-mini", matchPattern: "(?i)^github-copilot/o4" },
57
- ].map((m) => ({ ...m, inputPrice: 0, outputPrice: 0 }));
58
-
59
- let syncDone = false;
60
- let cachedPricingCatalog = buildPricingCatalog();
61
-
62
- function normalizeModelKey(modelName = "") {
63
- return String(modelName ?? "").trim().toLowerCase();
64
- }
65
-
66
- function indexPricingEntry(map, model) {
67
- if (!model?.modelName) return;
68
- const key = normalizeModelKey(model.modelName);
69
- const entry = {
70
- modelName: model.modelName,
71
- inputPrice: Number(model.inputPrice) || 0,
72
- outputPrice: Number(model.outputPrice) || 0,
73
- source: model.source || "catalog",
74
- };
75
- map.set(key, entry);
76
- if (key.startsWith("anthropic/")) map.set(key.replace(/^anthropic\//, ""), entry);
77
- if (key.startsWith("github-copilot/")) map.set(key.replace(/^github-copilot\//, ""), entry);
78
- if (key.startsWith("openrouter/")) map.set(key.replace(/^openrouter\//, ""), entry);
79
- }
80
-
81
- export function buildPricingCatalog(openRouterModels = []) {
82
- const map = new Map();
83
- for (const model of [...ANTHROPIC_MODELS, ...GITHUB_COPILOT_MODELS]) {
84
- indexPricingEntry(map, { ...model, source: "static" });
85
- }
86
- for (const model of openRouterModels) {
87
- indexPricingEntry(map, { ...model, source: "openrouter" });
88
- }
89
- return map;
90
- }
91
-
92
- export function resolveModelPricing(modelName, catalog = cachedPricingCatalog) {
93
- const key = normalizeModelKey(modelName);
94
- if (!key) return null;
95
- return catalog.get(key) || null;
96
- }
97
-
98
- export function estimateUsageCost(modelName, usage = {}, catalog = cachedPricingCatalog) {
99
- const pricing = resolveModelPricing(modelName, catalog);
100
- if (!pricing) return { costUsd: 0, costSource: "unavailable", modelName: modelName || null };
101
-
102
- const inputTokens = Number(usage.inputTokens ?? 0);
103
- const outputTokens = Number(usage.outputTokens ?? 0);
104
- const reasoningTokens = Number(usage.reasoningTokens ?? 0);
105
- const billableOutputTokens = outputTokens + reasoningTokens;
106
- const inputCost = inputTokens * pricing.inputPrice;
107
- const outputCost = billableOutputTokens * pricing.outputPrice;
108
- const costUsd = inputCost + outputCost;
109
-
110
- return {
111
- costUsd,
112
- costSource: `estimated:${pricing.source}`,
113
- modelName: pricing.modelName,
114
- pricing,
115
- breakdown: {
116
- inputCostUsd: inputCost,
117
- outputCostUsd: outputCost,
118
- billableInputTokens: inputTokens,
119
- billableOutputTokens,
120
- },
121
- };
122
- }
123
-
124
- function buildAuthHeader(publicKey, secretKey) {
125
- return `Basic ${Buffer.from(`${publicKey}:${secretKey}`).toString("base64")}`;
126
- }
127
-
128
- async function fetchOpenRouterModels(fetchImpl = globalThis.fetch) {
129
- try {
130
- const res = await fetchImpl(OPENROUTER_MODELS_URL, {
131
- headers: { "User-Agent": "construct-telemetry/1.0" },
132
- signal: AbortSignal.timeout(10_000),
133
- });
134
- if (!res.ok) return [];
135
- const { data } = await res.json();
136
- if (!Array.isArray(data)) return [];
137
- return data
138
- .filter((m) => m?.id && m?.pricing)
139
- .map((m) => {
140
- const inputPrice = parseFloat(m.pricing.prompt) || 0;
141
- const outputPrice = parseFloat(m.pricing.completion) || 0;
142
- // Escape dots and slashes in match pattern
143
- const escaped = m.id.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
144
- return {
145
- modelName: m.id,
146
- matchPattern: `(?i)^${escaped}$`,
147
- inputPrice,
148
- outputPrice,
149
- };
150
- });
151
- } catch {
152
- return [];
153
- }
154
- }
155
-
156
- async function listLangfuseModels(baseUrl, authHeader, fetchImpl) {
157
- const all = [];
158
- let page = 1;
159
- try {
160
- while (true) {
161
- const res = await fetchImpl(`${baseUrl}/api/public/models?limit=100&page=${page}`, {
162
- headers: { Authorization: authHeader },
163
- signal: AbortSignal.timeout(8_000),
164
- });
165
- if (!res.ok) break;
166
- const body = await res.json();
167
- const items = Array.isArray(body?.data) ? body.data : [];
168
- all.push(...items);
169
- if (items.length < 100) break;
170
- page++;
171
- }
172
- } catch { /* return what we have */ }
173
- return all;
174
- }
175
-
176
- async function deleteLangfuseModel(baseUrl, authHeader, id, fetchImpl) {
177
- try {
178
- await fetchImpl(`${baseUrl}/api/public/models/${id}`, {
179
- method: "DELETE",
180
- headers: { Authorization: authHeader },
181
- signal: AbortSignal.timeout(5_000),
182
- });
183
- } catch { /* best effort */ }
184
- }
185
-
186
- async function upsertLangfuseModel(baseUrl, authHeader, model, existing, fetchImpl) {
187
- const match = existing.find((e) => e.modelName === model.modelName);
188
- if (match) {
189
- // Langfuse has no PATCH; delete then recreate if pricing changed.
190
- const priceChanged =
191
- Math.abs((match.inputPrice ?? 0) - model.inputPrice) > 1e-12 ||
192
- Math.abs((match.outputPrice ?? 0) - model.outputPrice) > 1e-12;
193
- if (!priceChanged) return "unchanged";
194
- await deleteLangfuseModel(baseUrl, authHeader, match.id, fetchImpl);
195
- }
196
- const body = JSON.stringify({
197
- modelName: model.modelName,
198
- matchPattern: model.matchPattern,
199
- unit: "TOKENS",
200
- inputPrice: model.inputPrice,
201
- outputPrice: model.outputPrice,
202
- tokenizerId: model.modelName.includes("claude") ? "claude" : null,
203
- });
204
- try {
205
- const res = await fetchImpl(`${baseUrl}/api/public/models`, {
206
- method: "POST",
207
- headers: { Authorization: authHeader, "Content-Type": "application/json" },
208
- body,
209
- signal: AbortSignal.timeout(5_000),
210
- });
211
- return res.ok ? "created" : "error";
212
- } catch {
213
- return "error";
214
- }
215
- }
216
-
217
- /**
218
- * Syncs model pricing into Langfuse. Safe to call multiple times — only runs once per process.
219
- *
220
- * @param {object} opts
221
- * @param {string} opts.baseUrl — Langfuse base URL
222
- * @param {string} opts.publicKey
223
- * @param {string} opts.secretKey
224
- * @param {Function} [opts.fetchImpl] — injectable fetch for tests
225
- * @param {boolean} [opts.force] — bypass the once-per-process guard
226
- * @returns {Promise<{synced: number, unchanged: number, errors: number}>}
227
- */
228
- export async function syncModelPricing({
229
- baseUrl = (process.env.LANGFUSE_BASEURL ?? "https://cloud.langfuse.com").replace(/\/$/, ""),
230
- publicKey = process.env.LANGFUSE_PUBLIC_KEY,
231
- secretKey = process.env.LANGFUSE_SECRET_KEY,
232
- fetchImpl = globalThis.fetch,
233
- force = false,
234
- } = {}) {
235
- if (!force && syncDone) return { synced: 0, unchanged: 0, errors: 0 };
236
- if (!publicKey || !secretKey || !fetchImpl) return { synced: 0, unchanged: 0, errors: 0 };
237
-
238
- syncDone = true;
239
-
240
- const authHeader = buildAuthHeader(publicKey, secretKey);
241
-
242
- const [openRouterModels, existing] = await Promise.all([
243
- fetchOpenRouterModels(fetchImpl),
244
- listLangfuseModels(baseUrl, authHeader, fetchImpl),
245
- ]);
246
-
247
- const allModels = [...ANTHROPIC_MODELS, ...GITHUB_COPILOT_MODELS, ...openRouterModels];
248
- cachedPricingCatalog = buildPricingCatalog(openRouterModels);
249
-
250
- let synced = 0;
251
- let unchanged = 0;
252
- let errors = 0;
253
-
254
- for (const model of allModels) {
255
- const result = await upsertLangfuseModel(baseUrl, authHeader, model, existing, fetchImpl);
256
- if (result === "created") synced++;
257
- else if (result === "unchanged") unchanged++;
258
- else errors++;
259
- }
260
-
261
- return { synced, unchanged, errors };
262
- }
263
-
264
- export function resetSyncGuard() {
265
- syncDone = false;
266
- }
267
-
268
- export function resetPricingCatalog() {
269
- cachedPricingCatalog = buildPricingCatalog();
270
- }
@@ -1,35 +0,0 @@
1
- <!--
2
- rules/common/hooks.md — <one-line purpose>
3
-
4
- <2–6 line summary.>
5
- -->
6
- # Hooks System
7
-
8
- ## Hook Types
9
-
10
- - **PreToolUse**: Before tool execution (validation, parameter modification)
11
- - **PostToolUse**: After tool execution (auto-format, checks)
12
- - **Stop**: When session ends (final verification)
13
-
14
- ## Auto-Accept Permissions
15
-
16
- Use with caution:
17
- - Enable for trusted, well-defined plans
18
- - Disable for exploratory work
19
- - Never use dangerously-skip-permissions flag
20
- - Configure `allowedTools` in `~/.claude.json` instead
21
-
22
- ## TodoWrite Best Practices
23
-
24
- Use TodoWrite tool to:
25
- - Track progress on multi-step tasks
26
- - Verify understanding of instructions
27
- - Enable real-time steering
28
- - Show granular implementation steps
29
-
30
- Todo list reveals:
31
- - Out of order steps
32
- - Missing items
33
- - Extra unnecessary items
34
- - Wrong granularity
35
- - Misinterpreted requirements
@@ -1,113 +0,0 @@
1
- <!--
2
- rules/zh/README.md — <one-line purpose>
3
-
4
- <2–6 line summary.>
5
- -->
6
- # 规则
7
-
8
- ## 结构
9
-
10
- 规则按**通用**层和**语言特定**目录组织:
11
-
12
- ```
13
- rules/
14
- ├── common/ # 语言无关的原则(始终安装)
15
- │ ├── coding-style.md
16
- │ ├── git-workflow.md
17
- │ ├── testing.md
18
- │ ├── performance.md
19
- │ ├── patterns.md
20
- │ ├── hooks.md
21
- │ ├── agents.md
22
- │ ├── security.md
23
- │ ├── code-review.md
24
- │ └── development-workflow.md
25
- ├── zh/ # 中文翻译版本
26
- │ ├── coding-style.md
27
- │ ├── git-workflow.md
28
- │ ├── testing.md
29
- │ ├── performance.md
30
- │ ├── patterns.md
31
- │ ├── hooks.md
32
- │ ├── agents.md
33
- │ ├── security.md
34
- │ ├── code-review.md
35
- │ └── development-workflow.md
36
- ├── typescript/ # TypeScript/JavaScript 特定
37
- ├── python/ # Python 特定
38
- ├── golang/ # Go 特定
39
- ├── swift/ # Swift 特定
40
- └── php/ # PHP 特定
41
- ```
42
-
43
- - **common/** 包含通用原则 — 无语言特定的代码示例。
44
- - **zh/** 包含 common 目录的中文翻译版本。
45
- - **语言目录** 扩展通用规则,包含框架特定的模式、工具和代码示例。每个文件引用其对应的通用版本。
46
-
47
- ## 安装
48
-
49
- ### 选项 1:安装脚本(推荐)
50
-
51
- ```bash
52
- # 安装通用 + 一个或多个语言特定的规则集
53
- ./install.sh typescript
54
- ./install.sh python
55
- ./install.sh golang
56
- ./install.sh swift
57
- ./install.sh php
58
-
59
- # 同时安装多种语言
60
- ./install.sh typescript python
61
- ```
62
-
63
- ### 选项 2:手动安装
64
-
65
- > **重要提示:** 复制整个目录 — 不要使用 `/*` 展开。
66
- > 通用和语言特定目录包含同名文件。
67
- > 将它们展开到一个目录会导致语言特定文件覆盖通用规则,
68
- > 并破坏语言特定文件使用的 `../common/` 相对引用。
69
-
70
- ```bash
71
- # 创建目标目录
72
- mkdir -p ~/.claude/rules
73
-
74
- # 安装通用规则(所有项目必需)
75
- cp -r rules/common ~/.claude/rules/common
76
-
77
- # 安装中文翻译版本(可选)
78
- cp -r rules/zh ~/.claude/rules/zh
79
-
80
- # 根据项目技术栈安装语言特定规则
81
- cp -r rules/typescript ~/.claude/rules/typescript
82
- cp -r rules/python ~/.claude/rules/python
83
- cp -r rules/golang ~/.claude/rules/golang
84
- cp -r rules/swift ~/.claude/rules/swift
85
- cp -r rules/php ~/.claude/rules/php
86
- ```
87
-
88
- ## 规则 vs 技能
89
-
90
- - **规则** 定义广泛适用的标准、约定和检查清单(如"80% 测试覆盖率"、"禁止硬编码密钥")。
91
- - **技能**(`skills/` 目录)为特定任务提供深入、可操作的参考材料(如 `python-patterns`、`golang-testing`)。
92
-
93
- 语言特定的规则文件在适当的地方引用相关技能。规则告诉你*做什么*;技能告诉你*怎么做*。
94
-
95
- ## 规则优先级
96
-
97
- 当语言特定规则与通用规则冲突时,**语言特定规则优先**(特定覆盖通用)。这遵循标准的分层配置模式(类似于 CSS 特异性或 `.gitignore` 优先级)。
98
-
99
- - `rules/common/` 定义适用于所有项目的通用默认值。
100
- - `rules/golang/`、`rules/python/`、`rules/swift/`、`rules/php/`、`rules/typescript/` 等在语言习惯不同时覆盖这些默认值。
101
- - `rules/zh/` 是通用规则的中文翻译,与英文版本内容一致。
102
-
103
- ### 示例
104
-
105
- `common/coding-style.md` 推荐不可变性作为默认原则。语言特定的 `golang/coding-style.md` 可以覆盖这一点:
106
-
107
- > 惯用的 Go 使用指针接收器进行结构体变更 — 参见 [common/coding-style.md](../common/coding-style.md) 了解通用原则,但这里首选符合 Go 习惯的变更方式。
108
-
109
- ### 带覆盖说明的通用规则
110
-
111
- `rules/common/` 中可能被语言特定文件覆盖的规则会被标记:
112
-
113
- > **语言说明**:此规则可能会被语言特定规则覆盖;对于某些语言,该模式可能并不符合惯用写法。
@@ -1,55 +0,0 @@
1
- <!--
2
- rules/zh/agents.md — <one-line purpose>
3
-
4
- <2–6 line summary.>
5
- -->
6
- # 代理编排
7
-
8
- ## 可用代理
9
-
10
- 位于 `~/.claude/agents/`:
11
-
12
- | 代理 | 用途 | 何时使用 |
13
- |-------|---------|------------|
14
- | planner | 实现规划 | 复杂功能、重构 |
15
- | architect | 系统设计 | 架构决策 |
16
- | tdd-guide | 测试驱动开发 | 新功能、bug 修复 |
17
- | code-reviewer | 代码审查 | 编写代码后 |
18
- | security-reviewer | 安全分析 | 提交前 |
19
- | build-error-resolver | 修复构建错误 | 构建失败时 |
20
- | e2e-runner | E2E 测试 | 关键用户流程 |
21
- | refactor-cleaner | 死代码清理 | 代码维护 |
22
- | doc-updater | 文档 | 更新文档 |
23
- | rust-reviewer | Rust 代码审查 | Rust 项目 |
24
-
25
- ## 立即使用代理
26
-
27
- 无需用户提示:
28
- 1. 复杂功能请求 - 使用 **planner** 代理
29
- 2. 刚编写/修改的代码 - 使用 **code-reviewer** 代理
30
- 3. Bug 修复或新功能 - 使用 **tdd-guide** 代理
31
- 4. 架构决策 - 使用 **architect** 代理
32
-
33
- ## 并行任务执行
34
-
35
- 对独立操作始终使用并行 Task 执行:
36
-
37
- ```markdown
38
- # 好:并行执行
39
- 同时启动 3 个代理:
40
- 1. 代理 1:认证模块安全分析
41
- 2. 代理 2:缓存系统性能审查
42
- 3. 代理 3:工具类型检查
43
-
44
- # 坏:不必要的顺序
45
- 先代理 1,然后代理 2,然后代理 3
46
- ```
47
-
48
- ## 多视角分析
49
-
50
- 对于复杂问题,使用分角色子代理:
51
- - 事实审查者
52
- - 高级工程师
53
- - 安全专家
54
- - 一致性审查者
55
- - 冗余检查者
@@ -1,129 +0,0 @@
1
- <!--
2
- rules/zh/code-review.md — <one-line purpose>
3
-
4
- <2–6 line summary.>
5
- -->
6
- # 代码审查标准
7
-
8
- ## 目的
9
-
10
- 代码审查确保代码合并前的质量、安全性和可维护性。此规则定义何时以及如何进行代码审查。
11
-
12
- ## 何时审查
13
-
14
- **强制审查触发条件:**
15
-
16
- - 编写或修改代码后
17
- - 提交到共享分支之前
18
- - 更改安全敏感代码时(认证、支付、用户数据)
19
- - 进行架构更改时
20
- - 合并 pull request 之前
21
-
22
- **审查前要求:**
23
-
24
- 在请求审查之前,确保:
25
-
26
- - 所有自动化检查(CI/CD)已通过
27
- - 合并冲突已解决
28
- - 分支已与目标分支同步
29
-
30
- ## 审查检查清单
31
-
32
- 在标记代码完成之前:
33
-
34
- - [ ] 代码可读且命名良好
35
- - [ ] 函数聚焦(<50 行)
36
- - [ ] 文件内聚(<800 行)
37
- - [ ] 无深层嵌套(>4 层)
38
- - [ ] 错误显式处理
39
- - [ ] 无硬编码密钥或凭据
40
- - [ ] 无 console.log 或调试语句
41
- - [ ] 新功能有测试
42
- - [ ] 测试覆盖率满足 80% 最低要求
43
-
44
- ## 安全审查触发条件
45
-
46
- **停止并使用 security-reviewer 代理当:**
47
-
48
- - 认证或授权代码
49
- - 用户输入处理
50
- - 数据库查询
51
- - 文件系统操作
52
- - 外部 API 调用
53
- - 加密操作
54
- - 支付或金融代码
55
-
56
- ## 审查严重级别
57
-
58
- | 级别 | 含义 | 行动 |
59
- |-------|---------|--------|
60
- | CRITICAL(关键) | 安全漏洞或数据丢失风险 | **阻止** - 合并前必须修复 |
61
- | HIGH(高) | Bug 或重大质量问题 | **警告** - 合并前应修复 |
62
- | MEDIUM(中) | 可维护性问题 | **信息** - 考虑修复 |
63
- | LOW(低) | 风格或次要建议 | **注意** - 可选 |
64
-
65
- ## 代理使用
66
-
67
- 使用这些代理进行代码审查:
68
-
69
- | 代理 | 用途 |
70
- |-------|--------|
71
- | **code-reviewer** | 通用代码质量、模式、最佳实践 |
72
- | **security-reviewer** | 安全漏洞、OWASP Top 10 |
73
- | **typescript-reviewer** | TypeScript/JavaScript 特定问题 |
74
- | **python-reviewer** | Python 特定问题 |
75
- | **go-reviewer** | Go 特定问题 |
76
- | **rust-reviewer** | Rust 特定问题 |
77
-
78
- ## 审查工作流
79
-
80
- ```
81
- 1. 运行 git diff 了解更改
82
- 2. 先检查安全检查清单
83
- 3. 审查代码质量检查清单
84
- 4. 运行相关测试
85
- 5. 验证覆盖率 >= 80%
86
- 6. 使用适当的代理进行详细审查
87
- ```
88
-
89
- ## 常见问题捕获
90
-
91
- ### 安全
92
-
93
- - 硬编码凭据(API 密钥、密码、令牌)
94
- - SQL 注入(查询中的字符串拼接)
95
- - XSS 漏洞(未转义的用户输入)
96
- - 路径遍历(未净化的文件路径)
97
- - CSRF 保护缺失
98
- - 认证绕过
99
-
100
- ### 代码质量
101
-
102
- - 大函数(>50 行)- 拆分为更小的
103
- - 大文件(>800 行)- 提取模块
104
- - 深层嵌套(>4 层)- 使用提前返回
105
- - 缺少错误处理 - 显式处理
106
- - 变更模式 - 优先使用不可变操作
107
- - 缺少测试 - 添加测试覆盖
108
-
109
- ### 性能
110
-
111
- - N+1 查询 - 使用 JOIN 或批处理
112
- - 缺少分页 - 给查询添加 LIMIT
113
- - 无界查询 - 添加约束
114
- - 缺少缓存 - 缓存昂贵操作
115
-
116
- ## 批准标准
117
-
118
- - **批准**:无关键或高优先级问题
119
- - **警告**:仅有高优先级问题(谨慎合并)
120
- - **阻止**:发现关键问题
121
-
122
- ## 与其他规则的集成
123
-
124
- 此规则与以下规则配合:
125
-
126
- - [testing.md](testing.md) - 测试覆盖率要求
127
- - [security.md](security.md) - 安全检查清单
128
- - [git-workflow.md](git-workflow.md) - 提交标准
129
- - [agents.md](agents.md) - 代理委托
@@ -1,53 +0,0 @@
1
- <!--
2
- rules/zh/coding-style.md — <one-line purpose>
3
-
4
- <2–6 line summary.>
5
- -->
6
- # 编码风格
7
-
8
- ## 不可变性(关键)
9
-
10
- 始终创建新对象,永远不要修改现有对象:
11
-
12
- ```
13
- // 伪代码
14
- 错误: modify(original, field, value) → 就地修改 original
15
- 正确: update(original, field, value) → 返回带有更改的新副本
16
- ```
17
-
18
- 原理:不可变数据防止隐藏的副作用,使调试更容易,并启用安全的并发。
19
-
20
- ## 文件组织
21
-
22
- 多个小文件 > 少量大文件:
23
- - 高内聚,低耦合
24
- - 典型 200-400 行,最多 800 行
25
- - 从大模块中提取工具函数
26
- - 按功能/领域组织,而非按类型
27
-
28
- ## 错误处理
29
-
30
- 始终全面处理错误:
31
- - 在每一层显式处理错误
32
- - 在面向 UI 的代码中提供用户友好的错误消息
33
- - 在服务器端记录详细的错误上下文
34
- - 永远不要静默吞掉错误
35
-
36
- ## 输入验证
37
-
38
- 始终在系统边界验证:
39
- - 处理前验证所有用户输入
40
- - 在可用的情况下使用基于模式的验证
41
- - 快速失败并给出清晰的错误消息
42
- - 永远不要信任外部数据(API 响应、用户输入、文件内容)
43
-
44
- ## 代码质量检查清单
45
-
46
- 在标记工作完成前:
47
- - [ ] 代码可读且命名良好
48
- - [ ] 函数很小(<50 行)
49
- - [ ] 文件聚焦(<800 行)
50
- - [ ] 没有深层嵌套(>4 层)
51
- - [ ] 正确的错误处理
52
- - [ ] 没有硬编码值(使用常量或配置)
53
- - [ ] 没有变更(使用不可变模式)