surfcode 0.0.0-stage → 0.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 (117) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +325 -2
  3. package/assets/surfcode-logo.gif +0 -0
  4. package/dist/cli/auth.js +315 -0
  5. package/dist/cli/auth.js.map +1 -0
  6. package/dist/cli/config.js +228 -0
  7. package/dist/cli/config.js.map +1 -0
  8. package/dist/cli/headless.js +355 -0
  9. package/dist/cli/headless.js.map +1 -0
  10. package/dist/cli/inspect.js +462 -0
  11. package/dist/cli/inspect.js.map +1 -0
  12. package/dist/cli/interactive.js +130 -0
  13. package/dist/cli/interactive.js.map +1 -0
  14. package/dist/cli/sessions.js +170 -0
  15. package/dist/cli/sessions.js.map +1 -0
  16. package/dist/cli/sync.js +190 -0
  17. package/dist/cli/sync.js.map +1 -0
  18. package/dist/cli/util.js +345 -0
  19. package/dist/cli/util.js.map +1 -0
  20. package/dist/cli.js +485 -0
  21. package/dist/cli.js.map +1 -0
  22. package/dist/core/agent.js +281 -0
  23. package/dist/core/agent.js.map +1 -0
  24. package/dist/core/agents.js +55 -0
  25. package/dist/core/agents.js.map +1 -0
  26. package/dist/core/auth.js +107 -0
  27. package/dist/core/auth.js.map +1 -0
  28. package/dist/core/catalog.js +306 -0
  29. package/dist/core/catalog.js.map +1 -0
  30. package/dist/core/chat/anthropic.js +222 -0
  31. package/dist/core/chat/anthropic.js.map +1 -0
  32. package/dist/core/chat/common.js +367 -0
  33. package/dist/core/chat/common.js.map +1 -0
  34. package/dist/core/chat/google.js +180 -0
  35. package/dist/core/chat/google.js.map +1 -0
  36. package/dist/core/chat/index.js +80 -0
  37. package/dist/core/chat/index.js.map +1 -0
  38. package/dist/core/chat/openai.js +164 -0
  39. package/dist/core/chat/openai.js.map +1 -0
  40. package/dist/core/chat/types.js +2 -0
  41. package/dist/core/chat/types.js.map +1 -0
  42. package/dist/core/clipboard.js +34 -0
  43. package/dist/core/clipboard.js.map +1 -0
  44. package/dist/core/compact.js +39 -0
  45. package/dist/core/compact.js.map +1 -0
  46. package/dist/core/config.js +211 -0
  47. package/dist/core/config.js.map +1 -0
  48. package/dist/core/delegate.js +184 -0
  49. package/dist/core/delegate.js.map +1 -0
  50. package/dist/core/effort.js +80 -0
  51. package/dist/core/effort.js.map +1 -0
  52. package/dist/core/errors.js +32 -0
  53. package/dist/core/errors.js.map +1 -0
  54. package/dist/core/free.js +21 -0
  55. package/dist/core/free.js.map +1 -0
  56. package/dist/core/github.js +445 -0
  57. package/dist/core/github.js.map +1 -0
  58. package/dist/core/paths.js +51 -0
  59. package/dist/core/paths.js.map +1 -0
  60. package/dist/core/prompt.js +95 -0
  61. package/dist/core/prompt.js.map +1 -0
  62. package/dist/core/provider.js +298 -0
  63. package/dist/core/provider.js.map +1 -0
  64. package/dist/core/session.js +159 -0
  65. package/dist/core/session.js.map +1 -0
  66. package/dist/core/sync.js +126 -0
  67. package/dist/core/sync.js.map +1 -0
  68. package/dist/core/types.js +2 -0
  69. package/dist/core/types.js.map +1 -0
  70. package/dist/core/usage.js +127 -0
  71. package/dist/core/usage.js.map +1 -0
  72. package/dist/core/workspace.js +70 -0
  73. package/dist/core/workspace.js.map +1 -0
  74. package/dist/data/models.json +1 -0
  75. package/dist/sync/server.js +179 -0
  76. package/dist/sync/server.js.map +1 -0
  77. package/dist/tools/diff.js +21 -0
  78. package/dist/tools/diff.js.map +1 -0
  79. package/dist/tools/files.js +227 -0
  80. package/dist/tools/files.js.map +1 -0
  81. package/dist/tools/github.js +238 -0
  82. package/dist/tools/github.js.map +1 -0
  83. package/dist/tools/index.js +34 -0
  84. package/dist/tools/index.js.map +1 -0
  85. package/dist/tools/search.js +231 -0
  86. package/dist/tools/search.js.map +1 -0
  87. package/dist/tools/shell.js +118 -0
  88. package/dist/tools/shell.js.map +1 -0
  89. package/dist/tools/todos.js +50 -0
  90. package/dist/tools/todos.js.map +1 -0
  91. package/dist/tools/webfetch.js +108 -0
  92. package/dist/tools/webfetch.js.map +1 -0
  93. package/dist/tui/App.js +3002 -0
  94. package/dist/tui/App.js.map +1 -0
  95. package/dist/tui/ansi.js +151 -0
  96. package/dist/tui/ansi.js.map +1 -0
  97. package/dist/tui/commands.js +61 -0
  98. package/dist/tui/commands.js.map +1 -0
  99. package/dist/tui/explorer.js +152 -0
  100. package/dist/tui/explorer.js.map +1 -0
  101. package/dist/tui/icons.js +21 -0
  102. package/dist/tui/icons.js.map +1 -0
  103. package/dist/tui/layout.js +324 -0
  104. package/dist/tui/layout.js.map +1 -0
  105. package/dist/tui/markdown.js +335 -0
  106. package/dist/tui/markdown.js.map +1 -0
  107. package/dist/tui/overlays.js +316 -0
  108. package/dist/tui/overlays.js.map +1 -0
  109. package/dist/tui/render.js +234 -0
  110. package/dist/tui/render.js.map +1 -0
  111. package/dist/tui/theme.js +148 -0
  112. package/dist/tui/theme.js.map +1 -0
  113. package/dist/tui/types.js +73 -0
  114. package/dist/tui/types.js.map +1 -0
  115. package/dist/version.js +3 -0
  116. package/dist/version.js.map +1 -0
  117. package/package.json +75 -4
