noteconnection 1.7.0 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +674 -21
- package/README.md +242 -62
- package/dist/src/agent_workspace.contract.parity.test.js +475 -0
- package/dist/src/agent_workspace.frontend.test.js +9989 -0
- package/dist/src/agent_workspace.locale.contract.test.js +95 -0
- package/dist/src/agent_workspace.runtime.behavior.test.js +5072 -0
- package/dist/src/copy.assets.contract.test.js +130 -0
- package/dist/src/core/PathBridge.js +28 -3
- package/dist/src/export/WorkspaceExportBundle.js +1130 -0
- package/dist/src/export/WorkspaceExportBundle.test.js +1480 -0
- package/dist/src/export/index.js +18 -0
- package/dist/src/export/types.js +2 -0
- package/dist/src/fixrisk.issue.verifier.contract.test.js +3 -1
- package/dist/src/foundation.ann.runtime.contract.test.js +81 -0
- package/dist/src/foundation.release.evidence.contract.test.js +406 -0
- package/dist/src/foundation.sqlite.runtime.contract.test.js +82 -0
- package/dist/src/frontend/README.md +242 -62
- package/dist/src/frontend/agent_workspace.js +5353 -0
- package/dist/src/frontend/agent_workspace_runtime.js +4434 -0
- package/dist/src/frontend/analysis.js +31 -4
- package/dist/src/frontend/app.js +2178 -62
- package/dist/src/frontend/focus_mode_interactions.js +33 -0
- package/dist/src/frontend/godot_future_path_renderer.js +540 -0
- package/dist/src/frontend/godot_tree_interactions.js +178 -0
- package/dist/src/frontend/graph_state.mjs +105 -0
- package/dist/src/frontend/hosted_future_path_runtime.js +157 -0
- package/dist/src/frontend/i18n.mjs +186 -0
- package/dist/src/frontend/index.html +641 -266
- package/dist/src/frontend/layout_gpu.js +12 -4
- package/dist/src/frontend/locales/en.json +721 -5
- package/dist/src/frontend/locales/zh.json +721 -5
- package/dist/src/frontend/main.mjs +60 -0
- package/dist/src/frontend/markdown_runtime.js +827 -0
- package/dist/src/frontend/notemd.css +49 -0
- package/dist/src/frontend/notemd.html +7 -1
- package/dist/src/frontend/notemd.js +64 -0
- package/dist/src/frontend/path.html +107 -0
- package/dist/src/frontend/path_app.js +2108 -130
- package/dist/src/frontend/path_layout.mjs +143 -0
- package/dist/src/frontend/path_mermaid_utils.mjs +108 -0
- package/dist/src/frontend/path_modules_bridge.js +486 -0
- package/dist/src/frontend/path_state.mjs +118 -0
- package/dist/src/frontend/path_styles.css +146 -0
- package/dist/src/frontend/path_worker_bridge.mjs +85 -0
- package/dist/src/frontend/reader.js +393 -33
- package/dist/src/frontend/runtime_bridge.js +67 -54
- package/dist/src/frontend/runtime_bridge.mjs +279 -0
- package/dist/src/frontend/settings.js +130 -12
- package/dist/src/frontend/source_manager.js +190 -21
- package/dist/src/frontend/styles.css +2720 -72
- package/dist/src/frontend/workbench_state.mjs +101 -0
- package/dist/src/frontend/workspace_panes.js +10168 -0
- package/dist/src/frontend.locale.contract.test.js +62 -0
- package/dist/src/godot.sidecar.bootstrap.contract.test.js +244 -0
- package/dist/src/indexing/IndexLifecycle.js +195 -0
- package/dist/src/indexing/IndexLifecycle.test.js +49 -0
- package/dist/src/indexing/SegmentBuilder.js +64 -0
- package/dist/src/indexing/UnitBuilder.js +48 -0
- package/dist/src/indexing/types.js +2 -0
- package/dist/src/knowledge.api.contract.test.js +170 -0
- package/dist/src/learning/KnowledgeLearningPlatform.js +10386 -0
- package/dist/src/learning/KnowledgeLearningPlatform.persistence.test.js +327 -0
- package/dist/src/learning/KnowledgeLearningPlatform.program-f.test.js +99 -0
- package/dist/src/learning/KnowledgeLearningPlatform.test.js +2971 -0
- package/dist/src/learning/KnowledgeWorkspaceConversationRegression.js +2974 -0
- package/dist/src/learning/KnowledgeWorkspaceConversationRegression.test.js +3928 -0
- package/dist/src/learning/answerReleaseReview.js +4319 -0
- package/dist/src/learning/answerReleaseReview.test.js +2888 -0
- package/dist/src/learning/api.js +2 -0
- package/dist/src/learning/conversationComposer.js +1480 -0
- package/dist/src/learning/conversationComposer.test.js +1817 -0
- package/dist/src/learning/domains/ConversationManager.js +53 -0
- package/dist/src/learning/domains/KnowledgeIngestor.js +238 -0
- package/dist/src/learning/domains/KnowledgeQuerier.js +187 -0
- package/dist/src/learning/domains/MasteryEngine.js +387 -0
- package/dist/src/learning/domains/MemoryPolicyManager.js +408 -0
- package/dist/src/learning/domains/QualityEvaluator.js +307 -0
- package/dist/src/learning/domains/TutorRouter.js +313 -0
- package/dist/src/learning/domains/index.js +33 -0
- package/dist/src/learning/domains/types.js +7 -0
- package/dist/src/learning/errors.js +29 -0
- package/dist/src/learning/evidenceContextAssembler.js +1176 -0
- package/dist/src/learning/evidenceContextAssembler.test.js +6332 -0
- package/dist/src/learning/graphContextAssembler.js +870 -0
- package/dist/src/learning/graphContextAssembler.test.js +1033 -0
- package/dist/src/learning/index.js +28 -0
- package/dist/src/learning/queryBackend.js +1898 -0
- package/dist/src/learning/queryBackend.test.js +955 -0
- package/dist/src/learning/ragContextPack.js +257 -0
- package/dist/src/learning/ragContextPack.test.js +160 -0
- package/dist/src/learning/ragPublicText.js +38 -0
- package/dist/src/learning/ragSufficiencyJudge.js +161 -0
- package/dist/src/learning/ragSufficiencyJudge.test.js +177 -0
- package/dist/src/learning/ragSufficiencyProviderJudge.js +227 -0
- package/dist/src/learning/ragSufficiencyProviderJudge.test.js +156 -0
- package/dist/src/learning/requestNormalization.js +198 -0
- package/dist/src/learning/runtimeCapability.js +4677 -0
- package/dist/src/learning/runtimeCapability.test.js +3635 -0
- package/dist/src/learning/store.js +1240 -0
- package/dist/src/learning/store.test.js +1126 -0
- package/dist/src/learning/tutorAdapter.js +2 -0
- package/dist/src/learning/types.js +2 -0
- package/dist/src/learning/vectorAccelerationAdapter.js +942 -0
- package/dist/src/learning/vectorAccelerationAdapter.test.js +382 -0
- package/dist/src/lfs.asset.policy.contract.test.js +153 -0
- package/dist/src/license.policy.contract.test.js +66 -0
- package/dist/src/memory/MemoryGovernance.js +74 -0
- package/dist/src/memory/MemoryGovernance.test.js +46 -0
- package/dist/src/memory/types.js +2 -0
- package/dist/src/mermaid.frontend.guard.contract.test.js +77 -0
- package/dist/src/middleware/auth.js +17 -0
- package/dist/src/middleware/body-parser.js +45 -0
- package/dist/src/middleware/cors.js +44 -0
- package/dist/src/middleware/index.js +21 -0
- package/dist/src/middleware/request-trace.js +96 -0
- package/dist/src/notemd/AppConfigToml.js +6 -4
- package/dist/src/notemd/MermaidProcessor.js +400 -50
- package/dist/src/notemd/NotemdService.js +498 -13
- package/dist/src/notemd/PromptManager.js +15 -0
- package/dist/src/notemd/cli/commands.js +357 -0
- package/dist/src/notemd/cli/dispatcher.js +225 -0
- package/dist/src/notemd/cli/index.js +169 -0
- package/dist/src/notemd/cli/parser.js +68 -0
- package/dist/src/notemd/cli/types.js +2 -0
- package/dist/src/notemd/constants.js +43 -0
- package/dist/src/notemd/diagram/diagramGenerationService.js +78 -0
- package/dist/src/notemd/diagram/diagramSpec.js +79 -0
- package/dist/src/notemd/diagram/diagramSpecResponseParser.js +131 -0
- package/dist/src/notemd/diagram/intent.js +95 -0
- package/dist/src/notemd/diagram/planner.js +71 -0
- package/dist/src/notemd/diagram/prompts/diagramSpecPrompt.js +42 -0
- package/dist/src/notemd/diagram/types.js +18 -0
- package/dist/src/notemd/index.js +26 -0
- package/dist/src/notemd/operations/capabilityManifest.js +23 -0
- package/dist/src/notemd/operations/cliContracts.js +17 -0
- package/dist/src/notemd/operations/configProfileCommands.js +85 -0
- package/dist/src/notemd/operations/registry.contract.test.js +95 -0
- package/dist/src/notemd/operations/registry.js +991 -0
- package/dist/src/notemd/operations/types.js +2 -0
- package/dist/src/notemd/providerDiagnostics.js +220 -0
- package/dist/src/notemd/providerProfiles.js +42 -0
- package/dist/src/notemd/providerTemplates.js +231 -0
- package/dist/src/notemd/search/DuckDuckGoProvider.js +39 -0
- package/dist/src/notemd/search/SearchManager.js +13 -0
- package/dist/src/notemd/search/SearchProvider.js +2 -0
- package/dist/src/notemd/search/TavilyProvider.js +44 -0
- package/dist/src/notemd.agent.manifest.test.js +85 -0
- package/dist/src/notemd.api.contract.test.js +14 -1
- package/dist/src/notemd.app_config_toml.test.js +2 -1
- package/dist/src/notemd.batch.workflow.test.js +117 -0
- package/dist/src/notemd.cli.e2e.test.js +136 -0
- package/dist/src/notemd.core.test.js +51 -0
- package/dist/src/notemd.diagram.pipeline.test.js +233 -0
- package/dist/src/notemd.providerTemplates.test.js +34 -0
- package/dist/src/notemd.server.integration.test.js +143 -35
- package/dist/src/notemd.workflow.pipeline.test.js +162 -0
- package/dist/src/pathbridge.handshake.contract.test.js +16 -2
- package/dist/src/pathmode.background.contract.test.js +69 -0
- package/dist/src/pathmode.settings.api.contract.test.js +9 -0
- package/dist/src/pkg.sidecar.contract.test.js +9 -3
- package/dist/src/platform/ExportProfile.js +58 -0
- package/dist/src/platform/PlatformCapabilities.js +45 -0
- package/dist/src/platform/PlatformCapabilities.test.js +30 -0
- package/dist/src/platform/RenderMaterializer.js +33 -0
- package/dist/src/platform/RenderMaterializer.test.js +32 -0
- package/dist/src/query_backend.external_http.integration.test.js +410 -0
- package/dist/src/reader_renderer.js +404 -3
- package/dist/src/reader_renderer.test.js +87 -0
- package/dist/src/release.godot.mirror.contract.test.js +73 -0
- package/dist/src/resources/ResourceRegistry.js +223 -0
- package/dist/src/resources/ResourceRegistry.test.js +61 -0
- package/dist/src/resources/types.js +2 -0
- package/dist/src/routes/agentWorkspaceDiagnostics.js +173 -0
- package/dist/src/routes/data.js +267 -0
- package/dist/src/routes/diagnostics.js +51 -0
- package/dist/src/routes/index.js +23 -0
- package/dist/src/routes/knowledge.js +968 -0
- package/dist/src/routes/markdown.js +287 -0
- package/dist/src/routes/notemd.js +565 -0
- package/dist/src/routes/registry.contract.test.js +130 -0
- package/dist/src/routes/render.js +285 -0
- package/dist/src/routes/runtimeRunbookRouteOps.js +149 -0
- package/dist/src/routes/runtimeRunbookRouteOps.test.js +194 -0
- package/dist/src/routes/settings.js +6 -0
- package/dist/src/routes/staticFiles.js +94 -0
- package/dist/src/routes/types.js +2 -0
- package/dist/src/runtime.transport.adapter.contract.test.js +81 -0
- package/dist/src/server.js +11090 -1549
- package/dist/src/server.migration.test.js +193 -21
- package/dist/src/server.port.fallback.contract.test.js +63 -0
- package/dist/src/session/SessionStateStore.js +81 -0
- package/dist/src/session/SessionStateStore.test.js +58 -0
- package/dist/src/session/types.js +2 -0
- package/dist/src/settings.runtime.contract.test.js +50 -0
- package/dist/src/shared/types.contract.test.js +107 -0
- package/dist/src/shared/types.js +22 -0
- package/dist/src/sidecar.replacement.boundary.contract.test.js +128 -0
- package/dist/src/sidecar.supply.readiness.contract.test.js +144 -0
- package/dist/src/source_manager.loadflow.test.js +46 -0
- package/dist/src/startup.layout.snapshot.contract.test.js +57 -0
- package/dist/src/tauri.frontend.build.contract.test.js +60 -0
- package/dist/src/tauri.sidecar.cleanup.contract.test.js +21 -0
- package/dist/src/utils/RuntimePaths.js +4 -13
- package/dist/src/utils/platform.js +153 -0
- package/dist/src/workflows/WorkflowArtifactStore.js +96 -0
- package/dist/src/workflows/WorkflowArtifactStore.test.js +80 -0
- package/dist/src/workflows/types.js +2 -0
- package/dist/src/workspace/WorkspaceRegistry.js +122 -0
- package/dist/src/workspace/WorkspaceRegistry.test.js +29 -0
- package/dist/src/workspace/types.js +2 -0
- package/package.json +53 -10
|
@@ -9,6 +9,7 @@ class Reader {
|
|
|
9
9
|
this.contentBox = document.getElementById('reading-content-box');
|
|
10
10
|
this.body = document.getElementById('reading-body');
|
|
11
11
|
this.title = document.getElementById('reading-title');
|
|
12
|
+
this._touchZoomBoundBody = null;
|
|
12
13
|
|
|
13
14
|
this.isLocked = true;
|
|
14
15
|
this.currentZoom = 0.5;
|
|
@@ -51,14 +52,50 @@ class Reader {
|
|
|
51
52
|
}
|
|
52
53
|
|
|
53
54
|
// Touch Gestures (Pinch to Zoom)
|
|
54
|
-
this.
|
|
55
|
+
this.bindTouchZoomSurface();
|
|
55
56
|
}
|
|
56
|
-
|
|
57
|
-
|
|
57
|
+
|
|
58
|
+
refreshDomRefs() {
|
|
59
|
+
this.window = document.getElementById('reading-window');
|
|
60
|
+
this.contentBox = document.getElementById('reading-content-box');
|
|
61
|
+
this.body = document.getElementById('reading-body');
|
|
62
|
+
this.title = document.getElementById('reading-title');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
ensureReaderStructure() {
|
|
66
|
+
this.refreshDomRefs();
|
|
67
|
+
if (!this.window || !this.contentBox || !this.title) {
|
|
68
|
+
throw new Error('Reader shell structure is unavailable in the current document.');
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const existingBody = document.getElementById('reading-body');
|
|
72
|
+
const bodyDetached = !!(existingBody && !this.contentBox.contains(existingBody));
|
|
73
|
+
if (!existingBody || bodyDetached) {
|
|
74
|
+
const replacementBody = document.createElement('div');
|
|
75
|
+
replacementBody.id = 'reading-body';
|
|
76
|
+
replacementBody.className = `reading-body ${this.isLocked ? 'locked' : 'unlocked'}`;
|
|
77
|
+
replacementBody.style.fontSize = `${this.currentZoom}rem`;
|
|
78
|
+
this.contentBox.appendChild(replacementBody);
|
|
79
|
+
this.body = replacementBody;
|
|
80
|
+
} else {
|
|
81
|
+
this.body = existingBody;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
this.bindTouchZoomSurface();
|
|
85
|
+
return this.body;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
bindTouchZoomSurface() {
|
|
89
|
+
const body = this.ensureReaderStructureBodyOnly();
|
|
90
|
+
if (!body || this._touchZoomBoundBody === body) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
this._touchZoomBoundBody = body;
|
|
94
|
+
|
|
58
95
|
let initialDistance = 0;
|
|
59
96
|
let initialZoom = 1.0;
|
|
60
|
-
|
|
61
|
-
|
|
97
|
+
|
|
98
|
+
body.addEventListener('touchstart', (e) => {
|
|
62
99
|
if (e.touches.length === 2) {
|
|
63
100
|
initialDistance = Math.hypot(
|
|
64
101
|
e.touches[0].pageX - e.touches[1].pageX,
|
|
@@ -69,7 +106,7 @@ class Reader {
|
|
|
69
106
|
}
|
|
70
107
|
}, { passive: false });
|
|
71
108
|
|
|
72
|
-
|
|
109
|
+
body.addEventListener('touchmove', (e) => {
|
|
73
110
|
if (e.touches.length === 2) {
|
|
74
111
|
const currentDistance = Math.hypot(
|
|
75
112
|
e.touches[0].pageX - e.touches[1].pageX,
|
|
@@ -89,14 +126,158 @@ class Reader {
|
|
|
89
126
|
}
|
|
90
127
|
}, { passive: false });
|
|
91
128
|
|
|
92
|
-
|
|
129
|
+
body.addEventListener('touchend', (e) => {
|
|
93
130
|
if (e.touches.length < 2) {
|
|
94
131
|
initialDistance = 0;
|
|
95
132
|
}
|
|
96
133
|
});
|
|
97
134
|
}
|
|
98
135
|
|
|
136
|
+
ensureReaderStructureBodyOnly() {
|
|
137
|
+
this.refreshDomRefs();
|
|
138
|
+
return this.body || null;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
isMermaidErrorArtifactText(text) {
|
|
142
|
+
const normalized = String(text || '').toLowerCase();
|
|
143
|
+
if (!normalized) {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
return (
|
|
147
|
+
normalized.includes('syntax error in text') ||
|
|
148
|
+
normalized.includes('lexical error on line') ||
|
|
149
|
+
normalized.includes('parse error on line') ||
|
|
150
|
+
normalized.includes('mermaid version') ||
|
|
151
|
+
normalized.includes('diagram syntax error')
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
resolveMermaidErrorArtifactHost(node) {
|
|
156
|
+
if (!node || typeof node.closest !== 'function') {
|
|
157
|
+
return node;
|
|
158
|
+
}
|
|
159
|
+
return (
|
|
160
|
+
node.closest('.mermaid-render-host-offscreen') ||
|
|
161
|
+
node.closest('.mermaid') ||
|
|
162
|
+
node.closest('.mermaid-render-failed') ||
|
|
163
|
+
node.closest('.reader-block') ||
|
|
164
|
+
node.closest('svg') ||
|
|
165
|
+
node
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
isProtectedMermaidSuppressionHost(host) {
|
|
170
|
+
if (!host || host.nodeType !== Node.ELEMENT_NODE) {
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
return (
|
|
174
|
+
host === document.body ||
|
|
175
|
+
host === document.documentElement ||
|
|
176
|
+
host === document.head ||
|
|
177
|
+
host.id === 'graph-wrapper' ||
|
|
178
|
+
host.id === 'path-container' ||
|
|
179
|
+
host.id === 'reading-window' ||
|
|
180
|
+
host.id === 'reading-content-box' ||
|
|
181
|
+
host.id === 'reading-body'
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
collectMermaidErrorArtifactHosts(root) {
|
|
186
|
+
const hosts = [];
|
|
187
|
+
const hostSet = new Set();
|
|
188
|
+
const candidates = [];
|
|
189
|
+
if (!root) {
|
|
190
|
+
return hosts;
|
|
191
|
+
}
|
|
192
|
+
if (
|
|
193
|
+
root.nodeType === Node.ELEMENT_NODE &&
|
|
194
|
+
root !== document.body &&
|
|
195
|
+
root !== document.documentElement &&
|
|
196
|
+
root !== document.head
|
|
197
|
+
) {
|
|
198
|
+
candidates.push(root);
|
|
199
|
+
}
|
|
200
|
+
if (typeof root.querySelectorAll === 'function') {
|
|
201
|
+
root.querySelectorAll('svg, .mermaid, div, section, article, aside, img, foreignObject').forEach((node) => {
|
|
202
|
+
candidates.push(node);
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
candidates.forEach((candidate) => {
|
|
206
|
+
if (!candidate || candidate.nodeType !== Node.ELEMENT_NODE) {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
const text = String(
|
|
210
|
+
candidate.textContent ||
|
|
211
|
+
candidate.getAttribute?.('alt') ||
|
|
212
|
+
candidate.getAttribute?.('aria-label') ||
|
|
213
|
+
''
|
|
214
|
+
).trim();
|
|
215
|
+
const hasErrorClass = Boolean(
|
|
216
|
+
candidate.classList?.contains('error-icon') ||
|
|
217
|
+
candidate.querySelector?.('.error-icon')
|
|
218
|
+
);
|
|
219
|
+
if (!hasErrorClass && !this.isMermaidErrorArtifactText(text)) {
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
const host = this.resolveMermaidErrorArtifactHost(candidate);
|
|
223
|
+
if (!host || hostSet.has(host) || this.isProtectedMermaidSuppressionHost(host)) {
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
hostSet.add(host);
|
|
227
|
+
hosts.push(host);
|
|
228
|
+
});
|
|
229
|
+
return hosts;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
suppressLeakedMermaidErrorArtifacts(options = {}) {
|
|
233
|
+
const root = options.root || document.body;
|
|
234
|
+
const preserveNode = options.preserveNode || null;
|
|
235
|
+
const hosts = this.collectMermaidErrorArtifactHosts(root);
|
|
236
|
+
hosts.forEach((host) => {
|
|
237
|
+
if (!host || host.closest?.('.mermaid-render-failed')) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
if (preserveNode && (host === preserveNode || preserveNode.contains(host) || host.contains(preserveNode))) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
if (host.parentNode) {
|
|
244
|
+
host.parentNode.removeChild(host);
|
|
245
|
+
} else if (host.style) {
|
|
246
|
+
host.style.display = 'none';
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
return hosts.length;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
createOffscreenMermaidRenderHost(widthHint) {
|
|
253
|
+
const hostWidth = Math.max(480, Number(widthHint) || 960);
|
|
254
|
+
const host = document.createElement('div');
|
|
255
|
+
host.className = 'mermaid-render-host-offscreen';
|
|
256
|
+
host.style.position = 'fixed';
|
|
257
|
+
host.style.left = '-20000px';
|
|
258
|
+
host.style.top = '0';
|
|
259
|
+
host.style.width = String(hostWidth) + 'px';
|
|
260
|
+
host.style.minWidth = String(hostWidth) + 'px';
|
|
261
|
+
host.style.height = 'auto';
|
|
262
|
+
host.style.overflow = 'visible';
|
|
263
|
+
host.style.opacity = '0';
|
|
264
|
+
host.style.pointerEvents = 'none';
|
|
265
|
+
host.style.background = 'transparent';
|
|
266
|
+
host.style.fontFamily = '"Microsoft YaHei UI", "Microsoft YaHei", "PingFang SC", "Noto Sans CJK SC", "Segoe UI", sans-serif';
|
|
267
|
+
const mountRoot = (
|
|
268
|
+
(this.window && this.window.ownerDocument && this.window.ownerDocument.body) ||
|
|
269
|
+
document.body ||
|
|
270
|
+
document.documentElement
|
|
271
|
+
);
|
|
272
|
+
if (!mountRoot || typeof mountRoot.appendChild !== 'function') {
|
|
273
|
+
throw new Error('Reader Mermaid offscreen host mount root is unavailable.');
|
|
274
|
+
}
|
|
275
|
+
mountRoot.appendChild(host);
|
|
276
|
+
return host;
|
|
277
|
+
}
|
|
278
|
+
|
|
99
279
|
async open(node) {
|
|
280
|
+
this.ensureReaderStructure();
|
|
100
281
|
const nodeLike = this.normalizeNodeInput(node);
|
|
101
282
|
this.title.innerText = nodeLike.label;
|
|
102
283
|
|
|
@@ -125,6 +306,13 @@ class Reader {
|
|
|
125
306
|
let rendered = false;
|
|
126
307
|
if (filePath) {
|
|
127
308
|
rendered = await this.tryRenderViaMarkdownProtocol(nodeLike, filePath, resolvedTarget, sessionId);
|
|
309
|
+
if (rendered && this.isReaderBodyVisiblyEmpty()) {
|
|
310
|
+
console.warn('[Reader] Markdown protocol path completed without visible content. Falling back to raw markdown render.', {
|
|
311
|
+
nodeId: nodeLike.id,
|
|
312
|
+
filePath,
|
|
313
|
+
});
|
|
314
|
+
rendered = false;
|
|
315
|
+
}
|
|
128
316
|
}
|
|
129
317
|
if (!rendered) {
|
|
130
318
|
const rawContent = await this.loadRawContentFallback(nodeLike);
|
|
@@ -140,7 +328,7 @@ class Reader {
|
|
|
140
328
|
|
|
141
329
|
normalizeNodeInput(nodeLike) {
|
|
142
330
|
if (typeof nodeLike === 'string') {
|
|
143
|
-
|
|
331
|
+
nodeLike = {
|
|
144
332
|
id: nodeLike,
|
|
145
333
|
label: nodeLike,
|
|
146
334
|
content: '',
|
|
@@ -149,15 +337,41 @@ class Reader {
|
|
|
149
337
|
}
|
|
150
338
|
const safeNode = (nodeLike && typeof nodeLike === 'object') ? nodeLike : {};
|
|
151
339
|
const nodeId = String(safeNode.id || safeNode.label || 'unknown-node');
|
|
340
|
+
const hydratedNode = this.lookupNodeDataById(nodeId);
|
|
341
|
+
const hydratedMetadata = (hydratedNode && hydratedNode.metadata && typeof hydratedNode.metadata === 'object')
|
|
342
|
+
? hydratedNode.metadata
|
|
343
|
+
: {};
|
|
344
|
+
const safeMetadata = (safeNode.metadata && typeof safeNode.metadata === 'object') ? safeNode.metadata : {};
|
|
152
345
|
return {
|
|
346
|
+
...(hydratedNode && typeof hydratedNode === 'object' ? hydratedNode : {}),
|
|
153
347
|
...safeNode,
|
|
154
348
|
id: nodeId,
|
|
155
|
-
label: String(safeNode.label || nodeId),
|
|
349
|
+
label: String(safeNode.label || hydratedNode?.label || nodeId),
|
|
156
350
|
content: typeof safeNode.content === 'string' ? safeNode.content : '',
|
|
157
|
-
metadata:
|
|
351
|
+
metadata: {
|
|
352
|
+
...hydratedMetadata,
|
|
353
|
+
...safeMetadata,
|
|
354
|
+
},
|
|
158
355
|
};
|
|
159
356
|
}
|
|
160
357
|
|
|
358
|
+
lookupNodeDataById(nodeId) {
|
|
359
|
+
const normalizedNodeId = String(nodeId || '').trim();
|
|
360
|
+
if (!normalizedNodeId) {
|
|
361
|
+
return null;
|
|
362
|
+
}
|
|
363
|
+
const sourceData = (typeof graphData !== 'undefined') ? graphData : window.graphData;
|
|
364
|
+
if (!sourceData || !Array.isArray(sourceData.nodes)) {
|
|
365
|
+
return null;
|
|
366
|
+
}
|
|
367
|
+
const matchedNode = sourceData.nodes.find((item) => (
|
|
368
|
+
item &&
|
|
369
|
+
(String(item.id || '').trim() === normalizedNodeId ||
|
|
370
|
+
String(item.label || '').trim() === normalizedNodeId)
|
|
371
|
+
));
|
|
372
|
+
return matchedNode && typeof matchedNode === 'object' ? matchedNode : null;
|
|
373
|
+
}
|
|
374
|
+
|
|
161
375
|
extractNodeFilePath(nodeLike) {
|
|
162
376
|
if (!nodeLike || typeof nodeLike !== 'object') return '';
|
|
163
377
|
const metadata = (nodeLike.metadata && typeof nodeLike.metadata === 'object') ? nodeLike.metadata : {};
|
|
@@ -166,6 +380,16 @@ class Reader {
|
|
|
166
380
|
return String(nodeLike.filepath || nodeLike.filePath || '').trim();
|
|
167
381
|
}
|
|
168
382
|
|
|
383
|
+
isReaderBodyVisiblyEmpty() {
|
|
384
|
+
if (!this.body) {
|
|
385
|
+
return true;
|
|
386
|
+
}
|
|
387
|
+
return (
|
|
388
|
+
this.body.children.length === 0 &&
|
|
389
|
+
String(this.body.textContent || '').trim().length === 0
|
|
390
|
+
);
|
|
391
|
+
}
|
|
392
|
+
|
|
169
393
|
getRuntimeBaseUrl() {
|
|
170
394
|
if (window.NoteConnectionRuntime && typeof window.NoteConnectionRuntime.getBaseUrl === 'function') {
|
|
171
395
|
return window.NoteConnectionRuntime.getBaseUrl();
|
|
@@ -231,6 +455,89 @@ class Reader {
|
|
|
231
455
|
});
|
|
232
456
|
}
|
|
233
457
|
|
|
458
|
+
normalizeMermaidDefinition(source) {
|
|
459
|
+
if (window.pathModules && window.pathModules.utils && typeof window.pathModules.utils.normalizeBridgeMermaidDefinition === 'function') {
|
|
460
|
+
return window.pathModules.utils.normalizeBridgeMermaidDefinition(source);
|
|
461
|
+
}
|
|
462
|
+
return String(source || '').trim();
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
getMermaidDefinitionCandidates(source) {
|
|
466
|
+
const candidates = [];
|
|
467
|
+
const normalized = this.normalizeMermaidDefinition(source);
|
|
468
|
+
const raw = String(source || '').replace(/\r\n?/g, '\n').trim();
|
|
469
|
+
[normalized, raw].forEach((candidate) => {
|
|
470
|
+
const next = String(candidate || '').trim();
|
|
471
|
+
if (!next || candidates.includes(next)) {
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
candidates.push(next);
|
|
475
|
+
});
|
|
476
|
+
return candidates;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
async canParseMermaidDefinition(definition) {
|
|
480
|
+
if (!window.mermaid || typeof mermaid.parse !== 'function') {
|
|
481
|
+
return true;
|
|
482
|
+
}
|
|
483
|
+
try {
|
|
484
|
+
await mermaid.parse(definition);
|
|
485
|
+
return true;
|
|
486
|
+
} catch (_error) {
|
|
487
|
+
return false;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
isMermaidErrorSvgMarkup(markup) {
|
|
492
|
+
const text = String(markup || '').toLowerCase();
|
|
493
|
+
if (!text) {
|
|
494
|
+
return false;
|
|
495
|
+
}
|
|
496
|
+
return (
|
|
497
|
+
text.includes('syntax error in text') ||
|
|
498
|
+
text.includes('lexical error on line') ||
|
|
499
|
+
text.includes('parse error on line') ||
|
|
500
|
+
text.includes('mermaid version') ||
|
|
501
|
+
text.includes('class="error-icon"') ||
|
|
502
|
+
text.includes('id="error-icon"')
|
|
503
|
+
);
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
renderCompactMermaidFailure(wrapper, error, source) {
|
|
507
|
+
wrapper.classList.add('mermaid-render-failed');
|
|
508
|
+
wrapper.innerHTML = '';
|
|
509
|
+
|
|
510
|
+
const notice = document.createElement('div');
|
|
511
|
+
notice.className = 'mermaid-render-notice';
|
|
512
|
+
|
|
513
|
+
const title = document.createElement('div');
|
|
514
|
+
title.className = 'mermaid-render-notice-title';
|
|
515
|
+
title.textContent = 'Mermaid diagram unavailable.';
|
|
516
|
+
notice.appendChild(title);
|
|
517
|
+
|
|
518
|
+
const summary = document.createElement('div');
|
|
519
|
+
summary.className = 'mermaid-render-notice-summary';
|
|
520
|
+
summary.textContent = 'Rendering failed in the current runtime. Details are available on demand.';
|
|
521
|
+
notice.appendChild(summary);
|
|
522
|
+
|
|
523
|
+
const details = document.createElement('details');
|
|
524
|
+
details.className = 'mermaid-render-notice-details';
|
|
525
|
+
|
|
526
|
+
const detailsSummary = document.createElement('summary');
|
|
527
|
+
detailsSummary.textContent = 'Render details';
|
|
528
|
+
details.appendChild(detailsSummary);
|
|
529
|
+
|
|
530
|
+
const detailText = document.createElement('pre');
|
|
531
|
+
detailText.className = 'mermaid-render-notice-code';
|
|
532
|
+
const errorMessage = String(error && error.message ? error.message : error || 'Unknown error').trim();
|
|
533
|
+
const sourceSnippet = String(source || '').trim().slice(0, 320);
|
|
534
|
+
detailText.textContent = errorMessage + (sourceSnippet ? `\n\n${sourceSnippet}` : '');
|
|
535
|
+
details.appendChild(detailText);
|
|
536
|
+
|
|
537
|
+
notice.appendChild(details);
|
|
538
|
+
wrapper.appendChild(notice);
|
|
539
|
+
}
|
|
540
|
+
|
|
234
541
|
async tryRenderViaMarkdownProtocol(nodeLike, filePath, resolvedTarget, sessionId) {
|
|
235
542
|
const config = this.getReadingProtocolConfig();
|
|
236
543
|
if (String(config.markdownEngine || 'auto').toLowerCase() === 'legacy') {
|
|
@@ -312,13 +619,14 @@ class Reader {
|
|
|
312
619
|
|
|
313
620
|
cleanupProtocolState() {
|
|
314
621
|
this._protocolRenderState = null;
|
|
315
|
-
if (this._protocolScrollHandler) {
|
|
622
|
+
if (this._protocolScrollHandler && this.body) {
|
|
316
623
|
this.body.removeEventListener('scroll', this._protocolScrollHandler);
|
|
317
624
|
this._protocolScrollHandler = null;
|
|
318
625
|
}
|
|
319
626
|
}
|
|
320
627
|
|
|
321
628
|
async renderProtocolBlocks(blocks, position, currentFilePath, sessionId) {
|
|
629
|
+
this.ensureReaderStructure();
|
|
322
630
|
if (!Array.isArray(blocks) || blocks.length === 0) {
|
|
323
631
|
return;
|
|
324
632
|
}
|
|
@@ -731,6 +1039,7 @@ class Reader {
|
|
|
731
1039
|
}
|
|
732
1040
|
|
|
733
1041
|
async renderRawMarkdown(rawContent, currentFilePath, sessionId) {
|
|
1042
|
+
this.ensureReaderStructure();
|
|
734
1043
|
const sanitizedMarkdown = this.autoFixInlineMermaidFenceAfterBlockMath(
|
|
735
1044
|
String(rawContent || '*No content available.*')
|
|
736
1045
|
);
|
|
@@ -767,6 +1076,8 @@ class Reader {
|
|
|
767
1076
|
this._mermaidInitialized = true;
|
|
768
1077
|
}
|
|
769
1078
|
|
|
1079
|
+
this.suppressLeakedMermaidErrorArtifacts({ root: document.body });
|
|
1080
|
+
|
|
770
1081
|
let mermaidBlocks = Array.from(container.querySelectorAll('pre code.language-mermaid, pre code.lang-mermaid'));
|
|
771
1082
|
if (mermaidBlocks.length === 0 && container.dataset && container.dataset.codeLanguage === 'mermaid') {
|
|
772
1083
|
const fallbackBlock = container.querySelector('pre code');
|
|
@@ -778,7 +1089,8 @@ class Reader {
|
|
|
778
1089
|
for (const block of mermaidBlocks) {
|
|
779
1090
|
const txt = document.createElement('textarea');
|
|
780
1091
|
txt.innerHTML = block.innerHTML;
|
|
781
|
-
const
|
|
1092
|
+
const candidateDefinitions = this.getMermaidDefinitionCandidates(txt.value);
|
|
1093
|
+
const graphDefinition = candidateDefinitions[0] || '';
|
|
782
1094
|
const parentPre = block.parentElement;
|
|
783
1095
|
if (!parentPre || !parentPre.parentNode) continue;
|
|
784
1096
|
|
|
@@ -794,36 +1106,72 @@ class Reader {
|
|
|
794
1106
|
const blockId = section && section.dataset ? String(section.dataset.blockId || '').trim() : '';
|
|
795
1107
|
|
|
796
1108
|
if (hasFrontendMermaid) {
|
|
797
|
-
|
|
798
|
-
const
|
|
799
|
-
|
|
800
|
-
wrapper.
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
1109
|
+
for (let candidateIndex = 0; candidateIndex < candidateDefinitions.length; candidateIndex += 1) {
|
|
1110
|
+
const candidate = candidateDefinitions[candidateIndex];
|
|
1111
|
+
const offscreenHost = this.createOffscreenMermaidRenderHost(
|
|
1112
|
+
wrapper.clientWidth || parentPre.clientWidth || container.clientWidth || 960
|
|
1113
|
+
);
|
|
1114
|
+
try {
|
|
1115
|
+
wrapper.innerHTML = '';
|
|
1116
|
+
const renderedResult = await mermaid.render(`${renderId}-${candidateIndex}`, candidate, offscreenHost);
|
|
1117
|
+
if (renderedResult && typeof renderedResult.svg === 'string' && renderedResult.svg.trim()) {
|
|
1118
|
+
if (this.isMermaidErrorSvgMarkup(renderedResult.svg)) {
|
|
1119
|
+
throw new Error('Mermaid frontend renderer returned an error SVG instead of a diagram.');
|
|
1120
|
+
}
|
|
1121
|
+
wrapper.innerHTML = renderedResult.svg;
|
|
1122
|
+
}
|
|
1123
|
+
if (/<svg[\s>]/i.test(String(wrapper.innerHTML || ''))) {
|
|
1124
|
+
rendered = true;
|
|
1125
|
+
renderSource = 'frontend-render';
|
|
1126
|
+
this._mermaidRenderStats.frontendRender += 1;
|
|
1127
|
+
break;
|
|
1128
|
+
}
|
|
1129
|
+
} catch (error) {
|
|
1130
|
+
renderErrors.push(error);
|
|
1131
|
+
wrapper.innerHTML = '';
|
|
1132
|
+
this.suppressLeakedMermaidErrorArtifacts({
|
|
1133
|
+
root: document.body,
|
|
1134
|
+
preserveNode: wrapper,
|
|
1135
|
+
});
|
|
1136
|
+
} finally {
|
|
1137
|
+
offscreenHost.remove();
|
|
804
1138
|
}
|
|
805
|
-
} catch (error) {
|
|
806
|
-
renderErrors.push(error);
|
|
807
1139
|
}
|
|
808
1140
|
} else {
|
|
809
1141
|
renderErrors.push(new Error('Mermaid runtime is unavailable in current webview.'));
|
|
810
1142
|
}
|
|
811
1143
|
|
|
812
1144
|
if (!rendered && hasFrontendMermaid) {
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
await
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
1145
|
+
for (let candidateIndex = 0; candidateIndex < candidateDefinitions.length; candidateIndex += 1) {
|
|
1146
|
+
const candidate = candidateDefinitions[candidateIndex];
|
|
1147
|
+
const canParse = await this.canParseMermaidDefinition(candidate);
|
|
1148
|
+
if (!canParse) {
|
|
1149
|
+
continue;
|
|
1150
|
+
}
|
|
1151
|
+
try {
|
|
1152
|
+
wrapper.innerHTML = '';
|
|
1153
|
+
wrapper.textContent = candidate;
|
|
1154
|
+
await mermaid.run({ nodes: [wrapper] });
|
|
1155
|
+
rendered = /<svg[\s>]/i.test(String(wrapper.innerHTML || '')) &&
|
|
1156
|
+
!this.isMermaidErrorSvgMarkup(String(wrapper.innerHTML || ''));
|
|
1157
|
+
if (rendered) {
|
|
1158
|
+
renderSource = 'frontend-run';
|
|
1159
|
+
this._mermaidRenderStats.frontendRun += 1;
|
|
1160
|
+
break;
|
|
1161
|
+
}
|
|
1162
|
+
} catch (error) {
|
|
1163
|
+
renderErrors.push(error);
|
|
1164
|
+
wrapper.innerHTML = '';
|
|
1165
|
+
this.suppressLeakedMermaidErrorArtifacts({
|
|
1166
|
+
root: document.body,
|
|
1167
|
+
preserveNode: wrapper,
|
|
1168
|
+
});
|
|
820
1169
|
}
|
|
821
|
-
} catch (error) {
|
|
822
|
-
renderErrors.push(error);
|
|
823
1170
|
}
|
|
824
1171
|
}
|
|
825
1172
|
|
|
826
1173
|
if (!rendered) {
|
|
1174
|
+
wrapper.innerHTML = '';
|
|
827
1175
|
const backendRendered = await this.renderMermaidViaBackend(graphDefinition);
|
|
828
1176
|
if (backendRendered && backendRendered.pngBase64) {
|
|
829
1177
|
const altRenderer = backendRendered.renderer ? ` (${backendRendered.renderer})` : '';
|
|
@@ -836,7 +1184,7 @@ class Reader {
|
|
|
836
1184
|
|
|
837
1185
|
if (!rendered) {
|
|
838
1186
|
const lastError = renderErrors.length > 0 ? renderErrors[renderErrors.length - 1] : null;
|
|
839
|
-
|
|
1187
|
+
this.renderCompactMermaidFailure(wrapper, lastError, graphDefinition);
|
|
840
1188
|
if (lastError) {
|
|
841
1189
|
console.error('Mermaid error:', lastError);
|
|
842
1190
|
}
|
|
@@ -844,6 +1192,11 @@ class Reader {
|
|
|
844
1192
|
this._mermaidRenderStats.failed += 1;
|
|
845
1193
|
}
|
|
846
1194
|
|
|
1195
|
+
this.suppressLeakedMermaidErrorArtifacts({
|
|
1196
|
+
root: document.body,
|
|
1197
|
+
preserveNode: wrapper,
|
|
1198
|
+
});
|
|
1199
|
+
|
|
847
1200
|
if (renderSource) {
|
|
848
1201
|
wrapper.dataset.renderSource = renderSource;
|
|
849
1202
|
const blockSuffix = blockId ? ` block=${blockId}` : '';
|
|
@@ -859,7 +1212,7 @@ class Reader {
|
|
|
859
1212
|
}
|
|
860
1213
|
|
|
861
1214
|
async renderMermaidViaBackend(graphDefinition) {
|
|
862
|
-
const source =
|
|
1215
|
+
const source = this.normalizeMermaidDefinition(graphDefinition || '');
|
|
863
1216
|
if (!source) {
|
|
864
1217
|
return null;
|
|
865
1218
|
}
|
|
@@ -892,6 +1245,9 @@ class Reader {
|
|
|
892
1245
|
}
|
|
893
1246
|
|
|
894
1247
|
initMermaidZoom() {
|
|
1248
|
+
if (!this.body) {
|
|
1249
|
+
return;
|
|
1250
|
+
}
|
|
895
1251
|
const mermaidDivs = this.body.querySelectorAll('.mermaid');
|
|
896
1252
|
mermaidDivs.forEach(div => {
|
|
897
1253
|
if (div.dataset && div.dataset.readerZoomBound === '1') {
|
|
@@ -1066,7 +1422,9 @@ class Reader {
|
|
|
1066
1422
|
if (!this._sessionId) this._sessionId = 0;
|
|
1067
1423
|
this._sessionId += 1;
|
|
1068
1424
|
this.cleanupProtocolState();
|
|
1069
|
-
this.window
|
|
1425
|
+
if (this.window) {
|
|
1426
|
+
this.window.style.display = 'none';
|
|
1427
|
+
}
|
|
1070
1428
|
}
|
|
1071
1429
|
|
|
1072
1430
|
toggleLock() {
|
|
@@ -1075,6 +1433,7 @@ class Reader {
|
|
|
1075
1433
|
}
|
|
1076
1434
|
|
|
1077
1435
|
updateLockState() {
|
|
1436
|
+
this.ensureReaderStructure();
|
|
1078
1437
|
const btn = document.getElementById('btn-reader-lock');
|
|
1079
1438
|
const zoomBtns = document.querySelectorAll('#btn-reader-zoom-in, #btn-reader-zoom-out');
|
|
1080
1439
|
|
|
@@ -1100,6 +1459,7 @@ class Reader {
|
|
|
1100
1459
|
}
|
|
1101
1460
|
|
|
1102
1461
|
updateZoom() {
|
|
1462
|
+
this.ensureReaderStructure();
|
|
1103
1463
|
this.body.style.fontSize = `${this.currentZoom}rem`;
|
|
1104
1464
|
// Scale images if needed, but CSS 'resize' handles explicit image resizing in unlocked mode.
|
|
1105
1465
|
// Font size scaling handles text content scaling.
|