@mandujs/cli 0.9.22 β 0.9.23
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.
- package/README.ko.md +57 -4
- package/README.md +47 -15
- package/package.json +1 -1
- package/src/commands/check.ts +41 -5
- package/src/commands/contract.ts +135 -9
- package/src/commands/dev.ts +155 -95
- package/src/commands/guard-arch.ts +39 -9
- package/src/commands/guard-check.ts +3 -3
- package/src/commands/init.ts +264 -9
- package/src/commands/monitor.ts +21 -0
- package/src/main.ts +386 -344
- package/templates/default/app/globals.css +37 -0
- package/templates/default/app/layout.tsx +27 -0
- package/templates/default/app/page.tsx +27 -49
- package/templates/default/package.json +15 -6
- package/templates/default/postcss.config.js +6 -0
- package/templates/default/src/client/app/index.ts +1 -0
- package/templates/default/src/client/entities/index.ts +1 -0
- package/templates/default/src/client/features/index.ts +1 -0
- package/templates/default/src/client/pages/index.ts +1 -0
- package/templates/default/src/client/shared/index.ts +1 -0
- package/templates/default/src/client/shared/lib/utils.ts +16 -0
- package/templates/default/src/client/shared/ui/button.tsx +57 -0
- package/templates/default/src/client/shared/ui/card.tsx +78 -0
- package/templates/default/src/client/shared/ui/index.ts +21 -0
- package/templates/default/src/client/shared/ui/input.tsx +24 -0
- package/templates/default/src/client/widgets/index.ts +1 -0
- package/templates/default/src/server/api/index.ts +1 -0
- package/templates/default/src/server/application/index.ts +1 -0
- package/templates/default/src/server/core/index.ts +1 -0
- package/templates/default/src/server/domain/index.ts +1 -0
- package/templates/default/src/server/infra/index.ts +1 -0
- package/templates/default/src/shared/contracts/index.ts +1 -0
- package/templates/default/src/shared/env/index.ts +1 -0
- package/templates/default/src/shared/schema/index.ts +1 -0
- package/templates/default/src/shared/types/index.ts +1 -0
- package/templates/default/src/shared/utils/client/index.ts +1 -0
- package/templates/default/src/shared/utils/server/index.ts +1 -0
- package/templates/default/tailwind.config.ts +64 -0
- package/templates/default/tsconfig.json +14 -3
package/src/main.ts
CHANGED
|
@@ -1,74 +1,81 @@
|
|
|
1
|
-
#!/usr/bin/env bun
|
|
2
|
-
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
3
|
import { specUpsert } from "./commands/spec-upsert";
|
|
4
4
|
import { generateApply } from "./commands/generate-apply";
|
|
5
5
|
import { guardCheck } from "./commands/guard-check";
|
|
6
6
|
import { guardArch } from "./commands/guard-arch";
|
|
7
7
|
import { check } from "./commands/check";
|
|
8
8
|
import { dev } from "./commands/dev";
|
|
9
|
-
import { init } from "./commands/init";
|
|
10
|
-
import { build } from "./commands/build";
|
|
11
|
-
import { contractCreate, contractValidate } from "./commands/contract";
|
|
12
|
-
import { openAPIGenerate, openAPIServe } from "./commands/openapi";
|
|
13
|
-
import {
|
|
14
|
-
changeBegin,
|
|
15
|
-
changeCommit,
|
|
16
|
-
changeRollback,
|
|
17
|
-
changeStatus,
|
|
18
|
-
changeList,
|
|
19
|
-
changePrune,
|
|
20
|
-
} from "./commands/change";
|
|
21
|
-
import { doctor } from "./commands/doctor";
|
|
9
|
+
import { init } from "./commands/init";
|
|
10
|
+
import { build } from "./commands/build";
|
|
11
|
+
import { contractCreate, contractValidate, contractBuild, contractDiff } from "./commands/contract";
|
|
12
|
+
import { openAPIGenerate, openAPIServe } from "./commands/openapi";
|
|
13
|
+
import {
|
|
14
|
+
changeBegin,
|
|
15
|
+
changeCommit,
|
|
16
|
+
changeRollback,
|
|
17
|
+
changeStatus,
|
|
18
|
+
changeList,
|
|
19
|
+
changePrune,
|
|
20
|
+
} from "./commands/change";
|
|
21
|
+
import { doctor } from "./commands/doctor";
|
|
22
22
|
import { watch } from "./commands/watch";
|
|
23
23
|
import { brainSetup, brainStatus } from "./commands/brain";
|
|
24
24
|
import { routesGenerate, routesList, routesWatch } from "./commands/routes";
|
|
25
25
|
import { monitor } from "./commands/monitor";
|
|
26
|
-
|
|
27
|
-
const HELP_TEXT = `
|
|
28
|
-
π₯ Mandu CLI - Agent-Native Fullstack Framework
|
|
29
|
-
|
|
30
|
-
Usage: bunx mandu <command> [options]
|
|
31
|
-
|
|
26
|
+
|
|
27
|
+
const HELP_TEXT = `
|
|
28
|
+
π₯ Mandu CLI - Agent-Native Fullstack Framework
|
|
29
|
+
|
|
30
|
+
Usage: bunx mandu <command> [options]
|
|
31
|
+
|
|
32
32
|
Commands:
|
|
33
|
-
init μ νλ‘μ νΈ μμ±
|
|
33
|
+
init μ νλ‘μ νΈ μμ± (Tailwind + shadcn/ui κΈ°λ³Έ ν¬ν¨)
|
|
34
34
|
check FS Routes + Guard ν΅ν© κ²μ¬
|
|
35
35
|
routes generate FS Routes μ€μΊ λ° λ§€λνμ€νΈ μμ±
|
|
36
36
|
routes list νμ¬ λΌμ°νΈ λͺ©λ‘ μΆλ ₯
|
|
37
37
|
routes watch μ€μκ° λΌμ°νΈ κ°μ
|
|
38
38
|
dev κ°λ° μλ² μ€ν (FS Routes + Guard κΈ°λ³Έ)
|
|
39
39
|
dev --no-guard Guard κ°μ λΉνμ±ν
|
|
40
|
-
build ν΄λΌμ΄μΈνΈ λ²λ€ λΉλ (Hydration)
|
|
41
|
-
guard
|
|
42
|
-
guard arch μν€ν
μ² μλ° κ²μ¬ (FSD/Clean/Hexagonal)
|
|
43
|
-
guard
|
|
44
|
-
guard arch --
|
|
45
|
-
guard arch --
|
|
46
|
-
guard arch --
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
40
|
+
build ν΄λΌμ΄μΈνΈ λ²λ€ λΉλ (Hydration)
|
|
41
|
+
guard μν€ν
μ² μλ° κ²μ¬ (κΈ°λ³Έ)
|
|
42
|
+
guard arch μν€ν
μ² μλ° κ²μ¬ (FSD/Clean/Hexagonal)
|
|
43
|
+
guard legacy λ κ±°μ Spec Guard κ²μ¬
|
|
44
|
+
guard arch --watch μ€μκ° μν€ν
μ² κ°μ
|
|
45
|
+
guard arch --list-presets μ¬μ© κ°λ₯ν ν리μ
λͺ©λ‘
|
|
46
|
+
guard arch --output report.md 리ν¬νΈ νμΌ μμ±
|
|
47
|
+
guard arch --show-trend νΈλ λ λΆμ νμ
|
|
48
|
+
spec-upsert Spec νμΌ κ²μ¦ λ° lock κ°±μ (λ κ±°μ)
|
|
49
|
+
generate Specμμ μ½λ μμ± (λ κ±°μ)
|
|
50
|
+
|
|
51
|
+
doctor Guard μ€ν¨ λΆμ + ν¨μΉ μ μ (Brain)
|
|
51
52
|
watch μ€μκ° νμΌ κ°μ - κ²½κ³ λ§ (Brain)
|
|
52
53
|
monitor MCP Activity Monitor λ‘κ·Έ μ€νΈλ¦Ό
|
|
53
54
|
|
|
54
55
|
brain setup sLLM μ€μ (μ ν)
|
|
55
|
-
brain status Brain μν νμΈ
|
|
56
|
-
|
|
57
|
-
contract create <routeId> λΌμ°νΈμ λν Contract μμ±
|
|
58
|
-
contract validate Contract-Slot μΌκ΄μ± κ²μ¦
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
change
|
|
66
|
-
change
|
|
67
|
-
change
|
|
68
|
-
change
|
|
69
|
-
|
|
56
|
+
brain status Brain μν νμΈ
|
|
57
|
+
|
|
58
|
+
contract create <routeId> λΌμ°νΈμ λν Contract μμ±
|
|
59
|
+
contract validate Contract-Slot μΌκ΄μ± κ²μ¦
|
|
60
|
+
contract build Contract λ μ§μ€νΈλ¦¬ μμ±
|
|
61
|
+
contract diff Contract λ³κ²½μ¬ν λΉκ΅
|
|
62
|
+
|
|
63
|
+
openapi generate OpenAPI 3.0 μ€ν μμ±
|
|
64
|
+
openapi serve Swagger UI λ‘컬 μλ² μ€ν
|
|
65
|
+
|
|
66
|
+
change begin λ³κ²½ νΈλμμ
μμ (μ€λ
μ· μμ±)
|
|
67
|
+
change commit λ³κ²½ νμ
|
|
68
|
+
change rollback μ€λ
μ·μΌλ‘ 볡μ
|
|
69
|
+
change status νμ¬ νΈλμμ
μν
|
|
70
|
+
change list λ³κ²½ μ΄λ ₯ μ‘°ν
|
|
71
|
+
change prune μ€λλ μ€λ
μ· μ 리
|
|
72
|
+
|
|
70
73
|
Options:
|
|
71
74
|
--name <name> init μ νλ‘μ νΈ μ΄λ¦ (κΈ°λ³Έ: my-mandu-app)
|
|
75
|
+
--css <framework> init μ CSS νλ μμν¬: tailwind, panda, none (κΈ°λ³Έ: tailwind)
|
|
76
|
+
--ui <library> init μ UI λΌμ΄λΈλ¬λ¦¬: shadcn, ark, none (κΈ°λ³Έ: shadcn)
|
|
77
|
+
--theme init μ λ€ν¬λͺ¨λ ν
λ§ μμ€ν
μΆκ°
|
|
78
|
+
--minimal init μ CSS/UI μμ΄ μ΅μ ν
νλ¦Ώ μμ± (--css none --ui none)
|
|
72
79
|
--file <path> spec-upsert μ μ¬μ©ν spec νμΌ κ²½λ‘
|
|
73
80
|
--port <port> dev/openapi serve ν¬νΈ (κΈ°λ³Έ: 3000/8080)
|
|
74
81
|
--guard dev μ Architecture Guard μ€μκ° κ°μ νμ±ν (κΈ°λ³Έ: ON)
|
|
@@ -78,131 +85,144 @@ Options:
|
|
|
78
85
|
--legacy FS Routes λΉνμ±ν (λ κ±°μ λͺ¨λ)
|
|
79
86
|
--no-auto-correct guard μ μλ μμ λΉνμ±ν
|
|
80
87
|
--preset <name> guard/check ν리μ
(κΈ°λ³Έ: mandu) - fsd, clean, hexagonal, atomic μ ν κ°λ₯
|
|
81
|
-
--ci guard/check CI λͺ¨λ (
|
|
88
|
+
--ci guard/check CI λͺ¨λ (warningλ μ€ν¨ μ²λ¦¬)
|
|
82
89
|
--quiet guard/check μμ½λ§ μΆλ ₯
|
|
83
|
-
--report-format guard arch 리ν¬νΈ νμ: json, markdown, html
|
|
84
|
-
--save-stats guard arch ν΅κ³ μ μ₯ (νΈλ λ λΆμμ©)
|
|
85
|
-
--show-trend guard arch νΈλ λ λΆμ νμ
|
|
86
|
-
--minify build μ μ½λ μμΆ
|
|
87
|
-
--sourcemap build μ μμ€λ§΅ μμ±
|
|
90
|
+
--report-format guard arch 리ν¬νΈ νμ: json, markdown, html
|
|
91
|
+
--save-stats guard arch ν΅κ³ μ μ₯ (νΈλ λ λΆμμ©)
|
|
92
|
+
--show-trend guard arch νΈλ λ λΆμ νμ
|
|
93
|
+
--minify build μ μ½λ μμΆ
|
|
94
|
+
--sourcemap build μ μμ€λ§΅ μμ±
|
|
88
95
|
--watch build/guard arch νμΌ κ°μ λͺ¨λ
|
|
89
96
|
--summary monitor μμ½ μΆλ ₯ (JSON λ‘κ·Έμμλ§)
|
|
90
97
|
--since <duration> monitor μμ½ κΈ°κ° (μ: 5m, 30s, 1h)
|
|
91
98
|
--follow <bool> monitor follow λͺ¨λ (κΈ°λ³Έ: true)
|
|
92
99
|
--file <path> monitor λ‘κ·Έ νμΌ μ§μ μ§μ
|
|
93
100
|
--message <msg> change begin μ μ€λͺ
λ©μμ§
|
|
94
|
-
--id <id> change rollback μ νΉμ λ³κ²½ ID
|
|
95
|
-
--keep <n> change prune μ μ μ§ν μ€λ
μ· μ (κΈ°λ³Έ: 5)
|
|
96
|
-
--output <path> openapi/doctor μΆλ ₯ κ²½λ‘
|
|
101
|
+
--id <id> change rollback μ νΉμ λ³κ²½ ID
|
|
102
|
+
--keep <n> change prune μ μ μ§ν μ€λ
μ· μ (κΈ°λ³Έ: 5)
|
|
103
|
+
--output <path> openapi/doctor μΆλ ₯ κ²½λ‘
|
|
104
|
+
--from <path> contract diff κΈ°μ€ λ μ§μ€νΈλ¦¬ κ²½λ‘
|
|
105
|
+
--to <path> contract diff λμ λ μ§μ€νΈλ¦¬ κ²½λ‘
|
|
106
|
+
--json contract diff κ²°κ³Ό JSON μΆλ ₯
|
|
97
107
|
--format <fmt> guard/check μΆλ ₯ νμ: console, json, agent (κΈ°λ³Έ: μλ)
|
|
98
108
|
--format <fmt> doctor μΆλ ₯ νμ: console, json, markdown (κΈ°λ³Έ: console)
|
|
99
|
-
--no-llm doctorμμ LLM μ¬μ© μ ν¨ (ν
νλ¦Ώ λͺ¨λ)
|
|
100
|
-
--model <name> brain setup μ λͺ¨λΈ μ΄λ¦ (κΈ°λ³Έ: llama3.2)
|
|
101
|
-
--url <url> brain setup μ Ollama URL
|
|
102
|
-
--verbose μμΈ μΆλ ₯
|
|
103
|
-
--help, -h λμλ§ νμ
|
|
104
|
-
|
|
109
|
+
--no-llm doctorμμ LLM μ¬μ© μ ν¨ (ν
νλ¦Ώ λͺ¨λ)
|
|
110
|
+
--model <name> brain setup μ λͺ¨λΈ μ΄λ¦ (κΈ°λ³Έ: llama3.2)
|
|
111
|
+
--url <url> brain setup μ Ollama URL
|
|
112
|
+
--verbose μμΈ μΆλ ₯
|
|
113
|
+
--help, -h λμλ§ νμ
|
|
114
|
+
|
|
105
115
|
Examples:
|
|
106
|
-
bunx mandu init --name my-app
|
|
116
|
+
bunx mandu init --name my-app # Tailwind + shadcn/ui κΈ°λ³Έ
|
|
117
|
+
bunx mandu init my-app --minimal # CSS/UI μμ΄ μ΅μ ν
νλ¦Ώ
|
|
118
|
+
bunx mandu init my-app --theme # λ€ν¬λͺ¨λ ν
λ§ ν¬ν¨
|
|
119
|
+
bunx mandu init my-app --ui none # UI λΌμ΄λΈλ¬λ¦¬ μμ΄
|
|
107
120
|
bunx mandu check
|
|
108
121
|
bunx mandu routes list
|
|
109
122
|
bunx mandu routes generate
|
|
110
123
|
bunx mandu dev --port 3000
|
|
111
124
|
bunx mandu dev --no-guard
|
|
112
125
|
bunx mandu build --minify
|
|
113
|
-
bunx mandu guard
|
|
114
|
-
bunx mandu guard arch --preset fsd
|
|
115
|
-
bunx mandu guard arch --watch
|
|
126
|
+
bunx mandu guard
|
|
127
|
+
bunx mandu guard arch --preset fsd
|
|
128
|
+
bunx mandu guard arch --watch
|
|
116
129
|
bunx mandu guard arch --ci --format json
|
|
130
|
+
bunx mandu guard legacy
|
|
117
131
|
bunx mandu monitor
|
|
118
132
|
bunx mandu monitor --summary --since 5m
|
|
119
133
|
bunx mandu doctor
|
|
120
|
-
bunx mandu brain setup --model codellama
|
|
121
|
-
bunx mandu contract create users
|
|
122
|
-
bunx mandu
|
|
123
|
-
bunx mandu
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
options[
|
|
150
|
-
} else if (
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
*
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
134
|
+
bunx mandu brain setup --model codellama
|
|
135
|
+
bunx mandu contract create users
|
|
136
|
+
bunx mandu contract build
|
|
137
|
+
bunx mandu contract diff
|
|
138
|
+
bunx mandu openapi generate --output docs/api.json
|
|
139
|
+
bunx mandu change begin --message "Add new route"
|
|
140
|
+
|
|
141
|
+
FS Routes Workflow (κΆμ₯):
|
|
142
|
+
1. init β 2. app/ ν΄λμ page.tsx μμ± β 3. dev β 4. build
|
|
143
|
+
|
|
144
|
+
Legacy Workflow:
|
|
145
|
+
1. init β 2. spec-upsert β 3. generate β 4. build β 5. guard β 6. dev
|
|
146
|
+
|
|
147
|
+
Contract-first Workflow:
|
|
148
|
+
1. contract create β 2. Edit contract β 3. generate β 4. Edit slot β 5. contract validate
|
|
149
|
+
|
|
150
|
+
Brain (sLLM) Workflow:
|
|
151
|
+
1. brain setup β 2. doctor (λΆμ) β 3. watch (κ°μ)
|
|
152
|
+
`;
|
|
153
|
+
|
|
154
|
+
function parseArgs(args: string[]): { command: string; options: Record<string, string> } {
|
|
155
|
+
const command = args[0] || "";
|
|
156
|
+
const options: Record<string, string> = {};
|
|
157
|
+
|
|
158
|
+
for (let i = 1; i < args.length; i++) {
|
|
159
|
+
const arg = args[i];
|
|
160
|
+
if (arg.startsWith("--")) {
|
|
161
|
+
const key = arg.slice(2);
|
|
162
|
+
const value = args[i + 1] && !args[i + 1].startsWith("--") ? args[++i] : "true";
|
|
163
|
+
options[key] = value;
|
|
164
|
+
} else if (arg === "-h") {
|
|
165
|
+
options["help"] = "true";
|
|
166
|
+
} else if (!options._positional) {
|
|
167
|
+
// First non-flag argument after command is positional (e.g., project name)
|
|
168
|
+
options._positional = arg;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return { command, options };
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* ν¬νΈ μ΅μ
μμ νκ² νμ±
|
|
177
|
+
* - μ«μκ° μλλ©΄ undefined λ°ν (κΈ°λ³Έκ° μ¬μ©)
|
|
178
|
+
* - μ ν¨ λ²μ: 1-65535
|
|
179
|
+
*/
|
|
180
|
+
function parsePort(value: string | undefined, optionName = "port"): number | undefined {
|
|
181
|
+
if (!value || value === "true") {
|
|
182
|
+
return undefined; // κΈ°λ³Έκ° μ¬μ©
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const port = Number(value);
|
|
186
|
+
|
|
187
|
+
if (Number.isNaN(port)) {
|
|
188
|
+
console.warn(`β οΈ Invalid --${optionName} value: "${value}" (using default)`);
|
|
189
|
+
return undefined;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (!Number.isInteger(port) || port < 1 || port > 65535) {
|
|
193
|
+
console.warn(`β οΈ Invalid --${optionName} range: ${port} (must be 1-65535, using default)`);
|
|
194
|
+
return undefined;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return port;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
async function main(): Promise<void> {
|
|
201
|
+
const args = process.argv.slice(2);
|
|
202
|
+
const { command, options } = parseArgs(args);
|
|
203
|
+
|
|
204
|
+
if (options.help || command === "help" || !command) {
|
|
205
|
+
console.log(HELP_TEXT);
|
|
206
|
+
process.exit(0);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
let success = true;
|
|
210
|
+
|
|
211
|
+
switch (command) {
|
|
212
|
+
case "init":
|
|
213
|
+
success = await init({
|
|
214
|
+
name: options.name || options._positional,
|
|
215
|
+
css: options.css as any,
|
|
216
|
+
ui: options.ui as any,
|
|
217
|
+
theme: options.theme === "true",
|
|
218
|
+
minimal: options.minimal === "true",
|
|
219
|
+
});
|
|
220
|
+
break;
|
|
221
|
+
|
|
222
|
+
case "spec-upsert":
|
|
223
|
+
success = await specUpsert({ file: options.file });
|
|
224
|
+
break;
|
|
225
|
+
|
|
206
226
|
case "generate":
|
|
207
227
|
success = await generateApply();
|
|
208
228
|
break;
|
|
@@ -219,39 +239,50 @@ async function main(): Promise<void> {
|
|
|
219
239
|
|
|
220
240
|
case "guard": {
|
|
221
241
|
const subCommand = args[1];
|
|
242
|
+
const hasSubCommand = subCommand && !subCommand.startsWith("--");
|
|
243
|
+
const guardArchOptions = {
|
|
244
|
+
preset: options.preset as any,
|
|
245
|
+
watch: options.watch === "true",
|
|
246
|
+
ci: options.ci === "true",
|
|
247
|
+
format: options.format as any,
|
|
248
|
+
quiet: options.quiet === "true",
|
|
249
|
+
srcDir: options["src-dir"],
|
|
250
|
+
listPresets: options["list-presets"] === "true",
|
|
251
|
+
output: options.output,
|
|
252
|
+
reportFormat: (options["report-format"] as any) || "markdown",
|
|
253
|
+
saveStats: options["save-stats"] === "true",
|
|
254
|
+
showTrend: options["show-trend"] === "true",
|
|
255
|
+
};
|
|
222
256
|
switch (subCommand) {
|
|
223
257
|
case "arch":
|
|
224
|
-
success = await guardArch(
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
});
|
|
253
|
-
break;
|
|
254
|
-
|
|
258
|
+
success = await guardArch(guardArchOptions);
|
|
259
|
+
break;
|
|
260
|
+
case "legacy":
|
|
261
|
+
case "spec":
|
|
262
|
+
success = await guardCheck({
|
|
263
|
+
autoCorrect: options["no-auto-correct"] !== "true",
|
|
264
|
+
});
|
|
265
|
+
break;
|
|
266
|
+
default:
|
|
267
|
+
if (hasSubCommand) {
|
|
268
|
+
console.error(`β Unknown guard subcommand: ${subCommand}`);
|
|
269
|
+
console.log("\nUsage: bunx mandu guard <arch|legacy>");
|
|
270
|
+
process.exit(1);
|
|
271
|
+
}
|
|
272
|
+
// κΈ°λ³Έκ°: architecture guard
|
|
273
|
+
success = await guardArch(guardArchOptions);
|
|
274
|
+
}
|
|
275
|
+
break;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
case "build":
|
|
279
|
+
success = await build({
|
|
280
|
+
minify: options.minify === "true",
|
|
281
|
+
sourcemap: options.sourcemap === "true",
|
|
282
|
+
watch: options.watch === "true",
|
|
283
|
+
});
|
|
284
|
+
break;
|
|
285
|
+
|
|
255
286
|
case "dev":
|
|
256
287
|
await dev({
|
|
257
288
|
port: parsePort(options.port),
|
|
@@ -261,128 +292,139 @@ async function main(): Promise<void> {
|
|
|
261
292
|
legacy: options.legacy === "true",
|
|
262
293
|
});
|
|
263
294
|
break;
|
|
264
|
-
|
|
265
|
-
case "routes": {
|
|
266
|
-
const subCommand = args[1];
|
|
267
|
-
switch (subCommand) {
|
|
268
|
-
case "generate":
|
|
269
|
-
success = await routesGenerate({
|
|
270
|
-
output: options.output,
|
|
271
|
-
verbose: options.verbose === "true",
|
|
272
|
-
});
|
|
273
|
-
break;
|
|
274
|
-
case "list":
|
|
275
|
-
success = await routesList({
|
|
276
|
-
verbose: options.verbose === "true",
|
|
277
|
-
});
|
|
278
|
-
break;
|
|
279
|
-
case "watch":
|
|
280
|
-
success = await routesWatch({
|
|
281
|
-
output: options.output,
|
|
282
|
-
verbose: options.verbose === "true",
|
|
283
|
-
});
|
|
284
|
-
break;
|
|
285
|
-
default:
|
|
286
|
-
// κΈ°λ³Έκ°: list
|
|
287
|
-
if (!subCommand) {
|
|
288
|
-
success = await routesList({
|
|
289
|
-
verbose: options.verbose === "true",
|
|
290
|
-
});
|
|
291
|
-
} else {
|
|
292
|
-
console.error(`β Unknown routes subcommand: ${subCommand}`);
|
|
293
|
-
console.log("\nUsage: bunx mandu routes <generate|list|watch>");
|
|
294
|
-
process.exit(1);
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
break;
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
case "contract": {
|
|
301
|
-
const subCommand = args[1];
|
|
302
|
-
switch (subCommand) {
|
|
303
|
-
case "create": {
|
|
304
|
-
const routeId = args[2] || options._positional;
|
|
305
|
-
if (!routeId) {
|
|
306
|
-
console.error("β Route ID is required");
|
|
307
|
-
console.log("\nUsage: bunx mandu contract create <routeId>");
|
|
308
|
-
process.exit(1);
|
|
309
|
-
}
|
|
310
|
-
success = await contractCreate({ routeId });
|
|
311
|
-
break;
|
|
312
|
-
}
|
|
313
|
-
case "validate":
|
|
314
|
-
success = await contractValidate({ verbose: options.verbose === "true" });
|
|
315
|
-
break;
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
});
|
|
369
|
-
break;
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
295
|
+
|
|
296
|
+
case "routes": {
|
|
297
|
+
const subCommand = args[1];
|
|
298
|
+
switch (subCommand) {
|
|
299
|
+
case "generate":
|
|
300
|
+
success = await routesGenerate({
|
|
301
|
+
output: options.output,
|
|
302
|
+
verbose: options.verbose === "true",
|
|
303
|
+
});
|
|
304
|
+
break;
|
|
305
|
+
case "list":
|
|
306
|
+
success = await routesList({
|
|
307
|
+
verbose: options.verbose === "true",
|
|
308
|
+
});
|
|
309
|
+
break;
|
|
310
|
+
case "watch":
|
|
311
|
+
success = await routesWatch({
|
|
312
|
+
output: options.output,
|
|
313
|
+
verbose: options.verbose === "true",
|
|
314
|
+
});
|
|
315
|
+
break;
|
|
316
|
+
default:
|
|
317
|
+
// κΈ°λ³Έκ°: list
|
|
318
|
+
if (!subCommand) {
|
|
319
|
+
success = await routesList({
|
|
320
|
+
verbose: options.verbose === "true",
|
|
321
|
+
});
|
|
322
|
+
} else {
|
|
323
|
+
console.error(`β Unknown routes subcommand: ${subCommand}`);
|
|
324
|
+
console.log("\nUsage: bunx mandu routes <generate|list|watch>");
|
|
325
|
+
process.exit(1);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
break;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
case "contract": {
|
|
332
|
+
const subCommand = args[1];
|
|
333
|
+
switch (subCommand) {
|
|
334
|
+
case "create": {
|
|
335
|
+
const routeId = args[2] || options._positional;
|
|
336
|
+
if (!routeId) {
|
|
337
|
+
console.error("β Route ID is required");
|
|
338
|
+
console.log("\nUsage: bunx mandu contract create <routeId>");
|
|
339
|
+
process.exit(1);
|
|
340
|
+
}
|
|
341
|
+
success = await contractCreate({ routeId });
|
|
342
|
+
break;
|
|
343
|
+
}
|
|
344
|
+
case "validate":
|
|
345
|
+
success = await contractValidate({ verbose: options.verbose === "true" });
|
|
346
|
+
break;
|
|
347
|
+
case "build":
|
|
348
|
+
success = await contractBuild({ output: options.output });
|
|
349
|
+
break;
|
|
350
|
+
case "diff":
|
|
351
|
+
success = await contractDiff({
|
|
352
|
+
from: options.from,
|
|
353
|
+
to: options.to,
|
|
354
|
+
output: options.output,
|
|
355
|
+
json: options.json === "true",
|
|
356
|
+
});
|
|
357
|
+
break;
|
|
358
|
+
default:
|
|
359
|
+
console.error(`β Unknown contract subcommand: ${subCommand}`);
|
|
360
|
+
console.log("\nUsage: bunx mandu contract <create|validate|build|diff>");
|
|
361
|
+
process.exit(1);
|
|
362
|
+
}
|
|
363
|
+
break;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
case "openapi": {
|
|
367
|
+
const subCommand = args[1];
|
|
368
|
+
switch (subCommand) {
|
|
369
|
+
case "generate":
|
|
370
|
+
success = await openAPIGenerate({
|
|
371
|
+
output: options.output,
|
|
372
|
+
title: options.title,
|
|
373
|
+
version: options.version,
|
|
374
|
+
});
|
|
375
|
+
break;
|
|
376
|
+
case "serve":
|
|
377
|
+
success = await openAPIServe({
|
|
378
|
+
port: parsePort(options.port),
|
|
379
|
+
});
|
|
380
|
+
break;
|
|
381
|
+
default:
|
|
382
|
+
console.error(`β Unknown openapi subcommand: ${subCommand}`);
|
|
383
|
+
console.log("\nUsage: bunx mandu openapi <generate|serve>");
|
|
384
|
+
process.exit(1);
|
|
385
|
+
}
|
|
386
|
+
break;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
case "change": {
|
|
390
|
+
const subCommand = args[1];
|
|
391
|
+
switch (subCommand) {
|
|
392
|
+
case "begin":
|
|
393
|
+
success = await changeBegin({ message: options.message });
|
|
394
|
+
break;
|
|
395
|
+
case "commit":
|
|
396
|
+
success = await changeCommit();
|
|
397
|
+
break;
|
|
398
|
+
case "rollback":
|
|
399
|
+
success = await changeRollback({ id: options.id });
|
|
400
|
+
break;
|
|
401
|
+
case "status":
|
|
402
|
+
success = await changeStatus();
|
|
403
|
+
break;
|
|
404
|
+
case "list":
|
|
405
|
+
success = await changeList();
|
|
406
|
+
break;
|
|
407
|
+
case "prune":
|
|
408
|
+
success = await changePrune({
|
|
409
|
+
keep: options.keep ? Number(options.keep) : undefined,
|
|
410
|
+
});
|
|
411
|
+
break;
|
|
412
|
+
default:
|
|
413
|
+
console.error(`β Unknown change subcommand: ${subCommand}`);
|
|
414
|
+
console.log(`\nUsage: bunx mandu change <begin|commit|rollback|status|list|prune>`);
|
|
415
|
+
process.exit(1);
|
|
416
|
+
}
|
|
417
|
+
break;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
case "doctor":
|
|
421
|
+
success = await doctor({
|
|
422
|
+
format: (options.format as "console" | "json" | "markdown") || "console",
|
|
423
|
+
useLLM: options["no-llm"] !== "true",
|
|
424
|
+
output: options.output,
|
|
425
|
+
});
|
|
426
|
+
break;
|
|
427
|
+
|
|
386
428
|
case "watch":
|
|
387
429
|
success = await watch({
|
|
388
430
|
status: options.status === "true",
|
|
@@ -400,41 +442,41 @@ async function main(): Promise<void> {
|
|
|
400
442
|
});
|
|
401
443
|
break;
|
|
402
444
|
|
|
403
|
-
case "brain": {
|
|
404
|
-
const subCommand = args[1];
|
|
405
|
-
switch (subCommand) {
|
|
406
|
-
case "setup":
|
|
407
|
-
success = await brainSetup({
|
|
408
|
-
model: options.model,
|
|
409
|
-
url: options.url,
|
|
410
|
-
skipCheck: options["skip-check"] === "true",
|
|
411
|
-
});
|
|
412
|
-
break;
|
|
413
|
-
case "status":
|
|
414
|
-
success = await brainStatus({
|
|
415
|
-
verbose: options.verbose === "true",
|
|
416
|
-
});
|
|
417
|
-
break;
|
|
418
|
-
default:
|
|
419
|
-
console.error(`β Unknown brain subcommand: ${subCommand}`);
|
|
420
|
-
console.log("\nUsage: bunx mandu brain <setup|status>");
|
|
421
|
-
process.exit(1);
|
|
422
|
-
}
|
|
423
|
-
break;
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
default:
|
|
427
|
-
console.error(`β Unknown command: ${command}`);
|
|
428
|
-
console.log(HELP_TEXT);
|
|
429
|
-
process.exit(1);
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
if (!success) {
|
|
433
|
-
process.exit(1);
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
main().catch((error) => {
|
|
438
|
-
console.error("β μμμΉ λͺ»ν μ€λ₯:", error);
|
|
439
|
-
process.exit(1);
|
|
440
|
-
});
|
|
445
|
+
case "brain": {
|
|
446
|
+
const subCommand = args[1];
|
|
447
|
+
switch (subCommand) {
|
|
448
|
+
case "setup":
|
|
449
|
+
success = await brainSetup({
|
|
450
|
+
model: options.model,
|
|
451
|
+
url: options.url,
|
|
452
|
+
skipCheck: options["skip-check"] === "true",
|
|
453
|
+
});
|
|
454
|
+
break;
|
|
455
|
+
case "status":
|
|
456
|
+
success = await brainStatus({
|
|
457
|
+
verbose: options.verbose === "true",
|
|
458
|
+
});
|
|
459
|
+
break;
|
|
460
|
+
default:
|
|
461
|
+
console.error(`β Unknown brain subcommand: ${subCommand}`);
|
|
462
|
+
console.log("\nUsage: bunx mandu brain <setup|status>");
|
|
463
|
+
process.exit(1);
|
|
464
|
+
}
|
|
465
|
+
break;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
default:
|
|
469
|
+
console.error(`β Unknown command: ${command}`);
|
|
470
|
+
console.log(HELP_TEXT);
|
|
471
|
+
process.exit(1);
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
if (!success) {
|
|
475
|
+
process.exit(1);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
main().catch((error) => {
|
|
480
|
+
console.error("β μμμΉ λͺ»ν μ€λ₯:", error);
|
|
481
|
+
process.exit(1);
|
|
482
|
+
});
|