@neuralis/brain-core 0.3.2 → 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.
Files changed (311) hide show
  1. package/README.md +79 -1409
  2. package/app/README.md +1 -1
  3. package/app/cards/FilesystemCardShell.tsx +42 -4
  4. package/app/cards/FilesystemChangeCard.tsx +34 -11
  5. package/app/cards/README.md +6 -5
  6. package/app/cards/diffUtils.ts +99 -1
  7. package/app/filesystem/FilesystemHost.tsx +17 -2
  8. package/app/filesystem/api/README.md +3 -3
  9. package/app/filesystem/api/index.ts +35 -11
  10. package/app/filesystem/api/projectPackages.ts +13 -102
  11. package/app/filesystem/domain/types.ts +30 -10
  12. package/app/filesystem/hooks/README.md +3 -3
  13. package/app/filesystem/hooks/useDiscoverableSources.ts +19 -30
  14. package/app/filesystem/hooks/useFilesystemSSE.ts +1 -1
  15. package/app/filesystem/host/README.md +5 -3
  16. package/app/filesystem/host/buildFilesystemHostValue.ts +19 -0
  17. package/app/filesystem/host/installFilesystemHostComponents.tsx +1 -1
  18. package/app/filesystem/lib/sourceKindForm.ts +118 -39
  19. package/app/filesystem/lib/treeVisualState.tsx +98 -4
  20. package/app/filesystem/store/README.md +1 -0
  21. package/app/filesystem/store/filesystemStore.ts +86 -5
  22. package/app/filesystem/store/gitSlice.ts +5 -0
  23. package/app/filesystem/store/helpers.ts +17 -0
  24. package/app/filesystem/store/listSlice.ts +8 -0
  25. package/app/filesystem/ui/CodeEditor.tsx +18 -3
  26. package/app/filesystem/ui/FileEditor.tsx +15 -10
  27. package/app/filesystem/ui/FileTree.tsx +41 -16
  28. package/app/filesystem/ui/FolderPicker.tsx +251 -0
  29. package/app/filesystem/ui/GitControlPanel.tsx +5 -0
  30. package/app/filesystem/ui/PackagesPanel.tsx +52 -374
  31. package/app/filesystem/ui/PolicyEditor.tsx +109 -24
  32. package/app/filesystem/ui/README.md +17 -11
  33. package/app/filesystem/ui/RawMediaPreview.tsx +58 -0
  34. package/app/filesystem/ui/SourceBranchHeader.tsx +4 -4
  35. package/app/filesystem/ui/SourcesPanel.tsx +420 -360
  36. package/app/filesystem/ui/Toolbar.tsx +1 -2
  37. package/app/shared/filesystem.png +0 -0
  38. package/dist/app/host.js +57 -49
  39. package/dist/scripts/sourceRootPairV1.d.ts +47 -0
  40. package/dist/scripts/sourceRootPairV1.d.ts.map +1 -0
  41. package/dist/scripts/sourceRootPairV1.js +147 -0
  42. package/dist/scripts/sourceRootPairV1.js.map +1 -0
  43. package/dist/scripts/sourceToFolderV1.d.ts +56 -0
  44. package/dist/scripts/sourceToFolderV1.d.ts.map +1 -0
  45. package/dist/scripts/sourceToFolderV1.js +152 -0
  46. package/dist/scripts/sourceToFolderV1.js.map +1 -0
  47. package/dist/scripts/sourceToHostV1.d.ts +56 -0
  48. package/dist/scripts/sourceToHostV1.d.ts.map +1 -0
  49. package/dist/scripts/sourceToHostV1.js +132 -0
  50. package/dist/scripts/sourceToHostV1.js.map +1 -0
  51. package/dist/src/connectors/AppSourceConfigStore.d.ts +17 -3
  52. package/dist/src/connectors/AppSourceConfigStore.d.ts.map +1 -1
  53. package/dist/src/connectors/AppSourceConfigStore.js +46 -6
  54. package/dist/src/connectors/AppSourceConfigStore.js.map +1 -1
  55. package/dist/src/connectors/HostConnector.d.ts +201 -0
  56. package/dist/src/connectors/HostConnector.d.ts.map +1 -0
  57. package/dist/src/connectors/HostConnector.js +903 -0
  58. package/dist/src/connectors/HostConnector.js.map +1 -0
  59. package/dist/src/connectors/inProcessTransport.d.ts +131 -0
  60. package/dist/src/connectors/inProcessTransport.d.ts.map +1 -0
  61. package/dist/src/connectors/inProcessTransport.js +447 -0
  62. package/dist/src/connectors/inProcessTransport.js.map +1 -0
  63. package/dist/src/domain/access/callerPermissions.d.ts +29 -0
  64. package/dist/src/domain/access/callerPermissions.d.ts.map +1 -1
  65. package/dist/src/domain/access/callerPermissions.js +85 -5
  66. package/dist/src/domain/access/callerPermissions.js.map +1 -1
  67. package/dist/src/domain/access/nativeLocalFence.d.ts +65 -0
  68. package/dist/src/domain/access/nativeLocalFence.d.ts.map +1 -0
  69. package/dist/src/domain/access/nativeLocalFence.js +171 -0
  70. package/dist/src/domain/access/nativeLocalFence.js.map +1 -0
  71. package/dist/src/domain/access/uriPermission.js +3 -3
  72. package/dist/src/domain/access/uriPermission.js.map +1 -1
  73. package/dist/src/domain/byteRange.d.ts +15 -0
  74. package/dist/src/domain/byteRange.d.ts.map +1 -0
  75. package/dist/src/domain/byteRange.js +30 -0
  76. package/dist/src/domain/byteRange.js.map +1 -0
  77. package/dist/src/domain/defaultPermissions.d.ts.map +1 -1
  78. package/dist/src/domain/defaultPermissions.js +29 -0
  79. package/dist/src/domain/defaultPermissions.js.map +1 -1
  80. package/dist/src/domain/mime.d.ts +8 -16
  81. package/dist/src/domain/mime.d.ts.map +1 -1
  82. package/dist/src/domain/mime.js +10 -99
  83. package/dist/src/domain/mime.js.map +1 -1
  84. package/dist/src/domain/paths.d.ts.map +1 -1
  85. package/dist/src/domain/paths.js +5 -3
  86. package/dist/src/domain/paths.js.map +1 -1
  87. package/dist/src/domain/sourceConfig.d.ts +52 -19
  88. package/dist/src/domain/sourceConfig.d.ts.map +1 -1
  89. package/dist/src/domain/sourceConfig.js +103 -19
  90. package/dist/src/domain/sourceConfig.js.map +1 -1
  91. package/dist/src/domain/sourcePackages.d.ts +8 -8
  92. package/dist/src/domain/sourcePackages.d.ts.map +1 -1
  93. package/dist/src/domain/sourceRootPair.d.ts +88 -0
  94. package/dist/src/domain/sourceRootPair.d.ts.map +1 -0
  95. package/dist/src/domain/sourceRootPair.js +108 -0
  96. package/dist/src/domain/sourceRootPair.js.map +1 -0
  97. package/dist/src/domain/syncTypes.d.ts +8 -1
  98. package/dist/src/domain/syncTypes.d.ts.map +1 -1
  99. package/dist/src/domain/syncTypes.js +1 -0
  100. package/dist/src/domain/syncTypes.js.map +1 -1
  101. package/dist/src/domain/types.d.ts +24 -1
  102. package/dist/src/domain/types.d.ts.map +1 -1
  103. package/dist/src/domain/uri.d.ts.map +1 -1
  104. package/dist/src/domain/uri.js +3 -2
  105. package/dist/src/domain/uri.js.map +1 -1
  106. package/dist/src/embeddings/clients/GeminiEmbedder.d.ts.map +1 -1
  107. package/dist/src/embeddings/clients/GeminiEmbedder.js +2 -5
  108. package/dist/src/embeddings/clients/GeminiEmbedder.js.map +1 -1
  109. package/dist/src/embeddings/clients/OpenAIEmbedder.d.ts.map +1 -1
  110. package/dist/src/embeddings/clients/OpenAIEmbedder.js +2 -3
  111. package/dist/src/embeddings/clients/OpenAIEmbedder.js.map +1 -1
  112. package/dist/src/embeddings/clients/QwenEmbedder.d.ts +2 -0
  113. package/dist/src/embeddings/clients/QwenEmbedder.d.ts.map +1 -1
  114. package/dist/src/embeddings/clients/QwenEmbedder.js +10 -2
  115. package/dist/src/embeddings/clients/QwenEmbedder.js.map +1 -1
  116. package/dist/src/embeddings/clients/VoyageEmbedder.d.ts +2 -0
  117. package/dist/src/embeddings/clients/VoyageEmbedder.d.ts.map +1 -1
  118. package/dist/src/embeddings/clients/VoyageEmbedder.js +8 -1
  119. package/dist/src/embeddings/clients/VoyageEmbedder.js.map +1 -1
  120. package/dist/src/embeddings/factory.d.ts +5 -3
  121. package/dist/src/embeddings/factory.d.ts.map +1 -1
  122. package/dist/src/embeddings/factory.js +7 -3
  123. package/dist/src/embeddings/factory.js.map +1 -1
  124. package/dist/src/embeddings/models.d.ts +1 -1
  125. package/dist/src/embeddings/models.d.ts.map +1 -1
  126. package/dist/src/embeddings/retry.js +1 -1
  127. package/dist/src/embeddings/retry.js.map +1 -1
  128. package/dist/src/embeddings/types.d.ts +6 -0
  129. package/dist/src/embeddings/types.d.ts.map +1 -1
  130. package/dist/src/embeddings/types.js +11 -0
  131. package/dist/src/embeddings/types.js.map +1 -1
  132. package/dist/src/git/GitRunner.d.ts +110 -30
  133. package/dist/src/git/GitRunner.d.ts.map +1 -1
  134. package/dist/src/git/GitRunner.js +511 -199
  135. package/dist/src/git/GitRunner.js.map +1 -1
  136. package/dist/src/git/GitWatchRegistry.d.ts +41 -35
  137. package/dist/src/git/GitWatchRegistry.d.ts.map +1 -1
  138. package/dist/src/git/GitWatchRegistry.js +61 -79
  139. package/dist/src/git/GitWatchRegistry.js.map +1 -1
  140. package/dist/src/git/gitPlace.d.ts +61 -0
  141. package/dist/src/git/gitPlace.d.ts.map +1 -0
  142. package/dist/src/git/gitPlace.js +74 -0
  143. package/dist/src/git/gitPlace.js.map +1 -0
  144. package/dist/src/git/sourceGitControl.d.ts +31 -19
  145. package/dist/src/git/sourceGitControl.d.ts.map +1 -1
  146. package/dist/src/git/sourceGitControl.js +208 -92
  147. package/dist/src/git/sourceGitControl.js.map +1 -1
  148. package/dist/src/git/sourceGitStatus.js +1 -1
  149. package/dist/src/git/sourceGitStatus.js.map +1 -1
  150. package/dist/src/git/untrackedStats.js +1 -1
  151. package/dist/src/git/untrackedStats.js.map +1 -1
  152. package/dist/src/index.d.ts +2 -1
  153. package/dist/src/index.d.ts.map +1 -1
  154. package/dist/src/index.js +2 -1
  155. package/dist/src/index.js.map +1 -1
  156. package/dist/src/lifecycle.d.ts +8 -11
  157. package/dist/src/lifecycle.d.ts.map +1 -1
  158. package/dist/src/lifecycle.js +2 -1
  159. package/dist/src/lifecycle.js.map +1 -1
  160. package/dist/src/routes/git.d.ts.map +1 -1
  161. package/dist/src/routes/git.js +183 -54
  162. package/dist/src/routes/git.js.map +1 -1
  163. package/dist/src/routes/helpers/uriGuard.d.ts +1 -1
  164. package/dist/src/routes/helpers/uriGuard.d.ts.map +1 -1
  165. package/dist/src/routes/helpers/uriGuard.js +3 -2
  166. package/dist/src/routes/helpers/uriGuard.js.map +1 -1
  167. package/dist/src/routes/helpers.d.ts +10 -3
  168. package/dist/src/routes/helpers.d.ts.map +1 -1
  169. package/dist/src/routes/helpers.js +12 -5
  170. package/dist/src/routes/helpers.js.map +1 -1
  171. package/dist/src/routes/list.d.ts.map +1 -1
  172. package/dist/src/routes/list.js +2 -3
  173. package/dist/src/routes/list.js.map +1 -1
  174. package/dist/src/routes/policies.d.ts +6 -4
  175. package/dist/src/routes/policies.d.ts.map +1 -1
  176. package/dist/src/routes/policies.js +22 -16
  177. package/dist/src/routes/policies.js.map +1 -1
  178. package/dist/src/routes/raw.d.ts.map +1 -1
  179. package/dist/src/routes/raw.js +65 -11
  180. package/dist/src/routes/raw.js.map +1 -1
  181. package/dist/src/routes/sources.d.ts +60 -18
  182. package/dist/src/routes/sources.d.ts.map +1 -1
  183. package/dist/src/routes/sources.js +411 -299
  184. package/dist/src/routes/sources.js.map +1 -1
  185. package/dist/src/services/BridgeService.d.ts +15 -35
  186. package/dist/src/services/BridgeService.d.ts.map +1 -1
  187. package/dist/src/services/BridgeService.js +30 -88
  188. package/dist/src/services/BridgeService.js.map +1 -1
  189. package/dist/src/services/FilesystemService.d.ts +3 -2
  190. package/dist/src/services/FilesystemService.d.ts.map +1 -1
  191. package/dist/src/services/FilesystemService.js +110 -32
  192. package/dist/src/services/FilesystemService.js.map +1 -1
  193. package/dist/src/services/FilesystemUiService.d.ts +4 -1
  194. package/dist/src/services/FilesystemUiService.d.ts.map +1 -1
  195. package/dist/src/services/FilesystemUiService.js +66 -25
  196. package/dist/src/services/FilesystemUiService.js.map +1 -1
  197. package/dist/src/services/SyncScheduler.d.ts +12 -4
  198. package/dist/src/services/SyncScheduler.d.ts.map +1 -1
  199. package/dist/src/services/SyncScheduler.js +37 -8
  200. package/dist/src/services/SyncScheduler.js.map +1 -1
  201. package/dist/src/services/baselineRepair.d.ts +13 -3
  202. package/dist/src/services/baselineRepair.d.ts.map +1 -1
  203. package/dist/src/services/baselineRepair.js +13 -3
  204. package/dist/src/services/baselineRepair.js.map +1 -1
  205. package/dist/src/services/declaredSources.d.ts +125 -42
  206. package/dist/src/services/declaredSources.d.ts.map +1 -1
  207. package/dist/src/services/declaredSources.js +117 -45
  208. package/dist/src/services/declaredSources.js.map +1 -1
  209. package/dist/src/store/dataFormats.d.ts +17 -2
  210. package/dist/src/store/dataFormats.d.ts.map +1 -1
  211. package/dist/src/store/dataFormats.js +18 -3
  212. package/dist/src/store/dataFormats.js.map +1 -1
  213. package/dist/src/sync/DeltaSyncRunner.d.ts.map +1 -1
  214. package/dist/src/sync/DeltaSyncRunner.js +144 -4
  215. package/dist/src/sync/DeltaSyncRunner.js.map +1 -1
  216. package/dist/src/sync/SyncJobQueue.d.ts +7 -2
  217. package/dist/src/sync/SyncJobQueue.d.ts.map +1 -1
  218. package/dist/src/sync/SyncJobQueue.js +16 -10
  219. package/dist/src/sync/SyncJobQueue.js.map +1 -1
  220. package/dist/src/sync/SyncWatchService.d.ts +21 -4
  221. package/dist/src/sync/SyncWatchService.d.ts.map +1 -1
  222. package/dist/src/sync/SyncWatchService.js +115 -10
  223. package/dist/src/sync/SyncWatchService.js.map +1 -1
  224. package/dist/src/sync/categoryInference.d.ts +1 -1
  225. package/dist/src/sync/categoryInference.js +1 -1
  226. package/dist/src/usecases/admitSourceRoot.d.ts +65 -0
  227. package/dist/src/usecases/admitSourceRoot.d.ts.map +1 -0
  228. package/dist/src/usecases/admitSourceRoot.js +85 -0
  229. package/dist/src/usecases/admitSourceRoot.js.map +1 -0
  230. package/dist/src/usecases/browseSourceFolders.d.ts +85 -0
  231. package/dist/src/usecases/browseSourceFolders.d.ts.map +1 -0
  232. package/dist/src/usecases/browseSourceFolders.js +210 -0
  233. package/dist/src/usecases/browseSourceFolders.js.map +1 -0
  234. package/dist/src/usecases/createDeclaredSources.d.ts +13 -2
  235. package/dist/src/usecases/createDeclaredSources.d.ts.map +1 -1
  236. package/dist/src/usecases/createDeclaredSources.js +39 -0
  237. package/dist/src/usecases/createDeclaredSources.js.map +1 -1
  238. package/dist/src/usecases/list.d.ts.map +1 -1
  239. package/dist/src/usecases/list.js +83 -26
  240. package/dist/src/usecases/list.js.map +1 -1
  241. package/dist/src/usecases/listAttachableDevices.d.ts +13 -0
  242. package/dist/src/usecases/listAttachableDevices.d.ts.map +1 -0
  243. package/dist/src/usecases/listAttachableDevices.js +10 -0
  244. package/dist/src/usecases/listAttachableDevices.js.map +1 -0
  245. package/dist/src/usecases/listSourcePackages.d.ts.map +1 -1
  246. package/dist/src/usecases/listSourcePackages.js +2 -5
  247. package/dist/src/usecases/listSourcePackages.js.map +1 -1
  248. package/dist/src/usecases/purgeExcludedPoints.d.ts.map +1 -1
  249. package/dist/src/usecases/purgeExcludedPoints.js +3 -2
  250. package/dist/src/usecases/purgeExcludedPoints.js.map +1 -1
  251. package/dist/src/usecases/readFiles.d.ts.map +1 -1
  252. package/dist/src/usecases/readFiles.js +15 -0
  253. package/dist/src/usecases/readFiles.js.map +1 -1
  254. package/dist/src/usecases/reconcileSourcePackageRoots.d.ts +1 -1
  255. package/dist/src/usecases/reconcileSourcePackageRoots.d.ts.map +1 -1
  256. package/dist/src/usecases/reconcileSourcePackageRoots.js +2 -1
  257. package/dist/src/usecases/reconcileSourcePackageRoots.js.map +1 -1
  258. package/dist/src/usecases/revokePrincipal.d.ts +7 -5
  259. package/dist/src/usecases/revokePrincipal.d.ts.map +1 -1
  260. package/dist/src/usecases/revokePrincipal.js +29 -7
  261. package/dist/src/usecases/revokePrincipal.js.map +1 -1
  262. package/dist/src/usecases/scheduleSourceSync.d.ts +7 -0
  263. package/dist/src/usecases/scheduleSourceSync.d.ts.map +1 -1
  264. package/dist/src/usecases/scheduleSourceSync.js +6 -5
  265. package/dist/src/usecases/scheduleSourceSync.js.map +1 -1
  266. package/dist/src/usecases/triggerSourceSync.d.ts +46 -0
  267. package/dist/src/usecases/triggerSourceSync.d.ts.map +1 -0
  268. package/dist/src/usecases/triggerSourceSync.js +75 -0
  269. package/dist/src/usecases/triggerSourceSync.js.map +1 -0
  270. package/dist/src/usecases/uploadBinary.d.ts +2 -1
  271. package/dist/src/usecases/uploadBinary.d.ts.map +1 -1
  272. package/dist/src/usecases/uploadBinary.js +2 -2
  273. package/dist/src/usecases/uploadBinary.js.map +1 -1
  274. package/dist/src/usecases/vector/endpointGuard.d.ts +1 -1
  275. package/dist/src/usecases/vector/endpointGuard.js +1 -1
  276. package/dist/src/vector/qdrantClient.d.ts +1 -1
  277. package/dist/src/vector/qdrantClient.js +1 -1
  278. package/dist/src/wiring.d.ts +3 -0
  279. package/dist/src/wiring.d.ts.map +1 -1
  280. package/dist/src/wiring.js +72 -6
  281. package/dist/src/wiring.js.map +1 -1
  282. package/package.json +145 -54
  283. package/skills/connect-business-data/SKILL.md +2 -2
  284. package/skills/create-package/SKILL.md +18 -18
  285. package/skills/create-package/references/config-and-credentials.md +16 -13
  286. package/skills/create-package/references/connectors-and-uri-policies.md +36 -27
  287. package/skills/create-package/references/manifest-and-discovery.md +12 -12
  288. package/skills/create-package/references/runtime-and-build.md +18 -18
  289. package/skills/create-package/references/skills-and-context.md +35 -19
  290. package/skills/create-package/references/surfaces-and-design.md +16 -16
  291. package/skills/create-package/references/team-and-workflows.md +2 -2
  292. package/skills/create-package/references/test-and-ship.md +17 -17
  293. package/skills/create-package/references/tools-and-schemas.md +5 -5
  294. package/skills/create-package/scripts/{check-package.sh → check-package.mjs} +78 -64
  295. package/skills/create-package/scripts/{verify-loaded.sh → verify-loaded.mjs} +156 -162
  296. package/skills/git/SKILL.md +31 -29
  297. package/skills/manage-files/SKILL.md +11 -14
  298. package/skills/manage-sources/SKILL.md +85 -45
  299. package/skills/manage-uri-policy/SKILL.md +9 -6
  300. package/skills/sync/SKILL.md +1 -1
  301. package/dist/src/connectors/LocalDiskConnector.d.ts +0 -171
  302. package/dist/src/connectors/LocalDiskConnector.d.ts.map +0 -1
  303. package/dist/src/connectors/LocalDiskConnector.js +0 -1233
  304. package/dist/src/connectors/LocalDiskConnector.js.map +0 -1
  305. package/skills/manage-files/scripts/copy.sh +0 -7
  306. package/skills/manage-files/scripts/create.sh +0 -7
  307. package/skills/manage-files/scripts/mkdir.sh +0 -7
  308. package/skills/manage-files/scripts/modify.sh +0 -7
  309. package/skills/manage-files/scripts/upload.sh +0 -16
  310. package/skills/manage-files/scripts/write.sh +0 -29
  311. package/skills/manage-sources/scripts/reembed.sh +0 -23
