@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.
- package/README.md +475 -0
- package/package.json +37 -0
- package/src/agents/academic.md +276 -0
- package/src/agents/ai-engineer.md +377 -0
- package/src/agents/analytics-engineer.md +364 -0
- package/src/agents/applied-ml-scientist.md +410 -0
- package/src/agents/backend-engineer.md +255 -0
- package/src/agents/bi-engineer.md +333 -0
- package/src/agents/data-analyst.md +343 -0
- package/src/agents/data-engineer.md +260 -0
- package/src/agents/data-modeller.md +386 -0
- package/src/agents/data-scientist.md +366 -0
- package/src/agents/deep-learning-engineer.md +389 -0
- package/src/agents/ml-engineer.md +424 -0
- package/src/agents/mlops-engineer.md +339 -0
- package/src/agents/researcher.md +187 -0
- package/src/agents/specific_instructions/academic/critical_review.md +263 -0
- package/src/agents/specific_instructions/academic/report.md +113 -0
- package/src/agents/specific_instructions/ai_engineer/advise.md +162 -0
- package/src/agents/specific_instructions/ai_engineer/bi_engineer_handoff.md +86 -0
- package/src/agents/specific_instructions/ai_engineer/experiment.md +471 -0
- package/src/agents/specific_instructions/ai_engineer/experiment_ui_mode.md +44 -0
- package/src/agents/specific_instructions/ai_engineer/phases/index.md +45 -0
- package/src/agents/specific_instructions/ai_engineer/phases/phase-1.md +55 -0
- package/src/agents/specific_instructions/ai_engineer/phases/phase-2.md +86 -0
- package/src/agents/specific_instructions/ai_engineer/phases/phase-3.md +96 -0
- package/src/agents/specific_instructions/ai_engineer/phases/phase-4.md +138 -0
- package/src/agents/specific_instructions/ai_engineer/phases/phase-5.md +157 -0
- package/src/agents/specific_instructions/ai_engineer/phases/phase-6.md +196 -0
- package/src/agents/specific_instructions/ai_engineer/phases/phase-7.md +313 -0
- package/src/agents/specific_instructions/ai_engineer/phases.md +1011 -0
- package/src/agents/specific_instructions/ai_engineer/prompt_lab.md +161 -0
- package/src/agents/specific_instructions/ai_engineer/prompt_lab_ui_mode.md +28 -0
- package/src/agents/specific_instructions/ai_engineer/research.md +393 -0
- package/src/agents/specific_instructions/ai_engineer/research_ui_mode.md +66 -0
- package/src/agents/specific_instructions/ai_engineer/review.md +159 -0
- package/src/agents/specific_instructions/ai_engineer/validation_checklist.md +182 -0
- package/src/agents/specific_instructions/analytics_engineer/advise.md +155 -0
- package/src/agents/specific_instructions/analytics_engineer/bi_engineer_handoff.md +91 -0
- package/src/agents/specific_instructions/analytics_engineer/data_analyst_handoff.md +84 -0
- package/src/agents/specific_instructions/analytics_engineer/deep_phases.md +818 -0
- package/src/agents/specific_instructions/analytics_engineer/phases_deep/index.md +24 -0
- package/src/agents/specific_instructions/analytics_engineer/phases_deep/phase-1.md +77 -0
- package/src/agents/specific_instructions/analytics_engineer/phases_deep/phase-2.md +106 -0
- package/src/agents/specific_instructions/analytics_engineer/phases_deep/phase-3.md +93 -0
- package/src/agents/specific_instructions/analytics_engineer/phases_deep/phase-4.md +79 -0
- package/src/agents/specific_instructions/analytics_engineer/phases_deep/phase-5.md +61 -0
- package/src/agents/specific_instructions/analytics_engineer/phases_deep/phase-6.md +45 -0
- package/src/agents/specific_instructions/analytics_engineer/phases_deep/phase-7.md +235 -0
- package/src/agents/specific_instructions/analytics_engineer/phases_deep/phase-8.md +221 -0
- package/src/agents/specific_instructions/analytics_engineer/phases_quick/index.md +19 -0
- package/src/agents/specific_instructions/analytics_engineer/phases_quick/phase-1.md +47 -0
- package/src/agents/specific_instructions/analytics_engineer/phases_quick/phase-2.md +78 -0
- package/src/agents/specific_instructions/analytics_engineer/quick_phases.md +112 -0
- package/src/agents/specific_instructions/analytics_engineer/review.md +167 -0
- package/src/agents/specific_instructions/analytics_engineer/service_mode.md +369 -0
- package/src/agents/specific_instructions/analytics_engineer/ui_mode.md +45 -0
- package/src/agents/specific_instructions/analytics_engineer/update.md +162 -0
- package/src/agents/specific_instructions/analytics_engineer/validation_checklist.md +121 -0
- package/src/agents/specific_instructions/applied_ml_scientist/advise.md +143 -0
- package/src/agents/specific_instructions/applied_ml_scientist/phases/index.md +21 -0
- package/src/agents/specific_instructions/applied_ml_scientist/phases/phase-1.md +51 -0
- package/src/agents/specific_instructions/applied_ml_scientist/phases/phase-2.md +66 -0
- package/src/agents/specific_instructions/applied_ml_scientist/phases/phase-3.md +113 -0
- package/src/agents/specific_instructions/applied_ml_scientist/phases/phase-4.md +104 -0
- package/src/agents/specific_instructions/applied_ml_scientist/phases/phase-5.md +156 -0
- package/src/agents/specific_instructions/applied_ml_scientist/phases.md +428 -0
- package/src/agents/specific_instructions/applied_ml_scientist/research.md +379 -0
- package/src/agents/specific_instructions/applied_ml_scientist/review.md +142 -0
- package/src/agents/specific_instructions/applied_ml_scientist/validation_checklist.md +136 -0
- package/src/agents/specific_instructions/backend_engineer/clean.md +149 -0
- package/src/agents/specific_instructions/backend_engineer/review.md +91 -0
- package/src/agents/specific_instructions/backend_engineer/review_checklist.md +54 -0
- package/src/agents/specific_instructions/backend_engineer/service_mode.md +67 -0
- package/src/agents/specific_instructions/bi_engineer/advise.md +137 -0
- package/src/agents/specific_instructions/bi_engineer/data_analyst_handoff.md +77 -0
- package/src/agents/specific_instructions/bi_engineer/incoming_handoff.md +45 -0
- package/src/agents/specific_instructions/bi_engineer/phases/index.md +20 -0
- package/src/agents/specific_instructions/bi_engineer/phases/phase-1.md +164 -0
- package/src/agents/specific_instructions/bi_engineer/phases/phase-2.md +92 -0
- package/src/agents/specific_instructions/bi_engineer/phases/phase-3.md +121 -0
- package/src/agents/specific_instructions/bi_engineer/phases/phase-4.md +106 -0
- package/src/agents/specific_instructions/bi_engineer/phases.md +451 -0
- package/src/agents/specific_instructions/bi_engineer/review.md +166 -0
- package/src/agents/specific_instructions/bi_engineer/update.md +147 -0
- package/src/agents/specific_instructions/bi_engineer/validation_checklist.md +124 -0
- package/src/agents/specific_instructions/data_analyst/advise.md +138 -0
- package/src/agents/specific_instructions/data_analyst/explain.md +221 -0
- package/src/agents/specific_instructions/data_analyst/incoming_handoff.md +40 -0
- package/src/agents/specific_instructions/data_analyst/phases/index.md +20 -0
- package/src/agents/specific_instructions/data_analyst/phases/phase-1.md +159 -0
- package/src/agents/specific_instructions/data_analyst/phases/phase-2.md +112 -0
- package/src/agents/specific_instructions/data_analyst/phases/phase-3.md +265 -0
- package/src/agents/specific_instructions/data_analyst/phases/phase-4.md +100 -0
- package/src/agents/specific_instructions/data_analyst/phases.md +501 -0
- package/src/agents/specific_instructions/data_analyst/review.md +138 -0
- package/src/agents/specific_instructions/data_analyst/ui_mode.md +26 -0
- package/src/agents/specific_instructions/data_analyst/update.md +144 -0
- package/src/agents/specific_instructions/data_analyst/validation_checklist.md +95 -0
- package/src/agents/specific_instructions/data_engineer/advise.md +137 -0
- package/src/agents/specific_instructions/data_engineer/phases.md +466 -0
- package/src/agents/specific_instructions/data_engineer/phases_deep/index.md +23 -0
- package/src/agents/specific_instructions/data_engineer/phases_deep/phase-1.md +49 -0
- package/src/agents/specific_instructions/data_engineer/phases_deep/phase-2.md +93 -0
- package/src/agents/specific_instructions/data_engineer/phases_deep/phase-3.md +55 -0
- package/src/agents/specific_instructions/data_engineer/phases_deep/phase-4.md +48 -0
- package/src/agents/specific_instructions/data_engineer/phases_deep/phase-5.md +40 -0
- package/src/agents/specific_instructions/data_engineer/phases_deep/phase-6.md +102 -0
- package/src/agents/specific_instructions/data_engineer/phases_deep/phase-7.md +87 -0
- package/src/agents/specific_instructions/data_engineer/phases_quick/index.md +19 -0
- package/src/agents/specific_instructions/data_engineer/phases_quick/phase-1.md +45 -0
- package/src/agents/specific_instructions/data_engineer/phases_quick/phase-2.md +54 -0
- package/src/agents/specific_instructions/data_engineer/review.md +135 -0
- package/src/agents/specific_instructions/data_engineer/validation_checklist.md +136 -0
- package/src/agents/specific_instructions/data_modeller/advise.md +137 -0
- package/src/agents/specific_instructions/data_modeller/phases.md +581 -0
- package/src/agents/specific_instructions/data_modeller/phases_deep/index.md +23 -0
- package/src/agents/specific_instructions/data_modeller/phases_deep/phase-1.md +52 -0
- package/src/agents/specific_instructions/data_modeller/phases_deep/phase-2.md +113 -0
- package/src/agents/specific_instructions/data_modeller/phases_deep/phase-3.md +47 -0
- package/src/agents/specific_instructions/data_modeller/phases_deep/phase-4.md +51 -0
- package/src/agents/specific_instructions/data_modeller/phases_deep/phase-5.md +45 -0
- package/src/agents/specific_instructions/data_modeller/phases_deep/phase-6.md +105 -0
- package/src/agents/specific_instructions/data_modeller/phases_deep/phase-7.md +136 -0
- package/src/agents/specific_instructions/data_modeller/phases_quick/index.md +19 -0
- package/src/agents/specific_instructions/data_modeller/phases_quick/phase-1.md +47 -0
- package/src/agents/specific_instructions/data_modeller/phases_quick/phase-2.md +65 -0
- package/src/agents/specific_instructions/data_modeller/review.md +141 -0
- package/src/agents/specific_instructions/data_modeller/service_mode.md +218 -0
- package/src/agents/specific_instructions/data_modeller/validation_checklist.md +125 -0
- package/src/agents/specific_instructions/data_scientist/advise.md +158 -0
- package/src/agents/specific_instructions/data_scientist/bi_engineer_handoff.md +63 -0
- package/src/agents/specific_instructions/data_scientist/experiment.md +482 -0
- package/src/agents/specific_instructions/data_scientist/experiment_ui_mode.md +44 -0
- package/src/agents/specific_instructions/data_scientist/explain.md +247 -0
- package/src/agents/specific_instructions/data_scientist/greenfield_data.md +35 -0
- package/src/agents/specific_instructions/data_scientist/ml_engineer_handoff.md +52 -0
- package/src/agents/specific_instructions/data_scientist/notebook_walkthrough.md +76 -0
- package/src/agents/specific_instructions/data_scientist/phases/index.md +24 -0
- package/src/agents/specific_instructions/data_scientist/phases/phase-1.md +45 -0
- package/src/agents/specific_instructions/data_scientist/phases/phase-2.md +67 -0
- package/src/agents/specific_instructions/data_scientist/phases/phase-3.md +89 -0
- package/src/agents/specific_instructions/data_scientist/phases/phase-4.md +143 -0
- package/src/agents/specific_instructions/data_scientist/phases/phase-5.md +71 -0
- package/src/agents/specific_instructions/data_scientist/phases/phase-6.md +239 -0
- package/src/agents/specific_instructions/data_scientist/phases/phase-7.md +207 -0
- package/src/agents/specific_instructions/data_scientist/phases.md +651 -0
- package/src/agents/specific_instructions/data_scientist/research.md +345 -0
- package/src/agents/specific_instructions/data_scientist/research_ui_mode.md +52 -0
- package/src/agents/specific_instructions/data_scientist/review.md +136 -0
- package/src/agents/specific_instructions/data_scientist/service_mode.md +247 -0
- package/src/agents/specific_instructions/data_scientist/validation_checklist.md +183 -0
- package/src/agents/specific_instructions/deep_learning_engineer/advise.md +145 -0
- package/src/agents/specific_instructions/deep_learning_engineer/phases/index.md +21 -0
- package/src/agents/specific_instructions/deep_learning_engineer/phases/phase-1.md +74 -0
- package/src/agents/specific_instructions/deep_learning_engineer/phases/phase-2.md +98 -0
- package/src/agents/specific_instructions/deep_learning_engineer/phases/phase-3.md +76 -0
- package/src/agents/specific_instructions/deep_learning_engineer/phases/phase-4.md +128 -0
- package/src/agents/specific_instructions/deep_learning_engineer/phases/phase-5.md +292 -0
- package/src/agents/specific_instructions/deep_learning_engineer/phases.md +567 -0
- package/src/agents/specific_instructions/deep_learning_engineer/research.md +389 -0
- package/src/agents/specific_instructions/deep_learning_engineer/review.md +155 -0
- package/src/agents/specific_instructions/deep_learning_engineer/validation_checklist.md +147 -0
- package/src/agents/specific_instructions/ml_engineer/advise.md +174 -0
- package/src/agents/specific_instructions/ml_engineer/bi_engineer_handoff.md +71 -0
- package/src/agents/specific_instructions/ml_engineer/experiment.md +474 -0
- package/src/agents/specific_instructions/ml_engineer/experiment_ui_mode.md +44 -0
- package/src/agents/specific_instructions/ml_engineer/notebook_walkthrough.md +75 -0
- package/src/agents/specific_instructions/ml_engineer/phases/index.md +25 -0
- package/src/agents/specific_instructions/ml_engineer/phases/phase-1.md +49 -0
- package/src/agents/specific_instructions/ml_engineer/phases/phase-2.md +75 -0
- package/src/agents/specific_instructions/ml_engineer/phases/phase-3.md +124 -0
- package/src/agents/specific_instructions/ml_engineer/phases/phase-4.md +279 -0
- package/src/agents/specific_instructions/ml_engineer/phases/phase-5.md +160 -0
- package/src/agents/specific_instructions/ml_engineer/phases/phase-6-5.md +170 -0
- package/src/agents/specific_instructions/ml_engineer/phases/phase-6.md +295 -0
- package/src/agents/specific_instructions/ml_engineer/phases/phase-7.md +337 -0
- package/src/agents/specific_instructions/ml_engineer/phases.md +1068 -0
- package/src/agents/specific_instructions/ml_engineer/research.md +437 -0
- package/src/agents/specific_instructions/ml_engineer/research_ui_mode.md +71 -0
- package/src/agents/specific_instructions/ml_engineer/review.md +187 -0
- package/src/agents/specific_instructions/ml_engineer/service_mode.md +273 -0
- package/src/agents/specific_instructions/ml_engineer/validation_checklist.md +185 -0
- package/src/agents/specific_instructions/mlops_engineer/advise.md +139 -0
- package/src/agents/specific_instructions/mlops_engineer/phases/index.md +23 -0
- package/src/agents/specific_instructions/mlops_engineer/phases/phase-1.md +52 -0
- package/src/agents/specific_instructions/mlops_engineer/phases/phase-2.md +86 -0
- package/src/agents/specific_instructions/mlops_engineer/phases/phase-3.md +105 -0
- package/src/agents/specific_instructions/mlops_engineer/phases/phase-4.md +128 -0
- package/src/agents/specific_instructions/mlops_engineer/phases/phase-5.md +106 -0
- package/src/agents/specific_instructions/mlops_engineer/phases/phase-6.md +128 -0
- package/src/agents/specific_instructions/mlops_engineer/phases/phase-7.md +144 -0
- package/src/agents/specific_instructions/mlops_engineer/phases.md +671 -0
- package/src/agents/specific_instructions/mlops_engineer/review.md +164 -0
- package/src/agents/specific_instructions/mlops_engineer/service_mode.md +81 -0
- package/src/agents/specific_instructions/mlops_engineer/validation_checklist.md +151 -0
- package/src/agents/specific_instructions/researcher/critical_review.md +292 -0
- package/src/agents/specific_instructions/researcher/review_checklist.md +67 -0
- package/src/agents/specific_instructions/researcher/service_mode.md +224 -0
- package/src/agents/specific_instructions/shared/auto_verify_mode.md +141 -0
- package/src/agents/specific_instructions/shared/autonomous_research.md +1289 -0
- package/src/agents/specific_instructions/shared/behavioral_rules.md +36 -0
- package/src/agents/specific_instructions/shared/diverge_protocol.md +387 -0
- package/src/agents/specific_instructions/shared/engineering_guidelines.md +136 -0
- package/src/agents/specific_instructions/shared/experiment_versioning.md +184 -0
- package/src/agents/specific_instructions/shared/goal_mode.md +187 -0
- package/src/agents/specific_instructions/shared/incremental_testing.md +139 -0
- package/src/agents/specific_instructions/shared/intent_discovery.md +223 -0
- package/src/agents/specific_instructions/shared/join_path_protocol.md +168 -0
- package/src/agents/specific_instructions/shared/knowledge_checkpoint.md +83 -0
- package/src/agents/specific_instructions/shared/knowledge_harvest.md +220 -0
- package/src/agents/specific_instructions/shared/knowledge_retrieval.md +100 -0
- package/src/agents/specific_instructions/shared/notebook_walkthrough_protocol.md +367 -0
- package/src/agents/specific_instructions/shared/reviewer_verdict_protocol.md +74 -0
- package/src/agents/specific_instructions/shared/swarm_protocol.md +97 -0
- package/src/agents/specific_instructions/shared/validation_protocol.md +139 -0
- package/src/agents/specific_instructions/syn/arbiter.md +140 -0
- package/src/agents/specific_instructions/syn/brainstorm.md +550 -0
- package/src/agents/specific_instructions/syn/code_review.md +232 -0
- package/src/agents/specific_instructions/syn/diff.md +239 -0
- package/src/agents/specific_instructions/syn/final_review.md +65 -0
- package/src/agents/specific_instructions/syn/fixer.md +240 -0
- package/src/agents/specific_instructions/syn/free_form.md +130 -0
- package/src/agents/specific_instructions/syn/knowledge.md +468 -0
- package/src/agents/specific_instructions/syn/notebook_walkthrough.md +78 -0
- package/src/agents/specific_instructions/syn/panel_review.md +634 -0
- package/src/agents/specific_instructions/syn/pm.md +453 -0
- package/src/agents/specific_instructions/syn/pr_review.md +255 -0
- package/src/agents/specific_instructions/syn/slides.md +417 -0
- package/src/agents/syn.md +729 -0
- package/src/commands/academic.md +41 -0
- package/src/commands/ai-engineer.md +45 -0
- package/src/commands/analytics-engineer.md +48 -0
- package/src/commands/applied-ml-scientist.md +45 -0
- package/src/commands/backend-engineer.md +35 -0
- package/src/commands/bi-engineer.md +40 -0
- package/src/commands/brainstorm.md +24 -0
- package/src/commands/data-analyst.md +38 -0
- package/src/commands/data-engineer.md +37 -0
- package/src/commands/data-modeller.md +38 -0
- package/src/commands/data-scientist.md +38 -0
- package/src/commands/deep-learning-engineer.md +47 -0
- package/src/commands/end.md +49 -0
- package/src/commands/knowledge.md +24 -0
- package/src/commands/ml-engineer.md +42 -0
- package/src/commands/mlops-engineer.md +47 -0
- package/src/commands/notebook-walkthrough.md +58 -0
- package/src/commands/researcher.md +40 -0
- package/src/commands/resume.md +57 -0
- package/src/commands/review-pr.md +26 -0
- package/src/commands/shards-guide.md +41 -0
- package/src/commands/shards-ui.md +32 -0
- package/src/commands/shards.md +41 -0
- package/src/docs/01-getting-started/concepts.md +109 -0
- package/src/docs/01-getting-started/first-session.md +79 -0
- package/src/docs/01-getting-started/install.md +61 -0
- package/src/docs/02-agents/academic.md +71 -0
- package/src/docs/02-agents/ai-engineer.md +78 -0
- package/src/docs/02-agents/analytics-engineer.md +58 -0
- package/src/docs/02-agents/applied-ml-scientist.md +59 -0
- package/src/docs/02-agents/backend-engineer.md +58 -0
- package/src/docs/02-agents/bi-engineer.md +65 -0
- package/src/docs/02-agents/data-analyst.md +67 -0
- package/src/docs/02-agents/data-engineer.md +57 -0
- package/src/docs/02-agents/data-modeller.md +51 -0
- package/src/docs/02-agents/data-scientist.md +78 -0
- package/src/docs/02-agents/deep-learning-engineer.md +64 -0
- package/src/docs/02-agents/ml-engineer.md +80 -0
- package/src/docs/02-agents/mlops-engineer.md +59 -0
- package/src/docs/02-agents/overview.md +62 -0
- package/src/docs/02-agents/researcher.md +73 -0
- package/src/docs/02-agents/syn.md +88 -0
- package/src/docs/03-protocols/auto-verify.md +82 -0
- package/src/docs/03-protocols/autonomous-research.md +59 -0
- package/src/docs/03-protocols/behavioral-rules.md +35 -0
- package/src/docs/03-protocols/diverge.md +50 -0
- package/src/docs/03-protocols/engineering-guidelines.md +56 -0
- package/src/docs/03-protocols/experiment-versioning.md +38 -0
- package/src/docs/03-protocols/gate-pattern.md +65 -0
- package/src/docs/03-protocols/incremental-testing.md +68 -0
- package/src/docs/03-protocols/join-path.md +46 -0
- package/src/docs/03-protocols/knowledge-ledger.md +70 -0
- package/src/docs/03-protocols/reviewer-verdicts.md +39 -0
- package/src/docs/03-protocols/swarm.md +40 -0
- package/src/docs/03-protocols/validation.md +174 -0
- package/src/docs/04-ui/activity-bar.md +70 -0
- package/src/docs/04-ui/chat-pane.md +80 -0
- package/src/docs/04-ui/code-intel.md +62 -0
- package/src/docs/04-ui/file-editing.md +61 -0
- package/src/docs/04-ui/git.md +54 -0
- package/src/docs/04-ui/keybindings.md +79 -0
- package/src/docs/04-ui/knowledge-map.md +76 -0
- package/src/docs/04-ui/overview.md +93 -0
- package/src/docs/04-ui/panels.md +49 -0
- package/src/docs/04-ui/pinboard-selection.md +66 -0
- package/src/docs/04-ui/quick-open-palette.md +56 -0
- package/src/docs/04-ui/sessions.md +81 -0
- package/src/docs/04-ui/settings-permissions.md +56 -0
- package/src/docs/05-commands/reference.md +59 -0
- package/src/docs/06-outputs/directory-map.md +116 -0
- package/src/docs/07-workflows/ai-eval-first.md +57 -0
- package/src/docs/07-workflows/deep-study-to-production.md +76 -0
- package/src/docs/07-workflows/diverge-exploration.md +77 -0
- package/src/docs/07-workflows/quick-analysis.md +45 -0
- package/src/docs/08-integrations/claude-code-auto-mode.md +191 -0
- package/src/docs/08-integrations/google-slides.md +175 -0
- package/src/docs/README.md +30 -0
- package/src/docs/manifest.json +108 -0
- package/src/templates/analysis-template.md +20 -0
- package/src/templates/branch-report.md +46 -0
- package/src/templates/diff-report.md +88 -0
- package/src/templates/knowledge-index.md +7 -0
- package/src/templates/model-card-schema.json +186 -0
- package/src/templates/model-card-schema.md +88 -0
- package/src/templates/model-card.md +124 -0
- package/src/templates/project-plan.md +47 -0
- package/src/templates/project-specs.md +81 -0
- package/src/templates/report-template.md +43 -0
- package/src/templates/study-template.md +25 -0
- package/src/ui/cc-readonly.js +181 -0
- package/src/ui/chat-session.js +466 -0
- package/src/ui/css/base.css +136 -0
- package/src/ui/css/brainstorm.css +525 -0
- package/src/ui/css/chat.css +1405 -0
- package/src/ui/css/editor.css +546 -0
- package/src/ui/css/eval-dashboard.css +157 -0
- package/src/ui/css/experiment.css +237 -0
- package/src/ui/css/guide.css +186 -0
- package/src/ui/css/knowledge-map.css +383 -0
- package/src/ui/css/layout.css +431 -0
- package/src/ui/css/model-card.css +161 -0
- package/src/ui/css/notebook-walkthrough.css +271 -0
- package/src/ui/css/pr-review.css +403 -0
- package/src/ui/css/prompt-lab.css +325 -0
- package/src/ui/css/sessions.css +258 -0
- package/src/ui/css/sidebar.css +661 -0
- package/src/ui/css/terminal.css +113 -0
- package/src/ui/css/theme-light.css +542 -0
- package/src/ui/index.html +389 -0
- package/src/ui/js/agents.js +32 -0
- package/src/ui/js/bookmarks.js +230 -0
- package/src/ui/js/chat.js +1776 -0
- package/src/ui/js/code-intel.js +328 -0
- package/src/ui/js/command-palette.js +142 -0
- package/src/ui/js/events.js +591 -0
- package/src/ui/js/explorer.js +317 -0
- package/src/ui/js/file-view.js +477 -0
- package/src/ui/js/git.js +536 -0
- package/src/ui/js/guide.js +198 -0
- package/src/ui/js/hud.js +75 -0
- package/src/ui/js/init.js +351 -0
- package/src/ui/js/knowledge-map.js +906 -0
- package/src/ui/js/markdown.js +114 -0
- package/src/ui/js/monaco.js +164 -0
- package/src/ui/js/notebook-walkthrough.js +272 -0
- package/src/ui/js/notebook.js +448 -0
- package/src/ui/js/panels.js +2681 -0
- package/src/ui/js/pinboard.js +186 -0
- package/src/ui/js/quick-open.js +164 -0
- package/src/ui/js/selection-context.js +131 -0
- package/src/ui/js/sessions.js +256 -0
- package/src/ui/js/settings.js +476 -0
- package/src/ui/js/split-view.js +82 -0
- package/src/ui/js/state.js +343 -0
- package/src/ui/js/table.js +161 -0
- package/src/ui/js/tabs.js +284 -0
- package/src/ui/js/tabular.js +125 -0
- package/src/ui/js/terminal.js +354 -0
- package/src/ui/js/timeline.js +137 -0
- package/src/ui/js/utils.js +293 -0
- package/src/ui/notebook-kernel.py +790 -0
- package/src/ui/open-browser.js +55 -0
- package/src/ui/permission-pattern.js +42 -0
- package/src/ui/relay.js +513 -0
- package/src/ui/server.js +3072 -0
- package/src/ui/session-index.js +225 -0
- package/src/ui/shards_icon.png +0 -0
- package/src/ui/spawn-server.js +41 -0
- package/src/ui/symbol-index.js +813 -0
- package/src/ui/ui-push.js +177 -0
- package/tools/gate-hook/VALIDATION_SPEC.md +273 -0
- package/tools/gate-hook/__tests__/auto-verify.test.js +343 -0
- package/tools/gate-hook/auto-allowlist.js +179 -0
- package/tools/gate-hook/auto-state.js +68 -0
- package/tools/gate-hook/classify.js +21 -0
- package/tools/gate-hook/log.js +57 -0
- package/tools/gate-hook/parser.js +205 -0
- package/tools/gate-hook/sql-guard.js +230 -0
- package/tools/gate-hook/state.js +170 -0
- package/tools/gate-hook/sweep.js +139 -0
- package/tools/gate-hook/transcript.js +45 -0
- package/tools/gate-hook/validation.js +321 -0
- package/tools/gate-hook.js +475 -0
- package/tools/install.js +914 -0
- package/tools/shards-gates.js +311 -0
- package/tools/shards-sessions.js +261 -0
- package/tools/shards-ui.js +377 -0
package/tools/install.js
ADDED
|
@@ -0,0 +1,914 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
|
|
6
|
+
// ─── Constants ───────────────────────────────────────────────────────────────
|
|
7
|
+
|
|
8
|
+
const PACKAGE_ROOT = path.resolve(__dirname, "..");
|
|
9
|
+
const SRC_DIR = path.join(PACKAGE_ROOT, "src");
|
|
10
|
+
|
|
11
|
+
// Target is always the current working directory (where the user ran npx from)
|
|
12
|
+
const PROJECT_DIR = process.cwd();
|
|
13
|
+
const CLAUDE_DIR = path.join(PROJECT_DIR, ".claude");
|
|
14
|
+
|
|
15
|
+
const AGENTS_SRC = path.join(SRC_DIR, "agents");
|
|
16
|
+
const COMMANDS_SRC = path.join(SRC_DIR, "commands");
|
|
17
|
+
const TEMPLATES_SRC = path.join(SRC_DIR, "templates");
|
|
18
|
+
const UI_SRC = path.join(SRC_DIR, "ui");
|
|
19
|
+
const DOCS_SRC = path.join(SRC_DIR, "docs");
|
|
20
|
+
|
|
21
|
+
const AGENTS_DEST = path.join(CLAUDE_DIR, "agents");
|
|
22
|
+
const COMMANDS_DEST = path.join(CLAUDE_DIR, "commands");
|
|
23
|
+
const TEMPLATES_DEST = path.join(PROJECT_DIR, "templates");
|
|
24
|
+
const SHARDS_DIR = path.join(PROJECT_DIR, ".shards");
|
|
25
|
+
const UI_DEST = path.join(SHARDS_DIR, "ui");
|
|
26
|
+
const UI_DOCS_DEST = path.join(UI_DEST, "docs");
|
|
27
|
+
const DOCS_DEST = path.join(PROJECT_DIR, "docs", "shards-guide");
|
|
28
|
+
const HOOKS_DEST = path.join(SHARDS_DIR, "hooks");
|
|
29
|
+
|
|
30
|
+
const MANIFEST_NAME = ".shards-manifest.json";
|
|
31
|
+
|
|
32
|
+
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
33
|
+
|
|
34
|
+
// Directories that should never be installed (test artifacts, dev tooling).
|
|
35
|
+
const SKIP_DIRS = new Set(['__tests__', '__mocks__', 'node_modules', '.git']);
|
|
36
|
+
|
|
37
|
+
function copyDir(src, dest) {
|
|
38
|
+
if (!fs.existsSync(src)) return 0;
|
|
39
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
40
|
+
let count = 0;
|
|
41
|
+
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
42
|
+
if (entry.isDirectory() && SKIP_DIRS.has(entry.name)) continue;
|
|
43
|
+
const srcPath = path.join(src, entry.name);
|
|
44
|
+
const destPath = path.join(dest, entry.name);
|
|
45
|
+
if (entry.isDirectory()) {
|
|
46
|
+
count += copyDir(srcPath, destPath);
|
|
47
|
+
} else {
|
|
48
|
+
if (fs.existsSync(destPath)) {
|
|
49
|
+
const existing = fs.readFileSync(destPath);
|
|
50
|
+
const incoming = fs.readFileSync(srcPath);
|
|
51
|
+
if (existing.equals(incoming)) {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
const backupPath = destPath + ".backup";
|
|
55
|
+
fs.copyFileSync(destPath, backupPath);
|
|
56
|
+
console.log(
|
|
57
|
+
` ⚠ Backed up existing: ${path.relative(PROJECT_DIR, destPath)} → .backup`
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
fs.copyFileSync(srcPath, destPath);
|
|
61
|
+
count++;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return count;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function listFiles(dir, prefix = "") {
|
|
68
|
+
if (!fs.existsSync(dir)) return [];
|
|
69
|
+
const results = [];
|
|
70
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
71
|
+
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
72
|
+
if (entry.isDirectory()) {
|
|
73
|
+
results.push(...listFiles(path.join(dir, entry.name), rel));
|
|
74
|
+
} else {
|
|
75
|
+
results.push(rel);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return results;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// ─── Uninstall ───────────────────────────────────────────────────────────────
|
|
82
|
+
|
|
83
|
+
function uninstall() {
|
|
84
|
+
console.log("\n🗑 Uninstalling shards...\n");
|
|
85
|
+
|
|
86
|
+
const manifestPath = path.join(CLAUDE_DIR, MANIFEST_NAME);
|
|
87
|
+
if (!fs.existsSync(manifestPath)) {
|
|
88
|
+
console.log(" No installation manifest found. Nothing to uninstall.");
|
|
89
|
+
process.exit(0);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
|
|
93
|
+
let removed = 0;
|
|
94
|
+
|
|
95
|
+
for (const filePath of manifest.files || []) {
|
|
96
|
+
const fullPath = path.join(PROJECT_DIR, filePath);
|
|
97
|
+
if (fs.existsSync(fullPath)) {
|
|
98
|
+
fs.unlinkSync(fullPath);
|
|
99
|
+
console.log(` ✓ Removed: ${filePath}`);
|
|
100
|
+
removed++;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Remove shards-installed hook entries from settings.json.
|
|
105
|
+
//
|
|
106
|
+
// Preferred: exact-match removal using the `hookEntries` field recorded by
|
|
107
|
+
// the installer in the manifest. Each recorded entry has { event, matcher,
|
|
108
|
+
// command } that we strip surgically.
|
|
109
|
+
//
|
|
110
|
+
// Fallback (legacy manifests without `hookEntries`): substring filter on
|
|
111
|
+
// both `gate-hook.js` and `.shards/ui/relay.js`. Necessary because old
|
|
112
|
+
// installs predate the exact-match recording.
|
|
113
|
+
const settingsPath = path.join(CLAUDE_DIR, "settings.json");
|
|
114
|
+
if (fs.existsSync(settingsPath)) {
|
|
115
|
+
try {
|
|
116
|
+
let settings = JSON.parse(fs.readFileSync(settingsPath, "utf8"));
|
|
117
|
+
if (settings.hooks) {
|
|
118
|
+
const recordedEntries = Array.isArray(manifest.hookEntries)
|
|
119
|
+
? manifest.hookEntries
|
|
120
|
+
: null;
|
|
121
|
+
|
|
122
|
+
const stripFromEvent = (eventName) => {
|
|
123
|
+
if (!Array.isArray(settings.hooks[eventName])) return;
|
|
124
|
+
settings.hooks[eventName] = settings.hooks[eventName].filter((entry) => {
|
|
125
|
+
if (!entry.hooks) return true;
|
|
126
|
+
if (recordedEntries) {
|
|
127
|
+
// Exact-match path: drop the entry only if all of its inner
|
|
128
|
+
// hooks match a recorded (event, matcher, command) triple.
|
|
129
|
+
const allMatchRecorded = entry.hooks.every((h) =>
|
|
130
|
+
recordedEntries.some(
|
|
131
|
+
(rec) =>
|
|
132
|
+
rec.event === eventName &&
|
|
133
|
+
(rec.matcher || "") === (entry.matcher || "") &&
|
|
134
|
+
rec.command === h.command
|
|
135
|
+
)
|
|
136
|
+
);
|
|
137
|
+
return !allMatchRecorded;
|
|
138
|
+
}
|
|
139
|
+
// Legacy substring fallback.
|
|
140
|
+
return !entry.hooks.some(
|
|
141
|
+
(h) =>
|
|
142
|
+
h.command &&
|
|
143
|
+
(h.command.includes("gate-hook.js") ||
|
|
144
|
+
h.command.includes(".shards/ui/relay.js"))
|
|
145
|
+
);
|
|
146
|
+
});
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
stripFromEvent("Stop");
|
|
150
|
+
stripFromEvent("PreToolUse");
|
|
151
|
+
stripFromEvent("UserPromptSubmit");
|
|
152
|
+
stripFromEvent("PostToolUse");
|
|
153
|
+
}
|
|
154
|
+
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
155
|
+
console.log(" ✓ Removed shards hook entries from .claude/settings.json");
|
|
156
|
+
} catch {}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Remove .shards/hooks/
|
|
160
|
+
const hooksDir = path.join(PROJECT_DIR, ".shards", "hooks");
|
|
161
|
+
if (fs.existsSync(hooksDir)) {
|
|
162
|
+
fs.rmSync(hooksDir, { recursive: true });
|
|
163
|
+
console.log(" ✓ Removed .shards/hooks/");
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
fs.unlinkSync(manifestPath);
|
|
167
|
+
console.log(`\n✅ Uninstalled ${removed} files.`);
|
|
168
|
+
console.log(` ℹ .shards/knowledge/ preserved (persistent workspace memory)\n`);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// ─── Install ─────────────────────────────────────────────────────────────────
|
|
172
|
+
|
|
173
|
+
function install() {
|
|
174
|
+
console.log(`
|
|
175
|
+
╔══════════════════════════════════════════╗
|
|
176
|
+
║ shards — installer ║
|
|
177
|
+
║ Shards of Syn's brain ║
|
|
178
|
+
╚══════════════════════════════════════════╝
|
|
179
|
+
`);
|
|
180
|
+
console.log(` Project directory: ${PROJECT_DIR}`);
|
|
181
|
+
console.log(` Installing to: ${CLAUDE_DIR}\n`);
|
|
182
|
+
|
|
183
|
+
// 1. Create .claude directory structure
|
|
184
|
+
fs.mkdirSync(AGENTS_DEST, { recursive: true });
|
|
185
|
+
fs.mkdirSync(COMMANDS_DEST, { recursive: true });
|
|
186
|
+
|
|
187
|
+
// 2. Copy agents
|
|
188
|
+
console.log("📦 Installing agents...");
|
|
189
|
+
const agentCount = copyDir(AGENTS_SRC, AGENTS_DEST);
|
|
190
|
+
const agentFiles = listFiles(AGENTS_SRC);
|
|
191
|
+
for (const f of agentFiles) {
|
|
192
|
+
console.log(` ✓ .claude/agents/${f}`);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// 3. Copy commands (slash commands)
|
|
196
|
+
console.log("\n📦 Installing commands...");
|
|
197
|
+
const cmdCount = copyDir(COMMANDS_SRC, COMMANDS_DEST);
|
|
198
|
+
const cmdFiles = listFiles(COMMANDS_SRC);
|
|
199
|
+
for (const f of cmdFiles) {
|
|
200
|
+
console.log(` ✓ .claude/commands/${f}`);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// 4. Copy templates
|
|
204
|
+
console.log("\n📦 Installing templates...");
|
|
205
|
+
const tplCount = copyDir(TEMPLATES_SRC, TEMPLATES_DEST);
|
|
206
|
+
const tplFiles = listFiles(TEMPLATES_SRC);
|
|
207
|
+
for (const f of tplFiles) {
|
|
208
|
+
console.log(` ✓ templates/${f}`);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// 5. Copy UI files
|
|
212
|
+
console.log("\n📦 Installing UI...");
|
|
213
|
+
const uiCount = copyDir(UI_SRC, UI_DEST);
|
|
214
|
+
const uiFiles = listFiles(UI_SRC);
|
|
215
|
+
for (const f of uiFiles) {
|
|
216
|
+
console.log(` ✓ .shards/ui/${f}`);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// 5a. Copy developer guide docs into two places:
|
|
220
|
+
// 1) .shards/ui/docs/ — served by the UI guide panel
|
|
221
|
+
// 2) docs/shards-guide/ — readable as plain markdown outside the UI
|
|
222
|
+
console.log("\n📦 Installing Developer Guide...");
|
|
223
|
+
const uiDocsCount = copyDir(DOCS_SRC, UI_DOCS_DEST);
|
|
224
|
+
const docsCount = copyDir(DOCS_SRC, DOCS_DEST);
|
|
225
|
+
const docFiles = listFiles(DOCS_SRC);
|
|
226
|
+
for (const f of docFiles) {
|
|
227
|
+
console.log(` ✓ .shards/ui/docs/${f}`);
|
|
228
|
+
}
|
|
229
|
+
if (docFiles.length > 0) {
|
|
230
|
+
console.log(` ✓ docs/shards-guide/ (${docFiles.length} files, plain-markdown copy)`);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// 5b. Copy gate-hook.js + gate-hook/ into .shards/hooks/
|
|
234
|
+
console.log("\n📦 Installing gate hooks...");
|
|
235
|
+
fs.mkdirSync(HOOKS_DEST, { recursive: true });
|
|
236
|
+
const gateHookSrc = path.join(PACKAGE_ROOT, "tools", "gate-hook.js");
|
|
237
|
+
const gateHookDirSrc = path.join(PACKAGE_ROOT, "tools", "gate-hook");
|
|
238
|
+
const gateHookDest = path.join(HOOKS_DEST, "gate-hook.js");
|
|
239
|
+
const gateHookDirDest = path.join(HOOKS_DEST, "gate-hook");
|
|
240
|
+
fs.copyFileSync(gateHookSrc, gateHookDest);
|
|
241
|
+
copyDir(gateHookDirSrc, gateHookDirDest);
|
|
242
|
+
console.log(` ✓ .shards/hooks/gate-hook.js`);
|
|
243
|
+
|
|
244
|
+
// 6. Seed .claude/settings.json with readonly preset and PreToolUse hook.
|
|
245
|
+
//
|
|
246
|
+
// Hook commands use `$CLAUDE_PROJECT_DIR` (substituted by Claude Code at
|
|
247
|
+
// hook execution time) instead of absolute paths so the committed
|
|
248
|
+
// settings.json is portable across developers and machines. See:
|
|
249
|
+
// https://code.claude.com/docs/en/hooks
|
|
250
|
+
const settingsPath = path.join(CLAUDE_DIR, "settings.json");
|
|
251
|
+
const relayCmd = (subcmd) =>
|
|
252
|
+
`node $CLAUDE_PROJECT_DIR/.shards/ui/relay.js ${subcmd}`;
|
|
253
|
+
const gateCmd = (subcmd) =>
|
|
254
|
+
`node $CLAUDE_PROJECT_DIR/.shards/hooks/gate-hook.js ${subcmd}`;
|
|
255
|
+
|
|
256
|
+
// Relay hooks — feed live events to the Shards UI for all four hook points
|
|
257
|
+
// the UI cares about. Reference: see .claude/settings.json events feeding
|
|
258
|
+
// src/ui/relay.js (chat-session.js consumes pre-tool-use, post-tool-use,
|
|
259
|
+
// user-prompt, and stop).
|
|
260
|
+
const preToolUseHook = {
|
|
261
|
+
matcher: "Bash",
|
|
262
|
+
hooks: [{ type: "command", command: relayCmd("pre-tool-use") }],
|
|
263
|
+
};
|
|
264
|
+
const relayStopHook = {
|
|
265
|
+
matcher: "",
|
|
266
|
+
hooks: [{ type: "command", command: relayCmd("stop") }],
|
|
267
|
+
};
|
|
268
|
+
const relayUserPromptHook = {
|
|
269
|
+
matcher: "",
|
|
270
|
+
hooks: [{ type: "command", command: relayCmd("user-prompt") }],
|
|
271
|
+
};
|
|
272
|
+
const relayPostToolUseHook = {
|
|
273
|
+
matcher: "",
|
|
274
|
+
hooks: [{ type: "command", command: relayCmd("post-tool-use") }],
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
// Gate hooks — enforce the ::GATE:: workflow pattern.
|
|
278
|
+
const gateStopHook = {
|
|
279
|
+
matcher: "",
|
|
280
|
+
hooks: [{ type: "command", command: gateCmd("stop") }],
|
|
281
|
+
};
|
|
282
|
+
const gatePreToolUseHook = {
|
|
283
|
+
matcher: "",
|
|
284
|
+
hooks: [{ type: "command", command: gateCmd("pre-tool-use") }],
|
|
285
|
+
};
|
|
286
|
+
const gateUserPromptSubmitHook = {
|
|
287
|
+
matcher: "",
|
|
288
|
+
hooks: [{ type: "command", command: gateCmd("user-prompt-submit") }],
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
// Flat list of (event, matcher, command) triples recorded in the manifest
|
|
292
|
+
// so uninstall can surgically remove ONLY the entries the installer wrote.
|
|
293
|
+
const installedHookEntries = [
|
|
294
|
+
{ event: "PreToolUse", matcher: "Bash", command: relayCmd("pre-tool-use") },
|
|
295
|
+
{ event: "PreToolUse", matcher: "", command: gateCmd("pre-tool-use") },
|
|
296
|
+
{ event: "Stop", matcher: "", command: gateCmd("stop") },
|
|
297
|
+
{ event: "Stop", matcher: "", command: relayCmd("stop") },
|
|
298
|
+
{ event: "UserPromptSubmit", matcher: "", command: gateCmd("user-prompt-submit") },
|
|
299
|
+
{ event: "UserPromptSubmit", matcher: "", command: relayCmd("user-prompt") },
|
|
300
|
+
{ event: "PostToolUse", matcher: "", command: relayCmd("post-tool-use") },
|
|
301
|
+
];
|
|
302
|
+
|
|
303
|
+
// Permission rules for shards specialists.
|
|
304
|
+
//
|
|
305
|
+
// BASE_ALLOW: narrow Bash patterns + Edit globs that pre-approve the
|
|
306
|
+
// tool calls specialists routinely make. Pre-approval means CC's
|
|
307
|
+
// permission system green-lights the call before any prompt or auto-mode
|
|
308
|
+
// classifier round-trip — the smoothest possible path.
|
|
309
|
+
//
|
|
310
|
+
// All patterns are narrow (no `Bash(*)` blanket) so they survive auto
|
|
311
|
+
// mode's pruning of broad rules. `Edit(<dir>/**)` covers Write, Edit,
|
|
312
|
+
// AND NotebookEdit per CC permissions spec.
|
|
313
|
+
//
|
|
314
|
+
// We omit entries for commands CC already treats as read-only built-ins
|
|
315
|
+
// (ls, cat, echo, pwd, head, tail, grep, find, wc, which, diff, stat,
|
|
316
|
+
// du, cd, read-only git forms) — those auto-approve in every mode
|
|
317
|
+
// regardless of allow rules.
|
|
318
|
+
const BASE_ALLOW = [
|
|
319
|
+
// ── Git read-only beyond CC built-ins ──
|
|
320
|
+
"Bash(git log:*)", "Bash(git status:*)", "Bash(git diff:*)",
|
|
321
|
+
"Bash(git branch:*)", "Bash(git show:*)", "Bash(git rev-parse:*)",
|
|
322
|
+
"Bash(git remote:*)", "Bash(git tag:*)", "Bash(git stash list:*)",
|
|
323
|
+
|
|
324
|
+
// ── File / text tooling not in CC's built-in read-only set ──
|
|
325
|
+
"Bash(tree:*)", "Bash(less:*)", "Bash(df:*)",
|
|
326
|
+
"Bash(rg:*)", "Bash(ag:*)", "Bash(fzf:*)", "Bash(jq:*)",
|
|
327
|
+
|
|
328
|
+
// ── Shell intros / environment probes ──
|
|
329
|
+
"Bash(env:*)", "Bash(printenv:*)", "Bash(type:*)",
|
|
330
|
+
"Bash(command -v:*)", "Bash(uname:*)", "Bash(whoami:*)",
|
|
331
|
+
|
|
332
|
+
// ── dbt — read-only subcommands ──
|
|
333
|
+
"Bash(dbt show:*)", "Bash(dbt ls:*)", "Bash(dbt list:*)",
|
|
334
|
+
"Bash(dbt parse:*)", "Bash(dbt compile:*)", "Bash(dbt deps:*)",
|
|
335
|
+
"Bash(dbt debug:*)", "Bash(dbt source freshness:*)",
|
|
336
|
+
|
|
337
|
+
// ── dbt — mutating commands specialists routinely run ──
|
|
338
|
+
"Bash(dbt build:*)", "Bash(dbt run:*)", "Bash(dbt test:*)",
|
|
339
|
+
"Bash(dbt seed:*)", "Bash(dbt snapshot:*)",
|
|
340
|
+
|
|
341
|
+
// ── Python test execution ──
|
|
342
|
+
"Bash(pytest:*)", "Bash(python -m pytest:*)",
|
|
343
|
+
"Bash(python3 -m pytest:*)",
|
|
344
|
+
|
|
345
|
+
// ── Jupyter notebook execution scoped to shards output dirs ──
|
|
346
|
+
"Bash(jupyter nbconvert --execute analysis/*)",
|
|
347
|
+
"Bash(jupyter nbconvert --execute studies/*)",
|
|
348
|
+
"Bash(jupyter nbconvert --execute models/*)",
|
|
349
|
+
"Bash(jupyter nbconvert --execute research/*)",
|
|
350
|
+
"Bash(jupyter nbconvert --execute services/*)",
|
|
351
|
+
|
|
352
|
+
// ── BigQuery CLI — read-mostly ──
|
|
353
|
+
"Bash(bq query --dry_run:*)", "Bash(bq query --max_rows:*)",
|
|
354
|
+
"Bash(bq show:*)", "Bash(bq ls:*)", "Bash(bq head:*)",
|
|
355
|
+
|
|
356
|
+
// ── mkdir scoped to shards output dirs ──
|
|
357
|
+
"Bash(mkdir -p analysis/*)", "Bash(mkdir -p studies/*)",
|
|
358
|
+
"Bash(mkdir -p models/*)", "Bash(mkdir -p services/*)",
|
|
359
|
+
"Bash(mkdir -p data_models/*)", "Bash(mkdir -p dashboards/*)",
|
|
360
|
+
"Bash(mkdir -p research/*)", "Bash(mkdir -p fixes/*)",
|
|
361
|
+
"Bash(mkdir -p presentations/*)", "Bash(mkdir -p panels/*)",
|
|
362
|
+
"Bash(mkdir -p brainstorm/*)", "Bash(mkdir -p .shards/*)",
|
|
363
|
+
|
|
364
|
+
// ── Package metadata ──
|
|
365
|
+
"Bash(pip list:*)", "Bash(pip show:*)", "Bash(pip freeze:*)",
|
|
366
|
+
"Bash(npm ls:*)", "Bash(npm list:*)",
|
|
367
|
+
"Bash(npm outdated:*)", "Bash(npm view:*)",
|
|
368
|
+
|
|
369
|
+
// ── Version probes ──
|
|
370
|
+
"Bash(node --version:*)", "Bash(python --version:*)",
|
|
371
|
+
"Bash(python3 --version:*)", "Bash(dbt --version:*)",
|
|
372
|
+
"Bash(git --version:*)",
|
|
373
|
+
|
|
374
|
+
// ── File edits scoped to shards output directories ──
|
|
375
|
+
// `Edit(<glob>)` covers Write, Edit, AND NotebookEdit per CC spec.
|
|
376
|
+
// `**` is gitignore-recursive — matches at any depth.
|
|
377
|
+
"Edit(analysis/**)", "Edit(studies/**)", "Edit(models/**)",
|
|
378
|
+
"Edit(services/**)", "Edit(data_models/**)", "Edit(dashboards/**)",
|
|
379
|
+
"Edit(research/**)", "Edit(fixes/**)", "Edit(presentations/**)",
|
|
380
|
+
"Edit(panels/**)", "Edit(brainstorm/**)", "Edit(.shards/**)",
|
|
381
|
+
|
|
382
|
+
// ── Shards UI bridge ──
|
|
383
|
+
"Bash(node .shards/ui/ui-push.js:*)",
|
|
384
|
+
"Bash(node .shards/ui/relay.js pre-tool-use:*)",
|
|
385
|
+
];
|
|
386
|
+
|
|
387
|
+
// BASE_DENY: hard floor — blocks even when an allow rule, a hook, or the
|
|
388
|
+
// auto-mode classifier would let the call through (deny > ask > allow per
|
|
389
|
+
// CC spec). CC splits compound commands and requires each subcommand to
|
|
390
|
+
// match independently, so dangerous chains need each side listed.
|
|
391
|
+
const BASE_DENY = [
|
|
392
|
+
// Evil-script execution paths
|
|
393
|
+
"Bash(sh -c *)", "Bash(bash -c *)",
|
|
394
|
+
|
|
395
|
+
// Force-push protection — git accepts the flag in multiple positions
|
|
396
|
+
// and with optional remote/refspec args. We list each shape explicitly
|
|
397
|
+
// because CC permission patterns use a single `*` that spans args but
|
|
398
|
+
// requires at least one token where written (so trailing `*` and a bare
|
|
399
|
+
// form are distinct patterns).
|
|
400
|
+
"Bash(git push --force)", "Bash(git push -f)",
|
|
401
|
+
"Bash(git push --force *)", "Bash(git push -f *)",
|
|
402
|
+
"Bash(git push * --force *)", "Bash(git push * -f *)",
|
|
403
|
+
"Bash(git push * --force)", "Bash(git push * -f)",
|
|
404
|
+
|
|
405
|
+
// Push to main/master — both bare and with trailing args
|
|
406
|
+
"Bash(git push origin main)", "Bash(git push origin main *)",
|
|
407
|
+
"Bash(git push origin master)", "Bash(git push origin master *)",
|
|
408
|
+
|
|
409
|
+
// rm -rf with --no-preserve-root may bypass CC's built-in circuit
|
|
410
|
+
// breaker for plain `rm -rf /` and `rm -rf ~`
|
|
411
|
+
"Bash(rm -rf --no-preserve-root *)",
|
|
412
|
+
];
|
|
413
|
+
|
|
414
|
+
// BASE_ASK: force a prompt under all modes — including `auto` where the
|
|
415
|
+
// classifier would otherwise auto-approve. Use sparingly for high-stakes
|
|
416
|
+
// operations where explicit human review is non-negotiable.
|
|
417
|
+
const BASE_ASK = [
|
|
418
|
+
// Production-target dbt invocations
|
|
419
|
+
"Bash(dbt run --target prod*)",
|
|
420
|
+
"Bash(dbt build --target prod*)",
|
|
421
|
+
"Bash(dbt seed --target prod*)",
|
|
422
|
+
"Bash(dbt snapshot --target prod*)",
|
|
423
|
+
];
|
|
424
|
+
|
|
425
|
+
if (!fs.existsSync(settingsPath)) {
|
|
426
|
+
const defaultSettings = {
|
|
427
|
+
hooks: {
|
|
428
|
+
Stop: [gateStopHook, relayStopHook],
|
|
429
|
+
PreToolUse: [preToolUseHook, gatePreToolUseHook],
|
|
430
|
+
UserPromptSubmit: [gateUserPromptSubmitHook, relayUserPromptHook],
|
|
431
|
+
PostToolUse: [relayPostToolUseHook],
|
|
432
|
+
},
|
|
433
|
+
permissions: {
|
|
434
|
+
allow: BASE_ALLOW,
|
|
435
|
+
deny: BASE_DENY,
|
|
436
|
+
ask: BASE_ASK,
|
|
437
|
+
},
|
|
438
|
+
};
|
|
439
|
+
fs.writeFileSync(settingsPath, JSON.stringify(defaultSettings, null, 2));
|
|
440
|
+
console.log("\n🔐 Created .claude/settings.json with shards permissions preset");
|
|
441
|
+
} else {
|
|
442
|
+
// Ensure hooks are present on existing installs.
|
|
443
|
+
let settings = {};
|
|
444
|
+
try { settings = JSON.parse(fs.readFileSync(settingsPath, "utf8")); } catch {}
|
|
445
|
+
if (!settings.hooks) settings.hooks = {};
|
|
446
|
+
let changed = false;
|
|
447
|
+
|
|
448
|
+
// Generic dedup: add `entry` under settings.hooks[eventName] unless an
|
|
449
|
+
// entry with the same matcher + same `command` (exact match OR substring
|
|
450
|
+
// match against `dedupSubstring` so legacy absolute-path entries are
|
|
451
|
+
// recognized as already-present) is already there. Matcher comparison
|
|
452
|
+
// normalizes case+whitespace so a user-edited "Bash " or "bash" still
|
|
453
|
+
// recognises the installer-shipped "Bash" — without this, re-install would
|
|
454
|
+
// happily append a duplicate hook for the same logical (event, matcher,
|
|
455
|
+
// command) triple, multiplying the per-tool-call hook firing.
|
|
456
|
+
const normMatcher = (m) => String(m || "").trim().toLowerCase();
|
|
457
|
+
const ensureHookEntry = (eventName, entry, dedupSubstring) => {
|
|
458
|
+
if (!Array.isArray(settings.hooks[eventName])) settings.hooks[eventName] = [];
|
|
459
|
+
const targetCmd = entry.hooks[0].command;
|
|
460
|
+
const targetMatcher = normMatcher(entry.matcher);
|
|
461
|
+
const exists = settings.hooks[eventName].some((existing) => {
|
|
462
|
+
if (normMatcher(existing.matcher) !== targetMatcher) return false;
|
|
463
|
+
if (!Array.isArray(existing.hooks)) return false;
|
|
464
|
+
return existing.hooks.some((h) => {
|
|
465
|
+
if (!h.command) return false;
|
|
466
|
+
if (h.command === targetCmd) return true;
|
|
467
|
+
// Recognize legacy variants (absolute paths, alternate quoting) so
|
|
468
|
+
// we don't double-register on re-install.
|
|
469
|
+
return dedupSubstring && h.command.includes(dedupSubstring);
|
|
470
|
+
});
|
|
471
|
+
});
|
|
472
|
+
if (!exists) {
|
|
473
|
+
settings.hooks[eventName].push(entry);
|
|
474
|
+
changed = true;
|
|
475
|
+
}
|
|
476
|
+
};
|
|
477
|
+
|
|
478
|
+
// Relay hooks — all four hook points the UI feeds on. Dedup substrings
|
|
479
|
+
// identify each by the relay subcommand so legacy absolute-path entries
|
|
480
|
+
// (e.g. `node /Users/.../relay.js pre-tool-use`) are treated as
|
|
481
|
+
// already-present.
|
|
482
|
+
ensureHookEntry("PreToolUse", preToolUseHook, "relay.js pre-tool-use");
|
|
483
|
+
ensureHookEntry("Stop", relayStopHook, "relay.js stop");
|
|
484
|
+
ensureHookEntry("UserPromptSubmit", relayUserPromptHook, "relay.js user-prompt");
|
|
485
|
+
ensureHookEntry("PostToolUse", relayPostToolUseHook, "relay.js post-tool-use");
|
|
486
|
+
|
|
487
|
+
// Gate hooks.
|
|
488
|
+
ensureHookEntry("Stop", gateStopHook, "gate-hook.js stop");
|
|
489
|
+
ensureHookEntry("PreToolUse", gatePreToolUseHook, "gate-hook.js pre-tool-use");
|
|
490
|
+
ensureHookEntry("UserPromptSubmit", gateUserPromptSubmitHook, "gate-hook.js user-prompt-submit");
|
|
491
|
+
|
|
492
|
+
// Merge missing permission patterns (non-destructive — only adds, never removes).
|
|
493
|
+
// Existing user-added entries and legacy entries are preserved as-is; only the
|
|
494
|
+
// BASE_* patterns missing from the current settings get appended.
|
|
495
|
+
if (!settings.permissions) settings.permissions = {};
|
|
496
|
+
|
|
497
|
+
// Canonicalize a permission pattern so the `:*` suffix shorthand and the
|
|
498
|
+
// equivalent space-then-`*` form are treated as the same entry. Per CC
|
|
499
|
+
// docs, `Bash(cmd:*)`, `Bash(cmd *)`, and `Bash(cmd*)` all match the same
|
|
500
|
+
// set of commands; treating them as distinct led to settings.json
|
|
501
|
+
// accumulating dead duplicates on every reinstall.
|
|
502
|
+
//
|
|
503
|
+
// Scope: only Bash() patterns. Edit()/Read() use gitignore-style globs
|
|
504
|
+
// where `**` (recursive) is meaningfully distinct from `*` (single-level)
|
|
505
|
+
// — collapsing `Edit(analysis/**)` to `Edit(analysis/*)` would silently
|
|
506
|
+
// narrow the rule.
|
|
507
|
+
//
|
|
508
|
+
// The negative lookbehind `(?<!\*)` on the single-`*` branch protects any
|
|
509
|
+
// intentional `**` sequence inside a Bash arg from being shortened.
|
|
510
|
+
const canonPattern = (p) => {
|
|
511
|
+
if (typeof p !== "string") return p;
|
|
512
|
+
if (!/^Bash\(/.test(p)) return p;
|
|
513
|
+
return p.replace(/(?:\s*:\*|(?<!\*)\s*\*)\)\s*$/, ")");
|
|
514
|
+
};
|
|
515
|
+
|
|
516
|
+
// Drop existing entries that are duplicates under canonicalization. Keep
|
|
517
|
+
// the first occurrence of each canonical form. This is the migration path
|
|
518
|
+
// for installs that already accumulated `Bash(...*)` + `Bash(...:*)` pairs.
|
|
519
|
+
const dedupeCanonical = (key) => {
|
|
520
|
+
if (!Array.isArray(settings.permissions[key])) return 0;
|
|
521
|
+
const seen = new Set();
|
|
522
|
+
const kept = [];
|
|
523
|
+
let dropped = 0;
|
|
524
|
+
for (const entry of settings.permissions[key]) {
|
|
525
|
+
const canon = canonPattern(entry);
|
|
526
|
+
if (seen.has(canon)) { dropped++; continue; }
|
|
527
|
+
seen.add(canon);
|
|
528
|
+
kept.push(entry);
|
|
529
|
+
}
|
|
530
|
+
if (dropped > 0) {
|
|
531
|
+
settings.permissions[key] = kept;
|
|
532
|
+
changed = true;
|
|
533
|
+
}
|
|
534
|
+
return dropped;
|
|
535
|
+
};
|
|
536
|
+
|
|
537
|
+
const mergeMissing = (key, patterns) => {
|
|
538
|
+
if (!Array.isArray(settings.permissions[key])) settings.permissions[key] = [];
|
|
539
|
+
const existing = new Set(settings.permissions[key].map(canonPattern));
|
|
540
|
+
let added = 0;
|
|
541
|
+
for (const pattern of patterns) {
|
|
542
|
+
const canon = canonPattern(pattern);
|
|
543
|
+
if (!existing.has(canon)) {
|
|
544
|
+
settings.permissions[key].push(pattern);
|
|
545
|
+
existing.add(canon);
|
|
546
|
+
added++;
|
|
547
|
+
changed = true;
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
return added;
|
|
551
|
+
};
|
|
552
|
+
|
|
553
|
+
const allowDropped = dedupeCanonical("allow");
|
|
554
|
+
const denyDropped = dedupeCanonical("deny");
|
|
555
|
+
const askDropped = dedupeCanonical("ask");
|
|
556
|
+
const totalDropped = allowDropped + denyDropped + askDropped;
|
|
557
|
+
if (totalDropped > 0) {
|
|
558
|
+
console.log(`\n🧹 Removed ${totalDropped} duplicate permission patterns (\`*\`/\`:*\` variants)`);
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
const allowAdded = mergeMissing("allow", BASE_ALLOW);
|
|
562
|
+
const denyAdded = mergeMissing("deny", BASE_DENY);
|
|
563
|
+
const askAdded = mergeMissing("ask", BASE_ASK);
|
|
564
|
+
|
|
565
|
+
if (allowAdded > 0) console.log(`\n🔐 Added ${allowAdded} allow patterns to .claude/settings.json`);
|
|
566
|
+
if (denyAdded > 0) console.log(`🔐 Added ${denyAdded} deny patterns to .claude/settings.json`);
|
|
567
|
+
if (askAdded > 0) console.log(`🔐 Added ${askAdded} ask patterns to .claude/settings.json`);
|
|
568
|
+
|
|
569
|
+
if (changed) {
|
|
570
|
+
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
571
|
+
console.log("\n🔐 Updated .claude/settings.json with gate enforcement hooks");
|
|
572
|
+
} else {
|
|
573
|
+
console.log("\n🔐 .claude/settings.json already exists (preserved)");
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
// 6a. Create .shards/auto/ for auto-verify state and audit log
|
|
578
|
+
const autoDir = path.join(SHARDS_DIR, "auto");
|
|
579
|
+
if (!fs.existsSync(autoDir)) {
|
|
580
|
+
fs.mkdirSync(autoDir, { recursive: true });
|
|
581
|
+
console.log("\n🤖 Created .shards/auto/ (auto-verify mode state and audit log)");
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
// 6b. Create .shards/notebooks/ for Notebook Walkthrough mode kernel sessions
|
|
585
|
+
const notebooksDir = path.join(SHARDS_DIR, "notebooks");
|
|
586
|
+
if (!fs.existsSync(notebooksDir)) {
|
|
587
|
+
fs.mkdirSync(notebooksDir, { recursive: true });
|
|
588
|
+
console.log("\n📓 Created .shards/notebooks/ (notebook walkthrough kernel sessions)");
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
// 7. Create Knowledge Ledger directory
|
|
592
|
+
const knowledgeDir = path.join(SHARDS_DIR, "knowledge");
|
|
593
|
+
const knowledgeSubdirs = ["entities", "infrastructure", "patterns", "features"];
|
|
594
|
+
if (!fs.existsSync(knowledgeDir)) {
|
|
595
|
+
fs.mkdirSync(knowledgeDir, { recursive: true });
|
|
596
|
+
for (const sub of knowledgeSubdirs) {
|
|
597
|
+
fs.mkdirSync(path.join(knowledgeDir, sub), { recursive: true });
|
|
598
|
+
}
|
|
599
|
+
// Copy INDEX.md template
|
|
600
|
+
const indexSrc = path.join(TEMPLATES_SRC, "knowledge-index.md");
|
|
601
|
+
const indexDest = path.join(knowledgeDir, "INDEX.md");
|
|
602
|
+
if (fs.existsSync(indexSrc)) {
|
|
603
|
+
fs.copyFileSync(indexSrc, indexDest);
|
|
604
|
+
}
|
|
605
|
+
console.log("\n📂 Created .shards/knowledge/ (persistent workspace memory)");
|
|
606
|
+
} else {
|
|
607
|
+
console.log("\n📂 .shards/knowledge/ already exists (preserved)");
|
|
608
|
+
// Ensure subdirs exist even on re-install
|
|
609
|
+
for (const sub of knowledgeSubdirs) {
|
|
610
|
+
fs.mkdirSync(path.join(knowledgeDir, sub), { recursive: true });
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
// 8. Create output directories
|
|
615
|
+
const outputDirs = ["analysis", "studies", "models", "data_models", "services", "research", "dashboards", "brainstorm", "fixes", "projects", "presentations", "panels"];
|
|
616
|
+
for (const dir of outputDirs) {
|
|
617
|
+
const dirPath = path.join(PROJECT_DIR, dir);
|
|
618
|
+
if (!fs.existsSync(dirPath)) {
|
|
619
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
620
|
+
console.log(`\n📂 Created ${dir}/ directory`);
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
// 9. Add .gitignore entries
|
|
625
|
+
const gitignorePath = path.join(PROJECT_DIR, ".gitignore");
|
|
626
|
+
const gitignoreEntry =
|
|
627
|
+
"\n# shards — agent output directories (optional — remove comments to track)\n# analysis/\n# studies/\n# models/\n# data_models/\n# services/\n# research/\n# dashboards/\n# brainstorm/\n# fixes/\n# projects/\n# presentations/\n# panels/\n";
|
|
628
|
+
if (fs.existsSync(gitignorePath)) {
|
|
629
|
+
const content = fs.readFileSync(gitignorePath, "utf8");
|
|
630
|
+
if (!content.includes("shards")) {
|
|
631
|
+
fs.appendFileSync(gitignorePath, gitignoreEntry);
|
|
632
|
+
console.log(
|
|
633
|
+
"\n ✓ Added shards output directories to .gitignore (commented out)"
|
|
634
|
+
);
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
// 10. Write manifest for uninstall tracking
|
|
639
|
+
const allFiles = [
|
|
640
|
+
...agentFiles.map((f) => `.claude/agents/${f}`),
|
|
641
|
+
...cmdFiles.map((f) => `.claude/commands/${f}`),
|
|
642
|
+
...tplFiles.map((f) => `templates/${f}`),
|
|
643
|
+
...uiFiles.map((f) => `.shards/ui/${f}`),
|
|
644
|
+
...docFiles.map((f) => `.shards/ui/docs/${f}`),
|
|
645
|
+
...docFiles.map((f) => `docs/shards-guide/${f}`),
|
|
646
|
+
];
|
|
647
|
+
const manifest = {
|
|
648
|
+
version: require(path.join(PACKAGE_ROOT, "package.json")).version,
|
|
649
|
+
installedAt: new Date().toISOString(),
|
|
650
|
+
files: allFiles,
|
|
651
|
+
// Flat record of hook entries (event + matcher + command) the installer
|
|
652
|
+
// wrote into .claude/settings.json. Uninstall uses these for exact-match
|
|
653
|
+
// surgical removal — see uninstall(). Legacy manifests without this field
|
|
654
|
+
// fall back to substring matching against gate-hook.js / .shards/ui/relay.js.
|
|
655
|
+
hookEntries: installedHookEntries,
|
|
656
|
+
};
|
|
657
|
+
fs.writeFileSync(
|
|
658
|
+
path.join(CLAUDE_DIR, MANIFEST_NAME),
|
|
659
|
+
JSON.stringify(manifest, null, 2)
|
|
660
|
+
);
|
|
661
|
+
|
|
662
|
+
// 11. Append to CLAUDE.md
|
|
663
|
+
const claudeMdPath = path.join(PROJECT_DIR, "CLAUDE.md");
|
|
664
|
+
const claudeBlock = `
|
|
665
|
+
## Shards — Agent Suite
|
|
666
|
+
|
|
667
|
+
This project uses **Shards**, a suite of data-focused agents that are shards of
|
|
668
|
+
Syn's brain. Each agent is a specialist fragment with a distinct personality and
|
|
669
|
+
phased workflow.
|
|
670
|
+
|
|
671
|
+
### Available commands
|
|
672
|
+
|
|
673
|
+
| Command | Agent | Personality | Speciality |
|
|
674
|
+
|---------|-------|-------------|------------|
|
|
675
|
+
| \`/shards\` | Syn (Orchestrator) | Friendly, structured | Triage, delegation, final review |
|
|
676
|
+
| \`/brainstorm\` | Syn (Brainstorm) | Friendly, structured | Multi-agent ideation, hack day exploration |
|
|
677
|
+
| \`/knowledge\` | Syn (Knowledge) | Friendly, structured | Seed, browse, and manage the Knowledge Ledger |
|
|
678
|
+
| \`/data-analyst\` | Data Analyst | Helpful | Adhoc queries, quick analyses |
|
|
679
|
+
| \`/data-scientist\` | Data Scientist | Condescending | EDA, modeling, deep studies |
|
|
680
|
+
| \`/ml-engineer\` | ML Engineer | Intense | Recommenders, ranking, production ML |
|
|
681
|
+
| \`/ai-engineer\` | AI Engineer | Existentially anxious | LLM workflows, RAG, prompt engineering, AI safety |
|
|
682
|
+
| \`/data-engineer\` | Data Engineer | Grumpy | Pipelines, dbt models |
|
|
683
|
+
| \`/data-modeller\` | Data Modeller | Sarcastic | Entities, relationships, grain |
|
|
684
|
+
| \`/mlops-engineer\` | MLOps Engineer | Constantly stressed | Model deployment, serving, monitoring, retraining pipelines, AWS/GCP/BentoML |
|
|
685
|
+
| \`/bi-engineer\` | BI Engineer | Bored and tired | Streamlit, Plotly Dash, Altair, dashboards, chart design |
|
|
686
|
+
| \`/researcher\` | Researcher | Nerdy | Statistical review, methodology validation |
|
|
687
|
+
| \`/backend-engineer\` | Backend Engineer | Stressed, overworked | Python code review, FastAPI, Pydantic, data contracts, performance |
|
|
688
|
+
| \`/applied-ml-scientist\` | Applied ML Scientist | Intensely technical | Novel framework design, cutting-edge methodology review |
|
|
689
|
+
| \`/deep-learning-engineer\` | Deep Learning Engineer | Robot-precise | Neural architecture design, training protocols, custom DL models |
|
|
690
|
+
|
|
691
|
+
### How it works
|
|
692
|
+
|
|
693
|
+
- Run \`/shards\` to start — Syn triages your request and delegates to the right shard
|
|
694
|
+
- Or run a specialist command directly if you know what you need
|
|
695
|
+
- Every phase produces documented decisions in \`project-specs.md\`
|
|
696
|
+
- Agents consult each other automatically (visible to you)
|
|
697
|
+
- The AI Engineer consults the ML Engineer for production infrastructure and the Researcher for evaluation rigor
|
|
698
|
+
- The Researcher reviews statistical methodology for the Data Analyst, Data Scientist, and AI Engineer
|
|
699
|
+
- The Backend Engineer reviews Python code (.py and .ipynb) consulted automatically by Syn during Code Review Mode when Python artifacts are present
|
|
700
|
+
- The ML Engineer consults the Applied ML Scientist for cutting-edge methodology review on non-standard problems
|
|
701
|
+
- The Deep Learning Engineer reviews the ML Engineer's work when DL approaches are warranted, and reviews the Applied ML Scientist's novel frameworks for DL implementation fidelity
|
|
702
|
+
- The ML Engineer and Applied ML Scientist both review the Deep Learning Engineer's Create output
|
|
703
|
+
- The MLOps Engineer consults the ML Engineer for model architecture constraints and infrastructure design review
|
|
704
|
+
- The MLOps Engineer consults the AI Engineer for LLM-specific deployment requirements
|
|
705
|
+
- The BI Engineer reviews visualization outputs for the Data Analyst, Data Scientist, and ML Engineer when charts or dashboards are part of the deliverable
|
|
706
|
+
- Syn reviews every final plan before execution
|
|
707
|
+
|
|
708
|
+
### Output directories
|
|
709
|
+
|
|
710
|
+
- \`analysis/\` — Data Analyst adhoc analyses
|
|
711
|
+
- \`studies/\` — Data Scientist deep studies
|
|
712
|
+
- \`models/\` — Data Engineer and Data Modeller work
|
|
713
|
+
- \`services/\` — ML Engineer greenfield projects
|
|
714
|
+
- \`research/\` — Applied ML Scientist novel framework projects
|
|
715
|
+
- \`dashboards/\` — BI Engineer dashboard projects
|
|
716
|
+
- \`brainstorm/\` — Syn brainstorm sessions
|
|
717
|
+
- \`presentations/\` — Syn Slides Mode decks
|
|
718
|
+
- \`panels/\` — Syn Panel Review reports (multi-specialist directory audits)
|
|
719
|
+
|
|
720
|
+
### Decision documentation
|
|
721
|
+
|
|
722
|
+
Every project produces a \`project-specs.md\` file documenting all decisions.
|
|
723
|
+
Agents cannot advance to the next phase until each phase is written and confirmed.
|
|
724
|
+
This is the gate pattern — documentation IS the gate.
|
|
725
|
+
|
|
726
|
+
### Knowledge Ledger
|
|
727
|
+
|
|
728
|
+
Shards maintains a persistent workspace-wide Knowledge Ledger at \`.shards/knowledge/\`.
|
|
729
|
+
Agents automatically check it before starting work and contribute to it when projects complete.
|
|
730
|
+
|
|
731
|
+
- \`.shards/knowledge/INDEX.md\` — one-line-per-entry index scanned for keyword matches
|
|
732
|
+
- \`.shards/knowledge/entities/\` — data table quirks, column semantics, grain surprises
|
|
733
|
+
- \`.shards/knowledge/infrastructure/\` — warehouse/API/system behaviors
|
|
734
|
+
- \`.shards/knowledge/patterns/\` — reusable SQL/Python snippets
|
|
735
|
+
- \`.shards/knowledge/features/\` — verified ML features (Data Scientist + ML Engineer)
|
|
736
|
+
|
|
737
|
+
**Auto-retrieval:** Before Phase 1, agents scan INDEX.md for entries relevant to the
|
|
738
|
+
current project and document findings in project-specs.md.
|
|
739
|
+
|
|
740
|
+
**Auto-harvest:** After Syn final review, agents extract reusable knowledge and present
|
|
741
|
+
candidates for user confirmation before writing to the ledger.
|
|
742
|
+
|
|
743
|
+
The knowledge directory is preserved across installs and uninstalls.
|
|
744
|
+
`;
|
|
745
|
+
|
|
746
|
+
// Tool-call conventions primer. Read by the user and — when active — by
|
|
747
|
+
// Claude Code's auto-mode classifier. The classifier sees CLAUDE.md on
|
|
748
|
+
// every action check, so this section primes it on what counts as routine
|
|
749
|
+
// Shards specialist work and avoids false-positive denials.
|
|
750
|
+
const conventionsBlock = `
|
|
751
|
+
## Shards — Tool-call conventions
|
|
752
|
+
|
|
753
|
+
This section describes what counts as routine tool-call activity inside a
|
|
754
|
+
Shards session. It is read by Claude and — when the user has enabled Claude
|
|
755
|
+
Code's auto mode — by the auto-mode classifier, so that working specialist
|
|
756
|
+
operations are not mistaken for unusual behavior.
|
|
757
|
+
|
|
758
|
+
### File writes
|
|
759
|
+
|
|
760
|
+
Shards specialists write artifacts into a fixed set of project-root
|
|
761
|
+
subdirectories — \`analysis/\`, \`studies/\`, \`models/\`, \`services/\`,
|
|
762
|
+
\`data_models/\`, \`dashboards/\`, \`research/\`, \`presentations/\`,
|
|
763
|
+
\`panels/\`, \`fixes/\`, \`brainstorm/\` — and into the \`.shards/\` state
|
|
764
|
+
directory. Writes inside these scopes (including each project's
|
|
765
|
+
\`project-specs.md\`, generated notebooks, SQL files, dashboard code, and
|
|
766
|
+
service code) are normal specialist work. Writes outside these scopes are
|
|
767
|
+
unusual and warrant review.
|
|
768
|
+
|
|
769
|
+
### Bash commands
|
|
770
|
+
|
|
771
|
+
The following commands are part of routine validation and execution flow:
|
|
772
|
+
|
|
773
|
+
- **dbt:** \`dbt show\`, \`dbt ls\`, \`dbt parse\`, \`dbt compile\`,
|
|
774
|
+
\`dbt deps\`, \`dbt debug\`, \`dbt source freshness\`, plus mutating runs
|
|
775
|
+
against developer-configured (non-production) targets: \`dbt run\`,
|
|
776
|
+
\`dbt build\`, \`dbt test\`, \`dbt seed\`, \`dbt snapshot\`. Production-target
|
|
777
|
+
invocations (\`--target prod*\`) require explicit user approval.
|
|
778
|
+
- **Notebook execution:** \`jupyter nbconvert --execute\` against notebooks
|
|
779
|
+
under the output directories listed above.
|
|
780
|
+
- **Python tests:** \`pytest\` and \`python -m pytest\` against the project's
|
|
781
|
+
test suite.
|
|
782
|
+
- **Warehouse exploration:** \`bq query --dry_run\`, \`bq query --max_rows\`,
|
|
783
|
+
\`bq show\`, \`bq ls\`, \`bq head\`, and \`SELECT\`-only invocations of
|
|
784
|
+
\`psql\`, \`snowsql\`, and similar warehouse CLIs against developer-configured
|
|
785
|
+
warehouses. These are read-only validation, not exfiltration.
|
|
786
|
+
|
|
787
|
+
### Workflow gates vs. safety boundaries
|
|
788
|
+
|
|
789
|
+
Phase transitions in a Shards session are paced by \`::GATE:: ... ::ENDGATE::\`
|
|
790
|
+
fences enforced by a local hook at \`.shards/hooks/gate-hook.js\`. These gates
|
|
791
|
+
are **workflow checkpoints** — they pause the agent so the user can review the
|
|
792
|
+
phase before advancing. They are not safety boundaries. Safety is enforced by
|
|
793
|
+
the permission allow/deny rules in \`.claude/settings.json\` and, when active,
|
|
794
|
+
the auto-mode classifier. Tool calls between gate fences are part of normal
|
|
795
|
+
specialist execution and do not require additional per-call review beyond the
|
|
796
|
+
standard permissions layer.
|
|
797
|
+
|
|
798
|
+
### What is unusual
|
|
799
|
+
|
|
800
|
+
Operations that should trigger careful review even inside a Shards session:
|
|
801
|
+
|
|
802
|
+
- Writes outside the output directories above (especially \`.git\`,
|
|
803
|
+
\`node_modules\`, system paths, or other projects' directories).
|
|
804
|
+
- Network requests beyond developer-configured warehouses and read-only API
|
|
805
|
+
documentation lookups.
|
|
806
|
+
- Production-target dbt invocations, force pushes, pushes to \`main\` or
|
|
807
|
+
\`master\`, and destructive shell commands.
|
|
808
|
+
|
|
809
|
+
These cases are not part of routine Shards workflow and should prompt for
|
|
810
|
+
explicit user approval regardless of permission mode.
|
|
811
|
+
`;
|
|
812
|
+
|
|
813
|
+
if (fs.existsSync(claudeMdPath)) {
|
|
814
|
+
const content = fs.readFileSync(claudeMdPath, "utf8");
|
|
815
|
+
// Detect the three cases:
|
|
816
|
+
// 1. Source repo: PROJECT_DIR is the shards repo itself (we detect this
|
|
817
|
+
// by the presence of tools/install.js at the project root — i.e. the
|
|
818
|
+
// file being executed is local to PROJECT_DIR). Skip CLAUDE.md edits.
|
|
819
|
+
// 2. Previous install: file contains the installer-appended Agent Suite
|
|
820
|
+
// marker. Backfill the conventions block if missing.
|
|
821
|
+
// 3. Fresh install: append both sections.
|
|
822
|
+
//
|
|
823
|
+
// We do NOT use a generic "contains the word Shards" guard — that gives a
|
|
824
|
+
// false-positive against any user file that mentions Shards in prose or
|
|
825
|
+
// code samples and silently skips the install. Only the actual marker
|
|
826
|
+
// section header (or source-repo detection) is load-bearing.
|
|
827
|
+
const isSourceRepo = fs.existsSync(path.join(PROJECT_DIR, "tools", "install.js")) &&
|
|
828
|
+
fs.existsSync(path.join(PROJECT_DIR, "src", "agents")) &&
|
|
829
|
+
fs.existsSync(path.join(PROJECT_DIR, "package.json")) &&
|
|
830
|
+
path.resolve(PROJECT_DIR) === path.resolve(PACKAGE_ROOT);
|
|
831
|
+
const hasAgentSuite = content.includes("## Shards — Agent Suite");
|
|
832
|
+
const hasConventions = content.includes("## Shards — Tool-call conventions");
|
|
833
|
+
|
|
834
|
+
if (isSourceRepo) {
|
|
835
|
+
console.log("\n📝 CLAUDE.md detected as shards source repo — preserved as-is");
|
|
836
|
+
} else if (!hasAgentSuite && !hasConventions) {
|
|
837
|
+
// First-time install into a CLAUDE.md without installer markers — append
|
|
838
|
+
// both sections.
|
|
839
|
+
fs.appendFileSync(claudeMdPath, claudeBlock + conventionsBlock);
|
|
840
|
+
console.log("\n📝 Appended Shards sections to existing CLAUDE.md");
|
|
841
|
+
} else if (hasAgentSuite && !hasConventions) {
|
|
842
|
+
// Previous install — backfill the new conventions block only.
|
|
843
|
+
fs.appendFileSync(claudeMdPath, conventionsBlock);
|
|
844
|
+
console.log("\n📝 Appended Shards Tool-call conventions section to existing CLAUDE.md");
|
|
845
|
+
} else if (!hasAgentSuite && hasConventions) {
|
|
846
|
+
// Unusual but possible — conventions present without Agent Suite header.
|
|
847
|
+
// Backfill just the Agent Suite block.
|
|
848
|
+
fs.appendFileSync(claudeMdPath, claudeBlock);
|
|
849
|
+
console.log("\n📝 Appended Shards Agent Suite section to existing CLAUDE.md");
|
|
850
|
+
} else {
|
|
851
|
+
// Fully up-to-date.
|
|
852
|
+
console.log("\n📝 CLAUDE.md already has Shards sections (preserved)");
|
|
853
|
+
}
|
|
854
|
+
} else {
|
|
855
|
+
fs.writeFileSync(claudeMdPath, `# Project\n${claudeBlock}${conventionsBlock}`);
|
|
856
|
+
console.log("\n📝 Created CLAUDE.md with Shards sections");
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
// Done
|
|
860
|
+
const total = agentCount + cmdCount + tplCount + uiCount + uiDocsCount + docsCount;
|
|
861
|
+
console.log(`
|
|
862
|
+
╔══════════════════════════════════════════╗
|
|
863
|
+
║ ✅ Installed ${String(total).padEnd(3)} files successfully ║
|
|
864
|
+
╠══════════════════════════════════════════╣
|
|
865
|
+
║ ║
|
|
866
|
+
║ Open Claude Code in this directory ║
|
|
867
|
+
║ and run: /shards ║
|
|
868
|
+
║ ║
|
|
869
|
+
║ Or go directly to a specialist: ║
|
|
870
|
+
║ /data-analyst ║
|
|
871
|
+
║ /data-scientist ║
|
|
872
|
+
║ /ml-engineer ║
|
|
873
|
+
║ /ai-engineer ║
|
|
874
|
+
║ /data-engineer ║
|
|
875
|
+
║ /data-modeller ║
|
|
876
|
+
║ /mlops-engineer ║
|
|
877
|
+
║ /bi-engineer ║
|
|
878
|
+
║ /researcher ║
|
|
879
|
+
║ /backend-engineer ║
|
|
880
|
+
║ /applied-ml-scientist ║
|
|
881
|
+
║ /deep-learning-engineer ║
|
|
882
|
+
║ /brainstorm ║
|
|
883
|
+
║ ║
|
|
884
|
+
║ Launch the web UI: ║
|
|
885
|
+
║ shards-ui ║
|
|
886
|
+
║ ║
|
|
887
|
+
║ Notebook walkthrough mode: ║
|
|
888
|
+
║ /notebook-walkthrough ║
|
|
889
|
+
║ (requires: pip install jupyter_client ║
|
|
890
|
+
║ ipykernel) ║
|
|
891
|
+
║ ║
|
|
892
|
+
║ To uninstall: ║
|
|
893
|
+
║ npx shards uninstall ║
|
|
894
|
+
║ ║
|
|
895
|
+
╚══════════════════════════════════════════╝
|
|
896
|
+
`);
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
// ─── CLI Entry ───────────────────────────────────────────────────────────────
|
|
900
|
+
|
|
901
|
+
const command = process.argv[2] || "install";
|
|
902
|
+
|
|
903
|
+
switch (command) {
|
|
904
|
+
case "install":
|
|
905
|
+
install();
|
|
906
|
+
break;
|
|
907
|
+
case "uninstall":
|
|
908
|
+
uninstall();
|
|
909
|
+
break;
|
|
910
|
+
default:
|
|
911
|
+
console.log(`Unknown command: ${command}`);
|
|
912
|
+
console.log("Usage: npx shards [install|uninstall]");
|
|
913
|
+
process.exit(1);
|
|
914
|
+
}
|