Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ body:
- CLI
- Control Plane UI
- Runs / reports / evidence
- Playground
- Providers
- Harness SDK / existing drivers
- Documentation / build / tooling
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Before choosing a visual direction, identify:
- Existing visual and interaction conventions that must remain coherent.
- Real content, data density, and exceptional states.

For operational tools such as the FSQ Playground, prefer a quiet, work-focused interface optimized for scanning, comparison, repeated action, and clear status. Do not turn an application workspace into a marketing page.
For operational tools such as the FSQ Control Plane, prefer a quiet, work-focused interface optimized for scanning, comparison, repeated action, and clear status. Do not turn an application workspace into a marketing page.

## Design Before Implementation

Expand Down
5 changes: 0 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ jobs:

generated = (
Path("fsq_agent/adapters/control_plane/static"),
Path("fsq_agent/adapters/control_plane/playground/static"),
Path("fsq_agent/resources"),
)
present = [str(path) for path in generated if path.exists()]
Expand Down Expand Up @@ -110,7 +109,6 @@ jobs:

generated = (
Path("fsq_agent/adapters/control_plane/static"),
Path("fsq_agent/adapters/control_plane/playground/static"),
Path("fsq_agent/resources"),
)
present = [str(path) for path in generated if path.exists()]
Expand Down Expand Up @@ -229,13 +227,10 @@ jobs:

