@r1z4x/tezgah 1.9.2 → 1.11.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/CHANGELOG.md +83 -1
- package/MANIFEST +382 -144
- package/README.de.md +1 -1
- package/README.es.md +1 -1
- package/README.fr.md +1 -1
- package/README.md +1 -1
- package/README.tr.md +1 -1
- package/bin/codegen +5 -2
- package/bin/tezgah-design +288 -1
- package/bin/tezgah-docs +1 -1
- package/bin/tezgah-doctor +39 -2
- package/bin/tezgah-import-ai-research +26 -12
- package/bin/tezgah-ocr-review +296 -0
- package/bin/tezgah-research +216 -40
- package/bin/tezgah-review-quote +185 -0
- package/bin/tezgah-setup +136 -33
- package/bin/tezgah-skill +1 -1
- package/bin/tezgah-status +201 -3
- package/bin/tezgah-task +203 -3
- package/commands/adhd.md +2 -2
- package/commands/ponytail.md +4 -4
- package/docs/architecture.md +2 -2
- package/docs/citations-baseline.json +2 -2
- package/docs/clarity-baseline.json +2 -2
- package/docs/contract.md +87 -42
- package/docs/environment.md +2 -0
- package/docs/evidence.md +28 -9
- package/docs/feature-audit.md +2 -2
- package/docs/gate.md +54 -31
- package/docs/glossary.md +5 -2
- package/docs/hosts.md +17 -3
- package/docs/index.json +34 -8
- package/docs/judge.md +4 -2
- package/docs/layers.md +3 -3
- package/docs/models.md +31 -9
- package/docs/operations.md +126 -1
- package/docs/research.md +786 -5
- package/docs/skills.md +137 -13
- package/docs/status-line.md +115 -1
- package/hooks/hooks.json +1 -1
- package/hooks/lang/en.json +10 -0
- package/hooks/lang/tr.json +11 -1
- package/hooks/tezgah_agents.py +38 -22
- package/hooks/tezgah_apps.py +18 -0
- package/hooks/tezgah_components.py +4 -0
- package/hooks/tezgah_context.py +189 -50
- package/hooks/tezgah_extension.py +337 -0
- package/hooks/tezgah_gate.py +188 -56
- package/hooks/tezgah_integrity.py +652 -105
- package/hooks/tezgah_judge.py +6 -4
- package/hooks/tezgah_models.py +59 -19
- package/hooks/tezgah_orca.py +1 -1
- package/hooks/tezgah_paths.py +102 -6
- package/hooks/tezgah_policy.py +94 -45
- package/hooks/tezgah_rank.py +9 -6
- package/hooks/tezgah_replay.py +4 -4
- package/hooks/tezgah_research.py +1260 -65
- package/hooks/tezgah_research_capture.py +1544 -0
- package/hooks/tezgah_research_evidence.py +842 -0
- package/hooks/tezgah_research_stats.py +258 -0
- package/hooks/tezgah_skill_pick.py +408 -106
- package/hooks/tezgah_stopspec.py +8 -1
- package/hooks/tezgah_task.py +12 -4
- package/hooks/tezgah_taste_ledger.py +1 -1
- package/hosts/cursor/hook.py +29 -2
- package/hosts/opencode/plugins/tezgah.js +307 -46
- package/hosts/opencode/tui/cli/tui.tsx +100 -0
- package/hosts/opencode/tui/tezgah-tui.tsx +2 -1
- package/output-styles/tezgah.md +10 -10
- package/package.json +1 -1
- package/skills/ai-research/SKILL.md +21 -14
- package/skills/ai-research/SOURCE +7 -5
- package/skills/ai-research/index/1-frame.md +6 -6
- package/skills/ai-research/index/2-data.md +9 -9
- package/skills/ai-research/index/3-train.md +36 -36
- package/skills/ai-research/index/4-measure.md +13 -13
- package/skills/ai-research/index/5-run.md +11 -11
- package/skills/ai-research/index/6-write.md +23 -23
- package/skills/ai-research/library.json +104 -104
- package/skills/analyze-app/SKILL.md +17 -12
- package/skills/design-contract/SKILL.md +42 -7
- package/skills/design-contract/data-views.md +2 -2
- package/skills/design-library/EVALS.md +1 -1
- package/skills/design-library/INDEX.md +39 -39
- package/skills/design-library/SKILL.md +19 -13
- package/skills/design-library/SOURCE +45 -43
- package/skills/feature-audit/SKILL.md +20 -14
- package/skills/hallmark/LICENSE +21 -0
- package/skills/hallmark/SKILL.md +154 -0
- package/skills/hallmark/SOURCE +207 -0
- package/skills/hallmark/agents/openai.yaml +13 -0
- package/skills/hallmark/references/anatomy.md +71 -0
- package/skills/hallmark/references/brand-truth.md +40 -0
- package/skills/hallmark/references/comp.md +104 -0
- package/skills/hallmark/references/craft.md +116 -0
- package/skills/hallmark/references/dark-mode.md +49 -0
- package/skills/hallmark/references/data-viz.md +48 -0
- package/skills/hallmark/references/design-md.md +53 -0
- package/skills/hallmark/references/direction.md +52 -0
- package/skills/hallmark/references/export-formats.md +80 -0
- package/skills/hallmark/references/flow.md +131 -0
- package/skills/hallmark/references/fonts.md +58 -0
- package/skills/hallmark/references/gates.md +243 -0
- package/skills/hallmark/references/genres/atmospheric.md +24 -0
- package/skills/hallmark/references/genres/editorial.md +24 -0
- package/skills/hallmark/references/genres/modern-minimal.md +24 -0
- package/skills/hallmark/references/genres/playful.md +24 -0
- package/skills/hallmark/references/imagery.md +99 -0
- package/skills/hallmark/references/interaction-and-states.md +89 -0
- package/skills/hallmark/references/layout.md +104 -0
- package/skills/hallmark/references/macrostructures/01-bento-grid.md +21 -0
- package/skills/hallmark/references/macrostructures/02-long-document.md +35 -0
- package/skills/hallmark/references/macrostructures/03-marquee-hero.md +21 -0
- package/skills/hallmark/references/macrostructures/04-stat-led.md +21 -0
- package/skills/hallmark/references/macrostructures/05-workbench.md +21 -0
- package/skills/hallmark/references/macrostructures/06-conversational-faq.md +28 -0
- package/skills/hallmark/references/macrostructures/07-manifesto.md +28 -0
- package/skills/hallmark/references/macrostructures/08-photographic.md +21 -0
- package/skills/hallmark/references/macrostructures/09-quote-led.md +21 -0
- package/skills/hallmark/references/macrostructures/10-specimen.md +21 -0
- package/skills/hallmark/references/macrostructures/11-catalogue.md +21 -0
- package/skills/hallmark/references/macrostructures/12-letter.md +21 -0
- package/skills/hallmark/references/macrostructures/13-index-first.md +21 -0
- package/skills/hallmark/references/macrostructures/14-narrative-workflow.md +21 -0
- package/skills/hallmark/references/macrostructures/15-split-studio.md +21 -0
- package/skills/hallmark/references/macrostructures/16-feature-stack.md +23 -0
- package/skills/hallmark/references/macrostructures/17-type-specimen.md +19 -0
- package/skills/hallmark/references/macrostructures/18-portfolio-grid.md +21 -0
- package/skills/hallmark/references/macrostructures/19-map-diagram.md +21 -0
- package/skills/hallmark/references/macrostructures/20-ecosystem-index.md +19 -0
- package/skills/hallmark/references/macrostructures/21-component-playground.md +21 -0
- package/skills/hallmark/references/macrostructures.md +119 -0
- package/skills/hallmark/references/microinteractions.md +80 -0
- package/skills/hallmark/references/patterns.md +202 -0
- package/skills/hallmark/references/redesign.md +88 -0
- package/skills/hallmark/references/responsive.md +46 -0
- package/skills/hallmark/references/review-finish.md +19 -0
- package/skills/hallmark/references/review-hero.md +20 -0
- package/skills/hallmark/references/scroll-choreography.md +110 -0
- package/skills/hallmark/references/texture.md +90 -0
- package/skills/hallmark/references/themes/README.md +58 -0
- package/skills/hallmark/references/themes/almanac.jpg +0 -0
- package/skills/hallmark/references/themes/almanac.md +103 -0
- package/skills/hallmark/references/themes/arcade.jpg +0 -0
- package/skills/hallmark/references/themes/arcade.md +102 -0
- package/skills/hallmark/references/themes/atelier.jpg +0 -0
- package/skills/hallmark/references/themes/atelier.md +98 -0
- package/skills/hallmark/references/themes/bloom.jpg +0 -0
- package/skills/hallmark/references/themes/bloom.md +102 -0
- package/skills/hallmark/references/themes/blueprint.jpg +0 -0
- package/skills/hallmark/references/themes/blueprint.md +103 -0
- package/skills/hallmark/references/themes/broadside.jpg +0 -0
- package/skills/hallmark/references/themes/broadside.md +108 -0
- package/skills/hallmark/references/themes/brutal.jpg +0 -0
- package/skills/hallmark/references/themes/brutal.md +95 -0
- package/skills/hallmark/references/themes/carnival.jpg +0 -0
- package/skills/hallmark/references/themes/carnival.md +104 -0
- package/skills/hallmark/references/themes/cobalt.jpg +0 -0
- package/skills/hallmark/references/themes/cobalt.md +101 -0
- package/skills/hallmark/references/themes/console.jpg +0 -0
- package/skills/hallmark/references/themes/console.md +99 -0
- package/skills/hallmark/references/themes/coral.jpg +0 -0
- package/skills/hallmark/references/themes/coral.md +102 -0
- package/skills/hallmark/references/themes/darkroom.jpg +0 -0
- package/skills/hallmark/references/themes/darkroom.md +99 -0
- package/skills/hallmark/references/themes/dose.jpg +0 -0
- package/skills/hallmark/references/themes/dose.md +98 -0
- package/skills/hallmark/references/themes/dusk.jpg +0 -0
- package/skills/hallmark/references/themes/dusk.md +105 -0
- package/skills/hallmark/references/themes/editorial.jpg +0 -0
- package/skills/hallmark/references/themes/editorial.md +97 -0
- package/skills/hallmark/references/themes/formwork.jpg +0 -0
- package/skills/hallmark/references/themes/formwork.md +107 -0
- package/skills/hallmark/references/themes/furrow.jpg +0 -0
- package/skills/hallmark/references/themes/furrow.md +98 -0
- package/skills/hallmark/references/themes/garden.jpg +0 -0
- package/skills/hallmark/references/themes/garden.md +97 -0
- package/skills/hallmark/references/themes/grid.jpg +0 -0
- package/skills/hallmark/references/themes/grid.md +101 -0
- package/skills/hallmark/references/themes/halftone.jpg +0 -0
- package/skills/hallmark/references/themes/halftone.md +106 -0
- package/skills/hallmark/references/themes/hedgerow.jpg +0 -0
- package/skills/hallmark/references/themes/hedgerow.md +104 -0
- package/skills/hallmark/references/themes/hum.jpg +0 -0
- package/skills/hallmark/references/themes/hum.md +99 -0
- package/skills/hallmark/references/themes/index.json +2191 -0
- package/skills/hallmark/references/themes/ink.jpg +0 -0
- package/skills/hallmark/references/themes/ink.md +106 -0
- package/skills/hallmark/references/themes/kiln.jpg +0 -0
- package/skills/hallmark/references/themes/kiln.md +108 -0
- package/skills/hallmark/references/themes/loom.jpg +0 -0
- package/skills/hallmark/references/themes/loom.md +106 -0
- package/skills/hallmark/references/themes/lumen.jpg +0 -0
- package/skills/hallmark/references/themes/lumen.md +103 -0
- package/skills/hallmark/references/themes/manifesto.jpg +0 -0
- package/skills/hallmark/references/themes/manifesto.md +101 -0
- package/skills/hallmark/references/themes/midnight.jpg +0 -0
- package/skills/hallmark/references/themes/midnight.md +97 -0
- package/skills/hallmark/references/themes/newsprint.jpg +0 -0
- package/skills/hallmark/references/themes/newsprint.md +102 -0
- package/skills/hallmark/references/themes/overprint.jpg +0 -0
- package/skills/hallmark/references/themes/overprint.md +101 -0
- package/skills/hallmark/references/themes/pasteup.jpg +0 -0
- package/skills/hallmark/references/themes/pasteup.md +100 -0
- package/skills/hallmark/references/themes/piste.jpg +0 -0
- package/skills/hallmark/references/themes/piste.md +99 -0
- package/skills/hallmark/references/themes/ribbon.jpg +0 -0
- package/skills/hallmark/references/themes/ribbon.md +106 -0
- package/skills/hallmark/references/themes/rim.jpg +0 -0
- package/skills/hallmark/references/themes/rim.md +96 -0
- package/skills/hallmark/references/themes/riso.jpg +0 -0
- package/skills/hallmark/references/themes/riso.md +98 -0
- package/skills/hallmark/references/themes/solstice.jpg +0 -0
- package/skills/hallmark/references/themes/solstice.md +104 -0
- package/skills/hallmark/references/themes/specimen.jpg +0 -0
- package/skills/hallmark/references/themes/specimen.md +100 -0
- package/skills/hallmark/references/themes/spore.jpg +0 -0
- package/skills/hallmark/references/themes/spore.md +104 -0
- package/skills/hallmark/references/themes/sport.jpg +0 -0
- package/skills/hallmark/references/themes/sport.md +101 -0
- package/skills/hallmark/references/themes/squeeze.jpg +0 -0
- package/skills/hallmark/references/themes/squeeze.md +99 -0
- package/skills/hallmark/references/themes/sticker.jpg +0 -0
- package/skills/hallmark/references/themes/sticker.md +106 -0
- package/skills/hallmark/references/themes/studio.jpg +0 -0
- package/skills/hallmark/references/themes/studio.md +99 -0
- package/skills/hallmark/references/themes/terminal.jpg +0 -0
- package/skills/hallmark/references/themes/terminal.md +96 -0
- package/skills/hallmark/references/themes/terrazzo.jpg +0 -0
- package/skills/hallmark/references/themes/terrazzo.md +106 -0
- package/skills/hallmark/references/themes/ultraviolet.jpg +0 -0
- package/skills/hallmark/references/themes/ultraviolet.md +106 -0
- package/skills/hallmark/references/themes/vellum.jpg +0 -0
- package/skills/hallmark/references/themes/vellum.md +105 -0
- package/skills/hallmark/references/themes/wayfind.jpg +0 -0
- package/skills/hallmark/references/themes/wayfind.md +105 -0
- package/skills/hallmark/references/themes/werkstatt.jpg +0 -0
- package/skills/hallmark/references/themes/werkstatt.md +105 -0
- package/skills/hallmark/scripts/capture.mjs +125 -0
- package/skills/hallmark/scripts/fixtures/exemplars/atmospheric.html +324 -0
- package/skills/hallmark/scripts/fixtures/exemplars/editorial.html +363 -0
- package/skills/hallmark/scripts/fixtures/exemplars/modern-minimal.html +527 -0
- package/skills/hallmark/scripts/fixtures/exemplars/playful.html +353 -0
- package/skills/hallmark/scripts/fixtures/eyebrow-fail/index.html +118 -0
- package/skills/hallmark/scripts/fixtures/eyebrow-pass/index.html +137 -0
- package/skills/hallmark/scripts/fixtures/kept/after.html +27 -0
- package/skills/hallmark/scripts/fixtures/kept/before.html +26 -0
- package/skills/hallmark/scripts/fixtures/slopped.html +145 -0
- package/skills/hallmark/scripts/fixtures/tailwind-fail/Feature.vue +14 -0
- package/skills/hallmark/scripts/fixtures/tailwind-fail/Hero.tsx +33 -0
- package/skills/hallmark/scripts/fixtures/tailwind-fail/index.html +74 -0
- package/skills/hallmark/scripts/fixtures/tailwind-fail/style.css +6 -0
- package/skills/hallmark/scripts/fixtures/tailwind-pass/Hero.tsx +33 -0
- package/skills/hallmark/scripts/fixtures/tailwind-pass/index.html +57 -0
- package/skills/hallmark/scripts/fixtures/tailwind-pass/style.css +15 -0
- package/skills/hallmark/scripts/fixtures/waiver/index.html +54 -0
- package/skills/hallmark/scripts/imagegen.mjs +85 -0
- package/skills/hallmark/scripts/install-hook.mjs +70 -0
- package/skills/hallmark/scripts/install.mjs +141 -0
- package/skills/hallmark/scripts/lint-hook.mjs +49 -0
- package/skills/hallmark/scripts/photos.json +1 -0
- package/skills/hallmark/scripts/picture.mjs +71 -0
- package/skills/hallmark/scripts/refcheck.mjs +352 -0
- package/skills/hallmark/scripts/sloplint-render.mjs +1252 -0
- package/skills/hallmark/scripts/sloplint.mjs +4422 -0
- package/skills/hallmark/scripts/theme.mjs +650 -0
- package/skills/harness/SKILL.md +15 -8
- package/skills/i-have-adhd/SKILL.md +22 -11
- package/skills/no-ai-slop/SKILL.md +15 -1
- package/skills/plan-add/SKILL.md +33 -26
- package/skills/plan-status/SKILL.md +13 -7
- package/skills/plan-sync/SKILL.md +18 -12
- package/skills/pm-frameworks/SKILL.md +19 -10
- package/skills/pm-frameworks/SOURCE +7 -5
- package/skills/ponytail/SKILL.md +19 -14
- package/skills/product-analysis/SKILL.md +22 -18
- package/skills/product-flow/SKILL.md +14 -9
- package/skills/research/SKILL.md +75 -39
- package/skills/rl-env/SKILL.md +25 -13
- package/skills/rl-env/SOURCE +8 -6
- package/skills/tezgah-contract/SKILL.md +47 -42
- package/bin/tezgah-skill.py +0 -59
- /package/skills/ai-research/0-autoresearch-skill/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/01-model-architecture/litgpt/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/01-model-architecture/mamba/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/01-model-architecture/nanogpt/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/01-model-architecture/rwkv/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/01-model-architecture/torchtitan/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/02-tokenization/huggingface-tokenizers/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/02-tokenization/sentencepiece/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/03-fine-tuning/axolotl/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/03-fine-tuning/llama-factory/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/03-fine-tuning/peft/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/03-fine-tuning/unsloth/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/04-mechanistic-interpretability/nnsight/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/04-mechanistic-interpretability/pyvene/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/04-mechanistic-interpretability/saelens/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/04-mechanistic-interpretability/transformer-lens/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/05-data-processing/nemo-curator/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/05-data-processing/ray-data/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/06-post-training/grpo-rl-training/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/06-post-training/miles/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/06-post-training/openrlhf/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/06-post-training/simpo/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/06-post-training/slime/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/06-post-training/torchforge/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/06-post-training/trl-fine-tuning/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/06-post-training/verl/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/07-safety-alignment/constitutional-ai/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/07-safety-alignment/llamaguard/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/07-safety-alignment/nemo-guardrails/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/07-safety-alignment/prompt-guard/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/08-distributed-training/accelerate/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/08-distributed-training/deepspeed/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/08-distributed-training/megatron-core/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/08-distributed-training/pytorch-fsdp2/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/08-distributed-training/pytorch-lightning/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/08-distributed-training/ray-train/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/09-infrastructure/lambda-labs/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/09-infrastructure/modal/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/09-infrastructure/skypilot/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/10-optimization/awq/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/10-optimization/bitsandbytes/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/10-optimization/flash-attention/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/10-optimization/gguf/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/10-optimization/gptq/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/10-optimization/hqq/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/10-optimization/ml-training-recipes/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/11-evaluation/bigcode-evaluation-harness/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/11-evaluation/lm-evaluation-harness/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/11-evaluation/nemo-evaluator/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/12-inference-serving/llama-cpp/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/12-inference-serving/sglang/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/12-inference-serving/tensorrt-llm/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/12-inference-serving/vllm/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/13-mlops/mlflow/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/13-mlops/swanlab/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/13-mlops/tensorboard/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/13-mlops/weights-and-biases/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/14-agents/a-evolve/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/14-agents/autogpt/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/14-agents/crewai/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/14-agents/langchain/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/14-agents/llamaindex/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/15-rag/chroma/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/15-rag/faiss/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/15-rag/pinecone/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/15-rag/qdrant/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/15-rag/sentence-transformers/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/16-prompt-engineering/dspy/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/16-prompt-engineering/guidance/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/16-prompt-engineering/instructor/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/16-prompt-engineering/outlines/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/17-observability/langsmith/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/17-observability/phoenix/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/18-multimodal/audiocraft/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/18-multimodal/blip-2/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/18-multimodal/clip/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/18-multimodal/cosmos-policy/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/18-multimodal/llava/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/18-multimodal/openpi/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/18-multimodal/openvla-oft/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/18-multimodal/segment-anything/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/18-multimodal/stable-diffusion/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/18-multimodal/whisper/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/19-emerging-techniques/knowledge-distillation/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/19-emerging-techniques/long-context/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/19-emerging-techniques/model-merging/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/19-emerging-techniques/model-pruning/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/19-emerging-techniques/moe-training/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/19-emerging-techniques/speculative-decoding/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/20-ml-paper-writing/academic-plotting/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/20-ml-paper-writing/ml-paper-writing/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/20-ml-paper-writing/presenting-conference-talks/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/20-ml-paper-writing/systems-paper-writing/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/21-research-ideation/brainstorming-research-ideas/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/21-research-ideation/creative-thinking-for-research/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/22-agent-native-research-artifact/compiler/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/22-agent-native-research-artifact/research-manager/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/ai-research/22-agent-native-research-artifact/rigor-reviewer/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/adaptive-interfaces/skills/colour-independence/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/adaptive-interfaces/skills/flexible-typography/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/adaptive-interfaces/skills/information-density/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/adaptive-interfaces/skills/preference-audit/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/adaptive-interfaces/skills/responsive-accessibility/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/adaptive-interfaces/skills/responsive-review/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/adaptive-interfaces/skills/simplified-views/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/adaptive-interfaces/skills/specify/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/adaptive-interfaces/skills/user-preference-respect/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/cognitive-accessibility/skills/adaptive-personalisation/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/cognitive-accessibility/skills/assess-load/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/cognitive-accessibility/skills/cognitive-load-assessment/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/cognitive-accessibility/skills/contextual-help-design/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/cognitive-accessibility/skills/error-prevention-recovery/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/cognitive-accessibility/skills/focus-attention-design/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/cognitive-accessibility/skills/memory-load-reduction/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/cognitive-accessibility/skills/plain-language-design/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/cognitive-accessibility/skills/review/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/cognitive-accessibility/skills/simplify/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/cognitive-accessibility/skills/wayfinding-navigation/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/design-research/skills/behavioural-analytics/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/design-research/skills/qual-quant-triangulation/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/inclusive-interaction/skills/audit/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/inclusive-interaction/skills/design-flow/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/inclusive-interaction/skills/feedback-and-status/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/inclusive-interaction/skills/gesture-alternatives/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/inclusive-interaction/skills/keyboard-navigation/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/inclusive-interaction/skills/keyboard-review/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/inclusive-interaction/skills/motion-sensitivity/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/inclusive-interaction/skills/multi-modal-input/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/inclusive-interaction/skills/touch-target-design/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/inclusive-interaction/skills/voice-interaction/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/visual-critique/skills/critique-affordance/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/visual-critique/skills/critique-brand-consistency/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/visual-critique/skills/critique-color/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/visual-critique/skills/critique-composition/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/visual-critique/skills/critique-information-density/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/visual-critique/skills/critique-typography/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/design-library/visual-critique/skills/critique-visual-hierarchy/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/pm-frameworks/intended-vs-implemented/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/pm-frameworks/opportunity-solution-tree/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/rl-env/generate-nemo-gym-env/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/rl-env/generate-openenv-env/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/rl-env/generate-ors-env/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/rl-env/generate-verifiers-env/{SKILL.md → ENTRY.md} +0 -0
- /package/skills/rl-env/rl-env-from-description/{SKILL.md → ENTRY.md} +0 -0
package/bin/tezgah-setup
CHANGED
|
@@ -188,7 +188,7 @@ LOCAL_BIN = os.path.join(HOME, ".local", "bin")
|
|
|
188
188
|
SKILLS = ["harness", "tezgah-contract", "ponytail", "i-have-adhd", "no-ai-slop",
|
|
189
189
|
"analyze-app", "plan-add", "plan-status", "plan-sync", "research",
|
|
190
190
|
"product-analysis", "product-flow", "feature-audit", "design-contract",
|
|
191
|
-
"design-library", "pm-frameworks", "ai-research", "rl-env"]
|
|
191
|
+
"design-library", "hallmark", "pm-frameworks", "ai-research", "rl-env"]
|
|
192
192
|
|
|
193
193
|
|
|
194
194
|
def skills_linked(base):
|
|
@@ -209,6 +209,19 @@ RESEARCH_SKILLS = frozenset(("ai-research", "rl-env"))
|
|
|
209
209
|
# explicit value wins.
|
|
210
210
|
OPENCODE_IGNORE = [".git/**", "node_modules/**", "dist/**", "build/**",
|
|
211
211
|
".venv/**", "__pycache__/**", ".ruff_cache/**"]
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def opencode_v2():
|
|
215
|
+
"""opencode 2 keeps its terminal settings in cli.json (it migrates tui.json
|
|
216
|
+
into it once, on first start) and ignores tui.json afterwards."""
|
|
217
|
+
return os.path.isfile(os.path.join(OPENCODE, "cli.json"))
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
# The opencode 2 status line: a link to the plugin directory hosts/opencode/tui/cli,
|
|
221
|
+
# listed in cli.json `plugins` as file://<this path>.
|
|
222
|
+
OPENCODE_CLI_PLUGIN = os.path.join(OPENCODE, "tui-plugins", "tezgah-cli")
|
|
223
|
+
|
|
224
|
+
|
|
212
225
|
WORKFLOW_FILES = ["graph-map.js", "graph-review.js", "graph-impact.js"]
|
|
213
226
|
ALL_HOSTS = ["claude", "codex", "opencode", "cursor", "dsh", "omp"]
|
|
214
227
|
# orx ships an installable skill shim for four agents; dsh has no orx harness,
|
|
@@ -231,7 +244,8 @@ MATERIALISED = os.path.join(tp.CONFIG_DIR, "materialised")
|
|
|
231
244
|
# copies die with ~/.config/tezgah; the pre-multi-host setup wrote them to
|
|
232
245
|
# ~/.claude, which OFF_DIRS still honors, so a full uninstall sweeps those by
|
|
233
246
|
# name too - a switch left behind is a rule that stays silent with no file saying why.
|
|
234
|
-
OFF_SWITCH_NAMES = ("adhd-off", "agents-off", "consult-off", "
|
|
247
|
+
OFF_SWITCH_NAMES = ("adhd-off", "agents-off", "consult-off", "design-off", "docs-judge-off",
|
|
248
|
+
"exec-mode.off",
|
|
235
249
|
"judge-off", "lang-off", "orchestrate-off", "ponytail-auto.off",
|
|
236
250
|
"pretooluse-off", "reminder-off", "research-off", "slices-off",
|
|
237
251
|
"spec-off", "task-off", "triage-off", "update-check-off", "verify-off",
|
|
@@ -1039,7 +1053,10 @@ def install_common(new_roots, hosts):
|
|
|
1039
1053
|
(tp.roots() or [tp.DEFAULT_ROOT])
|
|
1040
1054
|
if tp.codegraph_bin():
|
|
1041
1055
|
cfg["codegraph_bin"] = tp.codegraph_bin()
|
|
1042
|
-
|
|
1056
|
+
# merged with the record, never replaced: arming one host must not drop
|
|
1057
|
+
# the others, whose wiring stays on disk and which --upgrade reads from here
|
|
1058
|
+
recorded = cfg.get("hosts") if isinstance(cfg.get("hosts"), list) else []
|
|
1059
|
+
cfg["hosts"] = recorded + [h for h in hosts if h not in recorded]
|
|
1043
1060
|
# The resolved selection, written beside roots/hosts: the next run reads one
|
|
1044
1061
|
# persisted answer instead of the flags some earlier run happened to carry,
|
|
1045
1062
|
# which is what lets --disable mean anything. A key absent here (and in the
|
|
@@ -1090,6 +1107,8 @@ def install_common(new_roots, hosts):
|
|
|
1090
1107
|
("tezgah-route", os.path.join(HERE, "bin", "tezgah-route")),
|
|
1091
1108
|
("tezgah-lessons", os.path.join(HERE, "bin", "tezgah-lessons")),
|
|
1092
1109
|
("tezgah-skill", os.path.join(HERE, "bin", "tezgah-skill")),
|
|
1110
|
+
("tezgah-review-quote", os.path.join(HERE, "bin", "tezgah-review-quote")),
|
|
1111
|
+
("tezgah-ocr-review", os.path.join(HERE, "bin", "tezgah-ocr-review")),
|
|
1093
1112
|
# `tezgah` is this installer under the name `tezgah update` is typed
|
|
1094
1113
|
# with (npm ships the same name). Not here on purpose: tezgah-dsh
|
|
1095
1114
|
# (wired as ~/.local/bin/dsh, see dsh_launcher) and
|
|
@@ -1647,6 +1666,11 @@ def skill_description(path):
|
|
|
1647
1666
|
else:
|
|
1648
1667
|
inline = re.search(r"description:\s*(.+)", block.group(1))
|
|
1649
1668
|
desc = inline.group(1).strip().strip("\"'") if inline else ""
|
|
1669
|
+
return _trigger_line(desc)
|
|
1670
|
+
|
|
1671
|
+
|
|
1672
|
+
def _trigger_line(desc):
|
|
1673
|
+
"""The sentence of `desc` carrying its `Use when ...` trigger, cut at 140."""
|
|
1650
1674
|
desc = re.sub(r"\s+", " ", desc).strip()
|
|
1651
1675
|
sentences = re.split(r"(?<=[.!?])\s+", desc)
|
|
1652
1676
|
line = next((s for s in sentences if re.match(r"(?:Also )?[Uu]se\b", s)),
|
|
@@ -1654,6 +1678,22 @@ def skill_description(path):
|
|
|
1654
1678
|
return line[:137].rstrip() + "..." if len(line) > 140 else line
|
|
1655
1679
|
|
|
1656
1680
|
|
|
1681
|
+
def skill_when_line(path):
|
|
1682
|
+
"""The trigger line of a SKILL.md body's `## When to use` first paragraph.
|
|
1683
|
+
|
|
1684
|
+
The frontmatter description is a short bilingual trigger list now, too short
|
|
1685
|
+
for two near-neighbours to share subject words; the long text it replaced
|
|
1686
|
+
opens the body's `## When to use`, and that is what still tells them apart.
|
|
1687
|
+
Best effort like skill_description: anything unreadable yields ""."""
|
|
1688
|
+
try:
|
|
1689
|
+
with open(path, encoding="utf-8", errors="replace") as fh:
|
|
1690
|
+
text = fh.read()
|
|
1691
|
+
except OSError:
|
|
1692
|
+
return ""
|
|
1693
|
+
para = re.search(r"^## When to use\n\s*\n(.*?)(?:\n\s*\n|\Z)", text, re.M | re.S)
|
|
1694
|
+
return _trigger_line(para.group(1)) if para else ""
|
|
1695
|
+
|
|
1696
|
+
|
|
1657
1697
|
def skill_category(name, path=""):
|
|
1658
1698
|
if name in RESEARCH_SKILLS:
|
|
1659
1699
|
return "research & papers"
|
|
@@ -1734,12 +1774,12 @@ under out up down off again more most other some such only own same too very can
|
|
|
1734
1774
|
will just don should now read reads reading use used uses using also one two
|
|
1735
1775
|
three every each any all both new old
|
|
1736
1776
|
""".split())
|
|
1737
|
-
# Two skills a session could pick either way from:
|
|
1738
|
-
# many subject words, so the description alone
|
|
1739
|
-
# where the shipped set
|
|
1740
|
-
#
|
|
1741
|
-
#
|
|
1742
|
-
#
|
|
1777
|
+
# Two skills a session could pick either way from: the trigger lines of their
|
|
1778
|
+
# `## When to use` share this many subject words, so the description alone
|
|
1779
|
+
# cannot settle the choice. Three is where the shipped set pairs near-neighbours -
|
|
1780
|
+
# `plan-add` / `plan-status` / `plan-sync` share four or five terms,
|
|
1781
|
+
# `product-analysis` / `feature-audit` and `design-contract` / `design-library`
|
|
1782
|
+
# three - while `ponytail` / `i-have-adhd` stay apart.
|
|
1743
1783
|
COLLISION_SHARED = 3
|
|
1744
1784
|
|
|
1745
1785
|
|
|
@@ -1758,7 +1798,7 @@ def skill_collisions(groups):
|
|
|
1758
1798
|
router is what a session picks from when the descriptions tie. It reads the
|
|
1759
1799
|
shipped names only: a vendored library's internal collisions are its own
|
|
1760
1800
|
index's business, and a pair tezgah cannot rename is not a tezgah decision."""
|
|
1761
|
-
lines = {name:
|
|
1801
|
+
lines = {name: skill_when_line(path)
|
|
1762
1802
|
for cat in ROUTER_ORDER for name, path in groups[cat]
|
|
1763
1803
|
if name in SKILLS}
|
|
1764
1804
|
names = sorted(lines)
|
|
@@ -1778,7 +1818,8 @@ def _collision_section(pairs):
|
|
|
1778
1818
|
out = [
|
|
1779
1819
|
"## Collisions",
|
|
1780
1820
|
"",
|
|
1781
|
-
"Pairs a description alone cannot settle: both
|
|
1821
|
+
"Pairs a description alone cannot settle: both entries' `## When to use`"
|
|
1822
|
+
" lines carry the"
|
|
1782
1823
|
" words below, so a session could pick either way from them. Read both"
|
|
1783
1824
|
" entries before choosing.",
|
|
1784
1825
|
"",
|
|
@@ -1856,20 +1897,38 @@ def install_opencode():
|
|
|
1856
1897
|
write_artifact(SKILL_ROUTER_FULL, full, write_if_changed)
|
|
1857
1898
|
print("%s %s (always-on, %d chars)" % (OK, SKILL_ROUTER, len(always)))
|
|
1858
1899
|
print("%s %s (on demand, %d chars)" % (OK, SKILL_ROUTER_FULL, len(full)))
|
|
1859
|
-
# TUI status line: opencode has no command statusLine, only a TUI plugin
|
|
1860
|
-
#
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1900
|
+
# TUI status line: opencode has no command statusLine, only a TUI plugin.
|
|
1901
|
+
# opencode 1 declares it in tui.json (a local spec resolves relative to it);
|
|
1902
|
+
# opencode 2 ignores tui.json and lists CLI plugins in cli.json `plugins`. A
|
|
1903
|
+
# local v2 entry must name a DIRECTORY whose `tui` module default-exports
|
|
1904
|
+
# Plugin.define({id, setup}) - a spec naming a file is skipped (measured on
|
|
1905
|
+
# v2.0.32) - so the directory hosts/opencode/tui/cli is what gets linked.
|
|
1906
|
+
v2 = opencode_v2()
|
|
1907
|
+
if v2:
|
|
1908
|
+
dst = OPENCODE_CLI_PLUGIN
|
|
1909
|
+
print(link(os.path.join(HERE, "hosts", "opencode", "tui", "cli"), dst))
|
|
1910
|
+
cpath = os.path.join(OPENCODE, "cli.json")
|
|
1911
|
+
cli = read_config(cpath, {})
|
|
1912
|
+
if cli is not None:
|
|
1913
|
+
plugins = cli.get("plugins") or []
|
|
1914
|
+
if "file://" + dst not in plugins:
|
|
1915
|
+
plugins.append("file://" + dst)
|
|
1916
|
+
cli["plugins"] = plugins
|
|
1917
|
+
write_json(cpath, cli)
|
|
1918
|
+
print("%s cli.json (status line plugin)" % OK)
|
|
1919
|
+
else:
|
|
1920
|
+
print(link(os.path.join(HERE, "hosts", "opencode", "tui", "tezgah-tui.tsx"),
|
|
1921
|
+
os.path.join(OPENCODE, "tui-plugins", "tezgah-tui.tsx")))
|
|
1922
|
+
tpath = os.path.join(OPENCODE, "tui.json")
|
|
1923
|
+
tui = read_config(tpath, {"$schema": "https://opencode.ai/tui.json"})
|
|
1924
|
+
if tui is not None:
|
|
1925
|
+
plugins = tui.get("plugin") or []
|
|
1926
|
+
spec = "./tui-plugins/tezgah-tui.tsx"
|
|
1927
|
+
if spec not in [p if isinstance(p, str) else p[0] for p in plugins]:
|
|
1928
|
+
plugins.append(spec)
|
|
1929
|
+
tui["plugin"] = plugins
|
|
1930
|
+
write_json(tpath, tui)
|
|
1931
|
+
print("%s tui.json (status line plugin)" % OK)
|
|
1873
1932
|
cfg = read_config(os.path.join(OPENCODE, "opencode.json"),
|
|
1874
1933
|
{"$schema": "https://opencode.ai/config.json"})
|
|
1875
1934
|
if cfg is None:
|
|
@@ -1921,7 +1980,8 @@ def install_opencode():
|
|
|
1921
1980
|
# Context hygiene: prune replaces old tool results in the prompt with
|
|
1922
1981
|
# "[Old tool result content cleared]" so a long session stops re-sending
|
|
1923
1982
|
# every output on every step. setdefault keeps a user's explicit choice.
|
|
1924
|
-
|
|
1983
|
+
if not v2: # opencode 2 omits it as an unsupported legacy setting
|
|
1984
|
+
cfg.setdefault("compaction", {}).setdefault("prune", True)
|
|
1925
1985
|
wat = cfg.setdefault("watcher", {})
|
|
1926
1986
|
ign = wat.setdefault("ignore", [])
|
|
1927
1987
|
for pat in OPENCODE_IGNORE:
|
|
@@ -1929,7 +1989,8 @@ def install_opencode():
|
|
|
1929
1989
|
ign.append(pat)
|
|
1930
1990
|
changed = write_json(os.path.join(OPENCODE, "opencode.json"), cfg)
|
|
1931
1991
|
print("%s opencode.json (instructions + skill router + mcp + skill deny)" % OK)
|
|
1932
|
-
print("%s opencode.json (
|
|
1992
|
+
print("%s opencode.json (%swatcher.ignore)"
|
|
1993
|
+
% (OK, "" if v2 else "compaction.prune + "))
|
|
1933
1994
|
if changed or dropped:
|
|
1934
1995
|
restart_hint("opencode", os.path.join(OPENCODE, "opencode.json"))
|
|
1935
1996
|
|
|
@@ -2945,6 +3006,20 @@ def _run_bounded(argv, timeout):
|
|
|
2945
3006
|
except OSError:
|
|
2946
3007
|
pass
|
|
2947
3008
|
proc.wait()
|
|
3009
|
+
# a member mid-fork as the kill swept the group can come out of the
|
|
3010
|
+
# fork unsignalled (macOS under load: the orphan held the caller's
|
|
3011
|
+
# pipes, plan 115), so signal the group again until it is empty. Each
|
|
3012
|
+
# round catches what forked since the last and a healthy group is gone
|
|
3013
|
+
# within a few; the 2 s cap only bounds one that will not die (a member
|
|
3014
|
+
# stuck in uninterruptible I/O, a zombie nobody reaps) so the Ctrl-C
|
|
3015
|
+
# still returns.
|
|
3016
|
+
deadline = time.monotonic() + 2
|
|
3017
|
+
while time.monotonic() < deadline:
|
|
3018
|
+
try:
|
|
3019
|
+
os.killpg(proc.pid, signal.SIGKILL)
|
|
3020
|
+
except OSError: # ESRCH: nothing left in the group
|
|
3021
|
+
break
|
|
3022
|
+
time.sleep(0.01)
|
|
2948
3023
|
raise
|
|
2949
3024
|
|
|
2950
3025
|
|
|
@@ -3363,9 +3438,12 @@ def verify_uninstall(hosts, full):
|
|
|
3363
3438
|
if "opencode" in hosts:
|
|
3364
3439
|
claim("opencode plugin unlinked",
|
|
3365
3440
|
[os.path.join(OPENCODE, d, "tezgah.js") for d in ("plugins", "plugin")]
|
|
3366
|
-
+ [os.path.join(OPENCODE, "tui-plugins",
|
|
3441
|
+
+ [os.path.join(OPENCODE, "tui-plugins", n)
|
|
3442
|
+
for n in ("tezgah-tui.tsx", "tezgah-cli")])
|
|
3367
3443
|
clean("opencode opencode.json unwired",
|
|
3368
3444
|
[os.path.join(OPENCODE, "opencode.json")])
|
|
3445
|
+
clean("opencode cli.json unwired", [os.path.join(OPENCODE, "cli.json")],
|
|
3446
|
+
needle=OPENCODE_CLI_PLUGIN)
|
|
3369
3447
|
claim("opencode generated routers gone", [SKILL_ROUTER, SKILL_ROUTER_FULL])
|
|
3370
3448
|
if "cursor" in hosts:
|
|
3371
3449
|
clean("cursor hooks.json unwired", [os.path.join(CURSOR, "hooks.json")])
|
|
@@ -3499,6 +3577,14 @@ def unwire_opencode_config():
|
|
|
3499
3577
|
tj.pop("plugin", None)
|
|
3500
3578
|
write_json(t, tj)
|
|
3501
3579
|
print("%s removed tezgah TUI plugin from %s" % (OK, t))
|
|
3580
|
+
cp = os.path.join(OPENCODE, "cli.json")
|
|
3581
|
+
cj = read_json(cp, None)
|
|
3582
|
+
if cj and isinstance(cj.get("plugins"), list):
|
|
3583
|
+
kept = [x for x in cj["plugins"] if x != "file://" + OPENCODE_CLI_PLUGIN]
|
|
3584
|
+
if kept != cj["plugins"]:
|
|
3585
|
+
cj["plugins"] = kept
|
|
3586
|
+
write_json(cp, cj)
|
|
3587
|
+
print("%s removed tezgah CLI plugin from %s" % (OK, cp))
|
|
3502
3588
|
|
|
3503
3589
|
|
|
3504
3590
|
def uninstall_claude():
|
|
@@ -3560,7 +3646,8 @@ def uninstall_opencode():
|
|
|
3560
3646
|
unlink_tezgah(os.path.join(OPENCODE, "skills", s))
|
|
3561
3647
|
for d in ("plugins", "plugin"):
|
|
3562
3648
|
unlink_tezgah(os.path.join(OPENCODE, d, "tezgah.js"))
|
|
3563
|
-
|
|
3649
|
+
for name in ("tezgah-tui.tsx", "tezgah-cli"):
|
|
3650
|
+
unlink_tezgah(os.path.join(OPENCODE, "tui-plugins", name))
|
|
3564
3651
|
unwire_opencode_config()
|
|
3565
3652
|
for path in (SKILL_ROUTER, SKILL_ROUTER_FULL):
|
|
3566
3653
|
try:
|
|
@@ -3714,6 +3801,13 @@ def uninstall(hosts, dry_run=False):
|
|
|
3714
3801
|
remove_install_tree()
|
|
3715
3802
|
elif armed:
|
|
3716
3803
|
rest = sorted(set(armed) - set(hosts))
|
|
3804
|
+
# install_common only ever merges into the record, so this is the one
|
|
3805
|
+
# place a host leaves it; kept, it made every later uninstall partial
|
|
3806
|
+
# and `tezgah update` re-armed it from the record
|
|
3807
|
+
cfg = read_config(tp.CONFIG, {})
|
|
3808
|
+
if cfg is not None:
|
|
3809
|
+
cfg["hosts"] = [h for h in armed if h in rest]
|
|
3810
|
+
write_json(tp.CONFIG, cfg)
|
|
3717
3811
|
print("\n%s still armed: %s keeps its config and the install tree"
|
|
3718
3812
|
% (NO, ", ".join(rest)))
|
|
3719
3813
|
remaining = verify_uninstall(hosts, full)
|
|
@@ -4376,6 +4470,8 @@ def report(hosts):
|
|
|
4376
4470
|
("codegen provider key (OpenRouter, DeepSeek or Inception)",
|
|
4377
4471
|
tp.have_provider_key()),
|
|
4378
4472
|
("orx on PATH (OpenResearch research routing)", bool(tp.orx_bin())),
|
|
4473
|
+
("ocr on PATH (open-code-review spec for the reviewer, opt-in)",
|
|
4474
|
+
bool(tp.ocr_bin())),
|
|
4379
4475
|
("npx on PATH (app-analysis MCP servers)", bool(shutil.which("npx"))),
|
|
4380
4476
|
("app artifacts dir %s" % tezgah_apps.ARTIFACTS,
|
|
4381
4477
|
os.path.isdir(tezgah_apps.ARTIFACTS)),
|
|
@@ -4694,6 +4790,7 @@ def host_checks_codex():
|
|
|
4694
4790
|
def host_checks_opencode():
|
|
4695
4791
|
cfg = read_json(os.path.join(OPENCODE, "opencode.json"), {})
|
|
4696
4792
|
tui = read_json(os.path.join(OPENCODE, "tui.json"), {})
|
|
4793
|
+
cli = read_json(os.path.join(OPENCODE, "cli.json"), {})
|
|
4697
4794
|
instr = cfg.get("instructions") or []
|
|
4698
4795
|
specs = [p if isinstance(p, str) else p[0] for p in (tui.get("plugin") or [])]
|
|
4699
4796
|
return [
|
|
@@ -4711,14 +4808,20 @@ def host_checks_opencode():
|
|
|
4711
4808
|
] + mcp_rows(set(cfg.get("mcp") or {}), "opencode.json") + [
|
|
4712
4809
|
mcp_row(TEZGAH_MCP_NAME, (cfg.get("mcp") or {}).get(TEZGAH_MCP_NAME),
|
|
4713
4810
|
"opencode.json", tezgah_mcp_command()),
|
|
4811
|
+
] + ([
|
|
4812
|
+
("status line plugin in cli.json + linked",
|
|
4813
|
+
"file://" + OPENCODE_CLI_PLUGIN in (cli.get("plugins") or [])
|
|
4814
|
+
and os.path.exists(OPENCODE_CLI_PLUGIN)),
|
|
4815
|
+
] if opencode_v2() else [
|
|
4714
4816
|
("context pruning armed (compaction.prune)",
|
|
4715
4817
|
(cfg.get("compaction") or {}).get("prune") is True),
|
|
4716
|
-
("watcher ignores noisy trees",
|
|
4717
|
-
bool(set(OPENCODE_IGNORE)
|
|
4718
|
-
& set(((cfg.get("watcher") or {}).get("ignore") or [])))),
|
|
4719
4818
|
("status line plugin in tui.json + linked",
|
|
4720
4819
|
any("tezgah-tui" in s for s in specs)
|
|
4721
4820
|
and os.path.exists(os.path.join(OPENCODE, "tui-plugins", "tezgah-tui.tsx"))),
|
|
4821
|
+
]) + [
|
|
4822
|
+
("watcher ignores noisy trees",
|
|
4823
|
+
bool(set(OPENCODE_IGNORE)
|
|
4824
|
+
& set(((cfg.get("watcher") or {}).get("ignore") or [])))),
|
|
4722
4825
|
# opencode's own registry declares INCEPTION_API_KEY for the inception
|
|
4723
4826
|
# provider, so nothing needs adding to opencode.json - but the route is
|
|
4724
4827
|
# only usable once a key resolves, and that is what this reports.
|
|
@@ -5923,7 +6026,7 @@ def hosts_row():
|
|
|
5923
6026
|
host's first HOST_CHECKS row), as one report row. Reported, never changed:
|
|
5924
6027
|
`--upgrade`, `--enable`/`--disable` and a full uninstall act on the recorded
|
|
5925
6028
|
list, so a host wired but not recorded is one they skip, and which list is
|
|
5926
|
-
right is the user's call (`--install --hosts ...`
|
|
6029
|
+
right is the user's call (`--install --hosts ...` adds to it)."""
|
|
5927
6030
|
recorded = sorted(tp.config().get("hosts") or [])
|
|
5928
6031
|
wired = sorted(h for h in ALL_HOSTS if HOST_CHECKS[h]()[0][1])
|
|
5929
6032
|
return ("config.json hosts (%s) match the hosts wired (%s)"
|
package/bin/tezgah-skill
CHANGED
|
@@ -25,7 +25,7 @@ import json
|
|
|
25
25
|
import os
|
|
26
26
|
import sys
|
|
27
27
|
|
|
28
|
-
HERE = os.path.dirname(os.path.dirname(os.path.
|
|
28
|
+
HERE = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
|
|
29
29
|
sys.path.insert(0, os.path.join(HERE, "hooks"))
|
|
30
30
|
import tezgah_skill_pick as sp # noqa: E402
|
|
31
31
|
|
package/bin/tezgah-status
CHANGED
|
@@ -29,6 +29,22 @@ their status line; this CLI is how every host (and a human) gets it:
|
|
|
29
29
|
The MCP half of a retirement decision is manual:
|
|
30
30
|
`tezgah-setup --mcp-schemas` measures what a server
|
|
31
31
|
costs, this counts what it fires.
|
|
32
|
+
tezgah-status --rates --since DATE --until DATE [--json]
|
|
33
|
+
every real ledger's rows in [since, until), folded per
|
|
34
|
+
window and per calendar day: turns, `claim` rows and
|
|
35
|
+
the Stop classes that blocked them, the shape flags
|
|
36
|
+
every judged reply carried, denies by rule, and the
|
|
37
|
+
rates (blocks per 100 turns, denies per 100 sessions,
|
|
38
|
+
the claim block and Stop shape shares, blocked claims
|
|
39
|
+
per 100 sessions by class). A repeated `--since`/
|
|
40
|
+
`--until` pair prints one block each and the pp delta
|
|
41
|
+
between adjacent windows - the unit plan 066's 056 row
|
|
42
|
+
states its bar in. A window that read more than one
|
|
43
|
+
row contract prints the split, and a delta across two
|
|
44
|
+
contracts says so (plan 135). `--json` prints
|
|
45
|
+
`{"windows": [...]}`.
|
|
46
|
+
`--until` is exclusive, so adjacent windows partition
|
|
47
|
+
their span.
|
|
32
48
|
tezgah-status --skill-fitness
|
|
33
49
|
per shipped skill, over the recorded sessions: how
|
|
34
50
|
many opened it and which were never opened. A
|
|
@@ -78,6 +94,16 @@ their status line; this CLI is how every host (and a human) gets it:
|
|
|
78
94
|
the set renders as dim "no state" instead of claiming
|
|
79
95
|
"armed, not used yet". A host that cannot see a skill
|
|
80
96
|
read (dsh) passes the tool-use four.
|
|
97
|
+
tezgah-status --manifest=FILE
|
|
98
|
+
read the repository extension from FILE instead of
|
|
99
|
+
the `.tezgah/extension.json` discovered from PATH (a
|
|
100
|
+
manifest outside the tree, e.g. an engagement's).
|
|
101
|
+
With `statusline.override: true` in the manifest the
|
|
102
|
+
project owns its line and points its own statusLine
|
|
103
|
+
here: the host's status-line payload on stdin (its
|
|
104
|
+
`cwd`/`workspace.current_dir` and `session_id`) is
|
|
105
|
+
read when no PATH is given, so this is the only line
|
|
106
|
+
and it keeps the built-in marks and the chips.
|
|
81
107
|
|
|
82
108
|
The session id may be passed as the second argument or via TEZGAH_SESSION;
|
|
83
109
|
without it the "used" marks cannot light up, so a host that knows the id should
|
|
@@ -97,6 +123,26 @@ from tezgah_context import ( # noqa: E402
|
|
|
97
123
|
# the line and `--json` carries every row, so a reader can always see what was
|
|
98
124
|
# cut.
|
|
99
125
|
TOP = 15
|
|
126
|
+
# The host payload an override reads on stdin: a status-line host writes one
|
|
127
|
+
# small JSON object and closes the pipe, so the read is bounded in bytes and in
|
|
128
|
+
# how long an empty pipe is waited for - a caller that never writes costs this
|
|
129
|
+
# long, never a hang.
|
|
130
|
+
PAYLOAD_MAX = 65536
|
|
131
|
+
PAYLOAD_WAIT = 0.2
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def host_payload():
|
|
135
|
+
"""The status-line host's JSON payload on stdin, or {} - a terminal, an
|
|
136
|
+
empty or silent pipe, malformed JSON or no stdin at all."""
|
|
137
|
+
import select
|
|
138
|
+
try:
|
|
139
|
+
if sys.stdin.isatty() or not select.select([sys.stdin], [], [],
|
|
140
|
+
PAYLOAD_WAIT)[0]:
|
|
141
|
+
return {}
|
|
142
|
+
payload = json.loads(sys.stdin.read(PAYLOAD_MAX) or "{}")
|
|
143
|
+
except (OSError, ValueError, AttributeError):
|
|
144
|
+
return {}
|
|
145
|
+
return payload if isinstance(payload, dict) else {}
|
|
100
146
|
|
|
101
147
|
|
|
102
148
|
def weeks_arg(args):
|
|
@@ -241,6 +287,115 @@ def print_orca(cwd, as_json):
|
|
|
241
287
|
return 0
|
|
242
288
|
|
|
243
289
|
|
|
290
|
+
def window_pairs(args):
|
|
291
|
+
"""`args` with the `--since`/`--until` pairs folded out, and the pairs in the
|
|
292
|
+
order written. Each `--until` closes the `--since` before it, and a flag
|
|
293
|
+
without its partner is ValueError: half a window is a question the reader
|
|
294
|
+
did not finish asking.
|
|
295
|
+
|
|
296
|
+
The spaced form is read here for the reason `--weeks`' is: the split in
|
|
297
|
+
`main` sends every non-`--` argument to `pos`, where a date would be read as
|
|
298
|
+
a session id."""
|
|
299
|
+
out, pairs, since, i = [], [], None, 0
|
|
300
|
+
while i < len(args):
|
|
301
|
+
a = args[i]
|
|
302
|
+
name = a.split("=", 1)[0]
|
|
303
|
+
if name not in ("--since", "--until"):
|
|
304
|
+
out.append(a)
|
|
305
|
+
i += 1
|
|
306
|
+
continue
|
|
307
|
+
if "=" in a:
|
|
308
|
+
value, i = a.split("=", 1)[1], i + 1
|
|
309
|
+
else:
|
|
310
|
+
value = args[i + 1] if i + 1 < len(args) else ""
|
|
311
|
+
i += 2 if i + 1 < len(args) else 1
|
|
312
|
+
if name == "--since":
|
|
313
|
+
if since is not None:
|
|
314
|
+
raise ValueError("--since %s has no --until" % since)
|
|
315
|
+
since = value
|
|
316
|
+
else:
|
|
317
|
+
if since is None:
|
|
318
|
+
raise ValueError("--until %s has no --since" % value)
|
|
319
|
+
pairs.append((since, value))
|
|
320
|
+
since = None
|
|
321
|
+
if since is not None:
|
|
322
|
+
raise ValueError("--since %s has no --until" % since)
|
|
323
|
+
return out, pairs
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
def share(value, numerator, denominator):
|
|
327
|
+
"""A share in the unit 056's `+2 pp` bar reads, or `n/a` with no
|
|
328
|
+
denominator - a window that decided nothing has no rate."""
|
|
329
|
+
return ("n/a" if value is None
|
|
330
|
+
else "%.2f%% (%d/%d)" % (100 * value, numerator, denominator))
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
def dominant_contract(window):
|
|
334
|
+
"""The row contract that wrote most of a window's rows, or `-` for a window
|
|
335
|
+
that read none. `claims` is one quantity under a contract and another across
|
|
336
|
+
a change to it (plan 135), so the delta line names both sides' contract."""
|
|
337
|
+
counts = window.get("row_versions") or {}
|
|
338
|
+
if not counts:
|
|
339
|
+
return "-"
|
|
340
|
+
return max(sorted(counts), key=lambda name: counts[name])
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
def print_rates(found):
|
|
344
|
+
"""The windowed rates, for `--rates`: one block per window, then the pp delta
|
|
345
|
+
between each adjacent pair - the unit plan 066's rows state their bars in."""
|
|
346
|
+
for w in found:
|
|
347
|
+
rates = w["rates"]
|
|
348
|
+
print("window %s..%s: %d days, %d sessions, %d turns, %d claims, %d "
|
|
349
|
+
"replies" % (w["since"], w["until"], w["days"], w["sessions"],
|
|
350
|
+
w["turns"], w["claims"], w["replies"]))
|
|
351
|
+
for key, label in (("blocked_claims", "blocked_claims"),
|
|
352
|
+
("shapes", "stop shapes"), ("denies", "denies")):
|
|
353
|
+
print(" %-15s %s" % (label, ", ".join(
|
|
354
|
+
"%s=%d" % kv for kv in sorted(w[key].items())) or "none"))
|
|
355
|
+
print(" %-15s %d" % ("shape_blocked", w["shape_blocked"]))
|
|
356
|
+
print(" %-15s blocks/100 turns %s, denies/100 sessions %s" % (
|
|
357
|
+
"rates", "n/a" if rates["blocks_per_100_turns"] is None
|
|
358
|
+
else "%.4f" % rates["blocks_per_100_turns"],
|
|
359
|
+
"n/a" if rates["denies_per_100_sessions"] is None
|
|
360
|
+
else "%.4f" % rates["denies_per_100_sessions"]))
|
|
361
|
+
print(" %-15s claim block %s, stop shape %s" % (
|
|
362
|
+
"shares", share(rates["claim_block_rate"],
|
|
363
|
+
sum(w["blocked_claims"].values()), w["claims"]),
|
|
364
|
+
share(rates["stop_shape_rate"], w["shape_flagged"], w["replies"])))
|
|
365
|
+
print(" %-15s %s" % ("blocked/100 sess", ", ".join(
|
|
366
|
+
"%s=%.4f" % kv for kv in
|
|
367
|
+
sorted(rates["blocked_claims_per_100_sessions"].items()))
|
|
368
|
+
or "none"))
|
|
369
|
+
# Which row contract wrote the rows, printed only when a window mixes
|
|
370
|
+
# two: `claims` means "every judged reply" before ROW_VERSION 3 and "a
|
|
371
|
+
# reply that claimed" after it, so a share read off a mixed or shifted
|
|
372
|
+
# window is not the same quantity as its neighbour's (plan 135).
|
|
373
|
+
if len(w["row_versions"]) > 1:
|
|
374
|
+
print(" %-15s %s" % ("contracts", ", ".join(
|
|
375
|
+
"%s=%d" % kv for kv in sorted(w["row_versions"].items()))))
|
|
376
|
+
for before, after in zip(found, found[1:]):
|
|
377
|
+
parts, unknown, over = [], False, False
|
|
378
|
+
for key, label in (("claim_block_rate", "claim block"),
|
|
379
|
+
("stop_shape_rate", "stop shape")):
|
|
380
|
+
a, b = before["rates"][key], after["rates"][key]
|
|
381
|
+
if a is None or b is None:
|
|
382
|
+
unknown = True
|
|
383
|
+
parts.append("%s n/a" % label)
|
|
384
|
+
continue
|
|
385
|
+
parts.append("%s %+.2f pp" % (label, 100 * (b - a)))
|
|
386
|
+
over = over or round(b - a, 4) > 0.02
|
|
387
|
+
shift = dominant_contract(before) != dominant_contract(after)
|
|
388
|
+
print("delta %s..%s -> %s..%s: %s; 056 bar (+2 pp): %s%s" % (
|
|
389
|
+
before["since"], before["until"], after["since"], after["until"],
|
|
390
|
+
", ".join(parts),
|
|
391
|
+
"unreadable (no denominator in a window)" if unknown
|
|
392
|
+
else "FAILS" if over else "holds",
|
|
393
|
+
"; the two windows' rows come from different contracts (%s vs %s), "
|
|
394
|
+
"so the shares are not one quantity" % (
|
|
395
|
+
dominant_contract(before), dominant_contract(after))
|
|
396
|
+
if shift else ""))
|
|
397
|
+
|
|
398
|
+
|
|
244
399
|
def main():
|
|
245
400
|
# `--` ends the options: what follows is PATH and SESSION_ID even when it
|
|
246
401
|
# starts with a dash. The dsh route and the MCP tool hand caller-chosen
|
|
@@ -250,6 +405,11 @@ def main():
|
|
|
250
405
|
rest = argv[argv.index("--") + 1:] if "--" in argv else []
|
|
251
406
|
argv = argv[:argv.index("--")] if "--" in argv else argv
|
|
252
407
|
args, weeks = weeks_arg(argv)
|
|
408
|
+
try:
|
|
409
|
+
args, windows = window_pairs(args)
|
|
410
|
+
except ValueError as err:
|
|
411
|
+
sys.stderr.write("tezgah-status: %s\n" % err)
|
|
412
|
+
return 2
|
|
253
413
|
# A sanity bound, not a policy: ten years of weeks is longer than any ledger
|
|
254
414
|
# this machine holds, and a number the reader mistyped should say so rather
|
|
255
415
|
# than print a thousand rows of nothing.
|
|
@@ -260,9 +420,11 @@ def main():
|
|
|
260
420
|
pos = [a for a in args if not a.startswith("--")] + rest
|
|
261
421
|
known = {"--legend", "--json", "--color", "--no-color", "--counters",
|
|
262
422
|
"--all", "--trend", "--skill-fitness", "--failure-shapes",
|
|
263
|
-
"--rule-yield", "--enforcers", "--orca", "--judge", "--
|
|
423
|
+
"--rule-yield", "--enforcers", "--orca", "--judge", "--rates",
|
|
424
|
+
"--help"}
|
|
264
425
|
unknown = sorted(f for f in flags
|
|
265
|
-
if f not in known
|
|
426
|
+
if f not in known
|
|
427
|
+
and not f.startswith(("--observable=", "--manifest=")))
|
|
266
428
|
if unknown:
|
|
267
429
|
sys.stderr.write("tezgah-status: unknown option(s): %s (try --help)\n"
|
|
268
430
|
% ", ".join(unknown))
|
|
@@ -293,6 +455,26 @@ def main():
|
|
|
293
455
|
sys.stderr.write("tezgah-status: %s only means something with "
|
|
294
456
|
"--counters\n" % modifier)
|
|
295
457
|
return 2
|
|
458
|
+
if windows and "--rates" not in flags:
|
|
459
|
+
sys.stderr.write("tezgah-status: --since/--until only mean something "
|
|
460
|
+
"with --rates\n")
|
|
461
|
+
return 2
|
|
462
|
+
if "--rates" in flags and not windows:
|
|
463
|
+
sys.stderr.write("tezgah-status: --rates wants --since and --until\n")
|
|
464
|
+
return 2
|
|
465
|
+
if "--rates" in flags:
|
|
466
|
+
import tezgah_integrity as ti
|
|
467
|
+
try:
|
|
468
|
+
found = [ti.rates(since, until) for since, until in windows]
|
|
469
|
+
except ValueError as err:
|
|
470
|
+
sys.stderr.write("tezgah-status: %s\n" % err)
|
|
471
|
+
return 2
|
|
472
|
+
if "--json" in flags:
|
|
473
|
+
# one shape for one window and for many: a consumer never branches
|
|
474
|
+
print(json.dumps({"windows": found}, sort_keys=True))
|
|
475
|
+
return 0
|
|
476
|
+
print_rates(found)
|
|
477
|
+
return 0
|
|
296
478
|
if "--judge" in flags:
|
|
297
479
|
import tezgah_judge as tj
|
|
298
480
|
last = tj.last_use()
|
|
@@ -430,7 +612,23 @@ def main():
|
|
|
430
612
|
spec = next((f.split("=", 1)[1] for f in flags
|
|
431
613
|
if f.startswith("--observable=")), None)
|
|
432
614
|
observable = set(spec.split(",")) if spec else None
|
|
433
|
-
|
|
615
|
+
manifest = next((f.split("=", 1)[1] for f in flags
|
|
616
|
+
if f.startswith("--manifest=")), None) or None
|
|
617
|
+
if not pos:
|
|
618
|
+
import tezgah_extension
|
|
619
|
+
if tezgah_extension.override(cwd, manifest):
|
|
620
|
+
# the project's own statusLine runs this renderer: the host says
|
|
621
|
+
# which directory and session the line is for
|
|
622
|
+
payload = host_payload()
|
|
623
|
+
workspace = payload.get("workspace")
|
|
624
|
+
where = ((workspace.get("current_dir")
|
|
625
|
+
if isinstance(workspace, dict) else None)
|
|
626
|
+
or payload.get("cwd"))
|
|
627
|
+
if isinstance(where, str) and where:
|
|
628
|
+
cwd = os.path.realpath(where)
|
|
629
|
+
if isinstance(payload.get("session_id"), str) and payload["session_id"]:
|
|
630
|
+
session = payload["session_id"]
|
|
631
|
+
segs = health_segments(cwd, session, observable=observable, manifest=manifest)
|
|
434
632
|
if "--json" in flags:
|
|
435
633
|
print(json.dumps(segs))
|
|
436
634
|
return 0
|