@neuralis/brain-core 0.1.0 → 0.2.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 (383) hide show
  1. package/README.md +26 -35
  2. package/app/cards/DiffView.tsx +9 -7
  3. package/app/cards/README.md +1 -1
  4. package/app/cards/diffLine.tsx +2 -4
  5. package/app/filesystem/README.md +1 -1
  6. package/app/filesystem/api/index.ts +14 -5
  7. package/app/filesystem/domain/types.ts +24 -5
  8. package/app/filesystem/store/filesystemStore.ts +20 -1
  9. package/app/filesystem/store/listSlice.ts +2 -0
  10. package/app/filesystem/store/searchSlice.ts +24 -1
  11. package/app/filesystem/ui/FileTreeSearch.tsx +29 -2
  12. package/app/filesystem/ui/PendingChangesPanel.tsx +74 -17
  13. package/app/filesystem/ui/PendingReviewDialog.tsx +45 -20
  14. package/app/filesystem/ui/README.md +8 -7
  15. package/app/filesystem/ui/ReembedDialog.tsx +20 -9
  16. package/app/filesystem/ui/SourceDeleteConfirm.tsx +1 -1
  17. package/app/filesystem/ui/SourcesPanel.tsx +110 -17
  18. package/app/filesystem/ui/VectorHealthPanel.tsx +14 -0
  19. package/app/filesystem/ui/pendingChangesModel.ts +9 -5
  20. package/dist/app/chunks/{astro-LRAFGXNX.js → astro-B2J4AS2D.js} +1 -1
  21. package/dist/app/chunks/bash-KY6SAQTH.js +1 -0
  22. package/dist/app/chunks/c-OBOPYVZ7.js +1 -0
  23. package/dist/app/chunks/{chunk-5H7ZCOD3.js → chunk-2X3GNKJ3.js} +1 -1
  24. package/dist/app/chunks/{chunk-XIFGTNRM.js → chunk-JPJIVRFI.js} +1 -1
  25. package/dist/app/chunks/{chunk-RH3QY5LF.js → chunk-LEFIFWND.js} +1 -1
  26. package/dist/app/chunks/{chunk-G4RZ3UNX.js → chunk-N6RXX3PH.js} +1 -1
  27. package/dist/app/chunks/{chunk-QXXJ73P5.js → chunk-PZAW4HPB.js} +1 -1
  28. package/dist/app/chunks/{chunk-3QLE7Y4L.js → chunk-ZBYWWTO6.js} +1 -1
  29. package/dist/app/chunks/cpp-TVWVOTEQ.js +1 -0
  30. package/dist/app/chunks/css-MANZBYA4.js +1 -0
  31. package/dist/app/chunks/{elixir-M36XROA6.js → elixir-S725Z7EH.js} +1 -1
  32. package/dist/app/chunks/{elm-7BG6QAIK.js → elm-5WUUSTNB.js} +1 -1
  33. package/dist/app/chunks/graphql-UGOPR3WU.js +1 -0
  34. package/dist/app/chunks/html-F6FWTBSG.js +1 -0
  35. package/dist/app/chunks/java-ANIVV5H5.js +1 -0
  36. package/dist/app/chunks/javascript-IH374YWG.js +1 -0
  37. package/dist/app/chunks/json-WGGVVXSB.js +1 -0
  38. package/dist/app/chunks/jsx-OTXJQD32.js +1 -0
  39. package/dist/app/chunks/{latex-ZWK7SXB6.js → latex-QCZNITGN.js} +1 -1
  40. package/dist/app/chunks/lua-4CRZ64PU.js +1 -0
  41. package/dist/app/chunks/{nginx-2L6VRV3A.js → nginx-V4CYS7WR.js} +1 -1
  42. package/dist/app/chunks/{perl-PBUAXXK6.js → perl-BHTX7F5B.js} +1 -1
  43. package/dist/app/chunks/{php-QJX57PA6.js → php-AYGJ5WYZ.js} +1 -1
  44. package/dist/app/chunks/r-4YFCFA4B.js +1 -0
  45. package/dist/app/chunks/{ruby-RLOWMVPO.js → ruby-42NMJWAL.js} +1 -1
  46. package/dist/app/chunks/{scss-B5CAI3HR.js → scss-XD7VU2CU.js} +1 -1
  47. package/dist/app/chunks/sql-B55MH6JJ.js +1 -0
  48. package/dist/app/chunks/{svelte-GT3D4C44.js → svelte-WR3QPIJU.js} +1 -1
  49. package/dist/app/chunks/tsx-S73GAE2L.js +1 -0
  50. package/dist/app/chunks/typescript-NEWOAB5Z.js +1 -0
  51. package/dist/app/chunks/{vue-JOW62MHD.js → vue-CCDS4VZK.js} +1 -1
  52. package/dist/app/chunks/xml-UXKAGLDR.js +1 -0
  53. package/dist/app/chunks/yaml-UMWKDTK7.js +1 -0
  54. package/dist/app/host.js +40 -40
  55. package/dist/scripts/embeddingLockV3.d.ts +30 -0
  56. package/dist/scripts/embeddingLockV3.d.ts.map +1 -0
  57. package/dist/scripts/embeddingLockV3.js +100 -0
  58. package/dist/scripts/embeddingLockV3.js.map +1 -0
  59. package/dist/scripts/vectorProofV1.d.ts +90 -0
  60. package/dist/scripts/vectorProofV1.d.ts.map +1 -0
  61. package/dist/scripts/vectorProofV1.js +220 -0
  62. package/dist/scripts/vectorProofV1.js.map +1 -0
  63. package/dist/src/config/env.d.ts +21 -0
  64. package/dist/src/config/env.d.ts.map +1 -1
  65. package/dist/src/config/env.js +55 -0
  66. package/dist/src/config/env.js.map +1 -1
  67. package/dist/src/connectors/AppSourceConfigStore.d.ts +12 -2
  68. package/dist/src/connectors/AppSourceConfigStore.d.ts.map +1 -1
  69. package/dist/src/connectors/AppSourceConfigStore.js +48 -40
  70. package/dist/src/connectors/AppSourceConfigStore.js.map +1 -1
  71. package/dist/src/connectors/LocalDiskConnector.d.ts +11 -14
  72. package/dist/src/connectors/LocalDiskConnector.d.ts.map +1 -1
  73. package/dist/src/connectors/LocalDiskConnector.js +87 -107
  74. package/dist/src/connectors/LocalDiskConnector.js.map +1 -1
  75. package/dist/src/connectors/sourceConfigMutation.d.ts +11 -1
  76. package/dist/src/connectors/sourceConfigMutation.d.ts.map +1 -1
  77. package/dist/src/connectors/sourceConfigMutation.js +36 -3
  78. package/dist/src/connectors/sourceConfigMutation.js.map +1 -1
  79. package/dist/src/domain/chunker.js +8 -3
  80. package/dist/src/domain/chunker.js.map +1 -1
  81. package/dist/src/domain/healthTypes.d.ts +11 -0
  82. package/dist/src/domain/healthTypes.d.ts.map +1 -1
  83. package/dist/src/domain/mime.d.ts +1 -0
  84. package/dist/src/domain/mime.d.ts.map +1 -1
  85. package/dist/src/domain/mime.js +48 -0
  86. package/dist/src/domain/mime.js.map +1 -1
  87. package/dist/src/domain/pendingChange.d.ts +7 -0
  88. package/dist/src/domain/pendingChange.d.ts.map +1 -1
  89. package/dist/src/domain/pendingChange.js +11 -0
  90. package/dist/src/domain/pendingChange.js.map +1 -1
  91. package/dist/src/domain/sourceConfig.d.ts +7 -14
  92. package/dist/src/domain/sourceConfig.d.ts.map +1 -1
  93. package/dist/src/domain/sourceConfig.js +1 -13
  94. package/dist/src/domain/sourceConfig.js.map +1 -1
  95. package/dist/src/domain/sourcePackages.d.ts +11 -2
  96. package/dist/src/domain/sourcePackages.d.ts.map +1 -1
  97. package/dist/src/domain/syncTrigger.d.ts +2 -3
  98. package/dist/src/domain/syncTrigger.d.ts.map +1 -1
  99. package/dist/src/domain/syncTrigger.js +2 -3
  100. package/dist/src/domain/syncTrigger.js.map +1 -1
  101. package/dist/src/domain/syncTypes.d.ts +21 -4
  102. package/dist/src/domain/syncTypes.d.ts.map +1 -1
  103. package/dist/src/domain/syncTypes.js.map +1 -1
  104. package/dist/src/domain/text.d.ts +3 -0
  105. package/dist/src/domain/text.d.ts.map +1 -1
  106. package/dist/src/domain/text.js +5 -0
  107. package/dist/src/domain/text.js.map +1 -1
  108. package/dist/src/domain/types.d.ts +9 -0
  109. package/dist/src/domain/types.d.ts.map +1 -1
  110. package/dist/src/embeddings/clients/GeminiEmbedder.d.ts.map +1 -1
  111. package/dist/src/embeddings/clients/GeminiEmbedder.js +11 -5
  112. package/dist/src/embeddings/clients/GeminiEmbedder.js.map +1 -1
  113. package/dist/src/embeddings/clients/OllamaEmbedder.d.ts.map +1 -1
  114. package/dist/src/embeddings/clients/OllamaEmbedder.js +13 -6
  115. package/dist/src/embeddings/clients/OllamaEmbedder.js.map +1 -1
  116. package/dist/src/embeddings/clients/OpenAIEmbedder.d.ts.map +1 -1
  117. package/dist/src/embeddings/clients/OpenAIEmbedder.js +12 -9
  118. package/dist/src/embeddings/clients/OpenAIEmbedder.js.map +1 -1
  119. package/dist/src/embeddings/clients/QwenEmbedder.d.ts.map +1 -1
  120. package/dist/src/embeddings/clients/QwenEmbedder.js +12 -5
  121. package/dist/src/embeddings/clients/QwenEmbedder.js.map +1 -1
  122. package/dist/src/embeddings/clients/VoyageEmbedder.d.ts.map +1 -1
  123. package/dist/src/embeddings/clients/VoyageEmbedder.js +12 -5
  124. package/dist/src/embeddings/clients/VoyageEmbedder.js.map +1 -1
  125. package/dist/src/embeddings/factory.d.ts +2 -0
  126. package/dist/src/embeddings/factory.d.ts.map +1 -1
  127. package/dist/src/embeddings/factory.js +23 -3
  128. package/dist/src/embeddings/factory.js.map +1 -1
  129. package/dist/src/embeddings/lock.d.ts +22 -11
  130. package/dist/src/embeddings/lock.d.ts.map +1 -1
  131. package/dist/src/embeddings/lock.js +47 -29
  132. package/dist/src/embeddings/lock.js.map +1 -1
  133. package/dist/src/embeddings/retry.d.ts +5 -0
  134. package/dist/src/embeddings/retry.d.ts.map +1 -1
  135. package/dist/src/embeddings/retry.js +35 -0
  136. package/dist/src/embeddings/retry.js.map +1 -1
  137. package/dist/src/events/pending.d.ts +56 -0
  138. package/dist/src/events/pending.d.ts.map +1 -0
  139. package/dist/src/events/pending.js +108 -0
  140. package/dist/src/events/pending.js.map +1 -0
  141. package/dist/src/events/source.d.ts +60 -14
  142. package/dist/src/events/source.d.ts.map +1 -1
  143. package/dist/src/events/source.js +149 -31
  144. package/dist/src/events/source.js.map +1 -1
  145. package/dist/src/events/vector.d.ts +33 -0
  146. package/dist/src/events/vector.d.ts.map +1 -0
  147. package/dist/src/events/vector.js +57 -0
  148. package/dist/src/events/vector.js.map +1 -0
  149. package/dist/src/git/GitRunner.d.ts.map +1 -1
  150. package/dist/src/git/GitRunner.js +11 -8
  151. package/dist/src/git/GitRunner.js.map +1 -1
  152. package/dist/src/git/sourceGitControl.d.ts.map +1 -1
  153. package/dist/src/git/sourceGitControl.js +2 -1
  154. package/dist/src/git/sourceGitControl.js.map +1 -1
  155. package/dist/src/index.d.ts +5 -4
  156. package/dist/src/index.d.ts.map +1 -1
  157. package/dist/src/index.js +4 -3
  158. package/dist/src/index.js.map +1 -1
  159. package/dist/src/lifecycle.d.ts +20 -4
  160. package/dist/src/lifecycle.d.ts.map +1 -1
  161. package/dist/src/lifecycle.js +5 -1
  162. package/dist/src/lifecycle.js.map +1 -1
  163. package/dist/src/routes/health.js +6 -1
  164. package/dist/src/routes/health.js.map +1 -1
  165. package/dist/src/routes/pending.d.ts.map +1 -1
  166. package/dist/src/routes/pending.js +2 -1
  167. package/dist/src/routes/pending.js.map +1 -1
  168. package/dist/src/routes/sources.d.ts.map +1 -1
  169. package/dist/src/routes/sources.js +60 -11
  170. package/dist/src/routes/sources.js.map +1 -1
  171. package/dist/src/services/BridgeService.d.ts +2 -2
  172. package/dist/src/services/BridgeService.d.ts.map +1 -1
  173. package/dist/src/services/BridgeService.js +11 -2
  174. package/dist/src/services/BridgeService.js.map +1 -1
  175. package/dist/src/services/FilesystemService.d.ts +3 -1
  176. package/dist/src/services/FilesystemService.d.ts.map +1 -1
  177. package/dist/src/services/FilesystemService.js +3 -1
  178. package/dist/src/services/FilesystemService.js.map +1 -1
  179. package/dist/src/services/FilesystemUiService.js +1 -1
  180. package/dist/src/services/FilesystemUiService.js.map +1 -1
  181. package/dist/src/services/SyncScheduler.d.ts.map +1 -1
  182. package/dist/src/services/SyncScheduler.js +0 -14
  183. package/dist/src/services/SyncScheduler.js.map +1 -1
  184. package/dist/src/services/VectorHealthService.d.ts.map +1 -1
  185. package/dist/src/services/VectorHealthService.js +2 -46
  186. package/dist/src/services/VectorHealthService.js.map +1 -1
  187. package/dist/src/services/baselineRepair.d.ts +2 -2
  188. package/dist/src/services/baselineRepair.js +2 -2
  189. package/dist/src/services/declaredSources.d.ts +8 -1
  190. package/dist/src/services/declaredSources.d.ts.map +1 -1
  191. package/dist/src/services/declaredSources.js +19 -19
  192. package/dist/src/services/declaredSources.js.map +1 -1
  193. package/dist/src/store/dataFormats.d.ts +14 -3
  194. package/dist/src/store/dataFormats.d.ts.map +1 -1
  195. package/dist/src/store/dataFormats.js +15 -5
  196. package/dist/src/store/dataFormats.js.map +1 -1
  197. package/dist/src/sync/DeltaSyncRunner.d.ts.map +1 -1
  198. package/dist/src/sync/DeltaSyncRunner.js +78 -243
  199. package/dist/src/sync/DeltaSyncRunner.js.map +1 -1
  200. package/dist/src/sync/SyncJobQueue.d.ts +33 -4
  201. package/dist/src/sync/SyncJobQueue.d.ts.map +1 -1
  202. package/dist/src/sync/SyncJobQueue.js +179 -19
  203. package/dist/src/sync/SyncJobQueue.js.map +1 -1
  204. package/dist/src/sync/moveDetector.d.ts +2 -1
  205. package/dist/src/sync/moveDetector.d.ts.map +1 -1
  206. package/dist/src/sync/moveDetector.js +2 -1
  207. package/dist/src/sync/moveDetector.js.map +1 -1
  208. package/dist/src/tools/fs_search.d.ts.map +1 -1
  209. package/dist/src/tools/fs_search.js +8 -0
  210. package/dist/src/tools/fs_search.js.map +1 -1
  211. package/dist/src/tools/fs_write.js +3 -1
  212. package/dist/src/tools/fs_write.js.map +1 -1
  213. package/dist/src/usecases/chunkUpsert.d.ts +4 -0
  214. package/dist/src/usecases/chunkUpsert.d.ts.map +1 -1
  215. package/dist/src/usecases/chunkUpsert.js +103 -60
  216. package/dist/src/usecases/chunkUpsert.js.map +1 -1
  217. package/dist/src/usecases/embeddingBacklog.d.ts +31 -0
  218. package/dist/src/usecases/embeddingBacklog.d.ts.map +1 -0
  219. package/dist/src/usecases/embeddingBacklog.js +244 -0
  220. package/dist/src/usecases/embeddingBacklog.js.map +1 -0
  221. package/dist/src/usecases/listSourcePackages.js +17 -1
  222. package/dist/src/usecases/listSourcePackages.js.map +1 -1
  223. package/dist/src/usecases/mediaLane.d.ts +11 -4
  224. package/dist/src/usecases/mediaLane.d.ts.map +1 -1
  225. package/dist/src/usecases/mediaLane.js +67 -30
  226. package/dist/src/usecases/mediaLane.js.map +1 -1
  227. package/dist/src/usecases/pendingReview.d.ts.map +1 -1
  228. package/dist/src/usecases/pendingReview.js +24 -7
  229. package/dist/src/usecases/pendingReview.js.map +1 -1
  230. package/dist/src/usecases/purgeExcludedPoints.d.ts +2 -0
  231. package/dist/src/usecases/purgeExcludedPoints.d.ts.map +1 -1
  232. package/dist/src/usecases/purgeExcludedPoints.js +3 -2
  233. package/dist/src/usecases/purgeExcludedPoints.js.map +1 -1
  234. package/dist/src/usecases/readFiles.d.ts.map +1 -1
  235. package/dist/src/usecases/readFiles.js +33 -6
  236. package/dist/src/usecases/readFiles.js.map +1 -1
  237. package/dist/src/usecases/reconcileSourcePackageRoots.d.ts +31 -0
  238. package/dist/src/usecases/reconcileSourcePackageRoots.d.ts.map +1 -0
  239. package/dist/src/usecases/reconcileSourcePackageRoots.js +114 -0
  240. package/dist/src/usecases/reconcileSourcePackageRoots.js.map +1 -0
  241. package/dist/src/usecases/searchFiles.d.ts.map +1 -1
  242. package/dist/src/usecases/searchFiles.js +62 -64
  243. package/dist/src/usecases/searchFiles.js.map +1 -1
  244. package/dist/src/usecases/syncIndexedFile.d.ts +42 -0
  245. package/dist/src/usecases/syncIndexedFile.d.ts.map +1 -0
  246. package/dist/src/usecases/syncIndexedFile.js +242 -0
  247. package/dist/src/usecases/syncIndexedFile.js.map +1 -0
  248. package/dist/src/usecases/syncPointWrites.d.ts +5 -0
  249. package/dist/src/usecases/syncPointWrites.d.ts.map +1 -1
  250. package/dist/src/usecases/syncPointWrites.js +32 -5
  251. package/dist/src/usecases/syncPointWrites.js.map +1 -1
  252. package/dist/src/usecases/uploadBinary.d.ts.map +1 -1
  253. package/dist/src/usecases/uploadBinary.js +36 -49
  254. package/dist/src/usecases/uploadBinary.js.map +1 -1
  255. package/dist/src/usecases/vector/endpointGuard.js +2 -1
  256. package/dist/src/usecases/vector/endpointGuard.js.map +1 -1
  257. package/dist/src/usecases/vector/estimate.d.ts +7 -4
  258. package/dist/src/usecases/vector/estimate.d.ts.map +1 -1
  259. package/dist/src/usecases/vector/estimate.js +8 -5
  260. package/dist/src/usecases/vector/estimate.js.map +1 -1
  261. package/dist/src/usecases/vector/rebuildGeneration.d.ts +29 -5
  262. package/dist/src/usecases/vector/rebuildGeneration.d.ts.map +1 -1
  263. package/dist/src/usecases/vector/rebuildGeneration.js +224 -82
  264. package/dist/src/usecases/vector/rebuildGeneration.js.map +1 -1
  265. package/dist/src/usecases/vectorMaintenance.d.ts +46 -4
  266. package/dist/src/usecases/vectorMaintenance.d.ts.map +1 -1
  267. package/dist/src/usecases/vectorMaintenance.js +190 -11
  268. package/dist/src/usecases/vectorMaintenance.js.map +1 -1
  269. package/dist/src/usecases/write/commit.d.ts +6 -8
  270. package/dist/src/usecases/write/commit.d.ts.map +1 -1
  271. package/dist/src/usecases/write/commit.js +96 -112
  272. package/dist/src/usecases/write/commit.js.map +1 -1
  273. package/dist/src/usecases/write/content.js +1 -2
  274. package/dist/src/usecases/write/content.js.map +1 -1
  275. package/dist/src/usecases/write/ports.d.ts +1 -0
  276. package/dist/src/usecases/write/ports.d.ts.map +1 -1
  277. package/dist/src/vector/FilesystemVectorIndex.d.ts +34 -3
  278. package/dist/src/vector/FilesystemVectorIndex.d.ts.map +1 -1
  279. package/dist/src/vector/FilesystemVectorIndex.js +254 -20
  280. package/dist/src/vector/FilesystemVectorIndex.js.map +1 -1
  281. package/dist/src/vector/InMemoryVectorIndex.d.ts +9 -2
  282. package/dist/src/vector/InMemoryVectorIndex.d.ts.map +1 -1
  283. package/dist/src/vector/InMemoryVectorIndex.js +25 -6
  284. package/dist/src/vector/InMemoryVectorIndex.js.map +1 -1
  285. package/dist/src/vector/QdrantVectorIndex.d.ts +35 -9
  286. package/dist/src/vector/QdrantVectorIndex.d.ts.map +1 -1
  287. package/dist/src/vector/QdrantVectorIndex.js +209 -90
  288. package/dist/src/vector/QdrantVectorIndex.js.map +1 -1
  289. package/dist/src/vector/qdrantFilter.d.ts +3 -1
  290. package/dist/src/vector/qdrantFilter.d.ts.map +1 -1
  291. package/dist/src/vector/qdrantFilter.js +2 -0
  292. package/dist/src/vector/qdrantFilter.js.map +1 -1
  293. package/dist/src/vector/types.d.ts +81 -0
  294. package/dist/src/vector/types.d.ts.map +1 -1
  295. package/dist/src/vector/types.js +2 -0
  296. package/dist/src/vector/types.js.map +1 -1
  297. package/dist/src/wiring.d.ts +6 -0
  298. package/dist/src/wiring.d.ts.map +1 -1
  299. package/dist/src/wiring.js +62 -3
  300. package/dist/src/wiring.js.map +1 -1
  301. package/dist/tools/fs_search.json +2 -2
  302. package/docs/drive-overview.md +2 -2
  303. package/instructions/brain-model.md +1 -1
  304. package/package.json +999 -10
  305. package/rules/brain-rules.md +1 -1
  306. package/skills/connect-business-data/SKILL.md +6 -4
  307. package/skills/create-package/SKILL.md +14 -12
  308. package/skills/create-package/references/config-and-credentials.md +3 -3
  309. package/skills/create-package/references/connectors-and-uri-policies.md +5 -3
  310. package/skills/create-package/references/manifest-and-discovery.md +4 -3
  311. package/skills/create-package/references/runtime-and-build.md +9 -9
  312. package/skills/create-package/references/skills-and-context.md +3 -3
  313. package/skills/create-package/references/surfaces-and-design.md +2 -1
  314. package/skills/create-package/references/team-and-workflows.md +2 -2
  315. package/skills/create-package/references/test-and-ship.md +15 -15
  316. package/skills/create-package/references/tools-and-schemas.md +1 -1
  317. package/skills/create-package/scripts/check-package.sh +3 -3
  318. package/skills/create-package/scripts/verify-loaded.sh +16 -16
  319. package/skills/manage-files/SKILL.md +2 -2
  320. package/skills/manage-sources/SKILL.md +16 -15
  321. package/skills/manage-sources/scripts/reembed.sh +9 -3
  322. package/skills/sync/SKILL.md +4 -4
  323. package/tools/fs_search.json +2 -2
  324. package/dist/app/chunks/bash-M45GHPBQ.js +0 -1
  325. package/dist/app/chunks/c-X3REOAWD.js +0 -1
  326. package/dist/app/chunks/cpp-VOWI743W.js +0 -1
  327. package/dist/app/chunks/css-2ZVPHE25.js +0 -1
  328. package/dist/app/chunks/graphql-7V2NP54C.js +0 -1
  329. package/dist/app/chunks/html-UF3LFLNA.js +0 -1
  330. package/dist/app/chunks/java-PNTAU4L3.js +0 -1
  331. package/dist/app/chunks/javascript-4JJTQGEL.js +0 -1
  332. package/dist/app/chunks/json-VLQ6D3JH.js +0 -1
  333. package/dist/app/chunks/jsx-KQKSLAAH.js +0 -1
  334. package/dist/app/chunks/lua-UFPYUJ2O.js +0 -1
  335. package/dist/app/chunks/r-QEZB45SR.js +0 -1
  336. package/dist/app/chunks/sql-DTZHNUZP.js +0 -1
  337. package/dist/app/chunks/tsx-WPR2WRZD.js +0 -1
  338. package/dist/app/chunks/typescript-LWO362OA.js +0 -1
  339. package/dist/app/chunks/xml-A5H72RTS.js +0 -1
  340. package/dist/app/chunks/yaml-MXHSIJCI.js +0 -1
  341. package/dist/src/services/purgePendingNodes.d.ts +0 -32
  342. package/dist/src/services/purgePendingNodes.d.ts.map +0 -1
  343. package/dist/src/services/purgePendingNodes.js +0 -61
  344. package/dist/src/services/purgePendingNodes.js.map +0 -1
  345. /package/dist/app/chunks/{chunk-737Y24HS.js → chunk-3JASFUPF.js} +0 -0
  346. /package/dist/app/chunks/{chunk-DKD2L57N.js → chunk-6EYLOQ4F.js} +0 -0
  347. /package/dist/app/chunks/{chunk-KYH5EHHY.js → chunk-7YRZ5LOQ.js} +0 -0
  348. /package/dist/app/chunks/{chunk-6TC3DVWV.js → chunk-C7LU4RID.js} +0 -0
  349. /package/dist/app/chunks/{chunk-TY33BMKR.js → chunk-CD52YDZP.js} +0 -0
  350. /package/dist/app/chunks/{chunk-OLEIKJ3X.js → chunk-DCJKTCJ5.js} +0 -0
  351. /package/dist/app/chunks/{chunk-QLBZ4JR2.js → chunk-EXIU2KBV.js} +0 -0
  352. /package/dist/app/chunks/{chunk-SFUNBBEA.js → chunk-FDP4LO4P.js} +0 -0
  353. /package/dist/app/chunks/{chunk-BGRVFATT.js → chunk-HNETUS7U.js} +0 -0
  354. /package/dist/app/chunks/{chunk-4QNMHAIR.js → chunk-LBFZJEDR.js} +0 -0
  355. /package/dist/app/chunks/{chunk-TRRUHDPN.js → chunk-ULRXL5VM.js} +0 -0
  356. /package/dist/app/chunks/{chunk-S6B4WWIF.js → chunk-XJK47SMJ.js} +0 -0
  357. /package/dist/app/chunks/{chunk-DZ5C5FKI.js → chunk-YYAAIAU2.js} +0 -0
  358. /package/dist/app/chunks/{clojure-OC6KPSJO.js → clojure-4QCN4GHG.js} +0 -0
  359. /package/dist/app/chunks/{core-KGE7TQJ3.js → core-ZHTX3P2Q.js} +0 -0
  360. /package/dist/app/chunks/{csharp-E7VIFITL.js → csharp-HQWR4N52.js} +0 -0
  361. /package/dist/app/chunks/{dark-plus-BOSCZXE4.js → dark-plus-GYPKKZES.js} +0 -0
  362. /package/dist/app/chunks/{dart-6Y3X27SZ.js → dart-FO4TTVO2.js} +0 -0
  363. /package/dist/app/chunks/{diff-TR2NPA64.js → diff-SHANV4YC.js} +0 -0
  364. /package/dist/app/chunks/{dist-T32U2VVR.js → dist-WSDF34DM.js} +0 -0
  365. /package/dist/app/chunks/{docker-N33HOW54.js → docker-VX55HTDS.js} +0 -0
  366. /package/dist/app/chunks/{go-6DGG5UTP.js → go-5UCPEC6S.js} +0 -0
  367. /package/dist/app/chunks/{haskell-KK36PMMM.js → haskell-25PJ3OSG.js} +0 -0
  368. /package/dist/app/chunks/{ini-VHVQ5TPB.js → ini-BJIVD5MK.js} +0 -0
  369. /package/dist/app/chunks/{kotlin-44WS3JHE.js → kotlin-MNR6XOEQ.js} +0 -0
  370. /package/dist/app/chunks/{less-5WZ3KLAK.js → less-KA5JURX6.js} +0 -0
  371. /package/dist/app/chunks/{light-plus-HGGBC43G.js → light-plus-QXH2UUWZ.js} +0 -0
  372. /package/dist/app/chunks/{make-X7RXMVW7.js → make-LPD5KOCO.js} +0 -0
  373. /package/dist/app/chunks/{markdown-46IKUAIB.js → markdown-LMWF6MQR.js} +0 -0
  374. /package/dist/app/chunks/{mdx-DGLHDAO7.js → mdx-WPMNN5BS.js} +0 -0
  375. /package/dist/app/chunks/{nix-Q6FYQZLX.js → nix-QGWLUUMZ.js} +0 -0
  376. /package/dist/app/chunks/{powershell-L4KJJ6DK.js → powershell-7GSBBEFF.js} +0 -0
  377. /package/dist/app/chunks/{prisma-IKS4LVH2.js → prisma-FPMPQISO.js} +0 -0
  378. /package/dist/app/chunks/{proto-AYCDOTJO.js → proto-7KDX5Z2U.js} +0 -0
  379. /package/dist/app/chunks/{python-KXMCSAFQ.js → python-CFG4FTQW.js} +0 -0
  380. /package/dist/app/chunks/{rust-J3BC3P6V.js → rust-X7A37WU3.js} +0 -0
  381. /package/dist/app/chunks/{scala-AYIIHBJK.js → scala-OYHJSUG2.js} +0 -0
  382. /package/dist/app/chunks/{swift-QPHHCQD3.js → swift-PE7VNYW5.js} +0 -0
  383. /package/dist/app/chunks/{toml-UV7JK7K7.js → toml-ETQRDILP.js} +0 -0
