Show Zotfile agent in startup resources
- commit
- d3084cce9102e211c4c9cac82493e72710514d1d
- author
- patriceckhart · · 2026-07-29 05:29 UTC
- parent
- 501b41b
- signature
- unsigned
- refs
- tag: v0.3.19
7 files · +25 -4
M README.md +2 -2
| @@ -159,7 +159,7 @@ zot discovers `AGENTS.md` files automatically at startup and loads them in this | |||
| 159 | 159 | 1. `$ZOT_HOME/AGENTS.md` (global, machine-wide instructions that apply to every project). | |
| 160 | 160 | 2. Every `AGENTS.md` from the filesystem root down to the current working directory. More specific (deeper) files may override earlier ones. This includes `~/AGENTS.md` when the working directory is inside your home directory. | |
| 161 | 161 | ||
| 162 | - | All discovered files are appended to the prompt in that order, so a global baseline can be refined per project. To list loaded context paths, extensions, and user-installed skills above the interactive transcript, enable **show loaded resources at startup** in `/settings`. The setting is off by default, built-in skills are omitted, and the displayed lists are not sent to the model or stored in the session transcript. | |
| 162 | + | All discovered files are appended to the prompt in that order, so a global baseline can be refined per project. To list the active Zotfile agent, loaded context paths, extensions, and user-installed skills above the interactive transcript, enable **show loaded resources at startup** in `/settings`. The agent section appears only for `zot run`, the setting is off by default, built-in skills are omitted, and the displayed lists are not sent to the model or stored in the session transcript. | |
| 163 | 163 | ||
| 164 | 164 | For a general, non-project-specific instruction set, put your rules in `$ZOT_HOME/AGENTS.md`, for example: | |
| 165 | 165 | ||
| @@ -381,7 +381,7 @@ Opens a dialog with every persistent setting. `up`/`down` to navigate, `enter` o | |||
| 381 | 381 | - **auto-compact threshold** — choose `off`, `70%`, `80%`, `85%` (default), or `90%` of the model's advertised context window. The selected percentage controls automatic compaction before and after interactive turns and persists as `auto_compact_threshold`. `off` disables percentage-based triggers but keeps manual `/compact` and automatic recovery from payload-too-large responses. | |
| 382 | 382 | - **jail new sessions by default**: start every new agent with tools confined to its working directory. Off by default. The setting applies to interactive, print, JSON, RPC, and background-agent runs, persists as `jail_by_default`, and immediately updates the current interactive session. `/jail` and `/unjail` remain session-scoped overrides and do not change this default. | |
| 383 | 383 | - **compact transcript rendering**: reduce visual chrome in the chat transcript. Tool calls render as a quiet header plus indented output instead of a bordered box, and sent messages render without padded background bubbles. Off by default. Changes apply immediately and persist to `config.json` as `compact_mode`. | |
| 384 | - | - **show loaded resources at startup**: list loaded `AGENTS.md` paths, extensions, and user-installed skills in compact sections above the transcript. Built-in skills are omitted. Off by default. Changes apply immediately and persist to `config.json` as `show_instructions_at_startup`. | |
| 384 | + | - **show loaded resources at startup**: list the active Zotfile agent (for `zot run`), loaded `AGENTS.md` paths, extensions, and user-installed skills in compact sections above the transcript. Built-in skills are omitted. Off by default. Changes apply immediately and persist to `config.json` as `show_instructions_at_startup`. | |
| 385 | 385 | - **TUI settings**: opens a sub-view for input layout and status placement. **Input style** can be `plain` (default prompt line), `lines` (separator lines above and below the input), or `block` (a user-bubble-style input block). **Status position** places model, usage, and working-directory information above or below the input. **Working spinner position** places the busy spinner above or below the input. Changes apply immediately and persist to `config.json` as `tui_input_style`, `tui_status_position`, and `tui_working_position` (`above_input` or `below_input` for the position fields). | |
| 386 | 386 | - **thinking level**: choose reasoning for supported models: off, minimum, low, medium, high, xhigh, or max. The `max` tier is opt-in and sent natively to GPT-5.6 and adaptive-thinking Claude models; unsupported backends clamp it to their highest accepted effort. The change is persisted to `config.json` and applied to the next model call. | |
| 387 | 387 | - **color theme** — choose the built-in auto/dark/light theme or any JSON theme discovered under `$ZOT_HOME/themes` or a loaded extension. Theme files can override any subset of UI colors, syntax colors, and spinner frames/messages. Changes apply immediately; if a selected theme file is deleted, zot resets to auto. See [docs/themes.md](docs/themes.md). | |
| @@ -159,7 +159,7 @@ zot discovers `AGENTS.md` files automatically at startup and loads them in this | |||||
| 159 | 1. `$ZOT_HOME/AGENTS.md` (global, machine-wide instructions that apply to every project). | 159 | 1. `$ZOT_HOME/AGENTS.md` (global, machine-wide instructions that apply to every project). | ||
| 160 | 2. Every `AGENTS.md` from the filesystem root down to the current working directory. More specific (deeper) files may override earlier ones. This includes `~/AGENTS.md` when the working directory is inside your home directory. | 160 | 2. Every `AGENTS.md` from the filesystem root down to the current working directory. More specific (deeper) files may override earlier ones. This includes `~/AGENTS.md` when the working directory is inside your home directory. | ||
| 161 | 161 | ||||
| 162 | - | All discovered files are appended to the prompt in that order, so a global baseline can be refined per project. To list loaded context paths, extensions, and user-installed skills above the interactive transcript, enable **show loaded resources at startup** in `/settings`. The setting is off by default, built-in skills are omitted, and the displayed lists are not sent to the model or stored in the session transcript. | 162 | + | All discovered files are appended to the prompt in that order, so a global baseline can be refined per project. To list the active Zotfile agent, loaded context paths, extensions, and user-installed skills above the interactive transcript, enable **show loaded resources at startup** in `/settings`. The agent section appears only for `zot run`, the setting is off by default, built-in skills are omitted, and the displayed lists are not sent to the model or stored in the session transcript. |
| 163 | 163 | ||||
| 164 | For a general, non-project-specific instruction set, put your rules in `$ZOT_HOME/AGENTS.md`, for example: | 164 | For a general, non-project-specific instruction set, put your rules in `$ZOT_HOME/AGENTS.md`, for example: | ||
| 165 | 165 | ||||
| @@ -381,7 +381,7 @@ Opens a dialog with every persistent setting. `up`/`down` to navigate, `enter` o | |||||
| 381 | - **auto-compact threshold** — choose `off`, `70%`, `80%`, `85%` (default), or `90%` of the model's advertised context window. The selected percentage controls automatic compaction before and after interactive turns and persists as `auto_compact_threshold`. `off` disables percentage-based triggers but keeps manual `/compact` and automatic recovery from payload-too-large responses. | 381 | - **auto-compact threshold** — choose `off`, `70%`, `80%`, `85%` (default), or `90%` of the model's advertised context window. The selected percentage controls automatic compaction before and after interactive turns and persists as `auto_compact_threshold`. `off` disables percentage-based triggers but keeps manual `/compact` and automatic recovery from payload-too-large responses. | ||
| 382 | - **jail new sessions by default**: start every new agent with tools confined to its working directory. Off by default. The setting applies to interactive, print, JSON, RPC, and background-agent runs, persists as `jail_by_default`, and immediately updates the current interactive session. `/jail` and `/unjail` remain session-scoped overrides and do not change this default. | 382 | - **jail new sessions by default**: start every new agent with tools confined to its working directory. Off by default. The setting applies to interactive, print, JSON, RPC, and background-agent runs, persists as `jail_by_default`, and immediately updates the current interactive session. `/jail` and `/unjail` remain session-scoped overrides and do not change this default. | ||
| 383 | - **compact transcript rendering**: reduce visual chrome in the chat transcript. Tool calls render as a quiet header plus indented output instead of a bordered box, and sent messages render without padded background bubbles. Off by default. Changes apply immediately and persist to `config.json` as `compact_mode`. | 383 | - **compact transcript rendering**: reduce visual chrome in the chat transcript. Tool calls render as a quiet header plus indented output instead of a bordered box, and sent messages render without padded background bubbles. Off by default. Changes apply immediately and persist to `config.json` as `compact_mode`. | ||
| 384 | - | - **show loaded resources at startup**: list loaded `AGENTS.md` paths, extensions, and user-installed skills in compact sections above the transcript. Built-in skills are omitted. Off by default. Changes apply immediately and persist to `config.json` as `show_instructions_at_startup`. | 384 | + | - **show loaded resources at startup**: list the active Zotfile agent (for `zot run`), loaded `AGENTS.md` paths, extensions, and user-installed skills in compact sections above the transcript. Built-in skills are omitted. Off by default. Changes apply immediately and persist to `config.json` as `show_instructions_at_startup`. |
| 385 | - **TUI settings**: opens a sub-view for input layout and status placement. **Input style** can be `plain` (default prompt line), `lines` (separator lines above and below the input), or `block` (a user-bubble-style input block). **Status position** places model, usage, and working-directory information above or below the input. **Working spinner position** places the busy spinner above or below the input. Changes apply immediately and persist to `config.json` as `tui_input_style`, `tui_status_position`, and `tui_working_position` (`above_input` or `below_input` for the position fields). | 385 | - **TUI settings**: opens a sub-view for input layout and status placement. **Input style** can be `plain` (default prompt line), `lines` (separator lines above and below the input), or `block` (a user-bubble-style input block). **Status position** places model, usage, and working-directory information above or below the input. **Working spinner position** places the busy spinner above or below the input. Changes apply immediately and persist to `config.json` as `tui_input_style`, `tui_status_position`, and `tui_working_position` (`above_input` or `below_input` for the position fields). | ||
| 386 | - **thinking level**: choose reasoning for supported models: off, minimum, low, medium, high, xhigh, or max. The `max` tier is opt-in and sent natively to GPT-5.6 and adaptive-thinking Claude models; unsupported backends clamp it to their highest accepted effort. The change is persisted to `config.json` and applied to the next model call. | 386 | - **thinking level**: choose reasoning for supported models: off, minimum, low, medium, high, xhigh, or max. The `max` tier is opt-in and sent natively to GPT-5.6 and adaptive-thinking Claude models; unsupported backends clamp it to their highest accepted effort. The change is persisted to `config.json` and applied to the next model call. | ||
| 387 | - **color theme** — choose the built-in auto/dark/light theme or any JSON theme discovered under `$ZOT_HOME/themes` or a loaded extension. Theme files can override any subset of UI colors, syntax colors, and spinner frames/messages. Changes apply immediately; if a selected theme file is deleted, zot resets to auto. See [docs/themes.md](docs/themes.md). | 387 | - **color theme** — choose the built-in auto/dark/light theme or any JSON theme discovered under `$ZOT_HOME/themes` or a loaded extension. Theme files can override any subset of UI colors, syntax colors, and spinner frames/messages. Changes apply immediately; if a selected theme file is deleted, zot resets to auto. See [docs/themes.md](docs/themes.md). | ||
M docs/zotfiles.md +1 -1
| @@ -492,7 +492,7 @@ zot run ./my-agent.zot --print "Do the task" | |||
| 492 | 492 | zot run ./my-agent.zot --json "Do the task" | |
| 493 | 493 | ``` | |
| 494 | 494 | ||
| 495 | - | Arguments after the reference use zot's normal CLI parser, so model, provider, reasoning, cwd, session, tool, and output-mode flags remain available. The manifest still imposes its permission and compatibility ceiling. | |
| 495 | + | Arguments after the reference use zot's normal CLI parser, so model, provider, reasoning, cwd, session, tool, and output-mode flags remain available. The manifest still imposes its permission and compatibility ceiling. In interactive mode, enabling **show loaded resources at startup** in `/settings` displays the manifest name in an `[Agent]` section above the transcript. | |
| 496 | 496 | ||
| 497 | 497 | Local filesystem directories, local archive paths, short names, and public GitHub agent-directory URLs are accepted. A short name uses local-first resolution: | |
| 498 | 498 | ||
| @@ -492,7 +492,7 @@ zot run ./my-agent.zot --print "Do the task" | |||||
| 492 | zot run ./my-agent.zot --json "Do the task" | 492 | zot run ./my-agent.zot --json "Do the task" | ||
| 493 | ``` | 493 | ``` | ||
| 494 | 494 | ||||
| 495 | - | Arguments after the reference use zot's normal CLI parser, so model, provider, reasoning, cwd, session, tool, and output-mode flags remain available. The manifest still imposes its permission and compatibility ceiling. | 495 | + | Arguments after the reference use zot's normal CLI parser, so model, provider, reasoning, cwd, session, tool, and output-mode flags remain available. The manifest still imposes its permission and compatibility ceiling. In interactive mode, enabling **show loaded resources at startup** in `/settings` displays the manifest name in an `[Agent]` section above the transcript. |
| 496 | 496 | ||||
| 497 | Local filesystem directories, local archive paths, short names, and public GitHub agent-directory URLs are accepted. A short name uses local-first resolution: | 497 | Local filesystem directories, local archive paths, short names, and public GitHub agent-directory URLs are accepted. A short name uses local-first resolution: | ||
| 498 | 498 | ||||
M packages/agent/cli.go +1 -0
| @@ -1013,6 +1013,7 @@ func runInteractive(ctx context.Context, args Args, version string) error { | |||
| 1013 | 1013 | Tools: r.ToolRegistry, | |
| 1014 | 1014 | MaxSteps: r.MaxSteps, | |
| 1015 | 1015 | CWD: r.CWD, | |
| 1016 | + | StartupAgentName: args.AgentName, | |
| 1016 | 1017 | StartupContextPaths: instructionContextPaths(r.ContextFiles), | |
| 1017 | 1018 | StartupExtensionNames: startupExtensionNames(extMgr.All()), | |
| 1018 | 1019 | StartupExtensionErrors: startupExtensionErrors, | |
| @@ -1013,6 +1013,7 @@ func runInteractive(ctx context.Context, args Args, version string) error { | |||||
| 1013 | Tools: r.ToolRegistry, | 1013 | Tools: r.ToolRegistry, | ||
| 1014 | MaxSteps: r.MaxSteps, | 1014 | MaxSteps: r.MaxSteps, | ||
| 1015 | CWD: r.CWD, | 1015 | CWD: r.CWD, | ||
| 1016 | + | StartupAgentName: args.AgentName, | |||
| 1016 | StartupContextPaths: instructionContextPaths(r.ContextFiles), | 1017 | StartupContextPaths: instructionContextPaths(r.ContextFiles), | ||
| 1017 | StartupExtensionNames: startupExtensionNames(extMgr.All()), | 1018 | StartupExtensionNames: startupExtensionNames(extMgr.All()), | ||
| 1018 | StartupExtensionErrors: startupExtensionErrors, | 1019 | StartupExtensionErrors: startupExtensionErrors, | ||
M packages/agent/modes/interactive.go +6 -0
| @@ -40,6 +40,7 @@ type InteractiveConfig struct { | |||
| 40 | 40 | ||
| 41 | 41 | // Startup resource fields are loaded inputs available to list before the | |
| 42 | 42 | // transcript. They are never sent to the provider or persisted by the view. | |
| 43 | + | StartupAgentName string | |
| 43 | 44 | StartupContextPaths []string | |
| 44 | 45 | StartupExtensionNames []string | |
| 45 | 46 | StartupSkillNames []string | |
| @@ -550,10 +551,12 @@ const resumeTailExpandStep = 80 | |||
| 550 | 551 | func NewInteractive(cfg InteractiveConfig) *Interactive { | |
| 551 | 552 | renderer := tui.NewRenderer(cfg.Terminal) | |
| 552 | 553 | renderer.SetTheme(cfg.Theme) | |
| 554 | + | startupAgentName := "" | |
| 553 | 555 | startupContextPaths := []string(nil) | |
| 554 | 556 | startupExtensionNames := []string(nil) | |
| 555 | 557 | startupSkillNames := []string(nil) | |
| 556 | 558 | if cfg.ShowInstructionsAtStartup != nil && *cfg.ShowInstructionsAtStartup { | |
| 559 | + | startupAgentName = cfg.StartupAgentName | |
| 557 | 560 | startupContextPaths = append(startupContextPaths, cfg.StartupContextPaths...) | |
| 558 | 561 | startupExtensionNames = append(startupExtensionNames, cfg.StartupExtensionNames...) | |
| 559 | 562 | startupSkillNames = append(startupSkillNames, cfg.StartupSkillNames...) | |
| @@ -566,6 +569,7 @@ func NewInteractive(cfg InteractiveConfig) *Interactive { | |||
| 566 | 569 | FlatTools: cfg.FlatTools, | |
| 567 | 570 | CompactUser: cfg.CompactUser, | |
| 568 | 571 | CompactMode: cfg.CompactMode != nil && *cfg.CompactMode, | |
| 572 | + | StartupAgentName: startupAgentName, | |
| 569 | 573 | StartupContextPaths: startupContextPaths, | |
| 570 | 574 | StartupExtensionNames: startupExtensionNames, | |
| 571 | 575 | StartupSkillNames: startupSkillNames, | |
| @@ -3719,10 +3723,12 @@ func (i *Interactive) applySettingToggle(key string, value bool) { | |||
| 3719 | 3723 | } | |
| 3720 | 3724 | } | |
| 3721 | 3725 | i.mu.Lock() | |
| 3726 | + | i.view.StartupAgentName = "" | |
| 3722 | 3727 | i.view.StartupContextPaths = nil | |
| 3723 | 3728 | i.view.StartupExtensionNames = nil | |
| 3724 | 3729 | i.view.StartupSkillNames = nil | |
| 3725 | 3730 | if value { | |
| 3731 | + | i.view.StartupAgentName = i.cfg.StartupAgentName | |
| 3726 | 3732 | i.view.StartupContextPaths = append(i.view.StartupContextPaths, i.cfg.StartupContextPaths...) | |
| 3727 | 3733 | i.view.StartupExtensionNames = append(i.view.StartupExtensionNames, i.cfg.StartupExtensionNames...) | |
| 3728 | 3734 | i.view.StartupSkillNames = append(i.view.StartupSkillNames, i.cfg.StartupSkillNames...) | |
| @@ -40,6 +40,7 @@ type InteractiveConfig struct { | |||||
| 40 | 40 | ||||
| 41 | // Startup resource fields are loaded inputs available to list before the | 41 | // Startup resource fields are loaded inputs available to list before the | ||
| 42 | // transcript. They are never sent to the provider or persisted by the view. | 42 | // transcript. They are never sent to the provider or persisted by the view. | ||
| 43 | + | StartupAgentName string | |||
| 43 | StartupContextPaths []string | 44 | StartupContextPaths []string | ||
| 44 | StartupExtensionNames []string | 45 | StartupExtensionNames []string | ||
| 45 | StartupSkillNames []string | 46 | StartupSkillNames []string | ||
| @@ -550,10 +551,12 @@ const resumeTailExpandStep = 80 | |||||
| 550 | func NewInteractive(cfg InteractiveConfig) *Interactive { | 551 | func NewInteractive(cfg InteractiveConfig) *Interactive { | ||
| 551 | renderer := tui.NewRenderer(cfg.Terminal) | 552 | renderer := tui.NewRenderer(cfg.Terminal) | ||
| 552 | renderer.SetTheme(cfg.Theme) | 553 | renderer.SetTheme(cfg.Theme) | ||
| 554 | + | startupAgentName := "" | |||
| 553 | startupContextPaths := []string(nil) | 555 | startupContextPaths := []string(nil) | ||
| 554 | startupExtensionNames := []string(nil) | 556 | startupExtensionNames := []string(nil) | ||
| 555 | startupSkillNames := []string(nil) | 557 | startupSkillNames := []string(nil) | ||
| 556 | if cfg.ShowInstructionsAtStartup != nil && *cfg.ShowInstructionsAtStartup { | 558 | if cfg.ShowInstructionsAtStartup != nil && *cfg.ShowInstructionsAtStartup { | ||
| 559 | + | startupAgentName = cfg.StartupAgentName | |||
| 557 | startupContextPaths = append(startupContextPaths, cfg.StartupContextPaths...) | 560 | startupContextPaths = append(startupContextPaths, cfg.StartupContextPaths...) | ||
| 558 | startupExtensionNames = append(startupExtensionNames, cfg.StartupExtensionNames...) | 561 | startupExtensionNames = append(startupExtensionNames, cfg.StartupExtensionNames...) | ||
| 559 | startupSkillNames = append(startupSkillNames, cfg.StartupSkillNames...) | 562 | startupSkillNames = append(startupSkillNames, cfg.StartupSkillNames...) | ||
| @@ -566,6 +569,7 @@ func NewInteractive(cfg InteractiveConfig) *Interactive { | |||||
| 566 | FlatTools: cfg.FlatTools, | 569 | FlatTools: cfg.FlatTools, | ||
| 567 | CompactUser: cfg.CompactUser, | 570 | CompactUser: cfg.CompactUser, | ||
| 568 | CompactMode: cfg.CompactMode != nil && *cfg.CompactMode, | 571 | CompactMode: cfg.CompactMode != nil && *cfg.CompactMode, | ||
| 572 | + | StartupAgentName: startupAgentName, | |||
| 569 | StartupContextPaths: startupContextPaths, | 573 | StartupContextPaths: startupContextPaths, | ||
| 570 | StartupExtensionNames: startupExtensionNames, | 574 | StartupExtensionNames: startupExtensionNames, | ||
| 571 | StartupSkillNames: startupSkillNames, | 575 | StartupSkillNames: startupSkillNames, | ||
| @@ -3719,10 +3723,12 @@ func (i *Interactive) applySettingToggle(key string, value bool) { | |||||
| 3719 | } | 3723 | } | ||
| 3720 | } | 3724 | } | ||
| 3721 | i.mu.Lock() | 3725 | i.mu.Lock() | ||
| 3726 | + | i.view.StartupAgentName = "" | |||
| 3722 | i.view.StartupContextPaths = nil | 3727 | i.view.StartupContextPaths = nil | ||
| 3723 | i.view.StartupExtensionNames = nil | 3728 | i.view.StartupExtensionNames = nil | ||
| 3724 | i.view.StartupSkillNames = nil | 3729 | i.view.StartupSkillNames = nil | ||
| 3725 | if value { | 3730 | if value { | ||
| 3731 | + | i.view.StartupAgentName = i.cfg.StartupAgentName | |||
| 3726 | i.view.StartupContextPaths = append(i.view.StartupContextPaths, i.cfg.StartupContextPaths...) | 3732 | i.view.StartupContextPaths = append(i.view.StartupContextPaths, i.cfg.StartupContextPaths...) | ||
| 3727 | i.view.StartupExtensionNames = append(i.view.StartupExtensionNames, i.cfg.StartupExtensionNames...) | 3733 | i.view.StartupExtensionNames = append(i.view.StartupExtensionNames, i.cfg.StartupExtensionNames...) | ||
| 3728 | i.view.StartupSkillNames = append(i.view.StartupSkillNames, i.cfg.StartupSkillNames...) | 3734 | i.view.StartupSkillNames = append(i.view.StartupSkillNames, i.cfg.StartupSkillNames...) | ||
M packages/agent/modes/startup_instructions_test.go +8 -0
| @@ -4,6 +4,7 @@ import "testing" | |||
| 4 | 4 | ||
| 5 | 5 | func TestStartupResourcesAreOptIn(t *testing.T) { | |
| 6 | 6 | cfg := InteractiveConfig{ | |
| 7 | + | StartupAgentName: "zot-maintenance", | |
| 7 | 8 | StartupContextPaths: []string{"/repo/AGENTS.md"}, | |
| 8 | 9 | StartupExtensionNames: []string{"workspaces"}, | |
| 9 | 10 | StartupSkillNames: []string{"review"}, | |
| @@ -27,6 +28,13 @@ func TestStartupResourcesAreOptIn(t *testing.T) { | |||
| 27 | 28 | ||
| 28 | 29 | func assertStartupResourceCounts(t *testing.T, i *Interactive, want int) { | |
| 29 | 30 | t.Helper() | |
| 31 | + | wantAgent := "" | |
| 32 | + | if want > 0 { | |
| 33 | + | wantAgent = "zot-maintenance" | |
| 34 | + | } | |
| 35 | + | if got := i.view.StartupAgentName; got != wantAgent { | |
| 36 | + | t.Fatalf("startup agent = %q, want %q", got, wantAgent) | |
| 37 | + | } | |
| 30 | 38 | if got := len(i.view.StartupContextPaths); got != want { | |
| 31 | 39 | t.Fatalf("startup context count = %d, want %d", got, want) | |
| 32 | 40 | } | |
| @@ -4,6 +4,7 @@ import "testing" | |||||
| 4 | 4 | ||||
| 5 | func TestStartupResourcesAreOptIn(t *testing.T) { | 5 | func TestStartupResourcesAreOptIn(t *testing.T) { | ||
| 6 | cfg := InteractiveConfig{ | 6 | cfg := InteractiveConfig{ | ||
| 7 | + | StartupAgentName: "zot-maintenance", | |||
| 7 | StartupContextPaths: []string{"/repo/AGENTS.md"}, | 8 | StartupContextPaths: []string{"/repo/AGENTS.md"}, | ||
| 8 | StartupExtensionNames: []string{"workspaces"}, | 9 | StartupExtensionNames: []string{"workspaces"}, | ||
| 9 | StartupSkillNames: []string{"review"}, | 10 | StartupSkillNames: []string{"review"}, | ||
| @@ -27,6 +28,13 @@ func TestStartupResourcesAreOptIn(t *testing.T) { | |||||
| 27 | 28 | ||||
| 28 | func assertStartupResourceCounts(t *testing.T, i *Interactive, want int) { | 29 | func assertStartupResourceCounts(t *testing.T, i *Interactive, want int) { | ||
| 29 | t.Helper() | 30 | t.Helper() | ||
| 31 | + | wantAgent := "" | |||
| 32 | + | if want > 0 { | |||
| 33 | + | wantAgent = "zot-maintenance" | |||
| 34 | + | } | |||
| 35 | + | if got := i.view.StartupAgentName; got != wantAgent { | |||
| 36 | + | t.Fatalf("startup agent = %q, want %q", got, wantAgent) | |||
| 37 | + | } | |||
| 30 | if got := len(i.view.StartupContextPaths); got != want { | 38 | if got := len(i.view.StartupContextPaths); got != want { | ||
| 31 | t.Fatalf("startup context count = %d, want %d", got, want) | 39 | t.Fatalf("startup context count = %d, want %d", got, want) | ||
| 32 | } | 40 | } | ||
M packages/tui/view.go +4 -0
| @@ -125,6 +125,7 @@ type View struct { | |||
| 125 | 125 | ||
| 126 | 126 | // Startup resource fields list host-loaded inputs before the transcript | |
| 127 | 127 | // without creating provider messages or persisted entries. | |
| 128 | + | StartupAgentName string | |
| 128 | 129 | StartupContextPaths []string | |
| 129 | 130 | StartupExtensionNames []string | |
| 130 | 131 | StartupSkillNames []string | |
| @@ -345,6 +346,9 @@ func (v *View) renderStartupResources(width int) []string { | |||
| 345 | 346 | } | |
| 346 | 347 | out = append(out, "") | |
| 347 | 348 | } | |
| 349 | + | if v.StartupAgentName != "" { | |
| 350 | + | appendSection("Agent", []string{v.StartupAgentName}) | |
| 351 | + | } | |
| 348 | 352 | appendSection("Context", v.StartupContextPaths) | |
| 349 | 353 | appendSection("Extensions", v.StartupExtensionNames) | |
| 350 | 354 | appendSection("Skills", v.StartupSkillNames) | |
| @@ -125,6 +125,7 @@ type View struct { | |||||
| 125 | 125 | ||||
| 126 | // Startup resource fields list host-loaded inputs before the transcript | 126 | // Startup resource fields list host-loaded inputs before the transcript | ||
| 127 | // without creating provider messages or persisted entries. | 127 | // without creating provider messages or persisted entries. | ||
| 128 | + | StartupAgentName string | |||
| 128 | StartupContextPaths []string | 129 | StartupContextPaths []string | ||
| 129 | StartupExtensionNames []string | 130 | StartupExtensionNames []string | ||
| 130 | StartupSkillNames []string | 131 | StartupSkillNames []string | ||
| @@ -345,6 +346,9 @@ func (v *View) renderStartupResources(width int) []string { | |||||
| 345 | } | 346 | } | ||
| 346 | out = append(out, "") | 347 | out = append(out, "") | ||
| 347 | } | 348 | } | ||
| 349 | + | if v.StartupAgentName != "" { | |||
| 350 | + | appendSection("Agent", []string{v.StartupAgentName}) | |||
| 351 | + | } | |||
| 348 | appendSection("Context", v.StartupContextPaths) | 352 | appendSection("Context", v.StartupContextPaths) | ||
| 349 | appendSection("Extensions", v.StartupExtensionNames) | 353 | appendSection("Extensions", v.StartupExtensionNames) | ||
| 350 | appendSection("Skills", v.StartupSkillNames) | 354 | appendSection("Skills", v.StartupSkillNames) | ||
M packages/tui/view_tool_overlay_test.go +3 -1
| @@ -10,7 +10,8 @@ import ( | |||
| 10 | 10 | ||
| 11 | 11 | func TestStartupResourcesRenderAsCompactSections(t *testing.T) { | |
| 12 | 12 | v := View{ | |
| 13 | - | Theme: Dark, | |
| 13 | + | Theme: Dark, | |
| 14 | + | StartupAgentName: "zot-maintenance", | |
| 14 | 15 | StartupContextPaths: []string{ | |
| 15 | 16 | "/home/user/AGENTS.md", | |
| 16 | 17 | "/repo/AGENTS.md", | |
| @@ -21,6 +22,7 @@ func TestStartupResourcesRenderAsCompactSections(t *testing.T) { | |||
| 21 | 22 | ||
| 22 | 23 | plain := stripANSI(strings.Join(v.Build(80), "\n")) | |
| 23 | 24 | for _, want := range []string{ | |
| 25 | + | "[Agent]", "zot-maintenance", | |
| 24 | 26 | "[Context]", "/home/user/AGENTS.md, /repo/AGENTS.md", | |
| 25 | 27 | "[Extensions]", "todo, workspaces", | |
| 26 | 28 | "[Skills]", "review, test", | |
| @@ -10,7 +10,8 @@ import ( | |||||
| 10 | 10 | ||||
| 11 | func TestStartupResourcesRenderAsCompactSections(t *testing.T) { | 11 | func TestStartupResourcesRenderAsCompactSections(t *testing.T) { | ||
| 12 | v := View{ | 12 | v := View{ | ||
| 13 | - | Theme: Dark, | 13 | + | Theme: Dark, |
| 14 | + | StartupAgentName: "zot-maintenance", | |||
| 14 | StartupContextPaths: []string{ | 15 | StartupContextPaths: []string{ | ||
| 15 | "/home/user/AGENTS.md", | 16 | "/home/user/AGENTS.md", | ||
| 16 | "/repo/AGENTS.md", | 17 | "/repo/AGENTS.md", | ||
| @@ -21,6 +22,7 @@ func TestStartupResourcesRenderAsCompactSections(t *testing.T) { | |||||
| 21 | 22 | ||||
| 22 | plain := stripANSI(strings.Join(v.Build(80), "\n")) | 23 | plain := stripANSI(strings.Join(v.Build(80), "\n")) | ||
| 23 | for _, want := range []string{ | 24 | for _, want := range []string{ | ||
| 25 | + | "[Agent]", "zot-maintenance", | |||
| 24 | "[Context]", "/home/user/AGENTS.md, /repo/AGENTS.md", | 26 | "[Context]", "/home/user/AGENTS.md, /repo/AGENTS.md", | ||
| 25 | "[Extensions]", "todo, workspaces", | 27 | "[Extensions]", "todo, workspaces", | ||
| 26 | "[Skills]", "review, test", | 28 | "[Skills]", "review, test", | ||