backpack-ontology 0.3.2 → 0.5.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.
@@ -0,0 +1,345 @@
1
+ // ============================================================
2
+ // Registry of backpacks (graph directories).
3
+ //
4
+ // A "backpack" is a named pointer to a directory of learning graphs.
5
+ // Users can own multiple backpacks (personal, work, family, a shared
6
+ // OneDrive folder, etc) and switch between them — only one is active
7
+ // at a time. All reads and writes go to the active backpack's path.
8
+ //
9
+ // On-disk config (single file):
10
+ // ~/.config/backpack/backpacks.json
11
+ // {
12
+ // "version": 2,
13
+ // "paths": [
14
+ // "/Users/noah/.local/share/backpack/graphs",
15
+ // "/Users/noah/OneDrive/work"
16
+ // ],
17
+ // "active": "/Users/noah/OneDrive/work"
18
+ // }
19
+ //
20
+ // Display names and colors are NOT stored — they're derived from the
21
+ // path on every read. Name = last path segment, with "personal" as a
22
+ // special case for the default personal graphs directory. Collisions
23
+ // get "-2", "-3" suffixes in registration order. Color is a stable
24
+ // hash of the path.
25
+ //
26
+ // Env var $BACKPACK_ACTIVE overrides the persisted active for the
27
+ // current process only (per-session isolation for power users).
28
+ //
29
+ // Auto-migration: on first load, if we see the old v1 format
30
+ // ({ version: 1, backpacks: [{ name, path, color }] }), we extract
31
+ // the paths, drop the names and colors, and rewrite the file as v2.
32
+ // The old separate active.json file (also v1) is merged in as the
33
+ // active path by looking up the path by name.
34
+ // ============================================================
35
+ import * as fs from "node:fs/promises";
36
+ import * as path from "node:path";
37
+ import * as os from "node:os";
38
+ import * as crypto from "node:crypto";
39
+ import { configDir, dataDir } from "./paths.js";
40
+ const CONFIG_VERSION = 2;
41
+ const DEFAULT_PERSONAL_NAME = "personal";
42
+ // --- Errors ---
43
+ export class BackpackRegistryError extends Error {
44
+ code;
45
+ constructor(message, code) {
46
+ super(message);
47
+ this.code = code;
48
+ this.name = "BackpackRegistryError";
49
+ }
50
+ }
51
+ // --- Derivation helpers ---
52
+ /**
53
+ * The default personal graphs path. Honors BACKPACK_DIR and XDG_DATA_HOME
54
+ * so users who customized their data directory keep it.
55
+ */
56
+ function defaultPersonalPath() {
57
+ return path.join(dataDir(), "graphs");
58
+ }
59
+ /**
60
+ * Last non-empty path segment, used as the base for the display name.
61
+ * Strips trailing separators. For `/OneDrive/work/` returns `work`.
62
+ */
63
+ function basename(p) {
64
+ const trimmed = p.replace(/[/\\]+$/, "");
65
+ const parts = trimmed.split(/[/\\]/);
66
+ const last = parts[parts.length - 1];
67
+ return last || trimmed;
68
+ }
69
+ /**
70
+ * Derive a stable 6-digit hex color from a path. Same path always
71
+ * produces the same color. Luminance clamped so the result is readable
72
+ * on both light and dark backgrounds.
73
+ */
74
+ export function colorForPath(p) {
75
+ const hash = crypto.createHash("sha256").update(p).digest();
76
+ const r = 80 + (hash[0] % 140);
77
+ const g = 80 + (hash[7] % 140);
78
+ const b = 80 + (hash[15] % 140);
79
+ return `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`;
80
+ }
81
+ /**
82
+ * Given a path and the full ordered list of paths, return the display
83
+ * name that should be used for it. Special-cases the default personal
84
+ * path to `personal`. On collision (two paths ending in the same
85
+ * segment), appends a disambiguating suffix in registration order.
86
+ */
87
+ export function deriveName(p, allPaths) {
88
+ const defaultPersonal = path.resolve(defaultPersonalPath());
89
+ if (path.resolve(p) === defaultPersonal) {
90
+ return DEFAULT_PERSONAL_NAME;
91
+ }
92
+ const base = basename(p);
93
+ // Count how many earlier paths would display with the same base name.
94
+ // The default personal path is included in the count when the base is
95
+ // `personal` — otherwise a user registering another `/whatever/personal`
96
+ // path would silently collide with the special-cased default.
97
+ let priorCount = 0;
98
+ for (const other of allPaths) {
99
+ if (other === p)
100
+ break;
101
+ const otherBase = path.resolve(other) === defaultPersonal
102
+ ? DEFAULT_PERSONAL_NAME
103
+ : basename(other);
104
+ if (otherBase === base)
105
+ priorCount++;
106
+ }
107
+ return priorCount === 0 ? base : `${base}-${priorCount + 1}`;
108
+ }
109
+ /**
110
+ * Expand a leading `~/` to the user's home directory. Does NOT do any
111
+ * other shell-like expansion (no `$VARS`, no globs).
112
+ */
113
+ function expandHome(p) {
114
+ if (p === "~")
115
+ return os.homedir();
116
+ if (p.startsWith("~/") || p.startsWith("~\\")) {
117
+ return path.join(os.homedir(), p.slice(2));
118
+ }
119
+ return p;
120
+ }
121
+ /** Normalize a user-provided path for storage: tilde-expand and resolve absolute. */
122
+ function normalizePath(p) {
123
+ return path.resolve(expandHome(p));
124
+ }
125
+ // --- File paths ---
126
+ function backpacksConfigFile() {
127
+ return path.join(configDir(), "backpacks.json");
128
+ }
129
+ function legacyActiveFile() {
130
+ return path.join(configDir(), "active.json");
131
+ }
132
+ // --- IO helpers ---
133
+ async function readJsonOrNull(p) {
134
+ try {
135
+ const raw = await fs.readFile(p, "utf8");
136
+ return JSON.parse(raw);
137
+ }
138
+ catch (err) {
139
+ if (err.code === "ENOENT")
140
+ return null;
141
+ throw err;
142
+ }
143
+ }
144
+ async function writeJsonAtomic(p, data) {
145
+ await fs.mkdir(path.dirname(p), { recursive: true });
146
+ const tmp = `${p}.tmp`;
147
+ await fs.writeFile(tmp, JSON.stringify(data, null, 2), "utf8");
148
+ await fs.rename(tmp, p);
149
+ }
150
+ // --- Migration ---
151
+ /**
152
+ * Convert a v1 file in memory to v2 shape, reading the separate
153
+ * legacy active.json to find the active entry. If the legacy active
154
+ * file is missing or points at an unknown name, default to the first
155
+ * path.
156
+ */
157
+ async function migrateV1ToV2(v1) {
158
+ const paths = v1.backpacks.map((b) => normalizePath(b.path));
159
+ let active = paths[0] ?? "";
160
+ const legacyActive = await readJsonOrNull(legacyActiveFile());
161
+ if (legacyActive && typeof legacyActive.name === "string") {
162
+ const match = v1.backpacks.find((b) => b.name === legacyActive.name);
163
+ if (match)
164
+ active = normalizePath(match.path);
165
+ }
166
+ return { version: CONFIG_VERSION, paths, active };
167
+ }
168
+ // --- Public API ---
169
+ /**
170
+ * Load the registry, seeding with the default personal path if the file
171
+ * doesn't exist, and auto-migrating from v1 format if it does. Always
172
+ * returns a well-formed v2 config. Safe to call many times.
173
+ */
174
+ export async function loadRegistry() {
175
+ const raw = await readJsonOrNull(backpacksConfigFile());
176
+ if (raw === null) {
177
+ // First run: seed with the personal default
178
+ const seeded = {
179
+ version: CONFIG_VERSION,
180
+ paths: [defaultPersonalPath()],
181
+ active: defaultPersonalPath(),
182
+ };
183
+ await writeJsonAtomic(backpacksConfigFile(), seeded);
184
+ return seeded;
185
+ }
186
+ if (typeof raw === "object" &&
187
+ raw !== null &&
188
+ "paths" in raw &&
189
+ Array.isArray(raw.paths)) {
190
+ // Already v2
191
+ const cfg = raw;
192
+ // Defensive: ensure `active` is one of the paths, else pick the first
193
+ if (!cfg.paths.includes(cfg.active)) {
194
+ cfg.active = cfg.paths[0] ?? defaultPersonalPath();
195
+ }
196
+ return {
197
+ version: CONFIG_VERSION,
198
+ paths: cfg.paths.slice(),
199
+ active: cfg.active,
200
+ };
201
+ }
202
+ if (typeof raw === "object" &&
203
+ raw !== null &&
204
+ "backpacks" in raw &&
205
+ Array.isArray(raw.backpacks)) {
206
+ // v1 format — migrate, write the v2 file, and remove the legacy
207
+ // active.json file to keep the config directory tidy.
208
+ const migrated = await migrateV1ToV2(raw);
209
+ await writeJsonAtomic(backpacksConfigFile(), migrated);
210
+ await fs.rm(legacyActiveFile()).catch(() => { });
211
+ return migrated;
212
+ }
213
+ // Garbage — treat as first run
214
+ const seeded = {
215
+ version: CONFIG_VERSION,
216
+ paths: [defaultPersonalPath()],
217
+ active: defaultPersonalPath(),
218
+ };
219
+ await writeJsonAtomic(backpacksConfigFile(), seeded);
220
+ return seeded;
221
+ }
222
+ /** List all registered backpacks as derived entries. */
223
+ export async function listBackpacks() {
224
+ const cfg = await loadRegistry();
225
+ return cfg.paths.map((p) => ({
226
+ path: p,
227
+ name: deriveName(p, cfg.paths),
228
+ color: colorForPath(p),
229
+ }));
230
+ }
231
+ /**
232
+ * Look up a backpack by either its absolute path or its derived name.
233
+ * Returns null if no match. Name lookup is case-sensitive.
234
+ */
235
+ export async function getBackpack(pathOrName) {
236
+ const entries = await listBackpacks();
237
+ // Try exact path match first (after normalization)
238
+ const resolved = normalizePath(pathOrName);
239
+ const byPath = entries.find((e) => e.path === resolved);
240
+ if (byPath)
241
+ return byPath;
242
+ // Try derived name match
243
+ const byName = entries.find((e) => e.name === pathOrName);
244
+ return byName ?? null;
245
+ }
246
+ /**
247
+ * Register a new backpack at the given path. Creates the directory
248
+ * if missing. Idempotent: if the path is already registered, returns
249
+ * the existing entry without duplicating.
250
+ */
251
+ export async function registerBackpack(rawPath) {
252
+ const resolved = normalizePath(rawPath);
253
+ const cfg = await loadRegistry();
254
+ // Idempotent
255
+ if (cfg.paths.includes(resolved)) {
256
+ const entry = (await listBackpacks()).find((e) => e.path === resolved);
257
+ if (entry)
258
+ return entry;
259
+ }
260
+ // Make sure the directory is usable
261
+ try {
262
+ await fs.mkdir(resolved, { recursive: true });
263
+ }
264
+ catch (err) {
265
+ throw new BackpackRegistryError(`cannot create or access path "${resolved}": ${err.message}`, "PATH_UNUSABLE");
266
+ }
267
+ cfg.paths.push(resolved);
268
+ await writeJsonAtomic(backpacksConfigFile(), cfg);
269
+ const all = cfg.paths;
270
+ return {
271
+ path: resolved,
272
+ name: deriveName(resolved, all),
273
+ color: colorForPath(resolved),
274
+ };
275
+ }
276
+ /**
277
+ * Unregister a backpack by path or derived name. Does NOT delete its
278
+ * data. Refuses to unregister the last remaining backpack. If the
279
+ * removed backpack was active, the first remaining becomes active.
280
+ */
281
+ export async function unregisterBackpack(pathOrName) {
282
+ const cfg = await loadRegistry();
283
+ const entry = await getBackpack(pathOrName);
284
+ if (!entry) {
285
+ throw new BackpackRegistryError(`backpack "${pathOrName}" is not registered`, "NOT_FOUND");
286
+ }
287
+ if (cfg.paths.length <= 1) {
288
+ throw new BackpackRegistryError(`cannot unregister the last remaining backpack`, "LAST_BACKPACK");
289
+ }
290
+ cfg.paths = cfg.paths.filter((p) => p !== entry.path);
291
+ if (cfg.active === entry.path) {
292
+ cfg.active = cfg.paths[0];
293
+ }
294
+ await writeJsonAtomic(backpacksConfigFile(), cfg);
295
+ }
296
+ /**
297
+ * Return the currently active backpack. Resolution order:
298
+ * 1. $BACKPACK_ACTIVE env var (accepts path or derived name)
299
+ * 2. config.active
300
+ * 3. first entry in the registry (fallback)
301
+ */
302
+ export async function getActiveBackpack() {
303
+ const cfg = await loadRegistry();
304
+ const entries = await listBackpacks();
305
+ if (entries.length === 0) {
306
+ // Shouldn't happen — loadRegistry seeds — but guard.
307
+ const fallback = defaultPersonalPath();
308
+ cfg.paths.push(fallback);
309
+ cfg.active = fallback;
310
+ await writeJsonAtomic(backpacksConfigFile(), cfg);
311
+ return {
312
+ path: fallback,
313
+ name: DEFAULT_PERSONAL_NAME,
314
+ color: colorForPath(fallback),
315
+ };
316
+ }
317
+ // 1. Env var override
318
+ const envInput = process.env.BACKPACK_ACTIVE;
319
+ if (envInput) {
320
+ const match = await getBackpack(envInput);
321
+ if (match)
322
+ return match;
323
+ }
324
+ // 2. Config active
325
+ const configMatch = entries.find((e) => e.path === cfg.active);
326
+ if (configMatch)
327
+ return configMatch;
328
+ // 3. First
329
+ return entries[0];
330
+ }
331
+ /**
332
+ * Persist a new active backpack. Accepts either a path or a derived
333
+ * name. Does NOT touch the env var override.
334
+ */
335
+ export async function setActiveBackpack(pathOrName) {
336
+ const cfg = await loadRegistry();
337
+ const entry = await getBackpack(pathOrName);
338
+ if (!entry) {
339
+ throw new BackpackRegistryError(`backpack "${pathOrName}" is not registered`, "NOT_FOUND");
340
+ }
341
+ cfg.active = entry.path;
342
+ await writeJsonAtomic(backpacksConfigFile(), cfg);
343
+ return entry;
344
+ }
345
+ //# sourceMappingURL=backpacks-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backpacks-registry.js","sourceRoot":"","sources":["../../src/core/backpacks-registry.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -7,6 +7,8 @@ export type { Node, Edge, LearningGraphData, LearningGraphMetadata, LearningGrap
7
7
  export { JsonFileBackend } from "./storage/json-file-backend.js";
