code-foundry 0.26.0 → 0.27.1

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 (44) hide show
  1. package/.githooks/pre-commit +3 -4
  2. package/.github/CONTRIBUTING.md +10 -13
  3. package/.github/actions/setup/action.yml +68 -3
  4. package/.github/code-foundry.yml +6 -1
  5. package/.github/workflows/ci.yml +29 -24
  6. package/.github/workflows/ci_self-ci.yml +1 -1
  7. package/.github/workflows/codeql.yml +23 -29
  8. package/.github/workflows/codeql_self-ci.yml +1 -1
  9. package/.github/workflows/draft-pr.yml +2 -2
  10. package/.github/workflows/release-pr.yml +4 -4
  11. package/.github/workflows/release.yml +17 -29
  12. package/.github/workflows/security.yml +24 -19
  13. package/.github/workflows/security_self-ci.yml +1 -1
  14. package/.github/workflows/test.yml +20 -20
  15. package/.github/workflows/test_self-ci.yml +1 -1
  16. package/AGENTS.md +13 -10
  17. package/CHANGELOG.md +29 -0
  18. package/README.md +16 -6
  19. package/docs/CONFIGURATION.md +10 -1
  20. package/docs/INITIALIZATION.md +6 -5
  21. package/docs/RELEASES.md +5 -0
  22. package/docs/WORKFLOWS.md +12 -5
  23. package/package.json +7 -3
  24. package/src/cli.mjs +29 -25
  25. package/src/commands/doctor.mjs +70 -0
  26. package/src/commands/sync.mjs +224 -0
  27. package/src/lib/config.mjs +38 -0
  28. package/src/lib/profile.mjs +114 -0
  29. package/src/runtime.mjs +321 -0
  30. package/.github/scripts/bootstrap.sh +0 -21
  31. package/.github/scripts/changed-files.sh +0 -96
  32. package/.github/scripts/ci.sh +0 -641
  33. package/.github/scripts/codeql-languages.sh +0 -91
  34. package/.github/scripts/doctor.sh +0 -98
  35. package/.github/scripts/format-fast-path.sh +0 -80
  36. package/.github/scripts/init-repo.sh +0 -268
  37. package/.github/scripts/pre-commit.sh +0 -67
  38. package/.github/scripts/profile.sh +0 -186
  39. package/.github/scripts/security.sh +0 -214
  40. package/.github/scripts/sitecustomize.py +0 -17
  41. package/.github/scripts/sync-codeowners.sh +0 -76
  42. package/.github/scripts/sync-protection.sh +0 -138
  43. package/.github/scripts/sync-template.sh +0 -748
  44. package/.github/scripts/turbo-cache-probe.sh +0 -102
@@ -44,6 +44,7 @@ jobs:
44
44
  rust: ${{ steps.profile.outputs.rust }}
45
45
  python: ${{ steps.profile.outputs.python }}
46
46
  python_requirements: ${{ steps.profile.outputs.python_requirements }}
47
+ dependency_review: ${{ steps.profile.outputs.dependency_review }}
47
48
  steps:
48
49
  - name: Checkout
49
50
  uses: actions/checkout@v7
@@ -83,15 +84,18 @@ jobs:
83
84
  path: .code-foundry
84
85
  sparse-checkout: |
85
86
  .github/actions
86
- .github/scripts
87
+ src/lib
88
+ src/runtime.mjs
87
89
  - name: Install runtime
88
90
  run: |
89
- mkdir -p .github/actions .github/scripts
91
+ mkdir -p .github/actions
90
92
  cp -R .code-foundry/.github/actions/. .github/actions/
91
- cp -R .code-foundry/.github/scripts/. .github/scripts/
92
93
  - name: Detect
93
94
  id: profile
94
- run: bash .github/scripts/security.sh profile >> "$GITHUB_OUTPUT"
95
+ env:
96
+ REPO_FOUNDRY_PRIVATE: ${{ github.event.repository.private }}
97
+ REPO_FOUNDRY_VISIBILITY: ${{ github.event.repository.visibility }}
98
+ run: node .code-foundry/src/runtime.mjs security profile >> "$GITHUB_OUTPUT"
95
99
 
96
100
  dependency-audit-javascript:
97
101
  name: Dependency Audit (JavaScript)
@@ -124,15 +128,15 @@ jobs:
124
128
  path: .code-foundry
125
129
  sparse-checkout: |
126
130
  .github/actions
