Skip to content

feat(playbooks): show agent-led progress and run history - #249

Merged
BastiHu merged 5 commits into
codex/agent-led-pb-01-runtimefrom
codex/agent-led-pb-02-runs
Sep 24, 2026
Merged

BastiHu merged 5 commits into
codex/agent-led-pb-01-runtimefrom
codex/agent-led-pb-02-runs

Conversation

@BastiHu

@BastiHu BastiHu commented Sep 22, 2026 •

Copy link
Copy Markdown
Collaborator

What changed

Playbook progress is visible in the thread board and in a Playbook runs section on Fleet, with active/all filtering, pagination, owner-thread links, and environment status. /playbook expands through the ordinary composer send path.

Part 2 of 4 for #194. Base: codex/agent-led-pb-01-runtime.

Review fixes

  • Reuse the shared visible-refresh helper. Poll every 7.5 seconds only when the fetched page has an active run; otherwise refresh on focus or thread run changes. Pending reads, hidden tabs, disconnected environments, and unsupported environments do not poll.
  • Put the overview on the existing J5-owned Fleet page. Sidebar, command palette, and generated route tree now match the base branch.
  • Show one progress bar and tooltip per overview card; keep the detailed step strip in the thread. Prioritize active runs with issues, followed by other active runs and terminal history.
  • Restore the original composer text after a failed send, remove the unrelated pending-question sizing change, and preserve the upstream slash-command type signature with the appended exclusion.
  • Update contract 38 and its applicable fork ledger rows, and remove the obsolete migration sentence from the user guide. Sidebar and command-palette ledger additions are unnecessary after removing those changes.

Validation

79 focused tests passed across the shared refresh hook, Playbook presentation, composer logic, and composer submission. Web and client-runtime typechecks, formatting, diff checks, and the web build passed. Scoped lint completed with warnings only.

Web and desktop share the changed view. The shared ordering helper is available to mobile; this PR adds no native mobile UI. Authenticated environment transport and provider contracts are unchanged. Active-to-terminal transitions, hidden views, pending reads, and multiple refresh consumers have focused coverage.

UI evidence

Before/after screenshots and integrated browser verification remain pending explicit permission required by AGENTS.md. They are still required before merge.

Updated with GPT-6 in Codex.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XL 500-999 effective changed lines (test files excluded in mixed PRs). labels Sep 22, 2026
@BastiHu
BastiHu added this pull request to stack #253 September 22, 2026 18:13
@BastiHu
BastiHu force-pushed the codex/agent-led-pb-02-runs branch from 72a0dcd to 4ed3668 Compare September 23, 2026 15:14
@github-actions github-actions Bot added size:XXL 1,000+ effective changed lines (test files excluded in mixed PRs). and removed size:XL 500-999 effective changed lines (test files excluded in mixed PRs). labels Sep 23, 2026
@BastiHu
BastiHu force-pushed the codex/agent-led-pb-02-runs branch from 4ed3668 to ceb6526 Compare September 23, 2026 16:07
@github-actions github-actions Bot added size:XL 500-999 effective changed lines (test files excluded in mixed PRs). and removed size:XXL 1,000+ effective changed lines (test files excluded in mixed PRs). labels Sep 23, 2026
@BastiHu
BastiHu marked this pull request as ready for review September 23, 2026 16:07

@bryantderosier bryantderosier 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.

Review of the progress board and runs page. Inline comments cover the specific changes I want.

The main issue is polling cost. Every open thread polls every 2.5s whether or not it has ever run a playbook, and each poll re-parses YAML on the host. That needs to change before this ships. It matters most over remote and tunnel connections.

