Skip to content

feat(Demo): add multi-agent browser demo workspaces - #226

Merged
themassiveone merged 23 commits into
mainfrom
223-parallel-agent-workspace-portraying-marketing-site-demo
Aug 3, 2026
Merged

feat(Demo): add multi-agent browser demo workspaces#226
themassiveone merged 23 commits into
mainfrom
223-parallel-agent-workspace-portraying-marketing-site-demo

Conversation

@themassiveone

@themassiveone themassiveone commented Aug 1, 2026

Copy link
Copy Markdown
Member

Summary

@coderabbitai

Summary by CodeRabbit

  • New Features

    • Added four ready-to-run demo workspaces covering SaaS, pricing, online shopping, returns, and fulfillment.
    • Added mock websites, dashboards, APIs, workers, payments, fulfillment, and database views with sample data.
    • Added workspace title and branch display overrides.
    • Added a CLI command to clear all workspaces.
    • Added animated browser clicks and improved URL-based application selection.
  • Bug Fixes

    • Improved workspace state updates, removal handling, browser cleanup, and local process launching.
  • Documentation

    • Added demo setup, recording, configuration, and CLI guidance.

@themassiveone themassiveone linked an issue Aug 1, 2026 that may be closed by this pull request
@coderabbitai coderabbitai Bot added release-note Include this pull request in customer-facing release notes release:feature New customer-facing functionality labels Aug 1, 2026
@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Added four Agent-Up demo workspaces, a shared HTTP renderer, direct process launching, workspace display overrides, staged browser clicks, application synchronization, workspace cleanup, and recording workflows.

Changes

Agent-Up features and demo workspaces

Layer / File(s) Summary
Shared demo runtime and workspace applications
Demo/common/demo-server.mjs, Demo/agent*/workspace.mjs, Demo/agent*/agent-up.json, Demo/agent*/*/server.mjs
Added loopback HTTP rendering, route data, application manifests, and server entry points for four demo workspaces.
Direct process launching and working directories
AgentUp.Server/..., AgentUp.Server.Tests/..., docs/user-docs/agent-up-json-reference.md
Updated working-directory handling, deterministic workspace aliases, and direct executable argument coverage.
Workspace display configuration
AgentUp.CLI/..., AgentUp.Server/..., AgentUp.CLI.Tests/..., AgentUp.Server.Tests/..., docs/..., AGENTS.md
Added optional display name and branch overrides with fallback behavior and validation.
Staged browser click execution
AgentUp.Desktop/Features/Browser/..., AgentUp.Desktop/Shared/Interfaces/..., AgentUp.Desktop.Tests/Features/Browser/..., docs/developer-guide/mcp.md
Added target inspection, workspace URL activation, delayed tab switching, animated clicks, cleanup, and browser-flow tests.
Workspace application selection and synchronization
AgentUp.Desktop/Features/Workspaces/..., AgentUp.Desktop.Tests/Features/Workspaces/..., AgentUp.Server/Features/Workspaces/...
Updated application-change notifications, state tracking, URL-based selection, workspace removal events, UI delegation, and browser-resource cleanup.
CLI workspace cleanup
AgentUp.CLI/Features/Workspaces/..., AgentUp.CLI.Tests/...
Added the clear command, workspace deletion, status handling, and runtime server URL help.
Demo recording workflows
Demo/README.md, Demo/agent*/PROMPT.md
Added setup instructions and local-only recording prompts for route inspection, screenshots, audit queries, and activity.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Agent
  participant AgentUp
  participant DemoProcess
  participant Browser
  Agent->>AgentUp: Start configured workspace
  AgentUp->>DemoProcess: Launch Node application
  Agent->>Browser: Inspect local application route
  Browser->>DemoProcess: Request HTML or JSON
  DemoProcess-->>Browser: Return rendered response
Loading

Possibly related PRs

