agent-toolkit-cli 1.11.0__py3-none-win_amd64.whl

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 (438) hide show
  1. agent_toolkit/__init__.py +4 -0
  2. agent_toolkit/__main__.py +5 -0
  3. agent_toolkit/_paths.py +145 -0
  4. agent_toolkit/bin/.gitkeep +0 -0
  5. agent_toolkit/bin/agent-toolkit.exe +0 -0
  6. agent_toolkit/cli/__init__.py +0 -0
  7. agent_toolkit/cli/__main__.py +5 -0
  8. agent_toolkit/cli/build.py +278 -0
  9. agent_toolkit/cli/completion.py +297 -0
  10. agent_toolkit/cli/context_budget.py +455 -0
  11. agent_toolkit/cli/devcompanion.py +923 -0
  12. agent_toolkit/cli/devcompanion_queue.py +235 -0
  13. agent_toolkit/cli/diff.py +176 -0
  14. agent_toolkit/cli/doctor.py +1052 -0
  15. agent_toolkit/cli/insights.py +771 -0
  16. agent_toolkit/cli/install.py +706 -0
  17. agent_toolkit/cli/main.py +171 -0
  18. agent_toolkit/cli/mcp.py +537 -0
  19. agent_toolkit/cli/memory.py +739 -0
  20. agent_toolkit/cli/plugin.py +224 -0
  21. agent_toolkit/cli/project.py +459 -0
  22. agent_toolkit/cli/release.py +178 -0
  23. agent_toolkit/cli/skills.py +461 -0
  24. agent_toolkit/cli/uninstall.py +166 -0
  25. agent_toolkit/cli/update.py +298 -0
  26. agent_toolkit/cli/workspace.py +1713 -0
  27. agent_toolkit/compiler/hook_registry.py +110 -0
  28. agent_toolkit/compiler/loader.py +338 -0
  29. agent_toolkit/compiler/mcp_registry.py +87 -0
  30. agent_toolkit/compiler/model.py +182 -0
  31. agent_toolkit/compiler/provenance.py +140 -0
  32. agent_toolkit/compiler/registry_emit.py +263 -0
  33. agent_toolkit/compiler/target_registry.py +122 -0
  34. agent_toolkit/compiler/targets/__init__.py +1 -0
  35. agent_toolkit/compiler/targets/agent_plugins.py +160 -0
  36. agent_toolkit/compiler/targets/base.py +229 -0
  37. agent_toolkit/compiler/targets/claude_code.py +241 -0
  38. agent_toolkit/compiler/targets/codex.py +261 -0
  39. agent_toolkit/compiler/targets/copilot.py +275 -0
  40. agent_toolkit/compiler/targets/cursor.py +207 -0
  41. agent_toolkit/compiler/targets/gemini_cli.py +213 -0
  42. agent_toolkit/compiler/targets/muse_code.py +113 -0
  43. agent_toolkit/compiler/targets/opencode.py +204 -0
  44. agent_toolkit/compiler/targets/pi.py +263 -0
  45. agent_toolkit/compiler/targets/windsurf.py +267 -0
  46. agent_toolkit/compiler/tool_mapping.py +83 -0
  47. agent_toolkit/data/.gitignore +4 -0
  48. agent_toolkit/data/__init__.py +1 -0
  49. agent_toolkit/data/agents/agentic-security-reviewer/AGENT.md +60 -0
  50. agent_toolkit/data/agents/architect/AGENT.md +30 -0
  51. agent_toolkit/data/agents/assistant/AGENT.md +59 -0
  52. agent_toolkit/data/agents/build-error-resolver/AGENT.md +30 -0
  53. agent_toolkit/data/agents/client-workflow-bootstrap/AGENT.md +60 -0
  54. agent_toolkit/data/agents/code-reviewer/AGENT.md +49 -0
  55. agent_toolkit/data/agents/database-reviewer/AGENT.md +44 -0
  56. agent_toolkit/data/agents/docs-lookup/AGENT.md +28 -0
  57. agent_toolkit/data/agents/e2e-runner/AGENT.md +38 -0
  58. agent_toolkit/data/agents/performance-optimizer/AGENT.md +52 -0
  59. agent_toolkit/data/agents/planner/AGENT.md +41 -0
  60. agent_toolkit/data/agents/refactor-cleaner/AGENT.md +43 -0
  61. agent_toolkit/data/agents/reference-lookup/AGENT.md +33 -0
  62. agent_toolkit/data/agents/security-reviewer/AGENT.md +47 -0
  63. agent_toolkit/data/agents/tdd-guide/AGENT.md +58 -0
  64. agent_toolkit/data/agents/tech-assistant/AGENT.md +11 -0
  65. agent_toolkit/data/agents/typescript-reviewer/AGENT.md +61 -0
  66. agent_toolkit/data/capabilities/hooks/README.md +6 -0
  67. agent_toolkit/data/capabilities/hooks/pre-commit-validate.yaml +26 -0
  68. agent_toolkit/data/capabilities/hooks/scripts/pre-commit-validate.sh +41 -0
  69. agent_toolkit/data/capabilities/hooks/scripts/session-start-context.sh +11 -0
  70. agent_toolkit/data/capabilities/hooks/session-start-context.yaml +23 -0
  71. agent_toolkit/data/capabilities/targets/registry.yaml +90 -0
  72. agent_toolkit/data/capabilities/upstream.lock +118 -0
  73. agent_toolkit/data/catalogs/agent-catalog.yaml +81 -0
  74. agent_toolkit/data/catalogs/loop-catalog.yaml +55 -0
  75. agent_toolkit/data/catalogs/skill-catalog.yaml +520 -0
  76. agent_toolkit/data/catalogs/skills-layout.json +391 -0
  77. agent_toolkit/data/distributions/products.yaml +190 -0
  78. agent_toolkit/data/distributions/targets/claude-code.yaml +47 -0
  79. agent_toolkit/data/distributions/targets/cursor.yaml +42 -0
  80. agent_toolkit/data/distributions/targets/opencode.yaml +55 -0
  81. agent_toolkit/data/loops/changelog-drafter/loop.yaml +40 -0
  82. agent_toolkit/data/loops/ci-sweeper/loop.yaml +53 -0
  83. agent_toolkit/data/loops/daily-triage/loop.yaml +47 -0
  84. agent_toolkit/data/loops/dep-sweeper/loop.yaml +46 -0
  85. agent_toolkit/data/loops/issue-triage/loop.yaml +40 -0
  86. agent_toolkit/data/loops/oss-daily-briefing/loop.yaml +65 -0
  87. agent_toolkit/data/loops/oss-pr-monitor/loop.yaml +86 -0
  88. agent_toolkit/data/loops/oss-triage/loop.yaml +67 -0
  89. agent_toolkit/data/loops/post-merge-cleanup/loop.yaml +44 -0
  90. agent_toolkit/data/loops/pr-babysitter/loop.yaml +46 -0
  91. agent_toolkit/data/mcp/registry/chrome-devtools.yaml +61 -0
  92. agent_toolkit/data/mcp/registry/clickup.yaml +48 -0
  93. agent_toolkit/data/mcp/registry/figma.yaml +44 -0
  94. agent_toolkit/data/mcp/registry/github.yaml +52 -0
  95. agent_toolkit/data/mcp/registry/linear.yaml +47 -0
  96. agent_toolkit/data/mcp/registry/notion.yaml +48 -0
  97. agent_toolkit/data/mcp/registry/slack.yaml +46 -0
  98. agent_toolkit/data/mcp/templates/chrome-devtools/README.md +57 -0
  99. agent_toolkit/data/mcp/templates/chrome-devtools/config.template.json +6 -0
  100. agent_toolkit/data/mcp/templates/clickup/README.md +45 -0
  101. agent_toolkit/data/mcp/templates/clickup/config.template.json +8 -0
  102. agent_toolkit/data/mcp/templates/clickup/wrapper.sh +23 -0
  103. agent_toolkit/data/mcp/templates/figma/README.md +54 -0
  104. agent_toolkit/data/mcp/templates/figma/config.template.json +9 -0
  105. agent_toolkit/data/mcp/templates/github/README.md +16 -0
  106. agent_toolkit/data/mcp/templates/github/config.template.json +15 -0
  107. agent_toolkit/data/mcp/templates/github/wrapper.sh +6 -0
  108. agent_toolkit/data/mcp/templates/linear/README.md +49 -0
  109. agent_toolkit/data/mcp/templates/linear/config.template.json +10 -0
  110. agent_toolkit/data/mcp/templates/notion/README.md +7 -0
  111. agent_toolkit/data/mcp/templates/notion/config.template.json +8 -0
  112. agent_toolkit/data/mcp/templates/notion/wrapper.sh +23 -0
  113. agent_toolkit/data/mcp/templates/slack/README.md +8 -0
  114. agent_toolkit/data/mcp/templates/slack/config.template.json +9 -0
  115. agent_toolkit/data/mcp/templates/slack/wrapper.sh +23 -0
  116. agent_toolkit/data/packs/README.md +66 -0
  117. agent_toolkit/data/packs/agentic-security/README.md +19 -0
  118. agent_toolkit/data/packs/agentic-security/config.yaml +25 -0
  119. agent_toolkit/data/packs/architecture/README.md +22 -0
  120. agent_toolkit/data/packs/architecture/config.yaml +27 -0
  121. agent_toolkit/data/packs/code-quality/README.md +19 -0
  122. agent_toolkit/data/packs/code-quality/config.yaml +21 -0
  123. agent_toolkit/data/packs/delivery-discipline/README.md +19 -0
  124. agent_toolkit/data/packs/delivery-discipline/config.yaml +42 -0
  125. agent_toolkit/data/packs/design-engineering/README.md +19 -0
  126. agent_toolkit/data/packs/design-engineering/config.yaml +41 -0
  127. agent_toolkit/data/packs/engineering-workflow/README.md +21 -0
  128. agent_toolkit/data/packs/engineering-workflow/config.yaml +57 -0
  129. agent_toolkit/data/packs/oss-maintenance/README.md +245 -0
  130. agent_toolkit/data/packs/oss-maintenance/config.yaml +75 -0
  131. agent_toolkit/data/profiles/claude-code/CLAUDE.md +110 -0
  132. agent_toolkit/data/profiles/claude-code/agents/assistant.md +59 -0
  133. agent_toolkit/data/profiles/claude-code/agents/build-error-resolver.md +30 -0
  134. agent_toolkit/data/profiles/claude-code/agents/client-workflow-bootstrap.md +60 -0
  135. agent_toolkit/data/profiles/claude-code/agents/contribution-planner.md +39 -0
  136. agent_toolkit/data/profiles/claude-code/agents/database-reviewer.md +44 -0
  137. agent_toolkit/data/profiles/claude-code/agents/docs-lookup.md +28 -0
  138. agent_toolkit/data/profiles/claude-code/agents/e2e-runner.md +38 -0
  139. agent_toolkit/data/profiles/claude-code/agents/performance-optimizer.md +52 -0
  140. agent_toolkit/data/profiles/claude-code/agents/planner.md +41 -0
  141. agent_toolkit/data/profiles/claude-code/agents/refactor-cleaner.md +43 -0
  142. agent_toolkit/data/profiles/claude-code/agents/reference-lookup.md +33 -0
  143. agent_toolkit/data/profiles/claude-code/agents/security-reviewer.md +47 -0
  144. agent_toolkit/data/profiles/claude-code/agents/tdd-guide.md +58 -0
  145. agent_toolkit/data/profiles/claude-code/agents/typescript-reviewer.md +61 -0
  146. agent_toolkit/data/profiles/claude-code/settings.json +86 -0
  147. agent_toolkit/data/profiles/copilot/copilot-instructions.md +15 -0
  148. agent_toolkit/data/profiles/cursor/README.md +33 -0
  149. agent_toolkit/data/profiles/cursor/rules/architect.mdc +23 -0
  150. agent_toolkit/data/profiles/cursor/rules/assistant.mdc +61 -0
  151. agent_toolkit/data/profiles/cursor/rules/build-error-resolver.mdc +20 -0
  152. agent_toolkit/data/profiles/cursor/rules/code-reviewer.mdc +21 -0
  153. agent_toolkit/data/profiles/cursor/rules/database-reviewer.mdc +29 -0
  154. agent_toolkit/data/profiles/cursor/rules/docs-lookup.mdc +15 -0
  155. agent_toolkit/data/profiles/cursor/rules/e2e-runner.mdc +30 -0
  156. agent_toolkit/data/profiles/cursor/rules/performance-optimizer.mdc +27 -0
  157. agent_toolkit/data/profiles/cursor/rules/planner.mdc +28 -0
  158. agent_toolkit/data/profiles/cursor/rules/refactor-cleaner.mdc +26 -0
  159. agent_toolkit/data/profiles/cursor/rules/reference-lookup.mdc +20 -0
  160. agent_toolkit/data/profiles/cursor/rules/security-reviewer.mdc +20 -0
  161. agent_toolkit/data/profiles/cursor/rules/tdd-guide.mdc +26 -0
  162. agent_toolkit/data/profiles/cursor/rules/typescript-reviewer.mdc +28 -0
  163. agent_toolkit/data/profiles/muse-code/README.md +35 -0
  164. agent_toolkit/data/profiles/opencode/README.md +44 -0
  165. agent_toolkit/data/profiles/opencode/agents/architect.md +30 -0
  166. agent_toolkit/data/profiles/opencode/agents/assistant.md +96 -0
  167. agent_toolkit/data/profiles/opencode/agents/build-error-resolver.md +31 -0
  168. agent_toolkit/data/profiles/opencode/agents/client-workflow-bootstrap.md +66 -0
  169. agent_toolkit/data/profiles/opencode/agents/code-reviewer.md +47 -0
  170. agent_toolkit/data/profiles/opencode/agents/contribution-planner.md +44 -0
  171. agent_toolkit/data/profiles/opencode/agents/database-reviewer.md +43 -0
  172. agent_toolkit/data/profiles/opencode/agents/docs-lookup.md +28 -0
  173. agent_toolkit/data/profiles/opencode/agents/e2e-runner.md +33 -0
  174. agent_toolkit/data/profiles/opencode/agents/performance-optimizer.md +34 -0
  175. agent_toolkit/data/profiles/opencode/agents/planner.md +27 -0
  176. agent_toolkit/data/profiles/opencode/agents/refactor-cleaner.md +27 -0
  177. agent_toolkit/data/profiles/opencode/agents/reference-lookup.md +27 -0
  178. agent_toolkit/data/profiles/opencode/agents/security-reviewer.md +27 -0
  179. agent_toolkit/data/profiles/opencode/agents/tdd-guide.md +27 -0
  180. agent_toolkit/data/profiles/opencode/agents/typescript-reviewer.md +30 -0
  181. agent_toolkit/data/profiles/opencode/opencode.json +3 -0
  182. agent_toolkit/data/profiles/pi/skills/architect/skill.md +5 -0
  183. agent_toolkit/data/profiles/pi/skills/assistant/skill.md +3 -0
  184. agent_toolkit/data/profiles/pi/skills/code-reviewer/skill.md +5 -0
  185. agent_toolkit/data/profiles/pi/skills/planner/skill.md +3 -0
  186. agent_toolkit/data/profiles/pi/skills/security-reviewer/skill.md +3 -0
  187. agent_toolkit/data/profiles/windsurf/memories/global_rules.md +114 -0
  188. agent_toolkit/data/profiles/windsurf/rules/architect.mdc +23 -0
  189. agent_toolkit/data/profiles/windsurf/rules/assistant.mdc +61 -0
  190. agent_toolkit/data/profiles/windsurf/rules/build-error-resolver.mdc +20 -0
  191. agent_toolkit/data/profiles/windsurf/rules/code-reviewer.mdc +21 -0
  192. agent_toolkit/data/profiles/windsurf/rules/database-reviewer.mdc +29 -0
  193. agent_toolkit/data/profiles/windsurf/rules/docs-lookup.mdc +15 -0
  194. agent_toolkit/data/profiles/windsurf/rules/e2e-runner.mdc +30 -0
  195. agent_toolkit/data/profiles/windsurf/rules/performance-optimizer.mdc +27 -0
  196. agent_toolkit/data/profiles/windsurf/rules/planner.mdc +28 -0
  197. agent_toolkit/data/profiles/windsurf/rules/refactor-cleaner.mdc +26 -0
  198. agent_toolkit/data/profiles/windsurf/rules/reference-lookup.mdc +20 -0
  199. agent_toolkit/data/profiles/windsurf/rules/security-reviewer.mdc +20 -0
  200. agent_toolkit/data/profiles/windsurf/rules/tdd-guide.mdc +26 -0
  201. agent_toolkit/data/profiles/windsurf/rules/typescript-reviewer.mdc +28 -0
  202. agent_toolkit/data/skills/accessibility/review/SKILL.md +116 -0
  203. agent_toolkit/data/skills/accessibility/review/references/a11y-checklist.md +25 -0
  204. agent_toolkit/data/skills/accessibility/review/references/a11y-findings-template.md +56 -0
  205. agent_toolkit/data/skills/accessibility/review/references/research.md +47 -0
  206. agent_toolkit/data/skills/agentic-security/mcp-audit/SKILL.md +116 -0
  207. agent_toolkit/data/skills/agentic-security/mcp-audit/references/mcp-audit-template.md +51 -0
  208. agent_toolkit/data/skills/agentic-security/owasp-agentic-review/SKILL.md +73 -0
  209. agent_toolkit/data/skills/agentic-security/owasp-agentic-review/references/owasp-agentic-template.md +32 -0
  210. agent_toolkit/data/skills/agentic-security/supply-chain-audit/SKILL.md +142 -0
  211. agent_toolkit/data/skills/agentic-security/threat-modeling/SKILL.md +100 -0
  212. agent_toolkit/data/skills/agentic-security/threat-modeling/references/threat-model-template.md +55 -0
  213. agent_toolkit/data/skills/architecture/c4-model/SKILL.md +49 -0
  214. agent_toolkit/data/skills/cloud/aws-well-architected-review/SKILL.md +37 -0
  215. agent_toolkit/data/skills/cloud/cloud-design-patterns/SKILL.md +38 -0
  216. agent_toolkit/data/skills/core/assistant/SKILL.md +216 -0
  217. agent_toolkit/data/skills/core/assistant/references/AGENTS_TEMPLATE.md +0 -0
  218. agent_toolkit/data/skills/core/assistant/references/ORCHESTRATION.md +0 -0
  219. agent_toolkit/data/skills/core/assistant/references/REPO_INSPECTION.md +0 -0
  220. agent_toolkit/data/skills/core/dev-companion/SKILL.md +65 -0
  221. agent_toolkit/data/skills/core/dev-companion/references/LOOP_GUARDRAILS.md +0 -0
  222. agent_toolkit/data/skills/core/onboarding/SKILL.md +122 -0
  223. agent_toolkit/data/skills/core/output-handshake/SKILL.md +26 -0
  224. agent_toolkit/data/skills/core/pr-fallback/SKILL.md +35 -0
  225. agent_toolkit/data/skills/core/pr-fallback/references/pr-body-default.md +0 -0
  226. agent_toolkit/data/skills/core/project/SKILL.md +89 -0
  227. agent_toolkit/data/skills/core/workspace/SKILL.md +103 -0
  228. agent_toolkit/data/skills/core/workspace-knowledge-sync/SKILL.md +140 -0
  229. agent_toolkit/data/skills/data/dbt-validation/SKILL.md +41 -0
  230. agent_toolkit/data/skills/data/snowflake-validation/SKILL.md +38 -0
  231. agent_toolkit/data/skills/delivery/adr/SKILL.md +56 -0
  232. agent_toolkit/data/skills/delivery/adr/references/default-template.md +35 -0
  233. agent_toolkit/data/skills/delivery/adr/references/example-001-graphql-adoption.md +66 -0
  234. agent_toolkit/data/skills/delivery/agreement/SKILL.md +24 -0
  235. agent_toolkit/data/skills/delivery/agreement/references/default-template.md +17 -0
  236. agent_toolkit/data/skills/delivery/agreement/references/example-api-versioning.md +29 -0
  237. agent_toolkit/data/skills/delivery/bug/SKILL.md +26 -0
  238. agent_toolkit/data/skills/delivery/bug/references/default-template.md +26 -0
  239. agent_toolkit/data/skills/delivery/bug/references/example-search-filter-bug.md +58 -0
  240. agent_toolkit/data/skills/delivery/decision-log/SKILL.md +28 -0
  241. agent_toolkit/data/skills/delivery/decision-log/references/default-template.md +17 -0
  242. agent_toolkit/data/skills/delivery/decision-log/references/example-repository-pattern.md +27 -0
  243. agent_toolkit/data/skills/delivery/development-workflow/SKILL.md +34 -0
  244. agent_toolkit/data/skills/delivery/development-workflow/references/default-workflow-checklist.md +44 -0
  245. agent_toolkit/data/skills/delivery/epic/SKILL.md +22 -0
  246. agent_toolkit/data/skills/delivery/epic/references/default-template.md +26 -0
  247. agent_toolkit/data/skills/delivery/epic/references/example-unified-dashboard.md +40 -0
  248. agent_toolkit/data/skills/delivery/incident/SKILL.md +24 -0
  249. agent_toolkit/data/skills/delivery/incident/references/default-template.md +29 -0
  250. agent_toolkit/data/skills/delivery/incident/references/example-payment-outage.md +62 -0
  251. agent_toolkit/data/skills/delivery/management-unit-assessment/SKILL.md +104 -0
  252. agent_toolkit/data/skills/delivery/management-unit-assessment/references/default-template.md +24 -0
  253. agent_toolkit/data/skills/delivery/management-unit-assessment/references/example-team-assessment.md +126 -0
  254. agent_toolkit/data/skills/delivery/meeting-minutes/SKILL.md +25 -0
  255. agent_toolkit/data/skills/delivery/meeting-minutes/references/default-template.md +22 -0
  256. agent_toolkit/data/skills/delivery/meeting-minutes/references/example-weekly-sync.md +72 -0
  257. agent_toolkit/data/skills/delivery/planning/SKILL.md +31 -0
  258. agent_toolkit/data/skills/delivery/planning/references/default-template.md +25 -0
  259. agent_toolkit/data/skills/delivery/planning/references/example-sprint-planning.md +62 -0
  260. agent_toolkit/data/skills/delivery/prd/SKILL.md +46 -0
  261. agent_toolkit/data/skills/delivery/prd/references/default-template.md +31 -0
  262. agent_toolkit/data/skills/delivery/prd/references/example-unified-api.md +71 -0
  263. agent_toolkit/data/skills/delivery/project-assessment/SKILL.md +90 -0
  264. agent_toolkit/data/skills/delivery/project-assessment/references/default-template.md +26 -0
  265. agent_toolkit/data/skills/delivery/project-assessment/references/example-platform-assessment.md +122 -0
  266. agent_toolkit/data/skills/delivery/project-assessment-evidence/SKILL.md +88 -0
  267. agent_toolkit/data/skills/delivery/project-assessment-evidence/references/default-template.md +24 -0
  268. agent_toolkit/data/skills/delivery/project-assessment-evidence/references/example-evidence-map.md +46 -0
  269. agent_toolkit/data/skills/delivery/spike/SKILL.md +24 -0
  270. agent_toolkit/data/skills/delivery/spike/references/default-template.md +29 -0
  271. agent_toolkit/data/skills/delivery/spike/references/example-graphql-federation.md +79 -0
  272. agent_toolkit/data/skills/delivery/task/SKILL.md +21 -0
  273. agent_toolkit/data/skills/delivery/task/references/default-template.md +21 -0
  274. agent_toolkit/data/skills/delivery/task/references/example-nav-system.md +33 -0
  275. agent_toolkit/data/skills/delivery/technical-unit-assessment/SKILL.md +58 -0
  276. agent_toolkit/data/skills/delivery/technical-unit-assessment/references/default-template.md +26 -0
  277. agent_toolkit/data/skills/delivery/technical-unit-assessment/references/example-frontend-assessment.md +112 -0
  278. agent_toolkit/data/skills/delivery/technical-unit-assessment/references/indicator-groups.md +65 -0
  279. agent_toolkit/data/skills/delivery/trd/SKILL.md +49 -0
  280. agent_toolkit/data/skills/delivery/trd/references/default-template.md +31 -0
  281. agent_toolkit/data/skills/delivery/trd/references/example-api-migration.md +122 -0
  282. agent_toolkit/data/skills/delivery/user-story/SKILL.md +21 -0
  283. agent_toolkit/data/skills/delivery/user-story/references/default-template.md +21 -0
  284. agent_toolkit/data/skills/delivery/user-story/references/example-advanced-filtering.md +37 -0
  285. agent_toolkit/data/skills/delivery/work-item/SKILL.md +31 -0
  286. agent_toolkit/data/skills/delivery/work-item/references/default-template.md +21 -0
  287. agent_toolkit/data/skills/delivery/work-item/references/example-routing-dashboard.md +23 -0
  288. agent_toolkit/data/skills/delivery/workflow-client-bootstrap/SKILL.md +148 -0
  289. agent_toolkit/data/skills/delivery/workflow-client-bootstrap/questions.yaml +165 -0
  290. agent_toolkit/data/skills/delivery/workflow-generic-project/SKILL.md +79 -0
  291. agent_toolkit/data/skills/design/design-assessment/SKILL.md +150 -0
  292. agent_toolkit/data/skills/design/design-assessment/references/design-scorecard-template.md +78 -0
  293. agent_toolkit/data/skills/design/design-improvement/SKILL.md +167 -0
  294. agent_toolkit/data/skills/design/design-improvement/references/improvement-plan-template.md +113 -0
  295. agent_toolkit/data/skills/design/figma/LICENSE.txt +2 -0
  296. agent_toolkit/data/skills/design/figma/NOTICE.txt +25 -0
  297. agent_toolkit/data/skills/design/figma/SKILL.md +98 -0
  298. agent_toolkit/data/skills/design/figma/references/figma-mcp-config.md +82 -0
  299. agent_toolkit/data/skills/design/figma/references/figma-tools-and-prompts.md +34 -0
  300. agent_toolkit/data/skills/design/figma-code-connect-components/LICENSE.txt +2 -0
  301. agent_toolkit/data/skills/design/figma-code-connect-components/NOTICE.txt +18 -0
  302. agent_toolkit/data/skills/design/figma-code-connect-components/SKILL.md +354 -0
  303. agent_toolkit/data/skills/design/figma-code-connect-components/references/mapping-checklist.md +7 -0
  304. agent_toolkit/data/skills/design/figma-code-connect-components/scripts/normalize_node_id.py +25 -0
  305. agent_toolkit/data/skills/design/figma-create-design-system-rules/LICENSE.txt +2 -0
  306. agent_toolkit/data/skills/design/figma-create-design-system-rules/NOTICE.txt +19 -0
  307. agent_toolkit/data/skills/design/figma-create-design-system-rules/SKILL.md +554 -0
  308. agent_toolkit/data/skills/design/figma-create-design-system-rules/references/rule-template.md +15 -0
  309. agent_toolkit/data/skills/design/figma-create-design-system-rules/scripts/check_agents_md.sh +9 -0
  310. agent_toolkit/data/skills/design/figma-create-new-file/LICENSE.txt +2 -0
  311. agent_toolkit/data/skills/design/figma-create-new-file/NOTICE.txt +17 -0
  312. agent_toolkit/data/skills/design/figma-create-new-file/SKILL.md +72 -0
  313. agent_toolkit/data/skills/design/figma-implement-design/LICENSE.txt +2 -0
  314. agent_toolkit/data/skills/design/figma-implement-design/NOTICE.txt +19 -0
  315. agent_toolkit/data/skills/design/figma-implement-design/SKILL.md +268 -0
  316. agent_toolkit/data/skills/design/frontend-design/LICENSE.txt +177 -0
  317. agent_toolkit/data/skills/design/frontend-design/SKILL.md +82 -0
  318. agent_toolkit/data/skills/design/frontend-design/UPSTREAM.md +14 -0
  319. agent_toolkit/data/skills/design/frontend-design-review/LICENSE +21 -0
  320. agent_toolkit/data/skills/design/frontend-design-review/SKILL.md +194 -0
  321. agent_toolkit/data/skills/design/frontend-design-review/references/pattern-examples.md +21 -0
  322. agent_toolkit/data/skills/design/frontend-design-review/references/quick-checklist.md +38 -0
  323. agent_toolkit/data/skills/design/frontend-design-review/references/review-output-format.md +68 -0
  324. agent_toolkit/data/skills/design/frontend-design-review/references/review-type-modifiers.md +31 -0
  325. agent_toolkit/data/skills/design/web-design-guidelines/SKILL.md +78 -0
  326. agent_toolkit/data/skills/design/web-design-guidelines/references/LICENSE +21 -0
  327. agent_toolkit/data/skills/design/web-design-guidelines/references/web-interface-guidelines.md +180 -0
  328. agent_toolkit/data/skills/forge/gh-address-comments/LICENSE.txt +202 -0
  329. agent_toolkit/data/skills/forge/gh-address-comments/NOTICE.txt +20 -0
  330. agent_toolkit/data/skills/forge/gh-address-comments/SKILL.md +72 -0
  331. agent_toolkit/data/skills/forge/gh-address-comments/scripts/fetch_comments.py +239 -0
  332. agent_toolkit/data/skills/forge/gh-contribution-planner/SKILL.md +160 -0
  333. agent_toolkit/data/skills/forge/gh-contribution-planner/scripts/inspect_contributions.py +818 -0
  334. agent_toolkit/data/skills/forge/gh-fix-ci/LICENSE.txt +201 -0
  335. agent_toolkit/data/skills/forge/gh-fix-ci/NOTICE.txt +20 -0
  336. agent_toolkit/data/skills/forge/gh-fix-ci/SKILL.md +74 -0
  337. agent_toolkit/data/skills/forge/gh-fix-ci/scripts/inspect_pr_checks.py +509 -0
  338. agent_toolkit/data/skills/forge/github-cli-workflow/SKILL.md +49 -0
  339. agent_toolkit/data/skills/forge/gitlab-cli-workflow/SKILL.md +44 -0
  340. agent_toolkit/data/skills/forge/workflow-client-bootstrap/SKILL.md +14 -0
  341. agent_toolkit/data/skills/forge/workflow-generic-project/SKILL.md +14 -0
  342. agent_toolkit/data/skills/forge/worktree/SKILL.md +113 -0
  343. agent_toolkit/data/skills/integrations/clickup-cli/SKILL.md +78 -0
  344. agent_toolkit/data/skills/integrations/clickup-cli/references/docs-management.md +57 -0
  345. agent_toolkit/data/skills/integrations/clickup-cli/references/task-management.md +131 -0
  346. agent_toolkit/data/skills/integrations/clickup-cli/references/time-tracking.md +38 -0
  347. agent_toolkit/data/skills/integrations/linear/LICENSE.txt +202 -0
  348. agent_toolkit/data/skills/integrations/linear/NOTICE.txt +23 -0
  349. agent_toolkit/data/skills/integrations/linear/SKILL.md +134 -0
  350. agent_toolkit/data/skills/integrations/mcp/SKILL.md +88 -0
  351. agent_toolkit/data/skills/integrations/slack-assistant/SKILL.md +138 -0
  352. agent_toolkit/data/skills/integrations/slack-cli/SKILL.md +109 -0
  353. agent_toolkit/data/skills/integrations/slack-cli/references/INSTALLATION.md +42 -0
  354. agent_toolkit/data/skills/loops/loop-runner/SKILL.md +92 -0
  355. agent_toolkit/data/skills/ops/docs-generator/SKILL.md +120 -0
  356. agent_toolkit/data/skills/ops/llm-cost-advisor/SKILL.md +87 -0
  357. agent_toolkit/data/skills/ops/swarm/SKILL.md +108 -0
  358. agent_toolkit/data/skills/ops/swarm-handoff/SKILL.md +112 -0
  359. agent_toolkit/data/skills/ops/swarm-observer/SKILL.md +102 -0
  360. agent_toolkit/data/skills/ops/triage/SKILL.md +119 -0
  361. agent_toolkit/data/skills/quality/codeql/SKILL.md +106 -0
  362. agent_toolkit/data/skills/quality/codeql/references/codeql-queries.md +43 -0
  363. agent_toolkit/data/skills/quality/megalinter/SKILL.md +162 -0
  364. agent_toolkit/data/skills/quality/megalinter/references/megalinter-images.md +36 -0
  365. agent_toolkit/data/skills/quality/megalinter/references/megalinter-license.md +41 -0
  366. agent_toolkit/data/skills/quality/megalinter/references/megalinter-targets.md +66 -0
  367. agent_toolkit/data/skills/tooling/chrome-devtools/SKILL.md +146 -0
  368. agent_toolkit/data/skills/tooling/herdr/SKILL.md +109 -0
  369. agent_toolkit/data/skills/tooling/inventory/SKILL.md +81 -0
  370. agent_toolkit/data/skills/tooling/jupyter-notebook/LICENSE.txt +201 -0
  371. agent_toolkit/data/skills/tooling/jupyter-notebook/NOTICE.txt +27 -0
  372. agent_toolkit/data/skills/tooling/jupyter-notebook/SKILL.md +145 -0
  373. agent_toolkit/data/skills/tooling/jupyter-notebook/assets/experiment-template.ipynb +117 -0
  374. agent_toolkit/data/skills/tooling/jupyter-notebook/assets/tutorial-template.ipynb +115 -0
  375. agent_toolkit/data/skills/tooling/jupyter-notebook/references/experiment-patterns.md +10 -0
  376. agent_toolkit/data/skills/tooling/jupyter-notebook/references/notebook-structure.md +17 -0
  377. agent_toolkit/data/skills/tooling/jupyter-notebook/references/quality-checklist.md +11 -0
  378. agent_toolkit/data/skills/tooling/jupyter-notebook/references/tutorial-patterns.md +9 -0
  379. agent_toolkit/data/skills/tooling/jupyter-notebook/scripts/new_notebook.py +132 -0
  380. agent_toolkit/data/skills/tooling/mermaid/SKILL.md +36 -0
  381. agent_toolkit/data/skills/tooling/playwright-cli/LICENSE.txt +201 -0
  382. agent_toolkit/data/skills/tooling/playwright-cli/NOTICE.txt +29 -0
  383. agent_toolkit/data/skills/tooling/playwright-cli/SKILL.md +154 -0
  384. agent_toolkit/data/skills/tooling/playwright-cli/references/cli.md +116 -0
  385. agent_toolkit/data/skills/tooling/playwright-cli/references/workflows.md +98 -0
  386. agent_toolkit/data/skills/tooling/playwright-cli/scripts/executable_playwright_cli.sh +25 -0
  387. agent_toolkit/data_cache.py +79 -0
  388. agent_toolkit/data_sync.py +144 -0
  389. agent_toolkit/installer/__init__.py +0 -0
  390. agent_toolkit/installer/merge.py +59 -0
  391. agent_toolkit/installer/receipt.py +89 -0
  392. agent_toolkit/installer/sources.py +92 -0
  393. agent_toolkit/installer/tracking.py +63 -0
  394. agent_toolkit/launcher.py +69 -0
  395. agent_toolkit/loop/__init__.py +0 -0
  396. agent_toolkit/loop/budget.py +107 -0
  397. agent_toolkit/loop/gh_gate.py +923 -0
  398. agent_toolkit/loop/loop-gh-gate +923 -0
  399. agent_toolkit/loop/pack.py +65 -0
  400. agent_toolkit/loop/runner.py +2722 -0
  401. agent_toolkit/runner/__init__.py +0 -0
  402. agent_toolkit/runner/dispatcher.py +163 -0
  403. agent_toolkit/runner/policy.py +356 -0
  404. agent_toolkit/runner/providers/__init__.py +21 -0
  405. agent_toolkit/runner/providers/anthropic_provider.py +109 -0
  406. agent_toolkit/runner/providers/base.py +53 -0
  407. agent_toolkit/runner/providers/ollama_provider.py +108 -0
  408. agent_toolkit/runner/providers/openai_provider.py +103 -0
  409. agent_toolkit/runner/providers/opencode_provider.py +127 -0
  410. agent_toolkit/swarm/__init__.py +5 -0
  411. agent_toolkit/swarm/approvals.py +121 -0
  412. agent_toolkit/swarm/backends/__init__.py +596 -0
  413. agent_toolkit/swarm/budget.py +83 -0
  414. agent_toolkit/swarm/cli.py +2448 -0
  415. agent_toolkit/swarm/config.py +351 -0
  416. agent_toolkit/swarm/handoff.py +174 -0
  417. agent_toolkit/swarm/models.py +230 -0
  418. agent_toolkit/swarm/prompts.py +177 -0
  419. agent_toolkit/swarm/recipes.py +304 -0
  420. agent_toolkit/swarm/runner.py +267 -0
  421. agent_toolkit/swarm/state.py +93 -0
  422. agent_toolkit/swarm/store.py +148 -0
  423. agent_toolkit/swarm/worktree.py +105 -0
  424. agent_toolkit/templates/workspace/.gitignore +19 -0
  425. agent_toolkit/templates/workspace/AGENTS.md +82 -0
  426. agent_toolkit/templates/workspace/knowledge/README.md +22 -0
  427. agent_toolkit/templates/workspace/knowledge/learnings/general.md +3 -0
  428. agent_toolkit/templates/workspace/knowledge/todos/pending.md +7 -0
  429. agent_toolkit/templates/workspace/packs/README.md +24 -0
  430. agent_toolkit/templates/workspace/personas/architect.md +12 -0
  431. agent_toolkit/templates/workspace/personas/implementer.md +12 -0
  432. agent_toolkit/templates/workspace/personas/researcher.md +12 -0
  433. agent_toolkit/templates/workspace/personas/reviewer.md +12 -0
  434. agent_toolkit_cli-1.11.0.dist-info/METADATA +363 -0
  435. agent_toolkit_cli-1.11.0.dist-info/RECORD +438 -0
  436. agent_toolkit_cli-1.11.0.dist-info/WHEEL +4 -0
  437. agent_toolkit_cli-1.11.0.dist-info/entry_points.txt +4 -0
  438. agent_toolkit_cli-1.11.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,351 @@