Also needed, but not attached to a specific line:

  • The before/after UI screenshots AGENTS.md asks for on UI changes. Please add them before this merges.
  • FORK.md ledger rows for contract 38 on ChatView.tsx, CommandPalette.tsx, ChatComposer.tsx, SidebarChrome.tsx, client-runtime/package.json, and docs/user/composer.md, plus a new row for composer-logic.ts. The case 38 prose covers these files; the ledger rows don't.
  • The SidebarChrome nested ternary gets re-indented (+7/-7) where inserting before : null would be a one-line append.

};
const sync = () => {
clearInterval(timer);
if (document.visibilityState === "visible") timer = setInterval(read, 2_500);

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.

2.5s is far hotter than anything else in J5 (inbox is 7.5s, squadrons 30s). Every poll goes through listForThread/listAll → progressRows → readDefinition, which means two realpath calls, a stat, a read, and a YAML parse and decode for up to 20 definitions on the host. One thread left open over a tunnel is about 24 requests a minute, forever.

Please poll only while the fetched runs include an active run (refresh on focus or on thread turn events otherwise), or refresh when a playbook change bumps the J5 revision counter.

Separately, this hook is nearly a line-for-line copy of createVisibleRefreshHook in apps/web/src/j5/useVisibleRefresh.ts. Please extend that helper with a per-instance/enabled variant and delete this copy.

}),
);
const [selectedRunId, setSelectedRunId] = useState<string | null>(null);
usePlaybookRunsRefresh(

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.

This mounts for every server thread and stays enabled even when the thread has zero runs (the "keeps polling an empty supported thread" test asserts it). Please gate it on the thread having an active run, per the comment on the hook.

import { usePlaybookRunsRefresh } from "./usePlaybookRunsRefresh";
import { PlaybookStepStrip } from "./PlaybookStepStrip";

function PlaybookRunCard({

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.

This page renders up to 100 PlaybookRunCards, each with a PlaybookStepStrip of up to 100 tabbable tooltip triggers. That's around 10k focusable nodes, all re-rendered on every poll because nothing is memoized. Please memo the card, or collapse the strip to a single progress bar with one tooltip on the overview.

const unsupported = query.data?.supported === false;
usePlaybookRunsRefresh(query.refresh, connected && !unsupported && !query.isPending);
const data = query.data?.supported ? query.data : null;
// ponytail: issue priority is page-local; global triage needs ordering before server pagination.

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.

Nit: same as the ponytail: comment in #248. It records a limitation instead of describing usage. Please remove or rewrite it.

export function sortPlaybookRuns(runs: ReadonlyArray<PlaybookProgress>) {
return runs.toSorted(
(a, b) =>
Number(!!b.issue) - Number(!!a.issue) ||

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.

This ranks any run with an issue first, including completed and cancelled ones. Combined with the #248 behavior where terminal runs get an issue once their YAML is gone, a deleted playbook pushes all its finished runs above healthy active runs. Please rank only active runs with issues first, and update the test that currently asserts the opposite.

@@ -5508,6 +5522,7 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps)
skills={selectedProviderSkills}
containerClassName={cn(isComposerResting && "min-w-0 flex-1")}
className={cn(
activePendingProgress && "min-h-10 max-h-28",

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.

activePendingProgress is the pending user-question state, not playbooks. This changes composer sizing for every pending-question prompt, and FORK case 38 doesn't mention it. Please drop it from this PR, or split it into its own fix with a FORK note.

Comment thread apps/web/src/composer-logic.ts Outdated
export function parseStandaloneComposerSlashCommand(
text: string,
): Exclude<ComposerSlashCommand, "model"> | null {
export function parseStandaloneComposerSlashCommand(text: string): "plan" | "default" | null {

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.

This rewrites the upstream signature (Exclude<ComposerSlashCommand, "model"> → literal "plan" | "default") rather than appending. Please use Exclude<ComposerSlashCommand, "model" | "playbook">, which is a one-token append and matches the case 38 description.

Comment thread apps/web/src/components/ChatView.tsx Outdated
@@ -6758,7 +6760,7 @@ export default function ChatView(props: ChatViewProps) {
},
]
: sendContextPreviewAnnotations;
const promptForSend = promptRef.current;
const promptForSend = expandPlaybookPrompt(promptRef.current);

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.

promptForSend is now the expanded text, and the failed-send retry path (~7358-7373) restores it into the composer. After a failed /playbook foo send, the composer shows "Start playbook foo" instead of what I typed. Please restore the original promptRef.current value.

Comment thread docs/user/playbooks.md Outdated
to follow agent-led runs across your connected environments. The overview shows
each run's owner thread, agent activity, and current step. Select a run to open
its thread, or choose **All** to include completed and cancelled runs. This
overview contains runs from the agent-led model; earlier playbook history is not

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.

There was never an earlier playbook engine or history on j5/main, so telling users "earlier playbook history is not imported" describes a migration that never applied to them. Please delete the sentence.

@@ -260,6 +268,11 @@ export const SidebarUtilityMenu = memo(function SidebarUtilityMenu() {
label="Usage"
onClick={handleUsageClick}
/>
<SidebarUtilityItem
icon={<BookOpenIcon />}
label="Playbooks"

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.

My standing fork rule is to mount new UI inside existing J5-owned surfaces rather than adding nav entries, routes, or search entries to upstream files. This PR adds a top-level /playbooks route, this sidebar item, and a CommandPalette action. Please move the runs overview into a section on the J5-owned Fleet page, which gets the upstream nav and route edits down to zero or one. If a standalone page is really the right call, argue for it in the PR body so we can sign off explicitly, like we did for the persona settings section.

@coderabbitai

coderabbitai Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

  • Run on-demand review

This review includes 29 billable files and costs up to $7.25.

Or wait 59 minutes for your next included review.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Repository: Jacksondr5/j5code/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: ec872115-89fd-42d9-8b45-d08b86d928aa

📥 Commits

Reviewing files that changed from the base of the PR and between 1081580 and 16ca431.

📒 Files selected for processing (29)
  • .github/workflows/j5-ci.yml
  • FORK.md
  • apps/server/src/auth/RpcAuthorization.ts
  • apps/server/src/j5/playbooks/PlaybookStore.test.ts
  • apps/server/src/j5/playbooks/PlaybookStore.ts
  • apps/server/src/j5/playbooks/playbookRpc.ts
  • apps/server/src/ws.ts
  • apps/web/src/components/ChatView.tsx
  • apps/web/src/components/chat/ChatComposer.tsx
  • apps/web/src/composer-logic.ts
  • apps/web/src/j5/fleet/FleetPage.tsx
  • apps/web/src/j5/playbooks/PlaybookBoard.tsx
  • apps/web/src/j5/playbooks/PlaybookRefresh.test.tsx
  • apps/web/src/j5/playbooks/PlaybookRunsSection.tsx
  • apps/web/src/j5/playbooks/PlaybookStepStrip.tsx
  • apps/web/src/j5/useVisibleRefresh.test.ts
  • apps/web/src/j5/useVisibleRefresh.ts
  • docs/user/composer.md
  • docs/user/playbooks.md
  • packages/client-runtime/package.json
  • packages/client-runtime/src/j5/http.test.ts
  • packages/client-runtime/src/j5/http.ts
  • packages/client-runtime/src/j5/playbooks.test.ts
  • packages/client-runtime/src/j5/playbooks.ts
  • packages/client-runtime/src/j5/state.test.ts
  • packages/client-runtime/src/j5/state.ts
  • packages/client-runtime/src/rpc/client.ts
  • packages/contracts/src/j5/playbook.ts
  • packages/contracts/src/rpc.ts

Comment @coderabbitai help to get the list of available commands.

@BastiHu
BastiHu force-pushed the codex/agent-led-pb-02-runs branch from c63c37c to a7194b6 Compare September 24, 2026 18:04
@BastiHu
BastiHu force-pushed the codex/agent-led-pb-02-runs branch from a7194b6 to 16ca431 Compare September 24, 2026 19:10
@BastiHu
BastiHu merged commit 2a2fb48 into j5/main Sep 24, 2026
41 of 49 checks passed
@BastiHu
BastiHu deleted the codex/agent-led-pb-02-runs branch September 24, 2026 19:20
Jacksondr5 added a commit that referenced this pull request Sep 24, 2026
Carried from j5/main 2a2fb48 onto the upstream V2 candidate.

Conflict: ws.ts keeps the candidate's single skills import beside the playbook imports; ChatView.tsx keeps upstream's direct-annotation reference in the prompt, expands /playbook on top of it, and restores the typed draft (not the expansion) on send failure via draftTextForRestore, dropping the element-contexts ref upstream removed; composer-logic.ts keeps upstream's trigger kinds, shortcut import and submission intents and appends playbook to the slash commands; docs/user/composer.md stays upstream (docs/user/playbooks.md already documents /playbook); FORK.md updates case 45's text and its ledger rows (45).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Jacksondr5 added a commit that referenced this pull request Sep 25, 2026
Joins fork head 2cf4ad7 (j5/main, including #247, #241, #244, #242,
#214, #215, #216, #248, #249, #250, #251) with the reviewed candidate
(j5/upstream-sync-20260924-candidate), which descends from frozen upstream
67a2be0. Upstream force-rewrote history,
so per FORK.md's rewrite runbook the candidate was built from the upstream
tree with pin 62aef85 as the content base, then carried each j5/main
PR since 8f56083 onto it and adapted it to upstream V2. This merge's
tree equals the candidate tree exactly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL 500-999 effective changed lines (test files excluded in mixed PRs). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants