fabro/lib/crates/fabro-cli/tests/it/cmd
fabro-sh-0530[bot] 0754f1ca4a
Add fabro_run_get read-only run inspection tool (#358)
## Summary

Adds a new `fabro_run_get` MCP tool that returns a run's summary,
resolved ID, projection, and pending questions without any mutation
capability. This separates read-only inspection from operational
control, allowing Ask Fabro sessions to inspect runs safely without
access to write operations.

## What changed and why

**New tool (`fabro-tool/src/get.rs`):** `FabroRunGetParams` /
`ValidatedRunGet` / `RunGetResult` follow the same
validation-and-dispatch pattern as other run tools. The implementation
resolves a selector, then fans out to three read-only API calls
(retrieve run, get state, list questions) and assembles them into a
single structured result.

**Tool registry and dispatch:** `FABRO_RUN_GET_TOOL_NAME` is exported
from `common.rs` and `lib.rs`, added to `TOOL_DEFINITIONS`, wired into
the MCP stdio server (`fabro-mcp-server/src/server.rs`), and dispatched
in the LLM agent executor (`fabro-workflow/src/handler/llm/api.rs`).

**Ask Fabro access policy (`fabro-server/.../sessions.rs`):** The
session now registers and allows only `fabro_run_events` +
`fabro_run_get` via the new `ASK_FABRO_RUN_TOOL_NAMES` constant.
`fabro_run_interact` is explicitly moved to the denied set, closing off
mutation from that session type. The policy match arm is refactored from
a hardcoded `|`-chain to a slice `contains` check so the constant is the
single source of truth.

**Docs:** `mcp.mdx` now lists `fabro_run_get` as the inspection tool and
redescribes `fabro_run_interact` as control-oriented.

**Backward compatibility:** `fabro_run_interact` (including `get` and
`get_questions` actions) is unchanged and still fully operational for
contexts that allow it.

### Plan Summary

- New `get.rs` module in `fabro-tool` with validation, async fetch, and
unit tests
- Constants + schema registration in `common.rs` / `lib.rs`
- MCP server and LLM dispatch branches added for
`FABRO_RUN_GET_TOOL_NAME`
- Ask Fabro session swaps `FABRO_RUN_INTERACT_TOOL_NAME` →
`FABRO_RUN_GET_TOOL_NAME` in registry and policy
- MCP integration tests: tool count constant, schema assertions, two new
end-to-end tests
(`mcp_get_resolves_selector_and_returns_summary_projection_and_questions`,
`mcp_get_rejects_blank_run_id_before_auth_or_network`)
- Public MCP docs updated


### Fabro Details

<details>
<summary>Ran 9 stages in 43m 30s for $13.42</summary>

| Stage | Duration | Cost | Retries |
|---|---|---|---|
| start | 0s | – | 0 |
| toolchain | 1s | – | 0 |
| preflight_compile | 2m 2s | – | 0 |
| preflight_lint | 2m 14s | – | 0 |
| implement | 19m 43s | $8.85 | 0 |
| simplify_opus | 5m 52s | $1.45 | 0 |
| simplify_gpt | 10m 16s | $3.12 | 0 |
| verify | 2m 53s | – | 0 |
| fmt | 3s | – | 0 |
| **Total** | **43m 30s** | **$13.42** | **0** |

</details>

<details>
<summary>Ran <code>ImplementPlan.fabro</code> (12 nodes and 15
edges)</summary>

```dot
digraph ImplementPlan {
    graph [
        goal="Implement and simplify",
        model_stylesheet="
            * { model: claude-opus-4-7; }
        "
    ]
    rankdir=LR

    start [shape=Mdiamond, label="Start"]
    exit  [shape=Msquare, label="Exit"]

    toolchain         [label="Toolchain", shape=parallelogram, script="command -v cargo >/dev/null || { curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && sudo ln -sf $HOME/.cargo/bin/* /usr/local/bin/; }; cargo --version 2>&1", max_retries=0]
    preflight_compile [label="Preflight Compile", shape=parallelogram, script="cargo check -q --workspace 2>&1", max_retries=0]
    preflight_lint    [label="Preflight Lint", shape=parallelogram, script="cargo +nightly-2026-04-14 clippy -q --workspace --all-targets -- -D warnings 2>&1", max_retries=0]
    fix_lints         [label="Fix Lints", prompt="The preflight lint step failed. Read the build output from context and fix all clippy lint warnings.", max_visits=3]
    implement         [label="Implement", prompt="Read the plan file referenced in the goal and implement every step. Make all the code changes described in the plan. Use red/green TDD."]
    simplify_opus     [label="Simplify (Opus)", prompt="@prompts/simplify.md"]
    simplify_gpt      [label="Simplify (GPT-55)", prompt="@prompts/simplify.md", model="gpt-55"]
    verify            [label="Verify", shape=parallelogram, script="cargo +nightly-2026-04-14 clippy -q --workspace --all-targets -- -D warnings 2>&1 && cargo nextest run --cargo-quiet --workspace --status-level fail 2>&1 && cargo dev docs refresh 2>&1 && cargo dev docs check 2>&1", goal_gate=true, retry_target="fixup"]
    fixup             [label="Fixup", prompt="The verify step failed. Read the build output from context and fix all clippy lint warnings, test failures, and generated docs errors.", max_visits=3]
    fmt               [label="Format", shape=parallelogram, script="cargo +nightly-2026-04-14 fmt --all 2>&1", max_retries=0]

    start -> toolchain
    toolchain -> preflight_compile [condition="outcome=succeeded"]
    toolchain -> exit
    preflight_compile -> preflight_lint [condition="outcome=succeeded"]
    preflight_compile -> exit
    preflight_lint -> implement [condition="outcome=succeeded"]
    preflight_lint -> fix_lints
    fix_lints -> preflight_lint
    implement -> simplify_opus -> simplify_gpt -> verify
    verify -> fmt   [condition="outcome=succeeded"]
    verify -> fixup
    fixup -> verify
    fmt -> exit
}

```

</details>

⚒️ Generated with [Fabro](https://fabro.sh)

---------

Co-authored-by: Fabro <noreply@fabro.sh>
2026-05-22 19:03:56 -04:00
..
archive.rs refactor(types): remove legacy run summary shape 2026-05-10 23:29:41 -04:00
artifact_cp.rs test(cli): trim slow integration fixture setup 2026-04-28 19:14:56 -07:00
artifact_list.rs test(cli): trim slow integration fixture setup 2026-04-28 19:14:56 -07:00
attach.rs feat: add run.checkpoint.skip_git_hooks to bypass Git commit hooks (#355) 2026-05-22 17:26:06 -04:00
auth.rs test(cli): tighten env-dev-token-ignore tests 2026-05-01 16:25:13 -04:00
cli_reference.rs refactor(dev): decouple CLI reference generation 2026-05-06 12:31:02 -04:00
config.rs Collapsible run stage sidebar (#352) 2026-05-22 12:20:29 -04:00
create.rs fix(validate): treat undefined template vars in @file prompts as warnings (#290) 2026-05-16 17:31:22 -04:00
diff.rs test(cli): prune slow integration outliers 2026-04-28 19:26:27 -07:00
discord.rs refactor(cli): deglobalize server and storage target flags 2026-04-05 16:06:42 -04:00
docs.rs refactor(cli): deglobalize server and storage target flags 2026-04-05 16:06:42 -04:00
doctor.rs refactor(auth): split credential sources and vault schemas (#306) 2026-05-18 11:07:42 -04:00
dump.rs refactor(workflow): remove local worktree mode 2026-05-09 11:04:23 -04:00
events.rs fix(runs): restore terminal sandbox regressions 2026-05-08 22:41:42 -04:00
exec.rs refactor(model): move provider facts into catalog (#298) 2026-05-17 20:59:08 -04:00
fabro.rs feat(api): bind sessions to runs (#336) 2026-05-21 10:53:41 -04:00
fork.rs refactor(runs): simplify run projection shape 2026-05-09 23:31:43 -04:00
graph.rs feat(cli): render fatal errors with miette 2026-04-24 15:35:57 -04:00
inspect.rs feat: add run.checkpoint.skip_git_hooks to bypass Git commit hooks (#355) 2026-05-22 17:26:06 -04:00
install.rs refactor(install): share persistence pipeline (#332) 2026-05-21 08:04:04 -04:00
json_global.rs fix(server): persist manifest metadata names (#302) 2026-05-18 08:31:23 -04:00
logs.rs fix(cli): preserve API error details 2026-05-06 14:03:12 -04:00
mcp.rs Add fabro_run_get read-only run inspection tool (#358) 2026-05-22 19:03:56 -04:00
mod.rs feat(api): bind sessions to runs (#336) 2026-05-21 10:53:41 -04:00
model.rs refactor(llm): split provider identity from adapters (#280) 2026-05-16 13:13:41 -04:00
model_list.rs refactor(cli): separate local socket and storage defaults 2026-04-06 11:57:14 -04:00
model_test.rs refactor(llm): split provider identity from adapters (#280) 2026-05-16 13:13:41 -04:00
parent.rs feat(cli): wire run parent commands (#288) 2026-05-16 15:15:28 -04:00
parse.rs feat(cli): render fatal errors with miette 2026-04-24 15:35:57 -04:00
pr.rs feat(pr): support GitHub pull request associations (#270) 2026-05-16 12:47:27 -04:00
pr_close.rs refactor(pr): simplify server-side PR plumbing 2026-04-24 11:17:01 -04:00
pr_create.rs feat(pr): support GitHub pull request associations (#270) 2026-05-16 12:47:27 -04:00
pr_link.rs feat(pr): support GitHub pull request associations (#270) 2026-05-16 12:47:27 -04:00
pr_merge.rs refactor(pr): simplify server-side PR plumbing 2026-04-24 11:17:01 -04:00
pr_unlink.rs feat(pr): support GitHub pull request associations (#270) 2026-05-16 12:47:27 -04:00
pr_view.rs feat(pr): support GitHub pull request associations (#270) 2026-05-16 12:47:27 -04:00
preflight.rs feat(template): add source-aware diagnostics (#292) 2026-05-16 18:47:37 -04:00
provider.rs refactor(cli): deglobalize server and storage target flags 2026-04-05 16:06:42 -04:00
provider_login.rs Complete provider credential auth and scripted install 2026-04-13 09:15:45 -04:00
ps.rs fix(server): persist manifest metadata names (#302) 2026-05-18 08:31:23 -04:00
render_graph.rs fix(graph): support dotted Fabro graph attributes (#324) 2026-05-20 09:31:08 -04:00
repo.rs feat(cli): render fatal errors with miette 2026-04-24 15:35:57 -04:00
repo_deinit.rs refactor(config): move project state under .fabro 2026-04-11 12:55:46 -04:00
repo_init.rs feat(cli): render fatal errors with miette 2026-04-24 15:35:57 -04:00
resume.rs test(cli): prune slow integration outliers 2026-04-28 19:26:27 -07:00
rewind.rs feat(api): unify public run shape 2026-05-10 20:48:55 -04:00
rm.rs fix(cli): print full run id on rm (#315) 2026-05-20 08:24:31 -04:00
run.rs feat: Replace duration/elapsed fields with wall_time_ms and StageTiming (#343) 2026-05-21 21:06:40 -04:00
runner.rs refactor(runs): simplify run projection shape 2026-05-09 23:31:43 -04:00
sandbox_cp.rs feat(api): unify public run shape 2026-05-10 20:48:55 -04:00
sandbox_preview.rs refactor(types): remove legacy run summary shape 2026-05-10 23:29:41 -04:00
sandbox_ssh.rs fix(cli): repair verification failures 2026-05-09 18:07:24 -04:00
secret.rs refactor(auth): split credential sources and vault schemas (#306) 2026-05-18 11:07:42 -04:00
secret_list.rs refactor(auth): split credential sources and vault schemas (#306) 2026-05-18 11:07:42 -04:00
secret_rm.rs refactor(cli): deglobalize server and storage target flags 2026-04-05 16:06:42 -04:00
secret_set.rs refactor(auth): split credential sources and vault schemas (#306) 2026-05-18 11:07:42 -04:00
send_analytics.rs refactor(cli): deglobalize server and storage target flags 2026-04-05 16:06:42 -04:00
send_panic.rs refactor(cli): deglobalize server and storage target flags 2026-04-05 16:06:42 -04:00
server_start.rs fix(server): default foreground logs to stdout 2026-05-06 12:41:52 -04:00
server_status.rs refactor(server): unify daemon runtime metadata 2026-04-22 16:07:52 -04:00
server_stop.rs refactor(test): promote shared server-lifecycle test helpers into fabro-test 2026-04-19 16:43:26 -04:00
start.rs refactor(workflow): remove retro stage (#230) 2026-05-09 10:18:20 -04:00
support.rs feat: Replace duration/elapsed fields with wall_time_ms and StageTiming (#343) 2026-05-21 21:06:40 -04:00
system.rs fix(system): expose unreadable run repair flow 2026-05-06 07:15:18 -04:00
system_df.rs fix(server): count whole storage tree in Fabro-managed bytes 2026-05-21 11:28:39 -04:00
system_events.rs refactor(cli): finish command context cleanup 2026-04-23 07:14:32 -04:00
system_info.rs refactor(cli): finish command context cleanup 2026-04-23 07:14:32 -04:00
system_prune.rs test(cli): trim slow integration fixture setup 2026-04-28 19:14:56 -07:00
system_repair.rs fix(runs): repair deletion of unreadable runs 2026-05-09 17:45:55 -04:00
test_panic.rs test: speed up slow default-profile tests and tighten nextest thresholds 2026-04-05 13:15:59 -04:00
top_level.rs feat(cli): show curated landing output for bare fabro 2026-04-17 08:59:03 -04:00
unarchive.rs refactor(types): remove legacy run summary shape 2026-05-10 23:29:41 -04:00
uninstall.rs refactor(server): unify daemon runtime metadata 2026-04-22 16:07:52 -04:00
upgrade.rs feat(cli): render fatal errors with miette 2026-04-24 15:35:57 -04:00
validate.rs feat(template): resolve template error locations (#333) 2026-05-20 20:15:04 -04:00
version.rs feat(cli): add fabro version command 2026-04-14 16:30:53 -04:00
wait.rs feat: Replace duration/elapsed fields with wall_time_ms and StageTiming (#343) 2026-05-21 21:06:40 -04:00
worker_auth.rs refactor(workflow): remove retro stage (#230) 2026-05-09 10:18:20 -04:00
workflow.rs fix(workflow): ignore deprecated project directory 2026-05-09 10:55:56 -04:00
workflow_create.rs fix(workflow): ignore deprecated project directory 2026-05-09 10:55:56 -04:00
workflow_list.rs feat(cli): render fatal errors with miette 2026-04-24 15:35:57 -04:00