fix(coding-agent): persist bash shortcut cwd changes
This commit is contained in:
@@ -13,6 +13,7 @@ import {
|
||||
import { Loader, Markdown, padding, Spacer, Text, visibleWidth } from "@oh-my-pi/pi-tui";
|
||||
import { formatDuration, Snowflake, sanitizeText } from "@oh-my-pi/pi-utils";
|
||||
import { shouldEnableAppendOnlyContext } from "../../config/append-only-context-mode";
|
||||
import { type BashResult, isPersistentShellCdCommand } from "../../exec/bash-executor";
|
||||
import { type LoadedCustomShare, loadCustomShare } from "../../export/custom-share";
|
||||
import { shareSession } from "../../export/share";
|
||||
import type { CompactOptions } from "../../extensibility/extensions/types";
|
||||
@@ -1100,6 +1101,12 @@ export class CommandController {
|
||||
|
||||
async handleBashCommand(command: string, excludeFromContext = false): Promise<void> {
|
||||
const isDeferred = this.ctx.session.isStreaming;
|
||||
const shouldPersistCwd = isPersistentShellCdCommand(command);
|
||||
if (isDeferred && shouldPersistCwd) {
|
||||
this.ctx.showWarning("Wait for the current response to finish or abort it before changing directories.");
|
||||
return;
|
||||
}
|
||||
|
||||
this.ctx.bashComponent = new BashExecutionComponent(command, this.ctx.ui, excludeFromContext);
|
||||
|
||||
if (isDeferred) {
|
||||
@@ -1120,7 +1127,6 @@ export class CommandController {
|
||||
},
|
||||
{ excludeFromContext, useUserShell: true },
|
||||
);
|
||||
|
||||
if (this.ctx.bashComponent) {
|
||||
const meta = outputMeta().truncationFromSummary(result, { direction: "tail" }).get();
|
||||
this.ctx.bashComponent.setComplete(result.exitCode, result.cancelled, {
|
||||
@@ -1128,6 +1134,15 @@ export class CommandController {
|
||||
truncation: meta?.truncation,
|
||||
});
|
||||
}
|
||||
try {
|
||||
if (shouldPersistCwd) await this.#applyBashResultCwd(result);
|
||||
} catch (error) {
|
||||
this.ctx.showError(
|
||||
`Bash command completed, but OMP failed to update its working directory: ${
|
||||
error instanceof Error ? error.message : "Unknown error"
|
||||
}`,
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.ctx.bashComponent) {
|
||||
this.ctx.bashComponent.setComplete(undefined, false);
|
||||
@@ -1139,6 +1154,31 @@ export class CommandController {
|
||||
this.ctx.ui.requestRender();
|
||||
}
|
||||
|
||||
async #moveInteractiveCwd(resolvedPath: string): Promise<void> {
|
||||
await this.ctx.sessionManager.moveTo(resolvedPath);
|
||||
await this.ctx.applyCwdChange(resolvedPath);
|
||||
this.ctx.updateEditorBorderColor();
|
||||
await this.ctx.reloadTodos();
|
||||
}
|
||||
|
||||
async #applyBashResultCwd(result: BashResult): Promise<void> {
|
||||
if (result.cancelled || result.exitCode !== 0 || !result.workingDir) return;
|
||||
if (!path.isAbsolute(result.workingDir)) return;
|
||||
|
||||
const resolvedPath = path.resolve(result.workingDir);
|
||||
if (resolvedPath === path.resolve(this.ctx.sessionManager.getCwd())) return;
|
||||
|
||||
let isDirectory = false;
|
||||
try {
|
||||
isDirectory = (await fs.stat(resolvedPath)).isDirectory();
|
||||
} catch {
|
||||
isDirectory = false;
|
||||
}
|
||||
if (!isDirectory) return;
|
||||
|
||||
await this.#moveInteractiveCwd(resolvedPath);
|
||||
}
|
||||
|
||||
async handlePythonCommand(code: string, excludeFromContext = false): Promise<void> {
|
||||
const isDeferred = this.ctx.session.isStreaming;
|
||||
this.ctx.pythonComponent = new EvalExecutionComponent(code, this.ctx.ui, excludeFromContext);
|
||||
|
||||
Reference in New Issue
Block a user