@travisennis/acai 0.0.12 → 0.0.14

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 (242) hide show
  1. package/README.md +5 -2
  2. package/dist/agent/index.d.ts.map +1 -1
  3. package/dist/agent/index.js +91 -5
  4. package/dist/commands/history/types.d.ts +3 -2
  5. package/dist/commands/history/types.d.ts.map +1 -1
  6. package/dist/commands/init-project/utils.d.ts +0 -1
  7. package/dist/commands/init-project/utils.d.ts.map +1 -1
  8. package/dist/commands/init-project/utils.js +1 -1
  9. package/dist/commands/manager.d.ts.map +1 -1
  10. package/dist/commands/manager.js +0 -18
  11. package/dist/commands/share/html-renderer.d.ts.map +1 -1
  12. package/dist/commands/share/html-renderer.js +54 -48
  13. package/dist/commands/tools/index.js +39 -38
  14. package/dist/config/index.d.ts +0 -2
  15. package/dist/config/index.d.ts.map +1 -1
  16. package/dist/config/index.js +3 -7
  17. package/dist/index.d.ts +14 -0
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +94 -76
  20. package/dist/models/manager.d.ts +1 -10
  21. package/dist/models/manager.d.ts.map +1 -1
  22. package/dist/models/manager.js +2 -2
  23. package/dist/models/opencode-go-provider.d.ts +6 -4
  24. package/dist/models/opencode-go-provider.d.ts.map +1 -1
  25. package/dist/models/opencode-go-provider.js +55 -35
  26. package/dist/models/providers.d.ts +1 -1
  27. package/dist/models/providers.d.ts.map +1 -1
  28. package/dist/prompts/system-prompt.d.ts +0 -2
  29. package/dist/prompts/system-prompt.d.ts.map +1 -1
  30. package/dist/prompts/system-prompt.js +6 -10
  31. package/dist/repl/index.d.ts +27 -11
  32. package/dist/repl/index.d.ts.map +1 -1
  33. package/dist/repl/index.js +238 -254
  34. package/dist/sessions/manager.d.ts +41 -0
  35. package/dist/sessions/manager.d.ts.map +1 -1
  36. package/dist/sessions/manager.js +53 -0
  37. package/dist/sessions/summary.d.ts.map +1 -1
  38. package/dist/sessions/summary.js +18 -0
  39. package/dist/skills/index.d.ts +12 -2
  40. package/dist/skills/index.d.ts.map +1 -1
  41. package/dist/skills/index.js +123 -73
  42. package/dist/terminal/control.d.ts +1 -21
  43. package/dist/terminal/control.d.ts.map +1 -1
  44. package/dist/terminal/control.js +1 -32
  45. package/dist/terminal/formatting.d.ts +0 -33
  46. package/dist/terminal/formatting.d.ts.map +1 -1
  47. package/dist/terminal/formatting.js +0 -91
  48. package/dist/terminal/highlight/theme.d.ts +0 -37
  49. package/dist/terminal/highlight/theme.d.ts.map +1 -1
  50. package/dist/terminal/highlight/theme.js +1 -79
  51. package/dist/terminal/keys.d.ts +0 -97
  52. package/dist/terminal/keys.d.ts.map +1 -1
  53. package/dist/terminal/keys.js +0 -194
  54. package/dist/terminal/select-prompt.d.ts.map +1 -1
  55. package/dist/terminal/select-prompt.js +65 -51
  56. package/dist/terminal/style.d.ts +1 -1
  57. package/dist/terminal/style.d.ts.map +1 -1
  58. package/dist/terminal/supports-color.d.ts.map +1 -1
  59. package/dist/terminal/supports-color.js +38 -20
  60. package/dist/terminal/supports-hyperlinks.d.ts +3 -0
  61. package/dist/terminal/supports-hyperlinks.d.ts.map +1 -1
  62. package/dist/terminal/supports-hyperlinks.js +72 -31
  63. package/dist/terminal/table/layout-manager.d.ts +0 -20
  64. package/dist/terminal/table/layout-manager.d.ts.map +1 -1
  65. package/dist/terminal/table/layout-manager.js +68 -44
  66. package/dist/terminal/table/utils.d.ts +0 -1
  67. package/dist/terminal/table/utils.d.ts.map +1 -1
  68. package/dist/terminal/table/utils.js +2 -4
  69. package/dist/tools/apply-patch.d.ts +5 -3
  70. package/dist/tools/apply-patch.d.ts.map +1 -1
  71. package/dist/tools/apply-patch.js +154 -123
  72. package/dist/tools/bash.d.ts.map +1 -1
  73. package/dist/tools/bash.js +11 -8
  74. package/dist/tools/dynamic-tool-loader.d.ts +6 -1
  75. package/dist/tools/dynamic-tool-loader.d.ts.map +1 -1
  76. package/dist/tools/dynamic-tool-loader.js +154 -135
  77. package/dist/tools/index.d.ts +3 -133
  78. package/dist/tools/index.d.ts.map +1 -1
  79. package/dist/tools/index.js +0 -20
  80. package/dist/tools/read-file.d.ts.map +1 -1
  81. package/dist/tools/read-file.js +32 -13
  82. package/dist/tools/skill.d.ts.map +1 -1
  83. package/dist/tools/skill.js +20 -13
  84. package/dist/tools/web-fetch.d.ts +2 -6
  85. package/dist/tools/web-fetch.d.ts.map +1 -1
  86. package/dist/tools/web-fetch.js +59 -36
  87. package/dist/tools/web-search.d.ts +0 -4
  88. package/dist/tools/web-search.d.ts.map +1 -1
  89. package/dist/tools/web-search.js +40 -32
  90. package/dist/tui/autocomplete/utils.d.ts +0 -15
  91. package/dist/tui/autocomplete/utils.d.ts.map +1 -1
  92. package/dist/tui/autocomplete/utils.js +0 -85
  93. package/dist/tui/autocomplete.d.ts +1 -1
  94. package/dist/tui/autocomplete.d.ts.map +1 -1
  95. package/dist/tui/autocomplete.js +1 -1
  96. package/dist/tui/components/editor.d.ts +12 -0
  97. package/dist/tui/components/editor.d.ts.map +1 -1
  98. package/dist/tui/components/editor.js +181 -195
  99. package/dist/tui/components/input.d.ts +4 -0
  100. package/dist/tui/components/input.d.ts.map +1 -1
  101. package/dist/tui/components/input.js +33 -31
  102. package/dist/tui/components/markdown.d.ts +30 -0
  103. package/dist/tui/components/markdown.d.ts.map +1 -1
  104. package/dist/tui/components/markdown.js +274 -242
  105. package/dist/tui/components/modal.d.ts.map +1 -1
  106. package/dist/tui/components/modal.js +11 -11
  107. package/dist/tui/components/select-list.d.ts +5 -0
  108. package/dist/tui/components/select-list.d.ts.map +1 -1
  109. package/dist/tui/components/select-list.js +69 -98
  110. package/dist/tui/components/table.d.ts +6 -0
  111. package/dist/tui/components/table.d.ts.map +1 -1
  112. package/dist/tui/components/table.js +61 -52
  113. package/dist/tui/index.d.ts +1 -8
  114. package/dist/tui/index.d.ts.map +1 -1
  115. package/dist/tui/index.js +0 -8
  116. package/dist/tui/tui.d.ts +9 -0
  117. package/dist/tui/tui.d.ts.map +1 -1
  118. package/dist/tui/tui.js +78 -48
  119. package/dist/tui/utils.d.ts +7 -0
  120. package/dist/tui/utils.d.ts.map +1 -1
  121. package/dist/tui/utils.js +117 -53
  122. package/dist/utils/bash.d.ts.map +1 -1
  123. package/dist/utils/bash.js +156 -104
  124. package/dist/utils/command-protection.d.ts +3 -6
  125. package/dist/utils/command-protection.d.ts.map +1 -1
  126. package/dist/utils/command-protection.js +213 -100
  127. package/dist/utils/filesystem/operations.d.ts +0 -15
  128. package/dist/utils/filesystem/operations.d.ts.map +1 -1
  129. package/dist/utils/filesystem/operations.js +1 -38
  130. package/dist/utils/filesystem/security.d.ts.map +1 -1
  131. package/dist/utils/filesystem/security.js +22 -15
  132. package/dist/utils/filetype-detection.d.ts +0 -1
  133. package/dist/utils/filetype-detection.d.ts.map +1 -1
  134. package/dist/utils/filetype-detection.js +0 -12
  135. package/dist/utils/formatting.d.ts +0 -30
  136. package/dist/utils/formatting.d.ts.map +1 -1
  137. package/dist/utils/formatting.js +0 -44
  138. package/dist/utils/git.d.ts +4 -6
  139. package/dist/utils/git.d.ts.map +1 -1
  140. package/dist/utils/git.js +36 -46
  141. package/dist/utils/ignore.d.ts +1 -1
  142. package/dist/utils/ignore.d.ts.map +1 -1
  143. package/dist/utils/ignore.js +1 -1
  144. package/dist/utils/process.d.ts.map +1 -1
  145. package/dist/utils/process.js +77 -79
  146. package/dist/utils/yaml.d.ts +0 -1
  147. package/dist/utils/yaml.d.ts.map +1 -1
  148. package/dist/utils/yaml.js +80 -89
  149. package/dist/utils/zod.d.ts +0 -3
  150. package/dist/utils/zod.d.ts.map +1 -1
  151. package/dist/utils/zod.js +0 -7
  152. package/package.json +25 -24
  153. package/dist/agent/sub-agent.d.ts +0 -23
  154. package/dist/agent/sub-agent.d.ts.map +0 -1
  155. package/dist/agent/sub-agent.js +0 -109
  156. package/dist/commands/add-directory/index.d.ts +0 -3
  157. package/dist/commands/add-directory/index.d.ts.map +0 -1
  158. package/dist/commands/add-directory/index.js +0 -50
  159. package/dist/commands/add-directory/utils.d.ts +0 -3
  160. package/dist/commands/add-directory/utils.d.ts.map +0 -1
  161. package/dist/commands/add-directory/utils.js +0 -15
  162. package/dist/commands/clear/index.d.ts +0 -3
  163. package/dist/commands/clear/index.d.ts.map +0 -1
  164. package/dist/commands/clear/index.js +0 -13
  165. package/dist/commands/generate-rules/index.d.ts +0 -3
  166. package/dist/commands/generate-rules/index.d.ts.map +0 -1
  167. package/dist/commands/generate-rules/index.js +0 -206
  168. package/dist/commands/generate-rules/service.d.ts +0 -22
  169. package/dist/commands/generate-rules/service.d.ts.map +0 -1
  170. package/dist/commands/generate-rules/service.js +0 -103
  171. package/dist/commands/generate-rules/utils.d.ts +0 -5
  172. package/dist/commands/generate-rules/utils.d.ts.map +0 -1
  173. package/dist/commands/generate-rules/utils.js +0 -25
  174. package/dist/commands/handoff/index.d.ts +0 -3
  175. package/dist/commands/handoff/index.d.ts.map +0 -1
  176. package/dist/commands/handoff/index.js +0 -97
  177. package/dist/commands/handoff/utils.d.ts +0 -4
  178. package/dist/commands/handoff/utils.d.ts.map +0 -1
  179. package/dist/commands/handoff/utils.js +0 -123
  180. package/dist/commands/list-directories/index.d.ts +0 -3
  181. package/dist/commands/list-directories/index.d.ts.map +0 -1
  182. package/dist/commands/list-directories/index.js +0 -35
  183. package/dist/commands/pickup/index.d.ts +0 -3
  184. package/dist/commands/pickup/index.d.ts.map +0 -1
  185. package/dist/commands/pickup/index.js +0 -141
  186. package/dist/commands/pickup/types.d.ts +0 -6
  187. package/dist/commands/pickup/types.d.ts.map +0 -1
  188. package/dist/commands/pickup/types.js +0 -1
  189. package/dist/commands/pickup/utils.d.ts +0 -7
  190. package/dist/commands/pickup/utils.d.ts.map +0 -1
  191. package/dist/commands/pickup/utils.js +0 -56
  192. package/dist/commands/remove-directory/index.d.ts +0 -3
  193. package/dist/commands/remove-directory/index.d.ts.map +0 -1
  194. package/dist/commands/remove-directory/index.js +0 -55
  195. package/dist/commands/review/index.d.ts +0 -3
  196. package/dist/commands/review/index.d.ts.map +0 -1
  197. package/dist/commands/review/index.js +0 -12
  198. package/dist/commands/review/review-panel.d.ts +0 -3
  199. package/dist/commands/review/review-panel.d.ts.map +0 -1
  200. package/dist/commands/review/review-panel.js +0 -186
  201. package/dist/commands/review/utils.d.ts +0 -18
  202. package/dist/commands/review/utils.d.ts.map +0 -1
  203. package/dist/commands/review/utils.js +0 -146
  204. package/dist/commands/shell/index.d.ts +0 -3
  205. package/dist/commands/shell/index.d.ts.map +0 -1
  206. package/dist/commands/shell/index.js +0 -96
  207. package/dist/subagents/index.d.ts +0 -16
  208. package/dist/subagents/index.d.ts.map +0 -1
  209. package/dist/subagents/index.js +0 -231
  210. package/dist/terminal/index.d.ts +0 -9
  211. package/dist/terminal/index.d.ts.map +0 -1
  212. package/dist/terminal/index.js +0 -8
  213. package/dist/tools/agent.d.ts +0 -27
  214. package/dist/tools/agent.d.ts.map +0 -1
  215. package/dist/tools/agent.js +0 -81
  216. package/dist/tools/directory-tree.d.ts +0 -28
  217. package/dist/tools/directory-tree.d.ts.map +0 -1
  218. package/dist/tools/directory-tree.js +0 -154
  219. package/dist/tools/glob.d.ts +0 -35
  220. package/dist/tools/glob.d.ts.map +0 -1
  221. package/dist/tools/glob.js +0 -167
  222. package/dist/tools/grep.d.ts +0 -100
  223. package/dist/tools/grep.d.ts.map +0 -1
  224. package/dist/tools/grep.js +0 -608
  225. package/dist/tools/ls.d.ts +0 -26
  226. package/dist/tools/ls.d.ts.map +0 -1
  227. package/dist/tools/ls.js +0 -83
  228. package/dist/tui/components/header.d.ts +0 -21
  229. package/dist/tui/components/header.d.ts.map +0 -1
  230. package/dist/tui/components/header.js +0 -63
  231. package/dist/utils/bash/parse.d.ts +0 -19
  232. package/dist/utils/bash/parse.d.ts.map +0 -1
  233. package/dist/utils/bash/parse.js +0 -223
  234. package/dist/utils/bash/quote.d.ts +0 -6
  235. package/dist/utils/bash/quote.d.ts.map +0 -1
  236. package/dist/utils/bash/quote.js +0 -23
  237. package/dist/utils/generators.d.ts +0 -3
  238. package/dist/utils/generators.d.ts.map +0 -1
  239. package/dist/utils/generators.js +0 -25
  240. package/dist/utils/glob.d.ts +0 -52
  241. package/dist/utils/glob.d.ts.map +0 -1
  242. package/dist/utils/glob.js +0 -376
