@heyai-rules/pilo-masterkit 1.2.2 → 2.1.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 (708) hide show
  1. package/.agent/agents/PILO_MASTER.md +77 -77
  2. package/.agent/agents/backend-specialist.md +263 -263
  3. package/.agent/agents/code-archaeologist.md +106 -106
  4. package/.agent/agents/csharp-reviewer.md +101 -0
  5. package/.agent/agents/dart-build-resolver.md +201 -0
  6. package/.agent/agents/database-architect.md +226 -226
  7. package/.agent/agents/debugger.md +225 -225
  8. package/.agent/agents/devops-engineer.md +242 -242
  9. package/.agent/agents/documentation-writer.md +104 -104
  10. package/.agent/agents/explorer-agent.md +73 -73
  11. package/.agent/agents/frontend-specialist.md +593 -593
  12. package/.agent/agents/game-developer.md +162 -162
  13. package/.agent/agents/gan-evaluator.md +209 -0
  14. package/.agent/agents/gan-generator.md +131 -0
  15. package/.agent/agents/gan-planner.md +99 -0
  16. package/.agent/agents/healthcare-reviewer.md +83 -0
  17. package/.agent/agents/mobile-developer.md +377 -377
  18. package/.agent/agents/opensource-forker.md +198 -0
  19. package/.agent/agents/opensource-packager.md +249 -0
  20. package/.agent/agents/opensource-sanitizer.md +188 -0
  21. package/.agent/agents/orchestrator.md +416 -416
  22. package/.agent/agents/penetration-tester.md +188 -188
  23. package/.agent/agents/performance-optimizer.md +446 -187
  24. package/.agent/agents/personas/athena-agent/agent.json +10 -0
  25. package/.agent/agents/personas/athena-agent/athena-backend-logic-architecture-profile.md +189 -0
  26. package/.agent/agents/personas/athena-agent/context-files/agents.md +55 -0
  27. package/.agent/agents/personas/athena-agent/context-files/identity.md +23 -0
  28. package/.agent/agents/personas/athena-agent/context-files/soul.md +51 -0
  29. package/.agent/agents/personas/athena-agent/context-files/user-predefined.md +15 -0
  30. package/.agent/agents/personas/athena-agent/user-context-files/system/bootstrap.md +37 -0
  31. package/.agent/agents/personas/athena-agent/user-context-files/system/user.md +45 -0
  32. package/.agent/agents/personas/da-vinci-agent/agent.json +10 -0
  33. package/.agent/agents/personas/da-vinci-agent/context-files/agents.md +55 -0
  34. package/.agent/agents/personas/da-vinci-agent/context-files/identity.md +23 -0
  35. package/.agent/agents/personas/da-vinci-agent/context-files/soul.md +51 -0
  36. package/.agent/agents/personas/da-vinci-agent/context-files/user-predefined.md +15 -0
  37. package/.agent/agents/personas/da-vinci-agent/da-vinci-frontend-ui-ux-design-profile.md +189 -0
  38. package/.agent/agents/personas/da-vinci-agent/user-context-files/system/bootstrap.md +37 -0
  39. package/.agent/agents/personas/da-vinci-agent/user-context-files/system/user.md +45 -0
  40. package/.agent/agents/personas/duong-tang-agent/agent.json +10 -0
  41. package/.agent/agents/personas/duong-tang-agent/context-files/agents.md +55 -0
  42. package/.agent/agents/personas/duong-tang-agent/context-files/identity.md +23 -0
  43. package/.agent/agents/personas/duong-tang-agent/context-files/soul.md +51 -0
  44. package/.agent/agents/personas/duong-tang-agent/context-files/user-predefined.md +15 -0
  45. package/.agent/agents/personas/duong-tang-agent/tang-monk-quality-testing-documentation-profile.md +189 -0
  46. package/.agent/agents/personas/duong-tang-agent/user-context-files/system/bootstrap.md +37 -0
  47. package/.agent/agents/personas/duong-tang-agent/user-context-files/system/user.md +45 -0
  48. package/.agent/agents/personas/gia-cat-luong-agent/agent.json +10 -0
  49. package/.agent/agents/personas/gia-cat-luong-agent/context-files/agents.md +55 -0
  50. package/.agent/agents/personas/gia-cat-luong-agent/context-files/identity.md +23 -0
  51. package/.agent/agents/personas/gia-cat-luong-agent/context-files/soul.md +51 -0
  52. package/.agent/agents/personas/gia-cat-luong-agent/context-files/user-predefined.md +15 -0
  53. package/.agent/agents/personas/gia-cat-luong-agent/kongming-research-strategy-analysis-profile.md +189 -0
  54. package/.agent/agents/personas/gia-cat-luong-agent/user-context-files/system/bootstrap.md +37 -0
  55. package/.agent/agents/personas/gia-cat-luong-agent/user-context-files/system/user.md +45 -0
  56. package/.agent/agents/personas/mihata-agent/agent.json +10 -0
  57. package/.agent/agents/personas/mihata-agent/context-files/agents.md +55 -0
  58. package/.agent/agents/personas/mihata-agent/context-files/identity.md +23 -0
  59. package/.agent/agents/personas/mihata-agent/context-files/soul.md +51 -0
  60. package/.agent/agents/personas/mihata-agent/context-files/user-predefined.md +15 -0
  61. package/.agent/agents/personas/mihata-agent/mihata-multi-agent-orchestration-profile.md +189 -0
  62. package/.agent/agents/personas/mihata-agent/user-context-files/system/bootstrap.md +37 -0
  63. package/.agent/agents/personas/mihata-agent/user-context-files/system/user.md +45 -0
  64. package/.agent/agents/personas/tesla-agent/agent.json +10 -0
  65. package/.agent/agents/personas/tesla-agent/context-files/agents.md +55 -0
  66. package/.agent/agents/personas/tesla-agent/context-files/identity.md +23 -0
  67. package/.agent/agents/personas/tesla-agent/context-files/soul.md +51 -0
  68. package/.agent/agents/personas/tesla-agent/context-files/user-predefined.md +15 -0
  69. package/.agent/agents/personas/tesla-agent/tesla-fullstack-system-optimization-profile.md +189 -0
  70. package/.agent/agents/personas/tesla-agent/user-context-files/system/bootstrap.md +37 -0
  71. package/.agent/agents/personas/tesla-agent/user-context-files/system/user.md +45 -0
  72. package/.agent/agents/personas/tu-ma-y-agent/agent.json +10 -0
  73. package/.agent/agents/personas/tu-ma-y-agent/context-files/agents.md +55 -0
  74. package/.agent/agents/personas/tu-ma-y-agent/context-files/identity.md +23 -0
  75. package/.agent/agents/personas/tu-ma-y-agent/context-files/soul.md +51 -0
  76. package/.agent/agents/personas/tu-ma-y-agent/context-files/user-predefined.md +15 -0
  77. package/.agent/agents/personas/tu-ma-y-agent/simayi-feasibility-risk-control-profile.md +189 -0
  78. package/.agent/agents/personas/tu-ma-y-agent/user-context-files/system/bootstrap.md +37 -0
  79. package/.agent/agents/personas/tu-ma-y-agent/user-context-files/system/user.md +45 -0
  80. package/.agent/agents/personas/venti-agent/agent.json +10 -0
  81. package/.agent/agents/personas/venti-agent/context-files/agents.md +55 -0
  82. package/.agent/agents/personas/venti-agent/context-files/identity.md +23 -0
  83. package/.agent/agents/personas/venti-agent/context-files/soul.md +51 -0
  84. package/.agent/agents/personas/venti-agent/context-files/user-predefined.md +15 -0
  85. package/.agent/agents/personas/venti-agent/user-context-files/system/bootstrap.md +37 -0
  86. package/.agent/agents/personas/venti-agent/user-context-files/system/user.md +45 -0
  87. package/.agent/agents/personas/venti-agent/venti-learning-communication-mentoring-profile.md +189 -0
  88. package/.agent/agents/product-manager.md +112 -112
  89. package/.agent/agents/product-owner.md +95 -95
  90. package/.agent/agents/project-planner.md +406 -406
  91. package/.agent/agents/qa-automation-engineer.md +103 -103
  92. package/.agent/agents/security-auditor.md +170 -170
  93. package/.agent/agents/seo-specialist.md +111 -111
  94. package/.agent/agents/test-engineer.md +158 -158
  95. package/.agent/contexts/dev.md +20 -0
  96. package/.agent/contexts/research.md +26 -0
  97. package/.agent/contexts/review.md +22 -0
  98. package/.agent/hooks/hooks.json +395 -0
  99. package/.agent/hooks/readme.md +222 -0
  100. package/.agent/mcp-configs/mcp-servers.json +181 -0
  101. package/.agent/rules/ARCHITECTURAL_BLUEPRINTS.md +62 -62
  102. package/.agent/rules/CODE_CRAFTSMANSHIP.md +69 -69
  103. package/.agent/rules/CORE_RULES.md +72 -72
  104. package/.agent/rules/PROJECT_MAP.md +58 -58
  105. package/.agent/rules/QUALITY_ASSURANCE.md +54 -54
  106. package/.agent/rules/SECURITY_ARMOR.md +44 -44
  107. package/.agent/rules/VERSION_ORCHESTRATION.md +64 -64
  108. package/.agent/rules/WORKFLOW_ORCHESTRATION.md +55 -55
  109. package/.agent/rules/common/agents.md +50 -0
  110. package/.agent/rules/common/code-review.md +124 -0
  111. package/.agent/rules/common/coding-style.md +48 -0
  112. package/.agent/rules/common/development-workflow.md +44 -0
  113. package/.agent/rules/common/git-workflow.md +24 -0
  114. package/.agent/rules/common/hooks.md +30 -0
  115. package/.agent/rules/common/patterns.md +31 -0
  116. package/.agent/rules/common/performance.md +55 -0
  117. package/.agent/rules/common/security.md +29 -0
  118. package/.agent/rules/common/testing.md +29 -0
  119. package/.agent/rules/cpp/coding-style.md +44 -0
  120. package/.agent/rules/cpp/hooks.md +39 -0
  121. package/.agent/rules/cpp/patterns.md +51 -0
  122. package/.agent/rules/cpp/security.md +51 -0
  123. package/.agent/rules/cpp/testing.md +44 -0
  124. package/.agent/rules/csharp/coding-style.md +72 -0
  125. package/.agent/rules/csharp/hooks.md +25 -0
  126. package/.agent/rules/csharp/patterns.md +50 -0
  127. package/.agent/rules/csharp/security.md +58 -0
  128. package/.agent/rules/csharp/testing.md +46 -0
  129. package/.agent/rules/dart/coding-style.md +159 -0
  130. package/.agent/rules/dart/hooks.md +66 -0
  131. package/.agent/rules/dart/patterns.md +261 -0
  132. package/.agent/rules/dart/security.md +135 -0
  133. package/.agent/rules/dart/testing.md +215 -0
  134. package/.agent/rules/golang/coding-style.md +32 -0
  135. package/.agent/rules/golang/hooks.md +17 -0
  136. package/.agent/rules/golang/patterns.md +45 -0
  137. package/.agent/rules/golang/security.md +34 -0
  138. package/.agent/rules/golang/testing.md +31 -0
  139. package/.agent/rules/java/coding-style.md +114 -0
  140. package/.agent/rules/java/hooks.md +18 -0
  141. package/.agent/rules/java/patterns.md +146 -0
  142. package/.agent/rules/java/security.md +100 -0
  143. package/.agent/rules/java/testing.md +131 -0
  144. package/.agent/rules/kotlin/coding-style.md +86 -0
  145. package/.agent/rules/kotlin/hooks.md +17 -0
  146. package/.agent/rules/kotlin/patterns.md +146 -0
  147. package/.agent/rules/kotlin/security.md +82 -0
  148. package/.agent/rules/kotlin/testing.md +128 -0
  149. package/.agent/rules/perl/coding-style.md +46 -0
  150. package/.agent/rules/perl/hooks.md +22 -0
  151. package/.agent/rules/perl/patterns.md +76 -0
  152. package/.agent/rules/perl/security.md +69 -0
  153. package/.agent/rules/perl/testing.md +54 -0
  154. package/.agent/rules/php/coding-style.md +40 -0
  155. package/.agent/rules/php/hooks.md +24 -0
  156. package/.agent/rules/php/patterns.md +33 -0
  157. package/.agent/rules/php/security.md +37 -0
  158. package/.agent/rules/php/testing.md +39 -0
  159. package/.agent/rules/python/coding-style.md +42 -0
  160. package/.agent/rules/python/hooks.md +19 -0
  161. package/.agent/rules/python/patterns.md +39 -0
  162. package/.agent/rules/python/security.md +30 -0
  163. package/.agent/rules/python/testing.md +38 -0
  164. package/.agent/rules/readme.md +111 -0
  165. package/.agent/rules/rust/coding-style.md +151 -0
  166. package/.agent/rules/rust/hooks.md +16 -0
  167. package/.agent/rules/rust/patterns.md +168 -0
  168. package/.agent/rules/rust/security.md +141 -0
  169. package/.agent/rules/rust/testing.md +154 -0
  170. package/.agent/rules/swift/coding-style.md +47 -0
  171. package/.agent/rules/swift/hooks.md +20 -0
  172. package/.agent/rules/swift/patterns.md +66 -0
  173. package/.agent/rules/swift/security.md +33 -0
  174. package/.agent/rules/swift/testing.md +45 -0
  175. package/.agent/rules/typescript/coding-style.md +199 -0
  176. package/.agent/rules/typescript/hooks.md +22 -0
  177. package/.agent/rules/typescript/patterns.md +52 -0
  178. package/.agent/rules/typescript/security.md +28 -0
  179. package/.agent/rules/typescript/testing.md +18 -0
  180. package/.agent/rules/web/coding-style.md +96 -0
  181. package/.agent/rules/web/design-quality.md +63 -0
  182. package/.agent/rules/web/hooks.md +120 -0
  183. package/.agent/rules/web/patterns.md +79 -0
  184. package/.agent/rules/web/performance.md +64 -0
  185. package/.agent/rules/web/security.md +57 -0
  186. package/.agent/rules/web/testing.md +55 -0
  187. package/.agent/rules/zh/agents.md +50 -0
  188. package/.agent/rules/zh/code-review.md +124 -0
  189. package/.agent/rules/zh/coding-style.md +48 -0
  190. package/.agent/rules/zh/development-workflow.md +44 -0
  191. package/.agent/rules/zh/git-workflow.md +24 -0
  192. package/.agent/rules/zh/hooks.md +30 -0
  193. package/.agent/rules/zh/patterns.md +31 -0
  194. package/.agent/rules/zh/performance.md +55 -0
  195. package/.agent/rules/zh/readme.md +108 -0
  196. package/.agent/rules/zh/security.md +29 -0
  197. package/.agent/rules/zh/testing.md +29 -0
  198. package/.agent/scripts/auto_preview.py +148 -148
  199. package/.agent/scripts/checklist.py +217 -217
  200. package/.agent/scripts/session_manager.py +120 -120
  201. package/.agent/scripts/verify_all.py +327 -327
  202. package/.agent/skills/agent-eval/SKILL.md +145 -0
  203. package/.agent/skills/agent-harness-construction/SKILL.md +73 -0
  204. package/.agent/skills/agent-payment-x402/SKILL.md +178 -0
  205. package/.agent/skills/agentic-engineering/SKILL.md +63 -0
  206. package/.agent/skills/ai-first-engineering/SKILL.md +51 -0
  207. package/.agent/skills/ai-regression-testing/SKILL.md +385 -0
  208. package/.agent/skills/android-clean-architecture/SKILL.md +339 -0
  209. package/.agent/skills/api-design/SKILL.md +523 -0
  210. package/.agent/skills/api-patterns/SKILL.md +81 -81
  211. package/.agent/skills/api-patterns/api-style.md +42 -42
  212. package/.agent/skills/api-patterns/auth.md +24 -24
  213. package/.agent/skills/api-patterns/documentation.md +26 -26
  214. package/.agent/skills/api-patterns/graphql.md +41 -41
  215. package/.agent/skills/api-patterns/rate-limiting.md +31 -31
  216. package/.agent/skills/api-patterns/response.md +37 -37
  217. package/.agent/skills/api-patterns/rest.md +40 -40
  218. package/.agent/skills/api-patterns/scripts/api_validator.py +211 -211
  219. package/.agent/skills/api-patterns/security-testing.md +122 -122
  220. package/.agent/skills/api-patterns/trpc.md +41 -41
  221. package/.agent/skills/api-patterns/versioning.md +22 -22
  222. package/.agent/skills/app-builder/SKILL.md +75 -75
  223. package/.agent/skills/app-builder/agent-coordination.md +71 -71
  224. package/.agent/skills/app-builder/feature-building.md +53 -53
  225. package/.agent/skills/app-builder/project-detection.md +34 -34
  226. package/.agent/skills/app-builder/scaffolding.md +118 -118
  227. package/.agent/skills/app-builder/tech-stack.md +41 -41
  228. package/.agent/skills/app-builder/templates/SKILL.md +39 -39
  229. package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +76 -76
  230. package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +92 -92
  231. package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +88 -88
  232. package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +88 -88
  233. package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +83 -83
  234. package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +90 -90
  235. package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +90 -90
  236. package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +122 -122
  237. package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +122 -122
  238. package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +169 -169
  239. package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +134 -134
  240. package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +83 -83
  241. package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +119 -119
  242. package/.agent/skills/architecture/SKILL.md +55 -55
  243. package/.agent/skills/architecture/context-discovery.md +43 -43
  244. package/.agent/skills/architecture/examples.md +94 -94
  245. package/.agent/skills/architecture/pattern-selection.md +68 -68
  246. package/.agent/skills/architecture/patterns-reference.md +50 -50
  247. package/.agent/skills/architecture/trade-off-analysis.md +77 -77
  248. package/.agent/skills/architecture-decision-records/SKILL.md +179 -0
  249. package/.agent/skills/article-writing/SKILL.md +79 -0
  250. package/.agent/skills/autonomous-agent-harness/SKILL.md +267 -0
  251. package/.agent/skills/autonomous-loops/SKILL.md +610 -0
  252. package/.agent/skills/backend-patterns/SKILL.md +598 -0
  253. package/.agent/skills/bash-linux/SKILL.md +199 -199
  254. package/.agent/skills/behavioral-modes/SKILL.md +242 -242
  255. package/.agent/skills/benchmark/SKILL.md +93 -0
  256. package/.agent/skills/blueprint/SKILL.md +105 -0
  257. package/.agent/skills/brainstorming/SKILL.md +163 -163
  258. package/.agent/skills/brainstorming/dynamic-questioning.md +350 -350
  259. package/.agent/skills/brand-voice/SKILL.md +97 -0
  260. package/.agent/skills/brand-voice/references/voice-profile-schema.md +55 -0
  261. package/.agent/skills/browser-qa/SKILL.md +87 -0
  262. package/.agent/skills/bun-runtime/SKILL.md +84 -0
  263. package/.agent/skills/canary-watch/SKILL.md +99 -0
  264. package/.agent/skills/carrier-relationship-management/SKILL.md +212 -0
  265. package/.agent/skills/ck/SKILL.md +147 -0
  266. package/.agent/skills/ck/commands/forget.mjs +44 -0
  267. package/.agent/skills/ck/commands/info.mjs +24 -0
  268. package/.agent/skills/ck/commands/init.mjs +143 -0
  269. package/.agent/skills/ck/commands/list.mjs +40 -0
  270. package/.agent/skills/ck/commands/migrate.mjs +202 -0
  271. package/.agent/skills/ck/commands/resume.mjs +36 -0
  272. package/.agent/skills/ck/commands/save.mjs +210 -0
  273. package/.agent/skills/ck/commands/shared.mjs +387 -0
  274. package/.agent/skills/ck/hooks/session-start.mjs +224 -0
  275. package/.agent/skills/claude-api/SKILL.md +337 -0
  276. package/.agent/skills/claude-devfleet/SKILL.md +103 -0
  277. package/.agent/skills/clean-code/SKILL.md +201 -201
  278. package/.agent/skills/click-path-audit/SKILL.md +244 -0
  279. package/.agent/skills/clickhouse-io/SKILL.md +439 -0
  280. package/.agent/skills/code-review-checklist/SKILL.md +109 -109
  281. package/.agent/skills/codebase-onboarding/SKILL.md +233 -0
  282. package/.agent/skills/coding-standards/SKILL.md +530 -0
  283. package/.agent/skills/compose-multiplatform-patterns/SKILL.md +299 -0
  284. package/.agent/skills/configure-ecc/SKILL.md +367 -0
  285. package/.agent/skills/connections-optimizer/SKILL.md +189 -0
  286. package/.agent/skills/content-engine/SKILL.md +131 -0
  287. package/.agent/skills/content-hash-cache-pattern/SKILL.md +161 -0
  288. package/.agent/skills/context-budget/SKILL.md +135 -0
  289. package/.agent/skills/continuous-agent-loop/SKILL.md +45 -0
  290. package/.agent/skills/continuous-learning/SKILL.md +119 -0
  291. package/.agent/skills/continuous-learning/config.json +18 -0
  292. package/.agent/skills/continuous-learning/evaluate-session.sh +69 -0
  293. package/.agent/skills/continuous-learning-v2/SKILL.md +365 -0
  294. package/.agent/skills/continuous-learning-v2/agents/observer-loop.sh +271 -0
  295. package/.agent/skills/continuous-learning-v2/agents/observer.md +198 -0
  296. package/.agent/skills/continuous-learning-v2/agents/session-guardian.sh +150 -0
  297. package/.agent/skills/continuous-learning-v2/agents/start-observer.sh +244 -0
  298. package/.agent/skills/continuous-learning-v2/config.json +8 -0
  299. package/.agent/skills/continuous-learning-v2/hooks/observe.sh +428 -0
  300. package/.agent/skills/continuous-learning-v2/scripts/detect-project.sh +228 -0
  301. package/.agent/skills/continuous-learning-v2/scripts/instinct-cli.py +1426 -0
  302. package/.agent/skills/continuous-learning-v2/scripts/test-parse-instinct.py +984 -0
  303. package/.agent/skills/cost-aware-llm-pipeline/SKILL.md +183 -0
  304. package/.agent/skills/cpp-coding-standards/SKILL.md +723 -0
  305. package/.agent/skills/cpp-testing/SKILL.md +324 -0
  306. package/.agent/skills/crosspost/SKILL.md +111 -0
  307. package/.agent/skills/csharp-testing/SKILL.md +321 -0
  308. package/.agent/skills/customer-billing-ops/SKILL.md +140 -0
  309. package/.agent/skills/customs-trade-compliance/SKILL.md +263 -0
  310. package/.agent/skills/dart-flutter-patterns/SKILL.md +563 -0
  311. package/.agent/skills/data-scraper-agent/SKILL.md +764 -0
  312. package/.agent/skills/database-design/SKILL.md +52 -52
  313. package/.agent/skills/database-design/database-selection.md +43 -43
  314. package/.agent/skills/database-design/indexing.md +39 -39
  315. package/.agent/skills/database-design/migrations.md +48 -48
  316. package/.agent/skills/database-design/optimization.md +36 -36
  317. package/.agent/skills/database-design/orm-selection.md +30 -30
  318. package/.agent/skills/database-design/schema-design.md +56 -56
  319. package/.agent/skills/database-design/scripts/schema_validator.py +172 -172
  320. package/.agent/skills/database-migrations/SKILL.md +429 -0
  321. package/.agent/skills/deep-research/SKILL.md +155 -0
  322. package/.agent/skills/deployment-patterns/SKILL.md +427 -0
  323. package/.agent/skills/deployment-procedures/SKILL.md +241 -241
  324. package/.agent/skills/design-system/SKILL.md +82 -0
  325. package/.agent/skills/django-patterns/SKILL.md +734 -0
  326. package/.agent/skills/django-security/SKILL.md +593 -0
  327. package/.agent/skills/django-tdd/SKILL.md +729 -0
  328. package/.agent/skills/django-verification/SKILL.md +469 -0
  329. package/.agent/skills/dmux-workflows/SKILL.md +191 -0
  330. package/.agent/skills/doc.md +177 -177
  331. package/.agent/skills/docker-patterns/SKILL.md +364 -0
  332. package/.agent/skills/documentation-lookup/SKILL.md +90 -0
  333. package/.agent/skills/documentation-templates/SKILL.md +194 -194
  334. package/.agent/skills/dotnet-patterns/SKILL.md +321 -0
  335. package/.agent/skills/e2e-testing/SKILL.md +326 -0
  336. package/.agent/skills/energy-procurement/SKILL.md +228 -0
  337. package/.agent/skills/enterprise-agent-ops/SKILL.md +50 -0
  338. package/.agent/skills/eval-harness/SKILL.md +270 -0
  339. package/.agent/skills/exa-search/SKILL.md +103 -0
  340. package/.agent/skills/fal-ai-media/SKILL.md +284 -0
  341. package/.agent/skills/flutter-dart-code-review/SKILL.md +435 -0
  342. package/.agent/skills/foundation-models-on-device/SKILL.md +243 -0
  343. package/.agent/skills/frontend-design/SKILL.md +452 -452
  344. package/.agent/skills/frontend-design/animation-guide.md +331 -331
  345. package/.agent/skills/frontend-design/color-system.md +311 -311
  346. package/.agent/skills/frontend-design/decision-trees.md +418 -418
  347. package/.agent/skills/frontend-design/motion-graphics.md +306 -306
  348. package/.agent/skills/frontend-design/scripts/accessibility_checker.py +183 -183
  349. package/.agent/skills/frontend-design/scripts/ux_audit.py +722 -722
  350. package/.agent/skills/frontend-design/typography-system.md +345 -345
  351. package/.agent/skills/frontend-design/ux-psychology.md +1116 -1116
  352. package/.agent/skills/frontend-design/visual-effects.md +383 -383
  353. package/.agent/skills/frontend-patterns/SKILL.md +642 -0
  354. package/.agent/skills/frontend-slides/SKILL.md +184 -0
  355. package/.agent/skills/frontend-slides/style-presets.md +330 -0
  356. package/.agent/skills/game-development/2d-games/SKILL.md +119 -119
  357. package/.agent/skills/game-development/3d-games/SKILL.md +135 -135
  358. package/.agent/skills/game-development/SKILL.md +167 -167
  359. package/.agent/skills/game-development/game-art/SKILL.md +185 -185
  360. package/.agent/skills/game-development/game-audio/SKILL.md +190 -190
  361. package/.agent/skills/game-development/game-design/SKILL.md +129 -129
  362. package/.agent/skills/game-development/mobile-games/SKILL.md +108 -108
  363. package/.agent/skills/game-development/multiplayer/SKILL.md +132 -132
  364. package/.agent/skills/game-development/pc-games/SKILL.md +144 -144
  365. package/.agent/skills/game-development/vr-ar/SKILL.md +123 -123
  366. package/.agent/skills/game-development/web-games/SKILL.md +150 -150
  367. package/.agent/skills/gan-style-harness/SKILL.md +278 -0
  368. package/.agent/skills/geo-fundamentals/SKILL.md +156 -156
  369. package/.agent/skills/geo-fundamentals/scripts/geo_checker.py +289 -289
  370. package/.agent/skills/git-workflow/SKILL.md +715 -0
  371. package/.agent/skills/golang-patterns/SKILL.md +674 -0
  372. package/.agent/skills/golang-testing/SKILL.md +720 -0
  373. package/.agent/skills/google-workspace-ops/SKILL.md +95 -0
  374. package/.agent/skills/healthcare-cdss-patterns/SKILL.md +245 -0
  375. package/.agent/skills/healthcare-emr-patterns/SKILL.md +159 -0
  376. package/.agent/skills/healthcare-eval-harness/SKILL.md +207 -0
  377. package/.agent/skills/healthcare-phi-compliance/SKILL.md +145 -0
  378. package/.agent/skills/hexagonal-architecture/SKILL.md +276 -0
  379. package/.agent/skills/i18n-localization/SKILL.md +154 -154
  380. package/.agent/skills/i18n-localization/scripts/i18n_checker.py +241 -241
  381. package/.agent/skills/intelligent-routing/SKILL.md +335 -335
  382. package/.agent/skills/inventory-demand-planning/SKILL.md +247 -0
  383. package/.agent/skills/investor-materials/SKILL.md +96 -0
  384. package/.agent/skills/investor-outreach/SKILL.md +91 -0
  385. package/.agent/skills/iterative-retrieval/SKILL.md +211 -0
  386. package/.agent/skills/java-coding-standards/SKILL.md +147 -0
  387. package/.agent/skills/jira-integration/SKILL.md +293 -0
  388. package/.agent/skills/jpa-patterns/SKILL.md +151 -0
  389. package/.agent/skills/kotlin-coroutines-flows/SKILL.md +284 -0
  390. package/.agent/skills/kotlin-exposed-patterns/SKILL.md +719 -0
  391. package/.agent/skills/kotlin-ktor-patterns/SKILL.md +689 -0
  392. package/.agent/skills/kotlin-patterns/SKILL.md +711 -0
  393. package/.agent/skills/kotlin-testing/SKILL.md +824 -0
  394. package/.agent/skills/laravel-patterns/SKILL.md +415 -0
  395. package/.agent/skills/laravel-plugin-discovery/SKILL.md +229 -0
  396. package/.agent/skills/laravel-security/SKILL.md +285 -0
  397. package/.agent/skills/laravel-tdd/SKILL.md +283 -0
  398. package/.agent/skills/laravel-verification/SKILL.md +179 -0
  399. package/.agent/skills/lead-intelligence/SKILL.md +321 -0
  400. package/.agent/skills/lead-intelligence/agents/enrichment-agent.md +85 -0
  401. package/.agent/skills/lead-intelligence/agents/mutual-mapper.md +75 -0
  402. package/.agent/skills/lead-intelligence/agents/outreach-drafter.md +98 -0
  403. package/.agent/skills/lead-intelligence/agents/signal-scorer.md +60 -0
  404. package/.agent/skills/lint-and-validate/SKILL.md +45 -45
  405. package/.agent/skills/lint-and-validate/scripts/lint_runner.py +184 -184
  406. package/.agent/skills/lint-and-validate/scripts/type_coverage.py +173 -173
  407. package/.agent/skills/liquid-glass-design/SKILL.md +279 -0
  408. package/.agent/skills/logistics-exception-management/SKILL.md +222 -0
  409. package/.agent/skills/manim-video/SKILL.md +89 -0
  410. package/.agent/skills/manim-video/assets/network-graph-scene.py +52 -0
  411. package/.agent/skills/market-research/SKILL.md +75 -0
  412. package/.agent/skills/mcp-builder/SKILL.md +173 -113
  413. package/.agent/skills/mcp-builder/license.txt +202 -0
  414. package/.agent/skills/mcp-builder/reference/evaluation.md +602 -0
  415. package/.agent/skills/mcp-builder/reference/mcp-best-practices.md +249 -0
  416. package/.agent/skills/mcp-builder/reference/node-mcp-server.md +970 -0
  417. package/.agent/skills/mcp-builder/reference/python-mcp-server.md +719 -0
  418. package/.agent/skills/mcp-builder/scripts/connections.py +151 -0
  419. package/.agent/skills/mcp-builder/scripts/evaluation.py +373 -0
  420. package/.agent/skills/mcp-builder/scripts/example-evaluation.xml +22 -0
  421. package/.agent/skills/mcp-builder/scripts/requirements.txt +2 -0
  422. package/.agent/skills/mcp-server-patterns/SKILL.md +67 -0
  423. package/.agent/skills/mobile-design/SKILL.md +394 -394
  424. package/.agent/skills/mobile-design/decision-trees.md +516 -516
  425. package/.agent/skills/mobile-design/mobile-backend.md +491 -491
  426. package/.agent/skills/mobile-design/mobile-color-system.md +420 -420
  427. package/.agent/skills/mobile-design/mobile-debugging.md +122 -122
  428. package/.agent/skills/mobile-design/mobile-design-thinking.md +357 -357
  429. package/.agent/skills/mobile-design/mobile-navigation.md +458 -458
  430. package/.agent/skills/mobile-design/mobile-performance.md +767 -767
  431. package/.agent/skills/mobile-design/mobile-testing.md +356 -356
  432. package/.agent/skills/mobile-design/mobile-typography.md +433 -433
  433. package/.agent/skills/mobile-design/platform-android.md +666 -666
  434. package/.agent/skills/mobile-design/platform-ios.md +561 -561
  435. package/.agent/skills/mobile-design/scripts/mobile_audit.py +670 -670
  436. package/.agent/skills/mobile-design/touch-psychology.md +537 -537
  437. package/.agent/skills/nanoclaw-repl/SKILL.md +33 -0
  438. package/.agent/skills/nestjs-patterns/SKILL.md +230 -0
  439. package/.agent/skills/nextjs-react-expert/1-async-eliminating-waterfalls.md +351 -351
  440. package/.agent/skills/nextjs-react-expert/2-bundle-bundle-size-optimization.md +240 -240
  441. package/.agent/skills/nextjs-react-expert/3-server-server-side-performance.md +490 -490
  442. package/.agent/skills/nextjs-react-expert/4-client-client-side-data-fetching.md +264 -264
  443. package/.agent/skills/nextjs-react-expert/5-rerender-re-render-optimization.md +581 -581
  444. package/.agent/skills/nextjs-react-expert/6-rendering-rendering-performance.md +432 -432
  445. package/.agent/skills/nextjs-react-expert/7-js-javascript-performance.md +684 -684
  446. package/.agent/skills/nextjs-react-expert/8-advanced-advanced-patterns.md +150 -150
  447. package/.agent/skills/nextjs-react-expert/9-cache-components.md +103 -103
  448. package/.agent/skills/nextjs-react-expert/SKILL.md +293 -293
  449. package/.agent/skills/nextjs-react-expert/scripts/convert_rules.py +222 -222
  450. package/.agent/skills/nextjs-react-expert/scripts/react_performance_checker.py +252 -252
  451. package/.agent/skills/nextjs-turbopack/SKILL.md +44 -0
  452. package/.agent/skills/nodejs-best-practices/SKILL.md +333 -333
  453. package/.agent/skills/nutrient-document-processing/SKILL.md +167 -0
  454. package/.agent/skills/nuxt4-patterns/SKILL.md +100 -0
  455. package/.agent/skills/openclaw-persona-forge/SKILL.md +296 -0
  456. package/.agent/skills/openclaw-persona-forge/gacha.py +224 -0
  457. package/.agent/skills/openclaw-persona-forge/gacha.sh +5 -0
  458. package/.agent/skills/openclaw-persona-forge/references/avatar-style.md +124 -0
  459. package/.agent/skills/openclaw-persona-forge/references/boundary-rules.md +53 -0
  460. package/.agent/skills/openclaw-persona-forge/references/error-handling.md +53 -0
  461. package/.agent/skills/openclaw-persona-forge/references/identity-tension.md +48 -0
  462. package/.agent/skills/openclaw-persona-forge/references/naming-system.md +39 -0
  463. package/.agent/skills/openclaw-persona-forge/references/output-template.md +166 -0
  464. package/.agent/skills/opensource-pipeline/SKILL.md +255 -0
  465. package/.agent/skills/parallel-agents/SKILL.md +175 -175
  466. package/.agent/skills/performance-profiling/SKILL.md +143 -143
  467. package/.agent/skills/performance-profiling/scripts/lighthouse_audit.py +76 -76
  468. package/.agent/skills/perl-patterns/SKILL.md +504 -0
  469. package/.agent/skills/perl-security/SKILL.md +503 -0
  470. package/.agent/skills/perl-testing/SKILL.md +475 -0
  471. package/.agent/skills/plan-writing/SKILL.md +152 -152
  472. package/.agent/skills/plankton-code-quality/SKILL.md +236 -0
  473. package/.agent/skills/postgres-patterns/SKILL.md +147 -0
  474. package/.agent/skills/powershell-windows/SKILL.md +167 -167
  475. package/.agent/skills/product-lens/SKILL.md +85 -0
  476. package/.agent/skills/production-scheduling/SKILL.md +238 -0
  477. package/.agent/skills/project-flow-ops/SKILL.md +111 -0
  478. package/.agent/skills/project-guidelines-example/SKILL.md +349 -0
  479. package/.agent/skills/prompt-optimizer/SKILL.md +397 -0
  480. package/.agent/skills/python-patterns/SKILL.md +750 -441
  481. package/.agent/skills/python-testing/SKILL.md +816 -0
  482. package/.agent/skills/pytorch-patterns/SKILL.md +396 -0
  483. package/.agent/skills/quality-nonconformance/SKILL.md +260 -0
  484. package/.agent/skills/ralphinho-rfc-pipeline/SKILL.md +67 -0
  485. package/.agent/skills/red-team-tactics/SKILL.md +199 -199
  486. package/.agent/skills/regex-vs-llm-structured-text/SKILL.md +220 -0
  487. package/.agent/skills/remotion-video-creation/SKILL.md +43 -0
  488. package/.agent/skills/remotion-video-creation/rules/3d.md +86 -0
  489. package/.agent/skills/remotion-video-creation/rules/animations.md +29 -0
  490. package/.agent/skills/remotion-video-creation/rules/assets/charts-bar-chart.tsx +173 -0
  491. package/.agent/skills/remotion-video-creation/rules/assets/text-animations-typewriter.tsx +100 -0
  492. package/.agent/skills/remotion-video-creation/rules/assets/text-animations-word-highlight.tsx +108 -0
  493. package/.agent/skills/remotion-video-creation/rules/assets.md +78 -0
  494. package/.agent/skills/remotion-video-creation/rules/audio.md +172 -0
  495. package/.agent/skills/remotion-video-creation/rules/calculate-metadata.md +104 -0
  496. package/.agent/skills/remotion-video-creation/rules/can-decode.md +75 -0
  497. package/.agent/skills/remotion-video-creation/rules/charts.md +58 -0
  498. package/.agent/skills/remotion-video-creation/rules/compositions.md +146 -0
  499. package/.agent/skills/remotion-video-creation/rules/display-captions.md +126 -0
  500. package/.agent/skills/remotion-video-creation/rules/extract-frames.md +229 -0
  501. package/.agent/skills/remotion-video-creation/rules/fonts.md +152 -0
  502. package/.agent/skills/remotion-video-creation/rules/get-audio-duration.md +58 -0
  503. package/.agent/skills/remotion-video-creation/rules/get-video-dimensions.md +68 -0
  504. package/.agent/skills/remotion-video-creation/rules/get-video-duration.md +58 -0
  505. package/.agent/skills/remotion-video-creation/rules/gifs.md +138 -0
  506. package/.agent/skills/remotion-video-creation/rules/images.md +130 -0
  507. package/.agent/skills/remotion-video-creation/rules/import-srt-captions.md +67 -0
  508. package/.agent/skills/remotion-video-creation/rules/lottie.md +67 -0
  509. package/.agent/skills/remotion-video-creation/rules/measuring-dom-nodes.md +34 -0
  510. package/.agent/skills/remotion-video-creation/rules/measuring-text.md +143 -0
  511. package/.agent/skills/remotion-video-creation/rules/sequencing.md +106 -0
  512. package/.agent/skills/remotion-video-creation/rules/tailwind.md +11 -0
  513. package/.agent/skills/remotion-video-creation/rules/text-animations.md +20 -0
  514. package/.agent/skills/remotion-video-creation/rules/timing.md +179 -0
  515. package/.agent/skills/remotion-video-creation/rules/transcribe-captions.md +19 -0
  516. package/.agent/skills/remotion-video-creation/rules/transitions.md +122 -0
  517. package/.agent/skills/remotion-video-creation/rules/trimming.md +52 -0
  518. package/.agent/skills/remotion-video-creation/rules/videos.md +171 -0
  519. package/.agent/skills/repo-scan/SKILL.md +78 -0
  520. package/.agent/skills/returns-reverse-logistics/SKILL.md +240 -0
  521. package/.agent/skills/rules-distill/SKILL.md +264 -0
  522. package/.agent/skills/rules-distill/scripts/scan-rules.sh +58 -0
  523. package/.agent/skills/rules-distill/scripts/scan-skills.sh +129 -0
  524. package/.agent/skills/rust-patterns/SKILL.md +499 -0
  525. package/.agent/skills/rust-pro/SKILL.md +175 -175
  526. package/.agent/skills/rust-testing/SKILL.md +500 -0
  527. package/.agent/skills/safety-guard/SKILL.md +75 -0
  528. package/.agent/skills/santa-method/SKILL.md +306 -0
  529. package/.agent/skills/search-first/SKILL.md +161 -0
  530. package/.agent/skills/security-review/SKILL.md +495 -0
  531. package/.agent/skills/security-review/cloud-infrastructure-security.md +361 -0
  532. package/.agent/skills/security-scan/SKILL.md +165 -0
  533. package/.agent/skills/seo-fundamentals/SKILL.md +129 -129
  534. package/.agent/skills/seo-fundamentals/scripts/seo_checker.py +219 -219
  535. package/.agent/skills/server-management/SKILL.md +161 -161
  536. package/.agent/skills/skill-comply/SKILL.md +58 -0
  537. package/.agent/skills/skill-comply/fixtures/compliant-trace.jsonl +5 -0
  538. package/.agent/skills/skill-comply/fixtures/noncompliant-trace.jsonl +3 -0
  539. package/.agent/skills/skill-comply/fixtures/tdd-spec.yaml +44 -0
  540. package/.agent/skills/skill-comply/prompts/classifier.md +24 -0
  541. package/.agent/skills/skill-comply/prompts/scenario-generator.md +62 -0
  542. package/.agent/skills/skill-comply/prompts/spec-generator.md +42 -0
  543. package/.agent/skills/skill-comply/pyproject.toml +15 -0
  544. package/.agent/skills/skill-comply/scripts/classifier.py +85 -0
  545. package/.agent/skills/skill-comply/scripts/grader.py +122 -0
  546. package/.agent/skills/skill-comply/scripts/init.py +0 -0
  547. package/.agent/skills/skill-comply/scripts/parser.py +107 -0
  548. package/.agent/skills/skill-comply/scripts/report.py +170 -0
  549. package/.agent/skills/skill-comply/scripts/run.py +127 -0
  550. package/.agent/skills/skill-comply/scripts/runner.py +161 -0
  551. package/.agent/skills/skill-comply/scripts/scenario-generator.py +70 -0
  552. package/.agent/skills/skill-comply/scripts/spec-generator.py +72 -0
  553. package/.agent/skills/skill-comply/scripts/utils.py +13 -0
  554. package/.agent/skills/skill-comply/tests/test-grader.py +137 -0
  555. package/.agent/skills/skill-comply/tests/test-parser.py +90 -0
  556. package/.agent/skills/skill-creator/SKILL.md +485 -0
  557. package/.agent/skills/skill-creator/agents/analyzer.md +274 -0
  558. package/.agent/skills/skill-creator/agents/comparator.md +202 -0
  559. package/.agent/skills/skill-creator/agents/grader.md +223 -0
  560. package/.agent/skills/skill-creator/assets/eval-review.html +146 -0
  561. package/.agent/skills/skill-creator/eval-viewer/generate-review.py +471 -0
  562. package/.agent/skills/skill-creator/eval-viewer/viewer.html +1325 -0
  563. package/.agent/skills/skill-creator/license.txt +202 -0
  564. package/.agent/skills/skill-creator/references/schemas.md +430 -0
  565. package/.agent/skills/skill-creator/scripts/aggregate-benchmark.py +401 -0
  566. package/.agent/skills/skill-creator/scripts/generate-report.py +326 -0
  567. package/.agent/skills/skill-creator/scripts/improve-description.py +247 -0
  568. package/.agent/skills/skill-creator/scripts/init.py +0 -0
  569. package/.agent/skills/skill-creator/scripts/package-skill.py +136 -0
  570. package/.agent/skills/skill-creator/scripts/quick-validate.py +103 -0
  571. package/.agent/skills/skill-creator/scripts/run-eval.py +310 -0
  572. package/.agent/skills/skill-creator/scripts/run-loop.py +328 -0
  573. package/.agent/skills/skill-creator/scripts/utils.py +47 -0
  574. package/.agent/skills/skill-stocktake/SKILL.md +193 -0
  575. package/.agent/skills/skill-stocktake/scripts/quick-diff.sh +87 -0
  576. package/.agent/skills/skill-stocktake/scripts/save-results.sh +56 -0
  577. package/.agent/skills/skill-stocktake/scripts/scan.sh +170 -0
  578. package/.agent/skills/social-graph-ranker/SKILL.md +154 -0
  579. package/.agent/skills/springboot-patterns/SKILL.md +314 -0
  580. package/.agent/skills/springboot-security/SKILL.md +272 -0
  581. package/.agent/skills/springboot-tdd/SKILL.md +158 -0
  582. package/.agent/skills/springboot-verification/SKILL.md +231 -0
  583. package/.agent/skills/strategic-compact/SKILL.md +131 -0
  584. package/.agent/skills/strategic-compact/suggest-compact.sh +54 -0
  585. package/.agent/skills/swift-actor-persistence/SKILL.md +143 -0
  586. package/.agent/skills/swift-concurrency-6-2/SKILL.md +216 -0
  587. package/.agent/skills/swift-protocol-di-testing/SKILL.md +190 -0
  588. package/.agent/skills/swiftui-patterns/SKILL.md +259 -0
  589. package/.agent/skills/systematic-debugging/SKILL.md +109 -109
  590. package/.agent/skills/tailwind-patterns/SKILL.md +269 -269
  591. package/.agent/skills/tdd-workflow/SKILL.md +463 -149
  592. package/.agent/skills/team-builder/SKILL.md +168 -0
  593. package/.agent/skills/testing-patterns/SKILL.md +178 -178
  594. package/.agent/skills/testing-patterns/scripts/test_runner.py +219 -219
  595. package/.agent/skills/token-budget-advisor/SKILL.md +133 -0
  596. package/.agent/skills/ui-demo/SKILL.md +465 -0
  597. package/.agent/skills/ui-ux-pro-max/SKILL.md +292 -292
  598. package/.agent/skills/ui-ux-pro-max/data/icons.csv +101 -101
  599. package/.agent/skills/ui-ux-pro-max/data/landing.csv +3 -3
  600. package/.agent/skills/ui-ux-pro-max/data/react-performance.csv +45 -45
  601. package/.agent/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -54
  602. package/.agent/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -53
  603. package/.agent/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -51
  604. package/.agent/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -59
  605. package/.agent/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -61
  606. package/.agent/skills/ui-ux-pro-max/data/typography.csv +57 -57
  607. package/.agent/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -101
  608. package/.agent/skills/ui-ux-pro-max/data/web-interface.csv +31 -31
  609. package/.agent/skills/ui-ux-pro-max/scripts/core.py +253 -253
  610. package/.agent/skills/ui-ux-pro-max/scripts/design_system.py +1067 -1067
  611. package/.agent/skills/verification-loop/SKILL.md +126 -0
  612. package/.agent/skills/video-editing/SKILL.md +310 -0
  613. package/.agent/skills/videodb/SKILL.md +374 -0
  614. package/.agent/skills/videodb/reference/api-reference.md +550 -0
  615. package/.agent/skills/videodb/reference/capture-reference.md +407 -0
  616. package/.agent/skills/videodb/reference/capture.md +101 -0
  617. package/.agent/skills/videodb/reference/editor.md +443 -0
  618. package/.agent/skills/videodb/reference/generative.md +331 -0
  619. package/.agent/skills/videodb/reference/rtstream-reference.md +564 -0
  620. package/.agent/skills/videodb/reference/rtstream.md +65 -0
  621. package/.agent/skills/videodb/reference/search.md +230 -0
  622. package/.agent/skills/videodb/reference/streaming.md +406 -0
  623. package/.agent/skills/videodb/reference/use-cases.md +118 -0
  624. package/.agent/skills/videodb/scripts/ws-listener.py +282 -0
  625. package/.agent/skills/visa-doc-translate/SKILL.md +117 -0
  626. package/.agent/skills/visa-doc-translate/readme.md +86 -0
  627. package/.agent/skills/vulnerability-scanner/SKILL.md +276 -276
  628. package/.agent/skills/vulnerability-scanner/checklists.md +121 -121
  629. package/.agent/skills/vulnerability-scanner/scripts/security_scan.py +458 -458
  630. package/.agent/skills/web-design-guidelines/SKILL.md +57 -57
  631. package/.agent/skills/webapp-testing/SKILL.md +187 -187
  632. package/.agent/skills/webapp-testing/scripts/playwright_runner.py +173 -173
  633. package/.agent/skills/workspace-surface-audit/SKILL.md +125 -0
  634. package/.agent/skills/x-api/SKILL.md +230 -0
  635. package/.agent/tasks/lessons.md +40 -40
  636. package/.agent/tasks/todo.md +33 -33
  637. package/.agent/tasks/two-track-merge-contract.md +29 -0
  638. package/.agent/workflows/aside.md +3 -3
  639. package/.agent/workflows/brainstorm.md +113 -113
  640. package/.agent/workflows/claw.md +13 -41
  641. package/.agent/workflows/clean-memory.md +34 -0
  642. package/.agent/workflows/code-review.md +260 -11
  643. package/.agent/workflows/context-budget.md +12 -18
  644. package/.agent/workflows/cpp-build.md +1 -1
  645. package/.agent/workflows/cpp-review.md +4 -4
  646. package/.agent/workflows/create.md +59 -59
  647. package/.agent/workflows/debug.md +103 -103
  648. package/.agent/workflows/deploy.md +176 -176
  649. package/.agent/workflows/devfleet.md +13 -82
  650. package/.agent/workflows/docs.md +13 -21
  651. package/.agent/workflows/e2e.md +38 -135
  652. package/.agent/workflows/enhance.md +63 -63
  653. package/.agent/workflows/eval.md +15 -112
  654. package/.agent/workflows/flutter-build.md +164 -0
  655. package/.agent/workflows/flutter-review.md +116 -0
  656. package/.agent/workflows/flutter-test.md +144 -0
  657. package/.agent/workflows/gan-build.md +99 -0
  658. package/.agent/workflows/gan-design.md +35 -0
  659. package/.agent/workflows/go-build.md +1 -1
  660. package/.agent/workflows/go-review.md +4 -4
  661. package/.agent/workflows/harness-audit.md +5 -3
  662. package/.agent/workflows/init-docs.md +46 -46
  663. package/.agent/workflows/instinct-import.md +4 -4
  664. package/.agent/workflows/jira.md +106 -0
  665. package/.agent/workflows/kotlin-build.md +1 -1
  666. package/.agent/workflows/kotlin-review.md +5 -5
  667. package/.agent/workflows/learn-eval.md +9 -9
  668. package/.agent/workflows/multi-plan.md +10 -10
  669. package/.agent/workflows/orchestrate.md +23 -119
  670. package/.agent/workflows/plan.md +2 -0
  671. package/.agent/workflows/preview.md +81 -81
  672. package/.agent/workflows/prompt-optimize.md +13 -28
  673. package/.agent/workflows/prp-commit.md +112 -0
  674. package/.agent/workflows/prp-implement.md +385 -0
  675. package/.agent/workflows/prp-plan.md +502 -0
  676. package/.agent/workflows/prp-pr.md +184 -0
  677. package/.agent/workflows/prp-prd.md +447 -0
  678. package/.agent/workflows/python-review.md +5 -5
  679. package/.agent/workflows/refactor-clean.md +1 -1
  680. package/.agent/workflows/resume-session.md +10 -10
  681. package/.agent/workflows/rules-distill.md +14 -5
  682. package/.agent/workflows/santa-loop.md +175 -0
  683. package/.agent/workflows/save-session.md +9 -9
  684. package/.agent/workflows/status.md +86 -86
  685. package/.agent/workflows/tdd.md +30 -127
  686. package/.agent/workflows/test-coverage.md +1 -1
  687. package/.agent/workflows/test.md +144 -144
  688. package/.agent/workflows/ui-ux-pro-max.md +295 -295
  689. package/.agent/workflows/verify.md +15 -51
  690. package/README.md +144 -136
  691. package/RELEASE.md +32 -36
  692. package/package.json +87 -79
  693. package/scripts/release-check.js +1 -1
  694. package/src/bin/cli.js +354 -78
  695. package/src/lib/installer.js +151 -117
  696. package/src/lib/manifests/stacks.js +122 -0
  697. package/src/lib/slash-commands.js +28 -0
  698. package/src/templates/claude/CLAUDE.en.md +42 -0
  699. package/src/templates/claude/CLAUDE.md +42 -0
  700. package/src/templates/claude/CLAUDE.vi.md +42 -0
  701. package/src/templates/codex/AGENTS.en.md +40 -0
  702. package/src/templates/codex/AGENTS.md +40 -0
  703. package/src/templates/codex/AGENTS.vi.md +40 -0
  704. package/src/templates/cursor/pilo-masterkit.mdc +20 -0
  705. package/src/templates/gemini/GEMINI.en.md +56 -0
  706. package/src/templates/gemini/GEMINI.md +56 -0
  707. package/src/templates/gemini/GEMINI.vi.md +56 -0
  708. package/src/templates/github/copilot-instructions.md +16 -0
