draftgo-cli 3.0.53 → 3.0.55
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/README.md +4 -0
- package/package.json +1 -1
- package/resources/skill/SKILL.md +5 -3
- package/resources/skill/manifest.json +1 -1
- package/resources/skill/references/checkout.md +2 -0
- package/resources/skill/references/frontend.md +13 -3
- package/resources/skill/references/mcp.md +3 -1
- package/resources/skill/references/modules.md +1 -1
- package/src/mcp/client.js +131 -2
package/README.md
CHANGED
|
@@ -55,6 +55,8 @@ DraftGo Skill 不能被 MCP 替代。根 `SKILL.md` 会在 Skill 触发时自动
|
|
|
55
55
|
|
|
56
56
|
页面任务读取 `frontend.md`,按需补读 `runtime.md` / `app-api.md`;数据、自定义服务和 AIHub 任务分别读取对应 Reference。目标明确时不要全量枚举无关资源。`mcp test` 是连接诊断,不是每次资源查询的前置步骤。
|
|
57
57
|
|
|
58
|
+
页面需求先结合用户意图和 MCP 实时资源判断是修改已有页面还是新增页面。已有页面在确认唯一 ID 后 checkout;独立新页面先通过实时 API 创建并取得 ID,再 checkout 完整正文。“做一个功能页面”本身不预设新建或修改,只有不同判断会产生明显不同结果时才需要向用户澄清。
|
|
59
|
+
|
|
58
60
|
只回答无需实时状态的本地规则问题时,不必调用 MCP。静态资源须先区分:平台内置目录由 `frontend.md` 说明,指定页面依赖经 MCP 定位、checkout 后本地搜索,服务器全量文件不能凭现有 Skill、MCP 摘要或 checkout 声称已枚举。
|
|
59
61
|
|
|
60
62
|
Skill 说明产品约束、内置能力和操作规则;MCP 说明当前远端状态;checkout 正文才能证明某个页面完整引用了哪些静态资源。汇报时应明确标注这三类证据,不能互相替代。
|
|
@@ -101,6 +103,8 @@ draftgo mcp test # 验证 initialize、tools/list、项目/正文
|
|
|
101
103
|
draftgo mcp serve # 启动 stdio -> 远端 Streamable HTTP bridge
|
|
102
104
|
```
|
|
103
105
|
|
|
106
|
+
`mcp serve` 会保留远端 `Mcp-Session-Id`。服务重启或 session 过期后,它会自动重新 initialize,并只重试一次被明确拒绝为 session 无效的当前请求;普通工具失败、超时和 5xx 不会自动重试。`mcp test` 使用独立的新连接,只证明当前配置能够建立新 session,不能直接证明宿主此前持有的 session 仍有效。
|
|
107
|
+
|
|
104
108
|
`setup` 不传 target 时自动检测当前项目的宿主。可用 `--target codex,cursor` 传入多个目标。
|
|
105
109
|
|
|
106
110
|
当前 MCP 宿主支持:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "draftgo-cli",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.55",
|
|
4
4
|
"description": "Install and manage the DraftGo skill across AI coding agents (Claude Code, Codex, Cursor, Windsurf, Antigravity, Copilot, Gemini, Kiro).",
|
|
5
5
|
"bin": {
|
|
6
6
|
"draftgo": "bin/draftgo.js"
|
package/resources/skill/SKILL.md
CHANGED
|
@@ -29,7 +29,7 @@ description: Use this skill to inspect, develop, debug, or deliver a DraftGo app
|
|
|
29
29
|
|
|
30
30
|
| 任务 | 专题资料与后续动作 |
|
|
31
31
|
|---|---|
|
|
32
|
-
| 页面、导航、交互或 UI | `references/frontend.md`;涉及 iframe、路由、认证或全局层加读 `runtime.md` / `app-api.md
|
|
32
|
+
| 页面、导航、交互或 UI | `references/frontend.md`;涉及 iframe、路由、认证或全局层加读 `runtime.md` / `app-api.md`;先结合需求与 MCP 资源判断新增或修改,已有资源按需 checkout |
|
|
33
33
|
| 动态 DB、筛选或关系 | `references/data.md`;需要关系完整示例时读 `db-relations.md`;API 调用遵循 `mcp.md` |
|
|
34
34
|
| AIHub、聊天或图片 | `references/aihub.md`、`references/chat-sdk.md`;资产与 operation 以 MCP 为准 |
|
|
35
35
|
| 自定义服务、权限、外部调用 | `references/custom-services.md`;管理和动态 Route operation 以 MCP 为准 |
|
|
@@ -39,6 +39,8 @@ description: Use this skill to inspect, develop, debug, or deliver a DraftGo app
|
|
|
39
39
|
|
|
40
40
|
不要用 MCP 摘要代替完整正文,也不要把 Skill 列出的 `/assets/` 能力声称为当前服务器全部文件。业务归属、系统资源或页面类型没有明确元数据时报告证据不足,不凭标题、路径或片段猜测。
|
|
41
41
|
|
|
42
|
+
页面需求不因出现“页面”二字就默认新建或 checkout。Agent 结合用户意图、现有 route、页面职责和入口自主判断:修改已有页面时定位唯一资源后 checkout;确需独立新页面时先通过 MCP 实时 API 创建并取得 ID,再 checkout 正文。证据足以判断时直接推进;多个候选会导致不同产品结果时再向用户澄清。
|
|
43
|
+
|
|
42
44
|
## 所有权与执行
|
|
43
45
|
|
|
44
46
|
- 同一文件或 DraftGo 资源全程只能由一个 Agent 修改;其他 Agent 只读分析并回传建议。
|
|
@@ -51,8 +53,8 @@ description: Use this skill to inspect, develop, debug, or deliver a DraftGo app
|
|
|
51
53
|
|
|
52
54
|
### 长正文
|
|
53
55
|
|
|
54
|
-
1.
|
|
55
|
-
2.
|
|
56
|
+
1. 确认目标 pages/nav/docs 已存在并通过 MCP 读取 metadata;新增资源先按实时 API 契约创建并取得 ID。
|
|
57
|
+
2. 对需要完整分析或编辑的目标批量 checkout;在 `.draftgo/worktree/` 按唯一 owner 编辑。
|
|
56
58
|
3. 主 Agent 回读全部修改,编辑过程中统一运行一次快速 `draftgo check`。交付前运行 `draftgo verify <type> <id...>`;需要远端证据时加 `--remote`,页面布局或交互变化时加对应 `--url`。
|
|
57
59
|
4. 用 `draftgo diff <type> <id>` 检查 base/local 差异,再按类型运行 `draftgo commit ...`。commit 后需要验证远端页面时运行 `draftgo verify <type> <id> --remote --url <url>`。
|
|
58
60
|
5. 409/412 时停止自动提交,保留 base/local/remote 冲突材料;不得 force、覆盖或自动合并。
|
|
@@ -24,6 +24,8 @@ The checkout set includes `pages`, `navigations`, `docs/articles`, and `custom_s
|
|
|
24
24
|
|
|
25
25
|
db_meta、AIHub、system_config、roles、users、doc_categories 和普通配置使用 MCP 实时 API,不 checkout。
|
|
26
26
|
|
|
27
|
+
Checkout 只为已存在且已确认 ID 的资源建立本地正文与 base,不创建页面、导航或文档。新增资源先按 MCP 实时 API 契约创建并取得 ID;需要编辑完整正文时再 checkout。只需元数据或正文片段即可完成判断时,不必 checkout。
|
|
28
|
+
|
|
27
29
|
## 命令
|
|
28
30
|
|
|
29
31
|
```bash
|
|
@@ -79,12 +79,22 @@ version: 2.0.0
|
|
|
79
79
|
- 系统内置页面通常不改;确需修改登录、设置、权限、用户、系统配置等页面时,先说明影响、验证方式和保留的管理员能力。
|
|
80
80
|
- 页面风格不要照搬管理侧内置页面;业务前台按业务用户和品牌语境设计,管理侧按操作效率和信息密度设计。
|
|
81
81
|
|
|
82
|
-
###
|
|
82
|
+
### 页面身份与创建
|
|
83
|
+
|
|
84
|
+
业务新页面默认是数据库中的完整 HTML 页面。开始正文工作前,结合用户表达与 MCP 中的标题、route、用途和入口判断目标:
|
|
85
|
+
|
|
86
|
+
- 用户指定页面、ID、已有 route,或现有页面与需求职责明确一致时,按已有页面修改并 checkout 对应 ID。
|
|
87
|
+
- 用户明确要求新增,或需求需要独立 route/职责且定向搜索后没有合适页面时,按新页面处理。通过 `draftgo_api_search` → `draftgo_api_describe` → `draftgo_api_call` 使用实时创建契约,取得新页面 ID 后再 checkout;完整 HTML 仍只走 checkout/commit。
|
|
88
|
+
- “做一个功能页面”本身不等于新增,也不等于修改。证据足以形成唯一合理方案时 Agent 直接推进;若多个已有候选或新增/修改会产生明显不同的产品结果,再用一个简短问题澄清。
|
|
89
|
+
|
|
90
|
+
搜索用于确认页面身份和避免重复,按标题、route 或业务用途逐步缩小范围即可,无需枚举无关资源。Checkout 应对应已确认的目标资源;新资源先创建并取得 ID。
|
|
91
|
+
|
|
92
|
+
### 新增页面入口
|
|
83
93
|
|
|
84
94
|
- 公开页 → 顶部/侧边导航、首页入口、相关按钮之一
|
|
85
95
|
- 后台页 → 后台导航、管理菜单或现有后台入口
|
|
86
96
|
- 多页面功能:列表/详情/新建/编辑/管理必须互相走通
|
|
87
|
-
-
|
|
97
|
+
- 隐藏页、回调页、按链接直达的详情页或草稿页可按产品目的不绑定全局入口;需要入口时优先接入现有导航或业务流程
|
|
88
98
|
|
|
89
99
|
### `page_1_root.html` 首页特例(强制)
|
|
90
100
|
|
|
@@ -138,7 +148,7 @@ version: 2.0.0
|
|
|
138
148
|
- **壳层前端**位于 DraftGo 基座的 `frontend/`,技术栈为 React 19 + Vite 8 + Tailwind CSS 4;这是维护壳层代码时使用的构建链路。
|
|
139
149
|
- **业务页面和导航 HTML**存储在数据库资源中,由壳层以 iframe 运行。它们必须是完整的原生 HTML 文档,不能写入 TSX、ESM import、npm 依赖或 Vite 构建产物。
|
|
140
150
|
- 数据库页面需要 React 时,只能使用下方内置的 React 18 UMD 资源和 `window.React` / `window.ReactDOM`。不要把壳层的 React 19 npm 依赖、外部 CDN 或其他 React 版本混入页面。
|
|
141
|
-
-
|
|
151
|
+
- 只有用户明确要求修改 DraftGo 壳层前端时,才处理 `frontend/` 源码。
|
|
142
152
|
|
|
143
153
|
### 内置组件库清单
|
|
144
154
|
|
|
@@ -84,7 +84,9 @@ draftgo mcp serve
|
|
|
84
84
|
- `setup` 写入项目级宿主配置,只替换 `draftgo` MCP 条目并保留其他配置。
|
|
85
85
|
- `status` 检查配置是否存在、格式是否有效,以及是否误写了凭据或远端 URL。
|
|
86
86
|
- `test` 从 `.draftgo/config.json` 读取连接,验证 initialize、tools/list、三类正文 resource_list,以及 db_meta 的 api_search、api_describe 和只读 api_call。
|
|
87
|
-
- `serve` 启动 stdio bridge,把宿主请求代理到当前项目配置的远端 Streamable HTTP `/mcp
|
|
87
|
+
- `serve` 启动 stdio bridge,把宿主请求代理到当前项目配置的远端 Streamable HTTP `/mcp`。远端重启或 session 过期后,bridge 会清除旧 `Mcp-Session-Id`、重新 initialize,并对被明确拒绝为 session 无效的当前请求重试一次;普通超时、服务端错误和工具错误不会自动重试。
|
|
88
|
+
|
|
89
|
+
`draftgo mcp test` 每次使用独立的新连接,因此它证明当前 server、SAT 和协议可以建立新 session,不代表宿主已持有的旧 session 仍然有效。宿主工具报告 session 失效但 `mcp test` 成功时,bridge 应自动恢复;若恢复仍失败,再检查远端日志、代理头传递和服务可用性。
|
|
88
90
|
|
|
89
91
|
`draftgo connect` 保存并验证 server/SAT、探测 `/mcp` 和关键工具,并可提示宿主 setup;`--server` 表示基础地址,完整 MCP endpoint 使用 `--mcp-url` 显式传入。它不下载业务资源,
|
|
90
92
|
也不创建 pages、navigation、docs、db_meta 等本地镜像。底座仍在开发或暂不可达时,报告诊断结果即可,
|
|
@@ -8,7 +8,7 @@ read_when: 评估功能可行性时 · 选择开发路径时 · 进入新项目
|
|
|
8
8
|
|
|
9
9
|
| 模块 | 开发方式 | 入口 |
|
|
10
10
|
|---|---|---|
|
|
11
|
-
| 页面 | 数据库 HTML(`page.value.html`) | MCP
|
|
11
|
+
| 页面 | 数据库 HTML(`page.value.html`) | 已有页面由 MCP 定位后 `checkout pages` / `commit pages`;新页面先按实时 API 契约创建并取得 ID |
|
|
12
12
|
| 导航栏 | 数据库 HTML(`navigation.html`) | MCP 定位,`checkout nav` / `commit nav` 编辑正文 |
|
|
13
13
|
| 动态 DB | db_meta 定义 schema 并操作结构化记录 | MCP `api_search` / `api_describe` / `api_call` |
|
|
14
14
|
| 自定义服务 | Go `Register` 服务,支持 route/event/scheduled 混合注册 | MCP 实时 API;不创建本地镜像 |
|
package/src/mcp/client.js
CHANGED
|
@@ -65,6 +65,44 @@ class McpRpcError extends Error {
|
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
const SESSION_INVALID_CODES = new Set([
|
|
69
|
+
-32002,
|
|
70
|
+
'SESSION_EXPIRED',
|
|
71
|
+
'SESSION_NOT_FOUND',
|
|
72
|
+
'MCP_SESSION_EXPIRED',
|
|
73
|
+
'MCP_SESSION_NOT_FOUND',
|
|
74
|
+
]);
|
|
75
|
+
|
|
76
|
+
function isSessionInvalidError(error) {
|
|
77
|
+
if (!error) return false;
|
|
78
|
+
if (Number(error.status) === 404) return true;
|
|
79
|
+
const code = error.code != null
|
|
80
|
+
? error.code
|
|
81
|
+
: error.rpc && error.rpc.error && error.rpc.error.code;
|
|
82
|
+
if (SESSION_INVALID_CODES.has(code)) return true;
|
|
83
|
+
const message = String(error.message
|
|
84
|
+
|| error.rpc && error.rpc.error && error.rpc.error.message
|
|
85
|
+
|| '');
|
|
86
|
+
return /\b(?:mcp\s+)?session(?:\s+id)?\s+(?:was\s+)?(?:not\s+found|expired|invalid|unknown|lost)\b/i.test(message)
|
|
87
|
+
|| /\b(?:server|mcp)\s+(?:is\s+)?(?:not initialized|uninitialized)\b/i.test(message)
|
|
88
|
+
|| /\binitialize first\b/i.test(message);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function requestIdKeys(message) {
|
|
92
|
+
const messages = Array.isArray(message) ? message : [message];
|
|
93
|
+
return new Set(messages
|
|
94
|
+
.filter((item) => isObject(item) && typeof item.method === 'string' && item.id != null)
|
|
95
|
+
.map((item) => `${typeof item.id}:${JSON.stringify(item.id)}`));
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function sessionInvalidResponse(message, expectedIds) {
|
|
99
|
+
const messages = Array.isArray(message) ? message : [message];
|
|
100
|
+
return messages.find((item) => isObject(item)
|
|
101
|
+
&& item.error
|
|
102
|
+
&& expectedIds.has(`${typeof item.id}:${JSON.stringify(item.id)}`)
|
|
103
|
+
&& isSessionInvalidError(item.error)) || null;
|
|
104
|
+
}
|
|
105
|
+
|
|
68
106
|
function diagnosticNextCursor(result) {
|
|
69
107
|
const value = diagnosticData(result);
|
|
70
108
|
if (!value || typeof value !== 'object' || Array.isArray(value)) return null;
|
|
@@ -154,6 +192,9 @@ class DraftGoMcpClient {
|
|
|
154
192
|
this.sessionId = null;
|
|
155
193
|
this.protocolVersion = options.protocolVersion || DEFAULT_PROTOCOL_VERSION;
|
|
156
194
|
this.nextId = 1;
|
|
195
|
+
this.sessionGeneration = 0;
|
|
196
|
+
this.sessionRecovery = null;
|
|
197
|
+
this.sessionRecoveryCount = 0;
|
|
157
198
|
this.onMessage = typeof options.onMessage === 'function' ? options.onMessage : null;
|
|
158
199
|
}
|
|
159
200
|
|
|
@@ -163,28 +204,65 @@ class DraftGoMcpClient {
|
|
|
163
204
|
}
|
|
164
205
|
|
|
165
206
|
const initialize = findInitializeRequest(message);
|
|
207
|
+
const internalRecovery = options._sessionRecoveryInternal === true;
|
|
208
|
+
if (!initialize && !internalRecovery && this.sessionRecovery) {
|
|
209
|
+
await this.sessionRecovery;
|
|
210
|
+
}
|
|
211
|
+
if (initialize) this.sessionId = null;
|
|
166
212
|
const requestedVersion = initialize
|
|
167
213
|
&& initialize.params
|
|
168
214
|
&& initialize.params.protocolVersion;
|
|
169
215
|
const delivered = [];
|
|
216
|
+
const expectedIds = requestIdKeys(message);
|
|
217
|
+
const attemptedSessionId = initialize ? null : this.sessionId;
|
|
218
|
+
const attemptedGeneration = this.sessionGeneration;
|
|
219
|
+
const canRecover = !initialize
|
|
220
|
+
&& !internalRecovery
|
|
221
|
+
&& options._sessionRecoveryAttempted !== true
|
|
222
|
+
&& attemptedSessionId != null;
|
|
223
|
+
let suppressedSessionError = null;
|
|
170
224
|
|
|
171
225
|
try {
|
|
172
226
|
await postJsonRpc(this.config, message, {
|
|
173
227
|
signal: options.signal,
|
|
174
228
|
timeoutMs: options.timeoutMs,
|
|
175
|
-
sessionId:
|
|
229
|
+
sessionId: attemptedSessionId,
|
|
176
230
|
protocolVersion: requestedVersion || this.protocolVersion,
|
|
177
|
-
onSession: (sessionId) => {
|
|
231
|
+
onSession: (sessionId) => {
|
|
232
|
+
if (initialize || (this.sessionGeneration === attemptedGeneration
|
|
233
|
+
&& this.sessionId === attemptedSessionId)) {
|
|
234
|
+
this.sessionId = sessionId;
|
|
235
|
+
}
|
|
236
|
+
},
|
|
178
237
|
onMessage: (remoteMessage) => {
|
|
179
238
|
const safe = redactValue(remoteMessage, this.secrets);
|
|
180
239
|
delivered.push(safe);
|
|
240
|
+
const invalid = canRecover && sessionInvalidResponse(safe, expectedIds);
|
|
241
|
+
if (invalid) {
|
|
242
|
+
suppressedSessionError = invalid;
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
if (options._suppressCallbacks === true) return;
|
|
181
246
|
if (this.onMessage) this.onMessage(safe);
|
|
182
247
|
if (typeof options.onMessage === 'function') options.onMessage(safe);
|
|
183
248
|
},
|
|
184
249
|
});
|
|
250
|
+
if (suppressedSessionError) {
|
|
251
|
+
const remoteError = suppressedSessionError.error;
|
|
252
|
+
const error = new McpRpcError(
|
|
253
|
+
remoteError.message || `MCP error ${remoteError.code}`,
|
|
254
|
+
{ code: remoteError.code, data: remoteError.data, id: suppressedSessionError.id },
|
|
255
|
+
);
|
|
256
|
+
error.rpc = suppressedSessionError;
|
|
257
|
+
throw error;
|
|
258
|
+
}
|
|
185
259
|
} catch (error) {
|
|
186
260
|
if (error && error.rpc) error.rpc = redactValue(error.rpc, this.secrets);
|
|
187
261
|
if (error && error.message) error.message = redactText(error.message, this.secrets);
|
|
262
|
+
if (canRecover && isSessionInvalidError(error)) {
|
|
263
|
+
await this.recoverSession(attemptedSessionId, attemptedGeneration, options);
|
|
264
|
+
return this.forward(message, { ...options, _sessionRecoveryAttempted: true });
|
|
265
|
+
}
|
|
188
266
|
throw error;
|
|
189
267
|
}
|
|
190
268
|
|
|
@@ -196,6 +274,54 @@ class DraftGoMcpClient {
|
|
|
196
274
|
return delivered;
|
|
197
275
|
}
|
|
198
276
|
|
|
277
|
+
async recoverSession(failedSessionId, failedGeneration, options = {}) {
|
|
278
|
+
if (this.sessionGeneration !== failedGeneration) return;
|
|
279
|
+
if (this.sessionId != null && this.sessionId !== failedSessionId) return;
|
|
280
|
+
if (this.sessionRecovery) return this.sessionRecovery;
|
|
281
|
+
|
|
282
|
+
const recoveryNumber = this.sessionRecoveryCount + 1;
|
|
283
|
+
this.sessionId = null;
|
|
284
|
+
const recovery = (async () => {
|
|
285
|
+
if (typeof options.onSessionRecovery === 'function') {
|
|
286
|
+
options.onSessionRecovery('started', { attempt: recoveryNumber });
|
|
287
|
+
}
|
|
288
|
+
try {
|
|
289
|
+
await this.initialize({
|
|
290
|
+
id: `draftgo-session-recovery-${recoveryNumber}`,
|
|
291
|
+
protocolVersion: this.protocolVersion,
|
|
292
|
+
timeoutMs: options.timeoutMs,
|
|
293
|
+
signal: options.signal,
|
|
294
|
+
_sessionRecoveryInternal: true,
|
|
295
|
+
_suppressCallbacks: true,
|
|
296
|
+
});
|
|
297
|
+
this.sessionRecoveryCount = recoveryNumber;
|
|
298
|
+
if (typeof options.onSessionRecovery === 'function') {
|
|
299
|
+
options.onSessionRecovery('succeeded', { attempt: recoveryNumber });
|
|
300
|
+
}
|
|
301
|
+
} catch (error) {
|
|
302
|
+
this.sessionId = null;
|
|
303
|
+
if (typeof options.onSessionRecovery === 'function') {
|
|
304
|
+
options.onSessionRecovery('failed', { attempt: recoveryNumber });
|
|
305
|
+
}
|
|
306
|
+
const message = redactText(error && error.message ? error.message : error, this.secrets);
|
|
307
|
+
const wrapped = new McpRpcError(`DraftGo MCP session recovery failed: ${message}`, {
|
|
308
|
+
code: error && error.code != null ? error.code : -32000,
|
|
309
|
+
data: error && error.data,
|
|
310
|
+
});
|
|
311
|
+
wrapped.status = Number(error && error.status) || 0;
|
|
312
|
+
wrapped.sessionRecovery = true;
|
|
313
|
+
wrapped.cause = error;
|
|
314
|
+
throw wrapped;
|
|
315
|
+
}
|
|
316
|
+
})();
|
|
317
|
+
this.sessionRecovery = recovery;
|
|
318
|
+
try {
|
|
319
|
+
await recovery;
|
|
320
|
+
} finally {
|
|
321
|
+
if (this.sessionRecovery === recovery) this.sessionRecovery = null;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
199
325
|
async request(method, params, options = {}) {
|
|
200
326
|
const id = options.id == null ? this.nextId++ : options.id;
|
|
201
327
|
const message = { jsonrpc: '2.0', id, method };
|
|
@@ -249,6 +375,7 @@ class DraftGoMcpClient {
|
|
|
249
375
|
throw error;
|
|
250
376
|
}
|
|
251
377
|
if (typeof options.onStage === 'function') options.onStage('initialized', 'succeeded');
|
|
378
|
+
this.sessionGeneration += 1;
|
|
252
379
|
return result;
|
|
253
380
|
}
|
|
254
381
|
|
|
@@ -425,6 +552,7 @@ class DraftGoMcpClient {
|
|
|
425
552
|
initialized,
|
|
426
553
|
protocolVersion: this.protocolVersion,
|
|
427
554
|
sessionId: this.sessionId,
|
|
555
|
+
sessionRecoveries: this.sessionRecoveryCount,
|
|
428
556
|
tools,
|
|
429
557
|
testedTool: tested[0].name,
|
|
430
558
|
toolResult: tested[0].result,
|
|
@@ -457,6 +585,7 @@ module.exports = {
|
|
|
457
585
|
diagnosticData,
|
|
458
586
|
diagnosticNextCursor,
|
|
459
587
|
findDBMetaListOperation,
|
|
588
|
+
isSessionInvalidError,
|
|
460
589
|
redactValue,
|
|
461
590
|
testConnection,
|
|
462
591
|
callTool,
|