@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.
Files changed (371) hide show
  1. package/README.md +88 -1417
  2. package/app/README.md +4 -4
  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 +24 -2
  8. package/app/filesystem/README.md +1 -1
  9. package/app/filesystem/api/README.md +3 -3
  10. package/app/filesystem/api/index.ts +38 -14
  11. package/app/filesystem/api/projectPackages.ts +13 -102
  12. package/app/filesystem/domain/types.ts +30 -10
  13. package/app/filesystem/hooks/README.md +4 -4
  14. package/app/filesystem/hooks/useDiscoverableSources.ts +19 -30
  15. package/app/filesystem/hooks/useFilesystemSSE.ts +42 -2
  16. package/app/filesystem/host/README.md +6 -4
  17. package/app/filesystem/host/buildFilesystemHostValue.ts +28 -2
  18. package/app/filesystem/host/installFilesystemHostComponents.tsx +1 -1
  19. package/app/filesystem/lib/sourceKindForm.ts +210 -27
  20. package/app/filesystem/lib/treeVisualState.tsx +98 -4
  21. package/app/filesystem/store/README.md +1 -0
  22. package/app/filesystem/store/filesystemStore.ts +99 -8
  23. package/app/filesystem/store/gitSlice.ts +5 -0
  24. package/app/filesystem/store/helpers.ts +17 -0
  25. package/app/filesystem/store/listSlice.ts +8 -0
  26. package/app/filesystem/ui/CodeEditor.tsx +18 -3
  27. package/app/filesystem/ui/DiscoverDock.tsx +5 -1
  28. package/app/filesystem/ui/FileEditor.tsx +15 -10
  29. package/app/filesystem/ui/FileTree.tsx +75 -24
  30. package/app/filesystem/ui/FilesystemWidget.tsx +10 -2
  31. package/app/filesystem/ui/FolderPicker.tsx +251 -0
  32. package/app/filesystem/ui/GitControlPanel.tsx +7 -2
  33. package/app/filesystem/ui/PackagesPanel.tsx +52 -374
  34. package/app/filesystem/ui/PendingChangesPanel.tsx +1 -1
  35. package/app/filesystem/ui/PolicyEditor.tsx +109 -24
  36. package/app/filesystem/ui/README.md +30 -23
  37. package/app/filesystem/ui/RawMediaPreview.tsx +58 -0
  38. package/app/filesystem/ui/SourceBranchHeader.tsx +4 -4
  39. package/app/filesystem/ui/SourcesPanel.tsx +502 -342
  40. package/app/filesystem/ui/Toolbar.tsx +1 -2
  41. package/app/filesystem/ui/VectorHealthPanel.tsx +2 -2
  42. package/app/shared/filesystem.png +0 -0
  43. package/dist/app/host.js +58 -46
  44. package/dist/scripts/sourceRootPairV1.d.ts +47 -0
  45. package/dist/scripts/sourceRootPairV1.d.ts.map +1 -0
  46. package/dist/scripts/sourceRootPairV1.js +147 -0
  47. package/dist/scripts/sourceRootPairV1.js.map +1 -0
  48. package/dist/scripts/sourceToFolderV1.d.ts +56 -0
  49. package/dist/scripts/sourceToFolderV1.d.ts.map +1 -0
  50. package/dist/scripts/sourceToFolderV1.js +152 -0
  51. package/dist/scripts/sourceToFolderV1.js.map +1 -0
  52. package/dist/scripts/sourceToHostV1.d.ts +56 -0
  53. package/dist/scripts/sourceToHostV1.d.ts.map +1 -0
  54. package/dist/scripts/sourceToHostV1.js +132 -0
  55. package/dist/scripts/sourceToHostV1.js.map +1 -0
  56. package/dist/src/channels/filesystem.d.ts +1 -1
  57. package/dist/src/channels/filesystem.js +1 -1
  58. package/dist/src/connectors/AppSourceConfigStore.d.ts +17 -3
  59. package/dist/src/connectors/AppSourceConfigStore.d.ts.map +1 -1
  60. package/dist/src/connectors/AppSourceConfigStore.js +46 -6
  61. package/dist/src/connectors/AppSourceConfigStore.js.map +1 -1
  62. package/dist/src/connectors/HostConnector.d.ts +201 -0
  63. package/dist/src/connectors/HostConnector.d.ts.map +1 -0
  64. package/dist/src/connectors/HostConnector.js +903 -0
  65. package/dist/src/connectors/HostConnector.js.map +1 -0
  66. package/dist/src/connectors/inProcessTransport.d.ts +131 -0
  67. package/dist/src/connectors/inProcessTransport.d.ts.map +1 -0
  68. package/dist/src/connectors/inProcessTransport.js +447 -0
  69. package/dist/src/connectors/inProcessTransport.js.map +1 -0
  70. package/dist/src/domain/access/callerPermissions.d.ts +29 -0
  71. package/dist/src/domain/access/callerPermissions.d.ts.map +1 -1
  72. package/dist/src/domain/access/callerPermissions.js +85 -5
  73. package/dist/src/domain/access/callerPermissions.js.map +1 -1
  74. package/dist/src/domain/access/nativeLocalFence.d.ts +65 -0
  75. package/dist/src/domain/access/nativeLocalFence.d.ts.map +1 -0
  76. package/dist/src/domain/access/nativeLocalFence.js +171 -0
  77. package/dist/src/domain/access/nativeLocalFence.js.map +1 -0
  78. package/dist/src/domain/access/uriPermission.js +3 -3
  79. package/dist/src/domain/access/uriPermission.js.map +1 -1
  80. package/dist/src/domain/byteRange.d.ts +15 -0
  81. package/dist/src/domain/byteRange.d.ts.map +1 -0
  82. package/dist/src/domain/byteRange.js +30 -0
  83. package/dist/src/domain/byteRange.js.map +1 -0
  84. package/dist/src/domain/defaultPermissions.d.ts.map +1 -1
  85. package/dist/src/domain/defaultPermissions.js +29 -0
  86. package/dist/src/domain/defaultPermissions.js.map +1 -1
  87. package/dist/src/domain/mime.d.ts +11 -19
  88. package/dist/src/domain/mime.d.ts.map +1 -1
  89. package/dist/src/domain/mime.js +13 -102
  90. package/dist/src/domain/mime.js.map +1 -1
  91. package/dist/src/domain/paths.d.ts.map +1 -1
  92. package/dist/src/domain/paths.js +5 -3
  93. package/dist/src/domain/paths.js.map +1 -1
  94. package/dist/src/domain/scopeAccessCtx.d.ts +2 -2
  95. package/dist/src/domain/scopeAccessCtx.js +2 -2
  96. package/dist/src/domain/sourceConfig.d.ts +52 -19
  97. package/dist/src/domain/sourceConfig.d.ts.map +1 -1
  98. package/dist/src/domain/sourceConfig.js +103 -19
  99. package/dist/src/domain/sourceConfig.js.map +1 -1
  100. package/dist/src/domain/sourcePackages.d.ts +8 -8
  101. package/dist/src/domain/sourcePackages.d.ts.map +1 -1
  102. package/dist/src/domain/sourceRootPair.d.ts +88 -0
  103. package/dist/src/domain/sourceRootPair.d.ts.map +1 -0
  104. package/dist/src/domain/sourceRootPair.js +108 -0
  105. package/dist/src/domain/sourceRootPair.js.map +1 -0
  106. package/dist/src/domain/syncTypes.d.ts +8 -1
  107. package/dist/src/domain/syncTypes.d.ts.map +1 -1
  108. package/dist/src/domain/syncTypes.js +1 -0
  109. package/dist/src/domain/syncTypes.js.map +1 -1
  110. package/dist/src/domain/types.d.ts +32 -2
  111. package/dist/src/domain/types.d.ts.map +1 -1
  112. package/dist/src/domain/uri.d.ts.map +1 -1
  113. package/dist/src/domain/uri.js +3 -2
  114. package/dist/src/domain/uri.js.map +1 -1
  115. package/dist/src/embeddings/clients/GeminiEmbedder.d.ts.map +1 -1
  116. package/dist/src/embeddings/clients/GeminiEmbedder.js +2 -5
  117. package/dist/src/embeddings/clients/GeminiEmbedder.js.map +1 -1
  118. package/dist/src/embeddings/clients/OpenAIEmbedder.d.ts.map +1 -1
  119. package/dist/src/embeddings/clients/OpenAIEmbedder.js +2 -3
  120. package/dist/src/embeddings/clients/OpenAIEmbedder.js.map +1 -1
  121. package/dist/src/embeddings/clients/QwenEmbedder.d.ts +2 -0
  122. package/dist/src/embeddings/clients/QwenEmbedder.d.ts.map +1 -1
  123. package/dist/src/embeddings/clients/QwenEmbedder.js +10 -2
  124. package/dist/src/embeddings/clients/QwenEmbedder.js.map +1 -1
  125. package/dist/src/embeddings/clients/VoyageEmbedder.d.ts +2 -0
  126. package/dist/src/embeddings/clients/VoyageEmbedder.d.ts.map +1 -1
  127. package/dist/src/embeddings/clients/VoyageEmbedder.js +8 -1
  128. package/dist/src/embeddings/clients/VoyageEmbedder.js.map +1 -1
  129. package/dist/src/embeddings/factory.d.ts +5 -3
  130. package/dist/src/embeddings/factory.d.ts.map +1 -1
  131. package/dist/src/embeddings/factory.js +7 -3
  132. package/dist/src/embeddings/factory.js.map +1 -1
  133. package/dist/src/embeddings/models.d.ts +1 -1
  134. package/dist/src/embeddings/models.d.ts.map +1 -1
  135. package/dist/src/embeddings/retry.js +1 -1
  136. package/dist/src/embeddings/retry.js.map +1 -1
  137. package/dist/src/embeddings/types.d.ts +6 -0
  138. package/dist/src/embeddings/types.d.ts.map +1 -1
  139. package/dist/src/embeddings/types.js +11 -0
  140. package/dist/src/embeddings/types.js.map +1 -1
  141. package/dist/src/events/pending.d.ts +1 -1
  142. package/dist/src/events/pending.js +1 -1
  143. package/dist/src/git/GitRunner.d.ts +110 -30
  144. package/dist/src/git/GitRunner.d.ts.map +1 -1
  145. package/dist/src/git/GitRunner.js +511 -199
  146. package/dist/src/git/GitRunner.js.map +1 -1
  147. package/dist/src/git/GitWatchRegistry.d.ts +41 -35
  148. package/dist/src/git/GitWatchRegistry.d.ts.map +1 -1
  149. package/dist/src/git/GitWatchRegistry.js +61 -79
  150. package/dist/src/git/GitWatchRegistry.js.map +1 -1
  151. package/dist/src/git/gitPlace.d.ts +61 -0
  152. package/dist/src/git/gitPlace.d.ts.map +1 -0
  153. package/dist/src/git/gitPlace.js +74 -0
  154. package/dist/src/git/gitPlace.js.map +1 -0
  155. package/dist/src/git/sourceGitControl.d.ts +33 -21
  156. package/dist/src/git/sourceGitControl.d.ts.map +1 -1
  157. package/dist/src/git/sourceGitControl.js +211 -95
  158. package/dist/src/git/sourceGitControl.js.map +1 -1
  159. package/dist/src/git/sourceGitStatus.js +1 -1
  160. package/dist/src/git/sourceGitStatus.js.map +1 -1
  161. package/dist/src/git/untrackedStats.js +1 -1
  162. package/dist/src/git/untrackedStats.js.map +1 -1
  163. package/dist/src/index.d.ts +2 -1
  164. package/dist/src/index.d.ts.map +1 -1
  165. package/dist/src/index.js +2 -1
  166. package/dist/src/index.js.map +1 -1
  167. package/dist/src/lifecycle.d.ts +9 -12
  168. package/dist/src/lifecycle.d.ts.map +1 -1
  169. package/dist/src/lifecycle.js +2 -1
  170. package/dist/src/lifecycle.js.map +1 -1
  171. package/dist/src/routes/approve.d.ts +1 -1
  172. package/dist/src/routes/approve.js +1 -1
  173. package/dist/src/routes/events.d.ts +1 -1
  174. package/dist/src/routes/events.js +1 -1
  175. package/dist/src/routes/git.d.ts +7 -7
  176. package/dist/src/routes/git.d.ts.map +1 -1
  177. package/dist/src/routes/git.js +201 -72
  178. package/dist/src/routes/git.js.map +1 -1
  179. package/dist/src/routes/health.d.ts +6 -6
  180. package/dist/src/routes/health.js +12 -12
  181. package/dist/src/routes/helpers/sourceNotConfigured.d.ts +1 -1
  182. package/dist/src/routes/helpers/sourceNotConfigured.js +1 -1
  183. package/dist/src/routes/helpers/uriGuard.d.ts +1 -1
  184. package/dist/src/routes/helpers/uriGuard.d.ts.map +1 -1
  185. package/dist/src/routes/helpers/uriGuard.js +3 -2
  186. package/dist/src/routes/helpers/uriGuard.js.map +1 -1
  187. package/dist/src/routes/helpers.d.ts +11 -4
  188. package/dist/src/routes/helpers.d.ts.map +1 -1
  189. package/dist/src/routes/helpers.js +13 -6
  190. package/dist/src/routes/helpers.js.map +1 -1
  191. package/dist/src/routes/list.d.ts +1 -1
  192. package/dist/src/routes/list.d.ts.map +1 -1
  193. package/dist/src/routes/list.js +3 -4
  194. package/dist/src/routes/list.js.map +1 -1
  195. package/dist/src/routes/pending.d.ts +4 -4
  196. package/dist/src/routes/pending.js +9 -9
  197. package/dist/src/routes/policies.d.ts +10 -8
  198. package/dist/src/routes/policies.d.ts.map +1 -1
  199. package/dist/src/routes/policies.js +31 -25
  200. package/dist/src/routes/policies.js.map +1 -1
  201. package/dist/src/routes/raw.d.ts +1 -1
  202. package/dist/src/routes/raw.d.ts.map +1 -1
  203. package/dist/src/routes/raw.js +66 -12
  204. package/dist/src/routes/raw.js.map +1 -1
  205. package/dist/src/routes/read.d.ts +1 -1
  206. package/dist/src/routes/read.js +1 -1
  207. package/dist/src/routes/search.d.ts +1 -1
  208. package/dist/src/routes/search.js +1 -1
  209. package/dist/src/routes/sources.d.ts +63 -6
  210. package/dist/src/routes/sources.d.ts.map +1 -1
  211. package/dist/src/routes/sources.js +494 -382
  212. package/dist/src/routes/sources.js.map +1 -1
  213. package/dist/src/routes/upload.d.ts +1 -1
  214. package/dist/src/routes/upload.js +1 -1
  215. package/dist/src/routes/write.d.ts +2 -2
  216. package/dist/src/routes/write.js +2 -2
  217. package/dist/src/services/BridgeService.d.ts +21 -35
  218. package/dist/src/services/BridgeService.d.ts.map +1 -1
  219. package/dist/src/services/BridgeService.js +42 -88
  220. package/dist/src/services/BridgeService.js.map +1 -1
  221. package/dist/src/services/FilesystemService.d.ts +4 -3
  222. package/dist/src/services/FilesystemService.d.ts.map +1 -1
  223. package/dist/src/services/FilesystemService.js +112 -34
  224. package/dist/src/services/FilesystemService.js.map +1 -1
  225. package/dist/src/services/FilesystemUiService.d.ts +4 -1
  226. package/dist/src/services/FilesystemUiService.d.ts.map +1 -1
  227. package/dist/src/services/FilesystemUiService.js +66 -25
  228. package/dist/src/services/FilesystemUiService.js.map +1 -1
  229. package/dist/src/services/SyncScheduler.d.ts +12 -4
  230. package/dist/src/services/SyncScheduler.d.ts.map +1 -1
  231. package/dist/src/services/SyncScheduler.js +37 -8
  232. package/dist/src/services/SyncScheduler.js.map +1 -1
  233. package/dist/src/services/baselineRepair.d.ts +13 -3
  234. package/dist/src/services/baselineRepair.d.ts.map +1 -1
  235. package/dist/src/services/baselineRepair.js +13 -3
  236. package/dist/src/services/baselineRepair.js.map +1 -1
  237. package/dist/src/services/declaredSources.d.ts +132 -43
  238. package/dist/src/services/declaredSources.d.ts.map +1 -1
  239. package/dist/src/services/declaredSources.js +118 -45
  240. package/dist/src/services/declaredSources.js.map +1 -1
  241. package/dist/src/store/dataFormats.d.ts +17 -2
  242. package/dist/src/store/dataFormats.d.ts.map +1 -1
  243. package/dist/src/store/dataFormats.js +18 -3
  244. package/dist/src/store/dataFormats.js.map +1 -1
  245. package/dist/src/sync/DeltaSyncRunner.d.ts.map +1 -1
  246. package/dist/src/sync/DeltaSyncRunner.js +144 -4
  247. package/dist/src/sync/DeltaSyncRunner.js.map +1 -1
  248. package/dist/src/sync/SyncJobQueue.d.ts +7 -2
  249. package/dist/src/sync/SyncJobQueue.d.ts.map +1 -1
  250. package/dist/src/sync/SyncJobQueue.js +16 -10
  251. package/dist/src/sync/SyncJobQueue.js.map +1 -1
  252. package/dist/src/sync/SyncWatchService.d.ts +21 -4
  253. package/dist/src/sync/SyncWatchService.d.ts.map +1 -1
  254. package/dist/src/sync/SyncWatchService.js +115 -10
  255. package/dist/src/sync/SyncWatchService.js.map +1 -1
  256. package/dist/src/sync/categoryInference.d.ts +1 -1
  257. package/dist/src/sync/categoryInference.js +1 -1
  258. package/dist/src/tools/execCtx.d.ts +2 -2
  259. package/dist/src/tools/execCtx.js +2 -2
  260. package/dist/src/tools/fs_read.d.ts.map +1 -1
  261. package/dist/src/tools/fs_read.js +5 -0
  262. package/dist/src/tools/fs_read.js.map +1 -1
  263. package/dist/src/usecases/admitSourceRoot.d.ts +65 -0
  264. package/dist/src/usecases/admitSourceRoot.d.ts.map +1 -0
  265. package/dist/src/usecases/admitSourceRoot.js +85 -0
  266. package/dist/src/usecases/admitSourceRoot.js.map +1 -0
  267. package/dist/src/usecases/browseSourceFolders.d.ts +85 -0
  268. package/dist/src/usecases/browseSourceFolders.d.ts.map +1 -0
  269. package/dist/src/usecases/browseSourceFolders.js +210 -0
  270. package/dist/src/usecases/browseSourceFolders.js.map +1 -0
  271. package/dist/src/usecases/createDeclaredSources.d.ts +13 -2
  272. package/dist/src/usecases/createDeclaredSources.d.ts.map +1 -1
  273. package/dist/src/usecases/createDeclaredSources.js +39 -0
  274. package/dist/src/usecases/createDeclaredSources.js.map +1 -1
  275. package/dist/src/usecases/embeddingBacklog.js +1 -1
  276. package/dist/src/usecases/embeddingBacklog.js.map +1 -1
  277. package/dist/src/usecases/list.d.ts.map +1 -1
  278. package/dist/src/usecases/list.js +83 -26
  279. package/dist/src/usecases/list.js.map +1 -1
  280. package/dist/src/usecases/listAttachableDevices.d.ts +13 -0
  281. package/dist/src/usecases/listAttachableDevices.d.ts.map +1 -0
  282. package/dist/src/usecases/listAttachableDevices.js +10 -0
  283. package/dist/src/usecases/listAttachableDevices.js.map +1 -0
  284. package/dist/src/usecases/listSourcePackages.d.ts.map +1 -1
  285. package/dist/src/usecases/listSourcePackages.js +2 -5
  286. package/dist/src/usecases/listSourcePackages.js.map +1 -1
  287. package/dist/src/usecases/purgeExcludedPoints.d.ts.map +1 -1
  288. package/dist/src/usecases/purgeExcludedPoints.js +3 -2
  289. package/dist/src/usecases/purgeExcludedPoints.js.map +1 -1
  290. package/dist/src/usecases/readFiles.d.ts.map +1 -1
  291. package/dist/src/usecases/readFiles.js +99 -1
  292. package/dist/src/usecases/readFiles.js.map +1 -1
  293. package/dist/src/usecases/reconcileSourcePackageRoots.d.ts +1 -1
  294. package/dist/src/usecases/reconcileSourcePackageRoots.d.ts.map +1 -1
  295. package/dist/src/usecases/reconcileSourcePackageRoots.js +2 -1
  296. package/dist/src/usecases/reconcileSourcePackageRoots.js.map +1 -1
  297. package/dist/src/usecases/revokePrincipal.d.ts +7 -5
  298. package/dist/src/usecases/revokePrincipal.d.ts.map +1 -1
  299. package/dist/src/usecases/revokePrincipal.js +29 -7
  300. package/dist/src/usecases/revokePrincipal.js.map +1 -1
  301. package/dist/src/usecases/scheduleSourceSync.d.ts +7 -0
  302. package/dist/src/usecases/scheduleSourceSync.d.ts.map +1 -1
  303. package/dist/src/usecases/scheduleSourceSync.js +6 -5
  304. package/dist/src/usecases/scheduleSourceSync.js.map +1 -1
  305. package/dist/src/usecases/syncPointWrites.d.ts +2 -0
  306. package/dist/src/usecases/syncPointWrites.d.ts.map +1 -1
  307. package/dist/src/usecases/syncPointWrites.js +5 -1
  308. package/dist/src/usecases/syncPointWrites.js.map +1 -1
  309. package/dist/src/usecases/triggerSourceSync.d.ts +46 -0
  310. package/dist/src/usecases/triggerSourceSync.d.ts.map +1 -0
  311. package/dist/src/usecases/triggerSourceSync.js +75 -0
  312. package/dist/src/usecases/triggerSourceSync.js.map +1 -0
  313. package/dist/src/usecases/uploadBinary.d.ts +2 -1
  314. package/dist/src/usecases/uploadBinary.d.ts.map +1 -1
  315. package/dist/src/usecases/uploadBinary.js +2 -2
  316. package/dist/src/usecases/uploadBinary.js.map +1 -1
  317. package/dist/src/usecases/vector/endpointGuard.d.ts +1 -1
  318. package/dist/src/usecases/vector/endpointGuard.js +1 -1
  319. package/dist/src/usecases/vectorMaintenance.js +1 -1
  320. package/dist/src/usecases/vectorMaintenance.js.map +1 -1
  321. package/dist/src/usecases/write/content.js +1 -1
  322. package/dist/src/vector/qdrantClient.d.ts +1 -1
  323. package/dist/src/vector/qdrantClient.js +1 -1
  324. package/dist/src/wiring.d.ts +3 -0
  325. package/dist/src/wiring.d.ts.map +1 -1
  326. package/dist/src/wiring.js +72 -6
  327. package/dist/src/wiring.js.map +1 -1
  328. package/dist/tools/fs_list.json +1 -1
  329. package/dist/tools/fs_read.json +1 -1
  330. package/dist/tools/fs_search.json +1 -1
  331. package/dist/tools/fs_write.json +1 -1
  332. package/instructions/brain-model.md +1 -1
  333. package/package.json +212 -114
  334. package/rules/brain-rules.md +2 -2
  335. package/skills/brain-start/SKILL.md +1 -1
  336. package/skills/connect-business-data/SKILL.md +3 -3
  337. package/skills/create-package/SKILL.md +26 -26
  338. package/skills/create-package/references/config-and-credentials.md +16 -13
  339. package/skills/create-package/references/connectors-and-uri-policies.md +39 -25
  340. package/skills/create-package/references/manifest-and-discovery.md +12 -12
  341. package/skills/create-package/references/runtime-and-build.md +19 -19
  342. package/skills/create-package/references/skills-and-context.md +36 -20
  343. package/skills/create-package/references/surfaces-and-design.md +16 -16
  344. package/skills/create-package/references/team-and-workflows.md +2 -2
  345. package/skills/create-package/references/test-and-ship.md +21 -21
  346. package/skills/create-package/references/tools-and-schemas.md +5 -5
  347. package/skills/create-package/scripts/{check-package.sh → check-package.mjs} +79 -65
  348. package/skills/create-package/scripts/{verify-loaded.sh → verify-loaded.mjs} +156 -162
  349. package/skills/git/SKILL.md +53 -51
  350. package/skills/manage-files/SKILL.md +22 -25
  351. package/skills/manage-sources/SKILL.md +128 -87
  352. package/skills/manage-uri-policy/SKILL.md +18 -15
  353. package/skills/organize/SKILL.md +1 -1
  354. package/skills/sync/SKILL.md +3 -3
  355. package/tools/fs_list.json +1 -1
  356. package/tools/fs_read.json +1 -1
  357. package/tools/fs_search.json +1 -1
  358. package/tools/fs_write.json +1 -1
  359. package/workflows/sources-digest.json +1 -1
  360. package/dist/src/connectors/LocalDiskConnector.d.ts +0 -171
  361. package/dist/src/connectors/LocalDiskConnector.d.ts.map +0 -1
  362. package/dist/src/connectors/LocalDiskConnector.js +0 -1233
  363. package/dist/src/connectors/LocalDiskConnector.js.map +0 -1
  364. package/docs/drive-overview.md +0 -59
  365. package/skills/manage-files/scripts/copy.sh +0 -7
  366. package/skills/manage-files/scripts/create.sh +0 -7
  367. package/skills/manage-files/scripts/mkdir.sh +0 -7
  368. package/skills/manage-files/scripts/modify.sh +0 -7
  369. package/skills/manage-files/scripts/upload.sh +0 -16
  370. package/skills/manage-files/scripts/write.sh +0 -29
  371. package/skills/manage-sources/scripts/reembed.sh +0 -23