127
- .github/scripts
131
+ src/lib
132
+ src/runtime.mjs
128
133
  - name: Install runtime
129
134
  run: |
130
- mkdir -p .github/actions .github/scripts
135
+ mkdir -p .github/actions
131
136
  cp -R .code-foundry/.github/actions/. .github/actions/
132
- cp -R .code-foundry/.github/scripts/. .github/scripts/
133
137
  - name: Detect
134
138
  id: applicability
135
- run: bash .github/scripts/security.sh should_run javascript >> "$GITHUB_OUTPUT"
139
+ run: node .code-foundry/src/runtime.mjs security should_run javascript >> "$GITHUB_OUTPUT"
136
140
  - name: Setup
137
141
  if: steps.applicability.outputs.applicable == 'true'
138
142
  uses: ./.github/actions/setup
@@ -141,7 +145,7 @@ jobs:
141
145
  cache-save: ${{ github.event_name != 'pull_request' }}
142
146
  - name: Audit dependencies
143
147
  if: steps.applicability.outputs.applicable == 'true'
144
- run: bash .github/scripts/security.sh audit javascript
148
+ run: node .code-foundry/src/runtime.mjs security audit javascript
145
149
 
146
150
  dependency-audit-rust:
147
151
  name: Dependency Audit (Rust)
@@ -168,15 +172,15 @@ jobs:
168
172
  path: .code-foundry
169
173
  sparse-checkout: |
170
174
  .github/actions
171
- .github/scripts
175
+ src/lib
176
+ src/runtime.mjs
172
177
  - name: Install runtime
173
178
  run: |
174
- mkdir -p .github/actions .github/scripts
179
+ mkdir -p .github/actions
175
180
  cp -R .code-foundry/.github/actions/. .github/actions/
176
- cp -R .code-foundry/.github/scripts/. .github/scripts/
177
181
  - name: Detect
178
182
  id: applicability
179
- run: bash .github/scripts/security.sh should_run rust >> "$GITHUB_OUTPUT"
183
+ run: node .code-foundry/src/runtime.mjs security should_run rust >> "$GITHUB_OUTPUT"
180
184
  - name: Check Rust
181
185
  id: system-rust
182
186
  if: steps.applicability.outputs.applicable == 'true'
@@ -204,7 +208,7 @@ jobs:
204
208
  tool: cargo-audit
205
209
  - name: Audit dependencies
206
210
  if: steps.applicability.outputs.applicable == 'true'
207
- run: bash .github/scripts/security.sh audit rust
211
+ run: node .code-foundry/src/runtime.mjs security audit rust
208
212
 
209
213
  dependency-audit-python:
210
214
  name: Dependency Audit (Python) / ${{ matrix.requirement }}
@@ -248,19 +252,19 @@ jobs:
248
252
  path: .code-foundry
249
253
  sparse-checkout: |
250
254
  .github/actions
251
- .github/scripts
255
+ src/lib
256
+ src/runtime.mjs
252
257
  - name: Install runtime
253
258
  run: |
254
- mkdir -p .github/actions .github/scripts
259
+ mkdir -p .github/actions
255
260
  cp -R .code-foundry/.github/actions/. .github/actions/
256
- cp -R .code-foundry/.github/scripts/. .github/scripts/
257
261
  - name: Setup
258
262
  uses: ./.github/actions/setup
259
263
  with:
260
264
  mise-scope: python
261
265
  cache-save: ${{ github.event_name != 'pull_request' }}
262
266
  - name: Audit dependencies
263
- run: bash .github/scripts/security.sh audit python
267
+ run: node .code-foundry/src/runtime.mjs security audit python
264
268
 
265
269
  dependency-audit-python-gate:
266
270
  name: Dependency Audit (Python)
@@ -285,7 +289,8 @@ jobs:
285
289
 
286
290
  dependency-review:
287
291
  name: Dependency Review
288
- if: ${{ github.event_name == 'pull_request' && !github.event.repository.private }}
292
+ needs: profile
293
+ if: ${{ github.event_name == 'pull_request' && needs.profile.outputs.dependency_review == 'true' }}
289
294
  runs-on: ${{ inputs.runner }}
290
295
  timeout-minutes: 10
291
296
  steps:
@@ -16,6 +16,6 @@ jobs:
16
16
  uses: ./.github/workflows/security.yml
17
17
  with:
18
18
  runtime-repository: 0xPlayerOne/code-foundry
