@datename/fastcode-termux 0.0.0-stage → 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 (197) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +400 -2
  3. package/bin/fastcode.mjs +59 -0
  4. package/dist/agent/guards.d.ts +35 -0
  5. package/dist/agent/guards.js +74 -0
  6. package/dist/agent/limits.d.ts +24 -0
  7. package/dist/agent/limits.js +71 -0
  8. package/dist/agent/protocol.d.ts +4 -0
  9. package/dist/agent/protocol.js +126 -0
  10. package/dist/agent/tools.d.ts +1 -0
  11. package/dist/agent/tools.js +377 -0
  12. package/dist/app.d.ts +4 -0
  13. package/dist/app.js +476 -0
  14. package/dist/cli.d.ts +1 -0
  15. package/dist/cli.js +518 -0
  16. package/dist/commands/about.d.ts +8 -0
  17. package/dist/commands/about.js +16 -0
  18. package/dist/commands/agent.d.ts +11 -0
  19. package/dist/commands/agent.js +18 -0
  20. package/dist/commands/clear.d.ts +11 -0
  21. package/dist/commands/clear.js +9 -0
  22. package/dist/commands/config.d.ts +7 -0
  23. package/dist/commands/config.js +24 -0
  24. package/dist/commands/cost.d.ts +9 -0
  25. package/dist/commands/cost.js +13 -0
  26. package/dist/commands/cwd.d.ts +7 -0
  27. package/dist/commands/cwd.js +7 -0
  28. package/dist/commands/exit.d.ts +9 -0
  29. package/dist/commands/exit.js +8 -0
  30. package/dist/commands/help.d.ts +6 -0
  31. package/dist/commands/help.js +18 -0
  32. package/dist/commands/index.d.ts +9 -0
  33. package/dist/commands/index.js +58 -0
  34. package/dist/commands/login.d.ts +16 -0
  35. package/dist/commands/login.js +61 -0
  36. package/dist/commands/logout.d.ts +9 -0
  37. package/dist/commands/logout.js +53 -0
  38. package/dist/commands/model.d.ts +11 -0
  39. package/dist/commands/model.js +30 -0
  40. package/dist/commands/plugin.d.ts +11 -0
  41. package/dist/commands/plugin.js +74 -0
  42. package/dist/commands/provider.d.ts +11 -0
  43. package/dist/commands/provider.js +28 -0
  44. package/dist/commands/reset.d.ts +9 -0
  45. package/dist/commands/reset.js +13 -0
  46. package/dist/commands/skills.d.ts +11 -0
  47. package/dist/commands/skills.js +106 -0
  48. package/dist/commands/system.d.ts +11 -0
  49. package/dist/commands/system.js +20 -0
  50. package/dist/commands/theme.d.ts +11 -0
  51. package/dist/commands/theme.js +22 -0
  52. package/dist/commands/tools.d.ts +7 -0
  53. package/dist/commands/tools.js +29 -0
  54. package/dist/commands/whoami.d.ts +9 -0
  55. package/dist/commands/whoami.js +51 -0
  56. package/dist/config/paths.d.ts +4 -0
  57. package/dist/config/paths.js +59 -0
  58. package/dist/config/store.d.ts +69 -0
  59. package/dist/config/store.js +208 -0
  60. package/dist/config/themes.d.ts +73 -0
  61. package/dist/config/themes.js +77 -0
  62. package/dist/config/trust.d.ts +9 -0
  63. package/dist/config/trust.js +67 -0
  64. package/dist/index.d.ts +1 -0
  65. package/dist/index.js +31 -0
  66. package/dist/lib/diagnostics.d.ts +41 -0
  67. package/dist/lib/diagnostics.js +139 -0
  68. package/dist/lib/http.d.ts +13 -0
  69. package/dist/lib/http.js +70 -0
  70. package/dist/lib/markdown.d.ts +1 -0
  71. package/dist/lib/markdown.js +32 -0
  72. package/dist/lib/pkg.d.ts +5 -0
  73. package/dist/lib/pkg.js +27 -0
  74. package/dist/lib/platform.d.ts +7 -0
  75. package/dist/lib/platform.js +57 -0
  76. package/dist/lib/startup.d.ts +6 -0
  77. package/dist/lib/startup.js +25 -0
  78. package/dist/lib/uiMode.d.ts +2 -0
  79. package/dist/lib/uiMode.js +7 -0
  80. package/dist/plugins/manager.d.ts +23 -0
  81. package/dist/plugins/manager.js +101 -0
  82. package/dist/providers/anthropic.d.ts +21 -0
  83. package/dist/providers/anthropic.js +107 -0
  84. package/dist/providers/custom.d.ts +24 -0
  85. package/dist/providers/custom.js +25 -0
  86. package/dist/providers/deepseek.d.ts +24 -0
  87. package/dist/providers/deepseek.js +15 -0
  88. package/dist/providers/google.d.ts +24 -0
  89. package/dist/providers/google.js +19 -0
  90. package/dist/providers/groq.d.ts +24 -0
  91. package/dist/providers/groq.js +20 -0
  92. package/dist/providers/index.d.ts +201 -0
  93. package/dist/providers/index.js +37 -0
  94. package/dist/providers/mistral.d.ts +24 -0
  95. package/dist/providers/mistral.js +19 -0
  96. package/dist/providers/moonshot.d.ts +24 -0
  97. package/dist/providers/moonshot.js +22 -0
  98. package/dist/providers/ollama.d.ts +24 -0
  99. package/dist/providers/ollama.js +22 -0
  100. package/dist/providers/openai.d.ts +24 -0
  101. package/dist/providers/openai.js +25 -0
  102. package/dist/providers/openaiCompatible.d.ts +17 -0
  103. package/dist/providers/openaiCompatible.js +110 -0
  104. package/dist/providers/openrouter.d.ts +24 -0
  105. package/dist/providers/openrouter.js +26 -0
  106. package/dist/providers/qwen.d.ts +24 -0
  107. package/dist/providers/qwen.js +23 -0
  108. package/dist/providers/xai.d.ts +24 -0
  109. package/dist/providers/xai.js +18 -0
  110. package/dist/providers/zhipu.d.ts +24 -0
  111. package/dist/providers/zhipu.js +23 -0
  112. package/dist/session/log.d.ts +29 -0
  113. package/dist/session/log.js +135 -0
  114. package/dist/skills/manager.d.ts +18 -0
  115. package/dist/skills/manager.js +201 -0
  116. package/dist/skills/parser.d.ts +18 -0
  117. package/dist/skills/parser.js +65 -0
  118. package/dist/types.d.ts +146 -0
  119. package/dist/types.js +1 -0
  120. package/dist/ui/Banner.d.ts +5 -0
  121. package/dist/ui/Banner.js +65 -0
  122. package/dist/ui/Message.d.ts +7 -0
  123. package/dist/ui/Message.js +13 -0
  124. package/dist/ui/Prompt.d.ts +10 -0
  125. package/dist/ui/Prompt.js +38 -0
  126. package/dist/ui/Spinner.d.ts +5 -0
  127. package/dist/ui/Spinner.js +33 -0
  128. package/dist/ui/StatusBar.d.ts +10 -0
  129. package/dist/ui/StatusBar.js +19 -0
  130. package/dist/ui/TrustGate.d.ts +5 -0
  131. package/dist/ui/TrustGate.js +26 -0
  132. package/package.json +96 -4
  133. package/src/agent/guards.ts +74 -0
  134. package/src/agent/limits.ts +71 -0
  135. package/src/agent/protocol.ts +126 -0
  136. package/src/agent/tools.ts +377 -0
  137. package/src/app.ts +476 -0
  138. package/src/cli.ts +308 -0
  139. package/src/commands/about.ts +16 -0
  140. package/src/commands/agent.ts +18 -0
  141. package/src/commands/clear.ts +9 -0
  142. package/src/commands/config.ts +24 -0
  143. package/src/commands/cost.ts +13 -0
  144. package/src/commands/cwd.ts +7 -0
  145. package/src/commands/exit.ts +8 -0
  146. package/src/commands/help.ts +18 -0
  147. package/src/commands/index.ts +58 -0
  148. package/src/commands/login.ts +61 -0
  149. package/src/commands/logout.ts +53 -0
  150. package/src/commands/model.ts +30 -0
  151. package/src/commands/plugin.ts +74 -0
  152. package/src/commands/provider.ts +28 -0
  153. package/src/commands/reset.ts +13 -0
  154. package/src/commands/skills.ts +106 -0
  155. package/src/commands/system.ts +20 -0
  156. package/src/commands/theme.ts +22 -0
  157. package/src/commands/tools.ts +29 -0
  158. package/src/commands/whoami.ts +51 -0
  159. package/src/config/paths.ts +59 -0
  160. package/src/config/store.ts +240 -0
  161. package/src/config/themes.ts +77 -0
  162. package/src/config/trust.ts +67 -0
  163. package/src/index.ts +31 -0
  164. package/src/lib/diagnostics.ts +139 -0
  165. package/src/lib/http.ts +70 -0
  166. package/src/lib/markdown.ts +32 -0
  167. package/src/lib/pkg.ts +35 -0
  168. package/src/lib/platform.ts +57 -0
  169. package/src/lib/startup.ts +25 -0
  170. package/src/lib/uiMode.ts +7 -0
  171. package/src/plugins/manager.ts +101 -0
  172. package/src/providers/anthropic.ts +107 -0
  173. package/src/providers/custom.ts +25 -0
  174. package/src/providers/deepseek.ts +15 -0
  175. package/src/providers/google.ts +19 -0
  176. package/src/providers/groq.ts +20 -0
  177. package/src/providers/index.ts +37 -0
  178. package/src/providers/mistral.ts +19 -0
  179. package/src/providers/moonshot.ts +22 -0
  180. package/src/providers/ollama.ts +22 -0
  181. package/src/providers/openai.ts +25 -0
  182. package/src/providers/openaiCompatible.ts +110 -0
  183. package/src/providers/openrouter.ts +26 -0
  184. package/src/providers/qwen.ts +23 -0
  185. package/src/providers/xai.ts +18 -0
  186. package/src/providers/zhipu.ts +23 -0
  187. package/src/session/log.ts +135 -0
  188. package/src/skills/manager.ts +201 -0
  189. package/src/skills/parser.ts +65 -0
  190. package/src/types.ts +143 -0
  191. package/src/ui/Banner.ts +68 -0
  192. package/src/ui/Message.ts +13 -0
  193. package/src/ui/Prompt.ts +38 -0
  194. package/src/ui/Spinner.ts +33 -0
  195. package/src/ui/StatusBar.ts +19 -0
  196. package/src/ui/TrustGate.ts +26 -0
  197. package/tsconfig.json +22 -0
