From 8aa3f291f659f1f969698880e09273b13bcb95a5 Mon Sep 17 00:00:00 2001 From: skulidropek <66840575+skulidropek@users.noreply.github.com> Date: Wed, 25 Mar 2026 09:17:14 +0000 Subject: [PATCH 1/2] fix(spawn): run agent directly via ssh instead of attaching tmux --- packages/app/src/docker-git/spawn.ts | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/packages/app/src/docker-git/spawn.ts b/packages/app/src/docker-git/spawn.ts index 9355206..82bd19a 100644 --- a/packages/app/src/docker-git/spawn.ts +++ b/packages/app/src/docker-git/spawn.ts @@ -11,15 +11,13 @@ import { type TemplateConfig } from "@effect-template/lib/core/domain" import type { SpawnCommand } from "@effect-template/lib/core/spawn-domain" -import { runCommandCapture, runCommandExitCode } from "@effect-template/lib/shell/command-runner" +import { runCommandCapture, runCommandExitCode, runCommandWithExitCodes } from "@effect-template/lib/shell/command-runner" import { readProjectConfig } from "@effect-template/lib/shell/config" import { CommandFailedError, SpawnProjectDirError, SpawnSetupError } from "@effect-template/lib/shell/errors" import { createProject } from "@effect-template/lib/usecases/actions" import { findSshPrivateKey } from "@effect-template/lib/usecases/path-helpers" import { getContainerIpIfInsideContainer } from "@effect-template/lib/usecases/projects-core" -import { spawnAttachTmux } from "./tmux.js" - const SPAWNDOCK_REPO_URL = "https://github.com/SpawnDock/tma-project" const SPAWNDOCK_REPO_REF = "main" @@ -174,5 +172,22 @@ export const spawnProject = (command: SpawnCommand) => } yield* _(Effect.log(`Project bootstrapped at ${projectDir}`)) - yield* _(spawnAttachTmux(template, projectDir, sshKey)) + + yield* _(Effect.log("Starting opencode directly via SSH...")) + yield* _( + runCommandWithExitCodes( + { + cwd: process.cwd(), + command: "ssh", + args: buildSshArgs( + template, + sshKey, + ipAddress, + `cd '${projectDir}' && spawn-dock agent` + ).filter((arg) => arg !== "-T" && arg !== "-o" && arg !== "BatchMode=yes" && arg !== "ConnectTimeout=2" && arg !== "ConnectionAttempts=1") + }, + [0, 255], // SSH frequently exits with 255 on user disconnect, which is normal + (exitCode) => new CommandFailedError({ command: "ssh agent", exitCode }) + ) + ) }) From 82753a7feacc48a8207877802a5be06cb32e816e Mon Sep 17 00:00:00 2001 From: skulidropek <66840575+skulidropek@users.noreply.github.com> Date: Wed, 25 Mar 2026 09:17:14 +0000 Subject: [PATCH 2/2] chore: version bump for spawn-dock tmux fix --- .changeset/remove-tmux.md | 5 +++ packages/app/src/docker-git/main.ts | 6 ++-- packages/app/src/docker-git/spawn.ts | 54 ++++++++++++++++++---------- 3 files changed, 43 insertions(+), 22 deletions(-) create mode 100644 .changeset/remove-tmux.md diff --git a/.changeset/remove-tmux.md b/.changeset/remove-tmux.md new file mode 100644 index 0000000..b80cfcc --- /dev/null +++ b/.changeset/remove-tmux.md @@ -0,0 +1,5 @@ +--- +"@spawn-dock/cli": patch +--- + +fix: execute agent directly via ssh instead of attaching tmux in spawn command diff --git a/packages/app/src/docker-git/main.ts b/packages/app/src/docker-git/main.ts index c869795..dc448f7 100644 --- a/packages/app/src/docker-git/main.ts +++ b/packages/app/src/docker-git/main.ts @@ -1,5 +1,6 @@ #!/usr/bin/env node +import * as _9 from "@effect/cli" import * as _1 from "@effect/cluster" import * as _2 from "@effect/experimental" import * as _3 from "@effect/printer" @@ -8,15 +9,14 @@ import * as _5 from "@effect/rpc" import * as _6 from "@effect/sql" import * as _7 from "@effect/typeclass" import * as _8 from "@effect/workflow" -import * as _9 from "@effect/cli" - -export const _dummyDeps = [_1, _2, _3, _4, _5, _6, _7, _8, _9] import { NodeContext, NodeRuntime } from "@effect/platform-node" import { Effect } from "effect" import { program } from "./program.js" +export const _dummyDeps = [_1, _2, _3, _4, _5, _6, _7, _8, _9] + // CHANGE: run docker-git CLI through the Node runtime // WHY: ensure platform services (FS, Path, Command) are available in app CLI // QUOTE(ТЗ): "CLI (отображение, фронт) это app" diff --git a/packages/app/src/docker-git/spawn.ts b/packages/app/src/docker-git/spawn.ts index 82bd19a..390d941 100644 --- a/packages/app/src/docker-git/spawn.ts +++ b/packages/app/src/docker-git/spawn.ts @@ -11,7 +11,11 @@ import { type TemplateConfig } from "@effect-template/lib/core/domain" import type { SpawnCommand } from "@effect-template/lib/core/spawn-domain" -import { runCommandCapture, runCommandExitCode, runCommandWithExitCodes } from "@effect-template/lib/shell/command-runner" +import { + runCommandCapture, + runCommandExitCode, + runCommandWithExitCodes +} from "@effect-template/lib/shell/command-runner" import { readProjectConfig } from "@effect-template/lib/shell/config" import { CommandFailedError, SpawnProjectDirError, SpawnSetupError } from "@effect-template/lib/shell/errors" import { createProject } from "@effect-template/lib/usecases/actions" @@ -119,6 +123,35 @@ const buildSpawnCreateCommand = (outDir: string, force: boolean): CreateCommand } } +const spawnAttachDirect = ( + template: TemplateConfig, + projectDir: string, + sshKey: string | null, + ipAddress: string | undefined +): Effect.Effect => + Effect.gen(function*(_) { + yield* _(Effect.log("Starting opencode directly via SSH...")) + yield* _( + runCommandWithExitCodes( + { + cwd: process.cwd(), + command: "ssh", + args: buildSshArgs( + template, + sshKey, + ipAddress, + `cd '${projectDir}' && spawn-dock agent` + ).filter((arg) => + arg !== "-T" && arg !== "-o" && arg !== "BatchMode=yes" && arg !== "ConnectTimeout=2" && + arg !== "ConnectionAttempts=1" + ) + }, + [0, 255], // SSH frequently exits with 255 on user disconnect, which is normal + (exitCode) => new CommandFailedError({ command: "ssh agent", exitCode }) + ) + ) + }) + // CHANGE: orchestrate spawn-dock spawn — creates container, runs @spawn-dock/create, opens tmux+opencode // WHY: provide one-command bootstrap from a Telegram bot pairing token // REF: spawn-command @@ -172,22 +205,5 @@ export const spawnProject = (command: SpawnCommand) => } yield* _(Effect.log(`Project bootstrapped at ${projectDir}`)) - - yield* _(Effect.log("Starting opencode directly via SSH...")) - yield* _( - runCommandWithExitCodes( - { - cwd: process.cwd(), - command: "ssh", - args: buildSshArgs( - template, - sshKey, - ipAddress, - `cd '${projectDir}' && spawn-dock agent` - ).filter((arg) => arg !== "-T" && arg !== "-o" && arg !== "BatchMode=yes" && arg !== "ConnectTimeout=2" && arg !== "ConnectionAttempts=1") - }, - [0, 255], // SSH frequently exits with 255 on user disconnect, which is normal - (exitCode) => new CommandFailedError({ command: "ssh agent", exitCode }) - ) - ) + yield* _(spawnAttachDirect(template, projectDir, sshKey, ipAddress)) })