@ibotor/smart-trellis 0.5.19
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 +235 -0
- package/README.md +263 -0
- package/bin/smart-trellis.js +3 -0
- package/bin/trellis.js +3 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +132 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/smart.d.ts +2 -0
- package/dist/cli/smart.d.ts.map +1 -0
- package/dist/cli/smart.js +41 -0
- package/dist/cli/smart.js.map +1 -0
- package/dist/commands/init.d.ts +56 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +1466 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/smart-init.d.ts +22 -0
- package/dist/commands/smart-init.d.ts.map +1 -0
- package/dist/commands/smart-init.js +122 -0
- package/dist/commands/smart-init.js.map +1 -0
- package/dist/commands/uninstall.d.ts +27 -0
- package/dist/commands/uninstall.d.ts.map +1 -0
- package/dist/commands/uninstall.js +339 -0
- package/dist/commands/uninstall.js.map +1 -0
- package/dist/commands/update.d.ts +72 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +1926 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/configurators/antigravity.d.ts +7 -0
- package/dist/configurators/antigravity.d.ts.map +1 -0
- package/dist/configurators/antigravity.js +19 -0
- package/dist/configurators/antigravity.js.map +1 -0
- package/dist/configurators/claude.d.ts +9 -0
- package/dist/configurators/claude.d.ts.map +1 -0
- package/dist/configurators/claude.js +72 -0
- package/dist/configurators/claude.js.map +1 -0
- package/dist/configurators/codebuddy.d.ts +10 -0
- package/dist/configurators/codebuddy.d.ts.map +1 -0
- package/dist/configurators/codebuddy.js +30 -0
- package/dist/configurators/codebuddy.js.map +1 -0
- package/dist/configurators/codex.d.ts +8 -0
- package/dist/configurators/codex.d.ts.map +1 -0
- package/dist/configurators/codex.js +85 -0
- package/dist/configurators/codex.js.map +1 -0
- package/dist/configurators/copilot.d.ts +10 -0
- package/dist/configurators/copilot.d.ts.map +1 -0
- package/dist/configurators/copilot.js +51 -0
- package/dist/configurators/copilot.js.map +1 -0
- package/dist/configurators/cursor.d.ts +10 -0
- package/dist/configurators/cursor.d.ts.map +1 -0
- package/dist/configurators/cursor.js +29 -0
- package/dist/configurators/cursor.js.map +1 -0
- package/dist/configurators/droid.d.ts +10 -0
- package/dist/configurators/droid.d.ts.map +1 -0
- package/dist/configurators/droid.js +30 -0
- package/dist/configurators/droid.js.map +1 -0
- package/dist/configurators/gemini.d.ts +16 -0
- package/dist/configurators/gemini.d.ts.map +1 -0
- package/dist/configurators/gemini.js +38 -0
- package/dist/configurators/gemini.js.map +1 -0
- package/dist/configurators/index.d.ts +65 -0
- package/dist/configurators/index.d.ts.map +1 -0
- package/dist/configurators/index.js +367 -0
- package/dist/configurators/index.js.map +1 -0
- package/dist/configurators/kilo.d.ts +7 -0
- package/dist/configurators/kilo.d.ts.map +1 -0
- package/dist/configurators/kilo.js +19 -0
- package/dist/configurators/kilo.js.map +1 -0
- package/dist/configurators/kiro.d.ts +8 -0
- package/dist/configurators/kiro.d.ts.map +1 -0
- package/dist/configurators/kiro.js +24 -0
- package/dist/configurators/kiro.js.map +1 -0
- package/dist/configurators/opencode.d.ts +14 -0
- package/dist/configurators/opencode.d.ts.map +1 -0
- package/dist/configurators/opencode.js +96 -0
- package/dist/configurators/opencode.js.map +1 -0
- package/dist/configurators/pi.d.ts +3 -0
- package/dist/configurators/pi.d.ts.map +1 -0
- package/dist/configurators/pi.js +45 -0
- package/dist/configurators/pi.js.map +1 -0
- package/dist/configurators/qoder.d.ts +11 -0
- package/dist/configurators/qoder.d.ts.map +1 -0
- package/dist/configurators/qoder.js +31 -0
- package/dist/configurators/qoder.js.map +1 -0
- package/dist/configurators/shared.d.ts +178 -0
- package/dist/configurators/shared.d.ts.map +1 -0
- package/dist/configurators/shared.js +538 -0
- package/dist/configurators/shared.js.map +1 -0
- package/dist/configurators/windsurf.d.ts +7 -0
- package/dist/configurators/windsurf.d.ts.map +1 -0
- package/dist/configurators/windsurf.js +19 -0
- package/dist/configurators/windsurf.js.map +1 -0
- package/dist/configurators/workflow.d.ts +29 -0
- package/dist/configurators/workflow.d.ts.map +1 -0
- package/dist/configurators/workflow.js +163 -0
- package/dist/configurators/workflow.js.map +1 -0
- package/dist/constants/paths.d.ts +70 -0
- package/dist/constants/paths.d.ts.map +1 -0
- package/dist/constants/paths.js +79 -0
- package/dist/constants/paths.js.map +1 -0
- package/dist/constants/version.d.ts +9 -0
- package/dist/constants/version.d.ts.map +1 -0
- package/dist/constants/version.js +15 -0
- package/dist/constants/version.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/migrations/index.d.ts +62 -0
- package/dist/migrations/index.d.ts.map +1 -0
- package/dist/migrations/index.js +187 -0
- package/dist/migrations/index.js.map +1 -0
- package/dist/migrations/manifests/0.1.9.json +30 -0
- package/dist/migrations/manifests/0.2.0.json +49 -0
- package/dist/migrations/manifests/0.2.12.json +9 -0
- package/dist/migrations/manifests/0.2.13.json +9 -0
- package/dist/migrations/manifests/0.2.14.json +175 -0
- package/dist/migrations/manifests/0.2.15.json +33 -0
- package/dist/migrations/manifests/0.3.0-beta.0.json +297 -0
- package/dist/migrations/manifests/0.3.0-beta.1.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.10.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.11.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.12.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.13.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.14.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.15.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.16.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.2.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.3.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.4.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.5.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.6.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.7.json +11 -0
- package/dist/migrations/manifests/0.3.0-beta.8.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.9.json +9 -0
- package/dist/migrations/manifests/0.3.0-rc.0.json +9 -0
- package/dist/migrations/manifests/0.3.0-rc.1.json +9 -0
- package/dist/migrations/manifests/0.3.0-rc.2.json +9 -0
- package/dist/migrations/manifests/0.3.0-rc.3.json +9 -0
- package/dist/migrations/manifests/0.3.0-rc.4.json +9 -0
- package/dist/migrations/manifests/0.3.0-rc.5.json +9 -0
- package/dist/migrations/manifests/0.3.0-rc.6.json +9 -0
- package/dist/migrations/manifests/0.3.0.json +11 -0
- package/dist/migrations/manifests/0.3.1.json +9 -0
- package/dist/migrations/manifests/0.3.10.json +9 -0
- package/dist/migrations/manifests/0.3.2.json +9 -0
- package/dist/migrations/manifests/0.3.3.json +9 -0
- package/dist/migrations/manifests/0.3.4.json +21 -0
- package/dist/migrations/manifests/0.3.5.json +9 -0
- package/dist/migrations/manifests/0.3.6.json +9 -0
- package/dist/migrations/manifests/0.3.7.json +9 -0
- package/dist/migrations/manifests/0.3.8.json +9 -0
- package/dist/migrations/manifests/0.3.9.json +9 -0
- package/dist/migrations/manifests/0.4.0-beta.1.json +228 -0
- package/dist/migrations/manifests/0.4.0-beta.10.json +9 -0
- package/dist/migrations/manifests/0.4.0-beta.2.json +9 -0
- package/dist/migrations/manifests/0.4.0-beta.3.json +9 -0
- package/dist/migrations/manifests/0.4.0-beta.4.json +9 -0
- package/dist/migrations/manifests/0.4.0-beta.5.json +9 -0
- package/dist/migrations/manifests/0.4.0-beta.6.json +9 -0
- package/dist/migrations/manifests/0.4.0-beta.7.json +9 -0
- package/dist/migrations/manifests/0.4.0-beta.8.json +34 -0
- package/dist/migrations/manifests/0.4.0-beta.9.json +9 -0
- package/dist/migrations/manifests/0.4.0-rc.0.json +9 -0
- package/dist/migrations/manifests/0.4.0-rc.1.json +9 -0
- package/dist/migrations/manifests/0.4.0.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.0.json +1646 -0
- package/dist/migrations/manifests/0.5.0-beta.1.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.10.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.11.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.12.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.13.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.14.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.15.json +116 -0
- package/dist/migrations/manifests/0.5.0-beta.16.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.17.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.18.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.19.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.2.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.3.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.4.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.5.json +222 -0
- package/dist/migrations/manifests/0.5.0-beta.6.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.7.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.8.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.9.json +48 -0
- package/dist/migrations/manifests/0.5.0-rc.0.json +9 -0
- package/dist/migrations/manifests/0.5.0-rc.1.json +9 -0
- package/dist/migrations/manifests/0.5.0-rc.2.json +9 -0
- package/dist/migrations/manifests/0.5.0-rc.3.json +9 -0
- package/dist/migrations/manifests/0.5.0-rc.4.json +9 -0
- package/dist/migrations/manifests/0.5.0-rc.5.json +9 -0
- package/dist/migrations/manifests/0.5.0-rc.6.json +9 -0
- package/dist/migrations/manifests/0.5.0-rc.7.json +9 -0
- package/dist/migrations/manifests/0.5.0.json +9 -0
- package/dist/migrations/manifests/0.5.1.json +9 -0
- package/dist/migrations/manifests/0.5.10.json +9 -0
- package/dist/migrations/manifests/0.5.11.json +16 -0
- package/dist/migrations/manifests/0.5.12.json +9 -0
- package/dist/migrations/manifests/0.5.13.json +9 -0
- package/dist/migrations/manifests/0.5.14.json +9 -0
- package/dist/migrations/manifests/0.5.15.json +9 -0
- package/dist/migrations/manifests/0.5.16.json +9 -0
- package/dist/migrations/manifests/0.5.17.json +9 -0
- package/dist/migrations/manifests/0.5.18.json +9 -0
- package/dist/migrations/manifests/0.5.19.json +9 -0
- package/dist/migrations/manifests/0.5.2.json +9 -0
- package/dist/migrations/manifests/0.5.3.json +9 -0
- package/dist/migrations/manifests/0.5.4.json +9 -0
- package/dist/migrations/manifests/0.5.5.json +9 -0
- package/dist/migrations/manifests/0.5.6.json +9 -0
- package/dist/migrations/manifests/0.5.7.json +16 -0
- package/dist/migrations/manifests/0.5.8.json +9 -0
- package/dist/migrations/manifests/0.5.9.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.0.json +16 -0
- package/dist/migrations/manifests/0.6.0-beta.1.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.10.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.11.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.12.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.13.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.14.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.15.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.16.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.17.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.18.json +16 -0
- package/dist/migrations/manifests/0.6.0-beta.19.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.2.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.20.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.21.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.3.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.4.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.5.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.6.json +16 -0
- package/dist/migrations/manifests/0.6.0-beta.7.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.8.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.9.json +9 -0
- package/dist/templates/claude/agents/trellis-check.md +109 -0
- package/dist/templates/claude/agents/trellis-implement.md +109 -0
- package/dist/templates/claude/agents/trellis-research.md +137 -0
- package/dist/templates/claude/index.d.ts +22 -0
- package/dist/templates/claude/index.d.ts.map +1 -0
- package/dist/templates/claude/index.js +46 -0
- package/dist/templates/claude/index.js.map +1 -0
- package/dist/templates/claude/settings.json +73 -0
- package/dist/templates/codebuddy/agents/trellis-check.md +109 -0
- package/dist/templates/codebuddy/agents/trellis-implement.md +109 -0
- package/dist/templates/codebuddy/agents/trellis-research.md +137 -0
- package/dist/templates/codebuddy/index.d.ts +15 -0
- package/dist/templates/codebuddy/index.d.ts.map +1 -0
- package/dist/templates/codebuddy/index.js +15 -0
- package/dist/templates/codebuddy/index.js.map +1 -0
- package/dist/templates/codebuddy/settings.json +59 -0
- package/dist/templates/codex/agents/trellis-check.toml +84 -0
- package/dist/templates/codex/agents/trellis-implement.toml +65 -0
- package/dist/templates/codex/agents/trellis-research.toml +73 -0
- package/dist/templates/codex/config.toml +28 -0
- package/dist/templates/codex/hooks/session-start.py +481 -0
- package/dist/templates/codex/hooks.json +15 -0
- package/dist/templates/codex/index.d.ts +39 -0
- package/dist/templates/codex/index.d.ts.map +1 -0
- package/dist/templates/codex/index.js +85 -0
- package/dist/templates/codex/index.js.map +1 -0
- package/dist/templates/codex/skills/before-dev/SKILL.md +34 -0
- package/dist/templates/codex/skills/brainstorm/SKILL.md +500 -0
- package/dist/templates/codex/skills/break-loop/SKILL.md +130 -0
- package/dist/templates/codex/skills/check/SKILL.md +30 -0
- package/dist/templates/codex/skills/check-cross-layer/SKILL.md +158 -0
- package/dist/templates/codex/skills/create-command/SKILL.md +101 -0
- package/dist/templates/codex/skills/finish-work/SKILL.md +90 -0
- package/dist/templates/codex/skills/improve-ut/SKILL.md +69 -0
- package/dist/templates/codex/skills/integrate-skill/SKILL.md +221 -0
- package/dist/templates/codex/skills/onboard/SKILL.md +363 -0
- package/dist/templates/codex/skills/record-session/SKILL.md +67 -0
- package/dist/templates/codex/skills/start/SKILL.md +354 -0
- package/dist/templates/codex/skills/update-spec/SKILL.md +335 -0
- package/dist/templates/common/bundled-skills/trellis-meta/SKILL.md +73 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/add-project-local-conventions.md +83 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-agents.md +54 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-context-loading.md +81 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-hooks.md +57 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-skills-or-commands.md +78 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-spec-structure.md +83 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-task-lifecycle.md +90 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-workflow.md +64 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/overview.md +55 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/context-injection.md +68 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/generated-files.md +80 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/overview.md +51 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/spec-system.md +102 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/task-system.md +101 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/workflow.md +75 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/workspace-memory.md +71 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/agents.md +79 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/hooks-and-settings.md +69 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/overview.md +59 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/platform-map.md +74 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/skills-and-commands.md +83 -0
- package/dist/templates/common/bundled-skills/trellis-spec-bootstarp/SKILL.md +41 -0
- package/dist/templates/common/bundled-skills/trellis-spec-bootstarp/references/mcp-setup.md +90 -0
- package/dist/templates/common/bundled-skills/trellis-spec-bootstarp/references/repository-analysis.md +59 -0
- package/dist/templates/common/bundled-skills/trellis-spec-bootstarp/references/spec-task-planning.md +61 -0
- package/dist/templates/common/bundled-skills/trellis-spec-bootstarp/references/spec-writing.md +70 -0
- package/dist/templates/common/commands/continue.md +55 -0
- package/dist/templates/common/commands/finish-work.md +66 -0
- package/dist/templates/common/commands/start.md +58 -0
- package/dist/templates/common/index.d.ts +48 -0
- package/dist/templates/common/index.d.ts.map +1 -0
- package/dist/templates/common/index.js +104 -0
- package/dist/templates/common/index.js.map +1 -0
- package/dist/templates/common/skills/before-dev.md +29 -0
- package/dist/templates/common/skills/brainstorm.md +543 -0
- package/dist/templates/common/skills/break-loop.md +125 -0
- package/dist/templates/common/skills/check.md +87 -0
- package/dist/templates/common/skills/update-spec.md +351 -0
- package/dist/templates/copilot/hooks/session-start.py +454 -0
- package/dist/templates/copilot/hooks.json +19 -0
- package/dist/templates/copilot/index.d.ts +23 -0
- package/dist/templates/copilot/index.d.ts.map +1 -0
- package/dist/templates/copilot/index.js +54 -0
- package/dist/templates/copilot/index.js.map +1 -0
- package/dist/templates/copilot/prompts/before-dev.prompt.md +33 -0
- package/dist/templates/copilot/prompts/brainstorm.prompt.md +499 -0
- package/dist/templates/copilot/prompts/break-loop.prompt.md +129 -0
- package/dist/templates/copilot/prompts/check-cross-layer.prompt.md +157 -0
- package/dist/templates/copilot/prompts/check.prompt.md +29 -0
- package/dist/templates/copilot/prompts/create-command.prompt.md +116 -0
- package/dist/templates/copilot/prompts/finish-work.prompt.md +99 -0
- package/dist/templates/copilot/prompts/integrate-skill.prompt.md +223 -0
- package/dist/templates/copilot/prompts/onboard.prompt.md +362 -0
- package/dist/templates/copilot/prompts/parallel.prompt.md +196 -0
- package/dist/templates/copilot/prompts/record-session.prompt.md +66 -0
- package/dist/templates/copilot/prompts/start.prompt.md +397 -0
- package/dist/templates/copilot/prompts/update-spec.prompt.md +358 -0
- package/dist/templates/cursor/agents/trellis-check.md +108 -0
- package/dist/templates/cursor/agents/trellis-implement.md +108 -0
- package/dist/templates/cursor/agents/trellis-research.md +136 -0
- package/dist/templates/cursor/hooks.json +24 -0
- package/dist/templates/cursor/index.d.ts +13 -0
- package/dist/templates/cursor/index.d.ts.map +1 -0
- package/dist/templates/cursor/index.js +13 -0
- package/dist/templates/cursor/index.js.map +1 -0
- package/dist/templates/droid/droids/trellis-check.md +101 -0
- package/dist/templates/droid/droids/trellis-implement.md +101 -0
- package/dist/templates/droid/droids/trellis-research.md +137 -0
- package/dist/templates/droid/index.d.ts +15 -0
- package/dist/templates/droid/index.d.ts.map +1 -0
- package/dist/templates/droid/index.js +15 -0
- package/dist/templates/droid/index.js.map +1 -0
- package/dist/templates/droid/settings.json +59 -0
- package/dist/templates/extract.d.ts +40 -0
- package/dist/templates/extract.d.ts.map +1 -0
- package/dist/templates/extract.js +106 -0
- package/dist/templates/extract.js.map +1 -0
- package/dist/templates/gemini/agents/trellis-check.md +101 -0
- package/dist/templates/gemini/agents/trellis-implement.md +101 -0
- package/dist/templates/gemini/agents/trellis-research.md +136 -0
- package/dist/templates/gemini/index.d.ts +13 -0
- package/dist/templates/gemini/index.d.ts.map +1 -0
- package/dist/templates/gemini/index.js +13 -0
- package/dist/templates/gemini/index.js.map +1 -0
- package/dist/templates/gemini/settings.json +28 -0
- package/dist/templates/kiro/agents/trellis-check.json +26 -0
- package/dist/templates/kiro/agents/trellis-implement.json +26 -0
- package/dist/templates/kiro/agents/trellis-research.json +30 -0
- package/dist/templates/kiro/index.d.ts +18 -0
- package/dist/templates/kiro/index.d.ts.map +1 -0
- package/dist/templates/kiro/index.js +18 -0
- package/dist/templates/kiro/index.js.map +1 -0
- package/dist/templates/markdown/agents.md +21 -0
- package/dist/templates/markdown/gitignore.txt +15 -0
- package/dist/templates/markdown/index.d.ts +27 -0
- package/dist/templates/markdown/index.d.ts.map +1 -0
- package/dist/templates/markdown/index.js +52 -0
- package/dist/templates/markdown/index.js.map +1 -0
- package/dist/templates/markdown/spec/backend/database-guidelines.md.txt +51 -0
- package/dist/templates/markdown/spec/backend/directory-structure.md.txt +54 -0
- package/dist/templates/markdown/spec/backend/error-handling.md.txt +51 -0
- package/dist/templates/markdown/spec/backend/index.md.txt +38 -0
- package/dist/templates/markdown/spec/backend/logging-guidelines.md.txt +51 -0
- package/dist/templates/markdown/spec/backend/quality-guidelines.md.txt +51 -0
- package/dist/templates/markdown/spec/frontend/component-guidelines.md.txt +59 -0
- package/dist/templates/markdown/spec/frontend/directory-structure.md.txt +54 -0
- package/dist/templates/markdown/spec/frontend/hook-guidelines.md.txt +51 -0
- package/dist/templates/markdown/spec/frontend/index.md.txt +39 -0
- package/dist/templates/markdown/spec/frontend/quality-guidelines.md.txt +51 -0
- package/dist/templates/markdown/spec/frontend/state-management.md.txt +51 -0
- package/dist/templates/markdown/spec/frontend/type-safety.md.txt +51 -0
- package/dist/templates/markdown/spec/guides/code-reuse-thinking-guide.md.txt +105 -0
- package/dist/templates/markdown/spec/guides/cross-layer-thinking-guide.md.txt +162 -0
- package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md.txt +595 -0
- package/dist/templates/markdown/spec/guides/index.md.txt +79 -0
- package/dist/templates/markdown/workspace-index.md +125 -0
- package/dist/templates/markdown/worktree.yaml.txt +58 -0
- package/dist/templates/opencode/agents/trellis-check.md +116 -0
- package/dist/templates/opencode/agents/trellis-implement.md +117 -0
- package/dist/templates/opencode/agents/trellis-research.md +145 -0
- package/dist/templates/opencode/lib/session-utils.js +432 -0
- package/dist/templates/opencode/lib/trellis-context.js +381 -0
- package/dist/templates/opencode/package.json +5 -0
- package/dist/templates/opencode/plugins/inject-subagent-context.js +497 -0
- package/dist/templates/opencode/plugins/inject-workflow-state.js +162 -0
- package/dist/templates/opencode/plugins/session-start.js +101 -0
- package/dist/templates/pi/agents/trellis-check.md +36 -0
- package/dist/templates/pi/agents/trellis-implement.md +41 -0
- package/dist/templates/pi/agents/trellis-research.md +25 -0
- package/dist/templates/pi/extensions/trellis/index.ts.txt +1172 -0
- package/dist/templates/pi/index.d.ts +5 -0
- package/dist/templates/pi/index.d.ts.map +1 -0
- package/dist/templates/pi/index.js +12 -0
- package/dist/templates/pi/index.js.map +1 -0
- package/dist/templates/pi/settings.json +21 -0
- package/dist/templates/qoder/agents/trellis-check.md +102 -0
- package/dist/templates/qoder/agents/trellis-implement.md +102 -0
- package/dist/templates/qoder/agents/trellis-research.md +137 -0
- package/dist/templates/qoder/index.d.ts +15 -0
- package/dist/templates/qoder/index.d.ts.map +1 -0
- package/dist/templates/qoder/index.js +15 -0
- package/dist/templates/qoder/index.js.map +1 -0
- package/dist/templates/qoder/settings.json +47 -0
- package/dist/templates/shared-hooks/index.d.ts +50 -0
- package/dist/templates/shared-hooks/index.d.ts.map +1 -0
- package/dist/templates/shared-hooks/index.js +88 -0
- package/dist/templates/shared-hooks/index.js.map +1 -0
- package/dist/templates/shared-hooks/inject-shell-session-context.py +183 -0
- package/dist/templates/shared-hooks/inject-subagent-context.py +749 -0
- package/dist/templates/shared-hooks/inject-workflow-state.py +387 -0
- package/dist/templates/shared-hooks/session-start.py +797 -0
- package/dist/templates/template-utils.d.ts +26 -0
- package/dist/templates/template-utils.d.ts.map +1 -0
- package/dist/templates/template-utils.js +60 -0
- package/dist/templates/template-utils.js.map +1 -0
- package/dist/templates/trellis/config.yaml +90 -0
- package/dist/templates/trellis/gitignore.txt +32 -0
- package/dist/templates/trellis/index.d.ts +52 -0
- package/dist/templates/trellis/index.d.ts.map +1 -0
- package/dist/templates/trellis/index.js +97 -0
- package/dist/templates/trellis/index.js.map +1 -0
- package/dist/templates/trellis/scripts/__init__.py +5 -0
- package/dist/templates/trellis/scripts/add_session.py +547 -0
- package/dist/templates/trellis/scripts/common/__init__.py +92 -0
- package/dist/templates/trellis/scripts/common/active_task.py +626 -0
- package/dist/templates/trellis/scripts/common/cli_adapter.py +811 -0
- package/dist/templates/trellis/scripts/common/config.py +445 -0
- package/dist/templates/trellis/scripts/common/developer.py +190 -0
- package/dist/templates/trellis/scripts/common/git.py +31 -0
- package/dist/templates/trellis/scripts/common/git_context.py +106 -0
- package/dist/templates/trellis/scripts/common/io.py +37 -0
- package/dist/templates/trellis/scripts/common/log.py +45 -0
- package/dist/templates/trellis/scripts/common/packages_context.py +238 -0
- package/dist/templates/trellis/scripts/common/paths.py +447 -0
- package/dist/templates/trellis/scripts/common/safe_commit.py +285 -0
- package/dist/templates/trellis/scripts/common/session_context.py +821 -0
- package/dist/templates/trellis/scripts/common/task_context.py +223 -0
- package/dist/templates/trellis/scripts/common/task_queue.py +188 -0
- package/dist/templates/trellis/scripts/common/task_store.py +697 -0
- package/dist/templates/trellis/scripts/common/task_utils.py +274 -0
- package/dist/templates/trellis/scripts/common/tasks.py +112 -0
- package/dist/templates/trellis/scripts/common/trellis_config.py +131 -0
- package/dist/templates/trellis/scripts/common/types.py +110 -0
- package/dist/templates/trellis/scripts/common/workflow_phase.py +215 -0
- package/dist/templates/trellis/scripts/get_context.py +16 -0
- package/dist/templates/trellis/scripts/get_developer.py +26 -0
- package/dist/templates/trellis/scripts/hooks/linear_sync.py +243 -0
- package/dist/templates/trellis/scripts/init_developer.py +51 -0
- package/dist/templates/trellis/scripts/task.py +500 -0
- package/dist/templates/trellis/tasks/.gitkeep +0 -0
- package/dist/templates/trellis/workflow.md +690 -0
- package/dist/types/ai-tools.d.ts +95 -0
- package/dist/types/ai-tools.d.ts.map +1 -0
- package/dist/types/ai-tools.js +280 -0
- package/dist/types/ai-tools.js.map +1 -0
- package/dist/types/migration.d.ts +125 -0
- package/dist/types/migration.d.ts.map +1 -0
- package/dist/types/migration.js +8 -0
- package/dist/types/migration.js.map +1 -0
- package/dist/utils/compare-versions.d.ts +12 -0
- package/dist/utils/compare-versions.d.ts.map +1 -0
- package/dist/utils/compare-versions.js +86 -0
- package/dist/utils/compare-versions.js.map +1 -0
- package/dist/utils/cwd-guard.d.ts +38 -0
- package/dist/utils/cwd-guard.d.ts.map +1 -0
- package/dist/utils/cwd-guard.js +62 -0
- package/dist/utils/cwd-guard.js.map +1 -0
- package/dist/utils/file-writer.d.ts +36 -0
- package/dist/utils/file-writer.d.ts.map +1 -0
- package/dist/utils/file-writer.js +203 -0
- package/dist/utils/file-writer.js.map +1 -0
- package/dist/utils/manifest-prune.d.ts +61 -0
- package/dist/utils/manifest-prune.d.ts.map +1 -0
- package/dist/utils/manifest-prune.js +136 -0
- package/dist/utils/manifest-prune.js.map +1 -0
- package/dist/utils/posix.d.ts +13 -0
- package/dist/utils/posix.d.ts.map +1 -0
- package/dist/utils/posix.js +15 -0
- package/dist/utils/posix.js.map +1 -0
- package/dist/utils/project-detector.d.ts +46 -0
- package/dist/utils/project-detector.d.ts.map +1 -0
- package/dist/utils/project-detector.js +666 -0
- package/dist/utils/project-detector.js.map +1 -0
- package/dist/utils/proxy.d.ts +25 -0
- package/dist/utils/proxy.d.ts.map +1 -0
- package/dist/utils/proxy.js +60 -0
- package/dist/utils/proxy.js.map +1 -0
- package/dist/utils/task-json.d.ts +46 -0
- package/dist/utils/task-json.d.ts.map +1 -0
- package/dist/utils/task-json.js +49 -0
- package/dist/utils/task-json.js.map +1 -0
- package/dist/utils/template-fetcher.d.ts +150 -0
- package/dist/utils/template-fetcher.d.ts.map +1 -0
- package/dist/utils/template-fetcher.js +907 -0
- package/dist/utils/template-fetcher.js.map +1 -0
- package/dist/utils/template-hash.d.ts +123 -0
- package/dist/utils/template-hash.d.ts.map +1 -0
- package/dist/utils/template-hash.js +334 -0
- package/dist/utils/template-hash.js.map +1 -0
- package/dist/utils/uninstall-scrubbers.d.ts +66 -0
- package/dist/utils/uninstall-scrubbers.d.ts.map +1 -0
- package/dist/utils/uninstall-scrubbers.js +342 -0
- package/dist/utils/uninstall-scrubbers.js.map +1 -0
- package/package.json +89 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-detector.d.ts","sourceRoot":"","sources":["../../src/utils/project-detector.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC;AAiK3E;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAqB1D;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAWnE;AAMD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,iEAAiE;IACjE,IAAI,EAAE,MAAM,CAAC;IACb,sEAAsE;IACtE,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,IAAI,EAAE,WAAW,CAAC;IAClB,8CAA8C;IAC9C,WAAW,EAAE,OAAO,CAAC;IACrB,sFAAsF;IACtF,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD;AAsYD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,EAAE,GAAG,IAAI,CAyHpE"}
|
|
@@ -0,0 +1,666 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
/**
|
|
4
|
+
* Files that indicate a frontend project
|
|
5
|
+
*/
|
|
6
|
+
const FRONTEND_INDICATORS = [
|
|
7
|
+
// Package managers with frontend deps
|
|
8
|
+
"package.json", // Will check for frontend dependencies
|
|
9
|
+
// Build tools
|
|
10
|
+
"vite.config.ts",
|
|
11
|
+
"vite.config.js",
|
|
12
|
+
"next.config.js",
|
|
13
|
+
"next.config.ts",
|
|
14
|
+
"next.config.mjs",
|
|
15
|
+
"nuxt.config.ts",
|
|
16
|
+
"nuxt.config.js",
|
|
17
|
+
"webpack.config.js",
|
|
18
|
+
"rollup.config.js",
|
|
19
|
+
// Framework configs
|
|
20
|
+
"svelte.config.js",
|
|
21
|
+
"astro.config.mjs",
|
|
22
|
+
"angular.json",
|
|
23
|
+
"vue.config.js",
|
|
24
|
+
// Source directories
|
|
25
|
+
"src/App.tsx",
|
|
26
|
+
"src/App.jsx",
|
|
27
|
+
"src/App.vue",
|
|
28
|
+
"src/app/page.tsx",
|
|
29
|
+
"app/page.tsx",
|
|
30
|
+
"pages/index.tsx",
|
|
31
|
+
"pages/index.jsx",
|
|
32
|
+
];
|
|
33
|
+
/**
|
|
34
|
+
* Files that indicate a backend project
|
|
35
|
+
*/
|
|
36
|
+
const BACKEND_INDICATORS = [
|
|
37
|
+
// Go
|
|
38
|
+
"go.mod",
|
|
39
|
+
"go.sum",
|
|
40
|
+
// Rust
|
|
41
|
+
"Cargo.toml",
|
|
42
|
+
"Cargo.lock",
|
|
43
|
+
// Python
|
|
44
|
+
"requirements.txt",
|
|
45
|
+
"pyproject.toml",
|
|
46
|
+
"setup.py",
|
|
47
|
+
"Pipfile",
|
|
48
|
+
"poetry.lock",
|
|
49
|
+
// Java/Kotlin
|
|
50
|
+
"pom.xml",
|
|
51
|
+
"build.gradle",
|
|
52
|
+
"build.gradle.kts",
|
|
53
|
+
// Ruby
|
|
54
|
+
"Gemfile",
|
|
55
|
+
// PHP
|
|
56
|
+
"composer.json",
|
|
57
|
+
// .NET
|
|
58
|
+
"*.csproj",
|
|
59
|
+
"*.fsproj",
|
|
60
|
+
// Elixir
|
|
61
|
+
"mix.exs",
|
|
62
|
+
// Node.js backend indicators
|
|
63
|
+
"server.ts",
|
|
64
|
+
"server.js",
|
|
65
|
+
"src/server.ts",
|
|
66
|
+
"src/index.ts", // Could be backend entry
|
|
67
|
+
];
|
|
68
|
+
/**
|
|
69
|
+
* Frontend dependencies in package.json
|
|
70
|
+
*/
|
|
71
|
+
const FRONTEND_DEPS = [
|
|
72
|
+
"react",
|
|
73
|
+
"vue",
|
|
74
|
+
"svelte",
|
|
75
|
+
"angular",
|
|
76
|
+
"@angular/core",
|
|
77
|
+
"next",
|
|
78
|
+
"nuxt",
|
|
79
|
+
"astro",
|
|
80
|
+
"solid-js",
|
|
81
|
+
"preact",
|
|
82
|
+
"lit",
|
|
83
|
+
"@remix-run/react",
|
|
84
|
+
];
|
|
85
|
+
/**
|
|
86
|
+
* Backend dependencies in package.json
|
|
87
|
+
*/
|
|
88
|
+
const BACKEND_DEPS = [
|
|
89
|
+
"express",
|
|
90
|
+
"fastify",
|
|
91
|
+
"hono",
|
|
92
|
+
"koa",
|
|
93
|
+
"hapi",
|
|
94
|
+
"nest",
|
|
95
|
+
"@nestjs/core",
|
|
96
|
+
"fastapi",
|
|
97
|
+
"flask",
|
|
98
|
+
"django",
|
|
99
|
+
];
|
|
100
|
+
/**
|
|
101
|
+
* Check if a file exists in the project directory
|
|
102
|
+
*/
|
|
103
|
+
function fileExists(cwd, filename) {
|
|
104
|
+
// Handle glob patterns like *.csproj
|
|
105
|
+
if (filename.includes("*")) {
|
|
106
|
+
const dir = path.dirname(filename) || ".";
|
|
107
|
+
const pattern = path.basename(filename);
|
|
108
|
+
const searchDir = path.join(cwd, dir);
|
|
109
|
+
if (!fs.existsSync(searchDir))
|
|
110
|
+
return false;
|
|
111
|
+
try {
|
|
112
|
+
const files = fs.readdirSync(searchDir);
|
|
113
|
+
const regex = new RegExp("^" + pattern.replace(/\*/g, ".*").replace(/\./g, "\\.") + "$");
|
|
114
|
+
return files.some((f) => regex.test(f));
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return fs.existsSync(path.join(cwd, filename));
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Check package.json for frontend/backend dependencies
|
|
124
|
+
*/
|
|
125
|
+
function checkPackageJson(cwd) {
|
|
126
|
+
const packageJsonPath = path.join(cwd, "package.json");
|
|
127
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
128
|
+
return { hasFrontend: false, hasBackend: false };
|
|
129
|
+
}
|
|
130
|
+
try {
|
|
131
|
+
const content = fs.readFileSync(packageJsonPath, "utf-8");
|
|
132
|
+
const pkg = JSON.parse(content);
|
|
133
|
+
const allDeps = {
|
|
134
|
+
...pkg.dependencies,
|
|
135
|
+
...pkg.devDependencies,
|
|
136
|
+
};
|
|
137
|
+
const depNames = Object.keys(allDeps ?? {});
|
|
138
|
+
const hasFrontend = FRONTEND_DEPS.some((dep) => depNames.includes(dep));
|
|
139
|
+
const hasBackend = BACKEND_DEPS.some((dep) => depNames.includes(dep));
|
|
140
|
+
return { hasFrontend, hasBackend };
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
return { hasFrontend: false, hasBackend: false };
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Detect project type by analyzing project files
|
|
148
|
+
*
|
|
149
|
+
* @param cwd - Current working directory to analyze
|
|
150
|
+
* @returns Detected project type
|
|
151
|
+
*/
|
|
152
|
+
export function detectProjectType(cwd) {
|
|
153
|
+
// Check for file indicators
|
|
154
|
+
const hasFrontendFiles = FRONTEND_INDICATORS.some((f) => fileExists(cwd, f));
|
|
155
|
+
const hasBackendFiles = BACKEND_INDICATORS.some((f) => fileExists(cwd, f));
|
|
156
|
+
// Check package.json dependencies
|
|
157
|
+
const { hasFrontend: hasFrontendDeps, hasBackend: hasBackendDeps } = checkPackageJson(cwd);
|
|
158
|
+
const isFrontend = hasFrontendFiles || hasFrontendDeps;
|
|
159
|
+
const isBackend = hasBackendFiles || hasBackendDeps;
|
|
160
|
+
if (isFrontend && isBackend) {
|
|
161
|
+
return "fullstack";
|
|
162
|
+
}
|
|
163
|
+
else if (isFrontend) {
|
|
164
|
+
return "frontend";
|
|
165
|
+
}
|
|
166
|
+
else if (isBackend) {
|
|
167
|
+
return "backend";
|
|
168
|
+
}
|
|
169
|
+
return "unknown";
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Get human-readable description of project type
|
|
173
|
+
*/
|
|
174
|
+
export function getProjectTypeDescription(type) {
|
|
175
|
+
switch (type) {
|
|
176
|
+
case "frontend":
|
|
177
|
+
return "Frontend project (UI/client-side)";
|
|
178
|
+
case "backend":
|
|
179
|
+
return "Backend project (server-side/API)";
|
|
180
|
+
case "fullstack":
|
|
181
|
+
return "Fullstack project (frontend + backend)";
|
|
182
|
+
case "unknown":
|
|
183
|
+
return "Unknown project type (defaults to fullstack)";
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Sanitize a package name for use as a directory name.
|
|
188
|
+
* Strips npm scope prefix (@scope/) so "@zhubao/desktop" becomes "desktop".
|
|
189
|
+
*/
|
|
190
|
+
export function sanitizePkgName(name) {
|
|
191
|
+
return name.replace(/^@[^/]+\//, "");
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Normalize a package path: strip ./ prefix, trailing /, unify separators.
|
|
195
|
+
*/
|
|
196
|
+
function normalizePkgPath(p) {
|
|
197
|
+
return p.replace(/\\/g, "/").replace(/^\.\//, "").replace(/\/+$/, "");
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Check if a relative path is an existing directory.
|
|
201
|
+
*/
|
|
202
|
+
function dirExists(cwd, relPath) {
|
|
203
|
+
try {
|
|
204
|
+
return fs.statSync(path.join(cwd, relPath)).isDirectory();
|
|
205
|
+
}
|
|
206
|
+
catch {
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
// --- Glob expansion for workspace patterns ---
|
|
211
|
+
/**
|
|
212
|
+
* Expand workspace glob patterns (e.g. "packages/*") into actual directory paths.
|
|
213
|
+
* Supports ! prefix for exclusion patterns.
|
|
214
|
+
*/
|
|
215
|
+
function expandWorkspaceGlobs(cwd, patterns) {
|
|
216
|
+
const included = [];
|
|
217
|
+
const excluded = new Set();
|
|
218
|
+
for (const raw of patterns) {
|
|
219
|
+
const isExclude = raw.startsWith("!");
|
|
220
|
+
const pattern = normalizePkgPath(isExclude ? raw.slice(1) : raw);
|
|
221
|
+
const dirs = pattern.includes("*")
|
|
222
|
+
? matchGlobSegments(cwd, pattern.split("/"), 0, "")
|
|
223
|
+
: dirExists(cwd, pattern)
|
|
224
|
+
? [pattern]
|
|
225
|
+
: [];
|
|
226
|
+
for (const d of dirs) {
|
|
227
|
+
if (isExclude)
|
|
228
|
+
excluded.add(d);
|
|
229
|
+
else
|
|
230
|
+
included.push(d);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return included.filter((p) => !excluded.has(p));
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Recursively match glob segments against the filesystem.
|
|
237
|
+
* Handles * as a single-level directory wildcard.
|
|
238
|
+
*/
|
|
239
|
+
function matchGlobSegments(cwd, segments, index, current) {
|
|
240
|
+
if (index >= segments.length) {
|
|
241
|
+
return dirExists(cwd, current) ? [current] : [];
|
|
242
|
+
}
|
|
243
|
+
const seg = segments[index];
|
|
244
|
+
if (seg !== "*") {
|
|
245
|
+
const next = current ? `${current}/${seg}` : seg;
|
|
246
|
+
return matchGlobSegments(cwd, segments, index + 1, next);
|
|
247
|
+
}
|
|
248
|
+
// Wildcard: match all direct subdirectories
|
|
249
|
+
const dir = current ? path.join(cwd, current) : cwd;
|
|
250
|
+
try {
|
|
251
|
+
return fs
|
|
252
|
+
.readdirSync(dir, { withFileTypes: true })
|
|
253
|
+
.filter((e) => e.isDirectory() && !e.name.startsWith("."))
|
|
254
|
+
.flatMap((e) => {
|
|
255
|
+
const next = current ? `${current}/${e.name}` : e.name;
|
|
256
|
+
return matchGlobSegments(cwd, segments, index + 1, next);
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
catch {
|
|
260
|
+
return [];
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
// --- Package name reading ---
|
|
264
|
+
/**
|
|
265
|
+
* Read a package name from various config files in the package directory.
|
|
266
|
+
* Falls back to directory name.
|
|
267
|
+
*/
|
|
268
|
+
function readPackageName(cwd, pkgPath) {
|
|
269
|
+
const absPath = path.join(cwd, pkgPath);
|
|
270
|
+
// package.json
|
|
271
|
+
try {
|
|
272
|
+
const pjson = JSON.parse(fs.readFileSync(path.join(absPath, "package.json"), "utf-8"));
|
|
273
|
+
if (pjson.name)
|
|
274
|
+
return pjson.name;
|
|
275
|
+
}
|
|
276
|
+
catch {
|
|
277
|
+
/* continue */
|
|
278
|
+
}
|
|
279
|
+
// Cargo.toml [package] name
|
|
280
|
+
try {
|
|
281
|
+
const cargo = fs.readFileSync(path.join(absPath, "Cargo.toml"), "utf-8");
|
|
282
|
+
const match = cargo.match(/\[package\][\s\S]*?name\s*=\s*"([^"]+)"/);
|
|
283
|
+
if (match)
|
|
284
|
+
return match[1];
|
|
285
|
+
}
|
|
286
|
+
catch {
|
|
287
|
+
/* continue */
|
|
288
|
+
}
|
|
289
|
+
// go.mod module name
|
|
290
|
+
try {
|
|
291
|
+
const gomod = fs.readFileSync(path.join(absPath, "go.mod"), "utf-8");
|
|
292
|
+
const match = gomod.match(/^module\s+(\S+)/m);
|
|
293
|
+
if (match)
|
|
294
|
+
return match[1].split("/").pop() ?? path.basename(pkgPath);
|
|
295
|
+
}
|
|
296
|
+
catch {
|
|
297
|
+
/* continue */
|
|
298
|
+
}
|
|
299
|
+
// pyproject.toml [project] name
|
|
300
|
+
try {
|
|
301
|
+
const pyproj = fs.readFileSync(path.join(absPath, "pyproject.toml"), "utf-8");
|
|
302
|
+
const match = pyproj.match(/\[project\][\s\S]*?name\s*=\s*"([^"]+)"/);
|
|
303
|
+
if (match)
|
|
304
|
+
return match[1];
|
|
305
|
+
}
|
|
306
|
+
catch {
|
|
307
|
+
/* continue */
|
|
308
|
+
}
|
|
309
|
+
return path.basename(pkgPath);
|
|
310
|
+
}
|
|
311
|
+
// --- Workspace format parsers ---
|
|
312
|
+
/** Parse pnpm-workspace.yaml packages list */
|
|
313
|
+
function parsePnpmWorkspace(cwd) {
|
|
314
|
+
try {
|
|
315
|
+
const content = fs.readFileSync(path.join(cwd, "pnpm-workspace.yaml"), "utf-8");
|
|
316
|
+
const patterns = [];
|
|
317
|
+
let inPackages = false;
|
|
318
|
+
for (const line of content.split("\n")) {
|
|
319
|
+
const trimmed = line.trim();
|
|
320
|
+
if (/^packages\s*:/.test(trimmed)) {
|
|
321
|
+
inPackages = true;
|
|
322
|
+
continue;
|
|
323
|
+
}
|
|
324
|
+
if (inPackages) {
|
|
325
|
+
if (trimmed.startsWith("- ")) {
|
|
326
|
+
patterns.push(trimmed
|
|
327
|
+
.slice(2)
|
|
328
|
+
.trim()
|
|
329
|
+
.replace(/^['"]|['"]$/g, ""));
|
|
330
|
+
}
|
|
331
|
+
else if (trimmed && !trimmed.startsWith("#")) {
|
|
332
|
+
break;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
return patterns.length > 0 ? patterns : null;
|
|
337
|
+
}
|
|
338
|
+
catch {
|
|
339
|
+
return null;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
/** Parse package.json workspaces (array or yarn v1 object form) */
|
|
343
|
+
function parseNpmWorkspaces(cwd) {
|
|
344
|
+
try {
|
|
345
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(cwd, "package.json"), "utf-8"));
|
|
346
|
+
const ws = pkg.workspaces;
|
|
347
|
+
if (!ws)
|
|
348
|
+
return null;
|
|
349
|
+
if (Array.isArray(ws))
|
|
350
|
+
return ws;
|
|
351
|
+
if (ws.packages && Array.isArray(ws.packages))
|
|
352
|
+
return ws.packages;
|
|
353
|
+
return null;
|
|
354
|
+
}
|
|
355
|
+
catch {
|
|
356
|
+
return null;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Parse a TOML inline array from a specific section.
|
|
361
|
+
* Handles both single-line and multi-line arrays.
|
|
362
|
+
*/
|
|
363
|
+
function parseTomlArray(content, key, sectionHeader) {
|
|
364
|
+
const sectionIdx = content.indexOf(sectionHeader);
|
|
365
|
+
if (sectionIdx === -1)
|
|
366
|
+
return null;
|
|
367
|
+
const afterSection = content.slice(sectionIdx + sectionHeader.length);
|
|
368
|
+
const nextSection = afterSection.search(/^\[[^[]/m);
|
|
369
|
+
const sectionContent = nextSection === -1 ? afterSection : afterSection.slice(0, nextSection);
|
|
370
|
+
const keyPattern = new RegExp(`${key}\\s*=\\s*\\[`);
|
|
371
|
+
const keyMatch = sectionContent.match(keyPattern);
|
|
372
|
+
if (keyMatch?.index === undefined)
|
|
373
|
+
return null;
|
|
374
|
+
const startIdx = keyMatch.index + keyMatch[0].length;
|
|
375
|
+
const endIdx = sectionContent.indexOf("]", startIdx);
|
|
376
|
+
if (endIdx === -1)
|
|
377
|
+
return null;
|
|
378
|
+
return sectionContent
|
|
379
|
+
.slice(startIdx, endIdx)
|
|
380
|
+
.split(/[,\n]/)
|
|
381
|
+
.map((s) => s.trim().replace(/^["']|["']$/g, ""))
|
|
382
|
+
.filter((s) => s && !s.startsWith("#"));
|
|
383
|
+
}
|
|
384
|
+
/** Parse Cargo.toml workspace members and exclude */
|
|
385
|
+
function parseCargoWorkspace(cwd) {
|
|
386
|
+
try {
|
|
387
|
+
const content = fs.readFileSync(path.join(cwd, "Cargo.toml"), "utf-8");
|
|
388
|
+
if (!/^\[workspace\]\s*$/m.test(content))
|
|
389
|
+
return null;
|
|
390
|
+
const members = parseTomlArray(content, "members", "[workspace]");
|
|
391
|
+
if (!members)
|
|
392
|
+
return null;
|
|
393
|
+
const exclude = parseTomlArray(content, "exclude", "[workspace]") ?? [];
|
|
394
|
+
return { members, exclude };
|
|
395
|
+
}
|
|
396
|
+
catch {
|
|
397
|
+
return null;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
/** Parse go.work use directives (block and single-line forms) */
|
|
401
|
+
function parseGoWork(cwd) {
|
|
402
|
+
try {
|
|
403
|
+
const content = fs.readFileSync(path.join(cwd, "go.work"), "utf-8");
|
|
404
|
+
const paths = [];
|
|
405
|
+
// Block form: use ( ... )
|
|
406
|
+
const blockMatch = content.match(/use\s*\(([\s\S]*?)\)/);
|
|
407
|
+
if (blockMatch) {
|
|
408
|
+
for (const line of blockMatch[1].split("\n")) {
|
|
409
|
+
const trimmed = line.trim();
|
|
410
|
+
if (trimmed && !trimmed.startsWith("//")) {
|
|
411
|
+
paths.push(trimmed);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
// Single-line form: use ./path
|
|
416
|
+
for (const match of content.matchAll(/^use\s+(\S+)\s*$/gm)) {
|
|
417
|
+
if (!match[1].startsWith("(")) {
|
|
418
|
+
paths.push(match[1]);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
return paths.length > 0 ? paths : null;
|
|
422
|
+
}
|
|
423
|
+
catch {
|
|
424
|
+
return null;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
/** Parse pyproject.toml [tool.uv.workspace] members */
|
|
428
|
+
function parseUvWorkspace(cwd) {
|
|
429
|
+
try {
|
|
430
|
+
const content = fs.readFileSync(path.join(cwd, "pyproject.toml"), "utf-8");
|
|
431
|
+
if (!content.includes("[tool.uv.workspace]"))
|
|
432
|
+
return null;
|
|
433
|
+
return parseTomlArray(content, "members", "[tool.uv.workspace]");
|
|
434
|
+
}
|
|
435
|
+
catch {
|
|
436
|
+
return null;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* Scan for sibling/grandchild directories that contain their own `.git`
|
|
441
|
+
* (polyrepo / meta-repo layout: independent clones placed under one parent).
|
|
442
|
+
*
|
|
443
|
+
* Rules:
|
|
444
|
+
* - Scans up to 2 levels deep (immediate children + grandchildren).
|
|
445
|
+
* - When a `.git` is found at a path, that path is a candidate and we DO NOT
|
|
446
|
+
* descend into it (a package is atomic).
|
|
447
|
+
* - Filters out hidden dirs (starting with `.`) and common build/vendor dirs.
|
|
448
|
+
* - `.git` may be a directory OR a file (worktree gitlink form) — uses
|
|
449
|
+
* `fs.existsSync` without `isDirectory()` check.
|
|
450
|
+
* - Skips paths in `submodulePaths` to avoid double-counting.
|
|
451
|
+
* - Returns `null` if fewer than 2 candidates (a single sibling repo is just
|
|
452
|
+
* a misclick, not a polyrepo).
|
|
453
|
+
*/
|
|
454
|
+
const POLYREPO_IGNORED_DIRS = new Set([
|
|
455
|
+
"node_modules",
|
|
456
|
+
"target",
|
|
457
|
+
"dist",
|
|
458
|
+
"build",
|
|
459
|
+
"out",
|
|
460
|
+
"bin",
|
|
461
|
+
"obj",
|
|
462
|
+
"vendor",
|
|
463
|
+
"coverage",
|
|
464
|
+
"tmp",
|
|
465
|
+
"__pycache__",
|
|
466
|
+
]);
|
|
467
|
+
function parsePolyrepo(cwd, submodulePaths) {
|
|
468
|
+
const MAX_DEPTH = 2;
|
|
469
|
+
const found = [];
|
|
470
|
+
function isCandidateDir(name) {
|
|
471
|
+
if (name.startsWith("."))
|
|
472
|
+
return false;
|
|
473
|
+
if (POLYREPO_IGNORED_DIRS.has(name))
|
|
474
|
+
return false;
|
|
475
|
+
return true;
|
|
476
|
+
}
|
|
477
|
+
function scan(relDir, depth) {
|
|
478
|
+
if (depth >= MAX_DEPTH)
|
|
479
|
+
return;
|
|
480
|
+
const absDir = relDir ? path.join(cwd, relDir) : cwd;
|
|
481
|
+
let entries;
|
|
482
|
+
try {
|
|
483
|
+
entries = fs.readdirSync(absDir, { withFileTypes: true });
|
|
484
|
+
}
|
|
485
|
+
catch {
|
|
486
|
+
return;
|
|
487
|
+
}
|
|
488
|
+
for (const entry of entries) {
|
|
489
|
+
if (!entry.isDirectory())
|
|
490
|
+
continue;
|
|
491
|
+
if (!isCandidateDir(entry.name))
|
|
492
|
+
continue;
|
|
493
|
+
const childRel = relDir ? `${relDir}/${entry.name}` : entry.name;
|
|
494
|
+
const childAbs = path.join(cwd, childRel);
|
|
495
|
+
// `.git` may be a file (worktree gitlink) or a directory — accept either.
|
|
496
|
+
const hasGit = fs.existsSync(path.join(childAbs, ".git"));
|
|
497
|
+
if (hasGit) {
|
|
498
|
+
// Skip if already covered by a submodule entry (avoid double-counting).
|
|
499
|
+
if (!submodulePaths.has(childRel)) {
|
|
500
|
+
found.push(childRel);
|
|
501
|
+
}
|
|
502
|
+
// Do NOT descend into a repo directory — package is atomic.
|
|
503
|
+
continue;
|
|
504
|
+
}
|
|
505
|
+
scan(childRel, depth + 1);
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
scan("", 0);
|
|
509
|
+
return found.length >= 2 ? found : null;
|
|
510
|
+
}
|
|
511
|
+
/** Parse .gitmodules for submodule names and paths */
|
|
512
|
+
function parseGitmodules(cwd) {
|
|
513
|
+
try {
|
|
514
|
+
const content = fs.readFileSync(path.join(cwd, ".gitmodules"), "utf-8");
|
|
515
|
+
const modules = [];
|
|
516
|
+
let currentName = "";
|
|
517
|
+
for (const line of content.split("\n")) {
|
|
518
|
+
const trimmed = line.trim();
|
|
519
|
+
const headerMatch = trimmed.match(/^\[submodule\s+"([^"]+)"]/);
|
|
520
|
+
if (headerMatch) {
|
|
521
|
+
currentName = headerMatch[1];
|
|
522
|
+
continue;
|
|
523
|
+
}
|
|
524
|
+
const pathMatch = trimmed.match(/^path\s*=\s*(.+)/);
|
|
525
|
+
if (pathMatch && currentName) {
|
|
526
|
+
modules.push({ name: currentName, path: pathMatch[1].trim() });
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
return modules.length > 0 ? modules : null;
|
|
530
|
+
}
|
|
531
|
+
catch {
|
|
532
|
+
return null;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
// --- Main monorepo detection ---
|
|
536
|
+
/**
|
|
537
|
+
* Detect monorepo workspace configuration and enumerate packages.
|
|
538
|
+
*
|
|
539
|
+
* Checks workspace managers in priority order (pnpm → npm/yarn/bun → Cargo → Go → uv),
|
|
540
|
+
* merges results, and marks git submodules. Returns null if no monorepo detected.
|
|
541
|
+
*
|
|
542
|
+
* @param cwd - Repository root to analyze
|
|
543
|
+
* @returns Array of detected packages, null if not a monorepo, empty array if config exists but no packages found
|
|
544
|
+
*/
|
|
545
|
+
export function detectMonorepo(cwd) {
|
|
546
|
+
const packages = new Map();
|
|
547
|
+
let detected = false;
|
|
548
|
+
// 1. Parse .gitmodules first to build submodule path set
|
|
549
|
+
const submodulePaths = new Map();
|
|
550
|
+
const gitmodules = parseGitmodules(cwd);
|
|
551
|
+
if (gitmodules) {
|
|
552
|
+
detected = true;
|
|
553
|
+
for (const mod of gitmodules) {
|
|
554
|
+
const np = normalizePkgPath(mod.path);
|
|
555
|
+
if (np && np !== ".") {
|
|
556
|
+
submodulePaths.set(np, mod.name);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
const workspaceParsers = [
|
|
561
|
+
() => {
|
|
562
|
+
const p = parsePnpmWorkspace(cwd);
|
|
563
|
+
return p
|
|
564
|
+
? { dirs: expandWorkspaceGlobs(cwd, p), isGitRepo: false }
|
|
565
|
+
: null;
|
|
566
|
+
},
|
|
567
|
+
() => {
|
|
568
|
+
const p = parseNpmWorkspaces(cwd);
|
|
569
|
+
return p
|
|
570
|
+
? { dirs: expandWorkspaceGlobs(cwd, p), isGitRepo: false }
|
|
571
|
+
: null;
|
|
572
|
+
},
|
|
573
|
+
() => {
|
|
574
|
+
const r = parseCargoWorkspace(cwd);
|
|
575
|
+
if (!r)
|
|
576
|
+
return null;
|
|
577
|
+
const inc = expandWorkspaceGlobs(cwd, r.members);
|
|
578
|
+
const exc = new Set(expandWorkspaceGlobs(cwd, r.exclude));
|
|
579
|
+
return { dirs: inc.filter((p) => !exc.has(p)), isGitRepo: false };
|
|
580
|
+
},
|
|
581
|
+
() => {
|
|
582
|
+
const p = parseGoWork(cwd);
|
|
583
|
+
if (!p)
|
|
584
|
+
return null;
|
|
585
|
+
return {
|
|
586
|
+
dirs: p
|
|
587
|
+
.map(normalizePkgPath)
|
|
588
|
+
.filter((d) => d && d !== "." && dirExists(cwd, d)),
|
|
589
|
+
isGitRepo: false,
|
|
590
|
+
};
|
|
591
|
+
},
|
|
592
|
+
() => {
|
|
593
|
+
const p = parseUvWorkspace(cwd);
|
|
594
|
+
return p
|
|
595
|
+
? { dirs: expandWorkspaceGlobs(cwd, p), isGitRepo: false }
|
|
596
|
+
: null;
|
|
597
|
+
},
|
|
598
|
+
];
|
|
599
|
+
let workspaceMatched = false;
|
|
600
|
+
for (const parse of workspaceParsers) {
|
|
601
|
+
const result = parse();
|
|
602
|
+
if (!result)
|
|
603
|
+
continue;
|
|
604
|
+
workspaceMatched = true;
|
|
605
|
+
detected = true;
|
|
606
|
+
for (const dir of result.dirs) {
|
|
607
|
+
const np = normalizePkgPath(dir);
|
|
608
|
+
if (!np || np === ".")
|
|
609
|
+
continue;
|
|
610
|
+
if (packages.has(np))
|
|
611
|
+
continue;
|
|
612
|
+
packages.set(np, {
|
|
613
|
+
name: readPackageName(cwd, np),
|
|
614
|
+
path: np,
|
|
615
|
+
type: dirExists(cwd, np)
|
|
616
|
+
? detectProjectType(path.join(cwd, np))
|
|
617
|
+
: "unknown",
|
|
618
|
+
isSubmodule: submodulePaths.has(np),
|
|
619
|
+
isGitRepo: result.isGitRepo,
|
|
620
|
+
});
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
// 3. Add submodule-only packages not already covered by workspace managers
|
|
624
|
+
for (const [np, name] of submodulePaths) {
|
|
625
|
+
if (packages.has(np))
|
|
626
|
+
continue;
|
|
627
|
+
packages.set(np, {
|
|
628
|
+
name,
|
|
629
|
+
path: np,
|
|
630
|
+
type: dirExists(cwd, np)
|
|
631
|
+
? detectProjectType(path.join(cwd, np))
|
|
632
|
+
: "unknown",
|
|
633
|
+
isSubmodule: true,
|
|
634
|
+
isGitRepo: false,
|
|
635
|
+
});
|
|
636
|
+
}
|
|
637
|
+
// 4. Polyrepo fallback: only fires if NO workspace parser matched AND no
|
|
638
|
+
// submodules were found. Sibling/grandchild .git directories indicate
|
|
639
|
+
// independent repos placed under one parent (meta-repo / polyrepo layout).
|
|
640
|
+
if (!workspaceMatched && submodulePaths.size === 0) {
|
|
641
|
+
const polyDirs = parsePolyrepo(cwd, new Set(submodulePaths.keys()));
|
|
642
|
+
if (polyDirs) {
|
|
643
|
+
detected = true;
|
|
644
|
+
for (const dir of polyDirs) {
|
|
645
|
+
const np = normalizePkgPath(dir);
|
|
646
|
+
if (!np || np === ".")
|
|
647
|
+
continue;
|
|
648
|
+
if (packages.has(np))
|
|
649
|
+
continue;
|
|
650
|
+
packages.set(np, {
|
|
651
|
+
name: readPackageName(cwd, np),
|
|
652
|
+
path: np,
|
|
653
|
+
type: dirExists(cwd, np)
|
|
654
|
+
? detectProjectType(path.join(cwd, np))
|
|
655
|
+
: "unknown",
|
|
656
|
+
isSubmodule: false,
|
|
657
|
+
isGitRepo: true,
|
|
658
|
+
});
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
if (!detected)
|
|
663
|
+
return null;
|
|
664
|
+
return Array.from(packages.values());
|
|
665
|
+
}
|
|
666
|
+
//# sourceMappingURL=project-detector.js.map
|