Changes before error encountered
Agent-Logs-Url: https://github.com/ComposioHQ/agent-orchestrator/sessions/9f3caf0b-66fb-4eff-bd3f-7fb9ab889630 Co-authored-by: Priyanchew <57816400+Priyanchew@users.noreply.github.com>
This commit is contained in:
parent
2a81a10b5b
commit
eaa27b9b79
|
|
@ -320,7 +320,7 @@ function ghInstallAttempts(): InstallAttempt[] {
|
|||
{ cmd: "sudo", args: ["dnf", "install", "-y", "gh"], label: "sudo dnf install -y gh" },
|
||||
];
|
||||
}
|
||||
if (process.platform === "win32") {
|
||||
if (isWindows()) {
|
||||
return [
|
||||
{
|
||||
cmd: "winget",
|
||||
|
|
@ -1625,7 +1625,7 @@ function isLocalPath(arg: string): boolean {
|
|||
* the parent process — the user explicitly asked us to stop AO.
|
||||
*/
|
||||
async function sweepWindowsPtyHostsBeforeParentKill(): Promise<void> {
|
||||
if (process.platform !== "win32") return;
|
||||
if (!isWindows()) return;
|
||||
try {
|
||||
const mod = (await import("@aoagents/ao-plugin-runtime-process")) as {
|
||||
sweepWindowsPtyHosts?: () => Promise<{
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
import { renameSync, writeFileSync, unlinkSync } from "node:fs";
|
||||
import { isWindows } from "./platform.js";
|
||||
|
||||
// Windows file-locking workaround. `renameSync` can fail with EPERM/EACCES when
|
||||
// antivirus, the Windows indexer, or another process briefly holds a handle on
|
||||
// the destination path. The failures are transient — a short retry loop is the
|
||||
// standard fix (same pattern Node's own `fs.rm` uses internally).
|
||||
const IS_WINDOWS = process.platform === "win32";
|
||||
const RENAME_RETRIES = IS_WINDOWS ? 10 : 0;
|
||||
const RENAME_RETRIES = isWindows() ? 10 : 0;
|
||||
const RENAME_RETRY_DELAY_MS = 50;
|
||||
|
||||
function renameWithRetry(src: string, dest: string): void {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import { WebSocketServer, WebSocket } from "ws";
|
|||
import { spawn } from "node:child_process";
|
||||
import { type Socket, connect as netConnect } from "node:net";
|
||||
import { findTmux, resolveTmuxSession, resolvePipePath, validateSessionId } from "./tmux-utils.js";
|
||||
import { getEnvDefaults } from "@aoagents/ao-core";
|
||||
import { getEnvDefaults, isWindows } from "@aoagents/ao-core";
|
||||
|
||||
// These types mirror src/lib/mux-protocol.ts exactly.
|
||||
// tsconfig.server.json constrains rootDir to "server/", so we cannot import
|
||||
|
|
@ -503,6 +503,7 @@ export function handleWindowsPipeMessage(
|
|||
pipeSocket.on("error", (err) => {
|
||||
winPipes.delete(pipeKey);
|
||||
winPipeBuffers.delete(pipeKey);
|
||||
pipeSocket.destroy();
|
||||
if (ws.readyState === WS_OPEN) {
|
||||
ws.send(
|
||||
JSON.stringify({
|
||||
|
|
@ -604,14 +605,14 @@ export function handleWindowsPipeMessage(
|
|||
export function createMuxWebSocket(tmuxPath?: string | null): WebSocketServer | null {
|
||||
// On Windows, we use named pipe relay instead of node-pty/tmux.
|
||||
// Allow the server to be created without ptySpawn on Windows.
|
||||
if (!ptySpawn && process.platform !== "win32") {
|
||||
if (!ptySpawn && !isWindows()) {
|
||||
console.warn("[MuxServer] node-pty not available — mux WebSocket will be disabled");
|
||||
return null;
|
||||
}
|
||||
|
||||
// On Windows, terminal I/O goes through named pipe relay — no TerminalManager needed.
|
||||
const terminalManager =
|
||||
ptySpawn && process.platform !== "win32" ? new TerminalManager(tmuxPath ?? undefined) : null;
|
||||
ptySpawn && !isWindows() ? new TerminalManager(tmuxPath ?? undefined) : null;
|
||||
|
||||
const nextPort = process.env.PORT || "3000";
|
||||
const broadcaster = new SessionBroadcaster(nextPort);
|
||||
|
|
@ -669,7 +670,7 @@ export function createMuxWebSocket(tmuxPath?: string | null): WebSocketServer |
|
|||
|
||||
try {
|
||||
if (type === "open") {
|
||||
if (process.platform === "win32") {
|
||||
if (isWindows()) {
|
||||
handleWindowsPipeMessage(
|
||||
msg as { id: string; type: string; projectId?: string; data?: string; cols?: number; rows?: number },
|
||||
ws,
|
||||
|
|
@ -739,7 +740,7 @@ export function createMuxWebSocket(tmuxPath?: string | null): WebSocketServer |
|
|||
}
|
||||
}
|
||||
} else if (type === "data" && "data" in msg) {
|
||||
if (process.platform === "win32") {
|
||||
if (isWindows()) {
|
||||
handleWindowsPipeMessage(
|
||||
msg as { id: string; type: string; projectId?: string; data: string },
|
||||
ws,
|
||||
|
|
@ -751,7 +752,7 @@ export function createMuxWebSocket(tmuxPath?: string | null): WebSocketServer |
|
|||
terminalManager?.write(id, msg.data, projectId);
|
||||
}
|
||||
} else if (type === "resize" && "cols" in msg && "rows" in msg) {
|
||||
if (process.platform === "win32") {
|
||||
if (isWindows()) {
|
||||
handleWindowsPipeMessage(
|
||||
msg as { id: string; type: string; projectId?: string; cols: number; rows: number },
|
||||
ws,
|
||||
|
|
@ -763,7 +764,7 @@ export function createMuxWebSocket(tmuxPath?: string | null): WebSocketServer |
|
|||
terminalManager?.resize(id, msg.cols, msg.rows, projectId);
|
||||
}
|
||||
} else if (type === "close") {
|
||||
if (process.platform === "win32") {
|
||||
if (isWindows()) {
|
||||
handleWindowsPipeMessage(
|
||||
msg as { id: string; type: string; projectId?: string; data?: string; cols?: number; rows?: number },
|
||||
ws,
|
||||
|
|
@ -840,7 +841,7 @@ export function createMuxWebSocket(tmuxPath?: string | null): WebSocketServer |
|
|||
subscriptions.clear();
|
||||
// Windows: close all open pipe sockets
|
||||
for (const pipeSocket of winPipes.values()) {
|
||||
pipeSocket.end();
|
||||
pipeSocket.destroy();
|
||||
}
|
||||
winPipes.clear();
|
||||
winPipeBuffers.clear();
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import { execFileSync } from "node:child_process";
|
|||
import { readdirSync, existsSync, readFileSync } from "node:fs";
|
||||
import { homedir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { isWindows } from "@aoagents/ao-core";
|
||||
|
||||
/** Session ID validation regex — alphanumeric, hyphens, underscores only */
|
||||
export const SESSION_ID_PATTERN = /^[a-zA-Z0-9_-]+$/;
|
||||
|
|
@ -110,7 +111,7 @@ export function validateSessionId(sessionId: string): boolean {
|
|||
export function findTmux(
|
||||
execFn: typeof execFileSync = execFileSync,
|
||||
): string | null {
|
||||
if (process.platform === "win32") return null;
|
||||
if (isWindows()) return null;
|
||||
const candidates = [
|
||||
"/opt/homebrew/bin/tmux", // macOS ARM (Homebrew)
|
||||
"/usr/local/bin/tmux", // macOS Intel (Homebrew)
|
||||
|
|
@ -233,7 +234,7 @@ export function resolvePipePath(
|
|||
readFile?: (path: string) => string;
|
||||
} = defaultFs,
|
||||
): string | null {
|
||||
if (process.platform !== "win32") return null;
|
||||
if (!isWindows()) return null;
|
||||
|
||||
const readFile = fs.readFile ?? ((p: string) => readFileSync(p, "utf8"));
|
||||
const aoBase = join(fs.homedir(), ".agent-orchestrator");
|
||||
|
|
|
|||
Loading…
Reference in New Issue