mcp-probe-kit 3.0.16 → 3.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/README.md +601 -399
  2. package/build/index.js +13 -1
  3. package/build/lib/__tests__/memory-client.unit.test.d.ts +1 -0
  4. package/build/lib/__tests__/memory-client.unit.test.js +83 -0
  5. package/build/lib/__tests__/memory-config.unit.test.d.ts +1 -0
  6. package/build/lib/__tests__/memory-config.unit.test.js +33 -0
  7. package/build/lib/cursor-history-client.d.ts +54 -0
  8. package/build/lib/cursor-history-client.js +240 -0
  9. package/build/lib/gitnexus-bridge.js +6 -8
  10. package/build/lib/memory-client.d.ts +61 -0
  11. package/build/lib/memory-client.js +293 -0
  12. package/build/lib/memory-config.d.ts +14 -0
  13. package/build/lib/memory-config.js +31 -0
  14. package/build/lib/memory-orchestration.d.ts +26 -0
  15. package/build/lib/memory-orchestration.js +65 -0
  16. package/build/lib/project-detector.js +6 -4
  17. package/build/lib/workspace-root.d.ts +12 -0
  18. package/build/lib/workspace-root.js +153 -0
  19. package/build/resources/ui-ux-data/metadata.json +1 -1
  20. package/build/schemas/code-analysis-tools.d.ts +1 -1
  21. package/build/schemas/code-analysis-tools.js +1 -1
  22. package/build/schemas/index.d.ts +198 -4
  23. package/build/schemas/index.js +2 -0
  24. package/build/schemas/memory-tools.d.ts +191 -0
  25. package/build/schemas/memory-tools.js +106 -0
  26. package/build/schemas/orchestration-tools.d.ts +3 -3
  27. package/build/schemas/orchestration-tools.js +3 -3
  28. package/build/schemas/ui-ux-schemas.d.ts +8 -0
  29. package/build/schemas/ui-ux-schemas.js +4 -0
  30. package/build/tools/__tests__/cursor-history.unit.test.d.ts +1 -0
  31. package/build/tools/__tests__/cursor-history.unit.test.js +87 -0
  32. package/build/tools/__tests__/memorize_asset.unit.test.d.ts +1 -0
  33. package/build/tools/__tests__/memorize_asset.unit.test.js +68 -0
  34. package/build/tools/code_insight.d.ts +20 -0
  35. package/build/tools/code_insight.js +15 -0
  36. package/build/tools/cursor_list_conversations.d.ts +7 -0
  37. package/build/tools/cursor_list_conversations.js +35 -0
  38. package/build/tools/cursor_read_conversation.d.ts +7 -0
  39. package/build/tools/cursor_read_conversation.js +36 -0
  40. package/build/tools/cursor_search_conversations.d.ts +7 -0
  41. package/build/tools/cursor_search_conversations.js +36 -0
  42. package/build/tools/index.d.ts +6 -0
  43. package/build/tools/index.js +7 -0
  44. package/build/tools/init_project_context.d.ts +20 -1
  45. package/build/tools/init_project_context.js +114 -99
  46. package/build/tools/memorize_asset.d.ts +7 -0
  47. package/build/tools/memorize_asset.js +66 -0
  48. package/build/tools/read_memory_asset.d.ts +7 -0
  49. package/build/tools/read_memory_asset.js +26 -0
  50. package/build/tools/scan_and_extract_patterns.d.ts +27 -0
  51. package/build/tools/scan_and_extract_patterns.js +346 -0
  52. package/build/tools/start_bugfix.d.ts +20 -0
  53. package/build/tools/start_bugfix.js +97 -69
  54. package/build/tools/start_feature.d.ts +20 -0
  55. package/build/tools/start_feature.js +61 -31
  56. package/build/tools/start_onboard.d.ts +20 -0
  57. package/build/tools/start_onboard.js +15 -0
  58. package/build/tools/start_ui.d.ts +20 -0
  59. package/build/tools/start_ui.js +66 -32
  60. package/docs/data/tools.js +472 -373
  61. package/docs/i18n/all-tools/en.json +38 -5
  62. package/docs/i18n/all-tools/ja.json +14 -4
  63. package/docs/i18n/all-tools/ko.json +13 -3
  64. package/docs/i18n/all-tools/zh-CN.json +38 -5
  65. package/docs/i18n/en.json +48 -10
  66. package/docs/i18n/ja.json +47 -9
  67. package/docs/i18n/ko.json +47 -9
  68. package/docs/i18n/zh-CN.json +48 -10
  69. package/docs/pages/all-tools.html +515 -515
  70. package/docs/pages/examples.html +661 -661
  71. package/docs/pages/getting-started.html +673 -582
  72. package/docs/pages/migration.html +291 -291
  73. package/package.json +83 -82
  74. package/docs/debug-i18n.html +0 -163
