fix(coding-agent): restore /import error flow and document throws

This commit is contained in:
Mario Zechner
2026-04-17 00:59:53 +02:00
parent 3ba0d85fa2
commit 36bffc1d13
3 changed files with 30 additions and 17 deletions

View File

@@ -7,6 +7,7 @@
- Fixed missing root exports for `RpcClient` and RPC protocol types from `@mariozechner/pi-coding-agent`, so ESM consumers can import them from the main package entrypoint ([#3275](https://github.com/badlogic/pi-mono/issues/3275))
- Fixed Bun binary asset path resolution to honor `PI_PACKAGE_DIR` for built-in themes, HTML export templates, and interactive bundled assets ([#3074](https://github.com/badlogic/pi-mono/issues/3074))
- Fixed user-message turn spacing in interactive mode by restoring an inter-message spacer before user turns (except the first user message), preventing assistant and user blocks from rendering flush together.
- Fixed interactive `/import` handling to route missing JSONL files through the non-fatal `SessionImportFileNotFoundError` path, and documented the `importFromJsonl()` exceptions (`SessionImportFileNotFoundError`, `MissingSessionCwdError`).
## [0.67.6] - 2026-04-16

View File

@@ -33,6 +33,9 @@ export type CreateAgentSessionRuntimeFactory = (options: {
sessionStartEvent?: SessionStartEvent;
}) => Promise<CreateAgentSessionRuntimeResult>;
/**
* Thrown when /import references a JSONL file path that does not exist.
*/
export class SessionImportFileNotFoundError extends Error {
readonly filePath: string;
@@ -258,6 +261,13 @@ export class AgentSessionRuntime {
return { cancelled: false, selectedText };
}
/**
* Import a session JSONL file and switch runtime state to the imported session.
*
* @returns `{ cancelled: true }` when cancelled by `session_before_switch`, otherwise `{ cancelled: false }`.
* @throws {SessionImportFileNotFoundError} When the input path does not exist.
* @throws {MissingSessionCwdError} When the imported session cwd cannot be resolved and no override is provided.
*/
async importFromJsonl(inputPath: string, cwdOverride?: string): Promise<{ cancelled: boolean }> {
const resolvedPath = resolve(inputPath);
if (!existsSync(resolvedPath)) {

View File

@@ -47,7 +47,7 @@ import {
VERSION,
} from "../../config.js";
import { type AgentSession, type AgentSessionEvent, parseSkillBlock } from "../../core/agent-session.js";
import type { AgentSessionRuntime } from "../../core/agent-session-runtime.js";
import { type AgentSessionRuntime, SessionImportFileNotFoundError } from "../../core/agent-session-runtime.js";
import type {
ExtensionContext,
ExtensionRunner,
@@ -4417,20 +4417,6 @@ export class InteractiveMode {
return;
}
const handleImportResult = async (result: "ok" | "cancelled" | "not_found"): Promise<void> => {
if (result === "cancelled") {
this.showStatus("Import cancelled");
return;
}
if (result === "not_found") {
this.showError(`Failed to import session: File not found: ${path.resolve(inputPath)}`);
return;
}
await this.handleRuntimeSessionChange();
this.renderCurrentSessionState();
this.showStatus(`Session imported from: ${inputPath}`);
};
try {
if (this.loadingAnimation) {
this.loadingAnimation.stop();
@@ -4438,7 +4424,13 @@ export class InteractiveMode {
}
this.statusContainer.clear();
const result = await this.runtimeHost.importFromJsonl(inputPath);
await handleImportResult(result);
if (result.cancelled) {
this.showStatus("Import cancelled");
return;
}
await this.handleRuntimeSessionChange();
this.renderCurrentSessionState();
this.showStatus(`Session imported from: ${inputPath}`);
} catch (error: unknown) {
if (error instanceof MissingSessionCwdError) {
const selectedCwd = await this.promptForMissingSessionCwd(error);
@@ -4447,7 +4439,17 @@ export class InteractiveMode {
return;
}
const result = await this.runtimeHost.importFromJsonl(inputPath, selectedCwd);
await handleImportResult(result);
if (result.cancelled) {
this.showStatus("Import cancelled");
return;
}
await this.handleRuntimeSessionChange();
this.renderCurrentSessionState();
this.showStatus(`Session imported from: ${inputPath}`);
return;
}
if (error instanceof SessionImportFileNotFoundError) {
this.showError(`Failed to import session: ${error.message}`);
return;
}
await this.handleFatalRuntimeError("Failed to import session", error);