codebyplan 1.13.0 → 1.13.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.
Files changed (28) hide show
  1. package/dist/cli.js +2337 -1701
  2. package/package.json +2 -2
  3. package/templates/github-workflows/publish.yml +207 -0
  4. package/templates/hooks/README.md +3 -19
  5. package/templates/hooks/cbp-test-hooks.sh +1 -9
  6. package/templates/hooks/hooks.json +0 -11
  7. package/templates/settings.project.base.json +154 -3
  8. package/templates/skills/cbp-build-cc-settings/SKILL.md +2 -0
  9. package/templates/skills/cbp-build-cc-settings/reference/cbp-permission-policy.md +48 -0
  10. package/templates/skills/cbp-checkpoint-end/SKILL.md +7 -0
  11. package/templates/skills/cbp-setup-eslint/SKILL.md +4 -3
  12. package/templates/skills/cbp-setup-eslint/reference/base.md +44 -55
  13. package/templates/skills/cbp-setup-eslint/reference/cli.md +43 -36
  14. package/templates/skills/cbp-setup-eslint/reference/e2e.md +57 -47
  15. package/templates/skills/cbp-setup-eslint/reference/jest.md +22 -38
  16. package/templates/skills/cbp-setup-eslint/reference/nestjs.md +39 -40
  17. package/templates/skills/cbp-setup-eslint/reference/nextjs.md +39 -40
  18. package/templates/skills/cbp-setup-eslint/reference/node.md +25 -54
  19. package/templates/skills/cbp-setup-eslint/reference/react-native.md +33 -37
  20. package/templates/skills/cbp-setup-eslint/reference/react.md +33 -58
  21. package/templates/skills/cbp-setup-eslint/reference/tailwind.md +45 -49
  22. package/templates/skills/cbp-setup-eslint/reference/testing-react.md +28 -37
  23. package/templates/skills/cbp-setup-eslint/reference/vitest.md +25 -45
  24. package/templates/skills/cbp-ship/reference/versioning.md +31 -3
  25. package/templates/skills/cbp-ship-configure/SKILL.md +16 -36
  26. package/templates/skills/cbp-ship-configure/reference/npm-package.md +15 -6
  27. package/templates/skills/cbp-ship-main/SKILL.md +4 -0
  28. package/templates/hooks/cbp-notify.sh +0 -68
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codebyplan",
3
- "version": "1.13.0",
3
+ "version": "1.13.4",
4
4
  "description": "CLI for CodeByPlan — AI-powered development planning and tracking",
5
5
  "type": "module",
6
6
  "bin": {
@@ -33,7 +33,7 @@
33
33
  "homepage": "https://codebyplan.com",
34
34
  "repository": {
35
35
  "type": "git",
36
- "url": "https://github.com/codebyplan/codebyplan.git",
36
+ "url": "https://github.com/midevyou/codebyplan.git",
37
37
  "directory": "packages/codebyplan-package"
38
38
  },
39
39
  "license": "MIT",
@@ -0,0 +1,207 @@
1
+ # Generated by: codebyplan scaffold-publish-workflow
2
+ #
3
+ # This workflow publishes the codebyplan npm package on every merge to main
4
+ # where the committed package.json version exceeds the version currently on npm.
5
+ # No release PR, no conventional-commit parsing — the version committed in the
6
+ # feat branch is the version that ships.
7
+ #
8
+ # Two values a consuming repo must adjust:
9
+ # 1. paths: — set to the package directory whose package.json drives versioning
10
+ # (current value: 'packages/codebyplan-package/**')
11
+ # 2. npm view <package-name> — replace `codebyplan` with the actual package name
12
+ # in the "Check version vs published" step
13
+ #
14
+ # Everything else (OIDC auth, pnpm 10.12.4, Node 20, build:npm → publish) is
15
+ # intentionally generic and works as-is for any single-package npm publish.
16
+
17
+ name: Publish codebyplan to npm
18
+
19
+ on:
20
+ push:
21
+ branches:
22
+ - main
23
+ paths:
24
+ - "packages/codebyplan-package/**"
25
+ workflow_dispatch:
26
+ inputs:
27
+ dry_run:
28
+ description: "Print what would be published without actually publishing"
29
+ type: boolean
30
+ default: false
31
+
32
+ permissions:
33
+ contents: write
34
+ id-token: write
35
+
36
+ jobs:
37
+ check-version:
38
+ name: Check if publish needed
39
+ runs-on: ubuntu-latest
40
+ outputs:
41
+ should_publish: ${{ steps.check.outputs.should_publish }}
42
+ version: ${{ steps.check.outputs.version }}
43
+ steps:
44
+ - name: Checkout
45
+ uses: actions/checkout@v4
46
+
47
+ - name: Check version vs published
48
+ id: check
49
+ run: |
50
+ VERSION=$(jq -r '.version' packages/codebyplan-package/package.json)
51
+ if [ -z "$VERSION" ] || [ "$VERSION" = "null" ]; then
52
+ echo "ERROR: could not read .version from packages/codebyplan-package/package.json"
53
+ exit 1
54
+ fi
55
+ echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
56
+
57
+ # Pre-release versions (e.g. 1.2.3-beta.1) must never auto-publish to the
58
+ # 'latest' dist-tag — sort -V is not semver-aware for pre-release suffixes,
59
+ # and this workflow always publishes to latest. Publish pre-releases
60
+ # manually with `npm publish --tag <pre-id>`. The version core (X.Y.Z) has
61
+ # no hyphen, so any '-' marks a pre-release.
62
+ case "$VERSION" in
63
+ *-*)
64
+ echo "VERSION=${VERSION} is a pre-release — skipping auto-publish."
65
+ echo "should_publish=false" >> "$GITHUB_OUTPUT"
66
+ exit 0
67
+ ;;
68
+ esac
69
+
70
+ # Manual dispatch: always publish (recovery / forced re-publish path).
71
+ if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
72
+ echo "Manual dispatch — skipping gt check, will publish."
73
+ echo "should_publish=true" >> "$GITHUB_OUTPUT"
74
+ exit 0
75
+ fi
76
+
77
+ # Push path: compare committed version against the npm registry.
78
+ # Distinguish "never published" (E404 → first publish) from a transient
79
+ # registry/network error (abort rather than blindly publish).
80
+ NPM_OUT=$(npm view codebyplan version 2>&1)
81
+ NPM_EXIT=$?
82
+ if [ "$NPM_EXIT" -ne 0 ]; then
83
+ if echo "$NPM_OUT" | grep -q "E404"; then
84
+ echo "Package not yet published — first publish."
85
+ echo "should_publish=true" >> "$GITHUB_OUTPUT"
86
+ exit 0
87
+ fi
88
+ echo "ERROR: npm view failed (exit ${NPM_EXIT}): ${NPM_OUT}"
89
+ exit 1
90
+ fi
91
+ PUBLISHED="$NPM_OUT"
92
+
93
+ # sort -V: version-aware sort. If VERSION sorts AFTER PUBLISHED, it is greater.
94
+ GREATER=$(printf '%s\n%s\n' "$PUBLISHED" "$VERSION" | sort -V | tail -n1)
95
+ if [ "$GREATER" = "$VERSION" ] && [ "$VERSION" != "$PUBLISHED" ]; then
96
+ echo "VERSION=${VERSION} > PUBLISHED=${PUBLISHED} — will publish."
97
+ echo "should_publish=true" >> "$GITHUB_OUTPUT"
98
+ else
99
+ echo "VERSION=${VERSION} <= PUBLISHED=${PUBLISHED} — skipping publish."
100
+ echo "should_publish=false" >> "$GITHUB_OUTPUT"
101
+ fi
102
+
103
+ publish-codebyplan:
104
+ name: Publish to npm (OIDC)
105
+ needs: check-version
106
+ if: needs.check-version.outputs.should_publish == 'true'
107
+ runs-on: ubuntu-latest
108
+ permissions:
109
+ # OIDC token for npm Trusted Publishing — no long-lived NPM_TOKEN needed.
110
+ id-token: write
111
+ contents: read
112
+ steps:
113
+ - uses: actions/checkout@v4
114
+
115
+ - name: Setup pnpm
116
+ uses: pnpm/action-setup@v4
117
+ with:
118
+ version: 10.12.4
119
+
120
+ # Deliberately NO registry-url: actions/setup-node would write an
121
+ # `_authToken=${NODE_AUTH_TOKEN}` line into .npmrc, and that (empty) token
122
+ # shadows OIDC trusted publishing — npm uses the token path and gets E404
123
+ # instead of doing the OIDC exchange. publishConfig.registry handles the
124
+ # target registry for `npm publish`.
125
+ - name: Setup Node
126
+ uses: actions/setup-node@v4
127
+ with:
128
+ node-version: 20
129
+ cache: pnpm
130
+
131
+ - name: Install dependencies
132
+ run: pnpm install --frozen-lockfile
133
+
134
+ - name: Build packages/codebyplan-package
135
+ working-directory: packages/codebyplan-package
136
+ run: pnpm build:npm
137
+
138
+ # npm Trusted Publishing (OIDC) requires npm >= 11.5.1; Node 20 ships npm 10.x.
139
+ - name: Upgrade npm for trusted publishing
140
+ run: |
141
+ npm install -g npm@latest
142
+ npm --version
143
+ echo "OIDC token request URL present: ${ACTIONS_ID_TOKEN_REQUEST_URL:+yes}"
144
+
145
+ - name: Dry-run check
146
+ if: ${{ github.event_name == 'workflow_dispatch' && inputs.dry_run == true }}
147
+ working-directory: packages/codebyplan-package
148
+ run: |
149
+ echo "dry_run=true — skipping actual publish."
150
+ echo "Would publish: codebyplan@${{ needs.check-version.outputs.version }}"
151
+
152
+ # No NODE_AUTH_TOKEN: npm >= 11.5.1 exchanges the GitHub OIDC token for a
153
+ # short-lived publish token. Requires a Trusted Publisher configured for
154
+ # this repo + workflow on npmjs.com.
155
+ #
156
+ # NO --provenance by default: npm provenance attestation only supports
157
+ # PUBLIC source repositories (the registry returns E422 "Unsupported
158
+ # source repository visibility: private" otherwise). This works for both
159
+ # public and private repos. If your source repo is PUBLIC and you want
160
+ # supply-chain attestation, add `--provenance` to the command below.
161
+ - name: Publish to npm
162
+ if: ${{ github.event_name != 'workflow_dispatch' || inputs.dry_run != true }}
163
+ working-directory: packages/codebyplan-package
164
+ run: npm publish --access public
165
+
166
+ tag-and-release:
167
+ name: Tag + GitHub release
168
+ needs: [check-version, publish-codebyplan]
169
+ if: |
170
+ needs.check-version.outputs.should_publish == 'true' &&
171
+ needs.publish-codebyplan.result == 'success' &&
172
+ !(github.event_name == 'workflow_dispatch' && inputs.dry_run == true)
173
+ runs-on: ubuntu-latest
174
+ permissions:
175
+ contents: write
176
+ steps:
177
+ - name: Checkout
178
+ uses: actions/checkout@v4
179
+
180
+ - name: Create tag and release (idempotent)
181
+ env:
182
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
183
+ VERSION: ${{ needs.check-version.outputs.version }}
184
+ run: |
185
+ TAG="v${VERSION}"
186
+
187
+ # Idempotent: skip tag creation if it already exists.
188
+ if git ls-remote --tags origin "refs/tags/${TAG}" | grep -q "${TAG}"; then
189
+ echo "Tag ${TAG} already exists — skipping tag creation."
190
+ else
191
+ git config user.name "github-actions[bot]"
192
+ git config user.email "github-actions[bot]@users.noreply.github.com"
193
+ git tag "${TAG}"
194
+ git push origin "${TAG}"
195
+ echo "Created and pushed tag ${TAG}."
196
+ fi
197
+
198
+ # Create GitHub release (idempotent: gh release create fails if exists; check first).
199
+ if gh release view "${TAG}" > /dev/null 2>&1; then
200
+ echo "GitHub release ${TAG} already exists — skipping."
201
+ else
202
+ gh release create "${TAG}" \
203
+ --title "codebyplan v${VERSION}" \
204
+ --notes "codebyplan v${VERSION} — published to npm: https://www.npmjs.com/package/codebyplan/v/${VERSION} (install: npm install -g codebyplan@${VERSION})" \
205
+ --latest
206
+ echo "Created GitHub release ${TAG}."
207
+ fi
@@ -2,7 +2,7 @@
2
2
 
