tribunal-kit 6.0.0 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (353) hide show
  1. package/.agent/.manifest.json +78 -0
  2. package/.agent/ARCHITECTURE.md +19 -241
  3. package/.agent/agents/accessibility-reviewer.md +23 -16
  4. package/.agent/agents/ai-code-reviewer.md +25 -21
  5. package/.agent/agents/anti-pattern-reviewer.md +12 -7
  6. package/.agent/agents/api-architect.md +1 -0
  7. package/.agent/agents/backend-specialist.md +23 -22
  8. package/.agent/agents/cloud-engineer.md +1 -0
  9. package/.agent/agents/code-archaeologist.md +1 -0
  10. package/.agent/agents/complexity-reviewer.md +10 -7
  11. package/.agent/agents/database-architect.md +3 -2
  12. package/.agent/agents/db-latency-auditor.md +6 -2
  13. package/.agent/agents/debugger.md +3 -2
  14. package/.agent/agents/dependency-reviewer.md +1 -0
  15. package/.agent/agents/devops-engineer.md +9 -8
  16. package/.agent/agents/documentation-writer.md +6 -5
  17. package/.agent/agents/explorer-agent.md +1 -0
  18. package/.agent/agents/frontend-reviewer.md +21 -17
  19. package/.agent/agents/frontend-specialist.md +23 -20
  20. package/.agent/agents/game-developer.md +1 -0
  21. package/.agent/agents/interaction-reviewer.md +10 -5
  22. package/.agent/agents/logic-reviewer.md +3 -0
  23. package/.agent/agents/minimalist-reviewer.md +6 -0
  24. package/.agent/agents/mobile-developer.md +7 -6
  25. package/.agent/agents/mobile-reviewer.md +14 -13
  26. package/.agent/agents/orchestrator.md +3 -0
  27. package/.agent/agents/penetration-tester.md +1 -0
  28. package/.agent/agents/performance-optimizer.md +6 -5
  29. package/.agent/agents/performance-reviewer.md +6 -6
  30. package/.agent/agents/pipeline-reviewer.md +144 -0
  31. package/.agent/agents/precedence-reviewer.md +1 -0
  32. package/.agent/agents/product-manager.md +1 -0
  33. package/.agent/agents/product-owner.md +1 -0
  34. package/.agent/agents/product-reviewer.md +12 -7
  35. package/.agent/agents/project-planner.md +3 -0
  36. package/.agent/agents/qa-automation-engineer.md +50 -43
  37. package/.agent/agents/resilience-reviewer.md +1 -0
  38. package/.agent/agents/schema-reviewer.md +1 -0
  39. package/.agent/agents/security-auditor.md +24 -24
  40. package/.agent/agents/seo-specialist.md +33 -23
  41. package/.agent/agents/sql-reviewer.md +5 -4
  42. package/.agent/agents/supervisor-agent.md +12 -2
  43. package/.agent/agents/swarm-worker-contracts.md +13 -13
  44. package/.agent/agents/swarm-worker-registry.md +51 -51
  45. package/.agent/agents/system-architect.md +1 -0
  46. package/.agent/agents/test-coverage-reviewer.md +25 -22
  47. package/.agent/agents/test-engineer.md +12 -11
  48. package/.agent/agents/throughput-optimizer.md +45 -40
  49. package/.agent/agents/type-safety-reviewer.md +5 -4
  50. package/.agent/agents/ui-ux-auditor.md +6 -4
  51. package/.agent/agents/ui-visual-auditor.md +3 -0
  52. package/.agent/agents/ux-reviewer.md +11 -6
  53. package/.agent/agents/visual-reviewer.md +11 -6
  54. package/.agent/agents/vitals-reviewer.md +5 -4
  55. package/.agent/history/memory/.memory.idx +3716 -1
  56. package/.agent/history/memory/MEMORY.md +246 -1
  57. package/.agent/mcp_config.json +1 -6
  58. package/.agent/routing_index.json +2034 -263
  59. package/.agent/rules/GEMINI.md +12 -10
  60. package/.agent/rules/GEMINI_PLANNER.md +19 -21
  61. package/.agent/scripts/_colors.js +52 -54
  62. package/.agent/scripts/_utils.js +52 -53
  63. package/.agent/scripts/auto_preview.js +39 -43
  64. package/.agent/scripts/bundle_analyzer.js +47 -60
  65. package/.agent/scripts/case_law_manager.js +200 -294
  66. package/.agent/scripts/checklist.js +73 -94
  67. package/.agent/scripts/cicd_validator.js +305 -0
  68. package/.agent/scripts/compile_router.py +4 -111
  69. package/.agent/scripts/context_broker.js +317 -412
  70. package/.agent/scripts/contract_engine.js +402 -0
  71. package/.agent/scripts/dependency_analyzer.js +112 -124
  72. package/.agent/scripts/graph_builder.js +75 -103
  73. package/.agent/scripts/graph_visualizer.js +10 -12
  74. package/.agent/scripts/graph_zoom.js +38 -55
  75. package/.agent/scripts/guardrail_engine.js +195 -145
  76. package/.agent/scripts/impact_classifier.js +55 -30
  77. package/.agent/scripts/inner_loop_validator.js +108 -159
  78. package/.agent/scripts/integrity_manifest.js +59 -67
  79. package/.agent/scripts/lint_runner.js +65 -75
  80. package/.agent/scripts/marathon_harness.js +131 -208
  81. package/.agent/scripts/migrate_skills_frontmatter.py +4 -63
  82. package/.agent/scripts/minify_context.js +29 -33
  83. package/.agent/scripts/minimal_change_engine.js +95 -87
  84. package/.agent/scripts/mutation_runner.js +46 -62
  85. package/.agent/scripts/pipeline_engine.js +320 -209
  86. package/.agent/scripts/prompt_compiler.js +118 -93
  87. package/.agent/scripts/schema_validator.js +73 -121
  88. package/.agent/scripts/security_scan.js +88 -117
  89. package/.agent/scripts/session_manager.js +52 -69
  90. package/.agent/scripts/signal_detector.js +24 -22
  91. package/.agent/scripts/skill_evolution.js +184 -245
  92. package/.agent/scripts/skill_integrator.js +35 -48
  93. package/.agent/scripts/socratic_gate_policy.js +15 -12
  94. package/.agent/scripts/strengthen_skills.js +29 -33
  95. package/.agent/scripts/swarm_dispatcher.js +120 -151
  96. package/.agent/scripts/test_runner.js +54 -56
  97. package/.agent/scripts/token_budget_broker.js +9 -7
  98. package/.agent/scripts/trace_engine.js +126 -0
  99. package/.agent/scripts/verify_all.js +76 -93
  100. package/.agent/scripts/visual_audit.js +16 -21
  101. package/.agent/skill_topic_map.json +237 -0
  102. package/.agent/skills/12-principles-of-animation/SKILL.md +7 -0
  103. package/.agent/skills/60fps-animation/SKILL.md +7 -0
  104. package/.agent/skills/accessible-animation/SKILL.md +5 -1
  105. package/.agent/skills/adapt/SKILL.md +7 -1
  106. package/.agent/skills/advanced-rag-pipelines/SKILL.md +1 -0
  107. package/.agent/skills/agent-organizer/SKILL.md +1 -0
  108. package/.agent/skills/agentic-patterns/SKILL.md +33 -25
  109. package/.agent/skills/agentic-workflows-2026/SKILL.md +80 -0
  110. package/.agent/skills/ai-app-hardening/SKILL.md +59 -0
  111. package/.agent/skills/ai-prompt-injection-defense/SKILL.md +7 -6
  112. package/.agent/skills/animation-on-scroll/SKILL.md +24 -15
  113. package/.agent/skills/animation-systems/SKILL.md +11 -10
  114. package/.agent/skills/antfu-conventions/SKILL.md +7 -2
  115. package/.agent/skills/api-patterns/SKILL.md +14 -10
  116. package/.agent/skills/api-security-auditor/SKILL.md +15 -14
  117. package/.agent/skills/app-builder/SKILL.md +1 -0
  118. package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +2 -2
  119. package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +1 -1
  120. package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +12 -12
  121. package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +3 -3
  122. package/.agent/skills/apple-design/SKILL.md +8 -7
  123. package/.agent/skills/architecture/SKILL.md +3 -2
  124. package/.agent/skills/audit-and-fix/SKILL.md +8 -5
  125. package/.agent/skills/authentication-best-practices/SKILL.md +9 -8
  126. package/.agent/skills/backend-security-expert/SKILL.md +1 -0
  127. package/.agent/skills/baseline-ui/SKILL.md +8 -7
  128. package/.agent/skills/bash-linux/SKILL.md +1 -0
  129. package/.agent/skills/behavioral-modes/SKILL.md +1 -0
  130. package/.agent/skills/better-colors/SKILL.md +11 -7
  131. package/.agent/skills/better-typography/SKILL.md +30 -16
  132. package/.agent/skills/better-ui/SKILL.md +17 -10
  133. package/.agent/skills/bolder/SKILL.md +6 -0
  134. package/.agent/skills/brainstorming/SKILL.md +6 -4
  135. package/.agent/skills/browser-native-ai/SKILL.md +5 -4
  136. package/.agent/skills/build-primitive/SKILL.md +5 -0
  137. package/.agent/skills/building-native-ui/SKILL.md +1 -0
  138. package/.agent/skills/cicd-pro/SKILL.md +2 -1
  139. package/.agent/skills/clarify/SKILL.md +19 -14
  140. package/.agent/skills/clean-code/SKILL.md +16 -15
  141. package/.agent/skills/cloud-architect/SKILL.md +1 -0
  142. package/.agent/skills/cobejs/SKILL.md +7 -9
  143. package/.agent/skills/code-review-checklist/SKILL.md +1 -0
  144. package/.agent/skills/codebase-design/SKILL.md +7 -2
  145. package/.agent/skills/colorize/SKILL.md +8 -3
  146. package/.agent/skills/compact-landing/SKILL.md +8 -3
  147. package/.agent/skills/company-logos/SKILL.md +6 -0
  148. package/.agent/skills/config-validator/SKILL.md +10 -9
  149. package/.agent/skills/containerization-pro/SKILL.md +6 -5
  150. package/.agent/skills/context-engineering-pro/SKILL.md +70 -0
  151. package/.agent/skills/create-design-md/SKILL.md +13 -5
  152. package/.agent/skills/critique/SKILL.md +10 -8
  153. package/.agent/skills/csharp-developer/SKILL.md +1 -0
  154. package/.agent/skills/data-validation-schemas/SKILL.md +28 -23
  155. package/.agent/skills/database-design/SKILL.md +2 -1
  156. package/.agent/skills/delight/SKILL.md +6 -0
  157. package/.agent/skills/deployment-procedures/SKILL.md +2 -1
  158. package/.agent/skills/design-lab/SKILL.md +5 -0
  159. package/.agent/skills/devops-engineer/SKILL.md +3 -2
  160. package/.agent/skills/devops-incident-responder/SKILL.md +2 -1
  161. package/.agent/skills/diagnosing-bugs/SKILL.md +12 -2
  162. package/.agent/skills/distill/SKILL.md +7 -2
  163. package/.agent/skills/documentation-templates/SKILL.md +3 -2
  164. package/.agent/skills/domain-modeling/SKILL.md +12 -4
  165. package/.agent/skills/duckdb-analytical-sql/SKILL.md +59 -0
  166. package/.agent/skills/edge-ai-mobile/SKILL.md +50 -0
  167. package/.agent/skills/edge-computing/SKILL.md +9 -8
  168. package/.agent/skills/emil-design-eng/SKILL.md +43 -27
  169. package/.agent/skills/error-resilience/SKILL.md +34 -16
  170. package/.agent/skills/expo-router-v4/SKILL.md +81 -0
  171. package/.agent/skills/extract-design-system/SKILL.md +12 -11
  172. package/.agent/skills/fabel-protocol/SKILL.md +24 -17
  173. package/.agent/skills/fixing-accessibility/SKILL.md +23 -16
  174. package/.agent/skills/fixing-metadata/SKILL.md +24 -13
  175. package/.agent/skills/fixing-motion-performance/SKILL.md +7 -5
  176. package/.agent/skills/framer-motion-expert/SKILL.md +29 -15
  177. package/.agent/skills/frontend-design/SKILL.md +21 -13
  178. package/.agent/skills/frontend-security-expert/SKILL.md +1 -0
  179. package/.agent/skills/game-design-expert/SKILL.md +1 -0
  180. package/.agent/skills/game-engineering-expert/SKILL.md +1 -0
  181. package/.agent/skills/generative-ui-expert/SKILL.md +3 -2
  182. package/.agent/skills/geo-fundamentals/SKILL.md +2 -1
  183. package/.agent/skills/git-pro/SKILL.md +10 -9
  184. package/.agent/skills/github-operations/SKILL.md +2 -1
  185. package/.agent/skills/gpt-taste/SKILL.md +7 -0
  186. package/.agent/skills/gsap-core/SKILL.md +26 -22
  187. package/.agent/skills/gsap-frameworks/SKILL.md +6 -5
  188. package/.agent/skills/gsap-performance/SKILL.md +4 -3
  189. package/.agent/skills/gsap-plugins/SKILL.md +34 -33
  190. package/.agent/skills/gsap-react/SKILL.md +9 -8
  191. package/.agent/skills/gsap-scrolltrigger/SKILL.md +34 -33
  192. package/.agent/skills/gsap-timeline/SKILL.md +18 -15
  193. package/.agent/skills/gsap-utils/SKILL.md +25 -24
  194. package/.agent/skills/harden/SKILL.md +9 -3
  195. package/.agent/skills/harness-protocol/SKILL.md +1 -0
  196. package/.agent/skills/i18n-localization/SKILL.md +10 -9
  197. package/.agent/skills/impeccable/SKILL.md +5 -0
  198. package/.agent/skills/improve-codebase-architecture/SKILL.md +10 -5
  199. package/.agent/skills/improve-ui/SKILL.md +12 -5
  200. package/.agent/skills/intelligent-routing/SKILL.md +7 -6
  201. package/.agent/skills/knowledge-graph/SKILL.md +1 -0
  202. package/.agent/skills/landing-page/SKILL.md +1 -0
  203. package/.agent/skills/lint-and-validate/SKILL.md +9 -4
  204. package/.agent/skills/llm-engineering/SKILL.md +55 -54
  205. package/.agent/skills/local-first/SKILL.md +20 -19
  206. package/.agent/skills/local-first-architecture/SKILL.md +6 -1
  207. package/.agent/skills/lottie-animation/SKILL.md +7 -3
  208. package/.agent/skills/marquee-loop/SKILL.md +1 -0
  209. package/.agent/skills/masked-reveal/SKILL.md +17 -4
  210. package/.agent/skills/mcp-builder/SKILL.md +13 -10
  211. package/.agent/skills/micro-interaction/SKILL.md +20 -5
  212. package/.agent/skills/mobile-design/SKILL.md +26 -15
  213. package/.agent/skills/monorepo-management/SKILL.md +3 -2
  214. package/.agent/skills/morphing-icons/SKILL.md +16 -6
  215. package/.agent/skills/motion-engineering/SKILL.md +19 -15
  216. package/.agent/skills/nextjs-react-expert/SKILL.md +26 -21
  217. package/.agent/skills/nodejs-best-practices/SKILL.md +89 -76
  218. package/.agent/skills/observability/SKILL.md +45 -44
  219. package/.agent/skills/opentelemetry-observability/SKILL.md +59 -0
  220. package/.agent/skills/page-transition-animation/SKILL.md +6 -3
  221. package/.agent/skills/parallel-agents/SKILL.md +7 -2
  222. package/.agent/skills/performance-profiling/SKILL.md +24 -13
  223. package/.agent/skills/plan-writing/SKILL.md +1 -0
  224. package/.agent/skills/platform-engineer/SKILL.md +3 -2
  225. package/.agent/skills/platform-engineering-opentofu/SKILL.md +68 -0
  226. package/.agent/skills/playwright-ai-e2e/SKILL.md +60 -0
  227. package/.agent/skills/playwright-best-practices/SKILL.md +29 -28
  228. package/.agent/skills/polish/SKILL.md +13 -12
  229. package/.agent/skills/powershell-windows/SKILL.md +1 -0
  230. package/.agent/skills/pricing-page/SKILL.md +8 -3
  231. package/.agent/skills/product-aware-heuristics/SKILL.md +122 -72
  232. package/.agent/skills/progressive-blur/SKILL.md +9 -4
  233. package/.agent/skills/project-idioms/SKILL.md +1 -0
  234. package/.agent/skills/property-based-testing/SKILL.md +58 -0
  235. package/.agent/skills/python-patterns/SKILL.md +1 -0
  236. package/.agent/skills/python-pro/SKILL.md +1 -0
  237. package/.agent/skills/quieter/SKILL.md +6 -0
  238. package/.agent/skills/react-doctor/SKILL.md +6 -0
  239. package/.agent/skills/react-specialist/SKILL.md +32 -28
  240. package/.agent/skills/readme-builder/SKILL.md +1 -0
  241. package/.agent/skills/realtime-patterns/SKILL.md +34 -33
  242. package/.agent/skills/red-team-tactics/SKILL.md +1 -0
  243. package/.agent/skills/redesign-skill/SKILL.md +6 -0
  244. package/.agent/skills/review-animations/SKILL.md +5 -2
  245. package/.agent/skills/review-animations/STANDARDS.md +37 -23
  246. package/.agent/skills/rust-pro/SKILL.md +1 -0
  247. package/.agent/skills/seo-fundamentals/SKILL.md +4 -3
  248. package/.agent/skills/server-management/SKILL.md +1 -0
  249. package/.agent/skills/shadcn-ui-expert/SKILL.md +28 -22
  250. package/.agent/skills/shape/SKILL.md +9 -2
  251. package/.agent/skills/skill-creator/SKILL.md +1 -0
  252. package/.agent/skills/soft-skill/SKILL.md +6 -0
  253. package/.agent/skills/sounds-on-the-web/SKILL.md +1 -0
  254. package/.agent/skills/sql-pro/SKILL.md +1 -0
  255. package/.agent/skills/supabase-postgres-best-practices/SKILL.md +1 -0
  256. package/.agent/skills/svg-animation/SKILL.md +16 -7
  257. package/.agent/skills/swiftui-expert/SKILL.md +1 -0
  258. package/.agent/skills/swiss-design/SKILL.md +5 -0
  259. package/.agent/skills/system-design-pro/SKILL.md +1 -0
  260. package/.agent/skills/systematic-debugging/SKILL.md +1 -0
  261. package/.agent/skills/tailwind-patterns/SKILL.md +25 -11
  262. package/.agent/skills/taste-skill/SKILL.md +6 -0
  263. package/.agent/skills/tdd-workflow/SKILL.md +5 -0
  264. package/.agent/skills/test-result-analyzer/SKILL.md +1 -0
  265. package/.agent/skills/testing-patterns/SKILL.md +123 -115
  266. package/.agent/skills/thermo-nuclear-code-quality-review/SKILL.md +5 -0
  267. package/.agent/skills/thinking-protocol/SKILL.md +3 -0
  268. package/.agent/skills/to-spring-or-not-to-spring/SKILL.md +9 -8
  269. package/.agent/skills/transitions-dev/SKILL.md +19 -6
  270. package/.agent/skills/trend-researcher/SKILL.md +1 -0
  271. package/.agent/skills/typescript-advanced/SKILL.md +23 -18
  272. package/.agent/skills/typeset/SKILL.md +10 -1
  273. package/.agent/skills/ui-reasoning-engine/SKILL.md +67 -48
  274. package/.agent/skills/ui-skill-packs/SKILL.md +6 -1
  275. package/.agent/skills/ui-skills-root/SKILL.md +39 -38
  276. package/.agent/skills/ui-ux-pro-max/SKILL.md +34 -26
  277. package/.agent/skills/ui-ux-researcher/SKILL.md +1 -0
  278. package/.agent/skills/vector-search-pgvector/SKILL.md +78 -0
  279. package/.agent/skills/vue-expert/SKILL.md +22 -19
  280. package/.agent/skills/vulnerability-scanner/SKILL.md +22 -21
  281. package/.agent/skills/web-accessibility-auditor/SKILL.md +2 -1
  282. package/.agent/skills/web-design-guidelines/SKILL.md +16 -10
  283. package/.agent/skills/web-quality-audit/SKILL.md +5 -0
  284. package/.agent/skills/webapp-testing/SKILL.md +14 -13
  285. package/.agent/skills/webgpu-performance/SKILL.md +1 -0
  286. package/.agent/skills/whimsy-injector/SKILL.md +9 -5
  287. package/.agent/skills/workflow-optimizer/SKILL.md +1 -0
  288. package/.agent/skills/zero-trust-passkeys/SKILL.md +90 -0
  289. package/.agent/templates/DESIGN.md +119 -110
  290. package/.agent/templates/design-tokens.json +9 -6
  291. package/.agent/workflows/acf.md +1 -0
  292. package/.agent/workflows/api-tester.md +1 -0
  293. package/.agent/workflows/audit.md +1 -0
  294. package/.agent/workflows/brainstorm.md +1 -0
  295. package/.agent/workflows/changelog.md +1 -0
  296. package/.agent/workflows/contract.md +60 -0
  297. package/.agent/workflows/create.md +1 -0
  298. package/.agent/workflows/debug.md +1 -0
  299. package/.agent/workflows/deploy.md +1 -0
  300. package/.agent/workflows/enhance.md +1 -0
  301. package/.agent/workflows/fix-ci.md +89 -0
  302. package/.agent/workflows/fix.md +1 -0
  303. package/.agent/workflows/generate.md +1 -0
  304. package/.agent/workflows/marathon.md +1 -0
  305. package/.agent/workflows/migrate.md +1 -0
  306. package/.agent/workflows/minimal.md +9 -7
  307. package/.agent/workflows/orchestrate.md +1 -0
  308. package/.agent/workflows/performance-benchmarker.md +1 -0
  309. package/.agent/workflows/pipeline.md +26 -21
  310. package/.agent/workflows/plan.md +1 -0
  311. package/.agent/workflows/preview.md +1 -0
  312. package/.agent/workflows/refactor.md +3 -2
  313. package/.agent/workflows/review-ai.md +4 -3
  314. package/.agent/workflows/review.md +1 -0
  315. package/.agent/workflows/session.md +1 -0
  316. package/.agent/workflows/status.md +1 -0
  317. package/.agent/workflows/strengthen-skills.md +1 -0
  318. package/.agent/workflows/super-prompt.md +1 -0
  319. package/.agent/workflows/swarm.md +15 -3
  320. package/.agent/workflows/test.md +8 -7
  321. package/.agent/workflows/tribunal-backend.md +3 -2
  322. package/.agent/workflows/tribunal-cicd.md +104 -0
  323. package/.agent/workflows/tribunal-database.md +1 -0
  324. package/.agent/workflows/tribunal-frontend.md +8 -6
  325. package/.agent/workflows/tribunal-full.md +15 -14
  326. package/.agent/workflows/tribunal-mobile.md +6 -5
  327. package/.agent/workflows/tribunal-performance.md +1 -0
  328. package/.agent/workflows/tribunal-speed.md +1 -0
  329. package/.agent/workflows/tribunal-ui.md +29 -21
  330. package/.agent/workflows/ui-ux-pro-max.md +19 -15
  331. package/CONTRIBUTING.md +3 -3
  332. package/README.md +160 -88
  333. package/SECURITY.md +11 -11
  334. package/bin/mcp-server.js +512 -233
  335. package/bin/tribunal-kit.js +29 -30
  336. package/bin/wrapper.js +45 -48
  337. package/dist/cli.js +26 -0
  338. package/dist/commands/case.js +2 -0
  339. package/dist/commands/contract.js +440 -0
  340. package/dist/commands/memory.js +3 -2
  341. package/dist/commands/native.js +36 -0
  342. package/dist/commands/status.js +6 -0
  343. package/dist/esm/index.mjs +32 -0
  344. package/dist/index.d.ts +58 -3
  345. package/package.json +20 -16
  346. package/scripts/benchmark.js +62 -86
  347. package/scripts/changelog.js +67 -73
  348. package/scripts/fix-vbc.js +13 -15
  349. package/scripts/fix-vbc.ps1 +2 -118
  350. package/scripts/stress_benchmark.js +358 -0
  351. package/scripts/sync-version.js +71 -41
  352. package/scripts/validate-payload.js +23 -30
  353. package/scripts/visual_audit.js +23 -13
