@datename/fastcode-termux 0.1.6-beta → 0.1.6

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.
Files changed (246) hide show
  1. package/README.md +6 -24
  2. package/dist/agent/guards.d.ts +0 -8
  3. package/dist/agent/guards.js +0 -195
  4. package/dist/agent/protocol.js +1 -4
  5. package/dist/agent/tools.d.ts +1 -3
  6. package/dist/agent/tools.js +377 -2
  7. package/dist/app.js +103 -335
  8. package/dist/cli.js +311 -362
  9. package/dist/commands/index.js +0 -22
  10. package/dist/commands/login.d.ts +2 -4
  11. package/dist/commands/login.js +10 -12
  12. package/dist/commands/logout.js +16 -8
  13. package/dist/commands/model.d.ts +0 -13
  14. package/dist/commands/model.js +22 -42
  15. package/dist/commands/provider.d.ts +0 -13
  16. package/dist/commands/provider.js +9 -20
  17. package/dist/commands/whoami.js +5 -6
  18. package/dist/config/store.d.ts +12 -32
  19. package/dist/config/store.js +65 -117
  20. package/dist/config/trust.d.ts +8 -21
  21. package/dist/config/trust.js +13 -99
  22. package/dist/lib/diagnostics.d.ts +4 -29
  23. package/dist/lib/diagnostics.js +4 -60
  24. package/dist/lib/http.d.ts +1 -11
  25. package/dist/lib/http.js +4 -62
  26. package/dist/providers/anthropic.d.ts +0 -1
  27. package/dist/providers/anthropic.js +0 -12
  28. package/dist/providers/custom.d.ts +0 -9
  29. package/dist/providers/deepseek.d.ts +0 -10
  30. package/dist/providers/deepseek.js +1 -2
  31. package/dist/providers/google.d.ts +0 -9
  32. package/dist/providers/groq.d.ts +0 -10
  33. package/dist/providers/groq.js +1 -2
  34. package/dist/providers/index.d.ts +201 -10
  35. package/dist/providers/index.js +0 -30
  36. package/dist/providers/mistral.d.ts +0 -10
  37. package/dist/providers/mistral.js +1 -2
  38. package/dist/providers/moonshot.d.ts +0 -10
  39. package/dist/providers/moonshot.js +1 -2
  40. package/dist/providers/ollama.d.ts +0 -9
  41. package/dist/providers/openai.d.ts +0 -10
  42. package/dist/providers/openai.js +1 -2
  43. package/dist/providers/openaiCompatible.d.ts +0 -9
  44. package/dist/providers/openaiCompatible.js +10 -58
  45. package/dist/providers/openrouter.d.ts +0 -10
  46. package/dist/providers/openrouter.js +1 -2
  47. package/dist/providers/qwen.d.ts +0 -10
  48. package/dist/providers/qwen.js +1 -2
  49. package/dist/providers/xai.d.ts +0 -10
  50. package/dist/providers/xai.js +1 -2
  51. package/dist/providers/zhipu.d.ts +0 -10
  52. package/dist/providers/zhipu.js +1 -2
  53. package/dist/session/log.d.ts +12 -35
  54. package/dist/session/log.js +10 -206
  55. package/dist/types.d.ts +1 -60
  56. package/dist/ui/Message.d.ts +7 -1
  57. package/dist/ui/Message.js +2 -13
  58. package/dist/ui/Prompt.d.ts +2 -1
  59. package/dist/ui/Prompt.js +2 -2
  60. package/dist/ui/Spinner.js +5 -11
  61. package/dist/ui/StatusBar.d.ts +1 -2
  62. package/dist/ui/StatusBar.js +5 -6
  63. package/package.json +1 -1
  64. package/src/agent/guards.ts +0 -196
  65. package/src/agent/protocol.ts +1 -4
  66. package/src/agent/tools.ts +377 -3
  67. package/src/app.ts +103 -335
  68. package/src/cli.ts +3 -30
  69. package/src/commands/index.ts +0 -22
  70. package/src/commands/login.ts +10 -12
  71. package/src/commands/logout.ts +16 -8
  72. package/src/commands/model.ts +22 -42
  73. package/src/commands/provider.ts +9 -20
  74. package/src/commands/whoami.ts +5 -6
  75. package/src/config/store.ts +69 -122
  76. package/src/config/trust.ts +21 -137
  77. package/src/lib/diagnostics.ts +4 -60
  78. package/src/lib/http.ts +4 -66
  79. package/src/providers/anthropic.ts +1 -13
  80. package/src/providers/deepseek.ts +1 -2
  81. package/src/providers/groq.ts +1 -2
  82. package/src/providers/index.ts +1 -32
  83. package/src/providers/mistral.ts +1 -2
  84. package/src/providers/moonshot.ts +1 -2
  85. package/src/providers/openai.ts +1 -2
  86. package/src/providers/openaiCompatible.ts +10 -58
  87. package/src/providers/openrouter.ts +1 -2
  88. package/src/providers/qwen.ts +1 -2
  89. package/src/providers/xai.ts +1 -2
  90. package/src/providers/zhipu.ts +1 -2
  91. package/src/session/log.ts +28 -267
  92. package/src/types.ts +1 -63
  93. package/src/ui/Message.ts +2 -13
  94. package/src/ui/Prompt.ts +2 -2
  95. package/src/ui/Spinner.ts +5 -11
  96. package/src/ui/StatusBar.ts +5 -6
  97. package/dist/agent/approval.d.ts +0 -50
  98. package/dist/agent/approval.js +0 -7
  99. package/dist/agent/compaction.d.ts +0 -39
  100. package/dist/agent/compaction.js +0 -227
  101. package/dist/agent/context.d.ts +0 -29
  102. package/dist/agent/context.js +0 -62
  103. package/dist/agent/ignore.d.ts +0 -11
  104. package/dist/agent/ignore.js +0 -129
  105. package/dist/agent/process-tree.d.ts +0 -2
  106. package/dist/agent/process-tree.js +0 -31
  107. package/dist/agent/protocol-mode.d.ts +0 -6
  108. package/dist/agent/protocol-mode.js +0 -51
  109. package/dist/agent/registry.d.ts +0 -17
  110. package/dist/agent/registry.js +0 -90
  111. package/dist/agent/runner.d.ts +0 -106
  112. package/dist/agent/runner.js +0 -352
  113. package/dist/agent/shell-session.d.ts +0 -37
  114. package/dist/agent/shell-session.js +0 -400
  115. package/dist/agent/stream.d.ts +0 -29
  116. package/dist/agent/stream.js +0 -103
  117. package/dist/agent/tool-schemas.d.ts +0 -2
  118. package/dist/agent/tool-schemas.js +0 -63
  119. package/dist/agent/tools/append_file.d.ts +0 -2
  120. package/dist/agent/tools/append_file.js +0 -26
  121. package/dist/agent/tools/apply_patch.d.ts +0 -10
  122. package/dist/agent/tools/apply_patch.js +0 -52
  123. package/dist/agent/tools/copy_file.d.ts +0 -2
  124. package/dist/agent/tools/copy_file.js +0 -30
  125. package/dist/agent/tools/delete_file.d.ts +0 -2
  126. package/dist/agent/tools/delete_file.js +0 -24
  127. package/dist/agent/tools/grep.d.ts +0 -2
  128. package/dist/agent/tools/grep.js +0 -23
  129. package/dist/agent/tools/index.d.ts +0 -2
  130. package/dist/agent/tools/index.js +0 -32
  131. package/dist/agent/tools/list_files.d.ts +0 -2
  132. package/dist/agent/tools/list_files.js +0 -17
  133. package/dist/agent/tools/make_dir.d.ts +0 -2
  134. package/dist/agent/tools/make_dir.js +0 -24
  135. package/dist/agent/tools/move_path.d.ts +0 -2
  136. package/dist/agent/tools/move_path.js +0 -47
  137. package/dist/agent/tools/paths.d.ts +0 -7
  138. package/dist/agent/tools/paths.js +0 -84
  139. package/dist/agent/tools/pwd.d.ts +0 -2
  140. package/dist/agent/tools/pwd.js +0 -10
  141. package/dist/agent/tools/read_file.d.ts +0 -2
  142. package/dist/agent/tools/read_file.js +0 -21
  143. package/dist/agent/tools/read_many.d.ts +0 -2
  144. package/dist/agent/tools/read_many.js +0 -25
  145. package/dist/agent/tools/readers.d.ts +0 -6
  146. package/dist/agent/tools/readers.js +0 -216
  147. package/dist/agent/tools/replace_in_file.d.ts +0 -2
  148. package/dist/agent/tools/replace_in_file.js +0 -30
  149. package/dist/agent/tools/shell.d.ts +0 -2
  150. package/dist/agent/tools/shell.js +0 -48
  151. package/dist/agent/tools/stat_path.d.ts +0 -2
  152. package/dist/agent/tools/stat_path.js +0 -31
  153. package/dist/agent/tools/types.d.ts +0 -39
  154. package/dist/agent/tools/types.js +0 -1
  155. package/dist/agent/tools/validate.d.ts +0 -6
  156. package/dist/agent/tools/validate.js +0 -29
  157. package/dist/agent/tools/write_file.d.ts +0 -2
  158. package/dist/agent/tools/write_file.js +0 -26
  159. package/dist/commands/attach.d.ts +0 -9
  160. package/dist/commands/attach.js +0 -15
  161. package/dist/commands/bg.d.ts +0 -7
  162. package/dist/commands/bg.js +0 -9
  163. package/dist/commands/cancel.d.ts +0 -10
  164. package/dist/commands/cancel.js +0 -10
  165. package/dist/commands/compact.d.ts +0 -10
  166. package/dist/commands/compact.js +0 -22
  167. package/dist/commands/context.d.ts +0 -7
  168. package/dist/commands/context.js +0 -24
  169. package/dist/commands/edit.d.ts +0 -10
  170. package/dist/commands/edit.js +0 -36
  171. package/dist/commands/effort.d.ts +0 -25
  172. package/dist/commands/effort.js +0 -48
  173. package/dist/commands/expand.d.ts +0 -10
  174. package/dist/commands/expand.js +0 -8
  175. package/dist/commands/jobs.d.ts +0 -7
  176. package/dist/commands/jobs.js +0 -16
  177. package/dist/commands/kill.d.ts +0 -7
  178. package/dist/commands/kill.js +0 -11
  179. package/dist/commands/steer.d.ts +0 -11
  180. package/dist/commands/steer.js +0 -13
  181. package/dist/lib/model-meta.d.ts +0 -19
  182. package/dist/lib/model-meta.js +0 -113
  183. package/dist/lib/native-tools.d.ts +0 -12
  184. package/dist/lib/native-tools.js +0 -21
  185. package/dist/lib/net.d.ts +0 -33
  186. package/dist/lib/net.js +0 -168
  187. package/dist/patch/apply.d.ts +0 -15
  188. package/dist/patch/apply.js +0 -172
  189. package/dist/patch/parse.d.ts +0 -29
  190. package/dist/patch/parse.js +0 -112
  191. package/dist/patch/plan.d.ts +0 -49
  192. package/dist/patch/plan.js +0 -273
  193. package/dist/session/projection.d.ts +0 -43
  194. package/dist/session/projection.js +0 -257
  195. package/dist/ui/Picker.d.ts +0 -8
  196. package/dist/ui/Picker.js +0 -24
  197. package/src/agent/approval.ts +0 -47
  198. package/src/agent/compaction.ts +0 -276
  199. package/src/agent/context.ts +0 -97
  200. package/src/agent/ignore.ts +0 -147
  201. package/src/agent/process-tree.ts +0 -32
  202. package/src/agent/protocol-mode.ts +0 -59
  203. package/src/agent/registry.ts +0 -98
  204. package/src/agent/runner.ts +0 -443
  205. package/src/agent/shell-session.ts +0 -449
  206. package/src/agent/stream.ts +0 -143
  207. package/src/agent/tool-schemas.ts +0 -67
  208. package/src/agent/tools/append_file.ts +0 -28
  209. package/src/agent/tools/apply_patch.ts +0 -54
  210. package/src/agent/tools/copy_file.ts +0 -32
  211. package/src/agent/tools/delete_file.ts +0 -26
  212. package/src/agent/tools/grep.ts +0 -25
  213. package/src/agent/tools/index.ts +0 -34
  214. package/src/agent/tools/list_files.ts +0 -19
  215. package/src/agent/tools/make_dir.ts +0 -26
  216. package/src/agent/tools/move_path.ts +0 -50
  217. package/src/agent/tools/paths.ts +0 -92
  218. package/src/agent/tools/pwd.ts +0 -12
  219. package/src/agent/tools/read_file.ts +0 -23
  220. package/src/agent/tools/read_many.ts +0 -27
  221. package/src/agent/tools/readers.ts +0 -228
  222. package/src/agent/tools/replace_in_file.ts +0 -32
  223. package/src/agent/tools/shell.ts +0 -53
  224. package/src/agent/tools/stat_path.ts +0 -33
  225. package/src/agent/tools/types.ts +0 -42
  226. package/src/agent/tools/validate.ts +0 -35
  227. package/src/agent/tools/write_file.ts +0 -28
  228. package/src/commands/attach.ts +0 -16
  229. package/src/commands/bg.ts +0 -9
  230. package/src/commands/cancel.ts +0 -10
  231. package/src/commands/compact.ts +0 -23
  232. package/src/commands/context.ts +0 -25
  233. package/src/commands/edit.ts +0 -37
  234. package/src/commands/effort.ts +0 -49
  235. package/src/commands/expand.ts +0 -8
  236. package/src/commands/jobs.ts +0 -17
  237. package/src/commands/kill.ts +0 -12
  238. package/src/commands/steer.ts +0 -13
  239. package/src/lib/model-meta.ts +0 -138
  240. package/src/lib/native-tools.ts +0 -32
  241. package/src/lib/net.ts +0 -204
  242. package/src/patch/apply.ts +0 -194
  243. package/src/patch/parse.ts +0 -131
  244. package/src/patch/plan.ts +0 -317
  245. package/src/session/projection.ts +0 -308
  246. package/src/ui/Picker.ts +0 -24