@@ -0,0 +1,984 @@
1
+ """Tests for continuous-learning-v2 instinct-cli.py
2
+
3
+ Covers:
4
+ - parse_instinct_file() — content preservation, edge cases
5
+ - _validate_file_path() — path traversal blocking
6
+ - detect_project() — project detection with mocked git/env
7
+ - load_all_instincts() — loading from project + global dirs, dedup
8
+ - _load_instincts_from_dir() — directory scanning
9
+ - cmd_projects() — listing projects from registry
10
+ - cmd_status() — status display
11
+ - _promote_specific() — single instinct promotion
12
+ - _promote_auto() — auto-promotion across projects
13
+ """
14
+
15
+ import importlib.util
16
+ import io
17
+ import json
18
+ import os
19
+ import sys
20
+ from pathlib import Path
21
+ from types import SimpleNamespace
22
+ from unittest import mock
23
+
24
+ import pytest
25
+
26
+ # Load instinct-cli.py (hyphenated filename requires importlib)
27
+ _spec = importlib.util.spec_from_file_location(
28
+ "instinct_cli",
29
+ os.path.join(os.path.dirname(__file__), "instinct-cli.py"),
30
+ )
31
+ _mod = importlib.util.module_from_spec(_spec)
32
+ _spec.loader.exec_module(_mod)
33
+
34
+ parse_instinct_file = _mod.parse_instinct_file
35
+ _validate_file_path = _mod._validate_file_path
36
+ detect_project = _mod.detect_project
37
+ load_all_instincts = _mod.load_all_instincts
38
+ load_project_only_instincts = _mod.load_project_only_instincts
39
+ _load_instincts_from_dir = _mod._load_instincts_from_dir
40
+ cmd_status = _mod.cmd_status
41
+ cmd_projects = _mod.cmd_projects
42
+ _promote_specific = _mod._promote_specific
43
+ _promote_auto = _mod._promote_auto
44
+ _find_cross_project_instincts = _mod._find_cross_project_instincts
45
+ load_registry = _mod.load_registry
46
+ _validate_instinct_id = _mod._validate_instinct_id
47
+ _update_registry = _mod._update_registry
48
+
49
+
50
+ # ─────────────────────────────────────────────
51
+ # Fixtures
52
+ # ─────────────────────────────────────────────
53
+
54
+ SAMPLE_INSTINCT_YAML = """\
55
+ ---
56
+ id: test-instinct
57
+ trigger: "when writing tests"
58
+ confidence: 0.8
59
+ domain: testing
60
+ scope: project
61
+ ---
62
+
63
+ ## Action
64
+ Always write tests first.
65
+
66
+ ## Evidence
67
+ TDD leads to better design.
68
+ """
69
+
70
+ SAMPLE_GLOBAL_INSTINCT_YAML = """\
71
+ ---
72
+ id: global-instinct
73
+ trigger: "always"
74
+ confidence: 0.9
75
+ domain: security
76
+ scope: global
77
+ ---
78
+
79
+ ## Action
80
+ Validate all user input.
81
+ """
82
+
83
+
84
+ @pytest.fixture
85
+ def project_tree(tmp_path):
86
+ """Create a realistic project directory tree for testing."""
87
+ homunculus = tmp_path / ".claude" / "homunculus"
88
+ projects_dir = homunculus / "projects"
89
+ global_personal = homunculus / "instincts" / "personal"
90
+ global_inherited = homunculus / "instincts" / "inherited"
91
+ global_evolved = homunculus / "evolved"
92
+
93
+ for d in [
94
+ global_personal, global_inherited,
95
+ global_evolved / "skills", global_evolved / "commands", global_evolved / "agents",
96
+ projects_dir,
97
+ ]:
98
+ d.mkdir(parents=True, exist_ok=True)
99
+
100
+ return {
101
+ "root": tmp_path,
102
+ "homunculus": homunculus,
103
+ "projects_dir": projects_dir,
104
+ "global_personal": global_personal,
105
+ "global_inherited": global_inherited,
106
+ "global_evolved": global_evolved,
107
+ "registry_file": homunculus / "projects.json",
108
+ }
109
+
110
+
111
+ @pytest.fixture
112
+ def patch_globals(project_tree, monkeypatch):
113
+ """Patch module-level globals to use tmp_path-based directories."""
114
+ monkeypatch.setattr(_mod, "HOMUNCULUS_DIR", project_tree["homunculus"])
115
+ monkeypatch.setattr(_mod, "PROJECTS_DIR", project_tree["projects_dir"])
116
+ monkeypatch.setattr(_mod, "REGISTRY_FILE", project_tree["registry_file"])
117
+ monkeypatch.setattr(_mod, "GLOBAL_PERSONAL_DIR", project_tree["global_personal"])
118
+ monkeypatch.setattr(_mod, "GLOBAL_INHERITED_DIR", project_tree["global_inherited"])
119
+ monkeypatch.setattr(_mod, "GLOBAL_EVOLVED_DIR", project_tree["global_evolved"])
120
+ monkeypatch.setattr(_mod, "GLOBAL_OBSERVATIONS_FILE", project_tree["homunculus"] / "observations.jsonl")
121
+ return project_tree
122
+
123
+
124
+ def _make_project(tree, pid="abc123", pname="test-project"):
125
+ """Create project directory structure and return a project dict."""
126
+ project_dir = tree["projects_dir"] / pid
127
+ personal_dir = project_dir / "instincts" / "personal"
128
+ inherited_dir = project_dir / "instincts" / "inherited"
129
+ for d in [personal_dir, inherited_dir,
130
+ project_dir / "evolved" / "skills",
131
+ project_dir / "evolved" / "commands",
132
+ project_dir / "evolved" / "agents",
133
+ project_dir / "observations.archive"]:
134
+ d.mkdir(parents=True, exist_ok=True)
135
+
136
+ return {
137
+ "id": pid,
138
+ "name": pname,
139
+ "root": str(tree["root"] / "fake-repo"),
140
+ "remote": "https://github.com/test/test-project.git",
141
+ "project_dir": project_dir,
142
+ "instincts_personal": personal_dir,
143
+ "instincts_inherited": inherited_dir,
144
+ "evolved_dir": project_dir / "evolved",
145
+ "observations_file": project_dir / "observations.jsonl",
146
+ }
147
+
148
+
149
+ # ─────────────────────────────────────────────
150
+ # parse_instinct_file tests
151
+ # ─────────────────────────────────────────────
152
+
153
+ MULTI_SECTION = """\
154
+ ---
155
+ id: instinct-a
156
+ trigger: "when coding"
157
+ confidence: 0.9
158
+ domain: general
159
+ ---
160
+
161
+ ## Action
162
+ Do thing A.
163
+
164
+ ## Examples
165
+ - Example A1
166
+
167
+ ---
168
+ id: instinct-b
169
+ trigger: "when testing"
170
+ confidence: 0.7
171
+ domain: testing
172
+ ---
173
+
174
+ ## Action
175
+ Do thing B.
176
+ """
177
+
178
+
179
+ def test_multiple_instincts_preserve_content():
180
+ result = parse_instinct_file(MULTI_SECTION)
181
+ assert len(result) == 2
182
+ assert "Do thing A." in result[0]["content"]
183
+ assert "Example A1" in result[0]["content"]
184
+ assert "Do thing B." in result[1]["content"]
185
+
186
+
187
+ def test_single_instinct_preserves_content():
188
+ content = """\
189
+ ---
190
+ id: solo
191
+ trigger: "when reviewing"
192
+ confidence: 0.8
193
+ domain: review
194
+ ---
195
+
196
+ ## Action
197
+ Check for security issues.
198
+
199
+ ## Evidence
200
+ Prevents vulnerabilities.
201
+ """
202
+ result = parse_instinct_file(content)
203
+ assert len(result) == 1
204
+ assert "Check for security issues." in result[0]["content"]
205
+ assert "Prevents vulnerabilities." in result[0]["content"]
206
+
207
+
208
+ def test_empty_content_no_error():
209
+ content = """\
210
+ ---
211
+ id: empty
212
+ trigger: "placeholder"
213
+ confidence: 0.5
214
+ domain: general
215
+ ---
216
+ """
217
+ result = parse_instinct_file(content)
218
+ assert len(result) == 1
219
+ assert result[0]["content"] == ""
220
+
221
+
222
+ def test_parse_no_id_skipped():
223
+ """Instincts without an 'id' field should be silently dropped."""
224
+ content = """\
225
+ ---
226
+ trigger: "when doing nothing"
227
+ confidence: 0.5
228
+ ---
229
+
230
+ No id here.
231
+ """
232
+ result = parse_instinct_file(content)
233
+ assert len(result) == 0
234
+
235
+
236
+ def test_parse_confidence_is_float():
237
+ content = """\
238
+ ---
239
+ id: float-check
240
+ trigger: "when parsing"
241
+ confidence: 0.42
242
+ domain: general
243
+ ---
244
+
245
+ Body.
246
+ """
247
+ result = parse_instinct_file(content)
248
+ assert isinstance(result[0]["confidence"], float)
249
+ assert result[0]["confidence"] == pytest.approx(0.42)
250
+
251
+
252
+ def test_parse_trigger_strips_quotes():
253
+ content = """\
254
+ ---
255
+ id: quote-check
256
+ trigger: "when quoting"
257
+ confidence: 0.5
258
+ domain: general
259
+ ---
260
+
261
+ Body.
262
+ """
263
+ result = parse_instinct_file(content)
264
+ assert result[0]["trigger"] == "when quoting"
265
+
266
+
267
+ def test_parse_empty_string():
268
+ result = parse_instinct_file("")
269
+ assert result == []
270
+
271
+
272
+ def test_parse_garbage_input():
273
+ result = parse_instinct_file("this is not yaml at all\nno frontmatter here")
274
+ assert result == []
275
+
276
+
277
+ # ─────────────────────────────────────────────
278
+ # _validate_file_path tests
279
+ # ─────────────────────────────────────────────
280
+
281
+ def test_validate_normal_path(tmp_path):
282
+ test_file = tmp_path / "test.yaml"
283
+ test_file.write_text("hello")
284
+ result = _validate_file_path(str(test_file), must_exist=True)
285
+ assert result == test_file.resolve()
286
+
287
+
288
+ def test_validate_rejects_etc():
289
+ with pytest.raises(ValueError, match="system directory"):
290
+ _validate_file_path("/etc/passwd")
291
+
292
+
293
+ def test_validate_rejects_var_log():
294
+ with pytest.raises(ValueError, match="system directory"):
295
+ _validate_file_path("/var/log/syslog")
296
+
297
+
298
+ def test_validate_rejects_usr():
299
+ with pytest.raises(ValueError, match="system directory"):
300
+ _validate_file_path("/usr/local/bin/foo")
301
+
302
+
303
+ def test_validate_rejects_proc():
304
+ with pytest.raises(ValueError, match="system directory"):
305
+ _validate_file_path("/proc/self/status")
306
+
307
+
308
+ def test_validate_must_exist_fails(tmp_path):
309
+ with pytest.raises(ValueError, match="does not exist"):
310
+ _validate_file_path(str(tmp_path / "nonexistent.yaml"), must_exist=True)
311
+
312
+
313
+ def test_validate_home_expansion(tmp_path):
314
+ """Tilde expansion should work."""
315
+ result = _validate_file_path("~/test.yaml")
316
+ assert str(result).startswith(str(Path.home()))
317
+
318
+
319
+ def test_validate_relative_path(tmp_path, monkeypatch):
320
+ """Relative paths should be resolved."""
321
+ monkeypatch.chdir(tmp_path)
322
+ test_file = tmp_path / "rel.yaml"
323
+ test_file.write_text("content")
324
+ result = _validate_file_path("rel.yaml", must_exist=True)
325
+ assert result == test_file.resolve()
326
+
327
+
328
+ # ─────────────────────────────────────────────
329
+ # detect_project tests
330
+ # ─────────────────────────────────────────────
331
+
332
+ def test_detect_project_global_fallback(patch_globals, monkeypatch):
333
+ """When no git and no env var, should return global project."""
334
+ monkeypatch.delenv("CLAUDE_PROJECT_DIR", raising=False)
335
+
336
+ # Mock subprocess.run to simulate git not available
337
+ def mock_run(*args, **kwargs):
338
+ raise FileNotFoundError("git not found")
339
+
340
+ monkeypatch.setattr("subprocess.run", mock_run)
341
+
342
+ project = detect_project()
343
+ assert project["id"] == "global"
344
+ assert project["name"] == "global"
345
+
346
+
347
+ def test_detect_project_from_env(patch_globals, monkeypatch, tmp_path):
348
+ """CLAUDE_PROJECT_DIR env var should be used as project root."""
349
+ fake_repo = tmp_path / "my-repo"
350
+ fake_repo.mkdir()
351
+ monkeypatch.setenv("CLAUDE_PROJECT_DIR", str(fake_repo))
352
+
353
+ # Mock git remote to return a URL
354
+ def mock_run(cmd, **kwargs):
355
+ if "rev-parse" in cmd:
356
+ return SimpleNamespace(returncode=0, stdout=str(fake_repo) + "\n", stderr="")
357
+ if "get-url" in cmd:
358
+ return SimpleNamespace(returncode=0, stdout="https://github.com/test/my-repo.git\n", stderr="")
359
+ return SimpleNamespace(returncode=1, stdout="", stderr="")
360
+
361
+ monkeypatch.setattr("subprocess.run", mock_run)
362
+
363
+ project = detect_project()
364
+ assert project["id"] != "global"
365
+ assert project["name"] == "my-repo"
366
+
367
+
368
+ def test_detect_project_git_timeout(patch_globals, monkeypatch):
369
+ """Git timeout should fall through to global."""
370
+ monkeypatch.delenv("CLAUDE_PROJECT_DIR", raising=False)
371
+ import subprocess as sp
372
+
373
+ def mock_run(cmd, **kwargs):
374
+ raise sp.TimeoutExpired(cmd, 5)
375
+
376
+ monkeypatch.setattr("subprocess.run", mock_run)
377
+
378
+ project = detect_project()
379
+ assert project["id"] == "global"
380
+
381
+
382
+ def test_detect_project_creates_directories(patch_globals, monkeypatch, tmp_path):
383
+ """detect_project should create the project dir structure."""
384
+ fake_repo = tmp_path / "structured-repo"
385
+ fake_repo.mkdir()
386
+ monkeypatch.setenv("CLAUDE_PROJECT_DIR", str(fake_repo))
387
+
388
+ def mock_run(cmd, **kwargs):
389
+ if "rev-parse" in cmd:
390
+ return SimpleNamespace(returncode=0, stdout=str(fake_repo) + "\n", stderr="")
391
+ if "get-url" in cmd:
392
+ return SimpleNamespace(returncode=1, stdout="", stderr="no remote")
393
+ return SimpleNamespace(returncode=1, stdout="", stderr="")
394
+
395
+ monkeypatch.setattr("subprocess.run", mock_run)
396
+
397
+ project = detect_project()
398
+ assert project["instincts_personal"].exists()
399
+ assert project["instincts_inherited"].exists()
400
+ assert (project["evolved_dir"] / "skills").exists()
401
+
402
+
403
+ # ─────────────────────────────────────────────
404
+ # _load_instincts_from_dir tests
405
+ # ─────────────────────────────────────────────
406
+
407
+ def test_load_from_empty_dir(tmp_path):
408
+ result = _load_instincts_from_dir(tmp_path, "personal", "project")
409
+ assert result == []
410
+
411
+
412
+ def test_load_from_nonexistent_dir(tmp_path):
413
+ result = _load_instincts_from_dir(tmp_path / "does-not-exist", "personal", "project")
414
+ assert result == []
415
+
416
+
417
+ def test_load_annotates_metadata(tmp_path):
418
+ """Loaded instincts should have _source_file, _source_type, _scope_label."""
419
+ yaml_file = tmp_path / "test.yaml"
420
+ yaml_file.write_text(SAMPLE_INSTINCT_YAML)
421
+
422
+ result = _load_instincts_from_dir(tmp_path, "personal", "project")
423
+ assert len(result) == 1
424
+ assert result[0]["_source_file"] == str(yaml_file)
425
+ assert result[0]["_source_type"] == "personal"
426
+ assert result[0]["_scope_label"] == "project"
427
+
428
+
429
+ def test_load_defaults_scope_from_label(tmp_path):
430
+ """If an instinct has no 'scope' in frontmatter, it should default to scope_label."""
431
+ no_scope_yaml = """\
432
+ ---
433
+ id: no-scope
434
+ trigger: "test"
435
+ confidence: 0.5
436
+ domain: general
437
+ ---
438
+
439
+ Body.
440
+ """
441
+ (tmp_path / "no-scope.yaml").write_text(no_scope_yaml)
442
+ result = _load_instincts_from_dir(tmp_path, "inherited", "global")
443
+ assert result[0]["scope"] == "global"
444
+
445
+
446
+ def test_load_preserves_explicit_scope(tmp_path):
447
+ """If frontmatter has explicit scope, it should be preserved."""
448
+ yaml_file = tmp_path / "test.yaml"
449
+ yaml_file.write_text(SAMPLE_INSTINCT_YAML)
450
+
451
+ result = _load_instincts_from_dir(tmp_path, "personal", "global")
452
+ # Frontmatter says scope: project, scope_label is global
453
+ # The explicit scope should be preserved (not overwritten)
454
+ assert result[0]["scope"] == "project"
455
+
456
+
457
+ def test_load_handles_corrupt_file(tmp_path, capsys):
458
+ """Corrupt YAML files should be warned about but not crash."""
459
+ # A file that will cause parse_instinct_file to return empty
460
+ (tmp_path / "good.yaml").write_text(SAMPLE_INSTINCT_YAML)
461
+ (tmp_path / "bad.yaml").write_text("not yaml\nno frontmatter")
462
+
463
+ result = _load_instincts_from_dir(tmp_path, "personal", "project")
464
+ # bad.yaml has no valid instincts (no id), so only good.yaml contributes
465
+ assert len(result) == 1
466
+ assert result[0]["id"] == "test-instinct"
467
+
468
+
469
+ def test_load_supports_yml_extension(tmp_path):
470
+ yml_file = tmp_path / "test.yml"
471
+ yml_file.write_text(SAMPLE_INSTINCT_YAML)
472
+
473
+ result = _load_instincts_from_dir(tmp_path, "personal", "project")
474
+ ids = {i["id"] for i in result}
475
+ assert "test-instinct" in ids
476
+
477
+
478
+ def test_load_supports_md_extension(tmp_path):
479
+ md_file = tmp_path / "legacy-instinct.md"
480
+ md_file.write_text(SAMPLE_INSTINCT_YAML)
481
+
482
+ result = _load_instincts_from_dir(tmp_path, "personal", "project")
483
+ ids = {i["id"] for i in result}
484
+ assert "test-instinct" in ids
485
+
486
+
487
+ def test_load_instincts_from_dir_uses_utf8_encoding(tmp_path, monkeypatch):
488
+ yaml_file = tmp_path / "test.yaml"
489
+ yaml_file.write_text("placeholder")
490
+ calls = []
491
+
492
+ def fake_read_text(self, *args, **kwargs):
493
+ calls.append(kwargs.get("encoding"))
494
+ return SAMPLE_INSTINCT_YAML
495
+
496
+ monkeypatch.setattr(Path, "read_text", fake_read_text)
497
+ result = _load_instincts_from_dir(tmp_path, "personal", "project")
498
+ assert result[0]["id"] == "test-instinct"
499
+ assert calls == ["utf-8"]
500
+
501
+
502
+ # ─────────────────────────────────────────────
503
+ # load_all_instincts tests
504
+ # ─────────────────────────────────────────────
505
+
506
+ def test_load_all_project_and_global(patch_globals):
507
+ """Should load from both project and global directories."""
508
+ tree = patch_globals
509
+ project = _make_project(tree)
510
+
511
+ # Write a project instinct
512
+ (project["instincts_personal"] / "proj.yaml").write_text(SAMPLE_INSTINCT_YAML)
513
+ # Write a global instinct
514
+ (tree["global_personal"] / "glob.yaml").write_text(SAMPLE_GLOBAL_INSTINCT_YAML)
515
+
516
+ result = load_all_instincts(project)
517
+ ids = {i["id"] for i in result}
518
+ assert "test-instinct" in ids
519
+ assert "global-instinct" in ids
520
+
521
+
522
+ def test_load_all_project_overrides_global(patch_globals):
523
+ """When project and global have same ID, project wins."""
524
+ tree = patch_globals
525
+ project = _make_project(tree)
526
+
527
+ # Same ID but different confidence
528
+ proj_yaml = SAMPLE_INSTINCT_YAML.replace("id: test-instinct", "id: shared-id")
529
+ proj_yaml = proj_yaml.replace("confidence: 0.8", "confidence: 0.9")
530
+ glob_yaml = SAMPLE_GLOBAL_INSTINCT_YAML.replace("id: global-instinct", "id: shared-id")
531
+ glob_yaml = glob_yaml.replace("confidence: 0.9", "confidence: 0.3")
532
+
533
+ (project["instincts_personal"] / "shared.yaml").write_text(proj_yaml)
534
+ (tree["global_personal"] / "shared.yaml").write_text(glob_yaml)
535
+
536
+ result = load_all_instincts(project)
537
+ shared = [i for i in result if i["id"] == "shared-id"]
538
+ assert len(shared) == 1
539
+ assert shared[0]["_scope_label"] == "project"
540
+ assert shared[0]["confidence"] == 0.9
541
+
542
+
543
+ def test_load_all_global_only(patch_globals):
544
+ """Global project should only load global instincts."""
545
+ tree = patch_globals
546
+ (tree["global_personal"] / "glob.yaml").write_text(SAMPLE_GLOBAL_INSTINCT_YAML)
547
+
548
+ global_project = {
549
+ "id": "global",
550
+ "name": "global",
551
+ "root": "",
552
+ "project_dir": tree["homunculus"],
553
+ "instincts_personal": tree["global_personal"],
554
+ "instincts_inherited": tree["global_inherited"],
555
+ "evolved_dir": tree["global_evolved"],
556
+ "observations_file": tree["homunculus"] / "observations.jsonl",
557
+ }
558
+
559
+ result = load_all_instincts(global_project)
560
+ assert len(result) == 1
561
+ assert result[0]["id"] == "global-instinct"
562
+
563
+
564
+ def test_load_project_only_excludes_global(patch_globals):
565
+ """load_project_only_instincts should NOT include global instincts."""
566
+ tree = patch_globals
567
+ project = _make_project(tree)
568
+
569
+ (project["instincts_personal"] / "proj.yaml").write_text(SAMPLE_INSTINCT_YAML)
570
+ (tree["global_personal"] / "glob.yaml").write_text(SAMPLE_GLOBAL_INSTINCT_YAML)
571
+
572
+ result = load_project_only_instincts(project)
573
+ ids = {i["id"] for i in result}
574
+ assert "test-instinct" in ids
575
+ assert "global-instinct" not in ids
576
+
577
+
578
+ def test_load_project_only_global_fallback_loads_global(patch_globals):
579
+ """Global fallback should return global instincts for project-only queries."""
580
+ tree = patch_globals
581
+ (tree["global_personal"] / "glob.yaml").write_text(SAMPLE_GLOBAL_INSTINCT_YAML)
582
+
583
+ global_project = {
584
+ "id": "global",
585
+ "name": "global",
586
+ "root": "",
587
+ "project_dir": tree["homunculus"],
588
+ "instincts_personal": tree["global_personal"],
589
+ "instincts_inherited": tree["global_inherited"],
590
+ "evolved_dir": tree["global_evolved"],
591
+ "observations_file": tree["homunculus"] / "observations.jsonl",
592
+ }
593
+
594
+ result = load_project_only_instincts(global_project)
595
+ assert len(result) == 1
596
+ assert result[0]["id"] == "global-instinct"
597
+
598
+
599
+ def test_load_all_empty(patch_globals):
600
+ """No instincts at all should return empty list."""
601
+ tree = patch_globals
602
+ project = _make_project(tree)
603
+
604
+ result = load_all_instincts(project)
605
+ assert result == []
606
+
607
+
608
+ # ─────────────────────────────────────────────
609
+ # cmd_status tests
610
+ # ─────────────────────────────────────────────
611
+
612
+ def test_cmd_status_no_instincts(patch_globals, monkeypatch, capsys):
613
+ """Status with no instincts should print fallback message."""
614
+ tree = patch_globals
615
+ project = _make_project(tree)
616
+ monkeypatch.setattr(_mod, "detect_project", lambda: project)
617
+
618
+ args = SimpleNamespace()
619
+ ret = cmd_status(args)
620
+ assert ret == 0
621
+ out = capsys.readouterr().out
622
+ assert "No instincts found." in out
623
+
624
+
625
+ def test_cmd_status_with_instincts(patch_globals, monkeypatch, capsys):
626
+ """Status should show project and global instinct counts."""
627
+ tree = patch_globals
628
+ project = _make_project(tree)
629
+ monkeypatch.setattr(_mod, "detect_project", lambda: project)
630
+
631
+ (project["instincts_personal"] / "proj.yaml").write_text(SAMPLE_INSTINCT_YAML)
632
+ (tree["global_personal"] / "glob.yaml").write_text(SAMPLE_GLOBAL_INSTINCT_YAML)
633
+
634
+ args = SimpleNamespace()
635
+ ret = cmd_status(args)
636
+ assert ret == 0
637
+ out = capsys.readouterr().out
638
+ assert "INSTINCT STATUS" in out
639
+ assert "Project instincts: 1" in out
640
+ assert "Global instincts: 1" in out
641
+ assert "PROJECT-SCOPED" in out
642
+ assert "GLOBAL" in out
643
+
644
+
645
+ def test_cmd_status_returns_int(patch_globals, monkeypatch):
646
+ """cmd_status should always return an int."""
647
+ tree = patch_globals
648
+ project = _make_project(tree)
649
+ monkeypatch.setattr(_mod, "detect_project", lambda: project)
650
+
651
+ args = SimpleNamespace()
652
+ ret = cmd_status(args)
653
+ assert isinstance(ret, int)
654
+
655
+
656
+ # ─────────────────────────────────────────────
657
+ # cmd_projects tests
658
+ # ─────────────────────────────────────────────
659
+
660
+ def test_cmd_projects_empty_registry(patch_globals, capsys):
661
+ """No projects should print helpful message."""
662
+ args = SimpleNamespace()
663
+ ret = cmd_projects(args)
664
+ assert ret == 0
665
+ out = capsys.readouterr().out
666
+ assert "No projects registered yet." in out
667
+
668
+
669
+ def test_cmd_projects_with_registry(patch_globals, capsys):
670
+ """Should list projects from registry."""
671
+ tree = patch_globals
672
+
673
+ # Create a project dir with instincts
674
+ pid = "test123abc"
675
+ project = _make_project(tree, pid=pid, pname="my-app")
676
+ (project["instincts_personal"] / "inst.yaml").write_text(SAMPLE_INSTINCT_YAML)
677
+
678
+ # Write registry
679
+ registry = {
680
+ pid: {
681
+ "name": "my-app",
682
+ "root": "/home/user/my-app",
683
+ "remote": "https://github.com/user/my-app.git",
684
+ "last_seen": "2025-01-15T12:00:00Z",
685
+ }
686
+ }
687
+ tree["registry_file"].write_text(json.dumps(registry))
688
+
689
+ args = SimpleNamespace()
690
+ ret = cmd_projects(args)
691
+ assert ret == 0
692
+ out = capsys.readouterr().out
693
+ assert "my-app" in out
694
+ assert pid in out
695
+ assert "1 personal" in out
696
+
697
+
698
+ # ─────────────────────────────────────────────
699
+ # _promote_specific tests
700
+ # ─────────────────────────────────────────────
701
+
702
+ def test_promote_specific_not_found(patch_globals, capsys):
703
+ """Promoting nonexistent instinct should fail."""
704
+ tree = patch_globals
705
+ project = _make_project(tree)
706
+
707
+ ret = _promote_specific(project, "nonexistent", force=True)
708
+ assert ret == 1
709
+ out = capsys.readouterr().out
710
+ assert "not found" in out
711
+
712
+
713
+ def test_promote_specific_rejects_invalid_id(patch_globals, capsys):
714
+ """Path-like instinct IDs should be rejected before file writes."""
715
+ tree = patch_globals
716
+ project = _make_project(tree)
717
+
718
+ ret = _promote_specific(project, "../escape", force=True)
719
+ assert ret == 1
720
+ err = capsys.readouterr().err
721
+ assert "Invalid instinct ID" in err
722
+
723
+
724
+ def test_promote_specific_already_global(patch_globals, capsys):
725
+ """Promoting an instinct that already exists globally should fail."""
726
+ tree = patch_globals
727
+ project = _make_project(tree)
728
+
729
+ # Write same-id instinct in both project and global
730
+ (project["instincts_personal"] / "shared.yaml").write_text(SAMPLE_INSTINCT_YAML)
731
+ global_yaml = SAMPLE_INSTINCT_YAML # same id: test-instinct
732
+ (tree["global_personal"] / "shared.yaml").write_text(global_yaml)
733
+
734
+ ret = _promote_specific(project, "test-instinct", force=True)
735
+ assert ret == 1
736
+ out = capsys.readouterr().out
737
+ assert "already exists in global" in out
738
+
739
+
740
+ def test_promote_specific_success(patch_globals, capsys):
741
+ """Promote a project instinct to global with --force."""
742
+ tree = patch_globals
743
+ project = _make_project(tree)
744
+
745
+ (project["instincts_personal"] / "inst.yaml").write_text(SAMPLE_INSTINCT_YAML)
746
+
747
+ ret = _promote_specific(project, "test-instinct", force=True)
748
+ assert ret == 0
749
+ out = capsys.readouterr().out
750
+ assert "Promoted" in out
751
+
752
+ # Verify file was created in global dir
753
+ promoted_file = tree["global_personal"] / "test-instinct.yaml"
754
+ assert promoted_file.exists()
755
+ content = promoted_file.read_text()
756
+ assert "scope: global" in content
757
+ assert "promoted_from: abc123" in content
758
+
759
+
760
+ # ─────────────────────────────────────────────
761
+ # _promote_auto tests
762
+ # ─────────────────────────────────────────────
763
+
764
+ def test_promote_auto_no_candidates(patch_globals, capsys):
765
+ """Auto-promote with no cross-project instincts should say so."""
766
+ tree = patch_globals
767
+ project = _make_project(tree)
768
+
769
+ # Empty registry
770
+ tree["registry_file"].write_text("{}")
771
+
772
+ ret = _promote_auto(project, force=True, dry_run=False)
773
+ assert ret == 0
774
+ out = capsys.readouterr().out
775
+ assert "No instincts qualify" in out
776
+
777
+
778
+ def test_promote_auto_dry_run(patch_globals, capsys):
779
+ """Dry run should list candidates but not write files."""
780
+ tree = patch_globals
781
+
782
+ # Create two projects with the same high-confidence instinct
783
+ p1 = _make_project(tree, pid="proj1", pname="project-one")
784
+ p2 = _make_project(tree, pid="proj2", pname="project-two")
785
+
786
+ high_conf_yaml = """\
787
+ ---
788
+ id: cross-project-instinct
789
+ trigger: "when reviewing"
790
+ confidence: 0.95
791
+ domain: security
792
+ scope: project
793
+ ---
794
+
795
+ ## Action
796
+ Always review for injection.
797
+ """
798
+ (p1["instincts_personal"] / "cross.yaml").write_text(high_conf_yaml)
799
+ (p2["instincts_personal"] / "cross.yaml").write_text(high_conf_yaml)
800
+
801
+ # Write registry
802
+ registry = {
803
+ "proj1": {"name": "project-one", "root": "/a", "remote": "", "last_seen": "2025-01-01T00:00:00Z"},
804
+ "proj2": {"name": "project-two", "root": "/b", "remote": "", "last_seen": "2025-01-01T00:00:00Z"},
805
+ }
806
+ tree["registry_file"].write_text(json.dumps(registry))
807
+
808
+ project = p1
809
+ ret = _promote_auto(project, force=True, dry_run=True)
810
+ assert ret == 0
811
+ out = capsys.readouterr().out
812
+ assert "DRY RUN" in out
813
+ assert "cross-project-instinct" in out
814
+
815
+ # Verify no file was created
816
+ assert not (tree["global_personal"] / "cross-project-instinct.yaml").exists()
817
+
818
+
819
+ def test_promote_auto_writes_file(patch_globals, capsys):
820
+ """Auto-promote with force should write global instinct file."""
821
+ tree = patch_globals
822
+
823
+ p1 = _make_project(tree, pid="proj1", pname="project-one")
824
+ p2 = _make_project(tree, pid="proj2", pname="project-two")
825
+
826
+ high_conf_yaml = """\
827
+ ---
828
+ id: universal-pattern
829
+ trigger: "when coding"
830
+ confidence: 0.85
831
+ domain: general
832
+ scope: project
833
+ ---
834
+
835
+ ## Action
836
+ Use descriptive variable names.
837
+ """
838
+ (p1["instincts_personal"] / "uni.yaml").write_text(high_conf_yaml)
839
+ (p2["instincts_personal"] / "uni.yaml").write_text(high_conf_yaml)
840
+
841
+ registry = {
842
+ "proj1": {"name": "project-one", "root": "/a", "remote": "", "last_seen": "2025-01-01T00:00:00Z"},
843
+ "proj2": {"name": "project-two", "root": "/b", "remote": "", "last_seen": "2025-01-01T00:00:00Z"},
844
+ }
845
+ tree["registry_file"].write_text(json.dumps(registry))
846
+
847
+ ret = _promote_auto(p1, force=True, dry_run=False)
848
+ assert ret == 0
849
+
850
+ promoted = tree["global_personal"] / "universal-pattern.yaml"
851
+ assert promoted.exists()
852
+ content = promoted.read_text()
853
+ assert "scope: global" in content
854
+ assert "auto-promoted" in content
855
+
856
+
857
+ def test_promote_auto_skips_invalid_id(patch_globals, capsys):
858
+ tree = patch_globals
859
+
860
+ p1 = _make_project(tree, pid="proj1", pname="project-one")
861
+ p2 = _make_project(tree, pid="proj2", pname="project-two")
862
+
863
+ bad_id_yaml = """\
864
+ ---
865
+ id: ../escape
866
+ trigger: "when coding"
867
+ confidence: 0.9
868
+ domain: general
869
+ scope: project
870
+ ---
871
+
872
+ ## Action
873
+ Invalid id should be skipped.
874
+ """
875
+ (p1["instincts_personal"] / "bad.yaml").write_text(bad_id_yaml)
876
+ (p2["instincts_personal"] / "bad.yaml").write_text(bad_id_yaml)
877
+
878
+ registry = {
879
+ "proj1": {"name": "project-one", "root": "/a", "remote": "", "last_seen": "2025-01-01T00:00:00Z"},
880
+ "proj2": {"name": "project-two", "root": "/b", "remote": "", "last_seen": "2025-01-01T00:00:00Z"},
881
+ }
882
+ tree["registry_file"].write_text(json.dumps(registry))
883
+
884
+ ret = _promote_auto(p1, force=True, dry_run=False)
885
+ assert ret == 0
886
+ err = capsys.readouterr().err
887
+ assert "Skipping invalid instinct ID" in err
888
+ assert not (tree["global_personal"] / "../escape.yaml").exists()
889
+
890
+
891
+ # ─────────────────────────────────────────────
892
+ # _find_cross_project_instincts tests
893
+ # ─────────────────────────────────────────────
894
+
895
+ def test_find_cross_project_empty_registry(patch_globals):
896
+ tree = patch_globals
897
+ tree["registry_file"].write_text("{}")
898
+ result = _find_cross_project_instincts()
899
+ assert result == {}
900
+
901
+
902
+ def test_find_cross_project_single_project(patch_globals):
903
+ """Single project should return nothing (need 2+)."""
904
+ tree = patch_globals
905
+ p1 = _make_project(tree, pid="proj1", pname="project-one")
906
+ (p1["instincts_personal"] / "inst.yaml").write_text(SAMPLE_INSTINCT_YAML)
907
+
908
+ registry = {"proj1": {"name": "project-one", "root": "/a", "remote": "", "last_seen": "2025-01-01T00:00:00Z"}}
909
+ tree["registry_file"].write_text(json.dumps(registry))
910
+
911
+ result = _find_cross_project_instincts()
912
+ assert result == {}
913
+
914
+
915
+ def test_find_cross_project_shared_instinct(patch_globals):
916
+ """Same instinct ID in 2 projects should be found."""
917
+ tree = patch_globals
918
+ p1 = _make_project(tree, pid="proj1", pname="project-one")
919
+ p2 = _make_project(tree, pid="proj2", pname="project-two")
920
+
921
+ (p1["instincts_personal"] / "shared.yaml").write_text(SAMPLE_INSTINCT_YAML)
922
+ (p2["instincts_personal"] / "shared.yaml").write_text(SAMPLE_INSTINCT_YAML)
923
+
924
+ registry = {
925
+ "proj1": {"name": "project-one", "root": "/a", "remote": "", "last_seen": "2025-01-01T00:00:00Z"},
926
+ "proj2": {"name": "project-two", "root": "/b", "remote": "", "last_seen": "2025-01-01T00:00:00Z"},
927
+ }
928
+ tree["registry_file"].write_text(json.dumps(registry))
929
+
930
+ result = _find_cross_project_instincts()
931
+ assert "test-instinct" in result
932
+ assert len(result["test-instinct"]) == 2
933
+
934
+
935
+ # ─────────────────────────────────────────────
936
+ # load_registry tests
937
+ # ─────────────────────────────────────────────
938
+
939
+ def test_load_registry_missing_file(patch_globals):
940
+ result = load_registry()
941
+ assert result == {}
942
+
943
+
944
+ def test_load_registry_corrupt_json(patch_globals):
945
+ tree = patch_globals
946
+ tree["registry_file"].write_text("not json at all {{{")
947
+ result = load_registry()
948
+ assert result == {}
949
+
950
+
951
+ def test_load_registry_valid(patch_globals):
952
+ tree = patch_globals
953
+ data = {"abc": {"name": "test", "root": "/test"}}
954
+ tree["registry_file"].write_text(json.dumps(data))
955
+ result = load_registry()
956
+ assert result == data
957
+
958
+
959
+ def test_load_registry_uses_utf8_encoding(monkeypatch):
960
+ calls = []
961
+
962
+ def fake_open(path, mode="r", *args, **kwargs):
963
+ calls.append(kwargs.get("encoding"))
964
+ return io.StringIO("{}")
965
+
966
+ monkeypatch.setattr(_mod, "open", fake_open, raising=False)
967
+ assert load_registry() == {}
968
+ assert calls == ["utf-8"]
969
+
970
+
971
+ def test_validate_instinct_id():
972
+ assert _validate_instinct_id("good-id_1.0")
973
+ assert not _validate_instinct_id("../bad")
974
+ assert not _validate_instinct_id("bad/name")
975
+ assert not _validate_instinct_id(".hidden")
976
+
977
+
978
+ def test_update_registry_atomic_replaces_file(patch_globals):
979
+ tree = patch_globals
980
+ _update_registry("abc123", "demo", "/repo", "https://example.com/repo.git")
981
+ data = json.loads(tree["registry_file"].read_text())
982
+ assert "abc123" in data
983
+ leftovers = list(tree["registry_file"].parent.glob(".projects.json.tmp.*"))
984
+ assert leftovers == []