arkaos 2.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (486) hide show
  1. package/CONSTITUTION.md +81 -0
  2. package/LICENSE +21 -0
  3. package/README.md +154 -0
  4. package/VERSION +1 -0
  5. package/arka/SKILL.md +134 -0
  6. package/bin/arkaos +107 -0
  7. package/config/constitution.yaml +168 -0
  8. package/config/hooks/post-tool-use-v2.sh +116 -0
  9. package/config/hooks/post-tool-use.sh +188 -0
  10. package/config/hooks/pre-compact-v2.sh +43 -0
  11. package/config/hooks/pre-compact.sh +99 -0
  12. package/config/hooks/user-prompt-submit-v2.sh +119 -0
  13. package/config/hooks/user-prompt-submit.sh +312 -0
  14. package/core/__init__.py +3 -0
  15. package/core/__pycache__/__init__.cpython-313.pyc +0 -0
  16. package/core/agents/__init__.py +14 -0
  17. package/core/agents/__pycache__/__init__.cpython-313.pyc +0 -0
  18. package/core/agents/__pycache__/loader.cpython-313.pyc +0 -0
  19. package/core/agents/__pycache__/registry_gen.cpython-313.pyc +0 -0
  20. package/core/agents/__pycache__/schema.cpython-313.pyc +0 -0
  21. package/core/agents/__pycache__/validator.cpython-313.pyc +0 -0
  22. package/core/agents/loader.py +88 -0
  23. package/core/agents/registry_gen.py +118 -0
  24. package/core/agents/schema.py +265 -0
  25. package/core/agents/validator.py +141 -0
  26. package/core/conclave/__init__.py +12 -0
  27. package/core/conclave/__pycache__/__init__.cpython-313.pyc +0 -0
  28. package/core/conclave/__pycache__/advisor_db.cpython-313.pyc +0 -0
  29. package/core/conclave/__pycache__/display.cpython-313.pyc +0 -0
  30. package/core/conclave/__pycache__/matcher.cpython-313.pyc +0 -0
  31. package/core/conclave/__pycache__/persistence.cpython-313.pyc +0 -0
  32. package/core/conclave/__pycache__/profiler.cpython-313.pyc +0 -0
  33. package/core/conclave/__pycache__/prompts.cpython-313.pyc +0 -0
  34. package/core/conclave/__pycache__/schema.cpython-313.pyc +0 -0
  35. package/core/conclave/advisor_db.py +373 -0
  36. package/core/conclave/display.py +104 -0
  37. package/core/conclave/matcher.py +104 -0
  38. package/core/conclave/persistence.py +61 -0
  39. package/core/conclave/profiler.py +298 -0
  40. package/core/conclave/prompts.py +77 -0
  41. package/core/conclave/schema.py +132 -0
  42. package/core/governance/__init__.py +5 -0
  43. package/core/governance/__pycache__/__init__.cpython-313.pyc +0 -0
  44. package/core/governance/__pycache__/constitution.cpython-313.pyc +0 -0
  45. package/core/governance/constitution.py +152 -0
  46. package/core/registry/__init__.py +1 -0
  47. package/core/registry/__pycache__/__init__.cpython-313.pyc +0 -0
  48. package/core/registry/__pycache__/generator.cpython-313.pyc +0 -0
  49. package/core/registry/generator.py +199 -0
  50. package/core/runtime/__init__.py +6 -0
  51. package/core/runtime/__pycache__/__init__.cpython-313.pyc +0 -0
  52. package/core/runtime/__pycache__/base.cpython-313.pyc +0 -0
  53. package/core/runtime/__pycache__/claude_code.cpython-313.pyc +0 -0
  54. package/core/runtime/__pycache__/codex_cli.cpython-313.pyc +0 -0
  55. package/core/runtime/__pycache__/cursor.cpython-313.pyc +0 -0
  56. package/core/runtime/__pycache__/gemini_cli.cpython-313.pyc +0 -0
  57. package/core/runtime/__pycache__/registry.cpython-313.pyc +0 -0
  58. package/core/runtime/__pycache__/subagent.cpython-313.pyc +0 -0
  59. package/core/runtime/base.py +143 -0
  60. package/core/runtime/claude_code.py +104 -0
  61. package/core/runtime/codex_cli.py +71 -0
  62. package/core/runtime/cursor.py +71 -0
  63. package/core/runtime/gemini_cli.py +68 -0
  64. package/core/runtime/registry.py +86 -0
  65. package/core/runtime/subagent.py +201 -0
  66. package/core/specs/__init__.py +10 -0
  67. package/core/specs/__pycache__/__init__.cpython-313.pyc +0 -0
  68. package/core/specs/__pycache__/manager.cpython-313.pyc +0 -0
  69. package/core/specs/__pycache__/schema.cpython-313.pyc +0 -0
  70. package/core/specs/manager.py +164 -0
  71. package/core/specs/schema.py +199 -0
  72. package/core/squads/__init__.py +7 -0
  73. package/core/squads/__pycache__/__init__.cpython-313.pyc +0 -0
  74. package/core/squads/__pycache__/loader.cpython-313.pyc +0 -0
  75. package/core/squads/__pycache__/registry.cpython-313.pyc +0 -0
  76. package/core/squads/__pycache__/schema.cpython-313.pyc +0 -0
  77. package/core/squads/loader.py +40 -0
  78. package/core/squads/registry.py +145 -0
  79. package/core/squads/schema.py +93 -0
  80. package/core/synapse/__init__.py +11 -0
  81. package/core/synapse/__pycache__/__init__.cpython-313.pyc +0 -0
  82. package/core/synapse/__pycache__/cache.cpython-313.pyc +0 -0
  83. package/core/synapse/__pycache__/engine.cpython-313.pyc +0 -0
  84. package/core/synapse/__pycache__/layers.cpython-313.pyc +0 -0
  85. package/core/synapse/cache.py +82 -0
  86. package/core/synapse/engine.py +184 -0
  87. package/core/synapse/layers.py +441 -0
  88. package/core/tasks/__init__.py +6 -0
  89. package/core/tasks/__pycache__/__init__.cpython-313.pyc +0 -0
  90. package/core/tasks/__pycache__/manager.cpython-313.pyc +0 -0
  91. package/core/tasks/__pycache__/schema.cpython-313.pyc +0 -0
  92. package/core/tasks/manager.py +150 -0
  93. package/core/tasks/schema.py +108 -0
  94. package/core/workflow/__init__.py +10 -0
  95. package/core/workflow/__pycache__/__init__.cpython-313.pyc +0 -0
  96. package/core/workflow/__pycache__/engine.cpython-313.pyc +0 -0
  97. package/core/workflow/__pycache__/loader.cpython-313.pyc +0 -0
  98. package/core/workflow/__pycache__/schema.cpython-313.pyc +0 -0
  99. package/core/workflow/engine.py +216 -0
  100. package/core/workflow/loader.py +28 -0
  101. package/core/workflow/schema.py +129 -0
  102. package/departments/brand/SKILL.md +85 -0
  103. package/departments/brand/agents/brand-director.yaml +77 -0
  104. package/departments/brand/agents/brand-strategist.md +182 -0
  105. package/departments/brand/agents/brand-strategist.yaml +58 -0
  106. package/departments/brand/agents/creative-director.md +149 -0
  107. package/departments/brand/agents/motion-designer.md +113 -0
  108. package/departments/brand/agents/ux-designer.yaml +60 -0
  109. package/departments/brand/agents/visual-designer.md +187 -0
  110. package/departments/brand/agents/visual-designer.yaml +58 -0
  111. package/departments/brand/references/brand-creation-guide.md +559 -0
  112. package/departments/brand/scripts/provider-call.sh +262 -0
  113. package/departments/brand/skills/archetype-finder/SKILL.md +18 -0
  114. package/departments/brand/skills/colors/SKILL.md +18 -0
  115. package/departments/brand/skills/design-system/SKILL.md +18 -0
  116. package/departments/brand/skills/identity-system/SKILL.md +18 -0
  117. package/departments/brand/skills/logo-brief/SKILL.md +18 -0
  118. package/departments/brand/skills/mockup-generate/SKILL.md +18 -0
  119. package/departments/brand/skills/naming-evaluate/SKILL.md +50 -0
  120. package/departments/brand/skills/positioning-statement/SKILL.md +18 -0
  121. package/departments/brand/skills/primal-audit/SKILL.md +43 -0
  122. package/departments/brand/skills/ux-audit/SKILL.md +18 -0
  123. package/departments/brand/skills/voice-guide/SKILL.md +18 -0
  124. package/departments/brand/skills/wireframe/SKILL.md +18 -0
  125. package/departments/brand/squad.yaml +39 -0
  126. package/departments/brand/workflows/identity.yaml +113 -0
  127. package/departments/brand/workflows/naming.yaml +58 -0
  128. package/departments/community/SKILL.md +62 -0
  129. package/departments/community/agents/community-manager.yaml +57 -0
  130. package/departments/community/agents/community-strategist.yaml +74 -0
  131. package/departments/community/agents/engagement-designer.yaml +56 -0
  132. package/departments/community/skills/ai-community/SKILL.md +18 -0
  133. package/departments/community/skills/betting-setup/SKILL.md +18 -0
  134. package/departments/community/skills/business-model/SKILL.md +53 -0
  135. package/departments/community/skills/content-calendar/SKILL.md +18 -0
  136. package/departments/community/skills/events-plan/SKILL.md +18 -0
  137. package/departments/community/skills/gamification-design/SKILL.md +18 -0
  138. package/departments/community/skills/growth-plan/SKILL.md +18 -0
  139. package/departments/community/skills/metrics-track/SKILL.md +18 -0
  140. package/departments/community/skills/moderation/SKILL.md +18 -0
  141. package/departments/community/skills/monetize-plan/SKILL.md +18 -0
  142. package/departments/community/skills/niche-setup/SKILL.md +18 -0
  143. package/departments/community/skills/onboarding-flow/SKILL.md +18 -0
  144. package/departments/community/skills/platform-select/SKILL.md +18 -0
  145. package/departments/community/skills/retention-system/SKILL.md +48 -0
  146. package/departments/community/squad.yaml +32 -0
  147. package/departments/community/workflows/setup.yaml +62 -0
  148. package/departments/content/SKILL.md +65 -0
  149. package/departments/content/agents/content-strategist.yaml +74 -0
  150. package/departments/content/agents/repurpose-distributor.yaml +57 -0
  151. package/departments/content/agents/scriptwriter.yaml +56 -0
  152. package/departments/content/agents/viral-engineer.yaml +56 -0
  153. package/departments/content/skills/ai-workflow/SKILL.md +18 -0
  154. package/departments/content/skills/analytics/SKILL.md +18 -0
  155. package/departments/content/skills/calendar/SKILL.md +18 -0
  156. package/departments/content/skills/content-system/SKILL.md +75 -0
  157. package/departments/content/skills/hook-write/SKILL.md +43 -0
  158. package/departments/content/skills/monetization-plan/SKILL.md +18 -0
  159. package/departments/content/skills/newsletter-write/SKILL.md +18 -0
  160. package/departments/content/skills/platform-optimize/SKILL.md +18 -0
  161. package/departments/content/skills/repurpose-plan/SKILL.md +18 -0
  162. package/departments/content/skills/script-structure/SKILL.md +18 -0
  163. package/departments/content/skills/short-form/SKILL.md +18 -0
  164. package/departments/content/skills/thumbnail-package/SKILL.md +18 -0
  165. package/departments/content/skills/viral-design/SKILL.md +45 -0
  166. package/departments/content/skills/youtube-strategy/SKILL.md +18 -0
  167. package/departments/content/squad.yaml +39 -0
  168. package/departments/content/workflows/viral.yaml +99 -0
  169. package/departments/dev/SKILL.md +135 -0
  170. package/departments/dev/agents/analyst.md +184 -0
  171. package/departments/dev/agents/architect.md +184 -0
  172. package/departments/dev/agents/architect.yaml +74 -0
  173. package/departments/dev/agents/backend-dev.yaml +70 -0
  174. package/departments/dev/agents/cto.md +140 -0
  175. package/departments/dev/agents/cto.yaml +77 -0
  176. package/departments/dev/agents/dba.yaml +72 -0
  177. package/departments/dev/agents/devops-eng.yaml +72 -0
  178. package/departments/dev/agents/devops.md +204 -0
  179. package/departments/dev/agents/frontend-dev.md +213 -0
  180. package/departments/dev/agents/frontend-dev.yaml +71 -0
  181. package/departments/dev/agents/qa-eng.yaml +72 -0
  182. package/departments/dev/agents/qa.md +231 -0
  183. package/departments/dev/agents/security-eng.yaml +72 -0
  184. package/departments/dev/agents/security.md +174 -0
  185. package/departments/dev/agents/senior-dev.md +177 -0
  186. package/departments/dev/agents/tech-lead.md +188 -0
  187. package/departments/dev/agents/tech-lead.yaml +72 -0
  188. package/departments/dev/skills/adversarial-review/SKILL.md +117 -0
  189. package/departments/dev/skills/agent-design/SKILL.md +127 -0
  190. package/departments/dev/skills/agent-workflow/SKILL.md +116 -0
  191. package/departments/dev/skills/ai-assisted-dev/SKILL.md +18 -0
  192. package/departments/dev/skills/ai-security/SKILL.md +112 -0
  193. package/departments/dev/skills/api-design/SKILL.md +59 -0
  194. package/departments/dev/skills/architecture-design/SKILL.md +89 -0
  195. package/departments/dev/skills/changelog/SKILL.md +110 -0
  196. package/departments/dev/skills/ci-cd-pipeline/SKILL.md +130 -0
  197. package/departments/dev/skills/clean-code-review/SKILL.md +65 -0
  198. package/departments/dev/skills/code-review/SKILL.md +18 -0
  199. package/departments/dev/skills/codebase-onboard/SKILL.md +109 -0
  200. package/departments/dev/skills/db-design/SKILL.md +18 -0
  201. package/departments/dev/skills/db-schema/SKILL.md +130 -0
  202. package/departments/dev/skills/ddd-model/SKILL.md +18 -0
  203. package/departments/dev/skills/dependency-audit/SKILL.md +118 -0
  204. package/departments/dev/skills/deploy/SKILL.md +18 -0
  205. package/departments/dev/skills/devops-pipeline/SKILL.md +18 -0
  206. package/departments/dev/skills/docs/SKILL.md +18 -0
  207. package/departments/dev/skills/env-secrets/SKILL.md +89 -0
  208. package/departments/dev/skills/incident/SKILL.md +125 -0
  209. package/departments/dev/skills/mcp/SKILL.md +106 -0
  210. package/departments/dev/skills/mcp-builder/SKILL.md +121 -0
  211. package/departments/dev/skills/observability/SKILL.md +119 -0
  212. package/departments/dev/skills/onboard/SKILL.md +389 -0
  213. package/departments/dev/skills/onboard/scripts/detect-stack.py +472 -0
  214. package/departments/dev/skills/performance-audit/SKILL.md +49 -0
  215. package/departments/dev/skills/performance-profiler/SKILL.md +128 -0
  216. package/departments/dev/skills/rag-architect/SKILL.md +125 -0
  217. package/departments/dev/skills/red-team/SKILL.md +112 -0
  218. package/departments/dev/skills/refactor-plan/SKILL.md +18 -0
  219. package/departments/dev/skills/release/SKILL.md +130 -0
  220. package/departments/dev/skills/research/SKILL.md +18 -0
  221. package/departments/dev/skills/runbook/SKILL.md +103 -0
  222. package/departments/dev/skills/scaffold/SKILL.md +249 -0
  223. package/departments/dev/skills/security-audit/SKILL.md +68 -0
  224. package/departments/dev/skills/skill-audit/SKILL.md +96 -0
  225. package/departments/dev/skills/spec/SKILL.md +218 -0
  226. package/departments/dev/skills/stack-check/SKILL.md +18 -0
  227. package/departments/dev/skills/tdd-cycle/SKILL.md +56 -0
  228. package/departments/dev/skills/tech-debt/SKILL.md +100 -0
  229. package/departments/dev/squad.yaml +62 -0
  230. package/departments/dev/workflows/debug.yaml +63 -0
  231. package/departments/dev/workflows/feature.yaml +129 -0
  232. package/departments/dev/workflows/refactor.yaml +64 -0
  233. package/departments/ecom/SKILL.md +39 -0
  234. package/departments/ecom/agents/commerce-engineer.yaml +58 -0
  235. package/departments/ecom/agents/cro-specialist.yaml +56 -0
  236. package/departments/ecom/agents/ecom-director.yaml +73 -0
  237. package/departments/ecom/agents/retention-manager.yaml +59 -0
  238. package/departments/ecom/skills/analytics/SKILL.md +18 -0
  239. package/departments/ecom/skills/cart-recovery/SKILL.md +18 -0
  240. package/departments/ecom/skills/cro-optimize/SKILL.md +58 -0
  241. package/departments/ecom/skills/customer-journey/SKILL.md +18 -0
  242. package/departments/ecom/skills/fulfillment-plan/SKILL.md +18 -0
  243. package/departments/ecom/skills/marketplace-manage/SKILL.md +18 -0
  244. package/departments/ecom/skills/pricing-strategy/SKILL.md +18 -0
  245. package/departments/ecom/skills/product-launch/SKILL.md +18 -0
  246. package/departments/ecom/skills/rfm-segment/SKILL.md +44 -0
  247. package/departments/ecom/skills/social-commerce/SKILL.md +18 -0
  248. package/departments/ecom/skills/store-audit/SKILL.md +18 -0
  249. package/departments/ecom/skills/subscription-model/SKILL.md +18 -0
  250. package/departments/ecom/squad.yaml +39 -0
  251. package/departments/ecom/workflows/product-page.yaml +62 -0
  252. package/departments/ecommerce/SKILL.md +363 -0
  253. package/departments/ecommerce/agents/ecommerce-manager.md +91 -0
  254. package/departments/finance/SKILL.md +37 -0
  255. package/departments/finance/agents/cfo.md +85 -0
  256. package/departments/finance/agents/cfo.yaml +77 -0
  257. package/departments/finance/agents/financial-analyst.yaml +57 -0
  258. package/departments/finance/agents/investment-strategist.yaml +58 -0
  259. package/departments/finance/skills/budget-plan/SKILL.md +18 -0
  260. package/departments/finance/skills/cashflow-forecast/SKILL.md +18 -0
  261. package/departments/finance/skills/ciso-advisor/SKILL.md +113 -0
  262. package/departments/finance/skills/financial-model/SKILL.md +70 -0
  263. package/departments/finance/skills/pitch-deck/SKILL.md +18 -0
  264. package/departments/finance/skills/scenario-analysis/SKILL.md +18 -0
  265. package/departments/finance/skills/unit-economics/SKILL.md +44 -0
  266. package/departments/finance/skills/valuation-model/SKILL.md +18 -0
  267. package/departments/finance/squad.yaml +37 -0
  268. package/departments/finance/workflows/cashflow.yaml +47 -0
  269. package/departments/finance/workflows/model.yaml +83 -0
  270. package/departments/kb/SKILL.md +38 -0
  271. package/departments/kb/agents/knowledge-curator.yaml +60 -0
  272. package/departments/kb/agents/knowledge-director.yaml +72 -0
  273. package/departments/kb/agents/research-analyst.yaml +58 -0
  274. package/departments/kb/skills/ai-research/SKILL.md +18 -0
  275. package/departments/kb/skills/competitive-intel/SKILL.md +18 -0
  276. package/departments/kb/skills/knowledge-review/SKILL.md +18 -0
  277. package/departments/kb/skills/learn-content/SKILL.md +18 -0
  278. package/departments/kb/skills/moc-create/SKILL.md +18 -0
  279. package/departments/kb/skills/persona-build/SKILL.md +18 -0
  280. package/departments/kb/skills/research-plan/SKILL.md +51 -0
  281. package/departments/kb/skills/search-kb/SKILL.md +18 -0
  282. package/departments/kb/skills/source-evaluate/SKILL.md +18 -0
  283. package/departments/kb/skills/taxonomy-manage/SKILL.md +18 -0
  284. package/departments/kb/skills/write-as-persona/SKILL.md +18 -0
  285. package/departments/kb/skills/zettelkasten-process/SKILL.md +56 -0
  286. package/departments/kb/squad.yaml +34 -0
  287. package/departments/kb/workflows/learn.yaml +63 -0
  288. package/departments/knowledge/SKILL.md +474 -0
  289. package/departments/knowledge/agents/knowledge-curator.md +89 -0
  290. package/departments/knowledge/scripts/kb-check-capabilities.sh +143 -0
  291. package/departments/knowledge/scripts/kb-cleanup.sh +135 -0
  292. package/departments/knowledge/scripts/kb-queue.sh +156 -0
  293. package/departments/knowledge/scripts/kb-status.sh +195 -0
  294. package/departments/knowledge/scripts/kb-worker.sh +217 -0
  295. package/departments/landing/SKILL.md +65 -0
  296. package/departments/landing/agents/affiliate-manager.yaml +57 -0
  297. package/departments/landing/agents/conversion-strategist.yaml +74 -0
  298. package/departments/landing/agents/cro-specialist.yaml +58 -0
  299. package/departments/landing/agents/sales-copywriter.yaml +61 -0
  300. package/departments/landing/skills/ab-test/SKILL.md +18 -0
  301. package/departments/landing/skills/affiliate-bridge/SKILL.md +18 -0
  302. package/departments/landing/skills/awareness-diagnose/SKILL.md +18 -0
  303. package/departments/landing/skills/copy-framework/SKILL.md +55 -0
  304. package/departments/landing/skills/email-sequence/SKILL.md +18 -0
  305. package/departments/landing/skills/funnel-design/SKILL.md +49 -0
  306. package/departments/landing/skills/funnel-metrics/SKILL.md +18 -0
  307. package/departments/landing/skills/headline-write/SKILL.md +18 -0
  308. package/departments/landing/skills/landing-gen/SKILL.md +124 -0
  309. package/departments/landing/skills/launch-sequence/SKILL.md +18 -0
  310. package/departments/landing/skills/offer-create/SKILL.md +62 -0
  311. package/departments/landing/skills/optimize-page/SKILL.md +18 -0
  312. package/departments/landing/skills/page-architect/SKILL.md +18 -0
  313. package/departments/landing/skills/persuasion-apply/SKILL.md +18 -0
  314. package/departments/landing/skills/webinar-funnel/SKILL.md +18 -0
  315. package/departments/landing/squad.yaml +39 -0
  316. package/departments/landing/workflows/launch.yaml +72 -0
  317. package/departments/landing/workflows/offer.yaml +99 -0
  318. package/departments/leadership/SKILL.md +35 -0
  319. package/departments/leadership/agents/culture-coach.yaml +59 -0
  320. package/departments/leadership/agents/hr-specialist.yaml +57 -0
  321. package/departments/leadership/agents/leadership-director.yaml +72 -0
  322. package/departments/leadership/skills/change-manage/SKILL.md +18 -0
  323. package/departments/leadership/skills/conflict-resolve/SKILL.md +18 -0
  324. package/departments/leadership/skills/culture-audit/SKILL.md +18 -0
  325. package/departments/leadership/skills/delegation-matrix/SKILL.md +18 -0
  326. package/departments/leadership/skills/disc-assess/SKILL.md +18 -0
  327. package/departments/leadership/skills/feedback-give/SKILL.md +18 -0
  328. package/departments/leadership/skills/hiring-plan/SKILL.md +18 -0
  329. package/departments/leadership/skills/okr-define/SKILL.md +69 -0
  330. package/departments/leadership/skills/performance-review/SKILL.md +18 -0
  331. package/departments/leadership/skills/team-health/SKILL.md +56 -0
  332. package/departments/leadership/squad.yaml +35 -0
  333. package/departments/leadership/workflows/team-build.yaml +55 -0
  334. package/departments/marketing/SKILL.md +61 -0
  335. package/departments/marketing/agents/content-creator.md +85 -0
  336. package/departments/marketing/agents/content-marketer.yaml +58 -0
  337. package/departments/marketing/agents/marketing-director.yaml +75 -0
  338. package/departments/marketing/agents/paid-specialist.yaml +58 -0
  339. package/departments/marketing/agents/seo-specialist.yaml +57 -0
  340. package/departments/marketing/skills/ab-test/SKILL.md +18 -0
  341. package/departments/marketing/skills/analytics-report/SKILL.md +18 -0
  342. package/departments/marketing/skills/audience-segment/SKILL.md +18 -0
  343. package/departments/marketing/skills/calendar-plan/SKILL.md +18 -0
  344. package/departments/marketing/skills/cold-email/SKILL.md +128 -0
  345. package/departments/marketing/skills/competitor-analysis/SKILL.md +18 -0
  346. package/departments/marketing/skills/content-audit/SKILL.md +18 -0
  347. package/departments/marketing/skills/email-sequence/SKILL.md +18 -0
  348. package/departments/marketing/skills/growth-loop/SKILL.md +50 -0
  349. package/departments/marketing/skills/marketing-automation/SKILL.md +18 -0
  350. package/departments/marketing/skills/paid-campaign/SKILL.md +18 -0
  351. package/departments/marketing/skills/programmatic-seo/SKILL.md +123 -0
  352. package/departments/marketing/skills/seo-audit/SKILL.md +48 -0
  353. package/departments/marketing/skills/social-strategy/SKILL.md +18 -0
  354. package/departments/marketing/squad.yaml +39 -0
  355. package/departments/marketing/workflows/campaign.yaml +112 -0
  356. package/departments/marketing/workflows/social.yaml +56 -0
  357. package/departments/operations/SKILL.md +422 -0
  358. package/departments/operations/agents/coo.md +88 -0
  359. package/departments/ops/SKILL.md +37 -0
  360. package/departments/ops/agents/automation-engineer.yaml +58 -0
  361. package/departments/ops/agents/ops-lead.yaml +71 -0
  362. package/departments/ops/skills/bottleneck-find/SKILL.md +49 -0
  363. package/departments/ops/skills/dashboard-build/SKILL.md +18 -0
  364. package/departments/ops/skills/gtd-setup/SKILL.md +18 -0
  365. package/departments/ops/skills/integration-design/SKILL.md +18 -0
  366. package/departments/ops/skills/lean-audit/SKILL.md +18 -0
  367. package/departments/ops/skills/metrics-dashboard/SKILL.md +18 -0
  368. package/departments/ops/skills/n8n-flow/SKILL.md +18 -0
  369. package/departments/ops/skills/sop-create/SKILL.md +18 -0
  370. package/departments/ops/skills/workflow-automate/SKILL.md +39 -0
  371. package/departments/ops/skills/zapier-flow/SKILL.md +18 -0
  372. package/departments/ops/squad.yaml +35 -0
  373. package/departments/ops/workflows/lean-audit.yaml +69 -0
  374. package/departments/org/SKILL.md +34 -0
  375. package/departments/org/agents/coo.yaml +80 -0
  376. package/departments/org/agents/org-designer.yaml +56 -0
  377. package/departments/org/agents/people-ops.yaml +56 -0
  378. package/departments/org/skills/compensation-plan/SKILL.md +18 -0
  379. package/departments/org/skills/culture-define/SKILL.md +18 -0
  380. package/departments/org/skills/decision-framework/SKILL.md +18 -0
  381. package/departments/org/skills/hiring-plan/SKILL.md +18 -0
  382. package/departments/org/skills/meeting-optimize/SKILL.md +18 -0
  383. package/departments/org/skills/onboarding-design/SKILL.md +18 -0
  384. package/departments/org/skills/org-design/SKILL.md +18 -0
  385. package/departments/org/skills/remote-setup/SKILL.md +18 -0
  386. package/departments/org/skills/sop-process/SKILL.md +18 -0
  387. package/departments/org/skills/team-assess/SKILL.md +18 -0
  388. package/departments/org/squad.yaml +33 -0
  389. package/departments/org/workflows/design.yaml +55 -0
  390. package/departments/pm/SKILL.md +39 -0
  391. package/departments/pm/agents/pm-director.yaml +75 -0
  392. package/departments/pm/agents/product-owner.yaml +59 -0
  393. package/departments/pm/agents/scrum-master.yaml +59 -0
  394. package/departments/pm/skills/agile-po/SKILL.md +118 -0
  395. package/departments/pm/skills/backlog-groom/SKILL.md +18 -0
  396. package/departments/pm/skills/discovery-plan/SKILL.md +48 -0
  397. package/departments/pm/skills/estimate-forecast/SKILL.md +18 -0
  398. package/departments/pm/skills/impact-map/SKILL.md +18 -0
  399. package/departments/pm/skills/kanban-setup/SKILL.md +18 -0
  400. package/departments/pm/skills/risk-register/SKILL.md +18 -0
  401. package/departments/pm/skills/roadmap-build/SKILL.md +18 -0
  402. package/departments/pm/skills/shape-pitch/SKILL.md +55 -0
  403. package/departments/pm/skills/sprint-plan/SKILL.md +18 -0
  404. package/departments/pm/skills/stakeholder-map/SKILL.md +18 -0
  405. package/departments/pm/skills/standup-run/SKILL.md +18 -0
  406. package/departments/pm/skills/story-write/SKILL.md +18 -0
  407. package/departments/pm/squad.yaml +37 -0
  408. package/departments/pm/workflows/retro.yaml +33 -0
  409. package/departments/quality/SKILL.md +66 -0
  410. package/departments/quality/agents/copy-director.md +134 -0
  411. package/departments/quality/agents/copy-director.yaml +73 -0
  412. package/departments/quality/agents/cqo.md +134 -0
  413. package/departments/quality/agents/cqo.yaml +76 -0
  414. package/departments/quality/agents/tech-director.yaml +79 -0
  415. package/departments/quality/agents/tech-ux-director.md +193 -0
  416. package/departments/quality/squad.yaml +25 -0
  417. package/departments/saas/SKILL.md +64 -0
  418. package/departments/saas/agents/cs-manager.yaml +57 -0
  419. package/departments/saas/agents/growth-engineer.yaml +57 -0
  420. package/departments/saas/agents/metrics-analyst.yaml +57 -0
  421. package/departments/saas/agents/saas-strategist.yaml +74 -0
  422. package/departments/saas/skills/benchmark-compare/SKILL.md +18 -0
  423. package/departments/saas/skills/churn-analysis/SKILL.md +18 -0
  424. package/departments/saas/skills/customer-success/SKILL.md +18 -0
  425. package/departments/saas/skills/growth-plan/SKILL.md +18 -0
  426. package/departments/saas/skills/gtm-strategy/SKILL.md +18 -0
  427. package/departments/saas/skills/launch-execute/SKILL.md +18 -0
  428. package/departments/saas/skills/metrics-dashboard/SKILL.md +18 -0
  429. package/departments/saas/skills/micro-saas-stack/SKILL.md +18 -0
  430. package/departments/saas/skills/mvp-build/SKILL.md +18 -0
  431. package/departments/saas/skills/niche-evaluate/SKILL.md +18 -0
  432. package/departments/saas/skills/onboarding-optimize/SKILL.md +18 -0
  433. package/departments/saas/skills/plg-setup/SKILL.md +53 -0
  434. package/departments/saas/skills/pricing-strategy/SKILL.md +48 -0
  435. package/departments/saas/skills/saas-scaffold/SKILL.md +127 -0
  436. package/departments/saas/skills/validate-idea/SKILL.md +55 -0
  437. package/departments/saas/squad.yaml +37 -0
  438. package/departments/saas/workflows/metrics.yaml +58 -0
  439. package/departments/saas/workflows/validate.yaml +103 -0
  440. package/departments/sales/SKILL.md +35 -0
  441. package/departments/sales/agents/sales-closer.yaml +58 -0
  442. package/departments/sales/agents/sales-director.yaml +72 -0
  443. package/departments/sales/agents/sales-ops.yaml +55 -0
  444. package/departments/sales/skills/challenger-sell/SKILL.md +18 -0
  445. package/departments/sales/skills/deal-qualify/SKILL.md +18 -0
  446. package/departments/sales/skills/discovery-call/SKILL.md +18 -0
  447. package/departments/sales/skills/forecast-revenue/SKILL.md +18 -0
  448. package/departments/sales/skills/negotiate-plan/SKILL.md +18 -0
  449. package/departments/sales/skills/objection-handle/SKILL.md +18 -0
  450. package/departments/sales/skills/pipeline-manage/SKILL.md +18 -0
  451. package/departments/sales/skills/pricing-negotiate/SKILL.md +18 -0
  452. package/departments/sales/skills/proposal-write/SKILL.md +54 -0
  453. package/departments/sales/skills/spin-sell/SKILL.md +50 -0
  454. package/departments/sales/squad.yaml +35 -0
  455. package/departments/sales/workflows/pipeline.yaml +49 -0
  456. package/departments/strategy/SKILL.md +37 -0
  457. package/departments/strategy/agents/business-model-designer.yaml +58 -0
  458. package/departments/strategy/agents/market-analyst.yaml +58 -0
  459. package/departments/strategy/agents/strategist.md +79 -0
  460. package/departments/strategy/agents/strategy-director.yaml +75 -0
  461. package/departments/strategy/skills/blue-ocean/SKILL.md +56 -0
  462. package/departments/strategy/skills/bmc/SKILL.md +18 -0
  463. package/departments/strategy/skills/board-advisor/SKILL.md +121 -0
  464. package/departments/strategy/skills/cto-advisor/SKILL.md +113 -0
  465. package/departments/strategy/skills/five-forces/SKILL.md +74 -0
  466. package/departments/strategy/skills/growth-strategy/SKILL.md +18 -0
  467. package/departments/strategy/skills/moat-analysis/SKILL.md +18 -0
  468. package/departments/strategy/skills/position/SKILL.md +18 -0
  469. package/departments/strategy/skills/scenario-plan/SKILL.md +18 -0
  470. package/departments/strategy/squad.yaml +37 -0
  471. package/departments/strategy/workflows/analysis.yaml +90 -0
  472. package/departments/strategy/workflows/swot.yaml +47 -0
  473. package/installer/adapters/claude-code.js +73 -0
  474. package/installer/adapters/codex-cli.js +34 -0
  475. package/installer/adapters/cursor.js +34 -0
  476. package/installer/adapters/gemini-cli.js +37 -0
  477. package/installer/cli.js +91 -0
  478. package/installer/detect-runtime.js +122 -0
  479. package/installer/doctor.js +105 -0
  480. package/installer/index.js +199 -0
  481. package/installer/uninstall.js +46 -0
  482. package/installer/update.js +39 -0
  483. package/knowledge/agents-registry-v2.json +2702 -0
  484. package/knowledge/commands-registry-v2.json +3827 -0
  485. package/package.json +58 -0
  486. package/pyproject.toml +64 -0
