oh-my-customcode 0.117.0 → 0.118.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/cli/index.js CHANGED
@@ -2334,7 +2334,7 @@ var init_package = __esm(() => {
2334
2334
  workspaces: [
2335
2335
  "packages/*"
2336
2336
  ],
2337
- version: "0.117.0",
2337
+ version: "0.118.1",
2338
2338
  description: "Batteries-included agent harness for Claude Code",
2339
2339
  type: "module",
2340
2340
  bin: {
@@ -9607,9 +9607,9 @@ __export(exports_projects, {
9607
9607
  default: () => projects_default
9608
9608
  });
9609
9609
  import { homedir as homedir3 } from "node:os";
9610
- import { basename as basename4, join as join10, sep as sep3 } from "node:path";
9610
+ import { basename as basename4, join as join11, sep as sep3 } from "node:path";
9611
9611
  async function readLockFile(projectDir) {
9612
- const lockFilePath = join10(projectDir, ".omcustom.lock.json");
9612
+ const lockFilePath = join11(projectDir, ".omcustom.lock.json");
9613
9613
  try {
9614
9614
  const fs2 = await import("node:fs/promises");
9615
9615
  const content = await fs2.readFile(lockFilePath, "utf-8");
@@ -9715,7 +9715,7 @@ async function _scanDirForLockfiles(dir2, depth, seen, results, home, currentVer
9715
9715
  }
9716
9716
  if (depth < 3) {
9717
9717
  const subdirs = entries.filter((e) => e.isDirectory() && !e.name.startsWith(".") && !SCAN_SKIP_DIRS2.has(e.name));
9718
- await Promise.all(subdirs.map((sub) => _scanDirForLockfiles(join10(dir2, sub.name), depth + 1, seen, results, home, currentVersion, fs2).catch(() => {})));
9718
+ await Promise.all(subdirs.map((sub) => _scanDirForLockfiles(join11(dir2, sub.name), depth + 1, seen, results, home, currentVersion, fs2).catch(() => {})));
9719
9719
  }
9720
9720
  }
9721
9721
  async function _findProjectsFromLockfiles(options, currentVersion) {
@@ -9738,7 +9738,7 @@ async function _findProjectsFromLockfiles(options, currentVersion) {
9738
9738
  }
9739
9739
  async function writeLockFile(projectDir, version, existing) {
9740
9740
  const fs2 = await import("node:fs/promises");
9741
- const lockFilePath = join10(projectDir, ".omcustom.lock.json");
9741
+ const lockFilePath = join11(projectDir, ".omcustom.lock.json");
9742
9742
  const now = new Date().toISOString();
9743
9743
  const merged = {
9744
9744
  ...existing || {},
@@ -9806,7 +9806,7 @@ async function runMigration(options) {
9806
9806
  const { homedir: _homedir } = await import("node:os");
9807
9807
  const DEFAULT_SEARCH_DIRS = ["workspace", "projects", "dev", "src", "code", "repos", "work"];
9808
9808
  const home = _homedir();
9809
- const searchDirs = [...DEFAULT_SEARCH_DIRS.map((d) => join10(home, d)), ...options.paths ?? []];
9809
+ const searchDirs = [...DEFAULT_SEARCH_DIRS.map((d) => join11(home, d)), ...options.paths ?? []];
9810
9810
  const cwd = process.cwd();
9811
9811
  if (!searchDirs.includes(cwd))
9812
9812
  searchDirs.push(cwd);
@@ -27552,7 +27552,7 @@ async function doctorCommand(options = {}) {
27552
27552
 
27553
27553
  // src/cli/init.ts
27554
27554
  init_package();
27555
- import { join as join12 } from "node:path";
27555
+ import { join as join13 } from "node:path";
27556
27556
 
27557
27557
  // src/core/installer.ts
27558
27558
  init_fs();
@@ -28392,7 +28392,6 @@ async function backupExistingInstallation(targetDir) {
28392
28392
 
28393
28393
  // src/core/mcp-config.ts
28394
28394
  init_fs();
28395
- import { execSync as execSync5 } from "node:child_process";
28396
28395
  import { writeFile as writeFile2 } from "node:fs/promises";
28397
28396
  import { join as join9 } from "node:path";
28398
28397
  async function generateMCPConfig(targetDir) {
@@ -28403,22 +28402,6 @@ async function generateMCPConfig(targetDir) {
28403
28402
  if (!ontologyExists) {
28404
28403
  return;
28405
28404
  }
28406
- try {
28407
- execSync5("uv --version", { stdio: "pipe" });
28408
- } catch {
28409
- warn("uv (Python package manager) not found. Install it with: curl -LsSf https://astral.sh/uv/install.sh | sh");
28410
- warn("Skipping ontology-rag MCP configuration. You can set it up manually later.");
28411
- return;
28412
- }
28413
- try {
28414
- execSync5("uv venv .venv", { cwd: targetDir, stdio: "pipe" });
28415
- execSync5('uv pip install "ontology-rag @ git+https://github.com/baekenough/oh-my-customcode.git#subdirectory=packages/ontology-rag"', { cwd: targetDir, stdio: "pipe" });
28416
- } catch (error2) {
28417
- const msg = error2 instanceof Error ? error2.message : String(error2);
28418
- warn(`Failed to setup ontology-rag: ${msg}`);
28419
- warn("You can configure the MCP server manually. See: https://github.com/baekenough/oh-my-customcode/tree/develop/packages/ontology-rag");
28420
- return;
28421
- }
28422
28405
  const config = {
28423
28406
  mcpServers: {
28424
28407
  "ontology-rag": {
@@ -28453,14 +28436,151 @@ async function generateMCPConfig(targetDir) {
28453
28436
  }
28454
28437
  info("ontology-rag MCP server configured successfully");
28455
28438
  }
28456
- async function checkUvAvailable() {
28439
+
28440
+ // src/core/ontology-rag-setup.ts
28441
+ init_fs();
28442
+ import { execSync as execSync5 } from "node:child_process";
28443
+ import { join as join10 } from "node:path";
28444
+ var MIN_PYTHON_MINOR = 10;
28445
+ var DETECTION_TIMEOUT_MS = 3000;
28446
+ var INSTALL_TIMEOUT_MS = 90000;
28447
+ function parsePythonVersion(output) {
28448
+ const match = /Python\s+(\d+)\.(\d+)/i.exec(output);
28449
+ if (!match)
28450
+ return null;
28451
+ return [Number(match[1]), Number(match[2])];
28452
+ }
28453
+ function checkPython3() {
28454
+ try {
28455
+ const output = execSync5("python3 --version 2>&1", {
28456
+ stdio: "pipe",
28457
+ timeout: DETECTION_TIMEOUT_MS
28458
+ }).toString().trim();
28459
+ const parsed = parsePythonVersion(output);
28460
+ if (!parsed) {
28461
+ return { available: true, versionOk: false, version: output };
28462
+ }
28463
+ const [major, minor] = parsed;
28464
+ const versionOk = major === 3 && minor >= MIN_PYTHON_MINOR;
28465
+ return { available: true, versionOk, version: `${major}.${minor}` };
28466
+ } catch {
28467
+ return { available: false, versionOk: false, version: "" };
28468
+ }
28469
+ }
28470
+ function checkUvAvailableForSetup() {
28457
28471
  try {
28458
- execSync5("uv --version", { stdio: "pipe" });
28472
+ execSync5("uv --version", { stdio: "pipe", timeout: DETECTION_TIMEOUT_MS });
28459
28473
  return true;
28460
28474
  } catch {
28461
28475
  return false;
28462
28476
  }
28463
28477
  }
28478
+ function createVenvWithUv(targetDir) {
28479
+ execSync5("uv venv --python 3.12 .venv", {
28480
+ cwd: targetDir,
28481
+ stdio: "pipe",
28482
+ timeout: INSTALL_TIMEOUT_MS
28483
+ });
28484
+ }
28485
+ function createVenvWithPython3(targetDir) {
28486
+ execSync5("python3 -m venv .venv", {
28487
+ cwd: targetDir,
28488
+ stdio: "pipe",
28489
+ timeout: INSTALL_TIMEOUT_MS
28490
+ });
28491
+ }
28492
+ function installOntologyRagEditable(targetDir, useUv) {
28493
+ const packageRoot = getPackageRoot();
28494
+ const ontologyPkgPath = join10(packageRoot, "packages", "ontology-rag");
28495
+ if (useUv) {
28496
+ execSync5(`uv pip install --python .venv/bin/python -e "${ontologyPkgPath}"`, {
28497
+ cwd: targetDir,
28498
+ stdio: "pipe",
28499
+ timeout: INSTALL_TIMEOUT_MS
28500
+ });
28501
+ } else {
28502
+ execSync5(`.venv/bin/pip install -e "${ontologyPkgPath}"`, {
28503
+ cwd: targetDir,
28504
+ stdio: "pipe",
28505
+ timeout: INSTALL_TIMEOUT_MS
28506
+ });
28507
+ }
28508
+ }
28509
+ async function setupOntologyRag(targetDir) {
28510
+ if (process.env.OMCUSTOM_SKIP_ONTOLOGY_RAG_SETUP === "1") {
28511
+ const statusLine = "ontology-rag MCP: ⚠ skipped (OMCUSTOM_SKIP_ONTOLOGY_RAG_SETUP=1)";
28512
+ console.warn(`Warning: ${statusLine}`);
28513
+ return { success: false, statusLine, reason: "skipped via env var" };
28514
+ }
28515
+ const python = checkPython3();
28516
+ if (!python.available) {
28517
+ const reason = `python3 not found. Install Python >= 3.${MIN_PYTHON_MINOR} (https://python.org) to enable ontology-rag.`;
28518
+ console.warn(`Warning: ${reason}`);
28519
+ return {
28520
+ success: false,
28521
+ statusLine: "ontology-rag MCP: skipped (python3 not found)",
28522
+ reason
28523
+ };
28524
+ }
28525
+ if (!python.versionOk) {
28526
+ const reason = `python3 ${python.version} is below the required 3.${MIN_PYTHON_MINOR}. ` + `Upgrade Python to enable ontology-rag.`;
28527
+ console.warn(`Warning: ${reason}`);
28528
+ return {
28529
+ success: false,
28530
+ statusLine: `ontology-rag MCP: skipped (python3 ${python.version} < 3.${MIN_PYTHON_MINOR})`,
28531
+ reason
28532
+ };
28533
+ }
28534
+ const uvAvailable = checkUvAvailableForSetup();
28535
+ if (!uvAvailable) {
28536
+ console.warn("Warning: uv not found. Falling back to `python3 -m venv` for ontology-rag setup.");
28537
+ console.warn("Install uv (https://docs.astral.sh/uv/) for faster Python environment setup.");
28538
+ }
28539
+ try {
28540
+ if (uvAvailable) {
28541
+ createVenvWithUv(targetDir);
28542
+ } else {
28543
+ createVenvWithPython3(targetDir);
28544
+ }
28545
+ } catch (err) {
28546
+ const msg = err instanceof Error ? err.message : String(err);
28547
+ const reason = `Failed to create .venv: ${msg}`;
28548
+ console.warn(`Warning: ${reason}`);
28549
+ return {
28550
+ success: false,
28551
+ statusLine: "ontology-rag MCP: skipped (venv creation failed)",
28552
+ reason
28553
+ };
28554
+ }
28555
+ try {
28556
+ installOntologyRagEditable(targetDir, uvAvailable);
28557
+ } catch (err) {
28558
+ const msg = err instanceof Error ? err.message : String(err);
28559
+ const reason = `Failed to install ontology-rag: ${msg}`;
28560
+ console.warn(`Warning: ${reason}`);
28561
+ return {
28562
+ success: false,
28563
+ statusLine: "ontology-rag MCP: skipped (install failed)",
28564
+ reason
28565
+ };
28566
+ }
28567
+ const venvPython = join10(targetDir, ".venv", "bin", "python");
28568
+ const venvReady = await fileExists(venvPython);
28569
+ if (!venvReady) {
28570
+ const reason = ".venv/bin/python missing after install — environment may be incomplete. " + "Run `uv pip install -e packages/ontology-rag` manually to complete setup.";
28571
+ console.warn(`Warning: ${reason}`);
28572
+ return {
28573
+ success: false,
28574
+ statusLine: "ontology-rag MCP: skipped (venv incomplete)",
28575
+ reason
28576
+ };
28577
+ }
28578
+ console.log("ontology-rag MCP: ready");
28579
+ return {
28580
+ success: true,
28581
+ statusLine: "ontology-rag MCP: ready"
28582
+ };
28583
+ }
28464
28584
 
28465
28585
  // src/cli/init.ts
28466
28586
  init_registry();
@@ -28470,12 +28590,12 @@ init_package();
28470
28590
  init_projects();
28471
28591
  import { existsSync as existsSync2 } from "node:fs";
28472
28592
  import { copyFile as copyFile2, cp } from "node:fs/promises";
28473
- import { join as join11 } from "node:path";
28593
+ import { join as join12 } from "node:path";
28474
28594
  init_fs();
28475
28595
  init_registry();
28476
28596
  async function checkExistingInstallation(targetDir) {
28477
28597
  const layout = getProviderLayout();
28478
- const rootDir = join11(targetDir, layout.rootDir);
28598
+ const rootDir = join12(targetDir, layout.rootDir);
28479
28599
  return fileExists(rootDir);
28480
28600
  }
28481
28601
  async function installFromSnapshot(targetDir, snapshotPath, options) {
@@ -28487,7 +28607,7 @@ async function installFromSnapshot(targetDir, snapshotPath, options) {
28487
28607
  };
28488
28608
  }
28489
28609
  const layout = getProviderLayout();
28490
- const snapshotClaude = join11(snapshotPath, layout.rootDir);
28610
+ const snapshotClaude = join12(snapshotPath, layout.rootDir);
28491
28611
  if (!existsSync2(snapshotClaude)) {
28492
28612
  return {
28493
28613
  success: false,
@@ -28501,24 +28621,24 @@ async function installFromSnapshot(targetDir, snapshotPath, options) {
28501
28621
  if (exists2 && !options.force) {
28502
28622
  console.log(i18n.t("cli.init.exists", { rootDir: layout.rootDir }));
28503
28623
  console.log(i18n.t("cli.init.backing_up"));
28504
- const backupDir = join11(targetDir, `.claude-backup-${new Date().toISOString().replace(/[:.]/g, "-").slice(0, -1)}`);
28505
- await cp(join11(targetDir, layout.rootDir), backupDir, { recursive: true });
28624
+ const backupDir = join12(targetDir, `.claude-backup-${new Date().toISOString().replace(/[:.]/g, "-").slice(0, -1)}`);
28625
+ await cp(join12(targetDir, layout.rootDir), backupDir, { recursive: true });
28506
28626
  console.log(` Backed up to: ${backupDir}`);
28507
28627
  }
28508
- await cp(snapshotClaude, join11(targetDir, layout.rootDir), {
28628
+ await cp(snapshotClaude, join12(targetDir, layout.rootDir), {
28509
28629
  recursive: true,
28510
28630
  force: true
28511
28631
  });
28512
- const snapshotGuides = join11(snapshotPath, "guides");
28632
+ const snapshotGuides = join12(snapshotPath, "guides");
28513
28633
  if (existsSync2(snapshotGuides)) {
28514
- await cp(snapshotGuides, join11(targetDir, "guides"), {
28634
+ await cp(snapshotGuides, join12(targetDir, "guides"), {
28515
28635
  recursive: true,
28516
28636
  force: true
28517
28637
  });
28518
28638
  }
28519
- const snapshotEntry = join11(snapshotPath, layout.entryFile);
28639
+ const snapshotEntry = join12(snapshotPath, layout.entryFile);
28520
28640
  if (existsSync2(snapshotEntry)) {
28521
- await copyFile2(snapshotEntry, join11(targetDir, layout.entryFile));
28641
+ await copyFile2(snapshotEntry, join12(targetDir, layout.entryFile));
28522
28642
  }
28523
28643
  try {
28524
28644
  const existing = await readLockFile(targetDir);
@@ -29526,7 +29646,7 @@ async function runInitWizard(options) {
29526
29646
  // src/cli/init.ts
29527
29647
  async function checkExistingInstallation2(targetDir) {
29528
29648
  const layout = getProviderLayout();
29529
- const rootDir = join12(targetDir, layout.rootDir);
29649
+ const rootDir = join13(targetDir, layout.rootDir);
29530
29650
  return fileExists(rootDir);
29531
29651
  }
29532
29652
  var PROVIDER_SUBDIR_COMPONENTS = new Set([
@@ -29540,13 +29660,13 @@ var PROVIDER_SUBDIR_COMPONENTS = new Set([
29540
29660
  function componentToPath(targetDir, component) {
29541
29661
  if (component === "entry-md") {
29542
29662
  const layout = getProviderLayout();
29543
- return join12(targetDir, layout.entryFile);
29663
+ return join13(targetDir, layout.entryFile);
29544
29664
  }
29545
29665
  if (PROVIDER_SUBDIR_COMPONENTS.has(component)) {
29546
29666
  const layout = getProviderLayout();
29547
- return join12(targetDir, layout.rootDir, component);
29667
+ return join13(targetDir, layout.rootDir, component);
29548
29668
  }
29549
- return join12(targetDir, component);
29669
+ return join13(targetDir, component);
29550
29670
  }
29551
29671
  function buildInstalledPaths(targetDir, components) {
29552
29672
  return components.map((component) => componentToPath(targetDir, component));
@@ -29597,17 +29717,15 @@ async function resolveOptions(options) {
29597
29717
  return { lang: defaults.lang, domain: defaults.domain };
29598
29718
  }
29599
29719
  async function setupMcpConfig(targetDir) {
29600
- const uvAvailable = await checkUvAvailable();
29601
- if (uvAvailable) {
29720
+ const setupResult = await setupOntologyRag(targetDir);
29721
+ console.log(` ${setupResult.statusLine}`);
29722
+ if (setupResult.success) {
29602
29723
  try {
29603
29724
  await generateMCPConfig(targetDir);
29604
29725
  } catch (error2) {
29605
29726
  const msg = error2 instanceof Error ? error2.message : String(error2);
29606
- console.warn(`Warning: Failed to setup MCP environment: ${msg}`);
29727
+ console.warn(`Warning: Failed to write .mcp.json: ${msg}`);
29607
29728
  }
29608
- } else {
29609
- console.warn("Warning: uv not found. Skipping MCP server configuration.");
29610
- console.warn("Install uv (https://docs.astral.sh/uv/) to enable MCP integration.");
29611
29729
  }
29612
29730
  }
29613
29731
  async function initCommand(options) {
@@ -29671,7 +29789,7 @@ async function initCommand(options) {
29671
29789
  }
29672
29790
 
29673
29791
  // src/cli/list.ts
29674
- import { basename as basename5, dirname as dirname3, join as join13, relative as relative3 } from "node:path";
29792
+ import { basename as basename5, dirname as dirname3, join as join14, relative as relative3 } from "node:path";
29675
29793
  init_fs();
29676
29794
  var ALLOWED_TOP_LEVEL_KEYS = new Set(["name", "type", "description", "version", "category"]);
29677
29795
  function parseKeyValue(line) {
@@ -29736,12 +29854,12 @@ function extractAgentTypeFromFilename(filename) {
29736
29854
  return prefixMap[prefix] || "unknown";
29737
29855
  }
29738
29856
  function extractSkillCategoryFromPath(skillPath, baseDir, rootDir) {
29739
- const relativePath = relative3(join13(baseDir, rootDir, "skills"), skillPath);
29857
+ const relativePath = relative3(join14(baseDir, rootDir, "skills"), skillPath);
29740
29858
  const parts = relativePath.split("/").filter(Boolean);
29741
29859
  return parts[0] || "unknown";
29742
29860
  }
29743
29861
  function extractGuideCategoryFromPath(guidePath, baseDir) {
29744
- const relativePath = relative3(join13(baseDir, "guides"), guidePath);
29862
+ const relativePath = relative3(join14(baseDir, "guides"), guidePath);
29745
29863
  const parts = relativePath.split("/").filter(Boolean);
29746
29864
  return parts[0] || "unknown";
29747
29865
  }
@@ -29835,7 +29953,7 @@ async function tryExtractMarkdownDescription(mdPath, options = {}) {
29835
29953
  }
29836
29954
  }
29837
29955
  async function getAgents(targetDir, rootDir = ".claude", config) {
29838
- const agentsDir = join13(targetDir, rootDir, "agents");
29956
+ const agentsDir = join14(targetDir, rootDir, "agents");
29839
29957
  if (!await fileExists(agentsDir))
29840
29958
  return [];
29841
29959
  try {
@@ -29863,7 +29981,7 @@ async function getAgents(targetDir, rootDir = ".claude", config) {
29863
29981
  }
29864
29982
  }
29865
29983
  async function getSkills(targetDir, rootDir = ".claude", config) {
29866
- const skillsDir = join13(targetDir, rootDir, "skills");
29984
+ const skillsDir = join14(targetDir, rootDir, "skills");
29867
29985
  if (!await fileExists(skillsDir))
29868
29986
  return [];
29869
29987
  try {
@@ -29873,7 +29991,7 @@ async function getSkills(targetDir, rootDir = ".claude", config) {
29873
29991
  const skillMdFiles = await listFiles(skillsDir, { recursive: true, pattern: "SKILL.md" });
29874
29992
  const skills = await Promise.all(skillMdFiles.map(async (skillMdPath) => {
29875
29993
  const skillDir = dirname3(skillMdPath);
29876
- const indexYamlPath = join13(skillDir, "index.yaml");
29994
+ const indexYamlPath = join14(skillDir, "index.yaml");
29877
29995
  const { description, version } = await tryReadIndexYamlMetadata(indexYamlPath);
29878
29996
  const relativePath = relative3(targetDir, skillDir);
29879
29997
  return {
@@ -29892,7 +30010,7 @@ async function getSkills(targetDir, rootDir = ".claude", config) {
29892
30010
  }
29893
30011
  }
29894
30012
  async function getGuides(targetDir, config) {
29895
- const guidesDir = join13(targetDir, "guides");
30013
+ const guidesDir = join14(targetDir, "guides");
29896
30014
  if (!await fileExists(guidesDir))
29897
30015
  return [];
29898
30016
  try {
@@ -29919,7 +30037,7 @@ async function getGuides(targetDir, config) {
29919
30037
  }
29920
30038
  var RULE_PRIORITY_ORDER = { MUST: 0, SHOULD: 1, MAY: 2 };
29921
30039
  async function getRules(targetDir, rootDir = ".claude", config) {
29922
- const rulesDir = join13(targetDir, rootDir, "rules");
30040
+ const rulesDir = join14(targetDir, rootDir, "rules");
29923
30041
  if (!await fileExists(rulesDir))
29924
30042
  return [];
29925
30043
  try {
@@ -29991,7 +30109,7 @@ function formatAsJson(components) {
29991
30109
  console.log(JSON.stringify(components, null, 2));
29992
30110
  }
29993
30111
  async function getHooks(targetDir, rootDir = ".claude") {
29994
- const hooksDir = join13(targetDir, rootDir, "hooks");
30112
+ const hooksDir = join14(targetDir, rootDir, "hooks");
29995
30113
  if (!await fileExists(hooksDir))
29996
30114
  return [];
29997
30115
  try {
@@ -30009,7 +30127,7 @@ async function getHooks(targetDir, rootDir = ".claude") {
30009
30127
  }
30010
30128
  }
30011
30129
  async function getContexts(targetDir, rootDir = ".claude") {
30012
- const contextsDir = join13(targetDir, rootDir, "contexts");
30130
+ const contextsDir = join14(targetDir, rootDir, "contexts");
30013
30131
  if (!await fileExists(contextsDir))
30014
30132
  return [];
30015
30133
  try {
@@ -30402,22 +30520,22 @@ async function securityCommand(_options = {}) {
30402
30520
 
30403
30521
  // src/cli/serve-commands.ts
30404
30522
  import { spawnSync as spawnSync2 } from "node:child_process";
30405
- import { join as join15 } from "node:path";
30523
+ import { join as join16 } from "node:path";
30406
30524
 
30407
30525
  // src/cli/serve.ts
30408
30526
  import { spawn } from "node:child_process";
30409
30527
  import { existsSync as existsSync3 } from "node:fs";
30410
30528
  import { readFile as readFile3, unlink, writeFile as writeFile3 } from "node:fs/promises";
30411
- import { join as join14 } from "node:path";
30529
+ import { join as join15 } from "node:path";
30412
30530
  var DEFAULT_PORT = 4321;
30413
- var PID_FILE = join14(process.env.HOME ?? "~", ".omcustom-serve.pid");
30531
+ var PID_FILE = join15(process.env.HOME ?? "~", ".omcustom-serve.pid");
30414
30532
  function findServeBuildDir(projectRoot, options) {
30415
- const localBuild = join14(projectRoot, "packages", "serve", "build");
30416
- if (existsSync3(join14(localBuild, "index.js")))
30533
+ const localBuild = join15(projectRoot, "packages", "serve", "build");
30534
+ if (existsSync3(join15(localBuild, "index.js")))
30417
30535
  return localBuild;
30418
30536
  if (options?.skipNpmFallback !== true) {
30419
- const npmBuild = join14(import.meta.dirname, "..", "..", "packages", "serve", "build");
30420
- if (existsSync3(join14(npmBuild, "index.js")))
30537
+ const npmBuild = join15(import.meta.dirname, "..", "..", "packages", "serve", "build");
30538
+ if (existsSync3(join15(npmBuild, "index.js")))
30421
30539
  return npmBuild;
30422
30540
  }
30423
30541
  return null;
@@ -30445,7 +30563,7 @@ async function startServeBackground(projectRoot, port = DEFAULT_PORT, buildDirOp
30445
30563
  if (buildDir === null) {
30446
30564
  return;
30447
30565
  }
30448
- const child = spawn("node", [join14(buildDir, "index.js")], {
30566
+ const child = spawn("node", [join15(buildDir, "index.js")], {
30449
30567
  env: {
30450
30568
  ...process.env,
30451
30569
  OMCUSTOM_PORT: String(port),
@@ -30522,7 +30640,7 @@ function runForeground(projectRoot, port, buildDirOpts) {
30522
30640
  process.exit(1);
30523
30641
  }
30524
30642
  console.log(`Web UI: http://localhost:${port}`);
30525
- spawnSync2("node", [join15(buildDir, "index.js")], {
30643
+ spawnSync2("node", [join16(buildDir, "index.js")], {
30526
30644
  env: {
30527
30645
  ...process.env,
30528
30646
  OMCUSTOM_PORT: String(port),
@@ -30541,12 +30659,12 @@ import { resolve as resolve3 } from "node:path";
30541
30659
  init_fs();
30542
30660
  import { existsSync as existsSync4 } from "node:fs";
30543
30661
  import { cp as cp2, mkdir as mkdir2 } from "node:fs/promises";
30544
- import { join as join16 } from "node:path";
30662
+ import { join as join17 } from "node:path";
30545
30663
  async function loadVersions() {
30546
30664
  try {
30547
30665
  const packageRoot = getPackageRoot();
30548
- const manifest = await readJsonFile(join16(packageRoot, "templates", "manifest.json"));
30549
- const pkg = await readJsonFile(join16(packageRoot, "package.json"));
30666
+ const manifest = await readJsonFile(join17(packageRoot, "templates", "manifest.json"));
30667
+ const pkg = await readJsonFile(join17(packageRoot, "package.json"));
30550
30668
  return { generatorVersion: pkg.version, templateVersion: manifest.version };
30551
30669
  } catch {
30552
30670
  return { generatorVersion: "0.0.0", templateVersion: "0.0.0" };
@@ -30616,7 +30734,7 @@ async function countFiles(dir2) {
30616
30734
  return 0;
30617
30735
  }
30618
30736
  for (const entry of entries) {
30619
- const full = join16(current, entry);
30737
+ const full = join17(current, entry);
30620
30738
  try {
30621
30739
  const s = await stat3(full);
30622
30740
  if (s.isDirectory()) {
@@ -30631,19 +30749,19 @@ async function countFiles(dir2) {
30631
30749
  return walk(dir2);
30632
30750
  }
30633
30751
  async function exportSnapshot(targetDir, outputPath) {
30634
- const claudeDir = join16(targetDir, ".claude");
30635
- const guidesDir = join16(targetDir, "guides");
30752
+ const claudeDir = join17(targetDir, ".claude");
30753
+ const guidesDir = join17(targetDir, "guides");
30636
30754
  if (!existsSync4(claudeDir)) {
30637
30755
  return { success: false, exportPath: outputPath, fileCount: 0 };
30638
30756
  }
30639
30757
  await mkdir2(outputPath, { recursive: true });
30640
- const destClaude = join16(outputPath, ".claude");
30758
+ const destClaude = join17(outputPath, ".claude");
30641
30759
  await cp2(claudeDir, destClaude, {
30642
30760
  recursive: true,
30643
30761
  filter: isExportable
30644
30762
  });
30645
30763
  if (existsSync4(guidesDir)) {
30646
- await cp2(guidesDir, join16(outputPath, "guides"), { recursive: true });
30764
+ await cp2(guidesDir, join17(outputPath, "guides"), { recursive: true });
30647
30765
  }
30648
30766
  const lockfile = await generateCurrentLockfile(targetDir);
30649
30767
  if (lockfile) {
@@ -30727,7 +30845,7 @@ import { constants as osConstants } from "node:os";
30727
30845
 
30728
30846
  // src/core/updater.ts
30729
30847
  init_package();
30730
- import { join as join17 } from "node:path";
30848
+ import { join as join18 } from "node:path";
30731
30849
  init_fs();
30732
30850
 
30733
30851
  // src/core/entry-merger.ts
@@ -30982,7 +31100,7 @@ function resolveCustomizations(customizations, configPreserveFiles, targetDir) {
30982
31100
  }
30983
31101
  async function updateEntryDoc(targetDir, config, options) {
30984
31102
  const layout = getProviderLayout();
30985
- const entryPath = join17(targetDir, layout.entryFile);
31103
+ const entryPath = join18(targetDir, layout.entryFile);
30986
31104
  const templateName = getEntryTemplateName2(config.language);
30987
31105
  const templatePath = resolveTemplatePath(templateName);
30988
31106
  if (!await fileExists(templatePath)) {
@@ -31020,7 +31138,7 @@ async function backfillStatusLineRefreshInterval(targetDir, options) {
31020
31138
  return;
31021
31139
  }
31022
31140
  const layout = getProviderLayout();
31023
- const settingsPath = join17(targetDir, layout.rootDir, "settings.local.json");
31141
+ const settingsPath = join18(targetDir, layout.rootDir, "settings.local.json");
31024
31142
  if (!await fileExists(settingsPath)) {
31025
31143
  return;
31026
31144
  }
@@ -31106,7 +31224,7 @@ async function regenerateLockfile(targetDir, result) {
31106
31224
  }
31107
31225
  }
31108
31226
  async function shouldSkipSelfUpdate2(targetDir, result) {
31109
- const targetPkgPath = join17(targetDir, "package.json");
31227
+ const targetPkgPath = join18(targetDir, "package.json");
31110
31228
  if (await fileExists(targetPkgPath)) {
31111
31229
  const targetPkg = await readJsonFile(targetPkgPath);
31112
31230
  if (targetPkg.name === "oh-my-customcode") {
@@ -31245,11 +31363,11 @@ async function collectProtectedSkipPaths(srcPath, destPath, componentPath, force
31245
31363
  const warnedPaths = [];
31246
31364
  const updatedPaths = [];
31247
31365
  for (const p of protectedRelative) {
31248
- const targetFilePath = join17(targetDir, componentPath, p);
31366
+ const targetFilePath = join18(targetDir, componentPath, p);
31249
31367
  const lockfileKey = `${componentPath}/${p}`.replace(/\\/g, "/");
31250
31368
  const shouldSkip = await shouldSkipProtectedFile(targetFilePath, lockfileKey, lockfile);
31251
31369
  if (shouldSkip) {
31252
- skipPaths.push(path3.relative(destPath, join17(destPath, p)));
31370
+ skipPaths.push(path3.relative(destPath, join18(destPath, p)));
31253
31371
  warnedPaths.push(p);
31254
31372
  } else {
31255
31373
  updatedPaths.push(p);
@@ -31295,7 +31413,7 @@ async function updateComponent(targetDir, component, customizations, options, co
31295
31413
  const preservedFiles = [];
31296
31414
  const componentPath = getComponentPath2(component);
31297
31415
  const srcPath = resolveTemplatePath(componentPath);
31298
- const destPath = join17(targetDir, componentPath);
31416
+ const destPath = join18(targetDir, componentPath);
31299
31417
  const customComponents = config.customComponents || [];
31300
31418
  const skipPaths = [];
31301
31419
  if (customizations && !options.forceOverwriteAll) {
@@ -31337,7 +31455,7 @@ async function updateComponent(targetDir, component, customizations, options, co
31337
31455
  }
31338
31456
  skipPaths.push(...protectedSkipPaths);
31339
31457
  const path3 = await import("node:path");
31340
- const normalizedSkipPaths = skipPaths.map((p) => path3.relative(destPath, join17(targetDir, p)));
31458
+ const normalizedSkipPaths = skipPaths.map((p) => path3.relative(destPath, join18(targetDir, p)));
31341
31459
  const uniqueSkipPaths = [...new Set(normalizedSkipPaths)];
31342
31460
  await copyDirectory(srcPath, destPath, {
31343
31461
  overwrite: true,
@@ -31359,12 +31477,12 @@ async function syncRootLevelFiles(targetDir, options) {
31359
31477
  const layout = getProviderLayout();
31360
31478
  const synced = [];
31361
31479
  for (const fileName of ROOT_LEVEL_FILES) {
31362
- const srcPath = resolveTemplatePath(join17(layout.rootDir, fileName));
31480
+ const srcPath = resolveTemplatePath(join18(layout.rootDir, fileName));
31363
31481
  if (!await fileExists(srcPath)) {
31364
31482
  continue;
31365
31483
  }
31366
- const destPath = join17(targetDir, layout.rootDir, fileName);
31367
- await ensureDirectory(join17(destPath, ".."));
31484
+ const destPath = join18(targetDir, layout.rootDir, fileName);
31485
+ await ensureDirectory(join18(destPath, ".."));
31368
31486
  await fs3.copyFile(srcPath, destPath);
31369
31487
  if (fileName.endsWith(".sh")) {
31370
31488
  await fs3.chmod(destPath, 493);
@@ -31399,7 +31517,7 @@ async function removeDeprecatedFiles(targetDir, options) {
31399
31517
  });
31400
31518
  continue;
31401
31519
  }
31402
- const fullPath = join17(targetDir, entry.path);
31520
+ const fullPath = join18(targetDir, entry.path);
31403
31521
  if (await fileExists(fullPath)) {
31404
31522
  await fs3.unlink(fullPath);
31405
31523
  removed.push(entry.path);
@@ -31440,7 +31558,7 @@ async function syncNamespaceInFile(targetFilePath, upstreamFilePath) {
31440
31558
  async function processNamespaceSyncEntry(entry, relPath, fullSrcPath, destPath, componentPath, lockfile) {
31441
31559
  if (!entry.isFile() || !entry.name.endsWith(".md"))
31442
31560
  return null;
31443
- const targetFilePath = join17(destPath, relPath);
31561
+ const targetFilePath = join18(destPath, relPath);
31444
31562
  const lockfileKey = `${componentPath}/${relPath}`.replace(/\\/g, "/");
31445
31563
  const shouldSkip = await shouldSkipProtectedFile(targetFilePath, lockfileKey, lockfile);
31446
31564
  if (shouldSkip)
@@ -31455,7 +31573,7 @@ async function applyNamespaceSync(targetDir, component, lockfile) {
31455
31573
  return [];
31456
31574
  const componentPath = getComponentPath2(component);
31457
31575
  const srcPath = resolveTemplatePath(componentPath);
31458
- const destPath = join17(targetDir, componentPath);
31576
+ const destPath = join18(targetDir, componentPath);
31459
31577
  const fs3 = await import("node:fs/promises");
31460
31578
  const synced = [];
31461
31579
  const queue = [{ dir: srcPath, relDir: "" }];
@@ -31469,7 +31587,7 @@ async function applyNamespaceSync(targetDir, component, lockfile) {
31469
31587
  }
31470
31588
  for (const entry of entries) {
31471
31589
  const relPath = relDir ? `${relDir}/${entry.name}` : entry.name;
31472
- const fullSrcPath = join17(dir2, entry.name);
31590
+ const fullSrcPath = join18(dir2, entry.name);
31473
31591
  if (entry.isDirectory()) {
31474
31592
  queue.push({ dir: fullSrcPath, relDir: relPath });
31475
31593
  continue;
@@ -31492,26 +31610,26 @@ function getComponentPath2(component) {
31492
31610
  }
31493
31611
  async function backupInstallation(targetDir) {
31494
31612
  const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
31495
- const backupDir = join17(targetDir, `.omcustom-backup-${timestamp}`);
31613
+ const backupDir = join18(targetDir, `.omcustom-backup-${timestamp}`);
31496
31614
  const fs3 = await import("node:fs/promises");
31497
31615
  await ensureDirectory(backupDir);
31498
31616
  const layout = getProviderLayout();
31499
31617
  const dirsToBackup = [layout.rootDir, "guides"];
31500
31618
  for (const dir2 of dirsToBackup) {
31501
- const srcPath = join17(targetDir, dir2);
31619
+ const srcPath = join18(targetDir, dir2);
31502
31620
  if (await fileExists(srcPath)) {
31503
- const destPath = join17(backupDir, dir2);
31621
+ const destPath = join18(backupDir, dir2);
31504
31622
  await copyDirectory(srcPath, destPath, { overwrite: true });
31505
31623
  }
31506
31624
  }
31507
- const entryPath = join17(targetDir, layout.entryFile);
31625
+ const entryPath = join18(targetDir, layout.entryFile);
31508
31626
  if (await fileExists(entryPath)) {
31509
- await fs3.copyFile(entryPath, join17(backupDir, layout.entryFile));
31627
+ await fs3.copyFile(entryPath, join18(backupDir, layout.entryFile));
31510
31628
  }
31511
31629
  return backupDir;
31512
31630
  }
31513
31631
  async function loadCustomizationManifest(targetDir) {
31514
- const manifestPath = join17(targetDir, CUSTOMIZATION_MANIFEST_FILE);
31632
+ const manifestPath = join18(targetDir, CUSTOMIZATION_MANIFEST_FILE);
31515
31633
  if (await fileExists(manifestPath)) {
31516
31634
  return readJsonFile(manifestPath);
31517
31635
  }
package/dist/index.js CHANGED
@@ -2014,7 +2014,7 @@ var package_default = {
2014
2014
  workspaces: [
2015
2015
  "packages/*"
2016
2016
  ],
2017
- version: "0.117.0",
2017
+ version: "0.118.1",
2018
2018
  description: "Batteries-included agent harness for Claude Code",
2019
2019
  type: "module",
2020
2020
  bin: {