@levelcode/cli 0.2.6 → 0.2.7

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 (2) hide show
  1. package/dist/index.js +259 -645
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -96978,7 +96978,7 @@ var getBaseEnv = () => ({
96978
96978
  OPEN_TUI_THEME: process.env.OPEN_TUI_THEME,
96979
96979
  OPENTUI_THEME: process.env.OPENTUI_THEME,
96980
96980
  LEVELCODE_IS_BINARY: process.env.LEVELCODE_IS_BINARY,
96981
- LEVELCODE_CLI_VERSION: "0.2.6",
96981
+ LEVELCODE_CLI_VERSION: "0.2.7",
96982
96982
  LEVELCODE_CLI_TARGET: process.env.LEVELCODE_CLI_TARGET,
96983
96983
  LEVELCODE_RG_PATH: process.env.LEVELCODE_RG_PATH,
96984
96984
  LEVELCODE_WASM_DIR: process.env.LEVELCODE_WASM_DIR,
@@ -189742,7 +189742,7 @@ var getCliEnv = () => ({
189742
189742
  OPEN_TUI_THEME: process.env.OPEN_TUI_THEME,
189743
189743
  OPENTUI_THEME: process.env.OPENTUI_THEME,
189744
189744
  LEVELCODE_IS_BINARY: process.env.LEVELCODE_IS_BINARY,
189745
- LEVELCODE_CLI_VERSION: "0.2.6",
189745
+ LEVELCODE_CLI_VERSION: "0.2.7",
189746
189746
  LEVELCODE_CLI_TARGET: process.env.LEVELCODE_CLI_TARGET,
189747
189747
  LEVELCODE_RG_PATH: process.env.LEVELCODE_RG_PATH,
189748
189748
  LEVELCODE_SCROLL_MULTIPLIER: process.env.LEVELCODE_SCROLL_MULTIPLIER,
@@ -191072,396 +191072,220 @@ async function testProvider(providerId, apiKey, baseUrl) {
191072
191072
  var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1);
191073
191073
 
191074
191074
  // src/components/provider-wizard.tsx
191075
- var CATEGORIES = Object.keys(PROVIDER_CATEGORY_LABELS);
191075
+ var CATEGORIES = Object.keys(PROVIDER_CATEGORY_LABELS).filter((c) => c !== "custom");
191076
191076
  var ProviderWizard = ({ onClose }) => {
191077
191077
  const theme = useTheme();
191078
191078
  const [step, setStep] = import_react14.useState("category");
191079
- const [selectedCategory, setSelectedCategory] = import_react14.useState(null);
191079
+ const [selectedCategory, setSelectedCategory] = import_react14.useState("major-paid");
191080
191080
  const [selectedProvider, setSelectedProvider] = import_react14.useState(null);
191081
191081
  const [apiKey, setApiKey] = import_react14.useState("");
191082
- const [baseUrl, setBaseUrl] = import_react14.useState("");
191083
191082
  const [testResult, setTestResult] = import_react14.useState(null);
191084
- const [customModelIds, setCustomModelIds] = import_react14.useState([]);
191085
191083
  const [selectedIndex, setSelectedIndex] = import_react14.useState(0);
191086
191084
  const [isTesting, setIsTesting] = import_react14.useState(false);
191087
- const [configField, setConfigField] = import_react14.useState("apiKey");
191088
- const categoryProviders = selectedCategory ? getProvidersByCategory()[selectedCategory] ?? [] : [];
191085
+ const categoryProviders = getProvidersByCategory()[selectedCategory] ?? [];
191089
191086
  import_react14.useEffect(() => {
191090
- if (step !== "test" || !selectedProvider)
191087
+ if (step !== "test" || !selectedProvider || isTesting || testResult)
191091
191088
  return;
191092
- if (isTesting || testResult)
191093
- return;
191094
- let cancelled = false;
191095
191089
  setIsTesting(true);
191096
- testProvider(selectedProvider.id, apiKey || undefined, baseUrl || undefined).then((result) => {
191097
- if (!cancelled) {
191098
- setTestResult(result);
191099
- setIsTesting(false);
191100
- }
191101
- });
191102
- return () => {
191103
- cancelled = true;
191104
- };
191105
- }, [step, selectedProvider, apiKey, baseUrl, isTesting, testResult]);
191106
- const handleSaveProvider = import_react14.useCallback(async () => {
191090
+ testProvider(selectedProvider.id, apiKey || undefined).then((result) => {
191091
+ setTestResult(result);
191092
+ setIsTesting(false);
191093
+ }).catch(() => {
191094
+ setTestResult({ success: false, latencyMs: 0, error: "Test failed", providerName: selectedProvider.name });
191095
+ setIsTesting(false);
191096
+ });
191097
+ }, [step, selectedProvider, apiKey, isTesting, testResult]);
191098
+ const handleSave = import_react14.useCallback(async () => {
191107
191099
  if (!selectedProvider)
191108
191100
  return;
191109
191101
  await useProviderStore.getState().addProvider(selectedProvider.id, {
191110
191102
  enabled: true,
191111
191103
  apiKey: apiKey || undefined,
191112
- baseUrl: baseUrl || undefined,
191113
191104
  models: testResult?.models ?? [],
191114
- customModelIds
191105
+ customModelIds: []
191115
191106
  });
191116
- }, [selectedProvider, apiKey, baseUrl, testResult, customModelIds]);
191107
+ setStep("done");
191108
+ }, [selectedProvider, apiKey, testResult]);
191117
191109
  useKeyboard(import_react14.useCallback((key) => {
191118
- if (key.name === "escape" || key.ctrl && key.name === "c") {
191110
+ if (key.name === "escape") {
191119
191111
  onClose();
191120
191112
  return;
191121
191113
  }
191122
191114
  if (step === "category") {
191123
- if (key.name === "up") {
191124
- setSelectedIndex((prev) => Math.max(0, prev - 1));
191125
- return;
191126
- }
191127
- if (key.name === "down") {
191128
- setSelectedIndex((prev) => Math.min(CATEGORIES.length - 1, prev + 1));
191129
- return;
191130
- }
191131
- if (key.name === "return" || key.name === "enter") {
191132
- const cat = CATEGORIES[selectedIndex];
191133
- if (cat) {
191134
- setSelectedCategory(cat);
191135
- setSelectedIndex(0);
191136
- setStep("provider");
191137
- }
191138
- return;
191115
+ if (key.name === "up")
191116
+ setSelectedIndex((p) => Math.max(0, p - 1));
191117
+ else if (key.name === "down")
191118
+ setSelectedIndex((p) => Math.min(CATEGORIES.length - 1, p + 1));
191119
+ else if (key.name === "return" || key.name === "enter") {
191120
+ setSelectedCategory(CATEGORIES[selectedIndex]);
191121
+ setSelectedIndex(0);
191122
+ setStep("provider");
191139
191123
  }
191124
+ return;
191140
191125
  }
191141
191126
  if (step === "provider") {
191142
- if (key.name === "up") {
191143
- setSelectedIndex((prev) => Math.max(0, prev - 1));
191144
- return;
191145
- }
191146
- if (key.name === "down") {
191147
- setSelectedIndex((prev) => Math.min(categoryProviders.length - 1, prev + 1));
191148
- return;
191149
- }
191150
- if (key.name === "return" || key.name === "enter") {
191127
+ if (key.name === "up")
191128
+ setSelectedIndex((p) => Math.max(0, p - 1));
191129
+ else if (key.name === "down")
191130
+ setSelectedIndex((p) => Math.min(categoryProviders.length - 1, p + 1));
191131
+ else if (key.name === "return" || key.name === "enter") {
191151
191132
  const provider2 = categoryProviders[selectedIndex];
191152
191133
  if (provider2) {
191153
191134
  setSelectedProvider(provider2);
191154
- setBaseUrl(provider2.baseUrl);
191155
- setStep("config");
191156
- setConfigField("apiKey");
191135
+ setStep(provider2.authType === "none" ? "test" : "apikey");
191157
191136
  }
191158
- return;
191159
191137
  }
191138
+ return;
191160
191139
  }
191161
- if (step === "config") {
191162
- if (key.name === "tab") {
191163
- setConfigField((prev) => prev === "apiKey" ? "baseUrl" : "apiKey");
191164
- return;
191165
- }
191140
+ if (step === "apikey") {
191166
191141
  if (key.name === "return" || key.name === "enter") {
191167
191142
  setStep("test");
191168
- return;
191169
- }
191170
- if (key.name === "backspace" || key.name === "delete") {
191171
- if (configField === "apiKey") {
191172
- setApiKey((prev) => prev.slice(0, -1));
191173
- } else {
191174
- setBaseUrl((prev) => prev.slice(0, -1));
191175
- }
191176
- return;
191177
- }
191178
- if (key.sequence && key.sequence.length === 1 && !key.ctrl && !key.meta) {
191179
- if (configField === "apiKey") {
191180
- setApiKey((prev) => prev + key.sequence);
191181
- } else {
191182
- setBaseUrl((prev) => prev + key.sequence);
191183
- }
191184
- return;
191143
+ } else if (key.name === "backspace" || key.name === "delete") {
191144
+ setApiKey((p) => p.slice(0, -1));
191145
+ } else if (key.sequence && key.sequence.length === 1 && !key.ctrl && !key.meta) {
191146
+ setApiKey((p) => p + key.sequence);
191185
191147
  }
191148
+ return;
191186
191149
  }
191187
- if (step === "test") {
191188
- if ((key.name === "return" || key.name === "enter") && testResult) {
191189
- handleSaveProvider().then(() => {
191190
- setStep("done");
191191
- });
191192
- return;
191150
+ if (step === "test" && testResult) {
191151
+ if (key.name === "return" || key.name === "enter") {
191152
+ handleSave();
191193
191153
  }
191154
+ return;
191194
191155
  }
191195
191156
  if (step === "done") {
191196
191157
  if (key.name === "return" || key.name === "enter") {
191197
191158
  onClose();
191198
- return;
191199
191159
  }
191160
+ return;
191200
191161
  }
191201
- }, [
191202
- step,
191203
- selectedIndex,
191204
- categoryProviders,
191205
- configField,
191206
- testResult,
191207
- onClose,
191208
- handleSaveProvider
191209
- ]));
191210
- if (step === "category") {
191211
- return /* @__PURE__ */ import_jsx_runtime3.jsxs("box", {
191212
- title: " Add Provider - Select Category ",
191213
- titleAlignment: "center",
191214
- style: {
191215
- width: "100%",
191216
- borderStyle: "single",
191217
- borderColor: theme.primary,
191218
- customBorderChars: BORDER_CHARS,
191219
- paddingLeft: 1,
191220
- paddingRight: 1,
191221
- flexDirection: "column"
191222
- },
191223
- children: [
191224
- CATEGORIES.map((cat, index) => {
191225
- const isSelected = index === selectedIndex;
191226
- return /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191227
- style: {
191228
- fg: isSelected ? theme.primary : theme.foreground,
191229
- bg: isSelected ? theme.surface : undefined
191230
- },
191231
- children: [
191232
- isSelected ? "> " : " ",
191233
- PROVIDER_CATEGORY_LABELS[cat]
191234
- ]
191235
- }, cat);
191236
- }),
191237
- /* @__PURE__ */ import_jsx_runtime3.jsx("text", {
191238
- style: { fg: theme.muted },
191239
- children: "\u2191\u2193 navigate \xB7 Enter select \xB7 Esc cancel"
191240
- })
191241
- ]
191242
- });
191243
- }
191244
- if (step === "provider") {
191245
- return /* @__PURE__ */ import_jsx_runtime3.jsxs("box", {
191246
- title: ` Add Provider - ${PROVIDER_CATEGORY_LABELS[selectedCategory]} `,
191247
- titleAlignment: "center",
191248
- style: {
191249
- width: "100%",
191250
- borderStyle: "single",
191251
- borderColor: theme.primary,
191252
- customBorderChars: BORDER_CHARS,
191253
- paddingLeft: 1,
191254
- paddingRight: 1,
191255
- flexDirection: "column"
191256
- },
191257
- children: [
191258
- categoryProviders.map((provider2, index) => {
191259
- const isSelected = index === selectedIndex;
191260
- return /* @__PURE__ */ import_jsx_runtime3.jsxs("box", {
191261
- style: { flexDirection: "row", height: 1 },
191262
- children: [
191263
- /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191264
- style: {
191265
- fg: isSelected ? theme.primary : theme.foreground,
191266
- bg: isSelected ? theme.surface : undefined
191267
- },
191268
- children: [
191269
- isSelected ? "> " : " ",
191270
- provider2.name
191271
- ]
191272
- }),
191273
- /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191274
- style: { fg: theme.muted },
191275
- children: [
191276
- " ",
191277
- provider2.baseUrl
191278
- ]
191279
- })
191280
- ]
191281
- }, provider2.id);
191282
- }),
191283
- /* @__PURE__ */ import_jsx_runtime3.jsx("text", {
191284
- style: { fg: theme.muted },
191285
- children: "\u2191\u2193 navigate \xB7 Enter select \xB7 Esc cancel"
191286
- })
191287
- ]
191288
- });
191289
- }
191290
- if (step === "config") {
191291
- const maskedKey = apiKey.length > 0 ? "*".repeat(Math.max(0, apiKey.length - 4)) + apiKey.slice(-4) : "";
191292
- return /* @__PURE__ */ import_jsx_runtime3.jsxs("box", {
191293
- title: ` Configure ${selectedProvider?.name ?? ""} `,
191294
- titleAlignment: "center",
191295
- style: {
191296
- width: "100%",
191297
- borderStyle: "single",
191298
- borderColor: theme.primary,
191299
- customBorderChars: BORDER_CHARS,
191300
- paddingLeft: 1,
191301
- paddingRight: 1,
191302
- flexDirection: "column"
191303
- },
191304
- children: [
191305
- /* @__PURE__ */ import_jsx_runtime3.jsxs("box", {
191306
- style: { flexDirection: "row", height: 1 },
191307
- children: [
191308
- /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191309
- style: {
191310
- fg: configField === "apiKey" ? theme.primary : theme.foreground
191311
- },
191312
- children: [
191313
- configField === "apiKey" ? "> " : " ",
191314
- "API Key:",
191315
- " "
191316
- ]
191317
- }),
191318
- /* @__PURE__ */ import_jsx_runtime3.jsx("text", {
191319
- style: { fg: theme.muted },
191320
- children: maskedKey || "(type to enter)"
191321
- })
191322
- ]
191323
- }),
191324
- /* @__PURE__ */ import_jsx_runtime3.jsxs("box", {
191325
- style: { flexDirection: "row", height: 1 },
191326
- children: [
191327
- /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191328
- style: {
191329
- fg: configField === "baseUrl" ? theme.primary : theme.foreground
191330
- },
191331
- children: [
191332
- configField === "baseUrl" ? "> " : " ",
191333
- "Base URL:",
191334
- " "
191335
- ]
191336
- }),
191337
- /* @__PURE__ */ import_jsx_runtime3.jsx("text", {
191338
- style: { fg: theme.muted },
191339
- children: baseUrl || "(empty)"
191340
- })
191341
- ]
191342
- }),
191343
- selectedProvider?.envVars && selectedProvider.envVars.length > 0 && /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191344
- style: { fg: theme.info },
191345
- children: [
191346
- " ",
191347
- "Env var: ",
191348
- selectedProvider.envVars.join(", ")
191349
- ]
191350
- }),
191351
- /* @__PURE__ */ import_jsx_runtime3.jsx("text", {
191352
- style: { fg: theme.muted },
191353
- children: "Tab switch field \xB7 Enter test connection \xB7 Esc cancel"
191354
- })
191355
- ]
191356
- });
191357
- }
191358
- if (step === "test") {
191359
- return /* @__PURE__ */ import_jsx_runtime3.jsxs("box", {
191360
- title: ` Testing ${selectedProvider?.name ?? ""} `,
191361
- titleAlignment: "center",
191362
- style: {
191363
- width: "100%",
191364
- borderStyle: "single",
191365
- borderColor: theme.primary,
191366
- customBorderChars: BORDER_CHARS,
191367
- paddingLeft: 1,
191368
- paddingRight: 1,
191369
- flexDirection: "column"
191370
- },
191371
- children: [
191372
- isTesting && /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191373
- style: { fg: theme.warning },
191374
- children: [
191375
- " ",
191376
- "Testing connection..."
191377
- ]
191378
- }),
191379
- testResult && testResult.success && /* @__PURE__ */ import_jsx_runtime3.jsxs("box", {
191380
- style: { flexDirection: "column" },
191381
- children: [
191382
- /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191383
- style: { fg: theme.success },
191384
- children: [
191385
- " ",
191386
- "Connection successful!"
191387
- ]
191388
- }),
191389
- /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191390
- style: { fg: theme.muted },
191391
- children: [
191392
- " ",
191393
- "Latency: ",
191394
- Math.round(testResult.latencyMs),
191395
- "ms"
191396
- ]
191397
- }),
191398
- testResult.models && testResult.models.length > 0 && /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191399
- style: { fg: theme.muted },
191400
- children: [
191401
- " ",
191402
- "Models found: ",
191403
- testResult.models.length
191404
- ]
191405
- })
191406
- ]
191407
- }),
191408
- testResult && !testResult.success && /* @__PURE__ */ import_jsx_runtime3.jsxs("box", {
191409
- style: { flexDirection: "column" },
191410
- children: [
191411
- /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191412
- style: { fg: theme.error },
191413
- children: [
191414
- " ",
191415
- "Connection failed"
191416
- ]
191417
- }),
191418
- /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191419
- style: { fg: theme.muted },
191420
- children: [
191421
- " ",
191422
- testResult.error ?? "Unknown error"
191423
- ]
191424
- })
191425
- ]
191426
- }),
191427
- testResult && /* @__PURE__ */ import_jsx_runtime3.jsx("text", {
191428
- style: { fg: theme.muted },
191429
- children: "Enter save provider \xB7 Esc cancel"
191430
- })
191431
- ]
191432
- });
191433
- }
191162
+ }, [step, selectedIndex, categoryProviders, testResult, onClose, handleSave]));
191434
191163
  return /* @__PURE__ */ import_jsx_runtime3.jsxs("box", {
191435
- title: " Provider Added ",
191436
- titleAlignment: "center",
191437
191164
  style: {
191438
191165
  width: "100%",
191439
191166
  borderStyle: "single",
191440
- borderColor: theme.success,
191167
+ borderColor: theme.primary,
191441
191168
  customBorderChars: BORDER_CHARS,
191442
191169
  paddingLeft: 1,
191443
191170
  paddingRight: 1,
191444
191171
  flexDirection: "column"
191445
191172
  },
191446
191173
  children: [
191447
- /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191448
- style: { fg: theme.success },
191174
+ step === "category" && /* @__PURE__ */ import_jsx_runtime3.jsxs(import_jsx_runtime3.Fragment, {
191449
191175
  children: [
191450
- " ",
191451
- "Provider added!"
191176
+ /* @__PURE__ */ import_jsx_runtime3.jsx("text", {
191177
+ style: { fg: theme.primary },
191178
+ children: "Add Provider - Select Category"
191179
+ }),
191180
+ CATEGORIES.map((cat, i2) => /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191181
+ style: { fg: i2 === selectedIndex ? theme.primary : theme.foreground },
191182
+ children: [
191183
+ i2 === selectedIndex ? "> " : " ",
191184
+ PROVIDER_CATEGORY_LABELS[cat]
191185
+ ]
191186
+ }, cat))
191452
191187
  ]
191453
191188
  }),
191454
- /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191455
- style: { fg: theme.foreground },
191189
+ step === "provider" && /* @__PURE__ */ import_jsx_runtime3.jsxs(import_jsx_runtime3.Fragment, {
191190
+ children: [
191191
+ /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191192
+ style: { fg: theme.primary },
191193
+ children: [
191194
+ "Add Provider - ",
191195
+ PROVIDER_CATEGORY_LABELS[selectedCategory]
191196
+ ]
191197
+ }),
191198
+ categoryProviders.map((p, i2) => /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191199
+ style: { fg: i2 === selectedIndex ? theme.primary : theme.foreground },
191200
+ children: [
191201
+ i2 === selectedIndex ? "> " : " ",
191202
+ p.name
191203
+ ]
191204
+ }, p.id))
191205
+ ]
191206
+ }),
191207
+ step === "apikey" && /* @__PURE__ */ import_jsx_runtime3.jsxs(import_jsx_runtime3.Fragment, {
191208
+ children: [
191209
+ /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191210
+ style: { fg: theme.primary },
191211
+ children: [
191212
+ "Configure ",
191213
+ selectedProvider?.name ?? ""
191214
+ ]
191215
+ }),
191216
+ /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191217
+ style: { fg: theme.foreground },
191218
+ children: [
191219
+ "API Key: ",
191220
+ apiKey.length > 0 ? "*".repeat(Math.max(0, apiKey.length - 4)) + apiKey.slice(-4) : "(type your API key)"
191221
+ ]
191222
+ }),
191223
+ selectedProvider?.envVars && selectedProvider.envVars.length > 0 && /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191224
+ style: { fg: theme.info },
191225
+ children: [
191226
+ "Env var: ",
191227
+ selectedProvider.envVars.join(", ")
191228
+ ]
191229
+ }),
191230
+ /* @__PURE__ */ import_jsx_runtime3.jsx("text", {
191231
+ style: { fg: theme.muted },
191232
+ children: "Enter to test connection"
191233
+ })
191234
+ ]
191235
+ }),
191236
+ step === "test" && /* @__PURE__ */ import_jsx_runtime3.jsxs(import_jsx_runtime3.Fragment, {
191456
191237
  children: [
191457
- " ",
191458
- selectedProvider?.name ?? "Unknown",
191459
- " is now configured."
191238
+ /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191239
+ style: { fg: theme.primary },
191240
+ children: [
191241
+ "Testing ",
191242
+ selectedProvider?.name ?? ""
191243
+ ]
191244
+ }),
191245
+ isTesting && /* @__PURE__ */ import_jsx_runtime3.jsx("text", {
191246
+ style: { fg: theme.warning },
191247
+ children: "Testing connection..."
191248
+ }),
191249
+ testResult && testResult.success && /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191250
+ style: { fg: theme.success },
191251
+ children: [
191252
+ "Connected! ",
191253
+ Math.round(testResult.latencyMs),
191254
+ "ms",
191255
+ testResult.models ? ` (${testResult.models.length} models)` : ""
191256
+ ]
191257
+ }),
191258
+ testResult && !testResult.success && /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191259
+ style: { fg: theme.error },
191260
+ children: [
191261
+ "Failed: ",
191262
+ testResult.error ?? "Unknown error"
191263
+ ]
191264
+ }),
191265
+ testResult && /* @__PURE__ */ import_jsx_runtime3.jsx("text", {
191266
+ style: { fg: theme.muted },
191267
+ children: "Enter to save"
191268
+ })
191269
+ ]
191270
+ }),
191271
+ step === "done" && /* @__PURE__ */ import_jsx_runtime3.jsxs(import_jsx_runtime3.Fragment, {
191272
+ children: [
191273
+ /* @__PURE__ */ import_jsx_runtime3.jsx("text", {
191274
+ style: { fg: theme.success },
191275
+ children: "Provider added!"
191276
+ }),
191277
+ /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191278
+ style: { fg: theme.foreground },
191279
+ children: [
191280
+ selectedProvider?.name ?? "",
191281
+ " is now configured."
191282
+ ]
191283
+ })
191460
191284
  ]
