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
@@ -22,6 +22,7 @@ import { find } from "./find/find.mjs";
22
22
  import { sed } from "./sed/sed.mjs";
23
23
  import { awk } from "./awk/awk.mjs";
24
24
  import { breakCmd, continueCmd } from "./break-continue/break-continue.mjs";
25
+ import { colon } from "./colon/colon.mjs";
25
26
  import { echo as echo2 } from "./echo/echo.mjs";
26
27
  import { cat as cat2 } from "./cat/cat.mjs";
27
28
  import { grep as grep2 } from "./grep/grep.mjs";
@@ -45,6 +46,7 @@ import { find as find2 } from "./find/find.mjs";
45
46
  import { sed as sed2 } from "./sed/sed.mjs";
46
47
  import { awk as awk2 } from "./awk/awk.mjs";
47
48
  import { breakCmd as breakCmd2, continueCmd as continueCmd2 } from "./break-continue/break-continue.mjs";
49
+ import { colon as colon2 } from "./colon/colon.mjs";
48
50
  var builtinCommands = {
49
51
  echo: echo2,
50
52
  cat: cat2,
@@ -71,7 +73,8 @@ var builtinCommands = {
71
73
  sed: sed2,
72
74
  awk: awk2,
73
75
  break: breakCmd2,
74
- continue: continueCmd2
76
+ continue: continueCmd2,
77
+ ":": colon2
75
78
  };
76
79
  export {
77
80
  wc,
@@ -96,6 +99,7 @@ export {
96
99
  echo,
97
100
  cp,
98
101
  continueCmd,
102
+ colon,
99
103
  cat,
100
104
  builtinCommands,
101
105
  breakCmd,
@@ -103,4 +107,4 @@ export {
103
107
  awk
104
108
  };
105
109
 
106
- //# debugId=217BED32E3D4B36564756E2164756E21
110
+ //# debugId=EB08C754C93B4E2664756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/commands/index.ts"],
4
4
  "sourcesContent": [
5
- "import type { Command } from \"../types.mjs\";\n\nexport { echo } from \"./echo/echo.mjs\";\nexport { cat } from \"./cat/cat.mjs\";\nexport { grep } from \"./grep/grep.mjs\";\nexport { wc } from \"./wc/wc.mjs\";\nexport { head } from \"./head/head.mjs\";\nexport { tail } from \"./tail/tail.mjs\";\nexport { sort } from \"./sort/sort.mjs\";\nexport { uniq } from \"./uniq/uniq.mjs\";\nexport { pwd } from \"./pwd/pwd.mjs\";\nexport { ls } from \"./ls/ls.mjs\";\nexport { mkdir } from \"./mkdir/mkdir.mjs\";\nexport { rm } from \"./rm/rm.mjs\";\nexport { test, bracket } from \"./test/test.mjs\";\nexport { trueCmd, falseCmd } from \"./true-false/true-false.mjs\";\nexport { touch } from \"./touch/touch.mjs\";\nexport { cp } from \"./cp/cp.mjs\";\nexport { mv } from \"./mv/mv.mjs\";\nexport { tee } from \"./tee/tee.mjs\";\nexport { tree } from \"./tree/tree.mjs\";\nexport { find } from \"./find/find.mjs\";\nexport { sed } from \"./sed/sed.mjs\";\nexport { awk } from \"./awk/awk.mjs\";\nexport { breakCmd, continueCmd } from \"./break-continue/break-continue.mjs\";\n\n// Re-export all commands as a bundle\nimport { echo } from \"./echo/echo.mjs\";\nimport { cat } from \"./cat/cat.mjs\";\nimport { grep } from \"./grep/grep.mjs\";\nimport { wc } from \"./wc/wc.mjs\";\nimport { head } from \"./head/head.mjs\";\nimport { tail } from \"./tail/tail.mjs\";\nimport { sort } from \"./sort/sort.mjs\";\nimport { uniq } from \"./uniq/uniq.mjs\";\nimport { pwd } from \"./pwd/pwd.mjs\";\nimport { ls } from \"./ls/ls.mjs\";\nimport { mkdir } from \"./mkdir/mkdir.mjs\";\nimport { rm } from \"./rm/rm.mjs\";\nimport { test, bracket } from \"./test/test.mjs\";\nimport { trueCmd, falseCmd } from \"./true-false/true-false.mjs\";\nimport { touch } from \"./touch/touch.mjs\";\nimport { cp } from \"./cp/cp.mjs\";\nimport { mv } from \"./mv/mv.mjs\";\nimport { tee } from \"./tee/tee.mjs\";\nimport { tree } from \"./tree/tree.mjs\";\nimport { find } from \"./find/find.mjs\";\nimport { sed } from \"./sed/sed.mjs\";\nimport { awk } from \"./awk/awk.mjs\";\nimport { breakCmd, continueCmd } from \"./break-continue/break-continue.mjs\";\n\nexport const builtinCommands: Record<string, Command> = {\n echo,\n cat,\n grep,\n wc,\n head,\n tail,\n sort,\n uniq,\n pwd,\n ls,\n mkdir,\n rm,\n test,\n \"[\": bracket,\n true: trueCmd,\n false: falseCmd,\n touch,\n cp,\n mv,\n tee,\n tree,\n find,\n sed,\n awk,\n break: breakCmd,\n continue: continueCmd,\n};\n"
5
+ "import type { Command } from \"../types.mjs\";\n\nexport { echo } from \"./echo/echo.mjs\";\nexport { cat } from \"./cat/cat.mjs\";\nexport { grep } from \"./grep/grep.mjs\";\nexport { wc } from \"./wc/wc.mjs\";\nexport { head } from \"./head/head.mjs\";\nexport { tail } from \"./tail/tail.mjs\";\nexport { sort } from \"./sort/sort.mjs\";\nexport { uniq } from \"./uniq/uniq.mjs\";\nexport { pwd } from \"./pwd/pwd.mjs\";\nexport { ls } from \"./ls/ls.mjs\";\nexport { mkdir } from \"./mkdir/mkdir.mjs\";\nexport { rm } from \"./rm/rm.mjs\";\nexport { test, bracket } from \"./test/test.mjs\";\nexport { trueCmd, falseCmd } from \"./true-false/true-false.mjs\";\nexport { touch } from \"./touch/touch.mjs\";\nexport { cp } from \"./cp/cp.mjs\";\nexport { mv } from \"./mv/mv.mjs\";\nexport { tee } from \"./tee/tee.mjs\";\nexport { tree } from \"./tree/tree.mjs\";\nexport { find } from \"./find/find.mjs\";\nexport { sed } from \"./sed/sed.mjs\";\nexport { awk } from \"./awk/awk.mjs\";\nexport { breakCmd, continueCmd } from \"./break-continue/break-continue.mjs\";\nexport { colon } from \"./colon/colon.mjs\";\n\n// Re-export all commands as a bundle\nimport { echo } from \"./echo/echo.mjs\";\nimport { cat } from \"./cat/cat.mjs\";\nimport { grep } from \"./grep/grep.mjs\";\nimport { wc } from \"./wc/wc.mjs\";\nimport { head } from \"./head/head.mjs\";\nimport { tail } from \"./tail/tail.mjs\";\nimport { sort } from \"./sort/sort.mjs\";\nimport { uniq } from \"./uniq/uniq.mjs\";\nimport { pwd } from \"./pwd/pwd.mjs\";\nimport { ls } from \"./ls/ls.mjs\";\nimport { mkdir } from \"./mkdir/mkdir.mjs\";\nimport { rm } from \"./rm/rm.mjs\";\nimport { test, bracket } from \"./test/test.mjs\";\nimport { trueCmd, falseCmd } from \"./true-false/true-false.mjs\";\nimport { touch } from \"./touch/touch.mjs\";\nimport { cp } from \"./cp/cp.mjs\";\nimport { mv } from \"./mv/mv.mjs\";\nimport { tee } from \"./tee/tee.mjs\";\nimport { tree } from \"./tree/tree.mjs\";\nimport { find } from \"./find/find.mjs\";\nimport { sed } from \"./sed/sed.mjs\";\nimport { awk } from \"./awk/awk.mjs\";\nimport { breakCmd, continueCmd } from \"./break-continue/break-continue.mjs\";\nimport { colon } from \"./colon/colon.mjs\";\n\nexport const builtinCommands: Record<string, Command> = {\n echo,\n cat,\n grep,\n wc,\n head,\n tail,\n sort,\n uniq,\n pwd,\n ls,\n mkdir,\n rm,\n test,\n \"[\": bracket,\n true: trueCmd,\n false: falseCmd,\n touch,\n cp,\n mv,\n tee,\n tree,\n find,\n sed,\n awk,\n break: breakCmd,\n continue: continueCmd,\n \":\": colon,\n};\n"
6
6
  ],
7
- "mappings": ";AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA,iBAAS;AACT,gBAAS;AACT,iBAAS;AACT,eAAS;AACT,iBAAS;AACT,iBAAS;AACT,iBAAS;AACT,iBAAS;AACT,gBAAS;AACT,eAAS;AACT,kBAAS;AACT,eAAS;AACT,iBAAS,kBAAM;AACf,oBAAS,sBAAS;AAClB,kBAAS;AACT,eAAS;AACT,eAAS;AACT,gBAAS;AACT,iBAAS;AACT,iBAAS;AACT,gBAAS;AACT,gBAAS;AACT,qBAAS,0BAAU;AAEZ,IAAM,kBAA2C;AAAA,EACtD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,KAAK;AAAA,EACL,MAAM;AAAA,EACN,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,UAAU;AACZ;",
8
- "debugId": "217BED32E3D4B36564756E2164756E21",
7
+ "mappings": ";AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA,iBAAS;AACT,gBAAS;AACT,iBAAS;AACT,eAAS;AACT,iBAAS;AACT,iBAAS;AACT,iBAAS;AACT,iBAAS;AACT,gBAAS;AACT,eAAS;AACT,kBAAS;AACT,eAAS;AACT,iBAAS,kBAAM;AACf,oBAAS,sBAAS;AAClB,kBAAS;AACT,eAAS;AACT,eAAS;AACT,gBAAS;AACT,iBAAS;AACT,iBAAS;AACT,gBAAS;AACT,gBAAS;AACT,qBAAS,0BAAU;AACnB,kBAAS;AAEF,IAAM,kBAA2C;AAAA,EACtD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,KAAK;AAAA,EACL,MAAM;AAAA,EACN,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,UAAU;AAAA,EACV,KAAK;AACP;",
8
+ "debugId": "EB08C754C93B4E2664756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -1,32 +1,32 @@
1
1
  // src/commands/ls/ls.ts
2
+ import { createFlagParser } from "../../utils/flag-parser.mjs";
3
+ var spec = {
4
+ name: "ls",
5
+ flags: [
6
+ { short: "a", long: "all" },
7
+ { short: "l" },
8
+ { short: "1" }
9
+ ],
10
+ usage: "ls [-al1] [file ...]"
11
+ };
12
+ var defaults = { all: false, long: false, onePerLine: false };
13
+ var handler = (flags, flag) => {
14
+ if (flag.short === "a")
15
+ flags.all = true;
16
+ if (flag.short === "l")
17
+ flags.long = true;
18
+ if (flag.short === "1")
19
+ flags.onePerLine = true;
20
+ };
21
+ var parser = createFlagParser(spec, defaults, handler);
2
22
  var ls = async (ctx) => {
3
- let showAll = false;
4
- let longFormat = false;
5
- let onePerLine = false;
6
- const paths = [];
7
- for (const arg of ctx.args) {
8
- if (arg === "-a" || arg === "--all") {
9
- showAll = true;
10
- } else if (arg === "-l") {
11
- longFormat = true;
12
- } else if (arg === "-1") {
13
- onePerLine = true;
14
- } else if (arg.startsWith("-")) {
15
- for (const flag of arg.slice(1)) {
16
- if (flag === "a")
17
- showAll = true;
18
- else if (flag === "l")
19
- longFormat = true;
20
- else if (flag === "1")
21
- onePerLine = true;
22
- }
23
- } else {
24
- paths.push(arg);
25
- }
26
- }
27
- if (paths.length === 0) {
28
- paths.push(".");
23
+ const result = parser.parse(ctx.args);
24
+ if (result.error) {
25
+ await parser.writeError(result.error, ctx.stderr);
26
+ return 1;
29
27
  }
28
+ const { all: showAll, long: longFormat, onePerLine } = result.flags;
29
+ const paths = result.args.length === 0 ? ["."] : result.args;
30
30
  for (let i = 0;i < paths.length; i++) {
31
31
  const pathArg = paths[i];
32
32
  const path = ctx.fs.resolve(ctx.cwd, pathArg);
@@ -86,4 +86,4 @@ export {
86
86
  ls
87
87
  };
88
88
 
89
- //# debugId=322ADB729375592364756E2164756E21
89
+ //# debugId=CEDE14395BFC6B1E64756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/commands/ls/ls.ts"],
4
4
  "sourcesContent": [
5
- "import type { Command } from \"../../types.mjs\";\n\nexport const ls: Command = async (ctx) => {\n let showAll = false;\n let longFormat = false;\n let onePerLine = false;\n const paths: string[] = [];\n\n // Parse arguments\n for (const arg of ctx.args) {\n if (arg === \"-a\" || arg === \"--all\") {\n showAll = true;\n } else if (arg === \"-l\") {\n longFormat = true;\n } else if (arg === \"-1\") {\n onePerLine = true;\n } else if (arg.startsWith(\"-\")) {\n for (const flag of arg.slice(1)) {\n if (flag === \"a\") showAll = true;\n else if (flag === \"l\") longFormat = true;\n else if (flag === \"1\") onePerLine = true;\n }\n } else {\n paths.push(arg);\n }\n }\n\n if (paths.length === 0) {\n paths.push(\".\");\n }\n\n for (let i = 0; i < paths.length; i++) {\n const pathArg = paths[i]!;\n const path = ctx.fs.resolve(ctx.cwd, pathArg);\n\n try {\n const stat = await ctx.fs.stat(path);\n\n if (stat.isFile()) {\n // It's a file, just print the name\n await ctx.stdout.writeText(ctx.fs.basename(path) + \"\\n\");\n continue;\n }\n\n // It's a directory\n if (paths.length > 1) {\n if (i > 0) await ctx.stdout.writeText(\"\\n\");\n await ctx.stdout.writeText(`${pathArg}:\\n`);\n }\n\n let entries = await ctx.fs.readdir(path);\n\n if (!showAll) {\n entries = entries.filter((e) => !e.startsWith(\".\"));\n }\n\n entries.sort();\n\n if (longFormat) {\n for (const entry of entries) {\n const entryPath = ctx.fs.resolve(path, entry);\n try {\n const entryStat = await ctx.fs.stat(entryPath);\n const type = entryStat.isDirectory() ? \"d\" : \"-\";\n const perms = \"rwxr-xr-x\"; // Simplified permissions\n const size = String(entryStat.size).padStart(8);\n const date = entryStat.mtime.toISOString().slice(0, 10);\n await ctx.stdout.writeText(`${type}${perms} ${size} ${date} ${entry}\\n`);\n } catch {\n await ctx.stdout.writeText(`?????????? ${entry}\\n`);\n }\n }\n } else if (onePerLine) {\n for (const entry of entries) {\n await ctx.stdout.writeText(entry + \"\\n\");\n }\n } else {\n // Default: space-separated\n await ctx.stdout.writeText(entries.join(\" \") + \"\\n\");\n }\n } catch (err) {\n await ctx.stderr.writeText(`ls: cannot access '${pathArg}': No such file or directory\\n`);\n return 1;\n }\n }\n\n return 0;\n};\n"
5
+ "import type { Command } from \"../../types.mjs\";\nimport { createFlagParser, type FlagDefinition } from \"../../utils/flag-parser.mjs\";\n\ninterface LsFlags {\n all: boolean;\n long: boolean;\n onePerLine: boolean;\n}\n\nconst spec = {\n name: \"ls\",\n flags: [\n { short: \"a\", long: \"all\" },\n { short: \"l\" },\n { short: \"1\" },\n ] as FlagDefinition[],\n usage: \"ls [-al1] [file ...]\",\n};\n\nconst defaults: LsFlags = { all: false, long: false, onePerLine: false };\n\nconst handler = (flags: LsFlags, flag: FlagDefinition) => {\n if (flag.short === \"a\") flags.all = true;\n if (flag.short === \"l\") flags.long = true;\n if (flag.short === \"1\") flags.onePerLine = true;\n};\n\nconst parser = createFlagParser(spec, defaults, handler);\n\nexport const ls: Command = async (ctx) => {\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 { all: showAll, long: longFormat, onePerLine } = result.flags;\n const paths = result.args.length === 0 ? [\".\"] : result.args;\n\n for (let i = 0; i < paths.length; i++) {\n const pathArg = paths[i]!;\n const path = ctx.fs.resolve(ctx.cwd, pathArg);\n\n try {\n const stat = await ctx.fs.stat(path);\n\n if (stat.isFile()) {\n // It's a file, just print the name\n await ctx.stdout.writeText(ctx.fs.basename(path) + \"\\n\");\n continue;\n }\n\n // It's a directory\n if (paths.length > 1) {\n if (i > 0) await ctx.stdout.writeText(\"\\n\");\n await ctx.stdout.writeText(`${pathArg}:\\n`);\n }\n\n let entries = await ctx.fs.readdir(path);\n\n if (!showAll) {\n entries = entries.filter((e) => !e.startsWith(\".\"));\n }\n\n entries.sort();\n\n if (longFormat) {\n for (const entry of entries) {\n const entryPath = ctx.fs.resolve(path, entry);\n try {\n const entryStat = await ctx.fs.stat(entryPath);\n const type = entryStat.isDirectory() ? \"d\" : \"-\";\n const perms = \"rwxr-xr-x\"; // Simplified permissions\n const size = String(entryStat.size).padStart(8);\n const date = entryStat.mtime.toISOString().slice(0, 10);\n await ctx.stdout.writeText(`${type}${perms} ${size} ${date} ${entry}\\n`);\n } catch {\n await ctx.stdout.writeText(`?????????? ${entry}\\n`);\n }\n }\n } else if (onePerLine) {\n for (const entry of entries) {\n await ctx.stdout.writeText(entry + \"\\n\");\n }\n } else {\n // Default: space-separated\n await ctx.stdout.writeText(entries.join(\" \") + \"\\n\");\n }\n } catch (err) {\n await ctx.stderr.writeText(`ls: cannot access '${pathArg}': No such file or directory\\n`);\n return 1;\n }\n }\n\n return 0;\n};\n"
6
6
  ],
7
- "mappings": ";AAEO,IAAM,KAAc,OAAO,QAAQ;AAAA,EACxC,IAAI,UAAU;AAAA,EACd,IAAI,aAAa;AAAA,EACjB,IAAI,aAAa;AAAA,EACjB,MAAM,QAAkB,CAAC;AAAA,EAGzB,WAAW,OAAO,IAAI,MAAM;AAAA,IAC1B,IAAI,QAAQ,QAAQ,QAAQ,SAAS;AAAA,MACnC,UAAU;AAAA,IACZ,EAAO,SAAI,QAAQ,MAAM;AAAA,MACvB,aAAa;AAAA,IACf,EAAO,SAAI,QAAQ,MAAM;AAAA,MACvB,aAAa;AAAA,IACf,EAAO,SAAI,IAAI,WAAW,GAAG,GAAG;AAAA,MAC9B,WAAW,QAAQ,IAAI,MAAM,CAAC,GAAG;AAAA,QAC/B,IAAI,SAAS;AAAA,UAAK,UAAU;AAAA,QACvB,SAAI,SAAS;AAAA,UAAK,aAAa;AAAA,QAC/B,SAAI,SAAS;AAAA,UAAK,aAAa;AAAA,MACtC;AAAA,IACF,EAAO;AAAA,MACL,MAAM,KAAK,GAAG;AAAA;AAAA,EAElB;AAAA,EAEA,IAAI,MAAM,WAAW,GAAG;AAAA,IACtB,MAAM,KAAK,GAAG;AAAA,EAChB;AAAA,EAEA,SAAS,IAAI,EAAG,IAAI,MAAM,QAAQ,KAAK;AAAA,IACrC,MAAM,UAAU,MAAM;AAAA,IACtB,MAAM,OAAO,IAAI,GAAG,QAAQ,IAAI,KAAK,OAAO;AAAA,IAE5C,IAAI;AAAA,MACF,MAAM,OAAO,MAAM,IAAI,GAAG,KAAK,IAAI;AAAA,MAEnC,IAAI,KAAK,OAAO,GAAG;AAAA,QAEjB,MAAM,IAAI,OAAO,UAAU,IAAI,GAAG,SAAS,IAAI,IAAI;AAAA,CAAI;AAAA,QACvD;AAAA,MACF;AAAA,MAGA,IAAI,MAAM,SAAS,GAAG;AAAA,QACpB,IAAI,IAAI;AAAA,UAAG,MAAM,IAAI,OAAO,UAAU;AAAA,CAAI;AAAA,QAC1C,MAAM,IAAI,OAAO,UAAU,GAAG;AAAA,CAAY;AAAA,MAC5C;AAAA,MAEA,IAAI,UAAU,MAAM,IAAI,GAAG,QAAQ,IAAI;AAAA,MAEvC,IAAI,CAAC,SAAS;AAAA,QACZ,UAAU,QAAQ,OAAO,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,CAAC;AAAA,MACpD;AAAA,MAEA,QAAQ,KAAK;AAAA,MAEb,IAAI,YAAY;AAAA,QACd,WAAW,SAAS,SAAS;AAAA,UAC3B,MAAM,YAAY,IAAI,GAAG,QAAQ,MAAM,KAAK;AAAA,UAC5C,IAAI;AAAA,YACF,MAAM,YAAY,MAAM,IAAI,GAAG,KAAK,SAAS;AAAA,YAC7C,MAAM,OAAO,UAAU,YAAY,IAAI,MAAM;AAAA,YAC7C,MAAM,QAAQ;AAAA,YACd,MAAM,OAAO,OAAO,UAAU,IAAI,EAAE,SAAS,CAAC;AAAA,YAC9C,MAAM,OAAO,UAAU,MAAM,YAAY,EAAE,MAAM,GAAG,EAAE;AAAA,YACtD,MAAM,IAAI,OAAO,UAAU,GAAG,OAAO,SAAS,QAAQ,QAAQ;AAAA,CAAS;AAAA,YACvE,MAAM;AAAA,YACN,MAAM,IAAI,OAAO,UAAU,cAAc;AAAA,CAAS;AAAA;AAAA,QAEtD;AAAA,MACF,EAAO,SAAI,YAAY;AAAA,QACrB,WAAW,SAAS,SAAS;AAAA,UAC3B,MAAM,IAAI,OAAO,UAAU,QAAQ;AAAA,CAAI;AAAA,QACzC;AAAA,MACF,EAAO;AAAA,QAEL,MAAM,IAAI,OAAO,UAAU,QAAQ,KAAK,IAAI,IAAI;AAAA,CAAI;AAAA;AAAA,MAEtD,OAAO,KAAK;AAAA,MACZ,MAAM,IAAI,OAAO,UAAU,sBAAsB;AAAA,CAAuC;AAAA,MACxF,OAAO;AAAA;AAAA,EAEX;AAAA,EAEA,OAAO;AAAA;",
8
- "debugId": "322ADB729375592364756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "CEDE14395BFC6B1E64756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -1,14 +1,25 @@
1
1
  // src/commands/mkdir/mkdir.ts
2
+ import { createFlagParser } from "../../utils/flag-parser.mjs";
3
+ var spec = {
4
+ name: "mkdir",
5
+ flags: [
6
+ { short: "p", long: "parents" }
7
+ ],
8
+ usage: "mkdir [-p] directory ..."
9
+ };
10
+ var defaults = { parents: false };
11
+ var handler = (flags, flag) => {
12
+ if (flag.short === "p")
13
+ flags.parents = true;
14
+ };
15
+ var parser = createFlagParser(spec, defaults, handler);
2
16
  var mkdir = async (ctx) => {
3
- let parents = false;
4
- const dirs = [];
5
- for (const arg of ctx.args) {
6
- if (arg === "-p" || arg === "--parents") {
7
- parents = true;
8
- } else if (!arg.startsWith("-")) {
9
- dirs.push(arg);
10
- }
17
+ const result = parser.parse(ctx.args);
18
+ if (result.error) {
19
+ await parser.writeError(result.error, ctx.stderr);
20
+ return 1;
11
21
  }
22
+ const dirs = result.args;
12
23
  if (dirs.length === 0) {
13
24
  await ctx.stderr.writeText(`mkdir: missing operand
14
25
  `);
@@ -17,7 +28,7 @@ var mkdir = async (ctx) => {
17
28
  for (const dir of dirs) {
18
29
  const path = ctx.fs.resolve(ctx.cwd, dir);
19
30
  try {
20
- await ctx.fs.mkdir(path, { recursive: parents });
31
+ await ctx.fs.mkdir(path, { recursive: result.flags.parents });
21
32
  } catch (err) {
22
33
  const message = err instanceof Error ? err.message : String(err);
23
34
  await ctx.stderr.writeText(`mkdir: cannot create directory '${dir}': ${message}
@@ -31,4 +42,4 @@ export {
31
42
  mkdir
32
43
  };
33
44
 
34
- //# debugId=43C20439FAB30DFD64756E2164756E21
45
+ //# debugId=B8B8F94D111926F564756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/commands/mkdir/mkdir.ts"],
4
4
  "sourcesContent": [
5
- "import type { Command } from \"../../types.mjs\";\n\nexport const mkdir: Command = async (ctx) => {\n let parents = false;\n const dirs: string[] = [];\n\n for (const arg of ctx.args) {\n if (arg === \"-p\" || arg === \"--parents\") {\n parents = true;\n } else if (!arg.startsWith(\"-\")) {\n dirs.push(arg);\n }\n }\n\n if (dirs.length === 0) {\n await ctx.stderr.writeText(\"mkdir: missing operand\\n\");\n return 1;\n }\n\n for (const dir of dirs) {\n const path = ctx.fs.resolve(ctx.cwd, dir);\n try {\n await ctx.fs.mkdir(path, { recursive: parents });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n await ctx.stderr.writeText(`mkdir: cannot create directory '${dir}': ${message}\\n`);\n return 1;\n }\n }\n\n return 0;\n};\n"
5
+ "import type { Command } from \"../../types.mjs\";\nimport { createFlagParser, type FlagDefinition } from \"../../utils/flag-parser.mjs\";\n\ninterface MkdirFlags {\n parents: boolean;\n}\n\nconst spec = {\n name: \"mkdir\",\n flags: [\n { short: \"p\", long: \"parents\" },\n ] as FlagDefinition[],\n usage: \"mkdir [-p] directory ...\",\n};\n\nconst defaults: MkdirFlags = { parents: false };\n\nconst handler = (flags: MkdirFlags, flag: FlagDefinition) => {\n if (flag.short === \"p\") flags.parents = true;\n};\n\nconst parser = createFlagParser(spec, defaults, handler);\n\nexport const mkdir: Command = async (ctx) => {\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 dirs = result.args;\n\n if (dirs.length === 0) {\n await ctx.stderr.writeText(\"mkdir: missing operand\\n\");\n return 1;\n }\n\n for (const dir of dirs) {\n const path = ctx.fs.resolve(ctx.cwd, dir);\n try {\n await ctx.fs.mkdir(path, { recursive: result.flags.parents });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n await ctx.stderr.writeText(`mkdir: cannot create directory '${dir}': ${message}\\n`);\n return 1;\n }\n }\n\n return 0;\n};\n"
6
6
  ],
7
- "mappings": ";AAEO,IAAM,QAAiB,OAAO,QAAQ;AAAA,EAC3C,IAAI,UAAU;AAAA,EACd,MAAM,OAAiB,CAAC;AAAA,EAExB,WAAW,OAAO,IAAI,MAAM;AAAA,IAC1B,IAAI,QAAQ,QAAQ,QAAQ,aAAa;AAAA,MACvC,UAAU;AAAA,IACZ,EAAO,SAAI,CAAC,IAAI,WAAW,GAAG,GAAG;AAAA,MAC/B,KAAK,KAAK,GAAG;AAAA,IACf;AAAA,EACF;AAAA,EAEA,IAAI,KAAK,WAAW,GAAG;AAAA,IACrB,MAAM,IAAI,OAAO,UAAU;AAAA,CAA0B;AAAA,IACrD,OAAO;AAAA,EACT;AAAA,EAEA,WAAW,OAAO,MAAM;AAAA,IACtB,MAAM,OAAO,IAAI,GAAG,QAAQ,IAAI,KAAK,GAAG;AAAA,IACxC,IAAI;AAAA,MACF,MAAM,IAAI,GAAG,MAAM,MAAM,EAAE,WAAW,QAAQ,CAAC;AAAA,MAC/C,OAAO,KAAK;AAAA,MACZ,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,MAC/D,MAAM,IAAI,OAAO,UAAU,mCAAmC,SAAS;AAAA,CAAW;AAAA,MAClF,OAAO;AAAA;AAAA,EAEX;AAAA,EAEA,OAAO;AAAA;",
8
- "debugId": "43C20439FAB30DFD64756E2164756E21",
7
+ "mappings": ";AACA;AAMA,IAAM,OAAO;AAAA,EACX,MAAM;AAAA,EACN,OAAO;AAAA,IACL,EAAE,OAAO,KAAK,MAAM,UAAU;AAAA,EAChC;AAAA,EACA,OAAO;AACT;AAEA,IAAM,WAAuB,EAAE,SAAS,MAAM;AAE9C,IAAM,UAAU,CAAC,OAAmB,SAAyB;AAAA,EAC3D,IAAI,KAAK,UAAU;AAAA,IAAK,MAAM,UAAU;AAAA;AAG1C,IAAM,SAAS,iBAAiB,MAAM,UAAU,OAAO;AAEhD,IAAM,QAAiB,OAAO,QAAQ;AAAA,EAC3C,MAAM,SAAS,OAAO,MAAM,IAAI,IAAI;AAAA,EAEpC,IAAI,OAAO,OAAO;AAAA,IAChB,MAAM,OAAO,WAAW,OAAO,OAAO,IAAI,MAAM;AAAA,IAChD,OAAO;AAAA,EACT;AAAA,EAEA,MAAM,OAAO,OAAO;AAAA,EAEpB,IAAI,KAAK,WAAW,GAAG;AAAA,IACrB,MAAM,IAAI,OAAO,UAAU;AAAA,CAA0B;AAAA,IACrD,OAAO;AAAA,EACT;AAAA,EAEA,WAAW,OAAO,MAAM;AAAA,IACtB,MAAM,OAAO,IAAI,GAAG,QAAQ,IAAI,KAAK,GAAG;AAAA,IACxC,IAAI;AAAA,MACF,MAAM,IAAI,GAAG,MAAM,MAAM,EAAE,WAAW,OAAO,MAAM,QAAQ,CAAC;AAAA,MAC5D,OAAO,KAAK;AAAA,MACZ,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,MAC/D,MAAM,IAAI,OAAO,UAAU,mCAAmC,SAAS;AAAA,CAAW;AAAA,MAClF,OAAO;AAAA;AAAA,EAEX;AAAA,EAEA,OAAO;AAAA;",
8
+ "debugId": "B8B8F94D111926F564756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -1,20 +1,27 @@
1
1
  // src/commands/mv/mv.ts
2
+ import { createFlagParser } from "../../utils/flag-parser.mjs";
3
+ var spec = {
4
+ name: "mv",
5
+ flags: [
6
+ { short: "n", long: "no-clobber" },
7
+ { short: "f", long: "force" }
8
+ ],
9
+ usage: "mv [-nf] source ... dest"
10
+ };
11
+ var defaults = { noClobber: false };
12
+ var handler = (flags, flag) => {
13
+ if (flag.short === "n")
14
+ flags.noClobber = true;
15
+ };
16
+ var parser = createFlagParser(spec, defaults, handler);
2
17
  var mv = async (ctx) => {
3
- let noClobber = false;
4
- const paths = [];
5
- for (const arg of ctx.args) {
6
- if (arg === "-n" || arg === "--no-clobber") {
7
- noClobber = true;
8
- } else if (arg === "-f" || arg === "--force") {} else if (arg.startsWith("-")) {
9
- for (const flag of arg.slice(1)) {
10
- if (flag === "n")
11
- noClobber = true;
12
- else if (flag === "f") {}
13
- }
14
- } else {
15
- paths.push(arg);
16
- }
18
+ const result = parser.parse(ctx.args);
19
+ if (result.error) {
20
+ await parser.writeError(result.error, ctx.stderr);
21
+ return 1;
17
22
  }
23
+ const { noClobber } = result.flags;
24
+ const paths = result.args;
18
25
  if (paths.length < 2) {
19
26
  await ctx.stderr.writeText(`mv: missing destination file operand
20
27
  `);
@@ -85,4 +92,4 @@ export {
85
92
  mv
86
93
  };
87
94
 
88
- //# debugId=9E82B62514CDCFA164756E2164756E21
95
+ //# debugId=7BEAB35C04AB93F764756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/commands/mv/mv.ts"],
4
4
  "sourcesContent": [
5
- "import type { Command } from \"../../types.mjs\";\n\nexport const mv: Command = async (ctx) => {\n let noClobber = false;\n const paths: string[] = [];\n\n for (const arg of ctx.args) {\n if (arg === \"-n\" || arg === \"--no-clobber\") {\n noClobber = true;\n } else if (arg === \"-f\" || arg === \"--force\") {\n // Force is default behavior, just accept the flag\n } else if (arg.startsWith(\"-\")) {\n // Parse combined flags\n for (const flag of arg.slice(1)) {\n if (flag === \"n\") noClobber = true;\n else if (flag === \"f\") { /* force is default */ }\n }\n } else {\n paths.push(arg);\n }\n }\n\n if (paths.length < 2) {\n await ctx.stderr.writeText(\"mv: missing destination file operand\\n\");\n return 1;\n }\n\n const sources = paths.slice(0, -1);\n const dest = paths[paths.length - 1]!;\n const destPath = ctx.fs.resolve(ctx.cwd, dest);\n\n // Check if destination is a directory\n let destIsDir = false;\n try {\n const stat = await ctx.fs.stat(destPath);\n destIsDir = stat.isDirectory();\n } catch {\n // Destination doesn't exist\n }\n\n // If multiple sources, dest must be a directory\n if (sources.length > 1 && !destIsDir) {\n await ctx.stderr.writeText(`mv: target '${dest}' is not a directory\\n`);\n return 1;\n }\n\n for (const source of sources) {\n const srcPath = ctx.fs.resolve(ctx.cwd, source);\n\n try {\n // Check source exists\n await ctx.fs.stat(srcPath);\n\n // Determine final destination path\n const finalDest = destIsDir\n ? ctx.fs.resolve(destPath, ctx.fs.basename(srcPath))\n : destPath;\n\n // Check if dest exists and noClobber\n if (noClobber) {\n const exists = await ctx.fs.exists(finalDest);\n if (exists) continue; // Skip silently\n }\n\n // Move: copy then delete\n const srcStat = await ctx.fs.stat(srcPath);\n if (srcStat.isDirectory()) {\n await moveDirectory(ctx, srcPath, finalDest, noClobber);\n } else {\n const content = await ctx.fs.readFile(srcPath);\n await ctx.fs.writeFile(finalDest, content);\n await ctx.fs.rm(srcPath);\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n await ctx.stderr.writeText(`mv: cannot stat '${source}': ${message}\\n`);\n return 1;\n }\n }\n\n return 0;\n};\n\nasync function moveDirectory(\n ctx: Parameters<Command>[0],\n src: string,\n dest: string,\n noClobber: boolean\n): Promise<void> {\n // Create destination directory\n await ctx.fs.mkdir(dest, { recursive: true });\n\n // Read source directory contents\n const entries = await ctx.fs.readdir(src);\n\n for (const entry of entries) {\n const srcPath = ctx.fs.resolve(src, entry);\n const destPath = ctx.fs.resolve(dest, entry);\n\n const stat = await ctx.fs.stat(srcPath);\n\n if (stat.isDirectory()) {\n await moveDirectory(ctx, srcPath, destPath, noClobber);\n } else {\n if (noClobber) {\n const exists = await ctx.fs.exists(destPath);\n if (exists) continue;\n }\n const content = await ctx.fs.readFile(srcPath);\n await ctx.fs.writeFile(destPath, content);\n }\n }\n\n // Remove source directory after copying\n await ctx.fs.rm(src, { recursive: true });\n}\n"
5
+ "import type { Command } from \"../../types.mjs\";\nimport { createFlagParser, type FlagDefinition } from \"../../utils/flag-parser.mjs\";\n\ninterface MvFlags {\n noClobber: boolean;\n}\n\nconst spec = {\n name: \"mv\",\n flags: [\n { short: \"n\", long: \"no-clobber\" },\n { short: \"f\", long: \"force\" },\n ] as FlagDefinition[],\n usage: \"mv [-nf] source ... dest\",\n};\n\nconst defaults: MvFlags = { noClobber: false };\n\nconst handler = (flags: MvFlags, flag: FlagDefinition) => {\n if (flag.short === \"n\") flags.noClobber = true;\n // -f is default behavior, so we don't need to do anything\n};\n\nconst parser = createFlagParser(spec, defaults, handler);\n\nexport const mv: Command = async (ctx) => {\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 { noClobber } = result.flags;\n const paths = result.args;\n\n if (paths.length < 2) {\n await ctx.stderr.writeText(\"mv: missing destination file operand\\n\");\n return 1;\n }\n\n const sources = paths.slice(0, -1);\n const dest = paths[paths.length - 1]!;\n const destPath = ctx.fs.resolve(ctx.cwd, dest);\n\n // Check if destination is a directory\n let destIsDir = false;\n try {\n const stat = await ctx.fs.stat(destPath);\n destIsDir = stat.isDirectory();\n } catch {\n // Destination doesn't exist\n }\n\n // If multiple sources, dest must be a directory\n if (sources.length > 1 && !destIsDir) {\n await ctx.stderr.writeText(`mv: target '${dest}' is not a directory\\n`);\n return 1;\n }\n\n for (const source of sources) {\n const srcPath = ctx.fs.resolve(ctx.cwd, source);\n\n try {\n // Check source exists\n await ctx.fs.stat(srcPath);\n\n // Determine final destination path\n const finalDest = destIsDir\n ? ctx.fs.resolve(destPath, ctx.fs.basename(srcPath))\n : destPath;\n\n // Check if dest exists and noClobber\n if (noClobber) {\n const exists = await ctx.fs.exists(finalDest);\n if (exists) continue; // Skip silently\n }\n\n // Move: copy then delete\n const srcStat = await ctx.fs.stat(srcPath);\n if (srcStat.isDirectory()) {\n await moveDirectory(ctx, srcPath, finalDest, noClobber);\n } else {\n const content = await ctx.fs.readFile(srcPath);\n await ctx.fs.writeFile(finalDest, content);\n await ctx.fs.rm(srcPath);\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n await ctx.stderr.writeText(`mv: cannot stat '${source}': ${message}\\n`);\n return 1;\n }\n }\n\n return 0;\n};\n\nasync function moveDirectory(\n ctx: Parameters<Command>[0],\n src: string,\n dest: string,\n noClobber: boolean\n): Promise<void> {\n // Create destination directory\n await ctx.fs.mkdir(dest, { recursive: true });\n\n // Read source directory contents\n const entries = await ctx.fs.readdir(src);\n\n for (const entry of entries) {\n const srcPath = ctx.fs.resolve(src, entry);\n const destPath = ctx.fs.resolve(dest, entry);\n\n const stat = await ctx.fs.stat(srcPath);\n\n if (stat.isDirectory()) {\n await moveDirectory(ctx, srcPath, destPath, noClobber);\n } else {\n if (noClobber) {\n const exists = await ctx.fs.exists(destPath);\n if (exists) continue;\n }\n const content = await ctx.fs.readFile(srcPath);\n await ctx.fs.writeFile(destPath, content);\n }\n }\n\n // Remove source directory after copying\n await ctx.fs.rm(src, { recursive: true });\n}\n"
6
6
  ],
7
- "mappings": ";AAEO,IAAM,KAAc,OAAO,QAAQ;AAAA,EACxC,IAAI,YAAY;AAAA,EAChB,MAAM,QAAkB,CAAC;AAAA,EAEzB,WAAW,OAAO,IAAI,MAAM;AAAA,IAC1B,IAAI,QAAQ,QAAQ,QAAQ,gBAAgB;AAAA,MAC1C,YAAY;AAAA,IACd,EAAO,SAAI,QAAQ,QAAQ,QAAQ,WAAW,CAE9C,EAAO,SAAI,IAAI,WAAW,GAAG,GAAG;AAAA,MAE9B,WAAW,QAAQ,IAAI,MAAM,CAAC,GAAG;AAAA,QAC/B,IAAI,SAAS;AAAA,UAAK,YAAY;AAAA,QACzB,SAAI,SAAS,KAAK,CAAyB;AAAA,MAClD;AAAA,IACF,EAAO;AAAA,MACL,MAAM,KAAK,GAAG;AAAA;AAAA,EAElB;AAAA,EAEA,IAAI,MAAM,SAAS,GAAG;AAAA,IACpB,MAAM,IAAI,OAAO,UAAU;AAAA,CAAwC;AAAA,IACnE,OAAO;AAAA,EACT;AAAA,EAEA,MAAM,UAAU,MAAM,MAAM,GAAG,EAAE;AAAA,EACjC,MAAM,OAAO,MAAM,MAAM,SAAS;AAAA,EAClC,MAAM,WAAW,IAAI,GAAG,QAAQ,IAAI,KAAK,IAAI;AAAA,EAG7C,IAAI,YAAY;AAAA,EAChB,IAAI;AAAA,IACF,MAAM,OAAO,MAAM,IAAI,GAAG,KAAK,QAAQ;AAAA,IACvC,YAAY,KAAK,YAAY;AAAA,IAC7B,MAAM;AAAA,EAKR,IAAI,QAAQ,SAAS,KAAK,CAAC,WAAW;AAAA,IACpC,MAAM,IAAI,OAAO,UAAU,eAAe;AAAA,CAA4B;AAAA,IACtE,OAAO;AAAA,EACT;AAAA,EAEA,WAAW,UAAU,SAAS;AAAA,IAC5B,MAAM,UAAU,IAAI,GAAG,QAAQ,IAAI,KAAK,MAAM;AAAA,IAE9C,IAAI;AAAA,MAEF,MAAM,IAAI,GAAG,KAAK,OAAO;AAAA,MAGzB,MAAM,YAAY,YACd,IAAI,GAAG,QAAQ,UAAU,IAAI,GAAG,SAAS,OAAO,CAAC,IACjD;AAAA,MAGJ,IAAI,WAAW;AAAA,QACb,MAAM,SAAS,MAAM,IAAI,GAAG,OAAO,SAAS;AAAA,QAC5C,IAAI;AAAA,UAAQ;AAAA,MACd;AAAA,MAGA,MAAM,UAAU,MAAM,IAAI,GAAG,KAAK,OAAO;AAAA,MACzC,IAAI,QAAQ,YAAY,GAAG;AAAA,QACzB,MAAM,cAAc,KAAK,SAAS,WAAW,SAAS;AAAA,MACxD,EAAO;AAAA,QACL,MAAM,UAAU,MAAM,IAAI,GAAG,SAAS,OAAO;AAAA,QAC7C,MAAM,IAAI,GAAG,UAAU,WAAW,OAAO;AAAA,QACzC,MAAM,IAAI,GAAG,GAAG,OAAO;AAAA;AAAA,MAEzB,OAAO,KAAK;AAAA,MACZ,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,MAC/D,MAAM,IAAI,OAAO,UAAU,oBAAoB,YAAY;AAAA,CAAW;AAAA,MACtE,OAAO;AAAA;AAAA,EAEX;AAAA,EAEA,OAAO;AAAA;AAGT,eAAe,aAAa,CAC1B,KACA,KACA,MACA,WACe;AAAA,EAEf,MAAM,IAAI,GAAG,MAAM,MAAM,EAAE,WAAW,KAAK,CAAC;AAAA,EAG5C,MAAM,UAAU,MAAM,IAAI,GAAG,QAAQ,GAAG;AAAA,EAExC,WAAW,SAAS,SAAS;AAAA,IAC3B,MAAM,UAAU,IAAI,GAAG,QAAQ,KAAK,KAAK;AAAA,IACzC,MAAM,WAAW,IAAI,GAAG,QAAQ,MAAM,KAAK;AAAA,IAE3C,MAAM,OAAO,MAAM,IAAI,GAAG,KAAK,OAAO;AAAA,IAEtC,IAAI,KAAK,YAAY,GAAG;AAAA,MACtB,MAAM,cAAc,KAAK,SAAS,UAAU,SAAS;AAAA,IACvD,EAAO;AAAA,MACL,IAAI,WAAW;AAAA,QACb,MAAM,SAAS,MAAM,IAAI,GAAG,OAAO,QAAQ;AAAA,QAC3C,IAAI;AAAA,UAAQ;AAAA,MACd;AAAA,MACA,MAAM,UAAU,MAAM,IAAI,GAAG,SAAS,OAAO;AAAA,MAC7C,MAAM,IAAI,GAAG,UAAU,UAAU,OAAO;AAAA;AAAA,EAE5C;AAAA,EAGA,MAAM,IAAI,GAAG,GAAG,KAAK,EAAE,WAAW,KAAK,CAAC;AAAA;",
8
- "debugId": "9E82B62514CDCFA164756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "7BEAB35C04AB93F764756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -1,5 +1,17 @@
1
1
  // src/commands/pwd/pwd.ts
2
+ import { createFlagParser } from "../../utils/flag-parser.mjs";
3
+ var spec = {
4
+ name: "pwd",
5
+ flags: [],
6
+ usage: "pwd"
7
+ };
8
+ var parser = createFlagParser(spec, {}, () => {});
2
9
  var pwd = async (ctx) => {
10
+ const result = parser.parse(ctx.args);
11
+ if (result.error) {
12
+ await parser.writeError(result.error, ctx.stderr);
13
+ return 1;
14
+ }
3
15
  await ctx.stdout.writeText(ctx.cwd + `
4
16
  `);
5
17
  return 0;
@@ -8,4 +20,4 @@ export {
8
20
  pwd
9
21
  };
10
22
 
11
- //# debugId=27E332D95222BBDB64756E2164756E21
23
+ //# debugId=581B717F9B17DF9B64756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/commands/pwd/pwd.ts"],
4
4
  "sourcesContent": [
5
- "import type { Command } from \"../../types.mjs\";\n\nexport const pwd: Command = async (ctx) => {\n await ctx.stdout.writeText(ctx.cwd + \"\\n\");\n return 0;\n};\n"
5
+ "import type { Command } from \"../../types.mjs\";\nimport { createFlagParser, type FlagDefinition } from \"../../utils/flag-parser.mjs\";\n\nconst spec = {\n name: \"pwd\",\n flags: [] as FlagDefinition[],\n usage: \"pwd\",\n};\n\nconst parser = createFlagParser(spec, {}, () => {});\n\nexport const pwd: Command = async (ctx) => {\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 await ctx.stdout.writeText(ctx.cwd + \"\\n\");\n return 0;\n};\n"
6
6
  ],
7
- "mappings": ";AAEO,IAAM,MAAe,OAAO,QAAQ;AAAA,EACzC,MAAM,IAAI,OAAO,UAAU,IAAI,MAAM;AAAA,CAAI;AAAA,EACzC,OAAO;AAAA;",
8
- "debugId": "27E332D95222BBDB64756E2164756E21",
7
+ "mappings": ";AACA;AAEA,IAAM,OAAO;AAAA,EACX,MAAM;AAAA,EACN,OAAO,CAAC;AAAA,EACR,OAAO;AACT;AAEA,IAAM,SAAS,iBAAiB,MAAM,CAAC,GAAG,MAAM,EAAE;AAE3C,IAAM,MAAe,OAAO,QAAQ;AAAA,EACzC,MAAM,SAAS,OAAO,MAAM,IAAI,IAAI;AAAA,EAEpC,IAAI,OAAO,OAAO;AAAA,IAChB,MAAM,OAAO,WAAW,OAAO,OAAO,IAAI,MAAM;AAAA,IAChD,OAAO;AAAA,EACT;AAAA,EAEA,MAAM,IAAI,OAAO,UAAU,IAAI,MAAM;AAAA,CAAI;AAAA,EACzC,OAAO;AAAA;",
8
+ "debugId": "581B717F9B17DF9B64756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -1,27 +1,30 @@
1
1
  // src/commands/rm/rm.ts
2
+ import { createFlagParser } from "../../utils/flag-parser.mjs";
3
+ var spec = {
4
+ name: "rm",
5
+ flags: [
6
+ { short: "r", long: "recursive" },
7
+ { short: "R" },
8
+ { short: "f", long: "force" }
9
+ ],
10
+ usage: "rm [-rf] file ..."
11
+ };
12
+ var defaults = { recursive: false, force: false };
13
+ var handler = (flags, flag) => {
14
+ if (flag.short === "r" || flag.short === "R")
15
+ flags.recursive = true;
16
+ if (flag.short === "f")
17
+ flags.force = true;
18
+ };
19
+ var parser = createFlagParser(spec, defaults, handler);
2
20
  var rm = async (ctx) => {
3
- let recursive = false;
4
- let force = false;
5
- const targets = [];
6
- for (const arg of ctx.args) {
7
- if (arg === "-r" || arg === "-R" || arg === "--recursive") {
8
- recursive = true;
9
- } else if (arg === "-f" || arg === "--force") {
10
- force = true;
11
- } else if (arg === "-rf" || arg === "-fr") {
12
- recursive = true;
13
- force = true;
14
- } else if (arg.startsWith("-")) {
15
- for (const flag of arg.slice(1)) {
16
- if (flag === "r" || flag === "R")
17
- recursive = true;
18
- else if (flag === "f")
19
- force = true;
20
- }
21
- } else {
22
- targets.push(arg);
23
- }
21
+ const result = parser.parse(ctx.args);
22
+ if (result.error) {
23
+ await parser.writeError(result.error, ctx.stderr);
24
+ return 1;
24
25
  }
26
+ const { recursive, force } = result.flags;
27
+ const targets = result.args;
25
28
  if (targets.length === 0) {
26
29
  if (!force) {
27
30
  await ctx.stderr.writeText(`rm: missing operand
@@ -49,4 +52,4 @@ export {
49
52
  rm
50
53
  };
51
54
 
52
- //# debugId=98255F03811F1CFC64756E2164756E21
55
+ //# debugId=145008A4147628A064756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/commands/rm/rm.ts"],
4
4
  "sourcesContent": [
5
- "import type { Command } from \"../../types.mjs\";\n\nexport const rm: Command = async (ctx) => {\n let recursive = false;\n let force = false;\n const targets: string[] = [];\n\n for (const arg of ctx.args) {\n if (arg === \"-r\" || arg === \"-R\" || arg === \"--recursive\") {\n recursive = true;\n } else if (arg === \"-f\" || arg === \"--force\") {\n force = true;\n } else if (arg === \"-rf\" || arg === \"-fr\") {\n recursive = true;\n force = true;\n } else if (arg.startsWith(\"-\")) {\n for (const flag of arg.slice(1)) {\n if (flag === \"r\" || flag === \"R\") recursive = true;\n else if (flag === \"f\") force = true;\n }\n } else {\n targets.push(arg);\n }\n }\n\n if (targets.length === 0) {\n if (!force) {\n await ctx.stderr.writeText(\"rm: missing operand\\n\");\n return 1;\n }\n return 0;\n }\n\n for (const target of targets) {\n const path = ctx.fs.resolve(ctx.cwd, target);\n try {\n await ctx.fs.rm(path, { recursive, force });\n } catch (err) {\n if (!force) {\n const message = err instanceof Error ? err.message : String(err);\n await ctx.stderr.writeText(`rm: cannot remove '${target}': ${message}\\n`);\n return 1;\n }\n }\n }\n\n return 0;\n};\n"
5
+ "import type { Command } from \"../../types.mjs\";\nimport { createFlagParser, type FlagDefinition } from \"../../utils/flag-parser.mjs\";\n\ninterface RmFlags {\n recursive: boolean;\n force: boolean;\n}\n\nconst spec = {\n name: \"rm\",\n flags: [\n { short: \"r\", long: \"recursive\" },\n { short: \"R\" },\n { short: \"f\", long: \"force\" },\n ] as FlagDefinition[],\n usage: \"rm [-rf] file ...\",\n};\n\nconst defaults: RmFlags = { recursive: false, force: false };\n\nconst handler = (flags: RmFlags, flag: FlagDefinition) => {\n if (flag.short === \"r\" || flag.short === \"R\") flags.recursive = true;\n if (flag.short === \"f\") flags.force = true;\n};\n\nconst parser = createFlagParser(spec, defaults, handler);\n\nexport const rm: Command = async (ctx) => {\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 { recursive, force } = result.flags;\n const targets = result.args;\n\n if (targets.length === 0) {\n if (!force) {\n await ctx.stderr.writeText(\"rm: missing operand\\n\");\n return 1;\n }\n return 0;\n }\n\n for (const target of targets) {\n const path = ctx.fs.resolve(ctx.cwd, target);\n try {\n await ctx.fs.rm(path, { recursive, force });\n } catch (err) {\n if (!force) {\n const message = err instanceof Error ? err.message : String(err);\n await ctx.stderr.writeText(`rm: cannot remove '${target}': ${message}\\n`);\n return 1;\n }\n }\n }\n\n return 0;\n};\n"
6
6
  ],
7
- "mappings": ";AAEO,IAAM,KAAc,OAAO,QAAQ;AAAA,EACxC,IAAI,YAAY;AAAA,EAChB,IAAI,QAAQ;AAAA,EACZ,MAAM,UAAoB,CAAC;AAAA,EAE3B,WAAW,OAAO,IAAI,MAAM;AAAA,IAC1B,IAAI,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,eAAe;AAAA,MACzD,YAAY;AAAA,IACd,EAAO,SAAI,QAAQ,QAAQ,QAAQ,WAAW;AAAA,MAC5C,QAAQ;AAAA,IACV,EAAO,SAAI,QAAQ,SAAS,QAAQ,OAAO;AAAA,MACzC,YAAY;AAAA,MACZ,QAAQ;AAAA,IACV,EAAO,SAAI,IAAI,WAAW,GAAG,GAAG;AAAA,MAC9B,WAAW,QAAQ,IAAI,MAAM,CAAC,GAAG;AAAA,QAC/B,IAAI,SAAS,OAAO,SAAS;AAAA,UAAK,YAAY;AAAA,QACzC,SAAI,SAAS;AAAA,UAAK,QAAQ;AAAA,MACjC;AAAA,IACF,EAAO;AAAA,MACL,QAAQ,KAAK,GAAG;AAAA;AAAA,EAEpB;AAAA,EAEA,IAAI,QAAQ,WAAW,GAAG;AAAA,IACxB,IAAI,CAAC,OAAO;AAAA,MACV,MAAM,IAAI,OAAO,UAAU;AAAA,CAAuB;AAAA,MAClD,OAAO;AAAA,IACT;AAAA,IACA,OAAO;AAAA,EACT;AAAA,EAEA,WAAW,UAAU,SAAS;AAAA,IAC5B,MAAM,OAAO,IAAI,GAAG,QAAQ,IAAI,KAAK,MAAM;AAAA,IAC3C,IAAI;AAAA,MACF,MAAM,IAAI,GAAG,GAAG,MAAM,EAAE,WAAW,MAAM,CAAC;AAAA,MAC1C,OAAO,KAAK;AAAA,MACZ,IAAI,CAAC,OAAO;AAAA,QACV,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,QAC/D,MAAM,IAAI,OAAO,UAAU,sBAAsB,YAAY;AAAA,CAAW;AAAA,QACxE,OAAO;AAAA,MACT;AAAA;AAAA,EAEJ;AAAA,EAEA,OAAO;AAAA;",
8
- "debugId": "98255F03811F1CFC64756E2164756E21",
7
+ "mappings": ";AACA;AAOA,IAAM,OAAO;AAAA,EACX,MAAM;AAAA,EACN,OAAO;AAAA,IACL,EAAE,OAAO,KAAK,MAAM,YAAY;AAAA,IAChC,EAAE,OAAO,IAAI;AAAA,IACb,EAAE,OAAO,KAAK,MAAM,QAAQ;AAAA,EAC9B;AAAA,EACA,OAAO;AACT;AAEA,IAAM,WAAoB,EAAE,WAAW,OAAO,OAAO,MAAM;AAE3D,IAAM,UAAU,CAAC,OAAgB,SAAyB;AAAA,EACxD,IAAI,KAAK,UAAU,OAAO,KAAK,UAAU;AAAA,IAAK,MAAM,YAAY;AAAA,EAChE,IAAI,KAAK,UAAU;AAAA,IAAK,MAAM,QAAQ;AAAA;AAGxC,IAAM,SAAS,iBAAiB,MAAM,UAAU,OAAO;AAEhD,IAAM,KAAc,OAAO,QAAQ;AAAA,EACxC,MAAM,SAAS,OAAO,MAAM,IAAI,IAAI;AAAA,EAEpC,IAAI,OAAO,OAAO;AAAA,IAChB,MAAM,OAAO,WAAW,OAAO,OAAO,IAAI,MAAM;AAAA,IAChD,OAAO;AAAA,EACT;AAAA,EAEA,QAAQ,WAAW,UAAU,OAAO;AAAA,EACpC,MAAM,UAAU,OAAO;AAAA,EAEvB,IAAI,QAAQ,WAAW,GAAG;AAAA,IACxB,IAAI,CAAC,OAAO;AAAA,MACV,MAAM,IAAI,OAAO,UAAU;AAAA,CAAuB;AAAA,MAClD,OAAO;AAAA,IACT;AAAA,IACA,OAAO;AAAA,EACT;AAAA,EAEA,WAAW,UAAU,SAAS;AAAA,IAC5B,MAAM,OAAO,IAAI,GAAG,QAAQ,IAAI,KAAK,MAAM;AAAA,IAC3C,IAAI;AAAA,MACF,MAAM,IAAI,GAAG,GAAG,MAAM,EAAE,WAAW,MAAM,CAAC;AAAA,MAC1C,OAAO,KAAK;AAAA,MACZ,IAAI,CAAC,OAAO;AAAA,QACV,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,QAC/D,MAAM,IAAI,OAAO,UAAU,sBAAsB,YAAY;AAAA,CAAW;AAAA,QACxE,OAAO;AAAA,MACT;AAAA;AAAA,EAEJ;AAAA,EAEA,OAAO;AAAA;",
8
+ "debugId": "145008A4147628A064756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -114,41 +114,99 @@ function parseArgs(args) {
114
114
  let i = 0;
115
115
  while (i < args.length) {
116
116
  const arg = args[i];
117
- if (arg === "-n") {
118
- options.suppressOutput = true;
117
+ if (arg === "--") {
119
118
  i++;
120
- continue;
119
+ while (i < args.length) {
120
+ const remaining = args[i];
121
+ if (options.commands.length === 0) {
122
+ const parts = splitScriptParts(remaining);
123
+ for (const part of parts) {
124
+ const cmd = parseCommand(part);
125
+ if (cmd)
126
+ options.commands.push(cmd);
127
+ }
128
+ } else {
129
+ files.push(remaining);
130
+ }
131
+ i++;
132
+ }
133
+ break;
121
134
  }
122
- if (arg === "-i") {
123
- options.inPlace = true;
124
- i++;
125
- continue;
135
+ if (arg.startsWith("--")) {
136
+ return {
137
+ options,
138
+ files,
139
+ error: { type: "unrecognized_option", option: arg }
140
+ };
126
141
  }
127
- if (arg === "-e" && args[i + 1] !== undefined) {
128
- const cmd = parseCommand(args[i + 1]);
129
- if (cmd) {
130
- options.commands.push(cmd);
142
+ if (arg.startsWith("-") && arg.length > 1) {
143
+ const flagChars = arg.slice(1);
144
+ for (let j = 0;j < flagChars.length; j++) {
145
+ const char = flagChars[j];
146
+ if (char === "n") {
147
+ options.suppressOutput = true;
148
+ } else if (char === "i") {
149
+ options.inPlace = true;
150
+ } else if (char === "e") {
151
+ const restOfArg = flagChars.slice(j + 1);
152
+ let script;
153
+ if (restOfArg.length > 0) {
154
+ script = restOfArg;
155
+ } else if (i + 1 < args.length) {
156
+ script = args[++i];
157
+ } else {
158
+ return {
159
+ options,
160
+ files,
161
+ error: { type: "missing_value", option: "-e" }
162
+ };
163
+ }
164
+ const cmd = parseCommand(script);
165
+ if (cmd)
166
+ options.commands.push(cmd);
167
+ break;
168
+ } else {
169
+ return {
170
+ options,
171
+ files,
172
+ error: { type: "unrecognized_option", option: `-${char}` }
173
+ };
174
+ }
131
175
  }
132
- i += 2;
176
+ i++;
133
177
  continue;
134
178
  }
135
- if (!arg.startsWith("-")) {
136
- if (options.commands.length === 0) {
137
- const parts = splitScriptParts(arg);
138
- for (const part of parts) {
139
- const cmd = parseCommand(part);
140
- if (cmd) {
141
- options.commands.push(cmd);
142
- }
143
- }
144
- } else {
145
- files.push(arg);
179
+ if (options.commands.length === 0) {
180
+ const parts = splitScriptParts(arg);
181
+ for (const part of parts) {
182
+ const cmd = parseCommand(part);
183
+ if (cmd)
184
+ options.commands.push(cmd);
146
185
  }
186
+ } else {
187
+ files.push(arg);
147
188
  }
148
189
  i++;
149
190
  }
150
191
  return { options, files };
151
192
  }
193
+ function formatError(error) {
194
+ let message;
195
+ if (error.type === "unrecognized_option") {
196
+ if (error.option.startsWith("--")) {
197
+ message = `sed: unrecognized option '${error.option}'
198
+ `;
199
+ } else {
200
+ message = `sed: invalid option -- '${error.option.slice(1)}'
201
+ `;
202
+ }
203
+ } else {
204
+ message = `sed: option '${error.option}' requires an argument
205
+ `;
206
+ }
207
+ return message + `usage: sed [-ni] [-e script] script [file ...]
208
+ `;
209
+ }
152
210
  function applySubstitution(line, cmd) {
153
211
  if (!cmd.pattern)
154
212
  return line;
@@ -191,7 +249,11 @@ function processLine(line, commands, suppressOutput) {
191
249
  return { output: currentLine, deleted: false };
192
250
  }
193
251
  var sed = async (ctx) => {
194
- const { options, files } = parseArgs(ctx.args);
252
+ const { options, files, error } = parseArgs(ctx.args);
253
+ if (error) {
254
+ await ctx.stderr.writeText(formatError(error));
255
+ return 1;
256
+ }
195
257
  if (options.commands.length === 0) {
196
258
  await ctx.stderr.writeText(`sed: missing script
197
259
  `);
@@ -262,4 +324,4 @@ export {
262
324
  sed
263
325
  };
264
326
 
265
- //# debugId=3B08A3537764916864756E2164756E21
327
+ //# debugId=787A27694F93454264756E2164756E21