@tuned-tensor/cli 0.21.0 → 0.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +83 -0
- package/dist/{chunk-PVLX7LJI.js → chunk-4SUXBHIY.js} +1319 -229
- package/dist/chunk-4SUXBHIY.js.map +1 -0
- package/dist/index.js +237 -37
- package/dist/index.js.map +1 -1
- package/dist/local-runtime.js +107 -44
- package/dist/local-runtime.js.map +1 -1
- package/docs/local-runtime/architecture.md +38 -0
- package/docs/local-runtime/aws-gpu.md +2 -0
- package/docs/spec-workflow.md +7 -0
- package/package.json +1 -1
- package/training/adapter/src/hub_download.py +384 -0
- package/training/adapter/src/prefetch.py +20 -31
- package/training/adapter/src/prefetch_dataset.py +116 -0
- package/training/adapter/src/serve.py +5 -1
- package/dist/chunk-PVLX7LJI.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
TRAINING_MODELS,
|
|
9
9
|
assertFoundationSettingsMatch,
|
|
10
10
|
assessHardware,
|
|
11
|
+
auditRun,
|
|
11
12
|
buildDecisionPythonCommand,
|
|
12
13
|
buildFoundationPythonCommand,
|
|
13
14
|
buildSystemMessage,
|
|
@@ -18,10 +19,12 @@ import {
|
|
|
18
19
|
configForSpec,
|
|
19
20
|
createExecutionPlan,
|
|
20
21
|
createLocalStore,
|
|
22
|
+
createRunConsoleReporter,
|
|
21
23
|
decisionLabels,
|
|
22
24
|
defaultLocalHome,
|
|
23
25
|
defaultStoreRoot,
|
|
24
26
|
deriveSampleSeed,
|
|
27
|
+
ensureDatasetCached,
|
|
25
28
|
evalReportSchema,
|
|
26
29
|
evaluateCapabilities,
|
|
27
30
|
expandUserPath,
|
|
@@ -55,7 +58,7 @@ import {
|
|
|
55
58
|
warningsFromSnapshot,
|
|
56
59
|
withDecisionPythonEnvironment,
|
|
57
60
|
withFoundationPythonEnvironment
|
|
58
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-4SUXBHIY.js";
|
|
59
62
|
|
|
60
63
|
// src/cli.ts
|
|
61
64
|
import { spawn as spawn4 } from "child_process";
|
|
@@ -2163,7 +2166,9 @@ function createTunedTensorTools(api, options = {}) {
|
|
|
2163
2166
|
runtime: Type2.Optional(Type2.Union([Type2.Record(Type2.String(), Type2.Unknown()), Type2.Null()])),
|
|
2164
2167
|
evaluation: Type2.Optional(Type2.Union([Type2.Record(Type2.String(), Type2.Unknown()), Type2.Null()])),
|
|
2165
2168
|
pipeline: Type2.Optional(Type2.Union([Type2.Record(Type2.String(), Type2.Unknown()), Type2.Null()])),
|
|
2166
|
-
dataset_prebuilt: Type2.Optional(Type2.Record(Type2.String(), Type2.Unknown()
|
|
2169
|
+
dataset_prebuilt: Type2.Optional(Type2.Record(Type2.String(), Type2.Unknown(), {
|
|
2170
|
+
description: "Local chat JSONL files ({training, validation|test}), or a Hugging Face dataset: {huggingface: {repo, revision?: 40-char commit, columns?: {input, output}}, training: 'repo/path.jsonl', test|validation: ...}. The user downloads it with `tt datasets prefetch tunedtensor.json`."
|
|
2171
|
+
}))
|
|
2167
2172
|
}, { additionalProperties: false })
|
|
2168
2173
|
}, { additionalProperties: false }),
|
|
2169
2174
|
async (p) => {
|
|
@@ -3752,6 +3757,8 @@ function gpuDetail(gpu) {
|
|
|
3752
3757
|
} else if (gpu.memory_total_bytes !== void 0) {
|
|
3753
3758
|
const used = gpu.memory_used_bytes;
|
|
3754
3759
|
parts.push(used === void 0 ? `${formatGiB(gpu.memory_total_bytes)} GiB VRAM` : `VRAM ${formatGiB(used)}/${formatGiB(gpu.memory_total_bytes)} GiB`);
|
|
3760
|
+
} else if (gpu.unified_memory) {
|
|
3761
|
+
parts.push("unified with system RAM");
|
|
3755
3762
|
}
|
|
3756
3763
|
if (gpu.temperature_c !== void 0) parts.push(`${Math.round(gpu.temperature_c)}\xB0C`);
|
|
3757
3764
|
return parts.join(" ");
|
|
@@ -3903,6 +3910,7 @@ function renderBanner(input) {
|
|
|
3903
3910
|
|
|
3904
3911
|
// src/local-runtime/live-usage.ts
|
|
3905
3912
|
import { execFile } from "child_process";
|
|
3913
|
+
import { readFileSync as readFileSync5 } from "fs";
|
|
3906
3914
|
import { statfs } from "fs/promises";
|
|
3907
3915
|
import { cpus, freemem, homedir, loadavg, totalmem } from "os";
|
|
3908
3916
|
import { dirname as dirname3, join as join7, resolve as resolve2 } from "path";
|
|
@@ -3974,6 +3982,50 @@ function queryNvidia(env, timeoutMs) {
|
|
|
3974
3982
|
function tidyCpuModel(model) {
|
|
3975
3983
|
return model.replace(/\((?:R|TM|tm|r)\)/g, "").replace(/\s+(?:CPU|Processor)\b/gi, "").replace(/\s*@\s*[\d.]+\s*[GM]Hz/i, "").replace(/\s+\d+-Core$/i, "").replace(/\s+/g, " ").trim() || "CPU";
|
|
3976
3984
|
}
|
|
3985
|
+
var ARM_CORES = {
|
|
3986
|
+
"0xd03": "Cortex-A53",
|
|
3987
|
+
"0xd05": "Cortex-A55",
|
|
3988
|
+
"0xd08": "Cortex-A72",
|
|
3989
|
+
"0xd0b": "Cortex-A76",
|
|
3990
|
+
"0xd0c": "Neoverse-N1",
|
|
3991
|
+
"0xd40": "Neoverse-V1",
|
|
3992
|
+
"0xd41": "Cortex-A78",
|
|
3993
|
+
"0xd44": "Cortex-X1",
|
|
3994
|
+
"0xd47": "Cortex-A710",
|
|
3995
|
+
"0xd48": "Cortex-X2",
|
|
3996
|
+
"0xd49": "Neoverse-N2",
|
|
3997
|
+
"0xd4d": "Cortex-A715",
|
|
3998
|
+
"0xd4e": "Cortex-X3",
|
|
3999
|
+
"0xd4f": "Neoverse-V2",
|
|
4000
|
+
"0xd80": "Cortex-A520",
|
|
4001
|
+
"0xd81": "Cortex-A720",
|
|
4002
|
+
"0xd82": "Cortex-X4",
|
|
4003
|
+
"0xd84": "Neoverse-V3",
|
|
4004
|
+
"0xd85": "Cortex-X925",
|
|
4005
|
+
"0xd87": "Cortex-A725",
|
|
4006
|
+
"0xd8e": "Neoverse-N3"
|
|
4007
|
+
};
|
|
4008
|
+
function armCpuModel(cpuinfo) {
|
|
4009
|
+
const names = [];
|
|
4010
|
+
let implementer;
|
|
4011
|
+
for (const line of cpuinfo.split(/\r?\n/)) {
|
|
4012
|
+
const [key, value] = line.split(":").map((item) => item.trim().toLowerCase());
|
|
4013
|
+
if (key === "cpu implementer") implementer = value;
|
|
4014
|
+
if (key !== "cpu part" || !value) continue;
|
|
4015
|
+
const name = implementer === "0x41" ? ARM_CORES[value] : void 0;
|
|
4016
|
+
if (name && !names.includes(name)) names.push(name);
|
|
4017
|
+
}
|
|
4018
|
+
return names.length > 0 ? names.join(" + ") : void 0;
|
|
4019
|
+
}
|
|
4020
|
+
function cpuModel(reported, platform, arch) {
|
|
4021
|
+
const model = tidyCpuModel(reported ?? "");
|
|
4022
|
+
if (platform !== "linux" || !/^(?:unknown|CPU)$/i.test(model)) return model;
|
|
4023
|
+
try {
|
|
4024
|
+
return armCpuModel(readFileSync5("/proc/cpuinfo", "utf8")) ?? (arch === "arm64" ? "Arm CPU" : model);
|
|
4025
|
+
} catch {
|
|
4026
|
+
return arch === "arm64" ? "Arm CPU" : model;
|
|
4027
|
+
}
|
|
4028
|
+
}
|
|
3977
4029
|
async function modelCacheDisk(env) {
|
|
3978
4030
|
const path = resolve2(env.HF_HOME?.trim() || join7(homedir(), ".cache", "huggingface"));
|
|
3979
4031
|
for (let probe = path, depth = 0; depth < 8; depth += 1) {
|
|
@@ -3992,9 +4044,9 @@ async function modelCacheDisk(env) {
|
|
|
3992
4044
|
}
|
|
3993
4045
|
return void 0;
|
|
3994
4046
|
}
|
|
3995
|
-
function appleGpu(
|
|
4047
|
+
function appleGpu(cpuModel2, platform, arch) {
|
|
3996
4048
|
if (platform !== "darwin" || arch !== "arm64") return void 0;
|
|
3997
|
-
const chip = /apple/i.test(
|
|
4049
|
+
const chip = /apple/i.test(cpuModel2) ? cpuModel2.trim() : "Apple Silicon";
|
|
3998
4050
|
return {
|
|
3999
4051
|
index: 0,
|
|
4000
4052
|
name: `${chip} GPU`,
|
|
@@ -4015,7 +4067,7 @@ async function sampleLiveUsage(options = {}) {
|
|
|
4015
4067
|
]);
|
|
4016
4068
|
const after = cpuTimes();
|
|
4017
4069
|
const list = cpus();
|
|
4018
|
-
const model =
|
|
4070
|
+
const model = cpuModel(list[0]?.model, platform, arch);
|
|
4019
4071
|
const total = totalmem();
|
|
4020
4072
|
const apple = nvidia.gpus.length === 0 ? appleGpu(model, platform, arch) : void 0;
|
|
4021
4073
|
const [one, five, fifteen] = loadavg();
|
|
@@ -4061,12 +4113,15 @@ var COMMAND_CATALOG = [
|
|
|
4061
4113
|
{ path: "runs report", description: "Show a local run report.", group: "Inspect", modes: LOCAL },
|
|
4062
4114
|
{ path: "runs compare", description: "Compare two local run reports.", group: "Inspect", modes: LOCAL },
|
|
4063
4115
|
{ path: "runs events", description: "Show local run progress events.", group: "Inspect", modes: LOCAL },
|
|
4116
|
+
{ path: "runs audit", description: "Verify a run's event log and report, with timeline and provenance.", group: "Inspect", modes: LOCAL },
|
|
4064
4117
|
{ path: "models list", description: "List local models.", group: "Inspect", modes: LOCAL },
|
|
4065
4118
|
{ path: "models get", description: "Show a local model.", group: "Inspect", modes: LOCAL },
|
|
4066
4119
|
{ path: "models serve", description: "Serve a model through an OpenAI-compatible API.", group: "Serving", modes: LOCAL },
|
|
4067
4120
|
{ path: "models verify", description: "Verify a local model artifact.", group: "Serving", modes: LOCAL },
|
|
4068
4121
|
{ path: "models prefetch", description: "Download the local base-model snapshot.", group: "Serving", modes: LOCAL },
|
|
4069
4122
|
{ path: "models verify-base", description: "Verify the local base-model snapshot.", group: "Serving", modes: LOCAL },
|
|
4123
|
+
{ path: "datasets prefetch", description: "Download the spec's Hugging Face dataset files.", group: "Workflow", modes: LOCAL },
|
|
4124
|
+
{ path: "datasets verify", description: "Verify the cached Hugging Face dataset files.", group: "Workflow", modes: LOCAL },
|
|
4070
4125
|
{ path: "models active", description: "Show the active local model.", group: "Serving", modes: LOCAL },
|
|
4071
4126
|
{ path: "models activate", description: "Activate a verified local model.", group: "Serving", modes: LOCAL },
|
|
4072
4127
|
{ path: "models rollback", description: "Roll back the active local model.", group: "Serving", modes: LOCAL },
|
|
@@ -6385,10 +6440,22 @@ function renderValidate(value) {
|
|
|
6385
6440
|
["Spec", text(value.behavior_spec_id)],
|
|
6386
6441
|
["Base model", text(value.base_model)],
|
|
6387
6442
|
["Dataset", text(value.dataset_format)],
|
|
6443
|
+
["Hugging Face", huggingFaceDatasetLabel(value)],
|
|
6388
6444
|
["Artifacts", text(value.artifact_root)],
|
|
6389
6445
|
["Store", text(value.store_root)],
|
|
6390
6446
|
["Dry run", text(value.dry_run)]
|
|
6391
6447
|
]);
|
|
6448
|
+
if (value.dataset_status === "not_downloaded") {
|
|
6449
|
+
printWarning(`Dataset files are not downloaded yet; dataset contents were not checked. Run \`${text(value.next_step) ?? "tt datasets prefetch"}\`.`);
|
|
6450
|
+
}
|
|
6451
|
+
}
|
|
6452
|
+
function huggingFaceDatasetLabel(value) {
|
|
6453
|
+
const source = record3(value.dataset_source) ?? record3(value.dataset_huggingface);
|
|
6454
|
+
const repo = text(source?.repo);
|
|
6455
|
+
if (!repo) return void 0;
|
|
6456
|
+
const revision = text(source?.revision) ?? "main";
|
|
6457
|
+
const status2 = value.dataset_status === "not_downloaded" ? "not downloaded" : "cached";
|
|
6458
|
+
return `${repo}@${revision} (${status2}${source?.pinned === false || !text(source?.revision) ? ", unpinned" : ""})`;
|
|
6392
6459
|
}
|
|
6393
6460
|
function renderRun(value) {
|
|
6394
6461
|
const runStatus = text(value.status) ?? "unknown";
|
|
@@ -6443,6 +6510,68 @@ function renderRunEvents(value) {
|
|
|
6443
6510
|
])
|
|
6444
6511
|
);
|
|
6445
6512
|
}
|
|
6513
|
+
function formatSeconds(value) {
|
|
6514
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return "running";
|
|
6515
|
+
const seconds = Math.round(value);
|
|
6516
|
+
const hours = Math.floor(seconds / 3600);
|
|
6517
|
+
const minutes = Math.floor(seconds % 3600 / 60);
|
|
6518
|
+
const rest = seconds % 60;
|
|
6519
|
+
if (hours) return `${hours}h ${String(minutes).padStart(2, "0")}m`;
|
|
6520
|
+
if (minutes) return `${minutes}m ${String(rest).padStart(2, "0")}s`;
|
|
6521
|
+
return `${rest}s`;
|
|
6522
|
+
}
|
|
6523
|
+
function shortHash(value) {
|
|
6524
|
+
const hash = text(value);
|
|
6525
|
+
return hash ? hash.slice(0, 12) : void 0;
|
|
6526
|
+
}
|
|
6527
|
+
function renderRunAudit(value) {
|
|
6528
|
+
const verdict = text(value.verdict);
|
|
6529
|
+
const chain = record3(value.chain);
|
|
6530
|
+
const reportInfo = record3(value.report);
|
|
6531
|
+
const findings = Array.isArray(value.findings) ? value.findings.map(String) : [];
|
|
6532
|
+
if (verdict === "verified") printSuccess("Run evidence verified: event log intact and report unchanged since completion");
|
|
6533
|
+
else if (verdict === "tampered") printError("Run evidence does not verify");
|
|
6534
|
+
else printWarning("Run evidence is incomplete");
|
|
6535
|
+
for (const finding of findings) console.log(` - ${finding}`);
|
|
6536
|
+
printDetail([
|
|
6537
|
+
["Run", text(value.run_id)],
|
|
6538
|
+
["Status", status(value.status)],
|
|
6539
|
+
["Event chain", `${text(chain?.status) ?? "\u2014"} (${text(chain?.chained_events) ?? 0}/${text(chain?.events) ?? 0} chained, head ${shortHash(chain?.head_hash) ?? "\u2014"})`],
|
|
6540
|
+
["Report sha256", shortHash(reportInfo?.recorded_sha256) ?? "not recorded"]
|
|
6541
|
+
]);
|
|
6542
|
+
const timeline = rows(value.timeline);
|
|
6543
|
+
if (timeline.length > 0) {
|
|
6544
|
+
console.log("");
|
|
6545
|
+
printTable(
|
|
6546
|
+
["Started", "Stage", "Duration", "Status"],
|
|
6547
|
+
timeline.map((entry) => [
|
|
6548
|
+
formatDate(text(entry.started_at)),
|
|
6549
|
+
text(entry.stage) ?? "\u2014",
|
|
6550
|
+
formatSeconds(entry.duration_seconds),
|
|
6551
|
+
status(entry.status)
|
|
6552
|
+
])
|
|
6553
|
+
);
|
|
6554
|
+
}
|
|
6555
|
+
const provenance = record3(value.provenance);
|
|
6556
|
+
if (provenance) {
|
|
6557
|
+
const software = record3(provenance.software);
|
|
6558
|
+
const execution = record3(provenance.execution);
|
|
6559
|
+
const spec = record3(provenance.spec);
|
|
6560
|
+
const baseModel = record3(provenance.base_model);
|
|
6561
|
+
const data3 = record3(provenance.data);
|
|
6562
|
+
const files = record3(data3?.file_sha256) ?? {};
|
|
6563
|
+
console.log("");
|
|
6564
|
+
printDetail([
|
|
6565
|
+
["TT", `${text(software?.tt_version) ?? "\u2014"} (node ${text(software?.node_version) ?? "\u2014"}, ${text(software?.platform) ?? "\u2014"}/${text(software?.arch) ?? "\u2014"})`],
|
|
6566
|
+
["Execution", `${text(execution?.target) ?? "\u2014"}${text(execution?.instance_id) ? ` ${text(execution?.instance_id)}` : ""} via ${text(execution?.training_backend) ?? "\u2014"}`],
|
|
6567
|
+
["Spec", `${text(spec?.file_path) ?? text(spec?.behavior_spec_id) ?? "\u2014"} (sha256 ${shortHash(spec?.file_sha256) ?? shortHash(spec?.snapshot_sha256) ?? "\u2014"})`],
|
|
6568
|
+
["Base model", `${text(baseModel?.id) ?? "\u2014"}@${shortHash(baseModel?.revision) ?? "unpinned"}`],
|
|
6569
|
+
...Object.entries(files).map(([split, hash]) => [`Data ${split}`, `sha256 ${shortHash(hash)}`]),
|
|
6570
|
+
["Training data", `sha256 ${shortHash(data3?.compiled_training_sha256) ?? "\u2014"} (${text(data3?.training_examples) ?? "\u2014"} examples)`],
|
|
6571
|
+
["Evaluation", `${text(data3?.eval_examples_used) ?? "\u2014"}/${text(data3?.eval_examples_total) ?? "\u2014"} ${text(data3?.eval_split) ?? ""} (seed ${text(data3?.eval_sample_seed) ?? "\u2014"})`]
|
|
6572
|
+
]);
|
|
6573
|
+
}
|
|
6574
|
+
}
|
|
6446
6575
|
function renderRunRecord(value) {
|
|
6447
6576
|
printDetail([
|
|
6448
6577
|
["Run", text(value.id) ?? text(value.run_id)],
|
|
@@ -6548,6 +6677,22 @@ function renderModelPrefetch(value) {
|
|
|
6548
6677
|
["Cache", text(value.model_cache) ?? text(value.hf_home)]
|
|
6549
6678
|
]);
|
|
6550
6679
|
}
|
|
6680
|
+
function renderDatasetPrefetch(value) {
|
|
6681
|
+
printSuccess(
|
|
6682
|
+
value.local_files_only === true ? "Verified the cached Hugging Face dataset" : "Dataset is ready locally"
|
|
6683
|
+
);
|
|
6684
|
+
const files = record3(value.files) ?? {};
|
|
6685
|
+
printDetail([
|
|
6686
|
+
["Dataset", text(value.repo)],
|
|
6687
|
+
["Revision", `${text(value.revision) ?? "\u2014"}${value.pinned === false ? " (unpinned: set dataset_prebuilt.huggingface.revision to pin it)" : ""}`],
|
|
6688
|
+
...Object.entries(files).map(([split, file]) => {
|
|
6689
|
+
const entry = record3(file);
|
|
6690
|
+
return [split[0].toUpperCase() + split.slice(1), `${text(entry?.path) ?? "\u2014"} (${displayBytes(entry?.size_bytes) ?? "\u2014"}, sha256 ${String(text(entry?.sha256) ?? "").slice(0, 12)})`];
|
|
6691
|
+
}),
|
|
6692
|
+
["Snapshot", text(value.snapshot_path)],
|
|
6693
|
+
["Cache", text(value.hub_cache)]
|
|
6694
|
+
]);
|
|
6695
|
+
}
|
|
6551
6696
|
function renderActiveModel(value) {
|
|
6552
6697
|
const active = text(value.active) ?? "base";
|
|
6553
6698
|
const pointer = record3(value.pointer);
|
|
@@ -6649,6 +6794,10 @@ function renderKnownJson(args2, value) {
|
|
|
6649
6794
|
renderRunEvents(value);
|
|
6650
6795
|
return true;
|
|
6651
6796
|
}
|
|
6797
|
+
if (subcommand === "audit" && isRecord4(value)) {
|
|
6798
|
+
renderRunAudit(value);
|
|
6799
|
+
return true;
|
|
6800
|
+
}
|
|
6652
6801
|
if (subcommand === "get" && isRecord4(value)) {
|
|
6653
6802
|
renderRunRecord(value);
|
|
6654
6803
|
return true;
|
|
@@ -6685,6 +6834,10 @@ function renderKnownJson(args2, value) {
|
|
|
6685
6834
|
return true;
|
|
6686
6835
|
}
|
|
6687
6836
|
}
|
|
6837
|
+
if (command === "datasets" && isRecord4(value)) {
|
|
6838
|
+
renderDatasetPrefetch(value);
|
|
6839
|
+
return true;
|
|
6840
|
+
}
|
|
6688
6841
|
if (command === "serve" && isRecord4(value)) {
|
|
6689
6842
|
renderServePlan(value);
|
|
6690
6843
|
return true;
|
|
@@ -6862,6 +7015,14 @@ function selectedSpecArgument(args2, cwd) {
|
|
|
6862
7015
|
if (command === "models" && ["prefetch", "verify-base"].includes(args2[1] ?? "")) {
|
|
6863
7016
|
return positionalSpecArgument(args2, 2, join9(cwd, DEFAULT_SPEC_NAME));
|
|
6864
7017
|
}
|
|
7018
|
+
if (command === "datasets") {
|
|
7019
|
+
if (args2[1] === void 0 || args2[1].startsWith("-") || args2[1].endsWith(".json")) {
|
|
7020
|
+
args2.splice(1, 0, "prefetch");
|
|
7021
|
+
}
|
|
7022
|
+
if (["prefetch", "verify"].includes(args2[1] ?? "")) {
|
|
7023
|
+
return positionalSpecArgument(args2, 2, join9(cwd, DEFAULT_SPEC_NAME));
|
|
7024
|
+
}
|
|
7025
|
+
}
|
|
6865
7026
|
const serves = command === "serve" || command === "models" && args2[1] === "serve";
|
|
6866
7027
|
if (!serves) return null;
|
|
6867
7028
|
const explicit = optionValueArgument(args2, "--spec");
|
|
@@ -7002,6 +7163,8 @@ function normalizeProjectedPaths(value, replacements) {
|
|
|
7002
7163
|
async function spawnLocalCli(args2) {
|
|
7003
7164
|
const output = args2.stdout ?? process.stdout;
|
|
7004
7165
|
const errors = args2.stderr ?? process.stderr;
|
|
7166
|
+
const errorTerminal = errors;
|
|
7167
|
+
const childEnv = errorTerminal.isTTY && !args2.jsonMode && args2.env.TT_PROGRESS_TTY === void 0 ? { ...args2.env, TT_PROGRESS_TTY: "1", TT_PROGRESS_COLUMNS: String(errorTerminal.columns ?? 100) } : args2.env;
|
|
7005
7168
|
const pipeInput = Boolean(args2.stdin && args2.stdin !== process.stdin);
|
|
7006
7169
|
const pipeStreamingOutput = args2.streamingStdout && Boolean(args2.stdout && args2.stdout !== process.stdout);
|
|
7007
7170
|
const child = spawn(
|
|
@@ -7009,7 +7172,7 @@ async function spawnLocalCli(args2) {
|
|
|
7009
7172
|
[args2.entrypoint, ...args2.commandArgs],
|
|
7010
7173
|
{
|
|
7011
7174
|
cwd: args2.cwd,
|
|
7012
|
-
env:
|
|
7175
|
+
env: childEnv,
|
|
7013
7176
|
stdio: [
|
|
7014
7177
|
pipeInput ? "pipe" : "inherit",
|
|
7015
7178
|
args2.streamingStdout && !pipeStreamingOutput ? "inherit" : "pipe",
|
|
@@ -7173,7 +7336,8 @@ var LOCAL_COMMANDS = [
|
|
|
7173
7336
|
"validate",
|
|
7174
7337
|
"serve",
|
|
7175
7338
|
"runs",
|
|
7176
|
-
"models"
|
|
7339
|
+
"models",
|
|
7340
|
+
"datasets"
|
|
7177
7341
|
];
|
|
7178
7342
|
var LOCAL_COMMAND_DESCRIPTIONS = {
|
|
7179
7343
|
info: "Show the installed local runtime version and runner status",
|
|
@@ -7183,7 +7347,8 @@ var LOCAL_COMMAND_DESCRIPTIONS = {
|
|
|
7183
7347
|
validate: "Validate a local behavior spec without executing it",
|
|
7184
7348
|
serve: "Serve a verified adapter, the active model, or the protected base",
|
|
7185
7349
|
runs: "Inspect locally stored runs",
|
|
7186
|
-
models: "Inspect, verify, prefetch, or serve local models"
|
|
7350
|
+
models: "Inspect, verify, prefetch, or serve local models",
|
|
7351
|
+
datasets: "Download or verify the Hugging Face dataset a spec trains on"
|
|
7187
7352
|
};
|
|
7188
7353
|
function applyExitCode(result2) {
|
|
7189
7354
|
if (result2?.exitCode !== null && result2?.exitCode !== void 0) {
|
|
@@ -7298,7 +7463,7 @@ function registerAgentCommands(parent, options) {
|
|
|
7298
7463
|
}
|
|
7299
7464
|
|
|
7300
7465
|
// src/commands/pipeline.ts
|
|
7301
|
-
import { existsSync as existsSync4, readFileSync as
|
|
7466
|
+
import { existsSync as existsSync4, readFileSync as readFileSync6, writeFileSync as writeFileSync3 } from "fs";
|
|
7302
7467
|
import { dirname as dirname9, join as join13, resolve as resolve8 } from "path";
|
|
7303
7468
|
|
|
7304
7469
|
// src/local-runtime/project-migration.ts
|
|
@@ -8186,7 +8351,7 @@ function loadPipelineFile(path) {
|
|
|
8186
8351
|
const resolved = resolve8(path);
|
|
8187
8352
|
if (!existsSync4(resolved)) throw new Error(`Pipeline file not found: ${path}. Run \`tt pipeline init\` to create one.`);
|
|
8188
8353
|
try {
|
|
8189
|
-
return JSON.parse(
|
|
8354
|
+
return JSON.parse(readFileSync6(resolved, "utf8"));
|
|
8190
8355
|
} catch (error) {
|
|
8191
8356
|
throw new Error(`Pipeline file must be JSON: ${error.message}`);
|
|
8192
8357
|
}
|
|
@@ -8202,7 +8367,7 @@ function resolvePipelineDocument(options, specRequired) {
|
|
|
8202
8367
|
if (requested !== void 0) return { document: parsePipeline(requested) };
|
|
8203
8368
|
throw new Error(`Behavior spec not found: ${options.spec}. Create tunedtensor.json or pass an explicit --file for a recipe-only preview.`);
|
|
8204
8369
|
}
|
|
8205
|
-
const source =
|
|
8370
|
+
const source = readFileSync6(specPath, "utf8");
|
|
8206
8371
|
const input = parseLocalRunInput(JSON.parse(source), specPath);
|
|
8207
8372
|
const document = pipelineForRunInput(input, requested);
|
|
8208
8373
|
const spec = {
|
|
@@ -8260,7 +8425,7 @@ function registerPipelineCommands(parent) {
|
|
|
8260
8425
|
pipeline2.command("init").description("Write a canonical v1 pipeline recipe").option("-f, --file <path>", "Legacy standalone recipe output (default: embed in tunedtensor.json)").option("--engine <engine>", "adapter (default) or foundation").option("--spec <path>", "Foundation spec whose hyperparameters stamp the DAG").action(async (options) => {
|
|
8261
8426
|
if (!options.file) {
|
|
8262
8427
|
const path2 = resolve8(options.spec ?? DEFAULT_SPEC_FILE);
|
|
8263
|
-
const raw = JSON.parse(
|
|
8428
|
+
const raw = JSON.parse(readFileSync6(path2, "utf8"));
|
|
8264
8429
|
const input = parseLocalRunInput(raw, path2);
|
|
8265
8430
|
if (input.kind === "request") throw new Error("Pipeline init requires a behavior spec.");
|
|
8266
8431
|
if (options.engine && options.engine !== (input.spec.engine ?? "adapter")) throw new Error("--engine must match the spec.");
|
|
@@ -8324,7 +8489,7 @@ function registerPipelineCommands(parent) {
|
|
|
8324
8489
|
const plan = createExecutionPlan(document, { only: parseList(options.only), skip: parseList(options.skip) });
|
|
8325
8490
|
outputPlan({ ...plan, ...spec ? { spec } : {} }, await hostWarningsForPipeline(document, input));
|
|
8326
8491
|
});
|
|
8327
|
-
pipeline2.command("run").description("Run an ordered local pipeline, or safely preview any pipeline").option("--dry-run", "Resolve and display only; never execute, transfer, or reserve credits").option("-f, --file <path>", "Explicit pipeline recipe (default: derive from behavior spec)").option("--spec <path>", "Local behavior spec", DEFAULT_SPEC_FILE).option("--config <path>", "Local runtime config").option("--output <path>", "Foundation or decision run directory (must not already exist)").option("--resume <path>", "Resume a foundation run directory").option("--only <ids>", "Comma-separated step IDs to include").option("--skip <ids>", "Comma-separated step IDs to omit").action(async (options, command) => {
|
|
8492
|
+
pipeline2.command("run").description("Run an ordered local pipeline, or safely preview any pipeline").option("--dry-run", "Resolve and display only; never execute, transfer, or reserve credits").option("-f, --file <path>", "Explicit pipeline recipe (default: derive from behavior spec)").option("--spec <path>", "Local behavior spec", DEFAULT_SPEC_FILE).option("--config <path>", "Local runtime config").option("--output <path>", "Foundation or decision run directory (must not already exist)").option("--resume <path>", "Resume a foundation run directory").option("--only <ids>", "Comma-separated step IDs to include").option("--skip <ids>", "Comma-separated step IDs to omit").option("--verbose", "Also stream training and evaluation process logs").option("--quiet", "Do not print live stage progress").action(async (options, command) => {
|
|
8328
8493
|
if (options.output && options.resume) {
|
|
8329
8494
|
throw new Error("--output and --resume are mutually exclusive.");
|
|
8330
8495
|
}
|
|
@@ -8387,7 +8552,19 @@ function registerPipelineCommands(parent) {
|
|
|
8387
8552
|
...plan.name ? { name: plan.name } : {},
|
|
8388
8553
|
steps: plan.steps.map(({ transfers: _transfers, ...step }) => step)
|
|
8389
8554
|
};
|
|
8390
|
-
const
|
|
8555
|
+
const reporter = options.quiet ? void 0 : createRunConsoleReporter({ verbose: options.verbose });
|
|
8556
|
+
const { request: request2 } = await ensureDatasetCached({ request: input.request, config, reporter });
|
|
8557
|
+
const result2 = await runLocalPipeline({
|
|
8558
|
+
request: request2,
|
|
8559
|
+
config,
|
|
8560
|
+
pipeline: localPipeline,
|
|
8561
|
+
...input.kind === "spec" ? { projectSpec: input.spec } : {},
|
|
8562
|
+
...spec ? { specFile: { path: spec.path, sha256: spec.sha256 } } : {},
|
|
8563
|
+
...reporter ? { reporter } : {}
|
|
8564
|
+
});
|
|
8565
|
+
if (!isJsonMode()) {
|
|
8566
|
+
console.error(`Run ${result2.request.run_id}: \`tt runs audit ${result2.request.run_id}\` verifies its record and shows timing and provenance.`);
|
|
8567
|
+
}
|
|
8391
8568
|
if (isJsonMode()) return printJson({ ...result2, spec });
|
|
8392
8569
|
printSuccess(`Pipeline completed with status ${result2.status}.`);
|
|
8393
8570
|
});
|
|
@@ -8660,7 +8837,7 @@ function registerTopupCommands(parent) {
|
|
|
8660
8837
|
|
|
8661
8838
|
// src/commands/publish.ts
|
|
8662
8839
|
import { createInterface as createInterface4 } from "readline/promises";
|
|
8663
|
-
import { existsSync as existsSync5, readFileSync as
|
|
8840
|
+
import { existsSync as existsSync5, readFileSync as readFileSync7 } from "fs";
|
|
8664
8841
|
import { homedir as homedir3 } from "os";
|
|
8665
8842
|
import { isAbsolute as isAbsolute5, join as join14, resolve as resolve9 } from "path";
|
|
8666
8843
|
import { stdin as defaultStdin, stdout as defaultStdout } from "process";
|
|
@@ -8677,13 +8854,13 @@ function resolvePublishStoreRoot(options) {
|
|
|
8677
8854
|
const localConfigPath = join14(cwd, "local-runner.json");
|
|
8678
8855
|
const projectPath = join14(cwd, "tunedtensor.json");
|
|
8679
8856
|
if (existsSync5(projectPath)) {
|
|
8680
|
-
const spec = localBehaviorSpecFileSchema.parse(JSON.parse(
|
|
8857
|
+
const spec = localBehaviorSpecFileSchema.parse(JSON.parse(readFileSync7(projectPath, "utf8")));
|
|
8681
8858
|
if (existsSync5(localConfigPath) && (spec.runtime || spec.evaluation)) throw new Error("Conflicting configuration sources; migrate local-runner.json first.");
|
|
8682
8859
|
if (!existsSync5(localConfigPath)) return expandPath2(spec.runtime?.storeRoot ?? (env.TT_LOCAL_HOME?.trim() || DEFAULT_PROJECT_STORE_ROOT), cwd, homeDirectory);
|
|
8683
8860
|
}
|
|
8684
8861
|
if (existsSync5(localConfigPath)) {
|
|
8685
8862
|
try {
|
|
8686
|
-
const raw = JSON.parse(
|
|
8863
|
+
const raw = JSON.parse(readFileSync7(localConfigPath, "utf-8"));
|
|
8687
8864
|
if (typeof raw.storeRoot === "string" && raw.storeRoot.trim()) {
|
|
8688
8865
|
return expandPath2(raw.storeRoot, cwd, homeDirectory);
|
|
8689
8866
|
}
|
|
@@ -8747,7 +8924,7 @@ function assertPublishPayloadSize(payload) {
|
|
|
8747
8924
|
}
|
|
8748
8925
|
}
|
|
8749
8926
|
function registerPublishCommand(parent) {
|
|
8750
|
-
parent.command("publish").description("Publish local run evidence to the Tuned Tensor dashboard").argument("[runId]", "Local run id or prefix (defaults to latest completed/failed run)").option("-k, --api-key <key>", "API key (tt_...)").option("-u, --base-url <url>", "API base URL").option("-y, --yes", "Skip confirmation prompt").option("--dry-run", "Show what would be published without uploading").action(async (runId, cmdOpts) => {
|
|
8927
|
+
parent.command("publish").description("Publish local run evidence to the Tuned Tensor dashboard").argument("[runId]", "Local run id or prefix (defaults to latest completed/failed run)").option("-k, --api-key <key>", "API key (tt_...)").option("-u, --base-url <url>", "API base URL").option("-y, --yes", "Skip confirmation prompt").option("--dry-run", "Show what would be published without uploading").option("--allow-unverified", "Publish evidence that cannot be fully verified (older TT versions, unreadable events)").action(async (runId, cmdOpts) => {
|
|
8751
8928
|
const inherited = parent.optsWithGlobals();
|
|
8752
8929
|
const opts = {
|
|
8753
8930
|
apiKey: cmdOpts.apiKey ?? inherited.apiKey,
|
|
@@ -8766,12 +8943,27 @@ function registerPublishCommand(parent) {
|
|
|
8766
8943
|
const report = runReportSchema.parse(rawReport);
|
|
8767
8944
|
const specRecord = await store.getSpec(run.behavior_spec_id);
|
|
8768
8945
|
const exampleCount = report.candidate.results.length || report.baseline.results.length;
|
|
8946
|
+
const audit = await auditRun(store, run.id);
|
|
8947
|
+
if (audit.verdict === "tampered") {
|
|
8948
|
+
throw new Error(
|
|
8949
|
+
`Run ${run.id} evidence does not verify: ${audit.findings.join(" ")} Inspect it with \`tt runs audit ${run.id}\`; tampered runs are not published.`
|
|
8950
|
+
);
|
|
8951
|
+
}
|
|
8769
8952
|
const payload = {
|
|
8770
8953
|
spec: {
|
|
8771
8954
|
id: specRecord.id,
|
|
8772
8955
|
...specRecord.spec
|
|
8773
8956
|
},
|
|
8774
|
-
report
|
|
8957
|
+
report: {
|
|
8958
|
+
...report,
|
|
8959
|
+
audit: {
|
|
8960
|
+
verdict: audit.verdict,
|
|
8961
|
+
findings: audit.findings,
|
|
8962
|
+
event_chain: { status: audit.chain.status, events: audit.chain.events, head_hash: audit.chain.head_hash },
|
|
8963
|
+
report_sha256: audit.report.recorded_sha256,
|
|
8964
|
+
timeline: audit.timeline
|
|
8965
|
+
}
|
|
8966
|
+
}
|
|
8775
8967
|
};
|
|
8776
8968
|
assertPublishPayloadSize(payload);
|
|
8777
8969
|
if (isJsonMode() && cmdOpts.dryRun) {
|
|
@@ -8799,6 +8991,14 @@ function registerPublishCommand(parent) {
|
|
|
8799
8991
|
printWarning(
|
|
8800
8992
|
"Prompts and model outputs from the run report will be uploaded to your Tuned Tensor account."
|
|
8801
8993
|
);
|
|
8994
|
+
if (audit.verdict !== "verified") {
|
|
8995
|
+
printWarning(`Run evidence is unverified: ${audit.findings.join(" ")}`);
|
|
8996
|
+
}
|
|
8997
|
+
}
|
|
8998
|
+
if (audit.verdict !== "verified" && !cmdOpts.allowUnverified && !cmdOpts.dryRun) {
|
|
8999
|
+
throw new Error(
|
|
9000
|
+
`Run ${run.id} evidence cannot be fully verified: ${audit.findings.join(" ")} Review it with \`tt runs audit\`, then pass --allow-unverified to publish it anyway; the dashboard will show it as unverified.`
|
|
9001
|
+
);
|
|
8802
9002
|
}
|
|
8803
9003
|
if (cmdOpts.dryRun) {
|
|
8804
9004
|
if (isJsonMode()) {
|
|
@@ -8843,7 +9043,7 @@ function registerPublishCommand(parent) {
|
|
|
8843
9043
|
}
|
|
8844
9044
|
|
|
8845
9045
|
// src/commands/specs.ts
|
|
8846
|
-
import { readFileSync as
|
|
9046
|
+
import { readFileSync as readFileSync8 } from "fs";
|
|
8847
9047
|
|
|
8848
9048
|
// src/resolve.ts
|
|
8849
9049
|
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
@@ -8947,7 +9147,7 @@ var SpecBodyError = class extends Error {
|
|
|
8947
9147
|
function loadSpecBody(filePath, mode) {
|
|
8948
9148
|
let parsed;
|
|
8949
9149
|
try {
|
|
8950
|
-
parsed = JSON.parse(
|
|
9150
|
+
parsed = JSON.parse(readFileSync8(filePath, "utf-8"));
|
|
8951
9151
|
} catch (e) {
|
|
8952
9152
|
throw new SpecBodyError(
|
|
8953
9153
|
`Could not parse ${filePath}: ${e.message}`
|
|
@@ -9076,7 +9276,7 @@ function registerSpecsCommands(parent) {
|
|
|
9076
9276
|
}
|
|
9077
9277
|
|
|
9078
9278
|
// src/commands/datasets.ts
|
|
9079
|
-
import { existsSync as existsSync6, readFileSync as
|
|
9279
|
+
import { existsSync as existsSync6, readFileSync as readFileSync9, statSync as statSync2 } from "fs";
|
|
9080
9280
|
var DOCUMENT_OCR_MIME_TYPES = /* @__PURE__ */ new Set(["image/png", "image/jpeg", "image/webp"]);
|
|
9081
9281
|
function formatBytes(bytes) {
|
|
9082
9282
|
if (bytes < 1024) return `${bytes} B`;
|
|
@@ -9206,7 +9406,7 @@ function parseDatasetFormat(value) {
|
|
|
9206
9406
|
throw new Error("--format must be one of: jsonl, document_ocr_jsonl");
|
|
9207
9407
|
}
|
|
9208
9408
|
function validateDatasetFile(file, requestedFormat) {
|
|
9209
|
-
const lines =
|
|
9409
|
+
const lines = readFileSync9(file, "utf8").split(/\r?\n/);
|
|
9210
9410
|
const errors = [];
|
|
9211
9411
|
let rowCount = 0;
|
|
9212
9412
|
let detectedFormat = null;
|
|
@@ -9338,7 +9538,7 @@ function registerDatasetsCommands(parent) {
|
|
|
9338
9538
|
}
|
|
9339
9539
|
const format = validateDatasetFile(file, parseDatasetFormat(cmdOpts.format));
|
|
9340
9540
|
const name = cmdOpts.name || file.split("/").pop().replace(/\.jsonl?$/, "");
|
|
9341
|
-
const fileBytes =
|
|
9541
|
+
const fileBytes = readFileSync9(file);
|
|
9342
9542
|
const uploadUrl = await post(
|
|
9343
9543
|
"/datasets/upload-url",
|
|
9344
9544
|
{
|
|
@@ -9383,7 +9583,7 @@ function registerDatasetsCommands(parent) {
|
|
|
9383
9583
|
}
|
|
9384
9584
|
|
|
9385
9585
|
// src/commands/label.ts
|
|
9386
|
-
import { existsSync as existsSync7, readFileSync as
|
|
9586
|
+
import { existsSync as existsSync7, readFileSync as readFileSync10, statSync as statSync3 } from "fs";
|
|
9387
9587
|
function formatCents2(cents) {
|
|
9388
9588
|
return `$${(cents / 100).toFixed(2)}`;
|
|
9389
9589
|
}
|
|
@@ -9427,7 +9627,7 @@ function validateUnlabeledFile(file, inputColumn) {
|
|
|
9427
9627
|
"CSV uploads need --input-column <name> to say which column holds the input text."
|
|
9428
9628
|
);
|
|
9429
9629
|
}
|
|
9430
|
-
const firstLine =
|
|
9630
|
+
const firstLine = readFileSync10(file, "utf8").split(/\r?\n/, 1)[0] ?? "";
|
|
9431
9631
|
const columns = parseCsvHeader(firstLine);
|
|
9432
9632
|
if (!columns.includes(inputColumn)) {
|
|
9433
9633
|
throw new Error(
|
|
@@ -9439,7 +9639,7 @@ function validateUnlabeledFile(file, inputColumn) {
|
|
|
9439
9639
|
if (!lower.endsWith(".jsonl") && !lower.endsWith(".json")) {
|
|
9440
9640
|
throw new Error("Labeling source file must be .jsonl or .csv");
|
|
9441
9641
|
}
|
|
9442
|
-
const lines =
|
|
9642
|
+
const lines = readFileSync10(file, "utf8").split(/\r?\n/);
|
|
9443
9643
|
const errors = [];
|
|
9444
9644
|
let rowCount = 0;
|
|
9445
9645
|
for (const [index, rawLine] of lines.entries()) {
|
|
@@ -9562,7 +9762,7 @@ function registerLabelCommands(parent) {
|
|
|
9562
9762
|
const { format } = validateUnlabeledFile(file, cmdOpts.inputColumn);
|
|
9563
9763
|
const specId = await resolveSpecId(cmdOpts.spec, opts);
|
|
9564
9764
|
const name = cmdOpts.name || file.split("/").pop().replace(/\.(jsonl|json|csv)$/, "");
|
|
9565
|
-
const fileBytes =
|
|
9765
|
+
const fileBytes = readFileSync10(file);
|
|
9566
9766
|
const contentType = format === "csv" ? "text/csv" : "application/jsonl";
|
|
9567
9767
|
const { data: uploadUrl } = await post(
|
|
9568
9768
|
"/labeling-jobs/upload-url",
|
|
@@ -9735,7 +9935,7 @@ function registerLabelCommands(parent) {
|
|
|
9735
9935
|
printError("Provide --output <text> or --file <path>.");
|
|
9736
9936
|
process.exit(1);
|
|
9737
9937
|
}
|
|
9738
|
-
const output = cmdOpts.output ??
|
|
9938
|
+
const output = cmdOpts.output ?? readFileSync10(cmdOpts.file, "utf8");
|
|
9739
9939
|
const jobId = await resolveLabelingJobId(id, opts);
|
|
9740
9940
|
const indexes = parseIndexList(cmdOpts.row);
|
|
9741
9941
|
const rowIds = await resolveRowIds(jobId, indexes, opts);
|
|
@@ -10225,7 +10425,7 @@ import {
|
|
|
10225
10425
|
statSync as statSync4,
|
|
10226
10426
|
createWriteStream,
|
|
10227
10427
|
unlinkSync,
|
|
10228
|
-
readFileSync as
|
|
10428
|
+
readFileSync as readFileSync12,
|
|
10229
10429
|
writeFileSync as writeFileSync5,
|
|
10230
10430
|
readdirSync,
|
|
10231
10431
|
rmSync
|
|
@@ -10236,7 +10436,7 @@ import { Readable, Transform } from "stream";
|
|
|
10236
10436
|
import { pipeline } from "stream/promises";
|
|
10237
10437
|
|
|
10238
10438
|
// src/commands/init.ts
|
|
10239
|
-
import { existsSync as existsSync8, readFileSync as
|
|
10439
|
+
import { existsSync as existsSync8, readFileSync as readFileSync11, writeFileSync as writeFileSync4 } from "fs";
|
|
10240
10440
|
import { resolve as resolve10 } from "path";
|
|
10241
10441
|
var DEFAULT_SPEC_FILE2 = "tunedtensor.json";
|
|
10242
10442
|
function loadSpec(filePath) {
|
|
@@ -10248,7 +10448,7 @@ Run \`tt init\` to create one.`
|
|
|
10248
10448
|
);
|
|
10249
10449
|
process.exit(1);
|
|
10250
10450
|
}
|
|
10251
|
-
const raw = JSON.parse(
|
|
10451
|
+
const raw = JSON.parse(readFileSync11(resolved, "utf-8"));
|
|
10252
10452
|
return raw;
|
|
10253
10453
|
}
|
|
10254
10454
|
|
|
@@ -11462,7 +11662,7 @@ function findSpecPath(explicitPath, modelPath) {
|
|
|
11462
11662
|
return null;
|
|
11463
11663
|
}
|
|
11464
11664
|
function loadSystemPromptFromSpec(specPath) {
|
|
11465
|
-
const spec = JSON.parse(
|
|
11665
|
+
const spec = JSON.parse(readFileSync12(specPath, "utf8"));
|
|
11466
11666
|
return buildSystemPrompt(spec);
|
|
11467
11667
|
}
|
|
11468
11668
|
function loadJsonSchemaForServe(schemaPath) {
|
|
@@ -11471,7 +11671,7 @@ function loadJsonSchemaForServe(schemaPath) {
|
|
|
11471
11671
|
throw new Error(`JSON schema file not found: ${schemaPath}`);
|
|
11472
11672
|
}
|
|
11473
11673
|
try {
|
|
11474
|
-
const schema = JSON.parse(
|
|
11674
|
+
const schema = JSON.parse(readFileSync12(resolved, "utf8"));
|
|
11475
11675
|
return JSON.stringify(schema);
|
|
11476
11676
|
} catch (err) {
|
|
11477
11677
|
throw new Error(`JSON schema file is not valid JSON: ${schemaPath}`);
|
|
@@ -12099,10 +12299,10 @@ function registerModelsCommands(parent) {
|
|
|
12099
12299
|
}
|
|
12100
12300
|
|
|
12101
12301
|
// src/commands/push.ts
|
|
12102
|
-
import { readFileSync as
|
|
12302
|
+
import { readFileSync as readFileSync13, writeFileSync as writeFileSync6 } from "fs";
|
|
12103
12303
|
import { resolve as resolve12 } from "path";
|
|
12104
12304
|
function persistRemoteId(filePath, id) {
|
|
12105
|
-
const raw = JSON.parse(
|
|
12305
|
+
const raw = JSON.parse(readFileSync13(filePath, "utf-8"));
|
|
12106
12306
|
raw.id = id;
|
|
12107
12307
|
writeFileSync6(filePath, JSON.stringify(raw, null, 2) + "\n");
|
|
12108
12308
|
}
|
|
@@ -12630,7 +12830,7 @@ async function runCli(version, runtime = {}) {
|
|
|
12630
12830
|
}
|
|
12631
12831
|
|
|
12632
12832
|
// src/index.ts
|
|
12633
|
-
runCli("0.
|
|
12833
|
+
runCli("0.22.0").catch((err) => {
|
|
12634
12834
|
reportError(err);
|
|
12635
12835
|
process.exit(1);
|
|
12636
12836
|
});
|