@mandujs/cli 0.12.2 → 0.13.0

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 (51) hide show
  1. package/README.ko.md +234 -234
  2. package/README.md +354 -354
  3. package/package.json +2 -2
  4. package/src/commands/contract.ts +173 -173
  5. package/src/commands/dev.ts +8 -68
  6. package/src/commands/doctor.ts +27 -27
  7. package/src/commands/guard-arch.ts +303 -303
  8. package/src/commands/guard-check.ts +3 -3
  9. package/src/commands/monitor.ts +300 -300
  10. package/src/commands/openapi.ts +107 -107
  11. package/src/commands/registry.ts +367 -357
  12. package/src/commands/routes.ts +228 -228
  13. package/src/commands/start.ts +184 -0
  14. package/src/errors/codes.ts +35 -35
  15. package/src/errors/index.ts +2 -2
  16. package/src/errors/messages.ts +143 -143
  17. package/src/hooks/index.ts +17 -17
  18. package/src/hooks/preaction.ts +256 -256
  19. package/src/main.ts +37 -34
  20. package/src/terminal/banner.ts +166 -166
  21. package/src/terminal/help.ts +306 -306
  22. package/src/terminal/index.ts +71 -71
  23. package/src/terminal/output.ts +295 -295
  24. package/src/terminal/palette.ts +30 -30
  25. package/src/terminal/progress.ts +327 -327
  26. package/src/terminal/stream-writer.ts +214 -214
  27. package/src/terminal/table.ts +354 -354
  28. package/src/terminal/theme.ts +142 -142
  29. package/src/util/bun.ts +6 -6
  30. package/src/util/fs.ts +23 -23
  31. package/src/util/handlers.ts +96 -0
  32. package/src/util/manifest.ts +52 -52
  33. package/src/util/output.ts +22 -22
  34. package/src/util/port.ts +71 -71
  35. package/templates/default/AGENTS.md +96 -96
  36. package/templates/default/app/api/health/route.ts +13 -13
  37. package/templates/default/app/globals.css +49 -49
  38. package/templates/default/app/layout.tsx +27 -27
  39. package/templates/default/app/page.tsx +38 -38
  40. package/templates/default/package.json +1 -0
  41. package/templates/default/src/client/shared/lib/utils.ts +16 -16
  42. package/templates/default/src/client/shared/ui/button.tsx +57 -57
  43. package/templates/default/src/client/shared/ui/card.tsx +78 -78
  44. package/templates/default/src/client/shared/ui/index.ts +21 -21
  45. package/templates/default/src/client/shared/ui/input.tsx +24 -24
  46. package/templates/default/tests/example.test.ts +58 -58
  47. package/templates/default/tests/helpers.ts +52 -52
  48. package/templates/default/tests/setup.ts +9 -9
  49. package/templates/default/tsconfig.json +12 -14
  50. package/templates/default/apps/server/main.ts +0 -67
  51. package/templates/default/apps/web/entry.tsx +0 -35