19
- runtime-ref: v0.22.0
19
+ runtime-ref: staging
20
20
  runner: ubuntu-slim
21
21
  secrets: inherit
@@ -61,15 +61,15 @@ jobs:
61
61
  path: .code-foundry
62
62
  sparse-checkout: |
63
63
  .github/actions
64
- .github/scripts
64
+ src/lib
65
+ src/runtime.mjs
65
66
  - name: Install runtime
66
67
  run: |
67
- mkdir -p .github/actions .github/scripts
68
+ mkdir -p .github/actions
68
69
  cp -R .code-foundry/.github/actions/. .github/actions/
69
- cp -R .code-foundry/.github/scripts/. .github/scripts/
70
70
  - name: Detect
71
71
  id: applicability
72
- run: bash .github/scripts/ci.sh task_profile unit >> "$GITHUB_OUTPUT"
72
+ run: node .code-foundry/src/runtime.mjs ci task_profile unit >> "$GITHUB_OUTPUT"
73
73
  - name: Setup
74
74
  if: steps.applicability.outputs.applicable == 'true'
75
75
  uses: ./.github/actions/setup
@@ -87,7 +87,7 @@ jobs:
87
87
  task-rust: ${{ steps.applicability.outputs.rust }}
88
88
  - name: Unit
89
89
  if: steps.applicability.outputs.applicable == 'true'
90
- run: bash .github/scripts/ci.sh unit
90
+ run: node .code-foundry/src/runtime.mjs ci unit
91
91
  - name: Upload coverage
92
92
  if: >-
93
93
  always() &&
@@ -122,15 +122,15 @@ jobs:
122
122
  path: .code-foundry
123
123
  sparse-checkout: |
124
124
  .github/actions
125
- .github/scripts
125
+ src/lib
126
+ src/runtime.mjs
126
127
  - name: Install runtime
127
128
  run: |
128
- mkdir -p .github/actions .github/scripts
129
+ mkdir -p .github/actions
129
130
  cp -R .code-foundry/.github/actions/. .github/actions/
130
- cp -R .code-foundry/.github/scripts/. .github/scripts/
131
131
  - name: Detect
132
132
  id: applicability
133
- run: bash .github/scripts/ci.sh task_profile integration >> "$GITHUB_OUTPUT"
133
+ run: node .code-foundry/src/runtime.mjs ci task_profile integration >> "$GITHUB_OUTPUT"
134
134
  - name: Setup
135
135
  if: steps.applicability.outputs.applicable == 'true'
136
136
  uses: ./.github/actions/setup
@@ -148,7 +148,7 @@ jobs:
148
148
  task-rust: ${{ steps.applicability.outputs.rust }}
149
149
  - name: Integration
150
150
  if: steps.applicability.outputs.applicable == 'true'
151
- run: bash .github/scripts/ci.sh integration
151
+ run: node .code-foundry/src/runtime.mjs ci integration
152
152
 
153
153
  e2e:
154
154
  name: E2E
@@ -167,15 +167,15 @@ jobs:
167
167
  path: .code-foundry
168
168
  sparse-checkout: |
169
169
  .github/actions
170
- .github/scripts
170
+ src/lib
171
+ src/runtime.mjs
171
172
  - name: Install runtime
172
173
  run: |
173
- mkdir -p .github/actions .github/scripts
174
+ mkdir -p .github/actions
174
175
  cp -R .code-foundry/.github/actions/. .github/actions/
175
- cp -R .code-foundry/.github/scripts/. .github/scripts/
176
176
  - name: Detect
177
177
  id: applicability
178
- run: bash .github/scripts/ci.sh task_profile e2e >> "$GITHUB_OUTPUT"
178
+ run: node .code-foundry/src/runtime.mjs ci task_profile e2e >> "$GITHUB_OUTPUT"
179
179
  - name: Cache browser binaries
180
180
  if: steps.applicability.outputs.applicable == 'true' && steps.applicability.outputs.browser == 'true'
181
181
  uses: ./.github/actions/cache
@@ -205,7 +205,7 @@ jobs:
205
205
  task-rust: ${{ steps.applicability.outputs.rust }}
206
206
  - name: E2E
207
207
  if: steps.applicability.outputs.applicable == 'true'
208
- run: bash .github/scripts/ci.sh e2e
208
+ run: node .code-foundry/src/runtime.mjs ci e2e
209
209
 
210
210
  smoke:
211
211
  name: Smoke
