Skip to content

feat(status): make an unusable raptor obvious, and give AI hosts runnable setup steps - #73

Merged
anujhydrabadi merged 3 commits into
mainfrom
fix/status-shows-raptor
Aug 5, 2026
Merged

feat(status): make an unusable raptor obvious, and give AI hosts runnable setup steps#73
anujhydrabadi merged 3 commits into
mainfrom
fix/status-shows-raptor

Conversation

@anshulsao

@anshulsao anshulsao commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

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 installed in checkTool — but when raptor is absent, checkable is false, the check short-circuits, and the flag is never rendered for a human:

cur, installed, checkable := spec.current()
f := Freshness{Tool: spec.Name, Installed: installed, Current: cur}
if os.Getenv("PRAXIS_NO_UPDATE_CHECK") != "" || !checkable {
    return f          // raptor absent exits here
}

#68 (raptor cross-check, @anujhydrabadi) added the raptor block 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: false said "ask the user to run raptor 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:

raptor:     not installed
logged in:  yes (anshul@facets.cloud)
raptor:     not installed — get it at https://github.com/Facets-cloud/raptor-releases#installation
logged in:  yes (anshul@facets.cloud)
skills:     148 installed
agents:     0 installed

⚠ setup incomplete: raptor is not installed.
  Facets projects, resources and releases all run through raptor.
  Install: https://github.com/Facets-cloud/raptor-releases#installation
  Then:    raptor login

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 block

Nested in the existing block rather than a new top-level key, so #68's "act on the raptor block" contract keeps holding:

"install_hint": {
  "docs": "https://github.com/Facets-cloud/raptor-releases#installation",
  "asset_url": ".../releases/latest/download/raptor-darwin-arm64",
  "no_sudo_commands": [
    "mkdir -p ~/.local/bin",
    "curl -fsSL .../raptor-darwin-arm64 -o ~/.local/bin/raptor",
    "chmod +x ~/.local/bin/raptor"
  ],
  "note": "Prefer docs — raptor's own steps install to /usr/local/bin via sudo. no_sudo_commands is an escape hatch for non-interactive hosts that can't answer a sudo password prompt; it installs to ~/.local/bin, which must be on PATH."
}

docs is 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_commands is an explicitly-labelled hatch, and it deviates from the README on purpose. raptor's documented steps end in sudo mv … /usr/local/bin. sudo prompts for a password, which a non-interactive AI host cannot answer — it would hang rather than fail. The hatch installs to ~/.local/bin instead. That is a deviation, the note says so, and ~/.local/bin is 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 docs only: 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 at docs first; use no_sudo_commands only if the user can't run those or asks the host to do it.
  • found: false — changed from "ask the user to run raptor login" to RUN it for them, exactly as this file already treats praxis 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: false bullet 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, so TestRaptorStatusLine's case was updated. Intended, not incidental.

Testing

  • go build ./..., go vet ./..., gofmt -l . clean
  • Full go test ./... green
  • Every new test verified failing against pre-change code, passing after
  • Binary exercised through a pty in all three states (raptor stubbed off PATH, installed-not-logged-in, --json) — output above is real, not hand-written
  • Asset names checked against the actual v0.1.91 release, not the README (which is stale on Windows)
  • Both the README anchor and the generated download URL fetched — 200
  • feat: raptor profile cross-check in status/login + local-mode docs in meta-skill #68's block fields pinned by a test so they can't be dropped

Open question for review

raptor upgrade self-replaces the binary. I have not verified it handles living in ~/.local/bin rather than /usr/local/bin. If it assumes the latter, the hatch could break upgrades. @anshulsao's machine runs raptor from ~/.local/bin today and upgrades work, but that's one data point.

Still open in #72

Whether praxis login should 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

    • Added a setup completion status to JSON output.
    • Added clear warnings when Raptor is not installed or lacks a usable profile.
    • Added platform-specific, no-sudo Raptor installation commands and documentation links.
    • Added guidance for unsupported platforms.
  • Improvements

    • Setup instructions can now guide Raptor installation and authentication automatically.
    • Installation hints are omitted once Raptor is ready.
    • Added clearer links to Raptor release downloads.