8
8
  export { EventSourcedBackend, ConcurrencyError, LOCK_FRESH_MS, } from "./storage/event-sourced-backend.js";
9
9
  export type { LockInfo } from "./storage/event-sourced-backend.js";
10
+ export { loadRegistry, listBackpacks, getBackpack, registerBackpack, unregisterBackpack, getActiveBackpack, setActiveBackpack, colorForPath, deriveName, BackpackRegistryError, } from "./core/backpacks-registry.js";
11
+ export type { BackpackEntry } from "./core/backpacks-registry.js";
10
12
  export { RemoteRegistry, RemoteRegistryError } from "./core/remote-registry.js";
11
13
  export type { RemoteEntry } from "./core/remote-registry.js";
12
14
  export { remoteFetch, RemoteFetchError, isBlockedIp } from "./core/remote-fetch.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,YAAY,EACV,IAAI,EACJ,IAAI,EACJ,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,WAAW,EACX,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,aAAa,EACb,cAAc,EACd,aAAa,GACd,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,GACd,MAAM,oCAAoC,CAAC;AAC5C,YAAY,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAC;AAGnE,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChF,YAAY,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACpF,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AACpF,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAGtG,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,iBAAiB,EAAE,QAAQ,IAAI,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGlH,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAGpH,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,YAAY,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,YAAY,EACV,IAAI,EACJ,IAAI,EACJ,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,WAAW,EACX,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,aAAa,EACb,cAAc,EACd,aAAa,GACd,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,GACd,MAAM,oCAAoC,CAAC;AAC5C,YAAY,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAC;AAGnE,OAAO,EACL,YAAY,EACZ,aAAa,EACb,WAAW,EACX,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,UAAU,EACV,qBAAqB,GACtB,MAAM,8BAA8B,CAAC;AACtC,YAAY,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAGlE,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChF,YAAY,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACpF,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AACpF,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAGtG,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,iBAAiB,EAAE,QAAQ,IAAI,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGlH,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAGpH,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,YAAY,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/index.js CHANGED