@@ -224,15 +224,15 @@ jobs:
224
224
  path: .code-foundry
225
225
  sparse-checkout: |
226
226
  .github/actions
227
- .github/scripts
227
+ src/lib
228
+ src/runtime.mjs
228
229
  - name: Install runtime
229
230
  run: |
230
- mkdir -p .github/actions .github/scripts
231
+ mkdir -p .github/actions
231
232
  cp -R .code-foundry/.github/actions/. .github/actions/
232
- cp -R .code-foundry/.github/scripts/. .github/scripts/
233
233
  - name: Detect
234
234
  id: applicability
235
- run: bash .github/scripts/ci.sh task_profile smoke >> "$GITHUB_OUTPUT"
235
+ run: node .code-foundry/src/runtime.mjs ci task_profile smoke >> "$GITHUB_OUTPUT"
236
236
  - name: Setup
237
237
  if: steps.applicability.outputs.applicable == 'true'
238
238
  uses: ./.github/actions/setup
@@ -250,4 +250,4 @@ jobs:
250
250
  task-rust: ${{ steps.applicability.outputs.rust }}
251
251
  - name: Smoke
252
252
  if: steps.applicability.outputs.applicable == 'true'
253
- run: bash .github/scripts/ci.sh smoke
253
+ run: node .code-foundry/src/runtime.mjs ci smoke
@@ -16,7 +16,7 @@ jobs:
16
16
  uses: ./.github/workflows/test.yml
17
17
  with:
18
18
  runtime-repository: 0xPlayerOne/code-foundry
19
- runtime-ref: v0.22.0
19
+ runtime-ref: staging
20
20
  runner: ubuntu-latest
21
21
  unit-runner: ubuntu-slim
22
22
  secrets: inherit
package/AGENTS.md CHANGED
@@ -7,7 +7,8 @@ They complement `CONTRIBUTING.md`. More specific instructions in nested `AGENTS.
7
7
  ## Mission
8
8
 
9
9
  - Keep formatting, linting, type checking, builds, tests, and coverage reproducible locally and in CI.
10
- - Prefer the versions pinned in `.mise.toml`.
10
+ - Prefer the repository's configured toolchain; `toolchain: auto` uses native
11
+ tools unless an existing `.mise.toml` is present.
11
12
  - Do not commit secrets, generated credentials, local environment files, or machine-specific paths.
12
13
  - Add tests for behavior changes and keep coverage thresholds explicit in the project configuration.
13
14
  - Make the smallest complete, well-tested change that solves the requested problem without disturbing unrelated work.
@@ -72,7 +73,9 @@ For normal feature work, branch from `staging` and target pull requests at `stag
72
73
 
73
74
  ## Toolchain and dependencies
74
75
 
75
- - Use the versions pinned in `.mise.toml`; run `mise install` when needed.
76
+ - Follow `toolchain: auto` in `.github/code-foundry.yml`; use native tools by
77
+ default and reuse mise only when the repository already has `.mise.toml`.
78
+ - If `toolchain: mise` is selected, run `mise install` before validation.
76
79
  - Use the package manager indicated by the existing lockfile:
77
80
  - `bun.lock` or `bun.lockb` → Bun
78
81
  - `pnpm-lock.yaml` → pnpm
@@ -88,14 +91,14 @@ For normal feature work, branch from `staging` and target pull requests at `stag
88
91
  Use the shared scripts when present. They detect supported tools and skip inapplicable checks:
89
92
 
90
93
  ```sh
91
- bash .github/scripts/ci.sh format
92
- bash .github/scripts/ci.sh lint
93
- bash .github/scripts/ci.sh type_check
94
- bash .github/scripts/ci.sh build
95
- bash .github/scripts/ci.sh unit
96
- bash .github/scripts/ci.sh integration
97
- bash .github/scripts/ci.sh e2e
98
- bash .github/scripts/ci.sh smoke
94
+ node src/runtime.mjs ci format
95
+ node src/runtime.mjs ci lint
96
+ node src/runtime.mjs ci type_check
97
+ node src/runtime.mjs ci build
98
+ node src/runtime.mjs ci unit
99
+ node src/runtime.mjs ci integration
100
+ node src/runtime.mjs ci e2e
101
+ node src/runtime.mjs ci smoke
99
102
  Security and dependency audits run through the GitHub Security workflow.
