diff --git a/.env.example b/.env.example index 4f874d8e2a..23f4d4558f 100644 --- a/.env.example +++ b/.env.example @@ -1,2 +1,2 @@ -JULES_API_KEY=your_api_key_here +JULES_API_KEY= DASHBOARD_PORT=4444 diff --git a/AGENTS.md b/AGENTS.md index 0a9a7705b5..46c548faf5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -28,7 +28,7 @@ Package manager is **pnpm** (`pnpm@10.33.0`), Node **22+**. Use `pnpm`, not `npm - `pnpm run typecheck` / `pnpm run lint`: strict `tsc --noEmit` (the two are the same command). - `pnpm run test`: full Vitest run. `pnpm run test:backend` / `pnpm run test:dashboard`: scoped suites. - `pnpm run test:watch`: watch mode. `pnpm run test:coverage`: coverage with threshold enforcement. -- `pnpm run ci`: local CI equivalent (`lint` → `test:backend:coverage` → `test:dashboard` → `build`). +- `pnpm run ci`: local CI equivalent (`quality:guardrails -> audit -> lint -> test:backend:coverage -> test:dashboard -> build`). - `pnpm run audit`: `pnpm audit --audit-level=high`. - `pnpm start`: run compiled `dist/index.js`. `node dist/index.js --help`: list CLI flags / env vars. - Electron: `pnpm run electron:dev`, `pnpm run electron:dist[:linux|:mac|:win]`. @@ -75,7 +75,7 @@ Package manager is **pnpm** (`pnpm@10.33.0`), Node **22+**. Use `pnpm`, not `npm - `dev` is the integration branch. Always create and work from a feature branch off `dev` (never commit directly to `dev` or `main`). - Use descriptive branch names such as `feat/`, `fix/`, or `chore/`. - Merge changes into `dev` only via pull requests after required CI checks pass (not into `main`). - - Push branches to `origin` (`codeux-ai/codeux`) and target it for PRs. + - Push branches to `origin` (the `numnx/codeux` fork) and target it for PRs. `upstream` is `codeux-ai/codeux`. - Use GitHub CLI (`gh`) for PR workflow when available (for example `gh pr create --base dev`, `gh pr view`, `gh pr merge`). - PRs should include: - What changed and why. @@ -165,7 +165,7 @@ Release note rules: - Default working flow for our collaboration: - Start every change on a new feature branch off `dev`. - Implement and validate locally (`pnpm run build` minimum; `pnpm run ci` preferred). - - Open a PR into `dev` against `origin` (`codeux-ai/codeux`) using GitHub CLI. + - Open a PR into `dev` against `origin` (the `numnx/codeux` fork) using GitHub CLI. - Monitor CI continuously after opening the PR. - Merge only through PR after all required CI checks pass without errors. - Delete merged feature branches to keep the branch list clean. diff --git a/CLAUDE.md b/CLAUDE.md index 168f090960..cd30138bc7 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -33,7 +33,7 @@ pnpm run test:watch # Vitest watch mode pnpm test tests/backend/smoke.test.ts # Single test file pnpm run test:coverage # Coverage with threshold enforcement pnpm run typecheck # tsc --noEmit (alias: lint — same command) -pnpm run ci # lint + test:backend:coverage + test:dashboard + build +pnpm run ci # quality:guardrails -> audit -> lint -> test:backend:coverage -> test:dashboard -> build pnpm run audit # pnpm audit --audit-level=high ``` @@ -41,7 +41,7 @@ Electron: `pnpm run electron:dev`, `pnpm run electron:dist[:linux|:mac|:win]`. Coverage thresholds (vitest.config.ts, ratchet-only — never lower): lines 77.4%, functions 71.5%, branches 66.1%, statements 76.0%. `src/server/activity-cache-service.ts` has a separate 80% line -gate. CI runs on Node 22: lint → backend coverage → dashboard tests → build. +gate. CI runs on Node 22: lint -> test:backend:coverage -> test:dashboard -> build. ## Architecture @@ -152,7 +152,8 @@ In this working environment you have broad latitude to operate the running syste - Conventional Commits (`feat:`, `fix:`, `docs:`, `chore:`). **`dev` is the integration branch** — branch off `dev` and open PRs **into `dev`** (not `main`) after CI passes; use `gh` for PR workflow. -- Remotes: `origin` is `codeux-ai/codeux` — push feature branches there and target it for PRs. +- Remotes: `origin` is the **`numnx/codeux` fork** — push branches there and target it for PRs. + `upstream` is `codeux-ai/codeux`; do not push or PR there unless explicitly asked. - 2-space indent, `camelCase` vars/functions, `PascalCase` types/components. Strict typing — avoid `any`. No new plain-JS modules. Tailwind is the only styling approach; don't add UI frameworks. - Documentation source of truth is `docs/` (entrypoint `docs/index.md`, index `docs/SUMMARY.md`). diff --git a/GEMINI.md b/GEMINI.md index 0b568944ed..0bbfeb9822 100644 --- a/GEMINI.md +++ b/GEMINI.md @@ -118,11 +118,7 @@ All UI work must meet the quality gate in `STYLEGUIDE.md`: `vi.spyOn()` for verification. ### Validation Workflow (`pnpm run ci`) -Before a task is complete, all of these MUST pass (`ci` = lint → backend coverage → dashboard → build): -1. `pnpm run lint` (alias of `typecheck`: strict `tsc --noEmit`). -2. `pnpm run test:backend:coverage`. -3. `pnpm run test:dashboard`. -4. `pnpm run build` (server `tsc` + dashboard typecheck + `vite build`). +Before a task is complete, all of these MUST pass (`ci` = quality:guardrails -> audit -> lint -> test:backend:coverage -> test:dashboard -> build). - Do not validate changes visually with Browser automation Tools unless explicitly told to --- diff --git a/README.md b/README.md index c43dbc90ce..fe57554742 100644 --- a/README.md +++ b/README.md @@ -141,7 +141,7 @@ Docker-backed execution provides: - Hermetic task workspaces and snapshot-based QA reviews. - Reusable runtime caches for package managers and provider CLIs. -- Auth-copy support for provider credentials such as `~/.codex`, `~/.claude`, `~/.gemini`, `~/.qwen`, and OpenCode auth. +- Isolated credential mounts for provider auth (such as `~/.codex`, `~/.claude`, `~/.gemini`, `~/.qwen`, and OpenCode) rather than broad workspace root exposure. - Short-lived execution containers that are cleaned up after runs instead of becoming permanent agent environments. - Isolated merge-conflict repair and CI autofix flows. - Startup cleanup for stale containers, workspaces, and preview sessions. @@ -289,6 +289,8 @@ start planning sprint work without rebuilding the same agent setup for every CLI ## Documentation +Canonical repository documentation lives in the `docs/` directory, while `docs-web/` serves as the sole publication and reference mirror. The use of a `docs-release/` directory is explicitly forbidden. + - [User quickstart](./docs-web/user/quickstart.md) - [Installation](./docs-web/user/installation.md) - [Providers and models](./docs-web/user/providers-and-models.md) @@ -329,6 +331,7 @@ Codex, Claude Code, Qwen Code, OpenCode, and Antigravity CLI. ```bash pnpm run dev +pnpm run dev:server-only ``` Then open `http://localhost:4444`. @@ -343,9 +346,11 @@ pnpm start ### Validate locally ```bash +pnpm run quality:guardrails +pnpm run audit pnpm run lint -pnpm run typecheck -pnpm run test +pnpm run test:backend:coverage +pnpm run test:dashboard pnpm run build ``` diff --git a/docs-web/architecture/configuration-resolution.md b/docs-web/architecture/configuration-resolution.md index ddee81b0ff..21927e6f26 100644 --- a/docs-web/architecture/configuration-resolution.md +++ b/docs-web/architecture/configuration-resolution.md @@ -65,10 +65,10 @@ After bootstrap, Code UX loads the settings tree from the database. Three tables For any field, the effective value at sprint scope is: ``` -defaults → system → project → sprint +system → project → sprint ``` -A field unspecified at higher scopes inherits from lower scopes. The merge is **deep** for object-valued fields (e.g. `aiProvider.providers.codex` only overrides the keys you set, not the whole object). +System settings act as the base (with built-in defaults folded into them). A field unspecified at higher scopes inherits from lower scopes. The merge is **deep** for object-valued fields (e.g. `aiProvider.providers.codex` only overrides the keys you set, not the whole object). ### Where defaults live @@ -83,7 +83,7 @@ System settings on a fresh install are the merge of these defaults plus any exte ### Live reload -Settings changes via `manage_code_ux` → `settings` → `patch_*_setting` (or the corresponding REST endpoints) trigger: +Settings changes via `manage_settings` → `patch_*_setting` (or the corresponding REST endpoints) trigger: - A WebSocket event broadcasting the change. - Hot-reload of the relevant subscribers (e.g. the orchestrator picks up new `watchLoopIntervalSeconds` on the next cycle). @@ -96,9 +96,9 @@ There is no need to restart the process for settings changes. - `GET /api/projects/:projectId/settings/effective` — merged at project scope. - `GET /api/projects/:projectId/sprints/:sprintId/settings/effective` — merged at sprint scope. -- `manage_code_ux` → `settings` → `resolve_project_effective` / `resolve_sprint_effective`. +- `manage_settings` → `resolve_project_effective` / `resolve_sprint_effective`. -These return the full merged tree, useful for debugging "why is this setting taking that value?". +These endpoints return an `EffectiveSettingsResponse` which includes both the merged tree (`settings`) and field-level provenance metadata (`sources` mapping each path to `system`, `project`, or `sprint`), useful for debugging "why is this setting taking that value?". ## External hints @@ -132,7 +132,7 @@ The default backend is **SQLite** at `~/.code-ux/database.sqlite`. A migration p ## Reset semantics -- **Per-project reset** (`reset_project_settings`) clears the project's override row; effective values revert to `system → defaults`. -- **Per-sprint reset** (`reset_sprint_settings`) clears the sprint's override; effective values revert to `project → system → defaults`. +- **Per-project reset** (`DELETE /api/projects/:projectId/settings` or `reset_project_settings`) clears the project's override row; effective values revert to `system`. +- **Per-sprint reset** (`DELETE /api/sprints/:sprintId/settings` or `reset_sprint_settings`) clears the sprint's override; effective values revert to `project → system`. - **System reset** (no dedicated action; use `replace_system_settings` with a default tree) requires explicit replacement. - **Database reset** (`POST /api/system/reset-database`) wipes everything; use only as a last resort. diff --git a/docs-web/architecture/dashboard-architecture.md b/docs-web/architecture/dashboard-architecture.md index 1b3868c501..686bae7456 100644 --- a/docs-web/architecture/dashboard-architecture.md +++ b/docs-web/architecture/dashboard-architecture.md @@ -77,7 +77,10 @@ const routes = [ { path: "/live", component: LiveSessionPage }, { path: "/chat", component: ChatPage }, { path: "/agents", component: AgentsPage }, + { path: "/scheduler", component: SchedulerPage }, { path: "/memory", component: MemoryPage }, + { path: "/knowledge", component: KnowledgePage }, + { path: "/files", component: FileBrowserPage }, { path: "/browser", component: BrowserPage }, { path: "/stats", component: StatsPage }, { path: "/config", component: SettingsPage }, @@ -98,7 +101,7 @@ State is managed with a mix of: - **`@preact/signals`** for global and page-level reactive state. - **Custom data hooks** wrapping REST + WebSocket subscriptions: - `useDashboardRuntimeData()` — live execution data. - - `useRealTimeResource()` — generic WebSocket subscription wrapper. + - `useRealtimeResource()` — generic WebSocket subscription wrapper. - `useProjectData()` — active project / sprint. - `useSprints()`, `usePreviewSessions()`, `useChatPageData()`, `useSettingsPageState()`, `useMemoryPageData()`, `useOverviewPageData()`, `useExecutionTimeline()`, `useProgressiveList()`. diff --git a/docs-web/architecture/data-model.md b/docs-web/architecture/data-model.md index cf342a1638..59fa8c9549 100644 --- a/docs-web/architecture/data-model.md +++ b/docs-web/architecture/data-model.md @@ -227,7 +227,7 @@ Memories with mismatched `embeddingModelId` are excluded from search; trigger re | `id` | string | – | | `endpointKey` | string | Stable client-supplied ID. | | `displayName` | string | – | -| `role` | enum | `project_manager`/`worker`/`listener`. | +| `role` | enum | `project_manager`/`worker-host`. | | `transport` | enum | `stdio`/`http`/`internal`. | | `capabilities` | json | – | | `status` | enum | `connected`/`disconnected`. | diff --git a/docs-web/architecture/index.md b/docs-web/architecture/index.md index 59f5cb3082..5bccd42204 100644 --- a/docs-web/architecture/index.md +++ b/docs-web/architecture/index.md @@ -8,7 +8,7 @@ It is for contributors and integrators who need to reason about *how* Code UX ma | # | Page | Topic | | --- | --- | --- | -| 1 | [System overview](./system-overview.md) | Process model, runtime composition, top-level data flow | +| 1 | [System overview](./system-overview.md) | Container-first process model, runtime composition, top-level data flow | | 2 | [MCP server](./mcp-server.md) | Tool dispatch, transports, authentication, session lifecycle | | 3 | [Sprint engine](./sprint-engine.md) | Cycle pipeline, watch loop state machine, dependency resolution, retries | | 4 | [Virtual workers](./virtual-workers.md) | Provisioning, lifecycle, Docker vs host execution, attention-item handling | diff --git a/docs-web/architecture/system-overview.md b/docs-web/architecture/system-overview.md index 9e17a6b132..422740d410 100644 --- a/docs-web/architecture/system-overview.md +++ b/docs-web/architecture/system-overview.md @@ -41,7 +41,7 @@ Code UX is a single Node process that hosts multiple cooperating services. This └────────────────────────────────────────────────────────────────────┘ ``` -The process is started by `src/index.ts` → `CodeUxServer.run()`. Lifecycle: +The primary CLI/management entrypoint is `src/index.ts`, which loads configuration and starts `CodeUxServer.run()`. `CodeUxServer` wires all backend services. The dashboard/API serves on a configured port (default 4444), while the worker host and Electron shell operate as separate entrypoints. Lifecycle: 1. **Boot settings** — load and migrate the settings DB. 2. **Refresh API key** — pull from CLI / env / settings. @@ -112,7 +112,7 @@ Subtask data is *also* persisted as markdown files for portability — see [Spri ## Data flow: a sprint cycle ``` -Dashboard click "Orchestrate" MCP client calls manage_code_ux:start +Dashboard click "Orchestrate" MCP client calls grouped tools (e.g., manage_sprints:start) (manage_code_ux is deprecated) │ │ ▼ ▼ POST /api/sprints/.../orchestrate ToolRegistry → sprint-actions.ts diff --git a/docs-web/architecture/virtual-workers.md b/docs-web/architecture/virtual-workers.md index 78c324c480..e4e08d2bc3 100644 --- a/docs-web/architecture/virtual-workers.md +++ b/docs-web/architecture/virtual-workers.md @@ -97,10 +97,11 @@ Per provider, `executionMode` is `DOCKER` (default) or `HOST`. ### DOCKER mode -- Image: `node:24-bookworm` (override via `workers.dockerImage`). +- Image: `node:24-bookworm` (override via `workers.dockerImage`). Images are cached across runs using a setup image cache. - Mounts: - - The worktree path read-write. - - The provider auth path (e.g. `~/.gemini`) read-only, if `mountAuth: true`. + - The workspace volume (`code-ux.workspace=true`) is mounted read-write. + - Runtime volumes (`code-ux.workspace-runtime=true`) are used for preserving package manager caches and the provider home directory outside of the main workspace. + - Provider credentials are conceptually mounted via dedicated, isolated credential mounts (e.g. `mountAuth: true` builds provider-specific mounts without exposing raw host tokens or keys to the workspace root or command arguments). - Optional setup script. - Network: default bridge. - The CLI runs as the container's default user (root, in the default image). @@ -110,7 +111,7 @@ Per provider, `executionMode` is `DOCKER` (default) or `HOST`. - The CLI runs directly on the host as the Code UX process user. - No mount; the CLI uses its native auth. -- Faster startup, no Docker dependency, but less hermetic. +- Used *only* as a fallback for specific edge cases (such as degraded CI autofix runs when Docker is unrecoverably unavailable). Docker is the strict default and is required for merge conflict isolation. ## Worktree management @@ -194,7 +195,7 @@ Each dispatch records: - PR URL on success. - Failure reason. -Visible in the dashboard's **Tasks** detail panel and via `manage_code_ux` → `tasks` → `inspect_run` and `telemetry` → `list_task_dispatches`. +Visible in the dashboard's **Tasks** detail panel and via `manage_tasks` → `inspect_run` and `manage_telemetry` → `list_task_dispatches`. ## Tuning diff --git a/docs-web/developer/building-from-source.md b/docs-web/developer/building-from-source.md index ba39ec17a9..2054038a9f 100644 --- a/docs-web/developer/building-from-source.md +++ b/docs-web/developer/building-from-source.md @@ -100,6 +100,7 @@ codeux --help ``` src/ ├── index.ts # CLI entry +├── electron/ # desktop shell entrypoint and policies (does not own orchestration) ├── app/ # lifecycle, dependency factory ├── config/ # CLI flag + env parsing ├── contracts/ # shared types, MCP tool definitions @@ -110,11 +111,11 @@ src/ ├── integrations/ # Jules API client ├── mcp/ # MCP server, request router, tool handlers ├── repositories/ # settings, agents, memory, project -├── server/ # Express dashboard server, routes, websocket +├── server/ # Express dashboard server (default port 4444), routes, websocket ├── services/ # virtual-worker-service, sprint-markdown-service, etc. ├── shared/ # config search paths, common utils ├── sprint/ # cycle steps (start-ready-tasks, etc.) -└── worker/ # worker-mode entry (reserved) +└── worker/ # worker-host mode entrypoint (separate from main server) dashboard/ ├── index.html @@ -149,13 +150,13 @@ tests/ pnpm run typecheck # tsc --noEmit (server) pnpm run typecheck:dashboard # tsc --noEmit (dashboard) pnpm run lint # alias for typecheck (no eslint shipped) -pnpm test # vitest run (full suite) +pnpm run test # vitest run (full suite) pnpm run test:watch # vitest watch mode pnpm run test:backend # backend only pnpm run test:dashboard # dashboard only pnpm run test:coverage # full coverage report pnpm run test:backend:coverage # backend coverage with threshold gate -pnpm run ci # local CI: guardrails + audit + lint + backend coverage + dashboard tests + build +pnpm run ci # local CI: quality:guardrails -> audit -> lint -> test:backend:coverage -> test:dashboard -> build pnpm run audit # pnpm audit --audit-level=high pnpm run smoke-test # node dist/index.js --help pnpm run dev:server-only # boot just the server from source @@ -194,6 +195,6 @@ The CI tag pipeline runs the full build, runs the audit, and publishes to npm. ## Development tips -- Use `pnpm run dev` + `pnpm run dev:dashboard` in two terminals for the fastest iteration loop. +- Use `pnpm run dev` in one terminal (which starts both the server and dashboard watcher) for the fastest iteration loop. - The MCP stdio server only activates if stdin is not a TTY. To exercise it locally, pipe a JSON-RPC request: `echo '{"jsonrpc":"2.0","id":1,"method":"initialize"}' | node dist/index.js`. - For one-off MCP HTTP integration tests, the legacy `--mcp-https` flag plus `curl` is the simplest harness. diff --git a/docs-web/developer/http-api.md b/docs-web/developer/http-api.md index d5ad190064..bd190dac46 100644 --- a/docs-web/developer/http-api.md +++ b/docs-web/developer/http-api.md @@ -6,7 +6,7 @@ This page lists every endpoint, grouped by domain. Path parameters use `:name` n > **Authentication:** The dashboard REST API is intended for trusted local consumption. It is not authenticated. Bind only to loopback (default) or front it with a reverse proxy when exposing remotely. -> **MCP HTTP gateway** (`--mcp-https`) is a *separate* listener for JSON-RPC and is documented in [MCP server](../architecture/mcp-server.md). +> **MCP HTTP gateway** (`--mcp-http`) is a *separate* listener for JSON-RPC and is documented in [MCP server](../architecture/mcp-server.md). --- diff --git a/docs-web/developer/management-actions.md b/docs-web/developer/management-actions.md index 259868e501..950f48f4b4 100644 --- a/docs-web/developer/management-actions.md +++ b/docs-web/developer/management-actions.md @@ -1,10 +1,11 @@ # Management actions -Code UX exposes **one MCP tool per management domain** — `manage_projects`, `manage_sprints`, +Code UX exposes grouped MCP tools per management domain — `manage_projects`, `manage_sprints`, `manage_tasks`, `manage_quicksprints`, `manage_scheduler`, `manage_agents`, `manage_memory`, -`manage_settings`, `manage_preview`, and `manage_telemetry` — ten domains, each with a set of -**actions**. This page is the complete matrix. (See [MCP tools](./mcp-tools.md) for the tool list and -schemas.) +`search_knowledge`, `manage_settings`, `manage_preview`, and `manage_telemetry`. The deprecated +`manage_code_ux` tool remains available for compatibility, but the grouped tools are the primary +surface. Each domain has a set of **actions**. This page is the complete matrix. (See +[MCP tools](./mcp-tools.md) for the tool list and schemas.) A dedicated-tool call takes the `action` plus action-specific fields: @@ -16,7 +17,7 @@ A dedicated-tool call takes the `action` plus action-specific fields: } ``` -**Approval handshake:** Destructive actions return `{ approvalRequired: true, approvalMessage: "..." }` on first call. Re-call with `approval: { confirmed: true }` to proceed. +**Approval handshake:** Destructive actions return `{ approvalRequired: true, approvalMessage: "..." }` on first call. Re-call with `approval: { confirmed: true }` (or `--payload-json '{"approval":{"confirmed":true}}'` in the CLI) to proceed. --- @@ -99,15 +100,17 @@ Task create/update fields include `title`, `name`, `promptMarkdown`, `descriptio | Action | Destructive | Required payload | Description | | --- | --- | --- | --- | | `list` | – | `projectId`, optional `from`, `to` | List scheduler entries and occurrences for a project window. | -| `create` | – | `projectId`, `targetType`, `scheduledFor`, target payload | Create a generic scheduler entry for `sprint`, `quicksprint`, or `chat`. | +| `create` | – | `projectId`, `targetType`, `scheduledFor`, target payload | Create a generic scheduler entry for `sprint`, `quicksprint`, `chat`, or `memory_remediation`. | | `schedule_sprint` | – | `projectId`, `scheduledFor`, `sprintId` | Schedule a sprint orchestration. | | `schedule_quicksprint` | – | `projectId`, `scheduledFor`, `templateId` | Schedule a quicksprint. Optional `taskCount`, `submitMode`, `additionalPrompt`, `agentPresetId`, `planningOverrides`. | | `schedule_chat` | – | `projectId`, `scheduledFor`, `bodyMarkdown` | Schedule a chat message. Optional `threadId`, `connectionId`, `title`, `timezone`, `recurrence`. | | `update` | – | `entryId`, update fields | Update scheduler title, status, time, recurrence, or target payload. | | `delete` | ✅ | `entryId` | Delete a scheduler entry. | -| `run_due` | – | optional `now` | Evaluate due entries immediately, mostly for operational verification. | +| `run_due` | – | optional `now` ISO date override | Evaluate due entries immediately, mostly for operational verification. | -`create` accepts nested targets (`sprintTarget`, `quicksprintTarget`, `chatTarget`) or the flattened fields used by the `schedule_*` aliases. Scheduled chat entries post through the dashboard chat runtime when due, so they can target an existing thread with `threadId` or create/use a titled thread with `title`. +`create` accepts nested targets (`sprintTarget`, `quicksprintTarget`, `chatTarget`) or the flattened fields used by the `schedule_*` aliases. `schedule_sprint`, `schedule_quicksprint`, and `schedule_chat` infer the target type. Scheduling supports an absolute time (`scheduledFor`) or an `after_sprint_end` anchor via `scheduleMode` or `anchorMode`, with `sourceSprintId` / `anchorSourceSprintId` and optional `offsetMinutes` / `anchorOffsetMinutes`. + +Memory remediation schedules use `targetType: "memory_remediation"` but have their own dedicated `/api/projects/:projectId/scheduler/memory-remediation` HTTP routes separate from the normal scheduler entries. --- @@ -123,13 +126,13 @@ Task create/update fields include `title`, `name`, `promptMarkdown`, `descriptio | `replace_system_settings` | ✅ | `settings` | Replace all system settings. | | `patch_system_setting` | ✅ | `path`, `value` | Patch one field by JSON path. | | `replace_project_settings` | ✅ | `projectId`, `settings` | Replace project settings. | -| `patch_project_setting` | – | `projectId`, `path`, `value` | Patch a project setting. | +| `patch_project_setting` | ✅ | `projectId`, `path`, `value` | Patch a project setting. | | `reset_project_settings` | ✅ | `projectId` | Reset project to defaults. | | `replace_sprint_settings` | ✅ | `projectId`, `sprintId`, `settings` | Replace sprint settings. | -| `patch_sprint_setting` | – | `projectId`, `sprintId`, `path`, `value` | Patch a sprint setting. | +| `patch_sprint_setting` | ✅ | `projectId`, `sprintId`, `path`, `value` | Patch a sprint setting. | | `reset_sprint_settings` | ✅ | `projectId`, `sprintId` | Reset sprint to defaults. | -All mutating settings actions are human-confirmation gated, including patch actions. The first call records the exact action and payload for up to 15 minutes and returns `approvalRequired: true`; it does not mutate settings, even if `approval.confirmed: true` was sent. After the user explicitly confirms, repeat the same action with the same payload and `approval.confirmed: true`. The approval is one-use and cannot approve a different settings payload. +All mutating settings actions (replace, patch, reset) require human confirmation. Get/resolve actions are read-only. Mutating settings actions first return an approval-required response; only the exact same action and payload may execute once with `approval.confirmed: true` within 15 minutes. The approval is one-use and cannot approve a different settings payload. JSON path examples for `patch_*`: - `aiProvider.providers.codex.model` → string @@ -174,6 +177,19 @@ Manages agent presets per project. | `count` | – | `projectId`, `scope` | Count by scope. | | `model_status` | – | – | Get embedding model status. | +### Claim actions + +The memory domain also exposes durable claim management: + +| Action | Destructive | Required payload | Description | +| --- | --- | --- | --- | +| `create_claim` | – | `projectId`, `claim` | Create a project claim. Accepts `category`, `confidence`, `durability`, `tags`, `appliesToPaths`, `sourceMemoryId`, `supersedesClaimId`, `supportType`, `weight`, and `evidenceWeight`. | +| `list_claims` | – | `projectId` | List project claims. Accepts `status`, `category`, and `limit`. | +| `get_claim` | – | `projectId`, `claimId` | Get a specific claim. | +| `update_claim` | – | `projectId`, `claimId` | Update a claim. Accepts `claim`, `category`, `confidence`, `durability`, `status`, `tags`, `appliesToPaths`, and `supersedesClaimId`. | +| `add_claim_evidence` | – | `projectId`, `claimId`, `memoryId` | Add evidence to a claim. Accepts `supportType` and `weight`. | +| `deprecate_claim` | ✅ | `projectId`, `claimId` | Deprecate a claim and require approval confirmation. | + --- ## `preview` @@ -205,6 +221,7 @@ Read-only execution telemetry. | `list_sprint_runs` | – | `projectId`, `sprintId` | Compact run list. | | `list_task_dispatches` | – | `projectId`, `sprintId`, `taskId` | Per-task dispatch list. | | `list_execution_invocations` | – | `projectId`, optional `sprintId`, `taskId`, `type` | Filter MCP invocations. | +| `list_execution_invocation_messages` | – | `invocationId` | List messages for a specific execution invocation. | --- diff --git a/docs-web/developer/settings-reference.md b/docs-web/developer/settings-reference.md index 161695fd21..5bb88708fe 100644 --- a/docs-web/developer/settings-reference.md +++ b/docs-web/developer/settings-reference.md @@ -1,8 +1,8 @@ # Settings schema reference -This page enumerates every settings field, its type, default, range (if applicable), and the JSON path you would use with `manage_code_ux` → `settings` → `patch_*_setting`. +This page enumerates every settings field, its type, default, range (if applicable), and the JSON path you would use with `manage_settings` → `patch_*_setting`. -Settings are evaluated in cascade: **Defaults → System → Project → Sprint**. Higher-level fields override lower; unspecified fields inherit. +Settings are evaluated in cascade: **System → Project → Sprint** (with built-in defaults folded into System). Higher-level fields override lower; unspecified fields inherit. Effective settings API responses include a `sources` object mapping JSON paths to their originating scope (`system`, `project`, or `sprint`). ## Top-level structure @@ -222,9 +222,12 @@ Disabling a step is for debugging; in production, leave them all enabled. { "defaultBranch": "main", "featureBranchPrefix": "feature/codeux/", - "branchScheme": { /* DEFAULT_SPRINT_BRANCH_SCHEME */ }, + "sprintBranchScheme": "feature/sprint{sprint_id}-implementation", + "sprintKeyPrefix": "SPR", "githubMode": "REMOTE" | "LOCAL", - "deleteMergedBranches": true + "deleteMergedBranches": true, + "autoCreatePr": true, + "prDescription": { /* task and sprint PR template toggles */ } } ``` @@ -326,21 +329,42 @@ Emergency stop threshold (consecutive task-start failures). Override via env: `J ```jsonc // Set the Codex model to gpt-5.4 system-wide +// 1. First call (unconfirmed) - returns approvalRequired: true +{ "domain": "settings", "action": "patch_system_setting", + "payload": { "path": "aiProvider.providers.codex.model", "value": "gpt-5.4" } } + +// 2. Second call (confirmed) - executes if within 15 minutes and exact same payload { "domain": "settings", "action": "patch_system_setting", "payload": { "path": "aiProvider.providers.codex.model", "value": "gpt-5.4" }, "approval": { "confirmed": true } } // For one project, force WHEN_GREEN auto-merge +// 1. First call (unconfirmed) { "domain": "settings", "action": "patch_project_setting", "payload": { "projectId": "proj-1", "path": "ciIntelligence.featurePrAutoMergeMode", "value": "WHEN_GREEN" } } +// 2. Second call (confirmed) +{ "domain": "settings", "action": "patch_project_setting", + "payload": { "projectId": "proj-1", "path": "ciIntelligence.featurePrAutoMergeMode", "value": "WHEN_GREEN" }, + "approval": { "confirmed": true } } + // For one sprint, route planning to Claude Opus +// 1. First call (unconfirmed) { "domain": "settings", "action": "patch_sprint_setting", "payload": { "projectId": "proj-1", "sprintId": "spr-3", "path": "aiProvider.routing.planning", "value": { "providerConfigId": "claude-code", "profile": "GLOBAL" } } } + +// 2. Second call (confirmed) +{ "domain": "settings", "action": "patch_sprint_setting", + "payload": { + "projectId": "proj-1", "sprintId": "spr-3", + "path": "aiProvider.routing.planning", + "value": { "providerConfigId": "claude-code", "profile": "GLOBAL" } + }, + "approval": { "confirmed": true } } ``` ## Validation diff --git a/docs-web/developer/testing.md b/docs-web/developer/testing.md index c0a39581b8..5f5fcce482 100644 --- a/docs-web/developer/testing.md +++ b/docs-web/developer/testing.md @@ -17,13 +17,13 @@ The Vitest config is at `vitest.config.ts`. Test environment is **Node** (not js ## Running tests ```bash -pnpm test # full suite, single run +pnpm run test # full suite, single run pnpm run test:watch # watch mode pnpm run test:backend # backend only pnpm run test:dashboard # dashboard only pnpm run test:coverage # full coverage with thresholds pnpm run test:backend:coverage # backend coverage with thresholds -pnpm test -- tests/backend/smoke.test.ts # single file +npx vitest run tests/backend/smoke.test.ts # single file ``` ## Coverage thresholds @@ -32,16 +32,16 @@ Enforced in CI: | Metric | Threshold | | --- | --- | -| Lines | **80%** | -| Functions | **69%** | -| Branches | **64%** | -| Statements | **80%** | +| Lines | **77.4%** | +| Functions | **71.5%** | +| Branches | **66.1%** | +| Statements | **76.0%** | Per-file gate: | File | Min line coverage | | --- | --- | -| `src/services/activity-cache-service.ts` | 80% | +| `src/server/activity-cache-service.ts` | 80% | A failing threshold fails CI. @@ -82,12 +82,7 @@ pnpm run ci This runs (in order): -1. `pnpm run quality:guardrails` -2. `pnpm run audit` -3. `pnpm run lint` — typecheck. -4. `pnpm run test:backend:coverage` — backend tests + coverage threshold. -5. `pnpm run test:dashboard` — dashboard tests. -6. `pnpm run build` — server + dashboard build. +`quality:guardrails -> audit -> lint -> test:backend:coverage -> test:dashboard -> build` If `pnpm run ci` is green, GitHub CI will be too (modulo platform-specific differences). diff --git a/docs-web/developer/websocket-realtime.md b/docs-web/developer/websocket-realtime.md index 7649bfb918..8f3ce0e78b 100644 --- a/docs-web/developer/websocket-realtime.md +++ b/docs-web/developer/websocket-realtime.md @@ -46,7 +46,7 @@ The server emits `ping` periodically (default 30 s); the client should reply wit | `project:` | Project metadata, settings effective values, attention items. | | `project::sprints` | Sprint list and status changes. | | `project::tasks` | Task status changes. | -| `project::execution` | Live cycle events for the active sprint run. | +| `project::execution` | Live cycle events (lean execution snapshots without heavy invocation feeds) for the active sprint run. | | `project::memory` | Memory adds / updates / promotions. | | `project::connections` | MCP connection list and presence. | | `project::conversations` | Chat thread updates. | diff --git a/docs-web/index.md b/docs-web/index.md index 127489b5d3..8bb274035a 100644 --- a/docs-web/index.md +++ b/docs-web/index.md @@ -2,7 +2,7 @@ > **Code UX** is a local-first, container-first multi-provider runtime. It turns a goal into a > managed sprint — planned, routed to the right agent, executed in isolated Docker workspaces, -> reviewed through Git and CI, and tracked in a live local dashboard — across hosted providers (like Jules) +> reviewed through Git and CI, and tracked in a live local dashboard — across hosted providers (like Code UX) > and local CLI/Docker providers (like Gemini, Codex, Claude Code, Qwen Code, OpenCode, and Antigravity). This site is the public publication and reference mirror for installing, operating, integrating, and extending Code UX. Canonical docs live in `docs/`. diff --git a/docs-web/user/automation-and-ci.md b/docs-web/user/automation-and-ci.md index 047a45294f..1ef9e05490 100644 --- a/docs-web/user/automation-and-ci.md +++ b/docs-web/user/automation-and-ci.md @@ -52,7 +52,7 @@ The `ciIntelligence` block (Settings → CI & Merge) controls how Code UX intera | Field | Default | Notes | | --- | --- | --- | | `waitForJulesCiAutofix` | `false` | If true, dispatch a `VirtualWorkerService` doing `ci_fix` tasks on failing CI. | -| `julesCiAutofixMaxRetries` | `3` (max `20`) | Max attempts before escalating. | +| `julesCiAutofixMaxRetries` | `3` (max `20`) | Max CI autofix attempts before escalation to human intervention. | ### Auto-merge modes diff --git a/docs-web/user/dashboard/agents.md b/docs-web/user/dashboard/agents.md index aa2bed019c..c3648a6190 100644 --- a/docs-web/user/dashboard/agents.md +++ b/docs-web/user/dashboard/agents.md @@ -28,10 +28,12 @@ Each preset is a card with avatar, name, label tags, and a one-line description. Click **+ New agent**. The form collects: - **Name** — required, unique within the project. -- **System instructions (markdown)** — the persona prompt. This is *appended* to a base preface that ensures the agent knows it operates inside Code UX. -- **Memory template override** — checkbox. When enabled, you can write a custom template that controls how `` and `` blocks render. Otherwise the project default is used. +- **System instructions (markdown)** — the persona prompt. This is *appended* to a base preface that ensures the agent knows it operates inside Code UX. You can also include reusable Instruction Files. +- **Memory template override** — checkbox. When enabled, you can write a custom template that controls how `` and `` blocks render via `Manage Memory`. Otherwise the project default is used. +- **Knowledge Base** — Subscribe the agent to documents from the shared library. +- **MCP Access** — Manage the agent's MCP tools access. - **Labels** — comma-separated tags (e.g. `planner`, `reviewer`, `migrator`). -- **Avatar** — auto-generated (geometric/colour seed). Click **Re-roll** to regenerate. +- **Avatar** — auto-generated (geometric/colour seed). You can customize it deeply using the avatar customizer. Save creates the preset and broadcasts a real-time event so connected clients refresh. @@ -61,6 +63,10 @@ This makes agent presets first-class repository content — you can check them i Destructive. Requires confirmation. Threads and tasks that referenced the deleted preset fall back to the project default agent. +## Instruction Files + +Instruction files are separate markdown documents that act as reusable prompt components. You can manage them with the Instruction Files editor and include them inside agent instructions. + ## Routing presets to invocation types Where Code UX *uses* a preset is governed by the **invocation routing** settings (Settings → Routing). For each routing ID you can specify which provider config and (optionally) which agent preset is used: diff --git a/docs-web/user/dashboard/browser-preview.md b/docs-web/user/dashboard/browser-preview.md index 17dc420196..1e88527f0d 100644 --- a/docs-web/user/dashboard/browser-preview.md +++ b/docs-web/user/dashboard/browser-preview.md @@ -10,20 +10,20 @@ This is invaluable for visually verifying changes a sprint has made (UI work, AP | --- | --- | | **Preview session** | A live Docker container running the sprint's working tree, plus a browser pane that connects to a chosen port inside it. | | **Preview script** | A shell script associated with the sprint that the container runs at startup (`npm run dev`, `python manage.py runserver`, etc.). | -| **Port mapping** | The container's internal port → host port mapping that the browser pane uses. | +| **Port mapping** | The container's internal port → host port mapping that the browser pane uses. A single preview container can expose multiple port mappings, rendered as distinct tabs in the browser chrome. | ## Starting a preview 1. Open the **Browser** page. -2. Pick a sprint from the dropdown. +2. Pick a sprint from the dropdown. Note that sessions are scoped strictly to one sprint per project. 3. Click **Launch container**. 4. If no preview script exists yet, the **Preview script editor** opens. Write the startup script (defaults provided per language). 5. Save and click **Start**. Code UX: - Builds a container image based on `node:24-bookworm` (or your override). - Exports the sprint branch snapshot into preview runtime storage and mounts it into the container. - Runs the script. - - Maps the configured port to a host port. -6. The browser pane appears. Logs stream in a side panel. + - Maps the configured container ports to explicit local host ports under `127.0.0.1`. +6. The browser pane appears. Logs stream in a side panel and are retained even if the container is stopped. ## Using the browser pane @@ -48,7 +48,7 @@ The **PreviewSessionSlider** at the top of the page shows all sessions currently ## Editing the preview script -The script lives in the project's `.code-ux/sprints/sprint-/preview.sh`. Editing it via the dashboard saves directly to that file, so the script is portable across teammates. +The script can be customized directly through the Browser page and saves to the project's runtime or the sprint snapshot. Editing it via the dashboard saves it using the `update_script` API/MCP tool so it applies directly to the specific sprint workspace. ## Quotas @@ -56,4 +56,4 @@ The page shows the count of running preview containers. Code UX does not enforce ## Programmatic control -The MCP `preview` management domain provides equivalent controls — `list_sessions`, `start_session`, `rebuild_session`, `stop_session`, `remove_session`, `get_script`. See [Management actions → preview](../../developer/management-actions.md#preview). +The MCP `preview` management domain provides equivalent controls — `list_sessions`, `start_session`, `rebuild_session`, `stop_session`, `remove_session`, `get_script`, `update_script`. See [Management actions → preview](../../developer/management-actions.md#preview). diff --git a/docs-web/user/dashboard/chat.md b/docs-web/user/dashboard/chat.md index 625a0de746..2f3a6a1f75 100644 --- a/docs-web/user/dashboard/chat.md +++ b/docs-web/user/dashboard/chat.md @@ -23,7 +23,7 @@ To rename a thread, use the edit control beside the active thread title. The inl To start a new thread, click **+ New thread**. To change the responding agent, open the thread header dropdown and pick from the list of agent presets defined for this project. -Each post triggers a routed invocation: the dashboard records the request, dispatches it to the chosen provider via the worker assignment service (routed through the `dashboard_reply` invocation type), and streams the reply back into the thread. +Each post is a runtime operation that honors the explicit route chosen (worker route, virtual provider route, automatic live-worker pickup, or fallback). The dashboard exposes in-flight state locally, allowing you to cancel active thread turns or invocations. Failed invocation restarts preserve the failed invocation transcript and expose the existing sanitized error message with a retry action. In 3D Chat, idle quick actions send project-scoped prompts directly through the active thread. **Web App** and **Desktop App** set up the currently selected project using its current techstack setting; an unassigned existing project stays `None`. They do not create or import a new Code UX project. @@ -46,7 +46,7 @@ The **Invocations** tab is a structured log of every `CallTool` MCP invocation r - **Timing** — start, end, duration. - **Linked task / sprint** — when an invocation arose from sprint orchestration. -Use this for debugging your MCP client integrations — for example to see exactly what arguments your LLM is passing to tools like `manage_memory` or `manage_settings` (Note: The legacy unified `manage_code_ux` tool is deprecated). +Use this for debugging your MCP client integrations — for example to see exactly what arguments your LLM is passing to tools like `manage_memory` or `manage_settings`. Invocation transcripts use the same live sprint status card as thread messages when planning metadata links them to a sprint. This means a planning invocation and its related chat message should show consistent task progress without a separate refresh control. @@ -58,4 +58,4 @@ The composer at the bottom supports: - **Slash commands** that invoke management actions inline. - **Attachments** *(planned)*. -The active thread can be deleted from the **⋯** menu. Deletion is local (the underlying provider session is closed) and does not affect sprints or tasks. +The active thread can be deleted from the **⋯** menu. Deletion is local (the underlying provider session is closed) and does not affect sprints or tasks. You can also cancel the currently running turn for a specific thread, which aborts only the matching in-flight thread turn. diff --git a/docs-web/user/dashboard/file-browser.md b/docs-web/user/dashboard/file-browser.md index 25ebe00ca1..0c0aa68a31 100644 --- a/docs-web/user/dashboard/file-browser.md +++ b/docs-web/user/dashboard/file-browser.md @@ -16,7 +16,11 @@ sprint is producing. A session has a status: | **Error** | The session failed to start or crashed. | You can **start**, **stop**, **rebuild**, and **remove** sessions, and pick which sprint to launch a -session for. +session for. These correspond directly to the technical backend API routes: +- `/api/projects/:projectId/sprints/:sprintId/file-browser/start` +- `/api/file-browser/sessions/:sessionId/stop` +- `/api/file-browser/sessions/:sessionId/rebuild` +- `DELETE /api/file-browser/sessions/:sessionId` (remove) ## Files mode diff --git a/docs-web/user/dashboard/live-session.md b/docs-web/user/dashboard/live-session.md index 8c602e31d4..49201ff7be 100644 --- a/docs-web/user/dashboard/live-session.md +++ b/docs-web/user/dashboard/live-session.md @@ -14,10 +14,12 @@ The page is composed of stacked panels: - Live activity preview (the latest line of agent output). - Duration and ETA. - Buttons to stop, retry, or open the detail panel. -3. **Execution timeline** — A horizontal timeline of every event in the run: cycle starts, task transitions, PR opens, merges, attention items. -4. **Runtime event feed** — A streaming log of orchestrator events. -5. **Git CI status panel** — PR status table for the feature branch: open PRs, CI status, merge conflicts. -6. **Human intervention badge** — Pulses when a merge conflict, CI failure, or other attention item needs you. +3. **Live Session Runtime Sidebar** — Contains the following collapsible panels: + - **Invocation feed panel** — A real-time log of individual provider invocations with restart and cancel controls. + - **Execution timeline** — A horizontal timeline of every event in the run: cycle starts, task transitions, PR opens, merges, attention items. + - **Git CI status panel** — PR status table for the feature branch: open PRs, CI status, merge conflicts. + - **Attention ledger** — A dedicated queue for managing human-intervention attention items. + - **Execution runtime panel** — Core runtime metrics, build statuses, and summary badges. ## Real-time updates @@ -31,13 +33,14 @@ If the project has no active sprint run, the page shows the **Idle Runtime State ## Attention items -When the engine cannot proceed without input, an attention item is created. It appears as a card in the live session view with: +When the engine cannot proceed without input, an attention item is created. It appears as a row in the **Attention ledger** sidebar panel with: - Category — `merge_conflict`, `ci_failure`, `action_required`, `qa_review_failed`. - Linked task and PR. - Recommended action. - **Claim** button — Mark that you (or a virtual worker) are working on it. - **Resolve** button — Mark it resolved; the engine will reattempt the cycle. +- **Dismiss** button — Clear the item from the queue when it is no longer relevant. A virtual worker can claim an attention item too. If you have configured `virtualWorkerProvider` in settings, the engine will offer eligible items to a worker before showing them to you. @@ -50,6 +53,13 @@ Two large buttons in the page header: A **Force cancel** option is hidden behind a confirm dialog. +### Invocation restart/cancel + +Individual provider invocations can be managed directly from the **Invocation feed panel** in the sidebar: +- **Cancel** — Stops a running provider invocation. +- **Restart / Continue** — Restarts a failed planning invocation or continues a disconnected session. +- **Reset timer** — Resets the rate-limit timeout for a quota-blocked invocation. + ## Finalisation When all tasks settle, the watch loop runs the *finalisation step*: diff --git a/docs-web/user/dashboard/memory.md b/docs-web/user/dashboard/memory.md index 259649d9f3..e8d185e65d 100644 --- a/docs-web/user/dashboard/memory.md +++ b/docs-web/user/dashboard/memory.md @@ -107,4 +107,4 @@ The footer shows aggregate memory statistics: total counts per scope/category, a ## Programmatic access -The Memory MCP tool (`manage_memory`) exposes search, list, get, create, update, delete, promote, start_reembed, get_map, count, and model_status actions, as well as durable claim actions. Destructive actions require approval confirmation. (Note: The legacy unified `manage_code_ux` tool is deprecated). See [Management actions → memory](../../developer/management-actions.md#memory). +The Memory MCP tool (`manage_memory`) exposes search, list, get, create, update, delete, promote, start_reembed, get_map, count, and model_status actions, as well as durable claim actions. Destructive actions require approval confirmation. See [Management actions → memory](../../developer/management-actions.md#memory). diff --git a/docs-web/user/dashboard/overview.md b/docs-web/user/dashboard/overview.md index 57ad1d4d6a..6a6a93d8c8 100644 --- a/docs-web/user/dashboard/overview.md +++ b/docs-web/user/dashboard/overview.md @@ -2,7 +2,7 @@ The Code UX dashboard is a real-time Preact application served at `http://localhost:4444` (configurable with `DASHBOARD_PORT`). It is the primary interface for humans operating Code UX. -This page introduces the layout. Each subsection links to a dedicated page. +This page mirrors the canonical dashboard guide and the active v2 page files, where v2 is the active UI backed directly by `dashboard/src/v2/*Page.tsx`. Each subsection links to a dedicated page. ## Layout @@ -39,7 +39,7 @@ The background is an animated Three.js scene ("Deep Ocean") that lazy-loads afte ## Real-time data -The dashboard maintains a live connection to the server using a custom WebSocket protocol at `wss://localhost:4444/api/realtime`. The connection: +The dashboard maintains a live connection to the server using a custom WebSocket protocol via `GET /api/realtime` (e.g., `ws://localhost:4444/api/realtime` for local HTTP dashboards, and `wss:///api/realtime` for HTTPS deployments). On the server side, `DashboardRealtimeService` in `src/services/dashboard-realtime-service.ts` coordinates events, and the websocket upgrade/transport is handled in `src/server/dashboard-realtime-websocket-server.ts`. The connection: - Subscribes to *scopes* (e.g. `project:`, `execution`, `git-status`). - Receives push events for sprint/task transitions, attention items, memory updates, Git status changes. diff --git a/docs-web/user/dashboard/projects.md b/docs-web/user/dashboard/projects.md index 89d57f608a..9fe3d1f039 100644 --- a/docs-web/user/dashboard/projects.md +++ b/docs-web/user/dashboard/projects.md @@ -55,7 +55,7 @@ Click the card's **Open** action to make it the active project, or use the **Set ## Deleting a project -Deletion is destructive — it removes the project's database row and runtime state, but **does not** delete files inside `/.code-ux/`. The MCP `manage_code_ux` action requires explicit `approval.confirmed = true`. +Deletion is destructive — it removes the project's database row and runtime state, but **does not** delete files inside `/.code-ux/`. The MCP `manage_projects` action requires explicit `approval.confirmed = true`. In the dashboard, the **Delete** action shows a confirm dialog with the count of sprints, tasks and memories that will become orphaned. diff --git a/docs-web/user/dashboard/sprints.md b/docs-web/user/dashboard/sprints.md index ad953126d6..4671f502c6 100644 --- a/docs-web/user/dashboard/sprints.md +++ b/docs-web/user/dashboard/sprints.md @@ -2,16 +2,16 @@ The **Sprints** page (`/sprints`) is where you plan, manage, and launch sprint runs. -## The sprint board +## The sprint gallery and ledger -Each sprint is rendered as a *bubble* showing: +Sprints are viewed either in a visual organic cell gallery or a dense ledger format. Each sprint cell/row shows: - **Status pill** — `idle`, `running`, `paused`, `completed`, `failed`, `cancelled`. - **Task counters** — completed / total, plus failures. - **Goal** — first line of the sprint goal. - **Action buttons** — Plan / Orchestrate / Pause / Cancel as appropriate. -Sprints can be **showcase-pinned** to surface them on the Overview page; toggle this from the bubble menu. +Sprints can be **showcase-pinned** to surface them on the Overview page; toggle this from the cell menu or bulk actions. ## Creating a sprint @@ -68,16 +68,17 @@ You can run any sprint multiple times. Each run has its own ID and its own row i - **Cancel** — The sprint enters `cancel_requested` and is cancelled gracefully. Active dispatches are signalled to stop. - **Force cancel** — Skips graceful steps. Use only if a normal cancel hangs. -Pausing / cancelling are also exposed as MCP actions (`manage_code_ux` → domain `sprints` → actions `pause`, `cancel`, `force_cancel`). +Pausing / cancelling are also exposed as MCP actions via the `manage_sprints` tool (actions `pause`, `cancel`, `force_cancel`). ## Importing & exporting sprints -Sprints are portable as Markdown bundles: +Sprints support importing issues directly from external providers, as well as being portable as Markdown bundles: +- **Issue Import** — Click **+ → Import** and choose **GitHub Issues**, **GitLab Issues**, or **Jira Issues**. You can search by text, labels, status, assignees, or exact issue keys (e.g., `#42` or `OPS-42`). Imported issues are attached as linked contexts, and Jira issues can optionally be converted directly into security or quality tasks. Code UX attempts to auto-transition or auto-close linked issues when the sprint completes. - **Export** — Click **⋯ → Export markdown**. You receive a downloadable bundle: one file per subtask plus a `sprint.md` describing the sprint. -- **Import** — Click **+ → Import**. Drop a previously exported bundle (or a hand-written one). Code UX validates and creates the sprint. +- **Import Bundle** — Click **+ → Import**. Drop a previously exported bundle (or a hand-written one). Code UX validates and creates the sprint. -Importing is the recommended way to template sprints across projects when [Quicksprints](../quicksprints.md) are not flexible enough. +Importing bundles is the recommended way to template sprints across projects when [Quicksprints](../quicksprints.md) are not flexible enough. ## Sprint settings overrides @@ -89,6 +90,8 @@ Each sprint can override project settings, which in turn override system setting Effective settings are inspectable at `GET /api/projects/:projectId/sprints/:sprintId/settings/effective`. -## Sprint deletion +## Sprint deletion and bulk actions -Deleting a sprint requires explicit confirmation and removes its database state but leaves the on-disk markdown directory intact (so you can re-import later if you change your mind). +The Sprints ledger supports multi-select for bulk starting, pinning, or deleting sprints. + +Deleting a sprint (single or bulk) requires explicit confirmation in a destructive dialog and removes its database state but leaves the on-disk markdown directory intact (so you can re-import later if you change your mind). diff --git a/docs-web/user/quicksprints.md b/docs-web/user/quicksprints.md index 3c2f06652c..84e3267efd 100644 --- a/docs-web/user/quicksprints.md +++ b/docs-web/user/quicksprints.md @@ -6,7 +6,7 @@ Use them when a particular shape of sprint recurs — e.g. *"add a CRUD endpoint ## Where they live -Quicksprint templates are scoped to a **project**. They are stored in the database and (optionally) mirrored on disk under `/.quicksprints/.md`. +Quicksprint templates are scoped to a **project**. They are stored in the database and mirrored on disk under `/.code-ux/quicksprints/templates/.md`. The dashboard surface for them is the **Quicksprint panel** on the **Sprints** page. @@ -16,31 +16,26 @@ A template has: - **Name** — A short label. - **Description** — One-line summary shown on cards. -- **Prompt template** — The sprint prompt body. May contain `{{placeholder}}` slots for runtime substitution. -- **Default sprint name template** — Used when generating the sprint name from a single execution. -- **Variables** — A typed list of placeholders the user fills before execution. -- **Tags** — Used for filtering on the panel. +- **Icon** — An icon identifier. +- **Category** — Used for grouping/filtering. +- **Category Color** *(optional)* — Color code for the category badge. +- **Agent Instructions** — The sprint prompt body. +- **Default Task Count** *(optional)* — The default number of subtasks to generate. ## Creating a template -From the Quicksprint panel, click **+ New template**. The editor lets you write the prompt body and define variables. Each variable has: - -- `key` (matches `{{key}}` in the prompt). -- `label` (UI label). -- `type` — `text`, `multiline`, `select`. -- `default` — pre-filled value. -- `options` — for `select` type. +From the Quicksprint panel, click **+ New template**. The editor lets you write the prompt body and define the metadata (Name, Description, Icon, Category, Default Task Count). Save persists the template and broadcasts a real-time event. ## Executing a template -Click any template card. A modal opens prompting for variable values. On **Run**: +Click any template card. A sidebar opens where you can configure the run: -1. Code UX substitutes `{{key}}` placeholders with your values. -2. Creates a new sprint in the active project. -3. Plans the sprint via the planning agent (using the substituted prompt). -4. Optionally orchestrates immediately (toggle in the modal). +1. Code UX prepares to plan the sprint. +2. You can override the model, or route. +3. You can use the slider to choose the number of subtasks (up to 30), or toggle **No limit** to let the planner decide. +4. Click **Plan & Start** to immediately orchestrate after planning, or **Plan Only** to review the plan first. The resulting sprint is identical to one created manually — you can edit subtasks before running. @@ -48,8 +43,8 @@ The resulting sprint is identical to one created manually — you can edit subta From the **⋯** menu on a template card: -- **Edit** — Update name, description, prompt, variables. -- **Delete** — Destructive; confirm to remove. +- **Edit** — Update name, description, instructions, category, icon, etc. +- **Delete** — Destructive; confirm to remove. Deleting a built-in template writes a local tombstone marker so it's hidden for the project. ## REST API @@ -67,24 +62,22 @@ From the **⋯** menu on a template card: ### "Add CRUD endpoint" template ```text -Add a complete CRUD endpoint for the `{{model}}` model. +Add a complete CRUD endpoint for the specified model. Requirements: -- POST /api/{{model_plural}} — create -- GET /api/{{model_plural}} — list (paginated) -- GET /api/{{model_plural}}/:id — read -- PATCH /api/{{model_plural}}/:id — update -- DELETE /api/{{model_plural}}/:id — delete (soft, unless {{soft_delete}} is "no") +- POST /api/models — create +- GET /api/models — list (paginated) +- GET /api/models/:id — read +- PATCH /api/models/:id — update +- DELETE /api/models/:id — delete Include input validation, integration tests, and an OpenAPI snippet. ``` -Variables: `model`, `model_plural`, `soft_delete` (select: yes/no). - ### "Dependency upgrade" template ```text -Upgrade `{{package}}` from {{from_version}} to {{to_version}}. +Upgrade the specified package. Steps: - Bump version in package.json / requirements.txt / equivalent. @@ -95,10 +88,7 @@ Steps: - Document the upgrade in CHANGELOG.md. ``` -Variables: `package`, `from_version`, `to_version`. - ## Tips - Keep templates short and prescriptive. The planner agent will produce better subtasks from a focused prompt. -- Use `multiline` variables for free-form context (linked tickets, design docs). -- Tag templates so you can filter "build" vs "maintenance" vs "investigation". +- Tag templates so you can filter them. diff --git a/docs-web/user/sprint-orchestration.md b/docs-web/user/sprint-orchestration.md index 71a8bf174a..8c0a4efc05 100644 --- a/docs-web/user/sprint-orchestration.md +++ b/docs-web/user/sprint-orchestration.md @@ -26,9 +26,8 @@ A single orchestration *cycle* runs the following pipeline (each step is indepen 4. **sessionSync** — Synchronize the latest state of every active provider invocation (hosted and CLI providers). 5. **statusDerivation** — Apply state rules to derive each subtask's effective status (`PENDING`, `RUNNING`, `CODING_COMPLETED`, `COMPLETED`, etc.). 6. **startReadyTasks** — Find subtasks whose dependencies are met and start a new worker session for each. Concurrency is capped per provider via `maxConcurrentTasks`. -7. **mergeProtocol** — Run the [CI gate](./automation-and-ci.md): create PRs, watch CI, auto-merge per policy, surface attention items for conflicts and CI failures. -8. **actionRequiredProtocol** — Auto-handle plan approvals, clarification answers, paused sessions per `automationInterventions` settings. -9. **statusTable** — Render the cycle report. +7. **protocol** — Run the [CI gate](./automation-and-ci.md): create PRs, watch CI, evaluate QA, auto-merge per policy, surface attention items for conflicts and CI failures. Also handles action-required automation for plan approvals, clarification answers, and paused sessions. +8. **statusTable** — Render the cycle report. Each step is independently catchable; a failure in one step does not crash the cycle. Errors are logged and surface as attention items. @@ -81,12 +80,14 @@ PENDING ──start──► RUNNING ──finish──► CODING_COMPLETED ─ ├──fail──► FAILED ──retry┤ ├──quota──► QUOTA ──next cycle┤ ├──QA reject──► QA_REVIEW_FAILED + ├──QA pass──► (proceeds to CI/merge gate) └──blocked deps──► BLOCKED ``` Detailed transitions: -- **CODING_COMPLETED → COMPLETED** when the merge protocol confirms `is_merged: true` or a settled merge indicator (`MERGED`, `AUTOMERGE`, `PR_ONLY`). +- **CODING_COMPLETED → COMPLETED** when the protocol confirms `is_merged: true` or a settled merge indicator (`MERGED`, `AUTOMERGE`, `PR_ONLY`) after any configured QA reviews pass. +- **CODING_COMPLETED → QA_REVIEW_FAILED** if QA review finds issues and the retry budget is exhausted. - **COMPLETED → CODING_COMPLETED** if `is_merged` is false but there is merge evidence (an open PR or a worker branch). This is a temporary "awaiting merge" state. - **FAILED**: retried in a new session if `retryFailed: true` (default). - **QUOTA**: retried next cycle automatically. @@ -181,8 +182,8 @@ Every UI action has an MCP equivalent: | UI action | MCP call | | --- | --- | -| Plan a sprint | `manage_code_ux` → `domain: "sprints"` (planning is internal during start) or use planning REST API | -| Orchestrate | `manage_code_ux` → `domain: "sprints", action: "start"` | +| Plan a sprint | `manage_sprints` (planning is internal during start) or use planning REST API | +| Orchestrate | `manage_sprints` → `action: "start"` | | Pause | `domain: "sprints", action: "pause"` | | Cancel | `domain: "sprints", action: "cancel"` (or `force_cancel`) | | Inspect run | `domain: "sprints", action: "inspect_run"` | diff --git a/docs/README.md b/docs/README.md index a1bd3b1fd9..8ac13be61a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -6,4 +6,4 @@ Start here: Structured table of contents: - [Summary](./SUMMARY.md) -**Note:** Canonical docs live in `docs/`. The `docs-web/` directory serves as the only publication and reference mirror. +**Note:** Canonical docs live in `docs/` as the single source of truth. The `docs-web/` directory serves as the only publication and reference mirror. A `docs-release/` directory should not be created or used. diff --git a/docs/architecture/agent-sync-and-planning-agent.md b/docs/architecture/agent-sync-and-planning-agent.md index 09c46730eb..91515faf5c 100644 --- a/docs/architecture/agent-sync-and-planning-agent.md +++ b/docs/architecture/agent-sync-and-planning-agent.md @@ -58,7 +58,7 @@ That means: - when project markdown mirroring is enabled, dashboard create/update writes the agent body into a project-local markdown file - mirrored project files use a filesystem-safe slug format such as `planning_agent.md` - editing a default or home-backed agent from the dashboard creates a project-local override file instead of modifying the default/home source -- if the linked markdown file later differs from the DB copy, the agent is marked `out_of_sync` +- if the linked markdown file later differs from the DB copy (including changes to memory settings, avatar config, or provider/model preferences), the agent is marked `out_of_sync` - the dashboard can re-import one agent or bulk-sync all out-of-sync project agents back into sqlite on demand - the dashboard can push `.code-ux/agents/*.md` back into git, either as a local commit, a commit plus branch push, or a feature-branch pull request into the default branch - when opening a pull request, Code UX resolves the effective dashboard GitHub/GitLab host tokens and forwards them to the PR service so repository-host authentication stays aligned with the current project settings @@ -95,7 +95,7 @@ The API record also exposes derived sync state: - `manual` - `synced` -- `out_of_sync` +- `out_of_sync` (triggers when name, description, markdown, avatar config, provider, model, or memory config differs between the DB and the file) - `missing_source` When markdown does not include `avatarConfig`, Code UX still persists a resolved avatar before writing sqlite. Built-in base roles use curated defaults, while generated or custom project agents receive a deterministic random look seeded from project, agent, and label metadata. Project Setup Agent output goes through the same resolver, so generated specialist agents get a stable avatar that is mirrored into project markdown instead of being recalculated on every dashboard load. diff --git a/docs/architecture/dashboard-realtime-foundation.md b/docs/architecture/dashboard-realtime-foundation.md index 55310df728..bfc0ed0bba 100644 --- a/docs/architecture/dashboard-realtime-foundation.md +++ b/docs/architecture/dashboard-realtime-foundation.md @@ -41,7 +41,7 @@ Production refinement shipped on March 15, 2026: ### Coalescing realtime publisher -Code UX now coalesces runtime writes before broadcasting them. +Code UX now coalesces runtime writes before broadcasting them. This is implemented by `DashboardRealtimeService` (`src/services/dashboard-realtime-service.ts`). The internal architecture uses a single unified `buildPublishTask` helper for all these endpoints, which handles caching, deduplication, payload fingerprinting, logging, and throttle semantics. @@ -97,7 +97,7 @@ July 5, 2026 helper contract: The dashboard server now exposes: -- `GET /api/realtime` +- `GET /api/realtime` (served by `bootDashboardRealtimeWebSocketServer` in `src/server/dashboard-realtime-websocket-server.ts` and wired from `src/server/dashboard-server.ts`) The protocol is intentionally small: @@ -165,7 +165,7 @@ Realtime refresh scheduling is currently wired from: - `src/repositories/connection-chat-repository.ts` - `src/repositories/project-attention-repository.ts` -That means the browser is refreshed when execution state or live connection state changes in the DB-native runtime path. +These repositories explicitly hand off mutation notifications to `DashboardRealtimeService`, which then broadcasts through the websocket server. That means the browser is refreshed when execution state or live connection state changes in the DB-native runtime path. The publisher intentionally ignores heartbeat-only execution writes where possible to avoid noisy event spam. diff --git a/docs/architecture/dashboard-resource-layer.md b/docs/architecture/dashboard-resource-layer.md index ec298ff94e..ddc79e2fc6 100644 --- a/docs/architecture/dashboard-resource-layer.md +++ b/docs/architecture/dashboard-resource-layer.md @@ -30,7 +30,7 @@ Data fetching is governed by a unified resource layer rather than ad-hoc `useEff - Project status is dynamically derived from `has_active_runs` (active/queued sprint runs or sprints with status `'running'`). If a project has no active runs, its status is mapped to `"idle"` even if the database status column is stale (e.g. from crashed processes or sprint deletions). - Sprints only show as `"running"` if their latest sprint run status is `"queued"` or `"running"`. If a sprint run is completed, failed, cancelled, or does not exist, the effective sprint status falls back to `"idle"`. - Header telemetry metrics (`TelemetryStats`) filter task counts to only include running and queued tasks belonging to actively running sprints, and they skip task loading entirely when no sprint is running. -- Cache invalidation is coordinated through realtime websocket events. +- Cache invalidation is coordinated through realtime websocket events. Repositories and runtime writes notify `DashboardRealtimeService` (`src/services/dashboard-realtime-service.ts`), which coalesces, fingerprints, schedules resource events, and appends sequence-backed realtime events. The `bootDashboardRealtimeWebSocketServer` function in `src/server/dashboard-realtime-websocket-server.ts` delivers those events over `/api/realtime`. Frontend resource hooks, such as `dashboard/src/hooks/use-realtime-resource.ts`, consume those events to invalidate or refresh resource keys. - Silent websocket/poll refreshes are deduplicated per resource, but a foreground refresh that supersedes an in-flight silent refresh must clear that silent dedupe handle. This prevents navigation or manual refresh from leaving future silent invalidations attached to an already-aborted request. Additionally, if a silent fetch is explicitly aborted, it will clear its own dedupe handle to avoid poisoning subsequent silent refreshes. External abort listeners attached to requests are properly cleaned up upon fetch completion to avoid memory leaks during rapid polling. - Direct websocket payload updates (where the event contains the full updated resource) are batched using `requestAnimationFrame`. This coalesces bursts of updates into at most one render per animation frame, preventing the main thread from saturating during high-frequency realtime events. - In-flight project-level requests are abort-safe: if a shared project-level request is aborted by its initial caller unmounting, subsequent callers automatically retry instead of inheriting a poisoned aborted promise. Cache entries are populated only from successful, non-aborted fetches. diff --git a/docs/architecture/git-stats-analytics.md b/docs/architecture/git-stats-analytics.md index aab45fffd9..8d10d5ff9b 100644 --- a/docs/architecture/git-stats-analytics.md +++ b/docs/architecture/git-stats-analytics.md @@ -32,7 +32,7 @@ When the frontend queries for Git analytics, the payload returned from `GET /api ## Analysis Studio Git Behavior -The dashboard incorporates these fields directly into the unified **Analysis Studio** on the Stats page (`/stats`). +The dashboard incorporates these fields directly into the unified **Analysis Studio** on the Stats page (`/stats`). The `useStatsPageData` hook coordinates the visual state and fetches the snapshot payload so Git analytics respects the same time windows and snapshot structures as standard token telemetry. - Git metrics are part of the embedded grouped metric selector, alongside the **Tokens** and **Time** groupings. - Changing the time window (e.g., from `7d` to `30d`) re-fetches the underlying snapshot and updates the Git metrics dynamically. diff --git a/docs/architecture/live-runtime-contract.md b/docs/architecture/live-runtime-contract.md index 31a01a2dc4..8b66f5239c 100644 --- a/docs/architecture/live-runtime-contract.md +++ b/docs/architecture/live-runtime-contract.md @@ -92,7 +92,7 @@ When the UI initiates an action (such as pausing a sprint, claiming an attention Live runtime panels preserve the last valid execution snapshot during recovery and stale-data windows. The transport banner distinguishes connection errors, disconnected transport, reconnecting transport, background refresh, first-snapshot recovery, and stale cached snapshots with visible titles, static status icons, `aria-live`, and `aria-busy` state. Assertive announcements are reserved for blocking errors and disconnected transport; stale data, background refresh, reconnecting, and first-snapshot recovery remain polite status updates. Reconnect and disconnect copy must explicitly say that cached runtime data remains visible when a cached snapshot exists. -Collapsible runtime panels keep their trigger focused, expose `aria-expanded` and `aria-controls`, and hide collapsed panel bodies from assistive technology with `aria-hidden` while the visual height collapses. Headers for connection panels, invocation feeds, attention queues, and execution runtime panels must retain visible summary counts while collapsed so operators can understand active, failed, open, claimed, or completed work without expanding the panel. Expansion/collapse and banner transitions use shared interaction token hooks so reduced-motion preferences resolve to instant state changes without hardcoded timing. +Collapsible runtime panels keep their trigger focused, expose `aria-expanded` and `aria-controls`, and hide collapsed panel bodies from assistive technology with `aria-hidden` while the visual height collapses. Headers for connection panels, invocation feeds (`InvocationFeedPanel` with invocation restart/cancel capabilities), attention queues (now the dedicated `AttentionLedger` sidebar component), and execution runtime panels must retain visible summary counts while collapsed so operators can understand active, failed, open, claimed, or completed work without expanding the panel. Note that `LiveConnectionsCard` is separated and no longer embedded directly into `ExecutionRuntimePanel`. Expansion/collapse and banner transitions use shared interaction token hooks so reduced-motion preferences resolve to instant state changes without hardcoded timing. Runtime action controls derive their pending display from dashboard view-model helpers. Pending controls keep focusable button semantics, expose `aria-disabled="true"` and `aria-busy="true"`, suppress duplicate activation, and include stable visible labels plus screen-reader status text for initiation and in-progress states. Disabled and pending buttons must expose a visible or described reason through persistent status text, `title`, or `aria-describedby`; they must not rely on click-time feedback from inert controls. Snapshot rows remain readable during background refresh; cached content is not hidden unless the execution snapshot is genuinely unavailable. diff --git a/docs/architecture/mcp-connections-and-listen-mode.md b/docs/architecture/mcp-connections-and-listen-mode.md index 8f523856bc..3e39e93c03 100644 --- a/docs/architecture/mcp-connections-and-listen-mode.md +++ b/docs/architecture/mcp-connections-and-listen-mode.md @@ -151,8 +151,10 @@ Transport notes: ## Current Routing Rules When a dashboard message is posted: -- if the thread already has a bound connection, the message stays with that connection -- otherwise the message remains queued and unassigned until a listener claims it or the dashboard explicitly targets a connection +- it honors an explicit thread-level worker route if the targeted worker is live +- otherwise it honors an explicit thread-level virtual provider route +- otherwise it falls back to automatic live-worker pickup +- finally it resolves the `dashboard_reply` invocation route When a dashboard thread is reassigned: - the thread's `connection_id` is updated explicitly diff --git a/docs/architecture/project-runtime-integration.md b/docs/architecture/project-runtime-integration.md index e8fc44b217..a17495d1cd 100644 --- a/docs/architecture/project-runtime-integration.md +++ b/docs/architecture/project-runtime-integration.md @@ -21,7 +21,7 @@ Key behavior: - orchestrator status updates are now mirrored into sqlite - selected-project live dashboard data is read back from sqlite - rerun actions can target DB task ids while still resetting markdown task state by task key -- git/CI tracking now resolves repo path and active branch from the selected project's stored runtime context +- git/CI tracking now resolves repo path and active branch from the selected project's stored runtime context, replacing tokens such as `{sprint_key_prefix}`, `{sprint_id}`, `{worker_provider}`, and `{worker_model}` ## Runtime Source Of Truth @@ -57,6 +57,9 @@ Legacy cleanup: - unscoped project-level runtime rows from the pre-multi-sprint bridge are treated as deprecated - explicit sprint reads and rerun flows now use sprint-scoped runtime only, so stale data from an old sprint cannot override the active sprint branch +Runtime cleanup: +- Dedicated cleanup paths (`RuntimeCleanupService`, `DockerRuntimePruneService`, `DockerAssetPruneService`) handle stale previews, orphaned containers, setup images, and workspace/runtime volumes, keeping execution state aligned with container assets. + ## Current Boundaries This is still a bridge layer, not the final runtime architecture. diff --git a/docs/architecture/quality-assurance-agent.md b/docs/architecture/quality-assurance-agent.md index c992da840e..ce6c6463ec 100644 --- a/docs/architecture/quality-assurance-agent.md +++ b/docs/architecture/quality-assurance-agent.md @@ -156,7 +156,7 @@ Task-level prompt scope: - QA must not tell the current coding session to implement, restore, or modify another task's scope - when task-level QA requests changes, `fixInstructions` must target the current task's coding session and `targetTaskKey` must identify that current task -If task QA is still pending, running, or has failed without exhausting `maxTaskReviewRuns`, Code UX marks the task merge state as `QA_PENDING` and keeps the sprint active instead of auto-merging. +If task QA is still pending, running, or has failed without exhausting `maxTaskReviewRuns`, Code UX marks the task merge state as `QA_PENDING` and keeps the sprint active instead of auto-merging. If QA is exhausted and configured to `ESCALATE_TO_HUMAN`, the task is held in `QA_REVIEW_FAILED` and will not be merged or marked complete until a human resolves it. Recovery guarantees: @@ -248,7 +248,7 @@ For CLI follow-up runs, Code UX: - refreshes `origin` and starts follow-up work from the latest remote feature branch when remote GitHub mode is enabled - resolves the expected resume workspace from `sessionId` plus CLI execution mode and recovers the current branch from that workspace when `task.worker_branch` and `taskRun.workerBranch` are empty - resets a reused task workspace to the latest remote worker branch when that branch already exists, so QA fixes build on the current task PR tip -- creates a missing local feature branch from `origin/` instead of recreating it from the default branch when the remote feature branch already exists +- creates a missing local feature branch from `origin/` instead of recreating it from the default branch when the remote tracking base branch exists, or falls back to resolving a repository default branch start point - resumes the worker branch - records the follow-up invocation in execution tracking - pushes/publishes any resulting PR updates when needed diff --git a/docs/architecture/repository-map.md b/docs/architecture/repository-map.md index a88b4b139f..41e86d758d 100644 --- a/docs/architecture/repository-map.md +++ b/docs/architecture/repository-map.md @@ -23,6 +23,11 @@ backup files appear there. - `index.ts` - Minimal bootstrap (`dotenv`, app config, server launch). +- `electron/` + - `main.ts` + - Desktop shell entrypoint and network policy, which hosts the Code UX UI without owning backend orchestration. +- `worker/` + - Headless execution role entrypoint for worker-host mode. - `config/` - `app-config.ts`, `external-settings.ts` - Startup/env config loading and external settings hints. @@ -37,7 +42,7 @@ backup files appear there. - Jules API HTTP client. - `server/` - `code-ux-server.ts` - - Main runtime composition and MCP server class. + - Main runtime composition wiring backend services (dashboard API on default port 4444 and MCP server). - `mcp-request-router.ts` - MCP list/call handler registration and dispatch routing. - `activity-cache-service.ts` diff --git a/docs/architecture/sprint-preview-browser.md b/docs/architecture/sprint-preview-browser.md index 3a685a2def..5b9f344e55 100644 --- a/docs/architecture/sprint-preview-browser.md +++ b/docs/architecture/sprint-preview-browser.md @@ -199,11 +199,15 @@ Preview endpoints are implemented in `src/server/dashboard-server.ts`. - `GET /api/projects/:projectId/preview/sessions` - `POST /api/projects/:projectId/sprints/:sprintId/preview/start` +- `POST /api/projects/:projectId/sprints/:sprintId/preview/sessions/:sessionId/rebuild` - `POST /api/browser/sessions/:sessionId/rebuild` +- `POST /api/projects/:projectId/sprints/:sprintId/preview/sessions/:sessionId/stop` - `POST /api/browser/sessions/:sessionId/stop` +- `DELETE /api/projects/:projectId/sprints/:sprintId/preview/sessions/:sessionId` - `DELETE /api/browser/sessions/:sessionId` - `GET /api/projects/:projectId/sprints/:sprintId/preview/script` - `PUT /api/projects/:projectId/sprints/:sprintId/preview/script` +- `GET /api/projects/:projectId/sprints/:sprintId/preview/sessions/:sessionId/logs` - `GET /api/browser/sessions/:sessionId/logs` - `ALL /api/browser/sessions/:sessionId/proxy/*` diff --git a/docs/architecture/system-overview.md b/docs/architecture/system-overview.md index 6559f7eebd..4d41863cc2 100644 --- a/docs/architecture/system-overview.md +++ b/docs/architecture/system-overview.md @@ -25,7 +25,7 @@ Code UX is a container-first multi-provider runtime with an integrated dashboard - Responsibilities: - Instantiate repositories, services, handlers, orchestrator. - Register MCP request handlers via `src/server/mcp-request-router.ts`. - - Start dashboard HTTP server. + - Start dashboard HTTP server (defaults to port 4444). - Start MCP stdio transport only for an attached MCP pipe/socket or explicit `CODE_UX_ENABLE_MCP_STDIO=1`; daemon stdin such as `/dev/null` keeps stdio disabled. - Serve cached dashboard live activity and git status via `src/server/activity-cache-service.ts`. - Dashboard dependency composition lives in `src/app/dependency-factory/dashboard-factory.ts`. When two dashboard services must be constructed before both concrete instances exist, the factory uses `LateBoundDependency` from `src/shared/late-bound-dependency.ts` and links it synchronously before returning dependencies. Consumers resolve these holders at action time so missing links fail with an explicit late-bound dependency error instead of placeholder objects or private-field mutation. @@ -76,7 +76,7 @@ Code UX is a container-first multi-provider runtime with an integrated dashboard ```mermaid flowchart TD - A[MCP Client] -->|stdio tool call| B[src/index.ts] + A[CLI/MCP Client] -->|launch / stdio| B[src/index.ts] B --> R[src/server/code-ux-server.ts] R --> C[src/mcp/core-tool-handler.ts] R --> D[src/mcp/agent-tool-handler.ts] @@ -97,7 +97,7 @@ flowchart TD ## High-Level Data Flow -1. MCP client sends tool call over stdio. +1. MCP client sends tool call (e.g., grouped tools like `manage_sprints:start`, rather than the deprecated `manage_code_ux`) over stdio. 2. Server dispatches tool to core or agent handler. 3. Handler invokes the DB-backed dispatch engine, inbox system, and provider execution layer. 4. Orchestrator runs atomic steps and updates `lastStatus`. diff --git a/docs/architecture/usage-telemetry-and-stats.md b/docs/architecture/usage-telemetry-and-stats.md index eb89f96158..c062a2e995 100644 --- a/docs/architecture/usage-telemetry-and-stats.md +++ b/docs/architecture/usage-telemetry-and-stats.md @@ -313,6 +313,8 @@ The page focuses on: This page is intentionally separate from the live execution view so the live dashboard can stay optimized for orchestration while the Stats page handles historical analysis. +The same telemetry bounds are also exposed through the `manage_telemetry` MCP tool, which mirrors the dashboard telemetry requests and allows programmatic inspection of execution snapshots, task dispatches, sprint runs, invocations, and individual execution invocation messages (via `list_execution_invocation_messages`). + ## Realtime And Refresh Project stats refresh on: diff --git a/docs/architecture/virtual-workers.md b/docs/architecture/virtual-workers.md index efc3027a19..f3d1554ffc 100644 --- a/docs/architecture/virtual-workers.md +++ b/docs/architecture/virtual-workers.md @@ -165,10 +165,10 @@ It deduplicates this project set and explicitly ignores all other projects in th Startup cleanup prunes orphaned `virtual_cli` endpoints from previous runs. -Startup cleanup also removes stale Code UX Docker assets through a background, label-filtered prune so server boot does not wait on full Docker daemon scans: +Startup cleanup also removes stale Code UX Docker assets through a background, label-filtered prune so server boot does not wait on full Docker daemon scans (managed via `DockerAssetPruneService`): -- stale labeled workspace/runtime volumes for finished, failed, unrecoverable, or outdated sessions -- orphaned labeled helper/login containers from previous runs, removing anonymous image-declared volumes with `docker rm -f -v` +- orphaned labeled helper/login containers and temp credential dirs from previous runs, removing anonymous image-declared volumes with `docker rm -f -v` +- stale labeled workspace volumes (`code-ux.workspace=true`) and paired runtime volumes (`code-ux.workspace-runtime=true`) for finished, failed, unrecoverable, or outdated sessions Cached setup-script Docker images are content-addressed by base image, setup script content, and setup-cache Dockerfile content. They are preserved across dashboard restarts and reused until one of those inputs changes or Docker no longer has the image. diff --git a/docs/dashboard/browser-preview.md b/docs/dashboard/browser-preview.md index 4c7811e4cc..f2623df2b5 100644 --- a/docs/dashboard/browser-preview.md +++ b/docs/dashboard/browser-preview.md @@ -33,7 +33,7 @@ The browser preview provides an integrated environment for interacting with runn - Session removal actions keep the card mounted while removal is pending, set `aria-busy` on the card and remove button, suppress duplicate removal, and describe the pending reason from the disabled control. - The active sessions menu opens predictably from hover, click, focus, `Enter`, `Space`, `ArrowDown`, and `ArrowUp`; supports `ArrowUp`/`ArrowDown`/`Home`/`End` within enabled menu items; and restores focus to the trigger after `Escape` or outside-click close. - File-browser trees and change lists should expose tree/listbox semantics, selected file state, loading/error/empty regions, and wrapping long paths so keyboard users do not need pointer hover to inspect files or diffs. -- Rebuild and stop track distinct pending actions. The active operation owns the button label, `aria-busy`, and status text; sibling controls are disabled with visible recovery text instead of relying on click-time announcements. +- Rebuild, stop, and remove track distinct pending actions. The active operation owns the button label, `aria-busy`, and status text; sibling controls are disabled with visible recovery text instead of relying on click-time announcements. Preview sessions are explicitly scoped per project/sprint pair. - Launch controls set `aria-busy` on both the launch region and launch button while a container is starting. The selected session iframe remains mounted during refresh/starting states when a previous frame exists; do not replace stale preview content with a blank loading placeholder unless no frame exists. - Launch pending state keeps the selected sprint value visible, explains the disabled select and launch controls through status text and control titles, and prevents duplicate launch submission until the start request settles. - Startup-script saving sets `aria-busy` on the save button and textarea and pauses editing until the save completes. Script save status is a polite live region connected through `aria-describedby`. @@ -62,6 +62,25 @@ The browser preview has two proxy paths with different credential rules: Both paths only route to loopback host ports recorded on the active preview session. The dashboard API proxy also removes `Set-Cookie`, CSP, CSP report-only, and `X-Frame-Options` response headers before writing the response on the dashboard origin. Preview-host HTML keeps iframe compatibility by stripping upstream document CSP and frame-blocking headers while allowing preview-origin app cookies to reach that preview host. +## File Browser Comparison + +The File Browser is a distinct dashboard surface and runtime capability separate from Browser Preview. While Browser Preview proxies live container ports to a dashboard iframe, the File Browser manages its own dedicated sessions to provide filesystem inspection and Git change reviews. + +File Browser sessions expose their own API routes: +- `/api/projects/:projectId/file-browser/sessions` (list sessions) +- `/api/projects/:projectId/sprints/:sprintId/file-browser/start` (launch session) +- `/api/file-browser/sessions/:sessionId/rebuild` (rebuild session) +- `/api/file-browser/sessions/:sessionId/stop` (stop session) +- `/api/file-browser/sessions/:sessionId` (DELETE to remove session) +- `/api/file-browser/sessions/:sessionId/tree` (fetch folder tree) +- `/api/file-browser/sessions/:sessionId/file` (fetch file content) +- `/api/file-browser/sessions/:sessionId/changes` (fetch Git status changes) +- `/api/file-browser/sessions/:sessionId/diff` (fetch Git diff) + +The UI provides two primary views: +- **Files mode**: Shows a complete workspace tree and syntax-highlighted file viewer. +- **Changes mode**: Shows a list of modified files in the sprint branch and a diff viewer. + ## Verification Notes For documentation-only updates, run `pnpm run lint` and: diff --git a/docs/dashboard/dashboard-guide.md b/docs/dashboard/dashboard-guide.md index 16bec4a991..d084c1e8e7 100644 --- a/docs/dashboard/dashboard-guide.md +++ b/docs/dashboard/dashboard-guide.md @@ -247,7 +247,7 @@ Legacy runtime: - Overview metric cards use the restored `StatsCard` visual system from the operational command surface: four responsive cards with ambient bottom sparklines, stable card height, and compact detail rows for cost, invocations, active sprint, queue health, and active time. ### Navigation -- Sidebar and dock navigation expose the primary routes in guided-tour order: Chat, Overview, Sprints, Tasks, Agents, Stats, Schedule (`/scheduler`), Memory, Knowledge (`/knowledge`), Browser, Files, Live, Docs (`/docs`), and Settings/Config. +- Sidebar and dock navigation expose the primary routes in guided-tour order: Chat, Overview, Sprints, Tasks, Agents, Stats, Schedule (`/scheduler`), Memory, Knowledge (`/knowledge`), Browser, Files (`/files`, providing project and sprint File Browser capabilities), Live, and Settings/Config. - The top-nav workspace search trigger uses a more opaque glass surface in light and dark mode so it stays readable against page content while preserving the existing blur treatment. - The notification panel announces refresh, mark-read, dismiss, and action outcomes through polite live regions. Refresh and mark-all-read controls expose pending state with `aria-busy`, disabled controls include visible reasons, and every repeated row action includes the notification title in its accessible name. - Notification rows include textual read/unread state in addition to the severity accent rail. Initial rows use the `listReveal` motion contract, read/dismiss compaction uses `listReorder`, and reduced-motion users receive immediate static state changes without transitional movement. diff --git a/docs/dashboard/design-system-overview.md b/docs/dashboard/design-system-overview.md index 5e6bca8b5b..f50adc2bda 100644 --- a/docs/dashboard/design-system-overview.md +++ b/docs/dashboard/design-system-overview.md @@ -3,7 +3,7 @@ This document outlines the architectural and stylistic guidelines for the Dashboard's primary Overview command surface. ## Goal -The overview page acts as a centralized "Polished Operational Command Surface." It is a dense, responsive workspace intended for real-time monitoring and routing, avoiding the loose, airy feel of a marketing landing page. +The overview page acts as a centralized "Polished Operational Command Surface." It is a dense, responsive workspace intended for real-time monitoring and routing, avoiding the loose, airy feel of a marketing landing page. The active UI runs on v2 pages (`/` Overview, `/projects`, `/sprints`, `/tasks`, `/agents`, `/stats`, `/scheduler`, `/memory`, `/knowledge`, `/browser`, `/files`, `/live`, `/chat`, and `/config`). ## Layout Hierarchy diff --git a/docs/dashboard/design-system-shell-navigation.md b/docs/dashboard/design-system-shell-navigation.md index f87c0cb9ec..22edcb22c5 100644 --- a/docs/dashboard/design-system-shell-navigation.md +++ b/docs/dashboard/design-system-shell-navigation.md @@ -36,7 +36,7 @@ Stable layouts on narrow widths (especially mobile or multi-panel layouts) must - **Scheduled Agent Indicator:** The top nav may render a compact `CalendarClock` count control for active agent-created task runs and wakeups. Keep it hidden when there are no active agent schedules, use the same compact shell control sizing as adjacent status buttons, and keep the count stable with tabular numerals. ### 5. Standardized Components -The shell relies on reusable layout components from `dashboard/src/v2/components/layout/` (such as `Sidebar` and `NavItem`) and top navigation components from `dashboard/src/v2/components/top-nav/` (such as `BrandSection`, `GlobalSearch`, and `TelemetryStats`). +The shell relies on reusable layout components from `dashboard/src/v2/components/layout/` (such as `Sidebar`, `NavItem`, and `KineticDock` which features labels for Overview, Sprints, Tasks, Agents, Stats, Schedule, Memory, Knowledge, Browser, Files, Live, Config, and Chat) and top navigation components from `dashboard/src/v2/components/top-nav/` (such as `BrandSection`, `GlobalSearch`, and `TelemetryStats`). ### 6. Hover and Active Indicators - **Motion Tokens:** Shell navigation must use the interaction contracts in `dashboard/src/v2/lib/motion`. Use `controlFeedback` for hover, focus, icon color, and label feedback; `selectionMovement` for active route backgrounds, vertical markers, and minimized/expanded label reveal; and `enterExit` for mobile drawer and backdrop transitions. diff --git a/docs/dashboard/design-system-stats.md b/docs/dashboard/design-system-stats.md index 9caeb57dd8..bc89875178 100644 --- a/docs/dashboard/design-system-stats.md +++ b/docs/dashboard/design-system-stats.md @@ -172,6 +172,10 @@ Use page-scoped Stats primitives instead of one-off analytics chrome. The post-r Dense analytics layouts should stay calm: restrained contrast, low-opacity fills, semantic color, stable grids, and short labels. Avoid nested decorative cards; repeated cards, ledger rows, modals, and tool panels may be framed, while page sections should read as workspaces. +## Architecture + +The `StatsPage` uses the `useStatsPageData` hook to coordinate visual modes. The hook manages and exposes state including `activeQuery`, `visualMode`, `chartState`, `providerSegments`, `sourceSegments`, `tokenSegments`, and `planningUsage`, ensuring seamless transitions across Trend, Composition, Models, Providers, Ledgers, and System views. + ## Responsive Behavior - The hero uses a two-zone command band on wide screens and stacks project context, time controls, and mode navigation on narrow screens. diff --git a/docs/dashboard/quicksprint-templates.md b/docs/dashboard/quicksprint-templates.md index 5f78dcacce..2b64460c6e 100644 --- a/docs/dashboard/quicksprint-templates.md +++ b/docs/dashboard/quicksprint-templates.md @@ -94,6 +94,17 @@ Editor validation must stay visible and durable. Saving is disabled until the te Template deletion is always confirmed in UI that names the target template. Browse deletion uses the shared destructive confirmation dialog and restores focus to the original delete control or the template rail fallback after removal. Inline editor deletion uses a two-step confirmation with Cancel/Escape and pending deletion copy. Neither deletion path may rely on browser-native confirmation prompts, color alone, or animation-only cues. +## API and Execution Contract + +The REST API and MCP `manage_quicksprints` tool expose these actions: +- `list_templates`: List built-in and custom templates for a project. +- `get_template`: Retrieve a specific template. +- `create_template`: Create a custom template with `name`, `description`, `icon`, `category`, and `agentInstructionMarkdown`. Optional fields include `categoryColor`, and `defaultTaskCount`. +- `update_template`: Update custom template fields. +- `delete_template`: Remove a custom template or hide a built-in template for a project. Requires explicit approval via MCP. +- `execute`: Plans a quicksprint. Payload supports `taskCount`, `noTaskLimit`, `submitMode`, `routeOverride`, and `modelOverride`. Defaults to `submitMode: "plan_only"`. +- `start`: Alias for execution defaulting to `submitMode: "plan_and_start"`. + Current built-in purpose set: - `Fullstack JS App` diff --git a/docs/dashboard/scheduler.md b/docs/dashboard/scheduler.md index 5f90c7db26..73dc336f23 100644 --- a/docs/dashboard/scheduler.md +++ b/docs/dashboard/scheduler.md @@ -96,13 +96,13 @@ The dashboard API routes are: - Updates status, timing, recurrence, or target payload. - Updating `scheduleAnchor` switches an entry to anchored semantics. Setting it to `null` returns the entry to absolute-time semantics with `scheduledFor`. - `DELETE /api/scheduler/:entryId` - - Deletes an entry. + - Deletes an entry. (Note: using the `manage_scheduler` MCP tool requires `approval: { confirmed: true }`). - `GET /api/projects/:projectId/scheduler/memory-remediation` - Returns the settings-managed long-term memory remediation entry, if one exists. - `PUT /api/projects/:projectId/scheduler/memory-remediation` - Creates, updates, or pauses the settings-managed long-term memory remediation entry. - `POST /api/scheduler/run-due` - - Processes due scheduler entries manually + - Processes due scheduler entries manually. Accepts an optional `now` ISO override for operational verification. ## Runtime Execution diff --git a/docs/deployment/electron-desktop.md b/docs/deployment/electron-desktop.md index c0d9efaf0e..7be790429e 100644 --- a/docs/deployment/electron-desktop.md +++ b/docs/deployment/electron-desktop.md @@ -8,6 +8,7 @@ Code UX can run as an installable Electron desktop app while preserving the exis - The backend still serves the dashboard over loopback HTTP. - The desktop window loads the resolved dashboard URL, usually `http://127.0.0.1:4444`. - If the requested dashboard port is busy, the backend keeps the existing retry behavior and the Electron window opens the actual runtime port. +- The Electron shell (`src/electron/main.ts` and `src/electron/dashboard-network-policy.ts`) defines desktop boundaries, native window management, and network policies for the UI. It does not own backend orchestration; it solely hosts the Code UX UI and connects to the existing container-first backend. - MCP stdio is disabled in the Electron runtime with `CODE_UX_DISABLE_MCP_STDIO=1` so the GUI process does not attach to desktop process stdio. - Mutable dashboard runtime traffic (`/api/*`, `/health`, and `/ready`) is treated as non-cacheable in both the backend response headers and the Electron session. The desktop app clears the Electron HTTP cache on startup, injects no-cache request headers only for runtime `GET`/`HEAD` reads, and injects no-store response headers for all loopback runtime data so stale Chromium cache entries cannot make settings, project, agent, or runtime pages appear frozen after navigation without interfering with JSON upload bodies. - Windows packaged builds keep the active WebGL context cap at 16 so the persistent shell canvas, avatar canvases, and route-scoped chart canvases have enough headroom during long navigation sessions while old Chromium contexts are waiting for garbage collection. diff --git a/docs/development/documentation-standards.md b/docs/development/documentation-standards.md index ad61609fe1..f6d575d9df 100644 --- a/docs/development/documentation-standards.md +++ b/docs/development/documentation-standards.md @@ -32,11 +32,13 @@ Each new major doc should include: When behavior changes: 1. Update the relevant topic doc. -2. Update `docs/index.md` if a new page is added. -3. Update `docs/SUMMARY.md` table of contents. -4. Add migration notes when behavior is not backward compatible. +2. If a new page is added, link it from both `docs/index.md` and `docs/SUMMARY.md`. +3. Add migration notes when behavior is not backward compatible. -**Publication Workflow:** Update canonical `docs/` first, then align the matching `docs-web/` page when the content is public-facing. +**Publication Workflow:** +- `docs/` is the canonical source of truth, and `docs-web/` is the publication and reference mirror. +- Update canonical `docs/` first, then align the matching `docs-web/` page consistently whenever public-facing behavior changes or new subsystems are introduced. +- A `docs-release/` directory should not be created or used. ## Source of Truth Hierarchy diff --git a/docs/development/testing-and-quality.md b/docs/development/testing-and-quality.md index 1bdca1804e..36b3822930 100644 --- a/docs/development/testing-and-quality.md +++ b/docs/development/testing-and-quality.md @@ -21,7 +21,7 @@ pnpm run lint - Run tests ```bash -pnpm test +pnpm run test ``` - Run backend tests only @@ -65,9 +65,9 @@ Provider invocation persistence tests should cover required observability fields pnpm run ci ``` -`pnpm run ci` starts with `pnpm run quality:guardrails`, then runs audit, lint, backend coverage, dashboard tests, and build. Run `pnpm run quality:guardrails` directly after changes that affect shared implementation structure, large modules, duplicate logic, dependency factory wiring, realtime snapshot persistence, optimistic task insertion, or the guardrail script itself. Treat blocking guardrail output as CI-equivalent; advisory oversized-file and broad-`any` reports identify cleanup targets but do not fail the command. +`pnpm run ci` executes `quality:guardrails -> audit -> lint -> test:backend:coverage -> test:dashboard -> build`. -GitHub Actions runs the same signals as separate jobs so a vulnerability finding does not obscure compile, test, or build failures. The `Security Audit` job runs `pnpm run audit` independently, while `Typecheck & Lint`, `Backend Tests & Coverage`, `Dashboard Tests`, and `Build` run the repository quality, TypeScript, Vitest, and bundle checks on Node 22 with pnpm 10.33.0. Workflow health tests under `tests/backend/ci/workflow-health.test.ts` assert this split, the `package.json` audit script value, the absence of audit execution from build and Playwright lanes, the pinned `pnpm/action-setup` and `actions/setup-node` versions, frozen `pnpm install --frozen-lockfile --ignore-scripts` installs, concurrency cancellation, and cache keys that include runner OS, Node 22, pnpm 10.33.0, and dependency/config hash inputs. +GitHub Actions runs the same signals as separate jobs so a vulnerability finding does not obscure compile, test, or build failures. The `Security Audit` job runs `pnpm run audit` independently, while `Typecheck & Lint` runs `pnpm run quality:guardrails`, `pnpm run typecheck`, and `pnpm run typecheck:dashboard`, `Backend Tests & Coverage` runs the backend Vitest coverage pass, `Dashboard Tests` runs the dashboard Vitest pass, and `Build` runs the repository bundle checks on Node 22 with pnpm 10.33.0. Workflow health tests under `tests/backend/ci/workflow-health.test.ts` assert this split, the `package.json` audit script value, the absence of audit execution from build and Playwright lanes, the pinned `pnpm/action-setup` and `actions/setup-node` versions, frozen `pnpm install --frozen-lockfile --ignore-scripts` installs, concurrency cancellation, and cache keys that include runner OS, Node 22, pnpm 10.33.0, and dependency/config hash inputs. The quality guardrail script also audits `vitest.config.ts` directly. It fails if `coverage.include` stops observing `src/**/*.ts`, if any global coverage threshold drops below the locked floors, if the `src/server/activity-cache-service.ts` line threshold is missing, malformed, below 80%, or if that file is excluded from coverage observability. The enforced global thresholds in `vitest.config.ts` are: | Metric | Threshold | diff --git a/docs/operations/management-cli.md b/docs/operations/management-cli.md index f4ba56c7d5..180e87dcff 100644 --- a/docs/operations/management-cli.md +++ b/docs/operations/management-cli.md @@ -2,6 +2,6 @@ Code UX exposes a direct command-line management surface for the same core resources that the MCP management tools cover. -The full command reference lives in [CLI Commands Reference](../reference/cli-commands.md). That page covers the action aliases, required flags, interactive prompting behavior, `--json`, `--payload-json`, and approval handling. +The full command reference lives in [CLI Commands Reference](../reference/cli-commands.md). That page covers the action aliases, flag coercions, startup behaviors, required flags, interactive prompting behavior, `--json`, `--payload-json`, and approval handling. Use this page as a quick landing spot when you just need to remember that the CLI routes through the existing `ManagementToolHandler` and stays aligned with the MCP tool surface. diff --git a/docs/operations/runbook.md b/docs/operations/runbook.md index d1b82e820d..f2a848c8c0 100644 --- a/docs/operations/runbook.md +++ b/docs/operations/runbook.md @@ -4,7 +4,7 @@ This runbook covers day-to-day operation and incident handling for the MCP serve ## Normal Startup Procedure -Database maintenance (`DatabaseMaintenanceService`) runs automatically during normal startup. Operators can expect: +Database maintenance (`DatabaseMaintenanceService`) runs automatically during normal startup to perform settings-driven DB pruning, VACUUM, and WAL checkpointing. Do not instruct operators to manually perform destructive DB edits. Operators can expect: - `dbAutoVacuumOnStartup`: Triggers VACUUM on local databases. Can skip if set to false. - `dbPruningEnabled`: Prunes old data matching `dbRetentionDays`. Can skip if set to false. - `dbRetentionDays`: Bounded to a safe range (1-3650 days). Negative or zero values will be clamped. @@ -175,17 +175,18 @@ Checks: - Docker Runtime memory limits apply to every CLI provider container. `containerMemoryLimitMb` defaults to `6144`; positive values are passed as both Docker `--memory` and `--memory-swap`, while `0` omits those flags. If full-suite tests or browser-heavy validation hit the cap, raise this setting for the affected project or sprint instead of increasing provider concurrency. - For WORKER-profile routes, a saved worker model is only forwarded when it belongs to the selected provider. If you switch a planning or worker run from Codex to Gemini/Claude, Code UX now falls back to that provider's own model instead of sending an incompatible model id like `gpt-5.3-codex` to Gemini or Claude. - Codex websocket `HTTP 5xx` failures are transport/server errors, not auth failures. If you see `responses_websocket` + `HTTP error: 500`, treat that as a transient provider-side failure rather than a stale local login. - - If auth is expected from host login state, is the relevant Docker auth mount enabled and is its mount path valid? - - Docker mode requires daemon-visible workspace paths. Runtime now prefers repo-scoped worktree paths for Docker sessions. + - If auth is expected from host login state, is the relevant Docker auth mount enabled and is its mount path valid? Docker uses dedicated, isolated credential mounts per provider to keep raw tokens and key paths out of the broader workspace and process arguments. + - Docker mode requires daemon-visible workspace paths. Runtime now prefers repo-scoped worktree paths for Docker sessions and mounts them as dedicated volumes alongside runtime volumes that hold provider home paths and package manager caches (`code-ux.workspace-runtime=true`). - Docker runtime state is stored under `~/.code-ux/runtime/docker//` by default (override with `JULES_DOCKER_RUNTIME_ROOT`). Cached setup image build contexts and build locks live under that root so setup-cache images survive dashboard restarts and concurrent post-restart jobs wait on the same build instead of starting duplicate builds. + - Startup pruning clears orphaned helper containers, login containers, temp credential dirs, and stale workspace/runtime volumes that are no longer referenced by active tracking. - During normal Code UX shutdown (`SIGINT`, `SIGTERM`, `SIGHUP`, or Electron quit), the server requests active dispatch aborts, drains persistent Git/workspace helper pools (including helpers that were still starting), and then kills any still-running Docker containers with `code-ux.*` labels or deterministic `code-ux-*` runtime names. It does not remove Docker workspace/runtime volumes. On the next start, recovery follows `Settings -> General -> Restart Behavior`: continue resumes active sprint runs by default, pause/cancel applies sprint-level policy before watch-loop recovery, and invocation restart/cancel removes labelled active containers without deleting preserved volumes. - Pausing a sprint run also pauses or stops active task dispatch rows, cancels linked provider and QA runtime rows, releases task and sprint leases, and resets affected project tasks to `pending`. Resuming that run uses existing-run recovery and will not create a second sprint run. - Dashboard and MCP HTTP listeners track and destroy open sockets during shutdown, including upgraded dashboard WebSocket sockets, so open browser tabs do not delay process exit or leave ports bound during rapid restarts. - Docker workspace/runtime volumes for tracked CLI sessions are preserved across startup pruning after recovery marks the interrupted session `CANCELLED`; the next retry can still resume the old workspace volume when `Resume failed task in same workspace` is enabled. - Rerun resume uses the latest `cli_workspace_bound` event as the source of truth for the workspace session id. If the latest interrupted provider invocation has a different `session_id`, Code UX still resumes the Docker volume named by the recorded workspace binding. - Codex uses per-session container home directories under that runtime root to prevent stale state from previous Codex runs. - - `RuntimeCleanupService` prunes stale `home-codex-*` session homes and stale shared runtime temp directories automatically once those sessions are no longer active. -- During shutdown, Code UX disposes the command-spawner host before Docker cleanup (`DockerRuntimePruneService` and `DockerAssetPruneService`). These services clean or prune runtime artifacts and stale Docker assets/workspaces (they do not perform a full repair for broken provider state). If shutdown is interrupted or Docker cleanup is slow, the helper process cannot continue launching Docker commands behind the exiting runtime. + - `RuntimeCleanupService` performs a periodic sweep for stale/offline connections, expired leases, terminal dispatch reconciliation, stale sprint runs, and runtime artifacts. +- During shutdown, Code UX disposes the command-spawner host before Docker cleanup (`DockerRuntimePruneService` and `DockerAssetPruneService`). `DockerRuntimePruneService` safely prunes stale per-runtime paths and shared temp paths after their age threshold while preserving active roots/Codex homes. `DockerAssetPruneService` cleans up orphaned workspace volumes, login containers, helper containers, and temporary credential directories on startup. Do not instruct operators to run broad manual `docker system prune` commands. - Docker provider launches use readable container names such as `code-ux-codex-` and mount provider arguments through a generated argv file instead of passing the full prompt through the host `docker run` command line. Secret-bearing provider environment variables are written to temporary `0600` env-files and supplied with `--env-file`, so `ps`/process-list inspection should show only the env-file path and not API key values. If Docker reports that the deterministic provider container name is already in use, Code UX force-removes that named container with volumes and retries the launch once; repeated conflicts usually mean an external Docker daemon or another runtime is recreating the same session container. Packaged Windows Electron builds that fail with `spawn ENAMETOOLONG` during provider launch are using an older build or a non-provider launch path that still embeds a large payload in command arguments. - When setup-image caching is enabled, the first Docker provider or preview run for a base image/setup-script combination may spend several minutes building a content-addressed `code-ux-setup-cache-*` image. Activity logs now call out the cache miss, stream Docker build steps, and report bounded progress; later runs reuse the cached image until the base image, setup script content, Dockerfile template, or Playwright-browser setting changes. If the build fails, Code UX logs the fallback and runs the setup script at container runtime instead. - Provider login uses a separate content-addressed `code-ux-login-base-node-24-bookworm-slim:*` image with curl and keyring prerequisites baked in. The image is prewarmed after dashboard logging is available, but this is best-effort: failures should be treated as startup warnings, not as a reason to block the dashboard or provider login. @@ -211,7 +212,7 @@ Checks: - Sprint deletion is rejected while the sprint has any queued/running/cancel-pending sprint run, active task dispatch, running provider/execution invocation, preserved invocation transcript, or a sprint run that finished in the last 30 seconds. Cancel, pause, or let runtime cleanup (`RuntimeCleanupService`) settle first; this prevents database cascades from deleting rows while an in-memory watch loop or provider callback is still unwinding. - To clean up stale workspace branches that were merged or closed on origin, use `BranchReaperService` logic via the dashboard. - `RuntimeStartupRecoveryService` closes active dispatch/task-run rows whose linked provider invocation already reached a terminal state. It reconciles persisted/runtime state after restart and cleans or marks stale execution artifacts according to service behavior. If the project task is already code-complete, the dispatch mirrors completion; otherwise the task is reset to pending for a clean retry instead of staying in a stale running state. -- Live provider telemetry refreshes the linked task-dispatch heartbeat (`HeartbeatService`) while the provider invocation is running. A dispatch heartbeat should not go stale when provider usage rows are still updating. +- Live provider telemetry refreshes the linked task-dispatch heartbeat (`HeartbeatService`) while the provider invocation is running. `HeartbeatService` acts to renew sprint-run heartbeat/lease on an interval and stops tracking when renewal fails. It is for liveness and lease maintenance, not a cleanup command. A dispatch heartbeat should not go stale when provider usage rows are still updating. - In local-git mode, an existing worker-owned main-merge conflict attention item suppresses additional `feature -> default` merge attempts while the worker is resolving the conflict. Human-escalated main-merge attention pauses the sprint with local conflict instructions. ### 5. Planning retry message appears but no provider work is visible @@ -308,7 +309,7 @@ Transient provider failures are classified and managed in `src/shared/providers/ ## Recovery Techniques - Temporarily disable selected loop steps for diagnosis. -- Startup recovery responsibilities are split into focused modular routines (QA review recovery, invocation recovery, etc.), while preserving centralized orchestration order. Recovered-state logging surfaces these distinct outcomes to the dashboard. +- Startup recovery is orchestrated centrally by `RuntimeStartupRecoveryService`. It handles reconciliation for interrupted CLI sessions, local/provider dispatches, retry waits, QA review runs, orphaned provider invocations, terminal dispatches, interrupted task runs, stale paused sprints, and recoverable sprint runs. Recovered-state logging surfaces these distinct outcomes to the dashboard. - Use the dashboard live view to inspect state without starting new work. - Use activities APIs to inspect detailed session trace. - Re-enable steps after diagnosis to restore normal operation. diff --git a/docs/operations/security-hardening.md b/docs/operations/security-hardening.md index c9264445c5..30deb0a621 100644 --- a/docs/operations/security-hardening.md +++ b/docs/operations/security-hardening.md @@ -60,7 +60,7 @@ While Code UX trusts the developer and any connected systems, several specific p - **Preview Proxy Hardening:** The local preview proxy enforces clear boundaries on the local ports and destination hosts it will forward traffic towards, reducing blind SSRF proxy abuse. Dashboard-origin API proxy requests under `/api/browser/sessions/:sessionId/proxy*` strip dashboard `Authorization`, `Cookie`, `Set-Cookie`, hop-by-hop, `proxy-*`, `x-code-ux-*`, `Host`, `Content-Length`, and `Accept-Encoding` headers before forwarding and normalize `Origin`, `Referer`, and `Sec-Fetch-Site` to the selected loopback upstream. - **Preview Response Header Isolation:** Dashboard-origin API proxy responses cannot set dashboard cookies or apply upstream CSP/frame-blocking policies to the dashboard origin. `Set-Cookie`, CSP, CSP report-only, and `X-Frame-Options` are removed before those responses are written back through `/api/browser/sessions/:sessionId/proxy*`. - **Preview Session Object Access:** Preview session IDs are scoped to their owning project and sprint before dashboard API rebuild, stop, remove, log, and proxy operations proceed. Foreign or missing sessions return a generic not-found response so callers cannot use session IDs to control or inspect another project preview. -- **Preview Frame Compatibility:** Preview-host traffic is treated as local trusted application content rather than dashboard chrome. The preview-host iframe path may forward that preview origin's own `Authorization` and `Cookie` headers so stateful preview apps keep working. The dashboard does not stamp its frame/permissions hardening headers onto preview-host responses, and proxied preview HTML has upstream CSP and `X-Frame-Options` stripped so the in-app iframe remains loadable. +- **Preview Frame Compatibility:** Preview-host traffic is treated as local trusted application content rather than dashboard chrome. The preview-host iframe path may forward that preview origin's own `Authorization` and `Cookie` headers so stateful preview apps keep working. The dashboard skips its `X-Frame-Options` and `Permissions-Policy` hardening headers on preview-host responses, and proxied preview HTML has upstream CSP and `X-Frame-Options` stripped so the in-app iframe remains loadable with full feature access (e.g. camera, microphone). - **Preview CORS Compatibility:** Preview-host traffic answers CORS preflights and overrides upstream `Access-Control-*` headers at the proxy boundary. The dashboard API origin keeps its CSRF guard; only preview-host origins get permissive local-app CORS behavior. ### Electron Desktop Shell @@ -75,7 +75,7 @@ While Code UX trusts the developer and any connected systems, several specific p - **Provider Transcript Sanitization:** Provider stdout/stderr callbacks, returned command output, and parsed usage transcript/conversation strings pass through the invocation-output sanitizer before they are persisted or surfaced to the dashboard. Raw provider streams may still be held transiently in memory while provider parsers compute usage and session metadata. - **MCP Gateway Log Hygiene:** Unauthorized, invalid-header, rate-limit, inactive-session, session-cap, idle-cleanup, and startup gateway logs omit bearer values, supplied session ids, supplied agent ids, raw request bodies, provider credentials, and login tokens. They retain only bounded operational metadata such as method, path, host, port, auth-required state, active-session counts, configured limits, and timeout values. - **Settings Secret Inputs:** Dashboard settings fields that store provider API keys, Git host tokens, Jira API tokens, and external embedding API keys render as masked secret inputs by default. Operators must explicitly use the reveal control to inspect a value. -- **Docker Secret Transport:** Provider and preview Docker launches write selected host/provider environment variables to temporary `0600` env-files and pass those files via `--env-file`. Provider argv and generated provider MCP/config artifacts are also staged in restrictive temporary files and mounted into the container instead of being inlined into `docker run` arguments or labels. This keeps API keys, MCP bearer tokens, and Git tokens out of the host `docker run` argv visible through process listings while preserving the same container environment. +- **Docker Secret Transport:** Provider and preview Docker launches write selected host/provider environment variables to temporary `0600` env-files and pass those files via `--env-file`. Provider argv and generated provider MCP/config artifacts are also staged in restrictive temporary files and mounted into the container instead of being inlined into `docker run` arguments or labels. Provider credentials use isolated credential mounts rather than broad workspace root exposure, ensuring secrets are strictly bounded and not inadvertently captured in workspace logs. This keeps API keys, MCP bearer tokens, and Git tokens out of the host `docker run` argv visible through process listings while preserving the same container environment. ### Subprocess & Settings Mutation Safety - **Shell-Free Command Execution:** Shared subprocess execution validates command names, argument null bytes, and stdin file paths immediately before spawning, then runs with `shell: false` so arguments are not reinterpreted by a shell. diff --git a/docs/reference/cli-commands.md b/docs/reference/cli-commands.md index 25e3d0c29e..a9319c9599 100644 --- a/docs/reference/cli-commands.md +++ b/docs/reference/cli-commands.md @@ -34,8 +34,21 @@ The direct domain form is the preferred shell interface. The generic `manage` fo - The CLI prompts for missing required flags only when `stdin` is a TTY. - If required flags are missing in non-interactive mode, the command fails instead of guessing. - `--json` prints the raw management envelope returned by the handler. -- `--payload-json` can carry `domain`, `action`, `payload`, and `approval` for the `manage` passthrough. -- Destructive actions require an approval retry. The first call returns an approval request, and the exact same action must be sent again with `approval.confirmed: true`. +- `--payload-json` properties merge with explicitly passed command-line flags. For the `manage` passthrough, it can carry `domain`, `action`, `payload`, and `approval`. For direct domain commands, it acts as a base payload. +- Destructive actions require an approval retry. The first call returns an approval request, and the exact same action must be sent again with approval confirmation via `--payload-json '{"approval":{"confirmed":true}}'`. + +## Startup Behavior + +Before parsing regular management commands, the CLI intercepts startup flags. +- `--help` and `-h` show global help. However, if they are placed after a management command (e.g. `codeux projects --help`), the CLI intercepts it as domain-specific help. +- The CLI parses global start-up flags with values (e.g. `--api-key`, `--runtime-role`) before routing to the management handler. + +## Flag Coercion + +The CLI parser automatically coerces certain flags into appropriate types before forwarding them to the management handlers: +- **Booleans**: Flags like `--auto-start`, `--replan`, or `--no-task-limit` will be parsed as true/false depending on value (e.g. `true`, `yes`, `1`, `on` vs `false`, `no`, `0`, `off`). +- **Numbers**: Numeric flags like `--tasks` (`taskCount`), `--limit`, or `--min-similarity` are parsed as finite numbers. +- **Arrays**: Certain flags accept array values by repeating the flag multiple times. For example: `--memory-ids mem-1 --memory-ids mem-2` will be merged into an array `["mem-1", "mem-2"]`. ## Common Aliases @@ -49,11 +62,37 @@ These aliases are accepted and normalized before dispatch: - `schedule-sprint` -> `schedule_sprint` - `schedule-quicksprint` -> `schedule_quicksprint` - `schedule-chat` -> `schedule_chat` +- `force-cancel` -> `force_cancel` +- `inspect-run` -> `inspect_run` +- `import-issues` -> `import_issues` +- `start-reembed` -> `start_reembed` +- `model-status` -> `model_status` - `get-system` -> `get_system` +- `get-project-override` -> `get_project_override` +- `resolve-project-effective` -> `resolve_project_effective` +- `get-sprint-override` -> `get_sprint_override` +- `resolve-sprint-effective` -> `resolve_sprint_effective` - `replace-system-settings` -> `replace_system_settings` +- `patch-system-setting` -> `patch_system_setting` +- `replace-project-settings` -> `replace_project_settings` - `patch-project-setting` -> `patch_project_setting` +- `reset-project-settings` -> `reset_project_settings` +- `replace-sprint-settings` -> `replace_sprint_settings` +- `patch-sprint-setting` -> `patch_sprint_setting` +- `reset-sprint-settings` -> `reset_sprint_settings` - `start-session` -> `start_session` +- `rebuild-session` -> `rebuild_session` +- `stop-session` -> `stop_session` +- `remove-session` -> `remove_session` +- `get-script` -> `get_script` +- `get-logs` -> `get_logs` +- `get-url` -> `get_url` +- `get-project-execution-snapshot` -> `get_project_execution_snapshot` - `get-project-stats-snapshot` -> `get_project_stats_snapshot` +- `list-sprint-runs` -> `list_sprint_runs` +- `list-task-dispatches` -> `list_task_dispatches` +- `list-execution-invocations` -> `list_execution_invocations` +- `list-execution-invocation-messages` -> `list_execution_invocation_messages` ## Flag Conventions @@ -103,7 +142,7 @@ Some commands intentionally block on approval before they mutate state: - `replace_*` settings actions - selected scheduler delete operations -When one of those commands runs without approval, Code UX returns an approval request instead of mutating anything. Re-run the same command with `approval.confirmed: true` once the user approves the change. +When one of those commands runs without approval, Code UX returns an approval request instead of mutating anything. Re-run the same command with `--payload-json '{"approval":{"confirmed":true}}'` once the user approves the change. ## Domain Examples @@ -163,12 +202,12 @@ codeux agents update --project proj-1 --preset qa-agent --payload-json '{"instru ```bash codeux memory search --project proj-1 --query "pricing page" -codeux memory promote --project proj-1 --memory-ids '["mem-1","mem-2"]' +codeux memory promote --project proj-1 --memory-ids mem-1 --memory-ids mem-2 codeux memory start_reembed --project proj-1 codeux manage --payload-json '{"domain":"memory","action":"create_claim","payload":{"projectId":"proj-1","claim":"Use dependency factory composition for service wiring.","category":"patterns","confidence":0.9,"durability":0.85}}' ``` -Durable claim actions exposed through the management surface are `create_claim`, `list_claims`, `get_claim`, `update_claim`, `add_claim_evidence`, and `deprecate_claim`. `deprecate_claim` follows the destructive approval flow: the first call returns an approval request, and the confirmed retry must include `approval.confirmed: true`. +Durable claim actions exposed through the management surface are `create_claim`, `list_claims`, `get_claim`, `update_claim`, `add_claim_evidence`, and `deprecate_claim`. `deprecate_claim` follows the destructive approval flow: the first call returns an approval request, and the confirmed retry must include `--payload-json '{"approval":{"confirmed":true}}'`. ### Preview diff --git a/docs/reference/glossary.md b/docs/reference/glossary.md index 10d5bed63c..13508b9afc 100644 --- a/docs/reference/glossary.md +++ b/docs/reference/glossary.md @@ -3,8 +3,8 @@ ## Code UX The container-first, local-first agentic coding runtime that coordinates the CLI, MCP server, sprint orchestrator, dashboard, and Electron shell around project work. -## Hosted Jules provider -The hosted remote provider accessed through the Jules API. Code UX treats it as one provider among several and can route sprint work to it when settings select Jules. +## Hosted Code UX provider +The hosted remote provider accessed through the Code UX API. Code UX treats it as one provider among several and can route sprint work to it when settings select Code UX. ## Local CLI providers Provider runtimes that execute through local CLI workflows, often inside Docker or host-backed worktrees, such as Gemini, Codex, Claude Code, Qwen Code, OpenCode, and Antigravity. @@ -12,11 +12,7 @@ Provider runtimes that execute through local CLI workflows, often inside Docker ## MCP tools The Model Context Protocol tool surface exposed by Code UX, including management, runtime, and dispatch contracts. -## Quicksprints -Short-lived, template-driven execution workflows for tightly scoped work. -## Scheduler -The persistent scheduler that queues sprint, quicksprint, and chat targets and releases them when they are due. ## .code-ux The canonical active project artifact directory for sprints, agents, instruction templates, logs, and runtime files. @@ -24,17 +20,11 @@ The canonical active project artifact directory for sprints, agents, instruction ## Provider instances Persisted provider configurations and the runtime sessions or dispatches created from them during execution. -## Memory / Knowledge -The short-term sprint evidence and durable project claims that Code UX stores for retrieval and review. -## Preview sessions -Browser preview sessions and their associated URLs, logs, and scripts used for frontend verification. ## Dashboard v2 surfaces The current Preact dashboard surfaces under `dashboard/src/v2/`, including execution, sprints, memory, settings, chat, and related views. -## Legacy `.jules-subagents` -Historical artifact directory used by older docs and migration notes. Current project artifacts live under `.code-ux/`. ## Agent Tool Handler Module that handles worker-local execution and reply helper calls. @@ -62,3 +52,24 @@ A markdown-defined unit of work in a sprint with fields like `depends_on`, `is_i ## Watch Loop Continuous orchestration mode that runs periodic cycles until exit criteria are reached. + +## Quicksprint +Reusable Markdown template resolved from project, home, bundled `.code-ux/quicksprints/templates`, or TS fallback, converted into a sprint goal and sent through normal sprint planning. + +## Scheduler +Project-scoped automation persisted in `scheduler_entries`; can run sprints, quicksprints, or chat messages once or on recurrence. + +## Memory +Runtime-learned short-term sprint and long-term project learnings, embedded and injected into prompts according to agent memory config. + +## Knowledge +Project-scoped document library ingested/uploaded/imported separately from memory, embedded locally, and attached to agent presets via subscriptions; agents use `search_knowledge` for exact passages. + +## Preview container +Sprint-scoped Docker preview session for one `(projectId, sprintId)`, persisted in `sprint_preview_sessions`, served through the in-app browser on a preview origin, using `.code-ux/browser/start-preview.sh` or generated fallback startup. + +## `manage_code_ux` (Deprecated) +Deprecated unified MCP dispatcher; dedicated `manage_*` tools are preferred. + +## Legacy `.jules-subagents` +Historical artifact directory used by older docs and migration notes. Current project artifacts live under `.code-ux/`. diff --git a/docs/settings/configuration-and-storage.md b/docs/settings/configuration-and-storage.md index e60977eb28..e14b88d468 100644 --- a/docs/settings/configuration-and-storage.md +++ b/docs/settings/configuration-and-storage.md @@ -29,9 +29,13 @@ External hint env keys used for dashboard import: ## Settings Overrides and Scoped Resolution -Code UX settings resolve through a scoped cascade: `system` → `project` → `sprint`. +Code UX settings resolve through a scoped cascade: `system` (base) → `project` (inherits from system) → `sprint` (inherits from project effective). System settings are the base of the cascade. -System settings hold global state, runtime behavior (e.g., ports, `consoleLogLevel`, `debugLogFileLevel`, `consoleLogMode`), and system integration credentials (Jira tokens, GitLab/GitHub tokens). +System settings hold global state, runtime behavior (e.g., ports, `consoleLogLevel`, `debugLogFileLevel`, `consoleLogMode`), and system integration credentials (Jira tokens, GitLab/GitHub tokens). They are also populated with defaults. + +Effective settings API endpoints include a `sources` dictionary mapping each JSON path to its originating scope (`system`, `project`, or `sprint`). + +Many settings families are handled by specific sanitizers that ensure defaults are applied and invalid shapes are repaired (e.g., `aiProvider`, `ciIntelligence`, `guardrails`, `cliWorkflow`, `git`, `jira`, `sprintLoopSteps`, `memory`, `modelPricing`, `workers`). Project and sprint scopes can override execution-specific settings, such as `aiProvider` routes (which now include provider instances and `invocationRouting` as first-class citizens instead of legacy top-level keys), `cliWorkflow` settings (like `gitMode`, `executionMode`, `containerImage`, `containerSetupScriptPath`), and preview defaults (like `sprintPreview.startupScriptPath` defaulting to `.code-ux/browser/start-preview.sh`). `git.defaultBranch` fallback is resolved based on scoped overrides too. Jira and GitLab integration configurations are also scoped and can be overridden. @@ -80,6 +84,7 @@ Runtime resolution: 2. Project setting override (Dashboard) 3. System setting default (Dashboard) 4. Hardcoded default (`main`) +- Additional Git branching behaviors configured here include `git.featureBranchPrefix` (e.g. `feature/codeux/`), `git.sprintBranchScheme` (e.g. `feature/sprint{sprint_id}-implementation`), and `git.sprintKeyPrefix` (uppercase identifier such as `SPR`). - The legacy project metadata `defaultBranch` column is retained for project records created before the scoped settings model and for display/initialization context, but sprint orchestration and final merge targets do not let that metadata override resolved scoped settings. A project inheriting a system default of `dev` must merge sprint completion PRs into `dev`, even if the older project row still says `main`. - In remote git mode, Code UX refreshes `origin` before sprint branch preflight and before each task start so branch resolution is based on current remote state instead of stale local refs. - HTTPS GitHub remotes use the configured dashboard token as a temporary Git extraheader during origin refresh, remote branch checks, and branch pushes. HTTPS origin refreshes and branch preflight network checks run with interactive credential prompts disabled and a bounded timeout so orchestration cannot remain stuck waiting on local credential helpers. Mandatory CLI task refreshes fetch the requested starting branch's remote-tracking ref when possible, avoiding a whole-origin fetch for every task dispatch. They use a 120 second default fetch timeout, configurable with `CODE_UX_GIT_FETCH_TIMEOUT_MS` for slow Git transports. If direct remote inspection is unavailable, branch preflight can use an existing `refs/remotes/origin/` ref as remote-branch evidence. Local origin-refresh failures remain strict for CLI-backed work that needs local git state, but are best-effort for branch preflight and Jules dispatch because Jules works from the remote source and starting branch. SSH remotes continue to use the local SSH agent/key setup unchanged. @@ -120,6 +125,7 @@ Runtime resolution: - `main` is only the final fallback when no sprint, project, or system base branch is configured. Normal sprint and task flows use the resolved `git.defaultBranch` value from scoped settings. - the old global `/api/settings` contract is removed in favor of explicit scoped endpoints - dashboard v2 settings queries clear both cached and in-flight effective-settings requests whenever system/project settings are saved or reset, which prevents stale AI model options immediately after integration updates. +- Settings actions that mutate state (replace, patch, reset) require human confirmation. Mutating settings actions first return an approval-required response; only the exact same action and payload may execute once with `approval.confirmed: true` within 15 minutes. Get/resolve actions are read-only. ## Persisted Scoped Settings Model diff --git a/docs/settings/opencode-integration.md b/docs/settings/opencode-integration.md index 718caf7a4e..7c3aa8ff1c 100644 --- a/docs/settings/opencode-integration.md +++ b/docs/settings/opencode-integration.md @@ -17,7 +17,7 @@ Planning routes use the same named OpenCode provider instance settings as chat a ## Authentication Modes -Each named OpenCode provider instance stores an `openCodeAuthMode` (`LOCAL_AUTH`, `ENV_KEY`, or `CUSTOM_PROVIDER`). +Each named OpenCode provider instance stores an `openCodeAuthMode` (`LOCAL_AUTH`, `ENV_KEY`, or `CUSTOM_PROVIDER`). API-key mode can use `ENV_KEY` or `CUSTOM_PROVIDER`; local/dashboard auth forces `openCodeAuthMode` to `LOCAL_AUTH`. ### Local Auth @@ -42,7 +42,7 @@ The generated config sets `permission` to `"allow"` for headless Code UX runs so ### Custom Provider -`CUSTOM_PROVIDER` generates an OpenCode provider entry for OpenAI-compatible endpoints: +`CUSTOM_PROVIDER` generates an OpenCode provider entry for OpenAI-compatible endpoints. The selected model becomes `/`, not the placeholder `custom/model`. ```json { diff --git a/docs/settings/provider-routing.md b/docs/settings/provider-routing.md index 170ffeefbb..917dbcff36 100644 --- a/docs/settings/provider-routing.md +++ b/docs/settings/provider-routing.md @@ -18,6 +18,9 @@ Code UX now separates: - optional per-agent provider/model preferences - provider credentials/instances managed by Integrations +Note that provider configuration is subject to the `system -> project -> sprint` resolution cascade and routing rules resolve against the effective settings at the current scope. +Effective API responses include `sources` metadata mapping routing rules and provider configurations to the scope that provided them. + *(Note: In routing contexts, `available` means detected credentials/auth presence or local auth enabled on that exact provider instance, whereas `enabled` means user-approved routing participation.)* ## Provider Runtime Artifacts @@ -49,11 +52,11 @@ Each `aiProvider.invocationRouting.` entry contains: - `strategy` - `MANUAL`, `WEIGHTED`, or `AGENT` - `provider` - - explicit manual provider instance id, or `null` to inherit the profile default + - explicit manual provider config id, or `null` to inherit the profile default - `allowedProviders` - - optional provider-instance subset for that invocation; empty means "all enabled providers" + - optional provider config id subset for that invocation; empty means "all enabled providers" - `providers` - - sparse per-provider-instance overrides for `enabled`, `model`, `weight`, and `thinkingMode` + - sparse overrides for `enabled`, `model`, `weight`, and `thinkingMode`, keyed by provider config id Provider instances are first-class routing targets: - the default built-in instances use ids `jules`, `gemini`, `codex`, `claude-code`, `qwen-code`, and `opencode` @@ -152,9 +155,8 @@ Provider-cap queueing is not a task creation failure. It must not increment the - CI fix and merge-conflict worker-owned repair flows - `src/services/memory-remediation-service.ts` - post-sprint memory curation and scheduled long-term memory cleanup -- `src/services/cli-workflow/pipeline/prepare-stage.ts` -- `src/services/cli-workflow/pipeline/execute-provider-stage.ts` - - consume explicit per-run provider settings instead of implicitly borrowing worker model overrides +- `src/services/cli-workflow/pipeline/*.ts` + - stages including `prepare`, `execute-provider`, `memory-capture`, `git-finalize`, `pr-finalize`, and `cleanup` consume explicit per-run provider settings instead of implicitly borrowing worker model overrides ## Dashboard Surface @@ -183,7 +185,7 @@ Dashboard route and model controls share provider display metadata from the sett - Codex model selectors include `gpt-5.6-sol`, `gpt-5.6-terra`, and `gpt-5.6-luna` as selectable catalog options while keeping `gpt-5.5` as the Codex default model - custom endpoint provider instances display their effective configured model in Settings defaults, route cards, and default model labels. Codex and Claude Code API-key custom endpoint instances use `customModel` and their custom base URL when local auth is not mounted; Qwen Code `MODEL_PROVIDER` and OpenCode `CUSTOM_PROVIDER` instances use their generated configured model ids and endpoint metadata. Mounted/local-auth and dashboard-auth instances ignore stale custom model or base URL fields and keep showing the saved provider default. - Sprint Composer and Quicksprint default route/model labels resolve from the `planning` invocation route mapping. A pinned Planning Route provider and its route-specific model override are displayed as the default, even when the worker default points at a different provider. -- Sprint Composer and Quicksprint explicit route selections keep the selected provider-instance id as the option value for UI state, but send the underlying CLI provider type in `PlanningOverrides.virtualProvider`. That keeps a selected instance such as `Claude Live` paired with the `claude-code` runtime when a model override is also selected. +- Sprint Composer and Quicksprint explicit route selections keep the selected provider-instance id as the option value for UI state, but send the underlying CLI provider type in `PlanningOverrides.virtualProvider`. This selects by CLI provider type for planning/prompt-improvement runs, and `virtualModel` only overrides that planning run's selected provider model (it is not a general task-coding model override). - model option values remain the provider catalog values returned by `getProviderModelOptions`; only labels and icons are display metadata File: diff --git a/docs/settings/qwen-code-integration.md b/docs/settings/qwen-code-integration.md index c91ba49ba8..6f91d6acbf 100644 --- a/docs/settings/qwen-code-integration.md +++ b/docs/settings/qwen-code-integration.md @@ -14,7 +14,7 @@ Qwen Code can be selected anywhere a virtual CLI provider is accepted: task codi ## Authentication Modes -The system integration entry for each named Qwen instance stores a `qwenAuthMode` (`LOCAL_AUTH`, `ALIBABA_CODING_PLAN`, or `MODEL_PROVIDER`). +The system integration entry for each named Qwen instance stores a `qwenAuthMode` (`LOCAL_AUTH`, `ALIBABA_CODING_PLAN`, or `MODEL_PROVIDER`). Non-local API-key mode can use either `ALIBABA_CODING_PLAN` or `MODEL_PROVIDER`, but if `authType` is local or dashboard auth, runtime forces `qwenAuthMode` to `LOCAL_AUTH`. ### Local Auth @@ -48,6 +48,8 @@ The Qwen runner launches with `--auth-type openai` and sets `OPENAI_BASE_URL` to - API key - model id registered in Qwen Code `modelProviders` +Placeholder models like `custom/model` or `local-model` resolve to `qwenModelId`. + For OpenAI-compatible providers, Code UX also forwards `OPENAI_API_KEY` and `OPENAI_BASE_URL` to the Qwen process. This covers DashScope compatible mode, OpenRouter, Ollama, vLLM, LM Studio, and similar endpoints. Custom endpoint instances appear on the AI Models page with their configured model id, such as `glm-4.7-flash`, instead of stale placeholders such as `custom/model` or `local-model`. diff --git a/docs/sprint-loop/atomic-loop.md b/docs/sprint-loop/atomic-loop.md index 864e487313..cc8c051c4e 100644 --- a/docs/sprint-loop/atomic-loop.md +++ b/docs/sprint-loop/atomic-loop.md @@ -33,8 +33,7 @@ Controlled by `dashboardSettings.sprintLoopSteps`: - `sessionSync` - `statusDerivation` - `startReadyTasks` -- `mergeProtocol` -- `actionRequiredProtocol` +- `protocol` - `statusTable` - `watchLoop` @@ -59,12 +58,13 @@ flowchart TD M --> N[status-derivation-step] N --> O{startReadyTasks} O --> P[start-ready-tasks-step] - P --> Q[protocol-step] - Q --> R{statusTable} - R --> S[status-table-step] - S --> T{wait && watchLoop} - T -->|true| U[watch loop cycles] - T -->|false| V[single-cycle report] + P --> Q{protocol} + Q --> R[protocol-step] + R --> S{statusTable} + S --> T[status-table-step] + T --> U{wait && watchLoop} + U -->|true| V[watch loop cycles] + U -->|false| W[single-cycle report] ``` ## Pull Request Content Rules @@ -114,14 +114,17 @@ For `status` and `orchestrate`, each cycle follows the strict execution order de - Evaluates the readiness gate: a task must be `PENDING`, dependencies completed and merged, provider concurrency available, and emergency stop inactive. - Task dispatch creates DB task dispatch and task-run records, selects the provider based on settings (uses hosted provider for `jules` and CLI/Docker or host workflows for local providers). - Marks tasks `RUNNING`, records session id/name/provider, and resets consecutive failure count on success. Triggers emergency stop after repeated real dispatch failures. -6. **Apply action-required automation**: Provider-agnostic handling of plan approval, clarification replies (via Project manager preset), and paused sessions, utilizing cooldown/dedupe rules and escalating attention items when necessary. -7. **Collect CI status**: Gathers CI data for feature branches. -8. **Backfill PR metadata**: Ensures PRs are tracked accurately. -9. **Run task QA review**: Evaluates completed coding work (`CODING_COMPLETED`). QA is a formal part of the merge gate, evaluating the work rather than acting as a vague final-only review. This handles retry/review behavior, stale QA invocation reconciliation, QA follow-up reruns, and transitions tasks back to in-progress when PR/CI/QA is not merge-ready. -10. **Evaluate feature PR CI/merge gate**: Evaluates completed coding work for PR/CI/merge readiness, review blockers, merge conflicts, missing PRs, and attention items. Does not automatically merge or apply fixes unless tied to configured auto-merge modes and intelligence settings. -11. **Persist CI gate state changes**: Saves the result of the CI merge gates. -12. **Rerun status derivation/start-ready**: Re-evaluates state and starts ready tasks if merges unblocked dependencies. -13. **Build status/protocol/table output**: Compiles the final cycle report and separates action-required tasks into agent and human intervention categories. +6. **Apply protocol step**: + - Provider-agnostic handling of plan approval, clarification replies (via Project manager preset), and paused sessions, utilizing cooldown/dedupe rules and escalating attention items when necessary. + - Gathers CI data for feature branches. + - Ensures PRs are tracked accurately. + - Evaluates completed coding work (`CODING_COMPLETED`). QA is a formal part of the merge gate, evaluating the work rather than acting as a vague final-only review. This handles retry/review behavior, stale QA invocation reconciliation, QA follow-up reruns, and transitions tasks back to in-progress when PR/CI/QA is not merge-ready. + - Evaluates completed coding work for PR/CI/merge readiness, review blockers, merge conflicts, missing PRs, and attention items. Does not automatically merge or apply fixes unless tied to configured auto-merge modes and intelligence settings. + - Saves the result of the CI merge gates. + - Re-evaluates state and starts ready tasks if merges unblocked dependencies. + +7. **Build status table output**: + - Compiles the final cycle report and separates action-required tasks into agent and human intervention categories. ## Watch Mode diff --git a/docs/yourdocs.md b/docs/yourdocs.md index 93928e662c..1879678dfb 100644 --- a/docs/yourdocs.md +++ b/docs/yourdocs.md @@ -5,17 +5,17 @@ This document describes the refactor that introduces: - Atomic sprint-loop architecture with independent step toggles. - Separation of MCP core tool logic and task/worker agent tool logic. - Editable markdown instruction templates with placeholder parsing. -- Home directory migration from `~/jules-subagents` to `~/.jules-subagents`. +- Home directory migration from `~/.code-ux` to `~/.code-ux`. - Dashboard settings for CI Intelligence merge gates. ## What Changed ### 1. Home Directory Path Migration The canonical runtime directory is now: -- `~/.jules-subagents` +- `~/.code-ux` Legacy path support: -- If `~/.jules-subagents/settings.db` does not exist and `~/jules-subagents/settings.db` exists, the DB is copied forward automatically. +- If `~/.code-ux/settings.db` does not exist and `~/.code-ux/settings.db` exists, the DB is copied forward automatically. - Runtime code now resolves to the dot-directory by default. Relevant file: @@ -64,17 +64,17 @@ This makes loop behavior reorderable/editable without touching MCP tool plumbing ### 1. Directory Layout Instruction templates are now expected at: -- `.jules-subagents/instructions/**` +- `.code-ux/instructions/**` Current sprint loop templates: -- `.jules-subagents/instructions/sprint-main-loop/guards/*` -- `.jules-subagents/instructions/sprint-main-loop/planning/*` -- `.jules-subagents/instructions/sprint-main-loop/protocol/*` -- `.jules-subagents/instructions/sprint-main-loop/watch/*` -- `.jules-subagents/instructions/sprint-main-loop/cleanup/*` +- `.code-ux/instructions/sprint-main-loop/guards/*` +- `.code-ux/instructions/sprint-main-loop/planning/*` +- `.code-ux/instructions/sprint-main-loop/protocol/*` +- `.code-ux/instructions/sprint-main-loop/watch/*` +- `.code-ux/instructions/sprint-main-loop/cleanup/*` Compatibility alias: -- `.jules-subagents/intructions/**` is also supported as a fallback search path for typo-safe compatibility. +- `.code-ux/intructions/**` is also supported as a fallback search path for typo-safe compatibility. ### 2. Placeholder Engine Template placeholder syntax: @@ -165,7 +165,7 @@ Validation run: ## Operational Notes -1. Existing projects can now override sprint loop messaging entirely by editing markdown templates under `.jules-subagents/instructions`. +1. Existing projects can now override sprint loop messaging entirely by editing markdown templates under `.code-ux/instructions`. 2. CI merge protocol can be tightened/relaxed in dashboard settings without code edits. 3. Loop behavior can be shaped for debugging or staged rollout by disabling selected steps. 4. Dot-directory migration is handled safely by default path resolution and legacy DB copy-forward. @@ -177,7 +177,7 @@ Validation run: - Startup no longer hard-fails when `JULES_API_KEY` is absent. - Server logs actionable setup instructions with sources: - `.env` - - `.jules-subagents/settings.json` + - `.code-ux/settings.json` - dashboard settings (`http://localhost:4444` default) - API-backed MCP handlers now preflight key presence and return setup guidance text when missing. - Dashboard planning remains available without a Jules key, but API-backed execution and session tools still return setup guidance until a key exists. @@ -347,10 +347,10 @@ Files: Change: - Background provider worktrees are now created under home-scoped runtime storage instead of inside the target repository. - New location pattern: - - `~/.jules-subagents/worktrees/-/` + - `~/.code-ux/worktrees/-/` Rationale: -- Prevents repository pollution when `.jules-subagents/worktrees` is not ignored. +- Prevents repository pollution when `.code-ux/worktrees` is not ignored. - Keeps transient execution workspaces in one runtime-managed location. File: @@ -409,8 +409,8 @@ Allow background Gemini/Codex runs to execute in isolated containers while prese - optional setup script execution before provider command - Setup script resolution order: 1. `containerSetupScriptPath` (if set) - 2. `/.jules-subagents/container/setup.sh` - 3. `~/.jules-subagents/container/setup.sh` + 2. `/.code-ux/container/setup.sh` + 3. `~/.code-ux/container/setup.sh` ### Files @@ -426,7 +426,7 @@ Allow background Gemini/Codex runs to execute in isolated containers while prese ## Incremental Update: Demo Container Bootstrap Script Added repository demo setup script for Docker execution bootstrap: -- Path: `.jules-subagents/container/setup.sh` +- Path: `.code-ux/container/setup.sh` - Purpose: - ensure `git` and GitHub CLI `gh` are available - ensure `pnpm` is available @@ -533,7 +533,7 @@ Files: ### SQLite Session Tracking for CLI Providers Added provider session/activity persistence: -- DB: `~/.jules-subagents/session-tracking.db` +- DB: `~/.code-ux/session-tracking.db` - Tables: - `provider_sessions` - `provider_activities` @@ -562,4 +562,4 @@ Files: - `src/sprint/steps/protocol-step.ts` - `src/sprint/steps/status-table-step.ts` - `src/instructions/instruction-template-catalog.ts` -- `.jules-subagents/instructions/sprint-main-loop/protocol/*.md` +- `.code-ux/instructions/sprint-main-loop/protocol/*.md`