@hasna/mementos 0.14.81 → 0.14.83
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 +567 -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 +480 -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 +1508 -55
- package/dist/sdk/index.d.ts +57 -0
- package/dist/sdk/index.d.ts.map +1 -1
- package/dist/sdk/index.js +79 -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,331 @@ 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
|
+
let pageCount = 0;
|
|
53689
|
+
let maxPageCount = 1;
|
|
53690
|
+
const resources = [];
|
|
53691
|
+
const seen = new Set;
|
|
53692
|
+
const seenCursors = new Set;
|
|
53693
|
+
do {
|
|
53694
|
+
const page = readMementosProjectResourcePage(projectId, {
|
|
53695
|
+
limit: pageSize,
|
|
53696
|
+
cursor,
|
|
53697
|
+
resource_kinds: options.resource_kinds
|
|
53698
|
+
}, db, authorityOptions);
|
|
53699
|
+
pageCount += 1;
|
|
53700
|
+
if (!first) {
|
|
53701
|
+
first = page;
|
|
53702
|
+
if (!Number.isSafeInteger(first.total) || first.total < 0) {
|
|
53703
|
+
throw new MementosProjectResourceError("MEMENTOS_PROJECT_RESOURCE_INCOMPLETE", "Mementos project resource traversal returned an invalid total");
|
|
53704
|
+
}
|
|
53705
|
+
maxPageCount = Math.max(1, Math.ceil(first.total / pageSize));
|
|
53706
|
+
}
|
|
53707
|
+
if (page.project_id !== projectId || page.collection_revision !== first.collection_revision || page.total !== first.total || JSON.stringify(page.resource_kinds) !== JSON.stringify(first.resource_kinds)) {
|
|
53708
|
+
throw new MementosProjectResourceError("MEMENTOS_PROJECT_RESOURCE_COLLECTION_CHANGED", "Mementos project resource collection changed during complete traversal");
|
|
53709
|
+
}
|
|
53710
|
+
for (const resource of page.resources) {
|
|
53711
|
+
const key = resourceKey(resource);
|
|
53712
|
+
if (seen.has(key)) {
|
|
53713
|
+
throw new MementosProjectResourceError("MEMENTOS_PROJECT_RESOURCE_INCOMPLETE", `Mementos project resource traversal returned duplicate stable ID: ${key}`);
|
|
53714
|
+
}
|
|
53715
|
+
seen.add(key);
|
|
53716
|
+
resources.push(resource);
|
|
53717
|
+
}
|
|
53718
|
+
if (page.has_more && !page.next_cursor) {
|
|
53719
|
+
throw new MementosProjectResourceError("MEMENTOS_PROJECT_RESOURCE_INCOMPLETE", "Mementos project resource page claimed more results without a continuation cursor");
|
|
53720
|
+
}
|
|
53721
|
+
if (!page.has_more && page.next_cursor) {
|
|
53722
|
+
throw new MementosProjectResourceError("MEMENTOS_PROJECT_RESOURCE_INCOMPLETE", "Mementos project resource page returned a continuation cursor while claiming no more results");
|
|
53723
|
+
}
|
|
53724
|
+
if (page.next_cursor && seenCursors.has(page.next_cursor)) {
|
|
53725
|
+
throw new MementosProjectResourceError("MEMENTOS_PROJECT_RESOURCE_INCOMPLETE", "Mementos project resource traversal repeated a continuation cursor");
|
|
53726
|
+
}
|
|
53727
|
+
if (page.has_more && pageCount >= maxPageCount) {
|
|
53728
|
+
throw new MementosProjectResourceError("MEMENTOS_PROJECT_RESOURCE_INCOMPLETE", `Mementos project resource traversal exceeded its bounded ${maxPageCount}-page population`);
|
|
53729
|
+
}
|
|
53730
|
+
if (page.next_cursor)
|
|
53731
|
+
seenCursors.add(page.next_cursor);
|
|
53732
|
+
cursor = page.next_cursor;
|
|
53733
|
+
} while (cursor);
|
|
53734
|
+
if (!first) {
|
|
53735
|
+
throw new MementosProjectResourceError("MEMENTOS_PROJECT_RESOURCE_INCOMPLETE", "Mementos project resource traversal returned no first page");
|
|
53736
|
+
}
|
|
53737
|
+
if (resources.length !== first.total) {
|
|
53738
|
+
throw new MementosProjectResourceError("MEMENTOS_PROJECT_RESOURCE_INCOMPLETE", `Mementos project resource traversal returned ${resources.length} of ${first.total} resources`);
|
|
53739
|
+
}
|
|
53740
|
+
return {
|
|
53741
|
+
...first,
|
|
53742
|
+
resources,
|
|
53743
|
+
count: resources.length,
|
|
53744
|
+
total: resources.length,
|
|
53745
|
+
limit: pageSize,
|
|
53746
|
+
cursor: null,
|
|
53747
|
+
next_cursor: null,
|
|
53748
|
+
has_more: false,
|
|
53749
|
+
complete: true,
|
|
53750
|
+
truncated: false
|
|
53751
|
+
};
|
|
53752
|
+
}
|
|
53753
|
+
function getMementosProjectResourceExact(projectId, resourceKind, stableId, db, authorityOptions = {}) {
|
|
53754
|
+
if (!MEMENTOS_PROJECT_RESOURCE_KINDS.includes(resourceKind)) {
|
|
53755
|
+
throw new MementosProjectResourceError("MEMENTOS_PROJECT_RESOURCE_INVALID_INPUT", `Unsupported Mementos project resource kind: ${resourceKind}`);
|
|
53756
|
+
}
|
|
53757
|
+
if (!db && isApiMode()) {
|
|
53758
|
+
const { data } = apiJson("GET", `/projects/${encodeURIComponent(projectId)}/resources/${encodeURIComponent(resourceKind)}/${encodeURIComponent(stableId)}`);
|
|
53759
|
+
return data;
|
|
53760
|
+
}
|
|
53761
|
+
const d = db ?? getDatabase();
|
|
53762
|
+
const { project, resources, collectionRevision } = localPopulation(projectId, d, [
|
|
53763
|
+
resourceKind
|
|
53764
|
+
]);
|
|
53765
|
+
const resource = resources.find((candidate) => candidate.stable_id === stableId);
|
|
53766
|
+
if (!resource) {
|
|
53767
|
+
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 });
|
|
53768
|
+
}
|
|
53769
|
+
const capability = buildMementosProjectRegistrationCapability(authorityOptions);
|
|
53770
|
+
return {
|
|
53771
|
+
schema: "mementos.project-resource.v1",
|
|
53772
|
+
authority: {
|
|
53773
|
+
authority: capability.authority,
|
|
53774
|
+
authority_id: capability.authority_id,
|
|
53775
|
+
tenant_id: capability.tenant_id,
|
|
53776
|
+
corpus_id: capability.corpus_id,
|
|
53777
|
+
package_version: capability.package_version
|
|
53778
|
+
},
|
|
53779
|
+
project_id: projectId,
|
|
53780
|
+
project_revision: timestamp(project.updated_at),
|
|
53781
|
+
collection_revision: collectionRevision,
|
|
53782
|
+
resource,
|
|
53783
|
+
complete: true,
|
|
53784
|
+
truncated: false
|
|
53785
|
+
};
|
|
53786
|
+
}
|
|
53398
53787
|
// src/db/machines.ts
|
|
53399
53788
|
init_database();
|
|
53400
53789
|
import { hostname, platform } from "os";
|
|
@@ -53519,13 +53908,13 @@ function createEntity(input, db) {
|
|
|
53519
53908
|
return data;
|
|
53520
53909
|
}
|
|
53521
53910
|
const d = db || getDatabase();
|
|
53522
|
-
const
|
|
53911
|
+
const timestamp2 = now();
|
|
53523
53912
|
const metadataJson = JSON.stringify(input.metadata || {});
|
|
53524
53913
|
const existing = d.query(`SELECT * FROM entities
|
|
53525
53914
|
WHERE name = ? AND type = ? AND COALESCE(project_id, '') = ?`).get(input.name, input.type, input.project_id || "");
|
|
53526
53915
|
if (existing) {
|
|
53527
53916
|
const sets = ["updated_at = ?"];
|
|
53528
|
-
const params = [
|
|
53917
|
+
const params = [timestamp2];
|
|
53529
53918
|
if (input.description !== undefined) {
|
|
53530
53919
|
sets.push("description = ?");
|
|
53531
53920
|
params.push(input.description);
|
|
@@ -53548,8 +53937,8 @@ function createEntity(input, db) {
|
|
|
53548
53937
|
input.description || null,
|
|
53549
53938
|
metadataJson,
|
|
53550
53939
|
input.project_id || null,
|
|
53551
|
-
|
|
53552
|
-
|
|
53940
|
+
timestamp2,
|
|
53941
|
+
timestamp2
|
|
53553
53942
|
]);
|
|
53554
53943
|
hookRegistry.runHooks("PostEntityCreate", {
|
|
53555
53944
|
entityId: id,
|
|
@@ -54377,7 +54766,7 @@ function memoryResource(memory) {
|
|
|
54377
54766
|
tags: memory.tags
|
|
54378
54767
|
};
|
|
54379
54768
|
}
|
|
54380
|
-
function
|
|
54769
|
+
function projectResource2(projectId, name, externalId) {
|
|
54381
54770
|
return {
|
|
54382
54771
|
kind: "project",
|
|
54383
54772
|
id: projectId,
|
|
@@ -54483,7 +54872,7 @@ function createMementosProjectPanel(projectRef, options = {}) {
|
|
|
54483
54872
|
actionResource("mementos:save", "Save project memory")
|
|
54484
54873
|
],
|
|
54485
54874
|
resourceRefs: [
|
|
54486
|
-
|
|
54875
|
+
projectResource2(projectId, project?.name ?? projectRef, project?.id ?? projectRef),
|
|
54487
54876
|
...memories.slice(0, limit).map(memoryResource)
|
|
54488
54877
|
],
|
|
54489
54878
|
renderFragment: {
|
|
@@ -55085,29 +55474,29 @@ function enforceQuotas(config, db) {
|
|
|
55085
55474
|
}
|
|
55086
55475
|
function archiveStale(staleDays, db) {
|
|
55087
55476
|
const d = db || getDatabase();
|
|
55088
|
-
const
|
|
55477
|
+
const timestamp2 = now();
|
|
55089
55478
|
const cutoff = new Date(Date.now() - staleDays * 24 * 60 * 60 * 1000).toISOString();
|
|
55090
55479
|
const archiveWhere = `status = 'active' AND pinned = 0 AND COALESCE(accessed_at, created_at) < ?`;
|
|
55091
55480
|
const count = d.query(`SELECT COUNT(*) as c FROM memories WHERE ${archiveWhere}`).get(cutoff).c;
|
|
55092
55481
|
if (count > 0) {
|
|
55093
|
-
d.run(`UPDATE memories SET status = 'archived', updated_at = ? WHERE ${archiveWhere}`, [
|
|
55482
|
+
d.run(`UPDATE memories SET status = 'archived', updated_at = ? WHERE ${archiveWhere}`, [timestamp2, cutoff]);
|
|
55094
55483
|
}
|
|
55095
55484
|
return count;
|
|
55096
55485
|
}
|
|
55097
55486
|
function archiveUnused(days, db) {
|
|
55098
55487
|
const d = db || getDatabase();
|
|
55099
|
-
const
|
|
55488
|
+
const timestamp2 = now();
|
|
55100
55489
|
const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString();
|
|
55101
55490
|
const unusedWhere = `status = 'active' AND pinned = 0 AND access_count = 0 AND created_at < ?`;
|
|
55102
55491
|
const count = d.query(`SELECT COUNT(*) as c FROM memories WHERE ${unusedWhere}`).get(cutoff).c;
|
|
55103
55492
|
if (count > 0) {
|
|
55104
|
-
d.run(`UPDATE memories SET status = 'archived', updated_at = ? WHERE ${unusedWhere}`, [
|
|
55493
|
+
d.run(`UPDATE memories SET status = 'archived', updated_at = ? WHERE ${unusedWhere}`, [timestamp2, cutoff]);
|
|
55105
55494
|
}
|
|
55106
55495
|
return count;
|
|
55107
55496
|
}
|
|
55108
55497
|
function deprioritizeStale(days, db) {
|
|
55109
55498
|
const d = db || getDatabase();
|
|
55110
|
-
const
|
|
55499
|
+
const timestamp2 = now();
|
|
55111
55500
|
const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString();
|
|
55112
55501
|
const deprioWhere = `status = 'active' AND pinned = 0 AND importance > 1 AND COALESCE(accessed_at, updated_at) < ?`;
|
|
55113
55502
|
const count = d.query(`SELECT COUNT(*) as c FROM memories WHERE ${deprioWhere}`).get(cutoff).c;
|
|
@@ -55116,7 +55505,7 @@ function deprioritizeStale(days, db) {
|
|
|
55116
55505
|
SET importance = importance - 1,
|
|
55117
55506
|
version = version + 1,
|
|
55118
55507
|
updated_at = ?
|
|
55119
|
-
WHERE ${deprioWhere}`, [
|
|
55508
|
+
WHERE ${deprioWhere}`, [timestamp2, cutoff]);
|
|
55120
55509
|
}
|
|
55121
55510
|
return count;
|
|
55122
55511
|
}
|
|
@@ -55140,9 +55529,9 @@ function getAgentSyncDir(agentName) {
|
|
|
55140
55529
|
}
|
|
55141
55530
|
return dir;
|
|
55142
55531
|
}
|
|
55143
|
-
function setHighWaterMark(agentDir,
|
|
55532
|
+
function setHighWaterMark(agentDir, timestamp2) {
|
|
55144
55533
|
const markFile = join6(agentDir, ".highwatermark");
|
|
55145
|
-
writeFileSync4(markFile,
|
|
55534
|
+
writeFileSync4(markFile, timestamp2, "utf-8");
|
|
55146
55535
|
}
|
|
55147
55536
|
function resolveConflict(local, remote, resolution) {
|
|
55148
55537
|
switch (resolution) {
|
|
@@ -55462,13 +55851,13 @@ function buildConflictKey(key, sourceMachine, updatedAt) {
|
|
|
55462
55851
|
return `${key}__conflict__${machineSegment}__${timestampSegment || "0"}`;
|
|
55463
55852
|
}
|
|
55464
55853
|
function buildConflictClone(loser, sourceMachine, winnerId) {
|
|
55465
|
-
const
|
|
55854
|
+
const timestamp2 = new Date().toISOString();
|
|
55466
55855
|
const tags = new Set(ensureArrayValue(loser["tags"]));
|
|
55467
55856
|
tags.add("sync-conflict");
|
|
55468
55857
|
tags.add(`source_machine:${sourceMachine}`);
|
|
55469
55858
|
const metadata = ensureObjectValue(loser["metadata"]);
|
|
55470
55859
|
metadata["sync_conflict"] = true;
|
|
55471
|
-
metadata["conflict_detected_at"] =
|
|
55860
|
+
metadata["conflict_detected_at"] = timestamp2;
|
|
55472
55861
|
metadata["conflict_original_id"] = loser["id"];
|
|
55473
55862
|
metadata["conflict_winner_id"] = winnerId;
|
|
55474
55863
|
metadata["conflict_source_machine"] = sourceMachine;
|
|
@@ -55480,10 +55869,10 @@ function buildConflictClone(loser, sourceMachine, winnerId) {
|
|
|
55480
55869
|
metadata: JSON.stringify(metadata),
|
|
55481
55870
|
access_count: 0,
|
|
55482
55871
|
version: 1,
|
|
55483
|
-
created_at:
|
|
55484
|
-
updated_at:
|
|
55872
|
+
created_at: timestamp2,
|
|
55873
|
+
updated_at: timestamp2,
|
|
55485
55874
|
..."accessed_at" in loser ? { accessed_at: null } : {},
|
|
55486
|
-
..."ingested_at" in loser ? { ingested_at:
|
|
55875
|
+
..."ingested_at" in loser ? { ingested_at: timestamp2 } : {}
|
|
55487
55876
|
}, sourceMachine);
|
|
55488
55877
|
}
|
|
55489
55878
|
function insertConflictCloneIfMissing(db, clone) {
|
|
@@ -55733,13 +56122,13 @@ function createRelation(input, db) {
|
|
|
55733
56122
|
}
|
|
55734
56123
|
const d = db || getDatabase();
|
|
55735
56124
|
const id = shortUuid();
|
|
55736
|
-
const
|
|
56125
|
+
const timestamp2 = now();
|
|
55737
56126
|
const weight = input.weight ?? 1;
|
|
55738
56127
|
const metadata = JSON.stringify(input.metadata ?? {});
|
|
55739
56128
|
d.run(`INSERT INTO relations (id, source_entity_id, target_entity_id, relation_type, weight, metadata, created_at)
|
|
55740
56129
|
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
55741
56130
|
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,
|
|
56131
|
+
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
56132
|
const row = d.query(`SELECT * FROM relations
|
|
55744
56133
|
WHERE source_entity_id = ? AND target_entity_id = ? AND relation_type = ?`).get(input.source_entity_id, input.target_entity_id, input.relation_type);
|
|
55745
56134
|
const relation = parseRelationRow(row);
|
|
@@ -55916,7 +56305,7 @@ function parseMemoryLink(row) {
|
|
|
55916
56305
|
function createMemoryLink(input, db) {
|
|
55917
56306
|
const d = db || getDatabase();
|
|
55918
56307
|
const id = shortUuid();
|
|
55919
|
-
const
|
|
56308
|
+
const timestamp2 = now();
|
|
55920
56309
|
d.run(`INSERT OR IGNORE INTO memory_links (id, source_memory_id, target_memory_id, relation_type, run_id, metadata, created_at)
|
|
55921
56310
|
VALUES (?, ?, ?, ?, ?, ?, ?)`, [
|
|
55922
56311
|
id,
|
|
@@ -55925,7 +56314,7 @@ function createMemoryLink(input, db) {
|
|
|
55925
56314
|
input.relation_type,
|
|
55926
56315
|
input.run_id ?? null,
|
|
55927
56316
|
JSON.stringify(input.metadata ?? {}),
|
|
55928
|
-
|
|
56317
|
+
timestamp2
|
|
55929
56318
|
]);
|
|
55930
56319
|
const row = d.query(`SELECT * FROM memory_links
|
|
55931
56320
|
WHERE source_memory_id = ? AND target_memory_id = ? AND relation_type = ? AND COALESCE(run_id, '') = ?
|
|
@@ -58214,6 +58603,7 @@ export {
|
|
|
58214
58603
|
rollbackMemoryProjectLink,
|
|
58215
58604
|
resolveProjectId,
|
|
58216
58605
|
resolvePartialId,
|
|
58606
|
+
resolveMementosProjectAuthorityIdentity,
|
|
58217
58607
|
resetDatabase,
|
|
58218
58608
|
renameMachine,
|
|
58219
58609
|
releaseResourceLocks,
|
|
@@ -58226,6 +58616,8 @@ export {
|
|
|
58226
58616
|
registerAgent,
|
|
58227
58617
|
reflectOnTrajectory,
|
|
58228
58618
|
redactSecrets,
|
|
58619
|
+
readMementosProjectResourcePage,
|
|
58620
|
+
readAllMementosProjectResources,
|
|
58229
58621
|
pushStorageChanges,
|
|
58230
58622
|
pullStorageChanges,
|
|
58231
58623
|
providerRegistry,
|
|
@@ -58286,6 +58678,7 @@ export {
|
|
|
58286
58678
|
getMemoriesForEntity,
|
|
58287
58679
|
getMemoriesByKey,
|
|
58288
58680
|
getMementosStorageStatus,
|
|
58681
|
+
getMementosProjectResourceExact,
|
|
58289
58682
|
getMachine,
|
|
58290
58683
|
getFocus,
|
|
58291
58684
|
getFallbackSyncTargetMachine,
|
|
@@ -58340,6 +58733,7 @@ export {
|
|
|
58340
58733
|
canonicalMementosProjectRegistrationJson,
|
|
58341
58734
|
bulkLinkEntities,
|
|
58342
58735
|
bulkDeleteMemories,
|
|
58736
|
+
buildMementosProjectRegistrationCapability,
|
|
58343
58737
|
buildFocusFilter,
|
|
58344
58738
|
archiveUnused,
|
|
58345
58739
|
archiveStale,
|
|
@@ -58362,17 +58756,22 @@ export {
|
|
|
58362
58756
|
MemoryLockConflictError,
|
|
58363
58757
|
MemoryInjector,
|
|
58364
58758
|
MemoryExpiredError,
|
|
58759
|
+
MementosProjectResourceError,
|
|
58365
58760
|
MementosProjectRegistrationHttpClient,
|
|
58366
58761
|
MementosProjectRegistrationError,
|
|
58762
|
+
MementosProjectAuthorityIdentityError,
|
|
58367
58763
|
MEMORY_PROJECT_LINK_RECEIPT_COLUMNS,
|
|
58368
58764
|
MEMENTOS_STORAGE_TABLES,
|
|
58369
58765
|
MEMENTOS_STORAGE_FALLBACK_ENV,
|
|
58370
58766
|
MEMENTOS_STORAGE_ENV,
|
|
58767
|
+
MEMENTOS_PROJECT_RESOURCE_ROUTE,
|
|
58768
|
+
MEMENTOS_PROJECT_RESOURCE_KINDS,
|
|
58371
58769
|
MEMENTOS_PROJECT_REGISTRATION_SCHEMA_VERSION,
|
|
58372
58770
|
MEMENTOS_PROJECT_REGISTRATION_ROUTE,
|
|
58373
58771
|
MEMENTOS_PROJECT_REGISTRATION_CALLER_ROUTE,
|
|
58374
58772
|
MEMENTOS_PROJECT_REFERENCE_SURFACES,
|
|
58375
58773
|
MEMENTOS_PROJECT_GUARDED_UPDATE_ROUTE,
|
|
58774
|
+
MEMENTOS_PROJECT_AUTHORITY_ENV,
|
|
58376
58775
|
MEMENTOS_MEMORY_PROJECT_LINK_ROUTE,
|
|
58377
58776
|
InvalidScopeError,
|
|
58378
58777
|
EntityNotFoundError,
|