diff --git a/.ai/prompts/code-review-deep-1.md b/.ai/prompts/code-review-deep-1.md
index 1d837cfe7..c15a499b6 100644
--- a/.ai/prompts/code-review-deep-1.md
+++ b/.ai/prompts/code-review-deep-1.md
@@ -17,7 +17,7 @@ Output a report with all the bugs using this format:
title of bugbrief description of bug
- lib/crates/fabro-cli/src/commands/resume.rs
+ lib/apps/fabro-cli/src/commands/resume.rs115115
diff --git a/.ai/prompts/code-review-deep-2.md b/.ai/prompts/code-review-deep-2.md
index 6bc81586b..aa7000436 100644
--- a/.ai/prompts/code-review-deep-2.md
+++ b/.ai/prompts/code-review-deep-2.md
@@ -19,7 +19,7 @@ Output a report with all the bugs using this format:
important OR nityes OR no
- lib/crates/fabro-cli/src/commands/resume.rs
+ lib/apps/fabro-cli/src/commands/resume.rs115115
@@ -51,7 +51,7 @@ Here is a real-world example:
importantno
- lib/crates/fabro-cli/src/commands/resume.rs
+ lib/apps/fabro-cli/src/commands/resume.rs208208
diff --git a/.claude/skills/docs/references/mapping.md b/.claude/skills/docs/references/mapping.md
index 0a7c9e329..0d6a0d3cf 100644
--- a/.claude/skills/docs/references/mapping.md
+++ b/.claude/skills/docs/references/mapping.md
@@ -4,32 +4,32 @@ Which source files affect which doc pages. Use this as guidance — also apply j
| Source | Docs |
|--------|------|
-| `lib/crates/fabro-cli/src/main.rs`, `lib/crates/fabro-workflow/src/cli/mod.rs`, `lib/crates/fabro-workflow/src/cli/run.rs` | `docs/public/reference/cli.mdx` |
-| `lib/crates/fabro-cli/src/cli_config.rs` | `docs/public/reference/cli-configuration.mdx` |
-| `lib/crates/fabro-llm/src/cli.rs` | `docs/public/reference/cli.mdx` |
-| `lib/crates/fabro-api/src/serve.rs` | `docs/public/reference/cli.mdx` |
-| `lib/crates/fabro-workflow/src/parser/*.rs` | `docs/public/reference/dot-language.mdx` |
-| `lib/crates/fabro-workflow/src/condition.rs` | `docs/public/reference/dot-language.mdx` |
-| `lib/crates/fabro-workflow/src/cli/validate.rs` | `docs/public/reference/dot-language.mdx` |
-| `lib/crates/fabro-workflow/src/stylesheet.rs` | `docs/public/workflows/stylesheets.mdx` |
-| `lib/crates/fabro-workflow/src/transform.rs` | `docs/public/workflows/variables.mdx` |
-| `lib/crates/fabro-workflow/src/handler/*.rs` | `docs/public/workflows/stages-and-nodes.mdx`, `docs/public/reference/dot-language.mdx` |
-| `lib/crates/fabro-workflow/src/handler/human.rs` | `docs/public/workflows/human-in-the-loop.mdx` |
-| `lib/crates/fabro-workflow/src/cli/run_config.rs` | `docs/public/execution/run-configuration.mdx` |
-| `lib/crates/fabro-workflow/src/engine.rs` | `docs/public/core-concepts/how-arc-works.mdx` |
-| `lib/crates/fabro-workflow/src/context/*.rs` | `docs/public/execution/context.mdx` |
-| `lib/crates/fabro-workflow/src/checkpoint.rs` | `docs/public/execution/checkpoints.mdx` |
-| `lib/crates/fabro-workflow/src/retro.rs`, `lib/crates/fabro-workflow/src/retro_agent.rs` | `docs/public/execution/retros.mdx` |
-| `lib/crates/fabro-workflow/src/interviewer/*.rs` | `docs/public/execution/interviews.mdx` |
-| `lib/crates/fabro-workflow/src/hook/*.rs` | `docs/public/agents/hooks.mdx` |
-| `lib/crates/fabro-workflow/src/daytona_sandbox.rs` | `docs/public/integrations/daytona.mdx`, `docs/public/execution/environments.mdx` |
-| `lib/crates/fabro-agent/src/tools.rs`, `lib/crates/fabro-agent/src/tool_registry.rs`, `lib/crates/fabro-agent/src/tool_execution.rs` | `docs/public/agents/tools.mdx` |
-| `lib/crates/fabro-agent/src/v4a_patch.rs` | `docs/public/agents/tools.mdx` |
-| `lib/crates/fabro-agent/src/cli.rs` | `docs/public/agents/permissions.mdx` |
-| `lib/crates/fabro-agent/src/subagent.rs` | `docs/public/agents/subagents.mdx` |
-| `lib/crates/fabro-agent/src/mcp_integration.rs` | `docs/public/agents/mcp.mdx` |
-| `lib/crates/fabro-llm/src/catalog.rs`, `lib/crates/fabro-llm/src/providers/*.rs` | `docs/public/core-concepts/models.mdx` |
-| `lib/crates/fabro-slack/src/*.rs` | `docs/public/integrations/slack.mdx` |
-| `lib/crates/fabro-mcp/src/*.rs` | `docs/public/agents/mcp.mdx` |
-| `lib/crates/fabro-api/src/*.rs` | `docs/public/api-reference/overview.mdx`, `docs/public/api-reference/demo-mode.mdx` |
-| `lib/crates/fabro-api/src/server_config.rs` | `docs/public/administration/server-configuration.mdx` |
+| `lib/apps/fabro-cli/src/main.rs`, `lib/components/fabro-workflow/src/cli/mod.rs`, `lib/components/fabro-workflow/src/cli/run.rs` | `docs/public/reference/cli.mdx` |
+| `lib/apps/fabro-cli/src/cli_config.rs` | `docs/public/reference/cli-configuration.mdx` |
+| `lib/components/fabro-llm/src/cli.rs` | `docs/public/reference/cli.mdx` |
+| `lib/foundation/fabro-api/src/serve.rs` | `docs/public/reference/cli.mdx` |
+| `lib/components/fabro-workflow/src/parser/*.rs` | `docs/public/reference/dot-language.mdx` |
+| `lib/components/fabro-workflow/src/condition.rs` | `docs/public/reference/dot-language.mdx` |
+| `lib/components/fabro-workflow/src/cli/validate.rs` | `docs/public/reference/dot-language.mdx` |
+| `lib/components/fabro-workflow/src/stylesheet.rs` | `docs/public/workflows/stylesheets.mdx` |
+| `lib/components/fabro-workflow/src/transform.rs` | `docs/public/workflows/variables.mdx` |
+| `lib/components/fabro-workflow/src/handler/*.rs` | `docs/public/workflows/stages-and-nodes.mdx`, `docs/public/reference/dot-language.mdx` |
+| `lib/components/fabro-workflow/src/handler/human.rs` | `docs/public/workflows/human-in-the-loop.mdx` |
+| `lib/components/fabro-workflow/src/cli/run_config.rs` | `docs/public/execution/run-configuration.mdx` |
+| `lib/components/fabro-workflow/src/engine.rs` | `docs/public/core-concepts/how-arc-works.mdx` |
+| `lib/components/fabro-workflow/src/context/*.rs` | `docs/public/execution/context.mdx` |
+| `lib/components/fabro-workflow/src/checkpoint.rs` | `docs/public/execution/checkpoints.mdx` |
+| `lib/components/fabro-workflow/src/retro.rs`, `lib/components/fabro-workflow/src/retro_agent.rs` | `docs/public/execution/retros.mdx` |
+| `lib/components/fabro-workflow/src/interviewer/*.rs` | `docs/public/execution/interviews.mdx` |
+| `lib/components/fabro-workflow/src/hook/*.rs` | `docs/public/agents/hooks.mdx` |
+| `lib/components/fabro-workflow/src/daytona_sandbox.rs` | `docs/public/integrations/daytona.mdx`, `docs/public/execution/environments.mdx` |
+| `lib/components/fabro-agent/src/tools.rs`, `lib/components/fabro-agent/src/tool_registry.rs`, `lib/components/fabro-agent/src/tool_execution.rs` | `docs/public/agents/tools.mdx` |
+| `lib/components/fabro-agent/src/v4a_patch.rs` | `docs/public/agents/tools.mdx` |
+| `lib/components/fabro-agent/src/cli.rs` | `docs/public/agents/permissions.mdx` |
+| `lib/components/fabro-agent/src/subagent.rs` | `docs/public/agents/subagents.mdx` |
+| `lib/components/fabro-agent/src/mcp_integration.rs` | `docs/public/agents/mcp.mdx` |
+| `lib/components/fabro-llm/src/catalog.rs`, `lib/components/fabro-llm/src/providers/*.rs` | `docs/public/core-concepts/models.mdx` |
+| `lib/components/fabro-slack/src/*.rs` | `docs/public/integrations/slack.mdx` |
+| `lib/components/fabro-mcp/src/*.rs` | `docs/public/agents/mcp.mdx` |
+| `lib/foundation/fabro-api/src/*.rs` | `docs/public/api-reference/overview.mdx`, `docs/public/api-reference/demo-mode.mdx` |
+| `lib/foundation/fabro-api/src/server_config.rs` | `docs/public/administration/server-configuration.mdx` |
diff --git a/.gitattributes b/.gitattributes
index 068cf7f02..96454cdd1 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,2 +1,2 @@
-lib/crates/fabro-spa/assets/** linguist-generated=true -diff
+lib/apps/fabro-spa/assets/** linguist-generated=true -diff
lib/packages/fabro-api-client/src/** linguist-generated=true
diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml
index 1580d81df..12ba1b9cc 100644
--- a/.github/workflows/rust.yml
+++ b/.github/workflows/rust.yml
@@ -4,7 +4,9 @@ on:
push:
branches: [main]
paths:
- - "lib/crates/**"
+ - "lib/apps/**"
+ - "lib/components/**"
+ - "lib/foundation/**"
- "test/**"
- "Cargo.toml"
- "Cargo.lock"
@@ -18,7 +20,9 @@ on:
pull_request:
branches: [main]
paths:
- - "lib/crates/**"
+ - "lib/apps/**"
+ - "lib/components/**"
+ - "lib/foundation/**"
- "test/**"
- "Cargo.toml"
- "Cargo.lock"
@@ -76,7 +80,7 @@ jobs:
- name: Verify legacy auth identity removal
run: |
if git grep -nE 'AuthMode::Disabled|RunAuthMethod|RunSubjectProvenance|\bActorRef\b|\bActorKind\b|AuthenticatedSubject|AuthenticatedService|AuthorizeRunScoped|AuthorizeRunBlob|AuthorizeStageArtifact|AuthorizeCommandLog|auth_method\s*==\s*"disabled"' \
- -- lib/crates apps lib/packages docs/public/api-reference/fabro-api.yaml; then
+ -- lib/apps lib/components lib/foundation apps lib/packages docs/public/api-reference/fabro-api.yaml; then
echo "::error::Legacy auth identities remain in the repository"
exit 1
else
diff --git a/.github/workflows/typescript.yml b/.github/workflows/typescript.yml
index e2f63a047..064c38c3d 100644
--- a/.github/workflows/typescript.yml
+++ b/.github/workflows/typescript.yml
@@ -5,7 +5,7 @@ on:
branches: [main]
paths:
- "apps/**"
- - "lib/crates/fabro-spa/**"
+ - "lib/apps/fabro-spa/**"
- "lib/packages/**"
- "package.json"
- "bun.lock"
@@ -17,7 +17,7 @@ on:
branches: [main]
paths:
- "apps/**"
- - "lib/crates/fabro-spa/**"
+ - "lib/apps/fabro-spa/**"
- "lib/packages/**"
- "package.json"
- "bun.lock"
diff --git a/.gitignore b/.gitignore
index 5c49b62a9..d9b235fc2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,8 +4,8 @@ target
node_modules
apps/fabro-web/dist
apps/fabro-web/.dist-builds/
-lib/crates/fabro-spa/assets/*
-!lib/crates/fabro-spa/assets/.gitkeep
+lib/apps/fabro-spa/assets/*
+!lib/apps/fabro-spa/assets/.gitkeep
tmp
evals/swe-bench/repos/
evals/swe-bench/results/
diff --git a/AGENTS.md b/AGENTS.md
index d77efe095..bdc9ab53f 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -56,7 +56,7 @@ The OpenAPI spec at `docs/public/api-reference/fabro-api.yaml` is the source of
1. Edit `docs/public/api-reference/fabro-api.yaml`
2. `cargo build -p fabro-api` — build.rs regenerates Rust types and client via progenitor
-3. Write/update handler in `lib/crates/fabro-server/src/server.rs`, add route to `build_router()`
+3. Write/update handler in `lib/apps/fabro-server/src/server.rs`, add route to `build_router()`
4. `cargo nextest run -p fabro-server` — conformance test catches spec/router drift
5. `cd lib/packages/fabro-api-client && bun run generate` — regenerates TypeScript Axios client
@@ -64,7 +64,7 @@ The OpenAPI spec at `docs/public/api-reference/fabro-api.yaml` is the source of
- Treat OpenAPI as the source of truth for the wire contract, not as the automatic owner of Rust types.
- Before adding or keeping a generated schema type, search the workspace for an existing hand-written Rust type with the same product meaning.
-- If the schema and an existing Rust type have the same semantics and serde shape, reuse the existing type via `lib/crates/fabro-api/build.rs` `with_replacement(...)` instead of generating a parallel API type.
+- If the schema and an existing Rust type have the same semantics and serde shape, reuse the existing type via `lib/foundation/fabro-api/build.rs` `with_replacement(...)` instead of generating a parallel API type.
- If two types are close but not identical, prefer proposing changes that align them into one canonical type rather than accepting small drift. It is usually better to iterate the API now than to create permanently split Rust/API types.
- Keep a separate API DTO only when the API is intentionally a projection, summary, or presentation-specific view of internal state. In that case, give it a distinct API-facing name instead of reusing the internal concept name.
- Treat `ApiFoo` aliases and `foo_to_api` / `foo_from_api` adapters as a smell unless they represent a real semantic boundary. They should not exist only to bridge accidental duplicate types.
@@ -107,7 +107,7 @@ Before merging changes that add or move shared test helpers, verify:
Fabro is an AI-powered workflow orchestration platform. Workflows are defined as Graphviz graphs, where each node is a stage (agent, prompt, command, conditional, human, parallel, etc.) executed by the workflow engine.
-### Rust crates (`lib/crates/`)
+### Rust crates (`lib/apps/`, `lib/components/`, and `lib/foundation/`)
- **fabro-cli** — CLI entry point. Commands: `run`, `exec`, `serve`, `validate`, `parse`, `cp`, `model`, `doctor`, `install`, `ps`, `system prune`
- **fabro-workflow** — Core workflow engine. Parses Graphviz graphs, runs stages, manages checkpoints/resume, hooks, and human-in-the-loop interactions
- **fabro-agent** — AI coding agent with tool use (Bash, Read, Write, Edit, Glob, Grep, WebFetch). `Sandbox` trait abstracts execution environments
diff --git a/Cargo.toml b/Cargo.toml
index 6cdec975b..e9f63c9d7 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,12 @@
[workspace]
-members = ["lib/crates/*", "test/twin/openai", "test/twin/github"]
-default-members = ["lib/crates/fabro-cli"]
+members = [
+ "lib/apps/*",
+ "lib/components/*",
+ "lib/foundation/*",
+ "test/twin/openai",
+ "test/twin/github",
+]
+default-members = ["lib/apps/fabro-cli"]
resolver = "2"
[workspace.package]
@@ -84,7 +90,7 @@ hmac = "0.12"
sha2 = "0.10"
hex = "0.4"
insta = "1"
-fabro-test = { path = "lib/crates/fabro-test" }
+fabro-test = { path = "lib/foundation/fabro-test" }
twin-openai = { path = "test/twin/openai" }
twin-github = { path = "test/twin/github" }
tokio-tungstenite = { version = "0.26", features = ["rustls-tls-webpki-roots"] }
@@ -100,11 +106,11 @@ rust-embed = "8"
percent-encoding = "2"
minijinja = "=2.19.0"
miette = { version = "7.6", features = ["fancy"] }
-fabro-http = { path = "lib/crates/fabro-http" }
-fabro-environment = { path = "lib/crates/fabro-environment" }
-fabro-options-metadata = { path = "lib/crates/fabro-options-metadata" }
-fabro-redact = { path = "lib/crates/fabro-redact" }
-fabro-static = { path = "lib/crates/fabro-static" }
+fabro-http = { path = "lib/foundation/fabro-http" }
+fabro-environment = { path = "lib/components/fabro-environment" }
+fabro-options-metadata = { path = "lib/foundation/fabro-options-metadata" }
+fabro-redact = { path = "lib/foundation/fabro-redact" }
+fabro-static = { path = "lib/foundation/fabro-static" }
graphviz-sys = { git = "https://github.com/fabro-sh/graphviz-sys" }
ref-cast = "1"
strum = { version = "0.28", features = ["derive"] }
diff --git a/apps/fabro-web/app/routes/run-overview.tsx b/apps/fabro-web/app/routes/run-overview.tsx
index 25262b748..0150d19ea 100644
--- a/apps/fabro-web/app/routes/run-overview.tsx
+++ b/apps/fabro-web/app/routes/run-overview.tsx
@@ -23,7 +23,7 @@ export const handle = { wide: true, fullHeight: true };
type Direction = "LR" | "TB";
-// Mirrors fabro-graphviz's RANKDIR_RE (lib/crates/fabro-graphviz/src/render.rs) —
+// Mirrors fabro-graphviz's RANKDIR_RE (lib/components/fabro-graphviz/src/render.rs) —
// keep the accepted `rankdir=` syntax in sync with that regex.
const RANKDIR_RE = /rankdir\s*=\s*(\w+)/;
diff --git a/docs/internal/cli-workflow-coupling-audit.md b/docs/internal/cli-workflow-coupling-audit.md
index 7fdf953ba..198e658f3 100644
--- a/docs/internal/cli-workflow-coupling-audit.md
+++ b/docs/internal/cli-workflow-coupling-audit.md
@@ -2,7 +2,7 @@
## Scope
-- Production imports under `lib/crates/fabro-cli/src/**` that still reference `fabro_workflow::*` after the server-owned selector/export refactor.
+- Production imports under `lib/apps/fabro-cli/src/**` that still reference `fabro_workflow::*` after the server-owned selector/export refactor.
- Test-only imports are listed separately so the remaining architectural debt is explicit.
## Completed In This Change
@@ -16,30 +16,30 @@
| Path | Direct dependency | Why it still exists | Required remediation track |
| --- | --- | --- | --- |
-| `lib/crates/fabro-cli/src/commands/pr/create.rs` | `StageOutcome`, `pull_request::maybe_open_pull_request` | CLI still reconstructs store state and runs PR creation logic from the workflow pipeline directly. | Replace with a server API, or extract PR orchestration into a non-engine shared service crate plus API. |
-| `lib/crates/fabro-cli/src/commands/run/runner.rs` | `artifact_snapshot::CapturedArtifactInfo`, `artifact_upload::{ArtifactSink, StageArtifactUploader}`, `event::{Emitter, RunEventSink}`, `operations::{self, StartServices}`, `run_control::RunControlState`, `runtime_store::{RunStoreBackend, RunStoreHandle}` | Hidden worker subprocess path still lives inside the CLI crate and embeds the workflow engine directly. | Re-home worker/runtime code outside the user CLI surface, ideally into a dedicated worker crate or binary. |
-| `lib/crates/fabro-cli/src/manifest_builder.rs` | `git::{GitSyncStatus, head_sha, sync_status}` | Manifest submission still relies on git helper logic that happens to live in `fabro_workflow`. | Extract git-sync inspection helpers into a non-workflow shared crate/module. |
-| `lib/crates/fabro-cli/src/server_client.rs` | `artifact_snapshot::CapturedArtifactInfo` | The upload client reuses a workflow-owned artifact snapshot DTO. | Extract shared artifact snapshot DTOs into `fabro-store`, `fabro-types`, or a dedicated shared crate. |
-| `lib/crates/fabro-cli/src/commands/runs/inspect.rs` | `run_status::RunStatus` | CLI output types still depend on engine-owned run status enums. | Extract shared status types into `fabro-types` or switch to API-generated/public store types. |
-| `lib/crates/fabro-cli/src/commands/runs/list.rs` | `run_status::RunStatus` | List rendering still depends on engine-owned run status enums. | Extract shared status types into `fabro-types` or switch to API-generated/public store types. |
-| `lib/crates/fabro-cli/src/commands/run/attach.rs` | `StageOutcome`, `run_status::RunStatus` | Attach/replay logic still formats engine-owned terminal status types directly. | Extract shared run/conclusion status types into `fabro-types`. |
-| `lib/crates/fabro-cli/src/commands/run/output.rs` | `StageOutcome`, `records::Conclusion` | Human-readable completion output still consumes workflow-owned conclusion/status records. | Extract shared conclusion/status DTOs into `fabro-types` or `fabro-store`. |
-| `lib/crates/fabro-cli/src/commands/run/wait.rs` | `records::Conclusion`, `run_status::RunStatus` | Wait output still depends on workflow-owned status/conclusion records. | Extract shared conclusion/status DTOs into `fabro-types` or `fabro-store`. |
-| `lib/crates/fabro-cli/src/commands/run/run_progress/stage_display.rs` | `StageOutcome`, `format_cost` | Progress UI still depends on shared stage outcome and workflow-owned cost-formatting helper code. | Move formatting helpers into `fabro-util`. |
-| `lib/crates/fabro-cli/src/commands/run/run_progress/info_display.rs` | `event::RunNoticeLevel` | Progress UI still formats workflow-owned notice levels directly. | Extract shared notice/event enums into `fabro-types`. |
-| `lib/crates/fabro-cli/src/commands/run/run_progress/event.rs` | `event::RunNoticeLevel` | Progress event translation still depends on workflow-owned notice levels. | Extract shared notice/event enums into `fabro-types`. |
+| `lib/apps/fabro-cli/src/commands/pr/create.rs` | `StageOutcome`, `pull_request::maybe_open_pull_request` | CLI still reconstructs store state and runs PR creation logic from the workflow pipeline directly. | Replace with a server API, or extract PR orchestration into a non-engine shared service crate plus API. |
+| `lib/apps/fabro-cli/src/commands/run/runner.rs` | `artifact_snapshot::CapturedArtifactInfo`, `artifact_upload::{ArtifactSink, StageArtifactUploader}`, `event::{Emitter, RunEventSink}`, `operations::{self, StartServices}`, `run_control::RunControlState`, `runtime_store::{RunStoreBackend, RunStoreHandle}` | Hidden worker subprocess path still lives inside the CLI crate and embeds the workflow engine directly. | Re-home worker/runtime code outside the user CLI surface, ideally into a dedicated worker crate or binary. |
+| `lib/apps/fabro-cli/src/manifest_builder.rs` | `git::{GitSyncStatus, head_sha, sync_status}` | Manifest submission still relies on git helper logic that happens to live in `fabro_workflow`. | Extract git-sync inspection helpers into a non-workflow shared crate/module. |
+| `lib/apps/fabro-cli/src/server_client.rs` | `artifact_snapshot::CapturedArtifactInfo` | The upload client reuses a workflow-owned artifact snapshot DTO. | Extract shared artifact snapshot DTOs into `fabro-store`, `fabro-types`, or a dedicated shared crate. |
+| `lib/apps/fabro-cli/src/commands/runs/inspect.rs` | `run_status::RunStatus` | CLI output types still depend on engine-owned run status enums. | Extract shared status types into `fabro-types` or switch to API-generated/public store types. |
+| `lib/apps/fabro-cli/src/commands/runs/list.rs` | `run_status::RunStatus` | List rendering still depends on engine-owned run status enums. | Extract shared status types into `fabro-types` or switch to API-generated/public store types. |
+| `lib/apps/fabro-cli/src/commands/run/attach.rs` | `StageOutcome`, `run_status::RunStatus` | Attach/replay logic still formats engine-owned terminal status types directly. | Extract shared run/conclusion status types into `fabro-types`. |
+| `lib/apps/fabro-cli/src/commands/run/output.rs` | `StageOutcome`, `records::Conclusion` | Human-readable completion output still consumes workflow-owned conclusion/status records. | Extract shared conclusion/status DTOs into `fabro-types` or `fabro-store`. |
+| `lib/apps/fabro-cli/src/commands/run/wait.rs` | `records::Conclusion`, `run_status::RunStatus` | Wait output still depends on workflow-owned status/conclusion records. | Extract shared conclusion/status DTOs into `fabro-types` or `fabro-store`. |
+| `lib/apps/fabro-cli/src/commands/run/run_progress/stage_display.rs` | `StageOutcome`, `format_cost` | Progress UI still depends on shared stage outcome and workflow-owned cost-formatting helper code. | Move formatting helpers into `fabro-util`. |
+| `lib/apps/fabro-cli/src/commands/run/run_progress/info_display.rs` | `event::RunNoticeLevel` | Progress UI still formats workflow-owned notice levels directly. | Extract shared notice/event enums into `fabro-types`. |
+| `lib/apps/fabro-cli/src/commands/run/run_progress/event.rs` | `event::RunNoticeLevel` | Progress event translation still depends on workflow-owned notice levels. | Extract shared notice/event enums into `fabro-types`. |
## Test-Only Couplings
| Path | Direct dependency | Why it still exists | Suggested handling |
| --- | --- | --- | --- |
-| `lib/crates/fabro-cli/src/commands/dump.rs` test module | `event::{Event, append_event}` | Unit tests synthesize workflow events directly. | Low priority; keep until a lighter-weight event fixture helper exists. |
-| `lib/crates/fabro-cli/src/commands/run/wait.rs` test module | `StageOutcome`, `records::Conclusion`, `run_status::RunStatusRecord` | Output tests construct workflow-owned records directly. | Replace with shared fixture builders once conclusion DTOs move out. |
-| `lib/crates/fabro-cli/src/commands/run/run_progress/mod.rs` test module | `event::{Event, RunNoticeLevel, to_run_event, to_run_event_at}`, `outcome::billed_model_usage_from_llm` | Progress tests build engine events directly. | Replace with shared event fixture helpers after event DTO extraction. |
-| `lib/crates/fabro-cli/src/commands/run/run_progress/event.rs` test module | `event::{Event, to_run_event}` | Event rendering tests depend on engine event constructors. | Replace with shared event fixture helpers after event DTO extraction. |
-| `lib/crates/fabro-cli/src/commands/run/runner.rs` test module | `artifact_upload::StageArtifactUploader` | Worker tests still reach into workflow upload internals. | Keep with worker re-home work; not worth separating first. |
-| `lib/crates/fabro-cli/tests/it/workflow/real_cli.rs` | `context::Context`, `event::Emitter`, `handler::agent::{CodergenBackend, CodergenResult}`, `handler::llm::cli::AgentCliBackend` | Integration test exercises the real workflow engine directly through CLI harnesses. | Accept as engine integration coverage or move under workflow-owned test support later. |
-| `lib/crates/fabro-cli/tests/it/scenario/recovery.rs` | `operations::{RunTimeline, build_timeline}` | Scenario test inspects rewind timeline internals directly. | Replace after server-owned rewind/timeline APIs exist. |
+| `lib/apps/fabro-cli/src/commands/dump.rs` test module | `event::{Event, append_event}` | Unit tests synthesize workflow events directly. | Low priority; keep until a lighter-weight event fixture helper exists. |
+| `lib/apps/fabro-cli/src/commands/run/wait.rs` test module | `StageOutcome`, `records::Conclusion`, `run_status::RunStatusRecord` | Output tests construct workflow-owned records directly. | Replace with shared fixture builders once conclusion DTOs move out. |
+| `lib/apps/fabro-cli/src/commands/run/run_progress/mod.rs` test module | `event::{Event, RunNoticeLevel, to_run_event, to_run_event_at}`, `outcome::billed_model_usage_from_llm` | Progress tests build engine events directly. | Replace with shared event fixture helpers after event DTO extraction. |
+| `lib/apps/fabro-cli/src/commands/run/run_progress/event.rs` test module | `event::{Event, to_run_event}` | Event rendering tests depend on engine event constructors. | Replace with shared event fixture helpers after event DTO extraction. |
+| `lib/apps/fabro-cli/src/commands/run/runner.rs` test module | `artifact_upload::StageArtifactUploader` | Worker tests still reach into workflow upload internals. | Keep with worker re-home work; not worth separating first. |
+| `lib/apps/fabro-cli/tests/it/workflow/real_cli.rs` | `context::Context`, `event::Emitter`, `handler::agent::{CodergenBackend, CodergenResult}`, `handler::llm::cli::AgentCliBackend` | Integration test exercises the real workflow engine directly through CLI harnesses. | Accept as engine integration coverage or move under workflow-owned test support later. |
+| `lib/apps/fabro-cli/tests/it/scenario/recovery.rs` | `operations::{RunTimeline, build_timeline}` | Scenario test inspects rewind timeline internals directly. | Replace after server-owned rewind/timeline APIs exist. |
## Follow-Up Order
diff --git a/docs/internal/event-schema-competitive-analysis.md b/docs/internal/event-schema-competitive-analysis.md
index 9763fdf30..60a1c02ab 100644
--- a/docs/internal/event-schema-competitive-analysis.md
+++ b/docs/internal/event-schema-competitive-analysis.md
@@ -48,9 +48,9 @@ That envelope is stronger than most comparator systems. It gives Fabro stable to
Relevant current Fabro sources:
- `docs-internal/events-strategy.md`
-- `lib/crates/fabro-workflow/src/event.rs`
-- `lib/crates/fabro-types/src/run_event/mod.rs`
-- `lib/crates/fabro-agent/src/types.rs`
+- `lib/components/fabro-workflow/src/event.rs`
+- `lib/foundation/fabro-types/src/run_event/mod.rs`
+- `lib/components/fabro-agent/src/types.rs`
## Comparison Matrix
diff --git a/docs/internal/events.md b/docs/internal/events.md
index 4af5ab491..7850a5411 100644
--- a/docs/internal/events.md
+++ b/docs/internal/events.md
@@ -1252,26 +1252,6 @@ Emitted when the agent detects a tool-use loop.
No properties.
-### `agent.turn.limit`
-
-Emitted when the agent reaches its maximum turn count.
-
-```json
-{
- "id": "...", "ts": "...", "run_id": "...",
- "event": "agent.turn.limit",
- "node_id": "code", "node_label": "code",
- "session_id": "ses_abc",
- "properties": {
- "max_turns": 25
- }
-}
-```
-
-| Property | Type | Description |
-|----------|------|-------------|
-| `max_turns` | number | Maximum turns allowed |
-
### `agent.skill.expanded`
```json
diff --git a/docs/internal/fabro-event-schema-v2-concrete-shape.md b/docs/internal/fabro-event-schema-v2-concrete-shape.md
index 4d8541b90..78134f619 100644
--- a/docs/internal/fabro-event-schema-v2-concrete-shape.md
+++ b/docs/internal/fabro-event-schema-v2-concrete-shape.md
@@ -269,21 +269,21 @@ The durable model remains simple: replay ordered events, no duplicate truth laye
An engineer implementing this proposal should make only these structural changes unless a later section explicitly says otherwise.
-1. Update [`RunEvent`](/Users/bhelmkamp/p/fabro-sh/fabro/lib/crates/fabro-types/src/run_event/mod.rs) to add:
+1. Update [`RunEvent`](/Users/bhelmkamp/p/fabro-sh/fabro/lib/foundation/fabro-types/src/run_event/mod.rs) to add:
- `stage_id`
- `parallel_group_id`
- `parallel_branch_id`
- `tool_call_id`
- `actor`
-2. Update `RunEvent::to_value()` and `RunEvent` parsing in [`run_event/mod.rs`](/Users/bhelmkamp/p/fabro-sh/fabro/lib/crates/fabro-types/src/run_event/mod.rs) so the new envelope fields serialize and deserialize.
-3. Extend `StoredEventFields` and `stored_event_fields()` in [`event.rs`](/Users/bhelmkamp/p/fabro-sh/fabro/lib/crates/fabro-workflow/src/event.rs) to populate:
+2. Update `RunEvent::to_value()` and `RunEvent` parsing in [`run_event/mod.rs`](/Users/bhelmkamp/p/fabro-sh/fabro/lib/foundation/fabro-types/src/run_event/mod.rs) so the new envelope fields serialize and deserialize.
+3. Extend `StoredEventFields` and `stored_event_fields()` in [`event.rs`](/Users/bhelmkamp/p/fabro-sh/fabro/lib/components/fabro-workflow/src/event.rs) to populate:
- `stage_id`
- `parallel_group_id`
- `parallel_branch_id`
- `tool_call_id` on tool-lifecycle events
- `actor` when there is a clear primary actor
These values should come from the emitter's current execution context for stage and parallel scope, and from event-specific payloads for `tool_call_id`.
-4. Leave [`EventEnvelope`](/Users/bhelmkamp/p/fabro-sh/fabro/lib/crates/fabro-store/src/types.rs) structurally unchanged:
+4. Leave [`EventEnvelope`](/Users/bhelmkamp/p/fabro-sh/fabro/lib/components/fabro-store/src/types.rs) structurally unchanged:
- `seq: u32`
- `payload: EventPayload`
5. Update API/SSE envelope serialization so wire JSON is flattened:
@@ -304,11 +304,11 @@ An engineer implementing this proposal should make only these structural changes
V2 should keep the current hand-coded domain split for prop structs:
-- run props in [`run.rs`](/Users/bhelmkamp/p/fabro-sh/fabro/lib/crates/fabro-types/src/run_event/run.rs)
-- stage and checkpoint props in [`stage.rs`](/Users/bhelmkamp/p/fabro-sh/fabro/lib/crates/fabro-types/src/run_event/stage.rs)
-- agent props in [`agent.rs`](/Users/bhelmkamp/p/fabro-sh/fabro/lib/crates/fabro-types/src/run_event/agent.rs)
-- infra/setup props in [`infra.rs`](/Users/bhelmkamp/p/fabro-sh/fabro/lib/crates/fabro-types/src/run_event/infra.rs)
-- parallel/interview/git/misc props in [`misc.rs`](/Users/bhelmkamp/p/fabro-sh/fabro/lib/crates/fabro-types/src/run_event/misc.rs)
+- run props in [`run.rs`](/Users/bhelmkamp/p/fabro-sh/fabro/lib/foundation/fabro-types/src/run_event/run.rs)
+- stage and checkpoint props in [`stage.rs`](/Users/bhelmkamp/p/fabro-sh/fabro/lib/foundation/fabro-types/src/run_event/stage.rs)
+- agent props in [`agent.rs`](/Users/bhelmkamp/p/fabro-sh/fabro/lib/foundation/fabro-types/src/run_event/agent.rs)
+- infra/setup props in [`infra.rs`](/Users/bhelmkamp/p/fabro-sh/fabro/lib/foundation/fabro-types/src/run_event/infra.rs)
+- parallel/interview/git/misc props in [`misc.rs`](/Users/bhelmkamp/p/fabro-sh/fabro/lib/foundation/fabro-types/src/run_event/misc.rs)
That split is part of the design quality. V2 should keep adding hand-coded prop structs, not collapse everything into generic maps.
@@ -374,7 +374,6 @@ V2 keeps the current durable family surface broadly intact.
- `agent.error`
- `agent.warning`
- `agent.loop.detected`
-- `agent.turn.limit`
- `agent.steering.injected`
- `agent.compaction.started`
- `agent.compaction.completed`
diff --git a/docs/internal/mcp-server-qa-test-plan.md b/docs/internal/mcp-server-qa-test-plan.md
index de2fcfc75..c5d7b8e74 100644
--- a/docs/internal/mcp-server-qa-test-plan.md
+++ b/docs/internal/mcp-server-qa-test-plan.md
@@ -1,6 +1,6 @@
# Fabro MCP Server — QA Test Plan
-One-time manual QA pass for the 5 tools exposed by `fabro-mcp-server`. Source of truth: `lib/crates/fabro-mcp-server/src/run_tools/`.
+One-time manual QA pass for the 5 tools exposed by `fabro-mcp-server`. Source of truth: `lib/apps/fabro-mcp-server/src/run_tools/`.
This plan is **not** a template for adding automated test coverage — it exists to drive a single hands-on sweep against a real running server. Tick boxes as scenarios pass; add notes inline for failures or surprising behavior. Open bugs/PRs for issues found; do not port these scenarios into the Rust test suite.
diff --git a/docs/internal/migrations-strategy.md b/docs/internal/migrations-strategy.md
index 1aa73370f..318463a58 100644
--- a/docs/internal/migrations-strategy.md
+++ b/docs/internal/migrations-strategy.md
@@ -9,7 +9,7 @@ Migrations are product-facing compatibility code. Treat them like startup and st
Each crate owns the migrations for the data it owns.
```text
-lib/crates//
+lib///
migrations/
YYYYMMDDSS_descriptive_name.rs
src/migrations.rs
diff --git a/docs/internal/plan-events-as-source-of-truth-follow-ups.md b/docs/internal/plan-events-as-source-of-truth-follow-ups.md
index 650eca25d..1ca2b9fc2 100644
--- a/docs/internal/plan-events-as-source-of-truth-follow-ups.md
+++ b/docs/internal/plan-events-as-source-of-truth-follow-ups.md
@@ -170,14 +170,14 @@ Required payload fields:
Emit from the same places that currently call `put_status`:
-- `lib/crates/fabro-workflow/src/operations/create.rs`
-- `lib/crates/fabro-workflow/src/operations/start.rs`
-- `lib/crates/fabro-workflow/src/operations/resume.rs`
-- `lib/crates/fabro-workflow/src/pipeline/finalize.rs`
-- `lib/crates/fabro-workflow/src/lifecycle/disk.rs`
+- `lib/components/fabro-workflow/src/operations/create.rs`
+- `lib/components/fabro-workflow/src/operations/start.rs`
+- `lib/components/fabro-workflow/src/operations/resume.rs`
+- `lib/components/fabro-workflow/src/pipeline/finalize.rs`
+- `lib/components/fabro-workflow/src/lifecycle/disk.rs`
- CLI administrative flows that directly mutate status:
- - `lib/crates/fabro-cli/src/commands/runs/rm.rs`
- - `lib/crates/fabro-cli/src/commands/run/rewind.rs`
+ - `lib/apps/fabro-cli/src/commands/runs/rm.rs`
+ - `lib/apps/fabro-cli/src/commands/run/rewind.rs`
### 2. Enrich `checkpoint.completed` to carry a full checkpoint snapshot
@@ -200,11 +200,11 @@ Add fields covering:
Emitter seam:
-- `lib/crates/fabro-workflow/src/lifecycle/event.rs`
+- `lib/components/fabro-workflow/src/lifecycle/event.rs`
Producer seam for the source checkpoint object:
-- `lib/crates/fabro-workflow/src/lifecycle/disk.rs`
+- `lib/components/fabro-workflow/src/lifecycle/disk.rs`
Design rule:
@@ -231,7 +231,7 @@ Add:
Producer seam:
-- `lib/crates/fabro-workflow/src/pipeline/pull_request.rs`
+- `lib/components/fabro-workflow/src/pipeline/pull_request.rs`
After this lands, `put_pull_request` should become removable during the later memoized-state cutover.
@@ -245,7 +245,7 @@ Do not add a separate storage-shaped event. The final patch is run-level termina
Enrich `run.completed`, using the patch already computed from:
-- `lib/crates/fabro-workflow/src/lifecycle/git.rs`
+- `lib/components/fabro-workflow/src/lifecycle/git.rs`
Required payload:
@@ -287,9 +287,9 @@ Required projected output:
Likely seams:
-- `lib/crates/fabro-workflow/src/handler/agent.rs`
-- `lib/crates/fabro-workflow/src/handler/llm/api.rs`
-- `lib/crates/fabro-workflow/src/pipeline/retro.rs` if retro uses the same forwarded agent session path
+- `lib/components/fabro-workflow/src/handler/agent.rs`
+- `lib/components/fabro-workflow/src/handler/llm/api.rs`
+- `lib/components/fabro-workflow/src/pipeline/retro.rs` if retro uses the same forwarded agent session path
- any CLI-backed LLM path if it still produces `provider_used.json`
Do not keep the current “read JSON sidecar, then `put_node_provider_used`” pattern once this event exists.
@@ -304,7 +304,7 @@ Use the existing terminal parallel event rather than adding a storage-shaped eve
Add to `parallel.completed`, emitted from:
-- `lib/crates/fabro-workflow/src/handler/parallel.rs`
+- `lib/components/fabro-workflow/src/handler/parallel.rs`
Required new payload:
@@ -346,19 +346,19 @@ Likely files to touch:
- `docs-internal/events.md`
- `docs-internal/run-directory-keys.md`
- `docs-internal/events-strategy.md`
-- `lib/crates/fabro-workflow/src/event.rs`
-- `lib/crates/fabro-workflow/src/lifecycle/event.rs`
-- `lib/crates/fabro-workflow/src/lifecycle/disk.rs`
-- `lib/crates/fabro-workflow/src/lifecycle/git.rs`
-- `lib/crates/fabro-workflow/src/operations/create.rs`
-- `lib/crates/fabro-workflow/src/operations/start.rs`
-- `lib/crates/fabro-workflow/src/operations/resume.rs`
-- `lib/crates/fabro-workflow/src/pipeline/finalize.rs`
-- `lib/crates/fabro-workflow/src/pipeline/pull_request.rs`
-- `lib/crates/fabro-workflow/src/handler/agent.rs`
-- `lib/crates/fabro-workflow/src/handler/parallel.rs`
-- `lib/crates/fabro-cli/src/commands/runs/rm.rs`
-- `lib/crates/fabro-cli/src/commands/run/rewind.rs`
+- `lib/components/fabro-workflow/src/event.rs`
+- `lib/components/fabro-workflow/src/lifecycle/event.rs`
+- `lib/components/fabro-workflow/src/lifecycle/disk.rs`
+- `lib/components/fabro-workflow/src/lifecycle/git.rs`
+- `lib/components/fabro-workflow/src/operations/create.rs`
+- `lib/components/fabro-workflow/src/operations/start.rs`
+- `lib/components/fabro-workflow/src/operations/resume.rs`
+- `lib/components/fabro-workflow/src/pipeline/finalize.rs`
+- `lib/components/fabro-workflow/src/pipeline/pull_request.rs`
+- `lib/components/fabro-workflow/src/handler/agent.rs`
+- `lib/components/fabro-workflow/src/handler/parallel.rs`
+- `lib/apps/fabro-cli/src/commands/runs/rm.rs`
+- `lib/apps/fabro-cli/src/commands/run/rewind.rs`
- tests in `fabro-workflow`, `fabro-cli`, and `fabro-store`
## Phases
diff --git a/docs/internal/run-directory-keys.md b/docs/internal/run-directory-keys.md
index 91ceeb2a8..1b78fd560 100644
--- a/docs/internal/run-directory-keys.md
+++ b/docs/internal/run-directory-keys.md
@@ -5,8 +5,8 @@ This document maps the files that still live under a run scratch directory. Dura
Scope:
- Scratch root: `~/.fabro/scratch/YYYYMMDD-{run_id}/`
- This covers local run files only
-- Persistent store keys live in `lib/crates/fabro-store/src/keys.rs`
-- Artifact object-store keys live in `lib/crates/fabro-store/src/artifact_store.rs`
+- Persistent store keys live in `lib/components/fabro-store/src/keys.rs`
+- Artifact object-store keys live in `lib/components/fabro-store/src/artifact_store.rs`
There is no `_init.json` anymore. Run existence in the database is determined by stored run events, and local scratch directories are managed separately under `scratch/`.
diff --git a/docs/internal/slow-test-opportunities-2026-04-07.md b/docs/internal/slow-test-opportunities-2026-04-07.md
index 2fe511ff4..790a80c20 100644
--- a/docs/internal/slow-test-opportunities-2026-04-07.md
+++ b/docs/internal/slow-test-opportunities-2026-04-07.md
@@ -22,7 +22,7 @@ Method:
### [x] 1. Change two slow `exec` mock responses from retriable `500` to non-retriable `400`
Files:
-- `lib/crates/fabro-cli/tests/it/cmd/exec.rs`
+- `lib/apps/fabro-cli/tests/it/cmd/exec.rs`
Measured evidence:
- `fabro-cli::it::cmd::exec::exec_cli_server_target_overrides_configured_server_target`: `6.858s` median
@@ -32,7 +32,7 @@ Measured evidence:
- mocked `400`: `0.053s` median
Implementation status:
-- Implemented in `lib/crates/fabro-cli/tests/it/cmd/exec.rs`
+- Implemented in `lib/apps/fabro-cli/tests/it/cmd/exec.rs`
- Verified with `ulimit -n 4096` via 5 targeted nextest runs per test
- Post-change nextest exec-time medians:
- `exec_server_target_uses_remote_transport_instead_of_local_api_key_resolution`: `1.580s`
@@ -57,7 +57,7 @@ Cons:
### 2. Short-circuit delete-path worker grace for already-terminal runs
Files:
-- `lib/crates/fabro-server/src/server.rs`
+- `lib/apps/fabro-server/src/server.rs`
Measured evidence:
- `fabro-cli::it::cmd::system_prune::system_prune_yes_deletes_matching_runs`: `10.477s`
@@ -87,11 +87,11 @@ Cons:
### [x] 3. Collapse the five abnormally slow `help` integration tests into one smoke test or a lighter harness
Files:
-- `lib/crates/fabro-cli/tests/it/cmd/artifact.rs`
-- `lib/crates/fabro-cli/tests/it/cmd/artifact_list.rs`
-- `lib/crates/fabro-cli/tests/it/cmd/artifact_cp.rs`
-- `lib/crates/fabro-cli/tests/it/cmd/config.rs`
-- `lib/crates/fabro-cli/tests/it/cmd/attach.rs`
+- `lib/apps/fabro-cli/tests/it/cmd/artifact.rs`
+- `lib/apps/fabro-cli/tests/it/cmd/artifact_list.rs`
+- `lib/apps/fabro-cli/tests/it/cmd/artifact_cp.rs`
+- `lib/apps/fabro-cli/tests/it/cmd/config.rs`
+- `lib/apps/fabro-cli/tests/it/cmd/attach.rs`
Measured evidence:
- Slow `help` tests:
@@ -131,8 +131,8 @@ Cons:
### [x] 4. Replace `doctor_no_color_when_no_color_set` with a render-path assertion
Files:
-- `lib/crates/fabro-cli/tests/it/cmd/doctor.rs`
-- `lib/crates/fabro-util/src/check_report.rs`
+- `lib/apps/fabro-cli/tests/it/cmd/doctor.rs`
+- `lib/foundation/fabro-util/src/check_report.rs`
Measured evidence:
- `fabro-cli::it::cmd::doctor::doctor_no_color_when_no_color_set`: `5.131s`
@@ -144,7 +144,7 @@ Estimated impact:
Implementation status:
- Implemented by deleting `fabro-cli::it::cmd::doctor::doctor_no_color_when_no_color_set`
-- Added a unit-level render assertion in `lib/crates/fabro-cli/src/commands/doctor.rs`:
+- Added a unit-level render assertion in `lib/apps/fabro-cli/src/commands/doctor.rs`:
- `render_report_text_without_color_has_no_ansi`
- Verified with `ulimit -n 4096; cargo nextest run -p fabro-cli render_report_text_without_color_has_no_ansi --status-level fail --final-status-level fail --show-progress none`
- Verification result: `1 passed`
@@ -166,8 +166,8 @@ Cons:
### [x] 5. Fix local Unix-socket autostart so it doesn't burn the full 5s readiness wait
Files:
-- `lib/crates/fabro-cli/src/server_client.rs`
-- `lib/crates/fabro-cli/tests/it/cmd/server_start.rs`
+- `lib/apps/fabro-cli/src/server_client.rs`
+- `lib/apps/fabro-cli/tests/it/cmd/server_start.rs`
Measured evidence:
- Pre-fix 5-run timing for `fabro-cli::it::cmd::server_start::concurrent_autostart_converges_on_one_shared_daemon_and_cleans_up`:
@@ -197,7 +197,7 @@ Implementation status:
- Implemented by splitting the Unix-socket connection path into:
- a single immediate health probe before autostart
- the existing retrying readiness wait after autostart
-- Kept the original integration test coverage in `lib/crates/fabro-cli/tests/it/cmd/server_start.rs`
+- Kept the original integration test coverage in `lib/apps/fabro-cli/tests/it/cmd/server_start.rs`
- Verified with `ulimit -n 4096; cargo nextest run -p fabro-cli concurrent_autostart_converges_on_one_shared_daemon_and_cleans_up --status-level fail --final-status-level fail --show-progress none`
- Verification result: `1 passed`
- Post-change 5-run timing for `fabro-cli::it::cmd::server_start::concurrent_autostart_converges_on_one_shared_daemon_and_cleans_up`:
@@ -217,7 +217,7 @@ Implementation status:
### [x] 6. Collapse three lightweight `attach` smoke tests into one scenario-style test
Files:
-- `lib/crates/fabro-cli/tests/it/cmd/attach.rs`
+- `lib/apps/fabro-cli/tests/it/cmd/attach.rs`
Measured evidence:
- `attach_requires_run_arg`: `1.595s`
@@ -230,7 +230,7 @@ Estimated impact:
- Conservative recoverable time: about `3.15s`
Implementation status:
-- Implemented by removing the 3 command-owned smoke tests from `lib/crates/fabro-cli/tests/it/cmd/attach.rs`
+- Implemented by removing the 3 command-owned smoke tests from `lib/apps/fabro-cli/tests/it/cmd/attach.rs`
- Added `fabro-cli::it::scenario::smoke::attach_smoke_covers_arg_validation_and_remote_server_behaviors`
- Verified with `ulimit -n 4096; cargo nextest run -p fabro-cli attach_smoke_covers_arg_validation_and_remote_server_behaviors --status-level fail --final-status-level fail --show-progress none`
- Verification result: `1 passed`
@@ -256,7 +256,7 @@ Cons:
### [x] 7. Collapse the three `completion` tests
Files:
-- `lib/crates/fabro-cli/tests/it/cmd/completion.rs`
+- `lib/apps/fabro-cli/tests/it/cmd/completion.rs`
Measured evidence:
- `completion::generates_zsh_completions`: `1.567s`
@@ -295,7 +295,7 @@ Cons:
### [x] 8. Remove or merge the duplicate attach replay test
Files:
-- `lib/crates/fabro-cli/tests/it/cmd/attach.rs`
+- `lib/apps/fabro-cli/tests/it/cmd/attach.rs`
Measured evidence:
- `attach_replays_completed_detached_run`: `2.696s`
@@ -303,7 +303,7 @@ Measured evidence:
- The two tests are currently identical in code and assertions
Implementation status:
-- Implemented by removing the duplicate test from `lib/crates/fabro-cli/tests/it/cmd/attach.rs`
+- Implemented by removing the duplicate test from `lib/apps/fabro-cli/tests/it/cmd/attach.rs`
- Verified with `ulimit -n 4096; cargo nextest run -p fabro-cli attach_replays_completed_detached_run --status-level fail --final-status-level fail --show-progress none`
- Verification result: `1 passed`
@@ -325,7 +325,7 @@ Cons:
### [x] 9. Make `attach_before_completion_streams_to_finished_state` event-driven instead of sleep-driven
Files:
-- `lib/crates/fabro-cli/tests/it/cmd/attach.rs`
+- `lib/apps/fabro-cli/tests/it/cmd/attach.rs`
Measured evidence:
- `attach_before_completion_streams_to_finished_state`: `3.043s`
@@ -333,7 +333,7 @@ Measured evidence:
- `write_gated_workflow()` adds another fixed `sleep 0.2`
Implementation status:
-- Implemented by replacing the fixed 1-second gate-release sleep with a real attach-output signal in `lib/crates/fabro-cli/tests/it/cmd/attach.rs`
+- Implemented by replacing the fixed 1-second gate-release sleep with a real attach-output signal in `lib/apps/fabro-cli/tests/it/cmd/attach.rs`
- The test now spawns `fabro attach`, waits for replayed stderr output (`✓ start`), then releases the workflow gate
- Verified with `ulimit -n 4096; cargo nextest run -p fabro-cli attach_before_completion_streams_to_finished_state --status-level fail --final-status-level fail --show-progress none`
- Verification result: `1 passed`
@@ -361,14 +361,14 @@ Cons:
### [x] 10. Remove or parameterize the fixed `sleep 0.2` in `write_gated_workflow()`
Files:
-- `lib/crates/fabro-cli/tests/it/cmd/support.rs`
+- `lib/apps/fabro-cli/tests/it/cmd/support.rs`
Measured evidence:
- `write_gated_workflow()` hardcodes `sleep 0.2`
- The helper is used in 6 cmd tests
Implementation status:
-- Implemented by deleting the fixed `sleep 0.2` from `write_gated_workflow()` in `lib/crates/fabro-cli/tests/it/cmd/support.rs`
+- Implemented by deleting the fixed `sleep 0.2` from `write_gated_workflow()` in `lib/apps/fabro-cli/tests/it/cmd/support.rs`
- Verified with `ulimit -n 4096; cargo nextest run -p fabro-cli -E 'test(attach_before_completion_streams_to_finished_state) | test(ctrl_c_cancels_active_run_via_server) | test(rm_force_terminates_active_run_worker) | test(start_rejects_already_active_or_completed_run) | test(start_runs_under_server_ownership_without_launcher_record)' --status-level fail --final-status-level fail --show-progress none`
- Verification result: `5 passed`
- Targeted 5-pass benchmark with `ulimit -n 4096` over the 5 tests that currently use the helper:
diff --git a/docs/internal/testing-strategy.md b/docs/internal/testing-strategy.md
index 5ec1534f5..b5fa9488a 100644
--- a/docs/internal/testing-strategy.md
+++ b/docs/internal/testing-strategy.md
@@ -37,7 +37,7 @@ This is the right place for:
If the setup requires direct writes to internal run files or runtime directories, prefer this layer over `fabro-cli/tests/it`.
-### `lib/crates/fabro-cli/tests/it/cmd/*.rs`
+### `lib/apps/fabro-cli/tests/it/cmd/*.rs`
`cmd/*` tests are command-owned tests.
@@ -64,7 +64,7 @@ Bad command-test assertions:
- behavior primarily owned by another command
- runtime internals that only exist because the test planted them by hand
-### `lib/crates/fabro-cli/tests/it/workflow/*.rs`
+### `lib/apps/fabro-cli/tests/it/workflow/*.rs`
`workflow/*` tests are black-box workflow-behavior tests.
@@ -79,7 +79,7 @@ Examples:
These tests should focus on the workflow's observed behavior, not on CLI help text or command argument validation.
-### `lib/crates/fabro-cli/tests/it/scenario/*.rs`
+### `lib/apps/fabro-cli/tests/it/scenario/*.rs`
`scenario/*` tests are cross-command lifecycle tests.
diff --git a/docs/public/agents/outputs.mdx b/docs/public/agents/outputs.mdx
index 28e3659a6..b726a9ffd 100644
--- a/docs/public/agents/outputs.mdx
+++ b/docs/public/agents/outputs.mdx
@@ -66,7 +66,7 @@ JSON objects without recognized fields are ignored.
### Validated routing output
-Set `output_schema="routing"` on an agent or prompt node to require Fabro's built-in routing directive schema:
+Set `output_schema="routing"` on an agent, prompt, or command node to require Fabro's built-in routing directive schema:
```dot
review [
@@ -81,7 +81,9 @@ With `output_schema="routing"`, the routing JSON must be an object with at least
Validated routing uses the same reverse scan as normal routing extraction: Fabro validates the last parsable JSON object that contains a recognized routing field. If a routing object is present but malformed or has invalid field types, Fabro repairs that response instead of falling through to a file fallback.
-Fabro repairs invalid structured output inside the same LLM context before failing the node. For prompt nodes, Fabro appends the invalid assistant response and a corrective user message to the same message list. For agent nodes using the API backend, Fabro sends the corrective message to the same live agent session. `output_retries` controls these repair turns and defaults to `2`; `output_retries=0` validates once and fails without a repair turn. Negative values are treated as `0`. These repair turns are separate from workflow `max_retries` and do not consume node retry attempts.
+Fabro repairs invalid structured output inside the same LLM context before failing an agent or prompt node. For prompt nodes, Fabro appends the invalid assistant response and a corrective user message to the same message list. For agent nodes using the API backend, Fabro sends the corrective message to the same live agent session. `output_retries` controls these repair turns and defaults to `2`; `output_retries=0` validates once and fails without a repair turn. Negative values are treated as `0`. These repair turns are separate from workflow `max_retries` and do not consume node retry attempts.
+
+Command nodes instead validate only after an exit-code-`0` script, applying the same reverse scan to merged stdout and stderr. Print the intended JSON object last. Invalid output fails deterministically without a repair turn, command retry, or `status.json` fallback; `output_retries`, `retry_policy`, and `max_retries` do not retry the validation failure. Nonzero exits keep their normal command failure behavior without schema validation.
### Routing fallback sources
@@ -97,7 +99,7 @@ This fallback chain applies to normal routing extraction and to `output_schema="
The last-file fallback only reads `.json` and `.md` files (case-insensitive), and the routing JSON must be the final JSON object in the file, with only whitespace after it. Fabro ignores other file types and routing JSON followed by any other content. These restrictions do not apply to the dedicated `status.json` fallback.
-Prompt nodes do not use file fallbacks; they validate or extract routing directives from the response text only.
+Prompt nodes do not use file fallbacks; they validate or extract routing directives from the response text only. Command nodes likewise have no file fallback and validate only their merged stdout and stderr.
If no source provides routing directives, the transition falls through to condition matching, unconditional edges, or weight-based tiebreaking as described in [Transitions](/workflows/transitions).
@@ -121,7 +123,7 @@ review -> approve [label="Approve"]
## Custom structured outputs
-Agent and prompt nodes can also validate their final JSON object against a JSON Schema file:
+Agent, prompt, and command nodes can also validate their final JSON object against a JSON Schema file:
```dot
audit [
@@ -132,9 +134,9 @@ audit [
]
```
-`output_schema="@path/to/schema.json"` uses the same workflow file-reference rules as prompt files: the schema is loaded relative to the workflow file and inlined before execution. The final JSON object in the LLM response is validated with `jsonschema`.
+`output_schema="@path/to/schema.json"` uses the same workflow file-reference rules as prompt files: the schema is loaded relative to the workflow file and inlined before execution. The final JSON object in the LLM response, or in a successful command's merged stdout and stderr, is validated with `jsonschema`.
-Custom schema validation only reads the response text. It does not fall back to `status.json` or the last file touched by the agent.
+Custom schema validation only reads response or command output text. It does not fall back to `status.json` or the last file touched by the agent.
When custom schema validation succeeds, Fabro stores the parsed JSON value in context at:
@@ -142,12 +144,12 @@ When custom schema validation succeeds, Fabro stores the parsed JSON value in co
|---|---|
| `output.{node_id}` | The parsed JSON object that matched the custom schema |
-For example, node `audit` writes its parsed custom output to `output.audit`. Fabro still stores the raw response text at `response.audit`.
+For example, node `audit` writes its parsed custom output to `output.audit`. Fabro still stores raw LLM response text at `response.audit`; command output remains available through `command.output`.
-If custom schema validation fails, Fabro sends concise validation feedback to the same prompt conversation or agent session and asks for corrected JSON. After `output_retries` repair turns are exhausted, the node fails terminally with `output schema validation failed after N repair attempt(s)`.
+If custom schema validation fails for an agent or prompt node, Fabro sends concise validation feedback to the same prompt conversation or agent session and asks for corrected JSON. After `output_retries` repair turns are exhausted, the node fails terminally with `output schema validation failed after N repair attempt(s)`. A command node instead fails deterministically after its first validation, without a repair turn or command retry.
-Structured output validation currently applies to agent and prompt nodes. `backend="acp"` does not support `output_schema` in this release. Custom schemas update `output.{node_id}`; routing schemas update routing fields and `context_updates` instead.
+Structured output validation applies to agent, prompt, and command nodes. `backend="acp"` does not support `output_schema` in this release. Custom schemas update `output.{node_id}`; routing schemas update routing fields and merge `context_updates` as flat context keys that edge conditions can read. Edge conditions cannot traverse the custom `output.{node_id}` object.
## Output logging
diff --git a/docs/public/agents/subagents.mdx b/docs/public/agents/subagents.mdx
index 11cf30c38..597bd96e3 100644
--- a/docs/public/agents/subagents.mdx
+++ b/docs/public/agents/subagents.mdx
@@ -44,7 +44,6 @@ Sub-agent failures do not automatically fail the parent stage. The parent receiv
Common cases:
-- **Hits `max_turns`** -- returns normally with its last output
- **Panics or errors** -- returned as a failed `wait` result
- **`spawn_agent` fails** -- returned immediately as a tool result
@@ -97,5 +96,5 @@ Sub-agents are most useful for:
Use [child runs](/execution/child-runs) instead when the delegated work should be a separate Fabro run with its own workflow, lifecycle, sandbox, checkpoints, and outputs.
-Sub-agents run with no turn limit by default. Pass `max_turns` when you want predictable cost or time bounds. All active sub-agents are cleaned up automatically when the parent session closes.
+Sub-agents run until they complete, fail, are cancelled, or hit the session's wall-clock timeout. All active sub-agents are cleaned up automatically when the parent session closes.
diff --git a/docs/public/api-reference/client-sdks.mdx b/docs/public/api-reference/client-sdks.mdx
index e0fcb4a94..b46291669 100644
--- a/docs/public/api-reference/client-sdks.mdx
+++ b/docs/public/api-reference/client-sdks.mdx
@@ -43,7 +43,7 @@ The `fabro-api` crate generates Rust structs, enums, and a `reqwest`-based HTTP
A `build.rs` script reads `docs/public/api-reference/fabro-api.yaml`, patches it from OpenAPI 3.1 to 3.0 for progenitor compatibility, and generates both types and a client. The generated code is written to `OUT_DIR` and included via:
```rust
-// lib/crates/fabro-api/src/lib.rs
+// lib/foundation/fabro-api/src/lib.rs
include!(concat!(env!("OUT_DIR"), "/codegen.rs"));
```
diff --git a/docs/public/api-reference/fabro-api.yaml b/docs/public/api-reference/fabro-api.yaml
index a2e5af539..519ee4188 100644
--- a/docs/public/api-reference/fabro-api.yaml
+++ b/docs/public/api-reference/fabro-api.yaml
@@ -8238,6 +8238,7 @@ components:
- reasoning
- reasoning_effort
- prompt_cache
+ - cache_control_breakpoints
- sampling_params
properties:
tools:
@@ -8254,6 +8255,12 @@ components:
prompt_cache:
type: boolean
description: Whether the model endpoint supports prompt caching.
+ cache_control_breakpoints:
+ type: boolean
+ description: >-
+ Whether the endpoint only caches when the request marks the
+ cacheable prefix with Anthropic-style cache_control breakpoints
+ (e.g. Claude via OpenRouter).
sampling_params:
type: boolean
description: Whether the model accepts classic sampling parameters (temperature, top_p).
@@ -10541,7 +10548,11 @@ components:
oneOf:
- $ref: "#/components/schemas/TodoListProjection"
- type: "null"
- description: Projected todo / task list for this stage.
+ description: |
+ Todo / task list owned by this stage's root agent session. OpenAI
+ child sessions have separate per-session plans that do not appear
+ here. Anthropic task lists are root-scoped and shared with child
+ sessions, so child mutations of that shared list do appear here.
subagents:
type: array
description: Subagents spawned by this stage, in replay/insertion order.
diff --git a/docs/public/changelog/2026-03-23.mdx b/docs/public/changelog/2026-03-23.mdx
index e3d47ecda..359f5bbc1 100644
--- a/docs/public/changelog/2026-03-23.mdx
+++ b/docs/public/changelog/2026-03-23.mdx
@@ -5,7 +5,7 @@ date: "2026-03-23"
## Unlimited agent tool rounds
-Agent stages no longer have an artificial cap on tool rounds per input or subagent turns. Previously, the default limits could cause agents to stop mid-task on complex operations. Both `max_tool_rounds_per_input` and subagent `max_turns` now default to unlimited, so agents run until they complete their work or hit the context window.
+Agent stages no longer have an artificial cap on tool rounds per input or subagent turns, so agents run until they complete their work or are interrupted.
## More
diff --git a/docs/public/examples/repl-handoff.mdx b/docs/public/examples/repl-handoff.mdx
index a89942013..bf05c425e 100644
--- a/docs/public/examples/repl-handoff.mdx
+++ b/docs/public/examples/repl-handoff.mdx
@@ -73,7 +73,7 @@ Use Claude Code's plan mode to collaborate on an implementation plan. Go back an
> /plan Add retry logic to the webhook delivery system
Planning...
-1. Add RetryPolicy struct to lib/crates/fabro-webhooks/src/policy.rs
+1. Add RetryPolicy struct to lib/components/fabro-webhooks/src/policy.rs
2. Implement exponential backoff with jitter
3. Add max_retries field to WebhookConfig
4. Write tests for retry timing, max attempts, and jitter bounds
diff --git a/docs/public/reference/dot-language.mdx b/docs/public/reference/dot-language.mdx
index 3dccb9734..fb6152163 100644
--- a/docs/public/reference/dot-language.mdx
+++ b/docs/public/reference/dot-language.mdx
@@ -206,7 +206,7 @@ Start nodes can also be identified by ID (`start` or `Start`). Exit nodes can be
| `model` | String | Explicit model ID (overrides stylesheet) |
| `provider` | String | Explicit provider name (overrides stylesheet). Auto-inferred from the model catalog when omitted. |
| `project_memory` | Boolean | When `true` (default), prompt nodes discover and include project docs (`AGENTS.md`, `CLAUDE.md`, etc.) as a system prompt. Set to `false` to disable. |
-| `output_schema` | String | Optional structured output validation. Use `routing` for Fabro's built-in routing directive schema, `@path/to/schema.json` for a JSON Schema file, or an inline JSON Schema object string. Supported on agent and prompt nodes. |
+| `output_schema` | String | Optional structured output validation. Use `routing` for Fabro's built-in routing directive schema, `@path/to/schema.json` for a JSON Schema file, or an inline JSON Schema object string. Supported on agent, prompt, and command nodes. |
| `output_retries` | Integer | Corrective structured-output turns inside the same prompt conversation or agent session. Default `2`; `0` validates once and fails without repair; negative values are treated as `0`. Separate from `max_retries`. |
| `backend` | String | Agent execution backend: `api` (default) or `acp`. `api` runs Fabro's tool loop through provider APIs; `acp` runs an Agent Client Protocol stdio agent inside the active sandbox. Prompt nodes are API-only. See [Agents — Backends](/core-concepts/agents#backends). |
| `acp.command` | String | Shell command for nodes with `backend="acp"`. Mutually exclusive with `acp.config`. The value is always parsed as a command string, not JSON. |
@@ -214,7 +214,7 @@ Start nodes can also be identified by ID (`start` or `Start`). Exit nodes can be
#### Structured output validation
-`output_schema` opts an agent or prompt node into strict JSON validation:
+`output_schema` opts an agent, prompt, or command node into strict JSON validation:
```dot
review [
@@ -236,6 +236,8 @@ audit [
- `output_retries` defaults to `2` and controls only these corrective structured-output turns. Negative values are treated as `0`. It is not the same as `max_retries` and does not consume workflow retry attempts.
- Custom schema output is stored in context at `output.{node_id}`. Routing schema output updates routing fields and any `context_updates`.
- Agent routing fallbacks still apply to `output_schema="routing"`: response text first, then `status.json`, then the last file touched by the agent. The last-file fallback only accepts `.json` and `.md` files (case-insensitive) whose final JSON object contains the routing directive; only whitespace may follow it. Custom schemas and prompt nodes validate response text only.
+- Command nodes validate merged stdout and stderr only after the script exits with code `0`, using the same object selection as agents and prompts: custom schemas validate the last JSON object, and `routing` validates the last JSON object containing a recognized routing field. Print the intended JSON object last. A validation error is a deterministic, non-retryable failure with no repair turn or `status.json` fallback. `output_retries`, `retry_policy`, and `max_retries` do not retry it. Nonzero exits retain normal command failure behavior without schema validation.
+- For commands, custom schema output is stored at `output.{node_id}`; edge conditions cannot traverse into its fields. The `routing` schema applies routing fields and merges `context_updates` into flat context keys, which conditions can read (for example, `context.kept_count`).
- `backend="acp"` with `output_schema` is unsupported in this release.
### Command nodes
@@ -244,6 +246,7 @@ audit [
|---|---|---|
| `script` | String | Shell command to execute |
| `language` | String | `"shell"` (default) or `"python"` |
+| `output_schema` | String | Optional structured output validation. Accepts `routing`, `@path/to/schema.json`, or an inline JSON Schema object string. See [Structured output validation](#structured-output-validation). |
### Parallel (fan-out) nodes
diff --git a/docs/public/reference/sdk.mdx b/docs/public/reference/sdk.mdx
index 4332f3adc..9f88c7696 100644
--- a/docs/public/reference/sdk.mdx
+++ b/docs/public/reference/sdk.mdx
@@ -84,7 +84,7 @@ pub fn new(
| Method | Description |
|---|---|
| `initialize().await` | Discovers project docs, skills, and MCP servers. Call before `process_input`. |
-| `process_input(input).await` | Sends user input and runs the agent loop until the model stops or a limit is hit. |
+| `process_input(input).await` | Sends user input and runs the agent loop until the model stops, the session is interrupted, or an error occurs. |
| `close()` | Ends the session and emits `SessionEnded`. |
| `interrupt()` | Cancels the current `process_input` call. |
| `cancel_token()` | Returns a `CancellationToken` for external cancellation. |
@@ -110,8 +110,6 @@ All fields are public. Key settings with their defaults:
| Field | Default | Description |
|---|---|---|
-| `max_turns` | `0` (unlimited) | Maximum conversation turns before stopping. |
-| `max_tool_rounds_per_input` | `200` | Maximum tool execution rounds per `process_input` call. |
| `default_command_timeout_ms` | `10,000` | Default timeout for Bash tool commands. |
| `max_command_timeout_ms` | `600,000` | Maximum allowed timeout for Bash tool commands. |
| `enable_loop_detection` | `true` | Detect and break out of repetitive tool call patterns. |
@@ -221,7 +219,6 @@ Key `AgentEvent` variants:
| `ToolCallCompleted { tool_name, tool_call_id, output, is_error }` | A tool call finished. |
| `Error { error }` | An `AgentError` occurred. |
| `LoopDetected` | The agent is repeating itself. |
-| `TurnLimitReached { max_turns }` | Turn limit hit. |
| `CompactionStarted` / `CompactionCompleted` | Context window compaction. |
| `SubAgentSpawned` / `SubAgentCompleted` | Sub-agent lifecycle. |
| `McpServerReady` / `McpServerFailed` | MCP server connection status. |
@@ -296,7 +293,7 @@ All fallible `Session` methods return `Result`:
| `SessionClosed` | `process_input` was called on a closed session. |
| `InvalidState(String)` | The session is in an unexpected state. |
| `ToolExecution(String)` | A tool execution failed. |
-| `Interrupted(InterruptReason)` | The session was cancelled (`Cancelled`) or timed out (`WallClockTimeout`). |
+| `Interrupted(InterruptReason)` | The session was cancelled or timed out. |
---
diff --git a/lib/crates/fabro-cli/Cargo.toml b/lib/apps/fabro-cli/Cargo.toml
similarity index 55%
rename from lib/crates/fabro-cli/Cargo.toml
rename to lib/apps/fabro-cli/Cargo.toml
index 4c84def39..44c9982bc 100644
--- a/lib/crates/fabro-cli/Cargo.toml
+++ b/lib/apps/fabro-cli/Cargo.toml
@@ -18,40 +18,40 @@ sleep_inhibitor = ["dep:core-foundation"]
workspace = true
[dependencies]
-fabro-auth = { path = "../fabro-auth" }
-fabro-config = { path = "../fabro-config" }
-fabro-environment = { path = "../fabro-environment" }
-fabro-llm = { path = "../fabro-llm" }
-fabro-model = { path = "../fabro-model" }
-fabro-oauth = { path = "../fabro-oauth" }
-fabro-github = { path = "../fabro-github" }
-fabro-agent = { path = "../fabro-agent" }
-fabro-dump = { path = "../fabro-dump" }
-fabro-hooks = { path = "../fabro-hooks" }
-fabro-install = { path = "../fabro-install" }
-fabro-interview = { path = "../fabro-interview" }
-fabro-mcp = { path = "../fabro-mcp" }
+fabro-auth = { path = "../../foundation/fabro-auth" }
+fabro-config = { path = "../../foundation/fabro-config" }
+fabro-environment = { path = "../../components/fabro-environment" }
+fabro-llm = { path = "../../components/fabro-llm" }
+fabro-model = { path = "../../foundation/fabro-model" }
+fabro-oauth = { path = "../../foundation/fabro-oauth" }
+fabro-github = { path = "../../components/fabro-github" }
+fabro-agent = { path = "../../components/fabro-agent" }
+fabro-dump = { path = "../../components/fabro-dump" }
+fabro-hooks = { path = "../../components/fabro-hooks" }
+fabro-install = { path = "../../components/fabro-install" }
+fabro-interview = { path = "../../components/fabro-interview" }
+fabro-mcp = { path = "../../components/fabro-mcp" }
fabro-mcp-server = { path = "../fabro-mcp-server" }
-fabro-manifest = { path = "../fabro-manifest" }
-fabro-proc = { path = "../fabro-proc" }
-fabro-sandbox = { path = "../fabro-sandbox", features = ["daytona"] }
-fabro-checkpoint = { path = "../fabro-checkpoint" }
-fabro-graphviz = { path = "../fabro-graphviz" }
-fabro-validate = { path = "../fabro-validate" }
-fabro-workflow = { path = "../fabro-workflow" }
+fabro-manifest = { path = "../../components/fabro-manifest" }
+fabro-proc = { path = "../../foundation/fabro-proc" }
+fabro-sandbox = { path = "../../components/fabro-sandbox", features = ["daytona"] }
+fabro-checkpoint = { path = "../../components/fabro-checkpoint" }
+fabro-graphviz = { path = "../../components/fabro-graphviz" }
+fabro-validate = { path = "../../components/fabro-validate" }
+fabro-workflow = { path = "../../components/fabro-workflow" }
fabro-server = { path = "../fabro-server" }
-fabro-client = { path = "../fabro-client" }
-fabro-api = { path = "../fabro-api" }
-fabro-telemetry = { path = "../fabro-telemetry" }
-fabro-store = { path = "../fabro-store" }
-fabro-vault = { path = "../fabro-vault" }
-fabro-types = { path = "../fabro-types", features = ["clap"] }
+fabro-client = { path = "../../foundation/fabro-client" }
+fabro-api = { path = "../../foundation/fabro-api" }
+fabro-telemetry = { path = "../../foundation/fabro-telemetry" }
+fabro-store = { path = "../../components/fabro-store" }
+fabro-vault = { path = "../../foundation/fabro-vault" }
+fabro-types = { path = "../../foundation/fabro-types", features = ["clap"] }
fabro-redact.workspace = true
-fabro-util = { path = "../fabro-util" }
+fabro-util = { path = "../../foundation/fabro-util" }
fabro-http.workspace = true
fabro-static.workspace = true
-fabro-template = { path = "../fabro-template" }
-fabro-tool = { path = "../fabro-tool" }
+fabro-template = { path = "../../foundation/fabro-template" }
+fabro-tool = { path = "../../components/fabro-tool" }
clap.workspace = true
clap_complete.workspace = true
cli-table.workspace = true
@@ -111,16 +111,16 @@ core-foundation = { version = "0.9", optional = true }
openssl = { version = "0.10", features = ["vendored"] }
[build-dependencies]
-fabro-build-support = { path = "../build-support" }
+fabro-build-support = { path = "../../foundation/build-support" }
chrono = { workspace = true }
[dev-dependencies]
assert_cmd = "2"
-fabro-acp = { path = "../fabro-acp", features = ["test-support"] }
-fabro-build-support = { path = "../build-support" }
+fabro-acp = { path = "../../components/fabro-acp", features = ["test-support"] }
+fabro-build-support = { path = "../../foundation/build-support" }
fabro-server = { path = "../fabro-server", features = ["test-support"] }
-fabro-workflow = { path = "../fabro-workflow", features = ["test-support"] }
-fabro-types = { path = "../fabro-types", features = ["clap", "test-support"] }
+fabro-workflow = { path = "../../components/fabro-workflow", features = ["test-support"] }
+fabro-types = { path = "../../foundation/fabro-types", features = ["clap", "test-support"] }
insta = { workspace = true, features = ["filters"] }
paste = "1"
predicates = "3"
@@ -129,7 +129,7 @@ tempfile = "3"
temp-env = "0.3"
httpmock = "0.8"
fabro-test = { workspace = true }
-fabro-macros = { path = "../fabro-macros" }
+fabro-macros = { path = "../../foundation/fabro-macros" }
hkdf.workspace = true
reqwest = { workspace = true, features = ["cookies"] }
tokio = { workspace = true, features = ["test-util", "macros"] }
diff --git a/lib/crates/fabro-cli/build.rs b/lib/apps/fabro-cli/build.rs
similarity index 100%
rename from lib/crates/fabro-cli/build.rs
rename to lib/apps/fabro-cli/build.rs
diff --git a/lib/crates/fabro-cli/src/args.rs b/lib/apps/fabro-cli/src/args.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/args.rs
rename to lib/apps/fabro-cli/src/args.rs
diff --git a/lib/crates/fabro-cli/src/command_context.rs b/lib/apps/fabro-cli/src/command_context.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/command_context.rs
rename to lib/apps/fabro-cli/src/command_context.rs
diff --git a/lib/crates/fabro-cli/src/commands/artifact/cp.rs b/lib/apps/fabro-cli/src/commands/artifact/cp.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/artifact/cp.rs
rename to lib/apps/fabro-cli/src/commands/artifact/cp.rs
diff --git a/lib/crates/fabro-cli/src/commands/artifact/list.rs b/lib/apps/fabro-cli/src/commands/artifact/list.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/artifact/list.rs
rename to lib/apps/fabro-cli/src/commands/artifact/list.rs
diff --git a/lib/crates/fabro-cli/src/commands/artifact/mod.rs b/lib/apps/fabro-cli/src/commands/artifact/mod.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/artifact/mod.rs
rename to lib/apps/fabro-cli/src/commands/artifact/mod.rs
diff --git a/lib/crates/fabro-cli/src/commands/auth/login.rs b/lib/apps/fabro-cli/src/commands/auth/login.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/auth/login.rs
rename to lib/apps/fabro-cli/src/commands/auth/login.rs
diff --git a/lib/crates/fabro-cli/src/commands/auth/logout.rs b/lib/apps/fabro-cli/src/commands/auth/logout.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/auth/logout.rs
rename to lib/apps/fabro-cli/src/commands/auth/logout.rs
diff --git a/lib/crates/fabro-cli/src/commands/auth/mod.rs b/lib/apps/fabro-cli/src/commands/auth/mod.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/auth/mod.rs
rename to lib/apps/fabro-cli/src/commands/auth/mod.rs
diff --git a/lib/crates/fabro-cli/src/commands/auth/status.rs b/lib/apps/fabro-cli/src/commands/auth/status.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/auth/status.rs
rename to lib/apps/fabro-cli/src/commands/auth/status.rs
diff --git a/lib/crates/fabro-cli/src/commands/cli_reference.rs b/lib/apps/fabro-cli/src/commands/cli_reference.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/cli_reference.rs
rename to lib/apps/fabro-cli/src/commands/cli_reference.rs
diff --git a/lib/crates/fabro-cli/src/commands/config/mod.rs b/lib/apps/fabro-cli/src/commands/config/mod.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/config/mod.rs
rename to lib/apps/fabro-cli/src/commands/config/mod.rs
diff --git a/lib/crates/fabro-cli/src/commands/doctor.rs b/lib/apps/fabro-cli/src/commands/doctor.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/doctor.rs
rename to lib/apps/fabro-cli/src/commands/doctor.rs
diff --git a/lib/crates/fabro-cli/src/commands/dump.rs b/lib/apps/fabro-cli/src/commands/dump.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/dump.rs
rename to lib/apps/fabro-cli/src/commands/dump.rs
diff --git a/lib/crates/fabro-cli/src/commands/exec.rs b/lib/apps/fabro-cli/src/commands/exec.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/exec.rs
rename to lib/apps/fabro-cli/src/commands/exec.rs
diff --git a/lib/crates/fabro-cli/src/commands/graph.rs b/lib/apps/fabro-cli/src/commands/graph.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/graph.rs
rename to lib/apps/fabro-cli/src/commands/graph.rs
diff --git a/lib/crates/fabro-cli/src/commands/install.rs b/lib/apps/fabro-cli/src/commands/install.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/install.rs
rename to lib/apps/fabro-cli/src/commands/install.rs
diff --git a/lib/crates/fabro-cli/src/commands/mcp/mod.rs b/lib/apps/fabro-cli/src/commands/mcp/mod.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/mcp/mod.rs
rename to lib/apps/fabro-cli/src/commands/mcp/mod.rs
diff --git a/lib/crates/fabro-cli/src/commands/mod.rs b/lib/apps/fabro-cli/src/commands/mod.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/mod.rs
rename to lib/apps/fabro-cli/src/commands/mod.rs
diff --git a/lib/crates/fabro-cli/src/commands/model.rs b/lib/apps/fabro-cli/src/commands/model.rs
similarity index 97%
rename from lib/crates/fabro-cli/src/commands/model.rs
rename to lib/apps/fabro-cli/src/commands/model.rs
index 4e5bd6f39..f84bd44e2 100644
--- a/lib/crates/fabro-cli/src/commands/model.rs
+++ b/lib/apps/fabro-cli/src/commands/model.rs
@@ -538,12 +538,13 @@ mod tests {
training: None,
knowledge_cutoff: None,
features: ModelFeatures {
- tools: true,
- vision: false,
- reasoning: false,
- reasoning_effort: ReasoningEffortFeature::None,
- prompt_cache: false,
- sampling_params: true,
+ tools: true,
+ vision: false,
+ reasoning: false,
+ reasoning_effort: ReasoningEffortFeature::None,
+ prompt_cache: false,
+ cache_control_breakpoints: false,
+ sampling_params: true,
},
costs: ModelCosts {
input_cost_per_mtok: Some(1.0),
@@ -572,12 +573,13 @@ mod tests {
training: None,
knowledge_cutoff: None,
features: ModelFeatures {
- tools: true,
- vision: false,
- reasoning: false,
- reasoning_effort: ReasoningEffortFeature::None,
- prompt_cache: false,
- sampling_params: true,
+ tools: true,
+ vision: false,
+ reasoning: false,
+ reasoning_effort: ReasoningEffortFeature::None,
+ prompt_cache: false,
+ cache_control_breakpoints: false,
+ sampling_params: true,
},
costs: ModelCosts {
input_cost_per_mtok: Some(1.0),
diff --git a/lib/crates/fabro-cli/src/commands/parent/link.rs b/lib/apps/fabro-cli/src/commands/parent/link.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/parent/link.rs
rename to lib/apps/fabro-cli/src/commands/parent/link.rs
diff --git a/lib/crates/fabro-cli/src/commands/parent/mod.rs b/lib/apps/fabro-cli/src/commands/parent/mod.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/parent/mod.rs
rename to lib/apps/fabro-cli/src/commands/parent/mod.rs
diff --git a/lib/crates/fabro-cli/src/commands/parent/unlink.rs b/lib/apps/fabro-cli/src/commands/parent/unlink.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/parent/unlink.rs
rename to lib/apps/fabro-cli/src/commands/parent/unlink.rs
diff --git a/lib/crates/fabro-cli/src/commands/parse.rs b/lib/apps/fabro-cli/src/commands/parse.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/parse.rs
rename to lib/apps/fabro-cli/src/commands/parse.rs
diff --git a/lib/crates/fabro-cli/src/commands/pr/close.rs b/lib/apps/fabro-cli/src/commands/pr/close.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/pr/close.rs
rename to lib/apps/fabro-cli/src/commands/pr/close.rs
diff --git a/lib/crates/fabro-cli/src/commands/pr/create.rs b/lib/apps/fabro-cli/src/commands/pr/create.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/pr/create.rs
rename to lib/apps/fabro-cli/src/commands/pr/create.rs
diff --git a/lib/crates/fabro-cli/src/commands/pr/link.rs b/lib/apps/fabro-cli/src/commands/pr/link.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/pr/link.rs
rename to lib/apps/fabro-cli/src/commands/pr/link.rs
diff --git a/lib/crates/fabro-cli/src/commands/pr/merge.rs b/lib/apps/fabro-cli/src/commands/pr/merge.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/pr/merge.rs
rename to lib/apps/fabro-cli/src/commands/pr/merge.rs
diff --git a/lib/crates/fabro-cli/src/commands/pr/mod.rs b/lib/apps/fabro-cli/src/commands/pr/mod.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/pr/mod.rs
rename to lib/apps/fabro-cli/src/commands/pr/mod.rs
diff --git a/lib/crates/fabro-cli/src/commands/pr/unlink.rs b/lib/apps/fabro-cli/src/commands/pr/unlink.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/pr/unlink.rs
rename to lib/apps/fabro-cli/src/commands/pr/unlink.rs
diff --git a/lib/crates/fabro-cli/src/commands/pr/view.rs b/lib/apps/fabro-cli/src/commands/pr/view.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/pr/view.rs
rename to lib/apps/fabro-cli/src/commands/pr/view.rs
diff --git a/lib/crates/fabro-cli/src/commands/preflight.rs b/lib/apps/fabro-cli/src/commands/preflight.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/preflight.rs
rename to lib/apps/fabro-cli/src/commands/preflight.rs
diff --git a/lib/crates/fabro-cli/src/commands/provider/login.rs b/lib/apps/fabro-cli/src/commands/provider/login.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/provider/login.rs
rename to lib/apps/fabro-cli/src/commands/provider/login.rs
diff --git a/lib/crates/fabro-cli/src/commands/provider/mod.rs b/lib/apps/fabro-cli/src/commands/provider/mod.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/provider/mod.rs
rename to lib/apps/fabro-cli/src/commands/provider/mod.rs
diff --git a/lib/crates/fabro-cli/src/commands/render_graph.rs b/lib/apps/fabro-cli/src/commands/render_graph.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/render_graph.rs
rename to lib/apps/fabro-cli/src/commands/render_graph.rs
diff --git a/lib/crates/fabro-cli/src/commands/repo/deinit.rs b/lib/apps/fabro-cli/src/commands/repo/deinit.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/repo/deinit.rs
rename to lib/apps/fabro-cli/src/commands/repo/deinit.rs
diff --git a/lib/crates/fabro-cli/src/commands/repo/init.rs b/lib/apps/fabro-cli/src/commands/repo/init.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/repo/init.rs
rename to lib/apps/fabro-cli/src/commands/repo/init.rs
diff --git a/lib/crates/fabro-cli/src/commands/repo/mod.rs b/lib/apps/fabro-cli/src/commands/repo/mod.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/repo/mod.rs
rename to lib/apps/fabro-cli/src/commands/repo/mod.rs
diff --git a/lib/crates/fabro-cli/src/commands/run/ask.rs b/lib/apps/fabro-cli/src/commands/run/ask.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/run/ask.rs
rename to lib/apps/fabro-cli/src/commands/run/ask.rs
diff --git a/lib/crates/fabro-cli/src/commands/run/attach.rs b/lib/apps/fabro-cli/src/commands/run/attach.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/run/attach.rs
rename to lib/apps/fabro-cli/src/commands/run/attach.rs
diff --git a/lib/crates/fabro-cli/src/commands/run/checkpoints.rs b/lib/apps/fabro-cli/src/commands/run/checkpoints.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/run/checkpoints.rs
rename to lib/apps/fabro-cli/src/commands/run/checkpoints.rs
diff --git a/lib/crates/fabro-cli/src/commands/run/command.rs b/lib/apps/fabro-cli/src/commands/run/command.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/run/command.rs
rename to lib/apps/fabro-cli/src/commands/run/command.rs
diff --git a/lib/crates/fabro-cli/src/commands/run/cp.rs b/lib/apps/fabro-cli/src/commands/run/cp.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/run/cp.rs
rename to lib/apps/fabro-cli/src/commands/run/cp.rs
diff --git a/lib/crates/fabro-cli/src/commands/run/create.rs b/lib/apps/fabro-cli/src/commands/run/create.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/run/create.rs
rename to lib/apps/fabro-cli/src/commands/run/create.rs
diff --git a/lib/crates/fabro-cli/src/commands/run/diff.rs b/lib/apps/fabro-cli/src/commands/run/diff.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/run/diff.rs
rename to lib/apps/fabro-cli/src/commands/run/diff.rs
diff --git a/lib/crates/fabro-cli/src/commands/run/events.rs b/lib/apps/fabro-cli/src/commands/run/events.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/run/events.rs
rename to lib/apps/fabro-cli/src/commands/run/events.rs
diff --git a/lib/crates/fabro-cli/src/commands/run/fork.rs b/lib/apps/fabro-cli/src/commands/run/fork.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/run/fork.rs
rename to lib/apps/fabro-cli/src/commands/run/fork.rs
diff --git a/lib/crates/fabro-cli/src/commands/run/logs.rs b/lib/apps/fabro-cli/src/commands/run/logs.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/run/logs.rs
rename to lib/apps/fabro-cli/src/commands/run/logs.rs
diff --git a/lib/crates/fabro-cli/src/commands/run/mod.rs b/lib/apps/fabro-cli/src/commands/run/mod.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/run/mod.rs
rename to lib/apps/fabro-cli/src/commands/run/mod.rs
diff --git a/lib/crates/fabro-cli/src/commands/run/output.rs b/lib/apps/fabro-cli/src/commands/run/output.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/run/output.rs
rename to lib/apps/fabro-cli/src/commands/run/output.rs
diff --git a/lib/crates/fabro-cli/src/commands/run/overrides.rs b/lib/apps/fabro-cli/src/commands/run/overrides.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/run/overrides.rs
rename to lib/apps/fabro-cli/src/commands/run/overrides.rs
diff --git a/lib/crates/fabro-cli/src/commands/run/preview.rs b/lib/apps/fabro-cli/src/commands/run/preview.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/run/preview.rs
rename to lib/apps/fabro-cli/src/commands/run/preview.rs
diff --git a/lib/crates/fabro-cli/src/commands/run/resume.rs b/lib/apps/fabro-cli/src/commands/run/resume.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/run/resume.rs
rename to lib/apps/fabro-cli/src/commands/run/resume.rs
diff --git a/lib/crates/fabro-cli/src/commands/run/rewind.rs b/lib/apps/fabro-cli/src/commands/run/rewind.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/run/rewind.rs
rename to lib/apps/fabro-cli/src/commands/run/rewind.rs
diff --git a/lib/crates/fabro-cli/src/commands/run/run_progress/event.rs b/lib/apps/fabro-cli/src/commands/run/run_progress/event.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/run/run_progress/event.rs
rename to lib/apps/fabro-cli/src/commands/run/run_progress/event.rs
diff --git a/lib/crates/fabro-cli/src/commands/run/run_progress/info_display.rs b/lib/apps/fabro-cli/src/commands/run/run_progress/info_display.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/run/run_progress/info_display.rs
rename to lib/apps/fabro-cli/src/commands/run/run_progress/info_display.rs
diff --git a/lib/crates/fabro-cli/src/commands/run/run_progress/mod.rs b/lib/apps/fabro-cli/src/commands/run/run_progress/mod.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/run/run_progress/mod.rs
rename to lib/apps/fabro-cli/src/commands/run/run_progress/mod.rs
diff --git a/lib/crates/fabro-cli/src/commands/run/run_progress/renderer.rs b/lib/apps/fabro-cli/src/commands/run/run_progress/renderer.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/run/run_progress/renderer.rs
rename to lib/apps/fabro-cli/src/commands/run/run_progress/renderer.rs
diff --git a/lib/crates/fabro-cli/src/commands/run/run_progress/setup_display.rs b/lib/apps/fabro-cli/src/commands/run/run_progress/setup_display.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/run/run_progress/setup_display.rs
rename to lib/apps/fabro-cli/src/commands/run/run_progress/setup_display.rs
diff --git a/lib/crates/fabro-cli/src/commands/run/run_progress/stage_display.rs b/lib/apps/fabro-cli/src/commands/run/run_progress/stage_display.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/run/run_progress/stage_display.rs
rename to lib/apps/fabro-cli/src/commands/run/run_progress/stage_display.rs
diff --git a/lib/crates/fabro-cli/src/commands/run/run_progress/styles.rs b/lib/apps/fabro-cli/src/commands/run/run_progress/styles.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/run/run_progress/styles.rs
rename to lib/apps/fabro-cli/src/commands/run/run_progress/styles.rs
diff --git a/lib/crates/fabro-cli/src/commands/run/runner.rs b/lib/apps/fabro-cli/src/commands/run/runner.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/run/runner.rs
rename to lib/apps/fabro-cli/src/commands/run/runner.rs
diff --git a/lib/crates/fabro-cli/src/commands/run/ssh.rs b/lib/apps/fabro-cli/src/commands/run/ssh.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/run/ssh.rs
rename to lib/apps/fabro-cli/src/commands/run/ssh.rs
diff --git a/lib/crates/fabro-cli/src/commands/run/start.rs b/lib/apps/fabro-cli/src/commands/run/start.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/run/start.rs
rename to lib/apps/fabro-cli/src/commands/run/start.rs
diff --git a/lib/crates/fabro-cli/src/commands/run/steer.rs b/lib/apps/fabro-cli/src/commands/run/steer.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/run/steer.rs
rename to lib/apps/fabro-cli/src/commands/run/steer.rs
diff --git a/lib/crates/fabro-cli/src/commands/run/wait.rs b/lib/apps/fabro-cli/src/commands/run/wait.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/run/wait.rs
rename to lib/apps/fabro-cli/src/commands/run/wait.rs
diff --git a/lib/crates/fabro-cli/src/commands/runs/approval.rs b/lib/apps/fabro-cli/src/commands/runs/approval.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/runs/approval.rs
rename to lib/apps/fabro-cli/src/commands/runs/approval.rs
diff --git a/lib/crates/fabro-cli/src/commands/runs/archive.rs b/lib/apps/fabro-cli/src/commands/runs/archive.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/runs/archive.rs
rename to lib/apps/fabro-cli/src/commands/runs/archive.rs
diff --git a/lib/crates/fabro-cli/src/commands/runs/inspect.rs b/lib/apps/fabro-cli/src/commands/runs/inspect.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/runs/inspect.rs
rename to lib/apps/fabro-cli/src/commands/runs/inspect.rs
diff --git a/lib/crates/fabro-cli/src/commands/runs/list.rs b/lib/apps/fabro-cli/src/commands/runs/list.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/runs/list.rs
rename to lib/apps/fabro-cli/src/commands/runs/list.rs
diff --git a/lib/crates/fabro-cli/src/commands/runs/mod.rs b/lib/apps/fabro-cli/src/commands/runs/mod.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/runs/mod.rs
rename to lib/apps/fabro-cli/src/commands/runs/mod.rs
diff --git a/lib/crates/fabro-cli/src/commands/runs/rm.rs b/lib/apps/fabro-cli/src/commands/runs/rm.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/runs/rm.rs
rename to lib/apps/fabro-cli/src/commands/runs/rm.rs
diff --git a/lib/crates/fabro-cli/src/commands/sandbox/mod.rs b/lib/apps/fabro-cli/src/commands/sandbox/mod.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/sandbox/mod.rs
rename to lib/apps/fabro-cli/src/commands/sandbox/mod.rs
diff --git a/lib/crates/fabro-cli/src/commands/secret/list.rs b/lib/apps/fabro-cli/src/commands/secret/list.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/secret/list.rs
rename to lib/apps/fabro-cli/src/commands/secret/list.rs
diff --git a/lib/crates/fabro-cli/src/commands/secret/mod.rs b/lib/apps/fabro-cli/src/commands/secret/mod.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/secret/mod.rs
rename to lib/apps/fabro-cli/src/commands/secret/mod.rs
diff --git a/lib/crates/fabro-cli/src/commands/secret/rm.rs b/lib/apps/fabro-cli/src/commands/secret/rm.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/secret/rm.rs
rename to lib/apps/fabro-cli/src/commands/secret/rm.rs
diff --git a/lib/crates/fabro-cli/src/commands/secret/set.rs b/lib/apps/fabro-cli/src/commands/secret/set.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/secret/set.rs
rename to lib/apps/fabro-cli/src/commands/secret/set.rs
diff --git a/lib/crates/fabro-cli/src/commands/server/foreground.rs b/lib/apps/fabro-cli/src/commands/server/foreground.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/server/foreground.rs
rename to lib/apps/fabro-cli/src/commands/server/foreground.rs
diff --git a/lib/crates/fabro-cli/src/commands/server/mod.rs b/lib/apps/fabro-cli/src/commands/server/mod.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/server/mod.rs
rename to lib/apps/fabro-cli/src/commands/server/mod.rs
diff --git a/lib/crates/fabro-cli/src/commands/server/start.rs b/lib/apps/fabro-cli/src/commands/server/start.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/server/start.rs
rename to lib/apps/fabro-cli/src/commands/server/start.rs
diff --git a/lib/crates/fabro-cli/src/commands/server/status.rs b/lib/apps/fabro-cli/src/commands/server/status.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/server/status.rs
rename to lib/apps/fabro-cli/src/commands/server/status.rs
diff --git a/lib/crates/fabro-cli/src/commands/server/stop.rs b/lib/apps/fabro-cli/src/commands/server/stop.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/server/stop.rs
rename to lib/apps/fabro-cli/src/commands/server/stop.rs
diff --git a/lib/crates/fabro-cli/src/commands/system/df.rs b/lib/apps/fabro-cli/src/commands/system/df.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/system/df.rs
rename to lib/apps/fabro-cli/src/commands/system/df.rs
diff --git a/lib/crates/fabro-cli/src/commands/system/events.rs b/lib/apps/fabro-cli/src/commands/system/events.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/system/events.rs
rename to lib/apps/fabro-cli/src/commands/system/events.rs
diff --git a/lib/crates/fabro-cli/src/commands/system/info.rs b/lib/apps/fabro-cli/src/commands/system/info.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/system/info.rs
rename to lib/apps/fabro-cli/src/commands/system/info.rs
diff --git a/lib/crates/fabro-cli/src/commands/system/mod.rs b/lib/apps/fabro-cli/src/commands/system/mod.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/system/mod.rs
rename to lib/apps/fabro-cli/src/commands/system/mod.rs
diff --git a/lib/crates/fabro-cli/src/commands/system/prune.rs b/lib/apps/fabro-cli/src/commands/system/prune.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/system/prune.rs
rename to lib/apps/fabro-cli/src/commands/system/prune.rs
diff --git a/lib/crates/fabro-cli/src/commands/system/repair.rs b/lib/apps/fabro-cli/src/commands/system/repair.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/system/repair.rs
rename to lib/apps/fabro-cli/src/commands/system/repair.rs
diff --git a/lib/crates/fabro-cli/src/commands/uninstall.rs b/lib/apps/fabro-cli/src/commands/uninstall.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/uninstall.rs
rename to lib/apps/fabro-cli/src/commands/uninstall.rs
diff --git a/lib/crates/fabro-cli/src/commands/upgrade.rs b/lib/apps/fabro-cli/src/commands/upgrade.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/upgrade.rs
rename to lib/apps/fabro-cli/src/commands/upgrade.rs
diff --git a/lib/crates/fabro-cli/src/commands/validate.rs b/lib/apps/fabro-cli/src/commands/validate.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/validate.rs
rename to lib/apps/fabro-cli/src/commands/validate.rs
diff --git a/lib/crates/fabro-cli/src/commands/variable/get.rs b/lib/apps/fabro-cli/src/commands/variable/get.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/variable/get.rs
rename to lib/apps/fabro-cli/src/commands/variable/get.rs
diff --git a/lib/crates/fabro-cli/src/commands/variable/list.rs b/lib/apps/fabro-cli/src/commands/variable/list.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/variable/list.rs
rename to lib/apps/fabro-cli/src/commands/variable/list.rs
diff --git a/lib/crates/fabro-cli/src/commands/variable/mod.rs b/lib/apps/fabro-cli/src/commands/variable/mod.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/variable/mod.rs
rename to lib/apps/fabro-cli/src/commands/variable/mod.rs
diff --git a/lib/crates/fabro-cli/src/commands/variable/rm.rs b/lib/apps/fabro-cli/src/commands/variable/rm.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/variable/rm.rs
rename to lib/apps/fabro-cli/src/commands/variable/rm.rs
diff --git a/lib/crates/fabro-cli/src/commands/variable/set.rs b/lib/apps/fabro-cli/src/commands/variable/set.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/variable/set.rs
rename to lib/apps/fabro-cli/src/commands/variable/set.rs
diff --git a/lib/crates/fabro-cli/src/commands/version.rs b/lib/apps/fabro-cli/src/commands/version.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/version.rs
rename to lib/apps/fabro-cli/src/commands/version.rs
diff --git a/lib/crates/fabro-cli/src/commands/workflow/create.rs b/lib/apps/fabro-cli/src/commands/workflow/create.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/workflow/create.rs
rename to lib/apps/fabro-cli/src/commands/workflow/create.rs
diff --git a/lib/crates/fabro-cli/src/commands/workflow/list.rs b/lib/apps/fabro-cli/src/commands/workflow/list.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/workflow/list.rs
rename to lib/apps/fabro-cli/src/commands/workflow/list.rs
diff --git a/lib/crates/fabro-cli/src/commands/workflow/mod.rs b/lib/apps/fabro-cli/src/commands/workflow/mod.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/commands/workflow/mod.rs
rename to lib/apps/fabro-cli/src/commands/workflow/mod.rs
diff --git a/lib/crates/fabro-cli/src/gh.rs b/lib/apps/fabro-cli/src/gh.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/gh.rs
rename to lib/apps/fabro-cli/src/gh.rs
diff --git a/lib/crates/fabro-cli/src/landing.rs b/lib/apps/fabro-cli/src/landing.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/landing.rs
rename to lib/apps/fabro-cli/src/landing.rs
diff --git a/lib/crates/fabro-cli/src/local_server.rs b/lib/apps/fabro-cli/src/local_server.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/local_server.rs
rename to lib/apps/fabro-cli/src/local_server.rs
diff --git a/lib/crates/fabro-cli/src/logging.rs b/lib/apps/fabro-cli/src/logging.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/logging.rs
rename to lib/apps/fabro-cli/src/logging.rs
diff --git a/lib/crates/fabro-cli/src/main.rs b/lib/apps/fabro-cli/src/main.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/main.rs
rename to lib/apps/fabro-cli/src/main.rs
diff --git a/lib/crates/fabro-cli/src/manifest_args.rs b/lib/apps/fabro-cli/src/manifest_args.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/manifest_args.rs
rename to lib/apps/fabro-cli/src/manifest_args.rs
diff --git a/lib/crates/fabro-cli/src/server_client.rs b/lib/apps/fabro-cli/src/server_client.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/server_client.rs
rename to lib/apps/fabro-cli/src/server_client.rs
diff --git a/lib/crates/fabro-cli/src/server_runs.rs b/lib/apps/fabro-cli/src/server_runs.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/server_runs.rs
rename to lib/apps/fabro-cli/src/server_runs.rs
diff --git a/lib/crates/fabro-cli/src/shared/github.rs b/lib/apps/fabro-cli/src/shared/github.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/shared/github.rs
rename to lib/apps/fabro-cli/src/shared/github.rs
diff --git a/lib/crates/fabro-cli/src/shared/mod.rs b/lib/apps/fabro-cli/src/shared/mod.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/shared/mod.rs
rename to lib/apps/fabro-cli/src/shared/mod.rs
diff --git a/lib/crates/fabro-cli/src/shared/provider_auth.rs b/lib/apps/fabro-cli/src/shared/provider_auth.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/shared/provider_auth.rs
rename to lib/apps/fabro-cli/src/shared/provider_auth.rs
diff --git a/lib/crates/fabro-cli/src/shared/repo.rs b/lib/apps/fabro-cli/src/shared/repo.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/shared/repo.rs
rename to lib/apps/fabro-cli/src/shared/repo.rs
diff --git a/lib/crates/fabro-cli/src/shared/utilities.rs b/lib/apps/fabro-cli/src/shared/utilities.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/shared/utilities.rs
rename to lib/apps/fabro-cli/src/shared/utilities.rs
diff --git a/lib/crates/fabro-cli/src/sleep_inhibitor/dummy.rs b/lib/apps/fabro-cli/src/sleep_inhibitor/dummy.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/sleep_inhibitor/dummy.rs
rename to lib/apps/fabro-cli/src/sleep_inhibitor/dummy.rs
diff --git a/lib/crates/fabro-cli/src/sleep_inhibitor/iokit_bindings.rs b/lib/apps/fabro-cli/src/sleep_inhibitor/iokit_bindings.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/sleep_inhibitor/iokit_bindings.rs
rename to lib/apps/fabro-cli/src/sleep_inhibitor/iokit_bindings.rs
diff --git a/lib/crates/fabro-cli/src/sleep_inhibitor/linux.rs b/lib/apps/fabro-cli/src/sleep_inhibitor/linux.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/sleep_inhibitor/linux.rs
rename to lib/apps/fabro-cli/src/sleep_inhibitor/linux.rs
diff --git a/lib/crates/fabro-cli/src/sleep_inhibitor/macos.rs b/lib/apps/fabro-cli/src/sleep_inhibitor/macos.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/sleep_inhibitor/macos.rs
rename to lib/apps/fabro-cli/src/sleep_inhibitor/macos.rs
diff --git a/lib/crates/fabro-cli/src/sleep_inhibitor/mod.rs b/lib/apps/fabro-cli/src/sleep_inhibitor/mod.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/sleep_inhibitor/mod.rs
rename to lib/apps/fabro-cli/src/sleep_inhibitor/mod.rs
diff --git a/lib/crates/fabro-cli/src/user_config.rs b/lib/apps/fabro-cli/src/user_config.rs
similarity index 100%
rename from lib/crates/fabro-cli/src/user_config.rs
rename to lib/apps/fabro-cli/src/user_config.rs
diff --git a/lib/crates/fabro-cli/tests/build_git_metadata.rs b/lib/apps/fabro-cli/tests/build_git_metadata.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/build_git_metadata.rs
rename to lib/apps/fabro-cli/tests/build_git_metadata.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/approve.rs b/lib/apps/fabro-cli/tests/it/cmd/approve.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/approve.rs
rename to lib/apps/fabro-cli/tests/it/cmd/approve.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/archive.rs b/lib/apps/fabro-cli/tests/it/cmd/archive.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/archive.rs
rename to lib/apps/fabro-cli/tests/it/cmd/archive.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/artifact_cp.rs b/lib/apps/fabro-cli/tests/it/cmd/artifact_cp.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/artifact_cp.rs
rename to lib/apps/fabro-cli/tests/it/cmd/artifact_cp.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/artifact_list.rs b/lib/apps/fabro-cli/tests/it/cmd/artifact_list.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/artifact_list.rs
rename to lib/apps/fabro-cli/tests/it/cmd/artifact_list.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/attach.rs b/lib/apps/fabro-cli/tests/it/cmd/attach.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/attach.rs
rename to lib/apps/fabro-cli/tests/it/cmd/attach.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/auth.rs b/lib/apps/fabro-cli/tests/it/cmd/auth.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/auth.rs
rename to lib/apps/fabro-cli/tests/it/cmd/auth.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/cli_reference.rs b/lib/apps/fabro-cli/tests/it/cmd/cli_reference.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/cli_reference.rs
rename to lib/apps/fabro-cli/tests/it/cmd/cli_reference.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/config.rs b/lib/apps/fabro-cli/tests/it/cmd/config.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/config.rs
rename to lib/apps/fabro-cli/tests/it/cmd/config.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/create.rs b/lib/apps/fabro-cli/tests/it/cmd/create.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/create.rs
rename to lib/apps/fabro-cli/tests/it/cmd/create.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/deny.rs b/lib/apps/fabro-cli/tests/it/cmd/deny.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/deny.rs
rename to lib/apps/fabro-cli/tests/it/cmd/deny.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/diff.rs b/lib/apps/fabro-cli/tests/it/cmd/diff.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/diff.rs
rename to lib/apps/fabro-cli/tests/it/cmd/diff.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/discord.rs b/lib/apps/fabro-cli/tests/it/cmd/discord.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/discord.rs
rename to lib/apps/fabro-cli/tests/it/cmd/discord.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/docs.rs b/lib/apps/fabro-cli/tests/it/cmd/docs.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/docs.rs
rename to lib/apps/fabro-cli/tests/it/cmd/docs.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/doctor.rs b/lib/apps/fabro-cli/tests/it/cmd/doctor.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/doctor.rs
rename to lib/apps/fabro-cli/tests/it/cmd/doctor.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/dump.rs b/lib/apps/fabro-cli/tests/it/cmd/dump.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/dump.rs
rename to lib/apps/fabro-cli/tests/it/cmd/dump.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/events.rs b/lib/apps/fabro-cli/tests/it/cmd/events.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/events.rs
rename to lib/apps/fabro-cli/tests/it/cmd/events.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/exec.rs b/lib/apps/fabro-cli/tests/it/cmd/exec.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/exec.rs
rename to lib/apps/fabro-cli/tests/it/cmd/exec.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/fabro.rs b/lib/apps/fabro-cli/tests/it/cmd/fabro.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/fabro.rs
rename to lib/apps/fabro-cli/tests/it/cmd/fabro.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/fork.rs b/lib/apps/fabro-cli/tests/it/cmd/fork.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/fork.rs
rename to lib/apps/fabro-cli/tests/it/cmd/fork.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/graph.rs b/lib/apps/fabro-cli/tests/it/cmd/graph.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/graph.rs
rename to lib/apps/fabro-cli/tests/it/cmd/graph.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/inspect.rs b/lib/apps/fabro-cli/tests/it/cmd/inspect.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/inspect.rs
rename to lib/apps/fabro-cli/tests/it/cmd/inspect.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/install.rs b/lib/apps/fabro-cli/tests/it/cmd/install.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/install.rs
rename to lib/apps/fabro-cli/tests/it/cmd/install.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/json_global.rs b/lib/apps/fabro-cli/tests/it/cmd/json_global.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/json_global.rs
rename to lib/apps/fabro-cli/tests/it/cmd/json_global.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/logs.rs b/lib/apps/fabro-cli/tests/it/cmd/logs.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/logs.rs
rename to lib/apps/fabro-cli/tests/it/cmd/logs.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/mcp.rs b/lib/apps/fabro-cli/tests/it/cmd/mcp.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/mcp.rs
rename to lib/apps/fabro-cli/tests/it/cmd/mcp.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/mod.rs b/lib/apps/fabro-cli/tests/it/cmd/mod.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/mod.rs
rename to lib/apps/fabro-cli/tests/it/cmd/mod.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/model.rs b/lib/apps/fabro-cli/tests/it/cmd/model.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/model.rs
rename to lib/apps/fabro-cli/tests/it/cmd/model.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/model_list.rs b/lib/apps/fabro-cli/tests/it/cmd/model_list.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/model_list.rs
rename to lib/apps/fabro-cli/tests/it/cmd/model_list.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/model_test.rs b/lib/apps/fabro-cli/tests/it/cmd/model_test.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/model_test.rs
rename to lib/apps/fabro-cli/tests/it/cmd/model_test.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/parent.rs b/lib/apps/fabro-cli/tests/it/cmd/parent.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/parent.rs
rename to lib/apps/fabro-cli/tests/it/cmd/parent.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/parse.rs b/lib/apps/fabro-cli/tests/it/cmd/parse.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/parse.rs
rename to lib/apps/fabro-cli/tests/it/cmd/parse.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/pr.rs b/lib/apps/fabro-cli/tests/it/cmd/pr.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/pr.rs
rename to lib/apps/fabro-cli/tests/it/cmd/pr.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/pr_close.rs b/lib/apps/fabro-cli/tests/it/cmd/pr_close.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/pr_close.rs
rename to lib/apps/fabro-cli/tests/it/cmd/pr_close.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/pr_create.rs b/lib/apps/fabro-cli/tests/it/cmd/pr_create.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/pr_create.rs
rename to lib/apps/fabro-cli/tests/it/cmd/pr_create.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/pr_link.rs b/lib/apps/fabro-cli/tests/it/cmd/pr_link.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/pr_link.rs
rename to lib/apps/fabro-cli/tests/it/cmd/pr_link.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/pr_merge.rs b/lib/apps/fabro-cli/tests/it/cmd/pr_merge.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/pr_merge.rs
rename to lib/apps/fabro-cli/tests/it/cmd/pr_merge.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/pr_unlink.rs b/lib/apps/fabro-cli/tests/it/cmd/pr_unlink.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/pr_unlink.rs
rename to lib/apps/fabro-cli/tests/it/cmd/pr_unlink.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/pr_view.rs b/lib/apps/fabro-cli/tests/it/cmd/pr_view.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/pr_view.rs
rename to lib/apps/fabro-cli/tests/it/cmd/pr_view.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/preflight.rs b/lib/apps/fabro-cli/tests/it/cmd/preflight.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/preflight.rs
rename to lib/apps/fabro-cli/tests/it/cmd/preflight.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/provider.rs b/lib/apps/fabro-cli/tests/it/cmd/provider.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/provider.rs
rename to lib/apps/fabro-cli/tests/it/cmd/provider.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/provider_login.rs b/lib/apps/fabro-cli/tests/it/cmd/provider_login.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/provider_login.rs
rename to lib/apps/fabro-cli/tests/it/cmd/provider_login.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/ps.rs b/lib/apps/fabro-cli/tests/it/cmd/ps.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/ps.rs
rename to lib/apps/fabro-cli/tests/it/cmd/ps.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/render_graph.rs b/lib/apps/fabro-cli/tests/it/cmd/render_graph.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/render_graph.rs
rename to lib/apps/fabro-cli/tests/it/cmd/render_graph.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/repo.rs b/lib/apps/fabro-cli/tests/it/cmd/repo.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/repo.rs
rename to lib/apps/fabro-cli/tests/it/cmd/repo.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/repo_deinit.rs b/lib/apps/fabro-cli/tests/it/cmd/repo_deinit.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/repo_deinit.rs
rename to lib/apps/fabro-cli/tests/it/cmd/repo_deinit.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/repo_init.rs b/lib/apps/fabro-cli/tests/it/cmd/repo_init.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/repo_init.rs
rename to lib/apps/fabro-cli/tests/it/cmd/repo_init.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/resume.rs b/lib/apps/fabro-cli/tests/it/cmd/resume.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/resume.rs
rename to lib/apps/fabro-cli/tests/it/cmd/resume.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/rewind.rs b/lib/apps/fabro-cli/tests/it/cmd/rewind.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/rewind.rs
rename to lib/apps/fabro-cli/tests/it/cmd/rewind.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/rm.rs b/lib/apps/fabro-cli/tests/it/cmd/rm.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/rm.rs
rename to lib/apps/fabro-cli/tests/it/cmd/rm.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/run.rs b/lib/apps/fabro-cli/tests/it/cmd/run.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/run.rs
rename to lib/apps/fabro-cli/tests/it/cmd/run.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/runner.rs b/lib/apps/fabro-cli/tests/it/cmd/runner.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/runner.rs
rename to lib/apps/fabro-cli/tests/it/cmd/runner.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/sandbox_cp.rs b/lib/apps/fabro-cli/tests/it/cmd/sandbox_cp.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/sandbox_cp.rs
rename to lib/apps/fabro-cli/tests/it/cmd/sandbox_cp.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/sandbox_preview.rs b/lib/apps/fabro-cli/tests/it/cmd/sandbox_preview.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/sandbox_preview.rs
rename to lib/apps/fabro-cli/tests/it/cmd/sandbox_preview.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/sandbox_ssh.rs b/lib/apps/fabro-cli/tests/it/cmd/sandbox_ssh.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/sandbox_ssh.rs
rename to lib/apps/fabro-cli/tests/it/cmd/sandbox_ssh.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/secret.rs b/lib/apps/fabro-cli/tests/it/cmd/secret.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/secret.rs
rename to lib/apps/fabro-cli/tests/it/cmd/secret.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/secret_list.rs b/lib/apps/fabro-cli/tests/it/cmd/secret_list.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/secret_list.rs
rename to lib/apps/fabro-cli/tests/it/cmd/secret_list.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/secret_rm.rs b/lib/apps/fabro-cli/tests/it/cmd/secret_rm.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/secret_rm.rs
rename to lib/apps/fabro-cli/tests/it/cmd/secret_rm.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/secret_set.rs b/lib/apps/fabro-cli/tests/it/cmd/secret_set.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/secret_set.rs
rename to lib/apps/fabro-cli/tests/it/cmd/secret_set.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/send_analytics.rs b/lib/apps/fabro-cli/tests/it/cmd/send_analytics.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/send_analytics.rs
rename to lib/apps/fabro-cli/tests/it/cmd/send_analytics.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/send_panic.rs b/lib/apps/fabro-cli/tests/it/cmd/send_panic.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/send_panic.rs
rename to lib/apps/fabro-cli/tests/it/cmd/send_panic.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/server_start.rs b/lib/apps/fabro-cli/tests/it/cmd/server_start.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/server_start.rs
rename to lib/apps/fabro-cli/tests/it/cmd/server_start.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/server_status.rs b/lib/apps/fabro-cli/tests/it/cmd/server_status.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/server_status.rs
rename to lib/apps/fabro-cli/tests/it/cmd/server_status.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/server_stop.rs b/lib/apps/fabro-cli/tests/it/cmd/server_stop.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/server_stop.rs
rename to lib/apps/fabro-cli/tests/it/cmd/server_stop.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/start.rs b/lib/apps/fabro-cli/tests/it/cmd/start.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/start.rs
rename to lib/apps/fabro-cli/tests/it/cmd/start.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/support.rs b/lib/apps/fabro-cli/tests/it/cmd/support.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/support.rs
rename to lib/apps/fabro-cli/tests/it/cmd/support.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/system.rs b/lib/apps/fabro-cli/tests/it/cmd/system.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/system.rs
rename to lib/apps/fabro-cli/tests/it/cmd/system.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/system_df.rs b/lib/apps/fabro-cli/tests/it/cmd/system_df.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/system_df.rs
rename to lib/apps/fabro-cli/tests/it/cmd/system_df.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/system_events.rs b/lib/apps/fabro-cli/tests/it/cmd/system_events.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/system_events.rs
rename to lib/apps/fabro-cli/tests/it/cmd/system_events.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/system_info.rs b/lib/apps/fabro-cli/tests/it/cmd/system_info.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/system_info.rs
rename to lib/apps/fabro-cli/tests/it/cmd/system_info.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/system_prune.rs b/lib/apps/fabro-cli/tests/it/cmd/system_prune.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/system_prune.rs
rename to lib/apps/fabro-cli/tests/it/cmd/system_prune.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/system_repair.rs b/lib/apps/fabro-cli/tests/it/cmd/system_repair.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/system_repair.rs
rename to lib/apps/fabro-cli/tests/it/cmd/system_repair.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/test_panic.rs b/lib/apps/fabro-cli/tests/it/cmd/test_panic.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/test_panic.rs
rename to lib/apps/fabro-cli/tests/it/cmd/test_panic.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/top_level.rs b/lib/apps/fabro-cli/tests/it/cmd/top_level.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/top_level.rs
rename to lib/apps/fabro-cli/tests/it/cmd/top_level.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/unarchive.rs b/lib/apps/fabro-cli/tests/it/cmd/unarchive.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/unarchive.rs
rename to lib/apps/fabro-cli/tests/it/cmd/unarchive.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/uninstall.rs b/lib/apps/fabro-cli/tests/it/cmd/uninstall.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/uninstall.rs
rename to lib/apps/fabro-cli/tests/it/cmd/uninstall.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/upgrade.rs b/lib/apps/fabro-cli/tests/it/cmd/upgrade.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/upgrade.rs
rename to lib/apps/fabro-cli/tests/it/cmd/upgrade.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/validate.rs b/lib/apps/fabro-cli/tests/it/cmd/validate.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/validate.rs
rename to lib/apps/fabro-cli/tests/it/cmd/validate.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/variable.rs b/lib/apps/fabro-cli/tests/it/cmd/variable.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/variable.rs
rename to lib/apps/fabro-cli/tests/it/cmd/variable.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/variable_get.rs b/lib/apps/fabro-cli/tests/it/cmd/variable_get.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/variable_get.rs
rename to lib/apps/fabro-cli/tests/it/cmd/variable_get.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/variable_list.rs b/lib/apps/fabro-cli/tests/it/cmd/variable_list.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/variable_list.rs
rename to lib/apps/fabro-cli/tests/it/cmd/variable_list.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/variable_rm.rs b/lib/apps/fabro-cli/tests/it/cmd/variable_rm.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/variable_rm.rs
rename to lib/apps/fabro-cli/tests/it/cmd/variable_rm.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/variable_set.rs b/lib/apps/fabro-cli/tests/it/cmd/variable_set.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/variable_set.rs
rename to lib/apps/fabro-cli/tests/it/cmd/variable_set.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/version.rs b/lib/apps/fabro-cli/tests/it/cmd/version.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/version.rs
rename to lib/apps/fabro-cli/tests/it/cmd/version.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/wait.rs b/lib/apps/fabro-cli/tests/it/cmd/wait.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/wait.rs
rename to lib/apps/fabro-cli/tests/it/cmd/wait.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/worker_auth.rs b/lib/apps/fabro-cli/tests/it/cmd/worker_auth.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/worker_auth.rs
rename to lib/apps/fabro-cli/tests/it/cmd/worker_auth.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/workflow.rs b/lib/apps/fabro-cli/tests/it/cmd/workflow.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/workflow.rs
rename to lib/apps/fabro-cli/tests/it/cmd/workflow.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/workflow_create.rs b/lib/apps/fabro-cli/tests/it/cmd/workflow_create.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/workflow_create.rs
rename to lib/apps/fabro-cli/tests/it/cmd/workflow_create.rs
diff --git a/lib/crates/fabro-cli/tests/it/cmd/workflow_list.rs b/lib/apps/fabro-cli/tests/it/cmd/workflow_list.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/cmd/workflow_list.rs
rename to lib/apps/fabro-cli/tests/it/cmd/workflow_list.rs
diff --git a/lib/crates/fabro-cli/tests/it/main.rs b/lib/apps/fabro-cli/tests/it/main.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/main.rs
rename to lib/apps/fabro-cli/tests/it/main.rs
diff --git a/lib/crates/fabro-cli/tests/it/scenario/archive.rs b/lib/apps/fabro-cli/tests/it/scenario/archive.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/scenario/archive.rs
rename to lib/apps/fabro-cli/tests/it/scenario/archive.rs
diff --git a/lib/crates/fabro-cli/tests/it/scenario/artifacts.rs b/lib/apps/fabro-cli/tests/it/scenario/artifacts.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/scenario/artifacts.rs
rename to lib/apps/fabro-cli/tests/it/scenario/artifacts.rs
diff --git a/lib/crates/fabro-cli/tests/it/scenario/auth.rs b/lib/apps/fabro-cli/tests/it/scenario/auth.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/scenario/auth.rs
rename to lib/apps/fabro-cli/tests/it/scenario/auth.rs
diff --git a/lib/crates/fabro-cli/tests/it/scenario/exec.rs b/lib/apps/fabro-cli/tests/it/scenario/exec.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/scenario/exec.rs
rename to lib/apps/fabro-cli/tests/it/scenario/exec.rs
diff --git a/lib/crates/fabro-cli/tests/it/scenario/lifecycle.rs b/lib/apps/fabro-cli/tests/it/scenario/lifecycle.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/scenario/lifecycle.rs
rename to lib/apps/fabro-cli/tests/it/scenario/lifecycle.rs
diff --git a/lib/crates/fabro-cli/tests/it/scenario/mod.rs b/lib/apps/fabro-cli/tests/it/scenario/mod.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/scenario/mod.rs
rename to lib/apps/fabro-cli/tests/it/scenario/mod.rs
diff --git a/lib/crates/fabro-cli/tests/it/scenario/server_lifecycle.rs b/lib/apps/fabro-cli/tests/it/scenario/server_lifecycle.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/scenario/server_lifecycle.rs
rename to lib/apps/fabro-cli/tests/it/scenario/server_lifecycle.rs
diff --git a/lib/crates/fabro-cli/tests/it/scenario/smoke.rs b/lib/apps/fabro-cli/tests/it/scenario/smoke.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/scenario/smoke.rs
rename to lib/apps/fabro-cli/tests/it/scenario/smoke.rs
diff --git a/lib/crates/fabro-cli/tests/it/support/auth_harness.rs b/lib/apps/fabro-cli/tests/it/support/auth_harness.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/support/auth_harness.rs
rename to lib/apps/fabro-cli/tests/it/support/auth_harness.rs
diff --git a/lib/crates/fabro-cli/tests/it/support/auth_tokens.rs b/lib/apps/fabro-cli/tests/it/support/auth_tokens.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/support/auth_tokens.rs
rename to lib/apps/fabro-cli/tests/it/support/auth_tokens.rs
diff --git a/lib/crates/fabro-cli/tests/it/support/mod.rs b/lib/apps/fabro-cli/tests/it/support/mod.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/support/mod.rs
rename to lib/apps/fabro-cli/tests/it/support/mod.rs
diff --git a/lib/crates/fabro-cli/tests/it/workflow/acp.rs b/lib/apps/fabro-cli/tests/it/workflow/acp.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/workflow/acp.rs
rename to lib/apps/fabro-cli/tests/it/workflow/acp.rs
diff --git a/lib/crates/fabro-cli/tests/it/workflow/agent_linear.rs b/lib/apps/fabro-cli/tests/it/workflow/agent_linear.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/workflow/agent_linear.rs
rename to lib/apps/fabro-cli/tests/it/workflow/agent_linear.rs
diff --git a/lib/crates/fabro-cli/tests/it/workflow/artifacts.rs b/lib/apps/fabro-cli/tests/it/workflow/artifacts.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/workflow/artifacts.rs
rename to lib/apps/fabro-cli/tests/it/workflow/artifacts.rs
diff --git a/lib/crates/fabro-cli/tests/it/workflow/command_agent_mixed.rs b/lib/apps/fabro-cli/tests/it/workflow/command_agent_mixed.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/workflow/command_agent_mixed.rs
rename to lib/apps/fabro-cli/tests/it/workflow/command_agent_mixed.rs
diff --git a/lib/crates/fabro-cli/tests/it/workflow/command_pipeline.rs b/lib/apps/fabro-cli/tests/it/workflow/command_pipeline.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/workflow/command_pipeline.rs
rename to lib/apps/fabro-cli/tests/it/workflow/command_pipeline.rs
diff --git a/lib/apps/fabro-cli/tests/it/workflow/command_routing.rs b/lib/apps/fabro-cli/tests/it/workflow/command_routing.rs
new file mode 100644
index 000000000..1052ae476
--- /dev/null
+++ b/lib/apps/fabro-cli/tests/it/workflow/command_routing.rs
@@ -0,0 +1,34 @@
+use fabro_test::test_context;
+
+use super::{completed_nodes, find_run_dir, fixture, read_conclusion, sandbox_tests, timeout_for};
+
+sandbox_tests!(command_routing);
+
+fn scenario_command_routing(sandbox: &str) {
+ let context = test_context!();
+ let workflow = fixture("command_routing.fabro");
+
+ context.validate().arg(&workflow).assert().success();
+
+ context
+ .run_cmd()
+ .args(["--auto-approve", "--environment", sandbox])
+ .arg(workflow)
+ .timeout(timeout_for(sandbox))
+ .assert()
+ .success();
+
+ let run_dir = find_run_dir(&context);
+ let conclusion = read_conclusion(&run_dir);
+ assert_eq!(conclusion["status"].as_str(), Some("succeeded"));
+
+ let nodes = completed_nodes(&run_dir);
+ assert!(
+ nodes.contains(&"kept".to_string()),
+ "kept node should be in completed_nodes: {nodes:?}"
+ );
+ assert!(
+ !nodes.contains(&"none".to_string()),
+ "none node should NOT be in completed_nodes: {nodes:?}"
+ );
+}
diff --git a/lib/crates/fabro-cli/tests/it/workflow/conditional_branching.rs b/lib/apps/fabro-cli/tests/it/workflow/conditional_branching.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/workflow/conditional_branching.rs
rename to lib/apps/fabro-cli/tests/it/workflow/conditional_branching.rs
diff --git a/lib/crates/fabro-cli/tests/it/workflow/dry_run_examples.rs b/lib/apps/fabro-cli/tests/it/workflow/dry_run_examples.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/workflow/dry_run_examples.rs
rename to lib/apps/fabro-cli/tests/it/workflow/dry_run_examples.rs
diff --git a/lib/crates/fabro-cli/tests/it/workflow/fixtures/agent_linear.fabro b/lib/apps/fabro-cli/tests/it/workflow/fixtures/agent_linear.fabro
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/workflow/fixtures/agent_linear.fabro
rename to lib/apps/fabro-cli/tests/it/workflow/fixtures/agent_linear.fabro
diff --git a/lib/crates/fabro-cli/tests/it/workflow/fixtures/command_agent_mixed.fabro b/lib/apps/fabro-cli/tests/it/workflow/fixtures/command_agent_mixed.fabro
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/workflow/fixtures/command_agent_mixed.fabro
rename to lib/apps/fabro-cli/tests/it/workflow/fixtures/command_agent_mixed.fabro
diff --git a/lib/crates/fabro-cli/tests/it/workflow/fixtures/command_pipeline.fabro b/lib/apps/fabro-cli/tests/it/workflow/fixtures/command_pipeline.fabro
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/workflow/fixtures/command_pipeline.fabro
rename to lib/apps/fabro-cli/tests/it/workflow/fixtures/command_pipeline.fabro
diff --git a/lib/apps/fabro-cli/tests/it/workflow/fixtures/command_routing.fabro b/lib/apps/fabro-cli/tests/it/workflow/fixtures/command_routing.fabro
new file mode 100644
index 000000000..0c47eccff
--- /dev/null
+++ b/lib/apps/fabro-cli/tests/it/workflow/fixtures/command_routing.fabro
@@ -0,0 +1,23 @@
+digraph CommandRouting {
+ graph [goal="Route on structured output from a command"]
+ rankdir=LR
+
+ start [shape=Mdiamond, label="Start"]
+ exit [shape=Msquare, label="Exit"]
+
+ classify [
+ label="Classify",
+ shape=parallelogram,
+ script="echo '{\"context_updates\":{\"kept_count\":2}}'",
+ output_schema="routing"
+ ]
+ gate [label="Check Count", shape=diamond]
+ kept [label="Kept", shape=parallelogram, script="echo kept"]
+ none [label="None", shape=parallelogram, script="echo none"]
+
+ start -> classify -> gate
+ gate -> kept [label="Kept", condition="context.kept_count > 0"]
+ gate -> none [label="None"]
+ kept -> exit
+ none -> exit
+}
diff --git a/lib/crates/fabro-cli/tests/it/workflow/fixtures/conditional_branching.fabro b/lib/apps/fabro-cli/tests/it/workflow/fixtures/conditional_branching.fabro
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/workflow/fixtures/conditional_branching.fabro
rename to lib/apps/fabro-cli/tests/it/workflow/fixtures/conditional_branching.fabro
diff --git a/lib/crates/fabro-cli/tests/it/workflow/fixtures/full_stack.fabro b/lib/apps/fabro-cli/tests/it/workflow/fixtures/full_stack.fabro
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/workflow/fixtures/full_stack.fabro
rename to lib/apps/fabro-cli/tests/it/workflow/fixtures/full_stack.fabro
diff --git a/lib/crates/fabro-cli/tests/it/workflow/fixtures/human_gate.fabro b/lib/apps/fabro-cli/tests/it/workflow/fixtures/human_gate.fabro
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/workflow/fixtures/human_gate.fabro
rename to lib/apps/fabro-cli/tests/it/workflow/fixtures/human_gate.fabro
diff --git a/lib/crates/fabro-cli/tests/it/workflow/full_stack.rs b/lib/apps/fabro-cli/tests/it/workflow/full_stack.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/workflow/full_stack.rs
rename to lib/apps/fabro-cli/tests/it/workflow/full_stack.rs
diff --git a/lib/crates/fabro-cli/tests/it/workflow/hooks.rs b/lib/apps/fabro-cli/tests/it/workflow/hooks.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/workflow/hooks.rs
rename to lib/apps/fabro-cli/tests/it/workflow/hooks.rs
diff --git a/lib/crates/fabro-cli/tests/it/workflow/human_gate.rs b/lib/apps/fabro-cli/tests/it/workflow/human_gate.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/it/workflow/human_gate.rs
rename to lib/apps/fabro-cli/tests/it/workflow/human_gate.rs
diff --git a/lib/crates/fabro-cli/tests/it/workflow/mod.rs b/lib/apps/fabro-cli/tests/it/workflow/mod.rs
similarity index 99%
rename from lib/crates/fabro-cli/tests/it/workflow/mod.rs
rename to lib/apps/fabro-cli/tests/it/workflow/mod.rs
index 365707d2c..5e0dd3738 100644
--- a/lib/crates/fabro-cli/tests/it/workflow/mod.rs
+++ b/lib/apps/fabro-cli/tests/it/workflow/mod.rs
@@ -8,6 +8,7 @@ mod agent_linear;
mod artifacts;
mod command_agent_mixed;
mod command_pipeline;
+mod command_routing;
mod conditional_branching;
mod dry_run_examples;
mod full_stack;
diff --git a/lib/crates/fabro-cli/tests/manifest_path_round_trip.rs b/lib/apps/fabro-cli/tests/manifest_path_round_trip.rs
similarity index 100%
rename from lib/crates/fabro-cli/tests/manifest_path_round_trip.rs
rename to lib/apps/fabro-cli/tests/manifest_path_round_trip.rs
diff --git a/lib/crates/fabro-mcp-server/Cargo.toml b/lib/apps/fabro-mcp-server/Cargo.toml
similarity index 59%
rename from lib/crates/fabro-mcp-server/Cargo.toml
rename to lib/apps/fabro-mcp-server/Cargo.toml
index de3caa633..cdbf6b65f 100644
--- a/lib/crates/fabro-mcp-server/Cargo.toml
+++ b/lib/apps/fabro-mcp-server/Cargo.toml
@@ -15,15 +15,15 @@ workspace = true
[dependencies]
anyhow.workspace = true
chrono = { workspace = true, features = ["serde"] }
-fabro-api = { path = "../fabro-api" }
-fabro-client = { path = "../fabro-client" }
-fabro-manifest = { path = "../fabro-manifest" }
-fabro-config = { path = "../fabro-config" }
-fabro-model = { path = "../fabro-model" }
+fabro-api = { path = "../../foundation/fabro-api" }
+fabro-client = { path = "../../foundation/fabro-client" }
+fabro-manifest = { path = "../../components/fabro-manifest" }
+fabro-config = { path = "../../foundation/fabro-config" }
+fabro-model = { path = "../../foundation/fabro-model" }
fabro-server = { path = "../fabro-server" }
-fabro-tool = { path = "../fabro-tool" }
-fabro-types = { path = "../fabro-types" }
-fabro-util = { path = "../fabro-util" }
+fabro-tool = { path = "../../components/fabro-tool" }
+fabro-types = { path = "../../foundation/fabro-types" }
+fabro-util = { path = "../../foundation/fabro-util" }
futures.workspace = true
rmcp = { workspace = true, features = ["server", "macros", "schemars", "transport-io"] }
schemars = "1.2.1"
diff --git a/lib/crates/fabro-mcp-server/src/config.rs b/lib/apps/fabro-mcp-server/src/config.rs
similarity index 100%
rename from lib/crates/fabro-mcp-server/src/config.rs
rename to lib/apps/fabro-mcp-server/src/config.rs
diff --git a/lib/crates/fabro-mcp-server/src/lib.rs b/lib/apps/fabro-mcp-server/src/lib.rs
similarity index 100%
rename from lib/crates/fabro-mcp-server/src/lib.rs
rename to lib/apps/fabro-mcp-server/src/lib.rs
diff --git a/lib/crates/fabro-mcp-server/src/manifest_builder.rs b/lib/apps/fabro-mcp-server/src/manifest_builder.rs
similarity index 100%
rename from lib/crates/fabro-mcp-server/src/manifest_builder.rs
rename to lib/apps/fabro-mcp-server/src/manifest_builder.rs
diff --git a/lib/crates/fabro-mcp-server/src/server.rs b/lib/apps/fabro-mcp-server/src/server.rs
similarity index 100%
rename from lib/crates/fabro-mcp-server/src/server.rs
rename to lib/apps/fabro-mcp-server/src/server.rs
diff --git a/lib/crates/fabro-server/Cargo.toml b/lib/apps/fabro-server/Cargo.toml
similarity index 56%
rename from lib/crates/fabro-server/Cargo.toml
rename to lib/apps/fabro-server/Cargo.toml
index b951b339f..1f2c5bb61 100644
--- a/lib/crates/fabro-server/Cargo.toml
+++ b/lib/apps/fabro-server/Cargo.toml
@@ -21,35 +21,35 @@ required-features = ["test-support"]
workspace = true
[dependencies]
-fabro-automation = { path = "../fabro-automation" }
-fabro-auth = { path = "../fabro-auth" }
-fabro-install = { path = "../fabro-install" }
+fabro-automation = { path = "../../components/fabro-automation" }
+fabro-auth = { path = "../../foundation/fabro-auth" }
+fabro-install = { path = "../../components/fabro-install" }
fabro-spa = { path = "../fabro-spa" }
-fabro-config = { path = "../fabro-config" }
+fabro-config = { path = "../../foundation/fabro-config" }
fabro-environment.workspace = true
-fabro-graphviz = { path = "../fabro-graphviz" }
-fabro-hooks = { path = "../fabro-hooks" }
-fabro-interview = { path = "../fabro-interview" }
-fabro-slack = { path = "../fabro-slack" }
-fabro-workflow = { path = "../fabro-workflow" }
-fabro-validate = { path = "../fabro-validate" }
-fabro-sandbox = { path = "../fabro-sandbox", features = ["daytona", "docker"] }
-fabro-github = { path = "../fabro-github" }
-fabro-agent = { path = "../fabro-agent" }
-fabro-llm = { path = "../fabro-llm" }
-fabro-manifest = { path = "../fabro-manifest" }
-fabro-mcp-store = { path = "../fabro-mcp-store" }
-fabro-model = { path = "../fabro-model" }
-fabro-proc = { path = "../fabro-proc" }
-fabro-tool = { path = "../fabro-tool" }
-fabro-types = { path = "../fabro-types" }
-fabro-util = { path = "../fabro-util" }
-fabro-api = { path = "../fabro-api" }
-fabro-client = { path = "../fabro-client" }
-fabro-db = { path = "../fabro-db" }
-fabro-store = { path = "../fabro-store" }
-fabro-vault = { path = "../fabro-vault" }
-fabro-variable = { path = "../fabro-variable" }
+fabro-graphviz = { path = "../../components/fabro-graphviz" }
+fabro-hooks = { path = "../../components/fabro-hooks" }
+fabro-interview = { path = "../../components/fabro-interview" }
+fabro-slack = { path = "../../components/fabro-slack" }
+fabro-workflow = { path = "../../components/fabro-workflow" }
+fabro-validate = { path = "../../components/fabro-validate" }
+fabro-sandbox = { path = "../../components/fabro-sandbox", features = ["daytona", "docker"] }
+fabro-github = { path = "../../components/fabro-github" }
+fabro-agent = { path = "../../components/fabro-agent" }
+fabro-llm = { path = "../../components/fabro-llm" }
+fabro-manifest = { path = "../../components/fabro-manifest" }
+fabro-mcp-store = { path = "../../components/fabro-mcp-store" }
+fabro-model = { path = "../../foundation/fabro-model" }
+fabro-proc = { path = "../../foundation/fabro-proc" }
+fabro-tool = { path = "../../components/fabro-tool" }
+fabro-types = { path = "../../foundation/fabro-types" }
+fabro-util = { path = "../../foundation/fabro-util" }
+fabro-api = { path = "../../foundation/fabro-api" }
+fabro-client = { path = "../../foundation/fabro-client" }
+fabro-db = { path = "../../foundation/fabro-db" }
+fabro-store = { path = "../../components/fabro-store" }
+fabro-vault = { path = "../../foundation/fabro-vault" }
+fabro-variable = { path = "../../components/fabro-variable" }
fabro-http.workspace = true
fabro-redact.workspace = true
fabro-static.workspace = true
@@ -104,7 +104,7 @@ strum.workspace = true
sysinfo = { version = "0.35.2", default-features = false, features = ["system", "disk"] }
[build-dependencies]
-fabro-build-support = { path = "../build-support" }
+fabro-build-support = { path = "../../foundation/build-support" }
chrono = { workspace = true }
[dev-dependencies]
@@ -117,7 +117,7 @@ sqlx.workspace = true
tracing-subscriber.workspace = true
tokio-util.workspace = true
tokio-tungstenite.workspace = true
-fabro-macros = { path = "../fabro-macros" }
-fabro-sandbox = { path = "../fabro-sandbox", features = ["test-support"] }
+fabro-macros = { path = "../../foundation/fabro-macros" }
+fabro-sandbox = { path = "../../components/fabro-sandbox", features = ["test-support"] }
fabro-test = { workspace = true }
-fabro-types = { path = "../fabro-types", features = ["test-support"] }
+fabro-types = { path = "../../foundation/fabro-types", features = ["test-support"] }
diff --git a/lib/crates/fabro-server/build.rs b/lib/apps/fabro-server/build.rs
similarity index 100%
rename from lib/crates/fabro-server/build.rs
rename to lib/apps/fabro-server/build.rs
diff --git a/lib/crates/fabro-server/migrations/2026051801_legacy_vault_entries.rs b/lib/apps/fabro-server/migrations/2026051801_legacy_vault_entries.rs
similarity index 100%
rename from lib/crates/fabro-server/migrations/2026051801_legacy_vault_entries.rs
rename to lib/apps/fabro-server/migrations/2026051801_legacy_vault_entries.rs
diff --git a/lib/crates/fabro-server/migrations/2026052501_optional_server_env_secrets_to_vault.rs b/lib/apps/fabro-server/migrations/2026052501_optional_server_env_secrets_to_vault.rs
similarity index 100%
rename from lib/crates/fabro-server/migrations/2026052501_optional_server_env_secrets_to_vault.rs
rename to lib/apps/fabro-server/migrations/2026052501_optional_server_env_secrets_to_vault.rs
diff --git a/lib/crates/fabro-server/src/auth/browser_shell.rs b/lib/apps/fabro-server/src/auth/browser_shell.rs
similarity index 100%
rename from lib/crates/fabro-server/src/auth/browser_shell.rs
rename to lib/apps/fabro-server/src/auth/browser_shell.rs
diff --git a/lib/crates/fabro-server/src/auth/cli_flow.rs b/lib/apps/fabro-server/src/auth/cli_flow.rs
similarity index 100%
rename from lib/crates/fabro-server/src/auth/cli_flow.rs
rename to lib/apps/fabro-server/src/auth/cli_flow.rs
diff --git a/lib/crates/fabro-server/src/auth/github_endpoints.rs b/lib/apps/fabro-server/src/auth/github_endpoints.rs
similarity index 100%
rename from lib/crates/fabro-server/src/auth/github_endpoints.rs
rename to lib/apps/fabro-server/src/auth/github_endpoints.rs
diff --git a/lib/crates/fabro-server/src/auth/jwt.rs b/lib/apps/fabro-server/src/auth/jwt.rs
similarity index 100%
rename from lib/crates/fabro-server/src/auth/jwt.rs
rename to lib/apps/fabro-server/src/auth/jwt.rs
diff --git a/lib/crates/fabro-server/src/auth/keys.rs b/lib/apps/fabro-server/src/auth/keys.rs
similarity index 100%
rename from lib/crates/fabro-server/src/auth/keys.rs
rename to lib/apps/fabro-server/src/auth/keys.rs
diff --git a/lib/crates/fabro-server/src/auth/mod.rs b/lib/apps/fabro-server/src/auth/mod.rs
similarity index 100%
rename from lib/crates/fabro-server/src/auth/mod.rs
rename to lib/apps/fabro-server/src/auth/mod.rs
diff --git a/lib/crates/fabro-server/src/auth/translate.rs b/lib/apps/fabro-server/src/auth/translate.rs
similarity index 100%
rename from lib/crates/fabro-server/src/auth/translate.rs
rename to lib/apps/fabro-server/src/auth/translate.rs
diff --git a/lib/crates/fabro-server/src/automation_materializer.rs b/lib/apps/fabro-server/src/automation_materializer.rs
similarity index 100%
rename from lib/crates/fabro-server/src/automation_materializer.rs
rename to lib/apps/fabro-server/src/automation_materializer.rs
diff --git a/lib/crates/fabro-server/src/canonical_host.rs b/lib/apps/fabro-server/src/canonical_host.rs
similarity index 100%
rename from lib/crates/fabro-server/src/canonical_host.rs
rename to lib/apps/fabro-server/src/canonical_host.rs
diff --git a/lib/crates/fabro-server/src/canonical_origin.rs b/lib/apps/fabro-server/src/canonical_origin.rs
similarity index 100%
rename from lib/crates/fabro-server/src/canonical_origin.rs
rename to lib/apps/fabro-server/src/canonical_origin.rs
diff --git a/lib/crates/fabro-server/src/csp.rs b/lib/apps/fabro-server/src/csp.rs
similarity index 100%
rename from lib/crates/fabro-server/src/csp.rs
rename to lib/apps/fabro-server/src/csp.rs
diff --git a/lib/crates/fabro-server/src/demo/mod.rs b/lib/apps/fabro-server/src/demo/mod.rs
similarity index 100%
rename from lib/crates/fabro-server/src/demo/mod.rs
rename to lib/apps/fabro-server/src/demo/mod.rs
diff --git a/lib/crates/fabro-server/src/diagnostics.rs b/lib/apps/fabro-server/src/diagnostics.rs
similarity index 100%
rename from lib/crates/fabro-server/src/diagnostics.rs
rename to lib/apps/fabro-server/src/diagnostics.rs
diff --git a/lib/crates/fabro-server/src/error.rs b/lib/apps/fabro-server/src/error.rs
similarity index 100%
rename from lib/crates/fabro-server/src/error.rs
rename to lib/apps/fabro-server/src/error.rs
diff --git a/lib/crates/fabro-server/src/git_checkout.rs b/lib/apps/fabro-server/src/git_checkout.rs
similarity index 100%
rename from lib/crates/fabro-server/src/git_checkout.rs
rename to lib/apps/fabro-server/src/git_checkout.rs
diff --git a/lib/crates/fabro-server/src/github_webhooks.rs b/lib/apps/fabro-server/src/github_webhooks.rs
similarity index 100%
rename from lib/crates/fabro-server/src/github_webhooks.rs
rename to lib/apps/fabro-server/src/github_webhooks.rs
diff --git a/lib/crates/fabro-server/src/install.rs b/lib/apps/fabro-server/src/install.rs
similarity index 100%
rename from lib/crates/fabro-server/src/install.rs
rename to lib/apps/fabro-server/src/install.rs
diff --git a/lib/crates/fabro-server/src/interp.rs b/lib/apps/fabro-server/src/interp.rs
similarity index 100%
rename from lib/crates/fabro-server/src/interp.rs
rename to lib/apps/fabro-server/src/interp.rs
diff --git a/lib/crates/fabro-server/src/jwt_auth.rs b/lib/apps/fabro-server/src/jwt_auth.rs
similarity index 100%
rename from lib/crates/fabro-server/src/jwt_auth.rs
rename to lib/apps/fabro-server/src/jwt_auth.rs
diff --git a/lib/crates/fabro-server/src/lib.rs b/lib/apps/fabro-server/src/lib.rs
similarity index 100%
rename from lib/crates/fabro-server/src/lib.rs
rename to lib/apps/fabro-server/src/lib.rs
diff --git a/lib/crates/fabro-server/src/manifest_validation.rs b/lib/apps/fabro-server/src/manifest_validation.rs
similarity index 100%
rename from lib/crates/fabro-server/src/manifest_validation.rs
rename to lib/apps/fabro-server/src/manifest_validation.rs
diff --git a/lib/crates/fabro-server/src/migrations.rs b/lib/apps/fabro-server/src/migrations.rs
similarity index 100%
rename from lib/crates/fabro-server/src/migrations.rs
rename to lib/apps/fabro-server/src/migrations.rs
diff --git a/lib/crates/fabro-server/src/principal_middleware.rs b/lib/apps/fabro-server/src/principal_middleware.rs
similarity index 100%
rename from lib/crates/fabro-server/src/principal_middleware.rs
rename to lib/apps/fabro-server/src/principal_middleware.rs
diff --git a/lib/crates/fabro-server/src/request_id.rs b/lib/apps/fabro-server/src/request_id.rs
similarity index 100%
rename from lib/crates/fabro-server/src/request_id.rs
rename to lib/apps/fabro-server/src/request_id.rs
diff --git a/lib/crates/fabro-server/src/run_files.rs b/lib/apps/fabro-server/src/run_files.rs
similarity index 100%
rename from lib/crates/fabro-server/src/run_files.rs
rename to lib/apps/fabro-server/src/run_files.rs
diff --git a/lib/crates/fabro-server/src/run_files_security.rs b/lib/apps/fabro-server/src/run_files_security.rs
similarity index 100%
rename from lib/crates/fabro-server/src/run_files_security.rs
rename to lib/apps/fabro-server/src/run_files_security.rs
diff --git a/lib/crates/fabro-server/src/run_manifest.rs b/lib/apps/fabro-server/src/run_manifest.rs
similarity index 100%
rename from lib/crates/fabro-server/src/run_manifest.rs
rename to lib/apps/fabro-server/src/run_manifest.rs
diff --git a/lib/crates/fabro-server/src/run_selector.rs b/lib/apps/fabro-server/src/run_selector.rs
similarity index 100%
rename from lib/crates/fabro-server/src/run_selector.rs
rename to lib/apps/fabro-server/src/run_selector.rs
diff --git a/lib/crates/fabro-server/src/run_title_generation.rs b/lib/apps/fabro-server/src/run_title_generation.rs
similarity index 100%
rename from lib/crates/fabro-server/src/run_title_generation.rs
rename to lib/apps/fabro-server/src/run_title_generation.rs
diff --git a/lib/crates/fabro-server/src/run_tool_manifest.rs b/lib/apps/fabro-server/src/run_tool_manifest.rs
similarity index 100%
rename from lib/crates/fabro-server/src/run_tool_manifest.rs
rename to lib/apps/fabro-server/src/run_tool_manifest.rs
diff --git a/lib/crates/fabro-server/src/security_headers.rs b/lib/apps/fabro-server/src/security_headers.rs
similarity index 100%
rename from lib/crates/fabro-server/src/security_headers.rs
rename to lib/apps/fabro-server/src/security_headers.rs
diff --git a/lib/crates/fabro-server/src/serve.rs b/lib/apps/fabro-server/src/serve.rs
similarity index 100%
rename from lib/crates/fabro-server/src/serve.rs
rename to lib/apps/fabro-server/src/serve.rs
diff --git a/lib/crates/fabro-server/src/server.rs b/lib/apps/fabro-server/src/server.rs
similarity index 100%
rename from lib/crates/fabro-server/src/server.rs
rename to lib/apps/fabro-server/src/server.rs
diff --git a/lib/crates/fabro-server/src/server/automation_scheduler.rs b/lib/apps/fabro-server/src/server/automation_scheduler.rs
similarity index 100%
rename from lib/crates/fabro-server/src/server/automation_scheduler.rs
rename to lib/apps/fabro-server/src/server/automation_scheduler.rs
diff --git a/lib/crates/fabro-server/src/server/handler/artifacts.rs b/lib/apps/fabro-server/src/server/handler/artifacts.rs
similarity index 100%
rename from lib/crates/fabro-server/src/server/handler/artifacts.rs
rename to lib/apps/fabro-server/src/server/handler/artifacts.rs
diff --git a/lib/crates/fabro-server/src/server/handler/automations.rs b/lib/apps/fabro-server/src/server/handler/automations.rs
similarity index 100%
rename from lib/crates/fabro-server/src/server/handler/automations.rs
rename to lib/apps/fabro-server/src/server/handler/automations.rs
diff --git a/lib/crates/fabro-server/src/server/handler/billing.rs b/lib/apps/fabro-server/src/server/handler/billing.rs
similarity index 100%
rename from lib/crates/fabro-server/src/server/handler/billing.rs
rename to lib/apps/fabro-server/src/server/handler/billing.rs
diff --git a/lib/crates/fabro-server/src/server/handler/completions.rs b/lib/apps/fabro-server/src/server/handler/completions.rs
similarity index 100%
rename from lib/crates/fabro-server/src/server/handler/completions.rs
rename to lib/apps/fabro-server/src/server/handler/completions.rs
diff --git a/lib/crates/fabro-server/src/server/handler/environments.rs b/lib/apps/fabro-server/src/server/handler/environments.rs
similarity index 100%
rename from lib/crates/fabro-server/src/server/handler/environments.rs
rename to lib/apps/fabro-server/src/server/handler/environments.rs
diff --git a/lib/crates/fabro-server/src/server/handler/events.rs b/lib/apps/fabro-server/src/server/handler/events.rs
similarity index 100%
rename from lib/crates/fabro-server/src/server/handler/events.rs
rename to lib/apps/fabro-server/src/server/handler/events.rs
diff --git a/lib/crates/fabro-server/src/server/handler/graph.rs b/lib/apps/fabro-server/src/server/handler/graph.rs
similarity index 100%
rename from lib/crates/fabro-server/src/server/handler/graph.rs
rename to lib/apps/fabro-server/src/server/handler/graph.rs
diff --git a/lib/crates/fabro-server/src/server/handler/lifecycle.rs b/lib/apps/fabro-server/src/server/handler/lifecycle.rs
similarity index 100%
rename from lib/crates/fabro-server/src/server/handler/lifecycle.rs
rename to lib/apps/fabro-server/src/server/handler/lifecycle.rs
diff --git a/lib/crates/fabro-server/src/server/handler/llm_sse.rs b/lib/apps/fabro-server/src/server/handler/llm_sse.rs
similarity index 100%
rename from lib/crates/fabro-server/src/server/handler/llm_sse.rs
rename to lib/apps/fabro-server/src/server/handler/llm_sse.rs
diff --git a/lib/crates/fabro-server/src/server/handler/mcp_servers.rs b/lib/apps/fabro-server/src/server/handler/mcp_servers.rs
similarity index 100%
rename from lib/crates/fabro-server/src/server/handler/mcp_servers.rs
rename to lib/apps/fabro-server/src/server/handler/mcp_servers.rs
diff --git a/lib/crates/fabro-server/src/server/handler/mod.rs b/lib/apps/fabro-server/src/server/handler/mod.rs
similarity index 100%
rename from lib/crates/fabro-server/src/server/handler/mod.rs
rename to lib/apps/fabro-server/src/server/handler/mod.rs
diff --git a/lib/crates/fabro-server/src/server/handler/models.rs b/lib/apps/fabro-server/src/server/handler/models.rs
similarity index 100%
rename from lib/crates/fabro-server/src/server/handler/models.rs
rename to lib/apps/fabro-server/src/server/handler/models.rs
diff --git a/lib/crates/fabro-server/src/server/handler/pair.rs b/lib/apps/fabro-server/src/server/handler/pair.rs
similarity index 100%
rename from lib/crates/fabro-server/src/server/handler/pair.rs
rename to lib/apps/fabro-server/src/server/handler/pair.rs
diff --git a/lib/crates/fabro-server/src/server/handler/playground.rs b/lib/apps/fabro-server/src/server/handler/playground.rs
similarity index 100%
rename from lib/crates/fabro-server/src/server/handler/playground.rs
rename to lib/apps/fabro-server/src/server/handler/playground.rs
diff --git a/lib/crates/fabro-server/src/server/handler/prompts/playground_system.md b/lib/apps/fabro-server/src/server/handler/prompts/playground_system.md
similarity index 100%
rename from lib/crates/fabro-server/src/server/handler/prompts/playground_system.md
rename to lib/apps/fabro-server/src/server/handler/prompts/playground_system.md
diff --git a/lib/crates/fabro-server/src/server/handler/pull_requests.rs b/lib/apps/fabro-server/src/server/handler/pull_requests.rs
similarity index 100%
rename from lib/crates/fabro-server/src/server/handler/pull_requests.rs
rename to lib/apps/fabro-server/src/server/handler/pull_requests.rs
diff --git a/lib/crates/fabro-server/src/server/handler/runs.rs b/lib/apps/fabro-server/src/server/handler/runs.rs
similarity index 100%
rename from lib/crates/fabro-server/src/server/handler/runs.rs
rename to lib/apps/fabro-server/src/server/handler/runs.rs
diff --git a/lib/crates/fabro-server/src/server/handler/sandbox.rs b/lib/apps/fabro-server/src/server/handler/sandbox.rs
similarity index 100%
rename from lib/crates/fabro-server/src/server/handler/sandbox.rs
rename to lib/apps/fabro-server/src/server/handler/sandbox.rs
diff --git a/lib/crates/fabro-server/src/server/handler/sandboxes.rs b/lib/apps/fabro-server/src/server/handler/sandboxes.rs
similarity index 100%
rename from lib/crates/fabro-server/src/server/handler/sandboxes.rs
rename to lib/apps/fabro-server/src/server/handler/sandboxes.rs
diff --git a/lib/crates/fabro-server/src/server/handler/secrets.rs b/lib/apps/fabro-server/src/server/handler/secrets.rs
similarity index 100%
rename from lib/crates/fabro-server/src/server/handler/secrets.rs
rename to lib/apps/fabro-server/src/server/handler/secrets.rs
diff --git a/lib/crates/fabro-server/src/server/handler/sessions.rs b/lib/apps/fabro-server/src/server/handler/sessions.rs
similarity index 100%
rename from lib/crates/fabro-server/src/server/handler/sessions.rs
rename to lib/apps/fabro-server/src/server/handler/sessions.rs
diff --git a/lib/crates/fabro-server/src/server/handler/steer.rs b/lib/apps/fabro-server/src/server/handler/steer.rs
similarity index 100%
rename from lib/crates/fabro-server/src/server/handler/steer.rs
rename to lib/apps/fabro-server/src/server/handler/steer.rs
diff --git a/lib/crates/fabro-server/src/server/handler/system.rs b/lib/apps/fabro-server/src/server/handler/system.rs
similarity index 100%
rename from lib/crates/fabro-server/src/server/handler/system.rs
rename to lib/apps/fabro-server/src/server/handler/system.rs
diff --git a/lib/crates/fabro-server/src/server/handler/variables.rs b/lib/apps/fabro-server/src/server/handler/variables.rs
similarity index 100%
rename from lib/crates/fabro-server/src/server/handler/variables.rs
rename to lib/apps/fabro-server/src/server/handler/variables.rs
diff --git a/lib/crates/fabro-server/src/server/handler/worker_control.rs b/lib/apps/fabro-server/src/server/handler/worker_control.rs
similarity index 100%
rename from lib/crates/fabro-server/src/server/handler/worker_control.rs
rename to lib/apps/fabro-server/src/server/handler/worker_control.rs
diff --git a/lib/crates/fabro-server/src/server/resource_sampler.rs b/lib/apps/fabro-server/src/server/resource_sampler.rs
similarity index 100%
rename from lib/crates/fabro-server/src/server/resource_sampler.rs
rename to lib/apps/fabro-server/src/server/resource_sampler.rs
diff --git a/lib/crates/fabro-server/src/server/session_runtime.rs b/lib/apps/fabro-server/src/server/session_runtime.rs
similarity index 100%
rename from lib/crates/fabro-server/src/server/session_runtime.rs
rename to lib/apps/fabro-server/src/server/session_runtime.rs
diff --git a/lib/crates/fabro-server/src/server/tests.rs b/lib/apps/fabro-server/src/server/tests.rs
similarity index 100%
rename from lib/crates/fabro-server/src/server/tests.rs
rename to lib/apps/fabro-server/src/server/tests.rs
diff --git a/lib/crates/fabro-server/src/server_secrets.rs b/lib/apps/fabro-server/src/server_secrets.rs
similarity index 100%
rename from lib/crates/fabro-server/src/server_secrets.rs
rename to lib/apps/fabro-server/src/server_secrets.rs
diff --git a/lib/crates/fabro-server/src/spawn_env.rs b/lib/apps/fabro-server/src/spawn_env.rs
similarity index 100%
rename from lib/crates/fabro-server/src/spawn_env.rs
rename to lib/apps/fabro-server/src/spawn_env.rs
diff --git a/lib/crates/fabro-server/src/startup.rs b/lib/apps/fabro-server/src/startup.rs
similarity index 100%
rename from lib/crates/fabro-server/src/startup.rs
rename to lib/apps/fabro-server/src/startup.rs
diff --git a/lib/crates/fabro-server/src/static_files.rs b/lib/apps/fabro-server/src/static_files.rs
similarity index 99%
rename from lib/crates/fabro-server/src/static_files.rs
rename to lib/apps/fabro-server/src/static_files.rs
index cb5c500a2..b0a9e623e 100644
--- a/lib/crates/fabro-server/src/static_files.rs
+++ b/lib/apps/fabro-server/src/static_files.rs
@@ -632,7 +632,7 @@ mod tests {
#[tokio::test]
async fn dev_disk_only_does_not_fall_back_to_embedded() {
// The embedded SPA snapshot has chunk-12xq903b.js (observed in
- // lib/crates/fabro-spa/assets/index.html). In disk-only mode that
+ // lib/apps/fabro-spa/assets/index.html). In disk-only mode that
// bytes-on-disk-or-503 contract must hold even for assets the
// embedded snapshot would otherwise serve.
let temp_dir = tempfile::tempdir().unwrap();
diff --git a/lib/crates/fabro-server/src/test_support.rs b/lib/apps/fabro-server/src/test_support.rs
similarity index 100%
rename from lib/crates/fabro-server/src/test_support.rs
rename to lib/apps/fabro-server/src/test_support.rs
diff --git a/lib/crates/fabro-server/src/web_auth.rs b/lib/apps/fabro-server/src/web_auth.rs
similarity index 100%
rename from lib/crates/fabro-server/src/web_auth.rs
rename to lib/apps/fabro-server/src/web_auth.rs
diff --git a/lib/crates/fabro-server/src/worker_control/bus.rs b/lib/apps/fabro-server/src/worker_control/bus.rs
similarity index 100%
rename from lib/crates/fabro-server/src/worker_control/bus.rs
rename to lib/apps/fabro-server/src/worker_control/bus.rs
diff --git a/lib/crates/fabro-server/src/worker_control/local.rs b/lib/apps/fabro-server/src/worker_control/local.rs
similarity index 100%
rename from lib/crates/fabro-server/src/worker_control/local.rs
rename to lib/apps/fabro-server/src/worker_control/local.rs
diff --git a/lib/crates/fabro-server/src/worker_control/mod.rs b/lib/apps/fabro-server/src/worker_control/mod.rs
similarity index 100%
rename from lib/crates/fabro-server/src/worker_control/mod.rs
rename to lib/apps/fabro-server/src/worker_control/mod.rs
diff --git a/lib/crates/fabro-server/src/worker_runtime.rs b/lib/apps/fabro-server/src/worker_runtime.rs
similarity index 100%
rename from lib/crates/fabro-server/src/worker_runtime.rs
rename to lib/apps/fabro-server/src/worker_runtime.rs
diff --git a/lib/crates/fabro-server/src/worker_token.rs b/lib/apps/fabro-server/src/worker_token.rs
similarity index 100%
rename from lib/crates/fabro-server/src/worker_token.rs
rename to lib/apps/fabro-server/src/worker_token.rs
diff --git a/lib/crates/fabro-server/tests/fixtures/spa/images/favicon.svg b/lib/apps/fabro-server/tests/fixtures/spa/images/favicon.svg
similarity index 100%
rename from lib/crates/fabro-server/tests/fixtures/spa/images/favicon.svg
rename to lib/apps/fabro-server/tests/fixtures/spa/images/favicon.svg
diff --git a/lib/crates/fabro-server/tests/fixtures/spa/index.html b/lib/apps/fabro-server/tests/fixtures/spa/index.html
similarity index 100%
rename from lib/crates/fabro-server/tests/fixtures/spa/index.html
rename to lib/apps/fabro-server/tests/fixtures/spa/index.html
diff --git a/lib/crates/fabro-server/tests/it/api/auth_sessions.rs b/lib/apps/fabro-server/tests/it/api/auth_sessions.rs
similarity index 100%
rename from lib/crates/fabro-server/tests/it/api/auth_sessions.rs
rename to lib/apps/fabro-server/tests/it/api/auth_sessions.rs
diff --git a/lib/crates/fabro-server/tests/it/api/automations.rs b/lib/apps/fabro-server/tests/it/api/automations.rs
similarity index 100%
rename from lib/crates/fabro-server/tests/it/api/automations.rs
rename to lib/apps/fabro-server/tests/it/api/automations.rs
diff --git a/lib/crates/fabro-server/tests/it/api/cli_auth_token.rs b/lib/apps/fabro-server/tests/it/api/cli_auth_token.rs
similarity index 100%
rename from lib/crates/fabro-server/tests/it/api/cli_auth_token.rs
rename to lib/apps/fabro-server/tests/it/api/cli_auth_token.rs
diff --git a/lib/crates/fabro-server/tests/it/api/compression.rs b/lib/apps/fabro-server/tests/it/api/compression.rs
similarity index 100%
rename from lib/crates/fabro-server/tests/it/api/compression.rs
rename to lib/apps/fabro-server/tests/it/api/compression.rs
diff --git a/lib/crates/fabro-server/tests/it/api/docs.rs b/lib/apps/fabro-server/tests/it/api/docs.rs
similarity index 100%
rename from lib/crates/fabro-server/tests/it/api/docs.rs
rename to lib/apps/fabro-server/tests/it/api/docs.rs
diff --git a/lib/crates/fabro-server/tests/it/api/environments.rs b/lib/apps/fabro-server/tests/it/api/environments.rs
similarity index 100%
rename from lib/crates/fabro-server/tests/it/api/environments.rs
rename to lib/apps/fabro-server/tests/it/api/environments.rs
diff --git a/lib/crates/fabro-server/tests/it/api/events.rs b/lib/apps/fabro-server/tests/it/api/events.rs
similarity index 100%
rename from lib/crates/fabro-server/tests/it/api/events.rs
rename to lib/apps/fabro-server/tests/it/api/events.rs
diff --git a/lib/crates/fabro-server/tests/it/api/install.rs b/lib/apps/fabro-server/tests/it/api/install.rs
similarity index 100%
rename from lib/crates/fabro-server/tests/it/api/install.rs
rename to lib/apps/fabro-server/tests/it/api/install.rs
diff --git a/lib/crates/fabro-server/tests/it/api/install_openai_compatible.rs b/lib/apps/fabro-server/tests/it/api/install_openai_compatible.rs
similarity index 100%
rename from lib/crates/fabro-server/tests/it/api/install_openai_compatible.rs
rename to lib/apps/fabro-server/tests/it/api/install_openai_compatible.rs
diff --git a/lib/crates/fabro-server/tests/it/api/mcp_servers.rs b/lib/apps/fabro-server/tests/it/api/mcp_servers.rs
similarity index 100%
rename from lib/crates/fabro-server/tests/it/api/mcp_servers.rs
rename to lib/apps/fabro-server/tests/it/api/mcp_servers.rs
diff --git a/lib/crates/fabro-server/tests/it/api/mod.rs b/lib/apps/fabro-server/tests/it/api/mod.rs
similarity index 100%
rename from lib/crates/fabro-server/tests/it/api/mod.rs
rename to lib/apps/fabro-server/tests/it/api/mod.rs
diff --git a/lib/crates/fabro-server/tests/it/api/routing.rs b/lib/apps/fabro-server/tests/it/api/routing.rs
similarity index 100%
rename from lib/crates/fabro-server/tests/it/api/routing.rs
rename to lib/apps/fabro-server/tests/it/api/routing.rs
diff --git a/lib/crates/fabro-server/tests/it/api/run_files.rs b/lib/apps/fabro-server/tests/it/api/run_files.rs
similarity index 100%
rename from lib/crates/fabro-server/tests/it/api/run_files.rs
rename to lib/apps/fabro-server/tests/it/api/run_files.rs
diff --git a/lib/crates/fabro-server/tests/it/api/runs.rs b/lib/apps/fabro-server/tests/it/api/runs.rs
similarity index 100%
rename from lib/crates/fabro-server/tests/it/api/runs.rs
rename to lib/apps/fabro-server/tests/it/api/runs.rs
diff --git a/lib/crates/fabro-server/tests/it/api/sandbox_vnc.rs b/lib/apps/fabro-server/tests/it/api/sandbox_vnc.rs
similarity index 100%
rename from lib/crates/fabro-server/tests/it/api/sandbox_vnc.rs
rename to lib/apps/fabro-server/tests/it/api/sandbox_vnc.rs
diff --git a/lib/crates/fabro-server/tests/it/api/sessions.rs b/lib/apps/fabro-server/tests/it/api/sessions.rs
similarity index 100%
rename from lib/crates/fabro-server/tests/it/api/sessions.rs
rename to lib/apps/fabro-server/tests/it/api/sessions.rs
diff --git a/lib/crates/fabro-server/tests/it/api/settings.rs b/lib/apps/fabro-server/tests/it/api/settings.rs
similarity index 100%
rename from lib/crates/fabro-server/tests/it/api/settings.rs
rename to lib/apps/fabro-server/tests/it/api/settings.rs
diff --git a/lib/crates/fabro-server/tests/it/api/system.rs b/lib/apps/fabro-server/tests/it/api/system.rs
similarity index 100%
rename from lib/crates/fabro-server/tests/it/api/system.rs
rename to lib/apps/fabro-server/tests/it/api/system.rs
diff --git a/lib/crates/fabro-server/tests/it/api/tcp.rs b/lib/apps/fabro-server/tests/it/api/tcp.rs
similarity index 100%
rename from lib/crates/fabro-server/tests/it/api/tcp.rs
rename to lib/apps/fabro-server/tests/it/api/tcp.rs
diff --git a/lib/crates/fabro-server/tests/it/api/variables.rs b/lib/apps/fabro-server/tests/it/api/variables.rs
similarity index 100%
rename from lib/crates/fabro-server/tests/it/api/variables.rs
rename to lib/apps/fabro-server/tests/it/api/variables.rs
diff --git a/lib/crates/fabro-server/tests/it/event_pagination.rs b/lib/apps/fabro-server/tests/it/event_pagination.rs
similarity index 100%
rename from lib/crates/fabro-server/tests/it/event_pagination.rs
rename to lib/apps/fabro-server/tests/it/event_pagination.rs
diff --git a/lib/crates/fabro-server/tests/it/helpers.rs b/lib/apps/fabro-server/tests/it/helpers.rs
similarity index 99%
rename from lib/crates/fabro-server/tests/it/helpers.rs
rename to lib/apps/fabro-server/tests/it/helpers.rs
index 569f7e7d0..9ecf30bb8 100644
--- a/lib/crates/fabro-server/tests/it/helpers.rs
+++ b/lib/apps/fabro-server/tests/it/helpers.rs
@@ -142,7 +142,7 @@ pub(crate) fn repo_root() -> PathBuf {
std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
.ancestors()
.nth(3)
- .expect("fabro-server crate should be nested under lib/crates/fabro-server")
+ .expect("fabro-server crate should be nested under lib/apps/fabro-server")
.to_path_buf()
}
diff --git a/lib/crates/fabro-server/tests/it/main.rs b/lib/apps/fabro-server/tests/it/main.rs
similarity index 100%
rename from lib/crates/fabro-server/tests/it/main.rs
rename to lib/apps/fabro-server/tests/it/main.rs
diff --git a/lib/crates/fabro-server/tests/it/openapi_conformance.rs b/lib/apps/fabro-server/tests/it/openapi_conformance.rs
similarity index 100%
rename from lib/crates/fabro-server/tests/it/openapi_conformance.rs
rename to lib/apps/fabro-server/tests/it/openapi_conformance.rs
diff --git a/lib/crates/fabro-server/tests/it/pagination.rs b/lib/apps/fabro-server/tests/it/pagination.rs
similarity index 100%
rename from lib/crates/fabro-server/tests/it/pagination.rs
rename to lib/apps/fabro-server/tests/it/pagination.rs
diff --git a/lib/crates/fabro-server/tests/it/scenario/archive.rs b/lib/apps/fabro-server/tests/it/scenario/archive.rs
similarity index 100%
rename from lib/crates/fabro-server/tests/it/scenario/archive.rs
rename to lib/apps/fabro-server/tests/it/scenario/archive.rs
diff --git a/lib/crates/fabro-server/tests/it/scenario/dry_run.rs b/lib/apps/fabro-server/tests/it/scenario/dry_run.rs
similarity index 100%
rename from lib/crates/fabro-server/tests/it/scenario/dry_run.rs
rename to lib/apps/fabro-server/tests/it/scenario/dry_run.rs
diff --git a/lib/crates/fabro-server/tests/it/scenario/lifecycle.rs b/lib/apps/fabro-server/tests/it/scenario/lifecycle.rs
similarity index 100%
rename from lib/crates/fabro-server/tests/it/scenario/lifecycle.rs
rename to lib/apps/fabro-server/tests/it/scenario/lifecycle.rs
diff --git a/lib/crates/fabro-server/tests/it/scenario/mod.rs b/lib/apps/fabro-server/tests/it/scenario/mod.rs
similarity index 100%
rename from lib/crates/fabro-server/tests/it/scenario/mod.rs
rename to lib/apps/fabro-server/tests/it/scenario/mod.rs
diff --git a/lib/crates/fabro-server/tests/it/scenario/run_completion.rs b/lib/apps/fabro-server/tests/it/scenario/run_completion.rs
similarity index 100%
rename from lib/crates/fabro-server/tests/it/scenario/run_completion.rs
rename to lib/apps/fabro-server/tests/it/scenario/run_completion.rs
diff --git a/lib/crates/fabro-server/tests/it/scenario/sse.rs b/lib/apps/fabro-server/tests/it/scenario/sse.rs
similarity index 100%
rename from lib/crates/fabro-server/tests/it/scenario/sse.rs
rename to lib/apps/fabro-server/tests/it/scenario/sse.rs
diff --git a/lib/crates/fabro-server/tests/it/scenario/usage.rs b/lib/apps/fabro-server/tests/it/scenario/usage.rs
similarity index 100%
rename from lib/crates/fabro-server/tests/it/scenario/usage.rs
rename to lib/apps/fabro-server/tests/it/scenario/usage.rs
diff --git a/lib/crates/fabro-spa/Cargo.toml b/lib/apps/fabro-spa/Cargo.toml
similarity index 100%
rename from lib/crates/fabro-spa/Cargo.toml
rename to lib/apps/fabro-spa/Cargo.toml
diff --git a/lib/crates/fabro-spa/assets/.gitkeep b/lib/apps/fabro-spa/assets/.gitkeep
similarity index 100%
rename from lib/crates/fabro-spa/assets/.gitkeep
rename to lib/apps/fabro-spa/assets/.gitkeep
diff --git a/lib/crates/fabro-spa/src/lib.rs b/lib/apps/fabro-spa/src/lib.rs
similarity index 100%
rename from lib/crates/fabro-spa/src/lib.rs
rename to lib/apps/fabro-spa/src/lib.rs
diff --git a/lib/crates/fabro-acp/Cargo.toml b/lib/components/fabro-acp/Cargo.toml
similarity index 88%
rename from lib/crates/fabro-acp/Cargo.toml
rename to lib/components/fabro-acp/Cargo.toml
index 2fb62b2d9..3e1962dbe 100644
--- a/lib/crates/fabro-acp/Cargo.toml
+++ b/lib/components/fabro-acp/Cargo.toml
@@ -28,8 +28,8 @@ workspace = true
agent-client-protocol.workspace = true
agent-client-protocol-tokio.workspace = true
fabro-sandbox = { path = "../fabro-sandbox", optional = true }
-fabro-types = { path = "../fabro-types", optional = true }
-fabro-util = { path = "../fabro-util" }
+fabro-types = { path = "../../foundation/fabro-types", optional = true }
+fabro-util = { path = "../../foundation/fabro-util" }
serde_json.workspace = true
shlex = "1"
thiserror.workspace = true
diff --git a/lib/crates/fabro-acp/src/command.rs b/lib/components/fabro-acp/src/command.rs
similarity index 100%
rename from lib/crates/fabro-acp/src/command.rs
rename to lib/components/fabro-acp/src/command.rs
diff --git a/lib/crates/fabro-acp/src/error.rs b/lib/components/fabro-acp/src/error.rs
similarity index 100%
rename from lib/crates/fabro-acp/src/error.rs
rename to lib/components/fabro-acp/src/error.rs
diff --git a/lib/crates/fabro-acp/src/lib.rs b/lib/components/fabro-acp/src/lib.rs
similarity index 100%
rename from lib/crates/fabro-acp/src/lib.rs
rename to lib/components/fabro-acp/src/lib.rs
diff --git a/lib/crates/fabro-acp/src/session.rs b/lib/components/fabro-acp/src/session.rs
similarity index 100%
rename from lib/crates/fabro-acp/src/session.rs
rename to lib/components/fabro-acp/src/session.rs
diff --git a/lib/crates/fabro-acp/src/test_support.rs b/lib/components/fabro-acp/src/test_support.rs
similarity index 100%
rename from lib/crates/fabro-acp/src/test_support.rs
rename to lib/components/fabro-acp/src/test_support.rs
diff --git a/lib/crates/fabro-acp/src/transport.rs b/lib/components/fabro-acp/src/transport.rs
similarity index 100%
rename from lib/crates/fabro-acp/src/transport.rs
rename to lib/components/fabro-acp/src/transport.rs
diff --git a/lib/crates/fabro-acp/tests/session.rs b/lib/components/fabro-acp/tests/session.rs
similarity index 100%
rename from lib/crates/fabro-acp/tests/session.rs
rename to lib/components/fabro-acp/tests/session.rs
diff --git a/lib/crates/fabro-agent/Cargo.toml b/lib/components/fabro-agent/Cargo.toml
similarity index 76%
rename from lib/crates/fabro-agent/Cargo.toml
rename to lib/components/fabro-agent/Cargo.toml
index 89f836440..4982a8667 100644
--- a/lib/crates/fabro-agent/Cargo.toml
+++ b/lib/components/fabro-agent/Cargo.toml
@@ -24,16 +24,16 @@ workspace = true
[dependencies]
clap.workspace = true
anyhow.workspace = true
-fabro-auth = { path = "../fabro-auth" }
-fabro-config = { path = "../fabro-config", features = ["clap"] }
-fabro-types = { path = "../fabro-types", features = ["clap"] }
+fabro-auth = { path = "../../foundation/fabro-auth" }
+fabro-config = { path = "../../foundation/fabro-config", features = ["clap"] }
+fabro-types = { path = "../../foundation/fabro-types", features = ["clap"] }
fabro-llm = { path = "../fabro-llm" }
-fabro-model = { path = "../fabro-model" }
+fabro-model = { path = "../../foundation/fabro-model" }
fabro-mcp = { path = "../fabro-mcp" }
fabro-sandbox = { path = "../fabro-sandbox" }
fabro-static.workspace = true
-fabro-util = { path = "../fabro-util" }
-fabro-vault = { path = "../fabro-vault" }
+fabro-util = { path = "../../foundation/fabro-util" }
+fabro-vault = { path = "../../foundation/fabro-vault" }
fabro-http.workspace = true
thiserror.workspace = true
serde.workspace = true
@@ -61,6 +61,6 @@ tokio = { workspace = true, features = ["test-util", "macros"] }
tempfile = "3"
paste = "1"
fabro-sandbox = { path = "../fabro-sandbox", features = ["test-support"] }
-fabro-macros = { path = "../fabro-macros" }
+fabro-macros = { path = "../../foundation/fabro-macros" }
fabro-test = { workspace = true }
tracing-subscriber.workspace = true
diff --git a/lib/crates/fabro-agent/README.md b/lib/components/fabro-agent/README.md
similarity index 98%
rename from lib/crates/fabro-agent/README.md
rename to lib/components/fabro-agent/README.md
index 5cac1be82..69764459e 100644
--- a/lib/crates/fabro-agent/README.md
+++ b/lib/components/fabro-agent/README.md
@@ -98,8 +98,6 @@ pub trait Sandbox: Send + Sync {
```rust
pub struct SessionConfig {
- pub max_turns: usize, // 0 = unlimited
- pub max_tool_rounds_per_input: usize, // default: 200
pub default_command_timeout_ms: u64, // default: 10s
pub max_command_timeout_ms: u64, // default: 600s
pub enable_loop_detection: bool, // default: true
@@ -134,7 +132,6 @@ let env = Arc::new(LocalSandbox::new(
// 4. Configure the session
let config = SessionConfig {
- max_tool_rounds_per_input: 50,
enable_loop_detection: true,
user_instructions: Some("Always write tests first".into()),
..SessionConfig::default()
diff --git a/lib/crates/fabro-agent/src/agent_profile.rs b/lib/components/fabro-agent/src/agent_profile.rs
similarity index 100%
rename from lib/crates/fabro-agent/src/agent_profile.rs
rename to lib/components/fabro-agent/src/agent_profile.rs
diff --git a/lib/crates/fabro-agent/src/apply_patch.lark b/lib/components/fabro-agent/src/apply_patch.lark
similarity index 100%
rename from lib/crates/fabro-agent/src/apply_patch.lark
rename to lib/components/fabro-agent/src/apply_patch.lark
diff --git a/lib/crates/fabro-agent/src/apply_patch.rs b/lib/components/fabro-agent/src/apply_patch.rs
similarity index 100%
rename from lib/crates/fabro-agent/src/apply_patch.rs
rename to lib/components/fabro-agent/src/apply_patch.rs
diff --git a/lib/crates/fabro-agent/src/cli.rs b/lib/components/fabro-agent/src/cli.rs
similarity index 98%
rename from lib/crates/fabro-agent/src/cli.rs
rename to lib/components/fabro-agent/src/cli.rs
index 7f34a3445..ddfdb3245 100644
--- a/lib/crates/fabro-agent/src/cli.rs
+++ b/lib/components/fabro-agent/src/cli.rs
@@ -1071,12 +1071,13 @@ mod tests {
max_output: None,
}),
features: Some(SettingsModelFeatures {
- tools: Some(true),
- vision: Some(false),
- reasoning: Some(false),
- reasoning_effort: None,
- prompt_cache: None,
- sampling_params: None,
+ tools: Some(true),
+ vision: Some(false),
+ reasoning: Some(false),
+ reasoning_effort: None,
+ prompt_cache: None,
+ cache_control_breakpoints: None,
+ sampling_params: None,
}),
..ModelCatalogSettings::default()
});
@@ -1156,12 +1157,13 @@ mod tests {
max_output: None,
}),
features: Some(SettingsModelFeatures {
- tools: Some(true),
- vision: Some(false),
- reasoning: Some(false),
- reasoning_effort: None,
- prompt_cache: None,
- sampling_params: None,
+ tools: Some(true),
+ vision: Some(false),
+ reasoning: Some(false),
+ reasoning_effort: None,
+ prompt_cache: None,
+ cache_control_breakpoints: None,
+ sampling_params: None,
}),
..ModelCatalogSettings::default()
});
diff --git a/lib/crates/fabro-agent/src/compaction.rs b/lib/components/fabro-agent/src/compaction.rs
similarity index 100%
rename from lib/crates/fabro-agent/src/compaction.rs
rename to lib/components/fabro-agent/src/compaction.rs
diff --git a/lib/crates/fabro-agent/src/config.rs b/lib/components/fabro-agent/src/config.rs
similarity index 96%
rename from lib/crates/fabro-agent/src/config.rs
rename to lib/components/fabro-agent/src/config.rs
index c54d49f01..bc22fd75c 100644
--- a/lib/crates/fabro-agent/src/config.rs
+++ b/lib/components/fabro-agent/src/config.rs
@@ -106,8 +106,6 @@ pub struct ToolSecrets {
#[derive(Clone)]
pub struct SessionOptions {
- pub max_turns: usize,
- pub max_tool_rounds_per_input: usize,
pub default_command_timeout_ms: u64,
pub max_command_timeout_ms: u64,
pub reasoning_effort: Option,
@@ -149,8 +147,6 @@ pub struct SessionOptions {
impl std::fmt::Debug for SessionOptions {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("SessionOptions")
- .field("max_turns", &self.max_turns)
- .field("max_tool_rounds_per_input", &self.max_tool_rounds_per_input)
.field(
"default_command_timeout_ms",
&self.default_command_timeout_ms,
@@ -196,8 +192,6 @@ impl std::fmt::Debug for SessionOptions {
impl Default for SessionOptions {
fn default() -> Self {
Self {
- max_turns: 0,
- max_tool_rounds_per_input: 0,
default_command_timeout_ms: 10_000,
max_command_timeout_ms: 600_000,
max_tokens: None,
@@ -280,8 +274,6 @@ mod tests {
#[test]
fn default_config_values() {
let config = SessionOptions::default();
- assert_eq!(config.max_turns, 0);
- assert_eq!(config.max_tool_rounds_per_input, 0);
assert_eq!(config.default_command_timeout_ms, 10_000);
assert_eq!(config.max_command_timeout_ms, 600_000);
assert!(config.reasoning_effort.is_none());
@@ -328,13 +320,10 @@ mod tests {
#[test]
fn config_with_custom_values() {
let config = SessionOptions {
- max_turns: 50,
reasoning_effort: Some(ReasoningEffort::High),
..Default::default()
};
- assert_eq!(config.max_turns, 50);
assert_eq!(config.reasoning_effort, Some(ReasoningEffort::High));
- assert_eq!(config.max_tool_rounds_per_input, 0);
}
#[test]
diff --git a/lib/crates/fabro-agent/src/context_window.rs b/lib/components/fabro-agent/src/context_window.rs
similarity index 100%
rename from lib/crates/fabro-agent/src/context_window.rs
rename to lib/components/fabro-agent/src/context_window.rs
diff --git a/lib/crates/fabro-agent/src/docker_sandbox.rs b/lib/components/fabro-agent/src/docker_sandbox.rs
similarity index 100%
rename from lib/crates/fabro-agent/src/docker_sandbox.rs
rename to lib/components/fabro-agent/src/docker_sandbox.rs
diff --git a/lib/crates/fabro-agent/src/error.rs b/lib/components/fabro-agent/src/error.rs
similarity index 100%
rename from lib/crates/fabro-agent/src/error.rs
rename to lib/components/fabro-agent/src/error.rs
diff --git a/lib/crates/fabro-agent/src/event.rs b/lib/components/fabro-agent/src/event.rs
similarity index 100%
rename from lib/crates/fabro-agent/src/event.rs
rename to lib/components/fabro-agent/src/event.rs
diff --git a/lib/crates/fabro-agent/src/file_tracker.rs b/lib/components/fabro-agent/src/file_tracker.rs
similarity index 100%
rename from lib/crates/fabro-agent/src/file_tracker.rs
rename to lib/components/fabro-agent/src/file_tracker.rs
diff --git a/lib/crates/fabro-agent/src/history.rs b/lib/components/fabro-agent/src/history.rs
similarity index 100%
rename from lib/crates/fabro-agent/src/history.rs
rename to lib/components/fabro-agent/src/history.rs
diff --git a/lib/crates/fabro-agent/src/lib.rs b/lib/components/fabro-agent/src/lib.rs
similarity index 100%
rename from lib/crates/fabro-agent/src/lib.rs
rename to lib/components/fabro-agent/src/lib.rs
diff --git a/lib/crates/fabro-agent/src/local_sandbox.rs b/lib/components/fabro-agent/src/local_sandbox.rs
similarity index 100%
rename from lib/crates/fabro-agent/src/local_sandbox.rs
rename to lib/components/fabro-agent/src/local_sandbox.rs
diff --git a/lib/crates/fabro-agent/src/loop_detection.rs b/lib/components/fabro-agent/src/loop_detection.rs
similarity index 100%
rename from lib/crates/fabro-agent/src/loop_detection.rs
rename to lib/components/fabro-agent/src/loop_detection.rs
diff --git a/lib/crates/fabro-agent/src/mcp_integration.rs b/lib/components/fabro-agent/src/mcp_integration.rs
similarity index 100%
rename from lib/crates/fabro-agent/src/mcp_integration.rs
rename to lib/components/fabro-agent/src/mcp_integration.rs
diff --git a/lib/crates/fabro-agent/src/memory.rs b/lib/components/fabro-agent/src/memory.rs
similarity index 100%
rename from lib/crates/fabro-agent/src/memory.rs
rename to lib/components/fabro-agent/src/memory.rs
diff --git a/lib/crates/fabro-agent/src/profiles/anthropic.rs b/lib/components/fabro-agent/src/profiles/anthropic.rs
similarity index 100%
rename from lib/crates/fabro-agent/src/profiles/anthropic.rs
rename to lib/components/fabro-agent/src/profiles/anthropic.rs
diff --git a/lib/crates/fabro-agent/src/profiles/gemini.rs b/lib/components/fabro-agent/src/profiles/gemini.rs
similarity index 100%
rename from lib/crates/fabro-agent/src/profiles/gemini.rs
rename to lib/components/fabro-agent/src/profiles/gemini.rs
diff --git a/lib/crates/fabro-agent/src/profiles/mod.rs b/lib/components/fabro-agent/src/profiles/mod.rs
similarity index 100%
rename from lib/crates/fabro-agent/src/profiles/mod.rs
rename to lib/components/fabro-agent/src/profiles/mod.rs
diff --git a/lib/crates/fabro-agent/src/profiles/openai.rs b/lib/components/fabro-agent/src/profiles/openai.rs
similarity index 96%
rename from lib/crates/fabro-agent/src/profiles/openai.rs
rename to lib/components/fabro-agent/src/profiles/openai.rs
index ffc02d90c..868d2e2fe 100644
--- a/lib/crates/fabro-agent/src/profiles/openai.rs
+++ b/lib/components/fabro-agent/src/profiles/openai.rs
@@ -229,6 +229,11 @@ and focused on the task.
{file_edit_failure_guidance}
- Do not `git commit` your changes or create new git branches unless explicitly requested.
+# Planning
+
+If you create a checklist or task list, you update item statuses incrementally as each item is \
+completed rather than marking every item done only at the end.
+
# Validating Your Work
If the codebase has tests or the ability to build or run, consider using them to verify your \
@@ -336,6 +341,17 @@ mod tests {
assert!(prompt.contains("existing code conventions"));
}
+ #[test]
+ fn openai_system_prompt_matches_codex_incremental_plan_guidance() {
+ let profile = OpenAiProfile::new("gpt-5.5");
+ let env = MockSandbox::linux();
+ let prompt = profile.build_system_prompt(&env, &EnvContext::default(), &[], None, &[]);
+ assert!(prompt.contains(
+ "update item statuses incrementally as each item is completed rather than \
+ marking every item done only at the end"
+ ));
+ }
+
#[test]
fn openai_system_prompt_includes_memory() {
let profile = OpenAiProfile::new("o3-mini");
diff --git a/lib/crates/fabro-agent/src/question_tools.rs b/lib/components/fabro-agent/src/question_tools.rs
similarity index 100%
rename from lib/crates/fabro-agent/src/question_tools.rs
rename to lib/components/fabro-agent/src/question_tools.rs
diff --git a/lib/crates/fabro-agent/src/read_before_write_sandbox.rs b/lib/components/fabro-agent/src/read_before_write_sandbox.rs
similarity index 100%
rename from lib/crates/fabro-agent/src/read_before_write_sandbox.rs
rename to lib/components/fabro-agent/src/read_before_write_sandbox.rs
diff --git a/lib/crates/fabro-agent/src/sandbox.rs b/lib/components/fabro-agent/src/sandbox.rs
similarity index 100%
rename from lib/crates/fabro-agent/src/sandbox.rs
rename to lib/components/fabro-agent/src/sandbox.rs
diff --git a/lib/crates/fabro-agent/src/session.rs b/lib/components/fabro-agent/src/session.rs
similarity index 98%
rename from lib/crates/fabro-agent/src/session.rs
rename to lib/components/fabro-agent/src/session.rs
index a169d3645..b36c8a639 100644
--- a/lib/crates/fabro-agent/src/session.rs
+++ b/lib/components/fabro-agent/src/session.rs
@@ -1224,10 +1224,6 @@ impl Session {
self.config.speed = speed;
}
- pub const fn set_max_turns(&mut self, max_turns: usize) {
- self.config.max_turns = max_turns;
- }
-
#[must_use]
pub const fn history(&self) -> &History {
&self.history
@@ -1239,7 +1235,14 @@ impl Session {
}
pub async fn process_input(&mut self, input: &str) -> Result<(), Error> {
- self.process_input_with_runtime(input, AgentToolRuntime::default())
+ self.process_input_with_output(input).await.map(drop)
+ }
+
+ pub(crate) async fn process_input_with_output(
+ &mut self,
+ input: &str,
+ ) -> Result