@@ -7,7 +7,6 @@ import { clearCommand } from "./clear.js";
7
7
  import { exitCommand } from "./exit.js";
8
8
  import { modelCommand } from "./model.js";
9
9
  import { providerCommand } from "./provider.js";
10
- import { effortCommand } from "./effort.js";
11
10
  import { loginCommand } from "./login.js";
12
11
  import { logoutCommand } from "./logout.js";
13
12
  import { skillsCommand } from "./skills.js";
@@ -18,16 +17,6 @@ import { systemCommand } from "./system.js";
18
17
  import { aboutCommand } from "./about.js";
19
18
  import { configCommand } from "./config.js";
20
19
  import { whoamiCommand } from "./whoami.js";
21
- import { contextCommand } from "./context.js";
22
- import { jobsCommand } from "./jobs.js";
23
- import { killCommand } from "./kill.js";
24
- import { cancelCommand } from "./cancel.js";
25
- import { steerCommand } from "./steer.js";
26
- import { compactCommand } from "./compact.js";
27
- import { expandCommand } from "./expand.js";
28
- import { attachCommand } from "./attach.js";
29
- import { bgCommand } from "./bg.js";
30
- import { editCommand } from "./edit.js";
31
20
  export const COMMANDS = [
32
21
  helpCommand,
33
22
  agentCommand,
@@ -38,7 +27,6 @@ export const COMMANDS = [
38
27
  exitCommand,
39
28
  modelCommand,
40
29
  providerCommand,
41
- effortCommand,
42
30
  loginCommand,
43
31
  logoutCommand,
44
32
  skillsCommand,
@@ -49,16 +37,6 @@ export const COMMANDS = [
49
37
  aboutCommand,
50
38
  configCommand,
51
39
  whoamiCommand,
52
- contextCommand,
53
- jobsCommand,
54
- killCommand,
55
- cancelCommand,
56
- steerCommand,
57
- compactCommand,
58
- expandCommand,
59
- attachCommand,
60
- bgCommand,
61
- editCommand,
62
40
  ];
63
41
  export function findCommand(name) {
64
42
  const lower = name.toLowerCase();
@@ -1,8 +1,6 @@
1
1
  /**
2
- * Save a provider-wide key and describe it for the terminal. `model` is kept
3
- * for the `/login provider model key` one-liner and only recorded as the
4
- * credential's origin — the key itself is reused by every model of that
5
- * provider. Shared by the `/login` command and the guided flow in the app.
2
+ * Save a key scoped to one provider + model and describe it for the terminal.
3
+ * Shared by the `/login` command and the guided flow in the app.
6
4
  */
7
5
  export declare function saveScopedKey(providerId: any, providerLabel: any, model: any, key: any): string;
8
6
  export declare const loginCommand: {
@@ -2,10 +2,8 @@ import { getProvider, PROVIDERS } from "../providers/index.js";
2
2
  import { maskKey, setCredential } from "../config/store.js";
3
3
  import { getPaths } from "../config/paths.js";
4
4
  /**
5
- * Save a provider-wide key and describe it for the terminal. `model` is kept
6
- * for the `/login provider model key` one-liner and only recorded as the
7
- * credential's origin — the key itself is reused by every model of that
8
- * provider. Shared by the `/login` command and the guided flow in the app.
5
+ * Save a key scoped to one provider + model and describe it for the terminal.
6
+ * Shared by the `/login` command and the guided flow in the app.
9
7
  */
10
8
  export function saveScopedKey(providerId, providerLabel, model, key) {
11
9
  const trimmed = key.trim();
@@ -14,16 +12,16 @@ export function saveScopedKey(providerId, providerLabel, model, key) {
14
12
  return [
15
13
  "Saved API key",
16
14
  ` provider ${providerLabel} (${providerId})`,
17
- ` scope all ${providerId} models (saved from ${model || "unknown"})`,
15
+ ` model ${model}`,
18
16
  ` key ${maskKey(trimmed)}`,
19
17
  ` stored ${paths.auth} (mode 0600)`,
20
18
  "",
21
- `Remove with /logout ${providerId}`,
19
+ `Remove with /logout ${providerId} ${model}`,
22
20
  ].join("\n");
23
21
  }
24
22
  export const loginCommand = {
25
23
  name: "login",
26
- description: "Bind a provider-wide API key. Usage: /login [provider] [model] [key]",
24
+ description: "Bind an API key to a provider + model. Usage: /login [provider] [model] [key]",
27
25
  run({ args, state, actions }) {
28
26
  if (args.length === 0) {
29
27
  actions.startLogin({});
@@ -38,12 +36,12 @@ export const loginCommand = {
38
36
  }
39
37
  if (args.length === 1) {
40
38
  actions.startLogin({ provider: provider.id });
41
- return { message: `Provider: ${provider.label} (${provider.id}).\nThe key will apply to every model of this provider.` };
39
+ return { message: `Provider: ${provider.label} (${provider.id}).\nNow pick the model this key is for.` };
42
40
  }
43
41
  const model = args[1];
44
42
  if (args.length === 2) {
45
43
  actions.startLogin({ provider: provider.id, model });
46
- return { message: `Provider: ${provider.id} · saved from model: ${model}.\nNow paste the API key (input is masked).` };
44
+ return { message: `Provider: ${provider.id} · model: ${model}.\nNow paste the API key (input is masked).` };
47
45
  }
48
46
  const key = args.slice(2).join(" ");
49
47
  return { message: saveScopedKey(provider.id, provider.label, model, key) };
@@ -52,11 +50,11 @@ export const loginCommand = {
52
50
  function introText(state) {
53
51
  const env = getProvider(state.providerId)?.authEnv?.[0] ?? "PROVIDER_API_KEY";
54
52
  return [
55
- "Bind a provider-wide API key (reused by every model of that provider).",
53
+ "Bind an API key to a specific provider + model.",
56
54
  "",
57
- ` current provider: ${state.providerId}`,
55
+ ` current scope: ${state.providerId} · ${state.model}`,
58
56
  "",
59
- "FastCode will ask for the provider, then optionally a model name, then the key.",
57
+ "FastCode will ask for the provider, then the model, then the key.",
60
58
  " one-liner: /login <provider> <model> <key>",
61
59
  ` or set: export ${env}=<key> (provider-wide, any model)`,
62
60
  ].join("\n");
@@ -8,11 +8,11 @@ export const logoutCommand = {
8
8
  const credentials = listCredentials();
9
9
  if (credentials.length === 0)
10
10
  return { message: "No stored keys. Use /login to add one." };
11
- const lines = ["Stored keys (provider-wide):"];
11
+ const lines = ["Stored keys (provider :: model):"];
12
12
  for (const c of credentials)
13
- lines.push(` ${c.provider} ${maskKey(c.key)}`);
13
+ lines.push(` ${c.provider}::${c.model} ${maskKey(c.key)}`);
14
14
  lines.push("");
15
- lines.push("Remove: /logout <provider>");
15
+ lines.push("Remove: /logout <provider> <model>");
16
16
  lines.push(" /logout <provider> --all");
17
17
  return { message: lines.join("\n") };
18
18
  }
@@ -29,17 +29,25 @@ export const logoutCommand = {
29
29
  };
30
30
  }
31
31
  if (args.length >= 2) {
32
- const ok = removeCredential(provider.id);
32
+ const model = args[1];
33
+ const ok = removeCredential(provider.id, model);
33
34
  return {
34
35
  message: ok
35
- ? `Removed the stored key for ${provider.id} (applies to all its models).`
36
- : `No stored key for ${provider.id}.`,
36
+ ? `Removed stored key for ${provider.id}::${model}.`
37
+ : `No stored key for ${provider.id}::${model}.`,
37
38
  };
38
39
  }
39
40
  const forProvider = listCredentials().filter((c) => c.provider === provider.id);
40
41
  if (forProvider.length === 0)
41
42
  return { message: `No stored key for ${provider.label}.` };
42
- removeCredential(provider.id);
43
- return { message: `Removed the stored key for ${provider.label} (all models).` };
43
+ if (forProvider.length === 1) {
44
+ removeCredential(forProvider[0].provider, forProvider[0].model);
45
+ return { message: `Removed stored key for ${forProvider[0].provider}::${forProvider[0].model}.` };
46
+ }
47
+ const lines = [`${provider.label} has ${forProvider.length} stored keys — pick one to remove:`];
48
+ for (const c of forProvider)
49
+ lines.push(` /logout ${c.provider} ${c.model} (${maskKey(c.key)})`);
50
+ lines.push(` /logout ${provider.id} --all (remove all)`);
51
+ return { message: lines.join("\n") };
44
52
  },
45
53
  };
@@ -7,18 +7,5 @@ export declare const modelCommand: {
7
7
  actions: any;
8
8
  }): Promise<{
9
9
  message: string;
10
- picker?: undefined;
11
- } | {
12
- message: string;
13
- picker: {
14
- title: string;
15
- current: any;
16
- items: {
17
- value: any;
18
- label: any;
19
- hint: string;
20
- }[];
21
- onSelect: (id: any) => void;
22
- };
23
10
  }>;
24
11
  };
@@ -1,50 +1,30 @@
1
- import { getProviderOrThrow, probeProvider } from "../providers/index.js";
1
+ import { getProviderOrThrow } from "../providers/index.js";
2
2
  import { resolveProviderKey } from "../config/store.js";
3
3
  export const modelCommand = {
4
4
  name: "model",
5
- description: "Pick a model interactively, or switch with /model <id>",
5
+ description: "List models for the current provider, or switch model. Usage: /model [id]",
6
6
  async run({ args, state, actions }) {
7
7
  const provider = getProviderOrThrow(state.providerId);
8
- if (args.length > 0) {
9
- const id = args.join(" ");
10
- actions.setModel(id);
11
- return { message: `Model set to ${id}.` };
8
+ if (args.length === 0) {
9
+ const { key } = resolveProviderKey(provider.id, provider.authEnv);
10
+ const models = await provider.listModels(key);
11
+ if (models.length === 0) {
12
+ return { message: `No models available from ${provider.label}.` };
13
+ }
14
+ const lines = [`Models for ${provider.label}:`];
15
+ for (const m of models.slice(0, 50)) {
16
+ const marker = m.id === state.model ? "● " : " ";
17
+ const label = m.label ? ` — ${m.label}` : "";
18
+ lines.push(`${marker}${m.id}${label}`);
19
+ }
20
+ if (models.length > 50)
21
+ lines.push(` … and ${models.length - 50} more.`);
22
+ lines.push("");
23
+ lines.push("Switch with `/model <id>`.");
24
+ return { message: lines.join("\n") };
12
25
  }
13
- const { key } = resolveProviderKey(provider.id, provider.authEnv);
14
- const fetched = await provider.listModels(key).catch(() => []);
15
- const models = dedupe(fetched);
16
- if (models.length === 0) {
17
- return { message: `No models available from ${provider.label}.` };
18
- }
19
- const online = await probeProvider(provider, key);
20
- const list = models.slice(0, 50);
21
- return {
22
- message: `Models for ${provider.label}: ${list.length}${online ? "" : " (offline — showing the built-in list)"}.\n` +
23
- "Use ↑/↓, a number, or Enter to select.",
24
- picker: {
25
- title: `Select model · ${provider.label}${online ? "" : " (offline)"}`,
26
- current: state.model,
27
- items: list.map((m) => ({
28
- value: m.id,
29
- label: m.id,
30
- hint: m.label ? `— ${m.label}` : undefined,
31
- })),
32
- onSelect: (id) => {
33
- actions.setModel(id);
34
- actions.pushSystemMessage(`Model set to ${id}.`);
35
- },
36
- },
37
- };
26
+ const id = args.join(" ");
27
+ actions.setModel(id);
28
+ return { message: `Model set to ${id}.` };
38
29
  },
39
30
  };
40
- function dedupe(models) {
41
- const seen = new Set();
42
- const out = [];
43
- for (const model of models) {
44
- if (!model?.id || seen.has(model.id))
45
- continue;
46
- seen.add(model.id);
47
- out.push(model);
48
- }
49
- return out;
50
- }
@@ -7,18 +7,5 @@ export declare const providerCommand: {
7
7
  state: any;
8
8
  }): {
9
9
  message: string;
10
- picker: {
11
- title: string;
12
- current: any;
13
- items: {
14
- value: string;
15
- label: string;
16
- hint: string;
17
- }[];
18
- onSelect: (id: any) => void;
19
- };
20
- } | {
21
- message: string;
22
- picker?: undefined;
23
10
  };
24
11
  };
@@ -4,26 +4,15 @@ export const providerCommand = {
4
4
  description: "List or switch the active LLM provider. Usage: /provider [id]",
5
5
  run({ args, actions, state }) {
6
6
  if (args.length === 0) {
7
- return {
8
- message: "Select a provider (↑/↓ or a number, Enter to confirm).",
9
- picker: {
10
- title: "Select provider",
11
- current: state.providerId,
12
- items: PROVIDERS.map((p) => ({
13
- value: p.id,
14
- label: `${p.id.padEnd(12)} ${p.label}`,
15
- hint: p.authEnv.length === 0 ? "(no key needed)" : `[${p.authEnv.join(", ")}]`,
16
- })),
17
- onSelect: (id) => {
18
- const next = getProvider(id);
19
- if (!next)
20
- return;
21
- actions.setProvider(next.id);
22
- actions.setModel(next.defaultModel);
23
- actions.pushSystemMessage(`Provider set to ${next.label}. Default model: ${next.defaultModel}.`);
24
- },
25
- },
26
- };
7
+ const lines = ["Available providers:"];
8
+ for (const p of PROVIDERS) {
9
+ const marker = p.id === state.providerId ? "● " : " ";
10
+ const auth = p.authEnv.length === 0 ? "(no key needed)" : `[${p.authEnv.join(", ")}]`;
11
+ lines.push(`${marker}${p.id.padEnd(12)} ${p.label} ${auth}`);
12
+ }
13
+ lines.push("");
14
+ lines.push("Switch with `/provider <id>` (e.g. `/provider openrouter`).");
15
+ return { message: lines.join("\n") };
27
16
  }
28
17
  const target = args[0];
29
18
  const next = getProvider(target);
@@ -10,20 +10,19 @@ export const whoamiCommand = {
10
10
  lines.push(" " + describeLookup(current, resolveApiKey(current.id, state.model, current.authEnv)));
11
11
  const credentials = listCredentials();
12
12
  lines.push("");
13
- lines.push(`Stored keys (${credentials.length}, provider-wide):`);
13
+ lines.push(`Stored keys (${credentials.length}):`);
14
14
  if (credentials.length === 0)
15
15
  lines.push(" (none) — add one with /login");
16
16
  for (const c of credentials) {
17
- const marker = c.provider === state.providerId ? "● " : " ";
18
- const origin = c.model ? ` (originally saved for ${c.model})` : "";
19
- lines.push(`${marker}${c.provider} ${maskKey(c.key)}${origin}`);
17
+ const marker = c.provider === state.providerId && c.model === state.model ? "● " : " ";
18
+ lines.push(`${marker}${c.provider}::${c.model} ${maskKey(c.key)}`);
20
19
  }
21
20
  const legacy = listLegacy();
22
21
  if (legacy.length > 0) {
23
22
  lines.push("");
24
- lines.push("Legacy keys (could not be migrated — re-save with /login):");
23
+ lines.push("Unbound legacy keys (NOT used — re-bind them to a model):");
25
24
  for (const l of legacy)
26
- lines.push(` ${l.provider} ${maskKey(l.key)}`);
25
+ lines.push(` ${l.provider} ${maskKey(l.key)} → /login ${l.provider} <model> <key>`);
27
26
  }
28
27
  const envLines = [];
29
28
  for (const p of PROVIDERS) {
@@ -8,40 +8,20 @@ export declare const DEFAULT_CONFIG: {
8
8
  enabledPlugins: any[];
9
9
  skillsRegistry: string;
10
10
  lifetimeCostUsd: number;
11
- /**
12
- * Extra directories the file tools may read and write outside the project
13
- * root. Relative entries are resolved against the project root; `~/` is
14
- * expanded against the user's home directory.
15
- */
16
- sharedDirs: any[];
17
- /** Maximum agent tool turns before the loop asks the user to continue. */
18
- maxAgentTurns: number;
19
- /** Abort a stream that receives no data for this long (ms). */
20
- requestIdleTimeoutMs: number;
21
- /** Approximate character budget before history compaction kicks in. */
22
- contextBudgetChars: number;
23
- /** Thinking depth: auto = send nothing, provider default. */
24
- reasoningEffort: string;
25
- /** Cached per-provider/model capabilities (native vs pseudo tool calling). */
26
- capabilities: {
27
- toolCalling: {};
28
- };
29
11
  };
30
12
  export interface StoredCredential {
31
13
  provider: string;
32
- /** Model the key was originally saved for (display only; keys are provider-wide). */
33
- model?: string;
14
+ model: string;
34
15
  key: string;
35
16
  addedAt: string;
36
17
  }
37
18
  export interface AuthStore {
38
19
  version: number;
39
- /** Provider-scoped credentials, keyed by provider id. */
20
+ /** Scoped credentials, keyed by `provider::model`. */
40
21
  keys: Record<string, StoredCredential>;
41
- /** Old provider-only keys that could not be migrated (kept for diagnostics). */
22
+ /** Old provider-only keys we refuse to use until the user re-binds them. */
42
23
  legacy: Record<string, string>;
43
24
  }
44
- export declare const AUTH_VERSION = 3;
45
25
  export type KeyLookup = {
46
26
  status: "ok";
47
27
  key: string;
@@ -56,31 +36,31 @@ export type KeyLookup = {
56
36
  };
57
37
  export declare function loadConfig(): any;
58
38
  export declare function saveConfig(cfg: any): void;
59
- /** Composite id used by the legacy v2 format; kept for API compatibility. */
39
+ /** Composite scope id for a provider + model credential. */
60
40
  export declare function scopeId(providerId: any, model: any): string;
61
41
  export declare function loadAuth(): AuthStore;
62
42
  export declare function saveAuth(store: AuthStore): void;
63
- export declare function getCredential(providerId: any, _model?: any): StoredCredential | undefined;
43
+ export declare function getCredential(providerId: any, model: any): StoredCredential | undefined;
64
44
  export declare function listCredentials(): StoredCredential[];
65
45
  export declare function listLegacy(): Array<{
66
46
  provider: string;
67
47
  key: string;
68
48
  }>;
69
49
  export declare function getLegacy(providerId: any): string | undefined;
70
- /** Save/replace the provider-wide credential (drops any legacy key). */
50
+ /** Save/replace the credential for one provider+model scope (drops the legacy key). */
71
51
  export declare function setCredential(providerId: any, model: any, key: any): StoredCredential;
72
- export declare function removeCredential(providerId: any, _model?: any): boolean;
73
- /** Remove the provider-wide credential plus any legacy leftovers. */
52
+ export declare function removeCredential(providerId: any, model: any): boolean;
53
+ /** Remove every credential for a provider (all models) plus its legacy key. */
74
54
  export declare function removeCredentialsForProvider(providerId: any): number;
75
55
  /** Turn a key into a safe terminal echo: `sk-****abcd`. */
76
56
  export declare function maskKey(key: any): string;
77
57
  /**
78
- * Resolve the key to use for a provider:
79
- * 1. the provider-wide credential in auth.json,
58
+ * Resolve the key to use for a specific provider+model:
59
+ * 1. the scoped credential in auth.json (exact provider+model match), then
80
60
  * 2. the provider's environment variable (provider-scoped, any model), and
81
- * 3. a legacy provider-only key that somehow escaped migration.
61
+ * 3. report an "unbound" legacy key instead of using it silently.
82
62
  */
83
- export declare function resolveApiKey(providerId: any, _model: any, envVars: any): KeyLookup;
63
+ export declare function resolveApiKey(providerId: any, model: any, envVars: any): KeyLookup;
84
64
  /** Best-effort key for a provider regardless of model (used to list models). */
85
65
  export declare function resolveProviderKey(providerId: any, envVars: any): {
86
66
  key?: string;