@@ -10,7 +10,7 @@ activation:
10
10
 
11
11
  ## Discovery and identity
12
12
 
13
- 1. **Search before you create.** Run semantic and live `grep` in parallel and reconcile by URI: semantic finds meaning, grep avoids index lag. Check for duplicates first.
13
+ 1. **Search before you create.** Pair semantic search with live `grep`, reconcile by URI and check `effective_mode`/embedding freshness: fallback text or retained vectors can miss meaning; grep avoids index lag. Check duplicates first.
14
14
  2. **Files are URIs.** Use source URIs such as `data://…`; never expose internal UUIDs or invent schemes. `<runtime_stack>` names configured sources; `os://` entries are labels, not sources.
15
15
  3. **Prefer scoped reads.** Batch small files; range-read a large one (a truncation marker means you did not see it all — `tool-use` owns that). Scope listings to a source/folder; use connector reads or grep when the index is cold.
16
16
  3b. **The ladder, once:** `fs_list` = the SHAPE of a place you can name · `fs_search` = FINDING one you cannot · `fs_read` = the CONTENT once you can · `execute` = when you need a PROGRAM, never because you skipped the three. `<runtime_stack>` `data_areas` names where each package keeps its files; start there.
@@ -36,8 +36,10 @@ retention and indexing behavior.
36
36
 
