@semiont/core 0.4.18 → 0.4.20

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 CHANGED
@@ -193,22 +193,36 @@ import { fetchAPI, createFetchAPI } from '@semiont/core';
193
193
  const response = await fetchAPI(url, { method: 'POST', body: data });
194
194
  ```
195
195
 
196
- ### Backend-Specific Annotation Utilities
196
+ ### Annotation body matcher
197
197
 
198
- Utilities that work with internal backend types:
198
+ `findBodyItem` locates a body item in an annotation body by identity
199
+ (type + source for `SpecificResource`, type + value for `TextualBody`).
200
+ Used by the `mark:body-updated` event replay path to apply add / remove /
201
+ replace operations.
199
202
 
200
203
  ```typescript
201
- import { bodyItemsMatch, findBodyItem } from '@semiont/core';
202
-
203
- // Find specific body item in annotation
204
- const item = findBodyItem(annotation.body, (item) => item.purpose === 'tagging');
205
-
206
- // Check if two body items match
207
- if (bodyItemsMatch(item1, item2)) {
208
- // ...
209
- }
204
+ import { findBodyItem, type BodyItemIdentity } from '@semiont/core';
205
+
206
+ // Loose match: any body item with this source, regardless of purpose.
207
+ // This is the common case for Semiont's bind/unbind flow.
208
+ const index = findBodyItem(annotation.body, {
209
+ type: 'SpecificResource',
210
+ source: 'https://example.com/target',
211
+ });
212
+
213
+ // Strict match: disambiguate among same-source bodies under different
214
+ // purposes. Needed when an annotation has multiple SpecificResource bodies
215
+ // pointing at the same target under different W3C purposes.
216
+ const linkingIdx = findBodyItem(annotation.body, {
217
+ type: 'SpecificResource',
218
+ source: 'https://example.com/target',
219
+ purpose: 'linking',
220
+ });
210
221
  ```
211
222
 
223
+ `purpose` is optional in the identity. Omit it to match on identity alone;
224
+ provide it when the caller knows which purpose to target.
225
+
212
226
  ### Backend Internal Types
213
227
 
214
228
  Types not in the OpenAPI spec:
@@ -14,6 +14,7 @@ import { E as EnvironmentConfig } from '../config.types-oPv3Ajk-.js';
14
14
  * configDir — $XDG_CONFIG_HOME/semiont/{name}/ (generated config for managed processes)
15
15
  * dataHome — $XDG_DATA_HOME/semiont/{name}/ (persistent user data, e.g. database files)
16
16
  * stateDir — $XDG_STATE_HOME/semiont/{name}/
17
+ * embeddingsDir — stateDir/embeddings/
17
18
  * projectionsDir — stateDir/projections/
18
19
  * jobsDir — stateDir/jobs/
19
20
  * backendLogsDir — stateDir/backend/
@@ -37,6 +38,7 @@ declare class SemiontProject {
37
38
  readonly configDir: string;
38
39
  readonly dataHome: string;
39
40
  readonly stateDir: string;
41
+ readonly embeddingsDir: string;
40
42
  readonly projectionsDir: string;
41
43
  readonly jobsDir: string;
42
44
  readonly backendLogsDir: string;
@@ -293,6 +293,7 @@ var SemiontProject = class _SemiontProject {
293
293
  dataHome;
294
294
  // Ephemeral — state
295
295
  stateDir;
296
+ embeddingsDir;
296
297
  projectionsDir;
297
298
  jobsDir;
298
299
  backendLogsDir;
@@ -322,6 +323,7 @@ name = "${name}"
322
323
  this.dataHome = path.join(xdgData, "semiont", this.name);
323
324
  const xdgState = process.env.XDG_STATE_HOME || path.join(os.homedir(), ".local", "state");
324
325
  this.stateDir = path.join(xdgState, "semiont", this.name);
326
+ this.embeddingsDir = path.join(this.stateDir, "embeddings");
325
327
  this.projectionsDir = path.join(this.stateDir, "projections");
326
328
  this.jobsDir = path.join(this.stateDir, "jobs");
327
329
  this.backendLogsDir = path.join(this.stateDir, "backend");
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/config/toml-loader.ts","../../src/project.ts","../../src/config/node-config-loader.ts"],"names":["parseToml","fs2","path2","os2"],"mappings":";;;;;;;AA0BA,SAAS,SAAA,CAA6C,MAAS,QAAA,EAAyB;AACtF,EAAA,MAAM,MAAA,GAAS,EAAE,GAAG,IAAA,EAAK;AACzB,EAAA,KAAA,MAAW,GAAA,IAAO,MAAA,CAAO,IAAA,CAAK,QAAQ,CAAA,EAAG;AACvC,IAAA,MAAM,CAAA,GAAI,KAAK,GAAG,CAAA;AAClB,IAAA,MAAM,CAAA,GAAI,SAAS,GAAG,CAAA;AACtB,IAAA,IAAI,CAAA,KAAM,UAAa,CAAA,KAAM,IAAA,IAAQ,OAAO,CAAA,KAAM,QAAA,IAAY,CAAC,KAAA,CAAM,OAAA,CAAQ,CAAC,KAC1E,CAAA,KAAM,MAAA,IAAa,CAAA,KAAM,IAAA,IAAQ,OAAO,CAAA,KAAM,YAAY,CAAC,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,EAAG;AAC/E,MAAA,MAAA,CAAO,GAAG,CAAA,GAAI,SAAA,CAAU,CAAA,EAA8B,CAA4B,CAAA;AAAA,IACpF,CAAA,MAAA,IAAW,MAAM,MAAA,EAAW;AAC1B,MAAA,MAAA,CAAO,GAAG,CAAA,GAAI,CAAA;AAAA,IAChB;AAAA,EACF;AACA,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,cAAA,CAAe,KAAc,GAAA,EAAkD;AACtF,EAAA,IAAI,OAAO,QAAQ,QAAA,EAAU;AAC3B,IAAA,OAAO,GAAA,CAAI,OAAA,CAAQ,gBAAA,EAAkB,CAAC,OAAO,OAAA,KAAY;AACvD,MAAA,IAAI,GAAA,CAAI,OAAO,CAAA,KAAM,MAAA,EAAW;AAC9B,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,qBAAA,EAAwB,OAAO,CAAA,qCAAA,EAAwC,KAAK,CAAA,CAAA,CAAG,CAAA;AAAA,MACjG;AACA,MAAA,OAAO,IAAI,OAAO,CAAA;AAAA,IACpB,CAAC,CAAA;AAAA,EACH;AACA,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA,EAAG;AACtB,IAAA,OAAO,IAAI,GAAA,CAAI,CAAA,IAAA,KAAQ,cAAA,CAAe,IAAA,EAAM,GAAG,CAAC,CAAA;AAAA,EAClD;AACA,EAAA,IAAI,GAAA,KAAQ,IAAA,IAAQ,OAAO,GAAA,KAAQ,QAAA,EAAU;AAC3C,IAAA,MAAM,WAAoC,EAAC;AAC3C,IAAA,KAAA,MAAW,OAAO,GAAA,EAAgC;AAChD,MAAA,QAAA,CAAS,GAAG,CAAA,GAAI,cAAA,CAAgB,GAAA,CAAgC,GAAG,GAAG,GAAG,CAAA;AAAA,IAC3E;AACA,IAAA,OAAO,QAAA;AAAA,EACT;AACA,EAAA,OAAO,GAAA;AACT;AAkJA,SAAS,eAAA,CAAgB,OAA2B,WAAA,EAAmC;AACrF,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,kCAAA,EAAqC,WAAW,CAAA,8EAAA,CAA2E,CAAA;AAAA,EAC7I;AACA,EAAA,OAAO,KAAA;AACT;AAaO,SAAS,cAAA,CACd,WAAA,EACA,WAAA,EACA,gBAAA,EACA,QACA,GAAA,EACmB;AAEnB,EAAA,MAAM,uBAAuB,WAAA,GAAc,MAAA,CAAO,aAAa,CAAA,EAAG,WAAW,kBAAkB,CAAA,GAAI,IAAA;AACnG,EAAA,IAAI,WAAA,GAAc,iBAAA;AAClB,EAAA,IAAI,cAAA;AACJ,EAAA,IAAI,WAAA;AACJ,EAAA,IAAI,oBAAwC,EAAC;AAC7C,EAAA,IAAI,oBAAA,EAAsB;AACxB,IAAA,MAAM,aAAA,GAAgBA,MAAU,oBAAoB,CAAA;AAKpD,IAAA,WAAA,GAAc,aAAA,CAAc,SAAS,IAAA,IAAQ,WAAA;AAC7C,IAAA,cAAA,GAAiB,cAAc,OAAA,EAAS,OAAA;AACxC,IAAA,WAAA,GAAc,aAAA,CAAc,IAAA;AAC5B,IAAA,iBAAA,GAAoB,aAAA,CAAc,YAAA,GAAe,WAAW,CAAA,IAAK,EAAC;AAAA,EACpE;AAGA,EAAA,MAAM,aAAA,GAAgB,MAAA,CAAO,YAAA,CAAa,gBAAgB,CAAA;AAC1D,EAAA,MAAM,GAAA,GAAM,aAAA,GAAiBA,KAAA,CAAU,aAAa,IAA2B,EAAC;AAGhF,EAAA,MAAM,cAAA,GAAqC,GAAA,CAAI,YAAA,GAAe,WAAW,KAAK,EAAC;AAC/E,EAAA,MAAM,UAAA,GAAiC,SAAA;AAAA,IACrC,iBAAA;AAAA,IACA;AAAA,GACF;AAGA,EAAA,MAAM,QAAA,GAAW,cAAA,CAAe,UAAA,EAAY,GAAG,CAAA;AAM/C,EAAA,MAAM,gBAAgB,QAAA,CAAS,SAAA;AAC/B,EAAA,MAAM,kBAAA,GAAqB,SAAS,cAAc,CAAA;AAClD,EAAA,MAAM,cAAA,GAAiB,QAAA,CAAS,OAAA,IAAW,EAAC;AAC5C,EAAA,MAAM,aAAA,GAAgB,QAAA,CAAS,MAAA,IAAU,EAAC;AAC1C,EAAA,MAAM,sBAAA,GAAyB,cAAA,CAAe,SAAS,CAAA,EAAG,SAAA;AAC1D,EAAA,MAAM,2BAAA,GAA8B,oBAAoB,OAAA,EAAS,SAAA;AAEjE,EAAA,SAAS,uBAAuB,QAAA,EAA4C;AAC1E,IAAA,IAAI,CAAC,eAAe,OAAO,QAAA;AAG3B,IAAA,MAAM,mBAA6C,EAAC;AACpD,IAAA,IAAI,QAAA,CAAS,SAAS,WAAA,EAAa;AACjC,MAAA,MAAM,IAAI,aAAA,CAAc,SAAA;AACxB,MAAA,IAAI,CAAA,EAAG;AACL,QAAA,gBAAA,CAAiB,SAAS,CAAA,CAAE,MAAA;AAC5B,QAAA,gBAAA,CAAiB,WAAW,CAAA,CAAE,QAAA;AAAA,MAChC,CAAA,MAAO;AACL,QAAA,IAAI,CAAC,cAAc,IAAA,EAAM;AACvB,UAAA,MAAM,IAAI,KAAA;AAAA,YACR,iBAAiB,WAAW,CAAA,+FAAA;AAAA,WAE9B;AAAA,QACF;AACA,QAAA,gBAAA,CAAiB,SAAS,aAAA,CAAc,MAAA;AACxC,QAAA,gBAAA,CAAiB,WAAW,aAAA,CAAc,QAAA;AAAA,MAC5C;AAAA,IACF,CAAA,MAAA,IAAW,QAAA,CAAS,IAAA,KAAS,QAAA,EAAU;AACrC,MAAA,MAAM,IAAI,aAAA,CAAc,MAAA;AACxB,MAAA,IAAI,CAAA,EAAG;AACL,QAAA,gBAAA,CAAiB,UAAU,CAAA,CAAE,OAAA;AAAA,MAC/B,CAAA,MAAO;AACL,QAAA,IAAI,CAAC,cAAc,IAAA,EAAM;AACvB,UAAA,MAAM,IAAI,KAAA;AAAA,YACR,iBAAiB,WAAW,CAAA,yFAAA;AAAA,WAE9B;AAAA,QACF;AACA,QAAA,gBAAA,CAAiB,UAAU,aAAA,CAAc,OAAA;AAAA,MAC3C;AAAA,IACF;AACA,IAAA,OAAO;AAAA,MACL,WAAW,aAAA,CAAc,SAAA;AAAA,MACzB,GAAG,gBAAA;AAAA,MACH,GAAG;AAAA,KACL;AAAA,EACF;AAEA,EAAA,SAAS,qBAAA,CAAsB,iBAAmC,UAAA,EAA2D;AAC3H,IAAA,MAAM,IAAA,GAAO,mBAAmB,UAAA,IAAc,2BAAA;AAC9C,IAAA,IAAI,CAAC,MAAM,OAAO,MAAA;AAClB,IAAA,OAAO,uBAAuB,IAAI,CAAA;AAAA,EACpC;AAEA,EAAA,MAAM,SAA+B,EAAC;AACtC,EAAA,MAAM,iBAAA,GAAoB,qBAAA;AAAA,IACxB,kBAAA,EAAoB,QAAQ,QAAA,EAAU,SAAA;AAAA,IACtC,aAAA,CAAc,UAAU,CAAA,EAAG;AAAA,GAC7B;AACA,EAAA,IAAI,iBAAA,SAA0B,QAAA,GAAW,iBAAA;AAEzC,EAAA,MAAM,gBAAA,GAAmB,qBAAA;AAAA,IACvB,kBAAA,EAAoB,QAAQ,OAAA,EAAS,SAAA;AAAA,IACrC,aAAA,CAAc,SAAS,CAAA,EAAG;AAAA,GAC5B;AACA,EAAA,IAAI,gBAAA,SAAyB,OAAA,GAAU,gBAAA;AAEvC,EAAA,MAAM,UAAiC,EAAC;AACxC,EAAA,MAAM,cAAc,CAAC,sBAAA,EAAwB,wBAAwB,uBAAA,EAAyB,oBAAA,EAAsB,kBAAkB,YAAY,CAAA;AAClJ,EAAA,IAAI,sBAAA,EAAwB;AAC1B,IAAA,OAAA,CAAQ,OAAA,GAAU,uBAAuB,sBAAsB,CAAA;AAAA,EACjE;AACA,EAAA,KAAA,MAAW,MAAM,WAAA,EAAa;AAC5B,IAAA,MAAM,QAAA,GAAW,cAAA,CAAe,EAAE,CAAA,EAAG,SAAA;AACrC,IAAA,IAAI,QAAA,EAAU;AACZ,MAAC,OAAA,CAA4C,EAAE,CAAA,GAAI,sBAAA,CAAuB,QAAQ,CAAA;AAAA,IACpF;AAAA,EACF;AAGA,EAAA,MAAM,UAAU,QAAA,CAAS,OAAA;AACzB,EAAA,MAAM,IAAA,GAAO,SAAS,IAAA,IAAQ,WAAA;AAC9B,EAAA,MAAM,mBAAmB,QAAA,CAAS,SAAA;AAMlC,EAAA,IAAI,kBAAA;AACJ,EAAA,IAAI,gBAAA,EAAkB;AACpB,IAAA,kBAAA,GAAqB,EAAC;AAEtB,IAAA,IAAI,iBAAiB,SAAA,EAAW;AAC9B,MAAA,MAAM,IAAI,gBAAA,CAAiB,SAAA;AAC3B,MAAA,kBAAA,CAAmB,SAAA,GAAY;AAAA,QAC7B,QAAA,EAAU,eAAA,CAAgB,CAAA,CAAE,QAAA,EAAU,qBAAqB,CAAA;AAAA,QAC3D,QAAA,EAAU,EAAE,QAAA,IAAY,2BAAA;AAAA,QACxB,MAAA,EAAQ,EAAE,MAAA,IAAU;AAAA,OACtB;AAAA,IACF,CAAA,MAAA,IAAW,gBAAA,CAAiB,IAAA,KAAS,WAAA,EAAa;AAChD,MAAA,kBAAA,CAAmB,SAAA,GAAY;AAAA,QAC7B,QAAA,EAAU,eAAA,CAAgB,gBAAA,CAAiB,QAAA,EAAU,WAAW,CAAA;AAAA,QAChE,QAAA,EAAU,iBAAiB,QAAA,IAAY,2BAAA;AAAA,QACvC,MAAA,EAAQ,iBAAiB,MAAA,IAAU;AAAA,OACrC;AAAA,IACF;AACA,IAAA,IAAI,iBAAiB,MAAA,EAAQ;AAC3B,MAAA,MAAM,IAAI,gBAAA,CAAiB,MAAA;AAC3B,MAAA,kBAAA,CAAmB,MAAA,GAAS;AAAA,QAC1B,UAAU,EAAE,IAAA,EAAM,gBAAgB,CAAA,CAAE,QAAA,EAAU,kBAAkB,CAAA,EAAE;AAAA,QAClE,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,IAAA,EAAM,CAAA,CAAE,OAAA,GAAU,MAAA,GAAa,EAAE,IAAA,IAAQ;AAAA,OAC3C;AAAA,IACF,CAAA,MAAA,IAAW,gBAAA,CAAiB,IAAA,KAAS,QAAA,EAAU;AAC7C,MAAA,kBAAA,CAAmB,MAAA,GAAS;AAAA,QAC1B,UAAU,EAAE,IAAA,EAAM,gBAAgB,gBAAA,CAAiB,QAAA,EAAU,WAAW,CAAA,EAAE;AAAA,QAC1E,SAAS,gBAAA,CAAiB,OAAA;AAAA,QAC1B,IAAA,EAAM,gBAAA,CAAiB,OAAA,GAAU,MAAA,GAAY;AAAA,OAC/C;AAAA,IACF;AAAA,EACF;AAGA,EAAA,MAAM,kBAAgD,EAAC;AACvD,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,cAAc,CAAA,EAAG;AACtD,IAAA,IAAI,EAAE,SAAA,EAAW;AACf,MAAA,eAAA,CAAgB,IAAI,CAAA,GAAI,EAAE,SAAA,EAAW,EAAE,IAAA,EAAM,CAAA,CAAE,SAAA,CAAU,IAAA,EAAM,KAAA,EAAO,CAAA,CAAE,SAAA,CAAU,OAAM,EAAE;AAAA,IAC5F;AAAA,EACF;AACA,EAAA,MAAM,iBAA8C,EAAC;AACrD,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,aAAa,CAAA,EAAG;AACrD,IAAA,IAAI,EAAE,SAAA,EAAW;AACf,MAAA,cAAA,CAAe,IAAI,CAAA,GAAI,EAAE,SAAA,EAAW,EAAE,IAAA,EAAM,CAAA,CAAE,SAAA,CAAU,IAAA,EAAM,KAAA,EAAO,CAAA,CAAE,SAAA,CAAU,OAAM,EAAE;AAAA,IAC3F;AAAA,EACF;AAEA,EAAA,IAAI,kBAAA,EAAoB,MAAA,EAAQ,QAAA,EAAU,SAAA,EAAW;AACnD,IAAA,cAAA,CAAe,UAAU,CAAA,GAAI,EAAE,SAAA,EAAW,EAAE,MAAM,kBAAA,CAAmB,MAAA,CAAO,QAAA,CAAS,SAAA,CAAU,MAAM,KAAA,EAAO,kBAAA,CAAmB,OAAO,QAAA,CAAS,SAAA,CAAU,OAAM,EAAE;AAAA,EACnK;AACA,EAAA,IAAI,kBAAA,EAAoB,MAAA,EAAQ,OAAA,EAAS,SAAA,EAAW;AAClD,IAAA,cAAA,CAAe,SAAS,CAAA,GAAI,EAAE,SAAA,EAAW,EAAE,MAAM,kBAAA,CAAmB,MAAA,CAAO,OAAA,CAAQ,SAAA,CAAU,MAAM,KAAA,EAAO,kBAAA,CAAmB,OAAO,OAAA,CAAQ,SAAA,CAAU,OAAM,EAAE;AAAA,EAChK;AAEA,EAAA,MAAM,WAAW,QAAA,CAAS,QAAA;AAE1B,EAAA,MAAM,WAA0C,EAAC;AAEjD,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,QAAA,CAAS,OAAA,GAAU;AAAA,MACjB,UAAU,EAAE,IAAA,EAAM,gBAAgB,OAAA,CAAQ,QAAA,EAAU,SAAS,CAAA,EAAE;AAAA,MAC/D,IAAA,EAAM,QAAQ,IAAA,IAAQ,GAAA;AAAA,MACtB,WAAW,OAAA,CAAQ,SAAA,IAAa,CAAA,iBAAA,EAAoB,OAAA,CAAQ,QAAQ,GAAI,CAAA,CAAA;AAAA,MACxE,UAAA,EAAY,OAAA,CAAQ,UAAA,IAAc,OAAA,CAAQ,WAAA,IAAe;AAAA,KAC3D;AAAA,EACF;AAEA,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,QAAA,CAAS,QAAA,GAAW;AAAA,MAClB,UAAU,EAAE,IAAA,EAAM,gBAAgB,QAAA,CAAS,QAAA,EAAU,UAAU,CAAA,EAAE;AAAA,MACjE,IAAA,EAAM,SAAS,IAAA,IAAQ,GAAA;AAAA,MACvB,QAAA,EAAU,MAAM,QAAA,IAAY,SAAA;AAAA,MAC5B,WAAW,QAAA,CAAS;AAAA,KACtB;AAAA,EACF;AAEA,EAAA,IAAI,SAAS,KAAA,EAAO;AAClB,IAAA,QAAA,CAAS,KAAA,GAAQ;AAAA,MACf,GAAG,QAAA,CAAS,KAAA;AAAA,MACZ,QAAA,EAAU,EAAE,IAAA,EAAM,eAAA,CAAgB,SAAS,KAAA,CAAM,QAAA,EAAgC,OAAO,CAAA,EAAE;AAAA,MAC1F,IAAA,EAAO,QAAA,CAAS,KAAA,CAAM,IAAA,IAAQ;AAAA,KAChC;AAAA,EACF,CAAA,MAAA,IAAW,oBAAoB,KAAA,EAAO;AACpC,IAAA,QAAA,CAAS,QAAQ,kBAAA,CAAmB,KAAA;AAAA,EACtC;AAEA,EAAA,IAAI,SAAS,QAAA,EAAU;AACrB,IAAA,QAAA,CAAS,QAAA,GAAW;AAAA,MAClB,QAAA,EAAU,EAAE,IAAA,EAAM,eAAA,CAAgB,SAAS,QAAA,CAAS,QAAA,EAAU,UAAU,CAAA,EAAE;AAAA,MAC1E,IAAA,EAAM,UAAA;AAAA,MACN,KAAA,EAAO,SAAS,QAAA,CAAS,KAAA;AAAA,MACzB,IAAA,EAAM,QAAA,CAAS,QAAA,CAAS,IAAA,IAAQ,WAAA;AAAA,MAChC,IAAA,EAAM,QAAA,CAAS,QAAA,CAAS,IAAA,IAAQ,IAAA;AAAA,MAChC,IAAA,EAAM,SAAS,QAAA,CAAS,IAAA;AAAA,MACxB,IAAA,EAAM,SAAS,QAAA,CAAS,IAAA;AAAA,MACxB,QAAA,EAAU,SAAS,QAAA,CAAS;AAAA,KAC9B;AAAA,EACF;AAEA,EAAA,IAAI,SAAS,OAAA,EAAS;AACpB,IAAA,QAAA,CAAS,OAAA,GAAU;AAAA,MACjB,QAAA,EAAU,EAAE,IAAA,EAAM,UAAA,EAA2B;AAAA,MAC7C,IAAA,EAAO,QAAA,CAAS,OAAA,CAAQ,IAAA,IAAQ,QAAA;AAAA,MAChC,IAAA,EAAM,SAAS,OAAA,CAAQ,IAAA;AAAA,MACvB,IAAA,EAAM,QAAA,CAAS,OAAA,CAAQ,IAAA,IAAQ;AAAA,KACjC;AAAA,EACF;AAGA,EAAA,MAAM,eAAA,GAAkB,QAAA,CAAS,SAAA,IAAa,QAAA,CAAS,OAAA,EAAS,SAAA;AAChE,EAAA,IAAI,eAAA,EAAiB;AACnB,IAAA,QAAA,CAAS,SAAA,GAAY;AAAA,MACnB,QAAA,EAAU,EAAE,IAAA,EAAM,UAAA,EAA2B;AAAA,MAC7C,MAAM,eAAA,CAAgB,IAAA;AAAA,MACtB,OAAO,eAAA,CAAgB,KAAA;AAAA,MACvB,QAAQ,eAAA,CAAgB,MAAA;AAAA,MACxB,SAAS,eAAA,CAAgB,OAAA;AAAA,MACzB,UAAU,eAAA,CAAgB,QAAA;AAAA,MAC1B,UAAW,QAAA,CAAS,SAAA,EAAW,QAAA,IAAY,QAAA,CAAS,SAAS,QAAA,GAAY;AAAA,QACvE,YAAY,QAAA,CAAS,SAAA,EAAW,YAAY,QAAA,CAAS,OAAA,EAAS,WAAW,SAAA,IAAa,GAAA;AAAA,QACtF,UAAU,QAAA,CAAS,SAAA,EAAW,YAAY,QAAA,CAAS,OAAA,EAAS,WAAW,OAAA,IAAW;AAAA,OACpF,GAAI;AAAA,KACN;AAAA,EACF;AAEA,EAAA,MAAM,MAAA,GAA4B;AAAA,IAChC,QAAA;AAAA,IACA,GAAI,kBAAA,GAAqB,EAAE,SAAA,EAAW,kBAAA,KAAuB,EAAC;AAAA,IAC9D,GAAI,MAAA,CAAO,IAAA,CAAK,eAAe,CAAA,CAAE,MAAA,GAAS,CAAA,GAAI,EAAE,OAAA,EAAS,eAAA,EAAgB,GAAI,EAAC;AAAA,IAC9E,GAAI,MAAA,CAAO,IAAA,CAAK,cAAc,CAAA,CAAE,MAAA,GAAS,CAAA,GAAI,EAAE,MAAA,EAAQ,cAAA,EAAe,GAAI,EAAC;AAAA,IAC3E,MAAM,IAAA,GAAO;AAAA,MACX,MAAA,EAAQ,KAAK,MAAA,IAAU,WAAA;AAAA,MACvB,UAAU,IAAA,CAAK,QAAA;AAAA,MACf,YAAY,IAAA,CAAK,UAAA;AAAA,MACjB,qBAAqB,IAAA,CAAK;AAAA,KAC5B,GAAI,MAAA;AAAA,IACJ,UAAU,QAAA,CAAS,QAAA;AAAA,IACnB,SAAA,EAAW;AAAA,MACT,WAAA;AAAA,MACA,WAAA;AAAA,MACA,WAAA;AAAA,MACA,cAAA;AAAA,MACA,GAAI,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA,CAAE,SAAS,CAAA,GAAI,EAAE,MAAA,EAAO,GAAI,EAAC;AAAA,MACnD,GAAI,MAAA,CAAO,IAAA,CAAK,OAAO,CAAA,CAAE,SAAS,CAAA,GAAI,EAAE,OAAA,EAAQ,GAAI;AAAC;AACvD,GACF;AAEA,EAAA,OAAO,MAAA;AACT;AAOO,SAAS,sBAAA,CACd,MAAA,EACA,gBAAA,EACA,GAAA,EACA;AACA,EAAA,OAAO,CAAC,aAA4B,WAAA,KAA2C;AAC7E,IAAA,OAAO,cAAA,CAAe,WAAA,EAAa,WAAA,EAAa,gBAAA,EAAkB,QAAQ,GAAG,CAAA;AAAA,EAC/E,CAAA;AACF;ACzeO,IAAM,cAAA,GAAN,MAAM,eAAA,CAAe;AAAA,EACjB,IAAA;AAAA,EACA,IAAA;AAAA;AAAA;AAAA,EAIA,OAAA;AAAA;AAAA,EAGA,SAAA;AAAA,EACA,kBAAA;AAAA;AAAA,EAGA,SAAA;AAAA;AAAA,EAGA,QAAA;AAAA;AAAA,EAGA,QAAA;AAAA,EACA,cAAA;AAAA,EACA,OAAA;AAAA,EACA,cAAA;AAAA,EACA,iBAAA;AAAA,EACA,mBAAA;AAAA;AAAA,EAGA,UAAA;AAAA,EACA,cAAA;AAAA,EAET,WAAA,CAAY,aAAqB,IAAA,EAAe;AAC9C,IAAA,IAAA,CAAK,IAAA,GAAO,WAAA;AACZ,IAAA,IAAI,SAAS,MAAA,EAAW;AACtB,MAAA,MAAM,UAAA,GAAkB,IAAA,CAAA,IAAA,CAAK,WAAA,EAAa,UAAA,EAAY,QAAQ,CAAA;AAC9D,MAAA,IAAI,CAAI,EAAA,CAAA,UAAA,CAAW,UAAU,CAAA,EAAG;AAC9B,QAAG,EAAA,CAAA,SAAA,CAAe,UAAK,WAAA,EAAa,UAAU,GAAG,EAAE,SAAA,EAAW,MAAM,CAAA;AACpE,QAAG,iBAAc,UAAA,EAAY,CAAA;AAAA,QAAA,EAAsB,IAAI,CAAA;AAAA,CAAK,CAAA;AAAA,MAC9D;AAAA,IACF;AACA,IAAA,IAAA,CAAK,IAAA,GAAO,eAAA,CAAe,QAAA,CAAS,WAAW,CAAA;AAC/C,IAAA,IAAA,CAAK,OAAA,GAAU,eAAA,CAAe,WAAA,CAAY,WAAW,CAAA;AAErD,IAAA,IAAA,CAAK,SAAA,GAAiB,IAAA,CAAA,IAAA,CAAK,WAAA,EAAa,UAAA,EAAY,QAAQ,CAAA;AAC5D,IAAA,IAAA,CAAK,kBAAA,GAA0B,IAAA,CAAA,IAAA,CAAK,WAAA,EAAa,iBAAiB,CAAA;AAElE,IAAA,MAAM,YAAY,OAAA,CAAQ,GAAA,CAAI,mBAAwB,IAAA,CAAA,IAAA,CAAQ,EAAA,CAAA,OAAA,IAAW,SAAS,CAAA;AAClF,IAAA,IAAA,CAAK,SAAA,GAAiB,IAAA,CAAA,IAAA,CAAK,SAAA,EAAW,SAAA,EAAW,KAAK,IAAI,CAAA;AAE1D,IAAA,MAAM,OAAA,GAAU,QAAQ,GAAA,CAAI,aAAA,IAAsB,UAAQ,EAAA,CAAA,OAAA,EAAQ,EAAG,UAAU,OAAO,CAAA;AACtF,IAAA,IAAA,CAAK,QAAA,GAAgB,IAAA,CAAA,IAAA,CAAK,OAAA,EAAS,SAAA,EAAW,KAAK,IAAI,CAAA;AAEvD,IAAA,MAAM,QAAA,GAAW,QAAQ,GAAA,CAAI,cAAA,IAAuB,UAAQ,EAAA,CAAA,OAAA,EAAQ,EAAG,UAAU,OAAO,CAAA;AACxF,IAAA,IAAA,CAAK,QAAA,GAAgB,IAAA,CAAA,IAAA,CAAK,QAAA,EAAU,SAAA,EAAW,KAAK,IAAI,CAAA;AACxD,IAAA,IAAA,CAAK,cAAA,GAAsB,IAAA,CAAA,IAAA,CAAK,IAAA,CAAK,QAAA,EAAU,aAAa,CAAA;AAC5D,IAAA,IAAA,CAAK,OAAA,GAAe,IAAA,CAAA,IAAA,CAAK,IAAA,CAAK,QAAA,EAAU,MAAM,CAAA;AAC9C,IAAA,IAAA,CAAK,cAAA,GAAsB,IAAA,CAAA,IAAA,CAAK,IAAA,CAAK,QAAA,EAAU,SAAS,CAAA;AACxD,IAAA,IAAA,CAAK,iBAAA,GAAyB,IAAA,CAAA,IAAA,CAAK,IAAA,CAAK,cAAA,EAAgB,SAAS,CAAA;AACjE,IAAA,IAAA,CAAK,mBAAA,GAA2B,IAAA,CAAA,IAAA,CAAK,IAAA,CAAK,cAAA,EAAgB,WAAW,CAAA;AAErE,IAAA,MAAM,UAAA,GAAa,QAAQ,GAAA,CAAI,eAAA;AAC/B,IAAA,MAAM,WAAA,GAAc,UAAA,IAAc,OAAA,CAAQ,GAAA,CAAI,MAAA,IAAU,MAAA;AACxD,IAAA,IAAA,CAAK,UAAA,GAAkB,IAAA,CAAA,IAAA,CAAK,WAAA,EAAa,SAAA,EAAW,KAAK,IAAI,CAAA;AAC7D,IAAA,IAAA,CAAK,cAAA,GAAsB,IAAA,CAAA,IAAA,CAAK,IAAA,CAAK,UAAA,EAAY,aAAa,CAAA;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAA,GAA2B;AACzB,IAAA,IAAI;AACF,MAAA,OAAO,aAAa,KAAA,EAAO,CAAC,WAAA,EAAa,cAAA,EAAgB,MAAM,CAAA,EAAG;AAAA,QAChE,KAAK,IAAA,CAAK,IAAA;AAAA,QACV,QAAA,EAAU,OAAA;AAAA,QACV,KAAA,EAAO,CAAC,QAAA,EAAU,MAAA,EAAQ,QAAQ;AAAA,OACnC,CAAA,CAAE,IAAA,EAAK,IAAK,IAAA;AAAA,IACf,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,OAAA,GAAyB;AAC7B,IAAA,MAAM,QAAQ,GAAA,CAAI;AAAA,MACb,EAAA,CAAA,QAAA,CAAS,GAAG,IAAA,CAAK,SAAA,EAAW,EAAE,SAAA,EAAW,IAAA,EAAM,KAAA,EAAO,IAAA,EAAM,CAAA;AAAA,MAC5D,EAAA,CAAA,QAAA,CAAS,GAAG,IAAA,CAAK,QAAA,EAAU,EAAE,SAAA,EAAW,IAAA,EAAM,KAAA,EAAO,IAAA,EAAM,CAAA;AAAA,MAC3D,EAAA,CAAA,QAAA,CAAS,GAAG,IAAA,CAAK,UAAA,EAAY,EAAE,SAAA,EAAW,IAAA,EAAM,KAAA,EAAO,IAAA,EAAM;AAAA,KACjE,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAe,YAAY,WAAA,EAA8B;AACvD,IAAA,MAAM,UAAA,GAAkB,IAAA,CAAA,IAAA,CAAK,WAAA,EAAa,UAAA,EAAY,QAAQ,CAAA;AAC9D,IAAA,IAAI,CAAI,EAAA,CAAA,UAAA,CAAW,UAAU,CAAA,EAAG,OAAO,KAAA;AACvC,IAAA,MAAM,OAAA,GAAa,EAAA,CAAA,YAAA,CAAa,UAAA,EAAY,OAAO,CAAA;AACnD,IAAA,IAAI,YAAA,GAAe,KAAA;AACnB,IAAA,KAAA,MAAW,IAAA,IAAQ,OAAA,CAAQ,KAAA,CAAM,IAAI,CAAA,EAAG;AACtC,MAAA,MAAM,OAAA,GAAU,KAAK,IAAA,EAAK;AAC1B,MAAA,IAAI,YAAY,OAAA,EAAS;AAAE,QAAA,YAAA,GAAe,IAAA;AAAM,QAAA;AAAA,MAAU;AAC1D,MAAA,IAAI,OAAA,CAAQ,UAAA,CAAW,GAAG,CAAA,EAAG;AAAE,QAAA,YAAA,GAAe,KAAA;AAAO,QAAA;AAAA,MAAU;AAC/D,MAAA,IAAI,YAAA,IAAgB,QAAQ,UAAA,CAAW,MAAM,KAAK,OAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,EAAG;AACvE,QAAA,MAAM,QAAQ,OAAA,CAAQ,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,GAAG,IAAA,EAAK;AAC1C,QAAA,OAAO,KAAA,KAAU,MAAA;AAAA,MACnB;AAAA,IACF;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAe,SAAS,WAAA,EAA6B;AACnD,IAAA,MAAM,UAAA,GAAkB,IAAA,CAAA,IAAA,CAAK,WAAA,EAAa,UAAA,EAAY,QAAQ,CAAA;AAC9D,IAAA,IAAO,EAAA,CAAA,UAAA,CAAW,UAAU,CAAA,EAAG;AAC7B,MAAA,MAAM,OAAA,GAAa,EAAA,CAAA,YAAA,CAAa,UAAA,EAAY,OAAO,CAAA;AACnD,MAAA,KAAA,MAAW,IAAA,IAAQ,OAAA,CAAQ,KAAA,CAAM,IAAI,CAAA,EAAG;AACtC,QAAA,MAAM,OAAA,GAAU,KAAK,IAAA,EAAK;AAC1B,QAAA,IAAI,QAAQ,UAAA,CAAW,MAAM,KAAK,OAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,EAAG;AACvD,UAAA,MAAM,GAAG,GAAG,IAAI,CAAA,GAAI,OAAA,CAAQ,MAAM,GAAG,CAAA;AACrC,UAAA,OAAO,IAAA,CAAK,KAAK,GAAG,CAAA,CAAE,MAAK,CAAE,OAAA,CAAQ,YAAY,IAAI,CAAA;AAAA,QACvD;AAAA,MACF;AAAA,IACF;AACA,IAAA,OAAY,cAAS,WAAW,CAAA;AAAA,EAClC;AACF;;;AC3JA,IAAM,kBAAA,GAAqB;AAAA,EACzB,YAAA,EAAc,CAAC,QAAA,KACVC,EAAA,CAAA,UAAA,CAAW,QAAQ,CAAA,GAAOA,EAAA,CAAA,YAAA,CAAa,QAAA,EAAU,OAAO,CAAA,GAAI;AACnE,CAAA;AAWO,SAAS,qBAAA,CACd,aACA,WAAA,EACmB;AACnB,EAAA,MAAM,gBAAA,GAAwBC,IAAA,CAAA,IAAA,CAAQC,EAAA,CAAA,OAAA,EAAQ,EAAG,gBAAgB,CAAA;AACjE,EAAA,OAAO,sBAAA;AAAA,IACL,kBAAA;AAAA,IACA,gBAAA;AAAA,IACA,OAAA,CAAQ;AAAA,GACV,CAAE,aAAa,WAAW,CAAA;AAC5B","file":"node-config-loader.js","sourcesContent":["/**\n * TOML Config Loader\n *\n * Reads ~/.semiontconfig (TOML) and .semiont/config (TOML) and produces\n * an EnvironmentConfig for the requested environment.\n *\n * File format: see TOML-XDG-CONFIG.md\n *\n * Loading sequence:\n * 1. Read .semiont/config → projectName, site, environments.<env>.* (project base)\n * 2. Read ~/.semiontconfig → defaults, environments.<env>.* (user overrides)\n * 3. Deep-merge: project base ← user overrides (user wins on conflicts)\n * Any environment name is valid (local, staging, production, custom, ...)\n * 4. Resolve ${VAR} references from process.env\n * 5. Apply inheritance: workers.<name> → workers.default → error\n * 6. Map to EnvironmentConfig shape\n */\n\nimport { parse as parseToml } from 'smol-toml';\nimport type { EnvironmentConfig, OllamaProviderConfig, AnthropicProviderConfig } from './config.types';\nimport type { PlatformType } from './config.types';\n\n/**\n * Deep merge two plain objects. Arrays and primitives in `override` replace those in `base`.\n * Nested objects are merged recursively. `override` takes precedence on conflicts.\n */\nfunction deepMerge<T extends Record<string, unknown>>(base: T, override: Partial<T>): T {\n const result = { ...base } as Record<string, unknown>;\n for (const key of Object.keys(override)) {\n const b = base[key];\n const o = override[key];\n if (o !== undefined && o !== null && typeof o === 'object' && !Array.isArray(o) &&\n b !== undefined && b !== null && typeof b === 'object' && !Array.isArray(b)) {\n result[key] = deepMerge(b as Record<string, unknown>, o as Record<string, unknown>);\n } else if (o !== undefined) {\n result[key] = o;\n }\n }\n return result as T;\n}\n\nfunction resolveEnvVars(obj: unknown, env: Record<string, string | undefined>): unknown {\n if (typeof obj === 'string') {\n return obj.replace(/\\$\\{([^}]+)\\}/g, (match, varName) => {\n if (env[varName] === undefined) {\n throw new Error(`Environment variable ${varName} is not set (referenced in config as ${match})`);\n }\n return env[varName] as string;\n });\n }\n if (Array.isArray(obj)) {\n return obj.map(item => resolveEnvVars(item, env));\n }\n if (obj !== null && typeof obj === 'object') {\n const resolved: Record<string, unknown> = {};\n for (const key in obj as Record<string, unknown>) {\n resolved[key] = resolveEnvVars((obj as Record<string, unknown>)[key], env);\n }\n return resolved;\n }\n return obj;\n}\n\n// ── Inference config types (mirrored from packages/make-meaning/src/config.ts) ─\n// Kept here to avoid a circular dependency: core cannot import make-meaning.\n\nexport interface InferenceConfig {\n type: 'anthropic' | 'ollama';\n model: string;\n maxTokens?: number;\n apiKey?: string;\n endpoint?: string;\n baseURL?: string;\n}\n\nexport interface ActorInferenceConfig {\n gatherer?: InferenceConfig;\n matcher?: InferenceConfig;\n}\n\nexport interface WorkerInferenceConfig {\n default?: InferenceConfig;\n 'reference-annotation'?: InferenceConfig;\n 'highlight-annotation'?: InferenceConfig;\n 'assessment-annotation'?: InferenceConfig;\n 'comment-annotation'?: InferenceConfig;\n 'tag-annotation'?: InferenceConfig;\n 'generation'?: InferenceConfig;\n}\n\n// ── Types for ~/.semiontconfig ────────────────────────────────────────────────\n\ninterface SemiontConfigFile {\n user?: {\n name?: string;\n email?: string;\n };\n defaults?: {\n environment?: string;\n platform?: string;\n };\n environments?: Record<string, EnvironmentSection>;\n}\n\ninterface GraphSection {\n platform?: string;\n type?: string;\n name?: string;\n uri?: string;\n username?: string;\n password?: string;\n database?: string;\n [key: string]: unknown;\n}\n\ninterface InferenceFlatSection {\n // Flat (single-provider) format: type = \"anthropic\"|\"ollama\" at this level\n type?: 'anthropic' | 'ollama';\n platform?: string;\n model?: string;\n maxTokens?: number;\n apiKey?: string;\n endpoint?: string;\n baseURL?: string;\n // Keyed (multi-provider) format: [inference.anthropic] / [inference.ollama]\n anthropic?: { platform?: string; apiKey?: string; endpoint?: string };\n ollama?: { platform?: string; baseURL?: string; port?: number };\n}\n\ninterface EnvironmentSection {\n backend?: {\n platform?: string;\n port?: number;\n publicURL?: string;\n frontendURL?: string;\n corsOrigin?: string;\n };\n frontend?: {\n platform?: string;\n port?: number;\n publicURL?: string;\n };\n site?: {\n domain?: string;\n siteName?: string;\n adminEmail?: string;\n oauthAllowedDomains?: string[];\n enableLocalAuth?: boolean;\n };\n database?: {\n platform?: string;\n image?: string;\n host?: string;\n port?: number;\n name?: string;\n user?: string;\n password?: string;\n };\n graph?: GraphSection;\n vectors?: {\n type?: 'qdrant' | 'memory';\n host?: string;\n port?: number;\n // Legacy: embedding nested under vectors (migrated to top-level)\n embedding?: {\n type?: 'voyage' | 'ollama';\n model?: string;\n apiKey?: string;\n baseURL?: string;\n endpoint?: string;\n };\n chunking?: {\n chunkSize?: number;\n overlap?: number;\n };\n };\n embedding?: {\n type?: 'voyage' | 'ollama';\n model?: string;\n apiKey?: string;\n baseURL?: string;\n endpoint?: string;\n chunking?: {\n chunkSize?: number;\n overlap?: number;\n };\n };\n inference?: InferenceFlatSection;\n 'make-meaning'?: {\n graph?: Record<string, unknown>;\n actors?: {\n gatherer?: { inference?: InferenceConfig };\n matcher?: { inference?: InferenceConfig };\n };\n default?: { inference?: InferenceConfig };\n };\n workers?: Record<string, { inference?: InferenceConfig }>;\n actors?: Record<string, { inference?: InferenceConfig }>;\n logLevel?: 'error' | 'warn' | 'info' | 'http' | 'debug';\n}\n\n// ── File reader abstraction (same pattern as createConfigLoader) ──────────────\n\nexport type TomlFileReader = {\n readIfExists: (path: string) => string | null;\n};\n\nfunction requirePlatform(value: string | undefined, serviceName: string): PlatformType {\n if (!value) {\n throw new Error(`platform is required for service '${serviceName}' — add 'platform = \"posix\"|\"container\"|\"external\"' to its config section`);\n }\n return value as PlatformType;\n}\n\n// ── Main loader function ──────────────────────────────────────────────────────\n\n/**\n * Parse ~/.semiontconfig and .semiont/config and return EnvironmentConfig.\n *\n * @param projectRoot - Path to the project root (contains .semiont/config)\n * @param environment - Environment name (e.g. 'local', 'production')\n * @param globalConfigPath - Path to ~/.semiontconfig (caller resolves ~ expansion)\n * @param reader - File reader abstraction\n * @param env - Environment variables for ${VAR} resolution\n */\nexport function loadTomlConfig(\n projectRoot: string | null,\n environment: string,\n globalConfigPath: string,\n reader: TomlFileReader,\n env: Record<string, string | undefined>\n): EnvironmentConfig {\n // 1. Read project config from .semiont/config (skipped when no project root)\n const projectConfigContent = projectRoot ? reader.readIfExists(`${projectRoot}/.semiont/config`) : null;\n let projectName = 'semiont-project';\n let projectVersion: string | undefined;\n let projectSite: EnvironmentSection['site'] | undefined;\n let projectEnvSection: EnvironmentSection = {};\n if (projectConfigContent) {\n const projectConfig = parseToml(projectConfigContent) as {\n project?: { name?: string; version?: string };\n site?: EnvironmentSection['site'];\n environments?: Record<string, EnvironmentSection>;\n };\n projectName = projectConfig.project?.name ?? projectName;\n projectVersion = projectConfig.project?.version;\n projectSite = projectConfig.site;\n projectEnvSection = projectConfig.environments?.[environment] ?? {};\n }\n\n // 2. Read global config (optional — missing config yields empty environments)\n const globalContent = reader.readIfExists(globalConfigPath);\n const raw = globalContent ? (parseToml(globalContent) as SemiontConfigFile) : ({} as SemiontConfigFile);\n\n // 3. Deep-merge: project base + user overrides (user wins on conflicts)\n const userEnvSection: EnvironmentSection = raw.environments?.[environment] ?? {};\n const envSection: EnvironmentSection = deepMerge(\n projectEnvSection as Record<string, unknown>,\n userEnvSection as Record<string, unknown>\n ) as EnvironmentSection;\n\n // 4. Resolve ${VAR} references\n const resolved = resolveEnvVars(envSection, env) as EnvironmentSection;\n\n // 5. Build make-meaning actor/worker inference config with inheritance\n // The flat [inference] section provides defaults (apiKey, maxTokens, endpoint/baseURL).\n // Actor/worker sections only need to specify type and model; missing fields fall back\n // to the flat inference section.\n const flatInference = resolved.inference;\n const makeMeaningSection = resolved['make-meaning'];\n const workersSection = resolved.workers ?? {};\n const actorsSection = resolved.actors ?? {};\n const defaultWorkerInference = workersSection['default']?.inference;\n const defaultMakeMeaningInference = makeMeaningSection?.default?.inference;\n\n function mergeWithFlatInference(specific: InferenceConfig): InferenceConfig {\n if (!flatInference) return specific;\n // For keyed sub-sections, inherit credentials from the matching provider sub-section.\n // For flat (legacy) format, flatInference.type is required to know which fields apply.\n const providerDefaults: Partial<InferenceConfig> = {};\n if (specific.type === 'anthropic') {\n const a = flatInference.anthropic;\n if (a) {\n providerDefaults.apiKey = a.apiKey;\n providerDefaults.endpoint = a.endpoint;\n } else {\n if (!flatInference.type) {\n throw new Error(\n `[environments.${environment}.inference] is missing 'type'. ` +\n `Add type = \"anthropic\" or use [inference.anthropic] sub-section.`\n );\n }\n providerDefaults.apiKey = flatInference.apiKey;\n providerDefaults.endpoint = flatInference.endpoint;\n }\n } else if (specific.type === 'ollama') {\n const o = flatInference.ollama;\n if (o) {\n providerDefaults.baseURL = o.baseURL;\n } else {\n if (!flatInference.type) {\n throw new Error(\n `[environments.${environment}.inference] is missing 'type'. ` +\n `Add type = \"ollama\" or use [inference.ollama] sub-section.`\n );\n }\n providerDefaults.baseURL = flatInference.baseURL;\n }\n }\n return {\n maxTokens: flatInference.maxTokens,\n ...providerDefaults,\n ...specific,\n };\n }\n\n function resolveActorInference(fromMakeMeaning?: InferenceConfig, fromActors?: InferenceConfig): InferenceConfig | undefined {\n const base = fromMakeMeaning ?? fromActors ?? defaultMakeMeaningInference;\n if (!base) return undefined;\n return mergeWithFlatInference(base);\n }\n\n const actors: ActorInferenceConfig = {};\n const gathererInference = resolveActorInference(\n makeMeaningSection?.actors?.gatherer?.inference,\n actorsSection['gatherer']?.inference\n );\n if (gathererInference) actors.gatherer = gathererInference;\n\n const matcherInference = resolveActorInference(\n makeMeaningSection?.actors?.matcher?.inference,\n actorsSection['matcher']?.inference\n );\n if (matcherInference) actors.matcher = matcherInference;\n\n const workers: WorkerInferenceConfig = {};\n const workerTypes = ['reference-annotation', 'highlight-annotation', 'assessment-annotation', 'comment-annotation', 'tag-annotation', 'generation'] as const;\n if (defaultWorkerInference) {\n workers.default = mergeWithFlatInference(defaultWorkerInference);\n }\n for (const wt of workerTypes) {\n const specific = workersSection[wt]?.inference;\n if (specific) {\n (workers as Record<string, InferenceConfig>)[wt] = mergeWithFlatInference(specific);\n }\n }\n\n // 6. Map to EnvironmentConfig\n const backend = resolved.backend;\n const site = resolved.site ?? projectSite;\n const inferenceSection = resolved.inference;\n\n // Build inference providers config.\n // Supports two formats:\n // Flat: [environments.local.inference] type = \"anthropic\"|\"ollama\" (single provider)\n // Keyed: [environments.local.inference.anthropic] / [environments.local.inference.ollama] (multi-provider)\n let inferenceProviders: EnvironmentConfig['inference'] | undefined;\n if (inferenceSection) {\n inferenceProviders = {};\n // Keyed sub-sections take priority\n if (inferenceSection.anthropic) {\n const a = inferenceSection.anthropic;\n inferenceProviders.anthropic = {\n platform: requirePlatform(a.platform, 'inference.anthropic'),\n endpoint: a.endpoint ?? 'https://api.anthropic.com',\n apiKey: a.apiKey ?? '',\n } as AnthropicProviderConfig;\n } else if (inferenceSection.type === 'anthropic') {\n inferenceProviders.anthropic = {\n platform: requirePlatform(inferenceSection.platform, 'inference'),\n endpoint: inferenceSection.endpoint ?? 'https://api.anthropic.com',\n apiKey: inferenceSection.apiKey ?? '',\n } as AnthropicProviderConfig;\n }\n if (inferenceSection.ollama) {\n const o = inferenceSection.ollama;\n inferenceProviders.ollama = {\n platform: { type: requirePlatform(o.platform, 'inference.ollama') },\n baseURL: o.baseURL,\n port: o.baseURL ? undefined : (o.port ?? 11434),\n } as OllamaProviderConfig;\n } else if (inferenceSection.type === 'ollama') {\n inferenceProviders.ollama = {\n platform: { type: requirePlatform(inferenceSection.platform, 'inference') },\n baseURL: inferenceSection.baseURL,\n port: inferenceSection.baseURL ? undefined : 11434,\n } as OllamaProviderConfig;\n }\n }\n\n // Build top-level workers/actors maps for EnvironmentConfig\n const topLevelWorkers: EnvironmentConfig['workers'] = {};\n for (const [name, w] of Object.entries(workersSection)) {\n if (w.inference) {\n topLevelWorkers[name] = { inference: { type: w.inference.type, model: w.inference.model } };\n }\n }\n const topLevelActors: EnvironmentConfig['actors'] = {};\n for (const [name, a] of Object.entries(actorsSection)) {\n if (a.inference) {\n topLevelActors[name] = { inference: { type: a.inference.type, model: a.inference.model } };\n }\n }\n // Also include make-meaning actors\n if (makeMeaningSection?.actors?.gatherer?.inference) {\n topLevelActors['gatherer'] = { inference: { type: makeMeaningSection.actors.gatherer.inference.type, model: makeMeaningSection.actors.gatherer.inference.model } };\n }\n if (makeMeaningSection?.actors?.matcher?.inference) {\n topLevelActors['matcher'] = { inference: { type: makeMeaningSection.actors.matcher.inference.type, model: makeMeaningSection.actors.matcher.inference.model } };\n }\n\n const frontend = resolved.frontend;\n\n const services: EnvironmentConfig['services'] = {};\n\n if (backend) {\n services.backend = {\n platform: { type: requirePlatform(backend.platform, 'backend') },\n port: backend.port ?? 4000,\n publicURL: backend.publicURL ?? `http://localhost:${backend.port ?? 4000}`,\n corsOrigin: backend.corsOrigin ?? backend.frontendURL ?? 'http://localhost:3000',\n };\n }\n\n if (frontend) {\n services.frontend = {\n platform: { type: requirePlatform(frontend.platform, 'frontend') },\n port: frontend.port ?? 3000,\n siteName: site?.siteName ?? 'Semiont',\n publicURL: frontend.publicURL,\n };\n }\n\n if (resolved.graph) {\n services.graph = {\n ...resolved.graph,\n platform: { type: requirePlatform(resolved.graph.platform as string | undefined, 'graph') },\n type: (resolved.graph.type ?? 'neo4j') as import('./config.types').GraphDatabaseType,\n } as EnvironmentConfig['services']['graph'];\n } else if (makeMeaningSection?.graph) {\n services.graph = makeMeaningSection.graph as EnvironmentConfig['services']['graph'];\n }\n\n if (resolved.database) {\n services.database = {\n platform: { type: requirePlatform(resolved.database.platform, 'database') },\n type: 'postgres',\n image: resolved.database.image,\n host: resolved.database.host ?? 'localhost',\n port: resolved.database.port ?? 5432,\n name: resolved.database.name,\n user: resolved.database.user,\n password: resolved.database.password,\n } as EnvironmentConfig['services']['database'];\n }\n\n if (resolved.vectors) {\n services.vectors = {\n platform: { type: 'external' as PlatformType },\n type: (resolved.vectors.type ?? 'qdrant') as 'qdrant' | 'memory',\n host: resolved.vectors.host,\n port: resolved.vectors.port ?? 6333,\n } as EnvironmentConfig['services']['vectors'];\n }\n\n // Embedding: top-level takes precedence, fall back to legacy vectors.embedding\n const embeddingSource = resolved.embedding ?? resolved.vectors?.embedding;\n if (embeddingSource) {\n services.embedding = {\n platform: { type: 'external' as PlatformType },\n type: embeddingSource.type!,\n model: embeddingSource.model!,\n apiKey: embeddingSource.apiKey,\n baseURL: embeddingSource.baseURL,\n endpoint: embeddingSource.endpoint,\n chunking: (resolved.embedding?.chunking ?? resolved.vectors?.chunking) ? {\n chunkSize: (resolved.embedding?.chunking ?? resolved.vectors?.chunking)?.chunkSize ?? 512,\n overlap: (resolved.embedding?.chunking ?? resolved.vectors?.chunking)?.overlap ?? 64,\n } : undefined,\n } as EnvironmentConfig['services']['embedding'];\n }\n\n const config: EnvironmentConfig = {\n services,\n ...(inferenceProviders ? { inference: inferenceProviders } : {}),\n ...(Object.keys(topLevelWorkers).length > 0 ? { workers: topLevelWorkers } : {}),\n ...(Object.keys(topLevelActors).length > 0 ? { actors: topLevelActors } : {}),\n site: site ? {\n domain: site.domain ?? 'localhost',\n siteName: site.siteName,\n adminEmail: site.adminEmail,\n oauthAllowedDomains: site.oauthAllowedDomains as [string, ...string[]] | undefined,\n } : undefined,\n logLevel: resolved.logLevel,\n _metadata: {\n environment,\n projectRoot,\n projectName,\n projectVersion,\n ...(Object.keys(actors).length > 0 ? { actors } : {}),\n ...(Object.keys(workers).length > 0 ? { workers } : {}),\n },\n };\n\n return config;\n}\n\n/**\n * Create a TOML config loader backed by a file reader.\n * Drop-in replacement for createConfigLoader that reads TOML instead of JSON.\n * The caller must resolve globalConfigPath (e.g. expand '~' using process.env.HOME).\n */\nexport function createTomlConfigLoader(\n reader: TomlFileReader,\n globalConfigPath: string,\n env: Record<string, string | undefined>\n) {\n return (projectRoot: string | null, environment: string): EnvironmentConfig => {\n return loadTomlConfig(projectRoot, environment, globalConfigPath, reader, env);\n };\n}\n","import * as fs from 'fs';\nimport * as os from 'os';\nimport * as path from 'path';\nimport { execFileSync } from 'child_process';\n\n/**\n * Represents a Semiont project rooted at a given directory.\n *\n * Computes all paths — durable and ephemeral — once at construction time.\n * XDG environment variables are read here and nowhere else.\n *\n * Durable paths (inside the project root, committed or repo-local):\n * eventsDir — .semiont/events/ (system of record, committed)\n * representationsDir — representations/ (content store, committed)\n *\n * Ephemeral paths (outside the project root, never committed):\n * configDir — $XDG_CONFIG_HOME/semiont/{name}/ (generated config for managed processes)\n * dataHome — $XDG_DATA_HOME/semiont/{name}/ (persistent user data, e.g. database files)\n * stateDir — $XDG_STATE_HOME/semiont/{name}/\n * projectionsDir — stateDir/projections/\n * jobsDir — stateDir/jobs/\n * backendLogsDir — stateDir/backend/\n * backendAppLogFile — backendLogsDir/app.log\n * backendErrorLogFile — backendLogsDir/error.log\n * runtimeDir — $XDG_RUNTIME_DIR/semiont/{name}/ (or $TMPDIR fallback)\n * backendPidFile — runtimeDir/backend.pid\n *\n * Note: frontend paths are NOT project-scoped. The frontend service is bundled\n * with the CLI and uses fixed XDG paths keyed by \"frontend\", not project name.\n * See apps/cli/src/platforms/posix/handlers/frontend-paths.ts.\n */\nexport class SemiontProject {\n readonly root: string;\n readonly name: string;\n\n /** True if [git] sync = true in .semiont/config. When true, semiont stages\n * working-tree and event-log changes in the git index automatically. */\n readonly gitSync: boolean;\n\n // Durable\n readonly eventsDir: string;\n readonly representationsDir: string;\n\n // Ephemeral — config (generated config files for managed processes)\n readonly configDir: string;\n\n // Ephemeral — data (persistent user data managed by semiont)\n readonly dataHome: string;\n\n // Ephemeral — state\n readonly stateDir: string;\n readonly projectionsDir: string;\n readonly jobsDir: string;\n readonly backendLogsDir: string;\n readonly backendAppLogFile: string;\n readonly backendErrorLogFile: string;\n\n // Ephemeral — runtime\n readonly runtimeDir: string;\n readonly backendPidFile: string;\n\n constructor(projectRoot: string, name?: string) {\n this.root = projectRoot;\n if (name !== undefined) {\n const configPath = path.join(projectRoot, '.semiont', 'config');\n if (!fs.existsSync(configPath)) {\n fs.mkdirSync(path.join(projectRoot, '.semiont'), { recursive: true });\n fs.writeFileSync(configPath, `[project]\\nname = \"${name}\"\\n`);\n }\n }\n this.name = SemiontProject.readName(projectRoot);\n this.gitSync = SemiontProject.readGitSync(projectRoot);\n\n this.eventsDir = path.join(projectRoot, '.semiont', 'events');\n this.representationsDir = path.join(projectRoot, 'representations');\n\n const xdgConfig = process.env.XDG_CONFIG_HOME || path.join(os.homedir(), '.config');\n this.configDir = path.join(xdgConfig, 'semiont', this.name);\n\n const xdgData = process.env.XDG_DATA_HOME || path.join(os.homedir(), '.local', 'share');\n this.dataHome = path.join(xdgData, 'semiont', this.name);\n\n const xdgState = process.env.XDG_STATE_HOME || path.join(os.homedir(), '.local', 'state');\n this.stateDir = path.join(xdgState, 'semiont', this.name);\n this.projectionsDir = path.join(this.stateDir, 'projections');\n this.jobsDir = path.join(this.stateDir, 'jobs');\n this.backendLogsDir = path.join(this.stateDir, 'backend');\n this.backendAppLogFile = path.join(this.backendLogsDir, 'app.log');\n this.backendErrorLogFile = path.join(this.backendLogsDir, 'error.log');\n\n const xdgRuntime = process.env.XDG_RUNTIME_DIR;\n const runtimeBase = xdgRuntime ?? process.env.TMPDIR ?? '/tmp';\n this.runtimeDir = path.join(runtimeBase, 'semiont', this.name);\n this.backendPidFile = path.join(this.runtimeDir, 'backend.pid');\n }\n\n /**\n * Read the current git branch for the project root.\n * Returns null if the project is not a git repo or git is not available.\n */\n gitBranch(): string | null {\n try {\n return execFileSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {\n cwd: this.root,\n encoding: 'utf-8',\n stdio: ['ignore', 'pipe', 'ignore'],\n }).trim() || null;\n } catch {\n return null;\n }\n }\n\n /**\n * Delete all ephemeral state for this project (stateDir + runtimeDir).\n * Does not touch eventsDir or dataDir.\n */\n async destroy(): Promise<void> {\n await Promise.all([\n fs.promises.rm(this.configDir, { recursive: true, force: true }),\n fs.promises.rm(this.stateDir, { recursive: true, force: true }),\n fs.promises.rm(this.runtimeDir, { recursive: true, force: true }),\n ]);\n }\n\n /**\n * Read [git] sync from .semiont/config.\n * Defaults to false if the section or key is absent.\n */\n private static readGitSync(projectRoot: string): boolean {\n const configPath = path.join(projectRoot, '.semiont', 'config');\n if (!fs.existsSync(configPath)) return false;\n const content = fs.readFileSync(configPath, 'utf-8');\n let inGitSection = false;\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (trimmed === '[git]') { inGitSection = true; continue; }\n if (trimmed.startsWith('[')) { inGitSection = false; continue; }\n if (inGitSection && trimmed.startsWith('sync') && trimmed.includes('=')) {\n const value = trimmed.split('=')[1]?.trim();\n return value === 'true';\n }\n }\n return false;\n }\n\n /**\n * Read the project name from .semiont/config [project] name = \"...\"\n * Falls back to the directory basename if the config is absent or has no name.\n */\n private static readName(projectRoot: string): string {\n const configPath = path.join(projectRoot, '.semiont', 'config');\n if (fs.existsSync(configPath)) {\n const content = fs.readFileSync(configPath, 'utf-8');\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (trimmed.startsWith('name') && trimmed.includes('=')) {\n const [, ...rest] = trimmed.split('=');\n return rest.join('=').trim().replace(/^\"(.*)\"$/, '$1');\n }\n }\n }\n return path.basename(projectRoot);\n }\n}\n","import * as fs from 'fs';\nimport * as os from 'os';\nimport * as path from 'path';\nimport { createTomlConfigLoader } from './toml-loader.js';\nimport type { EnvironmentConfig } from './config.types.js';\n\nexport { SemiontProject } from '../project.js';\n\nconst nodeTomlFileReader = {\n readIfExists: (filePath: string): string | null =>\n fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf-8') : null,\n};\n\n/**\n * Load semiont environment config for a Node.js process.\n *\n * Reads ~/.semiontconfig (global) merged with .semiont/config (project-local),\n * then selects the given environment overlay.\n *\n * This is the canonical config loader for any Node.js process. SEMIONT_ENV\n * should be read once at the process entry point and passed as `environment`.\n */\nexport function loadEnvironmentConfig(\n projectRoot: string,\n environment: string\n): EnvironmentConfig {\n const globalConfigPath = path.join(os.homedir(), '.semiontconfig');\n return createTomlConfigLoader(\n nodeTomlFileReader,\n globalConfigPath,\n process.env\n )(projectRoot, environment);\n}\n"]}
1
+ {"version":3,"sources":["../../src/config/toml-loader.ts","../../src/project.ts","../../src/config/node-config-loader.ts"],"names":["parseToml","fs2","path2","os2"],"mappings":"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","file":"node-config-loader.js","sourcesContent":["/**\n * TOML Config Loader\n *\n * Reads ~/.semiontconfig (TOML) and .semiont/config (TOML) and produces\n * an EnvironmentConfig for the requested environment.\n *\n * File format: see TOML-XDG-CONFIG.md\n *\n * Loading sequence:\n * 1. Read .semiont/config → projectName, site, environments.<env>.* (project base)\n * 2. Read ~/.semiontconfig → defaults, environments.<env>.* (user overrides)\n * 3. Deep-merge: project base ← user overrides (user wins on conflicts)\n * Any environment name is valid (local, staging, production, custom, ...)\n * 4. Resolve ${VAR} references from process.env\n * 5. Apply inheritance: workers.<name> → workers.default → error\n * 6. Map to EnvironmentConfig shape\n */\n\nimport { parse as parseToml } from 'smol-toml';\nimport type { EnvironmentConfig, OllamaProviderConfig, AnthropicProviderConfig } from './config.types';\nimport type { PlatformType } from './config.types';\n\n/**\n * Deep merge two plain objects. Arrays and primitives in `override` replace those in `base`.\n * Nested objects are merged recursively. `override` takes precedence on conflicts.\n */\nfunction deepMerge<T extends Record<string, unknown>>(base: T, override: Partial<T>): T {\n const result = { ...base } as Record<string, unknown>;\n for (const key of Object.keys(override)) {\n const b = base[key];\n const o = override[key];\n if (o !== undefined && o !== null && typeof o === 'object' && !Array.isArray(o) &&\n b !== undefined && b !== null && typeof b === 'object' && !Array.isArray(b)) {\n result[key] = deepMerge(b as Record<string, unknown>, o as Record<string, unknown>);\n } else if (o !== undefined) {\n result[key] = o;\n }\n }\n return result as T;\n}\n\nfunction resolveEnvVars(obj: unknown, env: Record<string, string | undefined>): unknown {\n if (typeof obj === 'string') {\n return obj.replace(/\\$\\{([^}]+)\\}/g, (match, varName) => {\n if (env[varName] === undefined) {\n throw new Error(`Environment variable ${varName} is not set (referenced in config as ${match})`);\n }\n return env[varName] as string;\n });\n }\n if (Array.isArray(obj)) {\n return obj.map(item => resolveEnvVars(item, env));\n }\n if (obj !== null && typeof obj === 'object') {\n const resolved: Record<string, unknown> = {};\n for (const key in obj as Record<string, unknown>) {\n resolved[key] = resolveEnvVars((obj as Record<string, unknown>)[key], env);\n }\n return resolved;\n }\n return obj;\n}\n\n// ── Inference config types (mirrored from packages/make-meaning/src/config.ts) ─\n// Kept here to avoid a circular dependency: core cannot import make-meaning.\n\nexport interface InferenceConfig {\n type: 'anthropic' | 'ollama';\n model: string;\n maxTokens?: number;\n apiKey?: string;\n endpoint?: string;\n baseURL?: string;\n}\n\nexport interface ActorInferenceConfig {\n gatherer?: InferenceConfig;\n matcher?: InferenceConfig;\n}\n\nexport interface WorkerInferenceConfig {\n default?: InferenceConfig;\n 'reference-annotation'?: InferenceConfig;\n 'highlight-annotation'?: InferenceConfig;\n 'assessment-annotation'?: InferenceConfig;\n 'comment-annotation'?: InferenceConfig;\n 'tag-annotation'?: InferenceConfig;\n 'generation'?: InferenceConfig;\n}\n\n// ── Types for ~/.semiontconfig ────────────────────────────────────────────────\n\ninterface SemiontConfigFile {\n user?: {\n name?: string;\n email?: string;\n };\n defaults?: {\n environment?: string;\n platform?: string;\n };\n environments?: Record<string, EnvironmentSection>;\n}\n\ninterface GraphSection {\n platform?: string;\n type?: string;\n name?: string;\n uri?: string;\n username?: string;\n password?: string;\n database?: string;\n [key: string]: unknown;\n}\n\ninterface InferenceFlatSection {\n // Flat (single-provider) format: type = \"anthropic\"|\"ollama\" at this level\n type?: 'anthropic' | 'ollama';\n platform?: string;\n model?: string;\n maxTokens?: number;\n apiKey?: string;\n endpoint?: string;\n baseURL?: string;\n // Keyed (multi-provider) format: [inference.anthropic] / [inference.ollama]\n anthropic?: { platform?: string; apiKey?: string; endpoint?: string };\n ollama?: { platform?: string; baseURL?: string; port?: number };\n}\n\ninterface EnvironmentSection {\n backend?: {\n platform?: string;\n port?: number;\n publicURL?: string;\n frontendURL?: string;\n corsOrigin?: string;\n };\n frontend?: {\n platform?: string;\n port?: number;\n publicURL?: string;\n };\n site?: {\n domain?: string;\n siteName?: string;\n adminEmail?: string;\n oauthAllowedDomains?: string[];\n enableLocalAuth?: boolean;\n };\n database?: {\n platform?: string;\n image?: string;\n host?: string;\n port?: number;\n name?: string;\n user?: string;\n password?: string;\n };\n graph?: GraphSection;\n vectors?: {\n type?: 'qdrant' | 'memory';\n host?: string;\n port?: number;\n // Legacy: embedding nested under vectors (migrated to top-level)\n embedding?: {\n type?: 'voyage' | 'ollama';\n model?: string;\n apiKey?: string;\n baseURL?: string;\n endpoint?: string;\n };\n chunking?: {\n chunkSize?: number;\n overlap?: number;\n };\n };\n embedding?: {\n type?: 'voyage' | 'ollama';\n model?: string;\n apiKey?: string;\n baseURL?: string;\n endpoint?: string;\n chunking?: {\n chunkSize?: number;\n overlap?: number;\n };\n };\n inference?: InferenceFlatSection;\n 'make-meaning'?: {\n graph?: Record<string, unknown>;\n actors?: {\n gatherer?: { inference?: InferenceConfig };\n matcher?: { inference?: InferenceConfig };\n };\n default?: { inference?: InferenceConfig };\n };\n workers?: Record<string, { inference?: InferenceConfig }>;\n actors?: Record<string, { inference?: InferenceConfig }>;\n logLevel?: 'error' | 'warn' | 'info' | 'http' | 'debug';\n}\n\n// ── File reader abstraction (same pattern as createConfigLoader) ──────────────\n\nexport type TomlFileReader = {\n readIfExists: (path: string) => string | null;\n};\n\nfunction requirePlatform(value: string | undefined, serviceName: string): PlatformType {\n if (!value) {\n throw new Error(`platform is required for service '${serviceName}' — add 'platform = \"posix\"|\"container\"|\"external\"' to its config section`);\n }\n return value as PlatformType;\n}\n\n// ── Main loader function ──────────────────────────────────────────────────────\n\n/**\n * Parse ~/.semiontconfig and .semiont/config and return EnvironmentConfig.\n *\n * @param projectRoot - Path to the project root (contains .semiont/config)\n * @param environment - Environment name (e.g. 'local', 'production')\n * @param globalConfigPath - Path to ~/.semiontconfig (caller resolves ~ expansion)\n * @param reader - File reader abstraction\n * @param env - Environment variables for ${VAR} resolution\n */\nexport function loadTomlConfig(\n projectRoot: string | null,\n environment: string,\n globalConfigPath: string,\n reader: TomlFileReader,\n env: Record<string, string | undefined>\n): EnvironmentConfig {\n // 1. Read project config from .semiont/config (skipped when no project root)\n const projectConfigContent = projectRoot ? reader.readIfExists(`${projectRoot}/.semiont/config`) : null;\n let projectName = 'semiont-project';\n let projectVersion: string | undefined;\n let projectSite: EnvironmentSection['site'] | undefined;\n let projectEnvSection: EnvironmentSection = {};\n if (projectConfigContent) {\n const projectConfig = parseToml(projectConfigContent) as {\n project?: { name?: string; version?: string };\n site?: EnvironmentSection['site'];\n environments?: Record<string, EnvironmentSection>;\n };\n projectName = projectConfig.project?.name ?? projectName;\n projectVersion = projectConfig.project?.version;\n projectSite = projectConfig.site;\n projectEnvSection = projectConfig.environments?.[environment] ?? {};\n }\n\n // 2. Read global config (optional — missing config yields empty environments)\n const globalContent = reader.readIfExists(globalConfigPath);\n const raw = globalContent ? (parseToml(globalContent) as SemiontConfigFile) : ({} as SemiontConfigFile);\n\n // 3. Deep-merge: project base + user overrides (user wins on conflicts)\n const userEnvSection: EnvironmentSection = raw.environments?.[environment] ?? {};\n const envSection: EnvironmentSection = deepMerge(\n projectEnvSection as Record<string, unknown>,\n userEnvSection as Record<string, unknown>\n ) as EnvironmentSection;\n\n // 4. Resolve ${VAR} references\n const resolved = resolveEnvVars(envSection, env) as EnvironmentSection;\n\n // 5. Build make-meaning actor/worker inference config with inheritance\n // The flat [inference] section provides defaults (apiKey, maxTokens, endpoint/baseURL).\n // Actor/worker sections only need to specify type and model; missing fields fall back\n // to the flat inference section.\n const flatInference = resolved.inference;\n const makeMeaningSection = resolved['make-meaning'];\n const workersSection = resolved.workers ?? {};\n const actorsSection = resolved.actors ?? {};\n const defaultWorkerInference = workersSection['default']?.inference;\n const defaultMakeMeaningInference = makeMeaningSection?.default?.inference;\n\n function mergeWithFlatInference(specific: InferenceConfig): InferenceConfig {\n if (!flatInference) return specific;\n // For keyed sub-sections, inherit credentials from the matching provider sub-section.\n // For flat (legacy) format, flatInference.type is required to know which fields apply.\n const providerDefaults: Partial<InferenceConfig> = {};\n if (specific.type === 'anthropic') {\n const a = flatInference.anthropic;\n if (a) {\n providerDefaults.apiKey = a.apiKey;\n providerDefaults.endpoint = a.endpoint;\n } else {\n if (!flatInference.type) {\n throw new Error(\n `[environments.${environment}.inference] is missing 'type'. ` +\n `Add type = \"anthropic\" or use [inference.anthropic] sub-section.`\n );\n }\n providerDefaults.apiKey = flatInference.apiKey;\n providerDefaults.endpoint = flatInference.endpoint;\n }\n } else if (specific.type === 'ollama') {\n const o = flatInference.ollama;\n if (o) {\n providerDefaults.baseURL = o.baseURL;\n } else {\n if (!flatInference.type) {\n throw new Error(\n `[environments.${environment}.inference] is missing 'type'. ` +\n `Add type = \"ollama\" or use [inference.ollama] sub-section.`\n );\n }\n providerDefaults.baseURL = flatInference.baseURL;\n }\n }\n return {\n maxTokens: flatInference.maxTokens,\n ...providerDefaults,\n ...specific,\n };\n }\n\n function resolveActorInference(fromMakeMeaning?: InferenceConfig, fromActors?: InferenceConfig): InferenceConfig | undefined {\n const base = fromMakeMeaning ?? fromActors ?? defaultMakeMeaningInference;\n if (!base) return undefined;\n return mergeWithFlatInference(base);\n }\n\n const actors: ActorInferenceConfig = {};\n const gathererInference = resolveActorInference(\n makeMeaningSection?.actors?.gatherer?.inference,\n actorsSection['gatherer']?.inference\n );\n if (gathererInference) actors.gatherer = gathererInference;\n\n const matcherInference = resolveActorInference(\n makeMeaningSection?.actors?.matcher?.inference,\n actorsSection['matcher']?.inference\n );\n if (matcherInference) actors.matcher = matcherInference;\n\n const workers: WorkerInferenceConfig = {};\n const workerTypes = ['reference-annotation', 'highlight-annotation', 'assessment-annotation', 'comment-annotation', 'tag-annotation', 'generation'] as const;\n if (defaultWorkerInference) {\n workers.default = mergeWithFlatInference(defaultWorkerInference);\n }\n for (const wt of workerTypes) {\n const specific = workersSection[wt]?.inference;\n if (specific) {\n (workers as Record<string, InferenceConfig>)[wt] = mergeWithFlatInference(specific);\n }\n }\n\n // 6. Map to EnvironmentConfig\n const backend = resolved.backend;\n const site = resolved.site ?? projectSite;\n const inferenceSection = resolved.inference;\n\n // Build inference providers config.\n // Supports two formats:\n // Flat: [environments.local.inference] type = \"anthropic\"|\"ollama\" (single provider)\n // Keyed: [environments.local.inference.anthropic] / [environments.local.inference.ollama] (multi-provider)\n let inferenceProviders: EnvironmentConfig['inference'] | undefined;\n if (inferenceSection) {\n inferenceProviders = {};\n // Keyed sub-sections take priority\n if (inferenceSection.anthropic) {\n const a = inferenceSection.anthropic;\n inferenceProviders.anthropic = {\n platform: requirePlatform(a.platform, 'inference.anthropic'),\n endpoint: a.endpoint ?? 'https://api.anthropic.com',\n apiKey: a.apiKey ?? '',\n } as AnthropicProviderConfig;\n } else if (inferenceSection.type === 'anthropic') {\n inferenceProviders.anthropic = {\n platform: requirePlatform(inferenceSection.platform, 'inference'),\n endpoint: inferenceSection.endpoint ?? 'https://api.anthropic.com',\n apiKey: inferenceSection.apiKey ?? '',\n } as AnthropicProviderConfig;\n }\n if (inferenceSection.ollama) {\n const o = inferenceSection.ollama;\n inferenceProviders.ollama = {\n platform: { type: requirePlatform(o.platform, 'inference.ollama') },\n baseURL: o.baseURL,\n port: o.baseURL ? undefined : (o.port ?? 11434),\n } as OllamaProviderConfig;\n } else if (inferenceSection.type === 'ollama') {\n inferenceProviders.ollama = {\n platform: { type: requirePlatform(inferenceSection.platform, 'inference') },\n baseURL: inferenceSection.baseURL,\n port: inferenceSection.baseURL ? undefined : 11434,\n } as OllamaProviderConfig;\n }\n }\n\n // Build top-level workers/actors maps for EnvironmentConfig\n const topLevelWorkers: EnvironmentConfig['workers'] = {};\n for (const [name, w] of Object.entries(workersSection)) {\n if (w.inference) {\n topLevelWorkers[name] = { inference: { type: w.inference.type, model: w.inference.model } };\n }\n }\n const topLevelActors: EnvironmentConfig['actors'] = {};\n for (const [name, a] of Object.entries(actorsSection)) {\n if (a.inference) {\n topLevelActors[name] = { inference: { type: a.inference.type, model: a.inference.model } };\n }\n }\n // Also include make-meaning actors\n if (makeMeaningSection?.actors?.gatherer?.inference) {\n topLevelActors['gatherer'] = { inference: { type: makeMeaningSection.actors.gatherer.inference.type, model: makeMeaningSection.actors.gatherer.inference.model } };\n }\n if (makeMeaningSection?.actors?.matcher?.inference) {\n topLevelActors['matcher'] = { inference: { type: makeMeaningSection.actors.matcher.inference.type, model: makeMeaningSection.actors.matcher.inference.model } };\n }\n\n const frontend = resolved.frontend;\n\n const services: EnvironmentConfig['services'] = {};\n\n if (backend) {\n services.backend = {\n platform: { type: requirePlatform(backend.platform, 'backend') },\n port: backend.port ?? 4000,\n publicURL: backend.publicURL ?? `http://localhost:${backend.port ?? 4000}`,\n corsOrigin: backend.corsOrigin ?? backend.frontendURL ?? 'http://localhost:3000',\n };\n }\n\n if (frontend) {\n services.frontend = {\n platform: { type: requirePlatform(frontend.platform, 'frontend') },\n port: frontend.port ?? 3000,\n siteName: site?.siteName ?? 'Semiont',\n publicURL: frontend.publicURL,\n };\n }\n\n if (resolved.graph) {\n services.graph = {\n ...resolved.graph,\n platform: { type: requirePlatform(resolved.graph.platform as string | undefined, 'graph') },\n type: (resolved.graph.type ?? 'neo4j') as import('./config.types').GraphDatabaseType,\n } as EnvironmentConfig['services']['graph'];\n } else if (makeMeaningSection?.graph) {\n services.graph = makeMeaningSection.graph as EnvironmentConfig['services']['graph'];\n }\n\n if (resolved.database) {\n services.database = {\n platform: { type: requirePlatform(resolved.database.platform, 'database') },\n type: 'postgres',\n image: resolved.database.image,\n host: resolved.database.host ?? 'localhost',\n port: resolved.database.port ?? 5432,\n name: resolved.database.name,\n user: resolved.database.user,\n password: resolved.database.password,\n } as EnvironmentConfig['services']['database'];\n }\n\n if (resolved.vectors) {\n services.vectors = {\n platform: { type: 'external' as PlatformType },\n type: (resolved.vectors.type ?? 'qdrant') as 'qdrant' | 'memory',\n host: resolved.vectors.host,\n port: resolved.vectors.port ?? 6333,\n } as EnvironmentConfig['services']['vectors'];\n }\n\n // Embedding: top-level takes precedence, fall back to legacy vectors.embedding\n const embeddingSource = resolved.embedding ?? resolved.vectors?.embedding;\n if (embeddingSource) {\n services.embedding = {\n platform: { type: 'external' as PlatformType },\n type: embeddingSource.type!,\n model: embeddingSource.model!,\n apiKey: embeddingSource.apiKey,\n baseURL: embeddingSource.baseURL,\n endpoint: embeddingSource.endpoint,\n chunking: (resolved.embedding?.chunking ?? resolved.vectors?.chunking) ? {\n chunkSize: (resolved.embedding?.chunking ?? resolved.vectors?.chunking)?.chunkSize ?? 512,\n overlap: (resolved.embedding?.chunking ?? resolved.vectors?.chunking)?.overlap ?? 64,\n } : undefined,\n } as EnvironmentConfig['services']['embedding'];\n }\n\n const config: EnvironmentConfig = {\n services,\n ...(inferenceProviders ? { inference: inferenceProviders } : {}),\n ...(Object.keys(topLevelWorkers).length > 0 ? { workers: topLevelWorkers } : {}),\n ...(Object.keys(topLevelActors).length > 0 ? { actors: topLevelActors } : {}),\n site: site ? {\n domain: site.domain ?? 'localhost',\n siteName: site.siteName,\n adminEmail: site.adminEmail,\n oauthAllowedDomains: site.oauthAllowedDomains as [string, ...string[]] | undefined,\n } : undefined,\n logLevel: resolved.logLevel,\n _metadata: {\n environment,\n projectRoot,\n projectName,\n projectVersion,\n ...(Object.keys(actors).length > 0 ? { actors } : {}),\n ...(Object.keys(workers).length > 0 ? { workers } : {}),\n },\n };\n\n return config;\n}\n\n/**\n * Create a TOML config loader backed by a file reader.\n * Drop-in replacement for createConfigLoader that reads TOML instead of JSON.\n * The caller must resolve globalConfigPath (e.g. expand '~' using process.env.HOME).\n */\nexport function createTomlConfigLoader(\n reader: TomlFileReader,\n globalConfigPath: string,\n env: Record<string, string | undefined>\n) {\n return (projectRoot: string | null, environment: string): EnvironmentConfig => {\n return loadTomlConfig(projectRoot, environment, globalConfigPath, reader, env);\n };\n}\n","import * as fs from 'fs';\nimport * as os from 'os';\nimport * as path from 'path';\nimport { execFileSync } from 'child_process';\n\n/**\n * Represents a Semiont project rooted at a given directory.\n *\n * Computes all paths — durable and ephemeral — once at construction time.\n * XDG environment variables are read here and nowhere else.\n *\n * Durable paths (inside the project root, committed or repo-local):\n * eventsDir — .semiont/events/ (system of record, committed)\n * representationsDir — representations/ (content store, committed)\n *\n * Ephemeral paths (outside the project root, never committed):\n * configDir — $XDG_CONFIG_HOME/semiont/{name}/ (generated config for managed processes)\n * dataHome — $XDG_DATA_HOME/semiont/{name}/ (persistent user data, e.g. database files)\n * stateDir — $XDG_STATE_HOME/semiont/{name}/\n * embeddingsDir — stateDir/embeddings/\n * projectionsDir — stateDir/projections/\n * jobsDir — stateDir/jobs/\n * backendLogsDir — stateDir/backend/\n * backendAppLogFile — backendLogsDir/app.log\n * backendErrorLogFile — backendLogsDir/error.log\n * runtimeDir — $XDG_RUNTIME_DIR/semiont/{name}/ (or $TMPDIR fallback)\n * backendPidFile — runtimeDir/backend.pid\n *\n * Note: frontend paths are NOT project-scoped. The frontend service is bundled\n * with the CLI and uses fixed XDG paths keyed by \"frontend\", not project name.\n * See apps/cli/src/platforms/posix/handlers/frontend-paths.ts.\n */\nexport class SemiontProject {\n readonly root: string;\n readonly name: string;\n\n /** True if [git] sync = true in .semiont/config. When true, semiont stages\n * working-tree and event-log changes in the git index automatically. */\n readonly gitSync: boolean;\n\n // Durable\n readonly eventsDir: string;\n readonly representationsDir: string;\n\n // Ephemeral — config (generated config files for managed processes)\n readonly configDir: string;\n\n // Ephemeral — data (persistent user data managed by semiont)\n readonly dataHome: string;\n\n // Ephemeral — state\n readonly stateDir: string;\n readonly embeddingsDir: string;\n readonly projectionsDir: string;\n readonly jobsDir: string;\n readonly backendLogsDir: string;\n readonly backendAppLogFile: string;\n readonly backendErrorLogFile: string;\n\n // Ephemeral — runtime\n readonly runtimeDir: string;\n readonly backendPidFile: string;\n\n constructor(projectRoot: string, name?: string) {\n this.root = projectRoot;\n if (name !== undefined) {\n const configPath = path.join(projectRoot, '.semiont', 'config');\n if (!fs.existsSync(configPath)) {\n fs.mkdirSync(path.join(projectRoot, '.semiont'), { recursive: true });\n fs.writeFileSync(configPath, `[project]\\nname = \"${name}\"\\n`);\n }\n }\n this.name = SemiontProject.readName(projectRoot);\n this.gitSync = SemiontProject.readGitSync(projectRoot);\n\n this.eventsDir = path.join(projectRoot, '.semiont', 'events');\n this.representationsDir = path.join(projectRoot, 'representations');\n\n const xdgConfig = process.env.XDG_CONFIG_HOME || path.join(os.homedir(), '.config');\n this.configDir = path.join(xdgConfig, 'semiont', this.name);\n\n const xdgData = process.env.XDG_DATA_HOME || path.join(os.homedir(), '.local', 'share');\n this.dataHome = path.join(xdgData, 'semiont', this.name);\n\n const xdgState = process.env.XDG_STATE_HOME || path.join(os.homedir(), '.local', 'state');\n this.stateDir = path.join(xdgState, 'semiont', this.name);\n this.embeddingsDir = path.join(this.stateDir, 'embeddings');\n this.projectionsDir = path.join(this.stateDir, 'projections');\n this.jobsDir = path.join(this.stateDir, 'jobs');\n this.backendLogsDir = path.join(this.stateDir, 'backend');\n this.backendAppLogFile = path.join(this.backendLogsDir, 'app.log');\n this.backendErrorLogFile = path.join(this.backendLogsDir, 'error.log');\n\n const xdgRuntime = process.env.XDG_RUNTIME_DIR;\n const runtimeBase = xdgRuntime ?? process.env.TMPDIR ?? '/tmp';\n this.runtimeDir = path.join(runtimeBase, 'semiont', this.name);\n this.backendPidFile = path.join(this.runtimeDir, 'backend.pid');\n }\n\n /**\n * Read the current git branch for the project root.\n * Returns null if the project is not a git repo or git is not available.\n */\n gitBranch(): string | null {\n try {\n return execFileSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {\n cwd: this.root,\n encoding: 'utf-8',\n stdio: ['ignore', 'pipe', 'ignore'],\n }).trim() || null;\n } catch {\n return null;\n }\n }\n\n /**\n * Delete all ephemeral state for this project (stateDir + runtimeDir).\n * Does not touch eventsDir or dataDir.\n */\n async destroy(): Promise<void> {\n await Promise.all([\n fs.promises.rm(this.configDir, { recursive: true, force: true }),\n fs.promises.rm(this.stateDir, { recursive: true, force: true }),\n fs.promises.rm(this.runtimeDir, { recursive: true, force: true }),\n ]);\n }\n\n /**\n * Read [git] sync from .semiont/config.\n * Defaults to false if the section or key is absent.\n */\n private static readGitSync(projectRoot: string): boolean {\n const configPath = path.join(projectRoot, '.semiont', 'config');\n if (!fs.existsSync(configPath)) return false;\n const content = fs.readFileSync(configPath, 'utf-8');\n let inGitSection = false;\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (trimmed === '[git]') { inGitSection = true; continue; }\n if (trimmed.startsWith('[')) { inGitSection = false; continue; }\n if (inGitSection && trimmed.startsWith('sync') && trimmed.includes('=')) {\n const value = trimmed.split('=')[1]?.trim();\n return value === 'true';\n }\n }\n return false;\n }\n\n /**\n * Read the project name from .semiont/config [project] name = \"...\"\n * Falls back to the directory basename if the config is absent or has no name.\n */\n private static readName(projectRoot: string): string {\n const configPath = path.join(projectRoot, '.semiont', 'config');\n if (fs.existsSync(configPath)) {\n const content = fs.readFileSync(configPath, 'utf-8');\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (trimmed.startsWith('name') && trimmed.includes('=')) {\n const [, ...rest] = trimmed.split('=');\n return rest.join('=').trim().replace(/^\"(.*)\"$/, '$1');\n }\n }\n }\n return path.basename(projectRoot);\n }\n}\n","import * as fs from 'fs';\nimport * as os from 'os';\nimport * as path from 'path';\nimport { createTomlConfigLoader } from './toml-loader.js';\nimport type { EnvironmentConfig } from './config.types.js';\n\nexport { SemiontProject } from '../project.js';\n\nconst nodeTomlFileReader = {\n readIfExists: (filePath: string): string | null =>\n fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf-8') : null,\n};\n\n/**\n * Load semiont environment config for a Node.js process.\n *\n * Reads ~/.semiontconfig (global) merged with .semiont/config (project-local),\n * then selects the given environment overlay.\n *\n * This is the canonical config loader for any Node.js process. SEMIONT_ENV\n * should be read once at the process entry point and passed as `environment`.\n */\nexport function loadEnvironmentConfig(\n projectRoot: string,\n environment: string\n): EnvironmentConfig {\n const globalConfigPath = path.join(os.homedir(), '.semiontconfig');\n return createTomlConfigLoader(\n nodeTomlFileReader,\n globalConfigPath,\n process.env\n )(projectRoot, environment);\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -3411,16 +3411,12 @@ interface components {
3411
3411
  percentage?: number;
3412
3412
  message?: string;
3413
3413
  };
3414
- /** @description Metadata added at persistence time. Part of every StoredEvent. */
3414
+ /** @description Metadata added at persistence time. Part of every StoredEvent. Integrity is provided by git at the commit level (when gitSync is enabled), not by in-event metadata fields. */
3415
3415
  EventMetadata: {
3416
3416
  /** @description Monotonic position in the event log (ordering authority) */
3417
3417
  sequenceNumber: number;
3418
3418
  /** @description Byte offset in the JSONL file */
3419
3419
  streamPosition: number;
3420
- /** @description SHA-256 of the previous event (hash chain) */
3421
- prevEventHash?: string;
3422
- /** @description SHA-256 of this event (integrity verification) */
3423
- checksum?: string;
3424
3420
  /** @description Optional correlation id propagated from a command. Lets clients match command-result events back to the POST that initiated them. Set by EventStore.appendEvent's options when a route handler passes one through. */
3425
3421
  correlationId?: string;
3426
3422
  };
@@ -3607,19 +3603,6 @@ interface components {
3607
3603
  error: string;
3608
3604
  details?: string;
3609
3605
  };
3610
- /** @description Payload for embedding:computed domain event */
3611
- EmbeddingComputedPayload: {
3612
- annotationId?: string;
3613
- chunkIndex: number;
3614
- chunkText: string;
3615
- embedding: number[];
3616
- model: string;
3617
- dimensions: number;
3618
- };
3619
- /** @description Payload for embedding:deleted domain event */
3620
- EmbeddingDeletedPayload: {
3621
- annotationId?: string;
3622
- };
3623
3606
  AnnotateHighlightsStreamRequest: {
3624
3607
  /** @description Optional instructions to guide AI highlight annotation */
3625
3608
  instructions?: string;
@@ -4312,21 +4295,6 @@ interface components {
4312
4295
  path: string;
4313
4296
  reason?: string;
4314
4297
  };
4315
- /** @description Command to store a computed embedding for a resource chunk */
4316
- EmbeddingComputeCommand: {
4317
- resourceId: string;
4318
- annotationId?: string;
4319
- chunkIndex: number;
4320
- chunkText: string;
4321
- embedding: number[];
4322
- model: string;
4323
- dimensions: number;
4324
- };
4325
- /** @description Command to delete embeddings for a resource or annotation */
4326
- EmbeddingDeleteCommand: {
4327
- resourceId: string;
4328
- annotationId?: string;
4329
- };
4330
4298
  /** @description W3C Web Annotation FragmentSelector for media fragment identifiers (RFC 3778 for PDFs) */
4331
4299
  FragmentSelector: {
4332
4300
  /** @enum {string} */
@@ -4963,7 +4931,7 @@ interface EntityTypeStats {
4963
4931
  /**
4964
4932
  * Persisted Events
4965
4933
  *
4966
- * The 20 event types that get appended to the JSONL event log.
4934
+ * The 18 event types that get appended to the JSONL event log.
4967
4935
  * Each maps a type string to its OpenAPI payload schema.
4968
4936
  * The PersistedEvent union derives from this catalog.
4969
4937
  */
@@ -4991,8 +4959,6 @@ type PersistedEventCatalog = {
4991
4959
  'job:progress': components['schemas']['JobProgressPayload'];
4992
4960
  'job:completed': components['schemas']['JobCompletedPayload'];
4993
4961
  'job:failed': components['schemas']['JobFailedPayload'];
4994
- 'embedding:computed': components['schemas']['EmbeddingComputedPayload'];
4995
- 'embedding:deleted': components['schemas']['EmbeddingDeletedPayload'];
4996
4962
  };
4997
4963
  /** System event types — persisted events that have no resourceId. */
4998
4964
  type SystemEventType = 'mark:entity-type-added';
@@ -5020,7 +4986,7 @@ type PersistedEventType = PersistedEvent['type'];
5020
4986
  * also adding it here: forgetting fails to typecheck rather than silently
5021
4987
  * dropping the event from the events-stream.
5022
4988
  */
5023
- declare const PERSISTED_EVENT_TYPES: readonly ["yield:created", "yield:cloned", "yield:updated", "yield:moved", "yield:representation-added", "yield:representation-removed", "mark:added", "mark:removed", "mark:body-updated", "mark:archived", "mark:unarchived", "mark:entity-tag-added", "mark:entity-tag-removed", "mark:entity-type-added", "job:started", "job:progress", "job:completed", "job:failed", "embedding:computed", "embedding:deleted"];
4989
+ declare const PERSISTED_EVENT_TYPES: readonly ["yield:created", "yield:cloned", "yield:updated", "yield:moved", "yield:representation-added", "yield:representation-removed", "mark:added", "mark:removed", "mark:body-updated", "mark:archived", "mark:unarchived", "mark:entity-tag-added", "mark:entity-tag-removed", "mark:entity-type-added", "job:started", "job:progress", "job:completed", "job:failed"];
5024
4990
  /** Input type for appendEvent — PersistedEvent without id/timestamp (assigned at persistence time). */
5025
4991
  type EventInput = Omit<PersistedEvent, 'id' | 'timestamp'>;
5026
4992
 
@@ -5306,8 +5272,6 @@ type EventMap = {
5306
5272
  'job:status-failed': {
5307
5273
  correlationId: string;
5308
5274
  } & components['schemas']['CommandError'];
5309
- 'embedding:compute': components['schemas']['EmbeddingComputeCommand'];
5310
- 'embedding:delete': components['schemas']['EmbeddingDeleteCommand'];
5311
5275
  'settings:theme-changed': components['schemas']['SettingsThemeChangedEvent'];
5312
5276
  'settings:line-numbers-toggled': void;
5313
5277
  'settings:locale-changed': components['schemas']['SettingsLocaleChangedEvent'];
@@ -5363,8 +5327,6 @@ interface StoredEventLike {
5363
5327
  payload?: unknown;
5364
5328
  metadata: {
5365
5329
  sequenceNumber: number;
5366
- prevEventHash?: string;
5367
- checksum?: string;
5368
5330
  };
5369
5331
  }
5370
5332
  /**
@@ -5583,6 +5545,57 @@ interface BurstBufferOptions {
5583
5545
  */
5584
5546
  declare function burstBuffer<T>(options: BurstBufferOptions): OperatorFunction<T, T | T[]>;
5585
5547
 
5548
+ /**
5549
+ * serializePerKey — run async work serialized per key, parallel across keys.
5550
+ *
5551
+ * Invariant: two calls with the same `key` run strictly in sequence (the
5552
+ * second `work` does not start until the first has settled). Calls with
5553
+ * different keys overlap freely.
5554
+ *
5555
+ * Error isolation: a rejected work function does not poison subsequent
5556
+ * tasks for the same key. The next task starts fresh from whatever state
5557
+ * the failed task left behind. The rejection still propagates to *this*
5558
+ * caller.
5559
+ *
5560
+ * Registry cleanup: the entry for a key is removed as soon as its chain
5561
+ * empties, so the Map stays bounded by the number of keys with work
5562
+ * currently in flight, not by the total number of keys ever seen.
5563
+ *
5564
+ * ## Usage
5565
+ *
5566
+ * ```ts
5567
+ * const chains = new Map<string, Promise<void>>();
5568
+ *
5569
+ * async function write(resourceId: string, event: Event) {
5570
+ * return serializePerKey(resourceId, chains, async () => {
5571
+ * // Read-modify-write on a view file. Any two concurrent calls with
5572
+ * // the same resourceId will be serialized; different resourceIds
5573
+ * // will proceed in parallel.
5574
+ * const view = await viewStorage.get(resourceId);
5575
+ * applyEvent(view, event);
5576
+ * await viewStorage.save(resourceId, view);
5577
+ * });
5578
+ * }
5579
+ * ```
5580
+ *
5581
+ * ## When to use this vs RxJS `groupBy + concatMap`
5582
+ *
5583
+ * Use `serializePerKey` when the work arrives as **direct method calls**
5584
+ * that need to block the caller until completion. This is the RPC shape
5585
+ * — think `EventStore.appendEvent` calling `await views.materializeResource(...)`
5586
+ * and needing the view written before any subscriber sees the published
5587
+ * event.
5588
+ *
5589
+ * Use RxJS `groupBy(keyFn) + concatMap(...)` when the work arrives as an
5590
+ * **event stream** that a component subscribes to once at startup. This
5591
+ * is how `Smelter`, `GraphDBConsumer`, and `Gatherer` serialize their own
5592
+ * per-resource work — see their implementations in `packages/make-meaning`.
5593
+ *
5594
+ * Both patterns solve the same logical problem ("serialize work per key").
5595
+ * The choice is dictated by whether the caller is awaiting the result.
5596
+ */
5597
+ declare function serializePerKey<K, T>(key: K, chains: Map<K, Promise<void>>, work: () => Promise<T>): Promise<T>;
5598
+
5586
5599
  /**
5587
5600
  * Logger interface for observability
5588
5601
  *
@@ -5608,17 +5621,78 @@ interface Logger {
5608
5621
  error(message: string, meta?: any): void;
5609
5622
  child(meta: Record<string, any>): Logger;
5610
5623
  }
5624
+ /**
5625
+ * Serialize an error value into a form that JSON.stringify can handle
5626
+ * meaningfully.
5627
+ *
5628
+ * Winston's default JSON formatter serializes `Error` instances as `{}`
5629
+ * because `message`, `stack`, and `name` are non-enumerable properties on
5630
+ * the Error prototype. That means `logger.error('x', { error })` with a
5631
+ * raw Error argument produces useless log lines like
5632
+ * `{"error":{},"message":"x",...}`, throwing away the information you
5633
+ * actually need to diagnose the failure.
5634
+ *
5635
+ * This helper extracts the parts you want to see in a log — name,
5636
+ * message, stack, and cause — and leaves non-Error values alone (so
5637
+ * strings, numbers, and plain objects pass through unchanged).
5638
+ *
5639
+ * ## Usage
5640
+ *
5641
+ * ```ts
5642
+ * try {
5643
+ * await doSomething();
5644
+ * } catch (error) {
5645
+ * logger.error('Something failed', { error: errField(error) });
5646
+ * }
5647
+ * ```
5648
+ *
5649
+ * Use this at every `logger.error` call site that includes an `error`
5650
+ * field derived from a catch block. Raw `{ error }` without this helper
5651
+ * is almost always a bug.
5652
+ */
5653
+ declare function errField(error: unknown): unknown;
5611
5654
 
5612
5655
  /**
5613
- * Backend-specific annotation utility functions
5656
+ * Annotation body utilities
5657
+ *
5658
+ * These are the matcher primitives used by the `mark:body-updated` event
5659
+ * replay path (ViewMaterializer and GraphDBConsumer) to apply add/remove/
5660
+ * replace operations against an annotation body.
5614
5661
  */
5615
5662
 
5616
5663
  type Annotation$2 = components['schemas']['Annotation'];
5664
+ type BodyPurpose = components['schemas']['BodyPurpose'];
5617
5665
  /**
5618
- * Find a body item in an array
5619
- * Returns the index of the first matching item, or -1 if not found
5666
+ * Identity of a body item for matching purposes.
5667
+ *
5668
+ * Identity is `type + source` for SpecificResource and `type + value` for
5669
+ * TextualBody. `purpose` is OPTIONAL: if the caller provides it, it's
5670
+ * included in the match (used to disambiguate same-source bodies under
5671
+ * different purposes, per the W3C Web Annotation model). If the caller
5672
+ * omits it, the matcher ignores purpose and matches on identity alone.
5673
+ *
5674
+ * Callers SHOULD provide `purpose` when they know it (e.g., the bind flow
5675
+ * always unlinks a `purpose: 'linking'` body) so that future multi-purpose
5676
+ * annotations continue to disambiguate correctly. Leaving `purpose`
5677
+ * unspecified matches whichever purpose comes first in the body — which is
5678
+ * fine today because Semiont annotations currently have at most one body
5679
+ * item per (type, source/value) pair.
5680
+ */
5681
+ type BodyItemIdentity = {
5682
+ type: 'SpecificResource';
5683
+ source: string;
5684
+ purpose?: BodyPurpose;
5685
+ } | {
5686
+ type: 'TextualBody';
5687
+ value: string;
5688
+ purpose?: BodyPurpose;
5689
+ };
5690
+ /**
5691
+ * Find a body item by identity. Returns the index of the first match, or -1.
5692
+ *
5693
+ * See `BodyItemIdentity` for matching semantics.
5620
5694
  */
5621
- declare function findBodyItem(body: Annotation$2['body'], targetItem: BodyItem): number;
5695
+ declare function findBodyItem(body: Annotation$2['body'], identity: BodyItemIdentity): number;
5622
5696
 
5623
5697
  /**
5624
5698
  * Annotation Assembly
@@ -5997,4 +6071,4 @@ declare function getAllPlatformTypes(): PlatformType[];
5997
6071
  declare const CORE_TYPES_VERSION = "0.1.0";
5998
6072
  declare const SDK_VERSION = "0.1.0";
5999
6073
 
6000
- export { APIError, type AccessToken, type AnnotationCategory, type AnnotationId, type AnnotationUri, type AssembledAnnotation, type AuthCode, type BaseUrl, type BodyItem, type BodyOperation, type Brand, type BurstBufferOptions, CORE_TYPES_VERSION, CREATION_METHODS, type CloneToken, ConfigurationError, ConflictError, type ContentFormat, type CreateAnnotationInternal, type CreationMethod, type Email, type EntityType, type EntityTypeStats, type Environment, EnvironmentConfig, type EventBase, EventBus, type EventInput, type EventMap, type EventMetadata, type EventName, type EventOfType, type EventQuery, type EventSignature, type GatheredContext, type GoogleAuthRequest, type GoogleCredential, type GraphConnection, type GraphPath, type JobId, type Logger, type MCPToken, type MarkProgress, type Motivation, NotFoundError, PERSISTED_EVENT_TYPES, type PersistedEvent, type PersistedEventType, type PlatformType, type RefreshToken, type ResourceAnnotationUri, type ResourceAnnotations, type ResourceFilter, type ResourceId, type ResourceUri, SDK_VERSION, STREAM_COMMAND_RESULT_TYPES, ScopedEventBus, ScriptError, type SearchQuery, type SelectionData, type Selector, SemiontError, type StoredEvent, type StoredEventLike, type ActorInferenceConfig as TomlActorInferenceConfig, type TomlFileReader, type InferenceConfig as TomlInferenceConfig, type WorkerInferenceConfig as TomlWorkerInferenceConfig, UnauthorizedError, type UpdateResourceInput, type UserDID, type UserId, ValidationError, type YieldProgress, accessToken, annotationId, annotationUri, applyBodyOperations, assembleAnnotation, authCode, baseUrl, burstBuffer, cloneToken, type components, createTomlConfigLoader, didToAgent, email, entityType, findBodyItem, generateUuid, getAllPlatformTypes, getAnnotationUriFromEvent, getFragmentSelector, getSvgSelector, getTextPositionSelector, googleCredential, isAnnotationId, isArray, isBoolean, isDefined, isEventRelatedToAnnotation, isFunction, isNull, isNullish, isNumber, isObject, isResourceId, isStoredEvent, isString, isUndefined, isValidPlatformType, jobId, loadTomlConfig, mcpToken, type operations, parseEnvironment, type paths, refreshToken, resourceAnnotationUri, resourceId, resourceUri, searchQuery, userDID, userId, userToAgent, userToDid, validateEnvironment, validateSvgMarkup };
6074
+ export { APIError, type AccessToken, type AnnotationCategory, type AnnotationId, type AnnotationUri, type AssembledAnnotation, type AuthCode, type BaseUrl, type BodyItem, type BodyItemIdentity, type BodyOperation, type Brand, type BurstBufferOptions, CORE_TYPES_VERSION, CREATION_METHODS, type CloneToken, ConfigurationError, ConflictError, type ContentFormat, type CreateAnnotationInternal, type CreationMethod, type Email, type EntityType, type EntityTypeStats, type Environment, EnvironmentConfig, type EventBase, EventBus, type EventInput, type EventMap, type EventMetadata, type EventName, type EventOfType, type EventQuery, type EventSignature, type GatheredContext, type GoogleAuthRequest, type GoogleCredential, type GraphConnection, type GraphPath, type JobId, type Logger, type MCPToken, type MarkProgress, type Motivation, NotFoundError, PERSISTED_EVENT_TYPES, type PersistedEvent, type PersistedEventType, type PlatformType, type RefreshToken, type ResourceAnnotationUri, type ResourceAnnotations, type ResourceFilter, type ResourceId, type ResourceUri, SDK_VERSION, STREAM_COMMAND_RESULT_TYPES, ScopedEventBus, ScriptError, type SearchQuery, type SelectionData, type Selector, SemiontError, type StoredEvent, type StoredEventLike, type ActorInferenceConfig as TomlActorInferenceConfig, type TomlFileReader, type InferenceConfig as TomlInferenceConfig, type WorkerInferenceConfig as TomlWorkerInferenceConfig, UnauthorizedError, type UpdateResourceInput, type UserDID, type UserId, ValidationError, type YieldProgress, accessToken, annotationId, annotationUri, applyBodyOperations, assembleAnnotation, authCode, baseUrl, burstBuffer, cloneToken, type components, createTomlConfigLoader, didToAgent, email, entityType, errField, findBodyItem, generateUuid, getAllPlatformTypes, getAnnotationUriFromEvent, getFragmentSelector, getSvgSelector, getTextPositionSelector, googleCredential, isAnnotationId, isArray, isBoolean, isDefined, isEventRelatedToAnnotation, isFunction, isNull, isNullish, isNumber, isObject, isResourceId, isStoredEvent, isString, isUndefined, isValidPlatformType, jobId, loadTomlConfig, mcpToken, type operations, parseEnvironment, type paths, refreshToken, resourceAnnotationUri, resourceId, resourceUri, searchQuery, serializePerKey, userDID, userId, userToAgent, userToDid, validateEnvironment, validateSvgMarkup };