@soyrageagency/docker-mcp 1.1.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.
Files changed (104) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +882 -0
  3. package/dist/ai/credentials.d.ts +72 -0
  4. package/dist/ai/credentials.js +157 -0
  5. package/dist/ai/credentials.js.map +1 -0
  6. package/dist/ai/login.d.ts +22 -0
  7. package/dist/ai/login.js +189 -0
  8. package/dist/ai/login.js.map +1 -0
  9. package/dist/ai/provider.d.ts +29 -0
  10. package/dist/ai/provider.js +113 -0
  11. package/dist/ai/provider.js.map +1 -0
  12. package/dist/assets.d.ts +20 -0
  13. package/dist/assets.js +56 -0
  14. package/dist/assets.js.map +1 -0
  15. package/dist/branding.d.ts +31 -0
  16. package/dist/branding.js +61 -0
  17. package/dist/branding.js.map +1 -0
  18. package/dist/config.d.ts +65 -0
  19. package/dist/config.js +128 -0
  20. package/dist/config.js.map +1 -0
  21. package/dist/docker/client.d.ts +66 -0
  22. package/dist/docker/client.js +161 -0
  23. package/dist/docker/client.js.map +1 -0
  24. package/dist/docker/compose.d.ts +74 -0
  25. package/dist/docker/compose.js +126 -0
  26. package/dist/docker/compose.js.map +1 -0
  27. package/dist/entry.d.ts +15 -0
  28. package/dist/entry.js +33 -0
  29. package/dist/entry.js.map +1 -0
  30. package/dist/index.d.ts +14 -0
  31. package/dist/index.js +100 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/logger.d.ts +25 -0
  34. package/dist/logger.js +68 -0
  35. package/dist/logger.js.map +1 -0
  36. package/dist/panel/index.d.ts +16 -0
  37. package/dist/panel/index.js +53 -0
  38. package/dist/panel/index.js.map +1 -0
  39. package/dist/panel/public/app.js +1004 -0
  40. package/dist/panel/public/index.html +243 -0
  41. package/dist/panel/public/styles.css +428 -0
  42. package/dist/panel/server.d.ts +23 -0
  43. package/dist/panel/server.js +355 -0
  44. package/dist/panel/server.js.map +1 -0
  45. package/dist/panel/service.d.ts +327 -0
  46. package/dist/panel/service.js +1356 -0
  47. package/dist/panel/service.js.map +1 -0
  48. package/dist/plugins.d.ts +50 -0
  49. package/dist/plugins.js +121 -0
  50. package/dist/plugins.js.map +1 -0
  51. package/dist/ragedocker.d.ts +21 -0
  52. package/dist/ragedocker.js +164 -0
  53. package/dist/ragedocker.js.map +1 -0
  54. package/dist/tools/about.d.ts +15 -0
  55. package/dist/tools/about.js +55 -0
  56. package/dist/tools/about.js.map +1 -0
  57. package/dist/tools/compose.d.ts +19 -0
  58. package/dist/tools/compose.js +145 -0
  59. package/dist/tools/compose.js.map +1 -0
  60. package/dist/tools/containers.d.ts +13 -0
  61. package/dist/tools/containers.js +119 -0
  62. package/dist/tools/containers.js.map +1 -0
  63. package/dist/tools/context.d.ts +37 -0
  64. package/dist/tools/context.js +13 -0
  65. package/dist/tools/context.js.map +1 -0
  66. package/dist/tools/images.d.ts +11 -0
  67. package/dist/tools/images.js +38 -0
  68. package/dist/tools/images.js.map +1 -0
  69. package/dist/tools/index.d.ts +15 -0
  70. package/dist/tools/index.js +34 -0
  71. package/dist/tools/index.js.map +1 -0
  72. package/dist/tools/lifecycle.d.ts +16 -0
  73. package/dist/tools/lifecycle.js +165 -0
  74. package/dist/tools/lifecycle.js.map +1 -0
  75. package/dist/tools/logs.d.ts +15 -0
  76. package/dist/tools/logs.js +110 -0
  77. package/dist/tools/logs.js.map +1 -0
  78. package/dist/tools/system.d.ts +14 -0
  79. package/dist/tools/system.js +108 -0
  80. package/dist/tools/system.js.map +1 -0
  81. package/dist/tui/ansi.d.ts +66 -0
  82. package/dist/tui/ansi.js +118 -0
  83. package/dist/tui/ansi.js.map +1 -0
  84. package/dist/tui/app.d.ts +160 -0
  85. package/dist/tui/app.js +1339 -0
  86. package/dist/tui/app.js.map +1 -0
  87. package/dist/tui/box.d.ts +18 -0
  88. package/dist/tui/box.js +38 -0
  89. package/dist/tui/box.js.map +1 -0
  90. package/dist/tui/index.d.ts +19 -0
  91. package/dist/tui/index.js +66 -0
  92. package/dist/tui/index.js.map +1 -0
  93. package/dist/update/channel.d.ts +82 -0
  94. package/dist/update/channel.js +178 -0
  95. package/dist/update/channel.js.map +1 -0
  96. package/dist/updates.json +42 -0
  97. package/dist/utils/format.d.ts +24 -0
  98. package/dist/utils/format.js +69 -0
  99. package/dist/utils/format.js.map +1 -0
  100. package/dist/utils/result.d.ts +35 -0
  101. package/dist/utils/result.js +31 -0
  102. package/dist/utils/result.js.map +1 -0
  103. package/package.json +90 -0
  104. package/scripts/install.mjs +132 -0