3
3
  The `codebyplan` npm package ships a small, portable set of Claude Code hooks. They run in your project, use only generic primitives (`git rev-parse`, `${CLAUDE_PROJECT_DIR}`, `${CLAUDE_PLUGIN_ROOT}`), and degrade gracefully (exit 0) when their preconditions aren't met.
4
4
 
5
- Hook registration lives in [`hooks/hooks.json`](./hooks.json) — PreToolUse, PostToolUse, and Notification events are wired. (`SessionStart`, `SessionEnd`, `Stop`, and `SubagentStop` are also schema-permitted but unused here.)
5
+ Hook registration lives in [`hooks/hooks.json`](./hooks.json) — PreToolUse and PostToolUse events are wired. (`Notification`, `SessionStart`, `SessionEnd`, `Stop`, and `SubagentStop` are also schema-permitted but unused here.)
6
6
 
7
7
  **`cbp-statusline.sh` is auto-wired via `settings.project.base.json`.** The `statusLine` block is shipped inside `templates/settings.project.base.json` and merged into the consumer's `.claude/settings.json` automatically by `codebyplan claude install` (and on every `codebyplan claude update`). No manual copy-paste is required.
8
8
 
@@ -176,22 +176,6 @@ Walks up from the edited file to the nearest `package.json` and uses that packag
176
176
 
177
177
  ---
178
178
 
