@remnic/core 9.41.0 → 9.43.0

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.
Files changed (72) hide show
  1. package/dist/access-admin-ops-surface.js +7 -7
  2. package/dist/access-authorization-probe.js +8 -8
  3. package/dist/access-boundary.js +7 -7
  4. package/dist/access-cli.js +19 -19
  5. package/dist/access-extraction-force-flush.js +7 -7
  6. package/dist/access-http.js +12 -12
  7. package/dist/access-identity-continuity-surface.js +7 -7
  8. package/dist/access-lcm-surface.js +7 -7
  9. package/dist/access-mcp.js +10 -10
  10. package/dist/access-namespace-preflight.js +7 -7
  11. package/dist/access-observe-write-surface.js +7 -7
  12. package/dist/access-operations-batch.js +8 -8
  13. package/dist/access-operations.d.ts +3 -3
  14. package/dist/access-operations.js +9 -9
  15. package/dist/access-recall-concurrency.js +7 -7
  16. package/dist/access-recall-response.js +7 -7
  17. package/dist/access-recall-surface.js +7 -7
  18. package/dist/access-schema.d.ts +84 -84
  19. package/dist/access-service.js +7 -7
  20. package/dist/{chunk-XRWVXPEM.js → chunk-4DYBLQZC.js} +2 -2
  21. package/dist/{chunk-Q4XL7LJW.js → chunk-5QZEVMLY.js} +4 -4
  22. package/dist/{chunk-KXGN6G2Y.js → chunk-AR2FSZBP.js} +2 -2
  23. package/dist/{chunk-IOQFPVGY.js → chunk-BGXHVOBI.js} +2 -2
  24. package/dist/{chunk-UZQCNOPS.js → chunk-EHKDORQN.js} +4 -4
  25. package/dist/{chunk-7VIB7PAE.js → chunk-EPQ76W5T.js} +2 -2
  26. package/dist/{chunk-PWKZV4A3.js → chunk-GS5UVGQK.js} +2 -2
  27. package/dist/{chunk-FHEJ22B7.js → chunk-JGXXPDM2.js} +2 -2
  28. package/dist/{chunk-UGCUVLOL.js → chunk-KDXD2AM6.js} +11 -11
  29. package/dist/{chunk-UQVGDEAJ.js → chunk-LZ5JKQCS.js} +2 -2
  30. package/dist/{chunk-OYFDEJZB.js → chunk-MBTPUVHZ.js} +2 -2
  31. package/dist/{chunk-LRGSLV7M.js → chunk-PYHOAXTI.js} +4 -4
  32. package/dist/{chunk-CQ5MR2HQ.js → chunk-SEUSFKNS.js} +4 -4
  33. package/dist/{chunk-CWPDM66T.js → chunk-UP67AFRN.js} +5 -5
  34. package/dist/{chunk-AXUU7SG3.js → chunk-YJHU5B3M.js} +2 -2
  35. package/dist/{chunk-6I2C3EOH.js → chunk-ZVVASRUT.js} +7 -7
  36. package/dist/cli.js +18 -18
  37. package/dist/corpus-watermark.js +5 -5
  38. package/dist/index.d.ts +388 -388
  39. package/dist/index.js +19 -19
  40. package/dist/namespaces/migrate.js +4 -4
  41. package/dist/namespaces/search.js +3 -3
  42. package/dist/operator-doctor-corpus.js +6 -6
  43. package/dist/operator-toolkit.js +8 -8
  44. package/dist/orchestrator.js +19 -19
  45. package/dist/reconcile/cursor.d.ts +21 -0
  46. package/dist/reconcile/cursor.js +104 -0
  47. package/dist/reconcile/cursor.js.map +1 -0
  48. package/dist/schemas.d.ts +76 -76
  49. package/dist/search/factory.js +2 -2
  50. package/dist/search/index.js +4 -4
  51. package/dist/shared-context/manager.d.ts +8 -8
  52. package/dist/transfer/import-sqlite.js +2 -2
  53. package/dist/transfer/types.d.ts +66 -66
  54. package/package.json +12 -2
  55. package/src/reconcile/cursor.test.ts +123 -0
  56. package/src/reconcile/cursor.ts +130 -0
  57. /package/dist/{chunk-XRWVXPEM.js.map → chunk-4DYBLQZC.js.map} +0 -0
  58. /package/dist/{chunk-Q4XL7LJW.js.map → chunk-5QZEVMLY.js.map} +0 -0
  59. /package/dist/{chunk-KXGN6G2Y.js.map → chunk-AR2FSZBP.js.map} +0 -0
  60. /package/dist/{chunk-IOQFPVGY.js.map → chunk-BGXHVOBI.js.map} +0 -0
  61. /package/dist/{chunk-UZQCNOPS.js.map → chunk-EHKDORQN.js.map} +0 -0
  62. /package/dist/{chunk-7VIB7PAE.js.map → chunk-EPQ76W5T.js.map} +0 -0
  63. /package/dist/{chunk-PWKZV4A3.js.map → chunk-GS5UVGQK.js.map} +0 -0
  64. /package/dist/{chunk-FHEJ22B7.js.map → chunk-JGXXPDM2.js.map} +0 -0
  65. /package/dist/{chunk-UGCUVLOL.js.map → chunk-KDXD2AM6.js.map} +0 -0
  66. /package/dist/{chunk-UQVGDEAJ.js.map → chunk-LZ5JKQCS.js.map} +0 -0
  67. /package/dist/{chunk-OYFDEJZB.js.map → chunk-MBTPUVHZ.js.map} +0 -0
  68. /package/dist/{chunk-LRGSLV7M.js.map → chunk-PYHOAXTI.js.map} +0 -0
  69. /package/dist/{chunk-CQ5MR2HQ.js.map → chunk-SEUSFKNS.js.map} +0 -0
  70. /package/dist/{chunk-CWPDM66T.js.map → chunk-UP67AFRN.js.map} +0 -0
  71. /package/dist/{chunk-AXUU7SG3.js.map → chunk-YJHU5B3M.js.map} +0 -0
  72. /package/dist/{chunk-6I2C3EOH.js.map → chunk-ZVVASRUT.js.map} +0 -0
