@qlucent/fishi 0.7.0 → 0.8.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 +196 -3
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  // src/index.ts
4
4
  import { Command } from "commander";
5
- import chalk9 from "chalk";
5
+ import chalk11 from "chalk";
6
6
 
7
7
  // src/commands/init.ts
8
8
  import chalk from "chalk";
@@ -1970,11 +1970,202 @@ async function sandboxCommand(action) {
1970
1970
  }
1971
1971
  }
1972
1972
 
1973
+ // src/commands/quickstart.ts
1974
+ import chalk9 from "chalk";
1975
+ import ora2 from "ora";
1976
+ import path11 from "path";
1977
+ import fs11 from "fs";
1978
+ import { detectDevServer, startDevServer, getVibeModeConfig } from "@qlucent/fishi-core";
1979
+ import { detectConflicts as detectConflicts2, createBackup as createBackup2 } from "@qlucent/fishi-core";
1980
+ import { detectDocker as detectDocker3 } from "@qlucent/fishi-core";
1981
+ async function quickstartCommand(description, options) {
1982
+ const targetDir = process.cwd();
1983
+ const projectName = path11.basename(targetDir);
1984
+ console.log("");
1985
+ console.log(chalk9.cyan.bold(" FISHI \u2014 Vibe Mode"));
1986
+ console.log(chalk9.gray(" Skip the ceremony, start shipping"));
1987
+ console.log("");
1988
+ if (fs11.existsSync(path11.join(targetDir, ".fishi"))) {
1989
+ console.log(chalk9.yellow(" FISHI already initialized. Starting dev server only..."));
1990
+ const serverConfig2 = detectDevServer(targetDir, options.devCmd);
1991
+ if (serverConfig2.detected) {
1992
+ console.log(chalk9.green(` Starting ${serverConfig2.framework} dev server on :${serverConfig2.port}...`));
1993
+ const child = startDevServer(targetDir, serverConfig2);
1994
+ child.stdout?.on("data", (d) => process.stdout.write(d));
1995
+ child.stderr?.on("data", (d) => process.stderr.write(d));
1996
+ child.on("close", (code) => process.exit(code || 0));
1997
+ return;
1998
+ }
1999
+ console.log(chalk9.yellow(" Could not detect dev server. Use --dev-cmd to specify."));
2000
+ return;
2001
+ }
2002
+ const spinner = ora2("Analyzing project...").start();
2003
+ const detection = await detectProjectType(targetDir);
2004
+ spinner.succeed(`Project type: ${chalk9.bold(detection.type)}`);
2005
+ let brownfieldAnalysis = null;
2006
+ if (detection.type === "brownfield" || detection.type === "hybrid") {
2007
+ const analysisSpinner = ora2("Running brownfield analysis...").start();
2008
+ brownfieldAnalysis = await runBrownfieldAnalysis(targetDir);
2009
+ analysisSpinner.succeed("Brownfield analysis complete");
2010
+ }
2011
+ const conflictResult = detectConflicts2(targetDir);
2012
+ let resolutions;
2013
+ if (conflictResult.hasConflicts) {
2014
+ console.log(chalk9.yellow(` Auto-merging ${conflictResult.totalConflicts} conflicting files (vibe mode)...`));
2015
+ const allPaths = conflictResult.categories.flatMap((c) => c.conflicts.map((f) => f.path));
2016
+ await createBackup2(targetDir, allPaths);
2017
+ resolutions = { categories: {}, files: {} };
2018
+ for (const cat of conflictResult.categories) {
2019
+ if (cat.conflicts.length > 0) {
2020
+ const noMerge = ["agents", "skills", "commands"];
2021
+ resolutions.categories[cat.name] = noMerge.includes(cat.name) ? "skip" : "merge";
2022
+ }
2023
+ }
2024
+ }
2025
+ const initOptions = {
2026
+ description: description || `${projectName} project`,
2027
+ interactive: false,
2028
+ costMode: options.costMode || "balanced",
2029
+ language: options.language || brownfieldAnalysis?.language,
2030
+ framework: options.framework || brownfieldAnalysis?.framework
2031
+ };
2032
+ let brownfieldData = void 0;
2033
+ if (brownfieldAnalysis) {
2034
+ brownfieldData = {
2035
+ language: brownfieldAnalysis.language,
2036
+ framework: brownfieldAnalysis.framework,
2037
+ testFramework: brownfieldAnalysis.testFramework,
2038
+ packageManager: brownfieldAnalysis.packageManager,
2039
+ linter: brownfieldAnalysis.linter,
2040
+ formatter: brownfieldAnalysis.formatter,
2041
+ cssFramework: brownfieldAnalysis.cssFramework,
2042
+ orm: brownfieldAnalysis.orm,
2043
+ database: brownfieldAnalysis.database,
2044
+ authProvider: brownfieldAnalysis.authProvider,
2045
+ apiStyle: brownfieldAnalysis.apiStyle,
2046
+ monorepo: brownfieldAnalysis.monorepo,
2047
+ conventions: brownfieldAnalysis.conventions,
2048
+ codePatterns: brownfieldAnalysis.codePatterns,
2049
+ fileStats: {
2050
+ totalFiles: brownfieldAnalysis.fileStats.totalFiles,
2051
+ codeFiles: brownfieldAnalysis.fileStats.codeFiles,
2052
+ testFiles: brownfieldAnalysis.fileStats.testFiles
2053
+ }
2054
+ };
2055
+ }
2056
+ const scaffoldSpinner = ora2("Scaffolding FISHI...").start();
2057
+ try {
2058
+ const result = await scaffold(targetDir, {
2059
+ ...initOptions,
2060
+ projectName,
2061
+ projectType: detection.type,
2062
+ brownfieldAnalysis: brownfieldData,
2063
+ resolutions,
2064
+ docsReadmeExists: conflictResult.docsReadmeExists,
2065
+ rootClaudeMdExists: conflictResult.rootClaudeMdExists
2066
+ });
2067
+ scaffoldSpinner.succeed(`Scaffolded: ${result.agentCount} agents, ${result.skillCount} skills, ${result.commandCount} commands`);
2068
+ } catch (error) {
2069
+ scaffoldSpinner.fail("Scaffolding failed");
2070
+ console.error(chalk9.red(` Error: ${error instanceof Error ? error.message : error}`));
2071
+ process.exit(1);
2072
+ }
2073
+ const fishiYamlPath = path11.join(targetDir, ".fishi", "fishi.yaml");
2074
+ if (fs11.existsSync(fishiYamlPath)) {
2075
+ fs11.appendFileSync(fishiYamlPath, getVibeModeConfig(true), "utf-8");
2076
+ }
2077
+ const dockerAvailable = detectDocker3();
2078
+ const sandboxMode = dockerAvailable ? "docker" : "process";
2079
+ fs11.appendFileSync(fishiYamlPath, `
2080
+ sandbox:
2081
+ mode: ${sandboxMode}
2082
+ docker_available: ${dockerAvailable}
2083
+ `, "utf-8");
2084
+ const projectYamlPath = path11.join(targetDir, ".fishi", "state", "project.yaml");
2085
+ if (fs11.existsSync(projectYamlPath)) {
2086
+ let content = fs11.readFileSync(projectYamlPath, "utf-8");
2087
+ content = content.replace(/^phase:\s*.+$/m, "phase: development");
2088
+ fs11.writeFileSync(projectYamlPath, content, "utf-8");
2089
+ }
2090
+ const serverConfig = detectDevServer(targetDir, options.devCmd);
2091
+ console.log("");
2092
+ console.log(chalk9.cyan.bold(" Vibe Mode Active"));
2093
+ console.log(chalk9.gray(` Phase: ${chalk9.green("development")} (gates auto-skipped)`));
2094
+ console.log(chalk9.gray(` Sandbox: ${sandboxMode}`));
2095
+ if (serverConfig.detected) {
2096
+ const port = options.port ? parseInt(options.port, 10) : serverConfig.port;
2097
+ console.log(chalk9.gray(` Dev server: ${serverConfig.framework} on :${port}`));
2098
+ console.log("");
2099
+ console.log(chalk9.green.bold(` Preview: http://localhost:${port}`));
2100
+ console.log("");
2101
+ console.log(chalk9.gray(" Starting dev server..."));
2102
+ console.log("");
2103
+ const child = startDevServer(targetDir, { ...serverConfig, port });
2104
+ child.stdout?.on("data", (d) => process.stdout.write(d));
2105
+ child.stderr?.on("data", (d) => process.stderr.write(d));
2106
+ child.on("close", (code) => {
2107
+ console.log(chalk9.gray(`
2108
+ Dev server stopped (exit ${code})`));
2109
+ });
2110
+ process.on("SIGINT", () => {
2111
+ child.kill();
2112
+ console.log(chalk9.gray("\n Dev server stopped."));
2113
+ process.exit(0);
2114
+ });
2115
+ } else {
2116
+ console.log("");
2117
+ console.log(chalk9.yellow(" No dev server detected. Run your dev server manually."));
2118
+ console.log(chalk9.gray(' Or use: fishi quickstart --dev-cmd "npm run dev"'));
2119
+ console.log("");
2120
+ console.log(chalk9.cyan.bold(" Ready to ship!"));
2121
+ console.log(chalk9.gray(" Run `claude` to start working with your AI dev team."));
2122
+ console.log("");
2123
+ }
2124
+ }
2125
+
2126
+ // src/commands/preview.ts
2127
+ import chalk10 from "chalk";
2128
+ import fs12 from "fs";
2129
+ import path12 from "path";
2130
+ import { detectDevServer as detectDevServer2, startDevServer as startDevServer2 } from "@qlucent/fishi-core";
2131
+ async function previewCommand(options) {
2132
+ const targetDir = process.cwd();
2133
+ if (!fs12.existsSync(path12.join(targetDir, ".fishi"))) {
2134
+ console.log(chalk10.yellow(" No FISHI project found. Run `fishi init` or `fishi quickstart` first."));
2135
+ return;
2136
+ }
2137
+ const serverConfig = detectDevServer2(targetDir, options.devCmd);
2138
+ if (!serverConfig.detected) {
2139
+ console.log(chalk10.yellow(" Could not detect dev server."));
2140
+ console.log(chalk10.gray(' Use --dev-cmd to specify: fishi preview --dev-cmd "npm run dev"'));
2141
+ return;
2142
+ }
2143
+ const port = options.port ? parseInt(options.port, 10) : serverConfig.port;
2144
+ console.log("");
2145
+ console.log(chalk10.cyan.bold(" FISHI Live Preview"));
2146
+ console.log(chalk10.gray(` Framework: ${serverConfig.framework}`));
2147
+ console.log(chalk10.green.bold(` URL: http://localhost:${port}`));
2148
+ console.log(chalk10.gray(" Press Ctrl+C to stop"));
2149
+ console.log("");
2150
+ const child = startDevServer2(targetDir, { ...serverConfig, port });
2151
+ child.stdout?.on("data", (d) => process.stdout.write(d));
2152
+ child.stderr?.on("data", (d) => process.stderr.write(d));
2153
+ child.on("close", (code) => {
2154
+ console.log(chalk10.gray(`
2155
+ Dev server stopped (exit ${code})`));
2156
+ });
2157
+ process.on("SIGINT", () => {
2158
+ child.kill();
2159
+ console.log(chalk10.gray("\n Dev server stopped."));
2160
+ process.exit(0);
2161
+ });
2162
+ }
2163
+
1973
2164
  // src/index.ts
