@fortemi/core 2026.7.10 → 2026.7.12

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
@@ -7664,7 +7664,7 @@ function createTarHeader(filename, size) {
7664
7664
  writeOctal(header, 108, 0, 8);
7665
7665
  writeOctal(header, 116, 0, 8);
7666
7666
  writeOctal(header, 124, size, 12);
7667
- writeOctal(header, 136, Math.floor(Date.now() / 1e3), 12);
7667
+ writeOctal(header, 136, 0, 12);
7668
7668
  header[156] = 48;
7669
7669
  writeString(header, 257, USTAR_MAGIC, 8);
7670
7670
  const checksum = computeHeaderChecksum(header);
@@ -7736,7 +7736,7 @@ function packTarGz(files, opts) {
7736
7736
  "Refusing to create archive: uncompressed size " + tarData.byteLength + " exceeds cap " + cap + " bytes"
7737
7737
  );
7738
7738
  }
7739
- return gzipSync(tarData);
7739
+ return gzipSync(tarData, { mtime: 0 });
7740
7740
  }
7741
7741
  var DEFAULT_MAX_DECOMPRESSED_BYTES = 256 * 1024 * 1024;
7742
7742
  function unpackTarGz(data, opts) {
@@ -14516,6 +14516,22 @@ function coreReferenceErrors(records) {
14516
14516
  errors.push(`collections.json[${index}] parent_id does not reference a declared collection`);
14517
14517
  }
14518
14518
  }
