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.
Files changed (211) hide show
  1. package/LICENSE +674 -21
  2. package/README.md +242 -62
  3. package/dist/src/agent_workspace.contract.parity.test.js +475 -0
  4. package/dist/src/agent_workspace.frontend.test.js +9989 -0
  5. package/dist/src/agent_workspace.locale.contract.test.js +95 -0
  6. package/dist/src/agent_workspace.runtime.behavior.test.js +5072 -0
  7. package/dist/src/copy.assets.contract.test.js +130 -0
  8. package/dist/src/core/PathBridge.js +28 -3
  9. package/dist/src/export/WorkspaceExportBundle.js +1130 -0
  10. package/dist/src/export/WorkspaceExportBundle.test.js +1480 -0
  11. package/dist/src/export/index.js +18 -0
  12. package/dist/src/export/types.js +2 -0
  13. package/dist/src/fixrisk.issue.verifier.contract.test.js +3 -1
  14. package/dist/src/foundation.ann.runtime.contract.test.js +81 -0
  15. package/dist/src/foundation.release.evidence.contract.test.js +406 -0
  16. package/dist/src/foundation.sqlite.runtime.contract.test.js +82 -0
  17. package/dist/src/frontend/README.md +242 -62
  18. package/dist/src/frontend/agent_workspace.js +5353 -0
  19. package/dist/src/frontend/agent_workspace_runtime.js +4434 -0
  20. package/dist/src/frontend/analysis.js +31 -4
  21. package/dist/src/frontend/app.js +2178 -62
  22. package/dist/src/frontend/focus_mode_interactions.js +33 -0
  23. package/dist/src/frontend/godot_future_path_renderer.js +540 -0
  24. package/dist/src/frontend/godot_tree_interactions.js +178 -0
  25. package/dist/src/frontend/graph_state.mjs +105 -0
  26. package/dist/src/frontend/hosted_future_path_runtime.js +157 -0
  27. package/dist/src/frontend/i18n.mjs +186 -0
  28. package/dist/src/frontend/index.html +641 -266
  29. package/dist/src/frontend/layout_gpu.js +12 -4
  30. package/dist/src/frontend/locales/en.json +721 -5
  31. package/dist/src/frontend/locales/zh.json +721 -5
  32. package/dist/src/frontend/main.mjs +60 -0
  33. package/dist/src/frontend/markdown_runtime.js +827 -0
  34. package/dist/src/frontend/notemd.css +49 -0
  35. package/dist/src/frontend/notemd.html +7 -1
  36. package/dist/src/frontend/notemd.js +64 -0
  37. package/dist/src/frontend/path.html +107 -0
  38. package/dist/src/frontend/path_app.js +2108 -130
  39. package/dist/src/frontend/path_layout.mjs +143 -0
  40. package/dist/src/frontend/path_mermaid_utils.mjs +108 -0
  41. package/dist/src/frontend/path_modules_bridge.js +486 -0
  42. package/dist/src/frontend/path_state.mjs +118 -0
  43. package/dist/src/frontend/path_styles.css +146 -0
  44. package/dist/src/frontend/path_worker_bridge.mjs +85 -0
  45. package/dist/src/frontend/reader.js +393 -33
  46. package/dist/src/frontend/runtime_bridge.js +67 -54
  47. package/dist/src/frontend/runtime_bridge.mjs +279 -0
  48. package/dist/src/frontend/settings.js +130 -12
  49. package/dist/src/frontend/source_manager.js +190 -21
  50. package/dist/src/frontend/styles.css +2720 -72
  51. package/dist/src/frontend/workbench_state.mjs +101 -0
  52. package/dist/src/frontend/workspace_panes.js +10168 -0
  53. package/dist/src/frontend.locale.contract.test.js +62 -0
  54. package/dist/src/godot.sidecar.bootstrap.contract.test.js +244 -0
  55. package/dist/src/indexing/IndexLifecycle.js +195 -0
  56. package/dist/src/indexing/IndexLifecycle.test.js +49 -0
  57. package/dist/src/indexing/SegmentBuilder.js +64 -0
  58. package/dist/src/indexing/UnitBuilder.js +48 -0
  59. package/dist/src/indexing/types.js +2 -0
  60. package/dist/src/knowledge.api.contract.test.js +170 -0
  61. package/dist/src/learning/KnowledgeLearningPlatform.js +10386 -0
  62. package/dist/src/learning/KnowledgeLearningPlatform.persistence.test.js +327 -0
  63. package/dist/src/learning/KnowledgeLearningPlatform.program-f.test.js +99 -0
  64. package/dist/src/learning/KnowledgeLearningPlatform.test.js +2971 -0
  65. package/dist/src/learning/KnowledgeWorkspaceConversationRegression.js +2974 -0
  66. package/dist/src/learning/KnowledgeWorkspaceConversationRegression.test.js +3928 -0
  67. package/dist/src/learning/answerReleaseReview.js +4319 -0
  68. package/dist/src/learning/answerReleaseReview.test.js +2888 -0
  69. package/dist/src/learning/api.js +2 -0
  70. package/dist/src/learning/conversationComposer.js +1480 -0
  71. package/dist/src/learning/conversationComposer.test.js +1817 -0
  72. package/dist/src/learning/domains/ConversationManager.js +53 -0
  73. package/dist/src/learning/domains/KnowledgeIngestor.js +238 -0
  74. package/dist/src/learning/domains/KnowledgeQuerier.js +187 -0
  75. package/dist/src/learning/domains/MasteryEngine.js +387 -0
  76. package/dist/src/learning/domains/MemoryPolicyManager.js +408 -0
  77. package/dist/src/learning/domains/QualityEvaluator.js +307 -0
  78. package/dist/src/learning/domains/TutorRouter.js +313 -0
  79. package/dist/src/learning/domains/index.js +33 -0
  80. package/dist/src/learning/domains/types.js +7 -0
  81. package/dist/src/learning/errors.js +29 -0
  82. package/dist/src/learning/evidenceContextAssembler.js +1176 -0
  83. package/dist/src/learning/evidenceContextAssembler.test.js +6332 -0
  84. package/dist/src/learning/graphContextAssembler.js +870 -0
  85. package/dist/src/learning/graphContextAssembler.test.js +1033 -0
  86. package/dist/src/learning/index.js +28 -0
  87. package/dist/src/learning/queryBackend.js +1898 -0
  88. package/dist/src/learning/queryBackend.test.js +955 -0
  89. package/dist/src/learning/ragContextPack.js +257 -0
  90. package/dist/src/learning/ragContextPack.test.js +160 -0
  91. package/dist/src/learning/ragPublicText.js +38 -0
  92. package/dist/src/learning/ragSufficiencyJudge.js +161 -0
  93. package/dist/src/learning/ragSufficiencyJudge.test.js +177 -0
  94. package/dist/src/learning/ragSufficiencyProviderJudge.js +227 -0
  95. package/dist/src/learning/ragSufficiencyProviderJudge.test.js +156 -0
  96. package/dist/src/learning/requestNormalization.js +198 -0
  97. package/dist/src/learning/runtimeCapability.js +4677 -0
  98. package/dist/src/learning/runtimeCapability.test.js +3635 -0
  99. package/dist/src/learning/store.js +1240 -0
  100. package/dist/src/learning/store.test.js +1126 -0
  101. package/dist/src/learning/tutorAdapter.js +2 -0
  102. package/dist/src/learning/types.js +2 -0
  103. package/dist/src/learning/vectorAccelerationAdapter.js +942 -0
  104. package/dist/src/learning/vectorAccelerationAdapter.test.js +382 -0
  105. package/dist/src/lfs.asset.policy.contract.test.js +153 -0
  106. package/dist/src/license.policy.contract.test.js +66 -0
  107. package/dist/src/memory/MemoryGovernance.js +74 -0
  108. package/dist/src/memory/MemoryGovernance.test.js +46 -0
  109. package/dist/src/memory/types.js +2 -0
  110. package/dist/src/mermaid.frontend.guard.contract.test.js +77 -0
  111. package/dist/src/middleware/auth.js +17 -0
  112. package/dist/src/middleware/body-parser.js +45 -0
  113. package/dist/src/middleware/cors.js +44 -0
  114. package/dist/src/middleware/index.js +21 -0
  115. package/dist/src/middleware/request-trace.js +96 -0
  116. package/dist/src/notemd/AppConfigToml.js +6 -4
  117. package/dist/src/notemd/MermaidProcessor.js +400 -50
  118. package/dist/src/notemd/NotemdService.js +498 -13
  119. package/dist/src/notemd/PromptManager.js +15 -0
  120. package/dist/src/notemd/cli/commands.js +357 -0
  121. package/dist/src/notemd/cli/dispatcher.js +225 -0
  122. package/dist/src/notemd/cli/index.js +169 -0
  123. package/dist/src/notemd/cli/parser.js +68 -0
  124. package/dist/src/notemd/cli/types.js +2 -0
  125. package/dist/src/notemd/constants.js +43 -0
  126. package/dist/src/notemd/diagram/diagramGenerationService.js +78 -0
  127. package/dist/src/notemd/diagram/diagramSpec.js +79 -0
  128. package/dist/src/notemd/diagram/diagramSpecResponseParser.js +131 -0
  129. package/dist/src/notemd/diagram/intent.js +95 -0
  130. package/dist/src/notemd/diagram/planner.js +71 -0
  131. package/dist/src/notemd/diagram/prompts/diagramSpecPrompt.js +42 -0
  132. package/dist/src/notemd/diagram/types.js +18 -0
  133. package/dist/src/notemd/index.js +26 -0
  134. package/dist/src/notemd/operations/capabilityManifest.js +23 -0
  135. package/dist/src/notemd/operations/cliContracts.js +17 -0
  136. package/dist/src/notemd/operations/configProfileCommands.js +85 -0
  137. package/dist/src/notemd/operations/registry.contract.test.js +95 -0
  138. package/dist/src/notemd/operations/registry.js +991 -0
  139. package/dist/src/notemd/operations/types.js +2 -0
  140. package/dist/src/notemd/providerDiagnostics.js +220 -0
  141. package/dist/src/notemd/providerProfiles.js +42 -0
  142. package/dist/src/notemd/providerTemplates.js +231 -0
  143. package/dist/src/notemd/search/DuckDuckGoProvider.js +39 -0
  144. package/dist/src/notemd/search/SearchManager.js +13 -0
  145. package/dist/src/notemd/search/SearchProvider.js +2 -0
  146. package/dist/src/notemd/search/TavilyProvider.js +44 -0
  147. package/dist/src/notemd.agent.manifest.test.js +85 -0
  148. package/dist/src/notemd.api.contract.test.js +14 -1
  149. package/dist/src/notemd.app_config_toml.test.js +2 -1
  150. package/dist/src/notemd.batch.workflow.test.js +117 -0
  151. package/dist/src/notemd.cli.e2e.test.js +136 -0
  152. package/dist/src/notemd.core.test.js +51 -0
  153. package/dist/src/notemd.diagram.pipeline.test.js +233 -0
  154. package/dist/src/notemd.providerTemplates.test.js +34 -0
  155. package/dist/src/notemd.server.integration.test.js +143 -35
  156. package/dist/src/notemd.workflow.pipeline.test.js +162 -0
  157. package/dist/src/pathbridge.handshake.contract.test.js +16 -2
  158. package/dist/src/pathmode.background.contract.test.js +69 -0
  159. package/dist/src/pathmode.settings.api.contract.test.js +9 -0
  160. package/dist/src/pkg.sidecar.contract.test.js +9 -3
  161. package/dist/src/platform/ExportProfile.js +58 -0
  162. package/dist/src/platform/PlatformCapabilities.js +45 -0
  163. package/dist/src/platform/PlatformCapabilities.test.js +30 -0
  164. package/dist/src/platform/RenderMaterializer.js +33 -0
  165. package/dist/src/platform/RenderMaterializer.test.js +32 -0
  166. package/dist/src/query_backend.external_http.integration.test.js +410 -0
  167. package/dist/src/reader_renderer.js +404 -3
  168. package/dist/src/reader_renderer.test.js +87 -0
  169. package/dist/src/release.godot.mirror.contract.test.js +73 -0
  170. package/dist/src/resources/ResourceRegistry.js +223 -0
  171. package/dist/src/resources/ResourceRegistry.test.js +61 -0
  172. package/dist/src/resources/types.js +2 -0
  173. package/dist/src/routes/agentWorkspaceDiagnostics.js +173 -0
  174. package/dist/src/routes/data.js +267 -0
  175. package/dist/src/routes/diagnostics.js +51 -0
  176. package/dist/src/routes/index.js +23 -0
  177. package/dist/src/routes/knowledge.js +968 -0
  178. package/dist/src/routes/markdown.js +287 -0
  179. package/dist/src/routes/notemd.js +565 -0
  180. package/dist/src/routes/registry.contract.test.js +130 -0
  181. package/dist/src/routes/render.js +285 -0
  182. package/dist/src/routes/runtimeRunbookRouteOps.js +149 -0
  183. package/dist/src/routes/runtimeRunbookRouteOps.test.js +194 -0
  184. package/dist/src/routes/settings.js +6 -0
  185. package/dist/src/routes/staticFiles.js +94 -0
  186. package/dist/src/routes/types.js +2 -0
  187. package/dist/src/runtime.transport.adapter.contract.test.js +81 -0
  188. package/dist/src/server.js +11090 -1549
  189. package/dist/src/server.migration.test.js +193 -21
  190. package/dist/src/server.port.fallback.contract.test.js +63 -0
  191. package/dist/src/session/SessionStateStore.js +81 -0
  192. package/dist/src/session/SessionStateStore.test.js +58 -0
  193. package/dist/src/session/types.js +2 -0
  194. package/dist/src/settings.runtime.contract.test.js +50 -0
  195. package/dist/src/shared/types.contract.test.js +107 -0
  196. package/dist/src/shared/types.js +22 -0
  197. package/dist/src/sidecar.replacement.boundary.contract.test.js +128 -0
  198. package/dist/src/sidecar.supply.readiness.contract.test.js +144 -0
  199. package/dist/src/source_manager.loadflow.test.js +46 -0
  200. package/dist/src/startup.layout.snapshot.contract.test.js +57 -0
  201. package/dist/src/tauri.frontend.build.contract.test.js +60 -0
  202. package/dist/src/tauri.sidecar.cleanup.contract.test.js +21 -0
  203. package/dist/src/utils/RuntimePaths.js +4 -13
  204. package/dist/src/utils/platform.js +153 -0
  205. package/dist/src/workflows/WorkflowArtifactStore.js +96 -0
  206. package/dist/src/workflows/WorkflowArtifactStore.test.js +80 -0
  207. package/dist/src/workflows/types.js +2 -0
  208. package/dist/src/workspace/WorkspaceRegistry.js +122 -0
  209. package/dist/src/workspace/WorkspaceRegistry.test.js +29 -0
  210. package/dist/src/workspace/types.js +2 -0
  211. package/package.json +53 -10
