| feat(always-on): add Dashboard sub-tab with cross-workspace event timeline
Emit phase-level events (discovery/plan/execution/report) from
DiscoveryFire and CronFire into a per-project events.jsonl, aggregate
them via a new GET /api/always-on/events endpoint, and render a
Dashboard tab inside the Always-On view showing stats cards and a
chronological event feed across all workspaces.
Co-authored-by: Cursor <cursoragent@cursor.com>
| 19 天前 |
| fix(ui): wire Always-On items tab to gateway storage for plans and cron
Replace the cron jobs empty stub with a live gateway.cronList() call and
map CronTask to the CronJobOverview shape the frontend expects. Switch
cron delete/run-now handlers from the legacy daemon socket to gateway
RPC (cronDelete / cronCreate-once). Redirect discovery plan reads from
the legacy .claude/always-on/ path to the gateway's pilotHome storage
(~/.pilotdeck/always-on/projects/<id>/plans/index.json), and align the
shared always-on-paths helper accordingly. Handle gateway↔UI status
enum differences (executing→running, schemaVersion field).
Co-authored-by: Cursor <cursoragent@cursor.com>
| 19 天前 |
| refactor(ui): remove dead Always-On plan/cron detail types and unused server exports
Drop 13 unused fields from DiscoveryPlanOverview, remove
DiscoveryPlanContextRefs, CronJobOverviewLatestRun, and
CronRunOutcomeStatus types that the UI never reads. Prune 4 dead
exports from always-on-run-history.js (and simplify its service
wiring) and 4 from always-on-run-logs.js, keeping only the append
helpers consumed by discovery-plans.js.
Co-authored-by: Cursor <cursoragent@cursor.com>
| 18 天前 |
| refactor(ui): remove dead Always-On plan/cron detail types and unused server exports
Drop 13 unused fields from DiscoveryPlanOverview, remove
DiscoveryPlanContextRefs, CronJobOverviewLatestRun, and
CronRunOutcomeStatus types that the UI never reads. Prune 4 dead
exports from always-on-run-history.js (and simplify its service
wiring) and 4 from always-on-run-logs.js, keeping only the append
helpers consumed by discovery-plans.js.
Co-authored-by: Cursor <cursoragent@cursor.com>
| 18 天前 |
| chore(branding): complete cleanup of legacy CloudCLI/Claude Code references
- CLOUDCLI_DISABLE_LOCAL_AUTH → PILOTDECK_DISABLE_LOCAL_AUTH
- CLOUDCLI_CRON_DAEMON_* → PILOTDECK_CRON_DAEMON_*
- CLOUDCLI_GITHUB_STARS → PILOTDECK_GITHUB_STARS
- ~/.claude-code-ui/plugins/ → ~/.pilotdeck/plugins/
- claudecodeui-server → pilotdeck-server
- edgeClawConfig i18n key → pilotDeckConfig (248 refs in TSX + settings.json)
- claude-code-main source provenance comments → generic descriptions
- CloudCLI user-facing strings → PilotDeck
- DEFAULT_PROVIDER_FALLBACK "edgeclaw" → "pilotdeck"
- .claude/ config home → .pilotdeck/ in cron daemon services
Co-authored-by: Cursor <cursoragent@cursor.com>
| 9 天前 |
| chore(branding): complete cleanup of legacy CloudCLI/Claude Code references
- CLOUDCLI_DISABLE_LOCAL_AUTH → PILOTDECK_DISABLE_LOCAL_AUTH
- CLOUDCLI_CRON_DAEMON_* → PILOTDECK_CRON_DAEMON_*
- CLOUDCLI_GITHUB_STARS → PILOTDECK_GITHUB_STARS
- ~/.claude-code-ui/plugins/ → ~/.pilotdeck/plugins/
- claudecodeui-server → pilotdeck-server
- edgeClawConfig i18n key → pilotDeckConfig (248 refs in TSX + settings.json)
- claude-code-main source provenance comments → generic descriptions
- CloudCLI user-facing strings → PilotDeck
- DEFAULT_PROVIDER_FALLBACK "edgeclaw" → "pilotdeck"
- .claude/ config home → .pilotdeck/ in cron daemon services
Co-authored-by: Cursor <cursoragent@cursor.com>
| 9 天前 |
| chore: scrub stale claudecodeui/claude-code-main residuals
Remove legacy brand leftovers from the pre-PilotDeck era so the repo
stops mentioning unrelated upstream projects and stops carrying parity
fixtures that point at a third-party tree no longer present.
- Drop src/context/memory/edgeclaw-memory-core/README.md (old CloudCLI
install guide that referenced a claude-code-main/ sibling dir).
- Delete tests + fixtures whose only purpose was to assert byte-for-byte
parity against third-party/claude-code-main/** (legacy-behavior tool
scenarios, dual-parity legacy context scenarios, the parity test
helper, and the six parity-* tests that consumed them).
- Rewrite stale code comments in apps/desktop, src/context/compaction,
src/agent/sub, src/context/memory/.../app.css and PermissionsSettingsTab
to drop dangling third-party/claude-code-main/... mirror references
and rename claudecodeui -> PilotDeck ui/server / ui shell.
- Repoint the auth-screen "PilotDeck is open source" footer link from
github.com/siteboon/claudecodeui to github.com/OpenBMB/PilotDeck.
- Align memory source tag written by ui/server with the one used by
the in-process src/** provider (claudecodeui -> pilotdeck) so the
memory_turns SQLite column is consistent across both write paths.
- Update VAPID web-push contact mailto domain (claudecodeui.local ->
pilotdeck.local).
- Drop two stale .gitignore entries for bundle tarballs that the current
build pipeline never produces.
CCR (/api/ccr/* routes, CCRConfig types, <ccr-subagent-model> tag,
CCR_SENTINEL) is intentionally untouched — those are kept for frontend
back-compat. Comparison mentions of "Claude Code" / "Claude Sonnet 4.6"
in README marketing copy are also intentional and untouched.
Co-authored-by: Cursor <cursoragent@cursor.com>
| 8 天前 |
| chore: add PilotDeck label to notification orchestrator
- Introduced 'PilotDeck' label in the PROVIDER_LABELS object to support recent integration efforts.
| 6 天前 |
| feat(todo): add TodoWrite plan execution flow
Require plan-driven sessions to initialize and refresh TodoWrite checklists before side-effecting tools run, and render markdown todo updates in the web UI.
Co-authored-by: Cursor <cursoragent@cursor.com>
| 15 天前 |
| fix: purge any provider with placeholder apiKey on config save
Legacy deployments bootstrapped with a real provider name (openrouter)
plus the sentinel apiKey. After onboarding added a real provider, the
stale openrouter entry with PLACEHOLDER_RUN_ONBOARDING_TO_REPLACE
lingered. Now purgeBootstrapPlaceholder removes any provider whose
apiKey matches the sentinel, and rewrites orphaned router refs.
Co-authored-by: Cursor <cursoragent@cursor.com>
| 6 天前 |
| refactor(ui-server): retire ~/.edgeclaw/config.yaml in favor of ~/.pilotdeck/pilotdeck.yaml (L3)
Bridges ui/server config to the same YAML file the PolitDeck gateway
already reads, eliminating dual-source drift between what the UI's
Settings tab shows and what the gateway runtime actually loads.
* services/pilotdeckConfig.js — replaces edgeclawConfig.js. Reads
~/.pilotdeck/pilotdeck.yaml (PILOTDECK_CONFIG_PATH overrides), maps
the gateway-native model.providers.<id>.{url,apiKey,models} /
agent.model shape onto the ui-internal models.providers/entries
+ agents.main.model shape via a bidirectional schema adapter, and
preserves non-UI metadata (displayName / capabilities / multimodal)
on write-back via read-modify-write.
* services/pilotdeckConfigReloader.js — replaces edgeclawConfigReloader.js.
Drops the dead CCR-router and EdgeClaw-IM-gateway reload branches
(both retired during the PilotDeck-only migration); keeps env-apply
and memory-scheduler reload. Proxy restart hook renamed to
pilotdeck:restart-proxy.
* services/pilotdeckConfigWatcher.js — replaces edgeclawConfigWatcher.js.
Watches ~/.pilotdeck/pilotdeck.yaml for external edits.
* Schema sweep: deleted ~600 lines of dead schema — channels.*
(Feishu / Telegram / Discord / Slack / Matrix / Mattermost / Email /
SMS / iMessage / 5+ other IM platforms), the embedded EdgeClaw IM
gateway.* segment (separate from src/gateway), and the CCR
router.* segment. None had a remaining consumer in ui/server after
the PilotDeck-only migration — the schema kept them only as defaults
that no code read. The new pilotdeckConfig.js schema fits in ~130
lines.
* load-env.js — rewritten as load-env for PilotDeck. Drops the
EDGECLAW_API_BASE_URL/API_KEY/MODEL startup sanity check (those env
vars had no consumer in ui/server; chat goes through pilotdeck-bridge
→ src/gateway, which reads pilotdeck.yaml directly).
* Env var rename throughout: EDGECLAW_PROXY_PORT → PILOTDECK_PROXY_PORT,
EDGECLAW_MEMORY_* → PILOTDECK_MEMORY_*, EDGECLAW_CRON_DAEMON_LOG →
PILOTDECK_CRON_DAEMON_LOG, EDGECLAW_CONFIG_PATH → PILOTDECK_CONFIG_PATH.
cron daemon log default moved to ~/.pilotdeck/cron-daemon.log.
* Function / file / process-event rename: getEdgeClawConfigPath →
getPilotDeckConfigPath, ensureEdgeClawProxyRunning →
ensurePilotDeckProxyRunning, startEdgeClawConfigWatcher →
startPilotDeckConfigWatcher, edgeclaw:restart-proxy →
pilotdeck:restart-proxy, edgeclaw:config-broadcast →
pilotdeck:config-broadcast.
* Routes (routes/config.js, routes/memory.js) and memoryService.js
switched to read/write through the new module.
* normalizePilotDeckConfig() made idempotent — it accepts either the
raw pilotdeck.yaml shape (has model / agent.model) or an already-
normalized ui-internal config (has models / agents) and routes
to the right path. Fixes a "未找到项目" / providers-disappear bug
caused by /api/config running the adapter twice over already-
normalized state.
Co-authored-by: Cursor <cursoragent@cursor.com>
| 22 天前 |
| fix(ui-server): serve disk YAML untouched in Raw view and watcher broadcasts
The Raw YAML view was lossy because the response pipeline always re-
synthesized raw via configToYaml(maskedInternal), which internally
calls adaptInternalToPilotDeckYaml(normalized, {}). Two losses
happen on every read:
1. adaptPilotDeckYamlToInternal only extracts what ui-internal
models — model.providers, agent.model, webui.runtime/memory —
so router/gateway/adapters/extension/cron/alwaysOn and the rich
sub-fields (capabilities, multimodal, displayName, aliases,
retry, agent.fallbackModel/params) are stripped on the way in.
2. The reverse adapter takes a rawYaml base for read-modify-write
preservation, but configToYaml passed {}, so anything not
in ui-internal had no chance to survive the round-trip.
End result: a 9-segment / 129-line disk file showed up in Settings as
4 segments / much shorter, and the Gateway-side configuration
(router/gateway/adapters/...) was invisible to the user.
Gateway already maintains its own PilotConfigStore with fs.watch
(src/pilot/config/PilotConfigStore.ts), so the only fix needed on
the UI server is to stop dropping those segments when surfacing the
file. We don't need to teach UI server about the gateway schema.
This commit handles the read path only:
- Add rawYamlToMaskedString(rawYaml) — masks secrets directly on
the parsed disk object and stringifies. Lossless.
- serializeConfigResponse prefers rawYamlToMaskedString(record.rawYaml)
when the disk file exists; falls back to the old configToYaml
template only for the bootstrap case (fresh install, no file yet)
so the editor still has a usable starting point.
- After PUT /api/config completes, re-read the disk so the response
uses the new rawYaml (the previous code passed `{exists, raw,
config}` only, missing rawYaml — that would have made the masked
response inadvertently fall back to the lossy template).
- pilotdeckConfigWatcher broadcasts use the same path, so vim / IDE
/ external edits trigger a hot-reload to the UI with the complete
YAML.
The JSON config field is unchanged (still lossy ui-internal) for
backward compatibility with structured editors (provider picker,
memory editor, onboarding) that consume it. Write path will be
addressed in a follow-up.
Verified end-to-end with a synthetic 9-segment YAML: all of
schemaVersion/agent/model/router/gateway/adapters/extension/cron/
alwaysOn/webui survive the round-trip, every apiKey is masked to
"********", and the no-file bootstrap path still renders the
default template.
Note for future contributors: 2eeeb13 tried this same approach but
was reverted alongside 47cd5f6, which made the write path require
req.body.raw and broke onboarding's req.body.config callers.
Read and write are split into separate commits this time so neither
side can drag the other down.
Co-authored-by: Cursor <cursoragent@cursor.com>
| 20 天前 |
| feat(ui): rewrite ui/ with EdgeClaw-derived front-end and pilotdeck bridge backend
Replaces the 4-file Vite demo (gateway-browser-client, main.tsx,
styles.css, vite.config.ts) with the full EdgeClaw-derived UI plus an
Express bridge that talks to src/gateway through pilotdeck-bridge.js,
unblocking dev-mode HMR and parity testing while the migration to the
gateway-only architecture (docs/old-ui-adaptation/04-implementation-plan)
is in flight.
- ui/server: Express bridge serving /api/* and /ws, providers / agent /
git / mcp / memory / projects / sessions routes, cron + always-on
daemon plumbing, vapid push, plugin process manager.
- ui/src: React 18 app — chat-v2 UI, app-shell, code editor, files,
git, mcp, memory, projects, settings, skills, tasks, terminals,
i18n, contexts, hooks, stores, etc.
- ui/src/stores/useSessionStore.ts: session-keyed message store with a
same-turn streaming dedup guard — fixes a bug where a NEW turn's
__streaming_<sid> message would splice out the PREVIOUS turn's
legitimate assistant tail in computeMerged, dropping the prior
assistant reply and reordering the new user message after the new
streaming row.
- ui/public: PWA manifest, icons, screenshots, service worker.
- Build/lint/typecheck config: vite.config.js (with /api /ws /shell
proxy + manualChunks split), tailwind, postcss, eslint, tsconfig,
.nvmrc (v22), node-pty postinstall fixup.
Co-authored-by: Cursor <cursoragent@cursor.com>
| 24 天前 |
| chore: scrub stale claudecodeui/claude-code-main residuals
Remove legacy brand leftovers from the pre-PilotDeck era so the repo
stops mentioning unrelated upstream projects and stops carrying parity
fixtures that point at a third-party tree no longer present.
- Drop src/context/memory/edgeclaw-memory-core/README.md (old CloudCLI
install guide that referenced a claude-code-main/ sibling dir).
- Delete tests + fixtures whose only purpose was to assert byte-for-byte
parity against third-party/claude-code-main/** (legacy-behavior tool
scenarios, dual-parity legacy context scenarios, the parity test
helper, and the six parity-* tests that consumed them).
- Rewrite stale code comments in apps/desktop, src/context/compaction,
src/agent/sub, src/context/memory/.../app.css and PermissionsSettingsTab
to drop dangling third-party/claude-code-main/... mirror references
and rename claudecodeui -> PilotDeck ui/server / ui shell.
- Repoint the auth-screen "PilotDeck is open source" footer link from
github.com/siteboon/claudecodeui to github.com/OpenBMB/PilotDeck.
- Align memory source tag written by ui/server with the one used by
the in-process src/** provider (claudecodeui -> pilotdeck) so the
memory_turns SQLite column is consistent across both write paths.
- Update VAPID web-push contact mailto domain (claudecodeui.local ->
pilotdeck.local).
- Drop two stale .gitignore entries for bundle tarballs that the current
build pipeline never produces.
CCR (/api/ccr/* routes, CCRConfig types, <ccr-subagent-model> tag,
CCR_SENTINEL) is intentionally untouched — those are kept for frontend
back-compat. Comparison mentions of "Claude Code" / "Claude Sonnet 4.6"
in README marketing copy are also intentional and untouched.
Co-authored-by: Cursor <cursoragent@cursor.com>
| 8 天前 |