@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,112 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { findLitOpenCodeCommand, litOpenCodeCommands } from "../commands.js";
|
|
4
|
+
import { renamedSkillIds, skillRenameNote } from "../skill-renames.js";
|
|
5
|
+
import { hasLitOpenCodeGeneratedFileMarker, litOpenCodeGeneratedFrontmatterMarker } from "../user-facing-markdown.js";
|
|
6
|
+
import { lstatIfPresent } from "./native-skill-tree.js";
|
|
7
|
+
function commandAliasFile(root, id) {
|
|
8
|
+
return path.join(root, "command", id + ".md");
|
|
9
|
+
}
|
|
10
|
+
function commandAliasContent(command) {
|
|
11
|
+
return [
|
|
12
|
+
"---",
|
|
13
|
+
"description: " + JSON.stringify(command.title + " - " + command.description),
|
|
14
|
+
...(command.agent === undefined ? [] : ["agent: " + command.agent]),
|
|
15
|
+
litOpenCodeGeneratedFrontmatterMarker,
|
|
16
|
+
"---",
|
|
17
|
+
"",
|
|
18
|
+
command.activationText,
|
|
19
|
+
""
|
|
20
|
+
].join("\n");
|
|
21
|
+
}
|
|
22
|
+
async function readTextIfPresent(filePath) {
|
|
23
|
+
try {
|
|
24
|
+
return await fs.readFile(filePath, "utf8");
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT")
|
|
28
|
+
return null;
|
|
29
|
+
throw error;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export async function describeCommandAliasMutation(root) {
|
|
33
|
+
const write = [];
|
|
34
|
+
const preserve = [];
|
|
35
|
+
for (const command of litOpenCodeCommands) {
|
|
36
|
+
const filePath = commandAliasFile(root, command.id);
|
|
37
|
+
const existing = await readTextIfPresent(filePath);
|
|
38
|
+
if (existing === null || hasLitOpenCodeGeneratedFileMarker(existing)) {
|
|
39
|
+
write.push(command.id);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
preserve.push(command.id);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
path: path.join(root, "command"),
|
|
47
|
+
changed: write.length > 0,
|
|
48
|
+
write,
|
|
49
|
+
preserve
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
export async function inspectCommandAliases(root) {
|
|
53
|
+
const present = [];
|
|
54
|
+
const missing = [];
|
|
55
|
+
const managed = [];
|
|
56
|
+
const preserved = [];
|
|
57
|
+
for (const command of litOpenCodeCommands) {
|
|
58
|
+
const existing = await readTextIfPresent(commandAliasFile(root, command.id));
|
|
59
|
+
if (existing === null)
|
|
60
|
+
missing.push(command.id);
|
|
61
|
+
else {
|
|
62
|
+
present.push(command.id);
|
|
63
|
+
if (hasLitOpenCodeGeneratedFileMarker(existing))
|
|
64
|
+
managed.push(command.id);
|
|
65
|
+
else
|
|
66
|
+
preserved.push(command.id);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
path: path.join(root, "command"),
|
|
71
|
+
expected: litOpenCodeCommands.map((command) => command.id),
|
|
72
|
+
present,
|
|
73
|
+
missing,
|
|
74
|
+
managed,
|
|
75
|
+
preserved,
|
|
76
|
+
ok: missing.length === 0
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
export async function ensureCommandAliases(root) {
|
|
80
|
+
const commandDir = path.join(root, "command");
|
|
81
|
+
await fs.mkdir(commandDir, { recursive: true });
|
|
82
|
+
for (const command of litOpenCodeCommands) {
|
|
83
|
+
const filePath = commandAliasFile(root, command.id);
|
|
84
|
+
const existing = await readTextIfPresent(filePath);
|
|
85
|
+
if (existing !== null && !hasLitOpenCodeGeneratedFileMarker(existing))
|
|
86
|
+
continue;
|
|
87
|
+
await fs.writeFile(filePath, commandAliasContent(command), "utf8");
|
|
88
|
+
}
|
|
89
|
+
for (const id of Object.keys(renamedSkillIds)) {
|
|
90
|
+
const filePath = commandAliasFile(root, renamedSkillIds[id]);
|
|
91
|
+
const stat = await lstatIfPresent(filePath);
|
|
92
|
+
if (stat !== null && (stat.isSymbolicLink() || !stat.isFile())) {
|
|
93
|
+
throw new Error(`Unsafe command redirect destination: ${filePath}`);
|
|
94
|
+
}
|
|
95
|
+
const existing = await readTextIfPresent(filePath);
|
|
96
|
+
if (existing !== null && !hasLitOpenCodeGeneratedFileMarker(existing))
|
|
97
|
+
continue;
|
|
98
|
+
const command = findLitOpenCodeCommand(id);
|
|
99
|
+
if (command === undefined)
|
|
100
|
+
throw new Error(`Missing redirect target: ${id}`);
|
|
101
|
+
await fs.writeFile(filePath, [
|
|
102
|
+
"---",
|
|
103
|
+
`description: ${JSON.stringify(`Redirect to /${id}`)}`,
|
|
104
|
+
...(command.agent === undefined ? [] : [`agent: ${command.agent}`]),
|
|
105
|
+
litOpenCodeGeneratedFrontmatterMarker,
|
|
106
|
+
"---",
|
|
107
|
+
"",
|
|
108
|
+
`Invoke /${id} with the supplied arguments and follow its skill contract. Print this line once: ${skillRenameNote(id)}`,
|
|
109
|
+
""
|
|
110
|
+
].join("\n"), "utf8");
|
|
111
|
+
}
|
|
112
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { litOpenCodeAgents, registerLitOpenCodeAgents } from "../agents.js";
|
|
4
|
+
import { defaultGlobalConfigFile, loadConfig, mergeConfigs, readLitOpenCodeConfigFile } from "../config.js";
|
|
5
|
+
import { diagnoseModelRoutes, effectiveAuthoredAgentRoutes, projectModelRoutesForDiagnostics } from "../model-route-policy.js";
|
|
6
|
+
import { litOpenCodeConfigFileForOpenCodeRoot } from "../state.js";
|
|
7
|
+
import { isRecord, readJsonObjectIfPresent, readPackageMetadata } from "./json.js";
|
|
8
|
+
import { inspectCommandAliases } from "./command-aliases.js";
|
|
9
|
+
import { inspectNativeSkills } from "./native-skills.js";
|
|
10
|
+
import { openCodeHostCapabilities } from "./host-capabilities.js";
|
|
11
|
+
import { inspectHostLimits } from "./host-limits.js";
|
|
12
|
+
import { inspectLspCapability } from "./lsp-capability.js";
|
|
13
|
+
import { isLitOpenCodeEntry } from "./plugin-mutation.js";
|
|
14
|
+
import { autoUpdateInstallLockPath, autoUpdateJournalPath, autoUpdateReceiptPath, isAutoUpdateDisabled, readAutoUpdateReceipt } from "./auto-update.js";
|
|
15
|
+
function pluginSpec(metadata) {
|
|
16
|
+
return metadata.name + "@" + metadata.version;
|
|
17
|
+
}
|
|
18
|
+
function pluginEntryId(value) {
|
|
19
|
+
if (typeof value === "string")
|
|
20
|
+
return value;
|
|
21
|
+
if (Array.isArray(value) && typeof value[0] === "string")
|
|
22
|
+
return value[0];
|
|
23
|
+
return "";
|
|
24
|
+
}
|
|
25
|
+
function stripJsonComments(value) {
|
|
26
|
+
return value.replace(/\/\*[\s\S]*?\*\//g, "").replace(/^\s*\/\/.*$/gm, "");
|
|
27
|
+
}
|
|
28
|
+
async function readOpenCodeConfig(root) {
|
|
29
|
+
const resolvedRoot = path.resolve(root);
|
|
30
|
+
const candidates = [path.join(resolvedRoot, "opencode.json"), path.join(resolvedRoot, "opencode.jsonc")];
|
|
31
|
+
for (const candidate of candidates) {
|
|
32
|
+
let raw;
|
|
33
|
+
try {
|
|
34
|
+
raw = await fs.readFile(candidate, "utf8");
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT")
|
|
38
|
+
continue;
|
|
39
|
+
throw error;
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
const parsed = JSON.parse(candidate.endsWith(".jsonc") ? stripJsonComments(raw) : raw);
|
|
43
|
+
return { path: candidate, config: isRecord(parsed) ? parsed : null, ...(isRecord(parsed) ? {} : { error: "expected object" }) };
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
return { path: candidate, config: null, error: error instanceof Error ? error.message : String(error) };
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return { path: candidates[0], config: null };
|
|
50
|
+
}
|
|
51
|
+
async function isLocalPackageEntry(root, value, packageName) {
|
|
52
|
+
if (!(path.isAbsolute(value) || value.startsWith(".")))
|
|
53
|
+
return false;
|
|
54
|
+
const packagePath = path.join(path.isAbsolute(value) ? value : path.resolve(root, value), "package.json");
|
|
55
|
+
const metadata = await readJsonObjectIfPresent(packagePath);
|
|
56
|
+
return metadata?.name === packageName;
|
|
57
|
+
}
|
|
58
|
+
async function inspectPlugin(root, metadata) {
|
|
59
|
+
const expected = pluginSpec(metadata);
|
|
60
|
+
const openCodeConfig = await readOpenCodeConfig(root);
|
|
61
|
+
const pluginValue = openCodeConfig.config?.plugin;
|
|
62
|
+
const entries = Array.isArray(pluginValue) ? pluginValue : [];
|
|
63
|
+
let configured = null;
|
|
64
|
+
let present = false;
|
|
65
|
+
for (const entry of entries) {
|
|
66
|
+
const id = pluginEntryId(entry);
|
|
67
|
+
if (id === expected || (await isLocalPackageEntry(root, id, metadata.name))) {
|
|
68
|
+
configured = id;
|
|
69
|
+
present = true;
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
if (configured === null && isLitOpenCodeEntry(entry))
|
|
73
|
+
configured = id;
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
path: openCodeConfig.path,
|
|
77
|
+
expected,
|
|
78
|
+
configured,
|
|
79
|
+
present,
|
|
80
|
+
ok: present && openCodeConfig.error === undefined,
|
|
81
|
+
...(openCodeConfig.error === undefined ? {} : { error: openCodeConfig.error })
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
export async function doctor(root) {
|
|
85
|
+
const metadata = await readPackageMetadata();
|
|
86
|
+
const loaded = await loadConfig(root);
|
|
87
|
+
const openCodeLitConfigPath = litOpenCodeConfigFileForOpenCodeRoot(root);
|
|
88
|
+
const openCodeLitConfig = await readLitOpenCodeConfigFile(openCodeLitConfigPath);
|
|
89
|
+
const effectiveOpenCodeConfig = openCodeLitConfig === undefined ? defaultGlobalConfigFile() : mergeConfigs(defaultGlobalConfigFile(), openCodeLitConfig);
|
|
90
|
+
const effectiveRoutes = effectiveAuthoredAgentRoutes(effectiveOpenCodeConfig, litOpenCodeAgents.map((agent) => agent.id));
|
|
91
|
+
const routeDiagnostics = diagnoseModelRoutes(effectiveRoutes);
|
|
92
|
+
let reportedRoutes = effectiveRoutes;
|
|
93
|
+
if (routeDiagnostics.length === 0) {
|
|
94
|
+
const projectedTarget = {};
|
|
95
|
+
registerLitOpenCodeAgents(projectedTarget, effectiveOpenCodeConfig);
|
|
96
|
+
reportedRoutes = Object.fromEntries(litOpenCodeAgents.map((agent) => [
|
|
97
|
+
agent.id,
|
|
98
|
+
projectedTarget.agent?.[agent.id] === undefined
|
|
99
|
+
? effectiveRoutes[agent.id]
|
|
100
|
+
: { ...effectiveRoutes[agent.id], ...projectedTarget.agent[agent.id] }
|
|
101
|
+
]));
|
|
102
|
+
}
|
|
103
|
+
const runtimeExists = await fs
|
|
104
|
+
.stat(loaded.paths.runtimeDir)
|
|
105
|
+
.then(() => true)
|
|
106
|
+
.catch((error) => {
|
|
107
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT")
|
|
108
|
+
return false;
|
|
109
|
+
throw error;
|
|
110
|
+
});
|
|
111
|
+
const installPlugin = await inspectPlugin(root, metadata);
|
|
112
|
+
const commandAliases = await inspectCommandAliases(root);
|
|
113
|
+
const nativeSkills = await inspectNativeSkills(root, metadata);
|
|
114
|
+
const hostConfig = await readOpenCodeConfig(root);
|
|
115
|
+
return {
|
|
116
|
+
exitCode: 0,
|
|
117
|
+
stdout: JSON.stringify({
|
|
118
|
+
package: metadata,
|
|
119
|
+
capabilities: openCodeHostCapabilities(),
|
|
120
|
+
hostLimits: { path: hostConfig.path, ...inspectHostLimits(hostConfig.config) },
|
|
121
|
+
lsp: inspectLspCapability(hostConfig.config),
|
|
122
|
+
config: {
|
|
123
|
+
source: loaded.source,
|
|
124
|
+
sources: loaded.sources,
|
|
125
|
+
path: loaded.paths.configFile,
|
|
126
|
+
enabled: loaded.config.enabled,
|
|
127
|
+
logLevel: loaded.config.logLevel,
|
|
128
|
+
knowledgeCapture: loaded.config.knowledge.capture
|
|
129
|
+
},
|
|
130
|
+
opencodeConfig: {
|
|
131
|
+
path: openCodeLitConfigPath,
|
|
132
|
+
exists: openCodeLitConfig !== undefined,
|
|
133
|
+
permissionMode: effectiveOpenCodeConfig.permissionMode,
|
|
134
|
+
agents: Object.keys(effectiveOpenCodeConfig.agents),
|
|
135
|
+
categories: Object.keys(effectiveOpenCodeConfig.categories),
|
|
136
|
+
effective: projectModelRoutesForDiagnostics(reportedRoutes, routeDiagnostics),
|
|
137
|
+
routeDiagnostics
|
|
138
|
+
},
|
|
139
|
+
state: {
|
|
140
|
+
runtimeDir: loaded.paths.runtimeDir,
|
|
141
|
+
runtimeExists,
|
|
142
|
+
stateFile: loaded.paths.stateFile,
|
|
143
|
+
logFile: loaded.paths.logFile,
|
|
144
|
+
ledgerFile: loaded.paths.ledgerFile,
|
|
145
|
+
boundedAuthority: {
|
|
146
|
+
schemaVersion: 3,
|
|
147
|
+
stateFile: loaded.paths.lifecycleStateFile,
|
|
148
|
+
eventsFile: loaded.paths.lifecycleEventsFile,
|
|
149
|
+
...loaded.config.boundedAuthority
|
|
150
|
+
},
|
|
151
|
+
knowledge: {
|
|
152
|
+
directory: loaded.paths.knowledgeDir,
|
|
153
|
+
authority: loaded.paths.knowledgeClaimsFile,
|
|
154
|
+
captureEnabled: loaded.config.knowledge.capture,
|
|
155
|
+
normalQueryBudgetBytes: 2048,
|
|
156
|
+
hardQueryLimitBytes: 4096,
|
|
157
|
+
derivedTruthFiles: false
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
autoUpdate: {
|
|
161
|
+
enabled: !isAutoUpdateDisabled(process.env),
|
|
162
|
+
installLock: autoUpdateInstallLockPath(),
|
|
163
|
+
journal: autoUpdateJournalPath(),
|
|
164
|
+
receipt: autoUpdateReceiptPath(),
|
|
165
|
+
lastReceipt: await readAutoUpdateReceipt()
|
|
166
|
+
},
|
|
167
|
+
install: {
|
|
168
|
+
ok: installPlugin.ok && commandAliases.ok && nativeSkills.ok,
|
|
169
|
+
plugin: installPlugin,
|
|
170
|
+
commandAliases,
|
|
171
|
+
nativeSkills
|
|
172
|
+
}
|
|
173
|
+
}, null, 2)
|
|
174
|
+
};
|
|
175
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type HostCapabilityStatus = "hard" | "advisory" | "unavailable";
|
|
2
|
+
export type HostCapability = {
|
|
3
|
+
readonly status: HostCapabilityStatus;
|
|
4
|
+
readonly reason: string;
|
|
5
|
+
readonly observedSource: string;
|
|
6
|
+
};
|
|
7
|
+
export type OpenCodeHostCapabilities = {
|
|
8
|
+
readonly contextCeiling372k: HostCapability;
|
|
9
|
+
readonly autoCompaction334800: HostCapability;
|
|
10
|
+
readonly subagentConcurrency20: HostCapability;
|
|
11
|
+
};
|
|
12
|
+
export declare function openCodeHostCapabilities(): OpenCodeHostCapabilities;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { compactionTriggerTokens, contextCeilingTokens } from "./host-limits.js";
|
|
2
|
+
export function openCodeHostCapabilities() {
|
|
3
|
+
const observedSource = "OpenCode 1.17.18 config schema and session overflow implementation";
|
|
4
|
+
return {
|
|
5
|
+
contextCeiling372k: {
|
|
6
|
+
status: "hard",
|
|
7
|
+
reason: "OpenCode accepts provider model input and context limits; LitOpenCode configures the exact " + contextCeilingTokens + " token ceiling.",
|
|
8
|
+
observedSource
|
|
9
|
+
},
|
|
10
|
+
autoCompaction334800: {
|
|
11
|
+
status: "hard",
|
|
12
|
+
reason: "OpenCode compacts at model input minus the reserved buffer; " +
|
|
13
|
+
contextCeilingTokens +
|
|
14
|
+
" minus 37200 yields " +
|
|
15
|
+
compactionTriggerTokens +
|
|
16
|
+
".",
|
|
17
|
+
observedSource
|
|
18
|
+
},
|
|
19
|
+
subagentConcurrency20: {
|
|
20
|
+
status: "advisory",
|
|
21
|
+
reason: "Use at most 20 concurrent subagents; OpenCode exposes no verified numeric hard-limit setting.",
|
|
22
|
+
observedSource
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export declare const contextCeilingTokens = 372000;
|
|
2
|
+
export declare const compactionTriggerTokens = 334800;
|
|
3
|
+
export declare const compactionReserveTokens: number;
|
|
4
|
+
export declare const offeredGpt56Models: readonly ["gpt-5.6-luna"];
|
|
5
|
+
export type HostLimitMutation = {
|
|
6
|
+
readonly reconfigure: boolean;
|
|
7
|
+
readonly changed: boolean;
|
|
8
|
+
readonly contextCeilingTokens: number;
|
|
9
|
+
readonly compactionTriggerTokens: number;
|
|
10
|
+
readonly compactionReserveTokens: number;
|
|
11
|
+
};
|
|
12
|
+
export type HostLimitState = {
|
|
13
|
+
readonly status: "configured" | "unconfigured";
|
|
14
|
+
readonly contextCeilingTokens: number;
|
|
15
|
+
readonly compactionTriggerTokens: number;
|
|
16
|
+
readonly compactionReserveTokens: number;
|
|
17
|
+
};
|
|
18
|
+
export declare function applyHostLimits(config: Record<string, unknown> | null): Record<string, unknown>;
|
|
19
|
+
export declare function describeHostLimitMutation(config: Record<string, unknown> | null, reconfigure: boolean): HostLimitMutation;
|
|
20
|
+
export declare function inspectHostLimits(config: Record<string, unknown> | null): HostLimitState;
|
|
21
|
+
export declare function ensureHostLimits(configPath: string, config: Record<string, unknown> | null, reconfigure: boolean): Promise<void>;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { isRecord } from "./json.js";
|
|
2
|
+
import { writeTextAtomically } from "./install-config.js";
|
|
3
|
+
import fs from "node:fs/promises";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
export const contextCeilingTokens = 372000;
|
|
6
|
+
export const compactionTriggerTokens = 334800;
|
|
7
|
+
export const compactionReserveTokens = contextCeilingTokens - compactionTriggerTokens;
|
|
8
|
+
export const offeredGpt56Models = ["gpt-5.6-luna"];
|
|
9
|
+
class HostConfigShapeError extends Error {
|
|
10
|
+
path;
|
|
11
|
+
constructor(path) {
|
|
12
|
+
super("Malformed OpenCode host config: " + path + " must be an object.");
|
|
13
|
+
this.name = "HostConfigShapeError";
|
|
14
|
+
this.path = path;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function optionalRecord(value, path) {
|
|
18
|
+
if (value === undefined)
|
|
19
|
+
return {};
|
|
20
|
+
if (isRecord(value))
|
|
21
|
+
return value;
|
|
22
|
+
throw new HostConfigShapeError(path);
|
|
23
|
+
}
|
|
24
|
+
function modelLimit() {
|
|
25
|
+
return {
|
|
26
|
+
context: contextCeilingTokens,
|
|
27
|
+
input: contextCeilingTokens,
|
|
28
|
+
output: 128000
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export function applyHostLimits(config) {
|
|
32
|
+
const current = config ?? { "$schema": "https://opencode.ai/config.json" };
|
|
33
|
+
const provider = optionalRecord(current.provider, "provider");
|
|
34
|
+
const openai = optionalRecord(provider.openai, "provider.openai");
|
|
35
|
+
const models = optionalRecord(openai.models, "provider.openai.models");
|
|
36
|
+
const nextModels = { ...models };
|
|
37
|
+
for (const model of offeredGpt56Models) {
|
|
38
|
+
const currentModel = optionalRecord(models[model], "provider.openai.models." + model);
|
|
39
|
+
const limit = optionalRecord(currentModel.limit, "provider.openai.models." + model + ".limit");
|
|
40
|
+
nextModels[model] = { ...currentModel, limit: { ...limit, ...modelLimit() } };
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
...current,
|
|
44
|
+
compaction: { ...optionalRecord(current.compaction, "compaction"), auto: true, reserved: compactionReserveTokens },
|
|
45
|
+
provider: { ...provider, openai: { ...openai, models: nextModels } }
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export function describeHostLimitMutation(config, reconfigure) {
|
|
49
|
+
if (!reconfigure) {
|
|
50
|
+
return {
|
|
51
|
+
reconfigure,
|
|
52
|
+
changed: false,
|
|
53
|
+
contextCeilingTokens,
|
|
54
|
+
compactionTriggerTokens,
|
|
55
|
+
compactionReserveTokens
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
reconfigure,
|
|
60
|
+
changed: JSON.stringify(config) !== JSON.stringify(applyHostLimits(config)),
|
|
61
|
+
contextCeilingTokens,
|
|
62
|
+
compactionTriggerTokens,
|
|
63
|
+
compactionReserveTokens
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
export function inspectHostLimits(config) {
|
|
67
|
+
const next = applyHostLimits(config);
|
|
68
|
+
return {
|
|
69
|
+
status: JSON.stringify(config) === JSON.stringify(next) ? "configured" : "unconfigured",
|
|
70
|
+
contextCeilingTokens,
|
|
71
|
+
compactionTriggerTokens,
|
|
72
|
+
compactionReserveTokens
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
export async function ensureHostLimits(configPath, config, reconfigure) {
|
|
76
|
+
if (!reconfigure)
|
|
77
|
+
return;
|
|
78
|
+
const next = applyHostLimits(config);
|
|
79
|
+
if (JSON.stringify(config) === JSON.stringify(next))
|
|
80
|
+
return;
|
|
81
|
+
await fs.mkdir(path.dirname(configPath), { recursive: true });
|
|
82
|
+
await writeTextAtomically(configPath, JSON.stringify(next, null, 2) + "\n");
|
|
83
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { InstallModelSelection, InstallPermissionMode, InstallReport, ModelConfigClassification } from "./types.ts";
|
|
2
|
+
type AtomicWriteOverrides = {
|
|
3
|
+
readonly rename?: (from: string, to: string) => Promise<void>;
|
|
4
|
+
};
|
|
5
|
+
export declare function writeTextAtomically(filePath: string, text: string, overrides?: AtomicWriteOverrides): Promise<void>;
|
|
6
|
+
export declare function readInstallModelClassification(root: string): Promise<ModelConfigClassification>;
|
|
7
|
+
export declare function readInstallModelSelection(root: string): Promise<InstallModelSelection | undefined>;
|
|
8
|
+
export declare function assertExistingModelRoutesSafe(root: string): Promise<void>;
|
|
9
|
+
export declare function describeInstallRoutes(root: string, hostConfig: Record<string, unknown> | null, selection: InstallModelSelection | undefined, permissionMode: InstallPermissionMode, permissionModeExplicit: boolean, outputStyle: string): Promise<NonNullable<InstallReport["routes"]>>;
|
|
10
|
+
export declare function readExistingOutputStyle(root: string): Promise<string>;
|
|
11
|
+
export declare function describeLitConfigMutation(root: string, selection: InstallModelSelection | undefined, permissionMode: InstallPermissionMode, permissionModeExplicit: boolean, outputStyle?: string): Promise<InstallReport["litopencodeConfig"]>;
|
|
12
|
+
export declare function ensureLitConfig(root: string, selection: InstallModelSelection | undefined, permissionMode: InstallPermissionMode, permissionModeExplicit: boolean, outputStyle?: string): Promise<void>;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { litOpenCodeAgents, registerLitOpenCodeAgents } from "../agents.js";
|
|
5
|
+
import { defaultGlobalConfigFile, defaultGlobalConfigJson, mergeConfigs, readLitOpenCodeConfigFile } from "../config.js";
|
|
6
|
+
import { diagnoseModelRoutes, effectiveAuthoredAgentRoutes, UnsafeModelRouteError } from "../model-route-policy.js";
|
|
7
|
+
import { litOpenCodeConfigFileForOpenCodeRoot } from "../state.js";
|
|
8
|
+
import { isRecord, readJsonObjectIfPresent } from "./json.js";
|
|
9
|
+
import { isModelProvider, modelMenuRows, stripFastSuffix } from "./model-catalog.js";
|
|
10
|
+
import { classifyModelConfig, selectedLitConfig } from "./model-policy.js";
|
|
11
|
+
export async function writeTextAtomically(filePath, text, overrides = {}) {
|
|
12
|
+
const tempPath = path.join(path.dirname(filePath), "." + path.basename(filePath) + ".tmp-" + randomUUID());
|
|
13
|
+
try {
|
|
14
|
+
await fs.writeFile(tempPath, text, { encoding: "utf8", flag: "wx", mode: 0o600 });
|
|
15
|
+
await (overrides.rename ?? fs.rename)(tempPath, filePath);
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
await fs.rm(tempPath, { force: true });
|
|
19
|
+
throw error;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
async function readValidatedConfig(root) {
|
|
23
|
+
const filePath = litOpenCodeConfigFileForOpenCodeRoot(root);
|
|
24
|
+
if ((await readLitOpenCodeConfigFile(filePath)) === undefined)
|
|
25
|
+
return null;
|
|
26
|
+
return await readJsonObjectIfPresent(filePath);
|
|
27
|
+
}
|
|
28
|
+
function sameJson(left, right) {
|
|
29
|
+
return left !== null && JSON.stringify(left) === JSON.stringify(right);
|
|
30
|
+
}
|
|
31
|
+
function uniformExistingVariant(config) {
|
|
32
|
+
if (config === null || !isRecord(config.categories))
|
|
33
|
+
return undefined;
|
|
34
|
+
const variants = Object.values(config.categories).map((category) => isRecord(category) && typeof category.variant === "string" ? category.variant : undefined);
|
|
35
|
+
const first = variants[0];
|
|
36
|
+
return first !== undefined && variants.every((variant) => variant === first) ? first : undefined;
|
|
37
|
+
}
|
|
38
|
+
export async function readInstallModelClassification(root) {
|
|
39
|
+
return classifyModelConfig(await readValidatedConfig(root));
|
|
40
|
+
}
|
|
41
|
+
const installCategories = ["planning", "execution", "review", "research"];
|
|
42
|
+
const installEfforts = ["low", "medium", "high", "xhigh", "max"];
|
|
43
|
+
function existingInstallRoute(value) {
|
|
44
|
+
if (!isRecord(value) || typeof value.provider !== "string" || !isModelProvider(value.provider))
|
|
45
|
+
return undefined;
|
|
46
|
+
if (typeof value.model !== "string" || value.model.includes("/") || value.reasoningEffort !== undefined)
|
|
47
|
+
return undefined;
|
|
48
|
+
const model = value.provider === "openai" ? stripFastSuffix(value.model) : value.model;
|
|
49
|
+
const row = modelMenuRows(value.provider).find((candidate) => candidate.model === model);
|
|
50
|
+
if (row === undefined)
|
|
51
|
+
return undefined;
|
|
52
|
+
if (value.variant === undefined)
|
|
53
|
+
return { provider: value.provider, model: value.model };
|
|
54
|
+
if (typeof value.variant !== "string" || !installEfforts.includes(value.variant))
|
|
55
|
+
return undefined;
|
|
56
|
+
if (!row.efforts.includes(value.variant))
|
|
57
|
+
return undefined;
|
|
58
|
+
return { provider: value.provider, model: value.model, effort: value.variant };
|
|
59
|
+
}
|
|
60
|
+
function sameInstallRoute(left, right) {
|
|
61
|
+
return left.provider === right.provider && left.model === right.model && left.effort === right.effort;
|
|
62
|
+
}
|
|
63
|
+
export async function readInstallModelSelection(root) {
|
|
64
|
+
const existing = await readValidatedConfig(root);
|
|
65
|
+
if (existing === null)
|
|
66
|
+
return undefined;
|
|
67
|
+
const categories = existing.categories;
|
|
68
|
+
if (!isRecord(categories))
|
|
69
|
+
return undefined;
|
|
70
|
+
const routes = installCategories.map((category) => existingInstallRoute(categories[category]));
|
|
71
|
+
const [planning, execution, review, research] = routes;
|
|
72
|
+
if (planning === undefined || execution === undefined || review === undefined || research === undefined)
|
|
73
|
+
return undefined;
|
|
74
|
+
if (!sameInstallRoute(planning, review) || !sameInstallRoute(execution, research))
|
|
75
|
+
return undefined;
|
|
76
|
+
return { ...planning, helper: execution };
|
|
77
|
+
}
|
|
78
|
+
export async function assertExistingModelRoutesSafe(root) {
|
|
79
|
+
const existing = await readValidatedConfig(root);
|
|
80
|
+
if (existing === null)
|
|
81
|
+
return;
|
|
82
|
+
const config = mergeConfigs(defaultGlobalConfigFile(), existing);
|
|
83
|
+
const diagnostics = diagnoseModelRoutes(effectiveAuthoredAgentRoutes(config, Object.keys(config.agents)));
|
|
84
|
+
if (diagnostics.length > 0)
|
|
85
|
+
throw new UnsafeModelRouteError(diagnostics);
|
|
86
|
+
}
|
|
87
|
+
function hostAgents(value) {
|
|
88
|
+
if (value === undefined)
|
|
89
|
+
return {};
|
|
90
|
+
if (!isRecord(value))
|
|
91
|
+
throw new Error("Malformed OpenCode host config: agent must be an object.");
|
|
92
|
+
const agents = {};
|
|
93
|
+
for (const [agentId, agent] of Object.entries(value)) {
|
|
94
|
+
if (!isRecord(agent))
|
|
95
|
+
throw new Error(`Malformed OpenCode host config: agent.${agentId} must be an object.`);
|
|
96
|
+
agents[agentId] = agent;
|
|
97
|
+
}
|
|
98
|
+
return agents;
|
|
99
|
+
}
|
|
100
|
+
function sameJsonValue(left, right) {
|
|
101
|
+
return JSON.stringify(left) === JSON.stringify(right);
|
|
102
|
+
}
|
|
103
|
+
function projectedRoute(agentId, value) {
|
|
104
|
+
if (!isRecord(value))
|
|
105
|
+
throw new Error(`Unsafe installer route: managed agent ${agentId} is not an object.`);
|
|
106
|
+
return {
|
|
107
|
+
agentId,
|
|
108
|
+
...(typeof value.model === "string" ? { model: value.model } : {}),
|
|
109
|
+
...(typeof value.variant === "string" ? { variant: value.variant } : {}),
|
|
110
|
+
...(typeof value.reasoningEffort === "string" ? { reasoningEffort: value.reasoningEffort } : {}),
|
|
111
|
+
status: "configured"
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
export async function describeInstallRoutes(root, hostConfig, selection, permissionMode, permissionModeExplicit, outputStyle) {
|
|
115
|
+
const existing = await readValidatedConfig(root);
|
|
116
|
+
const selected = selectedLitConfig(existing, selection, permissionMode, permissionModeExplicit, outputStyle);
|
|
117
|
+
const effective = mergeConfigs(defaultGlobalConfigFile(), selected);
|
|
118
|
+
const existingAgents = hostAgents(hostConfig?.agent);
|
|
119
|
+
const target = { agent: { ...existingAgents } };
|
|
120
|
+
registerLitOpenCodeAgents(target, effective);
|
|
121
|
+
const registeredAgents = target.agent;
|
|
122
|
+
if (!isRecord(registeredAgents))
|
|
123
|
+
throw new Error("Unsafe installer route: registered agent map is malformed.");
|
|
124
|
+
const managed = Object.fromEntries(litOpenCodeAgents.map((agent) => [agent.id, projectedRoute(agent.id, registeredAgents[agent.id])]));
|
|
125
|
+
const preservedAgents = Object.entries(existingAgents)
|
|
126
|
+
.filter(([agentId, agent]) => sameJsonValue(agent, registeredAgents[agentId]))
|
|
127
|
+
.map(([agentId]) => agentId);
|
|
128
|
+
const planningAgent = registeredAgents["lit-plan"];
|
|
129
|
+
const planningPermissions = isRecord(planningAgent) ? planningAgent.permission : undefined;
|
|
130
|
+
const planningTools = isRecord(planningAgent) ? planningAgent.tools : undefined;
|
|
131
|
+
if (!isRecord(planningAgent) ||
|
|
132
|
+
!isRecord(planningPermissions) ||
|
|
133
|
+
planningPermissions.edit !== "deny" ||
|
|
134
|
+
planningPermissions.bash !== "deny" ||
|
|
135
|
+
planningPermissions.task !== "deny" ||
|
|
136
|
+
!isRecord(planningTools) ||
|
|
137
|
+
planningTools.write !== false ||
|
|
138
|
+
planningTools.edit !== false ||
|
|
139
|
+
planningTools.bash !== false ||
|
|
140
|
+
planningTools.task !== false) {
|
|
141
|
+
throw new Error("Unsafe installer route: lit-plan planning-only permissions are not enforced.");
|
|
142
|
+
}
|
|
143
|
+
return {
|
|
144
|
+
managed,
|
|
145
|
+
preservedAgents,
|
|
146
|
+
planningOnly: {
|
|
147
|
+
agentId: "lit-plan",
|
|
148
|
+
permissions: { edit: "deny", bash: "deny", task: "deny" },
|
|
149
|
+
tools: { write: false, edit: false, bash: false, task: false }
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
export async function readExistingOutputStyle(root) {
|
|
154
|
+
const config = await readValidatedConfig(root);
|
|
155
|
+
const style = config?.outputStyle;
|
|
156
|
+
return typeof style === "string" ? style : "off";
|
|
157
|
+
}
|
|
158
|
+
export async function describeLitConfigMutation(root, selection, permissionMode, permissionModeExplicit, outputStyle = "off") {
|
|
159
|
+
const filePath = litOpenCodeConfigFileForOpenCodeRoot(root);
|
|
160
|
+
const existing = await readValidatedConfig(root);
|
|
161
|
+
const defaults = defaultGlobalConfigJson();
|
|
162
|
+
const selected = selectedLitConfig(existing, selection, permissionMode, permissionModeExplicit, outputStyle);
|
|
163
|
+
const existingPermissionMode = existing?.permissionMode === "balanced" || existing?.permissionMode === "yolo" ? existing.permissionMode : "safe";
|
|
164
|
+
const existingOutputStyle = typeof existing?.outputStyle === "string" ? existing.outputStyle : "off";
|
|
165
|
+
const modelChanged = selection !== undefined && !sameJson(existing, selected);
|
|
166
|
+
const permissionChanged = permissionModeExplicit
|
|
167
|
+
? existingPermissionMode !== permissionMode
|
|
168
|
+
: permissionMode !== "safe" && existingPermissionMode !== permissionMode;
|
|
169
|
+
const outputStyleChanged = outputStyle !== "off" && existingOutputStyle !== outputStyle;
|
|
170
|
+
const existingVariant = uniformExistingVariant(existing);
|
|
171
|
+
return {
|
|
172
|
+
path: filePath,
|
|
173
|
+
alreadyPresent: existing !== null,
|
|
174
|
+
changed: existing === null || modelChanged || permissionChanged || outputStyleChanged,
|
|
175
|
+
agents: isRecord(defaults.agents) ? Object.keys(defaults.agents) : [],
|
|
176
|
+
categories: isRecord(defaults.categories) ? Object.keys(defaults.categories) : [],
|
|
177
|
+
model: {
|
|
178
|
+
...(selection ?? {}),
|
|
179
|
+
classification: classifyModelConfig(existing),
|
|
180
|
+
...(existingVariant === undefined ? {} : { existingVariant }),
|
|
181
|
+
changed: modelChanged
|
|
182
|
+
},
|
|
183
|
+
permissionMode: {
|
|
184
|
+
mode: permissionModeExplicit || permissionMode !== "safe" ? permissionMode : existingPermissionMode,
|
|
185
|
+
changed: permissionChanged
|
|
186
|
+
},
|
|
187
|
+
outputStyle: {
|
|
188
|
+
style: outputStyle !== "off" ? outputStyle : existingOutputStyle,
|
|
189
|
+
changed: outputStyleChanged
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
export async function ensureLitConfig(root, selection, permissionMode, permissionModeExplicit, outputStyle = "off") {
|
|
194
|
+
const filePath = litOpenCodeConfigFileForOpenCodeRoot(root);
|
|
195
|
+
const existing = await readValidatedConfig(root);
|
|
196
|
+
const next = selectedLitConfig(existing, selection, permissionMode, permissionModeExplicit, outputStyle);
|
|
197
|
+
if (sameJson(existing, next))
|
|
198
|
+
return;
|
|
199
|
+
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
200
|
+
await writeTextAtomically(filePath, JSON.stringify(next, null, 2) + "\n");
|
|
201
|
+
}
|