clawbr 0.0.48 → 0.0.49

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.
@@ -119,50 +119,6 @@
119
119
  description: "ByteDance's SeedReam image generation"
120
120
  }
121
121
  ]
122
- },
123
- openai: {
124
- primary: "dall-e-3",
125
- fallbacks: [
126
- "dall-e-2"
127
- ],
128
- models: [
129
- {
130
- id: "dall-e-3",
131
- name: "DALL-E 3",
132
- supportsReferenceImage: false,
133
- supportsCustomSize: true,
134
- description: "OpenAI's DALL-E 3 (direct OpenAI API)"
135
- },
136
- {
137
- id: "dall-e-2",
138
- name: "DALL-E 2",
139
- supportsReferenceImage: false,
140
- supportsCustomSize: true,
141
- description: "OpenAI's DALL-E 2 (direct OpenAI API)"
142
- }
143
- ]
144
- },
145
- google: {
146
- primary: "imagen-4.0-generate-001",
147
- fallbacks: [
148
- "imagen-4.0-fast-generate-001"
149
- ],
150
- models: [
151
- {
152
- id: "imagen-4.0-generate-001",
153
- name: "Imagen 4.0",
154
- supportsReferenceImage: false,
155
- supportsCustomSize: true,
156
- description: "Google's Imagen 4.0 generation model"
157
- },
158
- {
159
- id: "imagen-4.0-fast-generate-001",
160
- name: "Imagen 4.0 Fast",
161
- supportsReferenceImage: false,
162
- supportsCustomSize: true,
163
- description: "Fast variant of Imagen 4.0"
164
- }
165
- ]
166
122
  }
167
123
  };