100
103
  ```
101
104
 
package/CHANGELOG.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.27.1](https://github.com/0xPlayerOne/code-foundry/compare/v0.27.0...v0.27.1) (2026-07-28)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * **ci:** cover framework and native test prerequisites ([53b8209](https://github.com/0xPlayerOne/code-foundry/commit/53b8209104cf52972e867eba65fed46d0b8f57bb))
9
+ * **ci:** install project format and Python tooling ([13fb972](https://github.com/0xPlayerOne/code-foundry/commit/13fb972e774e26c2d5794421a17c4ac685a28b0c))
10
+
11
+ ## [0.27.0](https://github.com/0xPlayerOne/code-foundry/compare/v0.26.0...v0.27.0) (2026-07-28)
12
+
13
+
14
+ ### Features
15
+
16
+ * add typed javascript cli checks ([2d9464b](https://github.com/0xPlayerOne/code-foundry/commit/2d9464bcbef8aa51607cdf52a6a60e3fc1bdb054))
17
+ * make mise an optional toolchain ([e62f023](https://github.com/0xPlayerOne/code-foundry/commit/e62f0238f4ddc2d1b0f89e0f2b23bca3679b934e))
18
+ * make paid github security checks opt-in ([bbfe899](https://github.com/0xPlayerOne/code-foundry/commit/bbfe8993d88a8415129ce29bfa5d2181807232ba))
19
+ * skip irrelevant language configuration ([39a0003](https://github.com/0xPlayerOne/code-foundry/commit/39a00037ba92152926e7a89759f3255d86a4f26e))
20
+ * standardize optional github security policies ([2cf6bc3](https://github.com/0xPlayerOne/code-foundry/commit/2cf6bc3af161ed8757a03447aab16f3e7ea310d7))
21
+
22
+
23
+ ### Bug Fixes
24
+
25
+ * include runtime libraries in every workflow job ([ce94cd9](https://github.com/0xPlayerOne/code-foundry/commit/ce94cd96a32eff54048712e1bf4b2d34a868ba2e))
26
+ * include runtime libraries in workflow checkout ([4b2c252](https://github.com/0xPlayerOne/code-foundry/commit/4b2c2527c37c82b498c2b3457df5dd52ef7c694f))
27
+ * migrate stale managed docs during sync ([380bab1](https://github.com/0xPlayerOne/code-foundry/commit/380bab1334c9125f97bf333cc29c796e1a16d57d))
28
+ * preserve authored notice files ([342e666](https://github.com/0xPlayerOne/code-foundry/commit/342e666f4e218e094180f10ecdc5a24b85a27b28))
29
+ * preserve repository notice attribution ([7d43911](https://github.com/0xPlayerOne/code-foundry/commit/7d439117ec89882d8d06895528d94ed717ade471))
30
+ * use pinned bun lockfile format ([0f75faf](https://github.com/0xPlayerOne/code-foundry/commit/0f75faf2c7614cc7055cbb4f26a01b3cf1639f85))
31
+
3
32
  ## [0.26.0](https://github.com/0xPlayerOne/code-foundry/compare/v0.25.0...v0.26.0) (2026-07-28)
4
33
 
5
34
 
package/README.md CHANGED
@@ -19,7 +19,7 @@ npx code-foundry init
19
19
  ```
20
20
 
21
21
  Initialization is repository-aware. It detects supported languages, package
22
- manager, profile, release strategy, and required mise tools, then writes the
22
+ manager, profile, release strategy, and toolchain preference, then writes the
23
23
  resolved choices to `.github/code-foundry.yml`.
24
24
 
