@justfortytwo/installer 0.1.1 → 0.1.3

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 CHANGED
@@ -43,16 +43,21 @@ gitignored `.fortytwo/identity.json`; neither is ever committed.
43
43
  | Verb | What it does |
44
44
  |------------|--------------|
45
45
  | `init` | Install any missing engine packages, then capture your assistant's name + owner details (interactive, or via flags/env for CI). Writes `.fortytwo/identity.json`, secrets + `ALLOWED_CHAT_IDS` to `.env`, wires `.mcp.json`, renders the persona, provisions local infra (pulls the embedder model, migrates the memory DB), and records the installed version set. |
46
- | `pair` | Issue a one-time `/login` pairing code to bind another chat/device to a channel. |
46
+ | `pair` | Issue a one-time `/login` pairing code, persisted to the bridge's bindings db so the separately-running bridge can redeem it (the dynamic counterpart to the static `ALLOWED_CHAT_IDS` allowlist). |
47
47
  | `doctor` | Health-check the engine: assert the gate's `POLICY_SCHEMA_VERSION` and memory's `MEMORY_TOOL_CONTRACT_VERSION` match what this CLI expects, confirm the memory DB is migrated, cross-check installed sibling versions against the declared compatibility ranges, and check the embedder model is pulled (warn-only). |
48
- | `update` | Resolve the latest in-range version of each engine package, install, then run `doctor` to verify. On failure it points you to `rollback`. |
49
- | `rollback` | Restore the previous version set recorded before the last `update`. |
48
+ | `update` | *(pending)* Resolve the latest in-range version of each engine package, install, then run `doctor` to verify. |
49
+ | `rollback` | *(pending)* Restore the previous version set recorded before the last `update`. |
50
50
  | `enrich` | Capture more answers to deepen the persona, then re-render (no clobber). |
51
- | `forget` | Redact or remove specific memories from the memory store. |
51
+ | `forget` | Permanently delete memories selected by `--id` / `--query` (semantic) / `--tag` / `--source` / `--since`/`--until` — previewed and confirmed (or `--yes`). Owner-only: it deletes via a library API, never exposed to the assistant. |
52
52
  | `unbind` | Revoke a channel binding (un-pair a chat / drop it from the allowlist). |
53
53
 
54
54
  Run `fortytwo <verb> --help` for verb-specific options.
55
55
 
