feat(status): make an unusable raptor obvious, and give AI hosts runnable setup steps - #73
Conversation
#68 added a `raptor:` line to `praxis status`, which fixed the silent case. But when raptor is absent that line reads only "not installed" — it names no consequence and no next step, and `logged in: yes` prints directly beneath it, so the output as a whole still scans as healthy. Nothing in this repo told a user where to get raptor either. That matters because raptor is not optional. Facets projects, resources, environments and releases all go through it, and 450 of the shell commands inside the skills praxis installs are `raptor ...`. A user who stops after `praxis login` has a working praxis and cannot do the work. Three changes: - `raptor: not installed` now points at the releases page. raptor ships no Homebrew formula or cask today (only Casks/praxis.rb exists in Facets-cloud/homebrew-tap), so the releases page is the install path we can honestly name. - A closing `⚠ setup incomplete` notice prints last, after the skills and agents listings, so an unfinished setup isn't buried above them. It distinguishes not-installed (install + login) from installed-but- not-logged-in (login only) — telling someone who already has raptor to go install it sends them down the wrong path, so that case is pinned by its own test. - `setup_complete` in the JSON, so an AI host can branch on one field instead of re-deriving usability from installed/found/logged_in. The skills' raptor preflight currently dead-ends at "ask the user to install it"; it can now point at `praxis status` and follow it. Behavior change: the not-installed string is no longer exactly "not installed", so TestRaptorStatusLine's case was updated. Part 1 of #72. Whether `praxis login` should offer to install raptor, and whether raptor should get a Homebrew cask, is still open there. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LpVxm5k6cuVWnz5pKsFUdT
WalkthroughChangesRaptor setup flow
Sequence Diagram(s)sequenceDiagram
participant User
participant Status
participant Raptor
participant PraxisMetaSkill
User->>Status: Run status
Status->>Raptor: Check installation and profile state
Raptor-->>Status: Return readiness and platform details
Status-->>User: Show setup_complete and installation guidance
User->>PraxisMetaSkill: Start Praxis workflow
PraxisMetaSkill->>Status: Read setup_complete
PraxisMetaSkill->>Raptor: Install or run login when required
Possibly related issues
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Comment |
Extends #68 rather than sitting beside it. That PR taught hosts to act on the `raptor` block in `praxis status --json`, but its cases all assume raptor is already present: `pinned`, `matches_praxis_url`, `found: false`. The absent case had no bullet, and `found: false` told the host to "ask the user to run raptor login" — which dead-ended, since nothing in this repo said how to install raptor in the first place. - `raptor.install_hint` (inside #68's block, not a new top-level key, so the "act on the raptor block" contract keeps holding). Carries the asset URL and shell commands already resolved for this machine's OS/arch — praxis is the only party that knows those, skill text can't. Installs to ~/.local/bin: `sudo` prompts for a password and would hang a non-interactive host. Omitted once raptor is installed. Platforms raptor publishes no build for get `docs` and no fabricated URL. - Meta-skill: new `installed: false` bullet in #68's own list, in its style; `found: false` amended from "ask the user" to RUN `raptor login` for them — the same treatment `praxis login` already gets in this file (browser opens, user completes it, host waits for exit 0). - Preflight section updated to match; it still said "don't install it yourself", which now contradicts the bullets below it. Credential guardrails are unchanged and pinned by test: never ask for a token in chat, never write ~/.facets/credentials. Running a browser login is not the same as handling the secret. Asset names verified against the real v0.1.91 release; the generated darwin-arm64 URL was fetched and returns 200. Part 1 of #72. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LpVxm5k6cuVWnz5pKsFUdT
|
@anujhydrabadi — this builds directly on your #68, so I'd value your eyes on it. What I did to your code, so it's not a surprise in the diff:
Things worth your scrutiny:
Testing: full suite green, every new test verified failing before the change, binary exercised through a pty in all three states, and the generated download URL actually fetched (200). |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@cmd/status.go`:
- Around line 91-95: Add table-driven command-level tests that execute the
status command and assert the public state["setup_complete"] value for
logged-out, raptor-missing, raptor-unresolved, and fully ready states. Exercise
the existing status flow and its raptorReady integration rather than testing
only the helper, while preserving the expected false/true contract for each
failure and success path.
- Around line 205-210: Update the install hint construction in the status flow
so installation remains usable when ~/.local/bin is not already on PATH: return
an immediate executable path or host-scoped PATH action, and have subsequent
raptor command resolution prefer that path until raptor resolves normally from
PATH. Ensure the installed-state check also recognizes this fallback so praxis
status reports the binary as installed.
- Around line 203-209: Update the release hint generation around the url and
hint["commands"] assignments to use an immutable release version instead of the
mutable releases/latest endpoint, then download and verify the official signed
checksum or provenance record before running chmod +x on the artifact. Preserve
the existing installation directory and command flow while ensuring execution is
only enabled after successful verification.
In `@internal/skillinstall/dummy.go`:
- Around line 250-252: Update the initial-session flow in the setup protocol to
use the top-level setup_complete value as its gate instead of branching only on
logged_in. When setup_complete is false, process the raptor block according to
the existing instructions before continuing; preserve the completed setup path
when it is true.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 0e41e48e-dbc6-4a2c-9272-47ab7b35d147
📒 Files selected for processing (4)
cmd/status.gocmd/status_test.gointernal/skillinstall/dummy.gointernal/skillinstall/dummy_test.go
| // One field an AI host can branch on instead of re-deriving "is this | ||
| // machine actually usable?" from installed/found/logged_in. The skills' | ||
| // raptor preflight reads this. | ||
| state["setup_complete"] = loggedIn && raptorReady(raptorSt) | ||
|
|
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Test the public setup_complete contract.
The added tests cover helper output. They do not execute status and assert setup_complete. Add table-driven command-level cases for logged-out, raptor-missing, raptor-unresolved, and ready states.
As per coding guidelines, tests must cover exported APIs and main failure paths.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@cmd/status.go` around lines 91 - 95, Add table-driven command-level tests
that execute the status command and assert the public state["setup_complete"]
value for logged-out, raptor-missing, raptor-unresolved, and fully ready states.
Exercise the existing status flow and its raptorReady integration rather than
testing only the helper, while preserving the expected false/true contract for
each failure and success path.
Source: Coding guidelines
| url := "https://github.com/Facets-cloud/raptor-releases/releases/latest/download/" + asset | ||
| hint["url"] = url | ||
| hint["commands"] = []string{ | ||
| "mkdir -p ~/.local/bin", | ||
| "curl -fsSL " + url + " -o ~/.local/bin/raptor", | ||
| "chmod +x ~/.local/bin/raptor", | ||
| } |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect whether the official release publishes checksum or signature assets.
curl -fsSL \
https://api.github.com/repos/Facets-cloud/raptor-releases/releases/latest |
jq -r '.tag_name, (.assets[]?.name)'Repository: Facets-cloud/praxis-cli
Length of output: 212
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- cmd/status.go: relevant implementation ---'
sed -n '150,225p' cmd/status.go
printf '%s\n' '--- release-install hint consumers and related paths ---'
rg -n -C 3 'latest/download|chmod \+x|hint\["commands"\]|raptor login|raptor-releases' cmd internal README.md docs 2>/dev/null || true
printf '%s\n' '--- status command structure ---'
rg -n -C 4 'func .*Status|statusCmd|agentinstall|Raptor' cmd/status.go internal/agentinstallRepository: Facets-cloud/praxis-cli
Length of output: 25159
Other (CWE-494): Download of Code Without Integrity Check
Reachability: External
Verify the release artifact before enabling it.
The generated commands download a mutable releases/latest asset and mark it executable without integrity verification. Use an immutable release version and verify an official signed checksum or provenance record before chmod +x.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@cmd/status.go` around lines 203 - 209, Update the release hint generation
around the url and hint["commands"] assignments to use an immutable release
version instead of the mutable releases/latest endpoint, then download and
verify the official signed checksum or provenance record before running chmod +x
on the artifact. Preserve the existing installation directory and command flow
while ensuring execution is only enabled after successful verification.
| hint["commands"] = []string{ | ||
| "mkdir -p ~/.local/bin", | ||
| "curl -fsSL " + url + " -o ~/.local/bin/raptor", | ||
| "chmod +x ~/.local/bin/raptor", | ||
| } | ||
| hint["note"] = "installs to ~/.local/bin (no sudo). If that isn't on PATH, add it." |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Make the installed binary usable without a pre-existing PATH entry.
When ~/.local/bin is absent from PATH, the next raptor login command cannot resolve raptor. A later praxis status also continues to report installed: false. The note does not make the host environment usable.
Return an immediate executable path or a host-scoped PATH action in install_hint, and use it until raptor resolves from PATH.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@cmd/status.go` around lines 205 - 210, Update the install hint construction
in the status flow so installation remains usable when ~/.local/bin is not
already on PATH: return an immediate executable path or host-scoped PATH action,
and have subsequent raptor command resolution prefer that path until raptor
resolves normally from PATH. Ensure the installed-state check also recognizes
this fallback so praxis status reports the binary as installed.
| - ` + "`setup_complete`" + ` (top level, not inside the raptor block) — true | ||
| only when praxis is logged in AND raptor is installed and resolved. | ||
| Check it first; the two bullets above say what to do when it's false. |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Make setup_complete the initial setup gate.
The initial protocol at Lines 39-72 says that praxis login is the entire setup and tells the host to branch only on logged_in. If Praxis is logged in but raptor is absent, the host can treat setup as complete and skip these later instructions.
Update the initial-session flow to branch on setup_complete. If it is false, process the raptor block before continuing.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@internal/skillinstall/dummy.go` around lines 250 - 252, Update the
initial-session flow in the setup protocol to use the top-level setup_complete
value as its gate instead of branching only on logged_in. When setup_complete is
false, process the raptor block according to the existing instructions before
continuing; preserve the completed setup path when it is true.
… hatch
The previous commit restated raptor's install steps inside praxis, with
~/.local/bin swapped in for the documented `sudo mv … /usr/local/bin`.
Two problems with that:
- It forks instructions raptor owns. That README already drifts from
reality (it documents Windows binaries the releases don't publish),
and a second copy in praxis would drift further.
- The ~/.local/bin substitution was mine, not sourced from any doc, and
the output presented it as if it were the official path.
So `docs` now points at the README (#installation) and is the primary
answer, and the no-sudo path is demoted to an explicitly-labelled hatch:
install_hint.docs raptor's own instructions — prefer these
install_hint.asset_url exact build for this OS/arch
install_hint.no_sudo_commands hatch for hosts that can't answer a sudo
password prompt (it would hang, not fail)
install_hint.note says the hatch deviates, and that
~/.local/bin must be on PATH
The meta-skill bullet mirrors that order: docs first, hatch only when the
user can't use them or asks the host to do it.
Unpublished platforms get docs and nothing else — no fabricated asset URL,
and no hatch we can't stand behind.
Both URLs verified reachable (200). Asset names verified against v0.1.91.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LpVxm5k6cuVWnz5pKsFUdT
Part 1 of #72. Builds on two earlier PRs — @anshulsao's #63 and @anujhydrabadi's #68 — extending their structures rather than adding parallel ones.
Where the two left off
#63 (freshness engine, @anshulsao) already tracks whether raptor is on PATH. It computes
installedincheckTool— but when raptor is absent,checkableis false, the check short-circuits, and the flag is never rendered for a human:#68 (raptor cross-check, @anujhydrabadi) added the
raptorblock and taught AI hosts to act on it. Its cases all assume raptor is present and possibly mis-aimed:pinned,matches_praxis_url,found: false.The gap sits between them: raptor absent had no bullet and no visible output, and
found: falsesaid "ask the user to runraptor login" while the preflight said "ask the user to install it; don't install it yourself" — with no install instructions anywhere in this repo.Not a corner case: raptor is where the control plane lives, and 450 of the shell commands inside the skills praxis installs are
raptor ....1. Human output says setup is unfinished
Before / after, raptor absent:
The notice prints last, after the skills/agents listings, so it isn't buried above 148 lines. Installed-but-logged-out gets a different notice that does not send the user back to the install page. Fully set up: silent.
2.
raptor.install_hint— inside #68's blockNested in the existing block rather than a new top-level key, so #68's "act on the raptor block" contract keeps holding:
docsis the primary answer. raptor owns its install steps; praxis must not fork them. That README already drifts from reality — it documents Windows binaries the releases don't publish — and a second copy here would drift further.no_sudo_commandsis an explicitly-labelled hatch, and it deviates from the README on purpose. raptor's documented steps end insudo mv … /usr/local/bin.sudoprompts for a password, which a non-interactive AI host cannot answer — it would hang rather than fail. The hatch installs to~/.local/bininstead. That is a deviation, thenotesays so, and~/.local/binis not on every PATH.praxis resolves the asset because it is the only party that knows this machine's OS/arch — skill text can't. Omitted once raptor is installed. Platforms with no published build get
docsonly: no fabricated URL, and no hatch we can't stand behind.3.
setup_complete(top level)One field to branch on instead of re-deriving usability from
installed/found/logged_in.4. Meta-skill: two bullets added to #68's list
In @anujhydrabadi's style, in his section:
installed: false— point atdocsfirst; useno_sudo_commandsonly if the user can't run those or asks the host to do it.found: false— changed from "ask the user to runraptor login" to RUN it for them, exactly as this file already treatspraxis login(browser opens, user completes sign-in, host waits for exit 0).The preflight section was updated to match — it still said "don't install it yourself", which would have contradicted the bullets below it.
@anujhydrabadi — flagging that I changed the wording of your
found: falsebullet on purpose. Happy to revert if you'd rather keep it ask-only.Guardrails unchanged
Installing a binary and opening a browser login is not the same as handling a secret. Still forbidden, and now pinned by test: never ask for a token in chat, never write
~/.facets/credentials.Behavior change
The not-installed string is no longer exactly
not installed, soTestRaptorStatusLine's case was updated. Intended, not incidental.Testing
go build ./...,go vet ./...,gofmt -l .cleango test ./...green--json) — output above is real, not hand-writtenOpen question for review
raptor upgradeself-replaces the binary. I have not verified it handles living in~/.local/binrather than/usr/local/bin. If it assumes the latter, the hatch could break upgrades. @anshulsao's machine runs raptor from~/.local/bintoday and upgrades work, but that's one data point.Still open in #72
Whether
praxis loginshould offer to install raptor, and whether raptor should get a Homebrew cask. The cask is likely the better root fix — it would make this whole hint one line. Deliberately out of scope here.🤖 Generated with Claude Code
https://claude.ai/code/session_01LpVxm5k6cuVWnz5pKsFUdT
Summary by CodeRabbit
New Features
Improvements