@@ -7,6 +7,8 @@ export { loadConfig } from "./core/config.js";
7
7
  // Storage backends
8
8
  export { JsonFileBackend } from "./storage/json-file-backend.js";
9
9
  export { EventSourcedBackend, ConcurrencyError, LOCK_FRESH_MS, } from "./storage/event-sourced-backend.js";
10
+ // Backpacks registry (multi-backpack management)
11
+ export { loadRegistry, listBackpacks, getBackpack, registerBackpack, unregisterBackpack, getActiveBackpack, setActiveBackpack, colorForPath, deriveName, BackpackRegistryError, } from "./core/backpacks-registry.js";
10
12
  // Remote graph registry (subscriptions to graphs hosted at HTTPS URLs)
11
13
  export { RemoteRegistry, RemoteRegistryError } from "./core/remote-registry.js";
12
14
  export { remoteFetch, RemoteFetchError, isBlockedIp } from "./core/remote-fetch.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAE7E,OAAO;AACP,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAkB9C,mBAAmB;AACnB,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,GACd,MAAM,oCAAoC,CAAC;AAG5C,uEAAuE;AACvE,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAEhF,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAEpF,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAEtG,YAAY;AACZ,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,iBAAiB,EAAE,QAAQ,IAAI,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAElH,mBAAmB;AACnB,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAEpH,qBAAqB;AACrB,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAE7E,OAAO;AACP,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAkB9C,mBAAmB;AACnB,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,GACd,MAAM,oCAAoC,CAAC;AAG5C,iDAAiD;AACjD,OAAO,EACL,YAAY,EACZ,aAAa,EACb,WAAW,EACX,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,UAAU,EACV,qBAAqB,GACtB,MAAM,8BAA8B,CAAC;AAGtC,uEAAuE;AACvE,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAEhF,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAEpF,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAEtG,YAAY;AACZ,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,iBAAiB,EAAE,QAAQ,IAAI,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAElH,mBAAmB;AACnB,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAEpH,qBAAqB;AACrB,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAgBpE,kDAAkD;AAClD,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,0DAA0D;AAC1D,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,KAAK,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,2DAA2D;AAC3D,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,KAAK,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,iBAAiB,GAAG,sBAAsB,GAAG,sBAAsB,CAAC;AAChF,MAAM,MAAM,oBAAoB,GAAG,mBAAmB,GAAG,iBAAiB,CAAC;AAE3E;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,MAAM,CAAC,EAAE,oBAAoB,GAC5B,OAAO,CAAC,SAAS,CAAC,CAqEpB"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAgBpE,kDAAkD;AAClD,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,0DAA0D;AAC1D,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,KAAK,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,2DAA2D;AAC3D,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,KAAK,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,iBAAiB,GAAG,sBAAsB,GAAG,sBAAsB,CAAC;AAChF,MAAM,MAAM,oBAAoB,GAAG,mBAAmB,GAAG,iBAAiB,CAAC;AAE3E;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,MAAM,CAAC,EAAE,oBAAoB,GAC5B,OAAO,CAAC,SAAS,CAAC,CAoFpB"}
