@qlucent/fishi 0.14.6 → 0.14.8
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 +88 -15
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1025,30 +1025,94 @@ async function initCommand(description, options) {
|
|
|
1025
1025
|
name: "installDocker",
|
|
1026
1026
|
message: "How would you like to proceed?",
|
|
1027
1027
|
choices: [
|
|
1028
|
-
{ name: "Install Docker (
|
|
1028
|
+
{ name: "Install Docker automatically (recommended)", value: "install" },
|
|
1029
1029
|
{ name: "Continue without Docker (process-level isolation only)", value: "skip" }
|
|
1030
1030
|
],
|
|
1031
1031
|
default: "install"
|
|
1032
1032
|
}]);
|
|
1033
1033
|
if (installDocker === "install") {
|
|
1034
|
-
const
|
|
1034
|
+
const { execSync: execSyncInstall } = await import("child_process");
|
|
1035
|
+
const platform = process.platform;
|
|
1036
|
+
let installCmd = "";
|
|
1037
|
+
let platformName = "";
|
|
1038
|
+
if (platform === "win32") {
|
|
1039
|
+
installCmd = "winget install Docker.DockerDesktop --accept-package-agreements --accept-source-agreements";
|
|
1040
|
+
platformName = "Windows (winget)";
|
|
1041
|
+
} else if (platform === "darwin") {
|
|
1042
|
+
installCmd = "brew install --cask docker";
|
|
1043
|
+
platformName = "macOS (Homebrew)";
|
|
1044
|
+
} else {
|
|
1045
|
+
try {
|
|
1046
|
+
execSyncInstall("which apt-get", { stdio: "ignore" });
|
|
1047
|
+
installCmd = "sudo apt-get update && sudo apt-get install -y docker.io docker-compose-v2";
|
|
1048
|
+
platformName = "Linux (apt)";
|
|
1049
|
+
} catch {
|
|
1050
|
+
try {
|
|
1051
|
+
execSyncInstall("which dnf", { stdio: "ignore" });
|
|
1052
|
+
installCmd = "sudo dnf install -y docker docker-compose";
|
|
1053
|
+
platformName = "Linux (dnf)";
|
|
1054
|
+
} catch {
|
|
1055
|
+
try {
|
|
1056
|
+
execSyncInstall("which yum", { stdio: "ignore" });
|
|
1057
|
+
installCmd = "sudo yum install -y docker docker-compose";
|
|
1058
|
+
platformName = "Linux (yum)";
|
|
1059
|
+
} catch {
|
|
1060
|
+
console.log(chalk.red(" Could not detect package manager. Install Docker manually:"));
|
|
1061
|
+
console.log(chalk.gray(" https://docs.docker.com/get-docker/"));
|
|
1062
|
+
console.log(chalk.gray(" Then run `fishi init` again."));
|
|
1063
|
+
console.log("");
|
|
1064
|
+
return;
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1035
1069
|
console.log("");
|
|
1036
|
-
console.log(chalk.cyan(`
|
|
1037
|
-
console.log(chalk.gray(
|
|
1070
|
+
console.log(chalk.cyan(` Detected: ${platformName}`));
|
|
1071
|
+
console.log(chalk.gray(` Running: ${installCmd}`));
|
|
1038
1072
|
console.log("");
|
|
1073
|
+
const installSpinner = ora("Installing Docker...").start();
|
|
1039
1074
|
try {
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1075
|
+
execSyncInstall(installCmd, { stdio: "inherit", timeout: 3e5 });
|
|
1076
|
+
installSpinner.succeed("Docker installed");
|
|
1077
|
+
console.log("");
|
|
1078
|
+
if (platform === "linux") {
|
|
1079
|
+
try {
|
|
1080
|
+
execSyncInstall("sudo systemctl start docker", { stdio: "ignore" });
|
|
1081
|
+
execSyncInstall("sudo systemctl enable docker", { stdio: "ignore" });
|
|
1082
|
+
execSyncInstall(`sudo usermod -aG docker ${process.env.USER || "root"}`, { stdio: "ignore" });
|
|
1083
|
+
} catch {
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
const readySpinner = ora("Waiting for Docker to start...").start();
|
|
1087
|
+
let dockerReady = false;
|
|
1088
|
+
for (let i = 0; i < 30; i++) {
|
|
1089
|
+
try {
|
|
1090
|
+
execSyncInstall("docker info", { stdio: "ignore", timeout: 5e3 });
|
|
1091
|
+
dockerReady = true;
|
|
1092
|
+
break;
|
|
1093
|
+
} catch {
|
|
1094
|
+
await new Promise((resolve) => setTimeout(resolve, 2e3));
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
if (dockerReady) {
|
|
1098
|
+
readySpinner.succeed("Docker is ready");
|
|
1099
|
+
sandboxMode = "docker";
|
|
1100
|
+
} else {
|
|
1101
|
+
readySpinner.warn("Docker installed but not running yet");
|
|
1102
|
+
console.log(chalk.gray(" Start Docker Desktop manually, then run `fishi upgrade` to switch to Docker mode."));
|
|
1103
|
+
console.log(chalk.gray(" Continuing with process-level sandbox for now."));
|
|
1104
|
+
}
|
|
1105
|
+
console.log("");
|
|
1106
|
+
} catch (err) {
|
|
1107
|
+
installSpinner.fail("Docker installation failed");
|
|
1108
|
+
console.log(chalk.gray(" Install manually: https://docs.docker.com/get-docker/"));
|
|
1109
|
+
console.log(chalk.gray(" Continuing with process-level sandbox."));
|
|
1110
|
+
console.log("");
|
|
1047
1111
|
}
|
|
1048
|
-
|
|
1112
|
+
} else {
|
|
1113
|
+
console.log(chalk.gray(" Continuing with process-level sandbox (limited isolation)."));
|
|
1114
|
+
console.log("");
|
|
1049
1115
|
}
|
|
1050
|
-
console.log(chalk.gray(" Continuing with process-level sandbox (limited isolation)."));
|
|
1051
|
-
console.log("");
|
|
1052
1116
|
}
|
|
1053
1117
|
}
|
|
1054
1118
|
let brownfieldAnalysis = null;
|
|
@@ -2528,8 +2592,17 @@ function fixDenyRules(settings) {
|
|
|
2528
2592
|
settings.permissions.deny = settings.permissions.deny.filter((rule) => {
|
|
2529
2593
|
if (rule.includes(":(){ :|:& };:")) return false;
|
|
2530
2594
|
if (/^Bash\(\s*\)$/.test(rule)) return false;
|
|
2595
|
+
if (rule === "Bash(npm *)" || rule === "Bash(yarn *)") return false;
|
|
2531
2596
|
return true;
|
|
2532
2597
|
});
|
|
2598
|
+
if (settings.permissions?.allow) {
|
|
2599
|
+
if (!settings.permissions.allow.includes("Bash(npm *)")) {
|
|
2600
|
+
settings.permissions.allow.push("Bash(npm *)");
|
|
2601
|
+
}
|
|
2602
|
+
if (!settings.permissions.allow.includes("Bash(yarn *)")) {
|
|
2603
|
+
settings.permissions.allow.push("Bash(yarn *)");
|
|
2604
|
+
}
|
|
2605
|
+
}
|
|
2533
2606
|
return settings.permissions.deny.length !== original;
|
|
2534
2607
|
}
|
|
2535
2608
|
async function upgradeCommand() {
|
|
@@ -2637,7 +2710,7 @@ async function upgradeCommand() {
|
|
|
2637
2710
|
var program = new Command();
|
|
2638
2711
|
program.name("fishi").description(
|
|
2639
2712
|
chalk15.cyan("\u{1F41F} FISHI") + " \u2014 AI-Powered Software Delivery Pipeline\n Autonomous AI development with human governance"
|
|
2640
|
-
).version("0.14.
|
|
2713
|
+
).version("0.14.7");
|
|
2641
2714
|
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(
|
|
2642
2715
|
"-c, --cost-mode <mode>",
|
|
2643
2716
|
"Cost mode: performance | balanced | economy",
|