@fractary/codex-cli 0.9.1 → 0.10.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 +2 -2
- package/dist/cli.cjs +361 -412
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +360 -411
- package/dist/cli.js.map +1 -1
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -8,7 +8,7 @@ import { ValidationError, PermissionDeniedError, ConfigurationError, CodexError
|
|
|
8
8
|
import * as os from 'os';
|
|
9
9
|
import { spawn } from 'child_process';
|
|
10
10
|
import { Command } from 'commander';
|
|
11
|
-
import
|
|
11
|
+
import chalk7 from 'chalk';
|
|
12
12
|
import * as crypto from 'crypto';
|
|
13
13
|
import { readFileSync } from 'fs';
|
|
14
14
|
|
|
@@ -796,14 +796,14 @@ function fetchCommand() {
|
|
|
796
796
|
try {
|
|
797
797
|
const { validateUri } = await import('@fractary/codex');
|
|
798
798
|
if (!validateUri(uri)) {
|
|
799
|
-
console.error(
|
|
800
|
-
console.log(
|
|
801
|
-
console.log(
|
|
799
|
+
console.error(chalk7.red("Error: Invalid URI format"));
|
|
800
|
+
console.log(chalk7.dim("Expected: codex://org/project/path/to/file.md"));
|
|
801
|
+
console.log(chalk7.dim("Example: codex://fractary/codex/docs/api.md"));
|
|
802
802
|
process.exit(1);
|
|
803
803
|
}
|
|
804
804
|
const client = await getClient();
|
|
805
805
|
if (!options.json && !options.bypassCache) {
|
|
806
|
-
console.error(
|
|
806
|
+
console.error(chalk7.dim(`Fetching ${uri}...`));
|
|
807
807
|
}
|
|
808
808
|
const result = await client.fetch(uri, {
|
|
809
809
|
bypassCache: options.bypassCache,
|
|
@@ -824,30 +824,30 @@ function fetchCommand() {
|
|
|
824
824
|
console.log(JSON.stringify(output, null, 2));
|
|
825
825
|
} else if (options.output) {
|
|
826
826
|
await fs.writeFile(options.output, result.content);
|
|
827
|
-
console.log(
|
|
828
|
-
console.log(
|
|
827
|
+
console.log(chalk7.green("\u2713"), `Written to ${options.output}`);
|
|
828
|
+
console.log(chalk7.dim(` Size: ${result.content.length} bytes`));
|
|
829
829
|
if (result.fromCache) {
|
|
830
|
-
console.log(
|
|
830
|
+
console.log(chalk7.dim(" Source: cache"));
|
|
831
831
|
} else {
|
|
832
|
-
console.log(
|
|
832
|
+
console.log(chalk7.dim(" Source: storage"));
|
|
833
833
|
}
|
|
834
834
|
} else {
|
|
835
835
|
if (result.fromCache && !options.bypassCache) {
|
|
836
|
-
console.error(
|
|
836
|
+
console.error(chalk7.green("\u2713"), chalk7.dim("from cache\n"));
|
|
837
837
|
} else {
|
|
838
|
-
console.error(
|
|
838
|
+
console.error(chalk7.green("\u2713"), chalk7.dim("fetched\n"));
|
|
839
839
|
}
|
|
840
840
|
console.log(result.content.toString("utf-8"));
|
|
841
841
|
}
|
|
842
842
|
} catch (error) {
|
|
843
|
-
console.error(
|
|
843
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
844
844
|
if (error.message.includes("Failed to load configuration")) {
|
|
845
|
-
console.log(
|
|
845
|
+
console.log(chalk7.dim('\nRun "fractary codex init" to create a configuration.'));
|
|
846
846
|
} else if (error.message.includes("GITHUB_TOKEN")) {
|
|
847
|
-
console.log(
|
|
847
|
+
console.log(chalk7.dim('\nSet your GitHub token: export GITHUB_TOKEN="your_token"'));
|
|
848
848
|
} else if (error.message.includes("not found") || error.message.includes("404")) {
|
|
849
|
-
console.log(
|
|
850
|
-
console.log(
|
|
849
|
+
console.log(chalk7.dim("\nThe document may not exist or you may not have access."));
|
|
850
|
+
console.log(chalk7.dim("Check the URI and ensure your storage providers are configured correctly."));
|
|
851
851
|
}
|
|
852
852
|
process.exit(1);
|
|
853
853
|
}
|
|
@@ -874,7 +874,7 @@ init_esm_shims();
|
|
|
874
874
|
function sanitizeForS3BucketName(name) {
|
|
875
875
|
return name.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/^-+|-+$/g, "").replace(/-+/g, "-").substring(0, 63);
|
|
876
876
|
}
|
|
877
|
-
function getDefaultUnifiedConfig(organization, project) {
|
|
877
|
+
function getDefaultUnifiedConfig(organization, project, codexRepo) {
|
|
878
878
|
const sanitizedProject = sanitizeForS3BucketName(project);
|
|
879
879
|
return {
|
|
880
880
|
file: {
|
|
@@ -918,6 +918,7 @@ function getDefaultUnifiedConfig(organization, project) {
|
|
|
918
918
|
schema_version: "2.0",
|
|
919
919
|
organization,
|
|
920
920
|
project,
|
|
921
|
+
codex_repo: codexRepo,
|
|
921
922
|
dependencies: {}
|
|
922
923
|
}
|
|
923
924
|
};
|
|
@@ -961,6 +962,7 @@ function mergeUnifiedConfigs(existing, updates) {
|
|
|
961
962
|
schema_version: updates.codex?.schema_version || existing.codex?.schema_version || "2.0",
|
|
962
963
|
organization: updates.codex?.organization || existing.codex?.organization || "default",
|
|
963
964
|
project: updates.codex?.project || existing.codex?.project || "default",
|
|
965
|
+
codex_repo: updates.codex?.codex_repo || existing.codex?.codex_repo || "",
|
|
964
966
|
dependencies: {
|
|
965
967
|
...existing.codex?.dependencies || {},
|
|
966
968
|
...updates.codex?.dependencies || {}
|
|
@@ -969,10 +971,10 @@ function mergeUnifiedConfigs(existing, updates) {
|
|
|
969
971
|
}
|
|
970
972
|
return merged;
|
|
971
973
|
}
|
|
972
|
-
async function initializeUnifiedConfig(configPath, organization, project, options) {
|
|
974
|
+
async function initializeUnifiedConfig(configPath, organization, project, codexRepo, options) {
|
|
973
975
|
const existingConfig = await readUnifiedConfig(configPath);
|
|
974
976
|
if (existingConfig && !options?.force) {
|
|
975
|
-
const defaultConfig = getDefaultUnifiedConfig(organization, project);
|
|
977
|
+
const defaultConfig = getDefaultUnifiedConfig(organization, project, codexRepo);
|
|
976
978
|
const merged = mergeUnifiedConfigs(existingConfig, defaultConfig);
|
|
977
979
|
await writeUnifiedConfig(merged, configPath);
|
|
978
980
|
return {
|
|
@@ -981,7 +983,7 @@ async function initializeUnifiedConfig(configPath, organization, project, option
|
|
|
981
983
|
config: merged
|
|
982
984
|
};
|
|
983
985
|
}
|
|
984
|
-
const config = getDefaultUnifiedConfig(organization, project);
|
|
986
|
+
const config = getDefaultUnifiedConfig(organization, project, codexRepo);
|
|
985
987
|
await writeUnifiedConfig(config, configPath);
|
|
986
988
|
return {
|
|
987
989
|
created: true,
|
|
@@ -999,7 +1001,6 @@ var DEFAULT_FRACTARY_GITIGNORE = `# .fractary/.gitignore
|
|
|
999
1001
|
codex/cache/
|
|
1000
1002
|
# ===== end fractary-codex =====
|
|
1001
1003
|
`;
|
|
1002
|
-
var DEFAULT_CACHE_DIR = "codex/cache/";
|
|
1003
1004
|
async function readFractaryGitignore(projectRoot) {
|
|
1004
1005
|
const gitignorePath = path5.join(projectRoot, ".fractary", ".gitignore");
|
|
1005
1006
|
try {
|
|
@@ -1091,6 +1092,20 @@ async function ensureCachePathIgnored(projectRoot, cachePath) {
|
|
|
1091
1092
|
}
|
|
1092
1093
|
|
|
1093
1094
|
// src/commands/config/init.ts
|
|
1095
|
+
function validateNameFormat(name, type) {
|
|
1096
|
+
if (!name || typeof name !== "string") {
|
|
1097
|
+
throw new Error(`${type} name is required`);
|
|
1098
|
+
}
|
|
1099
|
+
if (name.length > 100) {
|
|
1100
|
+
throw new Error(`${type} name too long (max 100 characters)`);
|
|
1101
|
+
}
|
|
1102
|
+
const safePattern = /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/;
|
|
1103
|
+
if (!safePattern.test(name)) {
|
|
1104
|
+
throw new Error(
|
|
1105
|
+
`Invalid ${type} name format: "${name}". Must start with alphanumeric and contain only: a-z, A-Z, 0-9, ., -, _`
|
|
1106
|
+
);
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1094
1109
|
async function getOrgFromGitRemote() {
|
|
1095
1110
|
try {
|
|
1096
1111
|
const { execSync } = __require("child_process");
|
|
@@ -1102,6 +1117,60 @@ async function getOrgFromGitRemote() {
|
|
|
1102
1117
|
return null;
|
|
1103
1118
|
}
|
|
1104
1119
|
}
|
|
1120
|
+
async function discoverCodexRepo(org) {
|
|
1121
|
+
try {
|
|
1122
|
+
validateNameFormat(org, "organization");
|
|
1123
|
+
} catch (error) {
|
|
1124
|
+
return { repo: null, error: "unknown", message: error.message };
|
|
1125
|
+
}
|
|
1126
|
+
try {
|
|
1127
|
+
const { execSync } = __require("child_process");
|
|
1128
|
+
try {
|
|
1129
|
+
execSync("gh --version", { encoding: "utf-8", stdio: "pipe" });
|
|
1130
|
+
} catch {
|
|
1131
|
+
return {
|
|
1132
|
+
repo: null,
|
|
1133
|
+
error: "gh_not_installed",
|
|
1134
|
+
message: "GitHub CLI (gh) is not installed. Install from https://cli.github.com/"
|
|
1135
|
+
};
|
|
1136
|
+
}
|
|
1137
|
+
try {
|
|
1138
|
+
execSync("gh auth status", { encoding: "utf-8", stdio: "pipe" });
|
|
1139
|
+
} catch {
|
|
1140
|
+
return {
|
|
1141
|
+
repo: null,
|
|
1142
|
+
error: "auth_failed",
|
|
1143
|
+
message: "GitHub CLI not authenticated. Run: gh auth login"
|
|
1144
|
+
};
|
|
1145
|
+
}
|
|
1146
|
+
const result = execSync(
|
|
1147
|
+
`gh repo list ${org} --json name --jq '.[].name | select(startswith("codex."))' 2>&1`,
|
|
1148
|
+
{ encoding: "utf-8" }
|
|
1149
|
+
).trim();
|
|
1150
|
+
if (result.includes("Could not resolve to an Organization") || result.includes("Not Found")) {
|
|
1151
|
+
return {
|
|
1152
|
+
repo: null,
|
|
1153
|
+
error: "org_not_found",
|
|
1154
|
+
message: `Organization '${org}' not found on GitHub`
|
|
1155
|
+
};
|
|
1156
|
+
}
|
|
1157
|
+
const repos = result.split("\n").filter(Boolean);
|
|
1158
|
+
if (repos.length === 0) {
|
|
1159
|
+
return {
|
|
1160
|
+
repo: null,
|
|
1161
|
+
error: "no_repos_found",
|
|
1162
|
+
message: `No codex.* repositories found in organization '${org}'`
|
|
1163
|
+
};
|
|
1164
|
+
}
|
|
1165
|
+
return { repo: repos[0] };
|
|
1166
|
+
} catch (error) {
|
|
1167
|
+
return {
|
|
1168
|
+
repo: null,
|
|
1169
|
+
error: "unknown",
|
|
1170
|
+
message: error.message || "Unknown error during discovery"
|
|
1171
|
+
};
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1105
1174
|
async function fileExists(filePath) {
|
|
1106
1175
|
try {
|
|
1107
1176
|
await fs.access(filePath);
|
|
@@ -1112,9 +1181,9 @@ async function fileExists(filePath) {
|
|
|
1112
1181
|
}
|
|
1113
1182
|
function initCommand() {
|
|
1114
1183
|
const cmd = new Command("init");
|
|
1115
|
-
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("--force", "Overwrite existing configuration").action(async (options) => {
|
|
1184
|
+
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) => {
|
|
1116
1185
|
try {
|
|
1117
|
-
console.log(
|
|
1186
|
+
console.log(chalk7.blue("Initializing unified Fractary configuration...\n"));
|
|
1118
1187
|
let org = options.org;
|
|
1119
1188
|
if (!org) {
|
|
1120
1189
|
org = await getOrgFromGitRemote();
|
|
@@ -1130,23 +1199,66 @@ function initCommand() {
|
|
|
1130
1199
|
}
|
|
1131
1200
|
if (!org) {
|
|
1132
1201
|
org = path5.basename(process.cwd()).split("-")[0] || "default";
|
|
1133
|
-
console.log(
|
|
1134
|
-
console.log(
|
|
1202
|
+
console.log(chalk7.yellow(`\u26A0 Could not detect organization, using: ${org}`));
|
|
1203
|
+
console.log(chalk7.dim(" Use --org <slug> to specify explicitly\n"));
|
|
1135
1204
|
} else {
|
|
1136
|
-
console.log(
|
|
1205
|
+
console.log(chalk7.dim(`Organization: ${chalk7.cyan(org)}
|
|
1137
1206
|
`));
|
|
1138
1207
|
}
|
|
1208
|
+
try {
|
|
1209
|
+
validateNameFormat(org, "organization");
|
|
1210
|
+
} catch (error) {
|
|
1211
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
1212
|
+
process.exit(1);
|
|
1213
|
+
}
|
|
1139
1214
|
let project = options.project;
|
|
1140
1215
|
if (!project) {
|
|
1141
1216
|
project = path5.basename(process.cwd());
|
|
1142
|
-
console.log(
|
|
1217
|
+
console.log(chalk7.dim(`Project: ${chalk7.cyan(project)}
|
|
1218
|
+
`));
|
|
1219
|
+
}
|
|
1220
|
+
let codexRepo = options.codexRepo;
|
|
1221
|
+
if (codexRepo) {
|
|
1222
|
+
try {
|
|
1223
|
+
validateNameFormat(codexRepo, "repository");
|
|
1224
|
+
} catch (error) {
|
|
1225
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
1226
|
+
process.exit(1);
|
|
1227
|
+
}
|
|
1228
|
+
console.log(chalk7.dim(`Codex repository: ${chalk7.cyan(codexRepo)}
|
|
1229
|
+
`));
|
|
1230
|
+
} else {
|
|
1231
|
+
const discoveryResult = await discoverCodexRepo(org);
|
|
1232
|
+
if (discoveryResult.repo) {
|
|
1233
|
+
codexRepo = discoveryResult.repo;
|
|
1234
|
+
console.log(chalk7.dim(`Codex repository: ${chalk7.cyan(codexRepo)} (auto-discovered)
|
|
1235
|
+
`));
|
|
1236
|
+
} else {
|
|
1237
|
+
if (discoveryResult.error === "gh_not_installed") {
|
|
1238
|
+
console.log(chalk7.dim(` Note: ${discoveryResult.message}
|
|
1239
|
+
`));
|
|
1240
|
+
} else if (discoveryResult.error === "auth_failed") {
|
|
1241
|
+
console.log(chalk7.dim(` Note: ${discoveryResult.message}
|
|
1242
|
+
`));
|
|
1243
|
+
} else if (discoveryResult.error === "org_not_found") {
|
|
1244
|
+
console.log(chalk7.dim(` Note: ${discoveryResult.message}
|
|
1245
|
+
`));
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
if (!codexRepo) {
|
|
1250
|
+
console.log(chalk7.yellow(`\u26A0 Could not discover codex repository in organization '${org}'`));
|
|
1251
|
+
console.log(chalk7.dim(" Use --codex-repo <name> to specify explicitly"));
|
|
1252
|
+
console.log(chalk7.dim(" Expected naming convention: codex.{org}.{tld} (e.g., codex.fractary.com)\n"));
|
|
1253
|
+
codexRepo = `codex.${org}.com`;
|
|
1254
|
+
console.log(chalk7.dim(` Using default: ${chalk7.cyan(codexRepo)}
|
|
1143
1255
|
`));
|
|
1144
1256
|
}
|
|
1145
1257
|
const configPath = path5.join(process.cwd(), ".fractary", "config.yaml");
|
|
1146
1258
|
const configExists = await fileExists(configPath);
|
|
1147
1259
|
if (configExists && !options.force) {
|
|
1148
|
-
console.log(
|
|
1149
|
-
console.log(
|
|
1260
|
+
console.log(chalk7.yellow(`\u26A0 Configuration already exists at .fractary/config.yaml`));
|
|
1261
|
+
console.log(chalk7.dim("Merging with existing configuration...\n"));
|
|
1150
1262
|
}
|
|
1151
1263
|
console.log("Creating directory structure...");
|
|
1152
1264
|
const dirs = [
|
|
@@ -1158,216 +1270,54 @@ function initCommand() {
|
|
|
1158
1270
|
];
|
|
1159
1271
|
for (const dir of dirs) {
|
|
1160
1272
|
await fs.mkdir(path5.join(process.cwd(), dir), { recursive: true });
|
|
1161
|
-
console.log(
|
|
1273
|
+
console.log(chalk7.green("\u2713"), chalk7.dim(dir + "/"));
|
|
1162
1274
|
}
|
|
1163
1275
|
const gitignoreResult = await ensureCachePathIgnored(process.cwd(), ".fractary/codex/cache");
|
|
1164
1276
|
if (gitignoreResult.created) {
|
|
1165
|
-
console.log(
|
|
1277
|
+
console.log(chalk7.green("\u2713"), chalk7.dim(".fractary/.gitignore (created)"));
|
|
1166
1278
|
} else if (gitignoreResult.updated) {
|
|
1167
|
-
console.log(
|
|
1279
|
+
console.log(chalk7.green("\u2713"), chalk7.dim(".fractary/.gitignore (updated)"));
|
|
1168
1280
|
} else {
|
|
1169
|
-
console.log(
|
|
1281
|
+
console.log(chalk7.green("\u2713"), chalk7.dim(".fractary/.gitignore (exists)"));
|
|
1170
1282
|
}
|
|
1171
1283
|
console.log("\nInitializing configuration...");
|
|
1172
1284
|
const result = await initializeUnifiedConfig(
|
|
1173
1285
|
configPath,
|
|
1174
1286
|
org,
|
|
1175
1287
|
project,
|
|
1288
|
+
codexRepo,
|
|
1176
1289
|
{ force: options.force }
|
|
1177
1290
|
);
|
|
1178
1291
|
if (result.created) {
|
|
1179
|
-
console.log(
|
|
1292
|
+
console.log(chalk7.green("\u2713"), chalk7.dim(".fractary/config.yaml (created)"));
|
|
1180
1293
|
} else if (result.merged) {
|
|
1181
|
-
console.log(
|
|
1182
|
-
}
|
|
1183
|
-
console.log(
|
|
1184
|
-
console.log(
|
|
1185
|
-
console.log(
|
|
1186
|
-
console.log(
|
|
1187
|
-
console.log(
|
|
1188
|
-
console.log(
|
|
1189
|
-
console.log(
|
|
1190
|
-
console.log(
|
|
1191
|
-
console.log(
|
|
1192
|
-
console.log(
|
|
1193
|
-
console.log(
|
|
1194
|
-
console.log(
|
|
1195
|
-
console.log(
|
|
1196
|
-
console.log(
|
|
1197
|
-
console.log(
|
|
1198
|
-
console.log(
|
|
1199
|
-
|
|
1200
|
-
console.
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
// src/commands/config/migrate.ts
|
|
1208
|
-
init_esm_shims();
|
|
1209
|
-
init_migrate_config();
|
|
1210
|
-
async function fileExists2(filePath) {
|
|
1211
|
-
try {
|
|
1212
|
-
await fs.access(filePath);
|
|
1213
|
-
return true;
|
|
1214
|
-
} catch {
|
|
1215
|
-
return false;
|
|
1216
|
-
}
|
|
1217
|
-
}
|
|
1218
|
-
async function readFileContent(filePath) {
|
|
1219
|
-
return fs.readFile(filePath, "utf-8");
|
|
1220
|
-
}
|
|
1221
|
-
function migrateCommand() {
|
|
1222
|
-
const cmd = new Command("migrate");
|
|
1223
|
-
cmd.description("Migrate legacy JSON configuration to v3.0 YAML format").option("--dry-run", "Show migration plan without executing").option("--no-backup", "Skip creating backup of old config").option("--json", "Output as JSON").action(async (options) => {
|
|
1224
|
-
try {
|
|
1225
|
-
const legacyConfigPath = path5.join(process.cwd(), ".fractary", "plugins", "codex", "config.json");
|
|
1226
|
-
const newConfigPath = path5.join(process.cwd(), ".fractary", "codex", "config.yaml");
|
|
1227
|
-
if (!await fileExists2(legacyConfigPath)) {
|
|
1228
|
-
if (options.json) {
|
|
1229
|
-
console.log(JSON.stringify({
|
|
1230
|
-
status: "no_config",
|
|
1231
|
-
message: "No legacy configuration file found",
|
|
1232
|
-
path: legacyConfigPath
|
|
1233
|
-
}));
|
|
1234
|
-
} else {
|
|
1235
|
-
console.log(chalk8.yellow("\u26A0 No legacy configuration file found."));
|
|
1236
|
-
console.log(chalk8.dim(` Expected: ${legacyConfigPath}`));
|
|
1237
|
-
console.log(chalk8.dim('\nRun "fractary codex init" to create a new v3.0 YAML configuration.'));
|
|
1238
|
-
}
|
|
1239
|
-
return;
|
|
1240
|
-
}
|
|
1241
|
-
if (await fileExists2(newConfigPath) && !options.dryRun) {
|
|
1242
|
-
if (options.json) {
|
|
1243
|
-
console.log(JSON.stringify({
|
|
1244
|
-
status: "already_migrated",
|
|
1245
|
-
message: "YAML configuration already exists",
|
|
1246
|
-
path: newConfigPath
|
|
1247
|
-
}));
|
|
1248
|
-
} else {
|
|
1249
|
-
console.log(chalk8.yellow("\u26A0 YAML configuration already exists."));
|
|
1250
|
-
console.log(chalk8.dim(` Path: ${newConfigPath}`));
|
|
1251
|
-
console.log(chalk8.dim('\nUse "fractary codex init --force" to recreate.'));
|
|
1252
|
-
}
|
|
1253
|
-
return;
|
|
1254
|
-
}
|
|
1255
|
-
const legacyContent = await readFileContent(legacyConfigPath);
|
|
1256
|
-
let legacyConfig;
|
|
1257
|
-
try {
|
|
1258
|
-
legacyConfig = JSON.parse(legacyContent);
|
|
1259
|
-
} catch (parseError) {
|
|
1260
|
-
console.error(chalk8.red("Error:"), "Invalid JSON in legacy config file.");
|
|
1261
|
-
console.error(chalk8.dim("Details:"), parseError.message);
|
|
1262
|
-
process.exit(1);
|
|
1263
|
-
}
|
|
1264
|
-
if (!options.json && !options.dryRun) {
|
|
1265
|
-
console.log(chalk8.blue("Migrating Codex configuration to v3.0 YAML format...\n"));
|
|
1266
|
-
}
|
|
1267
|
-
const migrationResult = await migrateConfig(
|
|
1268
|
-
legacyConfigPath,
|
|
1269
|
-
{
|
|
1270
|
-
createBackup: options.backup !== false,
|
|
1271
|
-
backupSuffix: (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")
|
|
1272
|
-
}
|
|
1273
|
-
);
|
|
1274
|
-
if (!options.json) {
|
|
1275
|
-
console.log(chalk8.bold("Legacy Configuration:"));
|
|
1276
|
-
console.log(chalk8.dim(` Path: ${legacyConfigPath}`));
|
|
1277
|
-
console.log(chalk8.dim(` Organization: ${legacyConfig.organization || legacyConfig.organizationSlug || "unknown"}`));
|
|
1278
|
-
console.log("");
|
|
1279
|
-
console.log(chalk8.bold("Migration Changes:"));
|
|
1280
|
-
console.log(chalk8.green(" + Format: JSON \u2192 YAML"));
|
|
1281
|
-
console.log(chalk8.green(" + Location: .fractary/plugins/codex/ \u2192 .fractary/"));
|
|
1282
|
-
console.log(chalk8.green(" + File: config.json \u2192 codex.yaml"));
|
|
1283
|
-
console.log(chalk8.green(" + Storage: Multi-provider configuration"));
|
|
1284
|
-
console.log(chalk8.green(" + Cache: Modern cache management"));
|
|
1285
|
-
console.log(chalk8.green(" + Types: Custom type registry"));
|
|
1286
|
-
if (migrationResult.warnings.length > 0) {
|
|
1287
|
-
console.log("");
|
|
1288
|
-
console.log(chalk8.yellow("Warnings:"));
|
|
1289
|
-
for (const warning of migrationResult.warnings) {
|
|
1290
|
-
console.log(chalk8.yellow(" \u26A0"), chalk8.dim(warning));
|
|
1291
|
-
}
|
|
1292
|
-
}
|
|
1293
|
-
console.log("");
|
|
1294
|
-
if (options.dryRun) {
|
|
1295
|
-
console.log(chalk8.blue("Dry run - no changes made."));
|
|
1296
|
-
console.log(chalk8.dim("Run without --dry-run to execute migration."));
|
|
1297
|
-
return;
|
|
1298
|
-
}
|
|
1299
|
-
}
|
|
1300
|
-
if (options.json) {
|
|
1301
|
-
const output = {
|
|
1302
|
-
status: options.dryRun ? "migration_ready" : "migrated",
|
|
1303
|
-
dryRun: options.dryRun || false,
|
|
1304
|
-
legacyConfig: {
|
|
1305
|
-
path: legacyConfigPath,
|
|
1306
|
-
organization: legacyConfig.organization || legacyConfig.organizationSlug
|
|
1307
|
-
},
|
|
1308
|
-
newConfig: {
|
|
1309
|
-
path: newConfigPath,
|
|
1310
|
-
organization: migrationResult.yamlConfig.organization
|
|
1311
|
-
},
|
|
1312
|
-
warnings: migrationResult.warnings,
|
|
1313
|
-
backupPath: migrationResult.backupPath
|
|
1314
|
-
};
|
|
1315
|
-
console.log(JSON.stringify(output, null, 2));
|
|
1316
|
-
if (options.dryRun) {
|
|
1317
|
-
return;
|
|
1318
|
-
}
|
|
1319
|
-
}
|
|
1320
|
-
if (!options.dryRun) {
|
|
1321
|
-
await writeYamlConfig(migrationResult.yamlConfig, newConfigPath);
|
|
1322
|
-
const configuredCacheDir = migrationResult.yamlConfig.cacheDir || ".fractary/codex/cache";
|
|
1323
|
-
const cacheDir = path5.join(process.cwd(), configuredCacheDir);
|
|
1324
|
-
await fs.mkdir(cacheDir, { recursive: true });
|
|
1325
|
-
const gitignoreResult = await ensureCachePathIgnored(process.cwd(), configuredCacheDir);
|
|
1326
|
-
const isCustomCachePath = normalizeCachePath(configuredCacheDir) !== DEFAULT_CACHE_DIR;
|
|
1327
|
-
if (!options.json) {
|
|
1328
|
-
console.log(chalk8.green("\u2713"), "YAML configuration created");
|
|
1329
|
-
console.log(chalk8.green("\u2713"), "Cache directory initialized");
|
|
1330
|
-
if (migrationResult.backupPath) {
|
|
1331
|
-
console.log(chalk8.green("\u2713"), "Legacy config backed up");
|
|
1332
|
-
}
|
|
1333
|
-
if (gitignoreResult.created) {
|
|
1334
|
-
console.log(chalk8.green("\u2713"), ".fractary/.gitignore created");
|
|
1335
|
-
} else if (gitignoreResult.updated) {
|
|
1336
|
-
console.log(chalk8.green("\u2713"), ".fractary/.gitignore updated with cache path");
|
|
1337
|
-
} else if (gitignoreResult.alreadyIgnored) {
|
|
1338
|
-
console.log(chalk8.green("\u2713"), "Cache path already in .fractary/.gitignore");
|
|
1339
|
-
}
|
|
1340
|
-
if (isCustomCachePath) {
|
|
1341
|
-
console.log("");
|
|
1342
|
-
console.log(chalk8.yellow("\u26A0 Custom cache directory detected:"), chalk8.dim(configuredCacheDir));
|
|
1343
|
-
console.log(chalk8.dim(" Ensure .fractary/.gitignore includes this path to avoid committing cache files."));
|
|
1344
|
-
}
|
|
1345
|
-
console.log("");
|
|
1346
|
-
console.log(chalk8.bold("New Configuration:"));
|
|
1347
|
-
console.log(chalk8.dim(` Path: ${newConfigPath}`));
|
|
1348
|
-
console.log(chalk8.dim(` Organization: ${migrationResult.yamlConfig.organization}`));
|
|
1349
|
-
console.log(chalk8.dim(` Cache: ${configuredCacheDir}`));
|
|
1350
|
-
console.log(chalk8.dim(` Storage Providers: ${migrationResult.yamlConfig.storage?.length || 0}`));
|
|
1351
|
-
console.log("");
|
|
1352
|
-
console.log(chalk8.bold("Next Steps:"));
|
|
1353
|
-
console.log(chalk8.dim(" 1. Review the new configuration: .fractary/codex/config.yaml"));
|
|
1354
|
-
console.log(chalk8.dim(' 2. Set your GitHub token: export GITHUB_TOKEN="your_token"'));
|
|
1355
|
-
console.log(chalk8.dim(" 3. Test fetching: fractary codex fetch codex://org/project/path"));
|
|
1356
|
-
if (migrationResult.backupPath) {
|
|
1357
|
-
console.log("");
|
|
1358
|
-
console.log(chalk8.dim(`Backup saved: ${path5.basename(migrationResult.backupPath)}`));
|
|
1359
|
-
}
|
|
1360
|
-
}
|
|
1361
|
-
}
|
|
1294
|
+
console.log(chalk7.green("\u2713"), chalk7.dim(".fractary/config.yaml (merged with existing)"));
|
|
1295
|
+
}
|
|
1296
|
+
console.log(chalk7.green("\n\u2713 Unified configuration initialized successfully!\n"));
|
|
1297
|
+
console.log(chalk7.bold("Configuration:"));
|
|
1298
|
+
console.log(chalk7.dim(` Organization: ${org}`));
|
|
1299
|
+
console.log(chalk7.dim(` Project: ${project}`));
|
|
1300
|
+
console.log(chalk7.dim(` Codex Repository: ${codexRepo}`));
|
|
1301
|
+
console.log(chalk7.dim(` Config: .fractary/config.yaml`));
|
|
1302
|
+
console.log(chalk7.bold("\nFile plugin sources:"));
|
|
1303
|
+
console.log(chalk7.dim(" - specs: .fractary/specs/ \u2192 S3"));
|
|
1304
|
+
console.log(chalk7.dim(" - logs: .fractary/logs/ \u2192 S3"));
|
|
1305
|
+
console.log(chalk7.bold("\nCodex plugin:"));
|
|
1306
|
+
console.log(chalk7.dim(" - Cache: .fractary/codex/cache/"));
|
|
1307
|
+
console.log(chalk7.dim(" - Dependencies: (none configured)"));
|
|
1308
|
+
console.log(chalk7.bold("\nGit Authentication:"));
|
|
1309
|
+
console.log(chalk7.dim(" Codex sync uses your existing git credentials."));
|
|
1310
|
+
console.log(chalk7.dim(" Ensure you have access to the codex repository:"));
|
|
1311
|
+
console.log(chalk7.dim(` gh repo view ${org}/${codexRepo}`));
|
|
1312
|
+
console.log(chalk7.dim(" Or set GITHUB_TOKEN environment variable."));
|
|
1313
|
+
console.log(chalk7.bold("\nNext steps:"));
|
|
1314
|
+
console.log(chalk7.dim(" 1. Verify codex repository access: gh repo view " + org + "/" + codexRepo));
|
|
1315
|
+
console.log(chalk7.dim(" 2. Configure AWS credentials for S3 access (if using file plugin)"));
|
|
1316
|
+
console.log(chalk7.dim(" 3. Edit .fractary/config.yaml to add external project dependencies"));
|
|
1317
|
+
console.log(chalk7.dim(" 4. Access current project files: codex://specs/SPEC-001.md"));
|
|
1318
|
+
console.log(chalk7.dim(" 5. Access external projects: codex://org/project/docs/README.md"));
|
|
1362
1319
|
} catch (error) {
|
|
1363
|
-
|
|
1364
|
-
console.log(JSON.stringify({
|
|
1365
|
-
status: "error",
|
|
1366
|
-
message: error.message
|
|
1367
|
-
}));
|
|
1368
|
-
} else {
|
|
1369
|
-
console.error(chalk8.red("Error:"), error.message);
|
|
1370
|
-
}
|
|
1320
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
1371
1321
|
process.exit(1);
|
|
1372
1322
|
}
|
|
1373
1323
|
});
|
|
@@ -1379,7 +1329,6 @@ function configCommand() {
|
|
|
1379
1329
|
const cmd = new Command("config");
|
|
1380
1330
|
cmd.description("Manage configuration");
|
|
1381
1331
|
cmd.addCommand(initCommand());
|
|
1382
|
-
cmd.addCommand(migrateCommand());
|
|
1383
1332
|
return cmd;
|
|
1384
1333
|
}
|
|
1385
1334
|
|
|
@@ -1403,8 +1352,8 @@ function cacheListCommand() {
|
|
|
1403
1352
|
if (options.json) {
|
|
1404
1353
|
console.log(JSON.stringify({ entries: 0, message: "Cache is empty" }));
|
|
1405
1354
|
} else {
|
|
1406
|
-
console.log(
|
|
1407
|
-
console.log(
|
|
1355
|
+
console.log(chalk7.yellow("Cache is empty."));
|
|
1356
|
+
console.log(chalk7.dim("Fetch some documents to populate the cache."));
|
|
1408
1357
|
}
|
|
1409
1358
|
return;
|
|
1410
1359
|
}
|
|
@@ -1418,25 +1367,25 @@ function cacheListCommand() {
|
|
|
1418
1367
|
}, null, 2));
|
|
1419
1368
|
return;
|
|
1420
1369
|
}
|
|
1421
|
-
console.log(
|
|
1422
|
-
console.log(
|
|
1423
|
-
console.log(` Total: ${
|
|
1424
|
-
console.log(` Fresh: ${
|
|
1425
|
-
console.log(` Stale: ${stats.staleCount > 0 ?
|
|
1426
|
-
console.log(` Expired: ${stats.expiredCount > 0 ?
|
|
1370
|
+
console.log(chalk7.bold("Cache Overview\n"));
|
|
1371
|
+
console.log(chalk7.bold("Entries:"));
|
|
1372
|
+
console.log(` Total: ${chalk7.cyan(stats.entryCount.toString())} entries`);
|
|
1373
|
+
console.log(` Fresh: ${chalk7.green(stats.freshCount.toString())} entries`);
|
|
1374
|
+
console.log(` Stale: ${stats.staleCount > 0 ? chalk7.yellow(stats.staleCount.toString()) : chalk7.dim("0")} entries`);
|
|
1375
|
+
console.log(` Expired: ${stats.expiredCount > 0 ? chalk7.red(stats.expiredCount.toString()) : chalk7.dim("0")} entries`);
|
|
1427
1376
|
console.log("");
|
|
1428
|
-
console.log(
|
|
1429
|
-
console.log(` Total size: ${
|
|
1377
|
+
console.log(chalk7.bold("Storage:"));
|
|
1378
|
+
console.log(` Total size: ${chalk7.cyan(formatSize(stats.totalSize))}`);
|
|
1430
1379
|
console.log("");
|
|
1431
1380
|
const healthPercent = stats.entryCount > 0 ? stats.freshCount / stats.entryCount * 100 : 100;
|
|
1432
|
-
const healthColor = healthPercent > 80 ?
|
|
1381
|
+
const healthColor = healthPercent > 80 ? chalk7.green : healthPercent > 50 ? chalk7.yellow : chalk7.red;
|
|
1433
1382
|
console.log(`Cache health: ${healthColor(`${healthPercent.toFixed(0)}% fresh`)}`);
|
|
1434
1383
|
console.log("");
|
|
1435
|
-
console.log(
|
|
1436
|
-
console.log(
|
|
1437
|
-
console.log(
|
|
1384
|
+
console.log(chalk7.dim("Note: Individual cache entries are managed by the SDK."));
|
|
1385
|
+
console.log(chalk7.dim('Use "fractary codex cache stats" for detailed statistics.'));
|
|
1386
|
+
console.log(chalk7.dim('Use "fractary codex cache clear" to clear cache entries.'));
|
|
1438
1387
|
} catch (error) {
|
|
1439
|
-
console.error(
|
|
1388
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
1440
1389
|
process.exit(1);
|
|
1441
1390
|
}
|
|
1442
1391
|
});
|
|
@@ -1452,7 +1401,7 @@ function cacheClearCommand() {
|
|
|
1452
1401
|
const client = await getClient();
|
|
1453
1402
|
const statsBefore = await client.getCacheStats();
|
|
1454
1403
|
if (statsBefore.entryCount === 0) {
|
|
1455
|
-
console.log(
|
|
1404
|
+
console.log(chalk7.yellow("Cache is already empty. Nothing to clear."));
|
|
1456
1405
|
return;
|
|
1457
1406
|
}
|
|
1458
1407
|
let pattern;
|
|
@@ -1461,45 +1410,45 @@ function cacheClearCommand() {
|
|
|
1461
1410
|
} else if (options.pattern) {
|
|
1462
1411
|
pattern = options.pattern;
|
|
1463
1412
|
} else {
|
|
1464
|
-
console.log(
|
|
1465
|
-
console.log(
|
|
1466
|
-
console.log(
|
|
1413
|
+
console.log(chalk7.yellow("Please specify what to clear:"));
|
|
1414
|
+
console.log(chalk7.dim(" --all Clear entire cache"));
|
|
1415
|
+
console.log(chalk7.dim(' --pattern Clear entries matching pattern (e.g., "codex://fractary/*")'));
|
|
1467
1416
|
console.log("");
|
|
1468
|
-
console.log(
|
|
1469
|
-
console.log(
|
|
1470
|
-
console.log(
|
|
1417
|
+
console.log(chalk7.dim("Examples:"));
|
|
1418
|
+
console.log(chalk7.dim(" fractary codex cache clear --all"));
|
|
1419
|
+
console.log(chalk7.dim(' fractary codex cache clear --pattern "codex://fractary/cli/*"'));
|
|
1471
1420
|
return;
|
|
1472
1421
|
}
|
|
1473
1422
|
if (options.dryRun) {
|
|
1474
|
-
console.log(
|
|
1423
|
+
console.log(chalk7.blue("Dry run - would clear:\n"));
|
|
1475
1424
|
if (pattern) {
|
|
1476
|
-
console.log(
|
|
1477
|
-
console.log(
|
|
1425
|
+
console.log(chalk7.dim(` Pattern: ${pattern}`));
|
|
1426
|
+
console.log(chalk7.dim(` This would invalidate matching cache entries`));
|
|
1478
1427
|
} else {
|
|
1479
|
-
console.log(
|
|
1428
|
+
console.log(chalk7.dim(` All cache entries (${statsBefore.entryCount} entries)`));
|
|
1480
1429
|
}
|
|
1481
|
-
console.log(
|
|
1430
|
+
console.log(chalk7.dim(`
|
|
1482
1431
|
Total size: ${formatSize2(statsBefore.totalSize)}`));
|
|
1483
1432
|
return;
|
|
1484
1433
|
}
|
|
1485
1434
|
if (pattern) {
|
|
1486
|
-
console.log(
|
|
1435
|
+
console.log(chalk7.blue(`Clearing cache entries matching pattern: ${pattern}
|
|
1487
1436
|
`));
|
|
1488
1437
|
await client.invalidateCache(pattern);
|
|
1489
1438
|
} else {
|
|
1490
|
-
console.log(
|
|
1439
|
+
console.log(chalk7.blue(`Clearing entire cache (${statsBefore.entryCount} entries)...
|
|
1491
1440
|
`));
|
|
1492
1441
|
await client.invalidateCache();
|
|
1493
1442
|
}
|
|
1494
1443
|
const statsAfter = await client.getCacheStats();
|
|
1495
1444
|
const entriesCleared = statsBefore.entryCount - statsAfter.entryCount;
|
|
1496
1445
|
const sizeFreed = statsBefore.totalSize - statsAfter.totalSize;
|
|
1497
|
-
console.log(
|
|
1446
|
+
console.log(chalk7.green(`\u2713 Cleared ${entriesCleared} entries (${formatSize2(sizeFreed)} freed)`));
|
|
1498
1447
|
if (statsAfter.entryCount > 0) {
|
|
1499
|
-
console.log(
|
|
1448
|
+
console.log(chalk7.dim(` Remaining: ${statsAfter.entryCount} entries (${formatSize2(statsAfter.totalSize)})`));
|
|
1500
1449
|
}
|
|
1501
1450
|
} catch (error) {
|
|
1502
|
-
console.error(
|
|
1451
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
1503
1452
|
process.exit(1);
|
|
1504
1453
|
}
|
|
1505
1454
|
});
|
|
@@ -1528,25 +1477,25 @@ function cacheStatsCommand() {
|
|
|
1528
1477
|
console.log(JSON.stringify(stats, null, 2));
|
|
1529
1478
|
return;
|
|
1530
1479
|
}
|
|
1531
|
-
console.log(
|
|
1532
|
-
console.log(
|
|
1533
|
-
console.log(` Total entries: ${
|
|
1534
|
-
console.log(` Total size: ${
|
|
1535
|
-
console.log(` Fresh entries: ${
|
|
1536
|
-
console.log(` Stale entries: ${stats.staleCount > 0 ?
|
|
1537
|
-
console.log(` Expired entries: ${stats.expiredCount > 0 ?
|
|
1480
|
+
console.log(chalk7.bold("Cache Statistics\n"));
|
|
1481
|
+
console.log(chalk7.bold("Overview"));
|
|
1482
|
+
console.log(` Total entries: ${chalk7.cyan(stats.entryCount.toString())}`);
|
|
1483
|
+
console.log(` Total size: ${chalk7.cyan(formatSize3(stats.totalSize))}`);
|
|
1484
|
+
console.log(` Fresh entries: ${chalk7.green(stats.freshCount.toString())}`);
|
|
1485
|
+
console.log(` Stale entries: ${stats.staleCount > 0 ? chalk7.yellow(stats.staleCount.toString()) : chalk7.dim("0")}`);
|
|
1486
|
+
console.log(` Expired entries: ${stats.expiredCount > 0 ? chalk7.red(stats.expiredCount.toString()) : chalk7.dim("0")}`);
|
|
1538
1487
|
console.log("");
|
|
1539
1488
|
const healthPercent = stats.entryCount > 0 ? stats.freshCount / stats.entryCount * 100 : 100;
|
|
1540
|
-
const healthColor = healthPercent > 80 ?
|
|
1489
|
+
const healthColor = healthPercent > 80 ? chalk7.green : healthPercent > 50 ? chalk7.yellow : chalk7.red;
|
|
1541
1490
|
console.log(`Cache health: ${healthColor(`${healthPercent.toFixed(0)}% fresh`)}`);
|
|
1542
1491
|
if (stats.expiredCount > 0) {
|
|
1543
|
-
console.log(
|
|
1492
|
+
console.log(chalk7.dim('\nRun "fractary codex cache clear --pattern <pattern>" to clean up entries.'));
|
|
1544
1493
|
}
|
|
1545
1494
|
if (stats.entryCount === 0) {
|
|
1546
|
-
console.log(
|
|
1495
|
+
console.log(chalk7.dim("\nNo cached entries. Fetch some documents to populate the cache."));
|
|
1547
1496
|
}
|
|
1548
1497
|
} catch (error) {
|
|
1549
|
-
console.error(
|
|
1498
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
1550
1499
|
process.exit(1);
|
|
1551
1500
|
}
|
|
1552
1501
|
});
|
|
@@ -1556,7 +1505,7 @@ function cacheStatsCommand() {
|
|
|
1556
1505
|
// src/commands/cache/health.ts
|
|
1557
1506
|
init_esm_shims();
|
|
1558
1507
|
init_migrate_config();
|
|
1559
|
-
async function
|
|
1508
|
+
async function fileExists2(filePath) {
|
|
1560
1509
|
try {
|
|
1561
1510
|
await fs.access(filePath);
|
|
1562
1511
|
return true;
|
|
@@ -1565,11 +1514,11 @@ async function fileExists3(filePath) {
|
|
|
1565
1514
|
}
|
|
1566
1515
|
}
|
|
1567
1516
|
async function checkConfiguration() {
|
|
1568
|
-
const configPath = path5.join(process.cwd(), ".fractary", "
|
|
1517
|
+
const configPath = path5.join(process.cwd(), ".fractary", "config.yaml");
|
|
1569
1518
|
const legacyConfigPath = path5.join(process.cwd(), ".fractary", "plugins", "codex", "config.json");
|
|
1570
1519
|
try {
|
|
1571
|
-
if (!await
|
|
1572
|
-
if (await
|
|
1520
|
+
if (!await fileExists2(configPath)) {
|
|
1521
|
+
if (await fileExists2(legacyConfigPath)) {
|
|
1573
1522
|
return {
|
|
1574
1523
|
name: "Configuration",
|
|
1575
1524
|
status: "warn",
|
|
@@ -1673,7 +1622,7 @@ async function checkCache() {
|
|
|
1673
1622
|
}
|
|
1674
1623
|
}
|
|
1675
1624
|
async function checkStorage() {
|
|
1676
|
-
const configPath = path5.join(process.cwd(), ".fractary", "
|
|
1625
|
+
const configPath = path5.join(process.cwd(), ".fractary", "config.yaml");
|
|
1677
1626
|
try {
|
|
1678
1627
|
const config = await readYamlConfig(configPath);
|
|
1679
1628
|
const providers = config.storage || [];
|
|
@@ -1682,7 +1631,7 @@ async function checkStorage() {
|
|
|
1682
1631
|
name: "Storage",
|
|
1683
1632
|
status: "warn",
|
|
1684
1633
|
message: "No storage providers configured",
|
|
1685
|
-
details: "Configure at least one provider in .fractary/
|
|
1634
|
+
details: "Configure at least one provider in .fractary/config.yaml"
|
|
1686
1635
|
};
|
|
1687
1636
|
}
|
|
1688
1637
|
const providerTypes = providers.map((p) => p.type).join(", ");
|
|
@@ -1763,32 +1712,32 @@ function healthCommand() {
|
|
|
1763
1712
|
}, null, 2));
|
|
1764
1713
|
return;
|
|
1765
1714
|
}
|
|
1766
|
-
console.log(
|
|
1715
|
+
console.log(chalk7.bold("Codex Health Check\n"));
|
|
1767
1716
|
for (const check of checks) {
|
|
1768
|
-
const icon = check.status === "pass" ?
|
|
1769
|
-
const statusColor = check.status === "pass" ?
|
|
1770
|
-
console.log(`${icon} ${
|
|
1717
|
+
const icon = check.status === "pass" ? chalk7.green("\u2713") : check.status === "warn" ? chalk7.yellow("\u26A0") : chalk7.red("\u2717");
|
|
1718
|
+
const statusColor = check.status === "pass" ? chalk7.green : check.status === "warn" ? chalk7.yellow : chalk7.red;
|
|
1719
|
+
console.log(`${icon} ${chalk7.bold(check.name)}`);
|
|
1771
1720
|
console.log(` ${statusColor(check.message)}`);
|
|
1772
1721
|
if (check.details) {
|
|
1773
|
-
console.log(` ${
|
|
1722
|
+
console.log(` ${chalk7.dim(check.details)}`);
|
|
1774
1723
|
}
|
|
1775
1724
|
console.log("");
|
|
1776
1725
|
}
|
|
1777
|
-
console.log(
|
|
1778
|
-
const overallStatus = failed > 0 ?
|
|
1726
|
+
console.log(chalk7.dim("\u2500".repeat(60)));
|
|
1727
|
+
const overallStatus = failed > 0 ? chalk7.red("UNHEALTHY") : warned > 0 ? chalk7.yellow("DEGRADED") : chalk7.green("HEALTHY");
|
|
1779
1728
|
console.log(`Status: ${overallStatus}`);
|
|
1780
|
-
console.log(
|
|
1729
|
+
console.log(chalk7.dim(`${passed} passed, ${warned} warnings, ${failed} failed`));
|
|
1781
1730
|
if (failed > 0 || warned > 0) {
|
|
1782
1731
|
console.log("");
|
|
1783
|
-
console.log(
|
|
1784
|
-
console.log(
|
|
1785
|
-
console.log(
|
|
1732
|
+
console.log(chalk7.dim("Run checks individually for more details:"));
|
|
1733
|
+
console.log(chalk7.dim(" fractary codex cache stats"));
|
|
1734
|
+
console.log(chalk7.dim(" fractary codex types list"));
|
|
1786
1735
|
}
|
|
1787
1736
|
if (failed > 0) {
|
|
1788
1737
|
process.exit(1);
|
|
1789
1738
|
}
|
|
1790
1739
|
} catch (error) {
|
|
1791
|
-
console.error(
|
|
1740
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
1792
1741
|
process.exit(1);
|
|
1793
1742
|
}
|
|
1794
1743
|
});
|
|
@@ -1836,8 +1785,8 @@ function syncCommand() {
|
|
|
1836
1785
|
try {
|
|
1837
1786
|
config = await readYamlConfig(configPath);
|
|
1838
1787
|
} catch (error) {
|
|
1839
|
-
console.error(
|
|
1840
|
-
console.log(
|
|
1788
|
+
console.error(chalk7.red("Error:"), "Codex not initialized.");
|
|
1789
|
+
console.log(chalk7.dim('Run "fractary codex init" first.'));
|
|
1841
1790
|
process.exit(1);
|
|
1842
1791
|
}
|
|
1843
1792
|
const { createSyncManager, createLocalStorage, detectCurrentProject } = await import('@fractary/codex');
|
|
@@ -1847,14 +1796,14 @@ function syncCommand() {
|
|
|
1847
1796
|
projectName = detected.project || void 0;
|
|
1848
1797
|
}
|
|
1849
1798
|
if (!projectName) {
|
|
1850
|
-
console.error(
|
|
1851
|
-
console.log(
|
|
1799
|
+
console.error(chalk7.red("Error:"), "Could not determine project name.");
|
|
1800
|
+
console.log(chalk7.dim("Provide project name as argument or run from a git repository."));
|
|
1852
1801
|
process.exit(1);
|
|
1853
1802
|
}
|
|
1854
1803
|
const validDirections = ["to-codex", "from-codex", "bidirectional"];
|
|
1855
1804
|
if (!validDirections.includes(options.direction)) {
|
|
1856
|
-
console.error(
|
|
1857
|
-
console.log(
|
|
1805
|
+
console.error(chalk7.red("Error:"), `Invalid direction: ${options.direction}`);
|
|
1806
|
+
console.log(chalk7.dim("Valid options: to-codex, from-codex, bidirectional"));
|
|
1858
1807
|
process.exit(1);
|
|
1859
1808
|
}
|
|
1860
1809
|
const direction = options.direction;
|
|
@@ -1911,13 +1860,13 @@ function syncCommand() {
|
|
|
1911
1860
|
});
|
|
1912
1861
|
matches.forEach((match) => matchedFilePaths.add(match));
|
|
1913
1862
|
} catch (error) {
|
|
1914
|
-
console.error(
|
|
1863
|
+
console.error(chalk7.yellow(`Warning: Invalid pattern "${pattern}": ${error.message}`));
|
|
1915
1864
|
}
|
|
1916
1865
|
}
|
|
1917
1866
|
const targetFiles = await Promise.all(
|
|
1918
1867
|
Array.from(matchedFilePaths).map(async (filePath) => {
|
|
1919
1868
|
const fullPath = path5.join(sourceDir, filePath);
|
|
1920
|
-
const stats = await import('fs/promises').then((
|
|
1869
|
+
const stats = await import('fs/promises').then((fs8) => fs8.stat(fullPath));
|
|
1921
1870
|
return {
|
|
1922
1871
|
path: filePath,
|
|
1923
1872
|
size: stats.size,
|
|
@@ -1939,14 +1888,14 @@ function syncCommand() {
|
|
|
1939
1888
|
try {
|
|
1940
1889
|
const { ensureCodexCloned: ensureCodexCloned2 } = await Promise.resolve().then(() => (init_codex_repository(), codex_repository_exports));
|
|
1941
1890
|
if (!options.json) {
|
|
1942
|
-
console.log(
|
|
1891
|
+
console.log(chalk7.blue("\u2139 Cloning/updating codex repository..."));
|
|
1943
1892
|
}
|
|
1944
1893
|
codexRepoPath = await ensureCodexCloned2(config, {
|
|
1945
1894
|
branch: targetBranch
|
|
1946
1895
|
});
|
|
1947
1896
|
if (!options.json) {
|
|
1948
|
-
console.log(
|
|
1949
|
-
console.log(
|
|
1897
|
+
console.log(chalk7.dim(` Codex cloned to: ${codexRepoPath}`));
|
|
1898
|
+
console.log(chalk7.dim(" Scanning for files routing to this project...\n"));
|
|
1950
1899
|
} else {
|
|
1951
1900
|
console.log(JSON.stringify({
|
|
1952
1901
|
info: "Routing-aware sync: cloned codex repository and scanning for files targeting this project",
|
|
@@ -1954,29 +1903,29 @@ function syncCommand() {
|
|
|
1954
1903
|
}, null, 2));
|
|
1955
1904
|
}
|
|
1956
1905
|
} catch (error) {
|
|
1957
|
-
console.error(
|
|
1958
|
-
console.error(
|
|
1959
|
-
console.log(
|
|
1906
|
+
console.error(chalk7.red("Error:"), "Failed to clone codex repository");
|
|
1907
|
+
console.error(chalk7.dim(` ${error.message}`));
|
|
1908
|
+
console.log(chalk7.yellow("\nTroubleshooting:"));
|
|
1960
1909
|
if (error.message.includes("Git command not found")) {
|
|
1961
|
-
console.log(
|
|
1962
|
-
console.log(
|
|
1910
|
+
console.log(chalk7.dim(" Git is not installed or not in PATH."));
|
|
1911
|
+
console.log(chalk7.dim(" Install git: https://git-scm.com/downloads"));
|
|
1963
1912
|
} else if (error.message.includes("authentication failed") || error.message.includes("Authentication failed")) {
|
|
1964
|
-
console.log(
|
|
1965
|
-
console.log(
|
|
1966
|
-
console.log(
|
|
1967
|
-
console.log(
|
|
1913
|
+
console.log(chalk7.dim(" GitHub authentication is required for private repositories."));
|
|
1914
|
+
console.log(chalk7.dim(" 1. Check auth status: gh auth status"));
|
|
1915
|
+
console.log(chalk7.dim(" 2. Login if needed: gh auth login"));
|
|
1916
|
+
console.log(chalk7.dim(" 3. Or set GITHUB_TOKEN environment variable"));
|
|
1968
1917
|
} else if (error.message.includes("Permission denied")) {
|
|
1969
|
-
console.log(
|
|
1970
|
-
console.log(
|
|
1971
|
-
console.log(
|
|
1918
|
+
console.log(chalk7.dim(" Permission denied accessing repository files."));
|
|
1919
|
+
console.log(chalk7.dim(" 1. Check file/directory permissions"));
|
|
1920
|
+
console.log(chalk7.dim(" 2. Ensure you have access to the repository"));
|
|
1972
1921
|
} else if (error.message.includes("not found") || error.message.includes("does not exist")) {
|
|
1973
|
-
console.log(
|
|
1974
|
-
console.log(
|
|
1975
|
-
console.log(
|
|
1922
|
+
console.log(chalk7.dim(` Repository not found: ${config.organization}/${config.codex_repository || "codex"}`));
|
|
1923
|
+
console.log(chalk7.dim(" 1. Verify the repository exists on GitHub"));
|
|
1924
|
+
console.log(chalk7.dim(" 2. Check organization and repository names in config"));
|
|
1976
1925
|
} else {
|
|
1977
|
-
console.log(
|
|
1978
|
-
console.log(
|
|
1979
|
-
console.log(
|
|
1926
|
+
console.log(chalk7.dim(" 1. Ensure git is installed: git --version"));
|
|
1927
|
+
console.log(chalk7.dim(" 2. Check GitHub auth: gh auth status"));
|
|
1928
|
+
console.log(chalk7.dim(` 3. Verify repo exists: ${config.organization}/${config.codex_repository || "codex"}`));
|
|
1980
1929
|
}
|
|
1981
1930
|
process.exit(1);
|
|
1982
1931
|
}
|
|
@@ -2006,7 +1955,7 @@ function syncCommand() {
|
|
|
2006
1955
|
synced: 0
|
|
2007
1956
|
}, null, 2));
|
|
2008
1957
|
} else {
|
|
2009
|
-
console.log(
|
|
1958
|
+
console.log(chalk7.yellow("No files to sync."));
|
|
2010
1959
|
}
|
|
2011
1960
|
return;
|
|
2012
1961
|
}
|
|
@@ -2049,98 +1998,98 @@ function syncCommand() {
|
|
|
2049
1998
|
}, null, 2));
|
|
2050
1999
|
return;
|
|
2051
2000
|
}
|
|
2052
|
-
console.log(
|
|
2053
|
-
console.log(` Project: ${
|
|
2054
|
-
console.log(` Organization: ${
|
|
2055
|
-
console.log(` Environment: ${
|
|
2056
|
-
console.log(` Direction: ${
|
|
2057
|
-
console.log(` Files: ${
|
|
2058
|
-
console.log(` Total size: ${
|
|
2001
|
+
console.log(chalk7.bold("Sync Plan\n"));
|
|
2002
|
+
console.log(` Project: ${chalk7.cyan(projectName)}`);
|
|
2003
|
+
console.log(` Organization: ${chalk7.cyan(config.organization)}`);
|
|
2004
|
+
console.log(` Environment: ${chalk7.cyan(options.env)} (${targetBranch})`);
|
|
2005
|
+
console.log(` Direction: ${chalk7.cyan(direction)}`);
|
|
2006
|
+
console.log(` Files: ${chalk7.cyan(plan.totalFiles.toString())}`);
|
|
2007
|
+
console.log(` Total size: ${chalk7.cyan(formatBytes(plan.totalBytes))}`);
|
|
2059
2008
|
if (plan.estimatedTime) {
|
|
2060
|
-
console.log(` Est. time: ${
|
|
2009
|
+
console.log(` Est. time: ${chalk7.dim(formatDuration(plan.estimatedTime))}`);
|
|
2061
2010
|
}
|
|
2062
2011
|
if (routingScan) {
|
|
2063
2012
|
console.log("");
|
|
2064
|
-
console.log(
|
|
2065
|
-
console.log(` Scanned: ${
|
|
2066
|
-
console.log(` Matched: ${
|
|
2067
|
-
console.log(` Source projects: ${
|
|
2013
|
+
console.log(chalk7.bold("Routing Statistics\n"));
|
|
2014
|
+
console.log(` Scanned: ${chalk7.cyan(routingScan.stats.totalScanned.toString())} files`);
|
|
2015
|
+
console.log(` Matched: ${chalk7.cyan(routingScan.stats.totalMatched.toString())} files`);
|
|
2016
|
+
console.log(` Source projects: ${chalk7.cyan(routingScan.stats.sourceProjects.length.toString())}`);
|
|
2068
2017
|
if (routingScan.stats.sourceProjects.length > 0) {
|
|
2069
|
-
console.log(
|
|
2018
|
+
console.log(chalk7.dim(` ${routingScan.stats.sourceProjects.slice(0, 5).join(", ")}`));
|
|
2070
2019
|
if (routingScan.stats.sourceProjects.length > 5) {
|
|
2071
|
-
console.log(
|
|
2020
|
+
console.log(chalk7.dim(` ... and ${routingScan.stats.sourceProjects.length - 5} more`));
|
|
2072
2021
|
}
|
|
2073
2022
|
}
|
|
2074
|
-
console.log(` Scan time: ${
|
|
2023
|
+
console.log(` Scan time: ${chalk7.dim(formatDuration(routingScan.stats.durationMs))}`);
|
|
2075
2024
|
}
|
|
2076
2025
|
console.log("");
|
|
2077
2026
|
if (plan.conflicts.length > 0) {
|
|
2078
|
-
console.log(
|
|
2027
|
+
console.log(chalk7.yellow(`\u26A0 ${plan.conflicts.length} conflicts detected:`));
|
|
2079
2028
|
for (const conflict of plan.conflicts.slice(0, 5)) {
|
|
2080
|
-
console.log(
|
|
2029
|
+
console.log(chalk7.yellow(` \u2022 ${conflict.path}`));
|
|
2081
2030
|
}
|
|
2082
2031
|
if (plan.conflicts.length > 5) {
|
|
2083
|
-
console.log(
|
|
2032
|
+
console.log(chalk7.dim(` ... and ${plan.conflicts.length - 5} more`));
|
|
2084
2033
|
}
|
|
2085
2034
|
console.log("");
|
|
2086
2035
|
}
|
|
2087
2036
|
if (plan.skipped.length > 0) {
|
|
2088
|
-
console.log(
|
|
2037
|
+
console.log(chalk7.dim(`${plan.skipped.length} files skipped (no changes)`));
|
|
2089
2038
|
console.log("");
|
|
2090
2039
|
}
|
|
2091
2040
|
if (options.dryRun) {
|
|
2092
|
-
console.log(
|
|
2041
|
+
console.log(chalk7.blue("Dry run - would sync:\n"));
|
|
2093
2042
|
const filesToShow = plan.files.slice(0, 10);
|
|
2094
2043
|
for (const file of filesToShow) {
|
|
2095
2044
|
const arrow = direction === "to-codex" ? "\u2192" : direction === "from-codex" ? "\u2190" : "\u2194";
|
|
2096
|
-
const opColor = file.operation === "create" ?
|
|
2045
|
+
const opColor = file.operation === "create" ? chalk7.green : file.operation === "update" ? chalk7.yellow : chalk7.dim;
|
|
2097
2046
|
console.log(
|
|
2098
|
-
|
|
2047
|
+
chalk7.dim(` ${arrow}`),
|
|
2099
2048
|
opColor(file.operation.padEnd(7)),
|
|
2100
2049
|
file.path,
|
|
2101
|
-
|
|
2050
|
+
chalk7.dim(`(${formatBytes(file.size || 0)})`)
|
|
2102
2051
|
);
|
|
2103
2052
|
}
|
|
2104
2053
|
if (plan.files.length > 10) {
|
|
2105
|
-
console.log(
|
|
2054
|
+
console.log(chalk7.dim(` ... and ${plan.files.length - 10} more files`));
|
|
2106
2055
|
}
|
|
2107
|
-
console.log(
|
|
2056
|
+
console.log(chalk7.dim(`
|
|
2108
2057
|
Total: ${plan.totalFiles} files (${formatBytes(plan.totalBytes)})`));
|
|
2109
|
-
console.log(
|
|
2058
|
+
console.log(chalk7.dim("Run without --dry-run to execute sync."));
|
|
2110
2059
|
return;
|
|
2111
2060
|
}
|
|
2112
|
-
console.log(
|
|
2061
|
+
console.log(chalk7.blue("Syncing...\n"));
|
|
2113
2062
|
const startTime = Date.now();
|
|
2114
2063
|
const result = await syncManager.executePlan(plan, syncOptions);
|
|
2115
2064
|
const duration = Date.now() - startTime;
|
|
2116
2065
|
console.log("");
|
|
2117
2066
|
if (result.success) {
|
|
2118
|
-
console.log(
|
|
2119
|
-
console.log(
|
|
2067
|
+
console.log(chalk7.green(`\u2713 Sync completed successfully`));
|
|
2068
|
+
console.log(chalk7.dim(` Synced: ${result.synced} files`));
|
|
2120
2069
|
if (result.skipped > 0) {
|
|
2121
|
-
console.log(
|
|
2070
|
+
console.log(chalk7.dim(` Skipped: ${result.skipped} files`));
|
|
2122
2071
|
}
|
|
2123
|
-
console.log(
|
|
2072
|
+
console.log(chalk7.dim(` Duration: ${formatDuration(duration)}`));
|
|
2124
2073
|
} else {
|
|
2125
|
-
console.log(
|
|
2126
|
-
console.log(
|
|
2127
|
-
console.log(
|
|
2074
|
+
console.log(chalk7.yellow(`\u26A0 Sync completed with errors`));
|
|
2075
|
+
console.log(chalk7.green(` Synced: ${result.synced} files`));
|
|
2076
|
+
console.log(chalk7.red(` Failed: ${result.failed} files`));
|
|
2128
2077
|
if (result.skipped > 0) {
|
|
2129
|
-
console.log(
|
|
2078
|
+
console.log(chalk7.dim(` Skipped: ${result.skipped} files`));
|
|
2130
2079
|
}
|
|
2131
2080
|
if (result.errors.length > 0) {
|
|
2132
2081
|
console.log("");
|
|
2133
|
-
console.log(
|
|
2082
|
+
console.log(chalk7.red("Errors:"));
|
|
2134
2083
|
for (const error of result.errors.slice(0, 5)) {
|
|
2135
|
-
console.log(
|
|
2084
|
+
console.log(chalk7.red(` \u2022 ${error.path}: ${error.error}`));
|
|
2136
2085
|
}
|
|
2137
2086
|
if (result.errors.length > 5) {
|
|
2138
|
-
console.log(
|
|
2087
|
+
console.log(chalk7.dim(` ... and ${result.errors.length - 5} more errors`));
|
|
2139
2088
|
}
|
|
2140
2089
|
}
|
|
2141
2090
|
}
|
|
2142
2091
|
} catch (error) {
|
|
2143
|
-
console.error(
|
|
2092
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
2144
2093
|
process.exit(1);
|
|
2145
2094
|
}
|
|
2146
2095
|
});
|
|
@@ -2192,35 +2141,35 @@ function typesListCommand() {
|
|
|
2192
2141
|
return;
|
|
2193
2142
|
}
|
|
2194
2143
|
if (types.length === 0) {
|
|
2195
|
-
console.log(
|
|
2144
|
+
console.log(chalk7.yellow("No types found."));
|
|
2196
2145
|
return;
|
|
2197
2146
|
}
|
|
2198
|
-
console.log(
|
|
2147
|
+
console.log(chalk7.bold("Artifact Types\n"));
|
|
2199
2148
|
const builtinTypes = types.filter((t) => registry.isBuiltIn(t.name));
|
|
2200
2149
|
const customTypes = types.filter((t) => !registry.isBuiltIn(t.name));
|
|
2201
2150
|
if (builtinTypes.length > 0 && !options.customOnly) {
|
|
2202
|
-
console.log(
|
|
2203
|
-
console.log(
|
|
2151
|
+
console.log(chalk7.bold("Built-in Types"));
|
|
2152
|
+
console.log(chalk7.dim("\u2500".repeat(70)));
|
|
2204
2153
|
for (const type of builtinTypes) {
|
|
2205
2154
|
const patternStr = type.patterns[0] || "";
|
|
2206
|
-
console.log(` ${
|
|
2207
|
-
console.log(` ${
|
|
2155
|
+
console.log(` ${chalk7.cyan(type.name.padEnd(12))} ${patternStr.padEnd(30)} ${chalk7.dim(`TTL: ${formatTtl(type.defaultTtl)}`)}`);
|
|
2156
|
+
console.log(` ${chalk7.dim(" ".repeat(12) + type.description)}`);
|
|
2208
2157
|
}
|
|
2209
2158
|
console.log("");
|
|
2210
2159
|
}
|
|
2211
2160
|
if (customTypes.length > 0 && !options.builtinOnly) {
|
|
2212
|
-
console.log(
|
|
2213
|
-
console.log(
|
|
2161
|
+
console.log(chalk7.bold("Custom Types"));
|
|
2162
|
+
console.log(chalk7.dim("\u2500".repeat(70)));
|
|
2214
2163
|
for (const type of customTypes) {
|
|
2215
2164
|
const patternStr = type.patterns[0] || "";
|
|
2216
|
-
console.log(` ${
|
|
2217
|
-
console.log(` ${
|
|
2165
|
+
console.log(` ${chalk7.green(type.name.padEnd(12))} ${patternStr.padEnd(30)} ${chalk7.dim(`TTL: ${formatTtl(type.defaultTtl)}`)}`);
|
|
2166
|
+
console.log(` ${chalk7.dim(" ".repeat(12) + type.description)}`);
|
|
2218
2167
|
}
|
|
2219
2168
|
console.log("");
|
|
2220
2169
|
}
|
|
2221
|
-
console.log(
|
|
2170
|
+
console.log(chalk7.dim(`Total: ${types.length} types (${builtinTypes.length} built-in, ${customTypes.length} custom)`));
|
|
2222
2171
|
} catch (error) {
|
|
2223
|
-
console.error(
|
|
2172
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
2224
2173
|
process.exit(1);
|
|
2225
2174
|
}
|
|
2226
2175
|
});
|
|
@@ -2243,8 +2192,8 @@ function typesShowCommand() {
|
|
|
2243
2192
|
const registry = client.getTypeRegistry();
|
|
2244
2193
|
const type = registry.get(name);
|
|
2245
2194
|
if (!type) {
|
|
2246
|
-
console.error(
|
|
2247
|
-
console.log(
|
|
2195
|
+
console.error(chalk7.red("Error:"), `Type "${name}" not found.`);
|
|
2196
|
+
console.log(chalk7.dim('Run "fractary codex types list" to see available types.'));
|
|
2248
2197
|
process.exit(1);
|
|
2249
2198
|
}
|
|
2250
2199
|
const isBuiltin = registry.isBuiltIn(name);
|
|
@@ -2263,39 +2212,39 @@ function typesShowCommand() {
|
|
|
2263
2212
|
}, null, 2));
|
|
2264
2213
|
return;
|
|
2265
2214
|
}
|
|
2266
|
-
const nameColor = isBuiltin ?
|
|
2267
|
-
console.log(
|
|
2215
|
+
const nameColor = isBuiltin ? chalk7.cyan : chalk7.green;
|
|
2216
|
+
console.log(chalk7.bold(`Type: ${nameColor(name)}
|
|
2268
2217
|
`));
|
|
2269
|
-
console.log(` ${
|
|
2270
|
-
console.log(` ${
|
|
2271
|
-
console.log(` ${
|
|
2218
|
+
console.log(` ${chalk7.dim("Source:")} ${isBuiltin ? "Built-in" : "Custom"}`);
|
|
2219
|
+
console.log(` ${chalk7.dim("Description:")} ${type.description}`);
|
|
2220
|
+
console.log(` ${chalk7.dim("TTL:")} ${formatTtl2(type.defaultTtl)} (${type.defaultTtl} seconds)`);
|
|
2272
2221
|
console.log("");
|
|
2273
|
-
console.log(
|
|
2222
|
+
console.log(chalk7.bold("Patterns"));
|
|
2274
2223
|
for (const pattern of type.patterns) {
|
|
2275
|
-
console.log(` ${
|
|
2224
|
+
console.log(` ${chalk7.dim("\u2022")} ${pattern}`);
|
|
2276
2225
|
}
|
|
2277
2226
|
if (type.archiveAfterDays !== null) {
|
|
2278
2227
|
console.log("");
|
|
2279
|
-
console.log(
|
|
2280
|
-
console.log(` ${
|
|
2281
|
-
console.log(` ${
|
|
2228
|
+
console.log(chalk7.bold("Archive Settings"));
|
|
2229
|
+
console.log(` ${chalk7.dim("After:")} ${type.archiveAfterDays} days`);
|
|
2230
|
+
console.log(` ${chalk7.dim("Storage:")} ${type.archiveStorage || "not set"}`);
|
|
2282
2231
|
}
|
|
2283
2232
|
if (type.syncPatterns && type.syncPatterns.length > 0) {
|
|
2284
2233
|
console.log("");
|
|
2285
|
-
console.log(
|
|
2234
|
+
console.log(chalk7.bold("Sync Patterns"));
|
|
2286
2235
|
for (const pattern of type.syncPatterns) {
|
|
2287
|
-
console.log(` ${
|
|
2236
|
+
console.log(` ${chalk7.dim("\u2022")} ${pattern}`);
|
|
2288
2237
|
}
|
|
2289
2238
|
}
|
|
2290
2239
|
if (type.excludePatterns && type.excludePatterns.length > 0) {
|
|
2291
2240
|
console.log("");
|
|
2292
|
-
console.log(
|
|
2241
|
+
console.log(chalk7.bold("Exclude Patterns"));
|
|
2293
2242
|
for (const pattern of type.excludePatterns) {
|
|
2294
|
-
console.log(` ${
|
|
2243
|
+
console.log(` ${chalk7.dim("\u2022")} ${pattern}`);
|
|
2295
2244
|
}
|
|
2296
2245
|
}
|
|
2297
2246
|
} catch (error) {
|
|
2298
|
-
console.error(
|
|
2247
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
2299
2248
|
process.exit(1);
|
|
2300
2249
|
}
|
|
2301
2250
|
});
|
|
@@ -2339,30 +2288,30 @@ function typesAddCommand() {
|
|
|
2339
2288
|
cmd.description("Add a custom artifact type").argument("<name>", "Type name (lowercase, alphanumeric with hyphens)").requiredOption("--pattern <glob>", "File pattern (glob syntax)").option("--ttl <duration>", 'Cache TTL (e.g., "24h", "7d")', "24h").option("--description <text>", "Type description").option("--json", "Output as JSON").action(async (name, options) => {
|
|
2340
2289
|
try {
|
|
2341
2290
|
if (!isValidTypeName(name)) {
|
|
2342
|
-
console.error(
|
|
2343
|
-
console.log(
|
|
2291
|
+
console.error(chalk7.red("Error:"), "Invalid type name.");
|
|
2292
|
+
console.log(chalk7.dim("Type name must be lowercase, start with a letter, and contain only letters, numbers, and hyphens."));
|
|
2344
2293
|
process.exit(1);
|
|
2345
2294
|
}
|
|
2346
2295
|
const client = await getClient();
|
|
2347
2296
|
const registry = client.getTypeRegistry();
|
|
2348
2297
|
if (registry.isBuiltIn(name)) {
|
|
2349
|
-
console.error(
|
|
2298
|
+
console.error(chalk7.red("Error:"), `Cannot override built-in type "${name}".`);
|
|
2350
2299
|
const builtinNames = registry.list().filter((t) => registry.isBuiltIn(t.name)).map((t) => t.name);
|
|
2351
|
-
console.log(
|
|
2300
|
+
console.log(chalk7.dim("Built-in types: " + builtinNames.join(", ")));
|
|
2352
2301
|
process.exit(1);
|
|
2353
2302
|
}
|
|
2354
2303
|
if (registry.has(name)) {
|
|
2355
|
-
console.error(
|
|
2356
|
-
console.log(
|
|
2304
|
+
console.error(chalk7.red("Error:"), `Custom type "${name}" already exists.`);
|
|
2305
|
+
console.log(chalk7.dim('Use "fractary codex types remove" first to remove it.'));
|
|
2357
2306
|
process.exit(1);
|
|
2358
2307
|
}
|
|
2359
2308
|
let ttlSeconds;
|
|
2360
2309
|
try {
|
|
2361
2310
|
ttlSeconds = parseTtl(options.ttl);
|
|
2362
2311
|
} catch {
|
|
2363
|
-
console.error(
|
|
2364
|
-
console.log(
|
|
2365
|
-
console.log(
|
|
2312
|
+
console.error(chalk7.red("Error:"), "Invalid TTL format.");
|
|
2313
|
+
console.log(chalk7.dim("Expected format: <number><unit> where unit is s (seconds), m (minutes), h (hours), or d (days)"));
|
|
2314
|
+
console.log(chalk7.dim("Examples: 30m, 24h, 7d"));
|
|
2366
2315
|
process.exit(1);
|
|
2367
2316
|
}
|
|
2368
2317
|
const configPath = path5.join(process.cwd(), ".fractary", "codex", "config.yaml");
|
|
@@ -2394,19 +2343,19 @@ function typesAddCommand() {
|
|
|
2394
2343
|
}, null, 2));
|
|
2395
2344
|
return;
|
|
2396
2345
|
}
|
|
2397
|
-
console.log(
|
|
2346
|
+
console.log(chalk7.green("\u2713"), `Added custom type "${chalk7.cyan(name)}"`);
|
|
2398
2347
|
console.log("");
|
|
2399
|
-
console.log(` ${
|
|
2400
|
-
console.log(` ${
|
|
2348
|
+
console.log(` ${chalk7.dim("Pattern:")} ${options.pattern}`);
|
|
2349
|
+
console.log(` ${chalk7.dim("TTL:")} ${formatTtl3(ttlSeconds)} (${ttlSeconds} seconds)`);
|
|
2401
2350
|
if (options.description) {
|
|
2402
|
-
console.log(` ${
|
|
2351
|
+
console.log(` ${chalk7.dim("Description:")} ${options.description}`);
|
|
2403
2352
|
}
|
|
2404
2353
|
console.log("");
|
|
2405
|
-
console.log(
|
|
2354
|
+
console.log(chalk7.dim("Note: Custom type will be available on next CLI invocation."));
|
|
2406
2355
|
} catch (error) {
|
|
2407
|
-
console.error(
|
|
2356
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
2408
2357
|
if (error.message.includes("Failed to load configuration")) {
|
|
2409
|
-
console.log(
|
|
2358
|
+
console.log(chalk7.dim('\nRun "fractary codex init" to create a configuration.'));
|
|
2410
2359
|
}
|
|
2411
2360
|
process.exit(1);
|
|
2412
2361
|
}
|
|
@@ -2424,20 +2373,20 @@ function typesRemoveCommand() {
|
|
|
2424
2373
|
const client = await getClient();
|
|
2425
2374
|
const registry = client.getTypeRegistry();
|
|
2426
2375
|
if (registry.isBuiltIn(name)) {
|
|
2427
|
-
console.error(
|
|
2428
|
-
console.log(
|
|
2376
|
+
console.error(chalk7.red("Error:"), `Cannot remove built-in type "${name}".`);
|
|
2377
|
+
console.log(chalk7.dim("Built-in types are permanent and cannot be removed."));
|
|
2429
2378
|
process.exit(1);
|
|
2430
2379
|
}
|
|
2431
2380
|
if (!registry.has(name)) {
|
|
2432
|
-
console.error(
|
|
2433
|
-
console.log(
|
|
2381
|
+
console.error(chalk7.red("Error:"), `Custom type "${name}" not found.`);
|
|
2382
|
+
console.log(chalk7.dim('Run "fractary codex types list --custom-only" to see custom types.'));
|
|
2434
2383
|
process.exit(1);
|
|
2435
2384
|
}
|
|
2436
2385
|
const typeInfo = registry.get(name);
|
|
2437
2386
|
const configPath = path5.join(process.cwd(), ".fractary", "codex", "config.yaml");
|
|
2438
2387
|
const config = await readYamlConfig(configPath);
|
|
2439
2388
|
if (!config.types?.custom?.[name]) {
|
|
2440
|
-
console.error(
|
|
2389
|
+
console.error(chalk7.red("Error:"), `Custom type "${name}" not found in configuration.`);
|
|
2441
2390
|
process.exit(1);
|
|
2442
2391
|
}
|
|
2443
2392
|
delete config.types.custom[name];
|
|
@@ -2461,17 +2410,17 @@ function typesRemoveCommand() {
|
|
|
2461
2410
|
}, null, 2));
|
|
2462
2411
|
return;
|
|
2463
2412
|
}
|
|
2464
|
-
console.log(
|
|
2413
|
+
console.log(chalk7.green("\u2713"), `Removed custom type "${chalk7.cyan(name)}"`);
|
|
2465
2414
|
console.log("");
|
|
2466
|
-
console.log(
|
|
2467
|
-
console.log(` ${
|
|
2468
|
-
console.log(` ${
|
|
2415
|
+
console.log(chalk7.dim("Removed configuration:"));
|
|
2416
|
+
console.log(` ${chalk7.dim("Pattern:")} ${typeInfo.patterns.join(", ")}`);
|
|
2417
|
+
console.log(` ${chalk7.dim("Description:")} ${typeInfo.description}`);
|
|
2469
2418
|
console.log("");
|
|
2470
|
-
console.log(
|
|
2419
|
+
console.log(chalk7.dim("Note: Custom type will be removed on next CLI invocation."));
|
|
2471
2420
|
} catch (error) {
|
|
2472
|
-
console.error(
|
|
2421
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
2473
2422
|
if (error.message.includes("Failed to load configuration")) {
|
|
2474
|
-
console.log(
|
|
2423
|
+
console.log(chalk7.dim('\nRun "fractary codex init" to create a configuration.'));
|
|
2475
2424
|
}
|
|
2476
2425
|
process.exit(1);
|
|
2477
2426
|
}
|