@proflandrigan/shards 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (397) hide show
  1. package/README.md +475 -0
  2. package/package.json +37 -0
  3. package/src/agents/academic.md +276 -0
  4. package/src/agents/ai-engineer.md +377 -0
  5. package/src/agents/analytics-engineer.md +364 -0
  6. package/src/agents/applied-ml-scientist.md +410 -0
  7. package/src/agents/backend-engineer.md +255 -0
  8. package/src/agents/bi-engineer.md +333 -0
  9. package/src/agents/data-analyst.md +343 -0
  10. package/src/agents/data-engineer.md +260 -0
  11. package/src/agents/data-modeller.md +386 -0
  12. package/src/agents/data-scientist.md +366 -0
  13. package/src/agents/deep-learning-engineer.md +389 -0
  14. package/src/agents/ml-engineer.md +424 -0
  15. package/src/agents/mlops-engineer.md +339 -0
  16. package/src/agents/researcher.md +187 -0
  17. package/src/agents/specific_instructions/academic/critical_review.md +263 -0
  18. package/src/agents/specific_instructions/academic/report.md +113 -0
  19. package/src/agents/specific_instructions/ai_engineer/advise.md +162 -0
  20. package/src/agents/specific_instructions/ai_engineer/bi_engineer_handoff.md +86 -0
  21. package/src/agents/specific_instructions/ai_engineer/experiment.md +471 -0
  22. package/src/agents/specific_instructions/ai_engineer/experiment_ui_mode.md +44 -0
  23. package/src/agents/specific_instructions/ai_engineer/phases/index.md +45 -0
  24. package/src/agents/specific_instructions/ai_engineer/phases/phase-1.md +55 -0
  25. package/src/agents/specific_instructions/ai_engineer/phases/phase-2.md +86 -0
  26. package/src/agents/specific_instructions/ai_engineer/phases/phase-3.md +96 -0
  27. package/src/agents/specific_instructions/ai_engineer/phases/phase-4.md +138 -0
  28. package/src/agents/specific_instructions/ai_engineer/phases/phase-5.md +157 -0
  29. package/src/agents/specific_instructions/ai_engineer/phases/phase-6.md +196 -0
  30. package/src/agents/specific_instructions/ai_engineer/phases/phase-7.md +313 -0
  31. package/src/agents/specific_instructions/ai_engineer/phases.md +1011 -0
  32. package/src/agents/specific_instructions/ai_engineer/prompt_lab.md +161 -0
  33. package/src/agents/specific_instructions/ai_engineer/prompt_lab_ui_mode.md +28 -0
  34. package/src/agents/specific_instructions/ai_engineer/research.md +393 -0
  35. package/src/agents/specific_instructions/ai_engineer/research_ui_mode.md +66 -0
  36. package/src/agents/specific_instructions/ai_engineer/review.md +159 -0
  37. package/src/agents/specific_instructions/ai_engineer/validation_checklist.md +182 -0
  38. package/src/agents/specific_instructions/analytics_engineer/advise.md +155 -0
  39. package/src/agents/specific_instructions/analytics_engineer/bi_engineer_handoff.md +91 -0
  40. package/src/agents/specific_instructions/analytics_engineer/data_analyst_handoff.md +84 -0
  41. package/src/agents/specific_instructions/analytics_engineer/deep_phases.md +818 -0
  42. package/src/agents/specific_instructions/analytics_engineer/phases_deep/index.md +24 -0
  43. package/src/agents/specific_instructions/analytics_engineer/phases_deep/phase-1.md +77 -0
  44. package/src/agents/specific_instructions/analytics_engineer/phases_deep/phase-2.md +106 -0
  45. package/src/agents/specific_instructions/analytics_engineer/phases_deep/phase-3.md +93 -0
  46. package/src/agents/specific_instructions/analytics_engineer/phases_deep/phase-4.md +79 -0
  47. package/src/agents/specific_instructions/analytics_engineer/phases_deep/phase-5.md +61 -0
  48. package/src/agents/specific_instructions/analytics_engineer/phases_deep/phase-6.md +45 -0
  49. package/src/agents/specific_instructions/analytics_engineer/phases_deep/phase-7.md +235 -0
  50. package/src/agents/specific_instructions/analytics_engineer/phases_deep/phase-8.md +221 -0
  51. package/src/agents/specific_instructions/analytics_engineer/phases_quick/index.md +19 -0
  52. package/src/agents/specific_instructions/analytics_engineer/phases_quick/phase-1.md +47 -0
  53. package/src/agents/specific_instructions/analytics_engineer/phases_quick/phase-2.md +78 -0
  54. package/src/agents/specific_instructions/analytics_engineer/quick_phases.md +112 -0
  55. package/src/agents/specific_instructions/analytics_engineer/review.md +167 -0
  56. package/src/agents/specific_instructions/analytics_engineer/service_mode.md +369 -0
  57. package/src/agents/specific_instructions/analytics_engineer/ui_mode.md +45 -0
  58. package/src/agents/specific_instructions/analytics_engineer/update.md +162 -0
  59. package/src/agents/specific_instructions/analytics_engineer/validation_checklist.md +121 -0
  60. package/src/agents/specific_instructions/applied_ml_scientist/advise.md +143 -0
  61. package/src/agents/specific_instructions/applied_ml_scientist/phases/index.md +21 -0
  62. package/src/agents/specific_instructions/applied_ml_scientist/phases/phase-1.md +51 -0
  63. package/src/agents/specific_instructions/applied_ml_scientist/phases/phase-2.md +66 -0
  64. package/src/agents/specific_instructions/applied_ml_scientist/phases/phase-3.md +113 -0
  65. package/src/agents/specific_instructions/applied_ml_scientist/phases/phase-4.md +104 -0
  66. package/src/agents/specific_instructions/applied_ml_scientist/phases/phase-5.md +156 -0
  67. package/src/agents/specific_instructions/applied_ml_scientist/phases.md +428 -0
  68. package/src/agents/specific_instructions/applied_ml_scientist/research.md +379 -0
  69. package/src/agents/specific_instructions/applied_ml_scientist/review.md +142 -0
  70. package/src/agents/specific_instructions/applied_ml_scientist/validation_checklist.md +136 -0
  71. package/src/agents/specific_instructions/backend_engineer/clean.md +149 -0
  72. package/src/agents/specific_instructions/backend_engineer/review.md +91 -0
  73. package/src/agents/specific_instructions/backend_engineer/review_checklist.md +54 -0
  74. package/src/agents/specific_instructions/backend_engineer/service_mode.md +67 -0
  75. package/src/agents/specific_instructions/bi_engineer/advise.md +137 -0
  76. package/src/agents/specific_instructions/bi_engineer/data_analyst_handoff.md +77 -0
  77. package/src/agents/specific_instructions/bi_engineer/incoming_handoff.md +45 -0
  78. package/src/agents/specific_instructions/bi_engineer/phases/index.md +20 -0
  79. package/src/agents/specific_instructions/bi_engineer/phases/phase-1.md +164 -0
  80. package/src/agents/specific_instructions/bi_engineer/phases/phase-2.md +92 -0
  81. package/src/agents/specific_instructions/bi_engineer/phases/phase-3.md +121 -0
  82. package/src/agents/specific_instructions/bi_engineer/phases/phase-4.md +106 -0
  83. package/src/agents/specific_instructions/bi_engineer/phases.md +451 -0
  84. package/src/agents/specific_instructions/bi_engineer/review.md +166 -0
  85. package/src/agents/specific_instructions/bi_engineer/update.md +147 -0
  86. package/src/agents/specific_instructions/bi_engineer/validation_checklist.md +124 -0
  87. package/src/agents/specific_instructions/data_analyst/advise.md +138 -0
  88. package/src/agents/specific_instructions/data_analyst/explain.md +221 -0
  89. package/src/agents/specific_instructions/data_analyst/incoming_handoff.md +40 -0
  90. package/src/agents/specific_instructions/data_analyst/phases/index.md +20 -0
  91. package/src/agents/specific_instructions/data_analyst/phases/phase-1.md +159 -0
  92. package/src/agents/specific_instructions/data_analyst/phases/phase-2.md +112 -0
  93. package/src/agents/specific_instructions/data_analyst/phases/phase-3.md +265 -0
  94. package/src/agents/specific_instructions/data_analyst/phases/phase-4.md +100 -0
  95. package/src/agents/specific_instructions/data_analyst/phases.md +501 -0
  96. package/src/agents/specific_instructions/data_analyst/review.md +138 -0
  97. package/src/agents/specific_instructions/data_analyst/ui_mode.md +26 -0
  98. package/src/agents/specific_instructions/data_analyst/update.md +144 -0
  99. package/src/agents/specific_instructions/data_analyst/validation_checklist.md +95 -0
  100. package/src/agents/specific_instructions/data_engineer/advise.md +137 -0
  101. package/src/agents/specific_instructions/data_engineer/phases.md +466 -0
  102. package/src/agents/specific_instructions/data_engineer/phases_deep/index.md +23 -0
  103. package/src/agents/specific_instructions/data_engineer/phases_deep/phase-1.md +49 -0
  104. package/src/agents/specific_instructions/data_engineer/phases_deep/phase-2.md +93 -0
  105. package/src/agents/specific_instructions/data_engineer/phases_deep/phase-3.md +55 -0
  106. package/src/agents/specific_instructions/data_engineer/phases_deep/phase-4.md +48 -0
  107. package/src/agents/specific_instructions/data_engineer/phases_deep/phase-5.md +40 -0
  108. package/src/agents/specific_instructions/data_engineer/phases_deep/phase-6.md +102 -0
  109. package/src/agents/specific_instructions/data_engineer/phases_deep/phase-7.md +87 -0
  110. package/src/agents/specific_instructions/data_engineer/phases_quick/index.md +19 -0
  111. package/src/agents/specific_instructions/data_engineer/phases_quick/phase-1.md +45 -0
  112. package/src/agents/specific_instructions/data_engineer/phases_quick/phase-2.md +54 -0
  113. package/src/agents/specific_instructions/data_engineer/review.md +135 -0
  114. package/src/agents/specific_instructions/data_engineer/validation_checklist.md +136 -0
  115. package/src/agents/specific_instructions/data_modeller/advise.md +137 -0
  116. package/src/agents/specific_instructions/data_modeller/phases.md +581 -0
  117. package/src/agents/specific_instructions/data_modeller/phases_deep/index.md +23 -0
  118. package/src/agents/specific_instructions/data_modeller/phases_deep/phase-1.md +52 -0
  119. package/src/agents/specific_instructions/data_modeller/phases_deep/phase-2.md +113 -0
  120. package/src/agents/specific_instructions/data_modeller/phases_deep/phase-3.md +47 -0
  121. package/src/agents/specific_instructions/data_modeller/phases_deep/phase-4.md +51 -0
  122. package/src/agents/specific_instructions/data_modeller/phases_deep/phase-5.md +45 -0
  123. package/src/agents/specific_instructions/data_modeller/phases_deep/phase-6.md +105 -0
  124. package/src/agents/specific_instructions/data_modeller/phases_deep/phase-7.md +136 -0
  125. package/src/agents/specific_instructions/data_modeller/phases_quick/index.md +19 -0
  126. package/src/agents/specific_instructions/data_modeller/phases_quick/phase-1.md +47 -0
  127. package/src/agents/specific_instructions/data_modeller/phases_quick/phase-2.md +65 -0
  128. package/src/agents/specific_instructions/data_modeller/review.md +141 -0
  129. package/src/agents/specific_instructions/data_modeller/service_mode.md +218 -0
  130. package/src/agents/specific_instructions/data_modeller/validation_checklist.md +125 -0
  131. package/src/agents/specific_instructions/data_scientist/advise.md +158 -0
  132. package/src/agents/specific_instructions/data_scientist/bi_engineer_handoff.md +63 -0
  133. package/src/agents/specific_instructions/data_scientist/experiment.md +482 -0
  134. package/src/agents/specific_instructions/data_scientist/experiment_ui_mode.md +44 -0
  135. package/src/agents/specific_instructions/data_scientist/explain.md +247 -0
  136. package/src/agents/specific_instructions/data_scientist/greenfield_data.md +35 -0
  137. package/src/agents/specific_instructions/data_scientist/ml_engineer_handoff.md +52 -0
  138. package/src/agents/specific_instructions/data_scientist/notebook_walkthrough.md +76 -0
  139. package/src/agents/specific_instructions/data_scientist/phases/index.md +24 -0
  140. package/src/agents/specific_instructions/data_scientist/phases/phase-1.md +45 -0
  141. package/src/agents/specific_instructions/data_scientist/phases/phase-2.md +67 -0
  142. package/src/agents/specific_instructions/data_scientist/phases/phase-3.md +89 -0
  143. package/src/agents/specific_instructions/data_scientist/phases/phase-4.md +143 -0
  144. package/src/agents/specific_instructions/data_scientist/phases/phase-5.md +71 -0
  145. package/src/agents/specific_instructions/data_scientist/phases/phase-6.md +239 -0
  146. package/src/agents/specific_instructions/data_scientist/phases/phase-7.md +207 -0
  147. package/src/agents/specific_instructions/data_scientist/phases.md +651 -0
  148. package/src/agents/specific_instructions/data_scientist/research.md +345 -0
  149. package/src/agents/specific_instructions/data_scientist/research_ui_mode.md +52 -0
  150. package/src/agents/specific_instructions/data_scientist/review.md +136 -0
  151. package/src/agents/specific_instructions/data_scientist/service_mode.md +247 -0
  152. package/src/agents/specific_instructions/data_scientist/validation_checklist.md +183 -0
  153. package/src/agents/specific_instructions/deep_learning_engineer/advise.md +145 -0
  154. package/src/agents/specific_instructions/deep_learning_engineer/phases/index.md +21 -0
  155. package/src/agents/specific_instructions/deep_learning_engineer/phases/phase-1.md +74 -0
  156. package/src/agents/specific_instructions/deep_learning_engineer/phases/phase-2.md +98 -0
  157. package/src/agents/specific_instructions/deep_learning_engineer/phases/phase-3.md +76 -0
  158. package/src/agents/specific_instructions/deep_learning_engineer/phases/phase-4.md +128 -0
  159. package/src/agents/specific_instructions/deep_learning_engineer/phases/phase-5.md +292 -0
  160. package/src/agents/specific_instructions/deep_learning_engineer/phases.md +567 -0
  161. package/src/agents/specific_instructions/deep_learning_engineer/research.md +389 -0
  162. package/src/agents/specific_instructions/deep_learning_engineer/review.md +155 -0
  163. package/src/agents/specific_instructions/deep_learning_engineer/validation_checklist.md +147 -0
  164. package/src/agents/specific_instructions/ml_engineer/advise.md +174 -0
  165. package/src/agents/specific_instructions/ml_engineer/bi_engineer_handoff.md +71 -0
  166. package/src/agents/specific_instructions/ml_engineer/experiment.md +474 -0
  167. package/src/agents/specific_instructions/ml_engineer/experiment_ui_mode.md +44 -0
  168. package/src/agents/specific_instructions/ml_engineer/notebook_walkthrough.md +75 -0
  169. package/src/agents/specific_instructions/ml_engineer/phases/index.md +25 -0
  170. package/src/agents/specific_instructions/ml_engineer/phases/phase-1.md +49 -0
  171. package/src/agents/specific_instructions/ml_engineer/phases/phase-2.md +75 -0
  172. package/src/agents/specific_instructions/ml_engineer/phases/phase-3.md +124 -0
  173. package/src/agents/specific_instructions/ml_engineer/phases/phase-4.md +279 -0
  174. package/src/agents/specific_instructions/ml_engineer/phases/phase-5.md +160 -0
  175. package/src/agents/specific_instructions/ml_engineer/phases/phase-6-5.md +170 -0
  176. package/src/agents/specific_instructions/ml_engineer/phases/phase-6.md +295 -0
  177. package/src/agents/specific_instructions/ml_engineer/phases/phase-7.md +337 -0
  178. package/src/agents/specific_instructions/ml_engineer/phases.md +1068 -0
  179. package/src/agents/specific_instructions/ml_engineer/research.md +437 -0
  180. package/src/agents/specific_instructions/ml_engineer/research_ui_mode.md +71 -0
  181. package/src/agents/specific_instructions/ml_engineer/review.md +187 -0
  182. package/src/agents/specific_instructions/ml_engineer/service_mode.md +273 -0
  183. package/src/agents/specific_instructions/ml_engineer/validation_checklist.md +185 -0
  184. package/src/agents/specific_instructions/mlops_engineer/advise.md +139 -0
  185. package/src/agents/specific_instructions/mlops_engineer/phases/index.md +23 -0
  186. package/src/agents/specific_instructions/mlops_engineer/phases/phase-1.md +52 -0
  187. package/src/agents/specific_instructions/mlops_engineer/phases/phase-2.md +86 -0
  188. package/src/agents/specific_instructions/mlops_engineer/phases/phase-3.md +105 -0
  189. package/src/agents/specific_instructions/mlops_engineer/phases/phase-4.md +128 -0
  190. package/src/agents/specific_instructions/mlops_engineer/phases/phase-5.md +106 -0
  191. package/src/agents/specific_instructions/mlops_engineer/phases/phase-6.md +128 -0
  192. package/src/agents/specific_instructions/mlops_engineer/phases/phase-7.md +144 -0
  193. package/src/agents/specific_instructions/mlops_engineer/phases.md +671 -0
  194. package/src/agents/specific_instructions/mlops_engineer/review.md +164 -0
  195. package/src/agents/specific_instructions/mlops_engineer/service_mode.md +81 -0
  196. package/src/agents/specific_instructions/mlops_engineer/validation_checklist.md +151 -0
  197. package/src/agents/specific_instructions/researcher/critical_review.md +292 -0
  198. package/src/agents/specific_instructions/researcher/review_checklist.md +67 -0
  199. package/src/agents/specific_instructions/researcher/service_mode.md +224 -0
  200. package/src/agents/specific_instructions/shared/auto_verify_mode.md +141 -0
  201. package/src/agents/specific_instructions/shared/autonomous_research.md +1289 -0
  202. package/src/agents/specific_instructions/shared/behavioral_rules.md +36 -0
  203. package/src/agents/specific_instructions/shared/diverge_protocol.md +387 -0
  204. package/src/agents/specific_instructions/shared/engineering_guidelines.md +136 -0
  205. package/src/agents/specific_instructions/shared/experiment_versioning.md +184 -0
  206. package/src/agents/specific_instructions/shared/goal_mode.md +187 -0
  207. package/src/agents/specific_instructions/shared/incremental_testing.md +139 -0
  208. package/src/agents/specific_instructions/shared/intent_discovery.md +223 -0
  209. package/src/agents/specific_instructions/shared/join_path_protocol.md +168 -0
  210. package/src/agents/specific_instructions/shared/knowledge_checkpoint.md +83 -0
  211. package/src/agents/specific_instructions/shared/knowledge_harvest.md +220 -0
  212. package/src/agents/specific_instructions/shared/knowledge_retrieval.md +100 -0
  213. package/src/agents/specific_instructions/shared/notebook_walkthrough_protocol.md +367 -0
  214. package/src/agents/specific_instructions/shared/reviewer_verdict_protocol.md +74 -0
  215. package/src/agents/specific_instructions/shared/swarm_protocol.md +97 -0
  216. package/src/agents/specific_instructions/shared/validation_protocol.md +139 -0
  217. package/src/agents/specific_instructions/syn/arbiter.md +140 -0
  218. package/src/agents/specific_instructions/syn/brainstorm.md +550 -0
  219. package/src/agents/specific_instructions/syn/code_review.md +232 -0
  220. package/src/agents/specific_instructions/syn/diff.md +239 -0
  221. package/src/agents/specific_instructions/syn/final_review.md +65 -0
  222. package/src/agents/specific_instructions/syn/fixer.md +240 -0
  223. package/src/agents/specific_instructions/syn/free_form.md +130 -0
  224. package/src/agents/specific_instructions/syn/knowledge.md +468 -0
  225. package/src/agents/specific_instructions/syn/notebook_walkthrough.md +78 -0
  226. package/src/agents/specific_instructions/syn/panel_review.md +634 -0
  227. package/src/agents/specific_instructions/syn/pm.md +453 -0
  228. package/src/agents/specific_instructions/syn/pr_review.md +255 -0
  229. package/src/agents/specific_instructions/syn/slides.md +417 -0
  230. package/src/agents/syn.md +729 -0
  231. package/src/commands/academic.md +41 -0
  232. package/src/commands/ai-engineer.md +45 -0
  233. package/src/commands/analytics-engineer.md +48 -0
  234. package/src/commands/applied-ml-scientist.md +45 -0
  235. package/src/commands/backend-engineer.md +35 -0
  236. package/src/commands/bi-engineer.md +40 -0
  237. package/src/commands/brainstorm.md +24 -0
  238. package/src/commands/data-analyst.md +38 -0
  239. package/src/commands/data-engineer.md +37 -0
  240. package/src/commands/data-modeller.md +38 -0
  241. package/src/commands/data-scientist.md +38 -0
  242. package/src/commands/deep-learning-engineer.md +47 -0
  243. package/src/commands/end.md +49 -0
  244. package/src/commands/knowledge.md +24 -0
  245. package/src/commands/ml-engineer.md +42 -0
  246. package/src/commands/mlops-engineer.md +47 -0
  247. package/src/commands/notebook-walkthrough.md +58 -0
  248. package/src/commands/researcher.md +40 -0
  249. package/src/commands/resume.md +57 -0
  250. package/src/commands/review-pr.md +26 -0
  251. package/src/commands/shards-guide.md +41 -0
  252. package/src/commands/shards-ui.md +32 -0
  253. package/src/commands/shards.md +41 -0
  254. package/src/docs/01-getting-started/concepts.md +109 -0
  255. package/src/docs/01-getting-started/first-session.md +79 -0
  256. package/src/docs/01-getting-started/install.md +61 -0
  257. package/src/docs/02-agents/academic.md +71 -0
  258. package/src/docs/02-agents/ai-engineer.md +78 -0
  259. package/src/docs/02-agents/analytics-engineer.md +58 -0
  260. package/src/docs/02-agents/applied-ml-scientist.md +59 -0
  261. package/src/docs/02-agents/backend-engineer.md +58 -0
  262. package/src/docs/02-agents/bi-engineer.md +65 -0
  263. package/src/docs/02-agents/data-analyst.md +67 -0
  264. package/src/docs/02-agents/data-engineer.md +57 -0
  265. package/src/docs/02-agents/data-modeller.md +51 -0
  266. package/src/docs/02-agents/data-scientist.md +78 -0
  267. package/src/docs/02-agents/deep-learning-engineer.md +64 -0
  268. package/src/docs/02-agents/ml-engineer.md +80 -0
  269. package/src/docs/02-agents/mlops-engineer.md +59 -0
  270. package/src/docs/02-agents/overview.md +62 -0
  271. package/src/docs/02-agents/researcher.md +73 -0
  272. package/src/docs/02-agents/syn.md +88 -0
  273. package/src/docs/03-protocols/auto-verify.md +82 -0
  274. package/src/docs/03-protocols/autonomous-research.md +59 -0
  275. package/src/docs/03-protocols/behavioral-rules.md +35 -0
  276. package/src/docs/03-protocols/diverge.md +50 -0
  277. package/src/docs/03-protocols/engineering-guidelines.md +56 -0
  278. package/src/docs/03-protocols/experiment-versioning.md +38 -0
  279. package/src/docs/03-protocols/gate-pattern.md +65 -0
  280. package/src/docs/03-protocols/incremental-testing.md +68 -0
  281. package/src/docs/03-protocols/join-path.md +46 -0
  282. package/src/docs/03-protocols/knowledge-ledger.md +70 -0
  283. package/src/docs/03-protocols/reviewer-verdicts.md +39 -0
  284. package/src/docs/03-protocols/swarm.md +40 -0
  285. package/src/docs/03-protocols/validation.md +174 -0
  286. package/src/docs/04-ui/activity-bar.md +70 -0
  287. package/src/docs/04-ui/chat-pane.md +80 -0
  288. package/src/docs/04-ui/code-intel.md +62 -0
  289. package/src/docs/04-ui/file-editing.md +61 -0
  290. package/src/docs/04-ui/git.md +54 -0
  291. package/src/docs/04-ui/keybindings.md +79 -0
  292. package/src/docs/04-ui/knowledge-map.md +76 -0
  293. package/src/docs/04-ui/overview.md +93 -0
  294. package/src/docs/04-ui/panels.md +49 -0
  295. package/src/docs/04-ui/pinboard-selection.md +66 -0
  296. package/src/docs/04-ui/quick-open-palette.md +56 -0
  297. package/src/docs/04-ui/sessions.md +81 -0
  298. package/src/docs/04-ui/settings-permissions.md +56 -0
  299. package/src/docs/05-commands/reference.md +59 -0
  300. package/src/docs/06-outputs/directory-map.md +116 -0
  301. package/src/docs/07-workflows/ai-eval-first.md +57 -0
  302. package/src/docs/07-workflows/deep-study-to-production.md +76 -0
  303. package/src/docs/07-workflows/diverge-exploration.md +77 -0
  304. package/src/docs/07-workflows/quick-analysis.md +45 -0
  305. package/src/docs/08-integrations/claude-code-auto-mode.md +191 -0
  306. package/src/docs/08-integrations/google-slides.md +175 -0
  307. package/src/docs/README.md +30 -0
  308. package/src/docs/manifest.json +108 -0
  309. package/src/templates/analysis-template.md +20 -0
  310. package/src/templates/branch-report.md +46 -0
  311. package/src/templates/diff-report.md +88 -0
  312. package/src/templates/knowledge-index.md +7 -0
  313. package/src/templates/model-card-schema.json +186 -0
  314. package/src/templates/model-card-schema.md +88 -0
  315. package/src/templates/model-card.md +124 -0
  316. package/src/templates/project-plan.md +47 -0
  317. package/src/templates/project-specs.md +81 -0
  318. package/src/templates/report-template.md +43 -0
  319. package/src/templates/study-template.md +25 -0
  320. package/src/ui/cc-readonly.js +181 -0
  321. package/src/ui/chat-session.js +466 -0
  322. package/src/ui/css/base.css +136 -0
  323. package/src/ui/css/brainstorm.css +525 -0
  324. package/src/ui/css/chat.css +1405 -0
  325. package/src/ui/css/editor.css +546 -0
  326. package/src/ui/css/eval-dashboard.css +157 -0
  327. package/src/ui/css/experiment.css +237 -0
  328. package/src/ui/css/guide.css +186 -0
  329. package/src/ui/css/knowledge-map.css +383 -0
  330. package/src/ui/css/layout.css +431 -0
  331. package/src/ui/css/model-card.css +161 -0
  332. package/src/ui/css/notebook-walkthrough.css +271 -0
  333. package/src/ui/css/pr-review.css +403 -0
  334. package/src/ui/css/prompt-lab.css +325 -0
  335. package/src/ui/css/sessions.css +258 -0
  336. package/src/ui/css/sidebar.css +661 -0
  337. package/src/ui/css/terminal.css +113 -0
  338. package/src/ui/css/theme-light.css +542 -0
  339. package/src/ui/index.html +389 -0
  340. package/src/ui/js/agents.js +32 -0
  341. package/src/ui/js/bookmarks.js +230 -0
  342. package/src/ui/js/chat.js +1776 -0
  343. package/src/ui/js/code-intel.js +328 -0
  344. package/src/ui/js/command-palette.js +142 -0
  345. package/src/ui/js/events.js +591 -0
  346. package/src/ui/js/explorer.js +317 -0
  347. package/src/ui/js/file-view.js +477 -0
  348. package/src/ui/js/git.js +536 -0
  349. package/src/ui/js/guide.js +198 -0
  350. package/src/ui/js/hud.js +75 -0
  351. package/src/ui/js/init.js +351 -0
  352. package/src/ui/js/knowledge-map.js +906 -0
  353. package/src/ui/js/markdown.js +114 -0
  354. package/src/ui/js/monaco.js +164 -0
  355. package/src/ui/js/notebook-walkthrough.js +272 -0
  356. package/src/ui/js/notebook.js +448 -0
  357. package/src/ui/js/panels.js +2681 -0
  358. package/src/ui/js/pinboard.js +186 -0
  359. package/src/ui/js/quick-open.js +164 -0
  360. package/src/ui/js/selection-context.js +131 -0
  361. package/src/ui/js/sessions.js +256 -0
  362. package/src/ui/js/settings.js +476 -0
  363. package/src/ui/js/split-view.js +82 -0
  364. package/src/ui/js/state.js +343 -0
  365. package/src/ui/js/table.js +161 -0
  366. package/src/ui/js/tabs.js +284 -0
  367. package/src/ui/js/tabular.js +125 -0
  368. package/src/ui/js/terminal.js +354 -0
  369. package/src/ui/js/timeline.js +137 -0
  370. package/src/ui/js/utils.js +293 -0
  371. package/src/ui/notebook-kernel.py +790 -0
  372. package/src/ui/open-browser.js +55 -0
  373. package/src/ui/permission-pattern.js +42 -0
  374. package/src/ui/relay.js +513 -0
  375. package/src/ui/server.js +3072 -0
  376. package/src/ui/session-index.js +225 -0
  377. package/src/ui/shards_icon.png +0 -0
  378. package/src/ui/spawn-server.js +41 -0
  379. package/src/ui/symbol-index.js +813 -0
  380. package/src/ui/ui-push.js +177 -0
  381. package/tools/gate-hook/VALIDATION_SPEC.md +273 -0
  382. package/tools/gate-hook/__tests__/auto-verify.test.js +343 -0
  383. package/tools/gate-hook/auto-allowlist.js +179 -0
  384. package/tools/gate-hook/auto-state.js +68 -0
  385. package/tools/gate-hook/classify.js +21 -0
  386. package/tools/gate-hook/log.js +57 -0
  387. package/tools/gate-hook/parser.js +205 -0
  388. package/tools/gate-hook/sql-guard.js +230 -0
  389. package/tools/gate-hook/state.js +170 -0
  390. package/tools/gate-hook/sweep.js +139 -0
  391. package/tools/gate-hook/transcript.js +45 -0
  392. package/tools/gate-hook/validation.js +321 -0
  393. package/tools/gate-hook.js +475 -0
  394. package/tools/install.js +914 -0
  395. package/tools/shards-gates.js +311 -0
  396. package/tools/shards-sessions.js +261 -0
  397. package/tools/shards-ui.js +377 -0
