berry-agent 0.1.0-alpha.1
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.
- package/LICENSE +21 -0
- package/README.md +96 -0
- package/dist/.api-emit.stamp +1 -0
- package/dist/.build-meta.json +6 -0
- package/dist/agent/events.js +1 -0
- package/dist/agent/index.js +2 -0
- package/dist/agent/loop.js +139 -0
- package/dist/agent/queue.js +119 -0
- package/dist/agent/stream.js +62 -0
- package/dist/agent/tools-batch.js +221 -0
- package/dist/agent/types.js +8 -0
- package/dist/api/berry-agent-llm.d.ts +18 -0
- package/dist/api/berry-agent.d.ts +9 -0
- package/dist/api/surface.json +1632 -0
- package/dist/api/tsconfig.paths.json +12 -0
- package/dist/api/typebox-compile.d.ts +2 -0
- package/dist/api/typebox-value.d.ts +2 -0
- package/dist/api/typebox.d.ts +2 -0
- package/dist/browser/cdp.js +256 -0
- package/dist/browser/codes.js +31 -0
- package/dist/browser/discover.js +107 -0
- package/dist/browser/engine.js +169 -0
- package/dist/browser/index.js +17 -0
- package/dist/browser/install.js +342 -0
- package/dist/browser/page.js +321 -0
- package/dist/browser/service.js +158 -0
- package/dist/browser/tools.js +198 -0
- package/dist/browser/types.js +81 -0
- package/dist/channels/ask-queue.js +82 -0
- package/dist/channels/commands.js +129 -0
- package/dist/channels/engine/cell.js +143 -0
- package/dist/channels/engine/diff.js +143 -0
- package/dist/channels/engine/engine.js +416 -0
- package/dist/channels/engine/index.js +8 -0
- package/dist/channels/engine/input-keys.js +86 -0
- package/dist/channels/engine/input.js +596 -0
- package/dist/channels/engine/memory-io.js +71 -0
- package/dist/channels/engine/process-io.js +38 -0
- package/dist/channels/engine/types.js +17 -0
- package/dist/channels/engine/width.js +122 -0
- package/dist/channels/index.js +15 -0
- package/dist/channels/registry.js +56 -0
- package/dist/channels/sdk/admit.js +29 -0
- package/dist/channels/sdk/backend.js +102 -0
- package/dist/channels/sdk/cursor.js +56 -0
- package/dist/channels/sdk/index.js +20 -0
- package/dist/channels/sdk/jsonl.js +208 -0
- package/dist/channels/sdk/protocol.js +24 -0
- package/dist/channels/sdk/schema.js +91 -0
- package/dist/channels/sdk/wire-core.js +446 -0
- package/dist/channels/service.js +169 -0
- package/dist/channels/tui/autocomplete/autocomplete.js +42 -0
- package/dist/channels/tui/autocomplete/file-mentions.js +106 -0
- package/dist/channels/tui/autocomplete/popup.js +148 -0
- package/dist/channels/tui/autocomplete/provider.js +7 -0
- package/dist/channels/tui/autocomplete/token.js +68 -0
- package/dist/channels/tui/backend/ansi-rows.js +211 -0
- package/dist/channels/tui/backend/main-screen.js +207 -0
- package/dist/channels/tui/backend/osc.js +91 -0
- package/dist/channels/tui/backend/transcript.js +230 -0
- package/dist/channels/tui/backend/tui-backend.js +915 -0
- package/dist/channels/tui/editor/editor-model.js +543 -0
- package/dist/channels/tui/editor/editor-view.js +140 -0
- package/dist/channels/tui/editor/editor.js +275 -0
- package/dist/channels/tui/editor/undo-stack.js +35 -0
- package/dist/channels/tui/editor/visual-lines.js +126 -0
- package/dist/channels/tui/editor/word-nav.js +106 -0
- package/dist/channels/tui/history/history-viewer.js +403 -0
- package/dist/channels/tui/index.js +3 -0
- package/dist/channels/tui/layout.js +167 -0
- package/dist/channels/tui/markdown/blocks.js +111 -0
- package/dist/channels/tui/markdown/inline.js +75 -0
- package/dist/channels/tui/markdown/markdown.js +182 -0
- package/dist/channels/tui/memory/memory-viewer.js +540 -0
- package/dist/channels/tui/overlay/alt-screen.js +105 -0
- package/dist/channels/tui/overlay/overlay.js +57 -0
- package/dist/channels/tui/overlay/select-confirm.js +156 -0
- package/dist/channels/tui/panels/todo-panel.js +54 -0
- package/dist/channels/tui/panels/tool-progress-panel.js +93 -0
- package/dist/channels/tui/scroll/scroll-view.js +254 -0
- package/dist/channels/tui/status/status-line.js +76 -0
- package/dist/channels/tui/text.js +38 -0
- package/dist/channels/tui/theme.js +41 -0
- package/dist/channels/types.js +11 -0
- package/dist/channels/ui-core.js +209 -0
- package/dist/checkpoint/capture.js +45 -0
- package/dist/checkpoint/codes.js +33 -0
- package/dist/checkpoint/command.js +82 -0
- package/dist/checkpoint/gate.js +48 -0
- package/dist/checkpoint/index.js +20 -0
- package/dist/checkpoint/restore.js +172 -0
- package/dist/checkpoint/store.js +247 -0
- package/dist/checkpoint/types.js +4 -0
- package/dist/checkpoint/walk.js +146 -0
- package/dist/compaction/ccr-tools.js +112 -0
- package/dist/compaction/ccr.js +84 -0
- package/dist/compaction/codes.js +21 -0
- package/dist/compaction/index.js +18 -0
- package/dist/compaction/policy.js +200 -0
- package/dist/compaction/service.js +422 -0
- package/dist/compaction/slots.js +121 -0
- package/dist/compaction/types.js +10 -0
- package/dist/context/codes.js +40 -0
- package/dist/context/events.js +160 -0
- package/dist/context/index.js +13 -0
- package/dist/context/logger.js +136 -0
- package/dist/context/scope.js +182 -0
- package/dist/context/workspace.js +104 -0
- package/dist/contracts/agent-events.d.ts +73 -0
- package/dist/contracts/agent-events.js +16 -0
- package/dist/contracts/api.d.ts +249 -0
- package/dist/contracts/api.js +299 -0
- package/dist/contracts/approval.d.ts +37 -0
- package/dist/contracts/approval.js +9 -0
- package/dist/contracts/env-ref.d.ts +41 -0
- package/dist/contracts/env-ref.js +32 -0
- package/dist/contracts/errors.d.ts +56 -0
- package/dist/contracts/errors.js +266 -0
- package/dist/contracts/events.d.ts +70 -0
- package/dist/contracts/events.js +329 -0
- package/dist/contracts/index.d.ts +32 -0
- package/dist/contracts/index.js +26 -0
- package/dist/contracts/llm.d.ts +275 -0
- package/dist/contracts/llm.js +12 -0
- package/dist/contracts/messages.d.ts +63 -0
- package/dist/contracts/messages.js +65 -0
- package/dist/contracts/redact.d.ts +46 -0
- package/dist/contracts/redact.js +223 -0
- package/dist/contracts/tools.d.ts +197 -0
- package/dist/contracts/tools.js +33 -0
- package/dist/contracts/types.d.ts +302 -0
- package/dist/contracts/types.js +50 -0
- package/dist/contracts/ui.d.ts +122 -0
- package/dist/contracts/ui.js +15 -0
- package/dist/conversation/agent-service.js +61 -0
- package/dist/conversation/approval-wiring.js +82 -0
- package/dist/conversation/backoff.js +38 -0
- package/dist/conversation/codes.js +47 -0
- package/dist/conversation/control-tools.js +102 -0
- package/dist/conversation/control.js +210 -0
- package/dist/conversation/driver.js +922 -0
- package/dist/conversation/index.js +12 -0
- package/dist/conversation/model-visible.js +169 -0
- package/dist/conversation/open-tools.js +126 -0
- package/dist/conversation/reseed.js +132 -0
- package/dist/conversation/sessions.js +215 -0
- package/dist/conversation/todo.js +203 -0
- package/dist/conversation/types.js +35 -0
- package/dist/conversation/wiring.js +204 -0
- package/dist/credentials/codes.js +59 -0
- package/dist/credentials/commands.js +186 -0
- package/dist/credentials/env-ref.js +34 -0
- package/dist/credentials/index.js +28 -0
- package/dist/credentials/migration.js +18 -0
- package/dist/credentials/oauth.js +266 -0
- package/dist/credentials/refresh.js +152 -0
- package/dist/credentials/secrets.js +118 -0
- package/dist/credentials/types.js +30 -0
- package/dist/exec/bash.js +279 -0
- package/dist/exec/codes.js +37 -0
- package/dist/exec/env.js +99 -0
- package/dist/exec/environment.js +39 -0
- package/dist/exec/git-guard.js +623 -0
- package/dist/exec/index.js +24 -0
- package/dist/exec/registry.js +120 -0
- package/dist/exec/spawn.js +281 -0
- package/dist/exec/tail.js +77 -0
- package/dist/exec/types.js +5 -0
- package/dist/goal/codes.js +33 -0
- package/dist/goal/command.js +175 -0
- package/dist/goal/fold.js +121 -0
- package/dist/goal/gates.js +122 -0
- package/dist/goal/index.js +22 -0
- package/dist/goal/migration.js +48 -0
- package/dist/goal/service.js +501 -0
- package/dist/goal/todo-tool.js +174 -0
- package/dist/goal/types.js +1 -0
- package/dist/goal/update-tool.js +46 -0
- package/dist/host/approval-cmd.js +276 -0
- package/dist/host/assembly.js +1146 -0
- package/dist/host/boot-failures.js +104 -0
- package/dist/host/budget-advisory.js +74 -0
- package/dist/host/budget-broadcast.js +50 -0
- package/dist/host/builtins.js +54 -0
- package/dist/host/cli.js +544 -0
- package/dist/host/codes.js +120 -0
- package/dist/host/config-schema.js +195 -0
- package/dist/host/conversation-stack.js +654 -0
- package/dist/host/core-plugins.js +1685 -0
- package/dist/host/credentials-cmd.js +42 -0
- package/dist/host/disclosure.js +30 -0
- package/dist/host/dispatch.js +105 -0
- package/dist/host/doors-cmd.js +154 -0
- package/dist/host/dump-config.js +44 -0
- package/dist/host/hook-dispatch-guard.js +27 -0
- package/dist/host/import-gate.js +153 -0
- package/dist/host/index.js +54 -0
- package/dist/host/issue-session.js +241 -0
- package/dist/host/loader.js +372 -0
- package/dist/host/main.js +161 -0
- package/dist/host/manifest.js +381 -0
- package/dist/host/mcp-entry.js +53 -0
- package/dist/host/plugin-boot.js +952 -0
- package/dist/host/plugin-context.js +672 -0
- package/dist/host/plugin-install.js +480 -0
- package/dist/host/plugin-reload.js +124 -0
- package/dist/host/plugin-store.js +462 -0
- package/dist/host/plugin-tools.js +359 -0
- package/dist/host/plugin-uninstall.js +257 -0
- package/dist/host/plugins-cmd.js +302 -0
- package/dist/host/plugins-command.js +130 -0
- package/dist/host/plugins-config.js +195 -0
- package/dist/host/prompt-sections.js +133 -0
- package/dist/host/run-entry.js +544 -0
- package/dist/host/runtime.js +209 -0
- package/dist/host/scheduler-tick.js +294 -0
- package/dist/host/serve-daemon.js +501 -0
- package/dist/host/serve-entry.js +279 -0
- package/dist/host/session-anchor.js +41 -0
- package/dist/host/sessions-cmd.js +219 -0
- package/dist/host/sessions-face.js +47 -0
- package/dist/host/settings-store.js +112 -0
- package/dist/host/signals.js +69 -0
- package/dist/host/single-instance.js +105 -0
- package/dist/host/subagent-factory.js +291 -0
- package/dist/host/testkit/harness.js +283 -0
- package/dist/host/testkit/index.js +14 -0
- package/dist/host/testkit/matrix.js +302 -0
- package/dist/host/tool-policy-store.js +177 -0
- package/dist/host/triggers.js +212 -0
- package/dist/host/tui-entry.js +216 -0
- package/dist/host/webui-bridge.js +165 -0
- package/dist/issue/codes.js +38 -0
- package/dist/issue/filter.js +146 -0
- package/dist/issue/github.js +116 -0
- package/dist/issue/index.js +17 -0
- package/dist/issue/mount.js +70 -0
- package/dist/issue/poll.js +58 -0
- package/dist/issue/service.js +341 -0
- package/dist/issue/tools.js +70 -0
- package/dist/issue/types.js +34 -0
- package/dist/issue/webhook.js +126 -0
- package/dist/llm/codes.js +77 -0
- package/dist/llm/complete.js +196 -0
- package/dist/llm/events.js +15 -0
- package/dist/llm/index.js +24 -0
- package/dist/llm/inflight.js +65 -0
- package/dist/llm/model-id.js +58 -0
- package/dist/llm/provider-face.d.ts +32 -0
- package/dist/llm/provider-face.js +34 -0
- package/dist/llm/recovery.js +146 -0
- package/dist/llm/runtime.js +46 -0
- package/dist/llm/stream-fn.js +147 -0
- package/dist/lsp/codes.js +31 -0
- package/dist/lsp/connection.js +147 -0
- package/dist/lsp/frame.js +110 -0
- package/dist/lsp/index.js +16 -0
- package/dist/lsp/inject.js +58 -0
- package/dist/lsp/instance.js +264 -0
- package/dist/lsp/service.js +522 -0
- package/dist/lsp/tools.js +53 -0
- package/dist/lsp/types.js +201 -0
- package/dist/mcp/bridge.js +222 -0
- package/dist/mcp/codes.js +21 -0
- package/dist/mcp/index.js +19 -0
- package/dist/mcp/jsonrpc.js +230 -0
- package/dist/mcp/service.js +125 -0
- package/dist/mcp/tools.js +145 -0
- package/dist/mcp/types.js +108 -0
- package/dist/memory/cite.js +131 -0
- package/dist/memory/codes.js +50 -0
- package/dist/memory/command.js +71 -0
- package/dist/memory/consolidate.js +219 -0
- package/dist/memory/cycle.js +109 -0
- package/dist/memory/dao.js +878 -0
- package/dist/memory/diff.js +238 -0
- package/dist/memory/extract.js +181 -0
- package/dist/memory/fts.js +58 -0
- package/dist/memory/index.js +42 -0
- package/dist/memory/inject.js +354 -0
- package/dist/memory/merge.js +178 -0
- package/dist/memory/migration.js +132 -0
- package/dist/memory/pollution.js +59 -0
- package/dist/memory/port.js +385 -0
- package/dist/memory/review.js +201 -0
- package/dist/memory/scan.js +89 -0
- package/dist/memory/tools.js +508 -0
- package/dist/memory/types.js +140 -0
- package/dist/obs/codes.js +38 -0
- package/dist/obs/db.js +115 -0
- package/dist/obs/index.js +20 -0
- package/dist/obs/rollup.js +61 -0
- package/dist/obs/service.js +363 -0
- package/dist/obs/session-tools.js +282 -0
- package/dist/obs/session-view.js +225 -0
- package/dist/obs/tool.js +97 -0
- package/dist/obs/types.js +1 -0
- package/dist/persist/audit.js +63 -0
- package/dist/persist/aux.js +39 -0
- package/dist/persist/codes.js +35 -0
- package/dist/persist/index.js +30 -0
- package/dist/persist/load-history.js +50 -0
- package/dist/persist/migrations.js +37 -0
- package/dist/persist/paths.js +108 -0
- package/dist/persist/persistence.js +229 -0
- package/dist/persist/schema.js +99 -0
- package/dist/persist/secret-box.js +95 -0
- package/dist/persist/store.js +706 -0
- package/dist/persist/write-behind.js +238 -0
- package/dist/safety/approval.js +171 -0
- package/dist/safety/bwrap.js +123 -0
- package/dist/safety/codes.js +57 -0
- package/dist/safety/danger.js +505 -0
- package/dist/safety/gate.js +226 -0
- package/dist/safety/index.js +24 -0
- package/dist/safety/presets.js +73 -0
- package/dist/safety/roots.js +139 -0
- package/dist/safety/sandbox.js +214 -0
- package/dist/safety/seatbelt.js +88 -0
- package/dist/safety/sensitive.js +34 -0
- package/dist/safety/tool-policy.js +203 -0
- package/dist/safety/types.js +13 -0
- package/dist/scheduler/codes.js +54 -0
- package/dist/scheduler/cron-backend.js +135 -0
- package/dist/scheduler/engine.js +280 -0
- package/dist/scheduler/gates.js +60 -0
- package/dist/scheduler/index.js +25 -0
- package/dist/scheduler/migration.js +22 -0
- package/dist/scheduler/runner.js +171 -0
- package/dist/scheduler/schedule.js +193 -0
- package/dist/scheduler/service.js +283 -0
- package/dist/scheduler/tick.js +139 -0
- package/dist/scheduler/types.js +1 -0
- package/dist/sdk/http.js +865 -0
- package/dist/sdk/index.js +22 -0
- package/dist/sdk/mcp.js +289 -0
- package/dist/sdk/plugin-route-registry.js +126 -0
- package/dist/sdk/plugin-routes.js +149 -0
- package/dist/sdk/security.js +116 -0
- package/dist/sdk/types.js +32 -0
- package/dist/session/budget.js +159 -0
- package/dist/session/codes.js +40 -0
- package/dist/session/derive.js +180 -0
- package/dist/session/event-data.js +1 -0
- package/dist/session/fork.js +72 -0
- package/dist/session/import-gates.js +148 -0
- package/dist/session/index.js +18 -0
- package/dist/session/recover.js +103 -0
- package/dist/session/session.js +279 -0
- package/dist/session/snapshot.js +107 -0
- package/dist/skills/agents.js +242 -0
- package/dist/skills/codes.js +51 -0
- package/dist/skills/discovery.js +266 -0
- package/dist/skills/frontmatter.js +215 -0
- package/dist/skills/index.js +28 -0
- package/dist/skills/load.js +118 -0
- package/dist/skills/manage.js +201 -0
- package/dist/skills/registry.js +138 -0
- package/dist/skills/render.js +124 -0
- package/dist/skills/sections.js +171 -0
- package/dist/skills/types.js +21 -0
- package/dist/subagent/codes.js +50 -0
- package/dist/subagent/declarative.js +55 -0
- package/dist/subagent/index.js +19 -0
- package/dist/subagent/notify.js +51 -0
- package/dist/subagent/provide.js +7 -0
- package/dist/subagent/registry.js +149 -0
- package/dist/subagent/service.js +338 -0
- package/dist/subagent/surface.js +44 -0
- package/dist/subagent/tool.js +153 -0
- package/dist/subagent/types.js +25 -0
- package/dist/tools/apply-patch.js +164 -0
- package/dist/tools/codes.js +109 -0
- package/dist/tools/fs.js +501 -0
- package/dist/tools/index.js +17 -0
- package/dist/tools/observed.js +99 -0
- package/dist/tools/pipeline.js +176 -0
- package/dist/tools/protected-read.js +54 -0
- package/dist/tools/registry.js +250 -0
- package/dist/tools/search.js +451 -0
- package/dist/tools/worktree.js +327 -0
- package/dist/web/codes.js +37 -0
- package/dist/web/gate.js +43 -0
- package/dist/web/hygiene.js +195 -0
- package/dist/web/index.js +16 -0
- package/dist/web/service.js +207 -0
- package/dist/web/ssrf-guard.js +44 -0
- package/dist/web/tool.js +76 -0
- package/dist/web/types.js +10 -0
- package/dist/webui/assets/index-B-t2O8gh.js +22 -0
- package/dist/webui/assets/index-DOlgSZ9Q.css +2 -0
- package/dist/webui/index.html +14 -0
- package/dist/webui/index.js +14 -0
- package/dist/webui/server.js +549 -0
- package/dist/webui/types.js +38 -0
- package/examples/README.md +26 -0
- package/examples/minimal-code-plugin/entry.js +43 -0
- package/examples/minimal-code-plugin/package.json +12 -0
- package/examples/pure-skill-pack/package.json +14 -0
- package/examples/pure-skill-pack/skills/markdown-table/SKILL.md +32 -0
- package/package.json +86 -0
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* core:lsp 类型面(03 §10.2——帧层 + 惰性实例 + 诊断回流;批 17a-3)。
|
|
3
|
+
*
|
|
4
|
+
* 词面独立律(02 §4.1 席 deps = contracts + context):本件与 exec/tools 零
|
|
5
|
+
* DAG 边——spawn / 工具注册 / 事件挂线 / 盘读全经**窄面注入**消费(mcp 件
|
|
6
|
+
* McpSpawnFace 先例同律):
|
|
7
|
+
* - `LspSpawnFace` 与 exec SpawnPipeline.spawnInteractive 结构兼容(组合根
|
|
8
|
+
* 直接传管道真身;兼容性互证测试在 compat.test.ts);
|
|
9
|
+
* - `LspRegisterToolsFace` 与 tools ToolRegistry.register 子面结构兼容;
|
|
10
|
+
* - `LspScopeFace` 与 context Scope 的 effect/isDisposed 子面结构兼容;
|
|
11
|
+
* - `LspEventsFace` 与 context EventDispatch.onWaterfall 子面结构兼容
|
|
12
|
+
* (tools_post_execute 挂线面);
|
|
13
|
+
* - `LspFsFace` 与 node:fs/promises 子面结构兼容(readFile/realpath——盘
|
|
14
|
+
* 真相源同步用)。
|
|
15
|
+
*
|
|
16
|
+
* context 席边为真消费(createLogger——装载态 ui.notify 接线随装配批)。
|
|
17
|
+
*
|
|
18
|
+
* 配置面归一(03 §10.2「config 坏形装载期归一响亮拒」条——2026-09-13 f-2
|
|
19
|
+
* 批立):行 config 经 `normalizeLspSettings` 装载期归一,坏形抛
|
|
20
|
+
* `LSP_CONFIG_INVALID` → 行级装载失败(/reload 时刻可修,与
|
|
21
|
+
* `MCP_CONFIG_INVALID`/`ISSUE_CONFIG_INVALID` 坏形律同族)。归一器与辅助
|
|
22
|
+
* 函数落本件——词面独立律下不 import mcp(镜像实现各自自持)。
|
|
23
|
+
*/
|
|
24
|
+
import { BaseError } from '../contracts/index.js';
|
|
25
|
+
/* ---------------- 常量(缺省值单源——03 §10.2 字段落码定形注) ---------------- */
|
|
26
|
+
/** 攒头态字节帽(无 \r\n\r\n 分隔符的持续流不无界攒积——超帽走坏帧路径) */
|
|
27
|
+
export const LSP_HEADER_LIMIT_BYTES = 16 * 1024;
|
|
28
|
+
/** 攒正文态字节帽(Content-Length 声明值即缓冲吸收上界——超帽走坏帧路径) */
|
|
29
|
+
export const LSP_BODY_LIMIT_BYTES = 16 * 1024 * 1024;
|
|
30
|
+
/** initialize 握手预算缺省秒数(只罩 spawn+握手;与请求钟分账不互截) */
|
|
31
|
+
export const LSP_STARTUP_TIMEOUT_SEC_DEFAULT = 30;
|
|
32
|
+
/** 单请求预算缺省秒数(只计单请求——与握手钟分账,两钟接力) */
|
|
33
|
+
export const LSP_REQUEST_TIMEOUT_SEC_DEFAULT = 15;
|
|
34
|
+
/** 同 server 连败熔断阈值(实例级旗标、复位走 /reload) */
|
|
35
|
+
export const LSP_CIRCUIT_FAILURE_LIMIT = 3;
|
|
36
|
+
/** 协议化关停宽限缺省(shutdown → exit 通知 → 宽限等退 → killTree 兜底) */
|
|
37
|
+
export const LSP_CLOSE_GRACE_MS = 3_000;
|
|
38
|
+
/** 诊断回流竞速钟缺省(工具面与 post 注入同源) */
|
|
39
|
+
export const LSP_DIAGNOSTICS_TIMEOUT_MS_DEFAULT = 3_500;
|
|
40
|
+
/** 诊断回流竞速钟硬帽(04 §11 同数——min(配置, 硬帽) 执法位) */
|
|
41
|
+
export const LSP_DIAGNOSTICS_TIMEOUT_MS_CAP = 3_500;
|
|
42
|
+
/** 诊断段条目上限(单次注入合计——超限截断注记) */
|
|
43
|
+
export const LSP_DIAGNOSTICS_MAX_ITEMS = 50;
|
|
44
|
+
/** 诊断段总字节上限(追加进 result.content 的段尺寸帽) */
|
|
45
|
+
export const LSP_DIAGNOSTICS_SEGMENT_LIMIT_BYTES = 4 * 1024;
|
|
46
|
+
/**
|
|
47
|
+
* 归一行 config(坏形响亮拒 LSP_CONFIG_INVALID——/reload 时刻可见;镜像
|
|
48
|
+
* mcp normalizeMcpConfig 律,词面独立律下辅助函数局部自持)。
|
|
49
|
+
* null/undefined → 空形 `{servers:{}}`(缺省 servers 空 = 行惰性无害零
|
|
50
|
+
* spawn);servers 键缺席同归空表(件级 diagnostics_timeout_ms 可独行)。
|
|
51
|
+
*/
|
|
52
|
+
export function normalizeLspSettings(raw) {
|
|
53
|
+
if (raw === undefined || raw === null)
|
|
54
|
+
return { servers: {} };
|
|
55
|
+
if (typeof raw !== 'object' || Array.isArray(raw)) {
|
|
56
|
+
throw new BaseError('LSP_CONFIG_INVALID', 'config 须为对象(servers + diagnostics_timeout_ms)');
|
|
57
|
+
}
|
|
58
|
+
const v = raw;
|
|
59
|
+
const servers = v.servers === undefined ? {} : normalizeServers(v.servers);
|
|
60
|
+
const diagnostics = positiveNumber(v.diagnostics_timeout_ms, 'diagnostics_timeout_ms');
|
|
61
|
+
return { servers, ...(diagnostics !== undefined ? { diagnostics_timeout_ms: diagnostics } : {}) };
|
|
62
|
+
}
|
|
63
|
+
/** servers 整值归一(键声明序 = 路由裁决序,Object.entries 保插入序) */
|
|
64
|
+
function normalizeServers(raw) {
|
|
65
|
+
if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {
|
|
66
|
+
throw new BaseError('LSP_CONFIG_INVALID', 'config.servers 须为对象(键 = 服务器名)');
|
|
67
|
+
}
|
|
68
|
+
const out = {};
|
|
69
|
+
for (const [name, value] of Object.entries(raw)) {
|
|
70
|
+
out[name] = normalizeServerEntry(name, value);
|
|
71
|
+
}
|
|
72
|
+
return out;
|
|
73
|
+
}
|
|
74
|
+
/** 单服务器条目归一(字段集逐一类型校验——绝对路径/非空路由表/正数域) */
|
|
75
|
+
function normalizeServerEntry(name, value) {
|
|
76
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
77
|
+
throw new BaseError('LSP_CONFIG_INVALID', `servers.${name} 须为对象`);
|
|
78
|
+
}
|
|
79
|
+
const v = value;
|
|
80
|
+
const command = v.command;
|
|
81
|
+
if (typeof command !== 'string' || command === '' || !command.startsWith('/')) {
|
|
82
|
+
throw new BaseError('LSP_CONFIG_INVALID', `servers.${name}.command 须为绝对路径(v1 只收绝对路径):${JSON.stringify(command)}`);
|
|
83
|
+
}
|
|
84
|
+
const languages = v.languages;
|
|
85
|
+
if (!Array.isArray(languages) || languages.length === 0 || languages.some((l) => typeof l !== 'string' || l === '')) {
|
|
86
|
+
// 空表即路由永不命中的死行——扩展名路由表的物理前提,缺席与空表同拒
|
|
87
|
+
throw new BaseError('LSP_CONFIG_INVALID', `servers.${name}.languages 须为非空字符串数组`);
|
|
88
|
+
}
|
|
89
|
+
const args = strArray(v.args, `servers.${name}.args`);
|
|
90
|
+
const env = strRecord(v.env, `servers.${name}.env`);
|
|
91
|
+
const startup = positiveNumber(v.startup_timeout_sec, `servers.${name}.startup_timeout_sec`);
|
|
92
|
+
const request = positiveNumber(v.request_timeout_sec, `servers.${name}.request_timeout_sec`);
|
|
93
|
+
return {
|
|
94
|
+
command,
|
|
95
|
+
languages: languages,
|
|
96
|
+
...(args !== undefined ? { args } : {}),
|
|
97
|
+
...(env !== undefined ? { env } : {}),
|
|
98
|
+
...(startup !== undefined ? { startup_timeout_sec: startup } : {}),
|
|
99
|
+
...(request !== undefined ? { request_timeout_sec: request } : {}),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
/** 字符串数组字段校验(undefined 放行——可选字段缺席合法) */
|
|
103
|
+
function strArray(value, label) {
|
|
104
|
+
if (value === undefined)
|
|
105
|
+
return undefined;
|
|
106
|
+
if (!Array.isArray(value) || value.some((e) => typeof e !== 'string')) {
|
|
107
|
+
throw new BaseError('LSP_CONFIG_INVALID', `${label} 须为字符串数组`);
|
|
108
|
+
}
|
|
109
|
+
return value;
|
|
110
|
+
}
|
|
111
|
+
/** 字符串记录字段校验(env 显式注入面) */
|
|
112
|
+
function strRecord(value, label) {
|
|
113
|
+
if (value === undefined)
|
|
114
|
+
return undefined;
|
|
115
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
116
|
+
throw new BaseError('LSP_CONFIG_INVALID', `${label} 须为 string→string 对象`);
|
|
117
|
+
}
|
|
118
|
+
for (const [k, val] of Object.entries(value)) {
|
|
119
|
+
if (typeof val !== 'string') {
|
|
120
|
+
throw new BaseError('LSP_CONFIG_INVALID', `${label}.${k} 须为 string`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return value;
|
|
124
|
+
}
|
|
125
|
+
/** 正数域字段校验(超时秒/ms——0/负/非数拒) */
|
|
126
|
+
function positiveNumber(value, label) {
|
|
127
|
+
if (value === undefined)
|
|
128
|
+
return undefined;
|
|
129
|
+
if (typeof value !== 'number' || !Number.isFinite(value) || value <= 0) {
|
|
130
|
+
throw new BaseError('LSP_CONFIG_INVALID', `${label} 须为正数`);
|
|
131
|
+
}
|
|
132
|
+
return value;
|
|
133
|
+
}
|
|
134
|
+
/* ---------------- 路由(扩展名路由表——全件唯一裁决序) ---------------- */
|
|
135
|
+
/** 扩展名归一(剥前导点 + lowercase) */
|
|
136
|
+
export function normalizeExtension(ext) {
|
|
137
|
+
return ext.replace(/^\.+/, '').toLowerCase();
|
|
138
|
+
}
|
|
139
|
+
/** 路径扩展名提取(末点后段,lowercase;无点返空串) */
|
|
140
|
+
export function extensionOf(path) {
|
|
141
|
+
const base = path.slice(Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\')) + 1);
|
|
142
|
+
const dot = base.lastIndexOf('.');
|
|
143
|
+
return dot < 0 ? '' : base.slice(dot + 1).toLowerCase();
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* 扩展名路由:config 键声明序扫描,首命中即返(多服务器同扩展名 = 声明序
|
|
147
|
+
* 首裁决——四工具与诊断注入同表同序,路由规则全件唯一)。无命中返 null。
|
|
148
|
+
*/
|
|
149
|
+
export function routeServer(config, path) {
|
|
150
|
+
const ext = extensionOf(path);
|
|
151
|
+
if (ext === '')
|
|
152
|
+
return null;
|
|
153
|
+
for (const [name, entry] of Object.entries(config)) {
|
|
154
|
+
if (entry.languages.some((l) => normalizeExtension(l) === ext))
|
|
155
|
+
return name;
|
|
156
|
+
}
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
/** didOpen languageId 派生表(常见扩展名;缺席回退扩展名本身) */
|
|
160
|
+
const LANGUAGE_IDS = {
|
|
161
|
+
ts: 'typescript',
|
|
162
|
+
tsx: 'typescriptreact',
|
|
163
|
+
mts: 'typescript',
|
|
164
|
+
cts: 'typescript',
|
|
165
|
+
js: 'javascript',
|
|
166
|
+
jsx: 'javascriptreact',
|
|
167
|
+
mjs: 'javascript',
|
|
168
|
+
cjs: 'javascript',
|
|
169
|
+
json: 'json',
|
|
170
|
+
md: 'markdown',
|
|
171
|
+
py: 'python',
|
|
172
|
+
rs: 'rust',
|
|
173
|
+
go: 'go',
|
|
174
|
+
java: 'java',
|
|
175
|
+
rb: 'ruby',
|
|
176
|
+
php: 'php',
|
|
177
|
+
c: 'c',
|
|
178
|
+
h: 'c',
|
|
179
|
+
cpp: 'cpp',
|
|
180
|
+
cc: 'cpp',
|
|
181
|
+
hpp: 'cpp',
|
|
182
|
+
cs: 'csharp',
|
|
183
|
+
css: 'css',
|
|
184
|
+
scss: 'scss',
|
|
185
|
+
html: 'html',
|
|
186
|
+
yml: 'yaml',
|
|
187
|
+
yaml: 'yaml',
|
|
188
|
+
toml: 'toml',
|
|
189
|
+
sh: 'shellscript',
|
|
190
|
+
zsh: 'shellscript',
|
|
191
|
+
sql: 'sql',
|
|
192
|
+
};
|
|
193
|
+
/** languageId 派生(扩展名 → languageId;未收录回退扩展名——诚实不猜语义) */
|
|
194
|
+
export function languageIdForPath(path) {
|
|
195
|
+
const ext = extensionOf(path);
|
|
196
|
+
return LANGUAGE_IDS[ext] ?? (ext !== '' ? ext : 'plaintext');
|
|
197
|
+
}
|
|
198
|
+
/** 工具结果文本项便捷构造(测试与工具面共用) */
|
|
199
|
+
export function textResult(text, isError) {
|
|
200
|
+
return { content: [{ type: 'text', text }], ...(isError === true ? { isError: true } : {}) };
|
|
201
|
+
}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP 服务器桥(03 §10.1 连接语义与子进程治理的承载腿——一服务器一桥)。
|
|
3
|
+
*
|
|
4
|
+
* connect 编舞:spawn(exec 管道窄面 + 登记簿同册)→ stderr 转 logger
|
|
5
|
+
* debug → initialize 握手(startup_timeout_sec 预算罩 spawn+握手全程)→
|
|
6
|
+
* notifications/initialized → tools/list 分页跟尽(nextCursor 不跟即静默丢
|
|
7
|
+
* 工具)。连接期任一步折 = MCP_CONNECT_FAILED(子进程收场不留孤儿)。
|
|
8
|
+
*
|
|
9
|
+
* call:tools/call 落桥(tool_timeout_sec 逐台执法);crash(载体 close)→
|
|
10
|
+
* 在途请求拒 + onDown 通知(服务面撤工具)——不自动重连,复位走 /reload。
|
|
11
|
+
*
|
|
12
|
+
* close(协议化关停——ctx.effect 回卷消费):stdin.end() 告别 → 宽限等退 →
|
|
13
|
+
* killTree 树杀兜底;幂等(二次 close 复用同一结算)。
|
|
14
|
+
*/
|
|
15
|
+
import { BaseError } from '../contracts/index.js';
|
|
16
|
+
import { createLogger } from '../context/index.js';
|
|
17
|
+
import { JsonRpcConnection } from './jsonrpc.js';
|
|
18
|
+
import { MCP_CLOSE_GRACE_MS, MCP_LINE_LIMIT_BYTES, MCP_PROTOCOL_VERSION, MCP_STARTUP_TIMEOUT_SEC_DEFAULT, MCP_TOOL_TIMEOUT_SEC_DEFAULT, } from './types.js';
|
|
19
|
+
/**
|
|
20
|
+
* 连接单服务器(发现全程——握手+分页)。连接期失败抛 MCP_CONNECT_FAILED
|
|
21
|
+
* (spawn 失败 / 握手超时 / 行帧超帽 / 服务器即退),子进程在抛出前收场。
|
|
22
|
+
*/
|
|
23
|
+
export async function connectMcpServer(server, config, deps) {
|
|
24
|
+
const logger = deps.logger ?? createLogger('mcp');
|
|
25
|
+
const graceMs = deps.closeGraceMs ?? MCP_CLOSE_GRACE_MS;
|
|
26
|
+
const startupMs = (config.startup_timeout_sec ?? MCP_STARTUP_TIMEOUT_SEC_DEFAULT) * 1_000;
|
|
27
|
+
const toolTimeoutMs = (config.tool_timeout_sec ?? MCP_TOOL_TIMEOUT_SEC_DEFAULT) * 1_000;
|
|
28
|
+
// ── spawn(登记簿同册:owner = mcp:<server>——「谁开的」审计面) ──
|
|
29
|
+
let child;
|
|
30
|
+
try {
|
|
31
|
+
child = deps.spawn.spawnInteractive({
|
|
32
|
+
argv: [config.command, ...(config.args ?? [])],
|
|
33
|
+
env: config.env !== undefined ? { set: config.env } : undefined,
|
|
34
|
+
owner: `mcp:${server}`,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
throw new BaseError('MCP_CONNECT_FAILED', `spawn 失败(${server}):${errText(err)}`, { cause: asError(err) });
|
|
39
|
+
}
|
|
40
|
+
// ── 载体状态机(crash 检测 = close 事件;行帧 fatal = 封读+树杀) ──
|
|
41
|
+
let downReason;
|
|
42
|
+
const downCallbacks = [];
|
|
43
|
+
let exitInfo;
|
|
44
|
+
const exitWaiters = [];
|
|
45
|
+
let closePromise;
|
|
46
|
+
let connection;
|
|
47
|
+
const markDown = (reason) => {
|
|
48
|
+
if (downReason !== undefined)
|
|
49
|
+
return; // 一次结算(crash 与 fatal 双源竞速同封)
|
|
50
|
+
downReason = reason;
|
|
51
|
+
for (const cb of [...downCallbacks])
|
|
52
|
+
cb(reason);
|
|
53
|
+
for (const w of [...exitWaiters])
|
|
54
|
+
w();
|
|
55
|
+
exitWaiters.length = 0;
|
|
56
|
+
};
|
|
57
|
+
child.onExit((info) => {
|
|
58
|
+
exitInfo = info;
|
|
59
|
+
connection?.failAll(new BaseError('MCP_CONNECT_FAILED', info.spawnError !== undefined
|
|
60
|
+
? `spawn 失败(${server}):${info.spawnError.message}`
|
|
61
|
+
: `server 退出(${server},code=${info.code})`));
|
|
62
|
+
markDown(info.spawnError !== undefined ? `spawn 失败:${info.spawnError.message}` : `server 退出(code=${info.code})`);
|
|
63
|
+
});
|
|
64
|
+
connection = new JsonRpcConnection({
|
|
65
|
+
send: (line) => child.stdin.write(`${line}\n`),
|
|
66
|
+
lineLimitBytes: MCP_LINE_LIMIT_BYTES,
|
|
67
|
+
warn: (message) => logger.warn(message),
|
|
68
|
+
onFatal: () => {
|
|
69
|
+
// 载体级失败收场:封读(静默巨行不进宿主堆)+ 树杀 server(不杀即永久孤儿)
|
|
70
|
+
child.stdout.destroy();
|
|
71
|
+
child.kill();
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
child.stdout.on('data', (chunk) => connection?.feed(chunk));
|
|
75
|
+
child.stderr.on('data', (chunk) => {
|
|
76
|
+
for (const line of chunk.toString('utf8').split('\n')) {
|
|
77
|
+
if (line.trim() !== '')
|
|
78
|
+
logger.debug(`[mcp:${server}] ${line}`);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
try {
|
|
82
|
+
// ── initialize 握手(startup 预算罩全程;服务器回显异版本不拒——v1 不挑) ──
|
|
83
|
+
await connection.request('initialize', {
|
|
84
|
+
protocolVersion: MCP_PROTOCOL_VERSION,
|
|
85
|
+
capabilities: {},
|
|
86
|
+
clientInfo: { name: 'berry-agent', version: deps.clientVersion ?? '0.1.0' },
|
|
87
|
+
}, startupMs);
|
|
88
|
+
connection.notify('notifications/initialized');
|
|
89
|
+
// ── tools/list 分页跟尽(nextCursor 不跟即静默丢工具——03 §10.1 明律) ──
|
|
90
|
+
const tools = [];
|
|
91
|
+
let cursor;
|
|
92
|
+
do {
|
|
93
|
+
const page = (await connection.request('tools/list', cursor !== undefined ? { cursor } : undefined, startupMs));
|
|
94
|
+
if (page !== null && typeof page === 'object' && Array.isArray(page.tools)) {
|
|
95
|
+
for (const raw of page.tools) {
|
|
96
|
+
const tool = normalizeTool(raw);
|
|
97
|
+
if (tool !== undefined)
|
|
98
|
+
tools.push(tool);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
cursor = typeof page?.nextCursor === 'string' ? page.nextCursor : undefined;
|
|
102
|
+
} while (cursor !== undefined);
|
|
103
|
+
if (downReason !== undefined) {
|
|
104
|
+
// 发现途中已死(竞速护栏——close 与末页响应近同时到)
|
|
105
|
+
throw new BaseError('MCP_CONNECT_FAILED', `server 退出(${server}):${downReason}`);
|
|
106
|
+
}
|
|
107
|
+
const bridge = {
|
|
108
|
+
server,
|
|
109
|
+
tools,
|
|
110
|
+
toolTimeoutMs,
|
|
111
|
+
call: (tool, args) => callTool(connection, server, tool, args, toolTimeoutMs, () => downReason),
|
|
112
|
+
onDown(callback) {
|
|
113
|
+
if (downReason !== undefined)
|
|
114
|
+
callback(downReason); // 迟到订阅即回调
|
|
115
|
+
else
|
|
116
|
+
downCallbacks.push(callback);
|
|
117
|
+
},
|
|
118
|
+
close: () => {
|
|
119
|
+
if (closePromise === undefined) {
|
|
120
|
+
closePromise = closeChild(child, graceMs, () => exitInfo, (waiter) => exitWaiters.push(waiter));
|
|
121
|
+
}
|
|
122
|
+
return closePromise; // 幂等——二次 close 复用首次结算
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
return bridge;
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
// 连接期失败收场:结清 pending + 树杀(不留孤儿)→ 分类抛出
|
|
129
|
+
connection.failAll(err instanceof BaseError ? err : new BaseError('MCP_CONNECT_FAILED', `连接失败(${server}):${errText(err)}`));
|
|
130
|
+
child.kill();
|
|
131
|
+
if (err instanceof BaseError && err.code === 'MCP_CONNECT_FAILED')
|
|
132
|
+
throw err;
|
|
133
|
+
if (err instanceof Error && err.message.includes('超时')) {
|
|
134
|
+
throw new BaseError('MCP_CONNECT_FAILED', `initialize 握手超时(${server},预算 ${startupMs}ms)`, {
|
|
135
|
+
cause: err,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
throw new BaseError('MCP_CONNECT_FAILED', `连接失败(${server}):${errText(err)}`, { cause: asError(err) });
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/** tools/call 执行体(一切失败折 isError 结果——数据面不改抛出面) */
|
|
142
|
+
function callTool(connection, server, tool, args, timeoutMs, downOf) {
|
|
143
|
+
const down = downOf();
|
|
144
|
+
if (connection === undefined || down !== undefined) {
|
|
145
|
+
return Promise.resolve({
|
|
146
|
+
content: [{ type: 'text', text: `MCP 服务器 ${server} 已断开(${down ?? '未知原因'})——/reload 复位` }],
|
|
147
|
+
isError: true,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
return connection
|
|
151
|
+
.request('tools/call', { name: tool, arguments: args }, timeoutMs)
|
|
152
|
+
.then((result) => mapToolResult(result))
|
|
153
|
+
.catch((err) => ({
|
|
154
|
+
content: [{ type: 'text', text: `MCP 工具调用失败(${server}__${tool}):${errText(err)}` }],
|
|
155
|
+
isError: true,
|
|
156
|
+
}));
|
|
157
|
+
}
|
|
158
|
+
/** tools/call 响应映射(text/image 直映射;其余形折 JSON 文本——不丢内容) */
|
|
159
|
+
function mapToolResult(result) {
|
|
160
|
+
const r = (result ?? {});
|
|
161
|
+
const content = [];
|
|
162
|
+
if (Array.isArray(r.content)) {
|
|
163
|
+
for (const item of r.content) {
|
|
164
|
+
if (typeof item !== 'object' || item === null)
|
|
165
|
+
continue;
|
|
166
|
+
const c = item;
|
|
167
|
+
if (c.type === 'text' && typeof c.text === 'string') {
|
|
168
|
+
content.push({ type: 'text', text: c.text });
|
|
169
|
+
}
|
|
170
|
+
else if (c.type === 'image' && typeof c.data === 'string' && typeof c.mimeType === 'string') {
|
|
171
|
+
content.push({ type: 'image', data: c.data, mimeType: c.mimeType });
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
content.push({ type: 'text', text: JSON.stringify(item) });
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return { content, isError: r.isError === true || undefined };
|
|
179
|
+
}
|
|
180
|
+
/** 协议化关停编舞(备忘录归调用侧):stdin.end 告别 → 宽限 → 树杀兜底 */
|
|
181
|
+
function closeChild(child, graceMs, exitOf, addWaiter) {
|
|
182
|
+
return (async () => {
|
|
183
|
+
try {
|
|
184
|
+
child.stdin.end(); // 协议化告别(stdin 关 = stdio server 的关停信号)
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
// stdin 已坏(服务器先死)——宽限/树杀照走
|
|
188
|
+
}
|
|
189
|
+
const exited = await new Promise((resolve) => {
|
|
190
|
+
if (exitOf() !== undefined) {
|
|
191
|
+
resolve(true);
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
const timer = setTimeout(() => resolve(false), graceMs);
|
|
195
|
+
addWaiter(() => {
|
|
196
|
+
clearTimeout(timer);
|
|
197
|
+
resolve(true);
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
if (!exited)
|
|
201
|
+
child.kill(); // 宽限尽——树杀兜底(防挂死 server 永久孤儿)
|
|
202
|
+
})();
|
|
203
|
+
}
|
|
204
|
+
/** tools/list 条目归一(name 非 string 弃;inputSchema 缺席容错空 object) */
|
|
205
|
+
function normalizeTool(raw) {
|
|
206
|
+
if (typeof raw !== 'object' || raw === null)
|
|
207
|
+
return undefined;
|
|
208
|
+
const t = raw;
|
|
209
|
+
if (typeof t.name !== 'string' || t.name === '')
|
|
210
|
+
return undefined;
|
|
211
|
+
return {
|
|
212
|
+
name: t.name,
|
|
213
|
+
...(typeof t.description === 'string' ? { description: t.description } : {}),
|
|
214
|
+
inputSchema: typeof t.inputSchema === 'object' && t.inputSchema !== null ? t.inputSchema : { type: 'object' },
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
function errText(err) {
|
|
218
|
+
return err instanceof Error ? err.message : String(err);
|
|
219
|
+
}
|
|
220
|
+
function asError(err) {
|
|
221
|
+
return err instanceof Error ? err : new Error(String(err));
|
|
222
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mcp 桥域错误码注册(03 §10.1——MCP_ 前缀族首批)。
|
|
3
|
+
*
|
|
4
|
+
* 前缀族明列见 contracts/errors.ts ERROR_CODE_PREFIXES(02 §5.3 #1);码名清
|
|
5
|
+
* 单与语义真源 = 03 篇 §10.1 连接语义/行帧卫生条 MCP_ 两码。本文件由模块公
|
|
6
|
+
* 开面 index.ts 引入(注册纪律:写入点文件必须实际 import 本文件注册才发
|
|
7
|
+
* 生——与 issue/scheduler 先例同款)。
|
|
8
|
+
*/
|
|
9
|
+
import { registerErrorCodes } from '../contracts/index.js';
|
|
10
|
+
registerErrorCodes([
|
|
11
|
+
{
|
|
12
|
+
code: 'MCP_CONNECT_FAILED',
|
|
13
|
+
module: 'mcp',
|
|
14
|
+
description: '单服务器连接失败降级(spawn 失败 / initialize 握手超时 / 运行期 crash / 行帧坏或 stdout 单行超 8MiB 帽的载体级失败——不阻同行其余、撤工具 + ui.notify warn、不自动重连)',
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
code: 'MCP_CONFIG_INVALID',
|
|
18
|
+
module: 'mcp',
|
|
19
|
+
description: 'config.servers 行载荷坏(键词法违例 / command 非绝对路径 / 字段类型坏形——响亮拒不静默吞)',
|
|
20
|
+
},
|
|
21
|
+
]);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* core:mcp 公开面(02 §4.1 席 deps {contracts, context}——stdio 行帧
|
|
3
|
+
* JSON-RPC 手写最小桥,03 §10.1)。
|
|
4
|
+
*
|
|
5
|
+
* 装载态集成归批 12 装载面后装配批:core:mcp 插件装载时组服务(spawn 窄面
|
|
6
|
+
* 注入 exec 管道真身、registry 窄面注入 tools 注册表真身、scope = ctx 作
|
|
7
|
+
* 用域、notify 接 ui.notify warn 面)→ config.servers 归一 → apply 异步发现
|
|
8
|
+
* → 注册进全局层。
|
|
9
|
+
*/
|
|
10
|
+
import './codes.js';
|
|
11
|
+
export { MCP_SERVER_NAME_RE, MCP_STARTUP_TIMEOUT_SEC_DEFAULT, MCP_TOOL_TIMEOUT_SEC_DEFAULT, MCP_LINE_LIMIT_BYTES, MCP_NATIVE_TOOL_LIMIT, MCP_CLOSE_GRACE_MS, MCP_PROTOCOL_VERSION, normalizeMcpConfig, } from './types.js';
|
|
12
|
+
// 行帧 JSON-RPC 协议腿
|
|
13
|
+
export { LineDecoder, JsonRpcConnection, JsonRpcError } from './jsonrpc.js';
|
|
14
|
+
// 服务器桥
|
|
15
|
+
export { connectMcpServer } from './bridge.js';
|
|
16
|
+
// 工具注册面
|
|
17
|
+
export { MCP_DIRECTORY_TOOL_NAME, mcpToolKey, splitMcpToolKey, filterServerTools, buildMcpToolDefs } from './tools.js';
|
|
18
|
+
// 服务编排
|
|
19
|
+
export { createMcpService } from './service.js';
|