@pixelbyte-software/pixcode 1.51.2 → 1.51.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (331) hide show
  1. package/CODE_OF_CONDUCT.md +41 -41
  2. package/CONTRIBUTING.md +155 -155
  3. package/LICENSE +718 -718
  4. package/README.de.md +169 -169
  5. package/README.ja.md +167 -167
  6. package/README.ko.md +167 -167
  7. package/README.md +419 -419
  8. package/README.ru.md +169 -169
  9. package/README.tr.md +298 -298
  10. package/README.zh-CN.md +167 -167
  11. package/SECURITY.md +46 -46
  12. package/dist/api-automation.html +110 -110
  13. package/dist/api-docs.html +548 -548
  14. package/dist/assets/index-B9N-gfOQ.css +32 -0
  15. package/dist/assets/{index-EN9ngyxf.js → index-HfGHXhD6.js} +175 -175
  16. package/dist/clear-cache.html +85 -85
  17. package/dist/convert-icons.md +52 -52
  18. package/dist/docs.html +308 -308
  19. package/dist/favicon.svg +8 -8
  20. package/dist/features.html +133 -133
  21. package/dist/generate-icons.js +48 -48
  22. package/dist/humans.txt +15 -15
  23. package/dist/icons/codex-white.svg +3 -3
  24. package/dist/icons/codex.svg +3 -3
  25. package/dist/icons/cursor-white.svg +11 -11
  26. package/dist/icons/icon-128x128.svg +9 -9
  27. package/dist/icons/icon-144x144.svg +9 -9
  28. package/dist/icons/icon-152x152.svg +9 -9
  29. package/dist/icons/icon-192x192.svg +9 -9
  30. package/dist/icons/icon-384x384.svg +9 -9
  31. package/dist/icons/icon-512x512.svg +9 -9
  32. package/dist/icons/icon-72x72.svg +9 -9
  33. package/dist/icons/icon-96x96.svg +9 -9
  34. package/dist/icons/icon-template.svg +9 -9
  35. package/dist/icons/qwen-logo.svg +14 -14
  36. package/dist/index.html +59 -59
  37. package/dist/landing.html +268 -268
  38. package/dist/llms-full.txt +119 -119
  39. package/dist/llms.txt +53 -53
  40. package/dist/logo.svg +12 -12
  41. package/dist/manifest.json +60 -60
  42. package/dist/openapi.yaml +1696 -1696
  43. package/dist/orchestration.html +125 -125
  44. package/dist/robots.txt +4 -4
  45. package/dist/site.css +692 -692
  46. package/dist/sitemap.xml +51 -51
  47. package/dist/sw.js +132 -132
  48. package/dist-server/server/cli.js +96 -96
  49. package/dist-server/server/daemon/manager.js +33 -33
  50. package/dist-server/server/daemon-manager.js +64 -64
  51. package/dist-server/server/database/db.js +14 -2
  52. package/dist-server/server/database/db.js.map +1 -1
  53. package/dist-server/server/index.js +191 -31
  54. package/dist-server/server/index.js.map +1 -1
  55. package/dist-server/server/middleware/auth.js +16 -5
  56. package/dist-server/server/middleware/auth.js.map +1 -1
  57. package/dist-server/server/modules/orchestration/a2a/adapters/json-event.adapter.js +84 -0
  58. package/dist-server/server/modules/orchestration/a2a/adapters/json-event.adapter.js.map +1 -0
  59. package/dist-server/server/modules/orchestration/a2a/adapters/json-event.adapter.test.js +43 -0
  60. package/dist-server/server/modules/orchestration/a2a/adapters/json-event.adapter.test.js.map +1 -0
  61. package/dist-server/server/modules/orchestration/hermes/hermes.routes.js +55 -1
  62. package/dist-server/server/modules/orchestration/hermes/hermes.routes.js.map +1 -1
  63. package/dist-server/server/modules/orchestration/index.js +1 -0
  64. package/dist-server/server/modules/orchestration/index.js.map +1 -1
  65. package/dist-server/server/routes/auth.js +12 -5
  66. package/dist-server/server/routes/auth.js.map +1 -1
  67. package/dist-server/server/routes/commands.js +25 -25
  68. package/dist-server/server/routes/git.js +29 -17
  69. package/dist-server/server/routes/git.js.map +1 -1
  70. package/dist-server/server/routes/live-view.js +46 -46
  71. package/dist-server/server/routes/platformization.js +7 -6
  72. package/dist-server/server/routes/platformization.js.map +1 -1
  73. package/dist-server/server/services/hermes-gateway.js +310 -0
  74. package/dist-server/server/services/hermes-gateway.js.map +1 -1
  75. package/dist-server/server/services/platformization.js +58 -2
  76. package/dist-server/server/services/platformization.js.map +1 -1
  77. package/dist-server/server/services/public-api-manifest.js +59 -51
  78. package/dist-server/server/services/public-api-manifest.js.map +1 -1
  79. package/package.json +222 -222
  80. package/scripts/fix-node-pty.js +67 -67
  81. package/scripts/github/create-v1.38-issues.mjs +351 -351
  82. package/scripts/github/create-vscode-workbench-issues.mjs +121 -121
  83. package/scripts/hermes/configure-pixcode-mcp.mjs +165 -163
  84. package/scripts/hermes/pixcode-mcp-server.mjs +1009 -958
  85. package/scripts/smoke/changes-panel-layout.mjs +48 -48
  86. package/scripts/smoke/chat-composer-fixed-layout.mjs +55 -55
  87. package/scripts/smoke/chat-message-timeline-order.mjs +41 -41
  88. package/scripts/smoke/chat-realtime-hydration.mjs +44 -44
  89. package/scripts/smoke/chat-session-provider-pools.mjs +35 -35
  90. package/scripts/smoke/chat-session-state.mjs +19 -19
  91. package/scripts/smoke/code-editor-theme.mjs +55 -55
  92. package/scripts/smoke/code-editor-vscode-engine.mjs +91 -91
  93. package/scripts/smoke/command-center-agent-writes.mjs +79 -79
  94. package/scripts/smoke/command-center-non-git.mjs +46 -46
  95. package/scripts/smoke/context-packet.mjs +43 -43
  96. package/scripts/smoke/control-room-ux-redesign.mjs +91 -91
  97. package/scripts/smoke/daemon-entrypoint.mjs +20 -20
  98. package/scripts/smoke/default-landing-routing.mjs +33 -33
  99. package/scripts/smoke/desktop-native-notifications.mjs +30 -30
  100. package/scripts/smoke/desktop-tray-icon.mjs +33 -33
  101. package/scripts/smoke/discord-release-workflow.mjs +24 -24
  102. package/scripts/smoke/git-install-update.mjs +255 -255
  103. package/scripts/smoke/handoff-artifact-protocol.mjs +50 -50
  104. package/scripts/smoke/hermes-api-install.mjs +56 -56
  105. package/scripts/smoke/hermes-gateway-persistence.mjs +104 -104
  106. package/scripts/smoke/hermes-mcp-pixcode-roundtrip.mjs +426 -367
  107. package/scripts/smoke/hermes-rest-chat-api.mjs +162 -162
  108. package/scripts/smoke/hermes-rest-chat-live.mjs +45 -45
  109. package/scripts/smoke/hermes-rest-codex-launch.mjs +209 -209
  110. package/scripts/smoke/hermes-rest-gateway.mjs +79 -70
  111. package/scripts/smoke/hermes-rest-live.mjs +42 -42
  112. package/scripts/smoke/hermes-roundtrip.mjs +167 -167
  113. package/scripts/smoke/hermes-settings-commands.mjs +349 -346
  114. package/scripts/smoke/hermes-smoke-launcher-guard.mjs +34 -34
  115. package/scripts/smoke/live-view-diagnostics.mjs +53 -53
  116. package/scripts/smoke/live-view-environment.mjs +92 -92
  117. package/scripts/smoke/live-view-integration.mjs +450 -450
  118. package/scripts/smoke/mac-desktop-runtime.mjs +37 -37
  119. package/scripts/smoke/mobile-tunnel-guidance.mjs +29 -29
  120. package/scripts/smoke/model-registry.mjs +36 -36
  121. package/scripts/smoke/multi-project-ui.mjs +45 -45
  122. package/scripts/smoke/multi-worker-slots.mjs +42 -42
  123. package/scripts/smoke/notification-center.mjs +87 -87
  124. package/scripts/smoke/notification-inapp-preference.mjs +23 -23
  125. package/scripts/smoke/notification-taxonomy.mjs +58 -58
  126. package/scripts/smoke/orchestration-api.mjs +172 -172
  127. package/scripts/smoke/orchestration-execution-dashboard.mjs +33 -33
  128. package/scripts/smoke/orchestration-live-run.mjs +176 -176
  129. package/scripts/smoke/orchestration-mobile-scroll.mjs +29 -29
  130. package/scripts/smoke/orchestration-model-sync.mjs +30 -30
  131. package/scripts/smoke/orchestration-permission-fallback.mjs +34 -34
  132. package/scripts/smoke/orchestration-runtime-guards.mjs +48 -48
  133. package/scripts/smoke/orchestration-user-facing-output.mjs +25 -25
  134. package/scripts/smoke/permission-policy.mjs +50 -50
  135. package/scripts/smoke/pixcode-workbench-1-48.mjs +167 -167
  136. package/scripts/smoke/provider-models-opencode-live.mjs +66 -66
  137. package/scripts/smoke/provider-rest-api.mjs +124 -124
  138. package/scripts/smoke/provider-selection-status.mjs +52 -52
  139. package/scripts/smoke/run-state-refresh.mjs +52 -52
  140. package/scripts/smoke/runtime-manager.mjs +99 -99
  141. package/scripts/smoke/shell-manual-disconnect.mjs +30 -30
  142. package/scripts/smoke/side-panel-editor-layout.mjs +34 -34
  143. package/scripts/smoke/static-root-routing.mjs +21 -21
  144. package/scripts/smoke/strict-handoff-compact.mjs +60 -60
  145. package/scripts/smoke/taskmaster-config.mjs +24 -24
  146. package/scripts/smoke/taskmaster-execution-telegram.mjs +3 -3
  147. package/scripts/smoke/taskmaster-onboarding.mjs +3 -3
  148. package/scripts/smoke/taskmaster-run-graph.mjs +3 -3
  149. package/scripts/smoke/telegram-control.mjs +242 -242
  150. package/scripts/smoke/tunnel-persistence.mjs +56 -56
  151. package/scripts/smoke/update-issue-progress.mjs +69 -69
  152. package/scripts/smoke/update-ux.mjs +55 -55
  153. package/scripts/smoke/v138-completion.mjs +132 -132
  154. package/scripts/smoke/v138-desktop-release-hardening.mjs +69 -69
  155. package/scripts/smoke/v138-diagnostics.mjs +63 -63
  156. package/scripts/smoke/v138-issue-planner.mjs +33 -33
  157. package/scripts/smoke/v143-remote-control.mjs +76 -76
  158. package/scripts/smoke/v144-production-loop.mjs +47 -47
  159. package/scripts/smoke/v145-platformization.mjs +46 -46
  160. package/scripts/smoke/v146-control-room-ui.mjs +150 -150
  161. package/scripts/smoke/version-modal-autoshow.mjs +29 -29
  162. package/scripts/smoke/vscode-workbench-layout.mjs +63 -63
  163. package/scripts/smoke/vscode-workbench-polish.mjs +461 -436
  164. package/scripts/smoke/workflow-fallback-replay.mjs +56 -56
  165. package/scripts/smoke/workflow-templates.mjs +43 -43
  166. package/scripts/smoke/workflow-trace-timeline.mjs +46 -46
  167. package/scripts/update-git-install.mjs +293 -293
  168. package/server/claude-sdk.js +920 -920
  169. package/server/cli.js +1039 -1039
  170. package/server/constants/config.js +4 -4
  171. package/server/cursor-cli.js +344 -344
  172. package/server/daemon/manager.js +563 -563
  173. package/server/daemon-manager.js +964 -964
  174. package/server/database/db.js +908 -895
  175. package/server/database/json-store.js +197 -197
  176. package/server/gemini-cli.js +550 -550
  177. package/server/gemini-response-handler.js +79 -79
  178. package/server/index.js +201 -30
  179. package/server/load-env.js +35 -35
  180. package/server/middleware/auth.js +171 -156
  181. package/server/modules/orchestration/a2a/adapter-registry.ts +108 -108
  182. package/server/modules/orchestration/a2a/adapters/abstract-a2a.adapter.ts +63 -63
  183. package/server/modules/orchestration/a2a/adapters/claude-code.adapter.ts +286 -286
  184. package/server/modules/orchestration/a2a/adapters/codex.adapter.ts +244 -244
  185. package/server/modules/orchestration/a2a/adapters/cursor.adapter.ts +249 -249
  186. package/server/modules/orchestration/a2a/adapters/gemini.adapter.ts +248 -248
  187. package/server/modules/orchestration/a2a/adapters/json-event.adapter.test.ts +60 -0
  188. package/server/modules/orchestration/a2a/adapters/json-event.adapter.ts +101 -0
  189. package/server/modules/orchestration/a2a/adapters/opencode.adapter.ts +248 -248
  190. package/server/modules/orchestration/a2a/adapters/qwen.adapter.ts +248 -248
  191. package/server/modules/orchestration/a2a/agent-card.ts +55 -55
  192. package/server/modules/orchestration/a2a/routes.ts +590 -590
  193. package/server/modules/orchestration/a2a/task-store.ts +178 -178
  194. package/server/modules/orchestration/a2a/types.ts +126 -126
  195. package/server/modules/orchestration/a2a/validator.ts +113 -113
  196. package/server/modules/orchestration/hermes/hermes.routes.ts +642 -583
  197. package/server/modules/orchestration/index.ts +101 -100
  198. package/server/modules/orchestration/preview/port-watcher.ts +112 -112
  199. package/server/modules/orchestration/preview/preview-proxy.ts +60 -60
  200. package/server/modules/orchestration/preview/types.ts +19 -19
  201. package/server/modules/orchestration/security/permission-policy.ts +401 -401
  202. package/server/modules/orchestration/tasks/orchestration-task-store.ts +41 -41
  203. package/server/modules/orchestration/tasks/orchestration-task.routes.ts +64 -64
  204. package/server/modules/orchestration/tasks/orchestration-task.service.ts +209 -209
  205. package/server/modules/orchestration/tasks/orchestration-task.types.ts +40 -40
  206. package/server/modules/orchestration/tasks/task-run-graph.ts +155 -155
  207. package/server/modules/orchestration/workflows/approval-queue.ts +106 -106
  208. package/server/modules/orchestration/workflows/built-in-workflows.ts +127 -127
  209. package/server/modules/orchestration/workflows/context-packet.ts +186 -186
  210. package/server/modules/orchestration/workflows/handoff-artifact.ts +175 -175
  211. package/server/modules/orchestration/workflows/workflow-fallback-policy.ts +161 -161
  212. package/server/modules/orchestration/workflows/workflow-replay.ts +254 -254
  213. package/server/modules/orchestration/workflows/workflow-runner.ts +2070 -2070
  214. package/server/modules/orchestration/workflows/workflow-store.ts +97 -97
  215. package/server/modules/orchestration/workflows/workflow-templates.ts +272 -272
  216. package/server/modules/orchestration/workflows/workflow-trace.ts +424 -424
  217. package/server/modules/orchestration/workflows/workflow.routes.ts +586 -586
  218. package/server/modules/orchestration/workflows/workflow.types.ts +111 -111
  219. package/server/modules/orchestration/workflows/workspace-target.ts +122 -122
  220. package/server/modules/orchestration/workspace/docker-workspace.ts +136 -136
  221. package/server/modules/orchestration/workspace/path-safety.ts +55 -55
  222. package/server/modules/orchestration/workspace/types.ts +52 -52
  223. package/server/modules/orchestration/workspace/workspace-manager.ts +102 -102
  224. package/server/modules/orchestration/workspace/worktree-workspace.ts +126 -126
  225. package/server/modules/providers/index.ts +2 -2
  226. package/server/modules/providers/list/claude/claude-auth.provider.ts +146 -146
  227. package/server/modules/providers/list/claude/claude-mcp.provider.ts +135 -135
  228. package/server/modules/providers/list/claude/claude-sessions.provider.ts +306 -306
  229. package/server/modules/providers/list/claude/claude.provider.ts +15 -15
  230. package/server/modules/providers/list/codex/codex-auth.provider.ts +117 -117
  231. package/server/modules/providers/list/codex/codex-mcp.provider.ts +135 -135
  232. package/server/modules/providers/list/codex/codex-sessions.provider.ts +319 -319
  233. package/server/modules/providers/list/codex/codex.provider.ts +15 -15
  234. package/server/modules/providers/list/cursor/cursor-auth.provider.ts +147 -147
  235. package/server/modules/providers/list/cursor/cursor-mcp.provider.ts +108 -108
  236. package/server/modules/providers/list/cursor/cursor-sessions.provider.ts +421 -421
  237. package/server/modules/providers/list/cursor/cursor.provider.ts +15 -15
  238. package/server/modules/providers/list/gemini/gemini-auth.provider.ts +173 -173
  239. package/server/modules/providers/list/gemini/gemini-mcp.provider.ts +110 -110
  240. package/server/modules/providers/list/gemini/gemini-sessions.provider.ts +227 -227
  241. package/server/modules/providers/list/gemini/gemini.provider.ts +15 -15
  242. package/server/modules/providers/list/opencode/opencode-auth.provider.ts +131 -131
  243. package/server/modules/providers/list/opencode/opencode-mcp.provider.ts +126 -126
  244. package/server/modules/providers/list/opencode/opencode-sessions.provider.ts +286 -286
  245. package/server/modules/providers/list/opencode/opencode.provider.ts +29 -29
  246. package/server/modules/providers/list/qwen/qwen-auth.provider.ts +146 -146
  247. package/server/modules/providers/list/qwen/qwen-mcp.provider.ts +114 -114
  248. package/server/modules/providers/list/qwen/qwen-sessions.provider.ts +265 -265
  249. package/server/modules/providers/list/qwen/qwen.provider.ts +21 -21
  250. package/server/modules/providers/provider.registry.ts +40 -40
  251. package/server/modules/providers/provider.routes.ts +944 -944
  252. package/server/modules/providers/services/mcp.service.ts +86 -86
  253. package/server/modules/providers/services/provider-auth.service.ts +26 -26
  254. package/server/modules/providers/services/sessions.service.ts +45 -45
  255. package/server/modules/providers/shared/base/abstract.provider.ts +20 -20
  256. package/server/modules/providers/shared/mcp/mcp.provider.ts +151 -151
  257. package/server/modules/providers/shared/provider-configs.ts +142 -142
  258. package/server/modules/providers/tests/mcp.test.ts +293 -293
  259. package/server/openai-codex.js +462 -462
  260. package/server/opencode-cli.js +491 -491
  261. package/server/opencode-response-handler.js +111 -111
  262. package/server/projects.js +3008 -3008
  263. package/server/qwen-code-cli.js +410 -410
  264. package/server/qwen-response-handler.js +73 -73
  265. package/server/routes/agent.js +1435 -1435
  266. package/server/routes/auth.js +154 -146
  267. package/server/routes/codex.js +20 -20
  268. package/server/routes/commands.js +570 -570
  269. package/server/routes/cursor.js +61 -61
  270. package/server/routes/diagnostics.js +41 -41
  271. package/server/routes/gemini.js +25 -25
  272. package/server/routes/git.js +1650 -1635
  273. package/server/routes/live-view.js +411 -411
  274. package/server/routes/mcp-utils.js +13 -13
  275. package/server/routes/messages.js +62 -62
  276. package/server/routes/network.js +125 -125
  277. package/server/routes/platformization.js +198 -197
  278. package/server/routes/plugins.js +320 -320
  279. package/server/routes/production-agent-loop.js +90 -90
  280. package/server/routes/projects.js +917 -917
  281. package/server/routes/public-api.js +34 -34
  282. package/server/routes/qwen.js +27 -27
  283. package/server/routes/remote.js +55 -55
  284. package/server/routes/settings.js +321 -321
  285. package/server/routes/telegram.js +140 -140
  286. package/server/routes/user.js +125 -125
  287. package/server/routes/webhooks.js +63 -63
  288. package/server/services/control-room.js +102 -102
  289. package/server/services/diagnostics.js +165 -165
  290. package/server/services/external-access.js +375 -375
  291. package/server/services/hermes-gateway.js +1562 -1247
  292. package/server/services/hermes-install-jobs.js +729 -729
  293. package/server/services/install-jobs.js +715 -715
  294. package/server/services/live-view.js +956 -956
  295. package/server/services/managed-runtimes.js +493 -493
  296. package/server/services/model-registry.js +144 -144
  297. package/server/services/notification-orchestrator.js +365 -365
  298. package/server/services/notification-taxonomy.js +204 -204
  299. package/server/services/platformization.js +844 -779
  300. package/server/services/production-agent-loop.js +248 -248
  301. package/server/services/provider-cli-versions.js +149 -149
  302. package/server/services/provider-credentials.js +189 -189
  303. package/server/services/provider-models.js +396 -396
  304. package/server/services/public-api-manifest.js +190 -182
  305. package/server/services/remote-connection.js +127 -127
  306. package/server/services/runtime-manager.js +323 -323
  307. package/server/services/startup-update.js +234 -234
  308. package/server/services/telegram/bot.js +331 -331
  309. package/server/services/telegram/control-center.js +979 -979
  310. package/server/services/telegram/telegram-http-client.js +151 -151
  311. package/server/services/telegram/translations.js +340 -340
  312. package/server/services/vapid-keys.js +36 -36
  313. package/server/services/webhooks.js +216 -216
  314. package/server/sessionManager.js +225 -225
  315. package/server/shared/interfaces.ts +54 -54
  316. package/server/shared/types.ts +172 -172
  317. package/server/shared/utils.ts +193 -193
  318. package/server/tsconfig.json +36 -36
  319. package/server/utils/colors.js +21 -21
  320. package/server/utils/commandParser.js +305 -305
  321. package/server/utils/frontmatter.js +18 -18
  322. package/server/utils/gitConfig.js +34 -34
  323. package/server/utils/plugin-loader.js +457 -457
  324. package/server/utils/plugin-process-manager.js +185 -185
  325. package/server/utils/port-access.js +209 -209
  326. package/server/utils/runtime-paths.js +37 -37
  327. package/server/utils/url-detection.js +71 -71
  328. package/server/vite-daemon.js +79 -79
  329. package/shared/modelConstants.js +161 -161
  330. package/shared/networkHosts.js +22 -22
  331. package/dist/assets/index-DMz0zv6T.css +0 -32