@@ -2,6 +2,7 @@ import { parseArgs, getString } from "../utils/parseArgs.js";
2
2
  import { okStructured } from "../lib/response.js";
3
3
  import { renderOrchestrationHeader } from "../lib/orchestration-guidance.js";
4
4
  import { detectProjectType } from "../lib/project-detector.js";
5
+ import { resolveWorkspaceRoot, isLikelyProjectNamedRelativePath, buildProjectRootRetryHint } from "../lib/workspace-root.js";
5
6
  import * as fs from 'fs';
6
7
  import * as path from 'path';
7
8
  /**
@@ -138,21 +139,21 @@ function generateDevGuide(docs) {
138
139
  result += `\n### ${category}\n${items.join('\n')}\n`;
139
140
  }
140
141
  }
141
- result += `\n### 理解代码图谱
142
- - **代码图谱洞察**: [latest.md](./graph-insights/latest.md) - 需要快速理解模块依赖、调用链、影响面时优先查看
142
+ result += `\n### 理解代码图谱
143
+ - **代码图谱洞察**: [latest.md](./graph-insights/latest.md) - 需要快速理解模块依赖、调用链、影响面时优先查看
143
144
  `;
144
145
  return result || '\n### 开发指南\n查看上面的文档导航,根据需要选择对应的文档。\n';
145
146
  }
146
147
  /**
147
148
  * 生成项目上下文文档指导
148
149
  */
