mirror of
https://github.com/Gitlawb/openclaude.git
synced 2026-11-06 20:58:14 -04:00
chore(deps): update execa to 10.x and chalk to 6.x (#2385)
This commit is contained in:
@@ -203,6 +203,31 @@ untouched. When updating `marked`, compare representative terminal, table, list,
|
||||
code, link, streaming, and memory-file output and run the markdown regression tests.
|
||||
Regenerate the exact dependency pin and lockfile with `bun add --exact marked@<version>`.
|
||||
|
||||
### Subprocesses and terminal colors
|
||||
|
||||
Use the exact `execa` and `chalk` pins in `package.json` and their public ESM
|
||||
exports and bundled types. Regenerate both pins and the lockfile with
|
||||
`bun add --exact execa@<version> chalk@<version>`.
|
||||
|
||||
Prefer asynchronous `execa(file, args, options)`; use `shell: true` only for
|
||||
commands that need shell syntax. With `reject: false`, check `failed`,
|
||||
`timedOut` and `exitCode` before consuming `stdout` or `stderr`. Use
|
||||
`SyncOptions` for synchronous options. The subprocess is a promise; access
|
||||
Node child-process event and lifecycle APIs through `subprocess.nodeChildProcess`.
|
||||
Use template strings or `parseCommandString()` for command splitting, and
|
||||
`ipc: true` for IPC. Explicit `input` takes precedence over inherited stdin;
|
||||
set stdin deliberately, and bound subprocess output with `maxBuffer` and
|
||||
execution time with `timeout`.
|
||||
|
||||
Use the shared default `chalk` instance for terminal styles and the existing
|
||||
`colorize()` and theme helpers for theme colors. Keep the VS Code color boost
|
||||
and tmux clamp in `src/ink/colorize.ts`. Numeric `FORCE_COLOR` selects an exact
|
||||
level (0 disables color, 1 selects 16 colors, 2 selects 256, 3 selects truecolor);
|
||||
`ansi256()` and `bgAnsi256()` downsample at level 1. Use `new Chalk({ level })`
|
||||
only when a separate capability level is intentional, as for Apple Terminal
|
||||
charts. Tests that change `chalk.level` must restore it, and environment-driven
|
||||
color detection tests must import in a fresh process.
|
||||
|
||||
## AI Agent Guidelines
|
||||
|
||||
If you are an AI agent (Copilot, Cursor, Claude, etc.) working on this codebase, refer to [AGENTS.md](AGENTS.md) for project-specific coding guidelines, conventions, and validation commands. Following these guidelines will help your contributions align with the project's patterns and reduce review friction.
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
"auto-bind": "5.0.1",
|
||||
"axios": "1.20.0",
|
||||
"bidi-js": "1.1.0",
|
||||
"chalk": "5.6.2",
|
||||
"chalk": "6.0.1",
|
||||
"chokidar": "4.0.3",
|
||||
"cli-boxes": "4.0.1",
|
||||
"cli-highlight": "2.1.11",
|
||||
@@ -46,7 +46,7 @@
|
||||
"emoji-regex": "11.0.0",
|
||||
"env-paths": "4.0.0",
|
||||
"eslint": "9.39.5",
|
||||
"execa": "9.6.1",
|
||||
"execa": "10.2.1",
|
||||
"fflate": "0.8.3",
|
||||
"figures": "6.1.0",
|
||||
"fuse.js": "7.5.0",
|
||||
@@ -649,7 +649,7 @@
|
||||
|
||||
"camelcase": ["camelcase@5.3.1", "", {}, "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="],
|
||||
|
||||
"chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="],
|
||||
"chalk": ["chalk@6.0.1", "", {}, "sha512-/Ce6KNm3vIbWdMlNna6RVIZ/ICQxnJxCicet5LBKK9ZffBkqzDw0xh9EiKSljdRtiIQ1S1z4YgcscUUGzNCWrA=="],
|
||||
|
||||
"chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="],
|
||||
|
||||
@@ -767,7 +767,7 @@
|
||||
|
||||
"eventsource-parser": ["eventsource-parser@3.0.8", "", {}, "sha512-70QWGkr4snxr0OXLRWsFLeRBIRPuQOvt4s8QYjmUlmlkyTZkRqS7EDVRZtzU3TiyDbXSzaOeF0XUKy8PchzukQ=="],
|
||||
|
||||
"execa": ["execa@9.6.1", "", { "dependencies": { "@sindresorhus/merge-streams": "^4.0.0", "cross-spawn": "^7.0.6", "figures": "^6.1.0", "get-stream": "^9.0.0", "human-signals": "^8.0.1", "is-plain-obj": "^4.1.0", "is-stream": "^4.0.1", "npm-run-path": "^6.0.0", "pretty-ms": "^9.2.0", "signal-exit": "^4.1.0", "strip-final-newline": "^4.0.0", "yoctocolors": "^2.1.1" } }, "sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA=="],
|
||||
"execa": ["execa@10.2.1", "", { "dependencies": { "@sindresorhus/merge-streams": "^4.0.0", "figures": "^6.1.0", "get-stream": "^9.0.1", "human-signals": "^8.0.1", "is-plain-obj": "^4.1.0", "is-stream": "^4.0.1", "npm-run-path": "^6.0.0", "pretty-ms": "^9.3.1", "signal-exit": "^4.1.0", "strip-final-newline": "^4.0.0", "which-command": "^0.1.0", "yoctocolors": "^2.2.0" } }, "sha512-/Bofl3ZBh2Q4/PG0W63qFzP5vDAypi8Zc90UWTBzaDNIYiX7apPOd0N6L8hG8CojUdq4V51adu8BObP+iVsSTw=="],
|
||||
|
||||
"express": ["express@5.2.1", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "depd": "^2.0.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" } }, "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw=="],
|
||||
|
||||
@@ -1081,7 +1081,7 @@
|
||||
|
||||
"prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
|
||||
|
||||
"pretty-ms": ["pretty-ms@9.3.0", "", { "dependencies": { "parse-ms": "^4.0.0" } }, "sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ=="],
|
||||
"pretty-ms": ["pretty-ms@9.3.1", "", { "dependencies": { "parse-ms": "^4.0.0" } }, "sha512-HzMy3Geq23nVALD/M2LliU+F+M+gVNsvkQWWqeBZ8HDiCgzo6YPJ/Omrmtq24EFrIsk0a3EkQGEd7bDOo+IhGA=="],
|
||||
|
||||
"proper-lockfile": ["proper-lockfile@4.1.2", "", { "dependencies": { "graceful-fs": "^4.2.4", "retry": "^0.12.0", "signal-exit": "^3.0.2" } }, "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA=="],
|
||||
|
||||
@@ -1245,6 +1245,8 @@
|
||||
|
||||
"which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
|
||||
|
||||
"which-command": ["which-command@0.1.0", "", { "bin": { "which-command": "cli.js" } }, "sha512-XZyoF5/5hZtXitIwzrU4NKK+Wtbb9aB9CezUEw2Q0wlYK8NUYQxC1rRXgNueYLtBAJwXIb+/tFVk4dozciNJMA=="],
|
||||
|
||||
"which-module": ["which-module@2.0.1", "", {}, "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ=="],
|
||||
|
||||
"word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="],
|
||||
@@ -1269,7 +1271,7 @@
|
||||
|
||||
"yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
|
||||
|
||||
"yoctocolors": ["yoctocolors@2.1.2", "", {}, "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug=="],
|
||||
"yoctocolors": ["yoctocolors@2.2.0", "", {}, "sha512-xYqdZFUK/VYazNl/oCDYN+3WloWQwMfZxBoiNt6qNyk+xfOdi598muWE42rNZFp1kNOiqW936q5RhUdnpqElSg=="],
|
||||
|
||||
"zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
|
||||
|
||||
|
||||
+2
-2
@@ -115,7 +115,7 @@
|
||||
"auto-bind": "5.0.1",
|
||||
"axios": "1.20.0",
|
||||
"bidi-js": "1.1.0",
|
||||
"chalk": "5.6.2",
|
||||
"chalk": "6.0.1",
|
||||
"chokidar": "4.0.3",
|
||||
"cli-boxes": "4.0.1",
|
||||
"cli-highlight": "2.1.11",
|
||||
@@ -126,7 +126,7 @@
|
||||
"emoji-regex": "11.0.0",
|
||||
"env-paths": "4.0.0",
|
||||
"eslint": "9.39.5",
|
||||
"execa": "9.6.1",
|
||||
"execa": "10.2.1",
|
||||
"fflate": "0.8.3",
|
||||
"figures": "6.1.0",
|
||||
"fuse.js": "7.5.0",
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
import { expect, test } from 'bun:test'
|
||||
import { spawnSync } from 'node:child_process'
|
||||
|
||||
const colorizeUrl = new URL('./colorize.ts', import.meta.url).href
|
||||
|
||||
// Each process imports chalk and colorize after its terminal environment is set.
|
||||
// Leave two seconds for assertions beyond the 8-second subprocess deadline.
|
||||
test.each([
|
||||
{ force: '0', terminal: '', tmux: '', level: 0, color: 'X' },
|
||||
{ force: '1', terminal: '', tmux: '', level: 1, color: '\x1b[91mX\x1b[39m' },
|
||||
{ force: '2', terminal: '', tmux: '', level: 2, color: '\x1b[38;5;196mX\x1b[39m' },
|
||||
{ force: '3', terminal: '', tmux: '', level: 3, color: '\x1b[38;5;196mX\x1b[39m' },
|
||||
{ force: '0', terminal: 'vscode', tmux: '', level: 0, color: 'X' },
|
||||
{ force: '2', terminal: 'vscode', tmux: '', level: 3, color: '\x1b[38;5;196mX\x1b[39m' },
|
||||
{ force: '3', terminal: 'vscode', tmux: 'test', level: 2, color: '\x1b[38;5;196mX\x1b[39m' },
|
||||
])('colorize respects FORCE_COLOR=$force, terminal=$terminal, tmux=$tmux', ({ force, terminal, tmux, level, color }) => {
|
||||
const script = `
|
||||
import chalk from 'chalk';
|
||||
import { colorize } from ${JSON.stringify(colorizeUrl)};
|
||||
process.stdout.write(JSON.stringify({
|
||||
level: chalk.level,
|
||||
foreground: colorize('X', 'ansi256(196)', 'foreground'),
|
||||
background: colorize('X', 'ansi256(196)', 'background'),
|
||||
}));
|
||||
`
|
||||
const result = spawnSync(process.execPath, ['--eval', script], {
|
||||
env: {
|
||||
...process.env,
|
||||
FORCE_COLOR: force,
|
||||
TERM_PROGRAM: terminal,
|
||||
TMUX: tmux,
|
||||
CLAUDE_CODE_TMUX_TRUECOLOR: '',
|
||||
COLORTERM: '',
|
||||
},
|
||||
encoding: 'utf8',
|
||||
timeout: 8_000,
|
||||
})
|
||||
expect(result.error).toBeUndefined()
|
||||
expect(result.status).toBe(0)
|
||||
const rendered = JSON.parse(result.stdout)
|
||||
expect(rendered.level).toBe(level)
|
||||
expect(rendered.foreground).toBe(color)
|
||||
expect(rendered.background).toBe(level === 0 ? 'X' : level === 1
|
||||
? '\x1b[101mX\x1b[49m'
|
||||
: '\x1b[48;5;196mX\x1b[49m')
|
||||
}, 10_000)
|
||||
@@ -0,0 +1,26 @@
|
||||
import { expect, test } from 'bun:test'
|
||||
import { execSyncWithDefaults_DEPRECATED } from './execFileNoThrowPortable.js'
|
||||
|
||||
// Allow assertions and cleanup beyond the subprocess's 8-second deadline.
|
||||
const options = { timeout: 8_000 }
|
||||
|
||||
test('portable sync execution trims captured stdout', () => {
|
||||
expect(execSyncWithDefaults_DEPRECATED('echo hello', options)).toBe('hello')
|
||||
}, 10_000)
|
||||
|
||||
test('portable sync execution preserves stdout on nonzero exit', () => {
|
||||
expect(execSyncWithDefaults_DEPRECATED('echo partial && exit 7', options)).toBe('partial')
|
||||
}, 10_000)
|
||||
|
||||
test('portable sync execution returns null without stdout', () => {
|
||||
expect(execSyncWithDefaults_DEPRECATED('exit 7', options)).toBeNull()
|
||||
}, 10_000)
|
||||
|
||||
test('portable sync execution forwards explicit stdin', () => {
|
||||
const command = `"${process.execPath}" -e "process.stdin.pipe(process.stdout)"`
|
||||
expect(execSyncWithDefaults_DEPRECATED(command, {
|
||||
...options,
|
||||
input: 'payload\n',
|
||||
stdio: ['pipe', 'pipe', 'pipe'],
|
||||
})).toBe('payload')
|
||||
}, 10_000)
|
||||
@@ -9,8 +9,8 @@ type ExecSyncOptions = {
|
||||
abortSignal?: AbortSignal
|
||||
timeout?: number
|
||||
input?: string
|
||||
// Sync variant: execaSync rejects async-only stdio values like 'overlapped'
|
||||
stdio?: ExecaSyncOptions['stdio']
|
||||
// This wrapper uses UTF-8 output, so exclude binary-only stdio transforms.
|
||||
stdio?: Extract<ExecaSyncOptions, { encoding?: 'utf8' | 'utf16le' }>['stdio']
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user