37
37
  1. **Files or an authorised export** (CSV/XLSX/JSON/PDF, a folder, an approved dump) → attach an
38
38
  existing source kind. This is the cheapest path.
39
- 2. **A live API, MCP server or OpenAPI service** → use an existing outbound integration or build a
40
- source connector when searchable filesystem semantics are required. An outbound connector belongs
39
+ 2. **A live API, MCP server or OpenAPI service** → an existing outbound integration first, then the
40
+ vendor's official skill, MCP server or plugin (create-package
41
+ `references/connectors-and-uri-policies.md` §The headline); build a source connector only when
42
+ neither exists or searchable filesystem semantics are required. An outbound connector belongs
41
43
  to ONE tenant — the platform lane for a first-party install, otherwise the owning project — so
42
44
  the set you can see is the platform lane plus your own project, and an id from another project
43
45
  answers the same generic `404` as a typo. Its write surface is admin-gated: listing rides
@@ -100,8 +102,8 @@ sync lifecycle; do not work around it by pasting the corpus into memory.
100
102
  - `manage-uri-policy` — per-path governance.
101
103
  - `create-package` — connector, skill, tool and workflow authoring around governed sources.
102
104
  - `create-package/references/connectors-and-uri-policies.md` — source and connector contract.
103
- - https://docs.neuralisapp.com/docs/package-system/connectors
104
- - https://docs.neuralisapp.com/docs/package-system/uri-policies
105
+ - https://docs.neuralisapp.com/package-system/connectors
106
+ - https://docs.neuralisapp.com/package-system/uri-policies
105
107
 
106
108
  ## Close the loop
107
109
 
@@ -23,7 +23,9 @@ argument.
23
23
 
24
24
  **One caveat:** activation happens through the `execute` tool and nowhere else — an agent without
25
25
  `execute` reads a skill's description and cannot run it. If the capability must work for such an
26
- agent, it is a tool, a route or a rule.
26
+ agent, it is a tool, a route or a rule. **And every capability a human gets has its agent path in
27
+ the same package** — a route the skill's script calls, or a tool, behind the same gate; a button only
28
+ a human can press is half a capability.
27
29
 
28
30
  ## Golden rules
29
31
 
@@ -52,14 +54,14 @@ ADD to it rather than replace it; shipping several kinds together is the stronge
52
54
  system — a governed tool plus a skill teaching the craft of driving it.
53
55
 
54
56
  1. **Knowledge, procedure, judgment, or a checklist?** → **SKILL.** The default; most requests.
