@neuralis/brain-core 0.4.0 → 0.4.1

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 (127) hide show
  1. package/README.md +2 -2
  2. package/dist/app/host.js +52 -55
  3. package/dist/src/config/env.d.ts +8 -0
  4. package/dist/src/config/env.d.ts.map +1 -1
  5. package/dist/src/config/env.js +17 -6
  6. package/dist/src/config/env.js.map +1 -1
  7. package/dist/src/domain/BrainError.d.ts +14 -0
  8. package/dist/src/domain/BrainError.d.ts.map +1 -1
  9. package/dist/src/domain/BrainError.js +21 -0
  10. package/dist/src/domain/BrainError.js.map +1 -1
  11. package/dist/src/domain/types.d.ts +5 -0
  12. package/dist/src/domain/types.d.ts.map +1 -1
  13. package/dist/src/embeddings/models.d.ts +1 -2
  14. package/dist/src/embeddings/models.d.ts.map +1 -1
  15. package/dist/src/embeddings/models.js +1 -2
  16. package/dist/src/embeddings/models.js.map +1 -1
  17. package/dist/src/lifecycle.d.ts +4 -5
  18. package/dist/src/lifecycle.d.ts.map +1 -1
  19. package/dist/src/lifecycle.js.map +1 -1
  20. package/dist/src/routes/approve.d.ts.map +1 -1
  21. package/dist/src/routes/approve.js +3 -3
  22. package/dist/src/routes/approve.js.map +1 -1
  23. package/dist/src/routes/health.d.ts.map +1 -1
  24. package/dist/src/routes/health.js +8 -5
  25. package/dist/src/routes/health.js.map +1 -1
  26. package/dist/src/routes/helpers.d.ts +10 -1
  27. package/dist/src/routes/helpers.d.ts.map +1 -1
  28. package/dist/src/routes/helpers.js +26 -0
  29. package/dist/src/routes/helpers.js.map +1 -1
  30. package/dist/src/routes/list.d.ts.map +1 -1
  31. package/dist/src/routes/list.js +3 -3
  32. package/dist/src/routes/list.js.map +1 -1
  33. package/dist/src/routes/pending.d.ts.map +1 -1
  34. package/dist/src/routes/pending.js +5 -5
  35. package/dist/src/routes/pending.js.map +1 -1
  36. package/dist/src/routes/raw.d.ts.map +1 -1
  37. package/dist/src/routes/raw.js +3 -3
  38. package/dist/src/routes/raw.js.map +1 -1
  39. package/dist/src/routes/read.d.ts.map +1 -1
  40. package/dist/src/routes/read.js +3 -3
  41. package/dist/src/routes/read.js.map +1 -1
  42. package/dist/src/routes/search.d.ts.map +1 -1
  43. package/dist/src/routes/search.js +3 -3
  44. package/dist/src/routes/search.js.map +1 -1
  45. package/dist/src/routes/sources.d.ts.map +1 -1
  46. package/dist/src/routes/sources.js +9 -9
  47. package/dist/src/routes/sources.js.map +1 -1
  48. package/dist/src/routes/upload.d.ts.map +1 -1
  49. package/dist/src/routes/upload.js +3 -3
  50. package/dist/src/routes/upload.js.map +1 -1
  51. package/dist/src/services/FilesystemService.d.ts.map +1 -1
  52. package/dist/src/services/FilesystemService.js +6 -0
  53. package/dist/src/services/FilesystemService.js.map +1 -1
  54. package/dist/src/services/FilesystemUiService.d.ts.map +1 -1
  55. package/dist/src/services/FilesystemUiService.js +5 -2
  56. package/dist/src/services/FilesystemUiService.js.map +1 -1
  57. package/dist/src/services/SyncScheduler.d.ts.map +1 -1
  58. package/dist/src/services/SyncScheduler.js +8 -2
  59. package/dist/src/services/SyncScheduler.js.map +1 -1
  60. package/dist/src/sync/SyncJobQueue.d.ts +7 -0
  61. package/dist/src/sync/SyncJobQueue.d.ts.map +1 -1
  62. package/dist/src/sync/SyncJobQueue.js +40 -0
  63. package/dist/src/sync/SyncJobQueue.js.map +1 -1
  64. package/dist/src/tools/execCtx.d.ts +6 -0
  65. package/dist/src/tools/execCtx.d.ts.map +1 -1
  66. package/dist/src/tools/execCtx.js +11 -0
  67. package/dist/src/tools/execCtx.js.map +1 -1
  68. package/dist/src/tools/fs_list.js +2 -2
  69. package/dist/src/tools/fs_list.js.map +1 -1
  70. package/dist/src/tools/fs_read.js +2 -2
  71. package/dist/src/tools/fs_read.js.map +1 -1
  72. package/dist/src/tools/fs_search.js +2 -2
  73. package/dist/src/tools/fs_search.js.map +1 -1
  74. package/dist/src/tools/fs_write.js +2 -2
  75. package/dist/src/tools/fs_write.js.map +1 -1
  76. package/dist/src/usecases/deprovisionProject.d.ts +4 -5
  77. package/dist/src/usecases/deprovisionProject.d.ts.map +1 -1
  78. package/dist/src/usecases/deprovisionProject.js +3 -8
  79. package/dist/src/usecases/deprovisionProject.js.map +1 -1
  80. package/dist/src/usecases/listSourcePackages.d.ts.map +1 -1
  81. package/dist/src/usecases/listSourcePackages.js +93 -74
  82. package/dist/src/usecases/listSourcePackages.js.map +1 -1
  83. package/dist/src/usecases/readFiles.d.ts.map +1 -1
  84. package/dist/src/usecases/readFiles.js +2 -1
  85. package/dist/src/usecases/readFiles.js.map +1 -1
  86. package/dist/src/usecases/searchFiles.d.ts.map +1 -1
  87. package/dist/src/usecases/searchFiles.js +13 -3
  88. package/dist/src/usecases/searchFiles.js.map +1 -1
  89. package/dist/src/usecases/sourcePackageInventory.d.ts +10 -2
  90. package/dist/src/usecases/sourcePackageInventory.d.ts.map +1 -1
  91. package/dist/src/usecases/sourcePackageInventory.js +24 -7
  92. package/dist/src/usecases/sourcePackageInventory.js.map +1 -1
  93. package/dist/src/usecases/vectorActivityWatch.d.ts +20 -13
  94. package/dist/src/usecases/vectorActivityWatch.d.ts.map +1 -1
  95. package/dist/src/usecases/vectorActivityWatch.js +61 -36
  96. package/dist/src/usecases/vectorActivityWatch.js.map +1 -1
  97. package/dist/src/usecases/vectorMaintenance.d.ts.map +1 -1
  98. package/dist/src/usecases/vectorMaintenance.js +16 -1
  99. package/dist/src/usecases/vectorMaintenance.js.map +1 -1
  100. package/dist/src/usecases/write/index.d.ts.map +1 -1
  101. package/dist/src/usecases/write/index.js +17 -2
  102. package/dist/src/usecases/write/index.js.map +1 -1
  103. package/dist/src/usecases/write/occupancy.d.ts +5 -1
  104. package/dist/src/usecases/write/occupancy.d.ts.map +1 -1
  105. package/dist/src/usecases/write/occupancy.js +13 -4
  106. package/dist/src/usecases/write/occupancy.js.map +1 -1
  107. package/dist/src/usecases/write/structure.d.ts.map +1 -1
  108. package/dist/src/usecases/write/structure.js +20 -5
  109. package/dist/src/usecases/write/structure.js.map +1 -1
  110. package/dist/src/vector/FilesystemVectorIndex.d.ts +72 -2
  111. package/dist/src/vector/FilesystemVectorIndex.d.ts.map +1 -1
  112. package/dist/src/vector/FilesystemVectorIndex.js +211 -27
  113. package/dist/src/vector/FilesystemVectorIndex.js.map +1 -1
  114. package/dist/src/vector/InMemoryVectorIndex.d.ts.map +1 -1
  115. package/dist/src/vector/InMemoryVectorIndex.js +55 -7
  116. package/dist/src/vector/InMemoryVectorIndex.js.map +1 -1
  117. package/dist/src/vector/qdrantClient.d.ts +17 -0
  118. package/dist/src/vector/qdrantClient.d.ts.map +1 -1
  119. package/dist/src/vector/qdrantClient.js +47 -5
  120. package/dist/src/vector/qdrantClient.js.map +1 -1
  121. package/dist/src/wiring.d.ts +7 -12
  122. package/dist/src/wiring.d.ts.map +1 -1
  123. package/dist/src/wiring.js +29 -55
  124. package/dist/src/wiring.js.map +1 -1
  125. package/package.json +24 -3
  126. package/skills/manage-files/SKILL.md +1 -1
  127. package/skills/sync/SKILL.md +1 -1
