@tuned-tensor/cli 0.4.2 → 0.4.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/dist/index.js CHANGED
@@ -6,6 +6,158 @@ import { Command } from "commander";
6
6
  // src/output.ts
7
7
  import chalk from "chalk";
8
8
  import Table from "cli-table3";
9
+
10
+ // src/client.ts
11
+ import { readFileSync as readFileSync2, statSync } from "fs";
12
+ import { basename } from "path";
13
+
14
+ // src/config.ts
15
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
16
+ import { homedir } from "os";
17
+ import { join } from "path";
18
+ var CONFIG_DIR_NAME = "tuned-tensor";
19
+ var CONFIG_FILE_NAME = "config.json";
20
+ function getConfigDir() {
21
+ const xdg = process.env.XDG_CONFIG_HOME;
22
+ const base = xdg || join(homedir(), ".config");
23
+ return join(base, CONFIG_DIR_NAME);
24
+ }
25
+ function getConfigPath() {
26
+ return join(getConfigDir(), CONFIG_FILE_NAME);
27
+ }
28
+ function readConfig() {
29
+ const path = getConfigPath();
30
+ if (!existsSync(path)) return {};
31
+ try {
32
+ return JSON.parse(readFileSync(path, "utf-8"));
33
+ } catch {
34
+ return {};
35
+ }
36
+ }
37
+ function writeConfig(config) {
38
+ const dir = getConfigDir();
39
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
40
+ writeFileSync(getConfigPath(), JSON.stringify(config, null, 2) + "\n");
41
+ }
42
+ function updateConfig(partial) {
43
+ const current = readConfig();
44
+ writeConfig({ ...current, ...partial });
45
+ }
46
+ function clearConfig() {
47
+ const path = getConfigPath();
48
+ if (existsSync(path)) writeFileSync(path, "{}\n");
49
+ }
50
+ var DEFAULT_BASE_URL = "https://tunedtensor.com";
51
+ function getBaseUrl(opts) {
52
+ return opts?.baseUrl || process.env.TUNED_TENSOR_URL || readConfig().base_url || DEFAULT_BASE_URL;
53
+ }
54
+ function getApiKey(opts) {
55
+ return opts?.apiKey || process.env.TUNED_TENSOR_API_KEY || readConfig().api_key;
56
+ }
57
+
58
+ // src/client.ts
59
+ var ApiError = class extends Error {
60
+ constructor(status, code, message) {
61
+ super(message);
62
+ this.status = status;
63
+ this.code = code;
64
+ this.name = "ApiError";
65
+ }
66
+ };
67
+ function resolveKey(opts) {
68
+ const key = getApiKey(opts);
69
+ if (!key) {
70
+ throw new ApiError(
71
+ 401,
72
+ "NO_API_KEY",
73
+ "No API key found. Run `tt auth login` or set TUNED_TENSOR_API_KEY."
74
+ );
75
+ }
76
+ return key;
77
+ }
78
+ function buildUrl(path, query, opts) {
79
+ const base = getBaseUrl(opts);
80
+ const url = new URL(`/api/v1${path}`, base);
81
+ if (query) {
82
+ for (const [k, v] of Object.entries(query)) {
83
+ if (v !== void 0) url.searchParams.set(k, String(v));
84
+ }
85
+ }
86
+ return url.toString();
87
+ }
88
+ async function request(method, path, options = {}) {
89
+ const key = resolveKey(options.opts);
90
+ const url = buildUrl(path, options.query, options.opts);
91
+ const headers = {
92
+ Authorization: `Bearer ${key}`
93
+ };
94
+ let bodyPayload;
95
+ if (options.body) {
96
+ headers["Content-Type"] = "application/json";
97
+ bodyPayload = JSON.stringify(options.body);
98
+ }
99
+ const res = await fetch(url, { method, headers, body: bodyPayload });
100
+ if (!res.ok) {
101
+ let errBody;
102
+ try {
103
+ errBody = await res.json();
104
+ } catch {
105
+ throw new ApiError(res.status, "UNKNOWN", res.statusText);
106
+ }
107
+ throw new ApiError(
108
+ res.status,
109
+ errBody.error?.code || "UNKNOWN",
110
+ errBody.error?.message || res.statusText
111
+ );
112
+ }
113
+ if (res.status === 204) return { data: null };
114
+ return await res.json();
115
+ }
116
+ function get(path, query, opts) {
117
+ return request("GET", path, { query, opts });
118
+ }
119
+ function post(path, body, opts) {
120
+ return request("POST", path, { body, opts });
121
+ }
122
+ function put(path, body, opts) {
123
+ return request("PUT", path, { body, opts });
124
+ }
125
+ function del(path, opts) {
126
+ return request("DELETE", path, { opts });
127
+ }
128
+ async function upload(path, filePath, fields, opts) {
129
+ const key = resolveKey(opts);
130
+ const url = buildUrl(path, void 0, opts);
131
+ const form = new FormData();
132
+ for (const [k, v] of Object.entries(fields)) {
133
+ form.append(k, v);
134
+ }
135
+ const fileBytes = readFileSync2(filePath);
136
+ const fileSize = statSync(filePath).size;
137
+ const blob = new Blob([fileBytes], { type: "application/jsonl" });
138
+ form.append("file", blob, basename(filePath));
139
+ const res = await fetch(url, {
140
+ method: "POST",
141
+ headers: { Authorization: `Bearer ${key}` },
142
+ body: form
143
+ });
144
+ if (!res.ok) {
145
+ let errBody;
146
+ try {
147
+ errBody = await res.json();
148
+ } catch {
149
+ throw new ApiError(res.status, "UNKNOWN", res.statusText);
150
+ }
151
+ throw new ApiError(
152
+ res.status,
153
+ errBody.error?.code || "UNKNOWN",
154
+ errBody.error?.message || res.statusText
155
+ );
156
+ }
157
+ return await res.json();
158
+ }
159
+
160
+ // src/output.ts
9
161
  var jsonMode = false;
