code-foundry 1.2.0 → 1.3.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.
@@ -11,7 +11,7 @@ dependency_review: auto
11
11
  package_manager: bun
12
12
  toolchain: auto
13
13
  runtime_repository: 0xPlayerOne/code-foundry
14
- runtime_ref: v1.1.1
14
+ runtime_ref: v1.2.0
15
15
  release_type: node
16
16
  npm_publish: true
17
17
  license: agpl-3.0-or-later
@@ -77,7 +77,7 @@ jobs:
77
77
  uses: ./.github/actions/setup
78
78
  with:
79
79
  # Repository format scripts normally call a project-local formatter
80
- # (for example, Prettier). Install dependencies before running them;
80
+ # (for example, Oxfmt). Install dependencies before running them;
81
81
  # otherwise a clean runner cannot resolve the declared tool.
82
82
  install: 'true'
83
83
  cache-format: 'true'
@@ -150,12 +150,17 @@ jobs:
150
150
  const languages = JSON.parse(process.env.MATRIX_LANGUAGES || "[]");
151
151
  const shards = JSON.parse(process.env.MATRIX_SHARDS || "[\"all\"]");
152
152
  const display = { actions: "Actions", "javascript-typescript": "TypeScript", python: "Python" };
153
+ // SARIF categories are the code-scanning baseline keys: they must
154
+ // stay byte-identical to the pre-matrix values (/language:actions,
155
+ // /language:javascript-typescript, /language:python,
156
+ // /language:rust/<scope>). Any rename orphans the main-branch
157
+ // baseline and breaks alert comparison on every pull request.
153
158
  const matrix = languages
154
159
  .filter((entry) => entry.language !== "rust")
155
160
  .map((entry) => ({
156
161
  display: display[entry.language] || entry.language,
157
162
  language: entry.language,
158
- category: "/language/" + entry.language,
163
+ category: "/language:" + entry.language,
159
164
  build_mode: entry["build-mode"] || "none",
160
165
  changed: entry.changed === true,
161
166
  }));
@@ -164,7 +169,7 @@ jobs:
164
169
  matrix.push({
165
170
  display: String(shard) === "all" ? "Rust" : "Rust (" + shard + ")",
166
171
  language: "rust",
167
- category: "/language/rust",
172
+ category: "/language:rust",
168
173
  build_mode: "none",
169
174
  changed: rust.changed === true,
170
175
  shard: String(shard),
package/.oxfmtrc.json ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "semi": false,
3
+ "singleQuote": true,
4
+ "trailingComma": "es5",
5
+ "printWidth": 100,
6
+ "ignorePatterns": ["CHANGELOG.md", ".github/.code-foundry", ".github/actions/"]
7
+ }
package/.oxlintrc.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "$schema": "./node_modules/oxlint/configuration_schema.json",
3
+ "categories": { "correctness": "error" },
4
+ "ignorePatterns": ["node_modules/**"]
5
+ }
package/AGENTS.md CHANGED
@@ -112,7 +112,7 @@ Run focused tests first, then the complete applicable set for release, security,
112
112
 
113
113
  At minimum:
114
114
 
115
- - TypeScript/JavaScript: Prettier formatting, ESLint linting, type-check, build, and Bun's native test runner for unit/integration tests; use the project's native browser runner for E2E tests
115
+ - TypeScript/JavaScript: Oxfmt formatting, Oxlint linting, type-check, build, and Bun's native test runner for unit/integration tests; use the project's native browser runner for E2E tests. Repositories still on Prettier/ESLint keep working through the runtime's fallback detection until they migrate.
116
116
  - Do not add Vitest. Preserve specialized native runners such as Matchstick for The Graph and Hardhat for smart contracts.
117
117
  - Rust: default rustfmt, Clippy with warnings treated as errors, check, unit/integration tests, and dependency audit