@@ -0,0 +1,68 @@
1
+ """Gemini CLI runtime adapter.
2
+
3
+ Google's Gemini CLI. Uses GEMINI.md for instructions and activate_skill for skills.
4
+ """
5
+
6
+ from pathlib import Path
7
+ from os.path import expanduser
8
+
9
+ from core.runtime.base import RuntimeAdapter, RuntimeConfig, AgentContext, AgentResult
10
+
11
+
12
+ class GeminiCliAdapter(RuntimeAdapter):
13
+ """Adapter for Google's Gemini CLI."""
14
+
15
+ def get_config(self) -> RuntimeConfig:
16
+ home = Path(expanduser("~"))
17
+ return RuntimeConfig(
18
+ id="gemini",
19
+ name="Gemini CLI",
20
+ config_dir=home / ".gemini",
21
+ skills_dir=home / ".gemini" / "skills",
22
+ settings_file=home / ".gemini" / "settings.json",
23
+ supports_hooks=False,
24
+ supports_subagents=True,
25
+ supports_mcp=True,
26
+ max_context_tokens=1_000_000,
27
+ )
28
+
29
+ def inject_context(self, layers: dict[str, str]) -> str:
30
+ """Gemini receives context via GEMINI.md instruction file."""
31
+ parts = []
32
+ for name, content in layers.items():
33
+ parts.append(f"## {name}\n{content}")
34
+ return "\n\n".join(parts)
35
+
36
+ def dispatch_agent(self, context: AgentContext) -> AgentResult:
37
+ return AgentResult(
38
+ agent_id=context.agent_id,
39
+ status="dispatched",
40
+ output=f"Agent {context.agent_id} dispatched via Gemini CLI",
41
+ metadata={"runtime": "gemini"},
42
+ )
43
+
44
+ def spawn_subagent(self, context: AgentContext) -> AgentResult:
45
+ return AgentResult(
46
+ agent_id=context.agent_id,
47
+ status="dispatched",
48
+ output=f"Subagent {context.agent_id} spawned via Gemini CLI",
49
+ metadata={"runtime": "gemini", "pattern": "subagent"},
50
+ )
51
+
52
+ def read_file(self, path: str) -> str:
53
+ raise NotImplementedError("Use Gemini CLI's native file read")
54
+
55
+ def write_file(self, path: str, content: str) -> None:
56
+ raise NotImplementedError("Use Gemini CLI's native file write")
57
+
58
+ def edit_file(self, path: str, old: str, new: str) -> None:
59
+ raise NotImplementedError("Use Gemini CLI's native file edit")
60
+
61
+ def execute_command(self, command: str, timeout: int = 120) -> tuple[str, int]:
62
+ raise NotImplementedError("Use Gemini CLI's native shell execution")
63
+
64
+ def search_files(self, pattern: str, path: str = ".") -> list[str]:
65
+ raise NotImplementedError("Use Gemini CLI's native file search")
66
+
67
+ def search_content(self, pattern: str, path: str = ".") -> list[str]:
68
+ raise NotImplementedError("Use Gemini CLI's native content search")
@@ -0,0 +1,86 @@
1
+ """Runtime registry — maps runtime IDs to adapter instances."""
2
+
3
+ from core.runtime.base import RuntimeAdapter
4
+ from core.runtime.claude_code import ClaudeCodeAdapter
5
+ from core.runtime.codex_cli import CodexCliAdapter
6
+ from core.runtime.gemini_cli import GeminiCliAdapter
7
+ from core.runtime.cursor import CursorAdapter
8
+
9
+ _ADAPTERS: dict[str, type[RuntimeAdapter]] = {
10
+ "claude-code": ClaudeCodeAdapter,
11
+ "codex": CodexCliAdapter,
12
+ "gemini": GeminiCliAdapter,
13
+ "cursor": CursorAdapter,
14
+ }
15
+
16
+
17
+ def get_adapter(runtime_id: str) -> RuntimeAdapter:
18
+ """Get an adapter instance for the given runtime ID.
19
+
20
+ Args:
21
+ runtime_id: One of 'claude-code', 'codex', 'gemini', 'cursor'
22
+
23
+ Returns:
24
+ Instantiated RuntimeAdapter for the runtime.
25
+
26
+ Raises:
27
+ ValueError: If runtime_id is not recognized.
28
+ """
29
+ adapter_cls = _ADAPTERS.get(runtime_id)
30
+ if adapter_cls is None:
31
+ supported = ", ".join(_ADAPTERS.keys())
32
+ raise ValueError(f"Unknown runtime: {runtime_id}. Supported: {supported}")
33
+ return adapter_cls()
34
+
35
+
36
+ def detect_runtime() -> str:
37
+ """Detect which runtime is currently active.
38
+
39
+ Checks environment variables and process context to determine
40
+ which AI runtime is executing this code.
41
+
42
+ Returns:
43
+ Runtime ID string.
44
+ """
45
+ import os
46
+
47
+ # Check environment variables set by each runtime
48
+ if os.environ.get("CLAUDE_CODE"):
49
+ return "claude-code"
50
+ if os.environ.get("CODEX_CLI"):
51
+ return "codex"
52
+ if os.environ.get("GEMINI_CLI"):
53
+ return "gemini"
54
+ if os.environ.get("CURSOR_SESSION"):
55
+ return "cursor"
56
+
57
+ # Check for runtime-specific config directories
58
+ from pathlib import Path
59
+
60
+ home = Path.home()
61
+ if (home / ".claude" / "settings.json").exists():
62
+ return "claude-code"
63
+ if (home / ".codex").exists():
64
+ return "codex"
65
+ if (home / ".gemini").exists():
66
+ return "gemini"
67
+ if (home / ".cursor").exists():
68
+ return "cursor"
69
+
70
+ # Default to claude-code as primary runtime
71
+ return "claude-code"
72
+
73
+
74
+ def list_runtimes() -> list[dict[str, str]]:
75
+ """List all supported runtimes with their status."""
76
+ results = []
77
+ for runtime_id, adapter_cls in _ADAPTERS.items():
78
+ adapter = adapter_cls()
79
+ config = adapter.get_config()
80
+ results.append({
81
+ "id": runtime_id,
82
+ "name": config.name,
83
+ "config_dir": str(config.config_dir),
84
+ "installed": config.config_dir.exists(),
85
+ })
86
+ return results
@@ -0,0 +1,201 @@
1
+ """Subagent Pattern — fresh agent instances per task.
2
+
3
+ Each subagent gets a fresh context window, preventing context pollution
4
+ between tasks. The orchestrator uses only 10-15% of its context to
5
+ dispatch and collect results.
6
+
7
+ Pattern: Orchestrator compacts task description + relevant context into
8
+ a brief, dispatches to a subagent, and receives a structured result.
9
+
10
+ Context budget:
11
+ - Orchestrator: 10-15% of context window for dispatch + collection
12
+ - Subagent: Full context window for task execution
13
+ - Handoff artifact: ~379 tokens per agent switch (compacted persona + task)
14
+ """
15
+
16
+ from dataclasses import dataclass, field
17
+ from enum import Enum
18
+ from typing import Optional, Any
19
+
20
+ from core.agents.schema import Agent
21
+
22
+
23
+ class SubagentStatus(str, Enum):
24
+ PENDING = "pending"
25
+ RUNNING = "running"
26
+ COMPLETED = "completed"
27
+ FAILED = "failed"
28
+ TIMEOUT = "timeout"
29
+
30
+
31
+ @dataclass
32
+ class HandoffArtifact:
33
+ """Compacted context passed from orchestrator to subagent.
34
+
35
+ This is the ~379-token artifact that carries everything
36
+ the subagent needs to start working without full history.
37
+ """
38
+ task_id: str
39
+ task_description: str
40
+ agent_id: str
41
+ agent_role: str
42
+ agent_disc: str # Compact DISC label
43
+ department: str
44
+ relevant_files: list[str] = field(default_factory=list)
45
+ context_summary: str = "" # Compacted prior context
46
+ constraints: list[str] = field(default_factory=list)
47
+ expected_output: str = ""
48
+ quality_criteria: list[str] = field(default_factory=list)
49
+
50
+ def to_prompt(self) -> str:
51
+ """Convert to a prompt string for the subagent."""
52
+ parts = [
53
+ f"# Task: {self.task_description}",
54
+ f"Agent: {self.agent_id} ({self.agent_role}, {self.agent_disc})",
55
+ f"Department: {self.department}",
56
+ ]
57
+ if self.context_summary:
58
+ parts.append(f"\n## Context\n{self.context_summary}")
59
+ if self.relevant_files:
60
+ parts.append(f"\n## Relevant Files\n" + "\n".join(f"- {f}" for f in self.relevant_files))
61
+ if self.constraints:
62
+ parts.append(f"\n## Constraints\n" + "\n".join(f"- {c}" for c in self.constraints))
63
+ if self.expected_output:
64
+ parts.append(f"\n## Expected Output\n{self.expected_output}")
65
+ if self.quality_criteria:
66
+ parts.append(f"\n## Quality Criteria\n" + "\n".join(f"- {q}" for q in self.quality_criteria))
67
+ return "\n".join(parts)
68
+
69
+ @property
70
+ def estimated_tokens(self) -> int:
71
+ """Estimate token count of this artifact."""
72
+ return len(self.to_prompt().split())
73
+
74
+
75
+ @dataclass
76
+ class SubagentResult:
77
+ """Result returned by a subagent."""
78
+ task_id: str
79
+ agent_id: str
80
+ status: SubagentStatus
81
+ output: str = ""
82
+ files_modified: list[str] = field(default_factory=list)
83
+ tokens_used: int = 0
84
+ duration_ms: int = 0
85
+ metadata: dict[str, Any] = field(default_factory=dict)
86
+
87
+ def to_summary(self, max_tokens: int = 200) -> str:
88
+ """Compact the result for the orchestrator's context.
89
+
90
+ The orchestrator doesn't need the full output, just a summary
91
+ to decide next steps.
92
+ """
93
+ words = self.output.split()
94
+ if len(words) <= max_tokens:
95
+ return self.output
96
+ return " ".join(words[:max_tokens]) + "..."
97
+
98
+
99
+ class SubagentDispatcher:
100
+ """Dispatches tasks to fresh subagent instances.
101
+
102
+ The dispatcher creates HandoffArtifacts from agent definitions
103
+ and task descriptions, then delegates to the runtime adapter
104
+ for actual execution.
105
+ """
106
+
107
+ def __init__(self) -> None:
108
+ self._pending: dict[str, HandoffArtifact] = {}
109
+ self._results: dict[str, SubagentResult] = {}
110
+ self._task_counter: int = 0
111
+
112
+ def create_handoff(
113
+ self,
114
+ agent: Agent,
115
+ task_description: str,
116
+ relevant_files: list[str] | None = None,
117
+ context_summary: str = "",
118
+ constraints: list[str] | None = None,
119
+ expected_output: str = "",
120
+ ) -> HandoffArtifact:
121
+ """Create a handoff artifact for a subagent dispatch.
122
+
123
+ Args:
124
+ agent: The agent to dispatch to.
125
+ task_description: What the subagent should do.
126
+ relevant_files: File paths the subagent should read.
127
+ context_summary: Compacted context from prior work.
128
+ constraints: Boundaries for the subagent.
129
+ expected_output: What format/content is expected back.
130
+
131
+ Returns:
132
+ HandoffArtifact ready for dispatch.
133
+ """
134
+ self._task_counter += 1
135
+ task_id = f"task-{self._task_counter}"
136
+
137
+ disc_label = agent.behavioral_dna.disc.label
138
+ quality = []
139
+ if agent.tier <= 1:
140
+ quality.append("Enterprise-grade quality expected")
141
+ quality.append("Follow SOLID principles")
142
+ quality.append("Human-readable output, no AI patterns")
143
+
144
+ artifact = HandoffArtifact(
145
+ task_id=task_id,
146
+ task_description=task_description,
147
+ agent_id=agent.id,
148
+ agent_role=agent.role,
149
+ agent_disc=disc_label,
150
+ department=agent.department,
151
+ relevant_files=relevant_files or [],
152
+ context_summary=context_summary,
153
+ constraints=constraints or [],
154
+ expected_output=expected_output,
155
+ quality_criteria=quality,
156
+ )
157
+
158
+ self._pending[task_id] = artifact
159
+ return artifact
160
+
161
+ def record_result(self, result: SubagentResult) -> None:
162
+ """Record a subagent's result."""
163
+ self._results[result.task_id] = result
164
+ self._pending.pop(result.task_id, None)
165
+
166
+ def get_result(self, task_id: str) -> Optional[SubagentResult]:
167
+ """Get a subagent's result by task ID."""
168
+ return self._results.get(task_id)
169
+
170
+ def get_pending(self) -> list[HandoffArtifact]:
171
+ """Get all pending (undispatched) handoffs."""
172
+ return list(self._pending.values())
173
+
174
+ def get_all_results(self) -> list[SubagentResult]:
175
+ """Get all collected results."""
176
+ return list(self._results.values())
177
+
178
+ @property
179
+ def pending_count(self) -> int:
180
+ return len(self._pending)
181
+
182
+ @property
183
+ def completed_count(self) -> int:
184
+ return len(self._results)
185
+
186
+ def orchestrator_context_usage(self) -> dict:
187
+ """Estimate how much context the orchestrator is using.
188
+
189
+ Target: 10-15% of context window for dispatch + collection.
190
+ """
191
+ dispatch_tokens = sum(a.estimated_tokens for a in self._pending.values())
192
+ result_tokens = sum(
193
+ len(r.to_summary().split()) for r in self._results.values()
194
+ )
195
+ total = dispatch_tokens + result_tokens
196
+ return {
197
+ "dispatch_tokens": dispatch_tokens,
198
+ "result_summary_tokens": result_tokens,
199
+ "total_orchestrator_tokens": total,
200
+ "tasks_dispatched": self._task_counter,
201
+ }
@@ -0,0 +1,10 @@
1
+ """Living Specs — bidirectional spec/code sync.
2
+
3
+ Specs are never stale. They track implementation status, record deltas,
4
+ and build a reusable library of validated specifications.
5
+ """
6
+
7
+ from core.specs.schema import Spec, SpecStatus, SpecSection, SpecDelta
8
+ from core.specs.manager import SpecManager
9
+
10
+ __all__ = ["Spec", "SpecStatus", "SpecSection", "SpecDelta", "SpecManager"]
@@ -0,0 +1,164 @@
1
+ """Spec manager — lifecycle management for Living Specs."""
2
+
3
+ from pathlib import Path
4
+ from typing import Optional
5
+
6
+ import yaml
7
+
8
+ from core.specs.schema import (
9
+ Spec, SpecStatus, SpecSection, SpecDelta,
10
+ AcceptanceCriterion, SpecMetadata, SectionStatus,
11
+ )
12
+
13
+
14
+ class SpecManager:
15
+ """Manages the lifecycle of Living Specs.
16
+
17
+ Handles creation, loading, saving, status transitions,
18
+ and the reusable spec library.
19
+ """
20
+
21
+ def __init__(self, specs_dir: str | Path = "") -> None:
22
+ self._specs: dict[str, Spec] = {}
23
+ self._specs_dir = Path(specs_dir) if specs_dir else None
24
+
25
+ def create(
26
+ self,
27
+ spec_id: str,
28
+ title: str,
29
+ description: str = "",
30
+ project: str = "",
31
+ department: str = "",
32
+ sections: list[dict] | None = None,
33
+ ) -> Spec:
34
+ """Create a new spec."""
35
+ from datetime import datetime
36
+
37
+ spec_sections = []
38
+ for s in (sections or []):
39
+ criteria = [
40
+ AcceptanceCriterion(id=f"ac-{i+1}", description=c)
41
+ for i, c in enumerate(s.get("acceptance_criteria", []))
42
+ ]
43
+ spec_sections.append(SpecSection(
44
+ id=s.get("id", f"section-{len(spec_sections)+1}"),
45
+ title=s.get("title", ""),
46
+ content=s.get("content", ""),
47
+ acceptance_criteria=criteria,
48
+ ))
49
+
50
+ spec = Spec(
51
+ id=spec_id,
52
+ title=title,
53
+ description=description,
54
+ status=SpecStatus.DRAFT,
55
+ metadata=SpecMetadata(
56
+ project=project,
57
+ department=department,
58
+ created_at=datetime.now().isoformat(),
59
+ ),
60
+ sections=spec_sections,
61
+ )
62
+
63
+ self._specs[spec_id] = spec
64
+ return spec
65
+
66
+ def get(self, spec_id: str) -> Optional[Spec]:
67
+ """Get a spec by ID."""
68
+ return self._specs.get(spec_id)
69
+
70
+ def approve(self, spec_id: str, approved_by: str = "") -> bool:
71
+ """Approve a spec for implementation."""
72
+ spec = self._specs.get(spec_id)
73
+ if spec is None or spec.status not in (SpecStatus.DRAFT, SpecStatus.REVIEW):
74
+ return False
75
+ spec.status = SpecStatus.APPROVED
76
+ spec.metadata.approved_by = approved_by
77
+ from datetime import datetime
78
+ spec.metadata.approved_at = datetime.now().isoformat()
79
+ return True
80
+
81
+ def start_implementation(self, spec_id: str) -> bool:
82
+ """Mark spec as in-progress."""
83
+ spec = self._specs.get(spec_id)
84
+ if spec is None or spec.status != SpecStatus.APPROVED:
85
+ return False
86
+ spec.status = SpecStatus.IN_PROGRESS
87
+ return True
88
+
89
+ def complete(self, spec_id: str) -> bool:
90
+ """Mark spec as completed."""
91
+ spec = self._specs.get(spec_id)
92
+ if spec is None or spec.status != SpecStatus.IN_PROGRESS:
93
+ return False
94
+ spec.status = SpecStatus.COMPLETED
95
+ return True
96
+
97
+ def list_all(self, status: Optional[SpecStatus] = None) -> list[Spec]:
98
+ """List all specs, optionally filtered by status."""
99
+ if status:
100
+ return [s for s in self._specs.values() if s.status == status]
101
+ return list(self._specs.values())
102
+
103
+ def save_to_yaml(self, spec_id: str, path: str | Path) -> bool:
104
+ """Save a spec to a YAML file."""
105
+ spec = self._specs.get(spec_id)
106
+ if spec is None:
107
+ return False
108
+ path = Path(path)
109
+ path.parent.mkdir(parents=True, exist_ok=True)
110
+ data = spec.model_dump(mode="json")
111
+ with open(path, "w") as f:
112
+ yaml.dump(data, f, default_flow_style=False, allow_unicode=True, sort_keys=False)
113
+ return True
114
+
115
+ def load_from_yaml(self, path: str | Path) -> Spec:
116
+ """Load a spec from a YAML file."""
117
+ path = Path(path)
118
+ if not path.exists():
119
+ raise FileNotFoundError(f"Spec file not found: {path}")
120
+ with open(path) as f:
121
+ data = yaml.safe_load(f)
122
+ spec = Spec.model_validate(data)
123
+ self._specs[spec.id] = spec
124
+ return spec
125
+
126
+ def extract_patterns(self, spec_id: str) -> list[str]:
127
+ """Extract reusable patterns from a completed spec.
128
+
129
+ Patterns are sections or approaches that worked well and
130
+ can be reused in future specs.
131
+ """
132
+ spec = self._specs.get(spec_id)
133
+ if spec is None or spec.status != SpecStatus.COMPLETED:
134
+ return []
135
+
136
+ patterns = []
137
+ for section in spec.sections:
138
+ if section.status == SectionStatus.IMPLEMENTED and not section.implementation_notes:
139
+ patterns.append(f"[{spec.metadata.department}] {section.title}: {section.content[:100]}")
140
+ elif section.status == SectionStatus.MODIFIED:
141
+ delta = next((d for d in spec.deltas if d.section_id == section.id), None)
142
+ if delta:
143
+ patterns.append(
144
+ f"[{spec.metadata.department}] {section.title}: "
145
+ f"Originally '{delta.original[:50]}', changed to '{delta.actual[:50]}' "
146
+ f"because: {delta.reason[:50]}"
147
+ )
148
+
149
+ spec.patterns = patterns
150
+ return patterns
151
+
152
+ @property
153
+ def total_specs(self) -> int:
154
+ return len(self._specs)
155
+
156
+ def summary(self) -> dict:
157
+ """Summary of all specs."""
158
+ by_status = {}
159
+ for spec in self._specs.values():
160
+ by_status[spec.status.value] = by_status.get(spec.status.value, 0) + 1
161
+ return {
162
+ "total": self.total_specs,
163
+ "by_status": by_status,
164
+ }