Compare commits

..

42 Commits

Author SHA1 Message Date
simosmik
863a98d583 chore: merge refactor/split-server-index into refactor/providers (brings main up to v1.29.5) 2026-04-17 08:47:36 +00:00
simosmik
acfa7cfffb chore: merge main into refactor/split-server-index (up to v1.29.5) 2026-04-17 08:39:36 +00:00
simosmik
3e99187a01 chore: add dist-server to gitignore 2026-04-17 08:21:18 +00:00
viper151
25b00b58de chore(release): v1.29.5 2026-04-16 11:02:31 +00:00
simosmik
6a13e1773b fix: update node-pty to latest version 2026-04-16 10:52:55 +00:00
viper151
6102b74455 chore(release): v1.29.4 2026-04-16 10:33:45 +00:00
Simos Mikelatos
9ef1ab533d Refactor CLI authentication module location (#660)
* refactor: move cli-auth.js to the providers folder

* fix: expired oauth token returns no error message
2026-04-16 12:32:25 +02:00
simosmik
e9c7a5041c feat: deleting from sidebar will now ask whether to remove all data as well 2026-04-16 09:05:56 +00:00
simosmik
289520814c refactor: remove the sqlite3 dependency 2026-04-16 08:37:59 +00:00
simosmik
09486016e6 chore: upgrade commit lint to 20.5.0 2026-04-16 08:08:36 +00:00
simosmik
4c106a5083 fix: pass pathToClaudeCodeExecutable to SDK when CLAUDE_CLI_PATH is set
Closes #468
2026-04-16 07:58:32 +00:00
simosmik
ef916615f8 refactor: creating providers placeholders and barrel file 2026-04-16 07:51:17 +00:00
Simos Mikelatos
63e996bb77 refactor(server): extract URL detection and color utils from index.js (#657)
No behavioral changes — 1:1 code move with imports replacing inline definitions.
2026-04-16 09:46:09 +02:00
Simos Mikelatos
9ddda5ba5e Merge branch 'main' into refactor/split-server-index 2026-04-16 09:45:52 +02:00
viper151
fbad3a90f8 chore(release): v1.29.3 2026-04-15 12:02:27 +00:00
Haile
96463df8da Feature/backend ts support andunification of auth settings on frontend (#654)
* fix: remove project dependency from settings controller and onboarding

* fix(settings): remove onClose prop from useSettingsController args

* chore: tailwind classes order

* refactor: move provider auth status management to custom hook

* refactor: rename SessionProvider to LLMProvider

* feat(frontend): support for @ alias based imports)

* fix: replace init.sql with schema.js

* fix: refactor database initialization to use schema.js for SQL statements

* feat(server): add a real backend TypeScript build and enforce module boundaries

The backend had started to grow beyond what the frontend-only tooling setup could
support safely. We were still running server code directly from /server, linting
mainly the client, and relying on path assumptions such as "../.." that only
worked in the source layout. That created three problems:

- backend alias imports were hard to resolve consistently in the editor, ESLint,
  and the runtime
- server code had no enforced module boundary rules, so cross-module deep imports
  could bypass intended public entry points
- building the backend into a separate output directory would break repo-level
  lookups for package.json, .env, dist, and public assets because those paths
  were derived from source-only relative assumptions

This change makes the backend tooling explicit and runtime-safe.

A dedicated backend TypeScript config now lives in server/tsconfig.json, with
tsconfig.server.json reduced to a compatibility shim. This gives the language
service and backend tooling a canonical project rooted in /server while still
preserving top-level compatibility for any existing references. The backend alias
mapping now resolves relative to /server, which avoids colliding with the
frontend's "@/..." -> "src/*" mapping.

The package scripts were updated so development runs through tsx with the backend
tsconfig, build now produces a compiled backend in dist-server, and typecheck/lint
cover both client and server. A new build-server.mjs script runs TypeScript and
tsc-alias and cleans dist-server first, which prevents stale compiled files from
shadowing current source files after refactors.

To make the compiled backend behave the same as the source backend, runtime path
resolution was centralized in server/utils/runtime-paths.js. Instead of assuming
fixed relative paths from each module, server entry points now resolve the actual
app root and server root at runtime. That keeps package.json, .env, dist, public,
and default database paths stable whether code is executed from /server or from
/dist-server/server.

ESLint was expanded from a frontend-only setup into a backend-aware one. The
backend now uses import resolution tied to the backend tsconfig so aliased imports
resolve correctly in linting, import ordering matches the frontend style, and
unused/duplicate imports are surfaced consistently.

Most importantly, eslint-plugin-boundaries now enforces server module boundaries.
Files under server/modules can no longer import another module's internals
directly. Cross-module imports must go through that module's barrel file
(index.ts/index.js). boundaries/no-unknown was also enabled so alias-resolution
gaps cannot silently bypass the rule.

Together, these changes make the backend buildable, keep runtime path resolution
stable after compilation, align server tooling with the client where appropriate,
and enforce a stricter modular architecture for server code.

* fix: update package.json to include dist-server in files and remove tsconfig.server.json

* refactor: remove build-server.mjs and inline its logic into package.json scripts

* fix: update paths in package.json and bin.js to use dist-server directory

* feat(eslint): add backend shared types and enforce compile-time contract for imports

* fix(eslint): update shared types pattern

---------

Co-authored-by: Haileyesus <something@gmail.com>
2026-04-15 13:26:12 +02:00
simosmik
9f99f6ab53 refactor(server): extract URL detection and color utils from index.js
No behavioral changes — 1:1 code move with imports replacing inline definitions.
2026-04-14 22:15:05 +00:00
simosmik
31f28a2c18 chore: remove unused route (migrated to providers already) 2026-04-14 21:58:53 +00:00
Simos Mikelatos
8ff5f35c05 Update model constants for Opus and Gemini versions 2026-04-14 23:06:43 +02:00
Haile
641304242d fix(version-upgrade-modal): implement reload countdown and update UI messages (#655)
Co-authored-by: Haileyesus <something@gmail.com>
2026-04-14 23:02:20 +02:00
viper151
c3599cd2c4 chore(release): v1.29.2 2026-04-14 18:16:20 +00:00
simosmik
9b11c034d9 fix(sandbox): use backgrounded sbx run to keep sandbox alive 2026-04-14 18:14:58 +00:00
viper151
b6d19201b6 chore(release): v1.29.1 2026-04-14 17:38:53 +00:00
simosmik
4a569725da fix: add latest tag to docker npx command and change the detach mode to work without spawn 2026-04-14 17:37:20 +00:00
viper151
6ce3306947 chore(release): v1.29.0 2026-04-14 15:20:18 +00:00
Haile
d0dd007d0f Feature/restart server on update (#652)
* feat: support restart server on update for platform

* feat: add update platform script to package.json

* feat: optimize platform update command by omitting dev dependencies

* feat: simplify update commands for platform

---------

Co-authored-by: Haileyesus <something@gmail.com>
Co-authored-by: Simos Mikelatos <simosmik@gmail.com>
2026-04-14 17:18:47 +02:00
simosmik
13e97e2c71 feat: adding docker sandbox environments 2026-04-14 15:18:02 +00:00
Haile
c7a5baf147 fix(thinking-mode): fix dropdown positioning (#646) 2026-04-13 11:44:31 +02:00
simosmik
e2459cb0f8 chore: update release flow node version 2026-04-10 14:56:33 +00:00
viper151
9552577e94 chore(release): v1.28.1 2026-04-10 13:36:05 +00:00
Haile
590dd42649 refactor: remove unused whispher transcribe logic (#637) 2026-04-10 15:34:34 +02:00
simosmik
2207d05c1c feat: add branding, community links, GitHub star badge, and About settings tab 2026-04-10 13:06:16 +00:00
Haile
a8dab0edcf fix(ui): remove mobile bottom nav, unify processing indicator, and improve tooltip behavior on mobile (#632)
* fix: update tooltip component

* fix: remove the mobile navigation component

In addition,
- the sidebar is also updated to take full space
- the terminal shortcuts in shell are updated to not interfere with the
shell content.

* fix: remove mobile nav component

* fix: remove "Thinking..." indicator

In addition, the claude status component has been restyled to be more
compact and less obtrusive.
- The type and prop arguments for ChatMessagesPane have been updated to
remove the isLoading prop, which was only used to control the display of
 the AssistantThinkingIndicator.

* fix: show elapsed time only when loading

---------

Co-authored-by: Haileyesus <something@gmail.com>
Co-authored-by: Simos Mikelatos <simosmik@gmail.com>
2026-04-10 12:36:06 +02:00
Haile
e61f8a543d fix: corrupted binary downloads (#634)
- The existing setup was using the text reader endpoint for downloading
files `fsPromises.readFile(..., 'utf8')` at line 801. This was incorrect

- In the old Files tab flow, the client then took that decoded string
and rebuilt it as a text blob. That UTF-8 decode/re-encode step changes
raw bytes, so the downloaded file no longer matches the original.
Folder ZIP export had the same problem for any binary file inside the
archive.

Co-authored-by: Haileyesus <something@gmail.com>
2026-04-10 12:35:23 +02:00
simosmik
388134c7a5 chore(release): v1.28.0 2026-04-03 15:41:05 +00:00
simosmik
ef51de259e chore: changing package name to @cloudcli-ai/cloudcli 2026-04-03 15:37:49 +00:00
simosmik
1628868470 feat: moving new session button higher 2026-03-31 20:53:20 +00:00
simosmik
8f1042cf25 feat: adding session resume in the api 2026-03-29 20:58:56 +00:00
viper151
051a6b1e74 chore(release): v1.27.1 2026-03-29 01:15:38 +00:00
simosmik
f1063fd339 chore: release tokens 2026-03-29 01:13:13 +00:00
simosmik
27cd12432b chore: relicense to AGPL-3.0-or-later
Siteboon AI B.V. contributions relicensed from GPL-3.0 to
AGPL-3.0-or-later. Existing community contributions remain
under GPL-3.0, combined per GPL-3.0 Section 13.
Adds Section 7 additional terms (attribution, origin
protection, publicity restriction, trademark).
2026-03-29 00:57:09 +00:00
simosmik
004135ef01 chore: add terminal plugin in the plugins list
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 10:38:00 +00:00
386 changed files with 5819 additions and 43299 deletions

View File

@@ -1,47 +0,0 @@
name: Cross Platform Server Verification
on:
pull_request:
push:
workflow_dispatch:
jobs:
verify:
name: Verify on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
- ubuntu-latest
- windows-latest
node:
- 22
steps:
# This step checks out the repository so the matrix job can build and test it.
- name: Checkout repository
uses: actions/checkout@v4
# This step installs the Node.js version the README already declares as the project baseline.
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
cache: npm
# This step installs dependencies exactly as locked so native and shell behavior stays reproducible.
- name: Install dependencies
run: npm ci
# This step verifies the TypeScript server code before runtime checks.
- name: Typecheck server
run: npm run typecheck:server
# This step runs the built-in Node tests that exercise the OS adapter layer directly.
- name: Test server adapters
run: npm run test:server
# This step ensures the in-progress TypeScript backend still compiles in each OS environment.
- name: Build server
run: npm run server:build

View File

@@ -20,13 +20,14 @@ jobs:
contents: write
id-token: write
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
fetch-depth: 0
token: ${{ secrets.RELEASE_PAT }}
- uses: actions/setup-node@v4
- uses: actions/setup-node@v6
with:
node-version: 20
node-version: 22
registry-url: https://registry.npmjs.org
- name: git config
@@ -44,6 +45,6 @@ jobs:
fi
npx release-it $ARGS
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.RELEASE_PAT }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

3
.gitignore vendored
View File

@@ -8,8 +8,7 @@ lerna-debug.log*
# Build outputs
dist/
server/dist/
dist-ssr/
dist-server/
build/
out/

View File

@@ -6,7 +6,8 @@
"requireCleanWorkingDir": true
},
"npm": {
"publish": true
"publish": true,
"publishArgs": ["--access public"]
},
"github": {
"release": true,

View File

@@ -3,6 +3,106 @@
All notable changes to CloudCLI UI will be documented in this file.
## [1.29.5](https://github.com/siteboon/claudecodeui/compare/v1.29.4...v1.29.5) (2026-04-16)
### Bug Fixes
* update node-pty to latest version ([6a13e17](https://github.com/siteboon/claudecodeui/commit/6a13e1773b145049ade512aa6e5cac21c2e5c4de))
## [1.29.4](https://github.com/siteboon/claudecodeui/compare/v1.29.3...v1.29.4) (2026-04-16)
### New Features
* deleting from sidebar will now ask whether to remove all data as well ([e9c7a50](https://github.com/siteboon/claudecodeui/commit/e9c7a5041c31a6f7b2032f06abe19c52d3d4cd8c))
### Bug Fixes
* pass pathToClaudeCodeExecutable to SDK when CLAUDE_CLI_PATH is set ([4c106a5](https://github.com/siteboon/claudecodeui/commit/4c106a5083d90989bbeedaefdbb68f5b3fa6fd58)), closes [#468](https://github.com/siteboon/claudecodeui/issues/468)
### Refactoring
* remove the sqlite3 dependency ([2895208](https://github.com/siteboon/claudecodeui/commit/289520814cf3ca36403056739ef22021f78c6033))
* **server:** extract URL detection and color utils from index.js ([#657](https://github.com/siteboon/claudecodeui/issues/657)) ([63e996b](https://github.com/siteboon/claudecodeui/commit/63e996bb77cfa97b1f55f6bdccc50161a75a3eee))
### Maintenance
* upgrade commit lint to 20.5.0 ([0948601](https://github.com/siteboon/claudecodeui/commit/09486016e67d97358c228ebc6eb4502ccb0012e4))
## [1.29.3](https://github.com/siteboon/claudecodeui/compare/v1.29.2...v1.29.3) (2026-04-15)
### Bug Fixes
* **version-upgrade-modal:** implement reload countdown and update UI messages ([#655](https://github.com/siteboon/claudecodeui/issues/655)) ([6413042](https://github.com/siteboon/claudecodeui/commit/641304242d7705b54aab65faa4a7673438c92c60))
### Maintenance
* remove unused route (migrated to providers already) ([31f28a2](https://github.com/siteboon/claudecodeui/commit/31f28a2c183f6ead50941027632d7ab64b7bb2d4))
## [1.29.2](https://github.com/siteboon/claudecodeui/compare/v1.29.1...v1.29.2) (2026-04-14)
### Bug Fixes
* **sandbox:** use backgrounded sbx run to keep sandbox alive ([9b11c03](https://github.com/siteboon/claudecodeui/commit/9b11c034d9a19710a23b56c62dcf07c21a17bd97))
## [1.29.1](https://github.com/siteboon/claudecodeui/compare/v1.29.0...v1.29.1) (2026-04-14)
### Bug Fixes
* add latest tag to docker npx command and change the detach mode to work without spawn ([4a56972](https://github.com/siteboon/claudecodeui/commit/4a569725dae320a505753359d8edfd8ca79f0fd7))
## [1.29.0](https://github.com/siteboon/claudecodeui/compare/v1.28.1...v1.29.0) (2026-04-14)
### New Features
* adding docker sandbox environments ([13e97e2](https://github.com/siteboon/claudecodeui/commit/13e97e2c71254de7a60afb5495b21064c4bc4241))
### Bug Fixes
* **thinking-mode:** fix dropdown positioning ([#646](https://github.com/siteboon/claudecodeui/issues/646)) ([c7a5baf](https://github.com/siteboon/claudecodeui/commit/c7a5baf1479404bd40e23aa58bd9f677df9a04c6))
### Maintenance
* update release flow node version ([e2459cb](https://github.com/siteboon/claudecodeui/commit/e2459cb0f8b35f54827778a7b444e6c3ca326506))
## [1.28.1](https://github.com/siteboon/claudecodeui/compare/v1.28.0...v1.28.1) (2026-04-10)
### New Features
* add branding, community links, GitHub star badge, and About settings tab ([2207d05](https://github.com/siteboon/claudecodeui/commit/2207d05c1ca229214aa9c2e2c9f4d0827d421574))
### Bug Fixes
* corrupted binary downloads ([#634](https://github.com/siteboon/claudecodeui/issues/634)) ([e61f8a5](https://github.com/siteboon/claudecodeui/commit/e61f8a543d63fe7c24a04b3d2186085a06dcbcdb))
* **ui:** remove mobile bottom nav, unify processing indicator, and improve tooltip behavior on mobile ([#632](https://github.com/siteboon/claudecodeui/issues/632)) ([a8dab0e](https://github.com/siteboon/claudecodeui/commit/a8dab0edcf949ae610820bae9500c433781f7c73))
### Refactoring
* remove unused whispher transcribe logic ([#637](https://github.com/siteboon/claudecodeui/issues/637)) ([590dd42](https://github.com/siteboon/claudecodeui/commit/590dd42649424ab990353fcf59ce0965036d3d25))
## [1.28.0](https://github.com/siteboon/claudecodeui/compare/v1.27.1...v1.28.0) (2026-04-03)
### New Features
* adding session resume in the api ([8f1042c](https://github.com/siteboon/claudecodeui/commit/8f1042cf256be282f009adcceeb55ab2dddf3fba))
* moving new session button higher ([1628868](https://github.com/siteboon/claudecodeui/commit/16288684702dec894cf054291ca3d545ddb8214b))
### Maintenance
* changing package name to @cloudcli-ai/cloudcli ([ef51de2](https://github.com/siteboon/claudecodeui/commit/ef51de259ea2b963bc15f058b084e11220bc216a))
## [1.27.1](https://github.com/siteboon/claudecodeui/compare/v1.26.3...v1.27.1) (2026-03-29)
### Bug Fixes
* prevent split on undefined[#491](https://github.com/siteboon/claudecodeui/issues/491) ([#563](https://github.com/siteboon/claudecodeui/issues/563)) ([b54cdf8](https://github.com/siteboon/claudecodeui/commit/b54cdf8168fc224e9907796e4229ae8ed34e6885))
### Maintenance
* add release-it github action ([42a1313](https://github.com/siteboon/claudecodeui/commit/42a131389a6954df0d2c3bedd2cb6d3406c5ebc1))
* add terminal plugin in the plugins list ([004135e](https://github.com/siteboon/claudecodeui/commit/004135ef0187023e1da29c4a7137a28a42ebf9af))
* release tokens ([f1063fd](https://github.com/siteboon/claudecodeui/commit/f1063fd33964ccb517f5ebcdd14526ed162e1138))
* relicense to AGPL-3.0-or-later ([27cd124](https://github.com/siteboon/claudecodeui/commit/27cd12432b7d3237981f86acd9cc99532d843d4a))
## [1.26.3](https://github.com/siteboon/claudecodeui/compare/v1.26.2...v1.26.3) (2026-03-22)
## [1.26.2](https://github.com/siteboon/claudecodeui/compare/v1.26.0...v1.26.2) (2026-03-21)

View File

@@ -153,4 +153,4 @@ This automatically:
## License
By contributing, you agree that your contributions will be licensed under the [GPL-3.0 License](LICENSE).
By contributing, you agree that your contributions will be licensed under the [AGPL-3.0-or-later License](LICENSE), including the additional terms specified in Section 7 of the LICENSE file.

789
LICENSE

File diff suppressed because it is too large Load Diff

13
NOTICE Normal file
View File

@@ -0,0 +1,13 @@
CloudCLI UI
Copyright 2025-2026 Siteboon AI B.V. and contributors
This software is licensed under the GNU Affero General Public License v3.0
or later (AGPL-3.0-or-later). See the LICENSE file for the full license text,
including additional terms under Section 7.
Originally developed by Siteboon AI B.V. (https://github.com/siteboon/claudecodeui).
Contributions by Siteboon AI B.V. prior to commit 004135ef were originally
published under GPL-3.0 and are hereby relicensed to AGPL-3.0-or-later.
Contributions by other authors prior to that commit remain under GPL-3.0
and are incorporated into this work as permitted by GPL-3.0 Section 13.

View File

@@ -76,16 +76,18 @@ Der schnellste Einstieg keine lokale Einrichtung erforderlich. Erhalte eine
### Self-Hosted (Open Source)
#### npm
CloudCLI UI sofort mit **npx** ausprobieren (erfordert **Node.js** v22+):
```bash
npx @siteboon/claude-code-ui
npx @cloudcli-ai/cloudcli
```
Oder **global** installieren für regelmäßige Nutzung:
```bash
npm install -g @siteboon/claude-code-ui
npm install -g @cloudcli-ai/cloudcli
cloudcli
```
@@ -93,6 +95,15 @@ cloudcli
Die **[Dokumentation →](https://cloudcli.ai/docs)** enthält weitere Konfigurationsoptionen, PM2, Remote-Server-Einrichtung und mehr.
#### Docker Sandboxes (Experimentell)
Agents in isolierten Sandboxes mit Hypervisor-Isolation ausführen. Standardmäßig wird Claude Code gestartet. Erfordert die [`sbx` CLI](https://docs.docker.com/ai/sandboxes/get-started/).
```
npx @cloudcli-ai/cloudcli@latest sandbox ~/my-project
```
Unterstützt Claude Code, Codex und Gemini CLI. Weitere Details in der [Sandbox-Dokumentation](docker/).
---
@@ -104,7 +115,7 @@ CloudCLI UI ist die Open-Source-UI-Schicht, die CloudCLI Cloud antreibt. Du kann
|---|---|---|
| **Am besten für** | Entwickler:innen, die eine vollständige UI für lokale Agent-Sitzungen auf ihrem eigenen Rechner möchten | Teams und Entwickler:innen, die Agents in der Cloud betreiben möchten, überall erreichbar |
| **Zugriff** | Browser via `[deineIP]:port` | Browser, jede IDE, REST API, n8n |
| **Einrichtung** | `npx @siteboon/claude-code-ui` | Keine Einrichtung erforderlich |
| **Einrichtung** | `npx @cloudcli-ai/cloudcli` | Keine Einrichtung erforderlich |
| **Rechner muss laufen** | Ja | Nein |
| **Mobiler Zugriff** | Jeder Browser im Netzwerk | Jedes Gerät, native App in Entwicklung |
| **Verfügbare Sitzungen** | Alle Sitzungen automatisch aus `~/.claude` erkannt | Alle Sitzungen in deiner Cloud-Umgebung |

View File

@@ -72,16 +72,18 @@
### セルフホスト(オープンソース)
#### npm
**npx** で今すぐ CloudCLI UI を試せます(**Node.js** v22+ が必要):
```bash
npx @siteboon/claude-code-ui
npx @cloudcli-ai/cloudcli
```
または、普段使いするなら **グローバル** にインストール:
```bash
npm install -g @siteboon/claude-code-ui
npm install -g @cloudcli-ai/cloudcli
cloudcli
```
@@ -89,6 +91,15 @@ cloudcli
より詳細な設定オプション、PM2、リモートサーバー設定などについては **[ドキュメントはこちら →](https://cloudcli.ai/docs)** を参照してください。
#### Docker Sandboxes実験的
ハイパーバイザーレベルの分離でエージェントをサンドボックスで実行します。デフォルトでは Claude Code が起動します。[`sbx` CLI](https://docs.docker.com/ai/sandboxes/get-started/) が必要です。
```
npx @cloudcli-ai/cloudcli@latest sandbox ~/my-project
```
Claude Code、Codex、Gemini CLI に対応。詳細は[サンドボックスのドキュメント](docker/)をご覧ください。
---
@@ -100,7 +111,7 @@ CloudCLI UI は、CloudCLI Cloud を支えるオープンソースの UI レイ
|---|---|---|
| **対象ユーザー** | 自分のマシン上でローカルの agent セッションに対してフル UI を使いたい開発者 | クラウド上で動く agents をどこからでも利用したいチーム/開発者 |
| **アクセス方法** | ブラウザ(`[yourip]:port` | ブラウザ、任意の IDE、REST API、n8n |
| **セットアップ** | `npx @siteboon/claude-code-ui` | セットアップ不要 |
| **セットアップ** | `npx @cloudcli-ai/cloudcli` | セットアップ不要 |
| **マシンの稼働継続** | はい | いいえ |
| **モバイルアクセス** | 同一ネットワーク内の任意のブラウザ | 任意のデバイス(ネイティブアプリも準備中) |
| **利用可能なセッション** | `~/.claude` から全セッションを自動検出 | クラウド環境内の全セッション |

View File

@@ -72,22 +72,34 @@
### 셀프 호스트 (오픈 소스)
#### npm
**npx**로 즉시 CloudCLI UI를 실행하세요 (Node.js v22+ 필요):
```bash
npx @siteboon/claude-code-ui
npx @cloudcli-ai/cloudcli
```
**정기적으로 사용한다면 전역 설치:**
```bash
npm install -g @siteboon/claude-code-ui
npm install -g @cloudcli-ai/cloudcli
cloudcli
```
`http://localhost:3001`을 열면 기존 세션이 자동으로 발견됩니다.
자세한 구성 옵션, PM2, 원격 서버 설정 등은 **[문서 →](https://cloudcli.ai/docs)**를 참고하세요
자세한 구성 옵션, PM2, 원격 서버 설정 등은 **[문서 →](https://cloudcli.ai/docs)**를 참고하세요.
#### Docker Sandboxes (실험적)
하이퍼바이저 수준 격리로 에이전트를 샌드박스에서 실행합니다. 기본 에이전트는 Claude Code입니다. [`sbx` CLI](https://docs.docker.com/ai/sandboxes/get-started/)가 필요합니다.
```
npx @cloudcli-ai/cloudcli@latest sandbox ~/my-project
```
Claude Code, Codex, Gemini CLI를 지원합니다. 자세한 내용은 [샌드박스 문서](docker/)를 참고하세요.
---
@@ -99,7 +111,7 @@ CloudCLI UI는 CloudCLI Cloud를 구동하는 오픈 소스 UI 계층입니다.
|---|---|---|
| **적합한 대상** | 로컬 에이전트 세션을 위한 전체 UI가 필요한 개발자 | 어디서든 접근 가능한 클라우드에서 에이전트를 운영하고자 하는 팀 및 개발자 |
| **접근 방법** | `[yourip]:port`를 통해 브라우저 접속 | 브라우저, IDE, REST API, n8n |
| **설정** | `npx @siteboon/claude-code-ui` | 설정 불필요 |
| **설정** | `npx @cloudcli-ai/cloudcli` | 설정 불필요 |
| **기기 유지 필요 여부** | 예 (머신 켜둬야 함) | 아니오 |
| **모바일 접근** | 네트워크 내 브라우저 | 모든 기기 (네이티브 앱 예정) |
| **세션 접근** | `~/.claude`에서 자동 발견 | 클라우드 환경 내 세션 |

View File

@@ -76,48 +76,58 @@ The fastest way to get started — no local setup required. Get a fully managed,
### Self-Hosted (Open source)
#### npm
Try CloudCLI UI instantly with **npx** (requires **Node.js** v22+):
```
npx @siteboon/claude-code-ui
npx @cloudcli-ai/cloudcli
```
Or install **globally** for regular use:
```
npm install -g @siteboon/claude-code-ui
npm install -g @cloudcli-ai/cloudcli
cloudcli
```
Open `http://localhost:3001` — all your existing sessions are discovered automatically.
Visit the **[documentation →](https://cloudcli.ai/docs)** for more full configuration options, PM2, remote server setup and more
Visit the **[documentation →](https://cloudcli.ai/docs)** for full configuration options, PM2, remote server setup and more.
#### Docker Sandboxes (Experimental)
Run agents in isolated sandboxes with hypervisor-level isolation. Starts Claude Code by default. Requires the [`sbx` CLI](https://docs.docker.com/ai/sandboxes/get-started/).
```
npx @cloudcli-ai/cloudcli@latest sandbox ~/my-project
```
Supports Claude Code, Codex, and Gemini CLI. See the [sandbox docs](docker/) for setup and advanced options.
---
## Which option is right for you?
CloudCLI UI is the open source UI layer that powers CloudCLI Cloud. You can self-host it on your own machine, or use CloudCLI Cloud which builds on top of it with a full managed cloud environment, team features, and deeper integrations.
CloudCLI UI is the open source UI layer that powers CloudCLI Cloud. You can self-host it on your own machine, run it in a Docker sandbox for isolation, or use CloudCLI Cloud for a fully managed environment.
| | CloudCLI UI (Self-hosted) | CloudCLI Cloud |
|---|---|---|
| **Best for** | Developers who want a full UI for local agent sessions on their own machine | Teams and developers who want agents running in the cloud, accessible from anywhere |
| **How you access it** | Browser via `[yourip]:port` | Browser, any IDE, REST API, n8n |
| **Setup** | `npx @siteboon/claude-code-ui` | No setup required |
| **Machine needs to stay on** | Yes | No |
| **Mobile access** | Any browser on your network | Any device, native app coming |
| **Sessions available** | All sessions auto-discovered from `~/.claude` | All sessions within your cloud environment |
| **Agents supported** | Claude Code, Cursor CLI, Codex, Gemini CLI | Claude Code, Cursor CLI, Codex, Gemini CLI |
| **File explorer and Git** | Yes, built into the UI | Yes, built into the UI |
| **MCP configuration** | Managed via UI, synced with your local `~/.claude` config | Managed via UI |
| **IDE access** | Your local IDE | Any IDE connected to your cloud environment |
| **REST API** | Yes | Yes |
| **n8n node** | No | Yes |
| **Team sharing** | No | Yes |
| **Platform cost** | Free, open source | Starts at $7/month |
| | Self-Hosted (npm) | Self-Hosted (Docker Sandbox) *(Experimental)* | CloudCLI Cloud |
|---|---|---|---|
| **Best for** | Local agent sessions on your own machine | Isolated agents with web/mobile IDE | Teams who want agents in the cloud |
| **How you access it** | Browser via `[yourip]:port` | Browser via `localhost:port` | Browser, any IDE, REST API, n8n |
| **Setup** | `npx @cloudcli-ai/cloudcli` | `npx @cloudcli-ai/cloudcli@latest sandbox ~/project` | No setup required |
| **Isolation** | Runs on your host | Hypervisor-level sandbox (microVM) | Full cloud isolation |
| **Machine needs to stay on** | Yes | Yes | No |
| **Mobile access** | Any browser on your network | Any browser on your network | Any device, native app coming |
| **Agents supported** | Claude Code, Cursor CLI, Codex, Gemini CLI | Claude Code, Codex, Gemini CLI | Claude Code, Cursor CLI, Codex, Gemini CLI |
| **File explorer and Git** | Yes | Yes | Yes |
| **MCP configuration** | Synced with `~/.claude` | Managed via UI | Managed via UI |
| **REST API** | Yes | Yes | Yes |
| **Team sharing** | No | No | Yes |
| **Platform cost** | Free, open source | Free, open source | Starts at $7/month |
> Both options use your own AI subscriptions (Claude, Cursor, etc.) — CloudCLI provides the environment, not the AI.
> All options use your own AI subscriptions (Claude, Cursor, etc.) — CloudCLI provides the environment, not the AI.
---
@@ -213,9 +223,11 @@ Yes, for self-hosted. CloudCLI UI reads from and writes to the same `~/.claude`
## License
GNU General Public License v3.0 - see [LICENSE](LICENSE) file for details.
GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later) — see [LICENSE](LICENSE) for the full text, including additional terms under Section 7.
This project is open source and free to use, modify, and distribute under the GPL v3 license.
This project is open source and free to use, modify, and distribute under the AGPL-3.0-or-later license. If you modify this software and run it as a network service, you must make your modified source code available to users of that service.
CloudCLI UI - (https://cloudcli.ai).
## Acknowledgments

View File

@@ -76,23 +76,34 @@
### Self-Hosted (Open source)
#### npm
Попробовать CloudCLI UI можно сразу через **npx** (требуется **Node.js** v22+):
```bash
npx @siteboon/claude-code-ui
npx @cloudcli-ai/cloudcli
```
Или установить **глобально** для регулярного использования:
```bash
npm install -g @siteboon/claude-code-ui
npm install -g @cloudcli-ai/cloudcli
cloudcli
```
Откройте `http://localhost:3001` — все ваши существующие сессии будут обнаружены автоматически.
Посетите **[документацию →](https://cloudcli.ai/docs)**, чтобы узнать про дополнительные варианты конфигурации, PM2, настройку удалённого сервера и многое другое
Посетите **[документацию →](https://cloudcli.ai/docs)**, чтобы узнать про дополнительные варианты конфигурации, PM2, настройку удалённого сервера и многое другое.
#### Docker Sandboxes (Экспериментально)
Запускайте агентов в изолированных песочницах с гипервизорной изоляцией. По умолчанию запускается Claude Code. Требуется [`sbx` CLI](https://docs.docker.com/ai/sandboxes/get-started/).
```
npx @cloudcli-ai/cloudcli@latest sandbox ~/my-project
```
Поддерживаются Claude Code, Codex и Gemini CLI. Подробнее в [документации sandbox](docker/).
---
@@ -104,7 +115,7 @@ CloudCLI UI — это open source UI-слой, на котором постро
|---|---|---|
| **Лучше всего подходит для** | Разработчиков, которым нужен полноценный UI для локальных агентских сессий на своей машине | Команд и разработчиков, которым нужны агенты в облаке с доступом откуда угодно |
| **Как вы получаете доступ** | Браузер через `[yourip]:port` | Браузер, любая IDE, REST API, n8n |
| **Настройка** | `npx @siteboon/claude-code-ui` | Настройка не требуется |
| **Настройка** | `npx @cloudcli-ai/cloudcli` | Настройка не требуется |
| **Машина должна оставаться включённой** | Да | Нет |
| **Доступ с мобильных устройств** | Любой браузер в вашей сети | Любое устройство, нативное приложение в разработке |
| **Доступные сессии** | Все сессии автоматически обнаруживаются из `~/.claude` | Все сессии внутри вашей облачной среды |

View File

@@ -72,22 +72,34 @@
### 自托管(开源)
#### npm
启动 CloudCLI UI只需一行 `npx`(需要 Node.js v22+
```bash
npx @siteboon/claude-code-ui
npx @cloudcli-ai/cloudcli
```
或进行全局安装,便于日常使用:
```bash
npm install -g @siteboon/claude-code-ui
npm install -g @cloudcli-ai/cloudcli
cloudcli
```
打开 `http://localhost:3001`,系统会自动发现所有现有会话。
更多配置选项、PM2、远程服务器设置等请参阅 **[文档 →](https://cloudcli.ai/docs)**
更多配置选项、PM2、远程服务器设置等请参阅 **[文档 →](https://cloudcli.ai/docs)**
#### Docker Sandboxes实验性
在隔离的沙箱中运行代理,具有虚拟机管理程序级别的隔离。默认启动 Claude Code。需要 [`sbx` CLI](https://docs.docker.com/ai/sandboxes/get-started/)。
```
npx @cloudcli-ai/cloudcli@latest sandbox ~/my-project
```
支持 Claude Code、Codex 和 Gemini CLI。详情请参阅 [沙箱文档](docker/)。
---
@@ -99,7 +111,7 @@ CloudCLI UI 是 CloudCLI Cloud 的开源 UI 层。你可以在本地机器上自
|---|---|---|
| **适合对象** | 需要为本地代理会话提供完整 UI 的开发者 | 需要部署在云端,随时从任何地方访问代理的团队与开发者 |
| **访问方式** | 通过 `[yourip]:port` 在浏览器中访问 | 浏览器、任意 IDE、REST API、n8n |
| **设置** | `npx @siteboon/claude-code-ui` | 无需设置 |
| **设置** | `npx @cloudcli-ai/cloudcli` | 无需设置 |
| **机器需保持开机吗** | 是 | 否 |
| **移动端访问** | 网络内任意浏览器 | 任意设备(原生应用即将推出) |
| **可用会话** | 自动发现 `~/.claude` 中的所有会话 | 云端环境内的会话 |

160
docker/README.md Normal file
View File

@@ -0,0 +1,160 @@
<!-- Docker Hub short description (100 chars max): -->
<!-- Sandbox templates for running AI coding agents with a web & mobile IDE (Claude Code, Codex, Gemini) -->
# Sandboxed coding agents with a web & mobile IDE (CloudCLI)
[Docker Sandbox](https://docs.docker.com/ai/sandboxes/) templates that add [CloudCLI](https://cloudcli.ai) on top of Claude Code, Codex, and Gemini CLI. You get a full web and mobile IDE accessible from any browser on any device.
## Get started
### 1. Install the sbx CLI
Docker Sandboxes run agents in isolated microVMs. Install the `sbx` CLI:
- **macOS**: `brew install docker/tap/sbx`
- **Windows**: `winget install -h Docker.sbx`
- **Linux**: `sudo apt-get install docker-sbx`
Full instructions: [docs.docker.com/ai/sandboxes/get-started](https://docs.docker.com/ai/sandboxes/get-started/)
### 2. Store your API key
`sbx` manages credentials securely — your API key never enters the sandbox. Store it once:
```bash
sbx login
sbx secret set -g anthropic
```
### 3. Launch Claude Code
```bash
npx @cloudcli-ai/cloudcli@latest sandbox ~/my-project
```
Open **http://localhost:3001**. Set a password on first visit. Start building.
### Using a different agent
Store the matching API key and pass `--agent`:
```bash
# OpenAI Codex
sbx secret set -g openai
npx @cloudcli-ai/cloudcli@latest sandbox ~/my-project --agent codex
# Gemini CLI
sbx secret set -g google
npx @cloudcli-ai/cloudcli@latest sandbox ~/my-project --agent gemini
```
### Available templates
| Agent | Template |
|-------|----------|
| **Claude Code** (default) | `docker.io/cloudcliai/sandbox:claude-code` |
| OpenAI Codex | `docker.io/cloudcliai/sandbox:codex` |
| Gemini CLI | `docker.io/cloudcliai/sandbox:gemini` |
These are used with `--template` when running `sbx` directly (see [Advanced usage](#advanced-usage)).
## Managing sandboxes
```bash
sbx ls # List all sandboxes
sbx stop my-project # Stop (preserves state)
sbx start my-project # Restart a stopped sandbox
sbx rm my-project # Remove everything
sbx exec my-project bash # Open a shell inside the sandbox
```
If you install CloudCLI globally (`npm install -g @cloudcli-ai/cloudcli`), you can also use:
```bash
cloudcli sandbox ls
cloudcli sandbox start my-project # Restart and re-launch web UI
cloudcli sandbox logs my-project # View server logs
```
## What you get
- **Chat** — Markdown rendering, code blocks, message history
- **Files** — File tree with syntax-highlighted editor
- **Git** — Diff viewer, staging, branch switching, commits
- **Shell** — Built-in terminal emulator
- **MCP** — Configure Model Context Protocol servers visually
- **Mobile** — Works on tablet and phone browsers
Your project directory is mounted bidirectionally — edits propagate in real time, both ways.
## Configuration
Set variables at creation time with `--env`:
```bash
npx @cloudcli-ai/cloudcli@latest sandbox ~/my-project --env SERVER_PORT=8080
```
Or inside a running sandbox:
```bash
sbx exec my-project bash -c 'echo "export SERVER_PORT=8080" >> /etc/sandbox-persistent.sh'
```
Restart CloudCLI for changes to take effect:
```bash
sbx exec my-project bash -c 'pkill -f "server/index.js"'
sbx exec -d my-project cloudcli start --port 3001
```
| Variable | Default | Description |
|----------|---------|-------------|
| `SERVER_PORT` | `3001` | Web UI port |
| `HOST` | `0.0.0.0` | Bind address (must be `0.0.0.0` for `sbx ports`) |
| `DATABASE_PATH` | `~/.cloudcli/auth.db` | SQLite database location |
## Advanced usage
For branch mode, multiple workspaces, memory limits, or the terminal agent experience, use `sbx` with the template:
```bash
# Terminal agent + web UI
sbx run --template docker.io/cloudcliai/sandbox:claude-code claude ~/my-project --name my-project
sbx ports my-project --publish 3001:3001
# Branch mode (Git worktree isolation)
sbx run --template docker.io/cloudcliai/sandbox:claude-code claude ~/my-project --branch my-feature
# Multiple workspaces
sbx run --template docker.io/cloudcliai/sandbox:claude-code claude ~/project ~/shared-libs:ro
# Pass a prompt directly
sbx run --template docker.io/cloudcliai/sandbox:claude-code claude ~/my-project -- "Fix the auth bug"
```
CloudCLI auto-starts via `.bashrc` when using `sbx run`.
Full options in the [Docker Sandboxes usage guide](https://docs.docker.com/ai/sandboxes/usage/).
## Network policies
Sandboxes restrict outbound access by default. To reach host services from inside the sandbox:
```bash
sbx policy allow network localhost:11434
# Inside the sandbox: curl http://host.docker.internal:11434
```
The web UI itself doesn't need a policy — access it via `sbx ports`.
## Links
- [CloudCLI Cloud](https://cloudcli.ai) — fully managed, no setup required
- [Documentation](https://cloudcli.ai/docs) — full configuration guide
- [Discord](https://discord.gg/buxwujPNRE) — community support
- [GitHub](https://github.com/siteboon/claudecodeui) — source code and issues
## License
AGPL-3.0-or-later

View File

@@ -0,0 +1,11 @@
FROM docker/sandbox-templates:claude-code
USER root
COPY shared/install-cloudcli.sh /tmp/install-cloudcli.sh
RUN chmod +x /tmp/install-cloudcli.sh && /tmp/install-cloudcli.sh
USER agent
RUN npm install -g @cloudcli-ai/cloudcli && cloudcli --version
COPY --chown=agent:agent shared/start-cloudcli.sh /home/agent/.cloudcli-start.sh
RUN echo '. ~/.cloudcli-start.sh' >> /home/agent/.bashrc

11
docker/codex/Dockerfile Normal file
View File

@@ -0,0 +1,11 @@
FROM docker/sandbox-templates:codex
USER root
COPY shared/install-cloudcli.sh /tmp/install-cloudcli.sh
RUN chmod +x /tmp/install-cloudcli.sh && /tmp/install-cloudcli.sh
USER agent
RUN npm install -g @cloudcli-ai/cloudcli && cloudcli --version
COPY --chown=agent:agent shared/start-cloudcli.sh /home/agent/.cloudcli-start.sh
RUN echo '. ~/.cloudcli-start.sh' >> /home/agent/.bashrc

11
docker/gemini/Dockerfile Normal file
View File

@@ -0,0 +1,11 @@
FROM docker/sandbox-templates:gemini
USER root
COPY shared/install-cloudcli.sh /tmp/install-cloudcli.sh
RUN chmod +x /tmp/install-cloudcli.sh && /tmp/install-cloudcli.sh
USER agent
RUN npm install -g @cloudcli-ai/cloudcli && cloudcli --version
COPY --chown=agent:agent shared/start-cloudcli.sh /home/agent/.cloudcli-start.sh
RUN echo '. ~/.cloudcli-start.sh' >> /home/agent/.bashrc

View File

@@ -0,0 +1,11 @@
#!/bin/bash
set -e
# Install build tools needed for native modules (node-pty, better-sqlite3, bcrypt)
# Node.js is already provided by the sandbox base image
apt-get update && apt-get install -y --no-install-recommends \
build-essential python3 python3-setuptools \
jq ripgrep sqlite3 zip unzip tree vim-tiny
# Clean up apt cache to reduce image size
rm -rf /var/lib/apt/lists/*

View File

@@ -0,0 +1,18 @@
#!/bin/bash
# Auto-start CloudCLI server in background if not already running.
# This script is sourced from ~/.bashrc on sandbox shell open.
if ! pgrep -f "server/index.js" > /dev/null 2>&1; then
nohup cloudcli start --port 3001 > /tmp/cloudcli-ui.log 2>&1 &
disown
echo ""
echo " CloudCLI is starting on port 3001..."
echo ""
echo " Forward the port from another terminal:"
echo " sbx ports <sandbox-name> --publish 3001:3001"
echo ""
echo " Then open: http://localhost:3001"
echo ""
fi

View File

@@ -1,144 +0,0 @@
transport,method,path,tag,authMode,sourceFile,sourceLine,purpose,consumerFiles,pathParams,queryParams,bodyHints,successShape,errorShape,sideEffects,priority
"http","GET","/health","System","public","server/index.js","345","Expose server health, timestamp, and install mode for diagnostics.","src/hooks/useVersionCheck.ts","","","","Structured JSON object response.","Handler-specific error behavior.","Read-only backend query.","low"
"http","POST","/api/system/update","System","bearer_token","server/index.js","425","Run the application update workflow on the host machine.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","","Structured JSON object response.","JSON error response with HTTP status code.","Mutates backend or external state.","low"
"http","GET","/api/projects","Projects","bearer_token","server/index.js","491","List detected projects and workspaces.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","","JSON payload returned directly from service logic.","JSON object with error message and optional details.","Touches local workspace files or directories.","high"
"http","GET","/api/projects/:projectName/sessions","Sessions","bearer_token","server/index.js","500","List or manage sessions associated with a project or provider.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","projectName","offset; try {
const { limit","","JSON payload returned directly from service logic.","JSON object with error message and optional details.","Touches local workspace files or directories.","high"
"http","GET","/api/projects/:projectName/sessions/:sessionId/messages","Sessions","bearer_token","server/index.js","512","Return paginated messages for a stored session.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","projectName; sessionId","limit; offset","","Structured JSON object response.","JSON object with error message and optional details.","Touches local workspace files or directories.","high"
"http","PUT","/api/projects/:projectName/rename","Projects","bearer_token","server/index.js","537","PUT /api/projects/:projectName/rename for backend runtime support.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","projectName","","try {
const { displayName","JSON object with an explicit success flag and payload.","JSON object with error message and optional details.","Mutates backend or external state.; Touches local workspace files or directories.","high"
"http","DELETE","/api/projects/:projectName/sessions/:sessionId","Sessions","bearer_token","server/index.js","548","List or manage sessions associated with a project or provider.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","projectName; sessionId","","","JSON object with an explicit success flag and payload.","JSON object with error message and optional details.","Mutates backend or external state.; Touches local workspace files or directories.","high"
"http","PUT","/api/sessions/:sessionId/rename","Sessions","bearer_token","server/index.js","563","List or manage sessions associated with a project or provider.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","sessionId","","provider; summary","JSON object with an explicit success flag and payload.","JSON object with error message and optional details.","Mutates backend or external state.","low"
"http","DELETE","/api/projects/:projectName","Projects","bearer_token","server/index.js","589","DELETE /api/projects/:projectName for backend runtime support.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","projectName","force","","JSON object with an explicit success flag and payload.","JSON object with error message and optional details.","Mutates backend or external state.; Touches local workspace files or directories.","high"
"http","POST","/api/projects/create","Projects","bearer_token","server/index.js","601","Manually add a project path to the workspace list.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","try {
const { path","JSON object with an explicit success flag and payload.","JSON object with error message and optional details.","Mutates backend or external state.; Touches local workspace files or directories.","high"
"sse","GET","/api/search/conversations","Sessions","bearer_token","server/index.js","618","Search conversation history across stored projects and stream results.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","limit; q","","Server-sent events stream with progress/result/error events.","Streamed error event or JSON error fallback.","Read-only backend query.","high"
"http","GET","/api/browse-filesystem","Realtime","bearer_token","server/index.js","674","Browse local directories so the UI can suggest workspace locations.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","try {
const { path","","Structured JSON object response.","JSON object with error message and optional details.","Read-only backend query.","low"
"http","POST","/api/create-folder","Projects","bearer_token","server/index.js","754","Create a new directory on the local filesystem.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","try {
const { path","JSON object with an explicit success flag and payload.","JSON object with error message and optional details.","Mutates backend or external state.","low"
"http","GET","/api/projects/:projectName/file","Files","bearer_token","server/index.js","795","Read, write, create, rename, delete, or upload project files.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","projectName","filePath","","Structured JSON object response.","JSON object with error message and optional details.","Touches local workspace files or directories.","high"
"http","GET","/api/projects/:projectName/files/content","Files","bearer_token","server/index.js","835","Read, write, create, rename, delete, or upload project files.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","projectName","path","","Mixed response shape; inspect handler during refactor.","JSON object with error message and optional details.","Touches local workspace files or directories.","high"
"http","PUT","/api/projects/:projectName/file","Files","bearer_token","server/index.js","888","Read, write, create, rename, delete, or upload project files.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","projectName","","content; filePath","Structured JSON object response.","JSON object with error message and optional details.","Mutates backend or external state.; Touches local workspace files or directories.","high"
"http","GET","/api/projects/:projectName/files","Files","bearer_token","server/index.js","937","Read, write, create, rename, delete, or upload project files.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","projectName","","","JSON payload returned directly from service logic.","JSON object with error message and optional details.","Touches local workspace files or directories.","high"
"http","POST","/api/projects/:projectName/files/create","Files","bearer_token","server/index.js","1016","Read, write, create, rename, delete, or upload project files.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","projectName","","name; path; type","Structured JSON object response.","JSON object with error message and optional details.","Mutates backend or external state.; Touches local workspace files or directories.","high"
"http","PUT","/api/projects/:projectName/files/rename","Files","bearer_token","server/index.js","1093","Read, write, create, rename, delete, or upload project files.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","projectName","","newName; oldPath","Structured JSON object response.","JSON object with error message and optional details.","Mutates backend or external state.; Touches local workspace files or directories.","high"
"http","DELETE","/api/projects/:projectName/files","Files","bearer_token","server/index.js","1170","Read, write, create, rename, delete, or upload project files.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","projectName","","path; relativePaths; targetPath; type","Structured JSON object response.","JSON object with error message and optional details.","Mutates backend or external state.; Touches local workspace files or directories.","high"
"http","POST","/api/projects/:projectName/files/upload","Files","bearer_token","server/index.js","1396","Read, write, create, rename, delete, or upload project files.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","projectName","","","Mixed response shape; inspect handler during refactor.","Handler-specific error behavior.","Mutates backend or external state.; Touches local workspace files or directories.","high"
"http","POST","/api/transcribe","Realtime","bearer_token","server/index.js","1964","Transcribe uploaded audio and optionally enhance the result for prompts or tasks.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","mode","Structured JSON object response.","JSON object with error message and optional details.","Mutates backend or external state.; Processes uploaded files and external model responses.","low"
"http","POST","/api/projects/:projectName/upload-images","Files","bearer_token","server/index.js","2113","Upload images for chat use and return browser-safe data URLs.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","projectName","","","Structured JSON object response.","JSON object with error message and optional details.","Mutates backend or external state.; Touches local workspace files or directories.","high"
"http","GET","/api/projects/:projectName/sessions/:sessionId/token-usage","Sessions","bearer_token","server/index.js","2198","Report token usage for a stored provider session.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","projectName; sessionId","provider","","Structured JSON object response.","JSON object with error message and optional details.","Touches local workspace files or directories.","high"
"http","GET","*","System","public","server/index.js","2386","Serve the React application fallback for non-API routes.","","","","","Static file or HTML response.","JSON error response with HTTP status code.","Read-only backend query.","low"
"http","GET","/api/auth/status","Auth","public","server/routes/auth.js","9","Report whether authentication is configured.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","","Structured JSON object response.","JSON object with error message and optional details.","Reads or writes local authentication or credential state.","medium"
"http","POST","/api/auth/register","Auth","public","server/routes/auth.js","23","Create the first local user account.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","password; try {
const { username","Structured JSON object response.","JSON object with error message and optional details.","Mutates backend or external state.; Reads or writes local authentication or credential state.","medium"
"http","POST","/api/auth/login","Auth","public","server/routes/auth.js","82","Authenticate a local user and issue a token.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","password; try {
const { username","Structured JSON object response.","JSON object with error message and optional details.","Mutates backend or external state.; Reads or writes local authentication or credential state.","medium"
"http","GET","/api/auth/user","Auth","bearer_token","server/routes/auth.js","122","Return the currently authenticated user.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","","Structured JSON object response.","Handler-specific error behavior.","Reads or writes local authentication or credential state.","medium"
"http","POST","/api/auth/logout","Auth","bearer_token","server/routes/auth.js","129","Invalidate the current authenticated session.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","","JSON object with an explicit success flag and payload.","Handler-specific error behavior.","Mutates backend or external state.; Reads or writes local authentication or credential state.","medium"
"http","POST","/api/projects/create-workspace","Projects","bearer_token","server/routes/projects.js","175","Create or register a workspace and optionally clone a GitHub repository into it.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","githubTokenId; githubUrl; newGithubToken; path; try {
const { workspaceType","Structured JSON object response.","JSON validation error response.","Mutates backend or external state.; Touches local workspace files or directories.","high"
"sse","GET","/api/projects/clone-progress","Projects","bearer_token","server/routes/projects.js","335","Stream workspace cloning progress events to the frontend.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","const { path; githubTokenId; githubUrl; newGithubToken","","Server-sent events stream with progress/result/error events.","Streamed error event or JSON error fallback.","Touches local workspace files or directories.","high"
"http","GET","/api/git/status","Git","bearer_token","server/routes/git.js","291","Read git status information for a project.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","const { project","","Structured JSON object response.","JSON validation error response.","Touches git repositories or local git config.","high"
"http","GET","/api/git/diff","Git","bearer_token","server/routes/git.js","354","Return git diff output for a project or file.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","const { project; file","","Structured JSON object response.","JSON validation error response.","Touches git repositories or local git config.","high"
"http","GET","/api/git/file-with-diff","Git","bearer_token","server/routes/git.js","437","Read, write, create, rename, delete, or upload project files.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","const { project; file","","Structured JSON object response.","JSON validation error response.","Touches git repositories or local git config.; Touches local workspace files or directories.","high"
"http","POST","/api/git/initial-commit","Git","bearer_token","server/routes/git.js","517","POST /api/git/initial-commit for backend runtime support.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","const { project","JSON object with an explicit success flag and payload.","JSON object with error message and optional details.","Mutates backend or external state.; Touches git repositories or local git config.","high"
"http","POST","/api/git/commit","Git","bearer_token","server/routes/git.js","561","POST /api/git/commit for backend runtime support.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","const { project; files; message","JSON object with an explicit success flag and payload.","JSON object with error message and optional details.","Mutates backend or external state.; Touches git repositories or local git config.","high"
"http","POST","/api/git/revert-local-commit","Git","bearer_token","server/routes/git.js","592","POST /api/git/revert-local-commit for backend runtime support.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","const { project","Structured JSON object response.","JSON object with error message and optional details.","Mutates backend or external state.; Touches git repositories or local git config.","high"
"http","GET","/api/git/branches","Git","bearer_token","server/routes/git.js","639","List git branches for a project.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","const { project","","Structured JSON object response.","JSON validation error response.","Touches git repositories or local git config.","high"
"http","POST","/api/git/checkout","Git","bearer_token","server/routes/git.js","681","POST /api/git/checkout for backend runtime support.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","branch; const { project","JSON object with an explicit success flag and payload.","JSON object with error message and optional details.","Mutates backend or external state.; Touches git repositories or local git config.","high"
"http","POST","/api/git/create-branch","Git","bearer_token","server/routes/git.js","703","POST /api/git/create-branch for backend runtime support.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","branch; const { project","JSON object with an explicit success flag and payload.","JSON object with error message and optional details.","Mutates backend or external state.; Touches git repositories or local git config.","high"
"http","GET","/api/git/commits","Git","bearer_token","server/routes/git.js","725","List recent commits for a project.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","const { project; limit","","Structured JSON object response.","JSON validation error response.","Touches git repositories or local git config.","high"
"http","GET","/api/git/commit-diff","Git","bearer_token","server/routes/git.js","782","Return diff details for a specific commit.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","commit; const { project","","Structured JSON object response.","JSON validation error response.","Touches git repositories or local git config.","high"
"http","POST","/api/git/generate-commit-message","Git","bearer_token","server/routes/git.js","814","Generate an AI-assisted commit message from the current diff.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","const { project; files; provider","Structured JSON object response.","JSON object with error message and optional details.","Mutates backend or external state.; Touches git repositories or local git config.","high"
"http","GET","/api/git/remote-status","Git","bearer_token","server/routes/git.js","1019","Report remote sync status for a project repository.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","const { project","","Structured JSON object response.","JSON validation error response.","Touches git repositories or local git config.","high"
"http","POST","/api/git/fetch","Git","bearer_token","server/routes/git.js","1097","POST /api/git/fetch for backend runtime support.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","const { project","JSON object with an explicit success flag and payload.","JSON validation error response.","Mutates backend or external state.; Touches git repositories or local git config.","high"
"http","POST","/api/git/pull","Git","bearer_token","server/routes/git.js","1138","POST /api/git/pull for backend runtime support.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","const { project","Structured JSON object response.","JSON validation error response.","Mutates backend or external state.; Touches git repositories or local git config.","high"
"http","POST","/api/git/push","Git","bearer_token","server/routes/git.js","1206","POST /api/git/push for backend runtime support.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","const { project","Structured JSON object response.","JSON validation error response.","Mutates backend or external state.; Touches git repositories or local git config.","high"
"http","POST","/api/git/publish","Git","bearer_token","server/routes/git.js","1277","POST /api/git/publish for backend runtime support.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","branch; const { project","Structured JSON object response.","JSON validation error response.","Mutates backend or external state.; Touches git repositories or local git config.","high"
"http","POST","/api/git/discard","Git","bearer_token","server/routes/git.js","1356","POST /api/git/discard for backend runtime support.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","const { project; file","JSON object with an explicit success flag and payload.","JSON object with error message and optional details.","Mutates backend or external state.; Touches git repositories or local git config.","high"
"http","POST","/api/git/delete-untracked","Git","bearer_token","server/routes/git.js","1410","POST /api/git/delete-untracked for backend runtime support.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","const { project; file","JSON object with an explicit success flag and payload.","JSON object with error message and optional details.","Mutates backend or external state.; Touches git repositories or local git config.","high"
"http","GET","/api/mcp/cli/list","MCP","bearer_token","server/routes/mcp.js","16","Manage Claude MCP CLI and configuration state.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","","JSON object with an explicit success flag and payload.","JSON object with error message and optional details.","Reads or writes MCP CLI configuration.","medium"
"http","POST","/api/mcp/cli/add","MCP","bearer_token","server/routes/mcp.js","59","Manage Claude MCP CLI and configuration state.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","","JSON object with an explicit success flag and payload.","JSON object with error message and optional details.","Mutates backend or external state.; Reads or writes MCP CLI configuration.","medium"
"http","POST","/api/mcp/cli/add-json","MCP","bearer_token","server/routes/mcp.js","142","Manage Claude MCP CLI and configuration state.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","jsonConfig; projectPath; scope; try {
const { name","JSON object with an explicit success flag and payload.","JSON object with error message and optional details.","Mutates backend or external state.; Reads or writes MCP CLI configuration.","medium"
"http","DELETE","/api/mcp/cli/remove/:name","MCP","bearer_token","server/routes/mcp.js","235","Manage Claude MCP CLI and configuration state.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","name","scope","","JSON object with an explicit success flag and payload.","JSON object with error message and optional details.","Mutates backend or external state.; Reads or writes MCP CLI configuration.","medium"
"http","GET","/api/mcp/cli/get/:name","MCP","bearer_token","server/routes/mcp.js","305","Manage Claude MCP CLI and configuration state.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","name","","","JSON object with an explicit success flag and payload.","JSON object with error message and optional details.","Reads or writes MCP CLI configuration.","medium"
"http","GET","/api/mcp/config/read","MCP","bearer_token","server/routes/mcp.js","348","Manage Claude MCP CLI and configuration state.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","","Structured JSON object response.","JSON error response with HTTP status code.","Reads or writes MCP CLI configuration.","medium"
"http","GET","/api/cursor/config","Providers","bearer_token","server/routes/cursor.js","15","Manage Cursor configuration, MCP settings, and stored sessions.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","","Structured JSON object response.","JSON error response with HTTP status code.","Read-only backend query.","medium"
"http","POST","/api/cursor/config","Providers","bearer_token","server/routes/cursor.js","59","Manage Cursor configuration, MCP settings, and stored sessions.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","model; try {
const { permissions","Structured JSON object response.","JSON error response with HTTP status code.","Mutates backend or external state.","medium"
"http","GET","/api/cursor/mcp","Providers","bearer_token","server/routes/cursor.js","122","Manage Cursor configuration, MCP settings, and stored sessions.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","","Structured JSON object response.","JSON error response with HTTP status code.","Reads or writes MCP CLI configuration.","medium"
"http","POST","/api/cursor/mcp/add","Providers","bearer_token","server/routes/cursor.js","183","Manage Cursor configuration, MCP settings, and stored sessions.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","","Structured JSON object response.","JSON error response with HTTP status code.","Mutates backend or external state.; Reads or writes MCP CLI configuration.","medium"
"http","DELETE","/api/cursor/mcp/:name","Providers","bearer_token","server/routes/cursor.js","245","Manage Cursor configuration, MCP settings, and stored sessions.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","name","","","Structured JSON object response.","JSON error response with HTTP status code.","Mutates backend or external state.; Reads or writes MCP CLI configuration.","medium"
"http","POST","/api/cursor/mcp/add-json","Providers","bearer_token","server/routes/cursor.js","292","Manage Cursor configuration, MCP settings, and stored sessions.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","jsonConfig; try {
const { name","Structured JSON object response.","JSON error response with HTTP status code.","Mutates backend or external state.; Reads or writes MCP CLI configuration.","medium"
"http","GET","/api/cursor/sessions","Providers","bearer_token","server/routes/cursor.js","348","List or manage sessions associated with a project or provider.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","try {
const { projectPath","","Structured JSON object response.","JSON error response with HTTP status code.","Read-only backend query.","medium"
"http","GET","/api/cursor/sessions/:sessionId","Providers","bearer_token","server/routes/cursor.js","583","List or manage sessions associated with a project or provider.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","sessionId","projectPath","","Structured JSON object response.","JSON error response with HTTP status code.","Read-only backend query.","medium"
"http","GET","/api/taskmaster/installation-status","TaskMaster","bearer_token","server/routes/taskmaster.js","243","Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","","Structured JSON object response.","JSON error response with HTTP status code.","Reads or writes TaskMaster project assets.","high"
"http","GET","/api/taskmaster/detect/:projectName","TaskMaster","bearer_token","server/routes/taskmaster.js","278","Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","projectName","","","JSON payload returned directly from service logic.","JSON error response with HTTP status code.","Reads or writes TaskMaster project assets.","high"
"http","GET","/api/taskmaster/detect-all","TaskMaster","bearer_token","server/routes/taskmaster.js","350","Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","","Structured JSON object response.","JSON error response with HTTP status code.","Reads or writes TaskMaster project assets.","high"
"http","POST","/api/taskmaster/initialize/:projectName","TaskMaster","bearer_token","server/routes/taskmaster.js","434","Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","projectName","","rules","Mixed response shape; inspect handler during refactor.","JSON error response with HTTP status code.","Mutates backend or external state.; Reads or writes TaskMaster project assets.","high"
"http","GET","/api/taskmaster/next/:projectName","TaskMaster","bearer_token","server/routes/taskmaster.js","460","Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","projectName","","","Structured JSON object response.","JSON error response with HTTP status code.","Reads or writes TaskMaster project assets.","high"
"http","GET","/api/taskmaster/tasks/:projectName","TaskMaster","bearer_token","server/routes/taskmaster.js","570","Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","projectName","","","Structured JSON object response.","JSON error response with HTTP status code.","Reads or writes TaskMaster project assets.","high"
"http","GET","/api/taskmaster/prd/:projectName","TaskMaster","bearer_token","server/routes/taskmaster.js","685","Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","projectName","","","Structured JSON object response.","JSON error response with HTTP status code.","Reads or writes TaskMaster project assets.","high"
"http","POST","/api/taskmaster/prd/:projectName","TaskMaster","bearer_token","server/routes/taskmaster.js","761","Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","projectName","","content; fileName","Structured JSON object response.","JSON error response with HTTP status code.","Mutates backend or external state.; Reads or writes TaskMaster project assets.","high"
"http","GET","/api/taskmaster/prd/:projectName/:fileName","TaskMaster","bearer_token","server/routes/taskmaster.js","846","Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","projectName; fileName","","","Structured JSON object response.","JSON error response with HTTP status code.","Reads or writes TaskMaster project assets.","high"
"http","DELETE","/api/taskmaster/prd/:projectName/:fileName","TaskMaster","bearer_token","server/routes/taskmaster.js","911","Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","projectName; fileName","","","Structured JSON object response.","JSON error response with HTTP status code.","Mutates backend or external state.; Reads or writes TaskMaster project assets.","high"
"http","POST","/api/taskmaster/init/:projectName","TaskMaster","bearer_token","server/routes/taskmaster.js","971","Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","projectName","","","Structured JSON object response.","JSON error response with HTTP status code.","Mutates backend or external state.; Reads or writes TaskMaster project assets.","high"
"http","POST","/api/taskmaster/add-task/:projectName","TaskMaster","bearer_token","server/routes/taskmaster.js","1060","Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","projectName","","dependencies; description; priority; prompt; title","Structured JSON object response.","JSON error response with HTTP status code.","Mutates backend or external state.; Reads or writes TaskMaster project assets.","high"
"http","PUT","/api/taskmaster/update-task/:projectName/:taskId","TaskMaster","bearer_token","server/routes/taskmaster.js","1164","Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","projectName; taskId","","description; details; priority; status; title","Structured JSON object response.","JSON error response with HTTP status code.","Mutates backend or external state.; Reads or writes TaskMaster project assets.","high"
"http","POST","/api/taskmaster/parse-prd/:projectName","TaskMaster","bearer_token","server/routes/taskmaster.js","1291","Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","projectName","","append; fileName; numTasks","Structured JSON object response.","JSON error response with HTTP status code.","Mutates backend or external state.; Reads or writes TaskMaster project assets.","high"
"http","GET","/api/taskmaster/prd-templates","TaskMaster","bearer_token","server/routes/taskmaster.js","1392","Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","","Structured JSON object response.","JSON error response with HTTP status code.","Reads or writes TaskMaster project assets.","high"
"http","POST","/api/taskmaster/apply-template/:projectName","TaskMaster","bearer_token","server/routes/taskmaster.js","1838","Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","projectName","","","Structured JSON object response.","JSON error response with HTTP status code.","Mutates backend or external state.; Reads or writes TaskMaster project assets.","high"
"http","GET","/api/mcp-utils/taskmaster-server","MCP","bearer_token","server/routes/mcp-utils.js","18","Return MCP helper information used by setup flows.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","","JSON payload returned directly from service logic.","JSON error response with HTTP status code.","Reads or writes TaskMaster project assets.; Reads or writes MCP CLI configuration.","medium"
"http","GET","/api/mcp-utils/all-servers","MCP","bearer_token","server/routes/mcp-utils.js","35","Return MCP helper information used by setup flows.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","","JSON payload returned directly from service logic.","JSON error response with HTTP status code.","Reads or writes MCP CLI configuration.","medium"
"http","POST","/api/commands/list","Commands","bearer_token","server/routes/commands.js","406","List, load, or execute slash commands available to the chat experience.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","try {
const { projectPath","Structured JSON object response.","JSON error response with HTTP status code.","Mutates backend or external state.","medium"
"http","POST","/api/commands/load","Commands","bearer_token","server/routes/commands.js","456","List, load, or execute slash commands available to the chat experience.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","commandPath; try {
const { commandPath","Structured JSON object response.","JSON error response with HTTP status code.","Mutates backend or external state.","medium"
"http","POST","/api/commands/execute","Commands","bearer_token","server/routes/commands.js","507","List, load, or execute slash commands available to the chat experience.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","commandPath","Structured JSON object response.","JSON error response with HTTP status code.","Mutates backend or external state.","medium"
"http","GET","/api/settings/api-keys","Settings","bearer_token","server/routes/settings.js","11","Manage local API keys used to access the backend.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","","Structured JSON object response.","JSON object with error message and optional details.","Reads or writes local authentication or credential state.","medium"
"http","POST","/api/settings/api-keys","Settings","bearer_token","server/routes/settings.js","27","Manage local API keys used to access the backend.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","try {
const { keyName","Structured JSON object response.","JSON object with error message and optional details.","Mutates backend or external state.; Reads or writes local authentication or credential state.","medium"
"http","DELETE","/api/settings/api-keys/:keyId","Settings","bearer_token","server/routes/settings.js","47","Manage local API keys used to access the backend.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","keyId","","","JSON object with an explicit success flag and payload.","JSON object with error message and optional details.","Mutates backend or external state.; Reads or writes local authentication or credential state.","medium"
"http","PATCH","/api/settings/api-keys/:keyId/toggle","Settings","bearer_token","server/routes/settings.js","64","Manage local API keys used to access the backend.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","keyId","","isActive","JSON object with an explicit success flag and payload.","JSON object with error message and optional details.","Mutates backend or external state.; Reads or writes local authentication or credential state.","medium"
"http","GET","/api/settings/credentials","Settings","bearer_token","server/routes/settings.js","91","Manage stored provider and GitHub credentials.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","try {
const { type","","Structured JSON object response.","JSON object with error message and optional details.","Reads or writes local authentication or credential state.","medium"
"http","POST","/api/settings/credentials","Settings","bearer_token","server/routes/settings.js","104","Manage stored provider and GitHub credentials.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","credentialType; credentialValue; description; try {
const { credentialName","Structured JSON object response.","JSON object with error message and optional details.","Mutates backend or external state.; Reads or writes local authentication or credential state.","medium"
"http","DELETE","/api/settings/credentials/:credentialId","Settings","bearer_token","server/routes/settings.js","139","Manage stored provider and GitHub credentials.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","credentialId","","","JSON object with an explicit success flag and payload.","JSON object with error message and optional details.","Mutates backend or external state.; Reads or writes local authentication or credential state.","medium"
"http","PATCH","/api/settings/credentials/:credentialId/toggle","Settings","bearer_token","server/routes/settings.js","156","Manage stored provider and GitHub credentials.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","credentialId","","isActive","JSON object with an explicit success flag and payload.","JSON object with error message and optional details.","Mutates backend or external state.; Reads or writes local authentication or credential state.","medium"
"http","GET","/api/cli/claude/status","CLI Auth","bearer_token","server/routes/cli-auth.js","9","Report local authentication status for provider CLIs.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","","Structured JSON object response.","JSON error response with HTTP status code.","Read-only backend query.","low"
"http","GET","/api/cli/cursor/status","CLI Auth","bearer_token","server/routes/cli-auth.js","39","Report local authentication status for provider CLIs.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","","Structured JSON object response.","JSON error response with HTTP status code.","Read-only backend query.","low"
"http","GET","/api/cli/codex/status","CLI Auth","bearer_token","server/routes/cli-auth.js","59","Report local authentication status for provider CLIs.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","","Structured JSON object response.","JSON error response with HTTP status code.","Read-only backend query.","low"
"http","GET","/api/cli/gemini/status","CLI Auth","bearer_token","server/routes/cli-auth.js","79","Report local authentication status for provider CLIs.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","","Structured JSON object response.","JSON error response with HTTP status code.","Read-only backend query.","low"
"http","GET","/api/user/git-config","User","bearer_token","server/routes/user.js","28","Read or update stored git identity settings.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","","Structured JSON object response.","JSON object with error message and optional details.","Touches git repositories or local git config.","medium"
"http","POST","/api/user/git-config","User","bearer_token","server/routes/user.js","57","Read or update stored git identity settings.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","gitEmail; try {
const userId = req.user.id;
const { gitName","Structured JSON object response.","JSON object with error message and optional details.","Mutates backend or external state.; Touches git repositories or local git config.","medium"
"http","POST","/api/user/complete-onboarding","User","bearer_token","server/routes/user.js","93","Mark onboarding as completed for the current user.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","","Structured JSON object response.","JSON object with error message and optional details.","Mutates backend or external state.","medium"
"http","GET","/api/user/onboarding-status","User","bearer_token","server/routes/user.js","108","Return onboarding completion status for the current user.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","","Structured JSON object response.","JSON object with error message and optional details.","Read-only backend query.","medium"
"http","GET","/api/codex/config","Providers","bearer_token","server/routes/codex.js","23","Manage Codex configuration, MCP settings, and stored sessions.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","","Structured JSON object response.","JSON error response with HTTP status code.","Read-only backend query.","medium"
"http","GET","/api/codex/sessions","Providers","bearer_token","server/routes/codex.js","54","List or manage sessions associated with a project or provider.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","try {
const { projectPath","","JSON object with an explicit success flag and payload.","JSON error response with HTTP status code.","Read-only backend query.","medium"
"http","GET","/api/codex/sessions/:sessionId/messages","Providers","bearer_token","server/routes/codex.js","71","Return paginated messages for a stored session.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","sessionId","limit; offset","","JSON object with an explicit success flag and payload.","JSON error response with HTTP status code.","Read-only backend query.","medium"
"http","DELETE","/api/codex/sessions/:sessionId","Providers","bearer_token","server/routes/codex.js","89","List or manage sessions associated with a project or provider.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","sessionId","","","JSON object with an explicit success flag and payload.","JSON error response with HTTP status code.","Mutates backend or external state.","medium"
"http","GET","/api/codex/mcp/cli/list","Providers","bearer_token","server/routes/codex.js","103","Manage Codex configuration, MCP settings, and stored sessions.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","","Mixed response shape; inspect handler during refactor.","JSON object with error message and optional details.","Reads or writes MCP CLI configuration.","medium"
"http","POST","/api/codex/mcp/cli/add","Providers","bearer_token","server/routes/codex.js","135","Manage Codex configuration, MCP settings, and stored sessions.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","","Mixed response shape; inspect handler during refactor.","JSON object with error message and optional details.","Mutates backend or external state.; Reads or writes MCP CLI configuration.","medium"
"http","DELETE","/api/codex/mcp/cli/remove/:name","Providers","bearer_token","server/routes/codex.js","186","Manage Codex configuration, MCP settings, and stored sessions.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","name","","","Mixed response shape; inspect handler during refactor.","JSON object with error message and optional details.","Mutates backend or external state.; Reads or writes MCP CLI configuration.","medium"
"http","GET","/api/codex/mcp/cli/get/:name","Providers","bearer_token","server/routes/codex.js","220","Manage Codex configuration, MCP settings, and stored sessions.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","name","","","Mixed response shape; inspect handler during refactor.","JSON object with error message and optional details.","Reads or writes MCP CLI configuration.","medium"
"http","GET","/api/codex/mcp/config/read","Providers","bearer_token","server/routes/codex.js","254","Manage Codex configuration, MCP settings, and stored sessions.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","","JSON object with an explicit success flag and payload.","JSON object with error message and optional details.","Reads or writes MCP CLI configuration.","medium"
"http","GET","/api/gemini/sessions/:sessionId/messages","Providers","bearer_token","server/routes/gemini.js","8","Return paginated messages for a stored session.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","sessionId","","","Structured JSON object response.","JSON error response with HTTP status code.","Read-only backend query.","medium"
"http","DELETE","/api/gemini/sessions/:sessionId","Providers","bearer_token","server/routes/gemini.js","37","List or manage sessions associated with a project or provider.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","sessionId","","","JSON object with an explicit success flag and payload.","JSON error response with HTTP status code.","Mutates backend or external state.","medium"
"http","GET","/api/plugins","Plugins","bearer_token","server/routes/plugins.js","27","List, install, update, serve, enable, or remove plugins.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","","Structured JSON object response.","JSON object with error message and optional details.","Installs, updates, or serves plugin assets/processes.","medium"
"http","GET","/api/plugins/:name/manifest","Plugins","bearer_token","server/routes/plugins.js","40","List, install, update, serve, enable, or remove plugins.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","name","","","JSON payload returned directly from service logic.","JSON object with error message and optional details.","Installs, updates, or serves plugin assets/processes.","medium"
"http","GET","/api/plugins/:name/assets/*","Plugins","bearer_token","server/routes/plugins.js","57","List, install, update, serve, enable, or remove plugins.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","name","","","Mixed response shape; inspect handler during refactor.","JSON object with error message and optional details.","Installs, updates, or serves plugin assets/processes.","medium"
"http","PUT","/api/plugins/:name/enable","Plugins","bearer_token","server/routes/plugins.js","96","List, install, update, serve, enable, or remove plugins.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","name","","try {
const { enabled","JSON object with an explicit success flag and payload.","JSON object with error message and optional details.","Mutates backend or external state.; Installs, updates, or serves plugin assets/processes.","medium"
"http","POST","/api/plugins/install","Plugins","bearer_token","server/routes/plugins.js","136","List, install, update, serve, enable, or remove plugins.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","try {
const { url","JSON object with an explicit success flag and payload.","JSON validation error response.","Mutates backend or external state.; Installs, updates, or serves plugin assets/processes.","medium"
"http","POST","/api/plugins/:name/update","Plugins","bearer_token","server/routes/plugins.js","169","List, install, update, serve, enable, or remove plugins.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","name","","","JSON object with an explicit success flag and payload.","JSON validation error response.","Mutates backend or external state.; Installs, updates, or serves plugin assets/processes.","medium"
"http","DELETE","/api/plugins/:name","Plugins","bearer_token","server/routes/plugins.js","282","List, install, update, serve, enable, or remove plugins.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","name","","","JSON object with an explicit success flag and payload.","JSON validation error response.","Mutates backend or external state.; Installs, updates, or serves plugin assets/processes.","medium"
"sse","POST","/api/agent","Agent","api_key_or_platform","server/routes/agent.js","839","Accept external agent jobs that run a provider against a local or cloned project.","src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js","","","branchName; cleanup; const { githubUrl; createBranch; createPR; githubToken; message; model; projectPath; provider; stream","Server-sent events stream with progress/result/error events.","Streamed error event or JSON error fallback.","Mutates backend or external state.; Invokes external AI providers and may modify project files.","high"
1 transport method path tag authMode sourceFile sourceLine purpose consumerFiles pathParams queryParams bodyHints successShape errorShape sideEffects priority
2 http GET /health System public server/index.js 345 Expose server health, timestamp, and install mode for diagnostics. src/hooks/useVersionCheck.ts Structured JSON object response. Handler-specific error behavior. Read-only backend query. low
3 http POST /api/system/update System bearer_token server/index.js 425 Run the application update workflow on the host machine. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js Structured JSON object response. JSON error response with HTTP status code. Mutates backend or external state. low
4 http GET /api/projects Projects bearer_token server/index.js 491 List detected projects and workspaces. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js JSON payload returned directly from service logic. JSON object with error message and optional details. Touches local workspace files or directories. high
5 http GET /api/projects/:projectName/sessions Sessions bearer_token server/index.js 500 List or manage sessions associated with a project or provider. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js projectName offset; try { const { limit JSON payload returned directly from service logic. JSON object with error message and optional details. Touches local workspace files or directories. high
6 http GET /api/projects/:projectName/sessions/:sessionId/messages Sessions bearer_token server/index.js 512 Return paginated messages for a stored session. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js projectName; sessionId limit; offset Structured JSON object response. JSON object with error message and optional details. Touches local workspace files or directories. high
7 http PUT /api/projects/:projectName/rename Projects bearer_token server/index.js 537 PUT /api/projects/:projectName/rename for backend runtime support. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js projectName try { const { displayName JSON object with an explicit success flag and payload. JSON object with error message and optional details. Mutates backend or external state.; Touches local workspace files or directories. high
8 http DELETE /api/projects/:projectName/sessions/:sessionId Sessions bearer_token server/index.js 548 List or manage sessions associated with a project or provider. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js projectName; sessionId JSON object with an explicit success flag and payload. JSON object with error message and optional details. Mutates backend or external state.; Touches local workspace files or directories. high
9 http PUT /api/sessions/:sessionId/rename Sessions bearer_token server/index.js 563 List or manage sessions associated with a project or provider. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js sessionId provider; summary JSON object with an explicit success flag and payload. JSON object with error message and optional details. Mutates backend or external state. low
10 http DELETE /api/projects/:projectName Projects bearer_token server/index.js 589 DELETE /api/projects/:projectName for backend runtime support. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js projectName force JSON object with an explicit success flag and payload. JSON object with error message and optional details. Mutates backend or external state.; Touches local workspace files or directories. high
11 http POST /api/projects/create Projects bearer_token server/index.js 601 Manually add a project path to the workspace list. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js try { const { path JSON object with an explicit success flag and payload. JSON object with error message and optional details. Mutates backend or external state.; Touches local workspace files or directories. high
12 sse GET /api/search/conversations Sessions bearer_token server/index.js 618 Search conversation history across stored projects and stream results. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js limit; q Server-sent events stream with progress/result/error events. Streamed error event or JSON error fallback. Read-only backend query. high
13 http GET /api/browse-filesystem Realtime bearer_token server/index.js 674 Browse local directories so the UI can suggest workspace locations. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js try { const { path Structured JSON object response. JSON object with error message and optional details. Read-only backend query. low
14 http POST /api/create-folder Projects bearer_token server/index.js 754 Create a new directory on the local filesystem. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js try { const { path JSON object with an explicit success flag and payload. JSON object with error message and optional details. Mutates backend or external state. low
15 http GET /api/projects/:projectName/file Files bearer_token server/index.js 795 Read, write, create, rename, delete, or upload project files. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js projectName filePath Structured JSON object response. JSON object with error message and optional details. Touches local workspace files or directories. high
16 http GET /api/projects/:projectName/files/content Files bearer_token server/index.js 835 Read, write, create, rename, delete, or upload project files. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js projectName path Mixed response shape; inspect handler during refactor. JSON object with error message and optional details. Touches local workspace files or directories. high
17 http PUT /api/projects/:projectName/file Files bearer_token server/index.js 888 Read, write, create, rename, delete, or upload project files. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js projectName content; filePath Structured JSON object response. JSON object with error message and optional details. Mutates backend or external state.; Touches local workspace files or directories. high
18 http GET /api/projects/:projectName/files Files bearer_token server/index.js 937 Read, write, create, rename, delete, or upload project files. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js projectName JSON payload returned directly from service logic. JSON object with error message and optional details. Touches local workspace files or directories. high
19 http POST /api/projects/:projectName/files/create Files bearer_token server/index.js 1016 Read, write, create, rename, delete, or upload project files. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js projectName name; path; type Structured JSON object response. JSON object with error message and optional details. Mutates backend or external state.; Touches local workspace files or directories. high
20 http PUT /api/projects/:projectName/files/rename Files bearer_token server/index.js 1093 Read, write, create, rename, delete, or upload project files. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js projectName newName; oldPath Structured JSON object response. JSON object with error message and optional details. Mutates backend or external state.; Touches local workspace files or directories. high
21 http DELETE /api/projects/:projectName/files Files bearer_token server/index.js 1170 Read, write, create, rename, delete, or upload project files. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js projectName path; relativePaths; targetPath; type Structured JSON object response. JSON object with error message and optional details. Mutates backend or external state.; Touches local workspace files or directories. high
22 http POST /api/projects/:projectName/files/upload Files bearer_token server/index.js 1396 Read, write, create, rename, delete, or upload project files. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js projectName Mixed response shape; inspect handler during refactor. Handler-specific error behavior. Mutates backend or external state.; Touches local workspace files or directories. high
23 http POST /api/transcribe Realtime bearer_token server/index.js 1964 Transcribe uploaded audio and optionally enhance the result for prompts or tasks. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js mode Structured JSON object response. JSON object with error message and optional details. Mutates backend or external state.; Processes uploaded files and external model responses. low
24 http POST /api/projects/:projectName/upload-images Files bearer_token server/index.js 2113 Upload images for chat use and return browser-safe data URLs. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js projectName Structured JSON object response. JSON object with error message and optional details. Mutates backend or external state.; Touches local workspace files or directories. high
25 http GET /api/projects/:projectName/sessions/:sessionId/token-usage Sessions bearer_token server/index.js 2198 Report token usage for a stored provider session. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js projectName; sessionId provider Structured JSON object response. JSON object with error message and optional details. Touches local workspace files or directories. high
26 http GET * System public server/index.js 2386 Serve the React application fallback for non-API routes. Static file or HTML response. JSON error response with HTTP status code. Read-only backend query. low
27 http GET /api/auth/status Auth public server/routes/auth.js 9 Report whether authentication is configured. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js Structured JSON object response. JSON object with error message and optional details. Reads or writes local authentication or credential state. medium
28 http POST /api/auth/register Auth public server/routes/auth.js 23 Create the first local user account. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js password; try { const { username Structured JSON object response. JSON object with error message and optional details. Mutates backend or external state.; Reads or writes local authentication or credential state. medium
29 http POST /api/auth/login Auth public server/routes/auth.js 82 Authenticate a local user and issue a token. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js password; try { const { username Structured JSON object response. JSON object with error message and optional details. Mutates backend or external state.; Reads or writes local authentication or credential state. medium
30 http GET /api/auth/user Auth bearer_token server/routes/auth.js 122 Return the currently authenticated user. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js Structured JSON object response. Handler-specific error behavior. Reads or writes local authentication or credential state. medium
31 http POST /api/auth/logout Auth bearer_token server/routes/auth.js 129 Invalidate the current authenticated session. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js JSON object with an explicit success flag and payload. Handler-specific error behavior. Mutates backend or external state.; Reads or writes local authentication or credential state. medium
32 http POST /api/projects/create-workspace Projects bearer_token server/routes/projects.js 175 Create or register a workspace and optionally clone a GitHub repository into it. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js githubTokenId; githubUrl; newGithubToken; path; try { const { workspaceType Structured JSON object response. JSON validation error response. Mutates backend or external state.; Touches local workspace files or directories. high
33 sse GET /api/projects/clone-progress Projects bearer_token server/routes/projects.js 335 Stream workspace cloning progress events to the frontend. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js const { path; githubTokenId; githubUrl; newGithubToken Server-sent events stream with progress/result/error events. Streamed error event or JSON error fallback. Touches local workspace files or directories. high
34 http GET /api/git/status Git bearer_token server/routes/git.js 291 Read git status information for a project. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js const { project Structured JSON object response. JSON validation error response. Touches git repositories or local git config. high
35 http GET /api/git/diff Git bearer_token server/routes/git.js 354 Return git diff output for a project or file. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js const { project; file Structured JSON object response. JSON validation error response. Touches git repositories or local git config. high
36 http GET /api/git/file-with-diff Git bearer_token server/routes/git.js 437 Read, write, create, rename, delete, or upload project files. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js const { project; file Structured JSON object response. JSON validation error response. Touches git repositories or local git config.; Touches local workspace files or directories. high
37 http POST /api/git/initial-commit Git bearer_token server/routes/git.js 517 POST /api/git/initial-commit for backend runtime support. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js const { project JSON object with an explicit success flag and payload. JSON object with error message and optional details. Mutates backend or external state.; Touches git repositories or local git config. high
38 http POST /api/git/commit Git bearer_token server/routes/git.js 561 POST /api/git/commit for backend runtime support. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js const { project; files; message JSON object with an explicit success flag and payload. JSON object with error message and optional details. Mutates backend or external state.; Touches git repositories or local git config. high
39 http POST /api/git/revert-local-commit Git bearer_token server/routes/git.js 592 POST /api/git/revert-local-commit for backend runtime support. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js const { project Structured JSON object response. JSON object with error message and optional details. Mutates backend or external state.; Touches git repositories or local git config. high
40 http GET /api/git/branches Git bearer_token server/routes/git.js 639 List git branches for a project. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js const { project Structured JSON object response. JSON validation error response. Touches git repositories or local git config. high
41 http POST /api/git/checkout Git bearer_token server/routes/git.js 681 POST /api/git/checkout for backend runtime support. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js branch; const { project JSON object with an explicit success flag and payload. JSON object with error message and optional details. Mutates backend or external state.; Touches git repositories or local git config. high
42 http POST /api/git/create-branch Git bearer_token server/routes/git.js 703 POST /api/git/create-branch for backend runtime support. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js branch; const { project JSON object with an explicit success flag and payload. JSON object with error message and optional details. Mutates backend or external state.; Touches git repositories or local git config. high
43 http GET /api/git/commits Git bearer_token server/routes/git.js 725 List recent commits for a project. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js const { project; limit Structured JSON object response. JSON validation error response. Touches git repositories or local git config. high
44 http GET /api/git/commit-diff Git bearer_token server/routes/git.js 782 Return diff details for a specific commit. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js commit; const { project Structured JSON object response. JSON validation error response. Touches git repositories or local git config. high
45 http POST /api/git/generate-commit-message Git bearer_token server/routes/git.js 814 Generate an AI-assisted commit message from the current diff. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js const { project; files; provider Structured JSON object response. JSON object with error message and optional details. Mutates backend or external state.; Touches git repositories or local git config. high
46 http GET /api/git/remote-status Git bearer_token server/routes/git.js 1019 Report remote sync status for a project repository. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js const { project Structured JSON object response. JSON validation error response. Touches git repositories or local git config. high
47 http POST /api/git/fetch Git bearer_token server/routes/git.js 1097 POST /api/git/fetch for backend runtime support. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js const { project JSON object with an explicit success flag and payload. JSON validation error response. Mutates backend or external state.; Touches git repositories or local git config. high
48 http POST /api/git/pull Git bearer_token server/routes/git.js 1138 POST /api/git/pull for backend runtime support. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js const { project Structured JSON object response. JSON validation error response. Mutates backend or external state.; Touches git repositories or local git config. high
49 http POST /api/git/push Git bearer_token server/routes/git.js 1206 POST /api/git/push for backend runtime support. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js const { project Structured JSON object response. JSON validation error response. Mutates backend or external state.; Touches git repositories or local git config. high
50 http POST /api/git/publish Git bearer_token server/routes/git.js 1277 POST /api/git/publish for backend runtime support. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js branch; const { project Structured JSON object response. JSON validation error response. Mutates backend or external state.; Touches git repositories or local git config. high
51 http POST /api/git/discard Git bearer_token server/routes/git.js 1356 POST /api/git/discard for backend runtime support. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js const { project; file JSON object with an explicit success flag and payload. JSON object with error message and optional details. Mutates backend or external state.; Touches git repositories or local git config. high
52 http POST /api/git/delete-untracked Git bearer_token server/routes/git.js 1410 POST /api/git/delete-untracked for backend runtime support. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js const { project; file JSON object with an explicit success flag and payload. JSON object with error message and optional details. Mutates backend or external state.; Touches git repositories or local git config. high
53 http GET /api/mcp/cli/list MCP bearer_token server/routes/mcp.js 16 Manage Claude MCP CLI and configuration state. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js JSON object with an explicit success flag and payload. JSON object with error message and optional details. Reads or writes MCP CLI configuration. medium
54 http POST /api/mcp/cli/add MCP bearer_token server/routes/mcp.js 59 Manage Claude MCP CLI and configuration state. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js JSON object with an explicit success flag and payload. JSON object with error message and optional details. Mutates backend or external state.; Reads or writes MCP CLI configuration. medium
55 http POST /api/mcp/cli/add-json MCP bearer_token server/routes/mcp.js 142 Manage Claude MCP CLI and configuration state. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js jsonConfig; projectPath; scope; try { const { name JSON object with an explicit success flag and payload. JSON object with error message and optional details. Mutates backend or external state.; Reads or writes MCP CLI configuration. medium
56 http DELETE /api/mcp/cli/remove/:name MCP bearer_token server/routes/mcp.js 235 Manage Claude MCP CLI and configuration state. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js name scope JSON object with an explicit success flag and payload. JSON object with error message and optional details. Mutates backend or external state.; Reads or writes MCP CLI configuration. medium
57 http GET /api/mcp/cli/get/:name MCP bearer_token server/routes/mcp.js 305 Manage Claude MCP CLI and configuration state. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js name JSON object with an explicit success flag and payload. JSON object with error message and optional details. Reads or writes MCP CLI configuration. medium
58 http GET /api/mcp/config/read MCP bearer_token server/routes/mcp.js 348 Manage Claude MCP CLI and configuration state. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js Structured JSON object response. JSON error response with HTTP status code. Reads or writes MCP CLI configuration. medium
59 http GET /api/cursor/config Providers bearer_token server/routes/cursor.js 15 Manage Cursor configuration, MCP settings, and stored sessions. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js Structured JSON object response. JSON error response with HTTP status code. Read-only backend query. medium
60 http POST /api/cursor/config Providers bearer_token server/routes/cursor.js 59 Manage Cursor configuration, MCP settings, and stored sessions. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js model; try { const { permissions Structured JSON object response. JSON error response with HTTP status code. Mutates backend or external state. medium
61 http GET /api/cursor/mcp Providers bearer_token server/routes/cursor.js 122 Manage Cursor configuration, MCP settings, and stored sessions. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js Structured JSON object response. JSON error response with HTTP status code. Reads or writes MCP CLI configuration. medium
62 http POST /api/cursor/mcp/add Providers bearer_token server/routes/cursor.js 183 Manage Cursor configuration, MCP settings, and stored sessions. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js Structured JSON object response. JSON error response with HTTP status code. Mutates backend or external state.; Reads or writes MCP CLI configuration. medium
63 http DELETE /api/cursor/mcp/:name Providers bearer_token server/routes/cursor.js 245 Manage Cursor configuration, MCP settings, and stored sessions. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js name Structured JSON object response. JSON error response with HTTP status code. Mutates backend or external state.; Reads or writes MCP CLI configuration. medium
64 http POST /api/cursor/mcp/add-json Providers bearer_token server/routes/cursor.js 292 Manage Cursor configuration, MCP settings, and stored sessions. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js jsonConfig; try { const { name Structured JSON object response. JSON error response with HTTP status code. Mutates backend or external state.; Reads or writes MCP CLI configuration. medium
65 http GET /api/cursor/sessions Providers bearer_token server/routes/cursor.js 348 List or manage sessions associated with a project or provider. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js try { const { projectPath Structured JSON object response. JSON error response with HTTP status code. Read-only backend query. medium
66 http GET /api/cursor/sessions/:sessionId Providers bearer_token server/routes/cursor.js 583 List or manage sessions associated with a project or provider. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js sessionId projectPath Structured JSON object response. JSON error response with HTTP status code. Read-only backend query. medium
67 http GET /api/taskmaster/installation-status TaskMaster bearer_token server/routes/taskmaster.js 243 Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js Structured JSON object response. JSON error response with HTTP status code. Reads or writes TaskMaster project assets. high
68 http GET /api/taskmaster/detect/:projectName TaskMaster bearer_token server/routes/taskmaster.js 278 Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js projectName JSON payload returned directly from service logic. JSON error response with HTTP status code. Reads or writes TaskMaster project assets. high
69 http GET /api/taskmaster/detect-all TaskMaster bearer_token server/routes/taskmaster.js 350 Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js Structured JSON object response. JSON error response with HTTP status code. Reads or writes TaskMaster project assets. high
70 http POST /api/taskmaster/initialize/:projectName TaskMaster bearer_token server/routes/taskmaster.js 434 Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js projectName rules Mixed response shape; inspect handler during refactor. JSON error response with HTTP status code. Mutates backend or external state.; Reads or writes TaskMaster project assets. high
71 http GET /api/taskmaster/next/:projectName TaskMaster bearer_token server/routes/taskmaster.js 460 Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js projectName Structured JSON object response. JSON error response with HTTP status code. Reads or writes TaskMaster project assets. high
72 http GET /api/taskmaster/tasks/:projectName TaskMaster bearer_token server/routes/taskmaster.js 570 Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js projectName Structured JSON object response. JSON error response with HTTP status code. Reads or writes TaskMaster project assets. high
73 http GET /api/taskmaster/prd/:projectName TaskMaster bearer_token server/routes/taskmaster.js 685 Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js projectName Structured JSON object response. JSON error response with HTTP status code. Reads or writes TaskMaster project assets. high
74 http POST /api/taskmaster/prd/:projectName TaskMaster bearer_token server/routes/taskmaster.js 761 Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js projectName content; fileName Structured JSON object response. JSON error response with HTTP status code. Mutates backend or external state.; Reads or writes TaskMaster project assets. high
75 http GET /api/taskmaster/prd/:projectName/:fileName TaskMaster bearer_token server/routes/taskmaster.js 846 Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js projectName; fileName Structured JSON object response. JSON error response with HTTP status code. Reads or writes TaskMaster project assets. high
76 http DELETE /api/taskmaster/prd/:projectName/:fileName TaskMaster bearer_token server/routes/taskmaster.js 911 Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js projectName; fileName Structured JSON object response. JSON error response with HTTP status code. Mutates backend or external state.; Reads or writes TaskMaster project assets. high
77 http POST /api/taskmaster/init/:projectName TaskMaster bearer_token server/routes/taskmaster.js 971 Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js projectName Structured JSON object response. JSON error response with HTTP status code. Mutates backend or external state.; Reads or writes TaskMaster project assets. high
78 http POST /api/taskmaster/add-task/:projectName TaskMaster bearer_token server/routes/taskmaster.js 1060 Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js projectName dependencies; description; priority; prompt; title Structured JSON object response. JSON error response with HTTP status code. Mutates backend or external state.; Reads or writes TaskMaster project assets. high
79 http PUT /api/taskmaster/update-task/:projectName/:taskId TaskMaster bearer_token server/routes/taskmaster.js 1164 Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js projectName; taskId description; details; priority; status; title Structured JSON object response. JSON error response with HTTP status code. Mutates backend or external state.; Reads or writes TaskMaster project assets. high
80 http POST /api/taskmaster/parse-prd/:projectName TaskMaster bearer_token server/routes/taskmaster.js 1291 Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js projectName append; fileName; numTasks Structured JSON object response. JSON error response with HTTP status code. Mutates backend or external state.; Reads or writes TaskMaster project assets. high
81 http GET /api/taskmaster/prd-templates TaskMaster bearer_token server/routes/taskmaster.js 1392 Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js Structured JSON object response. JSON error response with HTTP status code. Reads or writes TaskMaster project assets. high
82 http POST /api/taskmaster/apply-template/:projectName TaskMaster bearer_token server/routes/taskmaster.js 1838 Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js projectName Structured JSON object response. JSON error response with HTTP status code. Mutates backend or external state.; Reads or writes TaskMaster project assets. high
83 http GET /api/mcp-utils/taskmaster-server MCP bearer_token server/routes/mcp-utils.js 18 Return MCP helper information used by setup flows. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js JSON payload returned directly from service logic. JSON error response with HTTP status code. Reads or writes TaskMaster project assets.; Reads or writes MCP CLI configuration. medium
84 http GET /api/mcp-utils/all-servers MCP bearer_token server/routes/mcp-utils.js 35 Return MCP helper information used by setup flows. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js JSON payload returned directly from service logic. JSON error response with HTTP status code. Reads or writes MCP CLI configuration. medium
85 http POST /api/commands/list Commands bearer_token server/routes/commands.js 406 List, load, or execute slash commands available to the chat experience. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js try { const { projectPath Structured JSON object response. JSON error response with HTTP status code. Mutates backend or external state. medium
86 http POST /api/commands/load Commands bearer_token server/routes/commands.js 456 List, load, or execute slash commands available to the chat experience. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js commandPath; try { const { commandPath Structured JSON object response. JSON error response with HTTP status code. Mutates backend or external state. medium
87 http POST /api/commands/execute Commands bearer_token server/routes/commands.js 507 List, load, or execute slash commands available to the chat experience. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js commandPath Structured JSON object response. JSON error response with HTTP status code. Mutates backend or external state. medium
88 http GET /api/settings/api-keys Settings bearer_token server/routes/settings.js 11 Manage local API keys used to access the backend. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js Structured JSON object response. JSON object with error message and optional details. Reads or writes local authentication or credential state. medium
89 http POST /api/settings/api-keys Settings bearer_token server/routes/settings.js 27 Manage local API keys used to access the backend. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js try { const { keyName Structured JSON object response. JSON object with error message and optional details. Mutates backend or external state.; Reads or writes local authentication or credential state. medium
90 http DELETE /api/settings/api-keys/:keyId Settings bearer_token server/routes/settings.js 47 Manage local API keys used to access the backend. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js keyId JSON object with an explicit success flag and payload. JSON object with error message and optional details. Mutates backend or external state.; Reads or writes local authentication or credential state. medium
91 http PATCH /api/settings/api-keys/:keyId/toggle Settings bearer_token server/routes/settings.js 64 Manage local API keys used to access the backend. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js keyId isActive JSON object with an explicit success flag and payload. JSON object with error message and optional details. Mutates backend or external state.; Reads or writes local authentication or credential state. medium
92 http GET /api/settings/credentials Settings bearer_token server/routes/settings.js 91 Manage stored provider and GitHub credentials. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js try { const { type Structured JSON object response. JSON object with error message and optional details. Reads or writes local authentication or credential state. medium
93 http POST /api/settings/credentials Settings bearer_token server/routes/settings.js 104 Manage stored provider and GitHub credentials. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js credentialType; credentialValue; description; try { const { credentialName Structured JSON object response. JSON object with error message and optional details. Mutates backend or external state.; Reads or writes local authentication or credential state. medium
94 http DELETE /api/settings/credentials/:credentialId Settings bearer_token server/routes/settings.js 139 Manage stored provider and GitHub credentials. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js credentialId JSON object with an explicit success flag and payload. JSON object with error message and optional details. Mutates backend or external state.; Reads or writes local authentication or credential state. medium
95 http PATCH /api/settings/credentials/:credentialId/toggle Settings bearer_token server/routes/settings.js 156 Manage stored provider and GitHub credentials. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js credentialId isActive JSON object with an explicit success flag and payload. JSON object with error message and optional details. Mutates backend or external state.; Reads or writes local authentication or credential state. medium
96 http GET /api/cli/claude/status CLI Auth bearer_token server/routes/cli-auth.js 9 Report local authentication status for provider CLIs. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js Structured JSON object response. JSON error response with HTTP status code. Read-only backend query. low
97 http GET /api/cli/cursor/status CLI Auth bearer_token server/routes/cli-auth.js 39 Report local authentication status for provider CLIs. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js Structured JSON object response. JSON error response with HTTP status code. Read-only backend query. low
98 http GET /api/cli/codex/status CLI Auth bearer_token server/routes/cli-auth.js 59 Report local authentication status for provider CLIs. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js Structured JSON object response. JSON error response with HTTP status code. Read-only backend query. low
99 http GET /api/cli/gemini/status CLI Auth bearer_token server/routes/cli-auth.js 79 Report local authentication status for provider CLIs. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js Structured JSON object response. JSON error response with HTTP status code. Read-only backend query. low
100 http GET /api/user/git-config User bearer_token server/routes/user.js 28 Read or update stored git identity settings. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js Structured JSON object response. JSON object with error message and optional details. Touches git repositories or local git config. medium
101 http POST /api/user/git-config User bearer_token server/routes/user.js 57 Read or update stored git identity settings. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js gitEmail; try { const userId = req.user.id; const { gitName Structured JSON object response. JSON object with error message and optional details. Mutates backend or external state.; Touches git repositories or local git config. medium
102 http POST /api/user/complete-onboarding User bearer_token server/routes/user.js 93 Mark onboarding as completed for the current user. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js Structured JSON object response. JSON object with error message and optional details. Mutates backend or external state. medium
103 http GET /api/user/onboarding-status User bearer_token server/routes/user.js 108 Return onboarding completion status for the current user. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js Structured JSON object response. JSON object with error message and optional details. Read-only backend query. medium
104 http GET /api/codex/config Providers bearer_token server/routes/codex.js 23 Manage Codex configuration, MCP settings, and stored sessions. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js Structured JSON object response. JSON error response with HTTP status code. Read-only backend query. medium
105 http GET /api/codex/sessions Providers bearer_token server/routes/codex.js 54 List or manage sessions associated with a project or provider. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js try { const { projectPath JSON object with an explicit success flag and payload. JSON error response with HTTP status code. Read-only backend query. medium
106 http GET /api/codex/sessions/:sessionId/messages Providers bearer_token server/routes/codex.js 71 Return paginated messages for a stored session. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js sessionId limit; offset JSON object with an explicit success flag and payload. JSON error response with HTTP status code. Read-only backend query. medium
107 http DELETE /api/codex/sessions/:sessionId Providers bearer_token server/routes/codex.js 89 List or manage sessions associated with a project or provider. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js sessionId JSON object with an explicit success flag and payload. JSON error response with HTTP status code. Mutates backend or external state. medium
108 http GET /api/codex/mcp/cli/list Providers bearer_token server/routes/codex.js 103 Manage Codex configuration, MCP settings, and stored sessions. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js Mixed response shape; inspect handler during refactor. JSON object with error message and optional details. Reads or writes MCP CLI configuration. medium
109 http POST /api/codex/mcp/cli/add Providers bearer_token server/routes/codex.js 135 Manage Codex configuration, MCP settings, and stored sessions. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js Mixed response shape; inspect handler during refactor. JSON object with error message and optional details. Mutates backend or external state.; Reads or writes MCP CLI configuration. medium
110 http DELETE /api/codex/mcp/cli/remove/:name Providers bearer_token server/routes/codex.js 186 Manage Codex configuration, MCP settings, and stored sessions. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js name Mixed response shape; inspect handler during refactor. JSON object with error message and optional details. Mutates backend or external state.; Reads or writes MCP CLI configuration. medium
111 http GET /api/codex/mcp/cli/get/:name Providers bearer_token server/routes/codex.js 220 Manage Codex configuration, MCP settings, and stored sessions. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js name Mixed response shape; inspect handler during refactor. JSON object with error message and optional details. Reads or writes MCP CLI configuration. medium
112 http GET /api/codex/mcp/config/read Providers bearer_token server/routes/codex.js 254 Manage Codex configuration, MCP settings, and stored sessions. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js JSON object with an explicit success flag and payload. JSON object with error message and optional details. Reads or writes MCP CLI configuration. medium
113 http GET /api/gemini/sessions/:sessionId/messages Providers bearer_token server/routes/gemini.js 8 Return paginated messages for a stored session. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js sessionId Structured JSON object response. JSON error response with HTTP status code. Read-only backend query. medium
114 http DELETE /api/gemini/sessions/:sessionId Providers bearer_token server/routes/gemini.js 37 List or manage sessions associated with a project or provider. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js sessionId JSON object with an explicit success flag and payload. JSON error response with HTTP status code. Mutates backend or external state. medium
115 http GET /api/plugins Plugins bearer_token server/routes/plugins.js 27 List, install, update, serve, enable, or remove plugins. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js Structured JSON object response. JSON object with error message and optional details. Installs, updates, or serves plugin assets/processes. medium
116 http GET /api/plugins/:name/manifest Plugins bearer_token server/routes/plugins.js 40 List, install, update, serve, enable, or remove plugins. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js name JSON payload returned directly from service logic. JSON object with error message and optional details. Installs, updates, or serves plugin assets/processes. medium
117 http GET /api/plugins/:name/assets/* Plugins bearer_token server/routes/plugins.js 57 List, install, update, serve, enable, or remove plugins. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js name Mixed response shape; inspect handler during refactor. JSON object with error message and optional details. Installs, updates, or serves plugin assets/processes. medium
118 http PUT /api/plugins/:name/enable Plugins bearer_token server/routes/plugins.js 96 List, install, update, serve, enable, or remove plugins. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js name try { const { enabled JSON object with an explicit success flag and payload. JSON object with error message and optional details. Mutates backend or external state.; Installs, updates, or serves plugin assets/processes. medium
119 http POST /api/plugins/install Plugins bearer_token server/routes/plugins.js 136 List, install, update, serve, enable, or remove plugins. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js try { const { url JSON object with an explicit success flag and payload. JSON validation error response. Mutates backend or external state.; Installs, updates, or serves plugin assets/processes. medium
120 http POST /api/plugins/:name/update Plugins bearer_token server/routes/plugins.js 169 List, install, update, serve, enable, or remove plugins. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js name JSON object with an explicit success flag and payload. JSON validation error response. Mutates backend or external state.; Installs, updates, or serves plugin assets/processes. medium
121 http DELETE /api/plugins/:name Plugins bearer_token server/routes/plugins.js 282 List, install, update, serve, enable, or remove plugins. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js name JSON object with an explicit success flag and payload. JSON validation error response. Mutates backend or external state.; Installs, updates, or serves plugin assets/processes. medium
122 sse POST /api/agent Agent api_key_or_platform server/routes/agent.js 839 Accept external agent jobs that run a provider against a local or cloned project. src/components/chat/hooks/useChatComposerState.ts; src/components/chat/hooks/useChatProviderState.ts; src/components/chat/hooks/useChatSessionState.ts; src/components/chat/hooks/useSlashCommands.ts; src/components/file-tree/view/ImageViewer.tsx; src/components/git-panel/hooks/useGitPanelController.ts; src/components/git-panel/hooks/useRevertLocalCommit.ts; src/components/onboarding/view/Onboarding.tsx; src/components/plugins/view/PluginIcon.tsx; src/components/plugins/view/PluginTabContent.tsx; src/components/prd-editor/hooks/usePrdSave.ts; src/components/project-creation-wizard/data/workspaceApi.ts; src/components/settings/constants/constants.ts; src/components/settings/hooks/useCredentialsSettings.ts; src/components/settings/hooks/useGitSettings.ts; src/components/settings/hooks/useSettingsController.ts; src/components/version-upgrade/view/VersionUpgradeModal.tsx; src/contexts/PluginsContext.tsx; src/utils/api.js branchName; cleanup; const { githubUrl; createBranch; createPR; githubToken; message; model; projectPath; provider; stream Server-sent events stream with progress/result/error events. Streamed error event or JSON error fallback. Mutates backend or external state.; Invokes external AI providers and may modify project files. high

File diff suppressed because it is too large Load Diff

View File

@@ -1,217 +0,0 @@
# Backend Inventory
Generated on 2026-03-11T17:31:18.119Z.
## Summary
- HTTP routes: 118
- SSE routes: 3
- Modular routes: 96
- Inline routes: 25
- Route files scanned: 16
## Realtime Contracts
- Incoming websocket message types (14): abort-session, check-session-status, claude-command, claude-permission-response, codex-command, cursor-abort, cursor-command, cursor-resume, gemini-command, get-active-sessions, get-pending-permissions, init, input, resize
- Outgoing websocket message types (7): active-sessions, auth_url, error, output, pending-permissions-response, session-aborted, session-status
## Agent
| Method | Path | Auth | Purpose | Consumers | Source |
| --- | --- | --- | --- | --- | --- |
| POST | `/api/agent` | api_key_or_platform | Accept external agent jobs that run a provider against a local or cloned project. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/agent.js:839 |
## Auth
| Method | Path | Auth | Purpose | Consumers | Source |
| --- | --- | --- | --- | --- | --- |
| POST | `/api/auth/login` | public | Authenticate a local user and issue a token. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/auth.js:82 |
| POST | `/api/auth/logout` | bearer_token | Invalidate the current authenticated session. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/auth.js:129 |
| POST | `/api/auth/register` | public | Create the first local user account. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/auth.js:23 |
| GET | `/api/auth/status` | public | Report whether authentication is configured. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/auth.js:9 |
| GET | `/api/auth/user` | bearer_token | Return the currently authenticated user. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/auth.js:122 |
## CLI Auth
| Method | Path | Auth | Purpose | Consumers | Source |
| --- | --- | --- | --- | --- | --- |
| GET | `/api/cli/claude/status` | bearer_token | Report local authentication status for provider CLIs. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/cli-auth.js:9 |
| GET | `/api/cli/codex/status` | bearer_token | Report local authentication status for provider CLIs. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/cli-auth.js:59 |
| GET | `/api/cli/cursor/status` | bearer_token | Report local authentication status for provider CLIs. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/cli-auth.js:39 |
| GET | `/api/cli/gemini/status` | bearer_token | Report local authentication status for provider CLIs. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/cli-auth.js:79 |
## Commands
| Method | Path | Auth | Purpose | Consumers | Source |
| --- | --- | --- | --- | --- | --- |
| POST | `/api/commands/execute` | bearer_token | List, load, or execute slash commands available to the chat experience. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/commands.js:507 |
| POST | `/api/commands/list` | bearer_token | List, load, or execute slash commands available to the chat experience. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/commands.js:406 |
| POST | `/api/commands/load` | bearer_token | List, load, or execute slash commands available to the chat experience. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/commands.js:456 |
## Files
| Method | Path | Auth | Purpose | Consumers | Source |
| --- | --- | --- | --- | --- | --- |
| GET | `/api/projects/:projectName/file` | bearer_token | Read, write, create, rename, delete, or upload project files. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/index.js:795 |
| PUT | `/api/projects/:projectName/file` | bearer_token | Read, write, create, rename, delete, or upload project files. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/index.js:888 |
| GET | `/api/projects/:projectName/files` | bearer_token | Read, write, create, rename, delete, or upload project files. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/index.js:937 |
| DELETE | `/api/projects/:projectName/files` | bearer_token | Read, write, create, rename, delete, or upload project files. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/index.js:1170 |
| GET | `/api/projects/:projectName/files/content` | bearer_token | Read, write, create, rename, delete, or upload project files. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/index.js:835 |
| POST | `/api/projects/:projectName/files/create` | bearer_token | Read, write, create, rename, delete, or upload project files. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/index.js:1016 |
| PUT | `/api/projects/:projectName/files/rename` | bearer_token | Read, write, create, rename, delete, or upload project files. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/index.js:1093 |
| POST | `/api/projects/:projectName/files/upload` | bearer_token | Read, write, create, rename, delete, or upload project files. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/index.js:1396 |
| POST | `/api/projects/:projectName/upload-images` | bearer_token | Upload images for chat use and return browser-safe data URLs. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/index.js:2113 |
## Git
| Method | Path | Auth | Purpose | Consumers | Source |
| --- | --- | --- | --- | --- | --- |
| GET | `/api/git/branches` | bearer_token | List git branches for a project. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/git.js:639 |
| POST | `/api/git/checkout` | bearer_token | POST /api/git/checkout for backend runtime support. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/git.js:681 |
| POST | `/api/git/commit` | bearer_token | POST /api/git/commit for backend runtime support. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/git.js:561 |
| GET | `/api/git/commit-diff` | bearer_token | Return diff details for a specific commit. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/git.js:782 |
| GET | `/api/git/commits` | bearer_token | List recent commits for a project. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/git.js:725 |
| POST | `/api/git/create-branch` | bearer_token | POST /api/git/create-branch for backend runtime support. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/git.js:703 |
| POST | `/api/git/delete-untracked` | bearer_token | POST /api/git/delete-untracked for backend runtime support. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/git.js:1410 |
| GET | `/api/git/diff` | bearer_token | Return git diff output for a project or file. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/git.js:354 |
| POST | `/api/git/discard` | bearer_token | POST /api/git/discard for backend runtime support. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/git.js:1356 |
| POST | `/api/git/fetch` | bearer_token | POST /api/git/fetch for backend runtime support. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/git.js:1097 |
| GET | `/api/git/file-with-diff` | bearer_token | Read, write, create, rename, delete, or upload project files. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/git.js:437 |
| POST | `/api/git/generate-commit-message` | bearer_token | Generate an AI-assisted commit message from the current diff. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/git.js:814 |
| POST | `/api/git/initial-commit` | bearer_token | POST /api/git/initial-commit for backend runtime support. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/git.js:517 |
| POST | `/api/git/publish` | bearer_token | POST /api/git/publish for backend runtime support. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/git.js:1277 |
| POST | `/api/git/pull` | bearer_token | POST /api/git/pull for backend runtime support. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/git.js:1138 |
| POST | `/api/git/push` | bearer_token | POST /api/git/push for backend runtime support. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/git.js:1206 |
| GET | `/api/git/remote-status` | bearer_token | Report remote sync status for a project repository. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/git.js:1019 |
| POST | `/api/git/revert-local-commit` | bearer_token | POST /api/git/revert-local-commit for backend runtime support. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/git.js:592 |
| GET | `/api/git/status` | bearer_token | Read git status information for a project. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/git.js:291 |
## MCP
| Method | Path | Auth | Purpose | Consumers | Source |
| --- | --- | --- | --- | --- | --- |
| GET | `/api/mcp-utils/all-servers` | bearer_token | Return MCP helper information used by setup flows. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/mcp-utils.js:35 |
| GET | `/api/mcp-utils/taskmaster-server` | bearer_token | Return MCP helper information used by setup flows. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/mcp-utils.js:18 |
| POST | `/api/mcp/cli/add` | bearer_token | Manage Claude MCP CLI and configuration state. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/mcp.js:59 |
| POST | `/api/mcp/cli/add-json` | bearer_token | Manage Claude MCP CLI and configuration state. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/mcp.js:142 |
| GET | `/api/mcp/cli/get/:name` | bearer_token | Manage Claude MCP CLI and configuration state. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/mcp.js:305 |
| GET | `/api/mcp/cli/list` | bearer_token | Manage Claude MCP CLI and configuration state. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/mcp.js:16 |
| DELETE | `/api/mcp/cli/remove/:name` | bearer_token | Manage Claude MCP CLI and configuration state. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/mcp.js:235 |
| GET | `/api/mcp/config/read` | bearer_token | Manage Claude MCP CLI and configuration state. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/mcp.js:348 |
## Plugins
| Method | Path | Auth | Purpose | Consumers | Source |
| --- | --- | --- | --- | --- | --- |
| GET | `/api/plugins` | bearer_token | List, install, update, serve, enable, or remove plugins. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/plugins.js:27 |
| DELETE | `/api/plugins/:name` | bearer_token | List, install, update, serve, enable, or remove plugins. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/plugins.js:282 |
| GET | `/api/plugins/:name/assets/*` | bearer_token | List, install, update, serve, enable, or remove plugins. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/plugins.js:57 |
| PUT | `/api/plugins/:name/enable` | bearer_token | List, install, update, serve, enable, or remove plugins. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/plugins.js:96 |
| GET | `/api/plugins/:name/manifest` | bearer_token | List, install, update, serve, enable, or remove plugins. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/plugins.js:40 |
| POST | `/api/plugins/:name/update` | bearer_token | List, install, update, serve, enable, or remove plugins. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/plugins.js:169 |
| POST | `/api/plugins/install` | bearer_token | List, install, update, serve, enable, or remove plugins. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/plugins.js:136 |
## Projects
| Method | Path | Auth | Purpose | Consumers | Source |
| --- | --- | --- | --- | --- | --- |
| POST | `/api/create-folder` | bearer_token | Create a new directory on the local filesystem. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/index.js:754 |
| GET | `/api/projects` | bearer_token | List detected projects and workspaces. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/index.js:491 |
| DELETE | `/api/projects/:projectName` | bearer_token | DELETE /api/projects/:projectName for backend runtime support. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/index.js:589 |
| PUT | `/api/projects/:projectName/rename` | bearer_token | PUT /api/projects/:projectName/rename for backend runtime support. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/index.js:537 |
| GET | `/api/projects/clone-progress` | bearer_token | Stream workspace cloning progress events to the frontend. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/projects.js:335 |
| POST | `/api/projects/create` | bearer_token | Manually add a project path to the workspace list. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/index.js:601 |
| POST | `/api/projects/create-workspace` | bearer_token | Create or register a workspace and optionally clone a GitHub repository into it. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/projects.js:175 |
## Providers
| Method | Path | Auth | Purpose | Consumers | Source |
| --- | --- | --- | --- | --- | --- |
| GET | `/api/codex/config` | bearer_token | Manage Codex configuration, MCP settings, and stored sessions. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/codex.js:23 |
| POST | `/api/codex/mcp/cli/add` | bearer_token | Manage Codex configuration, MCP settings, and stored sessions. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/codex.js:135 |
| GET | `/api/codex/mcp/cli/get/:name` | bearer_token | Manage Codex configuration, MCP settings, and stored sessions. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/codex.js:220 |
| GET | `/api/codex/mcp/cli/list` | bearer_token | Manage Codex configuration, MCP settings, and stored sessions. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/codex.js:103 |
| DELETE | `/api/codex/mcp/cli/remove/:name` | bearer_token | Manage Codex configuration, MCP settings, and stored sessions. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/codex.js:186 |
| GET | `/api/codex/mcp/config/read` | bearer_token | Manage Codex configuration, MCP settings, and stored sessions. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/codex.js:254 |
| GET | `/api/codex/sessions` | bearer_token | List or manage sessions associated with a project or provider. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/codex.js:54 |
| DELETE | `/api/codex/sessions/:sessionId` | bearer_token | List or manage sessions associated with a project or provider. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/codex.js:89 |
| GET | `/api/codex/sessions/:sessionId/messages` | bearer_token | Return paginated messages for a stored session. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/codex.js:71 |
| GET | `/api/cursor/config` | bearer_token | Manage Cursor configuration, MCP settings, and stored sessions. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/cursor.js:15 |
| POST | `/api/cursor/config` | bearer_token | Manage Cursor configuration, MCP settings, and stored sessions. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/cursor.js:59 |
| GET | `/api/cursor/mcp` | bearer_token | Manage Cursor configuration, MCP settings, and stored sessions. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/cursor.js:122 |
| DELETE | `/api/cursor/mcp/:name` | bearer_token | Manage Cursor configuration, MCP settings, and stored sessions. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/cursor.js:245 |
| POST | `/api/cursor/mcp/add` | bearer_token | Manage Cursor configuration, MCP settings, and stored sessions. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/cursor.js:183 |
| POST | `/api/cursor/mcp/add-json` | bearer_token | Manage Cursor configuration, MCP settings, and stored sessions. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/cursor.js:292 |
| GET | `/api/cursor/sessions` | bearer_token | List or manage sessions associated with a project or provider. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/cursor.js:348 |
| GET | `/api/cursor/sessions/:sessionId` | bearer_token | List or manage sessions associated with a project or provider. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/cursor.js:583 |
| DELETE | `/api/gemini/sessions/:sessionId` | bearer_token | List or manage sessions associated with a project or provider. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/gemini.js:37 |
| GET | `/api/gemini/sessions/:sessionId/messages` | bearer_token | Return paginated messages for a stored session. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/gemini.js:8 |
## Realtime
| Method | Path | Auth | Purpose | Consumers | Source |
| --- | --- | --- | --- | --- | --- |
| GET | `/api/browse-filesystem` | bearer_token | Browse local directories so the UI can suggest workspace locations. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/index.js:674 |
| POST | `/api/transcribe` | bearer_token | Transcribe uploaded audio and optionally enhance the result for prompts or tasks. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/index.js:1964 |
## Sessions
| Method | Path | Auth | Purpose | Consumers | Source |
| --- | --- | --- | --- | --- | --- |
| GET | `/api/projects/:projectName/sessions` | bearer_token | List or manage sessions associated with a project or provider. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/index.js:500 |
| DELETE | `/api/projects/:projectName/sessions/:sessionId` | bearer_token | List or manage sessions associated with a project or provider. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/index.js:548 |
| GET | `/api/projects/:projectName/sessions/:sessionId/messages` | bearer_token | Return paginated messages for a stored session. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/index.js:512 |
| GET | `/api/projects/:projectName/sessions/:sessionId/token-usage` | bearer_token | Report token usage for a stored provider session. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/index.js:2198 |
| GET | `/api/search/conversations` | bearer_token | Search conversation history across stored projects and stream results. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/index.js:618 |
| PUT | `/api/sessions/:sessionId/rename` | bearer_token | List or manage sessions associated with a project or provider. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/index.js:563 |
## Settings
| Method | Path | Auth | Purpose | Consumers | Source |
| --- | --- | --- | --- | --- | --- |
| GET | `/api/settings/api-keys` | bearer_token | Manage local API keys used to access the backend. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/settings.js:11 |
| POST | `/api/settings/api-keys` | bearer_token | Manage local API keys used to access the backend. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/settings.js:27 |
| DELETE | `/api/settings/api-keys/:keyId` | bearer_token | Manage local API keys used to access the backend. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/settings.js:47 |
| PATCH | `/api/settings/api-keys/:keyId/toggle` | bearer_token | Manage local API keys used to access the backend. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/settings.js:64 |
| GET | `/api/settings/credentials` | bearer_token | Manage stored provider and GitHub credentials. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/settings.js:91 |
| POST | `/api/settings/credentials` | bearer_token | Manage stored provider and GitHub credentials. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/settings.js:104 |
| DELETE | `/api/settings/credentials/:credentialId` | bearer_token | Manage stored provider and GitHub credentials. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/settings.js:139 |
| PATCH | `/api/settings/credentials/:credentialId/toggle` | bearer_token | Manage stored provider and GitHub credentials. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/settings.js:156 |
## System
| Method | Path | Auth | Purpose | Consumers | Source |
| --- | --- | --- | --- | --- | --- |
| GET | `*` | public | Serve the React application fallback for non-API routes. | - | server/index.js:2386 |
| POST | `/api/system/update` | bearer_token | Run the application update workflow on the host machine. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/index.js:425 |
| GET | `/health` | public | Expose server health, timestamp, and install mode for diagnostics. | src/hooks/useVersionCheck.ts | server/index.js:345 |
## TaskMaster
| Method | Path | Auth | Purpose | Consumers | Source |
| --- | --- | --- | --- | --- | --- |
| POST | `/api/taskmaster/add-task/:projectName` | bearer_token | Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/taskmaster.js:1060 |
| POST | `/api/taskmaster/apply-template/:projectName` | bearer_token | Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/taskmaster.js:1838 |
| GET | `/api/taskmaster/detect-all` | bearer_token | Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/taskmaster.js:350 |
| GET | `/api/taskmaster/detect/:projectName` | bearer_token | Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/taskmaster.js:278 |
| POST | `/api/taskmaster/init/:projectName` | bearer_token | Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/taskmaster.js:971 |
| POST | `/api/taskmaster/initialize/:projectName` | bearer_token | Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/taskmaster.js:434 |
| GET | `/api/taskmaster/installation-status` | bearer_token | Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/taskmaster.js:243 |
| GET | `/api/taskmaster/next/:projectName` | bearer_token | Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/taskmaster.js:460 |
| POST | `/api/taskmaster/parse-prd/:projectName` | bearer_token | Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/taskmaster.js:1291 |
| GET | `/api/taskmaster/prd-templates` | bearer_token | Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/taskmaster.js:1392 |
| GET | `/api/taskmaster/prd/:projectName` | bearer_token | Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/taskmaster.js:685 |
| POST | `/api/taskmaster/prd/:projectName` | bearer_token | Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/taskmaster.js:761 |
| GET | `/api/taskmaster/prd/:projectName/:fileName` | bearer_token | Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/taskmaster.js:846 |
| DELETE | `/api/taskmaster/prd/:projectName/:fileName` | bearer_token | Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/taskmaster.js:911 |
| GET | `/api/taskmaster/tasks/:projectName` | bearer_token | Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/taskmaster.js:570 |
| PUT | `/api/taskmaster/update-task/:projectName/:taskId` | bearer_token | Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/taskmaster.js:1164 |
## User
| Method | Path | Auth | Purpose | Consumers | Source |
| --- | --- | --- | --- | --- | --- |
| POST | `/api/user/complete-onboarding` | bearer_token | Mark onboarding as completed for the current user. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/user.js:93 |
| GET | `/api/user/git-config` | bearer_token | Read or update stored git identity settings. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/user.js:28 |
| POST | `/api/user/git-config` | bearer_token | Read or update stored git identity settings. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/user.js:57 |
| GET | `/api/user/onboarding-status` | bearer_token | Return onboarding completion status for the current user. | src/components/chat/hooks/useChatComposerState.ts<br>src/components/chat/hooks/useChatProviderState.ts<br>src/components/chat/hooks/useChatSessionState.ts<br>src/components/chat/hooks/useSlashCommands.ts<br>src/components/file-tree/view/ImageViewer.tsx<br>src/components/git-panel/hooks/useGitPanelController.ts<br>src/components/git-panel/hooks/useRevertLocalCommit.ts<br>src/components/onboarding/view/Onboarding.tsx<br>src/components/plugins/view/PluginIcon.tsx<br>src/components/plugins/view/PluginTabContent.tsx<br>src/components/prd-editor/hooks/usePrdSave.ts<br>src/components/project-creation-wizard/data/workspaceApi.ts<br>src/components/settings/constants/constants.ts<br>src/components/settings/hooks/useCredentialsSettings.ts<br>src/components/settings/hooks/useGitSettings.ts<br>src/components/settings/hooks/useSettingsController.ts<br>src/components/version-upgrade/view/VersionUpgradeModal.tsx<br>src/contexts/PluginsContext.tsx<br>src/utils/api.js | server/routes/user.js:108 |

View File

@@ -1,314 +0,0 @@
# Cross-Platform Input Parsing Notes
## Why This Matters In This Repo
CloudCLI is not only an HTTP API plus React UI. From the README and current backend layout, it also launches CLIs, keeps interactive terminal sessions alive, reads and writes local files, parses process output, and forwards terminal input from the browser into local shells. That puts the backend on the boundary between browser input, terminal behavior, child process behavior, and filesystem behavior. Linux and Windows differ at each of those boundaries.
For the TypeScript migration, the OS adapter layer now lives in:
- [server/src/shared/platform/index.ts](/c:/Users/OMEN6/Desktop/Projects/Paid/ClaudeCodeUI%20-%20Siteboon/claudecodeui/server/src/shared/platform/index.ts)
Use those helpers in new `server/src` code so feature modules do not branch on the operating system.
## Assumptions
- The legacy runtime in `server/index.js` stays untouched for now.
- New backend code will be added under `server/src`.
- Node.js 22 is the baseline because the README already requires Node 22+.
- The main instability is text handling around shells, streams, and files, not business logic.
## Where Parsing Happens In This Repo
- `server/index.js`: PTY shell input/output and session reuse
- `server/cursor-cli.js`: streaming line-delimited JSON from `cursor-agent`
- `server/gemini-response-handler.js`: incremental parsing of Gemini JSON lines
- `server/routes/mcp.js` and `server/routes/codex.js`: parsing human-readable CLI output
- `server/cli.js` and `server/load-env.js`: parsing command-line args and `.env` text
- `server/routes/git.js` and related routes: parsing Git stdout line by line
Those are not all the same problem. In this repo, "input parsing" means terminal input parsing, stream parsing, file parsing, shell command construction, and path normalization.
## Core Terms
### Process
A process is a running program such as `node server/start.js`, `git`, `codex`, or `cursor-agent`. When your backend launches one of these, the backend is the parent process and the launched program is the child process.
### Child Process
A child process is a process started by another process. Examples:
- CloudCLI launches `git status`
- CloudCLI launches `codex mcp list`
- CloudCLI launches `cursor-agent --output-format stream-json`
Important point: a child process usually does not hand you one final string. It emits output over time.
### stdin, stdout, stderr
These are the three standard streams:
- `stdin`: data going into the process
- `stdout`: normal output coming out
- `stderr`: diagnostics, warnings, and errors
Node example:
```ts
const child = spawn('git', ['status']);
child.stdout.on('data', (chunk) => {
// normal output from git
});
child.stderr.on('data', (chunk) => {
// warnings or errors
});
child.stdin.write('yes\n');
child.stdin.end();
```
Repo examples:
- terminal keystrokes go to `stdin`
- `cursor-agent` JSON events arrive on `stdout`
- many CLI failures appear on `stderr`
### TTY and PTY
- `TTY`: a terminal device
- `PTY`: a pseudo-terminal, meaning software that behaves like a terminal
Why it matters:
- `spawn()` is best for non-interactive commands like `git status`
- `node-pty` is best for interactive shells like PowerShell or bash sessions
Repo example: `server/index.js` uses `node-pty` for the integrated shell because agents and shells expect terminal behavior, not just plain pipes.
### argv
`argv` means argument vector: the list of command-line arguments passed to a program.
Example:
```ts
spawn('git', ['log', '--oneline', '-5']);
```
Here the executable is `git` and the argv is `['log', '--oneline', '-5']`. This is safer than building one big shell string because Node passes arguments directly instead of asking a shell to reinterpret them.
### cwd
`cwd` means current working directory. Examples:
- run `git status` in the project root
- run `claude mcp add --scope local` inside the current project
- run a terminal session inside a selected workspace
If `cwd` is wrong, parsing may look broken even when the parser is correct, because the command itself is operating in the wrong place.
### Buffer, String, and Decoding
A `Buffer` is raw bytes. A string is decoded text. Processes emit bytes first, then you decode them, and only after that should you parse lines, JSON, or tokens.
Example:
```ts
child.stdout.on('data', (chunk: Buffer) => {
const text = chunk.toString('utf8');
});
```
### Line Ending
A line ending marks the end of a text line:
- Linux/macOS usually use LF: `\n`
- Windows often uses CRLF: `\r\n`
- older tools sometimes emit CR alone: `\r`
Classic bug:
```ts
'a\r\nb\r\n'.split('\n');
// ['a\r', 'b\r', '']
```
That hidden trailing `\r` is one of the most common Windows parsing bugs.
### BOM
BOM means byte order mark. In UTF-8 text it appears as `\uFEFF` at the start. Typical failures:
- first key becomes `\uFEFFNAME` instead of `NAME`
- JSON parsing fails because the first character is not what the parser expected
- `.env` parsing silently produces the wrong first variable name
The adapter layer strips BOM explicitly for that reason.
### Chunk
A chunk is one partial piece of stream data. Chunks are transport boundaries, not logical message boundaries. Important rules:
- one line can arrive in multiple chunks
- one chunk can contain many lines
- one JSON object can be split across chunk boundaries
Example:
```txt
Chunk 1: {"type":"message","text":"hel
Chunk 2: lo"}\r\n{"type":"message","text":"next"}\r\n
```
If you parse each chunk independently, you corrupt the first JSON object.
## The Backend Parsing Lifecycle
Most backend parsing problems in this repo can be viewed as a four-step pipeline:
1. Receive raw bytes or raw text.
2. Normalize transport details.
3. Parse business structure.
4. Return normalized data to the rest of the app.
Examples:
- file bytes -> UTF-8 string -> normalize line endings -> split lines -> parse fields
- stdout chunks -> accumulate partial lines -> parse JSON per line -> emit events
- browser terminal input -> normalize Enter/newlines -> write to PTY
The operating system mainly affects step 2. That is why the new adapter layer exists.
## Linux vs Windows Differences That Usually Matter
### 1. Newlines In Files And Process Output
Linux usually gives LF. Windows often gives CRLF. Some tools mix them.
Bad pattern:
```ts
const lines = output.split('\n');
```
Safer pattern:
```ts
import { splitLines } from '@/shared/platform/index.js';
const lines = splitLines(output, {
preserveEmptyLines: false,
trimTrailingEmptyLine: true,
});
```
Use `splitLines()` when you already have the whole string in memory.
### 2. Chunked Streams
A process stream is not line-oriented by default.
Bad pattern:
```ts
child.stdout.on('data', (chunk) => {
const event = JSON.parse(chunk.toString());
});
```
This fails when one JSON object is split across chunks.
Safer pattern:
```ts
import { createStreamLineAccumulator } from '@/shared/platform/index.js';
const lines = createStreamLineAccumulator({ preserveEmptyLines: false });
child.stdout.on('data', (chunk) => {
for (const line of lines.push(chunk)) {
const event = JSON.parse(line);
}
});
child.on('close', () => {
for (const line of lines.flush()) {
const event = JSON.parse(line);
}
});
```
Use this for Cursor, Gemini, JSONL, NDJSON, or any line-based CLI protocol.
### 3. Shell Syntax And Fallback Logic
POSIX shells and PowerShell do not use the same syntax.
- POSIX fallback: `cmd1 || cmd2`
- PowerShell fallback: `cmd1; if ($LASTEXITCODE -ne 0) { cmd2 }`
Use:
```ts
import { buildFallbackCommand, createShellSpawnPlan } from '@/shared/platform/index.js';
const shellCommand = buildFallbackCommand('codex resume 123', 'codex', 'windows');
const spawnPlan = createShellSpawnPlan(shellCommand, 'windows');
```
This keeps feature code from hardcoding bash rules into Windows paths or PowerShell rules into Linux code.
### 4. Quoting Rules
Even when two shells both support quotes, they do not escape them the same way.
- POSIX single quote escape is awkward: `'it'"'"'s'`
- PowerShell single quote escape doubles the quote: `'it''s'`
Use:
```ts
import { quoteShellArgument } from '@/shared/platform/index.js';
const safe = quoteShellArgument("it's", 'windows');
```
### 5. Path Separators And Case
- Linux paths use `/`
- Windows paths typically use `\`
- Linux is usually case-sensitive
- Windows is usually case-insensitive
Examples:
- `/repo/File.ts` and `/repo/file.ts` are different on Linux
- `C:\Repo\File.ts` and `c:\repo\file.ts` usually refer to the same file on Windows
Use:
```ts
import { arePathsEquivalent, normalizePathForPlatform, toPortablePath } from '@/shared/platform/index.js';
```
Guideline:
- use platform-specific paths when calling the OS
- use portable slash paths for logs, keys, and serialized payloads
### 6. Terminal Input
Terminal input is not the same as a normal HTML form submission.
- pressing Enter may arrive as `\r`
- pasted text may contain `\n` or `\r\n`
- terminal apps often expect carriage return behavior
Use:
```ts
import { normalizeTerminalInput } from '@/shared/platform/index.js';
```
This matters for PTY writes because terminal software often treats `\r` as the real Enter key behavior.
## The New Adapter Functions
- `normalizeTextForParsing()`: use when your goal is parsing text consistently, not preserving original file style; good for `.env`, JSONL, human-readable CLI output, and buffered command output.
- `splitLines()`: use when the full text is already in memory and you want clean logical lines; good for config files, buffered Git output, and fully collected CLI output.
- `createStreamLineAccumulator()`: use when text arrives incrementally over time; good for `stdout`, `stderr`, line-based streaming JSON, and long-lived child processes.
- `createShellSpawnPlan()`: use when the command must go through a shell because shell syntax is required; good for fallback commands, resume-or-start command chains, and interactive shell launch plans.
- `quoteShellArgument()`: use before interpolating dynamic values into shell command strings; good for session IDs, file paths, branch names, and user-provided subcommands.
- `buildFallbackCommand()`: use when the same logic must work in bash and PowerShell; a repo-shaped example is "resume Codex session if it exists, otherwise start a fresh one."
- `preserveExistingLineEndings()`: use when writing text files back to disk and you want to avoid noisy diffs; good for markdown files, config files, and user-managed text artifacts.
## Practical Backend Rules For This Repo
1. If you already have the full text, normalize once and then parse.
2. If the source is a stream, use an accumulator and never parse per chunk.
3. Prefer `spawn(executable, argv, { shell: false })` whenever possible.
4. Only use a shell when shell syntax is actually needed.
5. When you must use a shell, push all shell-specific behavior into the adapter layer.
6. Preserve existing line endings on user files unless you intentionally want normalization.
7. Separate transport normalization from business parsing.
## Common Mistakes To Avoid
- Parsing stdout chunk-by-chunk. Symptom: random JSON parse failures or truncated events. Fix: accumulate complete lines first.
- Using `split('\n')` on Windows text. Symptom: values end with `\r` and equality checks fail. Fix: normalize line endings or use `splitLines()`.
- Building one huge shell string for everything. Symptom: quoting bugs, OS-specific failures, and injection risk. Fix: prefer `spawn()` with argv; if shell is required, use `quoteShellArgument()` and `createShellSpawnPlan()`.
- Rewriting files with a different line-ending style. Symptom: huge git diffs and noisy file changes. Fix: use `preserveExistingLineEndings()`.
## Testing Strategy Implemented Here
This strategy intentionally does not add Jest, Vitest, or another test framework.
It uses:
- Node's built-in `node:test`
- `tsx` only to execute TypeScript tests
- a GitHub Actions matrix on Ubuntu and Windows
Local verification:
```bash
npm run test:server
npm run verify:server
```
CI verification:
- `npm run typecheck:server`
- `npm run test:server`
- `npm run server:build`
This gives you two kinds of confidence:
- contract confidence: the adapter functions behave as designed
- environment confidence: the same checks pass on real Linux and Windows runners
## Final Mental Model
Think in three layers:
1. Raw transport layer. Examples: chunks, bytes, terminal keystrokes, raw file text.
2. Normalization layer. Examples: strip BOM, normalize line endings, normalize terminal input, normalize shell behavior.
3. Business parsing layer. Examples: parse JSON, parse CLI output, parse `.env`, parse Git status, parse session files.
If you keep layer 2 in shared adapters, layer 3 stops caring about Linux vs Windows.

View File

@@ -1,190 +0,0 @@
# LLM Module Structure (Refactor Runtime)
This document describes the current backend structure under `server/src/modules/llm`, how execution/session state works, and how the provider abstraction is designed.
## High-Level Layout
```text
server/src/modules/llm/
llm.routes.ts
llm.registry.ts
providers/
provider.interface.ts
abstract.provider.ts
base-sdk.provider.ts
base-cli.provider.ts
claude.provider.ts
codex.provider.ts
cursor.provider.ts
gemini.provider.ts
services/
llm.service.ts
sessions.service.ts
sessions-watcher.service.ts
messages-unifier.service.ts
assets.service.ts
mcp.service.ts
skills.service.ts
session-indexers/
session-indexer.interface.ts
session-indexer.utils.ts
claude.session-indexer.ts
codex.session-indexer.ts
cursor.session-indexer.ts
gemini.session-indexer.ts
index.ts
tests/
llm-unifier.providers.test.ts
llm-unifier.sessions.test.ts
llm-unifier.images.test.ts
llm-unifier.mcp.test.ts
llm-unifier.skills.test.ts
llm-unifier.messages.test.ts
```
## Responsibilities By File Group
- `llm.routes.ts`
- HTTP API for provider runtime sessions (start/resume/stop/model/thinking), normalized session/history messages, assets upload, MCP config/probe, skills listing, indexed session CRUD/sync.
- `llm.registry.ts`
- Singleton provider registry. Instantiates one provider class per provider id.
- `providers/*`
- Runtime execution and live event collection.
- SDK family (`BaseSdkProvider`) for Claude/Codex.
- CLI family (`BaseCliProvider`) for Cursor/Gemini.
- `services/llm.service.ts`
- Input validation + capability gating + facade over provider registry.
- `services/sessions.service.ts`
- DB-backed indexed sessions and history file parsing.
- Returns normalized message history via `messages-unifier.service.ts`.
- `services/sessions-watcher.service.ts`
- `chokidar` watchers for provider artifact folders.
- On filesystem update, triggers `synchronizeProviderFile(provider, filePath)`.
- `services/messages-unifier.service.ts`
- Provider-specific raw event/history -> unified message contract for frontend.
- `services/assets.service.ts`
- Stores uploaded images in `.cloudcli/assets`.
- `services/mcp.service.ts`
- Unified MCP CRUD/probe across provider-native config formats/scopes/transports.
- `services/skills.service.ts`
- Provider-specific skill directory discovery and metadata extraction.
- `session-indexers/*`
- Scans provider artifacts from disk and upserts indexed sessions into `sessions` DB table.
## Runtime Flow (Provider Sessions)
1. `POST /api/llm/providers/:provider/sessions/start` hits `llm.routes.ts`.
2. Route calls `llmService.startSession(...)`.
3. `llm.service.ts` validates payload and capability constraints.
4. `llm.registry.ts` resolves provider instance.
5. Provider (`BaseSdkProvider` or `BaseCliProvider`) creates an in-memory session record and starts execution.
6. Stream/process output is appended as in-memory `ProviderSessionEvent[]`.
7. Route can either:
- return `202` immediately with snapshot, or
- await completion via `waitForSession`.
8. Snapshots are enriched with unified `messages` via `llmMessagesUnifier.normalizeSessionEvents(...)`.
## Indexed History Flow (Disk/DB)
1. Watcher or manual sync scans provider folders.
2. Provider-specific indexer extracts minimal metadata and upserts `sessionsDb`.
3. History endpoints (`/sessions/:sessionId/history`, `/sessions/:sessionId/messages`) read transcript path from DB.
4. JSON/JSONL is parsed and transformed via `llmMessagesUnifier.normalizeHistoryEntries(...)`.
## Interface + Abstract + Base-Class Design
### `IProvider` (interface)
`providers/provider.interface.ts`
- Consumer contract used by registry/service layer.
- Exposes:
- `launchSession`, `resumeSession`, `stopSession`, `waitForSession`
- `setSessionModel`, `setSessionThinkingMode`
- `getSession`, `listSessions`
- `listModels`
- Exposes `capabilities` so callers can gate unsupported features before calling provider-specific logic.
### `AbstractProvider` (abstract class)
`providers/abstract.provider.ts`
- Shared lifecycle state and rules:
- `sessions: Map<string, MutableProviderSession>`
- `sessionPreferences: Map<string, { model?, thinkingMode? }>`
- Implements:
- in-memory session reads (`getSession`, `listSessions`, `waitForSession`)
- stop handling + session status events
- model/thinking updates with capability checks
- event ring-buffer logic (`MAX_EVENT_BUFFER_SIZE`)
- Leaves provider execution specifics abstract (`listModels`, `launchSession`, `resumeSession`).
### `BaseSdkProvider` and `BaseCliProvider`
- `BaseSdkProvider`
- shared async iterable stream consumption.
- handles completion/error transitions and completion system event emission.
- `BaseCliProvider`
- shared child-process spawn + stdout/stderr line accumulation + JSON line parsing.
- graceful stop (`SIGTERM` then `SIGKILL`) and completion/error transitions.
### Concrete provider classes
- `ClaudeProvider` (SDK)
- uses `@anthropic-ai/claude-agent-sdk`.
- supports runtime permission requests and emits permission events.
- image payload support via base64 content blocks.
- `CodexProvider` (SDK)
- dynamic import of `@openai/codex-sdk`.
- supports text + `local_image` prompt items.
- `CursorProvider` (CLI)
- `cursor-agent` invocation builder + model list parsing.
- `GeminiProvider` (CLI)
- `gemini` invocation builder + curated model catalog.
## In-Memory Session Setup: How It Works
The in-memory part is inside `AbstractProvider` + base classes:
- Session record is created at launch/resume in memory (`Map`).
- Events are appended in real-time while stream/process runs.
- Snapshot endpoints read this map directly (`/providers/:provider/sessions...`).
- Stop/wait/model/thinking controls operate on this same in-memory handle.
- Completed sessions currently remain in map (bounded event history per session, but no map eviction).
Key characteristics:
- Process-local only (not shared across instances).
- Lost on server restart.
- Good for immediate live control and progress.
- Not the source of truth for historical transcripts (disk/DB is).
## Is In-Memory Session State Necessary, Or Useless?
Short answer: **not useless**, but **not sufficient as a durable architecture**.
### Why it is necessary in the current design
- You need live handles for:
- `stopSession` (abort process/stream now),
- `waitForSession`,
- real-time event buffering for immediate API responses.
- These are runtime concerns and cannot be satisfied by session-index DB rows alone.
### Where it is weak
- No eviction/pruning for completed session map entries.
- No persistence across restart.
- No cross-instance coordination (if horizontally scaled, only the owning instance can control that session).
### Practical conclusion
- Keep in-memory runtime state for **active execution control**.
- Treat DB/indexed history as the durable read model.
- If you need reliability across restarts/instances, move execution ownership to a durable worker/orchestrator and store live session metadata in a shared store.
## Suggested Hardening (Incremental)
1. Add session map eviction policy (TTL/LRU for completed/failed/stopped sessions).
2. Add ownership metadata (`instanceId`) if multiple backend instances will run.
3. Add explicit `activeSessions` metric endpoint.
4. Optionally persist minimal runtime state (status transitions + timestamps) to DB for auditability.

View File

@@ -1,456 +0,0 @@
# How each provider supports image uploading
Universally: First, we should upload the images in `.cloudcli/assets` folder. Then, it should just reference that path later on.
## Claude
- When clicking send, attach the images in the content list with the type of 'image'.
- https://platform.claude.com/docs/en/api/messages#message_param
```js
const imageBytes = await fs.readFile(imagePath);
const sdkPrompt = (async function*: AsyncIterable<SDKUserMessage> () {
yield {
type: 'user',
message: {
role: 'user',
content: [
{ type: 'text', text: prompt },
{
type: 'image',
source: {
type: 'base64',
media_type: 'image/jpeg',
data: imageBytes.toString('base64'),
},
},
],
},
parent_tool_use_id: null,
timestamp: new Date().toISOString(),
};
})(); // automatically executed because of the `()` in the end.
```
### Some useful types
```ts
export interface MessageParam {
content: string | Array<ContentBlockParam>;
role: 'user' | 'assistant'; // when we send the message for prompting, the role will be 'user'
}
/**
* Regular text content.
*/
export type ContentBlockParam =
| TextBlockParam
| ImageBlockParam
| DocumentBlockParam
| SearchResultBlockParam
| ThinkingBlockParam
| RedactedThinkingBlockParam
| ToolUseBlockParam
| ToolResultBlockParam
| ServerToolUseBlockParam
| WebSearchToolResultBlockParam;
export interface TextBlockParam {
text: string;
type: 'text';
}
export interface ImageBlockParam {
source: Base64ImageSource | URLImageSource; // I'll be using only base 64 for now.
type: 'image';
}
export interface Base64ImageSource {
data: string;
media_type: 'image/jpeg' | 'image/png' | 'image/gif' | 'image/webp';
type: 'base64';
}
```
### Explanations about async generators and yield
To understand why `async function*` is used, it helps to stop thinking of functions as "machines that run and finish" and start thinking of them as **"factories that stay open."**
```ts
async function* getTaskStatus(): AsyncIterable<string> {
yield "Checking permissions...";
await new Promise(r => setTimeout(r, 500)); // Simulate work
yield "Searching database...";
await new Promise(r => setTimeout(r, 500));
yield "Formatting prompt...";
}
// CONSUMPTION
async function run() {
const statusGenerator = getTaskStatus();
for await (const status of statusGenerator) {
console.log(`Current Status: ${status}`);
}
console.log("Done!");
}
```
## Codex
```ts
const streamed = await thread.runStreamed([ {type: "text", text: "Describe this image:"}, {type: "local_image", path: "scripts/pic.jpg"}
```
- Don't add the above query lines for codex. We can directly use the `sdk`.
## Gemini and Cursor
- Just add the path to the end of the prompt when clicking send for paths including images. For e.g.
```
<some-user-prompt>
<images_input>
---- IGNORE THE <images_input> QUERY LINES. Just use the attached list of an array of paths for images below and use it with the above prompt.
["scripts\pic.jpg", "<path-for-second-image>", ...]
```
# MCP servers (how to add/remove one and run it)
**What is the Model Context Protocol (MCP)?**
Think of MCP as the USB-C cable for AI.
- Historically, if you wanted an AI model to read your GitHub repository, query your database, or search your company's Notion workspace, developers had to write custom, one-off integrations for every single AI tool.
- Created by Anthropic as an open-source standard, the Model Context Protocol fixes this. It is a universal language that allows AI applications (the "clients") to securely connect to external data sources and tools (the "servers") using a single, unified protocol.
**What is an MCP Server?**
- If MCP is the USB-C cable, an **MCP Server** is the hard drive or webcam you are plugging in.
- It is a lightweight program that acts as a secure bridge between your specific data and the AI. When the AI needs context—like checking the current state of a file or executing a search—it asks the MCP server. The server translates the AI's request, securely fetches the data or performs the action, and hands the result back to the AI.
**Different transport mechanisms for MCP servers**
1. `stdio` - This is the default and most common transport for local development. When using `stdio`, the AI client directly launches the MCP server as a background "child process" on your machine. The client and server then talk to each other locally by writing to and reading from standard input (`stdin`) and standard output (`stdout`).
- **Clear Example:** A local **File System Server**. You want the AI to read your local `package.json` file. The AI client spawns the file system server via `stdio`. Because the server is running locally on your hardware, it inherently has access to your files without needing complex authentication. It reads the file and prints the contents back to the AI.
2. `https` (Streamable HTTP) - Streamable HTTP replaces older remote methods. It uses a single HTTP or HTTPS endpoint for bidirectional communication. The client sends standard `POST` requests, and the server can respond instantly or keep the connection open to stream data back. It behaves exactly like a modern web API. Because it runs over HTTP, it supports standard web security features like OAuth, Bearer tokens, and CORS.
- **Clear Example:** A **Cloud Database Server**. If you work on a team and want everyone's AI to be able to query a shared staging database, you would deploy an MCP server to the cloud. Your AI connects to `https://api.yourcompany.com/mcp` using Streamable HTTP and passes an API key in the headers to securely run queries.
3. `sse` (Server sent events) - SSE is the legacy transport mechanism for remote servers. While still widely supported, it is actively being phased out in favor of Streamable HTTP because it is slightly more cumbersome to build and maintain.
- **How it works:** Unlike Streamable HTTP which uses a single unified endpoint, SSE requires _two_ distinct network connections. The client connects to an SSE endpoint (via an HTTP `GET` request) strictly to listen for incoming messages from the server, and uses a separate HTTP `POST` endpoint to send messages to the server.
- **Clear Example:** An older **Slack Integration Server**. The AI client connects to the server's SSE stream to listen for real-time incoming messages from a Slack channel. When the AI wants to reply, it sends a payload to a separate `/message` POST endpoint.
**Frontend coordination**
- When listing the MCP servers for a provider, go to the appropriate files where the configuration is stored to fetch all of them. When listing, the User/Local/Project MCPs should be grouped separately.
- To add/remove an MCP server, go to the appropriate file and add/remove it there keeping in mind whether it is configured as User/Local/Project.
- To update the server, go to the appropriate file and update it from there.
- There should also be one big mcp adder that supports `http` and `stdio` only. When it's added from there, the server will automatically be added to every provider.
## Claude
Supports all 3 transports.
### `stdio`
- We can have arguments and env variables input when executing the command.
- `args` and `env` are optional.
```json
{
"mcpServers": {
"local-weather": {
"type": "stdio",
"command": "/path/to/weather-cli",
"args": ["--api-key", "abc123"],
"env": {
"CACHE_DIR": "/tmp"
}
}
}
}
```
### `http`
- We don't pass `env` inputs for now. It's supported but we will add it only later.
- `headers` is optional.
```json
{
"mcpServers": {
"weather-api": {
"type": "http",
"url": "https://api.weather.com/mcp",
"headers": {
"Authorization": "Bearer token"
}
}
}
}
```
### `sse`
- similar with `http` format.
```json
{
"mcpServers": {
"private-api": {
"type": "sse",
"url": "https://api.company.com/sse",
"headers": {
"X-API-Key": "your-key-here"
}
}
}
}
```
### Support for different modes (Local, user, project)
#### Local
- stored in `~/.claude.json` under the projects path.
#### User
- stored in `~/.claude.json` under the main object with the key `"mcpServers"
#### Project specific
- add it in the `.mcp.json` file in the project root directory.
## Codex
### Configuration (Only `stdio` and `http` are supported.)
#### `stdio`
- `command` (required): The command that starts the server.
- `args` (optional): Arguments to pass to the server.
- `env` (optional): Environment variables to set for the server.
- `env_vars` (optional): Environment variables to allow and forward.
- `cwd` (optional): Working directory to start the server from.
```toml
[mcp_servers.my_stdio]
command = "npx"
args = ["-y", "@upstash/context7-mcp"]
[mcp_servers.my_stdio.env]
API_KEY = "your-key"
```
With forwarded host env vars.
```toml
[mcp_servers.my_stdio]
command = "python"
args = ["server.py"]
env_vars = ["API_KEY", "DEBUG"]
cwd = "/path/to/project"
```
#### `http`
- `url` (required): The server address.
- `bearer_token_env_var` (optional): Environment variable name for a bearer token to send in `Authorization`.
- `http_headers` (optional): Map of header names to static values.
- `env_http_headers` (optional): Map of header names to environment variable names (values pulled from the environment).
```toml
[mcp_servers.my_http]
url = "https://example.com/mcp"
bearer_token_env_var = "MY_API_TOKEN"
http_headers = { "X-Custom-Header" = "custom-value" }
env_http_headers = { "X-Api-Key" = "MY_API_KEY_ENV" }
```
### Support for different modes (user, project)
#### User
- add it to the global `~/.codex/config.toml` file.
#### Project specific
- add it in `.codex/config.toml` file in the project's root directory.
## Gemini
Supports all 3 transports.
### `stdio`
- We can have arguments and env variables as inputs when executing the command.
- `args` and `env` are optional.
- No `type` attribute like Claude for `stdio`. If there is no type, we can infer that it must be `stdio` since the rest have it.
```json
{
"mcpServers": {
"serverName": {
"command": "path/to/server",
"args": ["--arg1", "value1"],
"env": {
"API_KEY": "$MY_API_TOKEN"
},
"cwd": "./server-directory"
}
}
}
```
### `http`
- We don't pass `env` inputs. Notice the type is set here like Claude.
- `headers` is optional.
- EXACTLY same as Claude `http`.
```json
{
"mcpServers": {
"weather-api": {
"type": "http",
"url": "https://api.weather.com/mcp",
"headers": {
"Authorization": "Bearer token"
}
}
}
}
```
### `sse`
- similar with `http` format.
- EXACT with Claude `sse` format.
```json
{
"mcpServers": {
"private-api": {
"type": "sse",
"url": "https://api.company.com/sse",
"headers": {
"X-API-Key": "your-key-here"
}
}
}
}
```
### Support for different modes (user, project)
#### User
- stored in `~/.gemini/settings.json`.
#### Project specific
- add it in the `.gemini/settings.json` file in the project root directory.
## Cursor
Supports all 3 transports. There is no `type` attribute for all 3. Here are the structures:
#### `stdio`
```json
{
"mcpServers": {
"server-name": {
"command": "npx",
"args": ["-y", "mcp-server"],
"env": {
"API_KEY": "value"
}
}
}
}
```
#### `http` / `sse`
```json
// MCP server using HTTP or SSE - runs on a server
{
"mcpServers": {
"server-name": {
"url": "http://localhost:3000/mcp",
"headers": {
"API_KEY": "value"
}
}
}
}
```
### Support for different modes (user, project)
#### User
- stored in `~/.cursor/mcp.json`.
#### Project specific
- add it in the `.cursor/mcp.json` file in the project root directory.
# Skills management (ONLY Fetching support needed for now)
## Claude
- To get user skills, fetch all `~/.claude/skills/<skill-name>/SKILL.md`.
- To get project skills, fetch from `.claude/skills/<skill-name>/SKILL.md`.
- To get plugin skills:
- Find all the enabled plugins in `~/.claude/settings.json`.
```json
{
"apiKeyHelper": "...",
"enabledPlugins": {
"example-skills@anthropic-agent-skills": true
},
...
}
```
- Then go to `~/.claude/plugins/installed_plugins.json` file to find where the plugin is installed.
```json
{
"version": 2,
"plugins": {
"example-skills@anthropic-agent-skills": [
{
"scope": "user",
"installPath": "C:\\Users\\OMEN6\\.claude\\plugins\\cache\\anthropic-agent-skills\\example-skills\\3d5951151859",
"version": "3d5951151859",
"installedAt": "2026-03-03T12:52:08.024Z",
"lastUpdated": "2026-03-03T12:52:08.024Z",
"gitCommitSha": "3d59511518591fa82e6cfcf0438d68dd5dad3e76"
}
]
}
}
```
- Then go the `installPath` directory. If there is a `skills` folder there, go to each of the skills in `<install-path>/skills/<skill-name>/SKILL.md`.
Then, parse the name and description of the skills from the md for every `SKILL.md`.
- The command for invoking skills is `/<skill-name>` .
- Whenever a skill is from a plugin, doing `/skill-name` should automatically be updated with `/plugin-name:skill-name`. This is because plugin skills use a `plugin-name:skill-name` namespace, so they cannot conflict with other levels.
I have attached the first initial contents of a sample `SKILL.md` file below.
```md
---
name: mcp-builder
description: Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node/TypeScript (MCP SDK).
license: Complete terms in LICENSE.txt
---
```
## Codex
Codex reads skills from repository, user, admin, and system locations.
| Skill Scope | Location | Suggested use |
| ----------- | ------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `REPO` | `$CWD/.agents/skills` <br>Current working directory: where you launch Codex. | If youre in a repository or code environment, teams can check in skills relevant to a working folder. For example, skills only relevant to a microservice or a module. |
| `REPO` | ` $CWD/../.agents/skills` <br>A folder above CWD when you launch Codex inside a Git repository. | If youre in a repository with nested folders, organizations can check in skills relevant to a shared area in a parent folder. |
| `REPO` | `$REPO_ROOT/.agents/skills` <br>The topmost root folder when you launch Codex inside a Git repository. | If youre in a repository with nested folders, organizations can check in skills relevant to everyone using the repository. These serve as root skills available to any subfolder in the repository. |
| `USER` | `$HOME/.agents/skills` <br>Any skills checked into the users personal folder. | Use to curate skills relevant to a user that apply to any repository the user may work in. |
| `ADMIN` | `/etc/codex/skills` <br>Any skills checked into the machine or container in a shared, system location. | Use for SDK scripts, automation, and for checking in default admin skills available to each user on the machine. |
| `SYSTEM` | `~/.codex/skills/.system` | Useful skills relevant to a broad audience such as the skill-creator and plan skills. Available to everyone when they start Codex. |
Then, parse the name and description of the skills from the md for every `SKILL.md`.
- The command for invoking skills is `$<skill-name>`
## Gemini
- Gets all skills from `~/.gemini/skills`, `~/.agents/skills`, `.gemini/skills`, `.agents/skills`
- command for invoking skills is same as Claude.
## Cursor
[Skill directories](https://cursor.com/docs/skills?utm_source=chatgpt.com#skill-directories)
Skills are automatically loaded from these locations:
|Location|Scope|
|---|---|
|`.agents/skills/`|Project-level|
|`.cursor/skills/`|Project-level|
|`~/.cursor/skills/`|User-level (global)|
Then, parse the name and description of the skills from the md for every `SKILL.md`.
- command for invoking skills is same as Claude.

File diff suppressed because it is too large Load Diff

View File

@@ -1,461 +0,0 @@
# How each session processes sessions
- The way each session processes the sessions is already setup in `server/src/modules/providers`. Port over the existing logic to the new classes if possible.
# How to start, resume, and stop a session
## Claude
A new session is created by calling `query({ prompt, options })` which yields an async stream of SDK messages. The session ID can be provided explicitly by using `resume` option and passing the session id (`sdkOptions.resume = sessionId;`).
https://platform.claude.com/docs/en/agent-sdk/typescript#types
Session can be stopped midway using `queryInstance.interrupt()`
https://platform.claude.com/docs/en/agent-sdk/typescript#methods
## Codex
- Starting - `const thread = codex.startThread(threadOptions)`
- Resuming - `codex.resumeThread(sessionId, threadOptions);`
- Stop a session
```
    // Execute with streaming
    const streamedTurn = await thread.runStreamed(command, {
      signal: abortController.signal
    });
```
### About Abort controllers
- Think of `AbortController` as a **cancel button for async work**.
- **Controller** = thing that sends the cancel command.
- **Signal** = thing that receives or carries the cancel state
```js
const controller = new AbortController();
fetch("https://api.example.com/data", {
signal: controller.signal
})
.then(response => response.json())
.then(data => {
console.log("Finished:", data);
})
.catch(error => {
if (error.name === "AbortError") {
console.log("The request was cancelled");
} else {
console.error("Real error:", error);
}
});
// Cancel it after 2 seconds
setTimeout(() => {
controller.abort();
}, 2000);
```
- `AbortController` does **not magically stop all JavaScript everywhere**. It only works if the API or function you are using actually supports cancellation via a signal. `fetch` does. Your own custom async functions can too, but you have to write that support yourself. In codex, the method `runStreamed` supports it as well.
```js
function wait(ms, { signal } = {}) {
return new Promise((resolve, reject) => {
// if signal was aborted EVEN BEFORE the function started, return back.
// This catches the case where someone did this first:
// controller.abort("Cancelled already");
// wait(5000, { signal: controller.signal });
if (signal?.aborted) {
reject(signal.reason); // it supports custom reasoning as well.
return;
}
const timeoutId = setTimeout(() => {
resolve("Done waiting");
}, ms);
// when the signal.abort event is fired (when controller.abort() is called somewhere else), it sends an `abort` event.
// When we get this, remove the timeoutId
signal?.addEventListener("abort", () => {
clearTimeout(timeoutId);
reject(signal.reason);
});
});
}
// ---------------- USAGE --------------------
const controller = new AbortController();
wait(5000, { signal: controller.signal })
.then(result => {
console.log(result);
})
.catch(error => {
console.log("Cancelled:", error);
});
setTimeout(() => {
controller.abort("User cancelled the wait");
}, 1000);
```
## Gemini
### Start
spawn `gemini --prompt "actualprompt" --model "actual model", --output-format 'stream-json'`
- Stream `json` output format send responses in terms of a series of `json` chunks. If we store it, we would use .`jsonl` format.
- Allowed tools aren't needed as it's depreciated.
```
--allowed-tools [DEPRECATED: Use Policy Engine instead See
https://geminicli.com/docs/core/policy-engine] Tools that are allowed
to run without confirmation
```
- `--prompt` allows us to run just one prompt in headless mode. It will automatically trust the workspace directory so it won't ask us whether we trust the workspace or not.
### Stop/Abort a session
```js
try {
geminiProc.kill('SIGTERM'); // gracefully terminates the process. It ASKS the process to shut down cleanly. The process can catch it, save state, close files, and exit
setTimeout(() => {
geminiProc.kill('SIGKILL'); // kills it immediately
}
}, 2000); // Wait 2 seconds before force kill
return true;
} catch (error) {
return false;
}
```
### resume
- spawn `gemini <the above formats> --resume <sessionId>`
### To receive a response
```
child.stdout.on('data', (chunk) => {
const text = chunk.toString();
...
})
child.stderr.on('data', (chunk) => {
const text = chunk.toString();
...
}
```
## Cursor
### Start
- spawn `cursor-agent --print --trust --output-format 'stream-json' <actual-prompt'>`
This won't be able to run shell commands like `git init`. To be able to run those, `--yolo` must be passed.
### Resume
- spawn `cursor-agent <above commands> --resume <sessionID>`
### abort
- same approach as gemini.
# How to fetch (list the model types supported for each model...find out if there is an easy way to fetch automatically from the files)
## Claude
`query.supportedModels()` returns `ModelInfo[]`.
```ts
/**
* Information about an available model.
*/
export declare type ModelInfo = {
/**
* Model identifier to use in API calls
*/
value: string;
/**
* Human-readable display name
*/
displayName: string;
/**
* Description of the model's capabilities
*/
description: string;
/**
* Whether this model supports effort levels
*/
supportsEffort?: boolean;
/**
* Available effort levels for this model
*/
supportedEffortLevels?: ('low' | 'medium' | 'high' | 'max')[];
/**
* Whether this model supports adaptive thinking (Claude decides when and how much to think)
*/
supportsAdaptiveThinking?: boolean;
};
```
```
supported models = [
{
value: 'default',
displayName: 'Default (recommended)',
description: 'Use the default model (currently Sonnet 4.6) · $3/$15 per Mtok',
supportsEffort: true,
supportedEffortLevels: [ 'low', 'medium', 'high', 'max' ],
supportsAdaptiveThinking: true
},
{
value: 'sonnet[1m]',
displayName: 'Sonnet (1M context)',
description: 'Sonnet 4.6 for long sessions · $6/$22.50 per Mtok',
supportsEffort: true,
supportedEffortLevels: [ 'low', 'medium', 'high', 'max' ],
supportsAdaptiveThinking: true
},
{
value: 'opus',
displayName: 'Opus',
description: 'Opus 4.6 · Most capable for complex work · $5/$25 per Mtok',
supportsEffort: true,
supportedEffortLevels: [ 'low', 'medium', 'high', 'max' ],
supportsAdaptiveThinking: true
},
{
value: 'opus[1m]',
displayName: 'Opus (1M context)',
description: 'Opus 4.6 for long sessions · $10/$37.50 per Mtok',
supportsEffort: true,
supportedEffortLevels: [ 'low', 'medium', 'high', 'max' ],
supportsAdaptiveThinking: true
},
{
value: 'haiku',
displayName: 'Haiku',
description: 'Haiku 4.5 · Fastest for quick answers · $1/$5 per Mtok'
},
{
value: 'sonnet',
displayName: 'sonnet',
description: 'Custom model',
supportsEffort: true,
supportedEffortLevels: [ 'low', 'medium', 'high', 'max' ],
supportsAdaptiveThinking: true
}
]
```
## Codex
- Found in `.codex/models_cache.json`. It's in the `models` attribute.
```json
{
...,
"models": [
{
"slug": "gpt-5.4",
"display_name": "gpt-5.4",
"description": "Latest frontier agentic coding model.",
"default_reasoning_level": "medium",
"supported_reasoning_levels": [
{
"effort": "low",
"description": "Fast responses with lighter reasoning"
},
{
"effort": "medium",
"description": "Balances speed and reasoning depth for everyday tasks"
},
{
"effort": "high",
"description": "Greater reasoning depth for complex problems"
},
{
"effort": "xhigh",
"description": "Extra high reasoning depth for complex problems"
}
],
"shell_type": "shell_command",
"visibility": "list",
"supported_in_api": true,
"priority": 1,
"availability_nux": null,
"upgrade": null,
"base_instructions": "...",
"model_messages": {
"instructions_template": "...",
"instructions_variables": {
"personality_default": "",
"personality_friendly": "..."
}
},
"supports_reasoning_summaries": true,
"default_reasoning_summary": "none",
"support_verbosity": true,
"default_verbosity": "low",
"apply_patch_tool_type": "freeform",
"web_search_tool_type": "text_and_image",
"truncation_policy": {
"mode": "tokens",
"limit": 10000
},
"supports_parallel_tool_calls": true,
"supports_image_detail_original": true,
"context_window": 272000,
"effective_context_window_percent": 95,
"experimental_supported_tools": [],
"input_modalities": [
"text",
"image"
],
"supports_search_tool": true
},
{
...
}
]
}
```
## Gemini
- There is no way to automatically do this. So, use this
![[Pasted image 20260401124033.png]]
The above is for free one. The below contains for all.
```
OPTIONS: [
{ value: 'gemini-3.1-pro-preview', label: 'Gemini 3.1 Pro Preview' },
{ value: 'gemini-3-pro-preview', label: 'Gemini 3 Pro Preview' },
{ value: 'gemini-3-flash-preview', label: 'Gemini 3 Flash Preview' },
{ value: 'gemini-2.5-flash', label: 'Gemini 2.5 Flash' },
{ value: 'gemini-2.5-pro', label: 'Gemini 2.5 Pro' },
{ value: 'gemini-2.0-flash-lite', label: 'Gemini 2.0 Flash Lite' },
{ value: 'gemini-2.0-flash', label: 'Gemini 2.0 Flash' },
{ value: 'gemini-2.0-pro-exp', label: 'Gemini 2.0 Pro Experimental' },
{ value: 'gemini-2.0-flash-thinking-exp', label: 'Gemini 2.0 Flash Thinking' }
],
```
## Cursor
- spawn `cursor-agent --list-models` and parse the ANSI output.
```js
function parseModelLine(line) {
const trimmed = line.trim();
if (!trimmed || trimmed === 'Available models' || trimmed.startsWith('Loading models') || trimmed.startsWith('Tip:')) {
return null;
}
const match = trimmed.match(/^(.+?)\s+-\s+(.+)$/);
if (!match) {
return null;
}
const name = match[1].trim();
let description = match[2].trim();
const current = /\(current\)/i.test(description);
const defaultModel = /\(default\)/i.test(description);
description = description.replace(/\s*\((current|default)\)/gi, '').replace(/\s{2,}/g, ' ').trim();
return {
name,
description,
current,
default: defaultModel,
};
}
function parseModelsOutput(text) {
const models = [];
for (const line of stripAnsi(text).split(/\r?\n/)) {
const parsed = parseModelLine(line);
if (parsed) {
models.push(parsed);
}
}
return models;
}
// ------------ tHE ABOVE RETURNS ------------
[
{
"name": "auto",
"description": "Auto",
"current": true,
"default": false
},
{
"name": "composer-2-fast",
"description": "Composer 2 Fast",
"current": false,
"default": true
},
{
"name": "composer-2",
"description": "Composer 2",
"current": false,
"default": false
},
...
]
```
# How to fetch session history
- In the sessions table, there is a `jsonl_path` column. Go to directly that and parse the JSONLs from there. For `gemini`, the `jsonl_path` actually points to a gemini JSON file (since Gemini stores information in JSON rather than JSONL). DON'T use the LEGACY fetcher.
# How to search conversations for each provider
- Go to all the JSONL path directories from the database and use `@vscode/ripgrep` library for searching something.
# How to change thinking modes for each model
## Claude
- Passed through `query` options through `effort: <'low' | 'medium' | 'high' | 'max'>`
Default is high.
## Codex
- passed through `threadOptions`
```
type ModelReasoningEffort = "minimal" | "low" | "medium" | "high" | "xhigh";
type ThreadOptions = {
model?: string;
sandboxMode?: SandboxMode;
workingDirectory?: string;
skipGitRepoCheck?: boolean;
modelReasoningEffort?: ModelReasoningEffort;
networkAccessEnabled?: boolean;
webSearchMode?: WebSearchMode;
webSearchEnabled?: boolean;
approvalPolicy?: ApprovalMode;
additionalDirectories?: string[];
};
```
- `minimal` is supported only by `GPT-5`
## Gemini
- Not changeable. We can only select the different providers that have different thinking levels by themselves.
## Cursor
- Same as gemini.
# How to set/change models at start/after a session response respectively?
## Claude
- Initially can be set at start using `queryOptions.model`
- Just resume the session by updating the model in `threadoptions`
## Codex
- Same as claude
## Gemini
- Just add the `--model <model-name>` property in the new spawned command. If there is something to resume, add `--resume <sessionID>`
## Cursor
- Just add the `--model <model-name>` property in the new spawned command. If there is something to resume, add `--resume <sessionID>`. In other words, same as gemini.

View File

@@ -1,41 +0,0 @@
# LLM Unifier Backend Testing Report
Date: 2026-04-06
## Scope
This report validates the backend functionality checklist in `docs/backend/llm-unifier-helper.md`.
## Test Files Added
- `server/src/modules/llm/llm-unifier.providers.test.ts`
- `server/src/modules/llm/llm-unifier.sessions.test.ts`
Each test case includes an inline comment describing which helper requirement it covers.
## Command Used
```powershell
$env:TSX_TSCONFIG_PATH='server/tsconfig.json'; npm run test:server -- server/src/modules/llm/llm-unifier.providers.test.ts server/src/modules/llm/llm-unifier.sessions.test.ts
```
## Result
- Total tests: 32
- Passed: 32
- Failed: 0
## Requirement Coverage Matrix
| Helper requirement | Coverage |
| --- | --- |
| Session processing logic orchestration | `llmSessionsService.synchronizeSessions aggregates processed counts and failures`, `llmSessionsService.synchronizeProvider honors fullRescan option` |
| Start/resume behavior: Cursor | `cursor provider builds start/resume CLI invocations correctly` |
| Start/resume behavior: Gemini | `gemini provider builds start/resume CLI invocations and exposes curated models` |
| Start/resume/stop behavior: Codex (`startThread`, `resumeThread`, abort controller) | `codex provider start/resume use correct SDK thread methods and stop aborts signal` |
| Claude helper behavior (effort mapping, runtime permission handler, event normalization) | `claude provider helper mappings match unifier contract` |
| Model listing: Cursor (`--list-models` parsing) | `cursor provider parses model list output into normalized models` |
| Model listing: Gemini (curated options) | `gemini provider builds start/resume CLI invocations and exposes curated models` |
| Model listing: Codex (`~/.codex/models_cache.json`) | `codex provider reads models_cache.json and maps model metadata` |
| Runtime permission/thinking support constraints | `llmService rejects unsupported runtime permission and thinking mode combinations`, `providers enforce capability gates for model/thinking updates` |
| Thinking mode + model preference persistence across launches | `codex provider applies saved model/thinking preferences on subsequent launch` |
| Session history from DB `jsonl_path` (JSONL + Gemini JSON), no legacy fetcher path | `llmSessionsService.getSessionHistory parses JSONL and Gemini JSON correctly` |
| Session artifact deletion using processor path | `llmSessionsService.deleteSessionArtifacts validates ids and deletes disk/db artifacts` |
| Session rename/update path | `llmSessionsService.updateSessionCustomName validates existence before updating` |
| Conversation search over indexed transcript paths with provider/case filters | `conversationSearchService searches indexed transcripts with provider and case filters` |

View File

@@ -1,56 +0,0 @@
# LLM Unifier Helper-2 Backend Testing Report
Date: 2026-04-06
## Scope
This report validates every backend functionality listed in:
- `docs/backend/llm-unifier-helper-2.md`
All test cases include inline comments that describe which helper-2 requirement they cover.
## Test Files
- `server/src/modules/llm/llm-unifier.providers.test.ts`
- `server/src/modules/llm/llm-unifier.sessions.test.ts`
- `server/src/modules/llm/llm-unifier.images.test.ts`
- `server/src/modules/llm/llm-unifier.mcp.test.ts`
- `server/src/modules/llm/llm-unifier.skills.test.ts`
## package.json Scripts
- `test:server` now includes the full unifier suite.
- Added `test:server:llm-unifier-2` for running only helper-2 unifier coverage.
## Commands Used
```powershell
npm run typecheck:server
npm run test:server:llm-unifier-2
npm run test:server
```
## Results
- `typecheck:server`: pass
- `test:server:llm-unifier-2`: pass (`30/30`)
- `test:server`: pass (`30/30`)
## Requirement Coverage Matrix
| Helper-2 requirement | Test coverage |
| --- | --- |
| Universal image upload into `.cloudcli/assets` | `llmAssetsService stores uploaded images in .cloudcli/assets` |
| Image upload validation for supported image mime types | `llmAssetsService rejects unsupported image mime types` |
| Claude image prompt as content blocks with base64 images | `claude provider builds async prompt payload with base64 image blocks` |
| Codex image prompt via `local_image` entries | `codex provider sends local_image prompt items when image paths are provided` |
| Gemini/Cursor image handling by appending image path array to prompt | `gemini and cursor providers append image path arrays to prompts` |
| Start payload imagePaths validation | `llmService rejects invalid imagePaths payloads before provider execution` |
| MCP list grouped by User/Local/Project | `llmMcpService handles claude MCP scopes/transports with file-backed persistence` |
| MCP add/remove/update behavior backed by provider config files | `llmMcpService handles claude MCP scopes/transports with file-backed persistence`, `llmMcpService handles codex MCP TOML config and capability validation`, `llmMcpService handles gemini and cursor MCP JSON config formats` |
| Claude MCP transports: stdio/http/sse and scopes: user/local/project | `llmMcpService handles claude MCP scopes/transports with file-backed persistence` |
| Codex MCP transports: stdio/http and scopes: user/project | `llmMcpService handles codex MCP TOML config and capability validation` |
| Gemini MCP transports: stdio/http/sse and scopes: user/project | `llmMcpService handles gemini and cursor MCP JSON config formats` |
| Cursor MCP transports: stdio/http/sse and scopes: user/project | `llmMcpService handles gemini and cursor MCP JSON config formats` |
| Global MCP adder supports only `http` and `stdio` and applies to all providers | `llmMcpService global adder writes to all providers and rejects unsupported transports` |
| MCP run/connectivity checks (stdio and http) | `llmMcpService runProviderServer probes stdio and http MCP servers` |
| Claude skills fetch (user/project/plugin) and plugin namespacing | `llmSkillsService lists claude user/project/plugin skills with proper invocation names` |
| Codex skills fetch (repo/user/admin/system path model; tested repo/user/system paths) and `$` invocation | `llmSkillsService lists codex skills from repo/user/system locations with dollar invocation` |
| Gemini skills fetch from documented directories and `/` invocation | `llmSkillsService lists gemini skills from documented directories` |
| Cursor skills fetch from documented directories and `/` invocation | `llmSkillsService lists cursor skills from documented directories` |
| Existing unifier provider/session baseline behaviors remain passing | `llm-unifier.providers.test.ts`, `llm-unifier.sessions.test.ts` full suite |

View File

@@ -3,7 +3,9 @@ import tseslint from "typescript-eslint";
import react from "eslint-plugin-react";
import reactHooks from "eslint-plugin-react-hooks";
import reactRefresh from "eslint-plugin-react-refresh";
import importX from "eslint-plugin-import-x";
import { createNodeResolver, importX } from "eslint-plugin-import-x";
import { createTypeScriptImportResolver } from "eslint-import-resolver-typescript";
import boundaries from "eslint-plugin-boundaries";
import tailwindcss from "eslint-plugin-tailwindcss";
import unusedImports from "eslint-plugin-unused-imports";
import globals from "globals";
@@ -82,7 +84,7 @@ export default tseslint.config(
"sibling",
"index",
],
"newlines-between": "never",
"newlines-between": "always",
},
],
@@ -98,5 +100,131 @@ export default tseslint.config(
"no-control-regex": "off",
"no-useless-escape": "off",
},
},
{
files: ["server/**/*.{js,ts}"], // apply this block only to backend source files
ignores: ["server/**/*.d.ts"], // skip generated declaration files in backend linting
plugins: {
boundaries, // enforce backend architecture boundaries (module-to-module contracts)
"import-x": importX, // keep import hygiene rules (duplicates, unresolved paths, etc.)
"unused-imports": unusedImports, // remove dead imports/variables from backend files
},
languageOptions: {
parser: tseslint.parser, // parse both JS and TS syntax in backend files
parserOptions: {
ecmaVersion: "latest", // support modern ECMAScript syntax in backend code
sourceType: "module", // treat backend files as ESM modules
},
globals: {
...globals.node, // expose Node.js globals such as process, Buffer, and __dirname equivalents
},
},
settings: {
"boundaries/include": ["server/**/*.{js,ts}"], // only analyze dependency boundaries inside backend files
"import/resolver": {
// boundaries resolves imports through eslint-module-utils, which reads the classic
// import/resolver setting instead of import-x/resolver-next.
typescript: {
project: ["server/tsconfig.json"], // resolve backend aliases using the canonical backend tsconfig
alwaysTryTypes: true, // keep normal TS package/type resolution working alongside aliases
},
node: {
extensions: [".mjs", ".cjs", ".js", ".json", ".node", ".ts", ".tsx"], // preserve Node-style fallback resolution for plain files
},
},
"import-x/resolver-next": [
// ESLint's import plugin does not read tsconfig path aliases on its own.
// This resolver teaches import-x how to understand the backend-only "@/*"
// mapping defined in server/tsconfig.json, which fixes false no-unresolved errors in editors.
createTypeScriptImportResolver({
project: ["server/tsconfig.json"], // point the resolver at the canonical backend tsconfig instead of the frontend one
alwaysTryTypes: true, // keep standard TypeScript package resolution working while backend aliases are enabled
}),
// Keep Node-style resolution available for normal package imports and plain relative JS files.
// The TypeScript resolver handles aliases, while the Node resolver preserves the expected fallback behavior.
createNodeResolver({
extensions: [".mjs", ".cjs", ".js", ".json", ".node", ".ts", ".tsx"],
}),
],
"boundaries/elements": [
{
type: "backend-shared-types", // shared backend type contract that modules may consume without creating runtime coupling
pattern: ["server/shared/types.{js,ts}"], // support the current shared types path
mode: "file", // treat the types file itself as the boundary element instead of the whole folder
},
{
type: "backend-module", // logical element name used by boundaries rules below
pattern: "server/modules/*", // each direct folder in server/modules is treated as one module boundary
mode: "folder", // classify dependencies at folder-module level (not per individual file)
capture: ["moduleName"], // capture the module folder name for messages/debugging/template use
},
],
},
rules: {
// --- Unused imports/vars (backend) ---
"unused-imports/no-unused-imports": "warn", // warn when imports are not used so they can be cleaned up
"unused-imports/no-unused-vars": "off", // keep backend signal focused on dead imports instead of local unused variables
// --- Import hygiene (backend) ---
"import-x/no-duplicates": "warn", // prevent duplicate import lines from the same module
"import-x/order": [
"warn", // keep backend import grouping/order consistent with the frontend config
{
groups: [
"builtin", // Node built-ins such as fs, path, and url come first
"external", // third-party packages come after built-ins
"internal", // aliased internal imports such as @/... come next
"parent", // ../ imports come after aliased internal imports
"sibling", // ./foo imports come after parent imports
"index", // bare ./ imports stay last
],
"newlines-between": "always", // require a blank line between import groups in backend files too
},
],
"import-x/no-unresolved": "error", // fail when an import path cannot be resolved
"import-x/no-useless-path-segments": "warn", // prefer cleaner paths (remove redundant ./ and ../ segments)
"import-x/no-absolute-path": "error", // disallow absolute filesystem imports in backend files
// --- General safety/style (backend) ---
eqeqeq: ["warn", "always", { null: "ignore" }], // avoid accidental coercion while still allowing x == null checks
// --- Architecture boundaries (backend modules) ---
"boundaries/dependencies": [
"error", // treat architecture violations as lint errors
{
default: "allow", // allow normal imports unless a rule below explicitly disallows them
checkInternals: false, // do not apply these cross-module rules to imports inside the same module
rules: [
{
from: { type: "backend-module" }, // modules may depend on the shared types contract only as erased type-only imports
to: { type: "backend-shared-types" },
disallow: {
dependency: { kind: ["value", "typeof"] },
}, // block runtime imports so shared types stay a compile-time contract instead of a hidden shared module
message:
"Backend modules may only use `import type` when importing from server/shared/types.ts (or server/types.ts).",
},
{
to: { type: "backend-module" }, // when importing anything that belongs to another backend module
disallow: { to: { internalPath: "**" } }, // block all direct/deep imports into module internals by default
message:
"Cross-module imports must go through that module's barrel file (server/modules/<module>/index.ts or index.js).", // explicit error message for architecture violations
},
{
to: { type: "backend-module" }, // same target scope as the disallow rule above
allow: {
to: {
internalPath: [
"index", // allow extensionless barrel imports resolved as module root index
"index.{js,mjs,cjs,ts,tsx}", // allow explicit index.* barrel file imports
],
},
}, // re-allow only public module entry points (barrel files)
},
],
},
],
"boundaries/no-unknown": "error", // fail fast if boundaries cannot classify a dependency, which prevents silent rule bypasses
},
}
);

1598
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,17 +1,17 @@
{
"name": "@siteboon/claude-code-ui",
"version": "1.26.3",
"name": "@cloudcli-ai/cloudcli",
"version": "1.29.5",
"description": "A web-based UI for Claude Code CLI",
"type": "module",
"main": "server/start.js",
"main": "dist-server/server/index.js",
"bin": {
"claude-code-ui": "server/cli.js",
"cloudcli": "server/cli.js"
"cloudcli": "dist-server/server/cli.js"
},
"files": [
"server/",
"shared/",
"dist/",
"dist-server/",
"scripts/",
"README.md"
],
@@ -24,36 +24,46 @@
"url": "https://github.com/siteboon/claudecodeui/issues"
},
"scripts": {
"dev": "concurrently --kill-others \"npm run server\" \"npm run client\"",
"server:dev": "tsx watch --tsconfig server/tsconfig.json server/src/bootstrap.ts",
"server": "tsx --tsconfig server/tsconfig.json server/src/bootstrap.ts",
"server:build": "tsc -p server/tsconfig.json && tsc-alias -p server/tsconfig.json",
"server:start": "node server/start.js",
"dev": "concurrently --kill-others \"npm run server:dev\" \"npm run client\"",
"server": "node dist-server/server/index.js",
"server:dev": "tsx --tsconfig server/tsconfig.json server/index.js",
"server:dev-watch": "tsx watch --tsconfig server/tsconfig.json server/index.js",
"client": "vite",
"build": "vite build",
"build": "npm run build:client && npm run build:server",
"build:client": "vite build",
"prebuild:server": "node -e \"require('node:fs').rmSync('dist-server', { recursive: true, force: true })\"",
"build:server": "tsc -p server/tsconfig.json && tsc-alias -p server/tsconfig.json",
"preview": "vite preview",
"typecheck:client": "tsc --noEmit -p tsconfig.json",
"typecheck:server": "tsc --noEmit -p server/tsconfig.json",
"test:server": "tsx --tsconfig server/tsconfig.json --test server/src/modules/ai-runtime/tests/*.test.ts",
"verify:server": "npm run typecheck:server && npm run test:server && npm run server:build",
"typecheck": "npm run typecheck:client && npm run typecheck:server",
"lint": "eslint src/",
"lint:fix": "eslint src/ --fix",
"start": "npm run build && npm run server:build && npm run server:start",
"typecheck": "tsc --noEmit -p tsconfig.json && tsc --noEmit -p server/tsconfig.json",
"lint": "eslint src/ server/",
"lint:fix": "eslint src/ server/ --fix",
"start": "npm run build && npm run server",
"release": "./release.sh",
"prepublishOnly": "npm run build && npm run server:build",
"prepublishOnly": "npm run build",
"postinstall": "node scripts/fix-node-pty.js",
"prepare": "husky"
"prepare": "husky",
"update:platform": "./update-platform.sh"
},
"keywords": [
"claude code",
"ai",
"claude-code",
"claude-code-ui",
"cloudcli",
"codex",
"gemini",
"gemini-cli",
"cursor",
"cursor-cli",
"anthropic",
"openai",
"google",
"coding-agent",
"web-ui",
"ui",
"mobile"
"mobile IDE"
],
"author": "CloudCLI UI Contributors",
"license": "GPL-3.0",
"license": "AGPL-3.0-or-later",
"dependencies": {
"@anthropic-ai/claude-agent-sdk": "^0.2.59",
"@codemirror/lang-css": "^6.3.1",
@@ -69,7 +79,6 @@
"@openai/codex-sdk": "^0.101.0",
"@replit/codemirror-minimap": "^0.5.2",
"@tailwindcss/typography": "^0.5.16",
"@types/multer": "^2.1.0",
"@uiw/react-codemirror": "^4.23.13",
"@xterm/addon-clipboard": "^0.1.0",
"@xterm/addon-fit": "^0.10.0",
@@ -95,7 +104,7 @@
"mime-types": "^3.0.1",
"multer": "^2.0.1",
"node-fetch": "^2.7.0",
"node-pty": "^1.1.0-beta34",
"node-pty": "^1.2.0-beta.12",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-dropzone": "^14.2.3",
@@ -108,33 +117,25 @@
"rehype-raw": "^7.0.0",
"remark-gfm": "^4.0.0",
"remark-math": "^6.0.0",
"sqlite": "^5.1.1",
"sqlite3": "^5.1.7",
"tailwind-merge": "^3.3.1",
"web-push": "^3.6.7",
"ws": "^8.14.2"
},
"devDependencies": {
"@commitlint/cli": "^20.4.3",
"@commitlint/config-conventional": "^20.4.3",
"@commitlint/cli": "^20.5.0",
"@commitlint/config-conventional": "^20.5.0",
"@eslint/js": "^9.39.3",
"@release-it/conventional-changelog": "^10.0.5",
"@types/bcrypt": "^6.0.0",
"@types/better-sqlite3": "^7.6.13",
"@types/cors": "^2.8.19",
"@types/cross-spawn": "^6.0.6",
"@types/express": "^5.0.3",
"@types/jsonwebtoken": "^9.0.10",
"@types/node": "^22.19.7",
"@types/react": "^18.2.43",
"@types/react-dom": "^18.2.17",
"@types/web-push": "^3.6.4",
"@types/ws": "^8.18.1",
"@vitejs/plugin-react": "^4.6.0",
"auto-changelog": "^2.5.0",
"autoprefixer": "^10.4.16",
"concurrently": "^8.2.2",
"eslint": "^9.39.3",
"eslint-import-resolver-typescript": "^4.4.4",
"eslint-plugin-boundaries": "^6.0.2",
"eslint-plugin-import-x": "^4.16.1",
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^7.0.1",
@@ -150,12 +151,13 @@
"sharp": "^0.34.2",
"tailwindcss": "^3.4.0",
"tsc-alias": "^1.8.16",
"tsx": "^4.20.6",
"tsx": "^4.21.0",
"typescript": "^5.9.3",
"typescript-eslint": "^8.56.1",
"vite": "^7.0.4"
},
"lint-staged": {
"src/**/*.{ts,tsx,js,jsx}": "eslint"
"src/**/*.{ts,tsx,js,jsx}": "eslint",
"server/**/*.{js,ts}": "eslint"
}
}

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Claude Code UI - API Documentation</title>
<title>CloudCLI - API Documentation</title>
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="icon" type="image/png" href="/favicon.png" />
@@ -418,7 +418,7 @@
</svg>
</div>
<div class="brand-text">
<h1>Claude Code UI</h1>
<h1>CloudCLI</h1>
<div class="subtitle">API Documentation</div>
</div>
</div>

View File

@@ -1,4 +1,4 @@
// Service Worker for Claude Code UI PWA
// Service Worker for CloudCLI PWA
// Cache only manifest (needed for PWA install). HTML and JS are never pre-cached
// so a rebuild + refresh always picks up the latest assets.
const CACHE_NAME = 'claude-ui-v2';
@@ -79,7 +79,7 @@ self.addEventListener('push', event => {
try {
payload = event.data.json();
} catch {
payload = { title: 'Claude Code UI', body: event.data.text() };
payload = { title: 'CloudCLI', body: event.data.text() };
}
const options = {
@@ -92,7 +92,7 @@ self.addEventListener('push', event => {
};
event.waitUntil(
self.registration.showNotification(payload.title || 'Claude Code UI', options)
self.registration.showNotification(payload.title || 'CloudCLI', options)
);
});

248
redirect-package/README.md Normal file
View File

@@ -0,0 +1,248 @@
<div align="center">
> ## This package has moved to [`@cloudcli-ai/cloudcli`](https://www.npmjs.com/package/@cloudcli-ai/cloudcli)
>
> ```bash
> npm install -g @cloudcli-ai/cloudcli
> ```
>
> This package (`@siteboon/claude-code-ui`) is now a thin wrapper that installs the new package automatically.
> For new installations, use `@cloudcli-ai/cloudcli` directly.
</div>
---
<div align="center">
<img src="https://raw.githubusercontent.com/siteboon/claudecodeui/main/public/logo.svg" alt="CloudCLI UI" width="64" height="64">
<h1>Cloud CLI (aka Claude Code UI)</h1>
<p>A desktop and mobile UI for <a href="https://docs.anthropic.com/en/docs/claude-code">Claude Code</a>, <a href="https://docs.cursor.com/en/cli/overview">Cursor CLI</a>, <a href="https://developers.openai.com/codex">Codex</a>, and <a href="https://geminicli.com/">Gemini-CLI</a>.<br>Use it locally or remotely to view your active projects and sessions from everywhere.</p>
</div>
<p align="center">
<a href="https://cloudcli.ai">CloudCLI Cloud</a> · <a href="https://cloudcli.ai/docs">Documentation</a> · <a href="https://discord.gg/buxwujPNRE">Discord</a> · <a href="https://github.com/siteboon/claudecodeui/issues">Bug Reports</a> · <a href="https://github.com/siteboon/claudecodeui/blob/main/CONTRIBUTING.md">Contributing</a>
</p>
<p align="center">
<a href="https://cloudcli.ai"><img src="https://img.shields.io/badge/☁_CloudCLI_Cloud-Try_Now-0066FF?style=for-the-badge" alt="CloudCLI Cloud"></a>
<a href="https://discord.gg/buxwujPNRE"><img src="https://img.shields.io/badge/Discord-Join%20Community-5865F2?style=for-the-badge&logo=discord&logoColor=white" alt="Join our Discord"></a>
<br><br>
<a href="https://trendshift.io/repositories/15586" target="_blank"><img src="https://trendshift.io/api/badge/repositories/15586" alt="siteboon%2Fclaudecodeui | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
</p>
---
## Screenshots
<div align="center">
<table>
<tr>
<td align="center">
<h3>Desktop View</h3>
<img src="https://raw.githubusercontent.com/siteboon/claudecodeui/main/public/screenshots/desktop-main.png" alt="Desktop Interface" width="400">
<br>
<em>Main interface showing project overview and chat</em>
</td>
<td align="center">
<h3>Mobile Experience</h3>
<img src="https://raw.githubusercontent.com/siteboon/claudecodeui/main/public/screenshots/mobile-chat.png" alt="Mobile Interface" width="250">
<br>
<em>Responsive mobile design with touch navigation</em>
</td>
</tr>
<tr>
<td align="center" colspan="2">
<h3>CLI Selection</h3>
<img src="https://raw.githubusercontent.com/siteboon/claudecodeui/main/public/screenshots/cli-selection.png" alt="CLI Selection" width="400">
<br>
<em>Select between Claude Code, Gemini, Cursor CLI and Codex</em>
</td>
</tr>
</table>
</div>
## Features
- **Responsive Design** - Works seamlessly across desktop, tablet, and mobile so you can also use Agents from mobile
- **Interactive Chat Interface** - Built-in chat interface for seamless communication with the Agents
- **Integrated Shell Terminal** - Direct access to the Agents CLI through built-in shell functionality
- **File Explorer** - Interactive file tree with syntax highlighting and live editing
- **Git Explorer** - View, stage and commit your changes. You can also switch branches
- **Session Management** - Resume conversations, manage multiple sessions, and track history
- **Plugin System** - Extend CloudCLI with custom plugins — add new tabs, backend services, and integrations. [Build your own →](https://github.com/cloudcli-ai/cloudcli-plugin-starter)
- **TaskMaster AI Integration** *(Optional)* - Advanced project management with AI-powered task planning, PRD parsing, and workflow automation
- **Model Compatibility** - Works with Claude, GPT, and Gemini model families (see [`shared/modelConstants.js`](https://github.com/siteboon/claudecodeui/blob/main/shared/modelConstants.js) for the full list of supported models)
## Quick Start
### CloudCLI Cloud (Recommended)
The fastest way to get started — no local setup required. Get a fully managed, containerized development environment accessible from the web, mobile app, API, or your favorite IDE.
**[Get started with CloudCLI Cloud](https://cloudcli.ai)**
### Self-Hosted (Open source)
Try CloudCLI UI instantly with **npx** (requires **Node.js** v22+):
```
npx @cloudcli-ai/cloudcli
```
Or install **globally** for regular use:
```
npm install -g @cloudcli-ai/cloudcli
cloudcli
```
Open `http://localhost:3001` — all your existing sessions are discovered automatically.
Visit the **[documentation →](https://cloudcli.ai/docs)** for more full configuration options, PM2, remote server setup and more
---
## Which option is right for you?
CloudCLI UI is the open source UI layer that powers CloudCLI Cloud. You can self-host it on your own machine, or use CloudCLI Cloud which builds on top of it with a full managed cloud environment, team features, and deeper integrations.
| | CloudCLI UI (Self-hosted) | CloudCLI Cloud |
|---|---|---|
| **Best for** | Developers who want a full UI for local agent sessions on their own machine | Teams and developers who want agents running in the cloud, accessible from anywhere |
| **How you access it** | Browser via `[yourip]:port` | Browser, any IDE, REST API, n8n |
| **Setup** | `npx @cloudcli-ai/cloudcli` | No setup required |
| **Machine needs to stay on** | Yes | No |
| **Mobile access** | Any browser on your network | Any device, native app coming |
| **Sessions available** | All sessions auto-discovered from `~/.claude` | All sessions within your cloud environment |
| **Agents supported** | Claude Code, Cursor CLI, Codex, Gemini CLI | Claude Code, Cursor CLI, Codex, Gemini CLI |
| **File explorer and Git** | Yes, built into the UI | Yes, built into the UI |
| **MCP configuration** | Managed via UI, synced with your local `~/.claude` config | Managed via UI |
| **IDE access** | Your local IDE | Any IDE connected to your cloud environment |
| **REST API** | Yes | Yes |
| **n8n node** | No | Yes |
| **Team sharing** | No | Yes |
| **Platform cost** | Free, open source | Starts at $7/month |
> Both options use your own AI subscriptions (Claude, Cursor, etc.) — CloudCLI provides the environment, not the AI.
---
## Security & Tools Configuration
**Important Notice**: All Claude Code tools are **disabled by default**. This prevents potentially harmful operations from running automatically.
### Enabling Tools
To use Claude Code's full functionality, you'll need to manually enable tools:
1. **Open Tools Settings** - Click the gear icon in the sidebar
2. **Enable Selectively** - Turn on only the tools you need
3. **Apply Settings** - Your preferences are saved locally
**Recommended approach**: Start with basic tools enabled and add more as needed. You can always adjust these settings later.
---
## Plugins
CloudCLI has a plugin system that lets you add custom tabs with their own frontend UI and optional Node.js backend. Install plugins from git repos directly in **Settings > Plugins**, or build your own.
### Available Plugins
| Plugin | Description |
|---|---|
| **[Project Stats](https://github.com/cloudcli-ai/cloudcli-plugin-starter)** | Shows file counts, lines of code, file-type breakdown, largest files, and recently modified files for your current project |
| **[Web Terminal](https://github.com/cloudcli-ai/cloudcli-plugin-terminal)** | Full xterm.js terminal with multi-tab support|
### Build Your Own
**[Plugin Starter Template →](https://github.com/cloudcli-ai/cloudcli-plugin-starter)** — fork this repo to create your own plugin. It includes a working example with frontend rendering, live context updates, and RPC communication to a backend server.
**[Plugin Documentation →](https://cloudcli.ai/docs/plugin-overview)** — full guide to the plugin API, manifest format, security model, and more.
---
## FAQ
<details>
<summary>How is this different from Claude Code Remote Control?</summary>
Claude Code Remote Control lets you send messages to a session already running in your local terminal. Your machine has to stay on, your terminal has to stay open, and sessions time out after roughly 10 minutes without a network connection.
CloudCLI UI and CloudCLI Cloud extend Claude Code rather than sit alongside it — your MCP servers, permissions, settings, and sessions are the exact same ones Claude Code uses natively. Nothing is duplicated or managed separately.
Here's what that means in practice:
- **All your sessions, not just one** — CloudCLI UI auto-discovers every session from your `~/.claude` folder. Remote Control only exposes the single active session to make it available in the Claude mobile app.
- **Your settings are your settings** — MCP servers, tool permissions, and project config you change in CloudCLI UI are written directly to your Claude Code config and take effect immediately, and vice versa.
- **Works with more agents** — Claude Code, Cursor CLI, Codex, and Gemini CLI, not just Claude Code.
- **Full UI, not just a chat window** — file explorer, Git integration, MCP management, and a shell terminal are all built in.
- **CloudCLI Cloud runs in the cloud** — close your laptop, the agent keeps running. No terminal to babysit, no machine to keep awake.
</details>
<details>
<summary>Do I need to pay for an AI subscription separately?</summary>
Yes. CloudCLI provides the environment, not the AI. You bring your own Claude, Cursor, Codex, or Gemini subscription. CloudCLI Cloud starts at $7/month for the hosted environment on top of that.
</details>
<details>
<summary>Can I use CloudCLI UI on my phone?</summary>
Yes. For self-hosted, run the server on your machine and open `[yourip]:port` in any browser on your network. For CloudCLI Cloud, open it from any device — no VPN, no port forwarding, no setup. A native app is also in the works.
</details>
<details>
<summary>Will changes I make in the UI affect my local Claude Code setup?</summary>
Yes, for self-hosted. CloudCLI UI reads from and writes to the same `~/.claude` config that Claude Code uses natively. MCP servers you add via the UI show up in Claude Code immediately and vice versa.
</details>
---
## Community & Support
- **[Documentation](https://cloudcli.ai/docs)** — installation, configuration, features, and troubleshooting
- **[Discord](https://discord.gg/buxwujPNRE)** — get help and connect with other users
- **[GitHub Issues](https://github.com/siteboon/claudecodeui/issues)** — bug reports and feature requests
- **[Contributing Guide](https://github.com/siteboon/claudecodeui/blob/main/CONTRIBUTING.md)** — how to contribute to the project
## License
GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later) — see [LICENSE](https://github.com/siteboon/claudecodeui/blob/main/LICENSE) for the full text, including additional terms under Section 7.
This project is open source and free to use, modify, and distribute under the AGPL-3.0-or-later license. If you modify this software and run it as a network service, you must make your modified source code available to users of that service.
CloudCLI UI - (https://cloudcli.ai).
## Acknowledgments
### Built With
- **[Claude Code](https://docs.anthropic.com/en/docs/claude-code)** - Anthropic's official CLI
- **[Cursor CLI](https://docs.cursor.com/en/cli/overview)** - Cursor's official CLI
- **[Codex](https://developers.openai.com/codex)** - OpenAI Codex
- **[Gemini-CLI](https://geminicli.com/)** - Google Gemini CLI
- **[React](https://react.dev/)** - User interface library
- **[Vite](https://vitejs.dev/)** - Fast build tool and dev server
- **[Tailwind CSS](https://tailwindcss.com/)** - Utility-first CSS framework
- **[CodeMirror](https://codemirror.net/)** - Advanced code editor
- **[TaskMaster AI](https://github.com/eyaltoledano/claude-task-master)** *(Optional)* - AI-powered project management and task planning
### Sponsors
- [Siteboon - AI powered website builder](https://siteboon.ai)
---
<div align="center">
<strong>Made with care for the Claude Code, Cursor and Codex community.</strong>
</div>

2
redirect-package/bin.js Normal file
View File

@@ -0,0 +1,2 @@
#!/usr/bin/env node
import('@cloudcli-ai/cloudcli/dist-server/server/cli.js');

View File

@@ -0,0 +1,2 @@
export * from '@cloudcli-ai/cloudcli';
export { default } from '@cloudcli-ai/cloudcli';

View File

@@ -0,0 +1,43 @@
{
"name": "@siteboon/claude-code-ui",
"version": "2.0.0",
"description": "This package has moved to @cloudcli-ai/cloudcli",
"type": "module",
"main": "index.js",
"bin": {
"claude-code-ui": "./bin.js",
"cloudcli": "./bin.js"
},
"homepage": "https://cloudcli.ai",
"repository": {
"type": "git",
"url": "git+https://github.com/siteboon/claudecodeui.git"
},
"bugs": {
"url": "https://github.com/siteboon/claudecodeui/issues"
},
"keywords": [
"claude code",
"claude-code",
"claude-code-ui",
"cloudcli",
"codex",
"gemini",
"gemini-cli",
"cursor",
"cursor-cli",
"anthropic",
"openai",
"google",
"coding-agent",
"web-ui",
"ui",
"mobile IDE"
],
"author": "CloudCLI UI Contributors",
"dependencies": {
"@cloudcli-ai/cloudcli": "*"
},
"deprecated": "This package has been renamed to @cloudcli-ai/cloudcli. Please install @cloudcli-ai/cloudcli instead.",
"license": "AGPL-3.0-or-later"
}

View File

@@ -1,657 +0,0 @@
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const projectRoot = path.resolve(__dirname, '..');
const serverRoot = path.join(projectRoot, 'server');
const clientRoot = path.join(projectRoot, 'src');
const docsRoot = path.join(projectRoot, 'docs', 'backend');
const HTTP_METHODS = ['get', 'post', 'put', 'delete', 'patch'];
const routeDefinitionPattern = /\b(app|router)\.(get|post|put|delete|patch)\(\s*(['"`])(.+?)\3/g;
const defaultImportPattern =
/^import\s+([A-Za-z0-9_$]+)(?:\s*,\s*\{[^}]+\})?\s+from\s+['"](.+?)['"];$/gm;
const incomingRealtimePattern = /data\.type === '([^']+)'/g;
const outgoingRealtimePattern = /type:\s*'([^']+)'/g;
fs.mkdirSync(docsRoot, { recursive: true });
function toPosix(value) {
return value.split(path.sep).join('/');
}
function readText(filePath) {
return fs.readFileSync(filePath, 'utf8');
}
function walkFiles(dirPath, files = []) {
for (const entry of fs.readdirSync(dirPath, { withFileTypes: true })) {
if (entry.name === 'dist' || entry.name === 'node_modules') {
continue;
}
const fullPath = path.join(dirPath, entry.name);
if (entry.isDirectory()) {
walkFiles(fullPath, files);
continue;
}
files.push(fullPath);
}
return files;
}
function getLineNumber(content, index) {
return content.slice(0, index).split(/\r?\n/).length;
}
function splitArgs(argumentSource) {
return argumentSource
.split(',')
.map(part => part.trim())
.filter(Boolean);
}
function sanitizeObjectKey(key) {
return key
.replace(/^[\s{]+|[\s}]+$/g, '')
.replace(/=.*$/, '')
.replace(/:.+$/, '')
.replace(/\?/g, '')
.trim();
}
function collectObjectKeys(block, accessor) {
const keys = new Set();
const directPattern = new RegExp(`req\\.${accessor}\\.([A-Za-z0-9_]+)`, 'g');
const destructuringPattern = new RegExp(`\\{([^}]*)\\}\\s*=\\s*req\\.${accessor}`, 'gs');
for (const match of block.matchAll(directPattern)) {
keys.add(match[1]);
}
for (const match of block.matchAll(destructuringPattern)) {
for (const rawKey of match[1].split(',')) {
const key = sanitizeObjectKey(rawKey);
if (key) {
keys.add(key);
}
}
}
return [...keys].sort();
}
function normalizeJoinedPath(basePath, routePath) {
const safeBase = basePath.endsWith('/') ? basePath.slice(0, -1) : basePath;
if (!routePath || routePath === '/') {
return safeBase || '/';
}
if (routePath === '*') {
return routePath;
}
const safeRoute = routePath.startsWith('/') ? routePath : `/${routePath}`;
return `${safeBase}${safeRoute}` || '/';
}
function getStaticSearchTokens(routePath) {
const cleaned = routePath.replace(/:[A-Za-z0-9_]+/g, '').replace(/\*/g, '');
const segments = cleaned.split('/').filter(Boolean);
const tokens = new Set();
if (cleaned && cleaned !== '/') {
tokens.add(cleaned.endsWith('/') ? cleaned : `${cleaned}`);
}
for (let index = segments.length; index >= 2; index -= 1) {
tokens.add(`/${segments.slice(0, index).join('/')}/`);
}
if (segments.length > 0) {
tokens.add(`/${segments.slice(0, 1).join('/')}/`);
}
return [...tokens].filter(Boolean);
}
function classifyTag(routePath) {
if (routePath === '*' || routePath === '/health' || routePath.startsWith('/api/system')) {
return 'System';
}
if (routePath.startsWith('/api/auth')) return 'Auth';
if (routePath.startsWith('/api/user')) return 'User';
if (routePath.startsWith('/api/settings')) return 'Settings';
if (routePath.startsWith('/api/git')) return 'Git';
if (routePath.startsWith('/api/taskmaster')) return 'TaskMaster';
if (routePath.startsWith('/api/plugins')) return 'Plugins';
if (routePath.startsWith('/api/agent')) return 'Agent';
if (routePath.startsWith('/api/commands')) return 'Commands';
if (routePath.startsWith('/api/mcp')) return 'MCP';
if (routePath.startsWith('/api/cli')) return 'CLI Auth';
if (
routePath.startsWith('/api/cursor') ||
routePath.startsWith('/api/codex') ||
routePath.startsWith('/api/gemini')
) {
return 'Providers';
}
if (routePath.startsWith('/api/search') || routePath.includes('/sessions')) {
return 'Sessions';
}
if (routePath.includes('/files') || routePath.includes('/file') || routePath.includes('/upload')) {
return 'Files';
}
if (routePath.startsWith('/api/projects') || routePath.startsWith('/api/create-folder')) {
return 'Projects';
}
return 'Realtime';
}
function classifyPriority(tag, routePath) {
if (
tag === 'Agent' ||
tag === 'TaskMaster' ||
tag === 'Git' ||
routePath.startsWith('/api/projects') ||
routePath.startsWith('/api/search')
) {
return 'high';
}
if (
tag === 'Providers' ||
tag === 'Commands' ||
tag === 'MCP' ||
tag === 'Plugins' ||
tag === 'Settings' ||
tag === 'Auth' ||
tag === 'User'
) {
return 'medium';
}
return 'low';
}
function describePurpose(method, routePath) {
const verb = method.toUpperCase();
if (routePath === '/health') {
return 'Expose server health, timestamp, and install mode for diagnostics.';
}
if (routePath === '*') {
return 'Serve the React application fallback for non-API routes.';
}
if (routePath.startsWith('/api/system/update')) {
return 'Run the application update workflow on the host machine.';
}
if (routePath.startsWith('/api/auth/status')) return 'Report whether authentication is configured.';
if (routePath.startsWith('/api/auth/register')) return 'Create the first local user account.';
if (routePath.startsWith('/api/auth/login')) return 'Authenticate a local user and issue a token.';
if (routePath.startsWith('/api/auth/user')) return 'Return the currently authenticated user.';
if (routePath.startsWith('/api/auth/logout')) return 'Invalidate the current authenticated session.';
if (routePath.startsWith('/api/user/git-config')) return 'Read or update stored git identity settings.';
if (routePath.startsWith('/api/user/complete-onboarding')) return 'Mark onboarding as completed for the current user.';
if (routePath.startsWith('/api/user/onboarding-status')) return 'Return onboarding completion status for the current user.';
if (routePath.startsWith('/api/settings/api-keys')) return 'Manage local API keys used to access the backend.';
if (routePath.startsWith('/api/settings/credentials')) return 'Manage stored provider and GitHub credentials.';
if (routePath.startsWith('/api/projects/create-workspace')) {
return 'Create or register a workspace and optionally clone a GitHub repository into it.';
}
if (routePath.startsWith('/api/projects/clone-progress')) {
return 'Stream workspace cloning progress events to the frontend.';
}
if (routePath === '/api/projects') return 'List detected projects and workspaces.';
if (routePath.startsWith('/api/projects/create')) return 'Manually add a project path to the workspace list.';
if (routePath.startsWith('/api/projects/:projectName/sessions/:sessionId/token-usage')) {
return 'Report token usage for a stored provider session.';
}
if (routePath.includes('/sessions/:sessionId/messages')) {
return 'Return paginated messages for a stored session.';
}
if (routePath.includes('/sessions')) {
return 'List or manage sessions associated with a project or provider.';
}
if (routePath.includes('/files') || routePath.includes('/file')) {
return 'Read, write, create, rename, delete, or upload project files.';
}
if (routePath.startsWith('/api/search/conversations')) {
return 'Search conversation history across stored projects and stream results.';
}
if (routePath.startsWith('/api/browse-filesystem')) {
return 'Browse local directories so the UI can suggest workspace locations.';
}
if (routePath.startsWith('/api/create-folder')) {
return 'Create a new directory on the local filesystem.';
}
if (routePath.startsWith('/api/transcribe')) {
return 'Transcribe uploaded audio and optionally enhance the result for prompts or tasks.';
}
if (routePath.includes('/upload-images')) {
return 'Upload images for chat use and return browser-safe data URLs.';
}
if (routePath.startsWith('/api/git/status')) return 'Read git status information for a project.';
if (routePath.startsWith('/api/git/diff')) return 'Return git diff output for a project or file.';
if (routePath.startsWith('/api/git/file-with-diff')) return 'Return file content together with diff context.';
if (routePath.startsWith('/api/git/branches')) return 'List git branches for a project.';
if (routePath.startsWith('/api/git/commits')) return 'List recent commits for a project.';
if (routePath.startsWith('/api/git/commit-diff')) return 'Return diff details for a specific commit.';
if (routePath.startsWith('/api/git/remote-status')) return 'Report remote sync status for a project repository.';
if (routePath.startsWith('/api/git/generate-commit-message')) return 'Generate an AI-assisted commit message from the current diff.';
if (routePath.startsWith('/api/taskmaster')) {
return 'Manage TaskMaster detection, PRDs, tasks, templates, and automation for a project.';
}
if (routePath.startsWith('/api/commands')) {
return 'List, load, or execute slash commands available to the chat experience.';
}
if (routePath.startsWith('/api/mcp-utils')) {
return 'Return MCP helper information used by setup flows.';
}
if (routePath.startsWith('/api/mcp')) {
return 'Manage Claude MCP CLI and configuration state.';
}
if (routePath.startsWith('/api/cursor')) {
return 'Manage Cursor configuration, MCP settings, and stored sessions.';
}
if (routePath.startsWith('/api/codex')) {
return 'Manage Codex configuration, MCP settings, and stored sessions.';
}
if (routePath.startsWith('/api/gemini')) {
return 'Manage Gemini session history for the UI.';
}
if (routePath.startsWith('/api/cli')) {
return 'Report local authentication status for provider CLIs.';
}
if (routePath.startsWith('/api/plugins')) {
return 'List, install, update, serve, enable, or remove plugins.';
}
if (routePath.startsWith('/api/agent')) {
return 'Accept external agent jobs that run a provider against a local or cloned project.';
}
return `${verb} ${routePath} for backend runtime support.`;
}
function describeSuccessShape(block, transport) {
if (transport === 'sse' || block.includes('text/event-stream')) {
return 'Server-sent events stream with progress/result/error events.';
}
if (block.includes('res.sendFile')) {
return 'Static file or HTML response.';
}
if (block.includes('res.redirect')) {
return 'HTTP redirect response.';
}
if (block.includes('res.json({ success: true')) {
return 'JSON object with an explicit success flag and payload.';
}
if (block.includes('res.json({')) {
return 'Structured JSON object response.';
}
if (block.includes('res.json(')) {
return 'JSON payload returned directly from service logic.';
}
return 'Mixed response shape; inspect handler during refactor.';
}
function describeErrorShape(block, transport) {
if (transport === 'sse' || block.includes('text/event-stream')) {
return 'Streamed error event or JSON error fallback.';
}
if (block.includes("res.status(500).json({ error:")) {
return 'JSON object with error message and optional details.';
}
if (block.includes("res.status(400).json({ error:")) {
return 'JSON validation error response.';
}
if (block.includes('res.status(')) {
return 'JSON error response with HTTP status code.';
}
return 'Handler-specific error behavior.';
}
function describeSideEffects(method, routePath) {
const effects = [];
if (method !== 'get') {
effects.push('Mutates backend or external state.');
}
if (routePath.includes('/git')) effects.push('Touches git repositories or local git config.');
if (routePath.includes('/projects') || routePath.includes('/file') || routePath.includes('/files')) {
effects.push('Touches local workspace files or directories.');
}
if (routePath.includes('/agent')) effects.push('Invokes external AI providers and may modify project files.');
if (routePath.includes('/taskmaster')) effects.push('Reads or writes TaskMaster project assets.');
if (routePath.includes('/plugins')) effects.push('Installs, updates, or serves plugin assets/processes.');
if (routePath.includes('/settings') || routePath.includes('/auth') || routePath.includes('/credentials')) {
effects.push('Reads or writes local authentication or credential state.');
}
if (routePath.includes('/mcp')) effects.push('Reads or writes MCP CLI configuration.');
if (routePath.includes('/transcribe')) effects.push('Processes uploaded files and external model responses.');
return effects.length > 0 ? effects : ['Read-only backend query.'];
}
function collectFrontendConsumers(routePath, clientFiles) {
const tokens = getStaticSearchTokens(routePath);
const consumers = new Set();
for (const file of clientFiles) {
const content = readText(file);
if (tokens.some(token => token && content.includes(token))) {
consumers.add(toPosix(path.relative(projectRoot, file)));
}
}
return [...consumers].sort();
}
function detectTransport(block) {
if (block.includes('text/event-stream')) {
return 'sse';
}
return 'http';
}
function parseMounts(runtimeContent) {
const routeImports = new Map();
for (const match of runtimeContent.matchAll(defaultImportPattern)) {
if (match[2].includes('/routes/')) {
routeImports.set(match[1], match[2]);
}
}
const mounts = new Map();
const mountPattern = /app\.use\(\s*(['"`])([^'"`]+)\1\s*,\s*([^)]+?)\);/g;
for (const match of runtimeContent.matchAll(mountPattern)) {
const basePath = match[2];
const args = splitArgs(match[3]);
const routeVariable = args.at(-1);
if (!routeVariable || !routeImports.has(routeVariable)) {
continue;
}
mounts.set(routeVariable, {
basePath,
routeImport: routeImports.get(routeVariable),
authMode: args.includes('authenticateToken')
? 'bearer_token'
: args.includes('validateExternalApiKey')
? 'api_key_or_platform'
: 'public_or_optional_api_key',
});
}
return mounts;
}
function parseRoutes(filePath, fullPathPrefix, authMode, clientFiles) {
const content = readText(filePath);
const matches = [...content.matchAll(routeDefinitionPattern)];
const routes = [];
for (let index = 0; index < matches.length; index += 1) {
const match = matches[index];
const nextMatch = matches[index + 1];
const routeMethod = match[2].toUpperCase();
const routePath = match[4];
const startIndex = match.index ?? 0;
const endIndex = nextMatch?.index ?? content.length;
const block = content.slice(startIndex, endIndex);
const declarationEnd = block.indexOf('=>');
const declarationSnippet = declarationEnd === -1 ? block : block.slice(0, declarationEnd);
const fullPath = fullPathPrefix
? normalizeJoinedPath(fullPathPrefix, routePath)
: routePath;
const transport = detectTransport(block);
const tag = classifyTag(fullPath);
const pathParams = [...fullPath.matchAll(/:([A-Za-z0-9_]+)/g)].map(token => token[1]);
const queryParams = collectObjectKeys(block, 'query');
const bodyHints = collectObjectKeys(block, 'body');
const localAuthMode =
fullPath === '/health' ||
fullPath === '/api/auth/status' ||
fullPath === '/api/auth/register' ||
fullPath === '/api/auth/login' ||
fullPath === '*'
? 'public'
: declarationSnippet.includes('authenticateToken')
? 'bearer_token'
: declarationSnippet.includes('validateExternalApiKey')
? 'api_key_or_platform'
: authMode;
routes.push({
transport,
method: routeMethod,
path: fullPath,
tag,
authMode: localAuthMode,
sourceFile: toPosix(path.relative(projectRoot, filePath)),
sourceLine: getLineNumber(content, startIndex),
purpose: describePurpose(routeMethod, fullPath),
consumerFiles: collectFrontendConsumers(fullPath, clientFiles),
inputs: {
pathParams,
queryParams,
bodyHints,
},
successShape: describeSuccessShape(block, transport),
errorShape: describeErrorShape(block, transport),
sideEffects: describeSideEffects(routeMethod.toLowerCase(), fullPath),
priority: classifyPriority(tag, fullPath),
});
}
return routes;
}
function parseRealtimeContracts(runtimeFile) {
const content = readText(runtimeFile);
const incoming = new Set();
const outgoing = new Set();
for (const match of content.matchAll(incomingRealtimePattern)) {
incoming.add(match[1]);
}
const websocketSectionIndex = content.indexOf("wss.on('connection'");
const websocketSection = websocketSectionIndex === -1 ? content : content.slice(websocketSectionIndex);
for (const match of websocketSection.matchAll(outgoingRealtimePattern)) {
outgoing.add(match[1]);
}
return {
incomingMessageTypes: [...incoming].sort(),
outgoingMessageTypes: [...outgoing].sort(),
};
}
function escapeCsv(value) {
const stringValue = Array.isArray(value) ? value.join('; ') : String(value ?? '');
const escaped = stringValue.replace(/"/g, '""');
return `"${escaped}"`;
}
function writeCsv(filePath, records) {
const header = [
'transport',
'method',
'path',
'tag',
'authMode',
'sourceFile',
'sourceLine',
'purpose',
'consumerFiles',
'pathParams',
'queryParams',
'bodyHints',
'successShape',
'errorShape',
'sideEffects',
'priority',
];
const rows = [
header.join(','),
...records.map(record => [
record.transport,
record.method,
record.path,
record.tag,
record.authMode,
record.sourceFile,
record.sourceLine,
record.purpose,
record.consumerFiles,
record.inputs.pathParams,
record.inputs.queryParams,
record.inputs.bodyHints,
record.successShape,
record.errorShape,
record.sideEffects,
record.priority,
].map(escapeCsv).join(',')),
];
fs.writeFileSync(filePath, `${rows.join('\n')}\n`);
}
function writeMarkdown(filePath, summary, records, realtimeContracts) {
const grouped = new Map();
for (const record of records) {
if (!grouped.has(record.tag)) {
grouped.set(record.tag, []);
}
grouped.get(record.tag).push(record);
}
const lines = [
'# Backend Inventory',
'',
`Generated on ${summary.generatedAt}.`,
'',
'## Summary',
'',
`- HTTP routes: ${summary.httpRoutes}`,
`- SSE routes: ${summary.sseRoutes}`,
`- Modular routes: ${summary.modularRoutes}`,
`- Inline routes: ${summary.inlineRoutes}`,
`- Route files scanned: ${summary.routeFilesScanned}`,
'',
'## Realtime Contracts',
'',
`- Incoming websocket message types (${realtimeContracts.incomingMessageTypes.length}): ${realtimeContracts.incomingMessageTypes.join(', ')}`,
`- Outgoing websocket message types (${realtimeContracts.outgoingMessageTypes.length}): ${realtimeContracts.outgoingMessageTypes.join(', ')}`,
'',
];
for (const [tag, tagRecords] of [...grouped.entries()].sort(([left], [right]) => left.localeCompare(right))) {
lines.push(`## ${tag}`);
lines.push('');
lines.push('| Method | Path | Auth | Purpose | Consumers | Source |');
lines.push('| --- | --- | --- | --- | --- | --- |');
for (const record of tagRecords.sort((left, right) => left.path.localeCompare(right.path))) {
lines.push(
`| ${record.method} | \`${record.path}\` | ${record.authMode} | ${record.purpose} | ${record.consumerFiles.join('<br>') || '-'} | ${record.sourceFile}:${record.sourceLine} |`
);
}
lines.push('');
}
fs.writeFileSync(filePath, `${lines.join('\n')}\n`);
}
const clientFiles = walkFiles(clientRoot).filter(filePath => /\.(js|jsx|ts|tsx)$/.test(filePath));
const legacyRuntimePath = path.join(serverRoot, 'index.js');
const runtimeContent = readText(legacyRuntimePath);
const mounts = parseMounts(runtimeContent);
const records = [];
records.push(...parseRoutes(legacyRuntimePath, '', 'mixed_or_inline', clientFiles));
for (const [routeVariable, mount] of mounts.entries()) {
const relativeImport = mount.routeImport.replace('./', '');
const routeFilePath = path.join(serverRoot, relativeImport);
records.push(...parseRoutes(routeFilePath, mount.basePath, mount.authMode, clientFiles));
}
const realtimeContracts = parseRealtimeContracts(legacyRuntimePath);
const summary = {
generatedAt: new Date().toISOString(),
httpRoutes: records.filter(record => record.transport === 'http').length,
sseRoutes: records.filter(record => record.transport === 'sse').length,
modularRoutes: records.filter(record => record.sourceFile.includes('/routes/')).length,
inlineRoutes: records.filter(record => record.sourceFile === 'server/index.js').length,
routeFilesScanned: new Set(records.map(record => record.sourceFile)).size,
};
fs.writeFileSync(
path.join(docsRoot, 'endpoint-inventory.json'),
JSON.stringify({ summary, realtimeContracts, records }, null, 2)
);
writeCsv(path.join(docsRoot, 'endpoint-inventory.csv'), records);
writeMarkdown(path.join(docsRoot, 'endpoint-inventory.md'), summary, records, realtimeContracts);
console.log('[inventory] Generated docs/backend/endpoint-inventory.{json,csv,md}');
console.log(
`[inventory] HTTP=${summary.httpRoutes} SSE=${summary.sseRoutes} Modular=${summary.modularRoutes} Inline=${summary.inlineRoutes}`
);

View File

@@ -24,15 +24,16 @@ import {
notifyRunStopped,
notifyUserIfEnabled
} from './services/notification-orchestrator.js';
import { claudeAdapter } from './providers/claude/adapter.js';
import { claudeAdapter } from './providers/claude/index.js';
import { createNormalizedMessage } from './providers/types.js';
import { getStatusChecker } from './providers/registry.js';
const activeSessions = new Map();
const pendingToolApprovals = new Map();
const TOOL_APPROVAL_TIMEOUT_MS = parseInt(process.env.CLAUDE_TOOL_APPROVAL_TIMEOUT_MS, 10) || 55000;
const TOOLS_REQUIRING_INTERACTION = new Set(['AskUserQuestion']);
const TOOLS_REQUIRING_INTERACTION = new Set(['AskUserQuestion', 'ExitPlanMode']);
function createRequestId() {
if (typeof crypto.randomUUID === 'function') {
@@ -148,6 +149,10 @@ function mapCliOptionsToSDK(options = {}) {
const sdkOptions = {};
if (process.env.CLAUDE_CLI_PATH) {
sdkOptions.pathToClaudeCodeExecutable = process.env.CLAUDE_CLI_PATH;
}
// Map working directory
if (cwd) {
sdkOptions.cwd = cwd;
@@ -701,8 +706,14 @@ async function queryClaudeSDK(command, options = {}, ws) {
// Clean up temporary image files on error
await cleanupTempFiles(tempImagePaths, tempDir);
// Check if Claude CLI is installed for a clearer error message
const installed = getStatusChecker('claude')?.checkInstalled() ?? true;
const errorContent = !installed
? 'Claude Code is not installed. Please install it first: https://docs.anthropic.com/en/docs/claude-code'
: error.message;
// Send error to WebSocket
ws.send(createNormalizedMessage({ kind: 'error', content: error.message, sessionId: capturedSessionId || sessionId || null, provider: 'claude' }));
ws.send(createNormalizedMessage({ kind: 'error', content: errorContent, sessionId: capturedSessionId || sessionId || null, provider: 'claude' }));
notifyRunFailed({
userId: ws?.userId || null,
provider: 'claude',
@@ -710,8 +721,6 @@ async function queryClaudeSDK(command, options = {}, ws) {
sessionName: sessionSummary,
error
});
throw error;
}
}

View File

@@ -1,12 +1,13 @@
#!/usr/bin/env node
/**
* Claude Code UI CLI
* CloudCLI CLI
*
* Provides command-line utilities for managing Claude Code UI
* Provides command-line utilities for managing CloudCLI
*
* Commands:
* (no args) - Start the server (default)
* start - Start the server
* sandbox - Manage Docker sandbox environments
* status - Show configuration and data locations
* help - Show help information
* version - Show version information
@@ -15,11 +16,12 @@
import fs from 'fs';
import path from 'path';
import os from 'os';
import { fileURLToPath } from 'url';
import { dirname } from 'path';
import { findAppRoot, getModuleDir } from './utils/runtime-paths.js';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const __dirname = getModuleDir(import.meta.url);
// The CLI is compiled into dist-server/server, but it still needs to read the top-level
// package.json and .env file. Resolving the app root once keeps those lookups stable.
const APP_ROOT = findAppRoot(__dirname);
// ANSI color codes for terminal output
const colors = {
@@ -49,13 +51,16 @@ const c = {
};
// Load package.json for version info
const packageJsonPath = path.join(__dirname, '../package.json');
const packageJsonPath = path.join(APP_ROOT, 'package.json');
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
// Match the runtime fallback in load-env.js so "cloudcli status" reports the same default
// database location that the backend will actually use when no DATABASE_PATH is configured.
const DEFAULT_DATABASE_PATH = path.join(os.homedir(), '.cloudcli', 'auth.db');
// Load environment variables from .env file if it exists
function loadEnvFile() {
try {
const envPath = path.join(__dirname, '../.env');
const envPath = path.join(APP_ROOT, '.env');
const envFile = fs.readFileSync(envPath, 'utf8');
envFile.split('\n').forEach(line => {
const trimmedLine = line.trim();
@@ -74,17 +79,17 @@ function loadEnvFile() {
// Get the database path (same logic as db.js)
function getDatabasePath() {
loadEnvFile();
return process.env.DATABASE_PATH || path.join(__dirname, 'database', 'auth.db');
return process.env.DATABASE_PATH || DEFAULT_DATABASE_PATH;
}
// Get the installation directory
function getInstallDir() {
return path.join(__dirname, '..');
return APP_ROOT;
}
// Show status command
function showStatus() {
console.log(`\n${c.bright('Claude Code UI - Status')}\n`);
console.log(`\n${c.bright('CloudCLI UI - Status')}\n`);
console.log(c.dim('═'.repeat(60)));
// Version info
@@ -123,7 +128,7 @@ function showStatus() {
console.log(` Status: ${projectsExists ? c.ok('[OK] Exists') : c.warn('[WARN] Not found')}`);
// Config file location
const envFilePath = path.join(__dirname, '../.env');
const envFilePath = path.join(APP_ROOT, '.env');
const envExists = fs.existsSync(envFilePath);
console.log(`\n${c.info('[INFO]')} Configuration File:`);
console.log(` ${c.dim(envFilePath)}`);
@@ -141,7 +146,7 @@ function showStatus() {
function showHelp() {
console.log(`
╔═══════════════════════════════════════════════════════════════╗
║ Claude Code UI - Command Line Tool ║
║ CloudCLI - Command Line Tool ║
╚═══════════════════════════════════════════════════════════════╝
Usage:
@@ -149,7 +154,8 @@ Usage:
cloudcli [command] [options]
Commands:
start Start the Claude Code UI server (default)
start Start the CloudCLI server (default)
sandbox Manage Docker sandbox environments
status Show configuration and data locations
update Update to the latest version
help Show this help information
@@ -164,8 +170,7 @@ Options:
Examples:
$ cloudcli # Start with defaults
$ cloudcli --port 8080 # Start on port 8080
$ cloudcli -p 3000 # Short form for port
$ cloudcli start --port 4000 # Explicit start command
$ cloudcli sandbox ~/my-project # Run in a Docker sandbox
$ cloudcli status # Show configuration
Environment Variables:
@@ -203,7 +208,7 @@ function isNewerVersion(v1, v2) {
async function checkForUpdates(silent = false) {
try {
const { execSync } = await import('child_process');
const latestVersion = execSync('npm show @siteboon/claude-code-ui version', { encoding: 'utf8' }).trim();
const latestVersion = execSync('npm show @cloudcli-ai/cloudcli version', { encoding: 'utf8' }).trim();
const currentVersion = packageJson.version;
if (isNewerVersion(latestVersion, currentVersion)) {
@@ -236,14 +241,361 @@ async function updatePackage() {
}
console.log(`${c.info('[INFO]')} Updating from ${currentVersion} to ${latestVersion}...`);
execSync('npm update -g @siteboon/claude-code-ui', { stdio: 'inherit' });
execSync('npm update -g @cloudcli-ai/cloudcli', { stdio: 'inherit' });
console.log(`${c.ok('[OK]')} Update complete! Restart cloudcli to use the new version.`);
} catch (e) {
console.error(`${c.error('[ERROR]')} Update failed: ${e.message}`);
console.log(`${c.tip('[TIP]')} Try running manually: npm update -g @siteboon/claude-code-ui`);
console.log(`${c.tip('[TIP]')} Try running manually: npm update -g @cloudcli-ai/cloudcli`);
}
}
// ── Sandbox command ─────────────────────────────────────────
const SANDBOX_TEMPLATES = {
claude: 'docker.io/cloudcliai/sandbox:claude-code',
codex: 'docker.io/cloudcliai/sandbox:codex',
gemini: 'docker.io/cloudcliai/sandbox:gemini',
};
const SANDBOX_SECRETS = {
claude: 'anthropic',
codex: 'openai',
gemini: 'google',
};
function parseSandboxArgs(args) {
const result = {
subcommand: null,
workspace: null,
agent: 'claude',
name: null,
port: 3001,
template: null,
env: [],
};
const subcommands = ['ls', 'stop', 'start', 'rm', 'logs', 'help'];
for (let i = 0; i < args.length; i++) {
const arg = args[i];
if (i === 0 && subcommands.includes(arg)) {
result.subcommand = arg;
} else if (arg === '--agent' || arg === '-a') {
result.agent = args[++i];
} else if (arg === '--name' || arg === '-n') {
result.name = args[++i];
} else if (arg === '--port') {
result.port = parseInt(args[++i], 10);
} else if (arg === '--template' || arg === '-t') {
result.template = args[++i];
} else if (arg === '--env' || arg === '-e') {
result.env.push(args[++i]);
} else if (!arg.startsWith('-')) {
if (!result.subcommand) {
result.workspace = arg;
} else {
result.name = arg; // for stop/start/rm/logs <name>
}
}
}
// Default subcommand based on what we got
if (!result.subcommand) {
result.subcommand = 'create';
}
// Derive name from workspace path if not set
if (!result.name && result.workspace) {
result.name = path.basename(path.resolve(result.workspace.replace(/^~/, os.homedir())));
}
// Default template from agent
if (!result.template) {
result.template = SANDBOX_TEMPLATES[result.agent] || SANDBOX_TEMPLATES.claude;
}
return result;
}
function showSandboxHelp() {
console.log(`
${c.bright('CloudCLI Sandbox')} — Run CloudCLI inside Docker Sandboxes
Usage:
cloudcli sandbox <workspace> Create and start a sandbox
cloudcli sandbox <subcommand> [name] Manage sandboxes
Subcommands:
${c.bright('(default)')} Create a sandbox and start the web UI
${c.bright('ls')} List all sandboxes
${c.bright('start')} Restart a stopped sandbox and re-launch the web UI
${c.bright('stop')} Stop a sandbox (preserves state)
${c.bright('rm')} Remove a sandbox
${c.bright('logs')} Show CloudCLI server logs
${c.bright('help')} Show this help
Options:
-a, --agent <agent> Agent to use: claude, codex, gemini (default: claude)
-n, --name <name> Sandbox name (default: derived from workspace folder)
-t, --template <image> Custom template image
-e, --env <KEY=VALUE> Set environment variable (repeatable)
--port <port> Host port for the web UI (default: 3001)
Examples:
$ cloudcli sandbox ~/my-project
$ cloudcli sandbox ~/my-project --agent codex --port 8080
$ cloudcli sandbox ~/my-project --env SERVER_PORT=8080 --env HOST=0.0.0.0
$ cloudcli sandbox ls
$ cloudcli sandbox stop my-project
$ cloudcli sandbox start my-project
$ cloudcli sandbox rm my-project
Prerequisites:
1. Install sbx CLI: https://docs.docker.com/ai/sandboxes/get-started/
2. Authenticate and store your API key:
sbx login
sbx secret set -g anthropic # for Claude
sbx secret set -g openai # for Codex
sbx secret set -g google # for Gemini
Advanced usage:
For branch mode, multiple workspaces, memory limits, network policies,
or passing prompts to the agent, use sbx directly with the template:
sbx run --template docker.io/cloudcliai/sandbox:claude-code claude ~/my-project --branch my-feature
sbx run --template docker.io/cloudcliai/sandbox:claude-code claude ~/project ~/libs:ro --memory 8g
Full Docker Sandboxes docs: https://docs.docker.com/ai/sandboxes/usage/
`);
}
async function sandboxCommand(args) {
const { execFileSync, spawn: spawnProcess } = await import('child_process');
// Safe execution — uses execFileSync (no shell) to prevent injection
const sbx = (subcmd, opts = {}) => {
const result = execFileSync('sbx', subcmd, {
encoding: 'utf8',
stdio: opts.inherit ? 'inherit' : 'pipe',
});
return result || '';
};
const opts = parseSandboxArgs(args);
if (opts.subcommand === 'help') {
showSandboxHelp();
return;
}
// Validate name (alphanumeric, hyphens, underscores only)
if (opts.name && !/^[\w-]+$/.test(opts.name)) {
console.error(`\n${c.error('❌')} Invalid sandbox name: ${opts.name}`);
console.log(` Names may only contain letters, numbers, hyphens, and underscores.\n`);
process.exit(1);
}
// Check sbx is installed
try {
sbx(['version']);
} catch {
console.error(`\n${c.error('❌')} ${c.bright('sbx')} CLI not found.\n`);
console.log(` Install it from: ${c.info('https://docs.docker.com/ai/sandboxes/get-started/')}`);
console.log(` Then run: ${c.bright('sbx login')}`);
console.log(` And store your API key: ${c.bright('sbx secret set -g anthropic')}\n`);
process.exit(1);
}
switch (opts.subcommand) {
case 'ls':
sbx(['ls'], { inherit: true });
break;
case 'stop':
if (!opts.name) {
console.error(`\n${c.error('❌')} Sandbox name required: cloudcli sandbox stop <name>\n`);
process.exit(1);
}
sbx(['stop', opts.name], { inherit: true });
break;
case 'rm':
if (!opts.name) {
console.error(`\n${c.error('❌')} Sandbox name required: cloudcli sandbox rm <name>\n`);
process.exit(1);
}
sbx(['rm', opts.name], { inherit: true });
break;
case 'logs':
if (!opts.name) {
console.error(`\n${c.error('❌')} Sandbox name required: cloudcli sandbox logs <name>\n`);
process.exit(1);
}
try {
sbx(['exec', opts.name, 'bash', '-c', 'cat /tmp/cloudcli-ui.log'], { inherit: true });
} catch (e) {
console.error(`\n${c.error('❌')} Could not read logs: ${e.message || 'Is the sandbox running?'}\n`);
}
break;
case 'start': {
if (!opts.name) {
console.error(`\n${c.error('❌')} Sandbox name required: cloudcli sandbox start <name>\n`);
process.exit(1);
}
console.log(`\n${c.info('▶')} Starting sandbox ${c.bright(opts.name)}...`);
const restartRun = spawnProcess('sbx', ['run', opts.name], {
detached: true,
stdio: ['ignore', 'ignore', 'ignore'],
});
restartRun.unref();
await new Promise(resolve => setTimeout(resolve, 5000));
console.log(`${c.info('▶')} Launching CloudCLI web server...`);
sbx(['exec', opts.name, 'bash', '-c', 'cloudcli start --port 3001 &']);
console.log(`${c.info('▶')} Forwarding port ${opts.port} → 3001...`);
try {
sbx(['ports', opts.name, '--publish', `${opts.port}:3001`]);
} catch (e) {
const msg = e.stdout || e.stderr || e.message || '';
if (msg.includes('address already in use')) {
const altPort = opts.port + 1;
console.log(`${c.warn('⚠')} Port ${opts.port} in use, trying ${altPort}...`);
try {
sbx(['ports', opts.name, '--publish', `${altPort}:3001`]);
opts.port = altPort;
} catch {
console.error(`${c.error('❌')} Ports ${opts.port} and ${altPort} both in use. Use --port to specify a free port.`);
process.exit(1);
}
} else {
throw e;
}
}
console.log(`\n${c.ok('✔')} ${c.bright('CloudCLI is ready!')}`);
console.log(` ${c.info('→')} ${c.bright(`http://localhost:${opts.port}`)}\n`);
break;
}
case 'create': {
if (!opts.workspace) {
console.error(`\n${c.error('❌')} Workspace path required: cloudcli sandbox <path>\n`);
console.log(` Example: ${c.bright('cloudcli sandbox ~/my-project')}\n`);
process.exit(1);
}
const workspace = opts.workspace.startsWith('~')
? opts.workspace.replace(/^~/, os.homedir())
: path.resolve(opts.workspace);
if (!fs.existsSync(workspace)) {
console.error(`\n${c.error('❌')} Workspace path not found: ${c.dim(workspace)}\n`);
process.exit(1);
}
const secret = SANDBOX_SECRETS[opts.agent] || 'anthropic';
// Check if the required secret is stored
try {
const secretList = sbx(['secret', 'ls']);
if (!secretList.includes(secret)) {
console.error(`\n${c.error('❌')} No ${c.bright(secret)} API key found.\n`);
console.log(` Run: ${c.bright(`sbx secret set -g ${secret}`)}\n`);
process.exit(1);
}
} catch { /* sbx secret ls not available, skip check */ }
console.log(`\n${c.bright('CloudCLI Sandbox')}`);
console.log(c.dim('─'.repeat(50)));
console.log(` Agent: ${c.info(opts.agent)} ${c.dim(`(${secret} credentials)`)}`);
console.log(` Workspace: ${c.dim(workspace)}`);
console.log(` Name: ${c.dim(opts.name)}`);
console.log(` Template: ${c.dim(opts.template)}`);
console.log(` Port: ${c.dim(String(opts.port))}`);
if (opts.env.length > 0) {
console.log(` Env: ${c.dim(opts.env.join(', '))}`);
}
console.log(c.dim('─'.repeat(50)));
// Step 1: Launch sandbox with sbx run in background.
// sbx run creates the sandbox (or reconnects) AND holds an active session,
// which prevents the sandbox from auto-stopping.
console.log(`\n${c.info('▶')} Creating sandbox ${c.bright(opts.name)}...`);
const bgRun = spawnProcess('sbx', [
'run', '--template', opts.template, '--name', opts.name, opts.agent, workspace,
], {
detached: true,
stdio: ['ignore', 'ignore', 'ignore'],
});
bgRun.unref();
// Wait for sandbox to be ready
await new Promise(resolve => setTimeout(resolve, 5000));
// Step 2: Inject environment variables
if (opts.env.length > 0) {
console.log(`${c.info('▶')} Setting environment variables...`);
const exports = opts.env
.filter(e => /^\w+=.+$/.test(e))
.map(e => `export ${e}`)
.join('\n');
if (exports) {
sbx(['exec', opts.name, 'bash', '-c', `echo '${exports}' >> /etc/sandbox-persistent.sh`]);
}
const invalid = opts.env.filter(e => !/^\w+=.+$/.test(e));
if (invalid.length > 0) {
console.log(`${c.warn('⚠')} Skipped invalid env vars: ${invalid.join(', ')} (expected KEY=VALUE)`);
}
}
// Step 3: Start CloudCLI inside the sandbox
console.log(`${c.info('▶')} Launching CloudCLI web server...`);
sbx(['exec', opts.name, 'bash', '-c', 'cloudcli start --port 3001 &']);
// Step 4: Forward port
console.log(`${c.info('▶')} Forwarding port ${opts.port} → 3001...`);
try {
sbx(['ports', opts.name, '--publish', `${opts.port}:3001`]);
} catch (e) {
const msg = e.stdout || e.stderr || e.message || '';
if (msg.includes('address already in use')) {
const altPort = opts.port + 1;
console.log(`${c.warn('⚠')} Port ${opts.port} in use, trying ${altPort}...`);
try {
sbx(['ports', opts.name, '--publish', `${altPort}:3001`]);
opts.port = altPort;
} catch {
console.error(`${c.error('❌')} Ports ${opts.port} and ${altPort} both in use. Use --port to specify a free port.`);
process.exit(1);
}
} else {
throw e;
}
}
// Done
console.log(`\n${c.ok('✔')} ${c.bright('CloudCLI is ready!')}`);
console.log(` ${c.info('→')} Open ${c.bright(`http://localhost:${opts.port}`)}`);
console.log(`\n${c.dim(' Manage with:')}`);
console.log(` ${c.dim('$')} sbx ls`);
console.log(` ${c.dim('$')} sbx stop ${opts.name}`);
console.log(` ${c.dim('$')} sbx start ${opts.name}`);
console.log(` ${c.dim('$')} sbx rm ${opts.name}`);
console.log(`\n${c.dim(' Or install globally:')} npm install -g @cloudcli-ai/cloudcli\n`);
break;
}
default:
showSandboxHelp();
}
}
// ── Server ──────────────────────────────────────────────────
// Start the server
async function startServer() {
// Check for updates silently on startup
@@ -274,6 +626,10 @@ function parseArgs(args) {
parsed.command = 'version';
} else if (!arg.startsWith('-')) {
parsed.command = arg;
if (arg === 'sandbox') {
parsed.remainingArgs = args.slice(i + 1);
break;
}
}
}
@@ -283,7 +639,7 @@ function parseArgs(args) {
// Main CLI handler
async function main() {
const args = process.argv.slice(2);
const { command, options } = parseArgs(args);
const { command, options, remainingArgs } = parseArgs(args);
// Apply CLI options to environment variables
if (options.serverPort) {
@@ -299,6 +655,9 @@ async function main() {
case 'start':
await startServer();
break;
case 'sandbox':
await sandboxCommand(remainingArgs || []);
break;
case 'status':
case 'info':
showStatus();

View File

@@ -1,8 +1,9 @@
import { spawn } from 'child_process';
import crossSpawn from 'cross-spawn';
import { notifyRunFailed, notifyRunStopped } from './services/notification-orchestrator.js';
import { cursorAdapter } from './providers/cursor/adapter.js';
import { cursorAdapter } from './providers/cursor/index.js';
import { createNormalizedMessage } from './providers/types.js';
import { getStatusChecker } from './providers/registry.js';
// Use cross-spawn on Windows for better command execution
const spawnFunction = process.platform === 'win32' ? crossSpawn : spawn;
@@ -294,7 +295,13 @@ async function spawnCursor(command, options = {}, ws) {
const finalSessionId = capturedSessionId || sessionId || processKey;
activeCursorProcesses.delete(finalSessionId);
ws.send(createNormalizedMessage({ kind: 'error', content: error.message, sessionId: capturedSessionId || sessionId || null, provider: 'cursor' }));
// Check if Cursor CLI is installed for a clearer error message
const installed = getStatusChecker('cursor')?.checkInstalled() ?? true;
const errorContent = !installed
? 'Cursor CLI is not installed. Please install it from https://cursor.com'
: error.message;
ws.send(createNormalizedMessage({ kind: 'error', content: errorContent, sessionId: capturedSessionId || sessionId || null, provider: 'cursor' }));
notifyTerminalState({ error });
settleOnce(() => reject(error));

View File

@@ -2,11 +2,21 @@ import Database from 'better-sqlite3';
import path from 'path';
import fs from 'fs';
import crypto from 'crypto';
import { fileURLToPath } from 'url';
import { dirname } from 'path';
import { findAppRoot, getModuleDir } from '../utils/runtime-paths.js';
import {
APP_CONFIG_TABLE_SQL,
USER_NOTIFICATION_PREFERENCES_TABLE_SQL,
VAPID_KEYS_TABLE_SQL,
PUSH_SUBSCRIPTIONS_TABLE_SQL,
SESSION_NAMES_TABLE_SQL,
SESSION_NAMES_LOOKUP_INDEX_SQL,
DATABASE_SCHEMA_SQL
} from './schema.js';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const __dirname = getModuleDir(import.meta.url);
// The compiled backend lives under dist-server/server/database, but the install root we log
// should still point at the project/app root. Resolving it here avoids build-layout drift.
const APP_ROOT = findAppRoot(__dirname);
// ANSI color codes for terminal output
const colors = {
@@ -24,7 +34,6 @@ const c = {
// Use DATABASE_PATH environment variable if set, otherwise use default location
const DB_PATH = process.env.DATABASE_PATH || path.join(__dirname, 'auth.db');
const INIT_SQL_PATH = path.join(__dirname, 'init.sql');
// Ensure database directory exists if custom path is provided
if (process.env.DATABASE_PATH) {
@@ -62,14 +71,10 @@ const db = new Database(DB_PATH);
// app_config must exist before any other module imports (auth.js reads the JWT secret at load time).
// runMigrations() also creates this table, but it runs too late for existing installations
// where auth.js is imported before initializeDatabase() is called.
db.exec(`CREATE TABLE IF NOT EXISTS app_config (
key TEXT PRIMARY KEY,
value TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)`);
db.exec(APP_CONFIG_TABLE_SQL);
// Show app installation path prominently
const appInstallPath = path.join(__dirname, '../..');
const appInstallPath = APP_ROOT;
console.log('');
console.log(c.dim('═'.repeat(60)));
console.log(`${c.info('[INFO]')} App Installation: ${c.bright(appInstallPath)}`);
@@ -100,53 +105,12 @@ const runMigrations = () => {
db.exec('ALTER TABLE users ADD COLUMN has_completed_onboarding BOOLEAN DEFAULT 0');
}
db.exec(`
CREATE TABLE IF NOT EXISTS user_notification_preferences (
user_id INTEGER PRIMARY KEY,
preferences_json TEXT NOT NULL,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
)
`);
db.exec(`
CREATE TABLE IF NOT EXISTS vapid_keys (
id INTEGER PRIMARY KEY AUTOINCREMENT,
public_key TEXT NOT NULL,
private_key TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
`);
db.exec(`
CREATE TABLE IF NOT EXISTS push_subscriptions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL,
endpoint TEXT NOT NULL UNIQUE,
keys_p256dh TEXT NOT NULL,
keys_auth TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
)
`);
// Create app_config table if it doesn't exist (for existing installations)
db.exec(`CREATE TABLE IF NOT EXISTS app_config (
key TEXT PRIMARY KEY,
value TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)`);
// Create session_names table if it doesn't exist (for existing installations)
db.exec(`CREATE TABLE IF NOT EXISTS session_names (
id INTEGER PRIMARY KEY AUTOINCREMENT,
session_id TEXT NOT NULL,
provider TEXT NOT NULL DEFAULT 'claude',
custom_name TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
UNIQUE(session_id, provider)
)`);
db.exec('CREATE INDEX IF NOT EXISTS idx_session_names_lookup ON session_names(session_id, provider)');
db.exec(USER_NOTIFICATION_PREFERENCES_TABLE_SQL);
db.exec(VAPID_KEYS_TABLE_SQL);
db.exec(PUSH_SUBSCRIPTIONS_TABLE_SQL);
db.exec(APP_CONFIG_TABLE_SQL);
db.exec(SESSION_NAMES_TABLE_SQL);
db.exec(SESSION_NAMES_LOOKUP_INDEX_SQL);
console.log('Database migrations completed successfully');
} catch (error) {
@@ -158,8 +122,7 @@ const runMigrations = () => {
// Initialize database with schema
const initializeDatabase = async () => {
try {
const initSQL = fs.readFileSync(INIT_SQL_PATH, 'utf8');
db.exec(initSQL);
db.exec(DATABASE_SCHEMA_SQL);
console.log('Database initialized successfully');
runMigrations();
} catch (error) {

View File

@@ -1,99 +0,0 @@
-- Initialize authentication database
PRAGMA foreign_keys = ON;
-- Users table (single user system)
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE NOT NULL,
password_hash TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
last_login DATETIME,
is_active BOOLEAN DEFAULT 1,
git_name TEXT,
git_email TEXT,
has_completed_onboarding BOOLEAN DEFAULT 0
);
-- Indexes for performance
CREATE INDEX IF NOT EXISTS idx_users_username ON users(username);
CREATE INDEX IF NOT EXISTS idx_users_active ON users(is_active);
-- API Keys table for external API access
CREATE TABLE IF NOT EXISTS api_keys (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL,
key_name TEXT NOT NULL,
api_key TEXT UNIQUE NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
last_used DATETIME,
is_active BOOLEAN DEFAULT 1,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_api_keys_key ON api_keys(api_key);
CREATE INDEX IF NOT EXISTS idx_api_keys_user_id ON api_keys(user_id);
CREATE INDEX IF NOT EXISTS idx_api_keys_active ON api_keys(is_active);
-- User credentials table for storing various tokens/credentials (GitHub, GitLab, etc.)
CREATE TABLE IF NOT EXISTS user_credentials (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL,
credential_name TEXT NOT NULL,
credential_type TEXT NOT NULL, -- 'github_token', 'gitlab_token', 'bitbucket_token', etc.
credential_value TEXT NOT NULL,
description TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
is_active BOOLEAN DEFAULT 1,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_user_credentials_user_id ON user_credentials(user_id);
CREATE INDEX IF NOT EXISTS idx_user_credentials_type ON user_credentials(credential_type);
CREATE INDEX IF NOT EXISTS idx_user_credentials_active ON user_credentials(is_active);
-- User notification preferences (backend-owned, provider-agnostic)
CREATE TABLE IF NOT EXISTS user_notification_preferences (
user_id INTEGER PRIMARY KEY,
preferences_json TEXT NOT NULL,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
-- VAPID key pair for Web Push notifications
CREATE TABLE IF NOT EXISTS vapid_keys (
id INTEGER PRIMARY KEY AUTOINCREMENT,
public_key TEXT NOT NULL,
private_key TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- Browser push subscriptions
CREATE TABLE IF NOT EXISTS push_subscriptions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL,
endpoint TEXT NOT NULL UNIQUE,
keys_p256dh TEXT NOT NULL,
keys_auth TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
-- Session custom names (provider-agnostic display name overrides)
CREATE TABLE IF NOT EXISTS session_names (
id INTEGER PRIMARY KEY AUTOINCREMENT,
session_id TEXT NOT NULL,
provider TEXT NOT NULL DEFAULT 'claude',
custom_name TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
UNIQUE(session_id, provider)
);
CREATE INDEX IF NOT EXISTS idx_session_names_lookup ON session_names(session_id, provider);
-- App configuration table (auto-generated secrets, settings, etc.)
CREATE TABLE IF NOT EXISTS app_config (
key TEXT PRIMARY KEY,
value TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

102
server/database/schema.js Normal file
View File

@@ -0,0 +1,102 @@
export const APP_CONFIG_TABLE_SQL = `CREATE TABLE IF NOT EXISTS app_config (
key TEXT PRIMARY KEY,
value TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);`;
export const USER_NOTIFICATION_PREFERENCES_TABLE_SQL = `CREATE TABLE IF NOT EXISTS user_notification_preferences (
user_id INTEGER PRIMARY KEY,
preferences_json TEXT NOT NULL,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);`;
export const VAPID_KEYS_TABLE_SQL = `CREATE TABLE IF NOT EXISTS vapid_keys (
id INTEGER PRIMARY KEY AUTOINCREMENT,
public_key TEXT NOT NULL,
private_key TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);`;
export const PUSH_SUBSCRIPTIONS_TABLE_SQL = `CREATE TABLE IF NOT EXISTS push_subscriptions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL,
endpoint TEXT NOT NULL UNIQUE,
keys_p256dh TEXT NOT NULL,
keys_auth TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);`;
export const SESSION_NAMES_TABLE_SQL = `CREATE TABLE IF NOT EXISTS session_names (
id INTEGER PRIMARY KEY AUTOINCREMENT,
session_id TEXT NOT NULL,
provider TEXT NOT NULL DEFAULT 'claude',
custom_name TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
UNIQUE(session_id, provider)
);`;
export const SESSION_NAMES_LOOKUP_INDEX_SQL = `CREATE INDEX IF NOT EXISTS idx_session_names_lookup ON session_names(session_id, provider);`;
export const DATABASE_SCHEMA_SQL = `PRAGMA foreign_keys = ON;
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE NOT NULL,
password_hash TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
last_login DATETIME,
is_active BOOLEAN DEFAULT 1,
git_name TEXT,
git_email TEXT,
has_completed_onboarding BOOLEAN DEFAULT 0
);
CREATE INDEX IF NOT EXISTS idx_users_username ON users(username);
CREATE INDEX IF NOT EXISTS idx_users_active ON users(is_active);
CREATE TABLE IF NOT EXISTS api_keys (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL,
key_name TEXT NOT NULL,
api_key TEXT UNIQUE NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
last_used DATETIME,
is_active BOOLEAN DEFAULT 1,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_api_keys_key ON api_keys(api_key);
CREATE INDEX IF NOT EXISTS idx_api_keys_user_id ON api_keys(user_id);
CREATE INDEX IF NOT EXISTS idx_api_keys_active ON api_keys(is_active);
CREATE TABLE IF NOT EXISTS user_credentials (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL,
credential_name TEXT NOT NULL,
credential_type TEXT NOT NULL,
credential_value TEXT NOT NULL,
description TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
is_active BOOLEAN DEFAULT 1,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_user_credentials_user_id ON user_credentials(user_id);
CREATE INDEX IF NOT EXISTS idx_user_credentials_type ON user_credentials(credential_type);
CREATE INDEX IF NOT EXISTS idx_user_credentials_active ON user_credentials(is_active);
${USER_NOTIFICATION_PREFERENCES_TABLE_SQL}
${VAPID_KEYS_TABLE_SQL}
${PUSH_SUBSCRIPTIONS_TABLE_SQL}
${SESSION_NAMES_TABLE_SQL}
${SESSION_NAMES_LOOKUP_INDEX_SQL}
${APP_CONFIG_TABLE_SQL}
`;

View File

@@ -10,6 +10,7 @@ import sessionManager from './sessionManager.js';
import GeminiResponseHandler from './gemini-response-handler.js';
import { notifyRunFailed, notifyRunStopped } from './services/notification-orchestrator.js';
import { createNormalizedMessage } from './providers/types.js';
import { getStatusChecker } from './providers/registry.js';
let activeGeminiProcesses = new Map(); // Track active processes by session ID
@@ -380,6 +381,15 @@ async function spawnGemini(command, options = {}, ws) {
notifyTerminalState({ code });
resolve();
} else {
// code 127 = shell "command not found" — check installation
if (code === 127) {
const installed = getStatusChecker('gemini')?.checkInstalled() ?? true;
if (!installed) {
const socketSessionId = typeof ws.getSessionId === 'function' ? ws.getSessionId() : finalSessionId;
ws.send(createNormalizedMessage({ kind: 'error', content: 'Gemini CLI is not installed. Please install it first: https://github.com/google-gemini/gemini-cli', sessionId: socketSessionId, provider: 'gemini' }));
}
}
notifyTerminalState({
code,
error: code === null ? 'Gemini CLI process was terminated or timed out' : null
@@ -394,8 +404,14 @@ async function spawnGemini(command, options = {}, ws) {
const finalSessionId = capturedSessionId || sessionId || processKey;
activeGeminiProcesses.delete(finalSessionId);
// Check if Gemini CLI is installed for a clearer error message
const installed = getStatusChecker('gemini')?.checkInstalled() ?? true;
const errorContent = !installed
? 'Gemini CLI is not installed. Please install it first: https://github.com/google-gemini/gemini-cli'
: error.message;
const errorSessionId = typeof ws.getSessionId === 'function' ? ws.getSessionId() : finalSessionId;
ws.send(createNormalizedMessage({ kind: 'error', content: error.message, sessionId: errorSessionId, provider: 'gemini' }));
ws.send(createNormalizedMessage({ kind: 'error', content: errorContent, sessionId: errorSessionId, provider: 'gemini' }));
notifyTerminalState({ error });
reject(error);

View File

@@ -1,5 +1,5 @@
// Gemini Response Handler - JSON Stream processing
import { geminiAdapter } from './providers/gemini/adapter.js';
import { geminiAdapter } from './providers/gemini/index.js';
class GeminiResponseHandler {
constructor(ws, options = {}) {

View File

@@ -3,33 +3,15 @@
import './load-env.js';
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import { dirname } from 'path';
import { findAppRoot, getModuleDir } from './utils/runtime-paths.js';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const __dirname = getModuleDir(import.meta.url);
// The server source runs from /server, while the compiled output runs from /dist-server/server.
// Resolving the app root once keeps every repo-level lookup below aligned across both layouts.
const APP_ROOT = findAppRoot(__dirname);
const installMode = fs.existsSync(path.join(APP_ROOT, '.git')) ? 'git' : 'npm';
const installMode = fs.existsSync(path.join(__dirname, '..', '.git')) ? 'git' : 'npm';
// ANSI color codes for terminal output
const colors = {
reset: '\x1b[0m',
bright: '\x1b[1m',
cyan: '\x1b[36m',
green: '\x1b[32m',
yellow: '\x1b[33m',
blue: '\x1b[34m',
dim: '\x1b[2m',
};
const c = {
info: (text) => `${colors.cyan}${text}${colors.reset}`,
ok: (text) => `${colors.green}${text}${colors.reset}`,
warn: (text) => `${colors.yellow}${text}${colors.reset}`,
tip: (text) => `${colors.blue}${text}${colors.reset}`,
bright: (text) => `${colors.bright}${text}${colors.reset}`,
dim: (text) => `${colors.dim}${text}${colors.reset}`,
};
import { c } from './utils/colors.js';
console.log('SERVER_PORT from env:', process.env.SERVER_PORT);
@@ -226,68 +208,7 @@ const server = http.createServer(app);
const ptySessionsMap = new Map();
const PTY_SESSION_TIMEOUT = 30 * 60 * 1000;
const SHELL_URL_PARSE_BUFFER_LIMIT = 32768;
const ANSI_ESCAPE_SEQUENCE_REGEX = /\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~]|\][^\x07]*(?:\x07|\x1B\\))/g;
const TRAILING_URL_PUNCTUATION_REGEX = /[)\]}>.,;:!?]+$/;
function stripAnsiSequences(value = '') {
return value.replace(ANSI_ESCAPE_SEQUENCE_REGEX, '');
}
function normalizeDetectedUrl(url) {
if (!url || typeof url !== 'string') return null;
const cleaned = url.trim().replace(TRAILING_URL_PUNCTUATION_REGEX, '');
if (!cleaned) return null;
try {
const parsed = new URL(cleaned);
if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
return null;
}
return parsed.toString();
} catch {
return null;
}
}
function extractUrlsFromText(value = '') {
const directMatches = value.match(/https?:\/\/[^\s<>"'`\\\x1b\x07]+/gi) || [];
// Handle wrapped terminal URLs split across lines by terminal width.
const wrappedMatches = [];
const continuationRegex = /^[A-Za-z0-9\-._~:/?#\[\]@!$&'()*+,;=%]+$/;
const lines = value.split(/\r?\n/);
for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim();
const startMatch = line.match(/https?:\/\/[^\s<>"'`\\\x1b\x07]+/i);
if (!startMatch) continue;
let combined = startMatch[0];
let j = i + 1;
while (j < lines.length) {
const continuation = lines[j].trim();
if (!continuation) break;
if (!continuationRegex.test(continuation)) break;
combined += continuation;
j++;
}
wrappedMatches.push(combined.replace(/\r?\n\s*/g, ''));
}
return Array.from(new Set([...directMatches, ...wrappedMatches]));
}
function shouldAutoOpenUrlFromOutput(value = '') {
const normalized = value.toLowerCase();
return (
normalized.includes('browser didn\'t open') ||
normalized.includes('open this url') ||
normalized.includes('continue in your browser') ||
normalized.includes('press enter to open') ||
normalized.includes('open_url:')
);
}
import { stripAnsiSequences, normalizeDetectedUrl, extractUrlsFromText, shouldAutoOpenUrlFromOutput } from './utils/url-detection.js';
// Single WebSocket server that handles both paths
const wss = new WebSocketServer({
@@ -405,11 +326,11 @@ app.use('/api/sessions', authenticateToken, messagesRoutes);
app.use('/api/agent', agentRoutes);
// Serve public files (like api-docs.html)
app.use(express.static(path.join(__dirname, '../public')));
app.use(express.static(path.join(APP_ROOT, 'public')));
// Static files served after API routes
// Add cache control: HTML files should not be cached, but assets can be cached
app.use(express.static(path.join(__dirname, '../dist'), {
app.use(express.static(path.join(APP_ROOT, 'dist'), {
setHeaders: (res, filePath) => {
if (filePath.endsWith('.html')) {
// Prevent HTML caching to avoid service worker issues after builds
@@ -431,17 +352,24 @@ app.use(express.static(path.join(__dirname, '../dist'), {
app.post('/api/system/update', authenticateToken, async (req, res) => {
try {
// Get the project root directory (parent of server directory)
const projectRoot = path.join(__dirname, '..');
const projectRoot = APP_ROOT;
console.log('Starting system update from directory:', projectRoot);
// Run the update command based on install mode
const updateCommand = installMode === 'git'
? 'git checkout main && git pull && npm install'
: 'npm install -g @siteboon/claude-code-ui@latest';
// Platform deployments use their own update workflow from the project root.
const updateCommand = IS_PLATFORM
// In platform, husky and dev dependencies are not needed
? 'npm run update:platform'
: installMode === 'git'
? 'git checkout main && git pull && npm install'
: 'npm install -g @cloudcli-ai/cloudcli@latest';
const updateCwd = IS_PLATFORM || installMode === 'git'
? projectRoot
: os.homedir();
const child = spawn('sh', ['-c', updateCommand], {
cwd: installMode === 'git' ? projectRoot : os.homedir(),
cwd: updateCwd,
env: process.env
});
@@ -566,12 +494,15 @@ app.put('/api/sessions/:sessionId/rename', authenticateToken, async (req, res) =
}
});
// Delete project endpoint (force=true to delete with sessions)
// Delete project endpoint
// force=true to allow removal even when sessions exist
// deleteData=true to also delete session/memory files on disk (destructive)
app.delete('/api/projects/:projectName', authenticateToken, async (req, res) => {
try {
const { projectName } = req.params;
const force = req.query.force === 'true';
await deleteProject(projectName, force);
const deleteData = req.query.deleteData === 'true';
await deleteProject(projectName, force, deleteData);
res.json({ success: true });
} catch (error) {
res.status(500).json({ error: error.message });
@@ -812,7 +743,7 @@ app.get('/api/projects/:projectName/file', authenticateToken, async (req, res) =
}
});
// Serve binary file content endpoint (for images, etc.)
// Serve raw file bytes for previews and downloads.
app.get('/api/projects/:projectName/files/content', authenticateToken, async (req, res) => {
try {
const { projectName } = req.params;
@@ -829,7 +760,11 @@ app.get('/api/projects/:projectName/files/content', authenticateToken, async (re
return res.status(404).json({ error: 'Project not found' });
}
const resolved = path.resolve(filePath);
// Match the text reader endpoint so callers can pass either project-relative
// or absolute paths without changing how the bytes are served.
const resolved = path.isAbsolute(filePath)
? path.resolve(filePath)
: path.resolve(projectRoot, filePath);
const normalizedRoot = path.resolve(projectRoot) + path.sep;
if (!resolved.startsWith(normalizedRoot)) {
return res.status(403).json({ error: 'Path must be under project root' });
@@ -1980,155 +1915,6 @@ function handleShellConnection(ws) {
console.error('[ERROR] Shell WebSocket error:', error);
});
}
// Audio transcription endpoint
app.post('/api/transcribe', authenticateToken, async (req, res) => {
try {
const multer = (await import('multer')).default;
const upload = multer({ storage: multer.memoryStorage() });
// Handle multipart form data
upload.single('audio')(req, res, async (err) => {
if (err) {
return res.status(400).json({ error: 'Failed to process audio file' });
}
if (!req.file) {
return res.status(400).json({ error: 'No audio file provided' });
}
const apiKey = process.env.OPENAI_API_KEY;
if (!apiKey) {
return res.status(500).json({ error: 'OpenAI API key not configured. Please set OPENAI_API_KEY in server environment.' });
}
try {
// Create form data for OpenAI
const FormData = (await import('form-data')).default;
const formData = new FormData();
formData.append('file', req.file.buffer, {
filename: req.file.originalname,
contentType: req.file.mimetype
});
formData.append('model', 'whisper-1');
formData.append('response_format', 'json');
formData.append('language', 'en');
// Make request to OpenAI
const response = await fetch('https://api.openai.com/v1/audio/transcriptions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
...formData.getHeaders()
},
body: formData
});
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
throw new Error(errorData.error?.message || `Whisper API error: ${response.status}`);
}
const data = await response.json();
let transcribedText = data.text || '';
// Check if enhancement mode is enabled
const mode = req.body.mode || 'default';
// If no transcribed text, return empty
if (!transcribedText) {
return res.json({ text: '' });
}
// If default mode, return transcribed text without enhancement
if (mode === 'default') {
return res.json({ text: transcribedText });
}
// Handle different enhancement modes
try {
const OpenAI = (await import('openai')).default;
const openai = new OpenAI({ apiKey });
let prompt, systemMessage, temperature = 0.7, maxTokens = 800;
switch (mode) {
case 'prompt':
systemMessage = 'You are an expert prompt engineer who creates clear, detailed, and effective prompts.';
prompt = `You are an expert prompt engineer. Transform the following rough instruction into a clear, detailed, and context-aware AI prompt.
Your enhanced prompt should:
1. Be specific and unambiguous
2. Include relevant context and constraints
3. Specify the desired output format
4. Use clear, actionable language
5. Include examples where helpful
6. Consider edge cases and potential ambiguities
Transform this rough instruction into a well-crafted prompt:
"${transcribedText}"
Enhanced prompt:`;
break;
case 'vibe':
case 'instructions':
case 'architect':
systemMessage = 'You are a helpful assistant that formats ideas into clear, actionable instructions for AI agents.';
temperature = 0.5; // Lower temperature for more controlled output
prompt = `Transform the following idea into clear, well-structured instructions that an AI agent can easily understand and execute.
IMPORTANT RULES:
- Format as clear, step-by-step instructions
- Add reasonable implementation details based on common patterns
- Only include details directly related to what was asked
- Do NOT add features or functionality not mentioned
- Keep the original intent and scope intact
- Use clear, actionable language an agent can follow
Transform this idea into agent-friendly instructions:
"${transcribedText}"
Agent instructions:`;
break;
default:
// No enhancement needed
break;
}
// Only make GPT call if we have a prompt
if (prompt) {
const completion = await openai.chat.completions.create({
model: 'gpt-4o-mini',
messages: [
{ role: 'system', content: systemMessage },
{ role: 'user', content: prompt }
],
temperature: temperature,
max_tokens: maxTokens
});
transcribedText = completion.choices[0].message.content || transcribedText;
}
} catch (gptError) {
console.error('GPT processing error:', gptError);
// Fall back to original transcription if GPT fails
}
res.json({ text: transcribedText });
} catch (error) {
console.error('Transcription error:', error);
res.status(500).json({ error: error.message });
}
});
} catch (error) {
console.error('Endpoint error:', error);
res.status(500).json({ error: 'Internal server error' });
}
});
// Image upload endpoint
app.post('/api/projects/:projectName/upload-images', authenticateToken, async (req, res) => {
try {
@@ -2411,7 +2197,7 @@ app.get('*', (req, res) => {
// Only serve index.html for HTML routes, not for static assets
// Static assets should already be handled by express.static middleware above
const indexPath = path.join(__dirname, '../dist/index.html');
const indexPath = path.join(APP_ROOT, 'dist', 'index.html');
// Check if dist/index.html exists (production build available)
if (fs.existsSync(indexPath)) {
@@ -2526,7 +2312,7 @@ async function startServer() {
configureWebPush();
// Check if running in production mode (dist folder exists)
const distIndexPath = path.join(__dirname, '../dist/index.html');
const distIndexPath = path.join(APP_ROOT, 'dist', 'index.html');
const isProduction = fs.existsSync(distIndexPath);
// Log Claude implementation mode
@@ -2540,11 +2326,11 @@ async function startServer() {
console.log(`${c.info('[INFO]')} To run in development mode with hot-module replacement, go to http://${DISPLAY_HOST}:${VITE_PORT}`);
server.listen(SERVER_PORT, HOST, async () => {
const appInstallPath = path.join(__dirname, '..');
const appInstallPath = APP_ROOT;
console.log('');
console.log(c.dim('═'.repeat(63)));
console.log(` ${c.bright('Claude Code UI Server - Ready')}`);
console.log(` ${c.bright('CloudCLI Server - Ready')}`);
console.log(c.dim('═'.repeat(63)));
console.log('');
console.log(`${c.info('[INFO]')} Server URL: ${c.bright('http://' + DISPLAY_HOST + ':' + SERVER_PORT)}`);

View File

@@ -2,14 +2,15 @@
import fs from 'fs';
import os from 'os';
import path from 'path';
import { fileURLToPath } from 'url';
import { dirname } from 'path';
import { findAppRoot, getModuleDir } from './utils/runtime-paths.js';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const __dirname = getModuleDir(import.meta.url);
// Resolve the repo/app root via the nearest /server folder so this file keeps finding the
// same top-level .env file from both /server/load-env.js and /dist-server/server/load-env.js.
const APP_ROOT = findAppRoot(__dirname);
try {
const envPath = path.join(__dirname, '../.env');
const envPath = path.join(APP_ROOT, '.env');
const envFile = fs.readFileSync(envPath, 'utf8');
envFile.split('\n').forEach(line => {
const trimmedLine = line.trim();
@@ -24,6 +25,10 @@ try {
console.log('No .env file found or error reading it:', e.message);
}
// Keep the default database in a stable user-level location so rebuilding dist-server
// never changes where the backend stores auth.db when DATABASE_PATH is not set explicitly.
const DEFAULT_DATABASE_PATH = path.join(os.homedir(), '.cloudcli', 'auth.db');
if (!process.env.DATABASE_PATH) {
process.env.DATABASE_PATH = path.join(os.homedir(), '.cloudcli', 'auth.db');
process.env.DATABASE_PATH = DEFAULT_DATABASE_PATH;
}

View File

@@ -15,8 +15,9 @@
import { Codex } from '@openai/codex-sdk';
import { notifyRunFailed, notifyRunStopped } from './services/notification-orchestrator.js';
import { codexAdapter } from './providers/codex/adapter.js';
import { codexAdapter } from './providers/codex/index.js';
import { createNormalizedMessage } from './providers/types.js';
import { getStatusChecker } from './providers/registry.js';
// Track active sessions
const activeCodexSessions = new Map();
@@ -308,7 +309,14 @@ export async function queryCodex(command, options = {}, ws) {
if (!wasAborted) {
console.error('[Codex] Error:', error);
sendMessage(ws, createNormalizedMessage({ kind: 'error', content: error.message, sessionId: currentSessionId, provider: 'codex' }));
// Check if Codex SDK is available for a clearer error message
const installed = getStatusChecker('codex')?.checkInstalled() ?? true;
const errorContent = !installed
? 'Codex CLI is not configured. Please set up authentication first.'
: error.message;
sendMessage(ws, createNormalizedMessage({ kind: 'error', content: errorContent, sessionId: currentSessionId, provider: 'codex' }));
if (!terminalFailure) {
notifyRunFailed({
userId: ws?.userId || null,

View File

@@ -62,8 +62,7 @@ import fsSync from 'fs';
import path from 'path';
import readline from 'readline';
import crypto from 'crypto';
import sqlite3 from 'sqlite3';
import { open } from 'sqlite';
import Database from 'better-sqlite3';
import os from 'os';
import sessionManager from './sessionManager.js';
import { applyCustomSessionNames } from './database/db.js';
@@ -1164,8 +1163,9 @@ async function isProjectEmpty(projectName) {
}
}
// Delete a project (force=true to delete even with sessions)
async function deleteProject(projectName, force = false) {
// Remove a project from the UI.
// When deleteData=true, also delete session/memory files on disk (destructive).
async function deleteProject(projectName, force = false, deleteData = false) {
const projectDir = path.join(os.homedir(), '.claude', 'projects', projectName);
try {
@@ -1175,48 +1175,50 @@ async function deleteProject(projectName, force = false) {
}
const config = await loadProjectConfig();
let projectPath = config[projectName]?.path || config[projectName]?.originalPath;
// Fallback to extractProjectDirectory if projectPath is not in config
if (!projectPath) {
projectPath = await extractProjectDirectory(projectName);
}
// Destructive path: delete underlying data when explicitly requested
if (deleteData) {
let projectPath = config[projectName]?.path || config[projectName]?.originalPath;
if (!projectPath) {
projectPath = await extractProjectDirectory(projectName);
}
// Remove the project directory (includes all Claude sessions)
await fs.rm(projectDir, { recursive: true, force: true });
// Remove the Claude project directory (session logs, memory, subagent data)
await fs.rm(projectDir, { recursive: true, force: true });
// Delete all Codex sessions associated with this project
if (projectPath) {
try {
const codexSessions = await getCodexSessions(projectPath, { limit: 0 });
for (const session of codexSessions) {
try {
await deleteCodexSession(session.id);
} catch (err) {
console.warn(`Failed to delete Codex session ${session.id}:`, err.message);
// Delete Codex sessions associated with this project
if (projectPath) {
try {
const codexSessions = await getCodexSessions(projectPath, { limit: 0 });
for (const session of codexSessions) {
try {
await deleteCodexSession(session.id);
} catch (err) {
console.warn(`Failed to delete Codex session ${session.id}:`, err.message);
}
}
} catch (err) {
console.warn('Failed to delete Codex sessions:', err.message);
}
} catch (err) {
console.warn('Failed to delete Codex sessions:', err.message);
}
// Delete Cursor sessions directory if it exists
try {
const hash = crypto.createHash('md5').update(projectPath).digest('hex');
const cursorProjectDir = path.join(os.homedir(), '.cursor', 'chats', hash);
await fs.rm(cursorProjectDir, { recursive: true, force: true });
} catch (err) {
// Cursor dir may not exist, ignore
// Delete Cursor sessions directory if it exists
try {
const hash = crypto.createHash('md5').update(projectPath).digest('hex');
const cursorProjectDir = path.join(os.homedir(), '.cursor', 'chats', hash);
await fs.rm(cursorProjectDir, { recursive: true, force: true });
} catch (err) {
// Cursor dir may not exist, ignore
}
}
}
// Remove from project config
// Always remove from project config
delete config[projectName];
await saveProjectConfig(config);
return true;
} catch (error) {
console.error(`Error deleting project ${projectName}:`, error);
console.error(`Error removing project ${projectName}:`, error);
throw error;
}
}
@@ -1305,16 +1307,10 @@ async function getCursorSessions(projectPath) {
} catch (_) { }
// Open SQLite database
const db = await open({
filename: storeDbPath,
driver: sqlite3.Database,
mode: sqlite3.OPEN_READONLY
});
const db = new Database(storeDbPath, { readonly: true, fileMustExist: true });
// Get metadata from meta table
const metaRows = await db.all(`
SELECT key, value FROM meta
`);
const metaRows = db.prepare('SELECT key, value FROM meta').all();
// Parse metadata
let metadata = {};
@@ -1336,11 +1332,9 @@ async function getCursorSessions(projectPath) {
}
// Get message count
const messageCountResult = await db.get(`
SELECT COUNT(*) as count FROM blobs
`);
const messageCountResult = db.prepare('SELECT COUNT(*) as count FROM blobs').get();
await db.close();
db.close();
// Extract session info
const sessionName = metadata.title || metadata.sessionTitle || 'Untitled Session';

View File

@@ -5,7 +5,6 @@
* @module adapters/claude
*/
import { getSessionMessages } from '../../projects.js';
import { createNormalizedMessage, generateMessageId } from '../types.js';
import { isInternalContent } from '../utils.js';
@@ -200,79 +199,3 @@ export function normalizeMessage(raw, sessionId) {
return messages;
}
/**
* @type {import('../types.js').ProviderAdapter}
*/
export const claudeAdapter = {
normalizeMessage,
/**
* Fetch session history from JSONL files, returning normalized messages.
*/
async fetchHistory(sessionId, opts = {}) {
const { projectName, limit = null, offset = 0 } = opts;
if (!projectName) {
return { messages: [], total: 0, hasMore: false, offset: 0, limit: null };
}
let result;
try {
result = await getSessionMessages(projectName, sessionId, limit, offset);
} catch (error) {
console.warn(`[ClaudeAdapter] Failed to load session ${sessionId}:`, error.message);
return { messages: [], total: 0, hasMore: false, offset: 0, limit: null };
}
// getSessionMessages returns either an array (no limit) or { messages, total, hasMore }
const rawMessages = Array.isArray(result) ? result : (result.messages || []);
const total = Array.isArray(result) ? rawMessages.length : (result.total || 0);
const hasMore = Array.isArray(result) ? false : Boolean(result.hasMore);
// First pass: collect tool results for attachment to tool_use messages
const toolResultMap = new Map();
for (const raw of rawMessages) {
if (raw.message?.role === 'user' && Array.isArray(raw.message?.content)) {
for (const part of raw.message.content) {
if (part.type === 'tool_result') {
toolResultMap.set(part.tool_use_id, {
content: part.content,
isError: Boolean(part.is_error),
timestamp: raw.timestamp,
subagentTools: raw.subagentTools,
toolUseResult: raw.toolUseResult,
});
}
}
}
}
// Second pass: normalize all messages
const normalized = [];
for (const raw of rawMessages) {
const entries = normalizeMessage(raw, sessionId);
normalized.push(...entries);
}
// Attach tool results to their corresponding tool_use messages
for (const msg of normalized) {
if (msg.kind === 'tool_use' && msg.toolId && toolResultMap.has(msg.toolId)) {
const tr = toolResultMap.get(msg.toolId);
msg.toolResult = {
content: typeof tr.content === 'string' ? tr.content : JSON.stringify(tr.content),
isError: tr.isError,
toolUseResult: tr.toolUseResult,
};
msg.subagentTools = tr.subagentTools;
}
}
return {
messages: normalized,
total,
hasMore,
offset,
limit,
};
},
};

View File

@@ -0,0 +1 @@
// TODO: migrate Claude session list/delete endpoints from server/index.js

View File

@@ -0,0 +1,8 @@
/**
* Claude provider barrel.
* Assembles the ProviderAdapter from adapter + sessions.
*/
import { normalizeMessage } from './adapter.js';
import { fetchHistory } from './sessions.js';
export const claudeAdapter = { normalizeMessage, fetchHistory };

View File

@@ -0,0 +1,82 @@
/**
* Claude provider session history.
*
* Fetches and normalizes persisted JSONL session data.
* @module adapters/claude/sessions
*/
import { normalizeMessage } from './adapter.js';
import { getSessionMessages } from '../../projects.js';
import { createNormalizedMessage } from '../types.js';
/**
* Fetch session history from JSONL files, returning normalized messages.
* @param {string} sessionId
* @param {import('../types.js').FetchHistoryOptions} opts
* @returns {Promise<import('../types.js').FetchHistoryResult>}
*/
export async function fetchHistory(sessionId, opts = {}) {
const { projectName, limit = null, offset = 0 } = opts;
if (!projectName) {
return { messages: [], total: 0, hasMore: false, offset: 0, limit: null };
}
let result;
try {
result = await getSessionMessages(projectName, sessionId, limit, offset);
} catch (error) {
console.warn(`[ClaudeAdapter] Failed to load session ${sessionId}:`, error.message);
return { messages: [], total: 0, hasMore: false, offset: 0, limit: null };
}
// getSessionMessages returns either an array (no limit) or { messages, total, hasMore }
const rawMessages = Array.isArray(result) ? result : (result.messages || []);
const total = Array.isArray(result) ? rawMessages.length : (result.total || 0);
const hasMore = Array.isArray(result) ? false : Boolean(result.hasMore);
// First pass: collect tool results for attachment to tool_use messages
const toolResultMap = new Map();
for (const raw of rawMessages) {
if (raw.message?.role === 'user' && Array.isArray(raw.message?.content)) {
for (const part of raw.message.content) {
if (part.type === 'tool_result') {
toolResultMap.set(part.tool_use_id, {
content: part.content,
isError: Boolean(part.is_error),
timestamp: raw.timestamp,
subagentTools: raw.subagentTools,
toolUseResult: raw.toolUseResult,
});
}
}
}
}
// Second pass: normalize all messages
const normalized = [];
for (const raw of rawMessages) {
const entries = normalizeMessage(raw, sessionId);
normalized.push(...entries);
}
// Attach tool results to their corresponding tool_use messages
for (const msg of normalized) {
if (msg.kind === 'tool_use' && msg.toolId && toolResultMap.has(msg.toolId)) {
const tr = toolResultMap.get(msg.toolId);
msg.toolResult = {
content: typeof tr.content === 'string' ? tr.content : JSON.stringify(tr.content),
isError: tr.isError,
toolUseResult: tr.toolUseResult,
};
msg.subagentTools = tr.subagentTools;
}
}
return {
messages: normalized,
total,
hasMore,
offset,
limit,
};
}

View File

@@ -0,0 +1,136 @@
/**
* Claude Provider Status
*
* Checks whether Claude Code CLI is installed and whether the user
* has valid authentication credentials.
*
* @module providers/claude/status
*/
import { execFileSync } from 'child_process';
import { promises as fs } from 'fs';
import path from 'path';
import os from 'os';
/**
* Check if Claude Code CLI is installed and available.
* Uses CLAUDE_CLI_PATH env var if set, otherwise looks for 'claude' in PATH.
* @returns {boolean}
*/
export function checkInstalled() {
const cliPath = process.env.CLAUDE_CLI_PATH || 'claude';
try {
execFileSync(cliPath, ['--version'], { stdio: 'ignore', timeout: 5000 });
return true;
} catch {
return false;
}
}
/**
* Full status check: installation + authentication.
* @returns {Promise<import('../types.js').ProviderStatus>}
*/
export async function checkStatus() {
const installed = checkInstalled();
if (!installed) {
return {
installed,
authenticated: false,
email: null,
method: null,
error: 'Claude Code CLI is not installed'
};
}
const credentialsResult = await checkCredentials();
if (credentialsResult.authenticated) {
return {
installed,
authenticated: true,
email: credentialsResult.email || 'Authenticated',
method: credentialsResult.method || null,
error: null
};
}
return {
installed,
authenticated: false,
email: credentialsResult.email || null,
method: credentialsResult.method || null,
error: credentialsResult.error || 'Not authenticated'
};
}
// ─── Internal helpers ───────────────────────────────────────────────────────
async function loadSettingsEnv() {
try {
const settingsPath = path.join(os.homedir(), '.claude', 'settings.json');
const content = await fs.readFile(settingsPath, 'utf8');
const settings = JSON.parse(content);
if (settings?.env && typeof settings.env === 'object') {
return settings.env;
}
} catch {
// Ignore missing or malformed settings.
}
return {};
}
/**
* Checks Claude authentication credentials.
*
* Priority 1: ANTHROPIC_API_KEY environment variable
* Priority 1b: ~/.claude/settings.json env values
* Priority 2: ~/.claude/.credentials.json OAuth tokens
*/
async function checkCredentials() {
if (process.env.ANTHROPIC_API_KEY && process.env.ANTHROPIC_API_KEY.trim()) {
return { authenticated: true, email: 'API Key Auth', method: 'api_key' };
}
const settingsEnv = await loadSettingsEnv();
if (typeof settingsEnv.ANTHROPIC_API_KEY === 'string' && settingsEnv.ANTHROPIC_API_KEY.trim()) {
return { authenticated: true, email: 'API Key Auth', method: 'api_key' };
}
if (typeof settingsEnv.ANTHROPIC_AUTH_TOKEN === 'string' && settingsEnv.ANTHROPIC_AUTH_TOKEN.trim()) {
return { authenticated: true, email: 'Configured via settings.json', method: 'api_key' };
}
try {
const credPath = path.join(os.homedir(), '.claude', '.credentials.json');
const content = await fs.readFile(credPath, 'utf8');
const creds = JSON.parse(content);
const oauth = creds.claudeAiOauth;
if (oauth && oauth.accessToken) {
const isExpired = oauth.expiresAt && Date.now() >= oauth.expiresAt;
if (!isExpired) {
return {
authenticated: true,
email: creds.email || creds.user || null,
method: 'credentials_file'
};
}
return {
authenticated: false,
email: creds.email || creds.user || null,
method: 'credentials_file',
error: 'OAuth token has expired. Please re-authenticate with claude login'
};
}
return { authenticated: false, email: null, method: null };
} catch {
return { authenticated: false, email: null, method: null };
}
}

View File

@@ -5,7 +5,6 @@
* @module adapters/codex
*/
import { getCodexSessionMessages } from '../../projects.js';
import { createNormalizedMessage, generateMessageId } from '../types.js';
const PROVIDER = 'codex';
@@ -16,7 +15,7 @@ const PROVIDER = 'codex';
* @param {string} sessionId
* @returns {import('../types.js').NormalizedMessage[]}
*/
function normalizeCodexHistoryEntry(raw, sessionId) {
export function normalizeCodexHistoryEntry(raw, sessionId) {
const ts = raw.timestamp || new Date().toISOString();
const baseId = raw.uuid || generateMessageId('codex');
@@ -191,58 +190,3 @@ export function normalizeMessage(raw, sessionId) {
return [];
}
/**
* @type {import('../types.js').ProviderAdapter}
*/
export const codexAdapter = {
normalizeMessage,
/**
* Fetch session history from Codex JSONL files.
*/
async fetchHistory(sessionId, opts = {}) {
const { limit = null, offset = 0 } = opts;
let result;
try {
result = await getCodexSessionMessages(sessionId, limit, offset);
} catch (error) {
console.warn(`[CodexAdapter] Failed to load session ${sessionId}:`, error.message);
return { messages: [], total: 0, hasMore: false, offset: 0, limit: null };
}
const rawMessages = Array.isArray(result) ? result : (result.messages || []);
const total = Array.isArray(result) ? rawMessages.length : (result.total || 0);
const hasMore = Array.isArray(result) ? false : Boolean(result.hasMore);
const tokenUsage = result.tokenUsage || null;
const normalized = [];
for (const raw of rawMessages) {
const entries = normalizeCodexHistoryEntry(raw, sessionId);
normalized.push(...entries);
}
// Attach tool results to tool_use messages
const toolResultMap = new Map();
for (const msg of normalized) {
if (msg.kind === 'tool_result' && msg.toolId) {
toolResultMap.set(msg.toolId, msg);
}
}
for (const msg of normalized) {
if (msg.kind === 'tool_use' && msg.toolId && toolResultMap.has(msg.toolId)) {
const tr = toolResultMap.get(msg.toolId);
msg.toolResult = { content: tr.content, isError: tr.isError };
}
}
return {
messages: normalized,
total,
hasMore,
offset,
limit,
tokenUsage,
};
},
};

View File

@@ -0,0 +1 @@
// TODO: migrate GET /config from server/routes/codex.js

View File

@@ -0,0 +1,8 @@
/**
* Codex provider barrel.
* Assembles the ProviderAdapter from adapter + sessions.
*/
import { normalizeMessage } from './adapter.js';
import { fetchHistory } from './sessions.js';
export const codexAdapter = { normalizeMessage, fetchHistory };

View File

@@ -0,0 +1 @@
// TODO: migrate MCP CRUD endpoints from server/routes/codex.js

View File

@@ -0,0 +1,63 @@
/**
* Codex session history fetcher.
*
* Extracted from adapter.js — pure data-access concern.
* @module providers/codex/sessions
*/
import { normalizeCodexHistoryEntry } from './adapter.js';
import { getCodexSessionMessages } from '../../projects.js';
/**
* Fetch session history from Codex JSONL files.
* @param {string} sessionId
* @param {object} opts
* @param {number|null} [opts.limit]
* @param {number} [opts.offset]
* @returns {Promise<{messages: import('../../providers/types.js').NormalizedMessage[], total: number, hasMore: boolean, offset: number, limit: number|null, tokenUsage: object|null}>}
*/
export async function fetchHistory(sessionId, opts = {}) {
const { limit = null, offset = 0 } = opts;
let result;
try {
result = await getCodexSessionMessages(sessionId, limit, offset);
} catch (error) {
console.warn(`[CodexAdapter] Failed to load session ${sessionId}:`, error.message);
return { messages: [], total: 0, hasMore: false, offset: 0, limit: null };
}
const rawMessages = Array.isArray(result) ? result : (result.messages || []);
const total = Array.isArray(result) ? rawMessages.length : (result.total || 0);
const hasMore = Array.isArray(result) ? false : Boolean(result.hasMore);
const tokenUsage = result.tokenUsage || null;
const normalized = [];
for (const raw of rawMessages) {
const entries = normalizeCodexHistoryEntry(raw, sessionId);
normalized.push(...entries);
}
// Attach tool results to tool_use messages
const toolResultMap = new Map();
for (const msg of normalized) {
if (msg.kind === 'tool_result' && msg.toolId) {
toolResultMap.set(msg.toolId, msg);
}
}
for (const msg of normalized) {
if (msg.kind === 'tool_use' && msg.toolId && toolResultMap.has(msg.toolId)) {
const tr = toolResultMap.get(msg.toolId);
msg.toolResult = { content: tr.content, isError: tr.isError };
}
}
return {
messages: normalized,
total,
hasMore,
offset,
limit,
tokenUsage,
};
}

View File

@@ -0,0 +1,78 @@
/**
* Codex Provider Status
*
* Checks whether the user has valid Codex authentication credentials.
* Codex uses an SDK that makes direct API calls (no external binary),
* so installation check always returns true if the server is running.
*
* @module providers/codex/status
*/
import { promises as fs } from 'fs';
import path from 'path';
import os from 'os';
/**
* Check if Codex is installed.
* Codex SDK is bundled with this application — no external binary needed.
* @returns {boolean}
*/
export function checkInstalled() {
return true;
}
/**
* Full status check: installation + authentication.
* @returns {Promise<import('../types.js').ProviderStatus>}
*/
export async function checkStatus() {
const installed = checkInstalled();
const result = await checkCredentials();
return {
installed,
authenticated: result.authenticated,
email: result.email || null,
error: result.error || null
};
}
// ─── Internal helpers ───────────────────────────────────────────────────────
async function checkCredentials() {
try {
const authPath = path.join(os.homedir(), '.codex', 'auth.json');
const content = await fs.readFile(authPath, 'utf8');
const auth = JSON.parse(content);
const tokens = auth.tokens || {};
if (tokens.id_token || tokens.access_token) {
let email = 'Authenticated';
if (tokens.id_token) {
try {
const parts = tokens.id_token.split('.');
if (parts.length >= 2) {
const payload = JSON.parse(Buffer.from(parts[1], 'base64url').toString('utf8'));
email = payload.email || payload.user || 'Authenticated';
}
} catch {
email = 'Authenticated';
}
}
return { authenticated: true, email };
}
if (auth.OPENAI_API_KEY) {
return { authenticated: true, email: 'API Key Auth' };
}
return { authenticated: false, email: null, error: 'No valid tokens found' };
} catch (error) {
if (error.code === 'ENOENT') {
return { authenticated: false, email: null, error: 'Codex not configured' };
}
return { authenticated: false, email: null, error: error.message };
}
}

View File

@@ -1,18 +1,18 @@
/**
* Cursor provider adapter.
*
* Normalizes Cursor CLI session history into NormalizedMessage format.
* Normalizes Cursor CLI realtime NDJSON events into NormalizedMessage format.
* History loading lives in ./sessions.js.
* @module adapters/cursor
*/
import path from 'path';
import os from 'os';
import crypto from 'crypto';
import { createNormalizedMessage, generateMessageId } from '../types.js';
import { createNormalizedMessage } from '../types.js';
const PROVIDER = 'cursor';
/**
<<<<<<< HEAD
=======
* Load raw blobs from Cursor's SQLite store.db, parse the DAG structure,
* and return sorted message blobs in chronological order.
* @param {string} sessionId
@@ -20,21 +20,16 @@ const PROVIDER = 'cursor';
* @returns {Promise<Array<{id: string, sequence: number, rowid: number, content: object}>>}
*/
async function loadCursorBlobs(sessionId, projectPath) {
// Lazy-import sqlite so the module doesn't fail if sqlite3 is unavailable
const { default: sqlite3 } = await import('sqlite3');
const { open } = await import('sqlite');
// Lazy-import better-sqlite3 so the module doesn't fail if it's unavailable
const { default: Database } = await import('better-sqlite3');
const cwdId = crypto.createHash('md5').update(projectPath || process.cwd()).digest('hex');
const storeDbPath = path.join(os.homedir(), '.cursor', 'chats', cwdId, sessionId, 'store.db');
const db = await open({
filename: storeDbPath,
driver: sqlite3.Database,
mode: sqlite3.OPEN_READONLY,
});
const db = new Database(storeDbPath, { readonly: true, fileMustExist: true });
try {
const allBlobs = await db.all('SELECT rowid, id, data FROM blobs');
const allBlobs = db.prepare('SELECT rowid, id, data FROM blobs').all();
const blobMap = new Map();
const parentRefs = new Map();
@@ -129,11 +124,12 @@ async function loadCursorBlobs(sessionId, projectPath) {
return messages;
} finally {
await db.close();
db.close();
}
}
/**
>>>>>>> refactor/split-server-index
* Normalize a realtime NDJSON event from Cursor CLI into NormalizedMessage(s).
* History uses normalizeCursorBlobs (SQLite DAG), this handles streaming NDJSON.
* @param {object|string} raw - A parsed NDJSON event or a raw text line
@@ -151,203 +147,3 @@ export function normalizeMessage(raw, sessionId) {
}
return [];
}
/**
* @type {import('../types.js').ProviderAdapter}
*/
export const cursorAdapter = {
normalizeMessage,
/**
* Fetch session history for Cursor from SQLite store.db.
*/
async fetchHistory(sessionId, opts = {}) {
const { projectPath = '', limit = null, offset = 0 } = opts;
try {
const blobs = await loadCursorBlobs(sessionId, projectPath);
const allNormalized = cursorAdapter.normalizeCursorBlobs(blobs, sessionId);
// Apply pagination
if (limit !== null && limit > 0) {
const start = offset;
const page = allNormalized.slice(start, start + limit);
return {
messages: page,
total: allNormalized.length,
hasMore: start + limit < allNormalized.length,
offset,
limit,
};
}
return {
messages: allNormalized,
total: allNormalized.length,
hasMore: false,
offset: 0,
limit: null,
};
} catch (error) {
// DB doesn't exist or is unreadable — return empty
console.warn(`[CursorAdapter] Failed to load session ${sessionId}:`, error.message);
return { messages: [], total: 0, hasMore: false, offset: 0, limit: null };
}
},
/**
* Normalize raw Cursor blob messages into NormalizedMessage[].
* @param {any[]} blobs - Raw cursor blobs from store.db ({id, sequence, rowid, content})
* @param {string} sessionId
* @returns {import('../types.js').NormalizedMessage[]}
*/
normalizeCursorBlobs(blobs, sessionId) {
const messages = [];
const toolUseMap = new Map();
// Use a fixed base timestamp so messages have stable, monotonically-increasing
// timestamps based on their sequence number rather than wall-clock time.
const baseTime = Date.now();
for (let i = 0; i < blobs.length; i++) {
const blob = blobs[i];
const content = blob.content;
const ts = new Date(baseTime + (blob.sequence ?? i) * 100).toISOString();
const baseId = blob.id || generateMessageId('cursor');
try {
if (!content?.role || !content?.content) {
// Try nested message format
if (content?.message?.role && content?.message?.content) {
if (content.message.role === 'system') continue;
const role = content.message.role === 'user' ? 'user' : 'assistant';
let text = '';
if (Array.isArray(content.message.content)) {
text = content.message.content
.map(p => typeof p === 'string' ? p : p?.text || '')
.filter(Boolean)
.join('\n');
} else if (typeof content.message.content === 'string') {
text = content.message.content;
}
if (text?.trim()) {
messages.push(createNormalizedMessage({
id: baseId,
sessionId,
timestamp: ts,
provider: PROVIDER,
kind: 'text',
role,
content: text,
sequence: blob.sequence,
rowid: blob.rowid,
}));
}
}
continue;
}
if (content.role === 'system') continue;
// Tool results
if (content.role === 'tool') {
const toolItems = Array.isArray(content.content) ? content.content : [];
for (const item of toolItems) {
if (item?.type !== 'tool-result') continue;
const toolCallId = item.toolCallId || content.id;
messages.push(createNormalizedMessage({
id: `${baseId}_tr`,
sessionId,
timestamp: ts,
provider: PROVIDER,
kind: 'tool_result',
toolId: toolCallId,
content: item.result || '',
isError: false,
}));
}
continue;
}
const role = content.role === 'user' ? 'user' : 'assistant';
if (Array.isArray(content.content)) {
for (let partIdx = 0; partIdx < content.content.length; partIdx++) {
const part = content.content[partIdx];
if (part?.type === 'text' && part?.text) {
messages.push(createNormalizedMessage({
id: `${baseId}_${partIdx}`,
sessionId,
timestamp: ts,
provider: PROVIDER,
kind: 'text',
role,
content: part.text,
sequence: blob.sequence,
rowid: blob.rowid,
}));
} else if (part?.type === 'reasoning' && part?.text) {
messages.push(createNormalizedMessage({
id: `${baseId}_${partIdx}`,
sessionId,
timestamp: ts,
provider: PROVIDER,
kind: 'thinking',
content: part.text,
}));
} else if (part?.type === 'tool-call' || part?.type === 'tool_use') {
const toolName = (part.toolName || part.name || 'Unknown Tool') === 'ApplyPatch'
? 'Edit' : (part.toolName || part.name || 'Unknown Tool');
const toolId = part.toolCallId || part.id || `tool_${i}_${partIdx}`;
messages.push(createNormalizedMessage({
id: `${baseId}_${partIdx}`,
sessionId,
timestamp: ts,
provider: PROVIDER,
kind: 'tool_use',
toolName,
toolInput: part.args || part.input,
toolId,
}));
toolUseMap.set(toolId, messages[messages.length - 1]);
}
}
} else if (typeof content.content === 'string' && content.content.trim()) {
messages.push(createNormalizedMessage({
id: baseId,
sessionId,
timestamp: ts,
provider: PROVIDER,
kind: 'text',
role,
content: content.content,
sequence: blob.sequence,
rowid: blob.rowid,
}));
}
} catch (error) {
console.warn('Error normalizing cursor blob:', error);
}
}
// Attach tool results to tool_use messages
for (const msg of messages) {
if (msg.kind === 'tool_result' && msg.toolId && toolUseMap.has(msg.toolId)) {
const toolUse = toolUseMap.get(msg.toolId);
toolUse.toolResult = {
content: msg.content,
isError: msg.isError,
};
}
}
// Sort by sequence/rowid
messages.sort((a, b) => {
if (a.sequence !== undefined && b.sequence !== undefined) return a.sequence - b.sequence;
if (a.rowid !== undefined && b.rowid !== undefined) return a.rowid - b.rowid;
return new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime();
});
return messages;
},
};

View File

@@ -0,0 +1 @@
// TODO: migrate GET/POST /config from server/routes/cursor.js

View File

@@ -0,0 +1,8 @@
/**
* Cursor provider barrel.
* Assembles the ProviderAdapter from adapter + sessions.
*/
import { normalizeMessage } from './adapter.js';
import { fetchHistory, normalizeCursorBlobs } from './sessions.js';
export const cursorAdapter = { normalizeMessage, fetchHistory, normalizeCursorBlobs };

View File

@@ -0,0 +1 @@
// TODO: migrate MCP CRUD endpoints from server/routes/cursor.js

View File

@@ -0,0 +1,330 @@
/**
* Cursor provider session history.
*
* Reads Cursor's SQLite store.db, walks the DAG, and returns
* NormalizedMessage[] for a given session.
* @module providers/cursor/sessions
*/
import path from 'path';
import os from 'os';
import crypto from 'crypto';
import { createNormalizedMessage, generateMessageId } from '../types.js';
const PROVIDER = 'cursor';
/**
* Load raw blobs from Cursor's SQLite store.db, parse the DAG structure,
* and return sorted message blobs in chronological order.
* @param {string} sessionId
* @param {string} projectPath - Absolute project path (used to compute cwdId hash)
* @returns {Promise<Array<{id: string, sequence: number, rowid: number, content: object}>>}
*/
async function loadCursorBlobs(sessionId, projectPath) {
// Lazy-import better-sqlite3 so the module doesn't fail if it's unavailable
const { default: Database } = await import('better-sqlite3');
const cwdId = crypto.createHash('md5').update(projectPath || process.cwd()).digest('hex');
const storeDbPath = path.join(os.homedir(), '.cursor', 'chats', cwdId, sessionId, 'store.db');
const db = new Database(storeDbPath, { readonly: true, fileMustExist: true });
try {
const allBlobs = db.prepare('SELECT rowid, id, data FROM blobs').all();
const blobMap = new Map();
const parentRefs = new Map();
const childRefs = new Map();
const jsonBlobs = [];
for (const blob of allBlobs) {
blobMap.set(blob.id, blob);
if (blob.data && blob.data[0] === 0x7B) {
try {
const parsed = JSON.parse(blob.data.toString('utf8'));
jsonBlobs.push({ ...blob, parsed });
} catch {
// skip unparseable blobs
}
} else if (blob.data) {
const parents = [];
let i = 0;
while (i < blob.data.length - 33) {
if (blob.data[i] === 0x0A && blob.data[i + 1] === 0x20) {
const parentHash = blob.data.slice(i + 2, i + 34).toString('hex');
if (blobMap.has(parentHash)) {
parents.push(parentHash);
}
i += 34;
} else {
i++;
}
}
if (parents.length > 0) {
parentRefs.set(blob.id, parents);
for (const parentId of parents) {
if (!childRefs.has(parentId)) childRefs.set(parentId, []);
childRefs.get(parentId).push(blob.id);
}
}
}
}
// Topological sort (DFS)
const visited = new Set();
const sorted = [];
function visit(nodeId) {
if (visited.has(nodeId)) return;
visited.add(nodeId);
for (const pid of (parentRefs.get(nodeId) || [])) visit(pid);
const b = blobMap.get(nodeId);
if (b) sorted.push(b);
}
for (const blob of allBlobs) {
if (!parentRefs.has(blob.id)) visit(blob.id);
}
for (const blob of allBlobs) visit(blob.id);
// Order JSON blobs by DAG appearance
const messageOrder = new Map();
let orderIndex = 0;
for (const blob of sorted) {
if (blob.data && blob.data[0] !== 0x7B) {
for (const jb of jsonBlobs) {
try {
const idBytes = Buffer.from(jb.id, 'hex');
if (blob.data.includes(idBytes) && !messageOrder.has(jb.id)) {
messageOrder.set(jb.id, orderIndex++);
}
} catch { /* skip */ }
}
}
}
const sortedJsonBlobs = jsonBlobs.sort((a, b) => {
const oa = messageOrder.get(a.id) ?? Number.MAX_SAFE_INTEGER;
const ob = messageOrder.get(b.id) ?? Number.MAX_SAFE_INTEGER;
return oa !== ob ? oa - ob : a.rowid - b.rowid;
});
const messages = [];
for (let idx = 0; idx < sortedJsonBlobs.length; idx++) {
const blob = sortedJsonBlobs[idx];
const parsed = blob.parsed;
if (!parsed) continue;
const role = parsed?.role || parsed?.message?.role;
if (role === 'system') continue;
messages.push({
id: blob.id,
sequence: idx + 1,
rowid: blob.rowid,
content: parsed,
});
}
return messages;
} finally {
db.close();
}
}
/**
* Normalize raw Cursor blob messages into NormalizedMessage[].
* @param {any[]} blobs - Raw cursor blobs from store.db ({id, sequence, rowid, content})
* @param {string} sessionId
* @returns {import('../types.js').NormalizedMessage[]}
*/
export function normalizeCursorBlobs(blobs, sessionId) {
const messages = [];
const toolUseMap = new Map();
// Use a fixed base timestamp so messages have stable, monotonically-increasing
// timestamps based on their sequence number rather than wall-clock time.
const baseTime = Date.now();
for (let i = 0; i < blobs.length; i++) {
const blob = blobs[i];
const content = blob.content;
const ts = new Date(baseTime + (blob.sequence ?? i) * 100).toISOString();
const baseId = blob.id || generateMessageId('cursor');
try {
if (!content?.role || !content?.content) {
// Try nested message format
if (content?.message?.role && content?.message?.content) {
if (content.message.role === 'system') continue;
const role = content.message.role === 'user' ? 'user' : 'assistant';
let text = '';
if (Array.isArray(content.message.content)) {
text = content.message.content
.map(p => typeof p === 'string' ? p : p?.text || '')
.filter(Boolean)
.join('\n');
} else if (typeof content.message.content === 'string') {
text = content.message.content;
}
if (text?.trim()) {
messages.push(createNormalizedMessage({
id: baseId,
sessionId,
timestamp: ts,
provider: PROVIDER,
kind: 'text',
role,
content: text,
sequence: blob.sequence,
rowid: blob.rowid,
}));
}
}
continue;
}
if (content.role === 'system') continue;
// Tool results
if (content.role === 'tool') {
const toolItems = Array.isArray(content.content) ? content.content : [];
for (const item of toolItems) {
if (item?.type !== 'tool-result') continue;
const toolCallId = item.toolCallId || content.id;
messages.push(createNormalizedMessage({
id: `${baseId}_tr`,
sessionId,
timestamp: ts,
provider: PROVIDER,
kind: 'tool_result',
toolId: toolCallId,
content: item.result || '',
isError: false,
}));
}
continue;
}
const role = content.role === 'user' ? 'user' : 'assistant';
if (Array.isArray(content.content)) {
for (let partIdx = 0; partIdx < content.content.length; partIdx++) {
const part = content.content[partIdx];
if (part?.type === 'text' && part?.text) {
messages.push(createNormalizedMessage({
id: `${baseId}_${partIdx}`,
sessionId,
timestamp: ts,
provider: PROVIDER,
kind: 'text',
role,
content: part.text,
sequence: blob.sequence,
rowid: blob.rowid,
}));
} else if (part?.type === 'reasoning' && part?.text) {
messages.push(createNormalizedMessage({
id: `${baseId}_${partIdx}`,
sessionId,
timestamp: ts,
provider: PROVIDER,
kind: 'thinking',
content: part.text,
}));
} else if (part?.type === 'tool-call' || part?.type === 'tool_use') {
const toolName = (part.toolName || part.name || 'Unknown Tool') === 'ApplyPatch'
? 'Edit' : (part.toolName || part.name || 'Unknown Tool');
const toolId = part.toolCallId || part.id || `tool_${i}_${partIdx}`;
messages.push(createNormalizedMessage({
id: `${baseId}_${partIdx}`,
sessionId,
timestamp: ts,
provider: PROVIDER,
kind: 'tool_use',
toolName,
toolInput: part.args || part.input,
toolId,
}));
toolUseMap.set(toolId, messages[messages.length - 1]);
}
}
} else if (typeof content.content === 'string' && content.content.trim()) {
messages.push(createNormalizedMessage({
id: baseId,
sessionId,
timestamp: ts,
provider: PROVIDER,
kind: 'text',
role,
content: content.content,
sequence: blob.sequence,
rowid: blob.rowid,
}));
}
} catch (error) {
console.warn('Error normalizing cursor blob:', error);
}
}
// Attach tool results to tool_use messages
for (const msg of messages) {
if (msg.kind === 'tool_result' && msg.toolId && toolUseMap.has(msg.toolId)) {
const toolUse = toolUseMap.get(msg.toolId);
toolUse.toolResult = {
content: msg.content,
isError: msg.isError,
};
}
}
// Sort by sequence/rowid
messages.sort((a, b) => {
if (a.sequence !== undefined && b.sequence !== undefined) return a.sequence - b.sequence;
if (a.rowid !== undefined && b.rowid !== undefined) return a.rowid - b.rowid;
return new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime();
});
return messages;
}
/**
* Fetch session history for Cursor from SQLite store.db.
* @param {string} sessionId
* @param {object} opts
* @param {string} [opts.projectPath='']
* @param {number|null} [opts.limit=null]
* @param {number} [opts.offset=0]
* @returns {Promise<{messages: import('../types.js').NormalizedMessage[], total: number, hasMore: boolean, offset: number, limit: number|null}>}
*/
export async function fetchHistory(sessionId, opts = {}) {
const { projectPath = '', limit = null, offset = 0 } = opts;
try {
const blobs = await loadCursorBlobs(sessionId, projectPath);
const allNormalized = normalizeCursorBlobs(blobs, sessionId);
// Apply pagination
if (limit !== null && limit > 0) {
const start = offset;
const page = allNormalized.slice(start, start + limit);
return {
messages: page,
total: allNormalized.length,
hasMore: start + limit < allNormalized.length,
offset,
limit,
};
}
return {
messages: allNormalized,
total: allNormalized.length,
hasMore: false,
offset: 0,
limit: null,
};
} catch (error) {
// DB doesn't exist or is unreadable — return empty
console.warn(`[CursorAdapter] Failed to load session ${sessionId}:`, error.message);
return { messages: [], total: 0, hasMore: false, offset: 0, limit: null };
}
}

View File

@@ -0,0 +1,128 @@
/**
* Cursor Provider Status
*
* Checks whether cursor-agent CLI is installed and whether the user
* is logged in.
*
* @module providers/cursor/status
*/
import { execFileSync, spawn } from 'child_process';
/**
* Check if cursor-agent CLI is installed.
* @returns {boolean}
*/
export function checkInstalled() {
try {
execFileSync('cursor-agent', ['--version'], { stdio: 'ignore', timeout: 5000 });
return true;
} catch {
return false;
}
}
/**
* Full status check: installation + authentication.
* @returns {Promise<import('../types.js').ProviderStatus>}
*/
export async function checkStatus() {
const installed = checkInstalled();
if (!installed) {
return {
installed,
authenticated: false,
email: null,
error: 'Cursor CLI is not installed'
};
}
const result = await checkCursorLogin();
return {
installed,
authenticated: result.authenticated,
email: result.email || null,
error: result.error || null
};
}
// ─── Internal helpers ───────────────────────────────────────────────────────
function checkCursorLogin() {
return new Promise((resolve) => {
let processCompleted = false;
const timeout = setTimeout(() => {
if (!processCompleted) {
processCompleted = true;
if (childProcess) {
childProcess.kill();
}
resolve({
authenticated: false,
email: null,
error: 'Command timeout'
});
}
}, 5000);
let childProcess;
try {
childProcess = spawn('cursor-agent', ['status']);
} catch {
clearTimeout(timeout);
processCompleted = true;
resolve({
authenticated: false,
email: null,
error: 'Cursor CLI not found or not installed'
});
return;
}
let stdout = '';
let stderr = '';
childProcess.stdout.on('data', (data) => {
stdout += data.toString();
});
childProcess.stderr.on('data', (data) => {
stderr += data.toString();
});
childProcess.on('close', (code) => {
if (processCompleted) return;
processCompleted = true;
clearTimeout(timeout);
if (code === 0) {
const emailMatch = stdout.match(/Logged in as ([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})/i);
if (emailMatch) {
resolve({ authenticated: true, email: emailMatch[1] });
} else if (stdout.includes('Logged in')) {
resolve({ authenticated: true, email: 'Logged in' });
} else {
resolve({ authenticated: false, email: null, error: 'Not logged in' });
}
} else {
resolve({ authenticated: false, email: null, error: stderr || 'Not logged in' });
}
});
childProcess.on('error', () => {
if (processCompleted) return;
processCompleted = true;
clearTimeout(timeout);
resolve({
authenticated: false,
email: null,
error: 'Cursor CLI not found or not installed'
});
});
});
}

View File

@@ -5,8 +5,6 @@
* @module adapters/gemini
*/
import sessionManager from '../../sessionManager.js';
import { getGeminiCliSessionMessages } from '../../projects.js';
import { createNormalizedMessage, generateMessageId } from '../types.js';
const PROVIDER = 'gemini';
@@ -72,115 +70,3 @@ export function normalizeMessage(raw, sessionId) {
return [];
}
/**
* @type {import('../types.js').ProviderAdapter}
*/
export const geminiAdapter = {
normalizeMessage,
/**
* Fetch session history for Gemini.
* First tries in-memory session manager, then falls back to CLI sessions on disk.
*/
async fetchHistory(sessionId, opts = {}) {
let rawMessages;
try {
rawMessages = sessionManager.getSessionMessages(sessionId);
// Fallback to Gemini CLI sessions on disk
if (rawMessages.length === 0) {
rawMessages = await getGeminiCliSessionMessages(sessionId);
}
} catch (error) {
console.warn(`[GeminiAdapter] Failed to load session ${sessionId}:`, error.message);
return { messages: [], total: 0, hasMore: false, offset: 0, limit: null };
}
const normalized = [];
for (let i = 0; i < rawMessages.length; i++) {
const raw = rawMessages[i];
const ts = raw.timestamp || new Date().toISOString();
const baseId = raw.uuid || generateMessageId('gemini');
// sessionManager format: { type: 'message', message: { role, content }, timestamp }
// CLI format: { role: 'user'|'gemini'|'assistant', content: string|array }
const role = raw.message?.role || raw.role;
const content = raw.message?.content || raw.content;
if (!role || !content) continue;
const normalizedRole = (role === 'user') ? 'user' : 'assistant';
if (Array.isArray(content)) {
for (let partIdx = 0; partIdx < content.length; partIdx++) {
const part = content[partIdx];
if (part.type === 'text' && part.text) {
normalized.push(createNormalizedMessage({
id: `${baseId}_${partIdx}`,
sessionId,
timestamp: ts,
provider: PROVIDER,
kind: 'text',
role: normalizedRole,
content: part.text,
}));
} else if (part.type === 'tool_use') {
normalized.push(createNormalizedMessage({
id: `${baseId}_${partIdx}`,
sessionId,
timestamp: ts,
provider: PROVIDER,
kind: 'tool_use',
toolName: part.name,
toolInput: part.input,
toolId: part.id || generateMessageId('gemini_tool'),
}));
} else if (part.type === 'tool_result') {
normalized.push(createNormalizedMessage({
id: `${baseId}_${partIdx}`,
sessionId,
timestamp: ts,
provider: PROVIDER,
kind: 'tool_result',
toolId: part.tool_use_id || '',
content: part.content === undefined ? '' : String(part.content),
isError: Boolean(part.is_error),
}));
}
}
} else if (typeof content === 'string' && content.trim()) {
normalized.push(createNormalizedMessage({
id: baseId,
sessionId,
timestamp: ts,
provider: PROVIDER,
kind: 'text',
role: normalizedRole,
content,
}));
}
}
// Attach tool results to tool_use messages
const toolResultMap = new Map();
for (const msg of normalized) {
if (msg.kind === 'tool_result' && msg.toolId) {
toolResultMap.set(msg.toolId, msg);
}
}
for (const msg of normalized) {
if (msg.kind === 'tool_use' && msg.toolId && toolResultMap.has(msg.toolId)) {
const tr = toolResultMap.get(msg.toolId);
msg.toolResult = { content: tr.content, isError: tr.isError };
}
}
return {
messages: normalized,
total: normalized.length,
hasMore: false,
offset: 0,
limit: null,
};
},
};

View File

@@ -0,0 +1,8 @@
/**
* Gemini provider barrel.
* Assembles the ProviderAdapter from adapter + sessions.
*/
import { normalizeMessage } from './adapter.js';
import { fetchHistory } from './sessions.js';
export const geminiAdapter = { normalizeMessage, fetchHistory };

View File

@@ -0,0 +1,121 @@
/**
* Gemini session history fetcher.
*
* Extracted from adapter.js — pure data-access concern.
* @module providers/gemini/sessions
*/
import sessionManager from '../../sessionManager.js';
import { getGeminiCliSessionMessages } from '../../projects.js';
import { createNormalizedMessage, generateMessageId } from '../types.js';
const PROVIDER = 'gemini';
/**
* Fetch session history for Gemini.
* First tries in-memory session manager, then falls back to CLI sessions on disk.
* @param {string} sessionId
* @param {object} opts
* @returns {Promise<{messages: import('../types.js').NormalizedMessage[], total: number, hasMore: boolean, offset: number, limit: number|null}>}
*/
export async function fetchHistory(sessionId, opts = {}) {
let rawMessages;
try {
rawMessages = sessionManager.getSessionMessages(sessionId);
// Fallback to Gemini CLI sessions on disk
if (rawMessages.length === 0) {
rawMessages = await getGeminiCliSessionMessages(sessionId);
}
} catch (error) {
console.warn(`[GeminiAdapter] Failed to load session ${sessionId}:`, error.message);
return { messages: [], total: 0, hasMore: false, offset: 0, limit: null };
}
const normalized = [];
for (let i = 0; i < rawMessages.length; i++) {
const raw = rawMessages[i];
const ts = raw.timestamp || new Date().toISOString();
const baseId = raw.uuid || generateMessageId('gemini');
// sessionManager format: { type: 'message', message: { role, content }, timestamp }
// CLI format: { role: 'user'|'gemini'|'assistant', content: string|array }
const role = raw.message?.role || raw.role;
const content = raw.message?.content || raw.content;
if (!role || !content) continue;
const normalizedRole = (role === 'user') ? 'user' : 'assistant';
if (Array.isArray(content)) {
for (let partIdx = 0; partIdx < content.length; partIdx++) {
const part = content[partIdx];
if (part.type === 'text' && part.text) {
normalized.push(createNormalizedMessage({
id: `${baseId}_${partIdx}`,
sessionId,
timestamp: ts,
provider: PROVIDER,
kind: 'text',
role: normalizedRole,
content: part.text,
}));
} else if (part.type === 'tool_use') {
normalized.push(createNormalizedMessage({
id: `${baseId}_${partIdx}`,
sessionId,
timestamp: ts,
provider: PROVIDER,
kind: 'tool_use',
toolName: part.name,
toolInput: part.input,
toolId: part.id || generateMessageId('gemini_tool'),
}));
} else if (part.type === 'tool_result') {
normalized.push(createNormalizedMessage({
id: `${baseId}_${partIdx}`,
sessionId,
timestamp: ts,
provider: PROVIDER,
kind: 'tool_result',
toolId: part.tool_use_id || '',
content: part.content === undefined ? '' : String(part.content),
isError: Boolean(part.is_error),
}));
}
}
} else if (typeof content === 'string' && content.trim()) {
normalized.push(createNormalizedMessage({
id: baseId,
sessionId,
timestamp: ts,
provider: PROVIDER,
kind: 'text',
role: normalizedRole,
content,
}));
}
}
// Attach tool results to tool_use messages
const toolResultMap = new Map();
for (const msg of normalized) {
if (msg.kind === 'tool_result' && msg.toolId) {
toolResultMap.set(msg.toolId, msg);
}
}
for (const msg of normalized) {
if (msg.kind === 'tool_use' && msg.toolId && toolResultMap.has(msg.toolId)) {
const tr = toolResultMap.get(msg.toolId);
msg.toolResult = { content: tr.content, isError: tr.isError };
}
}
return {
messages: normalized,
total: normalized.length,
hasMore: false,
offset: 0,
limit: null,
};
}

View File

@@ -0,0 +1,111 @@
/**
* Gemini Provider Status
*
* Checks whether Gemini CLI is installed and whether the user
* has valid authentication credentials.
*
* @module providers/gemini/status
*/
import { execFileSync } from 'child_process';
import { promises as fs } from 'fs';
import path from 'path';
import os from 'os';
/**
* Check if Gemini CLI is installed.
* Uses GEMINI_PATH env var if set, otherwise looks for 'gemini' in PATH.
* @returns {boolean}
*/
export function checkInstalled() {
const cliPath = process.env.GEMINI_PATH || 'gemini';
try {
execFileSync(cliPath, ['--version'], { stdio: 'ignore', timeout: 5000 });
return true;
} catch {
return false;
}
}
/**
* Full status check: installation + authentication.
* @returns {Promise<import('../types.js').ProviderStatus>}
*/
export async function checkStatus() {
const installed = checkInstalled();
if (!installed) {
return {
installed,
authenticated: false,
email: null,
error: 'Gemini CLI is not installed'
};
}
const result = await checkCredentials();
return {
installed,
authenticated: result.authenticated,
email: result.email || null,
error: result.error || null
};
}
// ─── Internal helpers ───────────────────────────────────────────────────────
async function checkCredentials() {
if (process.env.GEMINI_API_KEY && process.env.GEMINI_API_KEY.trim()) {
return { authenticated: true, email: 'API Key Auth' };
}
try {
const credsPath = path.join(os.homedir(), '.gemini', 'oauth_creds.json');
const content = await fs.readFile(credsPath, 'utf8');
const creds = JSON.parse(content);
if (creds.access_token) {
let email = 'OAuth Session';
try {
const tokenRes = await fetch(`https://oauth2.googleapis.com/tokeninfo?access_token=${creds.access_token}`);
if (tokenRes.ok) {
const tokenInfo = await tokenRes.json();
if (tokenInfo.email) {
email = tokenInfo.email;
}
} else if (!creds.refresh_token) {
return {
authenticated: false,
email: null,
error: 'Access token invalid and no refresh token found'
};
} else {
// Token might be expired but we have a refresh token, so CLI will refresh it
email = await getActiveAccountEmail() || email;
}
} catch {
// Network error, fallback to checking local accounts file
email = await getActiveAccountEmail() || email;
}
return { authenticated: true, email };
}
return { authenticated: false, email: null, error: 'No valid tokens found in oauth_creds' };
} catch {
return { authenticated: false, email: null, error: 'Gemini CLI not configured' };
}
}
async function getActiveAccountEmail() {
try {
const accPath = path.join(os.homedir(), '.gemini', 'google_accounts.json');
const accContent = await fs.readFile(accPath, 'utf8');
const accounts = JSON.parse(accContent);
return accounts.active || null;
} catch {
return null;
}
}

View File

@@ -1,16 +1,22 @@
/**
* Provider Registry
*
* Centralizes provider adapter lookup. All code that needs a provider adapter
* should go through this registry instead of importing individual adapters directly.
* Centralizes provider adapter and status checker lookup. All code that needs
* a provider adapter or status checker should go through this registry instead
* of importing individual modules directly.
*
* @module providers/registry
*/
import { claudeAdapter } from './claude/adapter.js';
import { cursorAdapter } from './cursor/adapter.js';
import { codexAdapter } from './codex/adapter.js';
import { geminiAdapter } from './gemini/adapter.js';
import { claudeAdapter } from './claude/index.js';
import { cursorAdapter } from './cursor/index.js';
import { codexAdapter } from './codex/index.js';
import { geminiAdapter } from './gemini/index.js';
import * as claudeStatus from './claude/status.js';
import * as cursorStatus from './cursor/status.js';
import * as codexStatus from './codex/status.js';
import * as geminiStatus from './gemini/status.js';
/**
* @typedef {import('./types.js').ProviderAdapter} ProviderAdapter
@@ -20,12 +26,20 @@ import { geminiAdapter } from './gemini/adapter.js';
/** @type {Map<string, ProviderAdapter>} */
const providers = new Map();
/** @type {Map<string, { checkInstalled: () => boolean, checkStatus: () => Promise<import('./types.js').ProviderStatus> }>} */
const statusCheckers = new Map();
// Register built-in providers
providers.set('claude', claudeAdapter);
providers.set('cursor', cursorAdapter);
providers.set('codex', codexAdapter);
providers.set('gemini', geminiAdapter);
statusCheckers.set('claude', claudeStatus);
statusCheckers.set('cursor', cursorStatus);
statusCheckers.set('codex', codexStatus);
statusCheckers.set('gemini', geminiStatus);
/**
* Get a provider adapter by name.
* @param {string} name - Provider name (e.g., 'claude', 'cursor', 'codex', 'gemini')
@@ -35,6 +49,15 @@ export function getProvider(name) {
return providers.get(name);
}
/**
* Get a provider status checker by name.
* @param {string} name - Provider name
* @returns {{ checkInstalled: () => boolean, checkStatus: () => Promise<import('./types.js').ProviderStatus> } | undefined}
*/
export function getStatusChecker(name) {
return statusCheckers.get(name);
}
/**
* Get all registered provider names.
* @returns {string[]}

View File

@@ -69,6 +69,19 @@
* @property {object} [tokenUsage] - Token usage data (provider-specific)
*/
// ─── Provider Status ────────────────────────────────────────────────────────
/**
* Result of a provider status check (installation + authentication).
*
* @typedef {Object} ProviderStatus
* @property {boolean} installed - Whether the provider's CLI/SDK is available
* @property {boolean} authenticated - Whether valid credentials exist
* @property {string|null} email - User email or auth method identifier
* @property {string|null} [method] - Auth method (e.g. 'api_key', 'credentials_file')
* @property {string|null} [error] - Error message if not installed or not authenticated
*/
// ─── Provider Adapter Interface ──────────────────────────────────────────────
/**

View File

@@ -475,6 +475,7 @@ class SSEStreamWriter {
setSessionId(sessionId) {
this.sessionId = sessionId;
this.send({ type: 'session-id', sessionId });
}
getSessionId() {
@@ -839,7 +840,7 @@ class ResponseCollector {
* }
*/
router.post('/', validateExternalApiKey, async (req, res) => {
const { githubUrl, projectPath, message, provider = 'claude', model, githubToken, branchName } = req.body;
const { githubUrl, projectPath, message, provider = 'claude', model, githubToken, branchName, sessionId } = req.body;
// Parse stream and cleanup as booleans (handle string "true"/"false" from curl)
const stream = req.body.stream === undefined ? true : (req.body.stream === true || req.body.stream === 'true');
@@ -875,9 +876,8 @@ router.post('/', validateExternalApiKey, async (req, res) => {
// Determine the final project path
if (githubUrl) {
// Clone repository (to projectPath if provided, otherwise generate path)
// TODO: use credinitalsDB when refactoring
const tokenToUse = githubToken || githubTokensDb.getActiveGithubToken(req.user.id);
let targetPath;
if (projectPath) {
targetPath = projectPath;
@@ -950,7 +950,7 @@ router.post('/', validateExternalApiKey, async (req, res) => {
await queryClaudeSDK(message.trim(), {
projectPath: finalProjectPath,
cwd: finalProjectPath,
sessionId: null, // New session
sessionId: sessionId || null,
model: model,
permissionMode: 'bypassPermissions' // Bypass all permissions for API calls
}, writer);
@@ -961,7 +961,7 @@ router.post('/', validateExternalApiKey, async (req, res) => {
await spawnCursor(message.trim(), {
projectPath: finalProjectPath,
cwd: finalProjectPath,
sessionId: null, // New session
sessionId: sessionId || null,
model: model || undefined,
skipPermissions: true // Bypass permissions for Cursor
}, writer);
@@ -971,7 +971,7 @@ router.post('/', validateExternalApiKey, async (req, res) => {
await queryCodex(message.trim(), {
projectPath: finalProjectPath,
cwd: finalProjectPath,
sessionId: null,
sessionId: sessionId || null,
model: model || CODEX_MODELS.DEFAULT,
permissionMode: 'bypassPermissions'
}, writer);
@@ -981,7 +981,7 @@ router.post('/', validateExternalApiKey, async (req, res) => {
await spawnGemini(message.trim(), {
projectPath: finalProjectPath,
cwd: finalProjectPath,
sessionId: null,
sessionId: sessionId || null,
model: model,
skipPermissions: true // CLI mode bypasses permissions
}, writer);
@@ -996,7 +996,6 @@ router.post('/', validateExternalApiKey, async (req, res) => {
console.log('🔄 Starting GitHub branch/PR creation workflow...');
// Get GitHub token
// TODO: use credinitalsDB when refactoring
const tokenToUse = githubToken || githubTokensDb.getActiveGithubToken(req.user.id);
if (!tokenToUse) {
@@ -1126,7 +1125,7 @@ router.post('/', validateExternalApiKey, async (req, res) => {
} else {
prBody += `Agent task: ${message}`;
}
prBody += '\n\n---\n*This pull request was automatically created by Claude Code UI Agent.*';
prBody += '\n\n---\n*This pull request was automatically created by CloudCLI.ai Agent.*';
console.log(`📝 PR Title: ${prTitle}`);

View File

@@ -1,434 +1,27 @@
/**
* CLI Auth Routes
*
* Thin router that delegates to per-provider status checkers
* registered in the provider registry.
*
* @module routes/cli-auth
*/
import express from 'express';
import { spawn } from 'child_process';
import fs from 'fs/promises';
import path from 'path';
import os from 'os';
import { getAllProviders, getStatusChecker } from '../providers/registry.js';
const router = express.Router();
router.get('/claude/status', async (req, res) => {
try {
const credentialsResult = await checkClaudeCredentials();
if (credentialsResult.authenticated) {
return res.json({
authenticated: true,
email: credentialsResult.email || 'Authenticated',
method: credentialsResult.method // 'api_key' or 'credentials_file'
});
}
return res.json({
authenticated: false,
email: null,
method: null,
error: credentialsResult.error || 'Not authenticated'
});
} catch (error) {
console.error('Error checking Claude auth status:', error);
res.status(500).json({
authenticated: false,
email: null,
method: null,
error: error.message
});
}
});
router.get('/cursor/status', async (req, res) => {
try {
const result = await checkCursorStatus();
res.json({
authenticated: result.authenticated,
email: result.email,
error: result.error
});
} catch (error) {
console.error('Error checking Cursor auth status:', error);
res.status(500).json({
authenticated: false,
email: null,
error: error.message
});
}
});
router.get('/codex/status', async (req, res) => {
try {
const result = await checkCodexCredentials();
res.json({
authenticated: result.authenticated,
email: result.email,
error: result.error
});
} catch (error) {
console.error('Error checking Codex auth status:', error);
res.status(500).json({
authenticated: false,
email: null,
error: error.message
});
}
});
router.get('/gemini/status', async (req, res) => {
try {
const result = await checkGeminiCredentials();
res.json({
authenticated: result.authenticated,
email: result.email,
error: result.error
});
} catch (error) {
console.error('Error checking Gemini auth status:', error);
res.status(500).json({
authenticated: false,
email: null,
error: error.message
});
}
});
async function loadClaudeSettingsEnv() {
try {
const settingsPath = path.join(os.homedir(), '.claude', 'settings.json');
const content = await fs.readFile(settingsPath, 'utf8');
const settings = JSON.parse(content);
if (settings?.env && typeof settings.env === 'object') {
return settings.env;
}
} catch (error) {
// Ignore missing or malformed settings and fall back to other auth sources.
}
return {};
}
/**
* Checks Claude authentication credentials using two methods with priority order:
*
* Priority 1: ANTHROPIC_API_KEY environment variable
* Priority 1b: ~/.claude/settings.json env values
* Priority 2: ~/.claude/.credentials.json OAuth tokens
*
* The Claude Agent SDK prioritizes environment variables over authenticated subscriptions.
* This matching behavior ensures consistency with how the SDK authenticates.
*
* References:
* - https://support.claude.com/en/articles/12304248-managing-api-key-environment-variables-in-claude-code
* "Claude Code prioritizes environment variable API keys over authenticated subscriptions"
* - https://platform.claude.com/docs/en/agent-sdk/overview
* SDK authentication documentation
*
* @returns {Promise<Object>} Authentication status with { authenticated, email, method }
* - authenticated: boolean indicating if valid credentials exist
* - email: user email or auth method identifier
* - method: 'api_key' for env var, 'credentials_file' for OAuth tokens
*/
async function checkClaudeCredentials() {
// Priority 1: Check for ANTHROPIC_API_KEY environment variable
// The SDK checks this first and uses it if present, even if OAuth tokens exist.
// When set, API calls are charged via pay-as-you-go rates instead of subscription.
if (process.env.ANTHROPIC_API_KEY && process.env.ANTHROPIC_API_KEY.trim()) {
return {
authenticated: true,
email: 'API Key Auth',
method: 'api_key'
};
}
// Priority 1b: Check ~/.claude/settings.json env values.
// Claude Code can read proxy/auth values from settings.json even when the
// CloudCLI server process itself was not started with those env vars exported.
const settingsEnv = await loadClaudeSettingsEnv();
if (typeof settingsEnv.ANTHROPIC_API_KEY === 'string' && settingsEnv.ANTHROPIC_API_KEY.trim()) {
return {
authenticated: true,
email: 'API Key Auth',
method: 'api_key'
};
}
if (typeof settingsEnv.ANTHROPIC_AUTH_TOKEN === 'string' && settingsEnv.ANTHROPIC_AUTH_TOKEN.trim()) {
return {
authenticated: true,
email: 'Configured via settings.json',
method: 'api_key'
};
}
// Priority 2: Check ~/.claude/.credentials.json for OAuth tokens
// This is the standard authentication method used by Claude CLI after running
// 'claude /login' or 'claude setup-token' commands.
try {
const credPath = path.join(os.homedir(), '.claude', '.credentials.json');
const content = await fs.readFile(credPath, 'utf8');
const creds = JSON.parse(content);
const oauth = creds.claudeAiOauth;
if (oauth && oauth.accessToken) {
const isExpired = oauth.expiresAt && Date.now() >= oauth.expiresAt;
if (!isExpired) {
return {
authenticated: true,
email: creds.email || creds.user || null,
method: 'credentials_file'
};
}
}
return {
authenticated: false,
email: null,
method: null
};
} catch (error) {
return {
authenticated: false,
email: null,
method: null
};
}
}
function checkCursorStatus() {
return new Promise((resolve) => {
let processCompleted = false;
const timeout = setTimeout(() => {
if (!processCompleted) {
processCompleted = true;
if (childProcess) {
childProcess.kill();
}
resolve({
authenticated: false,
email: null,
error: 'Command timeout'
});
}
}, 5000);
let childProcess;
for (const provider of getAllProviders()) {
router.get(`/${provider}/status`, async (req, res) => {
try {
childProcess = spawn('cursor-agent', ['status']);
} catch (err) {
clearTimeout(timeout);
processCompleted = true;
resolve({
authenticated: false,
email: null,
error: 'Cursor CLI not found or not installed'
});
return;
const checker = getStatusChecker(provider);
res.json(await checker.checkStatus());
} catch (error) {
console.error(`Error checking ${provider} status:`, error);
res.status(500).json({ authenticated: false, error: error.message });
}
let stdout = '';
let stderr = '';
childProcess.stdout.on('data', (data) => {
stdout += data.toString();
});
childProcess.stderr.on('data', (data) => {
stderr += data.toString();
});
childProcess.on('close', (code) => {
if (processCompleted) return;
processCompleted = true;
clearTimeout(timeout);
if (code === 0) {
const emailMatch = stdout.match(/Logged in as ([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})/i);
if (emailMatch) {
resolve({
authenticated: true,
email: emailMatch[1],
output: stdout
});
} else if (stdout.includes('Logged in')) {
resolve({
authenticated: true,
email: 'Logged in',
output: stdout
});
} else {
resolve({
authenticated: false,
email: null,
error: 'Not logged in'
});
}
} else {
resolve({
authenticated: false,
email: null,
error: stderr || 'Not logged in'
});
}
});
childProcess.on('error', (err) => {
if (processCompleted) return;
processCompleted = true;
clearTimeout(timeout);
resolve({
authenticated: false,
email: null,
error: 'Cursor CLI not found or not installed'
});
});
});
}
async function checkCodexCredentials() {
try {
const authPath = path.join(os.homedir(), '.codex', 'auth.json');
const content = await fs.readFile(authPath, 'utf8');
const auth = JSON.parse(content);
// Tokens are nested under 'tokens' key
const tokens = auth.tokens || {};
// Check for valid tokens (id_token or access_token)
if (tokens.id_token || tokens.access_token) {
// Try to extract email from id_token JWT payload
let email = 'Authenticated';
if (tokens.id_token) {
try {
// JWT is base64url encoded: header.payload.signature
const parts = tokens.id_token.split('.');
if (parts.length >= 2) {
// Decode the payload (second part)
const payload = JSON.parse(Buffer.from(parts[1], 'base64url').toString('utf8'));
email = payload.email || payload.user || 'Authenticated';
}
} catch {
// If JWT decoding fails, use fallback
email = 'Authenticated';
}
}
return {
authenticated: true,
email
};
}
// Also check for OPENAI_API_KEY as fallback auth method
if (auth.OPENAI_API_KEY) {
return {
authenticated: true,
email: 'API Key Auth'
};
}
return {
authenticated: false,
email: null,
error: 'No valid tokens found'
};
} catch (error) {
if (error.code === 'ENOENT') {
return {
authenticated: false,
email: null,
error: 'Codex not configured'
};
}
return {
authenticated: false,
email: null,
error: error.message
};
}
}
async function checkGeminiCredentials() {
if (process.env.GEMINI_API_KEY && process.env.GEMINI_API_KEY.trim()) {
return {
authenticated: true,
email: 'API Key Auth'
};
}
try {
const credsPath = path.join(os.homedir(), '.gemini', 'oauth_creds.json');
const content = await fs.readFile(credsPath, 'utf8');
const creds = JSON.parse(content);
if (creds.access_token) {
let email = 'OAuth Session';
try {
// Validate token against Google API
const tokenRes = await fetch(`https://oauth2.googleapis.com/tokeninfo?access_token=${creds.access_token}`);
if (tokenRes.ok) {
const tokenInfo = await tokenRes.json();
if (tokenInfo.email) {
email = tokenInfo.email;
}
} else if (!creds.refresh_token) {
// Token invalid and no refresh token available
return {
authenticated: false,
email: null,
error: 'Access token invalid and no refresh token found'
};
} else {
// Token might be expired but we have a refresh token, so CLI will refresh it
try {
const accPath = path.join(os.homedir(), '.gemini', 'google_accounts.json');
const accContent = await fs.readFile(accPath, 'utf8');
const accounts = JSON.parse(accContent);
if (accounts.active) {
email = accounts.active;
}
} catch (e) { }
}
} catch (e) {
// Network error, fallback to checking local accounts file
try {
const accPath = path.join(os.homedir(), '.gemini', 'google_accounts.json');
const accContent = await fs.readFile(accPath, 'utf8');
const accounts = JSON.parse(accContent);
if (accounts.active) {
email = accounts.active;
}
} catch (err) { }
}
return {
authenticated: true,
email: email
};
}
return {
authenticated: false,
email: null,
error: 'No valid tokens found in oauth_creds'
};
} catch (error) {
return {
authenticated: false,
email: null,
error: 'Gemini CLI not configured'
};
}
}
export default router;

View File

@@ -1,13 +1,15 @@
import express from 'express';
import { promises as fs } from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import os from 'os';
import { CLAUDE_MODELS, CURSOR_MODELS, CODEX_MODELS } from '../../shared/modelConstants.js';
import { parseFrontmatter } from '../utils/frontmatter.js';
import { findAppRoot, getModuleDir } from '../utils/runtime-paths.js';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const __dirname = getModuleDir(import.meta.url);
// This route reads the top-level package.json for the status command, so it needs the real
// app root even after compilation moves the route file under dist-server/server/routes.
const APP_ROOT = findAppRoot(__dirname);
const router = express.Router();
@@ -291,7 +293,7 @@ Custom commands can be created in:
'/status': async (args, context) => {
// Read version from package.json
const packageJsonPath = path.join(path.dirname(__dirname), '..', 'package.json');
const packageJsonPath = path.join(APP_ROOT, 'package.json');
let version = 'unknown';
let packageName = 'claude-code-ui';

View File

@@ -2,9 +2,7 @@ import express from 'express';
import { promises as fs } from 'fs';
import path from 'path';
import os from 'os';
import { spawn } from 'child_process';
import sqlite3 from 'sqlite3';
import { open } from 'sqlite';
import Database from 'better-sqlite3';
import crypto from 'crypto';
import { CURSOR_MODELS } from '../../shared/modelConstants.js';
import { applyCustomSessionNames } from '../database/db.js';
@@ -387,16 +385,10 @@ router.get('/sessions', async (req, res) => {
} catch (_) {}
// Open SQLite database
const db = await open({
filename: storeDbPath,
driver: sqlite3.Database,
mode: sqlite3.OPEN_READONLY
});
const db = new Database(storeDbPath, { readonly: true, fileMustExist: true });
// Get metadata from meta table
const metaRows = await db.all(`
SELECT key, value FROM meta
`);
const metaRows = db.prepare('SELECT key, value FROM meta').all();
let sessionData = {
id: sessionId,
@@ -458,20 +450,11 @@ router.get('/sessions', async (req, res) => {
// Get message count from JSON blobs only (actual messages, not DAG structure)
try {
const blobCount = await db.get(`
SELECT COUNT(*) as count
FROM blobs
WHERE substr(data, 1, 1) = X'7B'
`);
const blobCount = db.prepare(`SELECT COUNT(*) as count FROM blobs WHERE substr(data, 1, 1) = X'7B'`).get();
sessionData.messageCount = blobCount.count;
// Get the most recent JSON blob for preview (actual message, not DAG structure)
const lastBlob = await db.get(`
SELECT data FROM blobs
WHERE substr(data, 1, 1) = X'7B'
ORDER BY rowid DESC
LIMIT 1
`);
const lastBlob = db.prepare(`SELECT data FROM blobs WHERE substr(data, 1, 1) = X'7B' ORDER BY rowid DESC LIMIT 1`).get();
if (lastBlob && lastBlob.data) {
try {
@@ -526,7 +509,7 @@ router.get('/sessions', async (req, res) => {
console.log('Could not read blobs:', e.message);
}
await db.close();
db.close();
// Finalize createdAt: use parsed meta value when valid, else fall back to store.db mtime
if (!sessionData.createdAt) {
@@ -578,221 +561,4 @@ router.get('/sessions', async (req, res) => {
});
}
});
// GET /api/cursor/sessions/:sessionId - Get specific Cursor session from SQLite
router.get('/sessions/:sessionId', async (req, res) => {
try {
const { sessionId } = req.params;
const { projectPath } = req.query;
// Calculate cwdID hash for the project path
const cwdId = crypto.createHash('md5').update(projectPath || process.cwd()).digest('hex');
const storeDbPath = path.join(os.homedir(), '.cursor', 'chats', cwdId, sessionId, 'store.db');
// Open SQLite database
const db = await open({
filename: storeDbPath,
driver: sqlite3.Database,
mode: sqlite3.OPEN_READONLY
});
// Get all blobs to build the DAG structure
const allBlobs = await db.all(`
SELECT rowid, id, data FROM blobs
`);
// Build the DAG structure from parent-child relationships
const blobMap = new Map(); // id -> blob data
const parentRefs = new Map(); // blob id -> [parent blob ids]
const childRefs = new Map(); // blob id -> [child blob ids]
const jsonBlobs = []; // Clean JSON messages
for (const blob of allBlobs) {
blobMap.set(blob.id, blob);
// Check if this is a JSON blob (actual message) or protobuf (DAG structure)
if (blob.data && blob.data[0] === 0x7B) { // Starts with '{' - JSON blob
try {
const parsed = JSON.parse(blob.data.toString('utf8'));
jsonBlobs.push({ ...blob, parsed });
} catch (e) {
console.log('Failed to parse JSON blob:', blob.rowid);
}
} else if (blob.data) { // Protobuf blob - extract parent references
const parents = [];
let i = 0;
// Scan for parent references (0x0A 0x20 followed by 32-byte hash)
while (i < blob.data.length - 33) {
if (blob.data[i] === 0x0A && blob.data[i+1] === 0x20) {
const parentHash = blob.data.slice(i+2, i+34).toString('hex');
if (blobMap.has(parentHash)) {
parents.push(parentHash);
}
i += 34;
} else {
i++;
}
}
if (parents.length > 0) {
parentRefs.set(blob.id, parents);
// Update child references
for (const parentId of parents) {
if (!childRefs.has(parentId)) {
childRefs.set(parentId, []);
}
childRefs.get(parentId).push(blob.id);
}
}
}
}
// Perform topological sort to get chronological order
const visited = new Set();
const sorted = [];
// DFS-based topological sort
function visit(nodeId) {
if (visited.has(nodeId)) return;
visited.add(nodeId);
// Visit all parents first (dependencies)
const parents = parentRefs.get(nodeId) || [];
for (const parentId of parents) {
visit(parentId);
}
// Add this node after all its parents
const blob = blobMap.get(nodeId);
if (blob) {
sorted.push(blob);
}
}
// Start with nodes that have no parents (roots)
for (const blob of allBlobs) {
if (!parentRefs.has(blob.id)) {
visit(blob.id);
}
}
// Visit any remaining nodes (disconnected components)
for (const blob of allBlobs) {
visit(blob.id);
}
// Now extract JSON messages in the order they appear in the sorted DAG
const messageOrder = new Map(); // JSON blob id -> order index
let orderIndex = 0;
for (const blob of sorted) {
// Check if this blob references any JSON messages
if (blob.data && blob.data[0] !== 0x7B) { // Protobuf blob
// Look for JSON blob references
for (const jsonBlob of jsonBlobs) {
try {
const jsonIdBytes = Buffer.from(jsonBlob.id, 'hex');
if (blob.data.includes(jsonIdBytes)) {
if (!messageOrder.has(jsonBlob.id)) {
messageOrder.set(jsonBlob.id, orderIndex++);
}
}
} catch (e) {
// Skip if can't convert ID
}
}
}
}
// Sort JSON blobs by their appearance order in the DAG
const sortedJsonBlobs = jsonBlobs.sort((a, b) => {
const orderA = messageOrder.get(a.id) ?? Number.MAX_SAFE_INTEGER;
const orderB = messageOrder.get(b.id) ?? Number.MAX_SAFE_INTEGER;
if (orderA !== orderB) return orderA - orderB;
// Fallback to rowid if not in order map
return a.rowid - b.rowid;
});
// Use sorted JSON blobs
const blobs = sortedJsonBlobs.map((blob, idx) => ({
...blob,
sequence_num: idx + 1,
original_rowid: blob.rowid
}));
// Get metadata from meta table
const metaRows = await db.all(`
SELECT key, value FROM meta
`);
// Parse metadata
let metadata = {};
for (const row of metaRows) {
if (row.value) {
try {
// Try to decode as hex-encoded JSON
const hexMatch = row.value.toString().match(/^[0-9a-fA-F]+$/);
if (hexMatch) {
const jsonStr = Buffer.from(row.value, 'hex').toString('utf8');
metadata[row.key] = JSON.parse(jsonStr);
} else {
metadata[row.key] = row.value.toString();
}
} catch (e) {
metadata[row.key] = row.value.toString();
}
}
}
// Extract messages from sorted JSON blobs
const messages = [];
for (const blob of blobs) {
try {
// We already parsed JSON blobs earlier
const parsed = blob.parsed;
if (parsed) {
// Filter out ONLY system messages at the server level
// Check both direct role and nested message.role
const role = parsed?.role || parsed?.message?.role;
if (role === 'system') {
continue; // Skip only system messages
}
messages.push({
id: blob.id,
sequence: blob.sequence_num,
rowid: blob.original_rowid,
content: parsed
});
}
} catch (e) {
// Skip blobs that cause errors
console.log(`Skipping blob ${blob.id}: ${e.message}`);
}
}
await db.close();
res.json({
success: true,
session: {
id: sessionId,
projectPath: projectPath,
messages: messages,
metadata: metadata,
cwdId: cwdId
}
});
} catch (error) {
console.error('Error reading Cursor session:', error);
res.status(500).json({
error: 'Failed to read Cursor session',
details: error.message
});
}
});
export default router;

View File

@@ -125,7 +125,7 @@ function buildPushBody(event) {
const message = CODE_MAP[event.code] || 'You have a new notification';
return {
title: sessionName || 'Claude Code UI',
title: sessionName || 'CloudCLI',
body: `${providerLabel}: ${message}`,
data: {
sessionId: event.sessionId || null,

View File

@@ -1,32 +0,0 @@
import './config/load-env-vars.js';
import { pathToFileURL } from 'url';
import { getRuntimePaths } from '@/config/runtime.js';
import type { ServerApplication } from '@/shared/types/app.js';
import { logger } from '@/shared/utils/logger.js';
export function createServerApplication(): ServerApplication {
const runtimePaths = getRuntimePaths();
return {
runtimePaths,
start: async () => {
// ----------------------------------------------
// Legacy backend Runner
// logger.info('Bootstrapping backend via legacy runtime bridge', {
// legacyRuntime: runtimePaths.legacyRuntimePath,
// });
// await import(pathToFileURL(runtimePaths.legacyRuntimePath).href);
// ----------------------------------------------
// ----------------------------------------------
// Refactor backend Runner
logger.info('Bootstrapping backend via refactor runtime', {
refactorRuntime: runtimePaths.refactorRuntimePath,
});
await import(pathToFileURL(runtimePaths.refactorRuntimePath).href);
},
};
}

View File

@@ -1,8 +0,0 @@
import { createServerApplication } from '@/app.js';
async function startServerApplication(): Promise<void> {
const application = createServerApplication();
await application.start();
}
await startServerApplication();

View File

@@ -1,5 +0,0 @@
/**
* Environment Flag: Is Platform
* Indicates if the app is running in Platform mode (hosted) or OSS mode (self-hosted)
*/
export const IS_PLATFORM = process.env.VITE_IS_PLATFORM === 'true';

View File

@@ -1,30 +0,0 @@
// Load environment variables from .env before other imports execute.
import fs from 'fs';
import os from 'os';
import path from 'path';
import { fileURLToPath } from 'url';
import { dirname } from 'path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
try {
const envPath = path.join(__dirname, '../../../.env');
const envFile = fs.readFileSync(envPath, 'utf8');
envFile.split('\n').forEach(line => {
const trimmedLine = line.trim();
if (trimmedLine && !trimmedLine.startsWith('#')) {
const [key, ...valueParts] = trimmedLine.split('=');
if (key && valueParts.length > 0 && !process.env[key]) {
process.env[key] = valueParts.join('=').trim();
}
}
});
} catch (e: any) {
console.log('No .env file found or error reading it:', e.message);
}
// Set a default DATABASE_PATH if not already set by .env to ~/.cloudcli/auth.db
if (!process.env.DATABASE_PATH) {
process.env.DATABASE_PATH = path.join(os.homedir(), '.cloudcli', 'auth.db');
}

View File

@@ -1,27 +0,0 @@
import path from 'path';
import { fileURLToPath } from 'url';
import type { RuntimePaths } from '@/shared/types/app.js';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const RUN_REFACTOR_WITH_SRC = true;
export function getRuntimePaths(): RuntimePaths {
const serverSrcDir = path.resolve(__dirname, '..');
const serverDir = path.resolve(serverSrcDir, '..');
const refactorRuntimePath =
RUN_REFACTOR_WITH_SRC
? path.join(serverDir, 'src', 'runner.ts')
: path.join(serverDir, 'dist', 'runner.js');
return {
serverSrcDir,
serverDir,
projectRoot: path.resolve(serverDir, '..'),
legacyRuntimePath: path.join(serverDir, 'index.js'),
bootstrapEntrypointPath: path.join(serverDir, 'dist', 'bootstrap.js'),
refactorRuntimePath
};
}

View File

@@ -1 +0,0 @@

File diff suppressed because it is too large Load Diff

View File

@@ -1,42 +0,0 @@
import type { IProvider } from '@/modules/ai-runtime/types/index.js';
import { ClaudeProvider } from '@/modules/ai-runtime/providers/claude/claude.provider.js';
import { CodexProvider } from '@/modules/ai-runtime/providers/codex/codex.provider.js';
import { CursorProvider } from '@/modules/ai-runtime/providers/cursor/cursor.provider.js';
import { GeminiProvider } from '@/modules/ai-runtime/providers/gemini/gemini.provider.js';
import type { LLMProvider } from '@/shared/types/app.js';
import { AppError } from '@/shared/utils/app-error.js';
const providers: Record<LLMProvider, IProvider> = {
claude: new ClaudeProvider(),
codex: new CodexProvider(),
cursor: new CursorProvider(),
gemini: new GeminiProvider(),
};
/**
* Central registry for resolving provider implementations by id.
*/
export const llmProviderRegistry = {
/**
* Returns all registered providers.
*/
listProviders(): IProvider[] {
return Object.values(providers);
},
/**
* Resolves one provider or throws a typed 400 error.
*/
resolveProvider(provider: string): IProvider {
const key = provider as LLMProvider;
const resolvedProvider = providers[key];
if (!resolvedProvider) {
throw new AppError(`Unsupported provider "${provider}".`, {
code: 'UNSUPPORTED_PROVIDER',
statusCode: 400,
});
}
return resolvedProvider;
},
};

View File

@@ -1,563 +0,0 @@
import express, { type NextFunction, type Request, type Response } from 'express';
import { asyncHandler } from '@/shared/http/async-handler.js';
import { AppError } from '@/shared/utils/app-error.js';
import { createApiErrorResponse, createApiSuccessResponse } from '@/shared/http/api-response.js';
import { llmService } from '@/modules/ai-runtime/services/ai-runtime.service.js';
import { llmAuthService } from '@/modules/ai-runtime/services/auth.service.js';
import { llmSessionsService } from '@/modules/ai-runtime/services/sessions.service.js';
import { llmMcpService } from '@/modules/ai-runtime/services/mcp.service.js';
import { llmSkillsService } from '@/modules/ai-runtime/services/skills.service.js';
import type { McpScope, McpTransport, UpsertProviderMcpServerInput } from '@/modules/ai-runtime/types/index.js';
import { llmMessagesUnifier } from '@/modules/ai-runtime/services/messages-unifier.service.js';
import type { LLMProvider } from '@/shared/types/app.js';
import { logger } from '@/shared/utils/logger.js';
const router = express.Router();
/**
* Safely reads an Express path parameter that may arrive as string or string[].
*/
const readPathParam = (value: unknown, name: string): string => {
if (typeof value === 'string') {
return value;
}
if (Array.isArray(value) && typeof value[0] === 'string') {
return value[0];
}
throw new AppError(`${name} path parameter is invalid.`, {
code: 'INVALID_PATH_PARAMETER',
statusCode: 400,
});
};
const normalizeProviderParam = (value: unknown): string =>
readPathParam(value, 'provider').trim().toLowerCase();
/**
* Validates and normalizes rename payload.
*/
const parseRenamePayload = (payload: unknown): { summary: string } => {
if (!payload || typeof payload !== 'object') {
throw new AppError('Request body must be an object.', {
code: 'INVALID_REQUEST_BODY',
statusCode: 400,
});
}
const body = payload as Record<string, unknown>;
const summary = typeof body.summary === 'string' ? body.summary.trim() : '';
if (!summary) {
throw new AppError('summary is required.', {
code: 'SUMMARY_REQUIRED',
statusCode: 400,
});
}
if (summary.length > 500) {
throw new AppError('summary must not exceed 500 characters.', {
code: 'SUMMARY_TOO_LONG',
statusCode: 400,
});
}
return { summary };
};
/**
* Reads optional query values and trims surrounding whitespace.
*/
const readOptionalQueryString = (value: unknown): string | undefined => {
if (typeof value !== 'string') {
return undefined;
}
const normalized = value.trim();
return normalized.length > 0 ? normalized : undefined;
};
/**
* Validates MCP scope query/body values.
*/
const parseMcpScope = (value: unknown): McpScope | undefined => {
if (value === undefined) {
return undefined;
}
const normalized = readOptionalQueryString(value);
if (!normalized) {
return undefined;
}
if (normalized === 'user' || normalized === 'local' || normalized === 'project') {
return normalized;
}
throw new AppError(`Unsupported MCP scope "${normalized}".`, {
code: 'INVALID_MCP_SCOPE',
statusCode: 400,
});
};
/**
* Validates MCP transport query/body values.
*/
const parseMcpTransport = (value: unknown): McpTransport => {
const normalized = readOptionalQueryString(value);
if (!normalized) {
throw new AppError('transport is required.', {
code: 'MCP_TRANSPORT_REQUIRED',
statusCode: 400,
});
}
if (normalized === 'stdio' || normalized === 'http' || normalized === 'sse') {
return normalized;
}
throw new AppError(`Unsupported MCP transport "${normalized}".`, {
code: 'INVALID_MCP_TRANSPORT',
statusCode: 400,
});
};
/**
* Parses and validates MCP upsert payload.
*/
const parseMcpUpsertPayload = (payload: unknown): UpsertProviderMcpServerInput => {
if (!payload || typeof payload !== 'object') {
throw new AppError('Request body must be an object.', {
code: 'INVALID_REQUEST_BODY',
statusCode: 400,
});
}
const body = payload as Record<string, unknown>;
const name = readOptionalQueryString(body.name);
if (!name) {
throw new AppError('name is required.', {
code: 'MCP_NAME_REQUIRED',
statusCode: 400,
});
}
const transport = parseMcpTransport(body.transport);
const scope = parseMcpScope(body.scope);
const workspacePath = readOptionalQueryString(body.workspacePath);
return {
name,
transport,
scope,
workspacePath,
command: readOptionalQueryString(body.command),
args: Array.isArray(body.args) ? body.args.filter((entry): entry is string => typeof entry === 'string') : undefined,
env: typeof body.env === 'object' && body.env !== null
? Object.fromEntries(
Object.entries(body.env as Record<string, unknown>).filter(
(entry): entry is [string, string] => typeof entry[1] === 'string',
),
)
: undefined,
cwd: readOptionalQueryString(body.cwd),
url: readOptionalQueryString(body.url),
headers: typeof body.headers === 'object' && body.headers !== null
? Object.fromEntries(
Object.entries(body.headers as Record<string, unknown>).filter(
(entry): entry is [string, string] => typeof entry[1] === 'string',
),
)
: undefined,
envVars: Array.isArray(body.envVars)
? body.envVars.filter((entry): entry is string => typeof entry === 'string')
: undefined,
bearerTokenEnvVar: readOptionalQueryString(body.bearerTokenEnvVar),
envHttpHeaders: typeof body.envHttpHeaders === 'object' && body.envHttpHeaders !== null
? Object.fromEntries(
Object.entries(body.envHttpHeaders as Record<string, unknown>).filter(
(entry): entry is [string, string] => typeof entry[1] === 'string',
),
)
: undefined,
};
};
/**
* Converts any provider route parameter into the strongly typed provider union.
*/
const parseProvider = (value: unknown): LLMProvider => {
const normalized = normalizeProviderParam(value);
if (normalized === 'claude' || normalized === 'codex' || normalized === 'cursor' || normalized === 'gemini') {
return normalized;
}
throw new AppError(`Unsupported provider "${normalized}".`, {
code: 'UNSUPPORTED_PROVIDER',
statusCode: 400,
});
};
/**
* Enriches provider session snapshots with normalized message types for frontend rendering.
*/
const formatSessionSnapshot = (
provider: LLMProvider,
snapshot: {
sessionId: string;
events: Array<{
timestamp: string;
channel: 'sdk' | 'stdout' | 'stderr' | 'json' | 'system' | 'error';
message?: string;
data?: unknown;
}>;
},
) => ({
...snapshot,
messages: llmMessagesUnifier.normalizeSessionEvents(provider, snapshot.sessionId, snapshot.events),
});
router.get(
'/providers',
asyncHandler(async (_req: Request, res: Response) => {
res.json(createApiSuccessResponse({ providers: llmService.listProviders() }));
}),
);
router.get(
'/providers/:provider/models',
asyncHandler(async (req: Request, res: Response) => {
const provider = parseProvider(req.params.provider);
const models = await llmService.listModels(provider);
res.json(createApiSuccessResponse({ provider, models }));
}),
);
router.get(
'/providers/:provider/auth/status',
asyncHandler(async (req: Request, res: Response) => {
const provider = parseProvider(req.params.provider);
const auth = await llmAuthService.getProviderAuthStatus(provider);
res.json(createApiSuccessResponse({ provider, auth }));
}),
);
router.get(
'/providers/:provider/sessions',
asyncHandler(async (req: Request, res: Response) => {
const provider = parseProvider(req.params.provider);
const sessions = llmService.listSessions(provider).map((session) => formatSessionSnapshot(provider, session));
res.json(createApiSuccessResponse({ provider, sessions }));
}),
);
router.get(
'/providers/:provider/sessions/:sessionId',
asyncHandler(async (req: Request, res: Response) => {
const provider = parseProvider(req.params.provider);
const sessionId = readPathParam(req.params.sessionId, 'sessionId');
const session = llmService.getSession(provider, sessionId);
if (!session) {
throw new AppError(`Session "${sessionId}" not found for provider "${provider}".`, {
code: 'SESSION_NOT_FOUND',
statusCode: 404,
});
}
res.json(createApiSuccessResponse({ provider, session: formatSessionSnapshot(provider, session) }));
}),
);
router.post(
'/providers/:provider/sessions/start',
asyncHandler(async (req: Request, res: Response) => {
const provider = parseProvider(req.params.provider);
const snapshot = await llmService.startSession(provider, req.body);
const formattedSnapshot = formatSessionSnapshot(provider, snapshot);
res.status(202).json(
createApiSuccessResponse({
provider,
session: formattedSnapshot,
}),
);
}),
);
router.post(
'/providers/:provider/sessions/:sessionId/resume',
asyncHandler(async (req: Request, res: Response) => {
const provider = parseProvider(req.params.provider);
const sessionId = readPathParam(req.params.sessionId, 'sessionId');
const snapshot = await llmService.resumeSession(provider, sessionId, req.body);
res.status(202).json(createApiSuccessResponse({ provider, session: formatSessionSnapshot(provider, snapshot) }));
}),
);
router.post(
'/providers/:provider/sessions/:sessionId/stop',
asyncHandler(async (req: Request, res: Response) => {
const provider = parseProvider(req.params.provider);
const sessionId = readPathParam(req.params.sessionId, 'sessionId');
const stopped = await llmService.stopSession(provider, sessionId);
res.json(createApiSuccessResponse({ provider, sessionId, stopped }));
}),
);
/**
* Lists MCP servers for one provider grouped by user/local/project scopes.
*/
router.get(
'/providers/:provider/mcp/servers',
asyncHandler(async (req: Request, res: Response) => {
const provider = parseProvider(req.params.provider);
const workspacePath = readOptionalQueryString(req.query.workspacePath);
const scope = parseMcpScope(req.query.scope);
if (scope) {
const servers = await llmMcpService.listProviderMcpServersForScope(provider, scope, { workspacePath });
res.json(createApiSuccessResponse({ provider, scope, servers }));
return;
}
const groupedServers = await llmMcpService.listProviderMcpServers(provider, { workspacePath });
res.json(createApiSuccessResponse({ provider, scopes: groupedServers }));
}),
);
/**
* Adds one MCP server for one provider and scope.
*/
router.post(
'/providers/:provider/mcp/servers',
asyncHandler(async (req: Request, res: Response) => {
const provider = parseProvider(req.params.provider);
const payload = parseMcpUpsertPayload(req.body);
const server = await llmMcpService.upsertProviderMcpServer(provider, payload);
res.status(201).json(createApiSuccessResponse({ server }));
}),
);
/**
* Updates one provider MCP server definition.
*/
router.put(
'/providers/:provider/mcp/servers/:name',
asyncHandler(async (req: Request, res: Response) => {
const provider = parseProvider(req.params.provider);
const payload = parseMcpUpsertPayload({
...((req.body && typeof req.body === 'object') ? req.body as Record<string, unknown> : {}),
name: readPathParam(req.params.name, 'name'),
});
const server = await llmMcpService.upsertProviderMcpServer(provider, payload);
res.json(createApiSuccessResponse({ server }));
}),
);
/**
* Removes one provider MCP server from its configured scope.
*/
router.delete(
'/providers/:provider/mcp/servers/:name',
asyncHandler(async (req: Request, res: Response) => {
const provider = parseProvider(req.params.provider);
const scope = parseMcpScope(req.query.scope);
const workspacePath = readOptionalQueryString(req.query.workspacePath);
const result = await llmMcpService.removeProviderMcpServer(provider, {
name: readPathParam(req.params.name, 'name'),
scope,
workspacePath,
});
res.json(createApiSuccessResponse(result));
}),
);
/**
* Executes a lightweight startup/connectivity probe for one provider MCP server.
*/
router.post(
'/providers/:provider/mcp/servers/:name/run',
asyncHandler(async (req: Request, res: Response) => {
const provider = parseProvider(req.params.provider);
const body = (req.body as Record<string, unknown> | undefined) ?? {};
const scope = parseMcpScope(body.scope ?? req.query.scope);
const workspacePath = readOptionalQueryString(body.workspacePath ?? req.query.workspacePath);
const result = await llmMcpService.runProviderMcpServer(provider, {
name: readPathParam(req.params.name, 'name'),
scope,
workspacePath,
});
res.json(createApiSuccessResponse(result));
}),
);
/**
* Adds one HTTP/stdio MCP server to every provider.
*/
router.post(
'/mcp/servers/global',
asyncHandler(async (req: Request, res: Response) => {
const payload = parseMcpUpsertPayload(req.body);
if (payload.scope === 'local') {
throw new AppError('Global MCP add supports only "user" or "project" scopes.', {
code: 'INVALID_GLOBAL_MCP_SCOPE',
statusCode: 400,
});
}
const results = await llmMcpService.addMcpServerToAllProviders({
...payload,
scope: payload.scope === 'user' ? 'user' : 'project',
});
res.status(201).json(createApiSuccessResponse({ results }));
}),
);
/**
* Lists provider-specific skills from all documented skill directories.
*/
router.get(
'/providers/:provider/skills',
asyncHandler(async (req: Request, res: Response) => {
const provider = parseProvider(req.params.provider);
const workspacePath = readOptionalQueryString(req.query.workspacePath);
const skills = await llmSkillsService.listProviderSkills(provider, { workspacePath });
res.json(createApiSuccessResponse({ provider, skills }));
}),
);
/**
* Lists skills for one provider or for all providers in a single response.
*/
router.get(
'/skills',
asyncHandler(async (req: Request, res: Response) => {
const providerQuery = readOptionalQueryString(req.query.provider);
const workspacePath = readOptionalQueryString(req.query.workspacePath);
if (providerQuery) {
const provider = parseProvider(providerQuery);
const skills = await llmSkillsService.listProviderSkills(provider, { workspacePath });
res.json(createApiSuccessResponse({ provider, skills }));
return;
}
const providers: LLMProvider[] = ['claude', 'codex', 'cursor', 'gemini'];
const byProvider = Object.fromEntries(
await Promise.all(
providers.map(async (provider) => ([
provider,
await llmSkillsService.listProviderSkills(provider, { workspacePath }),
])),
),
);
res.json(createApiSuccessResponse({ providers: byProvider }));
}),
);
router.get(
'/sessions/:sessionId/messages',
asyncHandler(async (req: Request, res: Response) => {
const sessionId = readPathParam(req.params.sessionId, 'sessionId');
const history = await llmSessionsService.getSessionHistory(sessionId);
res.json(createApiSuccessResponse({
sessionId,
provider: history.provider,
messages: history.messages,
}));
}),
);
router.get(
'/sessions/:sessionId/history',
asyncHandler(async (req: Request, res: Response) => {
const sessionId = readPathParam(req.params.sessionId, 'sessionId');
const history = await llmSessionsService.getSessionHistory(sessionId);
res.json(createApiSuccessResponse(history));
}),
);
/**
* Renames one indexed session by writing the custom summary into DB.
*/
router.put(
'/sessions/:sessionId/rename',
asyncHandler(async (req: Request, res: Response) => {
const sessionId = readPathParam(req.params.sessionId, 'sessionId');
const { summary } = parseRenamePayload(req.body);
llmSessionsService.updateSessionCustomName(sessionId, summary);
res.json(createApiSuccessResponse({ sessionId, summary }));
}),
);
/**
* Returns DB-indexed sessions discovered by the session-processor scan.
*/
router.get(
'/sessions/index',
asyncHandler(async (req: Request, res: Response) => {
const provider =
typeof req.query.provider === 'string' ? req.query.provider.trim().toLowerCase() : undefined;
const sessions = llmSessionsService.listIndexedSessions(provider);
res.json(createApiSuccessResponse({ provider: provider ?? null, sessions }));
}),
);
/**
* Returns one DB-indexed session metadata row.
*/
router.get(
'/sessions/:sessionId',
asyncHandler(async (req: Request, res: Response) => {
const sessionId = readPathParam(req.params.sessionId, 'sessionId');
const session = llmSessionsService.getIndexedSession(sessionId);
res.json(createApiSuccessResponse({ session }));
}),
);
/**
* Triggers provider disk scans and refreshes the shared sessions table.
*/
router.post(
'/sessions/sync',
asyncHandler(async (_req: Request, res: Response) => {
const syncResult = await llmSessionsService.synchronizeSessions();
res.json(createApiSuccessResponse(syncResult));
}),
);
/**
* Deletes provider-specific session artifacts and removes the DB row.
*/
router.delete(
'/sessions/:sessionId',
asyncHandler(async (req: Request, res: Response) => {
const sessionId = readPathParam(req.params.sessionId, 'sessionId');
const result = await llmSessionsService.deleteSessionArtifacts(sessionId);
res.json(createApiSuccessResponse(result));
}),
);
/**
* Normalizes route-level failures to a consistent JSON API shape.
*/
router.use((error: unknown, _req: Request, res: Response, _next: NextFunction) => {
if (res.headersSent) {
return;
}
if (error instanceof AppError) {
res
.status(error.statusCode)
.json(createApiErrorResponse(error.code, error.message, undefined, error.details));
return;
}
const message = error instanceof Error ? error.message : 'Unexpected LLM route failure.';
logger.error(message, {
module: 'ai-runtime.routes',
});
res.status(500).json(createApiErrorResponse('INTERNAL_ERROR', message));
});
export default router;

View File

@@ -1,173 +0,0 @@
import type {
IProvider,
IProviderAuthRuntime,
IProviderMcpRuntime,
IProviderSessionSynchronizerRuntime,
IProviderSkillsRuntime,
MutableProviderSession,
ProviderCapabilities,
ProviderExecutionFamily,
ProviderModel,
ProviderSessionEvent,
ProviderSessionSnapshot,
StartSessionInput,
} from '@/modules/ai-runtime/types/index.js';
import type { LLMProvider } from '@/shared/types/app.js';
const MAX_EVENT_BUFFER_SIZE = 2_000;
/**
* Shared provider base for session lifecycle state and capability gating.
*/
export abstract class AbstractProvider implements IProvider {
readonly id: LLMProvider;
readonly family: ProviderExecutionFamily;
readonly capabilities: ProviderCapabilities;
abstract readonly mcp: IProviderMcpRuntime;
abstract readonly skills: IProviderSkillsRuntime;
abstract readonly sessionSynchronizer: IProviderSessionSynchronizerRuntime;
abstract readonly auth: IProviderAuthRuntime;
protected readonly sessions = new Map<string, MutableProviderSession>();
protected constructor(
id: LLMProvider,
family: ProviderExecutionFamily,
capabilities: ProviderCapabilities,
) {
this.id = id;
this.family = family;
this.capabilities = capabilities;
}
abstract listModels(): Promise<ProviderModel[]>;
abstract launchSession(input: StartSessionInput): Promise<ProviderSessionSnapshot>;
abstract resumeSession(
input: StartSessionInput & { sessionId: string },
): Promise<ProviderSessionSnapshot>;
/**
* Returns one in-memory session snapshot when present.
*/
getSession(sessionId: string): ProviderSessionSnapshot | null {
const session = this.sessions.get(sessionId);
if (!session) {
return null;
}
return this.toSnapshot(session);
}
/**
* Returns snapshots of all in-memory sessions.
*/
listSessions(): ProviderSessionSnapshot[] {
return [...this.sessions.values()].map((session) => this.toSnapshot(session));
}
/**
* Requests a graceful session stop.
*/
async stopSession(sessionId: string): Promise<boolean> {
const session = this.sessions.get(sessionId);
if (!session) {
return false;
}
const stopped = await session.stop();
if (stopped && session.status === 'running') {
this.updateSessionStatus(session, 'stopped');
this.appendEvent(session, {
timestamp: new Date().toISOString(),
channel: 'system',
message: 'Session stop requested.',
data: {
sessionId,
sessionStatus: 'SESSION_ABORTED',
},
});
}
return stopped;
}
/**
* Creates mutable internal session state and registers it in memory.
*/
protected createSessionRecord(
sessionId: string,
input: {
model?: string;
thinkingMode?: string;
},
): MutableProviderSession {
const session: MutableProviderSession = {
sessionId,
provider: this.id,
family: this.family,
status: 'running',
startedAt: new Date().toISOString(),
model: input.model,
thinkingMode: input.thinkingMode,
events: [],
completion: Promise.resolve(),
stop: async () => false,
};
this.sessions.set(sessionId, session);
this.appendEvent(session, {
timestamp: session.startedAt,
channel: 'system',
message: 'Session started.',
data: {
sessionId,
sessionStatus: 'STARTED',
},
});
return session;
}
/**
* Appends an event while enforcing the configured ring-buffer size.
*/
protected appendEvent(session: MutableProviderSession, event: ProviderSessionEvent): void {
session.events.push(event);
if (session.events.length > MAX_EVENT_BUFFER_SIZE) {
session.events.splice(0, session.events.length - MAX_EVENT_BUFFER_SIZE);
}
}
/**
* Marks the terminal state for a session.
*/
protected updateSessionStatus(
session: MutableProviderSession,
status: MutableProviderSession['status'],
error?: string,
): void {
session.status = status;
session.endedAt = new Date().toISOString();
session.error = error;
}
/**
* Converts mutable internal session state to an external snapshot.
*/
protected toSnapshot(session: MutableProviderSession): ProviderSessionSnapshot {
return {
sessionId: session.sessionId,
provider: session.provider,
family: session.family,
status: session.status,
startedAt: session.startedAt,
endedAt: session.endedAt,
model: session.model,
thinkingMode: session.thinkingMode,
events: [...session.events],
error: session.error,
};
}
}

View File

@@ -1,296 +0,0 @@
import { randomUUID } from 'node:crypto';
import { once } from 'node:events';
import type { ChildProcessWithoutNullStreams } from 'node:child_process';
import spawn from 'cross-spawn';
import { AbstractProvider } from '@/modules/ai-runtime/providers/base/abstract.provider.js';
import type {
MutableProviderSession,
ProviderCapabilities,
ProviderSessionEvent,
ProviderSessionSnapshot,
StartSessionInput,
} from '@/modules/ai-runtime/types/index.js';
import { createStreamLineAccumulator } from '@/shared/platform/stream.js';
import type { LLMProvider } from '@/shared/types/app.js';
type CreateCliInvocationInput = StartSessionInput & {
sessionId: string;
isResume: boolean;
};
type CliInvocation = {
command: string;
args: string[];
cwd?: string;
env?: Record<string, string | undefined>;
};
const PROCESS_SHUTDOWN_GRACE_PERIOD_MS = 2_000;
/**
* Base class for CLI-driven providers with streamed stdout/stderr parsing.
*/
export abstract class BaseCliProvider extends AbstractProvider {
protected constructor(providerId: LLMProvider, capabilities: ProviderCapabilities) {
super(providerId, 'cli', capabilities);
}
/**
* Starts a new CLI session and begins process output streaming.
*/
async launchSession(input: StartSessionInput): Promise<ProviderSessionSnapshot> {
return this.startSessionInternal({
...input,
sessionId: input.sessionId ?? randomUUID(),
isResume: false,
});
}
/**
* Resumes an existing CLI session and begins process output streaming.
*/
async resumeSession(input: StartSessionInput & { sessionId: string }): Promise<ProviderSessionSnapshot> {
return this.startSessionInternal({
...input,
isResume: true,
});
}
/**
* Implemented by concrete CLI providers to describe command invocation.
*/
protected abstract createCliInvocation(input: CreateCliInvocationInput): CliInvocation;
/**
* Appends uploaded image paths to prompt text for CLI providers that only accept string prompts.
*/
protected appendImagePathsToPrompt(prompt: string, imagePaths?: string[]): string {
if (!imagePaths || imagePaths.length === 0) {
return prompt;
}
return `${prompt}\n\n${JSON.stringify(imagePaths)}`;
}
/**
* Maps one stdout/stderr line into either JSON or plain-text event shapes.
*/
protected mapCliOutputLine(line: string, channel: 'stdout' | 'stderr'): ProviderSessionEvent {
const parsedJson = this.tryParseJson(line);
if (parsedJson !== null) {
return {
timestamp: new Date().toISOString(),
channel: 'json',
data: parsedJson,
};
}
return {
timestamp: new Date().toISOString(),
channel,
message: line,
};
}
/**
* Runs a one-off CLI command and returns full stdout text on success.
*/
protected async runCommandForOutput(command: string, args: string[]): Promise<string> {
const child = spawn(command, args, {
stdio: ['ignore', 'pipe', 'pipe'],
cwd: process.cwd(),
env: process.env,
});
let stdout = '';
let stderr = '';
child.stdout?.on('data', (chunk) => {
stdout += chunk.toString();
});
child.stderr?.on('data', (chunk) => {
stderr += chunk.toString();
});
const closePromise = once(child, 'close');
const errorPromise = once(child, 'error').then(([error]) => {
throw error;
});
await Promise.race([closePromise, errorPromise]);
if ((child.exitCode ?? 1) !== 0) {
const message = stderr.trim() || `Command "${command}" failed with code ${child.exitCode}`;
throw new Error(message);
}
return stdout;
}
/**
* Boots one CLI child process and wires stream handlers to the session buffer.
*/
private async startSessionInternal(input: CreateCliInvocationInput): Promise<ProviderSessionSnapshot> {
const session = this.createSessionRecord(input.sessionId, {
model: input.model,
thinkingMode: input.thinkingMode,
});
const invocation = this.createCliInvocation(input);
const child = spawn(invocation.command, invocation.args, {
cwd: invocation.cwd ?? input.workspacePath ?? process.cwd(),
env: {
...process.env,
...invocation.env,
},
stdio: ['ignore', 'pipe', 'pipe'],
}) as ChildProcessWithoutNullStreams;
const stop = async (): Promise<boolean> => this.terminateChildProcess(child);
session.stop = stop;
const stdoutAccumulator = createStreamLineAccumulator({ preserveEmptyLines: false });
const stderrAccumulator = createStreamLineAccumulator({ preserveEmptyLines: false });
child.stdout.on('data', (chunk) => {
const lines = stdoutAccumulator.push(chunk);
for (const line of lines) {
const event = this.mapCliOutputLine(line, 'stdout');
this.appendEvent(session, event);
}
});
child.stderr.on('data', (chunk) => {
const lines = stderrAccumulator.push(chunk);
for (const line of lines) {
const event = this.mapCliOutputLine(line, 'stderr');
this.appendEvent(session, event);
}
});
session.completion = this.waitForCliProcess(
session,
child,
stdoutAccumulator,
stderrAccumulator,
);
return this.toSnapshot(session);
}
/**
* Waits for process completion/error and marks final session status.
*/
private async waitForCliProcess(
session: MutableProviderSession,
child: ChildProcessWithoutNullStreams,
stdoutAccumulator: { flush: () => string[] },
stderrAccumulator: { flush: () => string[] },
): Promise<void> {
const closePromise = once(child, 'close') as Promise<[number | null, NodeJS.Signals | null]>;
const errorPromise = once(child, 'error') as Promise<[Error]>;
const raceResult = await Promise.race([
closePromise.then((result) => ({ type: 'close' as const, result })),
errorPromise.then((result) => ({ type: 'error' as const, result })),
]);
const pendingStdout = stdoutAccumulator.flush();
const pendingStderr = stderrAccumulator.flush();
for (const line of pendingStdout) {
this.appendEvent(session, this.mapCliOutputLine(line, 'stdout'));
}
for (const line of pendingStderr) {
this.appendEvent(session, this.mapCliOutputLine(line, 'stderr'));
}
if (raceResult.type === 'error') {
const [error] = raceResult.result;
const message = error.message || 'CLI process failed before start.';
this.updateSessionStatus(session, 'failed', message);
this.appendEvent(session, {
timestamp: new Date().toISOString(),
channel: 'error',
message,
});
return;
}
const [code, signal] = raceResult.result;
if (session.status === 'stopped') {
this.appendEvent(session, {
timestamp: new Date().toISOString(),
channel: 'system',
message: `Session stopped (${signal ?? 'SIGTERM'}).`,
});
return;
}
if (code === 0) {
this.updateSessionStatus(session, 'completed');
this.appendEvent(session, {
timestamp: new Date().toISOString(),
channel: 'system',
message: 'Session completed.',
data: {
sessionId: session.sessionId,
sessionStatus: 'COMPLETED',
},
});
return;
}
const message = `CLI command exited with code ${code ?? 'null'}${signal ? ` (signal: ${signal})` : ''}`;
this.updateSessionStatus(session, 'failed', message);
this.appendEvent(session, {
timestamp: new Date().toISOString(),
channel: 'error',
message,
});
}
/**
* Attempts graceful termination first, then force-kills when necessary.
*/
private async terminateChildProcess(child: ChildProcessWithoutNullStreams): Promise<boolean> {
if (child.killed || child.exitCode !== null) {
return true;
}
try {
child.kill('SIGTERM');
await Promise.race([
once(child, 'close'),
new Promise((resolve) => setTimeout(resolve, PROCESS_SHUTDOWN_GRACE_PERIOD_MS)),
]);
if (child.exitCode === null) {
child.kill('SIGKILL');
}
return true;
} catch {
return false;
}
}
/**
* Best-effort JSON parser for stream-json providers.
*/
private tryParseJson(line: string): unknown | null {
const trimmed = line.trim();
if (!trimmed || (!trimmed.startsWith('{') && !trimmed.startsWith('['))) {
return null;
}
try {
return JSON.parse(trimmed);
} catch {
return null;
}
}
}

View File

@@ -1,151 +0,0 @@
import { randomUUID } from 'node:crypto';
import { AbstractProvider } from '@/modules/ai-runtime/providers/base/abstract.provider.js';
import type {
MutableProviderSession,
ProviderCapabilities,
ProviderSessionEvent,
ProviderSessionSnapshot,
StartSessionInput,
} from '@/modules/ai-runtime/types/index.js';
import type { LLMProvider } from '@/shared/types/app.js';
type CreateSdkExecutionInput = StartSessionInput & {
sessionId: string;
isResume: boolean;
emitEvent?: (event: ProviderSessionEvent) => void;
};
type SdkExecution = {
stream: AsyncIterable<unknown>;
stop: () => Promise<boolean>;
};
/**
* Base class for SDK-driven providers with async stream consumption.
*/
export abstract class BaseSdkProvider extends AbstractProvider {
protected constructor(providerId: LLMProvider, capabilities: ProviderCapabilities) {
super(providerId, 'sdk', capabilities);
}
/**
* Starts a new SDK session and begins event streaming.
*/
async launchSession(input: StartSessionInput): Promise<ProviderSessionSnapshot> {
return this.startSessionInternal({
...input,
sessionId: input.sessionId ?? randomUUID(),
isResume: false,
});
}
/**
* Resumes an existing SDK session and begins event streaming.
*/
async resumeSession(input: StartSessionInput & { sessionId: string }): Promise<ProviderSessionSnapshot> {
return this.startSessionInternal({
...input,
isResume: true,
});
}
/**
* Implemented by concrete SDK providers to create a running execution.
*/
protected abstract createSdkExecution(input: CreateSdkExecutionInput): Promise<SdkExecution>;
/**
* Normalizes raw SDK events to the shared event shape.
*/
protected mapSdkEvent(rawEvent: unknown): ProviderSessionEvent | null {
return {
timestamp: new Date().toISOString(),
channel: 'sdk',
data: rawEvent,
};
}
/**
* Initializes one SDK execution and wires it to the internal session record.
*/
private async startSessionInternal(input: CreateSdkExecutionInput): Promise<ProviderSessionSnapshot> {
const session = this.createSessionRecord(input.sessionId, {
model: input.model,
thinkingMode: input.thinkingMode,
});
let execution: SdkExecution;
try {
execution = await this.createSdkExecution({
...input,
emitEvent: (event) => {
this.appendEvent(session, event);
},
});
} catch (error) {
const message = error instanceof Error ? error.message : 'Failed to start SDK session';
this.updateSessionStatus(session, 'failed', message);
this.appendEvent(session, {
timestamp: new Date().toISOString(),
channel: 'error',
message,
});
throw error;
}
session.stop = execution.stop;
session.completion = this.consumeStream(session, execution.stream);
return this.toSnapshot(session);
}
/**
* Drains SDK events until completion/error and updates final status.
*/
private async consumeStream(
session: MutableProviderSession,
stream: AsyncIterable<unknown>,
): Promise<void> {
try {
for await (const sdkEvent of stream) {
const normalized = this.mapSdkEvent(sdkEvent);
if (normalized) {
this.appendEvent(session, normalized);
}
}
// after stream completion, only update status if not already stopped by user
if (session.status === 'running') {
this.updateSessionStatus(session, 'completed');
this.appendEvent(session, {
timestamp: new Date().toISOString(),
channel: 'system',
message: 'Session completed.',
data: {
sessionId: session.sessionId,
sessionStatus: 'COMPLETED',
},
});
}
} catch (error) {
const message = error instanceof Error ? error.message : 'Unknown SDK execution failure';
if (session.status === 'stopped') {
this.appendEvent(session, {
timestamp: new Date().toISOString(),
channel: 'system',
message: 'Session stopped.',
});
return;
}
this.updateSessionStatus(session, 'failed', message);
this.appendEvent(session, {
timestamp: new Date().toISOString(),
channel: 'error',
message,
});
}
}
}

View File

@@ -1,120 +0,0 @@
import os from 'node:os';
import path from 'node:path';
import { readFile } from 'node:fs/promises';
import type { IProviderAuthRuntime, ProviderAuthStatus } from '@/modules/ai-runtime/types/index.js';
type ClaudeCredentialsFile = {
email?: string;
user?: string;
claudeAiOauth?: {
accessToken?: string;
expiresAt?: number | string;
};
};
/**
* Reads auth status for Claude from env/settings and OAuth credentials.
*/
export class ClaudeAuthRuntime implements IProviderAuthRuntime {
async getStatus(): Promise<ProviderAuthStatus> {
try {
if (process.env.ANTHROPIC_API_KEY?.trim()) {
return {
provider: 'claude',
authenticated: true,
email: 'API Key Auth',
method: 'api_key',
};
}
const settingsEnv = await this.loadClaudeSettingsEnv();
if (settingsEnv.ANTHROPIC_API_KEY?.trim()) {
return {
provider: 'claude',
authenticated: true,
email: 'API Key Auth',
method: 'api_key',
};
}
if (settingsEnv.ANTHROPIC_AUTH_TOKEN?.trim()) {
return {
provider: 'claude',
authenticated: true,
email: 'Configured via settings.json',
method: 'api_key',
};
}
const credentialsPath = path.join(os.homedir(), '.claude', '.credentials.json');
const content = await readFile(credentialsPath, 'utf8');
const credentials = JSON.parse(content) as ClaudeCredentialsFile;
const oauth = credentials.claudeAiOauth;
const accessToken = oauth?.accessToken;
if (accessToken && !this.isExpired(oauth?.expiresAt)) {
return {
provider: 'claude',
authenticated: true,
email: credentials.email ?? credentials.user ?? null,
method: 'credentials_file',
};
}
return {
provider: 'claude',
authenticated: false,
email: null,
method: null,
error: 'Not authenticated',
};
} catch {
return {
provider: 'claude',
authenticated: false,
email: null,
method: null,
error: 'Not authenticated',
};
}
}
/**
* Reads optional env values from ~/.claude/settings.json.
*/
private async loadClaudeSettingsEnv(): Promise<Record<string, string>> {
try {
const settingsPath = path.join(os.homedir(), '.claude', 'settings.json');
const content = await readFile(settingsPath, 'utf8');
const settings = JSON.parse(content) as { env?: unknown };
if (!settings.env || typeof settings.env !== 'object') {
return {};
}
return Object.fromEntries(
Object.entries(settings.env as Record<string, unknown>).filter(
(entry): entry is [string, string] => typeof entry[1] === 'string',
),
);
} catch {
return {};
}
}
/**
* Returns true when an OAuth expiration timestamp is in the past.
*/
private isExpired(expiresAt: number | string | undefined): boolean {
if (expiresAt === undefined) {
return false;
}
if (typeof expiresAt === 'number') {
return Date.now() >= expiresAt;
}
const numeric = Number.parseInt(expiresAt, 10);
return Number.isFinite(numeric) ? Date.now() >= numeric : false;
}
}

View File

@@ -1,154 +0,0 @@
import os from 'node:os';
import path from 'node:path';
import { AppError } from '@/shared/utils/app-error.js';
import type {
McpScope,
ProviderMcpServer,
UpsertProviderMcpServerInput,
} from '@/modules/ai-runtime/types/index.js';
import { BaseProviderMcpRuntime } from '@/modules/ai-runtime/providers/shared/mcp/base-provider-mcp.runtime.js';
import {
readJsonConfig,
readObjectRecord,
readOptionalString,
readStringArray,
readStringRecord,
writeJsonConfig,
} from '@/modules/ai-runtime/providers/shared/mcp/mcp-runtime.utils.js';
/**
* Claude MCP runtime backed by `~/.claude.json` and project `.mcp.json`.
*/
export class ClaudeMcpRuntime extends BaseProviderMcpRuntime {
constructor() {
super('claude', ['user', 'local', 'project'], ['stdio', 'http', 'sse']);
}
/**
* Reads Claude MCP servers from user/local/project config locations.
*/
protected async readScopedServers(scope: McpScope, workspacePath: string): Promise<Record<string, unknown>> {
if (scope === 'project') {
const filePath = path.join(workspacePath, '.mcp.json');
const config = await readJsonConfig(filePath);
return readObjectRecord(config.mcpServers) ?? {};
}
const filePath = path.join(os.homedir(), '.claude.json');
const config = await readJsonConfig(filePath);
if (scope === 'user') {
return readObjectRecord(config.mcpServers) ?? {};
}
const projects = readObjectRecord(config.projects) ?? {};
const projectConfig = readObjectRecord(projects[workspacePath]) ?? {};
return readObjectRecord(projectConfig.mcpServers) ?? {};
}
/**
* Writes Claude MCP servers to user/local/project config locations.
*/
protected async writeScopedServers(
scope: McpScope,
workspacePath: string,
servers: Record<string, unknown>,
): Promise<void> {
if (scope === 'project') {
const filePath = path.join(workspacePath, '.mcp.json');
const config = await readJsonConfig(filePath);
config.mcpServers = servers;
await writeJsonConfig(filePath, config);
return;
}
const filePath = path.join(os.homedir(), '.claude.json');
const config = await readJsonConfig(filePath);
if (scope === 'user') {
config.mcpServers = servers;
await writeJsonConfig(filePath, config);
return;
}
const projects = readObjectRecord(config.projects) ?? {};
const projectConfig = readObjectRecord(projects[workspacePath]) ?? {};
projectConfig.mcpServers = servers;
projects[workspacePath] = projectConfig;
config.projects = projects;
await writeJsonConfig(filePath, config);
}
/**
* Builds one Claude-native server object from the unified input payload.
*/
protected buildServerConfig(input: UpsertProviderMcpServerInput): Record<string, unknown> {
if (input.transport === 'stdio') {
if (!input.command?.trim()) {
throw new AppError('command is required for stdio MCP servers.', {
code: 'MCP_COMMAND_REQUIRED',
statusCode: 400,
});
}
return {
type: 'stdio',
command: input.command,
args: input.args ?? [],
env: input.env ?? {},
};
}
if (!input.url?.trim()) {
throw new AppError('url is required for http/sse MCP servers.', {
code: 'MCP_URL_REQUIRED',
statusCode: 400,
});
}
return {
type: input.transport,
url: input.url,
headers: input.headers ?? {},
};
}
/**
* Normalizes one Claude server object.
*/
protected normalizeServerConfig(
scope: McpScope,
name: string,
rawConfig: unknown,
): ProviderMcpServer | null {
if (!rawConfig || typeof rawConfig !== 'object') {
return null;
}
const config = rawConfig as Record<string, unknown>;
if (typeof config.command === 'string') {
return {
provider: 'claude',
name,
scope,
transport: 'stdio',
command: config.command,
args: readStringArray(config.args),
env: readStringRecord(config.env),
};
}
if (typeof config.url === 'string') {
const transport = readOptionalString(config.type) === 'sse' ? 'sse' : 'http';
return {
provider: 'claude',
name,
scope,
transport,
url: config.url,
headers: readStringRecord(config.headers),
};
}
return null;
}
}

View File

@@ -1,112 +0,0 @@
import os from 'node:os';
import path from 'node:path';
import { sessionsDb } from '@/shared/database/repositories/sessions.db.js';
import {
buildLookupMap,
extractFirstValidJsonlData,
findFilesRecursivelyCreatedAfter,
normalizeSessionName,
readFileTimestamps,
} from '@/modules/ai-runtime/providers/shared/session-synchronizer/session-synchronizer.utils.js';
import type { IProviderSessionSynchronizerRuntime } from '@/modules/ai-runtime/types/index.js';
type ParsedSession = {
sessionId: string;
workspacePath: string;
sessionName?: string;
};
/**
* Session indexer for Claude transcript artifacts.
*/
export class ClaudeSessionSynchronizerRuntime implements IProviderSessionSynchronizerRuntime {
private readonly provider = 'claude' as const;
private readonly claudeHome = path.join(os.homedir(), '.claude');
/**
* Scans ~/.claude projects and upserts discovered sessions into DB.
*/
async synchronize(since?: Date): Promise<number> {
const nameMap = await buildLookupMap(path.join(this.claudeHome, 'history.jsonl'), 'sessionId', 'display');
const files = await findFilesRecursivelyCreatedAfter(
path.join(this.claudeHome, 'projects'),
'.jsonl',
since ?? null,
);
let processed = 0;
for (const filePath of files) {
const parsed = await this.processSessionFile(filePath, nameMap);
if (!parsed) {
continue;
}
const timestamps = await readFileTimestamps(filePath);
sessionsDb.createSession(
parsed.sessionId,
this.provider,
parsed.workspacePath,
parsed.sessionName,
timestamps.createdAt,
timestamps.updatedAt,
filePath,
);
processed += 1;
}
return processed;
}
/**
* Parses and upserts one Claude session JSONL file.
*/
async synchronizeFile(filePath: string): Promise<boolean> {
if (!filePath.endsWith('.jsonl')) {
return false;
}
const nameMap = await buildLookupMap(path.join(this.claudeHome, 'history.jsonl'), 'sessionId', 'display');
const parsed = await this.processSessionFile(filePath, nameMap);
if (!parsed) {
return false;
}
const timestamps = await readFileTimestamps(filePath);
sessionsDb.createSession(
parsed.sessionId,
this.provider,
parsed.workspacePath,
parsed.sessionName,
timestamps.createdAt,
timestamps.updatedAt,
filePath,
);
return true;
}
/**
* Extracts session metadata from one Claude JSONL session file.
*/
private async processSessionFile(
filePath: string,
nameMap: Map<string, string>,
): Promise<ParsedSession | null> {
return extractFirstValidJsonlData(filePath, (rawData) => {
const data = rawData as Record<string, unknown>;
const sessionId = typeof data.sessionId === 'string' ? data.sessionId : undefined;
const workspacePath = typeof data.cwd === 'string' ? data.cwd : undefined;
if (!sessionId || !workspacePath) {
return null;
}
return {
sessionId,
workspacePath,
sessionName: normalizeSessionName(nameMap.get(sessionId), 'Untitled Claude Session'),
};
});
}
}

View File

@@ -1,133 +0,0 @@
import { readFile } from 'node:fs/promises';
import os from 'node:os';
import path from 'node:path';
import type { IProviderSkillsRuntime, ProviderSkill } from '@/modules/ai-runtime/types/index.js';
import { deduplicateSkills, listSkillsFromDirectory } from '@/modules/ai-runtime/providers/shared/skills/skills-runtime.utils.js';
/**
* Claude skills runtime backed by user/project/plugin skill directories.
*/
export class ClaudeSkillsRuntime implements IProviderSkillsRuntime {
/**
* Lists all available Claude skills from user/project/plugin locations.
*/
async listSkills(options?: { workspacePath?: string }): Promise<ProviderSkill[]> {
const workspacePath = path.resolve(options?.workspacePath ?? process.cwd());
const home = os.homedir();
const skills: ProviderSkill[] = [];
skills.push(
...(await listSkillsFromDirectory({
provider: 'claude',
scope: 'user',
skillsDirectory: path.join(home, '.claude', 'skills'),
invocationPrefix: '/',
})),
);
skills.push(
...(await listSkillsFromDirectory({
provider: 'claude',
scope: 'project',
skillsDirectory: path.join(workspacePath, '.claude', 'skills'),
invocationPrefix: '/',
})),
);
const enabledPlugins = await this.readClaudeEnabledPlugins();
if (!enabledPlugins.length) {
return skills;
}
const installedPluginIndex = await this.readClaudeInstalledPluginIndex();
for (const pluginId of enabledPlugins) {
const pluginInstalls = installedPluginIndex[pluginId];
if (!Array.isArray(pluginInstalls)) {
continue;
}
const pluginNamespace = pluginId.split('@')[0] ?? pluginId;
for (const install of pluginInstalls) {
if (!install || typeof install !== 'object') {
continue;
}
const installPath = typeof (install as Record<string, unknown>).installPath === 'string'
? (install as Record<string, unknown>).installPath as string
: '';
if (!installPath) {
continue;
}
const pluginSkills = await listSkillsFromDirectory({
provider: 'claude',
scope: 'plugin',
skillsDirectory: path.join(installPath, 'skills'),
invocationPrefix: '/',
pluginName: pluginNamespace,
});
for (const skill of pluginSkills) {
skill.invocation = `/${pluginNamespace}:${skill.name}`;
skill.pluginName = pluginNamespace;
}
skills.push(...pluginSkills);
}
}
return deduplicateSkills(skills);
}
/**
* Reads Claude enabled plugin map from `~/.claude/settings.json`.
*/
private async readClaudeEnabledPlugins(): Promise<string[]> {
const settingsPath = path.join(os.homedir(), '.claude', 'settings.json');
try {
const settingsContent = await readFile(settingsPath, 'utf8');
const settings = JSON.parse(settingsContent) as Record<string, unknown>;
const enabledPlugins = settings.enabledPlugins;
if (!enabledPlugins || typeof enabledPlugins !== 'object' || Array.isArray(enabledPlugins)) {
return [];
}
const enabledRecords = enabledPlugins as Record<string, unknown>;
return Object.entries(enabledRecords)
.filter(([, enabled]) => enabled === true)
.map(([pluginId]) => pluginId);
} catch (error) {
if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
return [];
}
throw error;
}
}
/**
* Reads Claude installed plugin index from `~/.claude/plugins/installed_plugins.json`.
*/
private async readClaudeInstalledPluginIndex(): Promise<Record<string, unknown[]>> {
const pluginIndexPath = path.join(os.homedir(), '.claude', 'plugins', 'installed_plugins.json');
try {
const indexContent = await readFile(pluginIndexPath, 'utf8');
const index = JSON.parse(indexContent) as Record<string, unknown>;
const plugins = index.plugins;
if (!plugins || typeof plugins !== 'object' || Array.isArray(plugins)) {
return {};
}
const normalized: Record<string, unknown[]> = {};
for (const [pluginId, entries] of Object.entries(plugins as Record<string, unknown>)) {
normalized[pluginId] = Array.isArray(entries) ? entries : [];
}
return normalized;
} catch (error) {
if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
return {};
}
throw error;
}
}
}

View File

@@ -1,325 +0,0 @@
import {
query,
type CanUseTool,
type ModelInfo,
type Options,
} from '@anthropic-ai/claude-agent-sdk';
import path from 'node:path';
import { readFile } from 'node:fs/promises';
import { BaseSdkProvider } from '@/modules/ai-runtime/providers/base/base-sdk.provider.js';
import type {
IProviderAuthRuntime,
IProviderMcpRuntime,
IProviderSessionSynchronizerRuntime,
IProviderSkillsRuntime,
ProviderModel,
ProviderSessionEvent,
RuntimePermissionMode,
StartSessionInput,
} from '@/modules/ai-runtime/types/index.js';
import { ClaudeMcpRuntime } from '@/modules/ai-runtime/providers/claude/claude-mcp.runtime.js';
import { ClaudeAuthRuntime } from '@/modules/ai-runtime/providers/claude/claude-auth.runtime.js';
import { ClaudeSkillsRuntime } from '@/modules/ai-runtime/providers/claude/claude-skills.runtime.js';
import { ClaudeSessionSynchronizerRuntime } from '@/modules/ai-runtime/providers/claude/claude-session-synchronizer.runtime.js';
type ClaudeExecutionInput = StartSessionInput & {
sessionId: string;
isResume: boolean;
emitEvent?: (event: ProviderSessionEvent) => void;
};
const CLAUDE_THINKING_LEVELS = new Set(['low', 'medium', 'high', 'max']);
const SUPPORTED_CLAUDE_IMAGE_TYPES = new Map<string, 'image/jpeg' | 'image/png' | 'image/gif' | 'image/webp'>([
['.jpg', 'image/jpeg'],
['.jpeg', 'image/jpeg'],
['.png', 'image/png'],
['.gif', 'image/gif'],
['.webp', 'image/webp'],
]);
type ClaudeUserPromptMessage = {
type: 'user';
message: {
role: 'user';
content: Array<
| {
type: 'text';
text: string;
}
| {
type: 'image';
source: {
type: 'base64';
media_type: 'image/jpeg' | 'image/png' | 'image/gif' | 'image/webp';
data: string;
};
}
>;
};
parent_tool_use_id: null;
timestamp: string;
};
/**
* Safely reads one optional string value from unknown data.
*/
const readString = (value: unknown): string | undefined => {
if (typeof value !== 'string') {
return undefined;
}
const normalized = value.trim();
return normalized.length ? normalized : undefined;
};
/**
* Claude SDK provider implementation.
*/
export class ClaudeProvider extends BaseSdkProvider {
readonly auth: IProviderAuthRuntime = new ClaudeAuthRuntime();
readonly mcp: IProviderMcpRuntime = new ClaudeMcpRuntime();
readonly skills: IProviderSkillsRuntime = new ClaudeSkillsRuntime();
readonly sessionSynchronizer: IProviderSessionSynchronizerRuntime = new ClaudeSessionSynchronizerRuntime();
constructor() {
super('claude', {
supportsRuntimePermissionRequests: true,
supportsThinkingModeControl: true,
});
}
/**
* Retrieves available Claude models from the SDK.
*/
async listModels(): Promise<ProviderModel[]> {
const probe = query({
prompt: 'model_probe',
options: {
permissionMode: 'plan',
},
});
try {
const models = await probe.supportedModels();
return models.map((model) => this.mapModelInfo(model));
} finally {
probe.close();
}
}
/**
* Creates a Claude SDK query execution for start/resume flows.
*/
protected async createSdkExecution(input: ClaudeExecutionInput): Promise<{
stream: AsyncIterable<unknown>;
stop: () => Promise<boolean>;
}> {
const options: Options = {
cwd: input.workspacePath,
model: input.model,
effort: this.resolveClaudeEffort(input.thinkingMode),
canUseTool: this.resolvePermissionHandler(input.runtimePermissionMode, input.emitEvent),
};
if (input.isResume) {
options.resume = input.sessionId;
} else {
options.sessionId = input.sessionId;
}
const promptInput = await this.buildPromptInput(input.prompt, input.imagePaths, input.workspacePath);
const queryInstance = query({
prompt: promptInput as any,
options,
});
return {
stream: queryInstance,
stop: async () => {
await queryInstance.interrupt();
return true;
},
};
}
/**
* Builds a Claude prompt payload. When images are present, this returns an async iterable user message.
*/
private async buildPromptInput(
prompt: string,
imagePaths?: string[],
workspacePath?: string,
): Promise<string | AsyncIterable<ClaudeUserPromptMessage>> {
if (!imagePaths || imagePaths.length === 0) {
return prompt;
}
const content: ClaudeUserPromptMessage['message']['content'] = [
{ type: 'text', text: prompt },
];
for (const imagePath of imagePaths) {
const resolvedPath = path.isAbsolute(imagePath)
? imagePath
: path.resolve(workspacePath ?? process.cwd(), imagePath);
const extension = path.extname(resolvedPath).toLowerCase();
const mediaType = SUPPORTED_CLAUDE_IMAGE_TYPES.get(extension);
if (!mediaType) {
continue;
}
const imageBytes = await readFile(resolvedPath);
content.push({
type: 'image',
source: {
type: 'base64',
media_type: mediaType,
data: imageBytes.toString('base64'),
},
});
}
const sdkPrompt = (async function* (): AsyncIterable<ClaudeUserPromptMessage> {
yield {
type: 'user',
message: {
role: 'user',
content,
},
parent_tool_use_id: null,
timestamp: new Date().toISOString(),
};
})();
return sdkPrompt;
}
/**
* Produces compact event metadata for frontend stream rendering.
*/
protected mapSdkEvent(rawEvent: unknown): ProviderSessionEvent | null {
if (typeof rawEvent !== 'object' || rawEvent === null) {
return {
timestamp: new Date().toISOString(),
channel: 'sdk',
message: String(rawEvent),
};
}
const messageType = this.getStringProperty(rawEvent, 'type');
const messageSubtype = this.getStringProperty(rawEvent, 'subtype');
const message = [messageType, messageSubtype].filter(Boolean).join(':') || 'claude_event';
return {
timestamp: new Date().toISOString(),
channel: 'sdk',
message,
data: rawEvent,
};
}
/**
* Normalizes Claude model metadata to the shared model shape.
*/
private mapModelInfo(model: ModelInfo): ProviderModel {
return {
value: model.value,
displayName: model.displayName,
description: model.description,
supportsThinkingModes: Boolean(model.supportsEffort),
supportedThinkingModes: model.supportedEffortLevels,
};
}
/**
* Maps requested thinking mode to Claude effort levels.
*/
private resolveClaudeEffort(thinkingMode?: string): Options['effort'] {
if (!thinkingMode) {
return 'high';
}
const normalized = thinkingMode.trim().toLowerCase();
if (CLAUDE_THINKING_LEVELS.has(normalized)) {
return normalized as Options['effort'];
}
return 'high';
}
/**
* Builds a runtime permission callback when explicit allow/deny is requested.
*/
private resolvePermissionHandler(
mode?: RuntimePermissionMode,
emitEvent?: (event: ProviderSessionEvent) => void,
): CanUseTool | undefined {
if (!mode || mode === 'ask') {
return undefined;
}
if (mode === 'allow') {
return async (toolName, input, options) => {
const optionsRecord = options as Record<string, unknown>;
emitEvent?.({
timestamp: new Date().toISOString(),
channel: 'system',
message: `Tool permission requested for "${toolName}".`,
data: {
type: 'tool_use_request',
toolName,
input,
toolUseID: options.toolUseID,
title: readString(optionsRecord.title),
displayName: readString(optionsRecord.displayName),
description: readString(optionsRecord.description),
blockedPath: options.blockedPath,
},
});
return { behavior: 'allow' };
};
}
return async (toolName, input, options) => {
const optionsRecord = options as Record<string, unknown>;
emitEvent?.({
timestamp: new Date().toISOString(),
channel: 'system',
message: `Tool permission denied for "${toolName}".`,
data: {
type: 'tool_use_request',
toolName,
input,
toolUseID: options.toolUseID,
title: readString(optionsRecord.title),
displayName: readString(optionsRecord.displayName),
description: readString(optionsRecord.description),
blockedPath: options.blockedPath,
},
});
return {
behavior: 'deny',
message: 'Permission denied by runtime permission mode.',
interrupt: false,
};
};
}
/**
* Reads one optional string property from an unknown event object.
*/
private getStringProperty(value: unknown, key: string): string | undefined {
if (!value || typeof value !== 'object') {
return undefined;
}
const record = value as Record<string, unknown>;
const rawValue = record[key];
if (typeof rawValue !== 'string') {
return undefined;
}
return rawValue;
}
}

View File

@@ -1,88 +0,0 @@
import os from 'node:os';
import path from 'node:path';
import { readFile } from 'node:fs/promises';
import type { IProviderAuthRuntime, ProviderAuthStatus } from '@/modules/ai-runtime/types/index.js';
type CodexAuthFile = {
OPENAI_API_KEY?: string;
tokens?: {
id_token?: string;
access_token?: string;
};
};
/**
* Reads auth status from ~/.codex/auth.json.
*/
export class CodexAuthRuntime implements IProviderAuthRuntime {
async getStatus(): Promise<ProviderAuthStatus> {
try {
const authPath = path.join(os.homedir(), '.codex', 'auth.json');
const content = await readFile(authPath, 'utf8');
const auth = JSON.parse(content) as CodexAuthFile;
const tokens = auth.tokens ?? {};
if (tokens.id_token || tokens.access_token) {
return {
provider: 'codex',
authenticated: true,
email: this.extractEmail(tokens.id_token),
method: 'token_file',
};
}
if (auth.OPENAI_API_KEY?.trim()) {
return {
provider: 'codex',
authenticated: true,
email: 'API Key Auth',
method: 'api_key',
};
}
return {
provider: 'codex',
authenticated: false,
email: null,
method: null,
error: 'No valid tokens found',
};
} catch (error) {
const code = (error as NodeJS.ErrnoException)?.code;
return {
provider: 'codex',
authenticated: false,
email: null,
method: null,
error: code === 'ENOENT'
? 'Codex not configured'
: (error instanceof Error ? error.message : 'Failed to read Codex auth state'),
};
}
}
/**
* Best-effort id_token email extraction from JWT payload.
*/
private extractEmail(idToken: string | undefined): string {
if (!idToken) {
return 'Authenticated';
}
try {
const parts = idToken.split('.');
if (parts.length < 2) {
return 'Authenticated';
}
const payload = JSON.parse(Buffer.from(parts[1], 'base64url').toString('utf8')) as {
email?: string;
user?: string;
};
return payload.email ?? payload.user ?? 'Authenticated';
} catch {
return 'Authenticated';
}
}
}

View File

@@ -1,133 +0,0 @@
import os from 'node:os';
import path from 'node:path';
import { AppError } from '@/shared/utils/app-error.js';
import type {
McpScope,
ProviderMcpServer,
UpsertProviderMcpServerInput,
} from '@/modules/ai-runtime/types/index.js';
import { BaseProviderMcpRuntime } from '@/modules/ai-runtime/providers/shared/mcp/base-provider-mcp.runtime.js';
import {
readObjectRecord,
readOptionalString,
readStringArray,
readStringRecord,
readTomlConfig,
writeTomlConfig,
} from '@/modules/ai-runtime/providers/shared/mcp/mcp-runtime.utils.js';
/**
* Codex MCP runtime backed by user/project `.codex/config.toml`.
*/
export class CodexMcpRuntime extends BaseProviderMcpRuntime {
constructor() {
super('codex', ['user', 'project'], ['stdio', 'http']);
}
/**
* Reads Codex MCP servers from user/project config.toml scopes.
*/
protected async readScopedServers(scope: McpScope, workspacePath: string): Promise<Record<string, unknown>> {
const filePath = scope === 'user'
? path.join(os.homedir(), '.codex', 'config.toml')
: path.join(workspacePath, '.codex', 'config.toml');
const config = await readTomlConfig(filePath);
return readObjectRecord(config.mcp_servers) ?? {};
}
/**
* Writes Codex MCP servers to user/project config.toml scopes.
*/
protected async writeScopedServers(
scope: McpScope,
workspacePath: string,
servers: Record<string, unknown>,
): Promise<void> {
const filePath = scope === 'user'
? path.join(os.homedir(), '.codex', 'config.toml')
: path.join(workspacePath, '.codex', 'config.toml');
const config = await readTomlConfig(filePath);
config.mcp_servers = servers;
await writeTomlConfig(filePath, config);
}
/**
* Builds one Codex-native server object from the unified input payload.
*/
protected buildServerConfig(input: UpsertProviderMcpServerInput): Record<string, unknown> {
if (input.transport === 'stdio') {
if (!input.command?.trim()) {
throw new AppError('command is required for stdio MCP servers.', {
code: 'MCP_COMMAND_REQUIRED',
statusCode: 400,
});
}
return {
command: input.command,
args: input.args ?? [],
env: input.env ?? {},
env_vars: input.envVars ?? [],
cwd: input.cwd,
};
}
if (!input.url?.trim()) {
throw new AppError('url is required for http MCP servers.', {
code: 'MCP_URL_REQUIRED',
statusCode: 400,
});
}
return {
url: input.url,
bearer_token_env_var: input.bearerTokenEnvVar,
http_headers: input.headers ?? {},
env_http_headers: input.envHttpHeaders ?? {},
};
}
/**
* Normalizes one Codex server object.
*/
protected normalizeServerConfig(
scope: McpScope,
name: string,
rawConfig: unknown,
): ProviderMcpServer | null {
if (!rawConfig || typeof rawConfig !== 'object') {
return null;
}
const config = rawConfig as Record<string, unknown>;
if (typeof config.command === 'string') {
return {
provider: 'codex',
name,
scope,
transport: 'stdio',
command: config.command,
args: readStringArray(config.args),
env: readStringRecord(config.env),
cwd: readOptionalString(config.cwd),
envVars: readStringArray(config.env_vars),
};
}
if (typeof config.url === 'string') {
return {
provider: 'codex',
name,
scope,
transport: 'http',
url: config.url,
headers: readStringRecord(config.http_headers),
bearerTokenEnvVar: readOptionalString(config.bearer_token_env_var),
envHttpHeaders: readStringRecord(config.env_http_headers),
};
}
return null;
}
}

View File

@@ -1,113 +0,0 @@
import os from 'node:os';
import path from 'node:path';
import { sessionsDb } from '@/shared/database/repositories/sessions.db.js';
import {
buildLookupMap,
extractFirstValidJsonlData,
findFilesRecursivelyCreatedAfter,
normalizeSessionName,
readFileTimestamps,
} from '@/modules/ai-runtime/providers/shared/session-synchronizer/session-synchronizer.utils.js';
import type { IProviderSessionSynchronizerRuntime } from '@/modules/ai-runtime/types/index.js';
type ParsedSession = {
sessionId: string;
workspacePath: string;
sessionName?: string;
};
/**
* Session indexer for Codex transcript artifacts.
*/
export class CodexSessionSynchronizerRuntime implements IProviderSessionSynchronizerRuntime {
private readonly provider = 'codex' as const;
private readonly codexHome = path.join(os.homedir(), '.codex');
/**
* Scans ~/.codex sessions and upserts discovered sessions into DB.
*/
async synchronize(since?: Date): Promise<number> {
const nameMap = await buildLookupMap(path.join(this.codexHome, 'session_index.jsonl'), 'id', 'thread_name');
const files = await findFilesRecursivelyCreatedAfter(
path.join(this.codexHome, 'sessions'),
'.jsonl',
since ?? null,
);
let processed = 0;
for (const filePath of files) {
const parsed = await this.processSessionFile(filePath, nameMap);
if (!parsed) {
continue;
}
const timestamps = await readFileTimestamps(filePath);
sessionsDb.createSession(
parsed.sessionId,
this.provider,
parsed.workspacePath,
parsed.sessionName,
timestamps.createdAt,
timestamps.updatedAt,
filePath,
);
processed += 1;
}
return processed;
}
/**
* Parses and upserts one Codex session JSONL file.
*/
async synchronizeFile(filePath: string): Promise<boolean> {
if (!filePath.endsWith('.jsonl')) {
return false;
}
const nameMap = await buildLookupMap(path.join(this.codexHome, 'session_index.jsonl'), 'id', 'thread_name');
const parsed = await this.processSessionFile(filePath, nameMap);
if (!parsed) {
return false;
}
const timestamps = await readFileTimestamps(filePath);
sessionsDb.createSession(
parsed.sessionId,
this.provider,
parsed.workspacePath,
parsed.sessionName,
timestamps.createdAt,
timestamps.updatedAt,
filePath,
);
return true;
}
/**
* Extracts session metadata from one Codex JSONL session file.
*/
private async processSessionFile(
filePath: string,
nameMap: Map<string, string>,
): Promise<ParsedSession | null> {
return extractFirstValidJsonlData(filePath, (rawData) => {
const data = rawData as Record<string, unknown>;
const payload = data.payload as Record<string, unknown> | undefined;
const sessionId = typeof payload?.id === 'string' ? payload.id : undefined;
const workspacePath = typeof payload?.cwd === 'string' ? payload.cwd : undefined;
if (!sessionId || !workspacePath) {
return null;
}
return {
sessionId,
workspacePath,
sessionName: normalizeSessionName(nameMap.get(sessionId), 'Untitled Codex Session'),
};
});
}
}

Some files were not shown because too many files have changed in this diff Show More