118
118
  - Python: Ruff formatting and linting, compile or type checks, pytest, coverage, and dependency audit
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.3.0](https://github.com/0xPlayerOne/code-foundry/compare/v1.2.1...v1.3.0) (2026-09-07)
4
+
5
+
6
+ ### Features
7
+
8
+ * migrate the JavaScript toolchain from ESLint/Prettier to oxlint/oxfmt ([#471](https://github.com/0xPlayerOne/code-foundry/issues/471)) ([8ed872a](https://github.com/0xPlayerOne/code-foundry/commit/8ed872a2c61c6bbac111da645760671c49333dbd))
9
+
10
+ ## [1.2.1](https://github.com/0xPlayerOne/code-foundry/compare/v1.2.0...v1.2.1) (2026-09-06)
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * restore pre-matrix CodeQL SARIF category strings ([#468](https://github.com/0xPlayerOne/code-foundry/issues/468)) ([8c51892](https://github.com/0xPlayerOne/code-foundry/commit/8c518921bf3632ba5b8ee4ca757efe3bc302739a))
16
+
3
17
  ## [1.2.0](https://github.com/0xPlayerOne/code-foundry/compare/v1.1.1...v1.2.0) (2026-09-06)
4
18
 
5
19
 
package/README.md CHANGED
@@ -73,8 +73,9 @@ The standard workflow triggers are:
73
73
  - Draft PR automation for supported feature/fix branches.
74
74
 
75
75
  Jobs are language-aware and skip irrelevant setup while remaining visible as
76
- successful required checks. TypeScript uses ESLint, Prettier, and Bun's native
77
- test runner. Rust uses `rustfmt`, Clippy with warnings as errors, and native
76
+ successful required checks. TypeScript uses Oxlint, Oxfmt, and Bun's native
77
+ test runner (Prettier/ESLint setups keep working through fallback detection).
78
+ Rust uses `rustfmt`, Clippy with warnings as errors, and native
78
79
  Cargo tests. Python uses Ruff, uv/pip-compatible setup, and native Python
79
80
  tests. Solidity projects retain their native toolchain and test runner.
80
81
 
@@ -29,29 +29,29 @@ repository manifests and source
29
29
 
30
30
  ## Core settings
31
31
 
32
- | Key | Values | Purpose |
33
- | --- | --- | --- |
34
- | `profile` | `auto`, `application`, `monorepo`, `minimal` | Repository shape |
35
- | `languages` | detected list | TypeScript, Rust, Python, Solidity |
36
- | `package_manager` | `bun`, `pnpm`, `yarn`, `npm`, `none` | JavaScript setup |
37
- | `toolchain` | `auto`, `native`, `mise` | Environment setup policy; defaults to `auto` |
38
- | `staging_validation_mode` | `fast`, `audit` | Validation tier for pull requests targeting `staging`; defaults to `fast` |
39
- | `features` | `all` or a list | Standard workflow callers |
40
- | `codeql` | `auto`, `true`, `false` | CodeQL policy; public repositories default to enabled, non-public repositories default to disabled |
41
- | `codeql_rust_shards` | JSON array of paths | Rust scan scopes; `["all"]` keeps the safe single full scan |
42
- | `codeql_rust_threads` | integer, 1-64 | Threads per Rust CodeQL job; values above 1 opt into local parallelism |
43
- | `codeql_rust_max_parallel` | integer, 1-8 | Maximum Rust shard jobs allowed to run concurrently |
44
- | `dependency_review` | `auto`, `true`, `false` | Dependency Review policy; public repositories default to enabled, non-public repositories default to disabled |
45
- | `prune_standard` | `true` or `false` | Remove disabled standard callers |
46
- | `runtime_repository` | `OWNER/REPO` | Reusable workflow source |
47
- | `runtime_ref` | tag or branch | Reusable workflow version |
48
- | `release_type` | `node`, `python`, `rust`, `simple`, `none` | Release strategy |
49
- | `npm_publish` | `true` or `false` | Opt into npm publication |
50
- | `license` | `gpl-3.0-or-later`, `agpl-3.0-or-later`, `apache-2.0`, `mit`, `preserve`, `none` | License policy; new repositories default to GPLv3 |
51
- | `git_workflow` | `direct` (default), `staging-release` | Branch/release model; `direct` opens feature branches into `main`, `staging-release` promotes `staging` into `main` |
52
- | `merge_strategy` | `rebase` | Promotion merge method for `staging` → `main`; only enforced by the `staging-release` topology |
53
- | `release_merge_strategy` | `rebase` | Merge method for Release Please version PRs into `main`; release automation fails closed unless rebase |
54
- | `runner` fields | GitHub runner names | Per-workflow runner policy |
32
+ | Key | Values | Purpose |
33
+ | -------------------------- | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
34
+ | `profile` | `auto`, `application`, `monorepo`, `minimal` | Repository shape |
35
+ | `languages` | detected list | TypeScript, Rust, Python, Solidity |
36
+ | `package_manager` | `bun`, `pnpm`, `yarn`, `npm`, `none` | JavaScript setup |
37
+ | `toolchain` | `auto`, `native`, `mise` | Environment setup policy; defaults to `auto` |
38
+ | `staging_validation_mode` | `fast`, `audit` | Validation tier for pull requests targeting `staging`; defaults to `fast` |
39
+ | `features` | `all` or a list | Standard workflow callers |
40
+ | `codeql` | `auto`, `true`, `false` | CodeQL policy; public repositories default to enabled, non-public repositories default to disabled |
41
+ | `codeql_rust_shards` | JSON array of paths | Rust scan scopes; `["all"]` keeps the safe single full scan |
42
+ | `codeql_rust_threads` | integer, 1-64 | Threads per Rust CodeQL job; values above 1 opt into local parallelism |
43
+ | `codeql_rust_max_parallel` | integer, 1-8 | Maximum Rust shard jobs allowed to run concurrently |
44
+ | `dependency_review` | `auto`, `true`, `false` | Dependency Review policy; public repositories default to enabled, non-public repositories default to disabled |
45
+ | `prune_standard` | `true` or `false` | Remove disabled standard callers |
46
+ | `runtime_repository` | `OWNER/REPO` | Reusable workflow source |
47
+ | `runtime_ref` | tag or branch | Reusable workflow version |
48
+ | `release_type` | `node`, `python`, `rust`, `simple`, `none` | Release strategy |
49
+ | `npm_publish` | `true` or `false` | Opt into npm publication |
50
+ | `license` | `gpl-3.0-or-later`, `agpl-3.0-or-later`, `apache-2.0`, `mit`, `preserve`, `none` | License policy; new repositories default to GPLv3 |
51
+ | `git_workflow` | `direct` (default), `staging-release` | Branch/release model; `direct` opens feature branches into `main`, `staging-release` promotes `staging` into `main` |
52
+ | `merge_strategy` | `rebase` | Promotion merge method for `staging` → `main`; only enforced by the `staging-release` topology |
53
+ | `release_merge_strategy` | `rebase` | Merge method for Release Please version PRs into `main`; release automation fails closed unless rebase |
54
+ | `runner` fields | GitHub runner names | Per-workflow runner policy |
55
55
 
56
56
  Supported features are `ci`, `codeql`, `security`, `test`, `draft-pr`,
57
57
  `release-pr`, `release`, and `dependabot`.
@@ -67,7 +67,7 @@ Supported features are `ci`, `codeql`, `security`, `test`, `draft-pr`,
67
67
  repository has no preview or staging environment.
68
68
  - `staging-release` (opt-in): feature branches squash into `staging`, a
69
69
  promotion PR rebases validated changes into `main` (`merge_strategy:
70
- rebase`), and Release Please version PRs rebase into `main`
70
+ rebase`), and Release Please version PRs rebase into `main`
71
71
  (`release_merge_strategy: rebase`). Choose this only when the repository
72
72
  maintains a preview/staging environment that needs validated integration
73
73
  before release.
package/docs/WORKFLOWS.md CHANGED
@@ -7,7 +7,7 @@ points; it does not run the same suites again on branch pushes:
7
7
 
8
8
  ```yaml
9
9
  pull_request:
10
- branches: [main, staging] # staging-release topology
10
+ branches: [main, staging] # staging-release topology
11
11
  # direct topology: branches: [main]
12
12
  schedule:
13
13
  - cron: '31 6 * * 1'
@@ -71,15 +71,15 @@ honor the shared billing pause.
71
71
 
72
72
  ## Standard workflow responsibilities
73
73
 
74
- | Workflow | Responsibility |
75
- | --- | --- |
76
- | CI | Format, lint, type-check, and build |
77
- | Test | Unit, integration, E2E, and smoke tests |
78
- | Security | Profile, audits, and public-only Dependency Review |
79
- | CodeQL | GitHub-native code scanning, kept separate from CI |
80
- | Draft PR | Create/update development pull requests |
74
+ | Workflow | Responsibility |
75
+ | ---------- | ------------------------------------------------------------- |
76
+ | CI | Format, lint, type-check, and build |
77
+ | Test | Unit, integration, E2E, and smoke tests |
78
+ | Security | Profile, audits, and public-only Dependency Review |
79
+ | CodeQL | GitHub-native code scanning, kept separate from CI |
80
+ | Draft PR | Create/update development pull requests |
81
81
  | Release PR | Promote `staging` into `main` (staging-release topology only) |
82
- | Release | Release Please, GitHub release, and optional npm publication |
82
+ | Release | Release Please, GitHub release, and optional npm publication |
83
83
 
84
84
  Use concise job names such as `CI / Format`, `Test / Unit`, and
85
85
  `CodeQL / Analyze (Python)`. Per-language CodeQL analyzers (Rust shards
@@ -98,12 +98,12 @@ The merge audit pins one merge method per transition. `code-foundry doctor`
98
98
  and `code-foundry sync` fail closed on any other strategy, and the release
99
99
  workflow refuses to run unless its strategy is exactly `rebase`.
100
100
 
101
- | Transition | Merge method | Enforcement |
102
- | --- | --- | --- |
103
- | Feature/fix PR into `main` (direct topology) | Squash | Contribution policy; see `CONTRIBUTING.md` |
104
- | Feature/fix PR into `staging` (staging-release topology) | Squash | Contribution policy; see `CONTRIBUTING.md` |
105
- | `staging` → `main` promotion PR (staging-release topology) | Rebase (`merge_strategy: rebase`) | Code Foundry creates a one-commit head with `main` as its parent and the exact validated `staging` tree; `merge_strategy` must be `rebase`, and merge commits are rejected |
106
- | Release Please version PR into `main` | Rebase (`release_merge_strategy: rebase`) | Release automation fails closed unless `rebase`; never defaults to `merge`, never uses `--admin` |
101
+ | Transition | Merge method | Enforcement |
102
+ | ---------------------------------------------------------- | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
103
+ | Feature/fix PR into `main` (direct topology) | Squash | Contribution policy; see `CONTRIBUTING.md` |
104
+ | Feature/fix PR into `staging` (staging-release topology) | Squash | Contribution policy; see `CONTRIBUTING.md` |
105
+ | `staging` → `main` promotion PR (staging-release topology) | Rebase (`merge_strategy: rebase`) | Code Foundry creates a one-commit head with `main` as its parent and the exact validated `staging` tree; `merge_strategy` must be `rebase`, and merge commits are rejected |
106
+ | Release Please version PR into `main` | Rebase (`release_merge_strategy: rebase`) | Release automation fails closed unless `rebase`; never defaults to `merge`, never uses `--admin` |
107
107
 
108
108
  The promotion rows above apply only to `staging-release`; `direct`
109
109
  repositories never generate a promotion caller and `merge_strategy` is not
@@ -178,7 +178,7 @@ validation gate. Land changes through the standard `direct` or
178
178
 
179
179
  ## Language defaults
180
180
 
181
- - TypeScript/JavaScript: ESLint, Prettier, and Bun's native `bun test`.
181
+ - TypeScript/JavaScript: Oxlint, Oxfmt, and Bun's native `bun test`.
182
182
  - Rust: default `rustfmt`, Clippy with `-D warnings`, and Cargo tests.
183
183
  - Python: Ruff formatting/linting, uv when a compatible lockfile exists, and
184
184
  native Python tests.
package/package.json CHANGED
@@ -1,18 +1,16 @@
1
1
  {
2
2
  "name": "code-foundry",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "A fast, language-aware repository factory for agent-ready workflows, testing, security, and release automation.",
5
- "type": "module",
5
+ "homepage": "https://github.com/0xPlayerOne/code-foundry#readme",
6
+ "bugs": {
7
+ "url": "https://github.com/0xPlayerOne/code-foundry/issues"
8
+ },
6
9
  "license": "AGPL-3.0-or-later",
7
10
  "repository": {
8
11
  "type": "git",
9
12
  "url": "https://github.com/0xPlayerOne/code-foundry.git"
10
13
  },
11
- "homepage": "https://github.com/0xPlayerOne/code-foundry#readme",
12
- "bugs": {
13
- "url": "https://github.com/0xPlayerOne/code-foundry/issues"
14
- },
15
- "packageManager": "bun@1.4.0",
16
14
  "bin": {
17
15
  "code-foundry": "src/cli.mjs"
18
16
  },
@@ -28,32 +26,37 @@
28
26
  "release-please-config.json",
29
27
  "ruff.toml",
30
28
  ".mise.toml",
31
- ".prettierrc",
32
- ".prettierignore",
29
+ ".oxfmtrc.json",
30
+ ".oxlintrc.json",
33
31
  ".env.example",
34
32
  "AGENTS.md",
35
33
  "LICENSE",
36
34
  "NOTICE",
37
35
  "README.md"
38
36
  ],
39
- "engines": {
40
- "node": ">=20"
37
+ "type": "module",
38
+ "publishConfig": {
39
+ "access": "public"
41
40
  },
42
41
  "scripts": {
43
42
  "build": "node --check src/cli.mjs",
44
- "format:check": "node --check src/cli.mjs",
45
- "lint": "node --check src/cli.mjs",
43
+ "format:check": "oxfmt --check .",
44
+ "fmt": "oxfmt .",
45
+ "lint": "oxlint",
46
46
  "test": "node --test",
47
47
  "test:unit": "node --test",
48
48
  "type-check": "tsc --project jsconfig.json",
49
49
  "pack:check": "npm pack --dry-run",
50
50
  "prepublishOnly": "npm test && npm run pack:check"
51
51
  },
52
- "publishConfig": {
53
- "access": "public"
54
- },
55
52
  "devDependencies": {
56
53
  "@types/node": "^26.0.0",
54
+ "oxfmt": "^0.66.0",
55
+ "oxlint": "^1.81.0",
57
56
  "typescript": "^7.0.2"
58
- }
57
+ },
58
+ "engines": {
59
+ "node": ">=20"
60
+ },
61
+ "packageManager": "bun@1.4.0"
59
62
  }
package/src/cli.mjs CHANGED
@@ -5,7 +5,12 @@ import { resolve } from 'node:path'
5
5
  import { readFileSync } from 'node:fs'
6
6
  import { fileURLToPath } from 'node:url'
7
7
  import { doctor } from './commands/doctor.mjs'
8
- import { dispatchPostReleaseHook, reconcileRelease, releaseRecoveryPlan, validateReleasePullRequestDiffs } from './commands/release.mjs'
8
+ import {
9
+ dispatchPostReleaseHook,
10
+ reconcileRelease,
11
+ releaseRecoveryPlan,
12
+ validateReleasePullRequestDiffs,
13
+ } from './commands/release.mjs'
9
14
  import { discoverRepositories, upgradeFleet } from './commands/fleet.mjs'
10
15
  import { syncRepository } from './commands/sync.mjs'
11
16
  import { manageCiBilling } from './commands/ci.mjs'
@@ -60,19 +65,40 @@ function parseArgs(argv) {
60
65
  const hasCommand = Boolean(first && !first.startsWith('-'))
61
66
  const command = hasCommand ? /** @type {string} */ (argv.shift()) : 'init'
62
67
  /** @type {Options} */
63
- const options = { target: process.cwd(), root: process.cwd(), dryRun: false, force: false, github: false, createPr: false, exclude: [], base: 'main', head: 'staging', tag: '', workflow: '', mode: 'auto', version: `v${readPackageVersion(packageRoot)}` }
68
+ const options = {
69
+ target: process.cwd(),
70
+ root: process.cwd(),
71
+ dryRun: false,
72
+ force: false,
73
+ github: false,
74
+ createPr: false,
75
+ exclude: [],
76
+ base: 'main',
77
+ head: 'staging',
78
+ tag: '',
79
+ workflow: '',
80
+ mode: 'auto',
81
+ version: `v${readPackageVersion(packageRoot)}`,
82
+ }
64
83
 
65
84
  if (command === 'release') {
66
85
  const subcommand = argv.shift() ?? ''
67
- if (!['reconcile', 'hook', 'validate-prs', 'recovery-plan'].includes(subcommand)) fail(`unknown release command: ${subcommand ?? '(missing)'}; use release reconcile, release hook, release validate-prs, or release recovery-plan`)
86
+ if (!['reconcile', 'hook', 'validate-prs', 'recovery-plan'].includes(subcommand))
87
+ fail(
88
+ `unknown release command: ${subcommand ?? '(missing)'}; use release reconcile, release hook, release validate-prs, or release recovery-plan`
89
+ )
68
90
  options.releaseSubcommand = subcommand
69
91
  } else if (command === 'fleet') {
70
92
  const subcommand = argv.shift() ?? ''
71
- if (subcommand !== 'status' && subcommand !== 'upgrade') fail(`unknown fleet command: ${subcommand ?? '(missing)'}; use fleet status or fleet upgrade`)
93
+ if (subcommand !== 'status' && subcommand !== 'upgrade')
94
+ fail(`unknown fleet command: ${subcommand ?? '(missing)'}; use fleet status or fleet upgrade`)
72
95
  options.fleetSubcommand = subcommand
73
96
  } else if (command === 'ci') {
74
97
  const subcommand = argv.shift() ?? ''
75
- if (!['pause', 'resume', 'status'].includes(subcommand)) fail(`unknown ci command: ${subcommand || '(missing)'}; use ci pause, ci resume, or ci status`)
98
+ if (!['pause', 'resume', 'status'].includes(subcommand))
99
+ fail(
100
+ `unknown ci command: ${subcommand || '(missing)'}; use ci pause, ci resume, or ci status`
101
+ )
76
102
  options.ciSubcommand = /** @type {'pause'|'resume'|'status'} */ (subcommand)
77
103
  }
78
104
 
@@ -92,12 +118,15 @@ function parseArgs(argv) {
92
118
  else if (arg === '--base') options.base = argv.shift() ?? fail('--base requires a branch')
93
119
  else if (arg === '--head') options.head = argv.shift() ?? fail('--head requires a branch')
94
120
  else if (arg === '--tag') options.tag = argv.shift() ?? fail('--tag requires a tag')
95
- else if (arg === '--workflow') options.workflow = argv.shift() ?? fail('--workflow requires a workflow')
96
- else if (arg === '--mode') options.mode = argv.shift() ?? fail('--mode requires a delivery mode')
121
+ else if (arg === '--workflow')
122
+ options.workflow = argv.shift() ?? fail('--workflow requires a workflow')
123
+ else if (arg === '--mode')
124
+ options.mode = argv.shift() ?? fail('--mode requires a delivery mode')
97
125
  else if (arg === '--root') options.root = argv.shift() ?? fail('--root requires a path')
98
126
  else if (arg === '--create-pr') options.createPr = true
99
127
  else if (arg === '--version') options.version = argv.shift() ?? fail('--version requires a tag')
100
- else if (arg === '--exclude') options.exclude.push(argv.shift() ?? fail('--exclude requires a name'))
128
+ else if (arg === '--exclude')
129
+ options.exclude.push(argv.shift() ?? fail('--exclude requires a name'))
101
130
  else fail(`unknown option: ${arg}; run --help for the supported options`)
102
131
  }
103
132
 
@@ -110,7 +139,13 @@ function main() {
110
139
 
111
140
  if (command === 'init') {
112
141
  try {
113
- syncRepository({ target, source: packageRoot, dryRun: options.dryRun, force: options.force, init: true })
142
+ syncRepository({
143
+ target,
144
+ source: packageRoot,
145
+ dryRun: options.dryRun,
146
+ force: options.force,
147
+ init: true,
148
+ })
114
149
  } catch (error) {
115
150
  fail(error instanceof Error ? error.message : String(error))
116
151
  }
@@ -139,8 +174,16 @@ function main() {
139
174
  } else if (command === 'fleet') {
140
175
  try {
141
176
  const root = resolve(options.root)
142
- if (options.fleetSubcommand === 'status') console.log(JSON.stringify(discoverRepositories(root), null, 2))
143
- else upgradeFleet(root, packageRoot, { createPr: options.createPr, dryRun: options.dryRun, force: options.force, version: options.version, exclude: options.exclude })
177
+ if (options.fleetSubcommand === 'status')
178
+ console.log(JSON.stringify(discoverRepositories(root), null, 2))
179
+ else
180
+ upgradeFleet(root, packageRoot, {
181
+ createPr: options.createPr,
182
+ dryRun: options.dryRun,
183
+ force: options.force,
184
+ version: options.version,
185
+ exclude: options.exclude,
186
+ })
144
187
  } catch (error) {
145
188
  fail(error instanceof Error ? error.message : String(error))
146
189
  }
@@ -150,13 +193,16 @@ function main() {
150
193
  } catch (error) {
151
194
  fail(error instanceof Error ? error.message : String(error))
152
195
  }
153
- }
154
- else fail(`unknown command: ${command}`)
196
+ } else fail(`unknown command: ${command}`)
155
197
  }
156
198
 
157
199
  main()
158
200
 
159
201
  /** @param {string} root @returns {string} */
160
202
  function readPackageVersion(root) {
161
- try { return JSON.parse(readFileSync(resolve(root, 'package.json'), 'utf8')).version ?? '0.0.0' } catch { return '0.0.0' }
203
+ try {
204
+ return JSON.parse(readFileSync(resolve(root, 'package.json'), 'utf8')).version ?? '0.0.0'
205
+ } catch {
206
+ return '0.0.0'
207
+ }
162
208
  }