codebyplan 1.13.51 → 1.13.53
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/dist/cli.js +1776 -449
- package/package.json +1 -1
- package/templates/agents/cbp-security-agent.md +9 -1
- package/templates/agents/cbp-testing-qa-agent.md +23 -9
- package/templates/github-workflows/ci.yml +63 -0
- package/templates/github-workflows/publish.yml +8 -27
- package/templates/github-workflows/release-desktop.yml +215 -0
- package/templates/settings.project.base.json +7 -1
- package/templates/skills/cbp-build-cc-skill/SKILL.md +1 -0
- package/templates/skills/cbp-build-cc-skill/reference/fork-eligibility.md +78 -0
- package/templates/skills/cbp-build-cc-skill/reference/frontmatter-fields.md +4 -0
- package/templates/skills/cbp-checkpoint-check/SKILL.md +9 -1
- package/templates/skills/cbp-checkpoint-end/SKILL.md +5 -1
- package/templates/skills/cbp-round-check/SKILL.md +2 -0
- package/templates/skills/cbp-setup-cd/SKILL.md +291 -0
- package/templates/skills/cbp-setup-cd/reference/github-actions-cd.md +231 -0
- package/templates/skills/cbp-setup-ci/SKILL.md +175 -0
- package/templates/skills/cbp-setup-ci/reference/github-actions.md +100 -0
- package/templates/skills/cbp-ship/SKILL.md +21 -0
- package/templates/skills/cbp-standalone-task-testing/SKILL.md +11 -2
- package/templates/skills/cbp-task-testing/SKILL.md +2 -0
package/package.json
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
+
scope: org-shared
|
|
2
3
|
name: cbp-security-agent
|
|
3
4
|
description: Security review specialist. Checks for OWASP top 10 vulnerabilities, hardcoded secrets, SQL injection, XSS, CSRF, and dependency vulnerabilities.
|
|
4
5
|
tools: Read, Glob, Grep, Bash
|
|
@@ -101,7 +102,14 @@ For API routes and server actions:
|
|
|
101
102
|
|
|
102
103
|
### Phase 7: Dependency Audit
|
|
103
104
|
|
|
104
|
-
|
|
105
|
+
Resolve the audit command from `.codebyplan/ci.json`, then run from the **monorepo root** (so root-level `pnpm.overrides` are reflected):
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
CI_AUDIT_CMD=$(npx codebyplan ci resolve audit 2>/dev/null || echo "pnpm audit --json")
|
|
109
|
+
cd /path/to/monorepo/root && ${CI_AUDIT_CMD} 2>&1
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Fallback: if `.codebyplan/ci.json` is absent, `codebyplan ci resolve audit` still returns the central default (exit 0). The `|| echo` guard handles repos where the `codebyplan` binary is unavailable. Parse output and report critical/high findings.
|
|
105
113
|
|
|
106
114
|
For transitive vulnerabilities, note the standard fix path: add `"package": ">=X.Y.Z"` to `pnpm.overrides` in root `package.json`. For direct vulnerabilities, suggest bumping the dependency in the consuming package.
|
|
107
115
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
+
scope: org-shared
|
|
2
3
|
name: cbp-testing-qa-agent
|
|
3
4
|
description: Combined testing, QA generation, and default checklists. Runs build/lint/types/unit-tests/audit, generates auto QA items, applies default production checklists. Does NOT consume e2e screenshots or frontend-ui findings.
|
|
4
5
|
tools: Read, Glob, Grep, Bash, AskUserQuestion
|
|
@@ -150,6 +151,19 @@ E2E (Playwright / Maestro / WebDriverIO / XCUITest / vscode-test) is NEVER run b
|
|
|
150
151
|
|
|
151
152
|
**CRITICAL: Within your profile's allowed check set (see Profile Gate Matrix above), every applicable command MUST be executed. No skipping an in-scope check without an explicit, logged reason.**
|
|
152
153
|
|
|
154
|
+
**Step 0: Resolve check commands from ci.json (absent-fallback safe)**
|
|
155
|
+
|
|
156
|
+
After detecting `$PLATFORM` in Step 1, resolve per-category commands from `.codebyplan/ci.json`:
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
CI_BUILD_CMD=$(npx codebyplan ci resolve build --platform "$PLATFORM" 2>/dev/null)
|
|
160
|
+
CI_TYPES_CMD=$(npx codebyplan ci resolve typecheck --platform "$PLATFORM" 2>/dev/null)
|
|
161
|
+
CI_UNIT_CMD=$(npx codebyplan ci resolve unit_test --platform "$PLATFORM" 2>/dev/null)
|
|
162
|
+
CI_AUDIT_CMD=$(npx codebyplan ci resolve audit 2>/dev/null)
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Fallback: if `.codebyplan/ci.json` is absent, `codebyplan ci resolve` returns the central default command (exit 0). If the binary is unavailable, the variable is empty and the `${CI_*_CMD:-<literal>}` guards in the command cells below activate the hardcoded fallback, keeping non-migrated repos working.
|
|
166
|
+
|
|
153
167
|
**Step 1: Determine project root and platform** — read `.claude/docs/architecture/testing-matrix.md` (when present) for platform-specific commands. Find the correct app directory and detect platform:
|
|
154
168
|
|
|
155
169
|
| Signal | Platform | Unit Runner |
|
|
@@ -171,9 +185,9 @@ For each check below, you MUST:
|
|
|
171
185
|
|
|
172
186
|
| Check | Command | Hard Fail | Skip Conditions | Skip when profile= |
|
|
173
187
|
|-------|---------|-----------|-----------------|-------------------|
|
|
174
|
-
| **Build** | `cd {app_dir} && npm run build 2>&1` | YES | Only if no app code changed | claude_only, or per app-type exclusion above |
|
|
188
|
+
| **Build** | `cd {app_dir} && ${CI_BUILD_CMD:-npm run build} 2>&1` | YES | Only if no app code changed | claude_only, or per app-type exclusion above |
|
|
175
189
|
| **Lint** | `cd {app_dir} && npm run lint 2>&1` | YES | Only if no app code changed | claude_only |
|
|
176
|
-
| **Types** | `cd {app_dir} && npx tsc --noEmit 2>&1` | YES | Only if no app code changed | claude_only |
|
|
190
|
+
| **Types** | `cd {app_dir} && ${CI_TYPES_CMD:-npx tsc --noEmit} 2>&1` | YES | Only if no app code changed | claude_only |
|
|
177
191
|
|
|
178
192
|
**Lint scope expansion on config change (MANDATORY)**: when ANY entry in `files_changed[]` matches `eslint.config.*` / `.eslintrc.*` / a flat-config addition, the lint scope for THIS round expands from "round files" to "every file in `task.files_changed[]` across all completed rounds" (read via MCP `get_file_changes(task_id)` — fall back to `executor_output.files_changed` aggregated with prior-round files from `task.context.cumulative_files_changed[]` if available).
|
|
179
193
|
|
|
@@ -194,12 +208,12 @@ Run the unit-test runners detected in Step 1:
|
|
|
194
208
|
|
|
195
209
|
| Platform | Unit Command |
|
|
196
210
|
|----------|-------------|
|
|
197
|
-
| Next.js | `cd {app_dir} && npx vitest --run 2>&1` |
|
|
198
|
-
| NestJS | `cd {app_dir} && npx jest 2>&1` |
|
|
199
|
-
| Tauri | `cd {app_dir} && npx vitest --run 2>&1` AND `cd {app_dir}/src-tauri && cargo test 2>&1` |
|
|
200
|
-
| Expo | `cd {app_dir} && npx jest 2>&1` |
|
|
201
|
-
| VS Code | `cd {app_dir} && npx vitest --run 2>&1` |
|
|
202
|
-
| Package | `cd {pkg_dir} && npx vitest --run 2>&1` |
|
|
211
|
+
| Next.js | `cd {app_dir} && ${CI_UNIT_CMD:-npx vitest --run} 2>&1` |
|
|
212
|
+
| NestJS | `cd {app_dir} && ${CI_UNIT_CMD:-npx jest} 2>&1` |
|
|
213
|
+
| Tauri | `cd {app_dir} && ${CI_UNIT_CMD:-npx vitest --run} 2>&1` AND `cd {app_dir}/src-tauri && cargo test 2>&1` |
|
|
214
|
+
| Expo | `cd {app_dir} && ${CI_UNIT_CMD:-npx jest} 2>&1` |
|
|
215
|
+
| VS Code | `cd {app_dir} && ${CI_UNIT_CMD:-npx vitest --run} 2>&1` |
|
|
216
|
+
| Package | `cd {pkg_dir} && ${CI_UNIT_CMD:-npx vitest --run} 2>&1` |
|
|
203
217
|
|
|
204
218
|
**Hard fail conditions:**
|
|
205
219
|
- Unit tests: YES — when source files in files_changed
|
|
@@ -288,7 +302,7 @@ Mandatory dependency vulnerability scan:
|
|
|
288
302
|
|
|
289
303
|
> **Vulnerability fix tasks**: If the current task title matches `/GHSA-|CVE-|vulnerabilit/i`, the audit result IS the primary test. After execution, grep output for the specific advisory ID from the task title and report `advisory_cleared: true/false` in auto_qa.
|
|
290
304
|
|
|
291
|
-
1. **Execute**: `cd /path/to/monorepo/root && pnpm audit --json 2>&1`
|
|
305
|
+
1. **Execute**: Run from the monorepo root (so root-level `pnpm.overrides` are reflected): `cd /path/to/monorepo/root && ${CI_AUDIT_CMD:-pnpm audit --json} 2>&1`
|
|
292
306
|
2. **Parse** JSON output, categorize by severity: critical, high, medium, low
|
|
293
307
|
3. **Determine pass/fail**:
|
|
294
308
|
- Critical or high found → `fail`, set `totals.hard_fail = true`
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Generated by: codebyplan ci scaffold-workflow
|
|
2
|
+
#
|
|
3
|
+
# This workflow runs lint, typecheck, tests, and build on every pull request.
|
|
4
|
+
# It is intentionally generic and works as-is for any pnpm + Turborepo project.
|
|
5
|
+
#
|
|
6
|
+
# By design this gates on FULL-REPO GREEN: `pnpm turbo <task>` runs the task
|
|
7
|
+
# across every package with no `--filter`, so a shallow checkout (fetch-depth:1)
|
|
8
|
+
# is fine — git history is not needed for affected-package detection. Per-package
|
|
9
|
+
# / changed-path scoping (`scope: per_app_changed` in .codebyplan/ci.json) is
|
|
10
|
+
# applied by the local CodeByPlan round/testing skills, NOT by this workflow.
|
|
11
|
+
# Do not add turbo `--filter=[HEAD^]` here without also setting fetch-depth: 0.
|
|
12
|
+
#
|
|
13
|
+
# Two values you can adjust via `codebyplan ci scaffold-workflow`:
|
|
14
|
+
# --pnpm-version <v> pnpm version (current: {{PNPM_VERSION}})
|
|
15
|
+
# --node-version <v> Node.js version (current: {{NODE_VERSION}})
|
|
16
|
+
|
|
17
|
+
name: CI
|
|
18
|
+
|
|
19
|
+
on:
|
|
20
|
+
pull_request:
|
|
21
|
+
|
|
22
|
+
# Cancel an in-progress run when a newer commit is pushed to the same PR/ref,
|
|
23
|
+
# so superseded full-repo runs don't queue up and waste runner minutes.
|
|
24
|
+
concurrency:
|
|
25
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
26
|
+
cancel-in-progress: true
|
|
27
|
+
|
|
28
|
+
permissions:
|
|
29
|
+
contents: read
|
|
30
|
+
|
|
31
|
+
jobs:
|
|
32
|
+
ci:
|
|
33
|
+
name: Lint + typecheck + test + build
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
steps:
|
|
36
|
+
- name: Checkout
|
|
37
|
+
uses: actions/checkout@v4
|
|
38
|
+
|
|
39
|
+
- name: Setup pnpm
|
|
40
|
+
uses: pnpm/action-setup@v4
|
|
41
|
+
with:
|
|
42
|
+
version: "{{PNPM_VERSION}}"
|
|
43
|
+
|
|
44
|
+
- name: Setup Node
|
|
45
|
+
uses: actions/setup-node@v4
|
|
46
|
+
with:
|
|
47
|
+
node-version: "{{NODE_VERSION}}"
|
|
48
|
+
cache: pnpm
|
|
49
|
+
|
|
50
|
+
- name: Install dependencies
|
|
51
|
+
run: pnpm install --frozen-lockfile
|
|
52
|
+
|
|
53
|
+
- name: Lint
|
|
54
|
+
run: pnpm turbo lint
|
|
55
|
+
|
|
56
|
+
- name: Typecheck
|
|
57
|
+
run: pnpm turbo typecheck
|
|
58
|
+
|
|
59
|
+
- name: Test
|
|
60
|
+
run: pnpm turbo test
|
|
61
|
+
|
|
62
|
+
- name: Build
|
|
63
|
+
run: pnpm turbo build
|
|
@@ -1,34 +1,16 @@
|
|
|
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
|
-
# It also auto-publishes prerelease versions (e.g. 1.14.0-beta.1) from feat/**
|
|
6
|
-
# branches to a scoped dist-tag (e.g. --tag beta) — see the beta channel docs
|
|
7
|
-
# for the full workflow. No release PR, no conventional-commit parsing — the
|
|
8
|
-
# version committed in the feat branch is the version that ships.
|
|
9
|
-
#
|
|
10
|
-
# Two values a consuming repo must adjust:
|
|
11
|
-
# 1. paths: — set to the package directory whose package.json drives versioning
|
|
12
|
-
# (current value: 'packages/codebyplan-package/**')
|
|
13
|
-
# 2. npm view <package-name> — replace `codebyplan` with the actual package name
|
|
14
|
-
# in the "Check version vs published" and exact-version check steps
|
|
15
|
-
#
|
|
16
|
-
# Everything else (OIDC auth, pnpm 10.12.4, Node 20, build:npm → publish) is
|
|
17
|
-
# intentionally generic and works as-is for any single-package npm publish.
|
|
18
|
-
|
|
19
1
|
name: Publish codebyplan to npm
|
|
20
2
|
|
|
21
3
|
on:
|
|
22
4
|
push:
|
|
23
5
|
branches:
|
|
24
6
|
- main
|
|
25
|
-
-
|
|
7
|
+
- 'feat/**'
|
|
26
8
|
paths:
|
|
27
|
-
-
|
|
9
|
+
- 'packages/codebyplan-package/**'
|
|
28
10
|
workflow_dispatch:
|
|
29
11
|
inputs:
|
|
30
12
|
dry_run:
|
|
31
|
-
description:
|
|
13
|
+
description: 'Print what would be published without actually publishing'
|
|
32
14
|
type: boolean
|
|
33
15
|
default: false
|
|
34
16
|
|
|
@@ -182,7 +164,7 @@ jobs:
|
|
|
182
164
|
- name: Setup Node
|
|
183
165
|
uses: actions/setup-node@v4
|
|
184
166
|
with:
|
|
185
|
-
node-version:
|
|
167
|
+
node-version: 22
|
|
186
168
|
cache: pnpm
|
|
187
169
|
|
|
188
170
|
- name: Install dependencies
|
|
@@ -210,11 +192,10 @@ jobs:
|
|
|
210
192
|
# short-lived publish token. Requires a Trusted Publisher configured for
|
|
211
193
|
# this repo + workflow on npmjs.com.
|
|
212
194
|
#
|
|
213
|
-
# NO --provenance
|
|
214
|
-
#
|
|
215
|
-
#
|
|
216
|
-
#
|
|
217
|
-
# supply-chain attestation, add `--provenance` to the command below.
|
|
195
|
+
# NO --provenance: npm provenance attestation only supports PUBLIC source
|
|
196
|
+
# repositories (registry returns E422 "Unsupported source repository
|
|
197
|
+
# visibility: private" otherwise). This repo is private, so provenance is
|
|
198
|
+
# omitted. Re-add `--provenance` only if the source repo becomes public.
|
|
218
199
|
#
|
|
219
200
|
# --tag: routes stable publishes to "latest" and prerelease publishes to
|
|
220
201
|
# the prerelease id (e.g. "beta", "rc"). C1 guarantee: betas never land on
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
name: Release Desktop App
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
paths:
|
|
8
|
+
- "apps/desktop/**"
|
|
9
|
+
workflow_dispatch: {}
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: write
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
check-version:
|
|
16
|
+
name: Check if release needed
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
outputs:
|
|
19
|
+
should_release: ${{ steps.check.outputs.should_release }}
|
|
20
|
+
version: ${{ steps.check.outputs.version }}
|
|
21
|
+
steps:
|
|
22
|
+
- name: Checkout
|
|
23
|
+
uses: actions/checkout@v4
|
|
24
|
+
|
|
25
|
+
- name: Check version tag
|
|
26
|
+
id: check
|
|
27
|
+
run: |
|
|
28
|
+
VERSION=$(jq -r '.version' apps/desktop/src-tauri/tauri.conf.json)
|
|
29
|
+
TAG="desktop-v${VERSION}"
|
|
30
|
+
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
|
|
31
|
+
|
|
32
|
+
if git ls-remote --tags origin "refs/tags/${TAG}" | grep -q "${TAG}"; then
|
|
33
|
+
echo "Tag ${TAG} already exists - skipping release"
|
|
34
|
+
echo "should_release=false" >> "$GITHUB_OUTPUT"
|
|
35
|
+
else
|
|
36
|
+
echo "Tag ${TAG} does not exist - will release"
|
|
37
|
+
echo "should_release=true" >> "$GITHUB_OUTPUT"
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
build:
|
|
41
|
+
needs: check-version
|
|
42
|
+
if: needs.check-version.outputs.should_release == 'true'
|
|
43
|
+
# `secrets` is not allowed in `if:` expressions — map presence to a job-level
|
|
44
|
+
# env (where `secrets` IS permitted) and test that in the step condition.
|
|
45
|
+
env:
|
|
46
|
+
HAS_WINDOWS_CERT: ${{ secrets.WINDOWS_CERTIFICATE != '' }}
|
|
47
|
+
strategy:
|
|
48
|
+
fail-fast: false
|
|
49
|
+
matrix:
|
|
50
|
+
include:
|
|
51
|
+
- platform: macos-latest
|
|
52
|
+
target: aarch64-apple-darwin
|
|
53
|
+
label: macOS (Apple Silicon)
|
|
54
|
+
- platform: macos-latest
|
|
55
|
+
target: x86_64-apple-darwin
|
|
56
|
+
label: macOS (Intel)
|
|
57
|
+
- platform: windows-latest
|
|
58
|
+
target: x86_64-pc-windows-msvc
|
|
59
|
+
label: Windows (x86_64)
|
|
60
|
+
|
|
61
|
+
name: Build ${{ matrix.label }}
|
|
62
|
+
runs-on: ${{ matrix.platform }}
|
|
63
|
+
|
|
64
|
+
steps:
|
|
65
|
+
- name: Checkout
|
|
66
|
+
uses: actions/checkout@v4
|
|
67
|
+
|
|
68
|
+
- name: Install Rust stable
|
|
69
|
+
uses: dtolnay/rust-toolchain@stable
|
|
70
|
+
with:
|
|
71
|
+
targets: ${{ matrix.target }}
|
|
72
|
+
|
|
73
|
+
- name: Install pnpm
|
|
74
|
+
uses: pnpm/action-setup@v4
|
|
75
|
+
|
|
76
|
+
- name: Setup Node.js
|
|
77
|
+
uses: actions/setup-node@v4
|
|
78
|
+
with:
|
|
79
|
+
node-version: 22
|
|
80
|
+
cache: pnpm
|
|
81
|
+
|
|
82
|
+
- name: Install dependencies
|
|
83
|
+
run: pnpm install --frozen-lockfile
|
|
84
|
+
|
|
85
|
+
- name: Write Apple API key to file
|
|
86
|
+
if: runner.os == 'macOS'
|
|
87
|
+
run: |
|
|
88
|
+
mkdir -p ~/private_keys
|
|
89
|
+
printf '%s' "$APPLE_API_KEY_CONTENT" > ~/private_keys/AuthKey.p8
|
|
90
|
+
env:
|
|
91
|
+
APPLE_API_KEY_CONTENT: ${{ secrets.APPLE_API_KEY_CONTENT }}
|
|
92
|
+
|
|
93
|
+
- name: Build desktop app
|
|
94
|
+
# Pinned for supply-chain safety. Review before bumping:
|
|
95
|
+
# https://github.com/tauri-apps/tauri-action/releases
|
|
96
|
+
#
|
|
97
|
+
# Windows leg skipped when WINDOWS_CERTIFICATE secret is absent — lets
|
|
98
|
+
# macOS-only notarized releases ship while the Windows EV cert is being
|
|
99
|
+
# procured. When the secret is present but the build fails for any other
|
|
100
|
+
# reason (network, tauri-action bug, etc.), the step still fails loudly.
|
|
101
|
+
if: ${{ runner.os != 'Windows' || env.HAS_WINDOWS_CERT == 'true' }}
|
|
102
|
+
uses: tauri-apps/tauri-action@84b9d35b5fc46c1e45415bdb6144030364f7ebc5 # action-v0.6.2
|
|
103
|
+
env:
|
|
104
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
105
|
+
# Tauri updater artifact signing (required for latest.json signatures on all platforms)
|
|
106
|
+
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
|
|
107
|
+
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
|
|
108
|
+
# Apple Developer signing (macOS only — empty on Windows, tauri-action ignores)
|
|
109
|
+
APPLE_CERTIFICATE: ${{ runner.os == 'macOS' && secrets.APPLE_CERTIFICATE || '' }}
|
|
110
|
+
APPLE_CERTIFICATE_PASSWORD: ${{ runner.os == 'macOS' && secrets.APPLE_CERTIFICATE_PASSWORD || '' }}
|
|
111
|
+
APPLE_SIGNING_IDENTITY: ${{ runner.os == 'macOS' && secrets.APPLE_SIGNING_IDENTITY || '' }}
|
|
112
|
+
APPLE_API_ISSUER: ${{ runner.os == 'macOS' && secrets.APPLE_API_ISSUER || '' }}
|
|
113
|
+
APPLE_API_KEY: ${{ runner.os == 'macOS' && secrets.APPLE_API_KEY || '' }}
|
|
114
|
+
APPLE_API_KEY_PATH: ${{ runner.os == 'macOS' && '~/private_keys/AuthKey.p8' || '' }}
|
|
115
|
+
# Windows code signing (Windows only — empty on macOS, tauri-action ignores)
|
|
116
|
+
WINDOWS_CERTIFICATE: ${{ runner.os == 'Windows' && secrets.WINDOWS_CERTIFICATE || '' }}
|
|
117
|
+
WINDOWS_CERTIFICATE_PASSWORD: ${{ runner.os == 'Windows' && secrets.WINDOWS_CERTIFICATE_PASSWORD || '' }}
|
|
118
|
+
with:
|
|
119
|
+
projectPath: apps/desktop
|
|
120
|
+
tauriScript: pnpm tauri
|
|
121
|
+
args: --target ${{ matrix.target }}
|
|
122
|
+
tagName: desktop-v${{ needs.check-version.outputs.version }}
|
|
123
|
+
releaseName: "CodeByPlan Desktop v${{ needs.check-version.outputs.version }}"
|
|
124
|
+
releaseBody: |
|
|
125
|
+
## CodeByPlan Desktop v${{ needs.check-version.outputs.version }}
|
|
126
|
+
|
|
127
|
+
Download the appropriate installer for your platform:
|
|
128
|
+
- **macOS Apple Silicon** (.dmg) - For M1/M2/M3/M4 Macs
|
|
129
|
+
- **macOS Intel** (.dmg) - For older Intel-based Macs
|
|
130
|
+
- **Windows** (.msi) - For Windows 10/11 x64
|
|
131
|
+
|
|
132
|
+
### Installation
|
|
133
|
+
|
|
134
|
+
**macOS:**
|
|
135
|
+
1. Download the `.dmg` file for your Mac
|
|
136
|
+
2. Open the `.dmg` and drag CodeByPlan to Applications
|
|
137
|
+
3. Launch CodeByPlan from Applications
|
|
138
|
+
|
|
139
|
+
**Windows:**
|
|
140
|
+
1. Download the `.msi` file
|
|
141
|
+
2. Run the installer and follow the prompts
|
|
142
|
+
3. Launch CodeByPlan from the Start Menu
|
|
143
|
+
releaseDraft: false
|
|
144
|
+
prerelease: false
|
|
145
|
+
includeUpdaterJson: true
|
|
146
|
+
|
|
147
|
+
notify:
|
|
148
|
+
needs: [check-version, build]
|
|
149
|
+
if: needs.check-version.outputs.should_release == 'true' && needs.build.result == 'success'
|
|
150
|
+
runs-on: ubuntu-latest
|
|
151
|
+
name: Register Release
|
|
152
|
+
steps:
|
|
153
|
+
- name: Checkout
|
|
154
|
+
uses: actions/checkout@v4
|
|
155
|
+
|
|
156
|
+
- name: Download latest.json from GitHub Release
|
|
157
|
+
env:
|
|
158
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
159
|
+
VERSION: ${{ needs.check-version.outputs.version }}
|
|
160
|
+
run: |
|
|
161
|
+
TAG="desktop-v${VERSION}"
|
|
162
|
+
gh release download "${TAG}" --pattern "latest.json" --dir .
|
|
163
|
+
|
|
164
|
+
- name: Post release metadata to API
|
|
165
|
+
env:
|
|
166
|
+
CBP_API_KEY: ${{ secrets.CODEBYPLAN_API_KEY }}
|
|
167
|
+
VERSION: ${{ needs.check-version.outputs.version }}
|
|
168
|
+
run: |
|
|
169
|
+
TAG="desktop-v${VERSION}"
|
|
170
|
+
REPO="${{ github.repository }}"
|
|
171
|
+
BASE_URL="https://github.com/${REPO}/releases/download/${TAG}"
|
|
172
|
+
|
|
173
|
+
# Read the latest.json generated by tauri-action
|
|
174
|
+
MANIFEST=$(cat latest.json)
|
|
175
|
+
echo "Manifest: ${MANIFEST}"
|
|
176
|
+
|
|
177
|
+
# Build download URLs (for website download page)
|
|
178
|
+
AARCH64_DMG_URL="${BASE_URL}/CodeByPlan_${VERSION}_aarch64.dmg"
|
|
179
|
+
X86_64_DMG_URL="${BASE_URL}/CodeByPlan_${VERSION}_x64.dmg"
|
|
180
|
+
WINDOWS_X86_64_MSI_URL="${BASE_URL}/CodeByPlan_${VERSION}_x64_en-US.msi"
|
|
181
|
+
|
|
182
|
+
# Extract updater data from latest.json and merge with installer URLs
|
|
183
|
+
PLATFORMS=$(echo "${MANIFEST}" | jq \
|
|
184
|
+
--arg aarch64_dmg "${AARCH64_DMG_URL}" \
|
|
185
|
+
--arg x86_64_dmg "${X86_64_DMG_URL}" \
|
|
186
|
+
--arg windows_x86_64_msi "${WINDOWS_X86_64_MSI_URL}" '
|
|
187
|
+
.platforms | to_entries | map(
|
|
188
|
+
.value += (
|
|
189
|
+
if .key == "darwin-aarch64" then { "dmg_url": $aarch64_dmg }
|
|
190
|
+
elif .key == "darwin-x86_64" then { "dmg_url": $x86_64_dmg }
|
|
191
|
+
elif .key == "windows-x86_64" then { "msi_url": $windows_x86_64_msi }
|
|
192
|
+
else {}
|
|
193
|
+
end
|
|
194
|
+
)
|
|
195
|
+
) | from_entries
|
|
196
|
+
')
|
|
197
|
+
|
|
198
|
+
NOTES=$(echo "${MANIFEST}" | jq -r '.notes // "CodeByPlan Desktop v'"${VERSION}"'"')
|
|
199
|
+
PUB_DATE=$(echo "${MANIFEST}" | jq -r '.pub_date // empty')
|
|
200
|
+
if [ -z "${PUB_DATE}" ]; then
|
|
201
|
+
PUB_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
202
|
+
fi
|
|
203
|
+
|
|
204
|
+
# POST to our API
|
|
205
|
+
curl -fL -X POST \
|
|
206
|
+
"https://www.codebyplan.com/api/desktop/releases" \
|
|
207
|
+
-H "Content-Type: application/json" \
|
|
208
|
+
-H "x-api-key: ${CBP_API_KEY}" \
|
|
209
|
+
-d "$(jq -n \
|
|
210
|
+
--arg version "${VERSION}" \
|
|
211
|
+
--arg notes "${NOTES}" \
|
|
212
|
+
--arg pub_date "${PUB_DATE}" \
|
|
213
|
+
--argjson platforms "${PLATFORMS}" \
|
|
214
|
+
'{version: $version, notes: $notes, pub_date: $pub_date, platforms: $platforms}'
|
|
215
|
+
)"
|
|
@@ -133,6 +133,8 @@
|
|
|
133
133
|
"Skill(cbp-round-start)",
|
|
134
134
|
"Skill(cbp-round-update)",
|
|
135
135
|
"Skill(cbp-session-start)",
|
|
136
|
+
"Skill(cbp-setup-cd)",
|
|
137
|
+
"Skill(cbp-setup-ci)",
|
|
136
138
|
"Skill(cbp-setup-e2e)",
|
|
137
139
|
"Skill(cbp-setup-eslint)",
|
|
138
140
|
"Skill(cbp-ship-configure)",
|
|
@@ -249,7 +251,11 @@
|
|
|
249
251
|
"Bash(codebyplan e2e:*)",
|
|
250
252
|
"Bash(npx codebyplan e2e:*)",
|
|
251
253
|
"Bash(codebyplan arch-map:*)",
|
|
252
|
-
"Bash(npx codebyplan arch-map:*)"
|
|
254
|
+
"Bash(npx codebyplan arch-map:*)",
|
|
255
|
+
"Bash(codebyplan ci:*)",
|
|
256
|
+
"Bash(npx codebyplan ci:*)",
|
|
257
|
+
"Bash(codebyplan cd:*)",
|
|
258
|
+
"Bash(npx codebyplan cd:*)"
|
|
253
259
|
]
|
|
254
260
|
},
|
|
255
261
|
"attribution": {
|
|
@@ -157,5 +157,6 @@ Checks: name matches directory, frontmatter parses, no invalid fields, arg-hint
|
|
|
157
157
|
- Rendered `SKILL.md` content enters the conversation once when invoked and stays until compaction — write standing instructions, not one-time steps
|
|
158
158
|
- Preloaded subagent skills cannot have `disable-model-invocation: true`
|
|
159
159
|
- `context: fork` is only meaningful when the skill body contains an actionable task; otherwise the subagent receives guidelines with no prompt
|
|
160
|
+
- `context: fork` ALSO disqualifies fan-out / spawn-then-route / inline-by-design / consumed-inline skills — they run in the main context for a reason; see [reference/fork-eligibility.md](reference/fork-eligibility.md) for the eligibility test + the CBP classification of which skills may fork and which must stay inline
|
|
160
161
|
- Descriptions front-load key use case: `description` + `when_to_use` cap at 1,536 chars in the skill listing
|
|
161
162
|
- `paths:` scoping applies when Claude reads files matching the globs, not on every tool use
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# `context: fork` Eligibility — when to fork a skill, and when not to
|
|
2
|
+
|
|
3
|
+
`context: fork` runs the **entire SKILL.md body in a forked subagent** — it inherits the
|
|
4
|
+
parent conversation and, per the runtime, **runs in the background by default**. It is
|
|
5
|
+
isolation for a *whole skill*, not a way to delegate one sub-step. A forked body therefore
|
|
6
|
+
cannot drive the main pipeline: it can't `AskUserQuestion`, can't auto-trigger another
|
|
7
|
+
skill, and can't run an inline-fallback that the orchestrator depends on.
|
|
8
|
+
|
|
9
|
+
So forking only helps a narrow shape of skill. The canonical eligible example is
|
|
10
|
+
[examples/fork-skill.md](../examples/fork-skill.md): a single self-contained analytical task
|
|
11
|
+
that reads, reasons, and returns a summary — nothing else.
|
|
12
|
+
|
|
13
|
+
## Eligibility test
|
|
14
|
+
|
|
15
|
+
A skill is **fork-eligible** only when ALL hold:
|
|
16
|
+
|
|
17
|
+
1. Its whole body is **one** self-contained analytical/generative task (read → reason → return).
|
|
18
|
+
2. It is **non-interactive** — no `AskUserQuestion`, no user decision gates.
|
|
19
|
+
3. It does **not route** — no auto-trigger of another skill, no close-out directive that must
|
|
20
|
+
fire in the main context.
|
|
21
|
+
4. It does **not fan out** — it does not spawn multiple subagents and coordinate them.
|
|
22
|
+
5. It has **no inline-fallback** contract the orchestrator relies on.
|
|
23
|
+
|
|
24
|
+
Fail any one → the skill stays **inline** (main context). Inline skills still get clean
|
|
25
|
+
context isolation the right way: by delegating their heavy step to a dedicated **agent**
|
|
26
|
+
(e.g. `cbp-task-check`, `cbp-improve-round`, `cbp-round-executor`). The agent is the
|
|
27
|
+
isolation boundary; the skill stays in the main thread to orchestrate, route, and interact.
|
|
28
|
+
|
|
29
|
+
## When NOT to use `context: fork` (the disqualifying patterns)
|
|
30
|
+
|
|
31
|
+
| Pattern | Why it can't fork | Example skills |
|
|
32
|
+
|---------|-------------------|----------------|
|
|
33
|
+
| **fan-out** | spawns multiple agents in parallel and coordinates them | `cbp-round-execute`, `cbp-checkpoint-check`, `cbp-map-architecture`, `cbp-refresh-arch-map` |
|
|
34
|
+
| **spawn-then-route** | spawns one agent, then `AskUserQuestion` / auto-triggers the next skill / runs inline-fallback | `cbp-task-check`, `cbp-standalone-task-check`, `cbp-round-start`, `cbp-round-end`, `cbp-checkpoint-plan` |
|
|
35
|
+
| **inline-by-design** | interactive Q&A or stepwise writes that must stay in the main context | `cbp-task-create`, `cbp-task-complete`, `cbp-round-update`, `cbp-merge-main` |
|
|
36
|
+
| **consumed-inline** | invoked *by* an agent (e.g. round-executor) and applies fixes synchronously into that context | `cbp-frontend-design`, `cbp-frontend-ui`, `cbp-frontend-ux` |
|
|
37
|
+
| **doc-ref-only** | mentions subagents/fork only as documentation; runs inline authoring | the `cbp-build-cc-*` authoring skills, `cbp-supabase-migrate` |
|
|
38
|
+
|
|
39
|
+
## CHK-220 audit — classification matrix
|
|
40
|
+
|
|
41
|
+
Every skill whose `SKILL.md` touches the subagent/fork boundary — by spawning a subagent, by
|
|
42
|
+
being invoked inline by an agent, or by documenting the feature — was classified against the
|
|
43
|
+
eligibility test. **Result: 0 of 25 are fork-eligible** — none were migrated, because every
|
|
44
|
+
one either already isolates heavy work in a dedicated agent (the correct boundary) or depends
|
|
45
|
+
on inline orchestration/interaction that a background fork would break.
|
|
46
|
+
|
|
47
|
+
| Skill | Pattern | Fork-eligible |
|
|
48
|
+
|-------|---------|:---:|
|
|
49
|
+
| cbp-round-execute | fan-out | no |
|
|
50
|
+
| cbp-checkpoint-check | fan-out | no |
|
|
51
|
+
| cbp-map-architecture | fan-out | no |
|
|
52
|
+
| cbp-refresh-arch-map | fan-out | no |
|
|
53
|
+
| cbp-round-start | spawn-then-route | no |
|
|
54
|
+
| cbp-round-end | spawn-then-route | no |
|
|
55
|
+
| cbp-task-check | spawn-then-route | no |
|
|
56
|
+
| cbp-standalone-task-check | spawn-then-route | no |
|
|
57
|
+
| cbp-checkpoint-plan | spawn-then-route | no |
|
|
58
|
+
| cbp-round-update | inline-by-design | no |
|
|
59
|
+
| cbp-task-create | inline-by-design | no |
|
|
60
|
+
| cbp-standalone-task-create | inline-by-design | no |
|
|
61
|
+
| cbp-task-complete | inline-by-design | no |
|
|
62
|
+
| cbp-standalone-task-complete | inline-by-design | no |
|
|
63
|
+
| cbp-merge-main | inline-by-design | no |
|
|
64
|
+
| cbp-task-testing | inline-by-design | no |
|
|
65
|
+
| cbp-standalone-task-testing | inline-by-design | no |
|
|
66
|
+
| cbp-frontend-design | consumed-inline | no |
|
|
67
|
+
| cbp-frontend-ui | consumed-inline | no |
|
|
68
|
+
| cbp-frontend-ux | consumed-inline | no |
|
|
69
|
+
| cbp-supabase-migrate | doc-ref-only | no |
|
|
70
|
+
| cbp-build-cc-skill | doc-ref-only | no |
|
|
71
|
+
| cbp-build-cc-agent | doc-ref-only | no |
|
|
72
|
+
| cbp-build-cc-settings | doc-ref-only | no |
|
|
73
|
+
| cbp-build-cc-mode | doc-ref-only | no |
|
|
74
|
+
|
|
75
|
+
If a **new** skill is authored that passes the eligibility test above, fork it: add
|
|
76
|
+
`context: fork` + `agent: <Explore|Plan|general-purpose|custom>` (use `--fork` in
|
|
77
|
+
`/cbp-build-cc-skill`). Do not retrofit fork onto any skill in the table — their inline
|
|
78
|
+
shape is load-bearing.
|
|
@@ -20,6 +20,10 @@ Source: official Claude Code skills spec. All fields are optional; `description`
|
|
|
20
20
|
| `paths` | Globs that auto-load the skill when matching files are in play |
|
|
21
21
|
| `shell` | `bash` (default) or `powershell` for `!`-commands |
|
|
22
22
|
|
|
23
|
+
> `context: fork` / `agent` are right for only a narrow shape of skill — a single
|
|
24
|
+
> non-interactive analytical body. See [fork-eligibility.md](fork-eligibility.md) for the
|
|
25
|
+
> eligibility test and the CBP classification of which skills may fork (and which must stay inline).
|
|
26
|
+
|
|
23
27
|
## Character budget
|
|
24
28
|
|
|
25
29
|
Combined `description` + `when_to_use` truncates at **1,536 characters** in the skill listing. Front-load the key use case.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
+
scope: org-shared
|
|
2
3
|
name: cbp-checkpoint-check
|
|
3
4
|
description: Full re-evaluation of a checkpoint with before/after comparison
|
|
4
5
|
argument-hint: [CHK-NNN]
|
|
@@ -83,7 +84,14 @@ Aggregate QA from all tasks and rounds:
|
|
|
83
84
|
| TASK-[N] | READY | all_pass | [N] |
|
|
84
85
|
```
|
|
85
86
|
|
|
86
|
-
Re-run build/lint/types on current codebase to verify nothing regressed across tasks.
|
|
87
|
+
Re-run build/lint/types on the current codebase to verify nothing regressed across tasks. Detect `$PLATFORM` from the project type (same signal table as `cbp-testing-qa-agent.md` Step 1), then resolve commands from `.codebyplan/ci.json`:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
CI_BUILD_CMD=$(npx codebyplan ci resolve build --platform "$PLATFORM" 2>/dev/null)
|
|
91
|
+
CI_TYPES_CMD=$(npx codebyplan ci resolve typecheck --platform "$PLATFORM" 2>/dev/null)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Run: `${CI_BUILD_CMD:-npm run build}` and `${CI_TYPES_CMD:-npx tsc --noEmit}`. For lint use the whole-repo command (`pnpm -w lint`). Fallback: if `.codebyplan/ci.json` is absent, `ci resolve` returns the central default; if the binary is unavailable the `${CI_*_CMD:-<literal>}` guard uses the hardcoded fallback.
|
|
87
95
|
|
|
88
96
|
### Step 5b: Whole-Checkpoint E2E
|
|
89
97
|
|
|
@@ -96,7 +96,11 @@ Runtime deployment for the base branch is handled in Step 7 by `/cbp-ship` (whic
|
|
|
96
96
|
|
|
97
97
|
### Step 7: Runtime Shipment via `/cbp-ship`
|
|
98
98
|
|
|
99
|
-
After branch promotion to main completes, invoke `/cbp-ship` to deploy every configured surface
|
|
99
|
+
After branch promotion to main completes, invoke `/cbp-ship` to deploy every configured surface.
|
|
100
|
+
`/cbp-ship` reads `.codebyplan/cd.json` when present to inform per-surface deploy variant
|
|
101
|
+
selection (trigger, environment, approval gate, OIDC auth, credential env-var names). Repos
|
|
102
|
+
without `cd.json` fall back to filesystem surface detection — no behavior change. Run
|
|
103
|
+
`/cbp-setup-cd` to set up `cd.json` for a repo that has not yet migrated.
|
|
100
104
|
|
|
101
105
|
- Vercel auto-deploy verification
|
|
102
106
|
- Mobile shipment (asks user: skip / EAS internal TestFlight / EAS external TestFlight)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
+
scope: org-shared
|
|
2
3
|
name: cbp-round-check
|
|
3
4
|
description: Run automated checks standalone for the current round
|
|
4
5
|
effort: low
|
|
@@ -129,4 +130,5 @@ If soft failures only: `Run /cbp-round-start to trigger auto-fix, or fix manuall
|
|
|
129
130
|
- **Writes (checkpoint KIND)**: `codebyplan round update` (qa field). Break-glass: MCP `update_round`.
|
|
130
131
|
- **Writes (standalone KIND)**: MCP `update_standalone_round` (qa field). (Standalone KIND still uses MCP until a later task.)
|
|
131
132
|
- **Runner**: `codebyplan check --scope round --json` (whole-repo + baseline via `turbo run`; runs gate6 + lint + typecheck + tests; `--files` is accepted but ignored in whole-repo mode)
|
|
133
|
+
- **ci.json awareness**: `codebyplan check` is turbo-native — it runs `turbo run lint|typecheck|test` directly and does NOT read `.codebyplan/ci.json`. ci.json command resolution (via `npx codebyplan ci resolve <category> [--platform <slug>]`) is used by non-check consumers (`cbp-testing-qa-agent`, `cbp-security-agent`, `cbp-standalone-task-testing`, `cbp-checkpoint-check`), with a central-default fallback ensuring exit 0 even when ci.json is absent.
|
|
132
134
|
- **Standalone**: Can be run independently at any time
|