setup-cc-room 0.2.2 → 0.2.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.
@@ -0,0 +1,280 @@
1
+ // src/i18n.ts
2
+ function resolveLocale(argv = process.argv, env = process.env) {
3
+ const langFlagIdx = argv.findIndex((a) => a === "--lang" || a === "--locale");
4
+ if (langFlagIdx >= 0 && argv[langFlagIdx + 1]) {
5
+ return normalizeLocale(argv[langFlagIdx + 1]);
6
+ }
7
+ const inline = argv.find((a) => a.startsWith("--lang=") || a.startsWith("--locale="));
8
+ if (inline) {
9
+ return normalizeLocale(inline.split("=")[1] ?? "en");
10
+ }
11
+ if (env.CC_ROOM_LANG) {
12
+ return normalizeLocale(env.CC_ROOM_LANG);
13
+ }
14
+ return "en";
15
+ }
16
+ function normalizeLocale(raw) {
17
+ const v = raw.trim().toLowerCase();
18
+ if (v === "ja" || v === "jp" || v === "japanese" || v.startsWith("ja-")) return "ja";
19
+ return "en";
20
+ }
21
+ var en = {
22
+ "cli.running_preflight": " Running preflight checks...",
23
+ "cli.preflight_failed": " \x1B[31mPrerequisites not met. Fix the issues above and try again.\x1B[0m\n",
24
+ "cli.preflight_ok": " \x1B[32mAll checks passed. Starting install...\x1B[0m\n",
25
+ "cli.install_done": " \x1B[32m\u2705 Setup complete!\x1B[0m",
26
+ "cli.uninstall_done": " \x1B[32m\u2705 Uninstall complete.\x1B[0m",
27
+ "cli.restart_claude": " Restart Claude Code so hooks / MCP take effect.",
28
+ "cli.unknown_arg": " Unknown argument: {arg}",
29
+ "cli.error": " \x1B[31mError:\x1B[0m",
30
+ "cli.help": `
31
+ \u{1F3E0} setup-cc-room v{version}
32
+
33
+ Usage:
34
+ npx setup-cc-room Install cc-room (English by default)
35
+ npx setup-cc-room --lang ja Install with Japanese UI / commands
36
+ npx setup-cc-room uninstall Remove cc-room
37
+ npx setup-cc-room --help Show this help
38
+
39
+ Language: --lang en|ja or CC_ROOM_LANG=ja
40
+ `,
41
+ "cli.install_guide": `
42
+ How to use cc-room:
43
+
44
+ [Open a room]
45
+ 1. Restart Claude Code (enable MCP and Hooks)
46
+ 2. /room open <name> \u2190 creates a room (PIN issued)
47
+ 3. Tell teammates the room name and PIN
48
+ 4. They run /room join <name> <PIN>
49
+
50
+ [If invited]
51
+ 1. Restart Claude Code
52
+ 2. /room join <name> <PIN>
53
+
54
+ [Daily]
55
+ /room \u2026 view the whiteboard
56
+ /private \u2026 status / local vs public (on|off|share|drop)
57
+
58
+ \u26A0\uFE0F cc-room does not notify others automatically.
59
+ Share the room name and PIN yourself.
60
+
61
+ You need to be on the same Wi\u2011Fi (LAN).
62
+ (A VPN that creates a shared LAN also works.)
63
+
64
+ Uninstall: npx setup-cc-room uninstall
65
+ Japanese UI: npx setup-cc-room --lang ja
66
+
67
+ Docs: https://github.com/takanorisuzuki/cc-room
68
+ `,
69
+ "install.step1": " [1/5] Setting up {dir}/bin/...",
70
+ "install.copied": " Copied: {path}",
71
+ "install.global_ok": " Found global binary: {path}",
72
+ "install.step2": " [2/5] Writing {path}...",
73
+ "install.config_created": " Created: {path} (identity: {identity})",
74
+ "install.config_skip": " Skip: {path} already exists",
75
+ "install.step3": " [3/5] Installing slash commands ({locale})...",
76
+ "install.commands_ok": " Installed {count} files into {dir}",
77
+ "install.step4": " [4/5] Updating .claude/settings.json...",
78
+ "install.step5": " [5/5] Registering OS auto-start...",
79
+ "daemon.missing": "cc-room-daemon not found. In the repo run `pnpm --filter setup-cc-room run pack:vendor`, or use the npm setup-cc-room package.",
80
+ "settings.updated": " Updated {path}",
81
+ "settings.parse_fail_backup": " \x1B[33m\u26A0 Failed to parse settings.json. Creating a backup and overwriting.\x1B[0m",
82
+ "settings.skip_missing": " Skip: {path} does not exist",
83
+ "settings.parse_fail_skip": " \x1B[33m\u26A0 Failed to parse settings.json; skipped removing hooks/MCP.\x1B[0m",
84
+ "settings.stripped": " Removed cc-room from {path}",
85
+ "svc.launchd_ok": " Registered with launchd: {path}",
86
+ "svc.launchd_fail": " \x1B[33m\u26A0 launchd registration failed: {msg}\x1B[0m",
87
+ "svc.launchd_manual": " Manual: launchctl load {path}",
88
+ "svc.systemd_ok": " Registered with systemd: {path}",
89
+ "svc.systemd_fail": " \x1B[33m\u26A0 systemd registration failed: {msg}\x1B[0m",
90
+ "svc.systemd_manual": " Manual: systemctl --user enable --now cc-room-daemon",
91
+ "svc.cc_room_home_unsafe": " \x1B[33m\u26A0 CC_ROOM_HOME contains characters unsafe for systemd (newline/quote); omitting from unit file\x1B[0m",
92
+ "svc.unsupported": " \x1B[33m\u26A0 Auto-start is not supported on {os}. Start cc-room-daemon manually.\x1B[0m",
93
+ "svc.waiting": " Waiting for daemon to start...",
94
+ "svc.started": " Daemon started",
95
+ "svc.start_unconfirmed": " \x1B[33m\u26A0 Could not confirm daemon start. Run cc-room-daemon manually.\x1B[0m",
96
+ "un.step1": " [1/4] Stopping OS service...",
97
+ "un.launchd_none": " launchd: not registered",
98
+ "un.launchd_ok": " Unregistered launchd: {path}",
99
+ "un.plist_fail": " \x1B[33m\u26A0 Failed to remove plist: {msg}\x1B[0m",
100
+ "un.systemd_ok": " Unregistered systemd: {path}",
101
+ "un.unit_fail": " \x1B[33m\u26A0 Failed to remove unit: {msg}\x1B[0m",
102
+ "un.systemd_none": " systemd: not registered",
103
+ "un.os_manual": " {os}: unregister auto-start manually",
104
+ "un.step2": " [2/4] Removing slash commands...",
105
+ "un.commands_ok": " Removed {count} command files ({dir})",
106
+ "un.step3": " [3/4] Removing cc-room from .claude/settings.json...",
107
+ "un.step4": " [4/4] Removing data directory...",
108
+ "un.data_skip": " Skip: {dir} does not exist",
109
+ "un.data_ok": " Deleted: {dir}",
110
+ "val.node_bad": "Node.js {version} (20+ required)",
111
+ "val.node_hint": "Upgrade to Node.js 20+: https://nodejs.org/",
112
+ "val.claude_ok": "Claude Code is installed",
113
+ "val.claude_missing": "Claude Code not found",
114
+ "val.claude_hint": "Install Claude Code: https://claude.ai/code",
115
+ "val.claude_dir_ok": "~/.claude/ directory exists",
116
+ "val.claude_dir_missing": "~/.claude/ not found",
117
+ "val.claude_dir_hint": "Start Claude Code once to create a session",
118
+ "val.settings_writable": "settings.json is writable",
119
+ "val.settings_not_writable": "No write permission for settings.json",
120
+ "val.settings_chmod": "Run chmod 644 {path}",
121
+ "val.settings_creatable": "Can create settings.json",
122
+ "val.claude_dir_not_writable": "No write permission for ~/.claude/",
123
+ "val.claude_dir_chmod": "Run chmod 755 {path}",
124
+ "val.hooks_unset": "Hooks: unrestricted (no settings.json yet)",
125
+ "val.hooks_disabled": "Hooks are disabled",
126
+ "val.hooks_disabled_hint": "cc-room needs the PostToolUse hook. Remove the hooks disable setting from settings.json",
127
+ "val.hooks_ok": "Hooks: enabled",
128
+ "val.hooks_unrestricted": "Hooks: unrestricted",
129
+ "val.mcp_ok": "MCP Server: can register",
130
+ "val.mcp_disabled": "MCP Server registration is disabled",
131
+ "val.mcp_disabled_hint": "cc-room talks to Claude Code via MCP. Remove the MCP disable setting from settings.json",
132
+ "val.session_ok": "Session directory exists",
133
+ "val.session_pending": "Session directory not created yet (appears after first session)",
134
+ "val.git_ok": "Git user: {name}",
135
+ "val.git_no_name": "git user.name is not set",
136
+ "val.git_no_name_hint": 'Set with git config --global user.name "Your Name" (used as cc-room identity)',
137
+ "val.git_missing": "git not found",
138
+ "val.git_hint": "Install git"
139
+ };
140
+ var ja = {
141
+ "cli.running_preflight": " Preflight checks \u3092\u5B9F\u884C\u4E2D...",
142
+ "cli.preflight_failed": " \x1B[31m\u524D\u63D0\u6761\u4EF6\u3092\u6E80\u305F\u3057\u3066\u3044\u307E\u305B\u3093\u3002\u4E0A\u8A18\u306E\u554F\u984C\u3092\u89E3\u6C7A\u3057\u3066\u304B\u3089\u518D\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002\x1B[0m\n",
143
+ "cli.preflight_ok": " \x1B[32m\u5168\u30C1\u30A7\u30C3\u30AF\u901A\u904E\u3002\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u3092\u958B\u59CB\u3057\u307E\u3059\u3002\x1B[0m\n",
144
+ "cli.install_done": " \x1B[32m\u2705 \u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u304C\u5B8C\u4E86\u3057\u307E\u3057\u305F\uFF01\x1B[0m",
145
+ "cli.uninstall_done": " \x1B[32m\u2705 \u30A2\u30F3\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u304C\u5B8C\u4E86\u3057\u307E\u3057\u305F\u3002\x1B[0m",
146
+ "cli.restart_claude": " Claude Code \u3092\u518D\u8D77\u52D5\u3057\u3066\u304F\u3060\u3055\u3044\uFF08hooks / MCP \u306E\u53CD\u6620\uFF09\u3002",
147
+ "cli.unknown_arg": " \u4E0D\u660E\u306A\u5F15\u6570: {arg}",
148
+ "cli.error": " \x1B[31m\u30A8\u30E9\u30FC:\x1B[0m",
149
+ "cli.help": `
150
+ \u{1F3E0} setup-cc-room v{version}
151
+
152
+ \u4F7F\u3044\u65B9:
153
+ npx setup-cc-room \u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\uFF08\u30C7\u30D5\u30A9\u30EB\u30C8\u306F\u82F1\u8A9E\uFF09
154
+ npx setup-cc-room --lang ja \u65E5\u672C\u8A9E UI / \u30B3\u30DE\u30F3\u30C9\u3067\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB
155
+ npx setup-cc-room uninstall \u30A2\u30F3\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB
156
+ npx setup-cc-room --help \u30D8\u30EB\u30D7
157
+
158
+ \u8A00\u8A9E: --lang en|ja \u307E\u305F\u306F CC_ROOM_LANG=ja
159
+ `,
160
+ "cli.install_guide": `
161
+ cc-room \u306E\u4F7F\u3044\u65B9:
162
+
163
+ \u3010\u4F1A\u8B70\u5BA4\u3092\u958B\u304F\u5834\u5408\u3011
164
+ 1. Claude Code \u3092\u518D\u8D77\u52D5\uFF08MCP \u3068 Hooks \u3092\u6709\u52B9\u5316\uFF09
165
+ 2. /room open <name> \u2190 \u4F1A\u8B70\u5BA4\u3092\u958B\u304F\uFF08PIN \u767A\u884C\uFF09
166
+ 3. \u8868\u793A\u3055\u308C\u308B\u90E8\u5C4B\u540D\u3068 PIN \u3092\u76F8\u624B\u306B\u53E3\u982D\u3084 DM \u3067\u4F1D\u3048\u308B
167
+ 4. \u76F8\u624B\u304C /room join <name> <PIN> \u3092\u5B9F\u884C\u3059\u308C\u3070\u53C2\u52A0\u5B8C\u4E86
168
+
169
+ \u3010\u62DB\u5F85\u3055\u308C\u305F\u5834\u5408\u3011
170
+ 1. Claude Code \u3092\u518D\u8D77\u52D5
171
+ 2. /room join <name> <PIN> \u2190 \u76F8\u624B\u304B\u3089\u53D7\u3051\u53D6\u3063\u305F\u5024\u3092\u5165\u529B
172
+
173
+ \u3010\u65E5\u5E38\u64CD\u4F5C\u3011
174
+ /room \u2026 \u30DB\u30EF\u30A4\u30C8\u30DC\u30FC\u30C9\u3092\u898B\u308B
175
+ /private \u2026 \u72B6\u614B\u8868\u793A\u3001\u624B\u5143/\u516C\u958B\u306E\u5207\u66FF\uFF08on|off|share|drop\uFF09
176
+
177
+ \u26A0\uFE0F cc-room \u306F\u81EA\u52D5\u3067\u76F8\u624B\u306B\u901A\u77E5\u3057\u307E\u305B\u3093\u3002
178
+ \u90E8\u5C4B\u540D\u3068 PIN \u306F\u81EA\u5206\u3067\u76F8\u624B\u306B\u4F1D\u3048\u3066\u304F\u3060\u3055\u3044\u3002
179
+
180
+ \u63A5\u7D9A\u5F8C\u306F\u540C\u3058 WiFi\uFF08LAN\uFF09\u5185\u306B\u3044\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002
181
+ \uFF08VPN \u3067\u540C\u4E00 LAN \u76F8\u5F53\u306B\u306A\u308C\u3070\u30EA\u30E2\u30FC\u30C8\u3067\u3082\u4F7F\u3048\u307E\u3059\uFF09
182
+
183
+ \u30A2\u30F3\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB: npx setup-cc-room uninstall
184
+
185
+ \u30C9\u30AD\u30E5\u30E1\u30F3\u30C8: https://github.com/takanorisuzuki/cc-room
186
+ `,
187
+ "install.step1": " [1/5] {dir}/bin/ \u306E\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7...",
188
+ "install.copied": " \u30B3\u30D4\u30FC\u5B8C\u4E86: {path}",
189
+ "install.global_ok": " \u30B0\u30ED\u30FC\u30D0\u30EB\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u78BA\u8A8D\u6E08\u307F: {path}",
190
+ "install.step2": " [2/5] {path} \u306E\u751F\u6210...",
191
+ "install.config_created": " \u751F\u6210\u5B8C\u4E86: {path} (identity: {identity})",
192
+ "install.config_skip": " \u30B9\u30AD\u30C3\u30D7: {path} \u306F\u65E2\u306B\u5B58\u5728\u3057\u307E\u3059",
193
+ "install.step3": " [3/5] \u30B3\u30DE\u30F3\u30C9\u30D5\u30A1\u30A4\u30EB\u306E\u914D\u7F6E ({locale})...",
194
+ "install.commands_ok": " {count} \u30D5\u30A1\u30A4\u30EB\u3092 {dir} \u306B\u914D\u7F6E\u3057\u307E\u3057\u305F",
195
+ "install.step4": " [4/5] .claude/settings.json \u306E\u66F4\u65B0...",
196
+ "install.step5": " [5/5] OS\u81EA\u52D5\u8D77\u52D5\u306E\u767B\u9332...",
197
+ "daemon.missing": "cc-room-daemon \u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002\u30EA\u30DD\u30B8\u30C8\u30EA\u3067\u306F `pnpm --filter setup-cc-room run pack:vendor` \u3092\u5B9F\u884C\u3059\u308B\u304B\u3001npm \u306E setup-cc-room \u30D1\u30C3\u30B1\u30FC\u30B8\u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044\u3002",
198
+ "settings.updated": " {path} \u3092\u66F4\u65B0\u3057\u307E\u3057\u305F",
199
+ "settings.parse_fail_backup": " \x1B[33m\u26A0 settings.json \u306E\u30D1\u30FC\u30B9\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002\u30D0\u30C3\u30AF\u30A2\u30C3\u30D7\u3092\u4F5C\u6210\u3057\u3066\u4E0A\u66F8\u304D\u3057\u307E\u3059\u3002\x1B[0m",
200
+ "settings.parse_fail_skip": " \x1B[33m\u26A0 settings.json \u306E\u30D1\u30FC\u30B9\u306B\u5931\u6557\u3057\u305F\u305F\u3081\u3001hooks/MCP \u306E\u9664\u53BB\u3092\u30B9\u30AD\u30C3\u30D7\u3057\u307E\u3059\u3002\x1B[0m",
201
+ "settings.skip_missing": " \u30B9\u30AD\u30C3\u30D7: {path} \u306F\u5B58\u5728\u3057\u307E\u305B\u3093",
202
+ "settings.stripped": " {path} \u304B\u3089 cc-room \u3092\u9664\u53BB\u3057\u307E\u3057\u305F",
203
+ "svc.launchd_ok": " launchd \u306B\u767B\u9332\u3057\u307E\u3057\u305F: {path}",
204
+ "svc.launchd_fail": " \x1B[33m\u26A0 launchd \u767B\u9332\u306B\u5931\u6557\u3057\u307E\u3057\u305F: {msg}\x1B[0m",
205
+ "svc.launchd_manual": " \u624B\u52D5\u3067\u767B\u9332: launchctl load {path}",
206
+ "svc.systemd_ok": " systemd \u306B\u767B\u9332\u3057\u307E\u3057\u305F: {path}",
207
+ "svc.systemd_fail": " \x1B[33m\u26A0 systemd \u767B\u9332\u306B\u5931\u6557\u3057\u307E\u3057\u305F: {msg}\x1B[0m",
208
+ "svc.systemd_manual": " \u624B\u52D5\u3067\u767B\u9332: systemctl --user enable --now cc-room-daemon",
209
+ "svc.cc_room_home_unsafe": " \x1B[33m\u26A0 CC_ROOM_HOME \u306B systemd \u3067\u5371\u967A\u306A\u6587\u5B57\uFF08\u6539\u884C/\u5F15\u7528\u7B26\uFF09\u304C\u542B\u307E\u308C\u308B\u305F\u3081 unit \u304B\u3089\u7701\u7565\u3057\u307E\u3059\x1B[0m",
210
+ "svc.unsupported": " \x1B[33m\u26A0 {os} \u3067\u306E\u81EA\u52D5\u8D77\u52D5\u767B\u9332\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002\u624B\u52D5\u3067 cc-room-daemon \u3092\u8D77\u52D5\u3057\u3066\u304F\u3060\u3055\u3044\u3002\x1B[0m",
211
+ "svc.waiting": " daemon \u306E\u8D77\u52D5\u3092\u5F85\u6A5F\u4E2D...",
212
+ "svc.started": " daemon \u304C\u8D77\u52D5\u3057\u307E\u3057\u305F",
213
+ "svc.start_unconfirmed": " \x1B[33m\u26A0 daemon \u306E\u81EA\u52D5\u8D77\u52D5\u78BA\u8A8D\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u624B\u52D5\u3067 cc-room-daemon \u3092\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002\x1B[0m",
214
+ "un.step1": " [1/4] OS \u30B5\u30FC\u30D3\u30B9\u3092\u505C\u6B62...",
215
+ "un.launchd_none": " launchd: \u672A\u767B\u9332",
216
+ "un.launchd_ok": " launchd \u3092\u89E3\u9664: {path}",
217
+ "un.plist_fail": " \x1B[33m\u26A0 plist \u524A\u9664\u306B\u5931\u6557: {msg}\x1B[0m",
218
+ "un.systemd_ok": " systemd \u3092\u89E3\u9664: {path}",
219
+ "un.unit_fail": " \x1B[33m\u26A0 unit \u524A\u9664\u306B\u5931\u6557: {msg}\x1B[0m",
220
+ "un.systemd_none": " systemd: \u672A\u767B\u9332",
221
+ "un.os_manual": " {os}: \u81EA\u52D5\u8D77\u52D5\u306E\u89E3\u9664\u306F\u624B\u52D5\u3067\u884C\u3063\u3066\u304F\u3060\u3055\u3044",
222
+ "un.step2": " [2/4] Slash commands \u3092\u524A\u9664...",
223
+ "un.commands_ok": " \u30B3\u30DE\u30F3\u30C9\u30D5\u30A1\u30A4\u30EB\u3092 {count} \u4EF6\u524A\u9664 ({dir})",
224
+ "un.step3": " [3/4] .claude/settings.json \u304B\u3089 cc-room \u3092\u9664\u53BB...",
225
+ "un.step4": " [4/4] \u30C7\u30FC\u30BF\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3092\u524A\u9664...",
226
+ "un.data_skip": " \u30B9\u30AD\u30C3\u30D7: {dir} \u306F\u5B58\u5728\u3057\u307E\u305B\u3093",
227
+ "un.data_ok": " \u524A\u9664: {dir}",
228
+ "val.node_bad": "Node.js {version} (20+ \u304C\u5FC5\u8981)",
229
+ "val.node_hint": "Node.js 20 \u4EE5\u4E0A\u306B\u30A2\u30C3\u30D7\u30B0\u30EC\u30FC\u30C9\u3057\u3066\u304F\u3060\u3055\u3044: https://nodejs.org/",
230
+ "val.claude_ok": "Claude Code \u304C\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u6E08\u307F",
231
+ "val.claude_missing": "Claude Code \u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093",
232
+ "val.claude_hint": "Claude Code \u3092\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u3057\u3066\u304F\u3060\u3055\u3044: https://claude.ai/code",
233
+ "val.claude_dir_ok": "~/.claude/ \u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u304C\u5B58\u5728",
234
+ "val.claude_dir_missing": "~/.claude/ \u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093",
235
+ "val.claude_dir_hint": "Claude Code \u3092\u4E00\u5EA6\u8D77\u52D5\u3057\u3066\u30BB\u30C3\u30B7\u30E7\u30F3\u3092\u4F5C\u6210\u3057\u3066\u304F\u3060\u3055\u3044",
236
+ "val.settings_writable": "settings.json \u306B\u66F8\u304D\u8FBC\u307F\u53EF\u80FD",
237
+ "val.settings_not_writable": "settings.json \u306B\u66F8\u304D\u8FBC\u307F\u6A29\u9650\u304C\u3042\u308A\u307E\u305B\u3093",
238
+ "val.settings_chmod": "chmod 644 {path} \u3092\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044",
239
+ "val.settings_creatable": "settings.json \u3092\u4F5C\u6210\u53EF\u80FD",
240
+ "val.claude_dir_not_writable": "~/.claude/ \u306B\u66F8\u304D\u8FBC\u307F\u6A29\u9650\u304C\u3042\u308A\u307E\u305B\u3093",
241
+ "val.claude_dir_chmod": "chmod 755 {path} \u3092\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044",
242
+ "val.hooks_unset": "Hooks: \u5236\u9650\u306A\u3057\uFF08settings.json \u672A\u4F5C\u6210\uFF09",
243
+ "val.hooks_disabled": "Hooks \u304C\u7121\u52B9\u5316\u3055\u308C\u3066\u3044\u307E\u3059",
244
+ "val.hooks_disabled_hint": "cc-room \u306F\u30D5\u30A1\u30A4\u30EB\u5171\u6709\u306B PostToolUse hook \u3092\u4F7F\u7528\u3057\u307E\u3059\u3002settings.json \u304B\u3089 hooks \u306E\u7121\u52B9\u5316\u8A2D\u5B9A\u3092\u524A\u9664\u3057\u3066\u304F\u3060\u3055\u3044",
245
+ "val.hooks_ok": "Hooks: \u6709\u52B9",
246
+ "val.hooks_unrestricted": "Hooks: \u5236\u9650\u306A\u3057",
247
+ "val.mcp_ok": "MCP Server: \u767B\u9332\u53EF\u80FD",
248
+ "val.mcp_disabled": "MCP Server \u306E\u767B\u9332\u304C\u7121\u52B9\u5316\u3055\u308C\u3066\u3044\u307E\u3059",
249
+ "val.mcp_disabled_hint": "cc-room \u306F MCP Server \u7D4C\u7531\u3067 Claude Code \u3068\u9023\u643A\u3057\u307E\u3059\u3002settings.json \u304B\u3089 MCP \u306E\u7121\u52B9\u5316\u8A2D\u5B9A\u3092\u524A\u9664\u3057\u3066\u304F\u3060\u3055\u3044",
250
+ "val.session_ok": "\u30BB\u30C3\u30B7\u30E7\u30F3\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u304C\u5B58\u5728",
251
+ "val.session_pending": "\u30BB\u30C3\u30B7\u30E7\u30F3\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u672A\u4F5C\u6210\uFF08\u521D\u56DE\u30BB\u30C3\u30B7\u30E7\u30F3\u5F8C\u306B\u751F\u6210\u3055\u308C\u308B\uFF09",
252
+ "val.git_ok": "Git \u30E6\u30FC\u30B6\u30FC: {name}",
253
+ "val.git_no_name": "git user.name \u304C\u672A\u8A2D\u5B9A",
254
+ "val.git_no_name_hint": 'git config --global user.name "Your Name" \u3067\u8A2D\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\uFF08cc-room \u306E identity \u306B\u4F7F\u7528\uFF09',
255
+ "val.git_missing": "git \u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093",
256
+ "val.git_hint": "git \u3092\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u3057\u3066\u304F\u3060\u3055\u3044"
257
+ };
258
+ var catalogs = { en, ja };
259
+ var activeLocale = "en";
260
+ function setLocale(locale) {
261
+ activeLocale = locale;
262
+ }
263
+ function getLocale() {
264
+ return activeLocale;
265
+ }
266
+ function t(key, vars = {}) {
267
+ const catalog = catalogs[activeLocale] ?? catalogs.en;
268
+ let template = catalog[key] ?? catalogs.en[key] ?? key;
269
+ for (const [k, v] of Object.entries(vars)) {
270
+ template = template.replaceAll(`{${k}}`, String(v));
271
+ }
272
+ return template;
273
+ }
274
+
275
+ export {
276
+ resolveLocale,
277
+ setLocale,
278
+ getLocale,
279
+ t
280
+ };
@@ -0,0 +1,125 @@
1
+ import {
2
+ resolveDaemonSource
3
+ } from "./chunk-3AMPTQ5K.js";
4
+ import {
5
+ registerService
6
+ } from "./chunk-EF2H256X.js";
7
+ import {
8
+ mergeSettings
9
+ } from "./chunk-DXODI3WA.js";
10
+ import {
11
+ t
12
+ } from "./chunk-OYW7MM4W.js";
13
+ import {
14
+ resolveCcRoomDir
15
+ } from "./chunk-WCEABGOA.js";
16
+
17
+ // src/installer.ts
18
+ import {
19
+ mkdirSync,
20
+ writeFileSync,
21
+ existsSync,
22
+ copyFileSync,
23
+ chmodSync,
24
+ unlinkSync
25
+ } from "fs";
26
+ import { join, dirname } from "path";
27
+ import { homedir } from "os";
28
+ import { execFileSync, spawnSync } from "child_process";
29
+ import { fileURLToPath } from "url";
30
+ import { stringify } from "yaml";
31
+ var CC_ROOM_DIR = resolveCcRoomDir();
32
+ var BIN_DIR = join(CC_ROOM_DIR, "bin");
33
+ var CONFIG_PATH = join(CC_ROOM_DIR, "config.yaml");
34
+ var COMMANDS_DIR = join(homedir(), ".claude", "commands");
35
+ var THIS_DIR = dirname(fileURLToPath(import.meta.url));
36
+ var SETUP_PACKAGE_ROOT = join(THIS_DIR, "..");
37
+ function getGitUserName() {
38
+ try {
39
+ return execFileSync("git", ["config", "user.name"], { encoding: "utf-8", stdio: "pipe" }).trim();
40
+ } catch {
41
+ return "unknown";
42
+ }
43
+ }
44
+ function resolveCommandSources(setupPackageRoot, locale) {
45
+ const candidates = [
46
+ join(setupPackageRoot, "vendor", "commands", "room", locale),
47
+ join(setupPackageRoot, "..", "commands", "room", locale),
48
+ // legacy flat layout (pre-i18n)
49
+ join(setupPackageRoot, "vendor", "commands", "room"),
50
+ join(setupPackageRoot, "..", "commands", "room")
51
+ ];
52
+ for (const dir of candidates) {
53
+ if (existsSync(join(dir, "room.md"))) return dir;
54
+ }
55
+ return null;
56
+ }
57
+ async function install(locale = "en") {
58
+ console.log(t("install.step1", { dir: CC_ROOM_DIR }));
59
+ mkdirSync(BIN_DIR, { recursive: true });
60
+ const daemonSrc = resolveDaemonSource(SETUP_PACKAGE_ROOT);
61
+ const daemonDest = join(BIN_DIR, "cc-room-daemon");
62
+ if (daemonSrc) {
63
+ copyFileSync(daemonSrc, daemonDest);
64
+ chmodSync(daemonDest, 493);
65
+ console.log(t("install.copied", { path: daemonDest }));
66
+ } else {
67
+ const globalBin = spawnSync("which", ["cc-room-daemon"], { encoding: "utf-8" });
68
+ if (globalBin.status === 0) {
69
+ console.log(t("install.global_ok", { path: globalBin.stdout.trim() }));
70
+ } else {
71
+ console.log(` \x1B[33m\u26A0 ${t("daemon.missing")}\x1B[0m`);
72
+ }
73
+ }
74
+ console.log(t("install.step2", { path: CONFIG_PATH }));
75
+ if (!existsSync(CONFIG_PATH)) {
76
+ const identity = getGitUserName();
77
+ const config = {
78
+ identity: { name: identity },
79
+ ui: { locale },
80
+ network: { port: 7331, http_port: 7332 },
81
+ trust: [],
82
+ sessions: { default_mode: "approve", share_files: true, share_context: true },
83
+ privacy: {
84
+ public_tools: ["room_context", "room_messages", "room_files", "room_status", "room_invite", "room_share"],
85
+ private_patterns: [],
86
+ redact_after_private_tool: true
87
+ },
88
+ summarizer: { model: "claude-haiku-4-5-20251001", interval_turns: 5, interval_seconds: 30 },
89
+ storage: { max_bytes: 524288e3, artifact_ttl_days: 30, context_ttl_days: 7, message_ttl_days: 14 }
90
+ };
91
+ writeFileSync(CONFIG_PATH, stringify(config), { mode: 384 });
92
+ console.log(t("install.config_created", { path: CONFIG_PATH, identity }));
93
+ } else {
94
+ console.log(t("install.config_skip", { path: CONFIG_PATH }));
95
+ }
96
+ console.log(t("install.step3", { locale }));
97
+ mkdirSync(COMMANDS_DIR, { recursive: true });
98
+ const commandFiles = ["room.md", "private.md", "show.md"];
99
+ const legacyFiles = ["invite.md", "join.md", "leave.md", "files.md", "remember.md", "share.md"];
100
+ const commandsSrcDir = resolveCommandSources(SETUP_PACKAGE_ROOT, locale);
101
+ if (!commandsSrcDir) {
102
+ throw new Error(`Command source directory not found for locale=${locale}`);
103
+ }
104
+ for (const cmd of commandFiles) {
105
+ const src = join(commandsSrcDir, cmd);
106
+ if (!existsSync(src)) throw new Error(`Command source file not found: ${src}`);
107
+ copyFileSync(src, join(COMMANDS_DIR, cmd));
108
+ }
109
+ for (const legacy of legacyFiles) {
110
+ const dest = join(COMMANDS_DIR, legacy);
111
+ if (existsSync(dest)) {
112
+ unlinkSync(dest);
113
+ }
114
+ }
115
+ console.log(t("install.commands_ok", { count: commandFiles.length, dir: COMMANDS_DIR }));
116
+ console.log(t("install.step4"));
117
+ mergeSettings();
118
+ console.log(t("install.step5"));
119
+ await registerService();
120
+ }
121
+
122
+ export {
123
+ resolveCommandSources,
124
+ install
125
+ };
@@ -3,6 +3,5 @@
3
3
  * 優先: vendor 同梱(npm / pack:vendor)→ ローカル dist-bundle
