code-foundry 1.7.0 → 1.8.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/.gitignore CHANGED
@@ -39,6 +39,8 @@ htmlcov/
39
39
  .coverage*
40
40
  .next/
41
41
  artifacts/
42
+ performance-results.json
43
+ performance-results/
42
44
  cache/
43
45
  !.github/actions/cache/
44
46
  !.github/actions/cache/action.yml
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.8.0](https://github.com/0xPlayerOne/code-foundry/compare/v1.7.0...v1.8.0) (2026-09-08)
4
+
5
+
6
+ ### Features
7
+
8
+ * **performance:** enforce source budgets ([#499](https://github.com/0xPlayerOne/code-foundry/issues/499)) ([2f65ba1](https://github.com/0xPlayerOne/code-foundry/commit/2f65ba127f8fe186eda5d6bcae77150f13458428))
9
+
3
10
  ## [1.7.0](https://github.com/0xPlayerOne/code-foundry/compare/v1.6.1...v1.7.0) (2026-09-08)
4
11
 
5
12
 
@@ -0,0 +1,58 @@
1
+ # Performance budgets and baselines
2
+
3
+ Code Foundry measures its source runtime with `bun run performance:check`. The
4
+ check writes `performance-results.json` for CI artifact upload and fails when a
5
+ budget is exceeded. Generated reports are ignored by Git because measurements
6
+ belong to the run that produced them, not the source tree.
7
+
8
+ ## Enforced budgets
9
+
10
+ | Metric | Budget | Why it is bounded |
11
+ | ----------------------------------- | -----: | ---------------------------------------------------- |
12
+ | CLI help startup p95 | 250 ms | Detect eager imports and startup regressions |
13
+ | Runtime mode startup p95 | 250 ms | Detect baseline runtime initialization regressions |
14
+ | Focused runtime tests | 10 s | Keep the representative runtime contract inexpensive |
15
+ | Format, lint, type-check, and build | 15 s | Bound the local CI feedback loop |
16
+ | Runtime dependencies | 0 | Keep the installed CLI dependency-free |
17
+ | Development dependencies | 4 | Prevent unreviewed toolchain growth |
18
+ | Packed artifact | 200 kB | Bound registry transfer and install cost |
19
+ | Unpacked artifact | 750 kB | Bound installed footprint |
20
+ | Packed files | 80 | Detect accidental release contents |
21
+
22
+ The performance workflow disables build-cache reads and writes for this task.
23
+ That makes timing comparisons independent of a warm protected-branch cache and
24
+ prevents benchmark code from populating shared cache entries.
25
+
26
+ ## v1.6.1 baseline
27
+
28
+ Measurements were taken on 2026-09-08 with Node 24.18.0. Process startup used
29
+ 30 measured samples after four warmups; before and after samples were
30
+ interleaved on the same host.
31
+
32
+ | Measurement | Before | After | Change |
33
+ | -------------------------- | -------: | ----------------------: | -------: |
34
+ | CLI help median | 36.11 ms | 29.57 ms | -18.1% |
35
+ | CLI help p95 | 38.11 ms | 31.56 ms | -17.2% |
36
+ | Runtime mode median | - | 35.94 ms | baseline |
37
+ | Focused runtime tests | - | 2.08 s | baseline |
38
+ | Local CI checks | - | 0.50 s | baseline |
39
+ | Packed / unpacked artifact | - | 160,114 / 616,887 bytes | baseline |
40
+ | Packed files | - | 74 | baseline |
41
+
42
+ The startup reduction comes from loading command implementations only after
43
+ argument parsing selects a command. `--help` no longer imports sync, release,
44
+ fleet, doctor, and CI command modules.
45
+
46
+ The first isolated full hosted audit completed in 3 minutes 2 seconds. Its
47
+ longest jobs were TypeScript CodeQL (66 s), dependency audit (62 s), and unit
48
+ tests (46 s); all other suite jobs completed in 20 seconds or less. Those
49
+ measurements identify the three lanes to optimize before adding more CI fanout.
50
+
51
+ ## Release path
52
+
53
+ Treat budget changes like source changes: explain the measured reason in a
54
+ pull request, run the complete validation gate, and merge only when the new
55
+ result artifact is available. A Release Please PR then carries the change into
56
+ the next version. Never raise a budget solely to clear CI; include before/after
57
+ measurements and the expected effect on local feedback, hosted runner time,
58
+ package transfer, or installed footprint.
package/docs/README.md CHANGED
@@ -12,6 +12,7 @@ its own names, environments, and deployment details.
12
12
  - [Release management](RELEASES.md)
13
13
  - [Publishing packages](PUBLISHING.md)
14
14
  - [Caching and remote caching](CACHING.md)
15
+ - [Performance budgets and baselines](PERFORMANCE.md)
15
16
 
16
17
  ## Repository-specific documentation
17
18
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "code-foundry",
3
- "version": "1.7.0",
3
+ "version": "1.8.0",
4
4
  "description": "A fast, language-aware repository factory for agent-ready workflows, testing, security, and release automation.",
5
5
  "homepage": "https://github.com/0xPlayerOne/code-foundry#readme",
6
6
  "bugs": {
@@ -43,6 +43,7 @@
43
43
  "format:check": "oxfmt --check .",
44
44
  "fmt": "oxfmt .",
45
45
  "lint": "oxlint",
46
+ "performance:check": "node scripts/performance-check.mjs",
46
47
  "test": "node --test",
47
48
  "test:unit": "node --test",
48
49
  "type-check": "tsc --project jsconfig.json",
package/src/cli.mjs CHANGED
@@ -4,16 +4,6 @@
4
4
  import { resolve } from 'node:path'
5
5
  import { readFileSync } from 'node:fs'
6
6
  import { fileURLToPath } from 'node:url'
7
- import { doctor } from './commands/doctor.mjs'
8
- import {
9
- dispatchPostReleaseHook,
10
- reconcileRelease,
11
- releaseRecoveryPlan,
12
- validateReleasePullRequestDiffs,
13
- } from './commands/release.mjs'
14
- import { discoverRepositories, upgradeFleet } from './commands/fleet.mjs'
15
- import { syncRepository } from './commands/sync.mjs'
16
- import { manageCiBilling } from './commands/ci.mjs'
17
7
 
18
8
  const packageRoot = resolve(fileURLToPath(new URL('..', import.meta.url)))
19
9
 
@@ -133,12 +123,13 @@ function parseArgs(argv) {
133
123
  return { command, options }
134
124
  }
135
125
 
136
- function main() {
126
+ async function main() {
137
127
  const { command, options } = parseArgs(process.argv.slice(2))
138
128
  const target = resolve(options.target)
139
129
 
140
130
  if (command === 'init') {
141
131
  try {
132
+ const { syncRepository } = await import('./commands/sync.mjs')
142
133
  syncRepository({
143
134
  target,
144
135
  source: packageRoot,
@@ -151,12 +142,14 @@ function main() {
151
142
  }
152
143
  } else if (command === 'sync') {
153
144
  try {
145
+ const { syncRepository } = await import('./commands/sync.mjs')
154
146
  syncRepository({ target, source: packageRoot, dryRun: options.dryRun, force: options.force })
155
147
  } catch (error) {
156
148
  fail(error instanceof Error ? error.message : String(error))
157
149
  }
158
150
  } else if (command === 'doctor') {
159
151
  try {
152
+ const { doctor } = await import('./commands/doctor.mjs')
160
153
  doctor(target, { github: options.github })
161
154
  } catch (error) {
162
155
  console.error(`code-foundry: ${error instanceof Error ? error.message : String(error)}`)
@@ -164,6 +157,12 @@ function main() {
164
157
  }
165
158
  } else if (command === 'release') {
166
159
  try {
160
+ const {
161
+ dispatchPostReleaseHook,
162
+ reconcileRelease,
163
+ releaseRecoveryPlan,
164
+ validateReleasePullRequestDiffs,
165
+ } = await import('./commands/release.mjs')
167
166
  if (options.releaseSubcommand === 'hook') dispatchPostReleaseHook(target, options)
168
167
  else if (options.releaseSubcommand === 'validate-prs') validateReleasePullRequestDiffs(target)
169
168
  else if (options.releaseSubcommand === 'recovery-plan') releaseRecoveryPlan(target)
@@ -173,6 +172,7 @@ function main() {
173
172
  }
174
173
  } else if (command === 'fleet') {
175
174
  try {
175
+ const { discoverRepositories, upgradeFleet } = await import('./commands/fleet.mjs')
176
176
  const root = resolve(options.root)
177
177
  if (options.fleetSubcommand === 'status')
178
178
  console.log(JSON.stringify(discoverRepositories(root), null, 2))
@@ -189,6 +189,7 @@ function main() {
189
189
  }
190
190
  } else if (command === 'ci') {
191
191
  try {
192
+ const { manageCiBilling } = await import('./commands/ci.mjs')
192
193
  manageCiBilling(target, /** @type {'pause'|'resume'|'status'} */ (options.ciSubcommand))
193
194
  } catch (error) {
194
195
  fail(error instanceof Error ? error.message : String(error))
@@ -196,7 +197,7 @@ function main() {
196
197
  } else fail(`unknown command: ${command}`)
197
198
  }
198
199
 
199
- main()
200
+ await main()
200
201
 
201
202
  /** @param {string} root @returns {string} */
202
203
  function readPackageVersion(root) {
@@ -39,6 +39,8 @@ htmlcov/
39
39
  .coverage*
40
40
  .next/
41
41
  artifacts/
42
+ performance-results.json
43
+ performance-results/
42
44
  cache/
43
45
  !.github/actions/cache/
44
46
  !.github/actions/cache/action.yml