@litfamily/litopencode 1.0.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/.gitattributes +8 -0
- package/ATTRIBUTION.md +56 -0
- package/CHANGELOG.md +267 -0
- package/CODE_OF_CONDUCT.md +30 -0
- package/CONTRIBUTING.md +82 -0
- package/LICENSE +21 -0
- package/README-Ko-KR.md +252 -0
- package/README.md +252 -0
- package/SECURITY.md +36 -0
- package/SUPPORT.md +37 -0
- package/bin/litopencode +3 -0
- package/bin/litopencode.cjs +10 -0
- package/dist/activation-managed-prompts.d.ts +2 -0
- package/dist/activation-managed-prompts.js +51 -0
- package/dist/activation-primary-prompts.d.ts +2 -0
- package/dist/activation-primary-prompts.js +176 -0
- package/dist/activation-probe.d.ts +3 -0
- package/dist/activation-probe.js +19 -0
- package/dist/activation-prompt-utils.d.ts +6 -0
- package/dist/activation-prompt-utils.js +36 -0
- package/dist/activation-routing.d.ts +5 -0
- package/dist/activation-routing.js +340 -0
- package/dist/activation-workflow-prompts.d.ts +26 -0
- package/dist/activation-workflow-prompts.js +295 -0
- package/dist/activation.d.ts +24 -0
- package/dist/activation.js +152 -0
- package/dist/agents/defaults.d.ts +15 -0
- package/dist/agents/defaults.js +112 -0
- package/dist/agents/registry.d.ts +65 -0
- package/dist/agents/registry.js +319 -0
- package/dist/agents/specialists.d.ts +49 -0
- package/dist/agents/specialists.js +307 -0
- package/dist/agents/types.d.ts +55 -0
- package/dist/agents/types.js +4 -0
- package/dist/agents.d.ts +4 -0
- package/dist/agents.js +3 -0
- package/dist/benchmark.d.ts +94 -0
- package/dist/benchmark.js +172 -0
- package/dist/bounded-authority-hooks.d.ts +19 -0
- package/dist/bounded-authority-hooks.js +157 -0
- package/dist/bounded-authority.d.ts +184 -0
- package/dist/bounded-authority.js +825 -0
- package/dist/cache-metrics.d.ts +54 -0
- package/dist/cache-metrics.js +81 -0
- package/dist/cli/args.d.ts +5 -0
- package/dist/cli/args.js +415 -0
- package/dist/cli/auto-update.d.ts +117 -0
- package/dist/cli/auto-update.js +604 -0
- package/dist/cli/command-alias-ownership.d.ts +2 -0
- package/dist/cli/command-alias-ownership.js +14 -0
- package/dist/cli/command-aliases.d.ts +12 -0
- package/dist/cli/command-aliases.js +112 -0
- package/dist/cli/doctor.d.ts +2 -0
- package/dist/cli/doctor.js +175 -0
- package/dist/cli/host-capabilities.d.ts +12 -0
- package/dist/cli/host-capabilities.js +25 -0
- package/dist/cli/host-limits.d.ts +21 -0
- package/dist/cli/host-limits.js +83 -0
- package/dist/cli/install-config.d.ts +13 -0
- package/dist/cli/install-config.js +201 -0
- package/dist/cli/install-report.d.ts +2 -0
- package/dist/cli/install-report.js +180 -0
- package/dist/cli/install-tui.d.ts +12 -0
- package/dist/cli/install-tui.js +174 -0
- package/dist/cli/install.d.ts +2 -0
- package/dist/cli/install.js +264 -0
- package/dist/cli/json.d.ts +4 -0
- package/dist/cli/json.js +31 -0
- package/dist/cli/loop.d.ts +3 -0
- package/dist/cli/loop.js +135 -0
- package/dist/cli/lsp-capability.d.ts +17 -0
- package/dist/cli/lsp-capability.js +92 -0
- package/dist/cli/managed-skill-assets.d.ts +23 -0
- package/dist/cli/managed-skill-assets.js +117 -0
- package/dist/cli/model-catalog.d.ts +21 -0
- package/dist/cli/model-catalog.js +107 -0
- package/dist/cli/model-policy.d.ts +3 -0
- package/dist/cli/model-policy.js +143 -0
- package/dist/cli/model-routing.d.ts +5 -0
- package/dist/cli/model-routing.js +208 -0
- package/dist/cli/native-canonical-backup.d.ts +9 -0
- package/dist/cli/native-canonical-backup.js +96 -0
- package/dist/cli/native-canonical-cache.d.ts +9 -0
- package/dist/cli/native-canonical-cache.js +37 -0
- package/dist/cli/native-skill-install.d.ts +2 -0
- package/dist/cli/native-skill-install.js +128 -0
- package/dist/cli/native-skill-integrity.d.ts +25 -0
- package/dist/cli/native-skill-integrity.js +178 -0
- package/dist/cli/native-skill-tree.d.ts +12 -0
- package/dist/cli/native-skill-tree.js +104 -0
- package/dist/cli/native-skills.d.ts +22 -0
- package/dist/cli/native-skills.js +105 -0
- package/dist/cli/plugin-mutation.d.ts +4 -0
- package/dist/cli/plugin-mutation.js +89 -0
- package/dist/cli/scientific-visualization-dependencies.d.ts +18 -0
- package/dist/cli/scientific-visualization-dependencies.js +91 -0
- package/dist/cli/skill-loop.d.ts +3 -0
- package/dist/cli/skill-loop.js +649 -0
- package/dist/cli/types.d.ts +188 -0
- package/dist/cli/types.js +1 -0
- package/dist/cli/update-check.d.ts +2 -0
- package/dist/cli/update-check.js +15 -0
- package/dist/cli/update-notifier.d.ts +70 -0
- package/dist/cli/update-notifier.js +717 -0
- package/dist/cli/vendor-path-migration.d.ts +9 -0
- package/dist/cli/vendor-path-migration.js +96 -0
- package/dist/cli.d.ts +7 -0
- package/dist/cli.js +250 -0
- package/dist/commands.d.ts +331 -0
- package/dist/commands.js +600 -0
- package/dist/config-parser.d.ts +5 -0
- package/dist/config-parser.js +274 -0
- package/dist/config.d.ts +72 -0
- package/dist/config.js +157 -0
- package/dist/deliverable-hedge-guard.d.ts +26 -0
- package/dist/deliverable-hedge-guard.js +302 -0
- package/dist/durable-plan.d.ts +23 -0
- package/dist/durable-plan.js +349 -0
- package/dist/features.d.ts +828 -0
- package/dist/features.js +1109 -0
- package/dist/hooks.d.ts +17 -0
- package/dist/hooks.js +83 -0
- package/dist/ignition.d.ts +14 -0
- package/dist/ignition.js +33 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.js +30 -0
- package/dist/inert-data.d.ts +2 -0
- package/dist/inert-data.js +13 -0
- package/dist/knowledge.d.ts +98 -0
- package/dist/knowledge.js +961 -0
- package/dist/ledger.d.ts +181 -0
- package/dist/ledger.js +1179 -0
- package/dist/lit-fetch-classify.d.ts +8 -0
- package/dist/lit-fetch-classify.js +107 -0
- package/dist/lit-fetch-content.d.ts +2 -0
- package/dist/lit-fetch-content.js +43 -0
- package/dist/lit-fetch-http.d.ts +10 -0
- package/dist/lit-fetch-http.js +82 -0
- package/dist/lit-fetch-result.d.ts +2 -0
- package/dist/lit-fetch-result.js +65 -0
- package/dist/lit-fetch-ssrf.d.ts +9 -0
- package/dist/lit-fetch-ssrf.js +77 -0
- package/dist/lit-fetch-url.d.ts +3 -0
- package/dist/lit-fetch-url.js +28 -0
- package/dist/lit-fetch.d.ts +69 -0
- package/dist/lit-fetch.js +84 -0
- package/dist/lit-mark.d.ts +17 -0
- package/dist/lit-mark.js +129 -0
- package/dist/logger.d.ts +9 -0
- package/dist/logger.js +21 -0
- package/dist/model-route-policy.d.ts +25 -0
- package/dist/model-route-policy.js +129 -0
- package/dist/reader-facing-output.d.ts +3 -0
- package/dist/reader-facing-output.js +28 -0
- package/dist/rules/discovery.d.ts +36 -0
- package/dist/rules/discovery.js +270 -0
- package/dist/rules/engine.d.ts +43 -0
- package/dist/rules/engine.js +236 -0
- package/dist/rules/frontmatter.d.ts +16 -0
- package/dist/rules/frontmatter.js +179 -0
- package/dist/rules/glob.d.ts +12 -0
- package/dist/rules/glob.js +233 -0
- package/dist/rules/hooks.d.ts +25 -0
- package/dist/rules/hooks.js +75 -0
- package/dist/rules/output-style.d.ts +1 -0
- package/dist/rules/output-style.js +20 -0
- package/dist/scientific-visualization-banner.d.ts +1 -0
- package/dist/scientific-visualization-banner.js +2 -0
- package/dist/search-workflow-ideas.d.ts +67 -0
- package/dist/search-workflow-ideas.js +128 -0
- package/dist/secret-shapes.d.ts +9 -0
- package/dist/secret-shapes.js +63 -0
- package/dist/server.d.ts +6 -0
- package/dist/server.js +129 -0
- package/dist/session-lineage.d.ts +8 -0
- package/dist/session-lineage.js +12 -0
- package/dist/skill-loop/apply.d.ts +19 -0
- package/dist/skill-loop/apply.js +483 -0
- package/dist/skill-loop/config.d.ts +50 -0
- package/dist/skill-loop/config.js +215 -0
- package/dist/skill-loop/curator.d.ts +18 -0
- package/dist/skill-loop/curator.js +232 -0
- package/dist/skill-loop/ledger.d.ts +39 -0
- package/dist/skill-loop/ledger.js +344 -0
- package/dist/skill-loop/proposals.d.ts +48 -0
- package/dist/skill-loop/proposals.js +290 -0
- package/dist/skill-loop/storage.d.ts +72 -0
- package/dist/skill-loop/storage.js +817 -0
- package/dist/skill-loop/time.d.ts +2 -0
- package/dist/skill-loop/time.js +23 -0
- package/dist/skill-loop/transaction.d.ts +62 -0
- package/dist/skill-loop/transaction.js +836 -0
- package/dist/skill-loop/usage.d.ts +31 -0
- package/dist/skill-loop/usage.js +146 -0
- package/dist/skill-observer.d.ts +22 -0
- package/dist/skill-observer.js +1154 -0
- package/dist/skill-renames.d.ts +5 -0
- package/dist/skill-renames.js +8 -0
- package/dist/skills.d.ts +307 -0
- package/dist/skills.js +450 -0
- package/dist/stable-identity.d.ts +14 -0
- package/dist/stable-identity.js +15 -0
- package/dist/state.d.ts +25 -0
- package/dist/state.js +38 -0
- package/dist/strict-json.d.ts +2 -0
- package/dist/strict-json.js +94 -0
- package/dist/tool-guards.d.ts +34 -0
- package/dist/tool-guards.js +210 -0
- package/dist/tool-kit.d.ts +32 -0
- package/dist/tool-kit.js +75 -0
- package/dist/tools.d.ts +43 -0
- package/dist/tools.js +381 -0
- package/dist/uiux-visual-catalog.d.ts +50 -0
- package/dist/uiux-visual-catalog.js +103 -0
- package/dist/user-facing-markdown.d.ts +5 -0
- package/dist/user-facing-markdown.js +93 -0
- package/dist/workflow-families.d.ts +16 -0
- package/dist/workflow-families.js +95 -0
- package/docs/assets/cover.webp +0 -0
- package/docs/assets/litopencode-continuity-1600.webp +0 -0
- package/docs/assets/litopencode-ignition-1600.webp +0 -0
- package/docs/assets/readme/badge-license.svg +1 -0
- package/docs/assets/readme/badge-version.svg +1 -0
- package/docs/assets/readme/litopencode-clay-icon.png +0 -0
- package/docs/assets/readme/litopencode-wordmark.svg +5 -0
- package/docs/lit-mark.md +46 -0
- package/docs/migration.md +162 -0
- package/docs/privacy.md +82 -0
- package/docs/reference-Ko-KR.md +309 -0
- package/docs/reference.md +444 -0
- package/output-styles/asd-ste100-ko.md +41 -0
- package/output-styles/asd-ste100.md +40 -0
- package/output-styles/eli5-ko.md +13 -0
- package/output-styles/eli5.md +11 -0
- package/package.json +57 -0
- package/qa/fixtures/litfamily-harness-speed-v1.json +38 -0
- package/qa/harness-speed-contract.mjs +209 -0
- package/qa/harness-speed-v2-contract.mjs +213 -0
- package/qa/harness-speed-verdict.mjs +105 -0
- package/skills/agent-roster/SKILL.md +262 -0
- package/skills/autoconference/LICENSE +21 -0
- package/skills/autoconference/PROVENANCE.md +20 -0
- package/skills/autoconference/SKILL.md +125 -0
- package/skills/autoconference/assets/conference_template.md +76 -0
- package/skills/autoconference/assets/report_template.md +53 -0
- package/skills/autoconference/assets/synthesis_template.md +39 -0
- package/skills/autoconference/modes/analyze.md +255 -0
- package/skills/autoconference/modes/core.md +112 -0
- package/skills/autoconference/modes/debate.md +373 -0
- package/skills/autoconference/modes/plan.md +310 -0
- package/skills/autoconference/modes/resume.md +48 -0
- package/skills/autoconference/modes/ship.md +57 -0
- package/skills/autoconference/modes/survey.md +109 -0
- package/skills/autoconference/references/agent-prompts.md +134 -0
- package/skills/autoconference/references/conference-protocol.md +102 -0
- package/skills/autoconference/references/convergence-guide.md +167 -0
- package/skills/autoconference/references/core-principles.md +83 -0
- package/skills/autoconference/references/crash-recovery.md +104 -0
- package/skills/autoconference/references/results-logging.md +198 -0
- package/skills/autoconference/references/upstream-family-contract.md +130 -0
- package/skills/autoconference/references/visualization-guide.md +105 -0
- package/skills/autoconference/scripts/check_conference.sh +371 -0
- package/skills/autoconference/scripts/init_conference.py +625 -0
- package/skills/autoconference/scripts/style_presets.py +104 -0
- package/skills/autoresearch/LICENSE +21 -0
- package/skills/autoresearch/PROVENANCE.md +20 -0
- package/skills/autoresearch/SKILL.md +131 -0
- package/skills/autoresearch/assets/report_template.md +50 -0
- package/skills/autoresearch/assets/research_template.md +38 -0
- package/skills/autoresearch/assets/results_template.tsv +1 -0
- package/skills/autoresearch/modes/core.md +216 -0
- package/skills/autoresearch/modes/debug.md +235 -0
- package/skills/autoresearch/modes/fix.md +173 -0
- package/skills/autoresearch/modes/learn.md +91 -0
- package/skills/autoresearch/modes/plan.md +291 -0
- package/skills/autoresearch/modes/predict.md +266 -0
- package/skills/autoresearch/modes/reason.md +170 -0
- package/skills/autoresearch/modes/scenario.md +164 -0
- package/skills/autoresearch/modes/security.md +282 -0
- package/skills/autoresearch/modes/ship.md +49 -0
- package/skills/autoresearch/references/core-principles.md +80 -0
- package/skills/autoresearch/references/evaluator-contract.md +126 -0
- package/skills/autoresearch/references/investigation-techniques.md +205 -0
- package/skills/autoresearch/references/owasp-checklist.md +161 -0
- package/skills/autoresearch/references/persona-templates.md +232 -0
- package/skills/autoresearch/references/results-logging.md +96 -0
- package/skills/autoresearch/references/scenario-dimensions.md +178 -0
- package/skills/autoresearch/references/stride-model.md +196 -0
- package/skills/autoresearch/references/stuck-detection.md +107 -0
- package/skills/autoresearch/references/type-checklists.md +163 -0
- package/skills/autoresearch/references/upstream-family-contract.md +125 -0
- package/skills/autoresearch/references/visualization-guide.md +95 -0
- package/skills/autoresearch/scripts/check_progress.sh +272 -0
- package/skills/autoresearch/scripts/init_research.py +330 -0
- package/skills/autoresearch/scripts/run_with_deadline.py +164 -0
- package/skills/autoresearch/scripts/style_presets.py +104 -0
- package/skills/browser-drive/SKILL.md +133 -0
- package/skills/browser-drive/references/snapshot-act-loop.md +37 -0
- package/skills/browser-drive/scripts/capability-probe.mjs +262 -0
- package/skills/comment-checker/SKILL.md +171 -0
- package/skills/debugging/SKILL.md +202 -0
- package/skills/debugging/references/README.md +15 -0
- package/skills/debugging/references/escalation.md +43 -0
- package/skills/debugging/references/runtimes/README.md +17 -0
- package/skills/debugging/references/runtimes/bundled-js-binary.md +44 -0
- package/skills/debugging/references/runtimes/go.md +37 -0
- package/skills/debugging/references/runtimes/native-binary.md +44 -0
- package/skills/debugging/references/runtimes/node.md +43 -0
- package/skills/debugging/references/runtimes/python.md +41 -0
- package/skills/debugging/references/runtimes/rust.md +37 -0
- package/skills/debugging/references/tools.md +72 -0
- package/skills/deep-interview/SKILL.md +201 -0
- package/skills/doctor-installer/SKILL.md +252 -0
- package/skills/durable-litgoal/SKILL.md +248 -0
- package/skills/frontend-ui-ux/SKILL.md +70 -0
- package/skills/frontend-ui-ux/data/LICENSE +21 -0
- package/skills/frontend-ui-ux/data/PROVENANCE.json +1088 -0
- package/skills/frontend-ui-ux/data/THIRD-PARTY-NOTICE.txt +14 -0
- package/skills/frontend-ui-ux/data/design-intelligence.json +1 -0
- package/skills/frontend-ui-ux/references/_canonical-corpus/ATTRIBUTION.md +217 -0
- package/skills/frontend-ui-ux/references/_canonical-corpus/LICENSE +21 -0
- package/skills/frontend-ui-ux/references/_canonical-corpus/LICENSE-Apache-2.0.txt +201 -0
- package/skills/frontend-ui-ux/references/_canonical-corpus/manifest.json +867 -0
- package/skills/frontend-ui-ux/references/adaptive-layout.md +85 -0
- package/skills/frontend-ui-ux/references/brand-and-imagery.md +79 -0
- package/skills/frontend-ui-ux/references/complete-contract.md +282 -0
- package/skills/frontend-ui-ux/references/composition.md +87 -0
- package/skills/frontend-ui-ux/references/creative-directions.md +83 -0
- package/skills/frontend-ui-ux/references/design/README.md +248 -0
- package/skills/frontend-ui-ux/references/design/_INDEX.md +191 -0
- package/skills/frontend-ui-ux/references/design/airbnb.md +393 -0
- package/skills/frontend-ui-ux/references/design/airtable.md +92 -0
- package/skills/frontend-ui-ux/references/design/apple.md +250 -0
- package/skills/frontend-ui-ux/references/design/aside.md +209 -0
- package/skills/frontend-ui-ux/references/design/binance.md +348 -0
- package/skills/frontend-ui-ux/references/design/bmw.md +183 -0
- package/skills/frontend-ui-ux/references/design/brutalist-skill.md +92 -0
- package/skills/frontend-ui-ux/references/design/bugatti.md +271 -0
- package/skills/frontend-ui-ux/references/design/cal.md +262 -0
- package/skills/frontend-ui-ux/references/design/claude.md +315 -0
- package/skills/frontend-ui-ux/references/design/clay.md +307 -0
- package/skills/frontend-ui-ux/references/design/clickhouse.md +284 -0
- package/skills/frontend-ui-ux/references/design/clone-from-url.md +65 -0
- package/skills/frontend-ui-ux/references/design/cohere.md +269 -0
- package/skills/frontend-ui-ux/references/design/coinbase.md +132 -0
- package/skills/frontend-ui-ux/references/design/composio.md +310 -0
- package/skills/frontend-ui-ux/references/design/cursor.md +312 -0
- package/skills/frontend-ui-ux/references/design/design-system-architecture.md +244 -0
- package/skills/frontend-ui-ux/references/design/elevenlabs.md +268 -0
- package/skills/frontend-ui-ux/references/design/expo.md +284 -0
- package/skills/frontend-ui-ux/references/design/ferrari.md +317 -0
- package/skills/frontend-ui-ux/references/design/figma.md +223 -0
- package/skills/frontend-ui-ux/references/design/framer.md +249 -0
- package/skills/frontend-ui-ux/references/design/gpt-tasteskill.md +74 -0
- package/skills/frontend-ui-ux/references/design/hashicorp.md +281 -0
- package/skills/frontend-ui-ux/references/design/ibm.md +335 -0
- package/skills/frontend-ui-ux/references/design/image-to-code-skill.md +1228 -0
- package/skills/frontend-ui-ux/references/design/imagegen-brandkit.md +798 -0
- package/skills/frontend-ui-ux/references/design/imagegen-frontend-mobile.md +1465 -0
- package/skills/frontend-ui-ux/references/design/imagegen-frontend-web.md +987 -0
- package/skills/frontend-ui-ux/references/design/intercom.md +149 -0
- package/skills/frontend-ui-ux/references/design/kraken.md +128 -0
- package/skills/frontend-ui-ux/references/design/lamborghini.md +291 -0
- package/skills/frontend-ui-ux/references/design/layout-skill.md +107 -0
- package/skills/frontend-ui-ux/references/design/lazyweb.md +77 -0
- package/skills/frontend-ui-ux/references/design/linear.app.md +370 -0
- package/skills/frontend-ui-ux/references/design/lovable.md +301 -0
- package/skills/frontend-ui-ux/references/design/mastercard.md +368 -0
- package/skills/frontend-ui-ux/references/design/meta.md +369 -0
- package/skills/frontend-ui-ux/references/design/minimalist-skill.md +85 -0
- package/skills/frontend-ui-ux/references/design/minimax.md +260 -0
- package/skills/frontend-ui-ux/references/design/mintlify.md +329 -0
- package/skills/frontend-ui-ux/references/design/miro.md +111 -0
- package/skills/frontend-ui-ux/references/design/mistral.ai.md +264 -0
- package/skills/frontend-ui-ux/references/design/mongodb.md +269 -0
- package/skills/frontend-ui-ux/references/design/nike.md +366 -0
- package/skills/frontend-ui-ux/references/design/notion.md +312 -0
- package/skills/frontend-ui-ux/references/design/nvidia.md +296 -0
- package/skills/frontend-ui-ux/references/design/ollama.md +270 -0
- package/skills/frontend-ui-ux/references/design/opencode.ai.md +284 -0
- package/skills/frontend-ui-ux/references/design/output-skill.md +49 -0
- package/skills/frontend-ui-ux/references/design/pinterest.md +233 -0
- package/skills/frontend-ui-ux/references/design/playstation.md +367 -0
- package/skills/frontend-ui-ux/references/design/posthog.md +259 -0
- package/skills/frontend-ui-ux/references/design/raycast.md +271 -0
- package/skills/frontend-ui-ux/references/design/react-dev-tooling-skill.md +230 -0
- package/skills/frontend-ui-ux/references/design/redesign-skill.md +178 -0
- package/skills/frontend-ui-ux/references/design/renault.md +314 -0
- package/skills/frontend-ui-ux/references/design/replicate.md +264 -0
- package/skills/frontend-ui-ux/references/design/resend.md +306 -0
- package/skills/frontend-ui-ux/references/design/revolut.md +188 -0
- package/skills/frontend-ui-ux/references/design/runwayml.md +247 -0
- package/skills/frontend-ui-ux/references/design/sanity.md +360 -0
- package/skills/frontend-ui-ux/references/design/sentry.md +265 -0
- package/skills/frontend-ui-ux/references/design/shopify.md +353 -0
- package/skills/frontend-ui-ux/references/design/soft-skill.md +98 -0
- package/skills/frontend-ui-ux/references/design/spacex.md +197 -0
- package/skills/frontend-ui-ux/references/design/spotify.md +249 -0
- package/skills/frontend-ui-ux/references/design/starbucks.md +583 -0
- package/skills/frontend-ui-ux/references/design/stitch-design-example.md +121 -0
- package/skills/frontend-ui-ux/references/design/stitch-skill.md +184 -0
- package/skills/frontend-ui-ux/references/design/stripe.md +325 -0
- package/skills/frontend-ui-ux/references/design/supabase.md +258 -0
- package/skills/frontend-ui-ux/references/design/superhuman.md +255 -0
- package/skills/frontend-ui-ux/references/design/taste-skill.md +1206 -0
- package/skills/frontend-ui-ux/references/design/tesla.md +289 -0
- package/skills/frontend-ui-ux/references/design/theverge.md +342 -0
- package/skills/frontend-ui-ux/references/design/together.ai.md +266 -0
- package/skills/frontend-ui-ux/references/design/uber.md +298 -0
- package/skills/frontend-ui-ux/references/design/vercel.md +313 -0
- package/skills/frontend-ui-ux/references/design/vodafone.md +426 -0
- package/skills/frontend-ui-ux/references/design/voltagent.md +326 -0
- package/skills/frontend-ui-ux/references/design/warp.md +256 -0
- package/skills/frontend-ui-ux/references/design/webflow.md +95 -0
- package/skills/frontend-ui-ux/references/design/wired.md +281 -0
- package/skills/frontend-ui-ux/references/design/wise.md +176 -0
- package/skills/frontend-ui-ux/references/design/x.ai.md +260 -0
- package/skills/frontend-ui-ux/references/design/zapier.md +331 -0
- package/skills/frontend-ui-ux/references/designpowers/EVIDENCE.md +97 -0
- package/skills/frontend-ui-ux/references/designpowers/README.md +48 -0
- package/skills/frontend-ui-ux/references/designpowers/UPSTREAM.md +80 -0
- package/skills/frontend-ui-ux/references/designpowers/lane-a-direction.md +64 -0
- package/skills/frontend-ui-ux/references/designpowers/lane-b-execution.md +65 -0
- package/skills/frontend-ui-ux/references/designpowers/lane-c-review.md +65 -0
- package/skills/frontend-ui-ux/references/designpowers/lane-d-memory.md +83 -0
- package/skills/frontend-ui-ux/references/designpowers/orchestration.md +80 -0
- package/skills/frontend-ui-ux/references/designpowers/routing.md +79 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/LICENSE +21 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/agents/accessibility-reviewer.md +83 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/agents/content-writer.md +132 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/agents/design-builder.md +109 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/agents/design-critic.md +89 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/agents/design-lead.md +113 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/agents/design-scout.md +78 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/agents/design-strategist.md +121 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/agents/heuristic-evaluator.md +268 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/agents/inspiration-scout.md +107 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/agents/motion-designer.md +120 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/skills/accessible-content/reference.md +101 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/skills/adaptive-interfaces/reference.md +109 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/skills/cognitive-accessibility/reference.md +107 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/skills/design-debate/reference.md +199 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/skills/design-debt-tracker/reference.md +174 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/skills/design-handoff/reference.md +125 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/skills/design-md/reference.md +106 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/skills/design-retrospective/reference.md +266 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/skills/design-review/reference.md +123 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/skills/design-system-alignment/reference.md +120 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/skills/designpowers-critique/reference.md +164 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/skills/heuristic-evaluation/reference.md +85 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/skills/inclusive-personas/reference.md +98 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/skills/inspiration-scouting/reference.md +165 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/skills/interaction-design/reference.md +122 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/skills/motion-choreography/reference.md +81 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/skills/research-planning/reference.md +96 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/skills/responsive-patterns/reference.md +77 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/skills/synthetic-user-testing/reference.md +192 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/skills/taste-feedback/reference.md +165 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/skills/taste-report/reference.md +78 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/skills/token-architecture/reference.md +75 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/skills/ui-composition/reference.md +117 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/skills/usability-testing/reference.md +78 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/skills/verification-before-shipping/reference.md +125 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/skills/voice-and-tone/reference.md +79 -0
- package/skills/frontend-ui-ux/references/designpowers/vendor/skills/writing-design-plans/reference.md +119 -0
- package/skills/frontend-ui-ux/references/evidence-review.md +103 -0
- package/skills/frontend-ui-ux/references/implementation-platforms.md +94 -0
- package/skills/frontend-ui-ux/references/inclusive-interface.md +85 -0
- package/skills/frontend-ui-ux/references/interaction-motion.md +93 -0
- package/skills/frontend-ui-ux/references/operating-lanes.md +80 -0
- package/skills/frontend-ui-ux/references/perfection/README.md +160 -0
- package/skills/frontend-ui-ux/references/perfection/react-perf-tooling.md +127 -0
- package/skills/frontend-ui-ux/references/performance-delivery.md +77 -0
- package/skills/frontend-ui-ux/references/product-direction.md +84 -0
- package/skills/frontend-ui-ux/references/redesign-playbook.md +88 -0
- package/skills/frontend-ui-ux/references/system-foundations.md +86 -0
- package/skills/frontend-ui-ux/references/taste-direction.md +55 -0
- package/skills/frontend-ui-ux/references/ui-ux-db/README.md +659 -0
- package/skills/frontend-ui-ux/references/ui-ux-db/data/charts.csv +26 -0
- package/skills/frontend-ui-ux/references/ui-ux-db/data/colors.csv +162 -0
- package/skills/frontend-ui-ux/references/ui-ux-db/data/icons.csv +106 -0
- package/skills/frontend-ui-ux/references/ui-ux-db/data/landing.csv +35 -0
- package/skills/frontend-ui-ux/references/ui-ux-db/data/products.csv +162 -0
- package/skills/frontend-ui-ux/references/ui-ux-db/data/react-performance.csv +45 -0
- package/skills/frontend-ui-ux/references/ui-ux-db/data/stacks/astro.csv +54 -0
- package/skills/frontend-ui-ux/references/ui-ux-db/data/stacks/flutter.csv +53 -0
- package/skills/frontend-ui-ux/references/ui-ux-db/data/stacks/html-tailwind.csv +56 -0
- package/skills/frontend-ui-ux/references/ui-ux-db/data/stacks/jetpack-compose.csv +53 -0
- package/skills/frontend-ui-ux/references/ui-ux-db/data/stacks/nextjs.csv +53 -0
- package/skills/frontend-ui-ux/references/ui-ux-db/data/stacks/nuxt-ui.csv +51 -0
- package/skills/frontend-ui-ux/references/ui-ux-db/data/stacks/nuxtjs.csv +59 -0
- package/skills/frontend-ui-ux/references/ui-ux-db/data/stacks/react-native.csv +52 -0
- package/skills/frontend-ui-ux/references/ui-ux-db/data/stacks/react.csv +54 -0
- package/skills/frontend-ui-ux/references/ui-ux-db/data/stacks/shadcn.csv +61 -0
- package/skills/frontend-ui-ux/references/ui-ux-db/data/stacks/svelte.csv +54 -0
- package/skills/frontend-ui-ux/references/ui-ux-db/data/stacks/swiftui.csv +51 -0
- package/skills/frontend-ui-ux/references/ui-ux-db/data/stacks/vue.csv +50 -0
- package/skills/frontend-ui-ux/references/ui-ux-db/data/styles.csv +85 -0
- package/skills/frontend-ui-ux/references/ui-ux-db/data/typography.csv +74 -0
- package/skills/frontend-ui-ux/references/ui-ux-db/data/ui-reasoning.csv +162 -0
- package/skills/frontend-ui-ux/references/ui-ux-db/data/ux-guidelines.csv +100 -0
- package/skills/frontend-ui-ux/references/ui-ux-db/data/web-interface.csv +31 -0
- package/skills/frontend-ui-ux/references/ui-ux-db/scripts/core.py +262 -0
- package/skills/frontend-ui-ux/references/ui-ux-db/scripts/design_system.py +1148 -0
- package/skills/frontend-ui-ux/references/ui-ux-db/scripts/search.py +114 -0
- package/skills/frontend-ui-ux/references/visual-language.md +84 -0
- package/skills/frontend-ui-ux/references/visual-reconstruction.md +87 -0
- package/skills/frontend-ui-ux/schemas/design-contract-v1alpha1.json +570 -0
- package/skills/frontend-ui-ux/schemas/design-contract-v1beta1.json +32 -0
- package/skills/frontend-ui-ux/schemas/design-contract-v1beta2.json +34 -0
- package/skills/frontend-ui-ux/scripts/bounded-json.mjs +45 -0
- package/skills/frontend-ui-ux/scripts/canonical-json.mjs +26 -0
- package/skills/frontend-ui-ux/scripts/contract-error.mjs +15 -0
- package/skills/frontend-ui-ux/scripts/csv.mjs +64 -0
- package/skills/frontend-ui-ux/scripts/dataset.mjs +65 -0
- package/skills/frontend-ui-ux/scripts/design-contract.mjs +609 -0
- package/skills/frontend-ui-ux/scripts/import-design-intelligence.mjs +193 -0
- package/skills/frontend-ui-ux/scripts/retrieval.mjs +92 -0
- package/skills/frontend-ui-ux/scripts/stable-file-read.mjs +237 -0
- package/skills/frontend-ui-ux/scripts/stdin-json.mjs +16 -0
- package/skills/frontend-ui-ux/scripts/strict-json.mjs +102 -0
- package/skills/frontend-ui-ux/scripts/uiux.mjs +86 -0
- package/skills/frontend-ui-ux/scripts/verify-canonical-corpus.mjs +266 -0
- package/skills/lit-burnoff/SKILL.md +227 -0
- package/skills/lit-burnoff-file/SKILL.md +175 -0
- package/skills/lit-code/SKILL.md +266 -0
- package/skills/lit-code/references/README.md +18 -0
- package/skills/lit-code/references/go/README.md +12 -0
- package/skills/lit-code/references/go/concurrency.md +42 -0
- package/skills/lit-code/references/go/error-handling.md +47 -0
- package/skills/lit-code/references/go/testing.md +55 -0
- package/skills/lit-code/references/go/tooling.md +35 -0
- package/skills/lit-code/references/go/type-patterns.md +50 -0
- package/skills/lit-code/references/python/README.md +12 -0
- package/skills/lit-code/references/python/async.md +50 -0
- package/skills/lit-code/references/python/error-handling.md +44 -0
- package/skills/lit-code/references/python/testing.md +50 -0
- package/skills/lit-code/references/python/tooling.md +38 -0
- package/skills/lit-code/references/python/type-patterns.md +46 -0
- package/skills/lit-code/references/rust/README.md +12 -0
- package/skills/lit-code/references/rust/concurrency.md +45 -0
- package/skills/lit-code/references/rust/error-handling.md +43 -0
- package/skills/lit-code/references/rust/tooling.md +36 -0
- package/skills/lit-code/references/rust/type-patterns.md +46 -0
- package/skills/lit-code/references/rust/unsafe.md +47 -0
- package/skills/lit-code/references/typescript/README.md +11 -0
- package/skills/lit-code/references/typescript/error-handling.md +56 -0
- package/skills/lit-code/references/typescript/testing.md +42 -0
- package/skills/lit-code/references/typescript/tsconfig-strict.md +40 -0
- package/skills/lit-code/references/typescript/type-patterns.md +60 -0
- package/skills/lit-commit/SKILL.md +222 -0
- package/skills/lit-comprehend/SKILL.md +278 -0
- package/skills/lit-comprehend/assets/explainer-scaffold.html +104 -0
- package/skills/lit-comprehend/references/artifact-template.md +114 -0
- package/skills/lit-comprehend/references/micro-worlds.md +115 -0
- package/skills/lit-comprehend/scripts/verify-explainer.ts +339 -0
- package/skills/lit-crucible/SKILL.md +212 -0
- package/skills/lit-fetch/SKILL.md +242 -0
- package/skills/lit-handoff/SKILL.md +199 -0
- package/skills/lit-init/SKILL.md +214 -0
- package/skills/lit-korean/SKILL.md +231 -0
- package/skills/lit-plan/SKILL.md +351 -0
- package/skills/lit-plan/scripts/scaffold-plan.mjs +275 -0
- package/skills/lit-recap/SKILL.md +233 -0
- package/skills/lit-scientific-visualization/SKILL.md +175 -0
- package/skills/litresearch/SKILL.md +436 -0
- package/skills/litwork/SKILL.md +227 -0
- package/skills/lsp/SKILL.md +186 -0
- package/skills/lsp-setup/SKILL.md +187 -0
- package/skills/lsp-setup/references/README.md +40 -0
- package/skills/lsp-setup/references/bash.md +31 -0
- package/skills/lsp-setup/references/c-cpp.md +43 -0
- package/skills/lsp-setup/references/csharp.md +29 -0
- package/skills/lsp-setup/references/dart.md +25 -0
- package/skills/lsp-setup/references/elixir.md +30 -0
- package/skills/lsp-setup/references/go.md +33 -0
- package/skills/lsp-setup/references/haskell.md +27 -0
- package/skills/lsp-setup/references/java.md +28 -0
- package/skills/lsp-setup/references/julia.md +28 -0
- package/skills/lsp-setup/references/kotlin.md +25 -0
- package/skills/lsp-setup/references/lua.md +26 -0
- package/skills/lsp-setup/references/php.md +30 -0
- package/skills/lsp-setup/references/python.md +33 -0
- package/skills/lsp-setup/references/ruby.md +34 -0
- package/skills/lsp-setup/references/rust.md +34 -0
- package/skills/lsp-setup/references/swift.md +26 -0
- package/skills/lsp-setup/references/terraform.md +26 -0
- package/skills/lsp-setup/references/typescript.md +35 -0
- package/skills/lsp-setup/references/yaml.md +27 -0
- package/skills/lsp-setup/references/zig.md +28 -0
- package/skills/managed-skill-manifest.json +1386 -0
- package/skills/native-goal-verdict/SKILL.md +216 -0
- package/skills/refactor/SKILL.md +221 -0
- package/skills/reference-benchmark-claims/SKILL.md +204 -0
- package/skills/release-guardrails/SKILL.md +245 -0
- package/skills/review-work/SKILL.md +301 -0
- package/skills/rules/SKILL.md +196 -0
- package/skills/search-workflow-ideas/SKILL.md +223 -0
- package/skills/skill-observer/SKILL.md +148 -0
- package/skills/skill-observer/references/review-contract.md +95 -0
- package/skills/skill-rename-aliases.json +10 -0
- package/skills/start-work/SKILL.md +334 -0
- package/skills/structural-search/SKILL.md +234 -0
- package/skills/tool-guards/SKILL.md +223 -0
- package/skills/visual-qa/SKILL.md +61 -0
- package/skills/visual-qa/references/capture-playbook.md +105 -0
- package/skills/visual-qa/references/complete-contract.md +411 -0
- package/skills/visual-qa/schemas/evidence-manifest-v1alpha1.json +201 -0
- package/skills/visual-qa/schemas/evidence-manifest-v1beta1.json +141 -0
- package/skills/visual-qa/schemas/review-receipt-v1alpha1.json +113 -0
- package/skills/visual-qa/scripts/artifact.mjs +123 -0
- package/skills/visual-qa/scripts/bounded-json.mjs +47 -0
- package/skills/visual-qa/scripts/canonical-json.mjs +28 -0
- package/skills/visual-qa/scripts/capabilities.mjs +66 -0
- package/skills/visual-qa/scripts/contract-text.mjs +15 -0
- package/skills/visual-qa/scripts/design-contract.mjs +611 -0
- package/skills/visual-qa/scripts/evidence-evaluate.mjs +521 -0
- package/skills/visual-qa/scripts/evidence.mjs +271 -0
- package/skills/visual-qa/scripts/png-decode.mjs +146 -0
- package/skills/visual-qa/scripts/png.mjs +154 -0
- package/skills/visual-qa/scripts/review.mjs +188 -0
- package/skills/visual-qa/scripts/stdin-json.mjs +16 -0
- package/skills/visual-qa/scripts/strict-json.mjs +102 -0
- package/skills/visual-qa/scripts/tui.mjs +149 -0
- package/skills/visual-qa/scripts/visual-qa.mjs +90 -0
- package/skills/wikify/LICENSE +21 -0
- package/skills/wikify/PROVENANCE.md +18 -0
- package/skills/wikify/SKILL.md +176 -0
- package/skills/wikify/assets/home-template.md +44 -0
- package/skills/wikify/assets/maintenance-report-template.md +46 -0
- package/skills/wikify/assets/paper-source-note-template.md +137 -0
- package/skills/wikify/assets/source-note-template.md +45 -0
- package/skills/wikify/assets/wiki-rules-template.md +117 -0
- package/skills/wikify/modes/ingest.md +57 -0
- package/skills/wikify/modes/init.md +44 -0
- package/skills/wikify/modes/lint.md +60 -0
- package/skills/wikify/modes/query.md +38 -0
- package/skills/wikify/modes/save.md +45 -0
- package/skills/wikify/references-upstream-contract.md +758 -0
- package/skills/workflow-loop/SKILL.md +387 -0
- package/tools/check-pack-payload.mjs +410 -0
- package/tools/check-payload-substance.mjs +738 -0
- package/tools/check-version-lockstep.mjs +238 -0
- package/tools/gen-canonical-frontend-manifest.mjs +66 -0
- package/tools/gen-managed-skill-manifest.mjs +135 -0
- package/tools/harness-speed-local.mjs +261 -0
- package/tools/payload-reference-exemptions.json +49 -0
- package/tools/payload-substance-allowlist.json +46 -0
- package/tools/payload-substance-parity.json +571 -0
- package/tools/qa-real-surface-fixtures.mjs +428 -0
- package/tools/qa-real-surface-harness.mjs +173 -0
- package/tools/run-behavior-replacement-probes.mjs +296 -0
- package/tools/run-build.mjs +101 -0
- package/tools/run-harness-speed-local.mjs +52 -0
- package/tools/run-harness-speed-v2.mjs +36 -0
- package/tools/run-installed-resource-tamper-probe.mjs +62 -0
- package/tools/run-negative-gate-matrix.mjs +516 -0
- package/tools/run-rules-glob-differential.mjs +232 -0
- package/tools/run-typecheck.mjs +25 -0
- package/tools/run-uiux-visual-qa-scenarios.mjs +234 -0
- package/tools/run-wikify-surface-probe.mjs +170 -0
- package/tools/scan-legacy-tokens.mjs +431 -0
- package/tools/version-manifests.json +60 -0
- package/tsconfig.build.json +12 -0
- package/tsconfig.json +13 -0
- package/vendor/NOTICE.md +21 -0
- package/vendor/handoff/SKILL.md +199 -0
- package/vendor/handoff/evals/evals.json +154 -0
- package/vendor/handoff/examples/HANDOFF-example-generic-auth-refactor.md +97 -0
- package/vendor/handoff/templates/HANDOFF.md +121 -0
- package/vendor/licenses/022_handoff-MIT.txt +21 -0
- package/vendor/licenses/045_scientific-visualization-MIT.txt +21 -0
- package/vendor/provenance/022_handoff.md +19 -0
- package/vendor/provenance/045_scientific-visualization.md +36 -0
- package/vendor/scientific-visualization/SKILL.md +283 -0
- package/vendor/scientific-visualization/assets/color_palettes.py +197 -0
- package/vendor/scientific-visualization/assets/nature.mplstyle +75 -0
- package/vendor/scientific-visualization/assets/presentation.mplstyle +74 -0
- package/vendor/scientific-visualization/assets/publication.mplstyle +78 -0
- package/vendor/scientific-visualization/evals/evals.json +158 -0
- package/vendor/scientific-visualization/references/color_palettes.md +380 -0
- package/vendor/scientific-visualization/references/journal_requirements.md +359 -0
- package/vendor/scientific-visualization/references/matplotlib_examples.md +608 -0
- package/vendor/scientific-visualization/references/mdanalysis_martini_visualization.md +85 -0
- package/vendor/scientific-visualization/references/publication_guidelines.md +217 -0
- package/vendor/scientific-visualization/references/seaborn_for_publications.md +293 -0
- package/vendor/scientific-visualization/scripts/figure_export.py +238 -0
- package/vendor/scientific-visualization/scripts/style_presets.py +467 -0
- package/vendor/scientific-visualization/tests/test_figure_export.py +51 -0
- package/vendor/scientific-visualization/tests/test_style_presets.py +114 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { litOpenCodeRuntimeSkills } from "../skills.ts";
|
|
2
|
+
import { type ManagedSkillId } from "./managed-skill-assets.ts";
|
|
3
|
+
import { type RetainedCanonicalCache } from "./native-canonical-cache.ts";
|
|
4
|
+
import type { PackageMetadata } from "./types.ts";
|
|
5
|
+
export type RuntimeSkill = (typeof litOpenCodeRuntimeSkills)[number];
|
|
6
|
+
export type DestinationState = {
|
|
7
|
+
readonly kind: "absent";
|
|
8
|
+
} | {
|
|
9
|
+
readonly kind: "managed";
|
|
10
|
+
readonly entrypoint: string;
|
|
11
|
+
} | {
|
|
12
|
+
readonly kind: "preserved";
|
|
13
|
+
readonly entrypoint?: string;
|
|
14
|
+
readonly reason: string;
|
|
15
|
+
};
|
|
16
|
+
export declare function nativeSkillsRoot(root: string): Promise<string>;
|
|
17
|
+
export declare function sourceSkillDir(metadata: PackageMetadata, id: string): string;
|
|
18
|
+
export declare function nativeSkillContent(metadata: PackageMetadata, skill: RuntimeSkill): Promise<string>;
|
|
19
|
+
export declare function validateManagedSkillSource(metadata: PackageMetadata, id: ManagedSkillId): Promise<void>;
|
|
20
|
+
export declare function validateSkillSource(metadata: PackageMetadata, skill: RuntimeSkill): Promise<void>;
|
|
21
|
+
export declare function destinationState(root: string, skill: {
|
|
22
|
+
readonly id: string;
|
|
23
|
+
}): Promise<DestinationState>;
|
|
24
|
+
export declare function invalidInstalledAssets(skillRoot: string, metadata: PackageMetadata, skill: RuntimeSkill): Promise<string[]>;
|
|
25
|
+
export declare function assertInstalledCanonicalOwnership(root: string, skill: RuntimeSkill): Promise<RetainedCanonicalCache[]>;
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { litOpenCodeRuntimeSkills } from "../skills.js";
|
|
5
|
+
import { hasLitOpenCodeGeneratedFileMarker, litOpenCodeGeneratedFrontmatterMarker, stripUserFacingHtmlCommentLines } from "../user-facing-markdown.js";
|
|
6
|
+
import { expectedManagedSkillFiles, expectedInstalledSkillFiles, installedCanonicalDirectory, nativeManagedSkillReferences, isRecursivelyManagedSkill, managedVendorAssets, managedSkillDefinition, managedSkillDiscoveryDescription } from "./managed-skill-assets.js";
|
|
7
|
+
import { assertContained, assertPathComponentsSafe, exactTreeFailures, inventoryTree, lstatIfPresent, resolveSafeDirectory } from "./native-skill-tree.js";
|
|
8
|
+
import { inspectCanonicalTree } from "./native-canonical-cache.js";
|
|
9
|
+
export async function nativeSkillsRoot(root) {
|
|
10
|
+
return resolveSafeDirectory(root, path.join(root, "skills"), "Native skills destination");
|
|
11
|
+
}
|
|
12
|
+
export function sourceSkillDir(metadata, id) {
|
|
13
|
+
return path.join(metadata.packageRoot, "skills", id);
|
|
14
|
+
}
|
|
15
|
+
function sourceSkillFile(metadata, id) {
|
|
16
|
+
return path.join(sourceSkillDir(metadata, id), "SKILL.md");
|
|
17
|
+
}
|
|
18
|
+
function stripYamlFrontmatter(text) {
|
|
19
|
+
if (!text.startsWith("---\n"))
|
|
20
|
+
return text;
|
|
21
|
+
const end = text.indexOf("\n---\n", 4);
|
|
22
|
+
return end === -1 ? text : text.slice(end + "\n---\n".length);
|
|
23
|
+
}
|
|
24
|
+
export async function nativeSkillContent(metadata, skill) {
|
|
25
|
+
const source = await fs.readFile(sourceSkillFile(metadata, skill.id), "utf8");
|
|
26
|
+
const body = nativeManagedSkillReferences(skill.id, stripUserFacingHtmlCommentLines(stripYamlFrontmatter(source))).trimStart();
|
|
27
|
+
const description = skill.summary + " " + managedSkillDiscoveryDescription(skill.id);
|
|
28
|
+
return [
|
|
29
|
+
"---",
|
|
30
|
+
"name: " + skill.id,
|
|
31
|
+
"description: |-",
|
|
32
|
+
...description.split("\n").map((line) => " " + line),
|
|
33
|
+
"metadata:",
|
|
34
|
+
` ${litOpenCodeGeneratedFrontmatterMarker.replace(": true", ': "true"')}`,
|
|
35
|
+
"---",
|
|
36
|
+
"",
|
|
37
|
+
body.trimEnd(),
|
|
38
|
+
""
|
|
39
|
+
].join("\n");
|
|
40
|
+
}
|
|
41
|
+
export async function validateManagedSkillSource(metadata, id) {
|
|
42
|
+
const skillRoot = sourceSkillDir(metadata, id);
|
|
43
|
+
await assertPathComponentsSafe(metadata.packageRoot, skillRoot, `Managed source ${id}`);
|
|
44
|
+
const stat = await lstatIfPresent(skillRoot);
|
|
45
|
+
if (stat === null || !stat.isDirectory())
|
|
46
|
+
throw new Error(`Managed source ${id} is not a directory: ${skillRoot}`);
|
|
47
|
+
const definition = managedSkillDefinition(id);
|
|
48
|
+
if (definition === undefined)
|
|
49
|
+
throw new Error(`Managed source manifest is missing ${id}`);
|
|
50
|
+
const failures = exactTreeFailures(await inventoryTree(skillRoot), expectedManagedSkillFiles(id));
|
|
51
|
+
if (failures.length > 0)
|
|
52
|
+
throw new Error(`Managed source ${id} has an altered file set: ${failures.join(", ")}`);
|
|
53
|
+
const canonicalRoot = definition.canonicalRoot === undefined
|
|
54
|
+
? skillRoot
|
|
55
|
+
: path.resolve(skillRoot, definition.canonicalRoot);
|
|
56
|
+
await assertPathComponentsSafe(metadata.packageRoot, canonicalRoot, `Managed source ${id} canonical root`);
|
|
57
|
+
const canonicalStat = await lstatIfPresent(canonicalRoot);
|
|
58
|
+
if (canonicalStat === null || !canonicalStat.isDirectory()) {
|
|
59
|
+
throw new Error(`Managed source ${id} canonical root is not a directory: ${canonicalRoot}`);
|
|
60
|
+
}
|
|
61
|
+
if (definition.canonicalRoot !== undefined) {
|
|
62
|
+
const canonicalFailures = exactTreeFailures(await inventoryTree(canonicalRoot), definition.canonicalFiles.map((asset) => asset.path));
|
|
63
|
+
if (canonicalFailures.length > 0) {
|
|
64
|
+
throw new Error(`Managed source ${id} canonical tree has an altered file set: ${canonicalFailures.join(", ")}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
for (const asset of definition.canonicalFiles) {
|
|
68
|
+
const actual = createHash("sha256").update(await fs.readFile(path.join(canonicalRoot, asset.path))).digest("hex");
|
|
69
|
+
if (actual !== asset.sha256) {
|
|
70
|
+
const sourceLabel = definition.canonicalRoot === undefined ? asset.path : `${definition.canonicalRoot}/${asset.path}`;
|
|
71
|
+
throw new Error(`Managed source ${id}/${sourceLabel} failed SHA-256: expected ${asset.sha256}, got ${actual}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
for (const asset of managedVendorAssets()) {
|
|
75
|
+
const vendorPath = path.join(metadata.packageRoot, "vendor", asset.path);
|
|
76
|
+
await assertPathComponentsSafe(metadata.packageRoot, vendorPath, `Managed vendor ${asset.path}`);
|
|
77
|
+
const actual = createHash("sha256").update(await fs.readFile(vendorPath)).digest("hex");
|
|
78
|
+
if (actual !== asset.sha256) {
|
|
79
|
+
throw new Error(`Managed vendor/${asset.path} failed SHA-256: expected ${asset.sha256}, got ${actual}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
export async function validateSkillSource(metadata, skill) {
|
|
84
|
+
const skillRoot = sourceSkillDir(metadata, skill.id);
|
|
85
|
+
await assertPathComponentsSafe(metadata.packageRoot, sourceSkillFile(metadata, skill.id), `Skill source ${skill.id}`);
|
|
86
|
+
if (isRecursivelyManagedSkill(skill.id)) {
|
|
87
|
+
await validateManagedSkillSource(metadata, skill.id);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const stat = await lstatIfPresent(sourceSkillFile(metadata, skill.id));
|
|
91
|
+
if (stat === null || !stat.isFile())
|
|
92
|
+
throw new Error(`Skill source entrypoint is missing: ${sourceSkillFile(metadata, skill.id)}`);
|
|
93
|
+
const rootStat = await lstatIfPresent(skillRoot);
|
|
94
|
+
if (rootStat === null || !rootStat.isDirectory())
|
|
95
|
+
throw new Error(`Skill source root is invalid: ${skillRoot}`);
|
|
96
|
+
}
|
|
97
|
+
export async function destinationState(root, skill) {
|
|
98
|
+
const skillsRoot = await nativeSkillsRoot(root);
|
|
99
|
+
const skillRoot = path.join(skillsRoot, skill.id);
|
|
100
|
+
assertContained(skillsRoot, skillRoot, `Native skill ${skill.id}`);
|
|
101
|
+
const rootStat = await lstatIfPresent(skillRoot);
|
|
102
|
+
if (rootStat === null)
|
|
103
|
+
return { kind: "absent" };
|
|
104
|
+
if (rootStat.isSymbolicLink())
|
|
105
|
+
throw new Error(`Native skill ${skill.id} destination is a symbolic link: ${skillRoot}`);
|
|
106
|
+
if (!rootStat.isDirectory())
|
|
107
|
+
return { kind: "preserved", reason: "skill root is not a directory" };
|
|
108
|
+
const entrypoint = path.join(skillRoot, "SKILL.md");
|
|
109
|
+
const entryStat = await lstatIfPresent(entrypoint);
|
|
110
|
+
if (entryStat === null)
|
|
111
|
+
return { kind: "preserved", reason: "pre-existing directory has no managed entrypoint" };
|
|
112
|
+
if (entryStat.isSymbolicLink())
|
|
113
|
+
throw new Error(`Native skill ${skill.id} entrypoint is a symbolic link: ${entrypoint}`);
|
|
114
|
+
if (!entryStat.isFile())
|
|
115
|
+
return { kind: "preserved", reason: "entrypoint is not a regular file" };
|
|
116
|
+
if (!hasLitOpenCodeGeneratedFileMarker(await fs.readFile(entrypoint, "utf8"))) {
|
|
117
|
+
return { kind: "preserved", entrypoint, reason: "entrypoint is user-owned" };
|
|
118
|
+
}
|
|
119
|
+
const inventory = await inventoryTree(skillRoot);
|
|
120
|
+
if (inventory.unsafe.length > 0) {
|
|
121
|
+
throw new Error(`Native skill ${skill.id} destination contains a symbolic link or special file: ${inventory.unsafe.join(", ")}`);
|
|
122
|
+
}
|
|
123
|
+
return { kind: "managed", entrypoint };
|
|
124
|
+
}
|
|
125
|
+
export async function invalidInstalledAssets(skillRoot, metadata, skill) {
|
|
126
|
+
const inventory = await inventoryTree(skillRoot);
|
|
127
|
+
if (inventory.unsafe.length > 0)
|
|
128
|
+
return exactTreeFailures(inventory, expectedInstalledSkillFiles(skill.id));
|
|
129
|
+
const definition = managedSkillDefinition(skill.id);
|
|
130
|
+
const canonical = definition?.canonicalRoot === undefined ? undefined : await inspectCanonicalTree(path.join(skillRoot, installedCanonicalDirectory), definition.canonicalFiles).catch(() => ({ failures: [installedCanonicalDirectory], caches: [] }));
|
|
131
|
+
const caches = canonical?.failures.length === 0 ? canonical.caches : [];
|
|
132
|
+
const failures = exactTreeFailures(inventory, [
|
|
133
|
+
...expectedInstalledSkillFiles(skill.id),
|
|
134
|
+
...caches.map((cache) => `${installedCanonicalDirectory}/${cache.path}`)
|
|
135
|
+
]);
|
|
136
|
+
if (canonical !== undefined)
|
|
137
|
+
failures.push(...canonical.failures.map((file) => `${installedCanonicalDirectory}/${file}`));
|
|
138
|
+
const expectedEntry = Buffer.from(await nativeSkillContent(metadata, skill));
|
|
139
|
+
const installedEntry = await fs.readFile(path.join(skillRoot, "SKILL.md"));
|
|
140
|
+
if (!installedEntry.equals(expectedEntry))
|
|
141
|
+
failures.push("SKILL.md");
|
|
142
|
+
if (definition !== undefined) {
|
|
143
|
+
for (const asset of definition.canonicalFiles) {
|
|
144
|
+
const relativePath = definition.canonicalRoot === undefined
|
|
145
|
+
? asset.path : `${installedCanonicalDirectory}/${asset.path}`;
|
|
146
|
+
const installed = await fs.readFile(path.join(skillRoot, relativePath)).catch(() => null);
|
|
147
|
+
const actual = installed === null ? null : createHash("sha256").update(installed).digest("hex");
|
|
148
|
+
if (actual !== asset.sha256)
|
|
149
|
+
failures.push(relativePath);
|
|
150
|
+
}
|
|
151
|
+
for (const relativePath of definition.distributionFiles.filter((candidate) => candidate !== "SKILL.md")) {
|
|
152
|
+
const expected = await fs.readFile(path.join(sourceSkillDir(metadata, skill.id), relativePath));
|
|
153
|
+
const installed = await fs.readFile(path.join(skillRoot, relativePath)).catch(() => null);
|
|
154
|
+
if (installed === null || !installed.equals(expected))
|
|
155
|
+
failures.push(relativePath);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return [...new Set(failures)].sort();
|
|
159
|
+
}
|
|
160
|
+
export async function assertInstalledCanonicalOwnership(root, skill) {
|
|
161
|
+
const definition = managedSkillDefinition(skill.id);
|
|
162
|
+
if (definition?.canonicalRoot === undefined)
|
|
163
|
+
return [];
|
|
164
|
+
const skillRoot = path.join(await nativeSkillsRoot(root), skill.id);
|
|
165
|
+
const canonicalRoot = path.join(skillRoot, installedCanonicalDirectory);
|
|
166
|
+
await assertPathComponentsSafe(skillRoot, canonicalRoot, `Native canonical ${skill.id}`);
|
|
167
|
+
const stat = await lstatIfPresent(canonicalRoot);
|
|
168
|
+
// No subtree is the previously shipped flat wrapper, so it can gain its missing closure.
|
|
169
|
+
if (stat === null)
|
|
170
|
+
return [];
|
|
171
|
+
if (!stat.isDirectory())
|
|
172
|
+
throw new Error(`Native canonical ${skill.id} is not an owned directory`);
|
|
173
|
+
const { failures, caches } = await inspectCanonicalTree(canonicalRoot, definition.canonicalFiles);
|
|
174
|
+
if (failures.length > 0) {
|
|
175
|
+
throw new Error(`Native canonical ${skill.id} contains modified, missing, foreign, or unsafe files; preserve it before retrying: ${failures.join(", ")}`);
|
|
176
|
+
}
|
|
177
|
+
return caches;
|
|
178
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
export type TreeInventory = {
|
|
3
|
+
readonly files: readonly string[];
|
|
4
|
+
readonly directories: readonly string[];
|
|
5
|
+
readonly unsafe: readonly string[];
|
|
6
|
+
};
|
|
7
|
+
export declare function lstatIfPresent(filePath: string): Promise<Awaited<ReturnType<typeof fs.lstat>> | null>;
|
|
8
|
+
export declare function assertContained(base: string, target: string, label: string): void;
|
|
9
|
+
export declare function assertPathComponentsSafe(base: string, target: string, label: string): Promise<void>;
|
|
10
|
+
export declare function resolveSafeDirectory(base: string, target: string, label: string): Promise<string>;
|
|
11
|
+
export declare function inventoryTree(root: string): Promise<TreeInventory>;
|
|
12
|
+
export declare function exactTreeFailures(inventory: TreeInventory, expectedFiles: readonly string[]): string[];
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
export async function lstatIfPresent(filePath) {
|
|
4
|
+
try {
|
|
5
|
+
return await fs.lstat(filePath);
|
|
6
|
+
}
|
|
7
|
+
catch (error) {
|
|
8
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT")
|
|
9
|
+
return null;
|
|
10
|
+
throw error;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export function assertContained(base, target, label) {
|
|
14
|
+
const relative = path.relative(path.resolve(base), path.resolve(target));
|
|
15
|
+
if (relative === "" || (!relative.startsWith(".." + path.sep) && relative !== ".." && !path.isAbsolute(relative)))
|
|
16
|
+
return;
|
|
17
|
+
throw new Error(`${label} escapes its managed root: ${target}`);
|
|
18
|
+
}
|
|
19
|
+
export async function assertPathComponentsSafe(base, target, label) {
|
|
20
|
+
assertContained(base, target, label);
|
|
21
|
+
const resolvedBase = path.resolve(base);
|
|
22
|
+
const resolvedTarget = path.resolve(target);
|
|
23
|
+
const relative = path.relative(resolvedBase, resolvedTarget);
|
|
24
|
+
const candidates = [resolvedBase];
|
|
25
|
+
let current = resolvedBase;
|
|
26
|
+
if (relative !== "") {
|
|
27
|
+
for (const component of relative.split(path.sep)) {
|
|
28
|
+
current = path.join(current, component);
|
|
29
|
+
candidates.push(current);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
for (const candidate of candidates) {
|
|
33
|
+
const stat = await lstatIfPresent(candidate);
|
|
34
|
+
if (stat?.isSymbolicLink())
|
|
35
|
+
throw new Error(`${label} contains a symbolic link: ${candidate}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export async function resolveSafeDirectory(base, target, label) {
|
|
39
|
+
const resolvedTarget = path.resolve(target);
|
|
40
|
+
assertContained(base, resolvedTarget, label);
|
|
41
|
+
await assertPathComponentsSafe(base, path.dirname(resolvedTarget), label);
|
|
42
|
+
const stat = await lstatIfPresent(resolvedTarget);
|
|
43
|
+
if (stat === null)
|
|
44
|
+
return resolvedTarget;
|
|
45
|
+
if (!stat.isSymbolicLink()) {
|
|
46
|
+
if (!stat.isDirectory())
|
|
47
|
+
throw new Error(`${label} is not a directory: ${resolvedTarget}`);
|
|
48
|
+
return resolvedTarget;
|
|
49
|
+
}
|
|
50
|
+
const canonicalTarget = await fs.realpath(resolvedTarget);
|
|
51
|
+
if (!(await fs.stat(canonicalTarget)).isDirectory()) {
|
|
52
|
+
throw new Error(`${label} symbolic link does not target a directory: ${resolvedTarget}`);
|
|
53
|
+
}
|
|
54
|
+
return canonicalTarget;
|
|
55
|
+
}
|
|
56
|
+
export async function inventoryTree(root) {
|
|
57
|
+
const files = [];
|
|
58
|
+
const directories = [];
|
|
59
|
+
const unsafe = [];
|
|
60
|
+
async function walk(directory, prefix) {
|
|
61
|
+
for (const entry of await fs.readdir(directory, { withFileTypes: true })) {
|
|
62
|
+
const relative = path.join(prefix, entry.name).split(path.sep).join("/");
|
|
63
|
+
if (entry.isSymbolicLink()) {
|
|
64
|
+
unsafe.push(relative);
|
|
65
|
+
}
|
|
66
|
+
else if (entry.isDirectory()) {
|
|
67
|
+
directories.push(relative);
|
|
68
|
+
await walk(path.join(directory, entry.name), relative);
|
|
69
|
+
}
|
|
70
|
+
else if (entry.isFile()) {
|
|
71
|
+
files.push(relative);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
unsafe.push(relative);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
await walk(root, "");
|
|
79
|
+
return { files: files.sort(), directories: directories.sort(), unsafe: unsafe.sort() };
|
|
80
|
+
}
|
|
81
|
+
export function exactTreeFailures(inventory, expectedFiles) {
|
|
82
|
+
const failures = [...inventory.unsafe];
|
|
83
|
+
const actualFiles = new Set(inventory.files);
|
|
84
|
+
const expectedFileSet = new Set(expectedFiles);
|
|
85
|
+
const expectedDirectorySet = new Set();
|
|
86
|
+
for (const file of expectedFiles) {
|
|
87
|
+
let directory = path.posix.dirname(file);
|
|
88
|
+
while (directory !== ".") {
|
|
89
|
+
expectedDirectorySet.add(directory);
|
|
90
|
+
directory = path.posix.dirname(directory);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
for (const file of expectedFiles)
|
|
94
|
+
if (!actualFiles.has(file))
|
|
95
|
+
failures.push(file);
|
|
96
|
+
for (const file of inventory.files)
|
|
97
|
+
if (!expectedFileSet.has(file))
|
|
98
|
+
failures.push(file);
|
|
99
|
+
for (const directory of inventory.directories) {
|
|
100
|
+
if (!expectedDirectorySet.has(directory))
|
|
101
|
+
failures.push(directory + "/");
|
|
102
|
+
}
|
|
103
|
+
return [...new Set(failures)].sort();
|
|
104
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { inspectScientificVisualizationDependencies } from "./scientific-visualization-dependencies.ts";
|
|
2
|
+
import type { InstallReport, PackageMetadata } from "./types.ts";
|
|
3
|
+
export { validateManagedSkillSource } from "./native-skill-integrity.ts";
|
|
4
|
+
export { ensureNativeSkills } from "./native-skill-install.ts";
|
|
5
|
+
export declare function describeNativeSkillMutation(root: string, metadata: PackageMetadata): Promise<InstallReport["nativeSkills"]>;
|
|
6
|
+
export type NativeSkillInspection = {
|
|
7
|
+
readonly path: string;
|
|
8
|
+
readonly expected: readonly string[];
|
|
9
|
+
readonly present: readonly string[];
|
|
10
|
+
readonly missing: readonly string[];
|
|
11
|
+
readonly managed: readonly string[];
|
|
12
|
+
readonly preserved: readonly string[];
|
|
13
|
+
readonly invalid: readonly string[];
|
|
14
|
+
readonly invalidAssets: readonly string[];
|
|
15
|
+
readonly sourceInvalid: readonly string[];
|
|
16
|
+
readonly canonicalCacheFiles: readonly string[];
|
|
17
|
+
readonly dependencies: {
|
|
18
|
+
readonly "lit-scientific-visualization": ReturnType<typeof inspectScientificVisualizationDependencies>;
|
|
19
|
+
};
|
|
20
|
+
readonly ok: boolean;
|
|
21
|
+
};
|
|
22
|
+
export declare function inspectNativeSkills(root: string, metadata: PackageMetadata): Promise<NativeSkillInspection>;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { litOpenCodeRuntimeSkills } from "../skills.js";
|
|
3
|
+
import { destinationState, assertInstalledCanonicalOwnership, invalidInstalledAssets, validateSkillSource } from "./native-skill-integrity.js";
|
|
4
|
+
import { inspectScientificVisualizationDependencies } from "./scientific-visualization-dependencies.js";
|
|
5
|
+
export { validateManagedSkillSource } from "./native-skill-integrity.js";
|
|
6
|
+
export { ensureNativeSkills } from "./native-skill-install.js";
|
|
7
|
+
export async function describeNativeSkillMutation(root, metadata) {
|
|
8
|
+
const write = [];
|
|
9
|
+
const preserve = [];
|
|
10
|
+
const collisions = [];
|
|
11
|
+
for (const skill of litOpenCodeRuntimeSkills) {
|
|
12
|
+
await validateSkillSource(metadata, skill);
|
|
13
|
+
const destination = await destinationState(root, skill);
|
|
14
|
+
if (destination.kind === "managed")
|
|
15
|
+
await assertInstalledCanonicalOwnership(root, skill);
|
|
16
|
+
if (destination.kind === "absent" || destination.kind === "managed")
|
|
17
|
+
write.push(skill.id);
|
|
18
|
+
else {
|
|
19
|
+
preserve.push(skill.id);
|
|
20
|
+
if (destination.entrypoint === undefined)
|
|
21
|
+
collisions.push(skill.id);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
path: path.join(root, "skills"),
|
|
26
|
+
changed: write.length > 0,
|
|
27
|
+
write,
|
|
28
|
+
preserve,
|
|
29
|
+
collisions
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export async function inspectNativeSkills(root, metadata) {
|
|
33
|
+
const present = [];
|
|
34
|
+
const missing = [];
|
|
35
|
+
const managed = [];
|
|
36
|
+
const preserved = [];
|
|
37
|
+
const invalid = [];
|
|
38
|
+
const invalidAssets = [];
|
|
39
|
+
const sourceInvalid = [];
|
|
40
|
+
const canonicalCacheFiles = [];
|
|
41
|
+
for (const skill of litOpenCodeRuntimeSkills) {
|
|
42
|
+
let sourceOk = true;
|
|
43
|
+
try {
|
|
44
|
+
await validateSkillSource(metadata, skill);
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
sourceOk = false;
|
|
48
|
+
sourceInvalid.push(skill.id);
|
|
49
|
+
invalid.push(skill.id);
|
|
50
|
+
invalidAssets.push(`${skill.id}/source: ${error instanceof Error ? error.message : String(error)}`);
|
|
51
|
+
}
|
|
52
|
+
let destination;
|
|
53
|
+
try {
|
|
54
|
+
destination = await destinationState(root, skill);
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
invalid.push(skill.id);
|
|
58
|
+
invalidAssets.push(`${skill.id}/destination: ${error instanceof Error ? error.message : String(error)}`);
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if (destination.kind === "absent") {
|
|
62
|
+
missing.push(skill.id);
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (destination.kind === "preserved") {
|
|
66
|
+
preserved.push(skill.id);
|
|
67
|
+
if (destination.entrypoint === undefined) {
|
|
68
|
+
missing.push(skill.id);
|
|
69
|
+
invalid.push(skill.id);
|
|
70
|
+
invalidAssets.push(`${skill.id}/SKILL.md`);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
present.push(skill.id);
|
|
74
|
+
}
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
present.push(skill.id);
|
|
78
|
+
managed.push(skill.id);
|
|
79
|
+
if (!sourceOk)
|
|
80
|
+
continue;
|
|
81
|
+
const failures = await invalidInstalledAssets(path.dirname(destination.entrypoint), metadata, skill);
|
|
82
|
+
if (failures.length > 0) {
|
|
83
|
+
invalid.push(skill.id);
|
|
84
|
+
invalidAssets.push(...failures.map((failure) => `${skill.id}/${failure}`));
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
canonicalCacheFiles.push(...(await assertInstalledCanonicalOwnership(root, skill)).map((cache) => `${skill.id}/canonical/${cache.path}`));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
const uniqueInvalid = [...new Set(invalid)];
|
|
91
|
+
return {
|
|
92
|
+
path: path.join(root, "skills"),
|
|
93
|
+
expected: litOpenCodeRuntimeSkills.map((skill) => skill.id),
|
|
94
|
+
present,
|
|
95
|
+
missing,
|
|
96
|
+
managed,
|
|
97
|
+
preserved,
|
|
98
|
+
invalid: uniqueInvalid,
|
|
99
|
+
invalidAssets: [...new Set(invalidAssets)],
|
|
100
|
+
sourceInvalid,
|
|
101
|
+
canonicalCacheFiles,
|
|
102
|
+
dependencies: { "lit-scientific-visualization": inspectScientificVisualizationDependencies() },
|
|
103
|
+
ok: missing.length === 0 && uniqueInvalid.length === 0
|
|
104
|
+
};
|
|
105
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { PluginMutation } from "./types.ts";
|
|
2
|
+
export declare function isLitOpenCodeEntry(value: unknown): boolean;
|
|
3
|
+
export declare function describePluginMutation(config: Record<string, unknown> | null, target: string): PluginMutation;
|
|
4
|
+
export declare function applyPluginMutation(config: Record<string, unknown> | null, mutation: PluginMutation, target: string): Record<string, unknown>;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
export function isLitOpenCodeEntry(value) {
|
|
2
|
+
const id = pluginEntryId(value);
|
|
3
|
+
return ["litopencode", "@litfamily/opencode", "@litfamily/litopencode"].some((name) => id === name || id.startsWith(`${name}@`));
|
|
4
|
+
}
|
|
5
|
+
function pluginEntryId(value) {
|
|
6
|
+
if (typeof value === "string")
|
|
7
|
+
return value;
|
|
8
|
+
if (Array.isArray(value) && typeof value[0] === "string")
|
|
9
|
+
return value[0];
|
|
10
|
+
return "";
|
|
11
|
+
}
|
|
12
|
+
function replaceLitOpenCodeEntry(value, target) {
|
|
13
|
+
if (Array.isArray(value) && isLitOpenCodeEntry(value))
|
|
14
|
+
return [target, ...value.slice(1)];
|
|
15
|
+
return target;
|
|
16
|
+
}
|
|
17
|
+
function normalizedPluginArray(pluginValue, target) {
|
|
18
|
+
const firstLitEntry = pluginValue.find(isLitOpenCodeEntry);
|
|
19
|
+
const replacement = firstLitEntry === undefined ? target : replaceLitOpenCodeEntry(firstLitEntry, target);
|
|
20
|
+
let replaced = false;
|
|
21
|
+
const next = [];
|
|
22
|
+
for (const value of pluginValue) {
|
|
23
|
+
if (!isLitOpenCodeEntry(value)) {
|
|
24
|
+
next.push(value);
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
if (replaced)
|
|
28
|
+
continue;
|
|
29
|
+
next.push(replacement);
|
|
30
|
+
replaced = true;
|
|
31
|
+
}
|
|
32
|
+
return next;
|
|
33
|
+
}
|
|
34
|
+
export function describePluginMutation(config, target) {
|
|
35
|
+
const pluginValue = config?.plugin;
|
|
36
|
+
const pluginIsArray = Array.isArray(pluginValue);
|
|
37
|
+
const existingIndex = pluginIsArray ? pluginValue.findIndex(isLitOpenCodeEntry) : -1;
|
|
38
|
+
const targetIndex = pluginIsArray ? pluginValue.findIndex((value) => pluginEntryId(value) === target) : -1;
|
|
39
|
+
const litEntryCount = pluginIsArray ? pluginValue.filter(isLitOpenCodeEntry).length : 0;
|
|
40
|
+
const alreadyPresent = targetIndex >= 0 && litEntryCount === 1;
|
|
41
|
+
const currentCount = pluginIsArray ? pluginValue.length : 0;
|
|
42
|
+
if (alreadyPresent) {
|
|
43
|
+
return {
|
|
44
|
+
changed: false,
|
|
45
|
+
plugin: { alreadyPresent: true, currentCount, resultCount: currentCount, add: [] },
|
|
46
|
+
patch: []
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
const add = [target];
|
|
50
|
+
if (pluginIsArray) {
|
|
51
|
+
if (existingIndex >= 0) {
|
|
52
|
+
if (litEntryCount > 1) {
|
|
53
|
+
return {
|
|
54
|
+
changed: true,
|
|
55
|
+
plugin: { alreadyPresent: targetIndex >= 0, currentCount, resultCount: currentCount - litEntryCount + 1, add },
|
|
56
|
+
patch: [{ op: "replace", path: "/plugin", value: normalizedPluginArray(pluginValue, target) }]
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
changed: true,
|
|
61
|
+
plugin: { alreadyPresent: true, currentCount, resultCount: currentCount, add },
|
|
62
|
+
patch: [{ op: "replace", path: `/plugin/${existingIndex}`, value: replaceLitOpenCodeEntry(pluginValue[existingIndex], target) }]
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
changed: true,
|
|
67
|
+
plugin: { alreadyPresent: false, currentCount, resultCount: currentCount + 1, add },
|
|
68
|
+
patch: [{ op: "add", path: "/plugin/-", value: target }]
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
const op = config !== null && Object.hasOwn(config, "plugin") ? "replace" : "add";
|
|
72
|
+
return {
|
|
73
|
+
changed: true,
|
|
74
|
+
plugin: { alreadyPresent: false, currentCount, resultCount: 1, add },
|
|
75
|
+
patch: [{ op, path: "/plugin", value: [target] }]
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
export function applyPluginMutation(config, mutation, target) {
|
|
79
|
+
const next = config === null ? { "$schema": "https://opencode.ai/config.json" } : { ...config };
|
|
80
|
+
if (!mutation.changed)
|
|
81
|
+
return next;
|
|
82
|
+
const pluginValue = next.plugin;
|
|
83
|
+
if (Array.isArray(pluginValue)) {
|
|
84
|
+
next.plugin = pluginValue.some(isLitOpenCodeEntry) ? normalizedPluginArray(pluginValue, target) : [...pluginValue, target];
|
|
85
|
+
return next;
|
|
86
|
+
}
|
|
87
|
+
next.plugin = [target];
|
|
88
|
+
return next;
|
|
89
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type ScientificVisualizationDependencyReport = {
|
|
2
|
+
readonly status: "READY" | "DEGRADED";
|
|
3
|
+
readonly interpreter: {
|
|
4
|
+
readonly command: string;
|
|
5
|
+
readonly available: boolean;
|
|
6
|
+
readonly version?: string;
|
|
7
|
+
};
|
|
8
|
+
readonly required: {
|
|
9
|
+
readonly available: readonly string[];
|
|
10
|
+
readonly missing: readonly string[];
|
|
11
|
+
};
|
|
12
|
+
readonly optional: {
|
|
13
|
+
readonly available: readonly string[];
|
|
14
|
+
readonly missing: readonly string[];
|
|
15
|
+
};
|
|
16
|
+
readonly autoInstall: false;
|
|
17
|
+
};
|
|
18
|
+
export declare function inspectScientificVisualizationDependencies(): ScientificVisualizationDependencyReport;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import { mkdtempSync, rmSync } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
const requiredModules = Object.freeze(["matplotlib"]);
|
|
6
|
+
const optionalModules = Object.freeze([
|
|
7
|
+
"numpy",
|
|
8
|
+
"seaborn",
|
|
9
|
+
"pandas",
|
|
10
|
+
"plotly",
|
|
11
|
+
"scipy",
|
|
12
|
+
"colorspacious",
|
|
13
|
+
"MDAnalysis",
|
|
14
|
+
"kaleido"
|
|
15
|
+
]);
|
|
16
|
+
function selectedInterpreter() {
|
|
17
|
+
const explicit = process.env.LITOPENCODE_SCIENTIFIC_PYTHON?.trim();
|
|
18
|
+
return explicit && explicit.length > 0 ? explicit : "python3";
|
|
19
|
+
}
|
|
20
|
+
function unavailableReport(command) {
|
|
21
|
+
return {
|
|
22
|
+
status: "DEGRADED",
|
|
23
|
+
interpreter: { command, available: false },
|
|
24
|
+
required: { available: [], missing: [command, ...requiredModules] },
|
|
25
|
+
optional: { available: [], missing: optionalModules },
|
|
26
|
+
autoInstall: false
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function availableNames(names, modules) {
|
|
30
|
+
return names.filter((name) => modules[name] === true);
|
|
31
|
+
}
|
|
32
|
+
function missingNames(names, modules) {
|
|
33
|
+
return names.filter((name) => modules[name] !== true);
|
|
34
|
+
}
|
|
35
|
+
export function inspectScientificVisualizationDependencies() {
|
|
36
|
+
const command = selectedInterpreter();
|
|
37
|
+
const modules = [...requiredModules, ...optionalModules];
|
|
38
|
+
const script = [
|
|
39
|
+
"import importlib, json, platform",
|
|
40
|
+
`modules = ${JSON.stringify(modules)}`,
|
|
41
|
+
"def can_import(name):",
|
|
42
|
+
" try:",
|
|
43
|
+
" importlib.import_module(name)",
|
|
44
|
+
" return True",
|
|
45
|
+
" except Exception:",
|
|
46
|
+
" return False",
|
|
47
|
+
"print(json.dumps({'version': platform.python_version(), 'modules': {name: can_import(name) for name in modules}}))"
|
|
48
|
+
].join("\n");
|
|
49
|
+
const matplotlibConfig = mkdtempSync(path.join(tmpdir(), "litopencode-matplotlib-probe-"));
|
|
50
|
+
let result;
|
|
51
|
+
try {
|
|
52
|
+
result = spawnSync(command, ["-c", script], {
|
|
53
|
+
encoding: "utf8",
|
|
54
|
+
timeout: 15_000,
|
|
55
|
+
env: {
|
|
56
|
+
...process.env,
|
|
57
|
+
MPLCONFIGDIR: matplotlibConfig,
|
|
58
|
+
PYTHONDONTWRITEBYTECODE: "1"
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
finally {
|
|
63
|
+
rmSync(matplotlibConfig, { recursive: true, force: true });
|
|
64
|
+
}
|
|
65
|
+
if (result.status !== 0 || result.error !== undefined)
|
|
66
|
+
return unavailableReport(command);
|
|
67
|
+
try {
|
|
68
|
+
const parsed = JSON.parse(String(result.stdout));
|
|
69
|
+
if (typeof parsed.version !== "string" || !parsed.modules || typeof parsed.modules !== "object") {
|
|
70
|
+
return unavailableReport(command);
|
|
71
|
+
}
|
|
72
|
+
const availability = parsed.modules;
|
|
73
|
+
const requiredMissing = missingNames(requiredModules, availability);
|
|
74
|
+
return {
|
|
75
|
+
status: requiredMissing.length === 0 ? "READY" : "DEGRADED",
|
|
76
|
+
interpreter: { command, available: true, version: parsed.version },
|
|
77
|
+
required: {
|
|
78
|
+
available: availableNames(requiredModules, availability),
|
|
79
|
+
missing: requiredMissing
|
|
80
|
+
},
|
|
81
|
+
optional: {
|
|
82
|
+
available: availableNames(optionalModules, availability),
|
|
83
|
+
missing: missingNames(optionalModules, availability)
|
|
84
|
+
},
|
|
85
|
+
autoInstall: false
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return unavailableReport(command);
|
|
90
|
+
}
|
|
91
|
+
}
|