191461
191285
  }),
191462
191286
  /* @__PURE__ */ import_jsx_runtime3.jsx("text", {
191463
191287
  style: { fg: theme.muted },
191464
- children: "Enter close \xB7 Esc close"
191288
+ children: "Esc cancel"
191465
191289
  })
191466
191290
  ]
191467
191291
  });
@@ -191474,41 +191298,19 @@ var ModelPicker = ({ onClose }) => {
191474
191298
  const theme = useTheme();
191475
191299
  const [searchQuery, setSearchQuery] = import_react16.useState("");
191476
191300
  const [selectedIndex, setSelectedIndex] = import_react16.useState(0);
191477
- const [selectedProviderId, setSelectedProviderId] = import_react16.useState(null);
191478
191301
  const catalogModels = useProviderStore((state) => state.catalogModels);
191479
191302
  const activeModel = useProviderStore((state) => state.config.activeModel);
191480
191303
  const activeProvider = useProviderStore((state) => state.config.activeProvider);
191481
- const configuredProviders = useProviderStore((state) => Object.keys(state.config.providers));
191482
191304
  const filteredModels2 = import_react16.useMemo(() => {
191483
- let models3 = catalogModels;
191484
- if (selectedProviderId) {
191485
- models3 = models3.filter((m) => m.providerId === selectedProviderId);
191486
- }
191487
- if (searchQuery.trim()) {
191488
- const query = searchQuery.toLowerCase();
191489
- models3 = models3.filter((m) => m.name.toLowerCase().includes(query) || m.id.toLowerCase().includes(query));
191490
- }
191491
- return models3;
191492
- }, [catalogModels, selectedProviderId, searchQuery]);
191493
- const formatCost = (model) => {
191494
- if (!model.cost)
191495
- return "-";
191496
- return `$${model.cost.input.toFixed(2)}/$${model.cost.output.toFixed(2)}`;
191497
- };
191498
- const formatContext = (model) => {
191499
- if (!model.limit?.context)
191500
- return "-";
191501
- const ctx = model.limit.context;
191502
- if (ctx >= 1e6)
191503
- return `${(ctx / 1e6).toFixed(1)}M`;
191504
- if (ctx >= 1000)
191505
- return `${Math.round(ctx / 1000)}K`;
191506
- return String(ctx);
191507
- };
191508
- const getProviderName = (providerId) => {
191509
- const def = PROVIDER_DEFINITIONS[providerId];
191510
- return def?.name ?? providerId;
191511
- };
191305
+ if (!searchQuery.trim())
191306
+ return catalogModels;
191307
+ const query = searchQuery.toLowerCase();
191308
+ return catalogModels.filter((m) => m.name.toLowerCase().includes(query) || m.id.toLowerCase().includes(query));
191309
+ }, [catalogModels, searchQuery]);
191310
+ const clampedIndex = Math.min(selectedIndex, Math.max(0, filteredModels2.length - 1));
191311
+ const maxVisible = 10;
191312
+ const scrollOffset = Math.max(0, Math.min(clampedIndex - Math.floor(maxVisible / 2), filteredModels2.length - maxVisible));
191313
+ const visibleModels = filteredModels2.slice(Math.max(0, scrollOffset), Math.max(0, scrollOffset) + maxVisible);
191512
191314
  useKeyboard(import_react16.useCallback((key) => {
191513
191315
  if (key.name === "escape") {
191514
191316
  onClose();
@@ -191523,26 +191325,11 @@ var ModelPicker = ({ onClose }) => {
191523
191325
  return;
191524
191326
  }
191525
191327
  if (key.name === "return" || key.name === "enter") {
191526
- const model = filteredModels2[selectedIndex];
191328
+ const model = filteredModels2[clampedIndex];
191527
191329
  if (model) {
191528
191330
  useProviderStore.getState().setActiveModel(model.providerId, model.id);
191529
- onClose();
191530
- }
191531
- return;
191532
- }
191533
- if (key.name === "tab") {
191534
- if (!selectedProviderId) {
191535
- setSelectedProviderId(configuredProviders[0] ?? null);
191536
- } else {
191537
- const currentIdx = configuredProviders.indexOf(selectedProviderId);
191538
- const nextIdx = currentIdx + 1;
191539
- if (nextIdx >= configuredProviders.length) {
191540
- setSelectedProviderId(null);
191541
- } else {
191542
- setSelectedProviderId(configuredProviders[nextIdx] ?? null);
191543
- }
191544
191331
  }
191545
- setSelectedIndex(0);
191332
+ onClose();
191546
191333
  return;
191547
191334
  }
191548
191335
  if (key.name === "backspace" || key.name === "delete") {
@@ -191555,13 +191342,8 @@ var ModelPicker = ({ onClose }) => {
191555
191342
  setSelectedIndex(0);
191556
191343
  return;
191557
191344
  }
191558
- }, [filteredModels2, selectedIndex, selectedProviderId, configuredProviders, onClose]));
191559
- const maxVisible = 12;
191560
- const scrollOffset = Math.max(0, Math.min(selectedIndex - Math.floor(maxVisible / 2), filteredModels2.length - maxVisible));
191561
- const visibleModels = filteredModels2.slice(scrollOffset, scrollOffset + maxVisible);
191345
+ }, [filteredModels2, clampedIndex, onClose]));
191562
191346
  return /* @__PURE__ */ import_jsx_runtime3.jsxs("box", {
191563
- title: " Model Picker ",
191564
- titleAlignment: "center",
191565
191347
  style: {
191566
191348
  width: "100%",
191567
191349
  borderStyle: "single",
@@ -191572,95 +191354,48 @@ var ModelPicker = ({ onClose }) => {
191572
191354
  flexDirection: "column"
191573
191355
  },
191574
191356
  children: [
191575
- /* @__PURE__ */ import_jsx_runtime3.jsxs("box", {
191576
- style: { flexDirection: "row", height: 1 },
191577
- children: [
191578
- /* @__PURE__ */ import_jsx_runtime3.jsx("text", {
191579
- style: { fg: theme.primary },
191580
- children: "Search: "
191581
- }),
191582
- /* @__PURE__ */ import_jsx_runtime3.jsx("text", {
191583
- style: { fg: theme.foreground },
191584
- children: searchQuery || ""
191585
- }),
191586
- /* @__PURE__ */ import_jsx_runtime3.jsx("text", {
191587
- style: { fg: theme.muted },
191588
- children: searchQuery ? "" : "(type to filter)"
191589
- })
191590
- ]
191357
+ /* @__PURE__ */ import_jsx_runtime3.jsx("text", {
191358
+ style: { fg: theme.primary },
191359
+ children: "Model Picker"
191591
191360
  }),
191592
- /* @__PURE__ */ import_jsx_runtime3.jsxs("box", {
191593
- style: { flexDirection: "row", height: 1 },
191361
+ /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191362
+ style: { fg: theme.muted },
191594
191363
  children: [
191595
- /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191596
- style: { fg: theme.muted },
191597
- children: [
191598
- "Filter:",
191599
- " "
191600
- ]
191601
- }),
191602
- /* @__PURE__ */ import_jsx_runtime3.jsx("text", {
191603
- style: {
191604
- fg: selectedProviderId ? theme.info : theme.muted
191605
- },
191606
- children: selectedProviderId ? getProviderName(selectedProviderId) : "All providers"
191607
- }),
191608
- /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191609
- style: { fg: theme.muted },
191610
- children: [
191611
- " ",
191612
- "(",
191613
- filteredModels2.length,
191614
- " models)"
191615
- ]
191616
- })
191364
+ "Search: ",
191365
+ searchQuery || "(type to filter)"
191617
191366
  ]
191618
191367
  }),
191619
191368
  /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191620
191369
  style: { fg: theme.muted },
191621
191370
  children: [
191622
- " ",
191623
- "Name".padEnd(32),
191624
- "Provider".padEnd(16),
191625
- "Cost".padEnd(16),
191626
- "Context"
191371
+ filteredModels2.length,
191372
+ " models available"
191627
191373
  ]
191628
191374
  }),
