@neuralis/brain-core 0.3.1 → 0.4.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 +88 -1417
- package/app/README.md +4 -4
- package/app/cards/FilesystemCardShell.tsx +42 -4
- package/app/cards/FilesystemChangeCard.tsx +34 -11
- package/app/cards/README.md +6 -5
- package/app/cards/diffUtils.ts +99 -1
- package/app/filesystem/FilesystemHost.tsx +24 -2
- package/app/filesystem/README.md +1 -1
- package/app/filesystem/api/README.md +3 -3
- package/app/filesystem/api/index.ts +38 -14
- package/app/filesystem/api/projectPackages.ts +13 -102
- package/app/filesystem/domain/types.ts +30 -10
- package/app/filesystem/hooks/README.md +4 -4
- package/app/filesystem/hooks/useDiscoverableSources.ts +19 -30
- package/app/filesystem/hooks/useFilesystemSSE.ts +42 -2
- package/app/filesystem/host/README.md +6 -4
- package/app/filesystem/host/buildFilesystemHostValue.ts +28 -2
- package/app/filesystem/host/installFilesystemHostComponents.tsx +1 -1
- package/app/filesystem/lib/sourceKindForm.ts +210 -27
- package/app/filesystem/lib/treeVisualState.tsx +98 -4
- package/app/filesystem/store/README.md +1 -0
- package/app/filesystem/store/filesystemStore.ts +99 -8
- package/app/filesystem/store/gitSlice.ts +5 -0
- package/app/filesystem/store/helpers.ts +17 -0
- package/app/filesystem/store/listSlice.ts +8 -0
- package/app/filesystem/ui/CodeEditor.tsx +18 -3
- package/app/filesystem/ui/DiscoverDock.tsx +5 -1
- package/app/filesystem/ui/FileEditor.tsx +15 -10
- package/app/filesystem/ui/FileTree.tsx +75 -24
- package/app/filesystem/ui/FilesystemWidget.tsx +10 -2
- package/app/filesystem/ui/FolderPicker.tsx +251 -0
- package/app/filesystem/ui/GitControlPanel.tsx +7 -2
- package/app/filesystem/ui/PackagesPanel.tsx +52 -374
- package/app/filesystem/ui/PendingChangesPanel.tsx +1 -1
- package/app/filesystem/ui/PolicyEditor.tsx +109 -24
- package/app/filesystem/ui/README.md +30 -23
- package/app/filesystem/ui/RawMediaPreview.tsx +58 -0
- package/app/filesystem/ui/SourceBranchHeader.tsx +4 -4
- package/app/filesystem/ui/SourcesPanel.tsx +502 -342
- package/app/filesystem/ui/Toolbar.tsx +1 -2
- package/app/filesystem/ui/VectorHealthPanel.tsx +2 -2
- package/app/shared/filesystem.png +0 -0
- package/dist/app/host.js +58 -46
- package/dist/scripts/sourceRootPairV1.d.ts +47 -0
- package/dist/scripts/sourceRootPairV1.d.ts.map +1 -0
- package/dist/scripts/sourceRootPairV1.js +147 -0
- package/dist/scripts/sourceRootPairV1.js.map +1 -0
- package/dist/scripts/sourceToFolderV1.d.ts +56 -0
- package/dist/scripts/sourceToFolderV1.d.ts.map +1 -0
- package/dist/scripts/sourceToFolderV1.js +152 -0
- package/dist/scripts/sourceToFolderV1.js.map +1 -0
- package/dist/scripts/sourceToHostV1.d.ts +56 -0
- package/dist/scripts/sourceToHostV1.d.ts.map +1 -0
- package/dist/scripts/sourceToHostV1.js +132 -0
- package/dist/scripts/sourceToHostV1.js.map +1 -0
- package/dist/src/channels/filesystem.d.ts +1 -1
- package/dist/src/channels/filesystem.js +1 -1
- package/dist/src/connectors/AppSourceConfigStore.d.ts +17 -3
- package/dist/src/connectors/AppSourceConfigStore.d.ts.map +1 -1
- package/dist/src/connectors/AppSourceConfigStore.js +46 -6
- package/dist/src/connectors/AppSourceConfigStore.js.map +1 -1
- package/dist/src/connectors/HostConnector.d.ts +201 -0
- package/dist/src/connectors/HostConnector.d.ts.map +1 -0
- package/dist/src/connectors/HostConnector.js +903 -0
- package/dist/src/connectors/HostConnector.js.map +1 -0
- package/dist/src/connectors/inProcessTransport.d.ts +131 -0
- package/dist/src/connectors/inProcessTransport.d.ts.map +1 -0
- package/dist/src/connectors/inProcessTransport.js +447 -0
- package/dist/src/connectors/inProcessTransport.js.map +1 -0
- package/dist/src/domain/access/callerPermissions.d.ts +29 -0
- package/dist/src/domain/access/callerPermissions.d.ts.map +1 -1
- package/dist/src/domain/access/callerPermissions.js +85 -5
- package/dist/src/domain/access/callerPermissions.js.map +1 -1
- package/dist/src/domain/access/nativeLocalFence.d.ts +65 -0
- package/dist/src/domain/access/nativeLocalFence.d.ts.map +1 -0
- package/dist/src/domain/access/nativeLocalFence.js +171 -0
- package/dist/src/domain/access/nativeLocalFence.js.map +1 -0
- package/dist/src/domain/access/uriPermission.js +3 -3
- package/dist/src/domain/access/uriPermission.js.map +1 -1
- package/dist/src/domain/byteRange.d.ts +15 -0
- package/dist/src/domain/byteRange.d.ts.map +1 -0
- package/dist/src/domain/byteRange.js +30 -0
- package/dist/src/domain/byteRange.js.map +1 -0
- package/dist/src/domain/defaultPermissions.d.ts.map +1 -1
- package/dist/src/domain/defaultPermissions.js +29 -0
- package/dist/src/domain/defaultPermissions.js.map +1 -1
- package/dist/src/domain/mime.d.ts +11 -19
- package/dist/src/domain/mime.d.ts.map +1 -1
- package/dist/src/domain/mime.js +13 -102
- package/dist/src/domain/mime.js.map +1 -1
- package/dist/src/domain/paths.d.ts.map +1 -1
- package/dist/src/domain/paths.js +5 -3
- package/dist/src/domain/paths.js.map +1 -1
- package/dist/src/domain/scopeAccessCtx.d.ts +2 -2
- package/dist/src/domain/scopeAccessCtx.js +2 -2
- package/dist/src/domain/sourceConfig.d.ts +52 -19
- package/dist/src/domain/sourceConfig.d.ts.map +1 -1
- package/dist/src/domain/sourceConfig.js +103 -19
- package/dist/src/domain/sourceConfig.js.map +1 -1
- package/dist/src/domain/sourcePackages.d.ts +8 -8
- package/dist/src/domain/sourcePackages.d.ts.map +1 -1
- package/dist/src/domain/sourceRootPair.d.ts +88 -0
- package/dist/src/domain/sourceRootPair.d.ts.map +1 -0
- package/dist/src/domain/sourceRootPair.js +108 -0
- package/dist/src/domain/sourceRootPair.js.map +1 -0
- package/dist/src/domain/syncTypes.d.ts +8 -1
- package/dist/src/domain/syncTypes.d.ts.map +1 -1
- package/dist/src/domain/syncTypes.js +1 -0
- package/dist/src/domain/syncTypes.js.map +1 -1
- package/dist/src/domain/types.d.ts +32 -2
- package/dist/src/domain/types.d.ts.map +1 -1
- package/dist/src/domain/uri.d.ts.map +1 -1
- package/dist/src/domain/uri.js +3 -2
- package/dist/src/domain/uri.js.map +1 -1
- package/dist/src/embeddings/clients/GeminiEmbedder.d.ts.map +1 -1
- package/dist/src/embeddings/clients/GeminiEmbedder.js +2 -5
- package/dist/src/embeddings/clients/GeminiEmbedder.js.map +1 -1
- package/dist/src/embeddings/clients/OpenAIEmbedder.d.ts.map +1 -1
- package/dist/src/embeddings/clients/OpenAIEmbedder.js +2 -3
- package/dist/src/embeddings/clients/OpenAIEmbedder.js.map +1 -1
- package/dist/src/embeddings/clients/QwenEmbedder.d.ts +2 -0
- package/dist/src/embeddings/clients/QwenEmbedder.d.ts.map +1 -1
- package/dist/src/embeddings/clients/QwenEmbedder.js +10 -2
- package/dist/src/embeddings/clients/QwenEmbedder.js.map +1 -1
- package/dist/src/embeddings/clients/VoyageEmbedder.d.ts +2 -0
- package/dist/src/embeddings/clients/VoyageEmbedder.d.ts.map +1 -1
- package/dist/src/embeddings/clients/VoyageEmbedder.js +8 -1
- package/dist/src/embeddings/clients/VoyageEmbedder.js.map +1 -1
- package/dist/src/embeddings/factory.d.ts +5 -3
- package/dist/src/embeddings/factory.d.ts.map +1 -1
- package/dist/src/embeddings/factory.js +7 -3
- package/dist/src/embeddings/factory.js.map +1 -1
- package/dist/src/embeddings/models.d.ts +1 -1
- package/dist/src/embeddings/models.d.ts.map +1 -1
- package/dist/src/embeddings/retry.js +1 -1
- package/dist/src/embeddings/retry.js.map +1 -1
- package/dist/src/embeddings/types.d.ts +6 -0
- package/dist/src/embeddings/types.d.ts.map +1 -1
- package/dist/src/embeddings/types.js +11 -0
- package/dist/src/embeddings/types.js.map +1 -1
- package/dist/src/events/pending.d.ts +1 -1
- package/dist/src/events/pending.js +1 -1
- package/dist/src/git/GitRunner.d.ts +110 -30
- package/dist/src/git/GitRunner.d.ts.map +1 -1
- package/dist/src/git/GitRunner.js +511 -199
- package/dist/src/git/GitRunner.js.map +1 -1
- package/dist/src/git/GitWatchRegistry.d.ts +41 -35
- package/dist/src/git/GitWatchRegistry.d.ts.map +1 -1
- package/dist/src/git/GitWatchRegistry.js +61 -79
- package/dist/src/git/GitWatchRegistry.js.map +1 -1
- package/dist/src/git/gitPlace.d.ts +61 -0
- package/dist/src/git/gitPlace.d.ts.map +1 -0
- package/dist/src/git/gitPlace.js +74 -0
- package/dist/src/git/gitPlace.js.map +1 -0
- package/dist/src/git/sourceGitControl.d.ts +33 -21
- package/dist/src/git/sourceGitControl.d.ts.map +1 -1
- package/dist/src/git/sourceGitControl.js +211 -95
- package/dist/src/git/sourceGitControl.js.map +1 -1
- package/dist/src/git/sourceGitStatus.js +1 -1
- package/dist/src/git/sourceGitStatus.js.map +1 -1
- package/dist/src/git/untrackedStats.js +1 -1
- package/dist/src/git/untrackedStats.js.map +1 -1
- package/dist/src/index.d.ts +2 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/lifecycle.d.ts +9 -12
- package/dist/src/lifecycle.d.ts.map +1 -1
- package/dist/src/lifecycle.js +2 -1
- package/dist/src/lifecycle.js.map +1 -1
- package/dist/src/routes/approve.d.ts +1 -1
- package/dist/src/routes/approve.js +1 -1
- package/dist/src/routes/events.d.ts +1 -1
- package/dist/src/routes/events.js +1 -1
- package/dist/src/routes/git.d.ts +7 -7
- package/dist/src/routes/git.d.ts.map +1 -1
- package/dist/src/routes/git.js +201 -72
- package/dist/src/routes/git.js.map +1 -1
- package/dist/src/routes/health.d.ts +6 -6
- package/dist/src/routes/health.js +12 -12
- package/dist/src/routes/helpers/sourceNotConfigured.d.ts +1 -1
- package/dist/src/routes/helpers/sourceNotConfigured.js +1 -1
- package/dist/src/routes/helpers/uriGuard.d.ts +1 -1
- package/dist/src/routes/helpers/uriGuard.d.ts.map +1 -1
- package/dist/src/routes/helpers/uriGuard.js +3 -2
- package/dist/src/routes/helpers/uriGuard.js.map +1 -1
- package/dist/src/routes/helpers.d.ts +11 -4
- package/dist/src/routes/helpers.d.ts.map +1 -1
- package/dist/src/routes/helpers.js +13 -6
- package/dist/src/routes/helpers.js.map +1 -1
- package/dist/src/routes/list.d.ts +1 -1
- package/dist/src/routes/list.d.ts.map +1 -1
- package/dist/src/routes/list.js +3 -4
- package/dist/src/routes/list.js.map +1 -1
- package/dist/src/routes/pending.d.ts +4 -4
- package/dist/src/routes/pending.js +9 -9
- package/dist/src/routes/policies.d.ts +10 -8
- package/dist/src/routes/policies.d.ts.map +1 -1
- package/dist/src/routes/policies.js +31 -25
- package/dist/src/routes/policies.js.map +1 -1
- package/dist/src/routes/raw.d.ts +1 -1
- package/dist/src/routes/raw.d.ts.map +1 -1
- package/dist/src/routes/raw.js +66 -12
- package/dist/src/routes/raw.js.map +1 -1
- package/dist/src/routes/read.d.ts +1 -1
- package/dist/src/routes/read.js +1 -1
- package/dist/src/routes/search.d.ts +1 -1
- package/dist/src/routes/search.js +1 -1
- package/dist/src/routes/sources.d.ts +63 -6
- package/dist/src/routes/sources.d.ts.map +1 -1
- package/dist/src/routes/sources.js +494 -382
- package/dist/src/routes/sources.js.map +1 -1
- package/dist/src/routes/upload.d.ts +1 -1
- package/dist/src/routes/upload.js +1 -1
- package/dist/src/routes/write.d.ts +2 -2
- package/dist/src/routes/write.js +2 -2
- package/dist/src/services/BridgeService.d.ts +21 -35
- package/dist/src/services/BridgeService.d.ts.map +1 -1
- package/dist/src/services/BridgeService.js +42 -88
- package/dist/src/services/BridgeService.js.map +1 -1
- package/dist/src/services/FilesystemService.d.ts +4 -3
- package/dist/src/services/FilesystemService.d.ts.map +1 -1
- package/dist/src/services/FilesystemService.js +112 -34
- package/dist/src/services/FilesystemService.js.map +1 -1
- package/dist/src/services/FilesystemUiService.d.ts +4 -1
- package/dist/src/services/FilesystemUiService.d.ts.map +1 -1
- package/dist/src/services/FilesystemUiService.js +66 -25
- package/dist/src/services/FilesystemUiService.js.map +1 -1
- package/dist/src/services/SyncScheduler.d.ts +12 -4
- package/dist/src/services/SyncScheduler.d.ts.map +1 -1
- package/dist/src/services/SyncScheduler.js +37 -8
- package/dist/src/services/SyncScheduler.js.map +1 -1
- package/dist/src/services/baselineRepair.d.ts +13 -3
- package/dist/src/services/baselineRepair.d.ts.map +1 -1
- package/dist/src/services/baselineRepair.js +13 -3
- package/dist/src/services/baselineRepair.js.map +1 -1
- package/dist/src/services/declaredSources.d.ts +132 -43
- package/dist/src/services/declaredSources.d.ts.map +1 -1
- package/dist/src/services/declaredSources.js +118 -45
- package/dist/src/services/declaredSources.js.map +1 -1
- package/dist/src/store/dataFormats.d.ts +17 -2
- package/dist/src/store/dataFormats.d.ts.map +1 -1
- package/dist/src/store/dataFormats.js +18 -3
- package/dist/src/store/dataFormats.js.map +1 -1
- package/dist/src/sync/DeltaSyncRunner.d.ts.map +1 -1
- package/dist/src/sync/DeltaSyncRunner.js +144 -4
- package/dist/src/sync/DeltaSyncRunner.js.map +1 -1
- package/dist/src/sync/SyncJobQueue.d.ts +7 -2
- package/dist/src/sync/SyncJobQueue.d.ts.map +1 -1
- package/dist/src/sync/SyncJobQueue.js +16 -10
- package/dist/src/sync/SyncJobQueue.js.map +1 -1
- package/dist/src/sync/SyncWatchService.d.ts +21 -4
- package/dist/src/sync/SyncWatchService.d.ts.map +1 -1
- package/dist/src/sync/SyncWatchService.js +115 -10
- package/dist/src/sync/SyncWatchService.js.map +1 -1
- package/dist/src/sync/categoryInference.d.ts +1 -1
- package/dist/src/sync/categoryInference.js +1 -1
- package/dist/src/tools/execCtx.d.ts +2 -2
- package/dist/src/tools/execCtx.js +2 -2
- package/dist/src/tools/fs_read.d.ts.map +1 -1
- package/dist/src/tools/fs_read.js +5 -0
- package/dist/src/tools/fs_read.js.map +1 -1
- package/dist/src/usecases/admitSourceRoot.d.ts +65 -0
- package/dist/src/usecases/admitSourceRoot.d.ts.map +1 -0
- package/dist/src/usecases/admitSourceRoot.js +85 -0
- package/dist/src/usecases/admitSourceRoot.js.map +1 -0
- package/dist/src/usecases/browseSourceFolders.d.ts +85 -0
- package/dist/src/usecases/browseSourceFolders.d.ts.map +1 -0
- package/dist/src/usecases/browseSourceFolders.js +210 -0
- package/dist/src/usecases/browseSourceFolders.js.map +1 -0
- package/dist/src/usecases/createDeclaredSources.d.ts +13 -2
- package/dist/src/usecases/createDeclaredSources.d.ts.map +1 -1
- package/dist/src/usecases/createDeclaredSources.js +39 -0
- package/dist/src/usecases/createDeclaredSources.js.map +1 -1
- package/dist/src/usecases/embeddingBacklog.js +1 -1
- package/dist/src/usecases/embeddingBacklog.js.map +1 -1
- package/dist/src/usecases/list.d.ts.map +1 -1
- package/dist/src/usecases/list.js +83 -26
- package/dist/src/usecases/list.js.map +1 -1
- package/dist/src/usecases/listAttachableDevices.d.ts +13 -0
- package/dist/src/usecases/listAttachableDevices.d.ts.map +1 -0
- package/dist/src/usecases/listAttachableDevices.js +10 -0
- package/dist/src/usecases/listAttachableDevices.js.map +1 -0
- package/dist/src/usecases/listSourcePackages.d.ts.map +1 -1
- package/dist/src/usecases/listSourcePackages.js +2 -5
- package/dist/src/usecases/listSourcePackages.js.map +1 -1
- package/dist/src/usecases/purgeExcludedPoints.d.ts.map +1 -1
- package/dist/src/usecases/purgeExcludedPoints.js +3 -2
- package/dist/src/usecases/purgeExcludedPoints.js.map +1 -1
- package/dist/src/usecases/readFiles.d.ts.map +1 -1
- package/dist/src/usecases/readFiles.js +99 -1
- package/dist/src/usecases/readFiles.js.map +1 -1
- package/dist/src/usecases/reconcileSourcePackageRoots.d.ts +1 -1
- package/dist/src/usecases/reconcileSourcePackageRoots.d.ts.map +1 -1
- package/dist/src/usecases/reconcileSourcePackageRoots.js +2 -1
- package/dist/src/usecases/reconcileSourcePackageRoots.js.map +1 -1
- package/dist/src/usecases/revokePrincipal.d.ts +7 -5
- package/dist/src/usecases/revokePrincipal.d.ts.map +1 -1
- package/dist/src/usecases/revokePrincipal.js +29 -7
- package/dist/src/usecases/revokePrincipal.js.map +1 -1
- package/dist/src/usecases/scheduleSourceSync.d.ts +7 -0
- package/dist/src/usecases/scheduleSourceSync.d.ts.map +1 -1
- package/dist/src/usecases/scheduleSourceSync.js +6 -5
- package/dist/src/usecases/scheduleSourceSync.js.map +1 -1
- package/dist/src/usecases/syncPointWrites.d.ts +2 -0
- package/dist/src/usecases/syncPointWrites.d.ts.map +1 -1
- package/dist/src/usecases/syncPointWrites.js +5 -1
- package/dist/src/usecases/syncPointWrites.js.map +1 -1
- package/dist/src/usecases/triggerSourceSync.d.ts +46 -0
- package/dist/src/usecases/triggerSourceSync.d.ts.map +1 -0
- package/dist/src/usecases/triggerSourceSync.js +75 -0
- package/dist/src/usecases/triggerSourceSync.js.map +1 -0
- package/dist/src/usecases/uploadBinary.d.ts +2 -1
- package/dist/src/usecases/uploadBinary.d.ts.map +1 -1
- package/dist/src/usecases/uploadBinary.js +2 -2
- package/dist/src/usecases/uploadBinary.js.map +1 -1
- package/dist/src/usecases/vector/endpointGuard.d.ts +1 -1
- package/dist/src/usecases/vector/endpointGuard.js +1 -1
- package/dist/src/usecases/vectorMaintenance.js +1 -1
- package/dist/src/usecases/vectorMaintenance.js.map +1 -1
- package/dist/src/usecases/write/content.js +1 -1
- package/dist/src/vector/qdrantClient.d.ts +1 -1
- package/dist/src/vector/qdrantClient.js +1 -1
- package/dist/src/wiring.d.ts +3 -0
- package/dist/src/wiring.d.ts.map +1 -1
- package/dist/src/wiring.js +72 -6
- package/dist/src/wiring.js.map +1 -1
- package/dist/tools/fs_list.json +1 -1
- package/dist/tools/fs_read.json +1 -1
- package/dist/tools/fs_search.json +1 -1
- package/dist/tools/fs_write.json +1 -1
- package/instructions/brain-model.md +1 -1
- package/package.json +212 -114
- package/rules/brain-rules.md +2 -2
- package/skills/brain-start/SKILL.md +1 -1
- package/skills/connect-business-data/SKILL.md +3 -3
- package/skills/create-package/SKILL.md +26 -26
- package/skills/create-package/references/config-and-credentials.md +16 -13
- package/skills/create-package/references/connectors-and-uri-policies.md +39 -25
- package/skills/create-package/references/manifest-and-discovery.md +12 -12
- package/skills/create-package/references/runtime-and-build.md +19 -19
- package/skills/create-package/references/skills-and-context.md +36 -20
- package/skills/create-package/references/surfaces-and-design.md +16 -16
- package/skills/create-package/references/team-and-workflows.md +2 -2
- package/skills/create-package/references/test-and-ship.md +21 -21
- package/skills/create-package/references/tools-and-schemas.md +5 -5
- package/skills/create-package/scripts/{check-package.sh → check-package.mjs} +79 -65
- package/skills/create-package/scripts/{verify-loaded.sh → verify-loaded.mjs} +156 -162
- package/skills/git/SKILL.md +53 -51
- package/skills/manage-files/SKILL.md +22 -25
- package/skills/manage-sources/SKILL.md +128 -87
- package/skills/manage-uri-policy/SKILL.md +18 -15
- package/skills/organize/SKILL.md +1 -1
- package/skills/sync/SKILL.md +3 -3
- package/tools/fs_list.json +1 -1
- package/tools/fs_read.json +1 -1
- package/tools/fs_search.json +1 -1
- package/tools/fs_write.json +1 -1
- package/workflows/sources-digest.json +1 -1
- package/dist/src/connectors/LocalDiskConnector.d.ts +0 -171
- package/dist/src/connectors/LocalDiskConnector.d.ts.map +0 -1
- package/dist/src/connectors/LocalDiskConnector.js +0 -1233
- package/dist/src/connectors/LocalDiskConnector.js.map +0 -1
- package/docs/drive-overview.md +0 -59
- package/skills/manage-files/scripts/copy.sh +0 -7
- package/skills/manage-files/scripts/create.sh +0 -7
- package/skills/manage-files/scripts/mkdir.sh +0 -7
- package/skills/manage-files/scripts/modify.sh +0 -7
- package/skills/manage-files/scripts/upload.sh +0 -16
- package/skills/manage-files/scripts/write.sh +0 -29
- package/skills/manage-sources/scripts/reembed.sh +0 -23
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The source-root-pair OFFLINE upgrade (`neuralis upgrade`, app STOPPED):
|
|
3
|
+
* `brain-core/source-config` v2 → v3. A `local` source's absolute root gets the
|
|
4
|
+
* missing half of its pair wherever one derives (`domain/sourceRootPair.ts` —
|
|
5
|
+
* the same derivation the create route and the store's fill run), so a source
|
|
6
|
+
* attached on one plane opens on the other over the same data home:
|
|
7
|
+
* - (i) a container-home root gets the machine home's path;
|
|
8
|
+
* - (ii) a mount root with a known host path gets that path;
|
|
9
|
+
* - (iii) a machine path under the machine home becomes the container spelling,
|
|
10
|
+
* the machine path its `hostRoot`.
|
|
11
|
+
* A root nothing derives (iv) and a relative root are kept as written. An
|
|
12
|
+
* existing pair is NEVER rewritten: one that disagrees with the derivation, or
|
|
13
|
+
* one no table can derive (a hand-set `hostRoot`), is LISTED by project and slug
|
|
14
|
+
* and left as it is. Every record — every kind — is stamped `formatVersion: 3`,
|
|
15
|
+
* so "the store is v3" is true record by record.
|
|
16
|
+
*
|
|
17
|
+
* The plane facts come from the operator command's runtime stack (`stackFor`):
|
|
18
|
+
* inside the container its own home is the container spelling and
|
|
19
|
+
* `NEURALIS_HOST_HOME` the machine's; on the host the data home IS the machine
|
|
20
|
+
* home. `dryRun` writes nothing; `apply` is idempotent — a second run finds
|
|
21
|
+
* every record v3 and every derivable half filled, and writes nothing.
|
|
22
|
+
*/
|
|
23
|
+
import { type OfflineUpgradeContext, type OfflineUpgradeModule } from '@neuralis/package-system/data';
|
|
24
|
+
import { type SourceRootPlane, type SourceRootRule, type SourceRootStack } from '../src/domain/sourceRootPair.js';
|
|
25
|
+
export declare const SOURCE_ROOT_PAIR_STEP: {
|
|
26
|
+
readonly id: 'source-root-pair-v1';
|
|
27
|
+
readonly kind: "brain-core/source-config";
|
|
28
|
+
readonly to: 3;
|
|
29
|
+
};
|
|
30
|
+
type Json = Record<string, unknown>;
|
|
31
|
+
/** One source config: what it is under the derivation, and the record to write (absent ⇒ unchanged). */
|
|
32
|
+
export type SourceRootPairRow = {
|
|
33
|
+
/** Home-relative path of the record. */
|
|
34
|
+
file: string;
|
|
35
|
+
projectId: string;
|
|
36
|
+
slug: string;
|
|
37
|
+
/** `filled` — a half was derived; `kept` — nothing to derive; `hand-set` / `disagrees` — an existing pair left as it is. */
|
|
38
|
+
outcome: 'filled' | 'kept' | 'hand-set' | 'disagrees' | 'not-local';
|
|
39
|
+
rule?: SourceRootRule;
|
|
40
|
+
next?: Json;
|
|
41
|
+
};
|
|
42
|
+
/** Every source config of the install, classified. Reads only. */
|
|
43
|
+
export declare function inspectSourceRootPairs(ctx: OfflineUpgradeContext, plane: SourceRootPlane): Promise<SourceRootPairRow[]>;
|
|
44
|
+
/** The step over the plane facts the operator command's runtime stack names. */
|
|
45
|
+
export declare function createSourceRootPairUpgrade(stackFor: (ctx: OfflineUpgradeContext) => SourceRootStack): OfflineUpgradeModule;
|
|
46
|
+
export {};
|
|
47
|
+
//# sourceMappingURL=sourceRootPairV1.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sourceRootPairV1.d.ts","sourceRoot":"","sources":["../../scripts/sourceRootPairV1.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAIH,OAAO,EAAsB,KAAK,qBAAqB,EAAE,KAAK,oBAAoB,EAA2B,MAAM,+BAA+B,CAAC;AAEnJ,OAAO,EAAmC,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,KAAK,eAAe,EAAE,MAAM,iCAAiC,CAAC;AASnJ,eAAO,MAAM,qBAAqB;aAAK,EAAE,EAAE,qBAAqB;aAAE,IAAI;aAA6B,EAAE;CAAyB,CAAC;AAE/H,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAGpC,wGAAwG;AACxG,MAAM,MAAM,iBAAiB,GAAG;IAC9B,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,4HAA4H;IAC5H,OAAO,EAAE,QAAQ,GAAG,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,WAAW,CAAC;IACpE,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,IAAI,CAAC,EAAE,IAAI,CAAC;CACb,CAAC;AAiBF,kEAAkE;AAClE,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,qBAAqB,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAkD7H;AA4BD,gFAAgF;AAChF,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,qBAAqB,KAAK,eAAe,GAAG,oBAAoB,CAW3H"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The source-root-pair OFFLINE upgrade (`neuralis upgrade`, app STOPPED):
|
|
3
|
+
* `brain-core/source-config` v2 → v3. A `local` source's absolute root gets the
|
|
4
|
+
* missing half of its pair wherever one derives (`domain/sourceRootPair.ts` —
|
|
5
|
+
* the same derivation the create route and the store's fill run), so a source
|
|
6
|
+
* attached on one plane opens on the other over the same data home:
|
|
7
|
+
* - (i) a container-home root gets the machine home's path;
|
|
8
|
+
* - (ii) a mount root with a known host path gets that path;
|
|
9
|
+
* - (iii) a machine path under the machine home becomes the container spelling,
|
|
10
|
+
* the machine path its `hostRoot`.
|
|
11
|
+
* A root nothing derives (iv) and a relative root are kept as written. An
|
|
12
|
+
* existing pair is NEVER rewritten: one that disagrees with the derivation, or
|
|
13
|
+
* one no table can derive (a hand-set `hostRoot`), is LISTED by project and slug
|
|
14
|
+
* and left as it is. Every record — every kind — is stamped `formatVersion: 3`,
|
|
15
|
+
* so "the store is v3" is true record by record.
|
|
16
|
+
*
|
|
17
|
+
* The plane facts come from the operator command's runtime stack (`stackFor`):
|
|
18
|
+
* inside the container its own home is the container spelling and
|
|
19
|
+
* `NEURALIS_HOST_HOME` the machine's; on the host the data home IS the machine
|
|
20
|
+
* home. `dryRun` writes nothing; `apply` is idempotent — a second run finds
|
|
21
|
+
* every record v3 and every derivable half filled, and writes nothing.
|
|
22
|
+
*/
|
|
23
|
+
import { readdir, readFile, stat } from 'node:fs/promises';
|
|
24
|
+
import { isAbsolute, join, relative, resolve } from 'node:path';
|
|
25
|
+
import { durableReplaceFile } from '@neuralis/package-system/data';
|
|
26
|
+
import { SOURCE_CONFIG_FORMAT } from '../src/store/dataFormats.js';
|
|
27
|
+
import { pairSourceRoot, sourceRootPlane } from '../src/domain/sourceRootPair.js';
|
|
28
|
+
/**
|
|
29
|
+
* The format THIS step writes. A chained step pins its own and never imports
|
|
30
|
+
* the live `SOURCE_CONFIG_FORMAT.version`: a later step raises the live one,
|
|
31
|
+
* and this step must still stamp what IT wrote.
|
|
32
|
+
*/
|
|
33
|
+
const STEP_VERSION = 3;
|
|
34
|
+
export const SOURCE_ROOT_PAIR_STEP = { id: 'source-root-pair-v1', kind: SOURCE_CONFIG_FORMAT.kind, to: STEP_VERSION };
|
|
35
|
+
const isObject = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
36
|
+
/** Classify an EXISTING absolute pair against the derivation: agrees, disagrees, or nothing derives it. */
|
|
37
|
+
function judgeStoredPair(root, hostRoot, plane) {
|
|
38
|
+
const fromRoot = pairSourceRoot(root, plane);
|
|
39
|
+
if (fromRoot.hostRoot !== undefined)
|
|
40
|
+
return fromRoot.hostRoot === resolve(hostRoot) ? 'agrees' : 'disagrees';
|
|
41
|
+
const fromHost = pairSourceRoot(hostRoot, plane);
|
|
42
|
+
if (fromHost.rule === 'machine-home')
|
|
43
|
+
return fromHost.root === fromRoot.root ? 'agrees' : 'disagrees';
|
|
44
|
+
return 'hand-set';
|
|
45
|
+
}
|
|
46
|
+
async function readJson(file) {
|
|
47
|
+
const record = JSON.parse(await readFile(file, 'utf8'));
|
|
48
|
+
if (!isObject(record))
|
|
49
|
+
throw new Error(`${file} is not a source config`);
|
|
50
|
+
return record;
|
|
51
|
+
}
|
|
52
|
+
/** Every source config of the install, classified. Reads only. */
|
|
53
|
+
export async function inspectSourceRootPairs(ctx, plane) {
|
|
54
|
+
const base = join(ctx.appRoot, 'config', 'sources');
|
|
55
|
+
let projects;
|
|
56
|
+
try {
|
|
57
|
+
projects = (await readdir(base)).sort();
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
if (error.code === 'ENOENT')
|
|
61
|
+
return [];
|
|
62
|
+
throw error;
|
|
63
|
+
}
|
|
64
|
+
const rows = [];
|
|
65
|
+
for (const projectId of projects) {
|
|
66
|
+
const dir = join(base, projectId);
|
|
67
|
+
if (!(await stat(dir)).isDirectory())
|
|
68
|
+
continue;
|
|
69
|
+
for (const name of (await readdir(dir)).filter((entry) => entry.endsWith('.json')).sort()) {
|
|
70
|
+
const path = join(dir, name);
|
|
71
|
+
const record = await readJson(path);
|
|
72
|
+
const file = relative(ctx.home, path);
|
|
73
|
+
const slug = typeof record.source === 'string' ? record.source : name.slice(0, -'.json'.length);
|
|
74
|
+
const connection = isObject(record.connection) ? record.connection : {};
|
|
75
|
+
const config = isObject(connection.config) ? connection.config : {};
|
|
76
|
+
let row = { file, projectId, slug, outcome: 'not-local' };
|
|
77
|
+
let nextConfig = config;
|
|
78
|
+
// A record a later step already raised is past this one (a resumed chain): never re-read, never lowered.
|
|
79
|
+
const raised = typeof record.formatVersion === 'number' && record.formatVersion > STEP_VERSION;
|
|
80
|
+
if (!raised && connection.kind === 'local' && typeof config.root === 'string' && config.root.length > 0) {
|
|
81
|
+
const { root, hostRoot } = config;
|
|
82
|
+
if (!isAbsolute(root)) {
|
|
83
|
+
row = { ...row, outcome: 'kept', rule: 'relative' };
|
|
84
|
+
}
|
|
85
|
+
else if (typeof hostRoot === 'string') {
|
|
86
|
+
const verdict = judgeStoredPair(root, hostRoot, plane);
|
|
87
|
+
row = { ...row, outcome: verdict === 'agrees' ? 'kept' : verdict };
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
const derived = pairSourceRoot(root, plane);
|
|
91
|
+
if (derived.hostRoot !== undefined) {
|
|
92
|
+
nextConfig = { ...config, root: derived.root, hostRoot: derived.hostRoot };
|
|
93
|
+
row = { ...row, outcome: 'filled', rule: derived.rule };
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
row = { ...row, outcome: 'kept', rule: derived.rule };
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
const next = raised
|
|
101
|
+
? record
|
|
102
|
+
: nextConfig === config
|
|
103
|
+
? { ...record, formatVersion: STEP_VERSION }
|
|
104
|
+
: { ...record, connection: { ...connection, config: nextConfig }, formatVersion: STEP_VERSION };
|
|
105
|
+
rows.push(JSON.stringify(next) === JSON.stringify(record) ? row : { ...row, next });
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return rows;
|
|
109
|
+
}
|
|
110
|
+
const RULE_LABEL = {
|
|
111
|
+
'container-home': '(i) data home', mount: '(ii) mount', 'machine-home': '(iii) machine path', none: '(iv) one spelling', relative: 'relative',
|
|
112
|
+
};
|
|
113
|
+
function asPlan(rows) {
|
|
114
|
+
const count = (outcome, rule) => rows.filter((row) => row.outcome === outcome && (rule === undefined || row.rule === rule)).length;
|
|
115
|
+
const named = (outcome, rule) => rows.filter((row) => row.outcome === outcome && (rule === undefined || row.rule === rule)).map((row) => ` ${row.projectId} · ${row.slug}`);
|
|
116
|
+
const writes = rows.filter((row) => row.next).length;
|
|
117
|
+
const notDerivable = named('kept', 'none');
|
|
118
|
+
const handSet = named('hand-set');
|
|
119
|
+
const disagreeing = named('disagrees');
|
|
120
|
+
return {
|
|
121
|
+
files: writes > 0 ? ['app/config/sources'] : [],
|
|
122
|
+
summary: [
|
|
123
|
+
`source configs: ${rows.length} read, ${writes} to rewrite (every record stamped v${STEP_VERSION})`,
|
|
124
|
+
`root pairs filled: ${['container-home', 'mount', 'machine-home'].map((rule) => `${RULE_LABEL[rule]} ${count('filled', rule)}`).join(', ')}`,
|
|
125
|
+
`kept as written: ${RULE_LABEL.none} ${count('kept', 'none')}, ${RULE_LABEL.relative} ${count('kept', 'relative')}, hand-set ${handSet.length}, disagreeing ${disagreeing.length}`,
|
|
126
|
+
...(notDerivable.length > 0 ? ['Not derivable — the root is read as written on both planes (project · source):', ...notDerivable] : []),
|
|
127
|
+
...(handSet.length > 0 ? ['Hand-set hostRoot no table derives, left as it is (project · source):', ...handSet] : []),
|
|
128
|
+
...(disagreeing.length > 0 ? ['Pairs that disagree with the derivation, left as they are (project · source):', ...disagreeing] : []),
|
|
129
|
+
],
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
/** The step over the plane facts the operator command's runtime stack names. */
|
|
133
|
+
export function createSourceRootPairUpgrade(stackFor) {
|
|
134
|
+
return {
|
|
135
|
+
id: SOURCE_ROOT_PAIR_STEP.id,
|
|
136
|
+
kinds: [{ kind: SOURCE_ROOT_PAIR_STEP.kind, to: SOURCE_ROOT_PAIR_STEP.to }],
|
|
137
|
+
dryRun: async (ctx) => asPlan(await inspectSourceRootPairs(ctx, sourceRootPlane(stackFor(ctx)))),
|
|
138
|
+
async apply(ctx) {
|
|
139
|
+
const rows = await inspectSourceRootPairs(ctx, sourceRootPlane(stackFor(ctx)));
|
|
140
|
+
for (const row of rows)
|
|
141
|
+
if (row.next)
|
|
142
|
+
await durableReplaceFile(join(ctx.home, row.file), JSON.stringify(row.next, null, 2));
|
|
143
|
+
ctx.log(`${SOURCE_ROOT_PAIR_STEP.id}: ${rows.filter((row) => row.next).length} of ${rows.length} source config(s) rewritten, ${rows.filter((row) => row.outcome === 'filled').length} root pair(s) filled`);
|
|
144
|
+
},
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=sourceRootPairV1.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sourceRootPairV1.js","sourceRoot":"","sources":["../../scripts/sourceRootPairV1.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The source-to-folder OFFLINE upgrade (`neuralis upgrade`, app STOPPED):
|
|
3
|
+
* `brain-core/source-config` v3 → v4. The two folder kinds become ONE, the
|
|
4
|
+
* `folder` kind, whose transport the stored config picks:
|
|
5
|
+
* - a `local` record becomes a `folder` with its config unchanged (the
|
|
6
|
+
* in-process filesystem, its root pair kept as written);
|
|
7
|
+
* - a `host` record (or a `host-*` kind) becomes a `folder` carrying its
|
|
8
|
+
* `device` (the device transport) — `source-device-v1`, which runs first,
|
|
9
|
+
* stamped that device into every host record that named none;
|
|
10
|
+
* - `recognizesPackages: true` becomes `packageFolders: ['']` (the whole source
|
|
11
|
+
* as one package folder); `recognizesPackages: false` is dropped.
|
|
12
|
+
* Every record — every kind — is stamped `formatVersion: 4`, so "the store is
|
|
13
|
+
* v4" is true record by record; the agent-core `host-source-config` kind the
|
|
14
|
+
* host records also answered to is retired with this step.
|
|
15
|
+
*
|
|
16
|
+
* The kind literals this step reads are pinned HERE (`local`, `host`,
|
|
17
|
+
* `host-*`): the live code no longer names them. A host record without a
|
|
18
|
+
* well-formed device, or with a `hostRoot` beside its device (the folder kind
|
|
19
|
+
* refuses the two together), is a BLOCKER listed by project and slug — the
|
|
20
|
+
* operator removes or repairs it in the running older build first. `dryRun`
|
|
21
|
+
* writes nothing; `apply` is idempotent — a second run finds every record v4
|
|
22
|
+
* and writes nothing.
|
|
23
|
+
*/
|
|
24
|
+
import { type OfflineUpgradeContext, type OfflineUpgradeModule } from '@neuralis/package-system/data';
|
|
25
|
+
export declare const SOURCE_TO_FOLDER_STEP: {
|
|
26
|
+
readonly id: 'source-to-folder-v1';
|
|
27
|
+
readonly kind: "brain-core/source-config";
|
|
28
|
+
readonly to: 4;
|
|
29
|
+
};
|
|
30
|
+
type Json = Record<string, unknown>;
|
|
31
|
+
/** One source config: what the merge makes of it, and the record to write (absent ⇒ unchanged). */
|
|
32
|
+
export type SourceToFolderRow = {
|
|
33
|
+
/** Home-relative path of the record. */
|
|
34
|
+
file: string;
|
|
35
|
+
projectId: string;
|
|
36
|
+
slug: string;
|
|
37
|
+
/** `in-process` — was `local`; `device` — was a host kind; `other` — another kind (stamp only); `blocked` — see `blocker`. */
|
|
38
|
+
outcome: 'in-process' | 'device' | 'other' | 'blocked';
|
|
39
|
+
/** The record carried `recognizesPackages: true` and now carries `packageFolders: ['']`. */
|
|
40
|
+
packages: boolean;
|
|
41
|
+
blocker?: string;
|
|
42
|
+
next?: Json;
|
|
43
|
+
};
|
|
44
|
+
/** The merged record for one stored config (pure; exported for the unit suite). */
|
|
45
|
+
export declare function mergeSourceRecord(record: Json): {
|
|
46
|
+
next: Json;
|
|
47
|
+
outcome: SourceToFolderRow['outcome'];
|
|
48
|
+
packages: boolean;
|
|
49
|
+
blocker?: string;
|
|
50
|
+
};
|
|
51
|
+
/** Every source config of the install, classified. Reads only. */
|
|
52
|
+
export declare function inspectSourceToFolder(ctx: OfflineUpgradeContext): Promise<SourceToFolderRow[]>;
|
|
53
|
+
/** The step (the host module names it for `scripts/upgrade.mts`). */
|
|
54
|
+
export declare function createSourceToFolderUpgrade(): OfflineUpgradeModule;
|
|
55
|
+
export {};
|
|
56
|
+
//# sourceMappingURL=sourceToFolderV1.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sourceToFolderV1.d.ts","sourceRoot":"","sources":["../../scripts/sourceToFolderV1.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH,OAAO,EAAsB,KAAK,qBAAqB,EAAE,KAAK,oBAAoB,EAA2B,MAAM,+BAA+B,CAAC;AAanJ,eAAO,MAAM,qBAAqB;aAAK,EAAE,EAAE,qBAAqB;aAAE,IAAI;aAA6B,EAAE;CAAyB,CAAC;AAO/H,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAGpC,mGAAmG;AACnG,MAAM,MAAM,iBAAiB,GAAG;IAC9B,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,8HAA8H;IAC9H,OAAO,EAAE,YAAY,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;IACvD,4FAA4F;IAC5F,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,IAAI,CAAC;CACb,CAAC;AAQF,mFAAmF;AACnF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,IAAI,GAAG;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAkC1I;AAED,kEAAkE;AAClE,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,qBAAqB,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC,CA2BpG;AAmBD,qEAAqE;AACrE,wBAAgB,2BAA2B,IAAI,oBAAoB,CAelE"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The source-to-folder OFFLINE upgrade (`neuralis upgrade`, app STOPPED):
|
|
3
|
+
* `brain-core/source-config` v3 → v4. The two folder kinds become ONE, the
|
|
4
|
+
* `folder` kind, whose transport the stored config picks:
|
|
5
|
+
* - a `local` record becomes a `folder` with its config unchanged (the
|
|
6
|
+
* in-process filesystem, its root pair kept as written);
|
|
7
|
+
* - a `host` record (or a `host-*` kind) becomes a `folder` carrying its
|
|
8
|
+
* `device` (the device transport) — `source-device-v1`, which runs first,
|
|
9
|
+
* stamped that device into every host record that named none;
|
|
10
|
+
* - `recognizesPackages: true` becomes `packageFolders: ['']` (the whole source
|
|
11
|
+
* as one package folder); `recognizesPackages: false` is dropped.
|
|
12
|
+
* Every record — every kind — is stamped `formatVersion: 4`, so "the store is
|
|
13
|
+
* v4" is true record by record; the agent-core `host-source-config` kind the
|
|
14
|
+
* host records also answered to is retired with this step.
|
|
15
|
+
*
|
|
16
|
+
* The kind literals this step reads are pinned HERE (`local`, `host`,
|
|
17
|
+
* `host-*`): the live code no longer names them. A host record without a
|
|
18
|
+
* well-formed device, or with a `hostRoot` beside its device (the folder kind
|
|
19
|
+
* refuses the two together), is a BLOCKER listed by project and slug — the
|
|
20
|
+
* operator removes or repairs it in the running older build first. `dryRun`
|
|
21
|
+
* writes nothing; `apply` is idempotent — a second run finds every record v4
|
|
22
|
+
* and writes nothing.
|
|
23
|
+
*/
|
|
24
|
+
import { readdir, readFile, stat } from 'node:fs/promises';
|
|
25
|
+
import { join, relative } from 'node:path';
|
|
26
|
+
import { durableReplaceFile } from '@neuralis/package-system/data';
|
|
27
|
+
import { SOURCE_CONFIG_FORMAT } from '../src/store/dataFormats.js';
|
|
28
|
+
/** The kind this step WROTE (v4) — pinned: a later step renames it, so the live constant cannot stand in. */
|
|
29
|
+
const FOLDER_SOURCE_KIND = 'folder';
|
|
30
|
+
/**
|
|
31
|
+
* The format THIS step writes. A chained step pins its own and never imports
|
|
32
|
+
* the live `SOURCE_CONFIG_FORMAT.version`: a later step raises the live one,
|
|
33
|
+
* and this step must still stamp what IT wrote.
|
|
34
|
+
*/
|
|
35
|
+
const STEP_VERSION = 4;
|
|
36
|
+
export const SOURCE_TO_FOLDER_STEP = { id: 'source-to-folder-v1', kind: SOURCE_CONFIG_FORMAT.kind, to: STEP_VERSION };
|
|
37
|
+
/** The pre-merge kinds, pinned as they were written (never the live plane predicate). */
|
|
38
|
+
const OLD_IN_PROCESS_KIND = 'local';
|
|
39
|
+
const isOldDeviceKind = (kind) => kind === 'host' || kind.startsWith('host-');
|
|
40
|
+
const DEVICE_ID = /^dev_[A-Za-z0-9]+$/;
|
|
41
|
+
const isObject = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
42
|
+
async function readJson(file) {
|
|
43
|
+
const record = JSON.parse(await readFile(file, 'utf8'));
|
|
44
|
+
if (!isObject(record))
|
|
45
|
+
throw new Error(`${file} is not a source config`);
|
|
46
|
+
return record;
|
|
47
|
+
}
|
|
48
|
+
/** The merged record for one stored config (pure; exported for the unit suite). */
|
|
49
|
+
export function mergeSourceRecord(record) {
|
|
50
|
+
// A record a later step already raised (a resumed chain over a v5 store,
|
|
51
|
+
// where `host` names the ONE folder kind, not the old device kind) is past
|
|
52
|
+
// this step: passed through untouched, never re-read in the old vocabulary.
|
|
53
|
+
if (typeof record.formatVersion === 'number' && record.formatVersion > STEP_VERSION) {
|
|
54
|
+
return { next: record, outcome: 'other', packages: false };
|
|
55
|
+
}
|
|
56
|
+
const connection = isObject(record.connection) ? record.connection : {};
|
|
57
|
+
const kind = typeof connection.kind === 'string' ? connection.kind : '';
|
|
58
|
+
const config = isObject(connection.config) ? connection.config : {};
|
|
59
|
+
let outcome = 'other';
|
|
60
|
+
let nextConnection = connection;
|
|
61
|
+
if (kind === OLD_IN_PROCESS_KIND) {
|
|
62
|
+
outcome = 'in-process';
|
|
63
|
+
nextConnection = { ...connection, kind: FOLDER_SOURCE_KIND };
|
|
64
|
+
}
|
|
65
|
+
else if (isOldDeviceKind(kind)) {
|
|
66
|
+
if (typeof config.device !== 'string' || !DEVICE_ID.test(config.device)) {
|
|
67
|
+
return { next: record, outcome: 'blocked', packages: false, blocker: 'names no paired device (connection.config.device)' };
|
|
68
|
+
}
|
|
69
|
+
if (config.hostRoot !== undefined) {
|
|
70
|
+
return { next: record, outcome: 'blocked', packages: false, blocker: 'carries a hostRoot beside its device' };
|
|
71
|
+
}
|
|
72
|
+
outcome = 'device';
|
|
73
|
+
nextConnection = { ...connection, kind: FOLDER_SOURCE_KIND };
|
|
74
|
+
}
|
|
75
|
+
const { recognizesPackages, ...rest } = record;
|
|
76
|
+
const packages = recognizesPackages === true;
|
|
77
|
+
const next = {
|
|
78
|
+
...rest,
|
|
79
|
+
connection: nextConnection,
|
|
80
|
+
...(packages ? { packageFolders: [''] } : {}),
|
|
81
|
+
formatVersion: STEP_VERSION,
|
|
82
|
+
};
|
|
83
|
+
return { next, outcome, packages };
|
|
84
|
+
}
|
|
85
|
+
/** Every source config of the install, classified. Reads only. */
|
|
86
|
+
export async function inspectSourceToFolder(ctx) {
|
|
87
|
+
const base = join(ctx.appRoot, 'config', 'sources');
|
|
88
|
+
let projects;
|
|
89
|
+
try {
|
|
90
|
+
projects = (await readdir(base)).sort();
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
if (error.code === 'ENOENT')
|
|
94
|
+
return [];
|
|
95
|
+
throw error;
|
|
96
|
+
}
|
|
97
|
+
const rows = [];
|
|
98
|
+
for (const projectId of projects) {
|
|
99
|
+
const dir = join(base, projectId);
|
|
100
|
+
if (!(await stat(dir)).isDirectory())
|
|
101
|
+
continue;
|
|
102
|
+
for (const name of (await readdir(dir)).filter((entry) => entry.endsWith('.json')).sort()) {
|
|
103
|
+
const path = join(dir, name);
|
|
104
|
+
const record = await readJson(path);
|
|
105
|
+
const file = relative(ctx.home, path);
|
|
106
|
+
const slug = typeof record.source === 'string' ? record.source : name.slice(0, -'.json'.length);
|
|
107
|
+
const merged = mergeSourceRecord(record);
|
|
108
|
+
const row = {
|
|
109
|
+
file, projectId, slug, outcome: merged.outcome, packages: merged.packages,
|
|
110
|
+
...(merged.blocker ? { blocker: merged.blocker } : {}),
|
|
111
|
+
};
|
|
112
|
+
rows.push(merged.outcome === 'blocked' || JSON.stringify(merged.next) === JSON.stringify(record) ? row : { ...row, next: merged.next });
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return rows;
|
|
116
|
+
}
|
|
117
|
+
function asPlan(rows) {
|
|
118
|
+
const count = (outcome) => rows.filter((row) => row.outcome === outcome).length;
|
|
119
|
+
const writes = rows.filter((row) => row.next).length;
|
|
120
|
+
const blocked = rows.filter((row) => row.blocker).map((row) => `${row.projectId} · ${row.slug} · ${row.file} · ${row.blocker}`);
|
|
121
|
+
return {
|
|
122
|
+
files: writes > 0 ? ['app/config/sources'] : [],
|
|
123
|
+
summary: [
|
|
124
|
+
`source configs: ${rows.length} read, ${writes} to rewrite (every record stamped v${STEP_VERSION})`,
|
|
125
|
+
`folders: ${count('in-process')} on this server (was local), ${count('device')} on a device (was host); other kinds ${count('other')}`,
|
|
126
|
+
`package folders: ${rows.filter((row) => row.packages).length} source(s) recognizing packages carry packageFolders ['']`,
|
|
127
|
+
],
|
|
128
|
+
...(blocked.length > 0
|
|
129
|
+
? { blockers: { lines: blocked, remedy: 'in the running older build, remove that host source or re-attach it on its device, then stop the app and run the upgrade again' } }
|
|
130
|
+
: {}),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
/** The step (the host module names it for `scripts/upgrade.mts`). */
|
|
134
|
+
export function createSourceToFolderUpgrade() {
|
|
135
|
+
return {
|
|
136
|
+
id: SOURCE_TO_FOLDER_STEP.id,
|
|
137
|
+
kinds: [{ kind: SOURCE_TO_FOLDER_STEP.kind, to: SOURCE_TO_FOLDER_STEP.to }],
|
|
138
|
+
dryRun: async (ctx) => asPlan(await inspectSourceToFolder(ctx)),
|
|
139
|
+
async apply(ctx) {
|
|
140
|
+
const rows = await inspectSourceToFolder(ctx);
|
|
141
|
+
const blocked = rows.filter((row) => row.blocker);
|
|
142
|
+
if (blocked.length > 0) {
|
|
143
|
+
throw new Error(`${SOURCE_TO_FOLDER_STEP.id}: ${blocked.map((row) => `${row.projectId} · ${row.slug} · ${row.blocker}`).join('; ')}`);
|
|
144
|
+
}
|
|
145
|
+
for (const row of rows)
|
|
146
|
+
if (row.next)
|
|
147
|
+
await durableReplaceFile(join(ctx.home, row.file), JSON.stringify(row.next, null, 2));
|
|
148
|
+
ctx.log(`${SOURCE_TO_FOLDER_STEP.id}: ${rows.filter((row) => row.next).length} of ${rows.length} source config(s) rewritten — ${rows.filter((row) => row.outcome === 'in-process').length} folder(s) on this server, ${rows.filter((row) => row.outcome === 'device').length} on a device`);
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=sourceToFolderV1.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sourceToFolderV1.js","sourceRoot":"","sources":["../../scripts/sourceToFolderV1.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Offline upgrade `source-to-host-v1`, brain-core's half: the ONE folder kind
|
|
3
|
+
* is spelled `host` — `brain-core/source-config` v4 → v5. What a source MEANS
|
|
4
|
+
* does not move: `root`, `hostRoot` (the Docker mount's machine half) and
|
|
5
|
+
* `device` (the transport) are carried byte for byte, so every coordinate the
|
|
6
|
+
* runtime derives — the container path, the machine path, the device path — is
|
|
7
|
+
* the one it derived before.
|
|
8
|
+
*
|
|
9
|
+
* ONE root does move, in the same step: a folder on this server rooted in the
|
|
10
|
+
* Docker image's Neuralis tree (`/neuralis` or a folder under it — the
|
|
11
|
+
* `--neuralis` overlay's container spelling, where "Neuralis Skills" was
|
|
12
|
+
* attached) becomes the LOGICAL root `neuralis-tree:<folder>` and drops its
|
|
13
|
+
* machine half; the runtime resolves it on each plane (the overlay in Docker,
|
|
14
|
+
* the host's own tree natively), so the attach opens on both. Nothing reads the
|
|
15
|
+
* old spelling as an alias.
|
|
16
|
+
*
|
|
17
|
+
* Every record — every kind — is stamped `formatVersion: 5`, so "the store is
|
|
18
|
+
* v5" is a fact a reader can check per record. A record a later step already
|
|
19
|
+
* raised is passed through untouched. `dryRun` writes nothing; `apply` is
|
|
20
|
+
* idempotent — a second run finds every record v5 and writes nothing.
|
|
21
|
+
*/
|
|
22
|
+
import { type OfflineUpgradeContext, type OfflineUpgradePlan } from '@neuralis/package-system/data';
|
|
23
|
+
export declare const SOURCE_TO_HOST_STEP: {
|
|
24
|
+
readonly id: 'source-to-host-v1';
|
|
25
|
+
readonly kind: "brain-core/source-config";
|
|
26
|
+
readonly to: 5;
|
|
27
|
+
};
|
|
28
|
+
/** `neuralis-tree:<rel>` for a root in the image tree; `null` for any other root. */
|
|
29
|
+
export declare function treeAnchorFor(root: unknown): string | null;
|
|
30
|
+
type Json = Record<string, unknown>;
|
|
31
|
+
/** One source config: what the step makes of it, and the record to write (absent ⇒ unchanged). */
|
|
32
|
+
export type SourceToHostRow = {
|
|
33
|
+
/** Home-relative path of the record. */
|
|
34
|
+
file: string;
|
|
35
|
+
projectId: string;
|
|
36
|
+
slug: string;
|
|
37
|
+
/** `local` / `device` — a v4 folder by its transport; `other` — another kind (stamp only); `current` — already v5. */
|
|
38
|
+
outcome: 'local' | 'device' | 'other' | 'current';
|
|
39
|
+
/** A folder on this server whose image-tree root became a `neuralis-tree:` root. */
|
|
40
|
+
anchored?: true;
|
|
41
|
+
next?: Json;
|
|
42
|
+
};
|
|
43
|
+
/** The v5 record for one stored v4 config (pure; exported for the unit suite). */
|
|
44
|
+
export declare function hostRecordOf(record: Json): {
|
|
45
|
+
next: Json;
|
|
46
|
+
outcome: SourceToHostRow['outcome'];
|
|
47
|
+
anchored?: true;
|
|
48
|
+
};
|
|
49
|
+
/** Every source config of the install, classified. Reads only. */
|
|
50
|
+
export declare function inspectSourceToHost(ctx: Pick<OfflineUpgradeContext, 'appRoot' | 'home'>): Promise<SourceToHostRow[]>;
|
|
51
|
+
/** The dry-run lines of brain-core's half (the host module adds agent-core's). */
|
|
52
|
+
export declare function sourceToHostSummary(rows: readonly SourceToHostRow[]): OfflineUpgradePlan;
|
|
53
|
+
/** Write every changed record (idempotent: an unchanged one has no `next`). */
|
|
54
|
+
export declare function applySourceToHost(ctx: Pick<OfflineUpgradeContext, 'home'>, rows: readonly SourceToHostRow[]): Promise<number>;
|
|
55
|
+
export {};
|
|
56
|
+
//# sourceMappingURL=sourceToHostV1.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sourceToHostV1.d.ts","sourceRoot":"","sources":["../../scripts/sourceToHostV1.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAIH,OAAO,EAAsB,KAAK,qBAAqB,EAAE,KAAK,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAMxH,eAAO,MAAM,mBAAmB;aAAK,EAAE,EAAE,mBAAmB;aAAE,IAAI;aAA6B,EAAE;CAAyB,CAAC;AAM3H,qFAAqF;AACrF,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAQ1D;AAMD,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAGpC,kGAAkG;AAClG,MAAM,MAAM,eAAe,GAAG;IAC5B,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,sHAAsH;IACtH,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;IAClD,oFAAoF;IACpF,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,IAAI,CAAC,EAAE,IAAI,CAAC;CACb,CAAC;AAEF,kFAAkF;AAClF,wBAAgB,YAAY,CAAC,MAAM,EAAE,IAAI,GAAG;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,eAAe,CAAC,SAAS,CAAC,CAAC;IAAC,QAAQ,CAAC,EAAE,IAAI,CAAA;CAAE,CAsB/G;AAQD,kEAAkE;AAClE,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,IAAI,CAAC,qBAAqB,EAAE,SAAS,GAAG,MAAM,CAAC,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAuB1H;AAED,kFAAkF;AAClF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,SAAS,eAAe,EAAE,GAAG,kBAAkB,CAWxF;AAED,+EAA+E;AAC/E,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,IAAI,CAAC,qBAAqB,EAAE,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,eAAe,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAQnI"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Offline upgrade `source-to-host-v1`, brain-core's half: the ONE folder kind
|
|
3
|
+
* is spelled `host` — `brain-core/source-config` v4 → v5. What a source MEANS
|
|
4
|
+
* does not move: `root`, `hostRoot` (the Docker mount's machine half) and
|
|
5
|
+
* `device` (the transport) are carried byte for byte, so every coordinate the
|
|
6
|
+
* runtime derives — the container path, the machine path, the device path — is
|
|
7
|
+
* the one it derived before.
|
|
8
|
+
*
|
|
9
|
+
* ONE root does move, in the same step: a folder on this server rooted in the
|
|
10
|
+
* Docker image's Neuralis tree (`/neuralis` or a folder under it — the
|
|
11
|
+
* `--neuralis` overlay's container spelling, where "Neuralis Skills" was
|
|
12
|
+
* attached) becomes the LOGICAL root `neuralis-tree:<folder>` and drops its
|
|
13
|
+
* machine half; the runtime resolves it on each plane (the overlay in Docker,
|
|
14
|
+
* the host's own tree natively), so the attach opens on both. Nothing reads the
|
|
15
|
+
* old spelling as an alias.
|
|
16
|
+
*
|
|
17
|
+
* Every record — every kind — is stamped `formatVersion: 5`, so "the store is
|
|
18
|
+
* v5" is a fact a reader can check per record. A record a later step already
|
|
19
|
+
* raised is passed through untouched. `dryRun` writes nothing; `apply` is
|
|
20
|
+
* idempotent — a second run finds every record v5 and writes nothing.
|
|
21
|
+
*/
|
|
22
|
+
import { readdir, readFile, stat } from 'node:fs/promises';
|
|
23
|
+
import { join, relative } from 'node:path';
|
|
24
|
+
import { durableReplaceFile } from '@neuralis/package-system/data';
|
|
25
|
+
import { SOURCE_CONFIG_FORMAT } from '../src/store/dataFormats.js';
|
|
26
|
+
/** The format THIS step writes — pinned, never the live `SOURCE_CONFIG_FORMAT.version`. */
|
|
27
|
+
const STEP_VERSION = 5;
|
|
28
|
+
export const SOURCE_TO_HOST_STEP = { id: 'source-to-host-v1', kind: SOURCE_CONFIG_FORMAT.kind, to: STEP_VERSION };
|
|
29
|
+
/** The Docker spelling of the Neuralis tree, and the logical root this step writes for it — both pinned. */
|
|
30
|
+
const IMAGE_NEURALIS_TREE = '/neuralis';
|
|
31
|
+
const V5_TREE_ANCHOR = 'neuralis-tree:';
|
|
32
|
+
/** `neuralis-tree:<rel>` for a root in the image tree; `null` for any other root. */
|
|
33
|
+
export function treeAnchorFor(root) {
|
|
34
|
+
if (typeof root !== 'string')
|
|
35
|
+
return null;
|
|
36
|
+
const trimmed = root.replace(/\/+$/, '');
|
|
37
|
+
if (trimmed === IMAGE_NEURALIS_TREE)
|
|
38
|
+
return V5_TREE_ANCHOR;
|
|
39
|
+
if (!trimmed.startsWith(`${IMAGE_NEURALIS_TREE}/`))
|
|
40
|
+
return null;
|
|
41
|
+
const rel = trimmed.slice(IMAGE_NEURALIS_TREE.length + 1);
|
|
42
|
+
const segments = rel.split('/');
|
|
43
|
+
return segments.every((s) => s !== '' && s !== '.' && s !== '..') ? `${V5_TREE_ANCHOR}${rel}` : null;
|
|
44
|
+
}
|
|
45
|
+
/** The kind as v4 wrote it, and as this step writes it — both pinned (a later rename must not move them). */
|
|
46
|
+
const V4_FOLDER_KIND = 'folder';
|
|
47
|
+
const V5_HOST_KIND = 'host';
|
|
48
|
+
const isObject = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
49
|
+
/** The v5 record for one stored v4 config (pure; exported for the unit suite). */
|
|
50
|
+
export function hostRecordOf(record) {
|
|
51
|
+
if (typeof record.formatVersion === 'number' && record.formatVersion >= STEP_VERSION)
|
|
52
|
+
return { next: record, outcome: 'current' };
|
|
53
|
+
const connection = isObject(record.connection) ? record.connection : undefined;
|
|
54
|
+
const kind = typeof connection?.kind === 'string' ? connection.kind : '';
|
|
55
|
+
if (connection && kind === V4_FOLDER_KIND) {
|
|
56
|
+
const config = isObject(connection.config) ? connection.config : {};
|
|
57
|
+
const onDevice = typeof config.device === 'string' && config.device.length > 0;
|
|
58
|
+
const anchor = onDevice ? null : treeAnchorFor(config.root);
|
|
59
|
+
if (anchor !== null) {
|
|
60
|
+
const { hostRoot: _machineHalf, ...rest } = config;
|
|
61
|
+
return {
|
|
62
|
+
next: { ...record, connection: { ...connection, kind: V5_HOST_KIND, config: { ...rest, root: anchor } }, formatVersion: STEP_VERSION },
|
|
63
|
+
outcome: 'local',
|
|
64
|
+
anchored: true,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
next: { ...record, connection: { ...connection, kind: V5_HOST_KIND }, formatVersion: STEP_VERSION },
|
|
69
|
+
outcome: onDevice ? 'device' : 'local',
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
return { next: { ...record, formatVersion: STEP_VERSION }, outcome: 'other' };
|
|
73
|
+
}
|
|
74
|
+
async function readJson(file) {
|
|
75
|
+
const record = JSON.parse(await readFile(file, 'utf8'));
|
|
76
|
+
if (!isObject(record))
|
|
77
|
+
throw new Error(`${file} is not a source config`);
|
|
78
|
+
return record;
|
|
79
|
+
}
|
|
80
|
+
/** Every source config of the install, classified. Reads only. */
|
|
81
|
+
export async function inspectSourceToHost(ctx) {
|
|
82
|
+
const base = join(ctx.appRoot, 'config', 'sources');
|
|
83
|
+
let projects;
|
|
84
|
+
try {
|
|
85
|
+
projects = (await readdir(base)).sort();
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
if (error.code === 'ENOENT')
|
|
89
|
+
return [];
|
|
90
|
+
throw error;
|
|
91
|
+
}
|
|
92
|
+
const rows = [];
|
|
93
|
+
for (const projectId of projects) {
|
|
94
|
+
const dir = join(base, projectId);
|
|
95
|
+
if (!(await stat(dir)).isDirectory())
|
|
96
|
+
continue;
|
|
97
|
+
for (const name of (await readdir(dir)).filter((entry) => entry.endsWith('.json')).sort()) {
|
|
98
|
+
const path = join(dir, name);
|
|
99
|
+
const record = await readJson(path);
|
|
100
|
+
const slug = typeof record.source === 'string' ? record.source : name.slice(0, -'.json'.length);
|
|
101
|
+
const { next, outcome, anchored } = hostRecordOf(record);
|
|
102
|
+
const row = { file: relative(ctx.home, path), projectId, slug, outcome, ...(anchored ? { anchored } : {}) };
|
|
103
|
+
rows.push(JSON.stringify(next) === JSON.stringify(record) ? row : { ...row, next });
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return rows;
|
|
107
|
+
}
|
|
108
|
+
/** The dry-run lines of brain-core's half (the host module adds agent-core's). */
|
|
109
|
+
export function sourceToHostSummary(rows) {
|
|
110
|
+
const count = (outcome) => rows.filter((row) => row.outcome === outcome).length;
|
|
111
|
+
const writes = rows.filter((row) => row.next).length;
|
|
112
|
+
return {
|
|
113
|
+
files: writes > 0 ? ['app/config/sources'] : [],
|
|
114
|
+
summary: [
|
|
115
|
+
`source configs: ${rows.length} read, ${writes} to rewrite (every record stamped v${STEP_VERSION})`,
|
|
116
|
+
`host sources: ${count('local')} on this server, ${count('device')} on a device (was folder); other kinds ${count('other')}; already v${STEP_VERSION} ${count('current')}`,
|
|
117
|
+
`Neuralis-tree roots: ${rows.filter((row) => row.anchored).length} folder(s) in the image tree take a logical root (\`neuralis-tree:…\`)`,
|
|
118
|
+
],
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/** Write every changed record (idempotent: an unchanged one has no `next`). */
|
|
122
|
+
export async function applySourceToHost(ctx, rows) {
|
|
123
|
+
let written = 0;
|
|
124
|
+
for (const row of rows) {
|
|
125
|
+
if (!row.next)
|
|
126
|
+
continue;
|
|
127
|
+
await durableReplaceFile(join(ctx.home, row.file), JSON.stringify(row.next, null, 2));
|
|
128
|
+
written += 1;
|
|
129
|
+
}
|
|
130
|
+
return written;
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=sourceToHostV1.js.map
|