Skip to content

fix(workflows): support editing global workflows#1557

Open
guanghuang wants to merge 1 commit intocoleam00:devfrom
guanghuang:fix/global-workflow-builder-edit
Open

fix(workflows): support editing global workflows#1557
guanghuang wants to merge 1 commit intocoleam00:devfrom
guanghuang:fix/global-workflow-builder-edit

Conversation

@guanghuang
Copy link
Copy Markdown

@guanghuang guanghuang commented May 3, 2026

Summary

  • Problem: Global workflows from ~/.archon/workflows are listed in the Web UI but cannot reliably be opened in the workflow builder because the detail endpoint does not resolve global workflow files.
  • Why it matters: Users who keep reusable workflows globally can see them in the list but cannot view or edit the DAG from the Web UI.
  • What changed: The workflow detail endpoint now resolves global workflows, save/delete can target global workflow scope with source=global, the builder preserves loaded workflow source on save, and global commands appear in the builder command library.
  • What did not change (scope boundary): Project workflow editing remains unchanged. Bundled/default workflows are still not edited in place.

UX Journey

Before

User                         Web UI                       Server
────                         ──────                       ──────
opens workflow list ──────▶  GET /api/workflows ───────▶ discover project/global/bundled
sees global workflow ◀─────  source: global returned ◀── global workflow included
clicks edit ──────────────▶  GET /api/workflows/:name ─▶ checks project + bundled only
sees load error ◀──────────  Workflow not found ◀─────── global workflow not resolved

After

User                         Web UI                          Server
────                         ──────                          ──────
opens workflow list ──────▶  GET /api/workflows ──────────▶ discover project/global/bundled
sees global workflow ◀─────  source: global returned ◀───── global workflow included
clicks edit ──────────────▶  GET /api/workflows/:name ────▶ [checks ~/.archon/workflows]
views DAG ◀────────────────  workflow + source: global ◀── global workflow parsed
saves edits ──────────────▶  PUT ?source=global ─────────▶ [writes ~/.archon/workflows]

Architecture Diagram

Before

packages/workflows/src/workflow-discovery.ts
  └─ GET /api/workflows
      └─ includes project + global + bundled workflows

packages/server/src/routes/api.ts
  └─ GET /api/workflows/:name
      ├─ project lookup
      └─ bundled/default lookup
          --x-- no global lookup

packages/web/src/components/workflows/WorkflowBuilder.tsx
  └─ load by name only, save without preserving source

packages/web/src/lib/command-categories.ts
  └─ project + bundled command groups only
      --x-- global commands dropped from grouped library view

After

packages/workflows/src/workflow-discovery.ts
  └─ GET /api/workflows
      └─ includes project + global + bundled workflows

[~] packages/server/src/routes/api.ts
  ├─ GET /api/workflows/:name
  │   ├─ project lookup
  │   ├─ [global lookup: ~/.archon/workflows/<name>.yaml]
  │   └─ bundled/default lookup
  ├─ PUT /api/workflows/:name?source=global
  │   └─ [writes ~/.archon/workflows/<name>.yaml]
  └─ DELETE /api/workflows/:name?source=global
      └─ [deletes ~/.archon/workflows/<name>.yaml]

[~] packages/web/src/components/workflows/WorkflowBuilder.tsx
  └─ preserves loaded workflow source and passes it on save

[~] packages/web/src/lib/command-categories.ts
  └─ includes Global command group

Connection inventory:

From To Status Notes
GET /api/workflows workflow discovery unchanged List already included global workflows.
GET /api/workflows/:name ~/.archon/workflows new Detail/edit loading now resolves global workflows.
Web workflow builder workflow detail response modified Builder now stores returned workflow source.
Web workflow builder PUT /api/workflows/:name modified Save includes source=global when editing a global workflow.
Command library grouping global command list entries modified Global commands are now shown in the grouped builder library.

Label Snapshot

  • Risk: risk: low
  • Size: size: S
  • Scope: server|web|tests
  • Module: workflows:builder

Change Metadata

  • Change type: bug
  • Primary scope: multi

Linked Issue

Validation Evidence (required)

Commands and result summary:

bun test packages/server/src/routes/api.workflows.test.ts
# Result: 29 pass, 0 fail

