workspacecord 1.0.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/LICENSE +21 -0
- package/README.md +190 -0
- package/README.zh-CN.md +190 -0
- package/dist/bot-B5HN4ZW6.js +6710 -0
- package/dist/chunk-2LBNM64L.js +84 -0
- package/dist/chunk-K3NQKI34.js +10 -0
- package/dist/chunk-NIXZJTOZ.js +175 -0
- package/dist/chunk-OKI4UVGY.js +221 -0
- package/dist/chunk-TSBM3BNT.js +1224 -0
- package/dist/chunk-WE4X3JB3.js +130 -0
- package/dist/cli.js +71 -0
- package/dist/codex-launcher-IF2IPLBP.js +132 -0
- package/dist/codex-provider-7CI5W34X.js +304 -0
- package/dist/config-cli-F2B5SYHJ.js +120 -0
- package/dist/daemon-NW4WRMQK.js +252 -0
- package/dist/project-cli-FEMPZIRQ.js +121 -0
- package/dist/project-registry-DQT5ORUU.js +32 -0
- package/dist/setup-TKOVXSME.js +262 -0
- package/dist/thread-manager-5T46QTZF.js +78 -0
- package/dist/utils-72GMT2X5.js +36 -0
- package/package.json +79 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
SENSITIVE_KEYS,
|
|
4
|
+
VALID_KEYS,
|
|
5
|
+
deleteConfigValue,
|
|
6
|
+
getAllConfig,
|
|
7
|
+
getConfigPath,
|
|
8
|
+
getConfigValue,
|
|
9
|
+
maskSensitive,
|
|
10
|
+
setConfigValue,
|
|
11
|
+
validateConfigValue
|
|
12
|
+
} from "./chunk-OKI4UVGY.js";
|
|
13
|
+
import "./chunk-K3NQKI34.js";
|
|
14
|
+
|
|
15
|
+
// src/config-cli.ts
|
|
16
|
+
function printHelp() {
|
|
17
|
+
console.log(`
|
|
18
|
+
\x1B[1mworkspacecord config\x1B[0m \u2014 manage global configuration
|
|
19
|
+
|
|
20
|
+
\x1B[1mUsage:\x1B[0m
|
|
21
|
+
workspacecord config setup Interactive configuration wizard
|
|
22
|
+
workspacecord config get <key> Read a configuration value
|
|
23
|
+
workspacecord config set <key> <val> Write a configuration value
|
|
24
|
+
workspacecord config unset <key> Remove a configuration value
|
|
25
|
+
workspacecord config list List all configuration values
|
|
26
|
+
workspacecord config path Show the config file path
|
|
27
|
+
|
|
28
|
+
\x1B[1mValid keys:\x1B[0m
|
|
29
|
+
${Array.from(VALID_KEYS).join(", ")}
|
|
30
|
+
`);
|
|
31
|
+
}
|
|
32
|
+
async function handleConfig(args) {
|
|
33
|
+
const [subcommand, ...rest] = args;
|
|
34
|
+
switch (subcommand) {
|
|
35
|
+
case "setup": {
|
|
36
|
+
const { runSetup } = await import("./setup-TKOVXSME.js");
|
|
37
|
+
await runSetup();
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
case "get": {
|
|
41
|
+
const key = rest[0];
|
|
42
|
+
if (!key) {
|
|
43
|
+
console.error("Usage: workspacecord config get <key>");
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
if (!VALID_KEYS.has(key)) {
|
|
47
|
+
console.error(`Unknown config key: ${key}`);
|
|
48
|
+
console.error(`Valid keys: ${Array.from(VALID_KEYS).join(", ")}`);
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
const value = getConfigValue(key);
|
|
52
|
+
if (value === void 0) {
|
|
53
|
+
console.log(`(not set)`);
|
|
54
|
+
} else {
|
|
55
|
+
console.log(maskSensitive(key, value));
|
|
56
|
+
}
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
case "set": {
|
|
60
|
+
const [key, value] = rest;
|
|
61
|
+
if (!key || value === void 0) {
|
|
62
|
+
console.error("Usage: workspacecord config set <key> <value>");
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|
|
65
|
+
const err = validateConfigValue(key, value);
|
|
66
|
+
if (err) {
|
|
67
|
+
console.error(err);
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
setConfigValue(key, value);
|
|
71
|
+
const display = SENSITIVE_KEYS.has(key) ? maskSensitive(key, value) : value;
|
|
72
|
+
console.log(`\x1B[32m\u2713\x1B[0m ${key} = ${display}`);
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
case "unset": {
|
|
76
|
+
const key = rest[0];
|
|
77
|
+
if (!key) {
|
|
78
|
+
console.error("Usage: workspacecord config unset <key>");
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
if (!VALID_KEYS.has(key)) {
|
|
82
|
+
console.error(`Unknown config key: ${key}`);
|
|
83
|
+
process.exit(1);
|
|
84
|
+
}
|
|
85
|
+
deleteConfigValue(key);
|
|
86
|
+
console.log(`\x1B[32m\u2713\x1B[0m ${key} removed`);
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
case "list": {
|
|
90
|
+
const all = getAllConfig();
|
|
91
|
+
const keys = Object.keys(all);
|
|
92
|
+
if (keys.length === 0) {
|
|
93
|
+
console.log("(no configuration set \u2014 run \x1B[36mworkspacecord config setup\x1B[0m)");
|
|
94
|
+
} else {
|
|
95
|
+
for (const key of keys) {
|
|
96
|
+
const value = all[key];
|
|
97
|
+
console.log(`${key}=${maskSensitive(key, value)}`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
case "path": {
|
|
103
|
+
console.log(getConfigPath());
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
case void 0:
|
|
107
|
+
case "help":
|
|
108
|
+
case "--help":
|
|
109
|
+
case "-h":
|
|
110
|
+
printHelp();
|
|
111
|
+
break;
|
|
112
|
+
default:
|
|
113
|
+
console.error(`Unknown config subcommand: ${subcommand}`);
|
|
114
|
+
printHelp();
|
|
115
|
+
process.exit(1);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
export {
|
|
119
|
+
handleConfig
|
|
120
|
+
};
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import "./chunk-K3NQKI34.js";
|
|
3
|
+
|
|
4
|
+
// src/daemon.ts
|
|
5
|
+
import * as p from "@clack/prompts";
|
|
6
|
+
import { existsSync, writeFileSync, unlinkSync, readFileSync } from "fs";
|
|
7
|
+
import { resolve, join } from "path";
|
|
8
|
+
import { execSync } from "child_process";
|
|
9
|
+
import { homedir, platform } from "os";
|
|
10
|
+
var LABEL = "com.workspacecord";
|
|
11
|
+
var SERVICE_NAME = "workspacecord";
|
|
12
|
+
function getMacPlistPath() {
|
|
13
|
+
return join(homedir(), "Library", "LaunchAgents", `${LABEL}.plist`);
|
|
14
|
+
}
|
|
15
|
+
function getLinuxServicePath() {
|
|
16
|
+
return join(homedir(), ".config", "systemd", "user", `${SERVICE_NAME}.service`);
|
|
17
|
+
}
|
|
18
|
+
function getNodePath() {
|
|
19
|
+
return process.execPath;
|
|
20
|
+
}
|
|
21
|
+
function getCliPath() {
|
|
22
|
+
try {
|
|
23
|
+
const result = execSync("which workspacecord", { encoding: "utf-8" }).trim();
|
|
24
|
+
if (result) {
|
|
25
|
+
try {
|
|
26
|
+
const wrapper = readFileSync(result, "utf-8");
|
|
27
|
+
const match = wrapper.match(
|
|
28
|
+
/exec\s+(?:node|"\$basedir\/node")\s+"?\$basedir\/([^"$\s]+cli\.js)"?/
|
|
29
|
+
);
|
|
30
|
+
if (match) {
|
|
31
|
+
const wrapperDir = execSync(`dirname "${result}"`, { encoding: "utf-8" }).trim();
|
|
32
|
+
const resolved = resolve(wrapperDir, match[1]);
|
|
33
|
+
if (existsSync(resolved)) return resolved;
|
|
34
|
+
}
|
|
35
|
+
} catch {
|
|
36
|
+
}
|
|
37
|
+
const realPath = execSync(
|
|
38
|
+
`readlink -f "${result}" 2>/dev/null || realpath "${result}" 2>/dev/null || echo "${result}"`,
|
|
39
|
+
{ encoding: "utf-8" }
|
|
40
|
+
).trim();
|
|
41
|
+
if (realPath.endsWith(".js") && existsSync(realPath)) return realPath;
|
|
42
|
+
}
|
|
43
|
+
} catch {
|
|
44
|
+
}
|
|
45
|
+
return resolve(import.meta.dirname, "..", "dist", "cli.js");
|
|
46
|
+
}
|
|
47
|
+
function generateMacPlist(workDir, logDir) {
|
|
48
|
+
const nodePath = getNodePath();
|
|
49
|
+
const cliPath = getCliPath();
|
|
50
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
51
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
52
|
+
<plist version="1.0">
|
|
53
|
+
<dict>
|
|
54
|
+
<key>Label</key>
|
|
55
|
+
<string>${LABEL}</string>
|
|
56
|
+
<key>ProgramArguments</key>
|
|
57
|
+
<array>
|
|
58
|
+
<string>${nodePath}</string>
|
|
59
|
+
<string>--watch</string>
|
|
60
|
+
<string>${cliPath}</string>
|
|
61
|
+
</array>
|
|
62
|
+
<key>WorkingDirectory</key>
|
|
63
|
+
<string>${workDir}</string>
|
|
64
|
+
<key>RunAtLoad</key>
|
|
65
|
+
<true/>
|
|
66
|
+
<key>KeepAlive</key>
|
|
67
|
+
<dict>
|
|
68
|
+
<key>Crashed</key>
|
|
69
|
+
<true/>
|
|
70
|
+
</dict>
|
|
71
|
+
<key>ThrottleInterval</key>
|
|
72
|
+
<integer>10</integer>
|
|
73
|
+
<key>StandardOutPath</key>
|
|
74
|
+
<string>${join(logDir, "workspacecord.log")}</string>
|
|
75
|
+
<key>StandardErrorPath</key>
|
|
76
|
+
<string>${join(logDir, "workspacecord.error.log")}</string>
|
|
77
|
+
<key>EnvironmentVariables</key>
|
|
78
|
+
<dict>
|
|
79
|
+
<key>PATH</key>
|
|
80
|
+
<string>/usr/local/bin:/usr/bin:/bin:/opt/homebrew/bin</string>
|
|
81
|
+
</dict>
|
|
82
|
+
</dict>
|
|
83
|
+
</plist>`;
|
|
84
|
+
}
|
|
85
|
+
function generateSystemdUnit(workDir) {
|
|
86
|
+
const nodePath = getNodePath();
|
|
87
|
+
const cliPath = getCliPath();
|
|
88
|
+
return `[Unit]
|
|
89
|
+
Description=workspacecord - Discord AI agent bot
|
|
90
|
+
After=network.target
|
|
91
|
+
|
|
92
|
+
[Service]
|
|
93
|
+
Type=simple
|
|
94
|
+
ExecStart=${nodePath} --watch ${cliPath}
|
|
95
|
+
WorkingDirectory=${workDir}
|
|
96
|
+
Restart=on-abnormal
|
|
97
|
+
RestartSec=10
|
|
98
|
+
Environment=PATH=/usr/local/bin:/usr/bin:/bin
|
|
99
|
+
|
|
100
|
+
[Install]
|
|
101
|
+
WantedBy=default.target
|
|
102
|
+
`;
|
|
103
|
+
}
|
|
104
|
+
async function install() {
|
|
105
|
+
const workDir = join(homedir(), ".workspacecord");
|
|
106
|
+
const isMac = platform() === "darwin";
|
|
107
|
+
if (isMac) {
|
|
108
|
+
const plistPath = getMacPlistPath();
|
|
109
|
+
const logDir = workDir;
|
|
110
|
+
if (existsSync(plistPath)) {
|
|
111
|
+
try {
|
|
112
|
+
execSync(`launchctl unload "${plistPath}" 2>/dev/null`);
|
|
113
|
+
} catch {
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
const plist = generateMacPlist(workDir, logDir);
|
|
117
|
+
writeFileSync(plistPath, plist);
|
|
118
|
+
execSync(`launchctl load "${plistPath}"`);
|
|
119
|
+
p.log.success("LaunchAgent installed and started.");
|
|
120
|
+
p.log.info(`Plist: ${plistPath}`);
|
|
121
|
+
p.log.info(`Logs: ${join(logDir, "workspacecord.log")}`);
|
|
122
|
+
p.log.info(`Errors: ${join(logDir, "workspacecord.error.log")}`);
|
|
123
|
+
} else {
|
|
124
|
+
const servicePath = getLinuxServicePath();
|
|
125
|
+
const serviceDir = resolve(servicePath, "..");
|
|
126
|
+
if (!existsSync(serviceDir)) {
|
|
127
|
+
execSync(`mkdir -p "${serviceDir}"`);
|
|
128
|
+
}
|
|
129
|
+
const unit = generateSystemdUnit(workDir);
|
|
130
|
+
writeFileSync(servicePath, unit);
|
|
131
|
+
execSync("systemctl --user daemon-reload");
|
|
132
|
+
execSync(`systemctl --user enable ${SERVICE_NAME}`);
|
|
133
|
+
execSync(`systemctl --user start ${SERVICE_NAME}`);
|
|
134
|
+
p.log.success("systemd user service installed and started.");
|
|
135
|
+
p.log.info(`Unit: ${servicePath}`);
|
|
136
|
+
p.log.info(`Logs: journalctl --user -u ${SERVICE_NAME} -f`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
async function uninstall() {
|
|
140
|
+
const isMac = platform() === "darwin";
|
|
141
|
+
if (isMac) {
|
|
142
|
+
const plistPath = getMacPlistPath();
|
|
143
|
+
if (!existsSync(plistPath)) {
|
|
144
|
+
p.log.warn("No LaunchAgent found. Nothing to uninstall.");
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
try {
|
|
148
|
+
execSync(`launchctl unload "${plistPath}"`);
|
|
149
|
+
} catch {
|
|
150
|
+
}
|
|
151
|
+
unlinkSync(plistPath);
|
|
152
|
+
p.log.success("LaunchAgent uninstalled.");
|
|
153
|
+
} else {
|
|
154
|
+
const servicePath = getLinuxServicePath();
|
|
155
|
+
if (!existsSync(servicePath)) {
|
|
156
|
+
p.log.warn("No systemd service found. Nothing to uninstall.");
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
try {
|
|
160
|
+
execSync(`systemctl --user stop ${SERVICE_NAME}`);
|
|
161
|
+
execSync(`systemctl --user disable ${SERVICE_NAME}`);
|
|
162
|
+
} catch {
|
|
163
|
+
}
|
|
164
|
+
unlinkSync(servicePath);
|
|
165
|
+
execSync("systemctl --user daemon-reload");
|
|
166
|
+
p.log.success("systemd user service uninstalled.");
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
async function status() {
|
|
170
|
+
const isMac = platform() === "darwin";
|
|
171
|
+
if (isMac) {
|
|
172
|
+
const plistPath = getMacPlistPath();
|
|
173
|
+
if (!existsSync(plistPath)) {
|
|
174
|
+
p.log.warn("No LaunchAgent installed.");
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
try {
|
|
178
|
+
const output = execSync(`launchctl list | grep ${LABEL}`, { encoding: "utf-8" }).trim();
|
|
179
|
+
if (output) {
|
|
180
|
+
const parts = output.split(" ");
|
|
181
|
+
const pid = parts[0];
|
|
182
|
+
const exitCode = parts[1];
|
|
183
|
+
if (pid && pid !== "-") {
|
|
184
|
+
p.log.success(`Running (PID ${pid})`);
|
|
185
|
+
} else {
|
|
186
|
+
p.log.warn(`Not running (last exit code: ${exitCode})`);
|
|
187
|
+
}
|
|
188
|
+
} else {
|
|
189
|
+
p.log.warn("Installed but not loaded.");
|
|
190
|
+
}
|
|
191
|
+
} catch {
|
|
192
|
+
p.log.warn("Installed but not loaded.");
|
|
193
|
+
}
|
|
194
|
+
try {
|
|
195
|
+
const plist = readFileSync(plistPath, "utf-8");
|
|
196
|
+
const match = plist.match(/<key>WorkingDirectory<\/key>\s*<string>(.+?)<\/string>/);
|
|
197
|
+
if (match) p.log.info(`Directory: ${match[1]}`);
|
|
198
|
+
} catch {
|
|
199
|
+
}
|
|
200
|
+
} else {
|
|
201
|
+
try {
|
|
202
|
+
const output = execSync(`systemctl --user is-active ${SERVICE_NAME}`, {
|
|
203
|
+
encoding: "utf-8"
|
|
204
|
+
}).trim();
|
|
205
|
+
if (output === "active") {
|
|
206
|
+
p.log.success("Running");
|
|
207
|
+
} else {
|
|
208
|
+
p.log.warn(`Status: ${output}`);
|
|
209
|
+
}
|
|
210
|
+
const statusOutput = execSync(`systemctl --user status ${SERVICE_NAME} --no-pager -l`, {
|
|
211
|
+
encoding: "utf-8"
|
|
212
|
+
});
|
|
213
|
+
console.log(statusOutput);
|
|
214
|
+
} catch (err) {
|
|
215
|
+
const servicePath = getLinuxServicePath();
|
|
216
|
+
if (existsSync(servicePath)) {
|
|
217
|
+
p.log.warn("Installed but not running.");
|
|
218
|
+
} else {
|
|
219
|
+
p.log.warn("No systemd service installed.");
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
async function handleDaemon(subcommand) {
|
|
225
|
+
switch (subcommand) {
|
|
226
|
+
case "install":
|
|
227
|
+
await install();
|
|
228
|
+
break;
|
|
229
|
+
case "uninstall":
|
|
230
|
+
case "remove":
|
|
231
|
+
await uninstall();
|
|
232
|
+
break;
|
|
233
|
+
case "status":
|
|
234
|
+
await status();
|
|
235
|
+
break;
|
|
236
|
+
default:
|
|
237
|
+
console.log(`
|
|
238
|
+
\x1B[1mworkspacecord daemon\x1B[0m \u2014 manage background service
|
|
239
|
+
|
|
240
|
+
\x1B[1mUsage:\x1B[0m
|
|
241
|
+
workspacecord daemon install Install and start as background service
|
|
242
|
+
workspacecord daemon uninstall Stop and remove the background service
|
|
243
|
+
workspacecord daemon status Check if the service is running
|
|
244
|
+
|
|
245
|
+
The service auto-starts on boot and restarts on crash.
|
|
246
|
+
Run \x1B[36mworkspacecord config setup\x1B[0m first to configure the bot.
|
|
247
|
+
`);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
export {
|
|
251
|
+
handleDaemon
|
|
252
|
+
};
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
getAllRegisteredProjects,
|
|
4
|
+
getProjectByPath,
|
|
5
|
+
loadRegistry,
|
|
6
|
+
registerProject,
|
|
7
|
+
removeProject,
|
|
8
|
+
renameProject,
|
|
9
|
+
unbindProjectCategory
|
|
10
|
+
} from "./chunk-NIXZJTOZ.js";
|
|
11
|
+
import "./chunk-K3NQKI34.js";
|
|
12
|
+
|
|
13
|
+
// src/project-cli.ts
|
|
14
|
+
import { basename, resolve } from "path";
|
|
15
|
+
function parseNameArg(args) {
|
|
16
|
+
const index = args.indexOf("--name");
|
|
17
|
+
if (index >= 0 && args[index + 1]) return args[index + 1];
|
|
18
|
+
return void 0;
|
|
19
|
+
}
|
|
20
|
+
function printHelp() {
|
|
21
|
+
console.log(`
|
|
22
|
+
workspacecord project \u2014 manage mounted projects
|
|
23
|
+
|
|
24
|
+
Usage:
|
|
25
|
+
workspacecord project init [--name <name>]
|
|
26
|
+
workspacecord project list
|
|
27
|
+
workspacecord project info
|
|
28
|
+
workspacecord project rename <new-name>
|
|
29
|
+
workspacecord project remove
|
|
30
|
+
`);
|
|
31
|
+
}
|
|
32
|
+
async function handleProject(args) {
|
|
33
|
+
await loadRegistry();
|
|
34
|
+
const [subcommand, ...rest] = args;
|
|
35
|
+
switch (subcommand) {
|
|
36
|
+
case "init": {
|
|
37
|
+
const cwd = resolve(process.cwd());
|
|
38
|
+
const name = parseNameArg(rest) || basename(cwd);
|
|
39
|
+
const project = await registerProject(name, cwd);
|
|
40
|
+
console.log(`\u2713 Project mounted: ${project.name}`);
|
|
41
|
+
console.log(` Path: ${project.path}`);
|
|
42
|
+
if (project.discordCategoryId) {
|
|
43
|
+
console.log(
|
|
44
|
+
` Bound Discord category: ${project.discordCategoryName ?? project.discordCategoryId}`
|
|
45
|
+
);
|
|
46
|
+
} else {
|
|
47
|
+
console.log(" Discord binding: pending (`/project setup` in Discord)");
|
|
48
|
+
}
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
case "list": {
|
|
52
|
+
const projects = getAllRegisteredProjects();
|
|
53
|
+
if (projects.length === 0) {
|
|
54
|
+
console.log("No projects mounted. Run `workspacecord project init` in a repository.");
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
for (const project of projects) {
|
|
58
|
+
const status = project.discordCategoryId ? `discord:${project.discordCategoryName ?? project.discordCategoryId}` : "discord:pending";
|
|
59
|
+
console.log(`${project.name} ${project.path} [${status}]`);
|
|
60
|
+
}
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
case "info": {
|
|
64
|
+
const cwd = resolve(process.cwd());
|
|
65
|
+
const project = getProjectByPath(cwd);
|
|
66
|
+
if (!project) {
|
|
67
|
+
console.log("Current directory is not mounted as a workspacecord project.");
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
console.log(`name: ${project.name}`);
|
|
71
|
+
console.log(`path: ${project.path}`);
|
|
72
|
+
console.log(`discordCategoryId: ${project.discordCategoryId ?? "(pending)"}`);
|
|
73
|
+
console.log(`discordCategoryName: ${project.discordCategoryName ?? "(pending)"}`);
|
|
74
|
+
console.log(`historyChannelId: ${project.historyChannelId ?? "(pending)"}`);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
case "rename": {
|
|
78
|
+
const newName = rest[0];
|
|
79
|
+
if (!newName) {
|
|
80
|
+
console.error("Usage: workspacecord project rename <new-name>");
|
|
81
|
+
process.exit(1);
|
|
82
|
+
}
|
|
83
|
+
const cwd = resolve(process.cwd());
|
|
84
|
+
const project = getProjectByPath(cwd);
|
|
85
|
+
if (!project) {
|
|
86
|
+
console.error("Current directory is not mounted.");
|
|
87
|
+
process.exit(1);
|
|
88
|
+
}
|
|
89
|
+
await renameProject(project.name, newName);
|
|
90
|
+
console.log(`\u2713 Project renamed: ${project.name} -> ${newName}`);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
case "remove": {
|
|
94
|
+
const cwd = resolve(process.cwd());
|
|
95
|
+
const project = getProjectByPath(cwd);
|
|
96
|
+
if (!project) {
|
|
97
|
+
console.error("Current directory is not mounted.");
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
if (project.discordCategoryId) {
|
|
101
|
+
await unbindProjectCategory(project.name);
|
|
102
|
+
}
|
|
103
|
+
await removeProject(project.name);
|
|
104
|
+
console.log(`\u2713 Project removed: ${project.name}`);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
case void 0:
|
|
108
|
+
case "help":
|
|
109
|
+
case "--help":
|
|
110
|
+
case "-h":
|
|
111
|
+
printHelp();
|
|
112
|
+
return;
|
|
113
|
+
default:
|
|
114
|
+
console.error(`Unknown project subcommand: ${subcommand}`);
|
|
115
|
+
printHelp();
|
|
116
|
+
process.exit(1);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
export {
|
|
120
|
+
handleProject
|
|
121
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
bindProjectCategory,
|
|
4
|
+
getAllRegisteredProjects,
|
|
5
|
+
getProjectByCategoryId,
|
|
6
|
+
getProjectByName,
|
|
7
|
+
getProjectByPath,
|
|
8
|
+
loadRegistry,
|
|
9
|
+
registerProject,
|
|
10
|
+
removeProject,
|
|
11
|
+
renameProject,
|
|
12
|
+
setProjectControlChannel,
|
|
13
|
+
setProjectHistoryChannel,
|
|
14
|
+
unbindProjectCategory,
|
|
15
|
+
updateProject
|
|
16
|
+
} from "./chunk-NIXZJTOZ.js";
|
|
17
|
+
import "./chunk-K3NQKI34.js";
|
|
18
|
+
export {
|
|
19
|
+
bindProjectCategory,
|
|
20
|
+
getAllRegisteredProjects,
|
|
21
|
+
getProjectByCategoryId,
|
|
22
|
+
getProjectByName,
|
|
23
|
+
getProjectByPath,
|
|
24
|
+
loadRegistry,
|
|
25
|
+
registerProject,
|
|
26
|
+
removeProject,
|
|
27
|
+
renameProject,
|
|
28
|
+
setProjectControlChannel,
|
|
29
|
+
setProjectHistoryChannel,
|
|
30
|
+
unbindProjectCategory,
|
|
31
|
+
updateProject
|
|
32
|
+
};
|