#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
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

Changes

Raptor setup flow

Layer / File(s) Summary
Setup readiness reporting
cmd/status.go, cmd/status_test.go
status now reports setup_complete in JSON and setup notices in human-readable output. Tests cover authentication and Raptor readiness states.
Platform-specific Raptor installation guidance
cmd/status.go, cmd/status_test.go
Raptor status includes release URLs, supported-platform commands, and documentation fallback guidance. Tests cover asset names, commands, and existing status fields.
Embedded skill setup execution
internal/skillinstall/dummy.go, internal/skillinstall/dummy_test.go
The Praxis meta-skill directs AI agents to install Raptor, run raptor login, and check setup_complete. Regression tests validate the guidance.

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
Loading

Possibly related issues

  • Facets-cloud/praxis-cli issue 72 — The PR implements setup warnings, platform-specific Raptor installation guidance, and login instructions described by the issue.

Possibly related PRs

Suggested reviewers: anujhydrabadi

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main changes: clearer unusable Raptor status and runnable setup guidance for AI hosts.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/status-shows-raptor

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

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
@anshulsao anshulsao changed the title feat(status): make an unusable raptor obvious and actionable feat(status): make an unusable raptor obvious, and give AI hosts runnable setup steps Aug 5, 2026
@anshulsao
anshulsao marked this pull request as ready for review August 5, 2026 03:17
@anshulsao
anshulsao requested a review from anujhydrabadi August 5, 2026 03:17
@anshulsao

Copy link
Copy Markdown
Contributor Author

@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:

  1. install_hint goes inside your raptor block, not as a new top-level key. Your meta-skill text tells hosts to act on that block, and I didn't want a second place they have to look.

  2. I changed the wording of your found: false bullet. It said "ask the user to run raptor login". It now says RUN it for them — same treatment praxis login already gets in that file (browser opens, user completes sign-in, host waits for exit 0). This was a deliberate product call from @anshulsao, not me tidying your prose. Happy to revert to ask-only if you'd rather.

  3. I added an installed: false bullet to your list, in your style. Your cases all assumed raptor was already present, which is the right scope for what feat: raptor profile cross-check in status/login + local-mode docs in meta-skill #68 set out to do — this just fills the absent case.

  4. I updated your preflight section. It still said "don't install it yourself", which would have contradicted the new bullets right below it. There's a test that fails if that line comes back.

Things worth your scrutiny:

  • The install goes to ~/.local/bin rather than /usr/local/bin, because sudo would block on a password prompt and hang a non-interactive host. Trade-off: ~/.local/bin isn't on everyone's PATH. I put that caveat in install_hint.note — tell me if you think that's too weak.
  • setup_complete is top-level, not in your block, since it also covers praxis login state. Say the word if you'd rather it lived elsewhere.
  • Asset names are hardcoded to match the real release (raptor-{darwin,linux}-{amd64,arm64}). If raptor ever publishes Windows, raptorAssetName needs a line. Test covers the unpublished-platform path so we degrade to docs rather than a 404.

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).

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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

📥 Commits

Reviewing files that changed from the base of the PR and between 2a863ef and 1d8e154.

📒 Files selected for processing (4)
  • cmd/status.go
  • cmd/status_test.go
  • internal/skillinstall/dummy.go
  • internal/skillinstall/dummy_test.go

Comment thread cmd/status.go
Comment on lines +91 to +95
// 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)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 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

Comment thread cmd/status.go Outdated
Comment on lines +203 to +209
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",
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 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/agentinstall

Repository: 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.

Comment thread cmd/status.go Outdated
Comment on lines +205 to +210
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."

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 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.

Comment on lines +250 to +252
- ` + "`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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 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
@anujhydrabadi
anujhydrabadi merged commit bd215e9 into main Aug 5, 2026
3 checks passed
@anujhydrabadi
anujhydrabadi deleted the fix/status-shows-raptor branch August 5, 2026 10:33
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.

2 participants