@@ -13,6 +13,7 @@ import { registerBulkTools } from "./tools/bulk-tools.js";
13
13
  import { registerVersionTools } from "./tools/version-tools.js";
14
14
  import { registerIntelligenceTools } from "./tools/intelligence-tools.js";
15
15
  import { registerRemoteTools } from "./tools/remote-tools.js";
16
+ import { registerBackpackTools } from "./tools/backpack-tools.js";
16
17
  /**
17
18
  * Create and configure the MCP server.
18
19
  *
@@ -21,12 +22,22 @@ import { registerRemoteTools } from "./tools/remote-tools.js";
21
22
  * - "app": Backpack App cloud API (via static token or OAuth2 SSO)
22
23
  */
23
24
  export async function createMcpServer(config) {
24
- let backend;
25
+ let backpack;
25
26
  if (!config || config.mode === "local") {
26
- backend = new JsonFileBackend(config?.dataDir);
27
+ // Local mode: resolve the active backpack from the registry. First
28
+ // run seeds a default "personal" entry pointing at the user's
29
+ // existing graphs directory, so upgrades from 0.3.x are transparent.
30
+ // A custom `config.dataDir` is honored only when explicitly passed —
31
+ // mostly used by tests. Normal users go through the registry.
32
+ if (config?.dataDir) {
33
+ backpack = new Backpack(new JsonFileBackend(config.dataDir));
34
+ }
35
+ else {
36
+ backpack = await Backpack.fromActiveBackpack();
37
+ }
27
38
  }
28
39
  else if ("token" in config) {
29
- backend = new BackpackAppBackend(config.url, config.token);
40
+ backpack = new Backpack(new BackpackAppBackend(config.url, config.token));
30
41
  }
31
42
  else {
32
43
  // OAuth2 SSO — opens browser on first run, caches tokens
@@ -36,9 +47,8 @@ export async function createMcpServer(config) {
36
47
  .digest("hex")
37
48
  .slice(0, 12);
38
49
  const oauth = new OAuthClient(config.clientId, config.issuerUrl, cacheKey);
39
- backend = new BackpackAppBackend(config.url, () => oauth.getAccessToken());
50
+ backpack = new Backpack(new BackpackAppBackend(config.url, () => oauth.getAccessToken()));
40
51
  }
41
- const backpack = new Backpack(backend);
42
52
  await backpack.initialize();
43
53
  // Initialize telemetry (non-blocking, fails silently)
44
54
  try {
@@ -79,6 +89,11 @@ Be selective — not every conversation needs to be captured. Focus on knowledge
79
89
  registerVersionTools(server, backpack);
80
90
  registerIntelligenceTools(server, backpack);
81
91
  registerRemoteTools(server, backpack, remoteRegistry);
92
+ // Local mode gets backpack (meta) management tools — cloud mode
93
+ // doesn't need them since the cloud backend is a single target.
94
+ if (!config || config.mode === "local") {
95
+ registerBackpackTools(server, backpack);
96
+ }
82
97
  return server;
83
98
  }
84
99
  //# sourceMappingURL=server.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { Backpack } from "../../core/backpack.js";
3
+ /**
4
+ * Tools that manage the set of registered backpacks and which one is
5
+ * currently active. These live in the meta-layer — they don't touch
6
+ * learning graph content, only the pointer to where graphs live.
7
+ */
8
+ export declare function registerBackpackTools(server: McpServer, backpack: Backpack): void;
9
+ //# sourceMappingURL=backpack-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backpack-tools.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/backpack-tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AASvD;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,SAAS,EACjB,QAAQ,EAAE,QAAQ,GACjB,IAAI,CAiMN"}