@@ -0,0 +1,65 @@
1
+ import { type RuntimeStackInfo } from '@neuralis/package-system/paths';
2
+ import { type HierarchicalPermissions, type SourceConfig, type SourceEnabledState, type SyncConfig } from '../sourceConfig.js';
3
+ /** Where a canonical path sits relative to what a native `local` source may root at. */
4
+ export type NativeLocalPlacement =
5
+ /** IS or UNDER the caller's project zone — attachable with `sources.mount`. */
6
+ 'project'
7
+ /** IS or UNDER a privileged row (a filesystem root exactly) — attachable with `sources.privileged`. */
8
+ | 'privileged'
9
+ /** A strict ANCESTOR of the project zone — browsable on the way down, never attachable. */
10
+ | 'ancestor' | 'outside';
11
+ /** The stable refusal every fenced consumer answers with. */
12
+ export declare const NATIVE_LOCAL_REFUSAL: {
13
+ readonly code: 'native_local_root_outside_project';
14
+ readonly error: "On a native install a folder outside this project's own zone is reached through your own paired device: pair this computer (`neuralis device pair`), allow the folder, and add it as a folder on that device.";
15
+ };
16
+ /** An EDIT of an existing outside-rooted source: it may only narrow (`fencedEditWidens`). */
17
+ export declare const NATIVE_LOCAL_EDIT_REFUSAL: {
18
+ readonly code: "native_local_root_outside_project";
19
+ readonly error: "This source is rooted outside this project's own zone, which a native install reaches only through your own paired device: it can still be disabled, narrowed, described or deleted, never widened.";
20
+ };
21
+ /** The fence applies unless the stack says, explicitly, that this is Docker. */
22
+ export declare function nativeLocalFenceApplies(stack: Pick<RuntimeStackInfo, 'isDocker'> | null | undefined): boolean;
23
+ /**
24
+ * Classify a canonical absolute path. `projectRoot` empty ⇒ no project zone
25
+ * (nothing is `project` or `ancestor`); `privilegedRoots` are the privileged
26
+ * table's zone paths.
27
+ */
28
+ export declare function nativeLocalPlacement(path: string, projectRoot: string, privilegedRoots: readonly string[]): NativeLocalPlacement;
29
+ /** Attachable as a native `local` root (the privileged rows still need their feature). */
30
+ export declare function attachableNatively(placement: NativeLocalPlacement): boolean;
31
+ /**
32
+ * Does the fence refuse an in-process folder rooted at `resolvedRoot` (already
33
+ * resolved the way the connector resolves it)? Judged on the lexical path and
34
+ * again on the REAL path when it exists — a symlink inside the project zone that
35
+ * points elsewhere is refused like its target. Any other plane (a device folder,
36
+ * a connector kind), or a Docker stack, is not the fence's to judge (`false`).
37
+ */
38
+ export declare function nativeLocalRootRefused(input: {
39
+ stack: Pick<RuntimeStackInfo, 'isDocker'> | null | undefined;
40
+ connection: {
41
+ kind: string;
42
+ config?: unknown;
43
+ };
44
+ resolvedRoot: string;
45
+ projectRoot: string;
46
+ privilegedRoots: readonly string[];
47
+ }): Promise<boolean>;
48
+ /**
49
+ * Would this edit of a fenced in-process folder keep or create reach WIDER than
50
+ * it has? Reach = who may read/write/exec under the root (`permissions`), whether
51
+ * the source is live (`enabled`), whether it loads code (a `packageFolders`
52
+ * entry it did not carry)
53
+ * and which of its files the indexer reads (sync created, an exclude dropped, a
54
+ * wider include). Cadence, scan cap, media lanes and the description are not
55
+ * reach. `byRole` resolves by role PRIORITY, so its key set is reach too: a key
56
+ * may only be added denying all three bits, never removed.
57
+ */
58
+ export declare function fencedEditWidens(existing: Pick<SourceConfig, 'permissions' | 'enabled' | 'sync' | 'packageFolders'>, patch: {
59
+ permissions?: HierarchicalPermissions;
60
+ enabled?: SourceEnabledState;
61
+ sync?: Pick<SyncConfig, 'exclude' | 'include'>;
62
+ clearSync?: boolean;
63
+ packageFolders?: readonly string[];
64
+ }): boolean;
65
+ //# sourceMappingURL=nativeLocalFence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nativeLocalFence.d.ts","sourceRoot":"","sources":["../../../../src/domain/access/nativeLocalFence.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAmD,KAAK,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAExH,OAAO,EAAuB,KAAK,uBAAuB,EAAuB,KAAK,YAAY,EAAE,KAAK,kBAAkB,EAAE,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEzK,wFAAwF;AACxF,MAAM,MAAM,oBAAoB;AAC9B,+EAA+E;AAC7E,SAAS;AACX,uGAAuG;GACrG,YAAY;AACd,2FAA2F;GACzF,UAAU,GACV,SAAS,CAAC;AAEd,6DAA6D;AAC7D,eAAO,MAAM,oBAAoB;aAC/B,IAAI,EAAE,mCAAmC;aACzC,KAAK,EAAE,+MAA+M;CAC9M,CAAC;AAEX,6FAA6F;AAC7F,eAAO,MAAM,yBAAyB;aACpC,IAAI;aACJ,KAAK,EAAE,qMAAqM;CACpM,CAAC;AAEX,gFAAgF;AAChF,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,IAAI,CAAC,gBAAgB,EAAE,UAAU,CAAC,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAE7G;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,SAAS,MAAM,EAAE,GACjC,oBAAoB,CAQtB;AAED,0FAA0F;AAC1F,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,oBAAoB,GAAG,OAAO,CAE3E;AAUD;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAAC,KAAK,EAAE;IAClD,KAAK,EAAE,IAAI,CAAC,gBAAgB,EAAE,UAAU,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;IAC7D,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC/C,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC,GAAG,OAAO,CAAC,OAAO,CAAC,CAWnB;AA8CD;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,IAAI,CAAC,YAAY,EAAE,aAAa,GAAG,SAAS,GAAG,MAAM,GAAG,gBAAgB,CAAC,EACnF,KAAK,EAAE;IACL,WAAW,CAAC,EAAE,uBAAuB,CAAC;IACtC,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,IAAI,CAAC,EAAE,IAAI,CAAC,UAAU,EAAE,SAAS,GAAG,SAAS,CAAC,CAAC;IAC/C,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC,GACA,OAAO,CAoBT"}
@@ -0,0 +1,171 @@
1
+ /**
2
+ * The native folder fence — where an IN-PROCESS folder (the `host` kind with
3
+ * no `device`, the kernel's `sourcePlane` = `local`) may be rooted when the
4
+ * platform runs WITHOUT a container (`stack.isDocker === false`).
5
+ *
6
+ * In Docker the container is the boundary: an in-process root names only what
7
+ * the operator mounted. On a native host there is none, so an in-process root is
8
+ * the host OS user's whole reach — a manager (`sources.mount` is a manager
9
+ * default) could otherwise attach `~/.ssh`. On a native host such a root is
10
+ * accepted only inside the caller's own project zone (`<home>/projects/<projectId>`),
11
+ * or IS / is UNDER one of the privileged rows (the App Zone, the Neuralis tree,
12
+ * the whole host — `/` or a drive root — exactly) — which still cost
13
+ * `sources.privileged` through the privileged-root table. Every other folder is
14
+ * a folder on the user's own paired device (the same kind, `device` set).
15
+ *
16
+ * The signal is the kernel's ONE `stack.isDocker`, and it fails CLOSED: only an
17
+ * explicit `true` opens the Docker arm. Scope: the folder kind's in-process
18
+ * transport only — the privileged-root gate's other root-bearing kinds are not
19
+ * covered here, and a device folder is the device owner's ceiling's to bound.
20
+ */
21
+ import { realpath } from 'node:fs/promises';
22
+ import { resolve } from 'node:path';
23
+ import { hostPathFlavour, isFilesystemRoot, isPathInside } from '@neuralis/package-system/paths';
24
+ import { sourcePlane } from '@neuralis/package-system/contracts';
25
+ import { resolveEnabledState } from '../sourceConfig.js';
26
+ /** The stable refusal every fenced consumer answers with. */
27
+ export const NATIVE_LOCAL_REFUSAL = {
28
+ code: 'native_local_root_outside_project',
29
+ error: "On a native install a folder outside this project's own zone is reached through your own paired device: pair this computer (`neuralis device pair`), allow the folder, and add it as a folder on that device.",
30
+ };
31
+ /** An EDIT of an existing outside-rooted source: it may only narrow (`fencedEditWidens`). */
32
+ export const NATIVE_LOCAL_EDIT_REFUSAL = {
33
+ code: NATIVE_LOCAL_REFUSAL.code,
34
+ error: "This source is rooted outside this project's own zone, which a native install reaches only through your own paired device: it can still be disabled, narrowed, described or deleted, never widened.",
35
+ };
36
+ /** The fence applies unless the stack says, explicitly, that this is Docker. */
37
+ export function nativeLocalFenceApplies(stack) {
38
+ return stack?.isDocker !== true;
39
+ }
40
+ /**
41
+ * Classify a canonical absolute path. `projectRoot` empty ⇒ no project zone
42
+ * (nothing is `project` or `ancestor`); `privilegedRoots` are the privileged
43
+ * table's zone paths.
44
+ */
45
+ export function nativeLocalPlacement(path, projectRoot, privilegedRoots) {
46
+ if (projectRoot && isPathInside(projectRoot, path))
47
+ return 'project';
48
+ for (const root of privilegedRoots) {
49
+ // A filesystem root covers only itself — under it is everything, which is no zone.
50
+ if ((!isFilesystemRoot(root) || isFilesystemRoot(path)) && isPathInside(root, path, hostPathFlavour(root)))
51
+ return 'privileged';
52
+ }
53
+ if (projectRoot && isPathInside(path, projectRoot))
54
+ return 'ancestor';
55
+ return 'outside';
56
+ }
57
+ /** Attachable as a native `local` root (the privileged rows still need their feature). */
58
+ export function attachableNatively(placement) {
59
+ return placement === 'project' || placement === 'privileged';
60
+ }
61
+ async function realOrSelf(path) {
62
+ try {
63
+ return await realpath(path);
64
+ }
65
+ catch {
66
+ return path;
67
+ }
68
+ }
69
+ /**
70
+ * Does the fence refuse an in-process folder rooted at `resolvedRoot` (already
71
+ * resolved the way the connector resolves it)? Judged on the lexical path and
72
+ * again on the REAL path when it exists — a symlink inside the project zone that
73
+ * points elsewhere is refused like its target. Any other plane (a device folder,
74
+ * a connector kind), or a Docker stack, is not the fence's to judge (`false`).
75
+ */
76
+ export async function nativeLocalRootRefused(input) {
77
+ const config = (input.connection.config ?? {});
78
+ if (sourcePlane(input.connection.kind, config) !== 'local' || !nativeLocalFenceApplies(input.stack))
79
+ return false;
80
+ const projectRoot = input.projectRoot ? resolve(input.projectRoot) : '';
81
+ const lexical = resolve(input.resolvedRoot);
82
+ if (!attachableNatively(nativeLocalPlacement(lexical, projectRoot, input.privilegedRoots)))
83
+ return true;
84
+ const real = await realOrSelf(lexical);
85
+ if (real === lexical)
86
+ return false;
87
+ const realProject = projectRoot ? await realOrSelf(projectRoot) : '';
88
+ const realPrivileged = await Promise.all(input.privilegedRoots.map((root) => (isFilesystemRoot(root) ? root : realOrSelf(root))));
89
+ return !attachableNatively(nativeLocalPlacement(real, realProject, realPrivileged));
90
+ }
91
+ const CAPS = ['read', 'write', 'exec'];
92
+ /** A bit narrows when it never gains reach: unchanged, true→false, true→unset, unset→false. */
93
+ const bitsNarrow = (old, next) => CAPS.every((c) => old[c] === next[c] || old[c] === true || next[c] === false);
94
+ const grantsNothing = (b) => CAPS.every((c) => b[c] !== true);
95
+ const deniesNothing = (b) => CAPS.every((c) => b[c] !== false);
96
+ const deniesAll = (b) => CAPS.every((c) => b[c] === false);
97
+ function entriesNarrow(old = {}, next = {}, added, removed) {
98
+ const has = Object.hasOwn;
99
+ return [...new Set([...Object.keys(old), ...Object.keys(next)])].every((k) => (has(old, k) && has(next, k) ? bitsNarrow(old[k], next[k])
100
+ : has(next, k) ? added(next[k]) : removed(old[k])));
101
+ }
102
+ const sameList = (a, b) => (a ?? []).join('\0') === (b ?? []).join('\0');
103
+ const sameRule = (a, b) => a.pattern === b.pattern && a.override === b.override
104
+ && a.floor === b.floor && a.priority === b.priority && sameList(a.roles, b.roles) && sameList(a.agents, b.agents) && sameList(a.users, b.users);
105
+ /**
106
+ * Path rows apply IN ORDER (an `override` row overwrites what came before), so
107
+ * the new list must derive from the old one through steps that each narrow: a
108
+ * row kept with the same pattern and conditions and narrowed bits, a removed row
109
+ * that denied nothing, an inserted row that grants nothing. Conservative — an
110
+ * alignment the walk misses is refused, never admitted.
111
+ */
112
+ function pathsNarrow(old = [], next = []) {
113
+ let i = 0;
114
+ let j = 0;
115
+ while (i < old.length || j < next.length) {
116
+ if (i < old.length && j < next.length && sameRule(old[i], next[j]) && bitsNarrow(old[i].permissions, next[j].permissions)) {
117
+ i++;
118
+ j++;
119
+ continue;
120
+ }
121
+ if (j < next.length && !next[j].floor && grantsNothing(next[j].permissions)) {
122
+ j++;
123
+ continue;
124
+ }
125
+ if (i < old.length && !old[i].floor && deniesNothing(old[i].permissions)) {
126
+ i++;
127
+ continue;
128
+ }
129
+ return false;
130
+ }
131
+ return true;
132
+ }
133
+ const ENABLED_RANK = { false: 0, auto: 1, true: 2 };
134
+ /**
135
+ * Would this edit of a fenced in-process folder keep or create reach WIDER than
136
+ * it has? Reach = who may read/write/exec under the root (`permissions`), whether
137
+ * the source is live (`enabled`), whether it loads code (a `packageFolders`
138
+ * entry it did not carry)
139
+ * and which of its files the indexer reads (sync created, an exclude dropped, a
140
+ * wider include). Cadence, scan cap, media lanes and the description are not
141
+ * reach. `byRole` resolves by role PRIORITY, so its key set is reach too: a key
142
+ * may only be added denying all three bits, never removed.
143
+ */
144
+ export function fencedEditWidens(existing, patch) {
145
+ if (patch.enabled !== undefined && ENABLED_RANK[`${patch.enabled}`] > ENABLED_RANK[`${resolveEnabledState(existing)}`])
146
+ return true;
147
+ if (patch.packageFolders && !patch.packageFolders.every((folder) => (existing.packageFolders ?? []).includes(folder)))
148
+ return true;
149
+ const sync = patch.clearSync ? undefined : patch.sync;
150
+ if (sync) {
151
+ const old = existing.sync;
152
+ if (!old)
153
+ return true;
154
+ if (!old.exclude.every((p) => sync.exclude.includes(p)))
155
+ return true;
156
+ const oldIn = old.include ?? [];
157
+ const nextIn = sync.include ?? [];
158
+ if (oldIn.length > 0 && (nextIn.length === 0 || !nextIn.every((p) => oldIn.includes(p))))
159
+ return true;
160
+ }
161
+ const o = existing.permissions;
162
+ const n = patch.permissions;
163
+ if (!n)
164
+ return false;
165
+ return !(bitsNarrow(o.default, n.default)
166
+ && entriesNarrow(o.byRole, n.byRole, deniesAll, () => false)
167
+ && entriesNarrow(o.byUser, n.byUser, grantsNothing, deniesNothing)
168
+ && entriesNarrow(o.byAgent, n.byAgent, grantsNothing, deniesNothing)
169
+ && pathsNarrow(o.paths, n.paths));
170
+ }
171
+ //# sourceMappingURL=nativeLocalFence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nativeLocalFence.js","sourceRoot":"","sources":["../../../../src/domain/access/nativeLocalFence.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@ import { scopeAccessCtxFromExecution } from '../scopeAccessCtx.js';
3
3
  import { deriveSourceKind } from '../source.js';
