reset-framework-cli 1.1.2 → 1.1.4

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 (34) hide show
  1. package/LICENSE +20 -20
  2. package/README.md +47 -47
  3. package/package.json +4 -4
  4. package/src/commands/build.js +114 -113
  5. package/src/commands/dev.js +157 -153
  6. package/src/commands/doctor.js +89 -89
  7. package/src/commands/init.js +925 -920
  8. package/src/commands/package.js +49 -44
  9. package/src/index.js +213 -213
  10. package/src/lib/context.js +66 -66
  11. package/src/lib/framework.js +150 -28
  12. package/src/lib/logger.js +11 -11
  13. package/src/lib/output.js +214 -106
  14. package/src/lib/process.js +188 -181
  15. package/src/lib/project.js +559 -475
  16. package/src/lib/toolchain.js +62 -62
  17. package/src/lib/ui.js +244 -244
  18. package/templates/basic/README.md +15 -15
  19. package/templates/basic/frontend/README.md +73 -73
  20. package/templates/basic/frontend/eslint.config.js +23 -23
  21. package/templates/basic/frontend/index.html +13 -13
  22. package/templates/basic/frontend/package.json +31 -31
  23. package/templates/basic/frontend/public/icons.svg +24 -24
  24. package/templates/basic/frontend/src/App.css +216 -138
  25. package/templates/basic/frontend/src/App.tsx +77 -76
  26. package/templates/basic/frontend/src/assets/vite.svg +1 -1
  27. package/templates/basic/frontend/src/index.css +111 -111
  28. package/templates/basic/frontend/src/lib/reset.ts +1 -1
  29. package/templates/basic/frontend/src/main.tsx +10 -10
  30. package/templates/basic/frontend/tsconfig.app.json +28 -28
  31. package/templates/basic/frontend/tsconfig.json +7 -7
  32. package/templates/basic/frontend/tsconfig.node.json +26 -26
  33. package/templates/basic/frontend/vite.config.ts +16 -16
  34. package/templates/basic/reset.config.json +58 -58
@@ -1,63 +1,68 @@
1
1
  import { existsSync } from "node:fs"
2
2
 
3
- import { createMacOSZipArchive } from "../lib/output.js"
3
+ import { createMacOSZipArchive, createWindowsZipArchive } from "../lib/output.js"
4
4
  import {
5
5
  assertAppProject,
6
6
  loadResetConfig,
7
- resolveAppOutputPaths,
8
- resolveAppPaths
9
- } from "../lib/project.js"
10
- import {
11
- createProgress,
12
- printBanner,
13
- printKeyValueTable,
14
- printSection,
15
- printStatusTable
16
- } from "../lib/ui.js"
17
-
7
+ resolveAppOutputPaths,
8
+ resolveAppPaths
9
+ } from "../lib/project.js"
10
+ import {
11
+ createProgress,
12
+ printBanner,
13
+ printKeyValueTable,
14
+ printSection,
15
+ printStatusTable
16
+ } from "../lib/ui.js"
17
+
18
18
  export const description = "Package the built desktop app into a distributable archive"
19
19
 
