@mandujs/cli 0.15.3 → 0.15.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mandujs/cli",
3
- "version": "0.15.3",
3
+ "version": "0.15.4",
4
4
  "description": "Agent-Native Fullstack Framework - 에이전트가 코딩해도 아키텍처가 무너지지 않는 개발 OS",
5
5
  "type": "module",
6
6
  "main": "./src/main.ts",
@@ -8,6 +8,54 @@ import {
8
8
  type LockfileValidationResult,
9
9
  } from "@mandujs/core";
10
10
 
11
+ /**
12
+ * Lockfile command templates for consistent messaging
13
+ */
14
+ export const LOCKFILE_COMMANDS = {
15
+ update: "mandu lock",
16
+ diff: "mandu lock --diff",
17
+ safeDev: "mandu lock && mandu dev --watch",
18
+ } as const;
19
+
20
+ /**
21
+ * Formatted lockfile guidance lines with alternative commands
22
+ */
23
+ export const LOCKFILE_GUIDE_LINES = {
24
+ update: `${LOCKFILE_COMMANDS.update} (or bunx mandu lock)`,
25
+ diff: `${LOCKFILE_COMMANDS.diff} (or bunx mandu lock --diff)`,
26
+ safeDev: `${LOCKFILE_COMMANDS.safeDev} (or bun run dev:safe)`,
27
+ } as const;
28
+
29
+ /**
30
+ * Returns formatted lockfile guidance lines for display
31
+ *
32
+ * @returns Array of guidance messages with Korean labels
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * const lines = getLockfileGuidanceLines();
37
+ * lines.forEach(line => console.log(` ↳ ${line}`));
38
+ * // Output:
39
+ * // ↳ lock 갱신: mandu lock (or bunx mandu lock)
40
+ * // ↳ 변경 확인: mandu lock --diff (or bunx mandu lock --diff)
41
+ * // ↳ 안정 실행: mandu lock && mandu dev --watch (or bun run dev:safe)
42
+ * ```
43
+ */
44
+ export function getLockfileGuidanceLines(): string[] {
45
+ return [
46
+ `lock 갱신: ${LOCKFILE_GUIDE_LINES.update}`,
47
+ `변경 확인: ${LOCKFILE_GUIDE_LINES.diff}`,
48
+ `안정 실행: ${LOCKFILE_GUIDE_LINES.safeDev}`,
49
+ ];
50
+ }
51
+
52
+ /**
53
+ * Validates runtime lockfile against current config
54
+ *
55
+ * @param config - Mandu configuration object
56
+ * @param rootDir - Project root directory
57
+ * @returns Validation result with lockfile, action, and bypass status
58
+ */
11
59
  export async function validateRuntimeLockfile(config: Record<string, unknown>, rootDir: string) {
12
60
  const lockfile = await readLockfile(rootDir);
13
61
 
@@ -30,17 +78,22 @@ export async function validateRuntimeLockfile(config: Record<string, unknown>, r
30
78
  return { lockfile, lockResult, action, bypassed };
31
79
  }
32
80
 
81
+ /**
82
+ * Handles blocked server start due to lockfile mismatch
83
+ *
84
+ * Exits process with error code 1 if action is "block"
85
+ *
86
+ * @param action - Policy action from lockfile validation
87
+ * @param lockResult - Validation result with details
88
+ */
33
89
  export function handleBlockedLockfile(action: "pass" | "warn" | "error" | "block", lockResult: LockfileValidationResult | null): void {
34
90
  if (action !== "block") return;
35
91
 
92
+ const guidance = getLockfileGuidanceLines();
36
93
  console.error("🛑 서버 시작 차단: Lockfile 불일치");
37
- console.error(" 설정이 변경되었습니다. 의도한 변경이라면 아래 중 하나를 실행하세요:");
38
- console.error(" $ mandu lock");
39
- console.error(" $ bunx mandu lock");
40
- console.error("");
41
- console.error(" 변경 사항 확인:");
42
- console.error(" $ mandu lock --diff");
43
- console.error(" $ bunx mandu lock --diff");
94
+ console.error(" 설정이 변경되었습니다. 의도한 변경이라면 아래를 실행하세요:");
95
+ console.error(` ${guidance[0]}`);
96
+ console.error(` ${guidance[1]}`);
44
97
  if (lockResult) {
45
98
  console.error("");
46
99
  console.error(formatValidationResult(lockResult));
@@ -48,6 +101,14 @@ export function handleBlockedLockfile(action: "pass" | "warn" | "error" | "block
48
101
  process.exit(1);
49
102
  }
50
103
 
104
+ /**
105
+ * Prints runtime lockfile validation status
106
+ *
107
+ * @param action - Policy action from lockfile validation
108
+ * @param bypassed - Whether validation was bypassed
109
+ * @param lockfile - Lockfile data (null if not found)
110
+ * @param lockResult - Validation result with hash and validity
111
+ */
51
112
  export function printRuntimeLockfileStatus(
52
113
  action: "pass" | "warn" | "error" | "block",
53
114
  bypassed: boolean,
@@ -56,11 +117,12 @@ export function printRuntimeLockfileStatus(
56
117
  ): void {
57
118
  if (action === "warn") {
58
119
  console.log(`⚠️ ${formatPolicyAction(action, bypassed)}`);
59
- console.log(` ↳ lock 갱신: mandu lock (or bunx mandu lock)`);
60
- console.log(` ↳ 변경 확인: mandu lock --diff (or bunx mandu lock --diff)`);
120
+ for (const line of getLockfileGuidanceLines()) {
121
+ console.log(` ↳ ${line}`);
122
+ }
61
123
  } else if (lockfile && lockResult?.valid) {
62
124
  console.log(`🔒 설정 무결성 확인됨 (${lockResult.currentHash?.slice(0, 8)})`);
63
125
  } else if (!lockfile) {
64
- console.log(`💡 Lockfile 없음 - 'mandu lock' 또는 'bunx mandu lock'으로 생성 권장`);
126
+ console.log(`💡 Lockfile 없음 - '${LOCKFILE_COMMANDS.update}'으로 생성 권장`);
65
127
  }
66
128
  }
@@ -7,7 +7,7 @@ import {
7
7
  openChatStream,
8
8
  sendChatMessage,
9
9
  type ChatStreamConnectionState,
10
- } from "./chat-api";
10
+ } from "@/client/features/chat/chat-api";
11
11
 
12
12
  export function useRealtimeChat() {
13
13
  const [messages, setMessages] = useState<ChatMessage[]>([]);