Skip to content

Commit aca08dc

Browse files
committed
chore(scripts): adopt canonical fix.mts (gains --all support + zizmor + agentshield)
Replaces the inline `oxfmt --write . && oxlint --fix -c .oxlintrc.json` form of `scripts.fix` with `node scripts/fix.mts`, the rich form that the rest of the fleet uses. The inline form rejected `--all` (oxlint complained about an unknown flag), forcing maintainers to remember which repos accepted the canonical fleet flag and which didn't. The new fix.mts forwards extra argv to `pnpm run lint --fix`, so `pnpm run fix --all` now works uniformly across the fleet, plus `pnpm run fix --staged` and explicit file paths. It also gains the two security-fixer steps every other fleet repo runs at fix time: 1. zizmor --fix .github/ (GitHub Actions workflow fixes) 2. agentshield scan --fix (Claude config fixes) Both are conditional — skipped when the relevant directory doesn't exist (.github/ for zizmor, .claude/ + agentshield install for agentshield). The lint step still runs first so format/lint fixes land before any security re-scans.
1 parent 6584730 commit aca08dc

2 files changed

Lines changed: 92 additions & 1 deletion

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"check:paths": "node scripts/check-paths.mts",
1717
"clean": "node scripts/clean.mts",
1818
"cover": "COVERAGE=true pnpm exec vitest run --coverage --config .config/vitest.config.mts",
19-
"fix": "oxfmt --write . && oxlint --fix -c .oxlintrc.json",
19+
"fix": "node scripts/fix.mts",
2020
"format": "oxfmt --write .",
2121
"format:check": "oxfmt --check .",
2222
"lint": "node scripts/lint.mts",

scripts/fix.mts

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/**
2+
* @fileoverview Auto-fix script — runs linters with --fix, then security
3+
* tools (zizmor, agentshield) if available.
4+
*
5+
* Steps:
6+
* 1. pnpm run lint --fix — oxlint + oxfmt (forwards extra argv like --all)
7+
* 2. zizmor --fix .github/ — GitHub Actions workflow fixes
8+
* (skipped if .github/ doesn't exist)
9+
* 3. agentshield scan --fix — Claude config fixes
10+
* (skipped if .claude/ or agentshield isn't installed)
11+
*
12+
* Forwards `process.argv.slice(2)` to the lint step, so
13+
* `pnpm run fix --all` runs `pnpm run lint --fix --all` (full-tree
14+
* fix), and `pnpm run fix --staged` does the staged-only flow.
15+
*/
16+
17+
import { existsSync } from 'node:fs'
18+
import process from 'node:process'
19+
20+
import { getDefaultLogger } from '@socketsecurity/lib/logger'
21+
import { spawn } from '@socketsecurity/lib/spawn'
22+
23+
const WIN32 = process.platform === 'win32'
24+
const logger = getDefaultLogger()
25+
26+
async function run(
27+
cmd: string,
28+
args: string[],
29+
{ label, required = true }: { label?: string; required?: boolean } = {},
30+
): Promise<number> {
31+
try {
32+
const result = await spawn(cmd, args, {
33+
shell: WIN32,
34+
stdio: 'inherit',
35+
})
36+
if (result.code !== 0 && required) {
37+
logger.error(`${label || cmd} failed (exit ${result.code})`)
38+
return result.code
39+
}
40+
if (result.code !== 0) {
41+
// Non-blocking: log warning and continue.
42+
logger.warn(`${label || cmd}: exited ${result.code} (non-blocking)`)
43+
}
44+
return 0
45+
} catch (e) {
46+
const msg = e instanceof Error ? e.message : String(e)
47+
if (!required) {
48+
logger.warn(`${label || cmd}: ${msg} (non-blocking)`)
49+
return 0
50+
}
51+
throw e
52+
}
53+
}
54+
55+
async function main(): Promise<void> {
56+
// Step 1: Lint fix — delegates to scripts/lint.mts which runs both
57+
// oxfmt and oxlint. Forward extra argv so `--all` / `--staged` /
58+
// explicit file paths reach the lint runner unchanged.
59+
const lintExit = await run(
60+
'pnpm',
61+
['run', 'lint', '--fix', ...process.argv.slice(2)],
62+
{ label: 'lint --fix' },
63+
)
64+
if (lintExit) {
65+
process.exitCode = lintExit
66+
}
67+
68+
// Step 2: zizmor — fixes GitHub Actions workflow security issues.
69+
// Only runs if .github/ directory exists (some repos don't have workflows).
70+
if (existsSync('.github')) {
71+
await run('zizmor', ['--fix', '.github/'], {
72+
label: 'zizmor --fix',
73+
required: false,
74+
})
75+
}
76+
77+
// Step 3: AgentShield — fixes Claude config security findings.
78+
// Only runs if .claude/ exists and agentshield binary is installed.
79+
if (existsSync('.claude') && existsSync('node_modules/.bin/agentshield')) {
80+
await run('pnpm', ['exec', 'agentshield', 'scan', '--fix'], {
81+
label: 'agentshield --fix',
82+
required: false,
83+
})
84+
}
85+
}
86+
87+
main().catch((e: unknown) => {
88+
const msg = e instanceof Error ? e.message : String(e)
89+
logger.error(msg)
90+
process.exitCode = 1
91+
})

0 commit comments

Comments
 (0)