@@ -1,166 +1,166 @@
1
- /**
2
- * DNA-017: Hero Banner with cfonts + gradient
3
- *
4
- * Sexy ASCII art banner for CLI startup
5
- * Inspired by Claude Code, Vite, Astro CLI screens
6
- *
7
- * @see https://github.com/dominikwilkowski/cfonts
8
- */
9
-
10
- import { theme, isRich, stripAnsi } from "./theme.js";
11
- import { MANDU_PALETTE } from "./palette.js";
12
-
13
- /**
14
- * Check if banner should be displayed
15
- */
16
- export function shouldShowBanner(argv: string[]): boolean {
17
- // Environment-based skip
18
- if (process.env.MANDU_NO_BANNER) return false;
19
- if (process.env.CI) return false;
20
- if (process.env.CLAUDE_CODE) return false;
21
- if (process.env.CODEX_AGENT) return false;
22
- if (process.env.MANDU_AGENT) return false;
23
-
24
- // TTY check
25
- if (!process.stdout.isTTY) return false;
26
-
27
- // Flag-based skip
28
- const hasJsonFlag = argv.includes("--json");
29
- const hasQuietFlag = argv.includes("--quiet") || argv.includes("-q");
30
- const hasHelpFlag = argv.includes("--help") || argv.includes("-h");
31
-
32
- if (hasJsonFlag || hasQuietFlag || hasHelpFlag) return false;
33
-
34
- return true;
35
- }
36
-
37
- /**
38
- * Fallback ASCII art banner (no dependencies)
39
- */
40
- const MANDU_ASCII_SMALL = `
41
- ╔╦╗╔═╗╔╗╔╔╦╗╦ ╦
42
- ║║║╠═╣║║║ ║║║ ║
43
- ╩ ╩╩ ╩╝╚╝═╩╝╚═╝
44
- `;
45
-
46
- const MANDU_ASCII_LARGE = `
47
- ███╗ ███╗ █████╗ ███╗ ██╗██████╗ ██╗ ██╗
48
- ████╗ ████║██╔══██╗████╗ ██║██╔══██╗██║ ██║
49
- ██╔████╔██║███████║██╔██╗ ██║██║ ██║██║ ██║
50
- ██║╚██╔╝██║██╔══██║██║╚██╗██║██║ ██║██║ ██║
51
- ██║ ╚═╝ ██║██║ ██║██║ ╚████║██████╔╝╚██████╔╝
52
- ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝╚═════╝ ╚═════╝
53
- `;
54
-
55
- /**
56
- * Apply gradient effect to text (simple version)
57
- */
58
- function applyGradient(text: string): string {
59
- if (!isRich()) return text;
60
-
61
- const lines = text.split("\n");
62
- const colorFns = [
63
- theme.accentDim,
64
- theme.accent,
65
- theme.accentBright,
66
- theme.accent,
67
- theme.accentDim,
68
- ];
69
-
70
- return lines
71
- .map((line, i) => {
72
- const colorIndex = Math.min(i, colorFns.length - 1);
73
- const colorFn = colorFns[colorIndex];
74
- return colorFn(line);
75
- })
76
- .join("\n");
77
- }
78
-
79
- /**
80
- * Render hero banner with cfonts (if available) or fallback
81
- */
82
- export async function renderHeroBanner(version: string): Promise<void> {
83
- const cols = process.stdout.columns ?? 80;
84
-
85
- // Very narrow terminal: minimal output
86
- if (cols < 40) {
87
- console.log(`\n 🥟 Mandu v${version}\n`);
88
- return;
89
- }
90
-
91
- // Try cfonts first
92
- try {
93
- const cfonts = await import("cfonts");
94
-
95
- cfonts.say("MANDU", {
96
- font: "block",
97
- gradient: [MANDU_PALETTE.accent, MANDU_PALETTE.accentBright],
98
- transitionGradient: true,
99
- align: "center",
100
- space: true,
101
- maxLength: Math.min(cols - 4, 80),
102
- });
103
- } catch {
104
- // cfonts not available, use fallback
105
- const ascii = cols >= 60 ? MANDU_ASCII_LARGE : MANDU_ASCII_SMALL;
106
- console.log(applyGradient(ascii));
107
- }
108
-
109
- // Tagline
110
- const tagline = `🥟 Agent-Native Web Framework v${version}`;
111
- const taglineWidth = stripAnsi(tagline).length;
112
- const padding = Math.max(0, Math.floor((cols - taglineWidth) / 2));
113
-
114
- console.log(" ".repeat(padding) + theme.muted(tagline));
115
- console.log();
116
- }
117
-
118
- /**
119
- * Render minimal banner (for narrow terminals or quick commands)
120
- */
121
- export function renderMiniBanner(version: string): void {
122
- if (!isRich()) {
123
- console.log(`\nMandu v${version}\n`);
124
- return;
125
- }
126
-
127
- console.log();
128
- console.log(` ${theme.heading("🥟 Mandu")} ${theme.muted(`v${version}`)}`);
129
- console.log(` ${theme.muted("Agent-Native Web Framework")}`);
130
- console.log();
131
- }
132
-
133
- /**
134
- * Render box banner (alternative style)
135
- */
136
- export function renderBoxBanner(version: string): void {
137
- if (!isRich()) {
138
- console.log(`\nMandu v${version}\n`);
139
- return;
140
- }
141
-
142
- const width = 30;
143
- const top = theme.accent(" ╭" + "─".repeat(width) + "╮");
144
- const mid1 =
145
- theme.accent(" │") +
146
- " " +
147
- theme.heading("🥟 Mandu") +
148
- " " +
149
- theme.muted(`v${version}`) +
150
- " ".repeat(width - 18 - version.length) +
151
- theme.accent("│");
152
- const mid2 =
153
- theme.accent(" │") +
154
- " " +
155
- theme.muted("Agent-Native Framework") +
156
- " ".repeat(width - 24) +
157
- theme.accent("│");
158
- const bottom = theme.accent(" ╰" + "─".repeat(width) + "╯");
159
-
160
- console.log();
161
- console.log(top);
162
- console.log(mid1);
163
- console.log(mid2);
164
- console.log(bottom);
165
- console.log();
166
- }
1
+ /**
2
+ * DNA-017: Hero Banner with cfonts + gradient
3
+ *
4
+ * Sexy ASCII art banner for CLI startup
5
+ * Inspired by Claude Code, Vite, Astro CLI screens
6
+ *
7
+ * @see https://github.com/dominikwilkowski/cfonts
8
+ */
9
+
10
+ import { theme, isRich, stripAnsi } from "./theme.js";
11
+ import { MANDU_PALETTE } from "./palette.js";
12
+
13
+ /**
14
+ * Check if banner should be displayed
15
+ */
16
+ export function shouldShowBanner(argv: string[]): boolean {
17
+ // Environment-based skip
18
+ if (process.env.MANDU_NO_BANNER) return false;
19
+ if (process.env.CI) return false;
20
+ if (process.env.CLAUDE_CODE) return false;
21
+ if (process.env.CODEX_AGENT) return false;
22
+ if (process.env.MANDU_AGENT) return false;
23
+
24
+ // TTY check
25
+ if (!process.stdout.isTTY) return false;
26
+
27
+ // Flag-based skip
28
+ const hasJsonFlag = argv.includes("--json");
29
+ const hasQuietFlag = argv.includes("--quiet") || argv.includes("-q");
30
+ const hasHelpFlag = argv.includes("--help") || argv.includes("-h");
31
+
32
+ if (hasJsonFlag || hasQuietFlag || hasHelpFlag) return false;
33
+
34
+ return true;
35
+ }
36
+
37
+ /**
38
+ * Fallback ASCII art banner (no dependencies)
39
+ */
40
+ const MANDU_ASCII_SMALL = `
41
+ ╔╦╗╔═╗╔╗╔╔╦╗╦ ╦
42
+ ║║║╠═╣║║║ ║║║ ║
43
+ ╩ ╩╩ ╩╝╚╝═╩╝╚═╝
44
+ `;
45
+
46
+ const MANDU_ASCII_LARGE = `
47
+ ███╗ ███╗ █████╗ ███╗ ██╗██████╗ ██╗ ██╗
48
+ ████╗ ████║██╔══██╗████╗ ██║██╔══██╗██║ ██║
49
+ ██╔████╔██║███████║██╔██╗ ██║██║ ██║██║ ██║
50
+ ██║╚██╔╝██║██╔══██║██║╚██╗██║██║ ██║██║ ██║
51
+ ██║ ╚═╝ ██║██║ ██║██║ ╚████║██████╔╝╚██████╔╝
52
+ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝╚═════╝ ╚═════╝
53
+ `;
54
+
55
+ /**
56
+ * Apply gradient effect to text (simple version)
57
+ */
58
+ function applyGradient(text: string): string {
59
+ if (!isRich()) return text;
60
+
61
+ const lines = text.split("\n");
62
+ const colorFns = [
63
+ theme.accentDim,
64
+ theme.accent,
65
+ theme.accentBright,
66
+ theme.accent,
67
+ theme.accentDim,
68
+ ];
69
+
70
+ return lines
71
+ .map((line, i) => {
72
+ const colorIndex = Math.min(i, colorFns.length - 1);
73
+ const colorFn = colorFns[colorIndex];
74
+ return colorFn(line);
75
+ })
76
+ .join("\n");
77
+ }
78
+
79
+ /**
80
+ * Render hero banner with cfonts (if available) or fallback
81
+ */
82
+ export async function renderHeroBanner(version: string): Promise<void> {
83
+ const cols = process.stdout.columns ?? 80;
84
+
85
+ // Very narrow terminal: minimal output
86
+ if (cols < 40) {
87
+ console.log(`\n 🥟 Mandu v${version}\n`);
88
+ return;
89
+ }
90
+
91
+ // Try cfonts first
92
+ try {
93
+ const cfonts = await import("cfonts");
94
+
95
+ cfonts.say("MANDU", {
96
+ font: "block",
97
+ gradient: [MANDU_PALETTE.accent, MANDU_PALETTE.accentBright],
98
+ transitionGradient: true,
99
+ align: "center",
100
+ space: true,
101
+ maxLength: Math.min(cols - 4, 80),
102
+ });
103
+ } catch {
104
+ // cfonts not available, use fallback
105
+ const ascii = cols >= 60 ? MANDU_ASCII_LARGE : MANDU_ASCII_SMALL;
106
+ console.log(applyGradient(ascii));
107
+ }
108
+
109
+ // Tagline
110
+ const tagline = `🥟 Agent-Native Web Framework v${version}`;
111
+ const taglineWidth = stripAnsi(tagline).length;
112
+ const padding = Math.max(0, Math.floor((cols - taglineWidth) / 2));
113
+
114
+ console.log(" ".repeat(padding) + theme.muted(tagline));
115
+ console.log();
116
+ }
117
+
118
+ /**
119
+ * Render minimal banner (for narrow terminals or quick commands)
120
+ */
121
+ export function renderMiniBanner(version: string): void {
122
+ if (!isRich()) {
123
+ console.log(`\nMandu v${version}\n`);
124
+ return;
125
+ }
126
+
127
+ console.log();
128
+ console.log(` ${theme.heading("🥟 Mandu")} ${theme.muted(`v${version}`)}`);
129
+ console.log(` ${theme.muted("Agent-Native Web Framework")}`);
130
+ console.log();
131
+ }
132
+
133
+ /**
134
+ * Render box banner (alternative style)
135
+ */
136
+ export function renderBoxBanner(version: string): void {
137
+ if (!isRich()) {
138
+ console.log(`\nMandu v${version}\n`);
139
+ return;
140
+ }
141
+
142
+ const width = 30;
143
+ const top = theme.accent(" ╭" + "─".repeat(width) + "╮");
144
+ const mid1 =
145
+ theme.accent(" │") +
146
+ " " +
147
+ theme.heading("🥟 Mandu") +
148
+ " " +
149
+ theme.muted(`v${version}`) +
150
+ " ".repeat(width - 18 - version.length) +
151
+ theme.accent("│");
152
+ const mid2 =
153
+ theme.accent(" │") +
154
+ " " +
155
+ theme.muted("Agent-Native Framework") +
156
+ " ".repeat(width - 24) +
157
+ theme.accent("│");
158
+ const bottom = theme.accent(" ╰" + "─".repeat(width) + "╯");
159
+
160
+ console.log();
161
+ console.log(top);
162
+ console.log(mid1);
163
+ console.log(mid2);
164
+ console.log(bottom);
165
+ console.log();
166
+ }