diff --git a/docs/brainstorms/2026-05-20-unified-follow-through-matrix.md b/docs/brainstorms/2026-05-20-unified-follow-through-matrix.md index 8ad39f7c..345ebbfd 100644 --- a/docs/brainstorms/2026-05-20-unified-follow-through-matrix.md +++ b/docs/brainstorms/2026-05-20-unified-follow-through-matrix.md @@ -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. diff --git a/docs/brainstorms/2026-05-20-unified-follow-through-matrix.zh-CN.md b/docs/brainstorms/2026-05-20-unified-follow-through-matrix.zh-CN.md index 48e14498..a4e2f4ff 100644 --- a/docs/brainstorms/2026-05-20-unified-follow-through-matrix.zh-CN.md +++ b/docs/brainstorms/2026-05-20-unified-follow-through-matrix.zh-CN.md @@ -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。 diff --git a/docs/brainstorms/2026-05-25-post-bounded-recovery-audit-and-next-level-direction.md b/docs/brainstorms/2026-05-25-post-bounded-recovery-audit-and-next-level-direction.md index 263dab3c..ac6aa74f 100644 --- a/docs/brainstorms/2026-05-25-post-bounded-recovery-audit-and-next-level-direction.md +++ b/docs/brainstorms/2026-05-25-post-bounded-recovery-audit-and-next-level-direction.md @@ -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. diff --git a/docs/brainstorms/2026-05-25-post-bounded-recovery-audit-and-next-level-direction.zh-CN.md b/docs/brainstorms/2026-05-25-post-bounded-recovery-audit-and-next-level-direction.zh-CN.md index b7d48ed0..33d17adb 100644 --- a/docs/brainstorms/2026-05-25-post-bounded-recovery-audit-and-next-level-direction.zh-CN.md +++ b/docs/brainstorms/2026-05-25-post-bounded-recovery-audit-and-next-level-direction.zh-CN.md @@ -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 等调优文档。 diff --git a/docs/maintainer/notemd-cli-capability-matrix.md b/docs/maintainer/notemd-cli-capability-matrix.md index 33b2832a..b765201b 100644 --- a/docs/maintainer/notemd-cli-capability-matrix.md +++ b/docs/maintainer/notemd-cli-capability-matrix.md @@ -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 diff --git a/docs/maintainer/notemd-cli-capability-matrix.zh-CN.md b/docs/maintainer/notemd-cli-capability-matrix.zh-CN.md index efa8d16f..38aaad83 100644 --- a/docs/maintainer/notemd-cli-capability-matrix.zh-CN.md +++ b/docs/maintainer/notemd-cli-capability-matrix.zh-CN.md @@ -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`, 设置驱动的输出控制 | ## 设置就绪度 diff --git a/src/main.ts b/src/main.ts index 37e5df60..62461bf5 100644 --- a/src/main.ts +++ b/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 { + 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 ): Promise { - 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 { - 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 { + 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, + '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 }; } diff --git a/src/operations/diagramCommandExecution.ts b/src/operations/diagramCommandExecution.ts index 30558db9..66ac5fb8 100644 --- a/src/operations/diagramCommandExecution.ts +++ b/src/operations/diagramCommandExecution.ts @@ -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 }; diff --git a/src/operations/diagramCommandHostAdapter.ts b/src/operations/diagramCommandHostAdapter.ts index d1f933af..72263578 100644 --- a/src/operations/diagramCommandHostAdapter.ts +++ b/src/operations/diagramCommandHostAdapter.ts @@ -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 }; diff --git a/src/operations/registry.ts b/src/operations/registry.ts index 0c372463..1432b801 100644 --- a/src/operations/registry.ts +++ b/src/operations/registry.ts @@ -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: { diff --git a/src/tests/cliContracts.test.ts b/src/tests/cliContracts.test.ts index 7ee61d9f..19cae306 100644 --- a/src/tests/cliContracts.test.ts +++ b/src/tests/cliContracts.test.ts @@ -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) diff --git a/src/tests/diagramCommandArchitecture.test.ts b/src/tests/diagramCommandArchitecture.test.ts index 4e7a5bd6..66b08ec3 100644 --- a/src/tests/diagramCommandArchitecture.test.ts +++ b/src/tests/diagramCommandArchitecture.test.ts @@ -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 }); diff --git a/src/tests/diagramCommandExecution.test.ts b/src/tests/diagramCommandExecution.test.ts index 68e21110..c0a3cf10 100644 --- a/src/tests/diagramCommandExecution.test.ts +++ b/src/tests/diagramCommandExecution.test.ts @@ -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 }); diff --git a/src/tests/diagramCommandHostAdapter.test.ts b/src/tests/diagramCommandHostAdapter.test.ts index 258c93fb..268fefb5 100644 --- a/src/tests/diagramCommandHostAdapter.test.ts +++ b/src/tests/diagramCommandHostAdapter.test.ts @@ -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 });