@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.
- package/README.md +26 -35
- package/app/cards/DiffView.tsx +9 -7
- package/app/cards/README.md +1 -1
- package/app/cards/diffLine.tsx +2 -4
- package/app/filesystem/README.md +1 -1
- package/app/filesystem/api/index.ts +14 -5
- package/app/filesystem/domain/types.ts +24 -5
- package/app/filesystem/store/filesystemStore.ts +20 -1
- package/app/filesystem/store/listSlice.ts +2 -0
- package/app/filesystem/store/searchSlice.ts +24 -1
- package/app/filesystem/ui/FileTreeSearch.tsx +29 -2
- package/app/filesystem/ui/PendingChangesPanel.tsx +74 -17
- package/app/filesystem/ui/PendingReviewDialog.tsx +45 -20
- package/app/filesystem/ui/README.md +8 -7
- package/app/filesystem/ui/ReembedDialog.tsx +20 -9
- package/app/filesystem/ui/SourceDeleteConfirm.tsx +1 -1
- package/app/filesystem/ui/SourcesPanel.tsx +110 -17
- package/app/filesystem/ui/VectorHealthPanel.tsx +14 -0
- package/app/filesystem/ui/pendingChangesModel.ts +9 -5
- package/dist/app/chunks/{astro-LRAFGXNX.js → astro-B2J4AS2D.js} +1 -1
- package/dist/app/chunks/bash-KY6SAQTH.js +1 -0
- package/dist/app/chunks/c-OBOPYVZ7.js +1 -0
- package/dist/app/chunks/{chunk-5H7ZCOD3.js → chunk-2X3GNKJ3.js} +1 -1
- package/dist/app/chunks/{chunk-XIFGTNRM.js → chunk-JPJIVRFI.js} +1 -1
- package/dist/app/chunks/{chunk-RH3QY5LF.js → chunk-LEFIFWND.js} +1 -1
- package/dist/app/chunks/{chunk-G4RZ3UNX.js → chunk-N6RXX3PH.js} +1 -1
- package/dist/app/chunks/{chunk-QXXJ73P5.js → chunk-PZAW4HPB.js} +1 -1
- package/dist/app/chunks/{chunk-3QLE7Y4L.js → chunk-ZBYWWTO6.js} +1 -1
- package/dist/app/chunks/cpp-TVWVOTEQ.js +1 -0
- package/dist/app/chunks/css-MANZBYA4.js +1 -0
- package/dist/app/chunks/{elixir-M36XROA6.js → elixir-S725Z7EH.js} +1 -1
- package/dist/app/chunks/{elm-7BG6QAIK.js → elm-5WUUSTNB.js} +1 -1
- package/dist/app/chunks/graphql-UGOPR3WU.js +1 -0
- package/dist/app/chunks/html-F6FWTBSG.js +1 -0
- package/dist/app/chunks/java-ANIVV5H5.js +1 -0
- package/dist/app/chunks/javascript-IH374YWG.js +1 -0
- package/dist/app/chunks/json-WGGVVXSB.js +1 -0
- package/dist/app/chunks/jsx-OTXJQD32.js +1 -0
- package/dist/app/chunks/{latex-ZWK7SXB6.js → latex-QCZNITGN.js} +1 -1
- package/dist/app/chunks/lua-4CRZ64PU.js +1 -0
- package/dist/app/chunks/{nginx-2L6VRV3A.js → nginx-V4CYS7WR.js} +1 -1
- package/dist/app/chunks/{perl-PBUAXXK6.js → perl-BHTX7F5B.js} +1 -1
- package/dist/app/chunks/{php-QJX57PA6.js → php-AYGJ5WYZ.js} +1 -1
- package/dist/app/chunks/r-4YFCFA4B.js +1 -0
- package/dist/app/chunks/{ruby-RLOWMVPO.js → ruby-42NMJWAL.js} +1 -1
- package/dist/app/chunks/{scss-B5CAI3HR.js → scss-XD7VU2CU.js} +1 -1
- package/dist/app/chunks/sql-B55MH6JJ.js +1 -0
- package/dist/app/chunks/{svelte-GT3D4C44.js → svelte-WR3QPIJU.js} +1 -1
- package/dist/app/chunks/tsx-S73GAE2L.js +1 -0
- package/dist/app/chunks/typescript-NEWOAB5Z.js +1 -0
- package/dist/app/chunks/{vue-JOW62MHD.js → vue-CCDS4VZK.js} +1 -1
- package/dist/app/chunks/xml-UXKAGLDR.js +1 -0
- package/dist/app/chunks/yaml-UMWKDTK7.js +1 -0
- package/dist/app/host.js +40 -40
- package/dist/scripts/embeddingLockV3.d.ts +30 -0
- package/dist/scripts/embeddingLockV3.d.ts.map +1 -0
- package/dist/scripts/embeddingLockV3.js +100 -0
- package/dist/scripts/embeddingLockV3.js.map +1 -0
- package/dist/scripts/vectorProofV1.d.ts +90 -0
- package/dist/scripts/vectorProofV1.d.ts.map +1 -0
- package/dist/scripts/vectorProofV1.js +220 -0
- package/dist/scripts/vectorProofV1.js.map +1 -0
- package/dist/src/config/env.d.ts +21 -0
- package/dist/src/config/env.d.ts.map +1 -1
- package/dist/src/config/env.js +55 -0
- package/dist/src/config/env.js.map +1 -1
- package/dist/src/connectors/AppSourceConfigStore.d.ts +12 -2
- package/dist/src/connectors/AppSourceConfigStore.d.ts.map +1 -1
- package/dist/src/connectors/AppSourceConfigStore.js +48 -40
- package/dist/src/connectors/AppSourceConfigStore.js.map +1 -1
- package/dist/src/connectors/LocalDiskConnector.d.ts +11 -14
- package/dist/src/connectors/LocalDiskConnector.d.ts.map +1 -1
- package/dist/src/connectors/LocalDiskConnector.js +87 -107
- package/dist/src/connectors/LocalDiskConnector.js.map +1 -1
- package/dist/src/connectors/sourceConfigMutation.d.ts +11 -1
- package/dist/src/connectors/sourceConfigMutation.d.ts.map +1 -1
- package/dist/src/connectors/sourceConfigMutation.js +36 -3
- package/dist/src/connectors/sourceConfigMutation.js.map +1 -1
- package/dist/src/domain/chunker.js +8 -3
- package/dist/src/domain/chunker.js.map +1 -1
- package/dist/src/domain/healthTypes.d.ts +11 -0
- package/dist/src/domain/healthTypes.d.ts.map +1 -1
- package/dist/src/domain/mime.d.ts +1 -0
- package/dist/src/domain/mime.d.ts.map +1 -1
- package/dist/src/domain/mime.js +48 -0
- package/dist/src/domain/mime.js.map +1 -1
- package/dist/src/domain/pendingChange.d.ts +7 -0
- package/dist/src/domain/pendingChange.d.ts.map +1 -1
- package/dist/src/domain/pendingChange.js +11 -0
- package/dist/src/domain/pendingChange.js.map +1 -1
- package/dist/src/domain/sourceConfig.d.ts +7 -14
- package/dist/src/domain/sourceConfig.d.ts.map +1 -1
- package/dist/src/domain/sourceConfig.js +1 -13
- package/dist/src/domain/sourceConfig.js.map +1 -1
- package/dist/src/domain/sourcePackages.d.ts +11 -2
- package/dist/src/domain/sourcePackages.d.ts.map +1 -1
- package/dist/src/domain/syncTrigger.d.ts +2 -3
- package/dist/src/domain/syncTrigger.d.ts.map +1 -1
- package/dist/src/domain/syncTrigger.js +2 -3
- package/dist/src/domain/syncTrigger.js.map +1 -1
- package/dist/src/domain/syncTypes.d.ts +21 -4
- package/dist/src/domain/syncTypes.d.ts.map +1 -1
- package/dist/src/domain/syncTypes.js.map +1 -1
- package/dist/src/domain/text.d.ts +3 -0
- package/dist/src/domain/text.d.ts.map +1 -1
- package/dist/src/domain/text.js +5 -0
- package/dist/src/domain/text.js.map +1 -1
- package/dist/src/domain/types.d.ts +9 -0
- package/dist/src/domain/types.d.ts.map +1 -1
- package/dist/src/embeddings/clients/GeminiEmbedder.d.ts.map +1 -1
- package/dist/src/embeddings/clients/GeminiEmbedder.js +11 -5
- package/dist/src/embeddings/clients/GeminiEmbedder.js.map +1 -1
- package/dist/src/embeddings/clients/OllamaEmbedder.d.ts.map +1 -1
- package/dist/src/embeddings/clients/OllamaEmbedder.js +13 -6
- package/dist/src/embeddings/clients/OllamaEmbedder.js.map +1 -1
- package/dist/src/embeddings/clients/OpenAIEmbedder.d.ts.map +1 -1
- package/dist/src/embeddings/clients/OpenAIEmbedder.js +12 -9
- package/dist/src/embeddings/clients/OpenAIEmbedder.js.map +1 -1
- package/dist/src/embeddings/clients/QwenEmbedder.d.ts.map +1 -1
- package/dist/src/embeddings/clients/QwenEmbedder.js +12 -5
- package/dist/src/embeddings/clients/QwenEmbedder.js.map +1 -1
- package/dist/src/embeddings/clients/VoyageEmbedder.d.ts.map +1 -1
- package/dist/src/embeddings/clients/VoyageEmbedder.js +12 -5
- package/dist/src/embeddings/clients/VoyageEmbedder.js.map +1 -1
- package/dist/src/embeddings/factory.d.ts +2 -0
- package/dist/src/embeddings/factory.d.ts.map +1 -1
- package/dist/src/embeddings/factory.js +23 -3
- package/dist/src/embeddings/factory.js.map +1 -1
- package/dist/src/embeddings/lock.d.ts +22 -11
- package/dist/src/embeddings/lock.d.ts.map +1 -1
- package/dist/src/embeddings/lock.js +47 -29
- package/dist/src/embeddings/lock.js.map +1 -1
- package/dist/src/embeddings/retry.d.ts +5 -0
- package/dist/src/embeddings/retry.d.ts.map +1 -1
- package/dist/src/embeddings/retry.js +35 -0
- package/dist/src/embeddings/retry.js.map +1 -1
- package/dist/src/events/pending.d.ts +56 -0
- package/dist/src/events/pending.d.ts.map +1 -0
- package/dist/src/events/pending.js +108 -0
- package/dist/src/events/pending.js.map +1 -0
- package/dist/src/events/source.d.ts +60 -14
- package/dist/src/events/source.d.ts.map +1 -1
- package/dist/src/events/source.js +149 -31
- package/dist/src/events/source.js.map +1 -1
- package/dist/src/events/vector.d.ts +33 -0
- package/dist/src/events/vector.d.ts.map +1 -0
- package/dist/src/events/vector.js +57 -0
- package/dist/src/events/vector.js.map +1 -0
- package/dist/src/git/GitRunner.d.ts.map +1 -1
- package/dist/src/git/GitRunner.js +11 -8
- package/dist/src/git/GitRunner.js.map +1 -1
- package/dist/src/git/sourceGitControl.d.ts.map +1 -1
- package/dist/src/git/sourceGitControl.js +2 -1
- package/dist/src/git/sourceGitControl.js.map +1 -1
- package/dist/src/index.d.ts +5 -4
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +4 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/lifecycle.d.ts +20 -4
- package/dist/src/lifecycle.d.ts.map +1 -1
- package/dist/src/lifecycle.js +5 -1
- package/dist/src/lifecycle.js.map +1 -1
- package/dist/src/routes/health.js +6 -1
- package/dist/src/routes/health.js.map +1 -1
- package/dist/src/routes/pending.d.ts.map +1 -1
- package/dist/src/routes/pending.js +2 -1
- package/dist/src/routes/pending.js.map +1 -1
- package/dist/src/routes/sources.d.ts.map +1 -1
- package/dist/src/routes/sources.js +60 -11
- package/dist/src/routes/sources.js.map +1 -1
- package/dist/src/services/BridgeService.d.ts +2 -2
- package/dist/src/services/BridgeService.d.ts.map +1 -1
- package/dist/src/services/BridgeService.js +11 -2
- package/dist/src/services/BridgeService.js.map +1 -1
- package/dist/src/services/FilesystemService.d.ts +3 -1
- package/dist/src/services/FilesystemService.d.ts.map +1 -1
- package/dist/src/services/FilesystemService.js +3 -1
- package/dist/src/services/FilesystemService.js.map +1 -1
- package/dist/src/services/FilesystemUiService.js +1 -1
- package/dist/src/services/FilesystemUiService.js.map +1 -1
- package/dist/src/services/SyncScheduler.d.ts.map +1 -1
- package/dist/src/services/SyncScheduler.js +0 -14
- package/dist/src/services/SyncScheduler.js.map +1 -1
- package/dist/src/services/VectorHealthService.d.ts.map +1 -1
- package/dist/src/services/VectorHealthService.js +2 -46
- package/dist/src/services/VectorHealthService.js.map +1 -1
- package/dist/src/services/baselineRepair.d.ts +2 -2
- package/dist/src/services/baselineRepair.js +2 -2
- package/dist/src/services/declaredSources.d.ts +8 -1
- package/dist/src/services/declaredSources.d.ts.map +1 -1
- package/dist/src/services/declaredSources.js +19 -19
- package/dist/src/services/declaredSources.js.map +1 -1
- package/dist/src/store/dataFormats.d.ts +14 -3
- package/dist/src/store/dataFormats.d.ts.map +1 -1
- package/dist/src/store/dataFormats.js +15 -5
- package/dist/src/store/dataFormats.js.map +1 -1
- package/dist/src/sync/DeltaSyncRunner.d.ts.map +1 -1
- package/dist/src/sync/DeltaSyncRunner.js +78 -243
- package/dist/src/sync/DeltaSyncRunner.js.map +1 -1
- package/dist/src/sync/SyncJobQueue.d.ts +33 -4
- package/dist/src/sync/SyncJobQueue.d.ts.map +1 -1
- package/dist/src/sync/SyncJobQueue.js +179 -19
- package/dist/src/sync/SyncJobQueue.js.map +1 -1
- package/dist/src/sync/moveDetector.d.ts +2 -1
- package/dist/src/sync/moveDetector.d.ts.map +1 -1
- package/dist/src/sync/moveDetector.js +2 -1
- package/dist/src/sync/moveDetector.js.map +1 -1
- package/dist/src/tools/fs_search.d.ts.map +1 -1
- package/dist/src/tools/fs_search.js +8 -0
- package/dist/src/tools/fs_search.js.map +1 -1
- package/dist/src/tools/fs_write.js +3 -1
- package/dist/src/tools/fs_write.js.map +1 -1
- package/dist/src/usecases/chunkUpsert.d.ts +4 -0
- package/dist/src/usecases/chunkUpsert.d.ts.map +1 -1
- package/dist/src/usecases/chunkUpsert.js +103 -60
- package/dist/src/usecases/chunkUpsert.js.map +1 -1
- package/dist/src/usecases/embeddingBacklog.d.ts +31 -0
- package/dist/src/usecases/embeddingBacklog.d.ts.map +1 -0
- package/dist/src/usecases/embeddingBacklog.js +244 -0
- package/dist/src/usecases/embeddingBacklog.js.map +1 -0
- package/dist/src/usecases/listSourcePackages.js +17 -1
- package/dist/src/usecases/listSourcePackages.js.map +1 -1
- package/dist/src/usecases/mediaLane.d.ts +11 -4
- package/dist/src/usecases/mediaLane.d.ts.map +1 -1
- package/dist/src/usecases/mediaLane.js +67 -30
- package/dist/src/usecases/mediaLane.js.map +1 -1
- package/dist/src/usecases/pendingReview.d.ts.map +1 -1
- package/dist/src/usecases/pendingReview.js +24 -7
- package/dist/src/usecases/pendingReview.js.map +1 -1
- package/dist/src/usecases/purgeExcludedPoints.d.ts +2 -0
- package/dist/src/usecases/purgeExcludedPoints.d.ts.map +1 -1
- package/dist/src/usecases/purgeExcludedPoints.js +3 -2
- package/dist/src/usecases/purgeExcludedPoints.js.map +1 -1
- package/dist/src/usecases/readFiles.d.ts.map +1 -1
- package/dist/src/usecases/readFiles.js +33 -6
- package/dist/src/usecases/readFiles.js.map +1 -1
- package/dist/src/usecases/reconcileSourcePackageRoots.d.ts +31 -0
- package/dist/src/usecases/reconcileSourcePackageRoots.d.ts.map +1 -0
- package/dist/src/usecases/reconcileSourcePackageRoots.js +114 -0
- package/dist/src/usecases/reconcileSourcePackageRoots.js.map +1 -0
- package/dist/src/usecases/searchFiles.d.ts.map +1 -1
- package/dist/src/usecases/searchFiles.js +62 -64
- package/dist/src/usecases/searchFiles.js.map +1 -1
- package/dist/src/usecases/syncIndexedFile.d.ts +42 -0
- package/dist/src/usecases/syncIndexedFile.d.ts.map +1 -0
- package/dist/src/usecases/syncIndexedFile.js +242 -0
- package/dist/src/usecases/syncIndexedFile.js.map +1 -0
- package/dist/src/usecases/syncPointWrites.d.ts +5 -0
- package/dist/src/usecases/syncPointWrites.d.ts.map +1 -1
- package/dist/src/usecases/syncPointWrites.js +32 -5
- package/dist/src/usecases/syncPointWrites.js.map +1 -1
- package/dist/src/usecases/uploadBinary.d.ts.map +1 -1
- package/dist/src/usecases/uploadBinary.js +36 -49
- package/dist/src/usecases/uploadBinary.js.map +1 -1
- package/dist/src/usecases/vector/endpointGuard.js +2 -1
- package/dist/src/usecases/vector/endpointGuard.js.map +1 -1
- package/dist/src/usecases/vector/estimate.d.ts +7 -4
- package/dist/src/usecases/vector/estimate.d.ts.map +1 -1
- package/dist/src/usecases/vector/estimate.js +8 -5
- package/dist/src/usecases/vector/estimate.js.map +1 -1
- package/dist/src/usecases/vector/rebuildGeneration.d.ts +29 -5
- package/dist/src/usecases/vector/rebuildGeneration.d.ts.map +1 -1
- package/dist/src/usecases/vector/rebuildGeneration.js +224 -82
- package/dist/src/usecases/vector/rebuildGeneration.js.map +1 -1
- package/dist/src/usecases/vectorMaintenance.d.ts +46 -4
- package/dist/src/usecases/vectorMaintenance.d.ts.map +1 -1
- package/dist/src/usecases/vectorMaintenance.js +190 -11
- package/dist/src/usecases/vectorMaintenance.js.map +1 -1
- package/dist/src/usecases/write/commit.d.ts +6 -8
- package/dist/src/usecases/write/commit.d.ts.map +1 -1
- package/dist/src/usecases/write/commit.js +96 -112
- package/dist/src/usecases/write/commit.js.map +1 -1
- package/dist/src/usecases/write/content.js +1 -2
- package/dist/src/usecases/write/content.js.map +1 -1
- package/dist/src/usecases/write/ports.d.ts +1 -0
- package/dist/src/usecases/write/ports.d.ts.map +1 -1
- package/dist/src/vector/FilesystemVectorIndex.d.ts +34 -3
- package/dist/src/vector/FilesystemVectorIndex.d.ts.map +1 -1
- package/dist/src/vector/FilesystemVectorIndex.js +254 -20
- package/dist/src/vector/FilesystemVectorIndex.js.map +1 -1
- package/dist/src/vector/InMemoryVectorIndex.d.ts +9 -2
- package/dist/src/vector/InMemoryVectorIndex.d.ts.map +1 -1
- package/dist/src/vector/InMemoryVectorIndex.js +25 -6
- package/dist/src/vector/InMemoryVectorIndex.js.map +1 -1
- package/dist/src/vector/QdrantVectorIndex.d.ts +35 -9
- package/dist/src/vector/QdrantVectorIndex.d.ts.map +1 -1
- package/dist/src/vector/QdrantVectorIndex.js +209 -90
- package/dist/src/vector/QdrantVectorIndex.js.map +1 -1
- package/dist/src/vector/qdrantFilter.d.ts +3 -1
- package/dist/src/vector/qdrantFilter.d.ts.map +1 -1
- package/dist/src/vector/qdrantFilter.js +2 -0
- package/dist/src/vector/qdrantFilter.js.map +1 -1
- package/dist/src/vector/types.d.ts +81 -0
- package/dist/src/vector/types.d.ts.map +1 -1
- package/dist/src/vector/types.js +2 -0
- package/dist/src/vector/types.js.map +1 -1
- package/dist/src/wiring.d.ts +6 -0
- package/dist/src/wiring.d.ts.map +1 -1
- package/dist/src/wiring.js +62 -3
- package/dist/src/wiring.js.map +1 -1
- package/dist/tools/fs_search.json +2 -2
- package/docs/drive-overview.md +2 -2
- package/instructions/brain-model.md +1 -1
- package/package.json +999 -10
- package/rules/brain-rules.md +1 -1
- package/skills/connect-business-data/SKILL.md +6 -4
- package/skills/create-package/SKILL.md +14 -12
- package/skills/create-package/references/config-and-credentials.md +3 -3
- package/skills/create-package/references/connectors-and-uri-policies.md +5 -3
- package/skills/create-package/references/manifest-and-discovery.md +4 -3
- package/skills/create-package/references/runtime-and-build.md +9 -9
- package/skills/create-package/references/skills-and-context.md +3 -3
- package/skills/create-package/references/surfaces-and-design.md +2 -1
- package/skills/create-package/references/team-and-workflows.md +2 -2
- package/skills/create-package/references/test-and-ship.md +15 -15
- package/skills/create-package/references/tools-and-schemas.md +1 -1
- package/skills/create-package/scripts/check-package.sh +3 -3
- package/skills/create-package/scripts/verify-loaded.sh +16 -16
- package/skills/manage-files/SKILL.md +2 -2
- package/skills/manage-sources/SKILL.md +16 -15
- package/skills/manage-sources/scripts/reembed.sh +9 -3
- package/skills/sync/SKILL.md +4 -4
- package/tools/fs_search.json +2 -2
- package/dist/app/chunks/bash-M45GHPBQ.js +0 -1
- package/dist/app/chunks/c-X3REOAWD.js +0 -1
- package/dist/app/chunks/cpp-VOWI743W.js +0 -1
- package/dist/app/chunks/css-2ZVPHE25.js +0 -1
- package/dist/app/chunks/graphql-7V2NP54C.js +0 -1
- package/dist/app/chunks/html-UF3LFLNA.js +0 -1
- package/dist/app/chunks/java-PNTAU4L3.js +0 -1
- package/dist/app/chunks/javascript-4JJTQGEL.js +0 -1
- package/dist/app/chunks/json-VLQ6D3JH.js +0 -1
- package/dist/app/chunks/jsx-KQKSLAAH.js +0 -1
- package/dist/app/chunks/lua-UFPYUJ2O.js +0 -1
- package/dist/app/chunks/r-QEZB45SR.js +0 -1
- package/dist/app/chunks/sql-DTZHNUZP.js +0 -1
- package/dist/app/chunks/tsx-WPR2WRZD.js +0 -1
- package/dist/app/chunks/typescript-LWO362OA.js +0 -1
- package/dist/app/chunks/xml-A5H72RTS.js +0 -1
- package/dist/app/chunks/yaml-MXHSIJCI.js +0 -1
- package/dist/src/services/purgePendingNodes.d.ts +0 -32
- package/dist/src/services/purgePendingNodes.d.ts.map +0 -1
- package/dist/src/services/purgePendingNodes.js +0 -61
- package/dist/src/services/purgePendingNodes.js.map +0 -1
- /package/dist/app/chunks/{chunk-737Y24HS.js → chunk-3JASFUPF.js} +0 -0
- /package/dist/app/chunks/{chunk-DKD2L57N.js → chunk-6EYLOQ4F.js} +0 -0
- /package/dist/app/chunks/{chunk-KYH5EHHY.js → chunk-7YRZ5LOQ.js} +0 -0
- /package/dist/app/chunks/{chunk-6TC3DVWV.js → chunk-C7LU4RID.js} +0 -0
- /package/dist/app/chunks/{chunk-TY33BMKR.js → chunk-CD52YDZP.js} +0 -0
- /package/dist/app/chunks/{chunk-OLEIKJ3X.js → chunk-DCJKTCJ5.js} +0 -0
- /package/dist/app/chunks/{chunk-QLBZ4JR2.js → chunk-EXIU2KBV.js} +0 -0
- /package/dist/app/chunks/{chunk-SFUNBBEA.js → chunk-FDP4LO4P.js} +0 -0
- /package/dist/app/chunks/{chunk-BGRVFATT.js → chunk-HNETUS7U.js} +0 -0
- /package/dist/app/chunks/{chunk-4QNMHAIR.js → chunk-LBFZJEDR.js} +0 -0
- /package/dist/app/chunks/{chunk-TRRUHDPN.js → chunk-ULRXL5VM.js} +0 -0
- /package/dist/app/chunks/{chunk-S6B4WWIF.js → chunk-XJK47SMJ.js} +0 -0
- /package/dist/app/chunks/{chunk-DZ5C5FKI.js → chunk-YYAAIAU2.js} +0 -0
- /package/dist/app/chunks/{clojure-OC6KPSJO.js → clojure-4QCN4GHG.js} +0 -0
- /package/dist/app/chunks/{core-KGE7TQJ3.js → core-ZHTX3P2Q.js} +0 -0
- /package/dist/app/chunks/{csharp-E7VIFITL.js → csharp-HQWR4N52.js} +0 -0
- /package/dist/app/chunks/{dark-plus-BOSCZXE4.js → dark-plus-GYPKKZES.js} +0 -0
- /package/dist/app/chunks/{dart-6Y3X27SZ.js → dart-FO4TTVO2.js} +0 -0
- /package/dist/app/chunks/{diff-TR2NPA64.js → diff-SHANV4YC.js} +0 -0
- /package/dist/app/chunks/{dist-T32U2VVR.js → dist-WSDF34DM.js} +0 -0
- /package/dist/app/chunks/{docker-N33HOW54.js → docker-VX55HTDS.js} +0 -0
- /package/dist/app/chunks/{go-6DGG5UTP.js → go-5UCPEC6S.js} +0 -0
- /package/dist/app/chunks/{haskell-KK36PMMM.js → haskell-25PJ3OSG.js} +0 -0
- /package/dist/app/chunks/{ini-VHVQ5TPB.js → ini-BJIVD5MK.js} +0 -0
- /package/dist/app/chunks/{kotlin-44WS3JHE.js → kotlin-MNR6XOEQ.js} +0 -0
- /package/dist/app/chunks/{less-5WZ3KLAK.js → less-KA5JURX6.js} +0 -0
- /package/dist/app/chunks/{light-plus-HGGBC43G.js → light-plus-QXH2UUWZ.js} +0 -0
- /package/dist/app/chunks/{make-X7RXMVW7.js → make-LPD5KOCO.js} +0 -0
- /package/dist/app/chunks/{markdown-46IKUAIB.js → markdown-LMWF6MQR.js} +0 -0
- /package/dist/app/chunks/{mdx-DGLHDAO7.js → mdx-WPMNN5BS.js} +0 -0
- /package/dist/app/chunks/{nix-Q6FYQZLX.js → nix-QGWLUUMZ.js} +0 -0
- /package/dist/app/chunks/{powershell-L4KJJ6DK.js → powershell-7GSBBEFF.js} +0 -0
- /package/dist/app/chunks/{prisma-IKS4LVH2.js → prisma-FPMPQISO.js} +0 -0
- /package/dist/app/chunks/{proto-AYCDOTJO.js → proto-7KDX5Z2U.js} +0 -0
- /package/dist/app/chunks/{python-KXMCSAFQ.js → python-CFG4FTQW.js} +0 -0
- /package/dist/app/chunks/{rust-J3BC3P6V.js → rust-X7A37WU3.js} +0 -0
- /package/dist/app/chunks/{scala-AYIIHBJK.js → scala-OYHJSUG2.js} +0 -0
- /package/dist/app/chunks/{swift-QPHHCQD3.js → swift-PE7VNYW5.js} +0 -0
- /package/dist/app/chunks/{toml-UV7JK7K7.js → toml-ETQRDILP.js} +0 -0
package/rules/brain-rules.md
CHANGED
|
@@ -10,7 +10,7 @@ activation:
|
|
|
10
10
|
|
|
11
11
|
## Discovery and identity
|
|
12
12
|
|
|
13
|
-
1. **Search before you create.**
|
|
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** →
|
|
40
|
-
|
|
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/
|
|
104
|
-
- https://docs.neuralisapp.com/
|
|
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
|
|
149
|
-
`p
|
|
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 `
|
|
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/
|
|
186
|
-
<https://docs.neuralisapp.com/
|
|
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
|
-
|
|
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/
|
|
283
|
-
examples, one per reach path: <https://docs.neuralisapp.com/
|
|
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/
|
|
162
|
-
- Credential scopes, the dynamic catalog and the encrypted store: <https://docs.neuralisapp.com/
|
|
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
|
-
**
|
|
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 `
|
|
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/
|
|
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 `
|
|
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
|
|
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/
|
|
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/<
|
|
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: `
|
|
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 & usage" docs pages:
|
|
169
|
-
<https://docs.neuralisapp.com/
|
|
170
|
-
<https://docs.neuralisapp.com/
|
|
171
|
-
<https://docs.neuralisapp.com/
|
|
172
|
-
<https://docs.neuralisapp.com/
|
|
173
|
-
<https://docs.neuralisapp.com/
|
|
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 `
|
|
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/
|
|
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
|
|
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/
|
|
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/
|
|
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
|
|
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/
|
|
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)
|
|
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
|
|
72
|
-
id
|
|
73
|
-
|
|
74
|
-
root itself is `
|
|
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 (`
|
|
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: `
|
|
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
|
-
`
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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/
|
|
502
|
-
registry: <https://docs.neuralisapp.com/
|
|
503
|
-
the three contract examples: <https://docs.neuralisapp.com/
|
|
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>
|
|
@@ -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/
|
|
42
|
-
# https://docs.neuralisapp.com/
|
|
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 "
|
|
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
|
-
#
|
|
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/
|
|
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
|
-
|
|
78
|
+
*://*)
|
|
79
79
|
cat >&2 <<'SRCFALLBACK'
|
|
80
80
|
|
|
81
81
|
Cannot verify programmatically. Do NOT record this package as working.
|
|
82
82
|
|
|
83
|
-
|
|
84
|
-
|
|
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
|
-
"
|
|
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
|
|
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.
|
|
246
|
-
w(' prefix included ("@acme/reports" is not "reports"). A
|
|
247
|
-
w('
|
|
248
|
-
w('
|
|
249
|
-
w('
|
|
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.
|
|
264
|
-
w(
|
|
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}) —
|
|
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
|