@@ -0,0 +1,130 @@
1
+ import { createHash, randomUUID } from "node:crypto";
2
+ import * as fs from "node:fs/promises";
3
+ import * as path from "node:path";
4
+
5
+ export interface ConvergeCursorFileState {
6
+ path: string;
7
+ sha256: string;
8
+ mtimeMs?: number;
9
+ bytes?: number;
10
+ }
11
+
12
+ export interface ConvergeCursorState {
13
+ version: 1;
14
+ peerUrl: string;
15
+ namespace: string;
16
+ lastConvergedAt?: string;
17
+ baseFiles: ConvergeCursorFileState[];
18
+ completedPaths?: string[];
19
+ }
20
+
21
+ export function hashPeerNamespace(peerUrl: string, namespace: string): string {
22
+ let normalizedUrl: string;
23
+ try {
24
+ const url = new URL(peerUrl);
25
+ const credentials =
26
+ url.username || url.password
27
+ ? `${url.username}${url.password ? `:${url.password}` : ""}@`
28
+ : "";
29
+ normalizedUrl =
30
+ `${url.protocol.toLowerCase()}//${credentials}${url.hostname.toLowerCase()}` +
31
+ `${url.port ? `:${url.port}` : ""}${url.pathname.replace(/\/+$/, "")}${url.search}${url.hash}`;
32
+ } catch {
33
+ normalizedUrl = peerUrl.trim().replace(/\/+$/, "").toLowerCase();
34
+ }
35
+ const normalizedNs = namespace.trim().toLowerCase();
36
+ return createHash("sha256")
37
+ .update(`${normalizedUrl}\0${normalizedNs}`)
38
+ .digest("hex")
39
+ .slice(0, 16);
40
+ }
41
+
42
+ export function defaultConvergeCursorPath(
43
+ memoryDir: string,
44
+ peerUrl: string,
45
+ namespace: string,
46
+ ): string {
47
+ const key = hashPeerNamespace(peerUrl, namespace);
48
+ return path.join(path.resolve(memoryDir), ".remnic", "state", "converge-cursors", `${key}.json`);
49
+ }
50
+
51
+ export function normalizeConvergeCursor(input: unknown): ConvergeCursorState {
52
+ if (!input || typeof input !== "object" || Array.isArray(input)) {
53
+ throw new Error("converge cursor must be an object");
54
+ }
55
+ const obj = input as Record<string, unknown>;
56
+ if (obj.version !== 1) {
57
+ throw new Error("converge cursor version must be 1");
58
+ }
59
+ if (typeof obj.peerUrl !== "string" || !obj.peerUrl.trim()) {
60
+ throw new Error("converge cursor missing peerUrl");
61
+ }
62
+ if (typeof obj.namespace !== "string" || !obj.namespace.trim()) {
63
+ throw new Error("converge cursor missing namespace");
64
+ }
65
+ const baseFiles: ConvergeCursorFileState[] = [];
66
+ if (Array.isArray(obj.baseFiles)) {
67
+ for (const item of obj.baseFiles) {
68
+ if (item && typeof item === "object") {
69
+ const fileItem = item as Record<string, unknown>;
70
+ if (typeof fileItem.path === "string" && typeof fileItem.sha256 === "string") {
71
+ baseFiles.push({
72
+ path: fileItem.path,
73
+ sha256: fileItem.sha256,
74
+ mtimeMs: typeof fileItem.mtimeMs === "number" ? fileItem.mtimeMs : undefined,
75
+ bytes: typeof fileItem.bytes === "number" ? fileItem.bytes : undefined,
76
+ });
77
+ }
78
+ }
79
+ }
80
+ }
81
+ const completedPaths: string[] = [];
82
+ if (Array.isArray(obj.completedPaths)) {
83
+ for (const item of obj.completedPaths) {
84
+ if (typeof item === "string") {
85
+ completedPaths.push(item);
86
+ }
87
+ }
88
+ }
89
+ return {
90
+ version: 1,
91
+ peerUrl: obj.peerUrl.trim(),
92
+ namespace: obj.namespace.trim(),
93
+ lastConvergedAt: typeof obj.lastConvergedAt === "string" ? obj.lastConvergedAt : undefined,
94
+ baseFiles,
95
+ completedPaths,
96
+ };
97
+ }
98
+
99
+ export async function readConvergeCursor(
100
+ cursorPath: string,
101
+ ): Promise<ConvergeCursorState | null> {
102
+ try {
103
+ const raw = await fs.readFile(path.resolve(cursorPath), "utf-8");
104
+ const parsed = JSON.parse(raw);
105
+ return normalizeConvergeCursor(parsed);
106
+ } catch (error) {
107
+ if ((error as NodeJS.ErrnoException).code === "ENOENT") return null;
108
+ return null;
109
+ }
110
+ }
111
+
112
+ export async function writeConvergeCursor(
113
+ cursorPath: string,
114
+ cursor: ConvergeCursorState,
115
+ ): Promise<void> {
116
+ const normalized = normalizeConvergeCursor(cursor);
117
+ const target = path.resolve(cursorPath);
118
+ await fs.mkdir(path.dirname(target), { recursive: true });
119
+ const tmp = path.join(
120
+ path.dirname(target),
121
+ `.converge-cursor.${process.pid}.${randomUUID()}.tmp`,
122
+ );
123
+ await fs.writeFile(tmp, JSON.stringify(normalized, null, 2) + "\n", "utf-8");
124
+ try {
125
+ await fs.rename(tmp, target);
126
+ } catch (error) {
127
+ await fs.unlink(tmp).catch(() => {});
128
+ throw error;
129
+ }
130
+ }