@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
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
// ═══════════════════════════════════════════════════════════════
|
|
2
|
+
// Shared mutable state
|
|
3
|
+
// ═══════════════════════════════════════════════════════════════
|
|
4
|
+
|
|
5
|
+
// P1: Auth token injected by server via <meta> tag
|
|
6
|
+
var SHARDS_TOKEN = (function() {
|
|
7
|
+
var meta = document.querySelector('meta[name="shards-token"]');
|
|
8
|
+
return meta ? meta.getAttribute('content') : '';
|
|
9
|
+
})();
|
|
10
|
+
|
|
11
|
+
// P1: Authenticated fetch wrapper
|
|
12
|
+
function authFetch(url, opts) {
|
|
13
|
+
opts = opts || {};
|
|
14
|
+
opts.headers = opts.headers || {};
|
|
15
|
+
if (SHARDS_TOKEN) {
|
|
16
|
+
opts.headers['Authorization'] = 'Bearer ' + SHARDS_TOKEN;
|
|
17
|
+
}
|
|
18
|
+
return fetch(url, opts);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
var currentAgent = null;
|
|
22
|
+
var monacoLoaded = false;
|
|
23
|
+
var monacoFailed = false;
|
|
24
|
+
var monacoLoadPromise = null;
|
|
25
|
+
var activeMonacoInstance = null;
|
|
26
|
+
var fileRenderGen = 0;
|
|
27
|
+
var activeNotebookCellMonaco = null;
|
|
28
|
+
var activeNotebookCellIdx = null;
|
|
29
|
+
var activeCellIdx = null;
|
|
30
|
+
var currentBrowseDir = null;
|
|
31
|
+
var explorerViewMode = localStorage.getItem('shards-explorer-view') || 'tree';
|
|
32
|
+
var activeSidebarView = localStorage.getItem('shards-sidebar-view') || 'explorer';
|
|
33
|
+
var treeExpanded = {};
|
|
34
|
+
var treeChildren = {};
|
|
35
|
+
var treeLoading = {};
|
|
36
|
+
var treeRootPath = null;
|
|
37
|
+
var activeTabulatorInstance = null;
|
|
38
|
+
var activeTabularColumns = null;
|
|
39
|
+
var sessionTouchedFiles = new Set(); // pointer to active session's set
|
|
40
|
+
var agentList = null;
|
|
41
|
+
|
|
42
|
+
// Per-session workspace state — globals act as pointers to active session's data.
|
|
43
|
+
// saveSessionWorkspace() / loadSessionWorkspace() swap these on session switch.
|
|
44
|
+
var openFiles = {};
|
|
45
|
+
var openPanels = {};
|
|
46
|
+
var fileTabOrder = [];
|
|
47
|
+
var panelTabOrder = [];
|
|
48
|
+
var activeTabId = 'chat';
|
|
49
|
+
var splitMode = false;
|
|
50
|
+
var currentFileInPane = null;
|
|
51
|
+
var selectionContext = null;
|
|
52
|
+
var pinnedItems = []; // pointer to active session's pinned items
|
|
53
|
+
|
|
54
|
+
// ═══════════════════════════════════════════════════════════════
|
|
55
|
+
// Multi-session state
|
|
56
|
+
// ═══════════════════════════════════════════════════════════════
|
|
57
|
+
|
|
58
|
+
var chatSessions = {}; // sessionId -> ChatSessionState
|
|
59
|
+
var activeSessionId = null; // currently viewed session tab
|
|
60
|
+
var sessionOrder = []; // ordered array of session IDs
|
|
61
|
+
|
|
62
|
+
// Browser tab title notification state
|
|
63
|
+
var _titleFlashInterval = null;
|
|
64
|
+
var _originalTitle = 'Shards UI';
|
|
65
|
+
|
|
66
|
+
function createSessionState(sid, agent) {
|
|
67
|
+
var state = {
|
|
68
|
+
sessionId: sid,
|
|
69
|
+
agent: agent,
|
|
70
|
+
title: null,
|
|
71
|
+
messages: [],
|
|
72
|
+
pendingBubble: null,
|
|
73
|
+
tokenBuffer: '',
|
|
74
|
+
tokenFlushPending: false,
|
|
75
|
+
chatResponding: false,
|
|
76
|
+
hasMessages: false,
|
|
77
|
+
chatTransitioning: false,
|
|
78
|
+
thinkingIndicatorEl: null,
|
|
79
|
+
consultingIndicatorEl: null,
|
|
80
|
+
workingIndicatorEl: null,
|
|
81
|
+
scrollTop: 0,
|
|
82
|
+
domFragment: null,
|
|
83
|
+
domDirty: false,
|
|
84
|
+
unread: false,
|
|
85
|
+
needsAttention: false,
|
|
86
|
+
pendingPermissions: [],
|
|
87
|
+
// Image attachments staged for the next send. Each entry:
|
|
88
|
+
// { id, mediaType, dataBase64, sizeBytes, name, previewUrl }
|
|
89
|
+
pendingAttachments: [],
|
|
90
|
+
attentionReason: null,
|
|
91
|
+
createdAt: Date.now(),
|
|
92
|
+
lastActivityAt: Date.now(),
|
|
93
|
+
// Project context — derived server-side from first matching file-touched
|
|
94
|
+
// path under analysis/, studies/, models/, etc. Populated via session-context event.
|
|
95
|
+
projectName: null,
|
|
96
|
+
projectDir: null,
|
|
97
|
+
// R2 — last action surface for tab subline
|
|
98
|
+
// Shape: { kind: 'tool'|'file'|'consult'|'gate'|'error'|'idle', label, ts }
|
|
99
|
+
lastSignal: null,
|
|
100
|
+
// R3 — bounded timeline (last ~30 events) for sidebar Activity panel
|
|
101
|
+
// Each entry: { ts, kind, label, meta }
|
|
102
|
+
timeline: [],
|
|
103
|
+
// Workspace state (each session owns its own file tabs, panels, split mode)
|
|
104
|
+
sessionTouchedFiles: new Set(),
|
|
105
|
+
openFiles: {},
|
|
106
|
+
fileTabOrder: [],
|
|
107
|
+
activeTabId: 'chat',
|
|
108
|
+
splitMode: false,
|
|
109
|
+
currentFileInPane: null,
|
|
110
|
+
openPanels: {},
|
|
111
|
+
panelTabOrder: [],
|
|
112
|
+
pinnedItems: [], // Pinboard: array of { type, path, name, text?, startLine?, endLine? }
|
|
113
|
+
totalCost: 0, // cumulative USD cost for this session
|
|
114
|
+
totalDuration: 0, // cumulative ms for this session
|
|
115
|
+
contextUsage: null, // { inputTokens, cacheReadTokens, cacheCreationTokens, outputTokens } — real per-turn usage from the CLI
|
|
116
|
+
// Buffered tool inputs streaming via chat-tool-input-delta. Keyed by content
|
|
117
|
+
// block index: { id, name, inputBuffer }. Cleared on chat-block-stop after
|
|
118
|
+
// we finalize the timeline entry with a richer label.
|
|
119
|
+
pendingToolCalls: {},
|
|
120
|
+
// Cached truncated first-prompt snippet for tab labels. Lazily filled the
|
|
121
|
+
// first time we need it; reset to null on chat-clear-messages.
|
|
122
|
+
_promptSnippet: null,
|
|
123
|
+
};
|
|
124
|
+
chatSessions[sid] = state;
|
|
125
|
+
sessionOrder.push(sid);
|
|
126
|
+
pushTimeline(state, 'start', agent, null);
|
|
127
|
+
return state;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// R3 — append an event to a session's bounded timeline. Caps history at 30
|
|
131
|
+
// entries to bound memory; older entries fall off the front.
|
|
132
|
+
var TIMELINE_MAX = 30;
|
|
133
|
+
function pushTimeline(session, kind, label, meta) {
|
|
134
|
+
if (!session) return;
|
|
135
|
+
if (!session.timeline) session.timeline = [];
|
|
136
|
+
session.timeline.push({
|
|
137
|
+
ts: Date.now(),
|
|
138
|
+
kind: kind,
|
|
139
|
+
label: label,
|
|
140
|
+
meta: meta || null,
|
|
141
|
+
});
|
|
142
|
+
if (session.timeline.length > TIMELINE_MAX) {
|
|
143
|
+
session.timeline.splice(0, session.timeline.length - TIMELINE_MAX);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Find a tool timeline entry by its tool-use id and patch its label/meta in
|
|
148
|
+
// place. No-ops if the entry has already rotated off the cap. Returns true on
|
|
149
|
+
// success so callers can fall back to pushing a fresh entry.
|
|
150
|
+
function updateToolTimelineEntry(session, id, patch) {
|
|
151
|
+
if (!session || !session.timeline || !id) return false;
|
|
152
|
+
for (var i = session.timeline.length - 1; i >= 0; i--) {
|
|
153
|
+
var e = session.timeline[i];
|
|
154
|
+
if (e.kind === 'tool' && e.meta && e.meta.id === id) {
|
|
155
|
+
if (patch.label != null) e.label = patch.label;
|
|
156
|
+
if (patch.meta) {
|
|
157
|
+
e.meta = Object.assign({}, e.meta, patch.meta);
|
|
158
|
+
}
|
|
159
|
+
e.ts = Date.now();
|
|
160
|
+
return true;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function removeSessionState(sid) {
|
|
167
|
+
delete chatSessions[sid];
|
|
168
|
+
var idx = sessionOrder.indexOf(sid);
|
|
169
|
+
if (idx !== -1) sessionOrder.splice(idx, 1);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function getActiveSession() {
|
|
173
|
+
return activeSessionId ? (chatSessions[activeSessionId] || null) : null;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function getSessionState(sid) {
|
|
177
|
+
return chatSessions[sid] || null;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Save current workspace globals into the given session object
|
|
181
|
+
function saveSessionWorkspace(session) {
|
|
182
|
+
if (!session) return;
|
|
183
|
+
session.sessionTouchedFiles = sessionTouchedFiles;
|
|
184
|
+
session.openFiles = openFiles;
|
|
185
|
+
session.fileTabOrder = fileTabOrder;
|
|
186
|
+
session.activeTabId = activeTabId;
|
|
187
|
+
session.splitMode = splitMode;
|
|
188
|
+
session.currentFileInPane = currentFileInPane;
|
|
189
|
+
session.openPanels = openPanels;
|
|
190
|
+
session.panelTabOrder = panelTabOrder;
|
|
191
|
+
session.pinnedItems = pinnedItems;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// ═══════════════════════════════════════════════════════════════
|
|
195
|
+
// Gate state subscription (SSE primary, polling fallback)
|
|
196
|
+
// ═══════════════════════════════════════════════════════════════
|
|
197
|
+
//
|
|
198
|
+
// The server pushes gate-state / gate-block / auto-state events on
|
|
199
|
+
// /gate-state-stream whenever .shards/gates/state.json,
|
|
200
|
+
// .shards/gates/violations.jsonl, or .shards/auto/state.json change. Replaces
|
|
201
|
+
// the legacy 2s poll which lagged real gate transitions and caused the
|
|
202
|
+
// Confirm-button-on-wrong-gate render bug. On SSE error we fall back to a
|
|
203
|
+
// 10s poll as resilience (server restart, network blip).
|
|
204
|
+
|
|
205
|
+
var gateState = { open: false, history: [] };
|
|
206
|
+
var gateMode = { enforce: true, checkpointEnforce: true, autoVerify: true };
|
|
207
|
+
var _gateEventSource = null;
|
|
208
|
+
var _gatePoller = null;
|
|
209
|
+
var _gateReconnectTimer = null;
|
|
210
|
+
|
|
211
|
+
function _onGateStateUpdate(state) {
|
|
212
|
+
gateState = state || { open: false, history: [] };
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function _onGateBlock(evt) {
|
|
216
|
+
if (typeof renderGateBlockBanner === 'function') {
|
|
217
|
+
renderGateBlockBanner(evt);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function _onGateModeLoaded(mode) {
|
|
222
|
+
gateMode = mode || gateMode;
|
|
223
|
+
if (typeof renderGateModeBanner === 'function') {
|
|
224
|
+
renderGateModeBanner(gateMode);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function _startGatePollingFallback() {
|
|
229
|
+
if (_gatePoller) return;
|
|
230
|
+
_gatePoller = setInterval(function() {
|
|
231
|
+
authFetch('/gate-state')
|
|
232
|
+
.then(function(r) { return r.json(); })
|
|
233
|
+
.then(function(data) { _onGateStateUpdate(data); })
|
|
234
|
+
.catch(function() {});
|
|
235
|
+
}, 10000);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function _stopGatePollingFallback() {
|
|
239
|
+
if (_gatePoller) { clearInterval(_gatePoller); _gatePoller = null; }
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function startGatePoller() {
|
|
243
|
+
// One-time fetches: initial gate-state + gate-mode. The SSE stream also
|
|
244
|
+
// pushes an initial gate-state on connect, but the fetch races with the
|
|
245
|
+
// EventSource open and we want whichever lands first to seed UI.
|
|
246
|
+
authFetch('/gate-state')
|
|
247
|
+
.then(function(r) { return r.json(); })
|
|
248
|
+
.then(_onGateStateUpdate)
|
|
249
|
+
.catch(function() {});
|
|
250
|
+
authFetch('/gate-mode')
|
|
251
|
+
.then(function(r) { return r.json(); })
|
|
252
|
+
.then(_onGateModeLoaded)
|
|
253
|
+
.catch(function() {});
|
|
254
|
+
|
|
255
|
+
_openGateStream();
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function _openGateStream() {
|
|
259
|
+
if (_gateEventSource) return;
|
|
260
|
+
// SSE EventSource can't set Authorization headers, so the server accepts
|
|
261
|
+
// ?token=… as a fallback (same pattern as /events).
|
|
262
|
+
var url = '/gate-state-stream?token=' + encodeURIComponent(SHARDS_TOKEN);
|
|
263
|
+
try {
|
|
264
|
+
_gateEventSource = new EventSource(url);
|
|
265
|
+
} catch (e) {
|
|
266
|
+
_startGatePollingFallback();
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
_gateEventSource.onopen = function() {
|
|
270
|
+
_stopGatePollingFallback();
|
|
271
|
+
};
|
|
272
|
+
_gateEventSource.onmessage = function(ev) {
|
|
273
|
+
var payload;
|
|
274
|
+
try { payload = JSON.parse(ev.data); } catch (e) { return; }
|
|
275
|
+
if (!payload || !payload.type) return;
|
|
276
|
+
if (payload.type === 'connected') return;
|
|
277
|
+
if (payload.type === 'gate-state') {
|
|
278
|
+
_onGateStateUpdate(payload.state);
|
|
279
|
+
} else if (payload.type === 'gate-block') {
|
|
280
|
+
_onGateBlock(payload);
|
|
281
|
+
} else if (payload.type === 'auto-state') {
|
|
282
|
+
// Reserved for future auto-verify HUD; non-fatal if no renderer.
|
|
283
|
+
if (typeof renderAutoStateBadge === 'function') renderAutoStateBadge(payload.state);
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
_gateEventSource.onerror = function() {
|
|
287
|
+
// EventSource auto-reconnects, but if the connection stays broken we
|
|
288
|
+
// also engage the 10s poll so the UI doesn't get stuck on stale state.
|
|
289
|
+
_startGatePollingFallback();
|
|
290
|
+
// If the connection is fully closed (readyState === 2), schedule an
|
|
291
|
+
// explicit reopen after a backoff window.
|
|
292
|
+
if (_gateEventSource && _gateEventSource.readyState === 2) {
|
|
293
|
+
try { _gateEventSource.close(); } catch (e) {}
|
|
294
|
+
_gateEventSource = null;
|
|
295
|
+
if (!_gateReconnectTimer) {
|
|
296
|
+
_gateReconnectTimer = setTimeout(function() {
|
|
297
|
+
_gateReconnectTimer = null;
|
|
298
|
+
_openGateStream();
|
|
299
|
+
}, 5000);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
function stopGatePoller() {
|
|
306
|
+
_stopGatePollingFallback();
|
|
307
|
+
if (_gateEventSource) {
|
|
308
|
+
try { _gateEventSource.close(); } catch (e) {}
|
|
309
|
+
_gateEventSource = null;
|
|
310
|
+
}
|
|
311
|
+
if (_gateReconnectTimer) {
|
|
312
|
+
clearTimeout(_gateReconnectTimer);
|
|
313
|
+
_gateReconnectTimer = null;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// Load workspace globals from the given session object
|
|
318
|
+
function loadSessionWorkspace(session) {
|
|
319
|
+
if (!session) {
|
|
320
|
+
sessionTouchedFiles = new Set();
|
|
321
|
+
openFiles = {};
|
|
322
|
+
fileTabOrder = [];
|
|
323
|
+
activeTabId = 'chat';
|
|
324
|
+
splitMode = false;
|
|
325
|
+
currentFileInPane = null;
|
|
326
|
+
openPanels = {};
|
|
327
|
+
panelTabOrder = [];
|
|
328
|
+
pinnedItems = [];
|
|
329
|
+
if (typeof renderPinboard === 'function') renderPinboard();
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
sessionTouchedFiles = session.sessionTouchedFiles;
|
|
333
|
+
openFiles = session.openFiles;
|
|
334
|
+
fileTabOrder = session.fileTabOrder;
|
|
335
|
+
activeTabId = session.activeTabId;
|
|
336
|
+
splitMode = session.splitMode;
|
|
337
|
+
currentFileInPane = session.currentFileInPane;
|
|
338
|
+
openPanels = session.openPanels;
|
|
339
|
+
panelTabOrder = session.panelTabOrder;
|
|
340
|
+
pinnedItems = session.pinnedItems || [];
|
|
341
|
+
if (typeof renderPinboard === 'function') renderPinboard();
|
|
342
|
+
if (typeof renderHud === 'function') renderHud();
|
|
343
|
+
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
// ═══════════════════════════════════════════════════════════════
|
|
2
|
+
// Tabulator.js integration
|
|
3
|
+
// ═══════════════════════════════════════════════════════════════
|
|
4
|
+
|
|
5
|
+
function destroyTabulator() {
|
|
6
|
+
if (activeTabulatorInstance) {
|
|
7
|
+
try { activeTabulatorInstance.destroy(); } catch(e) {}
|
|
8
|
+
activeTabulatorInstance = null;
|
|
9
|
+
activeTabularColumns = null;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function initTabulator(relPath, tableData) {
|
|
14
|
+
destroyTabulator();
|
|
15
|
+
|
|
16
|
+
var f = openFiles[relPath];
|
|
17
|
+
var editable = isEditableTabular(relPath);
|
|
18
|
+
|
|
19
|
+
// Store columns for serialization
|
|
20
|
+
activeTabularColumns = tableData.columns;
|
|
21
|
+
|
|
22
|
+
var columns = tableData.columns.map(function(col) {
|
|
23
|
+
return {
|
|
24
|
+
title: col,
|
|
25
|
+
field: col,
|
|
26
|
+
headerFilter: 'input',
|
|
27
|
+
sorter: 'string',
|
|
28
|
+
resizable: true,
|
|
29
|
+
editor: editable ? 'input' : false,
|
|
30
|
+
};
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
if (editable) {
|
|
34
|
+
columns.unshift({
|
|
35
|
+
formatter: 'rowSelection',
|
|
36
|
+
titleFormatter: 'rowSelection',
|
|
37
|
+
headerSort: false,
|
|
38
|
+
resizable: false,
|
|
39
|
+
width: 30,
|
|
40
|
+
cssClass: 'tabulator-row-select',
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
var container = document.getElementById('table-container');
|
|
45
|
+
container.innerHTML = '';
|
|
46
|
+
|
|
47
|
+
activeTabulatorInstance = new Tabulator(container, {
|
|
48
|
+
data: tableData.data,
|
|
49
|
+
columns: columns,
|
|
50
|
+
layout: 'fitDataFill',
|
|
51
|
+
height: '100%',
|
|
52
|
+
virtualDom: true,
|
|
53
|
+
selectableRows: editable ? true : false,
|
|
54
|
+
placeholder: 'No data',
|
|
55
|
+
cellEdited: editable ? function(cell) {
|
|
56
|
+
if (f) {
|
|
57
|
+
f.modified = true;
|
|
58
|
+
renderWsTabs();
|
|
59
|
+
}
|
|
60
|
+
} : undefined,
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// Update row count
|
|
64
|
+
activeTabulatorInstance.on('dataLoaded', function(data) {
|
|
65
|
+
document.getElementById('table-row-count').textContent = data.length + ' rows';
|
|
66
|
+
});
|
|
67
|
+
activeTabulatorInstance.on('dataFiltered', function(filters, rows) {
|
|
68
|
+
document.getElementById('table-row-count').textContent = rows.length + ' rows';
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// Show/hide edit buttons
|
|
72
|
+
var editBtns = document.getElementById('table-edit-btns');
|
|
73
|
+
editBtns.className = editable ? 'visible' : '';
|
|
74
|
+
|
|
75
|
+
// Wire up global search
|
|
76
|
+
var searchInput = document.getElementById('table-search');
|
|
77
|
+
searchInput.value = '';
|
|
78
|
+
searchInput.oninput = function() {
|
|
79
|
+
var term = searchInput.value.toLowerCase();
|
|
80
|
+
if (!term) {
|
|
81
|
+
activeTabulatorInstance.clearFilter();
|
|
82
|
+
} else {
|
|
83
|
+
activeTabulatorInstance.setFilter(function(data) {
|
|
84
|
+
return Object.values(data).some(function(v) {
|
|
85
|
+
return v != null && String(v).toLowerCase().includes(term);
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
// Store tabular data on file state
|
|
92
|
+
f.tabularData = tableData;
|
|
93
|
+
f.tabulatorInstance = activeTabulatorInstance;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function tableAddRow() {
|
|
97
|
+
if (!activeTabulatorInstance || !activeTabularColumns) return;
|
|
98
|
+
var empty = {};
|
|
99
|
+
for (var i = 0; i < activeTabularColumns.length; i++) empty[activeTabularColumns[i]] = '';
|
|
100
|
+
activeTabulatorInstance.addRow(empty);
|
|
101
|
+
var key = getCurrentFileKey();
|
|
102
|
+
if (key && openFiles[key]) {
|
|
103
|
+
openFiles[key].modified = true;
|
|
104
|
+
renderWsTabs();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function tableDeleteSelectedRows() {
|
|
109
|
+
if (!activeTabulatorInstance) return;
|
|
110
|
+
var selected = activeTabulatorInstance.getSelectedRows();
|
|
111
|
+
if (selected.length === 0) { alert('Select rows first (click the checkbox column)'); return; }
|
|
112
|
+
selected.forEach(function(row) { row.delete(); });
|
|
113
|
+
var key = getCurrentFileKey();
|
|
114
|
+
if (key && openFiles[key]) {
|
|
115
|
+
openFiles[key].modified = true;
|
|
116
|
+
renderWsTabs();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function tableAddColumn() {
|
|
121
|
+
if (!activeTabulatorInstance || !activeTabularColumns) return;
|
|
122
|
+
var name = prompt('Column name:');
|
|
123
|
+
if (!name || !name.trim()) return;
|
|
124
|
+
var colName = name.trim();
|
|
125
|
+
activeTabularColumns.push(colName);
|
|
126
|
+
activeTabulatorInstance.addColumn({
|
|
127
|
+
title: colName,
|
|
128
|
+
field: colName,
|
|
129
|
+
headerFilter: 'input',
|
|
130
|
+
sorter: 'string',
|
|
131
|
+
resizable: true,
|
|
132
|
+
editor: 'input',
|
|
133
|
+
});
|
|
134
|
+
var key = getCurrentFileKey();
|
|
135
|
+
if (key && openFiles[key]) {
|
|
136
|
+
openFiles[key].modified = true;
|
|
137
|
+
renderWsTabs();
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function tableDeleteColumn() {
|
|
142
|
+
if (!activeTabulatorInstance || !activeTabularColumns) return;
|
|
143
|
+
var name = prompt('Column name to delete:');
|
|
144
|
+
if (!name || !name.trim()) return;
|
|
145
|
+
var colName = name.trim();
|
|
146
|
+
if (!activeTabularColumns.includes(colName)) { alert('Column not found: ' + colName); return; }
|
|
147
|
+
activeTabulatorInstance.deleteColumn(colName);
|
|
148
|
+
activeTabularColumns = activeTabularColumns.filter(function(c) { return c !== colName; });
|
|
149
|
+
var key = getCurrentFileKey();
|
|
150
|
+
if (key && openFiles[key]) {
|
|
151
|
+
openFiles[key].modified = true;
|
|
152
|
+
renderWsTabs();
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function getTabulatorSerializedContent(relPath) {
|
|
157
|
+
if (!activeTabulatorInstance || !activeTabularColumns) return null;
|
|
158
|
+
var data = activeTabulatorInstance.getData();
|
|
159
|
+
var delimiter = getTabularDelimiter(relPath);
|
|
160
|
+
return serializeToDelimited(activeTabularColumns, data, delimiter);
|
|
161
|
+
}
|