Skip to content

Commit 0342c15

Browse files
committed
πŸ“ Update AGENTS.md with CLI subcommand lessons learned
1 parent 2df7257 commit 0342c15

1 file changed

Lines changed: 15 additions & 1 deletion

File tree

β€ŽAGENTS.mdβ€Ž

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# AGENT INSTRUCTIONS
22

3-
**Last Updated:** March 2026 | **For:** pvetui - Proxmox TUI
3+
**Last Updated:** March 2026 (CLI subcommands) | **For:** pvetui - Proxmox TUI
44

55
## Table of Contents
66
- [Initial Setup](#initial-setup)
@@ -170,6 +170,13 @@ The following conventions must be followed for any changes in this repository.
170170
- CacheItem stores data as `json.RawMessage` to avoid double marshaling
171171
- Supports configurable size limits for memory management
172172

173+
- **`internal/cli/`** - Non-interactive CLI subcommands (nodes, guests, tasks)
174+
- `cli_helpers.go` - `cliSession` abstraction, SSH helpers, output utilities
175+
- `guests.go` - Guest list/show/lifecycle/exec (QEMU guest agent + LXC pct exec)
176+
- `nodes.go` - Node list/show
177+
- `tasks.go` - Task list
178+
- All subcommands work with single-profile and aggregate group profiles transparently
179+
173180
- **`internal/ui/`** - TUI components using tview library
174181
- Main interface with tabbed navigation (Nodes, Guests, Tasks)
175182
- Context menus, dialogs, forms, and detail panels
@@ -263,6 +270,9 @@ Key architectural decisions and rationale:
263270
- **Interface-driven design**: All public APIs accept interfaces for maximum testability and flexibility
264271
- **Namespaced plugin caching**: Prevents cache key collisions and allows per-plugin cache management
265272
- **Plugin modal page registration**: Plugins declare modal pages via `ModalPageNames()` method instead of modifying core keyboard handler; maintains separation of concerns and enables self-contained plugins
273+
- **CLI subcommands via `cliSession`**: Non-interactive CLI shares all auth/config/group logic with the TUI through a `cliSession` struct that wraps either `*api.Client` (single profile) or `*api.GroupClientManager` (group/aggregate). Subcommand handlers call methods on `cliSession` without knowing which mode they're in. `BootstrapOptions.Quiet = true` suppresses TUI banners; `SilenceUsage: true` on the Cobra root prevents runtime errors from printing the full help menu.
274+
- **LXC exec via SSH + pct exec**: LXC containers have no API exec equivalent (unlike QEMU guest agent). Use `SSHClientImpl.ExecuteContainerCommandDetailed` from the command-runner package to run `pct exec <ctid> -- <cmd>` over SSH to the Proxmox node. SSH credentials are resolved per-VM via `vm.SourceProfile` β†’ global config fallback.
275+
- **Agent skill packaging**: Skills for the skills.sh ecosystem live in `skills/<skill-name>/SKILL.md` at the repo root. Install via `npx skills add owner/repo`. The `skills/` path is auto-discovered; `docs/skills/` is not.
266276

267277
## Common Pitfalls
268278

@@ -293,6 +303,10 @@ Key architectural decisions and rationale:
293303
- **Template guests are not ordinary stopped guests**: Proxmox templates often surface with `status=stopped`, but lifecycle UX must treat `VM.Template` as authoritative: label templates explicitly in guest list/details, do not offer start actions, and exclude them from batch lifecycle actions.
294304
- **Keybind unsetting semantics**: Treat empty string keybinds (for example `global_menu: ""`) as explicit unbinds; do not silently reapply default keys.
295305
- **Back navigation consistency**: For non-input views, support both `Esc` and `Backspace` for back navigation; avoid adding `Backspace` handlers on input-focused views where it must remain text editing.
306+
- **Cobra `SilenceUsage`**: Set `SilenceUsage: true` on the root command so runtime errors (API failures, not-found, wrong guest type) don't print the full help menu. Without it, any `RunE` error dumps usage, which is confusing for CLI consumers.
307+
- **CLI group mode detection**: Check `result.InitialGroup != ""` (from `bootstrap.Bootstrap`) to determine group mode; build a `GroupClientManager` with one `api.Client` per profile using `cfg.GetProfileNamesInGroup()`. Don't rely on single-client code paths when group mode is active β€” they only see one node's data.
308+
- **CLI SSH credential resolution**: For operations that need SSH to a node (e.g., LXC exec), resolve credentials with: source profile from `vm.SourceProfile` β†’ active profile β†’ global config `SSHUser`/`SSHJumpHost`. The same pattern is in `internal/ui/plugins/commandrunner/plugin.go:resolveSSHUser`.
309+
- **Shell quoting for pct exec**: When building `pct exec <ctid> -- <cmd>` as a shell string for `session.Run()`, shell-quote each argument with single quotes and escape embedded single quotes as `'\''`. Passing unquoted arguments silently mis-parses commands with spaces or special characters.
296310

297311
## Troubleshooting
298312

0 commit comments

Comments
Β (0)