20
20
  export async function run(context) {
21
21
  const dryRun = Boolean(context.flags["dry-run"])
22
+ const isWindows = process.platform === "win32"
23
+ const archiveBuilder = isWindows ? createWindowsZipArchive : createMacOSZipArchive
24
+ const archiveDescription = isWindows
25
+ ? "Create a Windows zip package from the built app folder"
26
+ : "Create a macOS zip package from the built app bundle"
22
27
  const appPaths = resolveAppPaths(context.projectRoot)
23
28
  assertAppProject(appPaths)
24
-
25
- const config = loadResetConfig(appPaths)
26
- assertAppProject(appPaths, config)
27
- const outputPaths = resolveAppOutputPaths(appPaths, config)
28
-
29
- printBanner("reset-framework-cli package", description)
30
- printSection("Project")
31
- printKeyValueTable([
32
- ["Desktop app", outputPaths.appBundlePath],
33
- ["Archive", outputPaths.zipPath]
34
- ])
35
- console.log("")
29
+
30
+ const config = loadResetConfig(appPaths)
31
+ assertAppProject(appPaths, config)
32
+ const outputPaths = resolveAppOutputPaths(appPaths, config)
33
+
34
+ printBanner("reset-framework-cli package", description)
35
+ printSection("Project")
36
+ printKeyValueTable([
37
+ ["Desktop app", outputPaths.appBundlePath],
38
+ ["Archive", outputPaths.zipPath]
39
+ ])
40
+ console.log("")
36
41
 
37
42
  printSection("Plan")
38
43
  printStatusTable([
39
- ["ready", "Archive", "Create a macOS zip package from the built app bundle"]
44
+ ["ready", "Archive", archiveDescription]
40
45
  ])
41
-
42
- if (!existsSync(outputPaths.appBundlePath) && !dryRun) {
43
- throw new Error(
44
- `Missing built app bundle at ${outputPaths.appBundlePath}. Run 'reset-framework-cli build' first.`
45
- )
46
- }
47
-
48
- if (dryRun) {
49
- console.log("")
50
- printSection("Dry run")
51
- printStatusTable([["plan", "Package", "No archive will be written"]])
52
- return
53
- }
46
+
47
+ if (!existsSync(outputPaths.appBundlePath) && !dryRun) {
48
+ throw new Error(
49
+ `Missing built app bundle at ${outputPaths.appBundlePath}. Run 'reset-framework-cli build' first.`
50
+ )
51
+ }
52
+
53
+ if (dryRun) {
54
+ console.log("")
55
+ printSection("Dry run")
56
+ printStatusTable([["plan", "Package", "No archive will be written"]])
57
+ return
58
+ }
54
59
 
55
60
  console.log("")
56
61
  const progress = createProgress(1, "Package")
57
- await createMacOSZipArchive(outputPaths, { dryRun })
62
+ await archiveBuilder(outputPaths, { dryRun })
58
63
  progress.tick("Archive created")
59
-
60
- console.log("")
61
- printSection("Result")
62
- printStatusTable([["done", "Package", outputPaths.zipPath]])
63
- }
64
+
65
+ console.log("")
66
+ printSection("Result")
67
+ printStatusTable([["done", "Package", outputPaths.zipPath]])
68
+ }
package/src/index.js CHANGED
@@ -1,214 +1,214 @@
1
1
  #!/usr/bin/env node