1
+ """Swarm config — precedence CLI > project > workspace > user > defaults."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ from pathlib import Path
7
+ from typing import Any
8
+
9
+ MODEL_PROFILE_NAMES = ("economy", "balanced", "quality", "private")
10
+ TASK_CLASSES = ("planning", "coding", "review", "architecture", "hardening", "qa")
11
+
12
+
13
+ # Aliases for prompt autodetect (short names -> OWNER/REPO)
14
+ _PROMPT_ALIASES: dict[str, str] = {
15
+ "create-node-app": "Create-Node-App/create-node-app",
16
+ "cna-templates": "Create-Node-App/cna-templates",
17
+ "create-awesome-node-app": "Create-Node-App/create-node-app",
18
+ }
19
+
20
+
21
+ def _candidate_repo_paths(owner_repo: str) -> list[Path]:
22
+ owner, repo = owner_repo.split("/", 1)
23
+ candidates: list[Path] = []
24
+ ws = Path.home() / ".ai-workspace"
25
+ candidates.append(ws / "repos" / "github.com" / owner / repo)
26
+ candidates.append(ws / "repos" / owner / repo)
27
+ try:
28
+ cwd_ws = Path.cwd().resolve()
29
+ for parent in [cwd_ws] + list(cwd_ws.parents):
30
+ if (parent / "repos").is_dir() and parent.name == ".ai-workspace":
31
+ candidates.append(parent / "repos" / "github.com" / owner / repo)
32
+ candidates.append(parent / "repos" / owner / repo)
33
+ break
34
+ except Exception:
35
+ pass
36
+ candidates.append(Path.home() / ".ai-workspace" / "repos" / "github.com" / owner / repo)
37
+ candidates.append(Path.cwd() / repo)
38
+ return candidates
39
+
40
+
41
+ def _resolve_owner_repo_from_prompt(prompt: str | None) -> str | None:
42
+ if not prompt:
43
+ return None
44
+ import re
45
+
46
+ m = re.search(r"https?://github\.com/([A-Za-z0-9_.-]+)/([A-Za-z0-9_.-]+)", prompt)
47
+ if m:
48
+ return f"{m.group(1)}/{m.group(2)}"
49
+ m = re.search(r"\b([A-Za-z0-9_.-]+)/([A-Za-z0-9_.-]+)(?:#\d+)?\b", prompt)
50
+ if m:
51
+ candidate = f"{m.group(1)}/{m.group(2)}"
52
+ if "/" in candidate and not candidate.lower().startswith("error"):
53
+ for cand in _candidate_repo_paths(candidate):
54
+ if (cand / ".git").exists():
55
+ return candidate
56
+ if candidate.startswith("Create-Node-App/"):
57
+ return candidate
58
+ pass
59
+ low = prompt.lower()
60
+ for alias, owner_repo in _PROMPT_ALIASES.items():
61
+ if alias in low:
62
+ return owner_repo
63
+ return None
64
+
65
+
66
+ def autodetect_repo_from_prompt(prompt: str | None) -> Path | None:
67
+ owner_repo = _resolve_owner_repo_from_prompt(prompt)
68
+ if not owner_repo:
69
+ return None
70
+ for cand in _candidate_repo_paths(owner_repo):
71
+ if (cand / ".git").exists():
72
+ return cand.resolve()
73
+ return None
74
+
75
+
76
+ def find_repo_root(
77
+ start: Path | None = None, prompt_text: str | None = None, workspace: str | None = None
78
+ ) -> Path:
79
+ if workspace:
80
+ ws = Path(workspace).expanduser().resolve()
81
+ if (ws / ".git").exists():
82
+ return ws
83
+ if "/" in workspace and not workspace.startswith("/"):
84
+ for cand in _candidate_repo_paths(workspace):
85
+ if (cand / ".git").exists():
86
+ return cand.resolve()
87
+ return ws
88
+ if prompt_text:
89
+ auto = autodetect_repo_from_prompt(prompt_text)
90
+ if auto is not None:
91
+ return auto
92
+ cur = (start or Path.cwd()).resolve()
93
+ # If we're inside a swarm worktree ( .../.agent-toolkit/swarm/runs/<run_id>/worktrees/<role> ),
94
+ # extract the main repo from that path directly
95
+ for p in [cur] + list(cur.parents):
96
+ # Detect being inside a run worktree: check for .agent-toolkit/swarm/runs segment
97
+ try:
98
+ parts = p.parts
99
+ if ".agent-toolkit" in parts:
100
+ idx = parts.index(".agent-toolkit")
101
+ # possible repo is parents[idx-1] if idx>0
102
+ if idx > 0:
103
+ candidate = Path(*parts[:idx])
104
+ if (candidate / ".git").exists() and (candidate / ".git").is_dir():
105
+ return candidate.resolve()
106
+ # also check if candidate is inside worktree path, try to find real repo via git common dir
107
+ if candidate.exists():
108
+ # Try git common dir resolution
109
+ import subprocess
110
+
111
+ try:
112
+ res = subprocess.run(
113
+ ["git", "rev-parse", "--git-common-dir"],
114
+ cwd=str(p),
115
+ capture_output=True,
116
+ text=True,
117
+ timeout=3,
118
+ )
119
+ if res.returncode == 0:
120
+ common = res.stdout.strip()
121
+ # common is like /path/to/repo/.git or /path/to/repo/.git/worktrees/...
122
+ # Find the repo root by looking for .git dir
123
+ common_path = Path(common)
124
+ if not common_path.is_absolute():
125
+ common_path = (p / common_path).resolve()
126
+ # common_path is .git or .git/worktrees/...
127
+ # The repo root is parent of .git
128
+ if common_path.name == ".git":
129
+ return common_path.parent.resolve()
130
+ elif common_path.parent.name == ".git":
131
+ # e.g., .git/worktrees/...
132
+ return common_path.parent.parent.resolve()
133
+ else:
134
+ # fallback: walk up from common_path looking for .git dir
135
+ for q in [common_path] + list(common_path.parents):
136
+ if (q / ".git").is_dir():
137
+ return q.resolve()
138
+ except Exception:
139
+ pass
140
+ except Exception:
141
+ pass
142
+ for p in [cur] + list(cur.parents):
143
+ git_path = p / ".git"
144
+ if git_path.exists():
145
+ # Prefer directory .git (main repo) over file (worktree)
146
+ if git_path.is_dir():
147
+ return p
148
+ # If .git is a file, it's a worktree — skip and continue searching up
149
+ # But also try to resolve via git common dir
150
+ try:
151
+ import subprocess
152
+
153
+ res = subprocess.run(
154
+ ["git", "rev-parse", "--git-common-dir"],
155
+ cwd=str(p),
156
+ capture_output=True,
157
+ text=True,
158
+ timeout=2,
159
+ )
160
+ if res.returncode == 0:
161
+ common = res.stdout.strip()
162
+ cp = Path(common)
163
+ if not cp.is_absolute():
164
+ cp = (p / cp).resolve()
165
+ if cp.name == ".git":
166
+ return cp.parent.resolve()
167
+ if cp.parent.name == ".git":
168
+ return cp.parent.parent.resolve()
169
+ except Exception:
170
+ pass
171
+ # Continue to next parent instead of returning worktree
172
+ continue
173
+ return cur
174
+
175
+
176
+ def find_run_dir_by_id(run_id: str, workspace: str | None = None) -> Path | None:
177
+ from .store import run_dir_for
178
+
179
+ if workspace:
180
+ repo = find_repo_root(workspace=workspace)
181
+ cand = run_dir_for(repo, run_id)
182
+ if cand.is_dir():
183
+ return cand
184
+ for cand2 in _candidate_repo_paths(workspace):
185
+ if (cand2 / ".git").exists():
186
+ cand = run_dir_for(cand2.resolve(), run_id)
187
+ if cand.is_dir():
188
+ return cand
189
+ try:
190
+ repo = find_repo_root()
191
+ cand = run_dir_for(repo, run_id)
192
+ if cand.is_dir():
193
+ return cand
194
+ except Exception:
195
+ pass
196
+ search_roots = [
197
+ Path.home() / ".ai-workspace" / "repos" / "github.com",
198
+ Path.home() / ".ai-workspace" / "repos",
199
+ ]
200
+ try:
201
+ cwd = Path.cwd().resolve()
202
+ for parent in [cwd] + list(cwd.parents):
203
+ if (parent / "repos").is_dir() and parent.name == ".ai-workspace":
204
+ search_roots.append(parent / "repos" / "github.com")
205
+ search_roots.append(parent / "repos")
206
+ break
207
+ except Exception:
208
+ pass
209
+ for root in search_roots:
210
+ if not root.is_dir():
211
+ continue
212
+ try:
213
+ for owner in root.iterdir():
214
+ if not owner.is_dir():
215
+ continue
216
+ if (owner / ".git").exists():
217
+ cand = run_dir_for(owner, run_id)
218
+ if cand.is_dir():
219
+ return cand
220
+ else:
221
+ for repo in owner.iterdir():
222
+ if not repo.is_dir() or not (repo / ".git").exists():
223
+ continue
224
+ cand = run_dir_for(repo, run_id)
225
+ if cand.is_dir():
226
+ return cand
227
+ except Exception:
228
+ continue
229
+ home_cand = Path.home() / ".agent-toolkit" / "swarm" / "runs" / run_id
230
+ if home_cand.is_dir():
231
+ return home_cand
232
+ return None
233
+
234
+
235
+ def list_all_runs(workspace: str | None = None) -> list[Path]:
236
+ from .store import list_runs
237
+
238
+ if workspace:
239
+ repo = find_repo_root(workspace=workspace)
240
+ return list_runs(repo)
241
+ try:
242
+ repo = find_repo_root()
243
+ runs = list_runs(repo)
244
+ if runs:
245
+ return runs
246
+ if repo.name == ".ai-workspace" or (repo / "repos").is_dir():
247
+ all_runs: list[Path] = []
248
+ seen: set[Path] = set()
249
+ search_roots = [
250
+ Path.home() / ".ai-workspace" / "repos" / "github.com",
251
+ Path.home() / ".ai-workspace" / "repos",
252
+ ]
253
+ for parent in [repo] + list(repo.parents):
254
+ if (parent / "repos").is_dir() and parent.name == ".ai-workspace":
255
+ search_roots.append(parent / "repos" / "github.com")
256
+ break
257
+ for root in search_roots:
258
+ if not root.is_dir():
259
+ continue
260
+ for owner in root.iterdir():
261
+ if not owner.is_dir():
262
+ continue
263
+ for maybe_repo in (
264
+ [owner]
265
+ if (owner / ".git").exists()
266
+ else (list(owner.iterdir()) if owner.is_dir() else [])
267
+ ):
268
+ if not maybe_repo.is_dir() or not (maybe_repo / ".git").exists():
269
+ continue
270
+ for rd in list_runs(maybe_repo):
271
+ rp = rd.resolve()
272
+ if rp not in seen:
273
+ seen.add(rp)
274
+ all_runs.append(rd)
275
+ home_root = Path.home() / ".agent-toolkit" / "swarm" / "runs"
276
+ if home_root.is_dir():
277
+ for rd in home_root.iterdir():
278
+ if rd.is_dir():
279
+ rp = rd.resolve()
280
+ if rp not in seen:
281
+ seen.add(rp)
282
+ all_runs.append(rd)
283
+ return sorted(
284
+ all_runs, key=lambda p: p.stat().st_mtime if p.exists() else 0, reverse=True
285
+ )
286
+ except Exception:
287
+ pass
288
+ return []
289
+
290
+
291
+ def load_yaml_file(path: Path) -> dict[str, Any]:
292
+ if not path.is_file():
293
+ return {}
294
+ text = path.read_text(encoding="utf-8")
295
+ try:
296
+ import yaml # type: ignore
297
+
298
+ data = yaml.safe_load(text)
299
+ return data if isinstance(data, dict) else {}
300
+ except ImportError:
301
+ import json
302
+
303
+ try:
304
+ return json.loads(text)
305
+ except Exception:
306
+ return {}
307
+ except Exception:
308
+ return {}
309
+
310
+
311
+ def resolve_config(repo_root: Path, cli_overrides: dict[str, Any] | None = None) -> dict[str, Any]:
312
+ # Precedence: CLI > project-local > workspace > user > defaults
313
+ defaults = {
314
+ "recipe": "pair",
315
+ "ui": "auto",
316
+ "runner": "opencode",
317
+ "model_profile": "balanced",
318
+ "budget": {},
319
+ "model_profiles": {},
320
+ }
321
+ # User config
322
+ user_cfg_path = Path.home() / ".config" / "agent-toolkit" / "swarm.yaml"
323
+ user_cfg = load_yaml_file(user_cfg_path)
324
+ # Workspace: repo/.agent-toolkit/swarm.yaml OR swarm.yaml
325
+ ws_cfg = {}
326
+ for p in [
327
+ repo_root / ".agent-toolkit" / "swarm.yaml",
328
+ repo_root / "swarm.yaml",
329
+ repo_root / ".agent-toolkit" / "swarm" / "config.yaml",
330
+ ]:
331
+ if p.is_file():
332
+ ws_cfg = load_yaml_file(p)
333
+ break
334
+ # Project-local is same as workspace for now (repo root)
335
+ merged = dict(defaults)
336
+ for src in (user_cfg, ws_cfg):
337
+ if src:
338
+ for k, v in src.items():
339
+ if v is not None:
340
+ if isinstance(v, dict) and isinstance(merged.get(k), dict):
341
+ merged[k] = {**merged[k], **v}
342
+ else:
343
+ merged[k] = v
344
+ if cli_overrides:
345
+ for k, v in cli_overrides.items():
346
+ if v is not None:
347
+ merged[k] = v
348
+ # Env overrides for runtime paths (not primary config)
349
+ if os.environ.get("AGENT_TOOLKIT_SWARM_RUNS_DIR"):
350
+ merged["runs_dir"] = os.environ["AGENT_TOOLKIT_SWARM_RUNS_DIR"]
351
+ return merged
@@ -0,0 +1,174 @@
1
+ """Handoff protocol — durable filesystem queue with validation."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import hashlib
6
+ import json
7
+ import os
8
+ import re
9
+ import tempfile
10
+ from pathlib import Path
11
+ from typing import Any
12
+
13
+ from .models import HANDOFF_VERSION
14
+ from .store import now_ts, validate_artifact_path
15
+
16
+ ALLOWED_TYPES = {"artifact", "commit", "feedback", "decision_request"}
17
+ SHA_RE = re.compile(r"^[0-9a-f]{40}$")
18
+ ROLE_RE = re.compile(r"^[a-z][a-z0-9_-]{1,31}$")
19
+
20
+
21
+ def handoff_id_for(payload: dict[str, Any]) -> str:
22
+ raw = json.dumps(payload, sort_keys=True)
23
+ return hashlib.sha256(raw.encode()).hexdigest()[:16]
24
+
25
+
26
+ def validate_handoff(data: dict[str, Any], run_dir: Path, roles: set[str]) -> list[str]:
27
+ errors: list[str] = []
28
+ if data.get("version") != HANDOFF_VERSION:
29
+ errors.append(f"version must be {HANDOFF_VERSION}")
30
+ htype = data.get("type")
31
+ if htype not in ALLOWED_TYPES:
32
+ errors.append(f"type must be one of {ALLOWED_TYPES}, got {htype!r}")
33
+ frm = data.get("from")
34
+ to = data.get("to")
35
+ if not isinstance(frm, str) or not ROLE_RE.match(frm):
36
+ errors.append(f"from invalid: {frm!r}")
37
+ elif frm not in roles and frm != "human":
38
+ errors.append(f"unknown from role: {frm!r}")
39
+ if not isinstance(to, str) or (not ROLE_RE.match(to) and to != "human"):
40
+ errors.append(f"to invalid: {to!r}")
41
+ elif to not in roles and to != "human":
42
+ errors.append(f"unknown to role: {to!r}")
43
+ prio = data.get("priority")
44
+ if not isinstance(prio, int) or not (0 <= prio <= 100):
45
+ errors.append("priority must be int 0..100")
46
+ artifact = data.get("artifact")
47
+ if artifact is not None:
48
+ if not isinstance(artifact, str):
49
+ errors.append("artifact must be string")
50
+ else:
51
+ try:
52
+ validate_artifact_path(run_dir, artifact)
53
+ # ensure stays under run_dir, no traversal — already checked
54
+ if artifact.startswith("/") or ".." in artifact:
55
+ errors.append("artifact traversal")
56
+ except ValueError as e:
57
+ errors.append(str(e))
58
+ # size limit check (1 MB default artifact limit later)
59
+ if artifact and len(artifact) > 512:
60
+ errors.append("artifact path too long")
61
+ if htype == "commit":
62
+ commit = data.get("commit")
63
+ branch = data.get("branch")
64
+ if not isinstance(commit, str) or not SHA_RE.match(commit.lower()):
65
+ errors.append("commit must be 40 hex chars")
66
+ if not isinstance(branch, str) or not branch:
67
+ errors.append("branch required for commit handoff")
68
+ elif ".." in branch or branch.startswith("/"):
69
+ errors.append("branch traversal")
70
+ # blocking check for feedback
71
+ if htype == "feedback":
72
+ if "blocking" in data and not isinstance(data["blocking"], bool):
73
+ errors.append("blocking must be bool")
74
+ return errors
75
+
76
+
77
+ def write_handoff_outbox(run_dir: Path, data: dict[str, Any]) -> Path:
78
+ # Atomically write to handoffs/outbox/<id>.json — ensure unique ID if collision
79
+ hid = data.get("handoff_id") or handoff_id_for(data)
80
+ data = dict(data)
81
+ data["handoff_id"] = hid
82
+ data["created_at"] = now_ts()
83
+ data.setdefault("version", HANDOFF_VERSION)
84
+ outbox = run_dir / "handoffs" / "outbox"
85
+ outbox.mkdir(parents=True, exist_ok=True)
86
+ # Ensure unique hid if file exists in any state
87
+ tried = 0
88
+ while any(
89
+ (run_dir / "handoffs" / st / f"{hid}.json").exists()
90
+ for st in ["outbox", "queued", "active", "completed", "failed"]
91
+ ):
92
+ # Append random suffix
93
+ import secrets
94
+
95
+ hid = handoff_id_for(data) + secrets.token_hex(2)
96
+ data["handoff_id"] = hid
97
+ tried += 1
98
+ if tried > 5:
99
+ break
100
+ tmp_fd, tmp_path = tempfile.mkstemp(dir=str(outbox), prefix=".tmp-")
101
+ try:
102
+ with os.fdopen(tmp_fd, "w", encoding="utf-8") as f:
103
+ json.dump(data, f, indent=2, sort_keys=True)
104
+ dest = outbox / f"{hid}.json"
105
+ os.replace(tmp_path, dest)
106
+ return dest
107
+ finally:
108
+ try:
109
+ Path(tmp_path).unlink(missing_ok=True)
110
+ except Exception:
111
+ pass
112
+
113
+
114
+ def move_handoff(run_dir: Path, handoff_id: str, from_state: str, to_state: str) -> Path | None:
115
+ src = run_dir / "handoffs" / from_state / f"{handoff_id}.json"
116
+ dst = run_dir / "handoffs" / to_state / f"{handoff_id}.json"
117
+ if not src.is_file():
118
+ return None
119
+ dst.parent.mkdir(parents=True, exist_ok=True)
120
+ src.rename(dst)
121
+ return dst
122
+
123
+
124
+ def list_handoffs(run_dir: Path, state: str) -> list[dict[str, Any]]:
125
+ d = run_dir / "handoffs" / state
126
+ if not d.is_dir():
127
+ return []
128
+ items: list[dict[str, Any]] = []
129
+ for p in sorted(d.glob("*.json")):
130
+ try:
131
+ data = json.loads(p.read_text(encoding="utf-8"))
132
+ items.append(data)
133
+ except Exception:
134
+ continue
135
+ return items
136
+
137
+
138
+ def validate_commit_exists(repo_root: Path, sha: str) -> bool:
139
+ import subprocess
140
+
141
+ try:
142
+ res = subprocess.run(
143
+ ["git", "cat-file", "-t", sha],
144
+ cwd=str(repo_root),
145
+ capture_output=True,
146
+ text=True,
147
+ timeout=5,
148
+ )
149
+ return res.returncode == 0 and "commit" in res.stdout
150
+ except Exception:
151
+ return False
152
+
153
+
154
+ def resolve_sha(repo_root: Path, abbrev: str) -> str | None:
155
+ import subprocess
156
+
157
+ # Use git rev-parse to resolve ambiguous abbreviations
158
+ try:
159
+ res = subprocess.run(
160
+ ["git", "rev-parse", "--verify", abbrev + "^{commit}"],
161
+ cwd=str(repo_root),
162
+ capture_output=True,
163
+ text=True,
164
+ timeout=5,
165
+ )
166
+ if res.returncode != 0:
167
+ return None
168
+ sha = res.stdout.strip()
169
+ if SHA_RE.match(sha):
170
+ # Check ambiguous: rev-parse should fail if ambiguous, but verify
171
+ return sha
172
+ return None
173
+ except Exception:
174
+ return None