@forvibe/cli 0.1.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +41 -128
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1885,61 +1885,6 @@ var ForvibeClient = class {
1885
1885
  }
1886
1886
  return await response.json();
1887
1887
  }
1888
- /**
1889
- * Send raw project data to backend for AI analysis (Gemini proxy)
1890
- */
1891
- async analyzeProject(input) {
1892
- if (!this.sessionToken) {
1893
- throw new Error("Not connected. Please validate OTC code first.");
1894
- }
1895
- const response = await fetch(`${this.baseUrl}/api/agent/analyze`, {
1896
- method: "POST",
1897
- headers: {
1898
- "Content-Type": "application/json",
1899
- Authorization: `Bearer ${this.sessionToken}`
1900
- },
1901
- body: JSON.stringify({
1902
- tech_stack: {
1903
- stack: input.techStack.stack,
1904
- label: input.techStack.label,
1905
- platforms: input.techStack.platforms,
1906
- configFiles: input.techStack.configFiles
1907
- },
1908
- config: {
1909
- app_name: input.config.app_name,
1910
- bundle_id: input.config.bundle_id,
1911
- version: input.config.version,
1912
- min_ios_version: input.config.min_ios_version,
1913
- min_android_sdk: input.config.min_android_sdk,
1914
- description: input.config.description
1915
- },
1916
- sdk_scan: {
1917
- detected_sdks: input.sdkScan.detected_sdks,
1918
- data_collected: input.sdkScan.data_collected,
1919
- advertising_type: input.sdkScan.advertising_type,
1920
- third_party_services: input.sdkScan.third_party_services,
1921
- has_iap: input.sdkScan.has_iap
1922
- },
1923
- branding: {
1924
- primary_color: input.branding.primary_color,
1925
- secondary_color: input.branding.secondary_color,
1926
- app_icon_base64: input.branding.app_icon_base64
1927
- },
1928
- readme_content: input.readmeContent,
1929
- source_code: input.sourceCode,
1930
- project_tree: input.projectTree
1931
- }),
1932
- signal: AbortSignal.timeout(12e4)
1933
- });
1934
- if (!response.ok) {
1935
- const error = await response.json().catch(() => ({ error: "Unknown error" }));
1936
- if (response.status === 401) {
1937
- throw new Error("Session expired. Please generate a new connection code.");
1938
- }
1939
- throw new Error(error.error || `Analysis failed (${response.status})`);
1940
- }
1941
- return await response.json();
1942
- }
1943
1888
  };
1944
1889
 
1945
1890
  // src/commands/analyze.ts
@@ -1962,6 +1907,15 @@ async function analyzeCommand(options) {
1962
1907
  chalk.bold(" Forvibe CLI") + chalk.gray(" \u2014 AI-powered App Store automation")
1963
1908
  );
1964
1909
  console.log();
1910
+ const geminiApiKey = process.env.GEMINI_API_KEY || process.env.GOOGLE_AI_API_KEY;
1911
+ if (!geminiApiKey) {
1912
+ console.log(chalk.red(" \u2717 Gemini API key is required for project analysis.\n"));
1913
+ console.log(chalk.white(" Set your API key:"));
1914
+ console.log(chalk.cyan(" export GEMINI_API_KEY=your-api-key-here\n"));
1915
+ console.log(chalk.gray(" Get a free API key at: https://aistudio.google.com/apikey"));
1916
+ console.log(chalk.gray(" Your source code is analyzed locally \u2014 it never leaves your machine.\n"));
1917
+ process.exit(1);
1918
+ }
1965
1919
  const otcCode = await askQuestion(
1966
1920
  chalk.cyan(" \u{1F517} Enter your Forvibe connection code: ")
1967
1921
  );
@@ -2061,78 +2015,40 @@ async function analyzeCommand(options) {
2061
2015
  `Source code: ${chalk.bold(String(sourceLines))} lines analyzed ${readmeContent ? chalk.gray("(README found)") : ""}`
2062
2016
  );
2063
2017
  console.log();
2064
- const useLocalAI = options.local && (process.env.GEMINI_API_KEY || process.env.GOOGLE_AI_API_KEY);
2065
2018
  let report;