Suggested labels: release-note, release:feature

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 3.23% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: adding multi-agent browser demo workspaces.
Description check ✅ Passed The description includes the required Summary heading and the required @coderabbitai marker.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 223-parallel-agent-workspace-portraying-marketing-site-demo

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Demo/agent4/workspace.mjs`:
- Around line 5-6: Assign agent 4 unique default Storefront, AdminPanel,
Fulfillment, and Postgres ports in Demo/agent4/workspace.mjs, then synchronize
those values in Demo/agent4/agent-up.json. Update Demo/agent1/agent-up.json and
Demo/agent3/agent-up.json with matching dedicated port ranges that do not
overlap any workspace. Document the assigned ranges or explicit
environment-variable overrides for concurrent recording in Demo/README.md.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: c3377113-0e8e-4a73-b8e3-1406cf67b965

📥 Commits

Reviewing files that changed from the base of the PR and between 95a01ca and e4c38b2.

📒 Files selected for processing (30)
  • Demo/README.md
  • Demo/agent1/PROMPT.md
  • Demo/agent1/agent-up.json
  • Demo/agent1/backend/server.mjs
  • Demo/agent1/dashboard/server.mjs
  • Demo/agent1/marketing-site/server.mjs
  • Demo/agent1/postgres/server.mjs
  • Demo/agent1/workspace.mjs
  • Demo/agent2/PROMPT.md
  • Demo/agent2/agent-up.json
  • Demo/agent2/dashboard/server.mjs
  • Demo/agent2/marketing-site/server.mjs
  • Demo/agent2/postgres/server.mjs
  • Demo/agent2/worker/server.mjs
  • Demo/agent2/workspace.mjs
  • Demo/agent3/PROMPT.md
  • Demo/agent3/admin-panel/server.mjs
  • Demo/agent3/agent-up.json
  • Demo/agent3/payments/server.mjs
  • Demo/agent3/postgres/server.mjs
  • Demo/agent3/storefront/server.mjs
  • Demo/agent3/workspace.mjs
  • Demo/agent4/PROMPT.md
  • Demo/agent4/admin-panel/server.mjs
  • Demo/agent4/agent-up.json
  • Demo/agent4/fulfillment/server.mjs
  • Demo/agent4/postgres/server.mjs
  • Demo/agent4/storefront/server.mjs
  • Demo/agent4/workspace.mjs
  • Demo/common/demo-server.mjs

Comment thread Demo/agent4/workspace.mjs Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@AgentUp.Server/Features/Processes/Providers/LocalProcessProvider.cs`:
- Line 97: Harden CreateWorkspaceDirectoryAlias so it fails closed: use a
securely private alias root, revalidate any existing alias target after
IOException races, and never return an unverified aliasPath. If symbolic-link
creation is unavailable on Windows, return workingDirectory or another tested
safe fallback, ensuring the resulting path is verified before use.

In `@docs/user-docs/agent-up-json-reference.md`:
- Line 39: Update the root application-command description in this document to
describe direct executable launching rather than opaque shell commands. State
that the first token must be an allowlisted executable name, and clarify that
custom executable names or paths fail validation at launch time; keep the
wording user-facing and consistent with the `command` field entry.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 5bb793f8-bd2f-42c4-9104-d8b481657927

📥 Commits

Reviewing files that changed from the base of the PR and between e4c38b2 and 63c8ff5.

📒 Files selected for processing (3)
  • AgentUp.Server.Tests/Features/Processes/Provider/WorkspaceProcessManagerTests.cs
  • AgentUp.Server/Features/Processes/Providers/LocalProcessProvider.cs
  • docs/user-docs/agent-up-json-reference.md

Comment thread AgentUp.Server/Features/Processes/Providers/LocalProcessProvider.cs Outdated
Comment thread docs/user-docs/agent-up-json-reference.md Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
AgentUp.Desktop/Features/Workspaces/ViewModels/WorkspaceApplicationViewModel.cs (1)

52-60: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Detect Command changes in UpdateFrom.

UpdateFrom assigns Command unconditionally but does not include it in the returned change flag. If only Command changes (ports and state stay the same), the method returns false. WorkspaceItemViewModel.UpdateFrom uses that return value to decide whether to raise ApplicationsChanged, so a command-only update will not refresh the application panel in MainViewModel. Add Command to the change detection.

🐛 Proposed fix
     public bool UpdateFrom(string command, string state, IReadOnlyList<PortMappingDto>? allocatedPorts)
     {
         var ports = allocatedPorts ?? [];
         var portsChanged = !AllocatedPorts.SequenceEqual(ports);
+        var commandChanged = !string.Equals(Command, command, StringComparison.Ordinal);
 
         Command = command;
         AllocatedPorts = ports;
-        return portsChanged | UpdateState(state);
+        return commandChanged | portsChanged | UpdateState(state);
     }

Consider adding a test case in WorkspaceItemViewModelTests.cs that changes only Command and asserts ApplicationsChanged fires once, since the current tests always pair a command change with a port or state change.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@AgentUp.Desktop/Features/Workspaces/ViewModels/WorkspaceApplicationViewModel.cs`
around lines 52 - 60, Update WorkspaceApplicationViewModel.UpdateFrom to compare
the incoming command with the current Command before assignment and include that
result in the returned change flag, preserving the existing port and state
detection. Add a WorkspaceItemViewModelTests case covering a command-only change
and verify ApplicationsChanged is raised once.
🧹 Nitpick comments (3)
AgentUp.Desktop/Features/Browser/Services/BrowserCommandPoller.cs (1)

17-36: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Delay injection is inconsistent; some call sites still use the static DelayAsync.

This change adds _delay as an injectable delegate for testability. However, lines 58, 74, and 184 still call the static DelayAsync method directly instead of _delay. This leaves those wait times untestable and, in tests, causes a real ~150 ms sleep in any test path that exercises ReadSettledPageStateAsync (line 184).

Route the remaining call sites through _delay for consistency with lines 199, 208, and 217.

♻️ Proposed fix for consistent delay injection
-                await DelayAsync(500, ct);
+                await _delay(500, ct);
-                await DelayAsync(1000, ct);
+                await _delay(1000, ct);
-            await DelayAsync((int)PageStateSettleInterval.TotalMilliseconds, ct);
+            await _delay((int)PageStateSettleInterval.TotalMilliseconds, ct);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@AgentUp.Desktop/Features/Browser/Services/BrowserCommandPoller.cs` around
lines 17 - 36, Update the remaining delay calls in BrowserCommandPoller,
including the paths around ReadSettledPageStateAsync and the call sites near
lines 58 and 74, to invoke the injected _delay delegate instead of the static
DelayAsync method. Preserve each existing delay duration and cancellation token
argument, matching the already-updated call sites near lines 199, 208, and 217.
AgentUp.Desktop/Features/Workspaces/Views/MainWindow.axaml.cs (1)

