litgrok-ai 0.2.0 → 0.2.4
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/.grok/agents/litgrok-boulder-executor.md +28 -0
- package/.grok/agents/litgrok-korean-prose-editor.md +28 -0
- package/.grok/agents/litgrok-korean-style-analyzer.md +26 -0
- package/.grok/agents/litgrok-librarian-researcher.md +27 -0
- package/.grok/agents/litgrok-meaning-preservation-auditor.md +26 -0
- package/.grok/agents/litgrok-native-flow-reviewer.md +26 -0
- package/.grok/agents/litgrok-oracle-verifier.md +28 -0
- package/.grok/agents/litgrok-polish-orchestrator.md +26 -0
- package/.grok/agents/litgrok-prometheus-planner.md +27 -0
- package/.grok/agents/litgrok-qa-runner.md +29 -0
- package/.grok/agents/litgrok-quality-reviewer.md +29 -0
- package/.grok/hooks/deliverable-hedge-guard.json +1 -1
- package/.grok/hooks/plan-gate.mjs +81 -0
- package/.grok/hooks/post-compact.json +1 -1
- package/.grok/hooks/post-tool-use-failure.json +1 -1
- package/.grok/hooks/post-tool-use.json +1 -1
- package/.grok/hooks/pre-compact.json +1 -1
- package/.grok/hooks/record-passive-event.mjs +25 -5
- package/.grok/hooks/session-start.json +1 -1
- package/.grok/hooks/session-start.mjs +23 -0
- package/.grok/hooks/stop-failure.json +1 -1
- package/.grok/hooks/stop.json +1 -1
- package/.grok/hooks/stop.mjs +32 -2
- package/.grok/hooks/subagent-start.json +1 -1
- package/.grok/hooks/subagent-stop.json +1 -1
- package/.grok/hooks/user-prompt-submit.json +1 -1
- package/.grok/skills/autoconference/LICENSE +21 -0
- package/.grok/skills/autoconference/PROVENANCE.md +23 -0
- package/.grok/skills/autoconference/SKILL.md +124 -263
- package/.grok/skills/autoconference/assets/conference_template.md +76 -0
- package/.grok/skills/autoconference/assets/report_template.md +56 -0
- package/.grok/skills/autoconference/assets/synthesis_template.md +40 -0
- package/.grok/skills/autoconference/references/_canonical-corpus/manifest.json +138 -0
- package/.grok/skills/autoconference/references/agent-prompts.md +30 -0
- package/.grok/skills/autoconference/references/conference-protocol.md +21 -0
- package/.grok/skills/autoconference/references/core-principles.md +13 -0
- package/.grok/skills/autoconference/references/family-contract.md +26 -0
- package/.grok/skills/autoconference/references/modes/analyze.md +11 -0
- package/.grok/skills/autoconference/references/modes/core/convergence-guide.md +41 -0
- package/.grok/skills/autoconference/references/modes/core/crash-recovery.md +11 -0
- package/.grok/skills/autoconference/references/modes/core.md +26 -0
- package/.grok/skills/autoconference/references/modes/debate.md +11 -0
- package/.grok/skills/autoconference/references/modes/plan.md +12 -0
- package/.grok/skills/autoconference/references/modes/resume.md +11 -0
- package/.grok/skills/autoconference/references/modes/ship.md +11 -0
- package/.grok/skills/autoconference/references/modes/survey.md +11 -0
- package/.grok/skills/autoconference/references/results-logging.md +12 -0
- package/.grok/skills/autoconference/references/visualization-guide.md +10 -0
- package/.grok/skills/autoconference/scripts/init_conference.py +620 -0
- package/.grok/skills/autoconference/scripts/verify-canonical-corpus.mjs +177 -0
- package/.grok/skills/autoconference/templates/code-performance.md +59 -0
- package/.grok/skills/autoconference/templates/debate-mode.md +50 -0
- package/.grok/skills/autoconference/templates/prompt-optimization.md +58 -0
- package/.grok/skills/autoconference/templates/quick-conference.md +48 -0
- package/.grok/skills/autoconference/templates/research-synthesis.md +56 -0
- package/.grok/skills/autoconference/templates/survey-mode.md +63 -0
- package/.grok/skills/autoresearch/LICENSE +21 -0
- package/.grok/skills/autoresearch/PROVENANCE.md +22 -0
- package/.grok/skills/autoresearch/SKILL.md +133 -212
- package/.grok/skills/autoresearch/assets/report_template.md +52 -0
- package/.grok/skills/autoresearch/assets/research_template.md +38 -0
- package/.grok/skills/autoresearch/assets/results_template.tsv +2 -0
- package/.grok/skills/autoresearch/references/_canonical-corpus/manifest.json +148 -0
- package/.grok/skills/autoresearch/references/core-principles.md +16 -0
- package/.grok/skills/autoresearch/references/family-contract.md +36 -0
- package/.grok/skills/autoresearch/references/modes/core/evaluator-contract.md +12 -0
- package/.grok/skills/autoresearch/references/modes/core/stuck-detection.md +11 -0
- package/.grok/skills/autoresearch/references/modes/core.md +21 -0
- package/.grok/skills/autoresearch/references/modes/debug/investigation-techniques.md +11 -0
- package/.grok/skills/autoresearch/references/modes/debug.md +11 -0
- package/.grok/skills/autoresearch/references/modes/fix.md +11 -0
- package/.grok/skills/autoresearch/references/modes/learn.md +11 -0
- package/.grok/skills/autoresearch/references/modes/plan.md +14 -0
- package/.grok/skills/autoresearch/references/modes/predict/persona-templates.md +11 -0
- package/.grok/skills/autoresearch/references/modes/predict.md +11 -0
- package/.grok/skills/autoresearch/references/modes/reason.md +11 -0
- package/.grok/skills/autoresearch/references/modes/scenario/dimensions.md +11 -0
- package/.grok/skills/autoresearch/references/modes/scenario.md +11 -0
- package/.grok/skills/autoresearch/references/modes/security/owasp-checklist.md +11 -0
- package/.grok/skills/autoresearch/references/modes/security/stride-model.md +11 -0
- package/.grok/skills/autoresearch/references/modes/security.md +12 -0
- package/.grok/skills/autoresearch/references/modes/ship/type-checklists.md +12 -0
- package/.grok/skills/autoresearch/references/modes/ship.md +11 -0
- package/.grok/skills/autoresearch/references/results-logging.md +12 -0
- package/.grok/skills/autoresearch/references/visualization-guide.md +24 -0
- package/.grok/skills/autoresearch/scripts/init_research.py +365 -0
- package/.grok/skills/autoresearch/scripts/style_presets.py +123 -0
- package/.grok/skills/autoresearch/scripts/verify-canonical-corpus.mjs +179 -0
- package/.grok/skills/browser-drive/SKILL.md +4 -0
- package/.grok/skills/browser-drive/references/snapshot-act-loop.md +61 -0
- package/.grok/skills/debugging/SKILL.md +21 -0
- package/.grok/skills/debugging/references/methodology/00-setup.md +108 -0
- package/.grok/skills/debugging/references/methodology/02-investigate.md +126 -0
- package/.grok/skills/debugging/references/methodology/04-oracle-triple.md +106 -0
- package/.grok/skills/debugging/references/methodology/05-escalate.md +69 -0
- package/.grok/skills/debugging/references/methodology/06-fix.md +116 -0
- package/.grok/skills/debugging/references/methodology/08-qa.md +94 -0
- package/.grok/skills/debugging/references/methodology/09-cleanup.md +164 -0
- package/.grok/skills/debugging/references/methodology/partial-runtime-evidence.md +228 -0
- package/.grok/skills/debugging/references/runtimes/bundled-js-binary.md +415 -0
- package/.grok/skills/debugging/references/runtimes/go.md +252 -0
- package/.grok/skills/debugging/references/runtimes/native-binary.md +484 -0
- package/.grok/skills/debugging/references/runtimes/node.md +260 -0
- package/.grok/skills/debugging/references/runtimes/python.md +248 -0
- package/.grok/skills/debugging/references/runtimes/rust.md +234 -0
- package/.grok/skills/debugging/references/tools/ghidra.md +212 -0
- package/.grok/skills/debugging/references/tools/playwright-cli.md +194 -0
- package/.grok/skills/debugging/references/tools/pwndbg.md +263 -0
- package/.grok/skills/debugging/references/tools/pwntools.md +265 -0
- package/.grok/skills/frontend-ui-ux/LICENSE +21 -0
- package/.grok/skills/frontend-ui-ux/PROVENANCE.json +38 -0
- package/.grok/skills/frontend-ui-ux/SKILL.md +52 -43
- package/.grok/skills/frontend-ui-ux/SOURCE-MANIFEST.json +1060 -0
- package/.grok/skills/frontend-ui-ux/THIRD-PARTY-NOTICE.txt +14 -0
- package/.grok/skills/frontend-ui-ux/data/design-intelligence.json +1 -0
- package/.grok/skills/frontend-ui-ux/references/_canonical-corpus/legal/frontend-ATTRIBUTION.md +217 -0
- package/.grok/skills/frontend-ui-ux/references/_canonical-corpus/legal/frontend-LICENSE-Apache-2.0.txt +201 -0
- package/.grok/skills/frontend-ui-ux/references/_canonical-corpus/legal/root-LICENSE +21 -0
- package/.grok/skills/frontend-ui-ux/references/_canonical-corpus/manifest.json +873 -0
- package/.grok/skills/frontend-ui-ux/references/adaptive-layout.md +92 -0
- package/.grok/skills/frontend-ui-ux/references/brand-and-imagery.md +93 -0
- package/.grok/skills/frontend-ui-ux/references/complete-contract.md +537 -39
- package/.grok/skills/frontend-ui-ux/references/composition.md +85 -0
- package/.grok/skills/frontend-ui-ux/references/creative-directions.md +80 -0
- package/.grok/skills/frontend-ui-ux/references/design/README.md +248 -0
- package/.grok/skills/frontend-ui-ux/references/design/_INDEX.md +191 -0
- package/.grok/skills/frontend-ui-ux/references/design/airbnb.md +393 -0
- package/.grok/skills/frontend-ui-ux/references/design/airtable.md +92 -0
- package/.grok/skills/frontend-ui-ux/references/design/apple.md +250 -0
- package/.grok/skills/frontend-ui-ux/references/design/aside.md +209 -0
- package/.grok/skills/frontend-ui-ux/references/design/binance.md +348 -0
- package/.grok/skills/frontend-ui-ux/references/design/bmw.md +183 -0
- package/.grok/skills/frontend-ui-ux/references/design/brutalist-skill.md +92 -0
- package/.grok/skills/frontend-ui-ux/references/design/bugatti.md +271 -0
- package/.grok/skills/frontend-ui-ux/references/design/cal.md +262 -0
- package/.grok/skills/frontend-ui-ux/references/design/claude.md +315 -0
- package/.grok/skills/frontend-ui-ux/references/design/clay.md +307 -0
- package/.grok/skills/frontend-ui-ux/references/design/clickhouse.md +284 -0
- package/.grok/skills/frontend-ui-ux/references/design/clone-from-url.md +65 -0
- package/.grok/skills/frontend-ui-ux/references/design/cohere.md +269 -0
- package/.grok/skills/frontend-ui-ux/references/design/coinbase.md +132 -0
- package/.grok/skills/frontend-ui-ux/references/design/composio.md +310 -0
- package/.grok/skills/frontend-ui-ux/references/design/cursor.md +312 -0
- package/.grok/skills/frontend-ui-ux/references/design/design-system-architecture.md +244 -0
- package/.grok/skills/frontend-ui-ux/references/design/elevenlabs.md +268 -0
- package/.grok/skills/frontend-ui-ux/references/design/expo.md +284 -0
- package/.grok/skills/frontend-ui-ux/references/design/ferrari.md +317 -0
- package/.grok/skills/frontend-ui-ux/references/design/figma.md +223 -0
- package/.grok/skills/frontend-ui-ux/references/design/framer.md +249 -0
- package/.grok/skills/frontend-ui-ux/references/design/gpt-tasteskill.md +74 -0
- package/.grok/skills/frontend-ui-ux/references/design/hashicorp.md +281 -0
- package/.grok/skills/frontend-ui-ux/references/design/ibm.md +335 -0
- package/.grok/skills/frontend-ui-ux/references/design/image-to-code-skill.md +1228 -0
- package/.grok/skills/frontend-ui-ux/references/design/imagegen-brandkit.md +798 -0
- package/.grok/skills/frontend-ui-ux/references/design/imagegen-frontend-mobile.md +1465 -0
- package/.grok/skills/frontend-ui-ux/references/design/imagegen-frontend-web.md +987 -0
- package/.grok/skills/frontend-ui-ux/references/design/intercom.md +149 -0
- package/.grok/skills/frontend-ui-ux/references/design/kraken.md +128 -0
- package/.grok/skills/frontend-ui-ux/references/design/lamborghini.md +291 -0
- package/.grok/skills/frontend-ui-ux/references/design/layout-skill.md +107 -0
- package/.grok/skills/frontend-ui-ux/references/design/lazyweb.md +77 -0
- package/.grok/skills/frontend-ui-ux/references/design/linear.app.md +370 -0
- package/.grok/skills/frontend-ui-ux/references/design/lovable.md +301 -0
- package/.grok/skills/frontend-ui-ux/references/design/mastercard.md +368 -0
- package/.grok/skills/frontend-ui-ux/references/design/meta.md +369 -0
- package/.grok/skills/frontend-ui-ux/references/design/minimalist-skill.md +85 -0
- package/.grok/skills/frontend-ui-ux/references/design/minimax.md +260 -0
- package/.grok/skills/frontend-ui-ux/references/design/mintlify.md +329 -0
- package/.grok/skills/frontend-ui-ux/references/design/miro.md +111 -0
- package/.grok/skills/frontend-ui-ux/references/design/mistral.ai.md +264 -0
- package/.grok/skills/frontend-ui-ux/references/design/mongodb.md +269 -0
- package/.grok/skills/frontend-ui-ux/references/design/nike.md +366 -0
- package/.grok/skills/frontend-ui-ux/references/design/notion.md +312 -0
- package/.grok/skills/frontend-ui-ux/references/design/nvidia.md +296 -0
- package/.grok/skills/frontend-ui-ux/references/design/ollama.md +270 -0
- package/.grok/skills/frontend-ui-ux/references/design/opencode.ai.md +284 -0
- package/.grok/skills/frontend-ui-ux/references/design/output-skill.md +49 -0
- package/.grok/skills/frontend-ui-ux/references/design/pinterest.md +233 -0
- package/.grok/skills/frontend-ui-ux/references/design/playstation.md +367 -0
- package/.grok/skills/frontend-ui-ux/references/design/posthog.md +259 -0
- package/.grok/skills/frontend-ui-ux/references/design/raycast.md +271 -0
- package/.grok/skills/frontend-ui-ux/references/design/react-dev-tooling-skill.md +230 -0
- package/.grok/skills/frontend-ui-ux/references/design/redesign-skill.md +178 -0
- package/.grok/skills/frontend-ui-ux/references/design/renault.md +314 -0
- package/.grok/skills/frontend-ui-ux/references/design/replicate.md +264 -0
- package/.grok/skills/frontend-ui-ux/references/design/resend.md +306 -0
- package/.grok/skills/frontend-ui-ux/references/design/revolut.md +188 -0
- package/.grok/skills/frontend-ui-ux/references/design/runwayml.md +247 -0
- package/.grok/skills/frontend-ui-ux/references/design/sanity.md +360 -0
- package/.grok/skills/frontend-ui-ux/references/design/sentry.md +265 -0
- package/.grok/skills/frontend-ui-ux/references/design/shopify.md +353 -0
- package/.grok/skills/frontend-ui-ux/references/design/soft-skill.md +98 -0
- package/.grok/skills/frontend-ui-ux/references/design/spacex.md +197 -0
- package/.grok/skills/frontend-ui-ux/references/design/spotify.md +249 -0
- package/.grok/skills/frontend-ui-ux/references/design/starbucks.md +583 -0
- package/.grok/skills/frontend-ui-ux/references/design/stitch-design-example.md +121 -0
- package/.grok/skills/frontend-ui-ux/references/design/stitch-skill.md +184 -0
- package/.grok/skills/frontend-ui-ux/references/design/stripe.md +325 -0
- package/.grok/skills/frontend-ui-ux/references/design/supabase.md +258 -0
- package/.grok/skills/frontend-ui-ux/references/design/superhuman.md +255 -0
- package/.grok/skills/frontend-ui-ux/references/design/taste-skill.md +1206 -0
- package/.grok/skills/frontend-ui-ux/references/design/tesla.md +289 -0
- package/.grok/skills/frontend-ui-ux/references/design/theverge.md +342 -0
- package/.grok/skills/frontend-ui-ux/references/design/together.ai.md +266 -0
- package/.grok/skills/frontend-ui-ux/references/design/uber.md +298 -0
- package/.grok/skills/frontend-ui-ux/references/design/vercel.md +313 -0
- package/.grok/skills/frontend-ui-ux/references/design/vodafone.md +426 -0
- package/.grok/skills/frontend-ui-ux/references/design/voltagent.md +326 -0
- package/.grok/skills/frontend-ui-ux/references/design/warp.md +256 -0
- package/.grok/skills/frontend-ui-ux/references/design/webflow.md +95 -0
- package/.grok/skills/frontend-ui-ux/references/design/wired.md +281 -0
- package/.grok/skills/frontend-ui-ux/references/design/wise.md +176 -0
- package/.grok/skills/frontend-ui-ux/references/design/x.ai.md +260 -0
- package/.grok/skills/frontend-ui-ux/references/design/zapier.md +331 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/EVIDENCE.md +97 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/README.md +48 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/UPSTREAM.md +80 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/lane-a-direction.md +64 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/lane-b-execution.md +65 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/lane-c-review.md +65 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/lane-d-memory.md +83 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/orchestration.md +80 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/routing.md +79 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/LICENSE +21 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/agents/accessibility-reviewer.md +83 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/agents/content-writer.md +132 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/agents/design-builder.md +109 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/agents/design-critic.md +89 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/agents/design-lead.md +113 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/agents/design-scout.md +78 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/agents/design-strategist.md +121 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/agents/heuristic-evaluator.md +268 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/agents/inspiration-scout.md +107 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/agents/motion-designer.md +120 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/skills/accessible-content/reference.md +101 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/skills/adaptive-interfaces/reference.md +109 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/skills/cognitive-accessibility/reference.md +107 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/skills/design-debate/reference.md +199 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/skills/design-debt-tracker/reference.md +174 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/skills/design-handoff/reference.md +125 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/skills/design-md/reference.md +106 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/skills/design-retrospective/reference.md +266 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/skills/design-review/reference.md +123 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/skills/design-system-alignment/reference.md +120 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/skills/designpowers-critique/reference.md +164 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/skills/heuristic-evaluation/reference.md +85 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/skills/inclusive-personas/reference.md +98 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/skills/inspiration-scouting/reference.md +165 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/skills/interaction-design/reference.md +122 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/skills/motion-choreography/reference.md +81 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/skills/research-planning/reference.md +96 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/skills/responsive-patterns/reference.md +77 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/skills/synthetic-user-testing/reference.md +192 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/skills/taste-feedback/reference.md +165 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/skills/taste-report/reference.md +78 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/skills/token-architecture/reference.md +75 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/skills/ui-composition/reference.md +117 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/skills/usability-testing/reference.md +78 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/skills/verification-before-shipping/reference.md +125 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/skills/voice-and-tone/reference.md +79 -0
- package/.grok/skills/frontend-ui-ux/references/designpowers/vendor/skills/writing-design-plans/reference.md +119 -0
- package/.grok/skills/frontend-ui-ux/references/evidence-review.md +126 -0
- package/.grok/skills/frontend-ui-ux/references/implementation-platforms.md +109 -0
- package/.grok/skills/frontend-ui-ux/references/inclusive-interface.md +92 -0
- package/.grok/skills/frontend-ui-ux/references/interaction-motion.md +101 -0
- package/.grok/skills/frontend-ui-ux/references/operating-lanes.md +92 -0
- package/.grok/skills/frontend-ui-ux/references/perfection/README.md +160 -0
- package/.grok/skills/frontend-ui-ux/references/perfection/react-perf-tooling.md +127 -0
- package/.grok/skills/frontend-ui-ux/references/performance-delivery.md +93 -0
- package/.grok/skills/frontend-ui-ux/references/product-direction.md +84 -0
- package/.grok/skills/frontend-ui-ux/references/redesign-playbook.md +97 -0
- package/.grok/skills/frontend-ui-ux/references/system-foundations.md +84 -0
- package/.grok/skills/frontend-ui-ux/references/taste-direction.md +86 -0
- package/.grok/skills/frontend-ui-ux/references/ui-ux-db/README.md +659 -0
- package/.grok/skills/frontend-ui-ux/references/ui-ux-db/data/charts.csv +26 -0
- package/.grok/skills/frontend-ui-ux/references/ui-ux-db/data/colors.csv +162 -0
- package/.grok/skills/frontend-ui-ux/references/ui-ux-db/data/icons.csv +106 -0
- package/.grok/skills/frontend-ui-ux/references/ui-ux-db/data/landing.csv +35 -0
- package/.grok/skills/frontend-ui-ux/references/ui-ux-db/data/products.csv +162 -0
- package/.grok/skills/frontend-ui-ux/references/ui-ux-db/data/react-performance.csv +45 -0
- package/.grok/skills/frontend-ui-ux/references/ui-ux-db/data/stacks/astro.csv +54 -0
- package/.grok/skills/frontend-ui-ux/references/ui-ux-db/data/stacks/flutter.csv +53 -0
- package/.grok/skills/frontend-ui-ux/references/ui-ux-db/data/stacks/html-tailwind.csv +56 -0
- package/.grok/skills/frontend-ui-ux/references/ui-ux-db/data/stacks/jetpack-compose.csv +53 -0
- package/.grok/skills/frontend-ui-ux/references/ui-ux-db/data/stacks/nextjs.csv +53 -0
- package/.grok/skills/frontend-ui-ux/references/ui-ux-db/data/stacks/nuxt-ui.csv +51 -0
- package/.grok/skills/frontend-ui-ux/references/ui-ux-db/data/stacks/nuxtjs.csv +59 -0
- package/.grok/skills/frontend-ui-ux/references/ui-ux-db/data/stacks/react-native.csv +52 -0
- package/.grok/skills/frontend-ui-ux/references/ui-ux-db/data/stacks/react.csv +54 -0
- package/.grok/skills/frontend-ui-ux/references/ui-ux-db/data/stacks/shadcn.csv +61 -0
- package/.grok/skills/frontend-ui-ux/references/ui-ux-db/data/stacks/svelte.csv +54 -0
- package/.grok/skills/frontend-ui-ux/references/ui-ux-db/data/stacks/swiftui.csv +51 -0
- package/.grok/skills/frontend-ui-ux/references/ui-ux-db/data/stacks/vue.csv +50 -0
- package/.grok/skills/frontend-ui-ux/references/ui-ux-db/data/styles.csv +85 -0
- package/.grok/skills/frontend-ui-ux/references/ui-ux-db/data/typography.csv +74 -0
- package/.grok/skills/frontend-ui-ux/references/ui-ux-db/data/ui-reasoning.csv +162 -0
- package/.grok/skills/frontend-ui-ux/references/ui-ux-db/data/ux-guidelines.csv +100 -0
- package/.grok/skills/frontend-ui-ux/references/ui-ux-db/data/web-interface.csv +31 -0
- package/.grok/skills/frontend-ui-ux/references/ui-ux-db/scripts/core.py +262 -0
- package/.grok/skills/frontend-ui-ux/references/ui-ux-db/scripts/design_system.py +1148 -0
- package/.grok/skills/frontend-ui-ux/references/ui-ux-db/scripts/search.py +114 -0
- package/.grok/skills/frontend-ui-ux/references/visual-language.md +84 -0
- package/.grok/skills/frontend-ui-ux/references/visual-reconstruction.md +97 -0
- package/.grok/skills/frontend-ui-ux/schemas/design-contract-v1alpha1.schema.json +306 -0
- package/.grok/skills/frontend-ui-ux/schemas/design-contract-v1beta1.schema.json +291 -0
- package/.grok/skills/frontend-ui-ux/schemas/design-contract-v1beta2.schema.json +311 -0
- package/.grok/skills/frontend-ui-ux/scripts/design-contract-format.mjs +286 -0
- package/.grok/skills/frontend-ui-ux/scripts/design-contract-inventory-rules.mjs +354 -0
- package/.grok/skills/frontend-ui-ux/scripts/design-contract-rules.mjs +361 -0
- package/.grok/skills/frontend-ui-ux/scripts/design-contract-surface-rules.mjs +313 -0
- package/.grok/skills/frontend-ui-ux/scripts/design-data.mjs +68 -0
- package/.grok/skills/frontend-ui-ux/scripts/errors.mjs +12 -0
- package/.grok/skills/frontend-ui-ux/scripts/import-design-intelligence.mjs +124 -0
- package/.grok/skills/frontend-ui-ux/scripts/json-boundary.mjs +63 -0
- package/.grok/skills/frontend-ui-ux/scripts/query-design-intelligence.mjs +106 -0
- package/.grok/skills/frontend-ui-ux/scripts/search.mjs +43 -0
- package/.grok/skills/frontend-ui-ux/scripts/source-replay.mjs +153 -0
- package/.grok/skills/frontend-ui-ux/scripts/strict-json.mjs +143 -0
- package/.grok/skills/frontend-ui-ux/scripts/validate-design-contract.mjs +52 -0
- package/.grok/skills/frontend-ui-ux/scripts/verify-canonical-corpus.mjs +214 -0
- package/.grok/skills/lit-comprehend/SKILL.md +2 -0
- package/.grok/skills/lit-comprehend/references/artifact-template.md +219 -0
- package/.grok/skills/lit-comprehend/references/micro-worlds.md +195 -0
- package/.grok/skills/lit-handoff/SKILL.md +140 -40
- package/.grok/skills/lit-handoff/evals/evals.json +154 -0
- package/.grok/skills/lit-handoff/examples/HANDOFF-example-generic-auth-refactor.md +97 -0
- package/.grok/skills/lit-handoff/references/_canonical-corpus/manifest.json +17 -0
- package/.grok/skills/lit-handoff/references/source-pointer.md +31 -0
- package/.grok/skills/lit-handoff/scripts/verify-canonical-corpus.mjs +137 -0
- package/.grok/skills/lit-handoff/templates/HANDOFF.md +121 -0
- package/.grok/skills/lit-plan/SKILL.md +13 -2
- package/.grok/skills/lit-plan/scripts/scaffold-plan.mjs +259 -0
- package/.grok/skills/lit-scientific-visualization/SKILL.md +191 -227
- package/.grok/skills/lit-scientific-visualization/assets/color_palettes.py +197 -0
- package/.grok/skills/lit-scientific-visualization/assets/nature.mplstyle +75 -0
- package/.grok/skills/lit-scientific-visualization/assets/presentation.mplstyle +74 -0
- package/.grok/skills/lit-scientific-visualization/assets/publication.mplstyle +78 -0
- package/.grok/skills/lit-scientific-visualization/evals/evals.json +158 -0
- package/.grok/skills/lit-scientific-visualization/references/_canonical-corpus/manifest.json +28 -0
- package/.grok/skills/lit-scientific-visualization/references/color_palettes.md +380 -0
- package/.grok/skills/lit-scientific-visualization/references/journal_requirements.md +359 -0
- package/.grok/skills/lit-scientific-visualization/references/matplotlib_examples.md +608 -0
- package/.grok/skills/lit-scientific-visualization/references/mdanalysis_martini_visualization.md +85 -0
- package/.grok/skills/lit-scientific-visualization/references/publication_guidelines.md +217 -0
- package/.grok/skills/lit-scientific-visualization/references/seaborn_for_publications.md +293 -0
- package/.grok/skills/lit-scientific-visualization/scripts/figure_export.py +238 -0
- package/.grok/skills/lit-scientific-visualization/scripts/style_presets.py +467 -0
- package/.grok/skills/lit-scientific-visualization/scripts/verify-canonical-corpus.mjs +158 -0
- package/.grok/skills/lit-scientific-visualization/tests/test_figure_export.py +51 -0
- package/.grok/skills/lit-scientific-visualization/tests/test_style_presets.py +114 -0
- package/.grok/skills/litgoal/SKILL.md +58 -32
- package/.grok/skills/litwork/SKILL.md +45 -44
- package/.grok/skills/lsp-setup/SKILL.md +78 -0
- package/.grok/skills/lsp-setup/references/bash/README.md +54 -0
- package/.grok/skills/lsp-setup/references/c-cpp/README.md +58 -0
- package/.grok/skills/lsp-setup/references/csharp/README.md +64 -0
- package/.grok/skills/lsp-setup/references/dart/README.md +48 -0
- package/.grok/skills/lsp-setup/references/elixir/README.md +51 -0
- package/.grok/skills/lsp-setup/references/go/README.md +53 -0
- package/.grok/skills/lsp-setup/references/haskell/README.md +57 -0
- package/.grok/skills/lsp-setup/references/java/README.md +55 -0
- package/.grok/skills/lsp-setup/references/julia/README.md +56 -0
- package/.grok/skills/lsp-setup/references/kotlin/README.md +58 -0
- package/.grok/skills/lsp-setup/references/lua/README.md +48 -0
- package/.grok/skills/lsp-setup/references/php/README.md +49 -0
- package/.grok/skills/lsp-setup/references/python/README.md +60 -0
- package/.grok/skills/lsp-setup/references/ruby/README.md +53 -0
- package/.grok/skills/lsp-setup/references/rust/README.md +55 -0
- package/.grok/skills/lsp-setup/references/swift/README.md +52 -0
- package/.grok/skills/lsp-setup/references/terraform/README.md +50 -0
- package/.grok/skills/lsp-setup/references/typescript/README.md +63 -0
- package/.grok/skills/lsp-setup/references/yaml/README.md +47 -0
- package/.grok/skills/lsp-setup/references/zig/README.md +49 -0
- package/.grok/skills/lsp-setup/scripts/detect-lsp.mjs +40 -0
- package/.grok/skills/lsp-setup/scripts/lsp-server-table.mjs +309 -0
- package/.grok/skills/lsp-setup/scripts/verify-lsp.mjs +54 -0
- package/.grok/skills/programming/SKILL.md +483 -30
- package/.grok/skills/programming/references/go/README.md +90 -0
- package/.grok/skills/programming/references/go/backend-stack.md +641 -0
- package/.grok/skills/programming/references/go/bootstrap.md +328 -0
- package/.grok/skills/programming/references/go/bubbletea-v2.md +360 -0
- package/.grok/skills/programming/references/go/cobra-stack.md +468 -0
- package/.grok/skills/programming/references/go/concurrency.md +362 -0
- package/.grok/skills/programming/references/go/data-modeling.md +329 -0
- package/.grok/skills/programming/references/go/error-handling.md +359 -0
- package/.grok/skills/programming/references/go/golangci-strict.md +236 -0
- package/.grok/skills/programming/references/go/grpc-connect.md +375 -0
- package/.grok/skills/programming/references/go/libraries.md +337 -0
- package/.grok/skills/programming/references/go/one-liners.md +202 -0
- package/.grok/skills/programming/references/go/sqlc-pgx.md +471 -0
- package/.grok/skills/programming/references/go/testing.md +467 -0
- package/.grok/skills/programming/references/go/type-patterns.md +298 -0
- package/.grok/skills/programming/references/python/README.md +314 -0
- package/.grok/skills/programming/references/python/async-anyio.md +442 -0
- package/.grok/skills/programming/references/python/data-modeling.md +233 -0
- package/.grok/skills/programming/references/python/data-processing.md +133 -0
- package/.grok/skills/programming/references/python/error-handling.md +218 -0
- package/.grok/skills/programming/references/python/fastapi-stack.md +316 -0
- package/.grok/skills/programming/references/python/httpx2-optimization.md +360 -0
- package/.grok/skills/programming/references/python/libraries.md +307 -0
- package/.grok/skills/programming/references/python/one-liners.md +268 -0
- package/.grok/skills/programming/references/python/orjson-stack.md +378 -0
- package/.grok/skills/programming/references/python/pydantic-ai.md +285 -0
- package/.grok/skills/programming/references/python/pyproject-strict.md +232 -0
- package/.grok/skills/programming/references/python/textual-tui.md +201 -0
- package/.grok/skills/programming/references/python/type-patterns.md +176 -0
- package/.grok/skills/programming/references/rust/README.md +317 -0
- package/.grok/skills/programming/references/rust/async-tokio.md +299 -0
- package/.grok/skills/programming/references/rust/axum-stack.md +467 -0
- package/.grok/skills/programming/references/rust/cargo-strict.md +317 -0
- package/.grok/skills/programming/references/rust/clap-stack.md +409 -0
- package/.grok/skills/programming/references/rust/concurrency.md +375 -0
- package/.grok/skills/programming/references/rust/libraries.md +439 -0
- package/.grok/skills/programming/references/rust/one-liners.md +291 -0
- package/.grok/skills/programming/references/rust/proptest-insta.md +429 -0
- package/.grok/skills/programming/references/rust/type-state.md +354 -0
- package/.grok/skills/programming/references/rust/unsafe-discipline.md +250 -0
- package/.grok/skills/programming/references/rust/zero-cost-safety.md +527 -0
- package/.grok/skills/programming/references/rust-ub/README.md +289 -0
- package/.grok/skills/programming/references/rust-ub/miri-sanitizers-loom.md +411 -0
- package/.grok/skills/programming/references/rust-ub/ub-taxonomy.md +269 -0
- package/.grok/skills/programming/references/typescript/README.md +195 -0
- package/.grok/skills/programming/references/typescript/backend-hono.md +672 -0
- package/.grok/skills/programming/references/typescript/bootstrap.md +199 -0
- package/.grok/skills/programming/references/typescript/data-modeling.md +202 -0
- package/.grok/skills/programming/references/typescript/error-handling.md +169 -0
- package/.grok/skills/programming/references/typescript/tsconfig-strict.md +152 -0
- package/.grok/skills/programming/references/typescript/type-patterns.md +196 -0
- package/.grok/skills/review-work/SKILL.md +476 -18
- package/.grok/skills/skill-observer/SKILL.md +13 -0
- package/.grok/skills/skill-observer/references/review-contract.md +77 -0
- package/.grok/skills/skill-observer/scripts/curator.mjs +121 -0
- package/.grok/skills/skill-observer/scripts/review.mjs +347 -0
- package/.grok/skills/skill-observer/scripts/skill-loop.mjs +1979 -0
- package/.grok/skills/start-work/SKILL.md +348 -27
- package/.grok/skills/visual-qa/references/complete-contract.md +673 -10
- package/CHANGELOG.md +42 -0
- package/README.md +43 -6
- package/README_ko-KR.md +43 -6
- package/bin/litgrok.mjs +37 -1
- package/package.json +3 -1
- package/plugin.json +27 -0
- package/.grok/skills/frontend-ui-ux/references/design-contract-schema.md +0 -103
- package/.grok/skills/frontend-ui-ux/references/token-layout-tables.md +0 -41
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
export class StrictJsonError extends Error {
|
|
2
|
+
constructor(code, message, details = {}) {
|
|
3
|
+
super(message);
|
|
4
|
+
this.name = "StrictJsonError";
|
|
5
|
+
this.code = code;
|
|
6
|
+
this.details = details;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const RESERVED_KEYS = new Set(["__proto__", "constructor", "prototype"]);
|
|
11
|
+
|
|
12
|
+
function fail(code, message, offset) {
|
|
13
|
+
throw new StrictJsonError(code, `${message} at byte ${offset}`, { offset });
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function decodeStrictUtf8(bytes) {
|
|
17
|
+
try {
|
|
18
|
+
const text = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
19
|
+
if (text.charCodeAt(0) === 0xfeff) fail("JSON_INVALID_UTF8", "UTF-8 BOM is not permitted", 0);
|
|
20
|
+
if (text.includes("\0")) fail("JSON_INVALID_UTF8", "NUL is not permitted", text.indexOf("\0"));
|
|
21
|
+
return text;
|
|
22
|
+
} catch (error) {
|
|
23
|
+
if (error instanceof StrictJsonError) throw error;
|
|
24
|
+
throw new StrictJsonError("JSON_INVALID_UTF8", "input is not valid UTF-8");
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function parseStrictJson(text) {
|
|
29
|
+
let index = 0;
|
|
30
|
+
const whitespace = () => {
|
|
31
|
+
while (index < text.length && /[\u0009\u000a\u000d\u0020]/u.test(text[index])) index += 1;
|
|
32
|
+
};
|
|
33
|
+
const string = () => {
|
|
34
|
+
const start = index;
|
|
35
|
+
if (text[index++] !== "\"") fail("JSON_SYNTAX_INVALID", "expected string", index);
|
|
36
|
+
while (index < text.length) {
|
|
37
|
+
const character = text[index++];
|
|
38
|
+
if (character === "\"") {
|
|
39
|
+
try {
|
|
40
|
+
return JSON.parse(text.slice(start, index));
|
|
41
|
+
} catch {
|
|
42
|
+
fail("JSON_SYNTAX_INVALID", "invalid string escape", start);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (character < "\u0020") fail("JSON_SYNTAX_INVALID", "control character in string", index - 1);
|
|
46
|
+
if (character === "\\") {
|
|
47
|
+
const escape = text[index++];
|
|
48
|
+
if (escape === "u") {
|
|
49
|
+
const hex = text.slice(index, index + 4);
|
|
50
|
+
if (!/^[0-9a-f]{4}$/iu.test(hex)) fail("JSON_SYNTAX_INVALID", "invalid unicode escape", index);
|
|
51
|
+
index += 4;
|
|
52
|
+
} else if (!"\"\\/bfnrt".includes(escape ?? "")) {
|
|
53
|
+
fail("JSON_SYNTAX_INVALID", "invalid string escape", index - 1);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
fail("JSON_SYNTAX_INVALID", "unterminated string", start);
|
|
58
|
+
};
|
|
59
|
+
const number = () => {
|
|
60
|
+
const match = text.slice(index).match(/^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?/u);
|
|
61
|
+
if (!match) fail("JSON_SYNTAX_INVALID", "invalid number", index);
|
|
62
|
+
index += match[0].length;
|
|
63
|
+
const value = Number(match[0]);
|
|
64
|
+
if (!Number.isFinite(value)) fail("JSON_SYNTAX_INVALID", "non-finite number", index);
|
|
65
|
+
return value;
|
|
66
|
+
};
|
|
67
|
+
const value = () => {
|
|
68
|
+
whitespace();
|
|
69
|
+
if (text[index] === "\"") return string();
|
|
70
|
+
if (text[index] === "{") return object();
|
|
71
|
+
if (text[index] === "[") return array();
|
|
72
|
+
for (const [literal, parsed] of [["true", true], ["false", false], ["null", null]]) {
|
|
73
|
+
if (text.startsWith(literal, index)) {
|
|
74
|
+
index += literal.length;
|
|
75
|
+
return parsed;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return number();
|
|
79
|
+
};
|
|
80
|
+
const array = () => {
|
|
81
|
+
index += 1;
|
|
82
|
+
const result = [];
|
|
83
|
+
whitespace();
|
|
84
|
+
if (text[index] === "]") {
|
|
85
|
+
index += 1;
|
|
86
|
+
return result;
|
|
87
|
+
}
|
|
88
|
+
while (index < text.length) {
|
|
89
|
+
result.push(value());
|
|
90
|
+
whitespace();
|
|
91
|
+
if (text[index] === "]") {
|
|
92
|
+
index += 1;
|
|
93
|
+
return result;
|
|
94
|
+
}
|
|
95
|
+
if (text[index++] !== ",") fail("JSON_SYNTAX_INVALID", "expected comma", index - 1);
|
|
96
|
+
whitespace();
|
|
97
|
+
}
|
|
98
|
+
fail("JSON_SYNTAX_INVALID", "unterminated array", index);
|
|
99
|
+
};
|
|
100
|
+
const object = () => {
|
|
101
|
+
index += 1;
|
|
102
|
+
const result = {};
|
|
103
|
+
const keys = new Set();
|
|
104
|
+
whitespace();
|
|
105
|
+
if (text[index] === "}") {
|
|
106
|
+
index += 1;
|
|
107
|
+
return result;
|
|
108
|
+
}
|
|
109
|
+
while (index < text.length) {
|
|
110
|
+
whitespace();
|
|
111
|
+
const keyOffset = index;
|
|
112
|
+
const key = string();
|
|
113
|
+
if (RESERVED_KEYS.has(key)) {
|
|
114
|
+
fail("JSON_RESERVED_KEY", `reserved object key ${JSON.stringify(key)}`, keyOffset);
|
|
115
|
+
}
|
|
116
|
+
if (keys.has(key)) fail("JSON_DUPLICATE_KEY", `duplicate object key ${JSON.stringify(key)}`, keyOffset);
|
|
117
|
+
keys.add(key);
|
|
118
|
+
whitespace();
|
|
119
|
+
if (text[index++] !== ":") fail("JSON_SYNTAX_INVALID", "expected colon", index - 1);
|
|
120
|
+
result[key] = value();
|
|
121
|
+
whitespace();
|
|
122
|
+
if (text[index] === "}") {
|
|
123
|
+
index += 1;
|
|
124
|
+
return result;
|
|
125
|
+
}
|
|
126
|
+
if (text[index++] !== ",") fail("JSON_SYNTAX_INVALID", "expected comma", index - 1);
|
|
127
|
+
}
|
|
128
|
+
fail("JSON_SYNTAX_INVALID", "unterminated object", index);
|
|
129
|
+
};
|
|
130
|
+
const parsed = value();
|
|
131
|
+
whitespace();
|
|
132
|
+
if (index !== text.length) fail("JSON_SYNTAX_INVALID", "unexpected trailing data", index);
|
|
133
|
+
return parsed;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function stableJson(value) {
|
|
137
|
+
if (Array.isArray(value)) return `[${value.map(stableJson).join(",")}]`;
|
|
138
|
+
if (value && typeof value === "object") {
|
|
139
|
+
return `{${Object.keys(value).sort().map((key) =>
|
|
140
|
+
`${JSON.stringify(key)}:${stableJson(value[key])}`).join(",")}}`;
|
|
141
|
+
}
|
|
142
|
+
return JSON.stringify(value);
|
|
143
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Validate one litfamily.design-contract/v1alpha1 artifact.
|
|
3
|
+
//
|
|
4
|
+
// Exit-code contract:
|
|
5
|
+
// 0 the contract is valid. stdout carries exactly one line of JSON with the keys
|
|
6
|
+
// valid, schema, and issues (an empty array). stderr stays empty.
|
|
7
|
+
// 1 the bytes parsed but the contract is invalid. stdout carries the same one-line
|
|
8
|
+
// envelope with valid false and a populated issues array, so a caller can machine-read
|
|
9
|
+
// every defect from a single run.
|
|
10
|
+
// 2 the input could not be trusted at all: missing, non-regular, oversize, non-UTF-8,
|
|
11
|
+
// malformed JSON, or carrying duplicate object keys. A human-readable line goes to
|
|
12
|
+
// stderr and stdout stays empty, because there is nothing trustworthy to report.
|
|
13
|
+
//
|
|
14
|
+
// The code is always assigned to process.exitCode and never passed to process.exit(). An
|
|
15
|
+
// immediate exit can discard a buffered stdout write when stdout is a pipe, which would turn
|
|
16
|
+
// a populated exit-1 envelope into silence. Assigning the code lets Node flush and then exit.
|
|
17
|
+
import { realpathSync } from "node:fs";
|
|
18
|
+
import process from "node:process";
|
|
19
|
+
import { fileURLToPath } from "node:url";
|
|
20
|
+
|
|
21
|
+
import { errorMessage, UiuxContractError } from "./errors.mjs";
|
|
22
|
+
import { readDesignContract } from "./design-contract-format.mjs";
|
|
23
|
+
import { designContractReport } from "./design-contract-rules.mjs";
|
|
24
|
+
|
|
25
|
+
const USAGE = "usage: validate-design-contract <design-contract.json>";
|
|
26
|
+
|
|
27
|
+
export function validateDesignContract(path) {
|
|
28
|
+
const { value } = readDesignContract(path);
|
|
29
|
+
return designContractReport(value);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function main() {
|
|
33
|
+
const [path, ...extra] = process.argv.slice(2);
|
|
34
|
+
if (typeof path !== "string" || path.length === 0 || extra.length > 0) {
|
|
35
|
+
process.stderr.write(`INVALID_ARGUMENT: ${USAGE}\n`);
|
|
36
|
+
process.exitCode = 2;
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
let report;
|
|
40
|
+
try {
|
|
41
|
+
report = validateDesignContract(path);
|
|
42
|
+
} catch (error) {
|
|
43
|
+
const code = error instanceof UiuxContractError ? error.code : "DESIGN_CONTRACT_UNTRUSTED_INPUT";
|
|
44
|
+
process.stderr.write(`${code}: ${errorMessage(error)}\n`);
|
|
45
|
+
process.exitCode = 2;
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
process.stdout.write(`${JSON.stringify(report)}\n`);
|
|
49
|
+
process.exitCode = report.valid ? 0 : 1;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (process.argv[1] && fileURLToPath(import.meta.url) === realpathSync(process.argv[1])) main();
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { createHash } from 'node:crypto';
|
|
4
|
+
import { existsSync, lstatSync, readdirSync, readFileSync } from 'node:fs';
|
|
5
|
+
import { dirname, join, relative, resolve } from 'node:path';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
|
|
8
|
+
const SKILL_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
|
9
|
+
const CORPUS_ROOTS = Object.freeze(['design', 'designpowers', 'perfection', 'ui-ux-db']);
|
|
10
|
+
const MANIFEST_RELATIVE = '_canonical-corpus/manifest.json';
|
|
11
|
+
const EXPECTED = Object.freeze({
|
|
12
|
+
schemaVersion: ['lit', 'claude'].join('') + '.canonical-frontend-corpus/v1',
|
|
13
|
+
source: Object.freeze({
|
|
14
|
+
commit: '8ec16c5129df7b9778959e8367657d0e79c2c3bb',
|
|
15
|
+
reference_tree: '9188410be0af35f2421ba300d91a0d7a7341caf0',
|
|
16
|
+
reference_subtree: 'frontend/references',
|
|
17
|
+
}),
|
|
18
|
+
fileCount: 167,
|
|
19
|
+
byteCount: 2_596_349,
|
|
20
|
+
aggregateSha256: 'f6959eeae02685102df9fbedafb2c437be4d51df8e102f9fcf32298f7674e7d7',
|
|
21
|
+
legalTreeSha256: '2b7174f0662a5e41259b922fd1d94c24670df66894c7b9f81c9595ebd35fbc52',
|
|
22
|
+
datasetBytes: 1_023_482,
|
|
23
|
+
datasetSha256: 'a89011236a6ff14e12ec55fccbfab1bbd40ae34614cea5710c022121aa841bb8',
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
function digest(value) {
|
|
27
|
+
return createHash('sha256').update(value).digest('hex');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function expectedKeys(value, keys, label, failures) {
|
|
31
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
32
|
+
failures.push(`${label} is not an object`);
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
const actual = Object.keys(value).sort();
|
|
36
|
+
const expected = [...keys].sort();
|
|
37
|
+
if (JSON.stringify(actual) !== JSON.stringify(expected)) {
|
|
38
|
+
failures.push(`${label} keys mismatch`);
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function safeRelativePath(value) {
|
|
45
|
+
return typeof value === 'string'
|
|
46
|
+
&& value.length > 0
|
|
47
|
+
&& !value.startsWith('/')
|
|
48
|
+
&& !value.includes('\\')
|
|
49
|
+
&& value.split('/').every((part) => part !== '' && part !== '.' && part !== '..');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function listFiles(directory, prefix = '') {
|
|
53
|
+
const files = [];
|
|
54
|
+
for (const entry of readdirSync(directory, { withFileTypes: true })) {
|
|
55
|
+
const child = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
56
|
+
const childPath = join(directory, entry.name);
|
|
57
|
+
if (entry.isDirectory()) files.push(...listFiles(childPath, child));
|
|
58
|
+
else if (entry.isFile()) files.push(child);
|
|
59
|
+
else throw new Error(`non-regular entry: ${child}`);
|
|
60
|
+
}
|
|
61
|
+
return files;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function readBytes(referencesRoot, relativePath) {
|
|
65
|
+
return readFileSync(join(referencesRoot, ...relativePath.split('/')));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function parseRoot(argv) {
|
|
69
|
+
if (argv.length === 0) return SKILL_ROOT;
|
|
70
|
+
if (argv.length === 2 && argv[0] === '--root' && argv[1] && !argv[1].startsWith('-')) return resolve(argv[1]);
|
|
71
|
+
throw new Error('usage: verify-canonical-corpus.mjs [--root <skill-directory>]');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function verify(skillRoot) {
|
|
75
|
+
const failures = [];
|
|
76
|
+
const referencesRoot = join(skillRoot, 'references');
|
|
77
|
+
const manifestPath = join(referencesRoot, ...MANIFEST_RELATIVE.split('/'));
|
|
78
|
+
if (!existsSync(manifestPath)) return ['missing _canonical-corpus/manifest.json'];
|
|
79
|
+
|
|
80
|
+
let manifest;
|
|
81
|
+
try {
|
|
82
|
+
manifest = JSON.parse(readFileSync(manifestPath, 'utf8'));
|
|
83
|
+
} catch (error) {
|
|
84
|
+
return [`manifest unreadable: ${error instanceof Error ? error.message : String(error)}`];
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (expectedKeys(manifest, [
|
|
88
|
+
'aggregate_sha256',
|
|
89
|
+
'byte_count',
|
|
90
|
+
'file_count',
|
|
91
|
+
'files',
|
|
92
|
+
'independent_normalized_dataset',
|
|
93
|
+
'legal',
|
|
94
|
+
'schema_version',
|
|
95
|
+
'source',
|
|
96
|
+
], 'manifest', failures)) {
|
|
97
|
+
if (manifest.schema_version !== EXPECTED.schemaVersion) failures.push('schema_version mismatch');
|
|
98
|
+
if (JSON.stringify(manifest.source) !== JSON.stringify(EXPECTED.source)) failures.push('source metadata mismatch');
|
|
99
|
+
if (manifest.file_count !== EXPECTED.fileCount) failures.push(`file_count expected ${EXPECTED.fileCount}, got ${manifest.file_count}`);
|
|
100
|
+
if (manifest.byte_count !== EXPECTED.byteCount) failures.push(`byte_count expected ${EXPECTED.byteCount}, got ${manifest.byte_count}`);
|
|
101
|
+
if (manifest.aggregate_sha256 !== EXPECTED.aggregateSha256) failures.push('aggregate_sha256 metadata mismatch');
|
|
102
|
+
}
|
|
103
|
+
const filesAreValid = Array.isArray(manifest.files);
|
|
104
|
+
const legalIsValid = Array.isArray(manifest.legal);
|
|
105
|
+
if (!filesAreValid) failures.push('manifest.files is not an array');
|
|
106
|
+
if (!legalIsValid) failures.push('manifest.legal is not an array');
|
|
107
|
+
if (filesAreValid && manifest.files.length !== EXPECTED.fileCount) failures.push(`manifest.files length expected ${EXPECTED.fileCount}, got ${manifest.files.length}`);
|
|
108
|
+
if (legalIsValid && manifest.legal.length !== 3) failures.push(`manifest.legal length expected 3, got ${manifest.legal.length}`);
|
|
109
|
+
|
|
110
|
+
if (expectedKeys(manifest.independent_normalized_dataset, ['record_count', 'sha256', 'source_count'], 'dataset metadata', failures)) {
|
|
111
|
+
if (manifest.independent_normalized_dataset.source_count !== 34) failures.push('dataset source_count mismatch');
|
|
112
|
+
if (manifest.independent_normalized_dataset.record_count !== 2277) failures.push('dataset record_count mismatch');
|
|
113
|
+
if (manifest.independent_normalized_dataset.sha256 !== EXPECTED.datasetSha256) failures.push('dataset sha256 metadata mismatch');
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const entries = [];
|
|
117
|
+
const paths = new Set();
|
|
118
|
+
for (const [index, entry] of (filesAreValid ? manifest.files : []).entries()) {
|
|
119
|
+
if (!expectedKeys(entry, ['path', 'sha256', 'size'], `files[${index}]`, failures)) continue;
|
|
120
|
+
if (!safeRelativePath(entry.path) || !CORPUS_ROOTS.some((root) => entry.path.startsWith(`${root}/`))) {
|
|
121
|
+
failures.push(`files[${index}] path is outside the canonical roots: ${entry.path}`);
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
if (paths.has(entry.path)) failures.push(`duplicate manifest path: ${entry.path}`);
|
|
125
|
+
paths.add(entry.path);
|
|
126
|
+
entries.push({ kind: 'corpus', ...entry });
|
|
127
|
+
}
|
|
128
|
+
for (const [index, entry] of (legalIsValid ? manifest.legal : []).entries()) {
|
|
129
|
+
if (!expectedKeys(entry, ['path', 'sha256', 'size', 'source_path'], `legal[${index}]`, failures)) continue;
|
|
130
|
+
if (!safeRelativePath(entry.path) || !entry.path.startsWith('_canonical-corpus/legal/')) {
|
|
131
|
+
failures.push(`legal[${index}] path is outside the legal root: ${entry.path}`);
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
if (!safeRelativePath(entry.source_path)) failures.push(`legal[${index}] source_path is unsafe: ${entry.source_path}`);
|
|
135
|
+
if (paths.has(entry.path)) failures.push(`duplicate manifest path: ${entry.path}`);
|
|
136
|
+
paths.add(entry.path);
|
|
137
|
+
entries.push({ kind: 'legal', ...entry });
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const expectedCorpusPaths = entries.filter(({ kind }) => kind === 'corpus').map(({ path }) => path).sort();
|
|
141
|
+
const expectedLegalPaths = [MANIFEST_RELATIVE, ...entries.filter(({ kind }) => kind === 'legal').map(({ path }) => path)].sort();
|
|
142
|
+
try {
|
|
143
|
+
const actualCorpusPaths = CORPUS_ROOTS.flatMap((root) => listFiles(join(referencesRoot, root), '')
|
|
144
|
+
.map((path) => `${root}/${path}`)).sort();
|
|
145
|
+
if (JSON.stringify(actualCorpusPaths) !== JSON.stringify(expectedCorpusPaths)) failures.push('corpus file set mismatch');
|
|
146
|
+
} catch (error) {
|
|
147
|
+
failures.push(`corpus inventory failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
148
|
+
}
|
|
149
|
+
try {
|
|
150
|
+
const actualLegalPaths = listFiles(join(referencesRoot, '_canonical-corpus'), '_canonical-corpus').sort();
|
|
151
|
+
if (JSON.stringify(actualLegalPaths) !== JSON.stringify(expectedLegalPaths)) failures.push('legal file set mismatch');
|
|
152
|
+
} catch (error) {
|
|
153
|
+
failures.push(`legal inventory failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const actualHashes = new Map();
|
|
157
|
+
let corpusBytes = 0;
|
|
158
|
+
for (const entry of entries) {
|
|
159
|
+
let bytes;
|
|
160
|
+
try {
|
|
161
|
+
bytes = readBytes(referencesRoot, entry.path);
|
|
162
|
+
} catch (error) {
|
|
163
|
+
failures.push(`missing ${entry.path}: ${error instanceof Error ? error.message : String(error)}`);
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
const actualHash = digest(bytes);
|
|
167
|
+
actualHashes.set(entry.path, actualHash);
|
|
168
|
+
if (bytes.byteLength !== entry.size) failures.push(`size mismatch: ${entry.path}`);
|
|
169
|
+
if (actualHash !== entry.sha256) failures.push(`sha256 mismatch: ${entry.path}`);
|
|
170
|
+
if (entry.kind === 'corpus') corpusBytes += bytes.byteLength;
|
|
171
|
+
}
|
|
172
|
+
if (corpusBytes !== EXPECTED.byteCount) failures.push(`corpus byte count expected ${EXPECTED.byteCount}, got ${corpusBytes}`);
|
|
173
|
+
const aggregate = entries.filter(({ kind }) => kind === 'corpus').every(({ path }) => actualHashes.has(path))
|
|
174
|
+
? digest(entries.filter(({ kind }) => kind === 'corpus').map(({ path }) => `${actualHashes.get(path)} ${path}\n`).join(''))
|
|
175
|
+
: null;
|
|
176
|
+
if (aggregate !== EXPECTED.aggregateSha256) failures.push(`aggregate sha256 expected ${EXPECTED.aggregateSha256}, got ${aggregate}`);
|
|
177
|
+
|
|
178
|
+
if (legalIsValid) {
|
|
179
|
+
const legalRows = manifest.legal
|
|
180
|
+
.map(({ path, source_path: sourcePath, size, sha256: sha }) => ({ path, sourcePath, size, sha256: sha }))
|
|
181
|
+
.sort((left, right) => left.path < right.path ? -1 : left.path > right.path ? 1 : 0)
|
|
182
|
+
.map(({ path, sourcePath, size, sha256: sha }) => `${JSON.stringify([path, sourcePath, size, sha])}\n`)
|
|
183
|
+
.join('');
|
|
184
|
+
const legalTree = digest(legalRows);
|
|
185
|
+
if (legalTree !== EXPECTED.legalTreeSha256) failures.push(`legal tree sha256 expected ${EXPECTED.legalTreeSha256}, got ${legalTree}`);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const datasetPath = join(skillRoot, 'data', 'design-intelligence.json');
|
|
189
|
+
try {
|
|
190
|
+
const dataset = readFileSync(datasetPath);
|
|
191
|
+
if (dataset.byteLength !== EXPECTED.datasetBytes) failures.push(`dataset byte count expected ${EXPECTED.datasetBytes}, got ${dataset.byteLength}`);
|
|
192
|
+
if (digest(dataset) !== EXPECTED.datasetSha256) failures.push('dataset sha256 mismatch');
|
|
193
|
+
} catch (error) {
|
|
194
|
+
failures.push(`dataset unreadable: ${error instanceof Error ? error.message : String(error)}`);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return failures;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
let skillRoot;
|
|
201
|
+
try {
|
|
202
|
+
skillRoot = parseRoot(process.argv.slice(2));
|
|
203
|
+
if (!existsSync(skillRoot) || !lstatSync(skillRoot).isDirectory()) throw new Error(`skill root is not a directory: ${skillRoot}`);
|
|
204
|
+
const failures = verify(skillRoot);
|
|
205
|
+
if (failures.length > 0) {
|
|
206
|
+
console.error(`FAIL ${failures.join('; ')}`);
|
|
207
|
+
process.exitCode = 1;
|
|
208
|
+
} else {
|
|
209
|
+
console.log(`PASS canonical-frontend-corpus files=${EXPECTED.fileCount} bytes=${EXPECTED.byteCount} sha256=${EXPECTED.aggregateSha256}`);
|
|
210
|
+
}
|
|
211
|
+
} catch (error) {
|
|
212
|
+
console.error(`FAIL ${error instanceof Error ? error.message : String(error)}`);
|
|
213
|
+
process.exitCode = 1;
|
|
214
|
+
}
|
|
@@ -25,6 +25,8 @@ limitations_channel: designated_section
|
|
|
25
25
|
Load `references/artifact-format.md` when the explanation must be written outside the repository or survive beyond the current session.
|
|
26
26
|
Load `references/honesty-ledger-contract.md` when classifying claim strength, conflicts, stale evidence, or missing probes.
|
|
27
27
|
Load `references/worked-explainer.md` when the requested explanation resembles an install boundary, failure trace, configuration-scope conflict, or stale test receipt.
|
|
28
|
+
Load `references/artifact-template.md` when composing the portable explainer sections, diagrams, quiz markup, or Markdown fallback.
|
|
29
|
+
Load `references/micro-worlds.md` when the explanation benefits from a small faithful miniature, slider, step-through, or old/new interaction.
|
|
28
30
|
|
|
29
31
|
## Establish the question
|
|
30
32
|
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# Artifact template — sections, diagrams, quiz markup
|
|
2
|
+
|
|
3
|
+
Read this when composing the explainer. It pairs with
|
|
4
|
+
`assets/explainer-scaffold.html`, which already contains the CSS, the quiz
|
|
5
|
+
engine, and the diagram classes referenced below. Copy the scaffold, replace
|
|
6
|
+
`__TITLE__`, `__SUBTITLE__`, `__TOC__`, and `__CONTENT__`, and write only the
|
|
7
|
+
content — reinventing the boilerplate per invocation wastes tokens and produces
|
|
8
|
+
a different-looking artifact every time.
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
SKILL_DIR="$(dirname "$0")/.." # or the resolved skill path
|
|
12
|
+
OUTPUT_DIR="/path/approved-by-user"
|
|
13
|
+
OUT="$OUTPUT_DIR/$(date +%F)-<slug>.html"
|
|
14
|
+
mkdir -p "$OUTPUT_DIR"
|
|
15
|
+
cp "$SKILL_DIR/assets/explainer-scaffold.html" "$OUT"
|
|
16
|
+
# then edit $OUT, replacing the four placeholders
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The TOC is an `<ol>` of `<li><a href="#s1">한눈에</a></li>` entries; give each
|
|
20
|
+
`<h2>` a matching `id`.
|
|
21
|
+
|
|
22
|
+
## Section contract
|
|
23
|
+
|
|
24
|
+
Headers are byte-identical across every LitFamily harness. Keep the Korean
|
|
25
|
+
header text exactly as written even when the body is English.
|
|
26
|
+
|
|
27
|
+
### 1. 한눈에
|
|
28
|
+
|
|
29
|
+
One tight paragraph, then a confidence line. The reader should be able to stop
|
|
30
|
+
here and still be better off. Say what changed, why it was done, and what to
|
|
31
|
+
look at first. Then a `.note` callout stating how much of this is verified:
|
|
32
|
+
|
|
33
|
+
```html
|
|
34
|
+
<div class="note ok">
|
|
35
|
+
<span class="label">신뢰도</span>
|
|
36
|
+
<p>동작 확인: 테스트 3건 통과 · 실제 실행 1건. 코드만 읽고 추론한 부분: 2건 (아래 확인 안 된 것 참고).</p>
|
|
37
|
+
</div>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### 2. 이미 알고 있던 것
|
|
41
|
+
|
|
42
|
+
The delta anchor. Restate, in the reader's own terms, the objective they set and
|
|
43
|
+
the state the system was in when they last had a clear picture. Quote the
|
|
44
|
+
objective from `goals.json` verbatim — it is literally their sentence.
|
|
45
|
+
|
|
46
|
+
If the change required machinery the reader has genuinely not met, introduce it
|
|
47
|
+
here inside `.skippable`, so someone who already knows it can move past without
|
|
48
|
+
wondering what they missed:
|
|
49
|
+
|
|
50
|
+
```html
|
|
51
|
+
<div class="skippable">
|
|
52
|
+
<p><strong>배경 (이미 아는 내용이면 건너뛰세요)</strong> — …</p>
|
|
53
|
+
</div>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 3. 직관
|
|
57
|
+
|
|
58
|
+
One subsection per theme. Essence before mechanism: the problem, one concrete
|
|
59
|
+
piece of toy data moving through, and why the obvious alternative fails. Reuse
|
|
60
|
+
the same toy data across the whole document.
|
|
61
|
+
|
|
62
|
+
### 4. 바뀐 것
|
|
63
|
+
|
|
64
|
+
The literate walkthrough, in conceptual order. Prose leads; each excerpt lands
|
|
65
|
+
where the reader has just been given a reason to care.
|
|
66
|
+
|
|
67
|
+
Every code block carries `data-src` so the verifier can confirm the quote is
|
|
68
|
+
real. Add a line anchor when it helps the reader navigate:
|
|
69
|
+
|
|
70
|
+
```html
|
|
71
|
+
<pre data-src="src/ledger.mjs:88-104">export function appendEvent(event) {
|
|
72
|
+
const line = JSON.stringify(event) + '\n';
|
|
73
|
+
<span class="add">const tmp = LEDGER + '.tmp';
|
|
74
|
+
writeFileSync(tmp, readIfExists(LEDGER) + line);
|
|
75
|
+
renameSync(tmp, LEDGER);</span>
|
|
76
|
+
}</pre>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
`.add` and `.del` shade inserted and removed lines. The verifier skips `.del`
|
|
80
|
+
content when checking quotes against the current file, since deleted lines are
|
|
81
|
+
correctly absent.
|
|
82
|
+
|
|
83
|
+
### 5. 직접 만져보기
|
|
84
|
+
|
|
85
|
+
The micro-world. See `micro-worlds.md`. Omit the section for purely structural
|
|
86
|
+
changes rather than inventing a pointless widget.
|
|
87
|
+
|
|
88
|
+
### 6. 확인 안 된 것
|
|
89
|
+
|
|
90
|
+
The honesty ledger. Concrete lines, not hedging prose. Use `.note warn` or
|
|
91
|
+
`.note bad` for anything that could bite:
|
|
92
|
+
|
|
93
|
+
```html
|
|
94
|
+
<div class="note warn">
|
|
95
|
+
<span class="label">실행되지 않음</span>
|
|
96
|
+
<p><code>.grok/hooks/user-prompt-submit.mjs</code>의 새 분기는 작성되었지만
|
|
97
|
+
이번 세션에서 한 번도 실행되지 않았습니다. 라우트가 실제로 닿는지 확인 전.</p>
|
|
98
|
+
</div>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### 7. 증거
|
|
102
|
+
|
|
103
|
+
A table mapping claim to proof. Wrap it in `.scroll-x` so it never forces the
|
|
104
|
+
page to scroll sideways.
|
|
105
|
+
|
|
106
|
+
```html
|
|
107
|
+
<div class="scroll-x"><table>
|
|
108
|
+
<tr><th>주장</th><th>근거</th><th>확인 방법</th><th>결과</th></tr>
|
|
109
|
+
<tr>
|
|
110
|
+
<td>원장이 중간 크래시에도 손상되지 않음</td>
|
|
111
|
+
<td><code>test/ledger-atomic.test.mjs</code></td>
|
|
112
|
+
<td><code>npm test -- ledger-atomic</code></td>
|
|
113
|
+
<td>3 pass</td>
|
|
114
|
+
</tr>
|
|
115
|
+
</table></div>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
A row whose 결과 column would be "미확인" belongs in 확인 안 된 것 instead.
|
|
119
|
+
|
|
120
|
+
### 8. 퀴즈
|
|
121
|
+
|
|
122
|
+
Five questions (three for a small change). Open with one sentence framing it as
|
|
123
|
+
a throttle, not a grade, and include the score element the engine updates:
|
|
124
|
+
|
|
125
|
+
```html
|
|
126
|
+
<div class="quiz-q" data-answer="2">
|
|
127
|
+
<p class="q"><span class="n">1.</span> 원장 쓰기가 rename 기반으로 바뀐 뒤,
|
|
128
|
+
쓰기 도중 프로세스가 죽으면 <code>ledger.jsonl</code>은 어떤 상태인가?</p>
|
|
129
|
+
<button class="opt" data-i="0">마지막 줄이 잘린 채 남는다</button>
|
|
130
|
+
<button class="opt" data-i="1">빈 파일이 된다</button>
|
|
131
|
+
<button class="opt" data-i="2">직전 상태 그대로 남는다</button>
|
|
132
|
+
<button class="opt" data-i="3">tmp 파일과 함께 병합된다</button>
|
|
133
|
+
<div class="fb" data-i="0">이전 구현의 동작입니다. append 중 죽으면 부분 줄이 남았고, 그게 이 변경의 이유입니다.</div>
|
|
134
|
+
<div class="fb" data-i="1">쓰기는 tmp에서 일어나므로 원본은 비워지지 않습니다.</div>
|
|
135
|
+
<div class="fb" data-i="2">정답입니다. rename은 원자적이라 성공 아니면 무변경 둘 중 하나입니다.</div>
|
|
136
|
+
<div class="fb" data-i="3">병합 로직은 없습니다. tmp는 고아로 남고 원본은 그대로입니다.</div>
|
|
137
|
+
</div>
|
|
138
|
+
<p class="quiz-score" id="quiz-score">— 문항을 눌러 확인하세요.</p>
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Two tells to design out, both of which readers learn faster than the material:
|
|
142
|
+
|
|
143
|
+
- **위치** — vary the correct slot; never three in a row in the same position.
|
|
144
|
+
The verifier fails the artifact for this.
|
|
145
|
+
- **길이** — keep all options within a similar length. If the correct option is
|
|
146
|
+
the longest every time, that is the answer key. Detail belongs in the
|
|
147
|
+
feedback, which is where the reader is already looking.
|
|
148
|
+
|
|
149
|
+
Every option gets feedback, including the correct one, and each explains *why*.
|
|
150
|
+
A wrong click is the only moment in the document where you know exactly what the
|
|
151
|
+
reader misunderstood; spending a sentence there is worth more than a paragraph
|
|
152
|
+
anywhere else.
|
|
153
|
+
|
|
154
|
+
### 9. 다음
|
|
155
|
+
|
|
156
|
+
Three concrete entry points — a file to open, a question worth asking, a risk
|
|
157
|
+
worth closing. Not "consider adding tests"; name the test.
|
|
158
|
+
|
|
159
|
+
## Diagram families
|
|
160
|
+
|
|
161
|
+
Pick two or three and reuse them. A new visual language per section costs the
|
|
162
|
+
reader more than it teaches.
|
|
163
|
+
|
|
164
|
+
**Pipeline** — stages and data flow. Always show the example datum changing.
|
|
165
|
+
|
|
166
|
+
```html
|
|
167
|
+
<figure>
|
|
168
|
+
<div class="pipe">
|
|
169
|
+
<div class="box"><span class="t">입력</span><span class="d">{id:7}</span></div>
|
|
170
|
+
<span class="arrow">→</span>
|
|
171
|
+
<div class="box hi"><span class="t">정규화</span><span class="d">신규</span></div>
|
|
172
|
+
<span class="arrow">→</span>
|
|
173
|
+
<div class="box"><span class="t">원장</span><span class="d">1줄 추가</span></div>
|
|
174
|
+
</div>
|
|
175
|
+
<figcaption>이벤트 하나가 원장에 닿기까지. 강조된 단계가 이번에 추가됐습니다.</figcaption>
|
|
176
|
+
</figure>
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
**Before / after** — usually the right first diagram. Same structure twice, only
|
|
180
|
+
the changed element highlighted.
|
|
181
|
+
|
|
182
|
+
```html
|
|
183
|
+
<figure>
|
|
184
|
+
<div class="ba">
|
|
185
|
+
<div class="side"><h4>이전</h4>
|
|
186
|
+
<div class="pipe"><div class="box">append</div><span class="arrow">→</span><div class="box ghost">부분 줄</div></div>
|
|
187
|
+
</div>
|
|
188
|
+
<div class="side after"><h4>이후</h4>
|
|
189
|
+
<div class="pipe"><div class="box">tmp 쓰기</div><span class="arrow">→</span><div class="box hi">rename</div></div>
|
|
190
|
+
</div>
|
|
191
|
+
</div>
|
|
192
|
+
<figcaption>실패 지점이 "쓰는 중"에서 "이름 바꾸기 직전"으로 옮겨갔습니다.</figcaption>
|
|
193
|
+
</figure>
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
**State / timeline** — for anything ordering-sensitive: what is true after each
|
|
197
|
+
step. A table with a step column reads better than boxes here.
|
|
198
|
+
|
|
199
|
+
**Simplified UI** — a stripped rendering of what the user sees, for surface
|
|
200
|
+
changes. Two or three `.box` elements in a frame beat a screenshot you cannot
|
|
201
|
+
take.
|
|
202
|
+
|
|
203
|
+
Never ASCII art. It collapses on wrap, cannot carry color or emphasis, and the
|
|
204
|
+
verifier fails on box-drawing characters outside code blocks.
|
|
205
|
+
|
|
206
|
+
## Language
|
|
207
|
+
|
|
208
|
+
Korean prose by default; English on `--en` or an English request. Headers stay
|
|
209
|
+
Korean either way. Technical tokens — paths, commands, identifiers, versions,
|
|
210
|
+
error strings — stay verbatim in every mode. Never translate an error message;
|
|
211
|
+
the reader needs to be able to grep for it.
|
|
212
|
+
|
|
213
|
+
## Markdown fallback
|
|
214
|
+
|
|
215
|
+
`--md`, or any environment where HTML cannot be opened. Same nine headers as
|
|
216
|
+
`##` sections. Quizzes become `<details>` blocks with the answer and all
|
|
217
|
+
per-option feedback inside. Micro-worlds become a worked example that shows
|
|
218
|
+
every intermediate value, since the reader cannot poke it. Keep `data-src`
|
|
219
|
+
information as a path line above each fenced block so quotes stay traceable.
|