backpack-ontology 0.2.25 → 0.3.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 (105) hide show
  1. package/README.md +153 -3
  2. package/dist/bin/backpack-benchmark.d.ts +3 -0
  3. package/dist/bin/backpack-benchmark.d.ts.map +1 -0
  4. package/dist/bin/backpack-benchmark.js +213 -0
  5. package/dist/bin/backpack-benchmark.js.map +1 -0
  6. package/dist/bin/backpack.js +3 -3
  7. package/dist/bin/backpack.js.map +1 -1
  8. package/dist/bin/init.js +8 -11
  9. package/dist/bin/init.js.map +1 -1
  10. package/dist/core/backpack.d.ts +69 -2
  11. package/dist/core/backpack.d.ts.map +1 -1
  12. package/dist/core/backpack.js +205 -3
  13. package/dist/core/backpack.js.map +1 -1
  14. package/dist/core/draft.d.ts +42 -0
  15. package/dist/core/draft.d.ts.map +1 -0
  16. package/dist/core/draft.js +232 -0
  17. package/dist/core/draft.js.map +1 -0
  18. package/dist/core/events.d.ts +114 -0
  19. package/dist/core/events.d.ts.map +1 -0
  20. package/dist/core/events.js +375 -0
  21. package/dist/core/events.js.map +1 -0
  22. package/dist/core/graph.d.ts +3 -1
  23. package/dist/core/graph.d.ts.map +1 -1
  24. package/dist/core/graph.js +50 -0
  25. package/dist/core/graph.js.map +1 -1
  26. package/dist/core/hooks.d.ts +11 -3
  27. package/dist/core/hooks.d.ts.map +1 -1
  28. package/dist/core/hooks.js +53 -47
  29. package/dist/core/hooks.js.map +1 -1
  30. package/dist/core/normalize.d.ts +28 -0
  31. package/dist/core/normalize.d.ts.map +1 -0
  32. package/dist/core/normalize.js +133 -0
  33. package/dist/core/normalize.js.map +1 -0
  34. package/dist/core/remote-fetch.d.ts +50 -0
  35. package/dist/core/remote-fetch.d.ts.map +1 -0
  36. package/dist/core/remote-fetch.js +338 -0
  37. package/dist/core/remote-fetch.js.map +1 -0
  38. package/dist/core/remote-registry.d.ts +95 -0
  39. package/dist/core/remote-registry.d.ts.map +1 -0
  40. package/dist/core/remote-registry.js +296 -0
  41. package/dist/core/remote-registry.js.map +1 -0
  42. package/dist/core/remote-schema.d.ts +31 -0
  43. package/dist/core/remote-schema.d.ts.map +1 -0
  44. package/dist/core/remote-schema.js +252 -0
  45. package/dist/core/remote-schema.js.map +1 -0
  46. package/dist/core/role-audit.d.ts +20 -0
  47. package/dist/core/role-audit.d.ts.map +1 -0
  48. package/dist/core/role-audit.js +197 -0
  49. package/dist/core/role-audit.js.map +1 -0
  50. package/dist/core/telemetry.d.ts +2 -0
  51. package/dist/core/telemetry.d.ts.map +1 -1
  52. package/dist/core/telemetry.js +16 -0
  53. package/dist/core/telemetry.js.map +1 -1
  54. package/dist/core/token-estimate.d.ts +16 -0
  55. package/dist/core/token-estimate.d.ts.map +1 -0
  56. package/dist/core/token-estimate.js +29 -0
  57. package/dist/core/token-estimate.js.map +1 -0
  58. package/dist/core/types.d.ts +30 -1
  59. package/dist/core/types.d.ts.map +1 -1
  60. package/dist/index.d.ts +9 -1
  61. package/dist/index.d.ts.map +1 -1
  62. package/dist/index.js +8 -1
  63. package/dist/index.js.map +1 -1
  64. package/dist/mcp/server.d.ts.map +1 -1
  65. package/dist/mcp/server.js +9 -0
  66. package/dist/mcp/server.js.map +1 -1
  67. package/dist/mcp/tools/bulk-tools.d.ts.map +1 -1
  68. package/dist/mcp/tools/bulk-tools.js +80 -12
  69. package/dist/mcp/tools/bulk-tools.js.map +1 -1
  70. package/dist/mcp/tools/edge-tools.d.ts.map +1 -1
  71. package/dist/mcp/tools/edge-tools.js +14 -18
  72. package/dist/mcp/tools/edge-tools.js.map +1 -1
  73. package/dist/mcp/tools/error-helpers.d.ts +16 -0
  74. package/dist/mcp/tools/error-helpers.d.ts.map +1 -0
  75. package/dist/mcp/tools/error-helpers.js +34 -0
  76. package/dist/mcp/tools/error-helpers.js.map +1 -0
  77. package/dist/mcp/tools/intelligence-tools.d.ts.map +1 -1
  78. package/dist/mcp/tools/intelligence-tools.js +28 -18
  79. package/dist/mcp/tools/intelligence-tools.js.map +1 -1
  80. package/dist/mcp/tools/node-tools.d.ts.map +1 -1
  81. package/dist/mcp/tools/node-tools.js +43 -40
  82. package/dist/mcp/tools/node-tools.js.map +1 -1
  83. package/dist/mcp/tools/ontology-tools.d.ts.map +1 -1
  84. package/dist/mcp/tools/ontology-tools.js +237 -12
  85. package/dist/mcp/tools/ontology-tools.js.map +1 -1
  86. package/dist/mcp/tools/remote-tools.d.ts +5 -0
  87. package/dist/mcp/tools/remote-tools.d.ts.map +1 -0
  88. package/dist/mcp/tools/remote-tools.js +295 -0
  89. package/dist/mcp/tools/remote-tools.js.map +1 -0
  90. package/dist/storage/backpack-app-backend.d.ts +1 -1
  91. package/dist/storage/backpack-app-backend.d.ts.map +1 -1
  92. package/dist/storage/backpack-app-backend.js +3 -1
  93. package/dist/storage/backpack-app-backend.js.map +1 -1
  94. package/dist/storage/event-sourced-backend.d.ts +174 -0
  95. package/dist/storage/event-sourced-backend.d.ts.map +1 -0
  96. package/dist/storage/event-sourced-backend.js +840 -0
  97. package/dist/storage/event-sourced-backend.js.map +1 -0
  98. package/dist/storage/json-file-backend.d.ts +1 -72
  99. package/dist/storage/json-file-backend.d.ts.map +1 -1
  100. package/dist/storage/json-file-backend.js +11 -549
  101. package/dist/storage/json-file-backend.js.map +1 -1
  102. package/package.json +3 -3
  103. package/hooks/auto-capture-prompt.md +0 -40
  104. package/hooks/hooks.json +0 -16
  105. package/hooks/suggest-viewer.sh +0 -4
