oh-my-customcodex 0.1.0 → 0.1.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 +126 -16
- package/dist/index.js +72 -4
- package/package.json +1 -1
- package/templates/manifest.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -3087,7 +3087,7 @@ var init_package = __esm(() => {
|
|
|
3087
3087
|
workspaces: [
|
|
3088
3088
|
"packages/*"
|
|
3089
3089
|
],
|
|
3090
|
-
version: "0.1.
|
|
3090
|
+
version: "0.1.1",
|
|
3091
3091
|
description: "Batteries-included agent harness on top of GPT Codex + OMX",
|
|
3092
3092
|
type: "module",
|
|
3093
3093
|
bin: {
|
|
@@ -25551,7 +25551,9 @@ var en_default = {
|
|
|
25551
25551
|
rtkMissing: "[RTK] RTK is not installed. Attempting installation...",
|
|
25552
25552
|
rtkInstalled: "[RTK] ✓ RTK installed — 60-90% token savings activated",
|
|
25553
25553
|
codexMissing: "[Codex] Codex CLI is not installed. Attempting installation...",
|
|
25554
|
-
codexInstalled: "[Codex] ✓ Codex CLI installed"
|
|
25554
|
+
codexInstalled: "[Codex] ✓ Codex CLI installed",
|
|
25555
|
+
omxMissing: "[OMX] oh-my-codex is not installed. Attempting installation...",
|
|
25556
|
+
omxInstalled: "[OMX] ✓ oh-my-codex installed"
|
|
25555
25557
|
},
|
|
25556
25558
|
list: {
|
|
25557
25559
|
description: "List installed components",
|
|
@@ -25729,7 +25731,11 @@ var en_default = {
|
|
|
25729
25731
|
codex_installing: "Installing Codex CLI...",
|
|
25730
25732
|
codex_success: "Codex CLI installed successfully",
|
|
25731
25733
|
codex_already: "Codex CLI already installed",
|
|
25732
|
-
codex_install_failed: "Codex CLI installation failed"
|
|
25734
|
+
codex_install_failed: "Codex CLI installation failed",
|
|
25735
|
+
omx_installing: "Installing oh-my-codex...",
|
|
25736
|
+
omx_success: "oh-my-codex installed successfully",
|
|
25737
|
+
omx_already: "oh-my-codex already installed",
|
|
25738
|
+
omx_install_failed: "oh-my-codex installation failed"
|
|
25733
25739
|
},
|
|
25734
25740
|
init: {
|
|
25735
25741
|
description: "Initialize oh-my-customcodex in the current directory",
|
|
@@ -25969,7 +25975,9 @@ var ko_default = {
|
|
|
25969
25975
|
rtkMissing: "[RTK] RTK가 설치되지 않았습니다. 설치를 시도합니다...",
|
|
25970
25976
|
rtkInstalled: "[RTK] ✓ RTK 설치 완료 — 토큰 60-90% 절감 활성화",
|
|
25971
25977
|
codexMissing: "[Codex] Codex CLI가 설치되지 않았습니다. 설치를 시도합니다...",
|
|
25972
|
-
codexInstalled: "[Codex] ✓ Codex CLI 설치 완료"
|
|
25978
|
+
codexInstalled: "[Codex] ✓ Codex CLI 설치 완료",
|
|
25979
|
+
omxMissing: "[OMX] oh-my-codex가 설치되지 않았습니다. 설치를 시도합니다...",
|
|
25980
|
+
omxInstalled: "[OMX] ✓ oh-my-codex 설치 완료"
|
|
25973
25981
|
},
|
|
25974
25982
|
list: {
|
|
25975
25983
|
description: "설치된 컴포넌트 목록 표시",
|
|
@@ -26147,7 +26155,11 @@ var ko_default = {
|
|
|
26147
26155
|
codex_installing: "Codex CLI 설치 중...",
|
|
26148
26156
|
codex_success: "Codex CLI 설치 완료",
|
|
26149
26157
|
codex_already: "Codex CLI 이미 설치됨",
|
|
26150
|
-
codex_install_failed: "Codex CLI 설치 실패"
|
|
26158
|
+
codex_install_failed: "Codex CLI 설치 실패",
|
|
26159
|
+
omx_installing: "oh-my-codex 설치 중...",
|
|
26160
|
+
omx_success: "oh-my-codex 설치 완료",
|
|
26161
|
+
omx_already: "oh-my-codex 이미 설치됨",
|
|
26162
|
+
omx_install_failed: "oh-my-codex 설치 실패"
|
|
26151
26163
|
},
|
|
26152
26164
|
init: {
|
|
26153
26165
|
description: "현재 디렉토리에 oh-my-customcodex 초기화",
|
|
@@ -26904,7 +26916,7 @@ async function checkFrameworkVersion(targetDir, latestVersion) {
|
|
|
26904
26916
|
init_layout();
|
|
26905
26917
|
init_lockfile();
|
|
26906
26918
|
|
|
26907
|
-
// src/core/
|
|
26919
|
+
// src/core/omx-installer.ts
|
|
26908
26920
|
init_logger();
|
|
26909
26921
|
import { execSync as execSync4 } from "node:child_process";
|
|
26910
26922
|
import { platform as platform2 } from "node:os";
|
|
@@ -26912,7 +26924,61 @@ var defaultDeps2 = {
|
|
|
26912
26924
|
exec: execSync4,
|
|
26913
26925
|
getPlatform: platform2
|
|
26914
26926
|
};
|
|
26915
|
-
function
|
|
26927
|
+
function isOmxInstalled(deps = defaultDeps2) {
|
|
26928
|
+
try {
|
|
26929
|
+
deps.exec("which omx", { stdio: "pipe", timeout: 3000 });
|
|
26930
|
+
return true;
|
|
26931
|
+
} catch {
|
|
26932
|
+
return false;
|
|
26933
|
+
}
|
|
26934
|
+
}
|
|
26935
|
+
function getOmxVersion(deps = defaultDeps2) {
|
|
26936
|
+
try {
|
|
26937
|
+
return deps.exec("omx --version", {
|
|
26938
|
+
encoding: "utf-8",
|
|
26939
|
+
stdio: "pipe",
|
|
26940
|
+
timeout: 3000
|
|
26941
|
+
}).trim();
|
|
26942
|
+
} catch {
|
|
26943
|
+
return null;
|
|
26944
|
+
}
|
|
26945
|
+
}
|
|
26946
|
+
function installOmx(deps = defaultDeps2) {
|
|
26947
|
+
if (process.env.CI || false || false) {
|
|
26948
|
+
return false;
|
|
26949
|
+
}
|
|
26950
|
+
if (isOmxInstalled(deps)) {
|
|
26951
|
+
info("install.omx_already");
|
|
26952
|
+
return true;
|
|
26953
|
+
}
|
|
26954
|
+
const os = deps.getPlatform();
|
|
26955
|
+
if (!["darwin", "linux", "win32"].includes(os)) {
|
|
26956
|
+
warn("install.omx_install_failed", { error: `Unsupported OS: ${os}` });
|
|
26957
|
+
return false;
|
|
26958
|
+
}
|
|
26959
|
+
try {
|
|
26960
|
+
info("install.omx_installing");
|
|
26961
|
+
deps.exec("npm install -g oh-my-codex", {
|
|
26962
|
+
stdio: "inherit",
|
|
26963
|
+
timeout: 120000
|
|
26964
|
+
});
|
|
26965
|
+
return isOmxInstalled(deps);
|
|
26966
|
+
} catch (err) {
|
|
26967
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
26968
|
+
warn("install.omx_install_failed", { error: message });
|
|
26969
|
+
return false;
|
|
26970
|
+
}
|
|
26971
|
+
}
|
|
26972
|
+
|
|
26973
|
+
// src/core/rtk-installer.ts
|
|
26974
|
+
init_logger();
|
|
26975
|
+
import { execSync as execSync5 } from "node:child_process";
|
|
26976
|
+
import { platform as platform3 } from "node:os";
|
|
26977
|
+
var defaultDeps3 = {
|
|
26978
|
+
exec: execSync5,
|
|
26979
|
+
getPlatform: platform3
|
|
26980
|
+
};
|
|
26981
|
+
function isRtkInstalled(deps = defaultDeps3) {
|
|
26916
26982
|
try {
|
|
26917
26983
|
deps.exec("which rtk", { stdio: "pipe", timeout: 3000 });
|
|
26918
26984
|
return true;
|
|
@@ -26920,14 +26986,14 @@ function isRtkInstalled(deps = defaultDeps2) {
|
|
|
26920
26986
|
return false;
|
|
26921
26987
|
}
|
|
26922
26988
|
}
|
|
26923
|
-
function getRtkVersion(deps =
|
|
26989
|
+
function getRtkVersion(deps = defaultDeps3) {
|
|
26924
26990
|
try {
|
|
26925
26991
|
return deps.exec("rtk --version", { encoding: "utf-8", stdio: "pipe", timeout: 3000 }).trim();
|
|
26926
26992
|
} catch {
|
|
26927
26993
|
return null;
|
|
26928
26994
|
}
|
|
26929
26995
|
}
|
|
26930
|
-
function installRtk(deps =
|
|
26996
|
+
function installRtk(deps = defaultDeps3) {
|
|
26931
26997
|
if (process.env.CI || false || false) {
|
|
26932
26998
|
return false;
|
|
26933
26999
|
}
|
|
@@ -27304,6 +27370,23 @@ async function checkCodex() {
|
|
|
27304
27370
|
fixable: false
|
|
27305
27371
|
};
|
|
27306
27372
|
}
|
|
27373
|
+
async function checkOmx() {
|
|
27374
|
+
if (!isOmxInstalled()) {
|
|
27375
|
+
return {
|
|
27376
|
+
name: "OMX",
|
|
27377
|
+
status: "warn",
|
|
27378
|
+
message: "OMX not installed — install manually: npm install -g oh-my-codex",
|
|
27379
|
+
fixable: true
|
|
27380
|
+
};
|
|
27381
|
+
}
|
|
27382
|
+
const version = getOmxVersion();
|
|
27383
|
+
return {
|
|
27384
|
+
name: "OMX",
|
|
27385
|
+
status: "pass",
|
|
27386
|
+
message: `OMX OK (${version ?? "unknown version"})`,
|
|
27387
|
+
fixable: false
|
|
27388
|
+
};
|
|
27389
|
+
}
|
|
27307
27390
|
async function checkContexts(targetDir, rootDir = ".codex") {
|
|
27308
27391
|
const contextsDir = path.join(targetDir, rootDir, "contexts");
|
|
27309
27392
|
const exists2 = await isDirectory(contextsDir);
|
|
@@ -27408,7 +27491,8 @@ async function fixSingleIssue(check, targetDir, rootDir = ".codex") {
|
|
|
27408
27491
|
return fixedCount > 0;
|
|
27409
27492
|
},
|
|
27410
27493
|
RTK: async () => Promise.resolve(installRtk()),
|
|
27411
|
-
Codex: async () => Promise.resolve(installCodex())
|
|
27494
|
+
Codex: async () => Promise.resolve(installCodex()),
|
|
27495
|
+
OMX: async () => Promise.resolve(installOmx())
|
|
27412
27496
|
};
|
|
27413
27497
|
const fixer = fixMap[check.name];
|
|
27414
27498
|
return fixer ? fixer() : false;
|
|
@@ -27558,7 +27642,8 @@ async function runAllChecks(targetDir, layout, packageVersion, includeUpdates) {
|
|
|
27558
27642
|
checkContexts(targetDir, layout.rootDir),
|
|
27559
27643
|
checkCustomComponents(targetDir, layout.rootDir),
|
|
27560
27644
|
checkRtk(),
|
|
27561
|
-
checkCodex()
|
|
27645
|
+
checkCodex(),
|
|
27646
|
+
checkOmx()
|
|
27562
27647
|
]);
|
|
27563
27648
|
const frameworkCheck = await checkFrameworkDrift(targetDir, packageVersion);
|
|
27564
27649
|
const checksWithFramework = frameworkCheck ? [...baseChecks, frameworkCheck] : baseChecks;
|
|
@@ -28239,6 +28324,19 @@ function installCodexIfNeeded(result) {
|
|
|
28239
28324
|
info("install.codex_already");
|
|
28240
28325
|
}
|
|
28241
28326
|
}
|
|
28327
|
+
function installOmxIfNeeded(result) {
|
|
28328
|
+
if (!isOmxInstalled()) {
|
|
28329
|
+
info("install.omx_installing");
|
|
28330
|
+
const omxInstalled = installOmx();
|
|
28331
|
+
if (omxInstalled) {
|
|
28332
|
+
info("install.omx_success");
|
|
28333
|
+
} else {
|
|
28334
|
+
result.warnings.push("OMX installation failed — install manually: npm install -g oh-my-codex");
|
|
28335
|
+
}
|
|
28336
|
+
} else {
|
|
28337
|
+
info("install.omx_already");
|
|
28338
|
+
}
|
|
28339
|
+
}
|
|
28242
28340
|
async function install(options) {
|
|
28243
28341
|
const result = createInstallResult(options.targetDir);
|
|
28244
28342
|
try {
|
|
@@ -28278,6 +28376,7 @@ async function install(options) {
|
|
|
28278
28376
|
}
|
|
28279
28377
|
installRtkIfNeeded(result);
|
|
28280
28378
|
installCodexIfNeeded(result);
|
|
28379
|
+
installOmxIfNeeded(result);
|
|
28281
28380
|
result.success = true;
|
|
28282
28381
|
success("install.success");
|
|
28283
28382
|
} catch (err) {
|
|
@@ -28466,7 +28565,7 @@ init_layout();
|
|
|
28466
28565
|
init_fs();
|
|
28467
28566
|
init_logger();
|
|
28468
28567
|
init_layout();
|
|
28469
|
-
import { execSync as
|
|
28568
|
+
import { execSync as execSync6 } from "node:child_process";
|
|
28470
28569
|
import { writeFile as writeFile2 } from "node:fs/promises";
|
|
28471
28570
|
import { join as join8 } from "node:path";
|
|
28472
28571
|
async function generateMCPConfig(targetDir) {
|
|
@@ -28478,15 +28577,15 @@ async function generateMCPConfig(targetDir) {
|
|
|
28478
28577
|
return;
|
|
28479
28578
|
}
|
|
28480
28579
|
try {
|
|
28481
|
-
|
|
28580
|
+
execSync6("uv --version", { stdio: "pipe" });
|
|
28482
28581
|
} catch {
|
|
28483
28582
|
warn("uv (Python package manager) not found. Install it with: curl -LsSf https://astral.sh/uv/install.sh | sh");
|
|
28484
28583
|
warn("Skipping ontology-rag MCP configuration. You can set it up manually later.");
|
|
28485
28584
|
return;
|
|
28486
28585
|
}
|
|
28487
28586
|
try {
|
|
28488
|
-
|
|
28489
|
-
|
|
28587
|
+
execSync6("uv venv .venv", { cwd: targetDir, stdio: "pipe" });
|
|
28588
|
+
execSync6('uv pip install "ontology-rag @ git+https://github.com/baekenough/oh-my-customcodex.git#subdirectory=packages/ontology-rag"', { cwd: targetDir, stdio: "pipe" });
|
|
28490
28589
|
} catch (error2) {
|
|
28491
28590
|
const msg = error2 instanceof Error ? error2.message : String(error2);
|
|
28492
28591
|
warn(`Failed to setup ontology-rag: ${msg}`);
|
|
@@ -28529,7 +28628,7 @@ async function generateMCPConfig(targetDir) {
|
|
|
28529
28628
|
}
|
|
28530
28629
|
async function checkUvAvailable() {
|
|
28531
28630
|
try {
|
|
28532
|
-
|
|
28631
|
+
execSync6("uv --version", { stdio: "pipe" });
|
|
28533
28632
|
return true;
|
|
28534
28633
|
} catch {
|
|
28535
28634
|
return false;
|
|
@@ -31262,6 +31361,16 @@ function checkAndInstallCodexAfterUpdate() {
|
|
|
31262
31361
|
}
|
|
31263
31362
|
}
|
|
31264
31363
|
}
|
|
31364
|
+
function checkAndInstallOmxAfterUpdate() {
|
|
31365
|
+
if (!isOmxInstalled()) {
|
|
31366
|
+
warn("update.omx_missing");
|
|
31367
|
+
console.log(i18n.t("cli.update.omxMissing"));
|
|
31368
|
+
const omxInstalled = installOmx();
|
|
31369
|
+
if (omxInstalled) {
|
|
31370
|
+
console.log(i18n.t("cli.update.omxInstalled"));
|
|
31371
|
+
}
|
|
31372
|
+
}
|
|
31373
|
+
}
|
|
31265
31374
|
async function update(options) {
|
|
31266
31375
|
const result = createUpdateResult();
|
|
31267
31376
|
try {
|
|
@@ -31296,6 +31405,7 @@ async function update(options) {
|
|
|
31296
31405
|
await regenerateLockfile(options.targetDir, result);
|
|
31297
31406
|
checkAndInstallRtkAfterUpdate();
|
|
31298
31407
|
checkAndInstallCodexAfterUpdate();
|
|
31408
|
+
checkAndInstallOmxAfterUpdate();
|
|
31299
31409
|
if (result.success && !options.dryRun) {
|
|
31300
31410
|
await updateProjectRegistry(options.targetDir, result.newVersion);
|
|
31301
31411
|
}
|
package/dist/index.js
CHANGED
|
@@ -1561,7 +1561,7 @@ async function cleanupPreservation(tempDir) {
|
|
|
1561
1561
|
init_layout();
|
|
1562
1562
|
init_lockfile();
|
|
1563
1563
|
|
|
1564
|
-
// src/core/
|
|
1564
|
+
// src/core/omx-installer.ts
|
|
1565
1565
|
init_logger();
|
|
1566
1566
|
import { execSync as execSync2 } from "node:child_process";
|
|
1567
1567
|
import { platform as platform2 } from "node:os";
|
|
@@ -1569,7 +1569,50 @@ var defaultDeps2 = {
|
|
|
1569
1569
|
exec: execSync2,
|
|
1570
1570
|
getPlatform: platform2
|
|
1571
1571
|
};
|
|
1572
|
-
function
|
|
1572
|
+
function isOmxInstalled(deps = defaultDeps2) {
|
|
1573
|
+
try {
|
|
1574
|
+
deps.exec("which omx", { stdio: "pipe", timeout: 3000 });
|
|
1575
|
+
return true;
|
|
1576
|
+
} catch {
|
|
1577
|
+
return false;
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1580
|
+
function installOmx(deps = defaultDeps2) {
|
|
1581
|
+
if (process.env.CI || false || false) {
|
|
1582
|
+
return false;
|
|
1583
|
+
}
|
|
1584
|
+
if (isOmxInstalled(deps)) {
|
|
1585
|
+
info("install.omx_already");
|
|
1586
|
+
return true;
|
|
1587
|
+
}
|
|
1588
|
+
const os = deps.getPlatform();
|
|
1589
|
+
if (!["darwin", "linux", "win32"].includes(os)) {
|
|
1590
|
+
warn("install.omx_install_failed", { error: `Unsupported OS: ${os}` });
|
|
1591
|
+
return false;
|
|
1592
|
+
}
|
|
1593
|
+
try {
|
|
1594
|
+
info("install.omx_installing");
|
|
1595
|
+
deps.exec("npm install -g oh-my-codex", {
|
|
1596
|
+
stdio: "inherit",
|
|
1597
|
+
timeout: 120000
|
|
1598
|
+
});
|
|
1599
|
+
return isOmxInstalled(deps);
|
|
1600
|
+
} catch (err) {
|
|
1601
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1602
|
+
warn("install.omx_install_failed", { error: message });
|
|
1603
|
+
return false;
|
|
1604
|
+
}
|
|
1605
|
+
}
|
|
1606
|
+
|
|
1607
|
+
// src/core/rtk-installer.ts
|
|
1608
|
+
init_logger();
|
|
1609
|
+
import { execSync as execSync3 } from "node:child_process";
|
|
1610
|
+
import { platform as platform3 } from "node:os";
|
|
1611
|
+
var defaultDeps3 = {
|
|
1612
|
+
exec: execSync3,
|
|
1613
|
+
getPlatform: platform3
|
|
1614
|
+
};
|
|
1615
|
+
function isRtkInstalled(deps = defaultDeps3) {
|
|
1573
1616
|
try {
|
|
1574
1617
|
deps.exec("which rtk", { stdio: "pipe", timeout: 3000 });
|
|
1575
1618
|
return true;
|
|
@@ -1577,7 +1620,7 @@ function isRtkInstalled(deps = defaultDeps2) {
|
|
|
1577
1620
|
return false;
|
|
1578
1621
|
}
|
|
1579
1622
|
}
|
|
1580
|
-
function installRtk(deps =
|
|
1623
|
+
function installRtk(deps = defaultDeps3) {
|
|
1581
1624
|
if (process.env.CI || false || false) {
|
|
1582
1625
|
return false;
|
|
1583
1626
|
}
|
|
@@ -1824,6 +1867,19 @@ function installCodexIfNeeded(result) {
|
|
|
1824
1867
|
info("install.codex_already");
|
|
1825
1868
|
}
|
|
1826
1869
|
}
|
|
1870
|
+
function installOmxIfNeeded(result) {
|
|
1871
|
+
if (!isOmxInstalled()) {
|
|
1872
|
+
info("install.omx_installing");
|
|
1873
|
+
const omxInstalled = installOmx();
|
|
1874
|
+
if (omxInstalled) {
|
|
1875
|
+
info("install.omx_success");
|
|
1876
|
+
} else {
|
|
1877
|
+
result.warnings.push("OMX installation failed — install manually: npm install -g oh-my-codex");
|
|
1878
|
+
}
|
|
1879
|
+
} else {
|
|
1880
|
+
info("install.omx_already");
|
|
1881
|
+
}
|
|
1882
|
+
}
|
|
1827
1883
|
async function install(options) {
|
|
1828
1884
|
const result = createInstallResult(options.targetDir);
|
|
1829
1885
|
try {
|
|
@@ -1863,6 +1919,7 @@ async function install(options) {
|
|
|
1863
1919
|
}
|
|
1864
1920
|
installRtkIfNeeded(result);
|
|
1865
1921
|
installCodexIfNeeded(result);
|
|
1922
|
+
installOmxIfNeeded(result);
|
|
1866
1923
|
result.success = true;
|
|
1867
1924
|
success("install.success");
|
|
1868
1925
|
} catch (err) {
|
|
@@ -2116,7 +2173,7 @@ var package_default = {
|
|
|
2116
2173
|
workspaces: [
|
|
2117
2174
|
"packages/*"
|
|
2118
2175
|
],
|
|
2119
|
-
version: "0.1.
|
|
2176
|
+
version: "0.1.1",
|
|
2120
2177
|
description: "Batteries-included agent harness on top of GPT Codex + OMX",
|
|
2121
2178
|
type: "module",
|
|
2122
2179
|
bin: {
|
|
@@ -5008,6 +5065,16 @@ function checkAndInstallCodexAfterUpdate() {
|
|
|
5008
5065
|
}
|
|
5009
5066
|
}
|
|
5010
5067
|
}
|
|
5068
|
+
function checkAndInstallOmxAfterUpdate() {
|
|
5069
|
+
if (!isOmxInstalled()) {
|
|
5070
|
+
warn("update.omx_missing");
|
|
5071
|
+
console.log(i18n.t("cli.update.omxMissing"));
|
|
5072
|
+
const omxInstalled = installOmx();
|
|
5073
|
+
if (omxInstalled) {
|
|
5074
|
+
console.log(i18n.t("cli.update.omxInstalled"));
|
|
5075
|
+
}
|
|
5076
|
+
}
|
|
5077
|
+
}
|
|
5011
5078
|
async function update(options) {
|
|
5012
5079
|
const result = createUpdateResult();
|
|
5013
5080
|
try {
|
|
@@ -5042,6 +5109,7 @@ async function update(options) {
|
|
|
5042
5109
|
await regenerateLockfile(options.targetDir, result);
|
|
5043
5110
|
checkAndInstallRtkAfterUpdate();
|
|
5044
5111
|
checkAndInstallCodexAfterUpdate();
|
|
5112
|
+
checkAndInstallOmxAfterUpdate();
|
|
5045
5113
|
if (result.success && !options.dryRun) {
|
|
5046
5114
|
await updateProjectRegistry(options.targetDir, result.newVersion);
|
|
5047
5115
|
}
|
package/package.json
CHANGED
package/templates/manifest.json
CHANGED