4
4
  */
5
5
  declare function resolveDaemonSource(setupPackageRoot: string): string | null;
6
- declare const DAEMON_MISSING_HINT = "cc-room-daemon not found. In the repo run `pnpm --filter setup-cc-room run pack:vendor`, or use the npm setup-cc-room package.";
7
6
 
8
- export { DAEMON_MISSING_HINT, resolveDaemonSource };
7
+ export { resolveDaemonSource };
@@ -1,8 +1,6 @@
1
1
  import {
2
- DAEMON_MISSING_HINT,
3
2
  resolveDaemonSource
4
- } from "./chunk-KEFBOTQD.js";
3
+ } from "./chunk-3AMPTQ5K.js";
5
4
  export {
6
- DAEMON_MISSING_HINT,
7
5
  resolveDaemonSource
8
6
  };
package/dist/i18n.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  resolveLocale,
4
4
  setLocale,
5
5
  t
6
- } from "./chunk-OYW7MM4W.js";
6
+ } from "./chunk-Y4O4R4IQ.js";
7
7
  export {
8
8
  getLocale,
9
9
  resolveLocale,
package/dist/index.js CHANGED
@@ -2,26 +2,26 @@
2
2
  import {
3
3
  printResults,
4
4
  validateAll
5
- } from "./chunk-RYVZHEHF.js";
5
+ } from "./chunk-XX72CSJC.js";
6
6
  import {
7
7
  install
8
- } from "./chunk-SMSDMP5O.js";
9
- import "./chunk-KEFBOTQD.js";
10
- import "./chunk-ZDOKJ4KX.js";
8
+ } from "./chunk-RB72MUPN.js";
9
+ import "./chunk-3AMPTQ5K.js";
10
+ import "./chunk-NHOFSPZ5.js";
11
11
  import {
12
12
  uninstall
13
- } from "./chunk-MSQUTURC.js";
14
- import "./chunk-WCEABGOA.js";
15
- import "./chunk-MVD6RIS2.js";
13
+ } from "./chunk-F5MDW7XR.js";
14
+ import "./chunk-CVPLSBRZ.js";
16
15
  import {
17
16
  getLocale,
18
17
  resolveLocale,
19
18
  setLocale,
20
19
  t
21
- } from "./chunk-OYW7MM4W.js";
20
+ } from "./chunk-Y4O4R4IQ.js";
21
+ import "./chunk-WCEABGOA.js";
22
22
 
