@dv.nghiem/flowdeck 0.4.11 → 0.4.12

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  // src/index.ts
2
- import { readFileSync as readFileSync25, readdirSync as readdirSync3, existsSync as existsSync27 } from "fs";
3
- import { join as join26, basename as basename2 } from "path";
2
+ import { readFileSync as readFileSync25, readdirSync as readdirSync3, existsSync as existsSync26 } from "fs";
3
+ import { join as join25, basename as basename2 } from "path";
4
4
  import { dirname as dirname3 } from "path";
5
5
  import { fileURLToPath as fileURLToPath2 } from "url";
6
6
 
@@ -1807,212 +1807,25 @@ var listRulesTool = tool11({
1807
1807
  }
1808
1808
  });
1809
1809
 
1810
- // src/tools/rtk-setup.ts
1810
+ // src/tools/merge-assist.ts
1811
1811
  import { tool as tool12 } from "@opencode-ai/plugin";
1812
-
1813
- // src/services/rtk-manager.ts
1812
+ import { readFileSync as readFileSync15, writeFileSync as writeFileSync11, existsSync as existsSync15, mkdirSync as mkdirSync10 } from "fs";
1813
+ import { join as join15 } from "path";
1814
1814
  import { spawnSync as spawnSync2 } from "child_process";
1815
- import { existsSync as existsSync14 } from "fs";
1816
- import { homedir } from "os";
1817
- import { join as join14 } from "path";
1818
-
1819
- // src/services/rtk-policy.ts
1820
- var SUPPORTED_COMMANDS = new Set([
1821
- "git",
1822
- "npm",
1823
- "npx",
1824
- "bun",
1825
- "pnpm",
1826
- "yarn",
1827
- "tsc",
1828
- "eslint",
1829
- "biome",
1830
- "oxlint",
1831
- "jest",
1832
- "vitest",
1833
- "pytest",
1834
- "cargo",
1835
- "docker",
1836
- "kubectl",
1837
- "gh"
1838
- ]);
1839
- var COMPACT_GIT_SUBCOMMANDS = new Set([
1840
- "rev-parse",
1841
- "hash-object",
1842
- "cat-file",
1843
- "ls-files",
1844
- "ls-tree",
1845
- "show-ref",
1846
- "for-each-ref",
1847
- "symbolic-ref",
1848
- "config"
1849
- ]);
1850
- var NEVER_WRAP = new Set(["codegraph", "curl", "sh", "bash", "zsh", "fish", "node", "python", "python3"]);
1851
- function getSupportedCommands() {
1852
- return [...SUPPORTED_COMMANDS].sort();
1853
- }
1854
-
1855
- // src/services/rtk-manager.ts
1856
- var INSTALL_INSTRUCTIONS = [
1857
- "rtk is not installed. To install it manually:",
1858
- " Linux/macOS: curl -fsSL https://raw.githubusercontent.com/rtk-ai/rtk/refs/heads/master/install.sh | sh",
1859
- " Then add ~/.local/bin to your PATH if needed.",
1860
- "After installation, call rtk-setup again to verify detection."
1861
- ].join(`
1862
- `);
1863
- var CANDIDATE_PATHS = [join14(homedir(), ".local", "bin", "rtk"), "/usr/local/bin/rtk", "/usr/bin/rtk"];
1864
- function detectRtk() {
1865
- const fromPath = spawnSync2("rtk", ["--version"], { encoding: "utf-8", timeout: 5000 });
1866
- if (fromPath.status === 0) {
1867
- const version = (fromPath.stdout ?? "").trim().split(`
1868
- `)[0] ?? "";
1869
- return { installed: true, binPath: "rtk", version };
1870
- }
1871
- for (const candidate of CANDIDATE_PATHS) {
1872
- if (!existsSync14(candidate))
1873
- continue;
1874
- const result = spawnSync2(candidate, ["--version"], { encoding: "utf-8", timeout: 5000 });
1875
- if (result.status === 0) {
1876
- const version = (result.stdout ?? "").trim().split(`
1877
- `)[0] ?? "";
1878
- return { installed: true, binPath: candidate, version };
1879
- }
1880
- }
1881
- return {
1882
- installed: false,
1883
- error: "rtk binary not found in PATH or known install locations"
1884
- };
1885
- }
1886
- function initRtk(binPath) {
1887
- try {
1888
- const result = spawnSync2(binPath, ["init", "-g"], {
1889
- encoding: "utf-8",
1890
- timeout: 30000,
1891
- stdio: "pipe"
1892
- });
1893
- if (result.status !== 0) {
1894
- return {
1895
- success: false,
1896
- log: (result.stdout ?? "").trim(),
1897
- telemetryDisabled: false,
1898
- error: (result.stderr ?? "").trim() || `rtk init -g exited with code ${result.status}`
1899
- };
1900
- }
1901
- const telResult = spawnSync2(binPath, ["telemetry", "disable"], {
1902
- encoding: "utf-8",
1903
- timeout: 1e4,
1904
- stdio: "pipe"
1905
- });
1906
- return {
1907
- success: true,
1908
- log: [
1909
- `[rtk] init -g succeeded: ${(result.stdout ?? "").trim()}`,
1910
- `[rtk] telemetry disable: ${telResult.status === 0 ? "ok" : `failed (code ${telResult.status}) — ${(telResult.stderr ?? "").trim()}`}`
1911
- ].filter(Boolean).join(`
1912
- `),
1913
- telemetryDisabled: telResult.status === 0
1914
- };
1915
- } catch (err) {
1916
- return { success: false, log: "", telemetryDisabled: false, error: String(err) };
1917
- }
1918
- }
1919
- function getRtkStatus(opts) {
1920
- const detection = detectRtk();
1921
- if (!detection.installed) {
1922
- return {
1923
- installed: false,
1924
- initAttempted: false,
1925
- initSuccess: false,
1926
- telemetryDisabled: false,
1927
- installInstructions: INSTALL_INSTRUCTIONS
1928
- };
1929
- }
1930
- let initAttempted = false;
1931
- let initSuccess = false;
1932
- let telemetryDisabled = false;
1933
- if (opts?.runInit && detection.binPath) {
1934
- initAttempted = true;
1935
- const initResult = initRtk(detection.binPath);
1936
- initSuccess = initResult.success;
1937
- telemetryDisabled = initResult.telemetryDisabled;
1938
- }
1939
- return {
1940
- installed: true,
1941
- binPath: detection.binPath,
1942
- version: detection.version,
1943
- initAttempted,
1944
- initSuccess,
1945
- telemetryDisabled
1946
- };
1947
- }
1948
-
1949
- // src/tools/rtk-setup.ts
1950
- var rtkSetupTool = tool12({
1951
- description: [
1952
- "Detect, initialize, and report status of rtk (output compression proxy for CLI commands).",
1953
- "rtk reduces noisy CLI output (git, npm, test runners, linters, docker) by 60-90%.",
1954
- "Call this to check if rtk is available, to run `rtk init -g`, or to get the binary path.",
1955
- "When RTK_INSTALLED=true in the environment, use `$RTK_BIN git status` for compressed output."
1956
- ].join(" "),
1957
- args: {
1958
- action: tool12.schema.enum(["status", "init"]).optional().describe("'status' — detect and report rtk state (default). " + "'init' — detect, then run `rtk init -g` to install the bash hook. " + "Use 'init' only once per environment setup.")
1959
- },
1960
- async execute(args) {
1961
- const action = args.action ?? "status";
1962
- const runInit = action === "init";
1963
- const status = getRtkStatus({ runInit });
1964
- const lines = ["## rtk Status"];
1965
- if (status.installed) {
1966
- lines.push(`- **Installed**: yes`);
1967
- lines.push(`- **Binary**: ${status.binPath ?? "rtk (in PATH)"}`);
1968
- if (status.version)
1969
- lines.push(`- **Version**: ${status.version}`);
1970
- if (runInit) {
1971
- if (status.initAttempted) {
1972
- lines.push(`- **Init**: ${status.initSuccess ? "✓ succeeded (bash hook installed)" : "✗ failed"}`);
1973
- lines.push(`- **Telemetry**: ${status.telemetryDisabled ? "✓ disabled (`rtk telemetry disable` ran)" : "⚠ disable step failed — run `rtk telemetry disable` manually"}`);
1974
- if (status.initSuccess) {
1975
- lines.push("", " **Bash hook caveat**: `rtk init -g` writes to Claude Code / Copilot global config.", " Whether it fires in non-interactive shell sessions depends on the runtime.", " For reliable compression, use `$RTK_BIN <cmd>` explicitly.", " `RTK_TELEMETRY_DISABLED=1` is always injected into bash sessions by FlowDeck.");
1976
- }
1977
- }
1978
- } else {
1979
- lines.push("- **Init**: not requested (pass `action: 'init'` to install bash hook)");
1980
- lines.push("- **Telemetry**: `RTK_TELEMETRY_DISABLED=1` is always set in bash sessions by FlowDeck");
1981
- }
1982
- lines.push("", "### Using rtk", "In bash commands, replace `git status` with `$RTK_BIN git status`.", "The `RTK_BIN` env var is injected by FlowDeck into every bash session when rtk is detected.", "", "### Supported commands", getSupportedCommands().map((c) => `- \`${c}\``).join(`
1983
- `));
1984
- } else {
1985
- lines.push("- **Installed**: no", "");
1986
- lines.push("### Install rtk");
1987
- if (status.installInstructions) {
1988
- lines.push("```", status.installInstructions, "```");
1989
- }
1990
- lines.push("", "After installing, call `rtk-setup` again to verify detection.");
1991
- }
1992
- return lines.join(`
1993
- `);
1994
- }
1995
- });
1996
-
1997
- // src/tools/merge-assist.ts
1998
- import { tool as tool13 } from "@opencode-ai/plugin";
1999
- import { readFileSync as readFileSync15, writeFileSync as writeFileSync11, existsSync as existsSync16, mkdirSync as mkdirSync10 } from "fs";
2000
- import { join as join16 } from "path";
2001
- import { spawnSync as spawnSync3 } from "child_process";
2002
1815
 
