shell-dsl 0.0.9 → 0.0.11

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 (111) hide show
  1. package/dist/cjs/package.json +1 -1
  2. package/dist/cjs/src/commands/awk/awk.cjs +79 -32
  3. package/dist/cjs/src/commands/awk/awk.cjs.map +3 -3
  4. package/dist/cjs/src/commands/cat/cat.cjs +16 -3
  5. package/dist/cjs/src/commands/cat/cat.cjs.map +3 -3
  6. package/dist/cjs/src/commands/colon/colon.cjs +39 -0
  7. package/dist/cjs/src/commands/colon/colon.cjs.map +10 -0
  8. package/dist/cjs/src/commands/cp/cp.cjs +26 -20
  9. package/dist/cjs/src/commands/cp/cp.cjs.map +3 -3
  10. package/dist/cjs/src/commands/echo/echo.cjs +22 -7
  11. package/dist/cjs/src/commands/echo/echo.cjs.map +3 -3
  12. package/dist/cjs/src/commands/grep/grep.cjs +166 -139
  13. package/dist/cjs/src/commands/grep/grep.cjs.map +3 -3
  14. package/dist/cjs/src/commands/head/head.cjs +29 -14
  15. package/dist/cjs/src/commands/head/head.cjs.map +3 -3
  16. package/dist/cjs/src/commands/index.cjs +6 -2
  17. package/dist/cjs/src/commands/index.cjs.map +3 -3
  18. package/dist/cjs/src/commands/ls/ls.cjs +27 -27
  19. package/dist/cjs/src/commands/ls/ls.cjs.map +3 -3
  20. package/dist/cjs/src/commands/mkdir/mkdir.cjs +21 -10
  21. package/dist/cjs/src/commands/mkdir/mkdir.cjs.map +3 -3
  22. package/dist/cjs/src/commands/mv/mv.cjs +22 -15
  23. package/dist/cjs/src/commands/mv/mv.cjs.map +3 -3
  24. package/dist/cjs/src/commands/pwd/pwd.cjs +13 -1
  25. package/dist/cjs/src/commands/pwd/pwd.cjs.map +3 -3
  26. package/dist/cjs/src/commands/rm/rm.cjs +25 -22
  27. package/dist/cjs/src/commands/rm/rm.cjs.map +3 -3
  28. package/dist/cjs/src/commands/sed/sed.cjs +87 -25
  29. package/dist/cjs/src/commands/sed/sed.cjs.map +3 -3
  30. package/dist/cjs/src/commands/sort/sort.cjs +27 -24
  31. package/dist/cjs/src/commands/sort/sort.cjs.map +3 -3
  32. package/dist/cjs/src/commands/tail/tail.cjs +29 -14
  33. package/dist/cjs/src/commands/tail/tail.cjs.map +3 -3
  34. package/dist/cjs/src/commands/tee/tee.cjs +21 -10
  35. package/dist/cjs/src/commands/tee/tee.cjs.map +3 -3
  36. package/dist/cjs/src/commands/touch/touch.cjs +21 -10
  37. package/dist/cjs/src/commands/touch/touch.cjs.map +3 -3
  38. package/dist/cjs/src/commands/tree/tree.cjs +45 -48
  39. package/dist/cjs/src/commands/tree/tree.cjs.map +3 -3
  40. package/dist/cjs/src/commands/uniq/uniq.cjs +27 -24
  41. package/dist/cjs/src/commands/uniq/uniq.cjs.map +3 -3
  42. package/dist/cjs/src/commands/wc/wc.cjs +28 -24
  43. package/dist/cjs/src/commands/wc/wc.cjs.map +3 -3
  44. package/dist/cjs/src/fs/memfs-adapter.cjs +3 -1
  45. package/dist/cjs/src/fs/memfs-adapter.cjs.map +3 -3
  46. package/dist/cjs/src/interpreter/interpreter.cjs +32 -7
  47. package/dist/cjs/src/interpreter/interpreter.cjs.map +3 -3
  48. package/dist/cjs/src/parser/parser.cjs +3 -3
  49. package/dist/cjs/src/parser/parser.cjs.map +3 -3
  50. package/dist/cjs/src/utils/flag-parser.cjs +162 -0
  51. package/dist/cjs/src/utils/flag-parser.cjs.map +10 -0
  52. package/dist/cjs/src/utils/index.cjs +4 -2
  53. package/dist/cjs/src/utils/index.cjs.map +3 -3
  54. package/dist/mjs/package.json +1 -1
  55. package/dist/mjs/src/commands/awk/awk.mjs +79 -32
  56. package/dist/mjs/src/commands/awk/awk.mjs.map +3 -3
  57. package/dist/mjs/src/commands/cat/cat.mjs +16 -3
  58. package/dist/mjs/src/commands/cat/cat.mjs.map +3 -3
  59. package/dist/mjs/src/commands/colon/colon.mjs +9 -0
  60. package/dist/mjs/src/commands/colon/colon.mjs.map +10 -0
  61. package/dist/mjs/src/commands/cp/cp.mjs +26 -20
  62. package/dist/mjs/src/commands/cp/cp.mjs.map +3 -3
  63. package/dist/mjs/src/commands/echo/echo.mjs +22 -7
  64. package/dist/mjs/src/commands/echo/echo.mjs.map +3 -3
  65. package/dist/mjs/src/commands/grep/grep.mjs +166 -139
  66. package/dist/mjs/src/commands/grep/grep.mjs.map +3 -3
  67. package/dist/mjs/src/commands/head/head.mjs +29 -14
  68. package/dist/mjs/src/commands/head/head.mjs.map +3 -3
  69. package/dist/mjs/src/commands/index.mjs +6 -2
  70. package/dist/mjs/src/commands/index.mjs.map +3 -3
  71. package/dist/mjs/src/commands/ls/ls.mjs +27 -27
  72. package/dist/mjs/src/commands/ls/ls.mjs.map +3 -3
  73. package/dist/mjs/src/commands/mkdir/mkdir.mjs +21 -10
  74. package/dist/mjs/src/commands/mkdir/mkdir.mjs.map +3 -3
  75. package/dist/mjs/src/commands/mv/mv.mjs +22 -15
  76. package/dist/mjs/src/commands/mv/mv.mjs.map +3 -3
  77. package/dist/mjs/src/commands/pwd/pwd.mjs +13 -1
  78. package/dist/mjs/src/commands/pwd/pwd.mjs.map +3 -3
  79. package/dist/mjs/src/commands/rm/rm.mjs +25 -22
  80. package/dist/mjs/src/commands/rm/rm.mjs.map +3 -3
  81. package/dist/mjs/src/commands/sed/sed.mjs +87 -25
  82. package/dist/mjs/src/commands/sed/sed.mjs.map +3 -3
  83. package/dist/mjs/src/commands/sort/sort.mjs +27 -24
  84. package/dist/mjs/src/commands/sort/sort.mjs.map +3 -3
  85. package/dist/mjs/src/commands/tail/tail.mjs +29 -14
  86. package/dist/mjs/src/commands/tail/tail.mjs.map +3 -3
  87. package/dist/mjs/src/commands/tee/tee.mjs +21 -10
  88. package/dist/mjs/src/commands/tee/tee.mjs.map +3 -3
  89. package/dist/mjs/src/commands/touch/touch.mjs +21 -10
  90. package/dist/mjs/src/commands/touch/touch.mjs.map +3 -3
  91. package/dist/mjs/src/commands/tree/tree.mjs +45 -48
  92. package/dist/mjs/src/commands/tree/tree.mjs.map +3 -3
  93. package/dist/mjs/src/commands/uniq/uniq.mjs +27 -24
  94. package/dist/mjs/src/commands/uniq/uniq.mjs.map +3 -3
  95. package/dist/mjs/src/commands/wc/wc.mjs +28 -24
  96. package/dist/mjs/src/commands/wc/wc.mjs.map +3 -3
  97. package/dist/mjs/src/fs/memfs-adapter.mjs +3 -1
  98. package/dist/mjs/src/fs/memfs-adapter.mjs.map +3 -3
  99. package/dist/mjs/src/interpreter/interpreter.mjs +32 -7
  100. package/dist/mjs/src/interpreter/interpreter.mjs.map +3 -3
  101. package/dist/mjs/src/parser/parser.mjs +3 -3
  102. package/dist/mjs/src/parser/parser.mjs.map +3 -3
  103. package/dist/mjs/src/utils/flag-parser.mjs +132 -0
  104. package/dist/mjs/src/utils/flag-parser.mjs.map +10 -0
  105. package/dist/mjs/src/utils/index.mjs +6 -2
  106. package/dist/mjs/src/utils/index.mjs.map +3 -3
  107. package/dist/types/src/commands/colon/colon.d.ts +2 -0
  108. package/dist/types/src/commands/index.d.ts +1 -0
  109. package/dist/types/src/utils/flag-parser.d.ts +36 -0
  110. package/dist/types/src/utils/index.d.ts +1 -0
  111. package/package.json +1 -1
@@ -32,8 +32,38 @@ __export(exports_grep, {
32
32
  grep: () => grep
33
33
  });
34
34
  module.exports = __toCommonJS(exports_grep);