2066
- if (useLocalAI) {
2067
- console.log(chalk.yellow(" \u26A0 Using local Gemini API (deprecated \u2014 will be removed in a future version)"));
2068
- const geminiApiKey = process.env.GEMINI_API_KEY || process.env.GOOGLE_AI_API_KEY;
2069
- const aiSpinner = ora({
2070
- text: "AI is analyzing your project...",
2071
- prefixText: " "
2072
- }).start();
2073
- try {
2074
- const { generateReport } = await import("./report-generator-NMGCGKPS.js");
2075
- report = await generateReport(
2076
- { techStack, config, sdkScan, branding, readmeContent, sourceCode, projectTree },
2077
- geminiApiKey
2078
- );
2079
- if (appAssets.length > 0) {
2080
- report.app_assets = appAssets;
2081
- }
2082
- aiSpinner.succeed(chalk.green("Analysis complete!"));
2083
- } catch (error) {
2084
- aiSpinner.fail(
2085
- chalk.red(`AI analysis failed: ${error instanceof Error ? error.message : "Unknown error"}`)
2086
- );
2087
- process.exit(1);
2088
- }
2089
- const asoSpinner = ora({
2090
- text: "Generating ASO-optimized store listing...",
2091
- prefixText: " "
2092
- }).start();
2093
- try {
2094
- const { generateASOContent } = await import("./aso-generator-AZXT6ZCL.js");
2095
- const asoContent = await generateASOContent(report, geminiApiKey);
2096
- report.aso_content = asoContent;
2097
- asoSpinner.succeed(chalk.green("Store listing content generated!"));
2098
- } catch (error) {
2099
- asoSpinner.warn(
2100
- chalk.yellow(`ASO generation skipped: ${error instanceof Error ? error.message : "Unknown error"}`)
2101
- );
2102
- }
2103
- } else {
2104
- const aiSpinner = ora({
2105
- text: "Analyzing your project...",
2106
- prefixText: " "
2107
- }).start();
2108
- try {
2109
- const result = await client.analyzeProject({
2110
- techStack,
2111
- config,
2112
- sdkScan,
2113
- branding,
2114
- readmeContent,
2115
- sourceCode,
2116
- projectTree
2117
- });
2118
- report = result.report;
2119
- if (appAssets.length > 0) {
2120
- report.app_assets = appAssets;
2121
- }
2122
- if (result.warnings && result.warnings.length > 0) {
2123
- aiSpinner.succeed(chalk.green("Analysis complete!"));
2124
- for (const warning of result.warnings) {
2125
- console.log(chalk.yellow(` \u26A0 ${warning}`));
2126
- }
2127
- } else {
2128
- aiSpinner.succeed(chalk.green("Analysis complete!"));
2129
- }
2130
- } catch (error) {
2131
- aiSpinner.fail(
2132
- chalk.red(`Analysis failed: ${error instanceof Error ? error.message : "Unknown error"}`)
2133
- );
2134
- process.exit(1);
2019
+ const aiSpinner = ora({
2020
+ text: "Analyzing locally with Gemini AI (your source code never leaves your machine)...",
2021
+ prefixText: " "
2022
+ }).start();
2023
+ try {
2024
+ const { generateReport } = await import("./report-generator-NMGCGKPS.js");
2025
+ report = await generateReport(
2026
+ { techStack, config, sdkScan, branding, readmeContent, sourceCode, projectTree },
2027
+ geminiApiKey
2028
+ );
2029
+ if (appAssets.length > 0) {
2030
+ report.app_assets = appAssets;
2135
2031
  }
2032
+ aiSpinner.succeed(chalk.green("Analysis complete!"));
2033
+ } catch (error) {
2034
+ aiSpinner.fail(
2035
+ chalk.red(`AI analysis failed: ${error instanceof Error ? error.message : "Unknown error"}`)
2036
+ );
2037
+ process.exit(1);
2038
+ }
2039
+ const asoSpinner = ora({
2040
+ text: "Generating ASO-optimized store listing...",
2041
+ prefixText: " "
2042
+ }).start();
2043
+ try {
2044
+ const { generateASOContent } = await import("./aso-generator-AZXT6ZCL.js");
2045
+ const asoContent = await generateASOContent(report, geminiApiKey);
2046
+ report.aso_content = asoContent;
2047
+ asoSpinner.succeed(chalk.green("Store listing content generated!"));
2048
+ } catch (error) {
2049
+ asoSpinner.warn(
2050
+ chalk.yellow(`ASO generation skipped: ${error instanceof Error ? error.message : "Unknown error"}`)
2051
+ );
2136
2052
  }
2137
2053
  console.log();
2138
2054
  console.log(chalk.bold(" \u{1F4CB} Report Summary"));
@@ -2208,8 +2124,5 @@ program.command("analyze", { isDefault: true }).description(
2208
2124
  "--api-url <url>",
2209
2125
  "Forvibe API URL (for development)",
2210
2126
  void 0
2211
- ).option(
2212
- "--local",
2213
- "Use local Gemini API key instead of Forvibe backend (requires GEMINI_API_KEY env var)"
2214
2127
  ).action(analyzeCommand);
2215
2128
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forvibe/cli",
3
- "version": "0.1.0",
3
+ "version": "1.0.0",
4
4
  "description": "Forvibe CLI - AI-powered project analyzer for App Store automation",
5
5
  "type": "module",
6
6
  "bin": {