fix(cli): externalize Windows startup PowerShell to .ps1 wrapper (schtasks /TR 261-char limit)

The inline PowerShell env-parsing script exceeded the Task Scheduler /TR
261-char limit, causing startup enable to fail on Windows. Extract the
script into a .ps1 wrapper file and reduce /TR to a short
powershell.exe -File command (~115 chars). Mirrors the macOS
writeMacosStartupWrapper pattern. Adds regression tests pinning
/TR < 200 (default) and < 261 (worst-case).

Apply fix to refactored lib/cli-startup.js (was cli.js before refactor).
This commit is contained in:
Tang
2026-07-04 10:32:19 +08:00
parent de1b85ac56
commit adb6ca2b08
2 changed files with 64 additions and 9 deletions
+35
View File
@@ -30,6 +30,7 @@ import {
parseArgs,
resolveServeHost,
} from './cli.js';
import { buildWindowsStartupTaskCommand } from './lib/cli-startup.js';
async function withTempOpenChamberDataDir(fn) {
const previous = process.env.OPENCHAMBER_DATA_DIR;
@@ -884,3 +885,37 @@ describe('lifecycle commands with unmanaged explicit ports', () => {
});
});
});
describe('Windows startup task command builder', () => {
it('default-path length stays under 200 chars', () => {
const cmd = buildWindowsStartupTaskCommand(
'C:\\Users\\test\\.config\\openchamber\\bin\\OpenChamber.ps1'
);
expect(cmd).toMatch(/^powershell\.exe -NoProfile -ExecutionPolicy Bypass -File /);
expect(cmd.length).toBeLessThan(200);
});
it('worst-case long path stays under 261-char Task Scheduler ceiling', () => {
// Build a wrapper path >= 180 chars (simulates long OPENCHAMBER_DATA_DIR)
// Overhead = 57 chars (prefix + closing quote), so max wrapper for <261 total is 203
const longPath =
'C:\\Users\\' +
'a'.repeat(139) +
'\\.config\\openchamber\\bin\\OpenChamber.ps1';
expect(longPath.length).toBeGreaterThanOrEqual(180);
const cmd = buildWindowsStartupTaskCommand(longPath);
expect(cmd.length).toBeLessThan(261);
});
it('does NOT inline SetEnvironmentVariable (externalization invariant)', () => {
const cmd = buildWindowsStartupTaskCommand('C:\\wrapper.ps1');
expect(cmd).not.toContain('SetEnvironmentVariable');
});
it('uses -File form, not -Command', () => {
const cmd = buildWindowsStartupTaskCommand('C:\\wrapper.ps1');
expect(cmd).toContain('-File ');
expect(cmd).not.toContain('-Command ');
});
});