35
- function parseArgs(args) {
36
- const options = {
35
+ var import_flag_parser = require("../../utils/flag-parser.cjs");
36
+ var spec = {
37
+ name: "grep",
38
+ flags: [
39
+ { short: "E", long: "extended-regexp" },
40
+ { short: "F", long: "fixed-strings" },
41
+ { short: "i", long: "ignore-case" },
42
+ { short: "w", long: "word-regexp" },
43
+ { short: "x", long: "line-regexp" },
44
+ { short: "v", long: "invert-match" },
45
+ { short: "c", long: "count" },
46
+ { short: "l", long: "files-with-matches" },
47
+ { short: "L", long: "files-without-match" },
48
+ { short: "n", long: "line-number" },
49
+ { short: "o", long: "only-matching" },
50
+ { short: "q", long: "quiet" },
51
+ { short: "H", long: "with-filename" },
52
+ { short: "h", long: "no-filename" },
53
+ { short: "r", long: "recursive" },
54
+ { short: "R" },
55
+ { short: "e", long: "regexp", takesValue: true },
56
+ { short: "m", long: "max-count", takesValue: true },
57
+ { short: "A", long: "after-context", takesValue: true },
58
+ { short: "B", long: "before-context", takesValue: true },
59
+ { short: "C", long: "context", takesValue: true },
60
+ { long: "include", takesValue: true },
61
+ { long: "exclude", takesValue: true }
62
+ ],
63
+ usage: "grep [-ivnclLqHhEFwxorR] [-e pattern] [-m num] pattern [file ...]"
64
+ };
65
+ function createDefaults() {
66
+ return {
37
67
  patterns: [],
38
68
  extendedRegex: true,
39
69
  fixedStrings: false,
@@ -51,135 +81,104 @@ function parseArgs(args) {
51
81
  showFilename: null,
52
82
  beforeContext: 0,
53
83
  afterContext: 0,
54
- recursive: false
84
+ recursive: false,
85
+ include: [],
86
+ exclude: []
55
87
  };
56
- const files = [];
57
- let pattern;
58
- let i = 0;
59
- while (i < args.length) {
60
- const arg = args[i];
61
- if (arg === "--") {
62
- files.push(...args.slice(i + 1));
88
+ }
89
+ var handler = (flags, flag, value) => {
90
+ switch (flag.short) {
91
+ case "E":
92
+ flags.extendedRegex = true;
63
93
  break;
64
- }
65
- if (arg === "-e" && args[i + 1] !== undefined) {
66
- options.patterns.push(args[i + 1]);
67
- i += 2;
68
- continue;
69
- }
70
- if (arg === "-m" && args[i + 1] !== undefined) {
71
- options.maxMatches = parseInt(args[i + 1], 10);
72
- i += 2;
73
- continue;
74
- }
75
- if (arg.startsWith("-m") && arg.length > 2) {
76
- options.maxMatches = parseInt(arg.slice(2), 10);
77
- i++;
78
- continue;
79
- }
80
- if (arg === "-A" && args[i + 1] !== undefined) {
81
- options.afterContext = parseInt(args[i + 1], 10);
82
- i += 2;
83
- continue;
84
- }
85
- if (arg.startsWith("-A") && arg.length > 2) {
86
- options.afterContext = parseInt(arg.slice(2), 10);
87
- i++;
88
- continue;
89
- }
90
- if (arg === "-B" && args[i + 1] !== undefined) {
91
- options.beforeContext = parseInt(args[i + 1], 10);
92
- i += 2;
93
- continue;
94
- }
95
- if (arg.startsWith("-B") && arg.length > 2) {
96
- options.beforeContext = parseInt(arg.slice(2), 10);
97
- i++;
98
- continue;
99
- }
100
- if (arg === "-C" && args[i + 1] !== undefined) {
101
- const num = parseInt(args[i + 1], 10);
102
- options.beforeContext = num;
103
- options.afterContext = num;
104
- i += 2;
105
- continue;
106
- }
107
- if (arg.startsWith("-C") && arg.length > 2) {
108
- const num = parseInt(arg.slice(2), 10);
109
- options.beforeContext = num;
110
- options.afterContext = num;
111
- i++;
112
- continue;
113
- }
114
- if (arg.startsWith("-") && arg.length > 1 && !arg.startsWith("--")) {
115
- for (const flag of arg.slice(1)) {
116
- switch (flag) {
117
- case "v":
118
- options.invert = true;
119
- break;
120
- case "i":
121
- options.ignoreCase = true;
122
- break;
123
- case "n":
124
- options.showLineNumbers = true;
125
- break;
126
- case "c":
127
- options.countOnly = true;
128
- break;
129
- case "l":
130
- options.filesWithMatches = true;
131
- break;
132
- case "L":
133
- options.filesWithoutMatches = true;
134
- break;
135
- case "q":
136
- options.quiet = true;
137
- break;
138
- case "H":
139
- options.showFilename = true;
140
- break;
141
- case "h":
142
- options.showFilename = false;
143
- break;
144
- case "E":
145
- options.extendedRegex = true;
146
- break;
147
- case "F":
148
- options.fixedStrings = true;
149
- break;
150
- case "w":
151
- options.wholeWord = true;
152
- break;
153
- case "x":
154
- options.wholeLine = true;
155
- break;
156
- case "o":
157
- options.onlyMatching = true;
158
- break;
159
- case "r":
160
- case "R":
161
- options.recursive = true;
162
- break;
163
- }
94
+ case "F":
95
+ flags.fixedStrings = true;
96
+ break;
97
+ case "i":
98
+ flags.ignoreCase = true;
99
+ break;
100
+ case "w":
101
+ flags.wholeWord = true;
102
+ break;
103
+ case "x":
104
+ flags.wholeLine = true;
105
+ break;
106
+ case "v":
107
+ flags.invert = true;
108
+ break;
109
+ case "c":
110
+ flags.countOnly = true;
111
+ break;
112
+ case "l":
113
+ flags.filesWithMatches = true;
114
+ break;
115
+ case "L":
116
+ flags.filesWithoutMatches = true;
117
+ break;
118
+ case "n":
119
+ flags.showLineNumbers = true;
120
+ break;
121
+ case "o":
122
+ flags.onlyMatching = true;
123
+ break;
124
+ case "q":
125
+ flags.quiet = true;
126
+ break;
127
+ case "H":
128
+ flags.showFilename = true;
129
+ break;
130
+ case "h":
131
+ flags.showFilename = false;
132
+ break;
133
+ case "r":
134
+ case "R":
135
+ flags.recursive = true;
136
+ break;
137
+ case "e":
138
+ if (value)
139
+ flags.patterns.push(value);
140
+ break;
141
+ case "m":
142
+ if (value)
143
+ flags.maxMatches = parseInt(value, 10);
144
+ break;
145
+ case "A":
146
+ if (value)
147
+ flags.afterContext = parseInt(value, 10);
148
+ break;
149
+ case "B":
150
+ if (value)
151
+ flags.beforeContext = parseInt(value, 10);
152
+ break;
153
+ case "C":
154
+ if (value) {
155
+ const num = parseInt(value, 10);
156
+ flags.beforeContext = num;
157
+ flags.afterContext = num;
164
158
  }
165
- i++;
166
- continue;
167
- }
168
- if (pattern === undefined && options.patterns.length === 0) {
169
- pattern = arg;
170
- } else {
171
- files.push(arg);
172
- }
173
- i++;
159
+ break;
160
+ default:
161
+ if (flag.long === "include" && value)
162
+ flags.include.push(value);
163
+ else if (flag.long === "exclude" && value)
164
+ flags.exclude.push(value);
165
+ break;
174
166
  }
175
- if (pattern !== undefined) {
176
- if (options.patterns.length === 0) {
177
- options.patterns.push(pattern);
178
- } else {
179
- files.unshift(pattern);
180
- }
167
+ };
168
+ function matchGlob(str, pattern) {
169
+ let re = "^";
170
+ for (const ch of pattern) {
171
+ if (ch === "*")
172
+ re += ".*";
173
+ else if (ch === "?")
174
+ re += ".";
175
+ else if (/[.+^${}()|[\]\\]/.test(ch))
176
+ re += "\\" + ch;
177
+ else
178
+ re += ch;
181
179
  }
182
- return { options, files };
180
+ re += "$";
181
+ return new RegExp(re).test(str);
183
182
  }
184
183
  function escapeRegex(str) {
185
184
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -200,11 +199,25 @@ function buildMatcher(options) {
200
199
  return new RegExp(combined, flags);
201
200
  }
202
201
  var grep = async (ctx) => {
203
- const { options, files } = parseArgs(ctx.args);
202
+ const parser = import_flag_parser.createFlagParser(spec, createDefaults(), handler);
203
+ const result = parser.parse(ctx.args);
204
+ if (result.error) {
205
+ await parser.writeError(result.error, ctx.stderr);
206
+ return 1;
207
+ }
208
+ const options = result.flags;
209
+ const args = result.args;
210
+ let files;
204
211
  if (options.patterns.length === 0) {
205
- await ctx.stderr.writeText(`grep: missing pattern
212
+ if (args.length === 0) {
213
+ await ctx.stderr.writeText(`grep: missing pattern
206
214
  `);
207
- return 1;
215
+ return 1;
216
+ }
217
+ options.patterns.push(args[0]);
218
+ files = args.slice(1);
219
+ } else {
220
+ files = args;
208
221
  }
209
222
  let regex;
210
223
  try {
@@ -243,6 +256,22 @@ var grep = async (ctx) => {
243
256
  expandedFiles.push(path);
244
257
  }
245
258
  }
259
+ if (options.include.length > 0 || options.exclude.length > 0) {
260
+ expandedFiles = expandedFiles.filter((f) => {
261
+ const basename = ctx.fs.basename(f);
262
+ if (options.include.length > 0) {
263
+ const included = options.include.some((pat) => matchGlob(basename, pat));
264
+ if (!included)
265
+ return false;
266
+ }
267
+ if (options.exclude.length > 0) {
268
+ const excluded = options.exclude.some((pat) => matchGlob(basename, pat));
269
+ if (excluded)
270
+ return false;
271
+ }
272
+ return true;
273
+ });
274
+ }
246
275
  if (showFilenames === null) {
247
276
  showFilenames = true;
248
277
  }
@@ -312,8 +341,6 @@ var grep = async (ctx) => {
312
341
  let fileFound = false;
313
342
  let fileMatchCount = 0;
314
343
  let lastPrintedLine = -1;
315
- let needSeparator = false;
316
- let afterRemaining = 0;
317
344
  const matchingLines = new Set;
318
345
  for (let lineIdx = 0;lineIdx < lines.length; lineIdx++) {
319
346
  const line = lines[lineIdx];
@@ -475,27 +502,27 @@ var grep = async (ctx) => {
475
502
  }
476
503
  let hasFilesWithoutMatches = false;
477
504
  if (options.filesWithMatches) {
478
- for (const [filename, result] of perFileResults) {
479
- if (result.found && !options.quiet) {
505
+ for (const [filename, result2] of perFileResults) {
506
+ if (result2.found && !options.quiet) {
480
507
  await ctx.stdout.writeText(filename + `
481
508
  `);
482
509
  }
483
510
  }
484
511
  } else if (options.filesWithoutMatches) {
485
- for (const [filename, result] of perFileResults) {
486
- if (!result.found) {
512
+ for (const [filename, result2] of perFileResults) {
513
+ if (!result2.found) {
487
514
  hasFilesWithoutMatches = true;
488
515
  await ctx.stdout.writeText(filename + `
489
516
  `);
490
517
  }
491
518
  }
492
519
  } else if (options.countOnly && !options.quiet) {
493
- for (const [filename, result] of perFileResults) {
520
+ for (const [filename, result2] of perFileResults) {
494
521
  if (showFilenames) {
495
- await ctx.stdout.writeText(`${filename}:${result.count}
522
+ await ctx.stdout.writeText(`${filename}:${result2.count}
496
523
  `);
497
524
  } else {
498
- await ctx.stdout.writeText(result.count + `
525
+ await ctx.stdout.writeText(result2.count + `
499
526
  `);
500
527
  }
501
528
  }
@@ -507,4 +534,4 @@ var grep = async (ctx) => {
507
534
  return globalFound ? 0 : 1;
508
535
  };
509
536
 
510
- //# debugId=FFCDB5B9AAFA922964756E2164756E21
537
+ //# debugId=E1E2499749A3C23A64756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/commands/grep/grep.ts"],
4
4
  "sourcesContent": [
5
- "import type { Command } from \"../../types.cjs\";\n\ninterface GrepOptions {\n patterns: string[];\n extendedRegex: boolean; // -E (default for JS)\n fixedStrings: boolean; // -F\n ignoreCase: boolean; // -i\n wholeWord: boolean; // -w\n wholeLine: boolean; // -x\n invert: boolean; // -v\n countOnly: boolean; // -c\n filesWithMatches: boolean; // -l\n filesWithoutMatches: boolean; // -L\n showLineNumbers: boolean; // -n\n onlyMatching: boolean; // -o\n quiet: boolean; // -q\n maxMatches: number; // -m (0 = unlimited)\n showFilename: boolean | null; // null=auto, true=-H, false=-h\n beforeContext: number; // -B\n afterContext: number; // -A\n recursive: boolean; // -r/-R\n}\n\nfunction parseArgs(args: string[]): { options: GrepOptions; files: string[] } {\n const options: GrepOptions = {\n patterns: [],\n extendedRegex: true, // JS regex is extended by default\n fixedStrings: false,\n ignoreCase: false,\n wholeWord: false,\n wholeLine: false,\n invert: false,\n countOnly: false,\n filesWithMatches: false,\n filesWithoutMatches: false,\n showLineNumbers: false,\n onlyMatching: false,\n quiet: false,\n maxMatches: 0,\n showFilename: null,\n beforeContext: 0,\n afterContext: 0,\n recursive: false,\n };\n const files: string[] = [];\n let pattern: string | undefined;\n\n let i = 0;\n while (i < args.length) {\n const arg = args[i]!;\n\n // Handle long-form options first\n if (arg === \"--\") {\n // Everything after -- is a file\n files.push(...args.slice(i + 1));\n break;\n }\n\n // Handle -e PATTERN (explicit pattern)\n if (arg === \"-e\" && args[i + 1] !== undefined) {\n options.patterns.push(args[i + 1]!);\n i += 2;\n continue;\n }\n\n // Handle -m NUM (max matches)\n if (arg === \"-m\" && args[i + 1] !== undefined) {\n options.maxMatches = parseInt(args[i + 1]!, 10);\n i += 2;\n continue;\n }\n if (arg.startsWith(\"-m\") && arg.length > 2) {\n options.maxMatches = parseInt(arg.slice(2), 10);\n i++;\n continue;\n }\n\n // Handle -A NUM (after context)\n if (arg === \"-A\" && args[i + 1] !== undefined) {\n options.afterContext = parseInt(args[i + 1]!, 10);\n i += 2;\n continue;\n }\n if (arg.startsWith(\"-A\") && arg.length > 2) {\n options.afterContext = parseInt(arg.slice(2), 10);\n i++;\n continue;\n }\n\n // Handle -B NUM (before context)\n if (arg === \"-B\" && args[i + 1] !== undefined) {\n options.beforeContext = parseInt(args[i + 1]!, 10);\n i += 2;\n continue;\n }\n if (arg.startsWith(\"-B\") && arg.length > 2) {\n options.beforeContext = parseInt(arg.slice(2), 10);\n i++;\n continue;\n }\n\n // Handle -C NUM (context both sides)\n if (arg === \"-C\" && args[i + 1] !== undefined) {\n const num = parseInt(args[i + 1]!, 10);\n options.beforeContext = num;\n options.afterContext = num;\n i += 2;\n continue;\n }\n if (arg.startsWith(\"-C\") && arg.length > 2) {\n const num = parseInt(arg.slice(2), 10);\n options.beforeContext = num;\n options.afterContext = num;\n i++;\n continue;\n }\n\n // Handle combined short flags like -iv, -in, etc.\n if (arg.startsWith(\"-\") && arg.length > 1 && !arg.startsWith(\"--\")) {\n for (const flag of arg.slice(1)) {\n switch (flag) {\n case \"v\": options.invert = true; break;\n case \"i\": options.ignoreCase = true; break;\n case \"n\": options.showLineNumbers = true; break;\n case \"c\": options.countOnly = true; break;\n case \"l\": options.filesWithMatches = true; break;\n case \"L\": options.filesWithoutMatches = true; break;\n case \"q\": options.quiet = true; break;\n case \"H\": options.showFilename = true; break;\n case \"h\": options.showFilename = false; break;\n case \"E\": options.extendedRegex = true; break;\n case \"F\": options.fixedStrings = true; break;\n case \"w\": options.wholeWord = true; break;\n case \"x\": options.wholeLine = true; break;\n case \"o\": options.onlyMatching = true; break;\n case \"r\":\n case \"R\": options.recursive = true; break;\n }\n }\n i++;\n continue;\n }\n\n // Non-flag argument\n if (pattern === undefined && options.patterns.length === 0) {\n pattern = arg;\n } else {\n files.push(arg);\n }\n i++;\n }\n\n // Add the positional pattern if we have one and no -e patterns\n if (pattern !== undefined) {\n if (options.patterns.length === 0) {\n options.patterns.push(pattern);\n } else {\n // If we have -e patterns, the positional arg is actually a file\n files.unshift(pattern);\n }\n }\n\n return { options, files };\n}\n\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction buildMatcher(options: GrepOptions): RegExp {\n let patterns = options.patterns;\n\n // If fixed strings mode, escape regex metacharacters\n if (options.fixedStrings) {\n patterns = patterns.map(escapeRegex);\n }\n\n // Combine multiple patterns with OR\n let combined = patterns.length > 1 ? patterns.map(p => `(?:${p})`).join(\"|\") : patterns[0] || \"\";\n\n // Whole word match\n if (options.wholeWord) {\n combined = `\\\\b(?:${combined})\\\\b`;\n }\n\n // Whole line match\n if (options.wholeLine) {\n combined = `^(?:${combined})$`;\n }\n\n const flags = options.ignoreCase ? \"gi\" : \"g\";\n return new RegExp(combined, flags);\n}\n\ninterface LineInfo {\n text: string;\n lineNum: number;\n isMatch: boolean;\n}\n\nexport const grep: Command = async (ctx) => {\n const { options, files } = parseArgs(ctx.args);\n\n if (options.patterns.length === 0) {\n await ctx.stderr.writeText(\"grep: missing pattern\\n\");\n return 1;\n }\n\n let regex: RegExp;\n try {\n regex = buildMatcher(options);\n } catch (err) {\n await ctx.stderr.writeText(`grep: invalid pattern: ${options.patterns.join(\", \")}\\n`);\n return 1;\n }\n\n let globalFound = false;\n let globalMatchCount = 0;\n let earlyExit = false;\n\n // Determine filename display mode\n let showFilenames = options.showFilename;\n\n // Expand files if recursive\n let expandedFiles = files;\n if (options.recursive && files.length > 0) {\n expandedFiles = [];\n for (const file of files) {\n const path = ctx.fs.resolve(ctx.cwd, file);\n try {\n const stat = await ctx.fs.stat(path);\n if (stat.isDirectory()) {\n // Glob all files in directory\n const globbed = await ctx.fs.glob(\"**/*\", { cwd: path });\n for (const f of globbed) {\n const fullPath = ctx.fs.resolve(path, f);\n try {\n const s = await ctx.fs.stat(fullPath);\n if (s.isFile()) {\n expandedFiles.push(fullPath);\n }\n } catch {\n // Skip if can't stat\n }\n }\n } else {\n expandedFiles.push(path);\n }\n } catch {\n expandedFiles.push(path); // Will error later\n }\n }\n // Default to showing filenames for recursive\n if (showFilenames === null) {\n showFilenames = true;\n }\n }\n\n // Default: show filenames if multiple files\n if (showFilenames === null) {\n showFilenames = expandedFiles.length > 1;\n }\n\n const processContent = async (\n lines: string[],\n filename?: string\n ): Promise<{ found: boolean; count: number }> => {\n let fileFound = false;\n let fileMatchCount = 0;\n\n // For context lines, we need a buffer approach\n const hasContext = options.beforeContext > 0 || options.afterContext > 0;\n\n if (hasContext) {\n return await processWithContext(lines, filename);\n }\n\n for (let lineIdx = 0; lineIdx < lines.length && !earlyExit; lineIdx++) {\n const line = lines[lineIdx]!;\n const lineNum = lineIdx + 1;\n\n // Reset regex lastIndex for each line\n regex.lastIndex = 0;\n const matches = regex.test(line);\n const shouldOutput = options.invert ? !matches : matches;\n\n if (shouldOutput) {\n fileFound = true;\n fileMatchCount++;\n\n // Quiet mode: exit immediately on first match\n if (options.quiet) {\n earlyExit = true;\n return { found: true, count: 1 };\n }\n\n // -l mode: we found a match in this file, stop processing this file\n if (options.filesWithMatches) {\n return { found: true, count: 1 };\n }\n\n // Output the match (unless countOnly or filesWithoutMatches)\n if (!options.countOnly && !options.filesWithoutMatches) {\n if (options.onlyMatching && !options.invert) {\n // Output only the matched parts\n regex.lastIndex = 0;\n let match;\n while ((match = regex.exec(line)) !== null) {\n let output = \"\";\n if (filename && showFilenames) output += filename + \":\";\n if (options.showLineNumbers) output += lineNum + \":\";\n output += match[0] + \"\\n\";\n await ctx.stdout.writeText(output);\n // Prevent infinite loop for zero-width matches\n if (match[0].length === 0) regex.lastIndex++;\n }\n } else {\n let output = \"\";\n if (filename && showFilenames) output += filename + \":\";\n if (options.showLineNumbers) output += lineNum + \":\";\n output += line + \"\\n\";\n await ctx.stdout.writeText(output);\n }\n }\n\n // Check max matches\n if (options.maxMatches > 0 && fileMatchCount >= options.maxMatches) {\n earlyExit = true;\n return { found: true, count: fileMatchCount };\n }\n }\n }\n\n return { found: fileFound, count: fileMatchCount };\n };\n\n const processWithContext = async (\n lines: string[],\n filename?: string\n ): Promise<{ found: boolean; count: number }> => {\n let fileFound = false;\n let fileMatchCount = 0;\n let lastPrintedLine = -1;\n let needSeparator = false;\n let afterRemaining = 0;\n\n // First pass: find all matching lines\n const matchingLines = new Set<number>();\n for (let lineIdx = 0; lineIdx < lines.length; lineIdx++) {\n const line = lines[lineIdx]!;\n regex.lastIndex = 0;\n const matches = regex.test(line);\n const shouldOutput = options.invert ? !matches : matches;\n if (shouldOutput) {\n matchingLines.add(lineIdx);\n }\n }\n\n // Determine which lines to print (matches + context)\n const linesToPrint = new Set<number>();\n for (const matchIdx of matchingLines) {\n // Add before context\n for (let i = Math.max(0, matchIdx - options.beforeContext); i < matchIdx; i++) {\n linesToPrint.add(i);\n }\n // Add the match itself\n linesToPrint.add(matchIdx);\n // Add after context\n for (let i = matchIdx + 1; i <= Math.min(lines.length - 1, matchIdx + options.afterContext); i++) {\n linesToPrint.add(i);\n }\n }\n\n // Sort and print\n const sortedLines = Array.from(linesToPrint).sort((a, b) => a - b);\n\n for (let i = 0; i < sortedLines.length && !earlyExit; i++) {\n const lineIdx = sortedLines[i]!;\n const line = lines[lineIdx]!;\n const lineNum = lineIdx + 1;\n const isMatch = matchingLines.has(lineIdx);\n\n // Print separator if there's a gap\n if (lastPrintedLine >= 0 && lineIdx > lastPrintedLine + 1) {\n await ctx.stdout.writeText(\"--\\n\");\n }\n\n if (isMatch) {\n fileFound = true;\n fileMatchCount++;\n\n if (options.quiet) {\n earlyExit = true;\n return { found: true, count: 1 };\n }\n\n if (options.filesWithMatches) {\n return { found: true, count: 1 };\n }\n\n if (!options.countOnly && !options.filesWithoutMatches) {\n if (options.onlyMatching && !options.invert) {\n regex.lastIndex = 0;\n let match;\n while ((match = regex.exec(line)) !== null) {\n let output = \"\";\n if (filename && showFilenames) output += filename + \":\";\n if (options.showLineNumbers) output += lineNum + \":\";\n output += match[0] + \"\\n\";\n await ctx.stdout.writeText(output);\n if (match[0].length === 0) regex.lastIndex++;\n }\n } else {\n let output = \"\";\n if (filename && showFilenames) output += filename + \":\";\n if (options.showLineNumbers) output += lineNum + \":\";\n output += line + \"\\n\";\n await ctx.stdout.writeText(output);\n }\n }\n\n if (options.maxMatches > 0 && fileMatchCount >= options.maxMatches) {\n // Still need to output remaining context lines after this match\n // Continue to output context but mark we should stop looking for more matches\n const remainingContextLines = sortedLines.slice(i + 1).filter(idx => !matchingLines.has(idx));\n for (const contextIdx of remainingContextLines) {\n const contextLine = lines[contextIdx]!;\n const contextLineNum = contextIdx + 1;\n // Check if it's within after-context of current match\n if (contextIdx <= lineIdx + options.afterContext) {\n if (lastPrintedLine >= 0 && contextIdx > lastPrintedLine + 1) {\n await ctx.stdout.writeText(\"--\\n\");\n }\n if (!options.countOnly && !options.filesWithoutMatches) {\n let output = \"\";\n if (filename && showFilenames) output += filename + \"-\";\n if (options.showLineNumbers) output += contextLineNum + \"-\";\n output += contextLine + \"\\n\";\n await ctx.stdout.writeText(output);\n }\n lastPrintedLine = contextIdx;\n }\n }\n earlyExit = true;\n return { found: true, count: fileMatchCount };\n }\n } else {\n // Context line\n if (!options.countOnly && !options.filesWithoutMatches) {\n let output = \"\";\n if (filename && showFilenames) output += filename + \"-\";\n if (options.showLineNumbers) output += lineNum + \"-\";\n output += line + \"\\n\";\n await ctx.stdout.writeText(output);\n }\n }\n\n lastPrintedLine = lineIdx;\n }\n\n return { found: fileFound, count: fileMatchCount };\n };\n\n if (expandedFiles.length === 0) {\n // Read from stdin\n const content = await ctx.stdin.text();\n const lines = content.split(\"\\n\");\n // Remove trailing empty line if content ends with newline\n if (lines.length > 0 && lines[lines.length - 1] === \"\") {\n lines.pop();\n }\n\n const { found, count } = await processContent(lines);\n globalFound = found;\n globalMatchCount = count;\n\n if (options.countOnly && !options.quiet && !options.filesWithMatches && !options.filesWithoutMatches) {\n await ctx.stdout.writeText(globalMatchCount + \"\\n\");\n }\n } else {\n // Read from files\n const perFileResults: Map<string, { found: boolean; count: number }> = new Map();\n\n for (const file of expandedFiles) {\n if (earlyExit && options.quiet) break;\n\n try {\n const path = file.startsWith(\"/\") ? file : ctx.fs.resolve(ctx.cwd, file);\n const stat = await ctx.fs.stat(path);\n\n if (stat.isDirectory()) {\n if (!options.recursive) {\n await ctx.stderr.writeText(`grep: ${file}: Is a directory\\n`);\n }\n continue;\n }\n\n const content = await ctx.fs.readFile(path);\n const lines = content.toString().split(\"\\n\");\n\n // Remove trailing empty line if file ends with newline\n if (lines.length > 0 && lines[lines.length - 1] === \"\") {\n lines.pop();\n }\n\n // Use original filename for display, not resolved path\n const displayName = files.includes(file) ? file :\n (options.recursive ? path : file);\n\n const { found, count } = await processContent(lines, displayName);\n perFileResults.set(displayName, { found, count });\n\n if (found) {\n globalFound = true;\n globalMatchCount += count;\n }\n } catch (err) {\n await ctx.stderr.writeText(`grep: ${file}: No such file or directory\\n`);\n // Continue to other files instead of immediately returning\n if (expandedFiles.length === 1) {\n return 1;\n }\n }\n }\n\n // Handle -l, -L, -c output modes\n let hasFilesWithoutMatches = false;\n if (options.filesWithMatches) {\n for (const [filename, result] of perFileResults) {\n if (result.found && !options.quiet) {\n await ctx.stdout.writeText(filename + \"\\n\");\n }\n }\n } else if (options.filesWithoutMatches) {\n for (const [filename, result] of perFileResults) {\n if (!result.found) {\n hasFilesWithoutMatches = true;\n await ctx.stdout.writeText(filename + \"\\n\");\n }\n }\n } else if (options.countOnly && !options.quiet) {\n for (const [filename, result] of perFileResults) {\n if (showFilenames) {\n await ctx.stdout.writeText(`${filename}:${result.count}\\n`);\n } else {\n await ctx.stdout.writeText(result.count + \"\\n\");\n }\n }\n }\n\n // Determine exit code for file processing\n if (options.filesWithoutMatches) {\n // -L: success if any file had NO matches\n return hasFilesWithoutMatches ? 0 : 1;\n }\n }\n\n // Determine exit code\n return globalFound ? 0 : 1;\n};\n"
5
+ "import type { Command } from \"../../types.cjs\";\nimport { createFlagParser, type FlagDefinition, type FlagError } from \"../../utils/flag-parser.cjs\";\n\ninterface GrepOptions {\n patterns: string[];\n extendedRegex: boolean; // -E (default for JS)\n fixedStrings: boolean; // -F\n ignoreCase: boolean; // -i\n wholeWord: boolean; // -w\n wholeLine: boolean; // -x\n invert: boolean; // -v\n countOnly: boolean; // -c\n filesWithMatches: boolean; // -l\n filesWithoutMatches: boolean; // -L\n showLineNumbers: boolean; // -n\n onlyMatching: boolean; // -o\n quiet: boolean; // -q\n maxMatches: number; // -m (0 = unlimited)\n showFilename: boolean | null; // null=auto, true=-H, false=-h\n beforeContext: number; // -B\n afterContext: number; // -A\n recursive: boolean; // -r/-R\n include: string[]; // --include\n exclude: string[]; // --exclude\n}\n\nconst spec = {\n name: \"grep\",\n flags: [\n { short: \"E\", long: \"extended-regexp\" },\n { short: \"F\", long: \"fixed-strings\" },\n { short: \"i\", long: \"ignore-case\" },\n { short: \"w\", long: \"word-regexp\" },\n { short: \"x\", long: \"line-regexp\" },\n { short: \"v\", long: \"invert-match\" },\n { short: \"c\", long: \"count\" },\n { short: \"l\", long: \"files-with-matches\" },\n { short: \"L\", long: \"files-without-match\" },\n { short: \"n\", long: \"line-number\" },\n { short: \"o\", long: \"only-matching\" },\n { short: \"q\", long: \"quiet\" },\n { short: \"H\", long: \"with-filename\" },\n { short: \"h\", long: \"no-filename\" },\n { short: \"r\", long: \"recursive\" },\n { short: \"R\" },\n { short: \"e\", long: \"regexp\", takesValue: true },\n { short: \"m\", long: \"max-count\", takesValue: true },\n { short: \"A\", long: \"after-context\", takesValue: true },\n { short: \"B\", long: \"before-context\", takesValue: true },\n { short: \"C\", long: \"context\", takesValue: true },\n { long: \"include\", takesValue: true },\n { long: \"exclude\", takesValue: true },\n ] as FlagDefinition[],\n usage: \"grep [-ivnclLqHhEFwxorR] [-e pattern] [-m num] pattern [file ...]\",\n};\n\nfunction createDefaults(): GrepOptions {\n return {\n patterns: [],\n extendedRegex: true, // JS regex is extended by default\n fixedStrings: false,\n ignoreCase: false,\n wholeWord: false,\n wholeLine: false,\n invert: false,\n countOnly: false,\n filesWithMatches: false,\n filesWithoutMatches: false,\n showLineNumbers: false,\n onlyMatching: false,\n quiet: false,\n maxMatches: 0,\n showFilename: null,\n beforeContext: 0,\n afterContext: 0,\n recursive: false,\n include: [],\n exclude: [],\n };\n}\n\nconst handler = (flags: GrepOptions, flag: FlagDefinition, value?: string) => {\n switch (flag.short) {\n case \"E\": flags.extendedRegex = true; break;\n case \"F\": flags.fixedStrings = true; break;\n case \"i\": flags.ignoreCase = true; break;\n case \"w\": flags.wholeWord = true; break;\n case \"x\": flags.wholeLine = true; break;\n case \"v\": flags.invert = true; break;\n case \"c\": flags.countOnly = true; break;\n case \"l\": flags.filesWithMatches = true; break;\n case \"L\": flags.filesWithoutMatches = true; break;\n case \"n\": flags.showLineNumbers = true; break;\n case \"o\": flags.onlyMatching = true; break;\n case \"q\": flags.quiet = true; break;\n case \"H\": flags.showFilename = true; break;\n case \"h\": flags.showFilename = false; break;\n case \"r\":\n case \"R\": flags.recursive = true; break;\n case \"e\": if (value) flags.patterns.push(value); break;\n case \"m\": if (value) flags.maxMatches = parseInt(value, 10); break;\n case \"A\": if (value) flags.afterContext = parseInt(value, 10); break;\n case \"B\": if (value) flags.beforeContext = parseInt(value, 10); break;\n case \"C\":\n if (value) {\n const num = parseInt(value, 10);\n flags.beforeContext = num;\n flags.afterContext = num;\n }\n break;\n default:\n // Handle long-only flags\n if (flag.long === \"include\" && value) flags.include.push(value);\n else if (flag.long === \"exclude\" && value) flags.exclude.push(value);\n break;\n }\n};\n\nfunction matchGlob(str: string, pattern: string): boolean {\n // Convert shell glob to regex: * -> .*, ? -> ., rest escaped\n let re = \"^\";\n for (const ch of pattern) {\n if (ch === \"*\") re += \".*\";\n else if (ch === \"?\") re += \".\";\n else if (/[.+^${}()|[\\]\\\\]/.test(ch)) re += \"\\\\\" + ch;\n else re += ch;\n }\n re += \"$\";\n return new RegExp(re).test(str);\n}\n\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction buildMatcher(options: GrepOptions): RegExp {\n let patterns = options.patterns;\n\n // If fixed strings mode, escape regex metacharacters\n if (options.fixedStrings) {\n patterns = patterns.map(escapeRegex);\n }\n\n // Combine multiple patterns with OR\n let combined = patterns.length > 1 ? patterns.map(p => `(?:${p})`).join(\"|\") : patterns[0] || \"\";\n\n // Whole word match\n if (options.wholeWord) {\n combined = `\\\\b(?:${combined})\\\\b`;\n }\n\n // Whole line match\n if (options.wholeLine) {\n combined = `^(?:${combined})$`;\n }\n\n const flags = options.ignoreCase ? \"gi\" : \"g\";\n return new RegExp(combined, flags);\n}\n\nexport const grep: Command = async (ctx) => {\n // Create fresh parser with fresh defaults for each invocation\n const parser = createFlagParser(spec, createDefaults(), handler);\n const result = parser.parse(ctx.args);\n\n if (result.error) {\n await parser.writeError(result.error, ctx.stderr);\n return 1;\n }\n\n const options = result.flags;\n const args = result.args;\n\n // First positional arg is pattern if no -e patterns\n let files: string[];\n if (options.patterns.length === 0) {\n if (args.length === 0) {\n await ctx.stderr.writeText(\"grep: missing pattern\\n\");\n return 1;\n }\n options.patterns.push(args[0]!);\n files = args.slice(1);\n } else {\n files = args;\n }\n\n let regex: RegExp;\n try {\n regex = buildMatcher(options);\n } catch (err) {\n await ctx.stderr.writeText(`grep: invalid pattern: ${options.patterns.join(\", \")}\\n`);\n return 1;\n }\n\n let globalFound = false;\n let globalMatchCount = 0;\n let earlyExit = false;\n\n // Determine filename display mode\n let showFilenames = options.showFilename;\n\n // Expand files if recursive\n let expandedFiles = files;\n if (options.recursive && files.length > 0) {\n expandedFiles = [];\n for (const file of files) {\n const path = ctx.fs.resolve(ctx.cwd, file);\n try {\n const stat = await ctx.fs.stat(path);\n if (stat.isDirectory()) {\n // Glob all files in directory\n const globbed = await ctx.fs.glob(\"**/*\", { cwd: path });\n for (const f of globbed) {\n const fullPath = ctx.fs.resolve(path, f);\n try {\n const s = await ctx.fs.stat(fullPath);\n if (s.isFile()) {\n expandedFiles.push(fullPath);\n }\n } catch {\n // Skip if can't stat\n }\n }\n } else {\n expandedFiles.push(path);\n }\n } catch {\n expandedFiles.push(path); // Will error later\n }\n }\n // Filter by include/exclude patterns\n if (options.include.length > 0 || options.exclude.length > 0) {\n expandedFiles = expandedFiles.filter((f) => {\n const basename = ctx.fs.basename(f);\n if (options.include.length > 0) {\n const included = options.include.some((pat) => matchGlob(basename, pat));\n if (!included) return false;\n }\n if (options.exclude.length > 0) {\n const excluded = options.exclude.some((pat) => matchGlob(basename, pat));\n if (excluded) return false;\n }\n return true;\n });\n }\n\n // Default to showing filenames for recursive\n if (showFilenames === null) {\n showFilenames = true;\n }\n }\n\n // Default: show filenames if multiple files\n if (showFilenames === null) {\n showFilenames = expandedFiles.length > 1;\n }\n\n const processContent = async (\n lines: string[],\n filename?: string\n ): Promise<{ found: boolean; count: number }> => {\n let fileFound = false;\n let fileMatchCount = 0;\n\n // For context lines, we need a buffer approach\n const hasContext = options.beforeContext > 0 || options.afterContext > 0;\n\n if (hasContext) {\n return await processWithContext(lines, filename);\n }\n\n for (let lineIdx = 0; lineIdx < lines.length && !earlyExit; lineIdx++) {\n const line = lines[lineIdx]!;\n const lineNum = lineIdx + 1;\n\n // Reset regex lastIndex for each line\n regex.lastIndex = 0;\n const matches = regex.test(line);\n const shouldOutput = options.invert ? !matches : matches;\n\n if (shouldOutput) {\n fileFound = true;\n fileMatchCount++;\n\n // Quiet mode: exit immediately on first match\n if (options.quiet) {\n earlyExit = true;\n return { found: true, count: 1 };\n }\n\n // -l mode: we found a match in this file, stop processing this file\n if (options.filesWithMatches) {\n return { found: true, count: 1 };\n }\n\n // Output the match (unless countOnly or filesWithoutMatches)\n if (!options.countOnly && !options.filesWithoutMatches) {\n if (options.onlyMatching && !options.invert) {\n // Output only the matched parts\n regex.lastIndex = 0;\n let match;\n while ((match = regex.exec(line)) !== null) {\n let output = \"\";\n if (filename && showFilenames) output += filename + \":\";\n if (options.showLineNumbers) output += lineNum + \":\";\n output += match[0] + \"\\n\";\n await ctx.stdout.writeText(output);\n // Prevent infinite loop for zero-width matches\n if (match[0].length === 0) regex.lastIndex++;\n }\n } else {\n let output = \"\";\n if (filename && showFilenames) output += filename + \":\";\n if (options.showLineNumbers) output += lineNum + \":\";\n output += line + \"\\n\";\n await ctx.stdout.writeText(output);\n }\n }\n\n // Check max matches\n if (options.maxMatches > 0 && fileMatchCount >= options.maxMatches) {\n earlyExit = true;\n return { found: true, count: fileMatchCount };\n }\n }\n }\n\n return { found: fileFound, count: fileMatchCount };\n };\n\n const processWithContext = async (\n lines: string[],\n filename?: string\n ): Promise<{ found: boolean; count: number }> => {\n let fileFound = false;\n let fileMatchCount = 0;\n let lastPrintedLine = -1;\n\n // First pass: find all matching lines\n const matchingLines = new Set<number>();\n for (let lineIdx = 0; lineIdx < lines.length; lineIdx++) {\n const line = lines[lineIdx]!;\n regex.lastIndex = 0;\n const matches = regex.test(line);\n const shouldOutput = options.invert ? !matches : matches;\n if (shouldOutput) {\n matchingLines.add(lineIdx);\n }\n }\n\n // Determine which lines to print (matches + context)\n const linesToPrint = new Set<number>();\n for (const matchIdx of matchingLines) {\n // Add before context\n for (let i = Math.max(0, matchIdx - options.beforeContext); i < matchIdx; i++) {\n linesToPrint.add(i);\n }\n // Add the match itself\n linesToPrint.add(matchIdx);\n // Add after context\n for (let i = matchIdx + 1; i <= Math.min(lines.length - 1, matchIdx + options.afterContext); i++) {\n linesToPrint.add(i);\n }\n }\n\n // Sort and print\n const sortedLines = Array.from(linesToPrint).sort((a, b) => a - b);\n\n for (let i = 0; i < sortedLines.length && !earlyExit; i++) {\n const lineIdx = sortedLines[i]!;\n const line = lines[lineIdx]!;\n const lineNum = lineIdx + 1;\n const isMatch = matchingLines.has(lineIdx);\n\n // Print separator if there's a gap\n if (lastPrintedLine >= 0 && lineIdx > lastPrintedLine + 1) {\n await ctx.stdout.writeText(\"--\\n\");\n }\n\n if (isMatch) {\n fileFound = true;\n fileMatchCount++;\n\n if (options.quiet) {\n earlyExit = true;\n return { found: true, count: 1 };\n }\n\n if (options.filesWithMatches) {\n return { found: true, count: 1 };\n }\n\n if (!options.countOnly && !options.filesWithoutMatches) {\n if (options.onlyMatching && !options.invert) {\n regex.lastIndex = 0;\n let match;\n while ((match = regex.exec(line)) !== null) {\n let output = \"\";\n if (filename && showFilenames) output += filename + \":\";\n if (options.showLineNumbers) output += lineNum + \":\";\n output += match[0] + \"\\n\";\n await ctx.stdout.writeText(output);\n if (match[0].length === 0) regex.lastIndex++;\n }\n } else {\n let output = \"\";\n if (filename && showFilenames) output += filename + \":\";\n if (options.showLineNumbers) output += lineNum + \":\";\n output += line + \"\\n\";\n await ctx.stdout.writeText(output);\n }\n }\n\n if (options.maxMatches > 0 && fileMatchCount >= options.maxMatches) {\n // Still need to output remaining context lines after this match\n // Continue to output context but mark we should stop looking for more matches\n const remainingContextLines = sortedLines.slice(i + 1).filter(idx => !matchingLines.has(idx));\n for (const contextIdx of remainingContextLines) {\n const contextLine = lines[contextIdx]!;\n const contextLineNum = contextIdx + 1;\n // Check if it's within after-context of current match\n if (contextIdx <= lineIdx + options.afterContext) {\n if (lastPrintedLine >= 0 && contextIdx > lastPrintedLine + 1) {\n await ctx.stdout.writeText(\"--\\n\");\n }\n if (!options.countOnly && !options.filesWithoutMatches) {\n let output = \"\";\n if (filename && showFilenames) output += filename + \"-\";\n if (options.showLineNumbers) output += contextLineNum + \"-\";\n output += contextLine + \"\\n\";\n await ctx.stdout.writeText(output);\n }\n lastPrintedLine = contextIdx;\n }\n }\n earlyExit = true;\n return { found: true, count: fileMatchCount };\n }\n } else {\n // Context line\n if (!options.countOnly && !options.filesWithoutMatches) {\n let output = \"\";\n if (filename && showFilenames) output += filename + \"-\";\n if (options.showLineNumbers) output += lineNum + \"-\";\n output += line + \"\\n\";\n await ctx.stdout.writeText(output);\n }\n }\n\n lastPrintedLine = lineIdx;\n }\n\n return { found: fileFound, count: fileMatchCount };\n };\n\n if (expandedFiles.length === 0) {\n // Read from stdin\n const content = await ctx.stdin.text();\n const lines = content.split(\"\\n\");\n // Remove trailing empty line if content ends with newline\n if (lines.length > 0 && lines[lines.length - 1] === \"\") {\n lines.pop();\n }\n\n const { found, count } = await processContent(lines);\n globalFound = found;\n globalMatchCount = count;\n\n if (options.countOnly && !options.quiet && !options.filesWithMatches && !options.filesWithoutMatches) {\n await ctx.stdout.writeText(globalMatchCount + \"\\n\");\n }\n } else {\n // Read from files\n const perFileResults: Map<string, { found: boolean; count: number }> = new Map();\n\n for (const file of expandedFiles) {\n if (earlyExit && options.quiet) break;\n\n try {\n const path = file.startsWith(\"/\") ? file : ctx.fs.resolve(ctx.cwd, file);\n const stat = await ctx.fs.stat(path);\n\n if (stat.isDirectory()) {\n if (!options.recursive) {\n await ctx.stderr.writeText(`grep: ${file}: Is a directory\\n`);\n }\n continue;\n }\n\n const content = await ctx.fs.readFile(path);\n const lines = content.toString().split(\"\\n\");\n\n // Remove trailing empty line if file ends with newline\n if (lines.length > 0 && lines[lines.length - 1] === \"\") {\n lines.pop();\n }\n\n // Use original filename for display, not resolved path\n const displayName = files.includes(file) ? file :\n (options.recursive ? path : file);\n\n const { found, count } = await processContent(lines, displayName);\n perFileResults.set(displayName, { found, count });\n\n if (found) {\n globalFound = true;\n globalMatchCount += count;\n }\n } catch (err) {\n await ctx.stderr.writeText(`grep: ${file}: No such file or directory\\n`);\n // Continue to other files instead of immediately returning\n if (expandedFiles.length === 1) {\n return 1;\n }\n }\n }\n\n // Handle -l, -L, -c output modes\n let hasFilesWithoutMatches = false;\n if (options.filesWithMatches) {\n for (const [filename, result] of perFileResults) {\n if (result.found && !options.quiet) {\n await ctx.stdout.writeText(filename + \"\\n\");\n }\n }\n } else if (options.filesWithoutMatches) {\n for (const [filename, result] of perFileResults) {\n if (!result.found) {\n hasFilesWithoutMatches = true;\n await ctx.stdout.writeText(filename + \"\\n\");\n }\n }\n } else if (options.countOnly && !options.quiet) {\n for (const [filename, result] of perFileResults) {\n if (showFilenames) {\n await ctx.stdout.writeText(`${filename}:${result.count}\\n`);\n } else {\n await ctx.stdout.writeText(result.count + \"\\n\");\n }\n }\n }\n\n // Determine exit code for file processing\n if (options.filesWithoutMatches) {\n // -L: success if any file had NO matches\n return hasFilesWithoutMatches ? 0 : 1;\n }\n }\n\n // Determine exit code\n return globalFound ? 0 : 1;\n};\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "FFCDB5B9AAFA922964756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "E1E2499749A3C23A64756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -32,22 +32,37 @@ __export(exports_head, {
32
32
  head: () => head
33
33
  });
34
34
  module.exports = __toCommonJS(exports_head);
35
+ var import_flag_parser = require("../../utils/flag-parser.cjs");
36
+ var spec = {
37
+ name: "head",
38
+ flags: [
39
+ { short: "n", long: "lines", takesValue: true }
40
+ ],
41
+ usage: "head [-n lines] [file ...]"
42
+ };
43
+ var defaults = { lines: 10 };
44
+ var handler = (flags, flag, value) => {
45
+ if (flag.short === "n" && value) {
46
+ flags.lines = parseInt(value, 10);
47
+ }
48
+ };
49
+ var parser = import_flag_parser.createFlagParser(spec, defaults, handler);
35
50
  var head = async (ctx) => {
36
- let numLines = 10;
37
- const files = [];
38
- for (let i = 0;i < ctx.args.length; i++) {
39
- const arg = ctx.args[i];
40
- if (arg === "-n" && ctx.args[i + 1]) {
41
- numLines = parseInt(ctx.args[i + 1], 10);
42
- i++;
43
- } else if (arg.startsWith("-n")) {
44
- numLines = parseInt(arg.slice(2), 10);
45
- } else if (arg.startsWith("-") && /^\d+$/.test(arg.slice(1))) {
46
- numLines = parseInt(arg.slice(1), 10);
47
- } else if (!arg.startsWith("-")) {
48
- files.push(arg);
51
+ const processedArgs = [];
52
+ for (const arg of ctx.args) {
53
+ if (arg.startsWith("-") && /^-\d+$/.test(arg)) {
54
+ processedArgs.push("-n", arg.slice(1));
55
+ } else {
56
+ processedArgs.push(arg);
49
57
  }
50
58
  }
59
+ const result = parser.parse(processedArgs);
60
+ if (result.error) {
61
+ await parser.writeError(result.error, ctx.stderr);
62
+ return 1;
63
+ }
64
+ const numLines = result.flags.lines;
65
+ const files = result.args;
51
66
  if (isNaN(numLines) || numLines < 0) {
52
67
  await ctx.stderr.writeText(`head: invalid number of lines
53
68
  `);
@@ -92,4 +107,4 @@ var head = async (ctx) => {
92
107
  return 0;
93
108
  };
94
109
 
95
- //# debugId=3CCE7B78F55717AA64756E2164756E21
110
+ //# debugId=3F50A1766BFF78DF64756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/commands/head/head.ts"],
4
4
  "sourcesContent": [
5
- "import type { Command } from \"../../types.cjs\";\n\nexport const head: Command = async (ctx) => {\n let numLines = 10;\n const files: string[] = [];\n\n // Parse arguments\n for (let i = 0; i < ctx.args.length; i++) {\n const arg = ctx.args[i]!;\n if (arg === \"-n\" && ctx.args[i + 1]) {\n numLines = parseInt(ctx.args[i + 1]!, 10);\n i++;\n } else if (arg.startsWith(\"-n\")) {\n numLines = parseInt(arg.slice(2), 10);\n } else if (arg.startsWith(\"-\") && /^\\d+$/.test(arg.slice(1))) {\n numLines = parseInt(arg.slice(1), 10);\n } else if (!arg.startsWith(\"-\")) {\n files.push(arg);\n }\n }\n\n if (isNaN(numLines) || numLines < 0) {\n await ctx.stderr.writeText(\"head: invalid number of lines\\n\");\n return 1;\n }\n\n const outputLines = async (content: string) => {\n const lines = content.split(\"\\n\");\n const toOutput = lines.slice(0, numLines);\n for (let i = 0; i < toOutput.length; i++) {\n await ctx.stdout.writeText(toOutput[i]!);\n if (i < toOutput.length - 1 || (lines.length > numLines)) {\n await ctx.stdout.writeText(\"\\n\");\n }\n }\n };\n\n if (files.length === 0) {\n // Read from stdin\n const content = await ctx.stdin.text();\n await outputLines(content);\n } else {\n for (let i = 0; i < files.length; i++) {\n const file = files[i]!;\n try {\n if (files.length > 1) {\n if (i > 0) await ctx.stdout.writeText(\"\\n\");\n await ctx.stdout.writeText(`==> ${file} <==\\n`);\n }\n const path = ctx.fs.resolve(ctx.cwd, file);\n const content = (await ctx.fs.readFile(path)).toString();\n await outputLines(content);\n } catch (err) {\n await ctx.stderr.writeText(`head: ${file}: No such file or directory\\n`);\n return 1;\n }\n }\n }\n\n return 0;\n};\n"
5
+ "import type { Command } from \"../../types.cjs\";\nimport { createFlagParser, type FlagDefinition } from \"../../utils/flag-parser.cjs\";\n\ninterface HeadFlags {\n lines: number;\n}\n\nconst spec = {\n name: \"head\",\n flags: [\n { short: \"n\", long: \"lines\", takesValue: true },\n ] as FlagDefinition[],\n usage: \"head [-n lines] [file ...]\",\n};\n\nconst defaults: HeadFlags = { lines: 10 };\n\nconst handler = (flags: HeadFlags, flag: FlagDefinition, value?: string) => {\n if (flag.short === \"n\" && value) {\n flags.lines = parseInt(value, 10);\n }\n};\n\nconst parser = createFlagParser(spec, defaults, handler);\n\nexport const head: Command = async (ctx) => {\n // Pre-process args to handle legacy -N format (e.g., -5 means -n 5)\n const processedArgs: string[] = [];\n for (const arg of ctx.args) {\n if (arg.startsWith(\"-\") && /^-\\d+$/.test(arg)) {\n processedArgs.push(\"-n\", arg.slice(1));\n } else {\n processedArgs.push(arg);\n }\n }\n\n const result = parser.parse(processedArgs);\n\n if (result.error) {\n await parser.writeError(result.error, ctx.stderr);\n return 1;\n }\n\n const numLines = result.flags.lines;\n const files = result.args;\n\n if (isNaN(numLines) || numLines < 0) {\n await ctx.stderr.writeText(\"head: invalid number of lines\\n\");\n return 1;\n }\n\n const outputLines = async (content: string) => {\n const lines = content.split(\"\\n\");\n const toOutput = lines.slice(0, numLines);\n for (let i = 0; i < toOutput.length; i++) {\n await ctx.stdout.writeText(toOutput[i]!);\n if (i < toOutput.length - 1 || (lines.length > numLines)) {\n await ctx.stdout.writeText(\"\\n\");\n }\n }\n };\n\n if (files.length === 0) {\n // Read from stdin\n const content = await ctx.stdin.text();\n await outputLines(content);\n } else {\n for (let i = 0; i < files.length; i++) {\n const file = files[i]!;\n try {\n if (files.length > 1) {\n if (i > 0) await ctx.stdout.writeText(\"\\n\");\n await ctx.stdout.writeText(`==> ${file} <==\\n`);\n }\n const path = ctx.fs.resolve(ctx.cwd, file);\n const content = (await ctx.fs.readFile(path)).toString();\n await outputLines(content);\n } catch (err) {\n await ctx.stderr.writeText(`head: ${file}: No such file or directory\\n`);\n return 1;\n }\n }\n }\n\n return 0;\n};\n"
6
6
  ],
7
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEO,IAAM,OAAgB,OAAO,QAAQ;AAAA,EAC1C,IAAI,WAAW;AAAA,EACf,MAAM,QAAkB,CAAC;AAAA,EAGzB,SAAS,IAAI,EAAG,IAAI,IAAI,KAAK,QAAQ,KAAK;AAAA,IACxC,MAAM,MAAM,IAAI,KAAK;AAAA,IACrB,IAAI,QAAQ,QAAQ,IAAI,KAAK,IAAI,IAAI;AAAA,MACnC,WAAW,SAAS,IAAI,KAAK,IAAI,IAAK,EAAE;AAAA,MACxC;AAAA,IACF,EAAO,SAAI,IAAI,WAAW,IAAI,GAAG;AAAA,MAC/B,WAAW,SAAS,IAAI,MAAM,CAAC,GAAG,EAAE;AAAA,IACtC,EAAO,SAAI,IAAI,WAAW,GAAG,KAAK,QAAQ,KAAK,IAAI,MAAM,CAAC,CAAC,GAAG;AAAA,MAC5D,WAAW,SAAS,IAAI,MAAM,CAAC,GAAG,EAAE;AAAA,IACtC,EAAO,SAAI,CAAC,IAAI,WAAW,GAAG,GAAG;AAAA,MAC/B,MAAM,KAAK,GAAG;AAAA,IAChB;AAAA,EACF;AAAA,EAEA,IAAI,MAAM,QAAQ,KAAK,WAAW,GAAG;AAAA,IACnC,MAAM,IAAI,OAAO,UAAU;AAAA,CAAiC;AAAA,IAC5D,OAAO;AAAA,EACT;AAAA,EAEA,MAAM,cAAc,OAAO,YAAoB;AAAA,IAC7C,MAAM,QAAQ,QAAQ,MAAM;AAAA,CAAI;AAAA,IAChC,MAAM,WAAW,MAAM,MAAM,GAAG,QAAQ;AAAA,IACxC,SAAS,IAAI,EAAG,IAAI,SAAS,QAAQ,KAAK;AAAA,MACxC,MAAM,IAAI,OAAO,UAAU,SAAS,EAAG;AAAA,MACvC,IAAI,IAAI,SAAS,SAAS,KAAM,MAAM,SAAS,UAAW;AAAA,QACxD,MAAM,IAAI,OAAO,UAAU;AAAA,CAAI;AAAA,MACjC;AAAA,IACF;AAAA;AAAA,EAGF,IAAI,MAAM,WAAW,GAAG;AAAA,IAEtB,MAAM,UAAU,MAAM,IAAI,MAAM,KAAK;AAAA,IACrC,MAAM,YAAY,OAAO;AAAA,EAC3B,EAAO;AAAA,IACL,SAAS,IAAI,EAAG,IAAI,MAAM,QAAQ,KAAK;AAAA,MACrC,MAAM,OAAO,MAAM;AAAA,MACnB,IAAI;AAAA,QACF,IAAI,MAAM,SAAS,GAAG;AAAA,UACpB,IAAI,IAAI;AAAA,YAAG,MAAM,IAAI,OAAO,UAAU;AAAA,CAAI;AAAA,UAC1C,MAAM,IAAI,OAAO,UAAU,OAAO;AAAA,CAAY;AAAA,QAChD;AAAA,QACA,MAAM,OAAO,IAAI,GAAG,QAAQ,IAAI,KAAK,IAAI;AAAA,QACzC,MAAM,WAAW,MAAM,IAAI,GAAG,SAAS,IAAI,GAAG,SAAS;AAAA,QACvD,MAAM,YAAY,OAAO;AAAA,QACzB,OAAO,KAAK;AAAA,QACZ,MAAM,IAAI,OAAO,UAAU,SAAS;AAAA,CAAmC;AAAA,QACvE,OAAO;AAAA;AAAA,IAEX;AAAA;AAAA,EAGF,OAAO;AAAA;",
8
- "debugId": "3CCE7B78F55717AA64756E2164756E21",
7
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACsD,IAAtD;AAMA,IAAM,OAAO;AAAA,EACX,MAAM;AAAA,EACN,OAAO;AAAA,IACL,EAAE,OAAO,KAAK,MAAM,SAAS,YAAY,KAAK;AAAA,EAChD;AAAA,EACA,OAAO;AACT;AAEA,IAAM,WAAsB,EAAE,OAAO,GAAG;AAExC,IAAM,UAAU,CAAC,OAAkB,MAAsB,UAAmB;AAAA,EAC1E,IAAI,KAAK,UAAU,OAAO,OAAO;AAAA,IAC/B,MAAM,QAAQ,SAAS,OAAO,EAAE;AAAA,EAClC;AAAA;AAGF,IAAM,SAAS,oCAAiB,MAAM,UAAU,OAAO;AAEhD,IAAM,OAAgB,OAAO,QAAQ;AAAA,EAE1C,MAAM,gBAA0B,CAAC;AAAA,EACjC,WAAW,OAAO,IAAI,MAAM;AAAA,IAC1B,IAAI,IAAI,WAAW,GAAG,KAAK,SAAS,KAAK,GAAG,GAAG;AAAA,MAC7C,cAAc,KAAK,MAAM,IAAI,MAAM,CAAC,CAAC;AAAA,IACvC,EAAO;AAAA,MACL,cAAc,KAAK,GAAG;AAAA;AAAA,EAE1B;AAAA,EAEA,MAAM,SAAS,OAAO,MAAM,aAAa;AAAA,EAEzC,IAAI,OAAO,OAAO;AAAA,IAChB,MAAM,OAAO,WAAW,OAAO,OAAO,IAAI,MAAM;AAAA,IAChD,OAAO;AAAA,EACT;AAAA,EAEA,MAAM,WAAW,OAAO,MAAM;AAAA,EAC9B,MAAM,QAAQ,OAAO;AAAA,EAErB,IAAI,MAAM,QAAQ,KAAK,WAAW,GAAG;AAAA,IACnC,MAAM,IAAI,OAAO,UAAU;AAAA,CAAiC;AAAA,IAC5D,OAAO;AAAA,EACT;AAAA,EAEA,MAAM,cAAc,OAAO,YAAoB;AAAA,IAC7C,MAAM,QAAQ,QAAQ,MAAM;AAAA,CAAI;AAAA,IAChC,MAAM,WAAW,MAAM,MAAM,GAAG,QAAQ;AAAA,IACxC,SAAS,IAAI,EAAG,IAAI,SAAS,QAAQ,KAAK;AAAA,MACxC,MAAM,IAAI,OAAO,UAAU,SAAS,EAAG;AAAA,MACvC,IAAI,IAAI,SAAS,SAAS,KAAM,MAAM,SAAS,UAAW;AAAA,QACxD,MAAM,IAAI,OAAO,UAAU;AAAA,CAAI;AAAA,MACjC;AAAA,IACF;AAAA;AAAA,EAGF,IAAI,MAAM,WAAW,GAAG;AAAA,IAEtB,MAAM,UAAU,MAAM,IAAI,MAAM,KAAK;AAAA,IACrC,MAAM,YAAY,OAAO;AAAA,EAC3B,EAAO;AAAA,IACL,SAAS,IAAI,EAAG,IAAI,MAAM,QAAQ,KAAK;AAAA,MACrC,MAAM,OAAO,MAAM;AAAA,MACnB,IAAI;AAAA,QACF,IAAI,MAAM,SAAS,GAAG;AAAA,UACpB,IAAI,IAAI;AAAA,YAAG,MAAM,IAAI,OAAO,UAAU;AAAA,CAAI;AAAA,UAC1C,MAAM,IAAI,OAAO,UAAU,OAAO;AAAA,CAAY;AAAA,QAChD;AAAA,QACA,MAAM,OAAO,IAAI,GAAG,QAAQ,IAAI,KAAK,IAAI;AAAA,QACzC,MAAM,WAAW,MAAM,IAAI,GAAG,SAAS,IAAI,GAAG,SAAS;AAAA,QACvD,MAAM,YAAY,OAAO;AAAA,QACzB,OAAO,KAAK;AAAA,QACZ,MAAM,IAAI,OAAO,UAAU,SAAS;AAAA,CAAmC;AAAA,QACvE,OAAO;AAAA;AAAA,IAEX;AAAA;AAAA,EAGF,OAAO;AAAA;",
8
+ "debugId": "3F50A1766BFF78DF64756E2164756E21",
9
9
  "names": []
10
10
  }