setup-cc-room 0.2.0 → 0.2.2
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-KEFBOTQD.js +22 -0
- package/dist/chunk-LMBNCW4L.js +142 -0
- package/dist/chunk-MSQUTURC.js +119 -0
- package/dist/chunk-MVD6RIS2.js +120 -0
- package/dist/chunk-OYW7MM4W.js +278 -0
- package/dist/chunk-RYVZHEHF.js +169 -0
- package/dist/chunk-SMSDMP5O.js +125 -0
- package/dist/chunk-ZDOKJ4KX.js +132 -0
- package/dist/daemon-resolver.d.ts +1 -1
- package/dist/daemon-resolver.js +1 -1
- package/dist/i18n.d.ts +7 -0
- package/dist/i18n.js +12 -0
- package/dist/index.js +73 -38
- package/dist/installer.d.ts +5 -2
- package/dist/installer.js +9 -6
- package/dist/register-service.js +2 -1
- package/dist/settings-merger.d.ts +4 -1
- package/dist/settings-merger.js +8 -3
- package/dist/uninstaller.d.ts +10 -0
- package/dist/uninstaller.js +23 -0
- package/dist/validators.js +2 -1
- package/package.json +2 -2
- package/vendor/commands/room/en/private.md +75 -0
- package/vendor/commands/room/en/room.md +475 -0
- package/vendor/commands/room/en/show.md +149 -0
- /package/vendor/commands/room/{private.md → ja/private.md} +0 -0
- /package/vendor/commands/room/{room.md → ja/room.md} +0 -0
- /package/vendor/commands/room/{show.md → ja/show.md} +0 -0
|
@@ -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,22 @@
|
|
|
1
|
+
// src/daemon-resolver.ts
|
|
2
|
+
import { existsSync } from "fs";
|
|
3
|
+
import { join } from "path";
|
|
4
|
+
function resolveDaemonSource(setupPackageRoot) {
|
|
5
|
+
const candidates = [
|
|
6
|
+
join(setupPackageRoot, "vendor", "daemon", "dist", "index.js"),
|
|
7
|
+
join(setupPackageRoot, "..", "daemon", "dist-bundle", "index.js"),
|
|
8
|
+
// モノレポ開発時のフォールバック(チャンク分割あり・単体コピーでは動かないことがある)
|
|
9
|
+
join(setupPackageRoot, "..", "daemon", "dist", "index.js"),
|
|
10
|
+
join(setupPackageRoot, "..", "..", "node_modules", "@cc-room", "daemon", "dist", "index.js")
|
|
11
|
+
];
|
|
12
|
+
for (const c of candidates) {
|
|
13
|
+
if (existsSync(c)) return c;
|
|
14
|
+
}
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
var 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.";
|
|
18
|
+
|
|
19
|
+
export {
|
|
20
|
+
resolveDaemonSource,
|
|
21
|
+
DAEMON_MISSING_HINT
|
|
22
|
+
};
|
|
@@ -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
|
+
};
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import {
|
|
2
|
+
resolveCcRoomDir
|
|
3
|
+
} from "./chunk-WCEABGOA.js";
|
|
4
|
+
import {
|
|
5
|
+
unmergeSettings
|
|
6
|
+
} from "./chunk-MVD6RIS2.js";
|
|
7
|
+
import {
|
|
8
|
+
t
|
|
9
|
+
} from "./chunk-OYW7MM4W.js";
|
|
10
|
+
|
|
11
|
+
// src/uninstaller.ts
|
|
12
|
+
import {
|
|
13
|
+
existsSync,
|
|
14
|
+
mkdirSync,
|
|
15
|
+
rmSync,
|
|
16
|
+
unlinkSync
|
|
17
|
+
} from "fs";
|
|
18
|
+
import { join } from "path";
|
|
19
|
+
import { homedir, platform } from "os";
|
|
20
|
+
import { execFileSync, spawnSync } from "child_process";
|
|
21
|
+
var COMMAND_FILES = ["room.md", "private.md", "show.md"];
|
|
22
|
+
function getLaunchdPlistPath(home = homedir()) {
|
|
23
|
+
return join(home, "Library", "LaunchAgents", "dev.ccroom.daemon.plist");
|
|
24
|
+
}
|
|
25
|
+
function getSystemdUnitPath(home = homedir()) {
|
|
26
|
+
return join(home, ".config", "systemd", "user", "cc-room-daemon.service");
|
|
27
|
+
}
|
|
28
|
+
function stopLaunchd(plistPath) {
|
|
29
|
+
if (!existsSync(plistPath)) {
|
|
30
|
+
console.log(t("un.launchd_none"));
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
execFileSync("launchctl", ["unload", plistPath], { stdio: "pipe" });
|
|
35
|
+
} catch {
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
unlinkSync(plistPath);
|
|
39
|
+
console.log(t("un.launchd_ok", { path: plistPath }));
|
|
40
|
+
} catch (err) {
|
|
41
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
42
|
+
console.log(t("un.plist_fail", { msg }));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function stopSystemd(unitPath) {
|
|
46
|
+
try {
|
|
47
|
+
execFileSync("systemctl", ["--user", "disable", "--now", "cc-room-daemon"], { stdio: "pipe" });
|
|
48
|
+
} catch {
|
|
49
|
+
}
|
|
50
|
+
if (existsSync(unitPath)) {
|
|
51
|
+
try {
|
|
52
|
+
unlinkSync(unitPath);
|
|
53
|
+
console.log(t("un.systemd_ok", { path: unitPath }));
|
|
54
|
+
} catch (err) {
|
|
55
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
56
|
+
console.log(t("un.unit_fail", { msg }));
|
|
57
|
+
}
|
|
58
|
+
} else {
|
|
59
|
+
console.log(t("un.systemd_none"));
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
execFileSync("systemctl", ["--user", "daemon-reload"], { stdio: "pipe" });
|
|
63
|
+
} catch {
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function removeCommandFiles(commandsDir) {
|
|
67
|
+
mkdirSync(commandsDir, { recursive: true });
|
|
68
|
+
let removed = 0;
|
|
69
|
+
for (const name of COMMAND_FILES) {
|
|
70
|
+
const path = join(commandsDir, name);
|
|
71
|
+
if (existsSync(path)) {
|
|
72
|
+
unlinkSync(path);
|
|
73
|
+
removed++;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
console.log(t("un.commands_ok", { count: removed, dir: commandsDir }));
|
|
77
|
+
}
|
|
78
|
+
function removeCcRoomData(ccRoomDir) {
|
|
79
|
+
if (!existsSync(ccRoomDir)) {
|
|
80
|
+
console.log(t("un.data_skip", { dir: ccRoomDir }));
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
rmSync(ccRoomDir, { recursive: true, force: true });
|
|
84
|
+
console.log(t("un.data_ok", { dir: ccRoomDir }));
|
|
85
|
+
}
|
|
86
|
+
function stopOrphanDaemon() {
|
|
87
|
+
spawnSync("pkill", ["-f", "cc-room-daemon"], { stdio: "pipe" });
|
|
88
|
+
}
|
|
89
|
+
async function uninstall() {
|
|
90
|
+
const ccRoomDir = resolveCcRoomDir();
|
|
91
|
+
const commandsDir = join(homedir(), ".claude", "commands");
|
|
92
|
+
const os = platform();
|
|
93
|
+
console.log(t("un.step1"));
|
|
94
|
+
if (os === "darwin") {
|
|
95
|
+
stopLaunchd(getLaunchdPlistPath());
|
|
96
|
+
} else if (os === "linux") {
|
|
97
|
+
stopSystemd(getSystemdUnitPath());
|
|
98
|
+
} else {
|
|
99
|
+
console.log(t("un.os_manual", { os }));
|
|
100
|
+
}
|
|
101
|
+
stopOrphanDaemon();
|
|
102
|
+
console.log(t("un.step2"));
|
|
103
|
+
removeCommandFiles(commandsDir);
|
|
104
|
+
console.log(t("un.step3"));
|
|
105
|
+
unmergeSettings();
|
|
106
|
+
console.log(t("un.step4"));
|
|
107
|
+
removeCcRoomData(ccRoomDir);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export {
|
|
111
|
+
getLaunchdPlistPath,
|
|
112
|
+
getSystemdUnitPath,
|
|
113
|
+
stopLaunchd,
|
|
114
|
+
stopSystemd,
|
|
115
|
+
removeCommandFiles,
|
|
116
|
+
removeCcRoomData,
|
|
117
|
+
stopOrphanDaemon,
|
|
118
|
+
uninstall
|
|
119
|
+
};
|