23
23
  // src/index.ts
24
- var VERSION = "0.2.2";
24
+ var VERSION = "0.2.4";
25
25
  function stripLangArgs(argv) {
26
26
  const out = [];
27
27
  for (let i = 0; i < argv.length; i++) {
package/dist/installer.js CHANGED
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  install,
3
3
  resolveCommandSources
4
- } from "./chunk-SMSDMP5O.js";
5
- import "./chunk-KEFBOTQD.js";
6
- import "./chunk-ZDOKJ4KX.js";
4
+ } from "./chunk-RB72MUPN.js";
5
+ import "./chunk-3AMPTQ5K.js";
6
+ import "./chunk-NHOFSPZ5.js";
7
+ import "./chunk-CVPLSBRZ.js";
8
+ import "./chunk-Y4O4R4IQ.js";
7
9
  import "./chunk-WCEABGOA.js";
8
- import "./chunk-MVD6RIS2.js";
9
- import "./chunk-OYW7MM4W.js";
10
10
  export {
11
11
  install,
12
12
  resolveCommandSources
@@ -1,3 +1,10 @@
1
+ /** launchd plist の <string> 用に XML 特殊文字をエスケープする */
2
+ declare function escapeXml(text: string): string;
3
+ /**
4
+ * systemd `Environment="KEY=value"` の value として安全なときだけ返す。
5
+ * 改行・NUL・二重引用符は unit ディレクティブ注入 / クォート破壊の恐れがある。
6
+ */
7
+ declare function sanitizeSystemdEnvValue(value: string): string | null;
1
8
  declare function registerService(): Promise<void>;
2
9
 
3
- export { registerService };
10
+ export { escapeXml, registerService, sanitizeSystemdEnvValue };
@@ -1,8 +1,13 @@
1
1
  import {
2
- registerService
3
- } from "./chunk-ZDOKJ4KX.js";
2
+ escapeXml,
3
+ registerService,
4
+ sanitizeSystemdEnvValue
5
+ } from "./chunk-NHOFSPZ5.js";
6
+ import "./chunk-CVPLSBRZ.js";
7
+ import "./chunk-Y4O4R4IQ.js";
4
8
  import "./chunk-WCEABGOA.js";
