@r1z4x/tezgah 1.9.2 → 1.13.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 +415 -1
- package/MANIFEST +404 -144
- package/README.de.md +1 -1
- package/README.es.md +1 -1
- package/README.fr.md +1 -1
- package/README.md +5 -4
- 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 +255 -44
- package/bin/tezgah-review-quote +185 -0
- package/bin/tezgah-setup +1365 -55
- package/bin/tezgah-skill +1 -1
- package/bin/tezgah-status +201 -3
- package/bin/tezgah-task +258 -20
- package/commands/adhd.md +2 -2
- package/commands/ponytail.md +4 -4
- package/docs/architecture.md +2 -2
- package/docs/citations-baseline.json +3 -3
- package/docs/clarity-baseline.json +11 -5
- package/docs/contract.md +91 -43
- package/docs/environment.md +5 -2
- package/docs/evidence.md +109 -17
- package/docs/feature-audit.md +2 -2
- package/docs/gate.md +60 -33
- package/docs/glossary.md +6 -3
- package/docs/hosts.md +313 -17
- package/docs/index.json +34 -8
- package/docs/judge.md +4 -2
- package/docs/layers.md +4 -4
- package/docs/models.md +37 -9
- package/docs/operations.md +141 -5
- package/docs/research.md +815 -8
- package/docs/skills.md +137 -13
- package/docs/status-line.md +121 -1
- package/docs/testing.md +3 -1
- package/hooks/hooks.json +2 -2
- package/hooks/lang/en.json +21 -0
- package/hooks/lang/tr.json +22 -1
- package/hooks/projects-stop.py +2 -1
- package/hooks/tezgah_agents.py +65 -25
- package/hooks/tezgah_apps.py +18 -0
- package/hooks/tezgah_attest.py +79 -10
- package/hooks/tezgah_components.py +4 -0
- package/hooks/tezgah_context.py +207 -55
- package/hooks/tezgah_extension.py +337 -0
- package/hooks/tezgah_gate.py +267 -79
- package/hooks/tezgah_integrity.py +864 -143
- 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 +145 -8
- package/hooks/tezgah_policy.py +128 -57
- package/hooks/tezgah_rank.py +9 -6
- package/hooks/tezgah_replay.py +12 -6
- package/hooks/tezgah_research.py +1414 -76
- 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_stack.py +236 -1
- package/hooks/tezgah_stopspec.py +8 -1
- package/hooks/tezgah_task.py +14 -5
- package/hooks/tezgah_taste_ledger.py +1 -1
- package/hosts/amp/hook.py +217 -0
- package/hosts/amp/tezgah-plugin.ts.in +386 -0
- package/hosts/antigravity/hook.py +255 -0
- package/hosts/codex/hook.py +2 -1
- package/hosts/commandcode/hook.py +239 -0
- package/hosts/copilot/hook.py +284 -0
- package/hosts/cursor/hook.py +31 -3
- package/hosts/droid/hook.py +259 -0
- package/hosts/dsh/hooks.json +1 -1
- package/hosts/gemini/hook.py +213 -0
- package/hosts/goose/hook.py +145 -0
- package/hosts/omp/hook.py +4 -1
- package/hosts/omp/tezgah-hook.ts.in +30 -7
- package/hosts/opencode/plugins/tezgah.js +309 -48
- package/hosts/opencode/tui/cli/tui.tsx +100 -0
- package/hosts/opencode/tui/tezgah-tui.tsx +2 -1
- package/hosts/qwen/hook.py +206 -0
- package/output-styles/tezgah.md +20 -15
- 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 +17 -8
- package/skills/i-have-adhd/SKILL.md +32 -12
- package/skills/no-ai-slop/SKILL.md +15 -1
- package/skills/plan-add/SKILL.md +38 -27
- 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 +97 -48
- package/skills/rl-env/SKILL.md +25 -13
- package/skills/rl-env/SOURCE +8 -6
- package/skills/tezgah-contract/SKILL.md +65 -47
- package/statusline.py +20 -9
- package/workflows/graph-review.js +14 -2
- 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/README.de.md
CHANGED
|
@@ -49,7 +49,7 @@ auf dieselbe Weise.
|
|
|
49
49
|
- **Forschung kommt mit eigener Bibliothek.** Forschungsaufgaben laufen über
|
|
50
50
|
OpenResearch, mit einer integrierten Bibliothek aus 98 Upstream-Skills, die
|
|
51
51
|
Eintrag für Eintrag geladen wird, damit der Kontext klein bleibt.
|
|
52
|
-
- **Jede Regel hat einen Ausschalter.**
|
|
52
|
+
- **Jede Regel hat einen Ausschalter.** Siebzehn Kill-Switches — dazu
|
|
53
53
|
Repo-Markierungen — entfernen den Regeltext aus der Sitzung; die Regel
|
|
54
54
|
stoppt damit wirklich, statt nur als aus zu erscheinen.
|
|
55
55
|
- **Eine feste Antwortform.** Antworten sind türkisch, sofern Sie keine andere Sprache wählen, und
|
package/README.es.md
CHANGED
|
@@ -49,7 +49,7 @@ en un lugar llega a todos los hosts de la misma manera.
|
|
|
49
49
|
dirigen a través de OpenResearch con una biblioteca incorporada de 98
|
|
50
50
|
habilidades upstream, cargada de una en una para que el contexto siga
|
|
51
51
|
siendo pequeño.
|
|
52
|
-
- **Cada regla tiene un interruptor de apagado.**
|
|
52
|
+
- **Cada regla tiene un interruptor de apagado.** Diecisiete interruptores — más
|
|
53
53
|
las marcas por repositorio — eliminan el texto de la regla de la sesión, de
|
|
54
54
|
modo que la regla realmente se detiene en lugar de limitarse a figurar como
|
|
55
55
|
desactivada.
|
package/README.fr.md
CHANGED
|
@@ -48,7 +48,7 @@ modifiée à un endroit atteint chaque hôte de la même façon.
|
|
|
48
48
|
- **La recherche arrive avec sa bibliothèque.** Les tâches de recherche
|
|
49
49
|
passent par OpenResearch avec une bibliothèque intégrée de 98 compétences
|
|
50
50
|
upstream, chargée une entrée à la fois pour que le contexte reste petit.
|
|
51
|
-
- **Chaque règle a un interrupteur.**
|
|
51
|
+
- **Chaque règle a un interrupteur.** Dix-sept interrupteurs — plus des
|
|
52
52
|
marques par dépôt — retirent le texte de la règle de la session ; la règle
|
|
53
53
|
s'arrête vraiment au lieu de simplement figurer comme désactivée.
|
|
54
54
|
- **Une forme de réponse fixe.** Les réponses sont en turc, sauf si vous choisissez une autre langue, et
|
package/README.md
CHANGED
|
@@ -35,8 +35,9 @@ reaches every host the same way.
|
|
|
35
35
|
|
|
36
36
|
## What tezgah enforces and records
|
|
37
37
|
|
|
38
|
-
- **One contract,
|
|
39
|
-
dsh
|
|
38
|
+
- **One contract, fourteen hosts.** omp, Claude Code, Codex, Cursor, opencode,
|
|
39
|
+
dsh, Qwen Code, Factory Droid, Command Code, GitHub Copilot CLI, Gemini CLI,
|
|
40
|
+
Antigravity CLI, Goose and Amp see the same rules, because every host is a thin adapter over one shared
|
|
40
41
|
core — change a rule once and all of them pick it up.
|
|
41
42
|
- **A done claim needs a passing check on record.** A gate of 15 refusals stops
|
|
42
43
|
the neutered check — `--no-verify`, `|| true`, a test piped into `tail`, a
|
|
@@ -46,7 +47,7 @@ reaches every host the same way.
|
|
|
46
47
|
- **Research ships with its library.** Research tasks route through
|
|
47
48
|
OpenResearch with a vendored library of 98 upstream skills, loaded one entry
|
|
48
49
|
at a time so the context stays small.
|
|
49
|
-
- **Every rule has an off switch.**
|
|
50
|
+
- **Every rule has an off switch.** Seventeen kill switches — plus per-repo
|
|
50
51
|
marks — remove a rule's text from the session, so the rule actually stops
|
|
51
52
|
rather than merely showing as off.
|
|
52
53
|
- **A fixed reply shape.** Replies lead with the outcome, in Turkish unless
|
|
@@ -154,7 +155,7 @@ and the optional integrations are in the [docs](docs/README.md).
|
|
|
154
155
|
|
|
155
156
|
## Supported hosts
|
|
156
157
|
|
|
157
|
-
**omp** (the primary host, developed and verified against), **Claude Code**, **Codex**, **Cursor**, **opencode**, **dsh** — thin adapters over one shared core.
|
|
158
|
+
**omp** (the primary host, developed and verified against), **Claude Code**, **Codex**, **Cursor**, **opencode**, **dsh**, **Qwen Code**, **Factory Droid**, **Command Code**, **GitHub Copilot CLI**, **Gemini CLI**, **Antigravity CLI**, **Goose**, **Amp** — thin adapters over one shared core. The last six are wired from their vendors' docs alone: no run of their binaries has shown them obeying a deny yet ([hosts](docs/hosts.md)).
|
|
158
159
|
|
|
159
160
|
## Where the depth lives
|
|
160
161
|
|
package/README.tr.md
CHANGED
|
@@ -48,7 +48,7 @@ değiştirdiğinizde her barındırıcıya aynı şekilde ulaşır.
|
|
|
48
48
|
- **Araştırma kütüphanesiyle birlikte gelir.** Araştırma görevleri,
|
|
49
49
|
bağlamın küçük kalması için tek tek yüklenen 98 becerilik gömülü
|
|
50
50
|
bir kütüphaneyle OpenResearch üzerinden yürütülür.
|
|
51
|
-
- **Her kuralın bir kapatma anahtarı vardır.** On
|
|
51
|
+
- **Her kuralın bir kapatma anahtarı vardır.** On yedi kapatma anahtarı — ve
|
|
52
52
|
depo başına işaretler — kuralın metnini oturumdan kaldırır; böylece kural
|
|
53
53
|
yalnızca kapalı görünmez, gerçekten durur.
|
|
54
54
|
- **Sabit bir yanıt biçimi.** Yanıtlar, başka bir dil seçmediyseniz Türkçedir ve sonuçla
|
package/bin/codegen
CHANGED
|
@@ -49,7 +49,7 @@ import urllib.request
|
|
|
49
49
|
import json
|
|
50
50
|
|
|
51
51
|
HOOKS = os.path.join(
|
|
52
|
-
os.path.dirname(os.path.dirname(os.path.
|
|
52
|
+
os.path.dirname(os.path.dirname(os.path.realpath(__file__))), "hooks")
|
|
53
53
|
sys.path.insert(0, HOOKS)
|
|
54
54
|
import tezgah_integrity as ti # noqa: E402
|
|
55
55
|
import tezgah_paths as tp # noqa: E402
|
|
@@ -220,7 +220,10 @@ def ask(task, files, model, provider, timeout, max_tokens):
|
|
|
220
220
|
|
|
221
221
|
def main():
|
|
222
222
|
args = sys.argv[1:]
|
|
223
|
-
if
|
|
223
|
+
if args and args[0] in ("-h", "--help"):
|
|
224
|
+
print(__doc__.strip())
|
|
225
|
+
return
|
|
226
|
+
if not args:
|
|
224
227
|
sys.exit(__doc__.strip())
|
|
225
228
|
task, files, model, provider, timeout, out_dir, max_tokens = \
|
|
226
229
|
args[0], [], None, "openrouter", 300, None, 0
|
package/bin/tezgah-design
CHANGED
|
@@ -4,12 +4,20 @@ can fail.
|
|
|
4
4
|
|
|
5
5
|
tezgah-design derive --repo DIR [--out FILE] [--json]
|
|
6
6
|
tezgah-design check --contract FILE --measured FILE|- [--json]
|
|
7
|
+
tezgah-design slop --repo DIR [--url URL] [--render] [--measured FILE]
|
|
8
|
+
[--out FILE] [--json]
|
|
7
9
|
|
|
8
10
|
The contract is the floor a UI turn is judged against: the colour roles, the
|
|
9
11
|
type scale, the spacing unit and the state set a repository already uses, plus
|
|
10
12
|
the component inventory it owns. `derive` writes a first `.tezgah/design-contract.md`
|
|
11
13
|
from the repository's own token source (CSS custom properties, a Tailwind config,
|
|
12
14
|
a tokens/theme JSON) and exits 2 rather than invent a palette it did not find.
|
|
15
|
+
`slop` runs Hallmark's own gate list (`skills/hallmark/scripts/sloplint.mjs`)
|
|
16
|
+
over the repository or a running URL, writes the verdict to
|
|
17
|
+
`.tezgah/design/slop.json` and exits 1 on any Floor FAIL. It is the Hallmark half
|
|
18
|
+
of the UI floor; `check` is ours, and a contract's `precedence` says which of the
|
|
19
|
+
two owns each key, so neither can quietly override the other. Exit 3 when Node or
|
|
20
|
+
the vendored skill is missing: that is a check that did not run, never a pass.
|
|
13
21
|
`check` compares a measurement - the per-component computed styles and observed
|
|
14
22
|
states the analyze-app loop produces - against that file, prints every violation
|
|
15
23
|
with its component and its rule, and exits non-zero when there is at least one.
|
|
@@ -26,8 +34,11 @@ repository in the artifact.
|
|
|
26
34
|
more violations; 2 usage, IO, a bad contract or nothing judged
|
|
27
35
|
"""
|
|
28
36
|
import json
|
|
37
|
+
import math
|
|
29
38
|
import os
|
|
30
39
|
import re
|
|
40
|
+
import shutil
|
|
41
|
+
import subprocess
|
|
31
42
|
import sys
|
|
32
43
|
|
|
33
44
|
HERE = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
|
|
@@ -51,6 +62,15 @@ KINDS = ("interactive", "data")
|
|
|
51
62
|
# The floors that are not this repository's to choose: WCAG 2.2 SC 2.5.8 (the
|
|
52
63
|
# 24x24 CSS px target size) and SC 1.4.3 (4.5:1, or 3:1 for large text, which is
|
|
53
64
|
# 24px and up, or 18.66px bold).
|
|
65
|
+
# The precedence table (plan 133). A key owned by two sources is refused by
|
|
66
|
+
# `check`, so the tie-break cannot drift silently; `verbatim` says how far the
|
|
67
|
+
# user's own words reach, and it stops at style.
|
|
68
|
+
PRECEDENCE = {
|
|
69
|
+
"ours": ["states", "components", "evidence", "facts"],
|
|
70
|
+
"theirs": ["material", "motion-character"],
|
|
71
|
+
"shared": ["contrast", "focus-visible", "reduced-motion", "tap-target"],
|
|
72
|
+
"verbatim": "style",
|
|
73
|
+
}
|
|
54
74
|
TAP_TARGET = 24
|
|
55
75
|
CONTRAST_NORMAL = 4.5
|
|
56
76
|
CONTRAST_LARGE = 3.0
|
|
@@ -506,9 +526,89 @@ def css_tokens(root, files):
|
|
|
506
526
|
return out, sources
|
|
507
527
|
|
|
508
528
|
|
|
529
|
+
DESIGN_MD = ("design.md", "DESIGN.md")
|
|
530
|
+
|
|
531
|
+
|
|
532
|
+
def _oklch_to_hex(value):
|
|
533
|
+
"""`oklch(L C H [/ A])` as `#rrggbb`, or None when it is not that shape.
|
|
534
|
+
|
|
535
|
+
Hallmark's locked system states its palette in OKLCH; the contract compares
|
|
536
|
+
measured colours as hex, so one side has to be converted and it is this one.
|
|
537
|
+
The conversion is Ottosson's OKLab -> linear sRGB with a clamp at the gamut,
|
|
538
|
+
which is what a browser paints for the same value."""
|
|
539
|
+
body = value.strip()
|
|
540
|
+
if not body.lower().startswith("oklch("):
|
|
541
|
+
return None
|
|
542
|
+
inner = body[body.index("(") + 1:body.rindex(")")]
|
|
543
|
+
inner = inner.split("/")[0]
|
|
544
|
+
parts = [p for p in re.split(r"[\s,]+", inner.strip()) if p]
|
|
545
|
+
if len(parts) < 3:
|
|
546
|
+
return None
|
|
547
|
+
try:
|
|
548
|
+
light = parts[0]
|
|
549
|
+
lum = float(light[:-1]) / 100.0 if light.endswith("%") else float(light)
|
|
550
|
+
c = float(parts[1])
|
|
551
|
+
hue = parts[2]
|
|
552
|
+
h = float(hue[:-3]) if hue.endswith("deg") else float(hue)
|
|
553
|
+
except ValueError:
|
|
554
|
+
return None
|
|
555
|
+
rad = math.radians(h)
|
|
556
|
+
a_, b_ = c * math.cos(rad), c * math.sin(rad)
|
|
557
|
+
l_ = (lum + 0.3963377774 * a_ + 0.2158037573 * b_) ** 3
|
|
558
|
+
m_ = (lum - 0.1055613458 * a_ - 0.0638541728 * b_) ** 3
|
|
559
|
+
s_ = (lum - 0.0894841775 * a_ - 1.2914855480 * b_) ** 3
|
|
560
|
+
r = 4.0767416621 * l_ - 3.3077115913 * m_ + 0.2309699292 * s_
|
|
561
|
+
g = -1.2684380046 * l_ + 2.6097574011 * m_ - 0.3413193965 * s_
|
|
562
|
+
bl = -0.0041960863 * l_ - 0.7034186147 * m_ + 1.7076147010 * s_
|
|
563
|
+
|
|
564
|
+
def gamma(x):
|
|
565
|
+
x = min(1.0, max(0.0, x))
|
|
566
|
+
return 12.92 * x if x <= 0.0031308 else 1.055 * x ** (1 / 2.4) - 0.055
|
|
567
|
+
return "#%02x%02x%02x" % tuple(int(round(gamma(v) * 255)) for v in (r, g, bl))
|
|
568
|
+
|
|
569
|
+
|
|
570
|
+
def design_md_tokens(root):
|
|
571
|
+
"""(tokens, source) from Hallmark's locked `design.md`, or ({}, "").
|
|
572
|
+
|
|
573
|
+
Hallmark's file owns the material: the palette stated in OKLCH, the font
|
|
574
|
+
roles and the motion character. It owns no state set, no component
|
|
575
|
+
inventory and no measured evidence, which stay the contract's, so reading it
|
|
576
|
+
fills the tokens half and leaves the rest to `contract_data`."""
|
|
577
|
+
for name in DESIGN_MD:
|
|
578
|
+
path = os.path.join(root, name)
|
|
579
|
+
if not os.path.isfile(path):
|
|
580
|
+
continue
|
|
581
|
+
text = open(path, encoding="utf-8", errors="replace").read()
|
|
582
|
+
block = re.search(r"```css\s*(.*?)```", text, re.S)
|
|
583
|
+
if not block:
|
|
584
|
+
continue
|
|
585
|
+
colors, fonts = {}, {}
|
|
586
|
+
for var, value in re.findall(r"--([a-z0-9-]+)\s*:\s*([^;]+);", block.group(1)):
|
|
587
|
+
value = value.strip()
|
|
588
|
+
if var.startswith("color-"):
|
|
589
|
+
role = var[len("color-"):]
|
|
590
|
+
hexv = _oklch_to_hex(value) if value.lower().startswith("oklch(") else (
|
|
591
|
+
value if re.fullmatch(r"#[0-9a-fA-F]{3,8}", value) else None)
|
|
592
|
+
if hexv:
|
|
593
|
+
colors[role] = hexv
|
|
594
|
+
elif var.startswith("font-"):
|
|
595
|
+
fonts[var[len("font-"):]] = value
|
|
596
|
+
if colors:
|
|
597
|
+
tokens = {"colors": colors}
|
|
598
|
+
if fonts:
|
|
599
|
+
tokens["fonts"] = fonts
|
|
600
|
+
return tokens, "design-md"
|
|
601
|
+
return {}, ""
|
|
602
|
+
|
|
603
|
+
|
|
509
604
|
def derive(root):
|
|
510
605
|
"""(tokens, source, read from) from the repository's own token source, or
|
|
511
606
|
(None, reason, []) when it carries none."""
|
|
607
|
+
locked, locked_source = design_md_tokens(root)
|
|
608
|
+
if locked.get("colors"):
|
|
609
|
+
# a locked system wins over a re-derivation: pages share it, and a second
|
|
610
|
+
# floor derived beside it is the drift plan 133 exists to prevent
|
|
611
|
+
return locked, locked_source, [os.path.join(root, "design.md")]
|
|
512
612
|
files = walk(root)
|
|
513
613
|
for name, reader in (("css-custom-properties", css_tokens),
|
|
514
614
|
("tailwind-config", tailwind_tokens),
|
|
@@ -532,10 +632,19 @@ def contract_data(tokens, source):
|
|
|
532
632
|
"colors": tokens.get("colors") or {},
|
|
533
633
|
"tap_target": TAP_TARGET,
|
|
534
634
|
"contrast": {"normal": CONTRAST_NORMAL, "large": CONTRAST_LARGE},
|
|
635
|
+
# Hallmark's design.md states the font roles; nothing else does, so
|
|
636
|
+
# they ride the tokens when it is the source (audit of plan 133)
|
|
637
|
+
**({"fonts": tokens["fonts"]} if tokens.get("fonts") else {}),
|
|
535
638
|
},
|
|
536
639
|
"states": {"interactive": list(STATES_INTERACTIVE),
|
|
537
640
|
"data": list(STATES_DATA)},
|
|
538
641
|
"components": [],
|
|
642
|
+
# plan 133: one machine-read precedence between this contract and
|
|
643
|
+
# Hallmark's design.md, so the two floors cannot drift. `ours` is what a
|
|
644
|
+
# Hallmark stamp, waiver or verbatim flag can never relax; `theirs` is
|
|
645
|
+
# the material we do not judge; `shared` states the same intent on both
|
|
646
|
+
# sides, our numbers and their shapes.
|
|
647
|
+
"precedence": dict(PRECEDENCE),
|
|
539
648
|
}
|
|
540
649
|
|
|
541
650
|
|
|
@@ -614,6 +723,40 @@ def _violation(component, rule, detail):
|
|
|
614
723
|
return {"component": component, "rule": rule, "detail": detail}
|
|
615
724
|
|
|
616
725
|
|
|
726
|
+
def precedence_problem(table):
|
|
727
|
+
"""Why a contract's precedence cannot be read, or "" when it can.
|
|
728
|
+
|
|
729
|
+
Plan 133: the table is the only tie-break between this floor and Hallmark's
|
|
730
|
+
design.md, so an ambiguous one is refused rather than resolved by whoever
|
|
731
|
+
reads it next. Absent is allowed - a contract written before the table
|
|
732
|
+
existed keeps working - but a present one must name every key exactly once
|
|
733
|
+
and must not hand `facts` to the user's own words."""
|
|
734
|
+
if table is None:
|
|
735
|
+
return ""
|
|
736
|
+
if not isinstance(table, dict):
|
|
737
|
+
return "precedence must be an object of classes to keys"
|
|
738
|
+
seen = {}
|
|
739
|
+
for cls in ("ours", "theirs", "shared"):
|
|
740
|
+
keys = table.get(cls)
|
|
741
|
+
if keys is None:
|
|
742
|
+
continue
|
|
743
|
+
if not isinstance(keys, list) or not all(isinstance(k, str) for k in keys):
|
|
744
|
+
return "precedence.%s must be a list of key names" % cls
|
|
745
|
+
for key in keys:
|
|
746
|
+
if key in seen:
|
|
747
|
+
return ("precedence names %r twice (%s and %s): one key belongs "
|
|
748
|
+
"to one source" % (key, seen[key], cls))
|
|
749
|
+
seen[key] = cls
|
|
750
|
+
if "facts" in table.get("theirs", []) or "facts" in table.get("shared", []):
|
|
751
|
+
return ("precedence cannot share `facts`: an invented metric, quote or "
|
|
752
|
+
"logo is never licensed by a theme, a waiver or the user's words")
|
|
753
|
+
verbatim = table.get("verbatim")
|
|
754
|
+
if verbatim not in (None, "style"):
|
|
755
|
+
return ("precedence.verbatim may only be `style`: the user's own words "
|
|
756
|
+
"excuse a style gate, never a fabricated fact")
|
|
757
|
+
return ""
|
|
758
|
+
|
|
759
|
+
|
|
617
760
|
def check(data, measured):
|
|
618
761
|
"""(violations, unjudged, judged): every disagreement between a measurement
|
|
619
762
|
and the contract, each naming its component and its rule, the count of
|
|
@@ -806,6 +949,8 @@ def parse(argv, names):
|
|
|
806
949
|
arg = argv[i]
|
|
807
950
|
if arg == "--json":
|
|
808
951
|
out["json"] = True
|
|
952
|
+
elif arg == "--render":
|
|
953
|
+
out["render"] = True
|
|
809
954
|
elif arg in names:
|
|
810
955
|
if i + 1 >= len(argv):
|
|
811
956
|
raise Usage("%s wants a value" % arg)
|
|
@@ -881,6 +1026,140 @@ def derive_cli(opts):
|
|
|
881
1026
|
return 0
|
|
882
1027
|
|
|
883
1028
|
|
|
1029
|
+
SLOPLINT = os.path.join("skills", "hallmark", "scripts", "sloplint.mjs")
|
|
1030
|
+
|
|
1031
|
+
|
|
1032
|
+
def sloplint_path(root):
|
|
1033
|
+
"""The vendored linter's path, or "" when it is not installed beside us."""
|
|
1034
|
+
# `HERE` is the realpath of this script's checkout: `abspath(__file__)` is
|
|
1035
|
+
# the symlink in `~/.config/tezgah/bin` under an install, so the linter was
|
|
1036
|
+
# looked for in `~/.config/tezgah/skills/...`, which no install writes
|
|
1037
|
+
# (audit of plan 133). `root`'s own copy comes first for a vendored checkout.
|
|
1038
|
+
candidates = [
|
|
1039
|
+
os.path.join(root, SLOPLINT),
|
|
1040
|
+
os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(root))), SLOPLINT),
|
|
1041
|
+
os.path.join(HERE, SLOPLINT),
|
|
1042
|
+
]
|
|
1043
|
+
for path in candidates:
|
|
1044
|
+
if os.path.isfile(path):
|
|
1045
|
+
return path
|
|
1046
|
+
return ""
|
|
1047
|
+
|
|
1048
|
+
|
|
1049
|
+
def slop_cli(opts):
|
|
1050
|
+
"""Hallmark's gate list, run over this repository, into one verdict.
|
|
1051
|
+
|
|
1052
|
+
The Floor is theirs and Ours is the contract's, so this verb is the one place
|
|
1053
|
+
the two are merged: `sloplint --json` gives FAIL/REFLEX, and the contract's
|
|
1054
|
+
`check` runs when a measurement is given. A merge that hides one side would
|
|
1055
|
+
make a page pass here and fail in the Stop rule, so the verdict is the union
|
|
1056
|
+
and it is written down (`.tezgah/design/slop.json`) for that rule to read."""
|
|
1057
|
+
root = project_top(os.path.abspath(opts.get("repo") or ""))
|
|
1058
|
+
if not os.path.isdir(root):
|
|
1059
|
+
raise Usage("--repo must name a directory")
|
|
1060
|
+
linter = sloplint_path(root)
|
|
1061
|
+
if not linter:
|
|
1062
|
+
sys.stderr.write("tezgah-design: hallmark is not installed beside tezgah "
|
|
1063
|
+
"(%s), so only the contract check can run - no static "
|
|
1064
|
+
"slop tier this time\n" % SLOPLINT)
|
|
1065
|
+
return 3
|
|
1066
|
+
if not shutil.which("node"):
|
|
1067
|
+
sys.stderr.write("tezgah-design: node is not on PATH, so hallmark's "
|
|
1068
|
+
"sloplint cannot run - only the contract check can\n")
|
|
1069
|
+
return 3
|
|
1070
|
+
target = opts.get("url") or root
|
|
1071
|
+
argv = [shutil.which("node"), linter, "--json"]
|
|
1072
|
+
if opts.get("url"):
|
|
1073
|
+
argv += ["--url", opts["url"]] # a URL is an address, never a path
|
|
1074
|
+
else:
|
|
1075
|
+
argv.append(root)
|
|
1076
|
+
if opts.get("render"):
|
|
1077
|
+
argv.append("--render")
|
|
1078
|
+
if opts.get("genre"):
|
|
1079
|
+
argv += ["--genre", opts["genre"]]
|
|
1080
|
+
try:
|
|
1081
|
+
proc = subprocess.run(argv, capture_output=True, text=True, timeout=300)
|
|
1082
|
+
except (OSError, subprocess.SubprocessError) as exc:
|
|
1083
|
+
raise Usage("sloplint could not run: %s" % exc)
|
|
1084
|
+
try:
|
|
1085
|
+
report = json.loads(proc.stdout)
|
|
1086
|
+
except ValueError:
|
|
1087
|
+
raise Usage("sloplint printed no JSON (exit %d): %s"
|
|
1088
|
+
% (proc.returncode, (proc.stderr or "").strip()[:200]))
|
|
1089
|
+
summary = report.get("summary") or {}
|
|
1090
|
+
fails, reflex = int(summary.get("fails") or 0), int(summary.get("reflex") or 0)
|
|
1091
|
+
# What the render tier actually did, never what the flag asked for: without
|
|
1092
|
+
# puppeteer-core sloplint answers `not run: …` and every Floor/R and M/R gate
|
|
1093
|
+
# stays unjudged, so a `clean` there would excuse a page nobody measured
|
|
1094
|
+
# (review of plan 133 finding 2).
|
|
1095
|
+
rendered = str(summary.get("render") or "off")
|
|
1096
|
+
unjudged = rendered.startswith("not run")
|
|
1097
|
+
verdict = {"version": 1, "tool": "tezgah-design slop",
|
|
1098
|
+
"sloplint_exit": proc.returncode,
|
|
1099
|
+
"target": target if opts.get("url") else os.path.abspath(target),
|
|
1100
|
+
"render": rendered,
|
|
1101
|
+
"render_unjudged": unjudged,
|
|
1102
|
+
"fails": fails, "reflex": reflex,
|
|
1103
|
+
"waived": int(summary.get("waived") or 0),
|
|
1104
|
+
"answered": int(summary.get("answered") or 0),
|
|
1105
|
+
"clean": fails == 0 and reflex == 0 and not unjudged,
|
|
1106
|
+
"findings": [f for f in (report.get("findings") or [])
|
|
1107
|
+
if f.get("grade") in ("FAIL", "REFLEX")]}
|
|
1108
|
+
ws = linked_main(root) or root
|
|
1109
|
+
# The union, enforced here rather than in the Stop rule (review of plan 133
|
|
1110
|
+
# finding 3): a component's UI floor is Hallmark's gate list AND this
|
|
1111
|
+
# repository's contract, so `slop` reads the contract half too. No contract,
|
|
1112
|
+
# no obligation. A contract with no measurement is unjudged, never clean.
|
|
1113
|
+
contract_path = os.path.join(ws, ".tezgah", "design-contract.md")
|
|
1114
|
+
contract = {"present": os.path.isfile(contract_path), "judged": False,
|
|
1115
|
+
"violations": [], "unjudged": 0}
|
|
1116
|
+
if contract["present"]:
|
|
1117
|
+
data, reason = read_contract(contract_path)
|
|
1118
|
+
if data is None:
|
|
1119
|
+
raise Usage(reason)
|
|
1120
|
+
problem = precedence_problem(data.get("precedence"))
|
|
1121
|
+
if problem:
|
|
1122
|
+
raise Usage(problem)
|
|
1123
|
+
raw = ""
|
|
1124
|
+
measured_path = opts.get("measured") or os.path.join(
|
|
1125
|
+
ws, ".tezgah", "design", "measurement.json")
|
|
1126
|
+
if os.path.isfile(measured_path):
|
|
1127
|
+
with open(measured_path, encoding="utf-8") as fh:
|
|
1128
|
+
raw = fh.read()
|
|
1129
|
+
if raw.strip():
|
|
1130
|
+
try:
|
|
1131
|
+
got = json.loads(raw)
|
|
1132
|
+
except ValueError:
|
|
1133
|
+
raise Usage("the measurement is not JSON: %s" % measured_path)
|
|
1134
|
+
if isinstance(got, list):
|
|
1135
|
+
got = {"components": got} # the shape check_cli also accepts
|
|
1136
|
+
violations, unjudged, judged = check(data, got)
|
|
1137
|
+
contract.update(judged=judged > 0, unjudged=unjudged,
|
|
1138
|
+
violations=list(violations))
|
|
1139
|
+
verdict["contract"] = contract
|
|
1140
|
+
if contract["present"] and (not contract["judged"] or contract["violations"]):
|
|
1141
|
+
verdict["clean"] = False
|
|
1142
|
+
out = opts.get("out") or os.path.join(ws, ".tezgah", "design", "slop.json")
|
|
1143
|
+
try:
|
|
1144
|
+
os.makedirs(os.path.dirname(os.path.abspath(out)), exist_ok=True)
|
|
1145
|
+
with open(out, "w", encoding="utf-8") as fh:
|
|
1146
|
+
json.dump(verdict, fh, indent=2, sort_keys=True)
|
|
1147
|
+
fh.write("\n")
|
|
1148
|
+
except OSError as exc:
|
|
1149
|
+
raise Usage("cannot write %s: %s" % (out, exc))
|
|
1150
|
+
if opts.get("json"):
|
|
1151
|
+
_print_json(verdict)
|
|
1152
|
+
else:
|
|
1153
|
+
sys.stdout.write("slop: %d FAIL, %d REFLEX over %s (render %s) -> %s\n"
|
|
1154
|
+
% (fails, reflex, target, rendered,
|
|
1155
|
+
"clean" if verdict["clean"] else "not clean"))
|
|
1156
|
+
if contract["present"] and not contract["judged"]:
|
|
1157
|
+
sys.stderr.write("tezgah-design: the contract exists but no measurement "
|
|
1158
|
+
"judged a component, so the design half is unjudged - "
|
|
1159
|
+
"run the analyze-app loop and pass --measured\n")
|
|
1160
|
+
return 0 if verdict["clean"] and not contract["violations"] else 1
|
|
1161
|
+
|
|
1162
|
+
|
|
884
1163
|
def check_cli(opts):
|
|
885
1164
|
contract = opts.get("contract")
|
|
886
1165
|
measured = opts.get("measured")
|
|
@@ -895,6 +1174,9 @@ def check_cli(opts):
|
|
|
895
1174
|
data, reason = read_contract(contract)
|
|
896
1175
|
if data is None:
|
|
897
1176
|
raise Usage(reason)
|
|
1177
|
+
problem = precedence_problem(data.get("precedence"))
|
|
1178
|
+
if problem:
|
|
1179
|
+
raise Usage(problem)
|
|
898
1180
|
if measured == "-":
|
|
899
1181
|
raw = sys.stdin.read()
|
|
900
1182
|
else:
|
|
@@ -954,12 +1236,17 @@ def main(argv):
|
|
|
954
1236
|
sys.stdout.write(__doc__)
|
|
955
1237
|
return 0 if argv else 2
|
|
956
1238
|
verb, rest = argv[0], argv[1:]
|
|
1239
|
+
if verb in ("derive", "check") and "--render" in rest:
|
|
1240
|
+
sys.stderr.write("tezgah-design: --render belongs to `slop`, not %s\n" % verb)
|
|
1241
|
+
return 2
|
|
957
1242
|
try:
|
|
958
1243
|
if verb == "derive":
|
|
959
1244
|
return derive_cli(parse(rest, ("--repo", "--out")))
|
|
960
1245
|
if verb == "check":
|
|
961
1246
|
return check_cli(parse(rest, ("--contract", "--measured")))
|
|
962
|
-
|
|
1247
|
+
if verb == "slop":
|
|
1248
|
+
return slop_cli(parse(rest, ("--repo", "--url", "--out", "--genre", "--measured")))
|
|
1249
|
+
raise Usage("unknown verb: %s (derive|check|slop)" % verb)
|
|
963
1250
|
except Usage as exc:
|
|
964
1251
|
sys.stderr.write("tezgah-design: %s\n" % exc)
|
|
965
1252
|
return 2
|
package/bin/tezgah-docs
CHANGED
|
@@ -106,7 +106,7 @@ RUN = re.compile(r"((?:`[A-Za-z_][A-Za-z0-9_]*(?:\(\))?`\s*[/,]?\s*){1,5})$")
|
|
|
106
106
|
CITE = re.compile(r"`([\w.-]+(?:/[\w.-]+)+|[\w-]+\.\w+):(\d+)(?:-(\d+))?`"
|
|
107
107
|
r"|`(:(\d+)(?:-(\d+))?)`")
|
|
108
108
|
# The symbol written after the citation instead of before it, the way a table
|
|
109
|
-
# cell reads: `hooks/tezgah_policy.py:
|
|
109
|
+
# cell reads: `hooks/tezgah_policy.py:819-1158` (`CORE`).
|
|
110
110
|
AFTER = re.compile(r"\s*\(`([A-Za-z_][A-Za-z0-9_]*)(?:\(\))?`\)")
|
|
111
111
|
# Any `path:line`, backticked or not: what CITE does not match of these (a
|
|
112
112
|
# bare token, a comma list `x.py:12,40`) is counted as unjudged, so a citation
|
package/bin/tezgah-doctor
CHANGED
|
@@ -11,7 +11,9 @@ Two stores grow without bound and neither rotates on its own:
|
|
|
11
11
|
|
|
12
12
|
It also reports the hosts' own state (~/.codex, ~/.omp, ~/.claude) and never
|
|
13
13
|
touches it: those stores belong to the hosts, and the number is here so a reader
|
|
14
|
-
can decide, not so this tool can act.
|
|
14
|
+
can decide, not so this tool can act. The current checkout's `.tezgah` shape is
|
|
15
|
+
one row: its own repository, or tracked by the project (folded), whose commits
|
|
16
|
+
are then the project's history.
|
|
15
17
|
|
|
16
18
|
This tool is read-only by default. With --clean it vacuums the opencode database
|
|
17
19
|
(only when opencode is not running, so it cannot fight a live connection).
|
|
@@ -65,7 +67,7 @@ HOME = os.path.expanduser("~")
|
|
|
65
67
|
REPO_ROOT = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
|
|
66
68
|
sys.path.insert(0, os.path.join(REPO_ROOT, "hooks"))
|
|
67
69
|
from tezgah_paths import (CACHE, CODEGRAPH, codegraph_bin, # noqa: E402
|
|
68
|
-
fallback_cache, root_for, roots)
|
|
70
|
+
fallback_cache, project_top, root_for, roots, workspace)
|
|
69
71
|
|
|
70
72
|
# the coverage rules, in the bench directory next to the hooks that own the roots
|
|
71
73
|
# and the binary resolver. MANIFEST lists it, so it ships; it is also the one file
|
|
@@ -214,6 +216,37 @@ def opencode_running():
|
|
|
214
216
|
return False
|
|
215
217
|
|
|
216
218
|
|
|
219
|
+
def workspace_shape(path):
|
|
220
|
+
"""{repo, shape} for the checkout holding `path`: `own` when its `.tezgah`
|
|
221
|
+
holds a repository of its own (a linked worktree's link to the main
|
|
222
|
+
checkout's included), `tracked` when the project tracks it (folded:
|
|
223
|
+
`tezgah_research.folded`, the project's history carries it), else `none`;
|
|
224
|
+
repo is None outside a git checkout."""
|
|
225
|
+
import tezgah_research
|
|
226
|
+
try:
|
|
227
|
+
out = subprocess.run(["git", "-C", path, "rev-parse", "--show-toplevel"],
|
|
228
|
+
capture_output=True, text=True)
|
|
229
|
+
except OSError:
|
|
230
|
+
return {"repo": None, "shape": "none"}
|
|
231
|
+
if out.returncode or not out.stdout.strip():
|
|
232
|
+
return {"repo": None, "shape": "none"}
|
|
233
|
+
repo = project_top(out.stdout.strip())
|
|
234
|
+
if tezgah_research.folded(repo):
|
|
235
|
+
shape = "tracked"
|
|
236
|
+
elif os.path.isdir(os.path.join(os.path.realpath(workspace(repo)), ".git")):
|
|
237
|
+
shape = "own"
|
|
238
|
+
else:
|
|
239
|
+
shape = "none"
|
|
240
|
+
return {"repo": repo, "shape": shape}
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
WORKSPACE_ROWS = {
|
|
244
|
+
"own": "own repository (`git -C .tezgah`)",
|
|
245
|
+
"tracked": "tracked by the project: the project's history carries it",
|
|
246
|
+
"none": "none yet",
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
|
|
217
250
|
def collect(pairs):
|
|
218
251
|
cfg = opencode_cfg()
|
|
219
252
|
repos = []
|
|
@@ -230,6 +263,7 @@ def collect(pairs):
|
|
|
230
263
|
"codegraph_repos": repos,
|
|
231
264
|
"codegraph_bytes": sum(r["bytes"] for r in repos),
|
|
232
265
|
"tezgah_cache_bytes": du(TEZGAH_CACHE) if os.path.isdir(TEZGAH_CACHE) else 0,
|
|
266
|
+
"workspace": workspace_shape(os.getcwd()),
|
|
233
267
|
**host_bytes(),
|
|
234
268
|
}
|
|
235
269
|
|
|
@@ -571,6 +605,9 @@ def report(rep):
|
|
|
571
605
|
len(rows) - indexed))
|
|
572
606
|
print("tezgah")
|
|
573
607
|
print(" cache %s" % human(rep["tezgah_cache_bytes"]))
|
|
608
|
+
ws = rep["workspace"]
|
|
609
|
+
print(" workspace %s" % ("%s (%s)" % (WORKSPACE_ROWS[ws["shape"]], ws["repo"])
|
|
610
|
+
if ws["repo"] else "not in a git checkout"))
|
|
574
611
|
print("host state (the hosts' own; this tool never touches it)")
|
|
575
612
|
for label, key in (("codex", "codex_bytes"), ("omp", "omp_bytes"),
|
|
576
613
|
("claude", "claude_bytes")):
|
|
@@ -9,8 +9,12 @@ upstream clone being present.
|
|
|
9
9
|
bin/tezgah-import-ai-research --source <path-to-AI-research-SKILLs-clone> --rev 773a529
|
|
10
10
|
bin/tezgah-import-ai-research --check
|
|
11
11
|
|
|
12
|
-
A vendored path is its provenance, so the upstream layout is kept verbatim
|
|
13
|
-
`<category>/<skill>/SKILL.md`
|
|
12
|
+
A vendored path is its provenance, so the upstream layout is kept verbatim, with
|
|
13
|
+
one rename: upstream's `<category>/<skill>/SKILL.md` is written as
|
|
14
|
+
`<category>/<skill>/ENTRY.md` beside its `references/`, bytes unchanged. codex
|
|
15
|
+
and Cursor list every SKILL.md below a skills directory, nested ones included,
|
|
16
|
+
so 98 vendored entries named SKILL.md would each be listed as a host skill and
|
|
17
|
+
push tezgah's own out of the host's skill budget. What is dropped, and why,
|
|
14
18
|
is DROP_FILES and DROP_DIRS; everything that is not markdown is dropped by the
|
|
15
19
|
`*.md` filter, so no PDF, LaTeX class, image or `.gitkeep` reaches the repo. A
|
|
16
20
|
vendored file with no YAML frontmatter gets one attribution comment; upstream's
|
|
@@ -41,7 +45,7 @@ LICENCE = "MIT"
|
|
|
41
45
|
EXPECTED_CATEGORIES, EXPECTED_SKILLS = 23, 98
|
|
42
46
|
|
|
43
47
|
# Three machine-scraped reference dumps. They are concatenated official docs with
|
|
44
|
-
# `URL:` headers, not guides, and the entry's own
|
|
48
|
+
# `URL:` headers, not guides, and the entry's own ENTRY.md already distils them.
|
|
45
49
|
DROP_FILES = (
|
|
46
50
|
"03-fine-tuning/unsloth/references/llms-full.md",
|
|
47
51
|
"03-fine-tuning/unsloth/references/llms-txt.md",
|
|
@@ -86,6 +90,8 @@ GENERATED_MARKS = ("automatically generated from official documentation",
|
|
|
86
90
|
ATTRIBUTION = "<!-- vendored from orchestra-research/%s@%s %s; %s (c) Orchestra Research -->"
|
|
87
91
|
|
|
88
92
|
CATEGORY_RE = re.compile(r"^(0-|[0-9]{2}-)")
|
|
93
|
+
# Upstream names an entry SKILL.md; the vendored copy is ENTRY.md (module docstring).
|
|
94
|
+
UPSTREAM_ENTRY, ENTRY = "SKILL.md", "ENTRY.md"
|
|
89
95
|
|
|
90
96
|
|
|
91
97
|
def sha256(path):
|
|
@@ -155,6 +161,12 @@ def rel_of(category, skill):
|
|
|
155
161
|
return category if skill == category else "%s/%s" % (category, skill)
|
|
156
162
|
|
|
157
163
|
|
|
164
|
+
def vendored(relfile):
|
|
165
|
+
"""The path an upstream file is written to: an entry SKILL.md becomes ENTRY.md."""
|
|
166
|
+
head, name = os.path.split(relfile)
|
|
167
|
+
return os.path.join(head, ENTRY) if name == UPSTREAM_ENTRY else relfile
|
|
168
|
+
|
|
169
|
+
|
|
158
170
|
def kept_files(source, rel):
|
|
159
171
|
"""The files this vendoring keeps from one skill dir, as relative paths."""
|
|
160
172
|
base = os.path.join(source, rel)
|
|
@@ -235,8 +247,8 @@ def build(source, rev):
|
|
|
235
247
|
"upstream_path": rel,
|
|
236
248
|
}
|
|
237
249
|
for relfile, body in sorted(body_texts.items()):
|
|
238
|
-
files[relfile] = body
|
|
239
|
-
entry["files"].append({"path": relfile, "bytes": len(body.encode()),
|
|
250
|
+
files[vendored(relfile)] = body
|
|
251
|
+
entry["files"].append({"path": vendored(relfile), "bytes": len(body.encode()),
|
|
240
252
|
"sha256": hashlib.sha256(body.encode()).hexdigest()})
|
|
241
253
|
entry["bytes"] = sum(f["bytes"] for f in entry["files"])
|
|
242
254
|
rows.append(entry)
|
|
@@ -270,8 +282,8 @@ def build(source, rev):
|
|
|
270
282
|
flags.append("stale-api")
|
|
271
283
|
if entry["dangling_links"]:
|
|
272
284
|
flags.append("dead-links: %d" % len(entry["dangling_links"]))
|
|
273
|
-
lines.append("| `%s` | `%s
|
|
274
|
-
% (entry["dir"], entry["upstream_path"], entry["purpose"],
|
|
285
|
+
lines.append("| `%s` | `%s/%s` | %s | %s |"
|
|
286
|
+
% (entry["dir"], entry["upstream_path"], ENTRY, entry["purpose"],
|
|
275
287
|
", ".join(flags)))
|
|
276
288
|
generated["index/%s.md" % stage] = "\n".join(lines) + "\n"
|
|
277
289
|
|
|
@@ -314,10 +326,12 @@ def source_text(manifest, rev):
|
|
|
314
326
|
"## What is vendored\n\n"
|
|
315
327
|
"Every skill's `SKILL.md` and every markdown file beside it, in the upstream\n"
|
|
316
328
|
"layout, because a vendored path is its provenance. %d skills across %d\n"
|
|
317
|
-
"categories, %d files, %d bytes
|
|
329
|
+
"categories, %d files, %d bytes. One rename: each entry's `SKILL.md` sits at\n"
|
|
330
|
+
"the upstream path as `ENTRY.md`, bytes unchanged, so a host that lists every\n"
|
|
331
|
+
"`SKILL.md` below its skills directory (codex, Cursor) does not list it.\n\n"
|
|
318
332
|
"## What is not, and why\n\n"
|
|
319
333
|
"Files: %s - machine-scraped reference dumps, which the entry's own\n"
|
|
320
|
-
"`
|
|
334
|
+
"`ENTRY.md` already distils.\n\n"
|
|
321
335
|
"Directories: %s - LaTeX class/bst/bib trees and example PDFs,\n"
|
|
322
336
|
"re-downloadable from each venue.\n\n"
|
|
323
337
|
"Everything else that is not markdown (PDFs, images, `.gitkeep`, scripts)\n"
|
|
@@ -325,9 +339,9 @@ def source_text(manifest, rev):
|
|
|
325
339
|
"`packages/`, `video-promo/` are upstream's repo furniture, not content.\n\n"
|
|
326
340
|
"## The only modification\n\n"
|
|
327
341
|
"A markdown file that carries no YAML frontmatter gets one attribution\n"
|
|
328
|
-
"comment on its first line. `
|
|
329
|
-
"frontmatter included. `skills/ai-research/SKILL.md` is
|
|
330
|
-
"not part of the manifest.\n\n"
|
|
342
|
+
"comment on its first line. `ENTRY.md` files are byte-for-byte upstream\n"
|
|
343
|
+
"`SKILL.md`, frontmatter included. `skills/ai-research/SKILL.md` is\n"
|
|
344
|
+
"tezgah's own and is not part of the manifest.\n\n"
|
|
331
345
|
"## Re-vendoring\n\n"
|
|
332
346
|
"`bin/tezgah-import-ai-research --source <clone> --rev <sha>`, then commit\n"
|
|
333
347
|
"the diff. `--check` verifies the committed tree against `library.json`\n"
|