@@ -1,84 +1,94 @@
1
- #!/usr/bin/env bash
2
- #
3
- # create-package/verify-loaded.sh — runtime proof that a package actually loaded.
4
- #
5
- # "It built clean" is not "it loaded". A package can compile, install, appear on
6
- # disk, and still register NOTHING — one bad tool schema aborts the whole load,
7
- # a missing build makes it declarative-only, an untrusted node runtime leaves
8
- # every handler returning an error. This script asks the platform, and reports
9
- # only what the platform said.
10
- #
11
- # WHAT IT CHECKS
12
- # Reads the agent-core package diagnostics and overview surfaces as YOU through
13
- # `neuralis request` (the session ticket inside an activated skill, your
14
- # `neuralis login` on your own machine), and reports one of:
15
- # loaded — registered and operational
16
- # partial — declarative contributions registered, no code runtime; prints
17
- # the reason (build-missing | runtime-unavailable |
18
- # untrusted-node | untrusted-mcp)
19
- # error — validation or init crash; prints the recorded message
20
- # missing — installed but never reached the loader (manifest read failed)
21
- # absent — the platform does not list it for you at all; the verdict then
22
- # prints every installed AND source package id it DOES list, so
23
- # you can find the right one without guessing
24
- # On a clean load it also prints the surface the platform registered FOR YOU:
25
- # tools, skills, instructions, rules, agents, docs, commands, workflows,
26
- # connectors, hooks, policies, app surfaces, team members, active file count.
27
- # The `connectors` row counts DECLARATIONS the loader accepted from the
28
- # manifest — not live outbound instances. An outbound (mcp/openapi/http)
29
- # connector is registered into ONE tenant, and into NO tenant at all when the
30
- # package is neither first-party nor owned by a resolvable project, so this
31
- # count can be non-zero while the connector exists nowhere.
32
- # A source package (markdown discovered in an indexed source) has no loader
33
- # status at all — it is reported separately, with its recognition reason.
34
- #
35
- # WHAT IT CANNOT CHECK
36
- # That a surface WORKS. A loaded package with a broken handler still says
37
- # `loaded`. Run the tool, open the widget, call the route — as the LEAST
38
- # privileged role that is supposed to have access, because feature-gated
39
- # contributions are hidden, so testing as the owner hides every gate bug.
40
- # It also cannot see what your identity may not see: these surfaces are
41
- # scoped, so `absent` can mean "correctly hidden from you", not "broken".
42
- # For a source package `absent` also covers "the files exist on disk but no
43
- # sync has indexed them yet" — discovery reads the index, never the live tree.
44
- # For the static half run, before you install:
45
- # bash "${SKILL_DIR}/scripts/check-package.sh" <package-root>
46
- #
47
- # USAGE bash verify-loaded.sh <package-id> [--raw]
48
- # <package-id> the manifest id, e.g. "@acme/reports" or "reports".
49
- # A drop or source package: its instance URI, quoted.
50
- # --raw dump both untouched JSON responses before the verdict,
51
- # so you can self-diagnose if the shape ever drifts.
52
- # EXIT 0 = loaded
53
- # 1 = partial (reason printed)
54
- # 2 = absent — not listed for this caller
55
- # 3 = error / missing (recorded message printed)
56
- # 4 = could not reach the diagnostics surface (no `neuralis` CLI or login, no
57
- # network, HTTP failure, or the caller lacks the `core.observe`
58
- # feature). NOTHING is claimed about the package in this state.
59
- #
60
- # This script never accepts, prints or persists a token.
61
- #
62
- # Testing reference: https://docs.neuralisapp.com/package-system/testing
1
+ //
2
+ // create-package/verify-loaded.mjs — runtime proof that a package actually loaded.
3
+ //
4
+ // "It built clean" is not "it loaded". A package can compile, install, appear on
5
+ // disk, and still register NOTHING — one bad tool schema aborts the whole load,
6
+ // a missing build makes it declarative-only, an untrusted node runtime leaves
7
+ // every handler returning an error. This script asks the platform, and reports
8
+ // only what the platform said.
9
+ //
10
+ // WHAT IT CHECKS
11
+ // Reads the agent-core package diagnostics and overview surfaces as YOU through
12
+ // `neuralis request` (the session ticket inside an activated skill, your
13
+ // `neuralis login` on your own machine), and reports one of:
14
+ // loaded — registered and operational
15
+ // partial — declarative contributions registered, no code runtime; prints
16
+ // the reason (build-missing | runtime-unavailable |
17
+ // untrusted-node | untrusted-mcp)
18
+ // error — validation or init crash; prints the recorded message
19
+ // missing — installed but never reached the loader (manifest read failed)
20
+ // absent — the platform does not list it for you at all; the verdict then
21
+ // prints every installed AND source package id it DOES list, so
22
+ // you can find the right one without guessing
23
+ // On a clean load it also prints the surface the platform registered FOR YOU:
24
+ // tools, skills, instructions, rules, agents, docs, commands, workflows,
25
+ // connectors, hooks, policies, app surfaces, team members, active file count.
26
+ // The `connectors` row counts DECLARATIONS the loader accepted from the
27
+ // manifest — not live outbound instances. An outbound (mcp/openapi/http)
28
+ // connector is registered into ONE tenant, and into NO tenant at all when the
29
+ // package is neither native nor owned by a resolvable project, so this
30
+ // count can be non-zero while the connector exists nowhere.
31
+ // A source package (markdown discovered in an indexed source) has no loader
32
+ // status at all — it is reported separately, with its recognition reason.
33
+ //
34
+ // WHAT IT CANNOT CHECK
35
+ // That a surface WORKS. A loaded package with a broken handler still says
36
+ // `loaded`. Run the tool, open the widget, call the route — as the LEAST
37
+ // privileged role that is supposed to have access, because feature-gated
38
+ // contributions are hidden, so testing as the owner hides every gate bug.
39
+ // It also cannot see what your identity may not see: these surfaces are
40
+ // scoped, so `absent` can mean "correctly hidden from you", not "broken".
41
+ // For a source package `absent` also covers "the files exist on disk but no
42
+ // sync has indexed them yet" — discovery reads the index, never the live tree.
43
+ // For the static half run, before you install:
44
+ // node "${SKILL_DIR}/scripts/check-package.mjs" <package-root>
45
+ //
46
+ // USAGE node verify-loaded.mjs <package-id> [--raw]
47
+ // <package-id> the manifest id, e.g. "@acme/reports" or "reports".
48
+ // A drop or source package: its instance URI, quoted.
49
+ // --raw dump both untouched JSON responses before the verdict,
50
+ // so you can self-diagnose if the shape ever drifts.
51
+ // EXIT 0 = loaded
52
+ // 1 = partial (reason printed)
53
+ // 2 = absent — not listed for this caller
54
+ // 3 = error / missing (recorded message printed)
55
+ // 4 = could not reach the diagnostics surface (no `neuralis` CLI or login, no
56
+ // network, HTTP failure, or the caller lacks the `core.observe`
57
+ // feature). NOTHING is claimed about the package in this state.
58
+ //
59
+ // The CLI runs as `node <NEURALIS_CLI_ENTRY> request …` — the entry every
60
+ // Neuralis runner exports — and never through a shell. With the variable
61
+ // absent, Linux and macOS start `neuralis` from PATH; Windows stops by name.
62
+ //
63
+ // This script never accepts, prints or persists a token.
64
+ //
65
+ // Testing reference: https://docs.neuralisapp.com/package-system/testing
63
66
 
