|
1 | 1 | # AGENT INSTRUCTIONS |
2 | 2 |
|
3 | | -**Last Updated:** March 2026 | **For:** pvetui - Proxmox TUI |
| 3 | +**Last Updated:** March 2026 (CLI subcommands) | **For:** pvetui - Proxmox TUI |
4 | 4 |
|
5 | 5 | ## Table of Contents |
6 | 6 | - [Initial Setup](#initial-setup) |
@@ -170,6 +170,13 @@ The following conventions must be followed for any changes in this repository. |
170 | 170 | - CacheItem stores data as `json.RawMessage` to avoid double marshaling |
171 | 171 | - Supports configurable size limits for memory management |
172 | 172 |
|
| 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 | + |
173 | 180 | - **`internal/ui/`** - TUI components using tview library |
174 | 181 | - Main interface with tabbed navigation (Nodes, Guests, Tasks) |
175 | 182 | - Context menus, dialogs, forms, and detail panels |
@@ -263,6 +270,9 @@ Key architectural decisions and rationale: |
263 | 270 | - **Interface-driven design**: All public APIs accept interfaces for maximum testability and flexibility |
264 | 271 | - **Namespaced plugin caching**: Prevents cache key collisions and allows per-plugin cache management |
265 | 272 | - **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. |
266 | 276 |
|
267 | 277 | ## Common Pitfalls |
268 | 278 |
|
@@ -293,6 +303,10 @@ Key architectural decisions and rationale: |
293 | 303 | - **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. |
294 | 304 | - **Keybind unsetting semantics**: Treat empty string keybinds (for example `global_menu: ""`) as explicit unbinds; do not silently reapply default keys. |
295 | 305 | - **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. |
296 | 310 |
|
297 | 311 | ## Troubleshooting |
298 | 312 |
|
|
0 commit comments