@ekzs/cli 0.3.0 → 0.3.4

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 (49) hide show
  1. package/README.md +31 -5
  2. package/dist/commands/ask.d.ts.map +1 -1
  3. package/dist/commands/ask.js +16 -3
  4. package/dist/commands/local-agent.d.ts.map +1 -1
  5. package/dist/commands/local-agent.js +146 -60
  6. package/dist/commands/setup.d.ts +5 -0
  7. package/dist/commands/setup.d.ts.map +1 -0
  8. package/dist/commands/setup.js +4 -0
  9. package/dist/index.js +18 -1
  10. package/dist/lib/commands-i18n.d.ts +2 -2
  11. package/dist/lib/commands-i18n.d.ts.map +1 -1
  12. package/dist/lib/commands-i18n.js +21 -12
  13. package/dist/lib/global-config.d.ts +19 -0
  14. package/dist/lib/global-config.d.ts.map +1 -0
  15. package/dist/lib/global-config.js +52 -0
  16. package/dist/lib/help.d.ts.map +1 -1
  17. package/dist/lib/help.js +3 -0
  18. package/dist/lib/locale.d.ts.map +1 -1
  19. package/dist/lib/locale.js +2 -1
  20. package/dist/lib/onboarding.d.ts +20 -0
  21. package/dist/lib/onboarding.d.ts.map +1 -0
  22. package/dist/lib/onboarding.js +129 -0
  23. package/dist/lib/providers/catalog.d.ts +5 -0
  24. package/dist/lib/providers/catalog.d.ts.map +1 -1
  25. package/dist/lib/providers/catalog.js +34 -1
  26. package/dist/lib/providers/credentials.d.ts +2 -0
  27. package/dist/lib/providers/credentials.d.ts.map +1 -1
  28. package/dist/lib/providers/credentials.js +19 -3
  29. package/dist/lib/providers/cursor-runner.d.ts +2 -2
  30. package/dist/lib/providers/cursor-runner.d.ts.map +1 -1
  31. package/dist/lib/providers/cursor-runner.js +7 -5
  32. package/dist/lib/providers/cursor-sdk.d.ts +8 -0
  33. package/dist/lib/providers/cursor-sdk.d.ts.map +1 -0
  34. package/dist/lib/providers/cursor-sdk.js +25 -0
  35. package/dist/lib/providers/store.d.ts +1 -1
  36. package/dist/lib/providers/store.d.ts.map +1 -1
  37. package/dist/lib/providers/store.js +13 -7
  38. package/dist/lib/providers/ui.d.ts +2 -0
  39. package/dist/lib/providers/ui.d.ts.map +1 -1
  40. package/dist/lib/providers/ui.js +60 -24
  41. package/dist/lib/setup-messages.d.ts +4 -0
  42. package/dist/lib/setup-messages.d.ts.map +1 -0
  43. package/dist/lib/setup-messages.js +13 -0
  44. package/dist/lib/ui/splash.d.ts.map +1 -1
  45. package/dist/lib/ui/splash.js +4 -0
  46. package/dist/lib/version.d.ts +2 -0
  47. package/dist/lib/version.d.ts.map +1 -0
  48. package/dist/lib/version.js +13 -0
  49. package/package.json +10 -2