@@ -0,0 +1,343 @@
1
+ // End-to-end tests for auto-verify mode.
2
+ //
3
+ // These tests pipe synthetic stdin payloads to gate-hook.js and assert on
4
+ // stdout (the hook response) and on .shards/auto/state.json (the persisted
5
+ // state). They run in an isolated tmp directory per test so concurrent
6
+ // runs don't collide.
7
+
8
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
9
+ import fs from 'fs';
10
+ import os from 'os';
11
+ import path from 'path';
12
+ import { spawnSync } from 'child_process';
13
+ import { fileURLToPath } from 'url';
14
+
15
+ const __filename = fileURLToPath(import.meta.url);
16
+ const __dirname = path.dirname(__filename);
17
+
18
+ const REPO_ROOT = path.resolve(__dirname, '..', '..', '..');
19
+ const HOOK = path.join(REPO_ROOT, 'tools', 'gate-hook.js');
20
+
21
+ // ─── Test infrastructure ──────────────────────────────────────────────────────
22
+
23
+ let tmp;
24
+
25
+ beforeEach(() => {
26
+ tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'shards-auto-test-'));
27
+ });
28
+
29
+ afterEach(() => {
30
+ if (tmp) {
31
+ fs.rmSync(tmp, { recursive: true, force: true });
32
+ tmp = null;
33
+ }
34
+ });
35
+
36
+ // Write a fake transcript file with one assistant message containing `text`.
37
+ // Mirrors the JSONL shape Claude Code writes:
38
+ // {type: "assistant", message: {role: "assistant", content: [...]}}
39
+ function writeTranscript(text, shape = 'real') {
40
+ const file = path.join(tmp, 'transcript.jsonl');
41
+ let entry;
42
+ if (shape === 'real') {
43
+ entry = {
44
+ type: 'assistant',
45
+ message: { role: 'assistant', content: [{ type: 'text', text }] },
46
+ };
47
+ } else {
48
+ // legacy — kept for symmetry; transcript.js still accepts this shape
49
+ entry = { role: 'assistant', content: [{ type: 'text', text }] };
50
+ }
51
+ fs.writeFileSync(file, JSON.stringify(entry) + '\n');
52
+ return file;
53
+ }
54
+
55
+ function runHook(event, payload, env = {}) {
56
+ const result = spawnSync('node', [HOOK, event], {
57
+ cwd: tmp,
58
+ input: JSON.stringify(payload),
59
+ encoding: 'utf8',
60
+ env: { ...process.env, ...env },
61
+ });
62
+ let parsed = null;
63
+ if (result.stdout && result.stdout.trim()) {
64
+ try { parsed = JSON.parse(result.stdout.trim()); } catch { /* not JSON */ }
65
+ }
66
+ return { stdout: result.stdout, stderr: result.stderr, status: result.status, parsed };
67
+ }
68
+
69
+ function readAutoState() {
70
+ const file = path.join(tmp, '.shards', 'auto', 'state.json');
71
+ if (!fs.existsSync(file)) return { open: false };
72
+ return JSON.parse(fs.readFileSync(file, 'utf8'));
73
+ }
74
+
75
+ function readGateState() {
76
+ const file = path.join(tmp, '.shards', 'gates', 'state.json');
77
+ if (!fs.existsSync(file)) return { open: false };
78
+ const raw = JSON.parse(fs.readFileSync(file, 'utf8'));
79
+ // v2 per-session shape: reduce to a flat { open, ... } by surfacing any open
80
+ // session slot (legacy single-slot files just pass through).
81
+ if (raw && raw.sessions && typeof raw.sessions === 'object') {
82
+ const open = Object.values(raw.sessions).find(g => g && g.open);
83
+ return open ? { open: true, ...open, history: raw.history || [] }
84
+ : { open: false, history: raw.history || [] };
85
+ }
86
+ return raw;
87
+ }
88
+
89
+ // ─── Tests ────────────────────────────────────────────────────────────────────
90
+
91
+ describe('auto-verify', () => {
92
+ it('::AUTO-VERIFY:: marker opens state', () => {
93
+ const transcript = writeTranscript(
94
+ '::AUTO-VERIFY:: agent=data-modeller phase=6 tool_budget=5 ttl_minutes=2'
95
+ );
96
+ runHook('stop', { transcript_path: transcript, session_id: 's1' });
97
+ const s = readAutoState();
98
+ expect(s.open).toBe(true);
99
+ expect(s.agent).toBe('data-modeller');
100
+ expect(s.phase).toBe('6');
101
+ expect(s.tool_budget_remaining).toBe(5);
102
+ expect(s.tool_budget_initial).toBe(5);
103
+ });
104
+
105
+ it('::ENDAUTO:: marker closes state', () => {
106
+ // Open
107
+ const t1 = writeTranscript('::AUTO-VERIFY:: agent=ml-engineer phase=3 tool_budget=10');
108
+ runHook('stop', { transcript_path: t1, session_id: 's1' });
109
+ expect(readAutoState().open).toBe(true);
110
+ // Close
111
+ const t2 = writeTranscript('Done with verification.\n\n::ENDAUTO::');
112
+ runHook('stop', { transcript_path: t2, session_id: 's1' });
113
+ expect(readAutoState().open).toBe(false);
114
+ });
115
+
116
+ it('PreToolUse auto-approves dbt show when block open', () => {
117
+ const t = writeTranscript('::AUTO-VERIFY:: agent=data-modeller phase=6 tool_budget=5');
118
+ runHook('stop', { transcript_path: t, session_id: 's1' });
119
+ const r = runHook('pre-tool-use', {
120
+ tool_name: 'Bash',
121
+ tool_input: { command: 'dbt show --select my_model' },
122
+ });
123
+ expect(r.parsed && r.parsed.hookSpecificOutput).toBeTruthy();
124
+ expect(r.parsed.hookSpecificOutput.permissionDecision).toBe('allow');
125
+ const s = readAutoState();
126
+ expect(s.tool_budget_remaining).toBe(4);
127
+ });
128
+
129
+ it('PreToolUse passes through non-allowlisted tool', () => {
130
+ const t = writeTranscript('::AUTO-VERIFY:: agent=data-modeller phase=6');
131
+ runHook('stop', { transcript_path: t, session_id: 's1' });
132
+ // A Write tool call should NOT be auto-approved.
133
+ const r = runHook('pre-tool-use', {
134
+ tool_name: 'Write',
135
+ tool_input: { file_path: '/x.sql' },
136
+ });
137
+ expect(r.parsed).toBeNull();
138
+ // Budget should not have decremented.
139
+ const s = readAutoState();
140
+ expect(s.tool_budget_remaining).toBe(20);
141
+ });
142
+
143
+ it('PreToolUse rejects dbt build (writes never auto-approved)', () => {
144
+ const t = writeTranscript('::AUTO-VERIFY:: agent=ae phase=7');
145
+ runHook('stop', { transcript_path: t, session_id: 's1' });
146
+ const r = runHook('pre-tool-use', {
147
+ tool_name: 'Bash',
148
+ tool_input: { command: 'dbt build --select my_model' },
149
+ });
150
+ expect(r.parsed).toBeNull();
151
+ });
152
+
153
+ it('PreToolUse rejects dbt run', () => {
154
+ const t = writeTranscript('::AUTO-VERIFY:: agent=ae phase=7');
155
+ runHook('stop', { transcript_path: t, session_id: 's1' });
156
+ const r = runHook('pre-tool-use', {
157
+ tool_name: 'Bash',
158
+ tool_input: { command: 'dbt run --select my_model' },
159
+ });
160
+ expect(r.parsed).toBeNull();
161
+ });
162
+
163
+ it('PreToolUse approves SELECT-only psql -c', () => {
164
+ const t = writeTranscript('::AUTO-VERIFY:: agent=da phase=3');
165
+ runHook('stop', { transcript_path: t, session_id: 's1' });
166
+ const r = runHook('pre-tool-use', {
167
+ tool_name: 'Bash',
168
+ tool_input: { command: 'psql -c "SELECT count(*) FROM events"' },
169
+ });
170
+ expect(r.parsed && r.parsed.hookSpecificOutput).toBeTruthy();
171
+ expect(r.parsed.hookSpecificOutput.permissionDecision).toBe('allow');
172
+ });
173
+
174
+ it('PreToolUse rejects INSERT via psql', () => {
175
+ const t = writeTranscript('::AUTO-VERIFY:: agent=da phase=3');
176
+ runHook('stop', { transcript_path: t, session_id: 's1' });
177
+ const r = runHook('pre-tool-use', {
178
+ tool_name: 'Bash',
179
+ tool_input: { command: 'psql -c "INSERT INTO events VALUES (1)"' },
180
+ });
181
+ expect(r.parsed).toBeNull();
182
+ });
183
+
184
+ it('Gate open suspends auto-verify (gates win)', () => {
185
+ // Open both auto-verify and gate
186
+ const t1 = writeTranscript('::AUTO-VERIFY:: agent=ae phase=7 tool_budget=5');
187
+ runHook('stop', { transcript_path: t1, session_id: 's1' });
188
+ const t2 = writeTranscript(
189
+ '::GATE:: id=test-gate phase=7 kind=phase agent=ae\nbody\n::ENDGATE::'
190
+ );
191
+ runHook('stop', { transcript_path: t2, session_id: 's1' });
192
+ expect(readGateState().open).toBe(true);
193
+ expect(readAutoState().open).toBe(true);
194
+
195
+ // Tool call should be BLOCKED by gate (not auto-approved). The hook
196
+ // returns the canonical PreToolUse contract — hookSpecificOutput.permission
197
+ // Decision: 'deny' — not the legacy `decision: 'block'` form.
198
+ const r = runHook('pre-tool-use', {
199
+ tool_name: 'Bash',
200
+ tool_input: { command: 'dbt show --select my_model' },
201
+ // Same session that opened the gate — under the v2 per-session model the
202
+ // gate only blocks its own session, so the session_id must match.
203
+ session_id: 's1',
204
+ });
205
+ expect(r.parsed && r.parsed.hookSpecificOutput).toBeTruthy();
206
+ expect(r.parsed.hookSpecificOutput.permissionDecision).toBe('deny');
207
+ expect(r.parsed.hookSpecificOutput.permissionDecisionReason).toMatch(/GATE-BLOCK/);
208
+ });
209
+
210
+ it('Tool budget exhaustion closes block', () => {
211
+ const t = writeTranscript('::AUTO-VERIFY:: agent=da phase=3 tool_budget=2');
212
+ runHook('stop', { transcript_path: t, session_id: 's1' });
213
+ // Use 2 approvals
214
+ for (let i = 0; i < 2; i++) {
215
+ runHook('pre-tool-use', {
216
+ tool_name: 'Bash', tool_input: { command: 'dbt show' },
217
+ });
218
+ }
219
+ // Third call: budget is 0 → isExpired returns true → block closes, falls through
220
+ const r = runHook('pre-tool-use', {
221
+ tool_name: 'Bash', tool_input: { command: 'dbt show' },
222
+ });
223
+ expect(r.parsed).toBeNull();
224
+ expect(readAutoState().open).toBe(false);
225
+ });
226
+
227
+ it('SHARDS_AUTO_VERIFY=0 disables the branch', () => {
228
+ // Open without env disabled
229
+ const t = writeTranscript('::AUTO-VERIFY:: agent=da phase=3');
230
+ runHook('stop', { transcript_path: t, session_id: 's1' }, { SHARDS_AUTO_VERIFY: '0' });
231
+ // State should NOT have been written
232
+ expect(readAutoState().open).toBe(false);
233
+ });
234
+
235
+ it('User halt prompt closes auto-verify', () => {
236
+ const t = writeTranscript('::AUTO-VERIFY:: agent=da phase=3');
237
+ runHook('stop', { transcript_path: t, session_id: 's1' });
238
+ expect(readAutoState().open).toBe(true);
239
+ runHook('user-prompt-submit', { prompt: 'stop, hold on a moment' });
240
+ expect(readAutoState().open).toBe(false);
241
+ });
242
+
243
+ it('Compound bash command is rejected (no auto-approve on rm via &&)', () => {
244
+ const t = writeTranscript('::AUTO-VERIFY:: agent=da phase=3');
245
+ runHook('stop', { transcript_path: t, session_id: 's1' });
246
+ const r = runHook('pre-tool-use', {
247
+ tool_name: 'Bash',
248
+ tool_input: { command: 'dbt show && rm -rf /tmp/foo' },
249
+ });
250
+ expect(r.parsed).toBeNull();
251
+ });
252
+
253
+ it('Read tool always auto-approves when block open', () => {
254
+ const t = writeTranscript('::AUTO-VERIFY:: agent=da phase=3');
255
+ runHook('stop', { transcript_path: t, session_id: 's1' });
256
+ const r = runHook('pre-tool-use', {
257
+ tool_name: 'Read',
258
+ tool_input: { file_path: '/x' },
259
+ });
260
+ expect(r.parsed && r.parsed.hookSpecificOutput.permissionDecision).toBe('allow');
261
+ });
262
+
263
+ it('Write tool blocked even with auto-verify open', () => {
264
+ const t = writeTranscript('::AUTO-VERIFY:: agent=da phase=3');
265
+ runHook('stop', { transcript_path: t, session_id: 's1' });
266
+ const r = runHook('pre-tool-use', {
267
+ tool_name: 'Write',
268
+ tool_input: { file_path: '/x' },
269
+ });
270
+ expect(r.parsed).toBeNull();
271
+ });
272
+
273
+ it('Auto-verify clamps tool_budget to AUTO_MAX_TOOL_BUDGET', () => {
274
+ const t = writeTranscript('::AUTO-VERIFY:: agent=da phase=3 tool_budget=999');
275
+ runHook('stop', { transcript_path: t, session_id: 's1' });
276
+ const s = readAutoState();
277
+ expect(s.tool_budget_initial).toBe(50);
278
+ });
279
+
280
+ it('reads real Claude Code transcript shape ({type, message: {role, content}})', () => {
281
+ // This is the canonical regression test — the actual transcript shape Claude
282
+ // Code writes. transcript.js previously only matched the legacy {role, content}
283
+ // shape, which silently broke gate + auto-verify enforcement.
284
+ const transcript = writeTranscript(
285
+ '::AUTO-VERIFY:: agent=data-modeller phase=6 tool_budget=5',
286
+ 'real'
287
+ );
288
+ runHook('stop', { transcript_path: transcript, session_id: 's1' });
289
+ const s = readAutoState();
290
+ expect(s.open).toBe(true);
291
+ expect(s.tool_budget_remaining).toBe(5);
292
+ });
293
+
294
+ it('reads legacy transcript shape for backward compat', () => {
295
+ const transcript = writeTranscript(
296
+ '::AUTO-VERIFY:: agent=data-modeller phase=6 tool_budget=5',
297
+ 'legacy'
298
+ );
299
+ runHook('stop', { transcript_path: transcript, session_id: 's1' });
300
+ const s = readAutoState();
301
+ expect(s.open).toBe(true);
302
+ });
303
+
304
+ it('open+close in same message: end state is closed', () => {
305
+ const transcript = writeTranscript(
306
+ '::AUTO-VERIFY:: agent=da phase=3 tool_budget=5\nverification done\n::ENDAUTO::'
307
+ );
308
+ runHook('stop', { transcript_path: transcript, session_id: 's1' });
309
+ const s = readAutoState();
310
+ expect(s.open).toBe(false);
311
+ expect(Array.isArray(s.history) && s.history.length >= 1).toBe(true);
312
+ });
313
+
314
+ it('close+open in same message: end state is open (re-opened)', () => {
315
+ // First open a block in turn 1
316
+ const t1 = writeTranscript('::AUTO-VERIFY:: agent=da phase=3 tool_budget=5');
317
+ runHook('stop', { transcript_path: t1, session_id: 's1' });
318
+ expect(readAutoState().open).toBe(true);
319
+ // Turn 2 closes the previous and opens a new one
320
+ const t2 = writeTranscript(
321
+ '::ENDAUTO::\n\n::AUTO-VERIFY:: agent=da phase=3 tool_budget=10'
322
+ );
323
+ runHook('stop', { transcript_path: t2, session_id: 's1' });
324
+ const s = readAutoState();
325
+ expect(s.open).toBe(true);
326
+ expect(s.tool_budget_initial).toBe(10);
327
+ });
328
+
329
+ it('audit log written to .shards/auto/history.jsonl', () => {
330
+ const t = writeTranscript('::AUTO-VERIFY:: agent=da phase=3');
331
+ runHook('stop', { transcript_path: t, session_id: 's1' });
332
+ runHook('pre-tool-use', {
333
+ tool_name: 'Bash',
334
+ tool_input: { command: 'dbt show --select x' },
335
+ });
336
+ const log = path.join(tmp, '.shards', 'auto', 'history.jsonl');
337
+ expect(fs.existsSync(log)).toBe(true);
338
+ const lines = fs.readFileSync(log, 'utf8').trim().split('\n');
339
+ const events = lines.map(l => JSON.parse(l));
340
+ expect(events.some(e => e.event === 'opened')).toBe(true);
341
+ expect(events.some(e => e.event === 'auto-approved' && e.tool === 'Bash')).toBe(true);
342
+ });
343
+ });
@@ -0,0 +1,179 @@
1
+ // Hardcoded read-only allowlist for auto-verify mode.
2
+ //
3
+ // Returns true ONLY for tool calls that are confirmed safe verification
4
+ // operations. Everything else falls through to the normal permission prompt.
5
+ //
6
+ // This list is intentionally NOT user-configurable. Users can extend the
7
+ // session-wide allowlist via .claude/settings.json permissions.allow[]
8
+ // (which Claude Code already honors before the hook fires). Auto-verify
9
+ // is for the *additional* operations agents do during bulk verification
10
+ // stretches that would otherwise spam prompts.
11
+ 'use strict';
12
+
13
+ const sqlGuard = require('./sql-guard.js');
14
+
15
+ // Tools that are always read-only.
16
+ const READ_ONLY_TOOLS = new Set([
17
+ 'Read', 'Glob', 'Grep', 'WebSearch',
18
+ ]);
19
+
20
+ // Bash command prefixes that are read-only verification operations.
21
+ // Matched as: command.trim() === prefix || command.startsWith(prefix + ' ')
22
+ // Use the most specific prefix (e.g. "dbt show" not just "dbt") so that
23
+ // destructive subcommands like "dbt run" or "dbt build" are NOT matched.
24
+ const READ_ONLY_BASH_PREFIXES = [
25
+ // dbt — read-only subcommands only
26
+ 'dbt show',
27
+ 'dbt ls',
28
+ 'dbt list',
29
+ 'dbt parse',
30
+ 'dbt compile',
31
+ 'dbt deps',
32
+ 'dbt debug',
33
+ 'dbt source freshness',
34
+
35
+ // BigQuery CLI — metadata reads
36
+ 'bq show',
37
+ 'bq ls',
38
+ 'bq head',
39
+
40
+ // git — already in the readonly preset, but listed here too as a
41
+ // belt-and-braces guarantee for users who edited their settings.json.
42
+ // Only read-only subcommand forms: bare `git branch`/`git tag`/`git remote`
43
+ // also match -d/-D/-m/-M, add/remove/set-url, and positional-arg creation.
44
+ 'git status',
45
+ 'git log',
46
+ 'git diff',
47
+ 'git show',
48
+ 'git rev-parse',
49
+ 'git stash list',
50
+ 'git branch --list',
51
+ 'git branch -a',
52
+ 'git branch -r',
53
+ 'git branch -v',
54
+ 'git branch -vv',
55
+ 'git branch --remotes',
56
+ 'git branch --merged',
57
+ 'git branch --no-merged',
58
+ 'git branch --show-current',
59
+ 'git branch --contains',
60
+ 'git tag --list',
61
+ 'git tag -l',
62
+ 'git remote -v',
63
+ 'git remote show',
64
+ 'git remote get-url',
65
+
66
+ // python/pip metadata
67
+ 'pip list',
68
+ 'pip show',
69
+ 'pip freeze',
70
+
71
+ // node/npm metadata
72
+ 'npm ls',
73
+ 'npm list',
74
+ 'npm outdated',
75
+ 'npm view',
76
+
77
+ // generic file inspection
78
+ 'ls', 'cat', 'head', 'tail', 'wc', 'file', 'stat',
79
+ ];
80
+
81
+ // Bash patterns that indicate destructive intent. Even if a more permissive
82
+ // prefix matches above, these veto the auto-approval. Belt-and-braces.
83
+ const DESTRUCTIVE_MARKERS = [
84
+ /\brm\b/, /\bmv\b/, /\bcp\s+-/, // basic destructive
85
+ />\s*[^|]/, // shell redirect to file
86
+ />>\s*/, // append redirect
87
+ /\bsudo\b/,
88
+ /\bcurl\b/, /\bwget\b/, // network fetches that may exfiltrate
89
+ /\|\s*sh\b/, /\|\s*bash\b/, // pipe-to-shell
90
+ /\$\([^)]/, // command substitution — bail (could hide anything)
91
+ /`[^`]/, // backtick command substitution
92
+ // find — -delete and -exec/-execdir/-ok/-okdir run arbitrary (often
93
+ // destructive) work with no `rm`/`;` present to trip the other markers;
94
+ // -fprint/-fprint0/-fprintf/-fls write output to a file (path-controlled
95
+ // write). `-ok` must not match `-okdir` (its exec-per-file prompt sibling),
96
+ // and `-fprint` must not match `-fprintf`, so each is listed separately;
97
+ // `-printf`/`-ls`/`-print0` (stdout-only forms) stay read-only.
98
+ /\s-delete\b/,
99
+ /\s-exec\b/,
100
+ /\s-execdir\b/,
101
+ /\s-ok\b/,
102
+ /\s-okdir\b/,
103
+ /\s-fprint(?:0)?\b/,
104
+ /\s-fprintf\b/,
105
+ /\s-fls\b/,
106
+ // git branch — the `-v`/`-vv` listing forms silently become CREATES when a
107
+ // bare branch name follows (`git branch -v feature` creates `feature`).
108
+ // Listing with `-v`/`-vv` never takes a positional, so any non-option token
109
+ // right after them is a create intent.
110
+ /\bgit\s+branch\s+-v+\s+[^\s-]/,
111
+ // git diff/show/log — --output=FILE / --output FILE / -o FILE silently
112
+ // writes a patch file. `--output-indicator-*` (a read-only diff styling
113
+ // flag) must not match.
114
+ /--output(?=\s|=)/,
115
+ /\bgit\s+(?:diff|show|log)\b[^\n]*\s-o(?=\s*\S)/,
116
+ ];
117
+
118
+ // Compound separator detection — a single allow shouldn't authorize
119
+ // `safe-cmd && rm -rf /`. If we see compound separators, bail.
120
+ // Covers `&&`, `||`, `;`, `|`, a lone backgrounding `&` (`cat x & rm ...`),
121
+ // and a literal newline (a command separator in bash when the model emits a
122
+ // multi-line tool call). `&&`/`||` are matched by their own alternatives so
123
+ // lone `&`/`|` (e.g. inside `$((..))` arithmetic) can't double-match.
124
+ const COMPOUND_SEPARATORS = /(\&\&|\|\||[;&\n]|\|(?!\|))/;
125
+
126
+ function isAutoApprovable(toolName, toolInput) {
127
+ if (!toolName) return false;
128
+
129
+ // Always-safe tools
130
+ if (READ_ONLY_TOOLS.has(toolName)) return true;
131
+
132
+ if (toolName !== 'Bash') return false;
133
+ if (!toolInput || typeof toolInput.command !== 'string') return false;
134
+
135
+ const cmd = toolInput.command.trim();
136
+ if (!cmd) return false;
137
+
138
+ // Reject compound commands outright. A user-facing rule should match each
139
+ // subcommand independently; we don't try to split-and-recheck because that
140
+ // gets risky. Agents doing verification should run one statement at a time.
141
+ if (COMPOUND_SEPARATORS.test(cmd)) {
142
+ // Special case: SQL guard already handles `;`-separated SELECT statements
143
+ // inside a quoted argument. The compound check fires on bare shell `;`.
144
+ // SQL invocations have the `;` *inside* a quoted SQL string, so the bare
145
+ // shell-level check would match. We give SQL guard first crack:
146
+ if (sqlGuard.isReadOnlyCliInvocation(cmd)) return true;
147
+ return false;
148
+ }
149
+
150
+ // Destructive markers veto.
151
+ for (const re of DESTRUCTIVE_MARKERS) {
152
+ if (re.test(cmd)) {
153
+ // Same SQL-guard exception: a SELECT may legitimately reference a column
154
+ // called `rm` or contain `>`. But destructive markers in non-SQL Bash
155
+ // commands are hard veto.
156
+ if (sqlGuard.isReadOnlyCliInvocation(cmd)) return true;
157
+ return false;
158
+ }
159
+ }
160
+
161
+ // Prefix match against the read-only list.
162
+ for (const prefix of READ_ONLY_BASH_PREFIXES) {
163
+ if (cmd === prefix) return true;
164
+ if (cmd.startsWith(prefix + ' ')) return true;
165
+ }
166
+
167
+ // bq query --dry_run is a metadata-only call.
168
+ if (/^bq\s+query\b/.test(cmd) && /--dry_run\b/.test(cmd)) {
169
+ // Dry-run still doesn't write. Allow.
170
+ return true;
171
+ }
172
+
173
+ // SELECT-only warehouse-CLI SQL.
174
+ if (sqlGuard.isReadOnlyCliInvocation(cmd)) return true;
175
+
176
+ return false;
177
+ }
178
+
179
+ module.exports = { isAutoApprovable, READ_ONLY_BASH_PREFIXES, READ_ONLY_TOOLS };
@@ -0,0 +1,68 @@
1
+ // Auto-verify state read/write for .shards/auto/state.json
2
+ 'use strict';
3
+
4
+ const fs = require('fs');
5
+ const path = require('path');
6
+
7
+ const AUTO_DIR = path.join(process.cwd(), '.shards', 'auto');
8
+ const STATE = path.join(AUTO_DIR, 'state.json');
9
+
10
+ function ensureDir() {
11
+ fs.mkdirSync(AUTO_DIR, { recursive: true });
12
+ }
13
+
14
+ function read() {
15
+ try {
16
+ return JSON.parse(fs.readFileSync(STATE, 'utf8'));
17
+ } catch {
18
+ return { open: false, history: [] };
19
+ }
20
+ }
21
+
22
+ // Atomic write via tmp + rename. See state.js for rationale. Concurrent UI
23
+ // polls and hook invocations would otherwise observe partial JSON during a
24
+ // bare writeFileSync and silently fall back to { open: false }.
25
+ function write(s) {
26
+ ensureDir();
27
+ const tmp = `${STATE}.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2, 8)}.tmp`;
28
+ try {
29
+ fs.writeFileSync(tmp, JSON.stringify(s, null, 2));
30
+ fs.renameSync(tmp, STATE);
31
+ } catch (err) {
32
+ try { fs.unlinkSync(tmp); } catch {}
33
+ throw err;
34
+ }
35
+ }
36
+
37
+ // Returns true if the auto-verify block has expired (ttl elapsed or budget
38
+ // exhausted). Caller is responsible for closing the state when this returns
39
+ // true.
40
+ function isExpired(s) {
41
+ if (!s || !s.open) return false;
42
+ if (typeof s.tool_budget_remaining === 'number' && s.tool_budget_remaining <= 0) {
43
+ return true;
44
+ }
45
+ if (s.expires_at) {
46
+ return new Date(s.expires_at).getTime() <= Date.now();
47
+ }
48
+ return false;
49
+ }
50
+
51
+ function close(s, reason) {
52
+ const closed_at = new Date().toISOString();
53
+ const historyEntry = {
54
+ id: s.id,
55
+ agent: s.agent,
56
+ phase: s.phase,
57
+ opened_at: s.opened_at,
58
+ closed_at,
59
+ closed_reason: reason,
60
+ approvals_used: (s.tool_budget_initial || 0) - (s.tool_budget_remaining || 0),
61
+ };
62
+ return {
63
+ open: false,
64
+ history: [...(s.history || []), historyEntry],
65
+ };
66
+ }
67
+
68
+ module.exports = { read, write, isExpired, close, STATE, AUTO_DIR };
@@ -0,0 +1,21 @@
1
+ // Classify user prompts as confirm / deny / ambiguous
2
+ 'use strict';
3
+
4
+ const CONFIRM_RE = /^\s*(y|yes|yep|yeah|yup|confirm(ed)?|proceed|go|go ahead|approved|lgtm|ship it|ok|okay|sounds good|looks good|continue|next|advance|move on)\b/i;
5
+ const DENY_RE = /^\s*(n|no|nope|stop|hold|wait|change|revise|actually|not quite|let me)\b/i;
6
+
7
+ // ::GATE-CONFIRM:: <id> — explicit confirm from advanced users
8
+ const EXPLICIT_CONFIRM_RE = /^\s*::GATE-CONFIRM::\s+(\S+)/i;
9
+
10
+ function classify(prompt) {
11
+ if (!prompt || !prompt.trim()) return 'ambiguous';
12
+
13
+ const m = EXPLICIT_CONFIRM_RE.exec(prompt);
14
+ if (m) return 'confirm';
15
+
16
+ if (CONFIRM_RE.test(prompt)) return 'confirm';
17
+ if (DENY_RE.test(prompt)) return 'deny';
18
+ return 'ambiguous';
19
+ }
20
+
21
+ module.exports = { classify };
@@ -0,0 +1,57 @@
1
+ // Append entries to violations.jsonl / gate-history.jsonl
2
+ 'use strict';
3
+
4
+ const fs = require('fs');
5
+ const path = require('path');
6
+
7
+ const GATE_DIR = path.join(process.cwd(), '.shards', 'gates');
8
+
9
+ function ensureDir(dir) {
10
+ fs.mkdirSync(dir, { recursive: true });
11
+ }
12
+
13
+ // Atomic-append: open with O_APPEND and write the full JSON line in a single
14
+ // syscall. POSIX guarantees that writes <= PIPE_BUF (typically 4096 bytes) to
15
+ // a file opened with O_APPEND are atomic with respect to other O_APPEND
16
+ // writers — concurrent gate-hook invocations cannot interleave bytes within a
17
+ // single line. JSONL entries here are well under PIPE_BUF.
18
+ //
19
+ // We deliberately do NOT use fs.appendFileSync here because Node's
20
+ // implementation can fall back to non-atomic open/write/close patterns under
21
+ // some conditions. Doing the open + writeSync + close explicitly is a
22
+ // belt-and-braces guarantee.
23
+ function atomicAppendLine(file, line) {
24
+ let fd;
25
+ try {
26
+ fd = fs.openSync(file, 'a');
27
+ fs.writeSync(fd, line);
28
+ } finally {
29
+ if (typeof fd === 'number') {
30
+ try { fs.closeSync(fd); } catch {}
31
+ }
32
+ }
33
+ }
34
+
35
+ function appendViolation(entry) {
36
+ ensureDir(GATE_DIR);
37
+ const file = path.join(GATE_DIR, 'violations.jsonl');
38
+ const line = JSON.stringify({ ...entry, ts: new Date().toISOString() }) + '\n';
39
+ atomicAppendLine(file, line);
40
+ }
41
+
42
+ function appendHistory(entry) {
43
+ ensureDir(GATE_DIR);
44
+ const file = path.join(GATE_DIR, 'gates.jsonl');
45
+ const line = JSON.stringify({ ...entry, ts: new Date().toISOString() }) + '\n';
46
+ atomicAppendLine(file, line);
47
+ }
48
+
49
+ function appendAutoHistory(entry) {
50
+ const dir = path.join(process.cwd(), '.shards', 'auto');
51
+ ensureDir(dir);
52
+ const file = path.join(dir, 'history.jsonl');
53
+ const line = JSON.stringify({ ...entry, ts: new Date().toISOString() }) + '\n';
54
+ atomicAppendLine(file, line);
55
+ }
56
+
57
+ module.exports = { appendViolation, appendHistory, appendAutoHistory };