5
- import "./chunk-OYW7MM4W.js";
6
9
  export {
7
- registerService
10
+ escapeXml,
11
+ registerService,
12
+ sanitizeSystemdEnvValue
8
13
  };
@@ -1,6 +1,36 @@
1
+ /** Claude Code hooks / MCP から呼ぶ daemon の絶対パスを解決する */
2
+ declare function resolveDaemonCommand(env?: NodeJS.ProcessEnv): string;
3
+ declare function buildCcRoomHooks(daemonBin: string): {
4
+ UserPromptSubmit: {
5
+ hooks: {
6
+ type: string;
7
+ command: string;
8
+ }[];
9
+ }[];
10
+ PostToolUse: {
11
+ matcher: string;
12
+ hooks: {
13
+ type: string;
14
+ command: string;
15
+ }[];
16
+ }[];
17
+ Stop: {
18
+ hooks: {
19
+ type: string;
20
+ command: string;
21
+ }[];
22
+ }[];
23
+ };
24
+ declare function buildCcRoomMcp(daemonBin: string): {
25
+ "cc-room": {
26
+ type: string;
27
+ command: string;
28
+ args: string[];
29
+ };
30
+ };
1
31
  declare function mergeSettings(): void;
2
32
  /** settings.json から cc-room の hooks / mcpServers を除去(他設定は保持) */