package/dist/openapi.yaml CHANGED
@@ -1,1696 +1,1696 @@
1
- openapi: 3.1.0
2
- info:
3
- title: Pixcode REST API
4
- version: 1.36.1
5
- description: |
6
- REST API for Pixcode — the multi-CLI web UI for Claude Code, Cursor CLI,
7
- Codex, Gemini CLI, Qwen Code, and OpenCode.
8
-
9
- ## Authentication
10
-
11
- Most endpoints require authentication. Two schemes are accepted:
12
-
13
- - **JWT cookie** (`token` HTTP-only cookie) — set automatically when the
14
- browser logs in via `POST /api/auth/login`.
15
- - **API key** (`Authorization: Bearer px_...`) — generated under
16
- Settings → API. API keys never expire and survive server restarts.
17
- Legacy `ck_...` keys remain accepted for older installations.
18
-
19
- Endpoints flagged `apiKey` accept both.
20
-
21
- ## Streaming endpoints
22
-
23
- Three classes of endpoint stream beyond plain JSON:
24
-
25
- - **WebSocket** (`/ws`, `/shell`) — chat session bidirectional traffic. Not
26
- documented here; see `docs/websocket-protocol.md` if it exists, or read
27
- `server/index.js` `handleChatConnection`.
28
- - **SSE** (Server-Sent Events) — long-running jobs. Each `data:` frame
29
- contains a JSON event; the stream ends with `event: done` or `event: error`.
30
- - **NDJSON** — provider chat output (one JSON event per line) when the
31
- backend forwards from a CLI's `--format json` mode.
32
-
33
- ## Errors
34
-
35
- Errors share a consistent envelope:
36
-
37
- ```json
38
- { "success": false, "error": { "code": "ROUTE_NOT_FOUND", "message": "..." } }
39
- ```
40
-
41
- contact:
42
- name: Pixcode on GitHub
43
- url: https://github.com/alicomert/pixcode
44
- license:
45
- name: AGPL-3.0-or-later
46
- url: https://www.gnu.org/licenses/agpl-3.0.txt
47
-
48
- servers:
49
- - url: http://localhost:3001
50
- description: Local development server
51
- - url: '{protocol}://{host}'
52
- description: Self-hosted Pixcode instance
53
- variables:
54
- protocol:
55
- enum: [http, https]
56
- default: http
57
- host:
58
- default: localhost:3001
59
-
60
- tags:
61
- - name: System
62
- description: Health, version, and self-update.
63
- - name: Authentication
64
- description: Login, register, JWT lifecycle, API keys.
65
- - name: Projects
66
- description: Project CRUD and session enumeration.
67
- - name: Files
68
- description: Project filesystem read/write and directory traversal.
69
- - name: Sessions
70
- description: Conversation sessions across providers.
71
- - name: Git
72
- description: Git status, diffs, branches, commits, push/pull.
73
- - name: Providers
74
- description: Multi-CLI provider auth, install, sessions, configuration.
75
- - name: Orchestration
76
- description: Hermes-backed multi-agent workflow planning, preview, execution, streaming, and cancellation.
77
- - name: Network
78
- description: LAN discovery, UPnP, public tunnel.
79
- - name: Settings
80
- description: User-scoped preferences and notification channels.
81
- - name: Search
82
- description: Full-text search across conversations.
83
- - name: MCP
84
- description: Model Context Protocol servers and tooling.
85
-
86
- components:
87
- securitySchemes:
88
- bearerAuth:
89
- type: http
90
- scheme: bearer
91
- bearerFormat: JWT
92
- description: |
93
- `Authorization: Bearer <token>` — token may be a JWT (issued by
94
- `/api/auth/login`) or an API key (prefix `px_`, generated under
95
- Settings → API). Legacy `ck_` keys are still accepted. The middleware
96
- sniffs the prefix to decide.
97
- apiKeyAuth:
98
- type: apiKey
99
- in: header
100
- name: X-API-Key
101
- description: |
102
- Alternative for tools that can't set `Authorization`. Accepts the same
103
- `px_...` keys as `bearerAuth`; legacy `ck_...` keys remain accepted.
104
- Either header works on every secured endpoint — pick whichever your
105
- client supports.
106
- cookieAuth:
107
- type: apiKey
108
- in: cookie
109
- name: token
110
- description: HTTP-only `token` cookie set by `/api/auth/login`.
111
-
112
- schemas:
113
- Error:
114
- type: object
115
- required: [success, error]
116
- properties:
117
- success: { type: boolean, enum: [false] }
118
- error:
119
- type: object
120
- required: [code, message]
121
- properties:
122
- code: { type: string, example: ROUTE_NOT_FOUND }
123
- message: { type: string }
124
-
125
- Health:
126
- type: object
127
- required: [status, timestamp]
128
- properties:
129
- status: { type: string, enum: [ok] }
130
- timestamp: { type: string, format: date-time }
131
- version:
132
- type: string
133
- description: Server version (matches semver `MAJOR.MINOR.PATCH`).
134
- example: 1.33.9
135
- installMode:
136
- type: string
137
- enum: [git, npm-global, runtime-dir, docker]
138
-
139
- User:
140
- type: object
141
- properties:
142
- id: { type: integer }
143
- username: { type: string }
144
- email: { type: string, format: email, nullable: true }
145
- created_at: { type: string, format: date-time }
146
-
147
- AuthStatus:
148
- type: object
149
- properties:
150
- success: { type: boolean }
151
- isAuthenticated: { type: boolean }
152
- needsSetup: { type: boolean, description: 'true if no users exist yet — UI shows registration screen.' }
153
- user: { $ref: '#/components/schemas/User' }
154
-
155
- LoginRequest:
156
- type: object
157
- required: [username, password]
158
- properties:
159
- username: { type: string }
160
- password: { type: string, format: password }
161
-
162
- LoginResponse:
163
- type: object
164
- properties:
165
- success: { type: boolean }
166
- token: { type: string, description: JWT (also set as `token` cookie). }
167
- user: { $ref: '#/components/schemas/User' }
168
-
169
- ApiKey:
170
- type: object
171
- properties:
172
- id: { type: integer }
173
- key_name: { type: string }
174
- api_key: { type: string, description: 'Format: `px_<32-hex>`. Returned in full on creation only. Legacy `ck_<32-hex>` keys remain valid.' }
175
- created_at: { type: string, format: date-time }
176
- last_used: { type: string, format: date-time, nullable: true }
177
- is_active: { type: boolean }
178
-
179
- Project:
180
- type: object
181
- properties:
182
- name: { type: string }
183
- displayName: { type: string }
184
- path: { type: string }
185
- fullPath: { type: string }
186
- sessions:
187
- type: array
188
- items: { $ref: '#/components/schemas/SessionMeta' }
189
-
190
- SessionMeta:
191
- type: object
192
- properties:
193
- id: { type: string }
194
- title: { type: string, nullable: true }
195
- provider:
196
- type: string
197
- enum: [claude, cursor, codex, gemini, qwen, opencode]
198
- lastActivity: { type: string, format: date-time }
199
-
200
- GitStatus:
201
- type: object
202
- properties:
203
- branch: { type: string }
204
- ahead: { type: integer }
205
- behind: { type: integer }
206
- modified: { type: array, items: { type: string } }
207
- added: { type: array, items: { type: string } }
208
- deleted: { type: array, items: { type: string } }
209
- untracked: { type: array, items: { type: string } }
210
-
211
- ProviderInfo:
212
- type: object
213
- properties:
214
- id:
215
- type: string
216
- enum: [claude, cursor, codex, gemini, qwen, opencode]
217
- installed: { type: boolean }
218
- authenticated: { type: boolean }
219
- version: { type: string, nullable: true }
220
- binaryPath: { type: string, nullable: true }
221
-
222
- InstallJob:
223
- type: object
224
- properties:
225
- jobId: { type: string }
226
- provider: { type: string }
227
- status: { type: string, enum: [pending, running, succeeded, failed, cancelled] }
228
-
229
- OrchestrationAgent:
230
- type: object
231
- required: [adapterId]
232
- properties:
233
- instanceId:
234
- type: string
235
- description: Stable client-side instance id. If omitted, Pixcode derives one from adapter id + order.
236
- example: codex-backend-1
237
- adapterId:
238
- type: string
239
- enum: [claude-code, codex, cursor, gemini, qwen, opencode]
240
- description: CLI adapter to execute this agent.
241
- label:
242
- type: string
243
- description: Human-readable label shown in workflow history.
244
- example: Backend Agent
245
- role:
246
- type: string
247
- description: |
248
- Optional language-independent orchestration hint. Known values are
249
- routed directly (`backend`, `frontend`, `review`, `proposal`,
250
- `critique`, etc.); custom stage names are accepted.
251
- instruction:
252
- type: string
253
- description: |
254
- Optional per-agent assignment supplied by the API caller. Pixcode
255
- does not require a fixed language or fixed text here.
256
- model:
257
- type: string
258
- description: Optional provider-specific model id. Omit this field to let the underlying CLI use its own configured/default model.
259
- permissionMode:
260
- type: string
261
- description: Provider-specific permission/sandbox mode.
262
- enabled:
263
- type: boolean
264
- default: true
265
- toolsSettings:
266
- type: object
267
- additionalProperties: true
268
-
269
- WorkflowNodeRun:
270
- type: object
271
- properties:
272
- nodeId: { type: string }
273
- adapterId: { type: string }
274
- agentInstanceId: { type: string }
275
- agentLabel: { type: string }
276
- assignment: { type: string }
277
- model: { type: string }
278
- permissionMode: { type: string }
279
- timeoutMs: { type: integer }
280
- status:
281
- type: string
282
- enum: [queued, running, completed, failed, canceled, skipped]
283
- hermesTaskId: { type: string }
284
- startedAt: { type: integer, format: int64 }
285
- finishedAt: { type: integer, format: int64 }
286
- error: { type: string }
287
- outputText: { type: string }
288
- messages:
289
- type: array
290
- items:
291
- type: object
292
- properties:
293
- role: { type: string, enum: [user, agent] }
294
- text: { type: string }
295
- createdAt: { type: integer, format: int64 }
296
- artifacts:
297
- type: array
298
- items:
299
- type: object
300
- properties:
301
- type: { type: string, enum: [file-diff, command-output, preview-url, data] }
302
- text: { type: string }
303
- data: { type: object, additionalProperties: true }
304
- metadata: { type: object, additionalProperties: true }
305
-
306
- WorkspaceTarget:
307
- type: object
308
- properties:
309
- kind:
310
- type: string
311
- enum: [selected_project, pixcode_app, custom]
312
- description: Which workspace should become the child agent cwd.
313
- label:
314
- type: string
315
- description: Human-readable target label shown in run metadata.
316
- projectPath:
317
- type: string
318
- description: Required for `custom`; optional for `pixcode_app`, where the server resolves the app root.
319
-
320
- WorkflowRun:
321
- type: object
322
- properties:
323
- id: { type: string, example: wrun_1234abcd }
324
- workflowId: { type: string, example: agent_team }
325
- contextId:
326
- type: string
327
- description: Shared Hermes context id used by every child task in this run.
328
- example: ctx_1234abcd
329
- status:
330
- type: string
331
- enum: [queued, running, completed, failed, canceled]
332
- input: { type: string }
333
- startedAt: { type: integer, format: int64 }
334
- finishedAt: { type: integer, format: int64 }
335
- metadata: { type: object, additionalProperties: true }
336
- nodeRuns:
337
- type: array
338
- items: { $ref: '#/components/schemas/WorkflowNodeRun' }
339
-
340
- WorkflowRunCreateRequest:
341
- type: object
342
- properties:
343
- input:
344
- type: string
345
- description: User goal sent to the workflow.
346
- metadata:
347
- type: object
348
- properties:
349
- projectId: { type: string }
350
- selectedProjectPath:
351
- type: string
352
- description: Absolute path of the UI-selected project used for history grouping and fallback.
353
- projectPath:
354
- type: string
355
- description: Resolved absolute host path where CLI agents should run.
356
- workspaceTarget:
357
- $ref: '#/components/schemas/WorkspaceTarget'
358
- agents:
359
- type: array
360
- items: { $ref: '#/components/schemas/OrchestrationAgent' }
361
- settings:
362
- type: object
363
- properties:
364
- maxParallelAgents:
365
- type: integer
366
- minimum: 1
367
- maximum: 12
368
- default: 3
369
- isolation:
370
- type: string
371
- enum: [host, worktree, docker]
372
- keepWorkspace:
373
- type: boolean
374
- default: true
375
-
376
- WorkflowPreviewResponse:
377
- type: object
378
- properties:
379
- workflow:
380
- type: object
381
- additionalProperties: true
382
- nodeCount: { type: integer }
383
- nodes:
384
- type: array
385
- items:
386
- type: object
387
- properties:
388
- id: { type: string }
389
- adapterId: { type: string }
390
- agentInstanceId: { type: string }
391
- agentLabel: { type: string }
392
- inputs:
393
- type: array
394
- items: { type: string }
395
- onFail: { type: string, enum: [abort, continue, retry] }
396
- output: { type: string, enum: [message, artifact, both] }
397
- timeoutMs: { type: integer }
398
-
399
- security:
400
- - bearerAuth: []
401
- - apiKeyAuth: []
402
- - cookieAuth: []
403
-
404
- paths:
405
- /health:
406
- get:
407
- tags: [System]
408
- summary: Liveness + version probe
409
- description: |
410
- Public, unauthenticated. Returns server version and install mode so the
411
- UI can detect updates and stale daemons. Used by:
412
-
413
- - The version-upgrade modal — polls during/after `/api/system/update`
414
- to detect when the new version is up.
415
- - `useVersionCheck` — falls back to the bundle's baked
416
- `__PIXCODE_UI_VERSION__` if `version` is missing or non-semver.
417
- security: []
418
- responses:
419
- '200':
420
- description: Server is up.
421
- content:
422
- application/json:
423
- schema: { $ref: '#/components/schemas/Health' }
424
-
425
- /api/system/update:
426
- post:
427
- tags: [System]
428
- summary: Self-update (SSE)
429
- description: |
430
- Streams the update process via SSE. Behavior depends on
431
- `installMode`:
432
-
433
- - **runtime-dir** (desktop wrapper): downloads the latest npm tarball,
434
- atomically swaps files, emits `done { selfRestarting: true }`, then
435
- `process.exit(42)` so the wrapper respawns. **Don't `POST /restart`
436
- when `selfRestarting` is true.**
437
- - **git/npm-global**: runs `git pull && npm install` or
438
- `npm install -g`. The supervising daemon may restart the server
439
- mid-stream — clients should treat a bare close + `/health` version
440
- bump as success.
441
- responses:
442
- '200':
443
- description: 'SSE stream of `event: log`, `event: progress`, `event: done`, `event: error`.'
444
- content:
445
- text/event-stream:
446
- schema: { type: string }
447
-
448
- /api/system/restart:
449
- post:
450
- tags: [System]
451
- summary: Restart the server process
452
- description: |
453
- Triggers a graceful exit; the supervising daemon (systemd/pm2/electron
454
- wrapper) is expected to respawn. Don't call after a `selfRestarting`
455
- update event — the wrapper has already been signalled.
456
- responses:
457
- '200':
458
- description: Restart scheduled.
459
-
460
- /api/auth/status:
461
- get:
462
- tags: [Authentication]
463
- summary: Probe authentication state
464
- description: Returns whether the current request carries a valid token, and whether the system has any users at all (`needsSetup`).
465
- security: []
466
- responses:
467
- '200':
468
- description: Auth status.
469
- content:
470
- application/json:
471
- schema: { $ref: '#/components/schemas/AuthStatus' }
472
-
473
- /api/auth/register:
474
- post:
475
- tags: [Authentication]
476
- summary: Register the first user
477
- description: Only allowed while `needsSetup` is true. Subsequent calls return 403.
478
- security: []
479
- requestBody:
480
- required: true
481
- content:
482
- application/json:
483
- schema: { $ref: '#/components/schemas/LoginRequest' }
484
- responses:
485
- '200':
486
- description: Registered + auto-logged-in.
487
- content:
488
- application/json:
489
- schema: { $ref: '#/components/schemas/LoginResponse' }
490
- '403':
491
- description: Setup already complete.
492
- content:
493
- application/json:
494
- schema: { $ref: '#/components/schemas/Error' }
495
-
496
- /api/auth/login:
497
- post:
498
- tags: [Authentication]
499
- summary: Log in
500
- security: []
501
- requestBody:
502
- required: true
503
- content:
504
- application/json:
505
- schema: { $ref: '#/components/schemas/LoginRequest' }
506
- responses:
507
- '200':
508
- description: Login OK; sets `token` cookie + returns JWT in body.
509
- content:
510
- application/json:
511
- schema: { $ref: '#/components/schemas/LoginResponse' }
512
- '401':
513
- description: Invalid credentials.
514
-
515
- /api/auth/user:
516
- get:
517
- tags: [Authentication]
518
- summary: Current user
519
- responses:
520
- '200':
521
- description: Authenticated user details.
522
- content:
523
- application/json:
524
- schema:
525
- type: object
526
- properties:
527
- user: { $ref: '#/components/schemas/User' }
528
-
529
- /api/auth/logout:
530
- post:
531
- tags: [Authentication]
532
- summary: Log out
533
- description: Clears the `token` cookie. JWT remains valid until expiry — server-side blacklist isn't implemented.
534
- responses:
535
- '200': { description: OK }
536
-
537
- /api/settings/api-keys:
538
- get:
539
- tags: [Authentication]
540
- summary: List user API keys
541
- responses:
542
- '200':
543
- description: List of keys (the `api_key` field is masked except on creation).
544
- content:
545
- application/json:
546
- schema:
547
- type: array
548
- items: { $ref: '#/components/schemas/ApiKey' }
549
- post:
550
- tags: [Authentication]
551
- summary: Create an API key
552
- requestBody:
553
- required: true
554
- content:
555
- application/json:
556
- schema:
557
- type: object
558
- required: [name]
559
- properties:
560
- name: { type: string, description: 'Human-readable label.' }
561
- responses:
562
- '201':
563
- description: Key created. The full `api_key` value is returned **once** — store it.
564
- content:
565
- application/json:
566
- schema: { $ref: '#/components/schemas/ApiKey' }
567
-
568
- /api/settings/api-keys/{keyId}:
569
- delete:
570
- tags: [Authentication]
571
- summary: Delete an API key
572
- parameters:
573
- - name: keyId
574
- in: path
575
- required: true
576
- schema: { type: integer }
577
- responses:
578
- '200': { description: Deleted. }
579
-
580
- /api/settings/api-keys/{keyId}/toggle:
581
- patch:
582
- tags: [Authentication]
583
- summary: Activate / deactivate an API key
584
- parameters:
585
- - name: keyId
586
- in: path
587
- required: true
588
- schema: { type: integer }
589
- requestBody:
590
- required: true
591
- content:
592
- application/json:
593
- schema:
594
- type: object
595
- properties:
596
- is_active: { type: boolean }
597
- responses:
598
- '200': { description: Updated. }
599
-
600
- /api/projects:
601
- get:
602
- tags: [Projects]
603
- summary: List all projects
604
- description: Walks `~/.claude/projects/*` plus any registered workspaces and returns a unified list. Sessions are flattened by provider.
605
- responses:
606
- '200':
607
- description: Project list.
608
- content:
609
- application/json:
610
- schema:
611
- type: array
612
- items: { $ref: '#/components/schemas/Project' }
613
-
614
- /api/projects/quick-start:
615
- post:
616
- tags: [Projects]
617
- summary: Open or create a project from an absolute path
618
- requestBody:
619
- required: true
620
- content:
621
- application/json:
622
- schema:
623
- type: object
624
- required: [path]
625
- properties:
626
- path: { type: string, description: 'Absolute filesystem path.' }
627
- responses:
628
- '200':
629
- description: Project record (created if it didn't exist).
630
- content:
631
- application/json:
632
- schema: { $ref: '#/components/schemas/Project' }
633
-
634
- /api/projects/{projectName}/rename:
635
- put:
636
- tags: [Projects]
637
- summary: Rename project display
638
- parameters:
639
- - { name: projectName, in: path, required: true, schema: { type: string } }
640
- requestBody:
641
- required: true
642
- content:
643
- application/json:
644
- schema:
645
- type: object
646
- properties:
647
- displayName: { type: string }
648
- responses:
649
- '200': { description: Renamed. }
650
-
651
- /api/projects/{projectName}:
652
- delete:
653
- tags: [Projects]
654
- summary: Delete (deregister) a project
655
- parameters:
656
- - { name: projectName, in: path, required: true, schema: { type: string } }
657
- responses:
658
- '200': { description: Deleted. }
659
-
660
- /api/projects/{projectName}/sessions:
661
- get:
662
- tags: [Sessions]
663
- summary: List sessions for a project
664
- parameters:
665
- - { name: projectName, in: path, required: true, schema: { type: string } }
666
- responses:
667
- '200':
668
- description: Sessions sorted by lastActivity desc.
669
- content:
670
- application/json:
671
- schema:
672
- type: array
673
- items: { $ref: '#/components/schemas/SessionMeta' }
674
-
675
- /api/projects/{projectName}/sessions/{sessionId}:
676
- delete:
677
- tags: [Sessions]
678
- summary: Delete a session
679
- parameters:
680
- - { name: projectName, in: path, required: true, schema: { type: string } }
681
- - { name: sessionId, in: path, required: true, schema: { type: string } }
682
- responses:
683
- '200': { description: Deleted. }
684
-
685
- /api/sessions/{sessionId}/rename:
686
- put:
687
- tags: [Sessions]
688
- summary: Rename a session
689
- parameters:
690
- - { name: sessionId, in: path, required: true, schema: { type: string } }
691
- requestBody:
692
- required: true
693
- content:
694
- application/json:
695
- schema:
696
- type: object
697
- properties:
698
- title: { type: string }
699
- responses:
700
- '200': { description: Renamed. }
701
-
702
- /api/sessions/{sessionId}/messages:
703
- get:
704
- tags: [Sessions]
705
- summary: Get session message history
706
- description: |
707
- Note: this is mounted at `/api/sessions`, NOT under `/api/projects` — the
708
- `projectName` is supplied as a query parameter rather than a path
709
- segment. The mount lives in `server/routes/messages.js`.
710
- parameters:
711
- - { name: sessionId, in: path, required: true, schema: { type: string } }
712
- - { name: projectName, in: query, required: true, schema: { type: string }, description: Pixcode project the session belongs to. }
713
- - { name: limit, in: query, required: false, schema: { type: integer, default: 100 } }
714
- - { name: offset, in: query, required: false, schema: { type: integer, default: 0 } }
715
- responses:
716
- '200':
717
- description: Normalized message stream.
718
- content:
719
- application/json:
720
- schema:
721
- type: object
722
- properties:
723
- messages: { type: array, items: { type: object, additionalProperties: true } }
724
- total: { type: integer }
725
- hasMore: { type: boolean }
726
-
727
- /api/search/conversations:
728
- get:
729
- tags: [Search]
730
- summary: Full-text search across all sessions
731
- parameters:
732
- - { name: q, in: query, required: true, schema: { type: string }, description: Search query. }
733
- - { name: provider, in: query, required: false, schema: { type: string, enum: [claude, cursor, codex, gemini, qwen, opencode] } }
734
- - { name: limit, in: query, required: false, schema: { type: integer, default: 50 } }
735
- responses:
736
- '200':
737
- description: Ranked matches.
738
- content:
739
- application/json:
740
- schema:
741
- type: object
742
- properties:
743
- results: { type: array, items: { type: object, additionalProperties: true } }
744
- total: { type: integer }
745
-
746
- /api/projects/{projectName}/files:
747
- get:
748
- tags: [Files]
749
- summary: List files in a project subtree
750
- parameters:
751
- - { name: projectName, in: path, required: true, schema: { type: string } }
752
- - { name: path, in: query, required: false, schema: { type: string }, description: Subdirectory relative to project root. }
753
- responses:
754
- '200':
755
- description: Directory listing.
756
- content:
757
- application/json:
758
- schema:
759
- type: array
760
- items:
761
- type: object
762
- properties:
763
- name: { type: string }
764
- path: { type: string }
765
- type: { type: string, enum: [file, directory] }
766
- size: { type: integer, nullable: true }
767
- delete:
768
- tags: [Files]
769
- summary: Delete a file or folder (path in body)
770
- description: |
771
- Same path as the listing endpoint above — discriminated by HTTP method.
772
- The target's project-relative path goes in the body, NOT the query
773
- string (so directory deletes can't be partially URL-encoded into a
774
- broken state).
775
- parameters:
776
- - { name: projectName, in: path, required: true, schema: { type: string } }
777
- requestBody:
778
- required: true
779
- content:
780
- application/json:
781
- schema:
782
- type: object
783
- required: [path]
784
- properties:
785
- path: { type: string, description: 'Project-relative path of the file or directory to delete.' }
786
- type: { type: string, enum: [file, directory], description: 'Optional hint; server detects automatically if omitted.' }
787
- responses:
788
- '200': { description: Deleted. }
789
-
790
- /api/projects/{projectName}/file:
791
- get:
792
- tags: [Files]
793
- summary: Read a single file
794
- parameters:
795
- - { name: projectName, in: path, required: true, schema: { type: string } }
796
- - { name: path, in: query, required: true, schema: { type: string } }
797
- responses:
798
- '200':
799
- description: File contents (utf-8 text or base64 binary).
800
- content:
801
- application/json:
802
- schema:
803
- type: object
804
- properties:
805
- content: { type: string }
806
- encoding: { type: string, enum: [utf-8, base64] }
807
- put:
808
- tags: [Files]
809
- summary: Overwrite a file
810
- parameters:
811
- - { name: projectName, in: path, required: true, schema: { type: string } }
812
- requestBody:
813
- required: true
814
- content:
815
- application/json:
816
- schema:
817
- type: object
818
- required: [path, content]
819
- properties:
820
- path: { type: string }
821
- content: { type: string }
822
- responses:
823
- '200': { description: Saved. }
824
-
825
- /api/projects/{projectName}/files/create:
826
- post:
827
- tags: [Files]
828
- summary: Create a new file or folder
829
- parameters:
830
- - { name: projectName, in: path, required: true, schema: { type: string } }
831
- requestBody:
832
- required: true
833
- content:
834
- application/json:
835
- schema:
836
- type: object
837
- required: [path, type]
838
- properties:
839
- path: { type: string }
840
- type: { type: string, enum: [file, directory] }
841
- content: { type: string, description: 'Initial content for files; ignored for directories.' }
842
- responses:
843
- '201': { description: Created. }
844
-
845
- /api/projects/{projectName}/files/rename:
846
- put:
847
- tags: [Files]
848
- summary: Rename / move a file
849
- parameters:
850
- - { name: projectName, in: path, required: true, schema: { type: string } }
851
- requestBody:
852
- required: true
853
- content:
854
- application/json:
855
- schema:
856
- type: object
857
- required: [oldPath, newPath]
858
- properties:
859
- oldPath: { type: string }
860
- newPath: { type: string }
861
- responses:
862
- '200': { description: Renamed. }
863
-
864
-
865
- /api/browse-filesystem:
866
- get:
867
- tags: [Files]
868
- summary: Native filesystem browser (outside project tree)
869
- description: Used by Quick Start to let the user pick a folder anywhere on the host. Honours `~` expansion.
870
- parameters:
871
- - { name: path, in: query, required: false, schema: { type: string, default: '~' } }
872
- responses:
873
- '200':
874
- description: Directory listing.
875
- content:
876
- application/json:
877
- schema:
878
- type: object
879
- properties:
880
- path: { type: string }
881
- parent: { type: string, nullable: true }
882
- entries:
883
- type: array
884
- items:
885
- type: object
886
- properties:
887
- name: { type: string }
888
- type: { type: string, enum: [file, directory] }
889
-
890
- /api/git/status:
891
- get:
892
- tags: [Git]
893
- summary: Working tree status
894
- parameters:
895
- - { name: project, in: query, required: true, schema: { type: string } }
896
- responses:
897
- '200':
898
- description: Git status snapshot.
899
- content:
900
- application/json:
901
- schema: { $ref: '#/components/schemas/GitStatus' }
902
-
903
- /api/git/diff:
904
- get:
905
- tags: [Git]
906
- summary: Unified diff for one file or the whole tree
907
- parameters:
908
- - { name: project, in: query, required: true, schema: { type: string } }
909
- - { name: file, in: query, required: false, schema: { type: string } }
910
- - { name: staged, in: query, required: false, schema: { type: boolean, default: false } }
911
- responses:
912
- '200':
913
- description: Diff text.
914
- content:
915
- application/json:
916
- schema:
917
- type: object
918
- properties:
919
- diff: { type: string }
920
-
921
- /api/git/branches:
922
- get:
923
- tags: [Git]
924
- summary: List local + remote branches
925
- parameters:
926
- - { name: project, in: query, required: true, schema: { type: string } }
927
- responses:
928
- '200':
929
- description: Branch list.
930
- content:
931
- application/json:
932
- schema:
933
- type: object
934
- properties:
935
- current: { type: string }
936
- local: { type: array, items: { type: string } }
937
- remote: { type: array, items: { type: string } }
938
-
939
- /api/git/commit:
940
- post:
941
- tags: [Git]
942
- summary: Create a commit
943
- requestBody:
944
- required: true
945
- content:
946
- application/json:
947
- schema:
948
- type: object
949
- required: [project, message]
950
- properties:
951
- project: { type: string }
952
- message: { type: string }
953
- files: { type: array, items: { type: string }, description: 'When omitted, all staged changes are committed.' }
954
- responses:
955
- '200': { description: Commit created. }
956
-
957
- /api/git/push:
958
- post:
959
- tags: [Git]
960
- summary: Push to remote
961
- requestBody:
962
- required: true
963
- content:
964
- application/json:
965
- schema:
966
- type: object
967
- required: [project]
968
- properties:
969
- project: { type: string }
970
- remote: { type: string, default: origin }
971
- branch: { type: string }
972
- force: { type: boolean, default: false }
973
- responses:
974
- '200': { description: Pushed. }
975
-
976
- /api/git/pull:
977
- post:
978
- tags: [Git]
979
- summary: Pull from remote
980
- requestBody:
981
- required: true
982
- content:
983
- application/json:
984
- schema:
985
- type: object
986
- required: [project]
987
- properties:
988
- project: { type: string }
989
- responses:
990
- '200': { description: Pulled. }
991
-
992
- /api/git/checkout:
993
- post:
994
- tags: [Git]
995
- summary: Switch branch
996
- requestBody:
997
- required: true
998
- content:
999
- application/json:
1000
- schema:
1001
- type: object
1002
- required: [project, branch]
1003
- properties:
1004
- project: { type: string }
1005
- branch: { type: string }
1006
- responses:
1007
- '200': { description: Switched. }
1008
-
1009
- /api/providers/credentials:
1010
- get:
1011
- tags: [Providers]
1012
- summary: List stored credentials across providers
1013
- description: Returns a sanitised inventory of API keys / OAuth tokens Pixcode is currently holding for each provider. Real secret values are NOT returned — only presence + masked tail.
1014
- responses:
1015
- '200':
1016
- description: Credentials inventory.
1017
- content:
1018
- application/json:
1019
- schema:
1020
- type: object
1021
- additionalProperties:
1022
- type: object
1023
- properties:
1024
- hasCredential: { type: boolean }
1025
- masked: { type: string, nullable: true, example: '...beef' }
1026
-
1027
- /api/providers/{provider}/auth/status:
1028
- get:
1029
- tags: [Providers]
1030
- summary: Auth status for a single provider
1031
- description: |
1032
- Returns whether the provider's CLI is installed, whether it has a
1033
- valid auth credential (api key / OAuth token), and the resolved
1034
- binary path the spawn layer will use.
1035
- parameters:
1036
- - { name: provider, in: path, required: true, schema: { type: string, enum: [claude, cursor, codex, gemini, qwen, opencode] } }
1037
- responses:
1038
- '200':
1039
- description: Auth status snapshot.
1040
- content:
1041
- application/json:
1042
- schema: { $ref: '#/components/schemas/ProviderInfo' }
1043
-
1044
- /api/providers/{provider}/auth/api-key:
1045
- post:
1046
- tags: [Providers]
1047
- summary: Save / replace an API-key credential for a provider
1048
- parameters:
1049
- - { name: provider, in: path, required: true, schema: { type: string } }
1050
- requestBody:
1051
- required: true
1052
- content:
1053
- application/json:
1054
- schema:
1055
- type: object
1056
- required: [apiKey]
1057
- properties:
1058
- apiKey: { type: string }
1059
- baseUrl: { type: string, description: Optional override (e.g. self-hosted Anthropic compat endpoint). }
1060
- responses:
1061
- '200': { description: Credential saved. }
1062
-
1063
- /api/providers/{provider}/oauth-paste:
1064
- post:
1065
- tags: [Providers]
1066
- summary: Paste an OAuth callback URL to complete login
1067
- description: |
1068
- For providers (Claude, Cursor) whose login flow opens a browser tab and
1069
- bounces back to a URL the user copies into Pixcode. The handler parses
1070
- the token and stores it as the active credential.
1071
- parameters:
1072
- - { name: provider, in: path, required: true, schema: { type: string } }
1073
- requestBody:
1074
- required: true
1075
- content:
1076
- application/json:
1077
- schema:
1078
- type: object
1079
- required: [url]
1080
- properties:
1081
- url: { type: string, format: uri }
1082
- responses:
1083
- '200': { description: Token extracted and stored. }
1084
- '400': { description: URL did not contain a recognisable token. }
1085
-
1086
- /api/providers/{provider}/models:
1087
- get:
1088
- tags: [Providers]
1089
- summary: List models the provider's CLI exposes
1090
- description: |
1091
- Pixcode caches the model list per provider on first call (or when the
1092
- cache is busted via `DELETE …/models/cache`). Each entry is the
1093
- `provider/model` form OpenCode expects.
1094
- parameters:
1095
- - { name: provider, in: path, required: true, schema: { type: string } }
1096
- responses:
1097
- '200':
1098
- description: Model catalog.
1099
- content:
1100
- application/json:
1101
- schema:
1102
- type: array
1103
- items:
1104
- type: object
1105
- properties:
1106
- id: { type: string, example: 'opencode/gpt-5.2' }
1107
- name: { type: string }
1108
- contextWindow: { type: integer, nullable: true }
1109
-
1110
- /api/providers/{provider}/models/cache:
1111
- delete:
1112
- tags: [Providers]
1113
- summary: Bust the cached model list for one provider
1114
- parameters:
1115
- - { name: provider, in: path, required: true, schema: { type: string } }
1116
- responses:
1117
- '200': { description: Cache cleared; next GET re-fetches. }
1118
-
1119
- /api/providers/{provider}/install:
1120
- post:
1121
- tags: [Providers]
1122
- summary: Install / update a provider CLI in the Pixcode sandbox
1123
- description: |
1124
- Installs the provider's npm package into `~/.pixcode/cli-bin/` (no
1125
- `-g`, no sudo/UAC). Returns a `jobId` immediately; subscribe to
1126
- `/install/{jobId}/stream` for live logs.
1127
- parameters:
1128
- - { name: provider, in: path, required: true, schema: { type: string } }
1129
- responses:
1130
- '202':
1131
- description: Job accepted.
1132
- content:
1133
- application/json:
1134
- schema: { $ref: '#/components/schemas/InstallJob' }
1135
-
1136
- /api/providers/{provider}/install/{jobId}/stream:
1137
- get:
1138
- tags: [Providers]
1139
- summary: Stream install job output (SSE)
1140
- description: Replays buffered output, then streams live until the job ends. Send `Last-Event-ID` to resume after disconnect.
1141
- parameters:
1142
- - { name: provider, in: path, required: true, schema: { type: string } }
1143
- - { name: jobId, in: path, required: true, schema: { type: string } }
1144
- responses:
1145
- '200':
1146
- description: 'SSE event stream — `event: log`, `event: status`, `event: done`, `event: error`.'
1147
- content:
1148
- text/event-stream:
1149
- schema: { type: string }
1150
-
1151
- /api/providers/{provider}/install/{jobId}:
1152
- delete:
1153
- tags: [Providers]
1154
- summary: Cancel an in-flight install
1155
- parameters:
1156
- - { name: provider, in: path, required: true, schema: { type: string } }
1157
- - { name: jobId, in: path, required: true, schema: { type: string } }
1158
- responses:
1159
- '200': { description: Cancelled. }
1160
-
1161
- /api/providers/{provider}/mcp/servers:
1162
- get:
1163
- tags: [MCP]
1164
- summary: List MCP servers configured for one provider
1165
- parameters:
1166
- - { name: provider, in: path, required: true, schema: { type: string } }
1167
- responses:
1168
- '200':
1169
- description: MCP server list (matches the provider's native config schema).
1170
- content:
1171
- application/json:
1172
- schema:
1173
- type: array
1174
- items: { type: object, additionalProperties: true }
1175
- post:
1176
- tags: [MCP]
1177
- summary: Add or replace an MCP server entry
1178
- parameters:
1179
- - { name: provider, in: path, required: true, schema: { type: string } }
1180
- requestBody:
1181
- required: true
1182
- content:
1183
- application/json:
1184
- schema:
1185
- type: object
1186
- required: [name, command]
1187
- properties:
1188
- name: { type: string }
1189
- command: { type: string }
1190
- args: { type: array, items: { type: string } }
1191
- env: { type: object, additionalProperties: { type: string } }
1192
- scope: { type: string, enum: [local, user], default: user }
1193
- responses:
1194
- '200': { description: Server saved. }
1195
-
1196
- /api/providers/{provider}/mcp/servers/{name}:
1197
- delete:
1198
- tags: [MCP]
1199
- summary: Remove an MCP server entry
1200
- parameters:
1201
- - { name: provider, in: path, required: true, schema: { type: string } }
1202
- - { name: name, in: path, required: true, schema: { type: string } }
1203
- responses:
1204
- '200': { description: Removed. }
1205
-
1206
- /api/providers/mcp/servers/global:
1207
- post:
1208
- tags: [MCP]
1209
- summary: Add an MCP server to every provider that supports MCP
1210
- description: Convenience endpoint that fans out the same server config to all MCP-capable providers (Claude, Cursor, Codex, OpenCode). Per-provider edits override.
1211
- requestBody:
1212
- required: true
1213
- content:
1214
- application/json:
1215
- schema:
1216
- type: object
1217
- required: [name, command]
1218
- properties:
1219
- name: { type: string }
1220
- command: { type: string }
1221
- args: { type: array, items: { type: string } }
1222
- env: { type: object, additionalProperties: { type: string } }
1223
- responses:
1224
- '200': { description: Server fanned out. }
1225
-
1226
- /api/providers/{provider}/config-files:
1227
- get:
1228
- tags: [Providers]
1229
- summary: List config files Pixcode knows about for a provider
1230
- description: |
1231
- Returns the catalog of editable config files for a provider — typically
1232
- `settings.json`, `auth.json`, `opencode.json`, etc. Each entry has an
1233
- opaque `fileId` used by `GET/PUT …/{fileId}`.
1234
- parameters:
1235
- - { name: provider, in: path, required: true, schema: { type: string } }
1236
- responses:
1237
- '200':
1238
- description: Config file catalog.
1239
- content:
1240
- application/json:
1241
- schema:
1242
- type: array
1243
- items:
1244
- type: object
1245
- properties:
1246
- fileId: { type: string }
1247
- path: { type: string }
1248
- label: { type: string }
1249
- exists: { type: boolean }
1250
- size: { type: integer, nullable: true }
1251
-
1252
- /api/providers/{provider}/config-files/{fileId}:
1253
- get:
1254
- tags: [Providers]
1255
- summary: Read a provider config file's contents
1256
- parameters:
1257
- - { name: provider, in: path, required: true, schema: { type: string } }
1258
- - { name: fileId, in: path, required: true, schema: { type: string } }
1259
- responses:
1260
- '200':
1261
- description: File contents.
1262
- content:
1263
- application/json:
1264
- schema:
1265
- type: object
1266
- properties:
1267
- content: { type: string }
1268
- path: { type: string }
1269
- encoding: { type: string, enum: [utf-8] }
1270
- put:
1271
- tags: [Providers]
1272
- summary: Overwrite a provider config file
1273
- parameters:
1274
- - { name: provider, in: path, required: true, schema: { type: string } }
1275
- - { name: fileId, in: path, required: true, schema: { type: string } }
1276
- requestBody:
1277
- required: true
1278
- content:
1279
- application/json:
1280
- schema:
1281
- type: object
1282
- required: [content]
1283
- properties:
1284
- content: { type: string }
1285
- responses:
1286
- '200': { description: Saved. }
1287
- '400': { description: Content failed validation (e.g. malformed JSON). }
1288
-
1289
- /api/orchestration/workflows:
1290
- get:
1291
- tags: [Orchestration]
1292
- summary: List built-in workflow modes
1293
- description: |
1294
- Returns the available "Çalışma modu / Work mode" definitions. The
1295
- `agent_team` workflow is dynamic: it expands from the API caller's
1296
- `metadata.agents` list at preview/run time.
1297
- responses:
1298
- '200':
1299
- description: Workflow catalog.
1300
- content:
1301
- application/json:
1302
- schema:
1303
- type: object
1304
- properties:
1305
- workflows:
1306
- type: array
1307
- items:
1308
- type: object
1309
- additionalProperties: true
1310
-
1311
- /api/orchestration/workflows/context:
1312
- get:
1313
- tags: [Orchestration]
1314
- summary: Read workflow execution context
1315
- description: |
1316
- Returns the Pixcode app root and supported target workspace modes so
1317
- clients can decide whether child agents should run in the selected
1318
- project, Pixcode itself, or a custom path.
1319
- responses:
1320
- '200':
1321
- description: Workflow execution context.
1322
- content:
1323
- application/json:
1324
- schema:
1325
- type: object
1326
- properties:
1327
- appRoot: { type: string, example: /root/pixcode }
1328
- defaultWorkspaceTarget: { type: string, example: selected_project }
1329
- supportedWorkspaceTargets:
1330
- type: array
1331
- items:
1332
- type: string
1333
- enum: [selected_project, pixcode_app, custom]
1334
-
1335
- /api/orchestration/workflows/{workflowId}/preview:
1336
- post:
1337
- tags: [Orchestration]
1338
- summary: Preview expanded workflow DAG without running agents
1339
- description: |
1340
- Dry-run endpoint for API clients and automated tests. It expands
1341
- `metadata.agents` into the actual node graph, validates dependencies,
1342
- and returns node ids, adapters, inputs, fail policy, and timeout values.
1343
-
1344
- Use `metadata.agents[].role` (`backend`, `frontend`, `review`,
1345
- `implementation`) for language-independent routing. `instruction` is
1346
- optional and fully caller-controlled.
1347
- parameters:
1348
- - name: workflowId
1349
- in: path
1350
- required: true
1351
- schema: { type: string, example: agent_team }
1352
- requestBody:
1353
- required: false
1354
- content:
1355
- application/json:
1356
- schema: { $ref: '#/components/schemas/WorkflowRunCreateRequest' }
1357
- examples:
1358
- roleBasedAgentTeam:
1359
- summary: Role-based agent team, no fixed instruction language
1360
- value:
1361
- metadata:
1362
- agents:
1363
- - adapterId: codex
1364
- label: Frontend Agent
1365
- role: frontend
1366
- - adapterId: codex
1367
- label: Backend Agent
1368
- role: backend
1369
- - adapterId: codex
1370
- label: Review Agent
1371
- role: review
1372
- settings:
1373
- maxParallelAgents: 3
1374
- isolation: host
1375
- responses:
1376
- '200':
1377
- description: Expanded workflow graph.
1378
- content:
1379
- application/json:
1380
- schema: { $ref: '#/components/schemas/WorkflowPreviewResponse' }
1381
- '400':
1382
- description: Invalid workflow metadata.
1383
-
1384
- /api/orchestration/workflows/{workflowId}/runs:
1385
- post:
1386
- tags: [Orchestration]
1387
- summary: Start a workflow run
1388
- description: |
1389
- Starts a multi-agent workflow. Every child Hermes task shares one
1390
- `contextId`, and returned child task ids can be used for low-level
1391
- Hermes inspection.
1392
-
1393
- For `agent_team`, Pixcode creates a coordinator, optional bounded
1394
- backend handoff nodes, worker nodes, review nodes, and a final report.
1395
- Frontend agents depend on backend handoff contracts, not on the full
1396
- backend implementation, so one slow backend task does not block all
1397
- UI work.
1398
- parameters:
1399
- - name: workflowId
1400
- in: path
1401
- required: true
1402
- schema: { type: string, example: agent_team }
1403
- requestBody:
1404
- required: true
1405
- content:
1406
- application/json:
1407
- schema: { $ref: '#/components/schemas/WorkflowRunCreateRequest' }
1408
- responses:
1409
- '202':
1410
- description: Workflow accepted.
1411
- content:
1412
- application/json:
1413
- schema: { $ref: '#/components/schemas/WorkflowRun' }
1414
- '400':
1415
- description: Invalid workflow request.
1416
- '404':
1417
- description: Workflow not found.
1418
-
1419
- /api/orchestration/workflows/runs:
1420
- get:
1421
- tags: [Orchestration]
1422
- summary: List workflow runs
1423
- parameters:
1424
- - name: projectId
1425
- in: query
1426
- required: false
1427
- schema: { type: string }
1428
- responses:
1429
- '200':
1430
- description: Runs sorted newest first.
1431
- content:
1432
- application/json:
1433
- schema:
1434
- type: object
1435
- properties:
1436
- runs:
1437
- type: array
1438
- items: { $ref: '#/components/schemas/WorkflowRun' }
1439
-
1440
- /api/orchestration/workflows/runs/{runId}:
1441
- get:
1442
- tags: [Orchestration]
1443
- summary: Read one workflow run snapshot
1444
- parameters:
1445
- - name: runId
1446
- in: path
1447
- required: true
1448
- schema: { type: string }
1449
- responses:
1450
- '200':
1451
- description: Workflow run state.
1452
- content:
1453
- application/json:
1454
- schema: { $ref: '#/components/schemas/WorkflowRun' }
1455
- '404':
1456
- description: Run not found.
1457
-
1458
- /api/orchestration/workflows/runs/{runId}/events:
1459
- get:
1460
- tags: [Orchestration]
1461
- summary: Stream workflow run snapshots (SSE)
1462
- description: |
1463
- Emits `event: snapshot` frames every second while the run is active.
1464
- Each `data:` payload is `{ "run": WorkflowRun }`. The stream ends
1465
- automatically when the run reaches `completed`, `failed`, or
1466
- `canceled`.
1467
- parameters:
1468
- - name: runId
1469
- in: path
1470
- required: true
1471
- schema: { type: string }
1472
- responses:
1473
- '200':
1474
- description: Server-Sent Events stream.
1475
- content:
1476
- text/event-stream:
1477
- schema: { type: string }
1478
- '404':
1479
- description: Run not found.
1480
-
1481
- /api/orchestration/workflows/runs/{runId}/cancel:
1482
- post:
1483
- tags: [Orchestration]
1484
- summary: Cancel a workflow run and active child Hermes tasks
1485
- parameters:
1486
- - name: runId
1487
- in: path
1488
- required: true
1489
- schema: { type: string }
1490
- responses:
1491
- '200':
1492
- description: Updated canceled run.
1493
- content:
1494
- application/json:
1495
- schema: { $ref: '#/components/schemas/WorkflowRun' }
1496
- '404':
1497
- description: Run not found.
1498
-
1499
- /api/network/endpoints:
1500
- get:
1501
- tags: [Network]
1502
- summary: LAN endpoints for mobile QR pairing
1503
- description: Returns every reachable IPv4 the host has bound, formatted as `http://<ip>:<port>`.
1504
- responses:
1505
- '200':
1506
- description: LAN endpoint list.
1507
- content:
1508
- application/json:
1509
- schema:
1510
- type: object
1511
- properties:
1512
- endpoints: { type: array, items: { type: string } }
1513
- port: { type: integer }
1514
-
1515
- /api/network/external:
1516
- get:
1517
- tags: [Network]
1518
- summary: Current external-access state (UPnP + tunnel)
1519
- responses:
1520
- '200':
1521
- description: Snapshot.
1522
- content:
1523
- application/json:
1524
- schema:
1525
- type: object
1526
- properties:
1527
- upnp:
1528
- type: object
1529
- properties:
1530
- active: { type: boolean }
1531
- externalIp: { type: string, nullable: true }
1532
- mappedPort: { type: integer, nullable: true }
1533
- tunnel:
1534
- type: object
1535
- properties:
1536
- active: { type: boolean }
1537
- provider: { type: string, enum: [cloudflared, ngrok], nullable: true }
1538
- url: { type: string, nullable: true }
1539
-
1540
- /api/network/upnp:
1541
- post:
1542
- tags: [Network]
1543
- summary: Open the LAN port on the router
1544
- responses:
1545
- '200': { description: Mapping created (or already present). }
1546
- delete:
1547
- tags: [Network]
1548
- summary: Remove the UPnP mapping
1549
- responses:
1550
- '200': { description: Removed. }
1551
-
1552
- /api/network/tunnel:
1553
- post:
1554
- tags: [Network]
1555
- summary: Start a public tunnel (cloudflared / ngrok auto-detect)
1556
- responses:
1557
- '200':
1558
- description: Tunnel started; URL returned.
1559
- content:
1560
- application/json:
1561
- schema:
1562
- type: object
1563
- properties:
1564
- url: { type: string, format: uri }
1565
- provider: { type: string }
1566
- delete:
1567
- tags: [Network]
1568
- summary: Stop the tunnel
1569
- responses:
1570
- '200': { description: Stopped. }
1571
-
1572
- /api/settings/notification-preferences:
1573
- get:
1574
- tags: [Settings]
1575
- summary: Get notification preferences
1576
- responses:
1577
- '200':
1578
- description: Per-channel + per-event toggles.
1579
- content:
1580
- application/json:
1581
- schema:
1582
- type: object
1583
- properties:
1584
- preferences:
1585
- type: object
1586
- properties:
1587
- channels:
1588
- type: object
1589
- properties:
1590
- inApp: { type: boolean }
1591
- webPush: { type: boolean }
1592
- events:
1593
- type: object
1594
- properties:
1595
- actionRequired: { type: boolean }
1596
- stop: { type: boolean }
1597
- error: { type: boolean }
1598
- put:
1599
- tags: [Settings]
1600
- summary: Update notification preferences
1601
- requestBody:
1602
- required: true
1603
- content:
1604
- application/json:
1605
- schema: { type: object }
1606
- responses:
1607
- '200': { description: Saved. }
1608
-
1609
- /api/agent:
1610
- post:
1611
- tags: [Providers]
1612
- summary: External REST entry point (API-key authenticated)
1613
- description: |
1614
- One-shot non-interactive run for automation/CI. Spawns the chosen
1615
- provider, optionally cloning a GitHub repo first, optionally cutting
1616
- a branch + opening a PR. **API key required** — accepts the same `px_`
1617
- keys as the rest of the API on `Authorization: Bearer`, `X-API-Key`,
1618
- or `?apiKey=`. Legacy `ck_` keys remain accepted.
1619
-
1620
- Default response is an SSE stream of provider-native events; pass
1621
- `stream: false` to buffer and return JSON.
1622
- security:
1623
- - bearerAuth: []
1624
- - apiKeyAuth: []
1625
- requestBody:
1626
- required: true
1627
- content:
1628
- application/json:
1629
- schema:
1630
- type: object
1631
- required: [message]
1632
- properties:
1633
- message:
1634
- type: string
1635
- description: Prompt text to send to the agent.
1636
- provider:
1637
- type: string
1638
- enum: [claude, cursor, codex, gemini, qwen, opencode]
1639
- default: claude
1640
- model:
1641
- type: string
1642
- description: Provider-specific model id (e.g. `opencode/gpt-5.2`).
1643
- projectPath:
1644
- type: string
1645
- description: Absolute path on the host. Required if `githubUrl` is omitted.
1646
- githubUrl:
1647
- type: string
1648
- format: uri
1649
- description: Clone this repo before running. Mutually inclusive with `projectPath` (used as the clone target if both are given).
1650
- githubToken:
1651
- type: string
1652
- description: Optional override for the per-user GitHub PAT stored under Settings → Git.
1653
- branchName:
1654
- type: string
1655
- description: 'Cutting `branchName` implies `createBranch: true`.'
1656
- createBranch:
1657
- type: boolean
1658
- default: false
1659
- createPR:
1660
- type: boolean
1661
- default: false
1662
- sessionId:
1663
- type: string
1664
- description: Resume an existing session instead of starting a new one.
1665
- stream:
1666
- type: boolean
1667
- default: true
1668
- description: 'Set false to buffer to a single JSON response.'
1669
- cleanup:
1670
- type: boolean
1671
- default: true
1672
- description: When `githubUrl` was used, delete the temp clone after the run.
1673
- responses:
1674
- '200':
1675
- description: |
1676
- When `stream:true` — SSE stream of provider events. When `stream:false` — final JSON payload with `text` + `sessionId` + `usage`.
1677
- content:
1678
- application/json:
1679
- schema:
1680
- type: object
1681
- properties:
1682
- text: { type: string }
1683
- sessionId: { type: string }
1684
- usage:
1685
- type: object
1686
- properties:
1687
- input: { type: integer }
1688
- output: { type: integer }
1689
- total: { type: integer }
1690
- cost: { type: number }
1691
- text/event-stream:
1692
- schema: { type: string }
1693
- '400':
1694
- description: 'Missing required fields, unknown provider, or invalid GitHub URL.'
1695
- '401':
1696
- description: Missing or invalid API key.
1
+ openapi: 3.1.0
2
+ info:
3
+ title: Pixcode REST API
4
+ version: 1.36.1
5
+ description: |
6
+ REST API for Pixcode — the multi-CLI web UI for Claude Code, Cursor CLI,
7
+ Codex, Gemini CLI, Qwen Code, and OpenCode.
8
+
9
+ ## Authentication
10
+
11
+ Most endpoints require authentication. Two schemes are accepted:
12
+
13
+ - **JWT cookie** (`token` HTTP-only cookie) — set automatically when the
14
+ browser logs in via `POST /api/auth/login`.
15
+ - **API key** (`Authorization: Bearer px_...`) — generated under
16
+ Settings → API. API keys never expire and survive server restarts.
17
+ Legacy `ck_...` keys remain accepted for older installations.
18
+
19
+ Endpoints flagged `apiKey` accept both.
20
+
21
+ ## Streaming endpoints
22
+
23
+ Three classes of endpoint stream beyond plain JSON:
24
+
25
+ - **WebSocket** (`/ws`, `/shell`) — chat session bidirectional traffic. Not
26
+ documented here; see `docs/websocket-protocol.md` if it exists, or read
27
+ `server/index.js` `handleChatConnection`.
28
+ - **SSE** (Server-Sent Events) — long-running jobs. Each `data:` frame
29
+ contains a JSON event; the stream ends with `event: done` or `event: error`.
30
+ - **NDJSON** — provider chat output (one JSON event per line) when the
31
+ backend forwards from a CLI's `--format json` mode.
32
+
33
+ ## Errors
34
+
35
+ Errors share a consistent envelope:
36
+
37
+ ```json
38
+ { "success": false, "error": { "code": "ROUTE_NOT_FOUND", "message": "..." } }
39
+ ```
40
+
41
+ contact:
42
+ name: Pixcode on GitHub
43
+ url: https://github.com/alicomert/pixcode
44
+ license:
45
+ name: AGPL-3.0-or-later
46
+ url: https://www.gnu.org/licenses/agpl-3.0.txt
47
+
48
+ servers:
49
+ - url: http://localhost:3001
50
+ description: Local development server
51
+ - url: '{protocol}://{host}'
52
+ description: Self-hosted Pixcode instance
53
+ variables:
54
+ protocol:
55
+ enum: [http, https]
56
+ default: http
57
+ host:
58
+ default: localhost:3001
59
+
60
+ tags:
61
+ - name: System
62
+ description: Health, version, and self-update.
63
+ - name: Authentication
64
+ description: Login, register, JWT lifecycle, API keys.
65
+ - name: Projects
66
+ description: Project CRUD and session enumeration.
67
+ - name: Files
68
+ description: Project filesystem read/write and directory traversal.
69
+ - name: Sessions
70
+ description: Conversation sessions across providers.
71
+ - name: Git
72
+ description: Git status, diffs, branches, commits, push/pull.
73
+ - name: Providers
74
+ description: Multi-CLI provider auth, install, sessions, configuration.
75
+ - name: Orchestration
76
+ description: Hermes-backed multi-agent workflow planning, preview, execution, streaming, and cancellation.
77
+ - name: Network
78
+ description: LAN discovery, UPnP, public tunnel.
79
+ - name: Settings
80
+ description: User-scoped preferences and notification channels.
81
+ - name: Search
82
+ description: Full-text search across conversations.
83
+ - name: MCP
84
+ description: Model Context Protocol servers and tooling.
85
+
86
+ components:
87
+ securitySchemes:
88
+ bearerAuth:
89
+ type: http
90
+ scheme: bearer
91
+ bearerFormat: JWT
92
+ description: |
93
+ `Authorization: Bearer <token>` — token may be a JWT (issued by
94
+ `/api/auth/login`) or an API key (prefix `px_`, generated under
95
+ Settings → API). Legacy `ck_` keys are still accepted. The middleware
96
+ sniffs the prefix to decide.
97
+ apiKeyAuth:
98
+ type: apiKey
99
+ in: header
100
+ name: X-API-Key
101
+ description: |
102
+ Alternative for tools that can't set `Authorization`. Accepts the same
103
+ `px_...` keys as `bearerAuth`; legacy `ck_...` keys remain accepted.
104
+ Either header works on every secured endpoint — pick whichever your
105
+ client supports.
106
+ cookieAuth:
107
+ type: apiKey
108
+ in: cookie
109
+ name: token
110
+ description: HTTP-only `token` cookie set by `/api/auth/login`.
111
+
112
+ schemas:
113
+ Error:
114
+ type: object
115
+ required: [success, error]
116
+ properties:
117
+ success: { type: boolean, enum: [false] }
118
+ error:
119
+ type: object
120
+ required: [code, message]
121
+ properties:
122
+ code: { type: string, example: ROUTE_NOT_FOUND }
123
+ message: { type: string }
124
+
125
+ Health:
126
+ type: object
127
+ required: [status, timestamp]
128
+ properties:
129
+ status: { type: string, enum: [ok] }
130
+ timestamp: { type: string, format: date-time }
131
+ version:
132
+ type: string
133
+ description: Server version (matches semver `MAJOR.MINOR.PATCH`).
134
+ example: 1.33.9
135
+ installMode:
136
+ type: string
137
+ enum: [git, npm-global, runtime-dir, docker]
138
+
139
+ User:
140
+ type: object
141
+ properties:
142
+ id: { type: integer }
143
+ username: { type: string }
144
+ email: { type: string, format: email, nullable: true }
145
+ created_at: { type: string, format: date-time }
146
+
147
+ AuthStatus:
148
+ type: object
149
+ properties:
150
+ success: { type: boolean }
151
+ isAuthenticated: { type: boolean }
152
+ needsSetup: { type: boolean, description: 'true if no users exist yet — UI shows registration screen.' }
153
+ user: { $ref: '#/components/schemas/User' }
154
+
155
+ LoginRequest:
156
+ type: object
157
+ required: [username, password]
158
+ properties:
159
+ username: { type: string }
160
+ password: { type: string, format: password }
161
+
162
+ LoginResponse:
163
+ type: object
164
+ properties:
165
+ success: { type: boolean }
166
+ token: { type: string, description: JWT (also set as `token` cookie). }
167
+ user: { $ref: '#/components/schemas/User' }
168
+
169
+ ApiKey:
170
+ type: object
171
+ properties:
172
+ id: { type: integer }
173
+ key_name: { type: string }
174
+ api_key: { type: string, description: 'Format: `px_<32-hex>`. Returned in full on creation only. Legacy `ck_<32-hex>` keys remain valid.' }
175
+ created_at: { type: string, format: date-time }
176
+ last_used: { type: string, format: date-time, nullable: true }
177
+ is_active: { type: boolean }
178
+
179
+ Project:
180
+ type: object
181
+ properties:
182
+ name: { type: string }
183
+ displayName: { type: string }
184
+ path: { type: string }
185
+ fullPath: { type: string }
186
+ sessions:
187
+ type: array
188
+ items: { $ref: '#/components/schemas/SessionMeta' }
189
+
190
+ SessionMeta:
191
+ type: object
192
+ properties:
193
+ id: { type: string }
194
+ title: { type: string, nullable: true }
195
+ provider:
196
+ type: string
197
+ enum: [claude, cursor, codex, gemini, qwen, opencode]
198
+ lastActivity: { type: string, format: date-time }
199
+
200
+ GitStatus:
201
+ type: object
202
+ properties:
203
+ branch: { type: string }
204
+ ahead: { type: integer }
205
+ behind: { type: integer }
206
+ modified: { type: array, items: { type: string } }
207
+ added: { type: array, items: { type: string } }
208
+ deleted: { type: array, items: { type: string } }
209
+ untracked: { type: array, items: { type: string } }
210
+
211
+ ProviderInfo:
212
+ type: object
213
+ properties:
214
+ id:
215
+ type: string
216
+ enum: [claude, cursor, codex, gemini, qwen, opencode]
217
+ installed: { type: boolean }
218
+ authenticated: { type: boolean }
219
+ version: { type: string, nullable: true }
220
+ binaryPath: { type: string, nullable: true }
221
+
222
+ InstallJob:
223
+ type: object
224
+ properties:
225
+ jobId: { type: string }
226
+ provider: { type: string }
227
+ status: { type: string, enum: [pending, running, succeeded, failed, cancelled] }
228
+
229
+ OrchestrationAgent:
230
+ type: object
231
+ required: [adapterId]
232
+ properties:
233
+ instanceId:
234
+ type: string
235
+ description: Stable client-side instance id. If omitted, Pixcode derives one from adapter id + order.
236
+ example: codex-backend-1
237
+ adapterId:
238
+ type: string
239
+ enum: [claude-code, codex, cursor, gemini, qwen, opencode]
240
+ description: CLI adapter to execute this agent.
241
+ label:
242
+ type: string
243
+ description: Human-readable label shown in workflow history.
244
+ example: Backend Agent
245
+ role:
246
+ type: string
247
+ description: |
248
+ Optional language-independent orchestration hint. Known values are
249
+ routed directly (`backend`, `frontend`, `review`, `proposal`,
250
+ `critique`, etc.); custom stage names are accepted.
251
+ instruction:
252
+ type: string
253
+ description: |
254
+ Optional per-agent assignment supplied by the API caller. Pixcode
255
+ does not require a fixed language or fixed text here.
256
+ model:
257
+ type: string
258
+ description: Optional provider-specific model id. Omit this field to let the underlying CLI use its own configured/default model.
259
+ permissionMode:
260
+ type: string
261
+ description: Provider-specific permission/sandbox mode.
262
+ enabled:
263
+ type: boolean
264
+ default: true
265
+ toolsSettings:
266
+ type: object
267
+ additionalProperties: true
268
+
269
+ WorkflowNodeRun:
270
+ type: object
271
+ properties:
272
+ nodeId: { type: string }
273
+ adapterId: { type: string }
274
+ agentInstanceId: { type: string }
275
+ agentLabel: { type: string }
276
+ assignment: { type: string }
277
+ model: { type: string }
278
+ permissionMode: { type: string }
279
+ timeoutMs: { type: integer }
280
+ status:
281
+ type: string
282
+ enum: [queued, running, completed, failed, canceled, skipped]
283
+ hermesTaskId: { type: string }
284
+ startedAt: { type: integer, format: int64 }
285
+ finishedAt: { type: integer, format: int64 }
286
+ error: { type: string }
287
+ outputText: { type: string }
288
+ messages:
289
+ type: array
290
+ items:
291
+ type: object
292
+ properties:
293
+ role: { type: string, enum: [user, agent] }
294
+ text: { type: string }
295
+ createdAt: { type: integer, format: int64 }
296
+ artifacts:
297
+ type: array
298
+ items:
299
+ type: object
300
+ properties:
301
+ type: { type: string, enum: [file-diff, command-output, preview-url, data] }
302
+ text: { type: string }
303
+ data: { type: object, additionalProperties: true }
304
+ metadata: { type: object, additionalProperties: true }
305
+
306
+ WorkspaceTarget:
307
+ type: object
308
+ properties:
309
+ kind:
310
+ type: string
311
+ enum: [selected_project, pixcode_app, custom]
312
+ description: Which workspace should become the child agent cwd.
313
+ label:
314
+ type: string
315
+ description: Human-readable target label shown in run metadata.
316
+ projectPath:
317
+ type: string
318
+ description: Required for `custom`; optional for `pixcode_app`, where the server resolves the app root.
319
+
320
+ WorkflowRun:
321
+ type: object
322
+ properties:
323
+ id: { type: string, example: wrun_1234abcd }
324
+ workflowId: { type: string, example: agent_team }
325
+ contextId:
326
+ type: string
327
+ description: Shared Hermes context id used by every child task in this run.
328
+ example: ctx_1234abcd
329
+ status:
330
+ type: string
331
+ enum: [queued, running, completed, failed, canceled]
332
+ input: { type: string }
333
+ startedAt: { type: integer, format: int64 }
334
+ finishedAt: { type: integer, format: int64 }
335
+ metadata: { type: object, additionalProperties: true }
336
+ nodeRuns:
337
+ type: array
338
+ items: { $ref: '#/components/schemas/WorkflowNodeRun' }
339
+
340
+ WorkflowRunCreateRequest:
341
+ type: object
342
+ properties:
343
+ input:
344
+ type: string
345
+ description: User goal sent to the workflow.
346
+ metadata:
347
+ type: object
348
+ properties:
349
+ projectId: { type: string }
350
+ selectedProjectPath:
351
+ type: string
352
+ description: Absolute path of the UI-selected project used for history grouping and fallback.
353
+ projectPath:
354
+ type: string
355
+ description: Resolved absolute host path where CLI agents should run.
356
+ workspaceTarget:
357
+ $ref: '#/components/schemas/WorkspaceTarget'
358
+ agents:
359
+ type: array
360
+ items: { $ref: '#/components/schemas/OrchestrationAgent' }
361
+ settings:
362
+ type: object
363
+ properties:
364
+ maxParallelAgents:
365
+ type: integer
366
+ minimum: 1
367
+ maximum: 12
368
+ default: 3
369
+ isolation:
370
+ type: string
371
+ enum: [host, worktree, docker]
372
+ keepWorkspace:
373
+ type: boolean
374
+ default: true
375
+
376
+ WorkflowPreviewResponse:
377
+ type: object
378
+ properties:
379
+ workflow:
380
+ type: object
381
+ additionalProperties: true
382
+ nodeCount: { type: integer }
383
+ nodes:
384
+ type: array
385
+ items:
386
+ type: object
387
+ properties:
388
+ id: { type: string }
389
+ adapterId: { type: string }
390
+ agentInstanceId: { type: string }
391
+ agentLabel: { type: string }
392
+ inputs:
393
+ type: array
394
+ items: { type: string }
395
+ onFail: { type: string, enum: [abort, continue, retry] }
396
+ output: { type: string, enum: [message, artifact, both] }
397
+ timeoutMs: { type: integer }
398
+
399
+ security:
400
+ - bearerAuth: []
401
+ - apiKeyAuth: []
402
+ - cookieAuth: []
403
+
404
+ paths:
405
+ /health:
406
+ get:
407
+ tags: [System]
408
+ summary: Liveness + version probe
409
+ description: |
410
+ Public, unauthenticated. Returns server version and install mode so the
411
+ UI can detect updates and stale daemons. Used by:
412
+
413
+ - The version-upgrade modal — polls during/after `/api/system/update`
414
+ to detect when the new version is up.
415
+ - `useVersionCheck` — falls back to the bundle's baked
416
+ `__PIXCODE_UI_VERSION__` if `version` is missing or non-semver.
417
+ security: []
418
+ responses:
419
+ '200':
420
+ description: Server is up.
421
+ content:
422
+ application/json:
423
+ schema: { $ref: '#/components/schemas/Health' }
424
+
425
+ /api/system/update:
426
+ post:
427
+ tags: [System]
428
+ summary: Self-update (SSE)
429
+ description: |
430
+ Streams the update process via SSE. Behavior depends on
431
+ `installMode`:
432
+
433
+ - **runtime-dir** (desktop wrapper): downloads the latest npm tarball,
434
+ atomically swaps files, emits `done { selfRestarting: true }`, then
435
+ `process.exit(42)` so the wrapper respawns. **Don't `POST /restart`
436
+ when `selfRestarting` is true.**
437
+ - **git/npm-global**: runs `git pull && npm install` or
438
+ `npm install -g`. The supervising daemon may restart the server
439
+ mid-stream — clients should treat a bare close + `/health` version
440
+ bump as success.
441
+ responses:
442
+ '200':
443
+ description: 'SSE stream of `event: log`, `event: progress`, `event: done`, `event: error`.'
444
+ content:
445
+ text/event-stream:
446
+ schema: { type: string }
447
+
448
+ /api/system/restart:
449
+ post:
450
+ tags: [System]
451
+ summary: Restart the server process
452
+ description: |
453
+ Triggers a graceful exit; the supervising daemon (systemd/pm2/electron
454
+ wrapper) is expected to respawn. Don't call after a `selfRestarting`
455
+ update event — the wrapper has already been signalled.
456
+ responses:
457
+ '200':
458
+ description: Restart scheduled.
459
+
460
+ /api/auth/status:
461
+ get:
462
+ tags: [Authentication]
463
+ summary: Probe authentication state
464
+ description: Returns whether the current request carries a valid token, and whether the system has any users at all (`needsSetup`).
465
+ security: []
466
+ responses:
467
+ '200':
468
+ description: Auth status.
469
+ content:
470
+ application/json:
471
+ schema: { $ref: '#/components/schemas/AuthStatus' }
472
+
473
+ /api/auth/register:
474
+ post:
475
+ tags: [Authentication]
476
+ summary: Register the first user
477
+ description: Only allowed while `needsSetup` is true. Subsequent calls return 403.
478
+ security: []
479
+ requestBody:
480
+ required: true
481
+ content:
482
+ application/json:
483
+ schema: { $ref: '#/components/schemas/LoginRequest' }
484
+ responses:
485
+ '200':
486
+ description: Registered + auto-logged-in.
487
+ content:
488
+ application/json:
489
+ schema: { $ref: '#/components/schemas/LoginResponse' }
490
+ '403':
491
+ description: Setup already complete.
492
+ content:
493
+ application/json:
494
+ schema: { $ref: '#/components/schemas/Error' }
495
+
496
+ /api/auth/login:
497
+ post:
498
+ tags: [Authentication]
499
+ summary: Log in
500
+ security: []
501
+ requestBody:
502
+ required: true
503
+ content:
504
+ application/json:
505
+ schema: { $ref: '#/components/schemas/LoginRequest' }
506
+ responses:
507
+ '200':
508
+ description: Login OK; sets `token` cookie + returns JWT in body.
509
+ content:
510
+ application/json:
511
+ schema: { $ref: '#/components/schemas/LoginResponse' }
512
+ '401':
513
+ description: Invalid credentials.
514
+
515
+ /api/auth/user:
516
+ get:
517
+ tags: [Authentication]
518
+ summary: Current user
519
+ responses:
520
+ '200':
521
+ description: Authenticated user details.
522
+ content:
523
+ application/json:
524
+ schema:
525
+ type: object
526
+ properties:
527
+ user: { $ref: '#/components/schemas/User' }
528
+
529
+ /api/auth/logout:
530
+ post:
531
+ tags: [Authentication]
532
+ summary: Log out
533
+ description: Clears the `token` cookie. JWT remains valid until expiry — server-side blacklist isn't implemented.
534
+ responses:
535
+ '200': { description: OK }
536
+
537
+ /api/settings/api-keys:
538
+ get:
539
+ tags: [Authentication]
540
+ summary: List user API keys
541
+ responses:
542
+ '200':
543
+ description: List of keys (the `api_key` field is masked except on creation).
544
+ content:
545
+ application/json:
546
+ schema:
547
+ type: array
548
+ items: { $ref: '#/components/schemas/ApiKey' }
549
+ post:
550
+ tags: [Authentication]
551
+ summary: Create an API key
552
+ requestBody:
553
+ required: true
554
+ content:
555
+ application/json:
556
+ schema:
557
+ type: object
558
+ required: [name]
559
+ properties:
560
+ name: { type: string, description: 'Human-readable label.' }
561
+ responses:
562
+ '201':
563
+ description: Key created. The full `api_key` value is returned **once** — store it.
564
+ content:
565
+ application/json:
566
+ schema: { $ref: '#/components/schemas/ApiKey' }
567
+
568
+ /api/settings/api-keys/{keyId}:
569
+ delete:
570
+ tags: [Authentication]
571
+ summary: Delete an API key
572
+ parameters:
573
+ - name: keyId
574
+ in: path
575
+ required: true
576
+ schema: { type: integer }
577
+ responses:
578
+ '200': { description: Deleted. }
579
+
580
+ /api/settings/api-keys/{keyId}/toggle:
581
+ patch:
582
+ tags: [Authentication]
583
+ summary: Activate / deactivate an API key
584
+ parameters:
585
+ - name: keyId
586
+ in: path
587
+ required: true
588
+ schema: { type: integer }
589
+ requestBody:
590
+ required: true
591
+ content:
592
+ application/json:
593
+ schema:
594
+ type: object
595
+ properties:
596
+ is_active: { type: boolean }
597
+ responses:
598
+ '200': { description: Updated. }
599
+
600
+ /api/projects:
601
+ get:
602
+ tags: [Projects]
603
+ summary: List all projects
604
+ description: Walks `~/.claude/projects/*` plus any registered workspaces and returns a unified list. Sessions are flattened by provider.
605
+ responses:
606
+ '200':
607
+ description: Project list.
608
+ content:
609
+ application/json:
610
+ schema:
611
+ type: array
612
+ items: { $ref: '#/components/schemas/Project' }
613
+
614
+ /api/projects/quick-start:
615
+ post:
616
+ tags: [Projects]
617
+ summary: Open or create a project from an absolute path
618
+ requestBody:
619
+ required: true
620
+ content:
621
+ application/json:
622
+ schema:
623
+ type: object
624
+ required: [path]
625
+ properties:
626
+ path: { type: string, description: 'Absolute filesystem path.' }
627
+ responses:
628
+ '200':
629
+ description: Project record (created if it didn't exist).
630
+ content:
631
+ application/json:
632
+ schema: { $ref: '#/components/schemas/Project' }
633
+
634
+ /api/projects/{projectName}/rename:
635
+ put:
636
+ tags: [Projects]
637
+ summary: Rename project display
638
+ parameters:
639
+ - { name: projectName, in: path, required: true, schema: { type: string } }
640
+ requestBody:
641
+ required: true
642
+ content:
643
+ application/json:
644
+ schema:
645
+ type: object
646
+ properties:
647
+ displayName: { type: string }
648
+ responses:
649
+ '200': { description: Renamed. }
650
+
651
+ /api/projects/{projectName}:
652
+ delete:
653
+ tags: [Projects]
654
+ summary: Delete (deregister) a project
655
+ parameters:
656
+ - { name: projectName, in: path, required: true, schema: { type: string } }
657
+ responses:
658
+ '200': { description: Deleted. }
659
+
660
+ /api/projects/{projectName}/sessions:
661
+ get:
662
+ tags: [Sessions]
663
+ summary: List sessions for a project
664
+ parameters:
665
+ - { name: projectName, in: path, required: true, schema: { type: string } }
666
+ responses:
667
+ '200':
668
+ description: Sessions sorted by lastActivity desc.
669
+ content:
670
+ application/json:
671
+ schema:
672
+ type: array
673
+ items: { $ref: '#/components/schemas/SessionMeta' }
674
+
675
+ /api/projects/{projectName}/sessions/{sessionId}:
676
+ delete:
677
+ tags: [Sessions]
678
+ summary: Delete a session
679
+ parameters:
680
+ - { name: projectName, in: path, required: true, schema: { type: string } }
681
+ - { name: sessionId, in: path, required: true, schema: { type: string } }
682
+ responses:
683
+ '200': { description: Deleted. }
684
+
685
+ /api/sessions/{sessionId}/rename:
686
+ put:
687
+ tags: [Sessions]
688
+ summary: Rename a session
689
+ parameters:
690
+ - { name: sessionId, in: path, required: true, schema: { type: string } }
691
+ requestBody:
692
+ required: true
693
+ content:
694
+ application/json:
695
+ schema:
696
+ type: object
697
+ properties:
698
+ title: { type: string }
699
+ responses:
700
+ '200': { description: Renamed. }
701
+
702
+ /api/sessions/{sessionId}/messages:
703
+ get:
704
+ tags: [Sessions]
705
+ summary: Get session message history
706
+ description: |
707
+ Note: this is mounted at `/api/sessions`, NOT under `/api/projects` — the
708
+ `projectName` is supplied as a query parameter rather than a path
709
+ segment. The mount lives in `server/routes/messages.js`.
710
+ parameters:
711
+ - { name: sessionId, in: path, required: true, schema: { type: string } }
712
+ - { name: projectName, in: query, required: true, schema: { type: string }, description: Pixcode project the session belongs to. }
713
+ - { name: limit, in: query, required: false, schema: { type: integer, default: 100 } }
714
+ - { name: offset, in: query, required: false, schema: { type: integer, default: 0 } }
715
+ responses:
716
+ '200':
717
+ description: Normalized message stream.
718
+ content:
719
+ application/json:
720
+ schema:
721
+ type: object
722
+ properties:
723
+ messages: { type: array, items: { type: object, additionalProperties: true } }
724
+ total: { type: integer }
725
+ hasMore: { type: boolean }
726
+
727
+ /api/search/conversations:
728
+ get:
729
+ tags: [Search]
730
+ summary: Full-text search across all sessions
731
+ parameters:
732
+ - { name: q, in: query, required: true, schema: { type: string }, description: Search query. }
733
+ - { name: provider, in: query, required: false, schema: { type: string, enum: [claude, cursor, codex, gemini, qwen, opencode] } }
734
+ - { name: limit, in: query, required: false, schema: { type: integer, default: 50 } }
735
+ responses:
736
+ '200':
737
+ description: Ranked matches.
738
+ content:
739
+ application/json:
740
+ schema:
741
+ type: object
742
+ properties:
743
+ results: { type: array, items: { type: object, additionalProperties: true } }
744
+ total: { type: integer }
745
+
746
+ /api/projects/{projectName}/files:
747
+ get:
748
+ tags: [Files]
749
+ summary: List files in a project subtree
750
+ parameters:
751
+ - { name: projectName, in: path, required: true, schema: { type: string } }
752
+ - { name: path, in: query, required: false, schema: { type: string }, description: Subdirectory relative to project root. }
753
+ responses:
754
+ '200':
755
+ description: Directory listing.
756
+ content:
757
+ application/json:
758
+ schema:
759
+ type: array
760
+ items:
761
+ type: object
762
+ properties:
763
+ name: { type: string }
764
+ path: { type: string }
765
+ type: { type: string, enum: [file, directory] }
766
+ size: { type: integer, nullable: true }
767
+ delete:
768
+ tags: [Files]
769
+ summary: Delete a file or folder (path in body)
770
+ description: |
771
+ Same path as the listing endpoint above — discriminated by HTTP method.
772
+ The target's project-relative path goes in the body, NOT the query
773
+ string (so directory deletes can't be partially URL-encoded into a
774
+ broken state).
775
+ parameters:
776
+ - { name: projectName, in: path, required: true, schema: { type: string } }
777
+ requestBody:
778
+ required: true
779
+ content:
780
+ application/json:
781
+ schema:
782
+ type: object
783
+ required: [path]
784
+ properties:
785
+ path: { type: string, description: 'Project-relative path of the file or directory to delete.' }
786
+ type: { type: string, enum: [file, directory], description: 'Optional hint; server detects automatically if omitted.' }
787
+ responses:
788
+ '200': { description: Deleted. }
789
+
790
+ /api/projects/{projectName}/file:
791
+ get:
792
+ tags: [Files]
793
+ summary: Read a single file
794
+ parameters:
795
+ - { name: projectName, in: path, required: true, schema: { type: string } }
796
+ - { name: path, in: query, required: true, schema: { type: string } }
797
+ responses:
798
+ '200':
799
+ description: File contents (utf-8 text or base64 binary).
800
+ content:
801
+ application/json:
802
+ schema:
803
+ type: object
804
+ properties:
805
+ content: { type: string }
806
+ encoding: { type: string, enum: [utf-8, base64] }
807
+ put:
808
+ tags: [Files]
809
+ summary: Overwrite a file
810
+ parameters:
811
+ - { name: projectName, in: path, required: true, schema: { type: string } }
812
+ requestBody:
813
+ required: true
814
+ content:
815
+ application/json:
816
+ schema:
817
+ type: object
818
+ required: [path, content]
819
+ properties:
820
+ path: { type: string }
821
+ content: { type: string }
822
+ responses:
823
+ '200': { description: Saved. }
824
+
825
+ /api/projects/{projectName}/files/create:
826
+ post:
827
+ tags: [Files]
828
+ summary: Create a new file or folder
829
+ parameters:
830
+ - { name: projectName, in: path, required: true, schema: { type: string } }
831
+ requestBody:
832
+ required: true
833
+ content:
834
+ application/json:
835
+ schema:
836
+ type: object
837
+ required: [path, type]
838
+ properties:
839
+ path: { type: string }
840
+ type: { type: string, enum: [file, directory] }
841
+ content: { type: string, description: 'Initial content for files; ignored for directories.' }
842
+ responses:
843
+ '201': { description: Created. }
844
+
845
+ /api/projects/{projectName}/files/rename:
846
+ put:
847
+ tags: [Files]
848
+ summary: Rename / move a file
849
+ parameters:
850
+ - { name: projectName, in: path, required: true, schema: { type: string } }
851
+ requestBody:
852
+ required: true
853
+ content:
854
+ application/json:
855
+ schema:
856
+ type: object
857
+ required: [oldPath, newPath]
858
+ properties:
859
+ oldPath: { type: string }
860
+ newPath: { type: string }
861
+ responses:
862
+ '200': { description: Renamed. }
863
+
864
+
865
+ /api/browse-filesystem:
866
+ get:
867
+ tags: [Files]
868
+ summary: Native filesystem browser (outside project tree)
869
+ description: Used by Quick Start to let the user pick a folder anywhere on the host. Honours `~` expansion.
870
+ parameters:
871
+ - { name: path, in: query, required: false, schema: { type: string, default: '~' } }
872
+ responses:
873
+ '200':
874
+ description: Directory listing.
875
+ content:
876
+ application/json:
877
+ schema:
878
+ type: object
879
+ properties:
880
+ path: { type: string }
881
+ parent: { type: string, nullable: true }
882
+ entries:
883
+ type: array
884
+ items:
885
+ type: object
886
+ properties:
887
+ name: { type: string }
888
+ type: { type: string, enum: [file, directory] }
889
+
890
+ /api/git/status:
891
+ get:
892
+ tags: [Git]
893
+ summary: Working tree status
894
+ parameters:
895
+ - { name: project, in: query, required: true, schema: { type: string } }
896
+ responses:
897
+ '200':
898
+ description: Git status snapshot.
899
+ content:
900
+ application/json:
901
+ schema: { $ref: '#/components/schemas/GitStatus' }
902
+
903
+ /api/git/diff:
904
+ get:
905
+ tags: [Git]
906
+ summary: Unified diff for one file or the whole tree
907
+ parameters:
908
+ - { name: project, in: query, required: true, schema: { type: string } }
909
+ - { name: file, in: query, required: false, schema: { type: string } }
910
+ - { name: staged, in: query, required: false, schema: { type: boolean, default: false } }
911
+ responses:
912
+ '200':
913
+ description: Diff text.
914
+ content:
915
+ application/json:
916
+ schema:
917
+ type: object
918
+ properties:
919
+ diff: { type: string }
920
+
921
+ /api/git/branches:
922
+ get:
923
+ tags: [Git]
924
+ summary: List local + remote branches
925
+ parameters:
926
+ - { name: project, in: query, required: true, schema: { type: string } }
927
+ responses:
928
+ '200':
929
+ description: Branch list.
930
+ content:
931
+ application/json:
932
+ schema:
933
+ type: object
934
+ properties:
935
+ current: { type: string }
936
+ local: { type: array, items: { type: string } }
937
+ remote: { type: array, items: { type: string } }
938
+
939
+ /api/git/commit:
940
+ post:
941
+ tags: [Git]
942
+ summary: Create a commit
943
+ requestBody:
944
+ required: true
945
+ content:
946
+ application/json:
947
+ schema:
948
+ type: object
949
+ required: [project, message]
950
+ properties:
951
+ project: { type: string }
952
+ message: { type: string }
953
+ files: { type: array, items: { type: string }, description: 'When omitted, all staged changes are committed.' }
954
+ responses:
955
+ '200': { description: Commit created. }
956
+
957
+ /api/git/push:
958
+ post:
959
+ tags: [Git]
960
+ summary: Push to remote
961
+ requestBody:
962
+ required: true
963
+ content:
964
+ application/json:
965
+ schema:
966
+ type: object
967
+ required: [project]
968
+ properties:
969
+ project: { type: string }
970
+ remote: { type: string, default: origin }
971
+ branch: { type: string }
972
+ force: { type: boolean, default: false }
973
+ responses:
974
+ '200': { description: Pushed. }
975
+
976
+ /api/git/pull:
977
+ post:
978
+ tags: [Git]
979
+ summary: Pull from remote
980
+ requestBody:
981
+ required: true
982
+ content:
983
+ application/json:
984
+ schema:
985
+ type: object
986
+ required: [project]
987
+ properties:
988
+ project: { type: string }
989
+ responses:
990
+ '200': { description: Pulled. }
991
+
992
+ /api/git/checkout:
993
+ post:
994
+ tags: [Git]
995
+ summary: Switch branch
996
+ requestBody:
997
+ required: true
998
+ content:
999
+ application/json:
1000
+ schema:
1001
+ type: object
1002
+ required: [project, branch]
1003
+ properties:
1004
+ project: { type: string }
1005
+ branch: { type: string }
1006
+ responses:
1007
+ '200': { description: Switched. }
1008
+
1009
+ /api/providers/credentials:
1010
+ get:
1011
+ tags: [Providers]
1012
+ summary: List stored credentials across providers
1013
+ description: Returns a sanitised inventory of API keys / OAuth tokens Pixcode is currently holding for each provider. Real secret values are NOT returned — only presence + masked tail.
1014
+ responses:
1015
+ '200':
1016
+ description: Credentials inventory.
1017
+ content:
1018
+ application/json:
1019
+ schema:
1020
+ type: object
1021
+ additionalProperties:
1022
+ type: object
1023
+ properties:
1024
+ hasCredential: { type: boolean }
1025
+ masked: { type: string, nullable: true, example: '...beef' }
1026
+
1027
+ /api/providers/{provider}/auth/status:
1028
+ get:
1029
+ tags: [Providers]
1030
+ summary: Auth status for a single provider
1031
+ description: |
1032
+ Returns whether the provider's CLI is installed, whether it has a
1033
+ valid auth credential (api key / OAuth token), and the resolved
1034
+ binary path the spawn layer will use.
1035
+ parameters:
1036
+ - { name: provider, in: path, required: true, schema: { type: string, enum: [claude, cursor, codex, gemini, qwen, opencode] } }
1037
+ responses:
1038
+ '200':
1039
+ description: Auth status snapshot.
1040
+ content:
1041
+ application/json:
1042
+ schema: { $ref: '#/components/schemas/ProviderInfo' }
1043
+
1044
+ /api/providers/{provider}/auth/api-key:
1045
+ post:
1046
+ tags: [Providers]
1047
+ summary: Save / replace an API-key credential for a provider
1048
+ parameters:
1049
+ - { name: provider, in: path, required: true, schema: { type: string } }
1050
+ requestBody:
1051
+ required: true
1052
+ content:
1053
+ application/json:
1054
+ schema:
1055
+ type: object
1056
+ required: [apiKey]
1057
+ properties:
1058
+ apiKey: { type: string }
1059
+ baseUrl: { type: string, description: Optional override (e.g. self-hosted Anthropic compat endpoint). }
1060
+ responses:
1061
+ '200': { description: Credential saved. }
1062
+
1063
+ /api/providers/{provider}/oauth-paste:
1064
+ post:
1065
+ tags: [Providers]
1066
+ summary: Paste an OAuth callback URL to complete login
1067
+ description: |
1068
+ For providers (Claude, Cursor) whose login flow opens a browser tab and
1069
+ bounces back to a URL the user copies into Pixcode. The handler parses
1070
+ the token and stores it as the active credential.
1071
+ parameters:
1072
+ - { name: provider, in: path, required: true, schema: { type: string } }
1073
+ requestBody:
1074
+ required: true
1075
+ content:
1076
+ application/json:
1077
+ schema:
1078
+ type: object
1079
+ required: [url]
1080
+ properties:
1081
+ url: { type: string, format: uri }
1082
+ responses:
1083
+ '200': { description: Token extracted and stored. }
1084
+ '400': { description: URL did not contain a recognisable token. }
1085
+
1086
+ /api/providers/{provider}/models:
1087
+ get:
1088
+ tags: [Providers]
1089
+ summary: List models the provider's CLI exposes
1090
+ description: |
1091
+ Pixcode caches the model list per provider on first call (or when the
1092
+ cache is busted via `DELETE …/models/cache`). Each entry is the
1093
+ `provider/model` form OpenCode expects.
1094
+ parameters:
1095
+ - { name: provider, in: path, required: true, schema: { type: string } }
1096
+ responses:
1097
+ '200':
1098
+ description: Model catalog.
1099
+ content:
1100
+ application/json:
1101
+ schema:
1102
+ type: array
1103
+ items:
1104
+ type: object
1105
+ properties:
1106
+ id: { type: string, example: 'opencode/gpt-5.2' }
1107
+ name: { type: string }
1108
+ contextWindow: { type: integer, nullable: true }
1109
+
1110
+ /api/providers/{provider}/models/cache:
1111
+ delete:
1112
+ tags: [Providers]
1113
+ summary: Bust the cached model list for one provider
1114
+ parameters:
1115
+ - { name: provider, in: path, required: true, schema: { type: string } }
1116
+ responses:
1117
+ '200': { description: Cache cleared; next GET re-fetches. }
1118
+
1119
+ /api/providers/{provider}/install:
1120
+ post:
1121
+ tags: [Providers]
1122
+ summary: Install / update a provider CLI in the Pixcode sandbox
1123
+ description: |
1124
+ Installs the provider's npm package into `~/.pixcode/cli-bin/` (no
1125
+ `-g`, no sudo/UAC). Returns a `jobId` immediately; subscribe to
1126
+ `/install/{jobId}/stream` for live logs.
1127
+ parameters:
1128
+ - { name: provider, in: path, required: true, schema: { type: string } }
1129
+ responses:
1130
+ '202':
1131
+ description: Job accepted.
1132
+ content:
1133
+ application/json:
1134
+ schema: { $ref: '#/components/schemas/InstallJob' }
1135
+
1136
+ /api/providers/{provider}/install/{jobId}/stream:
1137
+ get:
1138
+ tags: [Providers]
1139
+ summary: Stream install job output (SSE)
1140
+ description: Replays buffered output, then streams live until the job ends. Send `Last-Event-ID` to resume after disconnect.
1141
+ parameters:
1142
+ - { name: provider, in: path, required: true, schema: { type: string } }
1143
+ - { name: jobId, in: path, required: true, schema: { type: string } }
1144
+ responses:
1145
+ '200':
1146
+ description: 'SSE event stream — `event: log`, `event: status`, `event: done`, `event: error`.'
1147
+ content:
1148
+ text/event-stream:
1149
+ schema: { type: string }
1150
+
1151
+ /api/providers/{provider}/install/{jobId}:
1152
+ delete:
1153
+ tags: [Providers]
1154
+ summary: Cancel an in-flight install
1155
+ parameters:
1156
+ - { name: provider, in: path, required: true, schema: { type: string } }
1157
+ - { name: jobId, in: path, required: true, schema: { type: string } }
1158
+ responses:
1159
+ '200': { description: Cancelled. }
1160
+
1161
+ /api/providers/{provider}/mcp/servers:
1162
+ get:
1163
+ tags: [MCP]
1164
+ summary: List MCP servers configured for one provider
1165
+ parameters:
1166
+ - { name: provider, in: path, required: true, schema: { type: string } }
1167
+ responses:
1168
+ '200':
1169
+ description: MCP server list (matches the provider's native config schema).
1170
+ content:
1171
+ application/json:
1172
+ schema:
1173
+ type: array
1174
+ items: { type: object, additionalProperties: true }
1175
+ post:
1176
+ tags: [MCP]
1177
+ summary: Add or replace an MCP server entry
1178
+ parameters:
1179
+ - { name: provider, in: path, required: true, schema: { type: string } }
1180
+ requestBody:
1181
+ required: true
1182
+ content:
1183
+ application/json:
1184
+ schema:
1185
+ type: object
1186
+ required: [name, command]
1187
+ properties:
1188
+ name: { type: string }
1189
+ command: { type: string }
1190
+ args: { type: array, items: { type: string } }
1191
+ env: { type: object, additionalProperties: { type: string } }
1192
+ scope: { type: string, enum: [local, user], default: user }
1193
+ responses:
1194
+ '200': { description: Server saved. }
1195
+
1196
+ /api/providers/{provider}/mcp/servers/{name}:
1197
+ delete:
1198
+ tags: [MCP]
1199
+ summary: Remove an MCP server entry
1200
+ parameters:
1201
+ - { name: provider, in: path, required: true, schema: { type: string } }
1202
+ - { name: name, in: path, required: true, schema: { type: string } }
1203
+ responses:
1204
+ '200': { description: Removed. }
1205
+
1206
+ /api/providers/mcp/servers/global:
1207
+ post:
1208
+ tags: [MCP]
1209
+ summary: Add an MCP server to every provider that supports MCP
1210
+ description: Convenience endpoint that fans out the same server config to all MCP-capable providers (Claude, Cursor, Codex, OpenCode). Per-provider edits override.
1211
+ requestBody:
1212
+ required: true
1213
+ content:
1214
+ application/json:
1215
+ schema:
1216
+ type: object
1217
+ required: [name, command]
1218
+ properties:
1219
+ name: { type: string }
1220
+ command: { type: string }
1221
+ args: { type: array, items: { type: string } }
1222
+ env: { type: object, additionalProperties: { type: string } }
1223
+ responses:
1224
+ '200': { description: Server fanned out. }
1225
+
1226
+ /api/providers/{provider}/config-files:
1227
+ get:
1228
+ tags: [Providers]
1229
+ summary: List config files Pixcode knows about for a provider
1230
+ description: |
1231
+ Returns the catalog of editable config files for a provider — typically
1232
+ `settings.json`, `auth.json`, `opencode.json`, etc. Each entry has an
1233
+ opaque `fileId` used by `GET/PUT …/{fileId}`.
1234
+ parameters:
1235
+ - { name: provider, in: path, required: true, schema: { type: string } }
1236
+ responses:
1237
+ '200':
1238
+ description: Config file catalog.
1239
+ content:
1240
+ application/json:
1241
+ schema:
1242
+ type: array
1243
+ items:
1244
+ type: object
1245
+ properties:
1246
+ fileId: { type: string }
1247
+ path: { type: string }
1248
+ label: { type: string }
1249
+ exists: { type: boolean }
1250
+ size: { type: integer, nullable: true }
1251
+
1252
+ /api/providers/{provider}/config-files/{fileId}:
1253
+ get:
1254
+ tags: [Providers]
1255
+ summary: Read a provider config file's contents
1256
+ parameters:
1257
+ - { name: provider, in: path, required: true, schema: { type: string } }
1258
+ - { name: fileId, in: path, required: true, schema: { type: string } }
1259
+ responses:
1260
+ '200':
1261
+ description: File contents.
1262
+ content:
1263
+ application/json:
1264
+ schema:
1265
+ type: object
1266
+ properties:
1267
+ content: { type: string }
1268
+ path: { type: string }
1269
+ encoding: { type: string, enum: [utf-8] }
1270
+ put:
1271
+ tags: [Providers]
1272
+ summary: Overwrite a provider config file
1273
+ parameters:
1274
+ - { name: provider, in: path, required: true, schema: { type: string } }
1275
+ - { name: fileId, in: path, required: true, schema: { type: string } }
1276
+ requestBody:
1277
+ required: true
1278
+ content:
1279
+ application/json:
1280
+ schema:
1281
+ type: object
1282
+ required: [content]
1283
+ properties:
1284
+ content: { type: string }
1285
+ responses:
1286
+ '200': { description: Saved. }
1287
+ '400': { description: Content failed validation (e.g. malformed JSON). }
1288
+
1289
+ /api/orchestration/workflows:
1290
+ get:
1291
+ tags: [Orchestration]
1292
+ summary: List built-in workflow modes
1293
+ description: |
1294
+ Returns the available "Çalışma modu / Work mode" definitions. The
1295
+ `agent_team` workflow is dynamic: it expands from the API caller's
1296
+ `metadata.agents` list at preview/run time.
1297
+ responses:
1298
+ '200':
1299
+ description: Workflow catalog.
1300
+ content:
1301
+ application/json:
1302
+ schema:
1303
+ type: object
1304
+ properties:
1305
+ workflows:
1306
+ type: array
1307
+ items:
1308
+ type: object
1309
+ additionalProperties: true
1310
+
1311
+ /api/orchestration/workflows/context:
1312
+ get:
1313
+ tags: [Orchestration]
1314
+ summary: Read workflow execution context
1315
+ description: |
1316
+ Returns the Pixcode app root and supported target workspace modes so
1317
+ clients can decide whether child agents should run in the selected
1318
+ project, Pixcode itself, or a custom path.
1319
+ responses:
1320
+ '200':
1321
+ description: Workflow execution context.
1322
+ content:
1323
+ application/json:
1324
+ schema:
1325
+ type: object
1326
+ properties:
1327
+ appRoot: { type: string, example: /root/pixcode }
1328
+ defaultWorkspaceTarget: { type: string, example: selected_project }
1329
+ supportedWorkspaceTargets:
1330
+ type: array
1331
+ items:
1332
+ type: string
1333
+ enum: [selected_project, pixcode_app, custom]
1334
+
1335
+ /api/orchestration/workflows/{workflowId}/preview:
1336
+ post:
1337
+ tags: [Orchestration]
1338
+ summary: Preview expanded workflow DAG without running agents
1339
+ description: |
1340
+ Dry-run endpoint for API clients and automated tests. It expands
1341
+ `metadata.agents` into the actual node graph, validates dependencies,
1342
+ and returns node ids, adapters, inputs, fail policy, and timeout values.
1343
+
1344
+ Use `metadata.agents[].role` (`backend`, `frontend`, `review`,
1345
+ `implementation`) for language-independent routing. `instruction` is
1346
+ optional and fully caller-controlled.
1347
+ parameters:
1348
+ - name: workflowId
1349
+ in: path
1350
+ required: true
1351
+ schema: { type: string, example: agent_team }
1352
+ requestBody:
1353
+ required: false
1354
+ content:
1355
+ application/json:
1356
+ schema: { $ref: '#/components/schemas/WorkflowRunCreateRequest' }
1357
+ examples:
1358
+ roleBasedAgentTeam:
1359
+ summary: Role-based agent team, no fixed instruction language
1360
+ value:
1361
+ metadata:
1362
+ agents:
1363
+ - adapterId: codex
1364
+ label: Frontend Agent
1365
+ role: frontend
1366
+ - adapterId: codex
1367
+ label: Backend Agent
1368
+ role: backend
1369
+ - adapterId: codex
1370
+ label: Review Agent
1371
+ role: review
1372
+ settings:
1373
+ maxParallelAgents: 3
1374
+ isolation: host
1375
+ responses:
1376
+ '200':
1377
+ description: Expanded workflow graph.
1378
+ content:
1379
+ application/json:
1380
+ schema: { $ref: '#/components/schemas/WorkflowPreviewResponse' }
1381
+ '400':
1382
+ description: Invalid workflow metadata.
1383
+
1384
+ /api/orchestration/workflows/{workflowId}/runs:
1385
+ post:
1386
+ tags: [Orchestration]
1387
+ summary: Start a workflow run
1388
+ description: |
1389
+ Starts a multi-agent workflow. Every child Hermes task shares one
1390
+ `contextId`, and returned child task ids can be used for low-level
1391
+ Hermes inspection.
1392
+
1393
+ For `agent_team`, Pixcode creates a coordinator, optional bounded
1394
+ backend handoff nodes, worker nodes, review nodes, and a final report.
1395
+ Frontend agents depend on backend handoff contracts, not on the full
1396
+ backend implementation, so one slow backend task does not block all
1397
+ UI work.
1398
+ parameters:
1399
+ - name: workflowId
1400
+ in: path
1401
+ required: true
1402
+ schema: { type: string, example: agent_team }
1403
+ requestBody:
1404
+ required: true
1405
+ content:
1406
+ application/json:
1407
+ schema: { $ref: '#/components/schemas/WorkflowRunCreateRequest' }
1408
+ responses:
1409
+ '202':
1410
+ description: Workflow accepted.
1411
+ content:
1412
+ application/json:
1413
+ schema: { $ref: '#/components/schemas/WorkflowRun' }
1414
+ '400':
1415
+ description: Invalid workflow request.
1416
+ '404':
1417
+ description: Workflow not found.
1418
+
1419
+ /api/orchestration/workflows/runs:
1420
+ get:
1421
+ tags: [Orchestration]
1422
+ summary: List workflow runs
1423
+ parameters:
1424
+ - name: projectId
1425
+ in: query
1426
+ required: false
1427
+ schema: { type: string }
1428
+ responses:
1429
+ '200':
1430
+ description: Runs sorted newest first.
1431
+ content:
1432
+ application/json:
1433
+ schema:
1434
+ type: object
1435
+ properties:
1436
+ runs:
1437
+ type: array
1438
+ items: { $ref: '#/components/schemas/WorkflowRun' }
1439
+
1440
+ /api/orchestration/workflows/runs/{runId}:
1441
+ get:
1442
+ tags: [Orchestration]
1443
+ summary: Read one workflow run snapshot
1444
+ parameters:
1445
+ - name: runId
1446
+ in: path
1447
+ required: true
1448
+ schema: { type: string }
1449
+ responses:
1450
+ '200':
1451
+ description: Workflow run state.
1452
+ content:
1453
+ application/json:
1454
+ schema: { $ref: '#/components/schemas/WorkflowRun' }
1455
+ '404':
1456
+ description: Run not found.
1457
+
1458
+ /api/orchestration/workflows/runs/{runId}/events:
1459
+ get:
1460
+ tags: [Orchestration]
1461
+ summary: Stream workflow run snapshots (SSE)
1462
+ description: |
1463
+ Emits `event: snapshot` frames every second while the run is active.
1464
+ Each `data:` payload is `{ "run": WorkflowRun }`. The stream ends
1465
+ automatically when the run reaches `completed`, `failed`, or
1466
+ `canceled`.
1467
+ parameters:
1468
+ - name: runId
1469
+ in: path
1470
+ required: true
1471
+ schema: { type: string }
1472
+ responses:
1473
+ '200':
1474
+ description: Server-Sent Events stream.
1475
+ content:
1476
+ text/event-stream:
1477
+ schema: { type: string }
1478
+ '404':
1479
+ description: Run not found.
1480
+
1481
+ /api/orchestration/workflows/runs/{runId}/cancel:
1482
+ post:
1483
+ tags: [Orchestration]
1484
+ summary: Cancel a workflow run and active child Hermes tasks
1485
+ parameters:
1486
+ - name: runId
1487
+ in: path
1488
+ required: true
1489
+ schema: { type: string }
1490
+ responses:
1491
+ '200':
1492
+ description: Updated canceled run.
1493
+ content:
1494
+ application/json:
1495
+ schema: { $ref: '#/components/schemas/WorkflowRun' }
1496
+ '404':
1497
+ description: Run not found.
1498
+
1499
+ /api/network/endpoints:
1500
+ get:
1501
+ tags: [Network]
1502
+ summary: LAN endpoints for mobile QR pairing
1503
+ description: Returns every reachable IPv4 the host has bound, formatted as `http://<ip>:<port>`.
1504
+ responses:
1505
+ '200':
1506
+ description: LAN endpoint list.
1507
+ content:
1508
+ application/json:
1509
+ schema:
1510
+ type: object
1511
+ properties:
1512
+ endpoints: { type: array, items: { type: string } }
1513
+ port: { type: integer }
1514
+
1515
+ /api/network/external:
1516
+ get:
1517
+ tags: [Network]
1518
+ summary: Current external-access state (UPnP + tunnel)
1519
+ responses:
1520
+ '200':
1521
+ description: Snapshot.
1522
+ content:
1523
+ application/json:
1524
+ schema:
1525
+ type: object
1526
+ properties:
1527
+ upnp:
1528
+ type: object
1529
+ properties:
1530
+ active: { type: boolean }
1531
+ externalIp: { type: string, nullable: true }
1532
+ mappedPort: { type: integer, nullable: true }
1533
+ tunnel:
1534
+ type: object
1535
+ properties:
1536
+ active: { type: boolean }
1537
+ provider: { type: string, enum: [cloudflared, ngrok], nullable: true }
1538
+ url: { type: string, nullable: true }
1539
+
1540
+ /api/network/upnp:
1541
+ post:
1542
+ tags: [Network]
1543
+ summary: Open the LAN port on the router
1544
+ responses:
1545
+ '200': { description: Mapping created (or already present). }
1546
+ delete:
1547
+ tags: [Network]
1548
+ summary: Remove the UPnP mapping
1549
+ responses:
1550
+ '200': { description: Removed. }
1551
+
1552
+ /api/network/tunnel:
1553
+ post:
1554
+ tags: [Network]
1555
+ summary: Start a public tunnel (cloudflared / ngrok auto-detect)
1556
+ responses:
1557
+ '200':
1558
+ description: Tunnel started; URL returned.
1559
+ content:
1560
+ application/json:
1561
+ schema:
1562
+ type: object
1563
+ properties:
1564
+ url: { type: string, format: uri }
1565
+ provider: { type: string }
1566
+ delete:
1567
+ tags: [Network]
1568
+ summary: Stop the tunnel
1569
+ responses:
1570
+ '200': { description: Stopped. }
1571
+
1572
+ /api/settings/notification-preferences:
1573
+ get:
1574
+ tags: [Settings]
1575
+ summary: Get notification preferences
1576
+ responses:
1577
+ '200':
1578
+ description: Per-channel + per-event toggles.
1579
+ content:
1580
+ application/json:
1581
+ schema:
1582
+ type: object
1583
+ properties:
1584
+ preferences:
1585
+ type: object
1586
+ properties:
1587
+ channels:
1588
+ type: object
1589
+ properties:
1590
+ inApp: { type: boolean }
1591
+ webPush: { type: boolean }
1592
+ events:
1593
+ type: object
1594
+ properties:
1595
+ actionRequired: { type: boolean }
1596
+ stop: { type: boolean }
1597
+ error: { type: boolean }
1598
+ put:
1599
+ tags: [Settings]
1600
+ summary: Update notification preferences
1601
+ requestBody:
1602
+ required: true
1603
+ content:
1604
+ application/json:
1605
+ schema: { type: object }
1606
+ responses:
1607
+ '200': { description: Saved. }
1608
+
1609
+ /api/agent:
1610
+ post:
1611
+ tags: [Providers]
1612
+ summary: External REST entry point (API-key authenticated)
1613
+ description: |
1614
+ One-shot non-interactive run for automation/CI. Spawns the chosen
1615
+ provider, optionally cloning a GitHub repo first, optionally cutting
1616
+ a branch + opening a PR. **API key required** — accepts the same `px_`
1617
+ keys as the rest of the API on `Authorization: Bearer`, `X-API-Key`,
1618
+ or `?apiKey=`. Legacy `ck_` keys remain accepted.
1619
+
1620
+ Default response is an SSE stream of provider-native events; pass
1621
+ `stream: false` to buffer and return JSON.
1622
+ security:
1623
+ - bearerAuth: []
1624
+ - apiKeyAuth: []
1625
+ requestBody:
1626
+ required: true
1627
+ content:
1628
+ application/json:
1629
+ schema:
1630
+ type: object
1631
+ required: [message]
1632
+ properties:
1633
+ message:
1634
+ type: string
1635
+ description: Prompt text to send to the agent.
1636
+ provider:
1637
+ type: string
1638
+ enum: [claude, cursor, codex, gemini, qwen, opencode]
1639
+ default: claude
1640
+ model:
1641
+ type: string
1642
+ description: Provider-specific model id (e.g. `opencode/gpt-5.2`).
1643
+ projectPath:
1644
+ type: string
1645
+ description: Absolute path on the host. Required if `githubUrl` is omitted.
1646
+ githubUrl:
1647
+ type: string
1648
+ format: uri
1649
+ description: Clone this repo before running. Mutually inclusive with `projectPath` (used as the clone target if both are given).
1650
+ githubToken:
1651
+ type: string
1652
+ description: Optional override for the per-user GitHub PAT stored under Settings → Git.
1653
+ branchName:
1654
+ type: string
1655
+ description: 'Cutting `branchName` implies `createBranch: true`.'
1656
+ createBranch:
1657
+ type: boolean
1658
+ default: false
1659
+ createPR:
1660
+ type: boolean
1661
+ default: false
1662
+ sessionId:
1663
+ type: string
1664
+ description: Resume an existing session instead of starting a new one.
1665
+ stream:
1666
+ type: boolean
1667
+ default: true
1668
+ description: 'Set false to buffer to a single JSON response.'
1669
+ cleanup:
1670
+ type: boolean
1671
+ default: true
1672
+ description: When `githubUrl` was used, delete the temp clone after the run.
1673
+ responses:
1674
+ '200':
1675
+ description: |
1676
+ When `stream:true` — SSE stream of provider events. When `stream:false` — final JSON payload with `text` + `sessionId` + `usage`.
1677
+ content:
1678
+ application/json:
1679
+ schema:
1680
+ type: object
1681
+ properties:
1682
+ text: { type: string }
1683
+ sessionId: { type: string }
1684
+ usage:
1685
+ type: object
1686
+ properties:
1687
+ input: { type: integer }
1688
+ output: { type: integer }
1689
+ total: { type: integer }
1690
+ cost: { type: number }
1691
+ text/event-stream:
1692
+ schema: { type: string }
1693
+ '400':
1694
+ description: 'Missing required fields, unknown provider, or invalid GitHub URL.'
1695
+ '401':
1696
+ description: Missing or invalid API key.