25
25
  ```bash
@@ -39,7 +39,7 @@ contract. For normal updates, edit that file and run `npx code-foundry sync`.
39
39
  and Release.
40
40
  - A small `.githooks/pre-commit` launcher with language-aware formatting and
41
41
  linting.
42
- - `.mise.toml`, optional `mise.lock`, repository profile configuration, and
42
+ - An optional `.mise.toml`/`mise.lock`, repository profile configuration, and
43
43
  standard GitHub forms and policy files.
44
44
  - AGENTS instructions, CODEOWNERS, license/notice files, and reusable release
45
45
  configuration.
@@ -60,7 +60,9 @@ New repositories default to GPL-3.0-or-later. Existing projects preserve an
60
60
  authored license unless a replacement is explicitly selected. Our maintained
61
61
  repositories explicitly select AGPL-3.0-or-later. Authored
62
62
  documentation, application files, custom workflows, and existing `.mise.toml`
63
- files are preserved by default.
63
+ files are preserved by default. `toolchain: auto` uses an existing mise setup
64
+ when present and otherwise uses native language tooling; choose `native` or
65
+ `mise` explicitly when a repository needs a fixed policy.
64
66
 
65
67
  ## Workflow model
66
68
 
@@ -76,13 +78,21 @@ test runner. Rust uses `rustfmt`, Clippy with warnings as errors, and native
76
78
  Cargo tests. Python uses Ruff, uv/pip-compatible setup, and native Python
77
79
  tests. Solidity projects retain their native toolchain and test runner.
78
80
 
79
- CodeQL remains separate from CI and Security. Dependency Review is isolated in
80
- Security and is skipped where GitHub does not support it, while JavaScript,
81
- Python, and Rust audits remain available without GitHub Advanced Security.
81
+ CodeQL remains separate from CI and Security. With the default `codeql: auto`
82
+ and `dependency_review: auto` policies, public repositories use the free GitHub
83
+ security checks while private repositories skip them unless explicitly opted
84
+ in and supported by GitHub Advanced Security. JavaScript, Python, and Rust
85
+ audits remain available without Advanced Security. Code Foundry does not enable
86
+ GitHub Code Quality or other paid GitHub features.
82
87
 
83
88
  See [Workflow and CI conventions](docs/WORKFLOWS.md) for triggers, required
84
89
  checks, runners, coverage, caching, and custom workflow extensions.
85
90
 
91
+ The default contribution policy uses the `staging-release` workflow with
92
+ rebase merges. Repositories can set `merge_strategy: squash` or
93
+ `merge_strategy: merge` in `.github/code-foundry.yml` when their governance
94
+ requires another merge convention.
95
+
86
96
  ## Releases and publishing
87
97
 
88
98
  The standard flow promotes `staging` into `main`, lets Release Please open a
@@ -9,6 +9,10 @@ npx code-foundry init
9
9
  Initialization detects the repository and writes a fully resolved configuration.
10
10
  Edit that file directly, then run `npx code-foundry sync`.
11
11
 
12
+ The default `toolchain: auto` reuses an existing `.mise.toml`; otherwise it
13
+ selects native setup for the detected languages. Use `toolchain: native` to
14
+ prohibit mise or `toolchain: mise` to require it.
15
+
12
16
  ## Configuration flow
13
17
 
14
18
  ```text
@@ -17,7 +21,7 @@ repository manifests and source
17
21
  v
18
22
  .github/code-foundry.yml
19
23
  |
20
- +--> mise and environment setup
24
+ +--> native or mise toolchain setup
21
25
  +--> standard workflow callers
22
26
  +--> runtime repository and version
23
27
  +--> release, license, cache, and coverage policy
@@ -30,13 +34,18 @@ repository manifests and source
30
34
  | `profile` | `auto`, `application`, `monorepo`, `minimal` | Repository shape |
31
35
  | `languages` | detected list | TypeScript, Rust, Python, Solidity |
32
36
  | `package_manager` | `bun`, `pnpm`, `yarn`, `npm`, `none` | JavaScript setup |
37
+ | `toolchain` | `auto`, `native`, `mise` | Environment setup policy; defaults to `auto` |
33
38
  | `features` | `all` or a list | Standard workflow callers |
39
+ | `codeql` | `auto`, `true`, `false` | CodeQL policy; public repositories default to enabled, non-public repositories default to disabled |
40
+ | `dependency_review` | `auto`, `true`, `false` | Dependency Review policy; public repositories default to enabled, non-public repositories default to disabled |
34
41
  | `prune_standard` | `true` or `false` | Remove disabled standard callers |
35
42
  | `runtime_repository` | `OWNER/REPO` | Reusable workflow source |
36
43
  | `runtime_ref` | tag or branch | Reusable workflow version |
37
44
  | `release_type` | `node`, `python`, `rust`, `simple`, `none` | Release strategy |
38
45
  | `npm_publish` | `true` or `false` | Opt into npm publication |
39
46
  | `license` | `gpl-3.0-or-later`, `agpl-3.0-or-later`, `mit`, `preserve`, `none` | License policy; new repositories default to GPLv3 |
47
+ | `git_workflow` | `staging-release` | Branch/release model; the standard model promotes `staging` into `main` |
48
+ | `merge_strategy` | `rebase`, `squash`, `merge` | Preferred merge method for contribution and release PRs; defaults to `rebase` |
40
49
  | `runner` fields | GitHub runner names | Per-workflow runner policy |