package/README.md CHANGED
@@ -101,7 +101,7 @@ in the `neuralis-brain-core` skill; the git-plane security floors in `neuralis-s
101
101
 
102
102
  Lifecycle exports (`src/lifecycle.ts`):
103
103
 
104
- - `init`, `start`, `onBootstrapComplete`, `drain`, `stop`, `api`, `onCredentialChanged`, `health`, `onPrincipalRevoked`, `provisionProject` (`usecases/provisionProject.ts` — a NEW project's declared `seed:'auto'` sources, written complete through the same create path as the boot repair; see `src/services/README.md`), `deprovisionProject` (`usecases/deprovisionProject.ts` — on a PERMANENT project delete, ALL of the project's vector points leave the shared index in ONE bounded `deleteByFilter({ must: [{ field: 'projectId', equals: id }] })` — chunks + folder-ancestor points covered by the same keyword-index filter. MUST-HAVE: a failed delete throws, and so does a degraded boot where Qdrant is configured but the in-memory index is wired (a delete there would leave every real point in Qdrant); the host then stops the purge before any file is removed. It runs BEFORE the fs tree is removed, so resolving the brain infra cannot re-materialize the project dir).
104
+ - `init`, `start`, `onBootstrapComplete`, `drain`, `stop`, `api`, `onCredentialChanged`, `health`, `onPrincipalRevoked`, `provisionProject` (`usecases/provisionProject.ts` — a NEW project's declared `seed:'auto'` sources, written complete through the same create path as the boot repair; see `src/services/README.md`), `deprovisionProject` (`usecases/deprovisionProject.ts` — on a PERMANENT project delete, ALL of the project's vector points leave the shared index in ONE bounded `deleteByFilter({ must: [{ field: 'projectId', equals: id }] })` — chunks + folder-ancestor points covered by the same keyword-index filter. MUST-HAVE: a failed delete throws — an unavailable vector store included (the typed `vector_store_unavailable` refusal) — and the host then stops the purge before any file is removed. It runs BEFORE the fs tree is removed, so resolving the brain infra cannot re-materialize the project dir).
105
105
  - `init` state exposes `services["package-source-roots"]` for kernel registration; its `listPackageSourceRoots` delegate is the same function as the direct API method, and its `subscribePackageSourceRoots(listener)` calls `listener(projectId)` after every committed source-config write of the app root (`SourceConfigMutation.onChanged` — fired outside the write lock, a no-op write never fires, a throwing listener is logged and never reaches the writer), so the host re-derives that project's flagged package roots at once.
106
106
  - `BrainCoreApi` — `getProjectServices`, `getProjectInfra`, `getFilesystem`, `upsertSourceConfig`, `listShellSourceRoots(projectId)` (every shell-capable source with its persisted permissions; feeds agent-core's shell uri-policy gate and the terminal's host-tab resolver; NOT access-filtered — consumers evaluate the policy against the caller's own `SessionContext`. Rows carry an explicit **`plane`**: `container` sources contribute their `containerRoot`, resolved by the canonical `resolveLocalRoot`; **device-plane** sources contribute a raw `hostRoot` and an intentionally EMPTY `containerRoot` — no container path exists for them, and the empty value is load-bearing, because the consumer's local-plane filter drops rootless entries so a folder on a device can never leak into a local-plane lookup even if `plane` were ignored. The plane is the kernel's `sourcePlane` over the STORED connection (a `host` folder naming a `device` is the device plane), never the slug string — an ordinary folder may legitimately be named `host-notes`. Kinds that host no shell at all (brain vectors, webtop) contribute nothing), and `listSourceRuntimeSummaries(projectId, { userId, agentId, role?, grantedFeatures? })` (the READ sibling of `listShellSourceRoots`, feeding agent-core's `<runtime_stack>` source rendering — **all** connector kinds, **access-filtered** (device-plane rows carry `containerDir: null` — their root is a path in the OPERATOR's filesystem with no container equivalent, and the local-shaped derivation would otherwise print a container path that does not exist, baked into every agent's cached system prompt) via `canAccessScope` (with the source's plane: a user-scope device folder lists only for its owner) → `files.readOthers`/deny-by-default, each row carrying connector, `os_uri`/`container_dir`, the caller-effective uri-policy, `description`, and the cached index snapshot; reads persisted source-config JSON ONLY — no live walk / no vector count — so it is safe to call once per stream. Agent-core renders the stable structure in the cached `<runtime_stack>` prefix and the volatile counts + on/off in `<workspace_live>`. Disabled sources are INCLUDED, marked `enabledEffective:false`). `listPackageSourceRoots(projectId)` (enumerate every project-associated source as a runtime package-source candidate `{ slug, uriRoot, containerRoot, scope, plane, packageFolders, enabled, kind }` — `plane` is `sourcePlane` of the stored connection, the host's only source of it; identity-free like `listShellSourceRoots`, ALL candidates returned so the host applies the floor — package folders + enabled + a root this process opens; `containerRoot` of a device folder is agent-core's `devices.localFolderRoot` answer, asked only on a native host for a folder with package folders — the app's own loopback device inside the owner's ceiling — and `''` for any other device; the host's `projectPackages` consumes it to scan + hot-reload each package folder alongside `_packages/`). Filesystem events reach the `/brain-core/events` SSE route and the discovered `filesystem` channel of the host `/api/events` hub through ONE authorization adapter: it takes the real session, authorizes EACH requested agent deny-by-default (a foreign agent yields zero events, never an existence-confirming error), and filters events by user/project/types and the authorized agent or source.
107
107
 
@@ -143,7 +143,7 @@ There is intentionally no README inside the contribution folders; this section i
143
143
  ## How it plugs into the package-system kernel
144
144
 
145
145
  - `init(ctx: PackageInitContext)` builds shared infra (Qdrant + lazy embedder), the per-project `CommunityInfraFactory`, the global `AppSourceConfigStore`, the per-package sync/vector loggers, and the `VectorHealthService`. It returns a `BrainCoreState` and never starts the sync scheduler.
146
- - `start(state)` begins the background vector activity watch (`startQdrantWatch` wires `usecases/vectorActivityWatch.ts`, every `brainQdrantWatchIntervalMs` — 30 s — `BRAIN_INFRA_MODE=local` only). The vector backend wired at init is **not** hot-swapped (out of scope); the watch surfaces a degraded flag and logs transitions — `vector.qdrant.lost` and `vector.qdrant.recovered` (the latter notes that a restart re-enables Qdrant-backed search when the wired backend is in-memory). While Qdrant is reachable the same tick reads the server's optimizer tracker (one `GET /collections/<c>/optimizations?with=completed`, at most 50 finished runs) — Qdrant does not log its own background optimization — and writes `vector.optimizer.completed {optimizer, status, points, segments, durationMs}` once per finished run (the SERVER's start/finish times, so a run shorter than the tick is not lost), `vector.optimizer.long` once for a run still going after 10 minutes, and `vector.optimizer.overflow {returned}` when every returned run is new while earlier ones were seen (the tracker rolled past runs between two reads). The first read only seeds: runs finished before the process started are not re-logged at every boot. These lines go to the console (`docker logs`) AND `vector.jsonl`; the per-probe `vector.qdrant.health` line stays file-only. The lifecycle `health(state)` returns structured backend/connectivity checks to the generic runtime health aggregate; no vector-status package API is exposed. The interval is cleared in `stop()`.
146
+ - `start(state)` begins the background vector activity watch (`startQdrantWatch` wires `usecases/vectorActivityWatch.ts`, every `brainQdrantWatchIntervalMs` — 30 s — whenever the backend is Qdrant, `local` and `real` alike). Qdrant is wired at init whenever it is intended, reachable or not; the watch is what drives its availability gate: one bounded probe at a time (a probe-only client bounded by `brainQdrantProbeTimeoutMs`, 5 s, boot-read), one immediate probe when a call finds the store gone, and on the first answer the boot-once steps (server-version read, embedding-generation boot with its collection ensure) run once before the gate opens — no restart, ever. It logs `vector.qdrant.lost` and `vector.qdrant.recovered` (held sync jobs then run) and reports `degraded` / `store_unreachable` to health while the gate is closed. Every Qdrant request is bounded by `brainQdrantRequestTimeoutMs` (default 300 000 — the client's own default, so no long index build is newly aborted; boot-read). While Qdrant is reachable the same tick reads the server's optimizer tracker (one `GET /collections/<c>/optimizations?with=completed`, at most 50 finished runs) — Qdrant does not log its own background optimization — and writes `vector.optimizer.completed {optimizer, status, points, segments, durationMs}` once per finished run (the SERVER's start/finish times, so a run shorter than the tick is not lost), `vector.optimizer.long` once for a run still going after 10 minutes, and `vector.optimizer.overflow {returned}` when every returned run is new while earlier ones were seen (the tracker rolled past runs between two reads). The first read only seeds: runs finished before the process started are not re-logged at every boot. These lines go to the console (`docker logs`) AND `vector.jsonl`; the per-probe `vector.qdrant.health` line stays file-only. The lifecycle `health(state)` returns structured backend/connectivity checks to the generic runtime health aggregate; no vector-status package API is exposed. The interval is cleared in `stop()`.
147
147
  - `onBootstrapComplete(state, ctx: BootstrapCompleteContext)` is the single deferred-wiring entry point: it reads the published registries through `ctx.platform.connectorRegistries()` and starts the `SyncScheduler` from `ctx.platform.hostIdentity()`. The factory resolves those registries lazily through its init context. There are no imperative setters (`setHostIdentity`, `setConnectorRegistries`).
148
148
  - `init` delegates to `wiring.buildBrainState`, wiring the declared `ctx.config` reader and GLOBAL-only `ctx.credentials.resolveCredential` into the embedding provider before shared infrastructure is built. Platform facts are read lazily through `ctx.platform`; no config setter or source-running bootstrap push is exposed. Credential changes reach the bounded lifecycle hook, and runtime health reads structured vector checks.
149
149
  - **Data formats.** brain-core's three durable record kinds — `brain-core/embedding-lock` (v3), `brain-core/source-config` (v7) and `brain-core/pending-changes` (v1, the `_pending/changes.jsonl` journal) — are declared on the kernel's data-format ledger at module load (`src/store/dataFormats.ts`) and claimed at the top of `init`, before the first read: a kind a newer binary raised stops the init by name. Per record, the lock's `version` and a source config's or pending change's `formatVersion` (absent = 1) are checked before every rewrite — the check reads the STORED record, never the incoming one, so a config built fresh over a newer file is refused too — and a newer record is never rewritten (the journal's appends stay open; its compaction refuses). Every source-config write stamps the declared version (`SOURCE_CONFIG_FORMAT.version`, 7); an identical re-upsert still writes nothing. `embedding-lock` v3 and `source-config` v7 are `upgrade: offline` kinds: the app refuses to start over older data naming `neuralis upgrade`, which raises them (`scripts/embeddingLockV3.ts`, exported as `@neuralis/brain-core/upgrade`; `source-config` is a chain — the host's `package-identity-v2` step, then `scripts/sourceRootPairV1.ts`, exported as `@neuralis/brain-core/upgrade/source-root-pair`, which fills the root pairs, then `scripts/sourceToFolderV1.ts`, exported as `@neuralis/brain-core/upgrade/source-to-folder`, which merges the old `local` and `host` records into ONE `folder` kind and turns `recognizesPackages` into `packageFolders`, then `scripts/sourceToHostV1.ts`, exported as `@neuralis/brain-core/upgrade/source-to-host`, which spells that kind `host`, then the host's `source-uri-subject-v1` step, which moves owner/admin grant rows to `priority` (the caller's role priority, n or stronger), then the host's `source-use-grants-v1` step, which places agent-core's private-agent rows right after a project's first agent-folder write row and appends one read row per user who already used an agent they did not create — each step passes a record a later step already raised through untouched, so a resumed chain never re-reads one in an older vocabulary). Source configs are written durably, and one that fails validation is skipped AND logged (`source-config.invalid-skipped`), never silently gone.