Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions lua/agent-deck/backend.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
-- backend.lua — dispatch layer for backend abstraction
--
-- Single entry point for all backend operations. Callers use
-- require("agent-deck.backend") instead of require("agent-deck.cli").
--
-- Supports two backends:
-- "agent-deck" (default) — wraps cli.lua, sessions in tmux via agent-deck daemon
-- "cmux" — native cmux surfaces, plugin is the daemon
--
-- init() must be called from setup() before any method is invoked.
-- All interface methods are forwarded to the active backend implementation.
local M = {}

local log = require("agent-deck.logger")
local _impl = nil
local _name = "agent-deck" -- default backend

--- Initialize the backend. Must be called once from setup().
--- @param backend_name string|nil "agent-deck" (default) or "cmux"
function M.init(backend_name)
_name = backend_name or "agent-deck"
if _name == "cmux" then
_impl = require("agent-deck.backend.cmux")
else
_impl = require("agent-deck.backend.agent_deck")
end
log.info("backend.init: using '" .. _name .. "' backend")
-- Health check for cmux: verify app is running
if _impl.health_check then
_impl.health_check()
end
end

--- Return the active backend name ("agent-deck" or "cmux").
function M.name()
return _name
end

-- ── Method forwarding ────────────────────────────────────────────────────────
-- Every interface method is forwarded to the active backend implementation.
-- assert(_impl) guards against calling before init().

local METHODS = {
"status", "list_sessions", "session_show", "session_send",
"session_output", "session_start", "session_stop", "session_restart",
"session_delete", "launch", "group_list", "group_create",
"group_move", "session_set", "focus_session",
}

for _, method in ipairs(METHODS) do
M[method] = function(...)
assert(_impl, "backend.init() not called — call require('agent-deck').setup() first")
return _impl[method](...)
end
end

return M
23 changes: 23 additions & 0 deletions lua/agent-deck/backend/agent_deck.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
-- backend/agent_deck.lua — thin wrapper over cli.lua for the backend interface
--
-- Re-exports all cli.lua methods unchanged and adds focus_session() as a
-- no-op since agent-deck sessions live inside Neovim terminal buffers
-- (focusing is handled by the picker/parallel UI layer, not the backend).
local cli = require("agent-deck.cli")
local M = setmetatable({}, { __index = cli })

--- No-op for agent-deck backend: sessions live in Neovim terminals,
--- so "focusing" is handled by the UI layer (picker/parallel).
function M.focus_session(_, cb)
if cb then cb(true, nil) end
end

--- Health check: verify agent-deck binary is reachable.
function M.health_check()
local bin = vim.fn.exepath("agent-deck")
if bin == "" then
require("agent-deck.logger").warn("agent_deck backend: binary not found in PATH")
end
end

return M
21 changes: 21 additions & 0 deletions lua/agent-deck/backend/ansi.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
-- backend/ansi.lua — ANSI escape sequence stripping utility
--
-- Used by the cmux backend to clean raw terminal output from
-- `cmux read-screen` before presenting it to the user.
-- Strips CSI sequences, OSC sequences, single-char escapes,
-- and carriage returns.
local M = {}

--- Strip ANSI escape sequences from terminal output text.
--- Returns clean plain text suitable for display in a Neovim buffer.
function M.strip(text)
if not text then return "" end
text = text:gsub("\27%[[\032-\063]*[\064-\126]", "") -- CSI sequences (e.g. \27[0m, \27[38;5;12m)
text = text:gsub("\27%].-\a", "") -- OSC sequences (BEL terminated)
text = text:gsub("\27%].-\27\\", "") -- OSC sequences (ST terminated)
text = text:gsub("\27.", "") -- single-char escape sequences
text = text:gsub("\r", "") -- carriage returns
return text
end

return M
Loading