55
- 2. **Does the platform already reach it?** (Step 0 — sources and MCP too.) An `{ type: "mcp" }` connector is zero code and zero schema — the external server's tool list simply becomes available.
57
+ 2. **Does the platform already reach it?** (Step 0 — sources and MCP too; then the vendor's OFFICIAL skill, MCP server or plugin, imported before you write anything — `references/connectors-and-uri-policies.md` §The headline.) An `{ type: "mcp" }` connector is zero code and zero schema — the external server's tool list simply becomes available.
56
58
  3. **Must it run on a schedule or a trigger — "weekly", "every morning", "when a ticket lands"?** → **WORKFLOW template** (`workflows/*.json`) carrying the instruction, usually invoking the skill from #1. A skill alone fires only when someone asks; the schedule is what makes it run by itself.
57
59
  4. **A separate persona running in its own forked context with a restricted tool set?** → **AGENT file** (`agents/*.md`) — the one place `allowed-tools` is genuinely *enforced*, filtering the child's tools. Leave it out for a universal role (the child inherits what the caller can reach); write `allowed-tools: []` for a persona that must hold no tools at all.
58
60
  5. **Must every turn obey it, unconditionally, even when nothing triggered it?** → **RULE.** The most expensive slot in the system. Budget: one rule file per package, under 4 KB, unconditional behaviour only; anything domain-conditional is a skill or a doc.
59
61
  6. **Do you need one of four things a skill structurally cannot give you?** → **TOOL.** *Schema enforcement* — arguments validated before your handler runs, invalid calls rejected. *Permission gating* — a `requires.features` gate that both hides and rejects, a risk category driving approval posture, per-trust rate limits. *Determinism* — skill composition is non-deterministic; if correctness depends on it happening, it is a tool, a script or a hook, never prose asking the model to be careful. *A designed surface* — a card, a widget, or an app a human looks at repeatedly.
60
62
  7. **An external corpus of files or records to search?** → **GOVERNED CONNECTOR / source** — establish owner, approved location, audience/scope, sensitivity/retention, credential scope, copy permission and provenance first. Attach it as a configured source; never put the dataset in identity or memory. Skills, tools and workflows wrap the source and point to its URIs.
61
63
  8. **An AI coworker with an identity, a persona and evolving memory?** → **TEAM MEMBER.**
62
- 9. **Does a human look at it, repeatedly?** → **WIDGET + dock companion** (a standing panel) or **CARD** (the result of one tool call).
64
+ 9. **Does a human look at it, repeatedly?** → **WIDGET + dock companion** (a standing panel) or **CARD** (the result of one tool call). A tool whose result a human reads gets a card by default; the visual precedent is the platform's own cards (execute, todos, workflow) on the `CardShell` exported from `@neuralis/agent-core/app/chat`.
63
65
 
64
66
  **Corollaries.** Split read from write into separate tools — the approval floor is per-tool and never reads an argument's VALUE, so an `action` enum makes the destructive case ungateable; verbs sharing one posture go on one tool as keys, and a rare destructive verb inside that posture is gated by declaring its root key in `x-neuralis.askOnKeys` (`references/tools-and-schemas.md` §2, which also owns description craft — the callable contract there, the procedure in a skill). `allowed-tools` is enforced on agent files (absent = inherit, `[]` = nothing), advisory on skills — this one included.
65
67
 
@@ -145,9 +147,9 @@ a drop is rescanned in about half a second and source markdown needs no install
145
147
 
146
148
  **Where your files go.** A drop: `fs_write({ uri: "packages://<dir>/package.json", create: { content } })` — that URI
147
149
  is the project's `_packages/` folder, parent dirs made for you. The `packages://` path segment is
148
- the DIRECTORY name, never the registry id: a loaded drop registers under the namespaced id
149
- `p.<project>.project.<dir>`, which is what `verify-loaded.sh` and the trust/enable routes take,
150
- while every path stays `packages://<dir>/…`. An installed package's folder is
150
+ the DIRECTORY name, never the registry id: a loaded drop's id is the instance URI
151
+ `packages://<dir>?project=<p>&scope=project` (`<packages>` shows it short,
152
+ `packages://<dir>`), while every path stays `packages://<dir>/…`. An installed package's folder is
151
153
  replaced wholesale on every update: treat it read-only and **report** a defect in a shipped file
152
154
  instead of patching it. Skills, rules, instructions, agents and docs you created or downloaded live
153
155
  where you own them — improve those in place, never weakening a security rule you find there.
@@ -156,7 +158,7 @@ where you own them — improve those in place, never weakening a security rule y
156
158
 
157
159
  **Address it.** A source slug is its own URI scheme, so a source package lives at `<slug>://<path>`:
158
160
  a skill at `data://acme/skills/release-notes/SKILL.md` makes `data://acme` a package carrying one
159
- skill, id `source:data://acme`. Every project seeds two writable local sources, `data://` and
161
+ skill, id `data://acme?project=<p>&scope=project`. Every project seeds two writable local sources, `data://` and
160
162
  `packages://`. Only the `<runtime_stack>` `sources` list has paths and permissions: `policy=` is your
161
163
  own read/write/exec, `os_uri=` the host path, `container=` the shell's path — printed only when the
162
164
  source has one; absent, cwd the URI itself (`cwd: "data://acme"`). `fs_list` with no `uri` gives
@@ -182,8 +184,8 @@ around the gate — ask: files on disk, `drive.sync` named, Files widget → Sou
182
184
  **Sync** offered, in the words `references/test-and-ship.md` prescribes.
183
185
 
184
186
  Reach paths in full:
185
- <https://docs.neuralisapp.com/docs/package-system/directory-contract> ·
186
- <https://docs.neuralisapp.com/docs/package-system/source-packages>
187
+ <https://docs.neuralisapp.com/package-system/directory-contract> ·
188
+ <https://docs.neuralisapp.com/package-system/source-packages>
187
189
 
188
190
  ## What you can reach right now
189
191
 
@@ -255,7 +257,7 @@ bash ${SKILL_DIR}/scripts/verify-loaded.sh <package-id> # any path,
255
257
  everything; with **none** it runs markdown mode — package recognition, the categories, every
256
258
  frontmatter gate — then prints the manifest/tools/workflows/surfaces/runtime/dist checks it skipped,
257
259
  so no skip reads as a pass. `verify-loaded.sh` covers all three paths (for (c) pass
258
- `source:<rootUri>`) and reads package diagnostics, so it needs `core.observe` — lacking that it
260
+ `<rootUri>?project=<p>&scope=…`) and reads package diagnostics, so it needs `core.observe` — lacking that it
259
261
  reports it could not reach them rather than claiming the package is absent.
260
262
 
261
263
  **Enable, trust, install and rescan apply from the NEXT stream.** A stream captures the set of
@@ -279,8 +281,8 @@ a fresh stream before re-diagnosing.
279
281
  package restating its own README is the README with extra steps. Report the byte delta of the
280
282
  prose you changed and any growth's reason.
281
283
 
282
- Full reference: <https://docs.neuralisapp.com/docs/package-system/create-a-package> · worked
283
- examples, one per reach path: <https://docs.neuralisapp.com/docs/package-system/reference-package>.
284
+ Full reference: <https://docs.neuralisapp.com/package-system/create-a-package> · worked
285
+ examples, one per reach path: <https://docs.neuralisapp.com/package-system/reference-package>.
284
286
 
285
287
  The registry is real and readable: §11 of `references/test-and-ship.md` has the read rows (Tier A
286
288
  `/content` plain text, Tier B `/document` JSON) and the operator's publish procedure. The public
@@ -122,7 +122,7 @@ set -euo pipefail
122
122
  curl -sS -H "Authorization: Bearer $WEATHER_API_KEY" "https://api.weather.example/v1/forecast?q=$1"
123
123
  ```
124
124
 
125
- On activation the host resolves each declared id at the caller's real `(userId, projectId, agentId)` scope. **The model never sees a resolved value.**
125
+ On activation the host resolves each declared id at the caller's real `(userId, projectId, agentId)` scope, within the caller's tier ceiling: own user key always; agent and project keys with `project.credentials.write`; global with `platform.scope` too. A tier above it reads as missing, so a member's run needs the member's own key (`credentials.self`). **The model never sees a resolved value.**
126
126
 
127
127
  - **`credentials:` must be a list of plain strings.** A scalar or a list of objects is dropped silently by the whitelist frontmatter parser: the skill activates normally, the catalog shows no ids, and your script exits on the `${VAR:?…}` guard with no parse error anywhere.
128
128
  - **A missing value is non-fatal.** The id lands on a `missing` list, the rendered body carries a `(missing: <id>)` marker, and no variable is set — which is why scripts should fail with a message pointing the user at the Credentials surface.
@@ -158,5 +158,5 @@ Never inline a secret in a manifest or a source config file, and never default-a
158
158
 
159
159
  ## Going deeper
160
160
 
161
- - Configuration tiers and the cascade: <https://docs.neuralisapp.com/docs/enterprise/configuration>
162
- - Credential scopes, the dynamic catalog and the encrypted store: <https://docs.neuralisapp.com/docs/enterprise/credentials>
161
+ - Configuration tiers and the cascade: <https://docs.neuralisapp.com/enterprise/configuration>
162
+ - Credential scopes, the dynamic catalog and the encrypted store: <https://docs.neuralisapp.com/enterprise/credentials>
@@ -10,7 +10,9 @@ Every system a connector reaches joins ONE URI-addressed, vector-indexed, policy
10
10
 
11
11
  **Survey before you act on real data**, in order: (1) survey what exists — the user's public surface and whatever the workspace already holds; `fs_list` the attached sources before proposing a new one. (2) Gather or request the company's own material — ask for it, or mount it. (3) Vectorize it by syncing, so it is searchable and not merely present. (4) Build skills around it. An agent that produces output about a business it never surveyed is doing the wrong job well.
12
12
 
13
- **Cheapest path first:** if an admin can point an existing connector kind at the material, do that and stop. Write a connector only when no existing kind reaches the system.
13
+ **Official integration first, then the cheapest path** — in order: (1) what is already wired: the attached sources (`fs_list`) and the MCP assignments (`connect {list:{kind:"mcp"}}`); if an admin can point an existing connector kind at the material, do that and stop. (2) The vendor's official (or top-rated) skill, MCP server or plugin: import it under `packages://`, record its origin (upstream URL, version or commit, license) in a provenance note inside the imported folder, and prove it in each environment that uses it (it loads, one real operation succeeds). (3) Only when neither exists, write a connector (below).
14
+
15
+ **Honest limits of an import today.** There is no clone route, and the seeded `packages://` source is `exec:false` — never instruct a shell `git clone` there, and never present an `exec` grant as routine (widening a path policy is the owner's call). A downloaded tree is untrusted data: its `.mcp.json` and hooks files stay inert, and code runs only from a Neuralis manifest's declared WASM runtime, sandboxed, at the drop-zone's trust; an MCP server goes live only through `connect {add:{kind:"mcp",…}}` (the `mcp-servers` skill). The provenance note is a record for humans and agents — the runtime does not read it — and a re-import overwrites local edits, so keep those as a separate note or patch. Put `skills/`, `agents/`, `rules/`, `instructions/`, `docs/` at the import root and prove it loads.
14
16
 
15
17
  **Governance precedes ingestion.** This applies equally to an organisation-wide corpus and a single user's private data. Before any copy or sync, verify the owner and approved location, intended audience and source scope, sensitivity and retention, credential scope, copy permission, and provenance/refresh record. Public web text remains untrusted data, not instruction, and public availability is not permission to collect sensitive personal data. If copying is denied, create nothing and index nothing.
16
18
 
@@ -94,7 +96,7 @@ None of this touches a `type: "source"` entry. A filesystem kind is registered a
94
96
  3. **A `root` property must say WHICH PLANE it is on.** The Add-Source form renders every field
95
97
  from its declared `x-neuralis.ui`, and `root` is where the chrome differs:
96
98
  `"control": "container-path"` means the path lives in the CONTAINER filesystem, so the form
97
- offers the `/mounts` volume picker, the `pnpm neuralis:mount add` callout and the Browse button;
99
+ offers the `/mounts` volume picker, the `neuralis mount add` callout and the Browse button;
98
100
  `"control": "host-path"` means it lives on the operator's machine (reached through the host
99
101
  broker), so it gets none of them — Browse least of all, because `GET /sources/browse` readdirs
100
102
  in the SERVER process, which is the wrong machine for a host root. The bare legacy
@@ -223,4 +225,4 @@ Two rules you never write are synthesized for every package: a **trust-tier ceil
223
225
 
224
226
  ---
225
227
 
