Skip to content

Show working tips under the status line and add /upgrade - #585

Merged
igorcosta merged 15 commits into
mainfrom
working-tips
Sep 11, 2026
Merged

Show working tips under the status line and add /upgrade#585
igorcosta merged 15 commits into
mainfrom
working-tips

Conversation

@igorcosta

Copy link
Copy Markdown
Contributor

Summary

While the agent works, a muted tip line now rotates under the status line, and hitting an Autohand quota pins an upgrade hint there. A new /upgrade command opens the console checkout for the next plan.

  • Tips come from one JSON file. src/ui/tool_tips.json replaces the hardcoded list in src/ui/tips.ts. Plain entries are shown verbatim; skill and command entries are templates expanded against the user's installed skills and the slash-command registry, so "Try $my-skill" and "Type /goal to…" tips appear automatically. Templates re-expand whenever the shuffle bag refills, so skills installed mid-session show up. The pool also gains tips on $extension-builder, /goal, ?, /upgrade, and how to ask autohand to delegate to sub-agents.
  • Tip row in the Ink UI. TipLine renders directly under StatusLine, rotating every 10 s from the same ticker that refreshes elapsed time. It rides on a new tip state field, so the retry countdown (which rewrites status) cannot clobber it. A rotating tip clears when the turn ends; an upgrade hint survives until the next turn starts. The legacy readline spinner keeps its existing ⎿ Tip: line and now reads the same JSON.
  • Upgrade hint on quota. When an Autohand rate_limited error ends the turn, the row pins "You've reached your Free plan limit. Run /upgrade to move to Pro." Team, enterprise and unknown plans get "Run /upgrade to review your plan." Throughput limits are retried and never pin the hint.
  • /upgrade. Reads the entitlement tier, walks the ladder free → pro → max → team, and opens https://console.autohand.ai/?upgrade=<next>&source=cli. Team and enterprise open the billing page. Signed-out users are told to /login; RPC/ACP clients receive the link as text instead of a browser launch. Ladder, URL and hint copy live together in src/billing/planSummary.ts.
  • AUTOHAND_NO_BROWSER=1 makes the shared browser opener print the URL instead of launching anything. Tuistory sets it, so terminal tests can exercise /upgrade end to end.
  • Docs. /upgrade row in the slash-command table (English plus the eight locales that carry the table) and one sentence on the tip line next to activityVerbs.

No new config keys, no new dependencies.

Console counterpart

The console PR teaches ?upgrade=<plan>&source=<origin> to land in checkout and replaces "Manage Billing" on the overview with "Upgrade your plan" for accounts without a subscription. The source value reaches the checkout request but is not stored until the API adds it to checkout metadata.

Test plan

  • tests/ui/tips.spec.ts, tests/ui/activityIndicator.spec.ts — JSON pool, template expansion, lazy refill, fallback
  • tests/ui/ink/TipLine.test.tsx, tests/ui/ink/AgentUI.tipLine.test.tsx, tests/ui/ink/InkRenderer.tip.test.ts — placement, truncation, clearing rules
  • tests/core/agent/AgentUIRuntime.tips.test.ts — first tip at start, rotation at 10 s
  • tests/core/agent/AgentRateLimitUpgradeHint.test.ts — hint pinned only for Autohand rate limits
  • tests/billing/planSummary.test.ts — ladder, URL, hint copy
  • tests/commands/upgrade.test.ts, tests/commands/openBrowser.test.ts, tests/slashCommands.spec.ts
  • Tuistory: tip row under esc to cancel while working and gone when the reply lands; /upgrade prints the Max link for a Pro mock account
  • bun run lint, bun run typecheck
  • Full bun run proof on CI

…line in iTerm2

The composer already understood every encoded form of a shifted Enter, and Ink parses the kitty CSI u form natively, but nothing in the Ink runtime ever asked the terminal to encode modified keys: the only code that did, ProcessTerminal, has no callers. Terminals such as kitty and Ghostty send CSI u for Shift+Enter on their own, which is why the shortcut worked there and in the Tuistory harness, while iTerm2 sends a plain carriage return and Shift+Enter submitted the message.

The Ink renderer now pushes the kitty keyboard protocol's disambiguate flag when it starts and pops it when it stops. Only keys without a legacy encoding change shape, plain keys keep their bytes, and terminals without the protocol ignore the request. Ctrl+C, Esc and Shift+Tab were exercised in their encoded forms through the built CLI: they clear, cancel and cycle modes as before, and the flag is popped on exit so the shell is left in legacy mode.
Add ui.keybindingProfile to the config reference and describe the profile
table, the Claude Code and Codex remap files Autohand honours, the terminal
requirements for each newline chord, and the memories/sessions/skills import
offered during setup. The same section is added to all sixteen translated
references.
…mplates

Tips shown while the agent works now come from one JSON file instead of a
hardcoded list. Entries can be plain text or templates that expand against the
user's installed skills and the slash-command registry, so the pool grows with
what each user has installed. The activity indicator can rotate the tip on its
own without changing the verb.
While the agent works, a muted tip row now renders directly under the status
line and rotates every ten seconds from the shared tips bag. The tip rides on
its own state field so the retry countdown, which rewrites the status text,
cannot clobber it. A rotating tip clears when the turn ends; an upgrade hint
survives until the next turn starts.
… the turn

The plan ladder, the console upgrade link and the hint copy live together in
planSummary so the slash command and the quota path share one source of truth.
Also adds sub-agent tips explaining how to ask autohand to delegate work.
The command reads the signed-in entitlement, picks the next self-serve tier,
and opens the console deep link with the CLI as the source. Managed plans go
to the billing page, signed-out users are told to log in first, and
non-interactive clients receive the link as text instead of a browser launch.
…story suite

Adds an AUTOHAND_NO_BROWSER guard so terminal tests and headless sessions get
the URL printed instead of a browser launch, and uses it to exercise /upgrade
end to end against the mock auth server.
@igorcosta
igorcosta merged commit 5dcf8dd into main Sep 11, 2026
8 of 10 checks passed
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.

1 participant