code-foundry 0.21.2 → 0.22.0

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/README.md CHANGED
@@ -34,6 +34,10 @@ npx code-foundry init --dry-run
34
34
  For an existing installation, use `npx code-foundry sync`. Run
35
35
  `npx code-foundry doctor` to inspect the resulting repository configuration.
36
36
 
37
+ If `.github/code-foundry.yml` already exists, initialization uses it automatically.
38
+ You can also supply a different file with `--config PATH`; after changing the
39
+ file, run `npx code-foundry sync` to render the selected configuration.
40
+
37
41
  ## What it installs
38
42
 
39
43
  - Short workflow callers for CI, Test, Security, CodeQL, Draft PR, Release PR,
@@ -66,11 +70,12 @@ Initialization is flag-driven. The most important options are:
66
70
  --license-file PATH
67
71
  ```
68
72
 
69
- The selected profile is saved in `.github/template.yml`. Explicit flags take
73
+ The selected profile is saved in `.github/code-foundry.yml`. Explicit flags take
70
74
  precedence over `REPO_FOUNDRY_*` environment/repository variables, which take
71
75
  precedence over that file and automatic detection. See
72
- [Initialization and synchronization](docs/INITIALIZATION.md) for the full
73
- configuration contract.
76
+ [Configuration reference](docs/CONFIGURATION.md) for the visual configuration
77
+ guide and [Initialization and synchronization](docs/INITIALIZATION.md) for
78
+ the safety and precedence rules.
74
79
 
75
80
  New repositories default to AGPL-3.0-or-later. Synchronization preserves an
76
81
  existing license unless a replacement is explicitly selected. Authored
@@ -0,0 +1,87 @@
1
+ # Configuration reference
2
+
3
+ `.github/code-foundry.yml` is the repository's single Code Foundry control plane.
4
+ Initialize from it with:
5
+
6
+ ```bash
7
+ npx code-foundry init --config .github/code-foundry.yml
8
+ ```
9
+
10
+ After initialization, edit the file and run `npx code-foundry sync` to render
11
+ the selected callers and refresh the local baseline. Existing authored files
12
+ and custom workflows remain protected.
13
+
14
+ ## Configuration flow
15
+
16
+ ```text
17
+ code-foundry.yml
18
+ |
19
+ +--> profile and language detection
20
+ +--> enabled standard workflow callers
21
+ +--> runtime repository and ref
22
+ +--> workflow runner selection
23
+ +--> release, license, cache, and coverage policy
24
+ ```
25
+
26
+ ## Core settings
27
+
28
+ | Key | Values | Purpose |
29
+ | --- | --- | --- |
30
+ | `profile` | `auto`, `application`, `monorepo`, `minimal` | Repository shape |
31
+ | `languages` | `auto` or comma-separated languages | Toolchain and CodeQL scope |
32
+ | `package_manager` | `auto`, `bun`, `pnpm`, `yarn`, `npm` | Locked JavaScript setup |
33
+ | `features` | `all` or comma-separated names | Standard callers to install |
34
+ | `prune_standard` | `true` or `false` | Remove disabled standard callers on sync |
35
+ | `runtime_repository` | `OWNER/REPO` or blank | Reusable workflow source |
36
+ | `runtime_ref` | tag or branch | Reusable workflow version |
37
+ | `release_type` | `auto`, `node`, `python`, `rust`, `simple`, `none` | Release Please strategy |
38
+ | `npm_publish` | `true` or `false` | Opt into npm publication |
39
+ | `license` | license name, `preserve`, `none` | License generation policy |
40
+ | `license_file` | path | Optional exact license source |
41
+
42
+ Supported languages are TypeScript, Rust, Python, and Solidity. Supported
43
+ features are `ci`, `codeql`, `security`, `test`, `draft-pr`, `release-pr`,
44
+ `release`, and `dependabot`.
45
+
46
+ ## Workflow runners
47
+
48
+ Each caller can select its default runner without editing workflow YAML:
49
+
50
+ | Key | Default | Controls |
51
+ | --- | --- | --- |
52
+ | `runner` | `ubuntu-latest` | Shared fallback |
53
+ | `unit_runner` | `ubuntu-slim` | Unit tests |
54
+ | `ci_runner` | `ubuntu-latest` | Format, lint, type-check, build |
55
+ | `test_runner` | `ubuntu-latest` | Integration, E2E, smoke |
56
+ | `security_runner` | `ubuntu-slim` | Profile and dependency security jobs |
57
+ | `codeql_runner` | `ubuntu-latest` | CodeQL detection and analyzers |
58
+ | `pr_runner` | `ubuntu-slim` | Draft and Release PR automation |
59
+ | `release_runner` | `ubuntu-slim` | Release and package publication |
60
+
61
+ Use the full runner for native toolchains, browsers, or measured dependency
62
+ workloads. Use `ubuntu-slim` for lightweight orchestration and small projects.
63
+
64
+ ## Performance and quality
65
+
66
+ | Key | Default | Purpose |
67
+ | --- | --- | --- |
68
+ | `cache_packages` | `auto` | Package-store caching policy |
69
+ | `cache_build` | `auto` | Build-cache policy |
70
+ | `coverage_minimum` | `80` | Shared Bun/Python coverage target |
71
+ | `turbo_remote` | `auto` | Turborepo remote-cache policy |
72
+
73
+ Turborepo remote caching still requires the repository secret `TURBO_TOKEN` and
74
+ the variable `TURBO_TEAM`; the file controls policy, not credentials.
75
+
76
+ ## Precedence
77
+
78
+ The resolved value order is:
79
+
80
+ ```text
81
+ explicit CLI flag -> REPO_FOUNDRY_* variable -> code-foundry.yml -> detection/default
82
+ ```
83
+
84
+ Use variables for temporary CI overrides. Keep durable repository policy in
85
+ `.github/code-foundry.yml` so humans and agents have one discoverable source of
86
+ truth. The example file is a commented starter guide; it is intentionally not
87
+ a second generated configuration.
@@ -10,6 +10,17 @@ npx code-foundry sync [options]
10
10
  npx code-foundry doctor
11
11
  ```