@@ -0,0 +1,281 @@
1
+ import { addUsage, costForUsage, emptyUsage } from './usage.js';
2
+ import { buildSystemPrompt } from './prompt.js';
3
+ import { streamChat } from './chat/index.js';
4
+ import { createDelegateTool } from './delegate.js';
5
+ import { isAbortError, SurfError } from './errors.js';
6
+ import { findTool, toolSchemas } from '../tools/index.js';
7
+ export async function runAgent(options) {
8
+ const { cwd, provider, model, mode, tools, callbacks, permissions, maxSteps, signal } = options;
9
+ let messages = [...options.history];
10
+ const userMessage = { role: 'user', content: options.input.trim() };
11
+ if (!userMessage.content)
12
+ throw new SurfError('The prompt is empty.');
13
+ messages.push(userMessage);
14
+ const toolsEnabled = model.meta?.tool_call !== false;
15
+ const usage = emptyUsage();
16
+ const activeTools = [...tools];
17
+ const delegateWorkers = options.delegates?.map((delegate) => `${delegate.provider.id}/${delegate.model.id}`) ?? [];
18
+ if (toolsEnabled && options.delegates?.length) {
19
+ activeTools.push(createDelegateTool({
20
+ delegates: options.delegates,
21
+ getHistory: () => messages,
22
+ signal,
23
+ cwd,
24
+ maxTokens: options.maxTokens,
25
+ temperature: options.temperature,
26
+ effort: options.effort,
27
+ onUsage(delta) {
28
+ addUsage(usage, delta);
29
+ callbacks.onUsage({ ...usage });
30
+ }
31
+ }));
32
+ }
33
+ const system = await buildSystemPrompt({
34
+ cwd,
35
+ mode,
36
+ modelName: model.name,
37
+ providerName: provider.name,
38
+ toolsEnabled,
39
+ effort: options.effort,
40
+ agentWorkers: delegateWorkers
41
+ });
42
+ const schemas = toolsEnabled ? toolSchemas(activeTools) : [];
43
+ let aborted = false;
44
+ let todos = [];
45
+ for (let step = 1; step <= maxSteps; step += 1) {
46
+ if (signal.aborted) {
47
+ aborted = true;
48
+ break;
49
+ }
50
+ callbacks.onStep?.(step, maxSteps);
51
+ let partialText = '';
52
+ let partialReasoning = '';
53
+ let result;
54
+ try {
55
+ result = await streamChat({
56
+ provider,
57
+ model,
58
+ messages,
59
+ system,
60
+ tools: schemas,
61
+ options: {
62
+ signal,
63
+ maxTokens: options.maxTokens,
64
+ temperature: options.temperature,
65
+ effort: options.effort,
66
+ showReasoning: options.showReasoning,
67
+ timeout: provider.settings.timeout
68
+ },
69
+ callbacks: {
70
+ onText: (delta) => {
71
+ partialText += delta;
72
+ callbacks.onText(delta);
73
+ },
74
+ onReasoning: (delta) => {
75
+ partialReasoning += delta;
76
+ callbacks.onReasoning(delta);
77
+ }
78
+ }
79
+ });
80
+ }
81
+ catch (error) {
82
+ if (signal.aborted || isAbortError(error)) {
83
+ aborted = true;
84
+ if (partialText || partialReasoning) {
85
+ messages.push({
86
+ role: 'assistant',
87
+ content: partialText,
88
+ ...(partialReasoning ? { reasoning: partialReasoning } : {})
89
+ });
90
+ }
91
+ break;
92
+ }
93
+ throw error;
94
+ }
95
+ const turnUsage = {
96
+ inputTokens: result.usage.inputTokens ?? 0,
97
+ outputTokens: result.usage.outputTokens ?? 0,
98
+ reasoningTokens: result.usage.reasoningTokens ?? 0,
99
+ cacheReadTokens: result.usage.cacheReadTokens ?? 0,
100
+ cacheWriteTokens: result.usage.cacheWriteTokens ?? 0,
101
+ cost: costForUsage(model.meta, result.usage, provider.dialect),
102
+ requests: 1
103
+ };
104
+ addUsage(usage, turnUsage);
105
+ callbacks.onUsage({ ...usage });
106
+ if (result.text || result.reasoning || result.toolCalls.length > 0) {
107
+ messages.push({
108
+ role: 'assistant',
109
+ content: result.text,
110
+ ...(result.reasoning ? { reasoning: result.reasoning } : {}),
111
+ ...(result.toolCalls.length > 0 ? { toolCalls: result.toolCalls } : {}),
112
+ ...(result.thinkingBlocks?.length ? { thinkingBlocks: result.thinkingBlocks } : {})
113
+ });
114
+ }
115
+ if (result.toolCalls.length === 0) {
116
+ if (result.finishReason === 'length' || result.finishReason === 'max_tokens') {
117
+ messages.push({
118
+ role: 'assistant',
119
+ content: '_Response reached the output limit. Ask me to continue if you need the rest._'
120
+ });
121
+ }
122
+ break;
123
+ }
124
+ for (let index = 0; index < result.toolCalls.length; index += 1) {
125
+ const call = result.toolCalls[index];
126
+ if (signal.aborted) {
127
+ aborted = true;
128
+ for (const remaining of result.toolCalls.slice(index)) {
129
+ const cancelled = { output: 'Cancelled by user.', isError: true };
130
+ callbacks.onToolStart(remaining, findTool(activeTools, remaining.name));
131
+ callbacks.onToolResult(remaining, cancelled, 0);
132
+ messages.push({
133
+ role: 'tool',
134
+ toolCallId: remaining.id,
135
+ name: remaining.name,
136
+ content: cancelled.output,
137
+ isError: true
138
+ });
139
+ }
140
+ break;
141
+ }
142
+ const tool = findTool(activeTools, call.name);
143
+ callbacks.onToolStart(call, tool);
144
+ const started = Date.now();
145
+ let toolResult;
146
+ try {
147
+ if (call.rawArguments && Object.keys(call.arguments).length === 0) {
148
+ toolResult = {
149
+ output: `Invalid JSON arguments for ${call.name}: ${call.rawArguments.slice(0, 500)}`,
150
+ isError: true
151
+ };
152
+ }
153
+ else if (!tool) {
154
+ toolResult = {
155
+ output: `Unknown tool: ${call.name}. Available tools: ${activeTools.map((entry) => entry.name).join(', ')}.`,
156
+ isError: true
157
+ };
158
+ }
159
+ else {
160
+ toolResult = await executeWithPermission(call, tool, options, permissions, mode, callbacks, todos, (next) => {
161
+ todos = next;
162
+ callbacks.onTodos?.(next);
163
+ });
164
+ }
165
+ }
166
+ catch (error) {
167
+ if (signal.aborted || isAbortError(error)) {
168
+ toolResult = { output: 'Cancelled by user.', isError: true };
169
+ aborted = true;
170
+ }
171
+ else {
172
+ toolResult = {
173
+ output: error instanceof Error ? error.message : String(error),
174
+ isError: true
175
+ };
176
+ }
177
+ }
178
+ const duration = Date.now() - started;
179
+ callbacks.onToolResult(call, toolResult, duration);
180
+ messages.push({
181
+ role: 'tool',
182
+ toolCallId: call.id,
183
+ name: call.name,
184
+ content: toolResult.output,
185
+ ...(toolResult.isError ? { isError: true } : {})
186
+ });
187
+ if (aborted)
188
+ break;
189
+ }
190
+ if (aborted)
191
+ break;
192
+ if (step === maxSteps) {
193
+ messages.push({
194
+ role: 'assistant',
195
+ content: `_Stopped after ${maxSteps} tool steps. Ask me to continue, or raise maxSteps in the config._`
196
+ });
197
+ }
198
+ }
199
+ return { messages, usage, aborted };
200
+ }
201
+ async function executeWithPermission(call, tool, options, permissions, mode, callbacks, todos, setTodos) {
202
+ const permission = buildPermissionRequest(call, tool);
203
+ if (mode === 'plan' && !tool.readOnly) {
204
+ return {
205
+ output: `Plan mode blocked ${tool.name}. Switch to build mode to make changes.`,
206
+ isError: true,
207
+ display: { summary: 'blocked by plan mode' }
208
+ };
209
+ }
210
+ const policy = permissions[tool.action] ?? 'ask';
211
+ if (policy === 'deny') {
212
+ return {
213
+ output: `Permission denied by policy for ${tool.action}.`,
214
+ isError: true,
215
+ display: { summary: 'denied by policy' }
216
+ };
217
+ }
218
+ if (policy === 'ask') {
219
+ const decision = await callbacks.requestPermission(permission);
220
+ if (decision === 'deny') {
221
+ return {
222
+ output: 'Permission denied by user. Do not retry this exact action.',
223
+ isError: true,
224
+ display: { summary: 'denied' }
225
+ };
226
+ }
227
+ }
228
+ const context = {
229
+ cwd: options.cwd,
230
+ signal: options.signal,
231
+ allowOutsideWorkspace: options.allowOutsideWorkspace,
232
+ planMode: mode === 'plan',
233
+ requestPermission: async () => 'allow',
234
+ setTodos,
235
+ getTodos: () => todos
236
+ };
237
+ return await tool.execute(call.arguments, context);
238
+ }
239
+ function buildPermissionRequest(call, tool) {
240
+ const path = typeof call.arguments.path === 'string' ? call.arguments.path : undefined;
241
+ const command = typeof call.arguments.command === 'string' ? call.arguments.command : undefined;
242
+ const url = typeof call.arguments.url === 'string' ? call.arguments.url : undefined;
243
+ let request;
244
+ if (tool.action === 'shell') {
245
+ const risk = riskyCommand(command ?? '') ? 'high' : 'medium';
246
+ request = {
247
+ action: 'shell',
248
+ title: 'Run shell command',
249
+ detail: command,
250
+ risk,
251
+ rule: command
252
+ };
253
+ }
254
+ else if (tool.action === 'write') {
255
+ request = {
256
+ action: 'write',
257
+ title: tool.name === 'edit' ? 'Edit file' : 'Write file',
258
+ detail: path,
259
+ risk: 'medium',
260
+ rule: path
261
+ };
262
+ }
263
+ else if (tool.action === 'fetch') {
264
+ request = { action: 'fetch', title: 'Fetch URL', detail: url, risk: 'low', rule: url };
265
+ }
266
+ else {
267
+ request = {
268
+ action: 'read',
269
+ title: tool.name === 'read' ? 'Read file' : tool.name,
270
+ detail: path ?? url ?? (typeof call.arguments.pattern === 'string' ? call.arguments.pattern : undefined),
271
+ risk: 'low',
272
+ rule: path
273
+ };
274
+ }
275
+ const custom = tool.permission?.(call.arguments);
276
+ return custom ? { ...request, ...custom } : request;
277
+ }
278
+ function riskyCommand(command) {
279
+ return /(\brm\s+-[a-z]*r|\bsudo\b|\bmkfs\b|\bdd\s+if=|\bgit\s+(reset\s+--hard|clean\s+-[a-z]*f)|\bcurl\b[^|]*\|\s*(ba)?sh|\bchmod\s+-R\s+777|\bkillall\b|\bshutdown\b|\breboot\b)/i.test(command);
280
+ }
281
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/core/agent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ import { findModel, providerById } from './catalog.js';
2
+ import { resolveSelection } from './provider.js';
3
+ /**
4
+ * Worker references are always `provider/model`. Model ids may themselves
5
+ * contain slashes, so only the first slash separates the two halves.
6
+ */
7
+ export function parseWorkerRef(reference) {
8
+ const trimmed = reference.trim();
9
+ const slash = trimmed.indexOf('/');
10
+ if (slash <= 0 || slash === trimmed.length - 1)
11
+ return undefined;
12
+ return {
13
+ provider: trimmed.slice(0, slash),
14
+ model: trimmed.slice(slash + 1)
15
+ };
16
+ }
17
+ export function workerLabel(worker) {
18
+ return `${worker.provider}/${worker.model}`;
19
+ }
20
+ /**
21
+ * Resolve every configured worker against the catalog and the user's saved
22
+ * credentials. One broken worker never blocks the rest of /agent mode.
23
+ */
24
+ export async function resolveAgentWorkers(catalog, config) {
25
+ const delegates = [];
26
+ const failures = [];
27
+ const seen = new Set();
28
+ for (const worker of config.agents.workers) {
29
+ const label = workerLabel(worker);
30
+ if (seen.has(label))
31
+ continue;
32
+ seen.add(label);
33
+ if (!providerById(catalog, worker.provider)) {
34
+ failures.push(`${label} — unknown provider`);
35
+ continue;
36
+ }
37
+ if (!findModel(catalog, worker.provider, worker.model)) {
38
+ failures.push(`${label} — model not in catalog`);
39
+ continue;
40
+ }
41
+ try {
42
+ const selection = await resolveSelection(catalog, config, {
43
+ provider: worker.provider,
44
+ model: worker.model
45
+ });
46
+ delegates.push({ provider: selection.provider, model: selection.model });
47
+ }
48
+ catch (error) {
49
+ const reason = error instanceof Error ? error.message : String(error);
50
+ failures.push(`${label} — ${reason}`);
51
+ }
52
+ }
53
+ return { delegates, failures };
54
+ }
55
+ //# sourceMappingURL=agents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/core/agents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAgB,MAAM,cAAc,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAGjD;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,SAAiB;IAC9C,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;IACjC,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,KAAK,OAAO,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IACjE,OAAO;QACL,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC;QACjC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC;KAChC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,MAAmB;IAC7C,OAAO,GAAG,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;AAC9C,CAAC;AAOD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,OAAgB,EAChB,MAAkB;IAElB,MAAM,SAAS,GAAoB,EAAE,CAAC;IACtC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QAC3C,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;QAClC,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,SAAS;QAC9B,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAChB,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5C,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,qBAAqB,CAAC,CAAC;YAC7C,SAAS;QACX,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YACvD,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,yBAAyB,CAAC,CAAC;YACjD,SAAS;QACX,CAAC;QACD,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,MAAM,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE;gBACxD,QAAQ,EAAE,MAAM,CAAC,QAAQ;gBACzB,KAAK,EAAE,MAAM,CAAC,KAAK;aACpB,CAAC,CAAC;YACH,SAAS,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,SAAS,CAAC,QAAQ,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC;QAC3E,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,MAAM,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACtE,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,MAAM,MAAM,EAAE,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;AACjC,CAAC"}
@@ -0,0 +1,107 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { z } from 'zod';
3
+ import { ensurePaths, getPaths, writeFileAtomic } from './paths.js';
4
+ const authSchema = z.object({
5
+ version: z.literal(1).default(1),
6
+ keys: z.record(z.string(), z.string()).default({})
7
+ });
8
+ const LOCAL_PROVIDERS = new Set(['ollama', 'llamacpp', 'vllm', 'lmstudio']);
9
+ let cached;
10
+ export async function loadAuth(force = false) {
11
+ const paths = getPaths();
12
+ let raw;
13
+ try {
14
+ raw = await readFile(paths.authFile, 'utf8');
15
+ }
16
+ catch (error) {
17
+ if (error.code === 'ENOENT') {
18
+ cached = { version: 1, keys: {} };
19
+ return cached;
20
+ }
21
+ throw error;
22
+ }
23
+ if (cached && !force)
24
+ return cached;
25
+ try {
26
+ const parsed = authSchema.safeParse(JSON.parse(raw));
27
+ if (!parsed.success)
28
+ throw new Error('invalid shape');
29
+ cached = parsed.data;
30
+ return cached;
31
+ }
32
+ catch {
33
+ throw new Error(`Could not parse auth file at ${paths.authFile}.`);
34
+ }
35
+ }
36
+ export async function saveProviderKey(providerId, key) {
37
+ await ensurePaths();
38
+ const auth = await loadAuth(true);
39
+ auth.keys[providerId] = key.trim();
40
+ await writeFileAtomic(getPaths().authFile, `${JSON.stringify(auth, null, 2)}\n`);
41
+ cached = auth;
42
+ }
43
+ export async function removeProviderKey(providerId) {
44
+ const paths = getPaths();
45
+ const auth = await loadAuth(true);
46
+ if (!(providerId in auth.keys))
47
+ return false;
48
+ delete auth.keys[providerId];
49
+ await writeFileAtomic(paths.authFile, `${JSON.stringify(auth, null, 2)}\n`);
50
+ cached = auth;
51
+ return true;
52
+ }
53
+ export async function getStoredKey(providerId) {
54
+ const auth = await loadAuth();
55
+ return auth.keys[providerId]?.trim() || undefined;
56
+ }
57
+ export function envKeyFor(provider) {
58
+ for (const name of provider.env) {
59
+ const value = process.env[name]?.trim();
60
+ if (value)
61
+ return value;
62
+ }
63
+ return undefined;
64
+ }
65
+ export function envNameFor(provider) {
66
+ for (const name of provider.env) {
67
+ if (process.env[name]?.trim())
68
+ return name;
69
+ }
70
+ return provider.env[0];
71
+ }
72
+ export function isKeylessProvider(provider) {
73
+ if (LOCAL_PROVIDERS.has(provider.id))
74
+ return true;
75
+ if (provider.local)
76
+ return true;
77
+ // OpenAI-compatible localhost servers often do not require a key.
78
+ return typeof provider.api === 'string' && /localhost|127\.0\.0\.1|0\.0\.0\.0/.test(provider.api);
79
+ }
80
+ export async function credentialStatus(providers, config) {
81
+ const auth = await loadAuth();
82
+ return providers.map((provider) => {
83
+ const settings = config.providers[provider.id] ?? config.customProviders[provider.id] ?? {};
84
+ const envName = envNameFor(provider);
85
+ if (settings?.apiKey?.trim()) {
86
+ return { provider, configured: true, source: 'config', envName, masked: mask(settings.apiKey) };
87
+ }
88
+ if (auth.keys[provider.id]?.trim()) {
89
+ return { provider, configured: true, source: 'auth', envName, masked: mask(auth.keys[provider.id]) };
90
+ }
91
+ const envValue = envKeyFor(provider);
92
+ if (envValue) {
93
+ return { provider, configured: true, source: 'env', envName, masked: mask(envValue) };
94
+ }
95
+ if (isKeylessProvider(provider) || settings?.keyless) {
96
+ return { provider, configured: true, source: 'keyless', envName };
97
+ }
98
+ return { provider, configured: false, envName };
99
+ });
100
+ }
101
+ export function mask(key) {
102
+ const trimmed = key.trim();
103
+ if (trimmed.length <= 8)
104
+ return '••••';
105
+ return `${trimmed.slice(0, 4)}…${trimmed.slice(-4)}`;
106
+ }
107
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/core/auth.ts"],"names":[],"mappings":"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"}