@hasna/mementos 0.14.81 → 0.14.82
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/cli/commands/memory-cmd-crud.d.ts.map +1 -1
- package/dist/cli/commands/project.d.ts.map +1 -1
- package/dist/cli/index.js +547 -72
- package/dist/db/memory-project-link.d.ts.map +1 -1
- package/dist/db/projects.d.ts.map +1 -1
- package/dist/index.js +460 -81
- package/dist/project-registration/authority.d.ts.map +1 -1
- package/dist/project-registration/identity.d.ts +20 -0
- package/dist/project-registration/identity.d.ts.map +1 -0
- package/dist/project-registration/index.d.ts +5 -2
- package/dist/project-registration/index.d.ts.map +1 -1
- package/dist/project-registration/project-resources.d.ts +22 -0
- package/dist/project-registration/project-resources.d.ts.map +1 -0
- package/dist/project-registration/types.d.ts +52 -0
- package/dist/project-registration/types.d.ts.map +1 -1
- package/dist/project-registration.js +1488 -55
- package/dist/sdk/index.d.ts +57 -0
- package/dist/sdk/index.d.ts.map +1 -1
- package/dist/sdk/index.js +56 -0
- package/dist/server/index.js +644 -145
- package/dist/server/openapi.d.ts.map +1 -1
- package/dist/test-support/project-authority-identity.d.ts +8 -0
- package/dist/test-support/project-authority-identity.d.ts.map +1 -0
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -50488,6 +50488,98 @@ function getMementosPackageVersion() {
|
|
|
50488
50488
|
// src/db/memory-project-link.ts
|
|
50489
50489
|
init_schema();
|
|
50490
50490
|
|
|
50491
|
+
// src/project-registration/types.ts
|
|
50492
|
+
var MEMENTOS_PROJECT_REGISTRATION_ROUTE = "mementos.project-registration.v1";
|
|
50493
|
+
var MEMENTOS_PROJECT_REGISTRATION_CALLER_ROUTE = "projects.full-registration.v1";
|
|
50494
|
+
var MEMENTOS_PROJECT_REGISTRATION_SCHEMA_VERSION = 1;
|
|
50495
|
+
var MEMENTOS_PROJECT_GUARDED_UPDATE_ROUTE = "mementos.project-guarded-update.v1";
|
|
50496
|
+
var MEMENTOS_PROJECT_RESOURCE_ROUTE = "mementos.project-resources.v1";
|
|
50497
|
+
var MEMENTOS_PROJECT_RESOURCE_KINDS = [
|
|
50498
|
+
"project",
|
|
50499
|
+
"knowledge",
|
|
50500
|
+
"memory",
|
|
50501
|
+
"session"
|
|
50502
|
+
];
|
|
50503
|
+
|
|
50504
|
+
class MementosProjectRegistrationError extends Error {
|
|
50505
|
+
code;
|
|
50506
|
+
details;
|
|
50507
|
+
constructor(code, message, details = {}) {
|
|
50508
|
+
super(message);
|
|
50509
|
+
this.code = code;
|
|
50510
|
+
this.details = details;
|
|
50511
|
+
this.name = "MementosProjectRegistrationError";
|
|
50512
|
+
}
|
|
50513
|
+
}
|
|
50514
|
+
|
|
50515
|
+
// src/project-registration/identity.ts
|
|
50516
|
+
var MEMENTOS_PROJECT_AUTHORITY_ENV = {
|
|
50517
|
+
authorityId: "MEMENTOS_PROJECT_AUTHORITY_ID",
|
|
50518
|
+
tenantId: "MEMENTOS_PROJECT_TENANT_ID",
|
|
50519
|
+
corpusId: "MEMENTOS_PROJECT_CORPUS_ID"
|
|
50520
|
+
};
|
|
50521
|
+
function configuredValue(override, envKey) {
|
|
50522
|
+
return override?.trim() || process.env[envKey]?.trim() || null;
|
|
50523
|
+
}
|
|
50524
|
+
|
|
50525
|
+
class MementosProjectAuthorityIdentityError extends Error {
|
|
50526
|
+
missing_env;
|
|
50527
|
+
code = "MEMENTOS_PROJECT_AUTHORITY_UNCONFIGURED";
|
|
50528
|
+
constructor(missing_env) {
|
|
50529
|
+
super("Mementos project authority identity is not configured; set " + missing_env.join(", "));
|
|
50530
|
+
this.missing_env = missing_env;
|
|
50531
|
+
this.name = "MementosProjectAuthorityIdentityError";
|
|
50532
|
+
}
|
|
50533
|
+
}
|
|
50534
|
+
function resolveMementosProjectAuthorityIdentity(options = {}) {
|
|
50535
|
+
const authorityId = configuredValue(options.authorityId, MEMENTOS_PROJECT_AUTHORITY_ENV.authorityId);
|
|
50536
|
+
const tenantId = configuredValue(options.tenantId, MEMENTOS_PROJECT_AUTHORITY_ENV.tenantId);
|
|
50537
|
+
const corpusId = configuredValue(options.corpusId, MEMENTOS_PROJECT_AUTHORITY_ENV.corpusId);
|
|
50538
|
+
if (!authorityId || !tenantId || !corpusId) {
|
|
50539
|
+
const missingEnv = [];
|
|
50540
|
+
if (!authorityId)
|
|
50541
|
+
missingEnv.push(MEMENTOS_PROJECT_AUTHORITY_ENV.authorityId);
|
|
50542
|
+
if (!tenantId)
|
|
50543
|
+
missingEnv.push(MEMENTOS_PROJECT_AUTHORITY_ENV.tenantId);
|
|
50544
|
+
if (!corpusId)
|
|
50545
|
+
missingEnv.push(MEMENTOS_PROJECT_AUTHORITY_ENV.corpusId);
|
|
50546
|
+
throw new MementosProjectAuthorityIdentityError(missingEnv);
|
|
50547
|
+
}
|
|
50548
|
+
return {
|
|
50549
|
+
authority_id: authorityId,
|
|
50550
|
+
tenant_id: tenantId,
|
|
50551
|
+
corpus_id: corpusId
|
|
50552
|
+
};
|
|
50553
|
+
}
|
|
50554
|
+
function buildMementosProjectRegistrationCapability(options = {}) {
|
|
50555
|
+
const identity = resolveMementosProjectAuthorityIdentity(options);
|
|
50556
|
+
return {
|
|
50557
|
+
authority: "mementos",
|
|
50558
|
+
route: MEMENTOS_PROJECT_REGISTRATION_ROUTE,
|
|
50559
|
+
package_version: options.packageVersion ?? getMementosPackageVersion(),
|
|
50560
|
+
...identity,
|
|
50561
|
+
supported_resources: ["project"],
|
|
50562
|
+
conditional_create: true,
|
|
50563
|
+
immutable_receipts: true,
|
|
50564
|
+
exact_terminal_lookup: true,
|
|
50565
|
+
exact_readback: true,
|
|
50566
|
+
conditional_inverse: true,
|
|
50567
|
+
ambiguous_outcome_reconciliation: true,
|
|
50568
|
+
guarded_update: true,
|
|
50569
|
+
guarded_update_route: MEMENTOS_PROJECT_GUARDED_UPDATE_ROUTE,
|
|
50570
|
+
no_write_dry_run: true,
|
|
50571
|
+
expected_revision_compare_and_swap: true,
|
|
50572
|
+
caller_idempotency: true,
|
|
50573
|
+
exact_inverse_rollback: true,
|
|
50574
|
+
project_resource_enumeration: true,
|
|
50575
|
+
project_resource_route: MEMENTOS_PROJECT_RESOURCE_ROUTE,
|
|
50576
|
+
project_resource_kinds: ["project", "knowledge", "memory", "session"],
|
|
50577
|
+
stable_keyset_pagination: true,
|
|
50578
|
+
explicit_membership_only: true
|
|
50579
|
+
};
|
|
50580
|
+
}
|
|
50581
|
+
|
|
50582
|
+
// src/db/memory-project-link.ts
|
|
50491
50583
|
class MemoryProjectLinkError extends Error {
|
|
50492
50584
|
code;
|
|
50493
50585
|
details;
|
|
@@ -50498,12 +50590,17 @@ class MemoryProjectLinkError extends Error {
|
|
|
50498
50590
|
this.name = "MemoryProjectLinkError";
|
|
50499
50591
|
}
|
|
50500
50592
|
}
|
|
50501
|
-
var LINK_AUTHORITY = {
|
|
50502
|
-
authority_id: "mementos",
|
|
50503
|
-
tenant_id: "default",
|
|
50504
|
-
corpus_id: "default"
|
|
50505
|
-
};
|
|
50506
50593
|
var BOUNDED_IDENTIFIER = /^[A-Za-z0-9][A-Za-z0-9._:-]{7,127}$/;
|
|
50594
|
+
function linkAuthority() {
|
|
50595
|
+
try {
|
|
50596
|
+
return resolveMementosProjectAuthorityIdentity();
|
|
50597
|
+
} catch (error) {
|
|
50598
|
+
if (error instanceof MementosProjectAuthorityIdentityError) {
|
|
50599
|
+
throw new MemoryProjectLinkError("MEMORY_PROJECT_LINK_AUTHORITY_MISMATCH", error.message, { authority_code: error.code, missing_env: error.missing_env });
|
|
50600
|
+
}
|
|
50601
|
+
throw error;
|
|
50602
|
+
}
|
|
50603
|
+
}
|
|
50507
50604
|
function canonicalize(value) {
|
|
50508
50605
|
if (Array.isArray(value))
|
|
50509
50606
|
return value.map(canonicalize);
|
|
@@ -50611,7 +50708,8 @@ function receiptFromRow(row) {
|
|
|
50611
50708
|
};
|
|
50612
50709
|
}
|
|
50613
50710
|
function assertIdentity(identity) {
|
|
50614
|
-
|
|
50711
|
+
const expectedIdentity = linkAuthority();
|
|
50712
|
+
if (identity.authority_id !== expectedIdentity.authority_id || identity.tenant_id !== expectedIdentity.tenant_id || identity.corpus_id !== expectedIdentity.corpus_id) {
|
|
50615
50713
|
throw new MemoryProjectLinkError("MEMORY_PROJECT_LINK_AUTHORITY_MISMATCH", "memory project link does not match this authority, tenant, and corpus");
|
|
50616
50714
|
}
|
|
50617
50715
|
}
|
|
@@ -51088,7 +51186,7 @@ function rollbackMemoryProjectLink(memoryId, request, db) {
|
|
|
51088
51186
|
};
|
|
51089
51187
|
});
|
|
51090
51188
|
}
|
|
51091
|
-
function getMemoryProjectLinkReceipt(memoryId, receiptId, identity =
|
|
51189
|
+
function getMemoryProjectLinkReceipt(memoryId, receiptId, identity = linkAuthority(), db) {
|
|
51092
51190
|
assertIdentity(identity);
|
|
51093
51191
|
assertBoundedIdentifier(memoryId, "memory_id");
|
|
51094
51192
|
assertBoundedIdentifier(receiptId, "receipt_id");
|
|
@@ -51553,25 +51651,6 @@ function focusFilterSQL(agentId, projectId) {
|
|
|
51553
51651
|
init_database();
|
|
51554
51652
|
init_api_mode();
|
|
51555
51653
|
import { createHash as createHash2 } from "crypto";
|
|
51556
|
-
|
|
51557
|
-
// src/project-registration/types.ts
|
|
51558
|
-
var MEMENTOS_PROJECT_REGISTRATION_ROUTE = "mementos.project-registration.v1";
|
|
51559
|
-
var MEMENTOS_PROJECT_REGISTRATION_CALLER_ROUTE = "projects.full-registration.v1";
|
|
51560
|
-
var MEMENTOS_PROJECT_REGISTRATION_SCHEMA_VERSION = 1;
|
|
51561
|
-
var MEMENTOS_PROJECT_GUARDED_UPDATE_ROUTE = "mementos.project-guarded-update.v1";
|
|
51562
|
-
|
|
51563
|
-
class MementosProjectRegistrationError extends Error {
|
|
51564
|
-
code;
|
|
51565
|
-
details;
|
|
51566
|
-
constructor(code, message, details = {}) {
|
|
51567
|
-
super(message);
|
|
51568
|
-
this.code = code;
|
|
51569
|
-
this.details = details;
|
|
51570
|
-
this.name = "MementosProjectRegistrationError";
|
|
51571
|
-
}
|
|
51572
|
-
}
|
|
51573
|
-
|
|
51574
|
-
// src/db/projects.ts
|
|
51575
51654
|
function parseProjectRow2(row) {
|
|
51576
51655
|
return {
|
|
51577
51656
|
id: row["id"],
|
|
@@ -51605,12 +51684,17 @@ class ProjectGuardedUpdateError extends Error {
|
|
|
51605
51684
|
this.name = "ProjectGuardedUpdateError";
|
|
51606
51685
|
}
|
|
51607
51686
|
}
|
|
51608
|
-
var PROJECT_UPDATE_AUTHORITY = {
|
|
51609
|
-
authority_id: "mementos",
|
|
51610
|
-
tenant_id: "default",
|
|
51611
|
-
corpus_id: "default"
|
|
51612
|
-
};
|
|
51613
51687
|
var BOUNDED_IDENTIFIER2 = /^[A-Za-z0-9][A-Za-z0-9._:-]{7,127}$/;
|
|
51688
|
+
function projectUpdateAuthority() {
|
|
51689
|
+
try {
|
|
51690
|
+
return resolveMementosProjectAuthorityIdentity();
|
|
51691
|
+
} catch (error) {
|
|
51692
|
+
if (error instanceof MementosProjectAuthorityIdentityError) {
|
|
51693
|
+
throw new ProjectGuardedUpdateError("PROJECT_UPDATE_AUTHORITY_MISMATCH", error.message, { authority_code: error.code, missing_env: error.missing_env });
|
|
51694
|
+
}
|
|
51695
|
+
throw error;
|
|
51696
|
+
}
|
|
51697
|
+
}
|
|
51614
51698
|
function canonicalizeProjectUpdateValue(value) {
|
|
51615
51699
|
if (Array.isArray(value))
|
|
51616
51700
|
return value.map(canonicalizeProjectUpdateValue);
|
|
@@ -51683,7 +51767,7 @@ function normalizeProjectUpdateInput(input) {
|
|
|
51683
51767
|
}
|
|
51684
51768
|
return normalized;
|
|
51685
51769
|
}
|
|
51686
|
-
function assertProjectUpdateIdentity(identity, expectedIdentity =
|
|
51770
|
+
function assertProjectUpdateIdentity(identity, expectedIdentity = projectUpdateAuthority()) {
|
|
51687
51771
|
if (identity.authority_id !== expectedIdentity.authority_id || identity.tenant_id !== expectedIdentity.tenant_id || identity.corpus_id !== expectedIdentity.corpus_id) {
|
|
51688
51772
|
throw new ProjectGuardedUpdateError("PROJECT_UPDATE_AUTHORITY_MISMATCH", "guarded project update does not match this authority, tenant, and corpus");
|
|
51689
51773
|
}
|
|
@@ -51693,7 +51777,7 @@ function assertBoundedIdentifier2(value, field) {
|
|
|
51693
51777
|
throw new ProjectGuardedUpdateError("PROJECT_UPDATE_INVALID_INPUT", `${field} must be an 8-128 character bounded identifier`);
|
|
51694
51778
|
}
|
|
51695
51779
|
}
|
|
51696
|
-
function assertProjectUpdateRequest(request, expectedIdentity =
|
|
51780
|
+
function assertProjectUpdateRequest(request, expectedIdentity = projectUpdateAuthority()) {
|
|
51697
51781
|
assertProjectUpdateIdentity(request, expectedIdentity);
|
|
51698
51782
|
assertBoundedIdentifier2(request.operation_id, "operation_id");
|
|
51699
51783
|
assertBoundedIdentifier2(request.step_id, "step_id");
|
|
@@ -51871,7 +51955,7 @@ function listProjects(db) {
|
|
|
51871
51955
|
const rows = d.query("SELECT * FROM projects ORDER BY updated_at DESC").all();
|
|
51872
51956
|
return rows.map(parseProjectRow2);
|
|
51873
51957
|
}
|
|
51874
|
-
function previewProjectUpdate(id, request, db, expectedIdentity =
|
|
51958
|
+
function previewProjectUpdate(id, request, db, expectedIdentity = projectUpdateAuthority()) {
|
|
51875
51959
|
assertProjectUpdateRequest(request, expectedIdentity);
|
|
51876
51960
|
const normalized = normalizeProjectUpdateInput(request.updates);
|
|
51877
51961
|
if (!db && isApiMode()) {
|
|
@@ -51894,7 +51978,7 @@ function previewProjectUpdate(id, request, db, expectedIdentity = PROJECT_UPDATE
|
|
|
51894
51978
|
receipt: null
|
|
51895
51979
|
};
|
|
51896
51980
|
}
|
|
51897
|
-
function applyProjectUpdate(id, request, db, expectedIdentity =
|
|
51981
|
+
function applyProjectUpdate(id, request, db, expectedIdentity = projectUpdateAuthority(), resultDigestForProject) {
|
|
51898
51982
|
assertProjectUpdateRequest(request, expectedIdentity);
|
|
51899
51983
|
const normalized = normalizeProjectUpdateInput(request.updates);
|
|
51900
51984
|
if (!db && isApiMode()) {
|
|
@@ -51963,7 +52047,7 @@ function applyProjectUpdate(id, request, db, expectedIdentity = PROJECT_UPDATE_A
|
|
|
51963
52047
|
return { dry_run: false, applied: true, project: readback, receipt };
|
|
51964
52048
|
});
|
|
51965
52049
|
}
|
|
51966
|
-
function rollbackProjectUpdate(id, request, db, expectedIdentity =
|
|
52050
|
+
function rollbackProjectUpdate(id, request, db, expectedIdentity = projectUpdateAuthority(), resultDigestForProject) {
|
|
51967
52051
|
assertProjectUpdateRequest(request, expectedIdentity);
|
|
51968
52052
|
assertBoundedIdentifier2(request.accepted_receipt_id, "accepted_receipt_id");
|
|
51969
52053
|
if (!db && isApiMode()) {
|
|
@@ -52037,7 +52121,7 @@ function rollbackProjectUpdate(id, request, db, expectedIdentity = PROJECT_UPDAT
|
|
|
52037
52121
|
return { dry_run: false, applied: true, project: readback, receipt };
|
|
52038
52122
|
});
|
|
52039
52123
|
}
|
|
52040
|
-
function getProjectUpdateReceipt(id, receiptId, identity =
|
|
52124
|
+
function getProjectUpdateReceipt(id, receiptId, identity = projectUpdateAuthority(), db, expectedIdentity = projectUpdateAuthority()) {
|
|
52041
52125
|
assertProjectUpdateIdentity(identity, expectedIdentity);
|
|
52042
52126
|
if (!db && isApiMode()) {
|
|
52043
52127
|
const { data } = apiJson("POST", `/projects/${encodeURIComponent(id)}/update-receipts/lookup`, { ...identity, receipt_id: receiptId });
|
|
@@ -52679,27 +52763,7 @@ class PackageOwnedMementosProjectRegistrationAuthority {
|
|
|
52679
52763
|
this.db = db;
|
|
52680
52764
|
this.now = options.now ?? (() => new Date().toISOString());
|
|
52681
52765
|
this.faultInjector = options.faultInjector;
|
|
52682
|
-
this.capabilityValue =
|
|
52683
|
-
authority: "mementos",
|
|
52684
|
-
route: MEMENTOS_PROJECT_REGISTRATION_ROUTE,
|
|
52685
|
-
package_version: options.packageVersion ?? getMementosPackageVersion(),
|
|
52686
|
-
authority_id: options.authorityId ?? "mementos",
|
|
52687
|
-
tenant_id: options.tenantId ?? "default",
|
|
52688
|
-
corpus_id: options.corpusId ?? "default",
|
|
52689
|
-
supported_resources: ["project"],
|
|
52690
|
-
conditional_create: true,
|
|
52691
|
-
immutable_receipts: true,
|
|
52692
|
-
exact_terminal_lookup: true,
|
|
52693
|
-
exact_readback: true,
|
|
52694
|
-
conditional_inverse: true,
|
|
52695
|
-
ambiguous_outcome_reconciliation: true,
|
|
52696
|
-
guarded_update: true,
|
|
52697
|
-
guarded_update_route: MEMENTOS_PROJECT_GUARDED_UPDATE_ROUTE,
|
|
52698
|
-
no_write_dry_run: true,
|
|
52699
|
-
expected_revision_compare_and_swap: true,
|
|
52700
|
-
caller_idempotency: true,
|
|
52701
|
-
exact_inverse_rollback: true
|
|
52702
|
-
};
|
|
52766
|
+
this.capabilityValue = buildMementosProjectRegistrationCapability(options);
|
|
52703
52767
|
}
|
|
52704
52768
|
fault(point, request) {
|
|
52705
52769
|
this.faultInjector?.(point, {
|
|
@@ -53395,6 +53459,311 @@ class MementosProjectRegistrationHttpClient {
|
|
|
53395
53459
|
function createMementosProjectRegistrationHttpClient(options) {
|
|
53396
53460
|
return new MementosProjectRegistrationHttpClient(options);
|
|
53397
53461
|
}
|
|
53462
|
+
// src/project-registration/project-resources.ts
|
|
53463
|
+
init_api_mode();
|
|
53464
|
+
init_database();
|
|
53465
|
+
var DEFAULT_PAGE_LIMIT = 100;
|
|
53466
|
+
var MAX_PAGE_LIMIT = 1000;
|
|
53467
|
+
var CURSOR_SCHEMA = "mementos.project-resources.cursor.v1";
|
|
53468
|
+
|
|
53469
|
+
class MementosProjectResourceError extends Error {
|
|
53470
|
+
code;
|
|
53471
|
+
details;
|
|
53472
|
+
constructor(code, message, details = {}) {
|
|
53473
|
+
super(message);
|
|
53474
|
+
this.code = code;
|
|
53475
|
+
this.details = details;
|
|
53476
|
+
this.name = "MementosProjectResourceError";
|
|
53477
|
+
}
|
|
53478
|
+
}
|
|
53479
|
+
function timestamp(value) {
|
|
53480
|
+
return value instanceof Date ? value.toISOString() : String(value);
|
|
53481
|
+
}
|
|
53482
|
+
function normalizeSqlValue(value) {
|
|
53483
|
+
if (value instanceof Date)
|
|
53484
|
+
return value.toISOString();
|
|
53485
|
+
if (Array.isArray(value))
|
|
53486
|
+
return value.map(normalizeSqlValue);
|
|
53487
|
+
if (!value || typeof value !== "object")
|
|
53488
|
+
return value;
|
|
53489
|
+
return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, normalizeSqlValue(item)]));
|
|
53490
|
+
}
|
|
53491
|
+
function exactProject(db, projectId) {
|
|
53492
|
+
const row = db.get("SELECT id, name, path, description, memory_prefix, created_at, updated_at FROM projects WHERE id = ? LIMIT 1", projectId);
|
|
53493
|
+
if (!row) {
|
|
53494
|
+
throw new MementosProjectResourceError("MEMENTOS_PROJECT_RESOURCE_PROJECT_NOT_FOUND", `Mementos project not found: ${projectId}`, { project_id: projectId });
|
|
53495
|
+
}
|
|
53496
|
+
return row;
|
|
53497
|
+
}
|
|
53498
|
+
function resourceKey(resource) {
|
|
53499
|
+
const rank = MEMENTOS_PROJECT_RESOURCE_KINDS.indexOf(resource.resource_kind);
|
|
53500
|
+
return `${String(rank).padStart(2, "0")}:${resource.stable_id}`;
|
|
53501
|
+
}
|
|
53502
|
+
function projectResource(project) {
|
|
53503
|
+
const normalized = normalizeSqlValue(project);
|
|
53504
|
+
return {
|
|
53505
|
+
authority: "mementos",
|
|
53506
|
+
source_package: "@hasna/mementos",
|
|
53507
|
+
project_id: project.id,
|
|
53508
|
+
resource_kind: "project",
|
|
53509
|
+
stable_id: project.id,
|
|
53510
|
+
revision: timestamp(project.updated_at),
|
|
53511
|
+
digest: digestMementosProjectRegistrationValue(normalized),
|
|
53512
|
+
membership: "project_aggregate"
|
|
53513
|
+
};
|
|
53514
|
+
}
|
|
53515
|
+
function memoryResources(db, projectId) {
|
|
53516
|
+
const rows = db.all("SELECT * FROM memories WHERE project_id = ? ORDER BY id ASC", projectId);
|
|
53517
|
+
return rows.map((row) => {
|
|
53518
|
+
const memory = normalizeSqlValue(parseMemoryRow(row));
|
|
53519
|
+
return {
|
|
53520
|
+
authority: "mementos",
|
|
53521
|
+
source_package: "@hasna/mementos",
|
|
53522
|
+
project_id: projectId,
|
|
53523
|
+
resource_kind: row["category"] === "knowledge" ? "knowledge" : "memory",
|
|
53524
|
+
stable_id: String(row["id"]),
|
|
53525
|
+
revision: timestamp(row["updated_at"]),
|
|
53526
|
+
digest: digestMementosProjectRegistrationValue(memory),
|
|
53527
|
+
membership: "explicit_project_id_or_focus"
|
|
53528
|
+
};
|
|
53529
|
+
});
|
|
53530
|
+
}
|
|
53531
|
+
function sessionResources(db, projectId) {
|
|
53532
|
+
const rows = db.all("SELECT * FROM session_memory_jobs WHERE project_id = ? ORDER BY id ASC", projectId);
|
|
53533
|
+
return rows.map((row) => {
|
|
53534
|
+
const normalized = {
|
|
53535
|
+
id: String(row["id"]),
|
|
53536
|
+
session_id: String(row["session_id"]),
|
|
53537
|
+
agent_id: row["agent_id"] === null ? null : String(row["agent_id"] ?? "") || null,
|
|
53538
|
+
project_id: row["project_id"] === null ? null : String(row["project_id"] ?? "") || null,
|
|
53539
|
+
source: String(row["source"]),
|
|
53540
|
+
status: String(row["status"]),
|
|
53541
|
+
transcript: String(row["transcript"]),
|
|
53542
|
+
chunk_count: Number(row["chunk_count"]),
|
|
53543
|
+
memories_extracted: Number(row["memories_extracted"]),
|
|
53544
|
+
error: row["error"] === null ? null : String(row["error"] ?? "") || null,
|
|
53545
|
+
metadata: typeof row["metadata"] === "string" ? JSON.parse(row["metadata"] || "{}") : normalizeSqlValue(row["metadata"] ?? {}),
|
|
53546
|
+
created_at: timestamp(row["created_at"]),
|
|
53547
|
+
started_at: row["started_at"] === null ? null : timestamp(row["started_at"]),
|
|
53548
|
+
completed_at: row["completed_at"] === null ? null : timestamp(row["completed_at"])
|
|
53549
|
+
};
|
|
53550
|
+
return {
|
|
53551
|
+
authority: "mementos",
|
|
53552
|
+
source_package: "@hasna/mementos",
|
|
53553
|
+
project_id: projectId,
|
|
53554
|
+
resource_kind: "session",
|
|
53555
|
+
stable_id: String(row["id"]),
|
|
53556
|
+
revision: timestamp(row["completed_at"] ?? row["started_at"] ?? row["created_at"]),
|
|
53557
|
+
digest: digestMementosProjectRegistrationValue(normalized),
|
|
53558
|
+
membership: "explicit_project_id_or_focus"
|
|
53559
|
+
};
|
|
53560
|
+
});
|
|
53561
|
+
}
|
|
53562
|
+
function normalizeResourceKinds(value) {
|
|
53563
|
+
if (!value)
|
|
53564
|
+
return [...MEMENTOS_PROJECT_RESOURCE_KINDS];
|
|
53565
|
+
if (value.length === 0) {
|
|
53566
|
+
throw new MementosProjectResourceError("MEMENTOS_PROJECT_RESOURCE_INVALID_INPUT", "resource_kinds must contain at least one supported resource kind");
|
|
53567
|
+
}
|
|
53568
|
+
const requested = new Set(value);
|
|
53569
|
+
for (const kind of requested) {
|
|
53570
|
+
if (!MEMENTOS_PROJECT_RESOURCE_KINDS.includes(kind)) {
|
|
53571
|
+
throw new MementosProjectResourceError("MEMENTOS_PROJECT_RESOURCE_INVALID_INPUT", `Unsupported Mementos project resource kind: ${kind}`);
|
|
53572
|
+
}
|
|
53573
|
+
}
|
|
53574
|
+
return MEMENTOS_PROJECT_RESOURCE_KINDS.filter((kind) => requested.has(kind));
|
|
53575
|
+
}
|
|
53576
|
+
function normalizeLimit(value) {
|
|
53577
|
+
const limit = value ?? DEFAULT_PAGE_LIMIT;
|
|
53578
|
+
if (!Number.isSafeInteger(limit) || limit < 1 || limit > MAX_PAGE_LIMIT) {
|
|
53579
|
+
throw new MementosProjectResourceError("MEMENTOS_PROJECT_RESOURCE_INVALID_INPUT", `limit must be an integer between 1 and ${MAX_PAGE_LIMIT}`);
|
|
53580
|
+
}
|
|
53581
|
+
return limit;
|
|
53582
|
+
}
|
|
53583
|
+
function encodeCursor(cursor) {
|
|
53584
|
+
return Buffer.from(JSON.stringify(cursor), "utf8").toString("base64url");
|
|
53585
|
+
}
|
|
53586
|
+
function decodeCursor(raw) {
|
|
53587
|
+
try {
|
|
53588
|
+
const parsed = JSON.parse(Buffer.from(raw, "base64url").toString("utf8"));
|
|
53589
|
+
if (parsed.schema !== CURSOR_SCHEMA || typeof parsed.project_id !== "string" || typeof parsed.collection_revision !== "string" || !Array.isArray(parsed.resource_kinds) || typeof parsed.after_key !== "string") {
|
|
53590
|
+
throw new Error("invalid cursor shape");
|
|
53591
|
+
}
|
|
53592
|
+
return parsed;
|
|
53593
|
+
} catch {
|
|
53594
|
+
throw new MementosProjectResourceError("MEMENTOS_PROJECT_RESOURCE_INVALID_INPUT", "cursor is not a valid Mementos project-resource cursor");
|
|
53595
|
+
}
|
|
53596
|
+
}
|
|
53597
|
+
function localPopulation(projectId, db, resourceKinds) {
|
|
53598
|
+
const project = exactProject(db, projectId);
|
|
53599
|
+
const selected = new Set(resourceKinds);
|
|
53600
|
+
const resources = [
|
|
53601
|
+
...selected.has("project") ? [projectResource(project)] : [],
|
|
53602
|
+
...memoryResources(db, projectId).filter((resource) => selected.has(resource.resource_kind)),
|
|
53603
|
+
...selected.has("session") ? sessionResources(db, projectId) : []
|
|
53604
|
+
].sort((left, right) => resourceKey(left).localeCompare(resourceKey(right)));
|
|
53605
|
+
const collectionRevision = digestMementosProjectRegistrationValue({
|
|
53606
|
+
schema: MEMENTOS_PROJECT_RESOURCE_ROUTE,
|
|
53607
|
+
project_id: projectId,
|
|
53608
|
+
project_revision: timestamp(project.updated_at),
|
|
53609
|
+
resource_kinds: resourceKinds,
|
|
53610
|
+
resources: resources.map((resource) => ({
|
|
53611
|
+
resource_kind: resource.resource_kind,
|
|
53612
|
+
stable_id: resource.stable_id,
|
|
53613
|
+
revision: resource.revision,
|
|
53614
|
+
digest: resource.digest
|
|
53615
|
+
}))
|
|
53616
|
+
});
|
|
53617
|
+
return { project, resources, collectionRevision };
|
|
53618
|
+
}
|
|
53619
|
+
function readMementosProjectResourcePage(projectId, options = {}, db, authorityOptions = {}) {
|
|
53620
|
+
const resourceKinds = normalizeResourceKinds(options.resource_kinds);
|
|
53621
|
+
const limit = normalizeLimit(options.limit);
|
|
53622
|
+
if (!db && isApiMode()) {
|
|
53623
|
+
const { data } = apiJson("GET", `/projects/${encodeURIComponent(projectId)}/resources${toQuery({
|
|
53624
|
+
limit,
|
|
53625
|
+
cursor: options.cursor ?? undefined,
|
|
53626
|
+
resource_kinds: resourceKinds.join(",")
|
|
53627
|
+
})}`);
|
|
53628
|
+
return data;
|
|
53629
|
+
}
|
|
53630
|
+
const d = db ?? getDatabase();
|
|
53631
|
+
const { project, resources, collectionRevision } = localPopulation(projectId, d, resourceKinds);
|
|
53632
|
+
let start = 0;
|
|
53633
|
+
if (options.cursor) {
|
|
53634
|
+
const cursor = decodeCursor(options.cursor);
|
|
53635
|
+
if (cursor.project_id !== projectId || JSON.stringify(cursor.resource_kinds) !== JSON.stringify(resourceKinds)) {
|
|
53636
|
+
throw new MementosProjectResourceError("MEMENTOS_PROJECT_RESOURCE_INVALID_INPUT", "cursor does not belong to this project and resource-kind selection");
|
|
53637
|
+
}
|
|
53638
|
+
if (cursor.collection_revision !== collectionRevision) {
|
|
53639
|
+
throw new MementosProjectResourceError("MEMENTOS_PROJECT_RESOURCE_COLLECTION_CHANGED", "Mementos project resource collection changed; restart from the first page", {
|
|
53640
|
+
cursor_collection_revision: cursor.collection_revision,
|
|
53641
|
+
current_collection_revision: collectionRevision
|
|
53642
|
+
});
|
|
53643
|
+
}
|
|
53644
|
+
const afterIndex = resources.findIndex((resource) => resourceKey(resource) === cursor.after_key);
|
|
53645
|
+
if (afterIndex < 0) {
|
|
53646
|
+
throw new MementosProjectResourceError("MEMENTOS_PROJECT_RESOURCE_COLLECTION_CHANGED", "Mementos project resource cursor no longer names a member; restart from the first page");
|
|
53647
|
+
}
|
|
53648
|
+
start = afterIndex + 1;
|
|
53649
|
+
}
|
|
53650
|
+
const pageResources = resources.slice(start, start + limit);
|
|
53651
|
+
const hasMore = start + pageResources.length < resources.length;
|
|
53652
|
+
const nextCursor = hasMore && pageResources.length > 0 ? encodeCursor({
|
|
53653
|
+
schema: CURSOR_SCHEMA,
|
|
53654
|
+
project_id: projectId,
|
|
53655
|
+
collection_revision: collectionRevision,
|
|
53656
|
+
resource_kinds: resourceKinds,
|
|
53657
|
+
after_key: resourceKey(pageResources[pageResources.length - 1])
|
|
53658
|
+
}) : null;
|
|
53659
|
+
const capability = buildMementosProjectRegistrationCapability(authorityOptions);
|
|
53660
|
+
return {
|
|
53661
|
+
schema: "mementos.project-resources.v1",
|
|
53662
|
+
authority: {
|
|
53663
|
+
authority: capability.authority,
|
|
53664
|
+
authority_id: capability.authority_id,
|
|
53665
|
+
tenant_id: capability.tenant_id,
|
|
53666
|
+
corpus_id: capability.corpus_id,
|
|
53667
|
+
package_version: capability.package_version
|
|
53668
|
+
},
|
|
53669
|
+
project_id: projectId,
|
|
53670
|
+
project_revision: timestamp(project.updated_at),
|
|
53671
|
+
collection_revision: collectionRevision,
|
|
53672
|
+
resource_kinds: resourceKinds,
|
|
53673
|
+
resources: pageResources,
|
|
53674
|
+
count: pageResources.length,
|
|
53675
|
+
total: resources.length,
|
|
53676
|
+
limit,
|
|
53677
|
+
cursor: options.cursor ?? null,
|
|
53678
|
+
next_cursor: nextCursor,
|
|
53679
|
+
has_more: hasMore,
|
|
53680
|
+
complete: true,
|
|
53681
|
+
truncated: false
|
|
53682
|
+
};
|
|
53683
|
+
}
|
|
53684
|
+
function readAllMementosProjectResources(projectId, options = {}, db, authorityOptions = {}) {
|
|
53685
|
+
const pageSize = normalizeLimit(options.page_size);
|
|
53686
|
+
let cursor = null;
|
|
53687
|
+
let first = null;
|
|
53688
|
+
const resources = [];
|
|
53689
|
+
const seen = new Set;
|
|
53690
|
+
do {
|
|
53691
|
+
const page = readMementosProjectResourcePage(projectId, {
|
|
53692
|
+
limit: pageSize,
|
|
53693
|
+
cursor,
|
|
53694
|
+
resource_kinds: options.resource_kinds
|
|
53695
|
+
}, db, authorityOptions);
|
|
53696
|
+
if (!first)
|
|
53697
|
+
first = page;
|
|
53698
|
+
if (page.collection_revision !== first.collection_revision || page.total !== first.total || JSON.stringify(page.resource_kinds) !== JSON.stringify(first.resource_kinds)) {
|
|
53699
|
+
throw new MementosProjectResourceError("MEMENTOS_PROJECT_RESOURCE_COLLECTION_CHANGED", "Mementos project resource collection changed during complete traversal");
|
|
53700
|
+
}
|
|
53701
|
+
for (const resource of page.resources) {
|
|
53702
|
+
const key = resourceKey(resource);
|
|
53703
|
+
if (seen.has(key)) {
|
|
53704
|
+
throw new MementosProjectResourceError("MEMENTOS_PROJECT_RESOURCE_INCOMPLETE", `Mementos project resource traversal returned duplicate stable ID: ${key}`);
|
|
53705
|
+
}
|
|
53706
|
+
seen.add(key);
|
|
53707
|
+
resources.push(resource);
|
|
53708
|
+
}
|
|
53709
|
+
if (page.has_more && !page.next_cursor) {
|
|
53710
|
+
throw new MementosProjectResourceError("MEMENTOS_PROJECT_RESOURCE_INCOMPLETE", "Mementos project resource page claimed more results without a continuation cursor");
|
|
53711
|
+
}
|
|
53712
|
+
cursor = page.next_cursor;
|
|
53713
|
+
} while (cursor);
|
|
53714
|
+
if (!first) {
|
|
53715
|
+
throw new MementosProjectResourceError("MEMENTOS_PROJECT_RESOURCE_INCOMPLETE", "Mementos project resource traversal returned no first page");
|
|
53716
|
+
}
|
|
53717
|
+
if (resources.length !== first.total) {
|
|
53718
|
+
throw new MementosProjectResourceError("MEMENTOS_PROJECT_RESOURCE_INCOMPLETE", `Mementos project resource traversal returned ${resources.length} of ${first.total} resources`);
|
|
53719
|
+
}
|
|
53720
|
+
return {
|
|
53721
|
+
...first,
|
|
53722
|
+
resources,
|
|
53723
|
+
count: resources.length,
|
|
53724
|
+
total: resources.length,
|
|
53725
|
+
limit: pageSize,
|
|
53726
|
+
cursor: null,
|
|
53727
|
+
next_cursor: null,
|
|
53728
|
+
has_more: false,
|
|
53729
|
+
complete: true,
|
|
53730
|
+
truncated: false
|
|
53731
|
+
};
|
|
53732
|
+
}
|
|
53733
|
+
function getMementosProjectResourceExact(projectId, resourceKind, stableId, db, authorityOptions = {}) {
|
|
53734
|
+
if (!MEMENTOS_PROJECT_RESOURCE_KINDS.includes(resourceKind)) {
|
|
53735
|
+
throw new MementosProjectResourceError("MEMENTOS_PROJECT_RESOURCE_INVALID_INPUT", `Unsupported Mementos project resource kind: ${resourceKind}`);
|
|
53736
|
+
}
|
|
53737
|
+
if (!db && isApiMode()) {
|
|
53738
|
+
const { data } = apiJson("GET", `/projects/${encodeURIComponent(projectId)}/resources/${encodeURIComponent(resourceKind)}/${encodeURIComponent(stableId)}`);
|
|
53739
|
+
return data;
|
|
53740
|
+
}
|
|
53741
|
+
const d = db ?? getDatabase();
|
|
53742
|
+
const { project, resources, collectionRevision } = localPopulation(projectId, d, [
|
|
53743
|
+
resourceKind
|
|
53744
|
+
]);
|
|
53745
|
+
const resource = resources.find((candidate) => candidate.stable_id === stableId);
|
|
53746
|
+
if (!resource) {
|
|
53747
|
+
throw new MementosProjectResourceError("MEMENTOS_PROJECT_RESOURCE_NOT_FOUND", `Mementos ${resourceKind} resource not found in project ${projectId}: ${stableId}`, { project_id: projectId, resource_kind: resourceKind, stable_id: stableId });
|
|
53748
|
+
}
|
|
53749
|
+
const capability = buildMementosProjectRegistrationCapability(authorityOptions);
|
|
53750
|
+
return {
|
|
53751
|
+
schema: "mementos.project-resource.v1",
|
|
53752
|
+
authority: {
|
|
53753
|
+
authority: capability.authority,
|
|
53754
|
+
authority_id: capability.authority_id,
|
|
53755
|
+
tenant_id: capability.tenant_id,
|
|
53756
|
+
corpus_id: capability.corpus_id,
|
|
53757
|
+
package_version: capability.package_version
|
|
53758
|
+
},
|
|
53759
|
+
project_id: projectId,
|
|
53760
|
+
project_revision: timestamp(project.updated_at),
|
|
53761
|
+
collection_revision: collectionRevision,
|
|
53762
|
+
resource,
|
|
53763
|
+
complete: true,
|
|
53764
|
+
truncated: false
|
|
53765
|
+
};
|
|
53766
|
+
}
|
|
53398
53767
|
// src/db/machines.ts
|
|
53399
53768
|
init_database();
|
|
53400
53769
|
import { hostname, platform } from "os";
|
|
@@ -53519,13 +53888,13 @@ function createEntity(input, db) {
|
|
|
53519
53888
|
return data;
|
|
53520
53889
|
}
|
|
53521
53890
|
const d = db || getDatabase();
|
|
53522
|
-
const
|
|
53891
|
+
const timestamp2 = now();
|
|
53523
53892
|
const metadataJson = JSON.stringify(input.metadata || {});
|
|
53524
53893
|
const existing = d.query(`SELECT * FROM entities
|
|
53525
53894
|
WHERE name = ? AND type = ? AND COALESCE(project_id, '') = ?`).get(input.name, input.type, input.project_id || "");
|
|
53526
53895
|
if (existing) {
|
|
53527
53896
|
const sets = ["updated_at = ?"];
|
|
53528
|
-
const params = [
|
|
53897
|
+
const params = [timestamp2];
|
|
53529
53898
|
if (input.description !== undefined) {
|
|
53530
53899
|
sets.push("description = ?");
|
|
53531
53900
|
params.push(input.description);
|
|
@@ -53548,8 +53917,8 @@ function createEntity(input, db) {
|
|
|
53548
53917
|
input.description || null,
|
|
53549
53918
|
metadataJson,
|
|
53550
53919
|
input.project_id || null,
|
|
53551
|
-
|
|
53552
|
-
|
|
53920
|
+
timestamp2,
|
|
53921
|
+
timestamp2
|
|
53553
53922
|
]);
|
|
53554
53923
|
hookRegistry.runHooks("PostEntityCreate", {
|
|
53555
53924
|
entityId: id,
|
|
@@ -54377,7 +54746,7 @@ function memoryResource(memory) {
|
|
|
54377
54746
|
tags: memory.tags
|
|
54378
54747
|
};
|
|
54379
54748
|
}
|
|
54380
|
-
function
|
|
54749
|
+
function projectResource2(projectId, name, externalId) {
|
|
54381
54750
|
return {
|
|
54382
54751
|
kind: "project",
|
|
54383
54752
|
id: projectId,
|
|
@@ -54483,7 +54852,7 @@ function createMementosProjectPanel(projectRef, options = {}) {
|
|
|
54483
54852
|
actionResource("mementos:save", "Save project memory")
|
|
54484
54853
|
],
|
|
54485
54854
|
resourceRefs: [
|
|
54486
|
-
|
|
54855
|
+
projectResource2(projectId, project?.name ?? projectRef, project?.id ?? projectRef),
|
|
54487
54856
|
...memories.slice(0, limit).map(memoryResource)
|
|
54488
54857
|
],
|
|
54489
54858
|
renderFragment: {
|
|
@@ -55085,29 +55454,29 @@ function enforceQuotas(config, db) {
|
|
|
55085
55454
|
}
|
|
55086
55455
|
function archiveStale(staleDays, db) {
|
|
55087
55456
|
const d = db || getDatabase();
|
|
55088
|
-
const
|
|
55457
|
+
const timestamp2 = now();
|
|
55089
55458
|
const cutoff = new Date(Date.now() - staleDays * 24 * 60 * 60 * 1000).toISOString();
|
|
55090
55459
|
const archiveWhere = `status = 'active' AND pinned = 0 AND COALESCE(accessed_at, created_at) < ?`;
|
|
55091
55460
|
const count = d.query(`SELECT COUNT(*) as c FROM memories WHERE ${archiveWhere}`).get(cutoff).c;
|
|
55092
55461
|
if (count > 0) {
|
|
55093
|
-
d.run(`UPDATE memories SET status = 'archived', updated_at = ? WHERE ${archiveWhere}`, [
|
|
55462
|
+
d.run(`UPDATE memories SET status = 'archived', updated_at = ? WHERE ${archiveWhere}`, [timestamp2, cutoff]);
|
|
55094
55463
|
}
|
|
55095
55464
|
return count;
|
|
55096
55465
|
}
|
|
55097
55466
|
function archiveUnused(days, db) {
|
|
55098
55467
|
const d = db || getDatabase();
|
|
55099
|
-
const
|
|
55468
|
+
const timestamp2 = now();
|
|
55100
55469
|
const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString();
|
|
55101
55470
|
const unusedWhere = `status = 'active' AND pinned = 0 AND access_count = 0 AND created_at < ?`;
|
|
55102
55471
|
const count = d.query(`SELECT COUNT(*) as c FROM memories WHERE ${unusedWhere}`).get(cutoff).c;
|
|
55103
55472
|
if (count > 0) {
|
|
55104
|
-
d.run(`UPDATE memories SET status = 'archived', updated_at = ? WHERE ${unusedWhere}`, [
|
|
55473
|
+
d.run(`UPDATE memories SET status = 'archived', updated_at = ? WHERE ${unusedWhere}`, [timestamp2, cutoff]);
|
|
55105
55474
|
}
|
|
55106
55475
|
return count;
|
|
55107
55476
|
}
|
|
55108
55477
|
function deprioritizeStale(days, db) {
|
|
55109
55478
|
const d = db || getDatabase();
|
|
55110
|
-
const
|
|
55479
|
+
const timestamp2 = now();
|
|
55111
55480
|
const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString();
|
|
55112
55481
|
const deprioWhere = `status = 'active' AND pinned = 0 AND importance > 1 AND COALESCE(accessed_at, updated_at) < ?`;
|
|
55113
55482
|
const count = d.query(`SELECT COUNT(*) as c FROM memories WHERE ${deprioWhere}`).get(cutoff).c;
|
|
@@ -55116,7 +55485,7 @@ function deprioritizeStale(days, db) {
|
|
|
55116
55485
|
SET importance = importance - 1,
|
|
55117
55486
|
version = version + 1,
|
|
55118
55487
|
updated_at = ?
|
|
55119
|
-
WHERE ${deprioWhere}`, [
|
|
55488
|
+
WHERE ${deprioWhere}`, [timestamp2, cutoff]);
|
|
55120
55489
|
}
|
|
55121
55490
|
return count;
|
|
55122
55491
|
}
|
|
@@ -55140,9 +55509,9 @@ function getAgentSyncDir(agentName) {
|
|
|
55140
55509
|
}
|
|
55141
55510
|
return dir;
|
|
55142
55511
|
}
|
|
55143
|
-
function setHighWaterMark(agentDir,
|
|
55512
|
+
function setHighWaterMark(agentDir, timestamp2) {
|
|
55144
55513
|
const markFile = join6(agentDir, ".highwatermark");
|
|
55145
|
-
writeFileSync4(markFile,
|
|
55514
|
+
writeFileSync4(markFile, timestamp2, "utf-8");
|
|
55146
55515
|
}
|
|
55147
55516
|
function resolveConflict(local, remote, resolution) {
|
|
55148
55517
|
switch (resolution) {
|
|
@@ -55462,13 +55831,13 @@ function buildConflictKey(key, sourceMachine, updatedAt) {
|
|
|
55462
55831
|
return `${key}__conflict__${machineSegment}__${timestampSegment || "0"}`;
|
|
55463
55832
|
}
|
|
55464
55833
|
function buildConflictClone(loser, sourceMachine, winnerId) {
|
|
55465
|
-
const
|
|
55834
|
+
const timestamp2 = new Date().toISOString();
|
|
55466
55835
|
const tags = new Set(ensureArrayValue(loser["tags"]));
|
|
55467
55836
|
tags.add("sync-conflict");
|
|
55468
55837
|
tags.add(`source_machine:${sourceMachine}`);
|
|
55469
55838
|
const metadata = ensureObjectValue(loser["metadata"]);
|
|
55470
55839
|
metadata["sync_conflict"] = true;
|
|
55471
|
-
metadata["conflict_detected_at"] =
|
|
55840
|
+
metadata["conflict_detected_at"] = timestamp2;
|
|
55472
55841
|
metadata["conflict_original_id"] = loser["id"];
|
|
55473
55842
|
metadata["conflict_winner_id"] = winnerId;
|
|
55474
55843
|
metadata["conflict_source_machine"] = sourceMachine;
|
|
@@ -55480,10 +55849,10 @@ function buildConflictClone(loser, sourceMachine, winnerId) {
|
|
|
55480
55849
|
metadata: JSON.stringify(metadata),
|
|
55481
55850
|
access_count: 0,
|
|
55482
55851
|
version: 1,
|
|
55483
|
-
created_at:
|
|
55484
|
-
updated_at:
|
|
55852
|
+
created_at: timestamp2,
|
|
55853
|
+
updated_at: timestamp2,
|
|
55485
55854
|
..."accessed_at" in loser ? { accessed_at: null } : {},
|
|
55486
|
-
..."ingested_at" in loser ? { ingested_at:
|
|
55855
|
+
..."ingested_at" in loser ? { ingested_at: timestamp2 } : {}
|
|
55487
55856
|
}, sourceMachine);
|
|
55488
55857
|
}
|
|
55489
55858
|
function insertConflictCloneIfMissing(db, clone) {
|
|
@@ -55733,13 +56102,13 @@ function createRelation(input, db) {
|
|
|
55733
56102
|
}
|
|
55734
56103
|
const d = db || getDatabase();
|
|
55735
56104
|
const id = shortUuid();
|
|
55736
|
-
const
|
|
56105
|
+
const timestamp2 = now();
|
|
55737
56106
|
const weight = input.weight ?? 1;
|
|
55738
56107
|
const metadata = JSON.stringify(input.metadata ?? {});
|
|
55739
56108
|
d.run(`INSERT INTO relations (id, source_entity_id, target_entity_id, relation_type, weight, metadata, created_at)
|
|
55740
56109
|
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
55741
56110
|
ON CONFLICT(source_entity_id, target_entity_id, relation_type)
|
|
55742
|
-
DO UPDATE SET weight = excluded.weight, metadata = excluded.metadata`, [id, input.source_entity_id, input.target_entity_id, input.relation_type, weight, metadata,
|
|
56111
|
+
DO UPDATE SET weight = excluded.weight, metadata = excluded.metadata`, [id, input.source_entity_id, input.target_entity_id, input.relation_type, weight, metadata, timestamp2]);
|
|
55743
56112
|
const row = d.query(`SELECT * FROM relations
|
|
55744
56113
|
WHERE source_entity_id = ? AND target_entity_id = ? AND relation_type = ?`).get(input.source_entity_id, input.target_entity_id, input.relation_type);
|
|
55745
56114
|
const relation = parseRelationRow(row);
|
|
@@ -55916,7 +56285,7 @@ function parseMemoryLink(row) {
|
|
|
55916
56285
|
function createMemoryLink(input, db) {
|
|
55917
56286
|
const d = db || getDatabase();
|
|
55918
56287
|
const id = shortUuid();
|
|
55919
|
-
const
|
|
56288
|
+
const timestamp2 = now();
|
|
55920
56289
|
d.run(`INSERT OR IGNORE INTO memory_links (id, source_memory_id, target_memory_id, relation_type, run_id, metadata, created_at)
|
|
55921
56290
|
VALUES (?, ?, ?, ?, ?, ?, ?)`, [
|
|
55922
56291
|
id,
|
|
@@ -55925,7 +56294,7 @@ function createMemoryLink(input, db) {
|
|
|
55925
56294
|
input.relation_type,
|
|
55926
56295
|
input.run_id ?? null,
|
|
55927
56296
|
JSON.stringify(input.metadata ?? {}),
|
|
55928
|
-
|
|
56297
|
+
timestamp2
|
|
55929
56298
|
]);
|
|
55930
56299
|
const row = d.query(`SELECT * FROM memory_links
|
|
55931
56300
|
WHERE source_memory_id = ? AND target_memory_id = ? AND relation_type = ? AND COALESCE(run_id, '') = ?
|
|
@@ -58214,6 +58583,7 @@ export {
|
|
|
58214
58583
|
rollbackMemoryProjectLink,
|
|
58215
58584
|
resolveProjectId,
|
|
58216
58585
|
resolvePartialId,
|
|
58586
|
+
resolveMementosProjectAuthorityIdentity,
|
|
58217
58587
|
resetDatabase,
|
|
58218
58588
|
renameMachine,
|
|
58219
58589
|
releaseResourceLocks,
|
|
@@ -58226,6 +58596,8 @@ export {
|
|
|
58226
58596
|
registerAgent,
|
|
58227
58597
|
reflectOnTrajectory,
|
|
58228
58598
|
redactSecrets,
|
|
58599
|
+
readMementosProjectResourcePage,
|
|
58600
|
+
readAllMementosProjectResources,
|
|
58229
58601
|
pushStorageChanges,
|
|
58230
58602
|
pullStorageChanges,
|
|
58231
58603
|
providerRegistry,
|
|
@@ -58286,6 +58658,7 @@ export {
|
|
|
58286
58658
|
getMemoriesForEntity,
|
|
58287
58659
|
getMemoriesByKey,
|
|
58288
58660
|
getMementosStorageStatus,
|
|
58661
|
+
getMementosProjectResourceExact,
|
|
58289
58662
|
getMachine,
|
|
58290
58663
|
getFocus,
|
|
58291
58664
|
getFallbackSyncTargetMachine,
|
|
@@ -58340,6 +58713,7 @@ export {
|
|
|
58340
58713
|
canonicalMementosProjectRegistrationJson,
|
|
58341
58714
|
bulkLinkEntities,
|
|
58342
58715
|
bulkDeleteMemories,
|
|
58716
|
+
buildMementosProjectRegistrationCapability,
|
|
58343
58717
|
buildFocusFilter,
|
|
58344
58718
|
archiveUnused,
|
|
58345
58719
|
archiveStale,
|
|
@@ -58362,17 +58736,22 @@ export {
|
|
|
58362
58736
|
MemoryLockConflictError,
|
|
58363
58737
|
MemoryInjector,
|
|
58364
58738
|
MemoryExpiredError,
|
|
58739
|
+
MementosProjectResourceError,
|
|
58365
58740
|
MementosProjectRegistrationHttpClient,
|
|
58366
58741
|
MementosProjectRegistrationError,
|
|
58742
|
+
MementosProjectAuthorityIdentityError,
|
|
58367
58743
|
MEMORY_PROJECT_LINK_RECEIPT_COLUMNS,
|
|
58368
58744
|
MEMENTOS_STORAGE_TABLES,
|
|
58369
58745
|
MEMENTOS_STORAGE_FALLBACK_ENV,
|
|
58370
58746
|
MEMENTOS_STORAGE_ENV,
|
|
58747
|
+
MEMENTOS_PROJECT_RESOURCE_ROUTE,
|
|
58748
|
+
MEMENTOS_PROJECT_RESOURCE_KINDS,
|
|
58371
58749
|
MEMENTOS_PROJECT_REGISTRATION_SCHEMA_VERSION,
|
|
58372
58750
|
MEMENTOS_PROJECT_REGISTRATION_ROUTE,
|
|
58373
58751
|
MEMENTOS_PROJECT_REGISTRATION_CALLER_ROUTE,
|
|
58374
58752
|
MEMENTOS_PROJECT_REFERENCE_SURFACES,
|
|
58375
58753
|
MEMENTOS_PROJECT_GUARDED_UPDATE_ROUTE,
|
|
58754
|
+
MEMENTOS_PROJECT_AUTHORITY_ENV,
|
|
58376
58755
|
MEMENTOS_MEMORY_PROJECT_LINK_ROUTE,
|
|
58377
58756
|
InvalidScopeError,
|
|
58378
58757
|
EntityNotFoundError,
|