10
162
  function setJsonMode(enabled) {
11
163
  jsonMode = enabled;
@@ -51,6 +203,23 @@ function printWarning(message) {
51
203
  function printError(message) {
52
204
  console.error(chalk.red("\u2717") + " " + message);
53
205
  }
206
+ function reportError(err) {
207
+ const isApi = err instanceof ApiError;
208
+ const message = err?.message || String(err);
209
+ if (jsonMode) {
210
+ printJson({
211
+ error: {
212
+ status: isApi ? err.status : null,
213
+ code: isApi ? err.code : "CLI_ERROR",
214
+ message
215
+ }
216
+ });
217
+ } else if (isApi) {
218
+ printError(`[${err.status}] ${message}`);
219
+ } else {
220
+ printError(message);
221
+ }
222
+ }
54
223
  function formatDate(iso) {
55
224
  if (!iso) return "\u2014";
56
225
  return new Date(iso).toLocaleString();
@@ -83,52 +252,6 @@ function shortId(id) {
83
252
  // src/commands/auth.ts
84
253
  import { createInterface } from "readline/promises";
85
254
  import { stdin, stdout } from "process";
86
-
87
- // src/config.ts
88
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
89
- import { homedir } from "os";
90
- import { join } from "path";
91
- var CONFIG_DIR_NAME = "tuned-tensor";
92
- var CONFIG_FILE_NAME = "config.json";
93
- function getConfigDir() {
94
- const xdg = process.env.XDG_CONFIG_HOME;
95
- const base = xdg || join(homedir(), ".config");
96
- return join(base, CONFIG_DIR_NAME);
97
- }
98
- function getConfigPath() {
99
- return join(getConfigDir(), CONFIG_FILE_NAME);
100
- }
101
- function readConfig() {
102
- const path = getConfigPath();
103
- if (!existsSync(path)) return {};
104
- try {
105
- return JSON.parse(readFileSync(path, "utf-8"));
106
- } catch {
107
- return {};
108
- }
109
- }
110
- function writeConfig(config) {
111
- const dir = getConfigDir();
112
- if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
113
- writeFileSync(getConfigPath(), JSON.stringify(config, null, 2) + "\n");
114
- }
115
- function updateConfig(partial) {
116
- const current = readConfig();
117
- writeConfig({ ...current, ...partial });
118
- }
119
- function clearConfig() {
120
- const path = getConfigPath();
121
- if (existsSync(path)) writeFileSync(path, "{}\n");
122
- }
123
- var DEFAULT_BASE_URL = "https://www.tunedtensor.com";
124
- function getBaseUrl(opts) {
125
- return opts?.baseUrl || process.env.TUNED_TENSOR_URL || readConfig().base_url || DEFAULT_BASE_URL;
126
- }
127
- function getApiKey(opts) {
128
- return opts?.apiKey || process.env.TUNED_TENSOR_API_KEY || readConfig().api_key;
129
- }
130
-
131
- // src/commands/auth.ts
132
255
  import chalk2 from "chalk";
133
256
  function registerAuthCommands(parent) {
134
257
  const auth = parent.command("auth").description("Manage authentication");
@@ -191,112 +314,55 @@ function registerAuthCommands(parent) {
191
314
 
192
315
  // src/commands/specs.ts
193
316
  import { readFileSync as readFileSync3 } from "fs";
194
-
195
- // src/client.ts
196
- import { readFileSync as readFileSync2, statSync } from "fs";
197
- import { basename } from "path";
198
- var ApiError = class extends Error {
199
- constructor(status, code, message) {
200
- super(message);
201
- this.status = status;
202
- this.code = code;
203
- this.name = "ApiError";
204
- }
317
+ var SPEC_BODY_KEYS = /* @__PURE__ */ new Set([
318
+ "name",
319
+ "description",
320
+ "base_model",
321
+ "system_prompt",
322
+ "guidelines",
323
+ "constraints",
324
+ "examples"
325
+ ]);
326
+ var RUN_INPUT_KEYS = ["run_id", "behavior_spec_id", "spec_snapshot", "run_number"];
327
+ var SpecBodyError = class extends Error {
205
328
  };
206
- function resolveKey(opts) {
207
- const key = getApiKey(opts);
208
- if (!key) {
209
- throw new ApiError(
210
- 401,
211
- "NO_API_KEY",
212
- "No API key found. Run `tt auth login` or set TUNED_TENSOR_API_KEY."
329
+ function loadSpecBody(filePath, mode) {
330
+ let parsed;
331
+ try {
332
+ parsed = JSON.parse(readFileSync3(filePath, "utf-8"));
333
+ } catch (e) {
334
+ throw new SpecBodyError(
335
+ `Could not parse ${filePath}: ${e.message}`
213
336
  );
214
337
  }
215
- return key;
216
- }
217
- function buildUrl(path, query, opts) {
218
- const base = getBaseUrl(opts);
219
- const url = new URL(`/api/v1${path}`, base);
220
- if (query) {
221
- for (const [k, v] of Object.entries(query)) {
222
- if (v !== void 0) url.searchParams.set(k, String(v));
223
- }
338
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
339
+ throw new SpecBodyError(
340
+ `${filePath} must contain a JSON object at the top level.`
341
+ );
224
342
  }
225
- return url.toString();
226
- }
227
- async function request(method, path, options = {}) {
228
- const key = resolveKey(options.opts);
229
- const url = buildUrl(path, options.query, options.opts);
230
- const headers = {
231
- Authorization: `Bearer ${key}`
232
- };
233
- let bodyPayload;
234
- if (options.body) {
235
- headers["Content-Type"] = "application/json";
236
- bodyPayload = JSON.stringify(options.body);
343
+ const body = parsed;
344
+ const runInputHits = RUN_INPUT_KEYS.filter((k) => k in body);
345
+ if (runInputHits.length >= 2 || "spec_snapshot" in body) {
346
+ const hint = "spec_snapshot" in body ? `This file looks like a run-input payload (top-level keys: ${runInputHits.join(", ")}). The actual spec is nested under "spec_snapshot". Try:
347
+ jq '.spec_snapshot' ${filePath} > spec.json
348
+ tt specs ${mode === "create" ? "create" : "update <id>"} --file spec.json` : `This file looks like a run-input payload (top-level keys: ${runInputHits.join(", ")}), not a behaviour spec. To start a run on an existing spec, use: tt runs start <spec-id>`;
349
+ throw new SpecBodyError(hint);
237
350
  }
238
- const res = await fetch(url, { method, headers, body: bodyPayload });
239
- if (!res.ok) {
240
- let errBody;
241
- try {
242
- errBody = await res.json();
243
- } catch {
244
- throw new ApiError(res.status, "UNKNOWN", res.statusText);
245
- }
246
- throw new ApiError(
247
- res.status,
248
- errBody.error?.code || "UNKNOWN",
249
- errBody.error?.message || res.statusText
351
+ if (mode === "create" && typeof body.name !== "string") {
352
+ throw new SpecBodyError(
353
+ `${filePath} is missing required field "name" (string).`
250
354
  );
251
355
  }
252
- if (res.status === 204) return { data: null };
253
- return await res.json();
254
- }
255
- function get(path, query, opts) {
256
- return request("GET", path, { query, opts });
257
- }
258
- function post(path, body, opts) {
259
- return request("POST", path, { body, opts });
260
- }
261
- function put(path, body, opts) {
262
- return request("PUT", path, { body, opts });
263
- }
264
- function del(path, opts) {
265
- return request("DELETE", path, { opts });
266
- }
267
- async function upload(path, filePath, fields, opts) {
268
- const key = resolveKey(opts);
269
- const url = buildUrl(path, void 0, opts);
270
- const form = new FormData();
271
- for (const [k, v] of Object.entries(fields)) {
272
- form.append(k, v);
273
- }
274
- const fileBytes = readFileSync2(filePath);
275
- const fileSize = statSync(filePath).size;
276
- const blob = new Blob([fileBytes], { type: "application/jsonl" });
277
- form.append("file", blob, basename(filePath));
278
- const res = await fetch(url, {
279
- method: "POST",
280
- headers: { Authorization: `Bearer ${key}` },
281
- body: form
282
- });
283
- if (!res.ok) {
284
- let errBody;
285
- try {
286
- errBody = await res.json();
287
- } catch {
288
- throw new ApiError(res.status, "UNKNOWN", res.statusText);
289
- }
290
- throw new ApiError(
291
- res.status,
292
- errBody.error?.code || "UNKNOWN",
293
- errBody.error?.message || res.statusText
356
+ const unknown = Object.keys(body).filter(
357
+ (k) => !SPEC_BODY_KEYS.has(k) && k !== "id" && k !== "eval_cases"
358
+ );
359
+ if (unknown.length && !isJsonMode()) {
360
+ printWarning(
361
+ `Unknown spec field(s) in ${filePath}: ${unknown.join(", ")}. They will be sent but may be rejected by the API.`
294
362
  );
295
363
  }
296
- return await res.json();
364
+ return body;
297
365
  }
298
-
299
- // src/commands/specs.ts
300
366
  function registerSpecsCommands(parent) {
301
367
  const specs = parent.command("specs").description("Manage behaviour specs");
302
368
  specs.command("list").description("List behaviour specs").option("-p, --page <n>", "Page number", "1").option("--per-page <n>", "Results per page", "20").action(async (cmdOpts) => {
@@ -353,13 +419,12 @@ function registerSpecsCommands(parent) {
353
419
  const opts = parent.opts();
354
420
  let body;
355
421
  if (cmdOpts.file) {
356
- body = JSON.parse(readFileSync3(cmdOpts.file, "utf-8"));
422
+ body = loadSpecBody(cmdOpts.file, "create");
357
423
  } else if (cmdOpts.name) {
358
424
  body = { name: cmdOpts.name };
359
425
  if (cmdOpts.model) body.base_model = cmdOpts.model;
360
426
  } else {
361
- console.error("Provide --file or --name");
362
- process.exit(1);
427
+ throw new SpecBodyError("Provide --file or --name");
363
428
  }
364
429
  const { data } = await post("/behavior-specs", body, opts);
365
430
  if (isJsonMode()) return printJson(data);
@@ -369,7 +434,7 @@ function registerSpecsCommands(parent) {
369
434
  const opts = parent.opts();
370
435
  let body;
371
436
  if (cmdOpts.file) {
372
- body = JSON.parse(readFileSync3(cmdOpts.file, "utf-8"));
437
+ body = loadSpecBody(cmdOpts.file, "update");
373
438
  } else {
374
439
  body = {};
375
440
  if (cmdOpts.name) body.name = cmdOpts.name;
@@ -1187,9 +1252,9 @@ function registerPushCommand(parent) {
1187
1252
 
1188
1253
  // src/index.ts
1189
1254
  var program = new Command();
1190
- program.name("tt").description("Tuned Tensor CLI \u2014 fine-tune and evaluate LLMs").version("0.4.2").option("-k, --api-key <key>", "API key (overrides stored key)").option(
1255
+ program.name("tt").description("Tuned Tensor CLI \u2014 fine-tune and evaluate LLMs").version("0.4.3").option("-k, --api-key <key>", "API key (overrides stored key)").option(
1191
1256
  "-u, --base-url <url>",
1192
- "API base URL (default: https://www.tunedtensor.com)"
1257
+ "API base URL (default: https://tunedtensor.com)"
1193
1258
  ).option("--json", "Output raw JSON").option("--no-color", "Disable colors").hook("preAction", (_thisCommand, actionCommand) => {
1194
1259
  const rootOpts = program.opts();
1195
1260
  if (rootOpts.json) setJsonMode(true);
@@ -1207,12 +1272,9 @@ registerTopupCommands(program);
1207
1272
  registerInitCommand(program);
1208
1273
  registerEvalCommand(program);
1209
1274
  registerPushCommand(program);
1275
+ if (process.argv.includes("--json")) setJsonMode(true);
1210
1276
  program.parseAsync().catch((err) => {
1211
- if (err instanceof ApiError) {
1212
- printError(`[${err.status}] ${err.message}`);
1213
- process.exit(1);
1214
- }
1215
- printError(err.message || String(err));
1277
+ reportError(err);
1216
1278
  process.exit(1);
1217
1279
  });
1218
1280
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/output.ts","../src/commands/auth.ts","../src/config.ts","../src/commands/specs.ts","../src/client.ts","../src/commands/runs.ts","../src/commands/datasets.ts","../src/commands/models.ts","../src/commands/balance.ts","../src/commands/topup.ts","../src/commands/init.ts","../src/commands/eval.ts","../src/eval/rules.ts","../src/eval/runner.ts","../src/commands/push.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { setJsonMode, printError } from \"./output.js\";\nimport { registerAuthCommands } from \"./commands/auth.js\";\nimport { registerSpecsCommands } from \"./commands/specs.js\";\nimport { registerRunsCommands } from \"./commands/runs.js\";\nimport { registerDatasetsCommands } from \"./commands/datasets.js\";\nimport { registerModelsCommands } from \"./commands/models.js\";\n\nimport { registerBalanceCommands } from \"./commands/balance.js\";\nimport { registerTopupCommands } from \"./commands/topup.js\";\nimport { registerInitCommand } from \"./commands/init.js\";\nimport { registerEvalCommand } from \"./commands/eval.js\";\nimport { registerPushCommand } from \"./commands/push.js\";\nimport { ApiError } from \"./client.js\";\n\ndeclare const __TT_VERSION__: string;\n\nconst program = new Command();\n\nprogram\n .name(\"tt\")\n .description(\"Tuned Tensor CLI — fine-tune and evaluate LLMs\")\n .version(__TT_VERSION__)\n .option(\"-k, --api-key <key>\", \"API key (overrides stored key)\")\n .option(\n \"-u, --base-url <url>\",\n \"API base URL (default: https://www.tunedtensor.com)\",\n )\n .option(\"--json\", \"Output raw JSON\")\n .option(\"--no-color\", \"Disable colors\")\n .hook(\"preAction\", (_thisCommand, actionCommand) => {\n const rootOpts = program.opts();\n if (rootOpts.json) setJsonMode(true);\n if (rootOpts.color === false) {\n process.env.FORCE_COLOR = \"0\";\n }\n });\n\nregisterAuthCommands(program);\nregisterSpecsCommands(program);\nregisterRunsCommands(program);\nregisterDatasetsCommands(program);\nregisterModelsCommands(program);\n\nregisterBalanceCommands(program);\nregisterTopupCommands(program);\nregisterInitCommand(program);\nregisterEvalCommand(program);\nregisterPushCommand(program);\n\nprogram.parseAsync().catch((err) => {\n if (err instanceof ApiError) {\n printError(`[${err.status}] ${err.message}`);\n process.exit(1);\n }\n printError(err.message || String(err));\n process.exit(1);\n});\n","import chalk from \"chalk\";\nimport Table from \"cli-table3\";\n\nlet jsonMode = false;\n\nexport function setJsonMode(enabled: boolean) {\n jsonMode = enabled;\n}\n\nexport function isJsonMode(): boolean {\n return jsonMode;\n}\n\nexport function printJson(data: unknown) {\n console.log(JSON.stringify(data, null, 2));\n}\n\nexport function printTable(\n headers: string[],\n rows: string[][],\n meta?: { page: number; per_page: number; total: number },\n) {\n const table = new Table({\n head: headers.map((h) => chalk.bold.cyan(h)),\n style: { head: [], border: [] },\n });\n for (const row of rows) {\n table.push(row);\n }\n console.log(table.toString());\n\n if (meta) {\n const totalPages = Math.ceil(meta.total / meta.per_page);\n console.log(\n chalk.dim(\n `\\nPage ${meta.page}/${totalPages} (${meta.total} total)`,\n ),\n );\n }\n}\n\nexport function printDetail(fields: [string, string | undefined][]) {\n const maxLabel = Math.max(...fields.map(([l]) => l.length));\n for (const [label, value] of fields) {\n const paddedLabel = label.padEnd(maxLabel);\n console.log(`${chalk.bold.cyan(paddedLabel)} ${value ?? chalk.dim(\"—\")}`);\n }\n}\n\nexport function printSuccess(message: string) {\n console.log(chalk.green(\"✓\") + \" \" + message);\n}\n\nexport function printWarning(message: string) {\n console.log(chalk.yellow(\"!\") + \" \" + message);\n}\n\nexport function printError(message: string) {\n console.error(chalk.red(\"✗\") + \" \" + message);\n}\n\nexport function formatDate(iso?: string | null): string {\n if (!iso) return \"—\";\n return new Date(iso).toLocaleString();\n}\n\nexport function formatStatus(status: string): string {\n const map: Record<string, (s: string) => string> = {\n completed: chalk.green,\n running: chalk.blue,\n training: chalk.blue,\n evaluating: chalk.blue,\n preparing: chalk.yellow,\n pending: chalk.yellow,\n uploading: chalk.yellow,\n failed: chalk.red,\n cancelled: chalk.dim,\n validated: chalk.green,\n invalid: chalk.red,\n };\n const colorFn = map[status] || chalk.white;\n return colorFn(status);\n}\n\nexport function truncate(str: string, max: number): string {\n if (str.length <= max) return str;\n return str.slice(0, max - 1) + \"…\";\n}\n\nexport function shortId(id: string): string {\n return id.slice(0, 8);\n}\n","import { Command } from \"commander\";\nimport { createInterface } from \"node:readline/promises\";\nimport { stdin, stdout } from \"node:process\";\nimport {\n readConfig,\n updateConfig,\n clearConfig,\n getApiKey,\n getBaseUrl,\n DEFAULT_BASE_URL,\n} from \"../config.js\";\nimport {\n printSuccess,\n printDetail,\n printError,\n printWarning,\n isJsonMode,\n printJson,\n} from \"../output.js\";\nimport chalk from \"chalk\";\n\nexport function registerAuthCommands(parent: Command) {\n const auth = parent.command(\"auth\").description(\"Manage authentication\");\n\n auth\n .command(\"login\")\n .description(\"Store an API key for authentication\")\n .argument(\"[key]\", \"API key (tt_...). If omitted, you will be prompted.\")\n .action(async (key?: string) => {\n let apiKey = key;\n\n if (!apiKey) {\n const settingsUrl = `${DEFAULT_BASE_URL}/dashboard/settings`;\n console.log();\n console.log(\n ` To get your API key, go to ${chalk.bold(\"Settings → API Keys\")} in the Tuned Tensor dashboard:`,\n );\n console.log(` ${chalk.cyan.underline(settingsUrl)}`);\n console.log();\n\n const rl = createInterface({ input: stdin, output: stdout });\n apiKey = await rl.question(\"Enter your API key (tt_...): \");\n rl.close();\n }\n\n apiKey = apiKey.trim();\n\n if (!apiKey.startsWith(\"tt_\") || apiKey.length !== 51) {\n printError(\n \"Invalid API key format. Keys start with tt_ and are 51 characters long.\",\n );\n process.exit(1);\n }\n\n updateConfig({ api_key: apiKey });\n printSuccess(\n `API key stored (${apiKey.slice(0, 8)}...). You're ready to go.`,\n );\n });\n\n auth\n .command(\"logout\")\n .description(\"Remove stored credentials\")\n .action(() => {\n clearConfig();\n printSuccess(\"Credentials removed.\");\n });\n\n auth\n .command(\"status\")\n .description(\"Show current authentication status\")\n .action(() => {\n const opts = parent.opts();\n const apiKey = getApiKey(opts);\n const baseUrl = getBaseUrl(opts);\n\n if (isJsonMode()) {\n printJson({\n authenticated: !!apiKey,\n key_prefix: apiKey ? apiKey.slice(0, 8) + \"...\" : null,\n base_url: baseUrl,\n });\n return;\n }\n\n if (apiKey) {\n printDetail([\n [\"Authenticated\", \"Yes\"],\n [\"API Key\", apiKey.slice(0, 8) + \"...\"],\n [\"Base URL\", baseUrl],\n ]);\n } else {\n printWarning(\n \"Not authenticated. Run `tt auth login` to store an API key.\",\n );\n printDetail([[\"Base URL\", baseUrl]]);\n }\n });\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nexport interface Config {\n api_key?: string;\n base_url?: string;\n}\n\nconst CONFIG_DIR_NAME = \"tuned-tensor\";\nconst CONFIG_FILE_NAME = \"config.json\";\n\nfunction getConfigDir(): string {\n const xdg = process.env.XDG_CONFIG_HOME;\n const base = xdg || join(homedir(), \".config\");\n return join(base, CONFIG_DIR_NAME);\n}\n\nfunction getConfigPath(): string {\n return join(getConfigDir(), CONFIG_FILE_NAME);\n}\n\nexport function readConfig(): Config {\n const path = getConfigPath();\n if (!existsSync(path)) return {};\n try {\n return JSON.parse(readFileSync(path, \"utf-8\"));\n } catch {\n return {};\n }\n}\n\nexport function writeConfig(config: Config): void {\n const dir = getConfigDir();\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n writeFileSync(getConfigPath(), JSON.stringify(config, null, 2) + \"\\n\");\n}\n\nexport function updateConfig(partial: Partial<Config>): void {\n const current = readConfig();\n writeConfig({ ...current, ...partial });\n}\n\nexport function clearConfig(): void {\n const path = getConfigPath();\n if (existsSync(path)) writeFileSync(path, \"{}\\n\");\n}\n\nexport const DEFAULT_BASE_URL = \"https://www.tunedtensor.com\";\n\nexport function getBaseUrl(opts?: { baseUrl?: string }): string {\n return opts?.baseUrl || process.env.TUNED_TENSOR_URL || readConfig().base_url || DEFAULT_BASE_URL;\n}\n\nexport function getApiKey(opts?: { apiKey?: string }): string | undefined {\n return opts?.apiKey || process.env.TUNED_TENSOR_API_KEY || readConfig().api_key;\n}\n","import { Command } from \"commander\";\nimport { readFileSync } from \"node:fs\";\nimport { get, post, put, del, type ClientOpts } from \"../client.js\";\nimport {\n printTable,\n printDetail,\n printSuccess,\n printJson,\n isJsonMode,\n formatDate,\n formatStatus,\n truncate,\n shortId,\n} from \"../output.js\";\n\ninterface BehaviorSpec {\n id: string;\n name: string;\n description: string;\n system_prompt: string;\n guidelines: string[];\n examples: { input: string; output: string }[];\n constraints: string[];\n base_model: string;\n created_at: string;\n updated_at: string;\n _run_count?: number;\n _latest_run_status?: string;\n _latest_run_score?: number;\n _runs?: unknown[];\n}\n\nexport function registerSpecsCommands(parent: Command) {\n const specs = parent\n .command(\"specs\")\n .description(\"Manage behaviour specs\");\n\n specs\n .command(\"list\")\n .description(\"List behaviour specs\")\n .option(\"-p, --page <n>\", \"Page number\", \"1\")\n .option(\"--per-page <n>\", \"Results per page\", \"20\")\n .action(async (cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n const { data, meta } = await get<BehaviorSpec[]>(\n \"/behavior-specs\",\n { page: cmdOpts.page, per_page: cmdOpts.perPage },\n opts,\n );\n\n if (isJsonMode()) return printJson({ data, meta });\n\n printTable(\n [\"ID\", \"Name\", \"Model\", \"Examples\", \"Runs\", \"Status\", \"Updated\"],\n data.map((s) => [\n shortId(s.id),\n truncate(s.name, 30),\n s.base_model.split(\"/\").pop() || s.base_model,\n String(s.examples?.length ?? 0),\n String(s._run_count ?? 0),\n s._latest_run_status ? formatStatus(s._latest_run_status) : \"—\",\n formatDate(s.updated_at),\n ]),\n meta,\n );\n });\n\n specs\n .command(\"get\")\n .description(\"Show spec details\")\n .argument(\"<id>\", \"Spec ID (full or prefix)\")\n .action(async (id: string) => {\n const opts = parent.opts() as ClientOpts;\n const { data } = await get<BehaviorSpec>(`/behavior-specs/${id}`, undefined, opts);\n\n if (isJsonMode()) return printJson(data);\n\n printDetail([\n [\"ID\", data.id],\n [\"Name\", data.name],\n [\"Description\", data.description || undefined],\n [\"Base Model\", data.base_model],\n [\"System Prompt\", data.system_prompt ? truncate(data.system_prompt, 80) : undefined],\n [\"Guidelines\", data.guidelines?.length ? data.guidelines.join(\", \") : undefined],\n [\"Constraints\", data.constraints?.length ? data.constraints.join(\", \") : undefined],\n [\"Examples\", String(data.examples?.length ?? 0)],\n [\"Runs\", String(data._run_count ?? data._runs?.length ?? 0)],\n [\"Created\", formatDate(data.created_at)],\n [\"Updated\", formatDate(data.updated_at)],\n ]);\n\n if (data.examples?.length) {\n console.log(\"\\nExamples:\");\n for (const [i, ex] of data.examples.slice(0, 5).entries()) {\n console.log(` ${i + 1}. Input: ${truncate(ex.input, 60)}`);\n console.log(` Output: ${truncate(ex.output, 60)}`);\n }\n if (data.examples.length > 5) {\n console.log(` ... and ${data.examples.length - 5} more`);\n }\n }\n });\n\n specs\n .command(\"create\")\n .description(\"Create a behaviour spec\")\n .option(\"-f, --file <path>\", \"JSON file with spec definition\")\n .option(\"-n, --name <name>\", \"Spec name\")\n .option(\"--model <model>\", \"Base model ID\")\n .action(async (cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n let body: Record<string, unknown>;\n\n if (cmdOpts.file) {\n body = JSON.parse(readFileSync(cmdOpts.file, \"utf-8\"));\n } else if (cmdOpts.name) {\n body = { name: cmdOpts.name };\n if (cmdOpts.model) body.base_model = cmdOpts.model;\n } else {\n console.error(\"Provide --file or --name\");\n process.exit(1);\n }\n\n const { data } = await post<BehaviorSpec>(\"/behavior-specs\", body, opts);\n\n if (isJsonMode()) return printJson(data);\n printSuccess(`Spec created: ${data.name} (${shortId(data.id)})`);\n });\n\n specs\n .command(\"update\")\n .description(\"Update a behaviour spec\")\n .argument(\"<id>\", \"Spec ID\")\n .option(\"-f, --file <path>\", \"JSON file with fields to update\")\n .option(\"-n, --name <name>\", \"New name\")\n .option(\"--model <model>\", \"New base model ID\")\n .action(async (id: string, cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n let body: Record<string, unknown>;\n\n if (cmdOpts.file) {\n body = JSON.parse(readFileSync(cmdOpts.file, \"utf-8\"));\n } else {\n body = {};\n if (cmdOpts.name) body.name = cmdOpts.name;\n if (cmdOpts.model) body.base_model = cmdOpts.model;\n }\n\n const { data } = await put<BehaviorSpec>(\n `/behavior-specs/${id}`,\n body,\n opts,\n );\n\n if (isJsonMode()) return printJson(data);\n printSuccess(`Spec updated: ${data.name} (${shortId(data.id)})`);\n });\n\n specs\n .command(\"delete\")\n .description(\"Delete a behaviour spec\")\n .argument(\"<id>\", \"Spec ID\")\n .action(async (id: string) => {\n const opts = parent.opts() as ClientOpts;\n await del(`/behavior-specs/${id}`, opts);\n\n if (isJsonMode()) return printJson({ id, deleted: true });\n printSuccess(`Spec deleted: ${shortId(id)}`);\n });\n}\n","import { readFileSync, statSync } from \"node:fs\";\nimport { basename } from \"node:path\";\nimport { getApiKey, getBaseUrl } from \"./config.js\";\n\nexport interface ApiResponse<T> {\n data: T;\n meta?: { page: number; per_page: number; total: number };\n}\n\nexport interface ApiErrorBody {\n error: { code: string; message: string };\n}\n\nexport class ApiError extends Error {\n constructor(\n public status: number,\n public code: string,\n message: string,\n ) {\n super(message);\n this.name = \"ApiError\";\n }\n}\n\nexport interface ClientOpts {\n apiKey?: string;\n baseUrl?: string;\n}\n\nfunction resolveKey(opts?: ClientOpts): string {\n const key = getApiKey(opts);\n if (!key) {\n throw new ApiError(\n 401,\n \"NO_API_KEY\",\n \"No API key found. Run `tt auth login` or set TUNED_TENSOR_API_KEY.\",\n );\n }\n return key;\n}\n\nfunction buildUrl(\n path: string,\n query?: Record<string, string | number | undefined>,\n opts?: ClientOpts,\n): string {\n const base = getBaseUrl(opts);\n const url = new URL(`/api/v1${path}`, base);\n if (query) {\n for (const [k, v] of Object.entries(query)) {\n if (v !== undefined) url.searchParams.set(k, String(v));\n }\n }\n return url.toString();\n}\n\nasync function request<T>(\n method: string,\n path: string,\n options: {\n query?: Record<string, string | number | undefined>;\n body?: unknown;\n opts?: ClientOpts;\n } = {},\n): Promise<ApiResponse<T>> {\n const key = resolveKey(options.opts);\n const url = buildUrl(path, options.query, options.opts);\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${key}`,\n };\n\n let bodyPayload: string | undefined;\n if (options.body) {\n headers[\"Content-Type\"] = \"application/json\";\n bodyPayload = JSON.stringify(options.body);\n }\n\n const res = await fetch(url, { method, headers, body: bodyPayload });\n\n if (!res.ok) {\n let errBody: ApiErrorBody;\n try {\n errBody = (await res.json()) as ApiErrorBody;\n } catch {\n throw new ApiError(res.status, \"UNKNOWN\", res.statusText);\n }\n throw new ApiError(\n res.status,\n errBody.error?.code || \"UNKNOWN\",\n errBody.error?.message || res.statusText,\n );\n }\n\n if (res.status === 204) return { data: null as T };\n return (await res.json()) as ApiResponse<T>;\n}\n\nexport function get<T>(\n path: string,\n query?: Record<string, string | number | undefined>,\n opts?: ClientOpts,\n) {\n return request<T>(\"GET\", path, { query, opts });\n}\n\nexport function post<T>(\n path: string,\n body?: unknown,\n opts?: ClientOpts,\n) {\n return request<T>(\"POST\", path, { body, opts });\n}\n\nexport function put<T>(\n path: string,\n body?: unknown,\n opts?: ClientOpts,\n) {\n return request<T>(\"PUT\", path, { body, opts });\n}\n\nexport function patch<T>(\n path: string,\n body?: unknown,\n opts?: ClientOpts,\n) {\n return request<T>(\"PATCH\", path, { body, opts });\n}\n\nexport function del<T>(path: string, opts?: ClientOpts) {\n return request<T>(\"DELETE\", path, { opts });\n}\n\nexport async function upload<T>(\n path: string,\n filePath: string,\n fields: Record<string, string>,\n opts?: ClientOpts,\n): Promise<ApiResponse<T>> {\n const key = resolveKey(opts);\n const url = buildUrl(path, undefined, opts);\n\n const form = new FormData();\n for (const [k, v] of Object.entries(fields)) {\n form.append(k, v);\n }\n\n const fileBytes = readFileSync(filePath);\n const fileSize = statSync(filePath).size;\n const blob = new Blob([fileBytes], { type: \"application/jsonl\" });\n form.append(\"file\", blob, basename(filePath));\n\n const res = await fetch(url, {\n method: \"POST\",\n headers: { Authorization: `Bearer ${key}` },\n body: form,\n });\n\n if (!res.ok) {\n let errBody: ApiErrorBody;\n try {\n errBody = (await res.json()) as ApiErrorBody;\n } catch {\n throw new ApiError(res.status, \"UNKNOWN\", res.statusText);\n }\n throw new ApiError(\n res.status,\n errBody.error?.code || \"UNKNOWN\",\n errBody.error?.message || res.statusText,\n );\n }\n\n return (await res.json()) as ApiResponse<T>;\n}\n","import { Command } from \"commander\";\nimport ora from \"ora\";\nimport { get, post, type ClientOpts } from \"../client.js\";\nimport {\n printTable,\n printDetail,\n printSuccess,\n printJson,\n isJsonMode,\n formatDate,\n formatStatus,\n shortId,\n truncate,\n} from \"../output.js\";\n\ninterface Run {\n id: string;\n behavior_spec_id: string;\n run_number: number;\n status: string;\n current_stage?: string | null;\n stage_label?: string | null;\n progress_pct?: number | null;\n status_message?: string | null;\n hyperparameters: Record<string, unknown> | null;\n eval_summary: { mean_score?: number; pass_rate?: number } | null;\n error: string | null;\n started_at: string | null;\n completed_at: string | null;\n created_at: string;\n updated_at: string;\n _spec_name?: string;\n _evals?: RunEval[];\n _events?: RunEvent[];\n}\n\ninterface RunEval {\n id: string;\n prompt: string;\n expected: string;\n actual: string;\n passed: boolean;\n score: number | null;\n reasoning: string | null;\n latency_ms: number | null;\n}\n\ninterface RunEvent {\n id: string;\n stage: string;\n label: string;\n status: string;\n message: string | null;\n occurred_at: string;\n}\n\nfunction formatProgress(run: Run): string | undefined {\n if (run.progress_pct == null && !run.stage_label) return undefined;\n const label = run.stage_label ?? run.current_stage ?? \"Progress\";\n return run.progress_pct == null ? label : `${label} (${run.progress_pct}%)`;\n}\n\nexport function registerRunsCommands(parent: Command) {\n const runs = parent.command(\"runs\").description(\"Manage runs\");\n\n runs\n .command(\"list\")\n .description(\"List runs\")\n .option(\"-s, --spec <id>\", \"Filter by spec ID\")\n .option(\"-p, --page <n>\", \"Page number\", \"1\")\n .option(\"--per-page <n>\", \"Results per page\", \"20\")\n .action(async (cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n\n let path = \"/runs\";\n const query: Record<string, string | number> = {\n page: cmdOpts.page,\n per_page: cmdOpts.perPage,\n };\n\n if (cmdOpts.spec) {\n path = `/behavior-specs/${cmdOpts.spec}/runs`;\n }\n\n const { data, meta } = await get<Run[]>(path, query, opts);\n\n if (isJsonMode()) return printJson({ data, meta });\n\n printTable(\n [\"ID\", \"Spec\", \"#\", \"Status\", \"Score\", \"Started\", \"Completed\"],\n data.map((r) => [\n shortId(r.id),\n r._spec_name ? truncate(r._spec_name, 20) : shortId(r.behavior_spec_id),\n String(r.run_number),\n formatStatus(r.status),\n r.eval_summary?.mean_score != null\n ? (r.eval_summary.mean_score * 100).toFixed(1) + \"%\"\n : \"—\",\n formatDate(r.started_at),\n formatDate(r.completed_at),\n ]),\n meta,\n );\n });\n\n runs\n .command(\"get\")\n .description(\"Show run details and eval results\")\n .argument(\"<id>\", \"Run ID\")\n .action(async (id: string) => {\n const opts = parent.opts() as ClientOpts;\n const { data } = await get<Run>(`/runs/${id}`, undefined, opts);\n\n if (isJsonMode()) return printJson(data);\n\n printDetail([\n [\"ID\", data.id],\n [\"Spec\", data._spec_name ?? shortId(data.behavior_spec_id)],\n [\"Run #\", String(data.run_number)],\n [\"Status\", formatStatus(data.status)],\n [\"Stage\", formatProgress(data)],\n [\"Message\", data.status_message ?? undefined],\n [\"Score\", data.eval_summary?.mean_score != null\n ? (data.eval_summary.mean_score * 100).toFixed(1) + \"%\"\n : undefined],\n [\"Pass Rate\", data.eval_summary?.pass_rate != null\n ? (data.eval_summary.pass_rate * 100).toFixed(1) + \"%\"\n : undefined],\n [\"Error\", data.error ?? undefined],\n [\"Started\", formatDate(data.started_at)],\n [\"Completed\", formatDate(data.completed_at)],\n [\"Created\", formatDate(data.created_at)],\n ]);\n\n if (data.hyperparameters && Object.keys(data.hyperparameters).length) {\n console.log(\"\\nHyperparameters:\");\n for (const [k, v] of Object.entries(data.hyperparameters)) {\n console.log(` ${k}: ${v}`);\n }\n }\n\n if (data._events?.length) {\n console.log(\"\\nLatest Updates:\");\n for (const event of data._events.slice(-5)) {\n const time = formatDate(event.occurred_at);\n console.log(\n ` ${time} ${formatStatus(event.status)} ${event.label}${event.message ? ` — ${event.message}` : \"\"}`,\n );\n }\n }\n\n if (data._evals?.length) {\n console.log(`\\nEval Results (${data._evals.length}):`);\n printTable(\n [\"#\", \"Passed\", \"Score\", \"Prompt\", \"Latency\"],\n data._evals.map((e, i) => [\n String(i + 1),\n e.passed ? \"✓\" : \"✗\",\n e.score != null ? e.score.toFixed(2) : \"—\",\n truncate(e.prompt, 40),\n e.latency_ms != null ? `${e.latency_ms}ms` : \"—\",\n ]),\n );\n }\n });\n\n runs\n .command(\"start\")\n .description(\"Start a new run for a behaviour spec\")\n .argument(\"<spec-id>\", \"Behaviour spec ID\")\n .option(\"--no-augment\", \"Disable data augmentation\")\n .option(\"--epochs <n>\", \"Number of training epochs\")\n .option(\"--lr <rate>\", \"Learning rate\")\n .option(\"--batch-size <n>\", \"Batch size\")\n .option(\"--lora-rank <n>\", \"LoRA rank\")\n .option(\"--lora-alpha <n>\", \"LoRA alpha\")\n .action(async (specId: string, cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n const body: Record<string, unknown> = {};\n\n if (cmdOpts.augment === false) body.augment = false;\n\n const hp: Record<string, unknown> = {};\n if (cmdOpts.epochs) hp.n_epochs = Number(cmdOpts.epochs);\n if (cmdOpts.lr) hp.learning_rate = Number(cmdOpts.lr);\n if (cmdOpts.batchSize) hp.batch_size = Number(cmdOpts.batchSize);\n if (cmdOpts.loraRank) hp.lora_rank = Number(cmdOpts.loraRank);\n if (cmdOpts.loraAlpha) hp.lora_alpha = Number(cmdOpts.loraAlpha);\n if (Object.keys(hp).length) body.hyperparameters = hp;\n\n const { data } = await post<Run>(\n `/behavior-specs/${specId}/runs`,\n body,\n opts,\n );\n\n if (isJsonMode()) return printJson(data);\n printSuccess(\n `Run #${data.run_number} started (${shortId(data.id)}). ${formatProgress(data) ?? `Status: ${formatStatus(data.status)}`}`,\n );\n });\n\n runs\n .command(\"cancel\")\n .description(\"Cancel a running run\")\n .argument(\"<id>\", \"Run ID\")\n .action(async (id: string) => {\n const opts = parent.opts() as ClientOpts;\n const { data } = await post<Run>(`/runs/${id}/cancel`, undefined, opts);\n\n if (isJsonMode()) return printJson(data);\n printSuccess(`Run ${shortId(id)} cancelled.`);\n });\n\n runs\n .command(\"watch\")\n .description(\"Watch a run until it completes\")\n .argument(\"<id>\", \"Run ID\")\n .option(\"--interval <ms>\", \"Poll interval in milliseconds\", \"5000\")\n .action(async (id: string, cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n const interval = Number(cmdOpts.interval);\n const spinner = ora(`Watching run ${shortId(id)}...`).start();\n\n const terminalStates = new Set([\n \"completed\",\n \"failed\",\n \"cancelled\",\n ]);\n\n let run: Run;\n while (true) {\n const { data } = await get<Run>(`/runs/${id}`, undefined, opts);\n run = data;\n spinner.text = `Run ${shortId(id)} — ${formatProgress(run) ?? formatStatus(run.status)}`;\n\n if (terminalStates.has(run.status)) break;\n await new Promise((r) => setTimeout(r, interval));\n }\n\n spinner.stop();\n\n if (isJsonMode()) return printJson(run);\n\n printDetail([\n [\"Run\", shortId(run.id)],\n [\"Status\", formatStatus(run.status)],\n [\"Stage\", formatProgress(run)],\n [\"Message\", run.status_message ?? undefined],\n [\"Score\", run.eval_summary?.mean_score != null\n ? (run.eval_summary.mean_score * 100).toFixed(1) + \"%\"\n : undefined],\n [\"Error\", run.error ?? undefined],\n [\"Completed\", formatDate(run.completed_at)],\n ]);\n });\n}\n","import { Command } from \"commander\";\nimport { existsSync } from \"node:fs\";\nimport { get, del, upload, type ClientOpts } from \"../client.js\";\nimport {\n printTable,\n printDetail,\n printSuccess,\n printJson,\n printError,\n isJsonMode,\n formatDate,\n formatStatus,\n shortId,\n truncate,\n} from \"../output.js\";\n\ninterface Dataset {\n id: string;\n name: string;\n description: string | null;\n storage_path: string;\n file_size_bytes: number;\n row_count: number;\n format: string;\n status: string;\n validation_errors: string[] | null;\n created_at: string;\n updated_at: string;\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nexport function registerDatasetsCommands(parent: Command) {\n const datasets = parent\n .command(\"datasets\")\n .description(\"Manage datasets\");\n\n datasets\n .command(\"list\")\n .description(\"List datasets\")\n .option(\"-p, --page <n>\", \"Page number\", \"1\")\n .option(\"--per-page <n>\", \"Results per page\", \"20\")\n .action(async (cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n const { data, meta } = await get<Dataset[]>(\n \"/datasets\",\n { page: cmdOpts.page, per_page: cmdOpts.perPage },\n opts,\n );\n\n if (isJsonMode()) return printJson({ data, meta });\n\n printTable(\n [\"ID\", \"Name\", \"Rows\", \"Size\", \"Status\", \"Created\"],\n data.map((d) => [\n shortId(d.id),\n truncate(d.name, 30),\n String(d.row_count),\n formatBytes(d.file_size_bytes),\n formatStatus(d.status),\n formatDate(d.created_at),\n ]),\n meta,\n );\n });\n\n datasets\n .command(\"get\")\n .description(\"Show dataset details\")\n .argument(\"<id>\", \"Dataset ID\")\n .action(async (id: string) => {\n const opts = parent.opts() as ClientOpts;\n const { data } = await get<Dataset>(`/datasets/${id}`, undefined, opts);\n\n if (isJsonMode()) return printJson(data);\n\n printDetail([\n [\"ID\", data.id],\n [\"Name\", data.name],\n [\"Description\", data.description ?? undefined],\n [\"Format\", data.format],\n [\"Rows\", String(data.row_count)],\n [\"Size\", formatBytes(data.file_size_bytes)],\n [\"Status\", formatStatus(data.status)],\n [\"Created\", formatDate(data.created_at)],\n [\"Updated\", formatDate(data.updated_at)],\n ]);\n\n if (data.validation_errors?.length) {\n console.log(\"\\nValidation Errors:\");\n for (const err of data.validation_errors) {\n console.log(` - ${err}`);\n }\n }\n });\n\n datasets\n .command(\"upload\")\n .description(\"Upload a JSONL dataset file\")\n .argument(\"<file>\", \"Path to JSONL file\")\n .option(\"-n, --name <name>\", \"Dataset name (defaults to filename)\")\n .option(\"-d, --description <desc>\", \"Dataset description\")\n .action(async (file: string, cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n\n if (!existsSync(file)) {\n printError(`File not found: ${file}`);\n process.exit(1);\n }\n\n const fields: Record<string, string> = {\n name: cmdOpts.name || file.split(\"/\").pop()!.replace(/\\.jsonl?$/, \"\"),\n };\n if (cmdOpts.description) fields.description = cmdOpts.description;\n\n const { data } = await upload<Dataset>(\n \"/datasets\",\n file,\n fields,\n opts,\n );\n\n if (isJsonMode()) return printJson(data);\n printSuccess(\n `Dataset uploaded: ${data.name} (${shortId(data.id)}) — ${data.row_count} rows`,\n );\n });\n\n datasets\n .command(\"delete\")\n .description(\"Delete a dataset\")\n .argument(\"<id>\", \"Dataset ID\")\n .action(async (id: string) => {\n const opts = parent.opts() as ClientOpts;\n await del(`/datasets/${id}`, opts);\n\n if (isJsonMode()) return printJson({ id, deleted: true });\n printSuccess(`Dataset deleted: ${shortId(id)}`);\n });\n}\n","import { Command } from \"commander\";\nimport { get, del, type ClientOpts } from \"../client.js\";\nimport {\n printTable,\n printDetail,\n printSuccess,\n printJson,\n isJsonMode,\n formatDate,\n shortId,\n truncate,\n} from \"../output.js\";\n\ninterface Model {\n id: string;\n name: string;\n provider: string;\n provider_model_id: string;\n base_model: string;\n description: string | null;\n created_at: string;\n}\n\nexport function registerModelsCommands(parent: Command) {\n const models = parent.command(\"models\").description(\"Manage fine-tuned models\");\n\n models\n .command(\"list\")\n .description(\"List fine-tuned models\")\n .option(\"-p, --page <n>\", \"Page number\", \"1\")\n .option(\"--per-page <n>\", \"Results per page\", \"20\")\n .action(async (cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n const { data, meta } = await get<Model[]>(\n \"/models\",\n { page: cmdOpts.page, per_page: cmdOpts.perPage },\n opts,\n );\n\n if (isJsonMode()) return printJson({ data, meta });\n\n printTable(\n [\"ID\", \"Name\", \"Base Model\", \"Provider\", \"Created\"],\n data.map((m) => [\n shortId(m.id),\n truncate(m.name, 30),\n m.base_model.split(\"/\").pop() || m.base_model,\n m.provider,\n formatDate(m.created_at),\n ]),\n meta,\n );\n });\n\n models\n .command(\"get\")\n .description(\"Show model details\")\n .argument(\"<id>\", \"Model ID\")\n .action(async (id: string) => {\n const opts = parent.opts() as ClientOpts;\n const { data } = await get<Model>(`/models/${id}`, undefined, opts);\n\n if (isJsonMode()) return printJson(data);\n\n printDetail([\n [\"ID\", data.id],\n [\"Name\", data.name],\n [\"Base Model\", data.base_model],\n [\"Provider\", data.provider],\n [\"Provider Model\", data.provider_model_id],\n [\"Description\", data.description ?? undefined],\n [\"Created\", formatDate(data.created_at)],\n ]);\n });\n\n models\n .command(\"delete\")\n .description(\"Delete a model\")\n .argument(\"<id>\", \"Model ID\")\n .action(async (id: string) => {\n const opts = parent.opts() as ClientOpts;\n await del(`/models/${id}`, opts);\n\n if (isJsonMode()) return printJson({ id, deleted: true });\n printSuccess(`Model deleted: ${shortId(id)}`);\n });\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { get, type ClientOpts } from \"../client.js\";\nimport {\n printDetail,\n printJson,\n printTable,\n isJsonMode,\n formatDate,\n formatStatus,\n shortId,\n} from \"../output.js\";\n\ninterface BalanceResponse {\n balance_cents: number;\n reserved_cents: number;\n available_cents: number;\n lifetime_topup_cents: number;\n signup_bonus_cents: number;\n signup_bonus_granted: boolean;\n}\n\ntype CreditKind =\n | \"signup_bonus\"\n | \"topup\"\n | \"debit_run\"\n | \"debit_autotune\"\n | \"refund\"\n | \"adjustment\";\n\ninterface LedgerRow {\n id: string;\n kind: CreditKind;\n amount_cents: number;\n balance_after_cents: number;\n reference_id: string | null;\n created_at: string;\n}\n\nconst KIND_LABELS: Record<CreditKind, string> = {\n signup_bonus: \"Signup bonus\",\n topup: \"Top-up\",\n debit_run: \"Run\",\n debit_autotune: \"Auto-tune\",\n refund: \"Refund\",\n adjustment: \"Adjustment\",\n};\n\nfunction formatCents(cents: number): string {\n const sign = cents < 0 ? \"-\" : \"\";\n const abs = Math.abs(cents);\n return `${sign}$${(abs / 100).toFixed(2)}`;\n}\n\nfunction formatSigned(cents: number): string {\n if (cents > 0) return chalk.green(`+${formatCents(cents)}`);\n if (cents < 0) return chalk.red(formatCents(cents));\n return formatCents(cents);\n}\n\nexport function registerBalanceCommands(parent: Command) {\n parent\n .command(\"balance\")\n .description(\"Show available credits, held credits, and recent transactions\")\n .option(\"-n, --limit <n>\", \"Number of transactions to show (default 10)\", \"10\")\n .action(async (options) => {\n const opts = parent.opts() as ClientOpts;\n const limit = Number(options.limit) || 10;\n\n const [{ data: balance }, { data: transactions }] = await Promise.all([\n get<BalanceResponse>(\"/billing/balance\", undefined, opts),\n get<LedgerRow[]>(\"/billing/transactions\", { per_page: limit }, opts),\n ]);\n\n if (isJsonMode()) {\n return printJson({ balance, transactions });\n }\n\n const lowBalance = balance.available_cents < 100;\n const availableLine = lowBalance\n ? chalk.red(formatCents(balance.available_cents)) + chalk.dim(\" (low)\")\n : chalk.bold.green(formatCents(balance.available_cents));\n\n printDetail([\n [\"Available\", availableLine],\n [\"Total balance\", formatCents(balance.balance_cents)],\n [\"On hold\", formatCents(balance.reserved_cents)],\n [\n \"Signup bonus\",\n balance.signup_bonus_granted\n ? chalk.green(\"granted\") + ` (${formatCents(balance.signup_bonus_cents)})`\n : chalk.dim(\"not yet granted\"),\n ],\n [\"Lifetime top-ups\", formatCents(balance.lifetime_topup_cents)],\n ]);\n\n if (transactions && transactions.length > 0) {\n console.log(`\\n${chalk.bold(\"Recent transactions\")}`);\n printTable(\n [\"Date\", \"Type\", \"Amount\", \"Balance\", \"Reference\"],\n transactions.map((row) => [\n formatDate(row.created_at),\n KIND_LABELS[row.kind] ?? row.kind,\n formatSigned(row.amount_cents),\n formatCents(row.balance_after_cents),\n row.reference_id ? shortId(row.reference_id) : chalk.dim(\"—\"),\n ])\n );\n } else {\n console.log(\n `\\n${chalk.dim(\"No transactions yet — run `tt topup` to add credits.\")}`\n );\n }\n\n if (lowBalance) {\n console.log(\n `\\n${formatStatus(\"preparing\")} ${chalk.yellow(\n \"Run `tt topup` to add more available credits before starting a run.\"\n )}`\n );\n }\n });\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport open from \"open\";\nimport { post, type ClientOpts } from \"../client.js\";\nimport { printJson, isJsonMode, printSuccess } from \"../output.js\";\n\ninterface TopupResponse {\n checkout_url: string;\n session_id: string;\n}\n\nconst PRESETS_USD = [10, 25, 50, 100];\nconst MIN_USD = 5;\nconst MAX_USD = 10000;\n\nfunction parseAmount(input: string | undefined): number | null {\n if (!input) return null;\n const cleaned = input.replace(/^\\$/, \"\").trim();\n const num = Number(cleaned);\n if (!Number.isFinite(num) || num <= 0) return null;\n return num;\n}\n\nasync function readLine(prompt: string): Promise<string> {\n const readline = await import(\"node:readline/promises\");\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n try {\n return (await rl.question(prompt)).trim();\n } finally {\n rl.close();\n }\n}\n\nexport function registerTopupCommands(parent: Command) {\n parent\n .command(\"topup\")\n .description(\"Add prepaid credits via Stripe Checkout\")\n .option(\"-a, --amount <usd>\", \"Amount in USD (e.g. 25)\")\n .option(\"--no-open\", \"Print checkout URL instead of opening the browser\")\n .action(async (options) => {\n const opts = parent.opts() as ClientOpts;\n\n let amountUsd: number | null;\n\n if (options.amount !== undefined) {\n amountUsd = parseAmount(options.amount);\n if (amountUsd === null) {\n throw new Error(\"Invalid amount\");\n }\n } else {\n if (isJsonMode()) {\n throw new Error(\n \"amount is required in --json mode (use --amount <usd>)\"\n );\n }\n console.log(chalk.bold(\"Add credits via Stripe Checkout\"));\n console.log(\n chalk.dim(\n `Quick picks: ${PRESETS_USD.map((n) => `$${n}`).join(\", \")}`\n )\n );\n const input = await readLine(`Amount in USD (min $${MIN_USD}): `);\n amountUsd = parseAmount(input);\n if (amountUsd === null) {\n throw new Error(\"Invalid amount\");\n }\n }\n\n if (amountUsd < MIN_USD) {\n throw new Error(`Minimum top-up is $${MIN_USD}`);\n }\n if (amountUsd > MAX_USD) {\n throw new Error(`Maximum top-up is $${MAX_USD}`);\n }\n\n const amountCents = Math.round(amountUsd * 100);\n\n const { data } = await post<TopupResponse>(\n \"/billing/topup\",\n { amount_cents: amountCents },\n opts\n );\n\n if (isJsonMode()) {\n return printJson(data);\n }\n\n const url = data.checkout_url;\n console.log(\n `${chalk.bold(\"Checkout URL:\")} ${chalk.cyan(url)}\\n` +\n chalk.dim(\"Complete the payment to credit your account.\")\n );\n\n if (options.open !== false) {\n try {\n await open(url);\n printSuccess(\"Opened Stripe Checkout in your browser.\");\n } catch {\n console.log(\n chalk.yellow(\n \"Could not open browser automatically — copy the URL above.\"\n )\n );\n }\n }\n });\n}\n","import { Command } from \"commander\";\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { printSuccess, printError, printWarning } from \"../output.js\";\nimport type { LocalSpec } from \"../eval/types.js\";\n\nconst DEFAULT_SPEC_FILE = \"tunedtensor.json\";\n\nconst SCAFFOLD: LocalSpec = {\n name: \"My Agent\",\n description: \"\",\n base_model: \"meta-llama/Llama-3.2-3B-Instruct\",\n system_prompt: \"You are a helpful assistant.\",\n guidelines: [],\n constraints: [],\n examples: [\n { input: \"Hello\", output: \"Hi! How can I help you today?\" },\n ],\n eval_cases: [],\n};\n\nexport function registerInitCommand(parent: Command) {\n parent\n .command(\"init\")\n .description(\"Create a local behaviour spec file\")\n .option(\"-n, --name <name>\", \"Spec name\")\n .option(\"--model <model>\", \"Base model ID\")\n .option(\"-f, --file <path>\", \"Output file path\", DEFAULT_SPEC_FILE)\n .action(async (cmdOpts) => {\n const filePath = resolve(cmdOpts.file);\n\n if (existsSync(filePath)) {\n printWarning(`${cmdOpts.file} already exists. Use tt eval to run evals or edit it directly.`);\n return;\n }\n\n const spec: LocalSpec = { ...SCAFFOLD };\n if (cmdOpts.name) spec.name = cmdOpts.name;\n if (cmdOpts.model) spec.base_model = cmdOpts.model;\n\n writeFileSync(filePath, JSON.stringify(spec, null, 2) + \"\\n\");\n printSuccess(`Created ${cmdOpts.file}`);\n console.log(\"\\nNext steps:\");\n console.log(\" 1. Edit the spec: system_prompt, guidelines, examples\");\n console.log(\" 2. Run evals: tt eval --model <model-id>\");\n console.log(\" 3. Push to remote: tt push\");\n });\n}\n\nexport function loadSpec(filePath?: string): LocalSpec {\n const resolved = resolve(filePath || DEFAULT_SPEC_FILE);\n if (!existsSync(resolved)) {\n printError(\n `Spec file not found: ${filePath || DEFAULT_SPEC_FILE}\\nRun \\`tt init\\` to create one.`,\n );\n process.exit(1);\n }\n\n const raw = JSON.parse(readFileSync(resolved, \"utf-8\"));\n return raw as LocalSpec;\n}\n\nexport { DEFAULT_SPEC_FILE };\n","import { Command } from \"commander\";\nimport ora from \"ora\";\nimport chalk from \"chalk\";\nimport {\n printTable,\n printJson,\n isJsonMode,\n printWarning,\n truncate,\n} from \"../output.js\";\nimport type { ClientOpts } from \"../client.js\";\nimport { loadSpec, DEFAULT_SPEC_FILE } from \"./init.js\";\nimport { runEvals } from \"../eval/runner.js\";\nimport type { EvalSummary, ValidationCheck } from \"../eval/types.js\";\n\nexport function registerEvalCommand(parent: Command) {\n parent\n .command(\"eval\")\n .description(\"Evaluate a model against a behaviour spec using rule-based assertions\")\n .requiredOption(\"-m, --model <model>\", \"Model ID to evaluate (base or fine-tuned)\")\n .option(\"-f, --file <path>\", \"Spec file path\", DEFAULT_SPEC_FILE)\n .action(async (cmdOpts) => {\n const spec = loadSpec(cmdOpts.file);\n const clientOpts = parent.opts() as ClientOpts;\n\n if (!isJsonMode()) {\n console.log(chalk.dim(`\\nSpec: ${cmdOpts.file} | Model: ${cmdOpts.model}\\n`));\n }\n\n const spinner = ora(\"Running evals...\").start();\n\n const summary = await runEvals(spec, cmdOpts.model, {\n clientOpts,\n onProgress: (done, total) => { spinner.text = `Running evals... ${done}/${total}`; },\n });\n\n spinner.stop();\n\n if (isJsonMode()) return printJson(summary);\n\n printValidation(summary.spec_validation.checks);\n console.log();\n printResults(summary);\n });\n}\n\nfunction printValidation(checks: ValidationCheck[]) {\n console.log(chalk.bold(\"Spec Validation\"));\n for (const check of checks) {\n const icon = check.passed ? chalk.green(\"✓\") : chalk.red(\"✗\");\n const msg = check.message\n ? chalk.dim(` — ${check.message}`)\n : \"\";\n console.log(` ${icon} ${check.name}${msg}`);\n }\n}\n\nfunction printResults(summary: EvalSummary) {\n if (!summary.results.length) {\n printWarning(\"No eval cases to run. Add examples or eval_cases to your spec.\");\n return;\n }\n\n console.log(chalk.bold(`Eval Results (${summary.total}):`));\n\n printTable(\n [\"#\", \"Passed\", \"Input\", \"Latency\"],\n summary.results.map((r, i) => [\n String(i + 1),\n r.passed ? chalk.green(\"✓\") : chalk.red(\"✗\"),\n truncate(r.input, 40),\n r.latency_ms != null ? `${r.latency_ms}ms` : \"—\",\n ]),\n );\n\n console.log();\n\n const passStr = (summary.pass_rate * 100).toFixed(1) + \"%\";\n const color = summary.pass_rate >= 0.8\n ? chalk.green\n : summary.pass_rate >= 0.5\n ? chalk.yellow\n : chalk.red;\n\n console.log(\n ` Pass Rate: ${color(chalk.bold(passStr))} (${summary.passed}/${summary.total} passed)`,\n );\n\n const failedResults = summary.results.filter((r) => !r.passed);\n if (failedResults.length) {\n console.log(chalk.dim(`\\nFailed eval details:`));\n for (const r of failedResults) {\n console.log(chalk.dim(` • \"${truncate(r.input, 50)}\":`));\n if (r.actual) {\n console.log(chalk.dim(` Response: ${truncate(r.actual, 80)}`));\n }\n for (const a of r.assertions.filter((a) => !a.passed)) {\n console.log(chalk.red(` ✗ ${a.assertion}: ${a.message}`));\n }\n }\n }\n}\n","import type {\n AssertionResult,\n LocalSpec,\n ValidationCheck,\n ValidationResult,\n} from \"./types.js\";\n\nexport function validateSpec(spec: LocalSpec): ValidationResult {\n const checks: ValidationCheck[] = [];\n\n checks.push({\n name: \"Has name\",\n passed: Boolean(spec.name?.trim()),\n message: spec.name?.trim() ? undefined : \"Spec is missing a name\",\n });\n\n checks.push({\n name: \"Has system prompt\",\n passed: Boolean(spec.system_prompt?.trim()),\n message: spec.system_prompt?.trim()\n ? undefined\n : \"Spec is missing a system_prompt\",\n });\n\n checks.push({\n name: \"Has base model\",\n passed: Boolean(spec.base_model?.trim()),\n message: spec.base_model?.trim()\n ? undefined\n : \"Spec is missing a base_model\",\n });\n\n const exCount = spec.examples?.length ?? 0;\n checks.push({\n name: \"Has examples\",\n passed: exCount > 0,\n message: exCount > 0 ? `${exCount} example(s)` : \"Add at least one example\",\n });\n\n checks.push({\n name: \"Has guidelines\",\n passed: (spec.guidelines?.length ?? 0) > 0,\n message:\n (spec.guidelines?.length ?? 0) > 0\n ? undefined\n : \"Consider adding guidelines for better eval coverage\",\n });\n\n if (spec.constraints?.length && spec.examples?.length) {\n const violations = checkExamplesAgainstConstraints(spec);\n checks.push({\n name: \"Examples satisfy constraints\",\n passed: violations.length === 0,\n message:\n violations.length === 0\n ? undefined\n : violations.join(\"; \"),\n });\n }\n\n return {\n valid: checks.every((c) => c.passed),\n checks,\n };\n}\n\nfunction checkExamplesAgainstConstraints(spec: LocalSpec): string[] {\n const violations: string[] = [];\n for (const [i, ex] of spec.examples.entries()) {\n for (const constraint of spec.constraints) {\n const result = evaluateConstraint(ex.output, constraint);\n if (!result.passed) {\n violations.push(`Example ${i + 1} violates \"${constraint}\": ${result.message}`);\n }\n }\n }\n return violations;\n}\n\nfunction evaluateConstraint(\n text: string,\n constraint: string,\n): { passed: boolean; message?: string } {\n const lower = constraint.toLowerCase();\n\n const neverMatch = lower.match(/^never (?:share|mention|include|reveal|use|say|output|return|give|provide|show|disclose|expose)\\s+(.+)/);\n if (neverMatch) {\n const forbidden = neverMatch[1].replace(/['\"]/g, \"\").trim();\n if (text.toLowerCase().includes(forbidden.toLowerCase())) {\n return { passed: false, message: `Output contains \"${forbidden}\"` };\n }\n return { passed: true };\n }\n\n const alwaysMatch = lower.match(/^always (?:include|use|start with|end with|contain|respond in|reply in)\\s+(.+)/);\n if (alwaysMatch) {\n const required = alwaysMatch[1].replace(/['\"]/g, \"\").trim();\n if (!text.toLowerCase().includes(required.toLowerCase())) {\n return { passed: false, message: `Output missing \"${required}\"` };\n }\n return { passed: true };\n }\n\n return {\n passed: true,\n message: `Constraint not enforceable by rules: \"${constraint}\" (will be checked by LLM judge if a provider is configured)`,\n };\n}\n\nexport function runAssertions(\n text: string,\n assertions: string[],\n): AssertionResult[] {\n return assertions.map((assertion) => runSingleAssertion(text, assertion));\n}\n\nfunction runSingleAssertion(text: string, assertion: string): AssertionResult {\n const [type, ...rest] = assertion.split(\":\");\n const value = rest.join(\":\");\n\n switch (type) {\n case \"contains\":\n return {\n assertion,\n passed: text.includes(value),\n message: text.includes(value)\n ? undefined\n : `Expected output to contain \"${value}\"`,\n };\n\n case \"not-contains\":\n return {\n assertion,\n passed: !text.includes(value),\n message: !text.includes(value)\n ? undefined\n : `Expected output to not contain \"${value}\"`,\n };\n\n case \"matches\": {\n const re = new RegExp(value);\n const match = re.test(text);\n return {\n assertion,\n passed: match,\n message: match ? undefined : `Output did not match pattern /${value}/`,\n };\n }\n\n case \"max-length\": {\n const max = Number(value);\n return {\n assertion,\n passed: text.length <= max,\n message:\n text.length <= max\n ? undefined\n : `Output length ${text.length} exceeds max ${max}`,\n };\n }\n\n case \"min-length\": {\n const min = Number(value);\n return {\n assertion,\n passed: text.length >= min,\n message:\n text.length >= min\n ? undefined\n : `Output length ${text.length} below min ${min}`,\n };\n }\n\n case \"is-json\": {\n let valid = false;\n try {\n JSON.parse(text);\n valid = true;\n } catch {}\n return {\n assertion,\n passed: valid,\n message: valid ? undefined : \"Output is not valid JSON\",\n };\n }\n\n default:\n return {\n assertion,\n passed: true,\n message: `Unknown assertion type: ${type} (skipped)`,\n };\n }\n}\n\nexport function checkConstraints(\n text: string,\n constraints: string[],\n): AssertionResult[] {\n return constraints.map((constraint) => {\n const result = evaluateConstraint(text, constraint);\n return {\n assertion: `constraint: ${constraint}`,\n passed: result.passed,\n message: result.message,\n };\n });\n}\n","import type {\n EvalCase,\n EvalResult,\n EvalSummary,\n LocalSpec,\n PlaygroundResponse,\n} from \"./types.js\";\nimport type { ClientOpts } from \"../client.js\";\nimport { post } from \"../client.js\";\nimport { validateSpec } from \"./rules.js\";\nimport { runAssertions, checkConstraints } from \"./rules.js\";\n\nfunction buildEvalCases(spec: LocalSpec): EvalCase[] {\n if (spec.eval_cases?.length) return spec.eval_cases;\n\n return spec.examples.map((ex) => ({\n input: ex.input,\n expected: ex.output,\n }));\n}\n\nexport async function runEvals(\n spec: LocalSpec,\n model: string,\n opts?: {\n clientOpts?: ClientOpts;\n onProgress?: (completed: number, total: number) => void;\n },\n): Promise<EvalSummary> {\n const specValidation = validateSpec(spec);\n const cases = buildEvalCases(spec);\n const results: EvalResult[] = [];\n\n for (const [i, evalCase] of cases.entries()) {\n const result = await runSingleEval(spec, evalCase, model, opts?.clientOpts);\n results.push(result);\n opts?.onProgress?.(i + 1, cases.length);\n }\n\n return {\n total: results.length,\n passed: results.filter((r) => r.passed).length,\n failed: results.filter((r) => !r.passed).length,\n pass_rate: results.length ? results.filter((r) => r.passed).length / results.length : 0,\n model,\n results,\n spec_validation: specValidation,\n };\n}\n\nasync function runSingleEval(\n spec: LocalSpec,\n evalCase: EvalCase,\n model: string,\n clientOpts?: ClientOpts,\n): Promise<EvalResult> {\n try {\n const { data } = await post<PlaygroundResponse>(\n \"/playground/completions\",\n {\n model,\n messages: [\n { role: \"system\", content: spec.system_prompt },\n { role: \"user\", content: evalCase.input },\n ],\n temperature: 0,\n max_tokens: 2048,\n },\n clientOpts,\n );\n\n const assertions = [\n ...runAssertions(data.content, evalCase.assert ?? []),\n ...checkConstraints(data.content, spec.constraints),\n ];\n\n return {\n input: evalCase.input,\n expected: evalCase.expected ?? null,\n actual: data.content,\n passed: assertions.every((a) => a.passed),\n latency_ms: data.latency_ms,\n assertions,\n };\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return {\n input: evalCase.input,\n expected: evalCase.expected ?? null,\n actual: null,\n passed: false,\n latency_ms: null,\n assertions: [{ assertion: \"model-call\", passed: false, message: msg }],\n };\n }\n}\n","import { Command } from \"commander\";\nimport { readFileSync, writeFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { post, put, type ClientOpts } from \"../client.js\";\nimport { printSuccess, printJson, isJsonMode, shortId } from \"../output.js\";\nimport { loadSpec, DEFAULT_SPEC_FILE } from \"./init.js\";\n\ninterface RemoteSpec {\n id: string;\n name: string;\n [key: string]: unknown;\n}\n\nexport function registerPushCommand(parent: Command) {\n parent\n .command(\"push\")\n .description(\"Push local spec to the Tuned Tensor API\")\n .option(\"-f, --file <path>\", \"Spec file path\", DEFAULT_SPEC_FILE)\n .action(async (cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n const filePath = resolve(cmdOpts.file);\n const spec = loadSpec(cmdOpts.file);\n\n const { id, eval_cases, ...body } = spec as unknown as Record<string, unknown>;\n\n let data: RemoteSpec;\n\n if (id) {\n const res = await put<RemoteSpec>(`/behavior-specs/${id}`, body, opts);\n data = res.data;\n } else {\n const res = await post<RemoteSpec>(\"/behavior-specs\", body, opts);\n data = res.data;\n\n const raw = JSON.parse(readFileSync(filePath, \"utf-8\"));\n raw.id = data.id;\n writeFileSync(filePath, JSON.stringify(raw, null, 2) + \"\\n\");\n }\n\n if (isJsonMode()) return printJson(data);\n printSuccess(\n `Spec ${id ? \"updated\" : \"created\"}: ${data.name} (${shortId(data.id)})`,\n );\n });\n}\n"],"mappings":"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","names":["chalk","readFileSync","readFileSync","readFileSync","readFileSync","existsSync","existsSync","chalk","chalk","chalk","chalk","existsSync","readFileSync","writeFileSync","existsSync","writeFileSync","readFileSync","ora","chalk","chalk","ora","a","readFileSync","writeFileSync","resolve","resolve","readFileSync","writeFileSync"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/output.ts","../src/client.ts","../src/config.ts","../src/commands/auth.ts","../src/commands/specs.ts","../src/commands/runs.ts","../src/commands/datasets.ts","../src/commands/models.ts","../src/commands/balance.ts","../src/commands/topup.ts","../src/commands/init.ts","../src/commands/eval.ts","../src/eval/rules.ts","../src/eval/runner.ts","../src/commands/push.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { setJsonMode, reportError } from \"./output.js\";\nimport { registerAuthCommands } from \"./commands/auth.js\";\nimport { registerSpecsCommands } from \"./commands/specs.js\";\nimport { registerRunsCommands } from \"./commands/runs.js\";\nimport { registerDatasetsCommands } from \"./commands/datasets.js\";\nimport { registerModelsCommands } from \"./commands/models.js\";\n\nimport { registerBalanceCommands } from \"./commands/balance.js\";\nimport { registerTopupCommands } from \"./commands/topup.js\";\nimport { registerInitCommand } from \"./commands/init.js\";\nimport { registerEvalCommand } from \"./commands/eval.js\";\nimport { registerPushCommand } from \"./commands/push.js\";\n\ndeclare const __TT_VERSION__: string;\n\nconst program = new Command();\n\nprogram\n .name(\"tt\")\n .description(\"Tuned Tensor CLI — fine-tune and evaluate LLMs\")\n .version(__TT_VERSION__)\n .option(\"-k, --api-key <key>\", \"API key (overrides stored key)\")\n .option(\n \"-u, --base-url <url>\",\n \"API base URL (default: https://tunedtensor.com)\",\n )\n .option(\"--json\", \"Output raw JSON\")\n .option(\"--no-color\", \"Disable colors\")\n .hook(\"preAction\", (_thisCommand, actionCommand) => {\n const rootOpts = program.opts();\n if (rootOpts.json) setJsonMode(true);\n if (rootOpts.color === false) {\n process.env.FORCE_COLOR = \"0\";\n }\n });\n\nregisterAuthCommands(program);\nregisterSpecsCommands(program);\nregisterRunsCommands(program);\nregisterDatasetsCommands(program);\nregisterModelsCommands(program);\n\nregisterBalanceCommands(program);\nregisterTopupCommands(program);\nregisterInitCommand(program);\nregisterEvalCommand(program);\nregisterPushCommand(program);\n\n// Honor --json even when parsing fails before the preAction hook runs\n// (e.g. on unknown commands). Cheap argv sniff is fine here.\nif (process.argv.includes(\"--json\")) setJsonMode(true);\n\nprogram.parseAsync().catch((err) => {\n reportError(err);\n process.exit(1);\n});\n","import chalk from \"chalk\";\nimport Table from \"cli-table3\";\nimport { ApiError } from \"./client.js\";\n\nlet jsonMode = false;\n\nexport function setJsonMode(enabled: boolean) {\n jsonMode = enabled;\n}\n\nexport function isJsonMode(): boolean {\n return jsonMode;\n}\n\nexport function printJson(data: unknown) {\n console.log(JSON.stringify(data, null, 2));\n}\n\nexport function printTable(\n headers: string[],\n rows: string[][],\n meta?: { page: number; per_page: number; total: number },\n) {\n const table = new Table({\n head: headers.map((h) => chalk.bold.cyan(h)),\n style: { head: [], border: [] },\n });\n for (const row of rows) {\n table.push(row);\n }\n console.log(table.toString());\n\n if (meta) {\n const totalPages = Math.ceil(meta.total / meta.per_page);\n console.log(\n chalk.dim(\n `\\nPage ${meta.page}/${totalPages} (${meta.total} total)`,\n ),\n );\n }\n}\n\nexport function printDetail(fields: [string, string | undefined][]) {\n const maxLabel = Math.max(...fields.map(([l]) => l.length));\n for (const [label, value] of fields) {\n const paddedLabel = label.padEnd(maxLabel);\n console.log(`${chalk.bold.cyan(paddedLabel)} ${value ?? chalk.dim(\"—\")}`);\n }\n}\n\nexport function printSuccess(message: string) {\n console.log(chalk.green(\"✓\") + \" \" + message);\n}\n\nexport function printWarning(message: string) {\n console.log(chalk.yellow(\"!\") + \" \" + message);\n}\n\nexport function printError(message: string) {\n console.error(chalk.red(\"✗\") + \" \" + message);\n}\n\nexport function reportError(err: unknown): void {\n const isApi = err instanceof ApiError;\n const message = (err as Error)?.message || String(err);\n\n if (jsonMode) {\n printJson({\n error: {\n status: isApi ? err.status : null,\n code: isApi ? err.code : \"CLI_ERROR\",\n message,\n },\n });\n } else if (isApi) {\n printError(`[${err.status}] ${message}`);\n } else {\n printError(message);\n }\n}\n\nexport function formatDate(iso?: string | null): string {\n if (!iso) return \"—\";\n return new Date(iso).toLocaleString();\n}\n\nexport function formatStatus(status: string): string {\n const map: Record<string, (s: string) => string> = {\n completed: chalk.green,\n running: chalk.blue,\n training: chalk.blue,\n evaluating: chalk.blue,\n preparing: chalk.yellow,\n pending: chalk.yellow,\n uploading: chalk.yellow,\n failed: chalk.red,\n cancelled: chalk.dim,\n validated: chalk.green,\n invalid: chalk.red,\n };\n const colorFn = map[status] || chalk.white;\n return colorFn(status);\n}\n\nexport function truncate(str: string, max: number): string {\n if (str.length <= max) return str;\n return str.slice(0, max - 1) + \"…\";\n}\n\nexport function shortId(id: string): string {\n return id.slice(0, 8);\n}\n","import { readFileSync, statSync } from \"node:fs\";\nimport { basename } from \"node:path\";\nimport { getApiKey, getBaseUrl } from \"./config.js\";\n\nexport interface ApiResponse<T> {\n data: T;\n meta?: { page: number; per_page: number; total: number };\n}\n\nexport interface ApiErrorBody {\n error: { code: string; message: string };\n}\n\nexport class ApiError extends Error {\n constructor(\n public status: number,\n public code: string,\n message: string,\n ) {\n super(message);\n this.name = \"ApiError\";\n }\n}\n\nexport interface ClientOpts {\n apiKey?: string;\n baseUrl?: string;\n}\n\nfunction resolveKey(opts?: ClientOpts): string {\n const key = getApiKey(opts);\n if (!key) {\n throw new ApiError(\n 401,\n \"NO_API_KEY\",\n \"No API key found. Run `tt auth login` or set TUNED_TENSOR_API_KEY.\",\n );\n }\n return key;\n}\n\nfunction buildUrl(\n path: string,\n query?: Record<string, string | number | undefined>,\n opts?: ClientOpts,\n): string {\n const base = getBaseUrl(opts);\n const url = new URL(`/api/v1${path}`, base);\n if (query) {\n for (const [k, v] of Object.entries(query)) {\n if (v !== undefined) url.searchParams.set(k, String(v));\n }\n }\n return url.toString();\n}\n\nasync function request<T>(\n method: string,\n path: string,\n options: {\n query?: Record<string, string | number | undefined>;\n body?: unknown;\n opts?: ClientOpts;\n } = {},\n): Promise<ApiResponse<T>> {\n const key = resolveKey(options.opts);\n const url = buildUrl(path, options.query, options.opts);\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${key}`,\n };\n\n let bodyPayload: string | undefined;\n if (options.body) {\n headers[\"Content-Type\"] = \"application/json\";\n bodyPayload = JSON.stringify(options.body);\n }\n\n const res = await fetch(url, { method, headers, body: bodyPayload });\n\n if (!res.ok) {\n let errBody: ApiErrorBody;\n try {\n errBody = (await res.json()) as ApiErrorBody;\n } catch {\n throw new ApiError(res.status, \"UNKNOWN\", res.statusText);\n }\n throw new ApiError(\n res.status,\n errBody.error?.code || \"UNKNOWN\",\n errBody.error?.message || res.statusText,\n );\n }\n\n if (res.status === 204) return { data: null as T };\n return (await res.json()) as ApiResponse<T>;\n}\n\nexport function get<T>(\n path: string,\n query?: Record<string, string | number | undefined>,\n opts?: ClientOpts,\n) {\n return request<T>(\"GET\", path, { query, opts });\n}\n\nexport function post<T>(\n path: string,\n body?: unknown,\n opts?: ClientOpts,\n) {\n return request<T>(\"POST\", path, { body, opts });\n}\n\nexport function put<T>(\n path: string,\n body?: unknown,\n opts?: ClientOpts,\n) {\n return request<T>(\"PUT\", path, { body, opts });\n}\n\nexport function patch<T>(\n path: string,\n body?: unknown,\n opts?: ClientOpts,\n) {\n return request<T>(\"PATCH\", path, { body, opts });\n}\n\nexport function del<T>(path: string, opts?: ClientOpts) {\n return request<T>(\"DELETE\", path, { opts });\n}\n\nexport async function upload<T>(\n path: string,\n filePath: string,\n fields: Record<string, string>,\n opts?: ClientOpts,\n): Promise<ApiResponse<T>> {\n const key = resolveKey(opts);\n const url = buildUrl(path, undefined, opts);\n\n const form = new FormData();\n for (const [k, v] of Object.entries(fields)) {\n form.append(k, v);\n }\n\n const fileBytes = readFileSync(filePath);\n const fileSize = statSync(filePath).size;\n const blob = new Blob([fileBytes], { type: \"application/jsonl\" });\n form.append(\"file\", blob, basename(filePath));\n\n const res = await fetch(url, {\n method: \"POST\",\n headers: { Authorization: `Bearer ${key}` },\n body: form,\n });\n\n if (!res.ok) {\n let errBody: ApiErrorBody;\n try {\n errBody = (await res.json()) as ApiErrorBody;\n } catch {\n throw new ApiError(res.status, \"UNKNOWN\", res.statusText);\n }\n throw new ApiError(\n res.status,\n errBody.error?.code || \"UNKNOWN\",\n errBody.error?.message || res.statusText,\n );\n }\n\n return (await res.json()) as ApiResponse<T>;\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nexport interface Config {\n api_key?: string;\n base_url?: string;\n}\n\nconst CONFIG_DIR_NAME = \"tuned-tensor\";\nconst CONFIG_FILE_NAME = \"config.json\";\n\nfunction getConfigDir(): string {\n const xdg = process.env.XDG_CONFIG_HOME;\n const base = xdg || join(homedir(), \".config\");\n return join(base, CONFIG_DIR_NAME);\n}\n\nfunction getConfigPath(): string {\n return join(getConfigDir(), CONFIG_FILE_NAME);\n}\n\nexport function readConfig(): Config {\n const path = getConfigPath();\n if (!existsSync(path)) return {};\n try {\n return JSON.parse(readFileSync(path, \"utf-8\"));\n } catch {\n return {};\n }\n}\n\nexport function writeConfig(config: Config): void {\n const dir = getConfigDir();\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n writeFileSync(getConfigPath(), JSON.stringify(config, null, 2) + \"\\n\");\n}\n\nexport function updateConfig(partial: Partial<Config>): void {\n const current = readConfig();\n writeConfig({ ...current, ...partial });\n}\n\nexport function clearConfig(): void {\n const path = getConfigPath();\n if (existsSync(path)) writeFileSync(path, \"{}\\n\");\n}\n\nexport const DEFAULT_BASE_URL = \"https://tunedtensor.com\";\n\nexport function getBaseUrl(opts?: { baseUrl?: string }): string {\n return opts?.baseUrl || process.env.TUNED_TENSOR_URL || readConfig().base_url || DEFAULT_BASE_URL;\n}\n\nexport function getApiKey(opts?: { apiKey?: string }): string | undefined {\n return opts?.apiKey || process.env.TUNED_TENSOR_API_KEY || readConfig().api_key;\n}\n","import { Command } from \"commander\";\nimport { createInterface } from \"node:readline/promises\";\nimport { stdin, stdout } from \"node:process\";\nimport {\n readConfig,\n updateConfig,\n clearConfig,\n getApiKey,\n getBaseUrl,\n DEFAULT_BASE_URL,\n} from \"../config.js\";\nimport {\n printSuccess,\n printDetail,\n printError,\n printWarning,\n isJsonMode,\n printJson,\n} from \"../output.js\";\nimport chalk from \"chalk\";\n\nexport function registerAuthCommands(parent: Command) {\n const auth = parent.command(\"auth\").description(\"Manage authentication\");\n\n auth\n .command(\"login\")\n .description(\"Store an API key for authentication\")\n .argument(\"[key]\", \"API key (tt_...). If omitted, you will be prompted.\")\n .action(async (key?: string) => {\n let apiKey = key;\n\n if (!apiKey) {\n const settingsUrl = `${DEFAULT_BASE_URL}/dashboard/settings`;\n console.log();\n console.log(\n ` To get your API key, go to ${chalk.bold(\"Settings → API Keys\")} in the Tuned Tensor dashboard:`,\n );\n console.log(` ${chalk.cyan.underline(settingsUrl)}`);\n console.log();\n\n const rl = createInterface({ input: stdin, output: stdout });\n apiKey = await rl.question(\"Enter your API key (tt_...): \");\n rl.close();\n }\n\n apiKey = apiKey.trim();\n\n if (!apiKey.startsWith(\"tt_\") || apiKey.length !== 51) {\n printError(\n \"Invalid API key format. Keys start with tt_ and are 51 characters long.\",\n );\n process.exit(1);\n }\n\n updateConfig({ api_key: apiKey });\n printSuccess(\n `API key stored (${apiKey.slice(0, 8)}...). You're ready to go.`,\n );\n });\n\n auth\n .command(\"logout\")\n .description(\"Remove stored credentials\")\n .action(() => {\n clearConfig();\n printSuccess(\"Credentials removed.\");\n });\n\n auth\n .command(\"status\")\n .description(\"Show current authentication status\")\n .action(() => {\n const opts = parent.opts();\n const apiKey = getApiKey(opts);\n const baseUrl = getBaseUrl(opts);\n\n if (isJsonMode()) {\n printJson({\n authenticated: !!apiKey,\n key_prefix: apiKey ? apiKey.slice(0, 8) + \"...\" : null,\n base_url: baseUrl,\n });\n return;\n }\n\n if (apiKey) {\n printDetail([\n [\"Authenticated\", \"Yes\"],\n [\"API Key\", apiKey.slice(0, 8) + \"...\"],\n [\"Base URL\", baseUrl],\n ]);\n } else {\n printWarning(\n \"Not authenticated. Run `tt auth login` to store an API key.\",\n );\n printDetail([[\"Base URL\", baseUrl]]);\n }\n });\n}\n","import { Command } from \"commander\";\nimport { readFileSync } from \"node:fs\";\nimport { get, post, put, del, type ClientOpts } from \"../client.js\";\nimport {\n printTable,\n printDetail,\n printSuccess,\n printWarning,\n printJson,\n isJsonMode,\n formatDate,\n formatStatus,\n truncate,\n shortId,\n} from \"../output.js\";\n\nconst SPEC_BODY_KEYS = new Set([\n \"name\",\n \"description\",\n \"base_model\",\n \"system_prompt\",\n \"guidelines\",\n \"constraints\",\n \"examples\",\n]);\n\nconst RUN_INPUT_KEYS = [\"run_id\", \"behavior_spec_id\", \"spec_snapshot\", \"run_number\"];\n\nclass SpecBodyError extends Error {}\n\nfunction loadSpecBody(filePath: string, mode: \"create\" | \"update\"): Record<string, unknown> {\n let parsed: unknown;\n try {\n parsed = JSON.parse(readFileSync(filePath, \"utf-8\"));\n } catch (e) {\n throw new SpecBodyError(\n `Could not parse ${filePath}: ${(e as Error).message}`,\n );\n }\n\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new SpecBodyError(\n `${filePath} must contain a JSON object at the top level.`,\n );\n }\n\n const body = parsed as Record<string, unknown>;\n\n const runInputHits = RUN_INPUT_KEYS.filter((k) => k in body);\n if (runInputHits.length >= 2 || \"spec_snapshot\" in body) {\n const hint = \"spec_snapshot\" in body\n ? `This file looks like a run-input payload (top-level keys: ${runInputHits.join(\", \")}). The actual spec is nested under \"spec_snapshot\". Try:\\n jq '.spec_snapshot' ${filePath} > spec.json\\n tt specs ${mode === \"create\" ? \"create\" : \"update <id>\"} --file spec.json`\n : `This file looks like a run-input payload (top-level keys: ${runInputHits.join(\", \")}), not a behaviour spec. To start a run on an existing spec, use: tt runs start <spec-id>`;\n throw new SpecBodyError(hint);\n }\n\n if (mode === \"create\" && typeof body.name !== \"string\") {\n throw new SpecBodyError(\n `${filePath} is missing required field \"name\" (string).`,\n );\n }\n\n const unknown = Object.keys(body).filter(\n (k) => !SPEC_BODY_KEYS.has(k) && k !== \"id\" && k !== \"eval_cases\",\n );\n if (unknown.length && !isJsonMode()) {\n printWarning(\n `Unknown spec field(s) in ${filePath}: ${unknown.join(\", \")}. They will be sent but may be rejected by the API.`,\n );\n }\n\n return body;\n}\n\ninterface BehaviorSpec {\n id: string;\n name: string;\n description: string;\n system_prompt: string;\n guidelines: string[];\n examples: { input: string; output: string }[];\n constraints: string[];\n base_model: string;\n created_at: string;\n updated_at: string;\n _run_count?: number;\n _latest_run_status?: string;\n _latest_run_score?: number;\n _runs?: unknown[];\n}\n\nexport function registerSpecsCommands(parent: Command) {\n const specs = parent\n .command(\"specs\")\n .description(\"Manage behaviour specs\");\n\n specs\n .command(\"list\")\n .description(\"List behaviour specs\")\n .option(\"-p, --page <n>\", \"Page number\", \"1\")\n .option(\"--per-page <n>\", \"Results per page\", \"20\")\n .action(async (cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n const { data, meta } = await get<BehaviorSpec[]>(\n \"/behavior-specs\",\n { page: cmdOpts.page, per_page: cmdOpts.perPage },\n opts,\n );\n\n if (isJsonMode()) return printJson({ data, meta });\n\n printTable(\n [\"ID\", \"Name\", \"Model\", \"Examples\", \"Runs\", \"Status\", \"Updated\"],\n data.map((s) => [\n shortId(s.id),\n truncate(s.name, 30),\n s.base_model.split(\"/\").pop() || s.base_model,\n String(s.examples?.length ?? 0),\n String(s._run_count ?? 0),\n s._latest_run_status ? formatStatus(s._latest_run_status) : \"—\",\n formatDate(s.updated_at),\n ]),\n meta,\n );\n });\n\n specs\n .command(\"get\")\n .description(\"Show spec details\")\n .argument(\"<id>\", \"Spec ID (full or prefix)\")\n .action(async (id: string) => {\n const opts = parent.opts() as ClientOpts;\n const { data } = await get<BehaviorSpec>(`/behavior-specs/${id}`, undefined, opts);\n\n if (isJsonMode()) return printJson(data);\n\n printDetail([\n [\"ID\", data.id],\n [\"Name\", data.name],\n [\"Description\", data.description || undefined],\n [\"Base Model\", data.base_model],\n [\"System Prompt\", data.system_prompt ? truncate(data.system_prompt, 80) : undefined],\n [\"Guidelines\", data.guidelines?.length ? data.guidelines.join(\", \") : undefined],\n [\"Constraints\", data.constraints?.length ? data.constraints.join(\", \") : undefined],\n [\"Examples\", String(data.examples?.length ?? 0)],\n [\"Runs\", String(data._run_count ?? data._runs?.length ?? 0)],\n [\"Created\", formatDate(data.created_at)],\n [\"Updated\", formatDate(data.updated_at)],\n ]);\n\n if (data.examples?.length) {\n console.log(\"\\nExamples:\");\n for (const [i, ex] of data.examples.slice(0, 5).entries()) {\n console.log(` ${i + 1}. Input: ${truncate(ex.input, 60)}`);\n console.log(` Output: ${truncate(ex.output, 60)}`);\n }\n if (data.examples.length > 5) {\n console.log(` ... and ${data.examples.length - 5} more`);\n }\n }\n });\n\n specs\n .command(\"create\")\n .description(\"Create a behaviour spec\")\n .option(\"-f, --file <path>\", \"JSON file with spec definition\")\n .option(\"-n, --name <name>\", \"Spec name\")\n .option(\"--model <model>\", \"Base model ID\")\n .action(async (cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n let body: Record<string, unknown>;\n\n if (cmdOpts.file) {\n body = loadSpecBody(cmdOpts.file, \"create\");\n } else if (cmdOpts.name) {\n body = { name: cmdOpts.name };\n if (cmdOpts.model) body.base_model = cmdOpts.model;\n } else {\n throw new SpecBodyError(\"Provide --file or --name\");\n }\n\n const { data } = await post<BehaviorSpec>(\"/behavior-specs\", body, opts);\n\n if (isJsonMode()) return printJson(data);\n printSuccess(`Spec created: ${data.name} (${shortId(data.id)})`);\n });\n\n specs\n .command(\"update\")\n .description(\"Update a behaviour spec\")\n .argument(\"<id>\", \"Spec ID\")\n .option(\"-f, --file <path>\", \"JSON file with fields to update\")\n .option(\"-n, --name <name>\", \"New name\")\n .option(\"--model <model>\", \"New base model ID\")\n .action(async (id: string, cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n let body: Record<string, unknown>;\n\n if (cmdOpts.file) {\n body = loadSpecBody(cmdOpts.file, \"update\");\n } else {\n body = {};\n if (cmdOpts.name) body.name = cmdOpts.name;\n if (cmdOpts.model) body.base_model = cmdOpts.model;\n }\n\n const { data } = await put<BehaviorSpec>(\n `/behavior-specs/${id}`,\n body,\n opts,\n );\n\n if (isJsonMode()) return printJson(data);\n printSuccess(`Spec updated: ${data.name} (${shortId(data.id)})`);\n });\n\n specs\n .command(\"delete\")\n .description(\"Delete a behaviour spec\")\n .argument(\"<id>\", \"Spec ID\")\n .action(async (id: string) => {\n const opts = parent.opts() as ClientOpts;\n await del(`/behavior-specs/${id}`, opts);\n\n if (isJsonMode()) return printJson({ id, deleted: true });\n printSuccess(`Spec deleted: ${shortId(id)}`);\n });\n}\n","import { Command } from \"commander\";\nimport ora from \"ora\";\nimport { get, post, type ClientOpts } from \"../client.js\";\nimport {\n printTable,\n printDetail,\n printSuccess,\n printJson,\n isJsonMode,\n formatDate,\n formatStatus,\n shortId,\n truncate,\n} from \"../output.js\";\n\ninterface Run {\n id: string;\n behavior_spec_id: string;\n run_number: number;\n status: string;\n current_stage?: string | null;\n stage_label?: string | null;\n progress_pct?: number | null;\n status_message?: string | null;\n hyperparameters: Record<string, unknown> | null;\n eval_summary: { mean_score?: number; pass_rate?: number } | null;\n error: string | null;\n started_at: string | null;\n completed_at: string | null;\n created_at: string;\n updated_at: string;\n _spec_name?: string;\n _evals?: RunEval[];\n _events?: RunEvent[];\n}\n\ninterface RunEval {\n id: string;\n prompt: string;\n expected: string;\n actual: string;\n passed: boolean;\n score: number | null;\n reasoning: string | null;\n latency_ms: number | null;\n}\n\ninterface RunEvent {\n id: string;\n stage: string;\n label: string;\n status: string;\n message: string | null;\n occurred_at: string;\n}\n\nfunction formatProgress(run: Run): string | undefined {\n if (run.progress_pct == null && !run.stage_label) return undefined;\n const label = run.stage_label ?? run.current_stage ?? \"Progress\";\n return run.progress_pct == null ? label : `${label} (${run.progress_pct}%)`;\n}\n\nexport function registerRunsCommands(parent: Command) {\n const runs = parent.command(\"runs\").description(\"Manage runs\");\n\n runs\n .command(\"list\")\n .description(\"List runs\")\n .option(\"-s, --spec <id>\", \"Filter by spec ID\")\n .option(\"-p, --page <n>\", \"Page number\", \"1\")\n .option(\"--per-page <n>\", \"Results per page\", \"20\")\n .action(async (cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n\n let path = \"/runs\";\n const query: Record<string, string | number> = {\n page: cmdOpts.page,\n per_page: cmdOpts.perPage,\n };\n\n if (cmdOpts.spec) {\n path = `/behavior-specs/${cmdOpts.spec}/runs`;\n }\n\n const { data, meta } = await get<Run[]>(path, query, opts);\n\n if (isJsonMode()) return printJson({ data, meta });\n\n printTable(\n [\"ID\", \"Spec\", \"#\", \"Status\", \"Score\", \"Started\", \"Completed\"],\n data.map((r) => [\n shortId(r.id),\n r._spec_name ? truncate(r._spec_name, 20) : shortId(r.behavior_spec_id),\n String(r.run_number),\n formatStatus(r.status),\n r.eval_summary?.mean_score != null\n ? (r.eval_summary.mean_score * 100).toFixed(1) + \"%\"\n : \"—\",\n formatDate(r.started_at),\n formatDate(r.completed_at),\n ]),\n meta,\n );\n });\n\n runs\n .command(\"get\")\n .description(\"Show run details and eval results\")\n .argument(\"<id>\", \"Run ID\")\n .action(async (id: string) => {\n const opts = parent.opts() as ClientOpts;\n const { data } = await get<Run>(`/runs/${id}`, undefined, opts);\n\n if (isJsonMode()) return printJson(data);\n\n printDetail([\n [\"ID\", data.id],\n [\"Spec\", data._spec_name ?? shortId(data.behavior_spec_id)],\n [\"Run #\", String(data.run_number)],\n [\"Status\", formatStatus(data.status)],\n [\"Stage\", formatProgress(data)],\n [\"Message\", data.status_message ?? undefined],\n [\"Score\", data.eval_summary?.mean_score != null\n ? (data.eval_summary.mean_score * 100).toFixed(1) + \"%\"\n : undefined],\n [\"Pass Rate\", data.eval_summary?.pass_rate != null\n ? (data.eval_summary.pass_rate * 100).toFixed(1) + \"%\"\n : undefined],\n [\"Error\", data.error ?? undefined],\n [\"Started\", formatDate(data.started_at)],\n [\"Completed\", formatDate(data.completed_at)],\n [\"Created\", formatDate(data.created_at)],\n ]);\n\n if (data.hyperparameters && Object.keys(data.hyperparameters).length) {\n console.log(\"\\nHyperparameters:\");\n for (const [k, v] of Object.entries(data.hyperparameters)) {\n console.log(` ${k}: ${v}`);\n }\n }\n\n if (data._events?.length) {\n console.log(\"\\nLatest Updates:\");\n for (const event of data._events.slice(-5)) {\n const time = formatDate(event.occurred_at);\n console.log(\n ` ${time} ${formatStatus(event.status)} ${event.label}${event.message ? ` — ${event.message}` : \"\"}`,\n );\n }\n }\n\n if (data._evals?.length) {\n console.log(`\\nEval Results (${data._evals.length}):`);\n printTable(\n [\"#\", \"Passed\", \"Score\", \"Prompt\", \"Latency\"],\n data._evals.map((e, i) => [\n String(i + 1),\n e.passed ? \"✓\" : \"✗\",\n e.score != null ? e.score.toFixed(2) : \"—\",\n truncate(e.prompt, 40),\n e.latency_ms != null ? `${e.latency_ms}ms` : \"—\",\n ]),\n );\n }\n });\n\n runs\n .command(\"start\")\n .description(\"Start a new run for a behaviour spec\")\n .argument(\"<spec-id>\", \"Behaviour spec ID\")\n .option(\"--no-augment\", \"Disable data augmentation\")\n .option(\"--epochs <n>\", \"Number of training epochs\")\n .option(\"--lr <rate>\", \"Learning rate\")\n .option(\"--batch-size <n>\", \"Batch size\")\n .option(\"--lora-rank <n>\", \"LoRA rank\")\n .option(\"--lora-alpha <n>\", \"LoRA alpha\")\n .action(async (specId: string, cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n const body: Record<string, unknown> = {};\n\n if (cmdOpts.augment === false) body.augment = false;\n\n const hp: Record<string, unknown> = {};\n if (cmdOpts.epochs) hp.n_epochs = Number(cmdOpts.epochs);\n if (cmdOpts.lr) hp.learning_rate = Number(cmdOpts.lr);\n if (cmdOpts.batchSize) hp.batch_size = Number(cmdOpts.batchSize);\n if (cmdOpts.loraRank) hp.lora_rank = Number(cmdOpts.loraRank);\n if (cmdOpts.loraAlpha) hp.lora_alpha = Number(cmdOpts.loraAlpha);\n if (Object.keys(hp).length) body.hyperparameters = hp;\n\n const { data } = await post<Run>(\n `/behavior-specs/${specId}/runs`,\n body,\n opts,\n );\n\n if (isJsonMode()) return printJson(data);\n printSuccess(\n `Run #${data.run_number} started (${shortId(data.id)}). ${formatProgress(data) ?? `Status: ${formatStatus(data.status)}`}`,\n );\n });\n\n runs\n .command(\"cancel\")\n .description(\"Cancel a running run\")\n .argument(\"<id>\", \"Run ID\")\n .action(async (id: string) => {\n const opts = parent.opts() as ClientOpts;\n const { data } = await post<Run>(`/runs/${id}/cancel`, undefined, opts);\n\n if (isJsonMode()) return printJson(data);\n printSuccess(`Run ${shortId(id)} cancelled.`);\n });\n\n runs\n .command(\"watch\")\n .description(\"Watch a run until it completes\")\n .argument(\"<id>\", \"Run ID\")\n .option(\"--interval <ms>\", \"Poll interval in milliseconds\", \"5000\")\n .action(async (id: string, cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n const interval = Number(cmdOpts.interval);\n const spinner = ora(`Watching run ${shortId(id)}...`).start();\n\n const terminalStates = new Set([\n \"completed\",\n \"failed\",\n \"cancelled\",\n ]);\n\n let run: Run;\n while (true) {\n const { data } = await get<Run>(`/runs/${id}`, undefined, opts);\n run = data;\n spinner.text = `Run ${shortId(id)} — ${formatProgress(run) ?? formatStatus(run.status)}`;\n\n if (terminalStates.has(run.status)) break;\n await new Promise((r) => setTimeout(r, interval));\n }\n\n spinner.stop();\n\n if (isJsonMode()) return printJson(run);\n\n printDetail([\n [\"Run\", shortId(run.id)],\n [\"Status\", formatStatus(run.status)],\n [\"Stage\", formatProgress(run)],\n [\"Message\", run.status_message ?? undefined],\n [\"Score\", run.eval_summary?.mean_score != null\n ? (run.eval_summary.mean_score * 100).toFixed(1) + \"%\"\n : undefined],\n [\"Error\", run.error ?? undefined],\n [\"Completed\", formatDate(run.completed_at)],\n ]);\n });\n}\n","import { Command } from \"commander\";\nimport { existsSync } from \"node:fs\";\nimport { get, del, upload, type ClientOpts } from \"../client.js\";\nimport {\n printTable,\n printDetail,\n printSuccess,\n printJson,\n printError,\n isJsonMode,\n formatDate,\n formatStatus,\n shortId,\n truncate,\n} from \"../output.js\";\n\ninterface Dataset {\n id: string;\n name: string;\n description: string | null;\n storage_path: string;\n file_size_bytes: number;\n row_count: number;\n format: string;\n status: string;\n validation_errors: string[] | null;\n created_at: string;\n updated_at: string;\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nexport function registerDatasetsCommands(parent: Command) {\n const datasets = parent\n .command(\"datasets\")\n .description(\"Manage datasets\");\n\n datasets\n .command(\"list\")\n .description(\"List datasets\")\n .option(\"-p, --page <n>\", \"Page number\", \"1\")\n .option(\"--per-page <n>\", \"Results per page\", \"20\")\n .action(async (cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n const { data, meta } = await get<Dataset[]>(\n \"/datasets\",\n { page: cmdOpts.page, per_page: cmdOpts.perPage },\n opts,\n );\n\n if (isJsonMode()) return printJson({ data, meta });\n\n printTable(\n [\"ID\", \"Name\", \"Rows\", \"Size\", \"Status\", \"Created\"],\n data.map((d) => [\n shortId(d.id),\n truncate(d.name, 30),\n String(d.row_count),\n formatBytes(d.file_size_bytes),\n formatStatus(d.status),\n formatDate(d.created_at),\n ]),\n meta,\n );\n });\n\n datasets\n .command(\"get\")\n .description(\"Show dataset details\")\n .argument(\"<id>\", \"Dataset ID\")\n .action(async (id: string) => {\n const opts = parent.opts() as ClientOpts;\n const { data } = await get<Dataset>(`/datasets/${id}`, undefined, opts);\n\n if (isJsonMode()) return printJson(data);\n\n printDetail([\n [\"ID\", data.id],\n [\"Name\", data.name],\n [\"Description\", data.description ?? undefined],\n [\"Format\", data.format],\n [\"Rows\", String(data.row_count)],\n [\"Size\", formatBytes(data.file_size_bytes)],\n [\"Status\", formatStatus(data.status)],\n [\"Created\", formatDate(data.created_at)],\n [\"Updated\", formatDate(data.updated_at)],\n ]);\n\n if (data.validation_errors?.length) {\n console.log(\"\\nValidation Errors:\");\n for (const err of data.validation_errors) {\n console.log(` - ${err}`);\n }\n }\n });\n\n datasets\n .command(\"upload\")\n .description(\"Upload a JSONL dataset file\")\n .argument(\"<file>\", \"Path to JSONL file\")\n .option(\"-n, --name <name>\", \"Dataset name (defaults to filename)\")\n .option(\"-d, --description <desc>\", \"Dataset description\")\n .action(async (file: string, cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n\n if (!existsSync(file)) {\n printError(`File not found: ${file}`);\n process.exit(1);\n }\n\n const fields: Record<string, string> = {\n name: cmdOpts.name || file.split(\"/\").pop()!.replace(/\\.jsonl?$/, \"\"),\n };\n if (cmdOpts.description) fields.description = cmdOpts.description;\n\n const { data } = await upload<Dataset>(\n \"/datasets\",\n file,\n fields,\n opts,\n );\n\n if (isJsonMode()) return printJson(data);\n printSuccess(\n `Dataset uploaded: ${data.name} (${shortId(data.id)}) — ${data.row_count} rows`,\n );\n });\n\n datasets\n .command(\"delete\")\n .description(\"Delete a dataset\")\n .argument(\"<id>\", \"Dataset ID\")\n .action(async (id: string) => {\n const opts = parent.opts() as ClientOpts;\n await del(`/datasets/${id}`, opts);\n\n if (isJsonMode()) return printJson({ id, deleted: true });\n printSuccess(`Dataset deleted: ${shortId(id)}`);\n });\n}\n","import { Command } from \"commander\";\nimport { get, del, type ClientOpts } from \"../client.js\";\nimport {\n printTable,\n printDetail,\n printSuccess,\n printJson,\n isJsonMode,\n formatDate,\n shortId,\n truncate,\n} from \"../output.js\";\n\ninterface Model {\n id: string;\n name: string;\n provider: string;\n provider_model_id: string;\n base_model: string;\n description: string | null;\n created_at: string;\n}\n\nexport function registerModelsCommands(parent: Command) {\n const models = parent.command(\"models\").description(\"Manage fine-tuned models\");\n\n models\n .command(\"list\")\n .description(\"List fine-tuned models\")\n .option(\"-p, --page <n>\", \"Page number\", \"1\")\n .option(\"--per-page <n>\", \"Results per page\", \"20\")\n .action(async (cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n const { data, meta } = await get<Model[]>(\n \"/models\",\n { page: cmdOpts.page, per_page: cmdOpts.perPage },\n opts,\n );\n\n if (isJsonMode()) return printJson({ data, meta });\n\n printTable(\n [\"ID\", \"Name\", \"Base Model\", \"Provider\", \"Created\"],\n data.map((m) => [\n shortId(m.id),\n truncate(m.name, 30),\n m.base_model.split(\"/\").pop() || m.base_model,\n m.provider,\n formatDate(m.created_at),\n ]),\n meta,\n );\n });\n\n models\n .command(\"get\")\n .description(\"Show model details\")\n .argument(\"<id>\", \"Model ID\")\n .action(async (id: string) => {\n const opts = parent.opts() as ClientOpts;\n const { data } = await get<Model>(`/models/${id}`, undefined, opts);\n\n if (isJsonMode()) return printJson(data);\n\n printDetail([\n [\"ID\", data.id],\n [\"Name\", data.name],\n [\"Base Model\", data.base_model],\n [\"Provider\", data.provider],\n [\"Provider Model\", data.provider_model_id],\n [\"Description\", data.description ?? undefined],\n [\"Created\", formatDate(data.created_at)],\n ]);\n });\n\n models\n .command(\"delete\")\n .description(\"Delete a model\")\n .argument(\"<id>\", \"Model ID\")\n .action(async (id: string) => {\n const opts = parent.opts() as ClientOpts;\n await del(`/models/${id}`, opts);\n\n if (isJsonMode()) return printJson({ id, deleted: true });\n printSuccess(`Model deleted: ${shortId(id)}`);\n });\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { get, type ClientOpts } from \"../client.js\";\nimport {\n printDetail,\n printJson,\n printTable,\n isJsonMode,\n formatDate,\n formatStatus,\n shortId,\n} from \"../output.js\";\n\ninterface BalanceResponse {\n balance_cents: number;\n reserved_cents: number;\n available_cents: number;\n lifetime_topup_cents: number;\n signup_bonus_cents: number;\n signup_bonus_granted: boolean;\n}\n\ntype CreditKind =\n | \"signup_bonus\"\n | \"topup\"\n | \"debit_run\"\n | \"debit_autotune\"\n | \"refund\"\n | \"adjustment\";\n\ninterface LedgerRow {\n id: string;\n kind: CreditKind;\n amount_cents: number;\n balance_after_cents: number;\n reference_id: string | null;\n created_at: string;\n}\n\nconst KIND_LABELS: Record<CreditKind, string> = {\n signup_bonus: \"Signup bonus\",\n topup: \"Top-up\",\n debit_run: \"Run\",\n debit_autotune: \"Auto-tune\",\n refund: \"Refund\",\n adjustment: \"Adjustment\",\n};\n\nfunction formatCents(cents: number): string {\n const sign = cents < 0 ? \"-\" : \"\";\n const abs = Math.abs(cents);\n return `${sign}$${(abs / 100).toFixed(2)}`;\n}\n\nfunction formatSigned(cents: number): string {\n if (cents > 0) return chalk.green(`+${formatCents(cents)}`);\n if (cents < 0) return chalk.red(formatCents(cents));\n return formatCents(cents);\n}\n\nexport function registerBalanceCommands(parent: Command) {\n parent\n .command(\"balance\")\n .description(\"Show available credits, held credits, and recent transactions\")\n .option(\"-n, --limit <n>\", \"Number of transactions to show (default 10)\", \"10\")\n .action(async (options) => {\n const opts = parent.opts() as ClientOpts;\n const limit = Number(options.limit) || 10;\n\n const [{ data: balance }, { data: transactions }] = await Promise.all([\n get<BalanceResponse>(\"/billing/balance\", undefined, opts),\n get<LedgerRow[]>(\"/billing/transactions\", { per_page: limit }, opts),\n ]);\n\n if (isJsonMode()) {\n return printJson({ balance, transactions });\n }\n\n const lowBalance = balance.available_cents < 100;\n const availableLine = lowBalance\n ? chalk.red(formatCents(balance.available_cents)) + chalk.dim(\" (low)\")\n : chalk.bold.green(formatCents(balance.available_cents));\n\n printDetail([\n [\"Available\", availableLine],\n [\"Total balance\", formatCents(balance.balance_cents)],\n [\"On hold\", formatCents(balance.reserved_cents)],\n [\n \"Signup bonus\",\n balance.signup_bonus_granted\n ? chalk.green(\"granted\") + ` (${formatCents(balance.signup_bonus_cents)})`\n : chalk.dim(\"not yet granted\"),\n ],\n [\"Lifetime top-ups\", formatCents(balance.lifetime_topup_cents)],\n ]);\n\n if (transactions && transactions.length > 0) {\n console.log(`\\n${chalk.bold(\"Recent transactions\")}`);\n printTable(\n [\"Date\", \"Type\", \"Amount\", \"Balance\", \"Reference\"],\n transactions.map((row) => [\n formatDate(row.created_at),\n KIND_LABELS[row.kind] ?? row.kind,\n formatSigned(row.amount_cents),\n formatCents(row.balance_after_cents),\n row.reference_id ? shortId(row.reference_id) : chalk.dim(\"—\"),\n ])\n );\n } else {\n console.log(\n `\\n${chalk.dim(\"No transactions yet — run `tt topup` to add credits.\")}`\n );\n }\n\n if (lowBalance) {\n console.log(\n `\\n${formatStatus(\"preparing\")} ${chalk.yellow(\n \"Run `tt topup` to add more available credits before starting a run.\"\n )}`\n );\n }\n });\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport open from \"open\";\nimport { post, type ClientOpts } from \"../client.js\";\nimport { printJson, isJsonMode, printSuccess } from \"../output.js\";\n\ninterface TopupResponse {\n checkout_url: string;\n session_id: string;\n}\n\nconst PRESETS_USD = [10, 25, 50, 100];\nconst MIN_USD = 5;\nconst MAX_USD = 10000;\n\nfunction parseAmount(input: string | undefined): number | null {\n if (!input) return null;\n const cleaned = input.replace(/^\\$/, \"\").trim();\n const num = Number(cleaned);\n if (!Number.isFinite(num) || num <= 0) return null;\n return num;\n}\n\nasync function readLine(prompt: string): Promise<string> {\n const readline = await import(\"node:readline/promises\");\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n try {\n return (await rl.question(prompt)).trim();\n } finally {\n rl.close();\n }\n}\n\nexport function registerTopupCommands(parent: Command) {\n parent\n .command(\"topup\")\n .description(\"Add prepaid credits via Stripe Checkout\")\n .option(\"-a, --amount <usd>\", \"Amount in USD (e.g. 25)\")\n .option(\"--no-open\", \"Print checkout URL instead of opening the browser\")\n .action(async (options) => {\n const opts = parent.opts() as ClientOpts;\n\n let amountUsd: number | null;\n\n if (options.amount !== undefined) {\n amountUsd = parseAmount(options.amount);\n if (amountUsd === null) {\n throw new Error(\"Invalid amount\");\n }\n } else {\n if (isJsonMode()) {\n throw new Error(\n \"amount is required in --json mode (use --amount <usd>)\"\n );\n }\n console.log(chalk.bold(\"Add credits via Stripe Checkout\"));\n console.log(\n chalk.dim(\n `Quick picks: ${PRESETS_USD.map((n) => `$${n}`).join(\", \")}`\n )\n );\n const input = await readLine(`Amount in USD (min $${MIN_USD}): `);\n amountUsd = parseAmount(input);\n if (amountUsd === null) {\n throw new Error(\"Invalid amount\");\n }\n }\n\n if (amountUsd < MIN_USD) {\n throw new Error(`Minimum top-up is $${MIN_USD}`);\n }\n if (amountUsd > MAX_USD) {\n throw new Error(`Maximum top-up is $${MAX_USD}`);\n }\n\n const amountCents = Math.round(amountUsd * 100);\n\n const { data } = await post<TopupResponse>(\n \"/billing/topup\",\n { amount_cents: amountCents },\n opts\n );\n\n if (isJsonMode()) {\n return printJson(data);\n }\n\n const url = data.checkout_url;\n console.log(\n `${chalk.bold(\"Checkout URL:\")} ${chalk.cyan(url)}\\n` +\n chalk.dim(\"Complete the payment to credit your account.\")\n );\n\n if (options.open !== false) {\n try {\n await open(url);\n printSuccess(\"Opened Stripe Checkout in your browser.\");\n } catch {\n console.log(\n chalk.yellow(\n \"Could not open browser automatically — copy the URL above.\"\n )\n );\n }\n }\n });\n}\n","import { Command } from \"commander\";\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { printSuccess, printError, printWarning } from \"../output.js\";\nimport type { LocalSpec } from \"../eval/types.js\";\n\nconst DEFAULT_SPEC_FILE = \"tunedtensor.json\";\n\nconst SCAFFOLD: LocalSpec = {\n name: \"My Agent\",\n description: \"\",\n base_model: \"meta-llama/Llama-3.2-3B-Instruct\",\n system_prompt: \"You are a helpful assistant.\",\n guidelines: [],\n constraints: [],\n examples: [\n { input: \"Hello\", output: \"Hi! How can I help you today?\" },\n ],\n eval_cases: [],\n};\n\nexport function registerInitCommand(parent: Command) {\n parent\n .command(\"init\")\n .description(\"Create a local behaviour spec file\")\n .option(\"-n, --name <name>\", \"Spec name\")\n .option(\"--model <model>\", \"Base model ID\")\n .option(\"-f, --file <path>\", \"Output file path\", DEFAULT_SPEC_FILE)\n .action(async (cmdOpts) => {\n const filePath = resolve(cmdOpts.file);\n\n if (existsSync(filePath)) {\n printWarning(`${cmdOpts.file} already exists. Use tt eval to run evals or edit it directly.`);\n return;\n }\n\n const spec: LocalSpec = { ...SCAFFOLD };\n if (cmdOpts.name) spec.name = cmdOpts.name;\n if (cmdOpts.model) spec.base_model = cmdOpts.model;\n\n writeFileSync(filePath, JSON.stringify(spec, null, 2) + \"\\n\");\n printSuccess(`Created ${cmdOpts.file}`);\n console.log(\"\\nNext steps:\");\n console.log(\" 1. Edit the spec: system_prompt, guidelines, examples\");\n console.log(\" 2. Run evals: tt eval --model <model-id>\");\n console.log(\" 3. Push to remote: tt push\");\n });\n}\n\nexport function loadSpec(filePath?: string): LocalSpec {\n const resolved = resolve(filePath || DEFAULT_SPEC_FILE);\n if (!existsSync(resolved)) {\n printError(\n `Spec file not found: ${filePath || DEFAULT_SPEC_FILE}\\nRun \\`tt init\\` to create one.`,\n );\n process.exit(1);\n }\n\n const raw = JSON.parse(readFileSync(resolved, \"utf-8\"));\n return raw as LocalSpec;\n}\n\nexport { DEFAULT_SPEC_FILE };\n","import { Command } from \"commander\";\nimport ora from \"ora\";\nimport chalk from \"chalk\";\nimport {\n printTable,\n printJson,\n isJsonMode,\n printWarning,\n truncate,\n} from \"../output.js\";\nimport type { ClientOpts } from \"../client.js\";\nimport { loadSpec, DEFAULT_SPEC_FILE } from \"./init.js\";\nimport { runEvals } from \"../eval/runner.js\";\nimport type { EvalSummary, ValidationCheck } from \"../eval/types.js\";\n\nexport function registerEvalCommand(parent: Command) {\n parent\n .command(\"eval\")\n .description(\"Evaluate a model against a behaviour spec using rule-based assertions\")\n .requiredOption(\"-m, --model <model>\", \"Model ID to evaluate (base or fine-tuned)\")\n .option(\"-f, --file <path>\", \"Spec file path\", DEFAULT_SPEC_FILE)\n .action(async (cmdOpts) => {\n const spec = loadSpec(cmdOpts.file);\n const clientOpts = parent.opts() as ClientOpts;\n\n if (!isJsonMode()) {\n console.log(chalk.dim(`\\nSpec: ${cmdOpts.file} | Model: ${cmdOpts.model}\\n`));\n }\n\n const spinner = ora(\"Running evals...\").start();\n\n const summary = await runEvals(spec, cmdOpts.model, {\n clientOpts,\n onProgress: (done, total) => { spinner.text = `Running evals... ${done}/${total}`; },\n });\n\n spinner.stop();\n\n if (isJsonMode()) return printJson(summary);\n\n printValidation(summary.spec_validation.checks);\n console.log();\n printResults(summary);\n });\n}\n\nfunction printValidation(checks: ValidationCheck[]) {\n console.log(chalk.bold(\"Spec Validation\"));\n for (const check of checks) {\n const icon = check.passed ? chalk.green(\"✓\") : chalk.red(\"✗\");\n const msg = check.message\n ? chalk.dim(` — ${check.message}`)\n : \"\";\n console.log(` ${icon} ${check.name}${msg}`);\n }\n}\n\nfunction printResults(summary: EvalSummary) {\n if (!summary.results.length) {\n printWarning(\"No eval cases to run. Add examples or eval_cases to your spec.\");\n return;\n }\n\n console.log(chalk.bold(`Eval Results (${summary.total}):`));\n\n printTable(\n [\"#\", \"Passed\", \"Input\", \"Latency\"],\n summary.results.map((r, i) => [\n String(i + 1),\n r.passed ? chalk.green(\"✓\") : chalk.red(\"✗\"),\n truncate(r.input, 40),\n r.latency_ms != null ? `${r.latency_ms}ms` : \"—\",\n ]),\n );\n\n console.log();\n\n const passStr = (summary.pass_rate * 100).toFixed(1) + \"%\";\n const color = summary.pass_rate >= 0.8\n ? chalk.green\n : summary.pass_rate >= 0.5\n ? chalk.yellow\n : chalk.red;\n\n console.log(\n ` Pass Rate: ${color(chalk.bold(passStr))} (${summary.passed}/${summary.total} passed)`,\n );\n\n const failedResults = summary.results.filter((r) => !r.passed);\n if (failedResults.length) {\n console.log(chalk.dim(`\\nFailed eval details:`));\n for (const r of failedResults) {\n console.log(chalk.dim(` • \"${truncate(r.input, 50)}\":`));\n if (r.actual) {\n console.log(chalk.dim(` Response: ${truncate(r.actual, 80)}`));\n }\n for (const a of r.assertions.filter((a) => !a.passed)) {\n console.log(chalk.red(` ✗ ${a.assertion}: ${a.message}`));\n }\n }\n }\n}\n","import type {\n AssertionResult,\n LocalSpec,\n ValidationCheck,\n ValidationResult,\n} from \"./types.js\";\n\nexport function validateSpec(spec: LocalSpec): ValidationResult {\n const checks: ValidationCheck[] = [];\n\n checks.push({\n name: \"Has name\",\n passed: Boolean(spec.name?.trim()),\n message: spec.name?.trim() ? undefined : \"Spec is missing a name\",\n });\n\n checks.push({\n name: \"Has system prompt\",\n passed: Boolean(spec.system_prompt?.trim()),\n message: spec.system_prompt?.trim()\n ? undefined\n : \"Spec is missing a system_prompt\",\n });\n\n checks.push({\n name: \"Has base model\",\n passed: Boolean(spec.base_model?.trim()),\n message: spec.base_model?.trim()\n ? undefined\n : \"Spec is missing a base_model\",\n });\n\n const exCount = spec.examples?.length ?? 0;\n checks.push({\n name: \"Has examples\",\n passed: exCount > 0,\n message: exCount > 0 ? `${exCount} example(s)` : \"Add at least one example\",\n });\n\n checks.push({\n name: \"Has guidelines\",\n passed: (spec.guidelines?.length ?? 0) > 0,\n message:\n (spec.guidelines?.length ?? 0) > 0\n ? undefined\n : \"Consider adding guidelines for better eval coverage\",\n });\n\n if (spec.constraints?.length && spec.examples?.length) {\n const violations = checkExamplesAgainstConstraints(spec);\n checks.push({\n name: \"Examples satisfy constraints\",\n passed: violations.length === 0,\n message:\n violations.length === 0\n ? undefined\n : violations.join(\"; \"),\n });\n }\n\n return {\n valid: checks.every((c) => c.passed),\n checks,\n };\n}\n\nfunction checkExamplesAgainstConstraints(spec: LocalSpec): string[] {\n const violations: string[] = [];\n for (const [i, ex] of spec.examples.entries()) {\n for (const constraint of spec.constraints) {\n const result = evaluateConstraint(ex.output, constraint);\n if (!result.passed) {\n violations.push(`Example ${i + 1} violates \"${constraint}\": ${result.message}`);\n }\n }\n }\n return violations;\n}\n\nfunction evaluateConstraint(\n text: string,\n constraint: string,\n): { passed: boolean; message?: string } {\n const lower = constraint.toLowerCase();\n\n const neverMatch = lower.match(/^never (?:share|mention|include|reveal|use|say|output|return|give|provide|show|disclose|expose)\\s+(.+)/);\n if (neverMatch) {\n const forbidden = neverMatch[1].replace(/['\"]/g, \"\").trim();\n if (text.toLowerCase().includes(forbidden.toLowerCase())) {\n return { passed: false, message: `Output contains \"${forbidden}\"` };\n }\n return { passed: true };\n }\n\n const alwaysMatch = lower.match(/^always (?:include|use|start with|end with|contain|respond in|reply in)\\s+(.+)/);\n if (alwaysMatch) {\n const required = alwaysMatch[1].replace(/['\"]/g, \"\").trim();\n if (!text.toLowerCase().includes(required.toLowerCase())) {\n return { passed: false, message: `Output missing \"${required}\"` };\n }\n return { passed: true };\n }\n\n return {\n passed: true,\n message: `Constraint not enforceable by rules: \"${constraint}\" (will be checked by LLM judge if a provider is configured)`,\n };\n}\n\nexport function runAssertions(\n text: string,\n assertions: string[],\n): AssertionResult[] {\n return assertions.map((assertion) => runSingleAssertion(text, assertion));\n}\n\nfunction runSingleAssertion(text: string, assertion: string): AssertionResult {\n const [type, ...rest] = assertion.split(\":\");\n const value = rest.join(\":\");\n\n switch (type) {\n case \"contains\":\n return {\n assertion,\n passed: text.includes(value),\n message: text.includes(value)\n ? undefined\n : `Expected output to contain \"${value}\"`,\n };\n\n case \"not-contains\":\n return {\n assertion,\n passed: !text.includes(value),\n message: !text.includes(value)\n ? undefined\n : `Expected output to not contain \"${value}\"`,\n };\n\n case \"matches\": {\n const re = new RegExp(value);\n const match = re.test(text);\n return {\n assertion,\n passed: match,\n message: match ? undefined : `Output did not match pattern /${value}/`,\n };\n }\n\n case \"max-length\": {\n const max = Number(value);\n return {\n assertion,\n passed: text.length <= max,\n message:\n text.length <= max\n ? undefined\n : `Output length ${text.length} exceeds max ${max}`,\n };\n }\n\n case \"min-length\": {\n const min = Number(value);\n return {\n assertion,\n passed: text.length >= min,\n message:\n text.length >= min\n ? undefined\n : `Output length ${text.length} below min ${min}`,\n };\n }\n\n case \"is-json\": {\n let valid = false;\n try {\n JSON.parse(text);\n valid = true;\n } catch {}\n return {\n assertion,\n passed: valid,\n message: valid ? undefined : \"Output is not valid JSON\",\n };\n }\n\n default:\n return {\n assertion,\n passed: true,\n message: `Unknown assertion type: ${type} (skipped)`,\n };\n }\n}\n\nexport function checkConstraints(\n text: string,\n constraints: string[],\n): AssertionResult[] {\n return constraints.map((constraint) => {\n const result = evaluateConstraint(text, constraint);\n return {\n assertion: `constraint: ${constraint}`,\n passed: result.passed,\n message: result.message,\n };\n });\n}\n","import type {\n EvalCase,\n EvalResult,\n EvalSummary,\n LocalSpec,\n PlaygroundResponse,\n} from \"./types.js\";\nimport type { ClientOpts } from \"../client.js\";\nimport { post } from \"../client.js\";\nimport { validateSpec } from \"./rules.js\";\nimport { runAssertions, checkConstraints } from \"./rules.js\";\n\nfunction buildEvalCases(spec: LocalSpec): EvalCase[] {\n if (spec.eval_cases?.length) return spec.eval_cases;\n\n return spec.examples.map((ex) => ({\n input: ex.input,\n expected: ex.output,\n }));\n}\n\nexport async function runEvals(\n spec: LocalSpec,\n model: string,\n opts?: {\n clientOpts?: ClientOpts;\n onProgress?: (completed: number, total: number) => void;\n },\n): Promise<EvalSummary> {\n const specValidation = validateSpec(spec);\n const cases = buildEvalCases(spec);\n const results: EvalResult[] = [];\n\n for (const [i, evalCase] of cases.entries()) {\n const result = await runSingleEval(spec, evalCase, model, opts?.clientOpts);\n results.push(result);\n opts?.onProgress?.(i + 1, cases.length);\n }\n\n return {\n total: results.length,\n passed: results.filter((r) => r.passed).length,\n failed: results.filter((r) => !r.passed).length,\n pass_rate: results.length ? results.filter((r) => r.passed).length / results.length : 0,\n model,\n results,\n spec_validation: specValidation,\n };\n}\n\nasync function runSingleEval(\n spec: LocalSpec,\n evalCase: EvalCase,\n model: string,\n clientOpts?: ClientOpts,\n): Promise<EvalResult> {\n try {\n const { data } = await post<PlaygroundResponse>(\n \"/playground/completions\",\n {\n model,\n messages: [\n { role: \"system\", content: spec.system_prompt },\n { role: \"user\", content: evalCase.input },\n ],\n temperature: 0,\n max_tokens: 2048,\n },\n clientOpts,\n );\n\n const assertions = [\n ...runAssertions(data.content, evalCase.assert ?? []),\n ...checkConstraints(data.content, spec.constraints),\n ];\n\n return {\n input: evalCase.input,\n expected: evalCase.expected ?? null,\n actual: data.content,\n passed: assertions.every((a) => a.passed),\n latency_ms: data.latency_ms,\n assertions,\n };\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return {\n input: evalCase.input,\n expected: evalCase.expected ?? null,\n actual: null,\n passed: false,\n latency_ms: null,\n assertions: [{ assertion: \"model-call\", passed: false, message: msg }],\n };\n }\n}\n","import { Command } from \"commander\";\nimport { readFileSync, writeFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { post, put, type ClientOpts } from \"../client.js\";\nimport { printSuccess, printJson, isJsonMode, shortId } from \"../output.js\";\nimport { loadSpec, DEFAULT_SPEC_FILE } from \"./init.js\";\n\ninterface RemoteSpec {\n id: string;\n name: string;\n [key: string]: unknown;\n}\n\nexport function registerPushCommand(parent: Command) {\n parent\n .command(\"push\")\n .description(\"Push local spec to the Tuned Tensor API\")\n .option(\"-f, --file <path>\", \"Spec file path\", DEFAULT_SPEC_FILE)\n .action(async (cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n const filePath = resolve(cmdOpts.file);\n const spec = loadSpec(cmdOpts.file);\n\n const { id, eval_cases, ...body } = spec as unknown as Record<string, unknown>;\n\n let data: RemoteSpec;\n\n if (id) {\n const res = await put<RemoteSpec>(`/behavior-specs/${id}`, body, opts);\n data = res.data;\n } else {\n const res = await post<RemoteSpec>(\"/behavior-specs\", body, opts);\n data = res.data;\n\n const raw = JSON.parse(readFileSync(filePath, \"utf-8\"));\n raw.id = data.id;\n writeFileSync(filePath, JSON.stringify(raw, null, 2) + \"\\n\");\n }\n\n if (isJsonMode()) return printJson(data);\n printSuccess(\n `Spec ${id ? \"updated\" : \"created\"}: ${data.name} (${shortId(data.id)})`,\n );\n });\n}\n"],"mappings":"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","names":["readFileSync","readFileSync","chalk","readFileSync","readFileSync","existsSync","existsSync","chalk","chalk","chalk","chalk","existsSync","readFileSync","writeFileSync","existsSync","writeFileSync","readFileSync","ora","chalk","chalk","ora","a","readFileSync","writeFileSync","resolve","resolve","readFileSync","writeFileSync"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tuned-tensor/cli",
3
- "version": "0.4.2",
3
+ "version": "0.4.3",
4
4
  "description": "CLI for Tuned Tensor — fine-tune and evaluate LLMs from the command line",
5
5
  "type": "module",
6
6
  "bin": {