mirror of
https://github.com/jacobinwwey/obsidian-NotEMD.git
synced 2026-07-22 05:48:27 +00:00
feat(stage-c): close diagram retrieval telemetry gap
This commit is contained in:
parent
d92e2979f8
commit
d199238cea
14 changed files with 366 additions and 65 deletions
|
|
@ -36,7 +36,7 @@ This matrix is grounded in:
|
|||
| A. Packaging / semantic verification | Live build/audit truth is still single-entry `main.js` + inline `srcdoc`; source still contains render-host runtime candidate modules, but current execution and audit truth now explicitly keep them non-shipped by rejecting stray `render-host.mjs` assets/references | Later backup branch had a wider dedicated runtime-asset lane | Keep the current source-only decision explicit until a future batch ships a real multi-entry contract with build + release + audit + docs all updated together | Do not keep saying `render-host.mjs` is currently shipped on main just because candidate runtime code exists in `src/` | P0 |
|
||||
| B. CLI / automation surface | Current main now has registry-backed config/profile export/import, redacted provider export, public-surface export, registry-backed typed `content.split-note-by-chapters`, and repo-local maintainer help/invoke scripts for bounded path-based operations plus exports | Backup branch also carried broader maintainer-bridge aspirations, but the current reintegration keeps the surface intentionally narrow | Keep maintainer helper scope explicit and only promote path-based operations to broader/public CLI status with same-batch contract/test/doc proof | Do not describe the current surface as a general-purpose public CLI or a free-form maintainer mutation API | P1 |
|
||||
| C. User-facing settings / preview / onboarding | Current main now has preview flows, preview history, release-note digest in onboarding, provider diagnostics, settings reset, concept-note prerequisite guidance, API liveness/activity UI, and saved-artifact-aware preview recovery with `1.8.9` version truth resynced | Backup branch carried additional UX closure work, but the recovered slice is now re-proved on current main | Keep sidebar/preview/settings wording, i18n, saved-artifact behavior, and release-facing version truth aligned as the user-facing truth source | Do not regress to “these UX guardrails are missing on current main,” but also do not overclaim unrecovered UX ideas | P1 |
|
||||
| D. Regex / file selection / local-KB / chapter split | Current main now has file-selection profiles, folder regex/glob filtering, `relativePath` / `basename` matching, optional subfolder inclusion control, local-KB retrieval, chapter split, their regression tests, and machine-readable retrieval summaries plus timing/size telemetry on the title-generation and research result paths | Backup branch provided the original recovery evidence; current main now carries the bounded product slice directly and the latest Stage C follow-through work | Treat the next step as remaining chapter-split / diagram-adjacent result framing and offline retrieval-quality evaluation follow-through, not existence re-proof | Do not keep writing these capabilities as backup-only or absent from live mainline, and do not flatten retrieval back down to boolean-only signaling in docs or contracts | P1 |
|
||||
| D. Regex / file selection / local-KB / chapter split | Current main now has file-selection profiles, folder regex/glob filtering, `relativePath` / `basename` matching, optional subfolder inclusion control, local-KB retrieval, chapter split, their regression tests, and machine-readable retrieval summaries plus timing/size telemetry on the title-generation, research, and artifact-mode diagram result paths | Backup branch provided the original recovery evidence; current main now carries the bounded product slice directly and the latest Stage C follow-through work | Treat the next step as remaining chapter-split evidence framing and offline retrieval-quality evaluation follow-through, not existence re-proof | Do not keep writing these capabilities as backup-only or absent from live mainline, and do not flatten retrieval back down to boolean-only signaling in docs or contracts | P1 |
|
||||
| E. Release / repo-saga / clean-state hygiene | Current main now has release/repo-saga scripts plus shared repo-saga execution lock, tests, docs, and local-artifact ignore guardrails | Backup branch motivated the guardrails; the bounded serial-safety slice is now back on current main | Preserve serial execution discipline for repo-saga refresh flows and keep clean-state proof as part of finish criteria | Do not confuse “script still exists” with permission to run repo-saga refresh paths in parallel | P0 |
|
||||
|
||||
## 4. Reconfirmed Current-Main Register
|
||||
|
|
@ -51,7 +51,7 @@ These items are safe to describe as present on current main:
|
|||
6. redacted/public-safe CLI export surfaces plus repo-local maintainer help/invoke for bounded path-based operations;
|
||||
7. settings reset, concept-note prerequisite guidance, and concept synonym suppression;
|
||||
8. file-selection profiles and folder-scope regex/glob control;
|
||||
9. local knowledge-base retrieval, including machine-readable retrieval summaries on the title-generation and research result paths;
|
||||
9. local knowledge-base retrieval, including machine-readable retrieval summaries on the title-generation, research, and artifact-mode diagram result paths;
|
||||
10. chapter split;
|
||||
11. `1.8.9` release-facing version truth resync across package metadata, welcome digest, and README family.
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ canonical: true
|
|||
| A. Packaging / semantic verification | 当前 live build/audit 真值仍是单入口 `main.js` + inline `srcdoc`;源码中仍保留 render-host runtime 候选模块,但当前执行链与审计真值已明确把它们保持为 non-shipped,并拒绝残留的 `render-host.mjs` 资产/引用 | 更晚的备份分支曾进入更宽的 dedicated runtime-asset 通道 | 在未来真正补齐 build + release + audit + 文档之前,继续把当前 source-only 决策写清楚 | 不要因为 `src/` 里重新出现 runtime 候选代码,就继续把 `render-host.mjs` 写成当前主线已发货 | P0 |
|
||||
| B. CLI / automation surface | 当前主线现已具备 registry-backed 的 config/profile export/import、脱敏 provider 导出、public-surface 导出、已进入 registry-backed typed contract 的 `content.split-note-by-chapters`,以及覆盖有界 path-based 操作与 export 操作的 repo-local maintainer help/invoke 脚本 | 备份分支还承载过更宽的 maintainer-bridge 设想,但当前 reintegration 刻意保持在窄边界内 | 继续把 maintainer helper 的边界写清楚;若任何 path-based operation 要提升为更广或更公共的 CLI 面,必须同批补齐契约/测试/文档 | 不要把当前能力面写成通用 public CLI,或无边界的 maintainer mutation API | P1 |
|
||||
| C. 用户可见 settings / preview / onboarding | 当前主线现已具备 preview flows、preview history、欢迎弹窗 release digest、provider diagnostics、settings reset、concept-note 前置配置提示、API liveness/activity UI,以及面向已保存工件的 preview 恢复链路,并已重新同步 `1.8.9` release-facing version truth | 备份分支还有更多 UX 收口尝试,但目前已恢复切片已在当前主线上重新证明 | 继续保持 sidebar / preview / settings 的文案、i18n、已保存工件行为与 release-facing version truth 一致 | 不要再把这些 UX guardrail 写成“当前主线缺失”,但也不要顺手高估尚未恢复的 UX 想法 | P1 |
|
||||
| D. Regex / 文件筛选 / local-KB / chapter split | 当前主线现已具备 file-selection profiles、文件夹 regex/glob 筛选、`relativePath` / `basename` 匹配、可选子目录范围控制、local-KB retrieval、chapter split、对应回归测试,以及面向标题生成与研究结果路径的 machine-readable retrieval 摘要与 timing/size telemetry | 备份分支提供了最初恢复证据;当前主线现在已直接携带该有界产品切片与最新 Stage C 收口结果 | 下一步应转向剩余 chapter-split / diagram 邻近 result framing 与 offline retrieval-quality evaluation 跟进,而不是继续证明这些能力“是否存在” | 不要继续把这些能力写成只存在于 backup、或 live mainline 尚未具备,也不要在文档或契约里把 retrieval 再压回 boolean-only signaling | P1 |
|
||||
| D. Regex / 文件筛选 / local-KB / chapter split | 当前主线现已具备 file-selection profiles、文件夹 regex/glob 筛选、`relativePath` / `basename` 匹配、可选子目录范围控制、local-KB retrieval、chapter split、对应回归测试,以及面向标题生成、研究总结与 artifact-mode 图形结果路径的 machine-readable retrieval 摘要与 timing/size telemetry | 备份分支提供了最初恢复证据;当前主线现在已直接携带该有界产品切片与最新 Stage C 收口结果 | 下一步应转向剩余 chapter-split evidence framing 与 offline retrieval-quality evaluation 跟进,而不是继续证明这些能力“是否存在” | 不要继续把这些能力写成只存在于 backup、或 live mainline 尚未具备,也不要在文档或契约里把 retrieval 再压回 boolean-only signaling | P1 |
|
||||
| E. Release / repo-saga / clean-state hygiene | 当前主线现已具备 release/repo-saga 脚本,以及 repo-saga 执行锁、测试、文档与本地工件忽略 guardrail | 备份分支推动了这些 guardrail;当前主线已恢复有界串行安全切片 | 保持 repo-saga 刷新流程的串行纪律,并把 clean-state 证明保留为收尾要求 | 不要把“脚本还在”误读为“可以并行跑 repo-saga 刷新路径” | P0 |
|
||||
|
||||
## 4. 当前主线已确认 register
|
||||
|
|
@ -51,7 +51,7 @@ canonical: true
|
|||
6. 脱敏 / public-safe CLI 导出表面与仓库内 maintainer help/invoke(含有界 path-based 操作);
|
||||
7. settings reset、concept-note 前置提示与 concept synonym suppression;
|
||||
8. file-selection profiles 与 folder-scope regex/glob 控制;
|
||||
9. local knowledge-base retrieval,以及面向标题生成与研究结果路径的 machine-readable retrieval 摘要;
|
||||
9. local knowledge-base retrieval,以及面向标题生成、研究总结与 artifact-mode 图形结果路径的 machine-readable retrieval 摘要;
|
||||
10. chapter split;
|
||||
11. package metadata、welcome digest 与 README family 上重新同步到 `1.8.9` 的 release-facing version truth。
|
||||
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@ Goal:
|
|||
|
||||
Likely areas:
|
||||
|
||||
1. keep extending richer result/evidence framing to the remaining chapter-split / diagram-adjacent paths now that retrieval summaries plus timing telemetry are landed for title-generation and research;
|
||||
1. keep extending richer result/evidence framing to the remaining chapter-split paths now that retrieval summaries plus timing telemetry are landed for title-generation, research, and artifact-mode diagram generation;
|
||||
2. the shared maintainer helper now carries compact payload examples for the retrieval-dependent paths, so the next step is to keep those examples aligned as result schemas evolve;
|
||||
3. continue tuning/documentation around sliding-window size, snippet shaping, folder-scope expectations, and offline evaluation fixtures.
|
||||
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@ release-facing 真值也已在当前主线上重新对齐:
|
|||
|
||||
可能的切入点:
|
||||
|
||||
1. 在标题生成与研究总结已经落地 retrieval 摘要与 timing telemetry 之后,继续把 richer result/evidence framing 推进到剩余的 chapter-split / diagram 邻近路径;
|
||||
1. 在标题生成、研究总结与 artifact-mode 图形生成已经落地 retrieval 摘要与 timing telemetry 之后,继续把 richer result/evidence framing 推进到剩余的 chapter-split 路径;
|
||||
2. shared maintainer helper 现已为依赖 retrieval 的路径补上简洁 payload 示例,下一步重点是让这些示例持续跟随 result schema 演进;
|
||||
3. 继续完善 sliding-window、snippet shaping、folder-scope 预期与 offline evaluation fixture 等调优文档。
|
||||
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ Boundary:
|
|||
| `notemd:export-cli-capability-manifest` | Export command capability manifest | `safe` | Part of the bounded public-safe slice. Deterministic export, but still tied to plugin config-path write semantics | `cli.capability-manifest.export` |
|
||||
| `notemd:export-cli-invocation-contract` | Export typed invocation contract | `safe` | Part of the bounded public-safe slice. Deterministic export, but still tied to plugin config-path write semantics | `cli.invocation-contract.export` |
|
||||
| `notemd:export-cli-public-surface` | Export bounded public CLI surface | `safe` | Part of the bounded public-safe slice. Self-describes the currently supported official-CLI-safe subset | `cli.public-surface.export` |
|
||||
| `notemd:notemd-generate-diagram` | Generate spec-first artifact from active file | `requires-active-file` | Typed result now exposes the wrapper envelope plus explicit follow-through details (`kind`, `executionMode`, `sourcePath`, `actionLabel`, `operationInput`, `generation`, `followThrough`, `outputPath`, `previewOpened`), but active-file dependency, plugin state, and save/open side effects still keep this below a stable public API | `diagram.generate` (`exact`, `defaultInput.outputMode=artifact`) |
|
||||
| `notemd:notemd-generate-diagram` | Generate spec-first artifact from active file | `requires-active-file` | Typed result now exposes the wrapper envelope plus explicit follow-through details (`kind`, `executionMode`, `sourcePath`, `actionLabel`, `operationInput`, `generation`, `followThrough`, `outputPath`, `previewOpened`) and a machine-readable local-KB retrieval summary (`localKnowledgeContextUsed`, `localKnowledgeRetrieval`) for artifact-generation modes, but active-file dependency, plugin state, and save/open side effects still keep this below a stable public API | `diagram.generate` (`exact`, `defaultInput.outputMode=artifact`) |
|
||||
| `notemd:notemd-summarize-as-mermaid` | Save Mermaid output for active file | `requires-active-file` | Typed result now exposes the wrapper envelope plus explicit follow-through details (`kind`, `executionMode`, `sourcePath`, `actionLabel`, `operationInput`, `generation`, `followThrough`, `outputPath`, `previewOpened`), but active-file dependency plus plugin-managed save/output semantics still keep this below a stable public API | `diagram.generate` (`exact`, `defaultInput.outputMode=mermaid`) |
|
||||
| `notemd:notemd-preview-diagram` | Preview saved/sourced diagram | `interactive-ui` | Typed input/result schemas now describe the preview artifact boundary, but opening the preview modal is still UI-bound and not automation-stable | `diagram.preview` (`exact`) |
|
||||
| `notemd:process-with-notemd` | Process current file and add links | `requires-active-file` | Structured file result now exists, but active-file dependency, concept-note creation, output-path policy, and vault mutation still block stable automation | `file.process-add-links` |
|
||||
|
|
@ -135,9 +135,9 @@ Boundary:
|
|||
- The registry now includes the main note-processing, utility, selection, and export operation batches as well: `editor.create-link-and-generate`, `file.process-add-links`, `file.process-folder-add-links`, `content.generate-from-title`, `content.batch-generate-from-titles`, `content.split-note-by-chapters`, `research.summarize-topic`, `translate.file`, `translate.folder-batch`, `concept.extract-file`, `concept.extract-folder`, `content.extract-original-text`, `workflow.extract-and-generate`, `duplicate.check-file`, `concept.dedupe`, `mermaid.batch-fix`, `formula.fix-file`, `formula.batch-fix`, `provider.profile.export`, `provider.profile.export-redacted`, `provider.profile.import`, `cli.capability-manifest.export`, `cli.invocation-contract.export`, and `cli.public-surface.export`.
|
||||
- `src/operations/publicCliSurface.ts` now derives the bounded public-safe slice from the same registry/capability/contract pair instead of maintaining a parallel command allowlist.
|
||||
- `file.process-add-links`, `file.process-folder-add-links`, `content.generate-from-title`, `content.batch-generate-from-titles`, `mermaid.batch-fix`, `concept.dedupe`, `translate.*`, `formula.*`, and `content.extract-original-text` now form the current proof set for write-heavy contract enrichment: utility cores return structured results, host adapters own localized success/no-file/confirmation semantics, and the registry exports the richer schemas directly.
|
||||
- `content.generate-from-title`, `content.batch-generate-from-titles`, and `research.summarize-topic` now also expose machine-readable local-KB retrieval summaries instead of reducing retrieval to a boolean-only side note. Current summaries include indexed counts, matched/returned section counts, expanded section counts, source paths, requested `topK`, sliding-window size, current-file exclusion telemetry, index-build ms, query ms, and final context-char count.
|
||||
- `content.generate-from-title`, `content.batch-generate-from-titles`, `research.summarize-topic`, and artifact-mode `diagram.generate` now also expose machine-readable local-KB retrieval summaries instead of reducing retrieval to a boolean-only side note. Current summaries include indexed counts, matched/returned section counts, expanded section counts, source paths, requested `topK`, sliding-window size, current-file exclusion telemetry, index-build ms, query ms, and final context-char count.
|
||||
- `content.split-note-by-chapters` now follows the same direction more explicitly: the result shape names the requested heading level, chapter note paths, full managed artifact set, and stale removals instead of forcing callers to infer them indirectly from counts or filenames.
|
||||
- `diagram.generate` now carries an explicit typed follow-through layer beneath the host-neutral generation core: `followThrough.kind` differentiates Mermaid save, artifact save, and preview completion while preserving backward-compatible top-level `outputPath` / `previewOpened`.
|
||||
- `diagram.generate` now carries an explicit typed follow-through layer beneath the host-neutral generation core: `followThrough.kind` differentiates Mermaid save, artifact save, and preview completion while preserving backward-compatible top-level `outputPath` / `previewOpened`, and artifact-generation modes now also surface the local-KB retrieval telemetry through the same structured result.
|
||||
- The first checked-in semantic-verification helper now exists as `npm run verify:diagram-semantics`; it turns the maintainer runbook into a reusable, secret-free checklist artifact instead of leaving semantic verification as prose-only guidance.
|
||||
- The next contract-deepening order is now more precise: keep `diagram.generate` as the host-neutral generation core, treat the follow-through shape beneath it as landed, then move to packaging/semantic-verification convergence and only after that revisit broader CLI/public-surface claims.
|
||||
- Legacy aliases remain registered for compatibility, but they are intentionally excluded from capability-manifest export.
|
||||
|
|
@ -150,7 +150,7 @@ These are the best remaining candidates for registry-backed or more host-neutral
|
|||
|---|---|---|---|
|
||||
| P0 | Packaging source/build convergence around the latent render-host runtime lane | Current source now contains reusable runtime helpers (`src/rendering/runtime/renderHostEntry.ts`, `src/rendering/preview/renderHostRuntimeClient.ts`), but build/audit truth still proves `main.js`-only shipping. The highest-value next step is to remove that ambiguity explicitly: either keep the runtime lane source-only and document it as non-shipped, or ship a true multi-entry boundary in one batch | `esbuild.config.mjs`, `scripts/audit-render-host-bundle.js`, `src/rendering/runtime/renderHostEntry.ts`, `src/rendering/preview/renderHostRuntimeClient.ts` |
|
||||
| P1 | Bounded public-CLI promotion for explicit path-based operations | The maintainer helper already proves there is demand for path-based operations, but public promotion should happen only for operations whose write semantics and output contracts are stable enough to document and regression-lock | `src/maintainerCliBridge.ts`, `scripts/lib/maintainer-cli-operation-help.js`, `src/operations/registry.ts`, `src/tests/maintainerCliBridge.test.ts` |
|
||||
| P1 | Contract/result hardening for retrieval and chapter-split writes | Retrieval-dependent note-processing results now expose machine-readable `localKnowledgeRetrieval` summaries with timing/size telemetry, and the shared maintainer helper now carries compact payload examples; the next maturity gain is to carry the same discipline through the remaining chapter-split / diagram framing rather than broadening the surface count | `src/chapterSplit.ts`, `src/localKnowledgeBase.ts`, `src/fileUtils.ts`, `src/searchUtils.ts`, `scripts/lib/maintainer-cli-operation-help.js`, `src/tests/chapterSplit.test.ts`, `src/tests/localKnowledgeTaskIntegration.test.ts` |
|
||||
| P1 | Contract/result hardening for retrieval and chapter-split writes | Retrieval-dependent note-processing results, including artifact-mode `diagram.generate`, now expose machine-readable `localKnowledgeRetrieval` summaries with timing/size telemetry, and the shared maintainer helper now carries compact payload examples; the next maturity gain is to keep chapter-split evidence framing and offline retrieval-quality evaluation aligned rather than broadening the surface count | `src/chapterSplit.ts`, `src/localKnowledgeBase.ts`, `src/fileUtils.ts`, `src/searchUtils.ts`, `src/main.ts`, `scripts/lib/maintainer-cli-operation-help.js`, `src/tests/chapterSplit.test.ts`, `src/tests/localKnowledgeTaskIntegration.test.ts`, `src/tests/diagramCommandArchitecture.test.ts` |
|
||||
| P2 | Workflow/settings packaging | Workflow DSL and output-path toggles remain useful metadata but not yet stable public interfaces | `src/workflowButtons.ts`, settings-driven output controls |
|
||||
|
||||
## Settings Readiness
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@
|
|||
| `notemd:export-cli-capability-manifest` | 导出命令 capability manifest | `safe` | 属于当前收敛后的 public-safe slice。导出确定,但仍绑定插件 config-path 写入语义 | `cli.capability-manifest.export` |
|
||||
| `notemd:export-cli-invocation-contract` | 导出类型化 invocation contract | `safe` | 属于当前收敛后的 public-safe slice。导出确定,但仍绑定插件 config-path 写入语义 | `cli.invocation-contract.export` |
|
||||
| `notemd:export-cli-public-surface` | 导出当前收敛后的公共 CLI 表面 | `safe` | 属于当前收敛后的 public-safe slice。该导出会自描述当前真正支持的官方 CLI 安全子集 | `cli.public-surface.export` |
|
||||
| `notemd:notemd-generate-diagram` | 从活动文件生成 spec-first artifact | `requires-active-file` | 类型化结果现在已暴露完整 wrapper envelope,并额外包含显式 follow-through 细节(`kind`、`executionMode`、`sourcePath`、`actionLabel`、`operationInput`、`generation`、`followThrough`、`outputPath`、`previewOpened`),但 active-file 依赖、插件状态与保存/打开副作用仍使它不能直接宣称为稳定 public API | `diagram.generate`(`exact`,`defaultInput.outputMode=artifact`) |
|
||||
| `notemd:notemd-generate-diagram` | 从活动文件生成 spec-first artifact | `requires-active-file` | 类型化结果现在已暴露完整 wrapper envelope,并额外包含显式 follow-through 细节(`kind`、`executionMode`、`sourcePath`、`actionLabel`、`operationInput`、`generation`、`followThrough`、`outputPath`、`previewOpened`);对于 artifact-generation modes,还会显式带出 machine-readable 的本地知识库检索摘要(`localKnowledgeContextUsed`、`localKnowledgeRetrieval`),但 active-file 依赖、插件状态与保存/打开副作用仍使它不能直接宣称为稳定 public API | `diagram.generate`(`exact`,`defaultInput.outputMode=artifact`) |
|
||||
| `notemd:notemd-summarize-as-mermaid` | 为活动文件保存 Mermaid 输出 | `requires-active-file` | 类型化结果现在已暴露完整 wrapper envelope,并额外包含显式 follow-through 细节(`kind`、`executionMode`、`sourcePath`、`actionLabel`、`operationInput`、`generation`、`followThrough`、`outputPath`、`previewOpened`),但 active-file 依赖与插件管理的保存语义仍使它不能直接宣称为稳定 public API | `diagram.generate`(`exact`,`defaultInput.outputMode=mermaid`) |
|
||||
| `notemd:notemd-preview-diagram` | 预览已保存/已生成图表 | `interactive-ui` | 现在已经具备类型化 input/result schema 来描述 preview artifact 边界,但打开 preview modal 仍属于 UI-only 流程,不具备自动化稳定性 | `diagram.preview`(`exact`) |
|
||||
| `notemd:process-with-notemd` | 处理当前文件并加链接 | `requires-active-file` | 结构化文件结果已存在,但 active-file 依赖、概念笔记创建、输出路径策略与 vault 改写副作用仍阻碍稳定自动化 | `file.process-add-links` |
|
||||
|
|
@ -135,9 +135,9 @@
|
|||
- registry 现在也已纳入主要 note-processing、utility、selection 与 export operations:`editor.create-link-and-generate`、`file.process-add-links`、`file.process-folder-add-links`、`content.generate-from-title`、`content.batch-generate-from-titles`、`content.split-note-by-chapters`、`research.summarize-topic`、`translate.file`、`translate.folder-batch`、`concept.extract-file`、`concept.extract-folder`、`content.extract-original-text`、`workflow.extract-and-generate`、`duplicate.check-file`、`concept.dedupe`、`mermaid.batch-fix`、`formula.fix-file`、`formula.batch-fix`、`provider.profile.export`、`provider.profile.export-redacted`、`provider.profile.import`、`cli.capability-manifest.export`、`cli.invocation-contract.export` 与 `cli.public-surface.export`。
|
||||
- `src/operations/publicCliSurface.ts` 现在会从同一套 registry/capability/contract 组合直接推导 bounded public-safe slice,而不是维护另一份并行 allowlist。
|
||||
- `file.process-add-links`、`file.process-folder-add-links`、`content.generate-from-title`、`content.batch-generate-from-titles`、`mermaid.batch-fix`、`concept.dedupe`、`translate.*`、`formula.*` 与 `content.extract-original-text` 现在已经组成当前已验证的 write-heavy contract-enrichment proof set:utility core 返回结构化结果,host adapter 接管本地化成功/no-file/confirmation 语义,registry 直接导出 richer schema。
|
||||
- `content.generate-from-title`、`content.batch-generate-from-titles` 与 `research.summarize-topic` 现在也已直接暴露 machine-readable 的 local-KB retrieval 摘要,而不再只剩一个 boolean 侧记。当前摘要会带出 indexed counts、matched/returned section counts、expanded section counts、source paths、请求的 `topK`、sliding-window size、current-file exclusion telemetry、index-build ms、query ms 与最终 context-char count。
|
||||
- `content.generate-from-title`、`content.batch-generate-from-titles`、`research.summarize-topic` 以及 artifact-mode 的 `diagram.generate` 现在也已直接暴露 machine-readable 的 local-KB retrieval 摘要,而不再只剩一个 boolean 侧记。当前摘要会带出 indexed counts、matched/returned section counts、expanded section counts、source paths、请求的 `topK`、sliding-window size、current-file exclusion telemetry、index-build ms、query ms 与最终 context-char count。
|
||||
- `content.split-note-by-chapters` 现在也更明确地遵循同一方向:结果结构会直接命名请求的 heading level、章节文件路径、完整 managed artifact 集合以及 stale removal 明细,而不是继续逼调用方只靠 count 或文件名间接推断。
|
||||
- `diagram.generate` 现在已经在宿主无关 generation core 之下携带显式 typed follow-through:`followThrough.kind` 用来区分 Mermaid 保存、artifact 保存与 preview 完成,同时继续保留向后兼容的顶层 `outputPath` / `previewOpened`。
|
||||
- `diagram.generate` 现在已经在宿主无关 generation core 之下携带显式 typed follow-through:`followThrough.kind` 用来区分 Mermaid 保存、artifact 保存与 preview 完成,同时继续保留向后兼容的顶层 `outputPath` / `previewOpened`;artifact-generation modes 还会沿同一结构化结果暴露 local-KB retrieval telemetry。
|
||||
- 第一份已检入的 semantic-verification helper 现在也已经存在:`npm run verify:diagram-semantics` 会把维护者 runbook 落成可复用、无 secrets 的检查模板,而不是继续停留在纯文字指引层面。
|
||||
- 下一阶段 contract deepening 顺序现在也已更精确:先把 `diagram.generate` 保持为宿主无关 generation core,并把其下的 typed follow-through 视作已落地,再处理 packaging / semantic verification 的后续收敛,最后才重开更强的 CLI/public surface 声明。
|
||||
- 旧命令别名仍保留注册以保证兼容,但会被刻意排除在 capability manifest 导出之外。
|
||||
|
|
@ -150,7 +150,7 @@
|
|||
|---|---|---|---|
|
||||
| P0 | 围绕潜在 render-host runtime lane 的 source/build 收敛 | 当前源码已出现可复用的 runtime helper(`src/rendering/runtime/renderHostEntry.ts`、`src/rendering/preview/renderHostRuntimeClient.ts`),但 build/audit 真值仍只证明 `main.js` 单资产发货。下一步最高杠杆工作,是明确消除这层歧义:要么继续保持 source-only 候选态并写清非发货事实,要么同批落地真正的多入口构建边界 | `esbuild.config.mjs`、`scripts/audit-render-host-bundle.js`、`src/rendering/runtime/renderHostEntry.ts`、`src/rendering/preview/renderHostRuntimeClient.ts` |
|
||||
| P1 | 显式 path-based operations 的有界 public-CLI 提升 | maintainer helper 已证明 path-based operations 有真实需求,但只有当写入副作用与输出契约足够稳定、可文档化、可回归锁定时,才应该进入 public-safe slice | `src/maintainerCliBridge.ts`、`scripts/lib/maintainer-cli-operation-help.js`、`src/operations/registry.ts`、`src/tests/maintainerCliBridge.test.ts` |
|
||||
| P1 | retrieval / chapter-split 写入路径的契约与结果加固 | 面向 retrieval 的 note-processing 结果现在已为标题生成与研究总结显式暴露带 timing/size telemetry 的 machine-readable `localKnowledgeRetrieval` 摘要,shared maintainer helper 也已补上简洁 payload 示例;下一步成熟度提升点应是把同样的纪律继续推进到 chapter-split / diagram framing,而不是继续扩操作数量 | `src/chapterSplit.ts`、`src/localKnowledgeBase.ts`、`src/fileUtils.ts`、`src/searchUtils.ts`、`scripts/lib/maintainer-cli-operation-help.js`、`src/tests/chapterSplit.test.ts`、`src/tests/localKnowledgeTaskIntegration.test.ts` |
|
||||
| P1 | retrieval / chapter-split 写入路径的契约与结果加固 | 面向 retrieval 的 note-processing 结果现在已为标题生成、研究总结以及 artifact-mode 的 `diagram.generate` 显式暴露带 timing/size telemetry 的 machine-readable `localKnowledgeRetrieval` 摘要,shared maintainer helper 也已补上简洁 payload 示例;下一步成熟度提升点应是持续保持 chapter-split evidence framing 与 offline retrieval-quality evaluation 对齐,而不是继续扩操作数量 | `src/chapterSplit.ts`、`src/localKnowledgeBase.ts`、`src/fileUtils.ts`、`src/searchUtils.ts`、`src/main.ts`、`scripts/lib/maintainer-cli-operation-help.js`、`src/tests/chapterSplit.test.ts`、`src/tests/localKnowledgeTaskIntegration.test.ts`、`src/tests/diagramCommandArchitecture.test.ts` |
|
||||
| P2 | workflow/settings 打包 | Workflow DSL 与 output-path toggles 仍是有价值 metadata,但还不是稳定公共接口 | `src/workflowButtons.ts`, 设置驱动的输出控制 |
|
||||
|
||||
## 设置就绪度
|
||||
|
|
|
|||
128
src/main.ts
128
src/main.ts
|
|
@ -33,7 +33,12 @@ import {
|
|||
researchAndSummarizeFile,
|
||||
ResearchSummarizeResult
|
||||
} from './searchUtils';
|
||||
import { buildLocalKnowledgeBaseRetriever } from './localKnowledgeBase';
|
||||
import {
|
||||
buildLocalKnowledgeBaseRetriever,
|
||||
createEmptyLocalKnowledgeContextBuildResult,
|
||||
LocalKnowledgeRetrievalSummary,
|
||||
toLocalKnowledgeRetrievalSummary
|
||||
} from './localKnowledgeBase';
|
||||
import { stripMarkdownForSearch } from './markdownSectionUtils';
|
||||
import { ProgressModal } from './ui/ProgressModal';
|
||||
import { ErrorModal } from './ui/ErrorModal';
|
||||
|
|
@ -125,6 +130,12 @@ import {
|
|||
} from './operations/utilityCommandHostAdapter';
|
||||
import { ChapterSplitOptions, ChapterSplitResult, splitNoteByChapters } from './chapterSplit';
|
||||
|
||||
interface DiagramLocalKnowledgeContextResult {
|
||||
operationInput: DiagramOperationInput;
|
||||
localKnowledgeContextUsed: boolean;
|
||||
localKnowledgeRetrieval: LocalKnowledgeRetrievalSummary;
|
||||
}
|
||||
|
||||
export default class NotemdPlugin extends Plugin {
|
||||
settings: NotemdSettings;
|
||||
statusBarItem: HTMLElement;
|
||||
|
|
@ -133,6 +144,15 @@ export default class NotemdPlugin extends Plugin {
|
|||
private suppressConceptNotePathWarningOnce = false;
|
||||
currentProcessingFileBasename: { value: string | null } = { value: null }; // Keep track of the file being processed
|
||||
|
||||
private buildDiagramLocalKnowledgeQuery(operationInput: DiagramOperationInput): string {
|
||||
const strippedMarkdown = stripMarkdownForSearch(operationInput.sourceMarkdown);
|
||||
|
||||
return [
|
||||
operationInput.sourcePath?.split('/').pop()?.replace(/\.[^.]+$/u, ''),
|
||||
strippedMarkdown.slice(0, 1200)
|
||||
].filter((value): value is string => Boolean(value && value.trim())).join('\n');
|
||||
}
|
||||
|
||||
public getIsBusy(): boolean {
|
||||
return this.isBusy;
|
||||
}
|
||||
|
|
@ -1694,6 +1714,14 @@ export default class NotemdPlugin extends Plugin {
|
|||
actionLabel: string,
|
||||
i18n: DiagramCommandUiStrings = this.getUiStrings()
|
||||
): Promise<DiagramCommandExecutionDetails> {
|
||||
const localKnowledgeRetrieval = toLocalKnowledgeRetrievalSummary(
|
||||
createEmptyLocalKnowledgeContextBuildResult('', {
|
||||
currentFilePath: operationInput.sourcePath,
|
||||
topK: 0,
|
||||
slidingWindowSize: 0,
|
||||
maxSnippetChars: 0
|
||||
})
|
||||
);
|
||||
return runSaveMermaidDiagramExecutionWithHost(this.createDiagramCommandExecutionHost(), {
|
||||
file,
|
||||
operationInput,
|
||||
|
|
@ -1701,7 +1729,9 @@ export default class NotemdPlugin extends Plugin {
|
|||
modelName,
|
||||
reporter,
|
||||
actionLabel,
|
||||
i18n
|
||||
i18n,
|
||||
localKnowledgeContextUsed: false,
|
||||
localKnowledgeRetrieval
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -1715,19 +1745,19 @@ export default class NotemdPlugin extends Plugin {
|
|||
i18n: DiagramCommandUiStrings,
|
||||
executionMode: Extract<DiagramCommandExecutionMode, 'save-artifact' | 'preview-artifact'>
|
||||
): Promise<DiagramCommandExecutionDetails> {
|
||||
const effectiveOperationInput = executionMode === 'save-artifact'
|
||||
? await this.withDiagramLocalKnowledgeContext(operationInput, reporter)
|
||||
: operationInput;
|
||||
const localKnowledgeResult = await this.withDiagramLocalKnowledgeContext(operationInput, reporter);
|
||||
|
||||
return runArtifactDiagramExecutionWithHost(this.createDiagramCommandExecutionHost(), {
|
||||
file,
|
||||
operationInput: effectiveOperationInput,
|
||||
operationInput: localKnowledgeResult.operationInput,
|
||||
provider,
|
||||
modelName,
|
||||
reporter,
|
||||
actionLabel,
|
||||
i18n,
|
||||
executionMode
|
||||
executionMode,
|
||||
localKnowledgeContextUsed: localKnowledgeResult.localKnowledgeContextUsed,
|
||||
localKnowledgeRetrieval: localKnowledgeResult.localKnowledgeRetrieval
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -1750,37 +1780,77 @@ export default class NotemdPlugin extends Plugin {
|
|||
private async withDiagramLocalKnowledgeContext(
|
||||
operationInput: DiagramOperationInput,
|
||||
reporter: ProgressReporter
|
||||
): Promise<DiagramOperationInput> {
|
||||
if (!this.settings.enableLocalKnowledgeRetrieval || !this.settings.enableLocalKnowledgeForDiagramGeneration) {
|
||||
return operationInput;
|
||||
}
|
||||
|
||||
const retriever = await buildLocalKnowledgeBaseRetriever(this.app, this.settings, reporter);
|
||||
if (!retriever) {
|
||||
return operationInput;
|
||||
}
|
||||
|
||||
const strippedMarkdown = stripMarkdownForSearch(operationInput.sourceMarkdown);
|
||||
const query = [
|
||||
operationInput.sourcePath?.split('/').pop()?.replace(/\.[^.]+$/u, ''),
|
||||
strippedMarkdown.slice(0, 1200)
|
||||
].filter((value): value is string => Boolean(value && value.trim())).join('\n');
|
||||
|
||||
const localKnowledgeContext = retriever.buildContext(query, {
|
||||
): Promise<DiagramLocalKnowledgeContextResult> {
|
||||
const query = this.buildDiagramLocalKnowledgeQuery(operationInput);
|
||||
const localKnowledgeOptions = {
|
||||
currentFilePath: operationInput.sourcePath,
|
||||
topK: this.settings.localKnowledgeTopK,
|
||||
slidingWindowSize: this.settings.localKnowledgeSlidingWindowSize,
|
||||
maxSnippetChars: this.settings.localKnowledgeMaxSnippetChars
|
||||
};
|
||||
const emptyResult = (overrides?: Partial<Pick<
|
||||
ReturnType<typeof createEmptyLocalKnowledgeContextBuildResult>,
|
||||
'indexedFileCount' | 'indexedSectionCount' | 'excludeCurrentFileApplied' | 'indexBuildMs'
|
||||
>>): DiagramLocalKnowledgeContextResult => ({
|
||||
operationInput,
|
||||
localKnowledgeContextUsed: false,
|
||||
localKnowledgeRetrieval: toLocalKnowledgeRetrievalSummary(
|
||||
createEmptyLocalKnowledgeContextBuildResult(query, localKnowledgeOptions, overrides)
|
||||
)
|
||||
});
|
||||
|
||||
if (!localKnowledgeContext) {
|
||||
return operationInput;
|
||||
if (!this.settings.enableLocalKnowledgeRetrieval || !this.settings.enableLocalKnowledgeForDiagramGeneration) {
|
||||
return emptyResult();
|
||||
}
|
||||
|
||||
reporter.log(`Local knowledge retrieval returned context for diagram source "${operationInput.sourcePath ?? 'current note'}" (length: ${localKnowledgeContext.length}).`);
|
||||
const retriever = await buildLocalKnowledgeBaseRetriever(this.app, this.settings, reporter);
|
||||
if (!retriever) {
|
||||
return emptyResult({
|
||||
indexedFileCount: 0,
|
||||
indexedSectionCount: 0,
|
||||
excludeCurrentFileApplied: Boolean(
|
||||
this.settings.localKnowledgeExcludeCurrentFile && operationInput.sourcePath
|
||||
),
|
||||
indexBuildMs: 0
|
||||
});
|
||||
}
|
||||
|
||||
const localKnowledgeDetails = retriever.buildContextDetails(query, localKnowledgeOptions);
|
||||
const localKnowledgeContext = localKnowledgeDetails.context || '';
|
||||
const localKnowledgeRetrieval = toLocalKnowledgeRetrievalSummary(localKnowledgeDetails);
|
||||
|
||||
if (!localKnowledgeContext) {
|
||||
reporter.log(
|
||||
`Local knowledge retrieval returned no prompt context for diagram source `
|
||||
+ `"${operationInput.sourcePath ?? 'current note'}" `
|
||||
+ `(matched sections: ${localKnowledgeRetrieval.matchedSectionCount}, `
|
||||
+ `excluded current-file hits: ${localKnowledgeRetrieval.excludedCurrentFileHitCount}, `
|
||||
+ `build ${localKnowledgeRetrieval.indexBuildMs}ms, `
|
||||
+ `query ${localKnowledgeRetrieval.queryMs}ms).`
|
||||
);
|
||||
return {
|
||||
operationInput,
|
||||
localKnowledgeContextUsed: false,
|
||||
localKnowledgeRetrieval
|
||||
};
|
||||
}
|
||||
|
||||
reporter.log(
|
||||
`Local knowledge retrieval returned context for diagram source `
|
||||
+ `"${operationInput.sourcePath ?? 'current note'}" `
|
||||
+ `(length: ${localKnowledgeContext.length}, `
|
||||
+ `${localKnowledgeRetrieval.returnedHitCount} hit block(s), `
|
||||
+ `${localKnowledgeRetrieval.sourcePaths.length} file(s), `
|
||||
+ `build ${localKnowledgeRetrieval.indexBuildMs}ms, `
|
||||
+ `query ${localKnowledgeRetrieval.queryMs}ms).`
|
||||
);
|
||||
return {
|
||||
...operationInput,
|
||||
localKnowledgeContext
|
||||
operationInput: {
|
||||
...operationInput,
|
||||
localKnowledgeContext
|
||||
},
|
||||
localKnowledgeContextUsed: true,
|
||||
localKnowledgeRetrieval
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import {
|
|||
DiagramCommandHostAdapter,
|
||||
DiagramCommandUiStrings
|
||||
} from './diagramCommandHostAdapter';
|
||||
import { LocalKnowledgeRetrievalSummary } from '../localKnowledgeBase';
|
||||
import { LLMProviderConfig, NotemdSettings, ProgressReporter } from '../types';
|
||||
|
||||
export interface DiagramCommandExecutionHost {
|
||||
|
|
@ -27,6 +28,8 @@ export interface RunSaveMermaidDiagramExecutionParams {
|
|||
reporter: ProgressReporter;
|
||||
actionLabel: string;
|
||||
i18n: DiagramCommandUiStrings;
|
||||
localKnowledgeContextUsed: boolean;
|
||||
localKnowledgeRetrieval: LocalKnowledgeRetrievalSummary;
|
||||
}
|
||||
|
||||
export interface RunArtifactDiagramExecutionParams extends RunSaveMermaidDiagramExecutionParams {
|
||||
|
|
@ -72,6 +75,8 @@ export async function runSaveMermaidDiagramExecutionWithHost(
|
|||
autoFixAttempted: settings.autoMermaidFixAfterGenerate,
|
||||
artifactTarget: result.artifact.target
|
||||
},
|
||||
localKnowledgeContextUsed: params.localKnowledgeContextUsed,
|
||||
localKnowledgeRetrieval: params.localKnowledgeRetrieval,
|
||||
outputPath,
|
||||
previewOpened: false
|
||||
};
|
||||
|
|
@ -127,6 +132,8 @@ export async function runArtifactDiagramExecutionWithHost(
|
|||
autoFixAttempted,
|
||||
artifactTarget: result.artifact.target
|
||||
},
|
||||
localKnowledgeContextUsed: params.localKnowledgeContextUsed,
|
||||
localKnowledgeRetrieval: params.localKnowledgeRetrieval,
|
||||
outputPath,
|
||||
previewOpened
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { TFile } from 'obsidian';
|
|||
import { formatI18n } from '../i18n';
|
||||
import { DiagramGenerationResult } from '../diagram/diagramGenerationService';
|
||||
import { DiagramIntent, isSupportedDiagramIntent } from '../diagram/types';
|
||||
import { LocalKnowledgeRetrievalSummary } from '../localKnowledgeBase';
|
||||
import { RenderArtifact } from '../rendering/types';
|
||||
import { DiagramOperationInput, DiagramOperationExecutionMode, buildDiagramOperationInput } from '../diagram/diagramGenerationService';
|
||||
import { LLMProviderConfig, NotemdSettings, ProgressReporter } from '../types';
|
||||
|
|
@ -50,6 +51,8 @@ export interface DiagramCommandUiStrings {
|
|||
export interface DiagramCommandExecutionDetails {
|
||||
generation: DiagramGenerationResult;
|
||||
followThrough: DiagramCommandFollowThroughDetails;
|
||||
localKnowledgeContextUsed: boolean;
|
||||
localKnowledgeRetrieval: LocalKnowledgeRetrievalSummary;
|
||||
outputPath?: string;
|
||||
previewOpened: boolean;
|
||||
}
|
||||
|
|
@ -71,6 +74,8 @@ export type DiagramCommandRunResult =
|
|||
operationInput: DiagramOperationInput;
|
||||
generation: DiagramGenerationResult;
|
||||
followThrough: DiagramCommandFollowThroughDetails;
|
||||
localKnowledgeContextUsed: boolean;
|
||||
localKnowledgeRetrieval: LocalKnowledgeRetrievalSummary;
|
||||
outputPath?: string;
|
||||
previewOpened: boolean;
|
||||
}
|
||||
|
|
@ -649,6 +654,8 @@ export async function runGenerateDiagramCommandWithHost(
|
|||
operationInput,
|
||||
generation: executionDetails.generation,
|
||||
followThrough: executionDetails.followThrough,
|
||||
localKnowledgeContextUsed: executionDetails.localKnowledgeContextUsed,
|
||||
localKnowledgeRetrieval: executionDetails.localKnowledgeRetrieval,
|
||||
outputPath: executionDetails.outputPath,
|
||||
previewOpened: executionDetails.previewOpened
|
||||
};
|
||||
|
|
|
|||
|
|
@ -139,6 +139,28 @@ const DIAGRAM_GENERATE_RESULT_SCHEMA: OperationSchema = {
|
|||
actionLabel: { type: 'string' },
|
||||
operationInput: { type: 'object' },
|
||||
generation: { type: 'object' },
|
||||
localKnowledgeContextUsed: { type: 'boolean' },
|
||||
localKnowledgeRetrieval: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
indexedFileCount: { type: 'number' },
|
||||
indexedSectionCount: { type: 'number' },
|
||||
matchedSectionCount: { type: 'number' },
|
||||
returnedHitCount: { type: 'number' },
|
||||
expandedSectionCount: { type: 'number' },
|
||||
sourcePaths: {
|
||||
type: 'array',
|
||||
items: { type: 'string' }
|
||||
},
|
||||
usedSlidingWindowSize: { type: 'number' },
|
||||
requestedTopK: { type: 'number' },
|
||||
indexBuildMs: { type: 'number' },
|
||||
queryMs: { type: 'number' },
|
||||
contextCharCount: { type: 'number' },
|
||||
excludeCurrentFileApplied: { type: 'boolean' },
|
||||
excludedCurrentFileHitCount: { type: 'number' }
|
||||
}
|
||||
},
|
||||
followThrough: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
|
|
|
|||
|
|
@ -91,6 +91,8 @@ describe('CLI invocation contract', () => {
|
|||
operationInput: expect.any(Object),
|
||||
generation: expect.any(Object),
|
||||
followThrough: expect.any(Object),
|
||||
localKnowledgeContextUsed: expect.any(Object),
|
||||
localKnowledgeRetrieval: expect.any(Object),
|
||||
outputPath: expect.any(Object),
|
||||
previewOpened: expect.any(Object),
|
||||
errorMessage: expect.any(Object)
|
||||
|
|
|
|||
|
|
@ -190,27 +190,27 @@ describe('diagram command architecture', () => {
|
|||
test('artifact execution injects local knowledge context when diagram retrieval is enabled', async () => {
|
||||
plugin.settings.enableLocalKnowledgeRetrieval = true;
|
||||
plugin.settings.enableLocalKnowledgeForDiagramGeneration = true;
|
||||
const buildContextDetails = jest.fn(() => ({
|
||||
query: 'index',
|
||||
context: 'Path: Knowledge/Reference.md\nExcerpt: Deployment topology.',
|
||||
indexedFileCount: 1,
|
||||
indexedSectionCount: 1,
|
||||
matchedSectionCount: 1,
|
||||
returnedHitCount: 1,
|
||||
expandedSectionCount: 1,
|
||||
sourcePaths: ['Knowledge/Reference.md'],
|
||||
usedSlidingWindowSize: 0,
|
||||
requestedTopK: 1,
|
||||
indexBuildMs: 5,
|
||||
queryMs: 2,
|
||||
contextCharCount: 55,
|
||||
excludeCurrentFileApplied: true,
|
||||
excludedCurrentFileHitCount: 0
|
||||
}));
|
||||
jest.spyOn(localKnowledgeBase, 'buildLocalKnowledgeBaseRetriever').mockResolvedValue({
|
||||
indexedFileCount: 1,
|
||||
indexedSectionCount: 1,
|
||||
buildContextDetails: jest.fn(() => ({
|
||||
query: 'index',
|
||||
context: 'Path: Knowledge/Reference.md\nExcerpt: Deployment topology.',
|
||||
indexedFileCount: 1,
|
||||
indexedSectionCount: 1,
|
||||
matchedSectionCount: 1,
|
||||
returnedHitCount: 1,
|
||||
expandedSectionCount: 1,
|
||||
sourcePaths: ['Knowledge/Reference.md'],
|
||||
usedSlidingWindowSize: 0,
|
||||
requestedTopK: 1,
|
||||
indexBuildMs: 5,
|
||||
queryMs: 2,
|
||||
contextCharCount: 55,
|
||||
excludeCurrentFileApplied: true,
|
||||
excludedCurrentFileHitCount: 0
|
||||
})),
|
||||
buildContext: jest.fn(() => 'Path: Knowledge/Reference.md\nExcerpt: Deployment topology.')
|
||||
buildContextDetails
|
||||
} as any);
|
||||
const executionSpy = jest.spyOn(diagramCommandExecution, 'runArtifactDiagramExecutionWithHost').mockResolvedValue({
|
||||
generation: {
|
||||
|
|
@ -224,10 +224,26 @@ describe('diagram command architecture', () => {
|
|||
autoFixAttempted: false,
|
||||
artifactTarget: 'mermaid'
|
||||
},
|
||||
localKnowledgeContextUsed: true,
|
||||
localKnowledgeRetrieval: {
|
||||
indexedFileCount: 1,
|
||||
indexedSectionCount: 1,
|
||||
matchedSectionCount: 1,
|
||||
returnedHitCount: 1,
|
||||
expandedSectionCount: 1,
|
||||
sourcePaths: ['Knowledge/Reference.md'],
|
||||
usedSlidingWindowSize: 0,
|
||||
requestedTopK: 1,
|
||||
indexBuildMs: 5,
|
||||
queryMs: 2,
|
||||
contextCharCount: 55,
|
||||
excludeCurrentFileApplied: true,
|
||||
excludedCurrentFileHitCount: 0
|
||||
},
|
||||
previewOpened: false
|
||||
});
|
||||
|
||||
await (plugin as any).executeArtifactDiagramCommand(
|
||||
const result = await (plugin as any).executeArtifactDiagramCommand(
|
||||
file,
|
||||
{
|
||||
sourcePath: file.path,
|
||||
|
|
@ -251,6 +267,23 @@ describe('diagram command architecture', () => {
|
|||
})
|
||||
})
|
||||
);
|
||||
expect(buildContextDetails).toHaveBeenCalledWith(
|
||||
expect.stringContaining('Topic'),
|
||||
expect.objectContaining({
|
||||
currentFilePath: 'Notes/Topic.md',
|
||||
topK: mockSettings.localKnowledgeTopK,
|
||||
slidingWindowSize: mockSettings.localKnowledgeSlidingWindowSize
|
||||
})
|
||||
);
|
||||
expect(result).toEqual(expect.objectContaining({
|
||||
localKnowledgeContextUsed: true,
|
||||
localKnowledgeRetrieval: expect.objectContaining({
|
||||
returnedHitCount: 1,
|
||||
sourcePaths: ['Knowledge/Reference.md'],
|
||||
indexBuildMs: 5,
|
||||
queryMs: 2
|
||||
})
|
||||
}));
|
||||
});
|
||||
|
||||
test('generate command delegates busy and orchestration to extracted diagram host adapter wrapper', async () => {
|
||||
|
|
@ -272,6 +305,22 @@ describe('diagram command architecture', () => {
|
|||
spec: {} as any,
|
||||
artifact: {} as any
|
||||
},
|
||||
localKnowledgeContextUsed: false,
|
||||
localKnowledgeRetrieval: {
|
||||
indexedFileCount: 0,
|
||||
indexedSectionCount: 0,
|
||||
matchedSectionCount: 0,
|
||||
returnedHitCount: 0,
|
||||
expandedSectionCount: 0,
|
||||
sourcePaths: [],
|
||||
usedSlidingWindowSize: 0,
|
||||
requestedTopK: 0,
|
||||
indexBuildMs: 0,
|
||||
queryMs: 0,
|
||||
contextCharCount: 0,
|
||||
excludeCurrentFileApplied: false,
|
||||
excludedCurrentFileHitCount: 0
|
||||
},
|
||||
outputPath: 'Notes/Topic_diagram.canvas',
|
||||
previewOpened: true
|
||||
} as any);
|
||||
|
|
@ -324,6 +373,22 @@ describe('diagram command architecture', () => {
|
|||
autoFixAttempted: false,
|
||||
artifactTarget: 'mermaid'
|
||||
},
|
||||
localKnowledgeContextUsed: false,
|
||||
localKnowledgeRetrieval: {
|
||||
indexedFileCount: 0,
|
||||
indexedSectionCount: 0,
|
||||
matchedSectionCount: 0,
|
||||
returnedHitCount: 0,
|
||||
expandedSectionCount: 0,
|
||||
sourcePaths: [],
|
||||
usedSlidingWindowSize: 0,
|
||||
requestedTopK: 0,
|
||||
indexBuildMs: 0,
|
||||
queryMs: 0,
|
||||
contextCharCount: 0,
|
||||
excludeCurrentFileApplied: false,
|
||||
excludedCurrentFileHitCount: 0
|
||||
},
|
||||
outputPath: 'Notes/Topic_diagram.md',
|
||||
previewOpened: true
|
||||
});
|
||||
|
|
|
|||
|
|
@ -76,7 +76,23 @@ describe('diagram command execution', () => {
|
|||
modelName: mockSettings.providers[0].model,
|
||||
reporter: reporter as any,
|
||||
actionLabel: 'Summarize diagram',
|
||||
i18n: STRINGS_EN as any
|
||||
i18n: STRINGS_EN as any,
|
||||
localKnowledgeContextUsed: false,
|
||||
localKnowledgeRetrieval: {
|
||||
indexedFileCount: 0,
|
||||
indexedSectionCount: 0,
|
||||
matchedSectionCount: 0,
|
||||
returnedHitCount: 0,
|
||||
expandedSectionCount: 0,
|
||||
sourcePaths: [],
|
||||
usedSlidingWindowSize: 0,
|
||||
requestedTopK: 0,
|
||||
indexBuildMs: 0,
|
||||
queryMs: 0,
|
||||
contextCharCount: 0,
|
||||
excludeCurrentFileApplied: false,
|
||||
excludedCurrentFileHitCount: 0
|
||||
}
|
||||
});
|
||||
|
||||
expect(runSpy).toHaveBeenCalledWith(expect.objectContaining({
|
||||
|
|
@ -103,6 +119,22 @@ describe('diagram command execution', () => {
|
|||
autoFixAttempted: mockSettings.autoMermaidFixAfterGenerate,
|
||||
artifactTarget: 'mermaid'
|
||||
},
|
||||
localKnowledgeContextUsed: false,
|
||||
localKnowledgeRetrieval: {
|
||||
indexedFileCount: 0,
|
||||
indexedSectionCount: 0,
|
||||
matchedSectionCount: 0,
|
||||
returnedHitCount: 0,
|
||||
expandedSectionCount: 0,
|
||||
sourcePaths: [],
|
||||
usedSlidingWindowSize: 0,
|
||||
requestedTopK: 0,
|
||||
indexBuildMs: 0,
|
||||
queryMs: 0,
|
||||
contextCharCount: 0,
|
||||
excludeCurrentFileApplied: false,
|
||||
excludedCurrentFileHitCount: 0
|
||||
},
|
||||
outputPath: 'Notes/Topic_diagram.md',
|
||||
previewOpened: false
|
||||
});
|
||||
|
|
@ -141,7 +173,23 @@ describe('diagram command execution', () => {
|
|||
reporter: reporter as any,
|
||||
actionLabel: 'Generate diagram',
|
||||
i18n: STRINGS_EN as any,
|
||||
executionMode: 'save-artifact'
|
||||
executionMode: 'save-artifact',
|
||||
localKnowledgeContextUsed: true,
|
||||
localKnowledgeRetrieval: {
|
||||
indexedFileCount: 3,
|
||||
indexedSectionCount: 9,
|
||||
matchedSectionCount: 2,
|
||||
returnedHitCount: 1,
|
||||
expandedSectionCount: 2,
|
||||
sourcePaths: ['Knowledge/Topology.md'],
|
||||
usedSlidingWindowSize: 1,
|
||||
requestedTopK: 3,
|
||||
indexBuildMs: 8,
|
||||
queryMs: 4,
|
||||
contextCharCount: 88,
|
||||
excludeCurrentFileApplied: true,
|
||||
excludedCurrentFileHitCount: 0
|
||||
}
|
||||
});
|
||||
|
||||
expect(runSpy).toHaveBeenCalledWith(expect.objectContaining({
|
||||
|
|
@ -165,6 +213,22 @@ describe('diagram command execution', () => {
|
|||
autoFixAttempted: false,
|
||||
artifactTarget: 'json-canvas'
|
||||
},
|
||||
localKnowledgeContextUsed: true,
|
||||
localKnowledgeRetrieval: {
|
||||
indexedFileCount: 3,
|
||||
indexedSectionCount: 9,
|
||||
matchedSectionCount: 2,
|
||||
returnedHitCount: 1,
|
||||
expandedSectionCount: 2,
|
||||
sourcePaths: ['Knowledge/Topology.md'],
|
||||
usedSlidingWindowSize: 1,
|
||||
requestedTopK: 3,
|
||||
indexBuildMs: 8,
|
||||
queryMs: 4,
|
||||
contextCharCount: 88,
|
||||
excludeCurrentFileApplied: true,
|
||||
excludedCurrentFileHitCount: 0
|
||||
},
|
||||
outputPath: 'Notes/Topic_diagram.canvas',
|
||||
previewOpened: true
|
||||
});
|
||||
|
|
@ -202,7 +266,23 @@ describe('diagram command execution', () => {
|
|||
reporter: reporter as any,
|
||||
actionLabel: 'Preview diagram',
|
||||
i18n: STRINGS_EN as any,
|
||||
executionMode: 'preview-artifact'
|
||||
executionMode: 'preview-artifact',
|
||||
localKnowledgeContextUsed: true,
|
||||
localKnowledgeRetrieval: {
|
||||
indexedFileCount: 2,
|
||||
indexedSectionCount: 4,
|
||||
matchedSectionCount: 1,
|
||||
returnedHitCount: 1,
|
||||
expandedSectionCount: 1,
|
||||
sourcePaths: ['Knowledge/Preview.md'],
|
||||
usedSlidingWindowSize: 0,
|
||||
requestedTopK: 2,
|
||||
indexBuildMs: 6,
|
||||
queryMs: 3,
|
||||
contextCharCount: 51,
|
||||
excludeCurrentFileApplied: true,
|
||||
excludedCurrentFileHitCount: 0
|
||||
}
|
||||
});
|
||||
|
||||
expect(result).toEqual({
|
||||
|
|
@ -214,6 +294,22 @@ describe('diagram command execution', () => {
|
|||
autoFixAttempted: false,
|
||||
artifactTarget: 'mermaid'
|
||||
},
|
||||
localKnowledgeContextUsed: true,
|
||||
localKnowledgeRetrieval: {
|
||||
indexedFileCount: 2,
|
||||
indexedSectionCount: 4,
|
||||
matchedSectionCount: 1,
|
||||
returnedHitCount: 1,
|
||||
expandedSectionCount: 1,
|
||||
sourcePaths: ['Knowledge/Preview.md'],
|
||||
usedSlidingWindowSize: 0,
|
||||
requestedTopK: 2,
|
||||
indexBuildMs: 6,
|
||||
queryMs: 3,
|
||||
contextCharCount: 51,
|
||||
excludeCurrentFileApplied: true,
|
||||
excludedCurrentFileHitCount: 0
|
||||
},
|
||||
outputPath: undefined,
|
||||
previewOpened: true
|
||||
});
|
||||
|
|
|
|||
|
|
@ -69,6 +69,22 @@ function createDiagramHost() {
|
|||
autoFixAttempted: false,
|
||||
artifactTarget: 'json-canvas'
|
||||
},
|
||||
localKnowledgeContextUsed: true,
|
||||
localKnowledgeRetrieval: {
|
||||
indexedFileCount: 2,
|
||||
indexedSectionCount: 5,
|
||||
matchedSectionCount: 1,
|
||||
returnedHitCount: 1,
|
||||
expandedSectionCount: 1,
|
||||
sourcePaths: ['Knowledge/Reference.md'],
|
||||
usedSlidingWindowSize: 0,
|
||||
requestedTopK: 3,
|
||||
indexBuildMs: 9,
|
||||
queryMs: 4,
|
||||
contextCharCount: 64,
|
||||
excludeCurrentFileApplied: true,
|
||||
excludedCurrentFileHitCount: 0
|
||||
},
|
||||
outputPath: 'Notes/Topic_diagram.canvas',
|
||||
previewOpened: true
|
||||
}),
|
||||
|
|
@ -121,6 +137,22 @@ describe('diagram command host adapter', () => {
|
|||
autoFixAttempted: false,
|
||||
artifactTarget: 'json-canvas'
|
||||
},
|
||||
localKnowledgeContextUsed: true,
|
||||
localKnowledgeRetrieval: {
|
||||
indexedFileCount: 2,
|
||||
indexedSectionCount: 5,
|
||||
matchedSectionCount: 1,
|
||||
returnedHitCount: 1,
|
||||
expandedSectionCount: 1,
|
||||
sourcePaths: ['Knowledge/Reference.md'],
|
||||
usedSlidingWindowSize: 0,
|
||||
requestedTopK: 3,
|
||||
indexBuildMs: 9,
|
||||
queryMs: 4,
|
||||
contextCharCount: 64,
|
||||
excludeCurrentFileApplied: true,
|
||||
excludedCurrentFileHitCount: 0
|
||||
},
|
||||
outputPath: 'Notes/Topic_diagram.canvas',
|
||||
previewOpened: true
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue