@qlucent/fishi 0.8.0 → 0.11.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.
- package/dist/index.js +120 -5
- 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
|
|
5
|
+
import chalk12 from "chalk";
|
|
6
6
|
|
|
7
7
|
// src/commands/init.ts
|
|
8
8
|
import chalk from "chalk";
|
|
@@ -10,7 +10,7 @@ import ora from "ora";
|
|
|
10
10
|
import inquirer from "inquirer";
|
|
11
11
|
import path3 from "path";
|
|
12
12
|
import fs3 from "fs";
|
|
13
|
-
import { detectConflicts, createBackup, detectDocker } from "@qlucent/fishi-core";
|
|
13
|
+
import { detectConflicts, createBackup, detectDocker, getAvailableDomains, getDomainConfigYaml } from "@qlucent/fishi-core";
|
|
14
14
|
|
|
15
15
|
// src/analyzers/detector.ts
|
|
16
16
|
import fs from "fs";
|
|
@@ -1079,6 +1079,18 @@ async function initCommand(description, options) {
|
|
|
1079
1079
|
}
|
|
1080
1080
|
}
|
|
1081
1081
|
}
|
|
1082
|
+
let selectedDomain = "general";
|
|
1083
|
+
if (options.interactive !== false) {
|
|
1084
|
+
const domains = getAvailableDomains();
|
|
1085
|
+
const { domain } = await inquirer.prompt([{
|
|
1086
|
+
type: "list",
|
|
1087
|
+
name: "domain",
|
|
1088
|
+
message: "What type of application are you building?",
|
|
1089
|
+
choices: domains,
|
|
1090
|
+
default: "general"
|
|
1091
|
+
}]);
|
|
1092
|
+
selectedDomain = domain;
|
|
1093
|
+
}
|
|
1082
1094
|
const conflictResult = detectConflicts(targetDir);
|
|
1083
1095
|
let resolutions;
|
|
1084
1096
|
if (conflictResult.hasConflicts) {
|
|
@@ -1154,7 +1166,8 @@ async function initCommand(description, options) {
|
|
|
1154
1166
|
brownfieldAnalysis: brownfieldData,
|
|
1155
1167
|
resolutions,
|
|
1156
1168
|
docsReadmeExists: conflictResult?.docsReadmeExists,
|
|
1157
|
-
rootClaudeMdExists: conflictResult?.rootClaudeMdExists
|
|
1169
|
+
rootClaudeMdExists: conflictResult?.rootClaudeMdExists,
|
|
1170
|
+
domain: selectedDomain
|
|
1158
1171
|
});
|
|
1159
1172
|
if (brownfieldAnalysis) {
|
|
1160
1173
|
const reportPath = path3.join(targetDir, ".fishi", "memory", "brownfield-analysis.md");
|
|
@@ -1174,6 +1187,12 @@ sandbox:
|
|
|
1174
1187
|
if (fs3.existsSync(fishiYamlPath)) {
|
|
1175
1188
|
fs3.appendFileSync(fishiYamlPath, sandboxYaml, "utf-8");
|
|
1176
1189
|
}
|
|
1190
|
+
if (selectedDomain !== "general") {
|
|
1191
|
+
const fishiYamlPath2 = path3.join(targetDir, ".fishi", "fishi.yaml");
|
|
1192
|
+
if (fs3.existsSync(fishiYamlPath2)) {
|
|
1193
|
+
fs3.appendFileSync(fishiYamlPath2, getDomainConfigYaml(selectedDomain), "utf-8");
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1177
1196
|
const { getSandboxPolicyTemplate, getDockerfileTemplate } = await import("@qlucent/fishi-core");
|
|
1178
1197
|
fs3.writeFileSync(path3.join(targetDir, ".fishi", "sandbox-policy.yaml"), getSandboxPolicyTemplate(), "utf-8");
|
|
1179
1198
|
if (sandboxMode === "docker") {
|
|
@@ -2161,11 +2180,106 @@ async function previewCommand(options) {
|
|
|
2161
2180
|
});
|
|
2162
2181
|
}
|
|
2163
2182
|
|
|
2183
|
+
// src/commands/design.ts
|
|
2184
|
+
import chalk11 from "chalk";
|
|
2185
|
+
import fs13 from "fs";
|
|
2186
|
+
import path13 from "path";
|
|
2187
|
+
import {
|
|
2188
|
+
detectDesignTokens,
|
|
2189
|
+
generateDefaultTokens,
|
|
2190
|
+
detectComponentRegistry,
|
|
2191
|
+
runBrandGuardian,
|
|
2192
|
+
generateDesignSystemConfig
|
|
2193
|
+
} from "@qlucent/fishi-core";
|
|
2194
|
+
async function designCommand(action, options) {
|
|
2195
|
+
const targetDir = process.cwd();
|
|
2196
|
+
if (action === "detect") {
|
|
2197
|
+
console.log("");
|
|
2198
|
+
console.log(chalk11.cyan.bold(" FISHI Design System \u2014 Detect"));
|
|
2199
|
+
console.log("");
|
|
2200
|
+
const tokens = detectDesignTokens(targetDir);
|
|
2201
|
+
const registry = detectComponentRegistry(targetDir);
|
|
2202
|
+
console.log(chalk11.white.bold(" Design Tokens"));
|
|
2203
|
+
console.log(chalk11.gray(` Colors: ${Object.keys(tokens.colors).length} detected`));
|
|
2204
|
+
console.log(chalk11.gray(` Typography: ${tokens.typography.fontFamilies.length} font families, ${Object.keys(tokens.typography.scale).length} scale values`));
|
|
2205
|
+
console.log(chalk11.gray(` Spacing: ${Object.keys(tokens.spacing).length} values`));
|
|
2206
|
+
console.log(chalk11.gray(` Border radius: ${Object.keys(tokens.borderRadius).length} values`));
|
|
2207
|
+
console.log(chalk11.gray(` Dark mode: ${tokens.darkMode ? chalk11.green("yes") : chalk11.yellow("no")}`));
|
|
2208
|
+
console.log("");
|
|
2209
|
+
console.log(chalk11.white.bold(" Component Registry"));
|
|
2210
|
+
console.log(chalk11.gray(` Library: ${registry.library || "none detected"}`));
|
|
2211
|
+
console.log(chalk11.gray(` Framework: ${registry.framework || "none detected"}`));
|
|
2212
|
+
console.log(chalk11.gray(` Components: ${registry.components.length} found`));
|
|
2213
|
+
if (registry.components.length > 0) {
|
|
2214
|
+
const byType = {};
|
|
2215
|
+
for (const c of registry.components) byType[c.type] = (byType[c.type] || 0) + 1;
|
|
2216
|
+
for (const [type, count] of Object.entries(byType)) {
|
|
2217
|
+
console.log(chalk11.gray(` ${type}: ${count}`));
|
|
2218
|
+
}
|
|
2219
|
+
}
|
|
2220
|
+
console.log("");
|
|
2221
|
+
if (options.output || fs13.existsSync(path13.join(targetDir, ".fishi"))) {
|
|
2222
|
+
const outputPath = options.output || path13.join(targetDir, ".fishi", "design-system.json");
|
|
2223
|
+
const dir = path13.dirname(outputPath);
|
|
2224
|
+
if (!fs13.existsSync(dir)) fs13.mkdirSync(dir, { recursive: true });
|
|
2225
|
+
fs13.writeFileSync(outputPath, generateDesignSystemConfig(tokens, registry), "utf-8");
|
|
2226
|
+
console.log(chalk11.green(` Saved to ${path13.relative(targetDir, outputPath)}`));
|
|
2227
|
+
}
|
|
2228
|
+
} else if (action === "init") {
|
|
2229
|
+
console.log("");
|
|
2230
|
+
console.log(chalk11.cyan.bold(" FISHI Design System \u2014 Initialize"));
|
|
2231
|
+
console.log("");
|
|
2232
|
+
let tokens = detectDesignTokens(targetDir);
|
|
2233
|
+
const hasExisting = Object.keys(tokens.colors).length > 0;
|
|
2234
|
+
if (!hasExisting) {
|
|
2235
|
+
tokens = generateDefaultTokens();
|
|
2236
|
+
console.log(chalk11.yellow(" No design tokens found \u2014 using FISHI defaults."));
|
|
2237
|
+
} else {
|
|
2238
|
+
console.log(chalk11.green(` Detected ${Object.keys(tokens.colors).length} colors from your project.`));
|
|
2239
|
+
}
|
|
2240
|
+
const registry = detectComponentRegistry(targetDir);
|
|
2241
|
+
const outputPath = path13.join(targetDir, ".fishi", "design-system.json");
|
|
2242
|
+
const dir = path13.dirname(outputPath);
|
|
2243
|
+
if (!fs13.existsSync(dir)) fs13.mkdirSync(dir, { recursive: true });
|
|
2244
|
+
fs13.writeFileSync(outputPath, generateDesignSystemConfig(tokens, registry), "utf-8");
|
|
2245
|
+
console.log(chalk11.green(` Design system saved to .fishi/design-system.json`));
|
|
2246
|
+
console.log(chalk11.gray(" Your agents will use these tokens for consistent styling."));
|
|
2247
|
+
console.log("");
|
|
2248
|
+
} else if (action === "validate") {
|
|
2249
|
+
console.log("");
|
|
2250
|
+
console.log(chalk11.cyan.bold(" FISHI Brand Guardian \u2014 Validation"));
|
|
2251
|
+
console.log("");
|
|
2252
|
+
const tokens = detectDesignTokens(targetDir);
|
|
2253
|
+
const report = runBrandGuardian(targetDir, tokens);
|
|
2254
|
+
if (report.issues.length === 0) {
|
|
2255
|
+
console.log(chalk11.green(" No issues found! Your frontend follows the design system."));
|
|
2256
|
+
} else {
|
|
2257
|
+
for (const issue of report.issues) {
|
|
2258
|
+
const icon = issue.severity === "error" ? chalk11.red("ERROR") : issue.severity === "warning" ? chalk11.yellow("WARN") : chalk11.blue("INFO");
|
|
2259
|
+
console.log(` ${icon} ${chalk11.gray(issue.file)}:${issue.line}`);
|
|
2260
|
+
console.log(` ${issue.message}`);
|
|
2261
|
+
if (issue.fix) console.log(` ${chalk11.gray("Fix: " + issue.fix)}`);
|
|
2262
|
+
}
|
|
2263
|
+
}
|
|
2264
|
+
console.log("");
|
|
2265
|
+
console.log(chalk11.white.bold(" Summary"));
|
|
2266
|
+
console.log(chalk11.gray(` Files scanned: ${report.stats.filesScanned}`));
|
|
2267
|
+
console.log(chalk11.red(` Errors: ${report.stats.errors}`));
|
|
2268
|
+
console.log(chalk11.yellow(` Warnings: ${report.stats.warnings}`));
|
|
2269
|
+
console.log(chalk11.blue(` Info: ${report.stats.infos}`));
|
|
2270
|
+
console.log(` Status: ${report.passed ? chalk11.green("PASSED") : chalk11.red("FAILED")}`);
|
|
2271
|
+
console.log("");
|
|
2272
|
+
if (!report.passed) process.exit(1);
|
|
2273
|
+
} else {
|
|
2274
|
+
console.log(chalk11.yellow(` Unknown action: ${action}. Use: detect, init, validate`));
|
|
2275
|
+
}
|
|
2276
|
+
}
|
|
2277
|
+
|
|
2164
2278
|
// src/index.ts
|
|
2165
2279
|
var program = new Command();
|
|
2166
2280
|
program.name("fishi").description(
|
|
2167
|
-
|
|
2168
|
-
).version("0.
|
|
2281
|
+
chalk12.cyan("\u{1F41F} FISHI") + " \u2014 Your AI Dev Team That Actually Ships\n Autonomous agent framework for Claude Code"
|
|
2282
|
+
).version("0.11.0");
|
|
2169
2283
|
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(
|
|
2170
2284
|
"-c, --cost-mode <mode>",
|
|
2171
2285
|
"Cost mode: performance | balanced | economy",
|
|
@@ -2180,4 +2294,5 @@ program.command("dashboard").description("Agent observability \u2014 web dashboa
|
|
|
2180
2294
|
program.command("sandbox").description("Sandbox status and policy management").argument("<action>", "Action: status | policy").action(sandboxCommand);
|
|
2181
2295
|
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
2296
|
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);
|
|
2297
|
+
program.command("design").description("Design system \u2014 detect tokens, init design system, validate with Brand Guardian").argument("<action>", "Action: detect | init | validate").option("-o, --output <path>", "Output path for design config").action(designCommand);
|
|
2183
2298
|
program.parse();
|