@chimerai/cli 0.2.98 → 0.2.100

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.
@@ -1255,7 +1255,7 @@ async function getServerSessionWithPermissions() {
1255
1255
  if (features.includes('ai-chat')) {
1256
1256
  // Modular chat components (useChat hook + individual components)
1257
1257
  await fs_extra_1.default.ensureDir(path_1.default.join(targetDir, 'components/chat'));
1258
- await fs_extra_1.default.writeFile(path_1.default.join(targetDir, 'components/chat/use-chat.ts'), templates.generateUseChatHook());
1258
+ await fs_extra_1.default.writeFile(path_1.default.join(targetDir, 'components/chat/use-chat.ts'), templates.generateUseChatHook(features.includes('billing')));
1259
1259
  await fs_extra_1.default.writeFile(path_1.default.join(targetDir, 'components/chat/chat-message.tsx'), templates.generateChatMessage());
1260
1260
  await fs_extra_1.default.writeFile(path_1.default.join(targetDir, 'components/chat/chat-input.tsx'), templates.generateChatInput());
1261
1261
  await fs_extra_1.default.writeFile(path_1.default.join(targetDir, 'components/chat/chat-sidebar.tsx'), templates.generateChatSidebar());
@@ -1286,17 +1286,6 @@ async function getServerSessionWithPermissions() {
1286
1286
  await fs_extra_1.default.writeFile(path_1.default.join(targetDir, 'app/api/v1/models/route.ts'), templates.generateV1ModelsRoute());
1287
1287
  }
1288
1288
  // ── Billing / Stripe (when selected) ────────────────────────────
1289
- // Always generate /api/billing/credits — chat hook calls it unconditionally.
1290
- // Without billing: return a stub so the client gets a clean 200 instead of 404.
1291
- await fs_extra_1.default.ensureDir(path_1.default.join(targetDir, 'app/api/billing/credits'));
1292
- if (!features.includes('billing')) {
1293
- await fs_extra_1.default.writeFile(path_1.default.join(targetDir, 'app/api/billing/credits/route.ts'), `import { NextResponse } from 'next/server';
1294
- // Billing feature not enabled — return stub so the client doesn't get a 404
1295
- export async function GET() {
1296
- return NextResponse.json({ balance: null, enabled: false });
1297
- }
1298
- `);
1299
- }
1300
1289
  if (features.includes('billing')) {
1301
1290
  const stripeLib = templates.generateStripeLib();
1302
1291
  await fs_extra_1.default.ensureDir(path_1.default.join(targetDir, 'lib'));
@@ -1 +1 @@
1
- {"version":3,"file":"api-routes.d.ts","sourceRoot":"","sources":["../../src/templates/api-routes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;GAKG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CAuGhD;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAoGlD;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CAmEhD;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAsFlD;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAoH/C;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAkG7C;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CA0H/C;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,IAAI,MAAM,CAgDvD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAQ5C;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CA+D5C;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CA0E9C;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAyC9C;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,IAAI,MAAM,CAwBpD;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,IAAI,MAAM,CAmCvD;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,IAAI,MAAM,CA+EnD;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,CA8BjD"}
1
+ {"version":3,"file":"api-routes.d.ts","sourceRoot":"","sources":["../../src/templates/api-routes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;GAKG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CAuGhD;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAoGlD;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CAmEhD;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAsFlD;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAoH/C;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAkG7C;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CA0H/C;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,IAAI,MAAM,CAgDvD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAQ5C;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAwE5C;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CA0E9C;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAyC9C;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,IAAI,MAAM,CAwBpD;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,IAAI,MAAM,CAmCvD;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,IAAI,MAAM,CA+EnD;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,CA8BjD"}
@@ -858,6 +858,7 @@ export async function GET() {
858
858
  id: true,
859
859
  name: true,
860
860
  type: true,
861
+ config: true,
861
862
  },
862
863
  },
863
864
  },
@@ -875,18 +876,26 @@ export async function GET() {
875
876
  return caps.includes('chat') || caps.includes('vision') || caps.length === 0;
876
877
  });
877
878
 
878
- const result = chatModels.map((m: any) => ({
879
- id: m.id,
880
- modelId: m.modelId,
881
- name: m.name,
882
- providerId: m.providerId,
883
- providerType: m.provider.type,
884
- contextWindow: m.contextWindow || 0,
885
- inputCost: m.inputCost || 0,
886
- outputCost: m.outputCost || 0,
887
- capabilities: m.capabilities || [],
888
- provider: m.provider,
889
- }));
879
+ const result = chatModels.map((m: any) => {
880
+ // Resolve provider's configured default model (stored in config.defaultModel)
881
+ const providerConfig = typeof m.provider.config === 'string'
882
+ ? (() => { try { return JSON.parse(m.provider.config); } catch { return {}; } })()
883
+ : (m.provider.config || {});
884
+ const isProviderDefault = !!providerConfig.defaultModel && providerConfig.defaultModel === m.modelId;
885
+ return {
886
+ id: m.id,
887
+ modelId: m.modelId,
888
+ name: m.name,
889
+ providerId: m.providerId,
890
+ providerType: m.provider.type,
891
+ contextWindow: m.contextWindow || 0,
892
+ inputCost: m.inputCost || 0,
893
+ outputCost: m.outputCost || 0,
894
+ capabilities: m.capabilities || [],
895
+ provider: m.provider,
896
+ isProviderDefault,
897
+ };
898
+ });
890
899
 
891
900
  return NextResponse.json(result);
892
901
  } catch (error) {
@@ -27,7 +27,7 @@ export declare function generateConversationsRoute(): string;
27
27
  * Based on apps/frontend/components/chat/use-chat.ts
28
28
  * @returns TypeScript content for components/chat/use-chat.ts
29
29
  */
30
- export declare function generateUseChatHook(): string;
30
+ export declare function generateUseChatHook(hasBilling?: boolean): string;
31
31
  /**
32
32
  * Generates the ChatMessage component with Markdown rendering, copy, edit, delete
33
33
  * Based on apps/frontend/components/chat/chat-message.tsx
@@ -1 +1 @@
1
- {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/templates/chat.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAqI/C;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAuLzC;AAED;;;;GAIG;AACH,wBAAgB,sCAAsC,IAAI,MAAM,CAwa/D;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,IAAI,MAAM,CAwEnD;AAMD;;;;;GAKG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAkb5C;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAuQ5C;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAwH1C;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CA+O5C;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CA+D9C;AAED;;;GAGG;AACH,wBAAgB,+BAA+B,IAAI,MAAM,CAyGxD"}
1
+ {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/templates/chat.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAqI/C;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAuLzC;AAED;;;;GAIG;AACH,wBAAgB,sCAAsC,IAAI,MAAM,CAwa/D;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,IAAI,MAAM,CAwEnD;AAMD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,UAAQ,GAAG,MAAM,CAob9D;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAuQ5C;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAwH1C;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CA+O5C;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CA+D9C;AAED;;;GAGG;AACH,wBAAgB,+BAA+B,IAAI,MAAM,CAyGxD"}
@@ -854,7 +854,7 @@ export async function POST(request: NextRequest) {
854
854
  * Based on apps/frontend/components/chat/use-chat.ts
855
855
  * @returns TypeScript content for components/chat/use-chat.ts
856
856
  */
857
- function generateUseChatHook() {
857
+ function generateUseChatHook(hasBilling = false) {
858
858
  return `// @chimerai component=UseChatHook version=2.0
859
859
  'use client';
860
860
 
@@ -978,7 +978,9 @@ export function useChat(options: UseChatOptions = {}): UseChatReturn {
978
978
  const modelList = Array.isArray(data) ? data : data.models || [];
979
979
  setModels(modelList);
980
980
  if (modelList.length > 0 && !selectedModelId) {
981
- setSelectedModelId(modelList[0].id);
981
+ // Prefer provider's configured default model, fall back to first in list
982
+ const defaultModel = modelList.find((m: any) => m.isProviderDefault) || modelList[0];
983
+ setSelectedModelId(defaultModel.id);
982
984
  }
983
985
  }
984
986
  } catch (err) {
@@ -988,7 +990,7 @@ export function useChat(options: UseChatOptions = {}): UseChatReturn {
988
990
  }
989
991
  }, [selectedModelId]);
990
992
 
991
- // --- Fetch Credit Balance ---
993
+ ${hasBilling ? `// --- Fetch Credit Balance ---
992
994
  const fetchCreditBalance = useCallback(async () => {
993
995
  try {
994
996
  const res = await fetch('/api/billing/credits');
@@ -999,13 +1001,13 @@ export function useChat(options: UseChatOptions = {}): UseChatReturn {
999
1001
  } catch {
1000
1002
  // Credits endpoint may not exist — that's ok
1001
1003
  }
1002
- }, []);
1004
+ }, []);` : ''}
1003
1005
 
1004
1006
  // Load on mount
1005
1007
  useEffect(() => {
1006
1008
  refreshConversations();
1007
1009
  fetchModels();
1008
- fetchCreditBalance();
1010
+ ${hasBilling ? 'fetchCreditBalance();' : '// billing not enabled'}
1009
1011
  // eslint-disable-next-line react-hooks/exhaustive-deps
1010
1012
  }, []);
1011
1013
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chimerai/cli",
3
- "version": "0.2.98",
3
+ "version": "0.2.100",
4
4
  "description": "CLI wizard for ChimerAI starter kit — scaffold auth, RBAC, AI chat, billing and more into any Next.js project",
5
5
  "main": "./dist/index.js",
6
6
  "bin": {