bun run type-check
# Result: @archon/paths, @archon/git, @archon/providers, @archon/isolation,
# @archon/web, @archon/workflows, @archon/core, @archon/adapters,
# @archon/server, and @archon/cli type-check exited with code 0
  • Evidence provided (test/log/trace/screenshot): Server route tests for global workflow load/save plus full monorepo type-check output.
  • If any command is intentionally skipped, explain why: Full test suite was not run because this is a scoped API/Web UI workflow-builder fix; targeted route coverage and full type-check were run.

Security Impact (required)

  • New permissions/capabilities? (No)
  • New external network calls? (No)
  • Secrets/tokens handling changed? (No)
  • File system access scope changed? (Yes)
  • If any Yes, describe risk and mitigation: The existing workflow edit API can now explicitly target Archon's home-scoped workflow directory when source=global is supplied. The workflow name still passes existing command-name validation, and writes are constrained to getHomeWorkflowsPath() with a fixed .yaml filename.

Compatibility / Migration

  • Backward compatible? (Yes)
  • Config/env changes? (No)
  • Database migration needed? (No)
  • If yes, exact upgrade steps: Not applicable.

Human Verification (required)

What was personally validated beyond CI:

  • Verified scenarios: Clean branch created from origin/dev; only this feature fix is included; route tests cover loading from ARCHON_HOME/workflows and saving with source=global.
  • Edge cases checked: Invalid workflow names remain rejected; invalid source query values are rejected; project save path remains the default when no global source is supplied.
  • What was not verified: Manual browser screenshot of the workflow builder loading a real global workflow was not captured.

Side Effects / Blast Radius (required)

  • Affected subsystems/workflows: Web UI workflow builder, workflow REST API, command library grouping.
  • Potential unintended effects: A caller that sends source=global can update a same-named global workflow instead of creating a project workflow.
  • Guardrails/monitoring for early detection: Existing workflow route tests plus new global workflow load/save tests; OpenAPI query validation for allowed source values.

Rollback Plan (required)

  • Fast rollback command/path: Revert this PR commit.
  • Feature flags or config toggles (if any): None.
  • Observable failure symptoms: Global workflows again appear in the list but fail to open in the builder, or saving a global workflow writes to the wrong scope.

Risks and Mitigations

  • Risk: Source-aware save behavior could be confusing if users expect global workflows to become project-local copies.
    • Mitigation: The builder preserves the source returned by the API, matching the loaded workflow's listed scope.
  • Risk: Global workflow writes broaden the existing edit API's file target scope.
    • Mitigation: The write path is constrained to Archon's configured home workflows directory and validated workflow names.

Summary by CodeRabbit

  • New Features

    • Workflows can be saved/deleted as project-scoped or global/home-scoped via a new source option; fetching now resolves project → global → bundled defaults.
    • Web UI preserves and submits workflow source; API client surface restored with workflow and related endpoints.
    • Command lists are grouped into Project, Global, then bundled categories with predictable ordering.
  • Tests

    • Added tests covering global/home workflow behavior and persistence.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 3, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 73b433e1-2f47-4885-9fae-af567dd82988

📥 Commits

Reviewing files that changed from the base of the PR and between 3fa7435 and e6da4e6.

📒 Files selected for processing (5)
  • packages/server/src/routes/api.ts
  • packages/server/src/routes/api.workflows.test.ts
  • packages/web/src/components/workflows/WorkflowBuilder.tsx
  • packages/web/src/lib/api.ts
  • packages/web/src/lib/command-categories.ts

📝 Walkthrough

Walkthrough

Server and web changes add explicit workflow scoping: a source query parameter (project | global) is introduced for save/delete, GET now resolves project → global (home) → bundled workflows, the web client preserves and sends workflow source, and tests cover global workflow load/save behavior.

Changes

Workflow source support (project vs global/home)

