backpack-ontology 0.4.0 → 0.5.1
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/README.md +21 -5
- package/dist/core/backpacks-registry.d.ts +48 -34
- package/dist/core/backpacks-registry.d.ts.map +1 -1
- package/dist/core/backpacks-registry.js +241 -147
- package/dist/core/backpacks-registry.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/tools/backpack-tools.d.ts.map +1 -1
- package/dist/mcp/tools/backpack-tools.js +19 -18
- package/dist/mcp/tools/backpack-tools.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -272,22 +272,38 @@ Across sessions, the real value is that the graph exists at all. It's built once
|
|
|
272
272
|
| `npx backpack-ontology@latest` | Start the Backpack Local MCP server |
|
|
273
273
|
| `claude mcp add backpack-app ... --transport sse` | Connect to Backpack App cloud MCP |
|
|
274
274
|
| `npx -p backpack-ontology@latest backpack-sync` | Upload local learning graphs to Backpack App |
|
|
275
|
-
| `npx backpack-viewer` | Open the graph visualizer (http://localhost:5173) |
|
|
275
|
+
| `npx backpack-viewer@latest` | Open the graph visualizer (http://localhost:5173). Always include `@latest` — `npx backpack-viewer` without the version suffix reuses a cached older version. |
|
|
276
276
|
| `npx -p backpack-ontology@latest backpack-init` | Remove any leftover Backpack hooks from `.claude/settings.json` |
|
|
277
277
|
|
|
278
278
|
### Multiple backpacks
|
|
279
279
|
|
|
280
|
-
A **backpack** is a
|
|
280
|
+
A **backpack** is a directory of learning graphs. Most users start with one (`personal`, auto-created at `~/.local/share/backpack/graphs/`) and never touch the registry. But you can register additional backpacks — a shared OneDrive folder, a project-specific directory, a network-mounted share — and **switch between them** with a single command. Only one backpack is active at a time; all reads and writes go to the active one.
|
|
281
|
+
|
|
282
|
+
Backpacks are stored as a list of paths in `~/.config/backpack/backpacks.json`:
|
|
283
|
+
|
|
284
|
+
```json
|
|
285
|
+
{
|
|
286
|
+
"version": 2,
|
|
287
|
+
"paths": [
|
|
288
|
+
"/Users/me/.local/share/backpack/graphs",
|
|
289
|
+
"/Users/me/OneDrive/work",
|
|
290
|
+
"/Users/me/Dropbox/family-backpack"
|
|
291
|
+
],
|
|
292
|
+
"active": "/Users/me/OneDrive/work"
|
|
293
|
+
}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
The file is hand-editable — you can add paths directly if you prefer. Display names are derived from the last segment of each path (`work`, `family-backpack`), and colors are hashed from the path. No manual naming or coloring required.
|
|
281
297
|
|
|
282
298
|
Say to Claude:
|
|
283
299
|
|
|
284
|
-
> "Register a backpack
|
|
300
|
+
> "Register a backpack at /Users/me/OneDrive/work and switch to it."
|
|
285
301
|
|
|
286
302
|
> "Which backpack am I in?"
|
|
287
303
|
|
|
288
|
-
> "Switch to
|
|
304
|
+
> "Switch to personal."
|
|
289
305
|
|
|
290
|
-
The viewer shows the active backpack in the sidebar header with a colored indicator — click it to switch.
|
|
306
|
+
The viewer shows the active backpack in the sidebar header with a colored indicator — click it to switch. Per-user state (machine ID, telemetry, remote cache) stays at the default config location; only the graphs directory is shared.
|
|
291
307
|
|
|
292
308
|
### Tools
|
|
293
309
|
|
|
@@ -1,61 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A registered backpack as the user sees it. The path is the canonical
|
|
3
|
+
* identity. Name and color are derived from the path — not stored.
|
|
4
|
+
*/
|
|
1
5
|
export interface BackpackEntry {
|
|
2
|
-
/**
|
|
3
|
-
name: string;
|
|
4
|
-
/** Absolute path to a directory that will hold learning graphs. */
|
|
6
|
+
/** Absolute filesystem path to the graphs directory. */
|
|
5
7
|
path: string;
|
|
6
|
-
/**
|
|
8
|
+
/** Display name derived from the last path segment. */
|
|
9
|
+
name: string;
|
|
10
|
+
/** 6-digit hex color derived from a hash of the path. */
|
|
7
11
|
color: string;
|
|
8
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* On-disk config file shape (v2).
|
|
15
|
+
*/
|
|
9
16
|
export interface BackpacksConfigFile {
|
|
10
17
|
version: number;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
export interface ActiveConfigFile {
|
|
14
|
-
version: number;
|
|
15
|
-
name: string;
|
|
18
|
+
paths: string[];
|
|
19
|
+
active: string;
|
|
16
20
|
}
|
|
17
21
|
export declare class BackpackRegistryError extends Error {
|
|
18
22
|
readonly code: string;
|
|
19
23
|
constructor(message: string, code: string);
|
|
20
24
|
}
|
|
21
25
|
/**
|
|
22
|
-
* Derive a stable 6-digit hex color from a
|
|
23
|
-
*
|
|
24
|
-
*
|
|
26
|
+
* Derive a stable 6-digit hex color from a path. Same path always
|
|
27
|
+
* produces the same color. Luminance clamped so the result is readable
|
|
28
|
+
* on both light and dark backgrounds.
|
|
29
|
+
*/
|
|
30
|
+
export declare function colorForPath(p: string): string;
|
|
31
|
+
/**
|
|
32
|
+
* Given a path and the full ordered list of paths, return the display
|
|
33
|
+
* name that should be used for it. Special-cases the default personal
|
|
34
|
+
* path to `personal`. On collision (two paths ending in the same
|
|
35
|
+
* segment), appends a disambiguating suffix in registration order.
|
|
25
36
|
*/
|
|
26
|
-
export declare function
|
|
37
|
+
export declare function deriveName(p: string, allPaths: string[]): string;
|
|
27
38
|
/**
|
|
28
|
-
* Load the registry, seeding the default
|
|
29
|
-
*
|
|
39
|
+
* Load the registry, seeding with the default personal path if the file
|
|
40
|
+
* doesn't exist, and auto-migrating from v1 format if it does. Always
|
|
41
|
+
* returns a well-formed v2 config. Safe to call many times.
|
|
30
42
|
*/
|
|
31
43
|
export declare function loadRegistry(): Promise<BackpacksConfigFile>;
|
|
44
|
+
/** List all registered backpacks as derived entries. */
|
|
32
45
|
export declare function listBackpacks(): Promise<BackpackEntry[]>;
|
|
33
|
-
export declare function getBackpack(name: string): Promise<BackpackEntry | null>;
|
|
34
46
|
/**
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
|
|
47
|
+
* Look up a backpack by either its absolute path or its derived name.
|
|
48
|
+
* Returns null if no match. Name lookup is case-sensitive.
|
|
49
|
+
*/
|
|
50
|
+
export declare function getBackpack(pathOrName: string): Promise<BackpackEntry | null>;
|
|
51
|
+
/**
|
|
52
|
+
* Register a new backpack at the given path. Creates the directory
|
|
53
|
+
* if missing. Idempotent: if the path is already registered, returns
|
|
54
|
+
* the existing entry without duplicating.
|
|
38
55
|
*/
|
|
39
|
-
export declare function registerBackpack(
|
|
56
|
+
export declare function registerBackpack(rawPath: string): Promise<BackpackEntry>;
|
|
40
57
|
/**
|
|
41
|
-
* Unregister a backpack
|
|
42
|
-
* the last remaining backpack
|
|
43
|
-
*
|
|
58
|
+
* Unregister a backpack by path or derived name. Does NOT delete its
|
|
59
|
+
* data. Refuses to unregister the last remaining backpack. If the
|
|
60
|
+
* removed backpack was active, the first remaining becomes active.
|
|
44
61
|
*/
|
|
45
|
-
export declare function unregisterBackpack(
|
|
62
|
+
export declare function unregisterBackpack(pathOrName: string): Promise<void>;
|
|
46
63
|
/**
|
|
47
|
-
* Return the
|
|
48
|
-
* 1. $BACKPACK_ACTIVE env var (
|
|
49
|
-
* 2.
|
|
50
|
-
* 3. first entry in the registry
|
|
51
|
-
*
|
|
52
|
-
* Loads (and seeds) the registry as a side effect, so a fresh install
|
|
53
|
-
* always has something to return.
|
|
64
|
+
* Return the currently active backpack. Resolution order:
|
|
65
|
+
* 1. $BACKPACK_ACTIVE env var (accepts path or derived name)
|
|
66
|
+
* 2. config.active
|
|
67
|
+
* 3. first entry in the registry (fallback)
|
|
54
68
|
*/
|
|
55
69
|
export declare function getActiveBackpack(): Promise<BackpackEntry>;
|
|
56
70
|
/**
|
|
57
|
-
* Persist a new active backpack
|
|
58
|
-
* Does
|
|
71
|
+
* Persist a new active backpack. Accepts either a path or a derived
|
|
72
|
+
* name. Does NOT touch the env var override.
|
|
59
73
|
*/
|
|
60
|
-
export declare function setActiveBackpack(
|
|
74
|
+
export declare function setActiveBackpack(pathOrName: string): Promise<BackpackEntry>;
|
|
61
75
|
//# sourceMappingURL=backpacks-registry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backpacks-registry.d.ts","sourceRoot":"","sources":["../../src/core/backpacks-registry.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"backpacks-registry.d.ts","sourceRoot":"","sources":["../../src/core/backpacks-registry.ts"],"names":[],"mappings":"AA2CA;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAiBD,qBAAa,qBAAsB,SAAQ,KAAK;aAG5B,IAAI,EAAE,MAAM;gBAD5B,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,MAAM;CAK/B;AAuBD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAM9C;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAsBhE;AAqED;;;;GAIG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAuDjE;AAED,wDAAwD;AACxD,wBAAsB,aAAa,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAO9D;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CASnF;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CA6B9E;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAoB1E;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,aAAa,CAAC,CA6BhE;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAYlF"}
|
|
@@ -1,32 +1,44 @@
|
|
|
1
1
|
// ============================================================
|
|
2
2
|
// Registry of backpacks (graph directories).
|
|
3
3
|
//
|
|
4
|
-
// A "backpack"
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
// active backpack's graphs directory.
|
|
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.
|
|
9
8
|
//
|
|
10
|
-
//
|
|
11
|
-
// ~/.config/backpack/backpacks.json
|
|
12
|
-
//
|
|
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
|
+
// }
|
|
13
19
|
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
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.
|
|
17
25
|
//
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
//
|
|
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.
|
|
21
34
|
// ============================================================
|
|
22
35
|
import * as fs from "node:fs/promises";
|
|
23
36
|
import * as path from "node:path";
|
|
24
37
|
import * as os from "node:os";
|
|
25
38
|
import * as crypto from "node:crypto";
|
|
26
39
|
import { configDir, dataDir } from "./paths.js";
|
|
27
|
-
const CONFIG_VERSION =
|
|
28
|
-
const
|
|
29
|
-
const NAME_RE = /^[a-z0-9][a-z0-9_-]{0,31}$/;
|
|
40
|
+
const CONFIG_VERSION = 2;
|
|
41
|
+
const DEFAULT_PERSONAL_NAME = "personal";
|
|
30
42
|
// --- Errors ---
|
|
31
43
|
export class BackpackRegistryError extends Error {
|
|
32
44
|
code;
|
|
@@ -36,45 +48,88 @@ export class BackpackRegistryError extends Error {
|
|
|
36
48
|
this.name = "BackpackRegistryError";
|
|
37
49
|
}
|
|
38
50
|
}
|
|
39
|
-
// ---
|
|
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
|
+
}
|
|
40
59
|
/**
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* indicator so users don't have to pick colors manually.
|
|
60
|
+
* Last non-empty path segment, used as the base for the display name.
|
|
61
|
+
* Strips trailing separators. For `/OneDrive/work/` returns `work`.
|
|
44
62
|
*/
|
|
45
|
-
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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();
|
|
50
76
|
const r = 80 + (hash[0] % 140);
|
|
51
77
|
const g = 80 + (hash[7] % 140);
|
|
52
78
|
const b = 80 + (hash[15] % 140);
|
|
53
79
|
return `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`;
|
|
54
80
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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++;
|
|
58
106
|
}
|
|
107
|
+
return priorCount === 0 ? base : `${base}-${priorCount + 1}`;
|
|
59
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
|
+
*/
|
|
60
113
|
function expandHome(p) {
|
|
61
|
-
if (p
|
|
62
|
-
return
|
|
114
|
+
if (p === "~")
|
|
115
|
+
return os.homedir();
|
|
116
|
+
if (p.startsWith("~/") || p.startsWith("~\\")) {
|
|
117
|
+
return path.join(os.homedir(), p.slice(2));
|
|
63
118
|
}
|
|
64
119
|
return p;
|
|
65
120
|
}
|
|
121
|
+
/** Normalize a user-provided path for storage: tilde-expand and resolve absolute. */
|
|
66
122
|
function normalizePath(p) {
|
|
67
|
-
|
|
68
|
-
return path.resolve(expanded);
|
|
123
|
+
return path.resolve(expandHome(p));
|
|
69
124
|
}
|
|
70
125
|
// --- File paths ---
|
|
71
126
|
function backpacksConfigFile() {
|
|
72
127
|
return path.join(configDir(), "backpacks.json");
|
|
73
128
|
}
|
|
74
|
-
function
|
|
129
|
+
function legacyActiveFile() {
|
|
75
130
|
return path.join(configDir(), "active.json");
|
|
76
131
|
}
|
|
77
|
-
// --- IO ---
|
|
132
|
+
// --- IO helpers ---
|
|
78
133
|
async function readJsonOrNull(p) {
|
|
79
134
|
try {
|
|
80
135
|
const raw = await fs.readFile(p, "utf8");
|
|
@@ -92,160 +147,199 @@ async function writeJsonAtomic(p, data) {
|
|
|
92
147
|
await fs.writeFile(tmp, JSON.stringify(data, null, 2), "utf8");
|
|
93
148
|
await fs.rename(tmp, p);
|
|
94
149
|
}
|
|
95
|
-
// ---
|
|
150
|
+
// --- Migration ---
|
|
96
151
|
/**
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
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.
|
|
100
156
|
*/
|
|
101
|
-
function
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
name
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}
|
|
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 };
|
|
110
167
|
}
|
|
111
168
|
// --- Public API ---
|
|
112
169
|
/**
|
|
113
|
-
* Load the registry, seeding the default
|
|
114
|
-
*
|
|
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.
|
|
115
173
|
*/
|
|
116
174
|
export async function loadRegistry() {
|
|
117
|
-
const
|
|
118
|
-
if (
|
|
119
|
-
|
|
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
|
|
120
214
|
const seeded = {
|
|
121
215
|
version: CONFIG_VERSION,
|
|
122
|
-
|
|
216
|
+
paths: [defaultPersonalPath()],
|
|
217
|
+
active: defaultPersonalPath(),
|
|
123
218
|
};
|
|
124
219
|
await writeJsonAtomic(backpacksConfigFile(), seeded);
|
|
125
|
-
// Seed active too, but only if missing (don't clobber)
|
|
126
|
-
const activeExists = (await readJsonOrNull(activeConfigFile())) !== null;
|
|
127
|
-
if (!activeExists) {
|
|
128
|
-
await writeJsonAtomic(activeConfigFile(), {
|
|
129
|
-
version: CONFIG_VERSION,
|
|
130
|
-
name: DEFAULT_NAME,
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
220
|
return seeded;
|
|
134
221
|
}
|
|
222
|
+
/** List all registered backpacks as derived entries. */
|
|
135
223
|
export async function listBackpacks() {
|
|
136
|
-
const
|
|
137
|
-
return
|
|
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
|
+
}));
|
|
138
230
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
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;
|
|
142
245
|
}
|
|
143
246
|
/**
|
|
144
|
-
* Register a new backpack
|
|
145
|
-
*
|
|
146
|
-
*
|
|
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.
|
|
147
250
|
*/
|
|
148
|
-
export async function registerBackpack(
|
|
149
|
-
|
|
150
|
-
const
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
//
|
|
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
|
|
158
261
|
try {
|
|
159
|
-
await fs.mkdir(
|
|
262
|
+
await fs.mkdir(resolved, { recursive: true });
|
|
160
263
|
}
|
|
161
264
|
catch (err) {
|
|
162
|
-
throw new BackpackRegistryError(`cannot create or access path "${
|
|
265
|
+
throw new BackpackRegistryError(`cannot create or access path "${resolved}": ${err.message}`, "PATH_UNUSABLE");
|
|
163
266
|
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
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),
|
|
168
274
|
};
|
|
169
|
-
registry.backpacks.push(entry);
|
|
170
|
-
await writeJsonAtomic(backpacksConfigFile(), registry);
|
|
171
|
-
return entry;
|
|
172
275
|
}
|
|
173
276
|
/**
|
|
174
|
-
* Unregister a backpack
|
|
175
|
-
* the last remaining backpack
|
|
176
|
-
*
|
|
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.
|
|
177
280
|
*/
|
|
178
|
-
export async function unregisterBackpack(
|
|
179
|
-
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
if (registry.backpacks.length <= 1) {
|
|
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) {
|
|
186
288
|
throw new BackpackRegistryError(`cannot unregister the last remaining backpack`, "LAST_BACKPACK");
|
|
187
289
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
const active = await readJsonOrNull(activeConfigFile());
|
|
192
|
-
if (active && active.name === name) {
|
|
193
|
-
await writeJsonAtomic(activeConfigFile(), {
|
|
194
|
-
version: CONFIG_VERSION,
|
|
195
|
-
name: registry.backpacks[0].name,
|
|
196
|
-
});
|
|
290
|
+
cfg.paths = cfg.paths.filter((p) => p !== entry.path);
|
|
291
|
+
if (cfg.active === entry.path) {
|
|
292
|
+
cfg.active = cfg.paths[0];
|
|
197
293
|
}
|
|
294
|
+
await writeJsonAtomic(backpacksConfigFile(), cfg);
|
|
198
295
|
}
|
|
199
296
|
/**
|
|
200
|
-
* Return the
|
|
201
|
-
* 1. $BACKPACK_ACTIVE env var (
|
|
202
|
-
* 2.
|
|
203
|
-
* 3. first entry in the registry
|
|
204
|
-
*
|
|
205
|
-
* Loads (and seeds) the registry as a side effect, so a fresh install
|
|
206
|
-
* always has something to return.
|
|
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)
|
|
207
301
|
*/
|
|
208
302
|
export async function getActiveBackpack() {
|
|
209
|
-
const
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
// Env var points at an unknown name — ignore it rather than crash.
|
|
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
|
+
};
|
|
223
316
|
}
|
|
224
|
-
//
|
|
225
|
-
const
|
|
226
|
-
if (
|
|
227
|
-
const match =
|
|
317
|
+
// 1. Env var override
|
|
318
|
+
const envInput = process.env.BACKPACK_ACTIVE;
|
|
319
|
+
if (envInput) {
|
|
320
|
+
const match = await getBackpack(envInput);
|
|
228
321
|
if (match)
|
|
229
322
|
return match;
|
|
230
323
|
}
|
|
231
|
-
//
|
|
232
|
-
|
|
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];
|
|
233
330
|
}
|
|
234
331
|
/**
|
|
235
|
-
* Persist a new active backpack
|
|
236
|
-
* Does
|
|
332
|
+
* Persist a new active backpack. Accepts either a path or a derived
|
|
333
|
+
* name. Does NOT touch the env var override.
|
|
237
334
|
*/
|
|
238
|
-
export async function setActiveBackpack(
|
|
239
|
-
|
|
240
|
-
const
|
|
241
|
-
const entry = registry.backpacks.find((b) => b.name === name);
|
|
335
|
+
export async function setActiveBackpack(pathOrName) {
|
|
336
|
+
const cfg = await loadRegistry();
|
|
337
|
+
const entry = await getBackpack(pathOrName);
|
|
242
338
|
if (!entry) {
|
|
243
|
-
throw new BackpackRegistryError(`backpack "${
|
|
339
|
+
throw new BackpackRegistryError(`backpack "${pathOrName}" is not registered`, "NOT_FOUND");
|
|
244
340
|
}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
name,
|
|
248
|
-
});
|
|
341
|
+
cfg.active = entry.path;
|
|
342
|
+
await writeJsonAtomic(backpacksConfigFile(), cfg);
|
|
249
343
|
return entry;
|
|
250
344
|
}
|
|
251
345
|
//# sourceMappingURL=backpacks-registry.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backpacks-registry.js","sourceRoot":"","sources":["../../src/core/backpacks-registry.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,6CAA6C;AAC7C,EAAE;AACF,
|
|
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,7 +7,7 @@ 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,
|
|
10
|
+
export { loadRegistry, listBackpacks, getBackpack, registerBackpack, unregisterBackpack, getActiveBackpack, setActiveBackpack, colorForPath, deriveName, BackpackRegistryError, } from "./core/backpacks-registry.js";
|
|
11
11
|
export type { BackpackEntry } from "./core/backpacks-registry.js";
|
|
12
12
|
export { RemoteRegistry, RemoteRegistryError } from "./core/remote-registry.js";
|
|
13
13
|
export type { RemoteEntry } from "./core/remote-registry.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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,EACL,YAAY,EACZ,aAAa,EACb,WAAW,EACX,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,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"}
|
|
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
|
@@ -8,7 +8,7 @@ export { loadConfig } from "./core/config.js";
|
|
|
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
10
|
// Backpacks registry (multi-backpack management)
|
|
11
|
-
export { loadRegistry, listBackpacks, getBackpack, registerBackpack, unregisterBackpack, getActiveBackpack, setActiveBackpack,
|
|
11
|
+
export { loadRegistry, listBackpacks, getBackpack, registerBackpack, unregisterBackpack, getActiveBackpack, setActiveBackpack, colorForPath, deriveName, BackpackRegistryError, } from "./core/backpacks-registry.js";
|
|
12
12
|
// Remote graph registry (subscriptions to graphs hosted at HTTPS URLs)
|
|
13
13
|
export { RemoteRegistry, RemoteRegistryError } from "./core/remote-registry.js";
|
|
14
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,iDAAiD;AACjD,OAAO,EACL,YAAY,EACZ,aAAa,EACb,WAAW,EACX,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,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
|
+
{"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":"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,
|
|
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"}
|
|
@@ -9,26 +9,23 @@ import { registerBackpack, unregisterBackpack, listBackpacks, getActiveBackpack,
|
|
|
9
9
|
export function registerBackpackTools(server, backpack) {
|
|
10
10
|
server.registerTool("backpack_register", {
|
|
11
11
|
title: "Register a Backpack",
|
|
12
|
-
description: "Add a
|
|
12
|
+
description: "Add a backpack — a pointer to a graphs directory that lets the user switch between multiple collections of learning graphs (personal, a shared OneDrive folder, a project-specific folder, etc). The display name is derived from the last segment of the path (e.g. '/Users/me/OneDrive/work' shows as 'work'). The path is created if it doesn't exist. Registering an already-registered path is a no-op. Does not switch to the new backpack unless activate=true.",
|
|
13
13
|
inputSchema: {
|
|
14
|
-
name: z
|
|
15
|
-
.string()
|
|
16
|
-
.describe("Short unique name for this backpack (kebab-case, e.g. 'work', 'family', 'project-alpha')"),
|
|
17
14
|
path: z
|
|
18
15
|
.string()
|
|
19
|
-
.describe("Absolute or tilde-expanded path to
|
|
16
|
+
.describe("Absolute or tilde-expanded path to the directory that will hold learning graphs (e.g. '~/OneDrive/work', '/Users/me/Dropbox/family-backpack', '/Volumes/share/team-backpack')"),
|
|
20
17
|
activate: z
|
|
21
18
|
.boolean()
|
|
22
19
|
.optional()
|
|
23
20
|
.describe("If true, switch the active backpack to this new one immediately after registering"),
|
|
24
21
|
},
|
|
25
|
-
}, async ({
|
|
22
|
+
}, async ({ path, activate }) => {
|
|
26
23
|
try {
|
|
27
|
-
const entry = await registerBackpack(
|
|
24
|
+
const entry = await registerBackpack(path);
|
|
28
25
|
let switchedTo = null;
|
|
29
26
|
if (activate) {
|
|
30
|
-
await backpack.switchBackpack(
|
|
31
|
-
switchedTo = name;
|
|
27
|
+
await backpack.switchBackpack(entry.path);
|
|
28
|
+
switchedTo = entry.name;
|
|
32
29
|
}
|
|
33
30
|
trackEvent("tool_call", { tool: "backpack_register" });
|
|
34
31
|
const text = switchedTo !== null
|
|
@@ -47,11 +44,11 @@ export function registerBackpackTools(server, backpack) {
|
|
|
47
44
|
});
|
|
48
45
|
server.registerTool("backpack_switch", {
|
|
49
46
|
title: "Switch Active Backpack",
|
|
50
|
-
description: "Change which backpack is currently active. All subsequent reads and writes go to the new backpack's graphs directory. The previous backpack's data is untouched and can be switched back to at any time.",
|
|
47
|
+
description: "Change which backpack is currently active. All subsequent reads and writes go to the new backpack's graphs directory. The previous backpack's data is untouched and can be switched back to at any time. Accepts either a derived display name (e.g. 'work') or an absolute path.",
|
|
51
48
|
inputSchema: {
|
|
52
49
|
name: z
|
|
53
50
|
.string()
|
|
54
|
-
.describe("
|
|
51
|
+
.describe("Display name OR absolute path of the registered backpack to switch to"),
|
|
55
52
|
},
|
|
56
53
|
}, async ({ name }) => {
|
|
57
54
|
try {
|
|
@@ -133,19 +130,23 @@ export function registerBackpackTools(server, backpack) {
|
|
|
133
130
|
});
|
|
134
131
|
server.registerTool("backpack_unregister", {
|
|
135
132
|
title: "Unregister a Backpack",
|
|
136
|
-
description: "Remove a backpack from the registry. Does NOT delete any data — the graphs directory at the backpack's path is left alone. Refuses to unregister the last remaining backpack. If the removed backpack was active, the first remaining backpack becomes active automatically.",
|
|
133
|
+
description: "Remove a backpack from the registry. Does NOT delete any data — the graphs directory at the backpack's path is left alone. Refuses to unregister the last remaining backpack. If the removed backpack was active, the first remaining backpack becomes active automatically. Accepts either a display name or an absolute path.",
|
|
137
134
|
inputSchema: {
|
|
138
|
-
name: z
|
|
135
|
+
name: z
|
|
136
|
+
.string()
|
|
137
|
+
.describe("Display name OR absolute path of the backpack to unregister"),
|
|
139
138
|
},
|
|
140
139
|
}, async ({ name }) => {
|
|
141
140
|
try {
|
|
142
|
-
await unregisterBackpack(name);
|
|
143
|
-
// If we just unregistered the active one, the registry switched
|
|
144
|
-
// for us — sync the Backpack instance with the new active state.
|
|
145
141
|
const current = backpack.getActiveBackpackEntry();
|
|
146
|
-
|
|
142
|
+
const wasActive = current &&
|
|
143
|
+
(current.name === name || current.path === name);
|
|
144
|
+
await unregisterBackpack(name);
|
|
145
|
+
if (wasActive) {
|
|
146
|
+
// Registry auto-switched to the first remaining — sync the
|
|
147
|
+
// Backpack instance to match.
|
|
147
148
|
const nowActive = await getActiveBackpack();
|
|
148
|
-
await backpack.switchBackpack(nowActive.
|
|
149
|
+
await backpack.switchBackpack(nowActive.path);
|
|
149
150
|
}
|
|
150
151
|
trackEvent("tool_call", { tool: "backpack_unregister" });
|
|
151
152
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backpack-tools.js","sourceRoot":"","sources":["../../../src/mcp/tools/backpack-tools.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,aAAa,EACb,iBAAiB,GAClB,MAAM,kCAAkC,CAAC;AAE1C;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CACnC,MAAiB,EACjB,QAAkB;IAElB,MAAM,CAAC,YAAY,CACjB,mBAAmB,EACnB;QACE,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EACT,
|
|
1
|
+
{"version":3,"file":"backpack-tools.js","sourceRoot":"","sources":["../../../src/mcp/tools/backpack-tools.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "backpack-ontology",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "A persistent learning graph engine for Claude Code via MCP — structured knowledge that carries forward across sessions",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Noah Irzinger",
|