@ultrakit/ultrakit 0.0.0 → 0.0.2
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/README.md +84 -25
- package/dist/index.js +837 -426
- package/dist/template/{.opencode → opencode}/.env.example +25 -7
- package/dist/template/{.opencode → opencode}/AGENTS.md +52 -12
- package/dist/template/opencode/AGENT_ALIGNMENT.md +87 -0
- package/dist/template/opencode/README.md +116 -0
- package/dist/template/{.opencode → opencode}/agent/build.md +29 -0
- package/dist/template/opencode/agent/debugger.md +150 -0
- package/dist/template/{.opencode → opencode}/agent/plan.md +14 -3
- package/dist/template/{.opencode → opencode}/agent/review.md +16 -2
- package/dist/template/{.opencode → opencode}/agent/scout.md +4 -3
- package/dist/template/opencode/agent/verify.md +152 -0
- package/dist/template/opencode/command/cleanup.md +270 -0
- package/dist/template/{.opencode → opencode}/command/create.md +23 -22
- package/dist/template/{.opencode → opencode}/command/handoff.md +26 -0
- package/dist/template/{.opencode → opencode}/command/health.md +1 -1
- package/dist/template/{.opencode/command/explore.md → opencode/command/ideate.md} +3 -3
- package/dist/template/opencode/command/init-deep.md +368 -0
- package/dist/template/{.opencode → opencode}/command/lfg.md +23 -4
- package/dist/template/{.opencode → opencode}/command/plan.md +5 -4
- package/dist/template/{.opencode → opencode}/command/pr.md +24 -1
- package/dist/template/{.opencode → opencode}/command/research.md +8 -2
- package/dist/template/{.opencode → opencode}/command/resume.md +32 -0
- package/dist/template/{.opencode → opencode}/command/ship.md +19 -0
- package/dist/template/{.opencode → opencode}/command/status.md +24 -0
- package/dist/template/{.opencode → opencode}/command/ui-review.md +0 -1
- package/dist/template/{.opencode → opencode}/command/ui-slop-check.md +0 -1
- package/dist/template/{.opencode → opencode}/command/verify.md +1 -1
- package/dist/template/{.opencode → opencode}/dcp.jsonc +5 -2
- package/dist/template/{.opencode → opencode}/memory/README.md +14 -6
- package/dist/template/{.opencode/memory/project → opencode/memory/_templates}/gotchas.md +5 -1
- package/dist/template/opencode/memory/compiled/architecture.md +44 -0
- package/dist/template/opencode/memory/compiled/decisions.md +36 -0
- package/dist/template/opencode/memory/compiled/gotchas.md +36 -0
- package/dist/template/opencode/memory/compiled/workflows.md +35 -0
- package/dist/template/opencode/memory/project/gotchas.md +71 -0
- package/dist/template/opencode/memory/project/project.md +46 -0
- package/dist/template/opencode/memory/project/roadmap.md +88 -0
- package/dist/template/opencode/memory/project/state.md +69 -0
- package/dist/template/opencode/memory/project/tech-stack.md +68 -0
- package/dist/template/opencode/memory/project/user.md +41 -0
- package/dist/template/opencode/opencode.json +1033 -0
- package/dist/template/{.opencode → opencode}/package.json +3 -3
- package/dist/template/{.opencode → opencode}/plugin/lib/context.ts +2 -1
- package/dist/template/{.opencode → opencode}/plugin/lib/db/schema.ts +27 -0
- package/dist/template/{.opencode → opencode}/plugin/lib/inject.ts +5 -1
- package/dist/template/{.opencode → opencode}/plugin/lib/memory-db.ts +1 -1
- package/dist/template/{.opencode → opencode}/plugin/lib/memory-hooks.ts +14 -0
- package/dist/template/{.opencode → opencode}/plugin/lib/memory-tools.ts +112 -32
- package/dist/template/{.opencode → opencode}/skill/agent-evals/SKILL.md +11 -6
- package/dist/template/{.opencode → opencode}/skill/anti-ai-slop/SKILL.md +15 -0
- package/dist/template/{.opencode → opencode}/skill/api-and-interface-design/SKILL.md +1 -1
- package/dist/template/{.opencode → opencode}/skill/brand-asset-protocol/SKILL.md +9 -0
- package/dist/template/{.opencode → opencode}/skill/code-search-patterns/SKILL.md +1 -1
- package/dist/template/{.opencode → opencode}/skill/code-simplification/SKILL.md +14 -2
- package/dist/template/opencode/skill/codemap/SKILL.md +166 -0
- package/dist/template/opencode/skill/codemap/scripts/codemap.mjs +75 -0
- package/dist/template/{.opencode → opencode}/skill/context-condensation/SKILL.md +9 -0
- package/dist/template/{.opencode → opencode}/skill/context-management/SKILL.md +2 -2
- package/dist/template/{.opencode → opencode}/skill/deep-research/SKILL.md +8 -1
- package/dist/template/{.opencode → opencode}/skill/deprecation-and-migration/SKILL.md +1 -1
- package/dist/template/{.opencode → opencode}/skill/design-direction-advisor/SKILL.md +9 -2
- package/dist/template/{.opencode → opencode}/skill/design-system-audit/SKILL.md +2 -2
- package/dist/template/{.opencode → opencode}/skill/design-taste-frontend/SKILL.md +3 -0
- package/dist/template/{.opencode → opencode}/skill/development-lifecycle/SKILL.md +1 -10
- package/dist/template/{.opencode → opencode}/skill/executing-plans/SKILL.md +3 -3
- package/dist/template/{.opencode → opencode}/skill/figma-go/SKILL.md +1 -1
- package/dist/template/{.opencode → opencode}/skill/finishing-a-development-branch/SKILL.md +25 -8
- package/dist/template/{.opencode → opencode}/skill/full-output-enforcement/SKILL.md +3 -0
- package/dist/template/{.opencode → opencode}/skill/gh-fix-ci/scripts/inspect_pr_checks.py +0 -0
- package/dist/template/{.opencode → opencode}/skill/hi-fi-prototype-html/SKILL.md +11 -6
- package/dist/template/{.opencode → opencode}/skill/high-end-visual-design/SKILL.md +3 -0
- package/dist/template/{.opencode → opencode}/skill/html-deck-export/SKILL.md +15 -0
- package/dist/template/{.opencode → opencode}/skill/incremental-implementation/SKILL.md +2 -2
- package/dist/template/{.opencode → opencode}/skill/industrial-brutalist-ui/SKILL.md +3 -0
- package/dist/template/{.opencode → opencode}/skill/memory-grounding/SKILL.md +2 -1
- package/dist/template/{.opencode → opencode}/skill/minimalist-ui/SKILL.md +3 -0
- package/dist/template/{.opencode → opencode}/skill/performance-optimization/SKILL.md +1 -1
- package/dist/template/{.opencode → opencode}/skill/prd-task/SKILL.md +1 -1
- package/dist/template/{.opencode → opencode}/skill/prompt-leverage/SKILL.md +13 -2
- package/dist/template/{.opencode → opencode}/skill/reconcile/SKILL.md +2 -2
- package/dist/template/{.opencode → opencode}/skill/redesign-existing-projects/SKILL.md +3 -0
- package/dist/template/{.opencode → opencode}/skill/reflection-checkpoints/SKILL.md +2 -2
- package/dist/template/opencode/skill/research-tool-routing/SKILL.md +121 -0
- package/dist/template/{.opencode → opencode}/skill/root-cause-tracing/find-polluter.sh +0 -0
- package/dist/template/{.opencode → opencode}/skill/skill-installer/scripts/install-skill-from-github.py +0 -0
- package/dist/template/{.opencode → opencode}/skill/skill-installer/scripts/list-skills.py +0 -0
- package/dist/template/{.opencode → opencode}/skill/vercel-deploy-claimable/scripts/deploy.sh +0 -0
- package/dist/template/{.opencode → opencode}/skill/verification-before-completion/references/VERIFICATION_PROTOCOL.md +12 -5
- package/dist/template/{.opencode → opencode}/skill/verification-gates/SKILL.md +2 -1
- package/dist/template/{.opencode → opencode}/skill/webclaw/SKILL.md +12 -0
- package/dist/template/opencode/skill/workspace-setup/SKILL.md +139 -0
- package/package.json +14 -7
- package/dist/template/.opencode/.template-manifest.json +0 -718
- package/dist/template/.opencode/.version +0 -1
- package/dist/template/.opencode/AGENT_ALIGNMENT.md +0 -564
- package/dist/template/.opencode/README.md +0 -79
- package/dist/template/.opencode/memory/project/project.md +0 -92
- package/dist/template/.opencode/memory/project/roadmap.md +0 -142
- package/dist/template/.opencode/memory/project/state.md +0 -84
- package/dist/template/.opencode/memory/project/tech-stack.md +0 -53
- package/dist/template/.opencode/memory/project/user.md +0 -45
- package/dist/template/.opencode/memory/research/benchmark-framework.md +0 -162
- package/dist/template/.opencode/memory/research/ccpm-analysis.md +0 -334
- package/dist/template/.opencode/memory/research/context-management-analysis.md +0 -685
- package/dist/template/.opencode/memory/research/effectiveness-audit.md +0 -213
- package/dist/template/.opencode/memory/research/opencode-mcp-bug-report.md +0 -129
- package/dist/template/.opencode/memory/research/openspec-analysis.md +0 -226
- package/dist/template/.opencode/memory/session-context.md +0 -40
- package/dist/template/.opencode/opencode.json +0 -1148
- package/dist/template/.opencode/plugin/package.json +0 -7
- package/dist/template/.opencode/skill/opensrc/SKILL.md +0 -284
- package/dist/template/.opencode/skill/opensrc/references/architecture.md +0 -176
- package/dist/template/.opencode/skill/opensrc/references/cli-usage.md +0 -176
- package/dist/template/.opencode/skill/opensrc/references/registry-support.md +0 -137
- package/dist/template/.opencode/skill/workspace-setup/SKILL.md +0 -76
- /package/dist/template/{.opencode → opencode}/agent/explore.md +0 -0
- /package/dist/template/{.opencode → opencode}/agent/general.md +0 -0
- /package/dist/template/{.opencode → opencode}/agent/painter.md +0 -0
- /package/dist/template/{.opencode → opencode}/agent/vision.md +0 -0
- /package/dist/template/{.opencode → opencode}/command/compound.md +0 -0
- /package/dist/template/{.opencode → opencode}/command/curate.md +0 -0
- /package/dist/template/{.opencode → opencode}/command/design.md +0 -0
- /package/dist/template/{.opencode → opencode}/command/init-context.md +0 -0
- /package/dist/template/{.opencode → opencode}/command/init-user.md +0 -0
- /package/dist/template/{.opencode → opencode}/command/init.md +0 -0
- /package/dist/template/{.opencode → opencode}/command/iterate.md +0 -0
- /package/dist/template/{.opencode → opencode}/command/review-codebase.md +0 -0
- /package/dist/template/{.opencode → opencode}/context/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/context/git-context.md +0 -0
- /package/dist/template/{.opencode → opencode}/dcp-prompts/defaults/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/dcp-prompts/defaults/compress-message.md +0 -0
- /package/dist/template/{.opencode → opencode}/dcp-prompts/defaults/compress-range.md +0 -0
- /package/dist/template/{.opencode → opencode}/dcp-prompts/defaults/context-limit-nudge.md +0 -0
- /package/dist/template/{.opencode → opencode}/dcp-prompts/defaults/iteration-nudge.md +0 -0
- /package/dist/template/{.opencode → opencode}/dcp-prompts/defaults/system.md +0 -0
- /package/dist/template/{.opencode → opencode}/dcp-prompts/defaults/turn-nudge.md +0 -0
- /package/dist/template/{.opencode → opencode}/dcp-prompts/overrides/compress-message.md +0 -0
- /package/dist/template/{.opencode → opencode}/memory/_templates/design.md +0 -0
- /package/dist/template/{.opencode → opencode}/memory/_templates/prd.md +0 -0
- /package/dist/template/{.opencode → opencode}/memory/_templates/project.md +0 -0
- /package/dist/template/{.opencode → opencode}/memory/_templates/proposal.md +0 -0
- /package/dist/template/{.opencode → opencode}/memory/_templates/roadmap.md +0 -0
- /package/dist/template/{.opencode → opencode}/memory/_templates/state.md +0 -0
- /package/dist/template/{.opencode → opencode}/memory/_templates/tasks.md +0 -0
- /package/dist/template/{.opencode → opencode}/memory/_templates/tech-stack.md +0 -0
- /package/dist/template/{.opencode → opencode}/memory/_templates/user.md +0 -0
- /package/dist/template/{.opencode → opencode}/opencodex-fast.jsonc +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/copilot-auth.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/lib/capture.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/lib/compact.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/lib/compile.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/lib/curator.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/lib/db/graph.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/lib/db/maintenance.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/lib/db/observations.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/lib/db/pipeline.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/lib/db/types.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/lib/distill.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/lib/index-generator.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/lib/lint.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/lib/memory-admin-tools.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/lib/memory-helpers.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/lib/notify.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/lib/operation-log.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/lib/validate.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/memory.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/prompt-leverage.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/rtk.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/sdk/copilot/chat/convert-to-openai-compatible-chat-messages.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/sdk/copilot/chat/get-response-metadata.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/sdk/copilot/chat/map-openai-compatible-finish-reason.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/sdk/copilot/chat/openai-compatible-api-types.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/sdk/copilot/chat/openai-compatible-chat-language-model.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/sdk/copilot/chat/openai-compatible-chat-options.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/sdk/copilot/chat/openai-compatible-metadata-extractor.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/sdk/copilot/chat/openai-compatible-prepare-tools.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/sdk/copilot/copilot-provider.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/sdk/copilot/index.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/sdk/copilot/openai-compatible-error.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/sdk/copilot/responses/convert-to-openai-responses-input.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/sdk/copilot/responses/map-openai-responses-finish-reason.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/sdk/copilot/responses/openai-config.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/sdk/copilot/responses/openai-error.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/sdk/copilot/responses/openai-responses-api-types.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/sdk/copilot/responses/openai-responses-language-model.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/sdk/copilot/responses/openai-responses-prepare-tools.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/sdk/copilot/responses/openai-responses-settings.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/sdk/copilot/responses/tool/code-interpreter.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/sdk/copilot/responses/tool/file-search.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/sdk/copilot/responses/tool/image-generation.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/sdk/copilot/responses/tool/local-shell.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/sdk/copilot/responses/tool/web-search-preview.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/sdk/copilot/responses/tool/web-search.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/sessions.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/skill-mcp.ts +0 -0
- /package/dist/template/{.opencode → opencode}/plugin/tsconfig.json +0 -0
- /package/dist/template/{.opencode → opencode}/skill/accessibility-audit/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/agent-teams/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/augment-context-engine/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/augment-context-engine/mcp.json +0 -0
- /package/dist/template/{.opencode → opencode}/skill/beads/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/beads/references/BEST_PRACTICES.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/beads/references/BOUNDARIES.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/beads/references/DEPENDENCIES.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/beads/references/EXAMPLES.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/beads/references/FILE_CLAIMING.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/beads/references/GIT_SYNC.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/beads/references/HIERARCHY.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/beads/references/MULTI_AGENT.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/beads/references/RESUMABILITY.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/beads/references/SESSION_PROTOCOL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/beads/references/TASK_CREATION.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/beads/references/TROUBLESHOOTING.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/beads/references/WORKFLOWS.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/brainstorming/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/chrome-devtools/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/chrome-devtools/mcp.json +0 -0
- /package/dist/template/{.opencode → opencode}/skill/ci-cd-and-automation/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/agents-sdk/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/agents-sdk/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/agents-sdk/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/agents-sdk/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/agents-sdk/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/ai-gateway/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/ai-search/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/ai-search/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/ai-search/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/ai-search/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/ai-search/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/analytics-engine/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/analytics-engine/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/analytics-engine/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/analytics-engine/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/analytics-engine/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/api/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/api/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/api/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/api/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/api/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/api-shield/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/api-shield/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/api-shield/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/api-shield/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/api-shield/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/argo-smart-routing/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/argo-smart-routing/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/argo-smart-routing/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/argo-smart-routing/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/argo-smart-routing/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/bindings/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/bindings/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/bindings/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/bindings/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/bindings/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/bot-management/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/bot-management/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/bot-management/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/bot-management/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/bot-management/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/browser-rendering/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/browser-rendering/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/browser-rendering/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/browser-rendering/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/browser-rendering/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/c3/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/cache-reserve/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/cache-reserve/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/cache-reserve/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/cache-reserve/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/cache-reserve/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/containers/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/containers/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/containers/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/containers/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/containers/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/cron-triggers/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/cron-triggers/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/cron-triggers/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/cron-triggers/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/cron-triggers/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/d1/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/d1/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/d1/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/d1/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/d1/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/ddos/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/ddos/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/ddos/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/ddos/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/ddos/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/do-storage/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/do-storage/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/do-storage/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/do-storage/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/do-storage/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/durable-objects/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/durable-objects/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/durable-objects/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/durable-objects/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/durable-objects/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/email-routing/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/email-routing/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/email-routing/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/email-routing/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/email-routing/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/email-workers/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/hyperdrive/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/hyperdrive/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/hyperdrive/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/hyperdrive/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/hyperdrive/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/images/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/images/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/images/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/images/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/images/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/kv/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/kv/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/kv/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/kv/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/kv/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/miniflare/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/miniflare/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/miniflare/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/miniflare/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/miniflare/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/network-interconnect/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/network-interconnect/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/network-interconnect/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/network-interconnect/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/network-interconnect/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/observability/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/observability/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/observability/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/observability/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/observability/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/pages/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/pages/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/pages/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/pages/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/pages/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/pages-functions/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/pages-functions/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/pages-functions/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/pages-functions/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/pages-functions/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/pipelines/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/pulumi/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/pulumi/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/pulumi/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/pulumi/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/pulumi/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/queues/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/queues/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/queues/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/queues/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/queues/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/r2/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/r2/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/r2/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/r2/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/r2/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/r2-data-catalog/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/r2-data-catalog/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/r2-data-catalog/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/r2-data-catalog/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/r2-data-catalog/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/r2-sql/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/realtime-sfu/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/realtime-sfu/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/realtime-sfu/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/realtime-sfu/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/realtime-sfu/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/realtimekit/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/realtimekit/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/realtimekit/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/realtimekit/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/realtimekit/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/sandbox/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/sandbox/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/sandbox/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/sandbox/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/sandbox/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/secrets-store/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/secrets-store/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/secrets-store/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/secrets-store/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/secrets-store/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/smart-placement/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/smart-placement/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/smart-placement/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/smart-placement/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/smart-placement/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/snippets/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/snippets/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/snippets/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/snippets/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/snippets/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/spectrum/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/spectrum/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/spectrum/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/spectrum/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/spectrum/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/static-assets/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/static-assets/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/static-assets/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/static-assets/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/static-assets/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/stream/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/stream/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/stream/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/stream/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/stream/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/tail-workers/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/terraform/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/terraform/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/terraform/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/terraform/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/terraform/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/tunnel/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/tunnel/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/tunnel/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/tunnel/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/tunnel/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/turn/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/turnstile/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/turnstile/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/turnstile/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/turnstile/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/turnstile/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/vectorize/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/waf/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/waf/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/waf/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/waf/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/waf/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/web-analytics/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/web-analytics/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/web-analytics/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/web-analytics/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/web-analytics/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/workerd/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/workerd/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/workerd/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/workerd/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/workerd/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/workers/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/workers/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/workers/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/workers/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/workers/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/workers-ai/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/workers-for-platforms/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/workers-for-platforms/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/workers-for-platforms/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/workers-for-platforms/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/workers-for-platforms/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/workers-playground/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/workers-playground/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/workers-playground/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/workers-playground/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/workers-playground/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/workers-vpc/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/workflows/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/workflows/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/workflows/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/workflows/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/workflows/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/wrangler/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/wrangler/api.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/wrangler/configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/wrangler/gotchas.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/wrangler/patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/cloudflare/references/zaraz/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/condition-based-waiting/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/condition-based-waiting/example.ts +0 -0
- /package/dist/template/{.opencode → opencode}/skill/context-engineering/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/context-initialization/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/core-data-expert/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/core-data-expert/references/batch-operations.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/core-data-expert/references/cloudkit-integration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/core-data-expert/references/concurrency.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/core-data-expert/references/fetch-requests.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/core-data-expert/references/glossary.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/core-data-expert/references/migration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/core-data-expert/references/model-configuration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/core-data-expert/references/performance.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/core-data-expert/references/persistent-history.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/core-data-expert/references/project-audit.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/core-data-expert/references/saving.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/core-data-expert/references/stack-setup.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/core-data-expert/references/testing.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/core-data-expert/references/threading.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/defense-in-depth/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/dispatching-parallel-agents/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/documentation-and-adrs/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/figma/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/frontend-design/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/frontend-design/references/animation/motion-advanced.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/frontend-design/references/animation/motion-core.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/frontend-design/references/canvas/execution.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/frontend-design/references/canvas/philosophy.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/frontend-design/references/design/color-system.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/frontend-design/references/design/interaction.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/frontend-design/references/design/typography-rules.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/frontend-design/references/design/ux-writing.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/frontend-design/references/shadcn/accessibility.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/frontend-design/references/shadcn/core-components.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/frontend-design/references/shadcn/form-components.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/frontend-design/references/shadcn/setup.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/frontend-design/references/shadcn/theming.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/frontend-design/references/tailwind/responsive.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/frontend-design/references/tailwind/utilities-layout.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/frontend-design/references/tailwind/utilities-styling.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/frontend-design/references/tailwind/v4-config.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/frontend-design/references/tailwind/v4-features.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/gemini-large-context/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/gh-address-comments/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/gh-address-comments/scripts/fetch_comments.py +0 -0
- /package/dist/template/{.opencode → opencode}/skill/gh-fix-ci/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/index-knowledge/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/jira/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/jira/mcp.json +0 -0
- /package/dist/template/{.opencode → opencode}/skill/memory-system/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/mockup-to-code/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/pdf-extract/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/playwright/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/playwright/mcp.json +0 -0
- /package/dist/template/{.opencode → opencode}/skill/playwright/references/agent-browser-cli.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/playwriter/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/polar/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/portless/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/prd/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/prd-task/references/prd-schema.json +0 -0
- /package/dist/template/{.opencode → opencode}/skill/prompt-leverage/references/framework.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/prompt-leverage/scripts/augment_prompt.py +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/AGENTS.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/README.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/metadata.json +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/_sections.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/_template.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/advanced-event-handler-refs.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/advanced-use-latest.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/async-api-routes.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/async-defer-await.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/async-dependencies.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/async-parallel.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/async-suspense-boundaries.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/bundle-barrel-imports.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/bundle-conditional.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/bundle-defer-third-party.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/bundle-dynamic-imports.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/bundle-preload.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/client-event-listeners.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/client-localstorage-schema.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/client-passive-event-listeners.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/client-swr-dedup.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/js-batch-dom-css.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/js-cache-function-results.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/js-cache-property-access.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/js-cache-storage.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/js-combine-iterations.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/js-early-exit.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/js-hoist-regexp.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/js-index-maps.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/js-length-check-first.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/js-min-max-loop.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/js-set-map-lookups.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/js-tosorted-immutable.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/rendering-activity.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/rendering-animate-svg-wrapper.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/rendering-conditional-render.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/rendering-content-visibility.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/rendering-hoist-jsx.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/rendering-hydration-no-flicker.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/rendering-svg-precision.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/rerender-defer-reads.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/rerender-dependencies.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/rerender-derived-state.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/rerender-functional-setstate.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/rerender-lazy-state-init.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/rerender-memo.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/rerender-transitions.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/server-after-nonblocking.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/server-cache-lru.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/server-cache-react.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/server-parallel-fetching.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/react-best-practices/rules/server-serialization.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/receiving-code-review/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/requesting-code-review/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/requesting-code-review/references/specialist-profiles.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/requesting-code-review/review.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/resend/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/resend/references/react-email.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/resend/references/receive-email.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/resend/references/send-email.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/root-cause-tracing/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/rtk-command-compression/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/screenshot/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/screenshot/scripts/ensure_macos_permissions.sh +0 -0
- /package/dist/template/{.opencode → opencode}/skill/screenshot/scripts/macos_display_info.swift +0 -0
- /package/dist/template/{.opencode → opencode}/skill/screenshot/scripts/macos_permissions.swift +0 -0
- /package/dist/template/{.opencode → opencode}/skill/screenshot/scripts/macos_window_info.swift +0 -0
- /package/dist/template/{.opencode → opencode}/skill/screenshot/scripts/take_screenshot.ps1 +0 -0
- /package/dist/template/{.opencode → opencode}/skill/screenshot/scripts/take_screenshot.py +0 -0
- /package/dist/template/{.opencode → opencode}/skill/security-and-hardening/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/security-threat-model/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/security-threat-model/references/prompt-template.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/security-threat-model/references/security-controls-and-assets.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/sharing-skills/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/skill-creator/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/skill-installer/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/skill-installer/scripts/github_utils.py +0 -0
- /package/dist/template/{.opencode → opencode}/skill/structured-edit/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/subagent-driven-development/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/supabase/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/supabase/mcp.json +0 -0
- /package/dist/template/{.opencode → opencode}/skill/supabase-postgres-best-practices/AGENTS.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/supabase-postgres-best-practices/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/supabase-postgres-best-practices/rules/advanced-full-text-search.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/supabase-postgres-best-practices/rules/advanced-jsonb-indexing.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/supabase-postgres-best-practices/rules/conn-idle-timeout.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/supabase-postgres-best-practices/rules/conn-limits.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/supabase-postgres-best-practices/rules/conn-pooling.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/supabase-postgres-best-practices/rules/conn-prepared-statements.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/supabase-postgres-best-practices/rules/data-batch-inserts.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/supabase-postgres-best-practices/rules/data-n-plus-one.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/supabase-postgres-best-practices/rules/data-pagination.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/supabase-postgres-best-practices/rules/data-upsert.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/supabase-postgres-best-practices/rules/lock-advisory.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/supabase-postgres-best-practices/rules/lock-deadlock-prevention.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/supabase-postgres-best-practices/rules/lock-short-transactions.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/supabase-postgres-best-practices/rules/lock-skip-locked.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/supabase-postgres-best-practices/rules/monitor-explain-analyze.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/supabase-postgres-best-practices/rules/monitor-pg-stat-statements.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/supabase-postgres-best-practices/rules/monitor-vacuum-analyze.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/supabase-postgres-best-practices/rules/query-composite-indexes.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/supabase-postgres-best-practices/rules/query-covering-indexes.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/supabase-postgres-best-practices/rules/query-index-types.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/supabase-postgres-best-practices/rules/query-missing-indexes.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/supabase-postgres-best-practices/rules/query-partial-indexes.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/supabase-postgres-best-practices/rules/schema-data-types.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/supabase-postgres-best-practices/rules/schema-foreign-key-indexes.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/supabase-postgres-best-practices/rules/schema-lowercase-identifiers.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/supabase-postgres-best-practices/rules/schema-partitioning.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/supabase-postgres-best-practices/rules/schema-primary-keys.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/supabase-postgres-best-practices/rules/security-privileges.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/supabase-postgres-best-practices/rules/security-rls-basics.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/supabase-postgres-best-practices/rules/security-rls-performance.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swarm-coordination/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swarm-coordination/references/architecture.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swarm-coordination/references/delegation-worker-protocol.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swarm-coordination/references/dependency-graph.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swarm-coordination/references/drift-check.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swarm-coordination/references/integration-beads.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swarm-coordination/references/launch-flow.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swarm-coordination/references/reconciler.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swarm-coordination/references/tier-enforcement.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swarm-coordination/references/tmux-integration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swift-concurrency/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swift-concurrency/references/actors.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swift-concurrency/references/async-algorithms.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swift-concurrency/references/async-await-basics.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swift-concurrency/references/async-sequences.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swift-concurrency/references/core-data.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swift-concurrency/references/glossary.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swift-concurrency/references/linting.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swift-concurrency/references/memory-management.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swift-concurrency/references/migration.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swift-concurrency/references/performance.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swift-concurrency/references/sendable.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swift-concurrency/references/tasks.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swift-concurrency/references/testing.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swift-concurrency/references/threading.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swiftui-expert-skill/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swiftui-expert-skill/references/animation-advanced.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swiftui-expert-skill/references/animation-basics.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swiftui-expert-skill/references/animation-transitions.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swiftui-expert-skill/references/image-optimization.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swiftui-expert-skill/references/layout-best-practices.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swiftui-expert-skill/references/liquid-glass.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swiftui-expert-skill/references/list-patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swiftui-expert-skill/references/modern-apis.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swiftui-expert-skill/references/performance-patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swiftui-expert-skill/references/scroll-patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swiftui-expert-skill/references/sheet-navigation-patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swiftui-expert-skill/references/state-management.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swiftui-expert-skill/references/text-formatting.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/swiftui-expert-skill/references/view-structure.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/systematic-debugging/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/terse-output-mode/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/test-driven-development/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/testing-anti-patterns/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/think-in-code/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/using-git-worktrees/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/ux-quality-gates/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/v0/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/v1-run/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/v1-run/mcp.json +0 -0
- /package/dist/template/{.opencode → opencode}/skill/vercel-deploy-claimable/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/verification-before-completion/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/visual-analysis/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/web-design-guidelines/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/writing-plans/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/writing-skills/SKILL.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/writing-skills/anthropic-best-practices.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/writing-skills/graphviz-conventions.dot +0 -0
- /package/dist/template/{.opencode → opencode}/skill/writing-skills/persuasion-principles.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/writing-skills/references/anti-patterns.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/writing-skills/references/claude-search-optimization.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/writing-skills/references/discovery-workflow.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/writing-skills/references/file-organization.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/writing-skills/references/flowcharts-and-examples.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/writing-skills/references/rationalization-hardening.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/writing-skills/references/testing-methodology.md +0 -0
- /package/dist/template/{.opencode → opencode}/skill/writing-skills/references/testing-skill-types.md +0 -0
- /package/dist/template/{.opencode → opencode}/tool/context7.ts +0 -0
- /package/dist/template/{.opencode → opencode}/tool/grepsearch.ts +0 -0
- /package/dist/template/{.opencode → opencode}/tsconfig.json +0 -0
- /package/dist/template/{.opencode → opencode}/tui.json +0 -0
package/dist/index.js
CHANGED
|
@@ -1,258 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
|
-
import * as p from "@clack/prompts";
|
|
4
3
|
import { cac } from "cac";
|
|
5
|
-
import color from "picocolors";
|
|
6
|
-
import { createHash, createHmac } from "node:crypto";
|
|
7
4
|
import { copyFileSync, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, unlinkSync, writeFileSync } from "node:fs";
|
|
8
|
-
import { homedir, hostname, platform, release } from "node:os";
|
|
9
5
|
import { basename, dirname, join, relative } from "node:path";
|
|
10
|
-
import
|
|
11
|
-
import
|
|
6
|
+
import * as p from "@clack/prompts";
|
|
7
|
+
import color from "picocolors";
|
|
12
8
|
import { z } from "zod";
|
|
13
9
|
import { execSync, spawn } from "node:child_process";
|
|
10
|
+
import { homedir, platform } from "node:os";
|
|
14
11
|
import { fileURLToPath } from "node:url";
|
|
12
|
+
import { createHash } from "node:crypto";
|
|
15
13
|
import { applyPatch, createPatch } from "diff";
|
|
16
14
|
import * as readline from "node:readline";
|
|
17
15
|
//#region \0rolldown/runtime.js
|
|
18
16
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
19
17
|
//#endregion
|
|
20
18
|
//#region package.json
|
|
21
|
-
var version = "0.
|
|
22
|
-
//#endregion
|
|
23
|
-
//#region src/utils/license.ts
|
|
24
|
-
const { machineIdSync } = machineId;
|
|
25
|
-
const LICENSE_API_BASE_URL = process.env.OCK_LICENSE_API_BASE_URL ?? "https://payments-api.ultrakit.dev";
|
|
26
|
-
const LICENSE_REQUEST_TIMEOUT_MS = 1e4;
|
|
27
|
-
const LICENSE_HMAC_SECRET = process.env.OCK_LICENSE_HMAC_SECRET ?? "uk-license-v1-local-integrity";
|
|
28
|
-
const LICENSE_CHECK_INTERVAL_SECONDS = 10080 * 60;
|
|
29
|
-
const LICENSE_OFFLINE_GRACE_SECONDS = 720 * 60 * 60;
|
|
30
|
-
const LICENSE_KEY_PATTERN = /^OCK-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}$/;
|
|
31
|
-
const StoredLicenseSchema = z.object({
|
|
32
|
-
key: z.string(),
|
|
33
|
-
activationId: z.string(),
|
|
34
|
-
machineId: z.string(),
|
|
35
|
-
machineLabel: z.string(),
|
|
36
|
-
activatedAt: z.number(),
|
|
37
|
-
lastValidatedAt: z.number(),
|
|
38
|
-
nextCheckAt: z.number(),
|
|
39
|
-
hmac: z.string()
|
|
40
|
-
});
|
|
41
|
-
function unixNow() {
|
|
42
|
-
return Math.floor(Date.now() / 1e3);
|
|
43
|
-
}
|
|
44
|
-
function getLicensePaths() {
|
|
45
|
-
const paths = envPaths("ultrakit", { suffix: "" });
|
|
46
|
-
return {
|
|
47
|
-
dir: join(paths.data, "license"),
|
|
48
|
-
file: join(paths.data, "license", "license.json")
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
function toSign(payload) {
|
|
52
|
-
return [
|
|
53
|
-
payload.key,
|
|
54
|
-
payload.activationId,
|
|
55
|
-
payload.machineId,
|
|
56
|
-
payload.machineLabel,
|
|
57
|
-
payload.activatedAt,
|
|
58
|
-
payload.lastValidatedAt,
|
|
59
|
-
payload.nextCheckAt
|
|
60
|
-
].join("|");
|
|
61
|
-
}
|
|
62
|
-
function computeHmac(payload) {
|
|
63
|
-
return createHmac("sha256", LICENSE_HMAC_SECRET).update(toSign(payload), "utf8").digest("hex");
|
|
64
|
-
}
|
|
65
|
-
function getMachineId() {
|
|
66
|
-
return machineIdSync(false);
|
|
67
|
-
}
|
|
68
|
-
function getMachineLabel() {
|
|
69
|
-
return `${hostname()} (${platform()} ${release()})`;
|
|
70
|
-
}
|
|
71
|
-
function getLicenseFilePath() {
|
|
72
|
-
return getLicensePaths().file;
|
|
73
|
-
}
|
|
74
|
-
function readStoredLicense() {
|
|
75
|
-
const { file } = getLicensePaths();
|
|
76
|
-
if (!existsSync(file)) return null;
|
|
77
|
-
try {
|
|
78
|
-
const raw = readFileSync(file, "utf8");
|
|
79
|
-
const parsed = StoredLicenseSchema.safeParse(JSON.parse(raw));
|
|
80
|
-
if (!parsed.success) return null;
|
|
81
|
-
return parsed.data;
|
|
82
|
-
} catch {
|
|
83
|
-
return null;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
function deleteStoredLicense() {
|
|
87
|
-
const { file } = getLicensePaths();
|
|
88
|
-
if (!existsSync(file)) return;
|
|
89
|
-
rmSync(file, { force: true });
|
|
90
|
-
}
|
|
91
|
-
function isLicenseBypassEnabled() {
|
|
92
|
-
return process.env.OCK_LICENSE_BYPASS === "1";
|
|
93
|
-
}
|
|
94
|
-
function isLicenseKeyFormatValid(key) {
|
|
95
|
-
return LICENSE_KEY_PATTERN.test(key.trim().toUpperCase());
|
|
96
|
-
}
|
|
97
|
-
function isStoredLicenseIntegrityValid(stored) {
|
|
98
|
-
return computeHmac({
|
|
99
|
-
key: stored.key,
|
|
100
|
-
activationId: stored.activationId,
|
|
101
|
-
machineId: stored.machineId,
|
|
102
|
-
machineLabel: stored.machineLabel,
|
|
103
|
-
activatedAt: stored.activatedAt,
|
|
104
|
-
lastValidatedAt: stored.lastValidatedAt,
|
|
105
|
-
nextCheckAt: stored.nextCheckAt
|
|
106
|
-
}) === stored.hmac;
|
|
107
|
-
}
|
|
108
|
-
function writeStoredLicense(payload) {
|
|
109
|
-
const { dir, file } = getLicensePaths();
|
|
110
|
-
mkdirSync(dir, { recursive: true });
|
|
111
|
-
const stored = {
|
|
112
|
-
...payload,
|
|
113
|
-
hmac: computeHmac(payload)
|
|
114
|
-
};
|
|
115
|
-
writeFileSync(file, `${JSON.stringify(stored, null, 2)}\n`, "utf8");
|
|
116
|
-
return stored;
|
|
117
|
-
}
|
|
118
|
-
async function postJson(path, body) {
|
|
119
|
-
let response;
|
|
120
|
-
try {
|
|
121
|
-
response = await fetch(`${LICENSE_API_BASE_URL}${path}`, {
|
|
122
|
-
method: "POST",
|
|
123
|
-
headers: { "content-type": "application/json" },
|
|
124
|
-
body: JSON.stringify(body),
|
|
125
|
-
signal: AbortSignal.timeout(LICENSE_REQUEST_TIMEOUT_MS)
|
|
126
|
-
});
|
|
127
|
-
} catch (error) {
|
|
128
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
129
|
-
throw new Error(`License server request failed: ${message}`);
|
|
130
|
-
}
|
|
131
|
-
let data;
|
|
132
|
-
try {
|
|
133
|
-
data = await response.json();
|
|
134
|
-
} catch {
|
|
135
|
-
throw new Error(`License server returned invalid JSON (${response.status})`);
|
|
136
|
-
}
|
|
137
|
-
if (!response.ok) throw new Error(data?.message || `License server request failed with status ${response.status}`);
|
|
138
|
-
return data;
|
|
139
|
-
}
|
|
140
|
-
async function activateLicenseKey(key) {
|
|
141
|
-
const normalizedKey = key.trim().toUpperCase();
|
|
142
|
-
const machineId = getMachineId();
|
|
143
|
-
const machineLabel = getMachineLabel();
|
|
144
|
-
const now = unixNow();
|
|
145
|
-
const data = await postJson("/v1/activate", {
|
|
146
|
-
key: normalizedKey,
|
|
147
|
-
machine_id: machineId,
|
|
148
|
-
machine_label: machineLabel
|
|
149
|
-
});
|
|
150
|
-
if (!data.ok || !data.activation_id) throw new Error(data.message || data.error || "License activation failed");
|
|
151
|
-
return writeStoredLicense({
|
|
152
|
-
key: normalizedKey,
|
|
153
|
-
activationId: data.activation_id,
|
|
154
|
-
machineId,
|
|
155
|
-
machineLabel,
|
|
156
|
-
activatedAt: now,
|
|
157
|
-
lastValidatedAt: now,
|
|
158
|
-
nextCheckAt: now + LICENSE_CHECK_INTERVAL_SECONDS
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
async function validateLicenseOnline(stored) {
|
|
162
|
-
if (getMachineId() !== stored.machineId) throw new Error("License key is activated on a different machine");
|
|
163
|
-
const data = await postJson("/v1/validate", {
|
|
164
|
-
key: stored.key,
|
|
165
|
-
activation_id: stored.activationId,
|
|
166
|
-
machine_id: stored.machineId
|
|
167
|
-
});
|
|
168
|
-
if (!data.ok) throw new Error(data.message || data.error || "License validation failed");
|
|
169
|
-
const now = unixNow();
|
|
170
|
-
writeStoredLicense({
|
|
171
|
-
key: stored.key,
|
|
172
|
-
activationId: stored.activationId,
|
|
173
|
-
machineId: stored.machineId,
|
|
174
|
-
machineLabel: stored.machineLabel,
|
|
175
|
-
activatedAt: stored.activatedAt,
|
|
176
|
-
lastValidatedAt: now,
|
|
177
|
-
nextCheckAt: now + LICENSE_CHECK_INTERVAL_SECONDS
|
|
178
|
-
});
|
|
179
|
-
}
|
|
180
|
-
async function deactivateCurrentLicense(stored) {
|
|
181
|
-
const data = await postJson("/v1/deactivate", {
|
|
182
|
-
key: stored.key,
|
|
183
|
-
activation_id: stored.activationId,
|
|
184
|
-
machine_id: stored.machineId
|
|
185
|
-
});
|
|
186
|
-
if (!data.ok) throw new Error(data.message || data.error || "License deactivation failed");
|
|
187
|
-
deleteStoredLicense();
|
|
188
|
-
}
|
|
189
|
-
async function requireValidLicense() {
|
|
190
|
-
if (isLicenseBypassEnabled()) return {
|
|
191
|
-
mode: "bypass",
|
|
192
|
-
stored: null
|
|
193
|
-
};
|
|
194
|
-
const stored = readStoredLicense();
|
|
195
|
-
if (!stored) throw new Error("License not activated. Run: uk activate <LICENSE_KEY>");
|
|
196
|
-
if (!isStoredLicenseIntegrityValid(stored)) throw new Error(`License file integrity check failed (${dirname(getLicenseFilePath())}). Re-activate with: uk activate <LICENSE_KEY>`);
|
|
197
|
-
if (stored.machineId !== getMachineId()) throw new Error("License is tied to a different machine. Run: uk activate <LICENSE_KEY>");
|
|
198
|
-
const now = unixNow();
|
|
199
|
-
if (stored.nextCheckAt > now) return {
|
|
200
|
-
mode: "active",
|
|
201
|
-
stored
|
|
202
|
-
};
|
|
203
|
-
try {
|
|
204
|
-
await validateLicenseOnline(stored);
|
|
205
|
-
return {
|
|
206
|
-
mode: "active",
|
|
207
|
-
stored: readStoredLicense()
|
|
208
|
-
};
|
|
209
|
-
} catch (error) {
|
|
210
|
-
if (now - stored.lastValidatedAt <= LICENSE_OFFLINE_GRACE_SECONDS) return {
|
|
211
|
-
mode: "offline-grace",
|
|
212
|
-
stored
|
|
213
|
-
};
|
|
214
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
215
|
-
throw new Error(`License validation failed: ${message}`);
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
//#endregion
|
|
219
|
-
//#region src/commands/activate.ts
|
|
220
|
-
async function activateCommand(keyArg) {
|
|
221
|
-
p.intro(color.bgBlue(color.black(" License Activation ")));
|
|
222
|
-
let key = keyArg?.trim();
|
|
223
|
-
if (!key) {
|
|
224
|
-
const answer = await p.text({
|
|
225
|
-
message: "Enter your license key",
|
|
226
|
-
placeholder: "OCK-XXXX-XXXX-XXXX",
|
|
227
|
-
validate: (value) => {
|
|
228
|
-
if (!value) return "License key is required";
|
|
229
|
-
if (!isLicenseKeyFormatValid(value)) return "Invalid format. Expected OCK-XXXX-XXXX-XXXX";
|
|
230
|
-
}
|
|
231
|
-
});
|
|
232
|
-
if (p.isCancel(answer)) {
|
|
233
|
-
p.cancel("Cancelled");
|
|
234
|
-
return;
|
|
235
|
-
}
|
|
236
|
-
key = String(answer);
|
|
237
|
-
}
|
|
238
|
-
if (!isLicenseKeyFormatValid(key)) {
|
|
239
|
-
p.log.error("Invalid license key format. Expected OCK-XXXX-XXXX-XXXX");
|
|
240
|
-
return;
|
|
241
|
-
}
|
|
242
|
-
const spinner = p.spinner();
|
|
243
|
-
spinner.start("Activating license");
|
|
244
|
-
try {
|
|
245
|
-
const stored = await activateLicenseKey(key);
|
|
246
|
-
spinner.stop("License activated");
|
|
247
|
-
p.log.success(`Activated ${color.cyan(stored.key)}`);
|
|
248
|
-
p.log.info(`Stored at ${color.dim(getLicenseFilePath())}`);
|
|
249
|
-
p.outro(color.green("Activation complete"));
|
|
250
|
-
} catch (error) {
|
|
251
|
-
spinner.stop("Activation failed");
|
|
252
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
253
|
-
p.log.error(message);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
19
|
+
var version = "0.0.2";
|
|
256
20
|
//#endregion
|
|
257
21
|
//#region src/utils/errors.ts
|
|
258
22
|
/**
|
|
@@ -332,11 +96,38 @@ const InitOptionsSchema = z.object({
|
|
|
332
96
|
global: z.boolean().optional().default(false),
|
|
333
97
|
free: z.boolean().optional().default(false),
|
|
334
98
|
recommend: z.boolean().optional().default(false),
|
|
99
|
+
providerProfile: z.enum([
|
|
100
|
+
"existing-global",
|
|
101
|
+
"opencode-zen",
|
|
102
|
+
"openai",
|
|
103
|
+
"ollama",
|
|
104
|
+
"wafer",
|
|
105
|
+
"github-copilot",
|
|
106
|
+
"custom-openai-compatible"
|
|
107
|
+
]).optional(),
|
|
108
|
+
mcpPreset: z.enum([
|
|
109
|
+
"minimal",
|
|
110
|
+
"recommended",
|
|
111
|
+
"power",
|
|
112
|
+
"local-first"
|
|
113
|
+
]).optional(),
|
|
114
|
+
webclawMode: z.enum([
|
|
115
|
+
"auto",
|
|
116
|
+
"disabled",
|
|
117
|
+
"host-binary",
|
|
118
|
+
"docker-existing"
|
|
119
|
+
]).optional().default("auto"),
|
|
120
|
+
withSuperpowers: z.boolean().optional().default(false),
|
|
335
121
|
yes: z.boolean().optional().default(false),
|
|
336
122
|
backup: z.boolean().optional().default(false),
|
|
337
123
|
prune: z.boolean().optional().default(false),
|
|
338
124
|
pruneAll: z.boolean().optional().default(false),
|
|
339
|
-
projectOnly: z.boolean().optional().default(false)
|
|
125
|
+
projectOnly: z.boolean().optional().default(false),
|
|
126
|
+
variant: z.enum([
|
|
127
|
+
"full",
|
|
128
|
+
"minimal",
|
|
129
|
+
"dev"
|
|
130
|
+
]).optional().default("full")
|
|
340
131
|
});
|
|
341
132
|
const UpgradeOptionsSchema = z.object({
|
|
342
133
|
force: z.boolean().optional().default(false),
|
|
@@ -427,13 +218,17 @@ const CompletionShellSchema = z.enum([
|
|
|
427
218
|
z.enum(["status", "doctor"]).optional();
|
|
428
219
|
/**
|
|
429
220
|
* Parse and validate command options with Zod.
|
|
430
|
-
* Returns validated options or
|
|
221
|
+
* Returns validated options, defaults when provided, or throws on invalid input.
|
|
431
222
|
*/
|
|
432
223
|
function parseOptions(schema, options, defaults) {
|
|
433
224
|
const result = schema.safeParse(options);
|
|
434
225
|
if (result.success) return result.data;
|
|
435
226
|
if (process.env.DEBUG) console.error("[Schema validation failed]", result.error.format());
|
|
436
|
-
|
|
227
|
+
if (defaults !== void 0) return defaults;
|
|
228
|
+
const message = result.error.issues.map((issue) => {
|
|
229
|
+
return `${issue.path.join(".") || "options"}: ${issue.message}`;
|
|
230
|
+
}).join("; ");
|
|
231
|
+
throw new Error(`Invalid command options: ${message}`);
|
|
437
232
|
}
|
|
438
233
|
/**
|
|
439
234
|
* Validate action parameter against allowed actions.
|
|
@@ -1027,7 +822,7 @@ _uk_completion() {
|
|
|
1027
822
|
return 0
|
|
1028
823
|
;;
|
|
1029
824
|
init)
|
|
1030
|
-
COMPREPLY=( $(compgen -W "--force" -- "\${cur}") )
|
|
825
|
+
COMPREPLY=( $(compgen -W "--force --beads --global --free --recommend --yes --backup --prune --prune-all --project-only --with-superpowers" -- "\${cur}") )
|
|
1031
826
|
return 0
|
|
1032
827
|
;;
|
|
1033
828
|
upgrade)
|
|
@@ -1090,7 +885,18 @@ _uk() {
|
|
|
1090
885
|
_describe -t actions 'config action' config_actions
|
|
1091
886
|
;;
|
|
1092
887
|
init)
|
|
1093
|
-
_arguments
|
|
888
|
+
_arguments \\
|
|
889
|
+
'--force[Reinitialize even if already exists]' \\
|
|
890
|
+
'--beads[Also initialize .beads/ for multi-agent coordination]' \\
|
|
891
|
+
'--global[Install to global OpenCode config]' \\
|
|
892
|
+
'--free[Use free models]' \\
|
|
893
|
+
'--recommend[Use recommended premium models]' \\
|
|
894
|
+
'--yes[Skip prompts, use defaults]' \\
|
|
895
|
+
'--backup[Backup existing .opencode before overwriting]' \\
|
|
896
|
+
'--prune[Manually select orphan files to delete]' \\
|
|
897
|
+
'--prune-all[Auto-delete all orphan files]' \\
|
|
898
|
+
'--project-only[Only init project-scope files]' \\
|
|
899
|
+
'--with-superpowers[Enable upstream Superpowers plugin]'
|
|
1094
900
|
;;
|
|
1095
901
|
upgrade)
|
|
1096
902
|
_arguments \\
|
|
@@ -1133,6 +939,16 @@ complete -c uk -n "__fish_seen_subcommand_from config" -a "show" -d "View config
|
|
|
1133
939
|
|
|
1134
940
|
# init options
|
|
1135
941
|
complete -c uk -n "__fish_seen_subcommand_from init" -l force -d "Reinitialize"
|
|
942
|
+
complete -c uk -n "__fish_seen_subcommand_from init" -l beads -d "Initialize .beads"
|
|
943
|
+
complete -c uk -n "__fish_seen_subcommand_from init" -l global -d "Install global config"
|
|
944
|
+
complete -c uk -n "__fish_seen_subcommand_from init" -l free -d "Use free models"
|
|
945
|
+
complete -c uk -n "__fish_seen_subcommand_from init" -l recommend -d "Use recommended models"
|
|
946
|
+
complete -c uk -n "__fish_seen_subcommand_from init" -l yes -d "Skip prompts"
|
|
947
|
+
complete -c uk -n "__fish_seen_subcommand_from init" -l backup -d "Backup existing config"
|
|
948
|
+
complete -c uk -n "__fish_seen_subcommand_from init" -l prune -d "Select orphan files to delete"
|
|
949
|
+
complete -c uk -n "__fish_seen_subcommand_from init" -l prune-all -d "Delete all orphan files"
|
|
950
|
+
complete -c uk -n "__fish_seen_subcommand_from init" -l project-only -d "Only init project-scope files"
|
|
951
|
+
complete -c uk -n "__fish_seen_subcommand_from init" -l with-superpowers -d "Enable upstream Superpowers plugin"
|
|
1136
952
|
|
|
1137
953
|
# upgrade options
|
|
1138
954
|
complete -c uk -n "__fish_seen_subcommand_from upgrade" -l force -d "Force upgrade"
|
|
@@ -1233,7 +1049,7 @@ async function configCommand(action) {
|
|
|
1233
1049
|
if (!opencodePath) return;
|
|
1234
1050
|
const configPath = join(opencodePath, "opencode.json");
|
|
1235
1051
|
if (!existsSync(configPath)) {
|
|
1236
|
-
showError("opencode.json not found", "
|
|
1052
|
+
showError("opencode.json not found", "uk init --force");
|
|
1237
1053
|
return;
|
|
1238
1054
|
}
|
|
1239
1055
|
if (!action) {
|
|
@@ -2699,6 +2515,13 @@ function buildManifestFromDir(dir, skipDirs = [
|
|
|
2699
2515
|
}
|
|
2700
2516
|
/**
|
|
2701
2517
|
* Generate and save a template manifest after installation.
|
|
2518
|
+
*
|
|
2519
|
+
* IMPORTANT: This must be called BEFORE restoreUserFiles() in init.ts.
|
|
2520
|
+
* Preserved user files (opencode.json, .env, memory/project/*) are restored
|
|
2521
|
+
* AFTER manifest generation, so they are NOT included in the manifest. This
|
|
2522
|
+
* means upgrade treats them as "unknown" (user-owned) rather than template-managed,
|
|
2523
|
+
* which is the correct behavior — user files should never be overwritten by
|
|
2524
|
+
* template upgrades.
|
|
2702
2525
|
*/
|
|
2703
2526
|
function generateManifest(opencodeDir, version) {
|
|
2704
2527
|
const manifest = {
|
|
@@ -2747,6 +2570,7 @@ function fileModificationStatus(filePath, relativePath, manifest) {
|
|
|
2747
2570
|
const PATCHES_DIR = "patches";
|
|
2748
2571
|
const PATCHES_JSON = ".patches.json";
|
|
2749
2572
|
const METADATA_VERSION = "1.0.0";
|
|
2573
|
+
const TEMPLATE_SOURCE_DIR$3 = "opencode";
|
|
2750
2574
|
/**
|
|
2751
2575
|
* Calculate SHA-256 hash of content.
|
|
2752
2576
|
*/
|
|
@@ -2773,13 +2597,10 @@ function getTemplateRoot$2() {
|
|
|
2773
2597
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
2774
2598
|
const possiblePaths = [
|
|
2775
2599
|
join(__dirname, "template"),
|
|
2776
|
-
join(__dirname, "..", "..", "
|
|
2600
|
+
join(__dirname, "..", "..", "template"),
|
|
2777
2601
|
join(__dirname, "..", "template")
|
|
2778
2602
|
];
|
|
2779
|
-
for (const path of possiblePaths)
|
|
2780
|
-
if (existsSync(join(path, ".opencode"))) return path;
|
|
2781
|
-
if (existsSync(join(path, "opencode.json"))) return dirname(path);
|
|
2782
|
-
}
|
|
2603
|
+
for (const path of possiblePaths) if (existsSync(join(path, TEMPLATE_SOURCE_DIR$3))) return path;
|
|
2783
2604
|
return null;
|
|
2784
2605
|
}
|
|
2785
2606
|
/**
|
|
@@ -2856,10 +2677,7 @@ function removePatch(opencodeDir, relativePath) {
|
|
|
2856
2677
|
const entry = metadata.patches[relativePath];
|
|
2857
2678
|
if (!entry) return false;
|
|
2858
2679
|
const patchPath = join(getPatchesDir(opencodeDir), entry.patchFile);
|
|
2859
|
-
if (existsSync(patchPath))
|
|
2860
|
-
const { rmSync } = __require("node:fs");
|
|
2861
|
-
rmSync(patchPath);
|
|
2862
|
-
}
|
|
2680
|
+
if (existsSync(patchPath)) rmSync(patchPath);
|
|
2863
2681
|
delete metadata.patches[relativePath];
|
|
2864
2682
|
savePatchMetadata(opencodeDir, metadata);
|
|
2865
2683
|
return true;
|
|
@@ -2946,7 +2764,7 @@ function checkPatchStatus(opencodeDir, templateRoot) {
|
|
|
2946
2764
|
continue;
|
|
2947
2765
|
}
|
|
2948
2766
|
if (templateRoot) {
|
|
2949
|
-
const templateFilePath = join(templateRoot,
|
|
2767
|
+
const templateFilePath = join(templateRoot, TEMPLATE_SOURCE_DIR$3, relativePath);
|
|
2950
2768
|
if (existsSync(templateFilePath)) {
|
|
2951
2769
|
const templateContent = readFileSync(templateFilePath, "utf-8");
|
|
2952
2770
|
if (calculateHash(templateContent) !== entry.originalHash) {
|
|
@@ -2983,6 +2801,138 @@ function checkPatchStatus(opencodeDir, templateRoot) {
|
|
|
2983
2801
|
return statuses;
|
|
2984
2802
|
}
|
|
2985
2803
|
//#endregion
|
|
2804
|
+
//#region src/utils/variants.ts
|
|
2805
|
+
/**
|
|
2806
|
+
* Variant presets.
|
|
2807
|
+
*
|
|
2808
|
+
* - "full": Current behavior — all agents, commands, skills, tools.
|
|
2809
|
+
* - "minimal": Core agents + essential commands + no skills.
|
|
2810
|
+
* - "dev": Full dev workflow — all agents + dev commands + core skills.
|
|
2811
|
+
*/
|
|
2812
|
+
const VARIANT_PRESETS = {
|
|
2813
|
+
full: {
|
|
2814
|
+
agents: [],
|
|
2815
|
+
commands: [],
|
|
2816
|
+
skills: [],
|
|
2817
|
+
tools: []
|
|
2818
|
+
},
|
|
2819
|
+
minimal: {
|
|
2820
|
+
agents: [
|
|
2821
|
+
"build",
|
|
2822
|
+
"general",
|
|
2823
|
+
"explore"
|
|
2824
|
+
],
|
|
2825
|
+
commands: [
|
|
2826
|
+
"lfg",
|
|
2827
|
+
"ship",
|
|
2828
|
+
"plan",
|
|
2829
|
+
"init",
|
|
2830
|
+
"init-user",
|
|
2831
|
+
"status"
|
|
2832
|
+
],
|
|
2833
|
+
skills: [],
|
|
2834
|
+
tools: ["context7"]
|
|
2835
|
+
},
|
|
2836
|
+
dev: {
|
|
2837
|
+
agents: [
|
|
2838
|
+
"build",
|
|
2839
|
+
"plan",
|
|
2840
|
+
"review",
|
|
2841
|
+
"verify",
|
|
2842
|
+
"debugger",
|
|
2843
|
+
"explore",
|
|
2844
|
+
"general"
|
|
2845
|
+
],
|
|
2846
|
+
commands: [
|
|
2847
|
+
"lfg",
|
|
2848
|
+
"compound",
|
|
2849
|
+
"create",
|
|
2850
|
+
"ship",
|
|
2851
|
+
"plan",
|
|
2852
|
+
"resume",
|
|
2853
|
+
"handoff",
|
|
2854
|
+
"pr",
|
|
2855
|
+
"review-codebase",
|
|
2856
|
+
"research",
|
|
2857
|
+
"explore",
|
|
2858
|
+
"health",
|
|
2859
|
+
"curate",
|
|
2860
|
+
"iterate",
|
|
2861
|
+
"verify",
|
|
2862
|
+
"status",
|
|
2863
|
+
"init",
|
|
2864
|
+
"init-user",
|
|
2865
|
+
"init-context",
|
|
2866
|
+
"init-deep"
|
|
2867
|
+
],
|
|
2868
|
+
skills: [
|
|
2869
|
+
"beads",
|
|
2870
|
+
"brainstorming",
|
|
2871
|
+
"code-search-patterns",
|
|
2872
|
+
"context-engineering",
|
|
2873
|
+
"context-management",
|
|
2874
|
+
"deep-research",
|
|
2875
|
+
"incremental-implementation",
|
|
2876
|
+
"index-knowledge",
|
|
2877
|
+
"memory-grounding",
|
|
2878
|
+
"memory-system",
|
|
2879
|
+
"prompt-leverage",
|
|
2880
|
+
"skill-creator",
|
|
2881
|
+
"structured-edit",
|
|
2882
|
+
"subagent-driven-development",
|
|
2883
|
+
"swarm-coordination",
|
|
2884
|
+
"systematic-debugging",
|
|
2885
|
+
"test-driven-development",
|
|
2886
|
+
"testing-anti-patterns",
|
|
2887
|
+
"verification-before-completion",
|
|
2888
|
+
"verification-gates",
|
|
2889
|
+
"writing-plans",
|
|
2890
|
+
"executing-plans",
|
|
2891
|
+
"code-simplification",
|
|
2892
|
+
"react-best-practices",
|
|
2893
|
+
"security-and-hardening",
|
|
2894
|
+
"defense-in-depth",
|
|
2895
|
+
"opensrc",
|
|
2896
|
+
"agent-evals",
|
|
2897
|
+
"requesting-code-review",
|
|
2898
|
+
"receiving-code-review",
|
|
2899
|
+
"finishing-a-development-branch",
|
|
2900
|
+
"using-git-worktrees"
|
|
2901
|
+
],
|
|
2902
|
+
tools: ["context7", "grepsearch"]
|
|
2903
|
+
}
|
|
2904
|
+
};
|
|
2905
|
+
/**
|
|
2906
|
+
* Check if a variant is "full" (no filtering needed).
|
|
2907
|
+
*/
|
|
2908
|
+
function isFullVariant(variant) {
|
|
2909
|
+
return variant === "full";
|
|
2910
|
+
}
|
|
2911
|
+
/**
|
|
2912
|
+
* Get the filter for a variant name.
|
|
2913
|
+
* Returns the "full" filter (no filtering) for unknown variants.
|
|
2914
|
+
*/
|
|
2915
|
+
function getVariantFilter(variant) {
|
|
2916
|
+
return VARIANT_PRESETS[variant] ?? VARIANT_PRESETS.full;
|
|
2917
|
+
}
|
|
2918
|
+
/**
|
|
2919
|
+
* Check if a file should be included given a variant filter.
|
|
2920
|
+
* If the filter list is empty, all files are included (full variant).
|
|
2921
|
+
*/
|
|
2922
|
+
function shouldIncludeFile(filename, filterList, extension) {
|
|
2923
|
+
if (filterList.length === 0) return true;
|
|
2924
|
+
const nameWithoutExt = filename.endsWith(extension) ? filename.slice(0, -extension.length) : filename;
|
|
2925
|
+
return filterList.includes(nameWithoutExt);
|
|
2926
|
+
}
|
|
2927
|
+
/**
|
|
2928
|
+
* Check if a directory should be included given a variant filter.
|
|
2929
|
+
* If the filter list is empty, all directories are included (full variant).
|
|
2930
|
+
*/
|
|
2931
|
+
function shouldIncludeDir(dirname, filterList) {
|
|
2932
|
+
if (filterList.length === 0) return true;
|
|
2933
|
+
return filterList.includes(dirname);
|
|
2934
|
+
}
|
|
2935
|
+
//#endregion
|
|
2986
2936
|
//#region src/commands/init.ts
|
|
2987
2937
|
const EXCLUDED_DIRS = [
|
|
2988
2938
|
"node_modules",
|
|
@@ -3000,12 +2950,14 @@ const EXCLUDED_FILES = [
|
|
|
3000
2950
|
"pnpm-lock.yaml"
|
|
3001
2951
|
];
|
|
3002
2952
|
const PRESERVE_USER_DIRS = ["memory/project", "context"];
|
|
2953
|
+
const PRESERVE_USER_FILES = [".env", "opencode.json"];
|
|
3003
2954
|
const SHARED_CONFIG_DIRS = [
|
|
3004
2955
|
"agent",
|
|
3005
2956
|
"command",
|
|
3006
2957
|
"skill",
|
|
3007
2958
|
"tool"
|
|
3008
2959
|
];
|
|
2960
|
+
const TEMPLATE_SOURCE_DIR$2 = "opencode";
|
|
3009
2961
|
/**
|
|
3010
2962
|
* Detect if global config has any of the shared dirs populated.
|
|
3011
2963
|
* Returns null if no global config or no shared dirs found.
|
|
@@ -3046,8 +2998,8 @@ function detectMode(targetDir) {
|
|
|
3046
2998
|
}
|
|
3047
2999
|
function getTemplateRoot$1() {
|
|
3048
3000
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
3049
|
-
const possiblePaths = [join(__dirname, "template"), join(__dirname, "..", "..", "
|
|
3050
|
-
for (const path of possiblePaths) if (existsSync(join(path,
|
|
3001
|
+
const possiblePaths = [join(__dirname, "template"), join(__dirname, "..", "..", "template")];
|
|
3002
|
+
for (const path of possiblePaths) if (existsSync(join(path, TEMPLATE_SOURCE_DIR$2))) return path;
|
|
3051
3003
|
return null;
|
|
3052
3004
|
}
|
|
3053
3005
|
function getPackageVersion$1() {
|
|
@@ -3071,28 +3023,69 @@ async function copyDir(src, dest) {
|
|
|
3071
3023
|
else writeFileSync(destPath, readFileSync(srcPath, "utf-8"));
|
|
3072
3024
|
}
|
|
3073
3025
|
}
|
|
3074
|
-
|
|
3075
|
-
|
|
3026
|
+
/**
|
|
3027
|
+
* Copy a directory, but only include entries whose names (minus extension)
|
|
3028
|
+
* appear in the filterList. If filterList is empty, copy everything (full variant).
|
|
3029
|
+
* For skill directories, each entry is a subdirectory (e.g., "beads/", "cloudflare/"),
|
|
3030
|
+
* so we check directory names against the filterList.
|
|
3031
|
+
*/
|
|
3032
|
+
async function copyFilteredDir(src, dest, filterList, extension) {
|
|
3033
|
+
const { mkdir, readdir } = await import("node:fs/promises");
|
|
3034
|
+
await mkdir(dest, { recursive: true });
|
|
3035
|
+
for (const entry of await readdir(src, { withFileTypes: true })) {
|
|
3036
|
+
if (EXCLUDED_DIRS.includes(entry.name)) continue;
|
|
3037
|
+
if (!entry.isDirectory() && EXCLUDED_FILES.includes(entry.name)) continue;
|
|
3038
|
+
const srcPath = join(src, entry.name);
|
|
3039
|
+
const destPath = join(dest, entry.name);
|
|
3040
|
+
if (entry.isSymbolicLink()) {} else if (entry.isDirectory()) if (extension === "") {
|
|
3041
|
+
if (shouldIncludeDir(entry.name, filterList)) await copyDir(srcPath, destPath);
|
|
3042
|
+
} else await copyDir(srcPath, destPath);
|
|
3043
|
+
else if (shouldIncludeFile(entry.name, filterList, extension)) writeFileSync(destPath, readFileSync(srcPath, "utf-8"));
|
|
3044
|
+
}
|
|
3045
|
+
}
|
|
3046
|
+
async function copyOpenCodeOnly(templateRoot, targetDir, skipDirs, variant) {
|
|
3047
|
+
const opencodeSrc = join(templateRoot, TEMPLATE_SOURCE_DIR$2);
|
|
3076
3048
|
const opencodeDest = join(targetDir, ".opencode");
|
|
3077
3049
|
if (!existsSync(opencodeSrc)) return false;
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
if (EXCLUDED_DIRS.includes(entry.name)) continue;
|
|
3083
|
-
if (!entry.isDirectory() && EXCLUDED_FILES.includes(entry.name)) continue;
|
|
3084
|
-
if (entry.isSymbolicLink()) continue;
|
|
3085
|
-
if (entry.isDirectory() && skipSet.has(entry.name)) continue;
|
|
3086
|
-
const srcPath = join(opencodeSrc, entry.name);
|
|
3087
|
-
const destPath = join(opencodeDest, entry.name);
|
|
3088
|
-
if (entry.isDirectory()) await copyDir(srcPath, destPath);
|
|
3089
|
-
else writeFileSync(destPath, readFileSync(srcPath, "utf-8"));
|
|
3090
|
-
}
|
|
3050
|
+
const isFullCopy = !skipDirs?.length && (!variant || variant.agents.length === 0 && variant.commands.length === 0 && variant.skills.length === 0 && variant.tools.length === 0);
|
|
3051
|
+
const effectiveVariant = variant ?? getVariantFilter("full");
|
|
3052
|
+
if (isFullCopy && (!effectiveVariant || effectiveVariant.agents.length === 0 && effectiveVariant.commands.length === 0 && effectiveVariant.skills.length === 0 && effectiveVariant.tools.length === 0)) {
|
|
3053
|
+
await copyDir(opencodeSrc, opencodeDest);
|
|
3091
3054
|
return true;
|
|
3092
3055
|
}
|
|
3093
|
-
|
|
3056
|
+
const skipSet = new Set(skipDirs ?? []);
|
|
3057
|
+
mkdirSync(opencodeDest, { recursive: true });
|
|
3058
|
+
for (const entry of readdirSync(opencodeSrc, { withFileTypes: true })) {
|
|
3059
|
+
if (EXCLUDED_DIRS.includes(entry.name)) continue;
|
|
3060
|
+
if (!entry.isDirectory() && EXCLUDED_FILES.includes(entry.name)) continue;
|
|
3061
|
+
if (entry.isSymbolicLink()) continue;
|
|
3062
|
+
if (entry.isDirectory() && skipSet.has(entry.name)) continue;
|
|
3063
|
+
const srcPath = join(opencodeSrc, entry.name);
|
|
3064
|
+
const destPath = join(opencodeDest, entry.name);
|
|
3065
|
+
if (entry.isDirectory()) if (entry.name === "agent") await copyFilteredDir(srcPath, destPath, effectiveVariant.agents, ".md");
|
|
3066
|
+
else if (entry.name === "command") await copyFilteredDir(srcPath, destPath, effectiveVariant.commands, ".md");
|
|
3067
|
+
else if (entry.name === "skill") await copyFilteredDir(srcPath, destPath, effectiveVariant.skills, "");
|
|
3068
|
+
else if (entry.name === "tool") await copyFilteredDir(srcPath, destPath, effectiveVariant.tools, ".ts");
|
|
3069
|
+
else await copyDir(srcPath, destPath);
|
|
3070
|
+
else writeFileSync(destPath, readFileSync(srcPath, "utf-8"));
|
|
3071
|
+
}
|
|
3094
3072
|
return true;
|
|
3095
3073
|
}
|
|
3074
|
+
const TEMPLATE_AGENT_NAMES = [
|
|
3075
|
+
"build",
|
|
3076
|
+
"plan",
|
|
3077
|
+
"review",
|
|
3078
|
+
"verify",
|
|
3079
|
+
"debugger",
|
|
3080
|
+
"explore",
|
|
3081
|
+
"general",
|
|
3082
|
+
"vision",
|
|
3083
|
+
"scout",
|
|
3084
|
+
"painter"
|
|
3085
|
+
];
|
|
3086
|
+
function allAgentModels(model) {
|
|
3087
|
+
return Object.fromEntries(TEMPLATE_AGENT_NAMES.map((agent) => [agent, model]));
|
|
3088
|
+
}
|
|
3096
3089
|
const MODEL_PRESETS = {
|
|
3097
3090
|
free: {
|
|
3098
3091
|
model: "opencode/glm-5-free",
|
|
@@ -3100,6 +3093,8 @@ const MODEL_PRESETS = {
|
|
|
3100
3093
|
build: "opencode/minimax-m2.5-free",
|
|
3101
3094
|
plan: "opencode/minimax-m2.5-free",
|
|
3102
3095
|
review: "opencode/minimax-m2.5-free",
|
|
3096
|
+
verify: "opencode/minimax-m2.5-free",
|
|
3097
|
+
debugger: "opencode/minimax-m2.5-free",
|
|
3103
3098
|
explore: "opencode/glm-5-free",
|
|
3104
3099
|
general: "opencode/glm-5-free",
|
|
3105
3100
|
vision: "opencode/minimax-m2.5-free",
|
|
@@ -3113,14 +3108,232 @@ const MODEL_PRESETS = {
|
|
|
3113
3108
|
build: "github-copilot/gpt-5.4",
|
|
3114
3109
|
plan: "github-copilot/gpt-5.4",
|
|
3115
3110
|
review: "github-copilot/gpt-5.3-codex",
|
|
3111
|
+
verify: "github-copilot/gpt-5.3-codex",
|
|
3112
|
+
debugger: "github-copilot/gpt-5.3-codex",
|
|
3116
3113
|
explore: "github-copilot/claude-haiku-4.5",
|
|
3117
3114
|
general: "github-copilot/gpt-5.3-codex",
|
|
3118
3115
|
vision: "github-copilot/gemini-3.1-pro-preview",
|
|
3119
3116
|
scout: "github-copilot/claude-sonnet-4.6",
|
|
3120
|
-
painter: "
|
|
3117
|
+
painter: "github-copilot/gemini-3.1-pro-preview"
|
|
3121
3118
|
}
|
|
3122
3119
|
}
|
|
3123
3120
|
};
|
|
3121
|
+
const PROVIDER_PROFILES = {
|
|
3122
|
+
"existing-global": {},
|
|
3123
|
+
"opencode-zen": {
|
|
3124
|
+
model: "opencode/big-pickle",
|
|
3125
|
+
smallModel: "opencode/big-pickle",
|
|
3126
|
+
agents: allAgentModels("opencode/big-pickle")
|
|
3127
|
+
},
|
|
3128
|
+
openai: {
|
|
3129
|
+
model: "openai/gpt-5.1",
|
|
3130
|
+
smallModel: "openai/gpt-5.1-mini",
|
|
3131
|
+
agents: allAgentModels("openai/gpt-5.1")
|
|
3132
|
+
},
|
|
3133
|
+
ollama: {
|
|
3134
|
+
model: "ollama/qwen3-coder:latest",
|
|
3135
|
+
smallModel: "ollama/qwen3-coder:latest",
|
|
3136
|
+
agents: allAgentModels("ollama/qwen3-coder:latest"),
|
|
3137
|
+
provider: { ollama: {
|
|
3138
|
+
npm: "@ai-sdk/openai-compatible",
|
|
3139
|
+
name: "Ollama",
|
|
3140
|
+
options: { baseURL: "http://localhost:11434/v1" },
|
|
3141
|
+
models: {
|
|
3142
|
+
"qwen3-coder:latest": { tool_call: true },
|
|
3143
|
+
"llama3.3:latest": { tool_call: true }
|
|
3144
|
+
}
|
|
3145
|
+
} }
|
|
3146
|
+
},
|
|
3147
|
+
wafer: {
|
|
3148
|
+
model: "wafer/GLM-5.1",
|
|
3149
|
+
smallModel: "wafer/MiniMax-M2.7",
|
|
3150
|
+
agents: allAgentModels("wafer/GLM-5.1")
|
|
3151
|
+
},
|
|
3152
|
+
"github-copilot": {
|
|
3153
|
+
model: MODEL_PRESETS.recommend.model,
|
|
3154
|
+
smallModel: "github-copilot/gpt-5.3-codex",
|
|
3155
|
+
agents: MODEL_PRESETS.recommend.agents
|
|
3156
|
+
},
|
|
3157
|
+
"custom-openai-compatible": {
|
|
3158
|
+
model: "custom/default-model",
|
|
3159
|
+
smallModel: "custom/small-model",
|
|
3160
|
+
agents: allAgentModels("custom/default-model"),
|
|
3161
|
+
provider: { custom: {
|
|
3162
|
+
npm: "@ai-sdk/openai-compatible",
|
|
3163
|
+
name: "Custom OpenAI-compatible",
|
|
3164
|
+
options: {
|
|
3165
|
+
baseURL: "{env:CUSTOM_OPENAI_BASE_URL}",
|
|
3166
|
+
apiKey: "{env:CUSTOM_OPENAI_API_KEY}"
|
|
3167
|
+
},
|
|
3168
|
+
models: {
|
|
3169
|
+
"default-model": { tool_call: true },
|
|
3170
|
+
"small-model": { tool_call: true }
|
|
3171
|
+
}
|
|
3172
|
+
} }
|
|
3173
|
+
}
|
|
3174
|
+
};
|
|
3175
|
+
const PROFILE_PROVIDER_KEYS = new Set([
|
|
3176
|
+
"github-copilot",
|
|
3177
|
+
"opencode",
|
|
3178
|
+
"openai",
|
|
3179
|
+
"ollama",
|
|
3180
|
+
"wafer",
|
|
3181
|
+
"custom"
|
|
3182
|
+
]);
|
|
3183
|
+
const PROVIDER_PROFILE_OPTIONS = [
|
|
3184
|
+
{
|
|
3185
|
+
value: "existing-global",
|
|
3186
|
+
label: "Existing global config",
|
|
3187
|
+
hint: "use your global OpenCode config, no model changes"
|
|
3188
|
+
},
|
|
3189
|
+
{
|
|
3190
|
+
value: "opencode-zen",
|
|
3191
|
+
label: "OpenCode Zen",
|
|
3192
|
+
hint: "curated models, /connect required"
|
|
3193
|
+
},
|
|
3194
|
+
{
|
|
3195
|
+
value: "openai",
|
|
3196
|
+
label: "OpenAI",
|
|
3197
|
+
hint: "GPT models, /connect or API key"
|
|
3198
|
+
},
|
|
3199
|
+
{
|
|
3200
|
+
value: "ollama",
|
|
3201
|
+
label: "Ollama",
|
|
3202
|
+
hint: "local models, no API key needed"
|
|
3203
|
+
},
|
|
3204
|
+
{
|
|
3205
|
+
value: "wafer",
|
|
3206
|
+
label: "Wafer",
|
|
3207
|
+
hint: "GLM models, /connect or API key"
|
|
3208
|
+
},
|
|
3209
|
+
{
|
|
3210
|
+
value: "github-copilot",
|
|
3211
|
+
label: "GitHub Copilot",
|
|
3212
|
+
hint: "OAuth device flow, subscription required"
|
|
3213
|
+
},
|
|
3214
|
+
{
|
|
3215
|
+
value: "custom-openai-compatible",
|
|
3216
|
+
label: "Custom OpenAI-compatible",
|
|
3217
|
+
hint: "any OpenAI-compatible server"
|
|
3218
|
+
},
|
|
3219
|
+
{
|
|
3220
|
+
value: "custom",
|
|
3221
|
+
label: "Custom",
|
|
3222
|
+
hint: "configure each agent individually"
|
|
3223
|
+
},
|
|
3224
|
+
{
|
|
3225
|
+
value: "skip",
|
|
3226
|
+
label: "Skip",
|
|
3227
|
+
hint: "keep template defaults"
|
|
3228
|
+
}
|
|
3229
|
+
];
|
|
3230
|
+
function applyModelProfileToConfig(config, profile) {
|
|
3231
|
+
const profileConfig = PROVIDER_PROFILES[profile];
|
|
3232
|
+
if (!profileConfig) return;
|
|
3233
|
+
if (profile === "existing-global") {
|
|
3234
|
+
delete config.model;
|
|
3235
|
+
delete config.small_model;
|
|
3236
|
+
if (config.provider && typeof config.provider === "object") {
|
|
3237
|
+
for (const providerKey of PROFILE_PROVIDER_KEYS) delete config.provider[providerKey];
|
|
3238
|
+
if (Object.keys(config.provider).length === 0) delete config.provider;
|
|
3239
|
+
}
|
|
3240
|
+
if (config.agent && typeof config.agent === "object") for (const agent of Object.values(config.agent)) delete agent.model;
|
|
3241
|
+
return;
|
|
3242
|
+
}
|
|
3243
|
+
if (profileConfig.provider) config.provider = {
|
|
3244
|
+
...config.provider,
|
|
3245
|
+
...profileConfig.provider
|
|
3246
|
+
};
|
|
3247
|
+
const currentProviderKey = profileConfig.provider && typeof profileConfig.provider === "object" ? Object.keys(profileConfig.provider)[0] : profile === "github-copilot" ? "github-copilot" : profile === "opencode-zen" ? "opencode" : profile === "openai" ? "openai" : void 0;
|
|
3248
|
+
if (config.provider && typeof config.provider === "object") {
|
|
3249
|
+
for (const providerKey of PROFILE_PROVIDER_KEYS) if (providerKey !== currentProviderKey) delete config.provider[providerKey];
|
|
3250
|
+
}
|
|
3251
|
+
if (profileConfig.model) config.model = profileConfig.model;
|
|
3252
|
+
if (profileConfig.smallModel) config.small_model = profileConfig.smallModel;
|
|
3253
|
+
if (profileConfig.agents) {
|
|
3254
|
+
config.agent = getRecord(config.agent);
|
|
3255
|
+
for (const [agentName, model] of Object.entries(profileConfig.agents)) config.agent[agentName] = {
|
|
3256
|
+
...getRecord(config.agent[agentName]),
|
|
3257
|
+
model
|
|
3258
|
+
};
|
|
3259
|
+
}
|
|
3260
|
+
}
|
|
3261
|
+
function applyProviderProfileAtConfigPath(configPath, profile) {
|
|
3262
|
+
if (!existsSync(configPath)) return;
|
|
3263
|
+
const config = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
3264
|
+
applyModelProfileToConfig(config, profile);
|
|
3265
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
3266
|
+
}
|
|
3267
|
+
function getRecord(value) {
|
|
3268
|
+
return value && typeof value === "object" && !Array.isArray(value) ? { ...value } : {};
|
|
3269
|
+
}
|
|
3270
|
+
function withMcpDefaults(existing, defaults) {
|
|
3271
|
+
const existingRecord = getRecord(existing);
|
|
3272
|
+
return {
|
|
3273
|
+
...defaults,
|
|
3274
|
+
...existingRecord,
|
|
3275
|
+
type: defaults.type,
|
|
3276
|
+
enabled: defaults.enabled
|
|
3277
|
+
};
|
|
3278
|
+
}
|
|
3279
|
+
function applyProviderProfile(targetDir, profile) {
|
|
3280
|
+
applyProviderProfileAtConfigPath(join(targetDir, ".opencode", "opencode.json"), profile);
|
|
3281
|
+
}
|
|
3282
|
+
function applyMcpPresetAtConfigPath(configPath, preset, webclawMode = "auto") {
|
|
3283
|
+
if (!existsSync(configPath)) return;
|
|
3284
|
+
const config = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
3285
|
+
const mcp = { ...config.mcp };
|
|
3286
|
+
const context7Enabled = preset !== "minimal" && preset !== "local-first";
|
|
3287
|
+
const tilthEnabled = preset !== "minimal";
|
|
3288
|
+
const tilthThreads = preset === "power" ? "16" : "8";
|
|
3289
|
+
const defaultTimeout = preset === "power" ? 18e4 : 12e4;
|
|
3290
|
+
mcp.context7 = withMcpDefaults(mcp.context7, {
|
|
3291
|
+
type: "local",
|
|
3292
|
+
command: [
|
|
3293
|
+
"npx",
|
|
3294
|
+
"-y",
|
|
3295
|
+
"@upstash/context7-mcp"
|
|
3296
|
+
],
|
|
3297
|
+
enabled: context7Enabled,
|
|
3298
|
+
timeout: defaultTimeout
|
|
3299
|
+
});
|
|
3300
|
+
const existingTilth = getRecord(mcp.tilth);
|
|
3301
|
+
mcp.tilth = withMcpDefaults(existingTilth, {
|
|
3302
|
+
type: "local",
|
|
3303
|
+
command: [
|
|
3304
|
+
"npx",
|
|
3305
|
+
"-y",
|
|
3306
|
+
"tilth",
|
|
3307
|
+
"--mcp",
|
|
3308
|
+
"--edit"
|
|
3309
|
+
],
|
|
3310
|
+
enabled: tilthEnabled,
|
|
3311
|
+
timeout: defaultTimeout,
|
|
3312
|
+
environment: {
|
|
3313
|
+
TILTH_THREADS: tilthThreads,
|
|
3314
|
+
...getRecord(existingTilth.environment)
|
|
3315
|
+
}
|
|
3316
|
+
});
|
|
3317
|
+
const effectiveWebclawMode = webclawMode === "auto" ? preset === "recommended" || preset === "power" ? "host-binary" : "disabled" : webclawMode;
|
|
3318
|
+
const webclawCommand = effectiveWebclawMode === "docker-existing" ? [
|
|
3319
|
+
"docker",
|
|
3320
|
+
"exec",
|
|
3321
|
+
"-i",
|
|
3322
|
+
"webclaw-api",
|
|
3323
|
+
"webclaw-mcp"
|
|
3324
|
+
] : ["webclaw-mcp"];
|
|
3325
|
+
mcp.webclaw = withMcpDefaults(mcp.webclaw, {
|
|
3326
|
+
type: "local",
|
|
3327
|
+
command: webclawCommand,
|
|
3328
|
+
enabled: effectiveWebclawMode !== "disabled" && preset !== "minimal",
|
|
3329
|
+
timeout: defaultTimeout
|
|
3330
|
+
});
|
|
3331
|
+
config.mcp = mcp;
|
|
3332
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
3333
|
+
}
|
|
3334
|
+
function applyMcpPreset(targetDir, preset, webclawMode = "auto") {
|
|
3335
|
+
applyMcpPresetAtConfigPath(join(targetDir, ".opencode", "opencode.json"), preset, webclawMode);
|
|
3336
|
+
}
|
|
3124
3337
|
function applyModelPreset(targetDir, preset) {
|
|
3125
3338
|
const configPath = join(targetDir, ".opencode", "opencode.json");
|
|
3126
3339
|
if (!existsSync(configPath)) return;
|
|
@@ -3132,26 +3345,49 @@ function applyModelPreset(targetDir, preset) {
|
|
|
3132
3345
|
}
|
|
3133
3346
|
writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
3134
3347
|
}
|
|
3348
|
+
const SUPERPOWERS_PLUGIN = "superpowers@git+https://github.com/obra/superpowers.git#v5.1.0";
|
|
3349
|
+
function addPluginToConfig(config, plugin) {
|
|
3350
|
+
const existingPlugins = config.plugin;
|
|
3351
|
+
if (existingPlugins === void 0) return {
|
|
3352
|
+
...config,
|
|
3353
|
+
plugin: [plugin]
|
|
3354
|
+
};
|
|
3355
|
+
if (!Array.isArray(existingPlugins) || existingPlugins.some((existingPlugin) => typeof existingPlugin !== "string")) throw new Error("Invalid opencode.json: plugin must be an array of strings");
|
|
3356
|
+
if (existingPlugins.includes(plugin)) return config;
|
|
3357
|
+
return {
|
|
3358
|
+
...config,
|
|
3359
|
+
plugin: [...existingPlugins, plugin]
|
|
3360
|
+
};
|
|
3361
|
+
}
|
|
3362
|
+
function enableSuperpowersPluginAtConfigPath(configPath) {
|
|
3363
|
+
if (!existsSync(configPath)) return;
|
|
3364
|
+
const updatedConfig = addPluginToConfig(JSON.parse(readFileSync(configPath, "utf-8")), SUPERPOWERS_PLUGIN);
|
|
3365
|
+
writeFileSync(configPath, JSON.stringify(updatedConfig, null, 2));
|
|
3366
|
+
}
|
|
3367
|
+
function enableSuperpowersPlugin(targetDir) {
|
|
3368
|
+
enableSuperpowersPluginAtConfigPath(join(targetDir, ".opencode", "opencode.json"));
|
|
3369
|
+
}
|
|
3135
3370
|
const AGENT_DESCRIPTIONS = {
|
|
3136
3371
|
build: "Main coding agent (complex tasks)",
|
|
3137
3372
|
plan: "Planning and design agent",
|
|
3138
|
-
review: "
|
|
3373
|
+
review: "Correctness and security review",
|
|
3374
|
+
verify: "Goal verification and completion checks",
|
|
3375
|
+
debugger: "Root-cause debugging and fix paths",
|
|
3139
3376
|
explore: "Fast codebase search",
|
|
3140
3377
|
general: "Quick, simple tasks",
|
|
3141
3378
|
painter: "Image generation and editing",
|
|
3142
3379
|
vision: "Visual analysis (quality)",
|
|
3143
|
-
scout: "External research/docs"
|
|
3144
|
-
compaction: "Context summarization"
|
|
3380
|
+
scout: "External research/docs"
|
|
3145
3381
|
};
|
|
3146
3382
|
async function promptCustomModels(targetDir) {
|
|
3147
3383
|
const configPath = join(targetDir, ".opencode", "opencode.json");
|
|
3148
3384
|
if (!existsSync(configPath)) return;
|
|
3149
3385
|
const config = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
3150
|
-
p.log.info(color.dim("Enter model IDs (e.g.,
|
|
3386
|
+
p.log.info(color.dim("Enter model IDs (e.g., opencode/big-pickle, openai/gpt-5.1, ollama/qwen3-coder:latest)"));
|
|
3151
3387
|
p.log.info(color.dim("Press Enter to keep current value\n"));
|
|
3152
3388
|
const mainModel = await p.text({
|
|
3153
3389
|
message: "Main session model",
|
|
3154
|
-
placeholder: config.model || "
|
|
3390
|
+
placeholder: config.model || "opencode/big-pickle",
|
|
3155
3391
|
defaultValue: config.model
|
|
3156
3392
|
});
|
|
3157
3393
|
if (p.isCancel(mainModel)) {
|
|
@@ -3195,7 +3431,7 @@ function backupOpenCode(targetDir) {
|
|
|
3195
3431
|
return backupDir;
|
|
3196
3432
|
}
|
|
3197
3433
|
function getTemplateFiles(templateRoot) {
|
|
3198
|
-
const opencodeSrc = join(templateRoot,
|
|
3434
|
+
const opencodeSrc = join(templateRoot, TEMPLATE_SOURCE_DIR$2);
|
|
3199
3435
|
if (!existsSync(opencodeSrc)) return /* @__PURE__ */ new Set();
|
|
3200
3436
|
return new Set(getAffectedFiles(opencodeSrc));
|
|
3201
3437
|
}
|
|
@@ -3209,7 +3445,7 @@ function findOrphans(targetDir, templateFiles) {
|
|
|
3209
3445
|
* Returns the template content if it's a modified template file, null otherwise.
|
|
3210
3446
|
*/
|
|
3211
3447
|
function getModifiedTemplateContent(templateRoot, orphanPath) {
|
|
3212
|
-
const templateFilePath = join(templateRoot,
|
|
3448
|
+
const templateFilePath = join(templateRoot, TEMPLATE_SOURCE_DIR$2, orphanPath);
|
|
3213
3449
|
if (!existsSync(templateFilePath)) return null;
|
|
3214
3450
|
return readFileSync(templateFilePath, "utf-8");
|
|
3215
3451
|
}
|
|
@@ -3268,6 +3504,11 @@ function preserveUserFiles(targetDir) {
|
|
|
3268
3504
|
if (!existsSync(dirPath)) continue;
|
|
3269
3505
|
collectFiles(dirPath, relDir);
|
|
3270
3506
|
}
|
|
3507
|
+
for (const relativePath of PRESERVE_USER_FILES) {
|
|
3508
|
+
const filePath = join(opencodeDir, relativePath);
|
|
3509
|
+
if (!existsSync(filePath)) continue;
|
|
3510
|
+
preserved.set(relativePath, readFileSync(filePath, "utf-8"));
|
|
3511
|
+
}
|
|
3271
3512
|
return preserved;
|
|
3272
3513
|
}
|
|
3273
3514
|
/**
|
|
@@ -3311,14 +3552,31 @@ async function initCommand(rawOptions = {}) {
|
|
|
3311
3552
|
}
|
|
3312
3553
|
const s = p.spinner();
|
|
3313
3554
|
s.start("Copying to global config");
|
|
3314
|
-
const opencodeSrc = join(templateRoot,
|
|
3555
|
+
const opencodeSrc = join(templateRoot, TEMPLATE_SOURCE_DIR$2);
|
|
3315
3556
|
if (!existsSync(opencodeSrc)) {
|
|
3316
3557
|
s.stop("Failed");
|
|
3317
|
-
p.log.error("Template
|
|
3558
|
+
p.log.error("Template opencode bundle not found");
|
|
3318
3559
|
p.outro(color.red("Failed"));
|
|
3319
3560
|
process.exit(1);
|
|
3320
3561
|
}
|
|
3321
3562
|
await copyDir(opencodeSrc, globalDir);
|
|
3563
|
+
const globalConfigPath = join(globalDir, "opencode.json");
|
|
3564
|
+
if (options.providerProfile === "existing-global") {
|
|
3565
|
+
s.stop("Failed");
|
|
3566
|
+
p.log.error("--provider-profile existing-global cannot be used with --global because global config cannot inherit model defaults");
|
|
3567
|
+
p.outro(color.red("Failed"));
|
|
3568
|
+
process.exit(1);
|
|
3569
|
+
}
|
|
3570
|
+
if (options.providerProfile) {
|
|
3571
|
+
if (options.free || options.recommend) p.log.warn("--provider-profile takes precedence over --free/--recommend model presets");
|
|
3572
|
+
applyProviderProfileAtConfigPath(globalConfigPath, options.providerProfile);
|
|
3573
|
+
p.log.info(`Applied provider profile: ${options.providerProfile}`);
|
|
3574
|
+
}
|
|
3575
|
+
if (options.mcpPreset) {
|
|
3576
|
+
applyMcpPresetAtConfigPath(globalConfigPath, options.mcpPreset, options.webclawMode);
|
|
3577
|
+
p.log.info(`Applied MCP preset: ${options.mcpPreset}`);
|
|
3578
|
+
}
|
|
3579
|
+
if (options.withSuperpowers) enableSuperpowersPluginAtConfigPath(globalConfigPath);
|
|
3322
3580
|
s.stop("Done");
|
|
3323
3581
|
p.note(`Global config installed at:\n${globalDir}\n\nThis provides default agents, skills, and tools\nfor all OpenCode projects on this machine.`, "Global Installation Complete");
|
|
3324
3582
|
p.outro(color.green("Ready!"));
|
|
@@ -3403,65 +3661,65 @@ async function initCommand(rawOptions = {}) {
|
|
|
3403
3661
|
} else if (globalConfig && options.yes) p.log.info(`Global config found at ${color.cyan(globalConfig.dir)} — use ${color.bold("--project-only")} to skip shared dirs`);
|
|
3404
3662
|
}
|
|
3405
3663
|
const s = p.spinner();
|
|
3664
|
+
const variantName = options.variant ?? "full";
|
|
3665
|
+
const variantFilter = getVariantFilter(variantName);
|
|
3406
3666
|
if (mode === "scaffold") {
|
|
3407
3667
|
s.start("Scaffolding project");
|
|
3408
3668
|
mkdirSync(targetDir, { recursive: true });
|
|
3409
3669
|
} else if (mode === "add-config") s.start("Adding OpenCodeKit");
|
|
3410
3670
|
else s.start("Reinitializing");
|
|
3411
|
-
if (!await copyOpenCodeOnly(templateRoot, targetDir, skipDirs)) {
|
|
3671
|
+
if (!await copyOpenCodeOnly(templateRoot, targetDir, skipDirs, variantFilter)) {
|
|
3412
3672
|
s.stop("Failed");
|
|
3413
3673
|
p.outro(color.red("Template copy failed"));
|
|
3414
3674
|
process.exit(1);
|
|
3415
3675
|
}
|
|
3416
3676
|
s.stop("Done");
|
|
3677
|
+
if (!isFullVariant(variantName)) {
|
|
3678
|
+
const counts = {
|
|
3679
|
+
agents: variantFilter.agents.length || "all",
|
|
3680
|
+
commands: variantFilter.commands.length || "all",
|
|
3681
|
+
skills: variantFilter.skills.length || "all"
|
|
3682
|
+
};
|
|
3683
|
+
p.log.info(`Variant: ${color.bold(variantName)} — agents: ${counts.agents}, commands: ${counts.commands}, skills: ${counts.skills}`);
|
|
3684
|
+
}
|
|
3417
3685
|
if (skipDirs.length > 0) p.log.info(`Project-only init: skipped ${skipDirs.map((d) => color.dim(d)).join(", ")} (using global config)`);
|
|
3418
3686
|
const restoredFileCount = finalizeInstalledFiles(targetDir, getPackageVersion$1(), preservedFiles);
|
|
3419
3687
|
if (restoredFileCount > 0) p.log.info(`Preserved ${restoredFileCount} user memory files (memory/project/)`);
|
|
3420
|
-
if (options.
|
|
3688
|
+
if (options.providerProfile) {
|
|
3689
|
+
if (options.free || options.recommend) p.log.warn("--provider-profile takes precedence over --free/--recommend model presets");
|
|
3690
|
+
applyProviderProfile(targetDir, options.providerProfile);
|
|
3691
|
+
p.log.info(`Applied provider profile: ${options.providerProfile}`);
|
|
3692
|
+
} else if (options.free) {
|
|
3421
3693
|
applyModelPreset(targetDir, "free");
|
|
3422
3694
|
p.log.info("Applied free model preset");
|
|
3423
3695
|
} else if (options.recommend) {
|
|
3424
3696
|
applyModelPreset(targetDir, "recommend");
|
|
3425
3697
|
p.log.info("Applied recommended model preset");
|
|
3426
3698
|
} else if (options.yes) {
|
|
3427
|
-
|
|
3428
|
-
p.log.info("Applied
|
|
3699
|
+
applyProviderProfile(targetDir, "existing-global");
|
|
3700
|
+
p.log.info("Applied existing-global provider profile (default for CI)");
|
|
3429
3701
|
} else {
|
|
3430
|
-
const
|
|
3431
|
-
message: "Choose
|
|
3432
|
-
options:
|
|
3433
|
-
{
|
|
3434
|
-
value: "free",
|
|
3435
|
-
label: "Free models",
|
|
3436
|
-
hint: "minimax, glm, grok (no API costs)"
|
|
3437
|
-
},
|
|
3438
|
-
{
|
|
3439
|
-
value: "recommend",
|
|
3440
|
-
label: "Recommended models",
|
|
3441
|
-
hint: "gpt-5.4, gpt-5.3-codex, sonnet-4.6, gemini-3.1"
|
|
3442
|
-
},
|
|
3443
|
-
{
|
|
3444
|
-
value: "custom",
|
|
3445
|
-
label: "Custom",
|
|
3446
|
-
hint: "configure each agent individually"
|
|
3447
|
-
},
|
|
3448
|
-
{
|
|
3449
|
-
value: "skip",
|
|
3450
|
-
label: "Skip",
|
|
3451
|
-
hint: "keep template defaults"
|
|
3452
|
-
}
|
|
3453
|
-
]
|
|
3702
|
+
const selection = await p.select({
|
|
3703
|
+
message: "Choose provider profile",
|
|
3704
|
+
options: PROVIDER_PROFILE_OPTIONS
|
|
3454
3705
|
});
|
|
3455
|
-
if (!p.isCancel(
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
}
|
|
3706
|
+
if (!p.isCancel(selection)) if (selection === "custom") {
|
|
3707
|
+
await promptCustomModels(targetDir);
|
|
3708
|
+
p.log.info("Applied custom model configuration");
|
|
3709
|
+
} else if (selection === "skip") p.log.info("Keeping template defaults");
|
|
3710
|
+
else {
|
|
3711
|
+
applyProviderProfile(targetDir, selection);
|
|
3712
|
+
p.log.info(`Applied provider profile: ${selection}`);
|
|
3463
3713
|
}
|
|
3464
3714
|
}
|
|
3715
|
+
if (options.mcpPreset) {
|
|
3716
|
+
applyMcpPreset(targetDir, options.mcpPreset, options.webclawMode);
|
|
3717
|
+
p.log.info(`Applied MCP preset: ${options.mcpPreset}`);
|
|
3718
|
+
}
|
|
3719
|
+
if (options.withSuperpowers) {
|
|
3720
|
+
enableSuperpowersPlugin(targetDir);
|
|
3721
|
+
p.log.info("Enabled upstream Superpowers plugin");
|
|
3722
|
+
}
|
|
3465
3723
|
if (options.beads) {
|
|
3466
3724
|
const beadsDir = join(targetDir, ".beads");
|
|
3467
3725
|
if (!existsSync(beadsDir)) {
|
|
@@ -3579,76 +3837,126 @@ async function initCommand(rawOptions = {}) {
|
|
|
3579
3837
|
p.outro(color.green("Ready to code!"));
|
|
3580
3838
|
}
|
|
3581
3839
|
//#endregion
|
|
3582
|
-
//#region src/
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
p.log.error(`Unknown action: ${mode}`);
|
|
3594
|
-
p.log.info(`Available: ${color.cyan("status")}, ${color.cyan("deactivate")}`);
|
|
3840
|
+
//#region src/utils/jsonc.ts
|
|
3841
|
+
/**
|
|
3842
|
+
* Parse a JSONC string into a JavaScript value.
|
|
3843
|
+
*
|
|
3844
|
+
* @param input - JSONC string (may contain // comments, block comments, and trailing commas)
|
|
3845
|
+
* @returns Parsed value
|
|
3846
|
+
* @throws SyntaxError if the result is not valid JSON after stripping
|
|
3847
|
+
*/
|
|
3848
|
+
function parseJsonc(input) {
|
|
3849
|
+
const stripped = stripJsonc(input);
|
|
3850
|
+
return JSON.parse(stripped);
|
|
3595
3851
|
}
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3852
|
+
/**
|
|
3853
|
+
* Strip JSONC extensions from a string, producing valid JSON.
|
|
3854
|
+
*
|
|
3855
|
+
* 1. Removes single-line comments (// ... until EOL)
|
|
3856
|
+
* 2. Removes block comments (/* ... */)
|
|
3857
|
+
* 3. Removes trailing commas before } or ]
|
|
3858
|
+
*
|
|
3859
|
+
* Handles edge cases:
|
|
3860
|
+
* - Comments inside strings are preserved
|
|
3861
|
+
* - Escaped quotes inside strings don't break parsing
|
|
3862
|
+
* - Nested brackets/braces are tracked correctly
|
|
3863
|
+
*/
|
|
3864
|
+
function stripJsonc(input) {
|
|
3865
|
+
let result = "";
|
|
3866
|
+
let i = 0;
|
|
3867
|
+
const len = input.length;
|
|
3868
|
+
while (i < len) {
|
|
3869
|
+
const ch = input[i];
|
|
3870
|
+
if (ch === "\"") {
|
|
3871
|
+
result += ch;
|
|
3872
|
+
i++;
|
|
3873
|
+
while (i < len) {
|
|
3874
|
+
const s = input[i];
|
|
3875
|
+
result += s;
|
|
3876
|
+
i++;
|
|
3877
|
+
if (s === "\\") {
|
|
3878
|
+
if (i < len) {
|
|
3879
|
+
result += input[i];
|
|
3880
|
+
i++;
|
|
3881
|
+
}
|
|
3882
|
+
} else if (s === "\"") break;
|
|
3883
|
+
}
|
|
3884
|
+
continue;
|
|
3885
|
+
}
|
|
3886
|
+
if (ch === "/" && i + 1 < len && input[i + 1] === "/") {
|
|
3887
|
+
i += 2;
|
|
3888
|
+
while (i < len && input[i] !== "\n") i++;
|
|
3889
|
+
continue;
|
|
3890
|
+
}
|
|
3891
|
+
if (ch === "/" && i + 1 < len && input[i + 1] === "*") {
|
|
3892
|
+
i += 2;
|
|
3893
|
+
while (i + 1 < len && !(input[i] === "*" && input[i + 1] === "/")) {
|
|
3894
|
+
if (input[i] === "\n") result += "\n";
|
|
3895
|
+
i++;
|
|
3896
|
+
}
|
|
3897
|
+
if (i + 1 < len && input[i] === "*" && input[i + 1] === "/") i += 2;
|
|
3898
|
+
else i = len;
|
|
3899
|
+
continue;
|
|
3900
|
+
}
|
|
3901
|
+
result += ch;
|
|
3902
|
+
i++;
|
|
3626
3903
|
}
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
3633
|
-
|
|
3904
|
+
return stripTrailingCommas(result);
|
|
3905
|
+
}
|
|
3906
|
+
/**
|
|
3907
|
+
* Remove trailing commas before closing } or ].
|
|
3908
|
+
* Works on the already-comment-stripped string.
|
|
3909
|
+
*/
|
|
3910
|
+
function stripTrailingCommas(input) {
|
|
3911
|
+
let result = "";
|
|
3912
|
+
let i = 0;
|
|
3913
|
+
const len = input.length;
|
|
3914
|
+
while (i < len) {
|
|
3915
|
+
const ch = input[i];
|
|
3916
|
+
if (ch === "\"") {
|
|
3917
|
+
result += ch;
|
|
3918
|
+
i++;
|
|
3919
|
+
while (i < len) {
|
|
3920
|
+
const s = input[i];
|
|
3921
|
+
result += s;
|
|
3922
|
+
i++;
|
|
3923
|
+
if (s === "\\") {
|
|
3924
|
+
if (i < len) {
|
|
3925
|
+
result += input[i];
|
|
3926
|
+
i++;
|
|
3927
|
+
}
|
|
3928
|
+
} else if (s === "\"") break;
|
|
3929
|
+
}
|
|
3930
|
+
continue;
|
|
3931
|
+
}
|
|
3932
|
+
if (ch === ",") {
|
|
3933
|
+
let j = i + 1;
|
|
3934
|
+
while (j < len && /\s/.test(input[j])) j++;
|
|
3935
|
+
if (j < len && (input[j] === "}" || input[j] === "]")) {
|
|
3936
|
+
i++;
|
|
3937
|
+
continue;
|
|
3938
|
+
}
|
|
3939
|
+
}
|
|
3940
|
+
result += ch;
|
|
3941
|
+
i++;
|
|
3634
3942
|
}
|
|
3635
|
-
|
|
3636
|
-
|
|
3943
|
+
return result;
|
|
3944
|
+
}
|
|
3945
|
+
/**
|
|
3946
|
+
* Validate a JSONC string, returning any parse errors.
|
|
3947
|
+
*
|
|
3948
|
+
* @param input - JSONC string
|
|
3949
|
+
* @returns { valid: true } or { valid: false, error: string }
|
|
3950
|
+
*/
|
|
3951
|
+
function validateJsonc(input) {
|
|
3637
3952
|
try {
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
|
|
3645
|
-
const retry = await p.confirm({
|
|
3646
|
-
message: "Remove local license file anyway?",
|
|
3647
|
-
initialValue: false
|
|
3648
|
-
});
|
|
3649
|
-
if (p.isCancel(retry) || !retry) return;
|
|
3650
|
-
deleteStoredLicense();
|
|
3651
|
-
p.log.info(`Removed local license at ${color.dim(getLicenseFilePath())}`);
|
|
3953
|
+
parseJsonc(input);
|
|
3954
|
+
return { valid: true };
|
|
3955
|
+
} catch (err) {
|
|
3956
|
+
return {
|
|
3957
|
+
valid: false,
|
|
3958
|
+
error: err instanceof Error ? err.message : String(err)
|
|
3959
|
+
};
|
|
3652
3960
|
}
|
|
3653
3961
|
}
|
|
3654
3962
|
//#endregion
|
|
@@ -3933,10 +4241,11 @@ const SKIP_DIRS = [
|
|
|
3933
4241
|
"dist",
|
|
3934
4242
|
"coverage"
|
|
3935
4243
|
];
|
|
4244
|
+
const TEMPLATE_SOURCE_DIR$1 = "opencode";
|
|
3936
4245
|
function getTemplateRoot() {
|
|
3937
4246
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
3938
|
-
const possiblePaths = [join(__dirname, "template"), join(__dirname, "..", "..", "
|
|
3939
|
-
for (const path of possiblePaths) if (existsSync(join(path,
|
|
4247
|
+
const possiblePaths = [join(__dirname, "template"), join(__dirname, "..", "..", "template")];
|
|
4248
|
+
for (const path of possiblePaths) if (existsSync(join(path, TEMPLATE_SOURCE_DIR$1))) return path;
|
|
3940
4249
|
return null;
|
|
3941
4250
|
}
|
|
3942
4251
|
function getCurrentVersion(opencodeDir) {
|
|
@@ -4080,9 +4389,9 @@ async function upgradeCommand(rawOptions = {}) {
|
|
|
4080
4389
|
showError("Template not found", "Reinstall ultrakit");
|
|
4081
4390
|
return;
|
|
4082
4391
|
}
|
|
4083
|
-
const templateOpencode = join(templateRoot,
|
|
4392
|
+
const templateOpencode = join(templateRoot, TEMPLATE_SOURCE_DIR$1);
|
|
4084
4393
|
if (!existsSync(templateOpencode)) {
|
|
4085
|
-
showError("Template
|
|
4394
|
+
showError("Template opencode bundle not found");
|
|
4086
4395
|
return;
|
|
4087
4396
|
}
|
|
4088
4397
|
if (!options.force) {
|
|
@@ -4279,7 +4588,8 @@ const KNOWN_CONFIG_PROPERTIES = new Set([
|
|
|
4279
4588
|
]);
|
|
4280
4589
|
async function doctorCommand() {
|
|
4281
4590
|
if (process.argv.includes("--quiet")) return;
|
|
4282
|
-
const
|
|
4591
|
+
const cwd = process.cwd();
|
|
4592
|
+
const opencodeDir = join(cwd, ".opencode");
|
|
4283
4593
|
p.intro(color.bgBlue(color.white(" Doctor - Health Check ")));
|
|
4284
4594
|
const checks = [];
|
|
4285
4595
|
const warnings = [];
|
|
@@ -4461,6 +4771,138 @@ async function doctorCommand() {
|
|
|
4461
4771
|
});
|
|
4462
4772
|
checks.push(...toolChecks);
|
|
4463
4773
|
displayChecks(toolChecks);
|
|
4774
|
+
console.log();
|
|
4775
|
+
console.log(color.bold(" Template Drift"));
|
|
4776
|
+
const manifestChecks = [];
|
|
4777
|
+
const manifest = loadManifest(opencodeDir);
|
|
4778
|
+
if (manifest) {
|
|
4779
|
+
let driftedCount = 0;
|
|
4780
|
+
const totalTemplateFiles = Object.keys(manifest.files).length;
|
|
4781
|
+
for (const [relPath, expectedHash] of Object.entries(manifest.files)) {
|
|
4782
|
+
const fullPath = join(opencodeDir, relPath);
|
|
4783
|
+
if (!existsSync(fullPath)) {
|
|
4784
|
+
driftedCount++;
|
|
4785
|
+
continue;
|
|
4786
|
+
}
|
|
4787
|
+
if (createHash("sha256").update(readFileSync(fullPath, "utf-8")).digest("hex") !== expectedHash) driftedCount++;
|
|
4788
|
+
}
|
|
4789
|
+
const orphanDirs = [
|
|
4790
|
+
"agent",
|
|
4791
|
+
"command",
|
|
4792
|
+
"skill",
|
|
4793
|
+
"tool"
|
|
4794
|
+
];
|
|
4795
|
+
let orphanCount = 0;
|
|
4796
|
+
for (const dir of orphanDirs) {
|
|
4797
|
+
const dirPath = join(opencodeDir, dir);
|
|
4798
|
+
if (!existsSync(dirPath)) continue;
|
|
4799
|
+
for (const entry of readdirSync(dirPath)) if (!(`${dir}/${entry}` in manifest.files)) orphanCount++;
|
|
4800
|
+
}
|
|
4801
|
+
manifestChecks.push({
|
|
4802
|
+
name: `Manifest version (${manifest.version})`,
|
|
4803
|
+
ok: true
|
|
4804
|
+
});
|
|
4805
|
+
manifestChecks.push({
|
|
4806
|
+
name: `Template files (${totalTemplateFiles - driftedCount}/${totalTemplateFiles} unmodified)`,
|
|
4807
|
+
ok: driftedCount === 0,
|
|
4808
|
+
warn: driftedCount > 0,
|
|
4809
|
+
fix: driftedCount > 0 ? `${driftedCount} file(s) modified — use 'uk upgrade' to review` : void 0
|
|
4810
|
+
});
|
|
4811
|
+
if (orphanCount > 0) warnings.push({
|
|
4812
|
+
name: `${orphanCount} orphan file(s) not in template manifest`,
|
|
4813
|
+
ok: false,
|
|
4814
|
+
warn: true
|
|
4815
|
+
});
|
|
4816
|
+
} else manifestChecks.push({
|
|
4817
|
+
name: `${MANIFEST_FILE} exists`,
|
|
4818
|
+
ok: false,
|
|
4819
|
+
warn: true,
|
|
4820
|
+
fix: "Run 'uk init' or 'uk upgrade' to generate manifest"
|
|
4821
|
+
});
|
|
4822
|
+
checks.push(...manifestChecks);
|
|
4823
|
+
displayChecks(manifestChecks);
|
|
4824
|
+
console.log();
|
|
4825
|
+
console.log(color.bold(" JSONC Config"));
|
|
4826
|
+
const jsoncChecks = [];
|
|
4827
|
+
for (const jsoncFile of ["dcp.jsonc", "opencodex-fast.jsonc"]) {
|
|
4828
|
+
const jsoncPath = join(opencodeDir, jsoncFile);
|
|
4829
|
+
if (!existsSync(jsoncPath)) continue;
|
|
4830
|
+
try {
|
|
4831
|
+
const validation = validateJsonc(readFileSync(jsoncPath, "utf-8"));
|
|
4832
|
+
if (validation.valid) jsoncChecks.push({
|
|
4833
|
+
name: `${jsoncFile} valid`,
|
|
4834
|
+
ok: true
|
|
4835
|
+
});
|
|
4836
|
+
else jsoncChecks.push({
|
|
4837
|
+
name: `${jsoncFile} parse error`,
|
|
4838
|
+
ok: false,
|
|
4839
|
+
fix: `Fix syntax: ${validation.error}`
|
|
4840
|
+
});
|
|
4841
|
+
} catch {
|
|
4842
|
+
jsoncChecks.push({
|
|
4843
|
+
name: `${jsoncFile} read error`,
|
|
4844
|
+
ok: false,
|
|
4845
|
+
fix: "Check file permissions"
|
|
4846
|
+
});
|
|
4847
|
+
}
|
|
4848
|
+
}
|
|
4849
|
+
if (jsoncChecks.length > 0) {
|
|
4850
|
+
checks.push(...jsoncChecks);
|
|
4851
|
+
displayChecks(jsoncChecks);
|
|
4852
|
+
} else console.log(color.dim(" (no JSONC config files found)"));
|
|
4853
|
+
console.log();
|
|
4854
|
+
console.log(color.bold(" Preservation Safety"));
|
|
4855
|
+
const preservationChecks = [];
|
|
4856
|
+
const memoryProjectDir = join(opencodeDir, "memory", "project");
|
|
4857
|
+
const requiredProjectFiles = [
|
|
4858
|
+
"user.md",
|
|
4859
|
+
"tech-stack.md",
|
|
4860
|
+
"project.md"
|
|
4861
|
+
];
|
|
4862
|
+
const preservedProjectFiles = requiredProjectFiles.filter((f) => existsSync(join(memoryProjectDir, f)));
|
|
4863
|
+
preservationChecks.push({
|
|
4864
|
+
name: `memory/project/ (${preservedProjectFiles.length}/${requiredProjectFiles.length} required files)`,
|
|
4865
|
+
ok: preservedProjectFiles.length === requiredProjectFiles.length,
|
|
4866
|
+
warn: preservedProjectFiles.length > 0 && preservedProjectFiles.length < requiredProjectFiles.length,
|
|
4867
|
+
fix: preservedProjectFiles.length < requiredProjectFiles.length ? `Missing: ${requiredProjectFiles.filter((f) => !preservedProjectFiles.includes(f)).join(", ")}` : void 0
|
|
4868
|
+
});
|
|
4869
|
+
preservationChecks.push({
|
|
4870
|
+
name: "context/ directory",
|
|
4871
|
+
ok: existsSync(join(opencodeDir, "context")),
|
|
4872
|
+
warn: true,
|
|
4873
|
+
fix: "Run '/init-context' to create context directory"
|
|
4874
|
+
});
|
|
4875
|
+
preservationChecks.push({
|
|
4876
|
+
name: ".env file",
|
|
4877
|
+
ok: existsSync(join(opencodeDir, ".env")),
|
|
4878
|
+
warn: true,
|
|
4879
|
+
fix: "Copy from .env.example and fill in secrets"
|
|
4880
|
+
});
|
|
4881
|
+
checks.push(...preservationChecks);
|
|
4882
|
+
displayChecks(preservationChecks);
|
|
4883
|
+
if ([
|
|
4884
|
+
"package.json",
|
|
4885
|
+
"src",
|
|
4886
|
+
"tsdown.config.ts"
|
|
4887
|
+
].every((f) => existsSync(join(cwd, f)))) {
|
|
4888
|
+
const nestedOpencode = existsSync(join(cwd, ".opencode"));
|
|
4889
|
+
const nestedBeads = existsSync(join(cwd, ".beads"));
|
|
4890
|
+
if (nestedOpencode || nestedBeads) {
|
|
4891
|
+
const nestedItems = [];
|
|
4892
|
+
if (nestedOpencode) nestedItems.push(".opencode/");
|
|
4893
|
+
if (nestedBeads) nestedItems.push(".beads/");
|
|
4894
|
+
warnings.push({
|
|
4895
|
+
name: `Nested state dirs in ultrakit source: ${nestedItems.join(", ")}`,
|
|
4896
|
+
ok: false,
|
|
4897
|
+
warn: false
|
|
4898
|
+
});
|
|
4899
|
+
warnings.push({
|
|
4900
|
+
name: "These should be in the project root, not inside ultrakit/",
|
|
4901
|
+
ok: false,
|
|
4902
|
+
warn: true
|
|
4903
|
+
});
|
|
4904
|
+
}
|
|
4905
|
+
}
|
|
4464
4906
|
const errors = checks.filter((c) => !c.ok && !c.warn);
|
|
4465
4907
|
const warningCount = warnings.length + checks.filter((c) => !c.ok && c.warn).length;
|
|
4466
4908
|
if (warnings.length > 0) {
|
|
@@ -4526,6 +4968,7 @@ async function statusCommand() {
|
|
|
4526
4968
|
}
|
|
4527
4969
|
//#endregion
|
|
4528
4970
|
//#region src/commands/patch.ts
|
|
4971
|
+
const TEMPLATE_SOURCE_DIR = "opencode";
|
|
4529
4972
|
function listPatches(opencodeDir) {
|
|
4530
4973
|
const metadata = loadPatchMetadata(opencodeDir);
|
|
4531
4974
|
const entries = Object.entries(metadata.patches);
|
|
@@ -4573,7 +5016,7 @@ async function createPatch$1(opencodeDir) {
|
|
|
4573
5016
|
p.log.info(color.dim("Make sure uk is installed correctly"));
|
|
4574
5017
|
return;
|
|
4575
5018
|
}
|
|
4576
|
-
const templateFilePath = join(templateRoot,
|
|
5019
|
+
const templateFilePath = join(templateRoot, TEMPLATE_SOURCE_DIR, relativePath);
|
|
4577
5020
|
if (!existsSync(templateFilePath)) {
|
|
4578
5021
|
p.log.error(`No template file for ${color.cyan(relativePath)}`);
|
|
4579
5022
|
p.log.info(color.dim("Only template-originated files can be patched"));
|
|
@@ -5898,43 +6341,12 @@ if (process.stdout.setEncoding) process.stdout.setEncoding("utf8");
|
|
|
5898
6341
|
if (process.stderr.setEncoding) process.stderr.setEncoding("utf8");
|
|
5899
6342
|
const packageVersion = version;
|
|
5900
6343
|
const cli = cac("uk");
|
|
5901
|
-
async function ensureLicenseFor(commandName) {
|
|
5902
|
-
try {
|
|
5903
|
-
if ((await requireValidLicense()).mode === "offline-grace") p.log.warn("License server is unreachable. Running in offline grace mode.");
|
|
5904
|
-
return true;
|
|
5905
|
-
} catch (error) {
|
|
5906
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
5907
|
-
p.log.error(`${commandName} requires a valid license`);
|
|
5908
|
-
p.log.info(message);
|
|
5909
|
-
p.log.info("Run: uk activate <LICENSE_KEY>");
|
|
5910
|
-
process.exitCode = 1;
|
|
5911
|
-
return false;
|
|
5912
|
-
}
|
|
5913
|
-
}
|
|
5914
6344
|
cli.option("--verbose", "Enable verbose logging");
|
|
5915
6345
|
cli.option("--quiet", "Suppress all output");
|
|
5916
6346
|
cli.version(`${packageVersion}`);
|
|
5917
|
-
cli.command("init", "Initialize UltraKit in current directory").option("--force", "Reinitialize even if already exists").option("--beads", "Also initialize .beads/ for multi-agent coordination").option("--global", "Install to global OpenCode config (~/.config/opencode/)").option("--free", "Use free models (default)").option("--recommend", "Use recommended premium models").option("-y, --yes", "Skip prompts, use defaults (for CI)").option("--backup", "Backup existing .opencode before overwriting").option("--prune", "Manually select orphan files to delete").option("--prune-all", "Auto-delete all orphan files").option("--project-only", "Only init project-scope files (skip if global config has agents/skills/commands/tools)").action(async (options) => {
|
|
5918
|
-
if (!await ensureLicenseFor("init")) return;
|
|
6347
|
+
cli.command("init", "Initialize UltraKit in current directory").option("--force", "Reinitialize even if already exists").option("--beads", "Also initialize .beads/ for multi-agent coordination").option("--global", "Install to global OpenCode config (~/.config/opencode/)").option("--free", "Use free models (default)").option("--recommend", "Use recommended premium models").option("--provider-profile <profile>", "Provider profile: existing-global, opencode-zen, openai, ollama, wafer, github-copilot, custom-openai-compatible").option("--mcp-preset <preset>", "MCP preset: minimal, recommended, power, local-first").option("--webclaw-mode <mode>", "Webclaw mode: disabled, host-binary, docker-existing").option("--with-superpowers", "Enable upstream Superpowers OpenCode plugin (opt-in)").option("-y, --yes", "Skip prompts, use defaults (for CI)").option("--backup", "Backup existing .opencode before overwriting").option("--prune", "Manually select orphan files to delete").option("--prune-all", "Auto-delete all orphan files").option("--project-only", "Only init project-scope files (skip if global config has agents/skills/commands/tools)").option("--variant <variant>", "Template variant: full (default), minimal, dev").action(async (options) => {
|
|
5919
6348
|
await initCommand(options);
|
|
5920
6349
|
});
|
|
5921
|
-
cli.command("activate [key]", "Activate paid license key").action(async (key) => {
|
|
5922
|
-
await activateCommand(key);
|
|
5923
|
-
});
|
|
5924
|
-
cli.command("license [action]", "Manage license (status, deactivate)").action(async (action) => {
|
|
5925
|
-
await licenseCommand(action);
|
|
5926
|
-
});
|
|
5927
|
-
cli.command("agent [action]", "Manage agents (list, add, view)").action(async (action) => {
|
|
5928
|
-
if (!action) {
|
|
5929
|
-
console.log("\nUsage: uk agent <action>\n");
|
|
5930
|
-
console.log("Actions:");
|
|
5931
|
-
console.log(" list List all agents");
|
|
5932
|
-
console.log(" add Create a new agent");
|
|
5933
|
-
console.log(" view View agent details\n");
|
|
5934
|
-
return;
|
|
5935
|
-
}
|
|
5936
|
-
await agentCommand(action);
|
|
5937
|
-
});
|
|
5938
6350
|
cli.command("command [action]", "Manage slash commands (list, create, show, delete)").action(async (action) => {
|
|
5939
6351
|
if (!action) {
|
|
5940
6352
|
console.log("\nUsage: uk command <action>\n");
|
|
@@ -5965,7 +6377,6 @@ cli.command("config [action]", "Edit opencode.json (model, mcp, permission, vali
|
|
|
5965
6377
|
await configCommand(action);
|
|
5966
6378
|
});
|
|
5967
6379
|
cli.command("upgrade", "Update .opencode/ templates to latest version").option("--force", "Force upgrade even if already up to date").option("--check", "Check for updates without upgrading").option("--prune", "Manually select orphan files to delete").option("--prune-all", "Auto-delete all orphan files").action(async (options) => {
|
|
5968
|
-
if (!await ensureLicenseFor("upgrade")) return;
|
|
5969
6380
|
await upgradeCommand(options);
|
|
5970
6381
|
});
|
|
5971
6382
|
cli.command("patch [action]", "Manage template patches (list, create, apply, diff, remove, disable, enable)").action(async (action) => {
|