@@ -0,0 +1,8 @@
1
+ export declare const aboutCommand: {
2
+ name: string;
3
+ description: string;
4
+ aliases: string[];
5
+ run(): {
6
+ message: string;
7
+ };
8
+ };
@@ -0,0 +1,16 @@
1
+ import { platformLabel } from "../lib/platform.js";
2
+ export const aboutCommand = {
3
+ name: "about",
4
+ description: "Show version, platform, and links.",
5
+ aliases: ["version"],
6
+ run() {
7
+ const lines = [
8
+ `FastCode — multi-LLM TUI coding assistant`,
9
+ `Platform: ${platformLabel()} • Node ${process.version}`,
10
+ ``,
11
+ `GitHub: https://github.com/dateName/fastcode-termux`,
12
+ `Skills: https://skillshub.wtf`,
13
+ ];
14
+ return { message: lines.join("\n") };
15
+ },
16
+ };
@@ -0,0 +1,11 @@
1
+ export declare const agentCommand: {
2
+ name: string;
3
+ description: string;
4
+ run({ args, state, actions }: {
5
+ args: any;
6
+ state: any;
7
+ actions: any;
8
+ }): {
9
+ message: string;
10
+ };
11
+ };
@@ -0,0 +1,18 @@
1
+ export const agentCommand = {
2
+ name: "agent",
3
+ description: "Toggle coding-agent tools. Usage: /agent [on|off|status]",
4
+ run({ args, state, actions }) {
5
+ const sub = (args[0] ?? "status").toLowerCase();
6
+ if (sub === "on") {
7
+ actions.setAgentMode(true);
8
+ return { message: "Agent mode enabled. FastCode can run shell and file tools." };
9
+ }
10
+ if (sub === "off") {
11
+ actions.setAgentMode(false);
12
+ return { message: "Agent mode disabled." };
13
+ }
14
+ return {
15
+ message: `Agent mode: ${state.agentMode ? "on" : "off"}\n\nUse /agent on to let FastCode run local shell and file tools.`,
16
+ };
17
+ },
18
+ };
@@ -0,0 +1,11 @@
1
+ export declare const clearCommand: {
2
+ name: string;
3
+ description: string;
4
+ aliases: string[];
5
+ run({ actions }: {
6
+ actions: any;
7
+ }): {
8
+ message: string;
9
+ silent: boolean;
10
+ };
11
+ };
@@ -0,0 +1,9 @@
1
+ export const clearCommand = {
2
+ name: "clear",
3
+ description: "Clear the current conversation history.",
4
+ aliases: ["cls"],
5
+ run({ actions }) {
6
+ actions.clearHistory();
7
+ return { message: "Conversation cleared.", silent: false };
8
+ },
9
+ };
@@ -0,0 +1,7 @@
1
+ export declare const configCommand: {
2
+ name: string;
3
+ description: string;
4
+ run(): {
5
+ message: string;
6
+ };
7
+ };
@@ -0,0 +1,24 @@
1
+ import { loadConfig } from "../config/store.js";
2
+ import { getPaths } from "../config/paths.js";
3
+ export const configCommand = {
4
+ name: "config",
5
+ description: "Print effective config & paths.",
6
+ run() {
7
+ const cfg = loadConfig();
8
+ const paths = getPaths();
9
+ const lines = [
10
+ "Config (~/.fastcode/config.json):",
11
+ JSON.stringify(cfg, null, 2),
12
+ "",
13
+ "Paths:",
14
+ ` root: ${paths.root}`,
15
+ ` config: ${paths.config}`,
16
+ ` auth: ${paths.auth}`,
17
+ ` skills: ${paths.skills}`,
18
+ ` plugins: ${paths.plugins}`,
19
+ ` cache: ${paths.cache}`,
20
+ ` sessions: ${paths.sessions}`,
21
+ ];
22
+ return { message: lines.join("\n") };
23
+ },
24
+ };
@@ -0,0 +1,9 @@
1
+ export declare const costCommand: {
2
+ name: string;
3
+ description: string;
4
+ run({ state }: {
5
+ state: any;
6
+ }): {
7
+ message: string;
8
+ };
9
+ };
@@ -0,0 +1,13 @@
1
+ export const costCommand = {
2
+ name: "cost",
3
+ description: "Show approximate cost & token usage for this session.",
4
+ run({ state }) {
5
+ const lines = [
6
+ `Provider: ${state.providerId}`,
7
+ `Model: ${state.model}`,
8
+ `Tokens: ${state.totalInputTokens} in / ${state.totalOutputTokens} out`,
9
+ `Cost: ~$${state.totalCostUsd.toFixed(4)}`,
10
+ ];
11
+ return { message: lines.join("\n") };
12
+ },
13
+ };
@@ -0,0 +1,7 @@
1
+ export declare const cwdCommand: {
2
+ name: string;
3
+ description: string;
4
+ run(): {
5
+ message: string;
6
+ };
7
+ };
@@ -0,0 +1,7 @@
1
+ export const cwdCommand = {
2
+ name: "cwd",
3
+ description: "Show the current agent sandbox root.",
4
+ run() {
5
+ return { message: `Agent sandbox root:\n\n\`${process.cwd()}\`` };
6
+ },
7
+ };
@@ -0,0 +1,9 @@
1
+ export declare const exitCommand: {
2
+ name: string;
3
+ description: string;
4
+ aliases: string[];
5
+ run(): {
6
+ message: string;
7
+ quit: boolean;
8
+ };
9
+ };
@@ -0,0 +1,8 @@
1
+ export const exitCommand = {
2
+ name: "exit",
3
+ description: "Quit FastCode.",
4
+ aliases: ["quit", "q"],
5
+ run() {
6
+ return { message: "Bye!", quit: true };
7
+ },
8
+ };
@@ -0,0 +1,6 @@
1
+ export declare const helpCommand: {
2
+ name: string;
3
+ description: string;
4
+ aliases: string[];
5
+ run(): any;
6
+ };
@@ -0,0 +1,18 @@
1
+ import { COMMANDS } from "./index.js";
2
+ export const helpCommand = {
3
+ name: "help",
4
+ description: "Show all available slash commands.",
5
+ aliases: ["h", "?"],
6
+ run() {
7
+ const visible = COMMANDS.filter((c) => !c.hidden);
8
+ const widest = Math.max(...visible.map((c) => c.name.length));
9
+ const lines = [
10
+ "Slash commands — type any of these at the prompt:",
11
+ "",
12
+ ...visible.map((c) => ` /${c.name.padEnd(widest)} ${c.description}`),
13
+ "",
14
+ "Press ESC to cancel a streaming response. Press Ctrl+C twice to quit.",
15
+ ];
16
+ return { message: lines.join("\n") };
17
+ },
18
+ };
@@ -0,0 +1,9 @@
1
+ export declare const COMMANDS: any;
2
+ export declare function findCommand(name: any): any;
3
+ /** Parse a raw input string. Returns undefined if it's not a slash command. */
4
+ export declare function parseSlash(input: any): {
5
+ name: any;
6
+ args: any;
7
+ raw: any;
8
+ };
9
+ export declare function runCommand(cmd: any, ctx: any): Promise<any>;
@@ -0,0 +1,58 @@
1
+ import { agentCommand } from "./agent.js";
2
+ import { cwdCommand } from "./cwd.js";
3
+ import { helpCommand } from "./help.js";
4
+ import { pluginCommand } from "./plugin.js";
5
+ import { toolsCommand } from "./tools.js";
6
+ import { clearCommand } from "./clear.js";
7
+ import { exitCommand } from "./exit.js";
8
+ import { modelCommand } from "./model.js";
9
+ import { providerCommand } from "./provider.js";
10
+ import { loginCommand } from "./login.js";
11
+ import { logoutCommand } from "./logout.js";
12
+ import { skillsCommand } from "./skills.js";
13
+ import { themeCommand } from "./theme.js";
14
+ import { costCommand } from "./cost.js";
15
+ import { resetCommand } from "./reset.js";
16
+ import { systemCommand } from "./system.js";
17
+ import { aboutCommand } from "./about.js";
18
+ import { configCommand } from "./config.js";
19
+ import { whoamiCommand } from "./whoami.js";
20
+ export const COMMANDS = [
21
+ helpCommand,
22
+ agentCommand,
23
+ toolsCommand,
24
+ cwdCommand,
25
+ pluginCommand,
26
+ clearCommand,
27
+ exitCommand,
28
+ modelCommand,
29
+ providerCommand,
30
+ loginCommand,
31
+ logoutCommand,
32
+ skillsCommand,
33
+ themeCommand,
34
+ costCommand,
35
+ resetCommand,
36
+ systemCommand,
37
+ aboutCommand,
38
+ configCommand,
39
+ whoamiCommand,
40
+ ];
41
+ export function findCommand(name) {
42
+ const lower = name.toLowerCase();
43
+ return COMMANDS.find((c) => c.name === lower || (c.aliases ?? []).includes(lower));
44
+ }
45
+ /** Parse a raw input string. Returns undefined if it's not a slash command. */
46
+ export function parseSlash(input) {
47
+ const trimmed = input.trim();
48
+ if (!trimmed.startsWith("/"))
49
+ return undefined;
50
+ const tokens = trimmed.slice(1).split(/\s+/);
51
+ const head = tokens.shift() ?? "";
52
+ if (!head)
53
+ return undefined;
54
+ return { name: head, args: tokens, raw: trimmed };
55
+ }
56
+ export async function runCommand(cmd, ctx) {
57
+ return await cmd.run(ctx);
58
+ }
@@ -0,0 +1,16 @@
1
+ /**
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.
4
+ */
5
+ export declare function saveScopedKey(providerId: any, providerLabel: any, model: any, key: any): string;
6
+ export declare const loginCommand: {
7
+ name: string;
8
+ description: string;
9
+ run({ args, state, actions }: {
10
+ args: any;
11
+ state: any;
12
+ actions: any;
13
+ }): {
14
+ message: string;
15
+ };
16
+ };
@@ -0,0 +1,61 @@
1
+ import { getProvider, PROVIDERS } from "../providers/index.js";
2
+ import { maskKey, setCredential } from "../config/store.js";
3
+ import { getPaths } from "../config/paths.js";
4
+ /**
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.
7
+ */
8
+ export function saveScopedKey(providerId, providerLabel, model, key) {
9
+ const trimmed = key.trim();
10
+ setCredential(providerId, model, trimmed);
11
+ const paths = getPaths();
12
+ return [
13
+ "Saved API key",
14
+ ` provider ${providerLabel} (${providerId})`,
15
+ ` model ${model}`,
16
+ ` key ${maskKey(trimmed)}`,
17
+ ` stored ${paths.auth} (mode 0600)`,
18
+ "",
19
+ `Remove with /logout ${providerId} ${model}`,
20
+ ].join("\n");
21
+ }
22
+ export const loginCommand = {
23
+ name: "login",
24
+ description: "Bind an API key to a provider + model. Usage: /login [provider] [model] [key]",
25
+ run({ args, state, actions }) {
26
+ if (args.length === 0) {
27
+ actions.startLogin({});
28
+ return { message: introText(state) };
29
+ }
30
+ const provider = getProvider(args[0]);
31
+ if (!provider) {
32
+ return { message: `Unknown provider "${args[0]}". Available: ${PROVIDERS.map((p) => p.id).join(", ")}` };
33
+ }
34
+ if (provider.authEnv.length === 0) {
35
+ return { message: `${provider.label} doesn't require an API key. Nothing to save.` };
36
+ }
37
+ if (args.length === 1) {
38
+ actions.startLogin({ provider: provider.id });
39
+ return { message: `Provider: ${provider.label} (${provider.id}).\nNow pick the model this key is for.` };
40
+ }
41
+ const model = args[1];
42
+ if (args.length === 2) {
43
+ actions.startLogin({ provider: provider.id, model });
44
+ return { message: `Provider: ${provider.id} · model: ${model}.\nNow paste the API key (input is masked).` };
45
+ }
46
+ const key = args.slice(2).join(" ");
47
+ return { message: saveScopedKey(provider.id, provider.label, model, key) };
48
+ },
49
+ };
50
+ function introText(state) {
51
+ const env = getProvider(state.providerId)?.authEnv?.[0] ?? "PROVIDER_API_KEY";
52
+ return [
53
+ "Bind an API key to a specific provider + model.",
54
+ "",
55
+ ` current scope: ${state.providerId} · ${state.model}`,
56
+ "",
57
+ "FastCode will ask for the provider, then the model, then the key.",
58
+ " one-liner: /login <provider> <model> <key>",
59
+ ` or set: export ${env}=<key> (provider-wide, any model)`,
60
+ ].join("\n");
61
+ }
@@ -0,0 +1,9 @@
1
+ export declare const logoutCommand: {
2
+ name: string;
3
+ description: string;
4
+ run({ args }: {
5
+ args: any;
6
+ }): {
7
+ message: string;
8
+ };
9
+ };
@@ -0,0 +1,53 @@
1
+ import { getProvider } from "../providers/index.js";
2
+ import { listCredentials, maskKey, removeCredential, removeCredentialsForProvider } from "../config/store.js";
3
+ export const logoutCommand = {
4
+ name: "logout",
5
+ description: "Remove a stored API key. Usage: /logout <provider> [model] | /logout <provider> --all",
6
+ run({ args }) {
7
+ if (args.length === 0) {
8
+ const credentials = listCredentials();
9
+ if (credentials.length === 0)
10
+ return { message: "No stored keys. Use /login to add one." };
11
+ const lines = ["Stored keys (provider :: model):"];
12
+ for (const c of credentials)
13
+ lines.push(` ${c.provider}::${c.model} ${maskKey(c.key)}`);
14
+ lines.push("");
15
+ lines.push("Remove: /logout <provider> <model>");
16
+ lines.push(" /logout <provider> --all");
17
+ return { message: lines.join("\n") };
18
+ }
19
+ const id = args[0];
20
+ const provider = getProvider(id);
21
+ if (!provider)
22
+ return { message: `Unknown provider "${id}".` };
23
+ if (args.includes("--all")) {
24
+ const removed = removeCredentialsForProvider(provider.id);
25
+ return {
26
+ message: removed > 0
27
+ ? `Removed ${removed} stored key(s) for ${provider.label}.`
28
+ : `No stored key for ${provider.label}.`,
29
+ };
30
+ }
31
+ if (args.length >= 2) {
32
+ const model = args[1];
33
+ const ok = removeCredential(provider.id, model);
34
+ return {
35
+ message: ok
36
+ ? `Removed stored key for ${provider.id}::${model}.`
37
+ : `No stored key for ${provider.id}::${model}.`,
38
+ };
39
+ }
40
+ const forProvider = listCredentials().filter((c) => c.provider === provider.id);
41
+ if (forProvider.length === 0)
42
+ return { message: `No stored key for ${provider.label}.` };
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") };
52
+ },
53
+ };
@@ -0,0 +1,11 @@
1
+ export declare const modelCommand: {
2
+ name: string;
3
+ description: string;
4
+ run({ args, state, actions }: {
5
+ args: any;
6
+ state: any;
7
+ actions: any;
8
+ }): Promise<{
9
+ message: string;
10
+ }>;
11
+ };
@@ -0,0 +1,30 @@
1
+ import { getProviderOrThrow } from "../providers/index.js";
2
+ import { resolveProviderKey } from "../config/store.js";
3
+ export const modelCommand = {
4
+ name: "model",
5
+ description: "List models for the current provider, or switch model. Usage: /model [id]",
6
+ async run({ args, state, actions }) {
7
+ const provider = getProviderOrThrow(state.providerId);
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") };
25
+ }
26
+ const id = args.join(" ");
27
+ actions.setModel(id);
28
+ return { message: `Model set to ${id}.` };
29
+ },
30
+ };
@@ -0,0 +1,11 @@
1
+ export declare const pluginCommand: {
2
+ name: string;
3
+ description: string;
4
+ run({ args, state, actions }: {
5
+ args: any;
6
+ state: any;
7
+ actions: any;
8
+ }): {
9
+ message: string;
10
+ };
11
+ };
@@ -0,0 +1,74 @@
1
+ import { getPlugin, importPlugin, listInstalledPlugins, removePlugin, } from "../plugins/manager.js";
2
+ export const pluginCommand = {
3
+ name: "plugin",
4
+ description: "Manage always-active plugin packs. Usage: /plugin [list|import|enable|disable|remove|info]",
5
+ run({ args, state, actions }) {
6
+ const sub = (args[0] ?? "list").toLowerCase();
7
+ if (sub === "list") {
8
+ const plugins = listInstalledPlugins();
9
+ if (plugins.length === 0)
10
+ return { message: "No plugins installed. Import one with /plugin import <path> [name]." };
11
+ return {
12
+ message: [
13
+ "Installed plugins:",
14
+ "",
15
+ ...plugins.map((p) => {
16
+ const enabled = state.enabledPlugins.includes(p.name) ? "●" : " ";
17
+ return `${enabled} ${p.name} — ${p.description}`;
18
+ }),
19
+ ].join("\n"),
20
+ };
21
+ }
22
+ if (sub === "import") {
23
+ const source = args[1];
24
+ if (!source)
25
+ return { message: "Usage: /plugin import <folder-path> [name]" };
26
+ const plugin = importPlugin(source, args[2]);
27
+ actions.enablePlugin(plugin.name);
28
+ return { message: `Imported and enabled plugin ${plugin.name}.` };
29
+ }
30
+ if (sub === "enable") {
31
+ const name = args[1];
32
+ if (!name)
33
+ return { message: "Usage: /plugin enable <name>" };
34
+ const plugin = getPlugin(name);
35
+ if (!plugin)
36
+ return { message: `Plugin not found: ${name}` };
37
+ actions.enablePlugin(plugin.name);
38
+ return { message: `Enabled plugin ${plugin.name}.` };
39
+ }
40
+ if (sub === "disable") {
41
+ const name = args[1];
42
+ if (!name)
43
+ return { message: "Usage: /plugin disable <name>" };
44
+ actions.disablePlugin(name);
45
+ return { message: `Disabled plugin ${name}.` };
46
+ }
47
+ if (sub === "remove") {
48
+ const name = args[1];
49
+ if (!name)
50
+ return { message: "Usage: /plugin remove <name>" };
51
+ actions.disablePlugin(name);
52
+ return { message: removePlugin(name) ? `Removed plugin ${name}.` : `Plugin not found: ${name}` };
53
+ }
54
+ if (sub === "info") {
55
+ const name = args[1];
56
+ if (!name)
57
+ return { message: "Usage: /plugin info <name>" };
58
+ const plugin = getPlugin(name);
59
+ if (!plugin)
60
+ return { message: `Plugin not found: ${name}` };
61
+ return {
62
+ message: [
63
+ `Plugin: ${plugin.name}`,
64
+ `Path: ${plugin.path}`,
65
+ `Description: ${plugin.description}`,
66
+ `Skills: ${plugin.skills.map((s) => s.name).join(", ") || "none"}`,
67
+ "",
68
+ plugin.body.slice(0, 4000),
69
+ ].join("\n"),
70
+ };
71
+ }
72
+ return { message: "Usage: /plugin [list|import|enable|disable|remove|info]" };
73
+ },
74
+ };
@@ -0,0 +1,11 @@
1
+ export declare const providerCommand: {
2
+ name: string;
3
+ description: string;
4
+ run({ args, actions, state }: {
5
+ args: any;
6
+ actions: any;
7
+ state: any;
8
+ }): {
9
+ message: string;
10
+ };
11
+ };
@@ -0,0 +1,28 @@
1
+ import { PROVIDERS, getProvider } from "../providers/index.js";
2
+ export const providerCommand = {
3
+ name: "provider",
4
+ description: "List or switch the active LLM provider. Usage: /provider [id]",
5
+ run({ args, actions, state }) {
6
+ if (args.length === 0) {
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") };
16
+ }
17
+ const target = args[0];
18
+ const next = getProvider(target);
19
+ if (!next) {
20
+ return { message: `Unknown provider "${target}". Try /provider with no args.` };
21
+ }
22
+ actions.setProvider(next.id);
23
+ actions.setModel(next.defaultModel);
24
+ return {
25
+ message: `Provider set to ${next.label}. Default model: ${next.defaultModel}. Use /model to change.`,
26
+ };
27
+ },
28
+ };
@@ -0,0 +1,9 @@
1
+ export declare const resetCommand: {
2
+ name: string;
3
+ description: string;
4
+ run({ actions }: {
5
+ actions: any;
6
+ }): {
7
+ message: string;
8
+ };
9
+ };
@@ -0,0 +1,13 @@
1
+ import { DEFAULT_CONFIG, saveConfig } from "../config/store.js";
2
+ export const resetCommand = {
3
+ name: "reset",
4
+ description: "Reset config to defaults (does not touch API keys).",
5
+ run({ actions }) {
6
+ saveConfig({ ...DEFAULT_CONFIG });
7
+ actions.setProvider(DEFAULT_CONFIG.providerId);
8
+ actions.setModel(DEFAULT_CONFIG.model);
9
+ actions.setTheme(DEFAULT_CONFIG.theme);
10
+ actions.setSystemPrompt(DEFAULT_CONFIG.systemPrompt);
11
+ return { message: "Config reset to defaults." };
12
+ },
13
+ };
@@ -0,0 +1,11 @@
1
+ export declare const skillsCommand: {
2
+ name: string;
3
+ description: string;
4
+ run({ args, state, actions }: {
5
+ args: any;
6
+ state: any;
7
+ actions: any;
8
+ }): Promise<{
9
+ message: string;
10
+ }>;
11
+ };