168
124
  /**
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/config/image-models.ts"],"sourcesContent":["/**\n * Image Generation Models Configuration\n *\n * Defines available models for each AI provider with their capabilities.\n * Used by generate command to validate and select appropriate models.\n */\n\nexport interface ImageModel {\n id: string;\n name: string;\n supportsReferenceImage: boolean;\n supportsCustomSize: boolean;\n description?: string;\n}\n\nexport interface ProviderModels {\n primary: string;\n fallbacks: string[];\n models: ImageModel[];\n}\n\nexport const IMAGE_MODELS: Record<string, ProviderModels> = {\n openrouter: {\n primary: \"google/gemini-2.5-flash-image\",\n fallbacks: [\n \"google/gemini-3-pro-image-preview\",\n \"openai/gpt-5-image\",\n \"sourceful/riverflow-v2-pro\",\n \"black-forest-labs/flux.2-pro\",\n ],\n models: [\n {\n id: \"google/gemini-2.5-flash-image\",\n name: \"Gemini 2.5 Flash Image (Nano Banana)\",\n supportsReferenceImage: true,\n supportsCustomSize: true,\n description: \"Fast, affordable image generation with reference image support\",\n },\n {\n id: \"google/gemini-2.5-flash-image-preview\",\n name: \"Gemini 2.5 Flash Image Preview\",\n supportsReferenceImage: true,\n supportsCustomSize: true,\n description: \"Preview version of Gemini 2.5 Flash\",\n },\n {\n id: \"google/gemini-3-pro-image-preview\",\n name: \"Nano Banana Pro (Gemini 3 Pro)\",\n supportsReferenceImage: true,\n supportsCustomSize: true,\n description: \"Professional graphics, 4K, multi-subject support\",\n },\n\n {\n id: \"black-forest-labs/flux.2-pro\",\n name: \"FLUX.2 Pro\",\n supportsReferenceImage: true,\n supportsCustomSize: true,\n description: \"High-quality image generation with reference support\",\n },\n {\n id: \"black-forest-labs/flux.2-flex\",\n name: \"FLUX.2 Flex\",\n supportsReferenceImage: true,\n supportsCustomSize: true,\n description: \"Flexible FLUX variant for diverse styles\",\n },\n {\n id: \"openai/gpt-5-image\",\n name: \"GPT-5 Image\",\n supportsReferenceImage: false,\n supportsCustomSize: true,\n description: \"OpenAI's GPT-5 image generation (via OpenRouter)\",\n },\n {\n id: \"openai/gpt-5-image-mini\",\n name: \"GPT-5 Image Mini\",\n supportsReferenceImage: false,\n supportsCustomSize: true,\n description: \"Lightweight GPT-5 image generation (via OpenRouter)\",\n },\n {\n id: \"black-forest-labs/flux.2-max\",\n name: \"FLUX.2 Max\",\n supportsReferenceImage: true,\n supportsCustomSize: true,\n description: \"Maximum quality FLUX generation\",\n },\n {\n id: \"black-forest-labs/flux.2-klein-4b\",\n name: \"FLUX.2 Klein 4B\",\n supportsReferenceImage: true,\n supportsCustomSize: true,\n description: \"Compact FLUX model\",\n },\n {\n id: \"sourceful/riverflow-v2-fast\",\n name: \"Riverflow V2 Fast\",\n supportsReferenceImage: true,\n supportsCustomSize: true,\n description: \"Fast unified t2i/i2i model\",\n },\n {\n id: \"sourceful/riverflow-v2-fast-preview\",\n name: \"Riverflow V2 Fast Preview\",\n supportsReferenceImage: true,\n supportsCustomSize: true,\n description: \"Preview version of Riverflow V2 Fast\",\n },\n {\n id: \"sourceful/riverflow-v2-standard-preview\",\n name: \"Riverflow V2 Standard Preview\",\n supportsReferenceImage: true,\n supportsCustomSize: true,\n description: \"Standard Riverflow with t2i/i2i support\",\n },\n {\n id: \"sourceful/riverflow-v2-max-preview\",\n name: \"Riverflow V2 Max Preview\",\n supportsReferenceImage: true,\n supportsCustomSize: true,\n description: \"Maximum quality Riverflow generation\",\n },\n {\n id: \"sourceful/riverflow-v2-pro\",\n name: \"Riverflow V2 Pro\",\n supportsReferenceImage: true,\n supportsCustomSize: true,\n description: \"Professional Riverflow with advanced features\",\n },\n {\n id: \"bytedance-seed/seedream-4.5\",\n name: \"SeedReam 4.5\",\n supportsReferenceImage: false,\n supportsCustomSize: true,\n description: \"ByteDance's SeedReam image generation\",\n },\n ],\n },\n openai: {\n primary: \"dall-e-3\",\n fallbacks: [\"dall-e-2\"],\n models: [\n {\n id: \"dall-e-3\",\n name: \"DALL-E 3\",\n supportsReferenceImage: false,\n supportsCustomSize: true,\n description: \"OpenAI's DALL-E 3 (direct OpenAI API)\",\n },\n {\n id: \"dall-e-2\",\n name: \"DALL-E 2\",\n supportsReferenceImage: false,\n supportsCustomSize: true,\n description: \"OpenAI's DALL-E 2 (direct OpenAI API)\",\n },\n ],\n },\n google: {\n primary: \"imagen-4.0-generate-001\",\n fallbacks: [\"imagen-4.0-fast-generate-001\"],\n models: [\n {\n id: \"imagen-4.0-generate-001\",\n name: \"Imagen 4.0\",\n supportsReferenceImage: false,\n supportsCustomSize: true,\n description: \"Google's Imagen 4.0 generation model\",\n },\n {\n id: \"imagen-4.0-fast-generate-001\",\n name: \"Imagen 4.0 Fast\",\n supportsReferenceImage: false,\n supportsCustomSize: true,\n description: \"Fast variant of Imagen 4.0\",\n },\n ],\n },\n};\n\n/**\n * Get available models for a provider\n */\nexport function getProviderModels(provider: string): ImageModel[] {\n const providerConfig = IMAGE_MODELS[provider];\n if (!providerConfig) {\n throw new Error(`Unknown provider: ${provider}`);\n }\n return providerConfig.models;\n}\n\n/**\n * Get model by ID for a provider\n */\nexport function getModelById(provider: string, modelId: string): ImageModel | undefined {\n const models = getProviderModels(provider);\n return models.find((m) => m.id === modelId);\n}\n\n/**\n * Validate if a model exists for a provider\n */\nexport function isValidModel(provider: string, modelId: string): boolean {\n return getModelById(provider, modelId) !== undefined;\n}\n\n/**\n * Get primary model for a provider\n */\nexport function getPrimaryModel(provider: string): string {\n const providerConfig = IMAGE_MODELS[provider];\n if (!providerConfig) {\n throw new Error(`Unknown provider: ${provider}`);\n }\n return providerConfig.primary;\n}\n\n/**\n * Get fallback models for a provider\n */\nexport function getFallbackModels(provider: string): string[] {\n const providerConfig = IMAGE_MODELS[provider];\n if (!providerConfig) {\n throw new Error(`Unknown provider: ${provider}`);\n }\n return providerConfig.fallbacks;\n}\n\n/**\n * Check if a model supports reference images\n */\nexport function supportsReferenceImage(provider: string, modelId: string): boolean {\n const model = getModelById(provider, modelId);\n return model?.supportsReferenceImage ?? false;\n}\n\n/**\n * Get list of models that support reference images for a provider\n */\nexport function getModelsWithReferenceSupport(provider: string): ImageModel[] {\n return getProviderModels(provider).filter((m) => m.supportsReferenceImage);\n}\n\n/**\n * Format model list for display\n */\nexport function formatModelList(provider: string): string {\n const models = getProviderModels(provider);\n return models\n .map((m) => {\n const refSupport = m.supportsReferenceImage ? \" [supports reference images]\" : \"\";\n return ` • ${m.id}${refSupport}\\n ${m.description || \"\"}`;\n })\n .join(\"\\n\\n\");\n}\n"],"names":["IMAGE_MODELS","openrouter","primary","fallbacks","models","id","name","supportsReferenceImage","supportsCustomSize","description","openai","google","getProviderModels","provider","providerConfig","Error","getModelById","modelId","find","m","isValidModel","undefined","getPrimaryModel","getFallbackModels","model","getModelsWithReferenceSupport","filter","formatModelList","map","refSupport","join"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/config/image-models.ts"],"sourcesContent":["/**\n * Image Generation Models Configuration\n *\n * Defines available models for each AI provider with their capabilities.\n * Used by generate command to validate and select appropriate models.\n */\n\nexport interface ImageModel {\n id: string;\n name: string;\n supportsReferenceImage: boolean;\n supportsCustomSize: boolean;\n description?: string;\n}\n\nexport interface ProviderModels {\n primary: string;\n fallbacks: string[];\n models: ImageModel[];\n}\n\nexport const IMAGE_MODELS: Record<string, ProviderModels> = {\n openrouter: {\n primary: \"google/gemini-2.5-flash-image\",\n fallbacks: [\n \"google/gemini-3-pro-image-preview\",\n \"openai/gpt-5-image\",\n \"sourceful/riverflow-v2-pro\",\n \"black-forest-labs/flux.2-pro\",\n ],\n models: [\n {\n id: \"google/gemini-2.5-flash-image\",\n name: \"Gemini 2.5 Flash Image (Nano Banana)\",\n supportsReferenceImage: true,\n supportsCustomSize: true,\n description: \"Fast, affordable image generation with reference image support\",\n },\n {\n id: \"google/gemini-2.5-flash-image-preview\",\n name: \"Gemini 2.5 Flash Image Preview\",\n supportsReferenceImage: true,\n supportsCustomSize: true,\n description: \"Preview version of Gemini 2.5 Flash\",\n },\n {\n id: \"google/gemini-3-pro-image-preview\",\n name: \"Nano Banana Pro (Gemini 3 Pro)\",\n supportsReferenceImage: true,\n supportsCustomSize: true,\n description: \"Professional graphics, 4K, multi-subject support\",\n },\n\n {\n id: \"black-forest-labs/flux.2-pro\",\n name: \"FLUX.2 Pro\",\n supportsReferenceImage: true,\n supportsCustomSize: true,\n description: \"High-quality image generation with reference support\",\n },\n {\n id: \"black-forest-labs/flux.2-flex\",\n name: \"FLUX.2 Flex\",\n supportsReferenceImage: true,\n supportsCustomSize: true,\n description: \"Flexible FLUX variant for diverse styles\",\n },\n {\n id: \"openai/gpt-5-image\",\n name: \"GPT-5 Image\",\n supportsReferenceImage: false,\n supportsCustomSize: true,\n description: \"OpenAI's GPT-5 image generation (via OpenRouter)\",\n },\n {\n id: \"openai/gpt-5-image-mini\",\n name: \"GPT-5 Image Mini\",\n supportsReferenceImage: false,\n supportsCustomSize: true,\n description: \"Lightweight GPT-5 image generation (via OpenRouter)\",\n },\n {\n id: \"black-forest-labs/flux.2-max\",\n name: \"FLUX.2 Max\",\n supportsReferenceImage: true,\n supportsCustomSize: true,\n description: \"Maximum quality FLUX generation\",\n },\n {\n id: \"black-forest-labs/flux.2-klein-4b\",\n name: \"FLUX.2 Klein 4B\",\n supportsReferenceImage: true,\n supportsCustomSize: true,\n description: \"Compact FLUX model\",\n },\n {\n id: \"sourceful/riverflow-v2-fast\",\n name: \"Riverflow V2 Fast\",\n supportsReferenceImage: true,\n supportsCustomSize: true,\n description: \"Fast unified t2i/i2i model\",\n },\n {\n id: \"sourceful/riverflow-v2-fast-preview\",\n name: \"Riverflow V2 Fast Preview\",\n supportsReferenceImage: true,\n supportsCustomSize: true,\n description: \"Preview version of Riverflow V2 Fast\",\n },\n {\n id: \"sourceful/riverflow-v2-standard-preview\",\n name: \"Riverflow V2 Standard Preview\",\n supportsReferenceImage: true,\n supportsCustomSize: true,\n description: \"Standard Riverflow with t2i/i2i support\",\n },\n {\n id: \"sourceful/riverflow-v2-max-preview\",\n name: \"Riverflow V2 Max Preview\",\n supportsReferenceImage: true,\n supportsCustomSize: true,\n description: \"Maximum quality Riverflow generation\",\n },\n {\n id: \"sourceful/riverflow-v2-pro\",\n name: \"Riverflow V2 Pro\",\n supportsReferenceImage: true,\n supportsCustomSize: true,\n description: \"Professional Riverflow with advanced features\",\n },\n {\n id: \"bytedance-seed/seedream-4.5\",\n name: \"SeedReam 4.5\",\n supportsReferenceImage: false,\n supportsCustomSize: true,\n description: \"ByteDance's SeedReam image generation\",\n },\n ],\n },\n};\n\n/**\n * Get available models for a provider\n */\nexport function getProviderModels(provider: string): ImageModel[] {\n const providerConfig = IMAGE_MODELS[provider];\n if (!providerConfig) {\n throw new Error(`Unknown provider: ${provider}`);\n }\n return providerConfig.models;\n}\n\n/**\n * Get model by ID for a provider\n */\nexport function getModelById(provider: string, modelId: string): ImageModel | undefined {\n const models = getProviderModels(provider);\n return models.find((m) => m.id === modelId);\n}\n\n/**\n * Validate if a model exists for a provider\n */\nexport function isValidModel(provider: string, modelId: string): boolean {\n return getModelById(provider, modelId) !== undefined;\n}\n\n/**\n * Get primary model for a provider\n */\nexport function getPrimaryModel(provider: string): string {\n const providerConfig = IMAGE_MODELS[provider];\n if (!providerConfig) {\n throw new Error(`Unknown provider: ${provider}`);\n }\n return providerConfig.primary;\n}\n\n/**\n * Get fallback models for a provider\n */\nexport function getFallbackModels(provider: string): string[] {\n const providerConfig = IMAGE_MODELS[provider];\n if (!providerConfig) {\n throw new Error(`Unknown provider: ${provider}`);\n }\n return providerConfig.fallbacks;\n}\n\n/**\n * Check if a model supports reference images\n */\nexport function supportsReferenceImage(provider: string, modelId: string): boolean {\n const model = getModelById(provider, modelId);\n return model?.supportsReferenceImage ?? false;\n}\n\n/**\n * Get list of models that support reference images for a provider\n */\nexport function getModelsWithReferenceSupport(provider: string): ImageModel[] {\n return getProviderModels(provider).filter((m) => m.supportsReferenceImage);\n}\n\n/**\n * Format model list for display\n */\nexport function formatModelList(provider: string): string {\n const models = getProviderModels(provider);\n return models\n .map((m) => {\n const refSupport = m.supportsReferenceImage ? \" [supports reference images]\" : \"\";\n return ` • ${m.id}${refSupport}\\n ${m.description || \"\"}`;\n })\n .join(\"\\n\\n\");\n}\n"],"names":["IMAGE_MODELS","openrouter","primary","fallbacks","models","id","name","supportsReferenceImage","supportsCustomSize","description","getProviderModels","provider","providerConfig","Error","getModelById","modelId","find","m","isValidModel","undefined","getPrimaryModel","getFallbackModels","model","getModelsWithReferenceSupport","filter","formatModelList","map","refSupport","join"],"mappings":"AAAA;;;;;CAKC,GAgBD,OAAO,MAAMA,eAA+C;IAC1DC,YAAY;QACVC,SAAS;QACTC,WAAW;YACT;YACA;YACA;YACA;SACD;QACDC,QAAQ;YACN;gBACEC,IAAI;gBACJC,MAAM;gBACNC,wBAAwB;gBACxBC,oBAAoB;gBACpBC,aAAa;YACf;YACA;gBACEJ,IAAI;gBACJC,MAAM;gBACNC,wBAAwB;gBACxBC,oBAAoB;gBACpBC,aAAa;YACf;YACA;gBACEJ,IAAI;gBACJC,MAAM;gBACNC,wBAAwB;gBACxBC,oBAAoB;gBACpBC,aAAa;YACf;YAEA;gBACEJ,IAAI;gBACJC,MAAM;gBACNC,wBAAwB;gBACxBC,oBAAoB;gBACpBC,aAAa;YACf;YACA;gBACEJ,IAAI;gBACJC,MAAM;gBACNC,wBAAwB;gBACxBC,oBAAoB;gBACpBC,aAAa;YACf;YACA;gBACEJ,IAAI;gBACJC,MAAM;gBACNC,wBAAwB;gBACxBC,oBAAoB;gBACpBC,aAAa;YACf;YACA;gBACEJ,IAAI;gBACJC,MAAM;gBACNC,wBAAwB;gBACxBC,oBAAoB;gBACpBC,aAAa;YACf;YACA;gBACEJ,IAAI;gBACJC,MAAM;gBACNC,wBAAwB;gBACxBC,oBAAoB;gBACpBC,aAAa;YACf;YACA;gBACEJ,IAAI;gBACJC,MAAM;gBACNC,wBAAwB;gBACxBC,oBAAoB;gBACpBC,aAAa;YACf;YACA;gBACEJ,IAAI;gBACJC,MAAM;gBACNC,wBAAwB;gBACxBC,oBAAoB;gBACpBC,aAAa;YACf;YACA;gBACEJ,IAAI;gBACJC,MAAM;gBACNC,wBAAwB;gBACxBC,oBAAoB;gBACpBC,aAAa;YACf;YACA;gBACEJ,IAAI;gBACJC,MAAM;gBACNC,wBAAwB;gBACxBC,oBAAoB;gBACpBC,aAAa;YACf;YACA;gBACEJ,IAAI;gBACJC,MAAM;gBACNC,wBAAwB;gBACxBC,oBAAoB;gBACpBC,aAAa;YACf;YACA;gBACEJ,IAAI;gBACJC,MAAM;gBACNC,wBAAwB;gBACxBC,oBAAoB;gBACpBC,aAAa;YACf;YACA;gBACEJ,IAAI;gBACJC,MAAM;gBACNC,wBAAwB;gBACxBC,oBAAoB;gBACpBC,aAAa;YACf;SACD;IACH;AACF,EAAE;AAEF;;CAEC,GACD,OAAO,SAASC,kBAAkBC,QAAgB;IAChD,MAAMC,iBAAiBZ,YAAY,CAACW,SAAS;IAC7C,IAAI,CAACC,gBAAgB;QACnB,MAAM,IAAIC,MAAM,CAAC,kBAAkB,EAAEF,UAAU;IACjD;IACA,OAAOC,eAAeR,MAAM;AAC9B;AAEA;;CAEC,GACD,OAAO,SAASU,aAAaH,QAAgB,EAAEI,OAAe;IAC5D,MAAMX,SAASM,kBAAkBC;IACjC,OAAOP,OAAOY,IAAI,CAAC,CAACC,IAAMA,EAAEZ,EAAE,KAAKU;AACrC;AAEA;;CAEC,GACD,OAAO,SAASG,aAAaP,QAAgB,EAAEI,OAAe;IAC5D,OAAOD,aAAaH,UAAUI,aAAaI;AAC7C;AAEA;;CAEC,GACD,OAAO,SAASC,gBAAgBT,QAAgB;IAC9C,MAAMC,iBAAiBZ,YAAY,CAACW,SAAS;IAC7C,IAAI,CAACC,gBAAgB;QACnB,MAAM,IAAIC,MAAM,CAAC,kBAAkB,EAAEF,UAAU;IACjD;IACA,OAAOC,eAAeV,OAAO;AAC/B;AAEA;;CAEC,GACD,OAAO,SAASmB,kBAAkBV,QAAgB;IAChD,MAAMC,iBAAiBZ,YAAY,CAACW,SAAS;IAC7C,IAAI,CAACC,gBAAgB;QACnB,MAAM,IAAIC,MAAM,CAAC,kBAAkB,EAAEF,UAAU;IACjD;IACA,OAAOC,eAAeT,SAAS;AACjC;AAEA;;CAEC,GACD,OAAO,SAASI,uBAAuBI,QAAgB,EAAEI,OAAe;IACtE,MAAMO,QAAQR,aAAaH,UAAUI;IACrC,OAAOO,OAAOf,0BAA0B;AAC1C;AAEA;;CAEC,GACD,OAAO,SAASgB,8BAA8BZ,QAAgB;IAC5D,OAAOD,kBAAkBC,UAAUa,MAAM,CAAC,CAACP,IAAMA,EAAEV,sBAAsB;AAC3E;AAEA;;CAEC,GACD,OAAO,SAASkB,gBAAgBd,QAAgB;IAC9C,MAAMP,SAASM,kBAAkBC;IACjC,OAAOP,OACJsB,GAAG,CAAC,CAACT;QACJ,MAAMU,aAAaV,EAAEV,sBAAsB,GAAG,iCAAiC;QAC/E,OAAO,CAAC,IAAI,EAAEU,EAAEZ,EAAE,GAAGsB,WAAW,MAAM,EAAEV,EAAER,WAAW,IAAI,IAAI;IAC/D,GACCmB,IAAI,CAAC;AACV"}
package/dist/config.js CHANGED
@@ -21,11 +21,6 @@ export const envSchema = z.object({
21
21
  CLAWBR_CREDENTIALS_PATH: z.string().optional(),
22
22
  // OpenRouter API (for image generation)
23
23
  OPENROUTER_API_KEY: z.string().optional(),
24
- // Google Gemini API
25
- GEMINI_API_KEY: z.string().optional(),
26
- GOOGLE_AI_API_KEY: z.string().optional(),
27
- // OpenAI API
28
- OPENAI_API_KEY: z.string().optional(),
29
24
  // CLI behavior
30
25
  CLAWBR_NO_COLOR: z.string().optional().default("false"),
31
26
  CLAWBR_DEBUG: z.string().optional().default("false"),
@@ -75,9 +70,7 @@ export const parsedConfig = {
75
70
  skillsDir: join(config.CLAWBR_CONFIG_DIR, "skills")
76
71
  },
77
72
  providers: {
78
- openrouter: config.OPENROUTER_API_KEY,
79
- gemini: config.GEMINI_API_KEY || config.GOOGLE_AI_API_KEY,
80
- openai: config.OPENAI_API_KEY
73
+ openrouter: config.OPENROUTER_API_KEY
81
74
  },
82
75
  cli: {
83
76
  noColor: config.CLAWBR_NO_COLOR === "true",
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/config.ts"],"sourcesContent":["import { z } from \"zod\";\nimport dotenv from \"dotenv\";\nimport { homedir } from \"os\";\nimport { join } from \"path\";\n\ndotenv.config();\n\nconst logger = {\n log: (msg: string) => console.log(`[Config] ${msg}`),\n error: (msg: string) => console.error(`[Config] ${msg}`),\n};\n\nexport const envSchema = z.object({\n NODE_ENV: z.enum([\"development\", \"production\", \"test\"]).default(\"development\"),\n\n // clawbr API\n CLAWBR_API_URL: z.string().url().default(\"https://clawbr.com\"),\n CLAWBR_TOKEN: z.string().optional(),\n\n // Config paths\n CLAWBR_CONFIG_DIR: z.string().optional().default(join(homedir(), \".clawbr\")),\n CLAWBR_CREDENTIALS_PATH: z.string().optional(),\n\n // OpenRouter API (for image generation)\n OPENROUTER_API_KEY: z.string().optional(),\n\n // Google Gemini API\n GEMINI_API_KEY: z.string().optional(),\n GOOGLE_AI_API_KEY: z.string().optional(),\n\n // OpenAI API\n OPENAI_API_KEY: z.string().optional(),\n\n // CLI behavior\n CLAWBR_NO_COLOR: z.string().optional().default(\"false\"),\n CLAWBR_DEBUG: z.string().optional().default(\"false\"),\n CLAWBR_TIMEOUT: z.string().optional().default(\"30000\"), // 30 seconds\n});\n\nexport type EnvVars = z.infer<typeof envSchema>;\n\n// Skip validation when generating .env.example\nconst isGeneratingEnvExample = process.argv.some((arg) => arg.includes(\"generate-env-example\"));\n\nlet validatedEnv: EnvVars;\nif (isGeneratingEnvExample) {\n // Use defaults/dummy values for generation\n validatedEnv = {\n NODE_ENV: \"development\",\n CLAWBR_API_URL: \"https://clawbr.com\",\n CLAWBR_CONFIG_DIR: join(homedir(), \".clawbr\"),\n CLAWBR_NO_COLOR: \"false\",\n CLAWBR_DEBUG: \"false\",\n CLAWBR_TIMEOUT: \"30000\",\n };\n} else {\n try {\n validatedEnv = envSchema.parse(process.env);\n if (validatedEnv.CLAWBR_DEBUG === \"true\") {\n logger.log(\"✅ Environment variables validated successfully\");\n }\n } catch (error) {\n if (error instanceof z.ZodError) {\n logger.error(\"❌ Invalid environment variables:\");\n error.issues.forEach((issue) => {\n logger.error(` - ${issue.path.join(\".\")}: ${issue.message}`);\n });\n }\n throw new Error(\"Environment validation failed\");\n }\n}\n\nexport const config = validatedEnv;\n\nexport const parsedConfig = {\n isDevelopment: config.NODE_ENV === \"development\",\n isProduction: config.NODE_ENV === \"production\",\n api: {\n baseUrl: config.CLAWBR_API_URL,\n token: config.CLAWBR_TOKEN,\n timeout: parseInt(config.CLAWBR_TIMEOUT, 10),\n },\n paths: {\n configDir: config.CLAWBR_CONFIG_DIR,\n credentialsPath:\n config.CLAWBR_CREDENTIALS_PATH || join(config.CLAWBR_CONFIG_DIR, \"credentials.json\"),\n skillsDir: join(config.CLAWBR_CONFIG_DIR, \"skills\"),\n },\n providers: {\n openrouter: config.OPENROUTER_API_KEY,\n gemini: config.GEMINI_API_KEY || config.GOOGLE_AI_API_KEY,\n openai: config.OPENAI_API_KEY,\n },\n cli: {\n noColor: config.CLAWBR_NO_COLOR === \"true\",\n debug: config.CLAWBR_DEBUG === \"true\",\n },\n};\n\nexport const validateEnv = () => config;\n"],"names":["z","dotenv","homedir","join","config","logger","log","msg","console","error","envSchema","object","NODE_ENV","enum","default","CLAWBR_API_URL","string","url","CLAWBR_TOKEN","optional","CLAWBR_CONFIG_DIR","CLAWBR_CREDENTIALS_PATH","OPENROUTER_API_KEY","GEMINI_API_KEY","GOOGLE_AI_API_KEY","OPENAI_API_KEY","CLAWBR_NO_COLOR","CLAWBR_DEBUG","CLAWBR_TIMEOUT","isGeneratingEnvExample","process","argv","some","arg","includes","validatedEnv","parse","env","ZodError","issues","forEach","issue","path","message","Error","parsedConfig","isDevelopment","isProduction","api","baseUrl","token","timeout","parseInt","paths","configDir","credentialsPath","skillsDir","providers","openrouter","gemini","openai","cli","noColor","debug","validateEnv"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/config.ts"],"sourcesContent":["import { z } from \"zod\";\nimport dotenv from \"dotenv\";\nimport { homedir } from \"os\";\nimport { join } from \"path\";\n\ndotenv.config();\n\nconst logger = {\n log: (msg: string) => console.log(`[Config] ${msg}`),\n error: (msg: string) => console.error(`[Config] ${msg}`),\n};\n\nexport const envSchema = z.object({\n NODE_ENV: z.enum([\"development\", \"production\", \"test\"]).default(\"development\"),\n\n // clawbr API\n CLAWBR_API_URL: z.string().url().default(\"https://clawbr.com\"),\n CLAWBR_TOKEN: z.string().optional(),\n\n // Config paths\n CLAWBR_CONFIG_DIR: z.string().optional().default(join(homedir(), \".clawbr\")),\n CLAWBR_CREDENTIALS_PATH: z.string().optional(),\n\n // OpenRouter API (for image generation)\n OPENROUTER_API_KEY: z.string().optional(),\n\n // CLI behavior\n CLAWBR_NO_COLOR: z.string().optional().default(\"false\"),\n CLAWBR_DEBUG: z.string().optional().default(\"false\"),\n CLAWBR_TIMEOUT: z.string().optional().default(\"30000\"), // 30 seconds\n});\n\nexport type EnvVars = z.infer<typeof envSchema>;\n\n// Skip validation when generating .env.example\nconst isGeneratingEnvExample = process.argv.some((arg) => arg.includes(\"generate-env-example\"));\n\nlet validatedEnv: EnvVars;\nif (isGeneratingEnvExample) {\n // Use defaults/dummy values for generation\n validatedEnv = {\n NODE_ENV: \"development\",\n CLAWBR_API_URL: \"https://clawbr.com\",\n CLAWBR_CONFIG_DIR: join(homedir(), \".clawbr\"),\n CLAWBR_NO_COLOR: \"false\",\n CLAWBR_DEBUG: \"false\",\n CLAWBR_TIMEOUT: \"30000\",\n };\n} else {\n try {\n validatedEnv = envSchema.parse(process.env);\n if (validatedEnv.CLAWBR_DEBUG === \"true\") {\n logger.log(\"✅ Environment variables validated successfully\");\n }\n } catch (error) {\n if (error instanceof z.ZodError) {\n logger.error(\"❌ Invalid environment variables:\");\n error.issues.forEach((issue) => {\n logger.error(` - ${issue.path.join(\".\")}: ${issue.message}`);\n });\n }\n throw new Error(\"Environment validation failed\");\n }\n}\n\nexport const config = validatedEnv;\n\nexport const parsedConfig = {\n isDevelopment: config.NODE_ENV === \"development\",\n isProduction: config.NODE_ENV === \"production\",\n api: {\n baseUrl: config.CLAWBR_API_URL,\n token: config.CLAWBR_TOKEN,\n timeout: parseInt(config.CLAWBR_TIMEOUT, 10),\n },\n paths: {\n configDir: config.CLAWBR_CONFIG_DIR,\n credentialsPath:\n config.CLAWBR_CREDENTIALS_PATH || join(config.CLAWBR_CONFIG_DIR, \"credentials.json\"),\n skillsDir: join(config.CLAWBR_CONFIG_DIR, \"skills\"),\n },\n providers: {\n openrouter: config.OPENROUTER_API_KEY,\n },\n cli: {\n noColor: config.CLAWBR_NO_COLOR === \"true\",\n debug: config.CLAWBR_DEBUG === \"true\",\n },\n};\n\nexport const validateEnv = () => config;\n"],"names":["z","dotenv","homedir","join","config","logger","log","msg","console","error","envSchema","object","NODE_ENV","enum","default","CLAWBR_API_URL","string","url","CLAWBR_TOKEN","optional","CLAWBR_CONFIG_DIR","CLAWBR_CREDENTIALS_PATH","OPENROUTER_API_KEY","CLAWBR_NO_COLOR","CLAWBR_DEBUG","CLAWBR_TIMEOUT","isGeneratingEnvExample","process","argv","some","arg","includes","validatedEnv","parse","env","ZodError","issues","forEach","issue","path","message","Error","parsedConfig","isDevelopment","isProduction","api","baseUrl","token","timeout","parseInt","paths","configDir","credentialsPath","skillsDir","providers","openrouter","cli","noColor","debug","validateEnv"],"mappings":"AAAA,SAASA,CAAC,QAAQ,MAAM;AACxB,OAAOC,YAAY,SAAS;AAC5B,SAASC,OAAO,QAAQ,KAAK;AAC7B,SAASC,IAAI,QAAQ,OAAO;AAE5BF,OAAOG,MAAM;AAEb,MAAMC,SAAS;IACbC,KAAK,CAACC,MAAgBC,QAAQF,GAAG,CAAC,CAAC,SAAS,EAAEC,KAAK;IACnDE,OAAO,CAACF,MAAgBC,QAAQC,KAAK,CAAC,CAAC,SAAS,EAAEF,KAAK;AACzD;AAEA,OAAO,MAAMG,YAAYV,EAAEW,MAAM,CAAC;IAChCC,UAAUZ,EAAEa,IAAI,CAAC;QAAC;QAAe;QAAc;KAAO,EAAEC,OAAO,CAAC;IAEhE,aAAa;IACbC,gBAAgBf,EAAEgB,MAAM,GAAGC,GAAG,GAAGH,OAAO,CAAC;IACzCI,cAAclB,EAAEgB,MAAM,GAAGG,QAAQ;IAEjC,eAAe;IACfC,mBAAmBpB,EAAEgB,MAAM,GAAGG,QAAQ,GAAGL,OAAO,CAACX,KAAKD,WAAW;IACjEmB,yBAAyBrB,EAAEgB,MAAM,GAAGG,QAAQ;IAE5C,wCAAwC;IACxCG,oBAAoBtB,EAAEgB,MAAM,GAAGG,QAAQ;IAEvC,eAAe;IACfI,iBAAiBvB,EAAEgB,MAAM,GAAGG,QAAQ,GAAGL,OAAO,CAAC;IAC/CU,cAAcxB,EAAEgB,MAAM,GAAGG,QAAQ,GAAGL,OAAO,CAAC;IAC5CW,gBAAgBzB,EAAEgB,MAAM,GAAGG,QAAQ,GAAGL,OAAO,CAAC;AAChD,GAAG;AAIH,+CAA+C;AAC/C,MAAMY,yBAAyBC,QAAQC,IAAI,CAACC,IAAI,CAAC,CAACC,MAAQA,IAAIC,QAAQ,CAAC;AAEvE,IAAIC;AACJ,IAAIN,wBAAwB;IAC1B,2CAA2C;IAC3CM,eAAe;QACbpB,UAAU;QACVG,gBAAgB;QAChBK,mBAAmBjB,KAAKD,WAAW;QACnCqB,iBAAiB;QACjBC,cAAc;QACdC,gBAAgB;IAClB;AACF,OAAO;IACL,IAAI;QACFO,eAAetB,UAAUuB,KAAK,CAACN,QAAQO,GAAG;QAC1C,IAAIF,aAAaR,YAAY,KAAK,QAAQ;YACxCnB,OAAOC,GAAG,CAAC;QACb;IACF,EAAE,OAAOG,OAAO;QACd,IAAIA,iBAAiBT,EAAEmC,QAAQ,EAAE;YAC/B9B,OAAOI,KAAK,CAAC;YACbA,MAAM2B,MAAM,CAACC,OAAO,CAAC,CAACC;gBACpBjC,OAAOI,KAAK,CAAC,CAAC,IAAI,EAAE6B,MAAMC,IAAI,CAACpC,IAAI,CAAC,KAAK,EAAE,EAAEmC,MAAME,OAAO,EAAE;YAC9D;QACF;QACA,MAAM,IAAIC,MAAM;IAClB;AACF;AAEA,OAAO,MAAMrC,SAAS4B,aAAa;AAEnC,OAAO,MAAMU,eAAe;IAC1BC,eAAevC,OAAOQ,QAAQ,KAAK;IACnCgC,cAAcxC,OAAOQ,QAAQ,KAAK;IAClCiC,KAAK;QACHC,SAAS1C,OAAOW,cAAc;QAC9BgC,OAAO3C,OAAOc,YAAY;QAC1B8B,SAASC,SAAS7C,OAAOqB,cAAc,EAAE;IAC3C;IACAyB,OAAO;QACLC,WAAW/C,OAAOgB,iBAAiB;QACnCgC,iBACEhD,OAAOiB,uBAAuB,IAAIlB,KAAKC,OAAOgB,iBAAiB,EAAE;QACnEiC,WAAWlD,KAAKC,OAAOgB,iBAAiB,EAAE;IAC5C;IACAkC,WAAW;QACTC,YAAYnD,OAAOkB,kBAAkB;IACvC;IACAkC,KAAK;QACHC,SAASrD,OAAOmB,eAAe,KAAK;QACpCmC,OAAOtD,OAAOoB,YAAY,KAAK;IACjC;AACF,EAAE;AAEF,OAAO,MAAMmC,cAAc,IAAMvD,OAAO"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/api.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport fetch, { Response } from \"node-fetch\";\n\n/**\n * Enhanced error with rate limit info\n */\nclass ApiError extends Error {\n constructor(\n message: string,\n public statusCode?: number,\n public retryAfter?: number\n ) {\n super(message);\n this.name = \"ApiError\";\n }\n}\n\n/**\n * Parse error response and extract useful information\n */\nasync function parseErrorResponse(response: Response): Promise<ApiError> {\n const statusCode = response.status;\n\n // Check for rate limit headers\n const retryAfter = response.headers.get(\"retry-after\");\n const rateLimitReset = response.headers.get(\"x-ratelimit-reset\");\n\n let retryAfterSeconds: number | undefined;\n if (retryAfter) {\n retryAfterSeconds = parseInt(retryAfter, 10);\n } else if (rateLimitReset) {\n const resetTime = parseInt(rateLimitReset, 10) * 1000;\n retryAfterSeconds = Math.ceil((resetTime - Date.now()) / 1000);\n }\n\n try {\n const error = await response.json();\n const errorMessage = (error as any).error || response.statusText;\n\n if (statusCode === 429) {\n const waitTime = retryAfterSeconds || 30;\n return new ApiError(\n `Rate limit exceeded. Please wait ${waitTime} seconds before retrying.\\n` +\n `Tip: If you're testing, the server may have rate limiting enabled.\\n` +\n `Check with the server administrator if this persists.`,\n statusCode,\n retryAfterSeconds\n );\n }\n\n return new ApiError(errorMessage, statusCode);\n } catch {\n if (statusCode === 429) {\n return new ApiError(\n `Rate limit exceeded. Please wait before retrying.\\n` +\n `Tip: If you're testing, the server may have rate limiting enabled.`,\n statusCode,\n retryAfterSeconds\n );\n }\n return new ApiError(response.statusText || \"Unknown error\", statusCode);\n }\n}\n\nexport interface RegisterResponse {\n success: boolean;\n agent: {\n id: string;\n username: string;\n aiProvider: string;\n createdAt: string;\n };\n token: string;\n message: string;\n}\n\nexport interface PostResponse {\n success: boolean;\n post: {\n id: string;\n imageUrl: string;\n caption: string;\n visualSnapshot: string;\n createdAt: string;\n agent: {\n id: string;\n username: string;\n };\n };\n}\n\nexport interface FeedResponse {\n posts: Array<{\n id: string;\n imageUrl: string;\n caption: string;\n visualSnapshot: string;\n createdAt: string;\n agent: {\n id: string;\n username: string;\n rank?: number | null;\n score?: number;\n subscriberCount: number;\n };\n likeCount: number;\n metadata: {\n width: number | null;\n height: number | null;\n type: string | null;\n size: number | null;\n altText: string | null;\n isAnimated?: boolean;\n };\n }>;\n nextCursor: string | null;\n hasMore: boolean;\n}\n\nexport interface UploadResponse {\n url: string;\n key: string;\n bucket: string;\n}\n\n/**\n * Register a new agent\n */\nexport async function registerAgent(\n baseUrl: string,\n requestBody: {\n username: string;\n aiProvider: string;\n googleApiKey?: string;\n openrouterApiKey?: string;\n openaiApiKey?: string;\n }\n): Promise<RegisterResponse> {\n const url = `${baseUrl}/api/agents/register`;\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(requestBody),\n });\n\n if (!response.ok) {\n throw await parseErrorResponse(response);\n }\n\n return response.json() as Promise<RegisterResponse>;\n}\n\n/**\n * Legacy alias for backwards compatibility\n */\nexport async function claimApiKey(\n baseUrl: string,\n requestBody: {\n agentName: string;\n aiProvider: string;\n googleApiKey?: string;\n openrouterApiKey?: string;\n openaiApiKey?: string;\n inviteCode?: string;\n }\n): Promise<{ token: string; agentName: string; message: string }> {\n const { agentName, ...rest } = requestBody;\n const response = await registerAgent(baseUrl, {\n username: agentName,\n ...rest,\n });\n\n return {\n token: response.token,\n agentName: response.agent.username,\n message: response.message,\n };\n}\n\n/**\n * Create a new post\n */\nexport async function createPost(\n baseUrl: string,\n token: string,\n data: {\n caption: string;\n imageUrl?: string;\n imageFile?: Buffer;\n fileName?: string;\n }\n): Promise<PostResponse> {\n const url = `${baseUrl}/api/posts/create`;\n\n // If we have an image file, use multipart/form-data\n if (data.imageFile) {\n const FormData = (await import(\"form-data\")).default;\n const formData = new FormData();\n\n formData.append(\"caption\", data.caption);\n formData.append(\"file\", data.imageFile, data.fileName || \"image.png\");\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"X-Agent-Token\": token,\n ...formData.getHeaders(),\n },\n body: formData as any,\n });\n\n if (!response.ok) {\n throw await parseErrorResponse(response);\n }\n\n return response.json() as Promise<PostResponse>;\n }\n\n // Otherwise use JSON\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"X-Agent-Token\": token,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n caption: data.caption,\n imageUrl: data.imageUrl,\n }),\n });\n\n if (!response.ok) {\n throw await parseErrorResponse(response);\n }\n\n return response.json() as Promise<PostResponse>;\n}\n\n/**\n * Upload a file\n */\nexport async function uploadFile(\n baseUrl: string,\n token: string,\n fileBuffer: Buffer,\n fileName: string\n): Promise<UploadResponse> {\n const FormData = (await import(\"form-data\")).default;\n const formData = new FormData();\n\n formData.append(\"file\", fileBuffer, fileName);\n\n const url = `${baseUrl}/api/upload`;\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"X-Agent-Token\": token,\n ...formData.getHeaders(),\n },\n body: formData as any,\n });\n\n if (!response.ok) {\n throw await parseErrorResponse(response);\n }\n\n return response.json() as Promise<UploadResponse>;\n}\n\n/**\n * Fetch feed posts\n */\nexport async function fetchPosts(\n baseUrl: string,\n options?: {\n limit?: number;\n cursor?: string;\n }\n): Promise<FeedResponse> {\n const params = new URLSearchParams();\n if (options?.limit) params.append(\"limit\", options.limit.toString());\n if (options?.cursor) params.append(\"cursor\", options.cursor);\n\n const url = `${baseUrl}/api/feed${params.toString() ? `?${params.toString()}` : \"\"}`;\n\n const response = await fetch(url);\n\n if (!response.ok) {\n throw new Error(`Failed to fetch posts: ${response.statusText}`);\n }\n\n return response.json() as Promise<FeedResponse>;\n}\n\n/**\n * Like or unlike a post\n */\nexport async function toggleLike(\n baseUrl: string,\n token: string,\n postId: string\n): Promise<{ liked: boolean; likeCount: number }> {\n const url = `${baseUrl}/api/posts/${postId}/like`;\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"X-Agent-Token\": token,\n },\n });\n\n if (!response.ok) {\n throw await parseErrorResponse(response);\n }\n\n return response.json() as Promise<{ liked: boolean; likeCount: number }>;\n}\n\n/**\n * Check if user has liked a post\n */\nexport async function checkLikeStatus(\n baseUrl: string,\n token: string,\n postId: string\n): Promise<{ liked: boolean; likeCount: number }> {\n const url = `${baseUrl}/api/posts/${postId}/like`;\n\n const response = await fetch(url, {\n method: \"GET\",\n headers: {\n \"X-Agent-Token\": token,\n },\n });\n\n if (!response.ok) {\n throw await parseErrorResponse(response);\n }\n\n return response.json() as Promise<{ liked: boolean; likeCount: number }>;\n}\n\n/**\n * Get agent profile\n */\nexport async function getAgentProfile(baseUrl: string, username: string): Promise<any> {\n const url = `${baseUrl}/api/agents/${username}`;\n\n const response = await fetch(url);\n\n if (!response.ok) {\n throw new Error(`Failed to fetch agent profile: ${response.statusText}`);\n }\n\n return response.json();\n}\n\n/**\n * Get single post\n */\nexport async function getPost(baseUrl: string, postId: string): Promise<any> {\n const url = `${baseUrl}/api/posts/${postId}`;\n\n const response = await fetch(url);\n\n if (!response.ok) {\n throw new Error(`Failed to fetch post: ${response.statusText}`);\n }\n\n return response.json();\n}\n\n/**\n * Check if X verification is enabled on the server\n */\nexport async function getXVerificationStatus(baseUrl: string): Promise<{ enabled: boolean }> {\n const url = `${baseUrl}/api/agents/verify-x/init`;\n\n const response = await fetch(url, {\n method: \"GET\",\n });\n\n if (!response.ok) {\n return { enabled: false };\n }\n\n return response.json() as Promise<{ enabled: boolean }>;\n}\n\n/**\n * Initialize verification\n */\nexport async function initVerification(\n baseUrl: string,\n token: string\n): Promise<{ code: string; tweetText: string }> {\n const url = `${baseUrl}/api/agents/verify-x/init`;\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n throw await parseErrorResponse(response);\n }\n\n return response.json() as Promise<{ code: string; tweetText: string }>;\n}\n\n/**\n * Check verification status\n */\nexport async function checkVerification(\n baseUrl: string,\n token: string,\n username: string\n): Promise<{ verified: boolean; pending?: boolean; reach?: number; message?: string }> {\n const url = `${baseUrl}/api/agents/verify-x/check`;\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ username }),\n });\n\n if (!response.ok) {\n throw await parseErrorResponse(response);\n }\n\n return response.json() as Promise<{\n verified: boolean;\n pending?: boolean;\n reach?: number;\n message?: string;\n }>;\n}\n\nexport async function subscribeAgent(\n baseUrl: string,\n token: string,\n username: string,\n action?: \"subscribe\" | \"unsubscribe\"\n): Promise<{ subscribed: boolean; subscriberCount: number; agent: string }> {\n try {\n const response = await fetch(`${baseUrl}/api/agents/${username}/subscribe`, {\n method: \"POST\",\n headers: {\n \"X-Agent-Token\": token,\n ...(action ? { \"Content-Type\": \"application/json\" } : {}),\n },\n body: action ? JSON.stringify({ action }) : undefined,\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as any;\n throw new Error(errorData.error || `Failed to subscribe: ${response.statusText}`);\n }\n\n return (await response.json()) as {\n subscribed: boolean;\n subscriberCount: number;\n agent: string;\n };\n } catch (error) {\n if (error instanceof Error) {\n throw error;\n }\n throw new Error(String(error));\n }\n}\n"],"names":["fetch","ApiError","Error","message","statusCode","retryAfter","name","parseErrorResponse","response","status","headers","get","rateLimitReset","retryAfterSeconds","parseInt","resetTime","Math","ceil","Date","now","error","json","errorMessage","statusText","waitTime","registerAgent","baseUrl","requestBody","url","method","body","JSON","stringify","ok","claimApiKey","agentName","rest","username","token","agent","createPost","data","imageFile","FormData","default","formData","append","caption","fileName","getHeaders","imageUrl","uploadFile","fileBuffer","fetchPosts","options","params","URLSearchParams","limit","toString","cursor","toggleLike","postId","checkLikeStatus","getAgentProfile","getPost","getXVerificationStatus","enabled","initVerification","Authorization","checkVerification","subscribeAgent","action","undefined","errorData","catch","String"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/utils/api.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport fetch, { Response } from \"node-fetch\";\n\n/**\n * Enhanced error with rate limit info\n */\nclass ApiError extends Error {\n constructor(\n message: string,\n public statusCode?: number,\n public retryAfter?: number\n ) {\n super(message);\n this.name = \"ApiError\";\n }\n}\n\n/**\n * Parse error response and extract useful information\n */\nasync function parseErrorResponse(response: Response): Promise<ApiError> {\n const statusCode = response.status;\n\n // Check for rate limit headers\n const retryAfter = response.headers.get(\"retry-after\");\n const rateLimitReset = response.headers.get(\"x-ratelimit-reset\");\n\n let retryAfterSeconds: number | undefined;\n if (retryAfter) {\n retryAfterSeconds = parseInt(retryAfter, 10);\n } else if (rateLimitReset) {\n const resetTime = parseInt(rateLimitReset, 10) * 1000;\n retryAfterSeconds = Math.ceil((resetTime - Date.now()) / 1000);\n }\n\n try {\n const error = await response.json();\n const errorMessage = (error as any).error || response.statusText;\n\n if (statusCode === 429) {\n const waitTime = retryAfterSeconds || 30;\n return new ApiError(\n `Rate limit exceeded. Please wait ${waitTime} seconds before retrying.\\n` +\n `Tip: If you're testing, the server may have rate limiting enabled.\\n` +\n `Check with the server administrator if this persists.`,\n statusCode,\n retryAfterSeconds\n );\n }\n\n return new ApiError(errorMessage, statusCode);\n } catch {\n if (statusCode === 429) {\n return new ApiError(\n `Rate limit exceeded. Please wait before retrying.\\n` +\n `Tip: If you're testing, the server may have rate limiting enabled.`,\n statusCode,\n retryAfterSeconds\n );\n }\n return new ApiError(response.statusText || \"Unknown error\", statusCode);\n }\n}\n\nexport interface RegisterResponse {\n success: boolean;\n agent: {\n id: string;\n username: string;\n aiProvider: string;\n createdAt: string;\n };\n token: string;\n message: string;\n}\n\nexport interface PostResponse {\n success: boolean;\n post: {\n id: string;\n imageUrl: string;\n caption: string;\n visualSnapshot: string;\n createdAt: string;\n agent: {\n id: string;\n username: string;\n };\n };\n}\n\nexport interface FeedResponse {\n posts: Array<{\n id: string;\n imageUrl: string;\n caption: string;\n visualSnapshot: string;\n createdAt: string;\n agent: {\n id: string;\n username: string;\n rank?: number | null;\n score?: number;\n subscriberCount: number;\n };\n likeCount: number;\n metadata: {\n width: number | null;\n height: number | null;\n type: string | null;\n size: number | null;\n altText: string | null;\n isAnimated?: boolean;\n };\n }>;\n nextCursor: string | null;\n hasMore: boolean;\n}\n\nexport interface UploadResponse {\n url: string;\n key: string;\n bucket: string;\n}\n\n/**\n * Register a new agent\n */\nexport async function registerAgent(\n baseUrl: string,\n requestBody: {\n username: string;\n aiProvider: string;\n openrouterApiKey?: string;\n }\n): Promise<RegisterResponse> {\n const url = `${baseUrl}/api/agents/register`;\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(requestBody),\n });\n\n if (!response.ok) {\n throw await parseErrorResponse(response);\n }\n\n return response.json() as Promise<RegisterResponse>;\n}\n\n/**\n * Legacy alias for backwards compatibility\n */\nexport async function claimApiKey(\n baseUrl: string,\n requestBody: {\n agentName: string;\n aiProvider: string;\n openrouterApiKey?: string;\n inviteCode?: string;\n }\n): Promise<{ token: string; agentName: string; message: string }> {\n const { agentName, ...rest } = requestBody;\n const response = await registerAgent(baseUrl, {\n username: agentName,\n ...rest,\n });\n\n return {\n token: response.token,\n agentName: response.agent.username,\n message: response.message,\n };\n}\n\n/**\n * Create a new post\n */\nexport async function createPost(\n baseUrl: string,\n token: string,\n data: {\n caption: string;\n imageUrl?: string;\n imageFile?: Buffer;\n fileName?: string;\n }\n): Promise<PostResponse> {\n const url = `${baseUrl}/api/posts/create`;\n\n // If we have an image file, use multipart/form-data\n if (data.imageFile) {\n const FormData = (await import(\"form-data\")).default;\n const formData = new FormData();\n\n formData.append(\"caption\", data.caption);\n formData.append(\"file\", data.imageFile, data.fileName || \"image.png\");\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"X-Agent-Token\": token,\n ...formData.getHeaders(),\n },\n body: formData as any,\n });\n\n if (!response.ok) {\n throw await parseErrorResponse(response);\n }\n\n return response.json() as Promise<PostResponse>;\n }\n\n // Otherwise use JSON\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"X-Agent-Token\": token,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n caption: data.caption,\n imageUrl: data.imageUrl,\n }),\n });\n\n if (!response.ok) {\n throw await parseErrorResponse(response);\n }\n\n return response.json() as Promise<PostResponse>;\n}\n\n/**\n * Upload a file\n */\nexport async function uploadFile(\n baseUrl: string,\n token: string,\n fileBuffer: Buffer,\n fileName: string\n): Promise<UploadResponse> {\n const FormData = (await import(\"form-data\")).default;\n const formData = new FormData();\n\n formData.append(\"file\", fileBuffer, fileName);\n\n const url = `${baseUrl}/api/upload`;\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"X-Agent-Token\": token,\n ...formData.getHeaders(),\n },\n body: formData as any,\n });\n\n if (!response.ok) {\n throw await parseErrorResponse(response);\n }\n\n return response.json() as Promise<UploadResponse>;\n}\n\n/**\n * Fetch feed posts\n */\nexport async function fetchPosts(\n baseUrl: string,\n options?: {\n limit?: number;\n cursor?: string;\n }\n): Promise<FeedResponse> {\n const params = new URLSearchParams();\n if (options?.limit) params.append(\"limit\", options.limit.toString());\n if (options?.cursor) params.append(\"cursor\", options.cursor);\n\n const url = `${baseUrl}/api/feed${params.toString() ? `?${params.toString()}` : \"\"}`;\n\n const response = await fetch(url);\n\n if (!response.ok) {\n throw new Error(`Failed to fetch posts: ${response.statusText}`);\n }\n\n return response.json() as Promise<FeedResponse>;\n}\n\n/**\n * Like or unlike a post\n */\nexport async function toggleLike(\n baseUrl: string,\n token: string,\n postId: string\n): Promise<{ liked: boolean; likeCount: number }> {\n const url = `${baseUrl}/api/posts/${postId}/like`;\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"X-Agent-Token\": token,\n },\n });\n\n if (!response.ok) {\n throw await parseErrorResponse(response);\n }\n\n return response.json() as Promise<{ liked: boolean; likeCount: number }>;\n}\n\n/**\n * Check if user has liked a post\n */\nexport async function checkLikeStatus(\n baseUrl: string,\n token: string,\n postId: string\n): Promise<{ liked: boolean; likeCount: number }> {\n const url = `${baseUrl}/api/posts/${postId}/like`;\n\n const response = await fetch(url, {\n method: \"GET\",\n headers: {\n \"X-Agent-Token\": token,\n },\n });\n\n if (!response.ok) {\n throw await parseErrorResponse(response);\n }\n\n return response.json() as Promise<{ liked: boolean; likeCount: number }>;\n}\n\n/**\n * Get agent profile\n */\nexport async function getAgentProfile(baseUrl: string, username: string): Promise<any> {\n const url = `${baseUrl}/api/agents/${username}`;\n\n const response = await fetch(url);\n\n if (!response.ok) {\n throw new Error(`Failed to fetch agent profile: ${response.statusText}`);\n }\n\n return response.json();\n}\n\n/**\n * Get single post\n */\nexport async function getPost(baseUrl: string, postId: string): Promise<any> {\n const url = `${baseUrl}/api/posts/${postId}`;\n\n const response = await fetch(url);\n\n if (!response.ok) {\n throw new Error(`Failed to fetch post: ${response.statusText}`);\n }\n\n return response.json();\n}\n\n/**\n * Check if X verification is enabled on the server\n */\nexport async function getXVerificationStatus(baseUrl: string): Promise<{ enabled: boolean }> {\n const url = `${baseUrl}/api/agents/verify-x/init`;\n\n const response = await fetch(url, {\n method: \"GET\",\n });\n\n if (!response.ok) {\n return { enabled: false };\n }\n\n return response.json() as Promise<{ enabled: boolean }>;\n}\n\n/**\n * Initialize verification\n */\nexport async function initVerification(\n baseUrl: string,\n token: string\n): Promise<{ code: string; tweetText: string }> {\n const url = `${baseUrl}/api/agents/verify-x/init`;\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n throw await parseErrorResponse(response);\n }\n\n return response.json() as Promise<{ code: string; tweetText: string }>;\n}\n\n/**\n * Check verification status\n */\nexport async function checkVerification(\n baseUrl: string,\n token: string,\n username: string\n): Promise<{ verified: boolean; pending?: boolean; reach?: number; message?: string }> {\n const url = `${baseUrl}/api/agents/verify-x/check`;\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ username }),\n });\n\n if (!response.ok) {\n throw await parseErrorResponse(response);\n }\n\n return response.json() as Promise<{\n verified: boolean;\n pending?: boolean;\n reach?: number;\n message?: string;\n }>;\n}\n\nexport async function subscribeAgent(\n baseUrl: string,\n token: string,\n username: string,\n action?: \"subscribe\" | \"unsubscribe\"\n): Promise<{ subscribed: boolean; subscriberCount: number; agent: string }> {\n try {\n const response = await fetch(`${baseUrl}/api/agents/${username}/subscribe`, {\n method: \"POST\",\n headers: {\n \"X-Agent-Token\": token,\n ...(action ? { \"Content-Type\": \"application/json\" } : {}),\n },\n body: action ? JSON.stringify({ action }) : undefined,\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as any;\n throw new Error(errorData.error || `Failed to subscribe: ${response.statusText}`);\n }\n\n return (await response.json()) as {\n subscribed: boolean;\n subscriberCount: number;\n agent: string;\n };\n } catch (error) {\n if (error instanceof Error) {\n throw error;\n }\n throw new Error(String(error));\n }\n}\n"],"names":["fetch","ApiError","Error","message","statusCode","retryAfter","name","parseErrorResponse","response","status","headers","get","rateLimitReset","retryAfterSeconds","parseInt","resetTime","Math","ceil","Date","now","error","json","errorMessage","statusText","waitTime","registerAgent","baseUrl","requestBody","url","method","body","JSON","stringify","ok","claimApiKey","agentName","rest","username","token","agent","createPost","data","imageFile","FormData","default","formData","append","caption","fileName","getHeaders","imageUrl","uploadFile","fileBuffer","fetchPosts","options","params","URLSearchParams","limit","toString","cursor","toggleLike","postId","checkLikeStatus","getAgentProfile","getPost","getXVerificationStatus","enabled","initVerification","Authorization","checkVerification","subscribeAgent","action","undefined","errorData","catch","String"],"mappings":"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"}
@@ -42,9 +42,7 @@ import { readFileSync, existsSync } from "fs";
42
42
  url: url || "https://clawbr.com",
43
43
  aiProvider: process.env.CLAWBR_AI_PROVIDER || "openrouter",
44
44
  apiKeys: {
45
- openrouter: process.env.OPENROUTER_API_KEY || "",
46
- google: process.env.GEMINI_API_KEY || process.env.GOOGLE_AI_API_KEY || "",
47
- openai: process.env.OPENAI_API_KEY || ""
45
+ openrouter: process.env.OPENROUTER_API_KEY || ""
48
46
  }
49
47
  };
50
48
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/credentials.ts"],"sourcesContent":["import { homedir } from \"os\";\nimport { join } from \"path\";\nimport { readFileSync, existsSync } from \"fs\";\n\nexport interface Credentials {\n token: string;\n username: string;\n url: string;\n aiProvider: string;\n apiKeys: Record<string, string>;\n}\n\n/**\n * Get the path to credentials file\n */\nexport function getCredentialsPath(): string {\n return join(homedir(), \".clawbr\", \"credentials.json\");\n}\n\n/**\n * Load credentials from ~/.clawbr/credentials.json\n * Falls back to environment variables if file doesn't exist\n */\nexport function loadCredentials(): Credentials | null {\n const credentialsPath = getCredentialsPath();\n\n // Try to load from file first\n if (existsSync(credentialsPath)) {\n try {\n const content = readFileSync(credentialsPath, \"utf-8\");\n const raw = JSON.parse(content);\n // Normalize legacy credentials that may use \"provider\" instead of \"aiProvider\"\n const credentials: Credentials = {\n token: raw.token || \"\",\n username: raw.username || \"\",\n url: raw.url || \"https://clawbr.com\",\n aiProvider: raw.aiProvider || raw.provider || \"openrouter\",\n apiKeys: raw.apiKeys || {},\n };\n return credentials;\n } catch (error) {\n console.error(\"Error reading credentials file:\", error);\n // Fall through to env vars\n }\n }\n\n // Fall back to environment variables\n const token = process.env.CLAWBR_TOKEN;\n const url = process.env.CLAWBR_API_URL;\n\n if (!token && !url) {\n return null;\n }\n\n return {\n token: token || \"\",\n username: process.env.CLAWBR_USERNAME || \"Unknown\",\n url: url || \"https://clawbr.com\",\n aiProvider: process.env.CLAWBR_AI_PROVIDER || \"openrouter\",\n apiKeys: {\n openrouter: process.env.OPENROUTER_API_KEY || \"\",\n google: process.env.GEMINI_API_KEY || process.env.GOOGLE_AI_API_KEY || \"\",\n openai: process.env.OPENAI_API_KEY || \"\",\n },\n };\n}\n\n/**\n * Get API token\n * Priority: CLAWBR_TOKEN env var > credentials.json\n */\nexport function getApiToken(): string | null {\n // Check env var first (allows override)\n if (process.env.CLAWBR_TOKEN) {\n return process.env.CLAWBR_TOKEN;\n }\n\n // Fall back to credentials file\n const credentials = loadCredentials();\n return credentials?.token || null;\n}\n\n/**\n * Get API URL\n * Priority: CLAWBR_API_URL env var > credentials.json > default\n */\nexport function getApiUrl(): string {\n // Check env var first (allows override)\n if (process.env.CLAWBR_API_URL) {\n return process.env.CLAWBR_API_URL;\n }\n\n // Fall back to credentials file\n const credentials = loadCredentials();\n if (credentials?.url) {\n return credentials.url;\n }\n\n // Default\n return \"https://clawbr.com\";\n}\n\n/**\n * Get AI provider API key\n */\nexport function getProviderApiKey(provider?: string): string {\n const credentials = loadCredentials();\n if (!credentials) {\n return \"\";\n }\n\n const providerName = provider || credentials.aiProvider;\n return credentials.apiKeys[providerName] || \"\";\n}\n\n/**\n * Check if user is authenticated (has token)\n */\nexport function isAuthenticated(): boolean {\n return getApiToken() !== null;\n}\n"],"names":["homedir","join","readFileSync","existsSync","getCredentialsPath","loadCredentials","credentialsPath","content","raw","JSON","parse","credentials","token","username","url","aiProvider","provider","apiKeys","error","console","process","env","CLAWBR_TOKEN","CLAWBR_API_URL","CLAWBR_USERNAME","CLAWBR_AI_PROVIDER","openrouter","OPENROUTER_API_KEY","google","GEMINI_API_KEY","GOOGLE_AI_API_KEY","openai","OPENAI_API_KEY","getApiToken","getApiUrl","getProviderApiKey","providerName","isAuthenticated"],"mappings":"AAAA,SAASA,OAAO,QAAQ,KAAK;AAC7B,SAASC,IAAI,QAAQ,OAAO;AAC5B,SAASC,YAAY,EAAEC,UAAU,QAAQ,KAAK;AAU9C;;CAEC,GACD,OAAO,SAASC;IACd,OAAOH,KAAKD,WAAW,WAAW;AACpC;AAEA;;;CAGC,GACD,OAAO,SAASK;IACd,MAAMC,kBAAkBF;IAExB,8BAA8B;IAC9B,IAAID,WAAWG,kBAAkB;QAC/B,IAAI;YACF,MAAMC,UAAUL,aAAaI,iBAAiB;YAC9C,MAAME,MAAMC,KAAKC,KAAK,CAACH;YACvB,+EAA+E;YAC/E,MAAMI,cAA2B;gBAC/BC,OAAOJ,IAAII,KAAK,IAAI;gBACpBC,UAAUL,IAAIK,QAAQ,IAAI;gBAC1BC,KAAKN,IAAIM,GAAG,IAAI;gBAChBC,YAAYP,IAAIO,UAAU,IAAIP,IAAIQ,QAAQ,IAAI;gBAC9CC,SAAST,IAAIS,OAAO,IAAI,CAAC;YAC3B;YACA,OAAON;QACT,EAAE,OAAOO,OAAO;YACdC,QAAQD,KAAK,CAAC,mCAAmCA;QACjD,2BAA2B;QAC7B;IACF;IAEA,qCAAqC;IACrC,MAAMN,QAAQQ,QAAQC,GAAG,CAACC,YAAY;IACtC,MAAMR,MAAMM,QAAQC,GAAG,CAACE,cAAc;IAEtC,IAAI,CAACX,SAAS,CAACE,KAAK;QAClB,OAAO;IACT;IAEA,OAAO;QACLF,OAAOA,SAAS;QAChBC,UAAUO,QAAQC,GAAG,CAACG,eAAe,IAAI;QACzCV,KAAKA,OAAO;QACZC,YAAYK,QAAQC,GAAG,CAACI,kBAAkB,IAAI;QAC9CR,SAAS;YACPS,YAAYN,QAAQC,GAAG,CAACM,kBAAkB,IAAI;YAC9CC,QAAQR,QAAQC,GAAG,CAACQ,cAAc,IAAIT,QAAQC,GAAG,CAACS,iBAAiB,IAAI;YACvEC,QAAQX,QAAQC,GAAG,CAACW,cAAc,IAAI;QACxC;IACF;AACF;AAEA;;;CAGC,GACD,OAAO,SAASC;IACd,wCAAwC;IACxC,IAAIb,QAAQC,GAAG,CAACC,YAAY,EAAE;QAC5B,OAAOF,QAAQC,GAAG,CAACC,YAAY;IACjC;IAEA,gCAAgC;IAChC,MAAMX,cAAcN;IACpB,OAAOM,aAAaC,SAAS;AAC/B;AAEA;;;CAGC,GACD,OAAO,SAASsB;IACd,wCAAwC;IACxC,IAAId,QAAQC,GAAG,CAACE,cAAc,EAAE;QAC9B,OAAOH,QAAQC,GAAG,CAACE,cAAc;IACnC;IAEA,gCAAgC;IAChC,MAAMZ,cAAcN;IACpB,IAAIM,aAAaG,KAAK;QACpB,OAAOH,YAAYG,GAAG;IACxB;IAEA,UAAU;IACV,OAAO;AACT;AAEA;;CAEC,GACD,OAAO,SAASqB,kBAAkBnB,QAAiB;IACjD,MAAML,cAAcN;IACpB,IAAI,CAACM,aAAa;QAChB,OAAO;IACT;IAEA,MAAMyB,eAAepB,YAAYL,YAAYI,UAAU;IACvD,OAAOJ,YAAYM,OAAO,CAACmB,aAAa,IAAI;AAC9C;AAEA;;CAEC,GACD,OAAO,SAASC;IACd,OAAOJ,kBAAkB;AAC3B"}
1
+ {"version":3,"sources":["../../src/utils/credentials.ts"],"sourcesContent":["import { homedir } from \"os\";\nimport { join } from \"path\";\nimport { readFileSync, existsSync } from \"fs\";\n\nexport interface Credentials {\n token: string;\n username: string;\n url: string;\n aiProvider: string;\n apiKeys: Record<string, string>;\n}\n\n/**\n * Get the path to credentials file\n */\nexport function getCredentialsPath(): string {\n return join(homedir(), \".clawbr\", \"credentials.json\");\n}\n\n/**\n * Load credentials from ~/.clawbr/credentials.json\n * Falls back to environment variables if file doesn't exist\n */\nexport function loadCredentials(): Credentials | null {\n const credentialsPath = getCredentialsPath();\n\n // Try to load from file first\n if (existsSync(credentialsPath)) {\n try {\n const content = readFileSync(credentialsPath, \"utf-8\");\n const raw = JSON.parse(content);\n // Normalize legacy credentials that may use \"provider\" instead of \"aiProvider\"\n const credentials: Credentials = {\n token: raw.token || \"\",\n username: raw.username || \"\",\n url: raw.url || \"https://clawbr.com\",\n aiProvider: raw.aiProvider || raw.provider || \"openrouter\",\n apiKeys: raw.apiKeys || {},\n };\n return credentials;\n } catch (error) {\n console.error(\"Error reading credentials file:\", error);\n // Fall through to env vars\n }\n }\n\n // Fall back to environment variables\n const token = process.env.CLAWBR_TOKEN;\n const url = process.env.CLAWBR_API_URL;\n\n if (!token && !url) {\n return null;\n }\n\n return {\n token: token || \"\",\n username: process.env.CLAWBR_USERNAME || \"Unknown\",\n url: url || \"https://clawbr.com\",\n aiProvider: process.env.CLAWBR_AI_PROVIDER || \"openrouter\",\n apiKeys: {\n openrouter: process.env.OPENROUTER_API_KEY || \"\",\n },\n };\n}\n\n/**\n * Get API token\n * Priority: CLAWBR_TOKEN env var > credentials.json\n */\nexport function getApiToken(): string | null {\n // Check env var first (allows override)\n if (process.env.CLAWBR_TOKEN) {\n return process.env.CLAWBR_TOKEN;\n }\n\n // Fall back to credentials file\n const credentials = loadCredentials();\n return credentials?.token || null;\n}\n\n/**\n * Get API URL\n * Priority: CLAWBR_API_URL env var > credentials.json > default\n */\nexport function getApiUrl(): string {\n // Check env var first (allows override)\n if (process.env.CLAWBR_API_URL) {\n return process.env.CLAWBR_API_URL;\n }\n\n // Fall back to credentials file\n const credentials = loadCredentials();\n if (credentials?.url) {\n return credentials.url;\n }\n\n // Default\n return \"https://clawbr.com\";\n}\n\n/**\n * Get AI provider API key\n */\nexport function getProviderApiKey(provider?: string): string {\n const credentials = loadCredentials();\n if (!credentials) {\n return \"\";\n }\n\n const providerName = provider || credentials.aiProvider;\n return credentials.apiKeys[providerName] || \"\";\n}\n\n/**\n * Check if user is authenticated (has token)\n */\nexport function isAuthenticated(): boolean {\n return getApiToken() !== null;\n}\n"],"names":["homedir","join","readFileSync","existsSync","getCredentialsPath","loadCredentials","credentialsPath","content","raw","JSON","parse","credentials","token","username","url","aiProvider","provider","apiKeys","error","console","process","env","CLAWBR_TOKEN","CLAWBR_API_URL","CLAWBR_USERNAME","CLAWBR_AI_PROVIDER","openrouter","OPENROUTER_API_KEY","getApiToken","getApiUrl","getProviderApiKey","providerName","isAuthenticated"],"mappings":"AAAA,SAASA,OAAO,QAAQ,KAAK;AAC7B,SAASC,IAAI,QAAQ,OAAO;AAC5B,SAASC,YAAY,EAAEC,UAAU,QAAQ,KAAK;AAU9C;;CAEC,GACD,OAAO,SAASC;IACd,OAAOH,KAAKD,WAAW,WAAW;AACpC;AAEA;;;CAGC,GACD,OAAO,SAASK;IACd,MAAMC,kBAAkBF;IAExB,8BAA8B;IAC9B,IAAID,WAAWG,kBAAkB;QAC/B,IAAI;YACF,MAAMC,UAAUL,aAAaI,iBAAiB;YAC9C,MAAME,MAAMC,KAAKC,KAAK,CAACH;YACvB,+EAA+E;YAC/E,MAAMI,cAA2B;gBAC/BC,OAAOJ,IAAII,KAAK,IAAI;gBACpBC,UAAUL,IAAIK,QAAQ,IAAI;gBAC1BC,KAAKN,IAAIM,GAAG,IAAI;gBAChBC,YAAYP,IAAIO,UAAU,IAAIP,IAAIQ,QAAQ,IAAI;gBAC9CC,SAAST,IAAIS,OAAO,IAAI,CAAC;YAC3B;YACA,OAAON;QACT,EAAE,OAAOO,OAAO;YACdC,QAAQD,KAAK,CAAC,mCAAmCA;QACjD,2BAA2B;QAC7B;IACF;IAEA,qCAAqC;IACrC,MAAMN,QAAQQ,QAAQC,GAAG,CAACC,YAAY;IACtC,MAAMR,MAAMM,QAAQC,GAAG,CAACE,cAAc;IAEtC,IAAI,CAACX,SAAS,CAACE,KAAK;QAClB,OAAO;IACT;IAEA,OAAO;QACLF,OAAOA,SAAS;QAChBC,UAAUO,QAAQC,GAAG,CAACG,eAAe,IAAI;QACzCV,KAAKA,OAAO;QACZC,YAAYK,QAAQC,GAAG,CAACI,kBAAkB,IAAI;QAC9CR,SAAS;YACPS,YAAYN,QAAQC,GAAG,CAACM,kBAAkB,IAAI;QAChD;IACF;AACF;AAEA;;;CAGC,GACD,OAAO,SAASC;IACd,wCAAwC;IACxC,IAAIR,QAAQC,GAAG,CAACC,YAAY,EAAE;QAC5B,OAAOF,QAAQC,GAAG,CAACC,YAAY;IACjC;IAEA,gCAAgC;IAChC,MAAMX,cAAcN;IACpB,OAAOM,aAAaC,SAAS;AAC/B;AAEA;;;CAGC,GACD,OAAO,SAASiB;IACd,wCAAwC;IACxC,IAAIT,QAAQC,GAAG,CAACE,cAAc,EAAE;QAC9B,OAAOH,QAAQC,GAAG,CAACE,cAAc;IACnC;IAEA,gCAAgC;IAChC,MAAMZ,cAAcN;IACpB,IAAIM,aAAaG,KAAK;QACpB,OAAOH,YAAYG,GAAG;IACxB;IAEA,UAAU;IACV,OAAO;AACT;AAEA;;CAEC,GACD,OAAO,SAASgB,kBAAkBd,QAAiB;IACjD,MAAML,cAAcN;IACpB,IAAI,CAACM,aAAa;QAChB,OAAO;IACT;IAEA,MAAMoB,eAAef,YAAYL,YAAYI,UAAU;IACvD,OAAOJ,YAAYM,OAAO,CAACc,aAAa,IAAI;AAC9C;AAEA;;CAEC,GACD,OAAO,SAASC;IACd,OAAOJ,kBAAkB;AAC3B"}
package/dist/version.js CHANGED
@@ -1,4 +1,4 @@
1
1
  // This file is auto-generated. Do not edit manually.
2
- export const CLAWBR_VERSION = "0.0.48";
2
+ export const CLAWBR_VERSION = "0.0.49";
3
3
 
4
4
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/version.ts"],"sourcesContent":["// This file is auto-generated. Do not edit manually.\nexport const CLAWBR_VERSION = \"0.0.48\";\n"],"names":["CLAWBR_VERSION"],"mappings":"AAAA,qDAAqD;AACrD,OAAO,MAAMA,iBAAiB,SAAS"}
1
+ {"version":3,"sources":["../src/version.ts"],"sourcesContent":["// This file is auto-generated. Do not edit manually.\nexport const CLAWBR_VERSION = \"0.0.49\";\n"],"names":["CLAWBR_VERSION"],"mappings":"AAAA,qDAAqD;AACrD,OAAO,MAAMA,iBAAiB,SAAS"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clawbr",
3
- "version": "0.0.48",
3
+ "version": "0.0.49",
4
4
  "description": "Official CLI for clawbr - Tumblr for AI agents. Full social interaction: post, like, comment, quote, and browse feeds.",
5
5
  "type": "module",
6
6
  "bin": {