diff --git a/docs-ai/053-agent-profiles/000-plan.md b/docs-ai/053-agent-profiles/000-plan.md index 98757a79..9085188a 100644 --- a/docs-ai/053-agent-profiles/000-plan.md +++ b/docs-ai/053-agent-profiles/000-plan.md @@ -2,7 +2,7 @@ | | | | --- | --- | -| **Status** | Planned | +| **Status** | Implemented(见 [001-action.md](001-action.md)) | | **Anchor date** | 2026-07-29 | | **Primary PRs** | pending | | **Related** | [047 cross-agent handoff](../047-cross-agent-handoff/000-plan.md), [048 agent runtime adapters](../048-agent-runtime-adapters/000-plan.md), [049 Agents toolbar entry](../049-agents-toolbar-entry/000-plan.md), closed prototype [#617](https://github.com/onevcat/Prowl/pull/617) | diff --git a/docs-ai/053-agent-profiles/001-action.md b/docs-ai/053-agent-profiles/001-action.md new file mode 100644 index 00000000..a582d9a8 --- /dev/null +++ b/docs-ai/053-agent-profiles/001-action.md @@ -0,0 +1,63 @@ +# 053 — Agent Profiles: Action + +| | | +| --- | --- | +| **日期** | 2026-07-29 | +| **分支** | `agent/agent-profiles-v1` | +| **前置** | [000-plan.md](000-plan.md)(含全部讨论修订)· [002-home-spike.md](002-home-spike.md)(HOME 实测) | + +## 实施概要 + +按计划分五个提交块实现,每块独立通过测试、lint 与构建: + +1. **`8fa9c5b5` — domain 与 adapter**:`AgentProfile` 模型(preset 字段 + placement + + 可选账号绑定)、normalization、三层推荐 resolver、`ShellWordSplitter`; + `AgentStartIntent`(`.interactive` / `.prompt` / `.headless`)取代恒有 prompt, + handoff 调用点迁移;`AgentLaunchConfiguration` 增加 effort 与 extraArguments + (向后兼容解码);adapter 声明能力位(`CLAUDE_CONFIG_DIR` / `CODEX_HOME`)与 + effort 建议;`UserGlobalSettings` / `UserRepositorySettings` 扩展。 +2. **`b542cadb` — launch plan 与终端/检测**:`AgentProfileLaunchPlanner`(纯函数, + 预览与启动共用渲染)、`AgentProfileHomeProvisioner`(0700 + 包含校验)、 + `~/.prowl/agent-profiles/` 路径;`TerminalClient.launchAgentProfile` 经 + `GhosttySurfaceView(environment:)` 注入补丁,split 无可分割时退化为 tab, + surface 记录 launch 身份;claude/codex 的 `AgentSessionProfile` 增加 rooted + 布局,resolver 对绑定 surface 独占使用。 +3. **`ff536478` — AppFeature**:单一 `launchAgentProfile` action(解析 → 计划 → + 终端命令 + per-repo 记忆);`AgentProfileSeeder` 启动时一次性播种(安装启发: + 默认 home 存在),删除的种子不复活。 +4. **`a87d8f69` — Settings UI**:独立 Agents tab(列表顺序即兜底优先级、编辑器、 + Advanced 附加参数/绑定/预览);`.unrestricted` 保存前确认;绑定 profile 删除 + 走"确认 + 默认保留 + 可选 Trash";`AgentProfileHomeClient` 统一文件操作与 + 包含闸;Repo Settings 增加 Default Agent Profile 选择器。 +5. **`cf446750` — 入口与身份露出**:Agents capsule 永远是菜单(Hand Off 领衔、 + 推荐排前、未安装灰显示因、Manage 入口);palette "Launch Agent" 行共享同一 + action;Prowl 启动的 pane 在 Active Agents/capsule 显示 launch 时冻结的 + profile 名。 + +文档同步:新增 `docs/components/agent-profiles.md`,并更新 settings / +command-palette / active-agents / handoff 与 `docs/README.md` 索引。 + +## 测试证据 + +- 全量套件:`make test` 通过,**2105 个测试全绿**(5 个 warning 为 SPM 依赖扫描 + 既有噪音)。 +- 新增/扩展:`AgentProfileTests`(normalization、推荐回退、splitter、launch plan、 + 包含校验、provisioner 权限、settings 兼容解码)、`AgentRuntimeAdapterTests` + (三态 argv、effort 映射、附加参数顺序、能力位、legacy 解码)、 + `AgentProfilesFeatureTests`(增删改排、unrestricted 确认、绑定删除 Trash、 + repo 默认持久化)、`AppFeatureAgentProfileTests`(launch 命令与记忆、禁用忽略、 + 播种一次性、palette 条目、身份展示)、`AgentSessionProfileTests` rooted 布局。 +- `make check` 与 `make build-app` 全程零错误零警告。 +- 前置实测见 002-home-spike.md(指令文件/skills 原生拾取、凭证落点、并行登录 + 无串号、真实 home 零污染)。 + +## 与计划的偏差 + +1. **model 建议列表未实现**:model 为纯自由文本,只有 effort 有 adapter 建议列表。 + 原因:没有可靠的已验证 model 目录,硬编码会立即过时;后续可与 effort 同构补上。 +2. **resume 携带环境补丁推迟到 handoff 波次**:检测层的 config root 已实现,但 + `AgentResumeRequest` 未增加环境字段——填充它需要 handoff 的结构化请求改造 + (正是计划明确推迟的双路径工程)。当前从绑定 pane 发起 handoff 时,briefing + resume 会找不到 session 并优雅降级为 context-only。已知且可接受。 +3. **Settings 列表排序用上下移动(右键菜单)而非拖拽**:Form 内拖拽在 macOS 上 + 体验不佳;顺序语义(兜底优先级)不受影响。 diff --git a/docs/README.md b/docs/README.md index b6cf7da2..b7449371 100644 --- a/docs/README.md +++ b/docs/README.md @@ -51,6 +51,7 @@ its keyboard shortcuts, detailed behavior, settings, and gotchas. | [`components/command-palette.md`](components/command-palette.md) | `⌘P` searchable command launcher; every action category it exposes. | | [`components/active-agents.md`](components/active-agents.md) | The Active Agents panel: a live list of every running agent and its status, with one-click jump-to-agent. | | [`components/agent-detection.md`](components/agent-detection.md) | How Prowl knows an agent is Working / Blocked / Idle / Done, which agents it recognizes, and how the status indicator works. | +| [`components/agent-profiles.md`](components/agent-profiles.md) | Agent Profiles: named launch presets for Claude Code/Codex (model, effort, mode, placement), the Agents launcher menu, recommended-profile resolution, and opt-in dedicated homes for separate accounts. | | [`components/notifications.md`](components/notifications.md) | Agent-finished reminders, command-finished notifications, the bell/unread indicators, and Dock badge/bounce. | | [`components/diff-view.md`](components/diff-view.md) | Show Diff (`⌘⇧Y`) for working-tree changes vs HEAD, plus Outgoing Changes for pull-request branch diffs. | | [`components/github-pull-requests.md`](components/github-pull-requests.md) | GitHub PR integration via `gh`: PR status, CI checks, merge/close/re-run actions from the command palette. | diff --git a/docs/components/active-agents.md b/docs/components/active-agents.md index b87352cf..de91c8f4 100644 --- a/docs/components/active-agents.md +++ b/docs/components/active-agents.md @@ -28,7 +28,9 @@ Command Palette → "Toggle Active Agents Panel". icon even though it reports as the Pi agent; unknown wrappers fall back to the agent icon, then a sparkle). - **Title** — detected command/agent name + repository (repo color-coded); - command aliases such as `omp` are shown directly. + command aliases such as `omp` are shown directly. Panes Prowl launched from + an [agent profile](agent-profiles.md) show the profile's display name + instead (frozen at launch). - **Subtitle** — the agent's pane title (if `showActiveAgentTabTitles`) or branch name. The pane title is the surface's own terminal title, falling back to the tab title, so agents in different splits of one tab keep distinct subtitles. diff --git a/docs/components/agent-profiles.md b/docs/components/agent-profiles.md new file mode 100644 index 00000000..dfb61034 --- /dev/null +++ b/docs/components/agent-profiles.md @@ -0,0 +1,88 @@ +# Agent Profiles + +> Named launch presets for the verified agents (Claude Code, Codex): one click +> in the toolbar **Agents** menu or the Command Palette starts a fresh agent in +> the current worktree with your model, effort, mode, and — optionally — a +> dedicated account. + +**Keywords:** agent profile, preset, launch agent, agents menu, dedicated home, account, CLAUDE_CONFIG_DIR, CODEX_HOME, recommended profile + +**Related:** [handoff](handoff.md) · [active-agents](active-agents.md) · [command-palette](command-palette.md) · [settings](settings.md) + +## What a profile is + +A profile is a named preset for one runtime: display name, optional model, +optional reasoning effort (free text with per-runtime suggestions), execution +mode (Standard / Unrestricted), and a launch placement (New Tab or New Split +with a direction). By default a profile is **argv-only**: launching it is +exactly like typing `claude`/`codex` with those flags yourself — same login, +same skills, same session history. The same runtime can have any number of +profiles. + +On first run Prowl seeds one bare profile per installed runtime. Seeds are +ordinary profiles: rename, edit, or delete them freely — deleted seeds never +respawn. + +## Launching + +- **Toolbar Agents capsule** — always opens a popover. With a detected agent it + leads with Hand Off; launch rows follow, the current worktree's + **Recommended** profile first. Rows for runtimes that are not installed are + grayed with the reason. "Manage Agent Profiles…" opens Settings → Agents. +- **Command Palette** (`⌘P`) — "Launch Agent: " rows dispatch the exact + same action. + +A launch creates a **new** tab (or split, per placement) in the current +worktree, running the agent interactively with no initial prompt. Prowl never +types into an existing shell. The new pane records its profile identity at +creation: the Active Agents rows and the capsule show the profile's display +name (frozen at launch — later renames don't relabel live panes). + +**Recommended** resolves in three tiers: the repo's **Default Agent Profile** +(Repo Settings) → the last profile explicitly launched in this repo → the +first enabled profile in the Settings list order. Each tier only matches an +existing, enabled profile. + +## Dedicated home (separate account) + +Toggling **Use Dedicated Home** (Advanced) gives the profile its own runtime +home under `~/.prowl/agent-profiles//`, attached to the new surface via +`CLAUDE_CONFIG_DIR` / `CODEX_HOME`. That relocates the runtime's *entire* +home: separate login and usage, but also separate skills, global instructions +(`CLAUDE.md` / `AGENTS.md`), and session history. The first launch is the +sign-in moment — the agent's own TUI walks through login and the credentials +land inside the profile home. Prowl never reads or copies them; use **Reveal +Profile Files** to manage skills and instruction files there yourself. + +Deleting a bound profile asks first: **Remove Profile** keeps the folder on +disk, **Remove and Trash Files** moves it to the Trash (never `rm`). Pure +presets are removed with no file operations at all. + +## Advanced extra arguments + +The **Extra Arguments** field appends literal argv tokens after the +preset-generated options (quotes group values with spaces; nothing is ever +shell-interpreted). The **Launch Preview** at the bottom of the editor shows +the exact rendered invocation — including the env prefix for bound profiles — +using the same rendering as the real launch. + +## Where things live on disk + +| What | Where | +|------|-------| +| Profiles + seeding flag | `~/.prowl/global.onevcat.json` | +| Per-repo default + launch memory | `~/.prowl/repo//prowl.onevcat.json` | +| Dedicated profile homes | `~/.prowl/agent-profiles//` | + +## Gotchas for agents + +- Session detection follows the relocated home for Prowl-launched bound panes + (resume and handoff artifacts resolve against the profile's config root). + An agent you start manually with your own `CLAUDE_CONFIG_DIR`/`CODEX_HOME` + is still detected, but without session identity. +- Availability graying uses a heuristic: the runtime's default home + (`~/.claude` / `~/.codex`) exists iff the CLI has ever run. +- Prowl provides no directory sharing between a bound home and the default + one. Symlinking read-mostly directories (e.g. `skills/`) yourself works, but + never link files the CLI rewrites (`settings.json`, `config.toml`, + `auth.json`) — atomic rewrites replace the symlink and silently diverge. diff --git a/docs/components/command-palette.md b/docs/components/command-palette.md index b456b73e..752f15c4 100644 --- a/docs/components/command-palette.md +++ b/docs/components/command-palette.md @@ -51,6 +51,10 @@ selected worktree has a pull request). agent to write its briefing and run the hand-off itself, with fork and context-only fallbacks available while you wait. Same flow as the toolbar Agents capsule. See [handoff](handoff.md). +- **Agent profiles** (when a terminal worktree is selected): a + **Launch Agent: ** row per enabled profile, the current worktree's + Recommended profile first — the same launch action as the toolbar Agents + menu. See [agent-profiles](agent-profiles.md). - **Debug** (Debug builds only): toast/update/dock simulations. ## Behavior notes diff --git a/docs/components/handoff.md b/docs/components/handoff.md index e3ef1bb5..47d15cb5 100644 --- a/docs/components/handoff.md +++ b/docs/components/handoff.md @@ -167,7 +167,11 @@ same agent family. Full flag/payload reference: [cli](cli.md#prowl-handoff). A capsule button left of the branch title identifies the selected pane's detected agent. Clicking it opens a popover whose hand-off row explains the action — "Pass this task to another agent in a new tab; writes its own -briefing first" — and opens a centered HUD. The Command Palette (`⌘P`) offers +briefing first" — and opens a centered HUD. The popover is always available: +below the hand-off row it lists launchable +[agent profiles](agent-profiles.md) (Recommended first) and a +"Manage Agent Profiles…" entry, so the capsule doubles as the launcher even +when no agent is detected. The Command Palette (`⌘P`) offers the same flow as a single **Hand Off…** row; so does right-clicking a row in the [Active Agents panel](active-agents.md), which targets the row's own pane. diff --git a/docs/components/settings.md b/docs/components/settings.md index 9fdfc47f..6997621c 100644 --- a/docs/components/settings.md +++ b/docs/components/settings.md @@ -24,14 +24,16 @@ window is a sidebar of tabs plus a detail pane. | **Advanced** | Analytics, crash reports, restore terminal layout on launch (experimental) + clear saved layout, and the **Install Command Line Tool** (`prowl` CLI) action. | | **GitHub** | Enable GitHub integration (uses the `gh` CLI). → [github-pull-requests](github-pull-requests.md) | | **Commands** | Global Custom Commands. Enabled commands appear in the window toolbar; each repo can independently hide a Global command. → [custom-actions](custom-actions.md) | -| **Repositories / Repo Settings** | Per-repository: setup/archive/run scripts, **Custom Commands**, Global-command visibility, default base ref & directory, copy-files overrides, open-with app, custom title, icon & color, PR merge strategy, line-diff & PR-state fetching. Reached from the sidebar context menu → "Repo Settings". → [custom-actions](custom-actions.md), [repositories-and-worktrees](repositories-and-worktrees.md) | +| **Agents** | Agent Profiles: named launch presets for Claude Code/Codex (model, effort, execution mode, tab/split placement, extra arguments, opt-in dedicated home for a separate account) with a live launch preview. List order is the recommendation fallback. → [agent-profiles](agent-profiles.md) | +| **Repositories / Repo Settings** | Per-repository: setup/archive/run scripts, **Custom Commands**, Global-command visibility, **Default Agent Profile**, default base ref & directory, copy-files overrides, open-with app, custom title, icon & color, PR merge strategy, line-diff & PR-state fetching. Reached from the sidebar context menu → "Repo Settings". → [custom-actions](custom-actions.md), [repositories-and-worktrees](repositories-and-worktrees.md) | ## Where settings live on disk - **Global:** `~/.prowl/settings.json` -- **Global custom commands:** `~/.prowl/global.onevcat.json` +- **Global custom commands + agent profiles:** `~/.prowl/global.onevcat.json` - **Per-repo:** `~/.prowl/repo//prowl.json` -- **Per-repo custom commands:** `~/.prowl/repo//prowl.onevcat.json` +- **Per-repo custom commands + agent profile default/memory:** `~/.prowl/repo//prowl.onevcat.json` +- **Dedicated agent profile homes:** `~/.prowl/agent-profiles//` Legacy `~/.supacode` is migrated to `~/.prowl` on first launch.