179
- ### `notify.sh` — Notification, matcher `*`
180
-
181
- Sends a desktop notification when Claude Code emits a notification event (waiting for input, task complete, etc.). Title is `[<project-name>] Claude Code`; body is the notification message; clicking the notification focuses VS Code at the project directory (macOS only).
182
-
183
- **Cross-platform graceful skip**: exits 0 silently when `terminal-notifier` is not on `$PATH`. Linux, Windows, and macOS hosts without Homebrew see a no-op — no errors, no warnings.
184
-
185
- **VS Code click action**: only attached when running on macOS (`$OSTYPE` matches `darwin*`) AND the `code` CLI is on `$PATH`. On other hosts the notification still fires but is non-clickable.
186
-
187
- **Install hint** (macOS): `brew install terminal-notifier`. On other platforms the hook is a no-op — substitute your own notification mechanism via a settings.json override if desired.
188
-
189
- **Blocks vs warns**: never blocks — exit 0 always. Notification hooks must never block Claude.
190
-
191
- **Opt out**: settings.json override or plugin disable.
192
-
193
- ---
194
-
195
179
  ### `auto-test-hooks.sh` — PostToolUse, matcher `Edit|Write`
196
180
 
197
181
  Triggers `test-hooks.sh` automatically when any `*/hooks/*.sh` file is edited. Catches accidental breakage of the plugin's own hooks (or your project's `.claude/hooks/` if you author your own) at edit time, before the broken hook runs against future tool calls.
@@ -244,9 +228,9 @@ After a `complete_round` MCP call succeeds, reconciles the round's `files_change
244
228
 
245
229
  ### `test-hooks.sh` — invoked by `auto-test-hooks.sh`
246
230
 
247
- Test suite for the plugin's 10 registered hooks. Runs two passes:
231
+ Test suite for the plugin's 9 registered hooks. Runs two passes:
248
232
 
249
- 1. **Header check** — every registered hook (`lint-format-on-edit`, `test-coverage-gate`, `pre-commit-quality-gate`, `maestro-yaml-validate`, `notify`, `auto-test-hooks`, `mcp-migration-guard`, `validate-git-stash-deny`, `cbp-mcp-round-sync`) carries the required `# Hook:` and `# Purpose:` header comments. `statusline` uses its own `# Claude Code Status Line` marker.
233
+ 1. **Header check** — every registered hook (`lint-format-on-edit`, `test-coverage-gate`, `pre-commit-quality-gate`, `maestro-yaml-validate`, `auto-test-hooks`, `mcp-migration-guard`, `validate-git-stash-deny`, `cbp-mcp-round-sync`) carries the required `# Hook:` and `# Purpose:` header comments. `statusline` uses its own `# Claude Code Status Line` marker.
250
234
  2. **Functional smoke tests** — each hook is invoked with synthetic stdin matching its fast-path / graceful-degrade input; all must exit 0.
251
235
 
252
236
  Not in `hooks.json` — invoked indirectly via `auto-test-hooks.sh` on hook edits, or directly via `bash ${CLAUDE_PLUGIN_ROOT}/hooks/test-hooks.sh`.
