clef-mcp 0.1.3 → 0.1.4
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 +12 -7
- package/dist/cli.js +303 -48
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -26,11 +26,14 @@ Clef does **not** generate prose. It reads a `state` plus a set of typed questio
|
|
|
26
26
|
# 1. Detect hardware, download the model (~6 GB) + llama.cpp runtime, verify checksum + inference
|
|
27
27
|
npx clef-mcp install
|
|
28
28
|
|
|
29
|
-
# 2.
|
|
29
|
+
# 2. Register the MCP server + agent skill in your clients (zcode, claude-code, codex, cursor)
|
|
30
|
+
npx clef-mcp setup
|
|
31
|
+
|
|
32
|
+
# 3. Run the MCP server (stdio)
|
|
30
33
|
npx clef-mcp
|
|
31
34
|
```
|
|
32
35
|
|
|
33
|
-
`clef-mcp` (step
|
|
36
|
+
`clef-mcp` (step 3) never downloads anything. If the model is missing, tool calls return a structured `MODEL_NOT_INSTALLED` error with a hint. Steps 1 and 2 can be combined: `npx clef-mcp install --setup`.
|
|
34
37
|
|
|
35
38
|
### Register with your MCP client
|
|
36
39
|
|
|
@@ -150,11 +153,12 @@ The tool schema tells the client *what* `clef_decide` accepts; agents also need
|
|
|
150
153
|
Install it for your agent(s):
|
|
151
154
|
|
|
152
155
|
```bash
|
|
153
|
-
#
|
|
154
|
-
|
|
156
|
+
# automatic (registers the MCP server too)
|
|
157
|
+
clef-mcp setup
|
|
155
158
|
|
|
156
|
-
# or
|
|
157
|
-
cp -r
|
|
159
|
+
# or copy the skill manually
|
|
160
|
+
cp -r skills/clef-decisions ~/.agents/skills/ # from this repo
|
|
161
|
+
cp -r "$(npm root -g)/clef-mcp/skills/clef-decisions" ~/.agents/skills/ # from the npm package
|
|
158
162
|
```
|
|
159
163
|
|
|
160
164
|
`~/.agents/skills/` is the shared location for ZCode / Claude Code / Codex-style agents.
|
|
@@ -164,6 +168,7 @@ cp -r "$(npm root -g)/clef-mcp/skills/clef-decisions" ~/.agents/skills/
|
|
|
164
168
|
```bash
|
|
165
169
|
clef-mcp # run the MCP server on stdio (default command)
|
|
166
170
|
clef-mcp install # detect hardware → download model + runtime → verify checksum → verify inference
|
|
171
|
+
clef-mcp setup # register the MCP server + agent skill in zcode / claude-code / codex / cursor
|
|
167
172
|
clef-mcp models # list models/quantizations and install status
|
|
168
173
|
clef-mcp status # runtime, model, memory summary
|
|
169
174
|
clef-mcp doctor # full diagnosis (platform, RAM, GPU, binary, model, checksum*, inference, MCP config)
|
|
@@ -171,7 +176,7 @@ clef-mcp uninstall # remove the model (and optionally the managed runtime)
|
|
|
171
176
|
clef-mcp evals # run the evaluation dataset against the installed model
|
|
172
177
|
```
|
|
173
178
|
|
|
174
|
-
Useful flags: `install --quant Q8_0 --yes --skip-probe`, `doctor --deep` (re-hashes the model file), `uninstall --runtime --yes`.
|
|
179
|
+
Useful flags: `install --quant Q8_0 --yes --skip-probe`, `install --setup` (runs setup right after install), `setup --clients zcode,cursor --no-skill`, `doctor --deep` (re-hashes the model file), `uninstall --runtime --yes`.
|
|
175
180
|
|
|
176
181
|
## Configuration (environment variables)
|
|
177
182
|
|
package/dist/cli.js
CHANGED
|
@@ -1,29 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
var
|
|
5
|
-
|
|
6
|
-
MODEL_LOAD_FAILED: "MODEL_LOAD_FAILED",
|
|
7
|
-
RUNTIME_NOT_FOUND: "RUNTIME_NOT_FOUND",
|
|
8
|
-
RUNTIME_INIT_FAILED: "RUNTIME_INIT_FAILED",
|
|
9
|
-
RUNTIME_NOT_SUPPORTED: "RUNTIME_NOT_SUPPORTED",
|
|
10
|
-
INVALID_INPUT: "INVALID_INPUT",
|
|
11
|
-
CLEF_INFERENCE_FAILED: "CLEF_INFERENCE_FAILED",
|
|
12
|
-
UNSUPPORTED_PLATFORM: "UNSUPPORTED_PLATFORM",
|
|
13
|
-
OUT_OF_MEMORY: "OUT_OF_MEMORY",
|
|
14
|
-
CHECKSUM_MISMATCH: "CHECKSUM_MISMATCH",
|
|
15
|
-
DOWNLOAD_FAILED: "DOWNLOAD_FAILED"
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __esm = (fn, res) => function __init() {
|
|
5
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
16
6
|
};
|
|
17
|
-
var
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
constructor(code, message, hint) {
|
|
21
|
-
super(message);
|
|
22
|
-
this.name = "ClefError";
|
|
23
|
-
this.code = code;
|
|
24
|
-
this.hint = hint;
|
|
25
|
-
}
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
26
10
|
};
|
|
11
|
+
|
|
12
|
+
// src/clef/errors.ts
|
|
27
13
|
function errorJson(err) {
|
|
28
14
|
if (err instanceof ClefError) {
|
|
29
15
|
return {
|
|
@@ -53,12 +39,268 @@ function exitCodeFor(err) {
|
|
|
53
39
|
}
|
|
54
40
|
return 1;
|
|
55
41
|
}
|
|
42
|
+
var ClefErrorCode, ClefError;
|
|
43
|
+
var init_errors = __esm({
|
|
44
|
+
"src/clef/errors.ts"() {
|
|
45
|
+
"use strict";
|
|
46
|
+
ClefErrorCode = {
|
|
47
|
+
MODEL_NOT_INSTALLED: "MODEL_NOT_INSTALLED",
|
|
48
|
+
MODEL_LOAD_FAILED: "MODEL_LOAD_FAILED",
|
|
49
|
+
RUNTIME_NOT_FOUND: "RUNTIME_NOT_FOUND",
|
|
50
|
+
RUNTIME_INIT_FAILED: "RUNTIME_INIT_FAILED",
|
|
51
|
+
RUNTIME_NOT_SUPPORTED: "RUNTIME_NOT_SUPPORTED",
|
|
52
|
+
INVALID_INPUT: "INVALID_INPUT",
|
|
53
|
+
CLEF_INFERENCE_FAILED: "CLEF_INFERENCE_FAILED",
|
|
54
|
+
UNSUPPORTED_PLATFORM: "UNSUPPORTED_PLATFORM",
|
|
55
|
+
OUT_OF_MEMORY: "OUT_OF_MEMORY",
|
|
56
|
+
CHECKSUM_MISMATCH: "CHECKSUM_MISMATCH",
|
|
57
|
+
DOWNLOAD_FAILED: "DOWNLOAD_FAILED"
|
|
58
|
+
};
|
|
59
|
+
ClefError = class extends Error {
|
|
60
|
+
code;
|
|
61
|
+
hint;
|
|
62
|
+
constructor(code, message, hint) {
|
|
63
|
+
super(message);
|
|
64
|
+
this.name = "ClefError";
|
|
65
|
+
this.code = code;
|
|
66
|
+
this.hint = hint;
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// src/cli/prompt.ts
|
|
73
|
+
import readline from "readline/promises";
|
|
74
|
+
async function confirm(question, yes) {
|
|
75
|
+
if (yes) return true;
|
|
76
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
77
|
+
throw new ClefError(
|
|
78
|
+
ClefErrorCode.INVALID_INPUT,
|
|
79
|
+
"Refusing to proceed interactively without a terminal.",
|
|
80
|
+
"Re-run with --yes to confirm non-interactively."
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
84
|
+
try {
|
|
85
|
+
const answer = (await rl.question(`${question} [Y/n] `)).trim().toLowerCase();
|
|
86
|
+
return answer === "" || answer === "y" || answer === "yes";
|
|
87
|
+
} finally {
|
|
88
|
+
rl.close();
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
var init_prompt = __esm({
|
|
92
|
+
"src/cli/prompt.ts"() {
|
|
93
|
+
"use strict";
|
|
94
|
+
init_errors();
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// src/cli/setup.ts
|
|
99
|
+
var setup_exports = {};
|
|
100
|
+
__export(setup_exports, {
|
|
101
|
+
SERVER_ENTRY: () => SERVER_ENTRY,
|
|
102
|
+
installSkill: () => installSkill,
|
|
103
|
+
runSetup: () => runSetup
|
|
104
|
+
});
|
|
105
|
+
import { execFile as execFile4 } from "child_process";
|
|
106
|
+
import fsSync2 from "fs";
|
|
107
|
+
import fsp6 from "fs/promises";
|
|
108
|
+
import os4 from "os";
|
|
109
|
+
import path9 from "path";
|
|
110
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
111
|
+
function bundledSkillPath() {
|
|
112
|
+
return fileURLToPath2(new URL("../skills/clef-decisions/SKILL.md", import.meta.url));
|
|
113
|
+
}
|
|
114
|
+
async function mergeJsonServerEntry(file, serverKey, container) {
|
|
115
|
+
let doc = {};
|
|
116
|
+
try {
|
|
117
|
+
doc = JSON.parse(await fsp6.readFile(file, "utf8"));
|
|
118
|
+
} catch {
|
|
119
|
+
doc = {};
|
|
120
|
+
}
|
|
121
|
+
if (container === "mcp.servers") {
|
|
122
|
+
const mcp = doc.mcp ?? {};
|
|
123
|
+
const servers = mcp.servers ?? {};
|
|
124
|
+
if (servers[serverKey]) return "already-configured";
|
|
125
|
+
servers[serverKey] = { ...SERVER_ENTRY };
|
|
126
|
+
mcp.servers = servers;
|
|
127
|
+
doc.mcp = mcp;
|
|
128
|
+
} else {
|
|
129
|
+
const servers = doc.mcpServers ?? {};
|
|
130
|
+
if (servers[serverKey]) return "already-configured";
|
|
131
|
+
servers[serverKey] = { command: SERVER_ENTRY.command, args: [...SERVER_ENTRY.args] };
|
|
132
|
+
doc.mcpServers = servers;
|
|
133
|
+
}
|
|
134
|
+
await fsp6.mkdir(path9.dirname(file), { recursive: true });
|
|
135
|
+
await fsp6.writeFile(file, JSON.stringify(doc, null, 2) + "\n", "utf8");
|
|
136
|
+
return "configured";
|
|
137
|
+
}
|
|
138
|
+
async function setupCodex() {
|
|
139
|
+
const file = path9.join(HOME(), ".codex", "config.toml");
|
|
140
|
+
let content = "";
|
|
141
|
+
try {
|
|
142
|
+
content = await fsp6.readFile(file, "utf8");
|
|
143
|
+
} catch {
|
|
144
|
+
content = "";
|
|
145
|
+
}
|
|
146
|
+
if (content.includes("[mcp_servers.clef-mcp]")) {
|
|
147
|
+
return { client: "codex", status: "already-configured", detail: file };
|
|
148
|
+
}
|
|
149
|
+
const next = (content && !content.endsWith("\n") ? content + "\n" : content) + "\n" + CODEX_SECTION;
|
|
150
|
+
await fsp6.mkdir(path9.dirname(file), { recursive: true });
|
|
151
|
+
await fsp6.writeFile(file, next, "utf8");
|
|
152
|
+
return { client: "codex", status: "configured", detail: file };
|
|
153
|
+
}
|
|
154
|
+
async function setupZcode() {
|
|
155
|
+
const file = path9.join(HOME(), ".zcode", "cli", "config.json");
|
|
156
|
+
const status = await mergeJsonServerEntry(file, "clef-mcp", "mcp.servers");
|
|
157
|
+
return { client: "zcode", status, detail: file };
|
|
158
|
+
}
|
|
159
|
+
async function setupCursor() {
|
|
160
|
+
const file = path9.join(HOME(), ".cursor", "mcp.json");
|
|
161
|
+
const status = await mergeJsonServerEntry(file, "clef-mcp", "mcpServers");
|
|
162
|
+
return { client: "cursor", status, detail: file };
|
|
163
|
+
}
|
|
164
|
+
function whichCli(bin) {
|
|
165
|
+
const dirs = (process.env.PATH ?? "").split(path9.delimiter).filter(Boolean);
|
|
166
|
+
for (const dir of dirs) {
|
|
167
|
+
const candidate = path9.join(dir, bin);
|
|
168
|
+
try {
|
|
169
|
+
fsSync2.accessSync(candidate, fsSync2.constants.X_OK);
|
|
170
|
+
return candidate;
|
|
171
|
+
} catch {
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return void 0;
|
|
175
|
+
}
|
|
176
|
+
async function setupClaudeCode() {
|
|
177
|
+
const claude = whichCli("claude");
|
|
178
|
+
if (!claude) {
|
|
179
|
+
return {
|
|
180
|
+
client: "claude-code",
|
|
181
|
+
status: "manual-hint",
|
|
182
|
+
detail: "claude CLI not found \u2014 run manually: claude mcp add clef-mcp -- clef-mcp"
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
const existing = await new Promise((resolve) => {
|
|
186
|
+
execFile4(claude, ["mcp", "list"], { timeout: 3e4, encoding: "utf8" }, (_err, stdout) => resolve(String(stdout)));
|
|
187
|
+
});
|
|
188
|
+
if (existing.includes("clef-mcp")) {
|
|
189
|
+
return { client: "claude-code", status: "already-configured", detail: "claude mcp list" };
|
|
190
|
+
}
|
|
191
|
+
await new Promise((resolve, reject) => {
|
|
192
|
+
execFile4(
|
|
193
|
+
claude,
|
|
194
|
+
["mcp", "add", "--scope", "user", "clef-mcp", "--", "clef-mcp"],
|
|
195
|
+
{ timeout: 6e4, encoding: "utf8" },
|
|
196
|
+
(err) => err ? reject(err) : resolve()
|
|
197
|
+
);
|
|
198
|
+
});
|
|
199
|
+
return { client: "claude-code", status: "configured", detail: "claude mcp add --scope user" };
|
|
200
|
+
}
|
|
201
|
+
async function installSkill() {
|
|
202
|
+
const src = bundledSkillPath();
|
|
203
|
+
const destDir = path9.join(HOME(), ".agents", "skills", "clef-decisions");
|
|
204
|
+
const dest = path9.join(destDir, "SKILL.md");
|
|
205
|
+
let content = "";
|
|
206
|
+
try {
|
|
207
|
+
content = await fsp6.readFile(dest, "utf8");
|
|
208
|
+
} catch {
|
|
209
|
+
}
|
|
210
|
+
const incoming = await fsp6.readFile(src, "utf8");
|
|
211
|
+
if (content === incoming) {
|
|
212
|
+
return { client: "skill", status: "already-configured", detail: dest };
|
|
213
|
+
}
|
|
214
|
+
await fsp6.mkdir(destDir, { recursive: true });
|
|
215
|
+
await fsp6.writeFile(dest, incoming, "utf8");
|
|
216
|
+
return { client: "skill", status: "configured", detail: dest };
|
|
217
|
+
}
|
|
218
|
+
function parseClients(raw) {
|
|
219
|
+
const all = ["zcode", "claude-code", "codex", "cursor"];
|
|
220
|
+
if (!raw || raw === "all") return all;
|
|
221
|
+
const wanted = raw.split(",").map((s) => s.trim().toLowerCase()).filter(Boolean);
|
|
222
|
+
for (const w of wanted) {
|
|
223
|
+
if (!all.includes(w)) {
|
|
224
|
+
throw new ClefError(
|
|
225
|
+
ClefErrorCode.INVALID_INPUT,
|
|
226
|
+
`Unknown client "${w}".`,
|
|
227
|
+
`Available: ${all.join(", ")} (or "all")`
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return wanted;
|
|
232
|
+
}
|
|
233
|
+
async function runSetup(opts) {
|
|
234
|
+
const wantSkill = opts.skill === true || opts.noSkill !== true;
|
|
235
|
+
const clients = parseClients(opts.clients);
|
|
236
|
+
const plan = [...clients, ...wantSkill ? ["skill"] : []];
|
|
237
|
+
console.log(`Setup will register clef-mcp with: ${plan.join(", ")}
|
|
238
|
+
`);
|
|
239
|
+
const ok = await confirm("Continue?", opts.yes === true);
|
|
240
|
+
if (!ok) {
|
|
241
|
+
console.log("Aborted. Nothing was changed.");
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
const reports = [];
|
|
245
|
+
for (const client of clients) {
|
|
246
|
+
try {
|
|
247
|
+
if (client === "zcode") reports.push(await setupZcode());
|
|
248
|
+
else if (client === "cursor") reports.push(await setupCursor());
|
|
249
|
+
else if (client === "codex") reports.push(await setupCodex());
|
|
250
|
+
else if (client === "claude-code") reports.push(await setupClaudeCode());
|
|
251
|
+
} catch (err) {
|
|
252
|
+
reports.push({
|
|
253
|
+
client,
|
|
254
|
+
status: "manual-hint",
|
|
255
|
+
detail: `failed: ${err instanceof Error ? err.message : String(err)}`
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
if (wantSkill) {
|
|
260
|
+
try {
|
|
261
|
+
reports.push(await installSkill());
|
|
262
|
+
} catch (err) {
|
|
263
|
+
reports.push({
|
|
264
|
+
client: "skill",
|
|
265
|
+
status: "manual-hint",
|
|
266
|
+
detail: `failed: ${err instanceof Error ? err.message : String(err)}`
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
console.log("");
|
|
271
|
+
for (const r of reports) {
|
|
272
|
+
const mark2 = r.status === "configured" ? "+" : r.status === "already-configured" ? "=" : "!";
|
|
273
|
+
console.log(`${mark2} ${r.client.padEnd(12)} ${r.status.padEnd(20)} ${r.detail}`);
|
|
274
|
+
}
|
|
275
|
+
console.log("\nDone. Restart your MCP clients (new agent sessions) to pick up the server.");
|
|
276
|
+
}
|
|
277
|
+
var SERVER_ENTRY, HOME, CODEX_SECTION;
|
|
278
|
+
var init_setup = __esm({
|
|
279
|
+
"src/cli/setup.ts"() {
|
|
280
|
+
"use strict";
|
|
281
|
+
init_errors();
|
|
282
|
+
init_prompt();
|
|
283
|
+
SERVER_ENTRY = { command: "clef-mcp", args: [], type: "stdio" };
|
|
284
|
+
HOME = () => os4.homedir();
|
|
285
|
+
CODEX_SECTION = [
|
|
286
|
+
"[mcp_servers.clef-mcp]",
|
|
287
|
+
'command = "clef-mcp"',
|
|
288
|
+
"args = []",
|
|
289
|
+
""
|
|
290
|
+
].join("\n");
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
// src/cli/index.ts
|
|
295
|
+
init_errors();
|
|
56
296
|
|
|
57
297
|
// src/mcp/server.ts
|
|
298
|
+
init_errors();
|
|
58
299
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
59
300
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
60
301
|
|
|
61
302
|
// src/clef/systemone.ts
|
|
303
|
+
init_errors();
|
|
62
304
|
function stateToString(state) {
|
|
63
305
|
if (typeof state === "string") return state;
|
|
64
306
|
try {
|
|
@@ -369,6 +611,7 @@ function llamaServerName(platform) {
|
|
|
369
611
|
}
|
|
370
612
|
|
|
371
613
|
// src/models/registry.ts
|
|
614
|
+
init_errors();
|
|
372
615
|
var GB = 1024 ** 3;
|
|
373
616
|
var CLEF_FLASH = {
|
|
374
617
|
id: "clef-flash",
|
|
@@ -516,6 +759,7 @@ function readRuntimeManifest(manifestPath) {
|
|
|
516
759
|
}
|
|
517
760
|
|
|
518
761
|
// src/runtime/binary.ts
|
|
762
|
+
init_errors();
|
|
519
763
|
import fs2 from "fs";
|
|
520
764
|
import path4 from "path";
|
|
521
765
|
function existsExecutable(p) {
|
|
@@ -571,6 +815,7 @@ function resolveLlamaServerBinary(cfg, deps = {}) {
|
|
|
571
815
|
}
|
|
572
816
|
|
|
573
817
|
// src/runtime/llama-cpp.ts
|
|
818
|
+
init_errors();
|
|
574
819
|
import { spawn } from "child_process";
|
|
575
820
|
import net from "net";
|
|
576
821
|
var STDERR_TAIL_LIMIT = 4e3;
|
|
@@ -802,6 +1047,7 @@ ${tail}` : ""),
|
|
|
802
1047
|
};
|
|
803
1048
|
|
|
804
1049
|
// src/mcp/schema.ts
|
|
1050
|
+
init_errors();
|
|
805
1051
|
import { z } from "zod";
|
|
806
1052
|
function criteriaDescription(limits) {
|
|
807
1053
|
return z.string().min(1).max(limits.maxCriteriaDescChars);
|
|
@@ -1021,6 +1267,7 @@ function createClefServer(deps = {}) {
|
|
|
1021
1267
|
import { Command } from "commander";
|
|
1022
1268
|
|
|
1023
1269
|
// src/cli/doctor.ts
|
|
1270
|
+
init_errors();
|
|
1024
1271
|
import { execFile as execFile2 } from "child_process";
|
|
1025
1272
|
import os3 from "os";
|
|
1026
1273
|
import { promisify } from "util";
|
|
@@ -1028,6 +1275,7 @@ import fsp2 from "fs/promises";
|
|
|
1028
1275
|
import path5 from "path";
|
|
1029
1276
|
|
|
1030
1277
|
// src/models/platform.ts
|
|
1278
|
+
init_errors();
|
|
1031
1279
|
import { execFile } from "child_process";
|
|
1032
1280
|
import os2 from "os";
|
|
1033
1281
|
function exec(cmd, args, timeoutMs) {
|
|
@@ -1105,6 +1353,7 @@ function formatBytes(bytes) {
|
|
|
1105
1353
|
}
|
|
1106
1354
|
|
|
1107
1355
|
// src/runtime/probe.ts
|
|
1356
|
+
init_errors();
|
|
1108
1357
|
import fs3 from "fs/promises";
|
|
1109
1358
|
async function probeInference(cfg, manifest, log, loadTimeoutMs = 12e4) {
|
|
1110
1359
|
await fs3.access(manifest.modelPath).catch(() => {
|
|
@@ -1315,6 +1564,7 @@ ${failed.length} critical check(s) failed.`
|
|
|
1315
1564
|
}
|
|
1316
1565
|
|
|
1317
1566
|
// src/cli/evals.ts
|
|
1567
|
+
init_errors();
|
|
1318
1568
|
import fsp3 from "fs/promises";
|
|
1319
1569
|
import fsSync from "fs";
|
|
1320
1570
|
import { fileURLToPath } from "url";
|
|
@@ -1424,11 +1674,13 @@ ${passed}/${results.length} passed (${(rate * 100).toFixed(1)}%), required >= ${
|
|
|
1424
1674
|
}
|
|
1425
1675
|
|
|
1426
1676
|
// src/models/llama-install.ts
|
|
1677
|
+
init_errors();
|
|
1427
1678
|
import { execFile as execFile3 } from "child_process";
|
|
1428
1679
|
import fsp5 from "fs/promises";
|
|
1429
1680
|
import path8 from "path";
|
|
1430
1681
|
|
|
1431
1682
|
// src/models/hf.ts
|
|
1683
|
+
init_errors();
|
|
1432
1684
|
import { createHash as createHash2 } from "crypto";
|
|
1433
1685
|
import fsp4 from "fs/promises";
|
|
1434
1686
|
import path7 from "path";
|
|
@@ -1726,28 +1978,11 @@ async function removeManagedRuntime(cfg) {
|
|
|
1726
1978
|
return true;
|
|
1727
1979
|
}
|
|
1728
1980
|
|
|
1729
|
-
// src/cli/
|
|
1730
|
-
|
|
1731
|
-
async function confirm(question, yes) {
|
|
1732
|
-
if (yes) return true;
|
|
1733
|
-
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
1734
|
-
throw new ClefError(
|
|
1735
|
-
ClefErrorCode.INVALID_INPUT,
|
|
1736
|
-
"Refusing to proceed interactively without a terminal.",
|
|
1737
|
-
"Re-run with --yes to confirm non-interactively."
|
|
1738
|
-
);
|
|
1739
|
-
}
|
|
1740
|
-
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
1741
|
-
try {
|
|
1742
|
-
const answer = (await rl.question(`${question} [Y/n] `)).trim().toLowerCase();
|
|
1743
|
-
return answer === "" || answer === "y" || answer === "yes";
|
|
1744
|
-
} finally {
|
|
1745
|
-
rl.close();
|
|
1746
|
-
}
|
|
1747
|
-
}
|
|
1981
|
+
// src/cli/install.ts
|
|
1982
|
+
init_prompt();
|
|
1748
1983
|
|
|
1749
1984
|
// src/version.ts
|
|
1750
|
-
var VERSION = "0.1.
|
|
1985
|
+
var VERSION = "0.1.4";
|
|
1751
1986
|
|
|
1752
1987
|
// src/cli/install.ts
|
|
1753
1988
|
var OS_NAMES = {
|
|
@@ -1817,11 +2052,18 @@ Model license: ${spec.licenseId} \u2014 ${spec.licenseUrl}`);
|
|
|
1817
2052
|
const probe = await probeInference(config, manifest, log);
|
|
1818
2053
|
console.log(` Inference OK (${(probe.latencyMs / 1e3).toFixed(1)}s incl. model load, via ${probe.binarySource} binary)`);
|
|
1819
2054
|
}
|
|
2055
|
+
if (opts.setup) {
|
|
2056
|
+
const { runSetup: runSetup2 } = await Promise.resolve().then(() => (init_setup(), setup_exports));
|
|
2057
|
+
console.log("");
|
|
2058
|
+
await runSetup2({ yes: opts.yes });
|
|
2059
|
+
return;
|
|
2060
|
+
}
|
|
1820
2061
|
console.log("\nDone. Start the MCP server with:\n\n clef-mcp\n");
|
|
1821
|
-
console.log("
|
|
2062
|
+
console.log("Register it with your agents (or run `clef-mcp setup` to do it automatically):\n");
|
|
1822
2063
|
console.log(" Claude Code : claude mcp add clef-mcp -- clef-mcp");
|
|
1823
2064
|
console.log(" Codex : add [mcp_servers.clef-mcp] to ~/.codex/config.toml (see README)");
|
|
1824
|
-
console.log(" Cursor : add clef-mcp to .cursor/mcp.json (see README)
|
|
2065
|
+
console.log(" Cursor : add clef-mcp to .cursor/mcp.json (see README)");
|
|
2066
|
+
console.log(" ZCode : add clef-mcp to ~/.zcode/cli/config.json (see README)\n");
|
|
1825
2067
|
}
|
|
1826
2068
|
|
|
1827
2069
|
// src/cli/models-cmd.ts
|
|
@@ -1841,7 +2083,11 @@ async function runModels() {
|
|
|
1841
2083
|
}
|
|
1842
2084
|
}
|
|
1843
2085
|
|
|
2086
|
+
// src/cli/index.ts
|
|
2087
|
+
init_setup();
|
|
2088
|
+
|
|
1844
2089
|
// src/cli/status.ts
|
|
2090
|
+
init_errors();
|
|
1845
2091
|
async function runStatus() {
|
|
1846
2092
|
const config = loadConfig();
|
|
1847
2093
|
const info = await detectPlatform();
|
|
@@ -1881,7 +2127,9 @@ async function runStatus() {
|
|
|
1881
2127
|
}
|
|
1882
2128
|
|
|
1883
2129
|
// src/cli/uninstall.ts
|
|
1884
|
-
|
|
2130
|
+
init_errors();
|
|
2131
|
+
import fsp7 from "fs/promises";
|
|
2132
|
+
init_prompt();
|
|
1885
2133
|
async function runUninstall(opts) {
|
|
1886
2134
|
const config = loadConfig();
|
|
1887
2135
|
const spec = getModelSpec(opts.model ?? config.model);
|
|
@@ -1905,7 +2153,7 @@ async function runUninstall(opts) {
|
|
|
1905
2153
|
return;
|
|
1906
2154
|
}
|
|
1907
2155
|
if (target) {
|
|
1908
|
-
await
|
|
2156
|
+
await fsp7.rm(target, { recursive: true, force: true });
|
|
1909
2157
|
console.log(`Removed: ${target}`);
|
|
1910
2158
|
}
|
|
1911
2159
|
if (opts.runtime) {
|
|
@@ -1932,13 +2180,20 @@ program.action(async () => {
|
|
|
1932
2180
|
handleCliError(err);
|
|
1933
2181
|
}
|
|
1934
2182
|
});
|
|
1935
|
-
program.command("install").description("Detect the machine, download a Clef model + runtime, verify checksum and inference.").option("--model <id>", "model to install (default: clef-flash)").option("--quant <id>", "quantization override: Q4_K_M | Q8_0 | BF16").option("-y, --yes", "assume yes for all prompts (non-interactive)").option("--skip-runtime", "do not download/verify the llama.cpp runtime").option("--skip-probe", "skip the post-install inference verification").action(async (opts) => {
|
|
2183
|
+
program.command("install").description("Detect the machine, download a Clef model + runtime, verify checksum and inference.").option("--model <id>", "model to install (default: clef-flash)").option("--quant <id>", "quantization override: Q4_K_M | Q8_0 | BF16").option("-y, --yes", "assume yes for all prompts (non-interactive)").option("--skip-runtime", "do not download/verify the llama.cpp runtime").option("--skip-probe", "skip the post-install inference verification").option("--setup", "also register the MCP server + agent skill in detected clients (same as running `clef-mcp setup`)").action(async (opts) => {
|
|
1936
2184
|
try {
|
|
1937
2185
|
await runInstall(opts);
|
|
1938
2186
|
} catch (err) {
|
|
1939
2187
|
handleCliError(err);
|
|
1940
2188
|
}
|
|
1941
2189
|
});
|
|
2190
|
+
program.command("setup").description("Register the MCP server + agent skill in your clients (zcode, claude-code, codex, cursor).").option("--clients <list>", "comma-separated subset: zcode,claude-code,codex,cursor (default: all)").option("--skill", "install the agent skill (default)").option("--no-skill", "do not touch the agent skill").option("-y, --yes", "assume yes for all prompts (non-interactive)").action(async (opts) => {
|
|
2191
|
+
try {
|
|
2192
|
+
await runSetup(opts);
|
|
2193
|
+
} catch (err) {
|
|
2194
|
+
handleCliError(err);
|
|
2195
|
+
}
|
|
2196
|
+
});
|
|
1942
2197
|
program.command("models").description("List known Clef models, quantizations and install status.").action(async () => {
|
|
1943
2198
|
try {
|
|
1944
2199
|
await runModels();
|