@@ -19,14 +19,14 @@
19
19
  * Zero external dependencies. Node.js stdlib only.
20
20
  */
21
21
 
22
- "use strict";
22
+ 'use strict';
23
23
 
24
- const fs = require("fs");
25
- const path = require("path");
24
+ const fs = require('fs');
25
+ const path = require('path');
26
26
 
27
27
  // ── Constants ─────────────────────────────────────────────────────────────────
28
28
 
29
- const AGENT_DIR_NAME = ".agent";
29
+ const AGENT_DIR_NAME = '.agent';
30
30
 
31
31
  // ── YAML Frontmatter Parser (regex-based, zero deps) ─────────────────────────
32
32
 
@@ -57,24 +57,24 @@ function safeReaddir(dir) {
57
57
 
58
58
  function safeReadFile(filePath) {
59
59
  try {
60
- return fs.readFileSync(filePath, "utf8");
60
+ return fs.readFileSync(filePath, 'utf8');
61
61
  } catch {
62
- return "";
62
+ return '';
63
63
  }
64
64
  }
65
65
 
66
66
  // ── Agent Crawler ─────────────────────────────────────────────────────────────
67
67
 
68
68
  function crawlAgents(agentDir) {
69
- const agentsDir = path.join(agentDir, "agents");
70
- const files = safeReaddir(agentsDir).filter((f) => f.endsWith(".md"));
69
+ const agentsDir = path.join(agentDir, 'agents');
70
+ const files = safeReaddir(agentsDir).filter(f => f.endsWith('.md'));
71
71
 
72
72
  const reviewers = [];
73
73
  const specialists = [];
74
74
  const allAgents = [];
75
75
 
76
76
  for (const file of files) {
77
- const name = file.replace(/\.md$/, "");
77
+ const name = file.replace(/\.md$/, '');
78
78
  allAgents.push(name);
79
79
 
80
80
  // Classify: reviewer if name contains "reviewer", "auditor", or "tester"
@@ -85,7 +85,6 @@ function crawlAgents(agentDir) {
85
85
  /reviewer|auditor|tester|throughput-optimizer/i.test(name) ||
86
86
  (fm.role && /reviewer/i.test(fm.role));
87
87
 
88
-
89
88
  if (isReviewer) {
90
89
  reviewers.push(name);
91
90
  } else {
@@ -105,12 +104,12 @@ function crawlAgents(agentDir) {
105
104
  // ── Skill Crawler ─────────────────────────────────────────────────────────────
106
105
 
107
106
  function crawlSkills(agentDir) {
108
- const skillsDir = path.join(agentDir, "skills");
107
+ const skillsDir = path.join(agentDir, 'skills');
109
108
  const entries = safeReaddir(skillsDir);
110
109
  const names = [];
111
110
 
112
111
  for (const entry of entries) {
113
- const skillPath = path.join(skillsDir, entry, "SKILL.md");
112
+ const skillPath = path.join(skillsDir, entry, 'SKILL.md');
114
113
  if (fs.existsSync(skillPath)) {
115
114
  const content = safeReadFile(skillPath);
116
115
  const fm = parseFrontmatter(content);
@@ -127,15 +126,13 @@ function crawlSkills(agentDir) {
127
126
  // ── Script Crawler ────────────────────────────────────────────────────────────
128
127
 
129
128
  function crawlScripts(agentDir) {
130
- const scriptsDir = path.join(agentDir, "scripts");
131
- const files = safeReaddir(scriptsDir).filter(
132
- (f) => f.endsWith(".js") || f.endsWith(".py"),
133
- );
129
+ const scriptsDir = path.join(agentDir, 'scripts');
130
+ const files = safeReaddir(scriptsDir).filter(f => f.endsWith('.js') || f.endsWith('.py'));
134
131
 
135
132
  const fileMap = {};
136
133
  for (const file of files) {
137
- const relPath = path.join(AGENT_DIR_NAME, "scripts", file);
138
- fileMap[file] = relPath.replace(/\\/g, "/");
134
+ const relPath = path.join(AGENT_DIR_NAME, 'scripts', file);
135
+ fileMap[file] = relPath.replace(/\\/g, '/');
139
136
  }
140
137
 
141
138
  return {
@@ -147,9 +144,9 @@ function crawlScripts(agentDir) {
147
144
  // ── Workflow Crawler ──────────────────────────────────────────────────────────
148
145
 
149
146
  function crawlWorkflows(agentDir) {
150
- const workflowsDir = path.join(agentDir, "workflows");
151
- const files = safeReaddir(workflowsDir).filter((f) => f.endsWith(".md"));
152
- const names = files.map((f) => f.replace(/\.md$/, ""));
147
+ const workflowsDir = path.join(agentDir, 'workflows');
148
+ const files = safeReaddir(workflowsDir).filter(f => f.endsWith('.md'));
149
+ const names = files.map(f => f.replace(/\.md$/, ''));
153
150
 
154
151
  return {
155
152
  total: names.length,
@@ -170,11 +167,10 @@ function crawlWorkflows(agentDir) {
170
167
  */
171
168
  function extractCrossReferences(filePath, content, agentDir) {
172
169
  const refs = [];
173
- const relSource = path.relative(agentDir, filePath).replace(/\\/g, "/");
170
+ const relSource = path.relative(agentDir, filePath).replace(/\\/g, '/');
174
171
 
175
172
  // Agent references: agents/name.md or `agent-name`
176
- const agentRefRegex =
177
- /(?:agents\/)([\w-]+)(?:\.md)?/g;
173
+ const agentRefRegex = /(?:agents\/)([\w-]+)(?:\.md)?/g;
178
174
  let m;
179
175
  while ((m = agentRefRegex.exec(content)) !== null) {
180
176
  const refFile = `agents/${m[1]}.md`;
@@ -183,13 +179,12 @@ function extractCrossReferences(filePath, content, agentDir) {
183
179
  source: relSource,
184
180
  ref: refFile,
185
181
  exists: fs.existsSync(fullPath),
186
- type: "agent",
182
+ type: 'agent',
187
183
  });
188
184
  }
189
185
 
190
186
  // Script references: scripts/name.js or scripts/name.py
191
- const scriptRefRegex =
192
- /(?:scripts\/)([\w_-]+)\.(js|py)/g;
187
+ const scriptRefRegex = /(?:scripts\/)([\w_-]+)\.(js|py)/g;
193
188
  while ((m = scriptRefRegex.exec(content)) !== null) {
194
189
  const refFile = `scripts/${m[1]}.${m[2]}`;
195
190
  const fullPath = path.join(agentDir, refFile);
@@ -197,7 +192,7 @@ function extractCrossReferences(filePath, content, agentDir) {
197
192
  source: relSource,
198
193
  ref: refFile,
199
194
  exists: fs.existsSync(fullPath),
200
- type: "script",
195
+ type: 'script',
201
196
  });
202
197
  }
203
198
 
@@ -205,7 +200,7 @@ function extractCrossReferences(filePath, content, agentDir) {
205
200
  const workflowRefRegex = /(?:workflows\/)([\w-]+)(?:\.md)?/g;
206
201
  while ((m = workflowRefRegex.exec(content)) !== null) {
207
202
  const precedingText = content.substring(Math.max(0, m.index - 100), m.index);
208
- if (precedingText.includes(".github/") || precedingText.includes("github.com/")) {
203
+ if (precedingText.includes('.github/') || precedingText.includes('github.com/')) {
209
204
  continue;
210
205
  }
211
206
  const refFile = `workflows/${m[1]}.md`;
@@ -214,13 +209,13 @@ function extractCrossReferences(filePath, content, agentDir) {
214
209
  source: relSource,
215
210
  ref: refFile,
216
211
  exists: fs.existsSync(fullPath),
217
- type: "workflow",
212
+ type: 'workflow',
218
213
  });
219
214
  }
220
215
 
221
216
  // Deduplicate
222
217
  const seen = new Set();
223
- return refs.filter((r) => {
218
+ return refs.filter(r => {
224
219
  const key = `${r.source}→${r.ref}`;
225
220
  if (seen.has(key)) return false;
226
221
  seen.add(key);
@@ -236,18 +231,19 @@ function extractCrossReferences(filePath, content, agentDir) {
236
231
  */
237
232
  function extractNumericClaims(filePath, content, agentDir, actualCounts) {
238
233
  const claims = [];
239
- const relSource = path.relative(agentDir, filePath).replace(/\\/g, "/");
234
+ const relSource = path.relative(agentDir, filePath).replace(/\\/g, '/');
240
235
  const lines = content.split(/\r?\n/);
241
236
 
242
237
  const claimPatterns = [
243
238
  {
244
- regex: /(\d+)\s*(?:-\s*)?(?:(?:parallel|domain(?:-specific)?|tribunal|code)\s+)*reviewers?\b/gi,
245
- entity: "reviewers",
239
+ regex:
240
+ /(\d+)\s*(?:-\s*)?(?:(?:parallel|domain(?:-specific)?|tribunal|code)\s+)*reviewers?\b/gi,
241
+ entity: 'reviewers',
246
242
  },
247
- { regex: /(\d+)\s*(?:specialist\s+)?agents?\b/gi, entity: "agents" },
248
- { regex: /(\d+)\s*(?:modular\s+)?skills?\b/gi, entity: "skills" },
249
- { regex: /(\d+)\s*(?:slash\s+)?workflows?\b/gi, entity: "workflows" },
250
- { regex: /(\d+)\s*(?:JS\s+)?scripts?\b/gi, entity: "scripts" },
243
+ { regex: /(\d+)\s*(?:specialist\s+)?agents?\b/gi, entity: 'agents' },
244
+ { regex: /(\d+)\s*(?:modular\s+)?skills?\b/gi, entity: 'skills' },
245
+ { regex: /(\d+)\s*(?:slash\s+)?workflows?\b/gi, entity: 'workflows' },
246
+ { regex: /(\d+)\s*(?:JS\s+)?scripts?\b/gi, entity: 'scripts' },
251
247
  ];
252
248
 
253
249
  for (let i = 0; i < lines.length; i++) {
@@ -290,16 +286,16 @@ function walkMdFiles(dir, fileList = []) {
290
286
  const stat = fs.statSync(fullPath);
291
287
  if (stat.isDirectory()) {
292
288
  // Skip node_modules, .git, history, .backups, .shared
293
- if (
294
- ["node_modules", ".git", "history", ".backups", ".shared"].includes(
295
- entry,
296
- )
297
- ) {
289
+ if (['node_modules', '.git', 'history', '.backups', '.shared'].includes(entry)) {
298
290
  continue;
299
291
  }
300
292
  walkMdFiles(fullPath, fileList);
301
- } else if (entry.endsWith(".md") || entry.endsWith(".json")) {
302
- if (entry.startsWith("http") || entry.startsWith("#") || entry.startsWith("https://github.com/")) {
293
+ } else if (entry.endsWith('.md') || entry.endsWith('.json')) {
294
+ if (
295
+ entry.startsWith('http') ||
296
+ entry.startsWith('#') ||
297
+ entry.startsWith('https://github.com/')
298
+ ) {
303
299
  continue;
304
300
  }
305
301
  fileList.push(fullPath);
@@ -354,7 +350,7 @@ function generateManifest(projectRoot) {
354
350
 
355
351
  // Phase 3: Deduplicate cross-references
356
352
  const seenRefs = new Set();
357
- const uniqueRefs = allRefs.filter((r) => {
353
+ const uniqueRefs = allRefs.filter(r => {
358
354
  const key = `${r.source}→${r.ref}`;
359
355
  if (seenRefs.has(key)) return false;
360
356
  seenRefs.add(key);
@@ -362,12 +358,10 @@ function generateManifest(projectRoot) {
362
358
  });
363
359
 
364
360
  // Phase 4: Build manifest
365
- let version = "unknown";
361
+ let version = 'unknown';
366
362
  try {
367
- const pkg = JSON.parse(
368
- safeReadFile(path.join(projectRoot, "package.json")) || "{}",
369
- );
370
- version = pkg.version || "unknown";
363
+ const pkg = JSON.parse(safeReadFile(path.join(projectRoot, 'package.json')) || '{}');
364
+ version = pkg.version || 'unknown';
371
365
  } catch {
372
366
  // Ignore
373
367
  }
@@ -382,8 +376,8 @@ function generateManifest(projectRoot) {
382
376
  cross_references: uniqueRefs,
383
377
  numeric_claims: allClaims,
384
378
  integrity: {
385
- phantom_references: uniqueRefs.filter((r) => !r.exists).length,
386
- invalid_claims: allClaims.filter((c) => !c.valid).length,
379
+ phantom_references: uniqueRefs.filter(r => !r.exists).length,
380
+ invalid_claims: allClaims.filter(c => !c.valid).length,
387
381
  total_references: uniqueRefs.length,
388
382
  total_claims: allClaims.length,
389
383
  },
@@ -395,13 +389,13 @@ function generateManifest(projectRoot) {
395
389
  // ── Persist Manifest ──────────────────────────────────────────────────────────
396
390
 
397
391
  function saveManifest(manifest, projectRoot) {
398
- const historyDir = path.join(projectRoot, AGENT_DIR_NAME, "history");
392
+ const historyDir = path.join(projectRoot, AGENT_DIR_NAME, 'history');
399
393
  if (!fs.existsSync(historyDir)) {
400
394
  fs.mkdirSync(historyDir, { recursive: true });
401
395
  }
402
396
 
403
- const outputPath = path.join(historyDir, "integrity_manifest.json");
404
- fs.writeFileSync(outputPath, JSON.stringify(manifest, null, 2), "utf8");
397
+ const outputPath = path.join(historyDir, 'integrity_manifest.json');
398
+ fs.writeFileSync(outputPath, JSON.stringify(manifest, null, 2), 'utf8');
405
399
  return outputPath;
406
400
  }
407
401
 
@@ -410,8 +404,8 @@ function saveManifest(manifest, projectRoot) {
410
404
  function main() {
411
405
  const args = process.argv.slice(2);
412
406
  const projectRoot = process.cwd();
413
- const outputJson = args.includes("--output") && args.includes("json");
414
- const validateOnly = args.includes("--validate");
407
+ const outputJson = args.includes('--output') && args.includes('json');
408
+ const validateOnly = args.includes('--validate');
415
409
 
416
410
  const manifest = generateManifest(projectRoot);
417
411
 
@@ -433,7 +427,9 @@ function main() {
433
427
  console.log(`\n🛡️ Integrity Manifest Generated`);
434
428
  console.log(` Path: ${outputPath}`);
435
429
  console.log(` ─────────────────────────────────`);
436
- console.log(` Agents: ${manifest.agents.total} (${manifest.agents.reviewer_count} reviewers)`);
430
+ console.log(
431
+ ` Agents: ${manifest.agents.total} (${manifest.agents.reviewer_count} reviewers)`,
432
+ );
437
433
  console.log(` Skills: ${manifest.skills.total}`);
438
434
  console.log(` Scripts: ${manifest.scripts.total}`);
439
435
  console.log(` Workflows: ${manifest.workflows.total}`);
@@ -443,7 +439,7 @@ function main() {
443
439
 
444
440
  if (integrity.phantom_references > 0) {
445
441
  console.log(` ⚠️ Phantom references: ${integrity.phantom_references}`);
446
- const phantoms = manifest.cross_references.filter((r) => !r.exists);
442
+ const phantoms = manifest.cross_references.filter(r => !r.exists);
447
443
  for (const p of phantoms) {
448
444
  console.log(` ❌ ${p.source} → ${p.ref}`);
449
445
  }
@@ -451,24 +447,20 @@ function main() {
451
447
 
452
448
  if (integrity.invalid_claims > 0) {
453
449
  console.log(` ⚠️ Invalid claims: ${integrity.invalid_claims}`);
454
- const invalid = manifest.numeric_claims.filter((c) => !c.valid);
450
+ const invalid = manifest.numeric_claims.filter(c => !c.valid);
455
451
  for (const c of invalid) {
456
452
  console.log(` ❌ ${c.source}: says "${c.claim}" but actual is ${c.actual}`);
457
453
  }
458
454
  }
459
455
 
460
- if (
461
- integrity.phantom_references === 0 &&
462
- integrity.invalid_claims === 0
463
- ) {
456
+ if (integrity.phantom_references === 0 && integrity.invalid_claims === 0) {
464
457
  console.log(` ✅ All references valid. All claims accurate.`);
465
458
  }
466
459
 
467
460
  console.log();
468
461
 
469
462
  if (validateOnly) {
470
- const exitCode =
471
- integrity.phantom_references > 0 || integrity.invalid_claims > 0 ? 1 : 0;
463
+ const exitCode = integrity.phantom_references > 0 || integrity.invalid_claims > 0 ? 1 : 0;
472
464
  process.exit(exitCode);
473
465
  }
474
466
  }
@@ -8,11 +8,11 @@
8
8
  * node .agent/scripts/lint_runner.js . --files src/index.ts src/utils.ts
9
9
  */
10
10
 
11
- "use strict";
11
+ 'use strict';
12
12
 
13
- const fs = require("fs");
14
- const path = require("path");
15
- const { spawnSync } = require("child_process");
13
+ const fs = require('fs');
14
+ const path = require('path');
15
+ const { spawnSync } = require('child_process');
16
16
 
17
17
  const {
18
18
  RED,
@@ -29,39 +29,38 @@ const {
29
29
  ok,
30
30
  fail,
31
31
  skip,
32
- } = require("./_colors");
32
+ } = require('./_colors');
33
33
 
34
34
  const RESULTS = [];
35
35
 
36
36
  function runLinter(label, cmd, cwd) {
37
37
  const elapsed = timer();
38
38
  try {
39
- const executable =
40
- process.platform === "win32" && cmd[0] === "npx" ? "npx.cmd" : cmd[0];
39
+ const executable = process.platform === 'win32' && cmd[0] === 'npx' ? 'npx.cmd' : cmd[0];
41
40
  const result = spawnSync(executable, cmd.slice(1), {
42
41
  cwd,
43
- encoding: "utf8",
42
+ encoding: 'utf8',
44
43
  timeout: 120000,
45
- shell: process.platform === "win32",
44
+ shell: process.platform === 'win32',
46
45
  });
47
46
 
48
47
  const ms = elapsed();
49
48
  if (result.status === 0) {
50
49
  ok(`${label} — clean ${DIM}(${formatMs(ms)})${RESET}`);
51
- RESULTS.push({ name: label, status: "pass", ms });
50
+ RESULTS.push({ name: label, status: 'pass', ms });
52
51
  return true;
53
52
  }
54
53
 
55
54
  fail(`${label} — issues found ${DIM}(${formatMs(ms)})${RESET}`);
56
- RESULTS.push({ name: label, status: "fail", ms });
55
+ RESULTS.push({ name: label, status: 'fail', ms });
57
56
  if (result.error) {
58
57
  console.log(` Error: ${result.error.message}`);
59
58
  }
60
- const out = result.stdout ? result.stdout.toString() : "";
61
- const err = result.stderr ? result.stderr.toString() : "";
62
- const output = (out + "\n" + err).trim();
59
+ const out = result.stdout ? result.stdout.toString() : '';
60
+ const err = result.stderr ? result.stderr.toString() : '';
61
+ const output = (out + '\n' + err).trim();
63
62
  if (output) {
64
- const lines = output.split("\n");
63
+ const lines = output.split('\n');
65
64
  for (const line of lines.slice(0, 15)) {
66
65
  console.log(` ${line}`);
67
66
  }
@@ -72,45 +71,41 @@ function runLinter(label, cmd, cwd) {
72
71
  return false;
73
72
  } catch {
74
73
  skip(`${label} — tool not installed`);
75
- RESULTS.push({ name: label, status: "skip" });
74
+ RESULTS.push({ name: label, status: 'skip' });
76
75
  return true;
77
76
  }
78
77
  }
79
78
 
80
79
  function detectLinters(projectRoot) {
81
80
  const available = {};
82
- const pkgJson = path.join(projectRoot, "package.json");
81
+ const pkgJson = path.join(projectRoot, 'package.json');
83
82
 
84
83
  if (fs.existsSync(pkgJson)) {
85
84
  const eslintFiles = [
86
- ".eslintrc",
87
- ".eslintrc.js",
88
- ".eslintrc.json",
89
- ".eslintrc.yml",
90
- "eslint.config.js",
91
- "eslint.config.mjs",
85
+ '.eslintrc',
86
+ '.eslintrc.js',
87
+ '.eslintrc.json',
88
+ '.eslintrc.yml',
89
+ 'eslint.config.js',
90
+ 'eslint.config.mjs',
92
91
  ];
93
- available.eslint = eslintFiles.some((f) =>
94
- fs.existsSync(path.join(projectRoot, f)),
95
- );
92
+ available.eslint = eslintFiles.some(f => fs.existsSync(path.join(projectRoot, f)));
96
93
 
97
94
  const prettierFiles = [
98
- ".prettierrc",
99
- ".prettierrc.js",
100
- ".prettierrc.json",
101
- "prettier.config.js",
95
+ '.prettierrc',
96
+ '.prettierrc.js',
97
+ '.prettierrc.json',
98
+ 'prettier.config.js',
102
99
  ];
103
- available.prettier = prettierFiles.some((f) =>
104
- fs.existsSync(path.join(projectRoot, f)),
105
- );
100
+ available.prettier = prettierFiles.some(f => fs.existsSync(path.join(projectRoot, f)));
106
101
  }
107
102
 
108
103
  available.ruff =
109
- fs.existsSync(path.join(projectRoot, "pyproject.toml")) ||
110
- fs.existsSync(path.join(projectRoot, "ruff.toml"));
104
+ fs.existsSync(path.join(projectRoot, 'pyproject.toml')) ||
105
+ fs.existsSync(path.join(projectRoot, 'ruff.toml'));
111
106
  available.flake8 =
112
- fs.existsSync(path.join(projectRoot, ".flake8")) ||
113
- fs.existsSync(path.join(projectRoot, "setup.cfg"));
107
+ fs.existsSync(path.join(projectRoot, '.flake8')) ||
108
+ fs.existsSync(path.join(projectRoot, 'setup.cfg'));
114
109
 
115
110
  return available;
116
111
  }
@@ -119,27 +114,25 @@ function main() {
119
114
  const args = process.argv.slice(2);
120
115
  let targetPath = null;
121
116
  let fixFlag = false;
122
- let fileArgs = [];
117
+ const fileArgs = [];
123
118
 
124
119
  let i = 0;
125
120
  while (i < args.length) {
126
- if (args[i] === "--fix") fixFlag = true;
127
- else if (args[i] === "--files") {
121
+ if (args[i] === '--fix') fixFlag = true;
122
+ else if (args[i] === '--files') {
128
123
  i++;
129
- while (i < args.length && !args[i].startsWith("--")) {
124
+ while (i < args.length && !args[i].startsWith('--')) {
130
125
  fileArgs.push(args[i++]);
131
126
  }
132
127
  continue;
133
- } else if (!targetPath && !args[i].startsWith("-")) {
128
+ } else if (!targetPath && !args[i].startsWith('-')) {
134
129
  targetPath = args[i];
135
130
  }
136
131
  i++;
137
132
  }
138
133
 
139
134
  if (!targetPath) {
140
- console.log(
141
- "Usage: node lint_runner.js <path> [--fix] [--files <file1> <file2> ...]",
142
- );
135
+ console.log('Usage: node lint_runner.js <path> [--fix] [--files <file1> <file2> ...]');
143
136
  process.exit(1);
144
137
  }
145
138
 
@@ -150,15 +143,15 @@ function main() {
150
143
  }
151
144
 
152
145
  console.log(
153
- banner("lint_runner.js", {
146
+ banner('lint_runner.js', {
154
147
  Project: projectRoot,
155
- Mode: fixFlag ? "fix" : "check",
148
+ Mode: fixFlag ? 'fix' : 'check',
156
149
  }),
157
150
  );
158
151
 
159
152
  const available = detectLinters(projectRoot);
160
153
  if (!Object.values(available).some(Boolean)) {
161
- skip("No linter configuration detected in this project");
154
+ skip('No linter configuration detected in this project');
162
155
  process.exit(0);
163
156
  }
164
157
 
@@ -166,45 +159,44 @@ function main() {
166
159
  let failures = 0;
167
160
 
168
161
  if (available.eslint) {
169
- console.log(sectionHeader("ESLint"));
170
- const cmd = ["npx", "eslint"];
171
- if (fixFlag) cmd.push("--fix");
162
+ console.log(sectionHeader('ESLint'));
163
+ const cmd = ['npx', 'eslint'];
164
+ if (fixFlag) cmd.push('--fix');
172
165
  if (fileArgs.length) cmd.push(...fileArgs);
173
- else cmd.push(".", "--max-warnings=0");
174
- if (!runLinter("ESLint", cmd, projectRoot)) failures++;
166
+ else cmd.push('.', '--max-warnings=0');
167
+ if (!runLinter('ESLint', cmd, projectRoot)) failures++;
175
168
  }
176
169
 
177
170
  if (available.prettier) {
178
- console.log(sectionHeader("Prettier"));
179
- const cmd = ["npx", "prettier"];
180
- if (fixFlag) cmd.push("--write");
181
- else cmd.push("--check");
171
+ console.log(sectionHeader('Prettier'));
172
+ const cmd = ['npx', 'prettier'];
173
+ if (fixFlag) cmd.push('--write');
174
+ else cmd.push('--check');
182
175
  if (fileArgs.length) cmd.push(...fileArgs);
183
- else cmd.push(".");
184
- if (!runLinter("Prettier", cmd, projectRoot)) failures++;
176
+ else cmd.push('.');
177
+ if (!runLinter('Prettier', cmd, projectRoot)) failures++;
185
178
  }
186
179
 
187
180
  if (available.ruff) {
188
- console.log(sectionHeader("Ruff (Python)"));
189
- const cmd = ["ruff", "check"];
190
- if (fixFlag) cmd.push("--fix");
181
+ console.log(sectionHeader('Ruff (Python)'));
182
+ const cmd = ['ruff', 'check'];
183
+ if (fixFlag) cmd.push('--fix');
191
184
  if (fileArgs.length) cmd.push(...fileArgs);
192
- else cmd.push(".");
193
- if (!runLinter("Ruff", cmd, projectRoot)) failures++;
185
+ else cmd.push('.');
186
+ if (!runLinter('Ruff', cmd, projectRoot)) failures++;
194
187
  }
195
188
 
196
189
  if (available.flake8 && !available.ruff) {
197
- console.log(sectionHeader("Flake8 (Python)"));
198
- const cmd = ["flake8"];
190
+ console.log(sectionHeader('Flake8 (Python)'));
191
+ const cmd = ['flake8'];
199
192
  if (fileArgs.length) cmd.push(...fileArgs);
200
- else cmd.push(".");
201
- if (!runLinter("Flake8", cmd, projectRoot)) failures++;
193
+ else cmd.push('.');
194
+ if (!runLinter('Flake8', cmd, projectRoot)) failures++;
202
195
  }
203
196
 
204
- if (fs.existsSync(path.join(projectRoot, "tsconfig.json"))) {
205
- console.log(sectionHeader("TypeScript"));
206
- if (!runLinter("TypeScript", ["npx", "tsc", "--noEmit"], projectRoot))
207
- failures++;
197
+ if (fs.existsSync(path.join(projectRoot, 'tsconfig.json'))) {
198
+ console.log(sectionHeader('TypeScript'));
199
+ if (!runLinter('TypeScript', ['npx', 'tsc', '--noEmit'], projectRoot)) failures++;
208
200
  }
209
201
 
210
202
  console.log(`\n${BOLD}${CYAN}━━━ Lint Summary ━━━${RESET}`);
@@ -215,9 +207,7 @@ function main() {
215
207
  if (failures === 0) {
216
208
  console.log(`\n${GREEN}${BOLD} ✔ All linters passed.${RESET}\n`);
217
209
  } else {
218
- console.log(
219
- `\n${RED}${BOLD} ✖ ${failures} linter(s) reported issues.${RESET}\n`,
220
- );
210
+ console.log(`\n${RED}${BOLD} ✖ ${failures} linter(s) reported issues.${RESET}\n`);
221
211
  }
222
212
 
223
213
  process.exit(failures > 0 ? 1 : 0);