@bonesofspring/ai-rules 0.2.2 → 0.2.3
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 +63 -0
- package/README.md +26 -4
- package/bin/cli.js +259 -72
- package/package.json +3 -2
- package/presets/claude/ios-swift/CLAUDE.md +28 -20
- package/presets/claude/ios-swift/README.md +16 -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/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/README.md +10 -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/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 +141 -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/README.md +26 -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/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 +80 -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 +27 -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/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/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 +141 -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 +105 -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,63 @@
|
|
|
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
|
+
- **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).
|
|
13
|
+
- **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`.
|
|
14
|
+
- **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).
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- **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).
|
|
19
|
+
- Claude `next`: `agent-team-orchestrator` and `code-review-mr` use `paths:` (on-demand) — session-start matches the 3-rule budget above.
|
|
20
|
+
- 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).
|
|
21
|
+
- **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.
|
|
22
|
+
|
|
23
|
+
### Notes
|
|
24
|
+
|
|
25
|
+
- **P2 optional (ios-swift):** Remaining polish: feature-delivery matrix enrichment, swift-conventions body cap. (`BUGBOT.md` shipped.)
|
|
26
|
+
|
|
27
|
+
## 0.2.2
|
|
28
|
+
|
|
29
|
+
### Breaking
|
|
30
|
+
|
|
31
|
+
- **`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.
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
|
|
35
|
+
- Cursor `next`: `architecture-boundaries-ui.mdc`, `navigation-router-ui.mdc` (slim UI-edit rules); Claude equivalents under `architecture/` and `stack/`.
|
|
36
|
+
- Cursor/Claude `next`: `AGENTS.md` on Cursor init; team `fixtures/` for pipeline profiles; pipeline profiles (`full` / `standard` / `light`) in `task-router`.
|
|
37
|
+
- Claude `next`: `hooks/chain-team-phases.sh` feature parity with Cursor (tool paths only differ).
|
|
38
|
+
|
|
39
|
+
### Changed
|
|
40
|
+
|
|
41
|
+
- 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).
|
|
42
|
+
- README documents `AGENTS.md` and selective `clean`.
|
|
43
|
+
|
|
44
|
+
## 0.2.0
|
|
45
|
+
|
|
46
|
+
### Breaking
|
|
47
|
+
|
|
48
|
+
- **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.
|
|
49
|
+
- **`feature-delivery-flow.mdc` removed** — content merged into `feature-delivery-workflow.mdc`.
|
|
50
|
+
- **`agent-team-intake`** no longer always-on (Cursor: `alwaysApply: false`; Claude: `paths:` on commands/team). Use orchestrator or `/task`.
|
|
51
|
+
|
|
52
|
+
### Changed
|
|
53
|
+
|
|
54
|
+
- Slimmed always-on rules: `next-app-core`, `code-quality-and-refactoring`, `post-change-lint`, `package-manager` (~9 KB baseline vs ~21 KB).
|
|
55
|
+
- Narrowed globs: `css-property-order-stylelint`, `no-type-assertion-as-import-export`, `reference-features`, `public-imports`.
|
|
56
|
+
- `css-property-order` stub — property list delegated to Stylelint `--fix`.
|
|
57
|
+
- Slimmed `task-router` agent; pipeline JSON examples moved to `agents/README.md`.
|
|
58
|
+
- Agents reference skills as SSOT; scoped lint for `feature-developer` when next step is `build-verifier`.
|
|
59
|
+
- Orchestrator: explicit fast-path when to skip pipeline.
|
|
60
|
+
|
|
61
|
+
## 0.1.42
|
|
62
|
+
|
|
63
|
+
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`, and team artifacts 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`
|
|
34
|
+
- Claude root file: `CLAUDE.md`
|
|
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,11 @@ 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
|
+
| other | `BUGBOT.md`, `AGENTS.md` → `.cursor/` | `CLAUDE.md` → `.claude/CLAUDE.md` |
|
|
27
49
|
|
|
28
50
|
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
51
|
|
package/bin/cli.js
CHANGED
|
@@ -5,51 +5,88 @@
|
|
|
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
|
+
toolRootFiles: ['BUGBOT.md', 'AGENTS.md'],
|
|
18
21
|
},
|
|
19
22
|
claude: {
|
|
20
23
|
rulesDir: '.claude/rules',
|
|
21
24
|
commandsDir: '.claude/commands',
|
|
22
25
|
relBase: ['presets', 'claude'],
|
|
23
|
-
|
|
24
|
-
optionalClaudeDirs: ['skills', 'agents', 'hooks'],
|
|
25
|
-
/** Copied from preset root to `.claude/CLAUDE.md` when present. */
|
|
26
|
+
optionalClaudeDirs: ['skills', 'agents', 'hooks', 'team'],
|
|
26
27
|
claudeMdSrc: 'CLAUDE.md',
|
|
27
28
|
},
|
|
28
29
|
};
|
|
29
30
|
|
|
31
|
+
function getPackageRoot() {
|
|
32
|
+
try {
|
|
33
|
+
return path.dirname(require.resolve('@bonesofspring/ai-rules/package.json'));
|
|
34
|
+
} catch {
|
|
35
|
+
return path.join(__dirname, '..');
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
30
39
|
function printHelp() {
|
|
31
40
|
console.log(`@bonesofspring/ai-rules
|
|
32
41
|
|
|
33
42
|
Usage:
|
|
34
|
-
ai-rules init <cursor|claude> --preset <name>
|
|
35
|
-
ai-rules
|
|
43
|
+
ai-rules init <cursor|claude> [--preset <name>]
|
|
44
|
+
ai-rules init <cursor|claude> <preset-name>
|
|
45
|
+
ai-rules clean <cursor|claude> [--cwd <dir>]
|
|
46
|
+
|
|
47
|
+
Options:
|
|
48
|
+
--preset <name> Preset name (default: ${DEFAULT_PRESET})
|
|
49
|
+
--cwd <dir> Target project directory (default: current working directory)
|
|
36
50
|
|
|
37
51
|
Notes:
|
|
38
|
-
init merges into
|
|
39
|
-
|
|
40
|
-
|
|
52
|
+
init merges into the target directory; same-named files are overwritten.
|
|
53
|
+
Cursor init copies rules, commands, agents, hooks, skills, team, hooks.json, BUGBOT.md, AGENTS.md.
|
|
54
|
+
Claude init copies rules, commands, skills, agents, hooks, team, and CLAUDE.md when present.
|
|
55
|
+
Command forms: "init cursor --preset next", "init cursor next", "--preset next init cursor", "cursor init --preset next".
|
|
41
56
|
|
|
42
57
|
Examples:
|
|
43
58
|
npx @bonesofspring/ai-rules init cursor --preset next
|
|
59
|
+
npx @bonesofspring/ai-rules init cursor next
|
|
60
|
+
npx @bonesofspring/ai-rules init cursor --preset ios-swift
|
|
61
|
+
npx @bonesofspring/ai-rules init claude
|
|
44
62
|
npx @bonesofspring/ai-rules init claude --preset ios-swift
|
|
45
|
-
npx @bonesofspring/ai-rules clean
|
|
63
|
+
npx @bonesofspring/ai-rules clean cursor
|
|
46
64
|
`);
|
|
47
65
|
}
|
|
48
66
|
|
|
49
67
|
function parseArgs(argv) {
|
|
50
|
-
const args = { _: [] };
|
|
68
|
+
const args = { _: [], cwd: undefined, preset: undefined, presetError: undefined };
|
|
51
69
|
for (let i = 0; i < argv.length; i++) {
|
|
52
70
|
const a = argv[i];
|
|
71
|
+
if (a === '--cwd') {
|
|
72
|
+
const value = argv[i + 1];
|
|
73
|
+
if (value === undefined || value.startsWith('-')) {
|
|
74
|
+
args.cwdError = 'Missing value for --cwd';
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
args.cwd = value;
|
|
78
|
+
i++;
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
if (a.startsWith('--cwd=')) {
|
|
82
|
+
const value = a.slice('--cwd='.length);
|
|
83
|
+
if (value === '') {
|
|
84
|
+
args.cwdError = 'Missing value after --cwd=';
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
args.cwd = value;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
53
90
|
if (a === '--preset') {
|
|
54
91
|
const value = argv[i + 1];
|
|
55
92
|
if (value === undefined || value.startsWith('-')) {
|
|
@@ -70,17 +107,53 @@ function parseArgs(argv) {
|
|
|
70
107
|
args.preset = value;
|
|
71
108
|
continue;
|
|
72
109
|
}
|
|
110
|
+
if (a === '-h' || a === '--help') {
|
|
111
|
+
args.help = true;
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
73
114
|
args._.push(a);
|
|
74
115
|
}
|
|
75
116
|
return args;
|
|
76
117
|
}
|
|
77
118
|
|
|
119
|
+
/**
|
|
120
|
+
* Supports: init cursor, cursor init, init cursor next (positional preset).
|
|
121
|
+
*/
|
|
122
|
+
function normalizeInitClean(parsed) {
|
|
123
|
+
const positional = [...parsed._];
|
|
124
|
+
let command;
|
|
125
|
+
let tool;
|
|
126
|
+
let presetFromPositional;
|
|
127
|
+
|
|
128
|
+
if (positional.length >= 2 && TOOLS.has(positional[0]) && positional[1] === 'init') {
|
|
129
|
+
command = 'init';
|
|
130
|
+
tool = positional[0];
|
|
131
|
+
presetFromPositional = positional[2];
|
|
132
|
+
} else if (positional.length >= 2 && positional[0] === 'init' && TOOLS.has(positional[1])) {
|
|
133
|
+
command = 'init';
|
|
134
|
+
tool = positional[1];
|
|
135
|
+
presetFromPositional = positional[2];
|
|
136
|
+
} else if (positional.length >= 2 && positional[0] === 'clean' && TOOLS.has(positional[1])) {
|
|
137
|
+
command = 'clean';
|
|
138
|
+
tool = positional[1];
|
|
139
|
+
} else if (positional.length >= 1) {
|
|
140
|
+
command = positional[0];
|
|
141
|
+
tool = positional[1];
|
|
142
|
+
if (command === 'init' && positional[2] && PRESET_NAME_RE.test(positional[2])) {
|
|
143
|
+
presetFromPositional = positional[2];
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const preset = parsed.preset || presetFromPositional;
|
|
148
|
+
return { command, tool, preset };
|
|
149
|
+
}
|
|
150
|
+
|
|
78
151
|
/**
|
|
79
152
|
* @returns {string | null} Error message or null if valid.
|
|
80
153
|
*/
|
|
81
154
|
function validatePresetName(preset) {
|
|
82
155
|
if (preset === undefined || preset === '') {
|
|
83
|
-
return 'Missing --preset <name
|
|
156
|
+
return 'Missing preset name (use --preset <name>, e.g. --preset next)';
|
|
84
157
|
}
|
|
85
158
|
if (!PRESET_NAME_RE.test(preset) || preset.includes('..')) {
|
|
86
159
|
return (
|
|
@@ -91,9 +164,6 @@ function validatePresetName(preset) {
|
|
|
91
164
|
return null;
|
|
92
165
|
}
|
|
93
166
|
|
|
94
|
-
/**
|
|
95
|
-
* Ensures resolved preset dir stays under the tool presets root (defense in depth).
|
|
96
|
-
*/
|
|
97
167
|
function assertPresetDirInsideRoot(presetsRoot, presetBase) {
|
|
98
168
|
const root = path.resolve(presetsRoot);
|
|
99
169
|
const resolved = path.resolve(presetBase);
|
|
@@ -117,10 +187,17 @@ function copyDir(src, dest) {
|
|
|
117
187
|
copyDir(from, to);
|
|
118
188
|
} else {
|
|
119
189
|
fs.copyFileSync(from, to);
|
|
190
|
+
if (e.name.endsWith('.sh')) {
|
|
191
|
+
fs.chmodSync(to, 0o755);
|
|
192
|
+
}
|
|
120
193
|
}
|
|
121
194
|
}
|
|
122
195
|
}
|
|
123
196
|
|
|
197
|
+
function getOptionalDirs(cfg) {
|
|
198
|
+
return cfg.optionalCursorDirs || cfg.optionalClaudeDirs || [];
|
|
199
|
+
}
|
|
200
|
+
|
|
124
201
|
function removeDirIfExists(dir) {
|
|
125
202
|
if (fs.existsSync(dir)) {
|
|
126
203
|
fs.rmSync(dir, { recursive: true, force: true });
|
|
@@ -133,76 +210,157 @@ function removeFileIfExists(filePath) {
|
|
|
133
210
|
}
|
|
134
211
|
}
|
|
135
212
|
|
|
213
|
+
function listPresetNames(presetsRoot) {
|
|
214
|
+
if (!fs.existsSync(presetsRoot)) {
|
|
215
|
+
return [];
|
|
216
|
+
}
|
|
217
|
+
return fs
|
|
218
|
+
.readdirSync(presetsRoot, { withFileTypes: true })
|
|
219
|
+
.filter((e) => e.isDirectory())
|
|
220
|
+
.map((e) => e.name)
|
|
221
|
+
.filter((name) => PRESET_NAME_RE.test(name));
|
|
222
|
+
}
|
|
223
|
+
|
|
136
224
|
function presetHasAnySource(base, cfg) {
|
|
137
225
|
const rulesSrc = path.join(base, 'rules');
|
|
138
226
|
const commandsSrc = path.join(base, 'commands');
|
|
139
227
|
if (fs.existsSync(rulesSrc) || fs.existsSync(commandsSrc)) {
|
|
140
228
|
return true;
|
|
141
229
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
return true;
|
|
146
|
-
}
|
|
230
|
+
for (const name of getOptionalDirs(cfg)) {
|
|
231
|
+
if (fs.existsSync(path.join(base, name))) {
|
|
232
|
+
return true;
|
|
147
233
|
}
|
|
148
234
|
}
|
|
149
235
|
if (cfg.claudeMdSrc && fs.existsSync(path.join(base, cfg.claudeMdSrc))) {
|
|
150
236
|
return true;
|
|
151
237
|
}
|
|
238
|
+
if (cfg.hooksJsonSrc && fs.existsSync(path.join(base, cfg.hooksJsonSrc))) {
|
|
239
|
+
return true;
|
|
240
|
+
}
|
|
241
|
+
for (const name of cfg.toolRootFiles || []) {
|
|
242
|
+
if (fs.existsSync(path.join(base, name))) {
|
|
243
|
+
return true;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
152
246
|
return false;
|
|
153
247
|
}
|
|
154
248
|
|
|
155
|
-
function
|
|
156
|
-
const
|
|
157
|
-
if (!
|
|
158
|
-
console.error(`
|
|
249
|
+
function resolveTargetCwd(cwdOption) {
|
|
250
|
+
const cwd = cwdOption ? path.resolve(cwdOption) : process.cwd();
|
|
251
|
+
if (!fs.existsSync(cwd)) {
|
|
252
|
+
console.error(`Target directory does not exist: ${cwd}`);
|
|
253
|
+
process.exit(1);
|
|
254
|
+
}
|
|
255
|
+
if (!fs.statSync(cwd).isDirectory()) {
|
|
256
|
+
console.error(`Target path is not a directory: ${cwd}`);
|
|
159
257
|
process.exit(1);
|
|
160
258
|
}
|
|
161
|
-
|
|
259
|
+
return cwd;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
function resolvePresetName(tool, preset, packageRoot) {
|
|
263
|
+
const cfg = PRESETS[tool];
|
|
264
|
+
const presetsRoot = path.join(packageRoot, ...cfg.relBase);
|
|
265
|
+
let name = preset || DEFAULT_PRESET;
|
|
266
|
+
|
|
267
|
+
const nameErr = validatePresetName(name);
|
|
162
268
|
if (nameErr) {
|
|
163
269
|
console.error(nameErr);
|
|
164
270
|
process.exit(1);
|
|
165
271
|
}
|
|
166
|
-
|
|
167
|
-
|
|
272
|
+
|
|
273
|
+
let base = path.join(presetsRoot, name);
|
|
274
|
+
if (!presetHasAnySource(base, cfg)) {
|
|
275
|
+
const available = listPresetNames(presetsRoot);
|
|
276
|
+
if (!preset && available.includes(DEFAULT_PRESET)) {
|
|
277
|
+
name = DEFAULT_PRESET;
|
|
278
|
+
base = path.join(presetsRoot, name);
|
|
279
|
+
} else {
|
|
280
|
+
console.error(`Preset "${name}" for ${tool} not found.`);
|
|
281
|
+
console.error(`Looked in: ${base}`);
|
|
282
|
+
console.error(`Package root: ${packageRoot}`);
|
|
283
|
+
if (available.length > 0) {
|
|
284
|
+
console.error(`Available presets: ${available.join(', ')}`);
|
|
285
|
+
} else {
|
|
286
|
+
console.error(`No presets directory at: ${presetsRoot}`);
|
|
287
|
+
console.error(
|
|
288
|
+
'The installed package may be incomplete. Reinstall @bonesofspring/ai-rules or run from the package source.',
|
|
289
|
+
);
|
|
290
|
+
}
|
|
291
|
+
process.exit(1);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
168
295
|
assertPresetDirInsideRoot(presetsRoot, base);
|
|
296
|
+
return { name, base, presetsRoot };
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
function cmdInit(tool, preset, cwdOption) {
|
|
300
|
+
const cfg = PRESETS[tool];
|
|
301
|
+
if (!cfg) {
|
|
302
|
+
console.error(`Unknown tool: ${tool}. Use cursor or claude.`);
|
|
303
|
+
process.exit(1);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
const packageRoot = getPackageRoot();
|
|
307
|
+
const cwd = resolveTargetCwd(cwdOption);
|
|
308
|
+
const { name: presetName, base } = resolvePresetName(tool, preset, packageRoot);
|
|
169
309
|
|
|
170
310
|
const rulesSrc = path.join(base, 'rules');
|
|
171
311
|
const commandsSrc = path.join(base, 'commands');
|
|
172
|
-
const
|
|
312
|
+
const toolRoot = tool === 'cursor' ? '.cursor' : '.claude';
|
|
313
|
+
const toolRootAbs = path.join(cwd, toolRoot);
|
|
173
314
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
}
|
|
315
|
+
fs.mkdirSync(toolRootAbs, { recursive: true });
|
|
316
|
+
|
|
317
|
+
let copiedSteps = 0;
|
|
178
318
|
|
|
179
319
|
try {
|
|
180
320
|
if (tool === 'claude' && cfg.claudeMdSrc) {
|
|
181
321
|
const mdFrom = path.join(base, cfg.claudeMdSrc);
|
|
182
322
|
if (fs.existsSync(mdFrom)) {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
console.log('Copied CLAUDE.md → .claude/CLAUDE.md');
|
|
323
|
+
fs.copyFileSync(mdFrom, path.join(toolRootAbs, 'CLAUDE.md'));
|
|
324
|
+
console.log(`Copied CLAUDE.md → ${path.join(toolRoot, 'CLAUDE.md')}`);
|
|
325
|
+
copiedSteps++;
|
|
187
326
|
}
|
|
188
327
|
}
|
|
189
328
|
|
|
190
329
|
if (fs.existsSync(rulesSrc)) {
|
|
191
330
|
copyDir(rulesSrc, path.join(cwd, cfg.rulesDir));
|
|
192
331
|
console.log(`Copied rules → ${cfg.rulesDir}`);
|
|
332
|
+
copiedSteps++;
|
|
193
333
|
}
|
|
194
334
|
if (fs.existsSync(commandsSrc)) {
|
|
195
335
|
copyDir(commandsSrc, path.join(cwd, cfg.commandsDir));
|
|
196
336
|
console.log(`Copied commands → ${cfg.commandsDir}`);
|
|
337
|
+
copiedSteps++;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
for (const name of getOptionalDirs(cfg)) {
|
|
341
|
+
const src = path.join(base, name);
|
|
342
|
+
if (fs.existsSync(src)) {
|
|
343
|
+
copyDir(src, path.join(toolRootAbs, name));
|
|
344
|
+
console.log(`Copied ${name}/ → ${toolRoot}/${name}/`);
|
|
345
|
+
copiedSteps++;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
if (tool === 'cursor' && cfg.hooksJsonSrc) {
|
|
350
|
+
const hooksFrom = path.join(base, cfg.hooksJsonSrc);
|
|
351
|
+
if (fs.existsSync(hooksFrom)) {
|
|
352
|
+
fs.copyFileSync(hooksFrom, path.join(toolRootAbs, 'hooks.json'));
|
|
353
|
+
console.log(`Copied hooks.json → ${toolRoot}/hooks.json`);
|
|
354
|
+
copiedSteps++;
|
|
355
|
+
}
|
|
197
356
|
}
|
|
198
357
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
}
|
|
358
|
+
for (const name of cfg.toolRootFiles || []) {
|
|
359
|
+
const from = path.join(base, name);
|
|
360
|
+
if (fs.existsSync(from)) {
|
|
361
|
+
fs.copyFileSync(from, path.join(toolRootAbs, name));
|
|
362
|
+
console.log(`Copied ${name} → ${toolRoot}/${name}`);
|
|
363
|
+
copiedSteps++;
|
|
206
364
|
}
|
|
207
365
|
}
|
|
208
366
|
} catch (err) {
|
|
@@ -210,66 +368,95 @@ function cmdInit(tool, preset) {
|
|
|
210
368
|
console.error(`init failed: ${msg}`);
|
|
211
369
|
process.exit(1);
|
|
212
370
|
}
|
|
371
|
+
|
|
372
|
+
if (copiedSteps === 0) {
|
|
373
|
+
console.error(`init failed: preset "${presetName}" had no files to copy from ${base}`);
|
|
374
|
+
process.exit(1);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
if (!fs.existsSync(toolRootAbs)) {
|
|
378
|
+
console.error(`init failed: ${toolRootAbs} was not created`);
|
|
379
|
+
process.exit(1);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
console.log(`Done. ${toolRoot} installed at ${toolRootAbs} (preset: ${presetName})`);
|
|
213
383
|
}
|
|
214
384
|
|
|
215
|
-
function cmdClean(tool) {
|
|
385
|
+
function cmdClean(tool, cwdOption) {
|
|
216
386
|
const cfg = PRESETS[tool];
|
|
217
387
|
if (!cfg) {
|
|
218
388
|
console.error(`Unknown tool: ${tool}. Use cursor or claude.`);
|
|
219
389
|
process.exit(1);
|
|
220
390
|
}
|
|
221
|
-
const cwd =
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
return;
|
|
226
|
-
}
|
|
391
|
+
const cwd = resolveTargetCwd(cwdOption);
|
|
392
|
+
const toolRoot = tool === 'cursor' ? '.cursor' : '.claude';
|
|
393
|
+
const removedParts = [cfg.rulesDir, cfg.commandsDir];
|
|
394
|
+
|
|
227
395
|
removeDirIfExists(path.join(cwd, cfg.rulesDir));
|
|
228
396
|
removeDirIfExists(path.join(cwd, cfg.commandsDir));
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
)
|
|
397
|
+
|
|
398
|
+
const optionalDirs = getOptionalDirs(cfg);
|
|
399
|
+
for (const name of optionalDirs) {
|
|
400
|
+
removeDirIfExists(path.join(cwd, toolRoot, name));
|
|
401
|
+
removedParts.push(`${toolRoot}/${name}`);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
if (cfg.claudeMdSrc) {
|
|
405
|
+
removeFileIfExists(path.join(cwd, toolRoot, 'CLAUDE.md'));
|
|
406
|
+
removedParts.push(`${toolRoot}/CLAUDE.md`);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
if (cfg.hooksJsonSrc) {
|
|
410
|
+
removeFileIfExists(path.join(cwd, toolRoot, 'hooks.json'));
|
|
411
|
+
removedParts.push(`${toolRoot}/hooks.json`);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
for (const name of cfg.toolRootFiles || []) {
|
|
415
|
+
removeFileIfExists(path.join(cwd, toolRoot, name));
|
|
416
|
+
removedParts.push(`${toolRoot}/${name}`);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
console.log(`Removed ${removedParts.join(', ')} (if present)`);
|
|
242
420
|
}
|
|
243
421
|
|
|
244
422
|
function main() {
|
|
245
423
|
const argv = process.argv.slice(2);
|
|
246
|
-
if (argv.length === 0
|
|
424
|
+
if (argv.length === 0) {
|
|
247
425
|
printHelp();
|
|
248
426
|
process.exit(0);
|
|
249
427
|
}
|
|
250
428
|
|
|
251
429
|
const parsed = parseArgs(argv);
|
|
252
|
-
|
|
430
|
+
if (parsed.help) {
|
|
431
|
+
printHelp();
|
|
432
|
+
process.exit(0);
|
|
433
|
+
}
|
|
253
434
|
|
|
254
435
|
if (parsed.presetError) {
|
|
255
436
|
console.error(parsed.presetError);
|
|
256
437
|
process.exit(1);
|
|
257
438
|
}
|
|
439
|
+
if (parsed.cwdError) {
|
|
440
|
+
console.error(parsed.cwdError);
|
|
441
|
+
process.exit(1);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
const { command, tool, preset } = normalizeInitClean(parsed);
|
|
258
445
|
|
|
259
446
|
if (command === 'init') {
|
|
260
|
-
if (!tool) {
|
|
261
|
-
console.error('Missing
|
|
447
|
+
if (!tool || !TOOLS.has(tool)) {
|
|
448
|
+
console.error('Missing or invalid tool. Use: init cursor|claude [--preset next]');
|
|
262
449
|
process.exit(1);
|
|
263
450
|
}
|
|
264
|
-
cmdInit(tool, parsed.
|
|
451
|
+
cmdInit(tool, preset, parsed.cwd);
|
|
265
452
|
return;
|
|
266
453
|
}
|
|
267
454
|
if (command === 'clean') {
|
|
268
|
-
if (!tool) {
|
|
269
|
-
console.error('Missing
|
|
455
|
+
if (!tool || !TOOLS.has(tool)) {
|
|
456
|
+
console.error('Missing or invalid tool. Use: clean cursor|claude');
|
|
270
457
|
process.exit(1);
|
|
271
458
|
}
|
|
272
|
-
cmdClean(tool);
|
|
459
|
+
cmdClean(tool, parsed.cwd);
|
|
273
460
|
return;
|
|
274
461
|
}
|
|
275
462
|
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bonesofspring/ai-rules",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
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
|
],
|