64
- set -euo pipefail
67
+ import { execFileSync } from 'node:child_process';
68
+ import { readFileSync } from 'node:fs';
69
+ import { fileURLToPath } from 'node:url';
65
70
 
66
- RAW=0
67
- PKG_ID=""
68
- for arg in "$@"; do
69
- case "$arg" in
70
- --raw) RAW=1 ;;
71
- -h|--help) sed -n '2,60p' "$0" | sed 's/^#\{0,1\} \{0,1\}//'; exit 0 ;;
72
- -*) echo "unknown flag: $arg" >&2; exit 4 ;;
73
- *) if [ -z "$PKG_ID" ]; then PKG_ID="$arg"; else echo "unexpected argument: $arg" >&2; exit 4; fi ;;
74
- esac
75
- done
76
-
77
- manual_fallback() {
78
- case "$PKG_ID" in
79
- *://*)
80
- cat >&2 <<'SRCFALLBACK'
71
+ const SELF = fileURLToPath(import.meta.url);
72
+ let RAW = false;
73
+ let pkgId = '';
74
+ for (const arg of process.argv.slice(2)) {
75
+ if (arg === '--raw') RAW = true;
76
+ else if (arg === '-h' || arg === '--help') {
77
+ const head = readFileSync(SELF, 'utf8').split('\n');
78
+ const end = head.findIndex((l) => !l.startsWith('//'));
79
+ process.stdout.write(`${head.slice(1, end).map((l) => l.replace(/^\/\/ ?/, '')).join('\n')}\n`);
80
+ process.exit(0);
81
+ } else if (arg.startsWith('-')) {
82
+ process.stderr.write(`unknown flag: ${arg}\n`);
83
+ process.exit(4);
84
+ } else if (!pkgId) pkgId = arg;
85
+ else {
86
+ process.stderr.write(`unexpected argument: ${arg}\n`);
87
+ process.exit(4);
88
+ }
89
+ }
81
90
 
91
+ const SOURCE_FALLBACK = `
82
92
  Cannot verify programmatically. Do NOT record this package as working.
83
93
 
84
94
  A SOURCE package never passes through the loader, so there is NO load line
@@ -99,12 +109,8 @@ Verify a source package this way instead:
99
109
  SKILL.md, a marker dot-dir, or a usable manifest), and inside skills/
100
110
  only a file named SKILL.md counts.
101
111
 
102
- SRCFALLBACK
103
- return
104
- ;;
105
- esac
106
- cat >&2 <<FALLBACK
107
-
112
+ `;
113
+ const LOG_FALLBACK = `
108
114
  Cannot verify programmatically. Do NOT record this package as working.
109
115
  Fall back to the server log — the loader writes one line per package:
110
116
 
@@ -121,85 +127,76 @@ Fall back to the server log — the loader writes one line per package:
121
127
  Search the platform logs for your package id and read which of those five
122
128
  lines names it. No line at all means the loader never saw it: the install
123
129
  did not land, or the manifest could not be read.
124
- FALLBACK
125
- }
126
-
127
- if [ -z "$PKG_ID" ]; then
128
- echo "usage: bash verify-loaded.sh <package-id> [--raw]" >&2
129
- exit 4
130
- fi
131
- if ! command -v neuralis >/dev/null 2>&1; then
132
- echo "ERROR neuralis (the CLI) not found on PATH" >&2
133
- manual_fallback
134
- exit 4
135
- fi
136
- if ! command -v node >/dev/null 2>&1; then
137
- echo "ERROR node not found on PATH — this script parses JSON with node, not jq" >&2
138
- manual_fallback
139
- exit 4
140
- fi
141
- BASE_ROUTE="@neuralis/agent-core/packages"
142
-
143
- WORK="$(mktemp -d)"
144
- trap 'rm -rf "$WORK"' EXIT
130
+ `;
131
+ const manualFallback = () => process.stderr.write(pkgId.includes('://') ? SOURCE_FALLBACK : LOG_FALLBACK);
132
+ const fail = (message) => {
133
+ process.stderr.write(`${message}\n`);
134
+ manualFallback();
135
+ process.exit(4);
136
+ };
145
137
 
146
- # `neuralis request` prints a 2xx body on stdout (exit 0); a non-2xx body goes to
147
- # stderr with an `HTTP <code>` line (exit 1). No such line = no answer
148
- # at all (no CLI login, no network) — "000". Its error text stays in request.err.
149
- fetch() { # fetch <route> <outfile> -> echoes the HTTP status ("000" = no response)
150
- local rc=0 code
151
- neuralis request GET "$1" >"$2" 2>"$WORK/request.err" || rc=$?
152
- if [ "$rc" -eq 0 ]; then echo 200; return; fi
153
- code="$(sed -n '/^HTTP [0-9][0-9][0-9]$/{s/^HTTP //p;q;}' "$WORK/request.err")"
154
- if [ -n "$code" ]; then awk '!d && /^HTTP [0-9][0-9][0-9]$/ {d=1; next} {print}' "$WORK/request.err" > "$2"; else code="000"; fi
155
- echo "$code"
138
+ if (!pkgId) {
139
+ process.stderr.write('usage: node verify-loaded.mjs <package-id> [--raw]\n');
140
+ process.exit(4);
156
141
  }
142
+ const BASE_ROUTE = '@neuralis/agent-core/packages';
157
143
 
158
- DIAG_CODE="$(fetch "${BASE_ROUTE}/diagnostics" "$WORK/diag.json")"
159
-
160
- if [ "$DIAG_CODE" = "403" ]; then
161
- echo "FORBIDDEN the package diagnostics surface requires the 'core.observe' feature, and your identity does not hold it." >&2
162
- echo " This is a capability you are missing, not a broken package — say so instead of retrying." >&2
163
- manual_fallback
164
- exit 4
165
- fi
166
- if [ "$DIAG_CODE" != "200" ]; then
167
- echo "ERROR GET ${BASE_ROUTE}/diagnostics returned HTTP ${DIAG_CODE}" >&2
168
- [ -s "$WORK/request.err" ] && sed 's/^/ /' "$WORK/request.err" >&2
169
- [ -s "$WORK/diag.json" ] && head -c 600 "$WORK/diag.json" >&2 && echo >&2
170
- manual_fallback
171
- exit 4
172
- fi
173
-
174
- OVER_CODE="$(fetch "${BASE_ROUTE}/overview" "$WORK/overview.json")"
175
- [ "$OVER_CODE" = "200" ] || : > "$WORK/overview.json"
144
+ // `neuralis request` prints a 2xx body on stdout (exit 0); a non-2xx body goes to
145
+ // stderr after an `HTTP <code>` line (exit 1). No such line = no answer at all
146
+ // (no CLI login, no network) — "000"; its error text stays in `err`.
147
+ function fetchRoute(route) {
148
+ const args = ['request', 'GET', route];
149
+ const opts = { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'], maxBuffer: 256 * 1024 * 1024 };
150
+ const entry = process.env.NEURALIS_CLI_ENTRY;
151
+ if (entry === undefined && process.platform === 'win32') {
152
+ fail('ERROR set NEURALIS_CLI_ENTRY to the neuralis CLI entry (…/dist/neuralis.mjs) — on Windows this script starts the CLI through node, never a shell');
153
+ }
154
+ try {
155
+ const body = entry !== undefined ? execFileSync(process.execPath, [entry, ...args], opts) : execFileSync('neuralis', args, opts);
156
+ return { code: '200', body, err: '' };
157
+ } catch (e) {
158
+ if (e.code === 'ENOENT') fail('ERROR neuralis (the CLI) not found on PATH');
159
+ const err = typeof e.stderr === 'string' ? e.stderr : '';
160
+ const lines = err.split('\n');
161
+ const at = lines.findIndex((l) => /^HTTP [0-9]{3}$/.test(l));
162
+ if (at < 0) return { code: '000', body: '', err };
163
+ return { code: lines[at].slice(5), body: lines.slice(at + 1).join('\n'), err };
164
+ }
165
+ }
176
166
 
177
- if [ "$RAW" = "1" ]; then
178
- echo "--- diagnostics (HTTP ${DIAG_CODE}) ---"
179
- cat "$WORK/diag.json"; echo
180
- echo "--- overview (HTTP ${OVER_CODE}) ---"
181
- cat "$WORK/overview.json"; echo
182
- echo "--- verdict ---"
183
- fi
167
+ const diagRes = fetchRoute(`${BASE_ROUTE}/diagnostics`);
168
+ if (diagRes.code === '403') {
169
+ fail("FORBIDDEN the package diagnostics surface requires the 'core.observe' feature, and your identity does not hold it.\n"
170
+ + ' This is a capability you are missing, not a broken package — say so instead of retrying.');
171
+ }
172
+ if (diagRes.code !== '200') {
173
+ let detail = `ERROR GET ${BASE_ROUTE}/diagnostics returned HTTP ${diagRes.code}`;
174
+ if (diagRes.err) detail += `\n${diagRes.err.replace(/\n$/, '').split('\n').map((l) => ` ${l}`).join('\n')}`;
175
+ if (diagRes.body) detail += `\n${diagRes.body.slice(0, 600)}`;
176
+ fail(detail);
177
+ }
178
+ const overRes = fetchRoute(`${BASE_ROUTE}/overview`);
179
+ const overCode = overRes.code;
180
+ if (overCode !== '200') overRes.body = '';
184
181
 
185
- set +e
186
- node - "$PKG_ID" "$WORK/diag.json" "$WORK/overview.json" "$OVER_CODE" <<'NODE_VERIFY'
187
- 'use strict';
188
- const fs = require('fs');
189
- const [, , pkgId, diagPath, overPath, overCode] = process.argv;
182
+ if (RAW) {
183
+ process.stdout.write(`--- diagnostics (HTTP ${diagRes.code}) ---\n${diagRes.body}\n`);
184
+ process.stdout.write(`--- overview (HTTP ${overCode}) ---\n${overRes.body}\n`);
185
+ process.stdout.write('--- verdict ---\n');
186
+ }
190
187
 
191
- const readMaybe = (p) => {
192
- try { const t = fs.readFileSync(p, 'utf8'); return t.trim() ? JSON.parse(t) : null; }
188
+ const readMaybe = (t) => {
189
+ try { return t.trim() ? JSON.parse(t) : null; }
193
190
  catch { return null; }
194
191
  };
195
192
 
196
- const diag = readMaybe(diagPath);
193
+ const diag = readMaybe(diagRes.body);
197
194
  if (!diag || !Array.isArray(diag.entries)) {
198
195
  process.stderr.write('ERROR the diagnostics response did not carry an "entries" array — the response shape drifted.\n');
199
196
  process.stderr.write(' Re-run with --raw and read the payload before trusting any verdict.\n');
200
197
  process.exit(4);
201
198
  }
202
- const over = readMaybe(overPath);
199
+ const over = readMaybe(overRes.body);
203
200
  const overPackages = over && Array.isArray(over.packages) ? over.packages : [];
204
201
  const overSource = over && Array.isArray(over.sourcePackages) ? over.sourcePackages : [];
205
202
 
@@ -309,9 +306,9 @@ const counts = () => {
309
306
  // an outbound connector is registered into ONE tenant, or into none.
310
307
  process.stdout.write(' NOTE: connectors are DECLARATIONS, not live instances. An outbound\n');
311
308
  process.stdout.write(' (mcp/openapi/http) connector registers into exactly one tenant — the\n');
312
- process.stdout.write(' platform lane for a first-party install, the owning project for a\n');
309
+ process.stdout.write(' platform lane for a native install, the owning project for a\n');
313
310
  process.stdout.write(' drop — and into NO tenant at all when the package is neither\n');
314
- process.stdout.write(' first-party nor owned by a resolvable project, which is silent\n');
311
+ process.stdout.write(' native nor owned by a resolvable project, which is silent\n');
315
312
  process.stdout.write(' apart from one server log line. Prove the instance exists with\n');
316
313
  process.stdout.write(' neuralis request GET @neuralis/agent-core/connectors; that list is\n');
317
314
  process.stdout.write(' the platform lane plus your own project, and nothing else.\n');
@@ -325,8 +322,8 @@ const counts = () => {
325
322
  const REASONS = {
326
323
  'build-missing': 'the sandbox artifact was never built. Build the package, then reinstall.',
327
324
  'runtime-unavailable': 'the declared runtime could not start (a subprocess that failed to spawn, or a code runtime that crashed). Check the entry command and the runtime type.',
328
- 'untrusted-node': 'the manifest declares the in-process "node" runtime, which requires first-party trust. Declare "wasm" to run code on any other tier.',
329
- 'untrusted-mcp': 'the manifest declares the "mcp" runtime, which spawns a subprocess as the host user and requires first-party trust, so nothing was spawned. Declare "wasm" — it is the only code runtime available below first-party.',
325
+ 'untrusted-node': 'the manifest declares the in-process "node" runtime, which requires native trust. Declare "wasm" to run code on any other tier.',
326
+ 'untrusted-mcp': 'the manifest declares the "mcp" runtime, which spawns a subprocess as the host user and requires native trust, so nothing was spawned. Declare "wasm" — it is the only code runtime available below native.',
330
327
  };
331
328
 
332
329
  if (status === 'loaded') {
@@ -343,10 +340,11 @@ if (status === 'loaded') {
343
340
  process.stdout.write('If a skill of this package still answers "Skill not found" in the conversation\n');
344
341
  process.stdout.write('that just enabled, trusted or installed it: those changes apply from the NEXT\n');
345
342
  process.stdout.write('stream (a new user message, a workflow run, or a fresh conversation), never\n');
346
- process.stdout.write('mid-turn. A delegate spawned after the change sees its <packages> entry,\n');
347
- process.stdout.write('injected rules/instructions and agent resolution fresh, but its tool catalog\n');
348
- process.stdout.write('and skill activation still use the parent stream\'s gate. Retry from a fresh\n');
349
- process.stdout.write('stream before re-diagnosing.\n');
343
+ process.stdout.write('mid-turn. A FOREGROUND delegate spawned after the change sees its <packages>\n');
344
+ process.stdout.write('entry, injected rules/instructions and agent resolution fresh, but its tool\n');
345
+ process.stdout.write('catalog and skill activation still use the parent stream\'s gate; a background\n');
346
+ process.stdout.write('delegate re-reads all of them at its wake. Retry from a fresh stream before\n');
347
+ process.stdout.write('re-diagnosing.\n');
350
348
  process.exit(0);
351
349
  }
352
350
 
@@ -369,7 +367,7 @@ if (status === 'error' || status === 'missing') {
369
367
  if (entry.sourceRoot) line('sourceRoot', entry.sourceRoot);
370
368
  process.stdout.write(status === 'missing'
371
369
  ? '\nInstalled but it never reached the loader — the manifest could not be read.\n Check that package.json exists at the install root, parses, and carries a\n "neuralis" block with an id.\n'
372
- : '\nValidation or init crashed and NOTHING registered. The message above is the\n loader\'s own; a tool-schema error names the file that aborted the load.\n Fix it, then run check-package.sh on the package root before reinstalling.\n');
370
+ : '\nValidation or init crashed and NOTHING registered. The message above is the\n loader\'s own; a tool-schema error names the file that aborted the load.\n Fix it, then run check-package.mjs on the package root before reinstalling.\n');
373
371
  process.exit(3);
374
372
  }
375
373
 
@@ -377,7 +375,3 @@ process.stdout.write(`UNKNOWN STATUS ${pkgId} -> "${status}"\n`);
377
375
  process.stdout.write('The status vocabulary is loaded | partial | error | missing. Anything else\n');
378
376
  process.stdout.write('means the response shape drifted — re-run with --raw and read the payload.\n');
379
377
  process.exit(4);
380
- NODE_VERIFY
381
- NODE_STATUS=$?
382
- set -e
383
- exit "$NODE_STATUS"
@@ -2,22 +2,22 @@
2
2
  name: git
3
3
  description: "Operate git on a git-backed source through governed routes: inspect status, diff, history, and outgoing changes; stage, discard, commit, branch, switch, fetch, pull, or push. Use for repository work; choose governed git by default, raw CLI for allowed local inspection, and GitHub tools for remote collaboration."
4
4
  allowed-tools: execute
5
- requiredFeatures: [drive.read]
5
+ requiredFeatures: [files.read]
6
6
  ---
7
7
 
8
8
  # Git
9
9
 
10
- Drive git on a **git-backed source** (any `local`-kind source that is a git checkout)
10
+ Drive git on a **git-backed source** (any folder that is a git checkout — on this server, or on a paired device, where git runs on that device for its owner or for a member it admits; fetch/pull/push of a device folder run only for the device's owner, with their own git credentials there — anyone else gets `git_remote_owner_only`)
11
11
  through brain-core's governed git routes. These are the **same routes the Git Control
12
12
  panel drives**, so an agent gets exactly the rights a human member has: gated by
13
- `drive.read` / `drive.write` + the source's uri-policy, with a **server-side snapshot
13
+ `files.read` / `files.write` + the source's uri-policy, with a **server-side snapshot
14
14
  before every destructive op** and **credential-safe remotes** (the push/pull token is
15
15
  resolved server-side and never touches the agent shell).
16
16
 
17
17
  Call them with `neuralis request <GET|POST> @neuralis/brain-core/git/<route> …` — inside an
18
18
  activated skill it authenticates with the per-stream session ticket, on your own machine with
19
19
  `neuralis login`; never with a git credential (fetch/pull/push resolve the remote token
20
- server-side). The method is part of every call line: `commit` and `branch` READ on GET and
20
+ server-side, or — on a device folder — use its owner's own git credentials there). The method is part of every call line: `commit` and `branch` READ on GET and
21
21
  WRITE on POST. This is *not* about committing to the Neuralis repo itself — it is about an
22
22
  agent operating git on a user's source.
23
23
 
@@ -31,8 +31,8 @@ agent operating git on a user's source.
31
31
 
32
32
  Default to **A** for governed local ops and for pushing/pulling your connected remote; **B**
33
33
  for platform collaboration; **C** for a fast read or when a user's own skill already drives git.
34
- Plane A is always "call the routes with `neuralis request`" — the first-party `git` connector shown in the
35
- `<packages>` overview is metadata; there are no first-party git MCP *tools* to call.
34
+ Plane A is always "call the routes with `neuralis request`" — the native `git` connector shown in the
35
+ `<packages>` overview is metadata; there are no native git MCP *tools* to call.
36
36
 
37
37
  ## Routes covered
38
38
 
@@ -54,12 +54,11 @@ source and fence the rest with path policy, or split the subtree into its own re
54
54
  raw-CLI workaround.
55
55
 
56
56
  **But the refusal is only LOUD on the write side, and this has already fooled a run.** A write
57
- route answers a scrubbed **`400 git_outside_source`**. The four root-gated summary READS —
58
- `status`, `branch`, `log`, `log-stats` — **fail SOFT**: they answer `200 {"ok":true, …}` with an
59
- empty payload (`status` → `branch:null` + three empty buckets; `branch` → `branches:[]`;
60
- `log` → `commits:[]`; `log-stats` → `stats:{}`), which is **byte-identical to a clean repository
61
- with nothing to report**. The same empty answer covers a
62
- source with no `.git` at all. (`commit`, `outgoing` and `show` are honest — they answer a typed
57
+ route answers a scrubbed **`400 git_outside_source`**. Three root-gated summary READS —
58
+ `branch`, `log`, `log-stats` — **fail SOFT**: they answer `200 {"ok":true, …}` with an empty
59
+ payload (`branch` → `branches:[]`; `log` → `commits:[]`; `log-stats` → `stats:{}`), which is
60
+ **byte-identical to a clean repository with nothing to report**. The same empty answer covers a
61
+ source with no `.git` at all. (`status`, `commit`, `outgoing` and `show` are honest — they answer a typed
63
62
  `{"ok":false,"code":"unavailable"}` — and `diff` returns an empty diff string, except when it
64
63
  refuses a huge read with its own typed `{"ok":false,"code":"too_large"}`. Both of those typed
65
64
  refusals arrive on a **200**, so `neuralis request` exits 0: a zero exit with `ok:false` is a
@@ -67,41 +66,39 @@ soft answer, a non-zero exit is an HTTP refusal whose body and `HTTP <code>` are
67
66
  EVERY refusal carries `error`; a write-op failure and the three remote 409s also carry
68
67
  `ok:false` and `code`; a 403 carries `code` (`feature_denied` / `uri_policy_denied`).)
69
68
 
70
- **So an empty read is never evidence of a clean tree.** Do not test it with `branch:null`: a real
71
- repository on a detached HEAD, or freshly initialised with no commit yet, reports exactly that.
72
- **Ask `repos` first.** `{"ok":true,"repos":[]}` means there is no checkout at the source root and
73
- none one level down — every root-gated read on that source will fail soft, so report the git plane
74
- **UNKNOWN** and stop. A non-empty `repos` is **not yet** a live plane: rows carry `rel`, and only a
75
- row with `rel:""` is the SOURCE ROOT — any other `rel` is a nested checkout that answers only when
76
- you pass `repo=<rel>`, so a list of nested rows leaves a root-gated `status` (no `repo`) still
77
- failing soft. And a `rel:""` row only proves a `.git` is THERE, not that git accepted it — the
78
- containment refusal above keeps its row. Confirm on the repo you are about to trust with
79
- `outgoing`: `{"ok":true,…}` proves git actually ran there; `{"ok":false,"code":"unavailable"}`
80
- leaves it UNKNOWN (a dead plane and an unborn HEAD answer alike). Only then does an empty `status`
81
- mean a clean tree. When you have already read an empty `status` and cannot re-ask, say the plane was
82
- unreadable; never write "no changes" into a report you cannot back.
69
+ **So an empty `branch`/`log`/`log-stats` read is never evidence of a clean tree — `status` is.**
70
+ `{"ok":true,…}` from `status` proves git ran on that checkout, so empty buckets there mean a clean
71
+ tree; `{"ok":false,"code":"unavailable"}` means git could not read it (no checkout at that root, the
72
+ containment refusal above, or git failing there) — report the git plane **UNKNOWN**. Do not test
73
+ with `branch:null`: a real repository on a detached HEAD, or freshly initialised with no commit
74
+ yet, reports exactly that. **Ask `repos` first** to find the checkout. `{"ok":true,"repos":[]}`
75
+ means there is no checkout at the source root and none one level down. Rows carry `rel`, and only
76
+ a row with `rel:""` is the SOURCE ROOT — any other `rel` is a nested checkout that answers only
77
+ when you pass `repo=<rel>`. A `rel:""` row only proves a `.git` is THERE, not that git accepted it
78
+ — the containment refusal keeps its row, so `status` stays the confirmation. Never write "no
79
+ changes" into a report you cannot back.
83
80
 
84
81
  | Action | Method | Route | Key params | Gate |
85
82
  |---|---|---|---|---|
86
- | Whole-repo change-set + branch + ahead/behind | GET | `status` | `source`,`repo?` | `drive.read` + uri-policy `read` (root) |
87
- | Local branch list | GET | `branch` | `source`,`repo?` | `drive.read` + `read` (root) |
88
- | Per-file unified diff | GET | `diff` | `source`,`path` **(required)**; optionally one of `staged=1` \| `commit=<sha>` \| `base=<sha>&head=<sha>` (omit all three for the unstaged working-tree diff) | `drive.read` + `read` (per-path) |
89
- | Blob content at a rev | GET | `show` | `source`,`path`,`rev=index\|<sha>` | `drive.read` + `read` (per-path) |
90
- | Commit-DAG page (+ `outgoing[]`) | GET | `log` | `source`,`maxCount?`,`skip?`,`ref?` | `drive.read` + `read` (root) |
91
- | Per-commit `+/-` totals for a log page | GET | `log-stats` | `source`,`maxCount?`,`skip?`,`ref?` | `drive.read` + `read` (root) |
92
- | Files a commit changed | GET | `commit` | `source`,`sha=<sha>` | `drive.read` + `read` (root) |
93
- | Committed-but-not-pushed files | GET | `outgoing` | `source` | `drive.read` + `read` (root) |
94
- | In-source repo picker — **and the plane-liveness test: empty `repos` ⇒ every root-gated read fails soft** | GET | `repos` | `source` | `drive.read` + `read` (root) |
95
- | Stage whole files or a hunk | POST | `stage` | `source`,`paths:[…]` **or** `hunk:"<patch>"` | `drive.write` + `write` (per-path) |
96
- | Unstage whole files or a hunk | POST | `unstage` | `source`,`paths:[…]` **or** `hunk` | `drive.write` + `write` (per-path) |
97
- | Discard working-tree changes (**destructive** → returns `rescue`) | POST | `discard` | `source`,`paths:[…]` | `drive.write` + `write` (per-path) |
98
- | Create a commit from the index | POST | `commit` | `source`,`message`,`amend?` | `drive.write` + `write` (root) |
99
- | Create / delete a branch (delete **destructive** → `rescue`) | POST | `branch` | `source`,`action:"create"\|"delete"`,`name`,`startPoint?`,`force?` | `drive.write` + `write` (root) |
100
- | Switch branch (plain, refuses to clobber → 409) | POST | `checkout` | `source`,`ref` | `drive.write` + `write` (root) |
101
- | **Undo** a `discard` / `branch` delete from its `rescue` carrier | POST | `restore` | `source`,`rescue:{kind:"stash"\|"branch",ref,name?}` | `drive.write` + `write` (root) |
102
- | Fetch from the connected remote | POST | `fetch` | `source` | `drive.write` + uri-policy **`exec`** + connected remote |
103
- | Pull (fetch + fast-forward-only merge) | POST | `pull` | `source` | `drive.write` + `exec` + `write` + connected remote |
104
- | Push `HEAD` (no force) | POST | `push` | `source` | `drive.write` + `exec` + connected remote |
83
+ | Whole-repo change-set + branch + ahead/behind | GET | `status` | `source`,`repo?` | `files.read` + uri-policy `read` (root) |
84
+ | Local branch list | GET | `branch` | `source`,`repo?` | `files.read` + `read` (root) |
85
+ | Per-file unified diff | GET | `diff` | `source`,`path` **(required)**; optionally one of `staged=1` \| `commit=<sha>` \| `base=<sha>&head=<sha>` (omit all three for the unstaged working-tree diff) | `files.read` + `read` (per-path) |
86
+ | Blob content at a rev | GET | `show` | `source`,`path`,`rev=index\|<sha>` | `files.read` + `read` (per-path) |
87
+ | Commit-DAG page (+ `outgoing[]`) | GET | `log` | `source`,`maxCount?`,`skip?`,`ref?` | `files.read` + `read` (root) |
88
+ | Per-commit `+/-` totals for a log page | GET | `log-stats` | `source`,`maxCount?`,`skip?`,`ref?` | `files.read` + `read` (root) |
89
+ | Files a commit changed | GET | `commit` | `source`,`sha=<sha>` | `files.read` + `read` (root) |
90
+ | Committed-but-not-pushed files | GET | `outgoing` | `source` | `files.read` + `read` (root) |
91
+ | In-source repo picker — **empty `repos` ⇒ no checkout at the root or one level down** | GET | `repos` | `source` | `files.read` + `read` (root) |
92
+ | Stage whole files or a hunk | POST | `stage` | `source`,`paths:[…]` **or** `hunk:"<patch>"` | `files.write` + `write` (per-path) |
93
+ | Unstage whole files or a hunk | POST | `unstage` | `source`,`paths:[…]` **or** `hunk` | `files.write` + `write` (per-path) |
94
+ | Discard working-tree changes (**destructive** → returns `rescue`) | POST | `discard` | `source`,`paths:[…]` | `files.write` + `write` (per-path) |
95
+ | Create a commit from the index | POST | `commit` | `source`,`message`,`amend?` | `files.write` + `write` (root) |
96
+ | Create / delete a branch (delete **destructive** → `rescue`) | POST | `branch` | `source`,`action:"create"\|"delete"`,`name`,`startPoint?`,`force?` | `files.write` + `write` (root) |
97
+ | Switch branch (plain, refuses to clobber → 409) | POST | `checkout` | `source`,`ref` | `files.write` + `write` (root) |
98
+ | **Undo** a `discard` / `branch` delete from its `rescue` carrier | POST | `restore` | `source`,`rescue:{kind:"stash"\|"branch",ref,name?}` | `files.write` + `write` (root) |
99
+ | Fetch from the connected remote | POST | `fetch` | `source` | `files.write` + uri-policy **`exec`** + connected remote |
100
+ | Pull (fetch + fast-forward-only merge) | POST | `pull` | `source` | `files.write` + `exec` + `write` + connected remote |
101
+ | Push `HEAD` (no force) | POST | `push` | `source` | `files.write` + `exec` + connected remote |
105
102
 
106
103
  Notes:
107
104
  - `GET commit` (what a commit changed) and `POST commit` (create a commit) are **different**
@@ -111,7 +108,7 @@ Notes:
111
108
  only (never paths), and read-denied paths are excluded from the totals. Use it instead of
112
109
  fetching diffs to count lines.
113
110
  - The three capability tiers are gated **independently server-side**, regardless of this skill's
114
- `requiredFeatures`: read routes need `drive.read`, write routes additionally need `drive.write`
111
+ `requiredFeatures`: read routes need `files.read`, write routes additionally need `files.write`
115
112
  (a read-only caller sees a **403** from any POST), and the remote routes additionally need
116
113
  uri-policy **`exec`** on the source root (`exec` is off by default → a **403** whose body
117
114
  carries a grant-exec affordance) **plus a connected remote** (409 `not_connected` /
@@ -120,7 +117,7 @@ Notes:
120
117
  return a typed `rescue` carrier. **Undo it through the governed `restore` route** — echo the
121
118
  carrier straight back: `POST restore` with `{"source":"…","rescue":{"kind":"stash","ref":"<sha>"}}`
122
119
  for discarded content, `{"kind":"branch","ref":"<anchor>","name":"<branch>"}` for a deleted
123
- branch. Same gate as any other write (`drive.write` + `write` on the root — no `exec`, no new
120
+ branch. Same gate as any other write (`files.write` + `write` on the root — no `exec`, no new
124
121
  capability), and the restore itself snapshots first. Do **not** reach for raw-shell
125
122
  `git stash apply` / `git branch` instead: Plane C has no snapshot, so a failed recovery there is
126
123
  unrecoverable. Surface the `rescue` to the user either way — a carrier you never mention is a
@@ -136,7 +133,12 @@ The remote routes act as *you*: they read your own remote binding and resolve yo
136
133
  via the agent-core **git-connect** surface (feature `git.connect`) — the **Git Remotes** config
137
134
  card — with either a Personal Access Token or **GitHub OAuth**. Only `origin` over HTTPS is
138
135
  supported (SSH → 409). If a push/pull returns `not_connected` / `no_credential`, ask the user to
139
- connect the remote in that card first.
136
+ connect the remote in that card first. On a **device folder** no binding is used: the device's
137
+ owner fetches/pulls/pushes with their own git credentials on that machine; for anyone else the
138
+ route answers 409 `git_remote_owner_only` — ask the owner to run it. Any git call on a device
139
+ folder that answers 409 `git_device_unavailable` names why in `reason` (`devices_disabled`,
140
+ `runtime_offline`, `broker_outdated`, `others_denied`, `device_not_ready` — the device's broker is not
141
+ ready; its owner runs `neuralis device status` there, …) — report it; it is not an empty repo.
140
142
 
141
143
  ## Safe workflow
142
144
 
@@ -179,15 +181,15 @@ neuralis request GET @neuralis/brain-core/git/log -f source=my-repo -f maxCou
179
181
  # authorship, and is unsafe once it has been pushed (the remote keeps the original
180
182
  # and the two histories diverge). Stage NAMED paths only — `paths:[…]` is what keeps
181
183
  # a stray secret from being swept in; there is no route that un-commits.
182
- neuralis request POST @neuralis/brain-core/git/stage --input - <<<'{"source":"my-repo","paths":["src/app.ts","README.md"]}'
183
- neuralis request POST @neuralis/brain-core/git/commit --input - <<<'{"source":"my-repo","message":"Fix null guard in loader"}'
184
+ echo '{"source":"my-repo","paths":["src/app.ts","README.md"]}' | neuralis request POST @neuralis/brain-core/git/stage --input -
185
+ echo '{"source":"my-repo","message":"Fix null guard in loader"}' | neuralis request POST @neuralis/brain-core/git/commit --input -
184
186
 
185
187
  # Create a branch, then switch to it.
186
188
  # checkout MOVES HEAD and swaps the working tree to that branch's content — the files
187
189
  # the user is looking at change under them. It is plain (never `-f`): if the switch
188
190
  # would overwrite uncommitted local changes, git refuses and you get a 409. Report
189
191
  # that refusal; there is no force option here and you must not build one in Plane C.
190
- neuralis request POST @neuralis/brain-core/git/branch --input - <<<'{"source":"my-repo","action":"create","name":"fix/loader"}'
192
+ echo '{"source":"my-repo","action":"create","name":"fix/loader"}' | neuralis request POST @neuralis/brain-core/git/branch --input -
191
193
  neuralis request POST @neuralis/brain-core/git/checkout -f source=my-repo -f ref=fix/loader
192
194
 
193
195
  # Sync a connected remote (needs uri-policy exec + a connected remote).
@@ -202,5 +204,5 @@ neuralis request POST @neuralis/brain-core/git/pull -f source=my-repo
202
204
  neuralis request POST @neuralis/brain-core/git/push -f source=my-repo
203
205
 
204
206
  # Nested repo inside a multi-repo source: add the repo selector
205
- neuralis request GET @neuralis/brain-core/git/status -f source=mono -f repo=packages/api
207
+ neuralis request GET @neuralis/brain-core/git/status -f source=mono -f repo=api
206
208
  ```