@qlucent/fishi 0.14.4 → 0.14.5

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 +38 -23
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2468,14 +2468,41 @@ import ora4 from "ora";
2468
2468
  import path16 from "path";
2469
2469
  import fs16 from "fs";
2470
2470
  import {
2471
- getSettingsJsonTemplate,
2472
2471
  getSoulMdTemplate,
2473
2472
  getAgentsMdTemplate,
2474
2473
  getSandboxPolicyTemplate,
2475
2474
  getMonitorEmitterScript,
2476
2475
  getFileLockHookScript
2477
2476
  } from "@qlucent/fishi-core";
2478
- var CURRENT_VERSION = "0.14.3";
2477
+ var CURRENT_VERSION = "0.14.4";
2478
+ function fixHooksFormat(settings) {
2479
+ if (!settings.hooks) return false;
2480
+ let fixed = false;
2481
+ for (const [event, entries] of Object.entries(settings.hooks)) {
2482
+ if (!Array.isArray(entries)) continue;
2483
+ for (let i = 0; i < entries.length; i++) {
2484
+ const entry = entries[i];
2485
+ if (entry.command && !entry.hooks) {
2486
+ entries[i] = {
2487
+ matcher: entry.matcher || "",
2488
+ hooks: [{ type: "command", command: entry.command }]
2489
+ };
2490
+ fixed = true;
2491
+ }
2492
+ }
2493
+ }
2494
+ return fixed;
2495
+ }
2496
+ function fixDenyRules(settings) {
2497
+ if (!settings.permissions?.deny) return false;
2498
+ const original = settings.permissions.deny.length;
2499
+ settings.permissions.deny = settings.permissions.deny.filter((rule) => {
2500
+ if (rule.includes(":(){ :|:& };:")) return false;
2501
+ if (/^Bash\(\s*\)$/.test(rule)) return false;
2502
+ return true;
2503
+ });
2504
+ return settings.permissions.deny.length !== original;
2505
+ }
2479
2506
  async function upgradeCommand() {
2480
2507
  const targetDir = process.cwd();
2481
2508
  console.log("");
@@ -2493,30 +2520,18 @@ async function upgradeCommand() {
2493
2520
  if (fs16.existsSync(settingsPath)) {
2494
2521
  try {
2495
2522
  const existing = JSON.parse(fs16.readFileSync(settingsPath, "utf-8"));
2496
- let needsFix = false;
2497
- if (existing.hooks) {
2498
- for (const [event, entries] of Object.entries(existing.hooks)) {
2499
- if (Array.isArray(entries)) {
2500
- for (const entry of entries) {
2501
- if (entry.command && !entry.hooks) {
2502
- needsFix = true;
2503
- break;
2504
- }
2505
- }
2506
- }
2507
- if (needsFix) break;
2508
- }
2509
- }
2510
- if (needsFix) {
2523
+ const hooksFixed = fixHooksFormat(existing);
2524
+ const denyFixed = fixDenyRules(existing);
2525
+ if (hooksFixed || denyFixed) {
2511
2526
  const backupDir = path16.join(targetDir, ".fishi", "backup", "upgrade-" + (/* @__PURE__ */ new Date()).toISOString().replace(/:/g, "-").replace(/\.\d+Z$/, ""));
2512
2527
  fs16.mkdirSync(backupDir, { recursive: true });
2513
2528
  fs16.copyFileSync(settingsPath, path16.join(backupDir, "settings.json"));
2514
- fs16.writeFileSync(settingsPath, getSettingsJsonTemplate(), "utf-8");
2515
- updated.push(".claude/settings.json (hooks format fixed)");
2529
+ fs16.writeFileSync(settingsPath, JSON.stringify(existing, null, 2) + "\n", "utf-8");
2530
+ if (hooksFixed) updated.push(".claude/settings.json (hooks format: matcher+command \u2192 matcher+hooks array)");
2531
+ if (denyFixed) updated.push(".claude/settings.json (removed invalid deny rules)");
2516
2532
  }
2517
2533
  } catch {
2518
- fs16.writeFileSync(settingsPath, getSettingsJsonTemplate(), "utf-8");
2519
- updated.push(".claude/settings.json (replaced \u2014 was corrupted)");
2534
+ updated.push(".claude/settings.json (could not parse \u2014 please fix manually)");
2520
2535
  }
2521
2536
  }
2522
2537
  const soulPath = path16.join(targetDir, "SOUL.md");
@@ -2577,7 +2592,7 @@ async function upgradeCommand() {
2577
2592
  console.log("");
2578
2593
  }
2579
2594
  if (created.length > 0) {
2580
- console.log(chalk14.white.bold(" Created (new in v0.14):"));
2595
+ console.log(chalk14.white.bold(" Created (new in latest):"));
2581
2596
  for (const c of created) console.log(chalk14.cyan(` ${c}`));
2582
2597
  console.log("");
2583
2598
  }
@@ -2593,7 +2608,7 @@ async function upgradeCommand() {
2593
2608
  var program = new Command();
2594
2609
  program.name("fishi").description(
2595
2610
  chalk15.cyan("\u{1F41F} FISHI") + " \u2014 AI-Powered Software Delivery Pipeline\n Autonomous AI development with human governance"
2596
- ).version("0.14.3");
2611
+ ).version("0.14.4");
2597
2612
  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(
2598
2613
  "-c, --cost-mode <mode>",
2599
2614
  "Cost mode: performance | balanced | economy",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qlucent/fishi",
3
- "version": "0.14.4",
3
+ "version": "0.14.5",
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",