@fractary/codex-cli 0.10.13 → 0.10.14
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 +41 -315
- package/dist/cli.cjs +90 -15
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +91 -16
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -4,7 +4,7 @@ import { dirname, join } from 'path';
|
|
|
4
4
|
import { fileURLToPath } from 'url';
|
|
5
5
|
import * as fs from 'fs/promises';
|
|
6
6
|
import * as yaml2 from 'js-yaml';
|
|
7
|
-
import { readCodexConfig, expandEnvVarsInConfig, expandEnvVars, parseSize, parseDuration, ValidationError, PermissionDeniedError, ConfigurationError, CodexError } from '@fractary/codex';
|
|
7
|
+
import { readCodexConfig, CONFIG_SCHEMA_VERSION, expandEnvVarsInConfig, expandEnvVars, parseSize, parseDuration, ValidationError, PermissionDeniedError, ConfigurationError, CodexError } from '@fractary/codex';
|
|
8
8
|
import * as os from 'os';
|
|
9
9
|
import { spawn } from 'child_process';
|
|
10
10
|
import { Command } from 'commander';
|
|
@@ -790,7 +790,7 @@ function getDefaultUnifiedConfig(organization, project, codexRepo) {
|
|
|
790
790
|
const sanitizedProject = sanitizeForS3BucketName(project);
|
|
791
791
|
return {
|
|
792
792
|
file: {
|
|
793
|
-
schema_version:
|
|
793
|
+
schema_version: CONFIG_SCHEMA_VERSION,
|
|
794
794
|
sources: {
|
|
795
795
|
specs: {
|
|
796
796
|
type: "s3",
|
|
@@ -827,11 +827,16 @@ function getDefaultUnifiedConfig(organization, project, codexRepo) {
|
|
|
827
827
|
}
|
|
828
828
|
},
|
|
829
829
|
codex: {
|
|
830
|
-
schema_version:
|
|
830
|
+
schema_version: CONFIG_SCHEMA_VERSION,
|
|
831
831
|
organization,
|
|
832
832
|
project,
|
|
833
833
|
codex_repo: codexRepo,
|
|
834
|
-
|
|
834
|
+
remotes: {
|
|
835
|
+
// The codex repository - uses same token as git operations
|
|
836
|
+
[`${organization}/${codexRepo}`]: {
|
|
837
|
+
token: "${GITHUB_TOKEN}"
|
|
838
|
+
}
|
|
839
|
+
}
|
|
835
840
|
}
|
|
836
841
|
};
|
|
837
842
|
}
|
|
@@ -862,7 +867,7 @@ function mergeUnifiedConfigs(existing, updates) {
|
|
|
862
867
|
const merged = {};
|
|
863
868
|
if (updates.file || existing.file) {
|
|
864
869
|
merged.file = {
|
|
865
|
-
schema_version: updates.file?.schema_version || existing.file?.schema_version ||
|
|
870
|
+
schema_version: updates.file?.schema_version || existing.file?.schema_version || CONFIG_SCHEMA_VERSION,
|
|
866
871
|
sources: {
|
|
867
872
|
...existing.file?.sources || {},
|
|
868
873
|
...updates.file?.sources || {}
|
|
@@ -871,13 +876,13 @@ function mergeUnifiedConfigs(existing, updates) {
|
|
|
871
876
|
}
|
|
872
877
|
if (updates.codex || existing.codex) {
|
|
873
878
|
merged.codex = {
|
|
874
|
-
schema_version: updates.codex?.schema_version || existing.codex?.schema_version ||
|
|
879
|
+
schema_version: updates.codex?.schema_version || existing.codex?.schema_version || CONFIG_SCHEMA_VERSION,
|
|
875
880
|
organization: updates.codex?.organization || existing.codex?.organization || "default",
|
|
876
881
|
project: updates.codex?.project || existing.codex?.project || "default",
|
|
877
882
|
codex_repo: updates.codex?.codex_repo || existing.codex?.codex_repo || "",
|
|
878
|
-
|
|
879
|
-
...existing.codex?.
|
|
880
|
-
...updates.codex?.
|
|
883
|
+
remotes: {
|
|
884
|
+
...existing.codex?.remotes || {},
|
|
885
|
+
...updates.codex?.remotes || {}
|
|
881
886
|
}
|
|
882
887
|
};
|
|
883
888
|
}
|
|
@@ -1091,9 +1096,64 @@ async function fileExists(filePath) {
|
|
|
1091
1096
|
return false;
|
|
1092
1097
|
}
|
|
1093
1098
|
}
|
|
1099
|
+
async function installMcpServer(projectRoot, configPath = ".fractary/config.yaml", options = {}) {
|
|
1100
|
+
const mcpJsonPath = path5.join(projectRoot, ".mcp.json");
|
|
1101
|
+
const { backup = true } = options;
|
|
1102
|
+
let existingConfig = { mcpServers: {} };
|
|
1103
|
+
let backupPath;
|
|
1104
|
+
let migrated = false;
|
|
1105
|
+
if (await fileExists(mcpJsonPath)) {
|
|
1106
|
+
try {
|
|
1107
|
+
const content = await fs.readFile(mcpJsonPath, "utf-8");
|
|
1108
|
+
existingConfig = JSON.parse(content);
|
|
1109
|
+
if (backup) {
|
|
1110
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "").slice(0, 18);
|
|
1111
|
+
const suffix = Math.random().toString(36).substring(2, 6);
|
|
1112
|
+
backupPath = `${mcpJsonPath}.backup.${timestamp}-${suffix}`;
|
|
1113
|
+
await fs.writeFile(backupPath, content);
|
|
1114
|
+
}
|
|
1115
|
+
} catch {
|
|
1116
|
+
console.log(chalk7.yellow("\u26A0 Warning: .mcp.json contains invalid JSON, starting fresh"));
|
|
1117
|
+
existingConfig = { mcpServers: {} };
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
if (!existingConfig.mcpServers) {
|
|
1121
|
+
existingConfig.mcpServers = {};
|
|
1122
|
+
}
|
|
1123
|
+
const existing = existingConfig.mcpServers["fractary-codex"];
|
|
1124
|
+
if (existing) {
|
|
1125
|
+
const existingCommand = existing.command;
|
|
1126
|
+
const existingArgs = existing.args || [];
|
|
1127
|
+
if (existingCommand === "npx" && existingArgs.includes("@fractary/codex-mcp")) {
|
|
1128
|
+
return {
|
|
1129
|
+
installed: false,
|
|
1130
|
+
migrated: false,
|
|
1131
|
+
alreadyInstalled: true,
|
|
1132
|
+
backupPath
|
|
1133
|
+
};
|
|
1134
|
+
}
|
|
1135
|
+
if (existingCommand === "node" || existingArgs.includes("@fractary/codex")) {
|
|
1136
|
+
migrated = true;
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
existingConfig.mcpServers["fractary-codex"] = {
|
|
1140
|
+
command: "npx",
|
|
1141
|
+
args: ["-y", "@fractary/codex-mcp", "--config", configPath]
|
|
1142
|
+
};
|
|
1143
|
+
await fs.writeFile(
|
|
1144
|
+
mcpJsonPath,
|
|
1145
|
+
JSON.stringify(existingConfig, null, 2) + "\n"
|
|
1146
|
+
);
|
|
1147
|
+
return {
|
|
1148
|
+
installed: true,
|
|
1149
|
+
migrated,
|
|
1150
|
+
alreadyInstalled: false,
|
|
1151
|
+
backupPath
|
|
1152
|
+
};
|
|
1153
|
+
}
|
|
1094
1154
|
function initCommand() {
|
|
1095
1155
|
const cmd = new Command("init");
|
|
1096
|
-
cmd.description("Initialize unified Fractary configuration (.fractary/config.yaml)").option("--org <slug>", 'Organization slug (e.g., "fractary")').option("--project <name>", "Project name (default: derived from directory)").option("--codex-repo <name>", 'Codex repository name (e.g., "codex.fractary.com")').option("--force", "Overwrite existing configuration").action(async (options) => {
|
|
1156
|
+
cmd.description("Initialize unified Fractary configuration (.fractary/config.yaml)").option("--org <slug>", 'Organization slug (e.g., "fractary")').option("--project <name>", "Project name (default: derived from directory)").option("--codex-repo <name>", 'Codex repository name (e.g., "codex.fractary.com")').option("--force", "Overwrite existing configuration").option("--no-mcp", "Skip MCP server installation").action(async (options) => {
|
|
1097
1157
|
try {
|
|
1098
1158
|
console.log(chalk7.blue("Initializing unified Fractary configuration...\n"));
|
|
1099
1159
|
let org = options.org;
|
|
@@ -1205,6 +1265,20 @@ function initCommand() {
|
|
|
1205
1265
|
} else if (result.merged) {
|
|
1206
1266
|
console.log(chalk7.green("\u2713"), chalk7.dim(".fractary/config.yaml (merged with existing)"));
|
|
1207
1267
|
}
|
|
1268
|
+
if (options.mcp !== false) {
|
|
1269
|
+
console.log("\nConfiguring MCP server...");
|
|
1270
|
+
const mcpResult = await installMcpServer(process.cwd(), ".fractary/config.yaml");
|
|
1271
|
+
if (mcpResult.alreadyInstalled) {
|
|
1272
|
+
console.log(chalk7.green("\u2713"), chalk7.dim(".mcp.json (already configured)"));
|
|
1273
|
+
} else if (mcpResult.migrated) {
|
|
1274
|
+
console.log(chalk7.green("\u2713"), chalk7.dim(".mcp.json (migrated from old format)"));
|
|
1275
|
+
if (mcpResult.backupPath) {
|
|
1276
|
+
console.log(chalk7.dim(` Backup: ${path5.basename(mcpResult.backupPath)}`));
|
|
1277
|
+
}
|
|
1278
|
+
} else if (mcpResult.installed) {
|
|
1279
|
+
console.log(chalk7.green("\u2713"), chalk7.dim(".mcp.json (created)"));
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1208
1282
|
console.log(chalk7.green("\n\u2713 Unified configuration initialized successfully!\n"));
|
|
1209
1283
|
console.log(chalk7.bold("Configuration:"));
|
|
1210
1284
|
console.log(chalk7.dim(` Organization: ${org}`));
|
|
@@ -1216,18 +1290,19 @@ function initCommand() {
|
|
|
1216
1290
|
console.log(chalk7.dim(" - logs: .fractary/logs/ \u2192 S3"));
|
|
1217
1291
|
console.log(chalk7.bold("\nCodex plugin:"));
|
|
1218
1292
|
console.log(chalk7.dim(" - Cache: .fractary/codex/cache/"));
|
|
1219
|
-
console.log(chalk7.dim(" -
|
|
1293
|
+
console.log(chalk7.dim(" - MCP Server: @fractary/codex-mcp (via npx)"));
|
|
1294
|
+
console.log(chalk7.dim(" - Remotes: codex repo configured"));
|
|
1220
1295
|
console.log(chalk7.bold("\nGit Authentication:"));
|
|
1221
1296
|
console.log(chalk7.dim(" Codex sync uses your existing git credentials."));
|
|
1222
1297
|
console.log(chalk7.dim(" Ensure you have access to the codex repository:"));
|
|
1223
1298
|
console.log(chalk7.dim(` gh repo view ${org}/${codexRepo}`));
|
|
1224
1299
|
console.log(chalk7.dim(" Or set GITHUB_TOKEN environment variable."));
|
|
1225
1300
|
console.log(chalk7.bold("\nNext steps:"));
|
|
1226
|
-
console.log(chalk7.dim(" 1.
|
|
1227
|
-
console.log(chalk7.dim(" 2.
|
|
1228
|
-
console.log(chalk7.dim(" 3.
|
|
1229
|
-
console.log(chalk7.dim(" 4.
|
|
1230
|
-
console.log(chalk7.dim(" 5.
|
|
1301
|
+
console.log(chalk7.dim(" 1. Restart Claude Code to load the MCP server"));
|
|
1302
|
+
console.log(chalk7.dim(" 2. Verify codex repository access: gh repo view " + org + "/" + codexRepo));
|
|
1303
|
+
console.log(chalk7.dim(" 3. Configure AWS credentials for S3 access (if using file plugin)"));
|
|
1304
|
+
console.log(chalk7.dim(" 4. Edit .fractary/config.yaml to add external project remotes"));
|
|
1305
|
+
console.log(chalk7.dim(" 5. Reference docs via codex:// URIs (auto-fetched by MCP)"));
|
|
1231
1306
|
} catch (error) {
|
|
1232
1307
|
console.error(chalk7.red("Error:"), error.message);
|
|
1233
1308
|
process.exit(1);
|