Layer / File(s) Summary
API schema (query validation)
packages/server/src/routes/api.ts
Adds workflowTargetQuerySchema extending cwdQuerySchema with optional `source: 'project'
GET resolution order
packages/server/src/routes/api.ts
GET /api/workflows/:name now looks up project-scoped (cwd) first, then home/global (getHomeWorkflowsPath()), then bundled defaults; returns source: 'global' when found in home.
PUT (save) behavior
packages/server/src/routes/api.ts
PUT /api/workflows/:name accepts validated source; when source=global writes to home workflows dir and returns source: 'global', otherwise preserves project-scoped behavior (cwd validation).
DELETE behavior
packages/server/src/routes/api.ts
DELETE /api/workflows/:name accepts validated source; when source=global deletes from home workflows dir, otherwise deletes from project workflows; bundled-default deletion refusal is conditioned on source.
Server tests (global coverage)
packages/server/src/routes/api.workflows.test.ts
Adds GET /api/workflows/:name and PUT /api/workflows/:name?source=global tests that set ARCHON_HOME, create/remove ${ARCHON_HOME}/workflows files, assert source: "global", and verify written YAML contents; imports readFile for assertions.
Web API client signatures
packages/web/src/lib/api.ts
saveWorkflow and deleteWorkflow gain optional source?: WorkflowSource and append source=global to query when appropriate; many API types/exports restored/added.
WorkflowBuilder state and wiring
packages/web/src/components/workflows/WorkflowBuilder.tsx
Adds workflowSource state; loadWorkflow sets workflowSource from server response; handleSave passes workflowSource to saveWorkflow.
Command categorization (UI grouping)
packages/web/src/lib/command-categories.ts
categorizeCommands splits commands by source, adds a Global category for source === 'global', and orders Project → Global → bundled categories → Utilities.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Browser
  participant WebClient
  participant Server
  participant FS as Filesystem

  Browser->>WebClient: Open workflow in builder (name)
  WebClient->>Server: GET /api/workflows/:name?cwd=...?
  alt project file exists
    Server->>FS: read project/.archon/workflows/name.yaml
    FS-->>Server: project workflow
    Server-->>WebClient: 200 { workflow, source: "project" }
  else project missing but home exists
    Server->>FS: read $ARCHON_HOME/workflows/name.yaml
    FS-->>Server: global workflow
    Server-->>WebClient: 200 { workflow, source: "global" }
  else bundled exists
    Server-->>WebClient: 200 { workflow, source: "bundled" }
  end

  Browser->>WebClient: Save workflow (edited)
  WebClient->>Server: PUT /api/workflows/:name?cwd=...&source=global (if global)
  alt source=global
    Server->>FS: write $ARCHON_HOME/workflows/name.yaml
    FS-->>Server: ok
    Server-->>WebClient: 200 { name, source: "global" }
  else project
    Server->>FS: write project/.archon/workflows/name.yaml
    FS-->>Server: ok
    Server-->>WebClient: 200 { name, source: "project" }
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

"I hopped to ~/.archon with care,
Found global workflows waiting there.
I fetched and saved with gentle paw,
Project, Global — now both in law.
A little hop, a file well-placed — huzzah! 🐇"

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix(workflows): support editing global workflows' accurately describes the main change: enabling global workflow editing in the builder.
Description check ✅ Passed The PR description thoroughly covers all required template sections: summary with problem/impact/changes, detailed before/after UX journey with sequence diagrams, architecture diagrams with connection inventory, comprehensive validation evidence, security impact analysis, compatibility assessment, human verification details, side effects evaluation, and rollback plan.
Linked Issues check ✅ Passed The PR fully addresses all objectives from issue #1556: GET /api/workflows/:name now resolves global workflows; PUT/DELETE support source=global parameter; WorkflowBuilder preserves workflow source on save; global commands included in builder library; route tests added for global workflow load/save; monorepo type-check completed successfully.
Out of Scope Changes check ✅ Passed All changes are directly scoped to the linked issue: server route changes support global workflow detail/edit/delete, web builder preserves source on save, command categorization includes global commands, and test additions cover new functionality. No unrelated refactors or scope creep detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/server/src/routes/api.ts`:
- Line 1: The file was accidentally replaced by a single marker and no longer
exports registerApiRoutes; restore the module to export a registerApiRoutes
function that registers the workflow endpoints using
registerOpenApiRoute(createRoute({...}), handler). Specifically, implement and
export registerApiRoutes that calls registerOpenApiRoute with a GET route (e.g.,
WorkflowGetHandler) to fetch workflows, a PUT route (e.g., WorkflowPutHandler)
to create/update workflows, and a DELETE route (e.g., WorkflowDeleteHandler) to
remove workflows, ensuring each route is created via createRoute({...}) and
wired to its handler; follow the existing route shape and OpenAPI metadata
conventions used elsewhere in packages/server/src/routes and re-export the same
named symbols so imports elsewhere resolve.

