mirror of
https://github.com/docker/docker-agent.git
synced 2026-11-04 10:02:15 +00:00
Typing `/<skill-name>` in the TUI for a skill declared with `context: fork` used to inline the SKILL.md body into the parent conversation as a regular user message and let the parent agent answer it directly. The fork flag was silently ignored on this path: no sub-session was created, the parent transcript was polluted with a giant `<skill name="…">…</skill>` block, and the skill's own `allowed-tools` / `description` had no effect. Route fork-mode slash commands through the same machinery the `run_skill` tool uses, so the skill runs in an isolated child session and control returns to the parent when it ends: - `Runtime.RunSkillFork` is now a public entry point shared by the `run_skill` tool and the new App-level slash dispatcher; it handles lookup, fork-mode validation, content+placeholder expansion, optional model override, and `runForwarding`. - `App.SkillCommandFork` classifies user input as a fork-skill invocation; `App.RunSkillFork` drives the runtime and forwards events through the App's bus with the same context/cancellation discipline as `App.Run`. - `App.ResolveSkillCommand` short-circuits for fork-mode skills so `ResolveInput` never returns the inlined body for them. - The chat page calls `SkillCommandFork` first and falls back to the existing inline path for non-fork skills, agent commands and plain messages. The skill body is now framed as the **first user message** of the sub-session (matching the inline `<skill name="…">` envelope), not as an extra system message — otherwise the agent's invariant system prompt would drown it out and the model would ignore the instructions. The YAML frontmatter is stripped because the runtime has already consumed it; passing it through just adds noise. `!`shell`` placeholders continue to be expanded by the existing `ReadSkillContent` path, while plain backtick markdown such as `` `git commit -q -m "<subject>"` `` passes through verbatim. Tests: - `pkg/app/skills_fork_test.go` covers slash-command detection, the fork dispatch contract (parent session not mutated, args forwarded), and the preserved inline path for non-fork skills. - `pkg/tools/builtin/skills/build_user_message_test.go` pins the user-message envelope, frontmatter stripping, and the markdown pass-through.