@ekzs/cli 0.2.0 → 0.3.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 (47) hide show
  1. package/README.md +21 -11
  2. package/dist/commands/agent.d.ts +0 -4
  3. package/dist/commands/agent.d.ts.map +1 -1
  4. package/dist/commands/agent.js +0 -6
  5. package/dist/commands/ask.d.ts +3 -5
  6. package/dist/commands/ask.d.ts.map +1 -1
  7. package/dist/commands/ask.js +36 -35
  8. package/dist/commands/local-agent.d.ts +0 -2
  9. package/dist/commands/local-agent.d.ts.map +1 -1
  10. package/dist/commands/local-agent.js +200 -125
  11. package/dist/commands/providers.d.ts +4 -0
  12. package/dist/commands/providers.d.ts.map +1 -0
  13. package/dist/commands/providers.js +6 -0
  14. package/dist/index.js +25 -20
  15. package/dist/lib/commands-i18n.d.ts +12 -1
  16. package/dist/lib/commands-i18n.d.ts.map +1 -1
  17. package/dist/lib/commands-i18n.js +69 -14
  18. package/dist/lib/composer-model.d.ts +1 -1
  19. package/dist/lib/composer-model.d.ts.map +1 -1
  20. package/dist/lib/composer-model.js +2 -2
  21. package/dist/lib/help.js +13 -12
  22. package/dist/lib/providers/agent-runner.d.ts +12 -0
  23. package/dist/lib/providers/agent-runner.d.ts.map +1 -0
  24. package/dist/lib/providers/agent-runner.js +167 -0
  25. package/dist/lib/providers/catalog.d.ts +15 -0
  26. package/dist/lib/providers/catalog.d.ts.map +1 -0
  27. package/dist/lib/providers/catalog.js +93 -0
  28. package/dist/lib/providers/chat.d.ts +10 -0
  29. package/dist/lib/providers/chat.d.ts.map +1 -0
  30. package/dist/lib/providers/chat.js +121 -0
  31. package/dist/lib/providers/credentials.d.ts +26 -0
  32. package/dist/lib/providers/credentials.d.ts.map +1 -0
  33. package/dist/lib/providers/credentials.js +54 -0
  34. package/dist/lib/providers/cursor-runner.d.ts +13 -0
  35. package/dist/lib/providers/cursor-runner.d.ts.map +1 -0
  36. package/dist/lib/providers/cursor-runner.js +87 -0
  37. package/dist/lib/providers/store.d.ts +21 -0
  38. package/dist/lib/providers/store.d.ts.map +1 -0
  39. package/dist/lib/providers/store.js +81 -0
  40. package/dist/lib/providers/tools.d.ts +80 -0
  41. package/dist/lib/providers/tools.d.ts.map +1 -0
  42. package/dist/lib/providers/tools.js +145 -0
  43. package/dist/lib/providers/ui.d.ts +4 -0
  44. package/dist/lib/providers/ui.d.ts.map +1 -0
  45. package/dist/lib/providers/ui.js +188 -0
  46. package/package.json +1 -1
  47. package/skills/ekz-sdk-cli/SKILL.md +6 -4
@@ -1,83 +1,84 @@
1
1
  import { resolve } from "path";
2
- import { Agent, AgentBusyError, CursorAgentError } from "@cursor/sdk";
2
+ import { Agent, CursorAgentError } from "@cursor/sdk";
3
3
  import { executeAskTurn } from "../commands/ask.js";
4
4
  import { runDoctor } from "../commands/doctor.js";
5
5
  import { runScan } from "../commands/scan.js";
6
6
  import { inputPlaceholder, printHelp, printLangSwitch, printModeSwitch, printWelcome } from "../lib/banner.js";
7
7
  import { loadProjectEnv } from "../lib/env.js";
8
- import { resolveReplMetaCommand } from "../lib/commands-i18n.js";
8
+ import { resolveReplMetaCommand, isProvidersMetaCommand } from "../lib/commands-i18n.js";
9
9
  import { buildAgentPrompt, buildBootstrapContext } from "../lib/context.js";
