flavor-code 1.3.8 → 1.3.9

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.
@@ -16,7 +16,7 @@ import {
16
16
  redactErrorText,
17
17
  transcriptReducer,
18
18
  withTimeout
19
- } from "./chunk-GAQJZBOF.js";
19
+ } from "./chunk-M3U2JICC.js";
20
20
  import "./chunk-IG4Z23CL.js";
21
21
  import {
22
22
  Box_default,
@@ -4,7 +4,7 @@ import {
4
4
  message,
5
5
  redactErrorText,
6
6
  redactSecrets
7
- } from "./chunk-GAQJZBOF.js";
7
+ } from "./chunk-M3U2JICC.js";
8
8
 
9
9
  // src/rpc/server.ts
10
10
  import { createInterface } from "readline";
@@ -1984,6 +1984,7 @@ var FILE_TYPE_EXTENSIONS = {
1984
1984
  var GlobInput = z.object({
1985
1985
  pattern: z.string().min(1),
1986
1986
  path: z.string().min(1).describe('Workspace-relative search directory. Use JSON null, not the string "null", for the workspace root.').nullable().optional(),
1987
+ includeIgnored: z.boolean().describe("Include files excluded by .gitignore or .ignore. Git metadata remains excluded.").nullable().optional(),
1987
1988
  limit: z.coerce.number().int().positive().max(1e5).nullable().optional()
1988
1989
  });
1989
1990
  var GrepInput = z.object({
@@ -1991,6 +1992,7 @@ var GrepInput = z.object({
1991
1992
  path: z.string().min(1).describe('Workspace-relative search path. Use JSON null, not the string "null", for the workspace root.').nullable().optional(),
1992
1993
  glob: z.string().min(1).nullable().optional(),
1993
1994
  fileType: z.enum(FILE_TYPES).nullable().optional(),
1995
+ includeIgnored: z.boolean().describe("Include files excluded by .gitignore or .ignore. Git metadata remains excluded.").nullable().optional(),
1994
1996
  context: z.coerce.number().int().nonnegative().max(100).nullable().optional(),
1995
1997
  limit: z.coerce.number().int().positive().max(1e5).nullable().optional()
1996
1998
  });
@@ -2004,23 +2006,26 @@ function createGlobTool(workspace, options = {}) {
2004
2006
  paths: (input) => [scope(root, searchPath(input.path))],
2005
2007
  summarize: (input) => {
2006
2008
  const path = searchPath(input.path);
2007
- return path ? `pattern: "${input.pattern}" in ${path}` : `pattern: "${input.pattern}"`;
2009
+ const ignored2 = input.includeIgnored === true ? " (including ignored files)" : "";
2010
+ return (path ? `pattern: "${input.pattern}" in ${path}` : `pattern: "${input.pattern}"`) + ignored2;
2008
2011
  },
2009
2012
  execute: async (input, signal) => {
2010
2013
  const limit = input.limit ?? options.defaultLimit ?? DEFAULT_RESULT_LIMIT;
2011
2014
  const start = scope(root, searchPath(input.path));
2015
+ if (isGitMetadataPath(root, start)) return { matches: [], truncated: false };
2012
2016
  const matcher = globRegex(input.pattern);
2013
2017
  const ignoreBudget = createIgnoreBudget(resources);
2018
+ const includeIgnored = input.includeIgnored === true;
2014
2019
  let paths;
2015
2020
  if (options.forceNode === true) {
2016
- paths = await nodeFiles(root, start, signal, (path) => matcher.test(path), limit + 1, resources, ignoreBudget);
2021
+ paths = await nodeFiles(root, start, signal, (path) => matcher.test(path), limit + 1, resources, ignoreBudget, includeIgnored);
2017
2022
  } else {
2018
2023
  try {
2019
- paths = await rgFiles(root, start, input.pattern, signal, options.rgPath ?? bundledRgPath, options.rgArgsPrefix ?? [], limit + 1, options.maxSearchBytes ?? DEFAULT_MAX_SEARCH_BYTES, resources, ignoreBudget);
2024
+ paths = await rgFiles(root, start, input.pattern, signal, options.rgPath ?? bundledRgPath, options.rgArgsPrefix ?? [], limit + 1, options.maxSearchBytes ?? DEFAULT_MAX_SEARCH_BYTES, resources, ignoreBudget, includeIgnored);
2020
2025
  } catch (error) {
2021
2026
  if (signal.aborted) throw signal.reason;
2022
2027
  if (!(error instanceof SearchSpawnError) || !error.fallbackSafe) throw error;
2023
- paths = await nodeFiles(root, start, signal, (path) => matcher.test(path), limit + 1, resources, createIgnoreBudget(resources));
2028
+ paths = await nodeFiles(root, start, signal, (path) => matcher.test(path), limit + 1, resources, createIgnoreBudget(resources), includeIgnored);
2024
2029
  }
2025
2030
  }
2026
2031
  const matches = paths.filter((path) => matcher.test(path)).sort(comparePaths);
@@ -2040,24 +2045,27 @@ function createGrepTool(workspace, options = {}) {
2040
2045
  const path = searchPath(input.path);
2041
2046
  const where = path ? ` in ${path}` : "";
2042
2047
  const kind = input.fileType ? ` [${input.fileType}]` : "";
2043
- return `pattern: /${input.pattern}/${kind}${where}`;
2048
+ const ignored2 = input.includeIgnored === true ? " (including ignored files)" : "";
2049
+ return `pattern: /${input.pattern}/${kind}${where}${ignored2}`;
2044
2050
  },
2045
2051
  execute: async (input, signal) => {
2046
2052
  const expression = new RegExp(input.pattern);
2047
2053
  const limit = input.limit ?? options.defaultLimit ?? DEFAULT_RESULT_LIMIT;
2048
2054
  const context = input.context ?? 0;
2049
2055
  const start = await resolveGrepPath(root, searchPath(input.path));
2056
+ if (isGitMetadataPath(root, start)) return { matches: [], truncated: false };
2050
2057
  const ignoreBudget = createIgnoreBudget(resources);
2058
+ const includeIgnored = input.includeIgnored === true;
2051
2059
  let matches;
2052
2060
  if (options.forceNode === true) {
2053
- matches = await nodeGrep(root, start, input.glob ?? void 0, input.fileType ?? void 0, expression, context, signal, limit + 1, options.maxFileBytes ?? DEFAULT_MAX_FILE_BYTES, options.maxSearchBytes ?? DEFAULT_MAX_SEARCH_BYTES, resources, ignoreBudget);
2061
+ matches = await nodeGrep(root, start, input.glob ?? void 0, input.fileType ?? void 0, expression, context, signal, limit + 1, options.maxFileBytes ?? DEFAULT_MAX_FILE_BYTES, options.maxSearchBytes ?? DEFAULT_MAX_SEARCH_BYTES, resources, ignoreBudget, includeIgnored);
2054
2062
  } else {
2055
2063
  try {
2056
2064
  matches = await rgGrep(root, start, input, context, signal, options.rgPath ?? bundledRgPath, options.rgArgsPrefix ?? [], limit + 1, options.maxFileBytes ?? DEFAULT_MAX_FILE_BYTES, options.maxSearchBytes ?? DEFAULT_MAX_SEARCH_BYTES, resources, ignoreBudget);
2057
2065
  } catch (error) {
2058
2066
  if (signal.aborted) throw signal.reason;
2059
2067
  if (!(error instanceof SearchSpawnError) || !error.fallbackSafe) throw error;
2060
- matches = await nodeGrep(root, start, input.glob ?? void 0, input.fileType ?? void 0, expression, context, signal, limit + 1, options.maxFileBytes ?? DEFAULT_MAX_FILE_BYTES, options.maxSearchBytes ?? DEFAULT_MAX_SEARCH_BYTES, resources, createIgnoreBudget(resources));
2068
+ matches = await nodeGrep(root, start, input.glob ?? void 0, input.fileType ?? void 0, expression, context, signal, limit + 1, options.maxFileBytes ?? DEFAULT_MAX_FILE_BYTES, options.maxSearchBytes ?? DEFAULT_MAX_SEARCH_BYTES, resources, createIgnoreBudget(resources), includeIgnored);
2061
2069
  }
2062
2070
  }
2063
2071
  matches.sort(compareGrepMatches);
@@ -2065,10 +2073,10 @@ function createGrepTool(workspace, options = {}) {
2065
2073
  }
2066
2074
  };
2067
2075
  }
2068
- async function rgFiles(root, start, pattern, signal, executable, argsPrefix, limit, maxBytes, resources, ignoreBudget) {
2076
+ async function rgFiles(root, start, pattern, signal, executable, argsPrefix, limit, maxBytes, resources, ignoreBudget, includeIgnored) {
2069
2077
  const target = relative4(root, start) || ".";
2070
2078
  const matcher = globRegex(pattern);
2071
- const ignoreLayers = await collectIgnoreLayers(root, start, signal, resources, ignoreBudget);
2079
+ const ignoreLayers = includeIgnored ? [] : await collectIgnoreLayers(root, start, signal, resources, ignoreBudget);
2072
2080
  const paths = [];
2073
2081
  const parser = delimitedParser(0, (record) => {
2074
2082
  if (record.length === 0) return true;
@@ -2077,7 +2085,10 @@ async function rgFiles(root, start, pattern, signal, executable, argsPrefix, lim
2077
2085
  retainTopK(paths, path, limit, comparePaths);
2078
2086
  return true;
2079
2087
  });
2080
- const output = await runStreaming(executable, [...argsPrefix, "--files", "--null", "--sort", "path", "--hidden", "--glob", "!.git", "--glob", pattern, "--", target], root, signal, maxBytes, parser);
2088
+ const args = [...argsPrefix, "--files", "--null", "--sort", "path", "--hidden", "--glob", "!.git", "--glob", "!.git/**"];
2089
+ if (includeIgnored) args.push("--no-ignore");
2090
+ args.push("--glob", pattern, "--", target);
2091
+ const output = await runStreaming(executable, args, root, signal, maxBytes, parser);
2081
2092
  if (!output.stoppedEarly && output.code !== 0 && output.code !== 1) throw new Error(output.stderr || `ripgrep exited with ${output.code}`);
2082
2093
  parser.finish();
2083
2094
  return paths;
@@ -2087,12 +2098,13 @@ async function rgGrep(root, start, input, context, signal, executable, argsPrefi
2087
2098
  if (input.fileType !== void 0 && input.fileType !== null && typeExtensions === void 0) {
2088
2099
  throw new Error(`Unsupported file type: ${input.fileType}`);
2089
2100
  }
2090
- const args = ["--json", "--line-number", "--column", "--sort", "path", "--hidden", "--glob", "!.git", "--max-filesize", String(maxFileBytes), "--context", String(context)];
2101
+ const args = ["--json", "--line-number", "--column", "--sort", "path", "--hidden", "--glob", "!.git", "--glob", "!.git/**", "--max-filesize", String(maxFileBytes), "--context", String(context)];
2102
+ if (input.includeIgnored === true) args.push("--no-ignore");
2091
2103
  if (input.glob !== void 0 && input.glob !== null) args.push("--glob", input.glob);
2092
2104
  else for (const extension of typeExtensions ?? []) args.push("--glob", `*${extension}`);
2093
2105
  args.push("--regexp", input.pattern, "--", relative4(root, start) || ".");
2094
2106
  const matches = [];
2095
- const ignoreLayers = await collectIgnoreLayers(root, start, signal, resources, ignoreBudget);
2107
+ const ignoreLayers = input.includeIgnored === true ? [] : await collectIgnoreLayers(root, start, signal, resources, ignoreBudget);
2096
2108
  const parser = delimitedParser(10, (record) => {
2097
2109
  if (record.length === 0) return true;
2098
2110
  const event = JSON.parse(decodeUtf8(record, "ripgrep JSON"));
@@ -2147,8 +2159,8 @@ async function hydrateContext(root, matches, context, signal, maxFileBytes, maxT
2147
2159
  }
2148
2160
  }
2149
2161
  }
2150
- async function nodeGrep(root, start, glob, type, expression, context, signal, maxMatches, maxFileBytes, maxSearchBytes, resources, ignoreBudget) {
2151
- const files = await nodeFiles(root, start, signal, () => true, resources.maxDiscoveredFiles + 1, resources, ignoreBudget);
2162
+ async function nodeGrep(root, start, glob, type, expression, context, signal, maxMatches, maxFileBytes, maxSearchBytes, resources, ignoreBudget, includeIgnored) {
2163
+ const files = await nodeFiles(root, start, signal, () => true, resources.maxDiscoveredFiles + 1, resources, ignoreBudget, includeIgnored);
2152
2164
  if (files.length > resources.maxDiscoveredFiles) throw new Error(`Aggregate discovered file limit of ${resources.maxDiscoveredFiles} exceeded`);
2153
2165
  const matcher = glob === void 0 ? void 0 : globRegex(glob);
2154
2166
  const extension = type === void 0 ? void 0 : typeExtension(type);
@@ -2190,23 +2202,25 @@ async function nodeGrep(root, start, glob, type, expression, context, signal, ma
2190
2202
  }
2191
2203
  return matches;
2192
2204
  }
2193
- async function nodeFiles(root, start, signal, accept, limit, resources, ignoreBudget) {
2205
+ async function nodeFiles(root, start, signal, accept, limit, resources, ignoreBudget, includeIgnored) {
2194
2206
  const ignores = [];
2195
2207
  const output = [];
2196
2208
  const delta = relative4(root, start);
2197
2209
  const segments = delta === "" ? [] : delta.split(sep4);
2198
2210
  let ancestor = root;
2199
- for (let index = 0; index < segments.length; index += 1) {
2200
- noteIgnoreDirectory(ignoreBudget);
2201
- await loadIgnoreFiles(ancestor, normalizedRelative(root, ancestor), ignores, ignoreBudget, signal);
2202
- ancestor = resolve4(ancestor, segments[index]);
2211
+ if (!includeIgnored) {
2212
+ for (let index = 0; index < segments.length; index += 1) {
2213
+ noteIgnoreDirectory(ignoreBudget);
2214
+ await loadIgnoreFiles(ancestor, normalizedRelative(root, ancestor), ignores, ignoreBudget, signal);
2215
+ ancestor = resolve4(ancestor, segments[index]);
2216
+ }
2203
2217
  }
2204
2218
  async function walk(directory) {
2205
2219
  abort(signal);
2206
2220
  const relativeDirectory = normalizedRelative(root, directory);
2207
2221
  const ruleCount = ignores.length;
2208
2222
  noteIgnoreDirectory(ignoreBudget);
2209
- await loadIgnoreFiles(directory, relativeDirectory, ignores, ignoreBudget, signal);
2223
+ if (!includeIgnored) await loadIgnoreFiles(directory, relativeDirectory, ignores, ignoreBudget, signal);
2210
2224
  const handle = await opendir(directory);
2211
2225
  const entries = [];
2212
2226
  for await (const entry2 of handle) {
@@ -2219,7 +2233,7 @@ async function nodeFiles(root, start, signal, accept, limit, resources, ignoreBu
2219
2233
  abort(signal);
2220
2234
  const absolute = resolve4(directory, entry2.name);
2221
2235
  const path = normalizedRelative(root, absolute);
2222
- if (entry2.name === ".git" || ignored(path, entry2.isDirectory(), ignores)) continue;
2236
+ if (entry2.name === ".git" || !includeIgnored && ignored(path, entry2.isDirectory(), ignores)) continue;
2223
2237
  if (entry2.isDirectory()) await walk(absolute);
2224
2238
  else if (entry2.isFile() && accept(path)) output.push(path);
2225
2239
  if (output.length >= limit) break;
@@ -2388,6 +2402,9 @@ function normalizedRelative(root, path) {
2388
2402
  function normalizePath(path) {
2389
2403
  return path.replaceAll("\\", "/");
2390
2404
  }
2405
+ function isGitMetadataPath(root, path) {
2406
+ return normalizedRelative(root, path).split("/").some((segment) => segment.toLowerCase() === ".git");
2407
+ }
2391
2408
  function comparePaths(a, b) {
2392
2409
  return a < b ? -1 : a > b ? 1 : 0;
2393
2410
  }
@@ -13965,8 +13982,8 @@ function toolsSection(toolNames) {
13965
13982
  addToolRule(rules, toolNames, "Write", "Use `Write` to create a file only when a new file is necessary.");
13966
13983
  addToolRule(rules, toolNames, "Edit", "Use `Edit` for precise replacements in existing files. Before editing, read the file and copy `oldText` verbatim from its actual current content \u2014 exact characters matter, including quote style (full-width vs ASCII) and version strings. Include enough surrounding lines to make the match unique.");
13967
13984
  addToolRule(rules, toolNames, "ApplyPatch", "Use `ApplyPatch` only when an edit genuinely spans multiple regions of one file; hunks may relocate only when their exact context has one unique nearby match. Prefer `Edit` for a single small replacement \u2014 it is easier to get right.");
13968
- addToolRule(rules, toolNames, "Glob", "Use `Glob` to find files by path pattern instead of shell directory crawling. Confirm the exact path before reading, searching, or editing; the search scope is limited to the workspace, so never pass absolute paths outside it.");
13969
- addToolRule(rules, toolNames, "Grep", "Use `Grep` to search file contents instead of shell text-search commands.");
13985
+ addToolRule(rules, toolNames, "Glob", "Use `Glob` to find files by path pattern instead of shell directory crawling. Confirm the exact path before reading, searching, or editing; the search scope is limited to the workspace, so never pass absolute paths outside it. Set `includeIgnored: true` only when the user explicitly asks to inspect ignored files or an ignored path is required for the task.");
13986
+ addToolRule(rules, toolNames, "Grep", "Use `Grep` to search file contents instead of shell text-search commands. Set `includeIgnored: true` only when the user explicitly asks to inspect ignored files or an ignored path is required for the task.");
13970
13987
  addToolRule(rules, toolNames, "Shell", "Use `Shell` for builds, tests, Git inspection, and commands without a dedicated tool. Keep commands scoped, non-interactive, and easy to audit.");
13971
13988
  addToolRule(rules, toolNames, "LspFindRefs", "Use `LspFindRefs` to find all references to a symbol using the Language Server Protocol. Prefer this over Grep when you need precise semantic results.");
13972
13989
  addToolRule(rules, toolNames, "LspHover", "Use `LspHover` to get type information and documentation for a symbol at a cursor position.");
package/dist/cli.js CHANGED
@@ -3,7 +3,7 @@ import { createRequire } from "node:module"; const require = createRequire(impor
3
3
  import {
4
4
  FlavorRpcServer,
5
5
  TraceRecorder
6
- } from "./chunk-EJCI3VB5.js";
6
+ } from "./chunk-D4334NAE.js";
7
7
  import {
8
8
  staticTaskLines
9
9
  } from "./chunk-KKIBYDJI.js";
@@ -23,7 +23,7 @@ import {
23
23
  packageVersion,
24
24
  redactErrorText,
25
25
  runPalBroker
26
- } from "./chunk-GAQJZBOF.js";
26
+ } from "./chunk-M3U2JICC.js";
27
27
  import {
28
28
  McpServerConfigSchema,
29
29
  McpServerNameSchema,
@@ -877,7 +877,7 @@ async function runInteractiveCli(props) {
877
877
  const [{ render, AlternateScreen }, { createElement }, { App }] = await Promise.all([
878
878
  import("./claude-ink-ORUA7GWG.js"),
879
879
  import("react"),
880
- import("./app-OLOUQDIG.js")
880
+ import("./app-XAV5LRM7.js")
881
881
  ]);
882
882
  const instance = await render(createElement(
883
883
  AlternateScreen,
@@ -14603,8 +14603,8 @@ function toolsSection(toolNames) {
14603
14603
  addToolRule(rules, toolNames, "Write", "Use `Write` to create a file only when a new file is necessary.");
14604
14604
  addToolRule(rules, toolNames, "Edit", "Use `Edit` for precise replacements in existing files. Before editing, read the file and copy `oldText` verbatim from its actual current content \u2014 exact characters matter, including quote style (full-width vs ASCII) and version strings. Include enough surrounding lines to make the match unique.");
14605
14605
  addToolRule(rules, toolNames, "ApplyPatch", "Use `ApplyPatch` only when an edit genuinely spans multiple regions of one file; hunks may relocate only when their exact context has one unique nearby match. Prefer `Edit` for a single small replacement \u2014 it is easier to get right.");
14606
- addToolRule(rules, toolNames, "Glob", "Use `Glob` to find files by path pattern instead of shell directory crawling. Confirm the exact path before reading, searching, or editing; the search scope is limited to the workspace, so never pass absolute paths outside it.");
14607
- addToolRule(rules, toolNames, "Grep", "Use `Grep` to search file contents instead of shell text-search commands.");
14606
+ addToolRule(rules, toolNames, "Glob", "Use `Glob` to find files by path pattern instead of shell directory crawling. Confirm the exact path before reading, searching, or editing; the search scope is limited to the workspace, so never pass absolute paths outside it. Set `includeIgnored: true` only when the user explicitly asks to inspect ignored files or an ignored path is required for the task.");
14607
+ addToolRule(rules, toolNames, "Grep", "Use `Grep` to search file contents instead of shell text-search commands. Set `includeIgnored: true` only when the user explicitly asks to inspect ignored files or an ignored path is required for the task.");
14608
14608
  addToolRule(rules, toolNames, "Shell", "Use `Shell` for builds, tests, Git inspection, and commands without a dedicated tool. Keep commands scoped, non-interactive, and easy to audit.");
14609
14609
  addToolRule(rules, toolNames, "LspFindRefs", "Use `LspFindRefs` to find all references to a symbol using the Language Server Protocol. Prefer this over Grep when you need precise semantic results.");
14610
14610
  addToolRule(rules, toolNames, "LspHover", "Use `LspHover` to get type information and documentation for a symbol at a cursor position.");
@@ -17897,6 +17897,7 @@ var FILE_TYPE_EXTENSIONS = {
17897
17897
  var GlobInput = z30.object({
17898
17898
  pattern: z30.string().min(1),
17899
17899
  path: z30.string().min(1).describe('Workspace-relative search directory. Use JSON null, not the string "null", for the workspace root.').nullable().optional(),
17900
+ includeIgnored: z30.boolean().describe("Include files excluded by .gitignore or .ignore. Git metadata remains excluded.").nullable().optional(),
17900
17901
  limit: z30.coerce.number().int().positive().max(1e5).nullable().optional()
17901
17902
  });
17902
17903
  var GrepInput = z30.object({
@@ -17904,6 +17905,7 @@ var GrepInput = z30.object({
17904
17905
  path: z30.string().min(1).describe('Workspace-relative search path. Use JSON null, not the string "null", for the workspace root.').nullable().optional(),
17905
17906
  glob: z30.string().min(1).nullable().optional(),
17906
17907
  fileType: z30.enum(FILE_TYPES).nullable().optional(),
17908
+ includeIgnored: z30.boolean().describe("Include files excluded by .gitignore or .ignore. Git metadata remains excluded.").nullable().optional(),
17907
17909
  context: z30.coerce.number().int().nonnegative().max(100).nullable().optional(),
17908
17910
  limit: z30.coerce.number().int().positive().max(1e5).nullable().optional()
17909
17911
  });
@@ -17917,23 +17919,26 @@ function createGlobTool(workspace, options = {}) {
17917
17919
  paths: (input) => [scope(root, searchPath(input.path))],
17918
17920
  summarize: (input) => {
17919
17921
  const path = searchPath(input.path);
17920
- return path ? `pattern: "${input.pattern}" in ${path}` : `pattern: "${input.pattern}"`;
17922
+ const ignored2 = input.includeIgnored === true ? " (including ignored files)" : "";
17923
+ return (path ? `pattern: "${input.pattern}" in ${path}` : `pattern: "${input.pattern}"`) + ignored2;
17921
17924
  },
17922
17925
  execute: async (input, signal) => {
17923
17926
  const limit = input.limit ?? options.defaultLimit ?? DEFAULT_RESULT_LIMIT;
17924
17927
  const start = scope(root, searchPath(input.path));
17928
+ if (isGitMetadataPath(root, start)) return { matches: [], truncated: false };
17925
17929
  const matcher = globRegex(input.pattern);
17926
17930
  const ignoreBudget = createIgnoreBudget(resources);
17931
+ const includeIgnored = input.includeIgnored === true;
17927
17932
  let paths;
17928
17933
  if (options.forceNode === true) {
17929
- paths = await nodeFiles(root, start, signal, (path) => matcher.test(path), limit + 1, resources, ignoreBudget);
17934
+ paths = await nodeFiles(root, start, signal, (path) => matcher.test(path), limit + 1, resources, ignoreBudget, includeIgnored);
17930
17935
  } else {
17931
17936
  try {
17932
- paths = await rgFiles(root, start, input.pattern, signal, options.rgPath ?? bundledRgPath, options.rgArgsPrefix ?? [], limit + 1, options.maxSearchBytes ?? DEFAULT_MAX_SEARCH_BYTES, resources, ignoreBudget);
17937
+ paths = await rgFiles(root, start, input.pattern, signal, options.rgPath ?? bundledRgPath, options.rgArgsPrefix ?? [], limit + 1, options.maxSearchBytes ?? DEFAULT_MAX_SEARCH_BYTES, resources, ignoreBudget, includeIgnored);
17933
17938
  } catch (error) {
17934
17939
  if (signal.aborted) throw signal.reason;
17935
17940
  if (!(error instanceof SearchSpawnError) || !error.fallbackSafe) throw error;
17936
- paths = await nodeFiles(root, start, signal, (path) => matcher.test(path), limit + 1, resources, createIgnoreBudget(resources));
17941
+ paths = await nodeFiles(root, start, signal, (path) => matcher.test(path), limit + 1, resources, createIgnoreBudget(resources), includeIgnored);
17937
17942
  }
17938
17943
  }
17939
17944
  const matches = paths.filter((path) => matcher.test(path)).sort(comparePaths);
@@ -17953,24 +17958,27 @@ function createGrepTool(workspace, options = {}) {
17953
17958
  const path = searchPath(input.path);
17954
17959
  const where = path ? ` in ${path}` : "";
17955
17960
  const kind = input.fileType ? ` [${input.fileType}]` : "";
17956
- return `pattern: /${input.pattern}/${kind}${where}`;
17961
+ const ignored2 = input.includeIgnored === true ? " (including ignored files)" : "";
17962
+ return `pattern: /${input.pattern}/${kind}${where}${ignored2}`;
17957
17963
  },
17958
17964
  execute: async (input, signal) => {
17959
17965
  const expression = new RegExp(input.pattern);
17960
17966
  const limit = input.limit ?? options.defaultLimit ?? DEFAULT_RESULT_LIMIT;
17961
17967
  const context = input.context ?? 0;
17962
17968
  const start = await resolveGrepPath(root, searchPath(input.path));
17969
+ if (isGitMetadataPath(root, start)) return { matches: [], truncated: false };
17963
17970
  const ignoreBudget = createIgnoreBudget(resources);
17971
+ const includeIgnored = input.includeIgnored === true;
17964
17972
  let matches;
17965
17973
  if (options.forceNode === true) {
17966
- matches = await nodeGrep(root, start, input.glob ?? void 0, input.fileType ?? void 0, expression, context, signal, limit + 1, options.maxFileBytes ?? DEFAULT_MAX_FILE_BYTES, options.maxSearchBytes ?? DEFAULT_MAX_SEARCH_BYTES, resources, ignoreBudget);
17974
+ matches = await nodeGrep(root, start, input.glob ?? void 0, input.fileType ?? void 0, expression, context, signal, limit + 1, options.maxFileBytes ?? DEFAULT_MAX_FILE_BYTES, options.maxSearchBytes ?? DEFAULT_MAX_SEARCH_BYTES, resources, ignoreBudget, includeIgnored);
17967
17975
  } else {
17968
17976
  try {
17969
17977
  matches = await rgGrep(root, start, input, context, signal, options.rgPath ?? bundledRgPath, options.rgArgsPrefix ?? [], limit + 1, options.maxFileBytes ?? DEFAULT_MAX_FILE_BYTES, options.maxSearchBytes ?? DEFAULT_MAX_SEARCH_BYTES, resources, ignoreBudget);
17970
17978
  } catch (error) {
17971
17979
  if (signal.aborted) throw signal.reason;
17972
17980
  if (!(error instanceof SearchSpawnError) || !error.fallbackSafe) throw error;
17973
- matches = await nodeGrep(root, start, input.glob ?? void 0, input.fileType ?? void 0, expression, context, signal, limit + 1, options.maxFileBytes ?? DEFAULT_MAX_FILE_BYTES, options.maxSearchBytes ?? DEFAULT_MAX_SEARCH_BYTES, resources, createIgnoreBudget(resources));
17981
+ matches = await nodeGrep(root, start, input.glob ?? void 0, input.fileType ?? void 0, expression, context, signal, limit + 1, options.maxFileBytes ?? DEFAULT_MAX_FILE_BYTES, options.maxSearchBytes ?? DEFAULT_MAX_SEARCH_BYTES, resources, createIgnoreBudget(resources), includeIgnored);
17974
17982
  }
17975
17983
  }
17976
17984
  matches.sort(compareGrepMatches);
@@ -17978,10 +17986,10 @@ function createGrepTool(workspace, options = {}) {
17978
17986
  }
17979
17987
  };
17980
17988
  }
17981
- async function rgFiles(root, start, pattern, signal, executable, argsPrefix, limit, maxBytes, resources, ignoreBudget) {
17989
+ async function rgFiles(root, start, pattern, signal, executable, argsPrefix, limit, maxBytes, resources, ignoreBudget, includeIgnored) {
17982
17990
  const target = relative17(root, start) || ".";
17983
17991
  const matcher = globRegex(pattern);
17984
- const ignoreLayers = await collectIgnoreLayers(root, start, signal, resources, ignoreBudget);
17992
+ const ignoreLayers = includeIgnored ? [] : await collectIgnoreLayers(root, start, signal, resources, ignoreBudget);
17985
17993
  const paths = [];
17986
17994
  const parser = delimitedParser(0, (record3) => {
17987
17995
  if (record3.length === 0) return true;
@@ -17990,7 +17998,10 @@ async function rgFiles(root, start, pattern, signal, executable, argsPrefix, lim
17990
17998
  retainTopK(paths, path, limit, comparePaths);
17991
17999
  return true;
17992
18000
  });
17993
- const output = await runStreaming(executable, [...argsPrefix, "--files", "--null", "--sort", "path", "--hidden", "--glob", "!.git", "--glob", pattern, "--", target], root, signal, maxBytes, parser);
18001
+ const args = [...argsPrefix, "--files", "--null", "--sort", "path", "--hidden", "--glob", "!.git", "--glob", "!.git/**"];
18002
+ if (includeIgnored) args.push("--no-ignore");
18003
+ args.push("--glob", pattern, "--", target);
18004
+ const output = await runStreaming(executable, args, root, signal, maxBytes, parser);
17994
18005
  if (!output.stoppedEarly && output.code !== 0 && output.code !== 1) throw new Error(output.stderr || `ripgrep exited with ${output.code}`);
17995
18006
  parser.finish();
17996
18007
  return paths;
@@ -18000,12 +18011,13 @@ async function rgGrep(root, start, input, context, signal, executable, argsPrefi
18000
18011
  if (input.fileType !== void 0 && input.fileType !== null && typeExtensions === void 0) {
18001
18012
  throw new Error(`Unsupported file type: ${input.fileType}`);
18002
18013
  }
18003
- const args = ["--json", "--line-number", "--column", "--sort", "path", "--hidden", "--glob", "!.git", "--max-filesize", String(maxFileBytes), "--context", String(context)];
18014
+ const args = ["--json", "--line-number", "--column", "--sort", "path", "--hidden", "--glob", "!.git", "--glob", "!.git/**", "--max-filesize", String(maxFileBytes), "--context", String(context)];
18015
+ if (input.includeIgnored === true) args.push("--no-ignore");
18004
18016
  if (input.glob !== void 0 && input.glob !== null) args.push("--glob", input.glob);
18005
18017
  else for (const extension2 of typeExtensions ?? []) args.push("--glob", `*${extension2}`);
18006
18018
  args.push("--regexp", input.pattern, "--", relative17(root, start) || ".");
18007
18019
  const matches = [];
18008
- const ignoreLayers = await collectIgnoreLayers(root, start, signal, resources, ignoreBudget);
18020
+ const ignoreLayers = input.includeIgnored === true ? [] : await collectIgnoreLayers(root, start, signal, resources, ignoreBudget);
18009
18021
  const parser = delimitedParser(10, (record3) => {
18010
18022
  if (record3.length === 0) return true;
18011
18023
  const event = JSON.parse(decodeUtf82(record3, "ripgrep JSON"));
@@ -18060,8 +18072,8 @@ async function hydrateContext(root, matches, context, signal, maxFileBytes, maxT
18060
18072
  }
18061
18073
  }
18062
18074
  }
18063
- async function nodeGrep(root, start, glob, type, expression, context, signal, maxMatches, maxFileBytes, maxSearchBytes, resources, ignoreBudget) {
18064
- const files = await nodeFiles(root, start, signal, () => true, resources.maxDiscoveredFiles + 1, resources, ignoreBudget);
18075
+ async function nodeGrep(root, start, glob, type, expression, context, signal, maxMatches, maxFileBytes, maxSearchBytes, resources, ignoreBudget, includeIgnored) {
18076
+ const files = await nodeFiles(root, start, signal, () => true, resources.maxDiscoveredFiles + 1, resources, ignoreBudget, includeIgnored);
18065
18077
  if (files.length > resources.maxDiscoveredFiles) throw new Error(`Aggregate discovered file limit of ${resources.maxDiscoveredFiles} exceeded`);
18066
18078
  const matcher = glob === void 0 ? void 0 : globRegex(glob);
18067
18079
  const extension2 = type === void 0 ? void 0 : typeExtension(type);
@@ -18103,23 +18115,25 @@ async function nodeGrep(root, start, glob, type, expression, context, signal, ma
18103
18115
  }
18104
18116
  return matches;
18105
18117
  }
18106
- async function nodeFiles(root, start, signal, accept, limit, resources, ignoreBudget) {
18118
+ async function nodeFiles(root, start, signal, accept, limit, resources, ignoreBudget, includeIgnored) {
18107
18119
  const ignores = [];
18108
18120
  const output = [];
18109
18121
  const delta = relative17(root, start);
18110
18122
  const segments = delta === "" ? [] : delta.split(sep17);
18111
18123
  let ancestor = root;
18112
- for (let index = 0; index < segments.length; index += 1) {
18113
- noteIgnoreDirectory(ignoreBudget);
18114
- await loadIgnoreFiles(ancestor, normalizedRelative(root, ancestor), ignores, ignoreBudget, signal);
18115
- ancestor = resolve24(ancestor, segments[index]);
18124
+ if (!includeIgnored) {
18125
+ for (let index = 0; index < segments.length; index += 1) {
18126
+ noteIgnoreDirectory(ignoreBudget);
18127
+ await loadIgnoreFiles(ancestor, normalizedRelative(root, ancestor), ignores, ignoreBudget, signal);
18128
+ ancestor = resolve24(ancestor, segments[index]);
18129
+ }
18116
18130
  }
18117
18131
  async function walk(directory) {
18118
18132
  abort(signal);
18119
18133
  const relativeDirectory = normalizedRelative(root, directory);
18120
18134
  const ruleCount = ignores.length;
18121
18135
  noteIgnoreDirectory(ignoreBudget);
18122
- await loadIgnoreFiles(directory, relativeDirectory, ignores, ignoreBudget, signal);
18136
+ if (!includeIgnored) await loadIgnoreFiles(directory, relativeDirectory, ignores, ignoreBudget, signal);
18123
18137
  const handle = await opendir(directory);
18124
18138
  const entries = [];
18125
18139
  for await (const entry2 of handle) {
@@ -18132,7 +18146,7 @@ async function nodeFiles(root, start, signal, accept, limit, resources, ignoreBu
18132
18146
  abort(signal);
18133
18147
  const absolute = resolve24(directory, entry2.name);
18134
18148
  const path = normalizedRelative(root, absolute);
18135
- if (entry2.name === ".git" || ignored(path, entry2.isDirectory(), ignores)) continue;
18149
+ if (entry2.name === ".git" || !includeIgnored && ignored(path, entry2.isDirectory(), ignores)) continue;
18136
18150
  if (entry2.isDirectory()) await walk(absolute);
18137
18151
  else if (entry2.isFile() && accept(path)) output.push(path);
18138
18152
  if (output.length >= limit) break;
@@ -18301,6 +18315,9 @@ function normalizedRelative(root, path) {
18301
18315
  function normalizePath(path) {
18302
18316
  return path.replaceAll("\\", "/");
18303
18317
  }
18318
+ function isGitMetadataPath(root, path) {
18319
+ return normalizedRelative(root, path).split("/").some((segment) => segment.toLowerCase() === ".git");
18320
+ }
18304
18321
  function comparePaths(a, b) {
18305
18322
  return a < b ? -1 : a > b ? 1 : 0;
18306
18323
  }
package/dist/sdk/index.js CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  FlavorRpcServer,
5
5
  TraceRecordSchema,
6
6
  TraceRecorder
7
- } from "../chunk-EJCI3VB5.js";
7
+ } from "../chunk-D4334NAE.js";
8
8
  import {
9
9
  AgentMessageQueue,
10
10
  DockerExecutionEnvironment,
@@ -13,7 +13,7 @@ import {
13
13
  WorkspaceCheckpointStore,
14
14
  buildDockerInvocation,
15
15
  createProductionRuntime
16
- } from "../chunk-GAQJZBOF.js";
16
+ } from "../chunk-M3U2JICC.js";
17
17
  import "../chunk-IG4Z23CL.js";
18
18
  import "../chunk-RQTYHUMK.js";
19
19
  import "../chunk-S32JRDZK.js";
@@ -3,6 +3,7 @@ import type { ToolDefinition } from "./types.js";
3
3
  declare const GlobInput: z.ZodObject<{
4
4
  pattern: z.ZodString;
5
5
  path: z.ZodOptional<z.ZodNullable<z.ZodString>>;
6
+ includeIgnored: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
6
7
  limit: z.ZodOptional<z.ZodNullable<z.ZodCoercedNumber<unknown>>>;
7
8
  }, z.core.$strip>;
8
9
  declare const GrepInput: z.ZodObject<{
@@ -40,6 +41,7 @@ declare const GrepInput: z.ZodObject<{
40
41
  xml: "xml";
41
42
  yaml: "yaml";
42
43
  }>>>;
44
+ includeIgnored: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
43
45
  context: z.ZodOptional<z.ZodNullable<z.ZodCoercedNumber<unknown>>>;
44
46
  limit: z.ZodOptional<z.ZodNullable<z.ZodCoercedNumber<unknown>>>;
45
47
  }, z.core.$strip>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flavor-code",
3
- "version": "1.3.8",
3
+ "version": "1.3.9",
4
4
  "author": "YachuanWzh",
5
5
  "type": "module",
6
6
  "publishConfig": {