@tuned-tensor/cli 0.13.1-beta.0 → 0.13.1-beta.1

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 CHANGED
@@ -84,7 +84,7 @@ such as `runs list` and `doctor` work immediately. Chat waits until you choose
84
84
  a provider and model from inside the shell:
85
85
 
86
86
  ```text
87
- tt v0.13.1-beta.0
87
+ tt v0.13.1-beta.1
88
88
  agent not configured · workflow model base
89
89
  ctrl+c stop/clear · ctrl+d exit · /help commands · tab complete
90
90
 
@@ -113,7 +113,7 @@ After a model is selected, the banner shows it and ordinary sentences go to
113
113
  the agent:
114
114
 
115
115
  ```text
116
- tt v0.13.1-beta.0
116
+ tt v0.13.1-beta.1
117
117
  agent anthropic/claude-sonnet-4-5 · workflow model base
118
118
  ctrl+c stop/clear · ctrl+d exit · /help commands · tab complete
119
119
 
package/dist/index.js CHANGED
@@ -660,8 +660,8 @@ function getAgentSelection(env = process.env) {
660
660
  }
661
661
 
662
662
  // src/agent-model.ts
663
- function missingProviderAuthMessage(provider) {
664
- return `Provider "${provider}" is not authenticated. Open the tt shell and run /login ${provider} to save a key, then try again.`;
663
+ function missingProviderAuthMessage() {
664
+ return "No API key is saved for the selected model. Run /login, or /model to pick a different one.";
665
665
  }
666
666
  function unknownAgentProviderMessage(provider) {
667
667
  return `Unknown provider "${provider}". Use /login <id> or /model <id>.`;
@@ -676,6 +676,29 @@ function pushSecret(secrets, value) {
676
676
  if (secret.length < MIN_REDACTED_SECRET_LENGTH) return;
677
677
  if (!secrets.includes(secret)) secrets.push(secret);
678
678
  }
679
+ function persistProviderApiKey(provider, apiKey, authPath = getAgentAuthPath()) {
680
+ const key = apiKey.trim();
681
+ if (!key) {
682
+ throw new Error("API key cannot be empty.");
683
+ }
684
+ let stored = {};
685
+ if (existsSync2(authPath)) {
686
+ let parsed;
687
+ try {
688
+ parsed = JSON.parse(readFileSync2(authPath, "utf-8"));
689
+ } catch (error) {
690
+ throw new Error(
691
+ `Failed to read ${authPath}: ${error instanceof Error ? error.message : String(error)}`
692
+ );
693
+ }
694
+ if (!isRecord(parsed)) {
695
+ throw new Error(`Invalid auth.json: expected an object at ${authPath}`);
696
+ }
697
+ stored = parsed;
698
+ }
699
+ stored[provider] = { type: "api_key", key };
700
+ writePrivateJson(authPath, stored);
701
+ }
679
702
  function readStoredProviderSecrets(authPath = getAgentAuthPath()) {
680
703
  if (!existsSync2(authPath)) return [];
681
704
  let parsed;
@@ -700,7 +723,7 @@ function readStoredProviderSecrets(authPath = getAgentAuthPath()) {
700
723
  function resolveAgentModel(runtime, selection) {
701
724
  const resolved = resolveAgentModelDefinition(runtime, selection);
702
725
  if (!runtime.hasConfiguredAuth(selection.provider)) {
703
- throw new Error(missingProviderAuthMessage(selection.provider));
726
+ throw new Error(missingProviderAuthMessage());
704
727
  }
705
728
  return resolved;
706
729
  }
@@ -1970,7 +1993,6 @@ function formatShellStatus(context) {
1970
1993
  }
1971
1994
 
1972
1995
  // src/agent-control.ts
1973
- import { chmodSync as chmodSync3, existsSync as existsSync3 } from "fs";
1974
1996
  var FEATURED_AGENT_PROVIDERS = [
1975
1997
  "openai",
1976
1998
  "openrouter"
@@ -2089,12 +2111,10 @@ async function loginAgentProvider(runtime, provider, apiKey) {
2089
2111
  if (!key) {
2090
2112
  throw new Error("API key cannot be empty.");
2091
2113
  }
2092
- if (typeof runtime.setRuntimeApiKey !== "function") {
2093
- throw new Error("This session cannot store provider credentials.");
2114
+ persistProviderApiKey(choice.id, key);
2115
+ if (typeof runtime.setRuntimeApiKey === "function") {
2116
+ await runtime.setRuntimeApiKey(choice.id, key);
2094
2117
  }
2095
- await runtime.setRuntimeApiKey(choice.id, key);
2096
- const authPath = getAgentAuthPath();
2097
- if (existsSync3(authPath)) chmodSync3(authPath, 384);
2098
2118
  return { provider: choice.id };
2099
2119
  }
2100
2120
  function setAgentModel(runtime, env, provider, model, options = {}) {
@@ -3568,7 +3588,7 @@ ${chalk3.yellow.bold("Approval required")} ${chalk3.dim(action.id.slice(0, 8))}
3568
3588
  import { constants as osConstants } from "os";
3569
3589
  import { randomUUID as randomUUID4 } from "crypto";
3570
3590
  import { spawn } from "child_process";
3571
- import { existsSync as existsSync4 } from "fs";
3591
+ import { existsSync as existsSync3 } from "fs";
3572
3592
  import { fileURLToPath } from "url";
3573
3593
  import {
3574
3594
  readFile as readFile3,
@@ -4388,7 +4408,7 @@ async function projectSpecArguments(originalArgs, cwd) {
4388
4408
  }
4389
4409
  function resolveLocalCliEntrypoint() {
4390
4410
  const entrypoint = fileURLToPath(new URL("./local-runtime.js", import.meta.url));
4391
- if (!existsSync4(entrypoint)) {
4411
+ if (!existsSync3(entrypoint)) {
4392
4412
  throw new Error(
4393
4413
  "The bundled local runtime is missing. Rebuild or reinstall @tuned-tensor/cli."
4394
4414
  );
@@ -4718,7 +4738,7 @@ function registerAgentCommands(parent, options) {
4718
4738
  }
4719
4739
 
4720
4740
  // src/commands/pipeline.ts
4721
- import { existsSync as existsSync5, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
4741
+ import { existsSync as existsSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
4722
4742
  import { resolve as resolve4 } from "path";
4723
4743
  var DEFAULT_PIPELINE_FILE = "tunedtensor.pipeline.json";
4724
4744
  function parseList(value) {
@@ -4729,7 +4749,7 @@ function parseList(value) {
4729
4749
  }
4730
4750
  function loadPipeline(path) {
4731
4751
  const resolved = resolve4(path);
4732
- if (!existsSync5(resolved)) throw new Error(`Pipeline file not found: ${path}. Run \`tt pipeline init\` to create one.`);
4752
+ if (!existsSync4(resolved)) throw new Error(`Pipeline file not found: ${path}. Run \`tt pipeline init\` to create one.`);
4733
4753
  try {
4734
4754
  return JSON.parse(readFileSync4(resolved, "utf8"));
4735
4755
  } catch (error) {
@@ -4748,7 +4768,7 @@ function registerPipelineCommands(parent) {
4748
4768
  const pipeline = parent.command("pipeline").description("Create, validate, inspect, and safely dry-run ordered pipeline recipes");
4749
4769
  pipeline.command("init").description("Write a canonical v1 pipeline recipe").option("-f, --file <path>", "Output file", DEFAULT_PIPELINE_FILE).action((options) => {
4750
4770
  const path = resolve4(options.file);
4751
- if (existsSync5(path)) throw new Error(`Pipeline file already exists: ${options.file}.`);
4771
+ if (existsSync4(path)) throw new Error(`Pipeline file already exists: ${options.file}.`);
4752
4772
  const recipe = canonicalPipeline("local");
4753
4773
  writeFileSync3(path, `${JSON.stringify(recipe, null, 2)}
4754
4774
  `);
@@ -5186,7 +5206,7 @@ async function runCli(version, runtime = {}) {
5186
5206
  }
5187
5207
 
5188
5208
  // src/index.ts
5189
- runCli("0.13.1-beta.0").catch((err) => {
5209
+ runCli("0.13.1-beta.1").catch((err) => {
5190
5210
  reportError(err);
5191
5211
  process.exit(1);
5192
5212
  });