@@ -1,3 +1,4 @@
1
+ import { formatSetupRequiredMessage } from "./setup-messages.js";
1
2
  export function providersCommandLabels(locale) {
2
3
  if (locale === "pt") {
3
4
  return {
@@ -22,15 +23,8 @@ export function providersCommandLabels(locale) {
22
23
  replAliases: ["/provider"],
23
24
  };
24
25
  }
25
- export function providersSetupHint(locale) {
26
- const labels = providersCommandLabels(locale);
27
- if (locale === "pt") {
28
- return `Nenhum provider activo. Corre \`${labels.cli}\` ou \`${labels.repl}\` e cola a tua API key.`;
29
- }
30
- if (locale === "zh") {
31
- return `未配置 provider。运行 \`${labels.cli}\` 或 \`${labels.repl}\` 并粘贴 API key。`;
32
- }
33
- return `No active provider. Run \`${labels.cli}\` or \`${labels.repl}\` and paste your API key.`;
26
+ export function providersSetupHint(_locale) {
27
+ return formatSetupRequiredMessage();
34
28
  }
35
29
  export function isProvidersMetaCommand(token) {
36
30
  return resolveReplMetaCommand(token) === "providers";
@@ -44,6 +38,7 @@ const EN_SUBCOMMANDS = new Set([
44
38
  "fix",
45
39
  "ask",
46
40
  "providers",
41
+ "setup",
47
42
  ]);
48
43
  /** Map localized CLI tokens (and English) to canonical subcommand ids. */
49
44
  const CLI_ALIASES = {
@@ -76,6 +71,12 @@ const CLI_ALIASES = {
76
71
  供应商: "providers",
77
72
  提供商: "providers",
78
73
  模型: "providers",
74
+ setup: "setup",
75
+ configurar: "setup",
76
+ configuracao: "setup",
77
+ "configuração": "setup",
78
+ 设置: "setup",
79
+ 配置: "setup",
79
80
  诊断: "doctor",
80
81
  凭证: "health",
81
82
  扫描: "scan",
@@ -104,6 +105,7 @@ export const SPLASH_TOOLS = {
104
105
  { label: "agente", hint: "agent" },
105
106
  { label: "perguntar", hint: "ask" },
106
107
  { label: "provedores", hint: "BYOK" },
108
+ { label: "setup", hint: "configurar" },
107
109
  ],
108
110
  en: [
109
111
  { label: "doctor" },
@@ -114,6 +116,7 @@ export const SPLASH_TOOLS = {
114
116
  { label: "agent" },
115
117
  { label: "ask" },
116
118
  { label: "providers", hint: "BYOK" },
119
+ { label: "setup" },
117
120
  ],
118
121
  zh: [
119
122
  { label: "诊断", hint: "doctor" },
@@ -124,6 +127,7 @@ export const SPLASH_TOOLS = {
124
127
  { label: "代理", hint: "agent" },
125
128
  { label: "问答", hint: "ask" },
126
129
  { label: "供应商", hint: "BYOK" },
130
+ { label: "设置", hint: "setup" },
127
131
  ],
128
132
  };
129
133
  export function formatSplashTool(locale, tool) {
@@ -137,14 +141,19 @@ export function formatCliToolsSummary(locale) {
137
141
  }
138
142
  export function splashSessionLines(locale) {
139
143
  const p = providersCommandLabels(locale);
144
+ const setupLine = locale === "pt"
145
+ ? "ekz setup · ekz configurar"
146
+ : locale === "zh"
147
+ ? "ekz setup · ekz 设置"
148
+ : "ekz setup";
140
149
  const providersLine = `${p.repl} · ${p.cli}`;
141
150
  if (locale === "pt") {
142
- return [providersLine, "/guardar <nome>", "/retomar · /retomar 2", "ekz --resume", "ekz --fresh"];
151
+ return [setupLine, providersLine, "/guardar <nome>", "/retomar · /retomar 2", "ekz --resume", "ekz --fresh"];
143
152
  }
144
153
  if (locale === "zh") {
145
- return [providersLine, "/保存 <名称>", "/恢复 · /恢复 2", "ekz --resume", "ekz --fresh"];
154
+ return [setupLine, providersLine, "/保存 <名称>", "/恢复 · /恢复 2", "ekz --resume", "ekz --fresh"];
146
155
  }
147
- return [providersLine, "/save <name>", "/resume · /resume 2", "ekz --resume", "ekz --fresh"];
156
+ return [setupLine, providersLine, "/save <name>", "/resume · /resume 2", "ekz --resume", "ekz --fresh"];
148
157
  }
149
158
  export function splashHelpHint(locale) {
150
159
  if (locale === "pt")
@@ -0,0 +1,19 @@
1
+ import type { EkzLocale } from "./locale.js";
2
+ export type EkzGlobalConfig = {
3
+ locale?: EkzLocale;
4
+ userName?: string;
5
+ /** User chose offline mode (no LLM provider). */
6
+ offline?: boolean;
7
+ setupComplete?: boolean;
8
+ };
9
+ export declare function globalConfigPath(): string;
10
+ export declare function loadGlobalConfig(): EkzGlobalConfig;
11
+ export declare function saveGlobalConfig(patch: Partial<EkzGlobalConfig>): void;
12
+ export declare function getGlobalLocale(): EkzLocale | undefined;
13
+ export declare function getGlobalUserName(): string | undefined;
14
+ export declare function isGlobalOffline(): boolean;
15
+ export declare function setGlobalOffline(offline: boolean): void;
16
+ export declare function clearGlobalOffline(): void;
17
+ export declare function isSetupComplete(): boolean;
18
+ export declare function markSetupComplete(): void;
19
+ //# sourceMappingURL=global-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"global-config.d.ts","sourceRoot":"","sources":["../../src/lib/global-config.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAK7C,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AAMF,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED,wBAAgB,gBAAgB,IAAI,eAAe,CAQlD;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC,eAAe,CAAC,QAI/D;AAED,wBAAgB,eAAe,IAAI,SAAS,GAAG,SAAS,CAGvD;AAED,wBAAgB,iBAAiB,IAAI,MAAM,GAAG,SAAS,CAEtD;AAED,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,QAEhD;AAED,wBAAgB,kBAAkB,SAGjC;AAED,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAED,wBAAgB,iBAAiB,SAEhC"}
@@ -0,0 +1,52 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
2
+ import { homedir } from "os";
3
+ import { join } from "path";
4
+ const EKZ_HOME = join(homedir(), ".ekz");
5
+ const CONFIG_PATH = join(EKZ_HOME, "config.json");
6
+ function ensureEkzHome() {
7
+ if (!existsSync(EKZ_HOME))
8
+ mkdirSync(EKZ_HOME, { recursive: true, mode: 0o700 });
9
+ }
10
+ export function globalConfigPath() {
11
+ return CONFIG_PATH;
12
+ }
13
+ export function loadGlobalConfig() {
14
+ ensureEkzHome();
15
+ if (!existsSync(CONFIG_PATH))
16
+ return {};
17
+ try {
18
+ return JSON.parse(readFileSync(CONFIG_PATH, "utf8"));
19
+ }
20
+ catch {
21
+ return {};
22
+ }
23
+ }
24
+ export function saveGlobalConfig(patch) {
25
+ ensureEkzHome();
26
+ const next = { ...loadGlobalConfig(), ...patch };
27
+ writeFileSync(CONFIG_PATH, JSON.stringify(next, null, 2) + "\n", { mode: 0o600 });
28
+ }
29
+ export function getGlobalLocale() {
30
+ const l = loadGlobalConfig().locale;
31
+ return l === "pt" || l === "en" || l === "zh" ? l : undefined;
32
+ }
33
+ export function getGlobalUserName() {
34
+ return loadGlobalConfig().userName?.trim() || undefined;
35
+ }
36
+ export function isGlobalOffline() {
37
+ return loadGlobalConfig().offline === true;
38
+ }
39
+ export function setGlobalOffline(offline) {
40
+ saveGlobalConfig({ offline, setupComplete: true });
41
+ }
42
+ export function clearGlobalOffline() {
43
+ const cfg = loadGlobalConfig();
44
+ if (cfg.offline)
45
+ saveGlobalConfig({ offline: false });
46
+ }
47
+ export function isSetupComplete() {
48
+ return loadGlobalConfig().setupComplete === true;
49
+ }
50
+ export function markSetupComplete() {
51
+ saveGlobalConfig({ setupComplete: true });
52
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../src/lib/help.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,EAAe,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AAGtD,KAAK,WAAW,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAatD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,WAAW,CAAC,EAAE,OAAO,GAAG,WAAW,EAAE,CA4HzF;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,WAAW,CAAC,EAAE,OAAO,QAezE"}
1
+ {"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../src/lib/help.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,EAAe,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AAGtD,KAAK,WAAW,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAatD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,WAAW,CAAC,EAAE,OAAO,GAAG,WAAW,EAAE,CA+HzF;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,WAAW,CAAC,EAAE,OAAO,QAezE"}
package/dist/lib/help.js CHANGED
@@ -44,6 +44,7 @@ export function buildHelpSections(locale, currentMode) {
44
44
  ? [
45
45
  "Escreve perguntas ou tarefas em linguagem natural.",
46
46
  `${p.repl} · ${p.cli} (BYOK)`,
47
+ "ekz setup · ekz configurar",
47
48
  "/ajuda · /help",
48
49
  "/modo agente|plan|ask · /mode agent|plan|ask",
49
50
  "/idioma pt · /lang pt|en|zh",
@@ -55,6 +56,7 @@ export function buildHelpSections(locale, currentMode) {
55
56
  ? [
56
57
  "用自然语言提问或描述任务。",
57
58
  `${p.repl} · ${p.cli} (BYOK)`,
59
+ "ekz setup · ekz 设置",
58
60
  "/帮助 · /help · /ajuda",
59
61
  "/模式 代理|plan|ask · /mode agent|plan|ask",
60
62
  "/语言 pt · /lang pt|en|zh",
@@ -65,6 +67,7 @@ export function buildHelpSections(locale, currentMode) {
65
67
  : [
66
68
  "Type questions or tasks in natural language.",
67
69
  `${p.repl} · ${p.cli} (BYOK)`,
70
+ "ekz setup",
68
71
  "/help · /ajuda · /帮助",
69
72
  "/mode agent|plan|ask",
70
73
  "/lang pt · /lang en · /lang zh",
@@ -1 +1 @@
1
- {"version":3,"file":"locale.d.ts","sourceRoot":"","sources":["../../src/lib/locale.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE3C,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAInD,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAIlD,CAAC;AAEF,wBAAgB,WAAW,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAOnE;AAED,sEAAsE;AACtE,wBAAgB,aAAa,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,CAAC,EAAE,SAAS,GAAG,IAAI,GAAG,SAAS,CAE3F;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAgB7D;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,SAAS;;;;;;;;;;;;;;;;;;;sBAqBnB,MAAM;;;;;;;;;;EA4H7B"}
1
+ {"version":3,"file":"locale.d.ts","sourceRoot":"","sources":["../../src/lib/locale.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE3C,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAInD,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAIlD,CAAC;AAEF,wBAAgB,WAAW,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAOnE;AAED,sEAAsE;AACtE,wBAAgB,aAAa,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,CAAC,EAAE,SAAS,GAAG,IAAI,GAAG,SAAS,CAE3F;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAgB7D;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,SAAS;;;;;;;;;;;;;;;;;;;sBAqBnB,MAAM;;;;;;;;;;EA4H7B"}
@@ -1,3 +1,4 @@
1
+ import { getGlobalLocale } from "./global-config.js";
1
2
  export const LOCALE_LABELS = {
2
3
  pt: "Português (Angola)",
3
4
  en: "English",
@@ -22,7 +23,7 @@ export function parseLocale(input) {
22
23
  }
23
24
  /** Default: Portuguese (Angola). Override with EKZ_LANG or --lang. */
24
25
  export function resolveLocale(explicit, saved) {
25
- return parseLocale(explicit) ?? parseLocale(process.env.EKZ_LANG) ?? saved ?? "pt";
26
+ return parseLocale(explicit) ?? parseLocale(process.env.EKZ_LANG) ?? saved ?? getGlobalLocale() ?? "pt";
26
27
  }
27
28
  export function languageInstruction(locale) {
28
29
  if (locale === "pt") {
@@ -0,0 +1,20 @@
1
+ import { type EkzLocale } from "./locale.js";
2
+ import { type ResolvedCredentials } from "./providers/credentials.js";
3
+ export type AgentReadyState = {
4
+ offline: boolean;
5
+ creds: ResolvedCredentials | null;
6
+ };
7
+ export declare function offlineModelLabel(locale: EkzLocale): string;
8
+ /** Full first-run wizard: language → name → provider/offline. */
9
+ export declare function runSetupWizard(opts?: {
10
+ locale?: string;
11
+ force?: boolean;
12
+ }): Promise<void>;
13
+ /** Ensures the agent can start — provider, offline, or throws setup hint. */
14
+ export declare function ensureAgentReady(options: {
15
+ locale: EkzLocale;
16
+ offlineFlag?: boolean;
17
+ apiKey?: string;
18
+ }): Promise<AgentReadyState>;
19
+ export declare function offlineAgentHint(locale: EkzLocale): string;
20
+ //# sourceMappingURL=onboarding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"onboarding.d.ts","sourceRoot":"","sources":["../../src/lib/onboarding.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,KAAK,SAAS,EAAe,MAAM,aAAa,CAAC;AAG1D,OAAO,EAIL,KAAK,mBAAmB,EACzB,MAAM,4BAA4B,CAAC;AAyBpC,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,mBAAmB,GAAG,IAAI,CAAC;CACnC,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAI3D;AAoFD,iEAAiE;AACjE,wBAAsB,cAAc,CAAC,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,iBA6B/E;AAED,6EAA6E;AAC7E,wBAAsB,gBAAgB,CAAC,OAAO,EAAE;IAC9C,MAAM,EAAE,SAAS,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,eAAe,CAAC,CAgB3B;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAQ1D"}
@@ -0,0 +1,129 @@
1
+ import readline from "readline";
2
+ import { providersCommandLabels } from "./commands-i18n.js";
3
+ import { markSetupComplete, saveGlobalConfig, setGlobalOffline, clearGlobalOffline, isGlobalOffline, } from "./global-config.js";
4
+ import { parseLocale } from "./locale.js";
5
+ import { formatSetupRequiredMessage } from "./setup-messages.js";
6
+ import { info, ok } from "./output.js";
7
+ import { ProviderSetupError, resolveActiveCredentials, resolveCredentialsWithOverride, } from "./providers/credentials.js";
8
+ import { runSetupProviderWizard } from "./providers/ui.js";
9
+ import { c, muted } from "./theme.js";
10
+ function t(locale, pt, en, zh) {
11
+ if (locale === "pt")
12
+ return pt;
13
+ if (locale === "zh")
14
+ return zh;
15
+ return en;
16
+ }
17
+ async function askLine(prompt) {
18
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
19
+ return new Promise((resolve) => {
20
+ rl.question(prompt, (answer) => {
21
+ rl.close();
22
+ resolve(answer.trim());
23
+ });
24
+ });
25
+ }
26
+ function hasProvider(apiKey) {
27
+ if (apiKey?.trim())
28
+ return true;
29
+ return Boolean(resolveActiveCredentials());
30
+ }
31
+ export function offlineModelLabel(locale) {
32
+ if (locale === "pt")
33
+ return "offline · doctor/scan";
34
+ if (locale === "zh")
35
+ return "离线 · 诊断/扫描";
36
+ return "offline · doctor/scan";
37
+ }
38
+ async function pickLanguage() {
39
+ console.log("");
40
+ console.log(` ${c.bold}Ekz Connect — Setup${c.reset}`);
41
+ console.log("");
42
+ console.log(` ${muted("Choose language · Escolhe idioma · 选择语言")}`);
43
+ console.log("");
44
+ console.log(` ${c.bold}1.${c.reset} Português`);
45
+ console.log(` ${c.bold}2.${c.reset} English`);
46
+ console.log(` ${c.bold}3.${c.reset} 中文`);
47
+ console.log("");
48
+ const choice = (await askLine(" [1/2/3]: ")).toLowerCase();
49
+ if (choice === "2" || choice === "en" || choice === "english")
50
+ return "en";
51
+ if (choice === "3" || choice === "zh" || choice === "中文")
52
+ return "zh";
53
+ return "pt";
54
+ }
55
+ async function askUserName(locale) {
56
+ console.log("");
57
+ const prompt = t(locale, "Como devo te chamar? ", "What should we call you? (first name): ", "怎么称呼您?(名字): ");
58
+ const name = await askLine(` ${prompt}`);
59
+ if (!name)
60
+ return t(locale, "Developer", "Developer", "开发者");
61
+ return name.split(/\s+/)[0] ?? name;
62
+ }
63
+ async function providerStep(locale) {
64
+ const p = providersCommandLabels(locale);
65
+ console.log("");
66
+ console.log(` ${muted(t(locale, "LLM (BYOK) — opcional agora", "LLM (BYOK) — optional for now", "LLM (BYOK) — 可选"))}`);
67
+ console.log("");
68
+ console.log(` ${c.bold}1.${c.reset} ${t(locale, "Configurar provedor", "Configure provider", "配置 provider")}`);
69
+ console.log(` ${muted(t(locale, p.cli, p.cli, p.cli))}`);
70
+ console.log("");
71
+ console.log(` ${c.bold}2.${c.reset} ${t(locale, "Continuar offline", "Continue offline", "离线模式")}`);
72
+ console.log(` ${muted(t(locale, "doctor · scan · sem AI", "doctor · scan · no AI", "诊断 · 扫描 · 无 AI"))}`);
73
+ console.log("");
74
+ console.log(` ${muted("Enter · skip")}`);
75
+ console.log("");
76
+ const choice = (await askLine(t(locale, " Escolha [1/2/Enter]: ", " Choice [1/2/Enter]: ", " 选择 [1/2/Enter]: "))).toLowerCase();
77
+ if (choice === "2" || choice === "offline" || choice === "离线") {
78
+ setGlobalOffline(true);
79
+ ok(t(locale, "Modo offline activo.", "Offline mode enabled.", "已启用离线模式。"));
80
+ return "offline";
81
+ }
82
+ if (choice === "1" || choice === "p" || choice === "providers" || choice === "provedores" || choice === "供应商") {
83
+ const configured = await runSetupProviderWizard(locale);
84
+ if (configured && resolveActiveCredentials()) {
85
+ clearGlobalOffline();
86
+ ok(t(locale, "Provedor configurado.", "Provider configured.", "Provider 已配置。"));
87
+ return "configured";
88
+ }
89
+ info(t(locale, "Provedor não configurado.", "No provider configured.", "未配置 provider。"));
90
+ return "skip";
91
+ }
92
+ return "skip";
93
+ }
94
+ /** Full first-run wizard: language → name → provider/offline. */
95
+ export async function runSetupWizard(opts) {
96
+ if (!process.stdin.isTTY) {
97
+ console.error(formatSetupRequiredMessage());
98
+ process.exitCode = 1;
99
+ return;
100
+ }
101
+ let locale = parseLocale(opts?.locale) ?? (await pickLanguage());
102
+ saveGlobalConfig({ locale });
103
+ const userName = await askUserName(locale);
104
+ saveGlobalConfig({ userName });
105
+ ok(t(locale, `Olá ${userName}!`, `Hello ${userName}!`, `你好 ${userName}!`));
106
+ await providerStep(locale);
107
+ markSetupComplete();
108
+ console.log("");
109
+ ok(t(locale, "Setup concluído. Corre `ekz` para começar.", "Setup complete. Run `ekz` to start.", "设置完成。运行 `ekz` 开始。"));
110
+ }
111
+ /** Ensures the agent can start — provider, offline, or throws setup hint. */
112
+ export async function ensureAgentReady(options) {
113
+ const { locale, offlineFlag, apiKey } = options;
114
+ if (offlineFlag || isGlobalOffline()) {
115
+ return { offline: true, creds: null };
116
+ }
117
+ if (hasProvider(apiKey)) {
118
+ clearGlobalOffline();
119
+ if (apiKey?.trim()) {
120
+ return { offline: false, creds: resolveCredentialsWithOverride(apiKey, locale) };
121
+ }
122
+ return { offline: false, creds: resolveActiveCredentials() };
123
+ }
124
+ throw new ProviderSetupError(formatSetupRequiredMessage());
125
+ }
126
+ export function offlineAgentHint(locale) {
127
+ const p = providersCommandLabels(locale);
128
+ return t(locale, `Modo offline — sem AI. Usa \`ekz setup\`, ${p.repl}, /diagnóstico ou /analisar.`, `Offline mode — no AI. Use \`ekz setup\`, ${p.repl}, /doctor, or /scan.`, `离线模式 — 无 AI。使用 \`ekz setup\`、${p.repl}、/诊断 或 /扫描。`);
129
+ }
@@ -5,11 +5,16 @@ export type ProviderDefinition = {
5
5
  name: string;
6
6
  kind: ProviderKind;
7
7
  description: string;
8
+ /** Default model when user presses Enter */
8
9
  defaultModel: string;
10
+ /** Predefined API base — never shown in UI */
9
11
  defaultBaseUrl?: string;
12
+ /** Selectable models in setup / providers menu */
13
+ models: string[];
10
14
  keyHint: string;
11
15
  docsUrl: string;
12
16
  };
13
17
  export declare const PROVIDER_CATALOG: ProviderDefinition[];
14
18
  export declare function getProviderDefinition(id: string): ProviderDefinition | undefined;
19
+ export declare function resolveProviderModel(def: ProviderDefinition, storedModel?: string): string;
15
20
  //# sourceMappingURL=catalog.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../../src/lib/providers/catalog.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,mBAAmB,GAAG,WAAW,CAAC;AAExE,MAAM,MAAM,UAAU,GAClB,QAAQ,GACR,QAAQ,GACR,WAAW,GACX,UAAU,GACV,MAAM,GACN,MAAM,GACN,SAAS,GACT,QAAQ,GACR,QAAQ,CAAC;AAEb,MAAM,MAAM,kBAAkB,GAAG;IAC/B,EAAE,EAAE,UAAU,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,YAAY,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,kBAAkB,EAyFhD,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAEhF"}
1
+ {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../../src/lib/providers/catalog.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,mBAAmB,GAAG,WAAW,CAAC;AAExE,MAAM,MAAM,UAAU,GAClB,QAAQ,GACR,QAAQ,GACR,WAAW,GACX,UAAU,GACV,MAAM,GACN,MAAM,GACN,SAAS,GACT,QAAQ,GACR,QAAQ,CAAC;AAEb,MAAM,MAAM,kBAAkB,GAAG;IAC/B,EAAE,EAAE,UAAU,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,YAAY,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,YAAY,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kDAAkD;IAClD,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,kBAAkB,EAkHhD,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAEhF;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,kBAAkB,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAK1F"}
@@ -5,6 +5,19 @@ export const PROVIDER_CATALOG = [
5
5
  kind: "cursor",
6
6
  description: "Composer local agent (@cursor/sdk)",
7
7
  defaultModel: "composer-2.5-fast",
8
+ models: [
9
+ "composer-2.5-fast",
10
+ "composer-2-fast",
11
+ "composer-2.5",
12
+ "composer-2",
13
+ "claude-4.6-sonnet-medium-thinking",
14
+ "claude-opus-4-7-thinking-xhigh",
15
+ "gemini-3-flash",
16
+ "gemini-3.1-pro",
17
+ "gpt-5.3-codex",
18
+ "gpt-5.5-medium",
19
+ "kimi-k2.5",
20
+ ],
8
21
  keyHint: "crsr_…",
9
22
  docsUrl: "https://cursor.com/dashboard/integrations",
10
23
  },
@@ -15,6 +28,7 @@ export const PROVIDER_CATALOG = [
15
28
  description: "GPT-4o, o-series",
16
29
  defaultModel: "gpt-4o",
17
30
  defaultBaseUrl: "https://api.openai.com/v1",
31
+ models: ["gpt-4o", "gpt-4o-mini", "gpt-4.1", "gpt-4.1-mini", "o1", "o1-mini", "o3-mini"],
18
32
  keyHint: "sk-…",
19
33
  docsUrl: "https://platform.openai.com/api-keys",
20
34
  },
@@ -24,6 +38,11 @@ export const PROVIDER_CATALOG = [
24
38
  kind: "anthropic",
25
39
  description: "Claude Sonnet / Opus",
26
40
  defaultModel: "claude-sonnet-4-20250514",
41
+ models: [
42
+ "claude-sonnet-4-20250514",
43
+ "claude-opus-4-20250514",
44
+ "claude-3-5-haiku-20241022",
45
+ ],
27
46
  keyHint: "sk-ant-…",
28
47
  docsUrl: "https://console.anthropic.com/settings/keys",
29
48
  },
@@ -34,6 +53,7 @@ export const PROVIDER_CATALOG = [
34
53
  description: "DeepSeek Chat / Reasoner",
35
54
  defaultModel: "deepseek-chat",
36
55
  defaultBaseUrl: "https://api.deepseek.com",
56
+ models: ["deepseek-chat", "deepseek-reasoner"],
37
57
  keyHint: "sk-…",
38
58
  docsUrl: "https://platform.deepseek.com/api_keys",
39
59
  },
@@ -44,6 +64,7 @@ export const PROVIDER_CATALOG = [
44
64
  description: "Moonshot AI",
45
65
  defaultModel: "moonshot-v1-8k",
46
66
  defaultBaseUrl: "https://api.moonshot.cn/v1",
67
+ models: ["moonshot-v1-8k", "moonshot-v1-32k", "moonshot-v1-128k"],
47
68
  keyHint: "sk-…",
48
69
  docsUrl: "https://platform.moonshot.cn/console/api-keys",
49
70
  },
@@ -54,6 +75,7 @@ export const PROVIDER_CATALOG = [
54
75
  description: "Fast inference",
55
76
  defaultModel: "llama-3.3-70b-versatile",
56
77
  defaultBaseUrl: "https://api.groq.com/openai/v1",
78
+ models: ["llama-3.3-70b-versatile", "llama-3.1-8b-instant", "mixtral-8x7b-32768"],
57
79
  keyHint: "gsk_…",
58
80
  docsUrl: "https://console.groq.com/keys",
59
81
  },
@@ -64,6 +86,7 @@ export const PROVIDER_CATALOG = [
64
86
  description: "Mistral Large",
65
87
  defaultModel: "mistral-large-latest",
66
88
  defaultBaseUrl: "https://api.mistral.ai/v1",
89
+ models: ["mistral-large-latest", "mistral-small-latest", "codestral-latest"],
67
90
  keyHint: "…",
68
91
  docsUrl: "https://console.mistral.ai/api-keys",
69
92
  },
@@ -71,9 +94,10 @@ export const PROVIDER_CATALOG = [
71
94
  id: "google",
72
95
  name: "Google Gemini",
73
96
  kind: "openai-compatible",
74
- description: "Gemini via OpenAI-compatible endpoint",
97
+ description: "Gemini models",
75
98
  defaultModel: "gemini-2.0-flash",
76
99
  defaultBaseUrl: "https://generativelanguage.googleapis.com/v1beta/openai",
100
+ models: ["gemini-2.0-flash", "gemini-2.0-flash-lite", "gemini-1.5-pro", "gemini-1.5-flash"],
77
101
  keyHint: "AI…",
78
102
  docsUrl: "https://aistudio.google.com/apikey",
79
103
  },
@@ -84,6 +108,7 @@ export const PROVIDER_CATALOG = [
84
108
  description: "Local models",
85
109
  defaultModel: "llama3.2",
86
110
  defaultBaseUrl: "http://127.0.0.1:11434/v1",
111
+ models: ["llama3.2", "llama3.1", "qwen2.5", "mistral", "deepseek-r1"],
87
112
  keyHint: "ollama (optional)",
88
113
  docsUrl: "https://ollama.com",
89
114
  },
@@ -91,3 +116,11 @@ export const PROVIDER_CATALOG = [
91
116
  export function getProviderDefinition(id) {
92
117
  return PROVIDER_CATALOG.find((p) => p.id === id);
93
118
  }
119
+ export function resolveProviderModel(def, storedModel) {
120
+ const trimmed = storedModel?.trim();
121
+ if (trimmed && def.models.includes(trimmed))
122
+ return trimmed;
123
+ if (trimmed && !def.models.includes(trimmed))
124
+ return trimmed;
125
+ return def.defaultModel;
126
+ }
@@ -1,4 +1,5 @@
1
1
  import { type ProviderDefinition, type ProviderId } from "./catalog.js";
2
+ import type { EkzLocale } from "../locale.js";
2
3
  import { type StoredProvider } from "./store.js";
3
4
  export type ResolvedCredentials = {
4
5
  id: ProviderId;
@@ -23,4 +24,5 @@ export declare function getActiveProviderId(): ProviderId | undefined;
23
24
  export declare function resolveActiveCredentials(): ResolvedCredentials | null;
24
25
  export declare function requireActiveCredentials(locale?: "pt" | "en" | "zh"): ResolvedCredentials;
25
26
  export declare function isCursorProvider(creds: ResolvedCredentials): boolean;
27
+ export declare function resolveCredentialsWithOverride(override?: string, locale?: EkzLocale): ResolvedCredentials;
26
28
  //# sourceMappingURL=credentials.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../../src/lib/providers/credentials.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,kBAAkB,EAAE,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1F,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,mBAAmB,GAAG;IAChC,EAAE,EAAE,UAAU,CAAC;IACf,UAAU,EAAE,kBAAkB,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,OAAO,EAAE,MAAM;CAI5B;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,UAAU,EAAE,kBAAkB,CAAC;IAC/B,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,wBAAgB,gBAAgB,IAAI,WAAW,EAAE,CAYhD;AAED,wBAAgB,mBAAmB,IAAI,UAAU,GAAG,SAAS,CAE5D;AAED,wBAAgB,wBAAwB,IAAI,mBAAmB,GAAG,IAAI,CAgBrE;AAED,wBAAgB,wBAAwB,CAAC,MAAM,GAAE,IAAI,GAAG,IAAI,GAAG,IAAW,GAAG,mBAAmB,CAI/F;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAEpE"}
1
+ {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../../src/lib/providers/credentials.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2C,KAAK,kBAAkB,EAAE,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAGjH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,mBAAmB,GAAG;IAChC,EAAE,EAAE,UAAU,CAAC;IACf,UAAU,EAAE,kBAAkB,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,OAAO,EAAE,MAAM;CAI5B;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,UAAU,EAAE,kBAAkB,CAAC;IAC/B,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,wBAAgB,gBAAgB,IAAI,WAAW,EAAE,CAYhD;AAED,wBAAgB,mBAAmB,IAAI,UAAU,GAAG,SAAS,CAE5D;AAED,wBAAgB,wBAAwB,IAAI,mBAAmB,GAAG,IAAI,CAgBrE;AAED,wBAAgB,wBAAwB,CAAC,MAAM,GAAE,IAAI,GAAG,IAAI,GAAG,IAAW,GAAG,mBAAmB,CAI/F;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAEpE;AAED,wBAAgB,8BAA8B,CAC5C,QAAQ,CAAC,EAAE,MAAM,EACjB,MAAM,GAAE,SAAgB,GACvB,mBAAmB,CAarB"}
@@ -1,5 +1,6 @@
1
- import { PROVIDER_CATALOG } from "./catalog.js";
2
- import { providersSetupHint } from "../commands-i18n.js";
1
+ import { PROVIDER_CATALOG, getProviderDefinition } from "./catalog.js";
2
+ import { formatSetupRequiredMessage } from "../setup-messages.js";
3
+ import { resolveComposerModel } from "../composer-model.js";
3
4
  import { loadProvidersFile, maskApiKey, resolveBaseUrl, resolveModel, } from "./store.js";
4
5
  export class ProviderSetupError extends Error {
5
6
  constructor(message) {
@@ -47,8 +48,23 @@ export function requireActiveCredentials(locale = "en") {
47
48
  const creds = resolveActiveCredentials();
48
49
  if (creds)
49
50
  return creds;
50
- throw new ProviderSetupError(providersSetupHint(locale));
51
+ throw new ProviderSetupError(formatSetupRequiredMessage());
51
52
  }
52
53
  export function isCursorProvider(creds) {
53
54
  return creds.definition.kind === "cursor";
54
55
  }
56
+ export function resolveCredentialsWithOverride(override, locale = "en") {
57
+ if (override?.trim()) {
58
+ const def = getProviderDefinition("cursor");
59
+ if (!def)
60
+ throw new Error("Cursor provider missing from catalog.");
61
+ return {
62
+ id: "cursor",
63
+ definition: def,
64
+ apiKey: override.trim(),
65
+ model: resolveComposerModel().id,
66
+ maskedKey: maskApiKey(override.trim()),
67
+ };
68
+ }
69
+ return requireActiveCredentials(locale);
70
+ }
@@ -1,8 +1,8 @@
1
- import { type SDKAgent } from "@cursor/sdk";
2
1
  import { type EkzLocale } from "../locale.js";
2
+ import { type SDKAgent } from "./cursor-sdk.js";
3
3
  import { type ResolvedCredentials } from "./credentials.js";
4
4
  declare function disposeAgent(agent: SDKAgent): Promise<void>;
5
- declare function streamRun(agent: SDKAgent, prompt: string): Promise<void>;
5
+ declare function streamRun(agent: SDKAgent, prompt: string, locale: EkzLocale): Promise<void>;
6
6
  export declare function executeCursorAskTurn(options: {
7
7
  cwd: string;
8
8
  question: string;
@@ -1 +1 @@
1
- {"version":3,"file":"cursor-runner.d.ts","sourceRoot":"","sources":["../../../src/lib/providers/cursor-runner.ts"],"names":[],"mappings":"AACA,OAAO,EAA2C,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAIrF,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAK9C,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAE5D,iBAAe,YAAY,CAAC,KAAK,EAAE,QAAQ,iBAI1C;AAED,iBAAe,SAAS,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAkCvE;AAED,wBAAsB,oBAAoB,CAAC,OAAO,EAAE;IAClD,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,mBAAmB,CAAC;IAC3B,MAAM,EAAE,SAAS,CAAC;CACnB,GAAG,OAAO,CAAC,OAAO,CAAC,CAkCnB;AAED,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC"}
1
+ {"version":3,"file":"cursor-runner.d.ts","sourceRoot":"","sources":["../../../src/lib/providers/cursor-runner.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,SAAS,EAAuB,MAAM,cAAc,CAAC;AAInE,OAAO,EAAiB,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAE5D,iBAAe,YAAY,CAAC,KAAK,EAAE,QAAQ,iBAI1C;AAED,iBAAe,SAAS,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAmC1F;AAED,wBAAsB,oBAAoB,CAAC,OAAO,EAAE;IAClD,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,mBAAmB,CAAC;IAC3B,MAAM,EAAE,SAAS,CAAC;CACnB,GAAG,OAAO,CAAC,OAAO,CAAC,CAmCnB;AAED,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC"}
@@ -1,11 +1,11 @@
1
1
  import { resolve } from "path";
2
- import { Agent, AgentBusyError, CursorAgentError } from "@cursor/sdk";
3
2
  import { buildBootstrapContext } from "../context.js";
4
3
  import { resolveComposerModel } from "../composer-model.js";
5
- import { fail } from "../output.js";
6
- import { toolDone, toolError, toolRunning } from "../theme.js";
7
4
  import { languageInstruction } from "../locale.js";
5
+ import { fail } from "../output.js";
8
6
  import { agentScopeBlock } from "../scope.js";
7
+ import { toolDone, toolError, toolRunning } from "../theme.js";
8
+ import { loadCursorSdk } from "./cursor-sdk.js";
9
9
  async function disposeAgent(agent) {
10
10
  const disposer = agent[Symbol.asyncDispose];
11
11
  if (typeof disposer === "function")
@@ -13,7 +13,8 @@ async function disposeAgent(agent) {
13
13
  else
14
14
  agent.close();
15
15
  }
16
- async function streamRun(agent, prompt) {
16
+ async function streamRun(agent, prompt, locale) {
17
+ const { AgentBusyError, CursorAgentError } = await loadCursorSdk(locale);
17
18
  const sendOptions = {
18
19
  onDelta: ({ update }) => {
19
20
  if (update.type === "text-delta" && update.text)
@@ -52,6 +53,7 @@ export async function executeCursorAskTurn(options) {
52
53
  const cwd = resolve(options.cwd);
53
54
  const ctx = await buildBootstrapContext(cwd);
54
55
  const model = resolveComposerModel(process.env, options.creds.model);
56
+ const { Agent } = await loadCursorSdk(options.locale);
55
57
  const prompt = `${agentScopeBlock(options.locale)}
56
58
 
57
59
  ${languageInstruction(options.locale)}
@@ -71,7 +73,7 @@ ${options.question}`;
71
73
  model: { id: model.id, params: model.params },
72
74
  local: { cwd, settingSources: ["project"] },
73
75
  });
74
- await streamRun(agent, prompt);
76
+ await streamRun(agent, prompt, options.locale);
75
77
  console.log("");
76
78
  return true;
77
79
  }
@@ -0,0 +1,8 @@
1
+ import type { EkzLocale } from "../locale.js";
2
+ export declare class CursorSdkMissingError extends Error {
3
+ constructor(locale?: EkzLocale);
4
+ }
5
+ type CursorSdkModule = typeof import("@cursor/sdk");
6
+ export declare function loadCursorSdk(locale?: EkzLocale): Promise<CursorSdkModule>;
7
+ export type { SDKAgent } from "@cursor/sdk";
8
+ //# sourceMappingURL=cursor-sdk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor-sdk.d.ts","sourceRoot":"","sources":["../../../src/lib/providers/cursor-sdk.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,MAAM,GAAE,SAAgB;CAWrC;AAED,KAAK,eAAe,GAAG,cAAc,aAAa,CAAC,CAAC;AAIpD,wBAAsB,aAAa,CAAC,MAAM,GAAE,SAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAQtF;AAED,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC"}