required_prefixes = (
"fsq_agent/adapters/control_plane/static/",
"fsq_agent/adapters/control_plane/playground/static/",
)
required_files = (
"fsq_agent/adapters/control_plane/static/control-plane/index.html",
"fsq_agent/adapters/control_plane/static/entry-assets.json",
"fsq_agent/adapters/control_plane/playground/static/playground/index.html",
"fsq_agent/adapters/control_plane/playground/static/entry-assets.json",
"fsq_agent/resources/config.android.yaml",
"fsq_agent/resources/config.web.yaml",
"fsq_agent/resources/config.windows.yaml",
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ All notable changes are documented here. FSQ follows Semantic Versioning after p

- Initial open-source release preparation.

### Removed

- Removed the legacy Playground browser application, standalone HTTP server, Python APIs, and packaged frontend assets. Use `fsq ui` for the supported Control Plane browser workflows; raw YAML dynamic execution, lifecycle-hook editing, completed-Run loading, and automatic Goal Case publication are not carried forward.

## [0.1.0] - Unreleased

### Added
Expand Down
6 changes: 3 additions & 3 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ This roadmap communicates direction rather than a release commitment. Scope and

Make the repository trustworthy and practical for external contributors.

- Establish CI for linting, tests, package builds, and Playground builds.
- Establish CI for linting, tests, package builds, and Control Plane builds.
- Complete contributor-facing Issue and pull request workflows.
- Improve installation, quick-start, architecture, and troubleshooting documentation.
- Define the changelog, semantic versioning, and automated release process.
Expand Down Expand Up @@ -48,7 +48,7 @@ Target a five-minute path from installation to a first successful automation run
- Publish preconfigured Web and Android container images.
- Add Codespaces or equivalent cloud development setup.
- Add environment diagnostics and harness scaffolding commands.
- Improve interactive recording and Playground workflows.
- Improve interactive recording and Control Plane workflows.

## 2027 Q1-Q2: Ecosystem

Expand All @@ -57,7 +57,7 @@ Make FSQ useful as both a tool and a platform.
- Publish an official GitHub Action and CI integration guidance.
- Build a curated registry of reusable FSQ cases and skills.
- Add a compatibility matrix generated from tests and run evidence.
- Expand Playground into a case authoring and contribution workflow.
- Expand Control Plane into a case authoring and contribution workflow.
- Provide an embeddable Python SDK and progress toward a stable 1.0 release.
- Explore a VS Code extension for YAML authoring, evidence inspection, and run management.

Expand Down
34 changes: 13 additions & 21 deletions SPEC.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/assets/fsq-agent-exploration-flow.mmd
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
sequenceDiagram
participant User as User / Team
participant Entry as CLI / API / Playground
participant Entry as CLI / API / Control Plane
participant Planner as Model-Agnostic Planner
participant Model as Model Provider
participant K as Knowledge System
Expand Down
4 changes: 2 additions & 2 deletions docs/assets/fsq-agent-module-map.mmd
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
flowchart LR
subgraph Entry[Entry Modules]
CLI[CLI / API]
PLAY[Playground / Debug UI]
UI[Control Plane]
end

subgraph Testcase[Testcase Modules]
Expand Down Expand Up @@ -35,7 +35,7 @@ flowchart LR

CLI --> FSQYAML
CLI --> GOAL
PLAY --> DEBUG
UI --> DEBUG
FSQYAML --> NORMALIZER --> RUNNER --> ACTIONIR
GOAL --> PLANNER
MODEL <--> PLANNER
Expand Down
6 changes: 3 additions & 3 deletions docs/fsq-agent-architecture-deep-dive.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ Midscene uses a similar layered shape: entry integrations such as CLI, Playwrigh
flowchart LR
subgraph Entry[Entry Modules]
CLI[CLI / API]
PLAY[Playground / Debug UI]
UI[Control Plane]
end

subgraph Testcase[Testcase Modules]
Expand Down Expand Up @@ -125,7 +125,7 @@ flowchart LR

CLI --> FSQYAML
CLI --> GOAL
PLAY --> DEBUG
UI --> DEBUG
FSQYAML --> NORMALIZER --> RUNNER --> ACTIONIR
GOAL --> PLANNER
MODEL <--> PLANNER
Expand Down Expand Up @@ -188,7 +188,7 @@ The regression flow must not depend on a planner model. This is the main differe
```mermaid
sequenceDiagram
participant User as User / Team
participant Entry as CLI / API / Playground
participant Entry as CLI / API / Control Plane
participant Planner as Model-Agnostic Planner
participant Model as Model Provider
participant K as Knowledge System
Expand Down
2 changes: 1 addition & 1 deletion docs/release-acceptance-checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ The release workflow runs the equivalent automated gate before publication, incl
The CI package job is the executable contract for archive inspection. Confirm that it checks:

- exactly one wheel and one sdist;
- Control Plane and Playground HTML, JavaScript, CSS, and `entry-assets.json` in both archives;
- Control Plane HTML, JavaScript, CSS, and `entry-assets.json` in both archives;
- repository platform presets, default prompt templates, and configured skills in both archives;
- default dependencies for uiautomator2, Playwright, pywinauto, Pillow, and Appium Python Client;
- no platform extras;
Expand Down
2 changes: 1 addition & 1 deletion docs/step-runner-architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ Planner output / FSQ step
terminal progress
debug timeline
json report
live playground
Control Plane live timeline
CI reporter

这比让 Runner 直接 import 所有模块干净得多。
Expand Down
11 changes: 4 additions & 7 deletions frontend/SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,23 @@ This parent module does not own child application behavior or Python HTTP/runtim
- The root `package.json` and `package-lock.json` own exact npm dependencies and the single lock-file dependency graph.
- Supported Node.js versions are `^20.19.0 || >=22.12.0`.
- Vite is the frontend development and production build tool.
- `ts-ebml` is the current browser runtime dependency used by the Playground and Control Plane child modules for seekable WebM replay generation.
- `ts-ebml` is the current browser runtime dependency used by the Control Plane child module for seekable WebM replay generation.
- `react-markdown` is the current browser runtime dependency used by the Control Plane child module for safe Markdown preview without raw HTML support.
- The workspace consumes Python Playground and Control Plane HTTP origins only through Vite development proxy configuration and browser HTTP requests. Frontend source does not import Python modules.
- The workspace consumes the Python Control Plane HTTP origin only through Vite development proxy configuration and browser HTTP requests. Frontend source does not import Python modules.

## Public Interface

- `npm run dev` starts the Vite development server for frontend entries and proxies configured Playground API paths to `FSQ_PLAYGROUND_API_ORIGIN`, defaulting to `http://127.0.0.1:8878`.
- `npm run build` compiles all configured page entries through the untracked `.frontend-dist` staging directory and distributes each entry into its owning Python package static directory.
- `frontend/playground/SPEC.md` defines the Playground browser application's public behavior and source boundary.
- `npm run dev` starts the Vite development server for the Control Plane entry and proxies `/api/control-plane` to `FSQ_CONTROL_PLANE_API_ORIGIN`, defaulting to `http://127.0.0.1:8879`.
- `npm run build` compiles the configured Control Plane page entry through the untracked `.frontend-dist` staging directory and distributes it into its owning Python package static directory.
- `frontend/control-plane/SPEC.md` defines the Control Plane browser application's public behavior and source boundary.

## Internal Structure

- `../package.json`: Root npm metadata, scripts, Node.js compatibility, and exact direct dependency versions.
- `../package-lock.json`: Complete locked npm dependency graph.
- `../vite.config.js`: Multi-page entry configuration, development API proxying, and production output mapping.
- `playground/`: Independently specified Playground browser application.
- `control-plane/`: Independently specified Control Plane browser application.
- `../.frontend-dist/`: Untracked temporary Vite build staging.
- `../fsq_agent/adapters/control_plane/playground/static/`: Untracked generated Playground build output consumed by canonical Python packaging and production static serving; it is not authored frontend source.
- `../fsq_agent/adapters/control_plane/static/`: Untracked generated Control Plane build output consumed by canonical Python packaging and production static serving; it is not authored frontend source.

## Frontend Architecture
Expand Down
9 changes: 4 additions & 5 deletions frontend/control-plane/SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ The entry does not own backend validation, Provider/workspace persistence or aut
- `react-markdown` renders workspace Markdown previews with raw HTML disabled and no raw-HTML plugin.
- `/api/control-plane/*` is the only backend contract consumed by this entry.

The entry must not import Playground source, Python-generated static assets, backend implementation files, or another frontend entry's private code. It does not introduce Redux, React Query, a client router, Tailwind, CSS-in-JS, or a component framework.
The entry must not import Python-generated static assets, backend implementation files, or another frontend entry's private code. It does not introduce Redux, React Query, a client router, Tailwind, CSS-in-JS, or a component framework.

## Public Behavior

Expand Down Expand Up @@ -220,7 +220,7 @@ Current Devices ownership:
- `src/features/devices/components/ScreenView.tsx`, `UiSnapshotView.tsx`, and `RunLogsView.tsx`: current/selected-step evidence presentation; Logs owns structured-row message disclosure, sticky-table semantics, and log scroll following.
- `src/features/devices/components/ReplayVideoView.tsx`: terminal replay resolution, generation state, stored-video playback, and browser-resource cleanup.
- `src/features/devices/components/StepEvidenceView.tsx`: selected-step screenshot comparison and UI-snapshot diff presentation.
- `src/features/devices/replay/`: frame timing, Canvas/MediaRecorder capture, seekable WebM conversion, and diff helpers that remain independent from Playground source.
- `src/features/devices/replay/`: frame timing, Canvas/MediaRecorder capture, seekable WebM conversion, and diff helpers.
- `src/features/devices/hooks/useDeviceWorkspace.ts`: page state, one-time launch-intent validation/consumption, and discovery/run commands.
- `src/features/devices/hooks/useRunStream.ts`: sequence, SSE reconnect, and snapshot fallback.
- `src/styles/`: entry tokens and Devices-specific styles that do not override shell structure.
Expand Down Expand Up @@ -264,7 +264,7 @@ The application owns the Config request used to derive Overview's read-only safe
- Development requests under `/api/control-plane` proxy to the local Control Plane Python server and preserve unbuffered SSE.
- Production output is generated under `fsq_agent/adapters/control_plane/static`, remains untracked, and is included in the Python wheel beside the canonical Control Plane adapter.
- Installed-wheel use serves the generated entry and API from one Python process and requires no Node.js/network access.
- Static route fallback is limited to the Control Plane entry and never falls back to Playground.
- Static route fallback is limited to the Control Plane entry.
- The root package manifest and lock file own all frontend dependencies. No nested package project or second lock file exists.

## Error Handling
Expand Down Expand Up @@ -303,7 +303,7 @@ Empty states direct the user to create/select a workspace, add a configured plat
- Config tests cover malformed-response rejection, loading/empty/configured/unavailable states, complete Azure save and key visibility, dirty-state discard behavior, provider replacement preservation, immediate GitHub device-flow start, authorization/model-discovery polling, no-default model selection, offered-model save eligibility, discovery error/empty retry, save success/failure, expiration/cancel cleanup, saved-only Test connection eligibility/results, dialog keyboard/focus behavior, and secret-safe presentation.
- Devices tests cover shared workspace selection, ordinary entry with no implicit platform selection, available Workspace replay-intent platform/mode/case initialization, active-task precedence, missing/unavailable platform fallback, missing/non-selectable case fallback, valid configured-platform options, compound stale-request protection, derived start eligibility, workspace/platform Explore/Strict payloads, active workspace/platform/target locks, flat sequence-ordered timeline events, one-line overflow disclosure, active-run-only Jump visibility, exact bottom scrolling, immediate Jump dismissal/focus transfer, terminal Action selection, selected-step artifact states, screenshot comparison, UI Tree diff, replay generation/reuse/error cleanup, range-video playback, timeline/cancel/terminal/new-run behavior, stream resume/fallback, sticky Logs structure, per-row full event disclosure, tabs, accessible names, live announcements, and focus behavior.
- Browser verification covers Overview default with separate global AI and current-Workspace regions, safe Workspace identity, three-step flow, no selected Workspace, only-unavailable platforms, Provider configured/unconfigured/error states, desktop and narrow keyboard order, and navigation into Config, Workspace, and Devices; expanded Workspace group with path-free entries; multi-platform create, compact banner, configuration tabs, add/edit, and file-browser workflows; record-new-case navigation with workspace preservation and no platform; eligible top-level/nested FSQ replay navigation with explicit workspace/platform/Strict/case initialization and no automatic start; ineligible-file metadata without replay; stale-case empty selection; Markdown preview; selected-Workspace desktop title alignment and compact Configure presentation, edge-to-edge geometry, fixed structural dimensions, independent desktop scrolling, and omitted controls at 1440×900 and 1024×768; selected-Workspace stacked title and content flow without overlap or page-level horizontal overflow at 390×844; Devices workspace/platform selection plus viewport containment and independent scrolling at 1440×900 and 1280×720; keyboard-only navigation/disclosures/tree/tabs, Action selection, Show run replay, and immediate Jump dismissal; secret cleanup/visibility; long-path/content wrapping; Before/After comparison with original image edges; UI Tree diff including XML structured rendering; generated-video playback/seeking; constrained screenshot/replay media; sticky Logs; all four platform forms/readiness presentations; and at least one available platform's Explore/Strict progress, evidence, cancellation, and terminal behavior. Layout changes require reviewed desktop and narrow screenshots plus a clean browser console.
- Build/package verification proves both Vite entries are generated, existing Playground remains functional, and an isolated wheel starts Control Plane without Node.js.
- Build/package verification proves the Control Plane Vite entry is generated and an isolated wheel starts Control Plane without Node.js.

## Current Invariants

Expand All @@ -325,4 +325,3 @@ Empty states direct the user to create/select a workspace, add a configured plat
- Compound workspace-platform request generations prevent stale responses from changing the selected context.
- Terminal selected-Action evidence loading is non-destructive: changing Action selection does not clear the current selected-Action Screen/UI Tree presentation before the next Action's artifacts resolve, and stale artifact reads cannot replace the current selection.
- No large evidence bytes are carried in SSE.
- Existing Playground source and behavior remain independent.
Loading
Loading