14519
+ const collectionById = new Map(collections.map((collection) => [collection.id, collection]));
14520
+ const visiting = /* @__PURE__ */ new Set();
14521
+ const visited = /* @__PURE__ */ new Set();
14522
+ const visitCollection = (collection) => {
14523
+ if (visited.has(collection.id)) return;
14524
+ if (visiting.has(collection.id)) {
14525
+ errors.push(`collection hierarchy contains a cycle at ${String(collection.id)}`);
14526
+ return;
14527
+ }
14528
+ visiting.add(collection.id);
14529
+ const parent = collection.parent_id === null ? void 0 : collectionById.get(collection.parent_id);
14530
+ if (parent) visitCollection(parent);
14531
+ visiting.delete(collection.id);
14532
+ visited.add(collection.id);
14533
+ };
14534
+ for (const collection of collections) visitCollection(collection);
14519
14535
  for (const [index, note] of notes.entries()) {
14520
14536
  if (note.collection_id !== null && !collectionIds.has(note.collection_id)) {
14521
14537
  errors.push(`notes.jsonl[${index}] collection_id does not reference a declared collection`);
@@ -17470,6 +17486,8 @@ function clearPrefetchedShard(url) {
17470
17486
  }
17471
17487
  warmStore.delete(url);
17472
17488
  }
17489
+
17490
+ // src/aiwg-index.ts
17473
17491
  var AIWG_SCAN_REQUIRED_FIELDS = [
17474
17492
  "schema_version",
17475
17493
  "id",
@@ -20200,6 +20218,18 @@ var RECORD_STORE_CAPABILITIES = {
20200
20218
  vectorSearch: false,
20201
20219
  sqlJoins: false
20202
20220
  };
20221
+ function normalizeRecordMutation(mutation) {
20222
+ if (mutation.op === "put" && mutation.collection === "collection") {
20223
+ return {
20224
+ ...mutation,
20225
+ record: {
20226
+ ...mutation.record,
20227
+ parent_id: mutation.record.parent_id ?? null
20228
+ }
20229
+ };
20230
+ }
20231
+ return mutation;
20232
+ }
20203
20233
 
20204
20234
  // src/records/memory-record-store.ts
20205
20235
  var MemoryRecordStore = class {
@@ -20245,7 +20275,8 @@ var MemoryRecordStore = class {
20245
20275
  }
20246
20276
  return records;
20247
20277
  };
20248
- for (const mutation of mutations) {
20278
+ for (const rawMutation of mutations) {
20279
+ const mutation = normalizeRecordMutation(rawMutation);
20249
20280
  const entry = mutation.op === "put" ? {
20250
20281
  seq: ++stagedSeq,
20251
20282
  ts: (/* @__PURE__ */ new Date()).toISOString(),
@@ -20292,7 +20323,7 @@ var MemoryRecordStore = class {
20292
20323
  var DB_VERSION = 1;
20293
20324
  var JOURNAL_STORE = "journal";
20294
20325
  var META_STORE = "meta";
20295
- var RECORD_SCHEMA_VERSION = 1;
20326
+ var RECORD_SCHEMA_VERSION = 2;
20296
20327
  function requestToPromise(request) {
20297
20328
  return new Promise((resolve, reject) => {
20298
20329
  request.onsuccess = () => resolve(request.result);
@@ -20340,16 +20371,25 @@ var IdbRecordStore = class _IdbRecordStore {
20340
20371
  return store;
20341
20372
  }
20342
20373
  async ensureSchemaVersion() {
20343
- const tx = this.db.transaction(META_STORE, "readwrite");
20374
+ const tx = this.db.transaction([META_STORE, "collection"], "readwrite");
20344
20375
  const meta = tx.objectStore(META_STORE);
20345
20376
  const current = await requestToPromise(meta.get("schemaVersion"));
20346
- if (current === void 0) {
20347
- meta.put(RECORD_SCHEMA_VERSION, "schemaVersion");
20348
- } else if (current > RECORD_SCHEMA_VERSION) {
20377
+ if (current !== void 0 && current > RECORD_SCHEMA_VERSION) {
20349
20378
  throw new Error(
20350
20379
  `IdbRecordStore: records were written by a newer schema (v${current} > v${RECORD_SCHEMA_VERSION}); refusing to open`
20351
20380
  );
20352
20381
  }
20382
+ if ((current ?? 0) < 2) {
20383
+ const collections = await requestToPromise(
20384
+ tx.objectStore("collection").getAll()
20385
+ );
20386
+ for (const collection of collections) {
20387
+ if (!Object.hasOwn(collection, "parent_id")) {
20388
+ tx.objectStore("collection").put({ ...collection, parent_id: null });
20389
+ }
20390
+ }
20391
+ }
20392
+ meta.put(RECORD_SCHEMA_VERSION, "schemaVersion");
20353
20393
  await transactionComplete(tx);
20354
20394
  }
20355
20395
  async get(collection, id) {
@@ -20368,12 +20408,13 @@ var IdbRecordStore = class _IdbRecordStore {
20368
20408
  }
20369
20409
  async applyBatch(mutations) {
20370
20410
  if (mutations.length === 0) return [];
20371
- const collections = [...new Set(mutations.map((mutation) => mutation.collection))];
20411
+ const normalizedMutations = mutations.map(normalizeRecordMutation);
20412
+ const collections = [...new Set(normalizedMutations.map((mutation) => mutation.collection))];
20372
20413
  const tx = this.db.transaction([...collections, JOURNAL_STORE], "readwrite");
20373
20414
  const completed = transactionComplete(tx);
20374
20415
  const pendingEntries = [];
20375
20416
  try {
20376
- for (const mutation of mutations) {
20417
+ for (const mutation of normalizedMutations) {
20377
20418
  const records = tx.objectStore(mutation.collection);
20378
20419
  const pending = mutation.op === "put" ? {
20379
20420
  ts: (/* @__PURE__ */ new Date()).toISOString(),
@@ -20620,12 +20661,16 @@ ${revised.get(note.id) ?? ""}`.toLowerCase();
20620
20661
  );
20621
20662
  }
20622
20663
  // ── Collections ───────────────────────────────────────────────────────────
20623
- async createCollection(name, description) {
20664
+ async createCollection(name, description, parentId = null) {
20665
+ if (parentId !== null && !await this.store.get("collection", parentId)) {
20666
+ throw new Error(`Parent collection not found: ${parentId}`);
20667
+ }
20624
20668
  const ts = nowIso();
20625
20669
  const collection = {
20626
20670
  id: generateId(),
20627
20671
  name,
20628
20672
  description: description ?? null,
20673
+ parent_id: parentId,
20629
20674
  created_at: ts,
20630
20675
  updated_at: ts,
20631
20676
  deleted_at: null
@@ -20808,6 +20853,32 @@ async function dropAttachmentProjection(db) {
20808
20853
  }
20809
20854
 
20810
20855
  // src/records/record-projection.ts
20856
+ function collectionsParentFirst(collections) {
20857
+ const byId = new Map(collections.map((collection) => [collection.id, collection]));
20858
+ const ordered = [];
20859
+ const visiting = /* @__PURE__ */ new Set();
20860
+ const visited = /* @__PURE__ */ new Set();
20861
+ const visit = (collection) => {
20862
+ if (visited.has(collection.id)) return;
20863
+ if (visiting.has(collection.id)) {
20864
+ throw new Error(`Collection hierarchy contains a cycle at ${collection.id}`);
20865
+ }
20866
+ visiting.add(collection.id);
20867
+ const parentId = collection.parent_id ?? null;
20868
+ if (parentId !== null) {
20869
+ const parent = byId.get(parentId);
20870
+ if (!parent) {
20871
+ throw new Error(`Collection ${collection.id} references missing parent ${parentId}`);
20872
+ }
20873
+ visit(parent);
20874
+ }
20875
+ visiting.delete(collection.id);
20876
+ visited.add(collection.id);
20877
+ ordered.push(collection);
20878
+ };
20879
+ for (const collection of collections) visit(collection);
20880
+ return ordered;
20881
+ }
20811
20882
  async function projectNotes(db, store) {
20812
20883
  const [noteRows, originals, revised, tags, links, collections, memberships] = await Promise.all([
20813
20884
  store.list("note"),
@@ -20818,16 +20889,25 @@ async function projectNotes(db, store) {
20818
20889
  store.list("collection"),
20819
20890
  store.list("collection_note")
20820
20891
  ]);
20821
- for (const c of collections) {
20892
+ for (const c of collectionsParentFirst(collections)) {
20822
20893
  await db.query(
20823
- `INSERT INTO collection (id, name, description, created_at, updated_at, deleted_at)
20824
- VALUES ($1, $2, $3, $4, $5, $6)
20894
+ `INSERT INTO collection (id, name, description, parent_id, created_at, updated_at, deleted_at)
20895
+ VALUES ($1, $2, $3, $4, $5, $6, $7)
20825
20896
  ON CONFLICT (id) DO UPDATE SET
20826
20897
  name = EXCLUDED.name,
20827
20898
  description = EXCLUDED.description,
20899
+ parent_id = EXCLUDED.parent_id,
20828
20900
  updated_at = EXCLUDED.updated_at,
20829
20901
  deleted_at = EXCLUDED.deleted_at`,
20830
- [c.id, c.name, c.description, c.created_at, c.updated_at, c.deleted_at]
20902
+ [
20903
+ c.id,
20904
+ c.name,
20905
+ c.description,
20906
+ c.parent_id ?? null,
20907
+ c.created_at,
20908
+ c.updated_at,
20909
+ c.deleted_at
20910
+ ]
20831
20911
  );
20832
20912
  }
20833
20913
  for (const n of noteRows) {
@@ -21325,12 +21405,11 @@ async function buildRecordShardArchive(store, options, profile) {
21325
21405
  const orderedCollections = collections.sort((a, b) => a.name.localeCompare(b.name));
21326
21406
  const shardCollections = orderedCollections.map((c) => {
21327
21407
  const mapped = collectionToShard(
21328
- // Canonical collections are flat (no parent hierarchy yet).
21329
21408
  {
21330
21409
  id: c.id,
21331
21410
  name: c.name,
21332
21411
  description: c.description,
21333
- parent_id: null,
21412
+ parent_id: c.parent_id ?? null,
21334
21413
  created_at: c.created_at,
21335
21414
  updated_at: c.updated_at,
21336
21415
  deleted_at: c.deleted_at
@@ -21764,6 +21843,7 @@ async function importShardToRecords(store, data, options) {
21764
21843
  id: col.id,
21765
21844
  name: col.name,
21766
21845
  description: col.description,
21846
+ parent_id: col.parent_id,
21767
21847
  created_at: col.created_at,
21768
21848
  updated_at: col.updated_at,
21769
21849
  deleted_at: col.deleted_at
@@ -22038,7 +22118,7 @@ async function importShardToRecords(store, data, options) {
22038
22118
  }
22039
22119
 
22040
22120
  // src/index.ts
22041
- var VERSION = "2026.7.10";
22121
+ var VERSION = "2026.7.12";
22042
22122
 
22043
22123
  export { AIWG_SCAN_REQUIRED_FIELDS, AllowlistTrustStore, ArchiveManager, AttachmentsRepository, CORE_V1_COMPONENTS, CURRENT_MIGRATION_HEAD, CURRENT_SHARD_VERSION, CanonicalAttachmentsRepository, CanonicalNotesRepository, CapabilityManager, CaptureKnowledgeInputSchema, CollectionsRepository, CommunitiesRepository, DB_SNAPSHOT_SCHEMA_VERSION, DbSnapshotVersionError, EMBED_REQUEST_KIND, EMBED_RESPONSE_KIND, EmbeddingSetsRepository, FORTEMI_COMPATIBILITY_PATH, FORTEMI_COMPATIBILITY_STATES, FORTEMI_REQUIRED_COMPATIBILITY_CAPABILITIES, FallbackRouter, FortemiToolManifest, GetNoteInputSchema, GraphRepository, IdbRecordStore, JOB_CAPABILITIES, JOB_PRIORITIES, JobQueueWorker, LOCAL_ENDPOINTS, LinksRepository, ListNotesInputSchema, ManageArchiveInputSchema, ManageAttachmentsInputSchema, ManageCapabilitiesInputSchema, ManageCollectionsInputSchema, ManageLinksInputSchema, ManageNoteInputSchema, ManageTagsInputSchema, MemoryBlobStore, MemoryRecordStore, MigrationRunner, NotesRepository, OpenAICompatibleProvider, PGliteStorageBackend, PGliteStorageBackendFactory, PGliteWorkerClient, PGliteWorkerStorageBackend, PGliteWorkerStorageBackendFactory, ProvenanceRepository, ProviderRegistry, RECORD_COLLECTIONS, RECORD_SCHEMA_VERSION, RECORD_STORE_CAPABILITIES, SHARD_FORMAT, SIGNATURE_ENTRY, SIGNING_ENVELOPE_VERSION, SUPPORTED_PGLITE_VERSION, SearchInputSchema, SearchRepository, SkosRepository, TagsRepository, TransactionProxy, TypedEventBus, VERSION, aiRevisionHandler, aiwgFortemiIndexFromKnowledgeShard, aiwgFortemiIndexToCommunityGraph, aiwgFortemiIndexToKnowledgeShard, allMigrations, appendPluginScript, assertAiwgFortemiChunkManifest, assertAiwgFortemiChunkPart, assertAiwgFortemiIndexExport, assertAiwgStaticEmbeddingSet, assertShardComponentRecord, buildAiwgChunkedIndex, buildAiwgStaticEmbeddingSet, buildNoteConditions, buildPluginCsp, captureKnowledge, chunkText, classifyError, classifyModel, clearPrefetchedShard, collectionFromShard, collectionToShard, computeBlobHash, computeHash, computeSri, conceptTaggingHandler, cosineSimilarity, createAiwgFetchChunkLoader, createAiwgFetchDetailLoader, createAiwgIndexController, createAiwgReviewDecisionExport, createBlobStore, createCosineSemanticProvider, createCspReportHandler, createFortemi, createLazyBlobStore, createLegacyProvider, createPGliteBackend, createPGliteInstance, createRecordBackend, createRecordStore, createRemoteBackend, createRoutes, createShardBackend, createShardCapabilityReport, createWorkerEmbedFunction, defaultStorageBackendFactory, detectCommunities, detectGpuCapabilities, detectInferenceCapabilities, discoverLocalProviders, dropAttachmentProjection, dropNoteProjection, dumpDbSnapshot, embeddingConfigToShard, embeddingFromShard, embeddingGenerationHandler, embeddingSetFromShard, embeddingSetMemberToShard, embeddingSetToShard, embeddingToShard, enqueueFullWorkflow, enqueueJob, enqueueNoteCreationJobs, estimateModelFit, estimateVramMB, estimateVramTier, exportShard, exportShardFromRecords, exportShardFromRecordsWithReport, exportShardWithReport, fetchAndValidateFortemiCompatibility, fetchPluginScript, filterAiwgRecordsByPrivacy, findAiwgStaticDuplicatePairs, formatFortemiCompatibilitySummary, fortemiCompatibilityUrl, fortemiManifest, fromPrefetched, generateId, getAiwgFortemiFacets, getAiwgFortemiIndexExportSchema, getEmbedFunction, getFortemiBridge, getFortemiSecretStore, getJobQueueStatus, getKnowledgeShardContractReceipt, getKnowledgeShardProfileRegistry, getKnowledgeShardSchema, getLlmFunction, getNote, getPrefetchedSha256, handleEmbedRequests, hasFortemiSecureSecrets, importShard, importShardToRecords, isPluginScriptAllowed, isShardPrefetched, isShardSigningSupported, linkFromShard, linkToShard, linkingHandler, listNotes, manageArchive, manageAttachments, manageCapabilities, manageCollections, manageLinks, manageNote, manageTags, matchRoute, migrateLegacyBlobStore, noteFromShard, noteSkosTagToShard, noteToShard, openShard, packTarGz, parseCspReport, prefetchShard, profileSupportError, projectAttachments, projectNotes, projectRecords, provenanceEdgeToShard, queryAiwgFortemiIndex, queryAiwgHybridIndex, queryAiwgSemanticIndex, registerLlmCapability, registerSemanticCapability, registerSemanticCapabilityWorker, registerServiceWorker, restoreDbSnapshot, searchTool, selectBackend, selectLlmModel, setEmbedFunction, setLlmFunction, sha256Hex, sidecarBlobDigests, signShard, skosConceptToShard, skosRelationToShard, skosSchemeToShard, suggestTags, tagsToShard, templateToShard, titleGenerationHandler, unpackTarGz, unregisterLlmCapability, unregisterSemanticCapability, urlLinkToShard, validateAiwgFortemiChunkManifest, validateAiwgFortemiChunkPart, validateAiwgFortemiIndexExport, validateAiwgFortemiIndexExportSchema, validateAiwgFortemiProjectedRecordSchema, validateAiwgStaticEmbeddingSet, validateChecksums, validateCoreV1ShardArchive, validateFortemiCompatibilityResponse, validateFullV1ShardArchive, validateRecordV1ShardArchive, validateShardArchive, validateShardComponentRecord, validateShardManifest, verifyDbSnapshotMeta, verifyShardSignature, verifySri };
22044
22124
  //# sourceMappingURL=index.js.map