oh-my-customcodex 0.2.1 → 0.3.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/README.md +1 -1
- package/dist/cli/index.js +226 -87
- package/dist/index.js +39 -4
- package/package.json +4 -2
- package/templates/CLAUDE.md +3 -2
- package/templates/guides/browser-automation/README.md +3 -3
- package/templates/index.yaml +5 -4
- package/templates/manifest.json +4 -4
- package/templates/workflows/auto-dev.yaml +23 -2
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@ oh-my-customcodex is built on two ideas:
|
|
|
29
29
|
|
|
30
30
|
| Compile Concept | oh-my-customcodex |
|
|
31
31
|
|----------------|-----------------|
|
|
32
|
-
| Source code | `.
|
|
32
|
+
| Source code | `.agents/skills/` — reusable knowledge and workflows |
|
|
33
33
|
| Build artifacts | `.codex/agents/` — executable specialists assembled from skills |
|
|
34
34
|
| Compiler | `mgr-sauron` (R017) — structural verification and integrity |
|
|
35
35
|
| Spec | `.codex/rules/` — constraints and build rules |
|
package/dist/cli/index.js
CHANGED
|
@@ -2653,6 +2653,9 @@ function getComponentPath(component, provider = "codex") {
|
|
|
2653
2653
|
if (component === "guides") {
|
|
2654
2654
|
return "guides";
|
|
2655
2655
|
}
|
|
2656
|
+
if (provider === "codex" && component === "skills") {
|
|
2657
|
+
return ".agents/skills";
|
|
2658
|
+
}
|
|
2656
2659
|
return `${layout.rootDir}/${component}`;
|
|
2657
2660
|
}
|
|
2658
2661
|
function getTemplateComponentPath(component, provider = "codex") {
|
|
@@ -2681,8 +2684,9 @@ var init_layout = __esm(() => {
|
|
|
2681
2684
|
".codex/hooks",
|
|
2682
2685
|
".codex/contexts",
|
|
2683
2686
|
".codex/agents",
|
|
2684
|
-
".codex/skills",
|
|
2685
2687
|
".codex/ontology",
|
|
2688
|
+
".agents",
|
|
2689
|
+
".agents/skills",
|
|
2686
2690
|
"guides"
|
|
2687
2691
|
]
|
|
2688
2692
|
};
|
|
@@ -3087,12 +3091,14 @@ var init_package = __esm(() => {
|
|
|
3087
3091
|
workspaces: [
|
|
3088
3092
|
"packages/*"
|
|
3089
3093
|
],
|
|
3090
|
-
version: "0.
|
|
3094
|
+
version: "0.3.1",
|
|
3091
3095
|
description: "Batteries-included agent harness on top of GPT Codex + OMX",
|
|
3092
3096
|
type: "module",
|
|
3093
3097
|
bin: {
|
|
3094
3098
|
omcodex: "./dist/cli/index.js",
|
|
3095
|
-
omcustom: "./dist/cli/index.js"
|
|
3099
|
+
omcustom: "./dist/cli/index.js",
|
|
3100
|
+
omcustomx: "./dist/cli/index.js",
|
|
3101
|
+
omcustomcodex: "./dist/cli/index.js"
|
|
3096
3102
|
},
|
|
3097
3103
|
main: "./dist/index.js",
|
|
3098
3104
|
types: "./dist/index.d.ts",
|
|
@@ -3173,6 +3179,40 @@ var init_package = __esm(() => {
|
|
|
3173
3179
|
};
|
|
3174
3180
|
});
|
|
3175
3181
|
|
|
3182
|
+
// src/utils/cli-command-name.ts
|
|
3183
|
+
import { basename as basename2 } from "node:path";
|
|
3184
|
+
function normalizeCliCommandName(commandName) {
|
|
3185
|
+
const normalized = commandName?.trim().toLowerCase().replace(WINDOWS_SCRIPT_EXTENSIONS, "");
|
|
3186
|
+
return normalized && KNOWN_CLI_COMMANDS.has(normalized) ? normalized : DEFAULT_CLI_COMMAND;
|
|
3187
|
+
}
|
|
3188
|
+
function detectCliCommandName(argv = process.argv) {
|
|
3189
|
+
const invokedPath = argv[1];
|
|
3190
|
+
if (!invokedPath) {
|
|
3191
|
+
return DEFAULT_CLI_COMMAND;
|
|
3192
|
+
}
|
|
3193
|
+
const normalizedPath = invokedPath.replace(/\\/g, "/");
|
|
3194
|
+
return normalizeCliCommandName(basename2(normalizedPath));
|
|
3195
|
+
}
|
|
3196
|
+
function setActiveCliCommandName(commandName) {
|
|
3197
|
+
activeCliCommandName = normalizeCliCommandName(commandName);
|
|
3198
|
+
}
|
|
3199
|
+
function getActiveCliCommandName() {
|
|
3200
|
+
return activeCliCommandName;
|
|
3201
|
+
}
|
|
3202
|
+
function rewriteCliCommandReferences(text, commandName = getActiveCliCommandName()) {
|
|
3203
|
+
const normalizedCommandName = normalizeCliCommandName(commandName);
|
|
3204
|
+
if (normalizedCommandName === DEFAULT_CLI_COMMAND) {
|
|
3205
|
+
return text;
|
|
3206
|
+
}
|
|
3207
|
+
return text.replace(/(^|[^A-Za-z0-9_.-])omcodex(?=$|[^A-Za-z0-9_.-])/g, (_match, prefix) => `${prefix}${normalizedCommandName}`);
|
|
3208
|
+
}
|
|
3209
|
+
var DEFAULT_CLI_COMMAND = "omcodex", KNOWN_CLI_COMMANDS, WINDOWS_SCRIPT_EXTENSIONS, activeCliCommandName;
|
|
3210
|
+
var init_cli_command_name = __esm(() => {
|
|
3211
|
+
KNOWN_CLI_COMMANDS = new Set([DEFAULT_CLI_COMMAND, "omcustom", "omcustomx", "omcustomcodex"]);
|
|
3212
|
+
WINDOWS_SCRIPT_EXTENSIONS = /\.(cmd|exe|ps1|bat)$/i;
|
|
3213
|
+
activeCliCommandName = DEFAULT_CLI_COMMAND;
|
|
3214
|
+
});
|
|
3215
|
+
|
|
3176
3216
|
// node_modules/.bun/yaml@2.8.2/node_modules/yaml/dist/nodes/identity.js
|
|
3177
3217
|
var require_identity = __commonJS((exports) => {
|
|
3178
3218
|
var ALIAS = Symbol.for("yaml.alias");
|
|
@@ -10085,7 +10125,7 @@ __export(exports_projects, {
|
|
|
10085
10125
|
default: () => projects_default
|
|
10086
10126
|
});
|
|
10087
10127
|
import { homedir as homedir3 } from "node:os";
|
|
10088
|
-
import { basename as
|
|
10128
|
+
import { basename as basename5, join as join9, sep as sep3 } from "node:path";
|
|
10089
10129
|
async function readLockFile(projectDir) {
|
|
10090
10130
|
const fs2 = await import("node:fs/promises");
|
|
10091
10131
|
for (const lockFilePath of [
|
|
@@ -10145,7 +10185,7 @@ async function findProjects(options = {}) {
|
|
|
10145
10185
|
if (Object.keys(registry.projects).length === 0) {
|
|
10146
10186
|
const fallbackResults = await _findProjectsFromLockfiles(options, currentVersion);
|
|
10147
10187
|
if (fallbackResults.length === 0 && !options.paths) {
|
|
10148
|
-
process.stderr.write(" No projects in registry. Run `omcodex projects --migrate` to import existing projects.\n");
|
|
10188
|
+
process.stderr.write(rewriteCliCommandReferences(" No projects in registry. Run `omcodex projects --migrate` to import existing projects.\n"));
|
|
10149
10189
|
}
|
|
10150
10190
|
return fallbackResults;
|
|
10151
10191
|
}
|
|
@@ -10157,7 +10197,7 @@ async function findProjects(options = {}) {
|
|
|
10157
10197
|
if (!isUnderHome(projectPath, home))
|
|
10158
10198
|
continue;
|
|
10159
10199
|
results.push({
|
|
10160
|
-
name:
|
|
10200
|
+
name: basename5(projectPath),
|
|
10161
10201
|
path: projectPath,
|
|
10162
10202
|
version: entry.version || null,
|
|
10163
10203
|
installedAt: entry.installedAt || null,
|
|
@@ -10183,7 +10223,7 @@ async function _scanDirForLockfiles(dir2, depth, seen, results, home, currentVer
|
|
|
10183
10223
|
if (isUnderHome(dir2, home)) {
|
|
10184
10224
|
const version = lockFile.version || lockFile.templateVersion || null;
|
|
10185
10225
|
results.push({
|
|
10186
|
-
name:
|
|
10226
|
+
name: basename5(dir2),
|
|
10187
10227
|
path: dir2,
|
|
10188
10228
|
version,
|
|
10189
10229
|
installedAt: lockFile.installedAt || null,
|
|
@@ -10233,7 +10273,7 @@ function formatProjectsTable(projects, currentVersion) {
|
|
|
10233
10273
|
if (projects.length === 0) {
|
|
10234
10274
|
console.log(`
|
|
10235
10275
|
oh-my-customcodex가 적용된 프로젝트를 찾을 수 없습니다.`);
|
|
10236
|
-
console.log(" 레지스트리가 비어 있습니다. `omcodex projects --migrate`를 실행하여 기존 프로젝트를 가져오세요.\n");
|
|
10276
|
+
console.log(rewriteCliCommandReferences(" 레지스트리가 비어 있습니다. `omcodex projects --migrate`를 실행하여 기존 프로젝트를 가져오세요.\n"));
|
|
10237
10277
|
return;
|
|
10238
10278
|
}
|
|
10239
10279
|
const nameWidth = Math.max(20, ...projects.map((p) => p.name.length));
|
|
@@ -10340,6 +10380,7 @@ var SCAN_SKIP_DIRS2, projects_default;
|
|
|
10340
10380
|
var init_projects = __esm(() => {
|
|
10341
10381
|
init_package();
|
|
10342
10382
|
init_registry();
|
|
10383
|
+
init_cli_command_name();
|
|
10343
10384
|
init_fs();
|
|
10344
10385
|
SCAN_SKIP_DIRS2 = new Set(["node_modules", "dist", "build", ".git"]);
|
|
10345
10386
|
projects_default = projectsCommand;
|
|
@@ -22737,7 +22778,10 @@ var init_dist17 = __esm(() => {
|
|
|
22737
22778
|
});
|
|
22738
22779
|
|
|
22739
22780
|
// src/cli/index.ts
|
|
22781
|
+
import { realpathSync } from "node:fs";
|
|
22740
22782
|
import { createRequire as createRequire2 } from "node:module";
|
|
22783
|
+
import { resolve as resolve4 } from "node:path";
|
|
22784
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
22741
22785
|
|
|
22742
22786
|
// node_modules/.bun/commander@14.0.2/node_modules/commander/esm.mjs
|
|
22743
22787
|
var import__ = __toESM(require_commander(), 1);
|
|
@@ -25392,6 +25436,9 @@ var setDefaultNamespace = instance.setDefaultNamespace;
|
|
|
25392
25436
|
var hasLoadedNamespace = instance.hasLoadedNamespace;
|
|
25393
25437
|
var loadNamespaces = instance.loadNamespaces;
|
|
25394
25438
|
var loadLanguages = instance.loadLanguages;
|
|
25439
|
+
|
|
25440
|
+
// src/i18n/index.ts
|
|
25441
|
+
init_cli_command_name();
|
|
25395
25442
|
// src/i18n/locales/en.json
|
|
25396
25443
|
var en_default = {
|
|
25397
25444
|
common: {
|
|
@@ -26275,7 +26322,7 @@ async function initI18n(language) {
|
|
|
26275
26322
|
}
|
|
26276
26323
|
var i18n = {
|
|
26277
26324
|
t(key, options) {
|
|
26278
|
-
return instance.t(key, options);
|
|
26325
|
+
return rewriteCliCommandReferences(instance.t(key, options));
|
|
26279
26326
|
},
|
|
26280
26327
|
async changeLanguage(language) {
|
|
26281
26328
|
await instance.changeLanguage(language);
|
|
@@ -26606,6 +26653,9 @@ async function maybeHandleSelfUpdateForInit(options) {
|
|
|
26606
26653
|
runGlobalUpdate(packageName, latestVersion);
|
|
26607
26654
|
}
|
|
26608
26655
|
|
|
26656
|
+
// src/cli/index.ts
|
|
26657
|
+
init_cli_command_name();
|
|
26658
|
+
|
|
26609
26659
|
// src/cli/doctor.ts
|
|
26610
26660
|
import { constants, promises as fs, readFileSync as readFileSync2 } from "node:fs";
|
|
26611
26661
|
import path from "node:path";
|
|
@@ -27193,8 +27243,8 @@ async function checkAgents(targetDir, rootDir = ".codex") {
|
|
|
27193
27243
|
fixable: false
|
|
27194
27244
|
};
|
|
27195
27245
|
}
|
|
27196
|
-
async function checkSymlinks(targetDir,
|
|
27197
|
-
const skillsDir = path.join(targetDir,
|
|
27246
|
+
async function checkSymlinks(targetDir, _rootDir = ".codex") {
|
|
27247
|
+
const skillsDir = path.join(targetDir, getComponentPath("skills"));
|
|
27198
27248
|
const brokenSymlinks = [];
|
|
27199
27249
|
if (await isDirectory(skillsDir)) {
|
|
27200
27250
|
const skillSymlinks = await findRefsSymlinks(skillsDir);
|
|
@@ -27255,8 +27305,8 @@ async function checkIndexFiles(targetDir) {
|
|
|
27255
27305
|
fixable: false
|
|
27256
27306
|
};
|
|
27257
27307
|
}
|
|
27258
|
-
async function checkSkills(targetDir,
|
|
27259
|
-
const skillsDir = path.join(targetDir,
|
|
27308
|
+
async function checkSkills(targetDir, _rootDir = ".codex") {
|
|
27309
|
+
const skillsDir = path.join(targetDir, getComponentPath("skills"));
|
|
27260
27310
|
const exists2 = await isDirectory(skillsDir);
|
|
27261
27311
|
if (!exists2) {
|
|
27262
27312
|
return {
|
|
@@ -27479,7 +27529,7 @@ async function fixSingleIssue(check, targetDir, rootDir = ".codex") {
|
|
|
27479
27529
|
const fixMap = {
|
|
27480
27530
|
Rules: () => createMissingDirectory(path.join(targetDir, rootDir, "rules")),
|
|
27481
27531
|
Agents: () => createMissingDirectory(path.join(targetDir, rootDir, "agents")),
|
|
27482
|
-
Skills: () => createMissingDirectory(path.join(targetDir,
|
|
27532
|
+
Skills: () => createMissingDirectory(path.join(targetDir, getComponentPath("skills"))),
|
|
27483
27533
|
Guides: () => createMissingDirectory(path.join(targetDir, "guides")),
|
|
27484
27534
|
Hooks: () => createMissingDirectory(path.join(targetDir, rootDir, "hooks")),
|
|
27485
27535
|
Contexts: () => createMissingDirectory(path.join(targetDir, rootDir, "contexts")),
|
|
@@ -27719,19 +27769,19 @@ import {
|
|
|
27719
27769
|
rename,
|
|
27720
27770
|
stat as stat2
|
|
27721
27771
|
} from "node:fs/promises";
|
|
27722
|
-
import { basename as
|
|
27772
|
+
import { basename as basename4, join as join7 } from "node:path";
|
|
27723
27773
|
|
|
27724
27774
|
// src/core/file-preservation.ts
|
|
27725
27775
|
init_fs();
|
|
27726
27776
|
init_logger();
|
|
27727
|
-
import { basename as
|
|
27777
|
+
import { basename as basename3, join as join6 } from "node:path";
|
|
27728
27778
|
var DEFAULT_CRITICAL_FILES = ["settings.json", "settings.local.json"];
|
|
27729
27779
|
var DEFAULT_CRITICAL_DIRECTORIES = ["agent-memory", "agent-memory-local"];
|
|
27730
27780
|
var PROTECTED_FRAMEWORK_FILES = ["CLAUDE.md", "AGENTS.md"];
|
|
27731
27781
|
var PROTECTED_RULE_PATTERNS = ["rules/MUST-*.md"];
|
|
27732
27782
|
function isProtectedFile(relativePath) {
|
|
27733
|
-
const
|
|
27734
|
-
if (PROTECTED_FRAMEWORK_FILES.includes(
|
|
27783
|
+
const basename4 = relativePath.split("/").pop() ?? "";
|
|
27784
|
+
if (PROTECTED_FRAMEWORK_FILES.includes(basename4)) {
|
|
27735
27785
|
return true;
|
|
27736
27786
|
}
|
|
27737
27787
|
for (const pattern of PROTECTED_RULE_PATTERNS) {
|
|
@@ -27840,10 +27890,10 @@ async function mergeJsonFile(preservedPath, targetPath) {
|
|
|
27840
27890
|
const targetData = await readJsonFile(targetPath);
|
|
27841
27891
|
const merged = deepMerge(targetData, preservedData);
|
|
27842
27892
|
await writeJsonFile(targetPath, merged);
|
|
27843
|
-
debug("preserve.merged_json", { file:
|
|
27893
|
+
debug("preserve.merged_json", { file: basename3(targetPath) });
|
|
27844
27894
|
} else {
|
|
27845
27895
|
await copyFile(preservedPath, targetPath);
|
|
27846
|
-
debug("preserve.copied_json", { file:
|
|
27896
|
+
debug("preserve.copied_json", { file: basename3(targetPath) });
|
|
27847
27897
|
}
|
|
27848
27898
|
}
|
|
27849
27899
|
function deepMerge(target, source) {
|
|
@@ -28517,7 +28567,7 @@ async function installEntryDoc(targetDir, language, overwrite = false) {
|
|
|
28517
28567
|
return true;
|
|
28518
28568
|
}
|
|
28519
28569
|
async function backupExisting(sourcePath, backupDir) {
|
|
28520
|
-
const name =
|
|
28570
|
+
const name = basename4(sourcePath);
|
|
28521
28571
|
const backupPath = join7(backupDir, name);
|
|
28522
28572
|
await rename(sourcePath, backupPath);
|
|
28523
28573
|
return backupPath;
|
|
@@ -28525,6 +28575,9 @@ async function backupExisting(sourcePath, backupDir) {
|
|
|
28525
28575
|
async function checkExistingPaths(targetDir) {
|
|
28526
28576
|
const layout = getProviderLayout();
|
|
28527
28577
|
const pathsToCheck = [layout.entryFile, layout.rootDir, "guides"];
|
|
28578
|
+
if (layout.provider === "codex") {
|
|
28579
|
+
pathsToCheck.push(".agents");
|
|
28580
|
+
}
|
|
28528
28581
|
const existingPaths = [];
|
|
28529
28582
|
for (const relativePath of pathsToCheck) {
|
|
28530
28583
|
const fullPath = join7(targetDir, relativePath);
|
|
@@ -28649,51 +28702,101 @@ init_layout();
|
|
|
28649
28702
|
init_registry();
|
|
28650
28703
|
async function checkExistingInstallation(targetDir) {
|
|
28651
28704
|
const layout = getProviderLayout();
|
|
28652
|
-
const
|
|
28653
|
-
|
|
28705
|
+
const markers = [layout.entryFile, layout.rootDir];
|
|
28706
|
+
if (layout.provider === "codex") {
|
|
28707
|
+
markers.push(".agents");
|
|
28708
|
+
}
|
|
28709
|
+
for (const marker of markers) {
|
|
28710
|
+
if (await fileExists(join10(targetDir, marker))) {
|
|
28711
|
+
return true;
|
|
28712
|
+
}
|
|
28713
|
+
}
|
|
28714
|
+
return false;
|
|
28654
28715
|
}
|
|
28655
|
-
|
|
28716
|
+
function getSnapshotPaths(snapshotPath) {
|
|
28717
|
+
const layout = getProviderLayout();
|
|
28718
|
+
return {
|
|
28719
|
+
layout,
|
|
28720
|
+
snapshotRuntime: join10(snapshotPath, layout.rootDir),
|
|
28721
|
+
snapshotSkills: join10(snapshotPath, getComponentPath("skills")),
|
|
28722
|
+
snapshotGuides: join10(snapshotPath, "guides"),
|
|
28723
|
+
snapshotEntry: join10(snapshotPath, layout.entryFile)
|
|
28724
|
+
};
|
|
28725
|
+
}
|
|
28726
|
+
function validateSnapshot(snapshotPath) {
|
|
28656
28727
|
if (!existsSync2(snapshotPath)) {
|
|
28728
|
+
return { valid: false, error: `Snapshot path not found: ${snapshotPath}` };
|
|
28729
|
+
}
|
|
28730
|
+
const { layout, snapshotRuntime, snapshotSkills } = getSnapshotPaths(snapshotPath);
|
|
28731
|
+
if (!existsSync2(snapshotRuntime) && !existsSync2(snapshotSkills)) {
|
|
28657
28732
|
return {
|
|
28658
|
-
|
|
28659
|
-
|
|
28660
|
-
errors: [`Snapshot path not found: ${snapshotPath}`]
|
|
28733
|
+
valid: false,
|
|
28734
|
+
error: `Invalid snapshot: missing ${layout.rootDir}/ or ${getComponentPath("skills")} in ${snapshotPath}`
|
|
28661
28735
|
};
|
|
28662
28736
|
}
|
|
28663
|
-
|
|
28664
|
-
|
|
28665
|
-
|
|
28737
|
+
return { valid: true };
|
|
28738
|
+
}
|
|
28739
|
+
async function backupExistingInstallationForSnapshot(targetDir, snapshotPath) {
|
|
28740
|
+
const { layout } = getSnapshotPaths(snapshotPath);
|
|
28741
|
+
const exists2 = await checkExistingInstallation(targetDir);
|
|
28742
|
+
if (!exists2)
|
|
28743
|
+
return;
|
|
28744
|
+
console.log(i18n.t("cli.init.exists", { rootDir: layout.rootDir }));
|
|
28745
|
+
console.log(i18n.t("cli.init.backing_up"));
|
|
28746
|
+
const backupDir = join10(targetDir, `${layout.backupDirPrefix}${new Date().toISOString().replace(/[:.]/g, "-").slice(0, -1)}`);
|
|
28747
|
+
if (existsSync2(join10(targetDir, layout.rootDir))) {
|
|
28748
|
+
await cp(join10(targetDir, layout.rootDir), join10(backupDir, layout.rootDir), { recursive: true });
|
|
28749
|
+
}
|
|
28750
|
+
if (existsSync2(join10(targetDir, ".agents"))) {
|
|
28751
|
+
await cp(join10(targetDir, ".agents"), join10(backupDir, ".agents"), { recursive: true });
|
|
28752
|
+
}
|
|
28753
|
+
if (existsSync2(join10(targetDir, layout.entryFile))) {
|
|
28754
|
+
await copyFile2(join10(targetDir, layout.entryFile), join10(backupDir, layout.entryFile));
|
|
28755
|
+
}
|
|
28756
|
+
if (existsSync2(join10(targetDir, "guides"))) {
|
|
28757
|
+
await cp(join10(targetDir, "guides"), join10(backupDir, "guides"), { recursive: true });
|
|
28758
|
+
}
|
|
28759
|
+
console.log(` Backed up to: ${backupDir}`);
|
|
28760
|
+
}
|
|
28761
|
+
async function copySnapshotIntoTarget(targetDir, snapshotPath) {
|
|
28762
|
+
const { layout, snapshotRuntime, snapshotSkills, snapshotGuides, snapshotEntry } = getSnapshotPaths(snapshotPath);
|
|
28763
|
+
if (existsSync2(snapshotRuntime)) {
|
|
28764
|
+
await cp(snapshotRuntime, join10(targetDir, layout.rootDir), {
|
|
28765
|
+
recursive: true,
|
|
28766
|
+
force: true
|
|
28767
|
+
});
|
|
28768
|
+
}
|
|
28769
|
+
if (existsSync2(snapshotSkills)) {
|
|
28770
|
+
await cp(snapshotSkills, join10(targetDir, getComponentPath("skills")), {
|
|
28771
|
+
recursive: true,
|
|
28772
|
+
force: true
|
|
28773
|
+
});
|
|
28774
|
+
}
|
|
28775
|
+
if (existsSync2(snapshotGuides)) {
|
|
28776
|
+
await cp(snapshotGuides, join10(targetDir, "guides"), {
|
|
28777
|
+
recursive: true,
|
|
28778
|
+
force: true
|
|
28779
|
+
});
|
|
28780
|
+
}
|
|
28781
|
+
if (existsSync2(snapshotEntry)) {
|
|
28782
|
+
await copyFile2(snapshotEntry, join10(targetDir, layout.entryFile));
|
|
28783
|
+
}
|
|
28784
|
+
}
|
|
28785
|
+
async function installFromSnapshot(targetDir, snapshotPath, options) {
|
|
28786
|
+
const snapshotValidation = validateSnapshot(snapshotPath);
|
|
28787
|
+
if (!snapshotValidation.valid) {
|
|
28666
28788
|
return {
|
|
28667
28789
|
success: false,
|
|
28668
28790
|
message: i18n.t("cli.init.failed"),
|
|
28669
|
-
errors: [
|
|
28791
|
+
errors: [snapshotValidation.error]
|
|
28670
28792
|
};
|
|
28671
28793
|
}
|
|
28672
28794
|
console.log(`Installing from snapshot: ${snapshotPath}`);
|
|
28673
28795
|
try {
|
|
28674
|
-
|
|
28675
|
-
|
|
28676
|
-
console.log(i18n.t("cli.init.exists", { rootDir: layout.rootDir }));
|
|
28677
|
-
console.log(i18n.t("cli.init.backing_up"));
|
|
28678
|
-
const backupDir = join10(targetDir, `${layout.backupDirPrefix}${new Date().toISOString().replace(/[:.]/g, "-").slice(0, -1)}`);
|
|
28679
|
-
await cp(join10(targetDir, layout.rootDir), backupDir, { recursive: true });
|
|
28680
|
-
console.log(` Backed up to: ${backupDir}`);
|
|
28681
|
-
}
|
|
28682
|
-
await cp(snapshotClaude, join10(targetDir, layout.rootDir), {
|
|
28683
|
-
recursive: true,
|
|
28684
|
-
force: true
|
|
28685
|
-
});
|
|
28686
|
-
const snapshotGuides = join10(snapshotPath, "guides");
|
|
28687
|
-
if (existsSync2(snapshotGuides)) {
|
|
28688
|
-
await cp(snapshotGuides, join10(targetDir, "guides"), {
|
|
28689
|
-
recursive: true,
|
|
28690
|
-
force: true
|
|
28691
|
-
});
|
|
28692
|
-
}
|
|
28693
|
-
const snapshotEntry = join10(snapshotPath, layout.entryFile);
|
|
28694
|
-
if (existsSync2(snapshotEntry)) {
|
|
28695
|
-
await copyFile2(snapshotEntry, join10(targetDir, layout.entryFile));
|
|
28796
|
+
if (!options.force) {
|
|
28797
|
+
await backupExistingInstallationForSnapshot(targetDir, snapshotPath);
|
|
28696
28798
|
}
|
|
28799
|
+
await copySnapshotIntoTarget(targetDir, snapshotPath);
|
|
28697
28800
|
try {
|
|
28698
28801
|
const existing = await readLockFile(targetDir);
|
|
28699
28802
|
await writeLockFile(targetDir, package_default.version, existing);
|
|
@@ -29700,8 +29803,16 @@ async function runInitWizard(options) {
|
|
|
29700
29803
|
// src/cli/init.ts
|
|
29701
29804
|
async function checkExistingInstallation2(targetDir) {
|
|
29702
29805
|
const layout = getProviderLayout();
|
|
29703
|
-
const
|
|
29704
|
-
|
|
29806
|
+
const markers = [layout.entryFile, layout.rootDir];
|
|
29807
|
+
if (layout.provider === "codex") {
|
|
29808
|
+
markers.push(".agents");
|
|
29809
|
+
}
|
|
29810
|
+
for (const marker of markers) {
|
|
29811
|
+
if (await fileExists(join11(targetDir, marker))) {
|
|
29812
|
+
return true;
|
|
29813
|
+
}
|
|
29814
|
+
}
|
|
29815
|
+
return false;
|
|
29705
29816
|
}
|
|
29706
29817
|
var PROVIDER_SUBDIR_COMPONENTS = new Set([
|
|
29707
29818
|
"rules",
|
|
@@ -29712,13 +29823,8 @@ var PROVIDER_SUBDIR_COMPONENTS = new Set([
|
|
|
29712
29823
|
"ontology"
|
|
29713
29824
|
]);
|
|
29714
29825
|
function componentToPath(targetDir, component) {
|
|
29715
|
-
if (component === "entry-md") {
|
|
29716
|
-
|
|
29717
|
-
return join11(targetDir, layout.entryFile);
|
|
29718
|
-
}
|
|
29719
|
-
if (PROVIDER_SUBDIR_COMPONENTS.has(component)) {
|
|
29720
|
-
const layout = getProviderLayout();
|
|
29721
|
-
return join11(targetDir, layout.rootDir, component);
|
|
29826
|
+
if (component === "entry-md" || PROVIDER_SUBDIR_COMPONENTS.has(component)) {
|
|
29827
|
+
return join11(targetDir, getComponentPath(component));
|
|
29722
29828
|
}
|
|
29723
29829
|
return join11(targetDir, component);
|
|
29724
29830
|
}
|
|
@@ -29845,7 +29951,7 @@ async function initCommand(options) {
|
|
|
29845
29951
|
}
|
|
29846
29952
|
|
|
29847
29953
|
// src/cli/list.ts
|
|
29848
|
-
import { basename as
|
|
29954
|
+
import { basename as basename6, dirname as dirname3, join as join12, relative as relative3 } from "node:path";
|
|
29849
29955
|
init_layout();
|
|
29850
29956
|
init_fs();
|
|
29851
29957
|
var ALLOWED_TOP_LEVEL_KEYS = new Set(["name", "type", "description", "version", "category"]);
|
|
@@ -29893,7 +29999,7 @@ function parseYamlMetadata(content) {
|
|
|
29893
29999
|
return result;
|
|
29894
30000
|
}
|
|
29895
30001
|
function extractAgentTypeFromFilename(filename) {
|
|
29896
|
-
const name =
|
|
30002
|
+
const name = basename6(filename, ".md");
|
|
29897
30003
|
const prefixMap = {
|
|
29898
30004
|
lang: "language",
|
|
29899
30005
|
be: "backend",
|
|
@@ -29911,9 +30017,13 @@ function extractAgentTypeFromFilename(filename) {
|
|
|
29911
30017
|
return prefixMap[prefix] || "unknown";
|
|
29912
30018
|
}
|
|
29913
30019
|
function extractSkillCategoryFromPath(skillPath, baseDir, rootDir) {
|
|
29914
|
-
const
|
|
30020
|
+
const provider = rootDir === ".claude" ? "claude" : "codex";
|
|
30021
|
+
const relativePath = relative3(join12(baseDir, getComponentPath("skills", provider)), skillPath);
|
|
29915
30022
|
const parts = relativePath.split("/").filter(Boolean);
|
|
29916
|
-
|
|
30023
|
+
if (parts.length <= 1) {
|
|
30024
|
+
return "general";
|
|
30025
|
+
}
|
|
30026
|
+
return parts[0];
|
|
29917
30027
|
}
|
|
29918
30028
|
function extractGuideCategoryFromPath(guidePath, baseDir) {
|
|
29919
30029
|
const relativePath = relative3(join12(baseDir, "guides"), guidePath);
|
|
@@ -29921,7 +30031,7 @@ function extractGuideCategoryFromPath(guidePath, baseDir) {
|
|
|
29921
30031
|
return parts[0] || "unknown";
|
|
29922
30032
|
}
|
|
29923
30033
|
function extractRulePriorityFromFilename(filename) {
|
|
29924
|
-
const name =
|
|
30034
|
+
const name = basename6(filename, ".md");
|
|
29925
30035
|
const parts = name.split("-");
|
|
29926
30036
|
return parts[0] || "unknown";
|
|
29927
30037
|
}
|
|
@@ -30019,8 +30129,8 @@ async function getAgents(targetDir, rootDir = ".codex", config) {
|
|
|
30019
30129
|
const customAgentPaths = new Set(customComponents.filter((c) => c.type === "agent").map((c) => c.path));
|
|
30020
30130
|
const agentMdFiles = await listFiles(agentsDir, { recursive: false, pattern: "*.md" });
|
|
30021
30131
|
const agents = await Promise.all(agentMdFiles.map(async (agentMdPath) => {
|
|
30022
|
-
const filename =
|
|
30023
|
-
const name =
|
|
30132
|
+
const filename = basename6(agentMdPath);
|
|
30133
|
+
const name = basename6(filename, ".md");
|
|
30024
30134
|
const description = await tryExtractMarkdownDescription(agentMdPath);
|
|
30025
30135
|
const relativePath = relative3(targetDir, agentMdPath);
|
|
30026
30136
|
return {
|
|
@@ -30038,7 +30148,8 @@ async function getAgents(targetDir, rootDir = ".codex", config) {
|
|
|
30038
30148
|
}
|
|
30039
30149
|
}
|
|
30040
30150
|
async function getSkills(targetDir, rootDir = ".codex", config) {
|
|
30041
|
-
const
|
|
30151
|
+
const provider = rootDir === ".claude" ? "claude" : "codex";
|
|
30152
|
+
const skillsDir = join12(targetDir, getComponentPath("skills", provider));
|
|
30042
30153
|
if (!await fileExists(skillsDir))
|
|
30043
30154
|
return [];
|
|
30044
30155
|
try {
|
|
@@ -30052,7 +30163,7 @@ async function getSkills(targetDir, rootDir = ".codex", config) {
|
|
|
30052
30163
|
const { description, version } = await tryReadIndexYamlMetadata(indexYamlPath);
|
|
30053
30164
|
const relativePath = relative3(targetDir, skillDir);
|
|
30054
30165
|
return {
|
|
30055
|
-
name:
|
|
30166
|
+
name: basename6(skillDir),
|
|
30056
30167
|
type: "skill",
|
|
30057
30168
|
category: extractSkillCategoryFromPath(skillDir, targetDir, rootDir),
|
|
30058
30169
|
path: relativePath,
|
|
@@ -30079,7 +30190,7 @@ async function getGuides(targetDir, config) {
|
|
|
30079
30190
|
const description = await tryExtractMarkdownDescription(guideMdPath, { maxLength: 100 });
|
|
30080
30191
|
const relativePath = relative3(targetDir, guideMdPath);
|
|
30081
30192
|
return {
|
|
30082
|
-
name:
|
|
30193
|
+
name: basename6(guideMdPath, ".md"),
|
|
30083
30194
|
type: "guide",
|
|
30084
30195
|
category: extractGuideCategoryFromPath(guideMdPath, targetDir),
|
|
30085
30196
|
path: relativePath,
|
|
@@ -30103,13 +30214,13 @@ async function getRules(targetDir, rootDir = ".codex", config) {
|
|
|
30103
30214
|
const customRulePaths = new Set(customComponents.filter((c) => c.type === "rule").map((c) => c.path));
|
|
30104
30215
|
const ruleMdFiles = await listFiles(rulesDir, { recursive: false, pattern: "*.md" });
|
|
30105
30216
|
const rules = await Promise.all(ruleMdFiles.map(async (ruleMdPath) => {
|
|
30106
|
-
const filename =
|
|
30217
|
+
const filename = basename6(ruleMdPath);
|
|
30107
30218
|
const description = await tryExtractMarkdownDescription(ruleMdPath, {
|
|
30108
30219
|
cleanFormatting: true
|
|
30109
30220
|
});
|
|
30110
30221
|
const relativePath = relative3(targetDir, ruleMdPath);
|
|
30111
30222
|
return {
|
|
30112
|
-
name:
|
|
30223
|
+
name: basename6(ruleMdPath, ".md"),
|
|
30113
30224
|
type: extractRulePriorityFromFilename(filename),
|
|
30114
30225
|
path: relativePath,
|
|
30115
30226
|
description,
|
|
@@ -30175,7 +30286,7 @@ async function getHooks(targetDir, rootDir = ".codex") {
|
|
|
30175
30286
|
const hookYamls = await listFiles(hooksDir, { recursive: true, pattern: "*.yaml" });
|
|
30176
30287
|
const allFiles = [...hookFiles, ...hookConfigs, ...hookYamls];
|
|
30177
30288
|
return allFiles.map((hookPath) => ({
|
|
30178
|
-
name:
|
|
30289
|
+
name: basename6(hookPath),
|
|
30179
30290
|
type: "hook",
|
|
30180
30291
|
path: relative3(targetDir, hookPath)
|
|
30181
30292
|
})).sort((a, b) => a.name.localeCompare(b.name));
|
|
@@ -30195,7 +30306,7 @@ async function getContexts(targetDir, rootDir = ".codex") {
|
|
|
30195
30306
|
const ext = ctxPath.endsWith(".md") ? ".md" : ".yaml";
|
|
30196
30307
|
const description = ext === ".md" ? await tryExtractMarkdownDescription(ctxPath, { maxLength: 100 }) : undefined;
|
|
30197
30308
|
return {
|
|
30198
|
-
name:
|
|
30309
|
+
name: basename6(ctxPath, ext),
|
|
30199
30310
|
type: "context",
|
|
30200
30311
|
path: relative3(targetDir, ctxPath),
|
|
30201
30312
|
description
|
|
@@ -30883,6 +30994,7 @@ async function exportSnapshot(targetDir, outputPath) {
|
|
|
30883
30994
|
const detection = await detectProvider({ targetDir });
|
|
30884
30995
|
const layout = getProviderLayout(detection.provider);
|
|
30885
30996
|
const runtimeDir = join16(targetDir, layout.rootDir);
|
|
30997
|
+
const skillsDir = join16(targetDir, getComponentPath("skills", detection.provider));
|
|
30886
30998
|
const guidesDir = join16(targetDir, "guides");
|
|
30887
30999
|
if (!existsSync4(runtimeDir)) {
|
|
30888
31000
|
return { success: false, exportPath: outputPath, fileCount: 0 };
|
|
@@ -30893,6 +31005,12 @@ async function exportSnapshot(targetDir, outputPath) {
|
|
|
30893
31005
|
recursive: true,
|
|
30894
31006
|
filter: isExportable
|
|
30895
31007
|
});
|
|
31008
|
+
if (existsSync4(skillsDir)) {
|
|
31009
|
+
await cp2(skillsDir, join16(outputPath, getComponentPath("skills", detection.provider)), {
|
|
31010
|
+
recursive: true,
|
|
31011
|
+
filter: isExportable
|
|
31012
|
+
});
|
|
31013
|
+
}
|
|
30896
31014
|
if (existsSync4(guidesDir)) {
|
|
30897
31015
|
await cp2(guidesDir, join16(outputPath, "guides"), { recursive: true });
|
|
30898
31016
|
}
|
|
@@ -30905,6 +31023,7 @@ async function exportSnapshot(targetDir, outputPath) {
|
|
|
30905
31023
|
}
|
|
30906
31024
|
|
|
30907
31025
|
// src/cli/sync.ts
|
|
31026
|
+
init_cli_command_name();
|
|
30908
31027
|
async function runExport(targetDir, outputPath) {
|
|
30909
31028
|
const result = await exportSnapshot(targetDir, resolve3(outputPath));
|
|
30910
31029
|
const layout = getProviderLayout();
|
|
@@ -30915,7 +31034,7 @@ Export failed — no ${layout.rootDir}/ directory found in current project.`);
|
|
|
30915
31034
|
}
|
|
30916
31035
|
console.log(`
|
|
30917
31036
|
Snapshot exported: ${result.exportPath} (${result.fileCount} files)`);
|
|
30918
|
-
console.log(`Team members can install with: omcodex init --from-snapshot ${result.exportPath}`);
|
|
31037
|
+
console.log(rewriteCliCommandReferences(`Team members can install with: omcodex init --from-snapshot ${result.exportPath}`));
|
|
30919
31038
|
}
|
|
30920
31039
|
function printDriftDetails(result) {
|
|
30921
31040
|
if (result.unchanged > 0) {
|
|
@@ -30943,8 +31062,8 @@ function printDriftDetails(result) {
|
|
|
30943
31062
|
async function runCheck(targetDir, options) {
|
|
30944
31063
|
const result = await syncCheck(targetDir, { reference: options.reference });
|
|
30945
31064
|
if (!result.referenceVersion) {
|
|
30946
|
-
console.error(`
|
|
30947
|
-
No lockfile found. Run omcodex init first.`);
|
|
31065
|
+
console.error(rewriteCliCommandReferences(`
|
|
31066
|
+
No lockfile found. Run omcodex init first.`));
|
|
30948
31067
|
process.exit(1);
|
|
30949
31068
|
}
|
|
30950
31069
|
const label = options.reference ? `external snapshot at ${options.reference}` : `lockfile (v${result.referenceVersion})`;
|
|
@@ -31733,6 +31852,9 @@ function getComponentPath2(component) {
|
|
|
31733
31852
|
if (component === "guides") {
|
|
31734
31853
|
return "guides";
|
|
31735
31854
|
}
|
|
31855
|
+
if (layout.provider === "codex" && component === "skills") {
|
|
31856
|
+
return ".agents/skills";
|
|
31857
|
+
}
|
|
31736
31858
|
return `${layout.rootDir}/${component}`;
|
|
31737
31859
|
}
|
|
31738
31860
|
async function backupInstallation(targetDir) {
|
|
@@ -31742,6 +31864,9 @@ async function backupInstallation(targetDir) {
|
|
|
31742
31864
|
await ensureDirectory(backupDir);
|
|
31743
31865
|
const layout = getProviderLayout();
|
|
31744
31866
|
const dirsToBackup = [layout.rootDir, "guides"];
|
|
31867
|
+
if (layout.provider === "codex") {
|
|
31868
|
+
dirsToBackup.push(".agents");
|
|
31869
|
+
}
|
|
31745
31870
|
for (const dir2 of dirsToBackup) {
|
|
31746
31871
|
const srcPath = join17(targetDir, dir2);
|
|
31747
31872
|
if (await fileExists(srcPath)) {
|
|
@@ -32057,9 +32182,9 @@ async function webOpenCommand(options) {
|
|
|
32057
32182
|
// src/cli/index.ts
|
|
32058
32183
|
var require2 = createRequire2(import.meta.url);
|
|
32059
32184
|
var packageJson = require2("../../package.json");
|
|
32060
|
-
function createProgram() {
|
|
32185
|
+
function createProgram(commandName = getActiveCliCommandName()) {
|
|
32061
32186
|
const program2 = new Command;
|
|
32062
|
-
program2.name(
|
|
32187
|
+
program2.name(commandName).description(i18n.t("cli.description")).version(packageJson.version, "-v, --version", i18n.t("cli.versionOption")).option("--skip-version-check", "Skip CLI version pre-flight check");
|
|
32063
32188
|
program2.command("init").description(i18n.t("cli.init.description")).option("-l, --lang <language>", i18n.t("cli.init.langOption")).option("--domain <domain>", "Install only agents/skills for specific domain (backend, frontend, data-engineering, devops)").option("--yes", "Skip interactive wizard, use defaults").option("--from-snapshot <path>", "Install from a pre-configured team snapshot directory").action(async (options) => {
|
|
32064
32189
|
await initCommand(options);
|
|
32065
32190
|
});
|
|
@@ -32096,11 +32221,11 @@ function createProgram() {
|
|
|
32096
32221
|
web.action(async () => {
|
|
32097
32222
|
await webStatusCommand();
|
|
32098
32223
|
});
|
|
32099
|
-
program2.command("serve").description(
|
|
32224
|
+
program2.command("serve").description(`(Deprecated) Start the Web UI server — use \`${commandName} web start\` instead`).option("-p, --port <port>", i18n.t("cli.web.start.portOption"), "4321").option("--foreground", i18n.t("cli.web.start.foregroundOption")).action(async (options) => {
|
|
32100
32225
|
console.warn(i18n.t("cli.web.deprecated.serve"));
|
|
32101
32226
|
await serveCommand(options);
|
|
32102
32227
|
});
|
|
32103
|
-
program2.command("serve-stop").description(
|
|
32228
|
+
program2.command("serve-stop").description(`(Deprecated) Stop the Web UI server — use \`${commandName} web stop\` instead`).action(async () => {
|
|
32104
32229
|
console.warn(i18n.t("cli.web.deprecated.serveStop"));
|
|
32105
32230
|
await serveStopCommand();
|
|
32106
32231
|
});
|
|
@@ -32149,15 +32274,29 @@ function createProgram() {
|
|
|
32149
32274
|
return program2;
|
|
32150
32275
|
}
|
|
32151
32276
|
async function main() {
|
|
32277
|
+
setActiveCliCommandName(detectCliCommandName());
|
|
32152
32278
|
const lang = detectLanguage();
|
|
32153
32279
|
await initI18n(lang);
|
|
32154
32280
|
const program2 = createProgram();
|
|
32155
32281
|
await program2.parseAsync(process.argv);
|
|
32156
32282
|
}
|
|
32157
|
-
|
|
32158
|
-
|
|
32159
|
-
|
|
32160
|
-
|
|
32283
|
+
function isDirectExecution() {
|
|
32284
|
+
const argvPath = process.argv[1];
|
|
32285
|
+
if (!argvPath) {
|
|
32286
|
+
return false;
|
|
32287
|
+
}
|
|
32288
|
+
try {
|
|
32289
|
+
return realpathSync(argvPath) === realpathSync(fileURLToPath3(import.meta.url));
|
|
32290
|
+
} catch {
|
|
32291
|
+
return resolve4(argvPath) === resolve4(fileURLToPath3(import.meta.url));
|
|
32292
|
+
}
|
|
32293
|
+
}
|
|
32294
|
+
if (isDirectExecution()) {
|
|
32295
|
+
main().catch((error2) => {
|
|
32296
|
+
console.error(i18n.t("cli.error.unexpected"), error2);
|
|
32297
|
+
process.exit(1);
|
|
32298
|
+
});
|
|
32299
|
+
}
|
|
32161
32300
|
export {
|
|
32162
32301
|
main,
|
|
32163
32302
|
createProgram
|
package/dist/index.js
CHANGED
|
@@ -538,6 +538,9 @@ function getComponentPath(component, provider = "codex") {
|
|
|
538
538
|
if (component === "guides") {
|
|
539
539
|
return "guides";
|
|
540
540
|
}
|
|
541
|
+
if (provider === "codex" && component === "skills") {
|
|
542
|
+
return ".agents/skills";
|
|
543
|
+
}
|
|
541
544
|
return `${layout.rootDir}/${component}`;
|
|
542
545
|
}
|
|
543
546
|
function getTemplateComponentPath(component, provider = "codex") {
|
|
@@ -566,8 +569,9 @@ var init_layout = __esm(() => {
|
|
|
566
569
|
".codex/hooks",
|
|
567
570
|
".codex/contexts",
|
|
568
571
|
".codex/agents",
|
|
569
|
-
".codex/skills",
|
|
570
572
|
".codex/ontology",
|
|
573
|
+
".agents",
|
|
574
|
+
".agents/skills",
|
|
571
575
|
"guides"
|
|
572
576
|
]
|
|
573
577
|
};
|
|
@@ -2084,6 +2088,9 @@ async function backupExisting(sourcePath, backupDir) {
|
|
|
2084
2088
|
async function checkExistingPaths(targetDir) {
|
|
2085
2089
|
const layout = getProviderLayout();
|
|
2086
2090
|
const pathsToCheck = [layout.entryFile, layout.rootDir, "guides"];
|
|
2091
|
+
if (layout.provider === "codex") {
|
|
2092
|
+
pathsToCheck.push(".agents");
|
|
2093
|
+
}
|
|
2087
2094
|
const existingPaths = [];
|
|
2088
2095
|
for (const relativePath of pathsToCheck) {
|
|
2089
2096
|
const fullPath = join5(targetDir, relativePath);
|
|
@@ -2173,12 +2180,14 @@ var package_default = {
|
|
|
2173
2180
|
workspaces: [
|
|
2174
2181
|
"packages/*"
|
|
2175
2182
|
],
|
|
2176
|
-
version: "0.
|
|
2183
|
+
version: "0.3.1",
|
|
2177
2184
|
description: "Batteries-included agent harness on top of GPT Codex + OMX",
|
|
2178
2185
|
type: "module",
|
|
2179
2186
|
bin: {
|
|
2180
2187
|
omcodex: "./dist/cli/index.js",
|
|
2181
|
-
omcustom: "./dist/cli/index.js"
|
|
2188
|
+
omcustom: "./dist/cli/index.js",
|
|
2189
|
+
omcustomx: "./dist/cli/index.js",
|
|
2190
|
+
omcustomcodex: "./dist/cli/index.js"
|
|
2182
2191
|
},
|
|
2183
2192
|
main: "./dist/index.js",
|
|
2184
2193
|
types: "./dist/index.d.ts",
|
|
@@ -4669,12 +4678,32 @@ var setDefaultNamespace = instance.setDefaultNamespace;
|
|
|
4669
4678
|
var hasLoadedNamespace = instance.hasLoadedNamespace;
|
|
4670
4679
|
var loadNamespaces = instance.loadNamespaces;
|
|
4671
4680
|
var loadLanguages = instance.loadLanguages;
|
|
4681
|
+
|
|
4682
|
+
// src/utils/cli-command-name.ts
|
|
4683
|
+
var DEFAULT_CLI_COMMAND = "omcodex";
|
|
4684
|
+
var KNOWN_CLI_COMMANDS = new Set([DEFAULT_CLI_COMMAND, "omcustom", "omcustomx", "omcustomcodex"]);
|
|
4685
|
+
var WINDOWS_SCRIPT_EXTENSIONS = /\.(cmd|exe|ps1|bat)$/i;
|
|
4686
|
+
var activeCliCommandName = DEFAULT_CLI_COMMAND;
|
|
4687
|
+
function normalizeCliCommandName(commandName) {
|
|
4688
|
+
const normalized = commandName?.trim().toLowerCase().replace(WINDOWS_SCRIPT_EXTENSIONS, "");
|
|
4689
|
+
return normalized && KNOWN_CLI_COMMANDS.has(normalized) ? normalized : DEFAULT_CLI_COMMAND;
|
|
4690
|
+
}
|
|
4691
|
+
function getActiveCliCommandName() {
|
|
4692
|
+
return activeCliCommandName;
|
|
4693
|
+
}
|
|
4694
|
+
function rewriteCliCommandReferences(text, commandName = getActiveCliCommandName()) {
|
|
4695
|
+
const normalizedCommandName = normalizeCliCommandName(commandName);
|
|
4696
|
+
if (normalizedCommandName === DEFAULT_CLI_COMMAND) {
|
|
4697
|
+
return text;
|
|
4698
|
+
}
|
|
4699
|
+
return text.replace(/(^|[^A-Za-z0-9_.-])omcodex(?=$|[^A-Za-z0-9_.-])/g, (_match, prefix) => `${prefix}${normalizedCommandName}`);
|
|
4700
|
+
}
|
|
4672
4701
|
// src/i18n/types.ts
|
|
4673
4702
|
var DEFAULT_LANGUAGE2 = "en";
|
|
4674
4703
|
// src/i18n/index.ts
|
|
4675
4704
|
var i18n = {
|
|
4676
4705
|
t(key, options) {
|
|
4677
|
-
return instance.t(key, options);
|
|
4706
|
+
return rewriteCliCommandReferences(instance.t(key, options));
|
|
4678
4707
|
},
|
|
4679
4708
|
async changeLanguage(language) {
|
|
4680
4709
|
await instance.changeLanguage(language);
|
|
@@ -5458,6 +5487,9 @@ function getComponentPath2(component) {
|
|
|
5458
5487
|
if (component === "guides") {
|
|
5459
5488
|
return "guides";
|
|
5460
5489
|
}
|
|
5490
|
+
if (layout.provider === "codex" && component === "skills") {
|
|
5491
|
+
return ".agents/skills";
|
|
5492
|
+
}
|
|
5461
5493
|
return `${layout.rootDir}/${component}`;
|
|
5462
5494
|
}
|
|
5463
5495
|
async function backupInstallation(targetDir) {
|
|
@@ -5467,6 +5499,9 @@ async function backupInstallation(targetDir) {
|
|
|
5467
5499
|
await ensureDirectory(backupDir);
|
|
5468
5500
|
const layout = getProviderLayout();
|
|
5469
5501
|
const dirsToBackup = [layout.rootDir, "guides"];
|
|
5502
|
+
if (layout.provider === "codex") {
|
|
5503
|
+
dirsToBackup.push(".agents");
|
|
5504
|
+
}
|
|
5470
5505
|
for (const dir2 of dirsToBackup) {
|
|
5471
5506
|
const srcPath = join8(targetDir, dir2);
|
|
5472
5507
|
if (await fileExists(srcPath)) {
|
package/package.json
CHANGED
|
@@ -3,12 +3,14 @@
|
|
|
3
3
|
"workspaces": [
|
|
4
4
|
"packages/*"
|
|
5
5
|
],
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.3.1",
|
|
7
7
|
"description": "Batteries-included agent harness on top of GPT Codex + OMX",
|
|
8
8
|
"type": "module",
|
|
9
9
|
"bin": {
|
|
10
10
|
"omcodex": "./dist/cli/index.js",
|
|
11
|
-
"omcustom": "./dist/cli/index.js"
|
|
11
|
+
"omcustom": "./dist/cli/index.js",
|
|
12
|
+
"omcustomx": "./dist/cli/index.js",
|
|
13
|
+
"omcustomcodex": "./dist/cli/index.js"
|
|
12
14
|
},
|
|
13
15
|
"main": "./dist/index.js",
|
|
14
16
|
"types": "./dist/index.d.ts",
|
package/templates/CLAUDE.md
CHANGED
|
@@ -115,10 +115,11 @@ project/
|
|
|
115
115
|
+-- AGENTS.md # 진입점
|
|
116
116
|
+-- .codex/
|
|
117
117
|
| +-- agents/ # 서브에이전트 정의 (48 파일)
|
|
118
|
-
| +-- skills/ # 스킬 (109 디렉토리)
|
|
119
118
|
| +-- rules/ # 전역 규칙 (R000-R022)
|
|
120
119
|
| +-- hooks/ # 훅 스크립트 (보안, 검증, HUD)
|
|
121
120
|
| +-- contexts/ # 컨텍스트 파일 (ecomode)
|
|
121
|
+
+-- .agents/
|
|
122
|
+
| +-- skills/ # 스킬 (109 디렉토리)
|
|
122
123
|
+-- guides/ # 레퍼런스 문서 (39 토픽)
|
|
123
124
|
```
|
|
124
125
|
|
|
@@ -149,7 +150,7 @@ oh-my-customcodex는 소프트웨어 컴파일과 동일한 구조를 따릅니
|
|
|
149
150
|
|
|
150
151
|
| 컴파일 개념 | oh-my-customcodex 매핑 | 역할 |
|
|
151
152
|
|------------|----------------------|------|
|
|
152
|
-
| Source code | `.
|
|
153
|
+
| Source code | `.agents/skills/` | 재사용 가능한 지식과 워크플로우 정의 |
|
|
153
154
|
| Build artifacts | `.codex/agents/` | 스킬을 조합한 실행 가능한 전문가 |
|
|
154
155
|
| Compiler | `mgr-sauron` (R017) | 구조 검증 및 정합성 보장 |
|
|
155
156
|
| Spec | `.codex/rules/` | 빌드 규칙과 제약 조건 |
|
|
@@ -106,8 +106,8 @@ That keeps visual comparisons honest and makes "taste memory" reusable.
|
|
|
106
106
|
|
|
107
107
|
## Related Surfaces
|
|
108
108
|
|
|
109
|
-
- `.
|
|
110
|
-
- `.
|
|
111
|
-
- `.
|
|
109
|
+
- `.agents/skills/product-strategy/SKILL.md`
|
|
110
|
+
- `.agents/skills/design-shotgun/SKILL.md`
|
|
111
|
+
- `.agents/skills/playwright-compress/SKILL.md`
|
|
112
112
|
- `guides/web-scraping/README.md`
|
|
113
113
|
- `packages/serve/playwright.config.ts`
|
package/templates/index.yaml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Pipeline Registry
|
|
2
2
|
|
|
3
|
-
description: Registry of available
|
|
3
|
+
description: Registry of available workflow templates for the /pipeline skill
|
|
4
4
|
|
|
5
5
|
pipelines:
|
|
6
6
|
- name: code-review
|
|
@@ -13,6 +13,7 @@ templates:
|
|
|
13
13
|
description: Base template for creating new pipelines
|
|
14
14
|
|
|
15
15
|
usage:
|
|
16
|
-
run: "pipeline
|
|
17
|
-
list: "pipeline
|
|
18
|
-
|
|
16
|
+
run: "/pipeline <name>"
|
|
17
|
+
list: "/pipeline"
|
|
18
|
+
resume: "/pipeline resume"
|
|
19
|
+
create: "Create workflows/<name>.yaml from templates/pipeline-template.yaml"
|
package/templates/manifest.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.
|
|
3
|
-
"lastUpdated": "2026-04-
|
|
2
|
+
"version": "0.3.1",
|
|
3
|
+
"lastUpdated": "2026-04-22T03:55:00.000Z",
|
|
4
4
|
"components": [
|
|
5
5
|
{
|
|
6
6
|
"name": "rules",
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
},
|
|
17
17
|
{
|
|
18
18
|
"name": "skills",
|
|
19
|
-
"path": ".
|
|
20
|
-
"description": "Reusable skill modules (
|
|
19
|
+
"path": ".agents/skills",
|
|
20
|
+
"description": "Reusable skill modules (project-scoped repo skills)",
|
|
21
21
|
"files": 112
|
|
22
22
|
},
|
|
23
23
|
{
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# /pipeline auto-dev — Full-auto release pipeline
|
|
2
|
-
# Pre-triages open issues → triage verify-done → plan → implement → verify → PR → followup
|
|
2
|
+
# Pre-triages open issues → triage verify-done → plan → implement → verify → PR/release → publish → followup
|
|
3
3
|
|
|
4
4
|
name: auto-dev
|
|
5
|
-
description: "Full-auto release pipeline: pre-triage → triage → plan → implement → verify → PR → followup"
|
|
5
|
+
description: "Full-auto release pipeline: pre-triage → triage → plan → implement → verify → PR → publish → followup"
|
|
6
6
|
mode: auto
|
|
7
7
|
error: halt-and-report
|
|
8
8
|
|
|
@@ -41,6 +41,27 @@ steps:
|
|
|
41
41
|
prompt: "Create release branch and pull request"
|
|
42
42
|
description: Create release branch and pull request
|
|
43
43
|
|
|
44
|
+
- name: publish
|
|
45
|
+
prompt: |
|
|
46
|
+
Publish the validated release artifact after the release PR/branch stage.
|
|
47
|
+
|
|
48
|
+
Project-specific behavior:
|
|
49
|
+
- npm package:
|
|
50
|
+
1. Confirm package name and current version from package.json
|
|
51
|
+
2. Check registry state (`npm view <pkg> version`)
|
|
52
|
+
3. If version is unchanged but release-worthy, bump semver intentionally
|
|
53
|
+
4. Run the publish path (`npm publish` or the repo's release workflow trigger)
|
|
54
|
+
5. Verify registry publication (`npm view <pkg> version`)
|
|
55
|
+
- GitHub-release artifact project:
|
|
56
|
+
1. Create/push tag if required
|
|
57
|
+
2. Trigger or create the release artifact
|
|
58
|
+
3. Verify the release exists and assets are available
|
|
59
|
+
|
|
60
|
+
Halt and report on auth, versioning, or publish verification failures.
|
|
61
|
+
description: Publish the release artifact and verify external availability
|
|
62
|
+
depends_on: release
|
|
63
|
+
|
|
44
64
|
- name: followup
|
|
45
65
|
skill: post-release-followup
|
|
46
66
|
description: Recommend follow-up actions — user chooses to execute now or register as issues
|
|
67
|
+
depends_on: publish
|