oh-my-customcode 0.42.3 → 0.43.0
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/cli/index.js +186 -30
- package/package.json +1 -1
- package/templates/manifest.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -9376,7 +9376,9 @@ var require_src = __commonJS((exports, module) => {
|
|
|
9376
9376
|
});
|
|
9377
9377
|
|
|
9378
9378
|
// src/cli/index.ts
|
|
9379
|
+
import { existsSync as existsSync3 } from "node:fs";
|
|
9379
9380
|
import { createRequire as createRequire2 } from "node:module";
|
|
9381
|
+
import { join as join14 } from "node:path";
|
|
9380
9382
|
|
|
9381
9383
|
// node_modules/.bun/commander@14.0.2/node_modules/commander/esm.mjs
|
|
9382
9384
|
var import__ = __toESM(require_commander(), 1);
|
|
@@ -14207,7 +14209,7 @@ async function doctorCommand(options = {}) {
|
|
|
14207
14209
|
}
|
|
14208
14210
|
|
|
14209
14211
|
// src/cli/init.ts
|
|
14210
|
-
import { join as
|
|
14212
|
+
import { join as join10 } from "node:path";
|
|
14211
14213
|
|
|
14212
14214
|
// src/core/installer.ts
|
|
14213
14215
|
init_fs();
|
|
@@ -15063,6 +15065,82 @@ async function checkUvAvailable() {
|
|
|
15063
15065
|
// src/cli/init.ts
|
|
15064
15066
|
init_fs();
|
|
15065
15067
|
|
|
15068
|
+
// src/cli/serve.ts
|
|
15069
|
+
import { spawn } from "node:child_process";
|
|
15070
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
15071
|
+
import { readFile as readFile2, unlink, writeFile as writeFile2 } from "node:fs/promises";
|
|
15072
|
+
import { join as join9 } from "node:path";
|
|
15073
|
+
var DEFAULT_PORT = 4321;
|
|
15074
|
+
var PID_FILE = join9(process.env.HOME ?? "~", ".omcustom-serve.pid");
|
|
15075
|
+
function findServeBuildDir(projectRoot) {
|
|
15076
|
+
const localBuild = join9(projectRoot, "packages", "serve", "build");
|
|
15077
|
+
if (existsSync2(join9(localBuild, "index.js")))
|
|
15078
|
+
return localBuild;
|
|
15079
|
+
const npmBuild = join9(import.meta.dirname, "..", "..", "packages", "serve", "build");
|
|
15080
|
+
if (existsSync2(join9(npmBuild, "index.js")))
|
|
15081
|
+
return npmBuild;
|
|
15082
|
+
return null;
|
|
15083
|
+
}
|
|
15084
|
+
async function isServeRunning() {
|
|
15085
|
+
try {
|
|
15086
|
+
const raw = await readFile2(PID_FILE, "utf-8");
|
|
15087
|
+
const pid = Number(raw.trim());
|
|
15088
|
+
if (!Number.isFinite(pid) || pid <= 0) {
|
|
15089
|
+
await cleanupPidFile();
|
|
15090
|
+
return false;
|
|
15091
|
+
}
|
|
15092
|
+
process.kill(pid, 0);
|
|
15093
|
+
return true;
|
|
15094
|
+
} catch {
|
|
15095
|
+
await cleanupPidFile();
|
|
15096
|
+
return false;
|
|
15097
|
+
}
|
|
15098
|
+
}
|
|
15099
|
+
async function startServeBackground(projectRoot, port = DEFAULT_PORT) {
|
|
15100
|
+
if (await isServeRunning()) {
|
|
15101
|
+
return;
|
|
15102
|
+
}
|
|
15103
|
+
const buildDir = findServeBuildDir(projectRoot);
|
|
15104
|
+
if (buildDir === null) {
|
|
15105
|
+
return;
|
|
15106
|
+
}
|
|
15107
|
+
const child = spawn("node", [join9(buildDir, "index.js")], {
|
|
15108
|
+
env: {
|
|
15109
|
+
...process.env,
|
|
15110
|
+
PORT: String(port),
|
|
15111
|
+
HOST: "127.0.0.1",
|
|
15112
|
+
OMCUSTOM_PROJECT_ROOT: projectRoot
|
|
15113
|
+
},
|
|
15114
|
+
stdio: "ignore",
|
|
15115
|
+
detached: true
|
|
15116
|
+
});
|
|
15117
|
+
child.unref();
|
|
15118
|
+
if (child.pid !== undefined) {
|
|
15119
|
+
await writeFile2(PID_FILE, String(child.pid), "utf-8");
|
|
15120
|
+
}
|
|
15121
|
+
}
|
|
15122
|
+
async function stopServe() {
|
|
15123
|
+
try {
|
|
15124
|
+
const raw = await readFile2(PID_FILE, "utf-8");
|
|
15125
|
+
const pid = Number(raw.trim());
|
|
15126
|
+
if (!Number.isFinite(pid) || pid <= 0) {
|
|
15127
|
+
await cleanupPidFile();
|
|
15128
|
+
return false;
|
|
15129
|
+
}
|
|
15130
|
+
process.kill(pid, "SIGTERM");
|
|
15131
|
+
await cleanupPidFile();
|
|
15132
|
+
return true;
|
|
15133
|
+
} catch {
|
|
15134
|
+
await cleanupPidFile();
|
|
15135
|
+
return false;
|
|
15136
|
+
}
|
|
15137
|
+
}
|
|
15138
|
+
async function cleanupPidFile() {
|
|
15139
|
+
try {
|
|
15140
|
+
await unlink(PID_FILE);
|
|
15141
|
+
} catch {}
|
|
15142
|
+
}
|
|
15143
|
+
|
|
15066
15144
|
// node_modules/.bun/@clack+core@1.1.0/node_modules/@clack/core/dist/index.mjs
|
|
15067
15145
|
import { styleText as D } from "node:util";
|
|
15068
15146
|
import { stdout as R, stdin as q } from "node:process";
|
|
@@ -16040,7 +16118,7 @@ async function runInitWizard(options) {
|
|
|
16040
16118
|
// src/cli/init.ts
|
|
16041
16119
|
async function checkExistingInstallation(targetDir) {
|
|
16042
16120
|
const layout = getProviderLayout();
|
|
16043
|
-
const rootDir =
|
|
16121
|
+
const rootDir = join10(targetDir, layout.rootDir);
|
|
16044
16122
|
return fileExists(rootDir);
|
|
16045
16123
|
}
|
|
16046
16124
|
var PROVIDER_SUBDIR_COMPONENTS = new Set([
|
|
@@ -16054,13 +16132,13 @@ var PROVIDER_SUBDIR_COMPONENTS = new Set([
|
|
|
16054
16132
|
function componentToPath(targetDir, component) {
|
|
16055
16133
|
if (component === "entry-md") {
|
|
16056
16134
|
const layout = getProviderLayout();
|
|
16057
|
-
return
|
|
16135
|
+
return join10(targetDir, layout.entryFile);
|
|
16058
16136
|
}
|
|
16059
16137
|
if (PROVIDER_SUBDIR_COMPONENTS.has(component)) {
|
|
16060
16138
|
const layout = getProviderLayout();
|
|
16061
|
-
return
|
|
16139
|
+
return join10(targetDir, layout.rootDir, component);
|
|
16062
16140
|
}
|
|
16063
|
-
return
|
|
16141
|
+
return join10(targetDir, component);
|
|
16064
16142
|
}
|
|
16065
16143
|
function buildInstalledPaths(targetDir, components) {
|
|
16066
16144
|
return components.map((component) => componentToPath(targetDir, component));
|
|
@@ -16162,6 +16240,8 @@ async function initCommand(options) {
|
|
|
16162
16240
|
console.log(" /plugin install context7");
|
|
16163
16241
|
console.log("");
|
|
16164
16242
|
console.log('See CLAUDE.md "외부 의존성" section for details.');
|
|
16243
|
+
await startServeBackground(targetDir).catch(() => {});
|
|
16244
|
+
console.log(`Web UI: http://127.0.0.1:${DEFAULT_PORT}`);
|
|
16165
16245
|
return {
|
|
16166
16246
|
success: true,
|
|
16167
16247
|
message: i18n.t("cli.init.success"),
|
|
@@ -16175,7 +16255,7 @@ async function initCommand(options) {
|
|
|
16175
16255
|
}
|
|
16176
16256
|
|
|
16177
16257
|
// src/cli/list.ts
|
|
16178
|
-
import { basename as basename3, dirname as dirname3, join as
|
|
16258
|
+
import { basename as basename3, dirname as dirname3, join as join11, relative as relative3 } from "node:path";
|
|
16179
16259
|
init_fs();
|
|
16180
16260
|
var ALLOWED_TOP_LEVEL_KEYS = new Set(["name", "type", "description", "version", "category"]);
|
|
16181
16261
|
function parseKeyValue(line) {
|
|
@@ -16240,12 +16320,12 @@ function extractAgentTypeFromFilename(filename) {
|
|
|
16240
16320
|
return prefixMap[prefix] || "unknown";
|
|
16241
16321
|
}
|
|
16242
16322
|
function extractSkillCategoryFromPath(skillPath, baseDir, rootDir) {
|
|
16243
|
-
const relativePath = relative3(
|
|
16323
|
+
const relativePath = relative3(join11(baseDir, rootDir, "skills"), skillPath);
|
|
16244
16324
|
const parts = relativePath.split("/").filter(Boolean);
|
|
16245
16325
|
return parts[0] || "unknown";
|
|
16246
16326
|
}
|
|
16247
16327
|
function extractGuideCategoryFromPath(guidePath, baseDir) {
|
|
16248
|
-
const relativePath = relative3(
|
|
16328
|
+
const relativePath = relative3(join11(baseDir, "guides"), guidePath);
|
|
16249
16329
|
const parts = relativePath.split("/").filter(Boolean);
|
|
16250
16330
|
return parts[0] || "unknown";
|
|
16251
16331
|
}
|
|
@@ -16339,7 +16419,7 @@ async function tryExtractMarkdownDescription(mdPath, options = {}) {
|
|
|
16339
16419
|
}
|
|
16340
16420
|
}
|
|
16341
16421
|
async function getAgents(targetDir, rootDir = ".claude", config) {
|
|
16342
|
-
const agentsDir =
|
|
16422
|
+
const agentsDir = join11(targetDir, rootDir, "agents");
|
|
16343
16423
|
if (!await fileExists(agentsDir))
|
|
16344
16424
|
return [];
|
|
16345
16425
|
try {
|
|
@@ -16367,7 +16447,7 @@ async function getAgents(targetDir, rootDir = ".claude", config) {
|
|
|
16367
16447
|
}
|
|
16368
16448
|
}
|
|
16369
16449
|
async function getSkills(targetDir, rootDir = ".claude", config) {
|
|
16370
|
-
const skillsDir =
|
|
16450
|
+
const skillsDir = join11(targetDir, rootDir, "skills");
|
|
16371
16451
|
if (!await fileExists(skillsDir))
|
|
16372
16452
|
return [];
|
|
16373
16453
|
try {
|
|
@@ -16377,7 +16457,7 @@ async function getSkills(targetDir, rootDir = ".claude", config) {
|
|
|
16377
16457
|
const skillMdFiles = await listFiles(skillsDir, { recursive: true, pattern: "SKILL.md" });
|
|
16378
16458
|
const skills = await Promise.all(skillMdFiles.map(async (skillMdPath) => {
|
|
16379
16459
|
const skillDir = dirname3(skillMdPath);
|
|
16380
|
-
const indexYamlPath =
|
|
16460
|
+
const indexYamlPath = join11(skillDir, "index.yaml");
|
|
16381
16461
|
const { description, version } = await tryReadIndexYamlMetadata(indexYamlPath);
|
|
16382
16462
|
const relativePath = relative3(targetDir, skillDir);
|
|
16383
16463
|
return {
|
|
@@ -16396,7 +16476,7 @@ async function getSkills(targetDir, rootDir = ".claude", config) {
|
|
|
16396
16476
|
}
|
|
16397
16477
|
}
|
|
16398
16478
|
async function getGuides(targetDir, config) {
|
|
16399
|
-
const guidesDir =
|
|
16479
|
+
const guidesDir = join11(targetDir, "guides");
|
|
16400
16480
|
if (!await fileExists(guidesDir))
|
|
16401
16481
|
return [];
|
|
16402
16482
|
try {
|
|
@@ -16423,7 +16503,7 @@ async function getGuides(targetDir, config) {
|
|
|
16423
16503
|
}
|
|
16424
16504
|
var RULE_PRIORITY_ORDER = { MUST: 0, SHOULD: 1, MAY: 2 };
|
|
16425
16505
|
async function getRules(targetDir, rootDir = ".claude", config) {
|
|
16426
|
-
const rulesDir =
|
|
16506
|
+
const rulesDir = join11(targetDir, rootDir, "rules");
|
|
16427
16507
|
if (!await fileExists(rulesDir))
|
|
16428
16508
|
return [];
|
|
16429
16509
|
try {
|
|
@@ -16495,7 +16575,7 @@ function formatAsJson(components) {
|
|
|
16495
16575
|
console.log(JSON.stringify(components, null, 2));
|
|
16496
16576
|
}
|
|
16497
16577
|
async function getHooks(targetDir, rootDir = ".claude") {
|
|
16498
|
-
const hooksDir =
|
|
16578
|
+
const hooksDir = join11(targetDir, rootDir, "hooks");
|
|
16499
16579
|
if (!await fileExists(hooksDir))
|
|
16500
16580
|
return [];
|
|
16501
16581
|
try {
|
|
@@ -16513,7 +16593,7 @@ async function getHooks(targetDir, rootDir = ".claude") {
|
|
|
16513
16593
|
}
|
|
16514
16594
|
}
|
|
16515
16595
|
async function getContexts(targetDir, rootDir = ".claude") {
|
|
16516
|
-
const contextsDir =
|
|
16596
|
+
const contextsDir = join11(targetDir, rootDir, "contexts");
|
|
16517
16597
|
if (!await fileExists(contextsDir))
|
|
16518
16598
|
return [];
|
|
16519
16599
|
try {
|
|
@@ -16901,9 +16981,72 @@ async function securityCommand(_options = {}) {
|
|
|
16901
16981
|
};
|
|
16902
16982
|
}
|
|
16903
16983
|
|
|
16984
|
+
// src/cli/serve-commands.ts
|
|
16985
|
+
import { execFile, spawnSync as spawnSync2 } from "node:child_process";
|
|
16986
|
+
import { join as join12 } from "node:path";
|
|
16987
|
+
async function serveCommand(options) {
|
|
16988
|
+
const port = options.port !== undefined ? Number(options.port) : DEFAULT_PORT;
|
|
16989
|
+
if (!Number.isFinite(port) || port < 1 || port > 65535) {
|
|
16990
|
+
console.error(`Invalid port: ${options.port}`);
|
|
16991
|
+
process.exit(1);
|
|
16992
|
+
}
|
|
16993
|
+
const cwd = process.cwd();
|
|
16994
|
+
if (options.foreground === true) {
|
|
16995
|
+
runForeground(cwd, port);
|
|
16996
|
+
return;
|
|
16997
|
+
}
|
|
16998
|
+
await startServeBackground(cwd, port);
|
|
16999
|
+
const running = await isServeRunning();
|
|
17000
|
+
if (running) {
|
|
17001
|
+
console.log(`Web UI started: http://127.0.0.1:${port}`);
|
|
17002
|
+
if (options.open === true) {
|
|
17003
|
+
openBrowser(port);
|
|
17004
|
+
}
|
|
17005
|
+
} else {
|
|
17006
|
+
console.error("Failed to start Web UI server");
|
|
17007
|
+
process.exit(1);
|
|
17008
|
+
}
|
|
17009
|
+
}
|
|
17010
|
+
async function serveStopCommand() {
|
|
17011
|
+
const stopped = await stopServe();
|
|
17012
|
+
if (stopped) {
|
|
17013
|
+
console.log("Web UI server stopped");
|
|
17014
|
+
} else {
|
|
17015
|
+
console.log("Web UI server is not running");
|
|
17016
|
+
}
|
|
17017
|
+
}
|
|
17018
|
+
function runForeground(projectRoot, port) {
|
|
17019
|
+
const buildDir = findServeBuildDir(projectRoot);
|
|
17020
|
+
if (buildDir === null) {
|
|
17021
|
+
console.error("Web UI build not found. Run: cd packages/serve && bun run build");
|
|
17022
|
+
process.exit(1);
|
|
17023
|
+
}
|
|
17024
|
+
console.log(`Web UI: http://127.0.0.1:${port}`);
|
|
17025
|
+
spawnSync2("node", [join12(buildDir, "index.js")], {
|
|
17026
|
+
env: {
|
|
17027
|
+
...process.env,
|
|
17028
|
+
PORT: String(port),
|
|
17029
|
+
HOST: "127.0.0.1",
|
|
17030
|
+
OMCUSTOM_PROJECT_ROOT: projectRoot
|
|
17031
|
+
},
|
|
17032
|
+
stdio: "inherit"
|
|
17033
|
+
});
|
|
17034
|
+
}
|
|
17035
|
+
function openBrowser(port) {
|
|
17036
|
+
const url = `http://127.0.0.1:${port}`;
|
|
17037
|
+
const platform = process.platform;
|
|
17038
|
+
if (platform === "darwin") {
|
|
17039
|
+
execFile("open", [url], () => {});
|
|
17040
|
+
} else if (platform === "win32") {
|
|
17041
|
+
execFile("cmd", ["/c", "start", url], () => {});
|
|
17042
|
+
} else {
|
|
17043
|
+
execFile("xdg-open", [url], () => {});
|
|
17044
|
+
}
|
|
17045
|
+
}
|
|
17046
|
+
|
|
16904
17047
|
// src/core/updater.ts
|
|
16905
17048
|
init_fs();
|
|
16906
|
-
import { join as
|
|
17049
|
+
import { join as join13 } from "node:path";
|
|
16907
17050
|
|
|
16908
17051
|
// src/core/entry-merger.ts
|
|
16909
17052
|
var MANAGED_START = "<!-- omcustom:start -->";
|
|
@@ -17152,7 +17295,7 @@ function resolveCustomizations(customizations, configPreserveFiles, targetDir) {
|
|
|
17152
17295
|
}
|
|
17153
17296
|
async function updateEntryDoc(targetDir, config, options) {
|
|
17154
17297
|
const layout = getProviderLayout();
|
|
17155
|
-
const entryPath =
|
|
17298
|
+
const entryPath = join13(targetDir, layout.entryFile);
|
|
17156
17299
|
const templateName = getEntryTemplateName2(config.language);
|
|
17157
17300
|
const templatePath = resolveTemplatePath(templateName);
|
|
17158
17301
|
if (!await fileExists(templatePath)) {
|
|
@@ -17298,7 +17441,7 @@ async function collectProtectedSkipPaths(srcPath, destPath, componentPath, force
|
|
|
17298
17441
|
}
|
|
17299
17442
|
const protectedRelative = await findProtectedFilesInDir(srcPath, componentPath);
|
|
17300
17443
|
const path3 = await import("node:path");
|
|
17301
|
-
const skipPaths = protectedRelative.map((p) => path3.relative(destPath,
|
|
17444
|
+
const skipPaths = protectedRelative.map((p) => path3.relative(destPath, join13(destPath, p)));
|
|
17302
17445
|
return { skipPaths, warnedPaths: protectedRelative };
|
|
17303
17446
|
}
|
|
17304
17447
|
function isEntryProtected(relPath, componentRelativePrefix) {
|
|
@@ -17339,7 +17482,7 @@ async function updateComponent(targetDir, component, customizations, options, co
|
|
|
17339
17482
|
const preservedFiles = [];
|
|
17340
17483
|
const componentPath = getComponentPath2(component);
|
|
17341
17484
|
const srcPath = resolveTemplatePath(componentPath);
|
|
17342
|
-
const destPath =
|
|
17485
|
+
const destPath = join13(targetDir, componentPath);
|
|
17343
17486
|
const customComponents = config.customComponents || [];
|
|
17344
17487
|
const skipPaths = [];
|
|
17345
17488
|
if (customizations && !options.forceOverwriteAll) {
|
|
@@ -17370,7 +17513,7 @@ async function updateComponent(targetDir, component, customizations, options, co
|
|
|
17370
17513
|
}
|
|
17371
17514
|
skipPaths.push(...protectedSkipPaths);
|
|
17372
17515
|
const path3 = await import("node:path");
|
|
17373
|
-
const normalizedSkipPaths = skipPaths.map((p) => path3.relative(destPath,
|
|
17516
|
+
const normalizedSkipPaths = skipPaths.map((p) => path3.relative(destPath, join13(targetDir, p)));
|
|
17374
17517
|
const uniqueSkipPaths = [...new Set(normalizedSkipPaths)];
|
|
17375
17518
|
await copyDirectory(srcPath, destPath, {
|
|
17376
17519
|
overwrite: true,
|
|
@@ -17392,12 +17535,12 @@ async function syncRootLevelFiles(targetDir, options) {
|
|
|
17392
17535
|
const layout = getProviderLayout();
|
|
17393
17536
|
const synced = [];
|
|
17394
17537
|
for (const fileName of ROOT_LEVEL_FILES) {
|
|
17395
|
-
const srcPath = resolveTemplatePath(
|
|
17538
|
+
const srcPath = resolveTemplatePath(join13(layout.rootDir, fileName));
|
|
17396
17539
|
if (!await fileExists(srcPath)) {
|
|
17397
17540
|
continue;
|
|
17398
17541
|
}
|
|
17399
|
-
const destPath =
|
|
17400
|
-
await ensureDirectory(
|
|
17542
|
+
const destPath = join13(targetDir, layout.rootDir, fileName);
|
|
17543
|
+
await ensureDirectory(join13(destPath, ".."));
|
|
17401
17544
|
await fs3.copyFile(srcPath, destPath);
|
|
17402
17545
|
if (fileName.endsWith(".sh")) {
|
|
17403
17546
|
await fs3.chmod(destPath, 493);
|
|
@@ -17432,7 +17575,7 @@ async function removeDeprecatedFiles(targetDir, options) {
|
|
|
17432
17575
|
});
|
|
17433
17576
|
continue;
|
|
17434
17577
|
}
|
|
17435
|
-
const fullPath =
|
|
17578
|
+
const fullPath = join13(targetDir, entry.path);
|
|
17436
17579
|
if (await fileExists(fullPath)) {
|
|
17437
17580
|
await fs3.unlink(fullPath);
|
|
17438
17581
|
removed.push(entry.path);
|
|
@@ -17456,26 +17599,26 @@ function getComponentPath2(component) {
|
|
|
17456
17599
|
}
|
|
17457
17600
|
async function backupInstallation(targetDir) {
|
|
17458
17601
|
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
17459
|
-
const backupDir =
|
|
17602
|
+
const backupDir = join13(targetDir, `.omcustom-backup-${timestamp}`);
|
|
17460
17603
|
const fs3 = await import("node:fs/promises");
|
|
17461
17604
|
await ensureDirectory(backupDir);
|
|
17462
17605
|
const layout = getProviderLayout();
|
|
17463
17606
|
const dirsToBackup = [layout.rootDir, "guides"];
|
|
17464
17607
|
for (const dir2 of dirsToBackup) {
|
|
17465
|
-
const srcPath =
|
|
17608
|
+
const srcPath = join13(targetDir, dir2);
|
|
17466
17609
|
if (await fileExists(srcPath)) {
|
|
17467
|
-
const destPath =
|
|
17610
|
+
const destPath = join13(backupDir, dir2);
|
|
17468
17611
|
await copyDirectory(srcPath, destPath, { overwrite: true });
|
|
17469
17612
|
}
|
|
17470
17613
|
}
|
|
17471
|
-
const entryPath =
|
|
17614
|
+
const entryPath = join13(targetDir, layout.entryFile);
|
|
17472
17615
|
if (await fileExists(entryPath)) {
|
|
17473
|
-
await fs3.copyFile(entryPath,
|
|
17616
|
+
await fs3.copyFile(entryPath, join13(backupDir, layout.entryFile));
|
|
17474
17617
|
}
|
|
17475
17618
|
return backupDir;
|
|
17476
17619
|
}
|
|
17477
17620
|
async function loadCustomizationManifest(targetDir) {
|
|
17478
|
-
const manifestPath =
|
|
17621
|
+
const manifestPath = join13(targetDir, CUSTOMIZATION_MANIFEST_FILE);
|
|
17479
17622
|
if (await fileExists(manifestPath)) {
|
|
17480
17623
|
return readJsonFile(manifestPath);
|
|
17481
17624
|
}
|
|
@@ -17585,6 +17728,12 @@ function createProgram() {
|
|
|
17585
17728
|
const result = await securityCommand(options);
|
|
17586
17729
|
process.exitCode = result.success ? 0 : 1;
|
|
17587
17730
|
});
|
|
17731
|
+
program2.command("serve").description("Start the web UI server").option("-p, --port <port>", "Port number", "4321").option("--open", "Open browser automatically").option("--foreground", "Run in foreground (not detached)").action(async (options) => {
|
|
17732
|
+
await serveCommand(options);
|
|
17733
|
+
});
|
|
17734
|
+
program2.command("serve-stop").description("Stop the web UI server").action(async () => {
|
|
17735
|
+
await serveStopCommand();
|
|
17736
|
+
});
|
|
17588
17737
|
program2.hook("preAction", async (thisCommand, actionCommand) => {
|
|
17589
17738
|
const opts = thisCommand.optsWithGlobals();
|
|
17590
17739
|
const skipCheck = opts.skipVersionCheck || false;
|
|
@@ -17600,6 +17749,13 @@ function createProgram() {
|
|
|
17600
17749
|
console.warn(warnings);
|
|
17601
17750
|
console.warn("");
|
|
17602
17751
|
}
|
|
17752
|
+
const commandName = actionCommand.name();
|
|
17753
|
+
if (commandName !== "serve-stop" && commandName !== "serve") {
|
|
17754
|
+
const cwd = process.cwd();
|
|
17755
|
+
if (existsSync3(join14(cwd, ".claude"))) {
|
|
17756
|
+
startServeBackground(cwd).catch(() => {});
|
|
17757
|
+
}
|
|
17758
|
+
}
|
|
17603
17759
|
});
|
|
17604
17760
|
return program2;
|
|
17605
17761
|
}
|
package/package.json
CHANGED
package/templates/manifest.json
CHANGED