Skip to content

feat(system): Services card on Home — API, Web UI and Workflow engine status - #587

Merged
huyplb merged 1 commit into
mainfrom
feat/service-status
Nov 2, 2026
Merged

huyplb merged 1 commit into
mainfrom
feat/service-status

Conversation

@huyplb

@huyplb huyplb commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

Step 1 of the service status design (#586), for the board card dashboard-service-control. Read-only: starting and stopping the engine is step 2.

What it does

GET /api/system/services (signed in) answers:

  • api: running, with its version and uptime
  • engine, one of:
    • running: its /health answers. When the saved Workflow state isn't enabled, it also says Not taking new runs.
    • not_configured: no answer, and this server lacks WORKFLOW_ENGINE_TOKEN and/or FOXFLOW_ENCRYPTION_KEY, which are named
    • unreachable: no answer though everything is set, with the probe's reason

It reuses WorkflowSettingsService.probeEngineHealth(), so the status checks the same endpoint the proxy forwards to. WorkflowSettingsService is now exported from the workflow module's index.ts, because other features may only import that file. The response shape is in @foxschema/shared (service-status.ts). The Web UI isn't reported: the page asking proves it runs.

Home → Services shows API, Web UI and Workflow engine, each with a dot (blue running, amber unreachable, grey not configured), the state, and the reason. It refreshes every 10 s while Home is open.

Tests

  • service-status.test.ts (6): API version and uptime; engine running, and running without taking runs; which variables are missing; unreachable with the reason; a probe that throws
  • ServiceStatusCard.test.tsx (5): each engine state, the 10 s refresh, and a failed request
  • http-contract.test.ts: the new route is pinned (200)

Mutation checks: dropping the not-configured rule fails one test; dropping the running rule fails two.

Live: on this dev server the endpoint answered api 0.2.383 running, engine not_configured with both variables named, and the card on Home shows the same.

tsc and eslint are clean, and the test-ID catalog is regenerated.

🤖 Generated with Claude Code


Note

Low Risk
Read-only, user-authenticated system metadata and UI polling; no changes to auth, secrets handling, or engine start/stop.

Overview
Adds a read-only Services section on Home that shows whether the API, Web UI, and Workflow engine are up, with short reasons when the engine is not configured or unreachable.

Backend: New signed-in GET /api/system/services returns a shared ServiceStatusReport: API version and uptime, plus engine state from WorkflowSettingsService.probeEngineHealth(), mapping missing env vars to not_configured and failed probes to unreachable (including when the engine runs but is not taking new runs).

Frontend: ServiceStatusCard calls the endpoint on mount and every 10s while Home is open; fetchServiceStatus wraps the HTTP client. E2E test IDs and docs are updated for the new UI.

Tests: Server readServiceStatus cases, ServiceStatusCard behavior (states, refresh, fetch errors), and HTTP contract pin for the new route.

Reviewed by Cursor Bugbot for commit 4d4688f. Bugbot is set up for automated code reviews on this repo. Configure here.

… status

Step 1 of docs/plans/2026-11-01-service-status.md (board card
dashboard-service-control), read-only.

GET /api/system/services answers the API's version and uptime and the
engine's state: running when its /health answers (noting when it takes no
new runs), not_configured when it does not and this server lacks
WORKFLOW_ENGINE_TOKEN or FOXFLOW_ENCRYPTION_KEY (named), unreachable
otherwise, with the probe's reason. It reuses WorkflowSettingsService's
existing endpoint and health probe; the shape lives in @foxschema/shared.

Home shows a Services card: a blue dot for running, amber for unreachable,
grey for not configured, with the reason, refreshed every 10 s. Start and
stop for the engine is step 2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

Test IDs

Added (5)

  • home-service-{…}
  • home-service-{…}-detail
  • home-service-{…}-state
  • home-services
  • home-services-error

{…} is a part filled in at run time. The full tree: docs/testing/TEST_IDS.md.

@cursor cursor 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.

Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 4d4688f. Configure here.

const env = deps.env ?? process.env;
const missing = ENGINE_REQUIRED_ENV.filter((name) => !env[name]?.trim());
if (missing.length > 0) {
return { state: 'not_configured', detail: `Set ${missing.join(' and ')} on the server to run the engine.` };

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.

Engine key checked on wrong process

Medium Severity

FOXFLOW_ENCRYPTION_KEY is required only on the workflow engine, not on the FoxSchema API, but ENGINE_REQUIRED_ENV treats a missing value on this process as not_configured. In the documented Docker split, the fox service never receives that variable, so an unreachable engine is reported as unconfigured and operators are told to set a key that does not belong here.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 4d4688f. Configure here.

label={engine ? (report?.engine.version ? `${engine.label} · ${report.engine.version}` : engine.label) : 'Checking…'}
tone={engine?.tone ?? 'off'}
detail={report?.engine.detail}
/>

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.

Engine stays checking after failed request

Low Severity

When fetchServiceStatus fails and no prior report exists, the Workflow engine row keeps the Checking… label. Engine state comes from that same request, which has already finished, so the row looks as if a check is still in progress while API correctly shows No answer.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 4d4688f. Configure here.

@huyplb
huyplb merged commit 7599800 into main Nov 2, 2026
13 checks passed
@huyplb
huyplb deleted the feat/service-status branch November 2, 2026 02:23
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.

1 participant