149
- async function generateProjectContext(docsDir, projectRoot = process.cwd()) {
150
+ async function generateProjectContext(docsDir, projectRoot) {
150
151
  try {
151
152
  // 检测项目类型
152
- const detection = detectProjectType(projectRoot);
153
- const projectInfo = getProjectInfo(projectRoot);
153
+ const resolvedRoot = resolveWorkspaceRoot(projectRoot);
154
+ const detection = detectProjectType(resolvedRoot);
155
+ const projectInfo = getProjectInfo(resolvedRoot);
154
156
  const docs = getDocumentList(detection.category);
155
- const resolvedRoot = path.resolve(projectRoot);
156
157
  const projectContextPath = toPosixPath(path.join(resolvedRoot, docsDir, 'project-context.md'));
157
158
  const projectContextExists = fs.existsSync(path.join(resolvedRoot, docsDir, 'project-context.md'));
158
159
  const graphDocsRoot = toPosixPath(path.join(resolvedRoot, docsDir, 'graph-insights'));
@@ -265,10 +266,10 @@ async function generateProjectContext(docsDir, projectRoot = process.cwd()) {
265
266
  projectContextExists,
266
267
  },
267
268
  };
268
- return okStructured(`${header}${guide}
269
-
270
- ## delegated plan
271
- ${renderPlanSteps(plan.steps)}
269
+ return okStructured(`${header}${guide}
270
+
271
+ ## delegated plan
272
+ ${renderPlanSteps(plan.steps)}
272
273
  `, structuredData, {
273
274
  schema: (await import("../schemas/output/project-tools.js")).ProjectContextSchema,
274
275
  });
@@ -284,59 +285,59 @@ ${renderPlanSteps(plan.steps)}
284
285
  function generateGuideText(detection, projectInfo, docs, docsDir, projectRoot, options) {
285
286
  const timestamp = new Date().toISOString();
286
287
  const projectContextExists = options?.projectContextExists === true;
287
- return `# 项目上下文文档生成指导
288
-
289
- ## 📊 项目信息
288
+ return `# 项目上下文文档生成指导
289
+
290
+ ## 📊 项目信息
290
291
 
291
292
  - **项目名称**: ${projectInfo.name}
292
293
  - **版本**: ${projectInfo.version}
293
294
  - **语言**: ${detection.language}
294
295
  - **框架**: ${detection.framework || '未检测到'}
295
296
  - **类型**: ${detection.category}
296
- - **置信度**: ${detection.confidence}%
297
-
298
- ## 🔎 当前状态
299
-
300
- - **project-context.md**: ${projectContextExists ? '已存在(将保留,不覆盖)' : '不存在(需要生成)'}
301
- - **图谱文档**: 需要确保 ${docsDir}/graph-insights/latest.md 与 latest.json 可用
302
-
303
- ## 📋 需要生成的文档
304
-
305
- 请按照以下结构生成 **${docs.length + 1}** 个上下文文档,并为图谱文档预留入口:
306
-
307
- \`\`\`
308
- ${docsDir}/
309
- ├── project-context.md # 索引文件(必须首先生成)
310
- └── project-context/ # 分类文档目录
311
- ${docs.map(doc => ` ├── ${doc.file.padEnd(28)} # ${doc.title}`).join('\n')}
312
- \n${docsDir}/graph-insights/
313
- ├── latest.md # 最近一次 code_insight 的 Markdown 摘要
314
- └── latest.json # 最近一次 code_insight 的结构化结果
315
- \`\`\`
297
+ - **置信度**: ${detection.confidence}%
298
+
299
+ ## 🔎 当前状态
300
+
301
+ - **project-context.md**: ${projectContextExists ? '已存在(将保留,不覆盖)' : '不存在(需要生成)'}
302
+ - **图谱文档**: 需要确保 ${docsDir}/graph-insights/latest.md 与 latest.json 可用
303
+
304
+ ## 📋 需要生成的文档
305
+
306
+ 请按照以下结构生成 **${docs.length + 1}** 个上下文文档,并为图谱文档预留入口:
307
+
308
+ \`\`\`
309
+ ${docsDir}/
310
+ ├── project-context.md # 索引文件(必须首先生成)
311
+ └── project-context/ # 分类文档目录
312
+ ${docs.map(doc => ` ├── ${doc.file.padEnd(28)} # ${doc.title}`).join('\n')}
313
+ \n${docsDir}/graph-insights/
314
+ ├── latest.md # 最近一次 code_insight 的 Markdown 摘要
315
+ └── latest.json # 最近一次 code_insight 的结构化结果
316
+ \`\`\`
316
317
 
317
318
  ---
318
319
 
319
- ## 🎯 生成步骤
320
-
320
+ ## 🎯 生成步骤
321
+
321
322
  ${projectContextExists
322
- ? `### 已存在项目上下文(仅补图谱)
323
-
324
- 检测到 \`${docsDir}/project-context.md\` 已存在:
325
-
326
- - **不要重写** 现有 \`${docsDir}/project-context.md\`
327
- - **不要重写** \`${docsDir}/project-context/\` 下已有分类文档
328
- - 直接调用 \`code_insight\` 补齐 \`${docsDir}/graph-insights/latest.md\` 与 \`${docsDir}/graph-insights/latest.json\`
329
- - 仅在 \`project-context.md\` 中补充或刷新图谱入口
330
-
331
- ---
323
+ ? `### 已存在项目上下文(仅补图谱)
324
+
325
+ 检测到 \`${docsDir}/project-context.md\` 已存在:
326
+
327
+ - **不要重写** 现有 \`${docsDir}/project-context.md\`
328
+ - **不要重写** \`${docsDir}/project-context/\` 下已有分类文档
329
+ - 直接调用 \`code_insight\` 补齐 \`${docsDir}/graph-insights/latest.md\` 与 \`${docsDir}/graph-insights/latest.json\`
330
+ - 仅在 \`project-context.md\` 中补充或刷新图谱入口
331
+
332
+ ---
332
333
  `
333
- : ''}
334
-
335
- ### 第一步:生成索引文件(最重要!)
334
+ : ''}
335
+
336
+ ### 第一步:生成索引文件(最重要!)
337
+
338
+ **文件**: \`${docsDir}/project-context.md\`
336
339
 
337
- **文件**: \`${docsDir}/project-context.md\`
338
-
339
- 这是项目上下文的**灵魂**,必须首先生成。它是所有文档的入口和导航中心。
340
+ 这是项目上下文的**灵魂**,必须首先生成。它是所有文档的入口和导航中心。
340
341
 
341
342
  **模板**:
342
343
 
@@ -356,20 +357,20 @@ ${projectContextExists
356
357
  | 类型 | ${detection.category} |
357
358
  | 描述 | ${projectInfo.description || '待补充'} |
358
359
 
359
- ## 📚 文档导航
360
-
361
- ${docs.map(doc => `### [${doc.title}](./project-context/${doc.file})
362
- ${doc.purpose}
363
- `).join('\n')}
364
- ### [代码图谱洞察](./graph-insights/latest.md)
365
- 最近一次 code_insight 分析结果,包含模块依赖、调用链和影响面摘要
366
-
367
- ## 🚀 快速开始
368
-
369
- 1. 阅读 [技术栈](./project-context/tech-stack.md) 了解项目使用的技术
370
- 2. 阅读 [架构设计](./project-context/architecture.md) 了解项目结构
371
- 3. 阅读 [代码图谱洞察](./graph-insights/latest.md) 快速理解模块依赖与调用链
372
- 4. 根据需要查看具体的操作指南
360
+ ## 📚 文档导航
361
+
362
+ ${docs.map(doc => `### [${doc.title}](./project-context/${doc.file})
363
+ ${doc.purpose}
364
+ `).join('\n')}
365
+ ### [代码图谱洞察](./graph-insights/latest.md)
366
+ 最近一次 code_insight 分析结果,包含模块依赖、调用链和影响面摘要
367
+
368
+ ## 🚀 快速开始
369
+
370
+ 1. 阅读 [技术栈](./project-context/tech-stack.md) 了解项目使用的技术
371
+ 2. 阅读 [架构设计](./project-context/architecture.md) 了解项目结构
372
+ 3. 阅读 [代码图谱洞察](./graph-insights/latest.md) 快速理解模块依赖与调用链
373
+ 4. 根据需要查看具体的操作指南
373
374
 
374
375
  ## 💡 开发时查看对应文档
375
376
 
@@ -382,43 +383,43 @@ ${generateDevGuide(docs)}
382
383
  *生成工具: MCP Probe Kit - init_project_context v2.1*
383
384
  \`\`\`
384
385
 
385
- ${projectContextExists ? '**如果该文件已存在,跳过此步骤,不要覆盖**' : '**使用 fsWrite 创建此文件**'}
386
+ ${projectContextExists ? '**如果该文件已存在,跳过此步骤,不要覆盖**' : '**使用 fsWrite 创建此文件**'}
386
387
 
387
388
  ---
388
389
 
389
- ### 第二步:生成分类文档
390
-
391
- ${docs.map((doc, index) => generateDocTemplate(doc, index + 2, projectInfo, detection, docsDir)).join('\n\n---\n\n')}
390
+ ### 第二步:生成分类文档
391
+
392
+ ${docs.map((doc, index) => generateDocTemplate(doc, index + 2, projectInfo, detection, docsDir)).join('\n\n---\n\n')}
392
393
 
393
394
  ---
394
395
 
395
- ## ✅ 完成标准
396
-
397
- 请确认:
398
-
399
- - [ ] ${projectContextExists ? '保留现有 project-context 及分类文档,不做覆盖' : `已使用 fsWrite 创建 **${docs.length + 1}** 个文件`}
400
- - [ ] 索引文件 \`project-context.md\` ${projectContextExists ? '已存在并保留' : '已创建(最重要!)'}
401
- - [ ] 索引文件已包含 \`graph-insights/latest.md\` 的入口
402
- - [ ] 所有文档都包含**真实的文件路径**(不是 [xxx] 占位符)
403
- - [ ] 所有文档都包含**实际的代码示例**(从项目中复制)
404
- - [ ] 所有步骤都具体可操作
405
- - [ ] 所有示例都来自项目实际代码
406
-
407
- ---
408
-
409
- ## 🔄 完成文档骨架后立即执行
410
-
411
- 1. 调用 \`code_insight\`
412
- \`\`\`json
413
- {
414
- "mode": "auto",
415
- "project_root": "${toPosixPath(projectRoot)}",
416
- "docs_dir": "${docsDir}"
417
- }
418
- \`\`\`
419
- 2. 严格执行 \`code_insight\` 返回的 delegated plan
420
- 3. 确保 \`${docsDir}/graph-insights/latest.md\` 和 \`${docsDir}/graph-insights/latest.json\` 已写入
421
- 4. 若已有旧图谱,按 delegated plan 归档时间戳版本
396
+ ## ✅ 完成标准
397
+
398
+ 请确认:
399
+
400
+ - [ ] ${projectContextExists ? '保留现有 project-context 及分类文档,不做覆盖' : `已使用 fsWrite 创建 **${docs.length + 1}** 个文件`}
401
+ - [ ] 索引文件 \`project-context.md\` ${projectContextExists ? '已存在并保留' : '已创建(最重要!)'}
402
+ - [ ] 索引文件已包含 \`graph-insights/latest.md\` 的入口
403
+ - [ ] 所有文档都包含**真实的文件路径**(不是 [xxx] 占位符)
404
+ - [ ] 所有文档都包含**实际的代码示例**(从项目中复制)
405
+ - [ ] 所有步骤都具体可操作
406
+ - [ ] 所有示例都来自项目实际代码
407
+
408
+ ---
409
+
410
+ ## 🔄 完成文档骨架后立即执行
411
+
412
+ 1. 调用 \`code_insight\`
413
+ \`\`\`json
414
+ {
415
+ "mode": "auto",
416
+ "project_root": "${toPosixPath(projectRoot)}",
417
+ "docs_dir": "${docsDir}"
418
+ }
419
+ \`\`\`
420
+ 2. 严格执行 \`code_insight\` 返回的 delegated plan
421
+ 3. 确保 \`${docsDir}/graph-insights/latest.md\` 和 \`${docsDir}/graph-insights/latest.json\` 已写入
422
+ 4. 若已有旧图谱,按 delegated plan 归档时间戳版本
422
423
 
423
424
  ---
424
425
 
@@ -733,13 +734,13 @@ ${template}
733
734
  */
734
735
  export async function initProjectContext(args) {
735
736
  let docsDir = DEFAULT_DOCS_DIR;
736
- let projectRoot = process.cwd();
737
+ let projectRoot = resolveWorkspaceRoot();
737
738
  try {
738
739
  // 智能参数解析,支持自然语言输入
739
740
  const parsedArgs = parseArgs(args, {
740
741
  defaultValues: {
741
742
  docs_dir: DEFAULT_DOCS_DIR,
742
- project_root: process.cwd()
743
+ project_root: resolveWorkspaceRoot()
743
744
  },
744
745
  primaryField: "docs_dir",
745
746
  fieldAliases: {
@@ -748,7 +749,21 @@ export async function initProjectContext(args) {
748
749
  },
749
750
  });
750
751
  docsDir = getString(parsedArgs.docs_dir) || DEFAULT_DOCS_DIR;
751
- projectRoot = getString(parsedArgs.project_root) || process.cwd();
752
+ projectRoot = getString(parsedArgs.project_root) || resolveWorkspaceRoot();
753
+ if (isLikelyProjectNamedRelativePath(projectRoot)) {
754
+ return {
755
+ content: [{
756
+ type: "text",
757
+ text: `拒绝执行项目上下文初始化:project_root 不能传带项目名的半相对路径,例如 ${projectRoot}。请改为传项目根目录绝对路径。`,
758
+ }],
759
+ isError: true,
760
+ structuredContent: {
761
+ error_code: "INVALID_PROJECT_ROOT",
762
+ rejected_project_root: projectRoot,
763
+ retry_hint: buildProjectRootRetryHint(projectRoot),
764
+ },
765
+ };
766
+ }
752
767
  // 生成项目上下文
753
768
  return await generateProjectContext(docsDir, projectRoot);
754
769
  }
@@ -0,0 +1,7 @@
1
+ export declare function memorizeAsset(args: any): Promise<import("../lib/response.js").ToolResponse | {
2
+ content: Array<{
3
+ type: string;
4
+ text: string;
5
+ }>;
6
+ isError: true;
7
+ }>;
@@ -0,0 +1,66 @@
1
+ import { parseArgs, getString, getNumber } from '../utils/parseArgs.js';
2
+ import { okStructured } from '../lib/response.js';
3
+ import { createMemoryClient } from '../lib/memory-client.js';
4
+ import { handleToolError } from '../utils/error-handler.js';
5
+ export async function memorizeAsset(args) {
6
+ try {
7
+ const parsed = parseArgs(args, {
8
+ defaultValues: {
9
+ name: '',
10
+ type: 'code',
11
+ description: '',
12
+ summary: '',
13
+ content: '',
14
+ code_snippet: '',
15
+ file_path: '',
16
+ source_project: '',
17
+ source_path: '',
18
+ usage: '',
19
+ confidence: 0.7,
20
+ },
21
+ fieldAliases: {
22
+ code_snippet: ['code', 'snippet'],
23
+ file_path: ['path'],
24
+ source_project: ['project'],
25
+ source_path: ['source'],
26
+ },
27
+ });
28
+ const name = getString(parsed.name);
29
+ const type = getString(parsed.type) || 'code';
30
+ const description = getString(parsed.description);
31
+ const summary = getString(parsed.summary);
32
+ const content = getString(parsed.content) || getString(parsed.code_snippet);
33
+ const sourceProject = getString(parsed.source_project);
34
+ const sourcePath = getString(parsed.source_path) || getString(parsed.file_path);
35
+ const usage = getString(parsed.usage);
36
+ const confidence = getNumber(parsed.confidence, 0.7);
37
+ const tags = Array.isArray(parsed.tags) ? parsed.tags.filter((item) => typeof item === 'string') : [];
38
+ if (!name || !description || !summary || !content) {
39
+ throw new Error('缺少必填参数: name, description, summary, content/code_snippet');
40
+ }
41
+ const client = createMemoryClient();
42
+ if (!client.isEnabled()) {
43
+ return okStructured('记忆服务未开启,已跳过沉淀。', { enabled: false, stored: false });
44
+ }
45
+ const asset = await client.upsertAsset({
46
+ name,
47
+ type,
48
+ description,
49
+ summary,
50
+ content,
51
+ sourceProject: sourceProject || undefined,
52
+ sourcePath: sourcePath || undefined,
53
+ usage: usage || undefined,
54
+ confidence,
55
+ tags,
56
+ });
57
+ return okStructured(`已沉淀记忆资产: ${asset.name}`, {
58
+ enabled: true,
59
+ stored: true,
60
+ asset,
61
+ });
62
+ }
63
+ catch (error) {
64
+ return handleToolError(error, 'memorize_asset');
65
+ }
66
+ }
@@ -0,0 +1,7 @@
1
+ export declare function readMemoryAsset(args: any): Promise<import("../lib/response.js").ToolResponse | {
2
+ content: Array<{
3
+ type: string;
4
+ text: string;
5
+ }>;
6
+ isError: true;
7
+ }>;
@@ -0,0 +1,26 @@
1
+ import { okStructured } from '../lib/response.js';
2
+ import { createMemoryClient } from '../lib/memory-client.js';
3
+ import { handleToolError } from '../utils/error-handler.js';
4
+ export async function readMemoryAsset(args) {
5
+ try {
6
+ const assetId = typeof args?.asset_id === 'string' ? args.asset_id.trim() : '';
7
+ if (!assetId) {
8
+ throw new Error('缺少必填参数: asset_id');
9
+ }
10
+ const client = createMemoryClient();
11
+ if (!client.isReadEnabled()) {
12
+ return okStructured('记忆服务未开启,已跳过读取。', { enabled: false, asset: null });
13
+ }
14
+ const asset = await client.getAsset(assetId);
15
+ if (!asset) {
16
+ return okStructured(`未找到记忆资产: ${assetId}`, { enabled: true, asset: null });
17
+ }
18
+ return okStructured(`已读取记忆资产: ${asset.name}`, {
19
+ enabled: true,
20
+ asset,
21
+ });
22
+ }
23
+ catch (error) {
24
+ return handleToolError(error, 'read_memory_asset');
25
+ }
26
+ }
@@ -0,0 +1,27 @@
1
+ export declare function scanAndExtractPatterns(args: any): Promise<import("../lib/response.js").ToolResponse | {
2
+ content: Array<{
3
+ type: string;
4
+ text: string;
5
+ }>;
6
+ isError: true;
7
+ } | {
8
+ content: {
9
+ type: string;
10
+ text: string;
11
+ }[];
12
+ isError: boolean;
13
+ structuredContent: {
14
+ error_code: string;
15
+ mode: string;
16
+ rejected_directory_path: string;
17
+ retry_hint: {
18
+ preferred: {
19
+ project_root: string;
20
+ directory_path: string;
21
+ };
22
+ fallback: {
23
+ directory_path: string;
24
+ };
25
+ };
26
+ };
27
+ }>;