@qlucent/fishi 0.14.6 → 0.15.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 +114 -16
- package/package.json +64 -64
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;
|
|
@@ -2501,7 +2565,12 @@ import {
|
|
|
2501
2565
|
getAgentsMdTemplate,
|
|
2502
2566
|
getSandboxPolicyTemplate,
|
|
2503
2567
|
getMonitorEmitterScript,
|
|
2504
|
-
getFileLockHookScript
|
|
2568
|
+
getFileLockHookScript,
|
|
2569
|
+
getSessionStartHook,
|
|
2570
|
+
getAutoCheckpointHook,
|
|
2571
|
+
getAgentCompleteHook,
|
|
2572
|
+
getGateManagerScript,
|
|
2573
|
+
getWorktreeManagerScript
|
|
2505
2574
|
} from "@qlucent/fishi-core";
|
|
2506
2575
|
var CURRENT_VERSION = "0.14.4";
|
|
2507
2576
|
function fixHooksFormat(settings) {
|
|
@@ -2528,8 +2597,17 @@ function fixDenyRules(settings) {
|
|
|
2528
2597
|
settings.permissions.deny = settings.permissions.deny.filter((rule) => {
|
|
2529
2598
|
if (rule.includes(":(){ :|:& };:")) return false;
|
|
2530
2599
|
if (/^Bash\(\s*\)$/.test(rule)) return false;
|
|
2600
|
+
if (rule === "Bash(npm *)" || rule === "Bash(yarn *)") return false;
|
|
2531
2601
|
return true;
|
|
2532
2602
|
});
|
|
2603
|
+
if (settings.permissions?.allow) {
|
|
2604
|
+
if (!settings.permissions.allow.includes("Bash(npm *)")) {
|
|
2605
|
+
settings.permissions.allow.push("Bash(npm *)");
|
|
2606
|
+
}
|
|
2607
|
+
if (!settings.permissions.allow.includes("Bash(yarn *)")) {
|
|
2608
|
+
settings.permissions.allow.push("Bash(yarn *)");
|
|
2609
|
+
}
|
|
2610
|
+
}
|
|
2533
2611
|
return settings.permissions.deny.length !== original;
|
|
2534
2612
|
}
|
|
2535
2613
|
async function upgradeCommand() {
|
|
@@ -2613,6 +2691,26 @@ async function upgradeCommand() {
|
|
|
2613
2691
|
fs16.mkdirSync(researchPath, { recursive: true });
|
|
2614
2692
|
created.push(".fishi/research/");
|
|
2615
2693
|
}
|
|
2694
|
+
const hooksToRegenerate = [
|
|
2695
|
+
{ name: "session-start.mjs", getter: getSessionStartHook },
|
|
2696
|
+
{ name: "auto-checkpoint.mjs", getter: getAutoCheckpointHook },
|
|
2697
|
+
{ name: "agent-complete.mjs", getter: getAgentCompleteHook },
|
|
2698
|
+
{ name: "gate-manager.mjs", getter: getGateManagerScript },
|
|
2699
|
+
{ name: "worktree-manager.mjs", getter: getWorktreeManagerScript },
|
|
2700
|
+
{ name: "monitor-emitter.mjs", getter: getMonitorEmitterScript },
|
|
2701
|
+
{ name: "file-lock-hook.mjs", getter: getFileLockHookScript }
|
|
2702
|
+
];
|
|
2703
|
+
const scriptsDir = path16.join(targetDir, ".fishi", "scripts");
|
|
2704
|
+
if (fs16.existsSync(scriptsDir)) {
|
|
2705
|
+
for (const hook of hooksToRegenerate) {
|
|
2706
|
+
try {
|
|
2707
|
+
const scriptPath = path16.join(scriptsDir, hook.name);
|
|
2708
|
+
fs16.writeFileSync(scriptPath, hook.getter(), "utf-8");
|
|
2709
|
+
updated.push(`.fishi/scripts/${hook.name} (regenerated with monitoring)`);
|
|
2710
|
+
} catch {
|
|
2711
|
+
}
|
|
2712
|
+
}
|
|
2713
|
+
}
|
|
2616
2714
|
spinner.succeed("Upgrade complete");
|
|
2617
2715
|
console.log("");
|
|
2618
2716
|
if (updated.length > 0) {
|
|
@@ -2637,7 +2735,7 @@ async function upgradeCommand() {
|
|
|
2637
2735
|
var program = new Command();
|
|
2638
2736
|
program.name("fishi").description(
|
|
2639
2737
|
chalk15.cyan("\u{1F41F} FISHI") + " \u2014 AI-Powered Software Delivery Pipeline\n Autonomous AI development with human governance"
|
|
2640
|
-
).version("0.
|
|
2738
|
+
).version("0.15.0");
|
|
2641
2739
|
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
2740
|
"-c, --cost-mode <mode>",
|
|
2643
2741
|
"Cost mode: performance | balanced | economy",
|
package/package.json
CHANGED
|
@@ -1,64 +1,64 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@qlucent/fishi",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "FISHI — Your AI Dev Team That Actually Ships. Autonomous agent framework for Claude Code.",
|
|
5
|
-
"license": "MIT",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"bin": {
|
|
8
|
-
"fishi": "./dist/index.js"
|
|
9
|
-
},
|
|
10
|
-
"main": "./dist/index.js",
|
|
11
|
-
"types": "./dist/index.d.ts",
|
|
12
|
-
"scripts": {
|
|
13
|
-
"build": "tsup src/index.ts --format esm --clean",
|
|
14
|
-
"dev": "tsup src/index.ts --format esm --watch --onSuccess 'node dist/index.js'",
|
|
15
|
-
"clean": "rm -rf dist",
|
|
16
|
-
"test": "vitest run"
|
|
17
|
-
},
|
|
18
|
-
"dependencies": {
|
|
19
|
-
"@qlucent/fishi-core": "*",
|
|
20
|
-
"chalk": "^5.3.0",
|
|
21
|
-
"commander": "^12.0.0",
|
|
22
|
-
"fs-extra": "^11.2.0",
|
|
23
|
-
"inquirer": "^9.2.0",
|
|
24
|
-
"ora": "^8.0.0",
|
|
25
|
-
"yaml": "^2.4.0"
|
|
26
|
-
},
|
|
27
|
-
"devDependencies": {
|
|
28
|
-
"@types/fs-extra": "^11.0.0",
|
|
29
|
-
"@types/node": "^20.0.0",
|
|
30
|
-
"tsup": "^8.0.0",
|
|
31
|
-
"typescript": "^5.4.0",
|
|
32
|
-
"vitest": "^2.0.0"
|
|
33
|
-
},
|
|
34
|
-
"engines": {
|
|
35
|
-
"node": ">=18.0.0"
|
|
36
|
-
},
|
|
37
|
-
"keywords": [
|
|
38
|
-
"claude",
|
|
39
|
-
"claude-code",
|
|
40
|
-
"ai",
|
|
41
|
-
"agent",
|
|
42
|
-
"autonomous",
|
|
43
|
-
"development",
|
|
44
|
-
"framework",
|
|
45
|
-
"multi-agent",
|
|
46
|
-
"orchestration",
|
|
47
|
-
"tdd",
|
|
48
|
-
"worktree",
|
|
49
|
-
"project-management"
|
|
50
|
-
],
|
|
51
|
-
"repository": {
|
|
52
|
-
"type": "git",
|
|
53
|
-
"url": "https://github.com/kpkaranam/fishi"
|
|
54
|
-
},
|
|
55
|
-
"homepage": "https://github.com/kpkaranam/fishi#readme",
|
|
56
|
-
"bugs": {
|
|
57
|
-
"url": "https://github.com/kpkaranam/fishi/issues"
|
|
58
|
-
},
|
|
59
|
-
"files": [
|
|
60
|
-
"dist",
|
|
61
|
-
"README.md",
|
|
62
|
-
"LICENSE"
|
|
63
|
-
]
|
|
64
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@qlucent/fishi",
|
|
3
|
+
"version": "0.15.0",
|
|
4
|
+
"description": "FISHI — Your AI Dev Team That Actually Ships. Autonomous agent framework for Claude Code.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"fishi": "./dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"main": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsup src/index.ts --format esm --clean",
|
|
14
|
+
"dev": "tsup src/index.ts --format esm --watch --onSuccess 'node dist/index.js'",
|
|
15
|
+
"clean": "rm -rf dist",
|
|
16
|
+
"test": "vitest run"
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@qlucent/fishi-core": "*",
|
|
20
|
+
"chalk": "^5.3.0",
|
|
21
|
+
"commander": "^12.0.0",
|
|
22
|
+
"fs-extra": "^11.2.0",
|
|
23
|
+
"inquirer": "^9.2.0",
|
|
24
|
+
"ora": "^8.0.0",
|
|
25
|
+
"yaml": "^2.4.0"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@types/fs-extra": "^11.0.0",
|
|
29
|
+
"@types/node": "^20.0.0",
|
|
30
|
+
"tsup": "^8.0.0",
|
|
31
|
+
"typescript": "^5.4.0",
|
|
32
|
+
"vitest": "^2.0.0"
|
|
33
|
+
},
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">=18.0.0"
|
|
36
|
+
},
|
|
37
|
+
"keywords": [
|
|
38
|
+
"claude",
|
|
39
|
+
"claude-code",
|
|
40
|
+
"ai",
|
|
41
|
+
"agent",
|
|
42
|
+
"autonomous",
|
|
43
|
+
"development",
|
|
44
|
+
"framework",
|
|
45
|
+
"multi-agent",
|
|
46
|
+
"orchestration",
|
|
47
|
+
"tdd",
|
|
48
|
+
"worktree",
|
|
49
|
+
"project-management"
|
|
50
|
+
],
|
|
51
|
+
"repository": {
|
|
52
|
+
"type": "git",
|
|
53
|
+
"url": "https://github.com/kpkaranam/fishi"
|
|
54
|
+
},
|
|
55
|
+
"homepage": "https://github.com/kpkaranam/fishi#readme",
|
|
56
|
+
"bugs": {
|
|
57
|
+
"url": "https://github.com/kpkaranam/fishi/issues"
|
|
58
|
+
},
|
|
59
|
+
"files": [
|
|
60
|
+
"dist",
|
|
61
|
+
"README.md",
|
|
62
|
+
"LICENSE"
|
|
63
|
+
]
|
|
64
|
+
}
|