@baselane/packs 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +191 -0
- package/NOTICE +6 -0
- package/README.md +15 -0
- package/dist/ai-merge.d.ts +26 -0
- package/dist/ai-merge.js +165 -0
- package/dist/aliases.d.ts +7 -0
- package/dist/aliases.js +9 -0
- package/dist/compose-draft.d.ts +19 -0
- package/dist/compose-draft.js +170 -0
- package/dist/drift-detect.d.ts +8 -0
- package/dist/drift-detect.js +21 -0
- package/dist/index.d.ts +40 -0
- package/dist/index.js +21 -0
- package/dist/ingest.d.ts +25 -0
- package/dist/ingest.js +262 -0
- package/dist/load.d.ts +7 -0
- package/dist/load.js +29 -0
- package/dist/manifest.d.ts +71 -0
- package/dist/manifest.js +208 -0
- package/dist/materialize-harness.d.ts +15 -0
- package/dist/materialize-harness.js +48 -0
- package/dist/merge-region.d.ts +60 -0
- package/dist/merge-region.js +166 -0
- package/dist/overlap.d.ts +32 -0
- package/dist/overlap.js +49 -0
- package/dist/pack-from-fileset.d.ts +13 -0
- package/dist/pack-from-fileset.js +133 -0
- package/dist/render/adapters.d.ts +6 -0
- package/dist/render/adapters.js +43 -0
- package/dist/render/agents-md.d.ts +3 -0
- package/dist/render/agents-md.js +49 -0
- package/dist/render/bundle-union.d.ts +10 -0
- package/dist/render/bundle-union.js +87 -0
- package/dist/render/bundle.d.ts +3 -0
- package/dist/render/bundle.js +51 -0
- package/dist/render/capabilities.d.ts +19 -0
- package/dist/render/capabilities.js +86 -0
- package/dist/render/claude.d.ts +3 -0
- package/dist/render/claude.js +92 -0
- package/dist/render/design.d.ts +27 -0
- package/dist/render/design.js +443 -0
- package/dist/render/graph.d.ts +11 -0
- package/dist/render/graph.js +245 -0
- package/dist/render/memory.d.ts +35 -0
- package/dist/render/memory.js +353 -0
- package/dist/render/render-pack.d.ts +3 -0
- package/dist/render/render-pack.js +43 -0
- package/dist/render/repo-union.d.ts +14 -0
- package/dist/render/repo-union.js +94 -0
- package/dist/render/rollout-files.d.ts +18 -0
- package/dist/render/rollout-files.js +39 -0
- package/dist/render/system-map.d.ts +8 -0
- package/dist/render/system-map.js +73 -0
- package/dist/render/tasks.d.ts +32 -0
- package/dist/render/tasks.js +327 -0
- package/dist/render/wiki.d.ts +30 -0
- package/dist/render/wiki.js +288 -0
- package/dist/seed/graph-seed.d.ts +17 -0
- package/dist/seed/graph-seed.js +18 -0
- package/dist/seed/wiki-seed.d.ts +23 -0
- package/dist/seed/wiki-seed.js +133 -0
- package/dist/seed-skills.d.ts +18 -0
- package/dist/seed-skills.js +134 -0
- package/dist/types.d.ts +122 -0
- package/dist/types.js +1 -0
- package/dist/validate.d.ts +30 -0
- package/dist/validate.js +397 -0
- package/package.json +38 -0
- package/packs/database-review/pack.json +44 -0
- package/packs/database-review/rendered/.baselane/capabilities.json +10 -0
- package/packs/database-review/rendered/.baselane/system-map/README.md +18 -0
- package/packs/database-review/rendered/.claude/agents/database-reviewer.md +8 -0
- package/packs/database-review/rendered/.claude/commands/db-review.md +6 -0
- package/packs/database-review/rendered/.claude/commands/map.md +6 -0
- package/packs/database-review/rendered/.claude/settings.json +26 -0
- package/packs/database-review/rendered/.github/copilot-instructions.md +48 -0
- package/packs/database-review/rendered/AGENTS.md +66 -0
- package/packs/database-review/rendered/CLAUDE.md +9 -0
- package/packs/database-review/rendered/GEMINI.md +3 -0
- package/packs/disciplined-workflow/pack.json +63 -0
- package/packs/disciplined-workflow/rendered/.baselane/capabilities.json +10 -0
- package/packs/disciplined-workflow/rendered/.baselane/tasks/README.md +36 -0
- package/packs/disciplined-workflow/rendered/.claude/agents/plan-reviewer.md +8 -0
- package/packs/disciplined-workflow/rendered/.claude/agents/task-reviewer.md +8 -0
- package/packs/disciplined-workflow/rendered/.claude/commands/brainstorm.md +6 -0
- package/packs/disciplined-workflow/rendered/.claude/commands/execute-plan.md +6 -0
- package/packs/disciplined-workflow/rendered/.claude/commands/plan-work.md +6 -0
- package/packs/disciplined-workflow/rendered/.claude/commands/write-plan.md +6 -0
- package/packs/disciplined-workflow/rendered/.claude/settings.json +24 -0
- package/packs/disciplined-workflow/rendered/.github/copilot-instructions.md +24 -0
- package/packs/disciplined-workflow/rendered/AGENTS.md +43 -0
- package/packs/disciplined-workflow/rendered/CLAUDE.md +12 -0
- package/packs/disciplined-workflow/rendered/GEMINI.md +3 -0
- package/packs/frontend-design/pack.json +129 -0
- package/packs/frontend-design/rendered/.claude/skills/clone/SKILL.md +39 -0
- package/packs/frontend-design/rendered/.claude/skills/functional-ui/SKILL.md +78 -0
- package/packs/frontend-design/rendered/.claude/skills/gsap/SKILL.md +36 -0
- package/packs/frontend-design/rendered/.claude/skills/gsap/gsap-core.md +254 -0
- package/packs/frontend-design/rendered/.claude/skills/gsap/gsap-frameworks.md +266 -0
- package/packs/frontend-design/rendered/.claude/skills/gsap/gsap-performance.md +79 -0
- package/packs/frontend-design/rendered/.claude/skills/gsap/gsap-plugins.md +433 -0
- package/packs/frontend-design/rendered/.claude/skills/gsap/gsap-react.md +136 -0
- package/packs/frontend-design/rendered/.claude/skills/gsap/gsap-scrolltrigger.md +296 -0
- package/packs/frontend-design/rendered/.claude/skills/gsap/gsap-timeline.md +107 -0
- package/packs/frontend-design/rendered/.claude/skills/gsap/gsap-utils.md +284 -0
- package/packs/frontend-design/rendered/.claude/skills/marketing-ui/SKILL.md +36 -0
- package/packs/frontend-design/rendered/.claude/skills/shadcn/SKILL.md +267 -0
- package/packs/frontend-design/rendered/.claude/skills/shadcn/base-vs-radix.md +306 -0
- package/packs/frontend-design/rendered/.claude/skills/shadcn/cli.md +290 -0
- package/packs/frontend-design/rendered/.claude/skills/shadcn/composition.md +195 -0
- package/packs/frontend-design/rendered/.claude/skills/shadcn/customization.md +209 -0
- package/packs/frontend-design/rendered/.claude/skills/shadcn/forms.md +192 -0
- package/packs/frontend-design/rendered/.claude/skills/shadcn/icons.md +101 -0
- package/packs/frontend-design/rendered/.claude/skills/shadcn/mcp.md +105 -0
- package/packs/frontend-design/rendered/.claude/skills/shadcn/registry.md +277 -0
- package/packs/frontend-design/rendered/.claude/skills/shadcn/styling.md +162 -0
- package/packs/frontend-design/rendered/.github/copilot-instructions.md +474 -0
- package/packs/frontend-design/rendered/AGENTS.md +33 -0
- package/packs/frontend-design/rendered/CLAUDE.md +10 -0
- package/packs/frontend-design/rendered/GEMINI.md +456 -0
- package/packs/frontend-taste/pack.json +43 -0
- package/packs/frontend-taste/rendered/.baselane/capabilities.json +16 -0
- package/packs/frontend-taste/rendered/.claude/agents/taste-reviewer.md +8 -0
- package/packs/frontend-taste/rendered/.claude/commands/design-review.md +6 -0
- package/packs/frontend-taste/rendered/.claude/settings.json +15 -0
- package/packs/frontend-taste/rendered/.github/copilot-instructions.md +51 -0
- package/packs/frontend-taste/rendered/AGENTS.md +68 -0
- package/packs/frontend-taste/rendered/CLAUDE.md +8 -0
- package/packs/frontend-taste/rendered/DESIGN.md +72 -0
- package/packs/frontend-taste/rendered/GEMINI.md +3 -0
- package/packs/go-rules/pack.json +38 -0
- package/packs/go-rules/rendered/.claude/agents/go-reviewer.md +8 -0
- package/packs/go-rules/rendered/.claude/commands/go-review.md +6 -0
- package/packs/go-rules/rendered/.claude/settings.json +15 -0
- package/packs/go-rules/rendered/.github/copilot-instructions.md +44 -0
- package/packs/go-rules/rendered/AGENTS.md +54 -0
- package/packs/go-rules/rendered/CLAUDE.md +8 -0
- package/packs/go-rules/rendered/GEMINI.md +3 -0
- package/packs/python-rules/pack.json +38 -0
- package/packs/python-rules/rendered/.claude/agents/python-reviewer.md +8 -0
- package/packs/python-rules/rendered/.claude/commands/python-review.md +6 -0
- package/packs/python-rules/rendered/.claude/settings.json +15 -0
- package/packs/python-rules/rendered/.github/copilot-instructions.md +43 -0
- package/packs/python-rules/rendered/AGENTS.md +53 -0
- package/packs/python-rules/rendered/CLAUDE.md +8 -0
- package/packs/python-rules/rendered/GEMINI.md +3 -0
- package/packs/second-brain/pack.json +36 -0
- package/packs/second-brain/rendered/.baselane/capabilities.json +25 -0
- package/packs/second-brain/rendered/.baselane/memory/README.md +34 -0
- package/packs/second-brain/rendered/.baselane/wiki/README.md +62 -0
- package/packs/second-brain/rendered/.claude/agents/librarian.md +14 -0
- package/packs/second-brain/rendered/.claude/commands/remember.md +6 -0
- package/packs/second-brain/rendered/.claude/commands/wiki.md +6 -0
- package/packs/second-brain/rendered/.claude/settings.json +35 -0
- package/packs/second-brain/rendered/.github/copilot-instructions.md +24 -0
- package/packs/second-brain/rendered/AGENTS.md +41 -0
- package/packs/second-brain/rendered/CLAUDE.md +9 -0
- package/packs/second-brain/rendered/GEMINI.md +3 -0
- package/packs/security-review/pack.json +72 -0
- package/packs/security-review/rendered/.claude/agents/security-reviewer.md +8 -0
- package/packs/security-review/rendered/.claude/commands/security-audit.md +6 -0
- package/packs/security-review/rendered/.claude/commands/security-scan.md +6 -0
- package/packs/security-review/rendered/.claude/settings.json +35 -0
- package/packs/security-review/rendered/.claude/skills/security-audit/SKILL.md +44 -0
- package/packs/security-review/rendered/.claude/skills/validate-at-boundaries/SKILL.md +41 -0
- package/packs/security-review/rendered/.github/copilot-instructions.md +137 -0
- package/packs/security-review/rendered/AGENTS.md +66 -0
- package/packs/security-review/rendered/CLAUDE.md +11 -0
- package/packs/security-review/rendered/GEMINI.md +90 -0
- package/packs/software-engineer-harness/pack.json +98 -0
- package/packs/software-engineer-harness/rendered/.baselane/capabilities.json +15 -0
- package/packs/software-engineer-harness/rendered/.baselane/system-map/README.md +18 -0
- package/packs/software-engineer-harness/rendered/.baselane/tasks/README.md +36 -0
- package/packs/software-engineer-harness/rendered/.claude/agents/architect.md +8 -0
- package/packs/software-engineer-harness/rendered/.claude/agents/checker.md +8 -0
- package/packs/software-engineer-harness/rendered/.claude/agents/code-reviewer.md +8 -0
- package/packs/software-engineer-harness/rendered/.claude/agents/code-simplifier.md +8 -0
- package/packs/software-engineer-harness/rendered/.claude/agents/planner.md +8 -0
- package/packs/software-engineer-harness/rendered/.claude/agents/reviewer.md +8 -0
- package/packs/software-engineer-harness/rendered/.claude/commands/build-and-check.md +6 -0
- package/packs/software-engineer-harness/rendered/.claude/commands/map.md +6 -0
- package/packs/software-engineer-harness/rendered/.claude/commands/plan-change.md +6 -0
- package/packs/software-engineer-harness/rendered/.claude/commands/plan-work.md +6 -0
- package/packs/software-engineer-harness/rendered/.claude/commands/review-change.md +6 -0
- package/packs/software-engineer-harness/rendered/.claude/commands/tdd-task.md +6 -0
- package/packs/software-engineer-harness/rendered/.claude/settings.json +35 -0
- package/packs/software-engineer-harness/rendered/.github/copilot-instructions.md +37 -0
- package/packs/software-engineer-harness/rendered/AGENTS.md +58 -0
- package/packs/software-engineer-harness/rendered/CLAUDE.md +18 -0
- package/packs/software-engineer-harness/rendered/GEMINI.md +3 -0
- package/packs/systematic-debugging/pack.json +44 -0
- package/packs/systematic-debugging/rendered/.claude/agents/debugger.md +8 -0
- package/packs/systematic-debugging/rendered/.claude/commands/debug.md +6 -0
- package/packs/systematic-debugging/rendered/.claude/commands/root-cause.md +6 -0
- package/packs/systematic-debugging/rendered/.claude/settings.json +15 -0
- package/packs/systematic-debugging/rendered/.github/copilot-instructions.md +20 -0
- package/packs/systematic-debugging/rendered/AGENTS.md +31 -0
- package/packs/systematic-debugging/rendered/CLAUDE.md +9 -0
- package/packs/systematic-debugging/rendered/GEMINI.md +3 -0
- package/packs/token-efficiency-harness/pack.json +49 -0
- package/packs/token-efficiency-harness/rendered/.baselane/capabilities.json +10 -0
- package/packs/token-efficiency-harness/rendered/.baselane/memory/README.md +34 -0
- package/packs/token-efficiency-harness/rendered/.claude/agents/scout.md +8 -0
- package/packs/token-efficiency-harness/rendered/.claude/commands/handoff.md +6 -0
- package/packs/token-efficiency-harness/rendered/.claude/commands/remember.md +6 -0
- package/packs/token-efficiency-harness/rendered/.claude/commands/usage-audit.md +6 -0
- package/packs/token-efficiency-harness/rendered/.claude/settings.json +26 -0
- package/packs/token-efficiency-harness/rendered/.github/copilot-instructions.md +26 -0
- package/packs/token-efficiency-harness/rendered/AGENTS.md +44 -0
- package/packs/token-efficiency-harness/rendered/CLAUDE.md +10 -0
- package/packs/token-efficiency-harness/rendered/GEMINI.md +3 -0
- package/packs/typescript-rules/pack.json +46 -0
- package/packs/typescript-rules/rendered/.claude/agents/typescript-reviewer.md +8 -0
- package/packs/typescript-rules/rendered/.claude/commands/typescript-review.md +6 -0
- package/packs/typescript-rules/rendered/.claude/settings.json +15 -0
- package/packs/typescript-rules/rendered/.claude/skills/immutable-updates/SKILL.md +46 -0
- package/packs/typescript-rules/rendered/.github/copilot-instructions.md +89 -0
- package/packs/typescript-rules/rendered/AGENTS.md +55 -0
- package/packs/typescript-rules/rendered/CLAUDE.md +9 -0
- package/packs/typescript-rules/rendered/GEMINI.md +51 -0
- package/skills/algorithmic-art/LICENSE +202 -0
- package/skills/algorithmic-art/LICENSE.txt +202 -0
- package/skills/algorithmic-art/SKILL.md +405 -0
- package/skills/algorithmic-art/templates/generator_template.js +223 -0
- package/skills/algorithmic-art/templates/viewer.html +599 -0
- package/skills/brainstorming/LICENSE +21 -0
- package/skills/brainstorming/SKILL.md +159 -0
- package/skills/brainstorming/scripts/frame-template.html +213 -0
- package/skills/brainstorming/scripts/helper.js +167 -0
- package/skills/brainstorming/scripts/server.cjs +723 -0
- package/skills/brainstorming/scripts/start-server.sh +209 -0
- package/skills/brainstorming/scripts/stop-server.sh +120 -0
- package/skills/brainstorming/spec-document-reviewer-prompt.md +49 -0
- package/skills/brainstorming/visual-companion.md +291 -0
- package/skills/brand-guidelines/LICENSE +202 -0
- package/skills/brand-guidelines/LICENSE.txt +202 -0
- package/skills/brand-guidelines/SKILL.md +73 -0
- package/skills/canvas-design/LICENSE +202 -0
- package/skills/canvas-design/LICENSE.txt +202 -0
- package/skills/canvas-design/SKILL.md +130 -0
- package/skills/canvas-design/canvas-fonts/ArsenalSC-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/BigShoulders-Bold.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/BigShoulders-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/BigShoulders-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/Boldonse-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/Boldonse-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/CrimsonPro-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/DMMono-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/DMMono-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/EricaOne-OFL.txt +94 -0
- package/skills/canvas-design/canvas-fonts/EricaOne-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/GeistMono-Bold.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/GeistMono-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/GeistMono-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/Gloock-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/Gloock-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/IBMPlexMono-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/Italiana-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/Italiana-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/Jura-Light.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/Jura-Medium.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/Jura-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/LibreBaskerville-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/Lora-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/NationalPark-Bold.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/NationalPark-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/NationalPark-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/Outfit-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/PixelifySans-Medium.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/PixelifySans-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/PoiretOne-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/PoiretOne-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/RedHatMono-Bold.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/RedHatMono-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/RedHatMono-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/Silkscreen-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/Silkscreen-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/SmoochSans-Medium.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/SmoochSans-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/Tektur-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/WorkSans-Bold.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/WorkSans-Italic.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/WorkSans-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/WorkSans-Regular.ttf +0 -0
- package/skills/canvas-design/canvas-fonts/YoungSerif-OFL.txt +93 -0
- package/skills/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
- package/skills/dispatching-parallel-agents/LICENSE +21 -0
- package/skills/dispatching-parallel-agents/SKILL.md +185 -0
- package/skills/executing-plans/LICENSE +21 -0
- package/skills/executing-plans/SKILL.md +70 -0
- package/skills/finishing-a-development-branch/LICENSE +21 -0
- package/skills/finishing-a-development-branch/SKILL.md +241 -0
- package/skills/first-party/README.md +32 -0
- package/skills/first-party/append-only-jsonl-stores/SKILL.md +50 -0
- package/skills/first-party/golden-snapshot-discipline/SKILL.md +45 -0
- package/skills/first-party/immutable-updates/SKILL.md +46 -0
- package/skills/first-party/manifest.json +10 -0
- package/skills/first-party/ts-extension-imports/SKILL.md +49 -0
- package/skills/first-party/validate-at-boundaries/SKILL.md +41 -0
- package/skills/first-party/zero-dependency-discipline/SKILL.md +41 -0
- package/skills/frontend-design/LICENSE +177 -0
- package/skills/frontend-design/LICENSE.txt +177 -0
- package/skills/frontend-design/SKILL.md +55 -0
- package/skills/internal-comms/LICENSE +202 -0
- package/skills/internal-comms/LICENSE.txt +202 -0
- package/skills/internal-comms/SKILL.md +32 -0
- package/skills/internal-comms/examples/3p-updates.md +47 -0
- package/skills/internal-comms/examples/company-newsletter.md +65 -0
- package/skills/internal-comms/examples/faq-answers.md +30 -0
- package/skills/internal-comms/examples/general-comms.md +16 -0
- package/skills/mcp-builder/LICENSE +202 -0
- package/skills/mcp-builder/LICENSE.txt +202 -0
- package/skills/mcp-builder/SKILL.md +236 -0
- package/skills/mcp-builder/reference/evaluation.md +602 -0
- package/skills/mcp-builder/reference/mcp_best_practices.md +249 -0
- package/skills/mcp-builder/reference/node_mcp_server.md +970 -0
- package/skills/mcp-builder/reference/python_mcp_server.md +719 -0
- package/skills/mcp-builder/scripts/connections.py +151 -0
- package/skills/mcp-builder/scripts/evaluation.py +373 -0
- package/skills/mcp-builder/scripts/example_evaluation.xml +22 -0
- package/skills/mcp-builder/scripts/requirements.txt +2 -0
- package/skills/receiving-code-review/LICENSE +21 -0
- package/skills/receiving-code-review/SKILL.md +213 -0
- package/skills/requesting-code-review/LICENSE +21 -0
- package/skills/requesting-code-review/SKILL.md +103 -0
- package/skills/requesting-code-review/code-reviewer.md +172 -0
- package/skills/seed-manifest.json +185 -0
- package/skills/skill-creator/LICENSE +202 -0
- package/skills/skill-creator/LICENSE.txt +202 -0
- package/skills/skill-creator/SKILL.md +485 -0
- package/skills/skill-creator/agents/analyzer.md +274 -0
- package/skills/skill-creator/agents/comparator.md +202 -0
- package/skills/skill-creator/agents/grader.md +223 -0
- package/skills/skill-creator/assets/eval_review.html +146 -0
- package/skills/skill-creator/eval-viewer/generate_review.py +471 -0
- package/skills/skill-creator/eval-viewer/viewer.html +1325 -0
- package/skills/skill-creator/references/schemas.md +430 -0
- package/skills/skill-creator/scripts/__init__.py +0 -0
- package/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
- package/skills/skill-creator/scripts/generate_report.py +326 -0
- package/skills/skill-creator/scripts/improve_description.py +247 -0
- package/skills/skill-creator/scripts/package_skill.py +136 -0
- package/skills/skill-creator/scripts/quick_validate.py +103 -0
- package/skills/skill-creator/scripts/run_eval.py +310 -0
- package/skills/skill-creator/scripts/run_loop.py +328 -0
- package/skills/skill-creator/scripts/utils.py +47 -0
- package/skills/slack-gif-creator/LICENSE +202 -0
- package/skills/slack-gif-creator/LICENSE.txt +202 -0
- package/skills/slack-gif-creator/SKILL.md +254 -0
- package/skills/slack-gif-creator/core/easing.py +234 -0
- package/skills/slack-gif-creator/core/frame_composer.py +176 -0
- package/skills/slack-gif-creator/core/gif_builder.py +269 -0
- package/skills/slack-gif-creator/core/validators.py +136 -0
- package/skills/slack-gif-creator/requirements.txt +4 -0
- package/skills/subagent-driven-development/LICENSE +21 -0
- package/skills/subagent-driven-development/SKILL.md +418 -0
- package/skills/subagent-driven-development/implementer-prompt.md +139 -0
- package/skills/subagent-driven-development/scripts/review-package +44 -0
- package/skills/subagent-driven-development/scripts/sdd-workspace +22 -0
- package/skills/subagent-driven-development/scripts/task-brief +40 -0
- package/skills/subagent-driven-development/task-reviewer-prompt.md +188 -0
- package/skills/systematic-debugging/CREATION-LOG.md +119 -0
- package/skills/systematic-debugging/LICENSE +21 -0
- package/skills/systematic-debugging/SKILL.md +296 -0
- package/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
- package/skills/systematic-debugging/condition-based-waiting.md +115 -0
- package/skills/systematic-debugging/defense-in-depth.md +122 -0
- package/skills/systematic-debugging/find-polluter.sh +63 -0
- package/skills/systematic-debugging/root-cause-tracing.md +169 -0
- package/skills/systematic-debugging/test-academic.md +14 -0
- package/skills/systematic-debugging/test-pressure-1.md +58 -0
- package/skills/systematic-debugging/test-pressure-2.md +68 -0
- package/skills/systematic-debugging/test-pressure-3.md +69 -0
- package/skills/test-driven-development/LICENSE +21 -0
- package/skills/test-driven-development/SKILL.md +371 -0
- package/skills/test-driven-development/testing-anti-patterns.md +299 -0
- package/skills/theme-factory/LICENSE +202 -0
- package/skills/theme-factory/LICENSE.txt +202 -0
- package/skills/theme-factory/SKILL.md +59 -0
- package/skills/theme-factory/theme-showcase.pdf +0 -0
- package/skills/theme-factory/themes/arctic-frost.md +19 -0
- package/skills/theme-factory/themes/botanical-garden.md +19 -0
- package/skills/theme-factory/themes/desert-rose.md +19 -0
- package/skills/theme-factory/themes/forest-canopy.md +19 -0
- package/skills/theme-factory/themes/golden-hour.md +19 -0
- package/skills/theme-factory/themes/midnight-galaxy.md +19 -0
- package/skills/theme-factory/themes/modern-minimalist.md +19 -0
- package/skills/theme-factory/themes/ocean-depths.md +19 -0
- package/skills/theme-factory/themes/sunset-boulevard.md +19 -0
- package/skills/theme-factory/themes/tech-innovation.md +19 -0
- package/skills/using-git-worktrees/LICENSE +21 -0
- package/skills/using-git-worktrees/SKILL.md +202 -0
- package/skills/using-superpowers/LICENSE +21 -0
- package/skills/using-superpowers/SKILL.md +62 -0
- package/skills/using-superpowers/references/antigravity-tools.md +23 -0
- package/skills/using-superpowers/references/codex-tools.md +39 -0
- package/skills/using-superpowers/references/pi-tools.md +16 -0
- package/skills/verification-before-completion/LICENSE +21 -0
- package/skills/verification-before-completion/SKILL.md +139 -0
- package/skills/web-artifacts-builder/LICENSE +202 -0
- package/skills/web-artifacts-builder/LICENSE.txt +202 -0
- package/skills/web-artifacts-builder/SKILL.md +74 -0
- package/skills/web-artifacts-builder/scripts/bundle-artifact.sh +54 -0
- package/skills/web-artifacts-builder/scripts/init-artifact.sh +322 -0
- package/skills/web-artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
- package/skills/webapp-testing/LICENSE +202 -0
- package/skills/webapp-testing/LICENSE.txt +202 -0
- package/skills/webapp-testing/SKILL.md +96 -0
- package/skills/webapp-testing/examples/console_logging.py +35 -0
- package/skills/webapp-testing/examples/element_discovery.py +40 -0
- package/skills/webapp-testing/examples/static_html_automation.py +33 -0
- package/skills/webapp-testing/scripts/with_server.py +106 -0
- package/skills/writing-plans/LICENSE +21 -0
- package/skills/writing-plans/SKILL.md +174 -0
- package/skills/writing-plans/plan-document-reviewer-prompt.md +49 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { WorkflowPack } from "./types.ts";
|
|
2
|
+
import { type HarnessManifest, type Resolution } from "./manifest.ts";
|
|
3
|
+
export declare function sha256Hex(content: string): string;
|
|
4
|
+
export interface MaterializeInput {
|
|
5
|
+
manifest: HarnessManifest;
|
|
6
|
+
resolvedPacks: Record<string, WorkflowPack>;
|
|
7
|
+
currentFiles: Record<string, string | null>;
|
|
8
|
+
resolutions?: Record<string, Resolution>;
|
|
9
|
+
}
|
|
10
|
+
export interface MaterializeResult {
|
|
11
|
+
files: Record<string, string>;
|
|
12
|
+
collisions: string[];
|
|
13
|
+
manifest: HarnessManifest;
|
|
14
|
+
}
|
|
15
|
+
export declare function materializeHarness(input: MaterializeInput): MaterializeResult;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { isEntryFile, extractManagedRegions } from "./merge-region.js";
|
|
3
|
+
import { renderRolloutFiles } from "./render/rollout-files.js";
|
|
4
|
+
import { renderBundleUnion } from "./render/bundle-union.js";
|
|
5
|
+
import { validateManifest } from "./manifest.js";
|
|
6
|
+
export function sha256Hex(content) {
|
|
7
|
+
return createHash("sha256").update(content, "utf8").digest("hex");
|
|
8
|
+
}
|
|
9
|
+
const MACHINE_SETTINGS_PATH = "settings.json";
|
|
10
|
+
export function materializeHarness(input) {
|
|
11
|
+
const names = Object.keys(input.manifest.packs);
|
|
12
|
+
const packs = names.map((name) => {
|
|
13
|
+
const pack = input.resolvedPacks[name];
|
|
14
|
+
if (!pack)
|
|
15
|
+
throw new Error(`materialize: pack "${name}" was not resolved`);
|
|
16
|
+
return pack;
|
|
17
|
+
});
|
|
18
|
+
const rendered = input.manifest.target.kind === "repo"
|
|
19
|
+
? renderRolloutFiles(input.currentFiles, packs)
|
|
20
|
+
: renderBundleUnion(packs);
|
|
21
|
+
const vendored = [];
|
|
22
|
+
const managedRegions = [];
|
|
23
|
+
for (const [path, content] of Object.entries(rendered.files).sort(([a], [b]) => a.localeCompare(b))) {
|
|
24
|
+
if (input.manifest.target.kind === "machine" && path === MACHINE_SETTINGS_PATH)
|
|
25
|
+
continue;
|
|
26
|
+
if (isEntryFile(path)) {
|
|
27
|
+
const regions = extractManagedRegions(content).map((r) => ({
|
|
28
|
+
packId: r.packId,
|
|
29
|
+
version: r.version,
|
|
30
|
+
sha256: sha256Hex(r.body),
|
|
31
|
+
}));
|
|
32
|
+
managedRegions.push({ path, regions });
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
vendored.push({ path, sha256: sha256Hex(content) });
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const manifest = validateManifest({
|
|
39
|
+
...input.manifest,
|
|
40
|
+
materialized: {
|
|
41
|
+
vendored,
|
|
42
|
+
managedRegions,
|
|
43
|
+
derivedCommitted: [],
|
|
44
|
+
resolutions: input.resolutions ?? {},
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
return { files: rendered.files, collisions: rendered.collisions, manifest };
|
|
48
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/** The human-facing files a pack renders that get region-merged into a developer's own content. */
|
|
2
|
+
export declare const ENTRY_FILES: readonly string[];
|
|
3
|
+
export declare function isEntryFile(renderedPath: string): boolean;
|
|
4
|
+
export declare const END_MARKER = "<!-- baselane:end -->";
|
|
5
|
+
export declare function buildStartMarker(packId: string, version: string): string;
|
|
6
|
+
export interface ManagedRegion {
|
|
7
|
+
packId: string;
|
|
8
|
+
version: string;
|
|
9
|
+
body: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Reads every managed region present in an entry file's content — the read-side twin of
|
|
13
|
+
* mergeManagedRegion/buildStartMarker, built for inventory (drift detection, and
|
|
14
|
+
* union-rollout's strippedManagedPackIds, which is just `.map(r => r.packId)` on this)
|
|
15
|
+
* rather than merging. Shares mergeManagedRegion's exact boundary rules: a dangling
|
|
16
|
+
* opener with no closer, or a region whose true end is ambiguous because the body
|
|
17
|
+
* contains a stray end-marker literal before the next pack's start (or EOF), is skipped
|
|
18
|
+
* entirely rather than guessed at — fail safe, same as the merge path.
|
|
19
|
+
*/
|
|
20
|
+
export declare function extractManagedRegions(content: string): ManagedRegion[];
|
|
21
|
+
/**
|
|
22
|
+
* Merge this pack's managed markdown block into a developer's existing entry file
|
|
23
|
+
* (AGENTS.md, CLAUDE.md, GEMINI.md, copilot-instructions.md), preserving everything
|
|
24
|
+
* they wrote by hand — and everything any OTHER pack has already put there.
|
|
25
|
+
*
|
|
26
|
+
* - No existing content → the block alone.
|
|
27
|
+
* - Existing content with a valid region for THIS packId (any version of it) →
|
|
28
|
+
* replace just that region, byte-for-byte preserving text before and after it.
|
|
29
|
+
* A different pack's region elsewhere in the file is untouched, so multiple packs
|
|
30
|
+
* can coexist in the same entry file.
|
|
31
|
+
* - Existing content with no valid region for this pack — including a malformed
|
|
32
|
+
* half-marker with no matching close, or a region whose boundaries are
|
|
33
|
+
* unparseable because the body contains a stray end-marker literal — → append a
|
|
34
|
+
* fresh block below, never deleting or truncating their content.
|
|
35
|
+
*/
|
|
36
|
+
export declare function mergeManagedRegion(existing: string | null, managedBody: string, packId: string, version: string): string;
|
|
37
|
+
/**
|
|
38
|
+
* Removes the complete existing region for `packId` (any version), leaving everything else
|
|
39
|
+
* byte-for-byte untouched — the inverse of what `mergeManagedRegion` inserts. Joins the
|
|
40
|
+
* surrounding content with a single blank line where both sides remain non-empty, matching
|
|
41
|
+
* the spacing `mergeManagedRegion` itself produces around a region.
|
|
42
|
+
*
|
|
43
|
+
* Returns `content` unchanged when there's no region to remove: absent, a half marker with no
|
|
44
|
+
* matching close, or an ambiguous boundary (a stray END_MARKER inside the matched body before
|
|
45
|
+
* the next pack's start) — the exact same fail-safe guard `mergeManagedRegion` uses. Never
|
|
46
|
+
* guesses; an ambiguous match means don't slice.
|
|
47
|
+
*
|
|
48
|
+
* Reconcile note: a sibling in-flight branch is adding a canonical `extractManagedRegions()`
|
|
49
|
+
* scanner to this file. Once merged, this function's single-region removal could likely derive
|
|
50
|
+
* from that scanner's output instead of its own `buildRegionRe` match — not done here to avoid
|
|
51
|
+
* coupling two branches landing in the same file concurrently; left as a follow-up.
|
|
52
|
+
*/
|
|
53
|
+
export declare function stripManagedRegion(content: string, packId: string): string;
|
|
54
|
+
/**
|
|
55
|
+
* Every packId with a start marker present in `content`, in first-seen order, deduped. Used by
|
|
56
|
+
* the rollout renderer to know which packs' regions to strip before folding in the current
|
|
57
|
+
* effective set — safe to call even on a malformed/half-marker region, since `stripManagedRegion`
|
|
58
|
+
* itself is a no-op when it can't confidently remove one.
|
|
59
|
+
*/
|
|
60
|
+
export declare function strippedManagedPackIds(content: string): string[];
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/** The human-facing files a pack renders that get region-merged into a developer's own content. */
|
|
2
|
+
export const ENTRY_FILES = ["AGENTS.md", "CLAUDE.md", "GEMINI.md", ".github/copilot-instructions.md"];
|
|
3
|
+
export function isEntryFile(renderedPath) {
|
|
4
|
+
return ENTRY_FILES.includes(renderedPath);
|
|
5
|
+
}
|
|
6
|
+
// The single source of truth for the managed-region marker format. The AI merge path
|
|
7
|
+
// (ai-merge.ts) imports these so it validates against the exact same literals the
|
|
8
|
+
// mechanical merger writes — a format change here can never silently desync the two.
|
|
9
|
+
export const END_MARKER = "<!-- baselane:end -->";
|
|
10
|
+
export function buildStartMarker(packId, version) {
|
|
11
|
+
return `<!-- baselane:start ${packId}@${version} — managed region, do not edit inside -->`;
|
|
12
|
+
}
|
|
13
|
+
// Matches ANY pack's opening marker line, used only to bound where the OTHER pack's
|
|
14
|
+
// region ends (so we don't misread a neighboring pack's region as part of ours).
|
|
15
|
+
const START_MARKER_ANY_RE = /<!-- baselane:start [^\n]*? — managed region, do not edit inside -->/;
|
|
16
|
+
function escapeRegExp(value) {
|
|
17
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
18
|
+
}
|
|
19
|
+
// Matches a complete existing region for THIS pack id — any version of it — from its
|
|
20
|
+
// opening marker through the next closing marker. The packId is fixed; only the version
|
|
21
|
+
// is a wildcard, so a version bump of the SAME pack still replaces in place, but another
|
|
22
|
+
// pack's region (different packId) never matches. Non-greedy so it stops at the first
|
|
23
|
+
// close, and requires both markers to be present; a dangling opener with no closer
|
|
24
|
+
// won't match.
|
|
25
|
+
function buildRegionRe(packId) {
|
|
26
|
+
return new RegExp(`<!-- baselane:start ${escapeRegExp(packId)}@[^\\n]*? — managed region, do not edit inside -->\\n[\\s\\S]*?${escapeRegExp(END_MARKER)}`);
|
|
27
|
+
}
|
|
28
|
+
// managedBody is pack-controlled content, not user content — it must never itself
|
|
29
|
+
// contain a marker literal (e.g. pack docs that show marker syntax as an example).
|
|
30
|
+
// If it did, buildBlock would produce a block containing what looks like a second
|
|
31
|
+
// region boundary, corrupting every merge downstream. Fail loudly at the source.
|
|
32
|
+
function assertNoMarkersIn(managedBody) {
|
|
33
|
+
if (managedBody.includes(END_MARKER) || START_MARKER_ANY_RE.test(managedBody)) {
|
|
34
|
+
throw new Error("managedBody must not contain a baselane:start or baselane:end marker literal");
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function buildBlock(managedBody, packId, version) {
|
|
38
|
+
assertNoMarkersIn(managedBody);
|
|
39
|
+
const startMarker = buildStartMarker(packId, version);
|
|
40
|
+
return `${startMarker}\n${managedBody.trim()}\n${END_MARKER}`;
|
|
41
|
+
}
|
|
42
|
+
// Index of the next pack start marker (any pack) at or after `fromIndex`, or the end
|
|
43
|
+
// of the string if there isn't one. Used to bound how far we look for a stray end
|
|
44
|
+
// marker without accidentally reading into a genuinely separate, later region.
|
|
45
|
+
function indexOfNextStartMarker(text, fromIndex) {
|
|
46
|
+
const re = new RegExp(START_MARKER_ANY_RE.source, "g");
|
|
47
|
+
re.lastIndex = fromIndex;
|
|
48
|
+
const found = re.exec(text);
|
|
49
|
+
return found ? found.index : text.length;
|
|
50
|
+
}
|
|
51
|
+
// Captures every pack's opening marker with its packId/version split at the "@" that
|
|
52
|
+
// buildStartMarker joins them with — the read-side twin of that function. Global so
|
|
53
|
+
// extractManagedRegions can walk every region present in one pass.
|
|
54
|
+
const START_MARKER_CAPTURE_RE = /<!-- baselane:start ([^\n@]+)@([^\n]*?) — managed region, do not edit inside -->/g;
|
|
55
|
+
/**
|
|
56
|
+
* Reads every managed region present in an entry file's content — the read-side twin of
|
|
57
|
+
* mergeManagedRegion/buildStartMarker, built for inventory (drift detection, and
|
|
58
|
+
* union-rollout's strippedManagedPackIds, which is just `.map(r => r.packId)` on this)
|
|
59
|
+
* rather than merging. Shares mergeManagedRegion's exact boundary rules: a dangling
|
|
60
|
+
* opener with no closer, or a region whose true end is ambiguous because the body
|
|
61
|
+
* contains a stray end-marker literal before the next pack's start (or EOF), is skipped
|
|
62
|
+
* entirely rather than guessed at — fail safe, same as the merge path.
|
|
63
|
+
*/
|
|
64
|
+
export function extractManagedRegions(content) {
|
|
65
|
+
const regions = [];
|
|
66
|
+
const startRe = new RegExp(START_MARKER_CAPTURE_RE.source, "g");
|
|
67
|
+
let match;
|
|
68
|
+
while ((match = startRe.exec(content)) !== null) {
|
|
69
|
+
const packId = match[1];
|
|
70
|
+
const version = match[2];
|
|
71
|
+
const bodyStart = match.index + match[0].length;
|
|
72
|
+
const boundary = indexOfNextStartMarker(content, bodyStart);
|
|
73
|
+
const endIdx = content.indexOf(END_MARKER, bodyStart);
|
|
74
|
+
if (endIdx === -1 || endIdx >= boundary)
|
|
75
|
+
continue; // dangling opener — no valid close before the next region (or EOF)
|
|
76
|
+
const regionIsAmbiguous = content.slice(endIdx + END_MARKER.length, boundary).includes(END_MARKER);
|
|
77
|
+
if (regionIsAmbiguous)
|
|
78
|
+
continue; // embedded end-marker literal — true boundary unknowable, fail safe
|
|
79
|
+
regions.push({ packId, version, body: content.slice(bodyStart, endIdx).trim() });
|
|
80
|
+
}
|
|
81
|
+
return regions;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Merge this pack's managed markdown block into a developer's existing entry file
|
|
85
|
+
* (AGENTS.md, CLAUDE.md, GEMINI.md, copilot-instructions.md), preserving everything
|
|
86
|
+
* they wrote by hand — and everything any OTHER pack has already put there.
|
|
87
|
+
*
|
|
88
|
+
* - No existing content → the block alone.
|
|
89
|
+
* - Existing content with a valid region for THIS packId (any version of it) →
|
|
90
|
+
* replace just that region, byte-for-byte preserving text before and after it.
|
|
91
|
+
* A different pack's region elsewhere in the file is untouched, so multiple packs
|
|
92
|
+
* can coexist in the same entry file.
|
|
93
|
+
* - Existing content with no valid region for this pack — including a malformed
|
|
94
|
+
* half-marker with no matching close, or a region whose boundaries are
|
|
95
|
+
* unparseable because the body contains a stray end-marker literal — → append a
|
|
96
|
+
* fresh block below, never deleting or truncating their content.
|
|
97
|
+
*/
|
|
98
|
+
export function mergeManagedRegion(existing, managedBody, packId, version) {
|
|
99
|
+
const block = buildBlock(managedBody, packId, version);
|
|
100
|
+
if (existing === null || existing.trim() === "") {
|
|
101
|
+
return `${block}\n`;
|
|
102
|
+
}
|
|
103
|
+
const match = existing.match(buildRegionRe(packId));
|
|
104
|
+
if (match && match.index !== undefined) {
|
|
105
|
+
const matchEnd = match.index + match[0].length;
|
|
106
|
+
// The non-greedy region regex stops at the FIRST end marker. If the "body" we
|
|
107
|
+
// just matched contains another end marker further down before the next pack's
|
|
108
|
+
// start (or EOF), that first marker was actually embedded content, not the real
|
|
109
|
+
// boundary — our match is bogus and slicing on it would orphan the true
|
|
110
|
+
// remainder as loose text. Fail safe instead of guessing.
|
|
111
|
+
const boundary = indexOfNextStartMarker(existing, matchEnd);
|
|
112
|
+
const regionIsAmbiguous = existing.slice(matchEnd, boundary).includes(END_MARKER);
|
|
113
|
+
if (!regionIsAmbiguous) {
|
|
114
|
+
return existing.slice(0, match.index) + block + existing.slice(matchEnd);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return `${existing.replace(/\s+$/, "")}\n\n${block}\n`;
|
|
118
|
+
}
|
|
119
|
+
// Matches a start marker line, capturing the packId (everything before the first "@" —
|
|
120
|
+
// packIds are kebab-case slugs and never contain "@", so this split is unambiguous).
|
|
121
|
+
const START_MARKER_WITH_ID_RE = /<!-- baselane:start (.+?)@[^@\n]*? — managed region, do not edit inside -->/g;
|
|
122
|
+
/**
|
|
123
|
+
* Removes the complete existing region for `packId` (any version), leaving everything else
|
|
124
|
+
* byte-for-byte untouched — the inverse of what `mergeManagedRegion` inserts. Joins the
|
|
125
|
+
* surrounding content with a single blank line where both sides remain non-empty, matching
|
|
126
|
+
* the spacing `mergeManagedRegion` itself produces around a region.
|
|
127
|
+
*
|
|
128
|
+
* Returns `content` unchanged when there's no region to remove: absent, a half marker with no
|
|
129
|
+
* matching close, or an ambiguous boundary (a stray END_MARKER inside the matched body before
|
|
130
|
+
* the next pack's start) — the exact same fail-safe guard `mergeManagedRegion` uses. Never
|
|
131
|
+
* guesses; an ambiguous match means don't slice.
|
|
132
|
+
*
|
|
133
|
+
* Reconcile note: a sibling in-flight branch is adding a canonical `extractManagedRegions()`
|
|
134
|
+
* scanner to this file. Once merged, this function's single-region removal could likely derive
|
|
135
|
+
* from that scanner's output instead of its own `buildRegionRe` match — not done here to avoid
|
|
136
|
+
* coupling two branches landing in the same file concurrently; left as a follow-up.
|
|
137
|
+
*/
|
|
138
|
+
export function stripManagedRegion(content, packId) {
|
|
139
|
+
const match = content.match(buildRegionRe(packId));
|
|
140
|
+
if (!match || match.index === undefined)
|
|
141
|
+
return content;
|
|
142
|
+
const matchEnd = match.index + match[0].length;
|
|
143
|
+
const boundary = indexOfNextStartMarker(content, matchEnd);
|
|
144
|
+
const regionIsAmbiguous = content.slice(matchEnd, boundary).includes(END_MARKER);
|
|
145
|
+
if (regionIsAmbiguous)
|
|
146
|
+
return content;
|
|
147
|
+
const before = content.slice(0, match.index).replace(/\n+$/, "");
|
|
148
|
+
const after = content.slice(matchEnd).replace(/^\n+/, "");
|
|
149
|
+
if (before === "")
|
|
150
|
+
return after;
|
|
151
|
+
if (after === "")
|
|
152
|
+
return `${before}\n`;
|
|
153
|
+
return `${before}\n\n${after}`;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Every packId with a start marker present in `content`, in first-seen order, deduped. Used by
|
|
157
|
+
* the rollout renderer to know which packs' regions to strip before folding in the current
|
|
158
|
+
* effective set — safe to call even on a malformed/half-marker region, since `stripManagedRegion`
|
|
159
|
+
* itself is a no-op when it can't confidently remove one.
|
|
160
|
+
*/
|
|
161
|
+
export function strippedManagedPackIds(content) {
|
|
162
|
+
const seen = new Set();
|
|
163
|
+
for (const m of content.matchAll(START_MARKER_WITH_ID_RE))
|
|
164
|
+
seen.add(m[1]);
|
|
165
|
+
return [...seen];
|
|
166
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { SkillBlock, WorkflowPack } from "./types.ts";
|
|
2
|
+
/**
|
|
3
|
+
* #23 overlap detection: near-duplicate packs and pack↔skill pairs ship with no cross-link, so a
|
|
4
|
+
* user installs both and gets overlapping capabilities. This pure module finds those overlaps by
|
|
5
|
+
* name so the catalog can surface a "related to X" note, a maintainer-audit lint can list them, and
|
|
6
|
+
* the dashboard AI check can review them. Reused by all three — kept dependency-free.
|
|
7
|
+
*/
|
|
8
|
+
export interface SkillOverlap {
|
|
9
|
+
packId: string;
|
|
10
|
+
skillName: string;
|
|
11
|
+
/** Which surface of the pack the skill collided with. */
|
|
12
|
+
via: "pack-id" | "agent" | "command" | "attached-skill";
|
|
13
|
+
/** The pack-side name that matched (pre-normalization), for display. */
|
|
14
|
+
matchedName: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Normalize a hyphen/underscore/space-separated name to a comparable stem so different word forms
|
|
18
|
+
* of the same concept collapse together. Per word: strip a trailing gerund `-ing`, then a trailing
|
|
19
|
+
* `e`, then a trailing plural `-s`, then join. So `brainstorm`≈`brainstorming`,
|
|
20
|
+
* `write-plan`≈`writing-plans`, `execute-plan`≈`executing-plans`, and `systematic-debugging`
|
|
21
|
+
* matches itself — the exact and word-form cases the #23 finding cites. Deliberately conservative:
|
|
22
|
+
* it catches obvious variants, not arbitrary synonyms; genuinely fuzzy relationships are declared
|
|
23
|
+
* explicitly (the `relatedTo` field) rather than guessed here.
|
|
24
|
+
*/
|
|
25
|
+
export declare function normalizeName(name: string): string;
|
|
26
|
+
/**
|
|
27
|
+
* For every (pack, skill) pair whose names collapse to the same stem, emit one overlap. At most one
|
|
28
|
+
* overlap per pair even when several of the pack's surfaces match — the finding is "these two
|
|
29
|
+
* overlap", not "this skill matches three of the pack's names". The first matching surface (in
|
|
30
|
+
* id → agent → command → attached-skill order) is reported as the reason.
|
|
31
|
+
*/
|
|
32
|
+
export declare function computeSkillOverlaps(packs: WorkflowPack[], skills: SkillBlock[]): SkillOverlap[];
|
package/dist/overlap.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalize a hyphen/underscore/space-separated name to a comparable stem so different word forms
|
|
3
|
+
* of the same concept collapse together. Per word: strip a trailing gerund `-ing`, then a trailing
|
|
4
|
+
* `e`, then a trailing plural `-s`, then join. So `brainstorm`≈`brainstorming`,
|
|
5
|
+
* `write-plan`≈`writing-plans`, `execute-plan`≈`executing-plans`, and `systematic-debugging`
|
|
6
|
+
* matches itself — the exact and word-form cases the #23 finding cites. Deliberately conservative:
|
|
7
|
+
* it catches obvious variants, not arbitrary synonyms; genuinely fuzzy relationships are declared
|
|
8
|
+
* explicitly (the `relatedTo` field) rather than guessed here.
|
|
9
|
+
*/
|
|
10
|
+
export function normalizeName(name) {
|
|
11
|
+
return name
|
|
12
|
+
.toLowerCase()
|
|
13
|
+
.split(/[^a-z0-9]+/)
|
|
14
|
+
.filter((w) => w.length > 0)
|
|
15
|
+
.map((w) => w.replace(/ing$/, "").replace(/e$/, "").replace(/s$/, ""))
|
|
16
|
+
.join("");
|
|
17
|
+
}
|
|
18
|
+
/** Every name a pack "provides" — its id, agents, commands, and attached skills — as normalizable surfaces. */
|
|
19
|
+
function packSurfaces(pack) {
|
|
20
|
+
return [
|
|
21
|
+
{ via: "pack-id", name: pack.id },
|
|
22
|
+
...pack.agents.map((a) => ({ via: "agent", name: a.name })),
|
|
23
|
+
...pack.commands.map((c) => ({ via: "command", name: c.name })),
|
|
24
|
+
...(pack.skills ?? []).map((s) => ({ via: "attached-skill", name: s.name })),
|
|
25
|
+
];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* For every (pack, skill) pair whose names collapse to the same stem, emit one overlap. At most one
|
|
29
|
+
* overlap per pair even when several of the pack's surfaces match — the finding is "these two
|
|
30
|
+
* overlap", not "this skill matches three of the pack's names". The first matching surface (in
|
|
31
|
+
* id → agent → command → attached-skill order) is reported as the reason.
|
|
32
|
+
*/
|
|
33
|
+
export function computeSkillOverlaps(packs, skills) {
|
|
34
|
+
const overlaps = [];
|
|
35
|
+
for (const pack of packs) {
|
|
36
|
+
const byStem = new Map();
|
|
37
|
+
for (const surface of packSurfaces(pack)) {
|
|
38
|
+
const stem = normalizeName(surface.name);
|
|
39
|
+
if (stem.length > 0 && !byStem.has(stem))
|
|
40
|
+
byStem.set(stem, surface);
|
|
41
|
+
}
|
|
42
|
+
for (const skill of skills) {
|
|
43
|
+
const hit = byStem.get(normalizeName(skill.name));
|
|
44
|
+
if (hit)
|
|
45
|
+
overlaps.push({ packId: pack.id, skillName: skill.name, via: hit.via, matchedName: hit.name });
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return overlaps;
|
|
49
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { WorkflowPack } from "./types.ts";
|
|
2
|
+
export interface PackFromFilesetResult {
|
|
3
|
+
pack: WorkflowPack;
|
|
4
|
+
derived: boolean;
|
|
5
|
+
sources: string[];
|
|
6
|
+
skipped: string[];
|
|
7
|
+
}
|
|
8
|
+
export declare function packFromFileset(files: Record<string, string>, opts: {
|
|
9
|
+
repoName: string;
|
|
10
|
+
ref: string;
|
|
11
|
+
sha: string;
|
|
12
|
+
onlySkill?: string;
|
|
13
|
+
}): Promise<PackFromFilesetResult>;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { validatePack } from "./validate.js";
|
|
2
|
+
import { ingestHarness } from "./ingest.js";
|
|
3
|
+
const VERSION_TAG_RE = /^v?(\d+\.\d+\.\d+)$/;
|
|
4
|
+
const ONE_LEVEL_SKILL_RE = /^skills\/([^/]+)\/SKILL\.md$/;
|
|
5
|
+
const TWO_LEVEL_SKILL_RE = /^skills\/([^/]+)\/([^/]+)\/SKILL\.md$/;
|
|
6
|
+
const AGENTS_SKILL_RE = /^\.agents\/skills\/([^/]+)\/SKILL\.md$/;
|
|
7
|
+
const ROOT_SKILL_PATH = "SKILL.md";
|
|
8
|
+
function stampVersion(ref, sha) {
|
|
9
|
+
const m = VERSION_TAG_RE.exec(ref);
|
|
10
|
+
return m ? m[1] : `0.0.0+${sha.slice(0, 7)}`;
|
|
11
|
+
}
|
|
12
|
+
function rootSkillName(repoName) {
|
|
13
|
+
const segs = repoName.split("/");
|
|
14
|
+
return (segs[segs.length - 1] || repoName).toLowerCase();
|
|
15
|
+
}
|
|
16
|
+
/** Recognizes every npx-skills-convention layout for a SKILL.md: root single-skill repo,
|
|
17
|
+
* `skills/<name>/SKILL.md`, two-level `skills/<category>/<name>/SKILL.md` (category dirs include
|
|
18
|
+
* dot-dirs like `.curated`/`.experimental`/`.system`), and `.agents/skills/<name>/SKILL.md`. */
|
|
19
|
+
function findSkillMatches(paths, repoName) {
|
|
20
|
+
const matches = [];
|
|
21
|
+
for (const path of paths) {
|
|
22
|
+
let name = null;
|
|
23
|
+
let sourceDir = "";
|
|
24
|
+
if (path === ROOT_SKILL_PATH) {
|
|
25
|
+
name = rootSkillName(repoName);
|
|
26
|
+
sourceDir = "";
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
const oneLevel = ONE_LEVEL_SKILL_RE.exec(path);
|
|
30
|
+
const twoLevel = !oneLevel ? TWO_LEVEL_SKILL_RE.exec(path) : null;
|
|
31
|
+
const agentsLevel = !oneLevel && !twoLevel ? AGENTS_SKILL_RE.exec(path) : null;
|
|
32
|
+
if (oneLevel) {
|
|
33
|
+
name = oneLevel[1];
|
|
34
|
+
sourceDir = `skills/${oneLevel[1]}`;
|
|
35
|
+
}
|
|
36
|
+
else if (twoLevel) {
|
|
37
|
+
name = twoLevel[2];
|
|
38
|
+
sourceDir = `skills/${twoLevel[1]}/${twoLevel[2]}`;
|
|
39
|
+
}
|
|
40
|
+
else if (agentsLevel) {
|
|
41
|
+
name = agentsLevel[1];
|
|
42
|
+
sourceDir = `.agents/skills/${agentsLevel[1]}`;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (name === null)
|
|
46
|
+
continue;
|
|
47
|
+
matches.push({ path, name, sourceDir, depth: path.split("/").length - 1 });
|
|
48
|
+
}
|
|
49
|
+
return matches;
|
|
50
|
+
}
|
|
51
|
+
/** Shallow-shadows-deep: when the same skill name appears at multiple depths, the shallowest
|
|
52
|
+
* SKILL.md wins. At equal depth, the first path in sorted order wins (deterministic tie-break). */
|
|
53
|
+
function pickWinners(matches) {
|
|
54
|
+
const byName = new Map();
|
|
55
|
+
for (const m of matches) {
|
|
56
|
+
const arr = byName.get(m.name) ?? [];
|
|
57
|
+
arr.push(m);
|
|
58
|
+
byName.set(m.name, arr);
|
|
59
|
+
}
|
|
60
|
+
const winners = new Map();
|
|
61
|
+
for (const [name, arr] of byName) {
|
|
62
|
+
const sorted = [...arr].sort((a, b) => a.depth - b.depth || a.path.localeCompare(b.path));
|
|
63
|
+
winners.set(name, sorted[0]);
|
|
64
|
+
}
|
|
65
|
+
return winners;
|
|
66
|
+
}
|
|
67
|
+
/** Remaps every winning skills-corpus layout onto the `.claude/skills/<name>/...` surface that
|
|
68
|
+
* `ingestHarness` already knows how to read — the ONLY place layout knowledge lives. Sibling files
|
|
69
|
+
* (references, scripts) one level under a winning skill dir travel with it, under the same name.
|
|
70
|
+
* Shadowed SKILL.md's (and their siblings) are left at their original path, unremapped, so
|
|
71
|
+
* `ingestHarness` never sees them. Files not part of any skill layout pass through untouched. */
|
|
72
|
+
function remapSkillsLayout(files, repoName) {
|
|
73
|
+
const paths = Object.keys(files);
|
|
74
|
+
const winners = [...pickWinners(findSkillMatches(paths, repoName)).values()];
|
|
75
|
+
const winnersByPath = new Map(winners.map((w) => [w.path, w]));
|
|
76
|
+
const winningDirs = winners.filter((w) => w.sourceDir !== "").map((w) => ({ prefix: `${w.sourceDir}/`, name: w.name }));
|
|
77
|
+
const remapped = {};
|
|
78
|
+
for (const [path, content] of Object.entries(files)) {
|
|
79
|
+
const direct = winnersByPath.get(path);
|
|
80
|
+
if (direct) {
|
|
81
|
+
remapped[`.claude/skills/${direct.name}/SKILL.md`] = content;
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
const sibling = winningDirs.find((d) => path.startsWith(d.prefix) && !path.slice(d.prefix.length).includes("/"));
|
|
85
|
+
if (sibling) {
|
|
86
|
+
remapped[`.claude/skills/${sibling.name}/${path.slice(sibling.prefix.length)}`] = content;
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
remapped[path] = content;
|
|
90
|
+
}
|
|
91
|
+
return remapped;
|
|
92
|
+
}
|
|
93
|
+
/** Narrows an already-validated pack to a single named skill (the `@skill` selector). Throws
|
|
94
|
+
* naming every available skill name when `onlySkill` doesn't match any of them. */
|
|
95
|
+
function filterOnlySkill(pack, onlySkill) {
|
|
96
|
+
if (!onlySkill)
|
|
97
|
+
return pack;
|
|
98
|
+
const skills = pack.skills ?? [];
|
|
99
|
+
const match = skills.find((s) => s.name === onlySkill);
|
|
100
|
+
if (!match) {
|
|
101
|
+
const available = skills.map((s) => s.name).join(", ") || "(none)";
|
|
102
|
+
throw new Error(`pack-from-fileset: no skill named "${onlySkill}" — available: ${available}`);
|
|
103
|
+
}
|
|
104
|
+
return { ...pack, skills: [match] };
|
|
105
|
+
}
|
|
106
|
+
export async function packFromFileset(files, opts) {
|
|
107
|
+
if (typeof files["pack.json"] === "string") {
|
|
108
|
+
let raw;
|
|
109
|
+
try {
|
|
110
|
+
raw = JSON.parse(files["pack.json"]);
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
throw new Error(`pack-from-fileset: pack.json is not valid JSON: ${err instanceof Error ? err.message : String(err)}`);
|
|
114
|
+
}
|
|
115
|
+
const pack = filterOnlySkill(validatePack(raw), opts.onlySkill);
|
|
116
|
+
return { pack, derived: false, sources: ["pack.json"], skipped: [] };
|
|
117
|
+
}
|
|
118
|
+
// Skills-corpus layouts (plugin-repo skills/, two-level catalog dirs, .agents/skills/, root
|
|
119
|
+
// single-skill SKILL.md) → the .claude layout ingest knows.
|
|
120
|
+
const remapped = remapSkillsLayout(files, opts.repoName);
|
|
121
|
+
const input = {
|
|
122
|
+
repoName: opts.repoName,
|
|
123
|
+
listFiles: async () => Object.keys(remapped),
|
|
124
|
+
readFile: async (path) => remapped[path] ?? null,
|
|
125
|
+
};
|
|
126
|
+
const result = await ingestHarness(input);
|
|
127
|
+
const hasHarness = Object.keys(remapped).some((p) => p === "AGENTS.md" || p.startsWith(".claude/"));
|
|
128
|
+
if (!hasHarness) {
|
|
129
|
+
throw new Error(`pack-from-fileset: nothing installable — no root pack.json (native pack) and no AGENTS.md/.claude/skills content to ingest. See the pack format docs.`);
|
|
130
|
+
}
|
|
131
|
+
const pack = filterOnlySkill(validatePack({ ...result.pack, version: stampVersion(opts.ref, opts.sha) }), opts.onlySkill);
|
|
132
|
+
return { pack, derived: true, sources: result.sources, skipped: result.skipped };
|
|
133
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { WorkflowPack } from "../types.ts";
|
|
2
|
+
/** Copilot: no import syntax, no agent/command/hook surface — inline everything as prose. */
|
|
3
|
+
export declare function renderCopilot(pack: WorkflowPack): string;
|
|
4
|
+
/** Gemini CLI resolves @file imports like Claude Code — one-line pointer, plus full skill bodies
|
|
5
|
+
* appended (Gemini has no native skill mechanism). Byte-identical to the old pointer when no skills. */
|
|
6
|
+
export declare function renderGemini(pack: WorkflowPack): string;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/** Full skill bodies inlined for surfaces with no native skill mechanism (Option A). Empty when the
|
|
2
|
+
* pack has no skills, so callers stay byte-identical for skill-less packs. */
|
|
3
|
+
function skillBodiesSection(pack) {
|
|
4
|
+
if (!pack.skills || pack.skills.length === 0)
|
|
5
|
+
return [];
|
|
6
|
+
const out = ["## Skills", ""];
|
|
7
|
+
for (const s of pack.skills) {
|
|
8
|
+
out.push(`### ${s.name}`, "", s.description, "", s.body.trimEnd(), "");
|
|
9
|
+
}
|
|
10
|
+
return out;
|
|
11
|
+
}
|
|
12
|
+
/** Copilot: no import syntax, no agent/command/hook surface — inline everything as prose. */
|
|
13
|
+
export function renderCopilot(pack) {
|
|
14
|
+
const parts = ["# Copilot instructions", "", pack.context.markdown.trimEnd(), ""];
|
|
15
|
+
parts.push(`## Workflow pack: ${pack.title}`, "", pack.summary, "");
|
|
16
|
+
if (pack.agents.length > 0) {
|
|
17
|
+
for (const a of pack.agents) {
|
|
18
|
+
parts.push(`When acting as the ${a.name} role: ${a.prompt}`, "");
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
if (pack.commands.length > 0) {
|
|
22
|
+
parts.push("Workflow steps:", "");
|
|
23
|
+
for (const c of pack.commands)
|
|
24
|
+
parts.push(`- ${c.name}: ${c.prompt}`);
|
|
25
|
+
parts.push("");
|
|
26
|
+
}
|
|
27
|
+
if (pack.hooks.length > 0) {
|
|
28
|
+
for (const h of pack.hooks)
|
|
29
|
+
parts.push(`- ${h.action === "print-reminder" ? h.message : h.description}`);
|
|
30
|
+
parts.push("");
|
|
31
|
+
}
|
|
32
|
+
parts.push(...skillBodiesSection(pack));
|
|
33
|
+
return parts.join("\n");
|
|
34
|
+
}
|
|
35
|
+
/** Gemini CLI resolves @file imports like Claude Code — one-line pointer, plus full skill bodies
|
|
36
|
+
* appended (Gemini has no native skill mechanism). Byte-identical to the old pointer when no skills. */
|
|
37
|
+
export function renderGemini(pack) {
|
|
38
|
+
const base = "# GEMINI.md\n\n@AGENTS.md\n";
|
|
39
|
+
const bodies = skillBodiesSection(pack);
|
|
40
|
+
if (bodies.length === 0)
|
|
41
|
+
return base;
|
|
42
|
+
return `${base}\n${bodies.join("\n")}`;
|
|
43
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { renderCapabilities } from "./capabilities.js";
|
|
2
|
+
const FOOTER = "Tool-specific implementations live alongside this file (see `CLAUDE.md` for the " +
|
|
3
|
+
"Claude Code implementation). Tools without a native subagent/command surface should " +
|
|
4
|
+
"treat the sections above as operating instructions.";
|
|
5
|
+
/** Canonical AGENTS.md: context verbatim, then the pack as tool-agnostic sections. */
|
|
6
|
+
export function renderAgentsMd(pack) {
|
|
7
|
+
const a = pack.attribution;
|
|
8
|
+
const parts = [
|
|
9
|
+
"# AGENTS.md",
|
|
10
|
+
"",
|
|
11
|
+
`<!-- generated from workflow-pack ${pack.id} v${pack.version} -->`,
|
|
12
|
+
...(a ? [`<!-- adapted from ${a.source} (${a.license}) — ${a.url} -->`] : []),
|
|
13
|
+
"",
|
|
14
|
+
pack.context.markdown.trimEnd(),
|
|
15
|
+
"",
|
|
16
|
+
];
|
|
17
|
+
const { section } = renderCapabilities(pack);
|
|
18
|
+
if (section)
|
|
19
|
+
parts.push(section, "");
|
|
20
|
+
parts.push(`## Workflow pack: ${pack.title}`, "", pack.summary, "");
|
|
21
|
+
if (pack.agents.length > 0) {
|
|
22
|
+
parts.push("### Roles", "");
|
|
23
|
+
for (const a of pack.agents)
|
|
24
|
+
parts.push(`- **${a.name}** — ${a.description}`);
|
|
25
|
+
parts.push("");
|
|
26
|
+
}
|
|
27
|
+
if (pack.commands.length > 0) {
|
|
28
|
+
parts.push("### Commands", "");
|
|
29
|
+
for (const c of pack.commands) {
|
|
30
|
+
parts.push(`- **/${c.name}** \`${c.argument_hint}\` — ${c.description}`);
|
|
31
|
+
parts.push(` - How it runs: ${c.prompt}`);
|
|
32
|
+
}
|
|
33
|
+
parts.push("");
|
|
34
|
+
}
|
|
35
|
+
if (pack.hooks.length > 0) {
|
|
36
|
+
parts.push("### Guardrails", "");
|
|
37
|
+
for (const h of pack.hooks)
|
|
38
|
+
parts.push(`- ${h.description}`);
|
|
39
|
+
parts.push("");
|
|
40
|
+
}
|
|
41
|
+
if (pack.skills && pack.skills.length > 0) {
|
|
42
|
+
parts.push("### Skills", "");
|
|
43
|
+
for (const s of pack.skills)
|
|
44
|
+
parts.push(`- **${s.name}** — ${s.description}`);
|
|
45
|
+
parts.push("");
|
|
46
|
+
}
|
|
47
|
+
parts.push(FOOTER, "");
|
|
48
|
+
return parts.join("\n");
|
|
49
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { FileMap, WorkflowPack } from "../types.ts";
|
|
2
|
+
export interface BundleUnion {
|
|
3
|
+
files: FileMap;
|
|
4
|
+
collisions: string[];
|
|
5
|
+
}
|
|
6
|
+
/** Unions the machine-level bundle files of an ordered (most-specific-first) effective pack set.
|
|
7
|
+
* settings.json hooks concatenate per event; capabilities manifests dedup; every other path is
|
|
8
|
+
* first-writer-wins with a collisions note on a differing later write. `renderBundleUnion([p])`
|
|
9
|
+
* byte-equals `renderBundleFiles(p)`. */
|
|
10
|
+
export declare function renderBundleUnion(packs: WorkflowPack[]): BundleUnion;
|