@fortemi/core 2026.5.4 → 2026.6.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.
package/dist/index.js CHANGED
@@ -150,6 +150,103 @@ async function createPGliteInstance(persistence, archiveName = "default") {
150
150
  return db;
151
151
  }
152
152
 
153
+ // src/worker/worker-client.ts
154
+ var PGliteWorkerClient = class {
155
+ constructor(worker) {
156
+ this.worker = worker;
157
+ this.readyPromise = new Promise((resolve) => {
158
+ this.resolveReady = resolve;
159
+ });
160
+ this.worker.addEventListener("message", (e) => {
161
+ const msg = e.data;
162
+ if (msg.type === "READY") {
163
+ this.resolveReady();
164
+ return;
165
+ }
166
+ if (!("id" in msg)) return;
167
+ const pending = this.pending.get(msg.id);
168
+ if (!pending) return;
169
+ this.pending.delete(msg.id);
170
+ if (msg.type === "ERROR") {
171
+ pending.reject(new Error(msg.error));
172
+ } else {
173
+ pending.resolve(msg);
174
+ }
175
+ });
176
+ }
177
+ pending = /* @__PURE__ */ new Map();
178
+ readyPromise;
179
+ resolveReady;
180
+ /** Resolves when the worker broadcasts READY after database initialisation. */
181
+ async waitReady() {
182
+ return this.readyPromise;
183
+ }
184
+ send(request) {
185
+ const id = generateId();
186
+ return new Promise((resolve, reject) => {
187
+ this.pending.set(id, {
188
+ resolve,
189
+ reject
190
+ });
191
+ this.worker.postMessage({ ...request, id });
192
+ });
193
+ }
194
+ async query(sql, params) {
195
+ const resp = await this.send({ type: "QUERY", sql, params });
196
+ return { rows: resp.rows, fields: resp.fields };
197
+ }
198
+ async exec(sql) {
199
+ await this.send({ type: "EXEC", sql });
200
+ }
201
+ async transaction(fn) {
202
+ const resp = await this.send({ type: "BEGIN" });
203
+ const txId = resp.txId;
204
+ const proxy = new TransactionProxy(this, txId);
205
+ try {
206
+ const result = await fn(proxy);
207
+ await this.send({ type: "COMMIT", txId });
208
+ return result;
209
+ } catch (err) {
210
+ await this.send({ type: "ROLLBACK", txId }).catch(() => {
211
+ });
212
+ throw err;
213
+ }
214
+ }
215
+ /** Forward TX_QUERY for TransactionProxy — not part of the public surface. */
216
+ async _txQuery(txId, sql, params) {
217
+ const resp = await this.send({
218
+ type: "TX_QUERY",
219
+ txId,
220
+ sql,
221
+ params
222
+ });
223
+ return { rows: resp.rows };
224
+ }
225
+ /** Forward TX_EXEC for TransactionProxy — not part of the public surface. */
226
+ async _txExec(txId, sql) {
227
+ await this.send({ type: "TX_EXEC", txId, sql });
228
+ }
229
+ async ping() {
230
+ await this.send({ type: "PING" });
231
+ }
232
+ async close() {
233
+ await this.send({ type: "CLOSE" });
234
+ this.worker.terminate();
235
+ }
236
+ };
237
+ var TransactionProxy = class {
238
+ constructor(client, txId) {
239
+ this.client = client;
240
+ this.txId = txId;
241
+ }
242
+ async query(sql, params) {
243
+ return this.client._txQuery(this.txId, sql, params);
244
+ }
245
+ async exec(sql) {
246
+ return this.client._txExec(this.txId, sql);
247
+ }
248
+ };
249
+
153
250
  // src/storage-backend.ts