@@ -1,376 +0,0 @@
1
- import * as fs from "node:fs";
2
- import { readFile } from "node:fs/promises";
3
- import path, * as nodePath from "node:path";
4
- import * as process from "node:process";
5
- import fg from "fast-glob";
6
- import { isDirectory, slash, toPath } from "./filesystem/operations.js";
7
- import { Ignore } from "./ignore.js";
8
- // Cache for ignore patterns to avoid repeated IO
9
- const ignoreCache = new Map();
10
- const CACHE_TTL = 60000; // 1 minute TTL
11
- const assertPatternsInput = (patterns) => {
12
- if (patterns.some((pattern) => typeof pattern !== "string")) {
13
- throw new TypeError("Patterns must be a string or an array of strings");
14
- }
15
- };
16
- // Pre-compiled regexes for performance
17
- const GLOBSTAR_DIRECTORY_REGEX = /\*\*\/([^/]+)$/;
18
- const WILDCARD_CHARS_REGEX = /[*?[\]{}]/;
19
- const EXTENSION_PATTERN_REGEX = /\.[a-zA-Z0-9]{1,5}$/;
20
- const normalizePathForDirectoryGlob = (filePath, cwd) => {
21
- const path = isNegativePattern(filePath) ? filePath.slice(1) : filePath;
22
- return nodePath.isAbsolute(path) ? path : nodePath.join(cwd, path);
23
- };
24
- const shouldExpandGlobstarDirectory = (pattern) => {
25
- const match = pattern?.match(GLOBSTAR_DIRECTORY_REGEX);
26
- if (!match) {
27
- return false;
28
- }
29
- const dirname = match[1];
30
- const hasWildcards = WILDCARD_CHARS_REGEX.test(dirname);
31
- // Only consider it an extension if it looks like a file extension pattern
32
- // (e.g., contains common extension chars and doesn't look like a directory name)
33
- const hasExtension = EXTENSION_PATTERN_REGEX.test(dirname) && !dirname.startsWith(".");
34
- return !hasWildcards && !hasExtension;
35
- };
36
- const getDirectoryGlob = ({ directoryPath, files, extensions, }) => {
37
- const extensionGlob = extensions && extensions.length > 0
38
- ? `.${extensions.length > 1 ? `{${extensions.join(",")}}` : extensions[0]}`
39
- : "";
40
- return files
41
- ? files.map((file) => {
42
- // Don't append extension glob if file already has wildcards, extension, or looks like a pattern
43
- const hasGlobChars = /[*?[\]{}]/.test(file);
44
- const hasExtension = nodePath.extname(file);
45
- const shouldAppendExtension = extensionGlob && !hasGlobChars && !hasExtension;
46
- return nodePath.posix.join(directoryPath, `**/${shouldAppendExtension ? `${file}${extensionGlob}` : file}`);
47
- })
48
- : [
49
- nodePath.posix.join(directoryPath, `**${extensionGlob ? `/*${extensionGlob}` : ""}`),
50
- ];
51
- };
52
- const directoryToGlob = async (directoryPaths, { cwd = process.cwd(), files, extensions, } = {}) => {
53
- const globs = await Promise.all(directoryPaths.map(async (directoryPath) => {
54
- // Check pattern without negative prefix
55
- const checkPattern = isNegativePattern(directoryPath)
56
- ? directoryPath.slice(1)
57
- : directoryPath;
58
- // Expand globstar directory patterns like **/dirname to **/dirname/**
59
- if (shouldExpandGlobstarDirectory(checkPattern)) {
60
- return getDirectoryGlob({ directoryPath, files, extensions });
61
- }
62
- // If pattern contains any glob wildcard, do not stat; leave as-is
63
- if (/[*?[\]{}]/.test(checkPattern)) {
64
- return directoryPath;
65
- }
66
- // Original logic for checking actual directories
67
- const pathToCheck = normalizePathForDirectoryGlob(directoryPath, cwd);
68
- return (await isDirectory(pathToCheck))
69
- ? getDirectoryGlob({ directoryPath, files, extensions })
70
- : directoryPath;
71
- }));
72
- return globs.flat();
73
- };
74
- const toPatternsArray = (patterns) => {
75
- const flattenedPatterns = Array.from(new Set([patterns].flat()));
76
- assertPatternsInput(flattenedPatterns);
77
- return flattenedPatterns;
78
- };
79
- const checkCwdOption = (cwd) => {
80
- if (!cwd) {
81
- return;
82
- }
83
- let stat;
84
- try {
85
- stat = fs.statSync(cwd);
86
- }
87
- catch (_error) {
88
- throw new Error(`The \`cwd\` option must point to an existing directory: ${cwd}`);
89
- }
90
- if (!stat.isDirectory()) {
91
- throw new Error("The `cwd` option must be a path to a directory");
92
- }
93
- };
94
- const normalizeOptions = (options = {}) => {
95
- const resolvedCwd = options.cwd ? toPath(options.cwd) : undefined;
96
- const normalizedOptions = {
97
- ...options,
98
- ignore: options.ignore ?? [],
99
- expandDirectories: options.expandDirectories ?? true,
100
- cwd: resolvedCwd,
101
- };
102
- if (resolvedCwd) {
103
- checkCwdOption(resolvedCwd);
104
- }
105
- return normalizedOptions;
106
- };
107
- const normalizeArguments = (fn) => (patterns, options) => fn(toPatternsArray(patterns), normalizeOptions(options || {}));
108
- const getIgnoreFilesPatterns = (options) => {
109
- const { ignoreFiles, gitignore } = options;
110
- const patterns = ignoreFiles ? toPatternsArray(ignoreFiles) : [];
111
- if (gitignore) {
112
- patterns.push(GITIGNORE_FILES_PATTERN);
113
- }
114
- return patterns;
115
- };
116
- const getFilter = async (options) => {
117
- const ignoreFilesPatterns = getIgnoreFilesPatterns(options);
118
- const isIgnoredFn = ignoreFilesPatterns.length > 0
119
- ? await isIgnoredByIgnoreFiles(ignoreFilesPatterns, options)
120
- : false;
121
- return createFilterFunction(isIgnoredFn);
122
- };
123
- // No-op predicate for when no ignore filtering is needed
124
- const noOpPredicate = () => false;
125
- const createFilterFunction = (isIgnored) => {
126
- const seen = new Set();
127
- const ignorePredicate = isIgnored === false ? noOpPredicate : isIgnored;
128
- return (fastGlobResult) => {
129
- let pathKey;
130
- if (typeof fastGlobResult === "string") {
131
- pathKey = fastGlobResult;
132
- }
133
- else {
134
- const entry = fastGlobResult;
135
- if (!entry.path) {
136
- // Entry without path is invalid - skip it
137
- return false;
138
- }
139
- pathKey = entry.path;
140
- }
141
- // Normalize to POSIX for consistent cross-platform behavior
142
- pathKey = slash(nodePath.normalize(pathKey));
143
- if (seen.has(pathKey) || ignorePredicate(pathKey)) {
144
- return false;
145
- }
146
- seen.add(pathKey);
147
- return true;
148
- };
149
- };
150
- const unionFastGlobResults = (results, filter) => results.flat().filter((fastGlobResult) => filter(fastGlobResult));
151
- const convertNegativePatterns = (patterns, options) => {
152
- const tasks = [];
153
- let localPatterns = patterns;
154
- while (localPatterns.length > 0) {
155
- const index = localPatterns.findIndex((pattern) => isNegativePattern(pattern));
156
- if (index === -1) {
157
- tasks.push({ patterns: localPatterns, options });
158
- break;
159
- }
160
- const ignorePattern = localPatterns[index].slice(1);
161
- // Create immutable copies for all existing tasks
162
- for (let i = 0; i < tasks.length; i++) {
163
- tasks[i] = {
164
- ...tasks[i],
165
- options: {
166
- ...tasks[i].options,
167
- ignore: [...(tasks[i].options.ignore ?? []), ignorePattern],
168
- },
169
- };
170
- }
171
- if (index !== 0) {
172
- tasks.push({
173
- patterns: localPatterns.slice(0, index),
174
- options: {
175
- ...options,
176
- ignore: [...(options.ignore ?? []), ignorePattern],
177
- },
178
- });
179
- }
180
- localPatterns = localPatterns.slice(index + 1);
181
- }
182
- return tasks;
183
- };
184
- const normalizeExpandDirectoriesOption = (options, cwd) => {
185
- const result = {};
186
- if (cwd) {
187
- result.cwd = cwd;
188
- }
189
- if (Array.isArray(options)) {
190
- result.files = options;
191
- }
192
- else if (typeof options === "object" && options !== null) {
193
- if ("files" in options)
194
- result.files = options.files;
195
- if ("extensions" in options)
196
- result.extensions = options.extensions;
197
- }
198
- return result;
199
- };
200
- const generateTasks = async (patterns, options) => {
201
- const globTasks = convertNegativePatterns(patterns, options);
202
- const { cwd, expandDirectories } = options;
203
- if (!expandDirectories) {
204
- return globTasks;
205
- }
206
- const directoryToGlobOptions = normalizeExpandDirectoriesOption(expandDirectories, cwd ? toPath(cwd) : cwd);
207
- return Promise.all(globTasks.map(async (task) => {
208
- let { patterns, options } = task;
209
- [patterns, options.ignore] = await Promise.all([
210
- directoryToGlob(patterns, directoryToGlobOptions),
211
- directoryToGlob(options.ignore, {
212
- cwd: cwd ? toPath(cwd) : cwd,
213
- }),
214
- ]);
215
- return { patterns, options };
216
- }));
217
- };
218
- /**
219
- * Find files and directories using glob patterns.
220
- *
221
- * Note that glob patterns can only contain forward-slashes, not backward-slashes, so if you want to construct a glob pattern from path components, you need to use `path.posix.join()` instead of `path.join()`.
222
- *
223
- * @param patterns - See the supported [glob patterns](https://github.com/sindresorhus/globby#globbing-patterns).
224
- * @param options - See the [`fast-glob` options](https://github.com/mrmlnc/fast-glob#options-3) in addition to the ones in this package.
225
- * @returns The matching paths.
226
- */
227
- export const glob = normalizeArguments(async (patterns, options) => {
228
- const [tasks, filter] = await Promise.all([
229
- generateTasks(patterns, options),
230
- getFilter(options),
231
- ]);
232
- const results = await Promise.all(tasks.map((task) => fg(task.patterns, convertOptionsForFastGlob(task.options))));
233
- return unionFastGlobResults(results, filter);
234
- });
235
- // Helper function to convert our Options to fast-glob compatible options
236
- const convertOptionsForFastGlob = (options) => {
237
- const { cwd, ...rest } = options;
238
- return {
239
- ...rest,
240
- cwd: cwd ? toPath(cwd) : undefined,
241
- };
242
- };
243
- const defaultIgnoredDirectories = [
244
- "**/node_modules",
245
- "**/flow-typed",
246
- "**/coverage",
247
- "**/.git",
248
- ];
249
- const ignoreFilesGlobOptions = {
250
- absolute: true,
251
- dot: true,
252
- };
253
- const GITIGNORE_FILES_PATTERN = "**/.gitignore";
254
- // Apply base path to gitignore patterns based on .gitignore spec 2.22.1
255
- // https://git-scm.com/docs/gitignore#_pattern_format
256
- // See also https://github.com/sindresorhus/globby/issues/146
257
- const applyBaseToPattern = (pattern, base) => {
258
- if (!base) {
259
- return pattern;
260
- }
261
- const isNegative = isNegativePattern(pattern);
262
- const cleanPattern = isNegative ? pattern.slice(1) : pattern;
263
- // Check if pattern has non-trailing slashes
264
- const slashIndex = cleanPattern.indexOf("/");
265
- const hasNonTrailingSlash = slashIndex !== -1 && slashIndex !== cleanPattern.length - 1;
266
- let result;
267
- if (!hasNonTrailingSlash) {
268
- // "If there is no separator at the beginning or middle of the pattern,
269
- // then the pattern may also match at any level below the .gitignore level."
270
- // So patterns like '*.log' or 'temp' or 'build/' (trailing slash) match recursively.
271
- result = path.posix.join(base, "**", cleanPattern);
272
- }
273
- else if (cleanPattern.startsWith("/")) {
274
- // "If there is a separator at the beginning [...] of the pattern,
275
- // then the pattern is relative to the directory level of the particular .gitignore file itself."
276
- // Leading slash anchors the pattern to the .gitignore's directory.
277
- result = path.posix.join(base, cleanPattern.slice(1));
278
- }
279
- else {
280
- // "If there is a separator [...] middle [...] of the pattern,
281
- // then the pattern is relative to the directory level of the particular .gitignore file itself."
282
- // Patterns like 'src/foo' are relative to the .gitignore's directory.
283
- result = path.posix.join(base, cleanPattern);
284
- }
285
- return isNegative ? `!${result}` : result;
286
- };
287
- const parseIgnoreFile = (file, cwd) => {
288
- const base = slash(path.relative(cwd, path.dirname(file.filePath)));
289
- const patterns = [];
290
- for (const raw of file.content.split(/\r?\n/)) {
291
- if (raw === "")
292
- continue; // blank line
293
- if (raw.startsWith("#"))
294
- continue; // comment line (only when not escaped)
295
- const line = raw; // preserve escapes like \# and \ for Ignore engine
296
- patterns.push(applyBaseToPattern(line, base));
297
- }
298
- return patterns;
299
- };
300
- const toRelativePath = (fileOrDirectory, cwd) => {
301
- const abs = path.isAbsolute(fileOrDirectory)
302
- ? fileOrDirectory
303
- : path.resolve(cwd, fileOrDirectory);
304
- const rel = path.relative(cwd, abs);
305
- if (rel.startsWith("..") || path.isAbsolute(rel))
306
- return undefined;
307
- return rel.startsWith("./") ? rel.slice(2) : rel;
308
- };
309
- const getIsIgnoredPredicate = (files, cwd) => {
310
- // Sort files by path depth (ascending) so deeper .gitignore files override shallower ones
311
- const sortedFiles = [...files].sort((a, b) => {
312
- const depthA = a.filePath.split(nodePath.sep).length;
313
- const depthB = b.filePath.split(nodePath.sep).length;
314
- return depthA - depthB;
315
- });
316
- // Generate cache key using file paths + content hash
317
- const hashString = (s) => {
318
- // FNV-1a 32-bit
319
- let h = 0x811c9dc5;
320
- for (let i = 0; i < s.length; i++) {
321
- h ^= s.charCodeAt(i);
322
- h += (h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24);
323
- }
324
- // force to uint32 and hex
325
- return (h >>> 0).toString(16);
326
- };
327
- const cacheKey = `${cwd}|` +
328
- sortedFiles.map((f) => `${f.filePath}:${hashString(f.content)}`).join("|");
329
- const now = Date.now();
330
- const cached = ignoreCache.get(cacheKey);
331
- let patterns;
332
- if (cached && now - cached.timestamp < CACHE_TTL) {
333
- patterns = cached.patterns;
334
- }
335
- else {
336
- patterns = sortedFiles.flatMap((file) => parseIgnoreFile(file, cwd));
337
- ignoreCache.set(cacheKey, { patterns, timestamp: now });
338
- }
339
- const ignoreInstance = new Ignore().add(patterns);
340
- return (fileOrDirectory) => {
341
- let fileOrDirectoryAsPath = toPath(fileOrDirectory);
342
- fileOrDirectoryAsPath = toRelativePath(fileOrDirectoryAsPath, cwd);
343
- // If path is outside cwd (undefined), it can't be ignored by patterns in cwd
344
- if (fileOrDirectoryAsPath === undefined) {
345
- return false;
346
- }
347
- return fileOrDirectoryAsPath
348
- ? ignoreInstance.ignores(slash(fileOrDirectoryAsPath))
349
- : false;
350
- };
351
- };
352
- const normalizeIgnoreOptions = (options = {}) => ({
353
- cwd: options.cwd ? toPath(options.cwd) : process.cwd(),
354
- suppressErrors: Boolean(options.suppressErrors),
355
- deep: typeof options.deep === "number" ? options.deep : Number.POSITIVE_INFINITY,
356
- ignore: [...(options.ignore ?? []), ...defaultIgnoredDirectories],
357
- });
358
- const isIgnoredByIgnoreFiles = async (patterns, options) => {
359
- const { cwd, suppressErrors, deep, ignore } = normalizeIgnoreOptions(options);
360
- const paths = await fg(patterns, {
361
- cwd,
362
- suppressErrors,
363
- deep,
364
- ignore: ignore,
365
- ...ignoreFilesGlobOptions,
366
- });
367
- const files = await Promise.all(paths.map(async (filePath) => ({
368
- filePath,
369
- content: await readFile(filePath, "utf8"),
370
- })));
371
- return getIsIgnoredPredicate(files, cwd);
372
- };
373
- /**
374
- * Check if a pattern is negative (starts with '!')
375
- */
376
- const isNegativePattern = (pattern) => pattern[0] === "!";