198-204: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Update the stale comment on SwitchApplicationTabForUrl.

The comment says the method "Only acts when url targets the currently active workspace." vm.SelectApplicationForUrl now switches Sidebar.SelectedWorkspace for any workspaceId, regardless of which workspace is currently active. Update the comment to describe the actual behavior: a background navigation on any workspace can now switch the visible workspace in the desktop UI.

Also note: SelectApplicationForUrl currently switches the workspace selection before it confirms a matching application/port exists for the target URL. See the review comment on MainViewModel.SelectApplicationForUrl for the underlying issue; this call site inherits that risk since it discards the returned boolean.

📝 Proposed comment fix
-    // Switches the application and sub-tab to match the port in url, so the user can watch
-    // the agent's navigation. Only acts when url targets the currently active workspace.
+    // Switches the application and sub-tab to match the port in url, so the user can watch
+    // the agent's navigation. Switches the visible workspace to match workspaceId even when
+    // a different workspace is currently active.
     private void SwitchApplicationTabForUrl(string workspaceId, string url)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@AgentUp.Desktop/Features/Workspaces/Views/MainWindow.axaml.cs` around lines
198 - 204, Update the comment above SwitchApplicationTabForUrl to state that URL
navigation for any workspace may switch the desktop UI’s visible workspace
before selecting the matching application/sub-tab; remove the outdated
restriction that it only acts on the currently active workspace. Do not change
the method behavior here.
AgentUp.Desktop/Features/Workspaces/ViewModels/MainViewModel.cs (1)

252-280: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider documenting the new workspace/application synchronization behavior.

SelectApplicationForUrl introduces a broader runtime behavior: any background navigation on any workspace can now switch the desktop's active workspace and application selection. docs/developer-guide/mcp.md documents the staged browser_click sequence but not this general synchronization contract.

Based on learnings, when behavior, architecture, or runtime contracts change, update the matching AGENTS.md or canonical documentation source in the same change.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@AgentUp.Desktop/Features/Workspaces/ViewModels/MainViewModel.cs` around lines
252 - 280, Document the workspace/application synchronization contract
introduced by SelectApplicationForUrl in the canonical developer documentation,
updating the staged browser_click guidance in mcp.md or its referenced
documentation source. Describe that background navigation can select the
matching workspace, application, and port tab, and keep the documentation
aligned with the runtime behavior.

