mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-07-09 17:19:02 +00:00
refactor(cli): Finish serve kebab-case filenames (#5604)
This commit is contained in:
parent
f29f210201
commit
a8863c203c
35 changed files with 88 additions and 111 deletions
|
|
@ -25,7 +25,7 @@ standard ACP method (model switch, workspace introspection, heartbeat,
|
||||||
multi-client permission policy, SSE backpressure tuning). Rationale in §5.
|
multi-client permission policy, SSE backpressure tuning). Rationale in §5.
|
||||||
|
|
||||||
A complete, locally-runnable reference implementation ships in this PR
|
A complete, locally-runnable reference implementation ships in this PR
|
||||||
(`packages/cli/src/serve/acpHttp/`) plus a verification harness
|
(`packages/cli/src/serve/acp-http/`) plus a verification harness
|
||||||
(`scripts/acp-http-smoke.mjs`).
|
(`scripts/acp-http-smoke.mjs`).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -151,15 +151,15 @@ client ────────────────────────
|
||||||
qwen --acp child
|
qwen --acp child
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3.1 New module layout (`packages/cli/src/serve/acpHttp/`)
|
### 3.1 New module layout (`packages/cli/src/serve/acp-http/`)
|
||||||
|
|
||||||
| File | Responsibility |
|
| File | Responsibility |
|
||||||
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `index.ts` | `mountAcpHttp(app, bridge, opts)` — registers `/acp` routes on the existing Express app. |
|
| `index.ts` | `mountAcpHttp(app, bridge, opts)` — registers `/acp` routes on the existing Express app. |
|
||||||
| `connectionRegistry.ts` | `Acp-Connection-Id` → `AcpConnection` (connection SSE writer, `Map<sessionId, SessionStream>`, pending agent→client requests by JSON-RPC id, monotonic id allocator). TTL + DELETE cleanup. |
|
| `connection-registry.ts` | `Acp-Connection-Id` → `AcpConnection` (connection SSE writer, `Map<sessionId, SessionStream>`, pending agent→client requests by JSON-RPC id, monotonic id allocator). TTL + DELETE cleanup. |
|
||||||
| `jsonRpc.ts` | JSON-RPC 2.0 parse/validate/serialize helpers; error codes (`-32600` etc.); `_qwen/` namespace guard. |
|
| `json-rpc.ts` | JSON-RPC 2.0 parse/validate/serialize helpers; error codes (`-32600` etc.); `_qwen/` namespace guard. |
|
||||||
| `dispatch.ts` | Maps inbound JSON-RPC methods → `HttpAcpBridge` calls. Maps `BridgeEvent`s → outbound JSON-RPC frames. The translation table (§4). |
|
| `dispatch.ts` | Maps inbound JSON-RPC methods → `HttpAcpBridge` calls. Maps `BridgeEvent`s → outbound JSON-RPC frames. The translation table (§4). |
|
||||||
| `sseStream.ts` | Long-lived SSE writer (reuses the backpressure/heartbeat pattern from `server.ts`). Distinct from REST `/events` (different framing: full JSON-RPC objects, not qwen event envelopes). |
|
| `sse-stream.ts` | Long-lived SSE writer (reuses the backpressure/heartbeat pattern from `server.ts`). Distinct from REST `/events` (different framing: full JSON-RPC objects, not qwen event envelopes). |
|
||||||
|
|
||||||
No change to `bridge.ts` / `eventBus.ts` (additive consumer only).
|
No change to `bridge.ts` / `eventBus.ts` (additive consumer only).
|
||||||
|
|
||||||
|
|
@ -284,7 +284,7 @@ thin compat shim over `/acp` (separate, later PR).
|
||||||
- `session/request_permission` agent→client round-trip.
|
- `session/request_permission` agent→client round-trip.
|
||||||
- `_qwen/session/set_model` extension as the worked example of #2.
|
- `_qwen/session/set_model` extension as the worked example of #2.
|
||||||
- Bearer-auth + host allowlist reuse (same middleware as REST).
|
- Bearer-auth + host allowlist reuse (same middleware as REST).
|
||||||
- Unit tests (`acpHttp/*.test.ts`) + a black-box smoke script driving a real daemon.
|
- Unit tests (`acp-http/*.test.ts`) + a black-box smoke script driving a real daemon.
|
||||||
|
|
||||||
**Deferred (documented, not built now):**
|
**Deferred (documented, not built now):**
|
||||||
|
|
||||||
|
|
@ -309,7 +309,7 @@ thin compat shim over `/acp` (separate, later PR).
|
||||||
- Trigger a tool needing permission → assert `session/request_permission` request,
|
- Trigger a tool needing permission → assert `session/request_permission` request,
|
||||||
POST a grant response → assert prompt completes.
|
POST a grant response → assert prompt completes.
|
||||||
- `POST {_qwen/session/set_model}` → assert model switch + `session/update`.
|
- `POST {_qwen/session/set_model}` → assert model switch + `session/update`.
|
||||||
4. Vitest: `acpHttp/*.test.ts` green.
|
4. Vitest: `acp-http/*.test.ts` green.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -326,11 +326,11 @@ thin compat shim over `/acp` (separate, later PR).
|
||||||
|
|
||||||
## 10. Implementation & verification log (v1)
|
## 10. Implementation & verification log (v1)
|
||||||
|
|
||||||
Implemented in `packages/cli/src/serve/acpHttp/` (`jsonRpc.ts`, `sseStream.ts`,
|
Implemented in `packages/cli/src/serve/acp-http/` (`json-rpc.ts`, `sse-stream.ts`,
|
||||||
`connectionRegistry.ts`, `dispatch.ts`, `index.ts`), mounted from `server.ts`
|
`connection-registry.ts`, `dispatch.ts`, `index.ts`), mounted from `server.ts`
|
||||||
via `mountAcpHttp(app, bridge, { boundWorkspace })`.
|
via `mountAcpHttp(app, bridge, { boundWorkspace })`.
|
||||||
|
|
||||||
### Automated (`packages/cli/src/serve/acpHttp/*.test.ts`)
|
### Automated (`packages/cli/src/serve/acp-http/*.test.ts`)
|
||||||
|
|
||||||
`transport.test.ts` boots a real Express server + the real `mountAcpHttp` over
|
`transport.test.ts` boots a real Express server + the real `mountAcpHttp` over
|
||||||
a controllable fake bridge and drives it with `fetch` + manual SSE parsing.
|
a controllable fake bridge and drives it with `fetch` + manual SSE parsing.
|
||||||
|
|
@ -496,8 +496,8 @@ Another reviewer pass (qwen3.7-max). Suite **30 tests**, live re-verified.
|
||||||
| F3 | **P2** | 503 connection-cap rejection had no stderr log. | `writeStderrLine` with the cap value. |
|
| F3 | **P2** | 503 connection-cap rejection had no stderr log. | `writeStderrLine` with the cap value. |
|
||||||
| F4 | **P2** | `_qwen/notify stream_error` spread let `event.data.kind` shadow the discriminator. | Spread first, then `kind: 'stream_error'`. |
|
| F4 | **P2** | `_qwen/notify stream_error` spread let `event.data.kind` shadow the discriminator. | Spread first, then `kind: 'stream_error'`. |
|
||||||
| F5 | **P2** | `MAX_WORKSPACE_PATH_LENGTH` redeclared (`= 4096`) vs the canonical `fs/paths.js`. | Import from `../fs/paths.js` (no divergence). |
|
| F5 | **P2** | `MAX_WORKSPACE_PATH_LENGTH` redeclared (`= 4096`) vs the canonical `fs/paths.js`. | Import from `../fs/paths.js` (no divergence). |
|
||||||
| F6 | **P2** | `isObjectParams` duplicated `jsonRpc.isObject`. | Import `isObject`. |
|
| F6 | **P2** | `isObjectParams` duplicated `json-rpc.isObject`. | Import `isObject`. |
|
||||||
| F7 | **P2** | Raw `process.stderr.write` in `index.ts`/`sseStream.ts` vs `writeStderrLine` elsewhere. | Unified on `writeStderrLine` across the module. |
|
| F7 | **P2** | Raw `process.stderr.write` in `index.ts`/`sse-stream.ts` vs `writeStderrLine` elsewhere. | Unified on `writeStderrLine` across the module. |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,19 +37,19 @@
|
||||||
|
|
||||||
**Subsystems**:
|
**Subsystems**:
|
||||||
|
|
||||||
| Path | Role |
|
| Path | Role |
|
||||||
| ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
| ---------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||||
| `serve/fs/` | `WorkspaceFileSystem` factory plus `policy.ts` (size/trust/binary checks), `paths.ts` (canonicalize, resolveWithin, symlink rejection), `audit.ts`, and typed `FsError` values. |
|
| `serve/fs/` | `WorkspaceFileSystem` factory plus `policy.ts` (size/trust/binary checks), `paths.ts` (canonicalize, resolveWithin, symlink rejection), `audit.ts`, and typed `FsError` values. |
|
||||||
| `serve/routes/workspace-file-read.ts`, `workspace-file-write.ts` | HTTP handlers for `GET /file`, `GET /file/bytes`, `POST /file/write`, and `POST /file/edit`. |
|
| `serve/routes/workspace-file-read.ts`, `workspace-file-write.ts` | HTTP handlers for `GET /file`, `GET /file/bytes`, `POST /file/write`, and `POST /file/edit`. |
|
||||||
| `serve/workspace-memory.ts` | `GET/POST /workspace/memory` (QWEN.md CRUD). |
|
| `serve/workspace-memory.ts` | `GET/POST /workspace/memory` (QWEN.md CRUD). |
|
||||||
| `serve/workspace-agents.ts` | `GET/POST/DELETE /workspace/agents` (subagent CRUD). |
|
| `serve/workspace-agents.ts` | `GET/POST/DELETE /workspace/agents` (subagent CRUD). |
|
||||||
| `serve/daemon-status-provider.ts` | Env snapshot plus daemon-host preflight cells: Node version, CLI entry, workspace stat, ripgrep, git, npm. |
|
| `serve/daemon-status-provider.ts` | Env snapshot plus daemon-host preflight cells: Node version, CLI entry, workspace stat, ripgrep, git, npm. |
|
||||||
| `serve/permission-audit.ts` | `PermissionAuditRing` (512-entry FIFO) and `createPermissionAuditPublisher`. |
|
| `serve/permission-audit.ts` | `PermissionAuditRing` (512-entry FIFO) and `createPermissionAuditPublisher`. |
|
||||||
| `serve/auth/device-flow.ts`, `qwen-device-flow-provider.ts` | Device-flow OAuth routes. See [`12-auth-security.md`](./12-auth-security.md). |
|
| `serve/auth/device-flow.ts`, `qwen-device-flow-provider.ts` | Device-flow OAuth routes. See [`12-auth-security.md`](./12-auth-security.md). |
|
||||||
| `serve/daemonLogger.ts` | `DaemonLogger` structured file logs. See [`19-observability.md`](./19-observability.md). |
|
| `serve/daemon-logger.ts` | `DaemonLogger` structured file logs. See [`19-observability.md`](./19-observability.md). |
|
||||||
| `serve/debug-mode.ts` | Shared `isServeDebugMode()` predicate controlling verbose error context in HTTP responses. |
|
| `serve/debug-mode.ts` | Shared `isServeDebugMode()` predicate controlling verbose error context in HTTP responses. |
|
||||||
| `serve/acpHttp/` | ACP Streamable HTTP transport (RFD #721), mounted at `/acp`. Seven files implement JSON-RPC POST, SSE GET, DELETE teardown, and shared bridge usage in parallel with the REST surface. |
|
| `serve/acp-http/` | ACP Streamable HTTP transport (RFD #721), mounted at `/acp`. Seven files implement JSON-RPC POST, SSE GET, DELETE teardown, and shared bridge usage in parallel with the REST surface. |
|
||||||
| `serve/demo.ts` | Self-contained inline HTML for `GET /demo`: browser debug console with chat UI, event log, and workspace inspector. On loopback without `--require-auth`, it is registered **before** `bearerAuth`; on non-loopback or with `--require-auth`, it is registered **after** `bearerAuth`. Served with CSP `default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; connect-src 'self'; frame-ancestors 'none'` plus `X-Frame-Options: DENY`. |
|
| `serve/demo.ts` | Self-contained inline HTML for `GET /demo`: browser debug console with chat UI, event log, and workspace inspector. On loopback without `--require-auth`, it is registered **before** `bearerAuth`; on non-loopback or with `--require-auth`, it is registered **after** `bearerAuth`. Served with CSP `default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; connect-src 'self'; frame-ancestors 'none'` plus `X-Frame-Options: DENY`. |
|
||||||
|
|
||||||
**Re-export shims** for compatibility with pre-F1 import paths:
|
**Re-export shims** for compatibility with pre-F1 import paths:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
| ------------------------------------------- | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| ------------------------------------------- | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `QWEN_SERVE_DEBUG` stderr logs | `bridge.ts` and call sites | Env values `1` / `true` / `on` / `yes` (case-insensitive) print `qwen serve debug: ...` lines to stderr. |
|
| `QWEN_SERVE_DEBUG` stderr logs | `bridge.ts` and call sites | Env values `1` / `true` / `on` / `yes` (case-insensitive) print `qwen serve debug: ...` lines to stderr. |
|
||||||
| OpenTelemetry span instrumentation | `server.ts` `daemonTelemetryMiddleware` | Each HTTP request is wrapped in `withDaemonRequestSpan`; attributes include route, sessionId, clientId, and status code. Permission routes have dedicated spans. Prompt lifecycle is traced end-to-end. Configuration lives in `settings.json` `telemetry`. |
|
| OpenTelemetry span instrumentation | `server.ts` `daemonTelemetryMiddleware` | Each HTTP request is wrapped in `withDaemonRequestSpan`; attributes include route, sessionId, clientId, and status code. Permission routes have dedicated spans. Prompt lifecycle is traced end-to-end. Configuration lives in `settings.json` `telemetry`. |
|
||||||
| `DaemonLogger` structured file logs | `serve/daemonLogger.ts` | Structured JSON-like log lines are written to a file. Boot prints `daemon log -> <path>`. Supports `info` / `warn` / `error` levels, with structured fields such as `route`, `sessionId`, `clientId`, `childPid`, and `channelId`. |
|
| `DaemonLogger` structured file logs | `serve/daemon-logger.ts` | Structured JSON-like log lines are written to a file. Boot prints `daemon log -> <path>`. Supports `info` / `warn` / `error` levels, with structured fields such as `route`, `sessionId`, `clientId`, `childPid`, and `channelId`. |
|
||||||
| Per-request access-log middleware | `server.ts`, registered before `bearerAuth` | Logs `method`, `path`, `status`, `durationMs`, `sessionId`, and `clientId` after each request. Skips `GET /health` and heartbeat. 4xx+ uses `warn`; success uses `info`. |
|
| Per-request access-log middleware | `server.ts`, registered before `bearerAuth` | Logs `method`, `path`, `status`, `durationMs`, `sessionId`, and `clientId` after each request. Skips `GET /health` and heartbeat. 4xx+ uses `warn`; success uses `info`. |
|
||||||
| `/health` | `server.ts` route | Liveness probe; `?deep=1` returns extended details. |
|
| `/health` | `server.ts` route | Liveness probe; `?deep=1` returns extended details. |
|
||||||
| `/capabilities` | `server.ts` route | Preflight feature discovery. See [`11-capabilities-versioning.md`](./11-capabilities-versioning.md). |
|
| `/capabilities` | `server.ts` route | Preflight feature discovery. See [`11-capabilities-versioning.md`](./11-capabilities-versioning.md). |
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
| `/workspace/skills`, `/workspace/providers` | Routes | ACP-side live snapshots; return empty idle data when no session exists. |
|
| `/workspace/skills`, `/workspace/providers` | Routes | ACP-side live snapshots; return empty idle data when no session exists. |
|
||||||
| Per-session SSE | `GET /session/:id/events` | Real-time event stream. |
|
| Per-session SSE | `GET /session/:id/events` | Real-time event stream. |
|
||||||
| `/demo` debug console | `GET /demo` (`packages/cli/src/serve/demo.ts`) | Browser-accessible single-page console: chat, event log, workspace inspector, and permission UX. On loopback, `http://127.0.0.1:4170/demo` is the quickest end-to-end validation path without writing SDK code. Registration rules are in [`02-serve-runtime.md`](./02-serve-runtime.md). |
|
| `/demo` debug console | `GET /demo` (`packages/cli/src/serve/demo.ts`) | Browser-accessible single-page console: chat, event log, workspace inspector, and permission UX. On loopback, `http://127.0.0.1:4170/demo` is the quickest end-to-end validation path without writing SDK code. Registration rules are in [`02-serve-runtime.md`](./02-serve-runtime.md). |
|
||||||
| `PermissionAuditRing` | `permission-audit.ts` | In-memory FIFO of 512 permission decisions. |
|
| `PermissionAuditRing` | `permission-audit.ts` | In-memory FIFO of 512 permission decisions. |
|
||||||
| Mediator `decisionReason` audit | `permissionMediator.ts` | Internal structured record explaining why a permission request resolved the way it did. |
|
| Mediator `decisionReason` audit | `permissionMediator.ts` | Internal structured record explaining why a permission request resolved the way it did. |
|
||||||
|
|
||||||
## What does not exist today
|
## What does not exist today
|
||||||
|
|
@ -143,7 +143,7 @@ flowchart TD
|
||||||
## References
|
## References
|
||||||
|
|
||||||
- `packages/cli/src/serve/daemon-status-provider.ts`
|
- `packages/cli/src/serve/daemon-status-provider.ts`
|
||||||
- `packages/cli/src/serve/daemonLogger.ts` (`DaemonLogger`, `buildDaemonLogLine`)
|
- `packages/cli/src/serve/daemon-logger.ts` (`DaemonLogger`, `buildDaemonLogLine`)
|
||||||
- `packages/cli/src/serve/debug-mode.ts` (`isServeDebugMode`)
|
- `packages/cli/src/serve/debug-mode.ts` (`isServeDebugMode`)
|
||||||
- `packages/acp-bridge/src/permissionMediator.ts` (`PermissionDecisionReason`)
|
- `packages/acp-bridge/src/permissionMediator.ts` (`PermissionDecisionReason`)
|
||||||
- `packages/cli/src/serve/server.ts` (`daemonTelemetryMiddleware`, access-log middleware)
|
- `packages/cli/src/serve/server.ts` (`daemonTelemetryMiddleware`, access-log middleware)
|
||||||
|
|
|
||||||
|
|
@ -82,17 +82,13 @@ export const legacyFilenames = [
|
||||||
'cronScheduler',
|
'cronScheduler',
|
||||||
'customBanner',
|
'customBanner',
|
||||||
'customMatchers',
|
'customMatchers',
|
||||||
'daemonStatusProvider',
|
|
||||||
'DaemonTuiAdapter',
|
|
||||||
'dangerousRules',
|
'dangerousRules',
|
||||||
'DataProcessor',
|
'DataProcessor',
|
||||||
'debugLogger',
|
'debugLogger',
|
||||||
'debugMode',
|
|
||||||
'deepMerge',
|
'deepMerge',
|
||||||
'deleteCommand',
|
'deleteCommand',
|
||||||
'denialTracking',
|
'denialTracking',
|
||||||
'detectTodoChanges',
|
'detectTodoChanges',
|
||||||
'deviceFlow',
|
|
||||||
'dialogScopeUtils',
|
'dialogScopeUtils',
|
||||||
'diffCommand',
|
'diffCommand',
|
||||||
'diffOptions',
|
'diffOptions',
|
||||||
|
|
@ -109,7 +105,6 @@ export const legacyFilenames = [
|
||||||
'editorSettingsManager',
|
'editorSettingsManager',
|
||||||
'envInterpolator',
|
'envInterpolator',
|
||||||
'environmentContext',
|
'environmentContext',
|
||||||
'envSnapshot',
|
|
||||||
'envVarResolver',
|
'envVarResolver',
|
||||||
'errorCodes',
|
'errorCodes',
|
||||||
'errorHandler',
|
'errorHandler',
|
||||||
|
|
@ -205,7 +200,6 @@ export const legacyFilenames = [
|
||||||
'LlmRewriter',
|
'LlmRewriter',
|
||||||
'loadedSettingsAdapter',
|
'loadedSettingsAdapter',
|
||||||
'loggingContentGenerator',
|
'loggingContentGenerator',
|
||||||
'loopbackBinds',
|
|
||||||
'loopDetectionService',
|
'loopDetectionService',
|
||||||
'lowlightLoader',
|
'lowlightLoader',
|
||||||
'LruCache',
|
'LruCache',
|
||||||
|
|
@ -283,7 +277,6 @@ export const legacyFilenames = [
|
||||||
'quitCommand',
|
'quitCommand',
|
||||||
'quotaErrorDetection',
|
'quotaErrorDetection',
|
||||||
'qwenContentGenerator',
|
'qwenContentGenerator',
|
||||||
'qwenDeviceFlowProvider',
|
|
||||||
'qwenIgnoreParser',
|
'qwenIgnoreParser',
|
||||||
'qwenOAuth2',
|
'qwenOAuth2',
|
||||||
'rateLimit',
|
'rateLimit',
|
||||||
|
|
@ -309,7 +302,6 @@ export const legacyFilenames = [
|
||||||
'ripgrepUtils',
|
'ripgrepUtils',
|
||||||
'rulesDiscovery',
|
'rulesDiscovery',
|
||||||
'runBudget',
|
'runBudget',
|
||||||
'runQwenServe',
|
|
||||||
'runtimeDiagnostics',
|
'runtimeDiagnostics',
|
||||||
'runtimeFetchOptions',
|
'runtimeFetchOptions',
|
||||||
'runtimeOutputDirContext',
|
'runtimeOutputDirContext',
|
||||||
|
|
@ -511,12 +503,7 @@ export const legacyFilenames = [
|
||||||
'warningHandler',
|
'warningHandler',
|
||||||
'windowsPath',
|
'windowsPath',
|
||||||
'windowTitle',
|
'windowTitle',
|
||||||
'workspaceAgents',
|
|
||||||
'workspaceContext',
|
'workspaceContext',
|
||||||
'workspaceFileRead',
|
|
||||||
'workspaceFileSystem',
|
|
||||||
'workspaceFileWrite',
|
|
||||||
'workspaceMemory',
|
|
||||||
'worktreeCleanup',
|
'worktreeCleanup',
|
||||||
'worktreeSessionService',
|
'worktreeSessionService',
|
||||||
'worktreeStartup',
|
'worktreeStartup',
|
||||||
|
|
@ -525,10 +512,7 @@ export const legacyFilenames = [
|
||||||
'CodeColorizer',
|
'CodeColorizer',
|
||||||
'SKILL',
|
'SKILL',
|
||||||
'TeamManager',
|
'TeamManager',
|
||||||
'a2uiAction',
|
|
||||||
'acpSessionBridge',
|
|
||||||
'asciiCharts',
|
'asciiCharts',
|
||||||
'bridgeFileSystemAdapter',
|
|
||||||
'btwUtils',
|
'btwUtils',
|
||||||
'cdCommand',
|
'cdCommand',
|
||||||
'claudeMcpImport',
|
'claudeMcpImport',
|
||||||
|
|
@ -537,12 +521,9 @@ export const legacyFilenames = [
|
||||||
'compressFastCommand',
|
'compressFastCommand',
|
||||||
'concurrencyLimiter',
|
'concurrencyLimiter',
|
||||||
'configHash',
|
'configHash',
|
||||||
'connectionRegistry',
|
|
||||||
'corruptFile',
|
'corruptFile',
|
||||||
'cronTasksFile',
|
'cronTasksFile',
|
||||||
'cronTasksLock',
|
'cronTasksLock',
|
||||||
'daemonLogger',
|
|
||||||
'daemonStatus',
|
|
||||||
'enterPlanMode',
|
'enterPlanMode',
|
||||||
'extensionPreferences',
|
'extensionPreferences',
|
||||||
'forkCommand',
|
'forkCommand',
|
||||||
|
|
@ -555,7 +536,6 @@ export const legacyFilenames = [
|
||||||
'importConfigCommand',
|
'importConfigCommand',
|
||||||
'inlineMediaLimit',
|
'inlineMediaLimit',
|
||||||
'instructionsLoadedCallback',
|
'instructionsLoadedCallback',
|
||||||
'jsonRpc',
|
|
||||||
'leaderPermissionBridge',
|
'leaderPermissionBridge',
|
||||||
'liveAgentPanelVisibility',
|
'liveAgentPanelVisibility',
|
||||||
'mcpApprovals',
|
'mcpApprovals',
|
||||||
|
|
@ -564,7 +544,6 @@ export const legacyFilenames = [
|
||||||
'mcpServers',
|
'mcpServers',
|
||||||
'midTurnUserMessage',
|
'midTurnUserMessage',
|
||||||
'normalizeDisabledTools',
|
'normalizeDisabledTools',
|
||||||
'permissionAudit',
|
|
||||||
'planApprovalGate',
|
'planApprovalGate',
|
||||||
'promptAddendum',
|
'promptAddendum',
|
||||||
'retryErrorClassification',
|
'retryErrorClassification',
|
||||||
|
|
@ -578,7 +557,6 @@ export const legacyFilenames = [
|
||||||
'settingsWatcher',
|
'settingsWatcher',
|
||||||
'sleepInhibitor',
|
'sleepInhibitor',
|
||||||
'sourceRegistry',
|
'sourceRegistry',
|
||||||
'sseStream',
|
|
||||||
'statsDataService',
|
'statsDataService',
|
||||||
'tasksSnapshot',
|
'tasksSnapshot',
|
||||||
'teamHelpers',
|
'teamHelpers',
|
||||||
|
|
@ -587,15 +565,11 @@ export const legacyFilenames = [
|
||||||
'toolCallIdUtils',
|
'toolCallIdUtils',
|
||||||
'toolResultCleanup',
|
'toolResultCleanup',
|
||||||
'toolResultDisplayCompaction',
|
'toolResultDisplayCompaction',
|
||||||
'transportStream',
|
|
||||||
'usageHistoryService',
|
'usageHistoryService',
|
||||||
'useMcpApproval',
|
'useMcpApproval',
|
||||||
'useResizeSettleRepaint',
|
'useResizeSettleRepaint',
|
||||||
'useStatsDialog',
|
'useStatsDialog',
|
||||||
'useTeamInProcess',
|
'useTeamInProcess',
|
||||||
'userMemory',
|
'userMemory',
|
||||||
'webShellStatic',
|
|
||||||
'workflowsCommand',
|
'workflowsCommand',
|
||||||
'workspaceSettings',
|
|
||||||
'wsStream',
|
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { describe, expect, it } from 'vitest';
|
import { describe, expect, it } from 'vitest';
|
||||||
import { ConnectionRegistry } from './connectionRegistry.js';
|
import { ConnectionRegistry } from './connection-registry.js';
|
||||||
import type { TransportStream } from './transportStream.js';
|
import type { TransportStream } from './transport-stream.js';
|
||||||
|
|
||||||
class FakeStream implements TransportStream {
|
class FakeStream implements TransportStream {
|
||||||
isClosed = false;
|
isClosed = false;
|
||||||
|
|
@ -6,8 +6,8 @@
|
||||||
|
|
||||||
import { randomUUID } from 'node:crypto';
|
import { randomUUID } from 'node:crypto';
|
||||||
import { writeStderrLine } from '../../utils/stdioHelpers.js';
|
import { writeStderrLine } from '../../utils/stdioHelpers.js';
|
||||||
import { logSafe } from './jsonRpc.js';
|
import { logSafe } from './json-rpc.js';
|
||||||
import type { TransportStream } from './transportStream.js';
|
import type { TransportStream } from './transport-stream.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Per-stream cap on frames buffered before the client attaches its SSE
|
* Per-stream cap on frames buffered before the client attaches its SSE
|
||||||
|
|
@ -50,7 +50,7 @@ import type {
|
||||||
DaemonWorkspaceService,
|
DaemonWorkspaceService,
|
||||||
WorkspaceRequestContext,
|
WorkspaceRequestContext,
|
||||||
} from '../workspace-service/types.js';
|
} from '../workspace-service/types.js';
|
||||||
import type { AcpConnection } from './connectionRegistry.js';
|
import type { AcpConnection } from './connection-registry.js';
|
||||||
import {
|
import {
|
||||||
QWEN_META_KEY,
|
QWEN_META_KEY,
|
||||||
QWEN_METHOD_NS,
|
QWEN_METHOD_NS,
|
||||||
|
|
@ -68,7 +68,7 @@ import {
|
||||||
type JsonRpcInbound,
|
type JsonRpcInbound,
|
||||||
type JsonRpcRequest,
|
type JsonRpcRequest,
|
||||||
type JsonRpcResponse,
|
type JsonRpcResponse,
|
||||||
} from './jsonRpc.js';
|
} from './json-rpc.js';
|
||||||
|
|
||||||
function errMsg(err: unknown): string {
|
function errMsg(err: unknown): string {
|
||||||
return err instanceof Error ? err.message : String(err);
|
return err instanceof Error ? err.message : String(err);
|
||||||
|
|
@ -2697,5 +2697,5 @@ export class AcpDispatcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Re-export so tests can reference the request type without the jsonRpc path.
|
// Re-export so tests can reference the request type without the json-rpc path.
|
||||||
export type { JsonRpcRequest };
|
export type { JsonRpcRequest };
|
||||||
|
|
@ -18,11 +18,11 @@ import { AcpDispatcher } from './dispatch.js';
|
||||||
import {
|
import {
|
||||||
ConnectionRegistry,
|
ConnectionRegistry,
|
||||||
type AcpConnection,
|
type AcpConnection,
|
||||||
} from './connectionRegistry.js';
|
} from './connection-registry.js';
|
||||||
import { SseStream } from './sseStream.js';
|
import { SseStream } from './sse-stream.js';
|
||||||
import { WsStream } from './wsStream.js';
|
import { WsStream } from './ws-stream.js';
|
||||||
import type { RateLimitTier } from '../rate-limit.js';
|
import type { RateLimitTier } from '../rate-limit.js';
|
||||||
import { RPC, error as rpcError, isRequest, parseInbound } from './jsonRpc.js';
|
import { RPC, error as rpcError, isRequest, parseInbound } from './json-rpc.js';
|
||||||
|
|
||||||
export const ACP_CONNECTION_HEADER = 'acp-connection-id';
|
export const ACP_CONNECTION_HEADER = 'acp-connection-id';
|
||||||
export const ACP_SESSION_HEADER = 'acp-session-id';
|
export const ACP_SESSION_HEADER = 'acp-session-id';
|
||||||
|
|
@ -362,7 +362,7 @@ export function mountAcpHttp(
|
||||||
// stream. A reconnect already installed a newer stream — the prompt
|
// stream. A reconnect already installed a newer stream — the prompt
|
||||||
// must survive the old stream's close. CONTRACT: this identity guard
|
// must survive the old stream's close. CONTRACT: this identity guard
|
||||||
// pairs with `attachSessionStream`'s install-before-close ordering
|
// pairs with `attachSessionStream`'s install-before-close ordering
|
||||||
// (connectionRegistry.ts) — keep both in lockstep.
|
// (connection-registry.ts) — keep both in lockstep.
|
||||||
if (conn.sessions.get(sessionId)?.stream === stream) {
|
if (conn.sessions.get(sessionId)?.stream === stream) {
|
||||||
conn.sessions.get(sessionId)?.promptAbort?.abort();
|
conn.sessions.get(sessionId)?.promptAbort?.abort();
|
||||||
}
|
}
|
||||||
|
|
@ -799,7 +799,7 @@ function headerOf(req: Request, name: string): string | undefined {
|
||||||
* True when the request's KERNEL-stamped peer address is loopback. Mirrors
|
* True when the request's KERNEL-stamped peer address is loopback. Mirrors
|
||||||
* the REST surface's `detectFromLoopback` (NOT derived from forgeable
|
* the REST surface's `detectFromLoopback` (NOT derived from forgeable
|
||||||
* headers like `X-Forwarded-For`). Replicated here rather than imported
|
* headers like `X-Forwarded-For`). Replicated here rather than imported
|
||||||
* from `server.ts` to avoid a server↔acpHttp import cycle.
|
* from `server.ts` to avoid a server↔acp-http import cycle.
|
||||||
*/
|
*/
|
||||||
function isLoopbackSocket(socket: Duplex): boolean {
|
function isLoopbackSocket(socket: Duplex): boolean {
|
||||||
const addr = (socket as unknown as { remoteAddress?: string }).remoteAddress;
|
const addr = (socket as unknown as { remoteAddress?: string }).remoteAddress;
|
||||||
|
|
@ -12,9 +12,9 @@ import {
|
||||||
parseInbound,
|
parseInbound,
|
||||||
QWEN_METHOD_NS,
|
QWEN_METHOD_NS,
|
||||||
RPC,
|
RPC,
|
||||||
} from './jsonRpc.js';
|
} from './json-rpc.js';
|
||||||
|
|
||||||
describe('jsonRpc helpers', () => {
|
describe('json-rpc helpers', () => {
|
||||||
it('classifies a request', () => {
|
it('classifies a request', () => {
|
||||||
const m = { jsonrpc: '2.0', id: 1, method: 'initialize' };
|
const m = { jsonrpc: '2.0', id: 1, method: 'initialize' };
|
||||||
expect(isRequest(m)).toBe(true);
|
expect(isRequest(m)).toBe(true);
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Minimal JSON-RPC 2.0 helpers for the ACP-over-HTTP transport
|
* Minimal JSON-RPC 2.0 helpers for the ACP-over-HTTP transport
|
||||||
* (`packages/cli/src/serve/acpHttp/`). The official ACP Streamable HTTP
|
* (`packages/cli/src/serve/acp-http/`). The official ACP Streamable HTTP
|
||||||
* transport (RFD #721) frames every message as a JSON-RPC 2.0 object;
|
* transport (RFD #721) frames every message as a JSON-RPC 2.0 object;
|
||||||
* this module owns the wire types + parse/validate/serialize so the
|
* this module owns the wire types + parse/validate/serialize so the
|
||||||
* dispatcher stays focused on bridge routing.
|
* dispatcher stays focused on bridge routing.
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
import { EventEmitter } from 'node:events';
|
import { EventEmitter } from 'node:events';
|
||||||
import { afterEach, describe, expect, it, vi } from 'vitest';
|
import { afterEach, describe, expect, it, vi } from 'vitest';
|
||||||
import type { Response } from 'express';
|
import type { Response } from 'express';
|
||||||
import { SseStream } from './sseStream.js';
|
import { SseStream } from './sse-stream.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Minimal Express `Response` mock: an EventEmitter with the `write`/`end`/
|
* Minimal Express `Response` mock: an EventEmitter with the `write`/`end`/
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
||||||
import { EventEmitter } from 'node:events';
|
import { EventEmitter } from 'node:events';
|
||||||
import { WsStream } from './wsStream.js';
|
import { WsStream } from './ws-stream.js';
|
||||||
|
|
||||||
// Minimal WebSocket mock that implements the surface WsStream uses.
|
// Minimal WebSocket mock that implements the surface WsStream uses.
|
||||||
class MockWebSocket extends EventEmitter {
|
class MockWebSocket extends EventEmitter {
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
import type { WebSocket } from 'ws';
|
import type { WebSocket } from 'ws';
|
||||||
import { writeStderrLine } from '../../utils/stdioHelpers.js';
|
import { writeStderrLine } from '../../utils/stdioHelpers.js';
|
||||||
import type { TransportStream } from './transportStream.js';
|
import type { TransportStream } from './transport-stream.js';
|
||||||
|
|
||||||
export class WsStream implements TransportStream {
|
export class WsStream implements TransportStream {
|
||||||
readonly kind = 'ws' as const;
|
readonly kind = 'ws' as const;
|
||||||
|
|
@ -10,10 +10,10 @@
|
||||||
* #4175 PR F1 lifted the bridge core (`BridgeClient`,
|
* #4175 PR F1 lifted the bridge core (`BridgeClient`,
|
||||||
* `defaultSpawnChannelFactory`, `createAcpSessionBridge` factory closure,
|
* `defaultSpawnChannelFactory`, `createAcpSessionBridge` factory closure,
|
||||||
* plus the supporting types/errors/options/status) to
|
* plus the supporting types/errors/options/status) to
|
||||||
* `@qwen-code/acp-bridge`. This shim preserves every existing relative
|
* `@qwen-code/acp-bridge`. This shim preserves the CLI-local bridge import
|
||||||
* import path (`./acpSessionBridge.js`) so `server.ts`, `run-qwen-serve.ts`,
|
* surface so `server.ts`, `run-qwen-serve.ts`, `workspace-agents.ts`,
|
||||||
* `workspace-agents.ts`, `workspace-memory.ts`, `index.ts`, plus the
|
* `workspace-memory.ts`, `index.ts`, plus the bridge test suite, keep resolving
|
||||||
* bridge test suite, keep resolving without any call-site changes.
|
* through one module.
|
||||||
*
|
*
|
||||||
* The implementation now lives at:
|
* The implementation now lives at:
|
||||||
* - `@qwen-code/acp-bridge/bridge` — `createAcpSessionBridge` factory
|
* - `@qwen-code/acp-bridge/bridge` — `createAcpSessionBridge` factory
|
||||||
|
|
@ -16,7 +16,7 @@ import {
|
||||||
lstatSync,
|
lstatSync,
|
||||||
} from 'node:fs';
|
} from 'node:fs';
|
||||||
import { describe, it, expect, afterEach, beforeEach } from 'vitest';
|
import { describe, it, expect, afterEach, beforeEach } from 'vitest';
|
||||||
import { buildDaemonLogLine, initDaemonLogger } from './daemonLogger.js';
|
import { buildDaemonLogLine, initDaemonLogger } from './daemon-logger.js';
|
||||||
|
|
||||||
describe('buildDaemonLogLine', () => {
|
describe('buildDaemonLogLine', () => {
|
||||||
const FIXED = new Date('2026-05-26T03:14:15.926Z');
|
const FIXED = new Date('2026-05-26T03:14:15.926Z');
|
||||||
|
|
@ -6,16 +6,16 @@
|
||||||
|
|
||||||
import type { RequestHandler } from 'express';
|
import type { RequestHandler } from 'express';
|
||||||
import { afterEach, describe, expect, it, vi } from 'vitest';
|
import { afterEach, describe, expect, it, vi } from 'vitest';
|
||||||
import type { AcpHttpHandle } from './acpHttp/index.js';
|
import type { AcpHttpHandle } from './acp-http/index.js';
|
||||||
import type {
|
import type {
|
||||||
AcpSessionBridge,
|
AcpSessionBridge,
|
||||||
BridgeDaemonStatusSnapshot,
|
BridgeDaemonStatusSnapshot,
|
||||||
} from './acpSessionBridge.js';
|
} from './acp-session-bridge.js';
|
||||||
import { DeviceFlowRegistry } from './auth/device-flow.js';
|
import { DeviceFlowRegistry } from './auth/device-flow.js';
|
||||||
import {
|
import {
|
||||||
buildDaemonStatusResponse,
|
buildDaemonStatusResponse,
|
||||||
type BuildDaemonStatusOptions,
|
type BuildDaemonStatusOptions,
|
||||||
} from './daemonStatus.js';
|
} from './daemon-status.js';
|
||||||
import type { RateLimiterInstance, RateLimitTier } from './rate-limit.js';
|
import type { RateLimiterInstance, RateLimitTier } from './rate-limit.js';
|
||||||
import type { DaemonWorkspaceService } from './workspace-service/index.js';
|
import type { DaemonWorkspaceService } from './workspace-service/index.js';
|
||||||
|
|
||||||
|
|
@ -5,13 +5,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { ServeProtocolVersions } from './capabilities.js';
|
import type { ServeProtocolVersions } from './capabilities.js';
|
||||||
import type { AcpHttpHandle } from './acpHttp/index.js';
|
import type { AcpHttpHandle } from './acp-http/index.js';
|
||||||
import type { DeviceFlowRegistry } from './auth/device-flow.js';
|
import type { DeviceFlowRegistry } from './auth/device-flow.js';
|
||||||
import type { DaemonLogger } from './daemonLogger.js';
|
import type { DaemonLogger } from './daemon-logger.js';
|
||||||
import type {
|
import type {
|
||||||
AcpSessionBridge,
|
AcpSessionBridge,
|
||||||
BridgeDaemonStatusSnapshot,
|
BridgeDaemonStatusSnapshot,
|
||||||
} from './acpSessionBridge.js';
|
} from './acp-session-bridge.js';
|
||||||
import { isLoopbackBind } from './loopback-binds.js';
|
import { isLoopbackBind } from './loopback-binds.js';
|
||||||
import type { RateLimiterInstance, RateLimitTier } from './rate-limit.js';
|
import type { RateLimiterInstance, RateLimitTier } from './rate-limit.js';
|
||||||
import type { ServeOptions } from './types.js';
|
import type { ServeOptions } from './types.js';
|
||||||
|
|
@ -116,7 +116,7 @@ export {
|
||||||
// embeds that want to recognize these errors (parallel to how
|
// embeds that want to recognize these errors (parallel to how
|
||||||
// they already match `WorkspaceInitConflictError` /
|
// they already match `WorkspaceInitConflictError` /
|
||||||
// `SessionNotFoundError`) need them on the public barrel; without
|
// `SessionNotFoundError`) need them on the public barrel; without
|
||||||
// this they have to deep-import `./acpSessionBridge.js`.
|
// this they have to deep-import `./acp-session-bridge.js`.
|
||||||
McpServerNotFoundError,
|
McpServerNotFoundError,
|
||||||
McpServerRestartFailedError,
|
McpServerRestartFailedError,
|
||||||
SessionNotFoundError,
|
SessionNotFoundError,
|
||||||
|
|
@ -133,7 +133,7 @@ export {
|
||||||
type BridgeSpawnRequest,
|
type BridgeSpawnRequest,
|
||||||
type ChannelFactory,
|
type ChannelFactory,
|
||||||
type HttpAcpBridge,
|
type HttpAcpBridge,
|
||||||
} from './acpSessionBridge.js';
|
} from './acp-session-bridge.js';
|
||||||
export {
|
export {
|
||||||
EventBus,
|
EventBus,
|
||||||
EVENT_SCHEMA_VERSION,
|
EVENT_SCHEMA_VERSION,
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ import {
|
||||||
type A2uiActionResult,
|
type A2uiActionResult,
|
||||||
type McpServerCell,
|
type McpServerCell,
|
||||||
type McpServerConfigLike,
|
type McpServerConfigLike,
|
||||||
} from './a2uiAction.js';
|
} from './a2ui-action.js';
|
||||||
|
|
||||||
function makeApp(opts: {
|
function makeApp(opts: {
|
||||||
servers?: McpServerCell[];
|
servers?: McpServerCell[];
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { Application, Request, RequestHandler, Response } from 'express';
|
import type { Application, Request, RequestHandler, Response } from 'express';
|
||||||
import type { AcpSessionBridge } from '../acpSessionBridge.js';
|
import type { AcpSessionBridge } from '../acp-session-bridge.js';
|
||||||
import {
|
import {
|
||||||
isContentHash,
|
isContentHash,
|
||||||
type ContentHash,
|
type ContentHash,
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import {
|
||||||
runQwenServe,
|
runQwenServe,
|
||||||
validatePolicyConfig,
|
validatePolicyConfig,
|
||||||
} from './run-qwen-serve.js';
|
} from './run-qwen-serve.js';
|
||||||
import type { HttpAcpBridge } from './acpSessionBridge.js';
|
import type { HttpAcpBridge } from './acp-session-bridge.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* #4297 fold-in 7 (deepseek S1, addresses #3262690842). Lock the
|
* #4297 fold-in 7 (deepseek S1, addresses #3262690842). Lock the
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ import {
|
||||||
canonicalizeWorkspace,
|
canonicalizeWorkspace,
|
||||||
createAcpSessionBridge,
|
createAcpSessionBridge,
|
||||||
type AcpSessionBridge,
|
type AcpSessionBridge,
|
||||||
} from './acpSessionBridge.js';
|
} from './acp-session-bridge.js';
|
||||||
import {
|
import {
|
||||||
DEFAULT_OTLP_ENDPOINT,
|
DEFAULT_OTLP_ENDPOINT,
|
||||||
DEFAULT_TELEMETRY_TARGET,
|
DEFAULT_TELEMETRY_TARGET,
|
||||||
|
|
@ -51,7 +51,7 @@ import {
|
||||||
import { createBridgeFileSystemAdapter } from './bridge-file-system-adapter.js';
|
import { createBridgeFileSystemAdapter } from './bridge-file-system-adapter.js';
|
||||||
import { createDaemonStatusProvider } from './daemon-status-provider.js';
|
import { createDaemonStatusProvider } from './daemon-status-provider.js';
|
||||||
import { isLoopbackBind } from './loopback-binds.js';
|
import { isLoopbackBind } from './loopback-binds.js';
|
||||||
import { resolveWebShellDir } from './webShellStatic.js';
|
import { resolveWebShellDir } from './web-shell-static.js';
|
||||||
import { parseAllowOriginPatterns } from './auth.js';
|
import { parseAllowOriginPatterns } from './auth.js';
|
||||||
import {
|
import {
|
||||||
createPermissionAuditPublisher,
|
createPermissionAuditPublisher,
|
||||||
|
|
@ -62,7 +62,7 @@ import {
|
||||||
getActiveSseCount,
|
getActiveSseCount,
|
||||||
resolveBridgeFsFactory,
|
resolveBridgeFsFactory,
|
||||||
} from './server.js';
|
} from './server.js';
|
||||||
import { initDaemonLogger, type DaemonLogger } from './daemonLogger.js';
|
import { initDaemonLogger, type DaemonLogger } from './daemon-logger.js';
|
||||||
import { createSpawnChannelFactory } from '@qwen-code/acp-bridge/spawnChannel';
|
import { createSpawnChannelFactory } from '@qwen-code/acp-bridge/spawnChannel';
|
||||||
import { createDaemonWorkspaceService } from './workspace-service/index.js';
|
import { createDaemonWorkspaceService } from './workspace-service/index.js';
|
||||||
import { SERVE_CAPABILITY_REGISTRY } from './capabilities.js';
|
import { SERVE_CAPABILITY_REGISTRY } from './capabilities.js';
|
||||||
|
|
@ -75,7 +75,7 @@ import type { WorkspaceFileSystemFactory } from './fs/index.js';
|
||||||
import type { PermissionPolicy } from '@qwen-code/acp-bridge';
|
import type { PermissionPolicy } from '@qwen-code/acp-bridge';
|
||||||
import { getCliVersion } from '../utils/version.js';
|
import { getCliVersion } from '../utils/version.js';
|
||||||
import { getRateLimiter } from './rate-limit.js';
|
import { getRateLimiter } from './rate-limit.js';
|
||||||
import type { AcpHttpHandle } from './acpHttp/index.js';
|
import type { AcpHttpHandle } from './acp-http/index.js';
|
||||||
|
|
||||||
const QWEN_SERVER_TOKEN_ENV = 'QWEN_SERVER_TOKEN';
|
const QWEN_SERVER_TOKEN_ENV = 'QWEN_SERVER_TOKEN';
|
||||||
const QWEN_SERVE_PROMPT_DEADLINE_MS_ENV = 'QWEN_SERVE_PROMPT_DEADLINE_MS';
|
const QWEN_SERVE_PROMPT_DEADLINE_MS_ENV = 'QWEN_SERVE_PROMPT_DEADLINE_MS';
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,10 @@ import {
|
||||||
resolvePromptDeadlineMs,
|
resolvePromptDeadlineMs,
|
||||||
} from './server.js';
|
} from './server.js';
|
||||||
import { runQwenServe, type RunHandle } from './run-qwen-serve.js';
|
import { runQwenServe, type RunHandle } from './run-qwen-serve.js';
|
||||||
import { resolveWebShellDir, isDocumentNavigation } from './webShellStatic.js';
|
import {
|
||||||
|
resolveWebShellDir,
|
||||||
|
isDocumentNavigation,
|
||||||
|
} from './web-shell-static.js';
|
||||||
import {
|
import {
|
||||||
CONDITIONAL_SERVE_FEATURES,
|
CONDITIONAL_SERVE_FEATURES,
|
||||||
getAdvertisedServeFeatures,
|
getAdvertisedServeFeatures,
|
||||||
|
|
@ -77,7 +80,7 @@ import {
|
||||||
type BridgeSpawnRequest,
|
type BridgeSpawnRequest,
|
||||||
type AcpSessionBridge,
|
type AcpSessionBridge,
|
||||||
type SessionMetadataUpdate,
|
type SessionMetadataUpdate,
|
||||||
} from './acpSessionBridge.js';
|
} from './acp-session-bridge.js';
|
||||||
import type { BridgeEvent, SubscribeOptions } from './event-bus.js';
|
import type { BridgeEvent, SubscribeOptions } from './event-bus.js';
|
||||||
import type {
|
import type {
|
||||||
ServeSessionContextStatus,
|
ServeSessionContextStatus,
|
||||||
|
|
@ -96,7 +99,7 @@ import type {
|
||||||
ServeWorkspaceToolsStatus,
|
ServeWorkspaceToolsStatus,
|
||||||
} from './status.js';
|
} from './status.js';
|
||||||
import { CAPABILITIES_SCHEMA_VERSION, type ServeOptions } from './types.js';
|
import { CAPABILITIES_SCHEMA_VERSION, type ServeOptions } from './types.js';
|
||||||
import type { DaemonLogger } from './daemonLogger.js';
|
import type { DaemonLogger } from './daemon-logger.js';
|
||||||
import { FsError, type WorkspaceFileSystemFactory } from './fs/index.js';
|
import { FsError, type WorkspaceFileSystemFactory } from './fs/index.js';
|
||||||
|
|
||||||
const baseOpts: ServeOptions = {
|
const baseOpts: ServeOptions = {
|
||||||
|
|
@ -12229,7 +12232,7 @@ describe('sendBridgeError daemonLog routing', () => {
|
||||||
it('routes 5xx errors through daemonLog when provided', async () => {
|
it('routes 5xx errors through daemonLog when provided', async () => {
|
||||||
const tmp = await fsp.mkdtemp(path.join(os.tmpdir(), 'daemon-log-'));
|
const tmp = await fsp.mkdtemp(path.join(os.tmpdir(), 'daemon-log-'));
|
||||||
const stderrLines: string[] = [];
|
const stderrLines: string[] = [];
|
||||||
const { initDaemonLogger } = await import('./daemonLogger.js');
|
const { initDaemonLogger } = await import('./daemon-logger.js');
|
||||||
const daemonLog = initDaemonLogger({
|
const daemonLog = initDaemonLogger({
|
||||||
boundWorkspace: '/w',
|
boundWorkspace: '/w',
|
||||||
pid: 1,
|
pid: 1,
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ import {
|
||||||
type ExtensionSetting,
|
type ExtensionSetting,
|
||||||
} from '@qwen-code/qwen-code-core';
|
} from '@qwen-code/qwen-code-core';
|
||||||
import { writeStderrLine } from '../utils/stdioHelpers.js';
|
import { writeStderrLine } from '../utils/stdioHelpers.js';
|
||||||
import type { DaemonLogger } from './daemonLogger.js';
|
import type { DaemonLogger } from './daemon-logger.js';
|
||||||
import {
|
import {
|
||||||
allowOriginCors,
|
allowOriginCors,
|
||||||
bearerAuth,
|
bearerAuth,
|
||||||
|
|
@ -65,11 +65,11 @@ import { SUPPORTED_LANGUAGES } from '../i18n/index.js';
|
||||||
import { loadSettings } from '../config/settings.js';
|
import { loadSettings } from '../config/settings.js';
|
||||||
import { isWorkspaceTrusted } from '../config/trustedFolders.js';
|
import { isWorkspaceTrusted } from '../config/trustedFolders.js';
|
||||||
import { isLoopbackBind } from './loopback-binds.js';
|
import { isLoopbackBind } from './loopback-binds.js';
|
||||||
import { mountAcpHttp, type AcpHttpHandle } from './acpHttp/index.js';
|
import { mountAcpHttp, type AcpHttpHandle } from './acp-http/index.js';
|
||||||
import {
|
import {
|
||||||
buildDaemonStatusResponse,
|
buildDaemonStatusResponse,
|
||||||
parseDaemonStatusDetail,
|
parseDaemonStatusDetail,
|
||||||
} from './daemonStatus.js';
|
} from './daemon-status.js';
|
||||||
import {
|
import {
|
||||||
canonicalizeWorkspace,
|
canonicalizeWorkspace,
|
||||||
CancelSentinelCollisionError,
|
CancelSentinelCollisionError,
|
||||||
|
|
@ -99,7 +99,7 @@ import {
|
||||||
WorkspaceMismatchError,
|
WorkspaceMismatchError,
|
||||||
type BridgeSessionSummary,
|
type BridgeSessionSummary,
|
||||||
type AcpSessionBridge,
|
type AcpSessionBridge,
|
||||||
} from './acpSessionBridge.js';
|
} from './acp-session-bridge.js';
|
||||||
import {
|
import {
|
||||||
getAdvertisedServeFeatures,
|
getAdvertisedServeFeatures,
|
||||||
getServeProtocolVersions,
|
getServeProtocolVersions,
|
||||||
|
|
@ -118,7 +118,7 @@ import { getDemoHtml } from './demo.js';
|
||||||
import {
|
import {
|
||||||
mountWebShellAssets,
|
mountWebShellAssets,
|
||||||
mountWebShellSpaFallback,
|
mountWebShellSpaFallback,
|
||||||
} from './webShellStatic.js';
|
} from './web-shell-static.js';
|
||||||
import { mountWorkspaceMemoryRoutes } from './workspace-memory.js';
|
import { mountWorkspaceMemoryRoutes } from './workspace-memory.js';
|
||||||
import { mountWorkspaceAgentsRoutes } from './workspace-agents.js';
|
import { mountWorkspaceAgentsRoutes } from './workspace-agents.js';
|
||||||
import {
|
import {
|
||||||
|
|
@ -133,7 +133,7 @@ import {
|
||||||
type WorkspaceRequestContext,
|
type WorkspaceRequestContext,
|
||||||
} from './workspace-service/index.js';
|
} from './workspace-service/index.js';
|
||||||
import { registerWorkspaceSettingsRoutes } from './routes/workspace-settings.js';
|
import { registerWorkspaceSettingsRoutes } from './routes/workspace-settings.js';
|
||||||
import { registerA2uiActionRoutes } from './routes/a2uiAction.js';
|
import { registerA2uiActionRoutes } from './routes/a2ui-action.js';
|
||||||
import {
|
import {
|
||||||
createRateLimiter,
|
createRateLimiter,
|
||||||
setRateLimiter,
|
setRateLimiter,
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ import {
|
||||||
} from 'vitest';
|
} from 'vitest';
|
||||||
import { Storage, QWEN_DIR } from '@qwen-code/qwen-code-core';
|
import { Storage, QWEN_DIR } from '@qwen-code/qwen-code-core';
|
||||||
import { createMutationGate } from './auth.js';
|
import { createMutationGate } from './auth.js';
|
||||||
import type { AcpSessionBridge } from './acpSessionBridge.js';
|
import type { AcpSessionBridge } from './acp-session-bridge.js';
|
||||||
import type { BridgeEvent } from './event-bus.js';
|
import type { BridgeEvent } from './event-bus.js';
|
||||||
import { mountWorkspaceAgentsRoutes } from './workspace-agents.js';
|
import { mountWorkspaceAgentsRoutes } from './workspace-agents.js';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ import { isServeDebugMode } from './debug-mode.js';
|
||||||
import {
|
import {
|
||||||
InvalidClientIdError,
|
InvalidClientIdError,
|
||||||
type AcpSessionBridge,
|
type AcpSessionBridge,
|
||||||
} from './acpSessionBridge.js';
|
} from './acp-session-bridge.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pattern for the route-layer `:agentType` URL parameter. Matches the
|
* Pattern for the route-layer `:agentType` URL parameter. Matches the
|
||||||
|
|
@ -1370,5 +1370,5 @@ export function createDaemonSubagentManager(
|
||||||
|
|
||||||
// Re-export the bridge error type used by route helpers so test files
|
// Re-export the bridge error type used by route helpers so test files
|
||||||
// can import it from a single module without reaching into
|
// can import it from a single module without reaching into
|
||||||
// acpSessionBridge directly.
|
// acp-session-bridge directly.
|
||||||
export { InvalidClientIdError };
|
export { InvalidClientIdError };
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ import { createMutationGate } from './auth.js';
|
||||||
import {
|
import {
|
||||||
InvalidClientIdError,
|
InvalidClientIdError,
|
||||||
type AcpSessionBridge,
|
type AcpSessionBridge,
|
||||||
} from './acpSessionBridge.js';
|
} from './acp-session-bridge.js';
|
||||||
import type { BridgeEvent } from './event-bus.js';
|
import type { BridgeEvent } from './event-bus.js';
|
||||||
import { mountWorkspaceMemoryRoutes } from './workspace-memory.js';
|
import { mountWorkspaceMemoryRoutes } from './workspace-memory.js';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import {
|
||||||
} from '@qwen-code/qwen-code-core';
|
} from '@qwen-code/qwen-code-core';
|
||||||
import { writeStderrLine } from '../utils/stdioHelpers.js';
|
import { writeStderrLine } from '../utils/stdioHelpers.js';
|
||||||
import { isServeDebugMode } from './debug-mode.js';
|
import { isServeDebugMode } from './debug-mode.js';
|
||||||
import type { AcpSessionBridge } from './acpSessionBridge.js';
|
import type { AcpSessionBridge } from './acp-session-bridge.js';
|
||||||
import {
|
import {
|
||||||
createIdleWorkspaceMemoryStatus,
|
createIdleWorkspaceMemoryStatus,
|
||||||
STATUS_SCHEMA_VERSION,
|
STATUS_SCHEMA_VERSION,
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ import type {
|
||||||
DaemonWorkspaceService,
|
DaemonWorkspaceService,
|
||||||
WorkspaceRequestContext,
|
WorkspaceRequestContext,
|
||||||
} from '../types.js';
|
} from '../types.js';
|
||||||
import type { AcpSessionBridge } from '../../acpSessionBridge.js';
|
import type { AcpSessionBridge } from '../../acp-session-bridge.js';
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Test fixtures
|
// Test fixtures
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue