steroids-cli 0.15.3 → 0.15.5

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 (144) hide show
  1. package/dist/commands/ai-proxy.d.ts +6 -0
  2. package/dist/commands/ai-proxy.d.ts.map +1 -0
  3. package/dist/commands/ai-proxy.js +79 -0
  4. package/dist/commands/ai-proxy.js.map +1 -0
  5. package/dist/commands/ai-run.d.ts.map +1 -1
  6. package/dist/commands/ai-run.js +10 -7
  7. package/dist/commands/ai-run.js.map +1 -1
  8. package/dist/commands/ai.d.ts.map +1 -1
  9. package/dist/commands/ai.js +5 -0
  10. package/dist/commands/ai.js.map +1 -1
  11. package/dist/commands/completion.js +2 -1
  12. package/dist/commands/completion.js.map +1 -1
  13. package/dist/commands/features.d.ts +5 -0
  14. package/dist/commands/features.d.ts.map +1 -0
  15. package/dist/commands/features.js +255 -0
  16. package/dist/commands/features.js.map +1 -0
  17. package/dist/commands/llm-content.d.ts +1 -1
  18. package/dist/commands/llm-content.d.ts.map +1 -1
  19. package/dist/commands/llm-content.js +36 -6
  20. package/dist/commands/llm-content.js.map +1 -1
  21. package/dist/commands/llm.d.ts.map +1 -1
  22. package/dist/commands/llm.js +1 -0
  23. package/dist/commands/llm.js.map +1 -1
  24. package/dist/commands/web.d.ts.map +1 -1
  25. package/dist/commands/web.js +22 -3
  26. package/dist/commands/web.js.map +1 -1
  27. package/dist/database/queries.d.ts.map +1 -1
  28. package/dist/database/queries.js +13 -6
  29. package/dist/database/queries.js.map +1 -1
  30. package/dist/index.js +64 -1
  31. package/dist/index.js.map +1 -1
  32. package/dist/providers/api-models.d.ts +5 -1
  33. package/dist/providers/api-models.d.ts.map +1 -1
  34. package/dist/providers/api-models.js +10 -107
  35. package/dist/providers/api-models.js.map +1 -1
  36. package/dist/providers/claude.d.ts.map +1 -1
  37. package/dist/providers/claude.js +16 -1
  38. package/dist/providers/claude.js.map +1 -1
  39. package/dist/providers/codex.d.ts.map +1 -1
  40. package/dist/providers/codex.js +16 -1
  41. package/dist/providers/codex.js.map +1 -1
  42. package/dist/providers/interface.d.ts.map +1 -1
  43. package/dist/providers/interface.js +11 -1
  44. package/dist/providers/interface.js.map +1 -1
  45. package/dist/providers/mistral-models.d.ts +18 -0
  46. package/dist/providers/mistral-models.d.ts.map +1 -0
  47. package/dist/providers/mistral-models.js +145 -0
  48. package/dist/providers/mistral-models.js.map +1 -0
  49. package/dist/providers/mistral.d.ts +6 -0
  50. package/dist/providers/mistral.d.ts.map +1 -1
  51. package/dist/providers/mistral.js +31 -54
  52. package/dist/providers/mistral.js.map +1 -1
  53. package/dist/providers/opencode.d.ts.map +1 -1
  54. package/dist/providers/opencode.js +5 -1
  55. package/dist/providers/opencode.js.map +1 -1
  56. package/dist/proxy/daemon-entry.d.ts +9 -0
  57. package/dist/proxy/daemon-entry.d.ts.map +1 -0
  58. package/dist/proxy/daemon-entry.js +29 -0
  59. package/dist/proxy/daemon-entry.js.map +1 -0
  60. package/dist/proxy/hf-proxy.d.ts +16 -0
  61. package/dist/proxy/hf-proxy.d.ts.map +1 -0
  62. package/dist/proxy/hf-proxy.js +200 -0
  63. package/dist/proxy/hf-proxy.js.map +1 -0
  64. package/dist/proxy/hf-token.d.ts +18 -0
  65. package/dist/proxy/hf-token.d.ts.map +1 -0
  66. package/dist/proxy/hf-token.js +57 -0
  67. package/dist/proxy/hf-token.js.map +1 -0
  68. package/dist/proxy/lifecycle.d.ts +26 -0
  69. package/dist/proxy/lifecycle.d.ts.map +1 -0
  70. package/dist/proxy/lifecycle.js +129 -0
  71. package/dist/proxy/lifecycle.js.map +1 -0
  72. package/package.json +1 -1
  73. package/dist/commands/merge.d.ts +0 -3
  74. package/dist/commands/merge.d.ts.map +0 -1
  75. package/dist/commands/merge.js +0 -246
  76. package/dist/commands/merge.js.map +0 -1
  77. package/dist/parallel/merge-commit-checks.d.ts +0 -6
  78. package/dist/parallel/merge-commit-checks.d.ts.map +0 -1
  79. package/dist/parallel/merge-commit-checks.js +0 -28
  80. package/dist/parallel/merge-commit-checks.js.map +0 -1
  81. package/dist/parallel/merge-conflict-attempts.d.ts +0 -8
  82. package/dist/parallel/merge-conflict-attempts.d.ts.map +0 -1
  83. package/dist/parallel/merge-conflict-attempts.js +0 -60
  84. package/dist/parallel/merge-conflict-attempts.js.map +0 -1
  85. package/dist/parallel/merge-conflict-invoke.d.ts +0 -2
  86. package/dist/parallel/merge-conflict-invoke.d.ts.map +0 -1
  87. package/dist/parallel/merge-conflict-invoke.js +0 -41
  88. package/dist/parallel/merge-conflict-invoke.js.map +0 -1
  89. package/dist/parallel/merge-conflict-prompts.d.ts +0 -23
  90. package/dist/parallel/merge-conflict-prompts.d.ts.map +0 -1
  91. package/dist/parallel/merge-conflict-prompts.js +0 -40
  92. package/dist/parallel/merge-conflict-prompts.js.map +0 -1
  93. package/dist/parallel/merge-conflict-task.d.ts +0 -3
  94. package/dist/parallel/merge-conflict-task.d.ts.map +0 -1
  95. package/dist/parallel/merge-conflict-task.js +0 -59
  96. package/dist/parallel/merge-conflict-task.js.map +0 -1
  97. package/dist/parallel/merge-conflict.d.ts +0 -22
  98. package/dist/parallel/merge-conflict.d.ts.map +0 -1
  99. package/dist/parallel/merge-conflict.js +0 -176
  100. package/dist/parallel/merge-conflict.js.map +0 -1
  101. package/dist/parallel/merge-errors.d.ts +0 -12
  102. package/dist/parallel/merge-errors.d.ts.map +0 -1
  103. package/dist/parallel/merge-errors.js +0 -18
  104. package/dist/parallel/merge-errors.js.map +0 -1
  105. package/dist/parallel/merge-git.d.ts +0 -25
  106. package/dist/parallel/merge-git.d.ts.map +0 -1
  107. package/dist/parallel/merge-git.js +0 -141
  108. package/dist/parallel/merge-git.js.map +0 -1
  109. package/dist/parallel/merge-lock.d.ts +0 -28
  110. package/dist/parallel/merge-lock.d.ts.map +0 -1
  111. package/dist/parallel/merge-lock.js +0 -91
  112. package/dist/parallel/merge-lock.js.map +0 -1
  113. package/dist/parallel/merge-process.d.ts +0 -21
  114. package/dist/parallel/merge-process.d.ts.map +0 -1
  115. package/dist/parallel/merge-process.js +0 -104
  116. package/dist/parallel/merge-process.js.map +0 -1
  117. package/dist/parallel/merge-progress.d.ts +0 -22
  118. package/dist/parallel/merge-progress.d.ts.map +0 -1
  119. package/dist/parallel/merge-progress.js +0 -41
  120. package/dist/parallel/merge-progress.js.map +0 -1
  121. package/dist/parallel/merge-sealing.d.ts +0 -8
  122. package/dist/parallel/merge-sealing.d.ts.map +0 -1
  123. package/dist/parallel/merge-sealing.js +0 -60
  124. package/dist/parallel/merge-sealing.js.map +0 -1
  125. package/dist/parallel/merge-validation.d.ts +0 -6
  126. package/dist/parallel/merge-validation.d.ts.map +0 -1
  127. package/dist/parallel/merge-validation.js +0 -57
  128. package/dist/parallel/merge-validation.js.map +0 -1
  129. package/dist/parallel/merge-workspace.d.ts +0 -8
  130. package/dist/parallel/merge-workspace.d.ts.map +0 -1
  131. package/dist/parallel/merge-workspace.js +0 -37
  132. package/dist/parallel/merge-workspace.js.map +0 -1
  133. package/dist/parallel/merge.d.ts +0 -48
  134. package/dist/parallel/merge.d.ts.map +0 -1
  135. package/dist/parallel/merge.js +0 -228
  136. package/dist/parallel/merge.js.map +0 -1
  137. package/dist/workspace/git-lifecycle-merge.d.ts +0 -23
  138. package/dist/workspace/git-lifecycle-merge.d.ts.map +0 -1
  139. package/dist/workspace/git-lifecycle-merge.js +0 -159
  140. package/dist/workspace/git-lifecycle-merge.js.map +0 -1
  141. package/dist/workspace/merge-pipeline.d.ts +0 -21
  142. package/dist/workspace/merge-pipeline.d.ts.map +0 -1
  143. package/dist/workspace/merge-pipeline.js +0 -74
  144. package/dist/workspace/merge-pipeline.js.map +0 -1
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ /**
3
+ * HF Proxy Daemon Entry Point
4
+ *
5
+ * Standalone script spawned as a detached child process.
6
+ * Reads HF_TOKEN and optional HF_BASE_URL / PROXY_PORT from env,
7
+ * starts the proxy server, and stays alive until killed.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ const hf_proxy_js_1 = require("./hf-proxy.js");
11
+ const node_fs_1 = require("node:fs");
12
+ const node_path_1 = require("node:path");
13
+ const node_os_1 = require("node:os");
14
+ const PID_FILE = (0, node_path_1.join)((0, node_os_1.homedir)(), '.steroids', 'proxy.pid');
15
+ const hfToken = process.env.HF_TOKEN;
16
+ if (!hfToken) {
17
+ process.exit(1);
18
+ }
19
+ const hfBaseUrl = process.env.HF_BASE_URL ?? 'https://router.huggingface.co/v1';
20
+ const port = parseInt(process.env.PROXY_PORT ?? '3580', 10);
21
+ const server = (0, hf_proxy_js_1.createHFProxy)({ hfBaseUrl, hfToken });
22
+ server.listen(port, '127.0.0.1', () => {
23
+ const actualPort = server.address().port;
24
+ // Write PID file so lifecycle.ts can detect us
25
+ const pidDir = (0, node_path_1.dirname)(PID_FILE);
26
+ (0, node_fs_1.mkdirSync)(pidDir, { recursive: true });
27
+ (0, node_fs_1.writeFileSync)(PID_FILE, JSON.stringify({ pid: process.pid, port: actualPort }), 'utf-8');
28
+ });
29
+ //# sourceMappingURL=daemon-entry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon-entry.js","sourceRoot":"","sources":["../../src/proxy/daemon-entry.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAEH,+CAA8C;AAC9C,qCAAmD;AACnD,yCAA0C;AAC1C,qCAAkC;AAElC,MAAM,QAAQ,GAAG,IAAA,gBAAI,EAAC,IAAA,iBAAO,GAAE,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;AAE3D,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;AACrC,IAAI,CAAC,OAAO,EAAE,CAAC;IACb,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,kCAAkC,CAAC;AAChF,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,MAAM,EAAE,EAAE,CAAC,CAAC;AAE5D,MAAM,MAAM,GAAG,IAAA,2BAAa,EAAC,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;AAErD,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE;IACpC,MAAM,UAAU,GAAI,MAAM,CAAC,OAAO,EAAU,CAAC,IAAI,CAAC;IAElD,+CAA+C;IAC/C,MAAM,MAAM,GAAG,IAAA,mBAAO,EAAC,QAAQ,CAAC,CAAC;IACjC,IAAA,mBAAS,EAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvC,IAAA,uBAAa,EAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;AAC3F,CAAC,CAAC,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * HuggingFace Model Proxy
3
+ *
4
+ * Local HTTP server that translates between provider-native API formats
5
+ * and the HF Router's OpenAI-compatible endpoint. Enables Claude (Anthropic),
6
+ * Codex (OpenAI), and Vibe (Mistral) CLIs to use any HuggingFace model.
7
+ */
8
+ import http from 'node:http';
9
+ export interface HFProxyOptions {
10
+ /** HF Router base URL, e.g. https://router.huggingface.co/v1 */
11
+ hfBaseUrl: string;
12
+ /** Bearer token for HF API */
13
+ hfToken: string;
14
+ }
15
+ export declare function createHFProxy(options: HFProxyOptions): http.Server;
16
+ //# sourceMappingURL=hf-proxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hf-proxy.d.ts","sourceRoot":"","sources":["../../src/proxy/hf-proxy.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,WAAW,cAAc;IAC7B,gEAAgE;IAChE,SAAS,EAAE,MAAM,CAAC;IAClB,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAAC,MAAM,CAuBlE"}
@@ -0,0 +1,200 @@
1
+ "use strict";
2
+ /**
3
+ * HuggingFace Model Proxy
4
+ *
5
+ * Local HTTP server that translates between provider-native API formats
6
+ * and the HF Router's OpenAI-compatible endpoint. Enables Claude (Anthropic),
7
+ * Codex (OpenAI), and Vibe (Mistral) CLIs to use any HuggingFace model.
8
+ */
9
+ var __importDefault = (this && this.__importDefault) || function (mod) {
10
+ return (mod && mod.__esModule) ? mod : { "default": mod };
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.createHFProxy = createHFProxy;
14
+ const node_http_1 = __importDefault(require("node:http"));
15
+ function createHFProxy(options) {
16
+ const { hfBaseUrl, hfToken } = options;
17
+ return node_http_1.default.createServer(async (req, res) => {
18
+ try {
19
+ if (req.method === 'GET' && req.url === '/v1/models') {
20
+ await handleModels(hfBaseUrl, hfToken, res);
21
+ }
22
+ else if (req.method === 'POST' && req.url === '/v1/chat/completions') {
23
+ await handleChatCompletions(req, hfBaseUrl, hfToken, res);
24
+ }
25
+ else if (req.method === 'POST' && req.url === '/v1/messages') {
26
+ await handleAnthropicMessages(req, hfBaseUrl, hfToken, res);
27
+ }
28
+ else if (req.method === 'GET' && req.url === '/health') {
29
+ res.writeHead(200, { 'Content-Type': 'application/json' });
30
+ res.end(JSON.stringify({ status: 'ok' }));
31
+ }
32
+ else {
33
+ res.writeHead(404, { 'Content-Type': 'application/json' });
34
+ res.end(JSON.stringify({ error: 'Not found' }));
35
+ }
36
+ }
37
+ catch {
38
+ res.writeHead(502, { 'Content-Type': 'application/json' });
39
+ res.end(JSON.stringify({ error: 'Upstream error' }));
40
+ }
41
+ });
42
+ }
43
+ // ---------------------------------------------------------------------------
44
+ // GET /v1/models — normalize HF response to pure OpenAI schema
45
+ // ---------------------------------------------------------------------------
46
+ async function handleModels(hfBaseUrl, hfToken, res) {
47
+ const upstream = await fetch(`${hfBaseUrl}/models`, {
48
+ headers: { Authorization: `Bearer ${hfToken}` },
49
+ });
50
+ if (!upstream.ok) {
51
+ res.writeHead(upstream.status, { 'Content-Type': 'application/json' });
52
+ res.end(await upstream.text());
53
+ return;
54
+ }
55
+ const raw = (await upstream.json());
56
+ const rawModels = Array.isArray(raw) ? raw : (raw.data ?? []);
57
+ const models = rawModels.map((m) => ({
58
+ id: m.id,
59
+ object: 'model',
60
+ created: m.created ?? Math.floor(Date.now() / 1000),
61
+ owned_by: m.owned_by ?? m.id.split('/')[0] ?? 'unknown',
62
+ }));
63
+ res.writeHead(200, { 'Content-Type': 'application/json' });
64
+ res.end(JSON.stringify({ object: 'list', data: models }));
65
+ }
66
+ // ---------------------------------------------------------------------------
67
+ // POST /v1/chat/completions — stream-proxy to HF (pass-through)
68
+ // ---------------------------------------------------------------------------
69
+ async function handleChatCompletions(req, hfBaseUrl, hfToken, res) {
70
+ const body = await readBody(req);
71
+ const upstream = await fetch(`${hfBaseUrl}/chat/completions`, {
72
+ method: 'POST',
73
+ headers: {
74
+ Authorization: `Bearer ${hfToken}`,
75
+ 'Content-Type': 'application/json',
76
+ },
77
+ body,
78
+ });
79
+ res.writeHead(upstream.status, {
80
+ 'Content-Type': upstream.headers.get('content-type') ?? 'application/json',
81
+ });
82
+ if (!upstream.body) {
83
+ res.end(await upstream.text());
84
+ return;
85
+ }
86
+ const reader = upstream.body.getReader();
87
+ try {
88
+ while (true) {
89
+ const { done, value } = await reader.read();
90
+ if (done)
91
+ break;
92
+ res.write(value);
93
+ }
94
+ }
95
+ finally {
96
+ res.end();
97
+ }
98
+ }
99
+ function anthropicToOpenAI(body) {
100
+ const messages = [];
101
+ if (body.system) {
102
+ messages.push({ role: 'system', content: body.system });
103
+ }
104
+ for (const msg of body.messages) {
105
+ const content = typeof msg.content === 'string'
106
+ ? msg.content
107
+ : msg.content
108
+ .filter((b) => b.type === 'text')
109
+ .map((b) => b.text)
110
+ .join('\n');
111
+ messages.push({ role: msg.role, content });
112
+ }
113
+ return {
114
+ model: body.model,
115
+ messages,
116
+ max_tokens: body.max_tokens,
117
+ stream: body.stream ?? false,
118
+ ...(body.temperature !== undefined && { temperature: body.temperature }),
119
+ ...(body.top_p !== undefined && { top_p: body.top_p }),
120
+ ...(body.tools && { tools: body.tools.map(anthropicToolToOpenAI) }),
121
+ };
122
+ }
123
+ function anthropicToolToOpenAI(tool) {
124
+ return {
125
+ type: 'function',
126
+ function: {
127
+ name: tool.name,
128
+ description: tool.description ?? '',
129
+ parameters: tool.input_schema ?? {},
130
+ },
131
+ };
132
+ }
133
+ function openAIResponseToAnthropic(oai, model) {
134
+ const choice = oai.choices?.[0];
135
+ const content = [];
136
+ if (choice?.message?.content) {
137
+ content.push({ type: 'text', text: choice.message.content });
138
+ }
139
+ if (choice?.message?.tool_calls) {
140
+ for (const tc of choice.message.tool_calls) {
141
+ content.push({
142
+ type: 'tool_use',
143
+ id: tc.id,
144
+ name: tc.function.name,
145
+ input: JSON.parse(tc.function.arguments || '{}'),
146
+ });
147
+ }
148
+ }
149
+ const stopReasonMap = {
150
+ stop: 'end_turn',
151
+ length: 'max_tokens',
152
+ tool_calls: 'tool_use',
153
+ };
154
+ return {
155
+ id: oai.id ?? `msg_${Date.now()}`,
156
+ type: 'message',
157
+ role: 'assistant',
158
+ model,
159
+ content,
160
+ stop_reason: stopReasonMap[choice?.finish_reason] ?? 'end_turn',
161
+ usage: {
162
+ input_tokens: oai.usage?.prompt_tokens ?? 0,
163
+ output_tokens: oai.usage?.completion_tokens ?? 0,
164
+ },
165
+ };
166
+ }
167
+ async function handleAnthropicMessages(req, hfBaseUrl, hfToken, res) {
168
+ const rawBody = await readBody(req);
169
+ const anthropicReq = JSON.parse(rawBody);
170
+ const openaiReq = anthropicToOpenAI(anthropicReq);
171
+ const upstream = await fetch(`${hfBaseUrl}/chat/completions`, {
172
+ method: 'POST',
173
+ headers: {
174
+ Authorization: `Bearer ${hfToken}`,
175
+ 'Content-Type': 'application/json',
176
+ },
177
+ body: JSON.stringify(openaiReq),
178
+ });
179
+ if (!upstream.ok) {
180
+ res.writeHead(upstream.status, { 'Content-Type': 'application/json' });
181
+ res.end(await upstream.text());
182
+ return;
183
+ }
184
+ const oaiResponse = await upstream.json();
185
+ const anthropicResponse = openAIResponseToAnthropic(oaiResponse, anthropicReq.model);
186
+ res.writeHead(200, { 'Content-Type': 'application/json' });
187
+ res.end(JSON.stringify(anthropicResponse));
188
+ }
189
+ // ---------------------------------------------------------------------------
190
+ // Helpers
191
+ // ---------------------------------------------------------------------------
192
+ function readBody(req) {
193
+ return new Promise((resolve, reject) => {
194
+ let data = '';
195
+ req.on('data', (chunk) => (data += chunk.toString()));
196
+ req.on('end', () => resolve(data));
197
+ req.on('error', reject);
198
+ });
199
+ }
200
+ //# sourceMappingURL=hf-proxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hf-proxy.js","sourceRoot":"","sources":["../../src/proxy/hf-proxy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * HF Token Resolution
3
+ *
4
+ * Resolves a HuggingFace API token from available sources.
5
+ */
6
+ /**
7
+ * Resolve HF token from available sources (in priority order):
8
+ * 1. HF_TOKEN environment variable
9
+ * 2. opencode.json config file
10
+ * 3. ~/.huggingface/token file
11
+ */
12
+ export declare function resolveHFToken(configDir?: string): string | null;
13
+ /**
14
+ * Detect if a model ID is a HuggingFace model (contains org/name format).
15
+ * Native provider models don't contain slashes (e.g., claude-sonnet-4-6, gpt-5.3-codex).
16
+ */
17
+ export declare function isHFModel(modelId: string): boolean;
18
+ //# sourceMappingURL=hf-token.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hf-token.d.ts","sourceRoot":"","sources":["../../src/proxy/hf-token.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA4BhE;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAElD"}
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ /**
3
+ * HF Token Resolution
4
+ *
5
+ * Resolves a HuggingFace API token from available sources.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.resolveHFToken = resolveHFToken;
9
+ exports.isHFModel = isHFModel;
10
+ const node_fs_1 = require("node:fs");
11
+ const node_path_1 = require("node:path");
12
+ const node_os_1 = require("node:os");
13
+ /**
14
+ * Resolve HF token from available sources (in priority order):
15
+ * 1. HF_TOKEN environment variable
16
+ * 2. opencode.json config file
17
+ * 3. ~/.huggingface/token file
18
+ */
19
+ function resolveHFToken(configDir) {
20
+ if (process.env.HF_TOKEN)
21
+ return process.env.HF_TOKEN;
22
+ // Try opencode.json
23
+ const opencodeConfigPaths = [
24
+ configDir ? (0, node_path_1.join)(configDir, 'opencode.json') : null,
25
+ (0, node_path_1.join)((0, node_os_1.homedir)(), '.config', 'opencode', 'opencode.json'),
26
+ ].filter(Boolean);
27
+ for (const configPath of opencodeConfigPaths) {
28
+ try {
29
+ if (!(0, node_fs_1.existsSync)(configPath))
30
+ continue;
31
+ const config = JSON.parse((0, node_fs_1.readFileSync)(configPath, 'utf-8'));
32
+ const token = config?.provider?.huggingface?.options?.apiKey;
33
+ if (token)
34
+ return token;
35
+ }
36
+ catch { /* continue */ }
37
+ }
38
+ // Try ~/.huggingface/token
39
+ try {
40
+ const tokenPath = (0, node_path_1.join)((0, node_os_1.homedir)(), '.huggingface', 'token');
41
+ if ((0, node_fs_1.existsSync)(tokenPath)) {
42
+ const token = (0, node_fs_1.readFileSync)(tokenPath, 'utf-8').trim();
43
+ if (token)
44
+ return token;
45
+ }
46
+ }
47
+ catch { /* ignore */ }
48
+ return null;
49
+ }
50
+ /**
51
+ * Detect if a model ID is a HuggingFace model (contains org/name format).
52
+ * Native provider models don't contain slashes (e.g., claude-sonnet-4-6, gpt-5.3-codex).
53
+ */
54
+ function isHFModel(modelId) {
55
+ return modelId.includes('/') && !modelId.startsWith('models/');
56
+ }
57
+ //# sourceMappingURL=hf-token.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hf-token.js","sourceRoot":"","sources":["../../src/proxy/hf-token.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AAYH,wCA4BC;AAMD,8BAEC;AA9CD,qCAAmD;AACnD,yCAAiC;AACjC,qCAAkC;AAElC;;;;;GAKG;AACH,SAAgB,cAAc,CAAC,SAAkB;IAC/C,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ;QAAE,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;IAEtD,oBAAoB;IACpB,MAAM,mBAAmB,GAAG;QAC1B,SAAS,CAAC,CAAC,CAAC,IAAA,gBAAI,EAAC,SAAS,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI;QACnD,IAAA,gBAAI,EAAC,IAAA,iBAAO,GAAE,EAAE,SAAS,EAAE,UAAU,EAAE,eAAe,CAAC;KACxD,CAAC,MAAM,CAAC,OAAO,CAAa,CAAC;IAE9B,KAAK,MAAM,UAAU,IAAI,mBAAmB,EAAE,CAAC;QAC7C,IAAI,CAAC;YACH,IAAI,CAAC,IAAA,oBAAU,EAAC,UAAU,CAAC;gBAAE,SAAS;YACtC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,sBAAY,EAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;YAC7D,MAAM,KAAK,GAAG,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,CAAC;YAC7D,IAAI,KAAK;gBAAE,OAAO,KAAK,CAAC;QAC1B,CAAC;QAAC,MAAM,CAAC,CAAC,cAAc,CAAC,CAAC;IAC5B,CAAC;IAED,2BAA2B;IAC3B,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,IAAA,gBAAI,EAAC,IAAA,iBAAO,GAAE,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC;QAC3D,IAAI,IAAA,oBAAU,EAAC,SAAS,CAAC,EAAE,CAAC;YAC1B,MAAM,KAAK,GAAG,IAAA,sBAAY,EAAC,SAAS,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;YACtD,IAAI,KAAK;gBAAE,OAAO,KAAK,CAAC;QAC1B,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IAExB,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,SAAgB,SAAS,CAAC,OAAe;IACvC,OAAO,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;AACjE,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * HF Proxy Lifecycle
3
+ *
4
+ * Start/stop/ensure the local HuggingFace proxy server.
5
+ * PID file at ~/.steroids/proxy.pid tracks the running instance.
6
+ */
7
+ export interface ProxyStartOptions {
8
+ hfToken: string;
9
+ hfBaseUrl?: string;
10
+ port?: number;
11
+ }
12
+ export declare function startProxy(options: ProxyStartOptions): Promise<{
13
+ port: number;
14
+ pid: number;
15
+ }>;
16
+ export declare function stopProxy(): void;
17
+ export declare function isProxyRunning(): boolean;
18
+ export declare function getProxyPort(): number | null;
19
+ export declare function ensureProxy(options: ProxyStartOptions): Promise<number>;
20
+ /**
21
+ * Spawn the proxy as a detached background process that survives the parent exiting.
22
+ * Used by `steroids web` so the proxy stays alive alongside the dashboard.
23
+ * Returns the port the proxy is listening on, or null if it couldn't start.
24
+ */
25
+ export declare function spawnProxyDaemon(options: ProxyStartOptions): Promise<number | null>;
26
+ //# sourceMappingURL=lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../src/proxy/lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAcH,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAwBnG;AAED,wBAAgB,SAAS,IAAI,IAAI,CAQhC;AAED,wBAAgB,cAAc,IAAI,OAAO,CAaxC;AAED,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAQ5C;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAM7E;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAmCzF"}
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ /**
3
+ * HF Proxy Lifecycle
4
+ *
5
+ * Start/stop/ensure the local HuggingFace proxy server.
6
+ * PID file at ~/.steroids/proxy.pid tracks the running instance.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.startProxy = startProxy;
10
+ exports.stopProxy = stopProxy;
11
+ exports.isProxyRunning = isProxyRunning;
12
+ exports.getProxyPort = getProxyPort;
13
+ exports.ensureProxy = ensureProxy;
14
+ exports.spawnProxyDaemon = spawnProxyDaemon;
15
+ const node_fs_1 = require("node:fs");
16
+ const node_path_1 = require("node:path");
17
+ const node_os_1 = require("node:os");
18
+ const node_child_process_1 = require("node:child_process");
19
+ const hf_proxy_js_1 = require("./hf-proxy.js");
20
+ const PID_FILE = (0, node_path_1.join)((0, node_os_1.homedir)(), '.steroids', 'proxy.pid');
21
+ const DEFAULT_PORT = 3580;
22
+ let serverInstance = null;
23
+ async function startProxy(options) {
24
+ if (serverInstance) {
25
+ throw new Error('Proxy already running in this process');
26
+ }
27
+ const port = options.port ?? DEFAULT_PORT;
28
+ const hfBaseUrl = options.hfBaseUrl ?? 'https://router.huggingface.co/v1';
29
+ const server = (0, hf_proxy_js_1.createHFProxy)({ hfBaseUrl, hfToken: options.hfToken });
30
+ await new Promise((resolve, reject) => {
31
+ server.on('error', reject);
32
+ server.listen(port, '127.0.0.1', () => resolve());
33
+ });
34
+ const actualPort = server.address().port;
35
+ serverInstance = server;
36
+ // Write PID file
37
+ const pidDir = (0, node_path_1.dirname)(PID_FILE);
38
+ if (!(0, node_fs_1.existsSync)(pidDir))
39
+ (0, node_fs_1.mkdirSync)(pidDir, { recursive: true });
40
+ (0, node_fs_1.writeFileSync)(PID_FILE, JSON.stringify({ pid: process.pid, port: actualPort }), 'utf-8');
41
+ return { port: actualPort, pid: process.pid };
42
+ }
43
+ function stopProxy() {
44
+ if (serverInstance) {
45
+ serverInstance.close();
46
+ serverInstance = null;
47
+ }
48
+ try {
49
+ if ((0, node_fs_1.existsSync)(PID_FILE))
50
+ (0, node_fs_1.unlinkSync)(PID_FILE);
51
+ }
52
+ catch { /* ignore */ }
53
+ }
54
+ function isProxyRunning() {
55
+ if (serverInstance)
56
+ return true;
57
+ if (!(0, node_fs_1.existsSync)(PID_FILE))
58
+ return false;
59
+ try {
60
+ const { pid } = JSON.parse((0, node_fs_1.readFileSync)(PID_FILE, 'utf-8'));
61
+ process.kill(pid, 0); // Signal 0 = check if process exists
62
+ return true;
63
+ }
64
+ catch {
65
+ // Stale PID file
66
+ try {
67
+ (0, node_fs_1.unlinkSync)(PID_FILE);
68
+ }
69
+ catch { /* ignore */ }
70
+ return false;
71
+ }
72
+ }
73
+ function getProxyPort() {
74
+ if (!(0, node_fs_1.existsSync)(PID_FILE))
75
+ return null;
76
+ try {
77
+ const { port } = JSON.parse((0, node_fs_1.readFileSync)(PID_FILE, 'utf-8'));
78
+ return port;
79
+ }
80
+ catch {
81
+ return null;
82
+ }
83
+ }
84
+ async function ensureProxy(options) {
85
+ if (isProxyRunning()) {
86
+ return getProxyPort() ?? DEFAULT_PORT;
87
+ }
88
+ const { port } = await startProxy(options);
89
+ return port;
90
+ }
91
+ /**
92
+ * Spawn the proxy as a detached background process that survives the parent exiting.
93
+ * Used by `steroids web` so the proxy stays alive alongside the dashboard.
94
+ * Returns the port the proxy is listening on, or null if it couldn't start.
95
+ */
96
+ async function spawnProxyDaemon(options) {
97
+ if (isProxyRunning()) {
98
+ return getProxyPort();
99
+ }
100
+ const port = options.port ?? DEFAULT_PORT;
101
+ const hfBaseUrl = options.hfBaseUrl ?? 'https://router.huggingface.co/v1';
102
+ // Resolve the daemon entry script path (sibling to this file in dist/)
103
+ const entryScript = (0, node_path_1.join)(__dirname, 'daemon-entry.js');
104
+ if (!(0, node_fs_1.existsSync)(entryScript))
105
+ return null;
106
+ const logsDir = (0, node_path_1.join)((0, node_os_1.homedir)(), '.steroids', 'logs');
107
+ if (!(0, node_fs_1.existsSync)(logsDir))
108
+ (0, node_fs_1.mkdirSync)(logsDir, { recursive: true });
109
+ const logFd = (0, node_fs_1.openSync)((0, node_path_1.join)(logsDir, 'proxy.log'), node_fs_1.constants.O_WRONLY | node_fs_1.constants.O_CREAT | node_fs_1.constants.O_TRUNC);
110
+ const child = (0, node_child_process_1.spawn)('node', [entryScript], {
111
+ detached: true,
112
+ stdio: ['ignore', logFd, logFd],
113
+ env: {
114
+ ...process.env,
115
+ HF_TOKEN: options.hfToken,
116
+ HF_BASE_URL: hfBaseUrl,
117
+ PROXY_PORT: String(port),
118
+ },
119
+ });
120
+ child.unref();
121
+ // Wait briefly for the PID file to appear (daemon writes it on listen)
122
+ for (let i = 0; i < 20; i++) {
123
+ await new Promise((r) => setTimeout(r, 100));
124
+ if (isProxyRunning())
125
+ return getProxyPort();
126
+ }
127
+ return null;
128
+ }
129
+ //# sourceMappingURL=lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../src/proxy/lifecycle.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "steroids-cli",
3
- "version": "0.15.3",
3
+ "version": "0.15.5",
4
4
  "description": "Automated task execution system with coder/reviewer loop",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -1,3 +0,0 @@
1
- import type { GlobalFlags } from '../cli/flags.js';
2
- export declare function mergeCommand(args: string[], flags: GlobalFlags): Promise<void>;
3
- //# sourceMappingURL=merge.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../src/commands/merge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAmOnD,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAwGpF"}