2
-
3
- import { run as runBuild, description as buildDescription } from "./commands/build.js"
4
- import { run as runCreateApp, description as createAppDescription } from "./commands/init.js"
5
- import { run as runDev, description as devDescription } from "./commands/dev.js"
6
- import { run as runDoctor, description as doctorDescription } from "./commands/doctor.js"
7
- import { run as runInit, description as initDescription } from "./commands/init.js"
8
- import { run as runPackage, description as packageDescription } from "./commands/package.js"
9
- import { createCommandContext } from "./lib/context.js"
10
- import { logger } from "./lib/logger.js"
11
- import {
12
- printBanner,
13
- printCommandList,
14
- printKeyValueTable,
15
- printSection
16
- } from "./lib/ui.js"
17
-
18
- const commands = {
19
- build: {
20
- description: buildDescription,
21
- usage: "reset-framework-cli build [--skip-frontend] [--skip-runtime] [--skip-stage] [--dry-run]",
22
- options: [
23
- ["--skip-frontend", "Skip the frontend build step"],
24
- ["--skip-runtime", "Skip the release runtime build"],
25
- ["--skip-stage", "Skip assembling the final .app bundle"],
26
- ["--dry-run", "Print the build plan without running commands"]
27
- ],
28
- examples: [
29
- "reset-framework-cli build",
30
- "reset-framework-cli build --dry-run"
31
- ],
32
- run: runBuild
33
- },
34
- "create-app": {
35
- description: createAppDescription,
36
- usage: "reset-framework-cli create-app <directory> [options]",
37
- options: [
38
- ["--template <name>", "Choose a starter template"],
39
- ["--tailwind", "Use the Tailwind CSS starter"],
40
- ["--no-tailwind", "Keep the plain CSS starter"],
41
- ["--frontend-dir <path>", "Use a custom relative frontend directory"],
42
- ["--flat", "Place the frontend directly in the project root"],
43
- ["--product-name <name>", "Override the generated product name"],
44
- ["--app-id <id>", "Override the generated app identifier"],
45
- ["--package-manager <name>", "Choose npm, pnpm, yarn, or bun for dependency install"],
46
- ["--no-install", "Skip installing frontend dependencies after scaffolding"],
47
- ["--force", "Allow scaffolding into an existing directory"],
48
- ["--yes", "Skip the interactive questionnaire and use defaults"],
49
- ["--no-prompt", "Disable prompts even in an interactive terminal"],
50
- ["--dry-run", "Preview the scaffold plan without writing files"]
51
- ],
52
- examples: [
53
- "reset-framework-cli create-app my-app",
54
- "reset-framework-cli create-app my-app --tailwind",
55
- "reset-framework-cli create-app my-app --flat --yes"
56
- ],
57
- run: runCreateApp
58
- },
59
- dev: {
60
- description: devDescription,
61
- usage: "reset-framework-cli dev [--skip-frontend] [--skip-runtime] [--no-open] [--dry-run]",
62
- options: [
63
- ["--skip-frontend", "Reuse an already running frontend dev server"],
64
- ["--skip-runtime", "Reuse an existing native dev build"],
65
- ["--no-open", "Do not launch the desktop window after startup"],
66
- ["--dry-run", "Print the dev plan without starting processes"]
67
- ],
68
- examples: [
69
- "reset-framework-cli dev",
70
- "reset-framework-cli dev --skip-runtime"
71
- ],
72
- run: runDev
73
- },
74
- doctor: {
75
- description: doctorDescription,
76
- usage: "reset-framework-cli doctor",
77
- options: [],
78
- examples: ["reset-framework-cli doctor"],
79
- run: runDoctor
80
- },
81
- init: {
82
- description: `${initDescription} (alias for create-app)`,
83
- usage: "reset-framework-cli init <directory> [options]",
84
- options: [
85
- ["--template <name>", "Choose a starter template"],
86
- ["--tailwind", "Use the Tailwind CSS starter"],
87
- ["--no-tailwind", "Keep the plain CSS starter"],
88
- ["--frontend-dir <path>", "Use a custom relative frontend directory"],
89
- ["--flat", "Place the frontend directly in the project root"],
90
- ["--product-name <name>", "Override the generated product name"],
91
- ["--app-id <id>", "Override the generated app identifier"],
92
- ["--package-manager <name>", "Choose npm, pnpm, yarn, or bun for dependency install"],
93
- ["--no-install", "Skip installing frontend dependencies after scaffolding"],
94
- ["--force", "Allow scaffolding into an existing directory"],
95
- ["--yes", "Skip the interactive questionnaire and use defaults"],
96
- ["--no-prompt", "Disable prompts even in an interactive terminal"],
97
- ["--dry-run", "Preview the scaffold plan without writing files"]
98
- ],
99
- examples: ["reset-framework-cli init my-app"],
100
- run: runInit
101
- },
102
- package: {
103
- description: packageDescription,
104
- usage: "reset-framework-cli package [--dry-run]",
105
- options: [
106
- ["--dry-run", "Preview the archive step without writing the package file"]
107
- ],
108
- examples: [
109
- "reset-framework-cli package"
110
- ],
111
- run: runPackage
112
- }
113
- }
114
-
115
- const coreWorkflow = [
116
- "reset-framework-cli create-app my-app",
117
- "cd my-app",
118
- "reset-framework-cli dev",
119
- "reset-framework-cli build",
120
- "reset-framework-cli package"
121
- ]
122
-
123
- function getVisibleCommands() {
124
- return ["create-app", "dev", "build", "package", "doctor"].map((name) => ({
125
- name,
126
- description: commands[name].description
127
- }))
128
- }
129
-
130
- function printGeneralHelp() {
131
- printBanner("reset-framework-cli", "Developer-facing orchestration for Reset Framework desktop apps.")
132
-
133
- printSection("Usage")
134
- console.log(" reset-framework-cli <command> [options]")
135
- console.log("")
136
-
137
- printSection("Core workflow")
138
- for (const step of coreWorkflow) {
139
- console.log(` ${step}`)
140
- }
141
- console.log("")
142
-
143
- printSection("Commands")
144
- printCommandList(getVisibleCommands())
145
- console.log("")
146
- console.log(" reset-framework-cli help <command> Show command-specific help")
147
- console.log("")
148
- printSection("Global shortcuts")
149
- printKeyValueTable([
150
- ["-h, --help", "Show help for the current command"],
151
- ["-y, --yes", "Accept defaults in create-app without prompts"]
152
- ])
153
- }
154
-
155
- function printCommandHelp(name) {
156
- const command = commands[name]
157
-
158
- if (!command) {
159
- logger.error(`Unknown command: ${name}`)
160
- printGeneralHelp()
161
- process.exit(1)
162
- }
163
-
164
- printBanner(`reset-framework-cli ${name}`, command.description)
165
-
166
- printSection("Usage")
167
- console.log(` ${command.usage}`)
168
-
169
- if (command.options.length > 0) {
170
- console.log("")
171
- printSection("Options")
172
- printKeyValueTable(command.options)
173
- }
174
-
175
- if (command.examples.length > 0) {
176
- console.log("")
177
- printSection("Examples")
178
- for (const example of command.examples) {
179
- console.log(` ${example}`)
180
- }
181
- }
182
- }
183
-
184
- const context = createCommandContext(process.argv.slice(2))
185
-
186
- if (context.command === "help") {
187
- if (context.args[0]) {
188
- printCommandHelp(context.args[0])
189
- } else {
190
- printGeneralHelp()
191
- }
192
- process.exit(0)
193
- }
194
-
195
- if (context.flags.help) {
196
- printCommandHelp(context.command)
197
- process.exit(0)
198
- }
199
-
200
- const command = commands[context.command]
201
-
202
- if (!command) {
203
- logger.error(`Unknown command: ${context.command}`)
204
- printGeneralHelp()
205
- process.exit(1)
206
- }
207
-
208
- try {
209
- await command.run(context)
210
- } catch (error) {
211
- const message = error instanceof Error ? error.message : String(error)
212
- logger.error(message)
213
- process.exit(1)
214
- }
2
+
3
+ import { run as runBuild, description as buildDescription } from "./commands/build.js"
4
+ import { run as runCreateApp, description as createAppDescription } from "./commands/init.js"
5
+ import { run as runDev, description as devDescription } from "./commands/dev.js"
6
+ import { run as runDoctor, description as doctorDescription } from "./commands/doctor.js"
7
+ import { run as runInit, description as initDescription } from "./commands/init.js"
8
+ import { run as runPackage, description as packageDescription } from "./commands/package.js"
9
+ import { createCommandContext } from "./lib/context.js"
10
+ import { logger } from "./lib/logger.js"
11
+ import {
12
+ printBanner,
13
+ printCommandList,
14
+ printKeyValueTable,
15
+ printSection
16
+ } from "./lib/ui.js"
17
+
18
+ const commands = {
19
+ build: {
20
+ description: buildDescription,
21
+ usage: "reset-framework-cli build [--skip-frontend] [--skip-runtime] [--skip-stage] [--dry-run]",
22
+ options: [
23
+ ["--skip-frontend", "Skip the frontend build step"],
24
+ ["--skip-runtime", "Skip the release runtime build"],
25
+ ["--skip-stage", "Skip assembling the final .app bundle"],
26
+ ["--dry-run", "Print the build plan without running commands"]
27
+ ],
28
+ examples: [
29
+ "reset-framework-cli build",
30
+ "reset-framework-cli build --dry-run"
31
+ ],
32
+ run: runBuild
33
+ },
34
+ "create-app": {
35
+ description: createAppDescription,
36
+ usage: "reset-framework-cli create-app <directory> [options]",
37
+ options: [
38
+ ["--template <name>", "Choose a starter template"],
39
+ ["--tailwind", "Use the Tailwind CSS starter"],
40
+ ["--no-tailwind", "Keep the plain CSS starter"],
41
+ ["--frontend-dir <path>", "Use a custom relative frontend directory"],
42
+ ["--flat", "Place the frontend directly in the project root"],
43
+ ["--product-name <name>", "Override the generated product name"],
44
+ ["--app-id <id>", "Override the generated app identifier"],
45
+ ["--package-manager <name>", "Choose npm, pnpm, yarn, or bun for dependency install"],
46
+ ["--no-install", "Skip installing frontend dependencies after scaffolding"],
47
+ ["--force", "Allow scaffolding into an existing directory"],
48
+ ["--yes", "Skip the interactive questionnaire and use defaults"],
49
+ ["--no-prompt", "Disable prompts even in an interactive terminal"],
50
+ ["--dry-run", "Preview the scaffold plan without writing files"]
51
+ ],
52
+ examples: [
53
+ "reset-framework-cli create-app my-app",
54
+ "reset-framework-cli create-app my-app --tailwind",
55
+ "reset-framework-cli create-app my-app --flat --yes"
56
+ ],
57
+ run: runCreateApp
58
+ },
59
+ dev: {
60
+ description: devDescription,
61
+ usage: "reset-framework-cli dev [--skip-frontend] [--skip-runtime] [--no-open] [--dry-run]",
62
+ options: [
63
+ ["--skip-frontend", "Reuse an already running frontend dev server"],
64
+ ["--skip-runtime", "Reuse an existing native dev build"],
65
+ ["--no-open", "Do not launch the desktop window after startup"],
66
+ ["--dry-run", "Print the dev plan without starting processes"]
67
+ ],
68
+ examples: [
69
+ "reset-framework-cli dev",
70
+ "reset-framework-cli dev --skip-runtime"
71
+ ],
72
+ run: runDev
73
+ },
74
+ doctor: {
75
+ description: doctorDescription,
76
+ usage: "reset-framework-cli doctor",
77
+ options: [],
78
+ examples: ["reset-framework-cli doctor"],
79
+ run: runDoctor
80
+ },
81
+ init: {
82
+ description: `${initDescription} (alias for create-app)`,
83
+ usage: "reset-framework-cli init <directory> [options]",
84
+ options: [
85
+ ["--template <name>", "Choose a starter template"],
86
+ ["--tailwind", "Use the Tailwind CSS starter"],
87
+ ["--no-tailwind", "Keep the plain CSS starter"],
88
+ ["--frontend-dir <path>", "Use a custom relative frontend directory"],
89
+ ["--flat", "Place the frontend directly in the project root"],
90
+ ["--product-name <name>", "Override the generated product name"],
91
+ ["--app-id <id>", "Override the generated app identifier"],
92
+ ["--package-manager <name>", "Choose npm, pnpm, yarn, or bun for dependency install"],
93
+ ["--no-install", "Skip installing frontend dependencies after scaffolding"],
94
+ ["--force", "Allow scaffolding into an existing directory"],
95
+ ["--yes", "Skip the interactive questionnaire and use defaults"],
96
+ ["--no-prompt", "Disable prompts even in an interactive terminal"],
97
+ ["--dry-run", "Preview the scaffold plan without writing files"]
98
+ ],
99
+ examples: ["reset-framework-cli init my-app"],
100
+ run: runInit
101
+ },
102
+ package: {
103
+ description: packageDescription,
104
+ usage: "reset-framework-cli package [--dry-run]",
105
+ options: [
106
+ ["--dry-run", "Preview the archive step without writing the package file"]
107
+ ],
108
+ examples: [
109
+ "reset-framework-cli package"
110
+ ],
111
+ run: runPackage
112
+ }
113
+ }
114
+
115
+ const coreWorkflow = [
116
+ "reset-framework-cli create-app my-app",
117
+ "cd my-app",
118
+ "reset-framework-cli dev",
119
+ "reset-framework-cli build",
120
+ "reset-framework-cli package"
121
+ ]
122
+
123
+ function getVisibleCommands() {
124
+ return ["create-app", "dev", "build", "package", "doctor"].map((name) => ({
125
+ name,
126
+ description: commands[name].description
127
+ }))
128
+ }
129
+
130
+ function printGeneralHelp() {
131
+ printBanner("reset-framework-cli", "Developer-facing orchestration for Reset Framework desktop apps.")
132
+
133
+ printSection("Usage")
134
+ console.log(" reset-framework-cli <command> [options]")
135
+ console.log("")
136
+
137
+ printSection("Core workflow")
138
+ for (const step of coreWorkflow) {
139
+ console.log(` ${step}`)
140
+ }
141
+ console.log("")
142
+
143
+ printSection("Commands")
144
+ printCommandList(getVisibleCommands())
145
+ console.log("")
146
+ console.log(" reset-framework-cli help <command> Show command-specific help")
147
+ console.log("")
148
+ printSection("Global shortcuts")
149
+ printKeyValueTable([
150
+ ["-h, --help", "Show help for the current command"],
151
+ ["-y, --yes", "Accept defaults in create-app without prompts"]
152
+ ])
153
+ }
154
+
155
+ function printCommandHelp(name) {
156
+ const command = commands[name]
157
+
158
+ if (!command) {
159
+ logger.error(`Unknown command: ${name}`)
160
+ printGeneralHelp()
161
+ process.exit(1)
162
+ }
163
+
164
+ printBanner(`reset-framework-cli ${name}`, command.description)
165
+
166
+ printSection("Usage")
167
+ console.log(` ${command.usage}`)
168
+
169
+ if (command.options.length > 0) {
170
+ console.log("")
171
+ printSection("Options")
172
+ printKeyValueTable(command.options)
173
+ }
174
+
175
+ if (command.examples.length > 0) {
176
+ console.log("")
177
+ printSection("Examples")
178
+ for (const example of command.examples) {
179
+ console.log(` ${example}`)
180
+ }
181
+ }
182
+ }
183
+
184
+ const context = createCommandContext(process.argv.slice(2))
185
+
186
+ if (context.command === "help") {
187
+ if (context.args[0]) {
188
+ printCommandHelp(context.args[0])
189
+ } else {
190
+ printGeneralHelp()
191
+ }
192
+ process.exit(0)
193
+ }
194
+
195
+ if (context.flags.help) {
196
+ printCommandHelp(context.command)
197
+ process.exit(0)
198
+ }
199
+
200
+ const command = commands[context.command]
201
+
202
+ if (!command) {
203
+ logger.error(`Unknown command: ${context.command}`)
204
+ printGeneralHelp()
205
+ process.exit(1)
206
+ }
207
+
208
+ try {
209
+ await command.run(context)
210
+ } catch (error) {
211
+ const message = error instanceof Error ? error.message : String(error)
212
+ logger.error(message)
213
+ process.exit(1)
214
+ }
@@ -1,66 +1,66 @@
1
- import path from "node:path"
2
-
3
- const shortFlagAliases = {
4
- h: "help",
5
- y: "yes"
6
- }
7
-
8
- function parseArgv(argv) {
9
- const [command = "help", ...rest] = argv
10
- const args = []
11
- const flags = {}
12
-
13
- for (let index = 0; index < rest.length; index += 1) {
14
- const token = rest[index]
15
-
16
- if (!token.startsWith("-")) {
17
- args.push(token)
18
- continue
19
- }
20
-
21
- if (token.startsWith("--")) {
22
- const body = token.slice(2)
23
- const separatorIndex = body.indexOf("=")
24
- const key = separatorIndex === -1 ? body : body.slice(0, separatorIndex)
25
- const inlineValue = separatorIndex === -1 ? undefined : body.slice(separatorIndex + 1)
26
- const next = rest[index + 1]
27
-
28
- if (inlineValue !== undefined) {
29
- flags[key] = inlineValue
30
- continue
31
- }
32
-
33
- if (!next || next.startsWith("-")) {
34
- flags[key] = true
35
- continue
36
- }
37
-
38
- flags[key] = next
39
- index += 1
40
- continue
41
- }
42
-
43
- const shortFlags = token.slice(1).split("")
44
- for (const flag of shortFlags) {
45
- const alias = shortFlagAliases[flag]
46
- if (!alias) {
47
- flags[flag] = true
48
- continue
49
- }
50
-
51
- flags[alias] = true
52
- }
53
- }
54
-
55
- return { command, args, flags }
56
- }
57
-
58
- export function createCommandContext(argv, cwd = process.cwd()) {
59
- const parsed = parseArgv(argv)
60
-
61
- return {
62
- ...parsed,
63
- cwd,
64
- projectRoot: path.resolve(cwd)
65
- }
66
- }
1
+ import path from "node:path"
2
+
3
+ const shortFlagAliases = {
4
+ h: "help",
5
+ y: "yes"
6
+ }
7
+
8
+ function parseArgv(argv) {
9
+ const [command = "help", ...rest] = argv
10
+ const args = []
11
+ const flags = {}
12
+
13
+ for (let index = 0; index < rest.length; index += 1) {
14
+ const token = rest[index]
15
+
16
+ if (!token.startsWith("-")) {
17
+ args.push(token)
18
+ continue
19
+ }
20
+
21
+ if (token.startsWith("--")) {
22
+ const body = token.slice(2)
23
+ const separatorIndex = body.indexOf("=")
24
+ const key = separatorIndex === -1 ? body : body.slice(0, separatorIndex)
25
+ const inlineValue = separatorIndex === -1 ? undefined : body.slice(separatorIndex + 1)
26
+ const next = rest[index + 1]
27
+
28
+ if (inlineValue !== undefined) {
29
+ flags[key] = inlineValue
30
+ continue
31
+ }
32
+
33
+ if (!next || next.startsWith("-")) {
34
+ flags[key] = true
35
+ continue
36
+ }
37
+
38
+ flags[key] = next
39
+ index += 1
40
+ continue
41
+ }
42
+
43
+ const shortFlags = token.slice(1).split("")
44
+ for (const flag of shortFlags) {
45
+ const alias = shortFlagAliases[flag]
46
+ if (!alias) {
47
+ flags[flag] = true
48
+ continue
49
+ }
50
+
51
+ flags[alias] = true
52
+ }
53
+ }
54
+
55
+ return { command, args, flags }
56
+ }
57
+
58
+ export function createCommandContext(argv, cwd = process.cwd()) {
59
+ const parsed = parseArgv(argv)
60
+
61
+ return {
62
+ ...parsed,
63
+ cwd,
64
+ projectRoot: path.resolve(cwd)
65
+ }
66
+ }