191629
191375
  visibleModels.map((model, visibleIdx) => {
191630
- const realIndex = scrollOffset + visibleIdx;
191631
- const isSelected = realIndex === selectedIndex;
191376
+ const realIndex = Math.max(0, scrollOffset) + visibleIdx;
191377
+ const isSelected = realIndex === clampedIndex;
191632
191378
  const isActive = model.id === activeModel && model.providerId === activeProvider;
191633
- return /* @__PURE__ */ import_jsx_runtime3.jsx("box", {
191634
- style: { flexDirection: "row", height: 1 },
191635
- children: /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191636
- style: {
191637
- fg: isActive ? theme.success : isSelected ? theme.primary : theme.foreground,
191638
- bg: isSelected ? theme.surface : undefined
191639
- },
191640
- children: [
191641
- isSelected ? "> " : " ",
191642
- model.name.slice(0, 30).padEnd(30),
191643
- " ",
191644
- getProviderName(model.providerId).slice(0, 14).padEnd(14),
191645
- " ",
191646
- formatCost(model).padEnd(14),
191647
- " ",
191648
- formatContext(model),
191649
- isActive ? " *" : ""
191650
- ]
191651
- })
191652
- }, `${model.providerId}-${model.id}`);
191379
+ const providerName = getProviderDefinition(model.providerId)?.name ?? model.providerId;
191380
+ return /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191381
+ style: {
191382
+ fg: isActive ? theme.success : isSelected ? theme.primary : theme.foreground
191383
+ },
191384
+ children: [
191385
+ isSelected ? "> " : " ",
191386
+ model.name.slice(0, 30).padEnd(32),
191387
+ providerName.slice(0, 14).padEnd(16),
191388
+ isActive ? "*" : ""
191389
+ ]
191390
+ }, `${model.providerId}-${model.id}-${visibleIdx}`);
191653
191391
  }),