@@ -0,0 +1,338 @@
1
+ // ============================================================
2
+ // Hardened HTTPS fetch for remote learning graphs.
3
+ //
4
+ // Threats this module defends against:
5
+ // 1. SSRF — a malicious URL points at the user's private network
6
+ // (router admin, cloud metadata, internal services)
7
+ // 2. DNS rebinding — a hostname resolves once for validation,
8
+ // then to a different IP for the actual request
9
+ // 3. Resource exhaustion — slow loris, infinite stream, oversized body
10
+ // 4. Redirect loops to private addresses
11
+ //
12
+ // The contract:
13
+ // - HTTPS only
14
+ // - DNS resolved once; the IP is checked against a private-range
15
+ // blocklist; the request is dispatched against the IP directly
16
+ // so DNS rebinding cannot redirect to a different host
17
+ // - Hard size cap (default 10 MB)
18
+ // - Hard total timeout (15s) and connect timeout (5s)
19
+ // - Max 3 redirects, each re-validated
20
+ // - Returns the body bytes plus an ETag if present
21
+ // ============================================================
22
+ import * as https from "node:https";
23
+ import * as dns from "node:dns/promises";
24
+ import * as net from "node:net";
25
+ import { URL } from "node:url";
26
+ // --- Defaults ---
27
+ export const REMOTE_FETCH_DEFAULTS = {
28
+ maxBytes: 10 * 1024 * 1024, // 10 MB
29
+ totalTimeoutMs: 15_000,
30
+ connectTimeoutMs: 5_000,
31
+ maxRedirects: 3,
32
+ };
33
+ // --- Errors ---
34
+ export class RemoteFetchError extends Error {
35
+ code;
36
+ url;
37
+ constructor(message, code, url) {
38
+ super(message);
39
+ this.code = code;
40
+ this.url = url;
41
+ this.name = "RemoteFetchError";
42
+ }
43
+ }
44
+ /**
45
+ * Fetch a remote URL with full SSRF / size / timeout protections.
46
+ *
47
+ * Throws RemoteFetchError on any policy violation, network error,
48
+ * or oversized response.
49
+ */
50
+ export async function remoteFetch(rawUrl, options = {}) {
51
+ const opts = {
52
+ maxBytes: options.maxBytes ?? REMOTE_FETCH_DEFAULTS.maxBytes,
53
+ totalTimeoutMs: options.totalTimeoutMs ?? REMOTE_FETCH_DEFAULTS.totalTimeoutMs,
54
+ connectTimeoutMs: options.connectTimeoutMs ?? REMOTE_FETCH_DEFAULTS.connectTimeoutMs,
55
+ maxRedirects: options.maxRedirects ?? REMOTE_FETCH_DEFAULTS.maxRedirects,
56
+ ifNoneMatch: options.ifNoneMatch,
57
+ };
58
+ let currentUrl = rawUrl;
59
+ let redirectCount = 0;
60
+ const startedAt = Date.now();
61
+ while (true) {
62
+ if (Date.now() - startedAt > opts.totalTimeoutMs) {
63
+ throw new RemoteFetchError("total fetch timeout exceeded", "TIMEOUT", currentUrl);
64
+ }
65
+ const parsed = parseAndValidateUrl(currentUrl);
66
+ const resolvedIp = await resolveAndCheckHost(parsed.hostname);
67
+ const remaining = opts.totalTimeoutMs - (Date.now() - startedAt);
68
+ const response = await singleRequest(parsed, resolvedIp, {
69
+ maxBytes: opts.maxBytes,
70
+ totalTimeoutMs: remaining,
71
+ connectTimeoutMs: opts.connectTimeoutMs,
72
+ ifNoneMatch: opts.ifNoneMatch,
73
+ });
74
+ // 304 Not Modified — no body, return immediately
75
+ if (response.status === 304) {
76
+ return {
77
+ body: "",
78
+ bytes: 0,
79
+ etag: response.etag,
80
+ finalUrl: currentUrl,
81
+ status: 304,
82
+ notModified: true,
83
+ };
84
+ }
85
+ // Redirect handling
86
+ if (response.status >= 300 && response.status < 400 && response.location) {
87
+ if (redirectCount >= opts.maxRedirects) {
88
+ throw new RemoteFetchError(`too many redirects (max ${opts.maxRedirects})`, "TOO_MANY_REDIRECTS", currentUrl);
89
+ }
90
+ // Resolve relative redirects against the current URL
91
+ const nextUrl = new URL(response.location, currentUrl).toString();
92
+ redirectCount++;
93
+ currentUrl = nextUrl;
94
+ continue;
95
+ }
96
+ if (response.status < 200 || response.status >= 300) {
97
+ throw new RemoteFetchError(`HTTP ${response.status}`, "HTTP_ERROR", currentUrl);
98
+ }
99
+ return {
100
+ body: response.body,
101
+ bytes: response.bytes,
102
+ etag: response.etag,
103
+ finalUrl: currentUrl,
104
+ status: response.status,
105
+ notModified: false,
106
+ };
107
+ }
108
+ }
109
+ function parseAndValidateUrl(rawUrl) {
110
+ let url;
111
+ try {
112
+ url = new URL(rawUrl);
113
+ }
114
+ catch {
115
+ throw new RemoteFetchError(`invalid URL: ${rawUrl}`, "INVALID_URL", rawUrl);
116
+ }
117
+ if (url.protocol !== "https:") {
118
+ throw new RemoteFetchError(`only https:// URLs are allowed (got ${url.protocol})`, "INVALID_SCHEME", rawUrl);
119
+ }
120
+ if (!url.hostname) {
121
+ throw new RemoteFetchError("URL has no hostname", "INVALID_URL", rawUrl);
122
+ }
123
+ // Reject userinfo (https://user:pass@host) which can confuse parsers
124
+ if (url.username || url.password) {
125
+ throw new RemoteFetchError("URLs with userinfo are not allowed", "INVALID_URL", rawUrl);
126
+ }
127
+ // Node's URL parser keeps IPv6 brackets in `hostname` (e.g. "[::1]").
128
+ // Strip them so net.isIP() and DNS resolution work correctly.
129
+ let hostname = url.hostname;
130
+ if (hostname.startsWith("[") && hostname.endsWith("]")) {
131
+ hostname = hostname.slice(1, -1);
132
+ }
133
+ return {
134
+ href: url.href,
135
+ hostname,
136
+ port: url.port ? parseInt(url.port, 10) : 443,
137
+ pathname: url.pathname || "/",
138
+ search: url.search || "",
139
+ };
140
+ }
141
+ /**
142
+ * Resolves a hostname to an IP and rejects if the IP is in a private,
143
+ * loopback, link-local, multicast, or otherwise reserved range.
144
+ *
145
+ * Returns the resolved IP. Callers should dispatch the request against
146
+ * the IP directly to prevent DNS rebinding.
147
+ */
148
+ async function resolveAndCheckHost(hostname) {
149
+ // If the hostname is already a literal IP, check it directly
150
+ if (net.isIP(hostname)) {
151
+ if (isBlockedIp(hostname)) {
152
+ throw new RemoteFetchError(`IP address ${hostname} is in a blocked range`, "BLOCKED_IP");
153
+ }
154
+ return hostname;
155
+ }
156
+ let addrs;
157
+ try {
158
+ addrs = await dns.lookup(hostname, { all: true, verbatim: true });
159
+ }
160
+ catch (err) {
161
+ throw new RemoteFetchError(`DNS lookup failed: ${err.message}`, "DNS_ERROR");
162
+ }
163
+ if (addrs.length === 0) {
164
+ throw new RemoteFetchError("DNS lookup returned no addresses", "DNS_ERROR");
165
+ }
166
+ // Check ALL returned addresses — if any is private, refuse the whole hostname
167
+ for (const a of addrs) {
168
+ if (isBlockedIp(a.address)) {
169
+ throw new RemoteFetchError(`hostname ${hostname} resolves to blocked IP ${a.address}`, "BLOCKED_IP");
170
+ }
171
+ }
172
+ return addrs[0].address;
173
+ }
174
+ /**
175
+ * Returns true if the IP is in a private, loopback, link-local,
176
+ * multicast, broadcast, or reserved range. Both IPv4 and IPv6.
177
+ */
178
+ export function isBlockedIp(ip) {
179
+ if (net.isIPv4(ip)) {
180
+ return isBlockedIpv4(ip);
181
+ }
182
+ if (net.isIPv6(ip)) {
183
+ return isBlockedIpv6(ip);
184
+ }
185
+ return true; // unknown family — block by default
186
+ }
187
+ function isBlockedIpv4(ip) {
188
+ const parts = ip.split(".").map((p) => parseInt(p, 10));
189
+ if (parts.length !== 4 || parts.some((p) => isNaN(p) || p < 0 || p > 255)) {
190
+ return true;
191
+ }
192
+ const [a, b] = parts;
193
+ // 0.0.0.0/8 — "this network"
194
+ if (a === 0)
195
+ return true;
196
+ // 10.0.0.0/8 — private
197
+ if (a === 10)
198
+ return true;
199
+ // 100.64.0.0/10 — CGNAT shared address space
200
+ if (a === 100 && b >= 64 && b <= 127)
201
+ return true;
202
+ // 127.0.0.0/8 — loopback
203
+ if (a === 127)
204
+ return true;
205
+ // 169.254.0.0/16 — link-local (includes AWS/GCP metadata 169.254.169.254)
206
+ if (a === 169 && b === 254)
207
+ return true;
208
+ // 172.16.0.0/12 — private
209
+ if (a === 172 && b >= 16 && b <= 31)
210
+ return true;
211
+ // 192.0.0.0/24, 192.0.2.0/24 — IETF protocol assignments / TEST-NET-1
212
+ if (a === 192 && b === 0)
213
+ return true;
214
+ // 192.168.0.0/16 — private
215
+ if (a === 192 && b === 168)
216
+ return true;
217
+ // 198.18.0.0/15 — benchmarking
218
+ if (a === 198 && (b === 18 || b === 19))
219
+ return true;
220
+ // 198.51.100.0/24 — TEST-NET-2
221
+ if (a === 198 && b === 51)
222
+ return true;
223
+ // 203.0.113.0/24 — TEST-NET-3
224
+ if (a === 203 && b === 0)
225
+ return true;
226
+ // 224.0.0.0/4 — multicast
227
+ if (a >= 224 && a <= 239)
228
+ return true;
229
+ // 240.0.0.0/4 — reserved + 255.255.255.255 broadcast
230
+ if (a >= 240)
231
+ return true;
232
+ return false;
233
+ }
234
+ function isBlockedIpv6(ip) {
235
+ const lower = ip.toLowerCase();
236
+ // ::1 — loopback
237
+ if (lower === "::1")
238
+ return true;
239
+ // :: — unspecified
240
+ if (lower === "::")
241
+ return true;
242
+ // ::ffff:x.x.x.x — IPv4-mapped, recheck the IPv4
243
+ const v4MappedMatch = lower.match(/^::ffff:([\d.]+)$/);
244
+ if (v4MappedMatch) {
245
+ return isBlockedIpv4(v4MappedMatch[1]);
246
+ }
247
+ // fc00::/7 — unique local
248
+ if (lower.startsWith("fc") || lower.startsWith("fd"))
249
+ return true;
250
+ // fe80::/10 — link-local
251
+ if (lower.startsWith("fe8") || lower.startsWith("fe9") ||
252
+ lower.startsWith("fea") || lower.startsWith("feb"))
253
+ return true;
254
+ // ff00::/8 — multicast
255
+ if (lower.startsWith("ff"))
256
+ return true;
257
+ // 2001:db8::/32 — documentation
258
+ if (lower.startsWith("2001:db8:"))
259
+ return true;
260
+ return false;
261
+ }
262
+ function singleRequest(parsed, resolvedIp, opts) {
263
+ return new Promise((resolve, reject) => {
264
+ const headers = {
265
+ Host: parsed.hostname, // SNI / virtual host header still uses the name
266
+ "User-Agent": "backpack-remote-fetch/1.0",
267
+ Accept: "application/json",
268
+ };
269
+ if (opts.ifNoneMatch) {
270
+ headers["If-None-Match"] = opts.ifNoneMatch;
271
+ }
272
+ const req = https.request({
273
+ host: resolvedIp,
274
+ port: parsed.port,
275
+ path: parsed.pathname + parsed.search,
276
+ method: "GET",
277
+ headers,
278
+ servername: parsed.hostname, // SNI
279
+ // Strict TLS — no insecure fallback
280
+ rejectUnauthorized: true,
281
+ timeout: opts.connectTimeoutMs,
282
+ }, (res) => {
283
+ const status = res.statusCode || 0;
284
+ const etag = res.headers.etag || null;
285
+ const location = res.headers.location || null;
286
+ // 304 / 3xx — no body needed (or shouldn't read it)
287
+ if (status === 304 || (status >= 300 && status < 400)) {
288
+ res.resume(); // drain
289
+ resolve({ status, body: "", bytes: 0, etag, location });
290
+ return;
291
+ }
292
+ // Check declared content-length up front
293
+ const declared = parseInt(res.headers["content-length"] || "0", 10);
294
+ if (declared > opts.maxBytes) {
295
+ req.destroy();
296
+ reject(new RemoteFetchError(`Content-Length ${declared} exceeds max ${opts.maxBytes}`, "TOO_LARGE", parsed.href));
297
+ return;
298
+ }
299
+ const chunks = [];
300
+ let totalBytes = 0;
301
+ res.on("data", (chunk) => {
302
+ totalBytes += chunk.length;
303
+ if (totalBytes > opts.maxBytes) {
304
+ req.destroy();
305
+ reject(new RemoteFetchError(`response exceeds max ${opts.maxBytes} bytes`, "TOO_LARGE", parsed.href));
306
+ return;
307
+ }
308
+ chunks.push(chunk);
309
+ });
310
+ res.on("end", () => {
311
+ const body = Buffer.concat(chunks).toString("utf8");
312
+ resolve({ status, body, bytes: totalBytes, etag, location });
313
+ });
314
+ res.on("error", (err) => {
315
+ reject(new RemoteFetchError(`response error: ${err.message}`, "NETWORK_ERROR", parsed.href));
316
+ });
317
+ });
318
+ // Total timeout (separate from connect timeout)
319
+ const totalTimer = setTimeout(() => {
320
+ req.destroy();
321
+ reject(new RemoteFetchError("request timeout exceeded", "TIMEOUT", parsed.href));
322
+ }, opts.totalTimeoutMs);
323
+ req.on("timeout", () => {
324
+ req.destroy();
325
+ reject(new RemoteFetchError("connect timeout exceeded", "CONNECT_TIMEOUT", parsed.href));
326
+ });
327
+ req.on("error", (err) => {
328
+ clearTimeout(totalTimer);
329
+ // Already rejected above? Promise is idempotent, second reject is no-op
330
+ reject(new RemoteFetchError(`network error: ${err.message}`, "NETWORK_ERROR", parsed.href));
331
+ });
332
+ req.on("close", () => {
333
+ clearTimeout(totalTimer);
334
+ });
335
+ req.end();
336
+ });
337
+ }
338
+ //# sourceMappingURL=remote-fetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-fetch.js","sourceRoot":"","sources":["../../src/core/remote-fetch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,95 @@
1
+ import type { LearningGraphData } from "./types.js";
2
+ export interface RemoteEntry {
3
+ /** Local alias used in the viewer / MCP. Unique within the registry. */
4
+ name: string;
5
+ /** Source URL (must be https://). */
6
+ url: string;
7
+ /** Optional human-readable source label (e.g. "github:user/repo"). */
8
+ source?: string;
9
+ /** ISO timestamp when first registered. */
10
+ addedAt: string;
11
+ /** ISO timestamp of the last successful fetch. */
12
+ lastFetched: string;
13
+ /** Last seen ETag, for conditional GETs. */
14
+ etag: string | null;
15
+ /** SHA256 of the last fetched body. */
16
+ sha256: string;
17
+ /** If true, refetch refuses to overwrite when sha256 changes. */
18
+ pinned: boolean;
19
+ /** Size in bytes of the cached body. */
20
+ sizeBytes: number;
21
+ }
22
+ export interface RegistryFile {
23
+ version: number;
24
+ remotes: RemoteEntry[];
25
+ }
26
+ export declare class RemoteRegistryError extends Error {
27
+ readonly code: string;
28
+ constructor(message: string, code: string);
29
+ }
30
+ export declare class RemoteRegistry {
31
+ private baseDir;
32
+ constructor(baseDir?: string);
33
+ private registryFile;
34
+ private cacheDir;
35
+ private cacheFile;
36
+ /**
37
+ * Ensures the base directory and cache directory exist.
38
+ * Safe to call multiple times.
39
+ */
40
+ initialize(): Promise<void>;
41
+ /**
42
+ * Reads the registry file. Returns an empty registry if the file
43
+ * doesn't exist yet.
44
+ */
45
+ load(): Promise<RegistryFile>;
46
+ /**
47
+ * Atomically writes the registry file.
48
+ */
49
+ private save;
50
+ /**
51
+ * List all registered remotes.
52
+ */
53
+ list(): Promise<RemoteEntry[]>;
54
+ /**
55
+ * Look up a single remote by name.
56
+ */
57
+ get(name: string): Promise<RemoteEntry | null>;
58
+ /**
59
+ * Register a new remote: validate the name, fetch the URL, validate
60
+ * the graph schema, write to cache, and append to the registry.
61
+ *
62
+ * Throws if the name already exists, if the URL fails to fetch, or
63
+ * if the schema validation fails.
64
+ *
65
+ * The caller is responsible for ensuring the name does not collide
66
+ * with a local graph (this module doesn't know about local graphs).
67
+ */
68
+ register(opts: {
69
+ name: string;
70
+ url: string;
71
+ source?: string;
72
+ pin?: boolean;
73
+ }): Promise<RemoteEntry>;
74
+ /**
75
+ * Refetch a registered remote. Uses ETag for conditional GET.
76
+ *
77
+ * If pinned and the SHA256 changes, throws RemoteRegistryError with
78
+ * code "PIN_VIOLATION" without overwriting the cache.
79
+ */
80
+ refresh(name: string): Promise<{
81
+ entry: RemoteEntry;
82
+ changed: boolean;
83
+ notModified: boolean;
84
+ }>;
85
+ /**
86
+ * Remove a remote from the registry and delete its cache file.
87
+ */
88
+ unregister(name: string): Promise<void>;
89
+ /**
90
+ * Load the cached graph contents for a registered remote.
91
+ * Throws if the remote is not registered or the cache file is missing.
92
+ */
93
+ loadCached(name: string): Promise<LearningGraphData>;
94
+ }
95
+ //# sourceMappingURL=remote-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-registry.d.ts","sourceRoot":"","sources":["../../src/core/remote-registry.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAIpD,MAAM,WAAW,WAAW;IAC1B,wEAAwE;IACxE,IAAI,EAAE,MAAM,CAAC;IACb,qCAAqC;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,kDAAkD;IAClD,WAAW,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,iEAAiE;IACjE,MAAM,EAAE,OAAO,CAAC;IAChB,wCAAwC;IACxC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,WAAW,EAAE,CAAC;CACxB;AAOD,qBAAa,mBAAoB,SAAQ,KAAK;aAG1B,IAAI,EAAE,MAAM;gBAD5B,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,MAAM;CAK/B;AAuBD,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,CAAC,EAAE,MAAM;IAI5B,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,SAAS;IAcjB;;;OAGG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAKjC;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,YAAY,CAAC;IAwBnC;;OAEG;YACW,IAAI;IAMlB;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAKpC;;OAEG;IACG,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAMpD;;;;;;;;;OASG;IACG,QAAQ,CAAC,IAAI,EAAE;QACnB,IAAI,EAAE,MAAM,CAAC;QACb,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,GAAG,CAAC,EAAE,OAAO,CAAC;KACf,GAAG,OAAO,CAAC,WAAW,CAAC;IA0ExB;;;;;OAKG;IACG,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QACnC,KAAK,EAAE,WAAW,CAAC;QACnB,OAAO,EAAE,OAAO,CAAC;QACjB,WAAW,EAAE,OAAO,CAAC;KACtB,CAAC;IAgFF;;OAEG;IACG,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuB7C;;;OAGG;IACG,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAwB3D"}