@@ -0,0 +1,72 @@
1
+ /**
2
+ * AI credentials — where your Claude / ChatGPT keys live.
3
+ *
4
+ * A company laptop shouldn't have API keys scattered through shell profiles and
5
+ * `.env` files. `ragedocker ia login` walks you through it once and writes a
6
+ * single file at `~/.ragedocker/ai.json`, owner-readable only. Everything else —
7
+ * the TUI copilot, the panel's AI terminal — reads from there.
8
+ *
9
+ * Two slots so a team can keep both a shared work key and a personal one, or a
10
+ * fast cheap model alongside a strong one, and switch between them without
11
+ * re-entering anything: `primary` and `secondary`.
12
+ *
13
+ * Environment variables still win when set (`DOCKER_MCP_AI_*`), so an unattended
14
+ * gateway is configured the way it always was; the file is the interactive path
15
+ * for a human at a terminal.
16
+ *
17
+ * Part of Docker MCP Server.
18
+ * Crafted by SoyRage Agency — https://soyrage.es/
19
+ * MIT licensed (see LICENSE).
20
+ */
21
+ /** Which AI service an account talks to. */
22
+ export type AiProvider = "anthropic" | "openai" | "custom";
23
+ /** One configured AI account. The key is a secret; never log or echo it. */
24
+ export interface AiAccount {
25
+ provider: AiProvider;
26
+ /** API key / bearer token. */
27
+ key: string;
28
+ /** Model id — sensible default per provider when the user just hits enter. */
29
+ model: string;
30
+ /** Base URL. Fixed for the hosted providers; free-form for "custom". */
31
+ endpoint: string;
32
+ /** A human label so `ia list` reads nicely ("work Claude", "my ChatGPT"). */
33
+ label: string;
34
+ }
35
+ /** The two slots plus which one is active. */
36
+ export interface AiConfig {
37
+ active: "primary" | "secondary";
38
+ primary: AiAccount | null;
39
+ secondary: AiAccount | null;
40
+ }
41
+ export type AiSlot = "primary" | "secondary";
42
+ /** The defaults each provider gets when the user doesn't override them. */
43
+ export declare const PROVIDER_DEFAULTS: Record<AiProvider, {
44
+ endpoint: string;
45
+ model: string;
46
+ label: string;
47
+ keyHint: string;
48
+ console: string;
49
+ }>;
50
+ /** The file we read and write. Honours RAGEDOCKER_HOME for tests and CI. */
51
+ export declare function credentialsPath(): string;
52
+ /** Load the stored config. Never throws; a corrupt file reads as empty. */
53
+ export declare function loadCredentials(): AiConfig;
54
+ /** Persist the config, creating the directory and locking the file down. */
55
+ export declare function saveCredentials(config: AiConfig): void;
56
+ /** Fill in the defaults for a provider around a key the user supplied. */
57
+ export declare function buildAccount(provider: AiProvider, key: string, model?: string, endpoint?: string, label?: string): AiAccount;
58
+ /** Write one slot and make it the active one. */
59
+ export declare function setAccount(slot: AiSlot, account: AiAccount): AiConfig;
60
+ /** Switch the active slot (if it has an account). */
61
+ export declare function useSlot(slot: AiSlot): AiConfig;
62
+ /** Remove one slot, or both when none is named. */
63
+ export declare function clearAccount(slot?: AiSlot): AiConfig;
64
+ /**
65
+ * The account the app should use right now.
66
+ *
67
+ * Precedence: an explicit `DOCKER_MCP_AI_*` environment configuration wins (so
68
+ * a server deployment is unchanged), otherwise the active slot from the file.
69
+ */
70
+ export declare function activeAccount(): AiAccount | null;
71
+ /** Mask a key for display — first 6 and last 4, nothing in between. */
72
+ export declare function maskKey(key: string): string;
@@ -0,0 +1,157 @@
1
+ /**
2
+ * AI credentials — where your Claude / ChatGPT keys live.
3
+ *
4
+ * A company laptop shouldn't have API keys scattered through shell profiles and
5
+ * `.env` files. `ragedocker ia login` walks you through it once and writes a
6
+ * single file at `~/.ragedocker/ai.json`, owner-readable only. Everything else —
7
+ * the TUI copilot, the panel's AI terminal — reads from there.
8
+ *
9
+ * Two slots so a team can keep both a shared work key and a personal one, or a
10
+ * fast cheap model alongside a strong one, and switch between them without
11
+ * re-entering anything: `primary` and `secondary`.
12
+ *
13
+ * Environment variables still win when set (`DOCKER_MCP_AI_*`), so an unattended
14
+ * gateway is configured the way it always was; the file is the interactive path
15
+ * for a human at a terminal.
16
+ *
17
+ * Part of Docker MCP Server.
18
+ * Crafted by SoyRage Agency — https://soyrage.es/
19
+ * MIT licensed (see LICENSE).
20
+ */
21
+ import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
22
+ import { homedir } from "node:os";
23
+ import { dirname, join } from "node:path";
24
+ /** The defaults each provider gets when the user doesn't override them. */
25
+ export const PROVIDER_DEFAULTS = {
26
+ anthropic: {
27
+ endpoint: "https://api.anthropic.com",
28
+ model: "claude-opus-5",
29
+ label: "Claude",
30
+ keyHint: "sk-ant-…",
31
+ console: "https://console.anthropic.com/settings/keys",
32
+ },
33
+ openai: {
34
+ endpoint: "https://api.openai.com/v1",
35
+ model: "gpt-4o-mini",
36
+ label: "ChatGPT",
37
+ keyHint: "sk-…",
38
+ console: "https://platform.openai.com/api-keys",
39
+ },
40
+ custom: {
41
+ endpoint: "http://localhost:11434/v1",
42
+ model: "llama3.1",
43
+ label: "Local model",
44
+ keyHint: "(often blank for Ollama / LM Studio)",
45
+ console: "https://ollama.com",
46
+ },
47
+ };
48
+ const EMPTY = { active: "primary", primary: null, secondary: null };
49
+ /** The file we read and write. Honours RAGEDOCKER_HOME for tests and CI. */
50
+ export function credentialsPath() {
51
+ const base = process.env.RAGEDOCKER_HOME?.trim() || join(homedir(), ".ragedocker");
52
+ return join(base, "ai.json");
53
+ }
54
+ /** Load the stored config. Never throws; a corrupt file reads as empty. */
55
+ export function loadCredentials() {
56
+ const path = credentialsPath();
57
+ if (!existsSync(path))
58
+ return { ...EMPTY };
59
+ try {
60
+ const raw = JSON.parse(readFileSync(path, "utf8"));
61
+ return {
62
+ active: raw.active === "secondary" ? "secondary" : "primary",
63
+ primary: normaliseAccount(raw.primary),
64
+ secondary: normaliseAccount(raw.secondary),
65
+ };
66
+ }
67
+ catch {
68
+ return { ...EMPTY };
69
+ }
70
+ }
71
+ /** Persist the config, creating the directory and locking the file down. */
72
+ export function saveCredentials(config) {
73
+ const path = credentialsPath();
74
+ mkdirSync(dirname(path), { recursive: true });
75
+ writeFileSync(path, `${JSON.stringify(config, null, 2)}\n`, "utf8");
76
+ // Keys are secrets: 0600, so no other user on the box can read them.
77
+ try {
78
+ chmodSync(path, 0o600);
79
+ }
80
+ catch { /* Windows / unsupported fs — best effort */ }
81
+ }
82
+ /** Fill in the defaults for a provider around a key the user supplied. */
83
+ export function buildAccount(provider, key, model = "", endpoint = "", label = "") {
84
+ const d = PROVIDER_DEFAULTS[provider];
85
+ return {
86
+ provider,
87
+ key: key.trim(),
88
+ model: model.trim() || d.model,
89
+ endpoint: (endpoint.trim() || d.endpoint).replace(/\/+$/, ""),
90
+ label: label.trim() || d.label,
91
+ };
92
+ }
93
+ /** Write one slot and make it the active one. */
94
+ export function setAccount(slot, account) {
95
+ const config = loadCredentials();
96
+ config[slot] = account;
97
+ config.active = slot;
98
+ saveCredentials(config);
99
+ return config;
100
+ }
101
+ /** Switch the active slot (if it has an account). */
102
+ export function useSlot(slot) {
103
+ const config = loadCredentials();
104
+ if (config[slot]) {
105
+ config.active = slot;
106
+ saveCredentials(config);
107
+ }
108
+ return config;
109
+ }
110
+ /** Remove one slot, or both when none is named. */
111
+ export function clearAccount(slot) {
112
+ const config = loadCredentials();
113
+ if (slot)
114
+ config[slot] = null;
115
+ else {
116
+ config.primary = null;
117
+ config.secondary = null;
118
+ }
119
+ if (!config[config.active])
120
+ config.active = config.primary ? "primary" : "secondary";
121
+ saveCredentials(config);
122
+ return config;
123
+ }
124
+ /**
125
+ * The account the app should use right now.
126
+ *
127
+ * Precedence: an explicit `DOCKER_MCP_AI_*` environment configuration wins (so
128
+ * a server deployment is unchanged), otherwise the active slot from the file.
129
+ */
130
+ export function activeAccount() {
131
+ const envKey = process.env.DOCKER_MCP_AI_KEY?.trim();
132
+ const envEndpoint = process.env.DOCKER_MCP_AI_ENDPOINT?.trim();
133
+ if (envKey || envEndpoint) {
134
+ // The legacy env path is OpenAI-compatible; that's what it always was.
135
+ return buildAccount("openai", envKey ?? "", process.env.DOCKER_MCP_AI_MODEL ?? "", envEndpoint ?? "", "env");
136
+ }
137
+ const config = loadCredentials();
138
+ return config[config.active] ?? config.primary ?? config.secondary;
139
+ }
140
+ /** Mask a key for display — first 6 and last 4, nothing in between. */
141
+ export function maskKey(key) {
142
+ if (!key)
143
+ return "(none)";
144
+ if (key.length <= 12)
145
+ return "•".repeat(key.length);
146
+ return `${key.slice(0, 6)}…${key.slice(-4)}`;
147
+ }
148
+ function normaliseAccount(raw) {
149
+ if (!raw || typeof raw !== "object")
150
+ return null;
151
+ const a = raw;
152
+ if (typeof a.key !== "string" && typeof a.endpoint !== "string")
153
+ return null;
154
+ const provider = a.provider === "anthropic" || a.provider === "custom" ? a.provider : "openai";
155
+ return buildAccount(provider, String(a.key ?? ""), String(a.model ?? ""), String(a.endpoint ?? ""), String(a.label ?? ""));
156
+ }
157
+ //# sourceMappingURL=credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/ai/credentials.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * `ragedocker ia …` — signing in to Claude or ChatGPT from the terminal.
3
+ *
4
+ * ragedocker ia login set up (or replace) your main AI account
5
+ * ragedocker ia relogin re-enter the key for the account in use
6
+ * ragedocker ia secundaria set up a second account to switch to
7
+ * ragedocker ia use <slot> switch between primary and secondary
8
+ * ragedocker ia list show what's configured (keys masked)
9
+ * ragedocker ia test call the model once and report back
10
+ * ragedocker ia logout forget an account
11
+ *
12
+ * A short readline wizard, not a config file to hand-edit: pick the provider,
13
+ * paste the key, accept or change the model, and it verifies the credential
14
+ * before saving so a typo is caught here rather than the first time the copilot
15
+ * is used.
16
+ *
17
+ * Part of Docker MCP Server.
18
+ * Crafted by SoyRage Agency — https://soyrage.es/
19
+ * MIT licensed (see LICENSE).
20
+ */
21
+ /** Entry point dispatched from the launcher. `argv` is everything after `ia`. */
22
+ export declare function runIa(argv: string[]): Promise<void>;
@@ -0,0 +1,189 @@
1
+ /**
2
+ * `ragedocker ia …` — signing in to Claude or ChatGPT from the terminal.
3
+ *
4
+ * ragedocker ia login set up (or replace) your main AI account
5
+ * ragedocker ia relogin re-enter the key for the account in use
6
+ * ragedocker ia secundaria set up a second account to switch to
7
+ * ragedocker ia use <slot> switch between primary and secondary
8
+ * ragedocker ia list show what's configured (keys masked)
9
+ * ragedocker ia test call the model once and report back
10
+ * ragedocker ia logout forget an account
11
+ *
12
+ * A short readline wizard, not a config file to hand-edit: pick the provider,
13
+ * paste the key, accept or change the model, and it verifies the credential
14
+ * before saving so a typo is caught here rather than the first time the copilot
15
+ * is used.
16
+ *
17
+ * Part of Docker MCP Server.
18
+ * Crafted by SoyRage Agency — https://soyrage.es/
19
+ * MIT licensed (see LICENSE).
20
+ */
21
+ import { createInterface } from "node:readline";
22
+ import { color } from "../tui/ansi.js";
23
+ import { BRAND } from "../branding.js";
24
+ import { buildAccount, clearAccount, credentialsPath, loadCredentials, maskKey, PROVIDER_DEFAULTS, setAccount, useSlot, } from "./credentials.js";
25
+ import { verify } from "./provider.js";
26
+ const out = (s = "") => process.stdout.write(s + "\n");
27
+ /** Prompt for a line of input, with an optional default shown in brackets. */
28
+ function ask(rl, question, fallback = "") {
29
+ const suffix = fallback ? color.dim(` [${fallback}]`) : "";
30
+ return new Promise((resolve) => rl.question(` ${question}${suffix} `, (answer) => resolve(answer.trim() || fallback)));
31
+ }
32
+ /** Read an API key without echoing it to the terminal. */
33
+ function askSecret(question) {
34
+ return new Promise((resolve) => {
35
+ const stdin = process.stdin;
36
+ const wasRaw = stdin.isRaw;
37
+ process.stdout.write(` ${question} `);
38
+ let value = "";
39
+ const onData = (chunk) => {
40
+ const s = chunk.toString("utf8");
41
+ if (s === "\r" || s === "\n") {
42
+ stdin.removeListener("data", onData);
43
+ if (stdin.isTTY && !wasRaw)
44
+ stdin.setRawMode(false);
45
+ process.stdout.write("\n");
46
+ resolve(value.trim());
47
+ return;
48
+ }
49
+ if (s === "\x7f" || s === "\b") {
50
+ value = value.slice(0, -1);
51
+ return;
52
+ }
53
+ if (s === "\x03") {
54
+ process.stdout.write("\n");
55
+ process.exit(130);
56
+ }
57
+ // Ignore other control characters; append printable input.
58
+ if (s >= " ")
59
+ value += s;
60
+ };
61
+ if (stdin.isTTY)
62
+ stdin.setRawMode(true);
63
+ stdin.resume();
64
+ stdin.on("data", onData);
65
+ });
66
+ }
67
+ /** Choose a provider by number. */
68
+ async function chooseProvider(rl) {
69
+ out();
70
+ out(` ${color.bold("Which AI?")}`);
71
+ out(` ${color.accent("1")} Claude ${color.dim("(Anthropic — recommended)")}`);
72
+ out(` ${color.accent("2")} ChatGPT ${color.dim("(OpenAI)")}`);
73
+ out(` ${color.accent("3")} Other ${color.dim("(Ollama, LM Studio, any OpenAI-compatible endpoint)")}`);
74
+ const pick = await ask(rl, "Pick 1-3", "1");
75
+ return pick === "2" ? "openai" : pick === "3" ? "custom" : "anthropic";
76
+ }
77
+ /** The shared login flow for a slot. */
78
+ async function runLogin(slot, presetProvider) {
79
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
80
+ try {
81
+ const existing = loadCredentials()[slot];
82
+ const provider = presetProvider ?? (await chooseProvider(rl));
83
+ const d = PROVIDER_DEFAULTS[provider];
84
+ out();
85
+ out(` ${color.gray("Get a key here:")} ${color.brightBlue(d.console)}`);
86
+ const key = await askSecret(`Paste your ${color.bold(d.label)} API key ${color.dim(d.keyHint)}:`);
87
+ if (!key && provider !== "custom") {
88
+ out(`\n ${color.red("✗ No key entered.")}\n`);
89
+ return;
90
+ }
91
+ const endpoint = provider === "custom"
92
+ ? await ask(rl, "Endpoint (OpenAI-compatible base URL)", existing?.endpoint || d.endpoint)
93
+ : d.endpoint;
94
+ const model = await ask(rl, "Model", existing?.model || d.model);
95
+ const label = await ask(rl, "Label (for your own reference)", existing?.label || d.label);
96
+ const account = buildAccount(provider, key, model, endpoint, label);
97
+ out(`\n ${color.gray("Checking the credentials…")}`);
98
+ const check = await verify(account);
99
+ if (!check.ok) {
100
+ out(` ${color.red("✗ " + check.message)}`);
101
+ const anyway = await ask(rl, "Save it anyway? (y/N)", "n");
102
+ if (!/^y/i.test(anyway)) {
103
+ out(`\n ${color.gray("Not saved.")}\n`);
104
+ return;
105
+ }
106
+ }
107
+ else {
108
+ out(` ${color.green("✓ " + account.label + " answered: " + check.message)}`);
109
+ }
110
+ setAccount(slot, account);
111
+ out(`\n ${color.green("✓ Saved")} to ${color.dim(credentialsPath())} as the ${color.bold(slot)} account, and made active.`);
112
+ out(` ${color.gray("The TUI copilot (press")} ${color.accent("a")}${color.gray(") and the panel now use it.")}\n`);
113
+ }
114
+ finally {
115
+ rl.close();
116
+ }
117
+ }
118
+ /** Entry point dispatched from the launcher. `argv` is everything after `ia`. */
119
+ export async function runIa(argv) {
120
+ const sub = (argv[0] || "login").toLowerCase();
121
+ switch (sub) {
122
+ case "login":
123
+ return runLogin("primary");
124
+ case "relogin": {
125
+ const config = loadCredentials();
126
+ const slot = config.active;
127
+ return runLogin(slot, config[slot]?.provider);
128
+ }
129
+ case "secondary":
130
+ case "secundaria":
131
+ return runLogin("secondary");
132
+ case "use":
133
+ case "switch": {
134
+ const target = /^sec/i.test(argv[1] || "") ? "secondary" : "primary";
135
+ const config = useSlot(target);
136
+ if (!config[target])
137
+ out(`\n ${color.yellow("The " + target + " account is empty.")} Set it up with ${color.bold("ragedocker ia " + (target === "secondary" ? "secundaria" : "login"))}.\n`);
138
+ else
139
+ out(`\n ${color.green("✓ Now using the " + target + " account")} (${config[target].label}).\n`);
140
+ return;
141
+ }
142
+ case "list":
143
+ case "status":
144
+ return listAccounts();
145
+ case "test":
146
+ case "check": {
147
+ const config = loadCredentials();
148
+ const account = config[config.active];
149
+ if (!account) {
150
+ out(`\n ${color.yellow("No AI configured.")} Run ${color.bold("ragedocker ia login")}.\n`);
151
+ return;
152
+ }
153
+ out(`\n ${color.gray("Asking " + account.label + " (" + account.model + ")…")}`);
154
+ const check = await verify(account);
155
+ out(check.ok ? ` ${color.green("✓ " + check.message)}\n` : ` ${color.red("✗ " + check.message)}\n`);
156
+ return;
157
+ }
158
+ case "logout":
159
+ case "clear": {
160
+ const which = argv[1] ? (/^sec/i.test(argv[1]) ? "secondary" : "primary") : undefined;
161
+ clearAccount(which);
162
+ out(`\n ${color.green("✓ Forgotten")} ${which ? "the " + which + " account" : "all AI accounts"}.\n`);
163
+ return;
164
+ }
165
+ default:
166
+ out(`\n Unknown: ${color.bold("ia " + sub)}. Try: login · relogin · secundaria · use · list · test · logout\n`);
167
+ }
168
+ }
169
+ function listAccounts() {
170
+ const config = loadCredentials();
171
+ out();
172
+ out(` ${color.accent(color.bold("SOYRAGE"))} ${color.gray("▸")} ${color.bold(BRAND.product)} ${color.gray("· AI accounts")}`);
173
+ out();
174
+ for (const slot of ["primary", "secondary"]) {
175
+ const a = config[slot];
176
+ const active = config.active === slot;
177
+ const marker = active ? color.green("●") : color.gray("○");
178
+ if (!a) {
179
+ out(` ${marker} ${color.bold(slot.padEnd(10))} ${color.dim("(empty)")}`);
180
+ continue;
181
+ }
182
+ out(` ${marker} ${color.bold(slot.padEnd(10))} ${a.label} ${color.gray(a.provider)} ${color.dim(a.model)}`);
183
+ out(` ${color.gray("key")} ${color.dim(maskKey(a.key))} ${color.gray("endpoint")} ${color.dim(a.endpoint)}`);
184
+ }
185
+ out();
186
+ out(` ${color.gray("Switch with")} ${color.bold("ragedocker ia use secondary")}${color.gray(", set up with")} ${color.bold("ragedocker ia login")}${color.gray(".")}`);
187
+ out(` ${color.gray("Stored at")} ${color.dim(credentialsPath())} ${color.gray("(owner-readable only).")}\n`);
188
+ }
189
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/ai/login.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Talking to the model — Claude natively, ChatGPT and friends over the
3
+ * OpenAI-compatible shape.
4
+ *
5
+ * The two APIs differ in exactly the ways that matter here: Anthropic wants the
6
+ * key in `x-api-key` with an `anthropic-version` header and a `system` field
7
+ * beside `messages`, and returns the answer under `content[].text`; the OpenAI
8
+ * shape wants `Authorization: Bearer`, folds the system prompt into the message
9
+ * list, and returns it under `choices[].message.content`. One function per
10
+ * provider keeps each honest rather than pretending one client fits both.
11
+ *
12
+ * Every call has a timeout and turns a non-2xx into a readable error — an AI
13
+ * copilot that hangs is worse than one that says "your key was rejected".
14
+ *
15
+ * Part of Docker MCP Server.
16
+ * Crafted by SoyRage Agency — https://soyrage.es/
17
+ * MIT licensed (see LICENSE).
18
+ */
19
+ import type { AiAccount } from "./credentials.js";
20
+ /** Ask the configured model a single question. Returns its plain-text reply. */
21
+ export declare function chat(account: AiAccount, system: string, user: string, timeoutMs?: number): Promise<string>;
22
+ /**
23
+ * A quick credential check for `ia login` / `doctor`: one tiny prompt, and a
24
+ * boolean plus the model's echo. Never throws — a failure is a message.
25
+ */
26
+ export declare function verify(account: AiAccount): Promise<{
27
+ ok: boolean;
28
+ message: string;
29
+ }>;
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Talking to the model — Claude natively, ChatGPT and friends over the
3
+ * OpenAI-compatible shape.
4
+ *
5
+ * The two APIs differ in exactly the ways that matter here: Anthropic wants the
6
+ * key in `x-api-key` with an `anthropic-version` header and a `system` field
7
+ * beside `messages`, and returns the answer under `content[].text`; the OpenAI
8
+ * shape wants `Authorization: Bearer`, folds the system prompt into the message
9
+ * list, and returns it under `choices[].message.content`. One function per
10
+ * provider keeps each honest rather than pretending one client fits both.
11
+ *
12
+ * Every call has a timeout and turns a non-2xx into a readable error — an AI
13
+ * copilot that hangs is worse than one that says "your key was rejected".
14
+ *
15
+ * Part of Docker MCP Server.
16
+ * Crafted by SoyRage Agency — https://soyrage.es/
17
+ * MIT licensed (see LICENSE).
18
+ */
19
+ /** Ask the configured model a single question. Returns its plain-text reply. */
20
+ export async function chat(account, system, user, timeoutMs = 20000) {
21
+ const controller = new AbortController();
22
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
23
+ try {
24
+ return account.provider === "anthropic"
25
+ ? await anthropic(account, system, user, controller.signal)
26
+ : await openai(account, system, user, controller.signal);
27
+ }
28
+ catch (err) {
29
+ if (err.name === "AbortError")
30
+ throw new Error("The AI request timed out.");
31
+ throw err;
32
+ }
33
+ finally {
34
+ clearTimeout(timer);
35
+ }
36
+ }
37
+ /** Claude, via the native Messages API. */
38
+ async function anthropic(account, system, user, signal) {
39
+ const res = await fetch(`${account.endpoint.replace(/\/+$/, "")}/v1/messages`, {
40
+ method: "POST",
41
+ signal,
42
+ headers: {
43
+ "content-type": "application/json",
44
+ "x-api-key": account.key,
45
+ "anthropic-version": "2023-06-01",
46
+ },
47
+ body: JSON.stringify({
48
+ model: account.model,
49
+ max_tokens: 1024,
50
+ system,
51
+ messages: [{ role: "user", content: user }],
52
+ }),
53
+ });
54
+ if (!res.ok)
55
+ throw new Error(await describeError(res, "Claude"));
56
+ const data = (await res.json());
57
+ // The answer is the concatenation of the text blocks; thinking blocks, if any,
58
+ // carry no text under the default display and drop out naturally.
59
+ return (data.content ?? []).filter((b) => b.type === "text" || b.text).map((b) => b.text ?? "").join("").trim();
60
+ }
61
+ /** ChatGPT / Ollama / LM Studio / anything OpenAI-compatible. */
62
+ async function openai(account, system, user, signal) {
63
+ const res = await fetch(`${account.endpoint.replace(/\/+$/, "")}/chat/completions`, {
64
+ method: "POST",
65
+ signal,
66
+ headers: {
67
+ "content-type": "application/json",
68
+ ...(account.key ? { authorization: `Bearer ${account.key}` } : {}),
69
+ },
70
+ body: JSON.stringify({
71
+ model: account.model,
72
+ temperature: 0.1,
73
+ messages: [
74
+ { role: "system", content: system },
75
+ { role: "user", content: user },
76
+ ],
77
+ }),
78
+ });
79
+ if (!res.ok)
80
+ throw new Error(await describeError(res, account.label || "the AI endpoint"));
81
+ const data = (await res.json());
82
+ return (data.choices?.[0]?.message?.content ?? "").trim();
83
+ }
84
+ /** Turn a failed HTTP response into the provider's own words where possible. */
85
+ async function describeError(res, who) {
86
+ let detail = "";
87
+ try {
88
+ const body = (await res.json());
89
+ detail = typeof body.error === "string" ? body.error : body.error?.message ?? "";
90
+ }
91
+ catch { /* non-JSON error body */ }
92
+ if (res.status === 401 || res.status === 403)
93
+ return `${who} rejected the API key (${res.status}). Re-run "ragedocker ia relogin".`;
94
+ if (res.status === 404)
95
+ return `${who} has no such model or endpoint (404). Check the model name.`;
96
+ if (res.status === 429)
97
+ return `${who} is rate-limiting the request (429). Try again shortly.`;
98
+ return `${who} returned ${res.status}${detail ? `: ${detail}` : ""}.`;
99
+ }
100
+ /**
101
+ * A quick credential check for `ia login` / `doctor`: one tiny prompt, and a
102
+ * boolean plus the model's echo. Never throws — a failure is a message.
103
+ */
104
+ export async function verify(account) {
105
+ try {
106
+ const reply = await chat(account, "You are a health check. Reply with exactly: OK", "ping", 12000);
107
+ return { ok: true, message: reply.slice(0, 40) || "(empty reply)" };
108
+ }
109
+ catch (err) {
110
+ return { ok: false, message: err.message };
111
+ }
112
+ }
113
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/ai/provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Bundled-asset access — works the same whether we're running from `dist/` on a
3
+ * machine with Node, or as a single-file standalone binary (Node SEA) with no
4
+ * Node installed at all.
5
+ *
6
+ * When packaged, the panel's static files and the update channel are baked into
7
+ * the executable and read from the SEA blob; otherwise they're read from disk.
8
+ * Callers pass both an asset key and the on-disk path, and get back whichever is
9
+ * available — so the same code path serves both builds.
10
+ *
11
+ * Part of Docker MCP Server.
12
+ * Crafted by SoyRage Agency — https://soyrage.es/
13
+ * MIT licensed (see LICENSE).
14
+ */
15
+ /** True when running as an injected single-file executable. */
16
+ export declare function isPackaged(): boolean;
17
+ /** Read a bundled asset as a Buffer: from the SEA blob when packaged, else disk. */
18
+ export declare function readAssetBuffer(key: string, diskPath: string): Buffer;
19
+ /** Read a bundled asset as UTF-8 text. Returns null if it can't be read. */
20
+ export declare function readAssetText(key: string, diskPath: string): string | null;