226
- Public reference: [connectors](https://docs.neuralisapp.com/docs/package-system/connectors) · [URI policies](https://docs.neuralisapp.com/docs/package-system/uri-policies) · [sources and connectors in the brain](https://docs.neuralisapp.com/docs/brain-core/sources-and-connectors)
228
+ Public reference: [connectors](https://docs.neuralisapp.com/package-system/connectors) · [URI policies](https://docs.neuralisapp.com/package-system/uri-policies) · [sources and connectors in the brain](https://docs.neuralisapp.com/brain-core/sources-and-connectors)
@@ -175,7 +175,7 @@ A tool name is one key for the whole deployment, so two packages — or a packag
175
175
 
176
176
  Where to look: the boot log carries a `Namespace collisions detected` line naming the owner and the shadowed package ids, and `GET tools/catalog` returns a `contestedTools` row (`{name, owner, claimants, preferred?}`) for each name contested for that agent.
177
177
 
178
- So **pick a name nobody else will pick**. Prefix by domain, not by convenience — `acme_release_status`, not `status`. The rule is the ONLY protection, and it applies to every install class alike: the platform's own packages, an admin's `pnpm neuralis:pkg add`'ed dependency and a project `_packages/` drop all fight for the same key. Trust decides who WINS the fight, never whether there is one — a host dependency is stamped `first-party` by the host regardless of its scope, so `@acme/*` next to `@neuralis/*` is a lexical tie-break, not a rescue. Nothing anywhere refuses to start over a collision: a taken name shadows, it never takes the deployment down.
178
+ So **pick a name nobody else will pick**. Prefix by domain, not by convenience — `acme_release_status`, not `status`. The rule is the ONLY protection, and it applies to every install class alike: the platform's own packages, an admin's `neuralis pkg add`'ed dependency and a project `_packages/` drop all fight for the same key. Trust decides who WINS the fight, never whether there is one — a host dependency is stamped `first-party` by the host regardless of its scope, so `@acme/*` next to `@neuralis/*` is a lexical tie-break, not a rescue. Nothing anywhere refuses to start over a collision: a taken name shadows, it never takes the deployment down.
179
179
 
180
180
  ## `dataLayout` — say where you keep your files
181
181
 
@@ -183,7 +183,7 @@ So **pick a name nobody else will pick**. Prefix by domain, not by convenience
183
183
  "dataLayout": { "directories": ["cache", "state"] }
184
184
  ```
185
185
 
186
- If your package writes under its own `data://` zone, declare the first-level directory names — this is the ONE channel through which a fresh delegate (no `<workspace>`, no identity file) learns the layout exists: every agent's `<runtime_stack>` carries a `data_areas` row per visible package, built from this field alone. Names only, never descriptions or paths; `agentDirectories` is the per-agent variant (`<zone>/<agentId>/<name>/`) for a package that keys a subtree by agent id. The validator is fail-closed: a `..`, a separator, a placeholder, a brace, whitespace or a duplicate rejects the WHOLE manifest. Your zone root is `data://<slug>/` for a first-party package and `data://_installed/<slug>/` for every other install class — never `data://<id>/`. An empty declaration renders no row.
186
+ If your package writes under its own `data://` zone, declare the first-level directory names — this is the ONE channel through which a fresh delegate (no `<workspace>`, no identity file) learns the layout exists: every agent's `<runtime_stack>` carries a `data_areas` row per visible package, built from this field alone. Names only, never descriptions or paths; `agentDirectories` is the per-agent variant (`<zone>/<agentId>/<name>/`) for a package that keys a subtree by agent id. The validator is fail-closed: a `..`, a separator, a placeholder, a brace, whitespace or a duplicate rejects the WHOLE manifest. Your zone root is never `data://<id>/`: `data://<slug>/` for `@neuralis/<slug>`, `data://runtime/_npm/<npm id>/` for another npm install, and for a project instance its id's mirror, `data://runtime/<scheme>/<path>/` (`packages://acme` → `runtime/packages/acme`). An empty declaration renders no row.
187
187
 
188
188
  `"machineWritten": [{ "path": "*/stats/*.json", "class": "metrics" }]` (inside `dataLayout`) names the files your package writes on its own — never rendered into the prompt. `path` is a glob relative to your zone (`*` one segment, `**` any depth; a leading `/`, an empty or `..` segment, or any character outside `[A-Za-z0-9._*-]` rejects the manifest); `class` is `metrics` (numbers only), `log` or `runtime-text` (runtime state a person may search for). A NEW project's `data` source leaves `metrics` files out of its index from the start; existing projects keep their settings. Declarations from untrusted packages are ignored.
189
189
 
@@ -208,6 +208,7 @@ A package the host installs as a dependency can declare the moments a person sho
208
208
 
209
209
  - **`requires.features` is required** — name the feature of the route that serves the same record. A reader without it never receives the event, whatever your predicate says.
210
210
  - **`dock`** is the id of one of your OWN `kind: "dock"` surfaces; its badge counts the unread notifications.
211
+ - **`notify.clears`** (optional) lists your OWN event ids this one resolves — a `…recovered` that clears `…failed`. When it reaches a reader allowed to see it, their unread rows of those types about the SAME `subjectId` are marked read (kept in history), even if they muted the recovery itself. Never the event itself, never another package's id.
211
212
  - **Each `subject` needs `src/events/<subject>.ts`** (compiled to `dist/src/events/`): `export const subject`, a REQUIRED `visible(event, session, state)` answering whether this person may see an event about that subject — no file means every event of the subject is dropped — and an optional `bridge(publish, state)` that subscribes to your own internal bus, calls `publish({ event, subjectId, projectId, data, audience })` and returns its unsubscribe.
212
213
  - **An event is a signal, never content.** `data` holds ids and fixed codes, validated against `dataSchema` (a closed object, at most 4 KiB) — never an error message, a path or a transcript. The platform stamps `type` and `source` from your package, so you cannot emit another package's events, and a publish that breaks the schema throws.
213
214
  - **Two optional `data` keys shape the notification row** when your `dataSchema` declares them: `title` (a string, shown before the declaration title) and `nav` (`{ "widgetType": "<a widget>", "initialState": { … } }`, the row's navigation target). Without them the row shows the declaration title alone.
@@ -230,4 +231,4 @@ A malformed **hook** is skipped with a warning and the package still loads. A ma
230
231
 
231
232
  When nothing appears at all, re-check the two silent ones first: the `files` whitelist, and a category-folder markdown file with no `id`/`name`.
232
233
 
233
- Public reference: <https://docs.neuralisapp.com/docs/package-system/manifest> and <https://docs.neuralisapp.com/docs/package-system/directory-contract>.
234
+ Public reference: <https://docs.neuralisapp.com/package-system/manifest> and <https://docs.neuralisapp.com/package-system/directory-contract>.
@@ -62,11 +62,11 @@ export function api(state: NotesState) {
62
62
  - **Peer lookups belong in `onBootstrapComplete(state, ctx)`** — it fires once after every package's `init` and `start` have resolved. Elsewhere load order is not guaranteed: `getPackageApi()` returns `undefined` intermittently, fine on one boot, silently degraded on the next. From a non-first-party package `undefined` may also be a trust **denial** (audited `denied:untrusted` / `denied:trust-mismatch`), not a missing package.
63
63
  - **`onPrincipalRevoked(state, event)` closes; it never decides.** The host calls it when a user is disabled, deleted or has their sessions reset (no `event.projectId`), or loses one project (`membership_removed` / `project_archived`, with `projectId`). Stop what you hold open for `event.userId` — sockets, running jobs, pollers — through your existing stop, and return promptly: the call is bounded by a timeout, and the user is already refused everywhere else, so never re-check access here. Only a host-installed package's lifecycle runs at all; a `_packages/` drop never receives it.
64
64
 
65
- **`init` receives** `selfId`, `selfTrust`, `data { dataDir, globalDir?, fileStore<T>, jsonlAppender<T>, dataPath, logger }`, `host { id }`, `packages { isLoaded, getPackageApi<T> }`, `credentials?`, `sessions? { createProjectFactory }`, `config { get }`, lazy `platform` facts, first-party `hostPorts`, `logger`. Platform facts throw before publication and are read where used; bootstrap completion receives the same `platform`, rather than copied aggregates. `dataDir` is **per project**: `<projectsRoot>/<projectId>/data/<packageSlug>/`, mode `0700`, with `logs/`. First-party packages (host-installed, `@neuralis/*` and the deploy's own deps) additionally receive `data.globalDir` — a project-independent platform home under the app zone, where their process-global state and their `logs/` live; a project-installed package like yours has NO `globalDir` (its state is project data by nature), and `ctx.data.globalDir` is `undefined` for it.
65
+ **`init` receives** `selfId`, `selfTrust`, `data { dataDir, globalDir?, fileStore<T>, jsonlAppender<T>, dataPath, logger }`, `host { id }`, `packages { isLoaded, getPackageApi<T> }`, `credentials?`, `sessions? { createProjectFactory }`, `config { get }`, lazy `platform` facts, first-party `hostPorts`, `logger`. Platform facts throw before publication and are read where used; bootstrap completion receives the same `platform`, rather than copied aggregates. `dataDir` is **per project**: `<projectsRoot>/<projectId>/data/<zone>/`, mode `0700`, with `logs/`. First-party packages (host-installed, `@neuralis/*` and the deploy's own deps) additionally receive `data.globalDir` — a project-independent platform home under the app zone, where their process-global state and their `logs/` live; a project-installed package like yours has NO `globalDir` (its state is project data by nature), and `ctx.data.globalDir` is `undefined` for it.
66
66
 
67
67
  **Write through `dataPath`, and hold ONE appender.** `jsonlAppender()` takes a RESOLVED path, not a string — `ctx.data.dataPath('events.jsonl')` produces one, and it refuses anything that would leave your own data dir (an absolute path, or a relative one that climbs out), so you cannot write into a sibling package's data by accident. The APPENDER creates any missing intermediate directories when it writes; `dataPath` itself only resolves, so if you hand its result to your own `fs` call the directories are yours to create. Keep ONE appender for the life of the package: its write ordering is per-instance, so a fresh one per call gives up the guarantee that entries written together stay together. (The WASM guest plane's `ctx.data.*` also takes paths relative to the package data dir, but REPORTS failure as `{ ok: false, error }` instead of throwing — its answers cross into guest memory and carry a fixed code, never a filesystem path. Do not merge the two contracts in your head.)
68
68
 
69
- **The logger is levellable and append-only.** `ctx.data.logger` is a `PackageLogger` already pointed at `<dataDir>/logs/` (for a first-party package: `<globalDir>/logs/`); it resolves its level at every CALL — your package's entry in the operator's `packageLogLevelOverrides` (keyed on the `pkg` field of your log lines: `_installed/<your-slug>` for a project package, the bare name for a first-party one) → the global `packageLogLevel` → `debug`. Both are platform keys; your manifest declares nothing for them. Never cache `logger.level` in a constructor: the level is live, so a captured value stays pinned after an administrator edit. Every line is appended (O(1)), so the file is OLDEST-first: read "the newest N" with `JsonlAppender.readNewest(path, n)` (`@neuralis/package-system/data`), which takes the tail and then the rotated `.1`, `.2` … generations — never the first lines.
69
+ **The logger is levellable and append-only.** `ctx.data.logger` is a `PackageLogger` already pointed at `<dataDir>/logs/` (for a first-party package: `<globalDir>/logs/`); it resolves its level at every CALL — your package's entry in the operator's `packageLogLevelOverrides` (keyed on the `pkg` field of your log lines: your zone path, `runtime/packages/<dir>` for a drop, the bare name for `@neuralis/*`) → the global `packageLogLevel` → `debug`. Both are platform keys; your manifest declares nothing for them. Never cache `logger.level` in a constructor: the level is live, so a captured value stays pinned after an administrator edit. Every line is appended (O(1)), so the file is OLDEST-first: read "the newest N" with `JsonlAppender.readNewest(path, n)` (`@neuralis/package-system/data`), which takes the tail and then the rotated `.1`, `.2` … generations — never the first lines.
70
70
 
71
71
  `onCredentialChanged(state, event)` receives `{credentialId, scope, change}` after a write or delete; re-resolve a changed secret through `ctx.credentials`, never through the event. `drain(state)` finishes or checkpoints work before `stop`, and `health(state)` returns structured checks with closed status/reason values. Runtime fan-outs are bounded. A first-party package exposes its declared `provides` implementations on the state returned by standalone `init(ctx)`. The discovered adapter retains `state.services` as `PackageRuntimeApi.services`, separately from the public `api(state)`; the host resolves them by contract id.
72
72
 
@@ -166,11 +166,11 @@ wrappers over brain-core's `read`/`list`/`search`/`write` routes
166
166
  (`create`/`overwrite`/`edit`/`insert`/`lines`/`fields`/`move`/`copy`/`mkdir`/`revert`/`delete`). The route CATALOG —
167
167
  which routes exist and which feature each needs — lives on the per-package
168
168
  "API &amp; usage" docs pages:
169
- <https://docs.neuralisapp.com/docs/agent-core/api-usage> ·
170
- <https://docs.neuralisapp.com/docs/brain-core/api-usage> ·
171
- <https://docs.neuralisapp.com/docs/admin/features-and-routes> ·
172
- <https://docs.neuralisapp.com/docs/machine-core/api-usage> — mechanism:
173
- <https://docs.neuralisapp.com/docs/package-system/routes>.
169
+ <https://docs.neuralisapp.com/agent-core/api-usage> ·
170
+ <https://docs.neuralisapp.com/brain-core/api-usage> ·
171
+ <https://docs.neuralisapp.com/admin/features-and-routes> ·
172
+ <https://docs.neuralisapp.com/machine-core/api-usage> — mechanism:
173
+ <https://docs.neuralisapp.com/package-system/routes>.
174
174
 
175
175
  `callRoute` denials return `{ ok: false, error: '…' }` rather than throwing — a
176
176
  handler that ignores the `ok` flag looks like it succeeded.
@@ -275,7 +275,7 @@ platform's own packages and links them for you.
275
275
  a `build` script (and `build:ui` → `neuralis-build ui` when you declare `app.module`), `files[]`
276
276
  naming every first-level runtime folder, the kernel as a peer, and **no `link:`/`file:` spec that
277
277
  leaves your directory** — a devDependency `link:` into a Neuralis checkout beside yours cannot
278
- resolve inside the build, and `pnpm neuralis:pkg add --path` refuses it with the spec named. If your
278
+ resolve inside the build, and `neuralis pkg add --path` refuses it with the spec named. If your
279
279
  package manager installs peers automatically, a standalone install of your repository reaches for
280
280
  the kernel; with pnpm, `autoInstallPeers: false` in your own `pnpm-workspace.yaml` keeps it local.
281
281
  `pkg add` also runs the runtime's own admission check on the directory before it writes anything —
@@ -362,4 +362,4 @@ Hooks are declared in one package-root `hooks.json` shaped `{ "hooks": [ … ] }
362
362
 
363
363
  ---
364
364
 
365
- Public reference: [routes](https://docs.neuralisapp.com/docs/package-system/routes) · [lifecycle](https://docs.neuralisapp.com/docs/package-system/lifecycle) · [sessions](https://docs.neuralisapp.com/docs/package-system/sessions) · [sandboxed package build](https://docs.neuralisapp.com/docs/package-system/wasm-build)
365
+ Public reference: [routes](https://docs.neuralisapp.com/package-system/routes) · [lifecycle](https://docs.neuralisapp.com/package-system/lifecycle) · [sessions](https://docs.neuralisapp.com/package-system/sessions) · [sandboxed package build](https://docs.neuralisapp.com/package-system/wasm-build)
@@ -138,8 +138,8 @@ execution: the activation envelope can supply a directory URI for an exec-capabl
138
138
  that URI with a relative script, and never pass the sentinel as `cwd`.
139
139
 
140
140
  **Authenticating back to the platform from app/host execution:** the script carries a
141
- per-stream `NEURALIS_SESSION_TOKEN`, holding the caller’s real identity, re-minted per call. Use it. The ticket authenticates ONLY package routes under `/api/packages/<package-id>/…`; host-level `/api/*` routes (projects, auth, admin) reject it by design. **Never invent a bearer token and never ask the user for one.** `credentials:` is for **external** secrets only — each entry is both the credential-store id and the env-var name projected into the child process. A miss is non-fatal: it renders `(missing: <id>)` and is reported in the activation result, and the model never sees a value. **Credentials pushed by an activation are conversation-scoped and outlive the turn**;
142
- app/host shell calls receive the union of still-active skills. Clear them with
141
+ per-stream `NEURALIS_SESSION_TOKEN`, holding the caller’s real identity, re-minted per call. Use it. The ticket authenticates ONLY package routes under `/api/packages/<package-id>/…`; host-level `/api/*` routes (projects, auth, admin) reject it by design. **Never invent a bearer token and never ask the user for one.** `credentials:` is for **external** secrets only — each entry is both the credential-store id and the env-var name projected into the child process. A miss is non-fatal: it renders `(missing: <id>)` and is reported in the activation result, and the model never sees a value. **Credentials pushed by an activation are scoped to the conversation and the caller, and outlive the turn**;
142
+ app/host shell calls receive the union of the caller's still-active skills. Clear them with
143
143
  `args.deactivate=true`. **Connector execution receives no platform ticket, credential env or
144
144
  non-secret substitution env**, and a provider may refuse caller `env` or background execution
145
145
  entirely — never promise that a platform-authenticated script runs there unchanged.
@@ -345,4 +345,4 @@ Two parsers run on the same file: **discovery** keeps every top-level key, **act
345
345
 
346
346
  ---
347
347
 
348
- Full public reference: **https://docs.neuralisapp.com/docs/package-system/skills** — and the five-category contribution contract at **https://docs.neuralisapp.com/docs/package-system/contributions**.
348
+ Full public reference: **https://docs.neuralisapp.com/package-system/skills** — and the five-category contribution contract at **https://docs.neuralisapp.com/package-system/contributions**.
@@ -176,6 +176,7 @@ Host CSS custom properties (`--color-text`, `--w-bg-rgb`, `--icon-accent`, `--co
176
176
  - **Never override workspace chrome** (dock, panel headers, resize handles) or ship a per-component scrollbar override — one overlay-scrollbar rule with a stable gutter already covers it. Stay inside your panel's stacking context: the panel establishes one for you (`isolation: isolate`, at every transparency level), so your `z-index` values are scoped to your own surface and can never outrank the dock or the workspace's loading scrim. Do not try to escape it with a large `z-index`.
177
177
  - **A `position: fixed` overlay MUST `createPortal(…, document.body)`.** The panel emits a `backdrop-filter` at `dim` and at `opaque` (the latter is load-bearing and stays), none at `transparent` — and a filter makes the panel a containing block for `fixed` descendants, so at two of the three levels a `fixed` overlay anchors to your PANEL and is clipped to its rounded box, while at `transparent` it anchors to the viewport. The panel's `position: relative` covers `absolute` but never `fixed`. Symptom of skipping the portal: your modal is a widget-sized, corner-clipped rectangle for one user and a full-screen overlay for the next, purely because they cycled transparency. Portalling fixes it at **all three** levels, and `absolute` overlays need no portal at all. **One exception — a click-outside catcher for a popover that stays INSIDE the panel:** do not portal a scrim for it. The popover lives in the panel's isolated stacking context, so a body-level scrim paints over the popover and swallows its clicks; use a capture-phase `mousedown` listener on `document` that ignores targets inside the popover's zone instead — it needs no element, covers the real viewport, and closes on a click outside the widget too.
178
178
  - **No idle infinite animation** — it burns frames and breaks automated click stability. Inside the chat timeline — and inside ANY virtualized row your package renders, a file-tree row included — the rule is harder and it has no exception for "but it is still running": **a card in a timeline row must not animate `transform`, `opacity`, `filter`, `background-color` or `clip-path` at all — live or settled.** Those are the properties the browser accelerates, and they are exactly what a utility class like `animate-spin` or `animate-pulse` compiles to: the element becomes its own compositor layer, every row painted after it is pushed into another, and a fast wheel fling presents those layers at different generations (a glyph floating between rows, the next row drawn inside your card). A long-running tool multiplies it — several cards animating for minutes is several layers for minutes. A spinner still belongs to the tool call while it runs, but express it with something the compositor does not accelerate. The platform's own Files tree obeys the same floor — its virtualized rows import these primitives instead of an `animate-*` utility. **A `direct` card should not roll its own:** `@neuralis/agent-core/app/chat` exports the four live-motion primitives the platform's own cards use — `LiveSpinner` (a rotating arc), `LivePulseDot` (a pulsing status dot), `LiveCursor` (a streaming text caret) and `LivePulseText` (a pulsing line of text). Each takes its size and colour from `className` alone, so it drops into your layout at the box you give it (pass a `text-…` colour to the two that paint a shape — they fill with `currentColor`, not a background). If you do build your own, the mechanisms that work are SVG SMIL (`<animateTransform>`, or `<animate>` on `fill-opacity`, neither of which the compositor accelerates — note that element `opacity` DOES accelerate and `fill-opacity` does not) and a CSS keyframe on `color`. An `iframe` card is its own document and cannot import them; keep its body still and let the card header's status icon carry "this is running". A result state (`pending_review`, a parked approval) is the status icon's accessible name, never motion at all. **Truncate in flex and table cells**, and respect your declared `layout.minWidth` / `minHeight`.
179
+ - **Show honest, fresh state.** A counter, status, badge or button never shows a stale or false value — re-read it from the event or route that owns it — and an action that cannot run right now is rendered disabled with its reason, never offered.
179
180
  - **Design for a panel, not a page.** A panel is a few hundred pixels tall: three or more sections belong in a two-pane layout — a navigation rail plus one swapped content pane owning the only scroll container — never one long scrolling column.
180
181
 
181
182
  ### Chrome facts to design around
@@ -309,4 +310,4 @@ Then fetch the runtime snapshot with the `x-project-id` header and confirm it li
309
310
 
310
311
  ---
311
312
 
312
- Full public reference: <https://docs.neuralisapp.com/docs/package-system/app-surfaces>
313
+ Full public reference: <https://docs.neuralisapp.com/package-system/app-surfaces>
@@ -19,7 +19,7 @@ team/<slug>/
19
19
 
20
20
  Discovery scans `team/*/` at package root and walks `identity/**` and `files/**` recursively, on **both** the installed-package path and the project `_packages/` drop path. **Source markdown packages cannot carry a `team/` folder** — their vocabulary is only skill / instruction / rule / agent / docs. The `.md` match is **case-sensitive**: a `SOUL.MD` never reaches the agent, with no error. Discovery skips symlinks, and a `member.json`'s own `slug` must be a single safe path segment.
21
21
 
22
- **The template paths are a validated contract, not free text.** Whether discovered or declared inline, every `identityFiles` / `memberFiles` entry must be package-RELATIVE: no `..` or bare `.` segment, no absolute prefix, no backslash, no control character, at most 512 characters, at most 64 entries per list. A manifest that breaks any of these is a load ERROR and the package registers **nothing** — not a partial load. (Precisely: nothing enters the PACKAGE REGISTRY. It is not content quarantine — markdown inside a directory synced as a source is still discovered by the source-package scanner, which reads no manifest, so a rejected drop's `skills/**` can still reach an agent's context under a `source:packages://<slug>` id. Live-measured 2026-08-24.) The reason is worth knowing while you author: these strings become a file read performed by the platform process itself, which reaches further than the person installing your package, so they are checked before the join and resolved against the package root again at provision time. A path that will not resolve inside the package refuses the whole provision with `team_member_path_escape`.
22
+ **The template paths are a validated contract, not free text.** Whether discovered or declared inline, every `identityFiles` / `memberFiles` entry must be package-RELATIVE: no `..` or bare `.` segment, no absolute prefix, no backslash, no control character, at most 512 characters, at most 64 entries per list. A manifest that breaks any of these is a load ERROR and the package registers **nothing** — not a partial load. (Precisely: nothing enters the PACKAGE REGISTRY. It is not content quarantine — markdown inside a directory synced as a source is still discovered by the source-package scanner, which reads no manifest, so a rejected drop's `skills/**` can still reach an agent's context under its source-package id. Live-measured 2026-08-24.) The reason is worth knowing while you author: these strings become a file read performed by the platform process itself, which reaches further than the person installing your package, so they are checked before the join and resolved against the package root again at provision time. A path that will not resolve inside the package refuses the whole provision with `team_member_path_escape`.
23
23
 
24
24
  ### `member.json` — the complete field set
25
25
 
@@ -184,4 +184,4 @@ Installing a template is always **explicit**: it instantiates a mutable entry ow
184
184
 
185
185
  ---
186
186
 
187
- Public reference: [Workflows](https://docs.neuralisapp.com/docs/agent-core/workflows) · [Contributions, including team members](https://docs.neuralisapp.com/docs/package-system/contributions) · [Agent files and delegation](https://docs.neuralisapp.com/docs/agent-core/agents)
187
+ Public reference: [Workflows](https://docs.neuralisapp.com/agent-core/workflows) · [Contributions, including team members](https://docs.neuralisapp.com/package-system/contributions) · [Agent files and delegation](https://docs.neuralisapp.com/agent-core/agents)
@@ -38,7 +38,7 @@ when it was not. Exit `0` no errors · `1` errors · `2` usage. Passing proves n
38
38
  or discovery, in either mode.
39
39
 
40
40
  After the restart, rescan or sync: `bash ${SKILL_DIR}/scripts/verify-loaded.sh <package-id>` — the
41
- manifest id for (a) and (b), `source:<rootUri>` for (c) (§2).
41
+ manifest id for (a), the instance URI for (b) and (c) (§2).
42
42
 
43
43
  ---
44
44
 
@@ -68,10 +68,10 @@ tool handlers return.
68
68
 
69
69
  **A source package (path c) has no row in that table.** It never passes through the loader, so it
70
70
  has no status, no `reason` of that kind and no load line — done-gate step 1 for it is "it appears in
71
- the packages overview", not "it loaded". It is listed there under `sourcePackages[]`, keyed by the
72
- id **`source:<rootUri>`**: the literal prefix `source:` plus the package ROOT's URI, no trailing
73
- slash. A package rooted at `data://acme-pack` is `source:data://acme-pack`; one rooted at the source
74
- root itself is `source:data://`. Pass that id to `verify-loaded.sh` and it prints the root, the
71
+ the packages overview", not "it loaded". It is listed there under `sourcePackages[]`, keyed by its
72
+ instance id: the package ROOT's URI, no trailing slash, plus `?project=<p>&scope=<scope>`. A
73
+ package rooted at `data://acme-pack` is `data://acme-pack?project=<p>&scope=project`; one at the
74
+ source root itself is `data://?project=<p>&scope=project`. Pass that id to `verify-loaded.sh` and it prints the root, the
75
75
  grouping reason and the per-category file counts in place of a status.
76
76
 
77
77
  Where to read it without server-log access:
@@ -297,15 +297,15 @@ you publish.
297
297
 
298
298
  **(a) Installed node package — first-party, in-process.** Build so the compiled output exists (or
299
299
  leave a directory to the image build, which builds it), then have an admin register it as a
300
- dependency of the host — register, rebuild the image (`pnpm neuralis:rebuild` installs it), verify.
300
+ dependency of the host — register, rebuild the image (`neuralis rebuild` installs it), verify.
301
301
  That sequence is the **deploying admin's terminal work, not yours**; registering a directory or a
302
302
  tarball runs the loader's own admission check first, so fix what it names. The host command depends
303
- on the package's registry channel: `pnpm neuralis:pkg add <identity> --version <v>` (an EXACT
303
+ on the package's registry channel: `neuralis pkg add <identity> --version <v>` (an EXACT
304
304
  version) for an npm-channel package; the `neuralweb download <identity>@<v> --out <tgz>` +
305
- `pnpm neuralis:pkg add <identity> --tarball <tgz>` pair for an internal-channel one; and a
305
+ `neuralis pkg add <identity> --tarball <tgz>` pair for an internal-channel one; and a
306
306
  direct-upload package has **no builtin rail at all** — upload is declarative-only by construction
307
307
  and never joins the in-process class. (Where the operator has the `neuralweb` CLI,
308
- `neuralweb install <identity> --channel builtin` prints exactly these commands with a trust notice
308
+ `neuralweb install <identity> --channel builtin` prints these commands with a trust notice
309
309
  and never executes anything.) **Registering the dependency IS the trust act**: every dependency
310
310
  whose own `package.json` carries a `neuralis` block is discovered at boot and loaded in-process
311
311
  with host-assigned first-party trust — the same trust as the platform's own packages. Do it only
@@ -349,7 +349,7 @@ Worked example — a one-skill package needing no other file:
349
349
 
350
350
  ```text
351
351
  data://acme-pack/skills/release-notes/SKILL.md → root data://acme-pack (category-dirs)
352
- → id source:data://acme-pack
352
+ → id data://acme-pack?project=<p>&scope=project
353
353
  ```
354
354
 
355
355
  **Write it with `execute` (`action: "shell"`), not `fs_write`.** An agent's `fs_write` with content
@@ -384,12 +384,12 @@ invisible, with **no error anywhere** — indistinguishable from correctly hidde
384
384
  Until then the files are on disk but the package will not appear."*
385
385
 
386
386
  **Then prove it with the script** — it is the authoritative check:
387
- `bash ${SKILL_DIR}/scripts/verify-loaded.sh source:data://acme-pack`. It reads the overview surface,
387
+ `bash ${SKILL_DIR}/scripts/verify-loaded.sh 'data://acme-pack?project=<p>&scope=project'`. It reads the overview surface,
388
388
  which lists every discovered source package and reports each category as `N (M active)`. Once the
389
389
  sync has landed the package shows on the next stream — discovery is resolved fresh each time.
390
390
 
391
391
  Your own `<packages>` block is the second opinion, and it is the one that lies. A visible package
392
- renders there as `source:data://acme-pack [active, source]` followed by its root and
392
+ renders there short, `data://acme-pack [active, source]`, followed by its root and
393
393
  `acme-pack (category-dirs)` — but switched-OFF files are dropped from the listing, and a package
394
394
  with **nothing** visible left is omitted **entirely**, header and all. Remember the opt-in defaults:
395
395
  rule files and identity instructions arrive switched OFF (docs stay on, but are manual-invocation
@@ -498,6 +498,6 @@ evidence.
498
498
 
499
499
  ---
500
500
 
501
- Public reference: <https://docs.neuralisapp.com/docs/package-system/testing> ·
502
- registry: <https://docs.neuralisapp.com/docs/package-system/marketplace> ·
503
- the three contract examples: <https://docs.neuralisapp.com/docs/package-system/reference-package>
501
+ Public reference: <https://docs.neuralisapp.com/package-system/testing> ·
502
+ registry: <https://docs.neuralisapp.com/package-system/marketplace> ·
503
+ the three contract examples: <https://docs.neuralisapp.com/package-system/reference-package>
@@ -247,4 +247,4 @@ Untrusted tools are rate-limited an order of magnitude harder and time out soone
247
247
 
248
248
  ---
249
249
 
250
- Public reference: <https://docs.neuralisapp.com/docs/package-system/tools>
250
+ Public reference: <https://docs.neuralisapp.com/package-system/tools>
@@ -38,8 +38,8 @@
38
38
  #
39
39
  # USAGE bash check-package.sh <package-root>
40
40
  # EXIT 0 = no errors (warnings may print) · 1 = ERRORs · 2 = usage / no node
41
- # https://docs.neuralisapp.com/docs/package-system/directory-contract
42
- # https://docs.neuralisapp.com/docs/package-system/source-packages
41
+ # https://docs.neuralisapp.com/package-system/directory-contract
42
+ # https://docs.neuralisapp.com/package-system/source-packages
43
43
 
44
44
  set -euo pipefail
45
45
 
@@ -644,6 +644,6 @@ const sk = F.filter((x) => x.lvl === 'SKIP').length;
644
644
  out.write(`\n${e} error(s), ${F.length - e - sk} warning(s)${sk ? `, ${sk} check(s) SKIPPED` : ''} — ${path.basename(ROOT)}\n`);
645
645
  if (e === 0) out.write(MODE === 'manifest'
646
646
  ? 'Static checks pass — that proves NOTHING about loading. Install, then verify-loaded.sh.\n'
647
- : 'Static checks pass for what markdown can carry — that proves NOTHING about discovery.\nThe files must be indexed by a sync first, then: verify-loaded.sh "source:<slug>://<path>".\n');
647
+ : 'Static checks pass for what markdown can carry — that proves NOTHING about discovery.\nThe files must be indexed by a sync first, then: verify-loaded.sh "<slug>://<path>?project=<p>&scope=…".\n');
648
648
  process.exit(e > 0 ? 1 : 0);
649
649
  NODE_CHECK
@@ -45,7 +45,7 @@
45
45
  #
46
46
  # USAGE bash verify-loaded.sh <package-id> [--raw]
47
47
  # <package-id> the manifest id, e.g. "@acme/reports" or "reports".
48
- # For a source package pass its "source:<rootUri>" id.
48
+ # A drop or source package: its instance URI, quoted.
49
49
  # --raw dump both untouched JSON responses before the verdict,
50
50
  # so you can self-diagnose if the shape ever drifts.
51
51
  # EXIT 0 = loaded
@@ -58,7 +58,7 @@
58
58
  #
59
59
  # This script never accepts, prints or persists a token.
60
60
  #
61
- # Testing reference: https://docs.neuralisapp.com/docs/package-system/testing
61
+ # Testing reference: https://docs.neuralisapp.com/package-system/testing
62
62
 
63
63
  set -euo pipefail
64
64
 
@@ -75,17 +75,17 @@ done
75
75
 
76
76
  manual_fallback() {
77
77
  case "$PKG_ID" in
78
- source:*)
78
+ *://*)
79
79
  cat >&2 <<'SRCFALLBACK'
80
80
 
81
81
  Cannot verify programmatically. Do NOT record this package as working.
82
82
 
83
- This id names a SOURCE package. It never passes through the loader, so there
84
- is NO load line in the server log and its absence proves nothing. Verify it
85
- this way instead:
83
+ A SOURCE package never passes through the loader, so there is NO load line
84
+ in the server log (a drop's id has the same URI form and does get one).
85
+ Verify a source package this way instead:
86
86
 
87
87
  1. Read your own <packages> block. A recognised source package appears as
88
- "source:<rootUri> [active, source]" with its per-category counts.
88
+ "<rootUri> [active, source]" with its per-category counts.
89
89
  Caveat: files that are switched OFF by default (rule files, identity
90
90
  instructions) are dropped from that block, and a package with nothing
91
91
  visible left is omitted entirely — so <packages> can under-report a
@@ -223,7 +223,7 @@ if (!entry && srcEntry) {
223
223
  process.stdout.write(`SOURCE PACKAGE ${pkgId}\n`);
224
224
  line('name', srcEntry.name || '(unnamed)');
225
225
  line('source', `${srcEntry.source || '?'} (${srcEntry.connectorKind || '?'})`);
226
- line('root', `${srcEntry.rootUri || '?'} (the id is always "source:" + this)`);
226
+ line('root', `${srcEntry.rootUri || '?'} (the id is this + ?project=…&scope=…)`);
227
227
  line('recognized', `by ${srcEntry.reason}`);
228
228
  line('enabled', srcEntry.enabled === false ? 'no' : 'yes');
229
229
  for (const cat of ['skills', 'instructions', 'rules', 'agents', 'docs']) {
@@ -242,11 +242,11 @@ if (!entry) {
242
242
  w(`ABSENT ${pkgId}\n`);
243
243
  w(` Not among the ${diag.entries.length} installed and ${overSource.length} source package(s) the platform reports for you.\n\n`);
244
244
  w('This is often correct by design, not a failure. Work through these in order:\n');
245
- w(' 1. The id is wrong. An INSTALLED package is its manifest id EXACTLY, scope\n');
246
- w(' prefix included ("@acme/reports" is not "reports"). A SOURCE package is\n');
247
- w(' literally "source:" + its root URI — "source:data://acme-pack", no trailing\n');
248
- w(' slash on a sub-directory; a package at the source root keeps the "://"\n');
249
- w(' ("source:data://"). Both lists below print the exact strings.\n');
245
+ w(' 1. The id is wrong. A host-installed package is its manifest id EXACTLY,\n');
246
+ w(' scope prefix included ("@acme/reports" is not "reports"). A drop or SOURCE\n');
247
+ w(' package is its root URI, no trailing slash, plus project and scope:\n');
248
+ w(' "data://acme-pack?project=<p>&scope=project" — <packages> shows it short,\n');
249
+ w(' "data://acme-pack". Both lists below print the exact strings.\n');
250
250
  w(' 2. It was never installed, or the install did not land where you think.\n');
251
251
  w(' 3. It is disabled for this agent or conversation.\n');
252
252
  w(' 4. You cannot see it: visibility is scoped per user and per agent, and a\n');
@@ -260,8 +260,8 @@ if (!entry) {
260
260
  w(' package root or on the file itself. Once a sync has indexed the files they\n');
261
261
  w(' show on the next stream — discovery is not cached behind a timer.\n');
262
262
 
263
- if (pkgId.includes('://') && !pkgId.startsWith('source:')) {
264
- w(`\nThat looks like a root URI, not an id. Try: source:${pkgId.endsWith('://') ? pkgId : pkgId.replace(/\/+$/, '')}\n`);
263
+ if (pkgId.includes('://') && !pkgId.includes('?')) {
264
+ w('\nNot a full id: an instance id ends in ?project=…&scope=… — the lists below print it.\n');
265
265
  }
266
266
  const rows = (title, items) => {
267
267
  w(`\n${title}\n`);
@@ -271,7 +271,7 @@ if (!entry) {
271
271
  };
272
272
  rows(`Installed package ids the platform lists for you (${diag.entries.length}):`,
273
273
  diag.entries.map((e) => [String(e.packageId), e.status && e.status !== 'loaded' ? `[${e.status}]` : '']));
274
- rows(`Source package ids (${overSource.length}) — always "source:" + the root URI:`,
274
+ rows(`Source package ids (${overSource.length}) — the root URI + ?project=…&scope=…:`,
275
275
  overSource.map((p) => {
276
276
  const files = ['skills', 'instructions', 'rules', 'agents', 'docs']
277
277
  .reduce((n, c) => n + (Array.isArray(p[c]) ? p[c].length : 0), 0);
@@ -41,9 +41,9 @@ server-side **403** from `search.sh` even though the other scripts work.
41
41
  - `/write` body = `{"agentId":"…","uri":"data://notes/plan.md","<verb>":…}` — the VERB is a KEY and its presence is the intent. Content verbs COMPOSE in one call, in a fixed order, as ONE write with ONE baseline: `create` (`{content, client_request_id?}` — never overwrites; a taken name lands BESIDE as `name-2.ext` and the response `uri` is where it went, so read it back), `overwrite` (`{content}` — refuses on a missing file and names `create`), `edit` (`[{old_string, new_string?, replace_all?, expected_replacements?}]`, applied in order, one failure discards all of them), `insert` (`{insert_text, insert_line?}` — inserts AFTER that line, `0` = start of file, omitted = append), `lines` (`{line_start, line_end, content}`), `fields` (`{category, status, pinned, tags{add,remove,set}, metadata}`). Structural verbs stand ALONE: `move`/`copy` (a destination uri or, for a file move, a bare new filename; `copy` may cross sources), `mkdir:true` (a real empty directory; not on `brain://`, where folders are implicit), `revert:true` (one-level undo), `delete:true` (a file, or a whole folder recursively). **A 2xx does not mean success** — a refusal is 200 with `ok:false`, so branch on `ok`. A `move` (or a `revert` that relocates or re-creates) onto a uri that already holds something answers `ok:false` + `error:"DESTINATION_EXISTS"` — nothing was overwritten; delete or rename the occupant first. A delete has ONE spelling, the `delete` key: `fields.status:"deleted"` is refused. `review` is never read from the body — a content edit (`overwrite`/`edit`/`insert`/`lines`) lands `pending_review` on every lane (visible and revertible in Changes); `create`/`move`/`copy`/`mkdir` land committed for a human interactive caller and `pending_review` from this ticket lane; `/upload` also journals agent-origin uploads as pending review; interactive human uploads land committed. Use `/write` for JSON text and `/upload` for multipart file bytes. A missing `agentId`/`uri` is a **400** naming the field, a body the server could not parse a **400** `Request body must be a JSON object`. A uri-policy denial is a **403 with no `ok` field**, a disabled source a **409** with `code:"source_disabled"`. A source slug this project does not have answers one of two ways, and BOTH mean "stop guessing this name": with a scheme (`zzz://a.md`) the uri gate answers **403 `uri_policy_denied`** first; without one (`notes.md`) you get **404 `code:"source_not_configured"`** carrying `availableSources` — the sources you CAN address. `/list` gives the 404 in both forms. Switch to a source from that list (or from `<runtime_stack>`); retrying the same name never works. `/read` is different again: it reports PER FILE inside a 200, so a denied or disabled source arrives as `{uri, error, code:"forbidden"}` — never a 409 — and a missing file as `code:"not_found"`. No code means the read failed for some other reason; do not conclude the file is gone. A folder delete or copy that partly succeeded reports what really happened: `affected` (files touched) and `failed` (the NAMES that could not be), so "failed" does not mean "nothing happened". `warning:"moved_with_source_retained"` on a move means the copy landed but the original could not be removed — BOTH copies exist on purpose; do not re-run the move. `indexed:false` means the bytes DID land and are readable, but search indexing was skipped or failed; report it, do not re-write. Sync retries failed indexing only for eligible files; excluded files remain unindexed. Every script here runs curl with `--fail-with-body`, so a non-2xx prints that body too — in the merged output the body comes FIRST and curl's own `curl: (22)` line after it, under a `--- stderr ---` separator, so read the whole output.
42
42
  - `/search` body key is `search_mode` (semantic|filter|grep) — the SAME vocabulary as the `fs_search` tool; the legacy `mode` key is rejected with 400. The route forwards `search_mode`, `query`, `folder_uri`, `glob`, `category`, `tags`, `status`, `created_after`/`created_before`, `limit`, and the grep-only `path_glob`, `context` and `case_sensitive`. In `grep` mode the search is uri-policy `read`-gated (only paths the caller holds `read` policy on are grepped), the match is a FIXED STRING, and the answer carries `truncated` + `total_seen` — a cut set says so, so never read a full-looking list as proof that the rest is absent.
43
43
  - `/raw` is a GET — pass the file URI via `URI=…` (no `BODY_JSON`). It always returns the full bytes, so `raw.sh` is unaffected by the response headers; what those headers say is a BROWSER instruction. Safe types (images except SVG, video, audio, PDF, text, JSON) are marked for inline display; SVG, HTML and XML are marked `attachment` so a person clicking the link downloads them instead of executing them on the app origin. Do not describe a `.svg` or `.html` you wrote as viewable in the browser — offer it as a download, or convert it to a raster image if a human needs to look at it.
44
- - `/read` is at parity with the `fs_read` tool: the body takes `files[]` — each entry a URI string or `{"uri":"…","line_start":N,"line_end":M}` with that file's own window — plus `read_version`, batch-level `line_start`/`line_end` and `include_ids`. An entry that is neither shape is a **400**. If you only need the pre-edit content, a plain `/read` response already carries it: each file's `version.baseline.content`, with `available_versions` listing `baseline` exactly when one exists.
44
+ - `/read` is at parity with the `fs_read` tool: the body takes `files[]` — each entry a URI string or `{"uri":"…","line_start":N,"line_end":M}` with that file's own window — plus `read_version`, batch-level `line_start`/`line_end` and `include_ids`. An entry that is neither shape is a **400**. Text is a bounded preview; native media may accompany it, while unsupported/invalid binary data has a URI and marker. For a byte-exact binary copy use the authorized `/raw` byte lane and multipart `/upload`, never re-encode a text preview. If you only need the pre-edit content, a plain `/read` response already carries it: each file's `version.baseline.content`, with `available_versions` listing `baseline` exactly when one exists.
45
45
  - `/upload` is **multipart/form-data**, NOT JSON — pass `FILE_PATH=…` `AGENT_ID=…` (required) plus optional `URI=…` / `TAGS=a,b`; a JSON body is rejected with 400. The 200 carries `indexed`: `false` means the bytes DID land but search indexing was skipped by the source selection or failed (provider outage/quota) — report it, do not re-upload. An eligible sync retries failed indexing; excluded uploads remain unindexed until the selection changes. The 200 also carries `mimeType`, and it may differ from what the upload declared: the stored type is resolved from the filename extension first, with the declared value kept only for an extension the platform does not know, and a common-image claim the leading bytes contradict falls back to `application/octet-stream`. Give the file a truthful extension and the stored type follows.
46
- - `GET /pending` lists durable pending records inside the Changes workspace. `STATUS`, `SOURCE`, `OP`, and `LIMIT` filter the list; owner/scope and URI READ gates apply per record. Review begins with `POST /pending` `{action:"preview",id}`: it returns the current connector content separately from the recorded snapshot and saved baseline, typed missing/unavailable/binary/too-large states, `indexState`, `requiresAcknowledgement`, and `expectedFingerprint`. The preview is bounded by `pendingPreviewMaxBytes`; it never fabricates missing content or vectors. Resolve through `POST /approve` `{id,expectedFingerprint}` or `POST /pending` `{action:"revert"|"dismiss",id,expectedFingerprint}`. If the preview requires acknowledgement, inspect those states and include `acknowledgeCurrentState:true`; never auto-acknowledge an unseen preview. The server rechecks freshness and WRITE authority at apply: a changed fingerprint requires a new preview, and acknowledgement grants no missing permission. Bare legacy `/write revert:true` refuses unsafe pending recovery; ordinary non-pending one-level undo remains available. Approval/dismissal preserve the stored snapshot/index state (including recovery-only or absent index), rather than certifying current connector bytes as indexed. Terminal retries remain owner-gated and idempotent; `uri` is omitted without current READ and WRITE access. Revert restores the saved baseline and refuses missing baselines or occupied move destinations. Discard/Repair remain orphan-only, owner-gated operations; no transient outage is proof of orphanhood.
46
+ - `GET /pending` lists durable pending records inside the Changes workspace. `STATUS`, `SOURCE`, `OP`, and `LIMIT` filter the list; owner/scope and URI READ gates apply per record. Review begins with `POST /pending` `{action:"preview",id}`: it returns the current connector content separately from the recorded snapshot and saved baseline, typed missing/unavailable/binary/too-large states, `indexState`, `requiresAcknowledgement`, and `expectedFingerprint`. The preview is bounded by `pendingPreviewMaxBytes`; it never fabricates missing content or vectors. Resolve through `POST /approve` `{id,expectedFingerprint}` or `POST /pending` `{action:"revert"|"dismiss",id,expectedFingerprint}`. If the preview requires acknowledgement, inspect those states and include `acknowledgeCurrentState:true`; never auto-acknowledge an unseen preview. The server rechecks freshness and WRITE authority at apply: a changed fingerprint requires a new preview, and acknowledgement grants no missing permission. Bare legacy `/write revert:true` refuses unsafe pending recovery; ordinary non-pending one-level undo remains available. Approval/dismissal preserve the stored snapshot/index state (including recovery-only or absent index), rather than certifying current connector bytes as indexed. For a file the preview shows `missing` with a saved `journal-latest-write` baseline, an acknowledged approve/dismiss closes the review and the file stays gone; revert is the restore. Terminal retries remain owner-gated and idempotent; `uri` is omitted without current READ and WRITE access. Revert restores the saved baseline and refuses missing baselines or occupied move destinations. Discard/Repair remain orphan-only, owner-gated operations; no transient outage is proof of orphanhood.
47
47
 
48
48
 
49
49
  The body shape is route-specific — refer to brain-core's