@@ -62,7 +62,7 @@ for hook_file in "$HOOKS_DIR"/*.sh; do
62
62
 
63
63
  # Check for header comments (required for documentation generation).
64
64
  # Accept either marker convention used across the plugin's hooks:
65
- # - "# Hook:" + "# Purpose:" (used by notify, auto-test-hooks, etc.)
65
+ # - "# Hook:" + "# Purpose:" (used by auto-test-hooks, etc.)
66
66
  # - "# @event:" + a description line (used by maestro-yaml-validate, etc.)
67
67
  if (grep -q '^# Hook:' "$hook_file" && grep -q '^# Purpose:' "$hook_file") \
68
68
  || grep -q '^# @event:' "$hook_file"; then
@@ -77,14 +77,6 @@ echo ""
77
77
  # ===== FUNCTIONAL SMOKE TESTS =====
78
78
  echo "## Functional Smoke Tests"
79
79
 
80
- # cbp-notify.sh — graceful-degrade: exit 0 whether or not terminal-notifier is installed
81
- ACTUAL_EXIT=$(echo '{"message":"test","cwd":"/tmp"}' | bash "$HOOKS_DIR/cbp-notify.sh" >/dev/null 2>&1; echo $?)
82
- if [ "$ACTUAL_EXIT" = "0" ]; then
83
- test_result "cbp-notify.sh graceful-degrade exits 0" "passed" "passed"
84
- else
85
- test_result "cbp-notify.sh graceful-degrade exits 0" "passed" "failed"
86
- fi
87
-
88
80
  # cbp-lint-format-on-edit.sh — graceful-degrade: CLAUDE_PROJECT_DIR unset → exit 0
89
81
  if [ ! -f "$HOOKS_DIR/cbp-lint-format-on-edit.sh" ]; then
90
82
  test_result "cbp-lint-format-on-edit.sh present" "passed" "missing"
@@ -60,17 +60,6 @@
60
60
  }
61
61
  ]
62
62
  }
63
- ],
64
- "Notification": [
65
- {
66
- "matcher": "*",
67
- "hooks": [
68
- {
69
- "type": "command",
70
- "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/cbp-notify.sh"
71
- }
72
- ]
73
- }
74
63
  ]
75
64
  }
76
65
  }
@@ -13,7 +13,9 @@
13
13
  "spinnerTipsEnabled": true,
14
14
  "terminalProgressBarEnabled": true,
15
15
  "viewMode": "default",
16
- "worktree": { "baseRef": "fresh" },
16
+ "worktree": {
17
+ "baseRef": "fresh"
18
+ },
17
19
  "autoScrollEnabled": true,
18
20
  "cleanupPeriodDays": 30,
19
21
  "includeGitInstructions": true,
@@ -45,10 +47,159 @@
45
47
  "Bash(pnpm install:*)",
46
48
  "Bash(npm install:*)",
47
49
  "Bash(npm i:*)",
48
- "Bash(npx add:*)"
50
+ "Bash(npx add:*)",
51
+ "Skill(cbp-checkpoint-end)",
52
+ "Skill(cbp-ship)",
53
+ "Skill(cbp-ship-main)",
54
+ "mcp__codebyplan__accept_invite",
55
+ "mcp__codebyplan__change_role",
56
+ "mcp__codebyplan__create_launch",
57
+ "mcp__codebyplan__update_launch",
58
+ "mcp__codebyplan__delete_launch",
59
+ "mcp__codebyplan__create_repo",
60
+ "mcp__codebyplan__delete_session_log",
61
+ "mcp__codebyplan__delete_worktree",
62
+ "mcp__codebyplan__invite_member",
63
+ "mcp__codebyplan__remove_member",
64
+ "mcp__codebyplan__revoke_invite",
65
+ "mcp__codebyplan__release_assignment",
66
+ "Bash(codebyplan setup:*)",
67
+ "Bash(npx codebyplan setup:*)",
68
+ "Bash(codebyplan login:*)",
69
+ "Bash(npx codebyplan login:*)",
70
+ "Bash(codebyplan logout:*)",
71
+ "Bash(npx codebyplan logout:*)",
72
+ "Bash(codebyplan upgrade-auth:*)",
73
+ "Bash(npx codebyplan upgrade-auth:*)",
74
+ "Bash(codebyplan config:*)",
75
+ "Bash(npx codebyplan config:*)",
76
+ "Bash(codebyplan branch:*)",
77
+ "Bash(npx codebyplan branch:*)",
78
+ "Bash(codebyplan ship:*)",
79
+ "Bash(npx codebyplan ship:*)",
80
+ "Bash(codebyplan claude:*)",
81
+ "Bash(npx codebyplan claude:*)"
82
+ ],
83
+ "allow": [
84
+ "Skill(cbp-build-cc-agent)",
85
+ "Skill(cbp-build-cc-claude-file)",
86
+ "Skill(cbp-build-cc-memory)",
87
+ "Skill(cbp-build-cc-mode)",
88
+ "Skill(cbp-build-cc-rule)",
89
+ "Skill(cbp-build-cc-settings)",
90
+ "Skill(cbp-build-cc-skill)",
91
+ "Skill(cbp-checkpoint-check)",
92
+ "Skill(cbp-checkpoint-complete)",
93
+ "Skill(cbp-checkpoint-create)",
94
+ "Skill(cbp-checkpoint-plan)",
95
+ "Skill(cbp-checkpoint-start)",
96
+ "Skill(cbp-checkpoint-update)",
97
+ "Skill(cbp-frontend-a11y)",
98
+ "Skill(cbp-frontend-design)",
99
+ "Skill(cbp-frontend-ui)",
100
+ "Skill(cbp-frontend-ux)",
101
+ "Skill(cbp-git-branch-feat-create)",
102
+ "Skill(cbp-git-commit)",
103
+ "Skill(cbp-git-worktree-create)",
104
+ "Skill(cbp-git-worktree-remove)",
105
+ "Skill(cbp-merge-main)",
106
+ "Skill(cbp-refresh-infra)",
107
+ "Skill(cbp-round-check)",
108
+ "Skill(cbp-round-end)",
109
+ "Skill(cbp-round-execute)",
110
+ "Skill(cbp-round-input)",
111
+ "Skill(cbp-round-start)",
112
+ "Skill(cbp-round-update)",
113
+ "Skill(cbp-session-end)",
114
+ "Skill(cbp-session-start)",
115
+ "Skill(cbp-setup-e2e)",
116
+ "Skill(cbp-setup-eslint)",
117
+ "Skill(cbp-ship-configure)",
118
+ "Skill(cbp-supabase-branch-check)",
119
+ "Skill(cbp-supabase-migrate)",
120
+ "Skill(cbp-supabase-setup)",
121
+ "Skill(cbp-task-check)",
122
+ "Skill(cbp-task-complete)",
123
+ "Skill(cbp-task-create)",
124
+ "Skill(cbp-task-start)",
125
+ "Skill(cbp-task-testing)",
126
+ "Skill(cbp-todo)",
127
+ "mcp__codebyplan__get_checkpoints",
128
+ "mcp__codebyplan__get_current_task",
129
+ "mcp__codebyplan__get_eslint_presets",
130
+ "mcp__codebyplan__get_eslint_repo_config",
131
+ "mcp__codebyplan__get_file_changes",
132
+ "mcp__codebyplan__get_launch",
133
+ "mcp__codebyplan__get_launches",
134
+ "mcp__codebyplan__get_library_doc_job",
135
+ "mcp__codebyplan__get_next_action",
136
+ "mcp__codebyplan__get_repos",
137
+ "mcp__codebyplan__get_rounds",
138
+ "mcp__codebyplan__get_server_config",
139
+ "mcp__codebyplan__get_session_log",
140
+ "mcp__codebyplan__get_session_logs",
141
+ "mcp__codebyplan__get_session_state",
142
+ "mcp__codebyplan__get_task_template",
143
+ "mcp__codebyplan__get_task_templates",
144
+ "mcp__codebyplan__get_tasks",
145
+ "mcp__codebyplan__get_todos",
146
+ "mcp__codebyplan__get_work_plan",
147
+ "mcp__codebyplan__get_worktrees",
148
+ "mcp__codebyplan__list_tech_stack_sync_sessions",
149
+ "mcp__codebyplan__get_chunk",
150
+ "mcp__codebyplan__list_migrations",
151
+ "mcp__codebyplan__lookup_symbol",
152
+ "mcp__codebyplan__resolve_library_id",
153
+ "mcp__codebyplan__search_chunks",
154
+ "mcp__codebyplan__health_check",
155
+ "mcp__codebyplan__add_library",
156
+ "mcp__codebyplan__add_round",
157
+ "mcp__codebyplan__complete_round",
158
+ "mcp__codebyplan__update_round",
159
+ "mcp__codebyplan__complete_checkpoint",
160
+ "mcp__codebyplan__create_checkpoint",
161
+ "mcp__codebyplan__update_checkpoint",
162
+ "mcp__codebyplan__complete_task",
163
+ "mcp__codebyplan__create_task",
164
+ "mcp__codebyplan__update_task",
165
+ "mcp__codebyplan__create_session_log",
166
+ "mcp__codebyplan__update_session_log",
167
+ "mcp__codebyplan__update_session_state",
168
+ "mcp__codebyplan__create_worktree",
169
+ "mcp__codebyplan__flag_stale_chunk",
170
+ "mcp__codebyplan__list_invites",
171
+ "mcp__codebyplan__list_members",
172
+ "mcp__codebyplan__update_eslint_repo_config",
173
+ "mcp__codebyplan__update_server_config",
174
+ "mcp__codebyplan__update_task_template",
175
+ "Bash(codebyplan whoami:*)",
176
+ "Bash(npx codebyplan whoami:*)",
177
+ "Bash(codebyplan resolve-worktree:*)",
178
+ "Bash(npx codebyplan resolve-worktree:*)",
179
+ "Bash(codebyplan statusline:*)",
180
+ "Bash(npx codebyplan statusline:*)",
181
+ "Bash(codebyplan ports:*)",
182
+ "Bash(npx codebyplan ports:*)",
183
+ "Bash(codebyplan tech-stack:*)",
184
+ "Bash(npx codebyplan tech-stack:*)",
185
+ "Bash(codebyplan eslint:*)",
186
+ "Bash(npx codebyplan eslint:*)",
187
+ "Bash(codebyplan round:*)",
188
+ "Bash(npx codebyplan round:*)",
189
+ "Bash(codebyplan help:*)",
190
+ "Bash(npx codebyplan help:*)",
191
+ "Bash(codebyplan --version:*)",
192
+ "Bash(npx codebyplan --version:*)",
193
+ "Bash(codebyplan bump:*)",
194
+ "Bash(npx codebyplan bump:*)",
195
+ "Bash(codebyplan scaffold-publish-workflow:*)",
196
+ "Bash(npx codebyplan scaffold-publish-workflow:*)"
49
197
  ]
50
198
  },
51
- "attribution": { "commit": "", "pr": "" },
199
+ "attribution": {
200
+ "commit": "",
201
+ "pr": ""
202
+ },
52
203
  "showClearContextOnPlanAccept": false,
53
204
  "syntaxHighlightingDisabled": false
54
205
  }
@@ -76,6 +76,8 @@ Rules follow `Tool` or `Tool(specifier)`. Evaluated in order: **deny → ask →
76
76
 
77
77
  Full patterns: [reference/permission-rules.md](reference/permission-rules.md).
78
78
 
79
+ CBP-specific policy — which `codebyplan` CLI commands, `mcp__codebyplan__*` tools, and `/cbp-*` skills are pre-categorized `allow` vs `ask`, why, and how `codebyplan claude install/update` auto-populates them: [reference/cbp-permission-policy.md](reference/cbp-permission-policy.md).
80
+
79
81
  Common examples:
80
82
 
81
83
  ```json
@@ -0,0 +1,48 @@
1
+ # CodeByPlan Permission Policy
2
+
3
+ How the CodeByPlan surface — CLI commands, `mcp__codebyplan__*` tools, and `/cbp-*` skills — is pre-categorized into `permissions.allow` / `permissions.ask` in the settings the `codebyplan` package ships. Authored by CHK-157.
4
+
5
+ ## Where it lives + how it propagates
6
+
7
+ The curated arrays live in `templates/settings.project.base.json` inside the `codebyplan` npm package. `codebyplan claude install` and `codebyplan claude update` **union-merge** those `allow` / `ask` / `deny` arrays into the consuming repo's `.claude/settings.json` (the merge engine is `mergeBaseSettingsIntoSettings` in `src/lib/settings-merge.ts`); `codebyplan claude uninstall` strips them back out (`stripBaseSettingsFromSettings`). A user's own permission entries are preserved across all three operations (union on merge, membership-filter on strip).
8
+
9
+ No new plumbing was added — the categorization is **data** in the base template plus the completeness guard described below.
10
+
11
+ ## The interaction with `bypassPermissions`
12
+
13
+ CBP repos ship `permissions.defaultMode: "bypassPermissions"`. Under that mode, routine tool calls are auto-allowed without prompting — so the `allow` list is mostly an **explicit, documented enumeration** (and it takes effect verbatim if a repo ever lowers the mode). The harness still honors `ask` and `deny` under bypass, which is why the base settings have always carried an `ask` list (`git push --force`, `pnpm add`, …). Therefore:
14
+
15
+ - **`ask` is the operative "decide carefully" surface** — the deliberate stop-and-confirm set.
16
+ - **`deny`** is the hard block (dangerous `rm -rf` variants).
17
+ - **`allow`** is the explicit full enumeration of the rest of the CBP surface.
18
+
19
+ Precedence is `deny > ask > allow`; arrays union across scopes (managed/user/project/local).
20
+
21
+ ## The three tiers
22
+
23
+ ### `allow` — the autonomous workflow surface
24
+
25
+ - **All `/cbp-*` skills** except the production-shipment trio below. Invoking a skill is the intended mode of operation; the gated side effects happen inside via the Bash/MCP tools the skill calls, which carry their own tiering.
26
+ - **All `mcp__codebyplan__*` reads** (`get_*`, `list_*`, `search_*`, `health_check`, `lookup_symbol`, `resolve_library_id`, `get_chunk`).
27
+ - **Routine workflow-write MCP tools** the pipeline calls many times per task: create/update/complete checkpoint, task, and round; session log + session-state writes; `create_worktree`, `add_library`, `flag_stale_chunk`, `update_server_config`, `update_eslint_repo_config`, `update_task_template`. Gating these with `ask` would make the autonomous workflow unusable.
28
+ - **Read/safe CLI commands** (both `codebyplan X` and `npx codebyplan X`): `whoami`, `resolve-worktree`, `statusline`, `ports`, `tech-stack`, `eslint`, `round`, `help`, `--version`.
29
+
30
+ ### `ask` — the deliberate confirm-gate
31
+
32
+ - **Production-shipment skills**: `cbp-ship`, `cbp-ship-main`, `cbp-checkpoint-end` — these promote/deploy to production, so they prompt even in an otherwise auto-allowed setup.
33
+ - **Destructive / admin / external MCP tools**: `delete_session_log`, `delete_worktree`, `delete_launch`, `create_repo`, `create_launch`, `update_launch`, `release_assignment`, and the membership tools `invite_member`, `remove_member`, `change_role`, `accept_invite`, `revoke_invite`.
34
+ - **Mutating / external / clobber-risk CLI commands** (both prefixes): `setup`, `login`, `logout`, `upgrade-auth`, `config` (can overwrite committed `.codebyplan/` files), `branch` (rewrites branch config), `ship`, `claude` (`install`/`update`/`uninstall` overwrite `.claude/`).
35
+
36
+ ### `deny` — unchanged
37
+
38
+ The pre-existing dangerous-`rm -rf` blocks. This policy does not alter `deny` semantics.
39
+
40
+ ## Completeness guard (the "decide carefully" guarantee)
41
+
42
+ `src/lib/settings-permissions-completeness.test.ts` re-derives the live surface from source — skill directory names under `templates/skills/`, `registerToolWithAuthz(server, "...")` names in `packages/mcp-tools/src/tools/*.ts`, and `arg === "..."` CLI subcommands in `src/index.ts` — and fails if any item is not in exactly one tier. So a **newly-added skill, MCP tool, or CLI subcommand forces a deliberate allow-vs-ask decision** before the suite goes green; nothing slips in uncategorized. The test also round-trips the curated arrays through the install-merge and uninstall-strip engine.
43
+
44
+ When you add a skill / MCP tool / CLI subcommand, add its matching rule (`Skill(<name>)`, `mcp__codebyplan__<name>`, or `Bash(codebyplan <sub>:*)` + `Bash(npx codebyplan <sub>:*)`) to `allow` or `ask` in `templates/settings.project.base.json` — and mirror it into any dogfooding `.claude/settings.json`.
45
+
46
+ ## Scope
47
+
48
+ `scope: org-shared` — CBP-framework infrastructure that lands identically in every consuming repo via the `codebyplan` package.
@@ -30,6 +30,8 @@ Before any shipment logic, ensure the feat branch is current against main. Shipm
30
30
  2. If the skill exits with failure (offline, unresolved conflicts, user-aborted): surface the failure and STOP `/cbp-checkpoint-end` — shipment is not safe until the branch is reconciled. The user resolves and re-invokes.
31
31
  3. On clean success: continue to Step 1.
32
32
 
33
+ > **Version bumps ride this shipment automatically.** `codebyplan ship` (invoked by `/cbp-ship-main` in Step 5) patch-bumps every changed workspace package and commits `chore(release): bump versions` on the feat branch AFTER this main-sync merge and BEFORE push + PR creation — so the bump rides the same feat→main PR (no separate release PR). No manual bump step is required here; the planned bumps surface in the Step 5 report. See `cbp-ship/reference/versioning.md` (`in-branch-bump` mode).
34
+
33
35
  ### Step 1: Get Active Checkpoint
34
36
 
35
37
  Use MCP `get_current_task` with repo_id. Get the active checkpoint.
@@ -195,6 +197,7 @@ context.shipment: {
195
197
  timestamp: [ISO],
196
198
  branch_config: { base, protected },
197
199
  feat_to_base: { pr_url, merged: true/false },
200
+ version_bumps: [...], // from `codebyplan ship` bumps[] — packages patch-bumped on the feat branch this shipment
198
201
  surfaces: [...], // populated by /cbp-ship — per-surface deploy results
199
202
  skipped: [...], // populated by /cbp-ship — surfaces explicitly skipped
200
203
  stale_branches_cleaned: [list of deleted git branches],
@@ -211,6 +214,10 @@ Present summary:
211
214
  ### Branch Promotion
212
215
  - **feat -> [BASE]**: [PR URL] (merged)
213
216
 
217
+ ### Version Bumps
218
+ - [package]: [currentVersion] → [nextVersion]
219
+ (From `context.shipment.version_bumps[]` — committed as `chore(release): bump versions`; publishes on merge. Omit this section if no packages were bumped.)
220
+
214
221
  ### Runtime Surfaces (via /cbp-ship)
215
222
  | Surface | Variant | Status | URL/ID |
216
223
  | ... | ... | ... | ... |
@@ -181,13 +181,14 @@ command + which apps still need their `eslint.config.mjs` generated.
181
181
  `reference/*.md`, never silently skip
182
182
  - `codebyplan eslint init` failure is non-fatal — print the manual command and still write eslint.json
183
183
  - Atomic write (tmp + mv) — never leave eslint.json partial
184
- - Reference docs track the **latest official** flat-config setup and flag where CBP's DB
185
- presets diverge (e.g. ESLint v10 + `eslint-plugin-react-hooks@7` bundled compiler rules)
184
+ - Reference docs contain **only the official upstream ESLint setup** per stack (verbatim from each
185
+ tool's own docs) they are not CBP preset opinions. `codebyplan eslint init` generates from the DB
186
+ presets, which may differ; the reference docs are the canonical official guidance
186
187
 
187
188
  ## Additional resources
188
189
 
189
190
  - TypeScript foundation (ESLint v10 flat config): [reference/base.md](reference/base.md)
190
- - Next.js: [reference/nextjs.md](reference/nextjs.md) · React (+ Storybook): [reference/react.md](reference/react.md)
191
+ - Next.js: [reference/nextjs.md](reference/nextjs.md) · React: [reference/react.md](reference/react.md)
191
192
  - Node / Hono / Express: [reference/node.md](reference/node.md) · NestJS: [reference/nestjs.md](reference/nestjs.md)
192
193
  - CLI tools: [reference/cli.md](reference/cli.md) · Tailwind CSS: [reference/tailwind.md](reference/tailwind.md)
193
194
  - React Native / Expo: [reference/react-native.md](reference/react-native.md)