From 60438fc6a241bf278265946868975a9ac08dc7e6 Mon Sep 17 00:00:00 2001 From: "xiaohan.yuan" Date: Wed, 21 Oct 2026 18:04:35 +0800 Subject: [PATCH 1/2] chore(release): bump version to 0.0.10 Record the published 0.0.10 release version in package.json and package-lock.json (the 0.0.9 bump was never committed). The published installer is release/publish/0.0.10/YCode-0.0.10-Setup-x64.exe, SHA-256 d31dbf1c682d52aeffdc1c81387fac3952f96813d867bd25f963603615381ba8. Co-Authored-By: Claude Code --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 19f67d7..1394295 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ycode", - "version": "0.0.8", + "version": "0.0.10", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ycode", - "version": "0.0.8", + "version": "0.0.10", "dependencies": { "@anthropic-ai/claude-agent-sdk": "^0.3.304", "@anthropic-ai/sdk": "^0.135.0", diff --git a/package.json b/package.json index 697eb3b..f7779a6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ycode", - "version": "0.0.8", + "version": "0.0.10", "private": true, "description": "YCode - 个人 AI Agent 桌面应用(Electron)", "author": "YCode", From e68478f1a4d238fe85bc9d5311adbd9f13b7a03d Mon Sep 17 00:00:00 2001 From: "xiaohan.yuan" Date: Wed, 21 Oct 2026 18:17:17 +0800 Subject: [PATCH 2/2] fix(runtime): stabilize Windows preparation and smoke checks --- scripts/prepare-runtime-bundle.mjs | 15 ++++++++++++++- scripts/smoke-runtime-bundle.mjs | 8 ++++---- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/scripts/prepare-runtime-bundle.mjs b/scripts/prepare-runtime-bundle.mjs index e5bc332..584cf84 100644 --- a/scripts/prepare-runtime-bundle.mjs +++ b/scripts/prepare-runtime-bundle.mjs @@ -2,10 +2,23 @@ import fs from 'node:fs/promises' import path from 'node:path' import { spawnSync } from 'node:child_process' +import { setTimeout as delay } from 'node:timers/promises' import sevenZip from '7zip-bin' import { transformRuntime } from './runtime-transform.mjs' import { projectRoot, runtimeRoot, manifest, digest, inventory, verifyRuntimeBundle } from './runtime-bundle.mjs' const cache = path.join(projectRoot, '.tmp/runtime-downloads') +async function renameExtractedDirectory(source, destination) { + for (let attempt = 0; ; attempt += 1) { + try { + await fs.rename(source, destination) + return + } catch (error) { + // Windows scanners can briefly hold freshly extracted executables open. + if (process.platform !== 'win32' || !['EPERM', 'EACCES', 'EBUSY'].includes(error.code) || attempt >= 9) throw error + await delay(100 * (attempt + 1)) + } + } +} await fs.mkdir(cache, { recursive: true }) const stage = await fs.mkdtemp(path.join(runtimeRoot, '.prepare-')) try { @@ -26,7 +39,7 @@ try { const result = spawnSync(sevenZip.path7za, ['x', archive, `-o${unpack}`, '-y'], { encoding: 'utf8', windowsHide: true }) if (result.error || result.status !== 0) throw new Error(`Archive extraction failed: ${runtime.id}: ${result.error || result.stderr || result.stdout}`) const target = path.join(stage, runtime.id) - await fs.rename(path.join(unpack, runtime.prefix), target) + await renameExtractedDirectory(path.join(unpack, runtime.prefix), target) await transformRuntime(runtime.id, target) // No loose mutation of the extraction lock. A source update requires reviewed tree digest changes. const tree = digest(JSON.stringify(await inventory(target))) diff --git a/scripts/smoke-runtime-bundle.mjs b/scripts/smoke-runtime-bundle.mjs index a11d98f..52ef1ee 100644 --- a/scripts/smoke-runtime-bundle.mjs +++ b/scripts/smoke-runtime-bundle.mjs @@ -17,17 +17,17 @@ try { npm_config_userconfig: path.join(temp, 'npmrc'), npm_config_globalconfig: path.join(temp, 'npm-globalrc'), npm_config_cache: path.join(temp, 'npm-cache'), npm_config_prefix: path.join(temp, 'npm-prefix'), PYTHONUSERBASE: path.join(temp, 'python-user'), PIP_CACHE_DIR: path.join(temp, 'pip-cache'), - PYTHONNOUSERSITE: '1', GIT_CONFIG_NOSYSTEM: '1', GIT_CONFIG_GLOBAL: path.join(temp, 'gitconfig'), + PYTHONNOUSERSITE: '1', PYTHONDONTWRITEBYTECODE: '1', GIT_CONFIG_NOSYSTEM: '1', GIT_CONFIG_GLOBAL: path.join(temp, 'gitconfig'), PATH: [path.join(root, 'node'), path.join(root, 'python'), path.join(root, 'git/cmd'), path.join(root, 'git/bin'), path.join(process.env.SystemRoot || 'C:\\Windows', 'System32')].join(';') } - const run = (exe, args) => { - const r = spawnSync(exe, args, { cwd: temp, env, encoding: 'utf8', timeout: 60_000, windowsHide: true }) + const run = (exe, args, options = {}) => { + const r = spawnSync(exe, args, { cwd: temp, env, encoding: 'utf8', timeout: 60_000, windowsHide: true, ...options }) if (r.error || r.status !== 0) throw new Error(`${exe} ${args.join(' ')} failed: ${r.error || r.stderr || r.stdout}`) console.log(r.stdout.trim()) } const node = path.join(root, 'node/node.exe'), python = path.join(root, 'python/python.exe') run(node, ['--version']) // Explicit cmd.exe, fixed arguments only; downloaded npm/npx scripts never use shell interpolation from user input. - for (const command of ['npm', 'npx']) run(process.env.ComSpec || 'cmd.exe', ['/d', '/s', '/c', `""${path.join(root, `node/${command}.cmd`)}" --version"`]) + for (const command of ['npm', 'npx']) run(process.env.ComSpec || 'cmd.exe', ['/d', '/s', '/c', `""${path.join(root, `node/${command}.cmd`)}" --version"`], { windowsVerbatimArguments: true }) run(python, ['--version']); run(python, ['-m', 'pip', '--version']) run(python, ['-m', 'venv', path.join(temp, 'venv')]) run(path.join(temp, 'venv/Scripts/python.exe'), ['-m', 'pip', '--version'])