3
33
  declare function stripCcRoomFromSettings(settings: Record<string, unknown>): Record<string, unknown>;
4
34
  declare function unmergeSettings(): void;
5
35
 
6
- export { mergeSettings, stripCcRoomFromSettings, unmergeSettings };
36
+ export { buildCcRoomHooks, buildCcRoomMcp, mergeSettings, resolveDaemonCommand, stripCcRoomFromSettings, unmergeSettings };
@@ -1,11 +1,18 @@
1
1
  import {
2
+ buildCcRoomHooks,
3
+ buildCcRoomMcp,
2
4
  mergeSettings,
5
+ resolveDaemonCommand,
3
6
  stripCcRoomFromSettings,
4
7
  unmergeSettings
5
- } from "./chunk-MVD6RIS2.js";
6
- import "./chunk-OYW7MM4W.js";
8
+ } from "./chunk-CVPLSBRZ.js";
9
+ import "./chunk-Y4O4R4IQ.js";
10
+ import "./chunk-WCEABGOA.js";
7
11
  export {
12
+ buildCcRoomHooks,
13
+ buildCcRoomMcp,
8
14
  mergeSettings,
15
+ resolveDaemonCommand,
9
16
  stripCcRoomFromSettings,
10
17
  unmergeSettings
11
18
  };
@@ -7,10 +7,10 @@ import {
7
7
  stopOrphanDaemon,
8
8
  stopSystemd,
9
9
  uninstall
10
- } from "./chunk-MSQUTURC.js";
10
+ } from "./chunk-F5MDW7XR.js";
11
+ import "./chunk-CVPLSBRZ.js";
12
+ import "./chunk-Y4O4R4IQ.js";
11
13
  import "./chunk-WCEABGOA.js";
12
- import "./chunk-MVD6RIS2.js";
13
- import "./chunk-OYW7MM4W.js";
14
14
  export {
15
15
  getLaunchdPlistPath,
16
16
  getSystemdUnitPath,
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  printResults,
3
3
  validateAll
4
- } from "./chunk-RYVZHEHF.js";
5
- import "./chunk-OYW7MM4W.js";
4
+ } from "./chunk-XX72CSJC.js";
5
+ import "./chunk-Y4O4R4IQ.js";
6
6
  export {
7
7
  printResults,
8
8
  validateAll
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "setup-cc-room",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "Install cc-room — bring your Claude Code into a shared LAN meeting room",
5
5
  "license": "MIT",
6
6
  "author": "Takanori Suzuki",