@@ -0,0 +1,475 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const fs = __importStar(require("fs"));
37
+ const path = __importStar(require("path"));
38
+ function extractUnionLiterals(source, typeName) {
39
+ const pattern = new RegExp(`export type\\s+${typeName}\\s*=([\\s\\S]*?);`);
40
+ const match = source.match(pattern);
41
+ if (!match) {
42
+ throw new Error(`Unable to locate type definition for ${typeName}`);
43
+ }
44
+ return Array.from(match[1].matchAll(/'([^']+)'/g)).map((item) => item[1]);
45
+ }
46
+ function extractObjectLiteralKeys(source, constName) {
47
+ const objectLiteral = extractObjectLiteralSource(source, constName);
48
+ const keys = [];
49
+ let objectDepth = 0;
50
+ let lineStart = true;
51
+ for (let index = 0; index < objectLiteral.length; index += 1) {
52
+ const character = objectLiteral[index];
53
+ if (character === '{') {
54
+ objectDepth += 1;
55
+ lineStart = false;
56
+ continue;
57
+ }
58
+ if (character === '}') {
59
+ objectDepth -= 1;
60
+ lineStart = false;
61
+ continue;
62
+ }
63
+ if (character === '\n') {
64
+ lineStart = true;
65
+ continue;
66
+ }
67
+ if (objectDepth === 1 && lineStart) {
68
+ if (/\s/.test(character)) {
69
+ continue;
70
+ }
71
+ if (/[a-zA-Z0-9_]/.test(character)) {
72
+ let cursor = index;
73
+ while (cursor < objectLiteral.length && /[a-zA-Z0-9_]/.test(objectLiteral[cursor])) {
74
+ cursor += 1;
75
+ }
76
+ const key = objectLiteral.slice(index, cursor);
77
+ let separator = cursor;
78
+ while (separator < objectLiteral.length && /\s/.test(objectLiteral[separator])) {
79
+ separator += 1;
80
+ }
81
+ if (objectLiteral[separator] === ':') {
82
+ keys.push(key);
83
+ }
84
+ }
85
+ lineStart = false;
86
+ continue;
87
+ }
88
+ if (!/\s/.test(character)) {
89
+ lineStart = false;
90
+ }
91
+ }
92
+ return Array.from(new Set(keys));
93
+ }
94
+ function extractObjectLiteralSource(source, constName) {
95
+ const constStart = source.indexOf(`const ${constName} = {`);
96
+ if (constStart < 0) {
97
+ throw new Error(`Unable to locate constant ${constName}`);
98
+ }
99
+ const openBraceIndex = source.indexOf('{', constStart);
100
+ let depth = 0;
101
+ let endIndex = -1;
102
+ for (let index = openBraceIndex; index < source.length; index += 1) {
103
+ const character = source[index];
104
+ if (character === '{') {
105
+ depth += 1;
106
+ }
107
+ else if (character === '}') {
108
+ depth -= 1;
109
+ if (depth === 0) {
110
+ endIndex = index;
111
+ break;
112
+ }
113
+ }
114
+ }
115
+ if (endIndex < 0) {
116
+ throw new Error(`Unable to parse object literal for ${constName}`);
117
+ }
118
+ return source.slice(openBraceIndex, endIndex + 1);
119
+ }
120
+ function extractArrayLiteralAfterMarker(source, marker) {
121
+ const markerIndex = source.indexOf(marker);
122
+ if (markerIndex < 0) {
123
+ throw new Error(`Unable to locate marker: ${marker}`);
124
+ }
125
+ const openBracketIndex = source.indexOf('[', markerIndex + marker.length);
126
+ if (openBracketIndex < 0) {
127
+ throw new Error(`Unable to locate opening array bracket for marker: ${marker}`);
128
+ }
129
+ let depth = 0;
130
+ let endIndex = -1;
131
+ for (let index = openBracketIndex; index < source.length; index += 1) {
132
+ const character = source[index];
133
+ if (character === '[') {
134
+ depth += 1;
135
+ continue;
136
+ }
137
+ if (character === ']') {
138
+ depth -= 1;
139
+ if (depth === 0) {
140
+ endIndex = index;
141
+ break;
142
+ }
143
+ }
144
+ }
145
+ if (endIndex < 0) {
146
+ throw new Error(`Unable to resolve closing array bracket for marker: ${marker}`);
147
+ }
148
+ return source.slice(openBracketIndex, endIndex + 1);
149
+ }
150
+ function extractObjectFieldStringLiterals(source, fieldName) {
151
+ const pattern = new RegExp(`${fieldName}\\s*:\\s*'([^']+)'`, 'g');
152
+ return Array.from(source.matchAll(pattern)).map((match) => match[1]);
153
+ }
154
+ function extractOperationDefaultResultPresentationsFromFrontend(source) {
155
+ const registryLiteral = extractObjectLiteralSource(source, 'KNOWLEDGE_OPERATION_TRANSPORT_REGISTRY');
156
+ const entries = Array.from(registryLiteral.matchAll(/([a-zA-Z0-9_]+)\s*:\s*{[\s\S]*?defaultResultPresentation\s*:\s*'([^']+)'/g));
157
+ const mapping = {};
158
+ entries.forEach((entry) => {
159
+ const operationId = String(entry[1] || '').trim();
160
+ const resultPresentation = String(entry[2] || '').trim();
161
+ if (!operationId || !resultPresentation) {
162
+ return;
163
+ }
164
+ mapping[operationId] = resultPresentation;
165
+ });
166
+ return mapping;
167
+ }
168
+ function extractOperationResultPresentationOverridesFromFrontend(source) {
169
+ const overridesLiteral = extractObjectLiteralSource(source, 'KNOWLEDGE_OPERATION_RESULT_PRESENTATION_OVERRIDES');
170
+ const entries = Array.from(overridesLiteral.matchAll(/([a-zA-Z0-9_]+)\s*:\s*\[([^\]]*)\]/g));
171
+ const mapping = {};
172
+ entries.forEach((entry) => {
173
+ const operationId = String(entry[1] || '').trim();
174
+ if (!operationId) {
175
+ return;
176
+ }
177
+ const rawArrayLiteral = String(entry[2] || '');
178
+ const values = Array.from(rawArrayLiteral.matchAll(/'([^']+)'/g))
179
+ .map((valueMatch) => String(valueMatch[1] || '').trim())
180
+ .filter(Boolean);
181
+ mapping[operationId] = Array.from(new Set(values));
182
+ });
183
+ return mapping;
184
+ }
185
+ function extractOperationAllowedResultPresentationsFromFrontend(source) {
186
+ const defaultMapping = extractOperationDefaultResultPresentationsFromFrontend(source);
187
+ const overrideMapping = extractOperationResultPresentationOverridesFromFrontend(source);
188
+ const allOperationIds = new Set([
189
+ ...Object.keys(defaultMapping),
190
+ ...Object.keys(overrideMapping),
191
+ ]);
192
+ const allowedMapping = {};
193
+ allOperationIds.forEach((operationId) => {
194
+ const values = [
195
+ String(defaultMapping[operationId] || '').trim(),
196
+ ...(overrideMapping[operationId] || []),
197
+ ].filter(Boolean);
198
+ allowedMapping[operationId] = Array.from(new Set(values));
199
+ });
200
+ return allowedMapping;
201
+ }
202
+ function extractBackendKnowledgeOperationPairs(conversationCapabilityLiteral) {
203
+ const entries = Array.from(String(conversationCapabilityLiteral || '').matchAll(/execution\s*:\s*{[\s\S]*?kind\s*:\s*'knowledge_operation'[\s\S]*?operationId\s*:\s*'([^']+)'[\s\S]*?resultPresentation\s*:\s*'([^']+)'/g));
204
+ return entries.map((entry) => ({
205
+ operationId: String(entry[1] || '').trim(),
206
+ resultPresentation: String(entry[2] || '').trim(),
207
+ })).filter((entry) => entry.operationId.length > 0 && entry.resultPresentation.length > 0);
208
+ }
209
+ function extractTopLevelObjectLiteralsFromArrayLiteral(arrayLiteralSource) {
210
+ const source = String(arrayLiteralSource || '');
211
+ const objectLiterals = [];
212
+ let inString = null;
213
+ let isEscaped = false;
214
+ let objectDepth = 0;
215
+ let objectStartIndex = -1;
216
+ for (let index = 0; index < source.length; index += 1) {
217
+ const character = source[index];
218
+ if (inString) {
219
+ if (isEscaped) {
220
+ isEscaped = false;
221
+ continue;
222
+ }
223
+ if (character === '\\') {
224
+ isEscaped = true;
225
+ continue;
226
+ }
227
+ if (character === inString) {
228
+ inString = null;
229
+ }
230
+ continue;
231
+ }
232
+ if (character === '\'' || character === '"' || character === '`') {
233
+ inString = character;
234
+ continue;
235
+ }
236
+ if (character === '{') {
237
+ if (objectDepth === 0) {
238
+ objectStartIndex = index;
239
+ }
240
+ objectDepth += 1;
241
+ continue;
242
+ }
243
+ if (character === '}') {
244
+ if (objectDepth <= 0) {
245
+ continue;
246
+ }
247
+ objectDepth -= 1;
248
+ if (objectDepth === 0 && objectStartIndex >= 0) {
249
+ objectLiterals.push(source.slice(objectStartIndex, index + 1));
250
+ objectStartIndex = -1;
251
+ }
252
+ }
253
+ }
254
+ return objectLiterals;
255
+ }
256
+ describe('agent workspace capability registry parity', () => {
257
+ const repoRoot = path.resolve(__dirname, '..');
258
+ const typesSource = fs.readFileSync(path.join(repoRoot, 'src', 'learning', 'types.ts'), 'utf8');
259
+ const frontendSource = fs.readFileSync(path.join(repoRoot, 'src', 'frontend', 'agent_workspace.js'), 'utf8');
260
+ const knowledgePlatformSource = fs.readFileSync(path.join(repoRoot, 'src', 'learning', 'KnowledgeLearningPlatform.ts'), 'utf8');
261
+ const BACKEND_CONTRACT_MARKER = "const capabilities: AgentConversationResponse['knowledgePoints'][number]['capabilities'] =";
262
+ const backendContractAvailable = knowledgePlatformSource.indexOf(BACKEND_CONTRACT_MARKER) >= 0;
263
+ const backendTest = backendContractAvailable ? test : test.skip;
264
+ let conversationCapabilityLiteral;
265
+ try {
266
+ conversationCapabilityLiteral = extractArrayLiteralAfterMarker(knowledgePlatformSource, BACKEND_CONTRACT_MARKER);
267
+ }
268
+ catch {
269
+ conversationCapabilityLiteral = '';
270
+ }
271
+ test.skip('frontend operation transport registry covers AgentConversationCapabilityOperationId union', () => {
272
+ const operationIds = extractUnionLiterals(typesSource, 'AgentConversationCapabilityOperationId');
273
+ const frontendOperationIds = extractObjectLiteralKeys(frontendSource, 'KNOWLEDGE_OPERATION_TRANSPORT_REGISTRY');
274
+ expect(new Set(frontendOperationIds)).toEqual(new Set(operationIds));
275
+ });
276
+ test.skip('frontend operation request builder registry covers AgentConversationCapabilityOperationId union', () => {
277
+ const operationIds = extractUnionLiterals(typesSource, 'AgentConversationCapabilityOperationId');
278
+ const frontendOperationIds = extractObjectLiteralKeys(frontendSource, 'KNOWLEDGE_OPERATION_REQUEST_BUILDERS');
279
+ expect(new Set(frontendOperationIds)).toEqual(new Set(operationIds));
280
+ });
281
+ test('frontend operation transport and request builder registries stay aligned', () => {
282
+ const transportOperationIds = extractObjectLiteralKeys(frontendSource, 'KNOWLEDGE_OPERATION_TRANSPORT_REGISTRY');
283
+ const requestBuilderOperationIds = extractObjectLiteralKeys(frontendSource, 'KNOWLEDGE_OPERATION_REQUEST_BUILDERS');
284
+ expect(new Set(transportOperationIds)).toEqual(new Set(requestBuilderOperationIds));
285
+ });
286
+ test.skip('frontend operation result-presentation override keys stay within operation union', () => {
287
+ const operationIds = new Set(extractUnionLiterals(typesSource, 'AgentConversationCapabilityOperationId'));
288
+ const overrideMapping = extractOperationResultPresentationOverridesFromFrontend(frontendSource);
289
+ Object.keys(overrideMapping).forEach((operationId) => {
290
+ expect(operationIds.has(operationId)).toBe(true);
291
+ expect(overrideMapping[operationId].length).toBeGreaterThan(0);
292
+ });
293
+ });
294
+ test.skip('frontend operation result-presentation overrides stay within result-presentation union', () => {
295
+ const resultPresentationIds = new Set(extractUnionLiterals(typesSource, 'AgentConversationCapabilityResultPresentation'));
296
+ const overrideMapping = extractOperationResultPresentationOverridesFromFrontend(frontendSource);
297
+ Object.entries(overrideMapping).forEach(([operationId, presentations]) => {
298
+ expect(operationId).toBeTruthy();
299
+ expect(presentations.length).toBeGreaterThan(0);
300
+ presentations.forEach((presentation) => {
301
+ expect(resultPresentationIds.has(presentation)).toBe(true);
302
+ });
303
+ });
304
+ });
305
+ test('frontend operation allowlists include transport defaults and stay non-empty', () => {
306
+ const defaultMapping = extractOperationDefaultResultPresentationsFromFrontend(frontendSource);
307
+ const allowlistMapping = extractOperationAllowedResultPresentationsFromFrontend(frontendSource);
308
+ const overrideMapping = extractOperationResultPresentationOverridesFromFrontend(frontendSource);
309
+ Object.entries(defaultMapping).forEach(([operationId, defaultPresentation]) => {
310
+ expect(defaultPresentation).toBeTruthy();
311
+ const allowlist = allowlistMapping[operationId] || [];
312
+ expect(allowlist.length).toBeGreaterThan(0);
313
+ expect(allowlist).toContain(defaultPresentation);
314
+ expect(new Set(allowlist).size).toBe(allowlist.length);
315
+ });
316
+ Object.keys(overrideMapping).forEach((operationId) => {
317
+ expect(defaultMapping[operationId]).toBeDefined();
318
+ });
319
+ });
320
+ test('frontend operation result-presentation overrides only declare non-default presentations', () => {
321
+ const defaultMapping = extractOperationDefaultResultPresentationsFromFrontend(frontendSource);
322
+ const overrideMapping = extractOperationResultPresentationOverridesFromFrontend(frontendSource);
323
+ Object.entries(overrideMapping).forEach(([operationId, overridePresentations]) => {
324
+ const defaultPresentation = String(defaultMapping[operationId] || '').trim();
325
+ expect(defaultPresentation).toBeTruthy();
326
+ overridePresentations.forEach((presentation) => {
327
+ expect(presentation).not.toBe(defaultPresentation);
328
+ });
329
+ });
330
+ });
331
+ test('frontend registry diagnostics expose operation presentation maps', () => {
332
+ expect(frontendSource).toMatch(/operationResultPresentationOverrideMap\s*:\s*resolveOperationResultPresentationOverrideMap\(\)/);
333
+ expect(frontendSource).toMatch(/operationInvalidResultPresentationOverrideMap\s*:\s*(resolveOperationInvalidResultPresentationOverrideMap\(\)|invalidOverrideMap)/);
334
+ expect(frontendSource).toMatch(/operationUnknownResultPresentationOverrideMap\s*:\s*(resolveOperationUnknownResultPresentationOverrideMap\(\)|unknownOverrideMap)/);
335
+ expect(frontendSource).toMatch(/operationDefaultResultPresentations\s*:\s*resolveOperationDefaultResultPresentationMap\(\)/);
336
+ expect(frontendSource).toMatch(/operationAllowedResultPresentations\s*:\s*resolveOperationAllowedResultPresentationMap\(\)/);
337
+ expect(frontendSource).toMatch(/operationResultPresentationOverrideDriftDetected\s*:\s*\(/);
338
+ expect(frontendSource).toMatch(/operationResultPresentationInvalidOverrideTokenCount\s*:\s*invalidOverrideTokenCount/);
339
+ expect(frontendSource).toMatch(/operationResultPresentationUnknownOverrideTokenCount\s*:\s*unknownOverrideTokenCount/);
340
+ });
341
+ test.skip('frontend result presentation registries cover AgentConversationCapabilityResultPresentation union', () => {
342
+ const presentationIds = extractUnionLiterals(typesSource, 'AgentConversationCapabilityResultPresentation');
343
+ const customPresentationIds = extractObjectLiteralKeys(frontendSource, 'CUSTOM_RESULT_PRESENTERS');
344
+ const cardPresentationIds = extractObjectLiteralKeys(frontendSource, 'CARD_RESULT_PRESENTATION_REGISTRY');
345
+ expect(new Set([...customPresentationIds, ...cardPresentationIds])).toEqual(new Set(presentationIds));
346
+ });
347
+ test('frontend card result presentation registry and payload builders stay aligned', () => {
348
+ const cardPresentationIds = extractObjectLiteralKeys(frontendSource, 'CARD_RESULT_PRESENTATION_REGISTRY');
349
+ const payloadBuilderPresentationIds = extractObjectLiteralKeys(frontendSource, 'RESULT_PRESENTATION_PAYLOAD_BUILDERS');
350
+ expect(new Set(cardPresentationIds)).toEqual(new Set(payloadBuilderPresentationIds));
351
+ });
352
+ test.skip('frontend execution kind handlers cover AgentConversationCapabilityExecutionKind union', () => {
353
+ const executionKinds = extractUnionLiterals(typesSource, 'AgentConversationCapabilityExecutionKind');
354
+ const frontendExecutionKinds = extractObjectLiteralKeys(frontendSource, 'CAPABILITY_EXECUTION_KIND_HANDLERS');
355
+ expect(new Set(frontendExecutionKinds)).toEqual(new Set(executionKinds));
356
+ });
357
+ backendTest('backend conversation emitter action set stays governed and union-compatible', () => {
358
+ const backendActionIds = Array.from(new Set(extractObjectFieldStringLiterals(conversationCapabilityLiteral, 'actionId')));
359
+ const explicitActionIds = extractUnionLiterals(typesSource, 'AgentConversationActionId');
360
+ const tutorActionIds = extractUnionLiterals(typesSource, 'TutorActionKind');
361
+ const governedActionIds = [
362
+ 'open_focus_mode',
363
+ 'open_learning_path',
364
+ 'generate_quiz',
365
+ 'recap',
366
+ 'generate_transfer',
367
+ 'generate_counterexample',
368
+ 'follow_up',
369
+ 'compare_query_backends',
370
+ 'inspect_conversation_turn_cache_diagnostics',
371
+ 'inspect_conversation_turn_cache_alert_trend',
372
+ 'inspect_conversation_turn_cache_alert_trend_index',
373
+ 'inspect_conversation_turn_cache_alert_trend_export',
374
+ 'inspect_query_backend_diagnostics',
375
+ 'inspect_query_backend_comparison_history',
376
+ 'inspect_query_backend_comparison_trend',
377
+ 'inspect_tutor_adapter_telemetry',
378
+ 'inspect_tutor_trace_diagnostics',
379
+ 'inspect_learning_quality_trend',
380
+ 'inspect_learning_quality_history',
381
+ 'inspect_session_plan_quality_trend',
382
+ 'inspect_session_plan_quality_history',
383
+ 'inspect_runtime_capability_runbook_verify',
384
+ 'inspect_runtime_capability_runbook_history',
385
+ 'inspect_runtime_capability_runbook_checks',
386
+ 'inspect_runtime_capability_runbook_action_queue',
387
+ 'inspect_session_history',
388
+ 'build_study_session',
389
+ 'inspect_conversation_memory',
390
+ ];
391
+ const fullActionUnionSet = new Set([...explicitActionIds, ...tutorActionIds]);
392
+ backendActionIds.forEach((actionId) => {
393
+ expect(fullActionUnionSet.has(actionId)).toBe(true);
394
+ });
395
+ expect(new Set(backendActionIds)).toEqual(new Set(governedActionIds));
396
+ expect(backendActionIds).not.toContain('analyze_answer');
397
+ });
398
+ backendTest('backend conversation emitter operation ids stay in parity with frontend transport and request registries', () => {
399
+ const backendOperationIds = Array.from(new Set(extractObjectFieldStringLiterals(conversationCapabilityLiteral, 'operationId')));
400
+ const frontendTransportOperationIds = extractObjectLiteralKeys(frontendSource, 'KNOWLEDGE_OPERATION_TRANSPORT_REGISTRY');
401
+ const frontendRequestBuilderOperationIds = extractObjectLiteralKeys(frontendSource, 'KNOWLEDGE_OPERATION_REQUEST_BUILDERS');
402
+ expect(new Set(backendOperationIds)).toEqual(new Set(frontendTransportOperationIds));
403
+ expect(new Set(backendOperationIds)).toEqual(new Set(frontendRequestBuilderOperationIds));
404
+ });
405
+ backendTest('backend conversation emitter result presentations stay in parity with frontend presenters', () => {
406
+ const backendResultPresentations = Array.from(new Set(extractObjectFieldStringLiterals(conversationCapabilityLiteral, 'resultPresentation')));
407
+ const customPresentationIds = extractObjectLiteralKeys(frontendSource, 'CUSTOM_RESULT_PRESENTERS');
408
+ const cardPresentationIds = extractObjectLiteralKeys(frontendSource, 'CARD_RESULT_PRESENTATION_REGISTRY');
409
+ const frontendResultPresentations = new Set([...customPresentationIds, ...cardPresentationIds]);
410
+ expect(new Set(backendResultPresentations)).toEqual(frontendResultPresentations);
411
+ });
412
+ backendTest('backend knowledge-operation execution presentations stay within frontend operation allowlist', () => {
413
+ const frontendOperationAllowedPresentations = extractOperationAllowedResultPresentationsFromFrontend(frontendSource);
414
+ const backendOperationPairs = extractBackendKnowledgeOperationPairs(conversationCapabilityLiteral);
415
+ expect(backendOperationPairs.length).toBeGreaterThan(0);
416
+ const backendOperationPresentationSetByOperationId = new Map();
417
+ backendOperationPairs.forEach((entry) => {
418
+ expect(frontendOperationAllowedPresentations[entry.operationId]).toBeDefined();
419
+ expect(frontendOperationAllowedPresentations[entry.operationId]).toContain(entry.resultPresentation);
420
+ const knownPresentations = backendOperationPresentationSetByOperationId.get(entry.operationId) || new Set();
421
+ knownPresentations.add(entry.resultPresentation);
422
+ backendOperationPresentationSetByOperationId.set(entry.operationId, knownPresentations);
423
+ });
424
+ backendOperationPresentationSetByOperationId.forEach((presentations) => {
425
+ expect(presentations.size).toBe(1);
426
+ });
427
+ });
428
+ backendTest('backend non-default operation presentations require explicit frontend overrides', () => {
429
+ const defaultMapping = extractOperationDefaultResultPresentationsFromFrontend(frontendSource);
430
+ const overrideMapping = extractOperationResultPresentationOverridesFromFrontend(frontendSource);
431
+ const backendOperationPairs = extractBackendKnowledgeOperationPairs(conversationCapabilityLiteral);
432
+ expect(backendOperationPairs.length).toBeGreaterThan(0);
433
+ backendOperationPairs.forEach(({ operationId, resultPresentation }) => {
434
+ const defaultPresentation = String(defaultMapping[operationId] || '').trim();
435
+ expect(defaultPresentation).toBeTruthy();
436
+ if (resultPresentation !== defaultPresentation) {
437
+ const operationOverrides = overrideMapping[operationId] || [];
438
+ expect(operationOverrides).toContain(resultPresentation);
439
+ }
440
+ });
441
+ });
442
+ backendTest('frontend override presentations must be exercised by backend capability emission', () => {
443
+ const overrideMapping = extractOperationResultPresentationOverridesFromFrontend(frontendSource);
444
+ const backendOperationPairs = extractBackendKnowledgeOperationPairs(conversationCapabilityLiteral);
445
+ const backendOperationPresentations = new Map();
446
+ backendOperationPairs.forEach(({ operationId, resultPresentation }) => {
447
+ const knownPresentations = backendOperationPresentations.get(operationId) || new Set();
448
+ knownPresentations.add(resultPresentation);
449
+ backendOperationPresentations.set(operationId, knownPresentations);
450
+ });
451
+ Object.entries(overrideMapping).forEach(([operationId, overridePresentations]) => {
452
+ const backendPresentations = backendOperationPresentations.get(operationId) || new Set();
453
+ overridePresentations.forEach((presentation) => {
454
+ expect(backendPresentations.has(presentation)).toBe(true);
455
+ });
456
+ });
457
+ });
458
+ backendTest('backend conversation emitter capabilities keep executable contract completeness', () => {
459
+ const capabilityObjectLiterals = extractTopLevelObjectLiteralsFromArrayLiteral(conversationCapabilityLiteral);
460
+ expect(capabilityObjectLiterals.length).toBeGreaterThan(0);
461
+ capabilityObjectLiterals.forEach((capabilityLiteral) => {
462
+ expect(capabilityLiteral).toMatch(/capabilityId\s*:\s*`[^`]+`|capabilityId\s*:\s*'[^']+'/);
463
+ expect(capabilityLiteral).toMatch(/actionId\s*:\s*'[^']+'/);
464
+ expect(capabilityLiteral).toMatch(/labelKey\s*:\s*'agentWorkspace\.actions\.[^']+'/);
465
+ expect(capabilityLiteral).toMatch(/failure\s*:\s*{[\s\S]*?messageKey\s*:\s*'agentWorkspace\.messages\.[^']+'/);
466
+ expect(capabilityLiteral).toMatch(/failure\s*:\s*{[\s\S]*?fallbackMessage\s*:\s*'[^']+'/);
467
+ expect(capabilityLiteral).toMatch(/execution\s*:\s*{[\s\S]*?kind\s*:\s*'[^']+'/);
468
+ const isKnowledgeOperation = /execution\s*:\s*{[\s\S]*?kind\s*:\s*'knowledge_operation'/.test(capabilityLiteral);
469
+ if (isKnowledgeOperation) {
470
+ expect(capabilityLiteral).toMatch(/execution\s*:\s*{[\s\S]*?operationId\s*:\s*'[^']+'/);
471
+ expect(capabilityLiteral).toMatch(/execution\s*:\s*{[\s\S]*?resultPresentation\s*:\s*'[^']+'/);
472
+ }
473
+ });
474
+ });
475
+ });