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
|
@@ -0,0 +1,486 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* path_modules_bridge.js — Non-module bridge for extracted path modules.
|
|
3
|
+
*
|
|
4
|
+
* This script exposes utility functions from path_mermaid_utils.mjs and
|
|
5
|
+
* path_state.mjs on window.pathModules, so path_app.js can access them
|
|
6
|
+
* without ES module imports (which require <script type="module">).
|
|
7
|
+
*
|
|
8
|
+
* Load order:
|
|
9
|
+
* 1. <script src="path_modules_bridge.js"></script> (this file)
|
|
10
|
+
* 2. <script src="path_app.js"></script>
|
|
11
|
+
*
|
|
12
|
+
* path_app.js can then use:
|
|
13
|
+
* window.pathModules.utils.estimateBridgeTextLineWidth(text, fontSize)
|
|
14
|
+
* window.pathModules.state.createPathLearningState()
|
|
15
|
+
*
|
|
16
|
+
* When path_app.js migrates to ES modules, it can import directly from
|
|
17
|
+
* path_mermaid_utils.mjs and path_state.mjs instead.
|
|
18
|
+
*
|
|
19
|
+
* Phase 4 P1 — eliminates duplication; canonical source remains the .mjs files.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
(function () {
|
|
23
|
+
'use strict';
|
|
24
|
+
|
|
25
|
+
// ── SVG/Mermaid Utilities (from path_mermaid_utils.mjs) ──
|
|
26
|
+
|
|
27
|
+
function normalizeBridgeInlineText(text) {
|
|
28
|
+
return String(text || '').replace(/\s+/g, ' ').trim();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function isBridgeWideGlyph(char) {
|
|
32
|
+
return /[ᄀ-ᅟ⺀-가-힣豈-︐-︙︰-!-⦆¢-₩\u{1F300}-\u{1FAFF}]/u.test(char);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function estimateBridgeGlyphWidthUnits(char) {
|
|
36
|
+
if (!char) return 0;
|
|
37
|
+
if (/\s/.test(char)) return 0.35;
|
|
38
|
+
if (isBridgeWideGlyph(char)) return 1.02;
|
|
39
|
+
if (/[.,;:!'`|]/.test(char)) return 0.32;
|
|
40
|
+
if (/[(){}\[\]<>]/.test(char)) return 0.46;
|
|
41
|
+
if (/[\\/_-]/.test(char)) return 0.5;
|
|
42
|
+
if (/[0-9]/.test(char)) return 0.62;
|
|
43
|
+
if (/[A-Z]/.test(char)) return 0.72;
|
|
44
|
+
if (/[a-z]/.test(char)) return 0.64;
|
|
45
|
+
return 0.7;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function estimateBridgeTextLineWidth(text, fontSize) {
|
|
49
|
+
var units = 0;
|
|
50
|
+
var chars = Array.from(String(text || ''));
|
|
51
|
+
for (var i = 0; i < chars.length; i++) {
|
|
52
|
+
units += estimateBridgeGlyphWidthUnits(chars[i]);
|
|
53
|
+
}
|
|
54
|
+
return Math.max(fontSize * 0.75, (units * fontSize) + Math.max(2, fontSize * 0.12));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function splitBridgeTokenForWrap(token, fontSize, maxLineWidth) {
|
|
58
|
+
var wrapped = [];
|
|
59
|
+
var segment = '';
|
|
60
|
+
var chars = Array.from(token);
|
|
61
|
+
for (var i = 0; i < chars.length; i++) {
|
|
62
|
+
var candidate = segment + chars[i];
|
|
63
|
+
if (!segment || estimateBridgeTextLineWidth(candidate, fontSize) <= maxLineWidth) {
|
|
64
|
+
segment = candidate;
|
|
65
|
+
} else {
|
|
66
|
+
wrapped.push(segment);
|
|
67
|
+
segment = chars[i];
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (segment) wrapped.push(segment);
|
|
71
|
+
return wrapped;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function parseBridgeCssLength(lengthValue, baseFontSize) {
|
|
75
|
+
if (!lengthValue) return 0;
|
|
76
|
+
var normalized = String(lengthValue).trim().toLowerCase();
|
|
77
|
+
if (!normalized || normalized === 'normal') return 0;
|
|
78
|
+
var numeric = parseFloat(normalized);
|
|
79
|
+
if (!isFinite(numeric) || numeric <= 0) return 0;
|
|
80
|
+
if (normalized.indexOf('em') !== -1 || normalized.indexOf('rem') !== -1) {
|
|
81
|
+
return numeric * Math.max(10, baseFontSize || 16);
|
|
82
|
+
}
|
|
83
|
+
if (normalized.indexOf('%') !== -1) {
|
|
84
|
+
return (numeric / 100) * Math.max(10, baseFontSize || 16);
|
|
85
|
+
}
|
|
86
|
+
return numeric;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function parseBridgeNumericAttribute(element, name, fallback) {
|
|
90
|
+
var numeric = parseFloat(String((element && element.getAttribute) ? element.getAttribute(name) : ''));
|
|
91
|
+
return isFinite(numeric) ? numeric : (fallback || 0);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function extractBridgeInlineStyleValue(styleValue, propertyName) {
|
|
95
|
+
if (!styleValue) return null;
|
|
96
|
+
var pattern = new RegExp('(?:^|;)\\s*' + propertyName + '\\s*:\\s*([^;]+)', 'i');
|
|
97
|
+
var match = String(styleValue).match(pattern);
|
|
98
|
+
return match && match[1] ? String(match[1]).trim() : null;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function wrapBridgeMeasurementLine(line, fontSize, maxLineWidth) {
|
|
102
|
+
var normalized = normalizeBridgeInlineText(line);
|
|
103
|
+
if (!normalized) return [];
|
|
104
|
+
if (estimateBridgeTextLineWidth(normalized, fontSize) <= maxLineWidth) {
|
|
105
|
+
return [normalized];
|
|
106
|
+
}
|
|
107
|
+
var tokens = normalized.split(/\s+/);
|
|
108
|
+
var wrapped = [];
|
|
109
|
+
for (var i = 0; i < tokens.length; i++) {
|
|
110
|
+
var tokenWrapped = splitBridgeTokenForWrap(tokens[i], fontSize, maxLineWidth);
|
|
111
|
+
wrapped = wrapped.concat(tokenWrapped);
|
|
112
|
+
}
|
|
113
|
+
return wrapped;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function resolveBridgeTextProperty(element, propertyName) {
|
|
117
|
+
var current = element;
|
|
118
|
+
while (current) {
|
|
119
|
+
var attr = current.getAttribute && current.getAttribute(propertyName);
|
|
120
|
+
if (attr && String(attr).trim()) return String(attr).trim();
|
|
121
|
+
var styleVal = extractBridgeInlineStyleValue(
|
|
122
|
+
current.getAttribute && current.getAttribute('style'), propertyName
|
|
123
|
+
);
|
|
124
|
+
if (styleVal) return styleVal;
|
|
125
|
+
current = current.parentElement || null;
|
|
126
|
+
}
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function resolveBridgeSvgFontSize(element) {
|
|
131
|
+
var current = element;
|
|
132
|
+
while (current) {
|
|
133
|
+
var attr = current.getAttribute && current.getAttribute('font-size');
|
|
134
|
+
if (attr && String(attr).trim()) return String(attr).trim();
|
|
135
|
+
current = current.parentElement || null;
|
|
136
|
+
}
|
|
137
|
+
var parsed = parseBridgeCssLength('16', 16);
|
|
138
|
+
return parsed > 0 ? parsed : 16;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function resolveBridgeSvgLineHeight(element, fontSize) {
|
|
142
|
+
var current = element;
|
|
143
|
+
while (current) {
|
|
144
|
+
var attr = current.getAttribute && current.getAttribute('line-height');
|
|
145
|
+
if (attr && String(attr).trim()) return String(attr).trim();
|
|
146
|
+
current = current.parentElement || null;
|
|
147
|
+
}
|
|
148
|
+
var parsed = parseBridgeCssLength('normal', fontSize);
|
|
149
|
+
return parsed > 0 ? parsed : Math.max(fontSize * 1.18, fontSize + 4);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function normalizeBridgeMermaidLineBreaks(source) {
|
|
153
|
+
return String(source || '')
|
|
154
|
+
.replace(/\r\n?/g, '\n')
|
|
155
|
+
.replace(/<br\s*>/gi, '<br/>');
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function stripBridgeWrappingQuotes(text) {
|
|
159
|
+
var trimmed = String(text || '').trim();
|
|
160
|
+
if (trimmed.length >= 2 && trimmed.charAt(0) === '"' && trimmed.charAt(trimmed.length - 1) === '"') {
|
|
161
|
+
return trimmed.slice(1, -1);
|
|
162
|
+
}
|
|
163
|
+
return trimmed;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function splitBridgeMermaidTopLevelStatements(source) {
|
|
167
|
+
var text = normalizeBridgeMermaidLineBreaks(source)
|
|
168
|
+
.split('\n')
|
|
169
|
+
.map(function(line) {
|
|
170
|
+
return rewriteBridgeQuotedLabelAfterSemicolonLine(line) || line;
|
|
171
|
+
})
|
|
172
|
+
.join('\n');
|
|
173
|
+
var result = '';
|
|
174
|
+
var quote = false;
|
|
175
|
+
var squareDepth = 0;
|
|
176
|
+
var roundDepth = 0;
|
|
177
|
+
var curlyDepth = 0;
|
|
178
|
+
|
|
179
|
+
for (var index = 0; index < text.length; index += 1) {
|
|
180
|
+
var char = text.charAt(index);
|
|
181
|
+
if (char === '"' && text.charAt(index - 1) !== '\\') {
|
|
182
|
+
quote = !quote;
|
|
183
|
+
result += char;
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
if (!quote) {
|
|
187
|
+
if (char === '[') squareDepth += 1;
|
|
188
|
+
else if (char === ']') squareDepth = Math.max(0, squareDepth - 1);
|
|
189
|
+
else if (char === '(') roundDepth += 1;
|
|
190
|
+
else if (char === ')') roundDepth = Math.max(0, roundDepth - 1);
|
|
191
|
+
else if (char === '{') curlyDepth += 1;
|
|
192
|
+
else if (char === '}') curlyDepth = Math.max(0, curlyDepth - 1);
|
|
193
|
+
if (char === ';' && squareDepth === 0 && roundDepth === 0 && curlyDepth === 0) {
|
|
194
|
+
result += '\n';
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
result += char;
|
|
199
|
+
}
|
|
200
|
+
return result;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function rewriteBridgeQuotedLabelAfterSemicolonLine(line) {
|
|
204
|
+
if (String(line || '').indexOf('-->') === -1) {
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
var match = String(line || '').match(/^(.*?)\s*(-->)\s*(.*?);\s*"([^"\n]+)"\s*$/);
|
|
208
|
+
if (!match) {
|
|
209
|
+
return null;
|
|
210
|
+
}
|
|
211
|
+
var source = String(match[1] || '').trim();
|
|
212
|
+
var arrow = String(match[2] || '').trim();
|
|
213
|
+
var target = String(match[3] || '').trim();
|
|
214
|
+
var label = String(match[4] || '').trim();
|
|
215
|
+
if (!source || !target || !label) {
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
218
|
+
return `${source} -- "${label}" ${arrow} ${target};`;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function mergeBridgeDoubleArrowLabelLine(line) {
|
|
222
|
+
var match = String(line || '').match(/^(.*?)\s*--\s*"([^"\n]+)"\s*--\s*"([^"\n]+)"\s*(-->|---)\s*(.*)$/);
|
|
223
|
+
if (!match) {
|
|
224
|
+
return null;
|
|
225
|
+
}
|
|
226
|
+
var start = String(match[1] || '').trim();
|
|
227
|
+
var labelLeft = String(match[2] || '').trim();
|
|
228
|
+
var labelRight = String(match[3] || '').trim();
|
|
229
|
+
var arrow = String(match[4] || '').trim();
|
|
230
|
+
var end = String(match[5] || '').trim();
|
|
231
|
+
if (!start || !labelLeft || !labelRight || !end) {
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
return `${start} -- "${labelLeft}<br/>${labelRight}" ${arrow} ${end}`;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
function quoteBridgeUnquotedEdgeLabelLine(line) {
|
|
238
|
+
var match = String(line || '').match(/^(.*?)\s*--\s*([^"\n][^>\n]*?)\s*-->\s*(.*)$/);
|
|
239
|
+
if (!match) {
|
|
240
|
+
return null;
|
|
241
|
+
}
|
|
242
|
+
var start = String(match[1] || '').trim();
|
|
243
|
+
var label = String(match[2] || '').trim();
|
|
244
|
+
var end = String(match[3] || '').trim();
|
|
245
|
+
if (!start || !label || !end) {
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
if (
|
|
249
|
+
/^[A-Za-z_][A-Za-z0-9_]*$/.test(label)
|
|
250
|
+
|| /^[A-Za-z_][A-Za-z0-9_]*\s*[\[\(\{].*$/.test(label)
|
|
251
|
+
|| /^["[{(]/.test(label)
|
|
252
|
+
) {
|
|
253
|
+
return null;
|
|
254
|
+
}
|
|
255
|
+
return `${start} -- "${label}" --> ${end}`;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function splitBridgeIntermediateNodeLine(line) {
|
|
259
|
+
var match = String(line || '').match(/^(.*?)\s*(-->|---)\s*([A-Za-z_][A-Za-z0-9_]*)\s*(\[[^\]]+\]|\([^)]+\)|\{[^}]+\})\s*(-->|---)\s*(.*)$/);
|
|
260
|
+
if (!match) {
|
|
261
|
+
return null;
|
|
262
|
+
}
|
|
263
|
+
var start = String(match[1] || '').trim();
|
|
264
|
+
var leftArrow = String(match[2] || '').trim();
|
|
265
|
+
var nodeId = String(match[3] || '').trim();
|
|
266
|
+
var nodeShape = String(match[4] || '').trim();
|
|
267
|
+
var rightArrow = String(match[5] || '').trim();
|
|
268
|
+
var end = String(match[6] || '').trim();
|
|
269
|
+
if (!start || !nodeId || !nodeShape || !end) {
|
|
270
|
+
return null;
|
|
271
|
+
}
|
|
272
|
+
return [
|
|
273
|
+
`${start} ${leftArrow} ${nodeId}${nodeShape}`,
|
|
274
|
+
`${nodeId} ${rightArrow} ${end}`
|
|
275
|
+
];
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
function sanitizeBridgeMermaidIdentifier(rawValue, fallbackPrefix, counter) {
|
|
279
|
+
var raw = String(rawValue || '').trim();
|
|
280
|
+
var prefixedMatch = raw.match(/^([A-Za-z][A-Za-z0-9_]*)/);
|
|
281
|
+
if (prefixedMatch && prefixedMatch[1]) {
|
|
282
|
+
return prefixedMatch[1];
|
|
283
|
+
}
|
|
284
|
+
return `${fallbackPrefix}${counter}`;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
function escapeBridgeMermaidLabel(rawValue) {
|
|
288
|
+
return String(rawValue || '')
|
|
289
|
+
.replace(/\\/g, '\\\\')
|
|
290
|
+
.replace(/"/g, '\\"')
|
|
291
|
+
.trim();
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
function isBridgeMermaidControlLine(line) {
|
|
295
|
+
return /^\s*(?:graph|flowchart|subgraph|end|classDef|class|style|linkStyle|click|%%)\b/i.test(line);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
function convertBridgeNoteLine(line, state) {
|
|
299
|
+
var directionalMatch = String(line || '').match(/^\s*note\s+(?:right|left|top|bottom)\s+of\s+([A-Za-z0-9_]+)\s*:\s*(.+)$/i);
|
|
300
|
+
if (directionalMatch) {
|
|
301
|
+
state.syntheticCounter += 1;
|
|
302
|
+
var directionalNodeId = `AutoNote${state.syntheticCounter}`;
|
|
303
|
+
var directionalNodeText = escapeBridgeMermaidLabel(stripBridgeWrappingQuotes(directionalMatch[2]));
|
|
304
|
+
return [
|
|
305
|
+
`${directionalNodeId}["${directionalNodeText}"]`,
|
|
306
|
+
`${directionalMatch[1]} -.- ${directionalNodeId}`
|
|
307
|
+
];
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
var targetedMatch = String(line || '').match(/^\s*note\s+([A-Za-z0-9_]+)\s+"(.+)"\s*$/i);
|
|
311
|
+
if (targetedMatch) {
|
|
312
|
+
state.syntheticCounter += 1;
|
|
313
|
+
var targetedNodeId = `AutoNote${state.syntheticCounter}`;
|
|
314
|
+
var targetedNodeText = escapeBridgeMermaidLabel(stripBridgeWrappingQuotes(targetedMatch[2]));
|
|
315
|
+
return [
|
|
316
|
+
`${targetedNodeId}["${targetedNodeText}"]`,
|
|
317
|
+
`${targetedMatch[1]} -.- ${targetedNodeId}`
|
|
318
|
+
];
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
return null;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
function normalizeBridgeMermaidEdgeLabels(line) {
|
|
325
|
+
return String(line || '')
|
|
326
|
+
.replace(/--\s*"([^"\n]+)"\s*-->/g, '-->|$1|')
|
|
327
|
+
.replace(/--\s*"([^"\n]+)"\s*--\s*/g, ' -->|$1| ');
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
function normalizeBridgeMermaidEndpoint(rawValue, state) {
|
|
331
|
+
var raw = String(rawValue || '').trim();
|
|
332
|
+
if (!raw) return raw;
|
|
333
|
+
if (/^(?:\[|\{|\(|")/.test(raw)) return raw;
|
|
334
|
+
if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(raw)) return raw;
|
|
335
|
+
if (/^[A-Za-z_][A-Za-z0-9_]*\s*[\[\(\{].*$/.test(raw)) return raw;
|
|
336
|
+
|
|
337
|
+
var nodeId = state.labelToId.get(raw);
|
|
338
|
+
if (!nodeId) {
|
|
339
|
+
state.syntheticCounter += 1;
|
|
340
|
+
nodeId = sanitizeBridgeMermaidIdentifier(raw, 'AutoNode', state.syntheticCounter);
|
|
341
|
+
state.labelToId.set(raw, nodeId);
|
|
342
|
+
}
|
|
343
|
+
return `${nodeId}["${escapeBridgeMermaidLabel(raw)}"]`;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
function normalizeBridgeMermaidEdgeLine(line, state) {
|
|
347
|
+
var next = normalizeBridgeMermaidEdgeLabels(line);
|
|
348
|
+
var match = /(.*?)(--(?:>|o|x)(?:\|[^|]*\|)?\s*)(.+)$/.exec(next);
|
|
349
|
+
if (!match) {
|
|
350
|
+
return next;
|
|
351
|
+
}
|
|
352
|
+
var left = String(match[1] || '');
|
|
353
|
+
var connector = String(match[2] || '');
|
|
354
|
+
var right = String(match[3] || '').trim();
|
|
355
|
+
if (!right) {
|
|
356
|
+
return next;
|
|
357
|
+
}
|
|
358
|
+
return `${left}${connector}${normalizeBridgeMermaidEndpoint(right, state)}`;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
function fixBridgeDanglingBracketedNodeLabelLine(line) {
|
|
362
|
+
var match = String(line || '').match(/^(\s*[A-Za-z_][A-Za-z0-9_]*)\["([^"\n]*)\["\s*;?\s*$/);
|
|
363
|
+
if (!match) {
|
|
364
|
+
return null;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
var nodeId = String(match[1] || '').trim();
|
|
368
|
+
var label = String(match[2] || '').trim();
|
|
369
|
+
if (!nodeId || !label) {
|
|
370
|
+
return null;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
return `${nodeId}["${escapeBridgeMermaidLabel(label)}"]`;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
function applyBridgeLegacyMermaidRepairs(line, state) {
|
|
377
|
+
var noteLines = convertBridgeNoteLine(line, state);
|
|
378
|
+
if (noteLines) {
|
|
379
|
+
return noteLines;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
var next = String(line || '');
|
|
383
|
+
next = rewriteBridgeQuotedLabelAfterSemicolonLine(next) || next;
|
|
384
|
+
next = mergeBridgeDoubleArrowLabelLine(next) || next;
|
|
385
|
+
next = quoteBridgeUnquotedEdgeLabelLine(next) || next;
|
|
386
|
+
next = fixBridgeDanglingBracketedNodeLabelLine(next) || next;
|
|
387
|
+
|
|
388
|
+
var splitIntermediate = splitBridgeIntermediateNodeLine(next);
|
|
389
|
+
if (splitIntermediate) {
|
|
390
|
+
return splitIntermediate;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
return [next];
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
function normalizeBridgeMermaidDefinition(source) {
|
|
397
|
+
var split = splitBridgeMermaidTopLevelStatements(source);
|
|
398
|
+
var state = {
|
|
399
|
+
labelToId: new Map(),
|
|
400
|
+
syntheticCounter: 0
|
|
401
|
+
};
|
|
402
|
+
|
|
403
|
+
return split
|
|
404
|
+
.split('\n')
|
|
405
|
+
.reduce(function(lines, rawLine) {
|
|
406
|
+
var repairedLines = applyBridgeLegacyMermaidRepairs(rawLine, state);
|
|
407
|
+
for (var index = 0; index < repairedLines.length; index += 1) {
|
|
408
|
+
var line = repairedLines[index];
|
|
409
|
+
if (!String(line || '').trim()) {
|
|
410
|
+
continue;
|
|
411
|
+
}
|
|
412
|
+
if (isBridgeMermaidControlLine(line)) {
|
|
413
|
+
lines.push(line.trimEnd());
|
|
414
|
+
} else {
|
|
415
|
+
lines.push(normalizeBridgeMermaidEdgeLine(line, state).trimEnd());
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
return lines;
|
|
419
|
+
}, [])
|
|
420
|
+
.join('\n')
|
|
421
|
+
.replace(/\n{3,}/g, '\n\n')
|
|
422
|
+
.trim();
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// ── State Factories (from path_state.mjs) ──
|
|
426
|
+
|
|
427
|
+
function createPathGraphState() {
|
|
428
|
+
return {
|
|
429
|
+
canvas: null, ctx: null, worker: null,
|
|
430
|
+
transform: { k: 1, x: 0, y: 0 },
|
|
431
|
+
nodes: [], links: [], width: 0, height: 0,
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
function createPathLearningState() {
|
|
436
|
+
return {
|
|
437
|
+
centralNodeId: null, learningHistory: [],
|
|
438
|
+
completedNodes: new Set(), collapsedNodes: new Set(),
|
|
439
|
+
forcedExpansionNodes: new Set(), expansionOrder: [],
|
|
440
|
+
stickyClaimEnabled: true, currentTargetId: null,
|
|
441
|
+
currentTargetIds: [], lastTreeLayout: null, uiInitialized: false,
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
function createPathRuntimeConfig(overrides) {
|
|
446
|
+
var base = { mode: 'domain', strategy: 'foundational', layout: 'orbital',
|
|
447
|
+
targetId: null, targetIds: [], autoReconstruct: true, retainHistory: true };
|
|
448
|
+
if (overrides) { for (var k in overrides) { base[k] = overrides[k]; } }
|
|
449
|
+
return base;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
function createLearningWorkbenchState(userId) {
|
|
453
|
+
return {
|
|
454
|
+
userId: userId || 'path_user_default', loading: false,
|
|
455
|
+
lastError: '', lastUpdatedAt: '', sessionPlan: null,
|
|
456
|
+
qualitySnapshot: null, misconceptions: null, runtimeState: null,
|
|
457
|
+
tutorFeedback: null, sessionExecution: null, sessionHistory: null,
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
// ── Expose on window ──
|
|
462
|
+
|
|
463
|
+
window.pathModules = {
|
|
464
|
+
utils: {
|
|
465
|
+
normalizeBridgeInlineText: normalizeBridgeInlineText,
|
|
466
|
+
normalizeBridgeMermaidDefinition: normalizeBridgeMermaidDefinition,
|
|
467
|
+
parseBridgeNumericAttribute: parseBridgeNumericAttribute,
|
|
468
|
+
extractBridgeInlineStyleValue: extractBridgeInlineStyleValue,
|
|
469
|
+
parseBridgeCssLength: parseBridgeCssLength,
|
|
470
|
+
resolveBridgeTextProperty: resolveBridgeTextProperty,
|
|
471
|
+
resolveBridgeSvgFontSize: resolveBridgeSvgFontSize,
|
|
472
|
+
resolveBridgeSvgLineHeight: resolveBridgeSvgLineHeight,
|
|
473
|
+
estimateBridgeTextLineWidth: estimateBridgeTextLineWidth,
|
|
474
|
+
estimateBridgeGlyphWidthUnits: estimateBridgeGlyphWidthUnits,
|
|
475
|
+
splitBridgeTokenForWrap: splitBridgeTokenForWrap,
|
|
476
|
+
wrapBridgeMeasurementLine: wrapBridgeMeasurementLine,
|
|
477
|
+
isBridgeWideGlyph: isBridgeWideGlyph,
|
|
478
|
+
},
|
|
479
|
+
state: {
|
|
480
|
+
createPathGraphState: createPathGraphState,
|
|
481
|
+
createPathLearningState: createPathLearningState,
|
|
482
|
+
createPathRuntimeConfig: createPathRuntimeConfig,
|
|
483
|
+
createLearningWorkbenchState: createLearningWorkbenchState,
|
|
484
|
+
}
|
|
485
|
+
};
|
|
486
|
+
})();
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* path_state.mjs — Path Mode state object factories
|
|
3
|
+
* Extracted from path_app.js (v2.7, Phase 4 P2)
|
|
4
|
+
*
|
|
5
|
+
* These factory functions create the default state objects used by
|
|
6
|
+
* the Path Mode controller. They are pure data constructors with
|
|
7
|
+
* no DOM, event, or rendering dependencies.
|
|
8
|
+
*
|
|
9
|
+
* Usage (after migration to ES modules):
|
|
10
|
+
* import { createPathGraphState, createPathLearningState, ... } from './path_state.mjs';
|
|
11
|
+
*
|
|
12
|
+
* Current (pre-migration):
|
|
13
|
+
* These factories mirror the inline state definitions in path_app.js
|
|
14
|
+
* lines 7-58. Replace inline definitions with factory calls when
|
|
15
|
+
* path_app.js migrates to ES module loading.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/** Core graph rendering state: canvas, worker, transform, nodes, links. */
|
|
19
|
+
export function createPathGraphState() {
|
|
20
|
+
return {
|
|
21
|
+
canvas: null,
|
|
22
|
+
ctx: null,
|
|
23
|
+
worker: null,
|
|
24
|
+
transform: { k: 1, x: 0, y: 0 },
|
|
25
|
+
nodes: [],
|
|
26
|
+
links: [],
|
|
27
|
+
width: 0,
|
|
28
|
+
height: 0,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Learning path state: focus node, completion tracking, expansion control. */
|
|
33
|
+
export function createPathLearningState() {
|
|
34
|
+
return {
|
|
35
|
+
centralNodeId: null,
|
|
36
|
+
learningHistory: [],
|
|
37
|
+
completedNodes: new Set(),
|
|
38
|
+
collapsedNodes: new Set(),
|
|
39
|
+
forcedExpansionNodes: new Set(),
|
|
40
|
+
expansionOrder: [],
|
|
41
|
+
stickyClaimEnabled: true,
|
|
42
|
+
currentTargetId: null,
|
|
43
|
+
currentTargetIds: [],
|
|
44
|
+
lastTreeLayout: null,
|
|
45
|
+
uiInitialized: false,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Runtime configuration for Path Mode layout and behavior. */
|
|
50
|
+
export function createPathRuntimeConfig(overrides = {}) {
|
|
51
|
+
return {
|
|
52
|
+
mode: 'domain',
|
|
53
|
+
strategy: 'foundational',
|
|
54
|
+
layout: 'orbital',
|
|
55
|
+
targetId: null,
|
|
56
|
+
targetIds: [],
|
|
57
|
+
autoReconstruct: true,
|
|
58
|
+
retainHistory: true,
|
|
59
|
+
...overrides,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Learning workbench state: session plan, quality, misconceptions, tutor feedback. */
|
|
64
|
+
export function createLearningWorkbenchState(userId = 'path_user_default') {
|
|
65
|
+
return {
|
|
66
|
+
userId,
|
|
67
|
+
loading: false,
|
|
68
|
+
lastError: '',
|
|
69
|
+
lastUpdatedAt: '',
|
|
70
|
+
sessionPlan: null,
|
|
71
|
+
qualitySnapshot: null,
|
|
72
|
+
misconceptions: null,
|
|
73
|
+
runtimeState: null,
|
|
74
|
+
tutorFeedback: null,
|
|
75
|
+
sessionExecution: null,
|
|
76
|
+
sessionHistory: null,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Animation state for orbital graph rendering. */
|
|
81
|
+
export function createAnimationState() {
|
|
82
|
+
return {
|
|
83
|
+
animationId: null,
|
|
84
|
+
orbitalAngle: 0,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Bridge communication state. */
|
|
89
|
+
export function createBridgeState() {
|
|
90
|
+
return {
|
|
91
|
+
bridgeLanguageListenerRegistered: false,
|
|
92
|
+
bridgeMermaidRenderQueue: Promise.resolve(),
|
|
93
|
+
pendingWindowVisibility: null,
|
|
94
|
+
semanticA11yLastSummaryKey: '',
|
|
95
|
+
semanticA11yLastAnnouncementAt: 0,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** Complete Path Mode application state (all substates combined). */
|
|
100
|
+
export function createFullPathAppState(overrides = {}) {
|
|
101
|
+
const base = {
|
|
102
|
+
...createPathGraphState(),
|
|
103
|
+
...createPathLearningState(),
|
|
104
|
+
...createPathBridgeState(),
|
|
105
|
+
};
|
|
106
|
+
// Re-assign non-serializable objects that spread would lose
|
|
107
|
+
base.completedNodes = new Set();
|
|
108
|
+
base.collapsedNodes = new Set();
|
|
109
|
+
base.forcedExpansionNodes = new Set();
|
|
110
|
+
base.bridgeMermaidRenderQueue = Promise.resolve();
|
|
111
|
+
|
|
112
|
+
base.runtimeConfig = createPathRuntimeConfig();
|
|
113
|
+
base.learningWorkbench = createLearningWorkbenchState();
|
|
114
|
+
base.animationId = null;
|
|
115
|
+
base.orbitalAngle = 0;
|
|
116
|
+
|
|
117
|
+
return { ...base, ...overrides };
|
|
118
|
+
}
|