Source: Learnings

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@AgentUp.CLI/Features/Workspaces/DTOs/AgentUpJson.cs`:
- Around line 8-13: The workspace-start flow must be owned by the Server API
rather than duplicating orchestration in the CLI. In
AgentUp.CLI/Features/Workspaces/DTOs/AgentUpJson.cs:8-13, preserve the Dotnet
and Docker inputs in the Server configuration contract; expose a Server HTTP
start-by-worktree endpoint that performs configuration loading, Git
identity/display fallback resolution, registration, and startup. In
AgentUp.CLI/Features/Workspaces/Services/WorkspaceCommandService.cs:31-58,
replace the local resolution and sequencing with a call to that endpoint. Update
AgentUp.CLI.Tests/E2E/WorkspaceCommandsTests.cs:82-103 to assert the Server
response.

In `@AgentUp.Desktop/Features/Browser/Resources/BrowserScripts.cs`:
- Around line 47-69: Update the delayed click callback in AnimatedClick so
e.click() is wrapped with an explicit catch that resolves the Promise with an
error payload when the click throws. Keep cleanup of the animation element in
finally, but only resolve with {ok:true} after a successful click and prevent
exceptions from producing a false-positive success.
- Around line 47-69: Update AnimatedClick to use an explicit backend-independent
completion signal rather than relying on Promise handling, while retaining the
existing success/error payloads. Track every requestAnimationFrame and timer
handle, and cancel them during completion or timeout so e.click() cannot run
late. Add a host-side timeout in BrowserCommandPoller.EvalCommandAsync that
terminates the pending command and reports timeout failure.

In `@AgentUp.Desktop/Features/Workspaces/ViewModels/MainViewModel.cs`:
- Around line 252-280: Update SelectApplicationForUrl to find the matching
application through the target workspace’s own Applications collection and
validate the target port before assigning Sidebar.SelectedWorkspace; return
false without visible state changes when no match exists. Preserve the existing
selection and tab behavior for valid matches, and add a MainViewModelTests
regression test asserting a non-matching target-workspace port returns false and
leaves Sidebar.SelectedWorkspace unchanged.

---

Outside diff comments:
In
`@AgentUp.Desktop/Features/Workspaces/ViewModels/WorkspaceApplicationViewModel.cs`:
- Around line 52-60: Update WorkspaceApplicationViewModel.UpdateFrom to compare
the incoming command with the current Command before assignment and include that
result in the returned change flag, preserving the existing port and state
detection. Add a WorkspaceItemViewModelTests case covering a command-only change
and verify ApplicationsChanged is raised once.

---

Nitpick comments:
In `@AgentUp.Desktop/Features/Browser/Services/BrowserCommandPoller.cs`:
- Around line 17-36: Update the remaining delay calls in BrowserCommandPoller,
including the paths around ReadSettledPageStateAsync and the call sites near
lines 58 and 74, to invoke the injected _delay delegate instead of the static
DelayAsync method. Preserve each existing delay duration and cancellation token
argument, matching the already-updated call sites near lines 199, 208, and 217.

In `@AgentUp.Desktop/Features/Workspaces/ViewModels/MainViewModel.cs`:
- Around line 252-280: Document the workspace/application synchronization
contract introduced by SelectApplicationForUrl in the canonical developer
documentation, updating the staged browser_click guidance in mcp.md or its
referenced documentation source. Describe that background navigation can select
the matching workspace, application, and port tab, and keep the documentation
aligned with the runtime behavior.

In `@AgentUp.Desktop/Features/Workspaces/Views/MainWindow.axaml.cs`:
- Around line 198-204: Update the comment above SwitchApplicationTabForUrl to
state that URL navigation for any workspace may switch the desktop UI’s visible
workspace before selecting the matching application/sub-tab; remove the outdated
restriction that it only acts on the currently active workspace. Do not change
the method behavior here.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: deb2a50e-7568-4bcf-8f52-29724311d53e

📥 Commits

Reviewing files that changed from the base of the PR and between 63c8ff5 and fcffc58.

📒 Files selected for processing (24)
  • AGENTS.md
  • AgentUp.CLI.Tests/E2E/WorkspaceCommandsTests.cs
  • AgentUp.CLI/Features/Workspaces/DTOs/AgentUpJson.cs
  • AgentUp.CLI/Features/Workspaces/Services/WorkspaceCommandService.cs
  • AgentUp.Desktop.Tests/Features/Browser/Controller/BrowserAutomationControllerTests.cs
  • AgentUp.Desktop.Tests/Features/Browser/Unit/BrowserCommandPollerTests.cs
  • AgentUp.Desktop.Tests/Features/Workspaces/Unit/MainViewModelTests.cs
  • AgentUp.Desktop.Tests/Features/Workspaces/Unit/WorkspaceItemViewModelTests.cs
  • AgentUp.Desktop/Features/Browser/Models/ClickTargetDto.cs
  • AgentUp.Desktop/Features/Browser/Resources/BrowserScripts.cs
  • AgentUp.Desktop/Features/Browser/Services/BrowserCommandPoller.cs
  • AgentUp.Desktop/Features/Workspaces/ViewModels/MainViewModel.cs
  • AgentUp.Desktop/Features/Workspaces/ViewModels/WorkspaceApplicationViewModel.cs
  • AgentUp.Desktop/Features/Workspaces/ViewModels/WorkspaceItemViewModel.cs
  • AgentUp.Desktop/Features/Workspaces/Views/MainWindow.axaml.cs
  • AgentUp.Desktop/Shared/Interfaces/IBrowserWindowHost.cs
  • AgentUp.Server.Tests/Features/Orchestration/Controller/OrchestrationMcpResourcesTests.cs
  • AgentUp.Server.Tests/Features/Orchestration/Controller/OrchestrationMcpToolsTests.cs
  • AgentUp.Server/Features/Orchestration/DTOs/AgentUpConfiguration.cs
  • AgentUp.Server/Features/Orchestration/Providers/AgentUpContextProvider.cs
  • AgentUp.Server/Features/Orchestration/Services/OrchestrationWorkspaceService.cs
  • docs/developer-guide/mcp.md
  • docs/user-docs/agent-up-json-reference.md
  • docs/user-docs/agent-up-json.md

Comment on lines +8 to +13
List<DockerCapabilityDefinition>? Docker = null,
WorkspaceDisplayOptions? Display = null);

public sealed record WorkspaceDisplayOptions(
string? Name = null,
string? Branch = null);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

ast-grep outline AgentUp.Server/Features/Orchestration/Services/OrchestrationWorkspaceService.cs --items all
ast-grep outline AgentUp.CLI/Features/Workspaces/Services/WorkspaceCommandService.cs --items all

rg -n -C 5 --type cs \
  'StartAsync\(string worktreePath|RegisterAsync\(|StartWorkspaceAsync\(|HttpPost|MapPost' \
  AgentUp.Server AgentUp.CLI

Repository: agent-up-oss/agent-up

Length of output: 23118


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- server orchestration service ---'
sed -n '1,125p' AgentUp.Server/Features/Orchestration/Services/OrchestrationWorkspaceService.cs

printf '%s\n' '--- server orchestration controller ---'
cat -n AgentUp.Server/Features/Orchestration/Controllers/OrchestrationWorkspaceController.cs

printf '%s\n' '--- server workspace HTTP controller ---'
cat -n AgentUp.Server/Features/Workspaces/Controllers/WorkspacesController.cs

printf '%s\n' '--- CLI command service ---'
cat -n AgentUp.CLI/Features/Workspaces/Services/WorkspaceCommandService.cs

printf '%s\n' '--- CLI JSON DTO ---'
cat -n AgentUp.CLI/Features/Workspaces/DTOs/AgentUpJson.cs

printf '%s\n' '--- CLI API client ---'
cat -n AgentUp.CLI/Features/Workspaces/Providers/WorkspaceApiClient.cs

printf '%s\n' '--- relevant route/interface/config references ---'
rg -n -C 3 --type cs \
  'OrchestrationWorkspaceController|StartAsync\(string worktreePath|RegisterWorkspaceRequest|AgentUpConfiguration|WorkspaceCommandService|MapControllers|MapPost' \
  AgentUp.Server AgentUp.CLI AgentUp.CLI.Tests

Repository: agent-up-oss/agent-up

Length of output: 45240


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- server configuration and registration DTOs ---'
cat -n AgentUp.Server/Features/Orchestration/DTOs/AgentUpConfiguration.cs
cat -n AgentUp.Server/Features/Workspaces/DTOs/RegisterWorkspaceRequest.cs
cat -n AgentUp.CLI/Features/Workspaces/DTOs/RegisterWorkspaceRequest.cs

printf '%s\n' '--- server start continuation ---'
sed -n '120,240p' AgentUp.Server/Features/Orchestration/Services/OrchestrationWorkspaceService.cs

printf '%s\n' '--- CLI configuration provider and identity provider ---'
cat -n AgentUp.CLI/Features/Workspaces/Providers/WorkspaceConfigurationProvider.cs
cat -n AgentUp.CLI/Features/Workspaces/Providers/WorkspaceIdentityProvider.cs

printf '%s\n' '--- server workspace definitions and lifecycle inputs ---'
rg -n -C 4 --type cs \
  'class Workspace|record Workspace|Dotnet|Docker|Applications|Services' \
  AgentUp.Server/Features/Workspaces AgentUp.Server/Features/Orchestration

printf '%s\n' '--- start-related tests and CLI composition ---'
rg -n -C 8 --type cs \
  'Start_UsesDisplayOverrides|StartAsync\(|/api/workspaces|DisplayName|Dotnet|Docker' \
  AgentUp.CLI.Tests/E2E/WorkspaceCommandsTests.cs AgentUp.CLI/Composition/CliRunnerFactory.cs

Repository: agent-up-oss/agent-up

Length of output: 50377


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path

server = Path("AgentUp.Server/Features/Orchestration/Services/OrchestrationWorkspaceService.cs").read_text()
cli = Path("AgentUp.CLI/Features/Workspaces/Services/WorkspaceCommandService.cs").read_text()
http = Path("AgentUp.Server/Features/Workspaces/Controllers/WorkspacesController.cs").read_text()
config = Path("AgentUp.Server/Features/Orchestration/DTOs/AgentUpConfiguration.cs").read_text()

checks = {
    "server_start_loads_config": "_configuration.LoadAsync(worktreePath" in server,
    "server_start_reads_identity": "_identity.ReadAsync(worktreePath" in server,
    "server_start_resolves_display": "config.Display?.Name" in server and "config.Display?.Branch" in server,
    "server_start_registers_and_starts": "_workspaces.RegisterAsync" in server and "StartRegisteredAsync" in server,
    "cli_loads_config": "_configuration.LoadAsync(_workingDirectory)" in cli,
    "cli_reads_identity": "_identity.ReadAsync(_workingDirectory)" in cli,
    "cli_resolves_display": "config.Display?.Name" in cli and "config.Display?.Branch" in cli,
    "cli_registers_then_starts": "_client.RegisterAsync" in cli and "_client.StartWorkspaceAsync" in cli,
    "rest_has_register_route": '[HttpPost]' in http,
    "rest_has_id_start_only": '[HttpPost("{id}/start")]' in http,
    "rest_has_no_worktree_start_route": 'worktreePath' not in http,
    "server_config_has_no_dotnet_or_docker": "Dotnet" not in config and "Docker" not in config,
}

for name, value in checks.items():
    print(f"{name}={value}")

assert all(checks.values())
PY

Repository: agent-up-oss/agent-up

Length of output: 628


Move workspace-start orchestration behind a Server API boundary.

WorkspaceCommandService.StartAsync duplicates configuration loading, Git identity lookup, display fallback resolution, registration, and start sequencing from OrchestrationWorkspaceService.StartAsync. Expose the Server orchestration through an HTTP start-by-worktree endpoint, extend Server configuration to preserve the CLI’s Dotnet and Docker inputs, then remove the CLI-side resolution and update the E2E test to assert the Server response.

📍 Affects 3 files
  • AgentUp.CLI/Features/Workspaces/DTOs/AgentUpJson.cs#L8-L13 (this comment)
  • AgentUp.CLI/Features/Workspaces/Services/WorkspaceCommandService.cs#L31-L58
  • AgentUp.CLI.Tests/E2E/WorkspaceCommandsTests.cs#L82-L103
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@AgentUp.CLI/Features/Workspaces/DTOs/AgentUpJson.cs` around lines 8 - 13, The
workspace-start flow must be owned by the Server API rather than duplicating
orchestration in the CLI. In
AgentUp.CLI/Features/Workspaces/DTOs/AgentUpJson.cs:8-13, preserve the Dotnet
and Docker inputs in the Server configuration contract; expose a Server HTTP
start-by-worktree endpoint that performs configuration loading, Git
identity/display fallback resolution, registration, and startup. In
AgentUp.CLI/Features/Workspaces/Services/WorkspaceCommandService.cs:31-58,
replace the local resolution and sequencing with a call to that endpoint. Update
AgentUp.CLI.Tests/E2E/WorkspaceCommandsTests.cs:82-103 to assert the Server
response.

