fix(server): keep setup/teardown/terminal action paths failing loudly on bad paseo.json
Follow-up to the projection fix. The mechanism/policy split landed projection on a graceful-degrade path, but I also made the setup, teardown, and terminal wrappers silently absorb parse failures — which broke the existing contract that `runWorktreeSetupInBackground` surfaces "Failed to parse paseo.json" to the user when they invoke setup against a workspace with a malformed config. Restore the throw, but with the path included and the underlying parse error attached as `cause` (Pino expands it; UI surfaces the path + detail). Extract `paseoConfigParseError` so spawnWorkspaceScript and the three wrappers throw the same shape. Also update opencode-agent.full-access.test.ts mode-order assertion that the reorder commit forgot to update.
This commit is contained in:
@@ -132,7 +132,7 @@ describe("OpenCode full-access mode", () => {
|
||||
const client = new OpenCodeAgentClient(createTestLogger());
|
||||
const modes = await client.listModes({ cwd: "/tmp/project", force: false });
|
||||
|
||||
expect(modes.map((mode) => mode.id)).toEqual(["build", "full-access", "plan", "paseo-custom"]);
|
||||
expect(modes.map((mode) => mode.id)).toEqual(["build", "plan", "full-access", "paseo-custom"]);
|
||||
expect(modes.find((mode) => mode.id === "full-access")).toMatchObject({
|
||||
label: "Full Access",
|
||||
description: "Automatically approves all tool permission prompts for the session",
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
getScriptConfigs,
|
||||
getWorktreeTerminalSpecs,
|
||||
isServiceScript,
|
||||
paseoConfigParseError,
|
||||
processCarriageReturns,
|
||||
readPaseoConfig,
|
||||
resolveWorktreeRuntimeEnv,
|
||||
@@ -835,9 +836,7 @@ export async function spawnWorkspaceScript(
|
||||
} = options;
|
||||
const configResult = readPaseoConfig(repoRoot);
|
||||
if (!configResult.ok) {
|
||||
throw new Error(`Failed to parse ${configResult.configPath}`, {
|
||||
cause: configResult.error,
|
||||
});
|
||||
throw paseoConfigParseError(configResult);
|
||||
}
|
||||
const scriptConfigs = getScriptConfigs(configResult.config);
|
||||
const config = scriptConfigs.get(scriptName);
|
||||
|
||||
@@ -572,11 +572,13 @@ describe("runWorktreeSetupInBackground", () => {
|
||||
expect(progressMessages[0]?.payload.status).toBe("running");
|
||||
expect(progressMessages[0]?.payload.error).toBeNull();
|
||||
expect(progressMessages[1]?.payload.status).toBe("failed");
|
||||
expect(progressMessages[1]?.payload.error).toContain("Failed to parse paseo.json");
|
||||
expect(progressMessages[1]?.payload.error).toMatch(
|
||||
/Failed to parse paseo\.json at .*paseo\.json/,
|
||||
);
|
||||
expect(progressMessages[1]?.payload.detail.commands).toEqual([]);
|
||||
expect(snapshots.get(workspaceId)).toMatchObject({
|
||||
status: "failed",
|
||||
error: expect.stringContaining("Failed to parse paseo.json"),
|
||||
error: expect.stringMatching(/Failed to parse paseo\.json at .*paseo\.json/),
|
||||
});
|
||||
expect(archiveWorkspaceRecord).toHaveBeenCalledWith(workspaceId);
|
||||
expect(emitWorkspaceUpdateForCwd).toHaveBeenCalledWith(worktreePath);
|
||||
|
||||
@@ -213,19 +213,31 @@ export function readPaseoConfig(repoRoot: string): ReadPaseoConfigResult {
|
||||
}
|
||||
}
|
||||
|
||||
export function getWorktreeSetupCommands(repoRoot: string): string[] {
|
||||
export function paseoConfigParseError(failure: { configPath: string; error: unknown }): Error {
|
||||
const detail = failure.error instanceof Error ? failure.error.message : String(failure.error);
|
||||
return new Error(`Failed to parse paseo.json at ${failure.configPath}: ${detail}`, {
|
||||
cause: failure.error,
|
||||
});
|
||||
}
|
||||
|
||||
function readPaseoConfigOrThrow(repoRoot: string): PaseoConfig | null {
|
||||
const result = readPaseoConfig(repoRoot);
|
||||
return result.ok ? (result.config?.worktree?.setup ?? []) : [];
|
||||
if (!result.ok) {
|
||||
throw paseoConfigParseError(result);
|
||||
}
|
||||
return result.config;
|
||||
}
|
||||
|
||||
export function getWorktreeSetupCommands(repoRoot: string): string[] {
|
||||
return readPaseoConfigOrThrow(repoRoot)?.worktree?.setup ?? [];
|
||||
}
|
||||
|
||||
export function getWorktreeTeardownCommands(repoRoot: string): string[] {
|
||||
const result = readPaseoConfig(repoRoot);
|
||||
return result.ok ? (result.config?.worktree?.teardown ?? []) : [];
|
||||
return readPaseoConfigOrThrow(repoRoot)?.worktree?.teardown ?? [];
|
||||
}
|
||||
|
||||
export function getWorktreeTerminalSpecs(repoRoot: string): WorktreeTerminalConfig[] {
|
||||
const result = readPaseoConfig(repoRoot);
|
||||
const terminals = result.ok ? result.config?.worktree?.terminals : undefined;
|
||||
const terminals = readPaseoConfigOrThrow(repoRoot)?.worktree?.terminals;
|
||||
if (!Array.isArray(terminals) || terminals.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user