154
251
  var PGliteStorageBackend = class {
155
252
  constructor(id, db) {
@@ -177,6 +274,41 @@ var PGliteStorageBackendFactory = class {
177
274
  }
178
275
  };
179
276
  var defaultStorageBackendFactory = new PGliteStorageBackendFactory();
277
+ var PGliteWorkerStorageBackend = class {
278
+ constructor(id, client) {
279
+ this.id = id;
280
+ this.client = client;
281
+ }
282
+ mode = "readwrite";
283
+ query(sql, params) {
284
+ return this.client.query(sql, params);
285
+ }
286
+ exec(sql) {
287
+ return this.client.exec(sql);
288
+ }
289
+ transaction(fn) {
290
+ return this.client.transaction(fn);
291
+ }
292
+ close() {
293
+ return this.client.close();
294
+ }
295
+ };
296
+ var PGliteWorkerStorageBackendFactory = class {
297
+ constructor(options) {
298
+ this.options = options;
299
+ }
300
+ async open(input) {
301
+ const worker = this.options.createWorker();
302
+ const client = new PGliteWorkerClient(worker);
303
+ worker.postMessage({
304
+ type: "INIT",
305
+ persistence: input.persistence,
306
+ archiveName: input.archiveName
307
+ });
308
+ await client.waitReady();
309
+ return new PGliteWorkerStorageBackend(`pglite-worker:${input.persistence}:${input.archiveName}`, client);
310
+ }
311
+ };
180
312
 
181
313
  // src/capability-manager.ts
182
314
  var VALID_TRANSITIONS = {
@@ -799,13 +931,13 @@ var allMigrations = [
799
931
 
800
932
  // src/archive-manager.ts
801
933
  var ArchiveManager = class {
802
- constructor(persistenceOrFactory, events) {
934
+ constructor(persistenceOrFactory, events, persistenceOverride) {
803
935
  this.events = events;
804
936
  if (typeof persistenceOrFactory === "string") {
805
937
  this.persistence = persistenceOrFactory;
806
938
  this.backendFactory = defaultStorageBackendFactory;
807
939
  } else {
808
- this.persistence = "memory";
940
+ this.persistence = persistenceOverride ?? "memory";
809
941
  this.backendFactory = persistenceOrFactory;
810
942
  }
811
943
  this.archives.set("default", {
@@ -1170,103 +1302,6 @@ function createBlobStore(archiveName) {
1170
1302
  return new IdbBlobStore(archiveName);
1171
1303
  }
1172
1304
 
1173
- // src/worker/worker-client.ts
1174
- var PGliteWorkerClient = class {
1175
- constructor(worker) {
1176
- this.worker = worker;
1177
- this.readyPromise = new Promise((resolve) => {
1178
- this.resolveReady = resolve;
1179
- });
1180
- this.worker.addEventListener("message", (e) => {
1181
- const msg = e.data;
1182
- if (msg.type === "READY") {
1183
- this.resolveReady();
1184
- return;
1185
- }
1186
- if (!("id" in msg)) return;
1187
- const pending = this.pending.get(msg.id);
1188
- if (!pending) return;
1189
- this.pending.delete(msg.id);
1190
- if (msg.type === "ERROR") {
1191
- pending.reject(new Error(msg.error));
1192
- } else {
1193
- pending.resolve(msg);
1194
- }
1195
- });
1196
- }
1197
- pending = /* @__PURE__ */ new Map();
1198
- readyPromise;
1199
- resolveReady;
1200
- /** Resolves when the worker broadcasts READY after database initialisation. */
1201
- async waitReady() {
1202
- return this.readyPromise;
1203
- }
1204
- send(request) {
1205
- const id = generateId();
1206
- return new Promise((resolve, reject) => {
1207
- this.pending.set(id, {
1208
- resolve,
1209
- reject
1210
- });
1211
- this.worker.postMessage({ ...request, id });
1212
- });
1213
- }
1214
- async query(sql, params) {
1215
- const resp = await this.send({ type: "QUERY", sql, params });
1216
- return { rows: resp.rows, fields: resp.fields };
1217
- }
1218
- async exec(sql) {
1219
- await this.send({ type: "EXEC", sql });
1220
- }
1221
- async transaction(fn) {
1222
- const resp = await this.send({ type: "BEGIN" });
1223
- const txId = resp.txId;
1224
- const proxy = new TransactionProxy(this, txId);
1225
- try {
1226
- const result = await fn(proxy);
1227
- await this.send({ type: "COMMIT", txId });
1228
- return result;
1229
- } catch (err) {
1230
- await this.send({ type: "ROLLBACK", txId }).catch(() => {
1231
- });
1232
- throw err;
1233
- }
1234
- }
1235
- /** Forward TX_QUERY for TransactionProxy — not part of the public surface. */
1236
- async _txQuery(txId, sql, params) {
1237
- const resp = await this.send({
1238
- type: "TX_QUERY",
1239
- txId,
1240
- sql,
1241
- params
1242
- });
1243
- return { rows: resp.rows };
1244
- }
1245
- /** Forward TX_EXEC for TransactionProxy — not part of the public surface. */
1246
- async _txExec(txId, sql) {
1247
- await this.send({ type: "TX_EXEC", txId, sql });
1248
- }
1249
- async ping() {
1250
- await this.send({ type: "PING" });
1251
- }
1252
- async close() {
1253
- await this.send({ type: "CLOSE" });
1254
- this.worker.terminate();
1255
- }
1256
- };
1257
- var TransactionProxy = class {
1258
- constructor(client, txId) {
1259
- this.client = client;
1260
- this.txId = txId;
1261
- }
1262
- async query(sql, params) {
1263
- return this.client._txQuery(this.txId, sql, params);
1264
- }
1265
- async exec(sql) {
1266
- return this.client._txExec(this.txId, sql);
1267
- }
1268
- };
1269
-
1270
1305
  // src/repositories/notes-repository.ts
1271
1306
  var NotesRepository = class {
1272
1307
  constructor(db, events) {
@@ -2953,12 +2988,12 @@ var JobQueueWorker = class {
2953
2988
  if (job.required_capability) {
2954
2989
  const capName = job.required_capability;
2955
2990
  if (!this.capabilityManager?.isReady(capName)) {
2956
- console.log(`[JobQueue] Skipping ${job.job_type} \u2014 capability '${capName}' not ready`);
2991
+ await this.blockForCapability(job, capName);
2957
2992
  continue;
2958
2993
  }
2959
2994
  }
2960
2995
  await this.db.query(
2961
- `UPDATE job_queue SET status = 'processing', updated_at = now() WHERE id = $1`,
2996
+ `UPDATE job_queue SET status = 'processing', error = NULL, updated_at = now() WHERE id = $1`,
2962
2997
  [job.id]
2963
2998
  );
2964
2999
  try {
@@ -2966,7 +3001,7 @@ var JobQueueWorker = class {
2966
3001
  const jobResult = await handler(job, this.db);
2967
3002
  console.log(`[JobQueue] Completed ${job.job_type}:`, jobResult);
2968
3003
  await this.db.query(
2969
- `UPDATE job_queue SET status = 'completed', result = $1, updated_at = now() WHERE id = $2`,
3004
+ `UPDATE job_queue SET status = 'completed', error = NULL, result = $1, updated_at = now() WHERE id = $2`,
2970
3005
  [JSON.stringify(jobResult ?? null), job.id]
2971
3006
  );
2972
3007
  this.events?.emit("job.completed", {
@@ -3000,6 +3035,30 @@ var JobQueueWorker = class {
3000
3035
  }
3001
3036
  return processed;
3002
3037
  }
3038
+ async blockForCapability(job, capability) {
3039
+ const message = `requires capability '${capability}' \u2014 not ready`;
3040
+ console.log(`[JobQueue] Deferring ${job.job_type} \u2014 ${message}`);
3041
+ await this.db.query(
3042
+ `UPDATE job_queue
3043
+ SET status = 'pending', error = $1, updated_at = now()
3044
+ WHERE id = $2 AND error IS DISTINCT FROM $1`,
3045
+ [message, job.id]
3046
+ );
3047
+ this.events?.emit("job.blocked", {
3048
+ id: job.id,
3049
+ noteId: job.note_id,
3050
+ type: job.job_type,
3051
+ capability,
3052
+ message
3053
+ });
3054
+ this.events?.emit("capability.required", {
3055
+ name: capability,
3056
+ jobId: job.id,
3057
+ noteId: job.note_id,
3058
+ type: job.job_type,
3059
+ message
3060
+ });
3061
+ }
3003
3062
  getBackoffDelay(retryCount) {
3004
3063
  const delay = this.options.backoffBaseMs * Math.pow(2, retryCount);
3005
3064
  return Math.min(delay, this.options.backoffMaxMs);
@@ -5147,6 +5206,33 @@ var FallbackRouter = class {
5147
5206
  }
5148
5207
  };
5149
5208
 
5209
+ // src/fortemi-bridge.ts
5210
+ function getFortemiBridge(host = globalThis) {
5211
+ return host?.fortemiBridge ?? null;
5212
+ }
5213
+ function getFortemiSecretStore(host = globalThis) {
5214
+ return host?.fortemiBridge?.secrets ?? host?.fortemiSecureStorage ?? null;
5215
+ }
5216
+ async function hasFortemiSecureSecrets(host = globalThis) {
5217
+ const bridge = getFortemiBridge(host);
5218
+ if (bridge) {
5219
+ try {
5220
+ const capabilities = await bridge.capabilities();
5221
+ if (!capabilities.secureSecrets) return false;
5222
+ return Boolean(await bridge.secrets.isAvailable());
5223
+ } catch {
5224
+ return false;
5225
+ }
5226
+ }
5227
+ const legacySecrets = host?.fortemiSecureStorage;
5228
+ if (!legacySecrets) return false;
5229
+ try {
5230
+ return Boolean(await legacySecrets.isAvailable());
5231
+ } catch {
5232
+ return false;
5233
+ }
5234
+ }
5235
+
5150
5236
  // src/security/plugin-content.ts
5151
5237
  var DEFAULT_DIRECTIVES = {
5152
5238
  "default-src": ["'self'"],
@@ -5803,25 +5889,52 @@ async function exportShard(db, options) {
5803
5889
  components.push("provenance_edges");
5804
5890
  counts.provenance_edges = filteredProvenanceRows.length;
5805
5891
  if (options?.includeEmbeddings) {
5806
- const embSetRows = await db.query(`SELECT * FROM embedding_set ORDER BY created_at`);
5892
+ const embeddingSetIds = options.embeddingSetIds?.filter(Boolean) ?? [];
5893
+ const setScoped = embeddingSetIds.length > 0;
5894
+ const embSetRows = await db.query(
5895
+ `SELECT * FROM embedding_set
5896
+ ${setScoped ? "WHERE id = ANY($1)" : ""}
5897
+ ORDER BY created_at`,
5898
+ setScoped ? [embeddingSetIds] : []
5899
+ );
5900
+ const exportedSetIds = new Set(embSetRows.rows.map((row) => row.id));
5807
5901
  const shardEmbSets = embSetRows.rows.map(embeddingSetToShard);
5808
5902
  files.set("embedding_sets.json", encoder.encode(JSON.stringify(shardEmbSets)));
5809
5903
  components.push("embedding_sets");
5810
5904
  counts.embedding_sets = shardEmbSets.length;
5811
- const embMemberRows = await db.query(`SELECT * FROM embedding_set_member`);
5812
- const membersJsonl = embMemberRows.rows.map((m) => JSON.stringify(embeddingSetMemberToShard(m))).join("\n");
5905
+ const embMemberRows = await db.query(
5906
+ `SELECT * FROM embedding_set_member
5907
+ ${setScoped ? "WHERE embedding_set_id = ANY($1)" : ""}`,
5908
+ setScoped ? [embeddingSetIds] : []
5909
+ );
5910
+ const scopedEmbMemberRows = embMemberRows.rows.filter(
5911
+ (member) => exportedSetIds.has(member.embedding_set_id) && exportedNoteIds.has(member.note_id)
5912
+ );
5913
+ const membersJsonl = scopedEmbMemberRows.map((m) => JSON.stringify(embeddingSetMemberToShard(m))).join("\n");
5813
5914
  files.set("embedding_set_members.jsonl", encoder.encode(membersJsonl));
5814
5915
  components.push("embedding_set_members");
5815
- counts.embedding_set_members = embMemberRows.rows.length;
5816
- const embRows = await db.query(`SELECT * FROM embedding ORDER BY created_at`);
5817
- const embJsonl = embRows.rows.map((e) => JSON.stringify(embeddingToShard(e))).join("\n");
5916
+ counts.embedding_set_members = scopedEmbMemberRows.length;
5917
+ const embRows = await db.query(
5918
+ `SELECT * FROM embedding
5919
+ ${setScoped ? "WHERE embedding_set_id = ANY($1)" : ""}
5920
+ ORDER BY created_at`,
5921
+ setScoped ? [embeddingSetIds] : []
5922
+ );
5923
+ const memberEmbeddingIds = new Set(scopedEmbMemberRows.map((member) => member.embedding_id));
5924
+ const scopedEmbRows = embRows.rows.filter(
5925
+ (embedding) => exportedSetIds.has(embedding.embedding_set_id) && exportedNoteIds.has(embedding.note_id) && (memberEmbeddingIds.size === 0 || memberEmbeddingIds.has(embedding.id))
5926
+ );
5927
+ const embJsonl = scopedEmbRows.map((e) => JSON.stringify(embeddingToShard(e))).join("\n");
5818
5928
  files.set("embeddings.jsonl", encoder.encode(embJsonl));
5819
5929
  components.push("embeddings");
5820
- counts.embeddings = embRows.rows.length;
5930
+ counts.embeddings = scopedEmbRows.length;
5821
5931
  }
5822
5932
  const graphSourceRows = await db.query(`SELECT * FROM graph_source ORDER BY created_at, id`);
5823
- if (graphSourceRows.rows.length > 0) {
5824
- const shardGraphSources = graphSourceRows.rows.map((row) => ({
5933
+ const graphScoped = !!options?.embeddingSetIds?.length;
5934
+ const scopedGraphSourceRows = graphScoped ? graphSourceRows.rows.filter((row) => !row.embedding_set_id || options.embeddingSetIds?.includes(row.embedding_set_id)) : graphSourceRows.rows;
5935
+ const exportedGraphSourceIds = new Set(scopedGraphSourceRows.map((row) => row.id));
5936
+ if (scopedGraphSourceRows.length > 0) {
5937
+ const shardGraphSources = scopedGraphSourceRows.map((row) => ({
5825
5938
  id: row.id,
5826
5939
  name: row.name,
5827
5940
  kind: row.kind,
@@ -5843,8 +5956,9 @@ async function exportShard(db, options) {
5843
5956
  counts.graph_sources = shardGraphSources.length;
5844
5957
  }
5845
5958
  const graphEdgeRows = await db.query(`SELECT * FROM graph_edge_artifact ORDER BY graph_source_id, from_note_id, to_note_id, kind`);
5846
- if (graphEdgeRows.rows.length > 0) {
5847
- const graphEdgesJsonl = graphEdgeRows.rows.map((row) => JSON.stringify({
5959
+ const scopedGraphEdgeRows = graphScoped ? graphEdgeRows.rows.filter((row) => exportedGraphSourceIds.has(row.graph_source_id)) : graphEdgeRows.rows;
5960
+ if (scopedGraphEdgeRows.length > 0) {
5961
+ const graphEdgesJsonl = scopedGraphEdgeRows.map((row) => JSON.stringify({
5848
5962
  graph_source_id: row.graph_source_id,
5849
5963
  from_note_id: row.from_note_id,
5850
5964
  to_note_id: row.to_note_id,
@@ -5855,18 +5969,21 @@ async function exportShard(db, options) {
5855
5969
  })).join("\n");
5856
5970
  files.set("graph_edges.jsonl", encoder.encode(graphEdgesJsonl));
5857
5971
  components.push("graph_edges");
5858
- counts.graph_edges = graphEdgeRows.rows.length;
5972
+ counts.graph_edges = scopedGraphEdgeRows.length;
5859
5973
  }
5860
5974
  const communitySetRows = await db.query(`SELECT * FROM community_set ORDER BY created_at, id`);
5861
5975
  const communityRows = await db.query(`SELECT * FROM community ORDER BY community_set_id, rank NULLS LAST, id`);
5862
- if (communitySetRows.rows.length > 0) {
5976
+ const scopedCommunitySetRows = graphScoped ? communitySetRows.rows.filter((row) => exportedGraphSourceIds.has(row.graph_source_id)) : communitySetRows.rows;
5977
+ const exportedCommunitySetIds = new Set(scopedCommunitySetRows.map((row) => row.id));
5978
+ const scopedCommunityRows = graphScoped ? communityRows.rows.filter((row) => exportedCommunitySetIds.has(row.community_set_id)) : communityRows.rows;
5979
+ if (scopedCommunitySetRows.length > 0) {
5863
5980
  const communitiesBySet = /* @__PURE__ */ new Map();
5864
- for (const row of communityRows.rows) {
5981
+ for (const row of scopedCommunityRows) {
5865
5982
  const rows = communitiesBySet.get(row.community_set_id) ?? [];
5866
5983
  rows.push(row);
5867
5984
  communitiesBySet.set(row.community_set_id, rows);
5868
5985
  }
5869
- const shardCommunitySets = communitySetRows.rows.map((row) => ({
5986
+ const shardCommunitySets = scopedCommunitySetRows.map((row) => ({
5870
5987
  id: row.id,
5871
5988
  graph_source_id: row.graph_source_id,
5872
5989
  name: row.name,
@@ -5889,11 +6006,12 @@ async function exportShard(db, options) {
5889
6006
  files.set("communities.json", encoder.encode(JSON.stringify(shardCommunitySets)));
5890
6007
  components.push("communities");
5891
6008
  counts.community_sets = shardCommunitySets.length;
5892
- counts.communities = communityRows.rows.length;
6009
+ counts.communities = scopedCommunityRows.length;
5893
6010
  }
5894
6011
  const assignmentRows = await db.query(`SELECT * FROM community_assignment ORDER BY community_set_id, community_id, note_id`);
5895
- if (assignmentRows.rows.length > 0) {
5896
- const assignmentsJsonl = assignmentRows.rows.map((row) => JSON.stringify({
6012
+ const scopedAssignmentRows = graphScoped ? assignmentRows.rows.filter((row) => exportedCommunitySetIds.has(row.community_set_id)) : assignmentRows.rows;
6013
+ if (scopedAssignmentRows.length > 0) {
6014
+ const assignmentsJsonl = scopedAssignmentRows.map((row) => JSON.stringify({
5897
6015
  community_set_id: row.community_set_id,
5898
6016
  community_id: row.community_id,
5899
6017
  note_id: row.note_id,
@@ -5903,7 +6021,7 @@ async function exportShard(db, options) {
5903
6021
  })).join("\n");
5904
6022
  files.set("community_assignments.jsonl", encoder.encode(assignmentsJsonl));
5905
6023
  components.push("community_assignments");
5906
- counts.community_assignments = assignmentRows.rows.length;
6024
+ counts.community_assignments = scopedAssignmentRows.length;
5907
6025
  }
5908
6026
  const checksums = {};
5909
6027
  for (const [filename, data] of files) {
@@ -5925,9 +6043,25 @@ async function exportShard(db, options) {
5925
6043
 
5926
6044
  // src/shard/shard-import.ts
5927
6045
  var decoder = new TextDecoder();
6046
+ var DEFAULT_BATCH_SIZE = 250;
6047
+ async function yieldToEventLoop() {
6048
+ const scheduler = globalThis.scheduler;
6049
+ if (scheduler?.yield) {
6050
+ await scheduler.yield();
6051
+ return;
6052
+ }
6053
+ await new Promise((resolve) => setTimeout(resolve, 0));
6054
+ }
6055
+ async function maybeYield(done, batchSize) {
6056
+ if (batchSize > 0 && done > 0 && done % batchSize === 0) {
6057
+ await yieldToEventLoop();
6058
+ }
6059
+ }
5928
6060
  async function importShard(db, data, options) {
5929
6061
  const start = performance.now();
5930
6062
  const strategy = options?.conflictStrategy ?? "skip";
6063
+ const batchSize = options?.batchSize ?? DEFAULT_BATCH_SIZE;
6064
+ const report = options?.onProgress;
5931
6065
  const warnings = [];
5932
6066
  const errors = [];
5933
6067
  const counts = {
@@ -5951,9 +6085,11 @@ async function importShard(db, data, options) {
5951
6085
  };
5952
6086
  const skipped = {};
5953
6087
  const inputData = data instanceof ArrayBuffer ? new Uint8Array(data) : data;
6088
+ report?.({ phase: "unpack", done: 0, total: 1 });
5954
6089
  let files;
5955
6090
  try {
5956
6091
  files = unpackTarGz(inputData);
6092
+ report?.({ phase: "unpack", done: 1, total: 1 });
5957
6093
  } catch (err) {
5958
6094
  return {
5959
6095
  success: false,
@@ -6000,6 +6136,7 @@ async function importShard(db, data, options) {
6000
6136
  duration_ms: performance.now() - start
6001
6137
  };
6002
6138
  }
6139
+ report?.({ phase: "validate", done: 0, total: 1 });
6003
6140
  const checksumResult = await validateChecksums(manifest.checksums, files);
6004
6141
  if (!checksumResult.valid) {
6005
6142
  return {
@@ -6011,6 +6148,7 @@ async function importShard(db, data, options) {
6011
6148
  duration_ms: performance.now() - start
6012
6149
  };
6013
6150
  }
6151
+ report?.({ phase: "validate", done: 1, total: 1 });
6014
6152
  const parsedNotes = parseJsonl(files.get("notes.jsonl"));
6015
6153
  const parsedCollections = parseJsonArray(files.get("collections.json"));
6016
6154
  parseJsonArray(files.get("tags.json"));
@@ -6061,7 +6199,8 @@ async function importShard(db, data, options) {
6061
6199
  const conflictClause = strategy === "skip" ? "ON CONFLICT DO NOTHING" : "";
6062
6200
  try {
6063
6201
  await db.transaction(async (tx) => {
6064
- for (const shardCol of parsedCollections) {
6202
+ report?.({ phase: "collections", done: 0, total: parsedCollections.length });
6203
+ for (const [index, shardCol] of parsedCollections.entries()) {
6065
6204
  const col = collectionFromShard(shardCol);
6066
6205
  if (strategy === "replace") {
6067
6206
  await tx.query(
@@ -6078,8 +6217,11 @@ async function importShard(db, data, options) {
6078
6217
  );
6079
6218
  }
6080
6219
  counts.collections++;
6220
+ report?.({ phase: "collections", done: index + 1, total: parsedCollections.length });
6221
+ await maybeYield(index + 1, batchSize);
6081
6222
  }
6082
- for (const shardNote of parsedNotes) {
6223
+ report?.({ phase: "notes", done: 0, total: parsedNotes.length });
6224
+ for (const [index, shardNote] of parsedNotes.entries()) {
6083
6225
  const note = noteFromShard(shardNote);
6084
6226
  const contentHash = computeHash(new TextEncoder().encode(note.original_content));
6085
6227
  if (strategy === "replace") {
@@ -6156,7 +6298,12 @@ async function importShard(db, data, options) {
6156
6298
  );
6157
6299
  }
6158
6300
  counts.notes++;
6301
+ report?.({ phase: "notes", done: index + 1, total: parsedNotes.length });
6302
+ await maybeYield(index + 1, batchSize);
6159
6303
  }
6304
+ const totalSkos = parsedSkosSchemes.length + parsedSkosConcepts.length + parsedSkosRelations.length + parsedNoteSkosTags.length;
6305
+ let doneSkos = 0;
6306
+ report?.({ phase: "skos", done: doneSkos, total: totalSkos });
6160
6307
  for (const scheme of parsedSkosSchemes) {
6161
6308
  if (strategy === "replace") {
6162
6309
  await tx.query(
@@ -6173,6 +6320,8 @@ async function importShard(db, data, options) {
6173
6320
  );
6174
6321
  }
6175
6322
  counts.skos_schemes++;
6323
+ report?.({ phase: "skos", done: ++doneSkos, total: totalSkos });
6324
+ await maybeYield(doneSkos, batchSize);
6176
6325
  }
6177
6326
  for (const concept of parsedSkosConcepts) {
6178
6327
  const altLabels = JSON.stringify(concept.alt_labels ?? []);
@@ -6191,8 +6340,11 @@ async function importShard(db, data, options) {
6191
6340
  );
6192
6341
  }
6193
6342
  counts.skos_concepts++;
6343
+ report?.({ phase: "skos", done: ++doneSkos, total: totalSkos });
6344
+ await maybeYield(doneSkos, batchSize);
6194
6345
  }
6195
- for (const shardLink of parsedLinks) {
6346
+ report?.({ phase: "links", done: 0, total: parsedLinks.length });
6347
+ for (const [index, shardLink] of parsedLinks.entries()) {
6196
6348
  const link = linkFromShard(shardLink);
6197
6349
  if (strategy === "replace") {
6198
6350
  await tx.query(
@@ -6209,6 +6361,8 @@ async function importShard(db, data, options) {
6209
6361
  );
6210
6362
  }
6211
6363
  counts.links++;
6364
+ report?.({ phase: "links", done: index + 1, total: parsedLinks.length });
6365
+ await maybeYield(index + 1, batchSize);
6212
6366
  }
6213
6367
  for (const relation of parsedSkosRelations) {
6214
6368
  if (strategy === "replace") {
@@ -6226,6 +6380,8 @@ async function importShard(db, data, options) {
6226
6380
  );
6227
6381
  }
6228
6382
  counts.skos_relations++;
6383
+ report?.({ phase: "skos", done: ++doneSkos, total: totalSkos });
6384
+ await maybeYield(doneSkos, batchSize);
6229
6385
  }
6230
6386
  for (const tag of parsedNoteSkosTags) {
6231
6387
  await tx.query(
@@ -6235,8 +6391,11 @@ async function importShard(db, data, options) {
6235
6391
  [tag.id, tag.note_id, tag.concept_id, tag.created_at]
6236
6392
  );
6237
6393
  counts.note_skos_tags++;
6394
+ report?.({ phase: "skos", done: ++doneSkos, total: totalSkos });
6395
+ await maybeYield(doneSkos, batchSize);
6238
6396
  }
6239
- for (const edge of parsedProvenanceEdges) {
6397
+ report?.({ phase: "provenance", done: 0, total: parsedProvenanceEdges.length });
6398
+ for (const [index, edge] of parsedProvenanceEdges.entries()) {
6240
6399
  const attributes = edge.attributes === null ? null : JSON.stringify(edge.attributes);
6241
6400
  if (strategy === "replace") {
6242
6401
  await tx.query(
@@ -6253,8 +6412,11 @@ async function importShard(db, data, options) {
6253
6412
  );
6254
6413
  }
6255
6414
  counts.provenance_edges++;
6415
+ report?.({ phase: "provenance", done: index + 1, total: parsedProvenanceEdges.length });
6416
+ await maybeYield(index + 1, batchSize);
6256
6417
  }
6257
- for (const shardSet of parsedEmbSets) {
6418
+ report?.({ phase: "embedding_sets", done: 0, total: parsedEmbSets.length });
6419
+ for (const [index, shardSet] of parsedEmbSets.entries()) {
6258
6420
  const set = embeddingSetFromShard(shardSet);
6259
6421
  if (strategy === "replace") {
6260
6422
  await tx.query(
@@ -6277,8 +6439,11 @@ async function importShard(db, data, options) {
6277
6439
  );
6278
6440
  }
6279
6441
  counts.embedding_sets++;
6442
+ report?.({ phase: "embedding_sets", done: index + 1, total: parsedEmbSets.length });
6443
+ await maybeYield(index + 1, batchSize);
6280
6444
  }
6281
- for (const shardEmb of parsedEmbeddings) {
6445
+ report?.({ phase: "embeddings", done: 0, total: parsedEmbeddings.length });
6446
+ for (const [index, shardEmb] of parsedEmbeddings.entries()) {
6282
6447
  const emb = embeddingFromShard(shardEmb);
6283
6448
  if (strategy === "replace") {
6284
6449
  await tx.query(
@@ -6295,7 +6460,12 @@ async function importShard(db, data, options) {
6295
6460
  );
6296
6461
  }
6297
6462
  counts.embeddings++;
6463
+ report?.({ phase: "embeddings", done: index + 1, total: parsedEmbeddings.length });
6464
+ await maybeYield(index + 1, batchSize);
6298
6465
  }
6466
+ const totalGraph = parsedGraphSources.length + parsedGraphEdges.length;
6467
+ let doneGraph = 0;
6468
+ report?.({ phase: "graph", done: doneGraph, total: totalGraph });
6299
6469
  for (const source of parsedGraphSources) {
6300
6470
  const parameters = source.parameters == null ? null : JSON.stringify(source.parameters);
6301
6471
  const freshness = JSON.stringify({ ...source.freshness ?? {}, status: "unknown" });
@@ -6308,6 +6478,8 @@ async function importShard(db, data, options) {
6308
6478
  [source.id, source.name, source.kind, source.source_table ?? null, source.embedding_set_id ?? null, source.virtual_set_id ?? null, source.model ?? null, source.dimension ?? null, source.truncate_dimension ?? null, source.metric ?? null, source.algorithm ?? null, parameters, source.input_hash, freshness, source.created_at]
6309
6479
  );
6310
6480
  counts.graph_sources++;
6481
+ report?.({ phase: "graph", done: ++doneGraph, total: totalGraph });
6482
+ await maybeYield(doneGraph, batchSize);
6311
6483
  }
6312
6484
  for (const edge of parsedGraphEdges) {
6313
6485
  const metadata = edge.metadata == null ? null : JSON.stringify(edge.metadata);
@@ -6318,7 +6490,12 @@ async function importShard(db, data, options) {
6318
6490
  [edge.graph_source_id, edge.from_note_id, edge.to_note_id, edge.weight, edge.kind, edge.rank ?? null, metadata]
6319
6491
  );
6320
6492
  counts.graph_edges++;
6493
+ report?.({ phase: "graph", done: ++doneGraph, total: totalGraph });
6494
+ await maybeYield(doneGraph, batchSize);
6321
6495
  }
6496
+ const totalCommunities = parsedCommunitySets.length + parsedCommunitySets.reduce((sum, set) => sum + (set.communities?.length ?? 0), 0) + parsedCommunityAssignments.length;
6497
+ let doneCommunities = 0;
6498
+ report?.({ phase: "communities", done: doneCommunities, total: totalCommunities });
6322
6499
  for (const set of parsedCommunitySets) {
6323
6500
  const parameters = set.parameters == null ? null : JSON.stringify(set.parameters);
6324
6501
  const freshness = JSON.stringify({ ...set.freshness ?? {}, status: "unknown" });
@@ -6329,6 +6506,8 @@ async function importShard(db, data, options) {
6329
6506
  [set.id, set.graph_source_id, set.name, set.source_type, set.algorithm ?? null, parameters, set.input_hash, freshness, set.created_at]
6330
6507
  );
6331
6508
  counts.community_sets++;
6509
+ report?.({ phase: "communities", done: ++doneCommunities, total: totalCommunities });
6510
+ await maybeYield(doneCommunities, batchSize);
6332
6511
  for (const community of set.communities ?? []) {
6333
6512
  const metadata = community.metadata == null ? null : JSON.stringify(community.metadata);
6334
6513
  await tx.query(
@@ -6338,6 +6517,8 @@ async function importShard(db, data, options) {
6338
6517
  [set.id, community.id, community.label ?? null, community.rank ?? null, community.size ?? null, community.confidence ?? null, community.representative_note_ids ?? [], metadata]
6339
6518
  );
6340
6519
  counts.communities++;
6520
+ report?.({ phase: "communities", done: ++doneCommunities, total: totalCommunities });
6521
+ await maybeYield(doneCommunities, batchSize);
6341
6522
  }
6342
6523
  }
6343
6524
  for (const assignment of parsedCommunityAssignments) {
@@ -6349,16 +6530,22 @@ async function importShard(db, data, options) {
6349
6530
  [assignment.community_set_id, assignment.community_id, assignment.note_id, assignment.confidence ?? null, assignment.source_type, metadata]
6350
6531
  );
6351
6532
  counts.community_assignments++;
6533
+ report?.({ phase: "communities", done: ++doneCommunities, total: totalCommunities });
6534
+ await maybeYield(doneCommunities, batchSize);
6352
6535
  }
6353
- for (const member of parsedEmbMembers) {
6536
+ report?.({ phase: "embedding_set_members", done: 0, total: parsedEmbMembers.length });
6537
+ for (const [index, member] of parsedEmbMembers.entries()) {
6354
6538
  await tx.query(
6355
6539
  `INSERT INTO embedding_set_member (embedding_set_id, note_id, embedding_id)
6356
6540
  VALUES ($1, $2, $3) ON CONFLICT DO NOTHING`,
6357
6541
  [member.embedding_set_id, member.note_id, member.embedding_id]
6358
6542
  );
6359
6543
  counts.embedding_set_members++;
6544
+ report?.({ phase: "embedding_set_members", done: index + 1, total: parsedEmbMembers.length });
6545
+ await maybeYield(index + 1, batchSize);
6360
6546
  }
6361
6547
  });
6548
+ report?.({ phase: "index", done: 1, total: 1 });
6362
6549
  } catch (err) {
6363
6550
  return {
6364
6551
  success: false,
@@ -6388,9 +6575,187 @@ function parseJsonArray(data) {
6388
6575
  return JSON.parse(decoder.decode(data));
6389
6576
  }
6390
6577
 
6578
+ // src/aiwg-index.ts
6579
+ var REQUIRED_RECORD_FIELDS = [
6580
+ "schema_version",
6581
+ "id",
6582
+ "type",
6583
+ "source",
6584
+ "title",
6585
+ "text",
6586
+ "facets",
6587
+ "tags",
6588
+ "concepts",
6589
+ "relationships",
6590
+ "provenance",
6591
+ "privacy",
6592
+ "updated_at"
6593
+ ];
6594
+ var VALID_TYPES = /* @__PURE__ */ new Set([
6595
+ "crm.contact",
6596
+ "crm.organization",
6597
+ "crm.event",
6598
+ "crm.interaction",
6599
+ "aiwg.artifact"
6600
+ ]);
6601
+ function hasString(value) {
6602
+ return typeof value === "string" && value.length > 0;
6603
+ }
6604
+ function pushFacet(counts, name, value) {
6605
+ counts[name] ??= {};
6606
+ counts[name][value] = (counts[name][value] ?? 0) + 1;
6607
+ }
6608
+ function validateAiwgFortemiIndexExport(value) {
6609
+ const errors = [];
6610
+ const counts = {};
6611
+ const data = value;
6612
+ if (data?.schema_version !== "aiwg.fortemi.index.export.v1") {
6613
+ errors.push("schema_version must be aiwg.fortemi.index.export.v1");
6614
+ }
6615
+ if (!hasString(data?.generated_at)) errors.push("generated_at is required");
6616
+ if (!hasString(data?.source?.repo)) errors.push("source.repo is required");
6617
+ if (!hasString(data?.source?.privacy)) errors.push("source.privacy is required");
6618
+ if (!Array.isArray(data?.items)) errors.push("items must be an array");
6619
+ const ids = /* @__PURE__ */ new Set();
6620
+ let previousId = "";
6621
+ for (const [index, item] of (data.items ?? []).entries()) {
6622
+ for (const field of REQUIRED_RECORD_FIELDS) {
6623
+ if (!(field in item)) errors.push("items[" + index + "]." + field + " is required");
6624
+ }
6625
+ if (item.schema_version !== "aiwg.fortemi.index.record.v1") {
6626
+ errors.push("items[" + index + "].schema_version must be aiwg.fortemi.index.record.v1");
6627
+ }
6628
+ if (!hasString(item.id)) errors.push("items[" + index + "].id is required");
6629
+ if (hasString(item.id) && ids.has(item.id)) errors.push("duplicate id: " + item.id);
6630
+ if (hasString(item.id)) ids.add(item.id);
6631
+ if (previousId && hasString(item.id) && previousId.localeCompare(item.id) > 0) {
6632
+ errors.push("items must be sorted by id: " + previousId + " before " + item.id);
6633
+ }
6634
+ if (hasString(item.id)) previousId = item.id;
6635
+ if (!VALID_TYPES.has(item.type)) errors.push("items[" + index + "].type is invalid");
6636
+ else counts[item.type] = (counts[item.type] ?? 0) + 1;
6637
+ if (!hasString(item.source?.path)) errors.push("items[" + index + "].source.path is required");
6638
+ if (!hasString(item.source?.repo_relative_path)) errors.push("items[" + index + "].source.repo_relative_path is required");
6639
+ if (!hasString(item.source?.locator)) errors.push("items[" + index + "].source.locator is required");
6640
+ if (!Array.isArray(item.tags)) errors.push("items[" + index + "].tags must be an array");
6641
+ if (!Array.isArray(item.concepts)) errors.push("items[" + index + "].concepts must be an array");
6642
+ if (!Array.isArray(item.relationships)) errors.push("items[" + index + "].relationships must be an array");
6643
+ if (!Array.isArray(item.provenance) || item.provenance.length === 0) {
6644
+ errors.push("items[" + index + "].provenance must be a non-empty array");
6645
+ }
6646
+ if (!item.privacy || typeof item.privacy.pii !== "boolean" || !hasString(item.privacy.classification)) {
6647
+ errors.push("items[" + index + "].privacy requires classification and pii");
6648
+ }
6649
+ }
6650
+ return { valid: errors.length === 0, errors, counts };
6651
+ }
6652
+ function assertAiwgFortemiIndexExport(value) {
6653
+ const result = validateAiwgFortemiIndexExport(value);
6654
+ if (!result.valid) {
6655
+ throw new Error("Invalid AIWG Fortemi index export:\n" + result.errors.join("\n"));
6656
+ }
6657
+ return value;
6658
+ }
6659
+ function getAiwgFortemiFacets(items) {
6660
+ const result = {};
6661
+ for (const item of items) {
6662
+ pushFacet(result, "type", item.type);
6663
+ pushFacet(result, "privacy", item.privacy.classification);
6664
+ for (const tag of item.tags) pushFacet(result, "tag", tag);
6665
+ for (const concept of item.concepts) pushFacet(result, "concept", concept);
6666
+ for (const [name, values] of Object.entries(item.facets)) {
6667
+ for (const value of values) pushFacet(result, name, value);
6668
+ }
6669
+ }
6670
+ return result;
6671
+ }
6672
+ function includesAll(actual, expected) {
6673
+ if (!expected || expected.length === 0) return true;
6674
+ const actualSet = new Set(actual);
6675
+ return expected.every((value) => actualSet.has(value));
6676
+ }
6677
+ function matchesFacetFilters(item, filters) {
6678
+ if (!filters) return true;
6679
+ return Object.entries(filters).every(([name, expected]) => includesAll(item.facets[name] ?? [], expected));
6680
+ }
6681
+ function queryAiwgFortemiIndex(index, query = "", options = {}) {
6682
+ const q = query.trim().toLowerCase();
6683
+ const filtered = index.items.filter((item) => {
6684
+ if (q) {
6685
+ const haystack = [item.title, item.text, ...item.tags, ...item.concepts].join("\n").toLowerCase();
6686
+ if (!haystack.includes(q)) return false;
6687
+ }
6688
+ if (options.types && !options.types.includes(item.type)) return false;
6689
+ if (options.privacy && !options.privacy.includes(item.privacy.classification)) return false;
6690
+ if (!includesAll(item.tags, options.tags)) return false;
6691
+ if (!includesAll(item.concepts, options.concepts)) return false;
6692
+ if (!matchesFacetFilters(item, options.facets)) return false;
6693
+ if (options.relationshipTargetId && !item.relationships.some((rel) => rel.target_id === options.relationshipTargetId)) return false;
6694
+ return true;
6695
+ });
6696
+ const offset = options.offset ?? 0;
6697
+ const limit = options.limit ?? filtered.length;
6698
+ return {
6699
+ items: filtered.slice(offset, offset + limit),
6700
+ total: filtered.length,
6701
+ facets: getAiwgFortemiFacets(filtered)
6702
+ };
6703
+ }
6704
+ function createAiwgReviewDecisionExport(source, decisions, generatedAt = (/* @__PURE__ */ new Date()).toISOString()) {
6705
+ return {
6706
+ schema_version: "aiwg.fortemi.review-decisions.v1",
6707
+ generated_at: generatedAt,
6708
+ source_export_schema_version: source.schema_version,
6709
+ decisions: [...decisions].sort((left, right) => left.item_id.localeCompare(right.item_id))
6710
+ };
6711
+ }
6712
+ function aiwgFortemiIndexToCommunityGraph(index, options = {}) {
6713
+ const ids = new Set(index.items.map((item) => item.id));
6714
+ const relationshipWeights = options.relationshipWeights ?? {};
6715
+ const edgeCounts = /* @__PURE__ */ new Map();
6716
+ for (const item of index.items) {
6717
+ for (const relationship of item.relationships) {
6718
+ if (!ids.has(relationship.target_id) && !options.includeDanglingRelationships) continue;
6719
+ const kind = relationship.type;
6720
+ const baseWeight = relationshipWeights[kind] ?? 1;
6721
+ const key = `${item.id}\0${relationship.target_id}\0${kind}`;
6722
+ const existing = edgeCounts.get(key);
6723
+ if (existing) existing.weight += baseWeight;
6724
+ else edgeCounts.set(key, { source: item.id, target: relationship.target_id, kind, weight: baseWeight });
6725
+ }
6726
+ }
6727
+ const communities = /* @__PURE__ */ new Map();
6728
+ for (const item of index.items) {
6729
+ const communityIds = communityIdsFor(item, options);
6730
+ for (const communityId of communityIds) {
6731
+ const nodes = communities.get(communityId) ?? [];
6732
+ nodes.push(item.id);
6733
+ communities.set(communityId, nodes);
6734
+ }
6735
+ }
6736
+ return {
6737
+ nodes: index.items.map((item) => ({ id: item.id })),
6738
+ edges: Array.from(edgeCounts.values()).sort((left, right) => left.source.localeCompare(right.source) || left.target.localeCompare(right.target) || left.kind.localeCompare(right.kind)),
6739
+ communities: Array.from(communities.entries()).map(([id, nodes]) => ({ id, nodes: [...new Set(nodes)].sort() })).sort((left, right) => left.id.localeCompare(right.id))
6740
+ };
6741
+ }
6742
+ function communityIdsFor(item, options) {
6743
+ if (options.communityFacet) {
6744
+ const values = item.facets[options.communityFacet] ?? [];
6745
+ if (values.length > 0) return values.map((value) => `${options.communityFacet}:${value}`);
6746
+ }
6747
+ if (options.communityTagPrefix) {
6748
+ const prefix = options.communityTagPrefix;
6749
+ const tags = item.tags.filter((tag) => tag.startsWith(prefix));
6750
+ if (tags.length > 0) return tags;
6751
+ }
6752
+ if (item.concepts.length > 0) return item.concepts.map((concept) => `concept:${concept}`);
6753
+ return [`type:${item.type}`];
6754
+ }
6755
+
6391
6756
  // src/index.ts
6392
- var VERSION = "2026.5.4";
6757
+ var VERSION = "2026.6.1";
6393
6758
 
6394
- export { ArchiveManager, AttachmentsRepository, CURRENT_SHARD_VERSION, CapabilityManager, CaptureKnowledgeInputSchema, CollectionsRepository, CommunitiesRepository, EmbeddingSetsRepository, FallbackRouter, FortemiToolManifest, GetNoteInputSchema, GraphRepository, JOB_CAPABILITIES, JOB_PRIORITIES, JobQueueWorker, LOCAL_ENDPOINTS, LinksRepository, ListNotesInputSchema, ManageArchiveInputSchema, ManageAttachmentsInputSchema, ManageCapabilitiesInputSchema, ManageCollectionsInputSchema, ManageLinksInputSchema, ManageNoteInputSchema, ManageTagsInputSchema, MemoryBlobStore, MigrationRunner, NotesRepository, OpenAICompatibleProvider, PGliteStorageBackend, PGliteStorageBackendFactory, PGliteWorkerClient, ProviderRegistry, SHARD_FORMAT, SearchInputSchema, SearchRepository, SkosRepository, TagsRepository, TransactionProxy, TypedEventBus, VERSION, aiRevisionHandler, allMigrations, appendPluginScript, buildNoteConditions, buildPluginCsp, captureKnowledge, chunkText, classifyError, classifyModel, collectionFromShard, collectionToShard, computeHash, computeSri, conceptTaggingHandler, cosineSimilarity, createBlobStore, createCspReportHandler, createFortemi, createLegacyProvider, createPGliteInstance, createRoutes, defaultStorageBackendFactory, detectCommunities, detectGpuCapabilities, detectInferenceCapabilities, discoverLocalProviders, embeddingFromShard, embeddingGenerationHandler, embeddingSetFromShard, embeddingSetMemberToShard, embeddingSetToShard, embeddingToShard, enqueueFullWorkflow, enqueueJob, enqueueNoteCreationJobs, estimateModelFit, estimateVramMB, estimateVramTier, exportShard, fetchPluginScript, fortemiManifest, generateId, getEmbedFunction, getJobQueueStatus, getLlmFunction, getNote, importShard, isPluginScriptAllowed, linkFromShard, linkToShard, linkingHandler, listNotes, manageArchive, manageAttachments, manageCapabilities, manageCollections, manageLinks, manageNote, manageTags, matchRoute, noteFromShard, noteSkosTagToShard, noteToShard, packTarGz, parseCspReport, provenanceEdgeToShard, registerLlmCapability, registerSemanticCapability, registerServiceWorker, searchTool, selectLlmModel, setEmbedFunction, setLlmFunction, sha256Hex, skosConceptToShard, skosRelationToShard, skosSchemeToShard, suggestTags, tagsFromShard, tagsToShard, titleGenerationHandler, unpackTarGz, unregisterLlmCapability, unregisterSemanticCapability, validateChecksums, verifySri };
6759
+ export { ArchiveManager, AttachmentsRepository, CURRENT_SHARD_VERSION, CapabilityManager, CaptureKnowledgeInputSchema, CollectionsRepository, CommunitiesRepository, EmbeddingSetsRepository, FallbackRouter, FortemiToolManifest, GetNoteInputSchema, GraphRepository, JOB_CAPABILITIES, JOB_PRIORITIES, JobQueueWorker, LOCAL_ENDPOINTS, LinksRepository, ListNotesInputSchema, ManageArchiveInputSchema, ManageAttachmentsInputSchema, ManageCapabilitiesInputSchema, ManageCollectionsInputSchema, ManageLinksInputSchema, ManageNoteInputSchema, ManageTagsInputSchema, MemoryBlobStore, MigrationRunner, NotesRepository, OpenAICompatibleProvider, PGliteStorageBackend, PGliteStorageBackendFactory, PGliteWorkerClient, PGliteWorkerStorageBackend, PGliteWorkerStorageBackendFactory, ProviderRegistry, SHARD_FORMAT, SearchInputSchema, SearchRepository, SkosRepository, TagsRepository, TransactionProxy, TypedEventBus, VERSION, aiRevisionHandler, aiwgFortemiIndexToCommunityGraph, allMigrations, appendPluginScript, assertAiwgFortemiIndexExport, buildNoteConditions, buildPluginCsp, captureKnowledge, chunkText, classifyError, classifyModel, collectionFromShard, collectionToShard, computeHash, computeSri, conceptTaggingHandler, cosineSimilarity, createAiwgReviewDecisionExport, createBlobStore, createCspReportHandler, createFortemi, createLegacyProvider, createPGliteInstance, createRoutes, defaultStorageBackendFactory, detectCommunities, detectGpuCapabilities, detectInferenceCapabilities, discoverLocalProviders, embeddingFromShard, embeddingGenerationHandler, embeddingSetFromShard, embeddingSetMemberToShard, embeddingSetToShard, embeddingToShard, enqueueFullWorkflow, enqueueJob, enqueueNoteCreationJobs, estimateModelFit, estimateVramMB, estimateVramTier, exportShard, fetchPluginScript, fortemiManifest, generateId, getAiwgFortemiFacets, getEmbedFunction, getFortemiBridge, getFortemiSecretStore, getJobQueueStatus, getLlmFunction, getNote, hasFortemiSecureSecrets, importShard, isPluginScriptAllowed, linkFromShard, linkToShard, linkingHandler, listNotes, manageArchive, manageAttachments, manageCapabilities, manageCollections, manageLinks, manageNote, manageTags, matchRoute, noteFromShard, noteSkosTagToShard, noteToShard, packTarGz, parseCspReport, provenanceEdgeToShard, queryAiwgFortemiIndex, registerLlmCapability, registerSemanticCapability, registerServiceWorker, searchTool, selectLlmModel, setEmbedFunction, setLlmFunction, sha256Hex, skosConceptToShard, skosRelationToShard, skosSchemeToShard, suggestTags, tagsFromShard, tagsToShard, titleGenerationHandler, unpackTarGz, unregisterLlmCapability, unregisterSemanticCapability, validateAiwgFortemiIndexExport, validateChecksums, verifySri };
6395
6760
  //# sourceMappingURL=index.js.map
6396
6761
  //# sourceMappingURL=index.js.map