Source: Coding guidelines

Comment thread AgentUp.Desktop/Features/Browser/Resources/BrowserScripts.cs Outdated
Comment on lines +252 to +280
internal bool SelectApplicationForUrl(string workspaceId, string url)
{
if (!Uri.TryCreate(url, UriKind.Absolute, out var uri))
return false;

var workspace = Sidebar.Workspaces.FirstOrDefault(w => w.Id == workspaceId);
if (workspace is null)
return false;

if (Sidebar.SelectedWorkspace?.Id != workspaceId)
Sidebar.SelectedWorkspace = workspace;

var targetPort = uri.Port;
var matchingApp = Applications.Applications
.FirstOrDefault(a => a.AllocatedPorts.Any(p => p.AllocatedPort == targetPort));
if (matchingApp is null)
return false;

PreloadPortUrl(url);

if (Applications.SelectedApplication != matchingApp)
Applications.SelectedApplication = matchingApp;

var targetTab = SubTabs.OfType<PortSubTabViewModel>().FirstOrDefault(t => t.AllocatedPort == targetPort);
if (targetTab is not null && SelectedSubTab != targetTab)
SelectedSubTab = targetTab;

return true;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Validate the target application before switching Sidebar.SelectedWorkspace.

SelectApplicationForUrl switches Sidebar.SelectedWorkspace to workspace before confirming that any application in that workspace owns targetPort. If no application matches, the method returns false, but the workspace switch already happened. Both callers in MainWindow.axaml.cs discard this return value (SwitchApplicationTabForUrl at lines 202-203) or propagate it through a caller that also discards it (BrowserCommandPoller.ClickAsync). A link with a non-matching port silently leaves the desktop UI on the wrong workspace with no indication of failure.

Search the target workspace's own application list (workspace.Applications, which is independent of the current selection) before switching, so the method makes no visible change on failure.

🐛 Proposed fix
     internal bool SelectApplicationForUrl(string workspaceId, string url)
     {
         if (!Uri.TryCreate(url, UriKind.Absolute, out var uri))
             return false;
 
         var workspace = Sidebar.Workspaces.FirstOrDefault(w => w.Id == workspaceId);
         if (workspace is null)
             return false;
 
-        if (Sidebar.SelectedWorkspace?.Id != workspaceId)
-            Sidebar.SelectedWorkspace = workspace;
-
         var targetPort = uri.Port;
-        var matchingApp = Applications.Applications
+        var targetWorkspaceApp = workspace.Applications
             .FirstOrDefault(a => a.AllocatedPorts.Any(p => p.AllocatedPort == targetPort));
-        if (matchingApp is null)
+        if (targetWorkspaceApp is null)
             return false;
 
+        if (Sidebar.SelectedWorkspace?.Id != workspaceId)
+            Sidebar.SelectedWorkspace = workspace;
+
         PreloadPortUrl(url);
 
+        var matchingApp = Applications.Applications.FirstOrDefault(a => a.Name == targetWorkspaceApp.Name);
+        if (matchingApp is null)
+            return false;
+
         if (Applications.SelectedApplication != matchingApp)
             Applications.SelectedApplication = matchingApp;

Add a regression test in MainViewModelTests.cs covering a URL whose port does not match any application in the target workspace, asserting SelectApplicationForUrl returns false and Sidebar.SelectedWorkspace is unchanged.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
internal bool SelectApplicationForUrl(string workspaceId, string url)
{
if (!Uri.TryCreate(url, UriKind.Absolute, out var uri))
return false;
var workspace = Sidebar.Workspaces.FirstOrDefault(w => w.Id == workspaceId);
if (workspace is null)
return false;
if (Sidebar.SelectedWorkspace?.Id != workspaceId)
Sidebar.SelectedWorkspace = workspace;
var targetPort = uri.Port;
var matchingApp = Applications.Applications
.FirstOrDefault(a => a.AllocatedPorts.Any(p => p.AllocatedPort == targetPort));
if (matchingApp is null)
return false;
PreloadPortUrl(url);
if (Applications.SelectedApplication != matchingApp)
Applications.SelectedApplication = matchingApp;
var targetTab = SubTabs.OfType<PortSubTabViewModel>().FirstOrDefault(t => t.AllocatedPort == targetPort);
if (targetTab is not null && SelectedSubTab != targetTab)
SelectedSubTab = targetTab;
return true;
}
internal bool SelectApplicationForUrl(string workspaceId, string url)
{
if (!Uri.TryCreate(url, UriKind.Absolute, out var uri))
return false;
var workspace = Sidebar.Workspaces.FirstOrDefault(w => w.Id == workspaceId);
if (workspace is null)
return false;
var targetPort = uri.Port;
var targetWorkspaceApp = workspace.Applications
.FirstOrDefault(a => a.AllocatedPorts.Any(p => p.AllocatedPort == targetPort));
if (targetWorkspaceApp is null)
return false;
if (Sidebar.SelectedWorkspace?.Id != workspaceId)
Sidebar.SelectedWorkspace = workspace;
PreloadPortUrl(url);
var matchingApp = Applications.Applications.FirstOrDefault(a => a.Name == targetWorkspaceApp.Name);
if (matchingApp is null)
return false;
if (Applications.SelectedApplication != matchingApp)
Applications.SelectedApplication = matchingApp;
var targetTab = SubTabs.OfType<PortSubTabViewModel>().FirstOrDefault(t => t.AllocatedPort == targetPort);
if (targetTab is not null && SelectedSubTab != targetTab)
SelectedSubTab = targetTab;
return true;
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@AgentUp.Desktop/Features/Workspaces/ViewModels/MainViewModel.cs` around lines
252 - 280, Update SelectApplicationForUrl to find the matching application
through the target workspace’s own Applications collection and validate the
target port before assigning Sidebar.SelectedWorkspace; return false without
visible state changes when no match exists. Preserve the existing selection and
tab behavior for valid matches, and add a MainViewModelTests regression test
asserting a non-matching target-workspace port returns false and leaves
Sidebar.SelectedWorkspace unchanged.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@AgentUp.Desktop/Features/Browser/Resources/BrowserScripts.cs`:
- Around line 77-86: Update CompleteClick to retrieve and remove
__agentUpClickRing, then return an error when the target is missing or
e.matches(':disabled') is true, before setting window.__agentUpMouse. Preserve
successful clicks and return ok:true only when e.click() is actionable, and add
regression tests covering both early-failure paths.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: f461cf32-70fa-4d5c-977a-f3f4d1cebaec

📥 Commits

Reviewing files that changed from the base of the PR and between fcffc58 and 2a6fd74.

📒 Files selected for processing (7)
  • AgentUp.Desktop.Tests/Features/Browser/Unit/BrowserCommandPollerTests.cs
  • AgentUp.Desktop/Features/Browser/Resources/BrowserScripts.cs
  • AgentUp.Desktop/Features/Browser/Services/BrowserCommandPoller.cs
  • Demo/agent1/PROMPT.md
  • Demo/agent2/PROMPT.md
  • Demo/agent3/PROMPT.md
  • Demo/agent4/PROMPT.md
🚧 Files skipped from review as they are similar to previous changes (6)
  • Demo/agent2/PROMPT.md
  • Demo/agent3/PROMPT.md
  • Demo/agent1/PROMPT.md
  • Demo/agent4/PROMPT.md
  • AgentUp.Desktop/Features/Browser/Services/BrowserCommandPoller.cs
  • AgentUp.Desktop.Tests/Features/Browser/Unit/BrowserCommandPollerTests.cs

Comment thread AgentUp.Desktop/Features/Browser/Resources/BrowserScripts.cs Outdated
Comment thread AgentUp.Server/Features/Processes/Providers/LocalProcessProvider.cs Fixed

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
AgentUp.CLI.Tests/E2E/WorkspaceCommandsTests.cs (1)

82-103: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add a whitespace override fallback test.

StartAsync treats whitespace display.name and display.branch values as absent. This test only covers non-empty overrides. Add a focused test with whitespace values and verify that the configured name and Git branch remain in the registration payload.

As per coding guidelines, “Every validation rule affecting public behavior requires a focused test at the boundary where that behavior is observed.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@AgentUp.CLI.Tests/E2E/WorkspaceCommandsTests.cs` around lines 82 - 103, Add a
focused test alongside Start_UsesDisplayOverrides_ForDesktopVisuals that writes
whitespace-only display.name and display.branch values, runs the start command,
and verifies the registered workspace retains the configured project name and
Git branch while preserving the existing worktree assertion.

Source: Coding guidelines

🧹 Nitpick comments (1)
AgentUp.Desktop/Features/Workspaces/Views/MainWindow.axaml.cs (1)

304-318: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Add a partial-removal regression test.

WorkspaceListViewModel currently uses only Add and Remove; no production path calls Move or Sort, so a Move guard is not needed. Test removing one workspace from several and assert that the remaining workspace retains its WebView resources and cached state.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@AgentUp.Desktop/Features/Workspaces/Views/MainWindow.axaml.cs` around lines
304 - 318, Add a regression test for partial removal in the workspace collection
change handling around OnWorkspaceCollectionChanged: create several workspaces,
remove only one, and assert the remaining workspace retains its WebView
resources and cached state. Keep the test focused on Remove actions; no Move or
Sort handling is needed.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@AgentUp.CLI/Features/Workspaces/Providers/WorkspaceApiClient.cs`:
- Around line 54-59: Update DeleteWorkspaceAsync to declare the
HttpResponseMessage returned by _http.DeleteAsync with using, ensuring the
response is disposed after success or failure while preserving the existing
status check and problem-detail exception behavior.

In
`@AgentUp.Server.Tests/Features/Processes/Provider/WorkspaceProcessManagerTests.cs`:
- Around line 229-245: The test
CreateWorkspaceDirectoryAlias_RejectsExistingUnverifiedAlias currently covers
only an existing regular directory; update it to create a second directory, make
the deterministic alias path a symbolic link targeting that directory, and
assert that LocalProcessProvider.CreateWorkspaceDirectoryAlias rejects the
mismatched target with the existing verification failure.

---

Outside diff comments:
In `@AgentUp.CLI.Tests/E2E/WorkspaceCommandsTests.cs`:
- Around line 82-103: Add a focused test alongside
Start_UsesDisplayOverrides_ForDesktopVisuals that writes whitespace-only
display.name and display.branch values, runs the start command, and verifies the
registered workspace retains the configured project name and Git branch while
preserving the existing worktree assertion.

---

Nitpick comments:
In `@AgentUp.Desktop/Features/Workspaces/Views/MainWindow.axaml.cs`:
- Around line 304-318: Add a regression test for partial removal in the
workspace collection change handling around OnWorkspaceCollectionChanged: create
several workspaces, remove only one, and assert the remaining workspace retains
its WebView resources and cached state. Keep the test focused on Remove actions;
no Move or Sort handling is needed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: ba6969fb-b353-4c7b-81f0-2812fa461906

📥 Commits

Reviewing files that changed from the base of the PR and between 2a6fd74 and a72de3e.

📒 Files selected for processing (36)
  • AgentUp.CLI.Tests/E2E/WorkspaceCommandsTests.cs
  • AgentUp.CLI/Composition/CliRunnerFactory.cs
  • AgentUp.CLI/Features/Workspaces/Controllers/ClearCommand.cs
  • AgentUp.CLI/Features/Workspaces/Controllers/CliRunner.cs
  • AgentUp.CLI/Features/Workspaces/Providers/WorkspaceApiClient.cs
  • AgentUp.CLI/Features/Workspaces/Services/WorkspaceCommandService.cs
  • AgentUp.CLI/Properties/launchSettings.json
  • AgentUp.Desktop.Tests/Features/Browser/Unit/BrowserScriptsTests.cs
  • AgentUp.Desktop.Tests/Features/Workspaces/Headless/SidebarBehaviorTests.cs
  • AgentUp.Desktop.Tests/Features/Workspaces/Provider/WorkspaceEventClientTests.cs
  • AgentUp.Desktop.Tests/Features/Workspaces/Unit/MainViewModelTests.cs
  • AgentUp.Desktop.Tests/Support/AppDriver.cs
  • AgentUp.Desktop.Tests/Support/SidebarDriver.cs
  • AgentUp.Desktop/Features/Browser/Resources/BrowserScripts.cs
  • AgentUp.Desktop/Features/Workspaces/ViewModels/MainViewModel.cs
  • AgentUp.Desktop/Features/Workspaces/ViewModels/WorkspaceApplicationViewModel.cs
  • AgentUp.Desktop/Features/Workspaces/Views/MainWindow.axaml
  • AgentUp.Desktop/Features/Workspaces/Views/MainWindow.axaml.cs
  • AgentUp.Server.Tests/Fake/ServerTestComposition.cs
  • AgentUp.Server.Tests/Features/Processes/Provider/WorkspaceProcessManagerTests.cs
  • AgentUp.Server.Tests/Features/Workspaces/Unit/WorkspaceRegistryTests.cs
  • AgentUp.Server/Features/Processes/Providers/LocalProcessProvider.cs
  • AgentUp.Server/Features/Workspaces/Services/WorkspaceRegistry.cs
  • Demo/README.md
  • Demo/agent1/agent-up.json
  • Demo/agent1/workspace.mjs
  • Demo/agent2/agent-up.json
  • Demo/agent2/workspace.mjs
  • Demo/agent3/agent-up.json
  • Demo/agent3/workspace.mjs
  • Demo/agent4/agent-up.json
  • Demo/agent4/workspace.mjs
  • docs/user-docs/agent-up-json-reference.md
  • docs/user-docs/agent-up-json.md
  • docs/user-docs/cli.md
  • docs/user-docs/index.md
🚧 Files skipped from review as they are similar to previous changes (14)
  • Demo/agent1/agent-up.json
  • AgentUp.Desktop/Features/Workspaces/ViewModels/WorkspaceApplicationViewModel.cs
  • Demo/agent4/agent-up.json
  • Demo/agent4/workspace.mjs
  • Demo/agent3/agent-up.json
  • Demo/agent1/workspace.mjs
  • Demo/agent2/workspace.mjs
  • Demo/README.md
  • docs/user-docs/agent-up-json.md
  • docs/user-docs/agent-up-json-reference.md
  • Demo/agent3/workspace.mjs
  • Demo/agent2/agent-up.json
  • AgentUp.Desktop/Features/Browser/Resources/BrowserScripts.cs
  • AgentUp.Desktop/Features/Workspaces/ViewModels/MainViewModel.cs

Comment thread AgentUp.CLI/Features/Workspaces/Providers/WorkspaceApiClient.cs
@themassiveone
themassiveone merged commit af6d974 into main Aug 3, 2026
21 checks passed
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown

🎉 This PR is included in version 3.22.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 1.0.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release:feature New customer-facing functionality release-note Include this pull request in customer-facing release notes released

Projects

None yet

Development

Successfully merging this pull request may close these issues.

parallel agent workspace portraying marketing site demo

2 participants