191654
- filteredModels2.length === 0 && /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191392
+ filteredModels2.length === 0 && /* @__PURE__ */ import_jsx_runtime3.jsx("text", {
191655
191393
  style: { fg: theme.muted },
191656
- children: [
191657
- " ",
191658
- "No models found."
191659
- ]
191394
+ children: " No models found. Run /provider:add first."
191660
191395
  }),
191661
191396
  /* @__PURE__ */ import_jsx_runtime3.jsx("text", {
191662
191397
  style: { fg: theme.muted },
191663
- children: "\u2191\u2193 navigate \xB7 Enter select \xB7 Tab filter provider \xB7 Esc close"
191398
+ children: "Up/Down navigate | Enter select | Esc close"
191664
191399
  })
191665
191400
  ]
191666
191401
  });
@@ -191669,123 +191404,20 @@ var ModelPicker = ({ onClose }) => {
191669
191404
  // src/components/settings-panel.tsx
191670
191405
  var import_react18 = __toESM(require_react(), 1);
191671
191406
  init_provider_registry();
191672
- init_provider_types();
191673
- var SETTING_ROWS = [
191674
- { id: "autoDetectLocal", label: "Auto-detect local providers", type: "toggle" },
191675
- { id: "catalogRefreshHours", label: "Catalog refresh (hours)", type: "number" },
191676
- { id: "preferredProviderOrder", label: "Preferred provider order", type: "list" },
191677
- { id: "duplicateModelStrategy", label: "Duplicate model strategy", type: "select" },
191678
- { id: "providers", label: "Configured providers", type: "list" }
191679
- ];
191680
191407
  var SettingsPanel = ({ onClose }) => {
191681
191408
  const theme = useTheme();
191682
- const [selectedIndex, setSelectedIndex] = import_react18.useState(0);
191683
191409
  const settings = useProviderStore((state) => state.config.settings);
191684
191410
  const providers = useProviderStore((state) => state.config.providers);
191685
- const getProviderName = (id) => {
191686
- const def = PROVIDER_DEFINITIONS[id];
191687
- return def?.name ?? id;
191688
- };
191689
- const toggleAutoDetect = import_react18.useCallback(() => {
191690
- const next = !settings.autoDetectLocal;
191691
- useProviderStore.getState().updateSettings({ autoDetectLocal: next });
191692
- }, [settings.autoDetectLocal]);
191693
- const adjustRefreshHours = import_react18.useCallback((delta) => {
191694
- const next = Math.max(1, Math.min(24, settings.catalogRefreshHours + delta));
191695
- useProviderStore.getState().updateSettings({ catalogRefreshHours: next });
191696
- }, [settings.catalogRefreshHours]);
191697
- const cycleDuplicateStrategy = import_react18.useCallback((direction) => {
191698
- const strategies = DUPLICATE_MODEL_STRATEGIES;
191699
- const currentIdx = strategies.indexOf(settings.duplicateModelStrategy);
191700
- const nextIdx = (currentIdx + direction + strategies.length) % strategies.length;
191701
- const next = strategies[nextIdx];
191702
- useProviderStore.getState().updateSettings({ duplicateModelStrategy: next });
191703
- }, [settings.duplicateModelStrategy]);
191704
- const handleAction = import_react18.useCallback(() => {
191705
- const row = SETTING_ROWS[selectedIndex];
191706
- if (!row)
191707
- return;
191708
- switch (row.id) {
191709
- case "autoDetectLocal":
191710
- toggleAutoDetect();
191711
- break;
191712
- case "catalogRefreshHours":
191713
- adjustRefreshHours(1);
191714
- break;
191715
- case "duplicateModelStrategy":
191716
- cycleDuplicateStrategy(1);
191717
- break;
191718
- }
191719
- }, [selectedIndex, toggleAutoDetect, adjustRefreshHours, cycleDuplicateStrategy]);
191411
+ const activeProvider = useProviderStore((state) => state.config.activeProvider);
191412
+ const activeModel = useProviderStore((state) => state.config.activeModel);
191413
+ const providerEntries = Object.entries(providers);
191720
191414
  useKeyboard(import_react18.useCallback((key) => {
191721
- if (key.name === "escape" || key.ctrl && key.name === "c") {
191415
+ if (key.name === "escape") {
191722
191416
  onClose();
191723
191417
  return;
191724
191418
  }
191725
- if (key.name === "up") {
191726
- setSelectedIndex((prev) => Math.max(0, prev - 1));
191727
- return;
191728
- }
191729
- if (key.name === "down") {
191730
- setSelectedIndex((prev) => Math.min(SETTING_ROWS.length - 1, prev + 1));
191731
- return;
191732
- }
191733
- if (key.name === "return" || key.name === "enter" || key.name === "space") {
191734
- handleAction();
191735
- return;
191736
- }
191737
- const row = SETTING_ROWS[selectedIndex];
191738
- if (!row)
191739
- return;
191740
- if (key.name === "left") {
191741
- if (row.id === "catalogRefreshHours") {
191742
- adjustRefreshHours(-1);
191743
- } else if (row.id === "duplicateModelStrategy") {
191744
- cycleDuplicateStrategy(-1);
191745
- } else if (row.type === "toggle") {
191746
- handleAction();
191747
- }
191748
- return;
191749
- }
191750
- if (key.name === "right") {
191751
- if (row.id === "catalogRefreshHours") {
191752
- adjustRefreshHours(1);
191753
- } else if (row.id === "duplicateModelStrategy") {
191754
- cycleDuplicateStrategy(1);
191755
- } else if (row.type === "toggle") {
191756
- handleAction();
191757
- }
191758
- return;
191759
- }
191760
- }, [onClose, selectedIndex, handleAction, adjustRefreshHours, cycleDuplicateStrategy]));
191761
- const getValueDisplay = (row) => {
191762
- switch (row.id) {
191763
- case "autoDetectLocal":
191764
- return settings.autoDetectLocal ? "ON" : "OFF";
191765
- case "catalogRefreshHours":
191766
- return `< ${settings.catalogRefreshHours}h >`;
191767
- case "duplicateModelStrategy":
191768
- return `< ${settings.duplicateModelStrategy} >`;
191769
- case "preferredProviderOrder":
191770
- return settings.preferredProviderOrder.map((id) => getProviderName(id)).join(", ");
191771
- case "providers":
191772
- return "";
191773
- default:
191774
- return "";
191775
- }
191776
- };
191777
- const getValueColor = (row) => {
191778
- switch (row.id) {
191779
- case "autoDetectLocal":
191780
- return settings.autoDetectLocal ? theme.success : theme.muted;
191781
- default:
191782
- return theme.primary;
191783
- }
191784
- };
191785
- const providerEntries = Object.entries(providers);
191419
+ }, [onClose]));
191786
191420
  return /* @__PURE__ */ import_jsx_runtime3.jsxs("box", {
191787
- title: " Settings ",
191788
- titleAlignment: "center",
191789
191421
  style: {
191790
191422
  width: "100%",
191791
191423
  borderStyle: "single",
@@ -191796,93 +191428,75 @@ var SettingsPanel = ({ onClose }) => {
191796
191428
  flexDirection: "column"
191797
191429
  },
191798
191430
  children: [
191799
- SETTING_ROWS.map((row, index) => {
191800
- const isSelected = index === selectedIndex;
191801
- const valueDisplay = getValueDisplay(row);
191802
- const valueColor = getValueColor(row);
191803
- return /* @__PURE__ */ import_jsx_runtime3.jsxs("box", {
191804
- style: { flexDirection: "row", height: 1 },
191805
- children: [
191806
- /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191807
- style: {
191808
- fg: isSelected ? theme.primary : theme.foreground,
191809
- bg: isSelected ? theme.surface : undefined
191810
- },
191811
- children: [
191812
- isSelected ? "> " : " ",
191813
- row.label
191814
- ]
191815
- }),
191816
- valueDisplay && /* @__PURE__ */ import_jsx_runtime3.jsxs("box", {
191817
- style: { flexDirection: "row" },
191818
- children: [
191819
- /* @__PURE__ */ import_jsx_runtime3.jsx("text", {
191820
- style: { fg: theme.muted },
191821
- children: " "
191822
- }),
191823
- /* @__PURE__ */ import_jsx_runtime3.jsx("text", {
191824
- style: {
191825
- fg: isSelected ? valueColor : theme.muted
191826
- },
191827
- children: valueDisplay
191828
- })
191829
- ]
191830
- })
191831
- ]
191832
- }, row.id);
191431
+ /* @__PURE__ */ import_jsx_runtime3.jsx("text", {
191432
+ style: { fg: theme.primary },
191433
+ children: "Provider Settings"
191833
191434
  }),
191834
- providerEntries.length > 0 && /* @__PURE__ */ import_jsx_runtime3.jsxs("box", {
191835
- style: { flexDirection: "column" },
191435
+ /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191436
+ style: { fg: theme.foreground },
191836
191437
  children: [
191837
- /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191838
- style: { fg: theme.muted },
191839
- children: [
191840
- " ",
191841
- "---"
191842
- ]
191843
- }),
191844
- providerEntries.map(([id, entry]) => /* @__PURE__ */ import_jsx_runtime3.jsxs("box", {
191845
- style: { flexDirection: "row", height: 1 },
191846
- children: [
191847
- /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191848
- style: { fg: theme.foreground },
191849
- children: [
191850
- " ",
191851
- getProviderName(id)
191852
- ]
191853
- }),
191854
- /* @__PURE__ */ import_jsx_runtime3.jsx("text", {
191855
- style: { fg: theme.muted },
191856
- children: " "
191857
- }),
191858
- /* @__PURE__ */ import_jsx_runtime3.jsx("text", {
191859
- style: {
191860
- fg: entry.enabled ? theme.success : theme.muted
191861
- },
191862
- children: entry.enabled ? "enabled" : "disabled"
191863
- }),
191864
- entry.models.length > 0 && /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191865
- style: { fg: theme.muted },
191866
- children: [
191867
- " ",
191868
- entry.models.length,
191869
- " models"
191870
- ]
191871
- })
191872
- ]
191873
- }, id))
191438
+ "Active: ",
191439
+ activeProvider && activeModel ? `${activeProvider}/${activeModel}` : "None set"
191874
191440
  ]