41
50
 
42
51
  Supported features are `ci`, `codeql`, `security`, `test`, `draft-pr`,
@@ -11,7 +11,7 @@ npx code-foundry doctor
11
11
  ```
12
12
 
13
13
  `init` detects supported languages, package manager, repository profile,
14
- release strategy, mise tools, and standard features. It writes the resolved
14
+ release strategy, toolchain preference, and standard features. It writes the resolved
15
15
  choices to `.github/code-foundry.yml`, initializes the local environment, and
16
16
  renders the standard baseline.
17
17
 
@@ -40,7 +40,8 @@ Sync updates standard Code Foundry files only. It preserves application code,
40
40
  authored documentation, existing `.mise.toml` selections, and custom workflows
41
41
  such as deployment, search, Slither, or monitoring workflows.
42
42
 
43
- The environment bootstrap installs or reuses mise-managed tools and enables
44
- the repository hooks. Use `npx code-foundry doctor` when local setup needs to
45
- be checked; the CLI supplies the implementation without adding maintenance
46
- scripts to the consumer repository.
43
+ The environment bootstrap enables repository hooks and uses mise only when an
44
+ existing `.mise.toml` is present or `toolchain: mise` is selected. Otherwise it
45
+ uses the repository's native tools. Use `npx code-foundry doctor` when local
46
+ setup needs to be checked; the CLI supplies the implementation without adding
47
+ maintenance scripts to the consumer repository.
package/docs/RELEASES.md CHANGED
@@ -12,6 +12,11 @@ Keep commits Conventional Commit-shaped (`feat:`, `fix:`, `docs:`, `ci:`,
12
12
  `chore:`, and so on). Release Please uses them to select patch/minor/major
13
13
  versions and generate grouped changelog notes.
14
14
 
15
+ The default `merge_strategy` is `rebase`, matching the repository's linear
16
+ history policy. Set it to `squash` or `merge` in `.github/code-foundry.yml` when
17
+ that repository intentionally uses a different merge convention. The current
18
+ supported `git_workflow` is `staging-release`.
19
+
15
20
  The release workflow opens or updates a versioned PR after changes reach
16
21
  `main`. Merging that PR updates the changelog, creates the Git tag and GitHub
17
22
  Release, and triggers any configured package publication.
package/docs/WORKFLOWS.md CHANGED
@@ -46,11 +46,18 @@ ambiguous for mixed-language repositories.
46
46
 
47
47
  ## Security behavior
48
48
 
49
- CodeQL is a separate workflow using GitHub's official actions. Dependency
50
- Review is skipped where GitHub does not support it, while JavaScript, Python,
51
- and Rust audits remain available without Advanced Security. If GitHub default
52
- setup is enabled, disable its generated CodeQL workflow to avoid duplicate
53
- analysis.
49
+ CodeQL is a separate workflow using GitHub's official actions. The default
50
+ `codeql: auto` policy enables it for public repositories and skips it for
51
+ private repositories unless explicitly enabled and Advanced Security is
52
+ available. Dependency Review follows the same policy through
53
+ `dependency_review: auto`; JavaScript, Python, and Rust audits remain
54
+ available without Advanced Security. If GitHub default setup is enabled,
55
+ disable its generated CodeQL workflow to avoid duplicate analysis.
56
+
57
+ Code Foundry does not enable GitHub Code Quality or any paid GitHub feature.
58
+ The repository's format and lint jobs are ordinary CI checks. Set `codeql:
59
+ false` or `dependency_review: false` when a public repository also needs those
60
+ checks disabled.
54
61
 
55
62
  ## Branch protection
56
63
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "code-foundry",
3
- "version": "0.26.0",
3
+ "version": "0.27.1",
4
4
  "description": "A fast, language-aware repository factory for agent-ready workflows, testing, security, and release automation.",
5
5
  "type": "module",
6
6
  "license": "AGPL-3.0-or-later",
@@ -42,12 +42,16 @@
42
42
  "build": "node --check src/cli.mjs",
43
43
  "format:check": "node --check src/cli.mjs",
44
44
  "lint": "node --check src/cli.mjs",
45
- "test": "node --check src/cli.mjs",
46
- "type-check": "node --check src/cli.mjs",
45
+ "test": "node --test",
46
+ "type-check": "tsc --project jsconfig.json",
47
47
  "pack:check": "npm pack --dry-run",
48
48
  "prepublishOnly": "npm test && npm run pack:check"
49
49
  },
50
50
  "publishConfig": {
51
51
  "access": "public"
52
+ },
53
+ "devDependencies": {
54
+ "@types/node": "^24.0.0",
55
+ "typescript": "^5.8.3"
52
56
  }
53
57
  }
package/src/cli.mjs CHANGED
@@ -1,12 +1,16 @@
1
1
  #!/usr/bin/env node
2
+ // @ts-check
2
3
 
3
- import { existsSync } from 'node:fs'
4
4
  import { resolve } from 'node:path'
5
- import { spawnSync } from 'node:child_process'
6
5
  import { fileURLToPath } from 'node:url'
6
+ import { doctor } from './commands/doctor.mjs'
7
+ import { syncRepository } from './commands/sync.mjs'
7
8
 
8
9
  const packageRoot = resolve(fileURLToPath(new URL('..', import.meta.url)))
9
10
 
11
+ /** @typedef {{ target: string, dryRun: boolean, force: boolean }} Options */
12
+ /** @typedef {{ command: string, options: Options }} ParsedArgs */
13
+
10
14
  const usage = `code-foundry — initialize and maintain agent-ready repositories
