clef-mcp 0.1.3 → 0.1.5
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 +311 -49
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +9 -2
- 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;
|
|
@@ -608,6 +853,7 @@ var LlamaCppRuntime = class {
|
|
|
608
853
|
this.host = opts.host ?? "127.0.0.1";
|
|
609
854
|
this.loadTimeoutMs = opts.loadTimeoutMs ?? 12e4;
|
|
610
855
|
this.requestTimeoutMs = opts.requestTimeoutMs ?? 6e4;
|
|
856
|
+
this.batchSize = opts.batchSize ?? (Number.parseInt(process.env.CLEF_LLAMA_BATCH ?? "", 10) || 8192);
|
|
611
857
|
}
|
|
612
858
|
opts;
|
|
613
859
|
proc;
|
|
@@ -617,6 +863,7 @@ var LlamaCppRuntime = class {
|
|
|
617
863
|
requestTimeoutMs;
|
|
618
864
|
/** Serializes decide() calls: the llama.cpp clef path handles one sequence per batch. */
|
|
619
865
|
queue = Promise.resolve();
|
|
866
|
+
batchSize;
|
|
620
867
|
get endpoint() {
|
|
621
868
|
if (!this.resolvedPort) throw new ClefError(ClefErrorCode.RUNTIME_INIT_FAILED, "Runtime is not started");
|
|
622
869
|
return `http://${this.host}:${this.resolvedPort}`;
|
|
@@ -636,6 +883,10 @@ var LlamaCppRuntime = class {
|
|
|
636
883
|
"--port",
|
|
637
884
|
String(port),
|
|
638
885
|
"--no-webui",
|
|
886
|
+
"-b",
|
|
887
|
+
String(this.batchSize),
|
|
888
|
+
"-ub",
|
|
889
|
+
String(this.batchSize),
|
|
639
890
|
...this.opts.alias ? ["--alias", this.opts.alias] : []
|
|
640
891
|
];
|
|
641
892
|
this.opts.log?.debug("spawning llama-server", { bin: this.opts.serverBin, args });
|
|
@@ -753,7 +1004,8 @@ ${tail}` : ""),
|
|
|
753
1004
|
}
|
|
754
1005
|
throw new ClefError(
|
|
755
1006
|
ClefErrorCode.CLEF_INFERENCE_FAILED,
|
|
756
|
-
`Inference failed with HTTP ${res.status}: ${apiMessage.slice(0, 2e3)}
|
|
1007
|
+
`Inference failed with HTTP ${res.status}: ${apiMessage.slice(0, 2e3)}`,
|
|
1008
|
+
/physical batch size/i.test(apiMessage) ? "Too many/too large questions for one request. Split into several calls, reduce criteria text, or raise the batch with CLEF_LLAMA_BATCH." : void 0
|
|
757
1009
|
);
|
|
758
1010
|
}
|
|
759
1011
|
if (!body || typeof body !== "object") {
|
|
@@ -802,6 +1054,7 @@ ${tail}` : ""),
|
|
|
802
1054
|
};
|
|
803
1055
|
|
|
804
1056
|
// src/mcp/schema.ts
|
|
1057
|
+
init_errors();
|
|
805
1058
|
import { z } from "zod";
|
|
806
1059
|
function criteriaDescription(limits) {
|
|
807
1060
|
return z.string().min(1).max(limits.maxCriteriaDescChars);
|
|
@@ -1021,6 +1274,7 @@ function createClefServer(deps = {}) {
|
|
|
1021
1274
|
import { Command } from "commander";
|
|
1022
1275
|
|
|
1023
1276
|
// src/cli/doctor.ts
|
|
1277
|
+
init_errors();
|
|
1024
1278
|
import { execFile as execFile2 } from "child_process";
|
|
1025
1279
|
import os3 from "os";
|
|
1026
1280
|
import { promisify } from "util";
|
|
@@ -1028,6 +1282,7 @@ import fsp2 from "fs/promises";
|
|
|
1028
1282
|
import path5 from "path";
|
|
1029
1283
|
|
|
1030
1284
|
// src/models/platform.ts
|
|
1285
|
+
init_errors();
|
|
1031
1286
|
import { execFile } from "child_process";
|
|
1032
1287
|
import os2 from "os";
|
|
1033
1288
|
function exec(cmd, args, timeoutMs) {
|
|
@@ -1105,6 +1360,7 @@ function formatBytes(bytes) {
|
|
|
1105
1360
|
}
|
|
1106
1361
|
|
|
1107
1362
|
// src/runtime/probe.ts
|
|
1363
|
+
init_errors();
|
|
1108
1364
|
import fs3 from "fs/promises";
|
|
1109
1365
|
async function probeInference(cfg, manifest, log, loadTimeoutMs = 12e4) {
|
|
1110
1366
|
await fs3.access(manifest.modelPath).catch(() => {
|
|
@@ -1315,6 +1571,7 @@ ${failed.length} critical check(s) failed.`
|
|
|
1315
1571
|
}
|
|
1316
1572
|
|
|
1317
1573
|
// src/cli/evals.ts
|
|
1574
|
+
init_errors();
|
|
1318
1575
|
import fsp3 from "fs/promises";
|
|
1319
1576
|
import fsSync from "fs";
|
|
1320
1577
|
import { fileURLToPath } from "url";
|
|
@@ -1424,11 +1681,13 @@ ${passed}/${results.length} passed (${(rate * 100).toFixed(1)}%), required >= ${
|
|
|
1424
1681
|
}
|
|
1425
1682
|
|
|
1426
1683
|
// src/models/llama-install.ts
|
|
1684
|
+
init_errors();
|
|
1427
1685
|
import { execFile as execFile3 } from "child_process";
|
|
1428
1686
|
import fsp5 from "fs/promises";
|
|
1429
1687
|
import path8 from "path";
|
|
1430
1688
|
|
|
1431
1689
|
// src/models/hf.ts
|
|
1690
|
+
init_errors();
|
|
1432
1691
|
import { createHash as createHash2 } from "crypto";
|
|
1433
1692
|
import fsp4 from "fs/promises";
|
|
1434
1693
|
import path7 from "path";
|
|
@@ -1726,28 +1985,11 @@ async function removeManagedRuntime(cfg) {
|
|
|
1726
1985
|
return true;
|
|
1727
1986
|
}
|
|
1728
1987
|
|
|
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
|
-
}
|
|
1988
|
+
// src/cli/install.ts
|
|
1989
|
+
init_prompt();
|
|
1748
1990
|
|
|
1749
1991
|
// src/version.ts
|
|
1750
|
-
var VERSION = "0.1.
|
|
1992
|
+
var VERSION = "0.1.5";
|
|
1751
1993
|
|
|
1752
1994
|
// src/cli/install.ts
|
|
1753
1995
|
var OS_NAMES = {
|
|
@@ -1817,11 +2059,18 @@ Model license: ${spec.licenseId} \u2014 ${spec.licenseUrl}`);
|
|
|
1817
2059
|
const probe = await probeInference(config, manifest, log);
|
|
1818
2060
|
console.log(` Inference OK (${(probe.latencyMs / 1e3).toFixed(1)}s incl. model load, via ${probe.binarySource} binary)`);
|
|
1819
2061
|
}
|
|
2062
|
+
if (opts.setup) {
|
|
2063
|
+
const { runSetup: runSetup2 } = await Promise.resolve().then(() => (init_setup(), setup_exports));
|
|
2064
|
+
console.log("");
|
|
2065
|
+
await runSetup2({ yes: opts.yes });
|
|
2066
|
+
return;
|
|
2067
|
+
}
|
|
1820
2068
|
console.log("\nDone. Start the MCP server with:\n\n clef-mcp\n");
|
|
1821
|
-
console.log("
|
|
2069
|
+
console.log("Register it with your agents (or run `clef-mcp setup` to do it automatically):\n");
|
|
1822
2070
|
console.log(" Claude Code : claude mcp add clef-mcp -- clef-mcp");
|
|
1823
2071
|
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)
|
|
2072
|
+
console.log(" Cursor : add clef-mcp to .cursor/mcp.json (see README)");
|
|
2073
|
+
console.log(" ZCode : add clef-mcp to ~/.zcode/cli/config.json (see README)\n");
|
|
1825
2074
|
}
|
|
1826
2075
|
|
|
1827
2076
|
// src/cli/models-cmd.ts
|
|
@@ -1841,7 +2090,11 @@ async function runModels() {
|
|
|
1841
2090
|
}
|
|
1842
2091
|
}
|
|
1843
2092
|
|
|
2093
|
+
// src/cli/index.ts
|
|
2094
|
+
init_setup();
|
|
2095
|
+
|
|
1844
2096
|
// src/cli/status.ts
|
|
2097
|
+
init_errors();
|
|
1845
2098
|
async function runStatus() {
|
|
1846
2099
|
const config = loadConfig();
|
|
1847
2100
|
const info = await detectPlatform();
|
|
@@ -1881,7 +2134,9 @@ async function runStatus() {
|
|
|
1881
2134
|
}
|
|
1882
2135
|
|
|
1883
2136
|
// src/cli/uninstall.ts
|
|
1884
|
-
|
|
2137
|
+
init_errors();
|
|
2138
|
+
import fsp7 from "fs/promises";
|
|
2139
|
+
init_prompt();
|
|
1885
2140
|
async function runUninstall(opts) {
|
|
1886
2141
|
const config = loadConfig();
|
|
1887
2142
|
const spec = getModelSpec(opts.model ?? config.model);
|
|
@@ -1905,7 +2160,7 @@ async function runUninstall(opts) {
|
|
|
1905
2160
|
return;
|
|
1906
2161
|
}
|
|
1907
2162
|
if (target) {
|
|
1908
|
-
await
|
|
2163
|
+
await fsp7.rm(target, { recursive: true, force: true });
|
|
1909
2164
|
console.log(`Removed: ${target}`);
|
|
1910
2165
|
}
|
|
1911
2166
|
if (opts.runtime) {
|
|
@@ -1932,13 +2187,20 @@ program.action(async () => {
|
|
|
1932
2187
|
handleCliError(err);
|
|
1933
2188
|
}
|
|
1934
2189
|
});
|
|
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) => {
|
|
2190
|
+
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
2191
|
try {
|
|
1937
2192
|
await runInstall(opts);
|
|
1938
2193
|
} catch (err) {
|
|
1939
2194
|
handleCliError(err);
|
|
1940
2195
|
}
|
|
1941
2196
|
});
|
|
2197
|
+
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) => {
|
|
2198
|
+
try {
|
|
2199
|
+
await runSetup(opts);
|
|
2200
|
+
} catch (err) {
|
|
2201
|
+
handleCliError(err);
|
|
2202
|
+
}
|
|
2203
|
+
});
|
|
1942
2204
|
program.command("models").description("List known Clef models, quantizations and install status.").action(async () => {
|
|
1943
2205
|
try {
|
|
1944
2206
|
await runModels();
|