@bonesofspring/ai-rules 0.2.2 → 0.2.4
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/CHANGELOG.md +65 -0
- package/README.md +27 -4
- package/bin/cli.js +285 -72
- package/package.json +3 -2
- package/presets/claude/ios-swift/CLAUDE.md +28 -20
- package/presets/claude/ios-swift/MCP.md +14 -0
- package/presets/claude/ios-swift/README.md +18 -15
- package/presets/claude/ios-swift/agents/README.md +55 -0
- package/presets/claude/ios-swift/agents/accessibility-reviewer.md +67 -0
- package/presets/claude/ios-swift/agents/api-contract-reviewer.md +72 -0
- package/presets/claude/ios-swift/agents/build-verifier.md +64 -0
- package/presets/claude/ios-swift/agents/ci-investigator.md +73 -0
- package/presets/claude/ios-swift/agents/code-reviewer.md +75 -0
- package/presets/claude/ios-swift/agents/debugger.md +72 -0
- package/presets/claude/ios-swift/agents/feature-developer.md +35 -0
- package/presets/claude/ios-swift/agents/migration-specialist.md +73 -0
- package/presets/claude/ios-swift/agents/performance-auditor.md +72 -0
- package/presets/claude/ios-swift/agents/qa-tester.md +65 -0
- package/presets/claude/ios-swift/agents/security-reviewer.md +69 -0
- package/presets/claude/ios-swift/agents/solution-architect.md +17 -0
- package/presets/claude/ios-swift/agents/task-analyst.md +25 -0
- package/presets/claude/ios-swift/agents/task-router.md +62 -0
- package/presets/claude/ios-swift/agents/tech-writer.md +63 -0
- package/presets/claude/ios-swift/agents/unit-test-generator.md +54 -0
- package/presets/claude/ios-swift/agents/unit-test-healer.md +53 -0
- package/presets/claude/ios-swift/agents/unit-test-planner.md +64 -0
- package/presets/claude/ios-swift/agents/xcuitest-test-generator.md +47 -0
- package/presets/claude/ios-swift/agents/xcuitest-test-healer.md +47 -0
- package/presets/claude/ios-swift/agents/xcuitest-test-planner.md +67 -0
- package/presets/claude/ios-swift/commands/README.md +12 -2
- package/presets/claude/ios-swift/commands/feature-continue.md +51 -0
- package/presets/claude/ios-swift/commands/feature-start.md +30 -0
- package/presets/claude/ios-swift/commands/task-continue.md +49 -0
- package/presets/claude/ios-swift/commands/task.md +50 -0
- package/presets/claude/ios-swift/commands/technical-retro.md +58 -0
- package/presets/claude/ios-swift/hooks/README.md +10 -0
- package/presets/claude/ios-swift/hooks/chain-team-phases.sh +382 -0
- package/presets/claude/ios-swift/hooks/guard-shell-command.sh +79 -0
- package/presets/claude/ios-swift/mcp.json +12 -0
- package/presets/claude/ios-swift/rules/README.md +25 -14
- package/presets/claude/ios-swift/rules/api-and-data/README.md +2 -1
- package/presets/claude/ios-swift/rules/api-and-data/networking.md +2 -2
- package/presets/claude/ios-swift/rules/api-and-data/persistence.md +30 -0
- package/presets/claude/ios-swift/rules/architecture/README.md +3 -1
- package/presets/claude/ios-swift/rules/architecture/feature-delivery.md +10 -2
- package/presets/claude/ios-swift/rules/architecture/module-public-api.md +25 -0
- package/presets/claude/ios-swift/rules/architecture/reference-features.md +50 -0
- package/presets/claude/ios-swift/rules/stack/ios-app-core.md +2 -1
- package/presets/claude/ios-swift/rules/testing/ui.md +2 -0
- package/presets/claude/ios-swift/rules/tooling-and-review/README.md +6 -1
- package/presets/claude/ios-swift/rules/tooling-and-review/agent-team-intake.md +18 -0
- package/presets/claude/ios-swift/rules/tooling-and-review/agent-team-orchestrator.md +47 -0
- package/presets/claude/ios-swift/rules/tooling-and-review/code-review.md +5 -0
- package/presets/claude/ios-swift/rules/tooling-and-review/post-change-build.md +5 -0
- package/presets/claude/ios-swift/rules/tooling-and-review/security-ios.md +36 -0
- package/presets/claude/ios-swift/rules/tooling-and-review/technical-retro.md +14 -0
- package/presets/claude/ios-swift/rules/tooling-and-review/xcode-tooling.md +24 -0
- package/presets/claude/ios-swift/rules/ui-and-accessibility/README.md +2 -1
- package/presets/claude/ios-swift/rules/ui-and-accessibility/navigation.md +28 -0
- package/presets/claude/ios-swift/skills/README.md +13 -0
- package/presets/claude/ios-swift/skills/ci-investigation/SKILL.md +39 -0
- package/presets/claude/ios-swift/skills/code-review/SKILL.md +27 -0
- package/presets/claude/ios-swift/skills/debug-investigation/SKILL.md +30 -0
- package/presets/claude/ios-swift/skills/feature-delivery/SKILL.md +27 -0
- package/presets/claude/ios-swift/skills/technical-retro/SKILL.md +10 -0
- package/presets/claude/ios-swift/skills/unit-testing/SKILL.md +32 -0
- package/presets/claude/ios-swift/skills/xcuitest-e2e/SKILL.md +33 -0
- package/presets/claude/ios-swift/team/README.md +27 -0
- package/presets/claude/ios-swift/team/fixtures/bugfix-standard.json +33 -0
- package/presets/claude/ios-swift/team/fixtures/feature-full.json +48 -0
- package/presets/claude/ios-swift/team/fixtures/feature-light.json +36 -0
- package/presets/claude/next/CLAUDE.md +29 -5
- package/presets/claude/next/MCP.md +16 -0
- package/presets/claude/next/README.md +12 -0
- package/presets/claude/next/agents/README.md +155 -1
- package/presets/claude/next/agents/accessibility-reviewer.md +65 -0
- package/presets/claude/next/agents/api-contract-reviewer.md +69 -0
- package/presets/claude/next/agents/build-verifier.md +64 -0
- package/presets/claude/next/agents/ci-investigator.md +62 -0
- package/presets/claude/next/agents/code-reviewer.md +63 -0
- package/presets/claude/next/agents/debugger.md +63 -0
- package/presets/claude/next/agents/feature-developer.md +27 -0
- package/presets/claude/next/agents/migration-specialist.md +69 -0
- package/presets/claude/next/agents/performance-auditor.md +68 -0
- package/presets/claude/next/agents/qa-tester.md +56 -0
- package/presets/claude/next/agents/security-reviewer.md +64 -0
- package/presets/claude/next/agents/solution-architect.md +70 -0
- package/presets/claude/next/agents/task-analyst.md +111 -0
- package/presets/claude/next/agents/task-router.md +94 -0
- package/presets/claude/next/agents/tech-writer.md +61 -0
- package/presets/claude/next/agents/unit-test-generator.md +37 -0
- package/presets/claude/next/agents/unit-test-healer.md +38 -0
- package/presets/claude/next/agents/unit-test-planner.md +62 -0
- package/presets/claude/next/commands/README.md +10 -2
- package/presets/claude/next/commands/feature-continue.md +51 -0
- package/presets/claude/next/commands/feature-start.md +30 -0
- package/presets/claude/next/commands/task-continue.md +49 -0
- package/presets/claude/next/commands/task.md +50 -0
- package/presets/claude/next/commands/technical-retro.md +58 -0
- package/presets/claude/next/hooks/README.md +5 -2
- package/presets/claude/next/hooks/chain-team-phases.sh +380 -0
- package/presets/claude/next/hooks/guard-shell-command.sh +77 -0
- package/presets/claude/next/mcp.json +20 -0
- package/presets/claude/next/rules/README.md +42 -11
- package/presets/claude/next/rules/api-and-data/README.md +7 -1
- package/presets/claude/next/rules/api-and-data/api-services.md +57 -0
- package/presets/claude/next/rules/api-and-data/http-client.md +40 -0
- package/presets/claude/next/rules/api-and-data/store-rtk.md +65 -0
- package/presets/claude/next/rules/architecture/README.md +11 -2
- package/presets/claude/next/rules/architecture/architecture-boundaries-ui.md +15 -0
- package/presets/claude/next/rules/architecture/architecture-boundaries.md +75 -0
- package/presets/claude/next/rules/architecture/feature-delivery-workflow.md +79 -0
- package/presets/claude/next/rules/architecture/layer-barrel-exports.md +58 -0
- package/presets/claude/next/rules/architecture/public-imports.md +46 -0
- package/presets/claude/next/rules/architecture/reference-features.md +37 -0
- package/presets/claude/next/rules/stack/README.md +10 -1
- package/presets/claude/next/rules/stack/arrow-functions.md +45 -0
- package/presets/claude/next/rules/stack/navigation-router-ui.md +15 -0
- package/presets/claude/next/rules/stack/navigation-router.md +64 -0
- package/presets/claude/next/rules/stack/next-app-core.md +33 -0
- package/presets/claude/next/rules/stack/next-app-router.md +36 -0
- package/presets/claude/next/rules/stack/no-type-assertion.md +59 -0
- package/presets/claude/next/rules/stack/types-jsdoc.md +37 -0
- package/presets/claude/next/rules/testing/README.md +9 -1
- package/presets/claude/next/rules/testing/playwright-agents.md +74 -0
- package/presets/claude/next/rules/testing/tests-e2e-structure.md +52 -0
- package/presets/claude/next/rules/testing/tests-unit.md +66 -0
- package/presets/claude/next/rules/tooling-and-review/README.md +12 -1
- package/presets/claude/next/rules/tooling-and-review/agent-team-intake.md +15 -0
- package/presets/claude/next/rules/tooling-and-review/agent-team-orchestrator.md +145 -0
- package/presets/claude/next/rules/tooling-and-review/code-quality.md +42 -0
- package/presets/claude/next/rules/tooling-and-review/code-review-mr.md +30 -0
- package/presets/claude/next/rules/tooling-and-review/package-manager.md +11 -0
- package/presets/claude/next/rules/tooling-and-review/post-change-lint.md +44 -0
- package/presets/claude/next/rules/ui-and-accessibility/README.md +10 -1
- package/presets/claude/next/rules/ui-and-accessibility/css-property-order.md +14 -0
- package/presets/claude/next/rules/ui-and-accessibility/no-props-spread.md +57 -0
- package/presets/claude/next/rules/ui-and-accessibility/react-a11y-coding.md +37 -0
- package/presets/claude/next/rules/ui-and-accessibility/react-ui.md +91 -0
- package/presets/claude/next/skills/README.md +11 -1
- package/presets/claude/next/skills/ci-investigation/SKILL.md +36 -0
- package/presets/claude/next/skills/code-review/SKILL.md +26 -0
- package/presets/claude/next/skills/debug-investigation/SKILL.md +28 -0
- package/presets/claude/next/skills/feature-delivery/SKILL.md +15 -0
- package/presets/claude/next/skills/playwright-e2e/SKILL.md +31 -0
- package/presets/claude/next/skills/technical-retro/SKILL.md +40 -0
- package/presets/claude/next/skills/unit-testing/SKILL.md +32 -0
- package/presets/claude/next/team/README.md +105 -0
- package/presets/claude/next/team/fixtures/bugfix-standard.json +15 -0
- package/presets/claude/next/team/fixtures/feature-full.json +16 -0
- package/presets/claude/next/team/fixtures/feature-light.json +17 -0
- package/presets/claude/next/team/tasks/.gitkeep +1 -0
- package/presets/cursor/ios-swift/AGENTS.md +47 -0
- package/presets/cursor/ios-swift/BUGBOT.md +15 -0
- package/presets/cursor/ios-swift/MCP.md +16 -0
- package/presets/cursor/ios-swift/README.md +27 -7
- package/presets/cursor/ios-swift/agents/README.md +55 -0
- package/presets/cursor/ios-swift/agents/accessibility-reviewer.md +67 -0
- package/presets/cursor/ios-swift/agents/api-contract-reviewer.md +72 -0
- package/presets/cursor/ios-swift/agents/build-verifier.md +64 -0
- package/presets/cursor/ios-swift/agents/ci-investigator.md +73 -0
- package/presets/cursor/ios-swift/agents/code-reviewer.md +75 -0
- package/presets/cursor/ios-swift/agents/debugger.md +72 -0
- package/presets/cursor/ios-swift/agents/feature-developer.md +35 -0
- package/presets/cursor/ios-swift/agents/migration-specialist.md +73 -0
- package/presets/cursor/ios-swift/agents/performance-auditor.md +72 -0
- package/presets/cursor/ios-swift/agents/qa-tester.md +65 -0
- package/presets/cursor/ios-swift/agents/security-reviewer.md +69 -0
- package/presets/cursor/ios-swift/agents/solution-architect.md +17 -0
- package/presets/cursor/ios-swift/agents/task-analyst.md +25 -0
- package/presets/cursor/ios-swift/agents/task-router.md +62 -0
- package/presets/cursor/ios-swift/agents/tech-writer.md +63 -0
- package/presets/cursor/ios-swift/agents/unit-test-generator.md +54 -0
- package/presets/cursor/ios-swift/agents/unit-test-healer.md +53 -0
- package/presets/cursor/ios-swift/agents/unit-test-planner.md +64 -0
- package/presets/cursor/ios-swift/agents/xcuitest-test-generator.md +47 -0
- package/presets/cursor/ios-swift/agents/xcuitest-test-healer.md +47 -0
- package/presets/cursor/ios-swift/agents/xcuitest-test-planner.md +67 -0
- package/presets/cursor/ios-swift/commands/README.md +49 -1
- package/presets/cursor/ios-swift/commands/feature-continue.md +19 -0
- package/presets/cursor/ios-swift/commands/feature-start.md +33 -0
- package/presets/cursor/ios-swift/commands/task-continue.md +49 -0
- package/presets/cursor/ios-swift/commands/task.md +50 -0
- package/presets/cursor/ios-swift/commands/technical-retro.md +81 -0
- package/presets/cursor/ios-swift/hooks/README.md +8 -0
- package/presets/cursor/ios-swift/hooks/chain-team-phases.sh +382 -0
- package/presets/cursor/ios-swift/hooks/guard-shell-command.sh +79 -0
- package/presets/cursor/ios-swift/hooks.json +17 -0
- package/presets/cursor/ios-swift/mcp.json +11 -0
- package/presets/cursor/ios-swift/rules/README.md +45 -13
- package/presets/cursor/ios-swift/rules/agent-team-intake.mdc +16 -0
- package/presets/cursor/ios-swift/rules/agent-team-orchestrator.mdc +85 -0
- package/presets/cursor/ios-swift/rules/code-review-mr.mdc +1 -0
- package/presets/cursor/ios-swift/rules/feature-delivery-workflow.mdc +1 -1
- package/presets/cursor/ios-swift/rules/ios-app-core.mdc +2 -1
- package/presets/cursor/ios-swift/rules/module-public-api.mdc +26 -0
- package/presets/cursor/ios-swift/rules/navigation-coordinators.mdc +29 -0
- package/presets/cursor/ios-swift/rules/networking-services.mdc +2 -2
- package/presets/cursor/ios-swift/rules/persistence-data.mdc +31 -0
- package/presets/cursor/ios-swift/rules/reference-features.mdc +53 -0
- package/presets/cursor/ios-swift/rules/security-ios.mdc +35 -0
- package/presets/cursor/ios-swift/rules/technical-retro.mdc +12 -0
- package/presets/cursor/ios-swift/rules/tests-ui.mdc +1 -0
- package/presets/cursor/ios-swift/rules/xcode-tooling.mdc +20 -0
- package/presets/cursor/ios-swift/skills/README.md +13 -0
- package/presets/cursor/ios-swift/skills/ci-investigation/SKILL.md +39 -0
- package/presets/cursor/ios-swift/skills/code-review/SKILL.md +27 -0
- package/presets/cursor/ios-swift/skills/debug-investigation/SKILL.md +30 -0
- package/presets/cursor/ios-swift/skills/feature-delivery/SKILL.md +27 -0
- package/presets/cursor/ios-swift/skills/technical-retro/SKILL.md +10 -0
- package/presets/cursor/ios-swift/skills/unit-testing/SKILL.md +32 -0
- package/presets/cursor/ios-swift/skills/xcuitest-e2e/SKILL.md +33 -0
- package/presets/cursor/ios-swift/team/README.md +31 -0
- package/presets/cursor/ios-swift/team/fixtures/bugfix-standard.json +33 -0
- package/presets/cursor/ios-swift/team/fixtures/feature-full.json +48 -0
- package/presets/cursor/ios-swift/team/fixtures/feature-light.json +36 -0
- package/presets/cursor/next/AGENTS.md +36 -0
- package/presets/cursor/next/BUGBOT.md +14 -0
- package/presets/cursor/next/MCP.md +16 -0
- package/presets/cursor/next/agents/README.md +165 -0
- package/presets/cursor/next/agents/accessibility-reviewer.md +67 -0
- package/presets/cursor/next/agents/api-contract-reviewer.md +71 -0
- package/presets/cursor/next/agents/build-verifier.md +66 -0
- package/presets/cursor/next/agents/ci-investigator.md +64 -0
- package/presets/cursor/next/agents/code-reviewer.md +64 -0
- package/presets/cursor/next/agents/debugger.md +64 -0
- package/presets/cursor/next/agents/feature-developer.md +28 -0
- package/presets/cursor/next/agents/migration-specialist.md +71 -0
- package/presets/cursor/next/agents/performance-auditor.md +70 -0
- package/presets/cursor/next/agents/playwright-test-generator.md +27 -0
- package/presets/cursor/next/agents/playwright-test-healer.md +27 -0
- package/presets/cursor/next/agents/playwright-test-planner.md +28 -0
- package/presets/cursor/next/agents/qa-tester.md +58 -0
- package/presets/cursor/next/agents/security-reviewer.md +66 -0
- package/presets/cursor/next/agents/solution-architect.md +71 -0
- package/presets/cursor/next/agents/task-analyst.md +112 -0
- package/presets/cursor/next/agents/task-router.md +95 -0
- package/presets/cursor/next/agents/tech-writer.md +62 -0
- package/presets/cursor/next/agents/unit-test-generator.md +39 -0
- package/presets/cursor/next/agents/unit-test-healer.md +40 -0
- package/presets/cursor/next/agents/unit-test-planner.md +64 -0
- package/presets/cursor/next/commands/README.md +49 -1
- package/presets/cursor/next/commands/feature-continue.md +19 -0
- package/presets/cursor/next/commands/feature-start.md +33 -0
- package/presets/cursor/next/commands/task-continue.md +49 -0
- package/presets/cursor/next/commands/task.md +50 -0
- package/presets/cursor/next/commands/technical-retro.md +81 -0
- package/presets/cursor/next/hooks/README.md +8 -0
- package/presets/cursor/next/hooks/chain-team-phases.sh +380 -0
- package/presets/cursor/next/hooks/guard-shell-command.sh +77 -0
- package/presets/cursor/next/hooks.json +17 -0
- package/presets/cursor/next/mcp.json +19 -0
- package/presets/cursor/next/rules/README.md +67 -0
- package/presets/cursor/next/rules/agent-team-intake.mdc +14 -0
- package/presets/cursor/next/rules/agent-team-orchestrator.mdc +147 -0
- package/presets/cursor/next/rules/api-services.mdc +12 -10
- package/presets/cursor/next/rules/architecture-boundaries-ui.mdc +15 -0
- package/presets/cursor/next/rules/architecture-boundaries.mdc +31 -12
- package/presets/cursor/next/rules/arrow-functions.mdc +46 -0
- package/presets/cursor/next/rules/code-quality-and-refactoring.mdc +5 -4
- package/presets/cursor/next/rules/code-review-mr.mdc +21 -40
- package/presets/cursor/next/rules/css-property-order-stylelint.mdc +16 -0
- package/presets/cursor/next/rules/feature-delivery-workflow.mdc +76 -0
- package/presets/cursor/next/rules/http-client.mdc +42 -0
- package/presets/cursor/next/rules/layer-barrel-exports.mdc +59 -0
- package/presets/cursor/next/rules/navigation-router-stack.mdc +62 -0
- package/presets/cursor/next/rules/navigation-router-ui.mdc +16 -0
- package/presets/cursor/next/rules/next-app-core.mdc +18 -61
- package/presets/cursor/next/rules/next-app-router.mdc +36 -0
- package/presets/cursor/next/rules/no-props-spread.mdc +27 -4
- package/presets/cursor/next/rules/no-type-assertion-as-import-export.mdc +60 -0
- package/presets/cursor/next/rules/package-manager.mdc +16 -0
- package/presets/cursor/next/rules/playwright-agents.mdc +2 -1
- package/presets/cursor/next/rules/post-change-lint.mdc +40 -0
- package/presets/cursor/next/rules/public-imports.mdc +48 -0
- package/presets/cursor/next/rules/react-a11y-coding.mdc +37 -0
- package/presets/cursor/next/rules/react-ui.mdc +33 -3
- package/presets/cursor/next/rules/reference-features.mdc +39 -0
- package/presets/cursor/next/rules/store-rtk.mdc +13 -6
- package/presets/cursor/next/rules/technical-retro.mdc +12 -0
- package/presets/cursor/next/rules/tests-unit.mdc +30 -10
- package/presets/cursor/next/rules/types-jsdoc.mdc +42 -0
- package/presets/cursor/next/skills/README.md +15 -0
- package/presets/cursor/next/skills/ci-investigation/SKILL.md +36 -0
- package/presets/cursor/next/skills/code-review/SKILL.md +26 -0
- package/presets/cursor/next/skills/debug-investigation/SKILL.md +28 -0
- package/presets/cursor/next/skills/feature-delivery/SKILL.md +15 -0
- package/presets/cursor/next/skills/playwright-e2e/SKILL.md +31 -0
- package/presets/cursor/next/skills/technical-retro/SKILL.md +40 -0
- package/presets/cursor/next/skills/unit-testing/SKILL.md +32 -0
- package/presets/cursor/next/team/README.md +109 -0
- package/presets/cursor/next/team/fixtures/bugfix-standard.json +15 -0
- package/presets/cursor/next/team/fixtures/feature-full.json +16 -0
- package/presets/cursor/next/team/fixtures/feature-light.json +17 -0
- package/presets/cursor/next/team/tasks/.gitkeep +0 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
### Breaking
|
|
6
|
+
|
|
7
|
+
- **Deprecated rule stubs removed** (Cursor + Claude `next`): `types-public-imports`, `api-public-imports`, `no-cross-component-styles-import` / `component-styles`. Use `public-imports` and `react-ui` instead.
|
|
8
|
+
- **`next` preset — post-change-lint no longer always-on:** Cursor `post-change-lint.mdc` and Claude twin are **requestable** (not session-start / `alwaysApply`). Load explicitly after code edits via skill `feature-delivery` or agent `build-verifier`. Session-start / alwaysApply is now **3** rules: `next-app-core`, `package-manager`, `code-quality-and-refactoring`. Workspace dogfood `.cursor/rules/post-change-lint.mdc` synced.
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **MCP configs in presets** (`next` + `ios-swift`, Cursor + Claude): `mcp.json` + `MCP.md`. Cursor → `.cursor/mcp.json`; Claude → project-root `.mcp.json`. **next:** Context7, Playwright, Chrome DevTools, Figma (remote). **ios-swift:** Context7 + Figma. CLI `init`/`clean` manage these paths.
|
|
13
|
+
- **Cursor + Claude `ios-swift` — full agent-team parity with `next`:** **21** agents (Playwright trio → `xcuitest-test-{planner,generator,healer}`), **7** skills (`xcuitest-e2e`), **5** slash commands, `hooks.json` + iOS-adapted `chain-team-phases.sh` (Cursor) / hook scripts + README (Claude), `team/fixtures/` ×3, `AGENTS.md` (Cursor) / thin `CLAUDE.md` (≤35 lines).
|
|
14
|
+
- **ios-swift rules:** agent-team intake/orchestrator, `xcode-tooling`, `reference-features`, domain rules (`navigation-coordinators`, `persistence-data`, `security-ios`, `module-public-api`), `technical-retro` alias; **21** rule topics (+ README). CLI init copies agents, hooks, skills, team, `AGENTS.md`.
|
|
15
|
+
- **ios-swift retro follow-ups:** `build-verifier` preset checks (chain ≠ next; ban Playwright/`lint:js` handoffs); enriched 16 priority agent prompts + 6 skills; dogfood checklist (5 scenarios) in `AGENTS.md` / `reference-features`; Cursor-only **`BUGBOT.md`** (iOS review priorities).
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- **Agent team slug bootstrap:** `/task` and `/feature-start` (Cursor + Claude, `next` + `ios-swift`) create `.cursor|claude/team/tasks/<slug>/` via **Write**, not Shell `mkdir` — avoids Cursor sandbox `Operation not permitted` (esp. macOS Desktop/Documents). Orchestrator + `team/README` + `task-router` document the rule.
|
|
20
|
+
- **Token model (ios-swift + next):** both presets use **3** alwaysApply / session-start rules (~77 / ~59 body lines). Post-change verification is **requestable** — ios: `post-change-build`; next: `post-change-lint`. Orchestrator, intake, code-review, feature-delivery, tooling rules load on-demand (`paths:` / description).
|
|
21
|
+
- Claude `next`: `agent-team-orchestrator` and `code-review-mr` use `paths:` (on-demand) — session-start matches the 3-rule budget above.
|
|
22
|
+
- Cursor `next` agents: all pipeline agents set **`readonly: false`** so they can write `.cursor/team/**`. Production/app restrictions remain in prompt bodies (Cursor `readonly: true` blocks all file writes, including team artifacts).
|
|
23
|
+
- **ios-swift:** `networking-services` HTTP-only (persistence split out); soft AC-19 for thin aliases (`agent-team-intake`, `technical-retro`); `feature-developer` requires stack-specific hook handoff forks.
|
|
24
|
+
|
|
25
|
+
### Notes
|
|
26
|
+
|
|
27
|
+
- **P2 optional (ios-swift):** Remaining polish: feature-delivery matrix enrichment, swift-conventions body cap. (`BUGBOT.md` shipped.)
|
|
28
|
+
|
|
29
|
+
## 0.2.2
|
|
30
|
+
|
|
31
|
+
### Breaking
|
|
32
|
+
|
|
33
|
+
- **`clean` is selective:** removes only CLI-managed paths (`rules`, `commands`, optional `agents`/`hooks`/`skills`/`team`, plus Cursor `hooks.json` / `BUGBOT.md` / `AGENTS.md`, Claude `CLAUDE.md`). Does **not** wipe the entire `.cursor/` or `.claude/` directory.
|
|
34
|
+
|
|
35
|
+
### Added
|
|
36
|
+
|
|
37
|
+
- Cursor `next`: `architecture-boundaries-ui.mdc`, `navigation-router-ui.mdc` (slim UI-edit rules); Claude equivalents under `architecture/` and `stack/`.
|
|
38
|
+
- Cursor/Claude `next`: `AGENTS.md` on Cursor init; team `fixtures/` for pipeline profiles; pipeline profiles (`full` / `standard` / `light`) in `task-router`.
|
|
39
|
+
- Claude `next`: `hooks/chain-team-phases.sh` feature parity with Cursor (tool paths only differ).
|
|
40
|
+
|
|
41
|
+
### Changed
|
|
42
|
+
|
|
43
|
+
- Narrower globs for full `architecture-boundaries` / `navigation-router(-stack)` vs UI slim rules; `layer-barrel-exports` → `index.ts`; styles colocation consolidated into `react-ui` (stubs remain).
|
|
44
|
+
- README documents `AGENTS.md` and selective `clean`.
|
|
45
|
+
|
|
46
|
+
## 0.2.0
|
|
47
|
+
|
|
48
|
+
### Breaking
|
|
49
|
+
|
|
50
|
+
- **Import rules merged:** `types-public-imports.mdc` and `api-public-imports.mdc` → **`public-imports.mdc`** (Claude: `architecture/public-imports.md`). Old filenames remain as deprecated stubs for one release cycle.
|
|
51
|
+
- **`feature-delivery-flow.mdc` removed** — content merged into `feature-delivery-workflow.mdc`.
|
|
52
|
+
- **`agent-team-intake`** no longer always-on (Cursor: `alwaysApply: false`; Claude: `paths:` on commands/team). Use orchestrator or `/task`.
|
|
53
|
+
|
|
54
|
+
### Changed
|
|
55
|
+
|
|
56
|
+
- Slimmed always-on rules: `next-app-core`, `code-quality-and-refactoring`, `post-change-lint`, `package-manager` (~9 KB baseline vs ~21 KB).
|
|
57
|
+
- Narrowed globs: `css-property-order-stylelint`, `no-type-assertion-as-import-export`, `reference-features`, `public-imports`.
|
|
58
|
+
- `css-property-order` stub — property list delegated to Stylelint `--fix`.
|
|
59
|
+
- Slimmed `task-router` agent; pipeline JSON examples moved to `agents/README.md`.
|
|
60
|
+
- Agents reference skills as SSOT; scoped lint for `feature-developer` when next step is `build-verifier`.
|
|
61
|
+
- Orchestrator: explicit fast-path when to skip pipeline.
|
|
62
|
+
|
|
63
|
+
## 0.1.42
|
|
64
|
+
|
|
65
|
+
Prior releases — see git history.
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @bonesofspring/ai-rules
|
|
2
2
|
|
|
3
|
-
Presets for Cursor and Claude Code: rules, commands, plus
|
|
3
|
+
Presets for Cursor and Claude Code: rules, commands, plus optional `agents`, `hooks`, `skills`, team artifacts, and MCP configs when the preset includes them. For Claude: `CLAUDE.md`. Install from npm into a project so you don’t have to copy files out of the repo by hand.
|
|
4
4
|
|
|
5
5
|
Node 18+.
|
|
6
6
|
|
|
@@ -13,9 +13,27 @@ npx @bonesofspring/ai-rules clean cursor
|
|
|
13
13
|
|
|
14
14
|
Global: `npm i -g @bonesofspring/ai-rules`, then `ai-rules ...`.
|
|
15
15
|
|
|
16
|
-
`init` merges into the current directory: dirs are created, matching files are **overwritten**. `--preset`
|
|
16
|
+
`init` merges into the **current working directory** (or `--cwd <dir>`): dirs are created, matching files are **overwritten**. `--preset` defaults to **`next`**. Supported forms:
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
```bash
|
|
19
|
+
npx @bonesofspring/ai-rules init cursor --preset next
|
|
20
|
+
npx @bonesofspring/ai-rules init cursor next
|
|
21
|
+
npx @bonesofspring/ai-rules init cursor # preset next by default
|
|
22
|
+
npx @bonesofspring/ai-rules cursor init --preset next
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
If `.cursor` does not appear, check the command output for errors and confirm you run init from the **target project root** (where the app lives), not from `node_modules`. Success ends with: `Done. .cursor installed at <absolute-path>`.
|
|
26
|
+
|
|
27
|
+
### `clean` (breaking vs older wipe behavior)
|
|
28
|
+
|
|
29
|
+
`clean cursor` / `clean claude` removes **only CLI-managed paths** — not the entire `.cursor/` or `.claude/` tree:
|
|
30
|
+
|
|
31
|
+
- `rules/`, `commands/`
|
|
32
|
+
- optional dirs when present: `agents/`, `hooks/`, `skills/`, `team/`
|
|
33
|
+
- Cursor root files: `hooks.json`, `BUGBOT.md`, `AGENTS.md`, `MCP.md`, `mcp.json`
|
|
34
|
+
- Claude: `CLAUDE.md`, `MCP.md` under `.claude/`; project `.mcp.json` at repo root
|
|
35
|
+
|
|
36
|
+
Any other files you added under `.cursor/` or `.claude/` (notes, local overrides, IDE state) are **left intact**. Older releases that deleted the whole tool directory are no longer the behavior.
|
|
19
37
|
|
|
20
38
|
Where things go on `init`:
|
|
21
39
|
|
|
@@ -23,7 +41,12 @@ Where things go on `init`:
|
|
|
23
41
|
|---|--------|--------|
|
|
24
42
|
| rules | `.cursor/rules` | `.claude/rules` |
|
|
25
43
|
| commands | `.cursor/commands` | `.claude/commands` |
|
|
26
|
-
|
|
|
44
|
+
| agents | `.cursor/agents` | `.claude/agents` |
|
|
45
|
+
| hooks | `.cursor/hooks`, `.cursor/hooks.json` | `.claude/hooks` |
|
|
46
|
+
| skills | `.cursor/skills` | `.claude/skills` |
|
|
47
|
+
| team artifacts template | `.cursor/team` | `.claude/team` |
|
|
48
|
+
| MCP | `mcp.json` → `.cursor/mcp.json`, `MCP.md` → `.cursor/` | `mcp.json` → **`.mcp.json`** (project root), `MCP.md` → `.claude/` |
|
|
49
|
+
| other | `BUGBOT.md`, `AGENTS.md` → `.cursor/` | `CLAUDE.md` → `.claude/CLAUDE.md` |
|
|
27
50
|
|
|
28
51
|
The package ships presets including **`next`** (Next.js stack) and **`ios-swift`** (iOS apps on Swift / SwiftUI). Other preset names: see `presets/` in the [repo](https://github.com/bonesofspring/ai-rules). Name is a single path segment, no `/` or `..`.
|
|
29
52
|
|
package/bin/cli.js
CHANGED
|
@@ -5,51 +5,95 @@
|
|
|
5
5
|
const fs = require('fs');
|
|
6
6
|
const path = require('path');
|
|
7
7
|
|
|
8
|
-
const packageRoot = path.join(__dirname, '..');
|
|
9
|
-
|
|
10
8
|
/** Single path segment: letters, digits, dot, underscore, hyphen; no separators or "..". */
|
|
11
9
|
const PRESET_NAME_RE = /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/;
|
|
10
|
+
const DEFAULT_PRESET = 'next';
|
|
11
|
+
const TOOLS = new Set(['cursor', 'claude']);
|
|
12
12
|
|
|
13
13
|
const PRESETS = {
|
|
14
14
|
cursor: {
|
|
15
15
|
rulesDir: '.cursor/rules',
|
|
16
16
|
commandsDir: '.cursor/commands',
|
|
17
17
|
relBase: ['presets', 'cursor'],
|
|
18
|
+
optionalCursorDirs: ['agents', 'hooks', 'skills', 'team'],
|
|
19
|
+
hooksJsonSrc: 'hooks.json',
|
|
20
|
+
/** Project MCP → `.cursor/mcp.json` */
|
|
21
|
+
mcpJsonSrc: 'mcp.json',
|
|
22
|
+
mcpJsonDest: '.cursor/mcp.json',
|
|
23
|
+
toolRootFiles: ['BUGBOT.md', 'AGENTS.md', 'MCP.md'],
|
|
18
24
|
},
|
|
19
25
|
claude: {
|
|
20
26
|
rulesDir: '.claude/rules',
|
|
21
27
|
commandsDir: '.claude/commands',
|
|
22
28
|
relBase: ['presets', 'claude'],
|
|
23
|
-
|
|
24
|
-
optionalClaudeDirs: ['skills', 'agents', 'hooks'],
|
|
25
|
-
/** Copied from preset root to `.claude/CLAUDE.md` when present. */
|
|
29
|
+
optionalClaudeDirs: ['skills', 'agents', 'hooks', 'team'],
|
|
26
30
|
claudeMdSrc: 'CLAUDE.md',
|
|
31
|
+
/** Project MCP lives at repo root (Claude Code project scope), not under `.claude/`. */
|
|
32
|
+
mcpJsonSrc: 'mcp.json',
|
|
33
|
+
mcpJsonDest: '.mcp.json',
|
|
34
|
+
toolRootFiles: ['MCP.md'],
|
|
27
35
|
},
|
|
28
36
|
};
|
|
29
37
|
|
|
38
|
+
function getPackageRoot() {
|
|
39
|
+
try {
|
|
40
|
+
return path.dirname(require.resolve('@bonesofspring/ai-rules/package.json'));
|
|
41
|
+
} catch {
|
|
42
|
+
return path.join(__dirname, '..');
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
30
46
|
function printHelp() {
|
|
31
47
|
console.log(`@bonesofspring/ai-rules
|
|
32
48
|
|
|
33
49
|
Usage:
|
|
34
|
-
ai-rules init <cursor|claude> --preset <name>
|
|
35
|
-
ai-rules
|
|
50
|
+
ai-rules init <cursor|claude> [--preset <name>]
|
|
51
|
+
ai-rules init <cursor|claude> <preset-name>
|
|
52
|
+
ai-rules clean <cursor|claude> [--cwd <dir>]
|
|
53
|
+
|
|
54
|
+
Options:
|
|
55
|
+
--preset <name> Preset name (default: ${DEFAULT_PRESET})
|
|
56
|
+
--cwd <dir> Target project directory (default: current working directory)
|
|
36
57
|
|
|
37
58
|
Notes:
|
|
38
|
-
init merges into
|
|
39
|
-
|
|
40
|
-
|
|
59
|
+
init merges into the target directory; same-named files are overwritten.
|
|
60
|
+
Cursor init copies rules, commands, agents, hooks, skills, team, hooks.json, BUGBOT.md, AGENTS.md, MCP.md, mcp.json → .cursor/mcp.json.
|
|
61
|
+
Claude init copies rules, commands, skills, agents, hooks, team, CLAUDE.md, MCP.md, and mcp.json → .mcp.json (project root).
|
|
62
|
+
Command forms: "init cursor --preset next", "init cursor next", "--preset next init cursor", "cursor init --preset next".
|
|
41
63
|
|
|
42
64
|
Examples:
|
|
43
65
|
npx @bonesofspring/ai-rules init cursor --preset next
|
|
66
|
+
npx @bonesofspring/ai-rules init cursor next
|
|
67
|
+
npx @bonesofspring/ai-rules init cursor --preset ios-swift
|
|
68
|
+
npx @bonesofspring/ai-rules init claude
|
|
44
69
|
npx @bonesofspring/ai-rules init claude --preset ios-swift
|
|
45
|
-
npx @bonesofspring/ai-rules clean
|
|
70
|
+
npx @bonesofspring/ai-rules clean cursor
|
|
46
71
|
`);
|
|
47
72
|
}
|
|
48
73
|
|
|
49
74
|
function parseArgs(argv) {
|
|
50
|
-
const args = { _: [] };
|
|
75
|
+
const args = { _: [], cwd: undefined, preset: undefined, presetError: undefined };
|
|
51
76
|
for (let i = 0; i < argv.length; i++) {
|
|
52
77
|
const a = argv[i];
|
|
78
|
+
if (a === '--cwd') {
|
|
79
|
+
const value = argv[i + 1];
|
|
80
|
+
if (value === undefined || value.startsWith('-')) {
|
|
81
|
+
args.cwdError = 'Missing value for --cwd';
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
args.cwd = value;
|
|
85
|
+
i++;
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
if (a.startsWith('--cwd=')) {
|
|
89
|
+
const value = a.slice('--cwd='.length);
|
|
90
|
+
if (value === '') {
|
|
91
|
+
args.cwdError = 'Missing value after --cwd=';
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
args.cwd = value;
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
53
97
|
if (a === '--preset') {
|
|
54
98
|
const value = argv[i + 1];
|
|
55
99
|
if (value === undefined || value.startsWith('-')) {
|
|
@@ -70,17 +114,53 @@ function parseArgs(argv) {
|
|
|
70
114
|
args.preset = value;
|
|
71
115
|
continue;
|
|
72
116
|
}
|
|
117
|
+
if (a === '-h' || a === '--help') {
|
|
118
|
+
args.help = true;
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
73
121
|
args._.push(a);
|
|
74
122
|
}
|
|
75
123
|
return args;
|
|
76
124
|
}
|
|
77
125
|
|
|
126
|
+
/**
|
|
127
|
+
* Supports: init cursor, cursor init, init cursor next (positional preset).
|
|
128
|
+
*/
|
|
129
|
+
function normalizeInitClean(parsed) {
|
|
130
|
+
const positional = [...parsed._];
|
|
131
|
+
let command;
|
|
132
|
+
let tool;
|
|
133
|
+
let presetFromPositional;
|
|
134
|
+
|
|
135
|
+
if (positional.length >= 2 && TOOLS.has(positional[0]) && positional[1] === 'init') {
|
|
136
|
+
command = 'init';
|
|
137
|
+
tool = positional[0];
|
|
138
|
+
presetFromPositional = positional[2];
|
|
139
|
+
} else if (positional.length >= 2 && positional[0] === 'init' && TOOLS.has(positional[1])) {
|
|
140
|
+
command = 'init';
|
|
141
|
+
tool = positional[1];
|
|
142
|
+
presetFromPositional = positional[2];
|
|
143
|
+
} else if (positional.length >= 2 && positional[0] === 'clean' && TOOLS.has(positional[1])) {
|
|
144
|
+
command = 'clean';
|
|
145
|
+
tool = positional[1];
|
|
146
|
+
} else if (positional.length >= 1) {
|
|
147
|
+
command = positional[0];
|
|
148
|
+
tool = positional[1];
|
|
149
|
+
if (command === 'init' && positional[2] && PRESET_NAME_RE.test(positional[2])) {
|
|
150
|
+
presetFromPositional = positional[2];
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const preset = parsed.preset || presetFromPositional;
|
|
155
|
+
return { command, tool, preset };
|
|
156
|
+
}
|
|
157
|
+
|
|
78
158
|
/**
|
|
79
159
|
* @returns {string | null} Error message or null if valid.
|
|
80
160
|
*/
|
|
81
161
|
function validatePresetName(preset) {
|
|
82
162
|
if (preset === undefined || preset === '') {
|
|
83
|
-
return 'Missing --preset <name
|
|
163
|
+
return 'Missing preset name (use --preset <name>, e.g. --preset next)';
|
|
84
164
|
}
|
|
85
165
|
if (!PRESET_NAME_RE.test(preset) || preset.includes('..')) {
|
|
86
166
|
return (
|
|
@@ -91,9 +171,6 @@ function validatePresetName(preset) {
|
|
|
91
171
|
return null;
|
|
92
172
|
}
|
|
93
173
|
|
|
94
|
-
/**
|
|
95
|
-
* Ensures resolved preset dir stays under the tool presets root (defense in depth).
|
|
96
|
-
*/
|
|
97
174
|
function assertPresetDirInsideRoot(presetsRoot, presetBase) {
|
|
98
175
|
const root = path.resolve(presetsRoot);
|
|
99
176
|
const resolved = path.resolve(presetBase);
|
|
@@ -117,10 +194,17 @@ function copyDir(src, dest) {
|
|
|
117
194
|
copyDir(from, to);
|
|
118
195
|
} else {
|
|
119
196
|
fs.copyFileSync(from, to);
|
|
197
|
+
if (e.name.endsWith('.sh')) {
|
|
198
|
+
fs.chmodSync(to, 0o755);
|
|
199
|
+
}
|
|
120
200
|
}
|
|
121
201
|
}
|
|
122
202
|
}
|
|
123
203
|
|
|
204
|
+
function getOptionalDirs(cfg) {
|
|
205
|
+
return cfg.optionalCursorDirs || cfg.optionalClaudeDirs || [];
|
|
206
|
+
}
|
|
207
|
+
|
|
124
208
|
function removeDirIfExists(dir) {
|
|
125
209
|
if (fs.existsSync(dir)) {
|
|
126
210
|
fs.rmSync(dir, { recursive: true, force: true });
|
|
@@ -133,76 +217,171 @@ function removeFileIfExists(filePath) {
|
|
|
133
217
|
}
|
|
134
218
|
}
|
|
135
219
|
|
|
220
|
+
function listPresetNames(presetsRoot) {
|
|
221
|
+
if (!fs.existsSync(presetsRoot)) {
|
|
222
|
+
return [];
|
|
223
|
+
}
|
|
224
|
+
return fs
|
|
225
|
+
.readdirSync(presetsRoot, { withFileTypes: true })
|
|
226
|
+
.filter((e) => e.isDirectory())
|
|
227
|
+
.map((e) => e.name)
|
|
228
|
+
.filter((name) => PRESET_NAME_RE.test(name));
|
|
229
|
+
}
|
|
230
|
+
|
|
136
231
|
function presetHasAnySource(base, cfg) {
|
|
137
232
|
const rulesSrc = path.join(base, 'rules');
|
|
138
233
|
const commandsSrc = path.join(base, 'commands');
|
|
139
234
|
if (fs.existsSync(rulesSrc) || fs.existsSync(commandsSrc)) {
|
|
140
235
|
return true;
|
|
141
236
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
return true;
|
|
146
|
-
}
|
|
237
|
+
for (const name of getOptionalDirs(cfg)) {
|
|
238
|
+
if (fs.existsSync(path.join(base, name))) {
|
|
239
|
+
return true;
|
|
147
240
|
}
|
|
148
241
|
}
|
|
149
242
|
if (cfg.claudeMdSrc && fs.existsSync(path.join(base, cfg.claudeMdSrc))) {
|
|
150
243
|
return true;
|
|
151
244
|
}
|
|
245
|
+
if (cfg.hooksJsonSrc && fs.existsSync(path.join(base, cfg.hooksJsonSrc))) {
|
|
246
|
+
return true;
|
|
247
|
+
}
|
|
248
|
+
if (cfg.mcpJsonSrc && fs.existsSync(path.join(base, cfg.mcpJsonSrc))) {
|
|
249
|
+
return true;
|
|
250
|
+
}
|
|
251
|
+
for (const name of cfg.toolRootFiles || []) {
|
|
252
|
+
if (fs.existsSync(path.join(base, name))) {
|
|
253
|
+
return true;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
152
256
|
return false;
|
|
153
257
|
}
|
|
154
258
|
|
|
155
|
-
function
|
|
156
|
-
const
|
|
157
|
-
if (!
|
|
158
|
-
console.error(`
|
|
259
|
+
function resolveTargetCwd(cwdOption) {
|
|
260
|
+
const cwd = cwdOption ? path.resolve(cwdOption) : process.cwd();
|
|
261
|
+
if (!fs.existsSync(cwd)) {
|
|
262
|
+
console.error(`Target directory does not exist: ${cwd}`);
|
|
159
263
|
process.exit(1);
|
|
160
264
|
}
|
|
161
|
-
|
|
265
|
+
if (!fs.statSync(cwd).isDirectory()) {
|
|
266
|
+
console.error(`Target path is not a directory: ${cwd}`);
|
|
267
|
+
process.exit(1);
|
|
268
|
+
}
|
|
269
|
+
return cwd;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
function resolvePresetName(tool, preset, packageRoot) {
|
|
273
|
+
const cfg = PRESETS[tool];
|
|
274
|
+
const presetsRoot = path.join(packageRoot, ...cfg.relBase);
|
|
275
|
+
let name = preset || DEFAULT_PRESET;
|
|
276
|
+
|
|
277
|
+
const nameErr = validatePresetName(name);
|
|
162
278
|
if (nameErr) {
|
|
163
279
|
console.error(nameErr);
|
|
164
280
|
process.exit(1);
|
|
165
281
|
}
|
|
166
|
-
|
|
167
|
-
|
|
282
|
+
|
|
283
|
+
let base = path.join(presetsRoot, name);
|
|
284
|
+
if (!presetHasAnySource(base, cfg)) {
|
|
285
|
+
const available = listPresetNames(presetsRoot);
|
|
286
|
+
if (!preset && available.includes(DEFAULT_PRESET)) {
|
|
287
|
+
name = DEFAULT_PRESET;
|
|
288
|
+
base = path.join(presetsRoot, name);
|
|
289
|
+
} else {
|
|
290
|
+
console.error(`Preset "${name}" for ${tool} not found.`);
|
|
291
|
+
console.error(`Looked in: ${base}`);
|
|
292
|
+
console.error(`Package root: ${packageRoot}`);
|
|
293
|
+
if (available.length > 0) {
|
|
294
|
+
console.error(`Available presets: ${available.join(', ')}`);
|
|
295
|
+
} else {
|
|
296
|
+
console.error(`No presets directory at: ${presetsRoot}`);
|
|
297
|
+
console.error(
|
|
298
|
+
'The installed package may be incomplete. Reinstall @bonesofspring/ai-rules or run from the package source.',
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
process.exit(1);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
168
305
|
assertPresetDirInsideRoot(presetsRoot, base);
|
|
306
|
+
return { name, base, presetsRoot };
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
function cmdInit(tool, preset, cwdOption) {
|
|
310
|
+
const cfg = PRESETS[tool];
|
|
311
|
+
if (!cfg) {
|
|
312
|
+
console.error(`Unknown tool: ${tool}. Use cursor or claude.`);
|
|
313
|
+
process.exit(1);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
const packageRoot = getPackageRoot();
|
|
317
|
+
const cwd = resolveTargetCwd(cwdOption);
|
|
318
|
+
const { name: presetName, base } = resolvePresetName(tool, preset, packageRoot);
|
|
169
319
|
|
|
170
320
|
const rulesSrc = path.join(base, 'rules');
|
|
171
321
|
const commandsSrc = path.join(base, 'commands');
|
|
172
|
-
const
|
|
322
|
+
const toolRoot = tool === 'cursor' ? '.cursor' : '.claude';
|
|
323
|
+
const toolRootAbs = path.join(cwd, toolRoot);
|
|
173
324
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
}
|
|
325
|
+
fs.mkdirSync(toolRootAbs, { recursive: true });
|
|
326
|
+
|
|
327
|
+
let copiedSteps = 0;
|
|
178
328
|
|
|
179
329
|
try {
|
|
180
330
|
if (tool === 'claude' && cfg.claudeMdSrc) {
|
|
181
331
|
const mdFrom = path.join(base, cfg.claudeMdSrc);
|
|
182
332
|
if (fs.existsSync(mdFrom)) {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
console.log('Copied CLAUDE.md → .claude/CLAUDE.md');
|
|
333
|
+
fs.copyFileSync(mdFrom, path.join(toolRootAbs, 'CLAUDE.md'));
|
|
334
|
+
console.log(`Copied CLAUDE.md → ${path.join(toolRoot, 'CLAUDE.md')}`);
|
|
335
|
+
copiedSteps++;
|
|
187
336
|
}
|
|
188
337
|
}
|
|
189
338
|
|
|
190
339
|
if (fs.existsSync(rulesSrc)) {
|
|
191
340
|
copyDir(rulesSrc, path.join(cwd, cfg.rulesDir));
|
|
192
341
|
console.log(`Copied rules → ${cfg.rulesDir}`);
|
|
342
|
+
copiedSteps++;
|
|
193
343
|
}
|
|
194
344
|
if (fs.existsSync(commandsSrc)) {
|
|
195
345
|
copyDir(commandsSrc, path.join(cwd, cfg.commandsDir));
|
|
196
346
|
console.log(`Copied commands → ${cfg.commandsDir}`);
|
|
347
|
+
copiedSteps++;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
for (const name of getOptionalDirs(cfg)) {
|
|
351
|
+
const src = path.join(base, name);
|
|
352
|
+
if (fs.existsSync(src)) {
|
|
353
|
+
copyDir(src, path.join(toolRootAbs, name));
|
|
354
|
+
console.log(`Copied ${name}/ → ${toolRoot}/${name}/`);
|
|
355
|
+
copiedSteps++;
|
|
356
|
+
}
|
|
197
357
|
}
|
|
198
358
|
|
|
199
|
-
if (tool === '
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
359
|
+
if (tool === 'cursor' && cfg.hooksJsonSrc) {
|
|
360
|
+
const hooksFrom = path.join(base, cfg.hooksJsonSrc);
|
|
361
|
+
if (fs.existsSync(hooksFrom)) {
|
|
362
|
+
fs.copyFileSync(hooksFrom, path.join(toolRootAbs, 'hooks.json'));
|
|
363
|
+
console.log(`Copied hooks.json → ${toolRoot}/hooks.json`);
|
|
364
|
+
copiedSteps++;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
if (cfg.mcpJsonSrc && cfg.mcpJsonDest) {
|
|
369
|
+
const mcpFrom = path.join(base, cfg.mcpJsonSrc);
|
|
370
|
+
if (fs.existsSync(mcpFrom)) {
|
|
371
|
+
const mcpDestAbs = path.join(cwd, cfg.mcpJsonDest);
|
|
372
|
+
fs.mkdirSync(path.dirname(mcpDestAbs), { recursive: true });
|
|
373
|
+
fs.copyFileSync(mcpFrom, mcpDestAbs);
|
|
374
|
+
console.log(`Copied ${cfg.mcpJsonSrc} → ${cfg.mcpJsonDest}`);
|
|
375
|
+
copiedSteps++;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
for (const name of cfg.toolRootFiles || []) {
|
|
380
|
+
const from = path.join(base, name);
|
|
381
|
+
if (fs.existsSync(from)) {
|
|
382
|
+
fs.copyFileSync(from, path.join(toolRootAbs, name));
|
|
383
|
+
console.log(`Copied ${name} → ${toolRoot}/${name}`);
|
|
384
|
+
copiedSteps++;
|
|
206
385
|
}
|
|
207
386
|
}
|
|
208
387
|
} catch (err) {
|
|
@@ -210,66 +389,100 @@ function cmdInit(tool, preset) {
|
|
|
210
389
|
console.error(`init failed: ${msg}`);
|
|
211
390
|
process.exit(1);
|
|
212
391
|
}
|
|
392
|
+
|
|
393
|
+
if (copiedSteps === 0) {
|
|
394
|
+
console.error(`init failed: preset "${presetName}" had no files to copy from ${base}`);
|
|
395
|
+
process.exit(1);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
if (!fs.existsSync(toolRootAbs)) {
|
|
399
|
+
console.error(`init failed: ${toolRootAbs} was not created`);
|
|
400
|
+
process.exit(1);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
console.log(`Done. ${toolRoot} installed at ${toolRootAbs} (preset: ${presetName})`);
|
|
213
404
|
}
|
|
214
405
|
|
|
215
|
-
function cmdClean(tool) {
|
|
406
|
+
function cmdClean(tool, cwdOption) {
|
|
216
407
|
const cfg = PRESETS[tool];
|
|
217
408
|
if (!cfg) {
|
|
218
409
|
console.error(`Unknown tool: ${tool}. Use cursor or claude.`);
|
|
219
410
|
process.exit(1);
|
|
220
411
|
}
|
|
221
|
-
const cwd =
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
return;
|
|
226
|
-
}
|
|
412
|
+
const cwd = resolveTargetCwd(cwdOption);
|
|
413
|
+
const toolRoot = tool === 'cursor' ? '.cursor' : '.claude';
|
|
414
|
+
const removedParts = [cfg.rulesDir, cfg.commandsDir];
|
|
415
|
+
|
|
227
416
|
removeDirIfExists(path.join(cwd, cfg.rulesDir));
|
|
228
417
|
removeDirIfExists(path.join(cwd, cfg.commandsDir));
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
)
|
|
418
|
+
|
|
419
|
+
const optionalDirs = getOptionalDirs(cfg);
|
|
420
|
+
for (const name of optionalDirs) {
|
|
421
|
+
removeDirIfExists(path.join(cwd, toolRoot, name));
|
|
422
|
+
removedParts.push(`${toolRoot}/${name}`);
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
if (cfg.claudeMdSrc) {
|
|
426
|
+
removeFileIfExists(path.join(cwd, toolRoot, 'CLAUDE.md'));
|
|
427
|
+
removedParts.push(`${toolRoot}/CLAUDE.md`);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
if (cfg.hooksJsonSrc) {
|
|
431
|
+
removeFileIfExists(path.join(cwd, toolRoot, 'hooks.json'));
|
|
432
|
+
removedParts.push(`${toolRoot}/hooks.json`);
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
if (cfg.mcpJsonDest) {
|
|
436
|
+
removeFileIfExists(path.join(cwd, cfg.mcpJsonDest));
|
|
437
|
+
removedParts.push(cfg.mcpJsonDest);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
for (const name of cfg.toolRootFiles || []) {
|
|
441
|
+
removeFileIfExists(path.join(cwd, toolRoot, name));
|
|
442
|
+
removedParts.push(`${toolRoot}/${name}`);
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
console.log(`Removed ${removedParts.join(', ')} (if present)`);
|
|
242
446
|
}
|
|
243
447
|
|
|
244
448
|
function main() {
|
|
245
449
|
const argv = process.argv.slice(2);
|
|
246
|
-
if (argv.length === 0
|
|
450
|
+
if (argv.length === 0) {
|
|
247
451
|
printHelp();
|
|
248
452
|
process.exit(0);
|
|
249
453
|
}
|
|
250
454
|
|
|
251
455
|
const parsed = parseArgs(argv);
|
|
252
|
-
|
|
456
|
+
if (parsed.help) {
|
|
457
|
+
printHelp();
|
|
458
|
+
process.exit(0);
|
|
459
|
+
}
|
|
253
460
|
|
|
254
461
|
if (parsed.presetError) {
|
|
255
462
|
console.error(parsed.presetError);
|
|
256
463
|
process.exit(1);
|
|
257
464
|
}
|
|
465
|
+
if (parsed.cwdError) {
|
|
466
|
+
console.error(parsed.cwdError);
|
|
467
|
+
process.exit(1);
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
const { command, tool, preset } = normalizeInitClean(parsed);
|
|
258
471
|
|
|
259
472
|
if (command === 'init') {
|
|
260
|
-
if (!tool) {
|
|
261
|
-
console.error('Missing
|
|
473
|
+
if (!tool || !TOOLS.has(tool)) {
|
|
474
|
+
console.error('Missing or invalid tool. Use: init cursor|claude [--preset next]');
|
|
262
475
|
process.exit(1);
|
|
263
476
|
}
|
|
264
|
-
cmdInit(tool, parsed.
|
|
477
|
+
cmdInit(tool, preset, parsed.cwd);
|
|
265
478
|
return;
|
|
266
479
|
}
|
|
267
480
|
if (command === 'clean') {
|
|
268
|
-
if (!tool) {
|
|
269
|
-
console.error('Missing
|
|
481
|
+
if (!tool || !TOOLS.has(tool)) {
|
|
482
|
+
console.error('Missing or invalid tool. Use: clean cursor|claude');
|
|
270
483
|
process.exit(1);
|
|
271
484
|
}
|
|
272
|
-
cmdClean(tool);
|
|
485
|
+
cmdClean(tool, parsed.cwd);
|
|
273
486
|
return;
|
|
274
487
|
}
|
|
275
488
|
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bonesofspring/ai-rules",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "Presets of Cursor and Claude rules/commands for Revy Ross personal use",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Revy Ross",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
|
-
"url": "https://github.com/bonesofspring/ai-rules.git"
|
|
9
|
+
"url": "git+https://github.com/bonesofspring/ai-rules.git"
|
|
10
10
|
},
|
|
11
11
|
"keywords": [
|
|
12
12
|
"cursor",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
},
|
|
21
21
|
"files": [
|
|
22
22
|
"README.md",
|
|
23
|
+
"CHANGELOG.md",
|
|
23
24
|
"bin",
|
|
24
25
|
"presets"
|
|
25
26
|
],
|