10
10
  import { resolveComposerModel } from "../lib/composer-model.js";
11
11
  import { parseLocale, uiStrings } from "../lib/locale.js";
12
12
  import { modeRequiresCursorAgent, parseMode } from "../lib/mode.js";
13
13
  import { loadPreferences, savePreferences } from "../lib/preferences.js";
14
+ import { runByokAgentTurn, usesCursorSdk } from "../lib/providers/agent-runner.js";
15
+ import { disposeAgent, streamRun } from "../lib/providers/cursor-runner.js";
16
+ import { getProviderDefinition } from "../lib/providers/catalog.js";
17
+ import { requireActiveCredentials, } from "../lib/providers/credentials.js";
18
+ import { runProvidersInteractive, formatActiveProviderLabel } from "../lib/providers/ui.js";
19
+ import { maskApiKey } from "../lib/providers/store.js";
14
20
  import { clearSession, getSessionByIndex, loadSession, persistSession, saveNamedSession, } from "../lib/session.js";
15
21
  import { fail, info, ok, warn } from "../lib/output.js";
16
- import { toolDone, toolError, toolRunning, turnDivider } from "../lib/theme.js";
22
+ import { turnDivider } from "../lib/theme.js";
17
23
  import { askWithPlaceholder, formatInputPrompt } from "../lib/ui/prompt.js";
