setup-cc-room 0.2.0 → 0.2.1
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/dist/chunk-6SYATEI6.js +108 -0
- package/dist/chunk-AVDOC76K.js +116 -0
- package/dist/chunk-ETJNYBPF.js +116 -0
- package/dist/chunk-LMBNCW4L.js +142 -0
- package/dist/index.js +50 -4
- package/dist/installer.js +2 -2
- package/dist/settings-merger.d.ts +4 -1
- package/dist/settings-merger.js +7 -3
- package/dist/uninstaller.d.ts +10 -0
- package/dist/uninstaller.js +22 -0
- package/package.json +2 -2
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DAEMON_MISSING_HINT,
|
|
3
|
+
resolveDaemonSource
|
|
4
|
+
} from "./chunk-R5BAC4BK.js";
|
|
5
|
+
import {
|
|
6
|
+
registerService
|
|
7
|
+
} from "./chunk-UWFC4FU6.js";
|
|
8
|
+
import {
|
|
9
|
+
resolveCcRoomDir
|
|
10
|
+
} from "./chunk-WCEABGOA.js";
|
|
11
|
+
import {
|
|
12
|
+
mergeSettings
|
|
13
|
+
} from "./chunk-ETJNYBPF.js";
|
|
14
|
+
|
|
15
|
+
// src/installer.ts
|
|
16
|
+
import {
|
|
17
|
+
mkdirSync,
|
|
18
|
+
writeFileSync,
|
|
19
|
+
existsSync,
|
|
20
|
+
copyFileSync,
|
|
21
|
+
chmodSync,
|
|
22
|
+
unlinkSync
|
|
23
|
+
} from "fs";
|
|
24
|
+
import { join, dirname } from "path";
|
|
25
|
+
import { homedir } from "os";
|
|
26
|
+
import { execFileSync, spawnSync } from "child_process";
|
|
27
|
+
import { fileURLToPath } from "url";
|
|
28
|
+
import { stringify } from "yaml";
|
|
29
|
+
var CC_ROOM_DIR = resolveCcRoomDir();
|
|
30
|
+
var BIN_DIR = join(CC_ROOM_DIR, "bin");
|
|
31
|
+
var CONFIG_PATH = join(CC_ROOM_DIR, "config.yaml");
|
|
32
|
+
var COMMANDS_DIR = join(homedir(), ".claude", "commands");
|
|
33
|
+
var THIS_DIR = dirname(fileURLToPath(import.meta.url));
|
|
34
|
+
var SETUP_PACKAGE_ROOT = join(THIS_DIR, "..");
|
|
35
|
+
function getGitUserName() {
|
|
36
|
+
try {
|
|
37
|
+
return execFileSync("git", ["config", "user.name"], { encoding: "utf-8", stdio: "pipe" }).trim();
|
|
38
|
+
} catch {
|
|
39
|
+
return "unknown";
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
async function install() {
|
|
43
|
+
console.log(` [1/5] ${CC_ROOM_DIR}/bin/ \u306E\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7...`);
|
|
44
|
+
mkdirSync(BIN_DIR, { recursive: true });
|
|
45
|
+
const daemonSrc = resolveDaemonSource(SETUP_PACKAGE_ROOT);
|
|
46
|
+
const daemonDest = join(BIN_DIR, "cc-room-daemon");
|
|
47
|
+
if (daemonSrc) {
|
|
48
|
+
copyFileSync(daemonSrc, daemonDest);
|
|
49
|
+
chmodSync(daemonDest, 493);
|
|
50
|
+
console.log(` \u30B3\u30D4\u30FC\u5B8C\u4E86: ${daemonDest}`);
|
|
51
|
+
} else {
|
|
52
|
+
const globalBin = spawnSync("which", ["cc-room-daemon"], { encoding: "utf-8" });
|
|
53
|
+
if (globalBin.status === 0) {
|
|
54
|
+
console.log(` \u30B0\u30ED\u30FC\u30D0\u30EB\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u78BA\u8A8D\u6E08\u307F: ${globalBin.stdout.trim()}`);
|
|
55
|
+
} else {
|
|
56
|
+
console.log(` \x1B[33m\u26A0 ${DAEMON_MISSING_HINT}\x1B[0m`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
console.log(` [2/5] ${CONFIG_PATH} \u306E\u751F\u6210...`);
|
|
60
|
+
if (!existsSync(CONFIG_PATH)) {
|
|
61
|
+
const identity = getGitUserName();
|
|
62
|
+
const config = {
|
|
63
|
+
identity: { name: identity },
|
|
64
|
+
network: { port: 7331, http_port: 7332 },
|
|
65
|
+
trust: [],
|
|
66
|
+
sessions: { default_mode: "approve", share_files: true, share_context: true },
|
|
67
|
+
privacy: {
|
|
68
|
+
public_tools: ["room_context", "room_messages", "room_files", "room_status", "room_invite", "room_share"],
|
|
69
|
+
private_patterns: [],
|
|
70
|
+
redact_after_private_tool: true
|
|
71
|
+
},
|
|
72
|
+
summarizer: { model: "claude-haiku-4-5-20251001", interval_turns: 5, interval_seconds: 30 },
|
|
73
|
+
storage: { max_bytes: 524288e3, artifact_ttl_days: 30, context_ttl_days: 7, message_ttl_days: 14 }
|
|
74
|
+
};
|
|
75
|
+
writeFileSync(CONFIG_PATH, stringify(config), { mode: 384 });
|
|
76
|
+
console.log(` \u751F\u6210\u5B8C\u4E86: ${CONFIG_PATH} (identity: ${identity})`);
|
|
77
|
+
} else {
|
|
78
|
+
console.log(` \u30B9\u30AD\u30C3\u30D7: ${CONFIG_PATH} \u306F\u65E2\u306B\u5B58\u5728\u3057\u307E\u3059`);
|
|
79
|
+
}
|
|
80
|
+
console.log(" [3/5] \u30B3\u30DE\u30F3\u30C9\u30D5\u30A1\u30A4\u30EB\u306E\u914D\u7F6E...");
|
|
81
|
+
mkdirSync(COMMANDS_DIR, { recursive: true });
|
|
82
|
+
const commandFiles = ["room.md", "private.md", "show.md"];
|
|
83
|
+
const legacyFiles = ["invite.md", "join.md", "leave.md", "files.md", "remember.md", "share.md"];
|
|
84
|
+
for (const cmd of commandFiles) {
|
|
85
|
+
const src = [
|
|
86
|
+
join(THIS_DIR, "..", "vendor", "commands", "room", cmd),
|
|
87
|
+
join(THIS_DIR, "..", "..", "commands", "room", cmd),
|
|
88
|
+
join(THIS_DIR, "..", "commands", "room", cmd)
|
|
89
|
+
].find(existsSync);
|
|
90
|
+
if (!src) throw new Error(`Command source file not found: ${cmd}`);
|
|
91
|
+
copyFileSync(src, join(COMMANDS_DIR, cmd));
|
|
92
|
+
}
|
|
93
|
+
for (const legacy of legacyFiles) {
|
|
94
|
+
const dest = join(COMMANDS_DIR, legacy);
|
|
95
|
+
if (existsSync(dest)) {
|
|
96
|
+
unlinkSync(dest);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
console.log(` ${commandFiles.length} \u30D5\u30A1\u30A4\u30EB\u3092 ${COMMANDS_DIR} \u306B\u914D\u7F6E\u3057\u307E\u3057\u305F`);
|
|
100
|
+
console.log(" [4/5] .claude/settings.json \u306E\u66F4\u65B0...");
|
|
101
|
+
mergeSettings();
|
|
102
|
+
console.log(" [5/5] OS\u81EA\u52D5\u8D77\u52D5\u306E\u767B\u9332...");
|
|
103
|
+
await registerService();
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export {
|
|
107
|
+
install
|
|
108
|
+
};
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import {
|
|
2
|
+
resolveCcRoomDir
|
|
3
|
+
} from "./chunk-WCEABGOA.js";
|
|
4
|
+
import {
|
|
5
|
+
unmergeSettings
|
|
6
|
+
} from "./chunk-ETJNYBPF.js";
|
|
7
|
+
|
|
8
|
+
// src/uninstaller.ts
|
|
9
|
+
import {
|
|
10
|
+
existsSync,
|
|
11
|
+
mkdirSync,
|
|
12
|
+
rmSync,
|
|
13
|
+
unlinkSync
|
|
14
|
+
} from "fs";
|
|
15
|
+
import { join } from "path";
|
|
16
|
+
import { homedir, platform } from "os";
|
|
17
|
+
import { execFileSync, spawnSync } from "child_process";
|
|
18
|
+
var COMMAND_FILES = ["room.md", "private.md", "show.md"];
|
|
19
|
+
function getLaunchdPlistPath(home = homedir()) {
|
|
20
|
+
return join(home, "Library", "LaunchAgents", "dev.ccroom.daemon.plist");
|
|
21
|
+
}
|
|
22
|
+
function getSystemdUnitPath(home = homedir()) {
|
|
23
|
+
return join(home, ".config", "systemd", "user", "cc-room-daemon.service");
|
|
24
|
+
}
|
|
25
|
+
function stopLaunchd(plistPath) {
|
|
26
|
+
if (!existsSync(plistPath)) {
|
|
27
|
+
console.log(" launchd: \u672A\u767B\u9332");
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
execFileSync("launchctl", ["unload", plistPath], { stdio: "pipe" });
|
|
32
|
+
} catch {
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
unlinkSync(plistPath);
|
|
36
|
+
console.log(` launchd \u3092\u89E3\u9664: ${plistPath}`);
|
|
37
|
+
} catch (err) {
|
|
38
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
39
|
+
console.log(` \x1B[33m\u26A0 plist \u524A\u9664\u306B\u5931\u6557: ${msg}\x1B[0m`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function stopSystemd(unitPath) {
|
|
43
|
+
try {
|
|
44
|
+
execFileSync("systemctl", ["--user", "disable", "--now", "cc-room-daemon"], { stdio: "pipe" });
|
|
45
|
+
} catch {
|
|
46
|
+
}
|
|
47
|
+
if (existsSync(unitPath)) {
|
|
48
|
+
try {
|
|
49
|
+
unlinkSync(unitPath);
|
|
50
|
+
console.log(` systemd \u3092\u89E3\u9664: ${unitPath}`);
|
|
51
|
+
} catch (err) {
|
|
52
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
53
|
+
console.log(` \x1B[33m\u26A0 unit \u524A\u9664\u306B\u5931\u6557: ${msg}\x1B[0m`);
|
|
54
|
+
}
|
|
55
|
+
} else {
|
|
56
|
+
console.log(" systemd: \u672A\u767B\u9332");
|
|
57
|
+
}
|
|
58
|
+
try {
|
|
59
|
+
execFileSync("systemctl", ["--user", "daemon-reload"], { stdio: "pipe" });
|
|
60
|
+
} catch {
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function removeCommandFiles(commandsDir) {
|
|
64
|
+
mkdirSync(commandsDir, { recursive: true });
|
|
65
|
+
let removed = 0;
|
|
66
|
+
for (const name of COMMAND_FILES) {
|
|
67
|
+
const path = join(commandsDir, name);
|
|
68
|
+
if (existsSync(path)) {
|
|
69
|
+
unlinkSync(path);
|
|
70
|
+
removed++;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
console.log(` \u30B3\u30DE\u30F3\u30C9\u30D5\u30A1\u30A4\u30EB\u3092 ${removed} \u4EF6\u524A\u9664 (${commandsDir})`);
|
|
74
|
+
}
|
|
75
|
+
function removeCcRoomData(ccRoomDir) {
|
|
76
|
+
if (!existsSync(ccRoomDir)) {
|
|
77
|
+
console.log(` \u30B9\u30AD\u30C3\u30D7: ${ccRoomDir} \u306F\u5B58\u5728\u3057\u307E\u305B\u3093`);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
rmSync(ccRoomDir, { recursive: true, force: true });
|
|
81
|
+
console.log(` \u524A\u9664: ${ccRoomDir}`);
|
|
82
|
+
}
|
|
83
|
+
function stopOrphanDaemon() {
|
|
84
|
+
spawnSync("pkill", ["-f", "cc-room-daemon"], { stdio: "pipe" });
|
|
85
|
+
}
|
|
86
|
+
async function uninstall() {
|
|
87
|
+
const ccRoomDir = resolveCcRoomDir();
|
|
88
|
+
const commandsDir = join(homedir(), ".claude", "commands");
|
|
89
|
+
const os = platform();
|
|
90
|
+
console.log(" [1/4] OS \u30B5\u30FC\u30D3\u30B9\u3092\u505C\u6B62...");
|
|
91
|
+
if (os === "darwin") {
|
|
92
|
+
stopLaunchd(getLaunchdPlistPath());
|
|
93
|
+
} else if (os === "linux") {
|
|
94
|
+
stopSystemd(getSystemdUnitPath());
|
|
95
|
+
} else {
|
|
96
|
+
console.log(` ${os}: \u81EA\u52D5\u8D77\u52D5\u306E\u89E3\u9664\u306F\u624B\u52D5\u3067\u884C\u3063\u3066\u304F\u3060\u3055\u3044`);
|
|
97
|
+
}
|
|
98
|
+
stopOrphanDaemon();
|
|
99
|
+
console.log(" [2/4] Slash commands \u3092\u524A\u9664...");
|
|
100
|
+
removeCommandFiles(commandsDir);
|
|
101
|
+
console.log(" [3/4] .claude/settings.json \u304B\u3089 cc-room \u3092\u9664\u53BB...");
|
|
102
|
+
unmergeSettings();
|
|
103
|
+
console.log(" [4/4] \u30C7\u30FC\u30BF\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3092\u524A\u9664...");
|
|
104
|
+
removeCcRoomData(ccRoomDir);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export {
|
|
108
|
+
getLaunchdPlistPath,
|
|
109
|
+
getSystemdUnitPath,
|
|
110
|
+
stopLaunchd,
|
|
111
|
+
stopSystemd,
|
|
112
|
+
removeCommandFiles,
|
|
113
|
+
removeCcRoomData,
|
|
114
|
+
stopOrphanDaemon,
|
|
115
|
+
uninstall
|
|
116
|
+
};
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// src/settings-merger.ts
|
|
2
|
+
import { readFileSync, writeFileSync, existsSync, copyFileSync, mkdirSync } from "fs";
|
|
3
|
+
import { join } from "path";
|
|
4
|
+
import { homedir } from "os";
|
|
5
|
+
var SETTINGS_PATH = join(homedir(), ".claude", "settings.json");
|
|
6
|
+
var CC_ROOM_HOOKS = {
|
|
7
|
+
UserPromptSubmit: [
|
|
8
|
+
{
|
|
9
|
+
hooks: [
|
|
10
|
+
{
|
|
11
|
+
type: "command",
|
|
12
|
+
command: "cc-room-daemon hook user-prompt-submit"
|
|
13
|
+
}
|
|
14
|
+
]
|
|
15
|
+
}
|
|
16
|
+
],
|
|
17
|
+
PostToolUse: [
|
|
18
|
+
{
|
|
19
|
+
matcher: "Write|Edit",
|
|
20
|
+
hooks: [
|
|
21
|
+
{
|
|
22
|
+
type: "command",
|
|
23
|
+
command: "cc-room-daemon hook post-tool-use"
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
Stop: [
|
|
29
|
+
{
|
|
30
|
+
hooks: [
|
|
31
|
+
{
|
|
32
|
+
type: "command",
|
|
33
|
+
command: "cc-room-daemon hook session-stop"
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
]
|
|
38
|
+
};
|
|
39
|
+
var CC_ROOM_MCP = {
|
|
40
|
+
"cc-room": {
|
|
41
|
+
type: "stdio",
|
|
42
|
+
command: "cc-room-daemon",
|
|
43
|
+
args: ["mcp"]
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
function mergeSettings() {
|
|
47
|
+
let settings = {};
|
|
48
|
+
mkdirSync(join(homedir(), ".claude"), { recursive: true });
|
|
49
|
+
if (existsSync(SETTINGS_PATH)) {
|
|
50
|
+
try {
|
|
51
|
+
settings = JSON.parse(readFileSync(SETTINGS_PATH, "utf-8"));
|
|
52
|
+
} catch {
|
|
53
|
+
console.log(" \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");
|
|
54
|
+
copyFileSync(SETTINGS_PATH, SETTINGS_PATH + ".backup");
|
|
55
|
+
settings = {};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const existingHooks = settings.hooks ?? {};
|
|
59
|
+
const mergedHooks = { ...existingHooks };
|
|
60
|
+
for (const [event, newEntries] of Object.entries(CC_ROOM_HOOKS)) {
|
|
61
|
+
const existing = mergedHooks[event] ?? [];
|
|
62
|
+
const filtered = existing.filter((e) => {
|
|
63
|
+
const entry = e;
|
|
64
|
+
return !entry.hooks?.some((h) => h.command?.startsWith("cc-room-daemon hook"));
|
|
65
|
+
});
|
|
66
|
+
mergedHooks[event] = [...filtered, ...newEntries];
|
|
67
|
+
}
|
|
68
|
+
const existingMcp = settings.mcpServers ?? {};
|
|
69
|
+
const mergedMcp = { ...existingMcp, ...CC_ROOM_MCP };
|
|
70
|
+
settings.hooks = mergedHooks;
|
|
71
|
+
settings.mcpServers = mergedMcp;
|
|
72
|
+
writeFileSync(SETTINGS_PATH, JSON.stringify(settings, null, 2) + "\n", { mode: 420 });
|
|
73
|
+
console.log(` ${SETTINGS_PATH} \u3092\u66F4\u65B0\u3057\u307E\u3057\u305F`);
|
|
74
|
+
}
|
|
75
|
+
function stripCcRoomFromSettings(settings) {
|
|
76
|
+
const next = { ...settings };
|
|
77
|
+
const existingHooks = settings.hooks ?? {};
|
|
78
|
+
const strippedHooks = {};
|
|
79
|
+
for (const [event, entries] of Object.entries(existingHooks)) {
|
|
80
|
+
strippedHooks[event] = (entries ?? []).filter((e) => {
|
|
81
|
+
const entry = e;
|
|
82
|
+
return !entry.hooks?.some((h) => h.command?.startsWith("cc-room-daemon hook"));
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
if (Object.keys(existingHooks).length > 0 || Object.keys(strippedHooks).length > 0) {
|
|
86
|
+
next.hooks = strippedHooks;
|
|
87
|
+
}
|
|
88
|
+
const existingMcp = settings.mcpServers ?? {};
|
|
89
|
+
if (Object.keys(existingMcp).length > 0) {
|
|
90
|
+
const { ["cc-room"]: _removed, ...rest } = existingMcp;
|
|
91
|
+
next.mcpServers = rest;
|
|
92
|
+
}
|
|
93
|
+
return next;
|
|
94
|
+
}
|
|
95
|
+
function unmergeSettings() {
|
|
96
|
+
if (!existsSync(SETTINGS_PATH)) {
|
|
97
|
+
console.log(` \u30B9\u30AD\u30C3\u30D7: ${SETTINGS_PATH} \u306F\u5B58\u5728\u3057\u307E\u305B\u3093`);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
let settings;
|
|
101
|
+
try {
|
|
102
|
+
settings = JSON.parse(readFileSync(SETTINGS_PATH, "utf-8"));
|
|
103
|
+
} catch {
|
|
104
|
+
console.log(" \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");
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const next = stripCcRoomFromSettings(settings);
|
|
108
|
+
writeFileSync(SETTINGS_PATH, JSON.stringify(next, null, 2) + "\n", { mode: 420 });
|
|
109
|
+
console.log(` ${SETTINGS_PATH} \u304B\u3089 cc-room \u3092\u9664\u53BB\u3057\u307E\u3057\u305F`);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export {
|
|
113
|
+
mergeSettings,
|
|
114
|
+
stripCcRoomFromSettings,
|
|
115
|
+
unmergeSettings
|
|
116
|
+
};
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import {
|
|
2
|
+
resolveCcRoomDir
|
|
3
|
+
} from "./chunk-WCEABGOA.js";
|
|
4
|
+
import {
|
|
5
|
+
unmergeSettings
|
|
6
|
+
} from "./chunk-ETJNYBPF.js";
|
|
7
|
+
|
|
8
|
+
// src/uninstaller.ts
|
|
9
|
+
import {
|
|
10
|
+
existsSync,
|
|
11
|
+
mkdirSync,
|
|
12
|
+
rmSync,
|
|
13
|
+
unlinkSync,
|
|
14
|
+
writeFileSync,
|
|
15
|
+
readFileSync
|
|
16
|
+
} from "fs";
|
|
17
|
+
import { join } from "path";
|
|
18
|
+
import { homedir, platform } from "os";
|
|
19
|
+
import { execFileSync, spawnSync } from "child_process";
|
|
20
|
+
var COMMAND_FILES = ["room.md", "private.md", "show.md"];
|
|
21
|
+
function getLaunchdPlistPath(home = homedir()) {
|
|
22
|
+
return join(home, "Library", "LaunchAgents", "dev.ccroom.daemon.plist");
|
|
23
|
+
}
|
|
24
|
+
function getSystemdUnitPath(home = homedir()) {
|
|
25
|
+
return join(home, ".config", "systemd", "user", "cc-room-daemon.service");
|
|
26
|
+
}
|
|
27
|
+
function stopLaunchd(plistPath) {
|
|
28
|
+
if (!existsSync(plistPath)) {
|
|
29
|
+
console.log(" launchd: \u672A\u767B\u9332");
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
execFileSync("launchctl", ["unload", plistPath], { stdio: "pipe" });
|
|
34
|
+
} catch {
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
unlinkSync(plistPath);
|
|
38
|
+
console.log(` launchd \u3092\u89E3\u9664: ${plistPath}`);
|
|
39
|
+
} catch (err) {
|
|
40
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
41
|
+
console.log(` \x1B[33m\u26A0 plist \u524A\u9664\u306B\u5931\u6557: ${msg}\x1B[0m`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function stopSystemd(unitPath) {
|
|
45
|
+
try {
|
|
46
|
+
execFileSync("systemctl", ["--user", "disable", "--now", "cc-room-daemon"], { stdio: "pipe" });
|
|
47
|
+
} catch {
|
|
48
|
+
}
|
|
49
|
+
if (existsSync(unitPath)) {
|
|
50
|
+
try {
|
|
51
|
+
unlinkSync(unitPath);
|
|
52
|
+
console.log(` systemd \u3092\u89E3\u9664: ${unitPath}`);
|
|
53
|
+
} catch (err) {
|
|
54
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
55
|
+
console.log(` \x1B[33m\u26A0 unit \u524A\u9664\u306B\u5931\u6557: ${msg}\x1B[0m`);
|
|
56
|
+
}
|
|
57
|
+
} else {
|
|
58
|
+
console.log(" systemd: \u672A\u767B\u9332");
|
|
59
|
+
}
|
|
60
|
+
try {
|
|
61
|
+
execFileSync("systemctl", ["--user", "daemon-reload"], { stdio: "pipe" });
|
|
62
|
+
} catch {
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function removeCommandFiles(commandsDir) {
|
|
66
|
+
mkdirSync(commandsDir, { recursive: true });
|
|
67
|
+
let removed = 0;
|
|
68
|
+
for (const name of COMMAND_FILES) {
|
|
69
|
+
const path = join(commandsDir, name);
|
|
70
|
+
if (existsSync(path)) {
|
|
71
|
+
unlinkSync(path);
|
|
72
|
+
removed++;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
console.log(` \u30B3\u30DE\u30F3\u30C9\u30D5\u30A1\u30A4\u30EB\u3092 ${removed} \u4EF6\u524A\u9664 (${commandsDir})`);
|
|
76
|
+
}
|
|
77
|
+
function removeCcRoomData(ccRoomDir) {
|
|
78
|
+
if (!existsSync(ccRoomDir)) {
|
|
79
|
+
console.log(` \u30B9\u30AD\u30C3\u30D7: ${ccRoomDir} \u306F\u5B58\u5728\u3057\u307E\u305B\u3093`);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
rmSync(ccRoomDir, { recursive: true, force: true });
|
|
83
|
+
console.log(` \u524A\u9664: ${ccRoomDir}`);
|
|
84
|
+
}
|
|
85
|
+
function stopOrphanDaemon() {
|
|
86
|
+
spawnSync("pkill", ["-f", "cc-room-daemon"], { stdio: "pipe" });
|
|
87
|
+
}
|
|
88
|
+
async function uninstall() {
|
|
89
|
+
const ccRoomDir = resolveCcRoomDir();
|
|
90
|
+
const commandsDir = join(homedir(), ".claude", "commands");
|
|
91
|
+
const os = platform();
|
|
92
|
+
console.log(" [1/4] OS \u30B5\u30FC\u30D3\u30B9\u3092\u505C\u6B62...");
|
|
93
|
+
if (os === "darwin") {
|
|
94
|
+
stopLaunchd(getLaunchdPlistPath());
|
|
95
|
+
} else if (os === "linux") {
|
|
96
|
+
stopSystemd(getSystemdUnitPath());
|
|
97
|
+
} else {
|
|
98
|
+
console.log(` ${os}: \u81EA\u52D5\u8D77\u52D5\u306E\u89E3\u9664\u306F\u624B\u52D5\u3067\u884C\u3063\u3066\u304F\u3060\u3055\u3044`);
|
|
99
|
+
}
|
|
100
|
+
stopOrphanDaemon();
|
|
101
|
+
console.log(" [2/4] Slash commands \u3092\u524A\u9664...");
|
|
102
|
+
removeCommandFiles(commandsDir);
|
|
103
|
+
console.log(" [3/4] .claude/settings.json \u304B\u3089 cc-room \u3092\u9664\u53BB...");
|
|
104
|
+
unmergeSettings();
|
|
105
|
+
console.log(" [4/4] ~/.cc-room \u3092\u524A\u9664...");
|
|
106
|
+
removeCcRoomData(ccRoomDir);
|
|
107
|
+
}
|
|
108
|
+
function seedUninstallFixture(root) {
|
|
109
|
+
const plist = getLaunchdPlistPath(root.home);
|
|
110
|
+
mkdirSync(join(plist, ".."), { recursive: true });
|
|
111
|
+
writeFileSync(plist, "plist");
|
|
112
|
+
mkdirSync(join(root.ccRoomDir, "bin"), { recursive: true });
|
|
113
|
+
writeFileSync(join(root.ccRoomDir, "bin", "cc-room-daemon"), "daemon");
|
|
114
|
+
const commandsDir = join(root.home, ".claude", "commands");
|
|
115
|
+
mkdirSync(commandsDir, { recursive: true });
|
|
116
|
+
for (const name of COMMAND_FILES) {
|
|
117
|
+
writeFileSync(join(commandsDir, name), `# ${name}`);
|
|
118
|
+
}
|
|
119
|
+
const settingsPath = join(root.home, ".claude", "settings.json");
|
|
120
|
+
writeFileSync(
|
|
121
|
+
settingsPath,
|
|
122
|
+
JSON.stringify({
|
|
123
|
+
hooks: {
|
|
124
|
+
Stop: [{ hooks: [{ type: "command", command: "cc-room-daemon hook session-stop" }] }]
|
|
125
|
+
},
|
|
126
|
+
mcpServers: { "cc-room": { command: "cc-room-daemon" }, keep: {} }
|
|
127
|
+
})
|
|
128
|
+
);
|
|
129
|
+
readFileSync(settingsPath, "utf-8");
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export {
|
|
133
|
+
getLaunchdPlistPath,
|
|
134
|
+
getSystemdUnitPath,
|
|
135
|
+
stopLaunchd,
|
|
136
|
+
stopSystemd,
|
|
137
|
+
removeCommandFiles,
|
|
138
|
+
removeCcRoomData,
|
|
139
|
+
stopOrphanDaemon,
|
|
140
|
+
uninstall,
|
|
141
|
+
seedUninstallFixture
|
|
142
|
+
};
|
package/dist/index.js
CHANGED
|
@@ -1,19 +1,35 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
install
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-6SYATEI6.js";
|
|
5
5
|
import "./chunk-R5BAC4BK.js";
|
|
6
6
|
import "./chunk-UWFC4FU6.js";
|
|
7
|
+
import {
|
|
8
|
+
uninstall
|
|
9
|
+
} from "./chunk-AVDOC76K.js";
|
|
7
10
|
import "./chunk-WCEABGOA.js";
|
|
8
|
-
import "./chunk-
|
|
11
|
+
import "./chunk-ETJNYBPF.js";
|
|
9
12
|
import {
|
|
10
13
|
printResults,
|
|
11
14
|
validateAll
|
|
12
15
|
} from "./chunk-NJES6PZ3.js";
|
|
13
16
|
|
|
14
17
|
// src/index.ts
|
|
15
|
-
|
|
16
|
-
|
|
18
|
+
var VERSION = "0.2.1";
|
|
19
|
+
function printHelp() {
|
|
20
|
+
console.log(`
|
|
21
|
+
\u{1F3E0} setup-cc-room v${VERSION}
|
|
22
|
+
|
|
23
|
+
Usage:
|
|
24
|
+
npx setup-cc-room Install cc-room
|
|
25
|
+
npx setup-cc-room uninstall Remove cc-room (daemon, hooks, data)
|
|
26
|
+
npx setup-cc-room --help Show this help
|
|
27
|
+
`);
|
|
28
|
+
}
|
|
29
|
+
async function runInstall() {
|
|
30
|
+
console.log(`
|
|
31
|
+
\u{1F3E0} setup-cc-room v${VERSION}
|
|
32
|
+
`);
|
|
17
33
|
console.log(" Preflight checks \u3092\u5B9F\u884C\u4E2D...");
|
|
18
34
|
const { passed, results } = validateAll();
|
|
19
35
|
printResults(results);
|
|
@@ -48,9 +64,39 @@ async function main() {
|
|
|
48
64
|
\u63A5\u7D9A\u5F8C\u306F\u540C\u3058 WiFi\uFF08LAN\uFF09\u5185\u306B\u3044\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002
|
|
49
65
|
\uFF08VPN \u3067\u540C\u4E00 LAN \u76F8\u5F53\u306B\u306A\u308C\u3070\u30EA\u30E2\u30FC\u30C8\u3067\u3082\u4F7F\u3048\u307E\u3059\uFF09
|
|
50
66
|
|
|
67
|
+
\u30A2\u30F3\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB: npx setup-cc-room uninstall
|
|
68
|
+
|
|
51
69
|
\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8: https://github.com/takanorisuzuki/cc-room
|
|
52
70
|
`);
|
|
53
71
|
}
|
|
72
|
+
async function runUninstall() {
|
|
73
|
+
console.log(`
|
|
74
|
+
\u{1F3E0} setup-cc-room v${VERSION} \u2014 uninstall
|
|
75
|
+
`);
|
|
76
|
+
await uninstall();
|
|
77
|
+
console.log(`
|
|
78
|
+
\x1B[32m\u2705 \u30A2\u30F3\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u304C\u5B8C\u4E86\u3057\u307E\u3057\u305F\u3002\x1B[0m
|
|
79
|
+
|
|
80
|
+
Claude Code \u3092\u518D\u8D77\u52D5\u3057\u3066\u304F\u3060\u3055\u3044\uFF08hooks / MCP \u306E\u53CD\u6620\uFF09\u3002
|
|
81
|
+
`);
|
|
82
|
+
}
|
|
83
|
+
async function main() {
|
|
84
|
+
const arg = process.argv[2];
|
|
85
|
+
if (arg === "--help" || arg === "-h" || arg === "help") {
|
|
86
|
+
printHelp();
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (arg === "uninstall" || arg === "--uninstall") {
|
|
90
|
+
await runUninstall();
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
if (arg && arg !== "install") {
|
|
94
|
+
console.error(` \u4E0D\u660E\u306A\u5F15\u6570: ${arg}`);
|
|
95
|
+
printHelp();
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
98
|
+
await runInstall();
|
|
99
|
+
}
|
|
54
100
|
main().catch((err) => {
|
|
55
101
|
console.error(" \x1B[31m\u30A8\u30E9\u30FC:\x1B[0m", err instanceof Error ? err.message : err);
|
|
56
102
|
process.exit(1);
|
package/dist/installer.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
install
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-6SYATEI6.js";
|
|
4
4
|
import "./chunk-R5BAC4BK.js";
|
|
5
5
|
import "./chunk-UWFC4FU6.js";
|
|
6
6
|
import "./chunk-WCEABGOA.js";
|
|
7
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-ETJNYBPF.js";
|
|
8
8
|
export {
|
|
9
9
|
install
|
|
10
10
|
};
|
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
declare function mergeSettings(): void;
|
|
2
|
+
/** settings.json から cc-room の hooks / mcpServers を除去(他設定は保持) */
|
|
3
|
+
declare function stripCcRoomFromSettings(settings: Record<string, unknown>): Record<string, unknown>;
|
|
4
|
+
declare function unmergeSettings(): void;
|
|
2
5
|
|
|
3
|
-
export { mergeSettings };
|
|
6
|
+
export { mergeSettings, stripCcRoomFromSettings, unmergeSettings };
|
package/dist/settings-merger.js
CHANGED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
declare function getLaunchdPlistPath(home?: string): string;
|
|
2
|
+
declare function getSystemdUnitPath(home?: string): string;
|
|
3
|
+
declare function stopLaunchd(plistPath: string): void;
|
|
4
|
+
declare function stopSystemd(unitPath: string): void;
|
|
5
|
+
declare function removeCommandFiles(commandsDir: string): void;
|
|
6
|
+
declare function removeCcRoomData(ccRoomDir: string): void;
|
|
7
|
+
declare function stopOrphanDaemon(): void;
|
|
8
|
+
declare function uninstall(): Promise<void>;
|
|
9
|
+
|
|
10
|
+
export { getLaunchdPlistPath, getSystemdUnitPath, removeCcRoomData, removeCommandFiles, stopLaunchd, stopOrphanDaemon, stopSystemd, uninstall };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getLaunchdPlistPath,
|
|
3
|
+
getSystemdUnitPath,
|
|
4
|
+
removeCcRoomData,
|
|
5
|
+
removeCommandFiles,
|
|
6
|
+
stopLaunchd,
|
|
7
|
+
stopOrphanDaemon,
|
|
8
|
+
stopSystemd,
|
|
9
|
+
uninstall
|
|
10
|
+
} from "./chunk-AVDOC76K.js";
|
|
11
|
+
import "./chunk-WCEABGOA.js";
|
|
12
|
+
import "./chunk-ETJNYBPF.js";
|
|
13
|
+
export {
|
|
14
|
+
getLaunchdPlistPath,
|
|
15
|
+
getSystemdUnitPath,
|
|
16
|
+
removeCcRoomData,
|
|
17
|
+
removeCommandFiles,
|
|
18
|
+
stopLaunchd,
|
|
19
|
+
stopOrphanDaemon,
|
|
20
|
+
stopSystemd,
|
|
21
|
+
uninstall
|
|
22
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "setup-cc-room",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
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",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"vendor"
|
|
19
19
|
],
|
|
20
20
|
"scripts": {
|
|
21
|
-
"build": "tsup src/index.ts src/installer.ts src/settings-merger.ts src/register-service.ts src/validators.ts src/daemon-resolver.ts src/paths.ts --format esm --dts",
|
|
21
|
+
"build": "tsup src/index.ts src/installer.ts src/settings-merger.ts src/register-service.ts src/validators.ts src/daemon-resolver.ts src/paths.ts src/uninstaller.ts --format esm --dts",
|
|
22
22
|
"dev": "tsup src/index.ts --format esm --watch",
|
|
23
23
|
"pack:vendor": "node scripts/pack-vendor.mjs",
|
|
24
24
|
"prepack": "pnpm run build && pnpm run pack:vendor",
|