oh-my-customcode 0.68.0 → 0.68.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/README.md +7 -7
- package/dist/cli/index.js +162 -15
- package/dist/index.js +2518 -12
- package/package.json +1 -1
- package/templates/manifest.json +1 -1
package/README.md
CHANGED
|
@@ -294,15 +294,15 @@ your-project/
|
|
|
294
294
|
|
|
295
295
|
---
|
|
296
296
|
|
|
297
|
-
##
|
|
297
|
+
## External Tool Integrations
|
|
298
298
|
|
|
299
|
-
|
|
299
|
+
RTK is automatically installed during `omcustom init` for 60-90% token savings. Other tools are optional:
|
|
300
300
|
|
|
301
|
-
| Tool | Purpose | Install |
|
|
302
|
-
|
|
303
|
-
| [RTK](https://github.com/rtk-ai/rtk) | 60-90% token savings on CLI output |
|
|
304
|
-
| [Codex CLI](https://github.com/openai/codex) | OpenAI Codex hybrid workflows | `npm i -g @openai/codex` |
|
|
305
|
-
| [Gemini CLI](https://github.com/google-gemini/gemini-cli) | Google Gemini hybrid workflows | `npm i -g @
|
|
301
|
+
| Tool | Purpose | Install | Status |
|
|
302
|
+
|------|---------|---------|--------|
|
|
303
|
+
| [RTK](https://github.com/rtk-ai/rtk) | 60-90% token savings on CLI output | Auto-installed via `omcustom init` | **Recommended** |
|
|
304
|
+
| [Codex CLI](https://github.com/openai/codex) | OpenAI Codex hybrid workflows | `npm i -g @openai/codex` | Optional |
|
|
305
|
+
| [Gemini CLI](https://github.com/google-gemini/gemini-cli) | Google Gemini hybrid workflows | `npm i -g @google/gemini-cli` | Optional |
|
|
306
306
|
|
|
307
307
|
When installed, each tool is **auto-detected** at session start and its features become available. When not installed, all commands gracefully fall back to Claude-native alternatives.
|
|
308
308
|
|
package/dist/cli/index.js
CHANGED
|
@@ -9325,7 +9325,7 @@ var init_package = __esm(() => {
|
|
|
9325
9325
|
workspaces: [
|
|
9326
9326
|
"packages/*"
|
|
9327
9327
|
],
|
|
9328
|
-
version: "0.68.
|
|
9328
|
+
version: "0.68.2",
|
|
9329
9329
|
description: "Batteries-included agent harness for Claude Code",
|
|
9330
9330
|
type: "module",
|
|
9331
9331
|
bin: {
|
|
@@ -24824,7 +24824,9 @@ var en_default = {
|
|
|
24824
24824
|
interactiveNoneSelected: "No projects selected. Exiting.",
|
|
24825
24825
|
interactiveUpdating: "Updating selected projects...",
|
|
24826
24826
|
projectLatestSuffix: "(latest)",
|
|
24827
|
-
newVersionAvailable: "[Info] oh-my-customcode v{{latest}} available (current: v{{current}}). Run 'npm i -g oh-my-customcode' to upgrade."
|
|
24827
|
+
newVersionAvailable: "[Info] oh-my-customcode v{{latest}} available (current: v{{current}}). Run 'npm i -g oh-my-customcode' to upgrade.",
|
|
24828
|
+
rtkMissing: "[RTK] RTK is not installed. Attempting installation...",
|
|
24829
|
+
rtkInstalled: "[RTK] ✓ RTK installed — 60-90% token savings activated"
|
|
24828
24830
|
},
|
|
24829
24831
|
list: {
|
|
24830
24832
|
description: "List installed components",
|
|
@@ -24924,6 +24926,10 @@ var en_default = {
|
|
|
24924
24926
|
framework: {
|
|
24925
24927
|
pass: "Framework is up to date (v{{version}})",
|
|
24926
24928
|
warn: "Framework is outdated: installed v{{installed}}, latest v{{latest}} ({{behind}} version(s) behind). Run 'omcustom update' to sync."
|
|
24929
|
+
},
|
|
24930
|
+
rtk: {
|
|
24931
|
+
pass: "RTK installed",
|
|
24932
|
+
warn: "RTK not installed — token savings unavailable"
|
|
24927
24933
|
}
|
|
24928
24934
|
}
|
|
24929
24935
|
},
|
|
@@ -24983,6 +24989,12 @@ var en_default = {
|
|
|
24983
24989
|
}
|
|
24984
24990
|
}
|
|
24985
24991
|
},
|
|
24992
|
+
install: {
|
|
24993
|
+
rtk_installing: "Installing RTK...",
|
|
24994
|
+
rtk_success: "RTK installed successfully",
|
|
24995
|
+
rtk_already: "RTK already installed",
|
|
24996
|
+
rtk_install_failed: "RTK installation failed"
|
|
24997
|
+
},
|
|
24986
24998
|
init: {
|
|
24987
24999
|
description: "Initialize oh-my-customcode in the current directory",
|
|
24988
25000
|
starting: "Initializing oh-my-customcode...",
|
|
@@ -25209,7 +25221,9 @@ var ko_default = {
|
|
|
25209
25221
|
interactiveNoneSelected: "선택된 프로젝트가 없습니다. 종료합니다.",
|
|
25210
25222
|
interactiveUpdating: "선택된 프로젝트 업데이트 중...",
|
|
25211
25223
|
projectLatestSuffix: "(최신)",
|
|
25212
|
-
newVersionAvailable: "[정보] oh-my-customcode v{{latest}} 사용 가능 (현재: v{{current}}). 'npm i -g oh-my-customcode'를 실행하여 업그레이드하세요."
|
|
25224
|
+
newVersionAvailable: "[정보] oh-my-customcode v{{latest}} 사용 가능 (현재: v{{current}}). 'npm i -g oh-my-customcode'를 실행하여 업그레이드하세요.",
|
|
25225
|
+
rtkMissing: "[RTK] RTK가 설치되지 않았습니다. 설치를 시도합니다...",
|
|
25226
|
+
rtkInstalled: "[RTK] ✓ RTK 설치 완료 — 토큰 60-90% 절감 활성화"
|
|
25213
25227
|
},
|
|
25214
25228
|
list: {
|
|
25215
25229
|
description: "설치된 컴포넌트 목록 표시",
|
|
@@ -25309,6 +25323,10 @@ var ko_default = {
|
|
|
25309
25323
|
framework: {
|
|
25310
25324
|
pass: "프레임워크가 최신 상태입니다 (v{{version}})",
|
|
25311
25325
|
warn: "프레임워크가 구버전입니다: 설치됨 v{{installed}}, 최신 v{{latest}} ({{behind}}개 버전 뒤처짐). 'omcustom update'를 실행하여 동기화하세요."
|
|
25326
|
+
},
|
|
25327
|
+
rtk: {
|
|
25328
|
+
pass: "RTK 설치됨",
|
|
25329
|
+
warn: "RTK 미설치 — 토큰 절감 불가"
|
|
25312
25330
|
}
|
|
25313
25331
|
}
|
|
25314
25332
|
},
|
|
@@ -25368,6 +25386,12 @@ var ko_default = {
|
|
|
25368
25386
|
}
|
|
25369
25387
|
}
|
|
25370
25388
|
},
|
|
25389
|
+
install: {
|
|
25390
|
+
rtk_installing: "RTK 설치 중...",
|
|
25391
|
+
rtk_success: "RTK 설치 완료",
|
|
25392
|
+
rtk_already: "RTK 이미 설치됨",
|
|
25393
|
+
rtk_install_failed: "RTK 설치 실패"
|
|
25394
|
+
},
|
|
25371
25395
|
init: {
|
|
25372
25396
|
description: "현재 디렉토리에 oh-my-customcode 초기화",
|
|
25373
25397
|
starting: "oh-my-customcode 초기화 중...",
|
|
@@ -25513,6 +25537,19 @@ function compareSemver(a, b) {
|
|
|
25513
25537
|
}
|
|
25514
25538
|
return 0;
|
|
25515
25539
|
}
|
|
25540
|
+
function isVersionPlausible(currentVersion, candidateVersion) {
|
|
25541
|
+
const current = normalizeVersion(currentVersion).split(".").map((n) => parseInt(n, 10) || 0);
|
|
25542
|
+
const candidate = normalizeVersion(candidateVersion).split(".").map((n) => parseInt(n, 10) || 0);
|
|
25543
|
+
const majorDiff = (candidate[0] ?? 0) - (current[0] ?? 0);
|
|
25544
|
+
const minorDiff = (candidate[1] ?? 0) - (current[1] ?? 0);
|
|
25545
|
+
if (majorDiff >= 1) {
|
|
25546
|
+
return false;
|
|
25547
|
+
}
|
|
25548
|
+
if (majorDiff === 0 && minorDiff >= 10) {
|
|
25549
|
+
return false;
|
|
25550
|
+
}
|
|
25551
|
+
return true;
|
|
25552
|
+
}
|
|
25516
25553
|
function isInteractiveSession(stdin = process.stdin, stdout = process.stdout) {
|
|
25517
25554
|
return Boolean(stdin.isTTY && stdout.isTTY);
|
|
25518
25555
|
}
|
|
@@ -25639,12 +25676,16 @@ function checkSelfUpdate(options) {
|
|
|
25639
25676
|
let usedCache = false;
|
|
25640
25677
|
const cache = readCache(cachePath);
|
|
25641
25678
|
if (cache && isCacheFresh(cache, now, cacheTtlMs)) {
|
|
25642
|
-
|
|
25643
|
-
|
|
25679
|
+
const cachedVersion = normalizeVersion(cache.latestVersion);
|
|
25680
|
+
if (isVersionPlausible(currentVersion, cachedVersion)) {
|
|
25681
|
+
latestVersion = cachedVersion;
|
|
25682
|
+
usedCache = true;
|
|
25683
|
+
}
|
|
25644
25684
|
}
|
|
25645
25685
|
if (!latestVersion) {
|
|
25646
|
-
|
|
25647
|
-
if (
|
|
25686
|
+
const fetched = fetchLatestVersion(packageName);
|
|
25687
|
+
if (fetched && isVersionPlausible(currentVersion, fetched)) {
|
|
25688
|
+
latestVersion = fetched;
|
|
25648
25689
|
writeCache(cachePath, latestVersion, now);
|
|
25649
25690
|
}
|
|
25650
25691
|
}
|
|
@@ -26361,6 +26402,68 @@ async function generateAndWriteLockfileForDir(targetDir) {
|
|
|
26361
26402
|
}
|
|
26362
26403
|
}
|
|
26363
26404
|
|
|
26405
|
+
// src/core/rtk-installer.ts
|
|
26406
|
+
import { execSync as execSync3 } from "node:child_process";
|
|
26407
|
+
import { platform } from "node:os";
|
|
26408
|
+
function isRtkInstalled() {
|
|
26409
|
+
try {
|
|
26410
|
+
execSync3("which rtk", { stdio: "pipe", timeout: 3000 });
|
|
26411
|
+
return true;
|
|
26412
|
+
} catch {
|
|
26413
|
+
return false;
|
|
26414
|
+
}
|
|
26415
|
+
}
|
|
26416
|
+
function getRtkVersion() {
|
|
26417
|
+
try {
|
|
26418
|
+
return execSync3("rtk --version", { encoding: "utf-8", stdio: "pipe", timeout: 3000 }).trim();
|
|
26419
|
+
} catch {
|
|
26420
|
+
return null;
|
|
26421
|
+
}
|
|
26422
|
+
}
|
|
26423
|
+
function installRtk() {
|
|
26424
|
+
if (process.env.CI || false || false) {
|
|
26425
|
+
return false;
|
|
26426
|
+
}
|
|
26427
|
+
if (isRtkInstalled()) {
|
|
26428
|
+
info("rtk.already_installed");
|
|
26429
|
+
return true;
|
|
26430
|
+
}
|
|
26431
|
+
const os = platform();
|
|
26432
|
+
try {
|
|
26433
|
+
if (os === "darwin") {
|
|
26434
|
+
try {
|
|
26435
|
+
info("rtk.installing_brew");
|
|
26436
|
+
execSync3("brew install rtk-ai/tap/rtk", {
|
|
26437
|
+
stdio: "inherit",
|
|
26438
|
+
timeout: 120000
|
|
26439
|
+
});
|
|
26440
|
+
return true;
|
|
26441
|
+
} catch {
|
|
26442
|
+
info("rtk.installing_curl");
|
|
26443
|
+
execSync3("curl -fsSL https://raw.githubusercontent.com/rtk-ai/rtk/refs/heads/master/install.sh | sh", {
|
|
26444
|
+
stdio: "inherit",
|
|
26445
|
+
timeout: 120000
|
|
26446
|
+
});
|
|
26447
|
+
return isRtkInstalled();
|
|
26448
|
+
}
|
|
26449
|
+
} else if (os === "linux") {
|
|
26450
|
+
info("rtk.installing_curl");
|
|
26451
|
+
execSync3("curl -fsSL https://raw.githubusercontent.com/rtk-ai/rtk/refs/heads/master/install.sh | sh", {
|
|
26452
|
+
stdio: "inherit",
|
|
26453
|
+
timeout: 120000
|
|
26454
|
+
});
|
|
26455
|
+
return isRtkInstalled();
|
|
26456
|
+
} else {
|
|
26457
|
+
warn("rtk.unsupported_os", { os });
|
|
26458
|
+
return false;
|
|
26459
|
+
}
|
|
26460
|
+
} catch (err) {
|
|
26461
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
26462
|
+
warn("rtk.install_failed", { error: message });
|
|
26463
|
+
return false;
|
|
26464
|
+
}
|
|
26465
|
+
}
|
|
26466
|
+
|
|
26364
26467
|
// src/cli/doctor.ts
|
|
26365
26468
|
async function pathExists(targetPath) {
|
|
26366
26469
|
try {
|
|
@@ -26660,6 +26763,23 @@ async function checkHooks(targetDir, rootDir = ".claude") {
|
|
|
26660
26763
|
fixable: false
|
|
26661
26764
|
};
|
|
26662
26765
|
}
|
|
26766
|
+
async function checkRtk() {
|
|
26767
|
+
if (!isRtkInstalled()) {
|
|
26768
|
+
return {
|
|
26769
|
+
name: "RTK",
|
|
26770
|
+
status: "warn",
|
|
26771
|
+
message: "RTK not installed — token savings unavailable (brew install rtk-ai/tap/rtk)",
|
|
26772
|
+
fixable: true
|
|
26773
|
+
};
|
|
26774
|
+
}
|
|
26775
|
+
const version = getRtkVersion();
|
|
26776
|
+
return {
|
|
26777
|
+
name: "RTK",
|
|
26778
|
+
status: "pass",
|
|
26779
|
+
message: `RTK OK (${version ?? "unknown version"})`,
|
|
26780
|
+
fixable: false
|
|
26781
|
+
};
|
|
26782
|
+
}
|
|
26663
26783
|
async function checkContexts(targetDir, rootDir = ".claude") {
|
|
26664
26784
|
const contextsDir = path.join(targetDir, rootDir, "contexts");
|
|
26665
26785
|
const exists2 = await isDirectory(contextsDir);
|
|
@@ -26762,7 +26882,8 @@ async function fixSingleIssue(check, targetDir, rootDir = ".claude") {
|
|
|
26762
26882
|
const fullPaths = check.details.map((d) => path.join(targetDir, d));
|
|
26763
26883
|
const fixedCount = await fixBrokenSymlinks(targetDir, fullPaths);
|
|
26764
26884
|
return fixedCount > 0;
|
|
26765
|
-
}
|
|
26885
|
+
},
|
|
26886
|
+
RTK: async () => Promise.resolve(installRtk())
|
|
26766
26887
|
};
|
|
26767
26888
|
const fixer = fixMap[check.name];
|
|
26768
26889
|
return fixer ? fixer() : false;
|
|
@@ -26910,7 +27031,8 @@ async function runAllChecks(targetDir, layout, packageVersion, includeUpdates) {
|
|
|
26910
27031
|
checkGuides(targetDir),
|
|
26911
27032
|
checkHooks(targetDir, layout.rootDir),
|
|
26912
27033
|
checkContexts(targetDir, layout.rootDir),
|
|
26913
|
-
checkCustomComponents(targetDir, layout.rootDir)
|
|
27034
|
+
checkCustomComponents(targetDir, layout.rootDir),
|
|
27035
|
+
checkRtk()
|
|
26914
27036
|
]);
|
|
26915
27037
|
const frameworkCheck = await checkFrameworkDrift(targetDir, packageVersion);
|
|
26916
27038
|
const checksWithFramework = frameworkCheck ? [...baseChecks, frameworkCheck] : baseChecks;
|
|
@@ -27558,6 +27680,19 @@ async function updateInstallConfig(targetDir, options, installedComponents) {
|
|
|
27558
27680
|
config.installedComponents = installedComponents;
|
|
27559
27681
|
await saveConfig(targetDir, config);
|
|
27560
27682
|
}
|
|
27683
|
+
function installRtkIfNeeded(result) {
|
|
27684
|
+
if (!isRtkInstalled()) {
|
|
27685
|
+
info("install.rtk_installing");
|
|
27686
|
+
const rtkInstalled = installRtk();
|
|
27687
|
+
if (rtkInstalled) {
|
|
27688
|
+
info("install.rtk_success");
|
|
27689
|
+
} else {
|
|
27690
|
+
result.warnings.push("RTK installation failed — install manually: brew install rtk-ai/tap/rtk");
|
|
27691
|
+
}
|
|
27692
|
+
} else {
|
|
27693
|
+
info("install.rtk_already");
|
|
27694
|
+
}
|
|
27695
|
+
}
|
|
27561
27696
|
async function install(options) {
|
|
27562
27697
|
const result = createInstallResult(options.targetDir);
|
|
27563
27698
|
try {
|
|
@@ -27595,6 +27730,7 @@ async function install(options) {
|
|
|
27595
27730
|
} else {
|
|
27596
27731
|
info("install.lockfile_generated", { files: String(lockfileResult.fileCount) });
|
|
27597
27732
|
}
|
|
27733
|
+
installRtkIfNeeded(result);
|
|
27598
27734
|
result.success = true;
|
|
27599
27735
|
success("install.success");
|
|
27600
27736
|
} catch (err) {
|
|
@@ -27778,7 +27914,7 @@ async function backupExistingInstallation(targetDir) {
|
|
|
27778
27914
|
|
|
27779
27915
|
// src/core/mcp-config.ts
|
|
27780
27916
|
init_fs();
|
|
27781
|
-
import { execSync as
|
|
27917
|
+
import { execSync as execSync4 } from "node:child_process";
|
|
27782
27918
|
import { writeFile } from "node:fs/promises";
|
|
27783
27919
|
import { join as join8 } from "node:path";
|
|
27784
27920
|
async function generateMCPConfig(targetDir) {
|
|
@@ -27790,15 +27926,15 @@ async function generateMCPConfig(targetDir) {
|
|
|
27790
27926
|
return;
|
|
27791
27927
|
}
|
|
27792
27928
|
try {
|
|
27793
|
-
|
|
27929
|
+
execSync4("uv --version", { stdio: "pipe" });
|
|
27794
27930
|
} catch {
|
|
27795
27931
|
warn("uv (Python package manager) not found. Install it with: curl -LsSf https://astral.sh/uv/install.sh | sh");
|
|
27796
27932
|
warn("Skipping ontology-rag MCP configuration. You can set it up manually later.");
|
|
27797
27933
|
return;
|
|
27798
27934
|
}
|
|
27799
27935
|
try {
|
|
27800
|
-
|
|
27801
|
-
|
|
27936
|
+
execSync4("uv venv .venv", { cwd: targetDir, stdio: "pipe" });
|
|
27937
|
+
execSync4('uv pip install "ontology-rag @ git+https://github.com/baekenough/oh-my-customcode.git#subdirectory=packages/ontology-rag"', { cwd: targetDir, stdio: "pipe" });
|
|
27802
27938
|
} catch (error2) {
|
|
27803
27939
|
const msg = error2 instanceof Error ? error2.message : String(error2);
|
|
27804
27940
|
warn(`Failed to setup ontology-rag: ${msg}`);
|
|
@@ -27841,7 +27977,7 @@ async function generateMCPConfig(targetDir) {
|
|
|
27841
27977
|
}
|
|
27842
27978
|
async function checkUvAvailable() {
|
|
27843
27979
|
try {
|
|
27844
|
-
|
|
27980
|
+
execSync4("uv --version", { stdio: "pipe" });
|
|
27845
27981
|
return true;
|
|
27846
27982
|
} catch {
|
|
27847
27983
|
return false;
|
|
@@ -29836,8 +29972,8 @@ init_package();
|
|
|
29836
29972
|
|
|
29837
29973
|
// src/core/updater.ts
|
|
29838
29974
|
init_package();
|
|
29839
|
-
init_fs();
|
|
29840
29975
|
import { join as join14 } from "node:path";
|
|
29976
|
+
init_fs();
|
|
29841
29977
|
|
|
29842
29978
|
// src/core/entry-merger.ts
|
|
29843
29979
|
var MANAGED_START = "<!-- omcustom:start -->";
|
|
@@ -30160,6 +30296,16 @@ function compareSemver2(a, b) {
|
|
|
30160
30296
|
}
|
|
30161
30297
|
return 0;
|
|
30162
30298
|
}
|
|
30299
|
+
function checkAndInstallRtkAfterUpdate() {
|
|
30300
|
+
if (!isRtkInstalled()) {
|
|
30301
|
+
warn("update.rtk_missing");
|
|
30302
|
+
console.log(i18n.t("cli.update.rtkMissing"));
|
|
30303
|
+
const rtkInstalled = installRtk();
|
|
30304
|
+
if (rtkInstalled) {
|
|
30305
|
+
console.log(i18n.t("cli.update.rtkInstalled"));
|
|
30306
|
+
}
|
|
30307
|
+
}
|
|
30308
|
+
}
|
|
30163
30309
|
async function update(options) {
|
|
30164
30310
|
const result = createUpdateResult();
|
|
30165
30311
|
try {
|
|
@@ -30207,6 +30353,7 @@ async function update(options) {
|
|
|
30207
30353
|
files: String(lockfileResult.fileCount)
|
|
30208
30354
|
});
|
|
30209
30355
|
}
|
|
30356
|
+
checkAndInstallRtkAfterUpdate();
|
|
30210
30357
|
} catch (err) {
|
|
30211
30358
|
const message = err instanceof Error ? err.message : String(err);
|
|
30212
30359
|
result.error = message;
|