12
12
 
13
+ When `.github/code-foundry.yml` already exists, `init` treats it as the primary
14
+ configuration and does not replace its values with CLI defaults. To use another
15
+ file, pass it explicitly:
16
+
17
+ ```bash
18
+ npx code-foundry init --config ./configs/code-foundry.yml
19
+ ```
20
+
21
+ The file is copied to `.github/code-foundry.yml`, normalized, and used to render
22
+ the standard callers. Later edits can be applied with `npx code-foundry sync`.
23
+
13
24
  Use `--dry-run` to preview changes. Use `--no-bootstrap` when the repository is
14
25
  being initialized in CI or on a machine without mise. Run
15
26
  `bash .github/scripts/bootstrap.sh` later to install tools, enable hooks, and
@@ -38,7 +49,7 @@ npx code-foundry init \
38
49
  --runtime-ref v1.2.3
39
50
  ```
40
51
 
41
- Both values are persisted in `.github/template.yml` and rendered into the
52
+ Both values are persisted in `.github/code-foundry.yml` and rendered into the
42
53
  standard callers. `REPO_FOUNDRY_RUNTIME_REPOSITORY` and
43
54
  `REPO_FOUNDRY_RUNTIME_REF` provide equivalent environment/repository-variable
44
55
  overrides.
@@ -51,6 +62,6 @@ documentation. Existing licenses are preserved unless a license or license
51
62
  file is explicitly selected. Use `--force` only when intentionally refreshing
52
63
  protected standard documents.
53
64
 
54
- The initializer generates `.github/template.yml` as the repository-owned
65
+ The initializer generates `.github/code-foundry.yml` as the repository-owned
55
66
  configuration contract. Keep project-specific settings there rather than
56
67
  editing generated workflow callers by hand.
package/docs/README.md CHANGED
@@ -7,6 +7,7 @@ its own names, environments, and deployment details.
7
7
  ## Guides
8
8
 
9
9
  - [Initialization and synchronization](INITIALIZATION.md)
10
+ - [Configuration reference](CONFIGURATION.md)
10
11
  - [Workflow and CI conventions](WORKFLOWS.md)
11
12
  - [Release management](RELEASES.md)
12
13
  - [Publishing packages](PUBLISHING.md)
package/docs/RELEASES.md CHANGED
@@ -21,7 +21,7 @@ body. Existing `CHANGELOG.md` history remains repository-owned.
21
21
 
22
22
  ## Configuration
23
23
 
24
- Set these values in `.github/template.yml`:
24
+ Set these values in `.github/code-foundry.yml`:
25
25
 
26
26
  ```yaml
27
27
  release_type: auto # auto, node, python, rust, simple, or none
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "code-foundry",
3
- "version": "0.21.2",
3
+ "version": "0.22.0",
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",
package/src/cli.mjs CHANGED
@@ -18,6 +18,7 @@ Init/sync options:
18
18
  --target PATH Repository directory (default: current directory)
19
19
  --source PATH_OR_URL Template source override
20
20
  --ref REF Template branch or tag (default: main)
21
+ --config PATH Use a .github/code-foundry.yml configuration file
21
22
  --profile NAME auto, application, monorepo, or minimal
22
23
  --languages LIST auto or typescript,rust,python,solidity
23
24
  --features LIST all or ci,codeql,security,test,draft-pr,release-pr,release,dependabot
@@ -47,6 +48,7 @@ function parseArgs(argv) {
47
48
  target: process.cwd(),
48
49
  source: packageRoot,
49
50
  ref: 'main',
51
+ config: process.env.REPO_FOUNDRY_CONFIG || '',
50
52
  profile: process.env.REPO_FOUNDRY_PROFILE || 'auto',
51
53
  languages: process.env.REPO_FOUNDRY_LANGUAGES || 'auto',
52
54
  features: process.env.REPO_FOUNDRY_FEATURES || 'all',
@@ -62,6 +64,14 @@ function parseArgs(argv) {
62
64
  npmPublish: process.env.REPO_FOUNDRY_NPM_PUBLISH === 'true',
63
65
  languagesSet: false,
64
66
  featuresSet: false,
67
+ profileSet: Boolean(process.env.REPO_FOUNDRY_PROFILE),
68
+ packageManagerSet: Boolean(process.env.REPO_FOUNDRY_PACKAGE_MANAGER),
69
+ runtimeRepositorySet: Boolean(process.env.REPO_FOUNDRY_RUNTIME_REPOSITORY),
70
+ runtimeRefSet: Boolean(process.env.REPO_FOUNDRY_RUNTIME_REF),
71
+ releaseTypeSet: Boolean(process.env.REPO_FOUNDRY_RELEASE_TYPE),
72
+ licenseSet: Boolean(process.env.REPO_FOUNDRY_LICENSE),
73
+ licenseFileSet: Boolean(process.env.REPO_FOUNDRY_LICENSE_FILE),
74
+ npmPublishSet: Boolean(process.env.REPO_FOUNDRY_NPM_PUBLISH),
65
75
  dryRun: false,
66
76
  prune: false,
67
77
  force: false,
@@ -72,6 +82,7 @@ function parseArgs(argv) {
72
82
  ['--target', 'target'],
73
83
  ['--source', 'source'],
74
84
  ['--ref', 'ref'],
85
+ ['--config', 'config'],
75
86
  ['--profile', 'profile'],
76
87
  ['--languages', 'languages'],
77
88
  ['--features', 'features'],
@@ -95,6 +106,13 @@ function parseArgs(argv) {
95
106
  options[values.get(arg)] = value
96
107
  if (arg === '--languages') options.languagesSet = true
97
108
  if (arg === '--features') options.featuresSet = true
109
+ if (arg === '--profile') options.profileSet = true
110
+ if (arg === '--package-manager') options.packageManagerSet = true
111
+ if (arg === '--runtime-repository') options.runtimeRepositorySet = true
112
+ if (arg === '--runtime-ref') options.runtimeRefSet = true
113
+ if (arg === '--release-type') options.releaseTypeSet = true
114
+ if (arg === '--license') options.licenseSet = true
115
+ if (arg === '--license-file') options.licenseFileSet = true
98
116
  continue
99
117
  }
100
118
  if (arg === '--dry-run') options.dryRun = true
@@ -102,7 +120,7 @@ function parseArgs(argv) {
102
120
  else if (arg === '--prune') options.prune = true
103
121
  else if (arg === '--protection') options.protection = true
104
122
  else if (arg === '--no-bootstrap') options.bootstrap = false
105
- else if (arg === '--npm-publish') options.npmPublish = true
123
+ else if (arg === '--npm-publish') { options.npmPublish = true; options.npmPublishSet = true }
106
124
  else fail(`unknown option: ${arg}`)
107
125
  }
108
126
 
@@ -125,12 +143,16 @@ function main() {
125
143
  const { command, options } = parseArgs(process.argv.slice(2))
126
144
  const target = resolve(options.target)
127
145
  const common = ['--source', options.source, '--ref', options.ref]
128
- common.push('--license', options.license)
129
- if (options.licenseFile) common.push('--license-file', options.licenseFile)
146
+ if (options.config) common.push('--config', options.config)
147
+ if (options.profileSet) common.push('--profile', options.profile)
130
148
  if (options.languagesSet) common.push('--languages', options.languages)
131
149
  if (options.featuresSet) common.push('--features', options.features)
132
- if (options.runtimeRepository) common.push('--runtime-repository', options.runtimeRepository)
133
- if (options.runtimeRef) common.push('--runtime-ref', options.runtimeRef)
150
+ if (options.packageManagerSet) common.push('--package-manager', options.packageManager)
151
+ if (options.runtimeRepositorySet) common.push('--runtime-repository', options.runtimeRepository)
152
+ if (options.runtimeRefSet) common.push('--runtime-ref', options.runtimeRef)
153
+ if (options.releaseTypeSet) common.push('--release-type', options.releaseType)
154
+ if (options.licenseSet) common.push('--license', options.license)
155
+ if (options.licenseFileSet && options.licenseFile) common.push('--license-file', options.licenseFile)
134
156
  if (options.prune) common.push('--prune')
135
157
  if (options.force) common.push('--force')
136
158
  if (options.dryRun) common.push('--check')
@@ -140,21 +162,22 @@ function main() {
140
162
  const initArgs = [
141
163
  '--source', options.source,
142
164
  '--ref', options.ref,
143
- '--profile', options.profile,
144
- '--languages', options.languages,
145
- '--features', options.features,
146
- '--package-manager', options.packageManager,
147
- '--release-type', options.releaseType,
148
- '--license', options.license,
149
165
  ]
150
- if (options.runtimeRepository) initArgs.push('--runtime-repository', options.runtimeRepository)
151
- if (options.runtimeRef) initArgs.push('--runtime-ref', options.runtimeRef)
152
- if (options.licenseFile) initArgs.push('--license-file', options.licenseFile)
166
+ if (options.profileSet) initArgs.push('--profile', options.profile)
167
+ if (options.languagesSet) initArgs.push('--languages', options.languages)
168
+ if (options.featuresSet) initArgs.push('--features', options.features)
169
+ if (options.packageManagerSet) initArgs.push('--package-manager', options.packageManager)
170
+ if (options.releaseTypeSet) initArgs.push('--release-type', options.releaseType)
171
+ if (options.licenseSet) initArgs.push('--license', options.license)
172
+ if (options.config) initArgs.push('--config', options.config)
173
+ if (options.runtimeRepositorySet) initArgs.push('--runtime-repository', options.runtimeRepository)
174
+ if (options.runtimeRefSet) initArgs.push('--runtime-ref', options.runtimeRef)
175
+ if (options.licenseFileSet && options.licenseFile) initArgs.push('--license-file', options.licenseFile)
153
176
  if (options.protection) initArgs.push('--protection')
154
177
  if (options.dryRun) initArgs.push('--dry-run')
155
178
  if (options.prune) initArgs.push('--prune')
156
179
  if (options.force) initArgs.push('--force')
157
- if (options.npmPublish) initArgs.push('--npm-publish')
180
+ if (options.npmPublishSet && options.npmPublish) initArgs.push('--npm-publish')
158
181
  if (!options.bootstrap) initArgs.push('--no-bootstrap')
159
182
  run('init-repo.sh', initArgs, target)
160
183
  } else if (command === 'sync') {
@@ -1,18 +0,0 @@
1
- # Repository-specific settings for the shared initializer and sync scripts.
2
- version: 1
3
- template: code-foundry@latest
4
- profile: auto
5
- languages: auto
6
- features: all
7
- package_manager: auto
8
- runtime_repository: 0xPlayerOne/code-foundry
9
- runtime_ref: v0.20.2
10
- release_type: auto
11
- npm_publish: false
12
- license: preserve
13
- runner: ubuntu-latest
14
- unit_runner: ubuntu-slim
15
- cache_packages: auto
16
- cache_build: auto
17
- coverage_minimum: 80
18
- turbo_remote: auto