1974
2165
  var program = new Command();
1975
2166
  program.name("fishi").description(
1976
- chalk9.cyan("\u{1F41F} FISHI") + " \u2014 Your AI Dev Team That Actually Ships\n Autonomous agent framework for Claude Code"
1977
- ).version("0.7.0");
2167
+ chalk11.cyan("\u{1F41F} FISHI") + " \u2014 Your AI Dev Team That Actually Ships\n Autonomous agent framework for Claude Code"
2168
+ ).version("0.8.0");
1978
2169
  program.command("init").description("Initialize FISHI in the current directory").argument("[description]", "Project description (skip wizard with zero-config)").option("-l, --language <lang>", "Primary language (e.g., typescript, python)").option("-f, --framework <framework>", "Framework (e.g., nextjs, express, django)").option(
1979
2170
  "-c, --cost-mode <mode>",
1980
2171
  "Cost mode: performance | balanced | economy",
@@ -1987,4 +2178,6 @@ program.command("validate").description("Validate scaffold integrity \u2014 chec
1987
2178
  program.command("monitor").description("Agent observability \u2014 TUI dashboard showing agent activity, tokens, gates").option("-w, --watch", "Watch mode \u2014 auto-refresh on changes").action(monitorCommand);
1988
2179
  program.command("dashboard").description("Agent observability \u2014 web dashboard at http://localhost:4269").option("-p, --port <port>", "Port number", "4269").action(dashboardCommand);
1989
2180
  program.command("sandbox").description("Sandbox status and policy management").argument("<action>", "Action: status | policy").action(sandboxCommand);
2181
+ program.command("quickstart").description("Vibe mode \u2014 skip gates, scaffold + start dev server immediately").argument("[description]", "What are you building?").option("-l, --language <lang>", "Primary language").option("-f, --framework <framework>", "Framework").option("-c, --cost-mode <mode>", "Cost mode", "balanced").option("--dev-cmd <cmd>", "Custom dev server command").option("--port <port>", "Dev server port").action(quickstartCommand);
2182
+ program.command("preview").description("Start live preview dev server").option("--dev-cmd <cmd>", "Custom dev server command").option("--port <port>", "Dev server port").action(previewCommand);
1990
2183
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qlucent/fishi",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "FISHI — Your AI Dev Team That Actually Ships. Autonomous agent framework for Claude Code.",
5
5
  "license": "MIT",
6
6
  "type": "module",