Skip to content

Software Dependencies

This document describes Go module dependencies (third-party libraries) and internal package dependencies (how code in this repository imports other packages).

Companion docs: DIRECTORY_STRUCTURE.md · ARCHITECTURE.md


Table of contents


FRAMEWORK vs APP

The repo is split so a future non-debugger TUI app can reuse the same host without pulling GDB/Delve.

Layer Packages Role
FRAMEWORK termui, platform, commands, collections, ptyx, luahost, execcli, core Generic TUI, input, PTY, Lua host, shared events (PtyOutputMsg, ExecOutputMsg)
APP (gdbforge) internal/gdb, internal/dlv, internal/mcp, internal/gdbforge/* (incl. backend), cmd/gdbforge Debugger backends, MI parse/models, debug widgets, app events (GdbOutputMsg, InferiorOutputMsg)
APP (demo) internal/demo, cmd/demo Host showcase — same chrome, basic commands; no debugger

Composition root: only cmd/gdbforge (and tests) should wire APP packages into FRAMEWORK surfaces.

Second app (cmd/demo)

A host showcase binary lives at cmd/demo (+ internal/demo). It reuses FRAMEWORK packages only (termui, commands, platform, …) and must not import gdb, dlv, mcp, or gdbforge/*.

Recipe for another product binary:

  1. Add cmd/<app> as composition root and optional internal/<domain>/….
  2. Wire termui.TermApp + commands.CommandRegistry + basic :window / :quit / :help.
  3. Run task check-imports.

internal/mcp is debugger-app (GDB tools), not reusable host.

Lua: luahost installs framework APIs at New. Debugger Lua bindings (gdb, dlv_*, set_inferior_tty, program) are registered from cmd/gdbforge via gdbforge/luadebug.Install.

Quick answer: internal/termui

Yes — internal/termui depends only on the Go standard library and tcell.

It does not import:

  • internal/core
  • internal/gdb
  • any other third-party UI library

That is intentional: termui is the standalone TUI framework (layout, widgets, grid/canvas rendering, keyboard/mouse input via tcell). Domain logic and debugger backends stay outside it.

Wiring happens above termui:

Layer Role
internal/termui Generic terminal UI framework — window manager, layout, rendering
internal/gdbforge App state (AppState, modes) + debugger widgets (views)
cmd/gdbforge Application startup — services, models, event bus; composes termui, widgets, core, gdb, ptyx, mcp

Services, models, and widgets are wired in cmd/gdbforge. Data flows Service → Event Bus → Model → Widget; termui never imports services or models directly.


External dependencies (go.mod)

Module path: github.com/yairgd/gdbforge

Dependency Used by Purpose
github.com/gdamore/tcell/v2 internal/termui, internal/gdbforge/widgets Terminal screen, input, styles
github.com/creack/pty internal/ptyx Pseudo-terminal for GDB and :! exec I/O

No third-party runtime deps: cmd/docserve uses the Go standard library only.

System tools (not Go modules):

Tool Required by
gdb internal/gdb at runtime
go (see go.mod for version) build

Run go mod graph or go list -m all for exact versions and transitive modules.


Internal package graph

flowchart BT
    tcell["gdamore/tcell/v2"]
    ptyLib["creack/pty"]

    termui["internal/termui"]
    gdbforge_pkg["internal/gdbforge"]
    widgets["internal/gdbforge/widgets"]
    core["internal/core"]
    ptyx["internal/ptyx"]
    gdb["internal/gdb"]
    execcli["internal/execcli"]
    mcp["internal/mcp"]
    gdbforge_cmd["cmd/gdbforge"]
    docserve["cmd/docserve"]

    termui --> tcell
    widgets --> termui
    widgets --> mitext["gdbforge/mitext"]
    widgets --> events["gdbforge/events"]
    ptyx --> core
    ptyx --> ptyLib
    gdb --> core
    gdb --> ptyx
    execcli --> core
    execcli --> ptyx
    mcp --> core

    gdbforge_cmd --> termui
    gdbforge_cmd --> gdbforge_pkg
    gdbforge_cmd --> widgets
    gdbforge_cmd --> core
    gdbforge_cmd --> gdb
    gdbforge_cmd --> execcli
    gdbforge_cmd --> mcp

    docserve --> stdlib["Go stdlib only"]

    gdb -.->|"must NOT import"| termui
    ptyx -.->|"must NOT import"| termui
    mcp -.->|"must NOT import"| termui
    core -.->|"must NOT import"| termui
    termui -.->|"must NOT import"| core

Per-package import rules

Package May import Must not import
internal/termui stdlib, tcell core, gdb, ptyx, other UI libs
internal/core stdlib termui, tcell, gdb, ptyx
internal/ptyx stdlib, creack/pty, core termui, tcell
internal/gdb stdlib, ptyx, core termui, tcell
internal/execcli stdlib, ptyx, core termui, tcell
internal/mcp stdlib, core (net/http) termui, tcell, gdb, widgets
internal/gdbforge/mitext stdlib — (debugger MI string helpers; used by gdb + widgets)
internal/luahost stdlib, gopher-lua gdb, dlv, mcp, gdbforge (app wires debugger Lua)
internal/platform stdlib, termui (as needed) gdb, dlv, mcp, gdbforge
internal/gdbforge/backend gdb, dlv, core, ptyx, models, platform termui, tcell, widgets
internal/gdbforge/widgets termui, platform, gdbforge/mitext, gdbforge/events, gdbforge/models, stdlib gdb, mcp, dlv
internal/gdbforge/* app helpers (models, parse, debugstate, events, backend, …) must not be imported by FRAMEWORK packages
cmd/gdbforge FRAMEWORK + APP packages — (composition root)
cmd/docserve stdlib only

Heuristic: if code can be unit-tested without a terminal, it belongs in core / ptyx / mcp, not in termui.


Command binaries

Binary Path Pulls in
gdbforge cmd/gdbforge termui, widgets, backend, core, gdb, dlv, ptyx, execcli, mcp, tcell, creack/pty
docserve cmd/docserve stdlib only

Build all commands: task build or go build ./cmd/....


Forbidden edges

These import directions are architectural violations — do not add them:

FRAMEWORK (termui|platform|commands|collections|ptyx|luahost|core)
        ──X──>  gdb | dlv | mcp | gdbforge/*

dlv     ──X──>  termui
widgets ──X──>  gdb | mcp
mcp     ──X──>  termui | tcell | gdb | widgets
termui  ──X──>  gdb | ptyx | gdbforge
core    ──X──>  termui | tcell | gdb | ptyx
ptyx    ──X──>  termui | tcell
gdb     ──X──>  termui | tcell

Why: FRAMEWORK must stay reusable for non-debugger apps; backends stay UI-agnostic.

How data crosses the boundary: generic core.PtyOutputMsg / ExecOutputMsg; debugger UI payloads in internal/gdbforge/events (GdbOutputMsg, InferiorOutputMsg); composition in cmd/gdbforge.

Automated check: task check-imports (or ./scripts/check_imports.sh).


Verifying imports locally

Exact import lists change as code evolves. Regenerate them with:

# External modules
go list -m all

# Per-package imports
for pkg in ./internal/termui ./internal/core ./internal/ptyx ./internal/gdb \
           ./internal/execcli ./internal/mcp ./internal/gdbforge/widgets ./cmd/gdbforge ./cmd/docserve; do
  echo "=== $pkg ==="
  go list -f '{{join .Imports "\n"}}' $pkg | sort -u
done

To check for forbidden imports:

task check-imports
# or: ./scripts/check_imports.sh

go list -f '{{.ImportPath}} imports {{.Imports}}' ./internal/... ./cmd/...