2003
1816
  // src/lib/logger.ts
2004
- import { appendFileSync as appendFileSync3, existsSync as existsSync15, mkdirSync as mkdirSync9 } from "fs";
2005
- import { join as join15 } from "path";
1817
+ import { appendFileSync as appendFileSync3, existsSync as existsSync14, mkdirSync as mkdirSync9 } from "fs";
1818
+ import { join as join14 } from "path";
2006
1819
  var LOG_DIR = ".opencode";
2007
1820
  var LOG_FILE = "flowdeck.log";
2008
1821
  function ensureLogDir(logDir) {
2009
- if (!existsSync15(logDir)) {
1822
+ if (!existsSync14(logDir)) {
2010
1823
  mkdirSync9(logDir, { recursive: true });
2011
1824
  }
2012
1825
  }
2013
1826
  function logWrite(directory, level, source, message) {
2014
- const logDir = join15(directory, LOG_DIR);
2015
- const logFile = join15(logDir, LOG_FILE);
1827
+ const logDir = join14(directory, LOG_DIR);
1828
+ const logFile = join14(logDir, LOG_FILE);
2016
1829
  try {
2017
1830
  ensureLogDir(logDir);
2018
1831
  const entry = {
@@ -2029,14 +1842,14 @@ function logWrite(directory, level, source, message) {
2029
1842
  // src/tools/merge-assist.ts
2030
1843
  var MERGE_ASSIST_FILE = "MERGE_ASSIST.json";
2031
1844
  function statePath2(directory) {
2032
- return join16(codebaseDir(directory), MERGE_ASSIST_FILE);
1845
+ return join15(codebaseDir(directory), MERGE_ASSIST_FILE);
2033
1846
  }
2034
1847
  function emptyState() {
2035
1848
  return { version: "1.0", lastUpdated: new Date().toISOString(), sessions: {} };
2036
1849
  }
2037
1850
  function readState(directory) {
2038
1851
  const p = statePath2(directory);
2039
- if (!existsSync16(p))
1852
+ if (!existsSync15(p))
2040
1853
  return emptyState();
2041
1854
  try {
2042
1855
  return JSON.parse(readFileSync15(p, "utf-8"));
@@ -2047,7 +1860,7 @@ function readState(directory) {
2047
1860
  function writeState(directory, state) {
2048
1861
  try {
2049
1862
  const base = codebaseDir(directory);
2050
- if (!existsSync16(base))
1863
+ if (!existsSync15(base))
2051
1864
  mkdirSync10(base, { recursive: true });
2052
1865
  const newState = { ...state, lastUpdated: new Date().toISOString() };
2053
1866
  writeFileSync11(statePath2(directory), JSON.stringify(newState, null, 2), "utf-8");
@@ -2063,7 +1876,7 @@ function generateId() {
2063
1876
  return `ma-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
2064
1877
  }
2065
1878
  function safeGit(cwd, args) {
2066
- const result = spawnSync3("git", args, { cwd, encoding: "utf-8" });
1879
+ const result = spawnSync2("git", args, { cwd, encoding: "utf-8" });
2067
1880
  return {
2068
1881
  stdout: result.stdout?.trim() ?? "",
2069
1882
  stderr: result.stderr?.trim() ?? "",
@@ -2071,7 +1884,7 @@ function safeGit(cwd, args) {
2071
1884
  };
2072
1885
  }
2073
1886
  function isGitRepo(cwd) {
2074
- return existsSync16(join16(cwd, ".git")) && safeGit(cwd, ["rev-parse", "--git-dir"]).status === 0;
1887
+ return existsSync15(join15(cwd, ".git")) && safeGit(cwd, ["rev-parse", "--git-dir"]).status === 0;
2075
1888
  }
2076
1889
  function branchExists(cwd, branch) {
2077
1890
  return safeGit(cwd, ["show-ref", "--verify", "--quiet", `refs/heads/${branch}`]).status === 0;
@@ -2254,18 +2067,18 @@ function updateConfirmation(session, step, approved) {
2254
2067
  function isStepApproved(session, step) {
2255
2068
  return session.confirmations.some((c) => c.step === step && c.status === "approved");
2256
2069
  }
2257
- var mergeAssistTool = tool13({
2070
+ var mergeAssistTool = tool12({
2258
2071
  description: "Human-in-the-loop selective branch integration. Provides structured analysis and confirmation state management for cherry-pick or manual port workflows. Never executes state-changing git commands.",
2259
2072
  args: {
2260
- action: tool13.schema.enum(["start", "inspect", "plan", "confirm", "abort", "status", "list"]),
2261
- targetBranch: tool13.schema.string().optional(),
2262
- sourceBranch: tool13.schema.string().optional(),
2263
- featureDescription: tool13.schema.string().optional(),
2264
- sessionId: tool13.schema.string().optional(),
2265
- selectedCommits: tool13.schema.array(tool13.schema.string()).optional(),
2266
- step: tool13.schema.string().optional(),
2267
- approved: tool13.schema.boolean().optional(),
2268
- integrationBranch: tool13.schema.string().optional()
2073
+ action: tool12.schema.enum(["start", "inspect", "plan", "confirm", "abort", "status", "list"]),
2074
+ targetBranch: tool12.schema.string().optional(),
2075
+ sourceBranch: tool12.schema.string().optional(),
2076
+ featureDescription: tool12.schema.string().optional(),
2077
+ sessionId: tool12.schema.string().optional(),
2078
+ selectedCommits: tool12.schema.array(tool12.schema.string()).optional(),
2079
+ step: tool12.schema.string().optional(),
2080
+ approved: tool12.schema.boolean().optional(),
2081
+ integrationBranch: tool12.schema.string().optional()
2269
2082
  },
2270
2083
  async execute(args, context) {
2271
2084
  const dir = context.directory ?? process.cwd();
@@ -2470,8 +2283,8 @@ var mergeAssistTool = tool13({
2470
2283
  });
2471
2284
 
2472
2285
  // src/hooks/guard-rails.ts
2473
- import { existsSync as existsSync18, readFileSync as readFileSync17 } from "fs";
2474
- import { join as join18 } from "path";
2286
+ import { existsSync as existsSync17, readFileSync as readFileSync17 } from "fs";
2287
+ import { join as join17 } from "path";
2475
2288
 
2476
2289
  // src/lib/task-routing.ts
2477
2290
  var UI_HEAVY_KEYWORDS = [
@@ -2517,21 +2330,21 @@ function isUiHeavyTask(input) {
2517
2330
  }
2518
2331
 
2519
2332
  // src/config/loader.ts
2520
- import { existsSync as existsSync17, readFileSync as readFileSync16 } from "fs";
2521
- import { join as join17 } from "path";
2522
- import { homedir as homedir2 } from "os";
2333
+ import { existsSync as existsSync16, readFileSync as readFileSync16 } from "fs";
2334
+ import { join as join16 } from "path";
2335
+ import { homedir } from "os";
2523
2336
  var CONFIG_FILENAME = "flowdeck.json";
2524
2337
  function getGlobalConfigDir() {
2525
- return process.env.OPENCODE_CONFIG_DIR || (process.env.XDG_CONFIG_HOME ? join17(process.env.XDG_CONFIG_HOME, "opencode") : join17(homedir2(), ".config", "opencode"));
2338
+ return process.env.OPENCODE_CONFIG_DIR || (process.env.XDG_CONFIG_HOME ? join16(process.env.XDG_CONFIG_HOME, "opencode") : join16(homedir(), ".config", "opencode"));
2526
2339
  }
2527
2340
  function loadFlowDeckConfig(directory) {
2528
2341
  const candidates = [];
2529
2342
  if (directory) {
2530
- candidates.push(join17(directory, ".opencode", CONFIG_FILENAME));
2343
+ candidates.push(join16(directory, ".opencode", CONFIG_FILENAME));
2531
2344
  }
2532
- candidates.push(join17(getGlobalConfigDir(), CONFIG_FILENAME));
2345
+ candidates.push(join16(getGlobalConfigDir(), CONFIG_FILENAME));
2533
2346
  for (const configPath of candidates) {
2534
- if (existsSync17(configPath)) {
2347
+ if (existsSync16(configPath)) {
2535
2348
  try {
2536
2349
  const content = readFileSync16(configPath, "utf-8");
2537
2350
  return JSON.parse(content);
@@ -2560,7 +2373,7 @@ var PLANNING_DIR2 = ".planning";
2560
2373
  var CONFIG_FILE = "config.json";
2561
2374
  var STATE_FILE2 = "STATE.md";
2562
2375
  function resolveExecutionMode(configPath, trustScore, volatility) {
2563
- if (existsSync18(configPath)) {
2376
+ if (existsSync17(configPath)) {
2564
2377
  try {
2565
2378
  const config = JSON.parse(readFileSync17(configPath, "utf-8"));
2566
2379
  if (config.execution_mode === "review-only")
@@ -2616,22 +2429,22 @@ async function guardRailsHook(ctx, input, _output) {
2616
2429
  if (!ENABLED)
2617
2430
  return;
2618
2431
  const dir = ctx.directory;
2619
- const planningDirPath = join18(dir, PLANNING_DIR2);
2432
+ const planningDirPath = join17(dir, PLANNING_DIR2);
2620
2433
  const codebaseDirectory = codebaseDir(dir);
2621
- const configPath = join18(planningDirPath, CONFIG_FILE);
2622
- const statePath3 = join18(planningDirPath, STATE_FILE2);
2434
+ const configPath = join17(planningDirPath, CONFIG_FILE);
2435
+ const statePath3 = join17(planningDirPath, STATE_FILE2);
2623
2436
  const workspaceRoot = findWorkspaceRoot(dir);
2624
2437
  if (workspaceRoot && dir !== workspaceRoot) {
2625
2438
  const config = getWorkspaceConfig(dir);
2626
- if (config && config.workspace_mode === "shared" && !existsSync18(planningDirPath)) {
2439
+ if (config && config.workspace_mode === "shared" && !existsSync17(planningDirPath)) {
2627
2440
  const msg = `No .planning/ in this sub-repo. Switch to workspace root: cd ${workspaceRoot}`;
2628
2441
  throw new Error(`[flowdeck] BLOCK: ${msg}`);
2629
2442
  }
2630
2443
  }
2631
2444
  if (input.tool === "write" || input.tool === "edit") {
2632
- if (!existsSync18(planningDirPath))
2445
+ if (!existsSync17(planningDirPath))
2633
2446
  return;
2634
- if (!existsSync18(codebaseDirectory)) {
2447
+ if (!existsSync17(codebaseDirectory)) {
2635
2448
  throw new Error(`[flowdeck] WARNING: .codebase/ not found. Run /fd-map-codebase to map the codebase.`);
2636
2449
  }
2637
2450
  const execMode = resolveExecutionMode(configPath, null);
@@ -2687,13 +2500,13 @@ function getDesignGateMessage(dir) {
2687
2500
  }
2688
2501
  function planSuggestsUiHeavy(dir, phase) {
2689
2502
  const planPath = phasePlanPath(dir, phase);
2690
- if (!existsSync18(planPath))
2503
+ if (!existsSync17(planPath))
2691
2504
  return false;
2692
2505
  const planContent = readFileSync17(planPath, "utf-8");
2693
2506
  return isUiHeavyTask(planContent);
2694
2507
  }
2695
2508
  function effectiveSeverity(configPath, statePath3) {
2696
- if (existsSync18(configPath)) {
2509
+ if (existsSync17(configPath)) {
2697
2510
  try {
2698
2511
  const configContent = readFileSync17(configPath, "utf-8");
2699
2512
  const config = JSON.parse(configContent);
@@ -2711,7 +2524,7 @@ function getEffectiveSeverity(configPath, statePath3) {
2711
2524
  return effectiveSeverity(configPath, statePath3);
2712
2525
  }
2713
2526
  function getPlanConfirmed(statePath3) {
2714
- if (!existsSync18(statePath3))
2527
+ if (!existsSync17(statePath3))
2715
2528
  return false;
2716
2529
  try {
2717
2530
  const content = readFileSync17(statePath3, "utf-8");
@@ -2722,32 +2535,32 @@ function getPlanConfirmed(statePath3) {
2722
2535
  }
2723
2536
  }
2724
2537
  function getWarningMessage(planningDir2) {
2725
- if (!existsSync18(join18(planningDir2, STATE_FILE2))) {
2538
+ if (!existsSync17(join17(planningDir2, STATE_FILE2))) {
2726
2539
  return "No STATE.md found. Run /fd-map-codebase then /fd-new-feature to start a feature.";
2727
2540
  }
2728
2541
  return "Plan not confirmed. Run /fd-plan and confirm to enable execution.";
2729
2542
  }
2730
2543
  function getBlockMessage(planningDir2) {
2731
- if (!existsSync18(join18(planningDir2, STATE_FILE2))) {
2544
+ if (!existsSync17(join17(planningDir2, STATE_FILE2))) {
2732
2545
  return "No STATE.md found. Run /fd-map-codebase then /fd-new-feature to start a feature.";
2733
2546
  }
2734
2547
  return "Plan not confirmed. Run /fd-plan and confirm to enable execution.";
2735
2548
  }
2736
2549
 
2737
2550
  // src/hooks/tool-guard.ts
2738
- import { existsSync as existsSync19, readFileSync as readFileSync18 } from "fs";
2739
- import { join as join19 } from "path";
2551
+ import { existsSync as existsSync18, readFileSync as readFileSync18 } from "fs";
2552
+ import { join as join18 } from "path";
2740
2553
  var IS_ENABLED = () => process.env.FLOWDECK_TOOL_GUARD_ENABLED === "on";
2741
2554
  var BLOCKED_PATTERNS = {
2742
2555
  read: [".env", ".pem", ".key", ".secret"],
2743
2556
  write: ["node_modules"],
2744
2557
  bash: ["rm -rf"]
2745
2558
  };
2746
- function isBlocked(tool14, args) {
2747
- const patterns = BLOCKED_PATTERNS[tool14];
2559
+ function isBlocked(tool13, args) {
2560
+ const patterns = BLOCKED_PATTERNS[tool13];
2748
2561
  if (!patterns)
2749
2562
  return null;
2750
- if (tool14 === "bash") {
2563
+ if (tool13 === "bash") {
2751
2564
  const cmd = args.command;
2752
2565
  if (!cmd)
2753
2566
  return null;
@@ -2758,7 +2571,7 @@ function isBlocked(tool14, args) {
2758
2571
  }
2759
2572
  return null;
2760
2573
  }
2761
- if (tool14 === "read") {
2574
+ if (tool13 === "read") {
2762
2575
  const filePath = args.filePath;
2763
2576
  if (!filePath)
2764
2577
  return null;
@@ -2769,7 +2582,7 @@ function isBlocked(tool14, args) {
2769
2582
  }
2770
2583
  return null;
2771
2584
  }
2772
- if (tool14 === "write") {
2585
+ if (tool13 === "write") {
2773
2586
  const filePath = args.filePath;
2774
2587
  if (!filePath)
2775
2588
  return null;
@@ -2783,8 +2596,8 @@ function isBlocked(tool14, args) {
2783
2596
  return null;
2784
2597
  }
2785
2598
  function checkArchConstraint(directory, filePath) {
2786
- const constraintsPath = join19(codebaseDir(directory), "CONSTRAINTS.md");
2787
- if (!existsSync19(constraintsPath))
2599
+ const constraintsPath = join18(codebaseDir(directory), "CONSTRAINTS.md");
2600
+ if (!existsSync18(constraintsPath))
2788
2601
  return null;
2789
2602
  try {
2790
2603
  const content = readFileSync18(constraintsPath, "utf-8");
@@ -2828,7 +2641,7 @@ function isUiDesignApprovalRequired(directory) {
2828
2641
  return !(state.design_stage === "handoff_complete" && state.design_approved);
2829
2642
  }
2830
2643
  const planPath = phasePlanPath(directory, state.phase || 1);
2831
- if (!existsSync19(planPath))
2644
+ if (!existsSync18(planPath))
2832
2645
  return false;
2833
2646
  const planContent = readFileSync18(planPath, "utf-8");
2834
2647
  if (!isUiHeavyTask(planContent))
@@ -2859,18 +2672,18 @@ async function toolGuardHook(ctx, input, output) {
2859
2672
  }
2860
2673
 
2861
2674
  // src/hooks/session-start.ts
2862
- import { existsSync as existsSync20, readFileSync as readFileSync19 } from "fs";
2675
+ import { existsSync as existsSync19, readFileSync as readFileSync19 } from "fs";
2863
2676
  async function sessionStartHook(ctx) {
2864
2677
  const planningDir2 = ctx.directory + "/.planning";
2865
2678
  const codebaseDirectory = codebaseDir(ctx.directory);
2866
2679
  const workspaceRoot = findWorkspaceRoot(ctx.directory);
2867
2680
  const config = workspaceRoot ? getWorkspaceConfig(ctx.directory) : null;
2868
- if (!existsSync20(planningDir2)) {
2681
+ if (!existsSync19(planningDir2)) {
2869
2682
  return {
2870
2683
  flowdeck_phase: null,
2871
2684
  flowdeck_status: "no_plan",
2872
2685
  flowdeck_warning: "Run /fd-map-codebase to index the codebase, then /fd-new-feature to start a feature.",
2873
- flowdeck_has_codebase: existsSync20(codebaseDirectory),
2686
+ flowdeck_has_codebase: existsSync19(codebaseDirectory),
2874
2687
  ...workspaceRoot && config?.sub_repos ? {
2875
2688
  flowdeck_workspace_root: workspaceRoot,
2876
2689
  flowdeck_sub_repos: config.sub_repos,
@@ -2889,7 +2702,7 @@ async function sessionStartHook(ctx) {
2889
2702
  flowdeck_status: currentPhase["status"] ?? null,
2890
2703
  flowdeck_steps_pending: currentPhase["steps_pending"] ?? null,
2891
2704
  flowdeck_last_action: currentPhase["last_action"] ?? null,
2892
- flowdeck_has_codebase: existsSync20(codebaseDirectory)
2705
+ flowdeck_has_codebase: existsSync19(codebaseDirectory)
2893
2706
  };
2894
2707
  if (workspaceRoot && config?.sub_repos && config.sub_repos.length > 0) {
2895
2708
  result.flowdeck_workspace_root = workspaceRoot;
@@ -2903,7 +2716,7 @@ async function sessionStartHook(ctx) {
2903
2716
  flowdeck_phase: null,
2904
2717
  flowdeck_status: "error",
2905
2718
  flowdeck_warning: "State file unreadable. Continuing without flowdeck context.",
2906
- flowdeck_has_codebase: existsSync20(codebaseDirectory)
2719
+ flowdeck_has_codebase: existsSync19(codebaseDirectory)
2907
2720
  };
2908
2721
  if (workspaceRoot && config?.sub_repos && config.sub_repos.length > 0) {
2909
2722
  result.flowdeck_workspace_root = workspaceRoot;
@@ -3035,13 +2848,13 @@ class NotificationController {
3035
2848
  return this.lastNotifiedKey;
3036
2849
  }
3037
2850
  }
3038
- function notifyPermissionNeeded(tool14) {
3039
- notify("FlowDeck Permission Required", `Agent needs approval to use tool: ${tool14}`, "critical");
2851
+ function notifyPermissionNeeded(tool13) {
2852
+ notify("FlowDeck Permission Required", `Agent needs approval to use tool: ${tool13}`, "critical");
3040
2853
  }
3041
2854
 
3042
2855
  // src/hooks/patch-trust.ts
3043
- import { existsSync as existsSync21, readFileSync as readFileSync20 } from "fs";
3044
- import { join as join20 } from "path";
2856
+ import { existsSync as existsSync20, readFileSync as readFileSync20 } from "fs";
2857
+ import { join as join19 } from "path";
3045
2858
  var HIGH_RISK_KEYWORDS = [
3046
2859
  "password",
3047
2860
  "secret",
@@ -3063,8 +2876,8 @@ var HIGH_RISK_KEYWORDS = [
3063
2876
  "privilege"
3064
2877
  ];
3065
2878
  function loadFailedPaths(directory) {
3066
- const p = join20(codebaseDir(directory), "FAILURES.json");
3067
- if (!existsSync21(p))
2879
+ const p = join19(codebaseDir(directory), "FAILURES.json");
2880
+ if (!existsSync20(p))
3068
2881
  return [];
3069
2882
  try {
3070
2883
  const data = JSON.parse(readFileSync20(p, "utf-8"));
@@ -3120,8 +2933,8 @@ async function patchTrustHook(ctx, input, output) {
3120
2933
  }
3121
2934
 
3122
2935
  // src/hooks/decision-trace-hook.ts
3123
- import { existsSync as existsSync22, mkdirSync as mkdirSync11, appendFileSync as appendFileSync4 } from "fs";
3124
- import { join as join21 } from "path";
2936
+ import { existsSync as existsSync21, mkdirSync as mkdirSync11, appendFileSync as appendFileSync4 } from "fs";
2937
+ import { join as join20 } from "path";
3125
2938
  async function decisionTraceHook(ctx, input, output) {
3126
2939
  if (input.tool !== "write" && input.tool !== "edit")
3127
2940
  return;
@@ -3130,7 +2943,7 @@ async function decisionTraceHook(ctx, input, output) {
3130
2943
  return;
3131
2944
  const base = codebaseDir(ctx.directory);
3132
2945
  try {
3133
- if (!existsSync22(base))
2946
+ if (!existsSync21(base))
3134
2947
  mkdirSync11(base, { recursive: true });
3135
2948
  const entry = {
3136
2949
  timestamp: new Date().toISOString(),
@@ -3143,14 +2956,14 @@ async function decisionTraceHook(ctx, input, output) {
3143
2956
  risk_level: "unknown",
3144
2957
  auto_recorded: true
3145
2958
  };
3146
- appendFileSync4(join21(base, "DECISIONS.jsonl"), JSON.stringify(entry) + `
2959
+ appendFileSync4(join20(base, "DECISIONS.jsonl"), JSON.stringify(entry) + `
3147
2960
  `, "utf-8");
3148
2961
  } catch {}
3149
2962
  }
3150
2963
 
3151
2964
  // src/services/approval-manager.ts
3152
- import { existsSync as existsSync23, readFileSync as readFileSync21, writeFileSync as writeFileSync12, mkdirSync as mkdirSync12 } from "fs";
3153
- import { join as join22 } from "path";
2965
+ import { existsSync as existsSync22, readFileSync as readFileSync21, writeFileSync as writeFileSync12, mkdirSync as mkdirSync12 } from "fs";
2966
+ import { join as join21 } from "path";
3154
2967
  var APPROVAL_TTL_MS = 30 * 60 * 1000;
3155
2968
  var SENSITIVE_PATTERNS = [
3156
2969
  /auth/i,
@@ -3187,11 +3000,11 @@ function isSensitivePath(filePath) {
3187
3000
  return SENSITIVE_PATTERNS.some((p) => p.test(filePath));
3188
3001
  }
3189
3002
  function approvalsPath(dir) {
3190
- return join22(codebaseDir(dir), "APPROVALS.json");
3003
+ return join21(codebaseDir(dir), "APPROVALS.json");
3191
3004
  }
3192
3005
  function loadStore(dir) {
3193
3006
  const p = approvalsPath(dir);
3194
- if (!existsSync23(p))
3007
+ if (!existsSync22(p))
3195
3008
  return { requests: [] };
3196
3009
  try {
3197
3010
  return JSON.parse(readFileSync21(p, "utf-8"));
@@ -3212,8 +3025,8 @@ async function approvalHook(context, toolInput, output) {
3212
3025
  if (!ENABLED2)
3213
3026
  return;
3214
3027
  const dir = context.directory ?? process.cwd();
3215
- const tool14 = toolInput.name ?? toolInput.tool ?? "";
3216
- if (!WRITE_TOOLS.has(tool14))
3028
+ const tool13 = toolInput.name ?? toolInput.tool ?? "";
3029
+ if (!WRITE_TOOLS.has(tool13))
3217
3030
  return;
3218
3031
  const args = output.args ?? {};
3219
3032
  const filePath = String(args.path ?? args.file_path ?? args.filename ?? "");
@@ -3230,8 +3043,8 @@ async function approvalHook(context, toolInput, output) {
3230
3043
  }
3231
3044
 
3232
3045
  // src/services/event-logger.ts
3233
- import { existsSync as existsSync24, mkdirSync as mkdirSync13, appendFileSync as appendFileSync5, readFileSync as readFileSync22, writeFileSync as writeFileSync13, renameSync, unlinkSync, statSync } from "fs";
3234
- import { join as join23, resolve as resolve2, sep } from "path";
3046
+ import { existsSync as existsSync23, mkdirSync as mkdirSync13, appendFileSync as appendFileSync5, readFileSync as readFileSync22, writeFileSync as writeFileSync13, renameSync, unlinkSync, statSync } from "fs";
3047
+ import { join as join22, resolve as resolve2, sep } from "path";
3235
3048
  var SENSITIVE_KEYS = [
3236
3049
  "password",
3237
3050
  "token",
@@ -3301,10 +3114,10 @@ function logEvent(directory, event, log) {
3301
3114
  lastPersistenceError = "Invalid directory";
3302
3115
  return false;
3303
3116
  }
3304
- const logDir = join23(directory, ".opencode");
3305
- const logPath = join23(logDir, "flowdeck-events.jsonl");
3117
+ const logDir = join22(directory, ".opencode");
3118
+ const logPath = join22(logDir, "flowdeck-events.jsonl");
3306
3119
  try {
3307
- if (!existsSync24(logDir)) {
3120
+ if (!existsSync23(logDir)) {
3308
3121
  mkdirSync13(logDir, { recursive: true });
3309
3122
  }
3310
3123
  appendFileSync5(logPath, JSON.stringify(event) + `
@@ -3614,45 +3427,45 @@ function stableStringify(obj) {
3614
3427
  return `{${pairs.join(",")}}`;
3615
3428
  }
3616
3429
  function resolveEnvVars(command) {
3617
- return command.replace(/\$RTK_BIN\b/gi, "rtk").replace(/\$HOME\b/gi, "~").replace(/\$USER\b/gi, "user");
3430
+ return command.replace(/\$HOME\b/gi, "~").replace(/\$USER\b/gi, "user");
3618
3431
  }
3619
3432
  function collapseWhitespace(input) {
3620
3433
  return input.replace(/\s+/g, " ").trim();
3621
3434
  }
3622
3435
  function normalizeAction(toolName, args) {
3623
- const tool14 = toolName.toLowerCase();
3624
- if (tool14 === "bash" || tool14 === "shell") {
3436
+ const tool13 = toolName.toLowerCase();
3437
+ if (tool13 === "bash" || tool13 === "shell") {
3625
3438
  const command = typeof args.command === "string" ? args.command : "";
3626
3439
  const normalized = collapseWhitespace(resolveEnvVars(command)).toLowerCase();
3627
3440
  return `shell:${normalized}`;
3628
3441
  }
3629
- if (tool14 === "read" || tool14 === "view") {
3442
+ if (tool13 === "read" || tool13 === "view") {
3630
3443
  const filePath = typeof args.filePath === "string" ? args.filePath : "";
3631
3444
  try {
3632
- return `${tool14}:${resolve3(filePath || "")}`;
3445
+ return `${tool13}:${resolve3(filePath || "")}`;
3633
3446
  } catch {
3634
- return `${tool14}:${filePath}`;
3447
+ return `${tool13}:${filePath}`;
3635
3448
  }
3636
3449
  }
3637
- if (tool14 === "write" || tool14 === "edit") {
3450
+ if (tool13 === "write" || tool13 === "edit") {
3638
3451
  const filePath = typeof args.filePath === "string" ? args.filePath : "";
3639
3452
  try {
3640
- return `${tool14}:${resolve3(filePath || "")}`;
3453
+ return `${tool13}:${resolve3(filePath || "")}`;
3641
3454
  } catch {
3642
- return `${tool14}:${filePath}`;
3455
+ return `${tool13}:${filePath}`;
3643
3456
  }
3644
3457
  }
3645
- if (tool14 === "grep" || tool14 === "glob" || tool14 === "search") {
3458
+ if (tool13 === "grep" || tool13 === "glob" || tool13 === "search") {
3646
3459
  const pattern = typeof args.pattern === "string" ? args.pattern : "";
3647
3460
  const path = typeof args.path === "string" ? args.path : "";
3648
- return `${tool14}:${pattern}:${resolve3(path || ".")}`;
3461
+ return `${tool13}:${pattern}:${resolve3(path || ".")}`;
3649
3462
  }
3650
3463
  const sorted = stableStringify(args);
3651
- return `${tool14}:${sorted}`;
3464
+ return `${tool13}:${sorted}`;
3652
3465
  }
3653
3466
  function classifyObservation(toolName, previous, output, status, similarityThreshold) {
3654
3467
  const outputPreview = getOutputPreview(output);
3655
- const tool14 = toolName.toLowerCase();
3468
+ const tool13 = toolName.toLowerCase();
3656
3469
  if (status === "blocked") {
3657
3470
  return { observation: "same_result", outputHash: hashOutput(output), outputPreview };
3658
3471
  }
@@ -3666,7 +3479,7 @@ function classifyObservation(toolName, previous, output, status, similarityThres
3666
3479
  outputPreview: errorMessage.slice(0, 200)
3667
3480
  };
3668
3481
  }
3669
- if (tool14 === "write" || tool14 === "edit") {
3482
+ if (tool13 === "write" || tool13 === "edit") {
3670
3483
  const contentHash = hashOutput(output);
3671
3484
  return { observation: "new_information", outputHash: contentHash, outputPreview };
3672
3485
  }
@@ -3677,7 +3490,7 @@ function classifyObservation(toolName, previous, output, status, similarityThres
3677
3490
  if (outputHash === previous.outputHash) {
3678
3491
  return { observation: "same_result", outputHash, outputPreview };
3679
3492
  }
3680
- if (NON_MUTATING_TOOLS.has(tool14)) {
3493
+ if (NON_MUTATING_TOOLS.has(tool13)) {
3681
3494
  const similarity = lineSimilarity(outputPreview, previous.outputPreview);
3682
3495
  if (similarity >= similarityThreshold) {
3683
3496
  return { observation: "no_progress", outputHash, outputPreview };
@@ -3686,25 +3499,25 @@ function classifyObservation(toolName, previous, output, status, similarityThres
3686
3499
  return { observation: "new_information", outputHash, outputPreview };
3687
3500
  }
3688
3501
  function redactForDisplay(toolName, normalizedKey) {
3689
- const tool14 = toolName.toLowerCase();
3690
- if (tool14 === "bash" || tool14 === "shell") {
3502
+ const tool13 = toolName.toLowerCase();
3503
+ if (tool13 === "bash" || tool13 === "shell") {
3691
3504
  const idx2 = normalizedKey.indexOf(":");
3692
3505
  const cmd = idx2 >= 0 ? normalizedKey.slice(idx2 + 1) : normalizedKey;
3693
3506
  const preview = cmd.slice(0, 30);
3694
3507
  const hash = djb2Hash(cmd);
3695
- return `${tool14}:"${preview}" (hash: ${hash})`;
3508
+ return `${tool13}:"${preview}" (hash: ${hash})`;
3696
3509
  }
3697
3510
  const idx = normalizedKey.indexOf(":");
3698
3511
  if (idx >= 0) {
3699
3512
  const body = normalizedKey.slice(idx + 1);
3700
3513
  if (body.startsWith("/") || body.startsWith(".") || body.includes("/")) {
3701
- return `${tool14}:"${body}"`;
3514
+ return `${tool13}:"${body}"`;
3702
3515
  }
3703
3516
  const preview = body.slice(0, 30);
3704
3517
  const hash = djb2Hash(body);
3705
- return `${tool14}:"${preview}" (hash: ${hash})`;
3518
+ return `${tool13}:"${preview}" (hash: ${hash})`;
3706
3519
  }
3707
- return `${tool14}:"${normalizedKey}"`;
3520
+ return `${tool13}:"${normalizedKey}"`;
3708
3521
  }
3709
3522
 
3710
3523
  class LoopDetector {
@@ -3904,8 +3717,8 @@ function createContextWindowMonitorHook() {
3904
3717
  }
3905
3718
 
3906
3719
  // src/hooks/shell-env-hook.ts
3907
- import { existsSync as existsSync25, readFileSync as readFileSync23 } from "fs";
3908
- import { join as join24 } from "path";
3720
+ import { existsSync as existsSync24, readFileSync as readFileSync23 } from "fs";
3721
+ import { join as join23 } from "path";
3909
3722
  import { createRequire } from "module";
3910
3723
  var _version;
3911
3724
  function getVersion() {
@@ -3941,7 +3754,7 @@ var MARKER_TO_LANG = {
3941
3754
  };
3942
3755
  function detectPackageManager(root) {
3943
3756
  for (const [lockfile, pm] of Object.entries(LOCKFILE_TO_PM)) {
3944
- if (existsSync25(join24(root, lockfile)))
3757
+ if (existsSync24(join23(root, lockfile)))
3945
3758
  return pm;
3946
3759
  }
3947
3760
  return;
@@ -3950,7 +3763,7 @@ function detectLanguages(root) {
3950
3763
  const langs = [];
3951
3764
  const seen = new Set;
3952
3765
  for (const [marker, lang] of Object.entries(MARKER_TO_LANG)) {
3953
- if (!seen.has(lang) && existsSync25(join24(root, marker))) {
3766
+ if (!seen.has(lang) && existsSync24(join23(root, marker))) {
3954
3767
  langs.push(lang);
3955
3768
  seen.add(lang);
3956
3769
  }
@@ -3958,8 +3771,8 @@ function detectLanguages(root) {
3958
3771
  return langs;
3959
3772
  }
3960
3773
  function readCurrentPhase(root) {
3961
- const statePath3 = join24(root, ".planning", "STATE.md");
3962
- if (!existsSync25(statePath3))
3774
+ const statePath3 = join23(root, ".planning", "STATE.md");
3775
+ if (!existsSync24(statePath3))
3963
3776
  return;
3964
3777
  try {
3965
3778
  const content = readFileSync23(statePath3, "utf-8");
@@ -3969,18 +3782,6 @@ function readCurrentPhase(root) {
3969
3782
  return;
3970
3783
  }
3971
3784
  }
3972
- var _rtkDetection;
3973
- function getRtkDetection() {
3974
- if (_rtkDetection !== undefined)
3975
- return _rtkDetection;
3976
- try {
3977
- const det = detectRtk();
3978
- _rtkDetection = { installed: det.installed, binPath: det.binPath };
3979
- } catch {
3980
- _rtkDetection = { installed: false };
3981
- }
3982
- return _rtkDetection;
3983
- }
3984
3785
  function createShellEnvHook(ctx) {
3985
3786
  const root = ctx.worktree || ctx.directory;
3986
3787
  return async (_input, output) => {
@@ -3998,14 +3799,6 @@ function createShellEnvHook(ctx) {
3998
3799
  const phase = readCurrentPhase(root);
3999
3800
  if (phase)
4000
3801
  output.env.FLOWDECK_PHASE = phase;
4001
- const rtk = getRtkDetection();
4002
- output.env.RTK_INSTALLED = rtk.installed ? "true" : "false";
4003
- if (rtk.installed && rtk.binPath) {
4004
- output.env.RTK_BIN = rtk.binPath;
4005
- }
4006
- if (rtk.installed) {
4007
- output.env.RTK_TELEMETRY_DISABLED = "1";
4008
- }
4009
3802
  };
4010
3803
  }
4011
3804
 
@@ -4087,8 +3880,8 @@ function createSessionIdleHook(client, tracker) {
4087
3880
  }
4088
3881
 
4089
3882
  // src/hooks/compaction-hook.ts
4090
- import { existsSync as existsSync26, readFileSync as readFileSync24 } from "fs";
4091
- import { join as join25 } from "path";
3883
+ import { existsSync as existsSync25, readFileSync as readFileSync24 } from "fs";
3884
+ import { join as join24 } from "path";
4092
3885
  var STRUCTURED_SUMMARY_PROMPT = `
4093
3886
  When summarizing this session, you MUST include the following sections:
4094
3887
 
@@ -4129,7 +3922,7 @@ For each: agent name, status, description, session_id.
4129
3922
  var _lastInjected = new Map;
4130
3923
  function readPlanningState2(directory) {
4131
3924
  const sp = statePath(directory);
4132
- if (!existsSync26(sp))
3925
+ if (!existsSync25(sp))
4133
3926
  return null;
4134
3927
  try {
4135
3928
  const content = readFileSync24(sp, "utf-8");
@@ -4161,15 +3954,15 @@ function createCompactionHook(ctx, tracker) {
4161
3954
  sections.push(`_State unchanged since last compaction. summaryVersion=${currentStateVersion}_`);
4162
3955
  sections.push("");
4163
3956
  }
4164
- const indexPath2 = join25(ctx.directory, ".planning", "CODEBASE_INDEX.md");
4165
- if (indexChanged && existsSync26(indexPath2)) {
3957
+ const indexPath2 = join24(ctx.directory, ".planning", "CODEBASE_INDEX.md");
3958
+ if (indexChanged && existsSync25(indexPath2)) {
4166
3959
  try {
4167
3960
  const indexContent = readFileSync24(indexPath2, "utf-8");
4168
3961
  const indexSummary = "\n## Codebase Index\n```\n" + indexContent.slice(0, 800) + "\n```\n";
4169
3962
  sections.push(indexSummary);
4170
3963
  sections.push("");
4171
3964
  } catch {}
4172
- } else if (existsSync26(indexPath2)) {
3965
+ } else if (existsSync25(indexPath2)) {
4173
3966
  sections.push(`## Codebase Index (unchanged, v${currentIndexVersion})`);
4174
3967
  sections.push(`_Index unchanged since last compaction. summaryVersion=${currentIndexVersion}_`);
4175
3968
  sections.push("");
@@ -4250,7 +4043,6 @@ var ALWAYS_ALLOWED = new Set([
4250
4043
  "load-rules",
4251
4044
  "list-rules",
4252
4045
  "council",
4253
- "rtk-setup",
4254
4046
  "hash-edit",
4255
4047
  "failure-replay"
4256
4048
  ]);
@@ -4288,7 +4080,7 @@ function blockMessage(toolName) {
4288
4080
  ` + ` @tester — tests, builds, and shell-heavy verification
4289
4081
  ` + ` @writer — documentation writing
4290
4082
 
4291
- ` + `Allowed tools for orchestrator: read, search, planning-state, codebase-state, repo-memory, decision-trace, policy-engine, reflect, codegraph, load-rules, council, rtk-setup, hash-edit, failure-replay.
4083
+ ` + `Allowed tools for orchestrator: read, search, planning-state, codebase-state, repo-memory, decision-trace, policy-engine, reflect, codegraph, load-rules, council, hash-edit, failure-replay.
4292
4084
 
4293
4085
  ` + `To disable this guard: set FLOWDECK_ORCHESTRATOR_GUARD=off`;
4294
4086
  }
@@ -4403,14 +4195,14 @@ async function runAutoLearner(client, directory, appLog) {
4403
4195
  }
4404
4196
 
4405
4197
  // src/mcp/index.ts
4406
- import { spawnSync as spawnSync4 } from "child_process";
4198
+ import { spawnSync as spawnSync3 } from "child_process";
4407
4199
  function getDisabledMcps() {
4408
4200
  const raw = process.env.FLOWDECK_DISABLE_MCP ?? "";
4409
4201
  return new Set(raw.split(",").map((s) => s.trim()).filter(Boolean));
4410
4202
  }
4411
4203
  function isLauncherAvailable(launcher) {
4412
4204
  try {
4413
- const result = spawnSync4(launcher, ["--version"], {
4205
+ const result = spawnSync3(launcher, ["--version"], {
4414
4206
  encoding: "utf-8",
4415
4207
  timeout: 5000,
4416
4208
  stdio: "pipe"
@@ -7759,8 +7551,8 @@ function getAgentConfigs(agentModels) {
7759
7551
  // src/index.ts
7760
7552
  function lazyLoadRulePaths(projectRoot) {
7761
7553
  const __dir = dirname3(fileURLToPath2(import.meta.url));
7762
- const rulesDir = join26(__dir, "..", "src", "rules");
7763
- if (!existsSync27(rulesDir))
7554
+ const rulesDir = join25(__dir, "..", "src", "rules");
7555
+ if (!existsSync26(rulesDir))
7764
7556
  return { paths: [], diagnostics: "[LazyRuleLoader] rules directory not found" };
7765
7557
  const detectedLanguages = detectProjectLanguages(projectRoot);
7766
7558
  const paths = getStartupRulePaths(rulesDir, detectedLanguages);
@@ -7770,8 +7562,8 @@ function lazyLoadRulePaths(projectRoot) {
7770
7562
  }
7771
7563
  function loadCommands() {
7772
7564
  const __dir = dirname3(fileURLToPath2(import.meta.url));
7773
- const commandsDir = join26(__dir, "..", "src", "commands");
7774
- if (!existsSync27(commandsDir))
7565
+ const commandsDir = join25(__dir, "..", "src", "commands");
7566
+ if (!existsSync26(commandsDir))
7775
7567
  return {};
7776
7568
  const commands = {};
7777
7569
  try {
@@ -7779,7 +7571,7 @@ function loadCommands() {
7779
7571
  if (!file.endsWith(".md"))
7780
7572
  continue;
7781
7573
  const name = basename2(file, ".md");
7782
- const raw = readFileSync25(join26(commandsDir, file), "utf-8");
7574
+ const raw = readFileSync25(join25(commandsDir, file), "utf-8");
7783
7575
  let description;
7784
7576
  let template = raw;
7785
7577
  const fmMatch = raw.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/);
@@ -7872,8 +7664,8 @@ var plugin = async (input, _options) => {
7872
7664
  }
7873
7665
  }
7874
7666
  }
7875
- const skillsDir = join26(dirname3(fileURLToPath2(import.meta.url)), "..", "src", "skills");
7876
- if (existsSync27(skillsDir)) {
7667
+ const skillsDir = join25(dirname3(fileURLToPath2(import.meta.url)), "..", "src", "skills");
7668
+ if (existsSync26(skillsDir)) {
7877
7669
  const cfgAny = cfg;
7878
7670
  if (!cfgAny.skills || typeof cfgAny.skills !== "object") {
7879
7671
  cfgAny.skills = { paths: [] };
@@ -7912,7 +7704,6 @@ var plugin = async (input, _options) => {
7912
7704
  codegraph: codegraphTool,
7913
7705
  "load-rules": loadRulesTool,
7914
7706
  "list-rules": listRulesTool,
7915
- "rtk-setup": rtkSetupTool,
7916
7707
  "merge-assist": mergeAssistTool
7917
7708
  },
7918
7709
  "shell.env": shellEnvHook,