@justfortytwo/installer 0.1.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.
- package/LICENSE +21 -0
- package/README.md +70 -0
- package/dist/commands/doctor.d.ts +36 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +126 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/enrich.d.ts +2 -0
- package/dist/commands/enrich.d.ts.map +1 -0
- package/dist/commands/enrich.js +26 -0
- package/dist/commands/enrich.js.map +1 -0
- package/dist/commands/forget.d.ts +2 -0
- package/dist/commands/forget.d.ts.map +1 -0
- package/dist/commands/forget.js +19 -0
- package/dist/commands/forget.js.map +1 -0
- package/dist/commands/init.d.ts +48 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +284 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/pair.d.ts +2 -0
- package/dist/commands/pair.d.ts.map +1 -0
- package/dist/commands/pair.js +26 -0
- package/dist/commands/pair.js.map +1 -0
- package/dist/commands/rollback.d.ts +2 -0
- package/dist/commands/rollback.d.ts.map +1 -0
- package/dist/commands/rollback.js +32 -0
- package/dist/commands/rollback.js.map +1 -0
- package/dist/commands/unbind.d.ts +16 -0
- package/dist/commands/unbind.d.ts.map +1 -0
- package/dist/commands/unbind.js +67 -0
- package/dist/commands/unbind.js.map +1 -0
- package/dist/commands/update.d.ts +2 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +60 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/engine.d.ts +37 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +170 -0
- package/dist/engine.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +106 -0
- package/dist/index.js.map +1 -0
- package/dist/render.d.ts +78 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +113 -0
- package/dist/render.js.map +1 -0
- package/dist/state.d.ts +58 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +93 -0
- package/dist/state.js.map +1 -0
- package/package.json +79 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Enrico Deleo
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# @justfortytwo/installer
|
|
2
|
+
|
|
3
|
+
The all-in-one installer and lifecycle CLI for **fortytwo** — a personal
|
|
4
|
+
assistant built on Claude Code. One package ships two bins:
|
|
5
|
+
|
|
6
|
+
- **`create-fortytwo`** — the install-time alias (`npm create fortytwo` /
|
|
7
|
+
`npx create-fortytwo`). With no verb, it runs `init`.
|
|
8
|
+
- **`fortytwo`** — the everyday lifecycle alias for the verbs below.
|
|
9
|
+
|
|
10
|
+
## The two-surface model
|
|
11
|
+
|
|
12
|
+
fortytwo is delivered as **two surfaces**, and this CLI is the single
|
|
13
|
+
operator interface over both:
|
|
14
|
+
|
|
15
|
+
1. **The npm engine.** The reusable machinery — the memory MCP server, the
|
|
16
|
+
safety gate, the channel adapters, and the local embedder — published as
|
|
17
|
+
`@justfortytwo/*` packages and wired in as Claude Code plugins. This is
|
|
18
|
+
shared, versioned code.
|
|
19
|
+
2. **The scaffolded persona.** `CLAUDE.md` + `context/*` — who the assistant is
|
|
20
|
+
and who it serves. This is **not** a plugin. It is per-user, personal, and
|
|
21
|
+
gitignored. The CLI **scaffolds** it by rendering the `@justfortytwo/persona`
|
|
22
|
+
package's `templates/` (guided by its `manifest.json`) against your captured
|
|
23
|
+
answers in `.fortytwo/identity.json`. Re-rendering is idempotent and never
|
|
24
|
+
clobbers fields you've captured or hand-edited.
|
|
25
|
+
|
|
26
|
+
Secrets live only in a gitignored `.env`; your captured identity lives in the
|
|
27
|
+
gitignored `.fortytwo/identity.json`; neither is ever committed.
|
|
28
|
+
|
|
29
|
+
## Verbs
|
|
30
|
+
|
|
31
|
+
| Verb | What it does |
|
|
32
|
+
|------------|--------------|
|
|
33
|
+
| `init` | Capture your assistant's name + owner details (interactive, or via flags/env for CI). Writes `.fortytwo/identity.json`, secrets to `.env`, renders the persona, provisions local infra (pulls the embedder model, migrates the memory DB), records the installed version set, and issues a pairing code. |
|
|
34
|
+
| `pair` | Issue a one-time `/login` pairing code to bind another chat/device to a channel. |
|
|
35
|
+
| `doctor` | Health-check the engine: boot the memory MCP and assert its tool contract, fire a synthetic event at the safety gate, confirm DB migrations are applied, check the embedder model is pulled, and cross-check installed sibling versions against the declared compatibility ranges. |
|
|
36
|
+
| `update` | Resolve the latest in-range version of each engine package, install, then run `doctor` to verify. On failure it points you to `rollback`. |
|
|
37
|
+
| `rollback` | Restore the previous version set recorded before the last `update`. |
|
|
38
|
+
| `enrich` | Capture more answers to deepen the persona, then re-render (no clobber). |
|
|
39
|
+
| `forget` | Redact or remove specific memories from the memory store. |
|
|
40
|
+
| `unbind` | Revoke a channel binding (un-pair a chat / drop it from the allowlist). |
|
|
41
|
+
|
|
42
|
+
Run `fortytwo <verb> --help` for verb-specific options.
|
|
43
|
+
|
|
44
|
+
## Update safety
|
|
45
|
+
|
|
46
|
+
Distribution follows a **semver-ranges, latest-compatible** policy — there is no
|
|
47
|
+
curated bill-of-materials. `update` installs the latest in-range version of each
|
|
48
|
+
engine package and then runs `doctor` as a post-install health check. **Rollback
|
|
49
|
+
is manual**: the prior version set is recorded before every update, so
|
|
50
|
+
`fortytwo rollback` can restore exactly the set that was running before.
|
|
51
|
+
|
|
52
|
+
## The embedder
|
|
53
|
+
|
|
54
|
+
The engine uses a **local** embedder for privacy — personal data never leaves
|
|
55
|
+
your machine. The standard model is `qwen3-embedding:0.6b`, served by Ollama;
|
|
56
|
+
`init` pulls it and `doctor` verifies it.
|
|
57
|
+
|
|
58
|
+
## Requirements
|
|
59
|
+
|
|
60
|
+
- Node.js >= 18
|
|
61
|
+
- [Ollama](https://ollama.com/) for the local embedder (optional but
|
|
62
|
+
recommended — the engine degrades gracefully without it)
|
|
63
|
+
|
|
64
|
+
## License
|
|
65
|
+
|
|
66
|
+
MIT © 2026 Enrico Deleo
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
Created and maintained by [**Enrico Deleo**](https://enricodeleo.com).
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type MigrationState } from '../engine.js';
|
|
2
|
+
export interface CheckResult {
|
|
3
|
+
name: string;
|
|
4
|
+
ok: boolean;
|
|
5
|
+
detail: string;
|
|
6
|
+
/** A failed required check makes doctor exit non-zero; warn-only checks don't. */
|
|
7
|
+
required: boolean;
|
|
8
|
+
}
|
|
9
|
+
/** Everything the checks need, injectable so tests stay hermetic. */
|
|
10
|
+
export interface DoctorDeps {
|
|
11
|
+
loadGate: () => Promise<{
|
|
12
|
+
POLICY_SCHEMA_VERSION?: number;
|
|
13
|
+
} | null>;
|
|
14
|
+
loadMemory: () => Promise<{
|
|
15
|
+
MEMORY_TOOL_CONTRACT_VERSION?: number;
|
|
16
|
+
} | null>;
|
|
17
|
+
installedVersion: (spec: string) => string | null;
|
|
18
|
+
/** spec -> declared semver range (from this CLI's fortytwo.compat). */
|
|
19
|
+
compatRanges: Record<string, string>;
|
|
20
|
+
/** Installed Ollama model names, or null if unreachable. */
|
|
21
|
+
ollamaModels: () => Promise<string[] | null>;
|
|
22
|
+
embedModel: string;
|
|
23
|
+
migrationState: () => Promise<MigrationState>;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Run all checks, return per-check results + aggregate. Reused by `update` as
|
|
27
|
+
* the post-install verify step. Aggregate ok = every required check passed.
|
|
28
|
+
*/
|
|
29
|
+
export declare function runDoctorChecks(deps: DoctorDeps): Promise<{
|
|
30
|
+
results: CheckResult[];
|
|
31
|
+
ok: boolean;
|
|
32
|
+
}>;
|
|
33
|
+
/** Wire the real engine siblings, Ollama, and memory DB into the checks. */
|
|
34
|
+
export declare function defaultDoctorDeps(): DoctorDeps;
|
|
35
|
+
export declare function runDoctor(_argv: string[]): Promise<number>;
|
|
36
|
+
//# sourceMappingURL=doctor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAaA,OAAO,EAEkD,KAAK,cAAc,EAC3E,MAAM,cAAc,CAAC;AAQtB,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,kFAAkF;IAClF,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,qEAAqE;AACrE,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,OAAO,CAAC;QAAE,qBAAqB,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IACnE,UAAU,EAAE,MAAM,OAAO,CAAC;QAAE,4BAA4B,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IAC5E,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IAClD,uEAAuE;IACvE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,4DAA4D;IAC5D,YAAY,EAAE,MAAM,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,OAAO,CAAC,cAAc,CAAC,CAAC;CAC/C;AAyED;;;GAGG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,WAAW,EAAE,CAAC;IAAC,EAAE,EAAE,OAAO,CAAA;CAAE,CAAC,CAUxG;AAED,4EAA4E;AAC5E,wBAAgB,iBAAiB,IAAI,UAAU,CAa9C;AAED,wBAAsB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAQhE"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
// doctor — the post-verify health check. Run standalone, and also automatically
|
|
2
|
+
// at the end of `update` to decide whether an upgrade is healthy or needs rollback.
|
|
3
|
+
//
|
|
4
|
+
// Each check is independent and reported individually so a partial failure is
|
|
5
|
+
// actionable. Exit code is non-zero if ANY required check fails; warn-only
|
|
6
|
+
// checks (embedder) never fail the run.
|
|
7
|
+
//
|
|
8
|
+
// Checks are pure functions of an injected `DoctorDeps`, so they unit-test
|
|
9
|
+
// hermetically; `defaultDoctorDeps()` wires the real engine siblings + Ollama +
|
|
10
|
+
// the memory DB. CROSS-PACKAGE CONTRACTS asserted: gate's POLICY_SCHEMA_VERSION
|
|
11
|
+
// and memory's MEMORY_TOOL_CONTRACT_VERSION must equal what this CLI was built
|
|
12
|
+
// against, and installed siblings must satisfy the declared compat ranges.
|
|
13
|
+
import { loadGate, loadMemory, readInstalledVersion, readSelfCompatRanges, satisfiesRange, fetchOllamaModels, readMigrationState, } from '../engine.js';
|
|
14
|
+
import { EMBED_MODEL, DEFAULT_OLLAMA_BASE_URL, DEFAULT_DB_PATH } from './init.js';
|
|
15
|
+
// The contract versions this CLI was authored against. A sibling advertising a
|
|
16
|
+
// different MAJOR has broken the contract — doctor must flag it loudly.
|
|
17
|
+
const EXPECTED_POLICY_SCHEMA = 1;
|
|
18
|
+
const EXPECTED_MEMORY_CONTRACT = 1;
|
|
19
|
+
async function checkGate(deps) {
|
|
20
|
+
const name = 'safety gate';
|
|
21
|
+
const gate = await deps.loadGate();
|
|
22
|
+
if (!gate) {
|
|
23
|
+
return { name, ok: false, required: true, detail: '@justfortytwo/gate is not installed' };
|
|
24
|
+
}
|
|
25
|
+
const v = gate.POLICY_SCHEMA_VERSION;
|
|
26
|
+
if (v !== EXPECTED_POLICY_SCHEMA) {
|
|
27
|
+
return { name, ok: false, required: true, detail: `policySchema version ${v} != expected ${EXPECTED_POLICY_SCHEMA}` };
|
|
28
|
+
}
|
|
29
|
+
return { name, ok: true, required: true, detail: `gate present, policySchema v${v}` };
|
|
30
|
+
}
|
|
31
|
+
async function checkMemoryContract(deps) {
|
|
32
|
+
const name = 'memory-mcp contract';
|
|
33
|
+
const mem = await deps.loadMemory();
|
|
34
|
+
if (!mem) {
|
|
35
|
+
return { name, ok: false, required: true, detail: '@justfortytwo/memory is not installed' };
|
|
36
|
+
}
|
|
37
|
+
const v = mem.MEMORY_TOOL_CONTRACT_VERSION;
|
|
38
|
+
if (v !== EXPECTED_MEMORY_CONTRACT) {
|
|
39
|
+
return { name, ok: false, required: true, detail: `memory tool contract version ${v} != expected ${EXPECTED_MEMORY_CONTRACT}` };
|
|
40
|
+
}
|
|
41
|
+
return { name, ok: true, required: true, detail: `memory present, tool contract v${v}` };
|
|
42
|
+
}
|
|
43
|
+
async function checkCompat(deps) {
|
|
44
|
+
const name = 'peerDeps / fortytwo.compat';
|
|
45
|
+
const drift = [];
|
|
46
|
+
const seen = [];
|
|
47
|
+
for (const [spec, range] of Object.entries(deps.compatRanges)) {
|
|
48
|
+
const installed = deps.installedVersion(spec);
|
|
49
|
+
if (installed === null)
|
|
50
|
+
continue; // optional sibling not installed — not a drift
|
|
51
|
+
seen.push(`${spec}@${installed}`);
|
|
52
|
+
if (!satisfiesRange(installed, range))
|
|
53
|
+
drift.push(`${spec}@${installed} ∉ ${range}`);
|
|
54
|
+
}
|
|
55
|
+
if (drift.length > 0) {
|
|
56
|
+
return { name, ok: false, required: true, detail: `compat drift: ${drift.join('; ')}` };
|
|
57
|
+
}
|
|
58
|
+
return { name, ok: true, required: true, detail: seen.length ? `in range: ${seen.join(', ')}` : 'no engine siblings installed' };
|
|
59
|
+
}
|
|
60
|
+
async function checkEmbedder(deps) {
|
|
61
|
+
// Warn-only: a missing embedder degrades semantic recall (FakeEmbedder
|
|
62
|
+
// fallback) but never blocks the assistant — mirrors wakeup.sh.
|
|
63
|
+
const name = 'embedder model';
|
|
64
|
+
const models = await deps.ollamaModels();
|
|
65
|
+
if (models === null) {
|
|
66
|
+
return { name, ok: false, required: false, detail: 'Ollama unreachable (semantic recall will degrade)' };
|
|
67
|
+
}
|
|
68
|
+
if (!models.includes(deps.embedModel)) {
|
|
69
|
+
return { name, ok: false, required: false, detail: `model ${deps.embedModel} not pulled (run: ollama pull ${deps.embedModel})` };
|
|
70
|
+
}
|
|
71
|
+
return { name, ok: true, required: false, detail: `${deps.embedModel} present` };
|
|
72
|
+
}
|
|
73
|
+
async function checkMigrations(deps) {
|
|
74
|
+
const name = 'db migrations';
|
|
75
|
+
const state = await deps.migrationState();
|
|
76
|
+
switch (state) {
|
|
77
|
+
case 'ok':
|
|
78
|
+
return { name, ok: true, required: true, detail: 'memory DB migrated' };
|
|
79
|
+
case 'missing':
|
|
80
|
+
return { name, ok: false, required: true, detail: 'no memory DB found — run `fortytwo init` first' };
|
|
81
|
+
case 'pending':
|
|
82
|
+
return { name, ok: false, required: true, detail: 'memory DB present but not migrated' };
|
|
83
|
+
case 'unavailable':
|
|
84
|
+
return { name, ok: false, required: false, detail: 'memory package not installed — cannot check migrations' };
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Run all checks, return per-check results + aggregate. Reused by `update` as
|
|
89
|
+
* the post-install verify step. Aggregate ok = every required check passed.
|
|
90
|
+
*/
|
|
91
|
+
export async function runDoctorChecks(deps) {
|
|
92
|
+
const results = await Promise.all([
|
|
93
|
+
checkGate(deps),
|
|
94
|
+
checkMemoryContract(deps),
|
|
95
|
+
checkCompat(deps),
|
|
96
|
+
checkEmbedder(deps),
|
|
97
|
+
checkMigrations(deps),
|
|
98
|
+
]);
|
|
99
|
+
const ok = results.every((r) => r.ok || !r.required);
|
|
100
|
+
return { results, ok };
|
|
101
|
+
}
|
|
102
|
+
/** Wire the real engine siblings, Ollama, and memory DB into the checks. */
|
|
103
|
+
export function defaultDoctorDeps() {
|
|
104
|
+
const ollamaBaseUrl = process.env.OLLAMA_BASE_URL ?? DEFAULT_OLLAMA_BASE_URL;
|
|
105
|
+
const dbPath = process.env.DB_PATH ?? DEFAULT_DB_PATH;
|
|
106
|
+
const embedModel = process.env.EMBED_MODEL ?? EMBED_MODEL;
|
|
107
|
+
return {
|
|
108
|
+
loadGate,
|
|
109
|
+
loadMemory,
|
|
110
|
+
installedVersion: readInstalledVersion,
|
|
111
|
+
compatRanges: readSelfCompatRanges(),
|
|
112
|
+
ollamaModels: () => fetchOllamaModels(ollamaBaseUrl),
|
|
113
|
+
embedModel,
|
|
114
|
+
migrationState: () => readMigrationState(dbPath),
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
export async function runDoctor(_argv) {
|
|
118
|
+
const { results, ok } = await runDoctorChecks(defaultDoctorDeps());
|
|
119
|
+
for (const r of results) {
|
|
120
|
+
const mark = r.ok ? 'ok ' : r.required ? 'FAIL' : 'warn';
|
|
121
|
+
process.stdout.write(`[${mark}] ${r.name}: ${r.detail}\n`);
|
|
122
|
+
}
|
|
123
|
+
process.stdout.write(ok ? '\ndoctor: healthy\n' : '\ndoctor: required checks failed\n');
|
|
124
|
+
return ok ? 0 : 1;
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enrich.d.ts","sourceRoot":"","sources":["../../src/commands/enrich.ts"],"names":[],"mappings":"AAaA,wBAAsB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAWhE"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// enrich — deepen the persona by capturing more answers over time.
|
|
2
|
+
//
|
|
3
|
+
// init captures the minimum to boot. enrich is the ongoing "tell the assistant
|
|
4
|
+
// more about yourself / refine its persona" loop. It mutates the `enrichment`
|
|
5
|
+
// block of .fortytwo/identity.json, then re-renders the persona.
|
|
6
|
+
//
|
|
7
|
+
// CRITICAL idempotence guarantee: re-rendering MUST NOT clobber fields the user
|
|
8
|
+
// already captured or hand-edited. render.ts only overwrites MANAGED outputs and
|
|
9
|
+
// write-once-protects CAPTURED ones, so enrich is safe to run repeatedly.
|
|
10
|
+
import { readIdentity, writeIdentity } from '../state.js';
|
|
11
|
+
import { renderPersona } from '../render.js';
|
|
12
|
+
export async function runEnrich(_argv) {
|
|
13
|
+
// TODO(impl):
|
|
14
|
+
// const identity = readIdentity() // require init has run
|
|
15
|
+
// prompt for (or take from flags) additional persona answers; MERGE into
|
|
16
|
+
// identity.enrichment without dropping existing keys.
|
|
17
|
+
// writeIdentity(identity) // stamps updatedAt
|
|
18
|
+
// renderPersona(identity) // idempotent re-render; reports written/skipped
|
|
19
|
+
// print which context files changed.
|
|
20
|
+
void readIdentity;
|
|
21
|
+
void writeIdentity;
|
|
22
|
+
void renderPersona;
|
|
23
|
+
void null;
|
|
24
|
+
throw new Error('TODO(impl): runEnrich — capture more answers, merge into identity.json, re-render persona');
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=enrich.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enrich.js","sourceRoot":"","sources":["../../src/commands/enrich.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,EAAE;AACF,+EAA+E;AAC/E,8EAA8E;AAC9E,iEAAiE;AACjE,EAAE;AACF,gFAAgF;AAChF,iFAAiF;AACjF,0EAA0E;AAE1E,OAAO,EAAE,YAAY,EAAE,aAAa,EAAiB,MAAM,aAAa,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,KAAe;IAC7C,cAAc;IACd,6DAA6D;IAC7D,2EAA2E;IAC3E,0DAA0D;IAC1D,yDAAyD;IACzD,sFAAsF;IACtF,uCAAuC;IACvC,KAAK,YAAY,CAAC;IAAC,KAAK,aAAa,CAAC;IAAC,KAAK,aAAa,CAAC;IAC1D,KAAM,IAA4B,CAAC;IACnC,MAAM,IAAI,KAAK,CAAC,2FAA2F,CAAC,CAAC;AAC/G,CAAC"}
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// forget — redact/remove specific memories from the memory MCP store.
|
|
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;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=forget.js.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { Answers, VersionPin } from '../state.js';
|
|
2
|
+
export declare const EMBED_MODEL = "qwen3-embedding:0.6b";
|
|
3
|
+
export declare const DEFAULT_OLLAMA_BASE_URL = "http://localhost:11434";
|
|
4
|
+
export declare const DEFAULT_DB_PATH = "db/fortytwo.db";
|
|
5
|
+
export interface ManifestField {
|
|
6
|
+
key: string;
|
|
7
|
+
prompt: string;
|
|
8
|
+
type: 'string' | 'text' | 'list' | string;
|
|
9
|
+
required?: boolean;
|
|
10
|
+
default?: unknown;
|
|
11
|
+
}
|
|
12
|
+
export interface AnswerSources {
|
|
13
|
+
/** A pre-filled answers map (e.g. from `--answers <file.json>`). Highest precedence. */
|
|
14
|
+
answersFile?: Record<string, unknown>;
|
|
15
|
+
/** process.env (read as FORTYTWO_<UPPER_KEY>). */
|
|
16
|
+
env?: Record<string, string | undefined>;
|
|
17
|
+
/** CLI flags, keyed by manifest field key. */
|
|
18
|
+
flags?: Record<string, string>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Resolve every manifest field from (in precedence order) the answers file, the
|
|
22
|
+
* environment (FORTYTWO_<KEY>), CLI flags, then the manifest default. List
|
|
23
|
+
* fields are coerced to arrays; null/absent values become '' or [] so the
|
|
24
|
+
* renderer (which fails loud on null) never sees a hole. Required fields left
|
|
25
|
+
* empty are reported back, not silently defaulted.
|
|
26
|
+
*/
|
|
27
|
+
export declare function resolveAnswers(fields: ManifestField[], sources: AnswerSources): {
|
|
28
|
+
answers: Answers;
|
|
29
|
+
missingRequired: string[];
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Merge `vars` into existing `.env` content: update matching keys in place,
|
|
33
|
+
* append new ones, preserve comments and unrelated lines. Secrets NEVER go to
|
|
34
|
+
* identity.json — only here.
|
|
35
|
+
*/
|
|
36
|
+
export declare function mergeEnvContent(existing: string, vars: Record<string, string>): string;
|
|
37
|
+
export interface McpConfig {
|
|
38
|
+
mcpServers: Record<string, unknown>;
|
|
39
|
+
[k: string]: unknown;
|
|
40
|
+
}
|
|
41
|
+
/** Add (or replace) the `fortytwo-memory` MCP server entry, preserving others. */
|
|
42
|
+
export declare function buildMcpConfig(existing: McpConfig | null, opts: {
|
|
43
|
+
dbPath: string;
|
|
44
|
+
}): McpConfig;
|
|
45
|
+
/** Pin each declared sibling to its installed version; skip the absent. */
|
|
46
|
+
export declare function buildVersionPins(compatRanges: Record<string, string>, readVersion: (spec: string) => string | null): VersionPin[];
|
|
47
|
+
export declare function runInit(argv: string[]): Promise<number>;
|
|
48
|
+
//# sourceMappingURL=init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAY,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAMjE,eAAO,MAAM,WAAW,yBAAyB,CAAC;AAClD,eAAO,MAAM,uBAAuB,2BAA2B,CAAC;AAChE,eAAO,MAAM,eAAe,mBAAmB,CAAC;AAEhD,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IAC1C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,wFAAwF;IACxF,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,kDAAkD;IAClD,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,8CAA8C;IAC9C,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAiBD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,aAAa,EAAE,EACvB,OAAO,EAAE,aAAa,GACrB;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,eAAe,EAAE,MAAM,EAAE,CAAA;CAAE,CAajD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAetF;AAED,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACtB;AAED,kFAAkF;AAClF,wBAAgB,cAAc,CAAC,QAAQ,EAAE,SAAS,GAAG,IAAI,EAAE,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAS9F;AAED,2EAA2E;AAC3E,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACpC,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,GAC3C,UAAU,EAAE,CAOd;AA4GD,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAoE7D"}
|