11
15
 
12
16
  Usage:
@@ -25,13 +29,17 @@ Options:
25
29
  -h, --help Show this help
26
30
  `
27
31
 
32
+ /** @param {string} message @returns {never} */
28
33
  function fail(message) {
29
34
  console.error(`code-foundry: ${message}`)
30
35
  process.exit(2)
31
36
  }
32
37
 
38
+ /** @param {string[]} argv @returns {ParsedArgs} */
33
39
  function parseArgs(argv) {
34
- const command = argv[0] && !argv[0].startsWith('-') ? argv.shift() : 'init'
40
+ const first = argv[0]
41
+ const hasCommand = Boolean(first && !first.startsWith('-'))
42
+ const command = hasCommand ? /** @type {string} */ (argv.shift()) : 'init'
35
43
  const options = { target: process.cwd(), dryRun: false, force: false }
36
44
 
37
45
  while (argv.length) {
@@ -52,34 +60,30 @@ function parseArgs(argv) {
52
60
  return { command, options }
53
61
  }
54
62
 
55
- function run(script, args, target) {
56
- const scriptPath = resolve(packageRoot, '.github/scripts', script)
57
- if (!existsSync(scriptPath)) fail(`package is missing ${script}`)
58
- const result = spawnSync('bash', [scriptPath, ...args], {
59
- cwd: target,
60
- stdio: 'inherit',
61
- env: process.env,
62
- })
63
- if (result.error) fail(result.error.message)
64
- if (result.status !== 0) process.exit(result.status ?? 1)
65
- }
66
-
67
63
  function main() {
68
64
  const { command, options } = parseArgs(process.argv.slice(2))
69
65
  const target = resolve(options.target)
70
- const common = ['--source', packageRoot, '--ref', 'main']
71
- if (options.dryRun) common.push('--check')
72
- else common.push('--apply')
73
- if (options.force) common.push('--force')
74
66
 
75
67
  if (command === 'init') {
76
- const initArgs = ['--source', packageRoot, '--ref', 'main']
77
- if (options.dryRun) initArgs.push('--dry-run')
78
- if (options.force) initArgs.push('--force')
79
- run('init-repo.sh', initArgs, target)
68
+ try {
69
+ syncRepository({ target, source: packageRoot, dryRun: options.dryRun, force: options.force, init: true })
70
+ } catch (error) {
71
+ fail(error instanceof Error ? error.message : String(error))
72
+ }
73
+ } else if (command === 'sync') {
74
+ try {
75
+ syncRepository({ target, source: packageRoot, dryRun: options.dryRun, force: options.force })
76
+ } catch (error) {
77
+ fail(error instanceof Error ? error.message : String(error))
78
+ }
79
+ } else if (command === 'doctor') {
80
+ try {
81
+ doctor(target)
82
+ } catch (error) {
83
+ console.error(`code-foundry: ${error instanceof Error ? error.message : String(error)}`)
84
+ process.exitCode = 1
85
+ }
80
86
  }
81
- else if (command === 'sync') run('sync-template.sh', common, target)
82
- else if (command === 'doctor') run('doctor.sh', [], target)
83
87
  else fail(`unknown command: ${command}`)
84
88
  }
85
89