18
- function getApiKey(override, cwd) {
19
- if (cwd)
20
- loadProjectEnv(cwd);
21
- else
22
- loadProjectEnv(process.cwd());
23
- const key = override ?? process.env.CURSOR_API_KEY?.trim();
24
- if (!key) {
25
- throw new Error("CURSOR_API_KEY required. Add it to .env.local or export it — https://cursor.com/dashboard/integrations");
24
+ function resolveAgentCredentials(override, locale = "pt") {
25
+ if (override?.trim()) {
26
+ const def = getProviderDefinition("cursor");
27
+ if (!def)
28
+ throw new Error("Cursor provider missing from catalog.");
29
+ return {
30
+ id: "cursor",
31
+ definition: def,
32
+ apiKey: override.trim(),
33
+ model: resolveComposerModel().id,
34
+ maskedKey: maskApiKey(override.trim()),
35
+ };
26
36
  }
27
- return key;
37
+ return requireActiveCredentials(locale);
28
38
  }
29
- async function disposeAgent(agent) {
30
- const disposer = agent[Symbol.asyncDispose];
31
- if (typeof disposer === "function")
32
- await disposer.call(agent);
33
- else
34
- agent.close();
39
+ function resolveCursorModel(creds) {
40
+ return resolveComposerModel(process.env, creds.model);
35
41
  }
36
- async function streamRun(agent, prompt, locale, opts) {
37
- const t = uiStrings(locale);
38
- const sendOptions = {
39
- onDelta: ({ update }) => {
40
- if (update.type === "text-delta" && update.text) {
41
- process.stdout.write(update.text);
42
- }
43
- },
44
- ...(opts?.force ? { local: { force: true } } : {}),
45
- };
46
- let run;
47
- try {
48
- run = await agent.send(prompt, sendOptions);
49
- }
50
- catch (err) {
51
- if (err instanceof AgentBusyError) {
52
- warn(t.busyRun);
53
- run = await agent.send(prompt, { ...sendOptions, local: { force: true } });
54
- }
55
- else {
56
- throw err;
57
- }
58
- }
59
- for await (const event of run.stream()) {
60
- if (event.type === "tool_call" && event.status === "running") {
61
- process.stdout.write(toolRunning(event.name));
42
+ function providerModelLabel(creds) {
43
+ if (usesCursorSdk(creds))
44
+ return resolveCursorModel(creds).label;
45
+ return `${creds.definition.name} · ${creds.model}`;
46
+ }
47
+ async function runAgentTurn(options) {
48
+ if (usesCursorSdk(options.creds)) {
49
+ if (!options.cursorAgent) {
50
+ fail(options.locale === "pt" ? "Sem agente Cursor activo." : "No active Cursor agent.");
51
+ return { cursorAgent: null, ok: false };
62
52
  }
63
- if (event.type === "tool_call" && event.status === "completed") {
64
- process.stdout.write(toolDone(event.name));
53
+ const ctx = await buildBootstrapContext(options.cwd);
54
+ const prompt = buildAgentPrompt(options.task, ctx, options.locale);
55
+ try {
56
+ await streamRun(options.cursorAgent, prompt);
57
+ console.log("\n");
58
+ return { cursorAgent: options.cursorAgent, ok: true };
65
59
  }
66
- if (event.type === "tool_call" && event.status === "error") {
67
- process.stdout.write(toolError(event.name));
60
+ catch (err) {
61
+ if (err instanceof CursorAgentError) {
62
+ fail(err.message);
63
+ return { cursorAgent: options.cursorAgent, ok: false };
64
+ }
65
+ throw err;
68
66
  }
69
67
  }
70
- const result = await run.wait();
71
- if (result.status === "error") {
72
- fail(`${t.agentFailed} (${result.id})`);
73
- process.exitCode = 2;
74
- }
75
- return { status: result.status, result: result.result };
68
+ const okResult = await runByokAgentTurn({
69
+ cwd: options.cwd,
70
+ task: options.task,
71
+ creds: options.creds,
72
+ locale: options.locale,
73
+ mode: options.mode,
74
+ });
75
+ return { cursorAgent: options.cursorAgent, ok: okResult };
76
76
  }
77
- async function createOrResumeAgent(opts) {
77
+ async function createOrResumeAgent(opts, locale = "pt") {
78
78
  const cwd = resolve(opts.cwd);
79
- const apiKey = getApiKey(opts.apiKey, cwd);
80
- const model = resolveComposerModel();
79
+ const creds = resolveAgentCredentials(opts.apiKey, locale);
80
+ const apiKey = creds.apiKey;
81
+ const model = resolveCursorModel(creds);
81
82
  const usePlan = opts.mode === "plan" || Boolean(opts.plan);
82
83
  if (opts.fresh)
83
84
  clearSession(cwd);
@@ -100,9 +101,12 @@ async function createOrResumeAgent(opts) {
100
101
  });
101
102
  return { agent, resumed: false };
102
103
  }
103
- async function recreateAgentForMode(cwd, current, mode, apiKey) {
104
+ async function recreateAgentForMode(cwd, current, mode, apiKey, locale = "pt") {
104
105
  if (!modeRequiresCursorAgent(mode))
105
106
  return null;
107
+ const creds = resolveAgentCredentials(apiKey, locale);
108
+ if (!usesCursorSdk(creds))
109
+ return null;
106
110
  if (current)
107
111
  await disposeAgent(current);
108
112
  const { agent } = await createOrResumeAgent({
@@ -111,12 +115,12 @@ async function recreateAgentForMode(cwd, current, mode, apiKey) {
111
115
  fresh: true,
112
116
  mode,
113
117
  apiKey,
114
- });
118
+ }, locale);
115
119
  await persistAgent(cwd, agent);
116
120
  return agent;
117
121
  }
118
- async function persistAgent(cwd, agent) {
119
- const model = resolveComposerModel();
122
+ async function persistAgent(cwd, agent, creds) {
123
+ const model = creds ? resolveCursorModel(creds) : resolveComposerModel();
120
124
  persistSession(cwd, {
121
125
  agentId: agent.agentId,
122
126
  cwd: resolve(cwd),
@@ -180,37 +184,52 @@ function handleMetaCommand(line, locale, cwd, currentMode) {
180
184
  }
181
185
  return null;
182
186
  }
183
- async function resumeAgentInRepl(cwd, current, agentId, locale) {
187
+ async function resumeAgentInRepl(cwd, current, agentId, locale, apiKeyOverride) {
184
188
  if (current)
185
189
  await disposeAgent(current);
186
- const apiKey = getApiKey(undefined, cwd);
187
- const model = resolveComposerModel();
190
+ const creds = resolveAgentCredentials(apiKeyOverride, locale);
191
+ if (!usesCursorSdk(creds)) {
192
+ throw new Error(locale === "pt"
193
+ ? "Retomar sessão só com provider Cursor."
194
+ : locale === "zh"
195
+ ? "恢复会话仅适用于 Cursor provider。"
196
+ : "Resume session is Cursor-only.");
197
+ }
198
+ const model = resolveCursorModel(creds);
188
199
  const agent = await Agent.resume(agentId, {
189
- apiKey,
200
+ apiKey: creds.apiKey,
190
201
  model: { id: model.id, params: model.params },
191
202
  local: { cwd: resolve(cwd), settingSources: ["project"] },
192
203
  });
193
- await persistAgent(cwd, agent);
204
+ await persistAgent(cwd, agent, creds);
194
205
  ok(locale === "pt" ? "Sessão retomada." : "Session resumed.");
195
206
  return agent;
196
207
  }
197
208
  export async function runLocalAgent(opts) {
198
209
  const cwd = resolve(opts.cwd);
199
210
  loadProjectEnv(cwd);
200
- const model = resolveComposerModel();
201
211
  const prefs = loadPreferences(cwd, opts.locale, opts.mode, opts.plan);
202
212
  const mode = prefs.mode;
213
+ const providerLabel = formatActiveProviderLabel(prefs.locale);
203
214
  if (mode === "ask") {
204
- printWelcome({ cwd, locale: prefs.locale, mode: "ask" });
215
+ let askCreds;
216
+ try {
217
+ askCreds = resolveAgentCredentials(opts.apiKey, prefs.locale);
218
+ }
219
+ catch (err) {
220
+ fail(err instanceof Error ? err.message : String(err));
221
+ process.exitCode = 1;
222
+ return;
223
+ }
224
+ printWelcome({ cwd, locale: prefs.locale, mode: "ask", model: providerLabel });
205
225
  if (opts.task.trim()) {
206
226
  info(`${uiStrings(prefs.locale).workingOn}: ${opts.task.slice(0, 120)}${opts.task.length > 120 ? "…" : ""}\n`);
207
227
  await executeAskTurn({
208
228
  cwd,
209
229
  question: opts.task.trim(),
210
- apiKey: opts.askApiKey,
211
- apiUrl: opts.askApiUrl,
212
230
  offline: opts.askOffline,
213
231
  quiet: true,
232
+ locale: prefs.locale,
214
233
  });
215
234
  console.log("");
216
235
  }
@@ -221,17 +240,20 @@ export async function runLocalAgent(opts) {
221
240
  locale: prefs.locale,
222
241
  mode: "ask",
223
242
  apiKey: opts.apiKey,
224
- askApiKey: opts.askApiKey,
225
- askApiUrl: opts.askApiUrl,
226
243
  askOffline: opts.askOffline,
244
+ creds: askCreds,
227
245
  });
228
246
  }
229
247
  return;
230
248
  }
231
- let agent;
249
+ let agent = null;
232
250
  let resumed = false;
251
+ let creds;
233
252
  try {
234
- ({ agent, resumed } = await createOrResumeAgent({ ...opts, mode }));
253
+ creds = resolveAgentCredentials(opts.apiKey, prefs.locale);
254
+ if (usesCursorSdk(creds)) {
255
+ ({ agent, resumed } = await createOrResumeAgent({ ...opts, mode }, prefs.locale));
256
+ }
235
257
  }
236
258
  catch (err) {
237
259
  if (err instanceof CursorAgentError) {
@@ -239,26 +261,36 @@ export async function runLocalAgent(opts) {
239
261
  process.exitCode = 1;
240
262
  return;
241
263
  }
242
- throw err;
264
+ fail(err instanceof Error ? err.message : String(err));
265
+ process.exitCode = 1;
266
+ return;
243
267
  }
244
268
  printWelcome({
245
269
  cwd,
246
- model: model.label,
270
+ model: providerModelLabel(creds),
247
271
  locale: prefs.locale,
248
272
  mode,
249
273
  resumed,
250
- agentId: agent.agentId,
274
+ agentId: agent?.agentId,
251
275
  });
252
- await persistAgent(cwd, agent);
276
+ if (agent)
277
+ await persistAgent(cwd, agent, creds);
253
278
  savePreferences(cwd, { mode });
254
- const bootstrap = await buildBootstrapContext(cwd);
255
- const prompt = buildAgentPrompt(opts.task, bootstrap, prefs.locale);
256
279
  const t = uiStrings(prefs.locale);
257
280
  try {
258
281
  info(`${t.workingOn}: ${opts.task.slice(0, 120)}${opts.task.length > 120 ? "…" : ""}\n`);
259
- const outcome = await streamRun(agent, prompt, prefs.locale);
260
- console.log("\n");
261
- ok(`${t.done} (${outcome.status})`);
282
+ const outcome = await runAgentTurn({
283
+ cwd,
284
+ task: opts.task,
285
+ creds,
286
+ locale: prefs.locale,
287
+ mode,
288
+ cursorAgent: agent,
289
+ });
290
+ if (outcome.ok)
291
+ ok(t.done);
292
+ if (outcome.cursorAgent)
293
+ agent = outcome.cursorAgent;
262
294
  if (opts.interactive !== false) {
263
295
  await runRepl({
264
296
  agent,
@@ -266,9 +298,8 @@ export async function runLocalAgent(opts) {
266
298
  locale: prefs.locale,
267
299
  mode,
268
300
  apiKey: opts.apiKey,
269
- askApiKey: opts.askApiKey,
270
- askApiUrl: opts.askApiUrl,
271
301
  askOffline: opts.askOffline,
302
+ creds,
272
303
  });
273
304
  }
274
305
  else {
@@ -276,33 +307,46 @@ export async function runLocalAgent(opts) {
276
307
  }
277
308
  }
278
309
  finally {
279
- await disposeAgent(agent);
310
+ if (agent)
311
+ await disposeAgent(agent);
280
312
  }
281
313
  }
282
314
  export async function runInteractiveAgent(opts) {
283
315
  const cwd = resolve(opts.cwd);
284
316
  loadProjectEnv(cwd);
285
- const model = resolveComposerModel();
286
317
  const prefs = loadPreferences(cwd, opts.locale, opts.mode, opts.plan);
287
318
  const mode = prefs.mode;
319
+ const providerLabel = formatActiveProviderLabel(prefs.locale);
288
320
  if (mode === "ask") {
289
- printWelcome({ cwd, locale: prefs.locale, mode: "ask" });
321
+ let creds;
322
+ try {
323
+ creds = resolveAgentCredentials(opts.apiKey, prefs.locale);
324
+ }
325
+ catch (err) {
326
+ fail(err instanceof Error ? err.message : String(err));
327
+ process.exitCode = 1;
328
+ return;
329
+ }
330
+ printWelcome({ cwd, locale: prefs.locale, mode: "ask", model: providerLabel });
290
331
  await runRepl({
291
332
  agent: null,
292
333
  cwd,
293
334
  locale: prefs.locale,
294
335
  mode: "ask",
295
336
  apiKey: opts.apiKey,
296
- askApiKey: opts.askApiKey,
297
- askApiUrl: opts.askApiUrl,
298
337
  askOffline: opts.askOffline,
338
+ creds,
299
339
  });
300
340
  return;
301
341
  }
302
- let agent;
342
+ let agent = null;
303
343
  let resumed = false;
344
+ let creds;
304
345
  try {
305
- ({ agent, resumed } = await createOrResumeAgent({ ...opts, task: "", mode }));
346
+ creds = resolveAgentCredentials(opts.apiKey, prefs.locale);
347
+ if (usesCursorSdk(creds)) {
348
+ ({ agent, resumed } = await createOrResumeAgent({ ...opts, task: "", mode }, prefs.locale));
349
+ }
306
350
  }
307
351
  catch (err) {
308
352
  if (err instanceof CursorAgentError) {
@@ -310,17 +354,20 @@ export async function runInteractiveAgent(opts) {
310
354
  process.exitCode = 1;
311
355
  return;
312
356
  }
313
- throw err;
357
+ fail(err instanceof Error ? err.message : String(err));
358
+ process.exitCode = 1;
359
+ return;
314
360
  }
315
361
  printWelcome({
316
362
  cwd,
317
- model: model.label,
363
+ model: providerModelLabel(creds),
318
364
  locale: prefs.locale,
319
365
  mode,
320
366
  resumed,
321
- agentId: agent.agentId,
367
+ agentId: agent?.agentId,
322
368
  });
323
- await persistAgent(cwd, agent);
369
+ if (agent)
370
+ await persistAgent(cwd, agent, creds);
324
371
  savePreferences(cwd, { mode });
325
372
  try {
326
373
  await runRepl({
@@ -329,21 +376,31 @@ export async function runInteractiveAgent(opts) {
329
376
  locale: prefs.locale,
330
377
  mode,
331
378
  apiKey: opts.apiKey,
332
- askApiKey: opts.askApiKey,
333
- askApiUrl: opts.askApiUrl,
334
379
  askOffline: opts.askOffline,
380
+ creds,
335
381
  });
336
382
  }
337
383
  finally {
338
- await disposeAgent(agent);
384
+ if (agent)
385
+ await disposeAgent(agent);
339
386
  }
340
387
  }
341
388
  async function runRepl(opts) {
342
389
  let currentLocale = opts.locale;
343
390
  let currentMode = opts.mode;
344
391
  let currentAgent = opts.agent;
392
+ let currentCreds = opts.creds;
345
393
  let turn = 0;
346
394
  const t = () => uiStrings(currentLocale);
395
+ const resolveCreds = () => {
396
+ try {
397
+ currentCreds = resolveAgentCredentials(opts.apiKey, currentLocale);
398
+ }
399
+ catch {
400
+ /* keep previous */
401
+ }
402
+ return currentCreds;
403
+ };
347
404
  while (true) {
348
405
  const line = (await askWithPlaceholder({
349
406
  prompt: formatInputPrompt(),
@@ -351,6 +408,11 @@ async function runRepl(opts) {
351
408
  })).trim();
352
409
  if (!line || line === "exit" || line === "quit" || line === "sair" || line === "退出")
353
410
  break;
411
+ if (isProvidersMetaCommand(line.trim().split(/\s+/)[0] ?? "")) {
412
+ await runProvidersInteractive(currentLocale);
413
+ resolveCreds();
414
+ continue;
415
+ }
354
416
  const meta = handleMetaCommand(line, currentLocale, opts.cwd, currentMode);
355
417
  if (meta?.kind === "handled")
356
418
  continue;
@@ -369,7 +431,14 @@ async function runRepl(opts) {
369
431
  }
370
432
  }
371
433
  else {
372
- currentAgent = await recreateAgentForMode(opts.cwd, currentAgent, currentMode, opts.apiKey);
434
+ const creds = resolveCreds();
435
+ if (usesCursorSdk(creds)) {
436
+ currentAgent = await recreateAgentForMode(opts.cwd, currentAgent, currentMode, opts.apiKey, currentLocale);
437
+ }
438
+ else if (currentAgent) {
439
+ await disposeAgent(currentAgent);
440
+ currentAgent = null;
441
+ }
373
442
  }
374
443
  }
375
444
  catch (err) {
@@ -378,8 +447,12 @@ async function runRepl(opts) {
378
447
  continue;
379
448
  }
380
449
  if (meta?.kind === "resume") {
381
- if (currentMode === "ask") {
382
- warn(currentLocale === "pt" ? "Sessões Cursor só em modo agent/plan." : "Cursor sessions only in agent/plan mode.");
450
+ if (currentMode === "ask" || !usesCursorSdk(resolveCreds())) {
451
+ warn(currentLocale === "pt"
452
+ ? "Sessões guardadas só com provider Cursor."
453
+ : currentLocale === "zh"
454
+ ? "保存的会话仅适用于 Cursor。"
455
+ : "Saved sessions are Cursor-only.");
383
456
  continue;
384
457
  }
385
458
  try {
@@ -387,7 +460,7 @@ async function runRepl(opts) {
387
460
  fail(currentLocale === "pt" ? "Sem agente activo." : "No active agent.");
388
461
  continue;
389
462
  }
390
- currentAgent = await resumeAgentInRepl(opts.cwd, currentAgent, meta.agentId, currentLocale);
463
+ currentAgent = await resumeAgentInRepl(opts.cwd, currentAgent, meta.agentId, currentLocale, opts.apiKey);
391
464
  }
392
465
  catch (err) {
393
466
  fail(err instanceof Error ? err.message : String(err));
@@ -395,8 +468,12 @@ async function runRepl(opts) {
395
468
  continue;
396
469
  }
397
470
  if (meta?.kind === "save") {
398
- if (!currentAgent) {
399
- warn(currentLocale === "pt" ? "Guardar sessão só em modo agent/plan." : "Save session only in agent/plan mode.");
471
+ if (!currentAgent || !usesCursorSdk(resolveCreds())) {
472
+ warn(currentLocale === "pt"
473
+ ? "Guardar sessão só com provider Cursor."
474
+ : currentLocale === "zh"
475
+ ? "保存会话仅适用于 Cursor。"
476
+ : "Save session is Cursor-only.");
400
477
  continue;
401
478
  }
402
479
  const model = resolveComposerModel();
@@ -415,35 +492,33 @@ async function runRepl(opts) {
415
492
  await executeAskTurn({
416
493
  cwd: opts.cwd,
417
494
  question: line,
418
- apiKey: opts.askApiKey,
419
- apiUrl: opts.askApiUrl,
420
495
  offline: opts.askOffline,
421
496
  quiet: true,
497
+ locale: currentLocale,
422
498
  });
423
499
  console.log("\n");
424
500
  turn++;
425
501
  continue;
426
502
  }
427
- if (!currentAgent) {
428
- fail(currentLocale === "pt" ? "Sem agente activo." : "No active agent.");
503
+ const creds = resolveCreds();
504
+ if (usesCursorSdk(creds) && !currentAgent) {
505
+ fail(currentLocale === "pt" ? "Sem agente Cursor activo." : "No active Cursor agent.");
429
506
  continue;
430
507
  }
431
- await persistAgent(opts.cwd, currentAgent);
432
- const ctx = await buildBootstrapContext(opts.cwd);
433
- const prompt = buildAgentPrompt(line, ctx, currentLocale);
434
- try {
435
- await streamRun(currentAgent, prompt, currentLocale);
436
- }
437
- catch (err) {
438
- if (err instanceof CursorAgentError) {
439
- fail(err.message);
440
- turn++;
441
- continue;
442
- }
443
- throw err;
444
- }
445
- console.log("\n");
446
- await persistAgent(opts.cwd, currentAgent);
508
+ if (currentAgent)
509
+ await persistAgent(opts.cwd, currentAgent, creds);
510
+ const outcome = await runAgentTurn({
511
+ cwd: opts.cwd,
512
+ task: line,
513
+ creds,
514
+ locale: currentLocale,
515
+ mode: currentMode,
516
+ cursorAgent: currentAgent,
517
+ });
518
+ if (outcome.cursorAgent)
519
+ currentAgent = outcome.cursorAgent;
520
+ if (currentAgent)
521
+ await persistAgent(opts.cwd, currentAgent, creds);
447
522
  turn++;
448
523
  }
449
524
  ok(t().goodbye);
@@ -0,0 +1,4 @@
1
+ export declare function runProvidersCommand(opts: {
2
+ locale?: string;
3
+ }): Promise<void>;
4
+ //# sourceMappingURL=providers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../../src/commands/providers.ts"],"names":[],"mappings":"AAGA,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,iBAGlE"}
@@ -0,0 +1,6 @@
1
+ import { parseLocale } from "../lib/locale.js";
2
+ import { runProvidersInteractive } from "../lib/providers/ui.js";
3
+ export async function runProvidersCommand(opts) {
4
+ const locale = parseLocale(opts.locale) ?? "pt";
5
+ await runProvidersInteractive(locale);
6
+ }