191875
191441
  }),
191876
- providerEntries.length === 0 && /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191877
- style: { fg: theme.muted },
191442
+ /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191443
+ style: { fg: theme.foreground },
191878
191444
  children: [
191879
- " ",
191880
- "No providers configured. Use /provider:add to add one."
191445
+ "Auto-detect local: ",
191446
+ settings.autoDetectLocal ? "ON" : "OFF"
191881
191447
  ]
191882
191448
  }),
191449
+ /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191450
+ style: { fg: theme.foreground },
191451
+ children: [
191452
+ "Catalog refresh: ",
191453
+ settings.catalogRefreshHours,
191454
+ "h"
191455
+ ]
191456
+ }),
191457
+ /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191458
+ style: { fg: theme.foreground },
191459
+ children: [
191460
+ "Duplicate strategy: ",
191461
+ settings.duplicateModelStrategy
191462
+ ]
191463
+ }),
191464
+ /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191465
+ style: { fg: theme.foreground },
191466
+ children: [
191467
+ "Preferred order: ",
191468
+ settings.preferredProviderOrder.join(", ")
191469
+ ]
191470
+ }),
191471
+ providerEntries.length > 0 && /* @__PURE__ */ import_jsx_runtime3.jsxs(import_jsx_runtime3.Fragment, {
191472
+ children: [
191473
+ /* @__PURE__ */ import_jsx_runtime3.jsx("text", {
191474
+ style: { fg: theme.primary },
191475
+ children: "Configured Providers"
191476
+ }),
191477
+ providerEntries.map(([id, entry]) => {
191478
+ const name18 = getProviderDefinition(id)?.name ?? id;
191479
+ return /* @__PURE__ */ import_jsx_runtime3.jsxs("text", {
191480
+ style: { fg: entry.enabled ? theme.success : theme.muted },
191481
+ children: [
191482
+ " ",
191483
+ entry.enabled ? "\u25CF" : "\u25CB",
191484
+ " ",
191485
+ name18,
191486
+ entry.models.length > 0 ? ` (${entry.models.length} models)` : "",
191487
+ entry.autoDetected ? " [auto]" : ""
191488
+ ]
191489
+ }, id);
191490
+ })
191491
+ ]
191492
+ }),
191493
+ providerEntries.length === 0 && /* @__PURE__ */ import_jsx_runtime3.jsx("text", {
191494
+ style: { fg: theme.muted },
191495
+ children: "No providers configured. Use /provider:add to add one."
191496
+ }),
191883
191497
  /* @__PURE__ */ import_jsx_runtime3.jsx("text", {
191884
191498
  style: { fg: theme.muted },
191885
- children: "\u2191\u2193 navigate \xB7 Enter/Space toggle \xB7 \u2190\u2192 adjust \xB7 Esc close"
191499
+ children: "Esc close"
191886
191500
  })
191887
191501
  ]
191888
191502
  });
@@ -226777,7 +226391,7 @@ var Chat = ({
226777
226391
  useChatKeyboard({
226778
226392
  state: chatKeyboardState,
226779
226393
  handlers: chatKeyboardHandlers,
226780
- disabled: askUserState !== null || reviewMode
226394
+ disabled: askUserState !== null || reviewMode || providerWizardMode || modelPickerMode || providerSettingsMode
226781
226395
  });
226782
226396
  const setMessageBlockContext = useMessageBlockStore((state) => state.setContext);
226783
226397
  const setMessageBlockCallbacks = useMessageBlockStore((state) => state.setCallbacks);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@levelcode/cli",
3
- "version": "0.2.6",
3
+ "version": "0.2.7",
4
4
  "description": "LevelCode CLI - Terminal-based AI coding agent that outperforms Claude Code",
5
5
  "author": {
6
6
  "name": "Yethikrishna R",