noteconnection 1.8.0 → 1.9.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/README.md +257 -1803
- package/dist/src/agent_workspace.contract.parity.test.js +105 -421
- package/dist/src/agent_workspace.frontend.test.js +410 -11
- package/dist/src/android.knowledgebase.picker.contract.test.js +102 -0
- package/dist/src/appimage.patchelf.test.js +113 -0
- package/dist/src/appimage.portability.test.js +156 -0
- package/dist/src/backend/FileLoader.js +18 -4
- package/dist/src/backend/FileLoader.test.js +125 -0
- package/dist/src/backend/GraphBuilder.identity.test.js +86 -0
- package/dist/src/backend/GraphBuilder.js +66 -18
- package/dist/src/backend/GraphBuilder.matching.test.js +127 -0
- package/dist/src/backend/GraphMetrics.js +0 -3
- package/dist/src/backend/ResourceIdentity.js +155 -0
- package/dist/src/backend/ResourceIdentity.test.js +113 -0
- package/dist/src/backend/algorithms/CycleDetection.js +0 -1
- package/dist/src/backend/algorithms/HybridEngine.js +0 -3
- package/dist/src/backend/algorithms/LayoutEngine.js +0 -1
- package/dist/src/backend/algorithms/StatisticalAnalyzer.js +0 -4
- package/dist/src/backend/algorithms/TopologicalSort.js +0 -2
- package/dist/src/backend/build_dag.js +0 -1
- package/dist/src/capacitor.bridge.serialization.contract.test.js +3 -0
- package/dist/src/capacitor.runtime.contract.test.js +11 -2
- package/dist/src/core/Graph.js +138 -42
- package/dist/src/core/Graph.test.js +74 -0
- package/dist/src/core/NoteConnection.js +2 -2
- package/dist/src/core/PathBridge.js +265 -2
- package/dist/src/core/ResourceReference.js +17 -0
- package/dist/src/desktop.godot.pack.test.js +142 -0
- package/dist/src/desktop.runtime.graph.test.js +66 -0
- package/dist/src/export/WorkspaceExportBundle.js +44 -0
- package/dist/src/export/WorkspaceExportBundle.test.js +61 -0
- package/dist/src/foundation.release.evidence.contract.test.js +127 -9
- package/dist/src/foundation.sqlite.runtime.contract.test.js +6 -0
- package/dist/src/frontend/README.md +257 -1803
- package/dist/src/frontend/agent_workspace.js +665 -7
- package/dist/src/frontend/index.html +31 -2
- package/dist/src/frontend/knowledge_projection_contract.js +230 -0
- package/dist/src/frontend/knowledge_projection_store.js +214 -0
- package/dist/src/frontend/libs/path_core.js +158 -42
- package/dist/src/frontend/locales/en.json +32 -0
- package/dist/src/frontend/locales/zh.json +32 -0
- package/dist/src/frontend/mobile_budget_runtime.js +33 -0
- package/dist/src/frontend/mobile_exact_analyzer.js +393 -0
- package/dist/src/frontend/mobile_identity_contract.js +221 -0
- package/dist/src/frontend/mobile_semantic_comparator.js +264 -0
- package/dist/src/frontend/path.html +6 -2
- package/dist/src/frontend/simulationWorker.js +1 -1
- package/dist/src/frontend/source_manager.js +110 -4
- package/dist/src/frontend/storage_provider.js +661 -71
- package/dist/src/frontend/styles.css +107 -13
- package/dist/src/frontend/workspace_panes.js +111 -7
- package/dist/src/frontend.runtime.assets.contract.test.js +81 -0
- package/dist/src/graph.answer.operator.contract.test.js +72 -0
- package/dist/src/index.js +6 -2
- package/dist/src/index.knowledge-root.test.js +118 -0
- package/dist/src/indexing/IndexLifecycle.js +22 -0
- package/dist/src/indexing/IndexLifecycle.test.js +24 -0
- package/dist/src/knowledge.api.contract.test.js +4 -2
- package/dist/src/knowledge_projection.contract.test.js +134 -0
- package/dist/src/knowledge_projection_store.test.js +200 -0
- package/dist/src/learning/AnswerQualityEvaluation.js +153 -0
- package/dist/src/learning/AnswerQualityEvaluation.test.js +118 -0
- package/dist/src/learning/KnowledgeLearningPlatform.js +4687 -3892
- package/dist/src/learning/KnowledgeLearningPlatform.persistence.test.js +418 -0
- package/dist/src/learning/KnowledgeLearningPlatform.test.js +243 -6
- package/dist/src/learning/KnowledgeWorkspaceConversationRegression.js +25 -1
- package/dist/src/learning/KnowledgeWorkspaceConversationRegression.test.js +13 -5
- package/dist/src/learning/MeasurementEvidenceConflicts.test.js +78 -0
- package/dist/src/learning/PublicAnswerContract.test.js +85 -0
- package/dist/src/learning/PublicEvidenceSelection.test.js +94 -0
- package/dist/src/learning/PublicMeasurementDisclosure.test.js +54 -0
- package/dist/src/learning/agentConversationExecution.js +211 -0
- package/dist/src/learning/agentConversationExecution.test.js +209 -0
- package/dist/src/learning/agentConversationSerialization.js +266 -0
- package/dist/src/learning/agentConversationSerialization.test.js +165 -0
- package/dist/src/learning/agentResponseBudget.js +179 -0
- package/dist/src/learning/agentResponseBudget.test.js +97 -0
- package/dist/src/learning/agentWorkspaceCapabilityContracts.js +65 -0
- package/dist/src/learning/answerReleaseReview.js +1191 -250
- package/dist/src/learning/answerReleaseReview.test.js +1293 -7
- package/dist/src/learning/answerTaskPlan.js +473 -0
- package/dist/src/learning/conversationComposer.js +627 -386
- package/dist/src/learning/conversationComposer.test.js +1403 -0
- package/dist/src/learning/evidenceContextAssembler.js +312 -120
- package/dist/src/learning/graphAnswerCoverage.js +37 -0
- package/dist/src/learning/graphAnswerCoverage.test.js +93 -0
- package/dist/src/learning/graphAnswerCoverageCalibration.js +59 -0
- package/dist/src/learning/graphAnswerCoverageCalibration.test.js +46 -0
- package/dist/src/learning/graphAnswerFacts.js +94 -0
- package/dist/src/learning/graphAnswerFacts.test.js +39 -0
- package/dist/src/learning/graphAnswerPlan.js +908 -0
- package/dist/src/learning/graphAnswerPlan.test.js +907 -0
- package/dist/src/learning/graphAnswerQualityCalibration.js +255 -0
- package/dist/src/learning/graphAnswerQualityCalibration.test.js +72 -0
- package/dist/src/learning/graphAnswerQualityPolicy.js +30 -0
- package/dist/src/learning/graphClaimMatcher.js +104 -0
- package/dist/src/learning/graphConditionedContext.js +109 -0
- package/dist/src/learning/graphConditionedContext.test.js +99 -0
- package/dist/src/learning/graphContextAssembler.js +3 -13
- package/dist/src/learning/graphContextAssembler.test.js +2 -2
- package/dist/src/learning/graphExpansionPolicy.js +22 -0
- package/dist/src/learning/graphExpansionPolicy.test.js +33 -0
- package/dist/src/learning/identityMetadata.test.js +26 -0
- package/dist/src/learning/index.js +1 -0
- package/dist/src/learning/mobileAnswerProjection.js +104 -0
- package/dist/src/learning/mobileAnswerProjection.test.js +102 -0
- package/dist/src/learning/queryBackend.js +34 -10
- package/dist/src/learning/queryBackend.test.js +21 -0
- package/dist/src/learning/ragContextPack.js +115 -16
- package/dist/src/learning/ragContextPack.test.js +151 -0
- package/dist/src/learning/ragEvidenceQuality.js +96 -0
- package/dist/src/learning/ragEvidenceQuality.test.js +29 -0
- package/dist/src/learning/ragPublicText.js +67 -4
- package/dist/src/learning/ragPublicText.test.js +57 -0
- package/dist/src/learning/ragSufficiencyJudge.js +11 -1
- package/dist/src/learning/ragSufficiencyProviderJudge.js +16 -26
- package/dist/src/learning/ragSufficiencyProviderJudge.test.js +51 -0
- package/dist/src/learning/requestNormalization.js +106 -0
- package/dist/src/learning/requestNormalization.test.js +101 -0
- package/dist/src/learning/store.js +116 -12
- package/dist/src/learning/store.test.js +299 -0
- package/dist/src/learning/vectorAccelerationAdapter.js +22 -6
- package/dist/src/learning/vectorAccelerationAdapter.test.js +30 -0
- package/dist/src/learning/workspaceHydration.js +168 -0
- package/dist/src/learning/workspaceHydration.test.js +30 -0
- package/dist/src/license.policy.contract.test.js +9 -4
- package/dist/src/markdown/MarkdownGateway.js +4 -0
- package/dist/src/markdown/MarkdownGateway.test.js +59 -0
- package/dist/src/middleware/SseResponseWriter.js +122 -0
- package/dist/src/middleware/SseResponseWriter.test.js +54 -0
- package/dist/src/middleware/auth.js +28 -7
- package/dist/src/middleware/auth.test.js +33 -0
- package/dist/src/middleware/index.js +2 -1
- package/dist/src/mobile.android.evidence.contract.test.js +146 -0
- package/dist/src/mobile.android.signing.contract.test.js +66 -0
- package/dist/src/mobile.artifact.contract.test.js +144 -0
- package/dist/src/mobile.budget.contract.test.js +90 -0
- package/dist/src/mobile.canonical-id.readiness.test.js +54 -0
- package/dist/src/mobile.graph.parity.contract.test.js +207 -0
- package/dist/src/mobile.identity.contract.test.js +66 -0
- package/dist/src/mobile.identity.corpus.manifest.test.js +72 -0
- package/dist/src/mobile.identity.corpus.test.js +40 -0
- package/dist/src/mobile.native.recovery.contract.test.js +64 -0
- package/dist/src/mobile.pipeline.test.js +11 -1
- package/dist/src/mobile.profile.contract.test.js +225 -0
- package/dist/src/mobile.semantic.parity.test.js +92 -0
- package/dist/src/mobile_exact_analyzer.test.js +113 -0
- package/dist/src/notemd/ContentGenerator.js +4 -9
- package/dist/src/notemd/FileProcessor.js +4 -9
- package/dist/src/notemd/NotemdService.js +12 -17
- package/dist/src/notemd/Translator.js +4 -9
- package/dist/src/notemd/progressReporter.js +9 -0
- package/dist/src/notemd.server.integration.test.js +119 -4
- package/dist/src/notemd.workflow.pipeline.test.js +1 -1
- package/dist/src/pathbridge.handshake.contract.test.js +29 -0
- package/dist/src/pathbridge.host-adapter.contract.test.js +133 -0
- package/dist/src/pathcore.bundle.contract.test.js +8 -0
- package/dist/src/platform/ExportProfile.js +28 -0
- package/dist/src/platform/MobileBudget.js +11 -0
- package/dist/src/platform/PlatformCapabilities.js +14 -0
- package/dist/src/platform/PlatformCapabilities.test.js +6 -0
- package/dist/src/query_backend.external_http.integration.test.js +2 -2
- package/dist/src/release.godot.mirror.contract.test.js +28 -4
- package/dist/src/resources/ResourceRegistry.js +40 -0
- package/dist/src/resources/ResourceRegistry.test.js +36 -0
- package/dist/src/routes/index.js +0 -4
- package/dist/src/routes/knowledge.js +46 -33
- package/dist/src/routes/knowledgePayload.js +185 -0
- package/dist/src/routes/knowledgePayload.test.js +53 -0
- package/dist/src/routes/markdown.js +8 -0
- package/dist/src/routes/notemd.js +990 -234
- package/dist/src/routes/registry.contract.test.js +5 -2
- package/dist/src/routes/registry.shadow.contract.test.js +22 -0
- package/dist/src/routes/render.js +14 -51
- package/dist/src/runtime.capabilities.test.js +18 -2
- package/dist/src/server.js +566 -1090
- package/dist/src/server.migration.test.js +417 -15
- package/dist/src/sidecar.build.lock.contract.test.js +201 -0
- package/dist/src/sidecar.freshness.contract.test.js +184 -0
- package/dist/src/sidecar.replacement.boundary.contract.test.js +6 -3
- package/dist/src/sidecar.supply.readiness.contract.test.js +11 -0
- package/dist/src/simulation.worker.offline.test.js +104 -0
- package/dist/src/storage.provider.capacitor.content.contract.test.js +4 -1
- package/dist/src/storage.provider.contract.test.js +152 -1
- package/dist/src/tauri.frontend.build.contract.test.js +8 -0
- package/dist/src/tauri.window.evidence.execution.test.js +68 -0
- package/dist/src/utils/RuntimePaths.js +6 -0
- package/dist/src/utils/RuntimePaths.test.js +27 -0
- package/dist/src/windows.installer.build.test.js +109 -0
- package/dist/src/windows.installer.payload.test.js +76 -0
- package/dist/src/windows.installer.runtime.test.js +69 -0
- package/dist/src/workspace/WorkspaceRegistry.js +13 -0
- package/package.json +32 -10
- package/dist/src/routes/data.js +0 -267
- package/dist/src/routes/diagnostics.js +0 -51
|
@@ -0,0 +1,225 @@
|
|
|
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 crypto = __importStar(require("crypto"));
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const PlatformCapabilities_1 = require("./platform/PlatformCapabilities");
|
|
40
|
+
const RenderMaterializer_1 = require("./platform/RenderMaterializer");
|
|
41
|
+
describe('mobile-slim profile contract', () => {
|
|
42
|
+
const repoRoot = path.resolve(__dirname, '..');
|
|
43
|
+
const analyzerPath = path.join(repoRoot, 'src', 'frontend', 'mobile_exact_analyzer.js');
|
|
44
|
+
const projectionContractPath = path.join(repoRoot, 'src', 'frontend', 'knowledge_projection_contract.js');
|
|
45
|
+
const verifierPath = path.join(repoRoot, 'scripts', 'verify-mobile-slim-budget.js');
|
|
46
|
+
const preparePath = path.join(repoRoot, 'scripts', 'prepare-mobile-slim.js');
|
|
47
|
+
test('declares sidecar-free local analysis with optional remote inference and hard budgets', () => {
|
|
48
|
+
const capabilities = (0, PlatformCapabilities_1.resolvePlatformCapabilities)({ exportProfileId: 'mobile-slim' });
|
|
49
|
+
expect(capabilities.retrieval.supportsSidecar).toBe(false);
|
|
50
|
+
expect(capabilities.retrieval.supportsLocalIngest).toBe(true);
|
|
51
|
+
expect(capabilities.retrieval.supportsLocalExactQuery).toBe(true);
|
|
52
|
+
expect(capabilities.retrieval.supportsRemoteInference).toBe(true);
|
|
53
|
+
expect(capabilities.retrieval.requiresRemoteInference).toBe(false);
|
|
54
|
+
expect(capabilities.export.assetBudgetBytes).toBe(25 * 1024 * 1024);
|
|
55
|
+
expect(capabilities.export.maxResidentBytes).toBe(256 * 1024 * 1024);
|
|
56
|
+
});
|
|
57
|
+
test('rejects SVG materialization for mobile even when explicitly requested', () => {
|
|
58
|
+
const decision = (0, RenderMaterializer_1.resolveRenderMaterializationDecision)({
|
|
59
|
+
exportProfileId: 'mobile-slim',
|
|
60
|
+
includeSvg: true,
|
|
61
|
+
includeStages: true,
|
|
62
|
+
rendererPreference: 'frontend',
|
|
63
|
+
});
|
|
64
|
+
expect(decision.includeSvg).toBe(false);
|
|
65
|
+
expect(decision.vectorSuppressed).toBe(true);
|
|
66
|
+
expect(decision.responseArtifact).toBe('png');
|
|
67
|
+
expect(decision.rendererPreference).toBe('local');
|
|
68
|
+
});
|
|
69
|
+
test('ships a callable bounded exact graph analyzer without retaining document bodies', () => {
|
|
70
|
+
expect(fs.existsSync(analyzerPath)).toBe(true);
|
|
71
|
+
const analyzer = require(analyzerPath);
|
|
72
|
+
const index = analyzer.createMobileExactIndex({
|
|
73
|
+
nodes: [
|
|
74
|
+
{ id: 'fundamentals/alpha', label: 'Alpha', content: 'must not be retained' },
|
|
75
|
+
{ id: 'fundamentals/beta', label: 'Beta', metadata: { tags: ['core'] } },
|
|
76
|
+
{ id: 'advanced/gamma', label: 'Gamma' },
|
|
77
|
+
],
|
|
78
|
+
edges: [
|
|
79
|
+
{ source: 'fundamentals/alpha', target: 'fundamentals/beta', type: 'prerequisite' },
|
|
80
|
+
{ source: 'fundamentals/beta', target: 'advanced/gamma', type: 'next' },
|
|
81
|
+
],
|
|
82
|
+
});
|
|
83
|
+
expect(index.searchExact('beta')).toEqual([
|
|
84
|
+
expect.objectContaining({ id: 'fundamentals/beta' }),
|
|
85
|
+
]);
|
|
86
|
+
expect(index.searchExact('core')).toEqual([
|
|
87
|
+
expect.objectContaining({ id: 'fundamentals/beta' }),
|
|
88
|
+
]);
|
|
89
|
+
expect(index.neighbors('fundamentals/beta')).toEqual([
|
|
90
|
+
expect.objectContaining({ id: 'advanced/gamma' }),
|
|
91
|
+
expect.objectContaining({ id: 'fundamentals/alpha' }),
|
|
92
|
+
]);
|
|
93
|
+
expect(index.shortestPath('fundamentals/alpha', 'advanced/gamma')).toEqual([
|
|
94
|
+
'fundamentals/alpha',
|
|
95
|
+
'fundamentals/beta',
|
|
96
|
+
'advanced/gamma',
|
|
97
|
+
]);
|
|
98
|
+
expect(index.statistics()).toEqual({ nodeCount: 3, edgeCount: 2 });
|
|
99
|
+
expect(JSON.stringify(index.searchExact('alpha'))).not.toContain('must not be retained');
|
|
100
|
+
});
|
|
101
|
+
test('normalizes exact lookup keys independently of the device locale', () => {
|
|
102
|
+
const analyzerSource = fs.readFileSync(analyzerPath, 'utf8');
|
|
103
|
+
const analyzer = require(analyzerPath);
|
|
104
|
+
const index = analyzer.createMobileExactIndex({
|
|
105
|
+
nodes: [{ id: 'unicode-i', label: '\u0130' }],
|
|
106
|
+
edges: [],
|
|
107
|
+
});
|
|
108
|
+
expect(analyzerSource).not.toContain('.toLocaleLowerCase(');
|
|
109
|
+
expect(index.searchExact('i\u0307')).toEqual([
|
|
110
|
+
expect.objectContaining({ id: 'unicode-i' }),
|
|
111
|
+
]);
|
|
112
|
+
});
|
|
113
|
+
test('does not cross the requested visited-node ceiling during path traversal', () => {
|
|
114
|
+
const analyzer = require(analyzerPath);
|
|
115
|
+
const index = analyzer.createMobileExactIndex({
|
|
116
|
+
nodes: [
|
|
117
|
+
{ id: 'source' },
|
|
118
|
+
{ id: 'first-branch' },
|
|
119
|
+
{ id: 'target' },
|
|
120
|
+
],
|
|
121
|
+
edges: [
|
|
122
|
+
{ source: 'source', target: 'first-branch' },
|
|
123
|
+
{ source: 'source', target: 'target' },
|
|
124
|
+
],
|
|
125
|
+
});
|
|
126
|
+
expect(index.shortestPath('source', 'target', 2, 2)).toBeNull();
|
|
127
|
+
});
|
|
128
|
+
test('exposes exact query and path operations through the runtime storage boundary', () => {
|
|
129
|
+
const storageProvider = fs.readFileSync(path.join(repoRoot, 'src', 'frontend', 'storage_provider.js'), 'utf8');
|
|
130
|
+
const indexHtml = fs.readFileSync(path.join(repoRoot, 'src', 'frontend', 'index.html'), 'utf8');
|
|
131
|
+
const analyzerScriptOffset = indexHtml.indexOf('<script src="mobile_exact_analyzer.js"></script>');
|
|
132
|
+
const identityScriptOffset = indexHtml.indexOf('<script src="mobile_identity_contract.js"></script>');
|
|
133
|
+
const storageScriptOffset = indexHtml.indexOf('<script src="storage_provider.js"></script>');
|
|
134
|
+
expect(storageProvider).toContain('async queryKnowledgeBaseExact(request)');
|
|
135
|
+
expect(storageProvider).toContain('async findKnowledgePath(request)');
|
|
136
|
+
expect(storageProvider).toContain("this.readGeneratedAsset('graph_data.json')");
|
|
137
|
+
expect(analyzerScriptOffset).toBeGreaterThan(-1);
|
|
138
|
+
expect(identityScriptOffset).toBeGreaterThan(analyzerScriptOffset);
|
|
139
|
+
expect(identityScriptOffset).toBeLessThan(storageScriptOffset);
|
|
140
|
+
expect(analyzerScriptOffset).toBeLessThan(storageScriptOffset);
|
|
141
|
+
});
|
|
142
|
+
test('loads one versioned projection contract before both mobile consumers', () => {
|
|
143
|
+
const projectionContract = fs.readFileSync(projectionContractPath, 'utf8');
|
|
144
|
+
const storageProvider = fs.readFileSync(path.join(repoRoot, 'src', 'frontend', 'storage_provider.js'), 'utf8');
|
|
145
|
+
const indexHtml = fs.readFileSync(path.join(repoRoot, 'src', 'frontend', 'index.html'), 'utf8');
|
|
146
|
+
const projectionScriptOffset = indexHtml.indexOf('<script src="knowledge_projection_contract.js"></script>');
|
|
147
|
+
expect(projectionContract).toContain('schemaVersion: SCHEMA_VERSION');
|
|
148
|
+
expect(projectionContract).toContain('MAX_NEIGHBORS');
|
|
149
|
+
expect(storageProvider).toContain('window.NoteConnectionKnowledgeProjection');
|
|
150
|
+
expect(storageProvider).toContain('createKnowledgeProjection');
|
|
151
|
+
expect(storageProvider).toContain('createFileProjectionStore');
|
|
152
|
+
expect(storageProvider).toContain("fileName: 'graph_data.json'");
|
|
153
|
+
expect(projectionScriptOffset).toBeGreaterThan(-1);
|
|
154
|
+
expect(projectionScriptOffset).toBeLessThan(indexHtml.indexOf('<script src="mobile_exact_analyzer.js"></script>'));
|
|
155
|
+
expect(projectionScriptOffset).toBeLessThan(indexHtml.indexOf('<script src="storage_provider.js"></script>'));
|
|
156
|
+
});
|
|
157
|
+
test('fails closed for oversized, forbidden, and over-RSS mobile staging evidence', () => {
|
|
158
|
+
expect(fs.existsSync(verifierPath)).toBe(true);
|
|
159
|
+
const verifier = require(verifierPath);
|
|
160
|
+
const fixtureRoot = fs.mkdtempSync(path.join(repoRoot, '.mobile-slim-contract-'));
|
|
161
|
+
try {
|
|
162
|
+
fs.writeFileSync(path.join(fixtureRoot, 'index.html'), crypto.randomBytes(2048));
|
|
163
|
+
expect(() => verifier.assertMobileSlimBudget({
|
|
164
|
+
stagingDir: fixtureRoot,
|
|
165
|
+
assetBudgetBytes: 128,
|
|
166
|
+
maxResidentBytes: 1024,
|
|
167
|
+
})).toThrow(/compressed payload/i);
|
|
168
|
+
fs.rmSync(path.join(fixtureRoot, 'index.html'));
|
|
169
|
+
fs.writeFileSync(path.join(fixtureRoot, 'server-aarch64-linux'), 'forbidden');
|
|
170
|
+
expect(() => verifier.assertMobileSlimBudget({
|
|
171
|
+
stagingDir: fixtureRoot,
|
|
172
|
+
assetBudgetBytes: 4096,
|
|
173
|
+
maxResidentBytes: 1024,
|
|
174
|
+
})).toThrow(/forbidden mobile artifact/i);
|
|
175
|
+
fs.rmSync(path.join(fixtureRoot, 'server-aarch64-linux'));
|
|
176
|
+
fs.writeFileSync(path.join(fixtureRoot, 'index.html'), 'ok');
|
|
177
|
+
const rssEvidencePath = path.join(fixtureRoot, 'rss-evidence.json');
|
|
178
|
+
fs.writeFileSync(rssEvidencePath, JSON.stringify({ peakResidentBytes: 2048 }));
|
|
179
|
+
expect(() => verifier.assertMobileSlimBudget({
|
|
180
|
+
stagingDir: fixtureRoot,
|
|
181
|
+
assetBudgetBytes: 4096,
|
|
182
|
+
maxResidentBytes: 1024,
|
|
183
|
+
rssEvidencePath,
|
|
184
|
+
})).toThrow(/peak RSS/i);
|
|
185
|
+
}
|
|
186
|
+
finally {
|
|
187
|
+
fs.rmSync(fixtureRoot, { recursive: true, force: true });
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
test('routes both Android packagers through the deterministic mobile staging directory', () => {
|
|
191
|
+
expect(fs.existsSync(preparePath)).toBe(true);
|
|
192
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(repoRoot, 'package.json'), 'utf8'));
|
|
193
|
+
const capacitorConfig = fs.readFileSync(path.join(repoRoot, 'capacitor.config.ts'), 'utf8');
|
|
194
|
+
const capacitorBuild = fs.readFileSync(path.join(repoRoot, 'build_apk.bat'), 'utf8');
|
|
195
|
+
const tauriAndroidConfig = JSON.parse(fs.readFileSync(path.join(repoRoot, 'src-tauri', 'tauri.android.conf.json'), 'utf8'));
|
|
196
|
+
expect(pkg.scripts['mobile:prepare:slim']).toContain('prepare-mobile-slim.js');
|
|
197
|
+
expect(pkg.scripts['mobile:prepare:slim']).toContain('verify-mobile-slim-budget.js');
|
|
198
|
+
expect(pkg.scripts['tauri:android:init']).toContain('mobile:prepare:slim');
|
|
199
|
+
expect(pkg.scripts['verify:mobile:slim:budget']).toContain('verify-mobile-slim-budget.js');
|
|
200
|
+
expect(pkg.scripts['tauri:android:build']).toContain('mobile:prepare:slim');
|
|
201
|
+
expect(pkg.scripts['tauri:android:build']).not.toContain('build:sidecar');
|
|
202
|
+
expect(capacitorConfig).toContain('NOTE_CONNECTION_MOBILE_WEB_DIR');
|
|
203
|
+
expect(capacitorBuild).toContain('npm run mobile:prepare:slim');
|
|
204
|
+
expect(capacitorBuild).toContain('NOTE_CONNECTION_MOBILE_WEB_DIR');
|
|
205
|
+
expect(tauriAndroidConfig.build?.frontendDist).toBe('../dist/mobile-slim/frontend');
|
|
206
|
+
expect(tauriAndroidConfig.bundle?.externalBin).toEqual([]);
|
|
207
|
+
});
|
|
208
|
+
test('keeps Godot Android integration explicit instead of enabling it in mobile-slim', () => {
|
|
209
|
+
const runner = fs.readFileSync(path.join(repoRoot, 'scripts', 'run-tauri-android.js'), 'utf8');
|
|
210
|
+
const patcher = fs.readFileSync(path.join(repoRoot, 'scripts', 'apply-tauri-android-pathmode.js'), 'utf8');
|
|
211
|
+
expect(runner).toContain('NOTE_CONNECTION_ANDROID_INCLUDE_GODOT_PATHMODE');
|
|
212
|
+
expect(runner).toContain("runPathmodePatch({ mode: 'disable'");
|
|
213
|
+
expect(patcher).toContain("process.argv.includes('--disable')");
|
|
214
|
+
expect(patcher).toContain('removePathmodeAssets');
|
|
215
|
+
});
|
|
216
|
+
test('keeps the semantic comparator out of mobile-slim runtime staging', () => {
|
|
217
|
+
const prepareSource = fs.readFileSync(preparePath, 'utf8');
|
|
218
|
+
expect(prepareSource).toContain('mobile_semantic_comparator\\.js');
|
|
219
|
+
});
|
|
220
|
+
test('does not allocate the full-content graph on Android runtime builds', () => {
|
|
221
|
+
const rustSource = fs.readFileSync(path.join(repoRoot, 'src-tauri', 'src', 'lib.rs'), 'utf8');
|
|
222
|
+
expect(rustSource).toContain('#[cfg(not(target_os = "android"))]\n let full_nodes');
|
|
223
|
+
expect(rustSource).toContain('#[cfg(not(target_os = "android"))]\n let full_graph');
|
|
224
|
+
});
|
|
225
|
+
});
|
|
@@ -0,0 +1,92 @@
|
|
|
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 path = __importStar(require("path"));
|
|
37
|
+
const comparator = require(path.resolve(__dirname, 'frontend', 'mobile_semantic_comparator.js'));
|
|
38
|
+
const projectionContract = require(path.resolve(__dirname, 'frontend', 'knowledge_projection_contract.js'));
|
|
39
|
+
describe('cross-host mobile semantic parity', () => {
|
|
40
|
+
test('matches canonical nodes and directed edge provenance across host-specific ids', () => {
|
|
41
|
+
const left = projectionContract.createKnowledgeProjection({
|
|
42
|
+
nodes: [
|
|
43
|
+
{ id: 'base', canonicalId: 'financial/base', sourceUri: 'note://workspace/v1/financial/base.md' },
|
|
44
|
+
{ id: 'intro', canonicalId: 'financial/intro', sourceUri: 'note://workspace/v1/financial/intro.md' },
|
|
45
|
+
],
|
|
46
|
+
edges: [{
|
|
47
|
+
source: 'base',
|
|
48
|
+
target: 'intro',
|
|
49
|
+
sourceUri: 'note://workspace/v1/financial/base.md',
|
|
50
|
+
targetUri: 'note://workspace/v1/financial/intro.md',
|
|
51
|
+
type: 'explicit-prerequisite',
|
|
52
|
+
kind: 'explicit',
|
|
53
|
+
provenance: 'explicit-prerequisite',
|
|
54
|
+
}],
|
|
55
|
+
});
|
|
56
|
+
const right = projectionContract.createKnowledgeProjection({
|
|
57
|
+
nodes: [
|
|
58
|
+
{ id: 'financial/base', canonicalId: 'financial/base', sourceUri: 'note://workspace/v1/financial/base.md' },
|
|
59
|
+
{ id: 'financial/intro', canonicalId: 'financial/intro', sourceUri: 'note://workspace/v1/financial/intro.md' },
|
|
60
|
+
],
|
|
61
|
+
edges: [{
|
|
62
|
+
source: 'financial/base',
|
|
63
|
+
target: 'financial/intro',
|
|
64
|
+
type: 'explicit-prerequisite',
|
|
65
|
+
kind: 'explicit',
|
|
66
|
+
provenance: 'explicit-prerequisite',
|
|
67
|
+
}],
|
|
68
|
+
});
|
|
69
|
+
expect(comparator.compareSemanticProjections(left, right).equal).toBe(true);
|
|
70
|
+
expect(() => comparator.assertSemanticParity(left, right, 'fixture')).not.toThrow();
|
|
71
|
+
});
|
|
72
|
+
test('reports provenance changes instead of collapsing same-endpoint edges', () => {
|
|
73
|
+
const left = {
|
|
74
|
+
nodes: [
|
|
75
|
+
{ id: 'a', canonicalId: 'a', sourceUri: 'note://workspace/v1/a.md' },
|
|
76
|
+
{ id: 'b', canonicalId: 'b', sourceUri: 'note://workspace/v1/b.md' },
|
|
77
|
+
],
|
|
78
|
+
edges: [{ source: 'a', target: 'b', type: 'wiki-link', provenance: 'wiki-link' }],
|
|
79
|
+
};
|
|
80
|
+
const right = {
|
|
81
|
+
nodes: [
|
|
82
|
+
{ id: 'a', canonicalId: 'a', sourceUri: 'note://workspace/v1/a.md' },
|
|
83
|
+
{ id: 'b', canonicalId: 'b', sourceUri: 'note://workspace/v1/b.md' },
|
|
84
|
+
],
|
|
85
|
+
edges: [{ source: 'a', target: 'b', type: 'markdown-link', provenance: 'markdown-link' }],
|
|
86
|
+
};
|
|
87
|
+
const comparison = comparator.compareSemanticProjections(left, right);
|
|
88
|
+
expect(comparison.equal).toBe(false);
|
|
89
|
+
expect(comparison.extraEdges.length).toBeGreaterThan(0);
|
|
90
|
+
expect(() => comparator.assertSemanticParity(left, right, 'provenance')).toThrow(/semantic projection parity failed/);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
@@ -0,0 +1,113 @@
|
|
|
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 path = __importStar(require("path"));
|
|
37
|
+
// The analyzer is deliberately a browser-compatible CommonJS/IIFE artifact so
|
|
38
|
+
// the same projection can be replayed in Capacitor and the desktop test runner.
|
|
39
|
+
const analyzer = require(path.resolve(__dirname, 'frontend', 'mobile_exact_analyzer.js'));
|
|
40
|
+
describe('mobile exact projection contract', () => {
|
|
41
|
+
test('indexes stable URI aliases and separates explicit from inferred edges', () => {
|
|
42
|
+
const index = analyzer.createMobileExactIndex({
|
|
43
|
+
nodes: [
|
|
44
|
+
{
|
|
45
|
+
id: 'Legacy A',
|
|
46
|
+
label: 'A',
|
|
47
|
+
sourceUri: 'note://workspace/v1/a.md',
|
|
48
|
+
identityAliases: ['a.md'],
|
|
49
|
+
metadata: { tags: ['algebra'] },
|
|
50
|
+
},
|
|
51
|
+
{ id: 'B', label: 'B' },
|
|
52
|
+
],
|
|
53
|
+
edges: [
|
|
54
|
+
{ source: 'Legacy A', target: 'B', type: 'explicit-prerequisite' },
|
|
55
|
+
{ source: 'B', target: 'Legacy A', type: 'vector-association' },
|
|
56
|
+
],
|
|
57
|
+
});
|
|
58
|
+
expect(index.searchExact('note://workspace/v1/a.md', 5)[0]).toEqual(expect.objectContaining({
|
|
59
|
+
id: 'Legacy A',
|
|
60
|
+
sourceUri: 'note://workspace/v1/a.md',
|
|
61
|
+
}));
|
|
62
|
+
expect(index.neighbors('note://workspace/v1/a.md', 5, ['explicit'])).toEqual([
|
|
63
|
+
expect.objectContaining({ id: 'B', edgeKind: 'explicit' }),
|
|
64
|
+
]);
|
|
65
|
+
expect(index.statistics({ includeProvenance: true })).toEqual(expect.objectContaining({
|
|
66
|
+
projectionVersion: 1,
|
|
67
|
+
edgeCount: 2,
|
|
68
|
+
explicitEdgeCount: 1,
|
|
69
|
+
inferredEdgeCount: 1,
|
|
70
|
+
}));
|
|
71
|
+
});
|
|
72
|
+
test('resolves a source URI in bounded path queries', () => {
|
|
73
|
+
const index = analyzer.createMobileExactIndex({
|
|
74
|
+
nodes: [
|
|
75
|
+
{ id: 'A', sourceUri: 'note://workspace/v1/a.md' },
|
|
76
|
+
{ id: 'B', sourceUri: 'note://workspace/v1/b.md' },
|
|
77
|
+
],
|
|
78
|
+
edges: [{ source: 'A', target: 'B', type: 'sequence' }],
|
|
79
|
+
});
|
|
80
|
+
expect(index.shortestPath('note://workspace/v1/a.md', 'note://workspace/v1/b.md', 4, 10)).toEqual(['A', 'B']);
|
|
81
|
+
});
|
|
82
|
+
test('resolves a path-derived canonical id without changing the legacy node id', () => {
|
|
83
|
+
const index = analyzer.createMobileExactIndex({
|
|
84
|
+
nodes: [{ id: 'Index', canonicalId: 'algebra/index', label: 'Index' }],
|
|
85
|
+
edges: [],
|
|
86
|
+
});
|
|
87
|
+
expect(index.searchExact('algebra/index', 5)).toEqual([
|
|
88
|
+
expect.objectContaining({ id: 'Index', canonicalId: 'algebra/index' }),
|
|
89
|
+
]);
|
|
90
|
+
});
|
|
91
|
+
test('builds a bounded prerequisite-aware learning route from explicit graph edges', () => {
|
|
92
|
+
const index = analyzer.createMobileExactIndex({
|
|
93
|
+
nodes: [
|
|
94
|
+
{ id: 'water', label: 'Water molecules' },
|
|
95
|
+
{ id: 'ice', label: 'Amorphous ice' },
|
|
96
|
+
{ id: 'rdf', label: 'Radial distribution function g(r)' },
|
|
97
|
+
{ id: 'application', label: 'Applications' },
|
|
98
|
+
],
|
|
99
|
+
edges: [
|
|
100
|
+
{ source: 'water', target: 'ice', type: 'explicit-prerequisite' },
|
|
101
|
+
{ source: 'ice', target: 'rdf', type: 'sequence' },
|
|
102
|
+
{ source: 'ice', target: 'application', type: 'application' },
|
|
103
|
+
],
|
|
104
|
+
});
|
|
105
|
+
expect(index.learningRoute('ice', 6)).toEqual([
|
|
106
|
+
expect.objectContaining({ nodeId: 'water', role: 'prerequisite', order: 1, orderingBasis: 'explicit_prerequisite' }),
|
|
107
|
+
expect.objectContaining({ nodeId: 'ice', role: 'core', order: 2 }),
|
|
108
|
+
expect.objectContaining({ nodeId: 'rdf', role: 'mechanism', order: 3 }),
|
|
109
|
+
expect.objectContaining({ nodeId: 'application', role: 'application', order: 4 }),
|
|
110
|
+
]);
|
|
111
|
+
expect(index.learningRoute('ice', 2)).toHaveLength(2);
|
|
112
|
+
});
|
|
113
|
+
});
|
|
@@ -41,12 +41,7 @@ const constants_1 = require("./constants");
|
|
|
41
41
|
const LlmProvider_1 = require("./LlmProvider");
|
|
42
42
|
const PromptManager_1 = require("./PromptManager");
|
|
43
43
|
const types_1 = require("./types");
|
|
44
|
-
|
|
45
|
-
return {
|
|
46
|
-
report: () => undefined,
|
|
47
|
-
isCancelled: () => false,
|
|
48
|
-
};
|
|
49
|
-
}
|
|
44
|
+
const progressReporter_1 = require("./progressReporter");
|
|
50
45
|
function isTextExtension(filePath) {
|
|
51
46
|
return constants_1.NOTEMD_SUPPORTED_TEXT_EXTENSIONS.has(path.extname(filePath).toLowerCase());
|
|
52
47
|
}
|
|
@@ -56,7 +51,7 @@ class ContentGenerator {
|
|
|
56
51
|
this.promptManager = promptManager;
|
|
57
52
|
this.batchProcessor = batchProcessor;
|
|
58
53
|
}
|
|
59
|
-
async generateFromTitle(request, settings, reporter =
|
|
54
|
+
async generateFromTitle(request, settings, reporter = (0, progressReporter_1.createNoopProgressReporter)(), signal) {
|
|
60
55
|
const title = String(request.title || '').trim();
|
|
61
56
|
if (!title) {
|
|
62
57
|
throw new types_1.ValidationError('Missing title.');
|
|
@@ -90,7 +85,7 @@ class ContentGenerator {
|
|
|
90
85
|
reporter.report({ type: 'done', message: `Generated content for "${title}"`, percent: 100 });
|
|
91
86
|
return result.text.trim();
|
|
92
87
|
}
|
|
93
|
-
async generateForFile(filePath, settings, reporter =
|
|
88
|
+
async generateForFile(filePath, settings, reporter = (0, progressReporter_1.createNoopProgressReporter)(), signal) {
|
|
94
89
|
const absoluteFilePath = path.resolve(String(filePath || '').trim());
|
|
95
90
|
if (!absoluteFilePath) {
|
|
96
91
|
throw new types_1.ValidationError('Missing file path.');
|
|
@@ -113,7 +108,7 @@ class ContentGenerator {
|
|
|
113
108
|
generated: true,
|
|
114
109
|
};
|
|
115
110
|
}
|
|
116
|
-
async generateFolderFromTitles(folderPath, settings, reporter =
|
|
111
|
+
async generateFolderFromTitles(folderPath, settings, reporter = (0, progressReporter_1.createNoopProgressReporter)(), signal) {
|
|
117
112
|
const absoluteFolder = path.resolve(String(folderPath || '').trim());
|
|
118
113
|
if (!absoluteFolder) {
|
|
119
114
|
throw new types_1.ValidationError('Missing folder path.');
|
|
@@ -42,6 +42,7 @@ const LlmProvider_1 = require("./LlmProvider");
|
|
|
42
42
|
const PromptManager_1 = require("./PromptManager");
|
|
43
43
|
const types_1 = require("./types");
|
|
44
44
|
const constants_1 = require("./constants");
|
|
45
|
+
const progressReporter_1 = require("./progressReporter");
|
|
45
46
|
function countWords(text) {
|
|
46
47
|
return text
|
|
47
48
|
.trim()
|
|
@@ -71,12 +72,6 @@ function looksLikeConcept(raw) {
|
|
|
71
72
|
}
|
|
72
73
|
return true;
|
|
73
74
|
}
|
|
74
|
-
function defaultReporter() {
|
|
75
|
-
return {
|
|
76
|
-
report: () => undefined,
|
|
77
|
-
isCancelled: () => false,
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
75
|
class FileProcessor {
|
|
81
76
|
constructor(llmClient = new LlmProvider_1.LlmProviderClient(), promptManager = new PromptManager_1.PromptManager(), duplicateDetector = new DuplicateDetector_1.DuplicateDetector(), batchProcessor = new BatchProcessor_1.BatchProcessor()) {
|
|
82
77
|
this.llmClient = llmClient;
|
|
@@ -105,7 +100,7 @@ class FileProcessor {
|
|
|
105
100
|
}
|
|
106
101
|
return chunks.length > 0 ? chunks : [String(content || '')];
|
|
107
102
|
}
|
|
108
|
-
async extractConceptsFromText(content, settings, reporter =
|
|
103
|
+
async extractConceptsFromText(content, settings, reporter = (0, progressReporter_1.createNoopProgressReporter)(), signal) {
|
|
109
104
|
const concepts = new Set();
|
|
110
105
|
const chunks = this.splitContent(content, settings.chunkWordCount);
|
|
111
106
|
const provider = (0, LlmProvider_1.selectProviderForTask)(settings, 'extractConcepts');
|
|
@@ -151,7 +146,7 @@ class FileProcessor {
|
|
|
151
146
|
}
|
|
152
147
|
return concepts;
|
|
153
148
|
}
|
|
154
|
-
async processFile(request, settings, reporter =
|
|
149
|
+
async processFile(request, settings, reporter = (0, progressReporter_1.createNoopProgressReporter)(), signal) {
|
|
155
150
|
const filePath = path.resolve(String(request.filePath || '').trim());
|
|
156
151
|
if (!filePath) {
|
|
157
152
|
throw new types_1.ValidationError('Missing filePath.');
|
|
@@ -208,7 +203,7 @@ class FileProcessor {
|
|
|
208
203
|
changed,
|
|
209
204
|
};
|
|
210
205
|
}
|
|
211
|
-
async processFolder(request, settings, reporter =
|
|
206
|
+
async processFolder(request, settings, reporter = (0, progressReporter_1.createNoopProgressReporter)(), signal) {
|
|
212
207
|
const folderPath = path.resolve(String(request.folderPath || '').trim());
|
|
213
208
|
if (!folderPath) {
|
|
214
209
|
throw new types_1.ValidationError('Missing folderPath.');
|
|
@@ -47,12 +47,7 @@ const SearchManager_1 = require("./search/SearchManager");
|
|
|
47
47
|
const diagramGenerationService_1 = require("./diagram/diagramGenerationService");
|
|
48
48
|
const LlmProvider_1 = require("./LlmProvider");
|
|
49
49
|
const types_1 = require("./types");
|
|
50
|
-
|
|
51
|
-
return {
|
|
52
|
-
report: () => undefined,
|
|
53
|
-
isCancelled: () => false,
|
|
54
|
-
};
|
|
55
|
-
}
|
|
50
|
+
const progressReporter_1 = require("./progressReporter");
|
|
56
51
|
class NotemdService {
|
|
57
52
|
constructor(fileProcessor = new FileProcessor_1.FileProcessor(), translator = new Translator_1.Translator(), contentGenerator = new ContentGenerator_1.ContentGenerator(), mermaidProcessor = new MermaidProcessor_1.MermaidProcessor(), formulaFixer = new FormulaFixer_1.FormulaFixer(), duplicateDetector = new DuplicateDetector_1.DuplicateDetector(), llmProviderClient = new LlmProvider_1.LlmProviderClient()) {
|
|
58
53
|
// ── Batch progress tracking ──
|
|
@@ -65,22 +60,22 @@ class NotemdService {
|
|
|
65
60
|
this.duplicateDetector = duplicateDetector;
|
|
66
61
|
this.llmProviderClient = llmProviderClient;
|
|
67
62
|
}
|
|
68
|
-
processFile(request, settings, reporter =
|
|
63
|
+
processFile(request, settings, reporter = (0, progressReporter_1.createNoopProgressReporter)(), signal) {
|
|
69
64
|
return this.fileProcessor.processFile(request, settings, reporter, signal);
|
|
70
65
|
}
|
|
71
|
-
processFolder(request, settings, reporter =
|
|
66
|
+
processFolder(request, settings, reporter = (0, progressReporter_1.createNoopProgressReporter)(), signal) {
|
|
72
67
|
return this.fileProcessor.processFolder(request, settings, reporter, signal);
|
|
73
68
|
}
|
|
74
|
-
translateFile(request, settings, reporter =
|
|
69
|
+
translateFile(request, settings, reporter = (0, progressReporter_1.createNoopProgressReporter)(), signal) {
|
|
75
70
|
return this.translator.translateFile(request, settings, reporter, signal);
|
|
76
71
|
}
|
|
77
|
-
translateFolder(folderPath, targetLanguage, settings, reporter =
|
|
72
|
+
translateFolder(folderPath, targetLanguage, settings, reporter = (0, progressReporter_1.createNoopProgressReporter)(), signal) {
|
|
78
73
|
return this.translator.translateFolder(folderPath, targetLanguage, settings, reporter, signal);
|
|
79
74
|
}
|
|
80
|
-
generateContent(title, context, settings, reporter =
|
|
75
|
+
generateContent(title, context, settings, reporter = (0, progressReporter_1.createNoopProgressReporter)(), signal) {
|
|
81
76
|
return this.contentGenerator.generateFromTitle({ title, context }, settings, reporter, signal);
|
|
82
77
|
}
|
|
83
|
-
generateFolderContent(folderPath, settings, reporter =
|
|
78
|
+
generateFolderContent(folderPath, settings, reporter = (0, progressReporter_1.createNoopProgressReporter)(), signal) {
|
|
84
79
|
return this.contentGenerator.generateFolderFromTitles(folderPath, settings, reporter, signal);
|
|
85
80
|
}
|
|
86
81
|
async batchFixMermaid(folderPath, inPlace = true) {
|
|
@@ -192,7 +187,7 @@ class NotemdService {
|
|
|
192
187
|
duplicateWikiLinks: this.duplicateDetector.detectDuplicateWikiLinks(source),
|
|
193
188
|
};
|
|
194
189
|
}
|
|
195
|
-
async extractConcepts(filePath, settings, reporter =
|
|
190
|
+
async extractConcepts(filePath, settings, reporter = (0, progressReporter_1.createNoopProgressReporter)(), signal) {
|
|
196
191
|
const resolvedPath = path.resolve(String(filePath || '').trim());
|
|
197
192
|
if (!resolvedPath) {
|
|
198
193
|
throw new types_1.ValidationError('Missing filePath.');
|
|
@@ -205,7 +200,7 @@ class NotemdService {
|
|
|
205
200
|
};
|
|
206
201
|
}
|
|
207
202
|
// ── Workflow Pipeline (NoteConnection native) ──
|
|
208
|
-
async runWorkflow(request, settings, reporter =
|
|
203
|
+
async runWorkflow(request, settings, reporter = (0, progressReporter_1.createNoopProgressReporter)(), signal) {
|
|
209
204
|
const resolvedPath = path.resolve(String(request.filePath || '').trim());
|
|
210
205
|
if (!resolvedPath)
|
|
211
206
|
throw new types_1.ValidationError('Missing filePath.');
|
|
@@ -326,7 +321,7 @@ class NotemdService {
|
|
|
326
321
|
errors,
|
|
327
322
|
};
|
|
328
323
|
}
|
|
329
|
-
async runBatchWorkflow(request, settings, reporter =
|
|
324
|
+
async runBatchWorkflow(request, settings, reporter = (0, progressReporter_1.createNoopProgressReporter)(), signal) {
|
|
330
325
|
const resolvedFolderPath = path.resolve(String(request.folderPath || '').trim());
|
|
331
326
|
if (!resolvedFolderPath)
|
|
332
327
|
throw new types_1.ValidationError('Missing folderPath.');
|
|
@@ -407,7 +402,7 @@ class NotemdService {
|
|
|
407
402
|
};
|
|
408
403
|
}
|
|
409
404
|
// Backward-compatible wrapper — uses knowledge-base-root-relative output path
|
|
410
|
-
async oneClickExtract(filePath, settings, reporter =
|
|
405
|
+
async oneClickExtract(filePath, settings, reporter = (0, progressReporter_1.createNoopProgressReporter)(), signal) {
|
|
411
406
|
const resolvedPath = path.resolve(String(filePath || '').trim());
|
|
412
407
|
const kbRoot = this.resolveKnowledgeBaseRootForFile(resolvedPath);
|
|
413
408
|
const outputFolderPath = path.join(kbRoot, path.basename(resolvedPath, path.extname(resolvedPath)));
|
|
@@ -597,7 +592,7 @@ class NotemdService {
|
|
|
597
592
|
};
|
|
598
593
|
}
|
|
599
594
|
// ── Extract original text (obsidian-notemd v1.8.4) ──
|
|
600
|
-
async extractOriginalText(request, _settings, _reporter =
|
|
595
|
+
async extractOriginalText(request, _settings, _reporter = (0, progressReporter_1.createNoopProgressReporter)(), _signal) {
|
|
601
596
|
const resolvedPath = path.resolve(String(request.filePath || '').trim());
|
|
602
597
|
if (!resolvedPath)
|
|
603
598
|
throw new types_1.ValidationError('Missing filePath.');
|
|
@@ -41,12 +41,7 @@ const constants_1 = require("./constants");
|
|
|
41
41
|
const LlmProvider_1 = require("./LlmProvider");
|
|
42
42
|
const PromptManager_1 = require("./PromptManager");
|
|
43
43
|
const types_1 = require("./types");
|
|
44
|
-
|
|
45
|
-
return {
|
|
46
|
-
report: () => undefined,
|
|
47
|
-
isCancelled: () => false,
|
|
48
|
-
};
|
|
49
|
-
}
|
|
44
|
+
const progressReporter_1 = require("./progressReporter");
|
|
50
45
|
function countWords(text) {
|
|
51
46
|
return text
|
|
52
47
|
.trim()
|
|
@@ -80,7 +75,7 @@ class Translator {
|
|
|
80
75
|
this.promptManager = promptManager;
|
|
81
76
|
this.batchProcessor = batchProcessor;
|
|
82
77
|
}
|
|
83
|
-
async translateText(content, targetLanguage, settings, reporter =
|
|
78
|
+
async translateText(content, targetLanguage, settings, reporter = (0, progressReporter_1.createNoopProgressReporter)(), signal) {
|
|
84
79
|
const provider = (0, LlmProvider_1.selectProviderForTask)(settings, 'translate');
|
|
85
80
|
const model = (0, LlmProvider_1.selectModelForTask)(settings, 'translate', provider);
|
|
86
81
|
const chunks = splitByWordCount(content, settings.chunkWordCount);
|
|
@@ -117,7 +112,7 @@ class Translator {
|
|
|
117
112
|
}
|
|
118
113
|
return translatedChunks.join('\n\n').trim();
|
|
119
114
|
}
|
|
120
|
-
async translateFile(request, settings, reporter =
|
|
115
|
+
async translateFile(request, settings, reporter = (0, progressReporter_1.createNoopProgressReporter)(), signal) {
|
|
121
116
|
const filePath = path.resolve(String(request.filePath || '').trim());
|
|
122
117
|
if (!filePath) {
|
|
123
118
|
throw new types_1.ValidationError('Missing filePath.');
|
|
@@ -144,7 +139,7 @@ class Translator {
|
|
|
144
139
|
changed: translated !== source || outputPath !== filePath,
|
|
145
140
|
};
|
|
146
141
|
}
|
|
147
|
-
async translateFolder(folderPath, targetLanguage, settings, reporter =
|
|
142
|
+
async translateFolder(folderPath, targetLanguage, settings, reporter = (0, progressReporter_1.createNoopProgressReporter)(), signal) {
|
|
148
143
|
const root = path.resolve(String(folderPath || '').trim());
|
|
149
144
|
const stats = await this.stat(root);
|
|
150
145
|
if (!stats.isDirectory()) {
|