Skip to content

Add Pi activity tracking plugin - #3594

Draft
adity982 wants to merge 1 commit into
max-sixty:mainfrom
adity982:agent/add-pi-activity-plugin
Draft

Add Pi activity tracking plugin#3594
adity982 wants to merge 1 commit into
max-sixty:mainfrom
adity982:agent/add-pi-activity-plugin

Conversation

@adity982

Copy link
Copy Markdown

Summary

  • add wt config plugins pi install|uninstall
  • install a profile-aware Pi / oh-my-pi hook with atomic writes
  • map Pi lifecycle events to Worktrunk working, waiting, and cleared activity markers
  • honor Pi's agent-directory, config-directory, and profile environment variables
  • cover profile paths, explicit directory overrides, uninstall behavior, and CLI output snapshots

Validation

  • cargo fmt --check — passed
  • cargo test --test integration test_pi_ -- --nocapture — 3 passed
  • the same snapshot tests passed again without INSTA_UPDATE
  • cargo clippy --bin wt -- -D warnings — passed

Closes #3571

Signed-off-by: Aditya Datta <crazyme07071996@gmail.com>

@worktrunk-bot worktrunk-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewing as a draft — flagging anything that looks worth a quick fix. Mark ready for a full review.

Nice work — the pi.rs handler and the dev/pi-plugin.ts hook closely mirror the existing opencode plugin, which is the right pattern to follow. A few things I'd tighten before this goes green:

1. The parent wt config plugins help + snapshot are out of sync. Adding the Pi variant to ConfigPluginsCommand changes the wt config plugins --help command list, but tests/snapshots/…__help_config_plugins.snap still enumerates only claude/codex/opencode — so test_help_config_plugins (and test_docs_are_in_sync) will fail in CI. The snapshots regenerate via the pre-merge hook (cargo run -- hook pre-merge --yes, or cargo insta test --accept -- --test integration "test_help").

That regen won't fix the authored prose, though: the Plugins command's after_long_help in src/cli/config.rs (the ## Supported tools list and ## Examples, near the Install and manage Worktrunk plugins for AI coding tools. block) still omits Pi. That one's a hand edit — add:

- **pi** — Pi / oh-my-pi plugin (activity tracking)

to the Supported tools list, and $ wt config plugins pi install to the Examples block.

2. PI_CODING_AGENT_DIR precedence when a profile is active. In pi_agent_dir(), PI_CODING_AGENT_DIR is honored only when active_profile().is_none() — an active $OMP_PROFILE/$PI_PROFILE silently overrides an explicit $PI_CODING_AGENT_DIR. I can't verify Pi's own resolution order from CI, but "explicit dir override loses to profile" reads backwards from the usual "most-explicit wins" expectation. Worth confirming against Pi's actual behavior (and a one-line comment in the code recording why, since it's non-obvious).

3. Hook doesn't tolerate wt failing. The opencode hook guards every call with || true so a wt failure (not in a managed repo, wt not on PATH) never propagates into the host. The Pi hook does a bare await pi.exec("wt", …). If pi.exec rejects on a non-zero exit, an agent_start in a non-worktrunk directory would surface an error into the Pi session. Does pi.exec reject on non-zero exit, or is it fire-and-forget? If it rejects, wrap the body in a try/catch (or the Pi equivalent of || true).

4. Test coverage is lighter than opencode's. The opencode suite covers the already-installed, prompt-declined, and uninstall-not-installed branches; the Pi tests cover only the install/uninstall happy paths (and only OMP_PROFILE, not PI_PROFILE or PI_CONFIG_DIR). Those extra branches are exactly what codecov/patch tends to flag — worth mirroring the opencode tests before marking ready.

Minor: handle_pi_uninstall uses std::fs::remove_file — identical to the accepted opencode uninstall (removes only the tool's own hook at a fixed path), so low-risk, but flagging it since it's on worktrunk's data-safety radar. @max-sixty for eventual eyes on the deletion path.

@adity982

Copy link
Copy Markdown
Author

Thanks for the draft review. The parent help/snapshots, Pi directory precedence, pi.exec failure semantics, and the missing install/uninstall/profile branches all need to be checked before this is ready. I will keep the PR in draft while those items are addressed.

max-sixty pushed a commit that referenced this pull request Aug 18, 2026
…thout a plugin (#3848)

## Problem

#3847 asks for a documented "generic agent" integration: worktrunk ships
plugins for Claude Code, Codex, OpenCode, and Gemini, so users of any
other agent CLI have no documented way to get the 🤖/💬 activity markers
in `wt list`. The mechanism is already agent-agnostic — the plugins just
call `wt config state marker` on their host's session events — but the
docs only present manual markers as a personal-workflow convenience, so
users reverse-engineer the integration from that section. #3571 (pi /
oh-my-pi) is the same gap from a different host.

## Solution

A new **Agent CLIs without a plugin** subsection under Activity tracking
in
[`docs/content/claude-code.md`](https://github.com/max-sixty/worktrunk/blob/main/docs/content/claude-code.md),
stating the three-call contract (set 🤖 on session start, set 💬 on turn
end, clear on session end) plus the three things that actually bite:

- the command resolves the branch from its working directory, so the
hook must run inside the worktree (`--branch` where the host pins cwd
elsewhere);
- `marker set` exits non-zero outside a repository, and hosts differ on
what a non-zero hook does — guard it;
- pair every set with a clear, and expect a stale marker if the process
is killed first.

Docs-only. The skill and plugin-skill mirrors are regenerated by the
sync test.

## Testing

`cargo test --test integration test_docs_are_in_sync` passes (it
regenerated both mirrors, committed here).

Each claim in the section was verified against a scratch repo with a
linked worktree rather than taken from the existing prose:

<details><summary>Verification</summary>

```
$ wt config state marker set "🤖"          # from /tmp/mrepo.feature-x
✓ Set marker for feature-x to 🤖
$ git config --get worktrunk.state.feature-x.marker
{"marker":"🤖","set_at":1787044121}
```

- Works from a subdirectory of the worktree (branch still resolves to
`feature-x`).
- Outside a repository: `✗ git rev-parse --git-common-dir failed (exit
128)`, exit code 1 — the basis for the "guard it" bullet.
- `marker clear` with no marker set exits 0 (`○ No marker set for
main`), so a session-end hook is safe to run unconditionally.
- `wt list` renders the marker in the Status column as documented.

</details>

## Scope

Deliberately host-agnostic. The reporter's second ask — a native `wt
config plugins copilot` target — is a maintainer call and isn't
attempted here: GitHub Copilot CLI does expose the needed events
(`sessionStart` / `agentStop` / `sessionEnd`, user-level hooks under
`~/.copilot/hooks/`, per the [hooks
reference](https://docs.github.com/en/copilot/reference/hooks-reference)),
but nothing in CI can drive a Copilot session to verify a generated hook
file end to end. A concrete Copilot config is posted on the issue for
the reporter to confirm; if it works, adding it here as a worked example
is a natural follow-up. #3594 (native `pi` target) is the adjacent
in-flight work and doesn't overlap with this.

---
Refs #3847 — automated triage

---------

Co-authored-by: worktrunk-bot <254187624+worktrunk-bot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] Support Pi / Oh My Pi coding agent

2 participants