In `@packages/server/src/routes/api.workflows.test.ts`:
- Line 1: The file currently contains only a placeholder string and must be
replaced with a real test module: restore
packages/server/src/routes/api.workflows.test.ts to export/define Jest tests
that exercise the global workflow load/save endpoints (e.g., tests named "loads
global workflows" and "saves global workflows"); import the app/server instance
and any test helpers (supertest/request, fixtures or mocked DB), set up/tear
down test data, call the relevant routes (GET/POST or PUT for global workflows),
assert responses and persisted state, and re-enable any mocked auth or DB
helpers previously used by other route tests so coverage for global workflow
load/save is restored. Ensure the module uses proper TypeScript imports/exports
and Jest describe/it blocks rather than the marker string.

In `@packages/web/src/components/workflows/WorkflowBuilder.tsx`:
- Line 1: The file currently contains only a string and must be replaced with
the real React component implementation: restore a functional exported component
named WorkflowBuilder (used by WorkflowBuilderPage.tsx) that implements
source-aware save/load for global workflows; specifically, reintroduce the
component (function WorkflowBuilder or const WorkflowBuilder: React.FC) with its
state/hooks to load workflow data based on source metadata, provide UI handlers
for saving which include source attribution and branch/commit info, and export
default WorkflowBuilder so WorkflowBuilderPage.tsx can import it — locate
references to WorkflowBuilder, its props (if any), and any load/save helpers
used elsewhere in the repo and wire them back into this component to match the
previous behavior.

In `@packages/web/src/lib/api.ts`:
- Line 1: The file currently contains an invalid marker and must be replaced
with the full TypeScript API surface required by the web package: restore
exports for functions like listWorkflows and listProviders and constants like
SSE_BASE_URL, and the types DagNode, CommandEntry, CodebaseResponse,
ConversationResponse, MessageResponse (and any other types used across
ChatPage.tsx, SettingsPage.tsx, DashboardPage.tsx, useProviders.ts, useSSE.ts).
Fix by replacing the marker string with the original module implementation or by
re-exporting the real implementations/types from their canonical module (e.g.,
export { listWorkflows, listProviders, SSE_BASE_URL } from '...'; export type {
DagNode, CommandEntry, CodebaseResponse, ConversationResponse, MessageResponse }
from '...'), making sure all named exports referenced across the web package are
present and properly typed so TypeScript type-checking and imports succeed.

In `@packages/web/src/lib/command-categories.ts`:
- Line 1: This module is empty but other modules import categorizeCommands; add
and export a named function categorizeCommands that matches the signature
expected by NodeLibrary.tsx and CommandPicker.tsx (e.g.,
categorizeCommands(commands: Command[]): Record<string, Command[]> or the exact
type those components expect), implement the logic to group commands into
categories (e.g., by command.category or similar property), and export any
related types used by callers; ensure the exported function name is exactly
"categorizeCommands" and the TypeScript types align with the Command type
imported/used by the callers so compilation succeeds.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5df9e04e-a957-4ea5-b6a3-b4211ac76ba1

📥 Commits

Reviewing files that changed from the base of the PR and between 69b2c89 and 3fa7435.

📒 Files selected for processing (5)
  • packages/server/src/routes/api.ts
  • packages/server/src/routes/api.workflows.test.ts
  • packages/web/src/components/workflows/WorkflowBuilder.tsx
  • packages/web/src/lib/api.ts
  • packages/web/src/lib/command-categories.ts

Comment thread packages/server/src/routes/api.ts Outdated
Comment thread packages/server/src/routes/api.workflows.test.ts Outdated
Comment thread packages/web/src/components/workflows/WorkflowBuilder.tsx Outdated
Comment thread packages/web/src/lib/api.ts Outdated
Comment thread packages/web/src/lib/command-categories.ts Outdated
@guanghuang guanghuang force-pushed the fix/global-workflow-builder-edit branch from 3fa7435 to e6da4e6 Compare May 3, 2026 18:39
@Wirasm
Copy link
Copy Markdown
Collaborator

Wirasm commented May 4, 2026

@guanghuang related to #1556 — global workflow editing support.

@blankse
Copy link
Copy Markdown

blankse commented May 4, 2026

There's significant overlap with #1525 (opened 2026-05-01, also still open), which addresses the same underlying gap - the single-workflow REST endpoints don't resolve ~/.archon/workflows/, so home-scoped workflows show up in the list but break on the detail page.

Both PRs touch packages/server/src/routes/api.ts and api.workflows.test.ts and add the same project → global → bundled tier in GET /api/workflows/:name. The interesting differences are:

Closing one in favor of the other, or rebasing #1557 on top of #1525's server fix and keeping only the Web UI/builder changes here, would avoid non-trivial merge conflicts in api.ts and the test file.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Workflow builder cannot view or edit global workflows from ~/.archon/workflows

3 participants