56
+ > **Status:** `init`, `pair`, `doctor`, `forget`, and `unbind` are functional.
57
+ > `update`/`rollback` validate state and print guidance, but their npm
58
+ > resolve/install step is not wired yet (now that the packages are published,
59
+ > it's the next piece). `enrich` is still a stub.
60
+
56
61
  ## Update safety
57
62
 
58
63
  Distribution follows a **semver-ranges, latest-compatible** policy — there is no
@@ -69,7 +74,9 @@ your machine. The standard model is `qwen3-embedding:0.6b`, served by Ollama;
69
74
 
70
75
  ## Requirements
71
76
 
72
- - Node.js >= 18
77
+ - Node.js >= 20 (Node 20 or 22 LTS recommended — the memory engine's native
78
+ `better-sqlite3` ships prebuilt binaries for LTS releases; newer/odd versions
79
+ may fall back to a slow source compile)
73
80
  - [Ollama](https://ollama.com/) for the local embedder (optional but
74
81
  recommended — the engine degrades gracefully without it)
75
82
 
@@ -1,2 +1,16 @@
1
- export declare function runForget(_argv: string[]): Promise<number>;
1
+ export interface ForgetFlags {
2
+ id?: number;
3
+ query?: string;
4
+ since?: string;
5
+ until?: string;
6
+ tag?: string;
7
+ source?: string;
8
+ yes?: boolean;
9
+ limit: number;
10
+ dbPath: string;
11
+ }
12
+ export declare function parseForgetArgs(argv: string[]): ForgetFlags;
13
+ /** True when at least one selector was given (refuse a blanket delete). */
14
+ export declare function hasForgetSelector(f: ForgetFlags): boolean;
15
+ export declare function runForget(argv: string[]): Promise<number>;
2
16
  //# sourceMappingURL=forget.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"forget.d.ts","sourceRoot":"","sources":["../../src/commands/forget.ts"],"names":[],"mappings":"AAOA,wBAAsB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAahE"}
1
+ {"version":3,"file":"forget.d.ts","sourceRoot":"","sources":["../../src/commands/forget.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,WAAW;IAC1B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,WAAW,CAoB3D;AAED,2EAA2E;AAC3E,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,WAAW,GAAG,OAAO,CAEzD;AAWD,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA0D/D"}
@@ -1,19 +1,124 @@
1
- // forget — redact/remove specific memories from the memory MCP store.
1
+ // forget — remove specific memories from the memory store.
2
2
  //
3
- // The data-hygiene verb: the owner asks the assistant to forget something
4
- // (a person, a topic, a date range, a specific entry). This is a privileged
5
- // operation against the canonical memory store, distinct from the assistant's
6
- // own turn-time memory writes.
7
- export async function runForget(_argv) {
8
- // BLOCKED: forget needs a deletion/redaction surface on @justfortytwo/memory
9
- // (delete from the store AND the derived FTS + embedding indexes so recall
10
- // can't resurface a removed entry). The memory package does not expose one
11
- // yet, so this command cannot honor a forget request safely. When that API
12
- // lands, wire selectors here: --id, --query (semantic match + confirm),
13
- // --since/--until (range), --entity, with a confirmation summary + --yes.
14
- process.stderr.write('forget: not yet available it requires a deletion/redaction API in ' +
15
- '@justfortytwo/memory (not implemented). Until then, no command can remove ' +
16
- 'stored memories; do not assume a forget succeeded.\n');
17
- return 2;
3
+ // The data-hygiene verb: the OWNER asks to forget something (a specific entry,
4
+ // a topic, a date range, a source). This is a privileged operation against the
5
+ // canonical store deliberately a CLI command and NOT an MCP tool, so the
6
+ // assistant can never be tricked by injected content into deleting memories.
7
+ // Selectors resolve candidates, which are previewed and confirmed before a hard
8
+ // delete (row + vector + FTS) via @justfortytwo/memory's deleteByIds.
9
+ import { createInterface } from 'node:readline/promises';
10
+ import { loadMemory } from '../engine.js';
11
+ import { EMBED_MODEL, DEFAULT_DB_PATH } from './init.js';
12
+ export function parseForgetArgs(argv) {
13
+ const f = { limit: 50, dbPath: process.env.DB_PATH ?? DEFAULT_DB_PATH };
14
+ for (let i = 0; i < argv.length; i++) {
15
+ const a = argv[i];
16
+ if (a === undefined)
17
+ continue;
18
+ if (a === '--yes' || a === '-y') {
19
+ f.yes = true;
20
+ continue;
21
+ }
22
+ if (!a.startsWith('--'))
23
+ continue;
24
+ const v = argv[++i] ?? '';
25
+ switch (a.slice(2)) {
26
+ case 'id':
27
+ f.id = Number(v);
28
+ break;
29
+ case 'query':
30
+ f.query = v;
31
+ break;
32
+ case 'since':
33
+ f.since = v;
34
+ break;
35
+ case 'until':
36
+ f.until = v;
37
+ break;
38
+ case 'tag':
39
+ f.tag = v;
40
+ break;
41
+ case 'source':
42
+ f.source = v;
43
+ break;
44
+ case 'limit':
45
+ f.limit = Number(v) || 50;
46
+ break;
47
+ case 'db-path':
48
+ f.dbPath = v;
49
+ break;
50
+ }
51
+ }
52
+ return f;
53
+ }
54
+ /** True when at least one selector was given (refuse a blanket delete). */
55
+ export function hasForgetSelector(f) {
56
+ return f.id !== undefined || !!f.query || !!f.tag || !!f.source || !!f.since || !!f.until;
57
+ }
58
+ export async function runForget(argv) {
59
+ const f = parseForgetArgs(argv);
60
+ if (!hasForgetSelector(f)) {
61
+ process.stderr.write('forget: specify what to forget — --id <n>, --query <text>, --tag/--source <v>, or --since/--until <date>.\n');
62
+ return 2;
63
+ }
64
+ const mem = (await loadMemory());
65
+ if (!mem || typeof mem.deleteByIds !== 'function') {
66
+ process.stderr.write('forget: @justfortytwo/memory (>=0.1.1, with deleteByIds) is not installed.\n');
67
+ return 2;
68
+ }
69
+ const h = mem.openDb(f.dbPath);
70
+ try {
71
+ let rows;
72
+ if (f.id !== undefined) {
73
+ rows = (await mem.query(h, { liveOnly: false, limit: 100000 })).filter((r) => r.id === f.id);
74
+ }
75
+ else if (f.query) {
76
+ const embedder = process.env.EMBED_MODEL
77
+ ? new mem.OllamaEmbedder(process.env.EMBED_MODEL, process.env.OLLAMA_BASE_URL)
78
+ : new mem.FakeEmbedder();
79
+ rows = await mem.recall(h, embedder, f.query, f.limit);
80
+ }
81
+ else {
82
+ rows = await mem.query(h, {
83
+ source: f.source, tag: f.tag, since: f.since, until: f.until, liveOnly: false, limit: f.limit,
84
+ });
85
+ }
86
+ if (rows.length === 0) {
87
+ process.stdout.write('forget: no matching memories.\n');
88
+ return 0;
89
+ }
90
+ process.stdout.write(`forget: ${rows.length} match(es):\n`);
91
+ for (const r of rows.slice(0, 10)) {
92
+ process.stdout.write(` [${r.id}] ${r.content.replace(/\s+/g, ' ').slice(0, 80)}\n`);
93
+ }
94
+ if (rows.length > 10)
95
+ process.stdout.write(` … and ${rows.length - 10} more\n`);
96
+ if (!f.yes) {
97
+ if (!process.stdin.isTTY) {
98
+ process.stderr.write('forget: refusing to delete without confirmation — re-run with --yes.\n');
99
+ return 2;
100
+ }
101
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
102
+ const ans = (await rl.question(`Permanently forget ${rows.length} memory(ies)? [y/N] `)).trim().toLowerCase();
103
+ rl.close();
104
+ if (ans !== 'y' && ans !== 'yes') {
105
+ process.stdout.write('forget: aborted; nothing deleted.\n');
106
+ return 0;
107
+ }
108
+ }
109
+ const n = mem.deleteByIds(h, rows.map((r) => r.id));
110
+ process.stdout.write(`✓ forgot ${n} memory(ies).\n`);
111
+ return 0;
112
+ }
113
+ finally {
114
+ try {
115
+ await h.k?.destroy?.();
116
+ }
117
+ catch { /* best-effort */ }
118
+ try {
119
+ h.close?.();
120
+ }
121
+ catch { /* best-effort */ }
122
+ }
18
123
  }
19
124
  //# sourceMappingURL=forget.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"forget.js","sourceRoot":"","sources":["../../src/commands/forget.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,EAAE;AACF,0EAA0E;AAC1E,4EAA4E;AAC5E,8EAA8E;AAC9E,+BAA+B;AAE/B,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,KAAe;IAC7C,6EAA6E;IAC7E,2EAA2E;IAC3E,2EAA2E;IAC3E,2EAA2E;IAC3E,wEAAwE;IACxE,0EAA0E;IAC1E,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,sEAAsE;QACtE,4EAA4E;QAC5E,sDAAsD,CACvD,CAAC;IACF,OAAO,CAAC,CAAC;AACX,CAAC"}
1
+ {"version":3,"file":"forget.js","sourceRoot":"","sources":["../../src/commands/forget.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,15 @@
1
- export declare function runPair(_argv: string[]): Promise<number>;
1
+ export interface PairFlags {
2
+ /** Which channel to pair. Defaults to telegram (the only adapter at v0). */
3
+ channel: string;
4
+ /** Optional TTL override (seconds) for the code. */
5
+ ttlSeconds?: number;
6
+ }
7
+ export declare function parsePairArgs(argv: string[]): PairFlags;
8
+ /**
9
+ * The bindings db the bridge uses — MUST match @justfortytwo/telegram's bridge
10
+ * (`<root>/state/telegram-bindings.db`, overridable via TELEGRAM_BINDINGS_DB),
11
+ * or a code minted here would land in a db the bridge never reads.
12
+ */
13
+ export declare function resolveBindingsDbPath(root: string): string;
14
+ export declare function runPair(argv: string[]): Promise<number>;
2
15
  //# sourceMappingURL=pair.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pair.d.ts","sourceRoot":"","sources":["../../src/commands/pair.ts"],"names":[],"mappings":"AAkBA,wBAAsB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAe9D"}
1
+ {"version":3,"file":"pair.d.ts","sourceRoot":"","sources":["../../src/commands/pair.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,SAAS;IACxB,4EAA4E;IAC5E,OAAO,EAAE,MAAM,CAAC;IAChB,oDAAoD;IACpD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,SAAS,CAUvD;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI1D;AASD,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAqB7D"}
@@ -1,26 +1,57 @@
1
1
  // pair — issue a one-time `/login` pairing code for a channel.
2
2
  //
3
- // Unlike init (which also provisions), pair is the standalone "bind another
4
- // device/chat" verb. It mints a short-lived code; the owner sends `/login <code>`
5
- // from the target chat, and the channel adapter confirms the binding (adding the
6
- // chat to the allowlist and recording it in identity.json's `channels`).
7
- //
8
- // This is the lifecycle counterpart to `unbind`.
9
- export async function runPair(_argv) {
10
- // BLOCKED: dynamic /login pairing requires that an issued challenge be
11
- // redeemable by the SEPARATELY-RUNNING bridge. TelegramAdapter currently keeps
12
- // pending challenges in an in-memory Map, so a code minted by this CLI process
13
- // is invisible to the bridge process — cross-process pairing can't work until
14
- // @justfortytwo/telegram persists challenges in its store. The path that works
15
- // today is the static allowlist: set ALLOWED_CHAT_IDS in .env (fortytwo init
16
- // writes it), which the bridge authorizes against directly.
17
- void resolveChannel;
18
- process.stderr.write('pair: dynamic /login pairing is not available yet (it needs cross-process ' +
19
- 'challenge persistence in @justfortytwo/telegram). For now, authorize a chat ' +
20
- 'by adding its id to ALLOWED_CHAT_IDS in .env.\n');
21
- return 2;
3
+ // Mints a short-lived code and PERSISTS it (via @justfortytwo/telegram's
4
+ // store-backed challenges) to the SAME bindings db the running bridge reads.
5
+ // The owner sends `/login <code>` from the target chat; the bridge a separate
6
+ // process redeems the persisted challenge and records the binding. This is the
7
+ // dynamic counterpart to the static ALLOWED_CHAT_IDS allowlist, and the
8
+ // lifecycle counterpart to `unbind`.
9
+ import { resolve, dirname } from 'node:path';
10
+ import { mkdirSync } from 'node:fs';
11
+ import { loadTelegram } from '../engine.js';
12
+ export function parsePairArgs(argv) {
13
+ const f = { channel: 'telegram' };
14
+ for (let i = 0; i < argv.length; i++) {
15
+ const a = argv[i];
16
+ if (a === undefined || !a.startsWith('--'))
17
+ continue;
18
+ const v = argv[++i] ?? '';
19
+ if (a === '--channel')
20
+ f.channel = v || 'telegram';
21
+ else if (a === '--ttl')
22
+ f.ttlSeconds = Number(v) || undefined;
23
+ }
24
+ return f;
25
+ }
26
+ /**
27
+ * The bindings db the bridge uses — MUST match @justfortytwo/telegram's bridge
28
+ * (`<root>/state/telegram-bindings.db`, overridable via TELEGRAM_BINDINGS_DB),
29
+ * or a code minted here would land in a db the bridge never reads.
30
+ */
31
+ export function resolveBindingsDbPath(root) {
32
+ return process.env.TELEGRAM_BINDINGS_DB
33
+ ? resolve(root, process.env.TELEGRAM_BINDINGS_DB)
34
+ : resolve(root, 'state', 'telegram-bindings.db');
22
35
  }
23
- function resolveChannel(_flags, _identity) {
24
- return 'telegram';
36
+ export async function runPair(argv) {
37
+ const flags = parsePairArgs(argv);
38
+ if (flags.channel !== 'telegram') {
39
+ process.stderr.write(`pair: unsupported channel "${flags.channel}" (only telegram at v0).\n`);
40
+ return 2;
41
+ }
42
+ const tg = (await loadTelegram());
43
+ if (!tg || typeof tg.SqliteBindingStore !== 'function' || typeof tg.TelegramAdapter !== 'function') {
44
+ process.stderr.write('pair: @justfortytwo/telegram (>=0.1.1, with persisted challenges) is not installed.\n');
45
+ return 2;
46
+ }
47
+ const dbPath = resolveBindingsDbPath(process.cwd());
48
+ mkdirSync(dirname(dbPath), { recursive: true });
49
+ const store = new tg.SqliteBindingStore(dbPath);
50
+ const adapter = new tg.TelegramAdapter(store, flags.ttlSeconds ? { ttlSeconds: flags.ttlSeconds } : {});
51
+ const { code, ttl } = adapter.issueChallenge('owner');
52
+ process.stdout.write(`Pairing code: ${code}\n`);
53
+ process.stdout.write(`From your Telegram chat, send: /login ${code}\n`);
54
+ process.stdout.write(`(valid ${Math.round(ttl / 60)} min — the running bridge binds that chat to you)\n`);
55
+ return 0;
25
56
  }
26
57
  //# sourceMappingURL=pair.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pair.js","sourceRoot":"","sources":["../../src/commands/pair.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,EAAE;AACF,4EAA4E;AAC5E,kFAAkF;AAClF,iFAAiF;AACjF,yEAAyE;AACzE,EAAE;AACF,iDAAiD;AAWjD,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,KAAe;IAC3C,uEAAuE;IACvE,+EAA+E;IAC/E,+EAA+E;IAC/E,8EAA8E;IAC9E,+EAA+E;IAC/E,6EAA6E;IAC7E,4DAA4D;IAC5D,KAAK,cAAc,CAAC;IACpB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,4EAA4E;QAC5E,8EAA8E;QAC9E,iDAAiD,CAClD,CAAC;IACF,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,cAAc,CAAC,MAAiB,EAAE,SAA0B;IACnE,OAAO,UAAU,CAAC;AACpB,CAAC"}
1
+ {"version":3,"file":"pair.js","sourceRoot":"","sources":["../../src/commands/pair.ts"],"names":[],"mappings":"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"}
package/dist/engine.d.ts CHANGED
@@ -15,7 +15,13 @@ export declare const loadMemory: () => Promise<{
15
15
  runMigrations?: (k: unknown) => Promise<void>;
16
16
  } | null>;
17
17
  export declare const loadTelegram: () => Promise<Record<string, unknown> | null>;
18
- /** Installed version of a sibling (its package.json `version`), or null. */
18
+ /**
19
+ * Installed version of a sibling (its package.json `version`), or null. Walks up
20
+ * ancestor `node_modules` dirs exactly like Node's resolver — pure fs, so it is
21
+ * immune to import-only `exports` maps (which defeat require.resolve) and to
22
+ * bundled test runners where import.meta.resolve is unavailable. Matches where
23
+ * loadSibling's dynamic import would find the package.
24
+ */
19
25
  export declare function readInstalledVersion(spec: string): string | null;
20
26
  /** The CLI's declared compat ranges (package.json `fortytwo.compat`). */
21
27
  export declare function readSelfCompatRanges(): Record<string, string>;
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAcA,yEAAyE;AACzE,wBAAsB,WAAW,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAM9F;AAED,eAAO,MAAM,QAAQ;4BAA+C,MAAM;SAAyB,CAAC;AACpG,eAAO,MAAM,UAAU;mCAEY,MAAM;aAG5B,CAAC,IAAI,EAAE,MAAM,KAAK;QAAE,CAAC,EAAE;YAAE,MAAM,EAAE;gBAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;aAAE,CAAA;SAAE,CAAA;KAAE;oBAC1E,CAAC,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC;SACrB,CAAC;AAC7B,eAAO,MAAM,YAAY,+CAA8C,CAAC;AAExE,4EAA4E;AAC5E,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAyChE;AAoBD,yEAAyE;AACzE,wBAAgB,oBAAoB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAI7D;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAetE;AAED,oFAAoF;AACpF,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CASjF;AAED,MAAM,MAAM,cAAc,GAAG,IAAI,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,CAAC;AAE1E;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAehF"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAWA,yEAAyE;AACzE,wBAAsB,WAAW,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAM9F;AAED,eAAO,MAAM,QAAQ;4BAA+C,MAAM;SAAyB,CAAC;AACpG,eAAO,MAAM,UAAU;mCAEY,MAAM;aAG5B,CAAC,IAAI,EAAE,MAAM,KAAK;QAAE,CAAC,EAAE;YAAE,MAAM,EAAE;gBAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;aAAE,CAAA;SAAE,CAAA;KAAE;oBAC1E,CAAC,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC;SACrB,CAAC;AAC7B,eAAO,MAAM,YAAY,+CAA8C,CAAC;AAExE;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAgBhE;AAoBD,yEAAyE;AACzE,wBAAgB,oBAAoB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAI7D;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAetE;AAED,oFAAoF;AACpF,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CASjF;AAED,MAAM,MAAM,cAAc,GAAG,IAAI,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,CAAC;AAE1E;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAehF"}
package/dist/engine.js CHANGED
@@ -4,11 +4,9 @@
4
4
  // reaches them via dynamic import, so a partial install (e.g. gate-only) never
5
5
  // crashes the CLI — a missing sibling makes the dependent command/check report
6
6
  // "not installed" instead of throwing.
7
- import { createRequire } from 'node:module';
8
7
  import { readFileSync, existsSync } from 'node:fs';
9
8
  import { fileURLToPath } from 'node:url';
10
9
  import { dirname, join, parse } from 'node:path';
11
- const require = createRequire(import.meta.url);
12
10
  /** Dynamically import an engine sibling; null if it is not installed. */
13
11
  export async function loadSibling(spec) {
14
12
  try {
@@ -21,56 +19,30 @@ export async function loadSibling(spec) {
21
19
  export const loadGate = () => loadSibling('@justfortytwo/gate');
22
20
  export const loadMemory = () => loadSibling('@justfortytwo/memory');
23
21
  export const loadTelegram = () => loadSibling('@justfortytwo/telegram');
24
- /** Installed version of a sibling (its package.json `version`), or null. */
22
+ /**
23
+ * Installed version of a sibling (its package.json `version`), or null. Walks up
24
+ * ancestor `node_modules` dirs exactly like Node's resolver — pure fs, so it is
25
+ * immune to import-only `exports` maps (which defeat require.resolve) and to
26
+ * bundled test runners where import.meta.resolve is unavailable. Matches where
27
+ * loadSibling's dynamic import would find the package.
28
+ */
25
29
  export function readInstalledVersion(spec) {
26
- // Prefer the direct package.json subpath; packages with a restrictive
27
- // `exports` map block it, so fall back to resolving the entry and walking up
28
- // to the package.json whose `name` matches the spec.
29
- const readVersion = (pkgPath) => {
30
- try {
31
- return JSON.parse(readFileSync(pkgPath, 'utf8')).version ?? null;
32
- }
33
- catch {
34
- return null;
35
- }
36
- };
37
- try {
38
- return readVersion(require.resolve(`${spec}/package.json`));
39
- }
40
- catch {
41
- /* exports-restricted — fall through */
42
- }
43
- try {
44
- // Resolve the entry with the ESM resolver (matches the package's `import`
45
- // condition — the same path loadSibling uses), then walk up to the
46
- // package.json whose name matches. CJS require.resolve can't see
47
- // import-only exports maps, so prefer import.meta.resolve.
48
- let entry = null;
49
- const esmResolve = import.meta.resolve;
50
- if (esmResolve) {
30
+ const segments = spec.split('/'); // e.g. ['@justfortytwo', 'gate']
31
+ let dir = dirname(fileURLToPath(import.meta.url));
32
+ const root = parse(dir).root;
33
+ while (true) {
34
+ const candidate = join(dir, 'node_modules', ...segments, 'package.json');
35
+ if (existsSync(candidate)) {
51
36
  try {
52
- entry = fileURLToPath(esmResolve(spec));
37
+ return JSON.parse(readFileSync(candidate, 'utf8')).version ?? null;
53
38
  }
54
- catch { /* try CJS next */ }
55
- }
56
- if (!entry)
57
- entry = require.resolve(spec);
58
- let dir = dirname(entry);
59
- const root = parse(dir).root;
60
- while (true) {
61
- const candidate = join(dir, 'package.json');
62
- if (existsSync(candidate)) {
63
- const json = JSON.parse(readFileSync(candidate, 'utf8'));
64
- if (json.name === spec)
65
- return json.version ?? null;
66
- }
67
- if (dir === root)
39
+ catch {
68
40
  return null;
69
- dir = dirname(dir);
41
+ }
70
42
  }
71
- }
72
- catch {
73
- return null;
43
+ if (dir === root)
44
+ return null;
45
+ dir = dirname(dir);
74
46
  }
75
47
  }
76
48
  /** Walk up from this module to find the installer's own package.json. */
@@ -1 +1 @@
1
- {"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@justfortytwo/installer",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "All-in-one installer and lifecycle CLI for fortytwo — scaffolds the persona surface and provisions the npm engine (memory MCP, safety gate, channel adapters, embedder).",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -14,7 +14,7 @@
14
14
  },
15
15
  "type": "module",
16
16
  "engines": {
17
- "node": ">=18"
17
+ "node": ">=20"
18
18
  },
19
19
  "bin": {
20
20
  "create-fortytwo": "dist/index.js",
@@ -67,10 +67,10 @@
67
67
  "fortytwo": {
68
68
  "comment": "Compatibility contract this CLI version was authored against. doctor cross-checks the *installed* sibling packages against these ranges; update/rollback record the resolved set into .fortytwo/state.json. TODO(wire): bump these as sibling contracts evolve.",
69
69
  "compat": {
70
- "@justfortytwo/memory": "^0.1.0",
70
+ "@justfortytwo/memory": "^0.1.1",
71
71
  "@justfortytwo/gate": "^0.1.0",
72
72
  "@justfortytwo/persona": "^0.1.0",
73
- "@justfortytwo/telegram": "^0.1.0"
73
+ "@justfortytwo/telegram": "^0.1.1"
74
74
  }
75
75
  },
76
76
  "publishConfig": {