4
4
  import { sourceFromUri } from '../uri.js';
5
5
  import { resolveCallerPermissions } from './callerPermissions.js';
6
- import { SourceNotConfiguredError, SourcePermissionDeniedError } from '../sourceConfig.js';
6
+ import { SourceNotConfiguredError, SourcePermissionDeniedError, sourceScopeOrigin } from '../sourceConfig.js';
7
7
  import { assertSourceEnabled } from './sourceEnabled.js';
8
8
  /**
9
9
  * The THROWING per-uri gate every write (and every single-result read) passes.
@@ -65,11 +65,11 @@ export async function checkUriPermission(deps, ctx, uri, operation, configCache)
65
65
  throw new SourceNotConfiguredError(source);
66
66
  }
67
67
  const scopeCtx = scopeAccessCtxFromExecution(ctx);
68
- if (!canAccessScope(config.scope, scopeCtx, 'read')) {
68
+ if (!canAccessScope(config.scope, scopeCtx, 'read', sourceScopeOrigin(config.connection))) {
69
69
  throw new SourceNotConfiguredError(source);
70
70
  }
71
71
  await assertSourceEnabled(deps, ctx.projectId, source, config);
72
- if (operation !== 'read' && !canAccessScope(config.scope, scopeCtx, 'write')) {
72
+ if (operation !== 'read' && !canAccessScope(config.scope, scopeCtx, 'write', sourceScopeOrigin(config.connection))) {
73
73
  throw new SourcePermissionDeniedError(source, operation);
74
74
  }
75
75
  const resolved = await resolveCallerPermissions(config, uri, ctx, source);
@@ -1 +1 @@
1
- {"version":3,"file":"uriPermission.js","sourceRoot":"","sources":["../../../../src/domain/access/uriPermission.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAEpE,OAAO,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAElE,OAAO,EAAE,wBAAwB,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AAE3F,OAAO,EAAE,mBAAmB,EAA0B,MAAM,oBAAoB,CAAC;AAOjF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,IAAuB,EACvB,GAAqB,EACrB,GAAW,EACX,SAAoC,EACpC,WAA8C;IAE9C,IAAI,CAAC,IAAI,CAAC,aAAa;QAAE,OAAO;IAChC,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,MAA2B,CAAC;IAChC,IAAI,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7B,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC;IAC3C,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CACnC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,EAChD,MAAM,CACP,CAAC;QACF,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,CAAC;IACD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,IAAI,gBAAgB,CAAC,MAAM,CAAC,KAAK,OAAO;YAAE,OAAO;QACjD,MAAM,IAAI,wBAAwB,CAAC,MAAM,CAAC,CAAC;IAC7C,CAAC;IACD,MAAM,QAAQ,GAAG,2BAA2B,CAAC,GAAG,CAAC,CAAC;IAClD,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,wBAAwB,CAAC,MAAM,CAAC,CAAC;IAC7C,CAAC;IACD,MAAM,mBAAmB,CAAC,IAAI,EAAE,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/D,IAAI,SAAS,KAAK,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,CAAC;QAC7E,MAAM,IAAI,2BAA2B,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC3D,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,wBAAwB,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;IAC1E,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,2BAA2B,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC3D,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"uriPermission.js","sourceRoot":"","sources":["../../../../src/domain/access/uriPermission.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAEpE,OAAO,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAElE,OAAO,EAAE,wBAAwB,EAAE,2BAA2B,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE9G,OAAO,EAAE,mBAAmB,EAA0B,MAAM,oBAAoB,CAAC;AAOjF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,IAAuB,EACvB,GAAqB,EACrB,GAAW,EACX,SAAoC,EACpC,WAA8C;IAE9C,IAAI,CAAC,IAAI,CAAC,aAAa;QAAE,OAAO;IAChC,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,MAA2B,CAAC;IAChC,IAAI,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7B,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC;IAC3C,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CACnC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,EAChD,MAAM,CACP,CAAC;QACF,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,CAAC;IACD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,IAAI,gBAAgB,CAAC,MAAM,CAAC,KAAK,OAAO;YAAE,OAAO;QACjD,MAAM,IAAI,wBAAwB,CAAC,MAAM,CAAC,CAAC;IAC7C,CAAC;IACD,MAAM,QAAQ,GAAG,2BAA2B,CAAC,GAAG,CAAC,CAAC;IAClD,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,iBAAiB,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;QAC1F,MAAM,IAAI,wBAAwB,CAAC,MAAM,CAAC,CAAC;IAC7C,CAAC;IACD,MAAM,mBAAmB,CAAC,IAAI,EAAE,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/D,IAAI,SAAS,KAAK,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAAiB,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;QACnH,MAAM,IAAI,2BAA2B,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC3D,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,wBAAwB,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;IAC1E,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,2BAA2B,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC3D,CAAC;AACH,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * One `bytes=` range against a body of `size` bytes: `[start, end]` inclusive,
3
+ * `'unsatisfiable'` (416), or `null` when the header is absent, malformed or
4
+ * names several ranges — those get the whole body (RFC 9110 §14.2 lets a
5
+ * server ignore a Range it does not support).
6
+ */
7
+ export declare function parseByteRange(header: string | null | undefined, size: number): [number, number] | 'unsatisfiable' | null;
8
+ /**
9
+ * The most bytes ONE ranged answer carries (8 MiB). A range wider than this —
10
+ * a player's open-ended `bytes=0-` — is answered with its first 8 MiB and a
11
+ * `Content-Range` saying so; the client asks for the rest. This is what keeps a
12
+ * 206 memory-bounded however large the file is.
13
+ */
14
+ export declare const RAW_RANGE_MAX_BYTES: number;
15
+ //# sourceMappingURL=byteRange.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"byteRange.d.ts","sourceRoot":"","sources":["../../../src/domain/byteRange.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,eAAe,GAAG,IAAI,CAYzH;AAED;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,QAAkB,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * One `bytes=` range against a body of `size` bytes: `[start, end]` inclusive,
3
+ * `'unsatisfiable'` (416), or `null` when the header is absent, malformed or
4
+ * names several ranges — those get the whole body (RFC 9110 §14.2 lets a
5
+ * server ignore a Range it does not support).
6
+ */
7
+ export function parseByteRange(header, size) {
8
+ const match = /^bytes=(\d*)-(\d*)$/.exec(String(header ?? '').trim());
9
+ if (!match || (match[1] === '' && match[2] === ''))
10
+ return null;
11
+ if (match[1] === '') {
12
+ const suffix = Number(match[2]);
13
+ if (suffix === 0 || size === 0)
14
+ return 'unsatisfiable';
15
+ return [Math.max(0, size - suffix), size - 1];
16
+ }
17
+ const start = Number(match[1]);
18
+ if (start >= size)
19
+ return 'unsatisfiable';
20
+ const end = match[2] === '' ? size - 1 : Math.min(Number(match[2]), size - 1);
21
+ return end < start ? null : [start, end];
22
+ }
23
+ /**
24
+ * The most bytes ONE ranged answer carries (8 MiB). A range wider than this —
25
+ * a player's open-ended `bytes=0-` — is answered with its first 8 MiB and a
26
+ * `Content-Range` saying so; the client asks for the rest. This is what keeps a
27
+ * 206 memory-bounded however large the file is.
28
+ */
29
+ export const RAW_RANGE_MAX_BYTES = 8 * 1024 * 1024;
30
+ //# sourceMappingURL=byteRange.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"byteRange.js","sourceRoot":"","sources":["../../../src/domain/byteRange.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,MAAiC,EAAE,IAAY;IAC5E,MAAM,KAAK,GAAG,qBAAqB,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACtE,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC;QAAE,OAAO,IAAI,CAAC;IAChE,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;QACpB,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAChC,IAAI,MAAM,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC;YAAE,OAAO,eAAe,CAAC;QACvD,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC;IAChD,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/B,IAAI,KAAK,IAAI,IAAI;QAAE,OAAO,eAAe,CAAC;IAC1C,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC;IAC9E,OAAO,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"defaultPermissions.d.ts","sourceRoot":"","sources":["../../../src/domain/defaultPermissions.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAEjE;;;;;;;;;GASG;AACH,eAAO,MAAM,4BAA4B,UAwGxC,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,wBAAwB,EAAE,uBAGtC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,EAAE,uBAG1C,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,EAAE,uBAMvC,CAAC"}
1
+ {"version":3,"file":"defaultPermissions.d.ts","sourceRoot":"","sources":["../../../src/domain/defaultPermissions.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAEjE;;;;;;;;;GASG;AACH,eAAO,MAAM,4BAA4B,UAqIxC,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,wBAAwB,EAAE,uBAGtC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,EAAE,uBAG1C,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,EAAE,uBAMvC,CAAC"}
@@ -118,6 +118,35 @@ export const DEFAULT_QDRANT_SYNC_EXCLUDES = [
118
118
  '**/.config/chromium/**',
119
119
  '**/.config/google-chrome/**',
120
120
  '**/.mozilla/**',
121
+ // A Neuralis device's own credentials: the CLI sign-in (Linux, macOS,
122
+ // Windows) and the device folder — every host's link secret — and the
123
+ // Neuralis host's own data in the same home, for a source that covers it
124
+ // (a whole-host or drive-root source): keys, users and platform config,
125
+ // each project's conversations and notifications, the backups. Named
126
+ // folder by folder: a project's own files and a device's scratch live
127
+ // under `.neuralis` too, never exclude it whole.
128
+ '**/.config/neuralis/**',
129
+ '**/Library/Application Support/neuralis/**',
130
+ '**/AppData/Roaming/neuralis/**',
131
+ '**/.neuralis/device/**',
132
+ '**/.local/share/neuralis/device/**',
133
+ '**/.neuralis/app/**',
134
+ '**/.local/share/neuralis/app/**',
135
+ '**/.neuralis/projects/*/data/**',
136
+ '**/.local/share/neuralis/projects/*/data/**',
137
+ '**/.neuralis/projects/*/notifications/**',
138
+ '**/.local/share/neuralis/projects/*/notifications/**',
139
+ '**/.neuralis/checkpoints/**',
140
+ '**/.local/share/neuralis/checkpoints/**',
141
+ '**/.neuralis/qdrant-backups/**',
142
+ '**/.local/share/neuralis/qdrant-backups/**',
143
+ '**/.neuralis/build/**',
144
+ '**/.local/share/neuralis/build/**',
145
+ '**/.neuralis/qdrant-version.json',
146
+ '**/.local/share/neuralis/qdrant-version.json',
147
+ // The pending OAuth sign-in store under the App Zone: a PKCE code verifier,
148
+ // the OAuth state and the captured sink for each sign-in in flight.
149
+ '**/oauth-flows/**',
121
150
  ];
122
151
  /**
123
152
  * data — generic frame applied at source creation. Every per-package
@@ -1 +1 @@
1
- {"version":3,"file":"defaultPermissions.js","sourceRoot":"","sources":["../../../src/domain/defaultPermissions.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG;IAC1C,iBAAiB;IACjB,oBAAoB;IACpB,2EAA2E;IAC3E,0EAA0E;IAC1E,6DAA6D;IAC7D,gBAAgB;IAChB,mBAAmB;IACnB,gBAAgB;IAChB,mBAAmB;IACnB,SAAS;IACT,YAAY;IACZ,iBAAiB;IACjB,oBAAoB;IACpB,gBAAgB;IAChB,mBAAmB;IACnB,UAAU;IACV,aAAa;IACb,SAAS;IACT,YAAY;IACZ,UAAU;IACV,aAAa;IACb,QAAQ;IACR,WAAW;IACX,eAAe;IACf,kBAAkB;IAClB,QAAQ;IACR,WAAW;IACX,MAAM;IACN,SAAS;IACT,QAAQ;IACR,WAAW;IACX,OAAO;IACP,UAAU;IACV,OAAO;IACP,UAAU;IACV,QAAQ;IACR,WAAW;IACX,YAAY;IACZ,eAAe;IACf,gBAAgB;IAChB,mBAAmB;IACnB,WAAW;IACX,cAAc;IACd,4EAA4E;IAC5E,4EAA4E;IAC5E,2EAA2E;IAC3E,0EAA0E;IAC1E,6EAA6E;IAC7E,4EAA4E;IAC5E,6DAA6D;IAC7D,SAAS;IACT,YAAY;IACZ,YAAY;IACZ,4EAA4E;IAC5E,0EAA0E;IAC1E,0BAA0B;IAC1B,4EAA4E;IAC5E,4EAA4E;IAC5E,2EAA2E;IAC3E,sEAAsE;IACtE,6DAA6D;IAC7D,wBAAwB;IACxB,2BAA2B;IAC3B,yEAAyE;IACzE,2EAA2E;IAC3E,4EAA4E;IAC5E,yEAAyE;IACzE,uEAAuE;IACvE,wEAAwE;IACxE,4EAA4E;IAC5E,uEAAuE;IACvE,yEAAyE;IACzE,kEAAkE;IAClE,0EAA0E;IAC1E,YAAY;IACZ,cAAc;IACd,yEAAyE;IACzE,kEAAkE;IAClE,0EAA0E;IAC1E,qEAAqE;IACrE,uEAAuE;IACvE,2EAA2E;IAC3E,4DAA4D;IAC5D,YAAY;IACZ,wBAAwB;IACxB,YAAY;IACZ,YAAY;IACZ,cAAc;IACd,aAAa;IACb,eAAe;IACf,6BAA6B;IAC7B,sBAAsB;IACtB,kBAAkB;IAClB,sBAAsB;IACtB,WAAW;IACX,qBAAqB;IACrB,WAAW;IACX,YAAY;IACZ,6EAA6E;IAC7E,4BAA4B;IAC5B,wBAAwB;IACxB,6BAA6B;IAC7B,gBAAgB;CACjB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAA4B;IAC/D,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE;IACjD,KAAK,EAAE,EAAE;CACV,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAA4B;IACnE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE;IACjD,KAAK,EAAE,EAAE;CACV,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAA4B;IAChE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE;IACjD,MAAM,EAAE;QACN,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE;KACzB;IACD,KAAK,EAAE,EAAE;CACV,CAAC"}
1
+ {"version":3,"file":"defaultPermissions.js","sourceRoot":"","sources":["../../../src/domain/defaultPermissions.ts"],"names":[],"mappings":"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"}
@@ -4,8 +4,9 @@
4
4
  * Two jobs live here, and they are deliberately different layers:
5
5
  *
6
6
  * 1. **Resolution** (`inferMimeTypeFromFilename`, `looksTextByMime`) — what a
7
- * file's type honestly IS. Moved here from `FilesystemUiService` so the
8
- * serve path and the store path answer from the same table.
7
+ * file's type honestly IS, so the serve path and the store path answer from
8
+ * the same table. The extension tables themselves are the kernel's
9
+ * (`@neuralis/package-system/web-common`), re-exported below.
9
10
  * 2. **Response policy** (`classifyResponseMime`, `buildRawResponseHeaders`) —
10
11
  * what the byte lane is allowed to tell a BROWSER to do with those bytes.
11
12
  *
@@ -79,17 +80,8 @@
79
80
  * `FilesystemUiService` excludes the active-document class at that one site for
80
81
  * exactly this reason — the body is JSON and the wire should say so.
81
82
  */
83
+ export { binaryMimeTypeForPath, inferMimeTypeFromFilename } from '@neuralis/package-system/web-common';
82
84
  export declare function looksTextByMime(mimeType: string | undefined): boolean;
83
- /**
84
- * Extension → mime, for files whose stored metadata carries no type.
85
- *
86
- * The five document extensions at the end are NOT decoration: they make the
87
- * extension agree with `classifyResponseMime`'s active-document set, so an
88
- * `.html` or `.xml` file reports what it is instead of `application/octet-stream`
89
- * and is classified on its merits. Both land on `attachment` either way — this
90
- * only removes a lie from the wire.
91
- */
92
- export declare function inferMimeTypeFromFilename(filename: string): string;
93
85
  /**
94
86
  * Lowercase `type/subtype`, parameters dropped, syntactically validated.
95
87
  * Returns `null` for anything absent, over-long or not token-shaped — the
@@ -141,9 +133,10 @@ export declare function buildRawResponseHeaders(input: RawResponseHeaderInput):
141
133
  *
142
134
  * **SCOPE, measured live — the magic-byte check governs the STORED value, and
143
135
  * on a non-brain source it does NOT reach the wire.** `loadRawBytes` returns
144
- * `result.mimeType || mimeType` for `sourceKind !== 'brain'`, so the local
145
- * connector's own extension-derived type wins over the persisted metadata at
146
- * serve time. HTML bytes stored as `application/octet-stream` under the name
136
+ * the connector's type for `sourceKind !== 'brain'` whenever the connector can
137
+ * tell (anything but `application/octet-stream`, the contract's "cannot
138
+ * tell"), so the local connector's own extension-derived type wins over the
139
+ * persisted metadata at serve time. HTML bytes stored as `application/octet-stream` under the name
147
140
  * `x.png` are therefore SERVED `image/png`. That is bounded and not a hole: the
148
141
  * classification still runs on the extension, so `.svg`/`.html`/`.xml` stay
149
142
  * `attachment`, and a mislabelled raster is inert under the globally-present
@@ -171,5 +164,4 @@ export declare function normalizeStoredMimeType(declared: string | undefined, fi
171
164
  * for every other reader of that request.
172
165
  */
173
166
  export declare function normalizeNodeMetadataMime(metadata: unknown, filename: string): Record<string, unknown> | undefined;
174
- export declare function binaryMimeTypeForPath(filePath: string): string | undefined;
175
167
  //# sourceMappingURL=mime.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mime.d.ts","sourceRoot":"","sources":["../../../src/domain/mime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgFG;AAWH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAGrE;AAED;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAmBlE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAI9E;AAED,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,iBAAiB,GAAG,QAAQ,CAAC;AAsBxE;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,iBAAiB,CAS9E;AA4BD,MAAM,MAAM,sBAAsB,GAAG;IACnC,oFAAoF;IACpF,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,sBAAsB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAqB7F;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,QAAQ,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,UAAU,GACjB,MAAM,CAaR;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,OAAO,EACjB,QAAQ,EAAE,MAAM,GACf,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CASrC;AA8CD,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAI1E"}
1
+ {"version":3,"file":"mime.d.ts","sourceRoot":"","sources":["../../../src/domain/mime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiFG;AAMH,OAAO,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,MAAM,qCAAqC,CAAC;AAQvG,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAGrE;AAGD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAI9E;AAED,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,iBAAiB,GAAG,QAAQ,CAAC;AAsBxE;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,iBAAiB,CAS9E;AA4BD,MAAM,MAAM,sBAAsB,GAAG;IACnC,oFAAoF;IACpF,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,sBAAsB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAqB7F;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,QAAQ,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,UAAU,GACjB,MAAM,CAaR;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,OAAO,EACjB,QAAQ,EAAE,MAAM,GACf,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CASrC"}
@@ -4,8 +4,9 @@
4
4
  * Two jobs live here, and they are deliberately different layers:
5
5
  *
6
6
  * 1. **Resolution** (`inferMimeTypeFromFilename`, `looksTextByMime`) — what a
7
- * file's type honestly IS. Moved here from `FilesystemUiService` so the
8
- * serve path and the store path answer from the same table.
7
+ * file's type honestly IS, so the serve path and the store path answer from
8
+ * the same table. The extension tables themselves are the kernel's
9
+ * (`@neuralis/package-system/web-common`), re-exported below.
9
10
  * 2. **Response policy** (`classifyResponseMime`, `buildRawResponseHeaders`) —
10
11
  * what the byte lane is allowed to tell a BROWSER to do with those bytes.
11
12
  *
@@ -79,8 +80,10 @@
79
80
  * `FilesystemUiService` excludes the active-document class at that one site for
80
81
  * exactly this reason — the body is JSON and the wire should say so.
81
82
  */
82
- import { matchesMagic, MIN_MAGIC_BYTES } from '@neuralis/package-system/web-common';
83
+ import { inferMimeTypeFromFilename, matchesMagic, MIN_MAGIC_BYTES } from '@neuralis/package-system/web-common';
83
84
  import { sanitizeFilename } from './paths.js';
85
+ // The extension tables are the kernel's (`web-common/fileMime.ts`) — agent-core's device connector reads them too.
86
+ export { binaryMimeTypeForPath, inferMimeTypeFromFilename } from '@neuralis/package-system/web-common';
84
87
  /** Longest mime essence we will echo; anything longer is treated as garbage. */
85
88
  const MAX_MIME_ESSENCE_LENGTH = 255;
86
89
  /** `type/subtype` in RFC 9110 token characters, nothing else. */
@@ -89,51 +92,6 @@ export function looksTextByMime(mimeType) {
89
92
  const mime = String(mimeType || '').toLowerCase();
90
93
  return mime.startsWith('text/') || mime === 'application/json' || mime.endsWith('+json');
91
94
  }
92
- /**
93
- * Extension → mime, for files whose stored metadata carries no type.
94
- *
95
- * The five document extensions at the end are NOT decoration: they make the
96
- * extension agree with `classifyResponseMime`'s active-document set, so an
97
- * `.html` or `.xml` file reports what it is instead of `application/octet-stream`
98
- * and is classified on its merits. Both land on `attachment` either way — this
99
- * only removes a lie from the wire.
100
- */
101
- export function inferMimeTypeFromFilename(filename) {
102
- const lower = filename.toLowerCase();
103
- if (lower.endsWith('.png'))
104
- return 'image/png';
105
- if (lower.endsWith('.jpg') || lower.endsWith('.jpeg'))
106
- return 'image/jpeg';
107
- if (lower.endsWith('.webp'))
108
- return 'image/webp';
109
- if (lower.endsWith('.gif'))
110
- return 'image/gif';
111
- if (lower.endsWith('.svg'))
112
- return 'image/svg+xml';
113
- if (lower.endsWith('.mp4'))
114
- return 'video/mp4';
115
- if (lower.endsWith('.webm'))
116
- return 'video/webm';
117
- if (lower.endsWith('.mp3'))
118
- return 'audio/mpeg';
119
- if (lower.endsWith('.wav'))
120
- return 'audio/wav';
121
- if (lower.endsWith('.json'))
122
- return 'application/json; charset=utf-8';
123
- if (lower.endsWith('.md'))
124
- return 'text/markdown; charset=utf-8';
125
- if (lower.endsWith('.txt'))
126
- return 'text/plain; charset=utf-8';
127
- if (lower.endsWith('.html') || lower.endsWith('.htm'))
128
- return 'text/html; charset=utf-8';
129
- if (lower.endsWith('.xhtml'))
130
- return 'application/xhtml+xml';
131
- if (lower.endsWith('.xml'))
132
- return 'text/xml; charset=utf-8';
133
- if (lower.endsWith('.xsl') || lower.endsWith('.xslt'))
134
- return 'application/xslt+xml';
135
- return 'application/octet-stream';
136
- }
137
95
  /**
138
96
  * Lowercase `type/subtype`, parameters dropped, syntactically validated.
139
97
  * Returns `null` for anything absent, over-long or not token-shaped — the
@@ -252,9 +210,10 @@ export function buildRawResponseHeaders(input) {
252
210
  *
253
211
  * **SCOPE, measured live — the magic-byte check governs the STORED value, and
254
212
  * on a non-brain source it does NOT reach the wire.** `loadRawBytes` returns
255
- * `result.mimeType || mimeType` for `sourceKind !== 'brain'`, so the local
256
- * connector's own extension-derived type wins over the persisted metadata at
257
- * serve time. HTML bytes stored as `application/octet-stream` under the name
213
+ * the connector's type for `sourceKind !== 'brain'` whenever the connector can
214
+ * tell (anything but `application/octet-stream`, the contract's "cannot
215
+ * tell"), so the local connector's own extension-derived type wins over the
216
+ * persisted metadata at serve time. HTML bytes stored as `application/octet-stream` under the name
258
217
  * `x.png` are therefore SERVED `image/png`. That is bounded and not a hole: the
259
218
  * classification still runs on the extension, so `.svg`/`.html`/`.xml` stay
260
219
  * `attachment`, and a mislabelled raster is inert under the globally-present
@@ -300,52 +259,4 @@ export function normalizeNodeMetadataMime(metadata, filename) {
300
259
  bag.mimeType = normalizeStoredMimeType(typeof bag.mimeType === 'string' ? bag.mimeType : undefined, filename);
301
260
  return bag;
302
261
  }
303
- const BINARY_READ_MIME_BY_EXTENSION = new Map([
304
- ['.wasm', 'application/wasm'],
305
- ['.png', 'image/png'],
306
- ['.jpg', 'image/jpeg'],
307
- ['.jpeg', 'image/jpeg'],
308
- ['.gif', 'image/gif'],
309
- ['.webp', 'image/webp'],
310
- ['.ico', 'image/x-icon'],
311
- ['.bmp', 'image/bmp'],
312
- ['.mp4', 'video/mp4'],
313
- ['.webm', 'video/webm'],
314
- ['.avi', 'video/x-msvideo'],
315
- ['.mov', 'video/quicktime'],
316
- ['.mkv', 'video/x-matroska'],
317
- ['.mp3', 'audio/mpeg'],
318
- ['.wav', 'audio/wav'],
319
- ['.ogg', 'audio/ogg'],
320
- ['.flac', 'audio/flac'],
321
- ['.aac', 'audio/aac'],
322
- ['.m4a', 'audio/mp4'],
323
- ['.zip', 'application/zip'],
324
- ['.tar', 'application/x-tar'],
325
- ['.gz', 'application/gzip'],
326
- ['.bz2', 'application/x-bzip2'],
327
- ['.7z', 'application/x-7z-compressed'],
328
- ['.rar', 'application/vnd.rar'],
329
- ['.pdf', 'application/pdf'],
330
- ['.doc', 'application/msword'],
331
- ['.docx', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'],
332
- ['.xls', 'application/vnd.ms-excel'],
333
- ['.xlsx', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'],
334
- ['.ppt', 'application/vnd.ms-powerpoint'],
335
- ['.pptx', 'application/vnd.openxmlformats-officedocument.presentationml.presentation'],
336
- ['.exe', 'application/octet-stream'],
337
- ['.dll', 'application/octet-stream'],
338
- ['.so', 'application/octet-stream'],
339
- ['.dylib', 'application/octet-stream'],
340
- ['.ttf', 'font/ttf'],
341
- ['.otf', 'font/otf'],
342
- ['.woff', 'font/woff'],
343
- ['.woff2', 'font/woff2'],
344
- ['.eot', 'application/vnd.ms-fontobject'],
345
- ]);
346
- export function binaryMimeTypeForPath(filePath) {
347
- const name = filePath.slice(filePath.lastIndexOf('/') + 1);
348
- const dot = name.lastIndexOf('.');
349
- return dot > 0 ? BINARY_READ_MIME_BY_EXTENSION.get(name.slice(dot).toLowerCase()) : undefined;
350
- }
351
262
  //# sourceMappingURL=mime.js.map