@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/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 chalk8 from 'chalk';
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(chalk8.red("Error: Invalid URI format"));
800
- console.log(chalk8.dim("Expected: codex://org/project/path/to/file.md"));
801
- console.log(chalk8.dim("Example: codex://fractary/codex/docs/api.md"));
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(chalk8.dim(`Fetching ${uri}...`));
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(chalk8.green("\u2713"), `Written to ${options.output}`);
828
- console.log(chalk8.dim(` Size: ${result.content.length} bytes`));
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(chalk8.dim(" Source: cache"));
830
+ console.log(chalk7.dim(" Source: cache"));
831
831
  } else {
832
- console.log(chalk8.dim(" Source: storage"));
832
+ console.log(chalk7.dim(" Source: storage"));
833
833
  }
834
834
  } else {
835
835
  if (result.fromCache && !options.bypassCache) {
836
- console.error(chalk8.green("\u2713"), chalk8.dim("from cache\n"));
836
+ console.error(chalk7.green("\u2713"), chalk7.dim("from cache\n"));
837
837
  } else {
838
- console.error(chalk8.green("\u2713"), chalk8.dim("fetched\n"));
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(chalk8.red("Error:"), error.message);
843
+ console.error(chalk7.red("Error:"), error.message);
844
844
  if (error.message.includes("Failed to load configuration")) {
845
- console.log(chalk8.dim('\nRun "fractary codex init" to create a configuration.'));
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(chalk8.dim('\nSet your GitHub token: export GITHUB_TOKEN="your_token"'));
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(chalk8.dim("\nThe document may not exist or you may not have access."));
850
- console.log(chalk8.dim("Check the URI and ensure your storage providers are configured correctly."));
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(chalk8.blue("Initializing unified Fractary configuration...\n"));
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(chalk8.yellow(`\u26A0 Could not detect organization, using: ${org}`));
1134
- console.log(chalk8.dim(" Use --org <slug> to specify explicitly\n"));
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(chalk8.dim(`Organization: ${chalk8.cyan(org)}
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(chalk8.dim(`Project: ${chalk8.cyan(project)}
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(chalk8.yellow(`\u26A0 Configuration already exists at .fractary/config.yaml`));
1149
- console.log(chalk8.dim("Merging with existing configuration...\n"));
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(chalk8.green("\u2713"), chalk8.dim(dir + "/"));
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(chalk8.green("\u2713"), chalk8.dim(".fractary/.gitignore (created)"));
1277
+ console.log(chalk7.green("\u2713"), chalk7.dim(".fractary/.gitignore (created)"));
1166
1278
  } else if (gitignoreResult.updated) {
1167
- console.log(chalk8.green("\u2713"), chalk8.dim(".fractary/.gitignore (updated)"));
1279
+ console.log(chalk7.green("\u2713"), chalk7.dim(".fractary/.gitignore (updated)"));
1168
1280
  } else {
1169
- console.log(chalk8.green("\u2713"), chalk8.dim(".fractary/.gitignore (exists)"));
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(chalk8.green("\u2713"), chalk8.dim(".fractary/config.yaml (created)"));
1292
+ console.log(chalk7.green("\u2713"), chalk7.dim(".fractary/config.yaml (created)"));
1180
1293
  } else if (result.merged) {
1181
- console.log(chalk8.green("\u2713"), chalk8.dim(".fractary/config.yaml (merged with existing)"));
1182
- }
1183
- console.log(chalk8.green("\n\u2713 Unified configuration initialized successfully!\n"));
1184
- console.log(chalk8.bold("Configuration:"));
1185
- console.log(chalk8.dim(` Organization: ${org}`));
1186
- console.log(chalk8.dim(` Project: ${project}`));
1187
- console.log(chalk8.dim(` Config: .fractary/config.yaml`));
1188
- console.log(chalk8.bold("\nFile plugin sources:"));
1189
- console.log(chalk8.dim(" - specs: .fractary/specs/ \u2192 S3"));
1190
- console.log(chalk8.dim(" - logs: .fractary/logs/ \u2192 S3"));
1191
- console.log(chalk8.bold("\nCodex plugin:"));
1192
- console.log(chalk8.dim(" - Cache: .fractary/codex/cache/"));
1193
- console.log(chalk8.dim(" - Dependencies: (none configured)"));
1194
- console.log(chalk8.bold("\nNext steps:"));
1195
- console.log(chalk8.dim(" 1. Configure AWS credentials for S3 access"));
1196
- console.log(chalk8.dim(" 2. Edit .fractary/config.yaml to add external project dependencies"));
1197
- console.log(chalk8.dim(" 3. Access current project files: codex://specs/SPEC-001.md"));
1198
- console.log(chalk8.dim(" 4. Access external projects: codex://org/project/docs/README.md"));
1199
- } catch (error) {
1200
- console.error(chalk8.red("Error:"), error.message);
1201
- process.exit(1);
1202
- }
1203
- });
1204
- return cmd;
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
- if (options.json) {
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(chalk8.yellow("Cache is empty."));
1407
- console.log(chalk8.dim("Fetch some documents to populate the cache."));
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(chalk8.bold("Cache Overview\n"));
1422
- console.log(chalk8.bold("Entries:"));
1423
- console.log(` Total: ${chalk8.cyan(stats.entryCount.toString())} entries`);
1424
- console.log(` Fresh: ${chalk8.green(stats.freshCount.toString())} entries`);
1425
- console.log(` Stale: ${stats.staleCount > 0 ? chalk8.yellow(stats.staleCount.toString()) : chalk8.dim("0")} entries`);
1426
- console.log(` Expired: ${stats.expiredCount > 0 ? chalk8.red(stats.expiredCount.toString()) : chalk8.dim("0")} entries`);
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(chalk8.bold("Storage:"));
1429
- console.log(` Total size: ${chalk8.cyan(formatSize(stats.totalSize))}`);
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 ? chalk8.green : healthPercent > 50 ? chalk8.yellow : chalk8.red;
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(chalk8.dim("Note: Individual cache entries are managed by the SDK."));
1436
- console.log(chalk8.dim('Use "fractary codex cache stats" for detailed statistics.'));
1437
- console.log(chalk8.dim('Use "fractary codex cache clear" to clear cache entries.'));
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(chalk8.red("Error:"), error.message);
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(chalk8.yellow("Cache is already empty. Nothing to clear."));
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(chalk8.yellow("Please specify what to clear:"));
1465
- console.log(chalk8.dim(" --all Clear entire cache"));
1466
- console.log(chalk8.dim(' --pattern Clear entries matching pattern (e.g., "codex://fractary/*")'));
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(chalk8.dim("Examples:"));
1469
- console.log(chalk8.dim(" fractary codex cache clear --all"));
1470
- console.log(chalk8.dim(' fractary codex cache clear --pattern "codex://fractary/cli/*"'));
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(chalk8.blue("Dry run - would clear:\n"));
1423
+ console.log(chalk7.blue("Dry run - would clear:\n"));
1475
1424
  if (pattern) {
1476
- console.log(chalk8.dim(` Pattern: ${pattern}`));
1477
- console.log(chalk8.dim(` This would invalidate matching cache entries`));
1425
+ console.log(chalk7.dim(` Pattern: ${pattern}`));
1426
+ console.log(chalk7.dim(` This would invalidate matching cache entries`));
1478
1427
  } else {
1479
- console.log(chalk8.dim(` All cache entries (${statsBefore.entryCount} entries)`));
1428
+ console.log(chalk7.dim(` All cache entries (${statsBefore.entryCount} entries)`));
1480
1429
  }
1481
- console.log(chalk8.dim(`
1430
+ console.log(chalk7.dim(`
1482
1431
  Total size: ${formatSize2(statsBefore.totalSize)}`));
1483
1432
  return;
1484
1433
  }
1485
1434
  if (pattern) {
1486
- console.log(chalk8.blue(`Clearing cache entries matching pattern: ${pattern}
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(chalk8.blue(`Clearing entire cache (${statsBefore.entryCount} entries)...
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(chalk8.green(`\u2713 Cleared ${entriesCleared} entries (${formatSize2(sizeFreed)} freed)`));
1446
+ console.log(chalk7.green(`\u2713 Cleared ${entriesCleared} entries (${formatSize2(sizeFreed)} freed)`));
1498
1447
  if (statsAfter.entryCount > 0) {
1499
- console.log(chalk8.dim(` Remaining: ${statsAfter.entryCount} entries (${formatSize2(statsAfter.totalSize)})`));
1448
+ console.log(chalk7.dim(` Remaining: ${statsAfter.entryCount} entries (${formatSize2(statsAfter.totalSize)})`));
1500
1449
  }
1501
1450
  } catch (error) {
1502
- console.error(chalk8.red("Error:"), error.message);
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(chalk8.bold("Cache Statistics\n"));
1532
- console.log(chalk8.bold("Overview"));
1533
- console.log(` Total entries: ${chalk8.cyan(stats.entryCount.toString())}`);
1534
- console.log(` Total size: ${chalk8.cyan(formatSize3(stats.totalSize))}`);
1535
- console.log(` Fresh entries: ${chalk8.green(stats.freshCount.toString())}`);
1536
- console.log(` Stale entries: ${stats.staleCount > 0 ? chalk8.yellow(stats.staleCount.toString()) : chalk8.dim("0")}`);
1537
- console.log(` Expired entries: ${stats.expiredCount > 0 ? chalk8.red(stats.expiredCount.toString()) : chalk8.dim("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 ? chalk8.green : healthPercent > 50 ? chalk8.yellow : chalk8.red;
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(chalk8.dim('\nRun "fractary codex cache clear --pattern <pattern>" to clean up entries.'));
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(chalk8.dim("\nNo cached entries. Fetch some documents to populate the cache."));
1495
+ console.log(chalk7.dim("\nNo cached entries. Fetch some documents to populate the cache."));
1547
1496
  }
1548
1497
  } catch (error) {
1549
- console.error(chalk8.red("Error:"), error.message);
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 fileExists3(filePath) {
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", "codex", "config.yaml");
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 fileExists3(configPath)) {
1572
- if (await fileExists3(legacyConfigPath)) {
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", "codex", "config.yaml");
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/codex/config.yaml"
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(chalk8.bold("Codex Health Check\n"));
1715
+ console.log(chalk7.bold("Codex Health Check\n"));
1767
1716
  for (const check of checks) {
1768
- const icon = check.status === "pass" ? chalk8.green("\u2713") : check.status === "warn" ? chalk8.yellow("\u26A0") : chalk8.red("\u2717");
1769
- const statusColor = check.status === "pass" ? chalk8.green : check.status === "warn" ? chalk8.yellow : chalk8.red;
1770
- console.log(`${icon} ${chalk8.bold(check.name)}`);
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(` ${chalk8.dim(check.details)}`);
1722
+ console.log(` ${chalk7.dim(check.details)}`);
1774
1723
  }
1775
1724
  console.log("");
1776
1725
  }
1777
- console.log(chalk8.dim("\u2500".repeat(60)));
1778
- const overallStatus = failed > 0 ? chalk8.red("UNHEALTHY") : warned > 0 ? chalk8.yellow("DEGRADED") : chalk8.green("HEALTHY");
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(chalk8.dim(`${passed} passed, ${warned} warnings, ${failed} failed`));
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(chalk8.dim("Run checks individually for more details:"));
1784
- console.log(chalk8.dim(" fractary codex cache stats"));
1785
- console.log(chalk8.dim(" fractary codex types list"));
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(chalk8.red("Error:"), error.message);
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(chalk8.red("Error:"), "Codex not initialized.");
1840
- console.log(chalk8.dim('Run "fractary codex init" first.'));
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(chalk8.red("Error:"), "Could not determine project name.");
1851
- console.log(chalk8.dim("Provide project name as argument or run from a git repository."));
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(chalk8.red("Error:"), `Invalid direction: ${options.direction}`);
1857
- console.log(chalk8.dim("Valid options: to-codex, from-codex, bidirectional"));
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(chalk8.yellow(`Warning: Invalid pattern "${pattern}": ${error.message}`));
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((fs9) => fs9.stat(fullPath));
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(chalk8.blue("\u2139 Cloning/updating codex repository..."));
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(chalk8.dim(` Codex cloned to: ${codexRepoPath}`));
1949
- console.log(chalk8.dim(" Scanning for files routing to this project...\n"));
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(chalk8.red("Error:"), "Failed to clone codex repository");
1958
- console.error(chalk8.dim(` ${error.message}`));
1959
- console.log(chalk8.yellow("\nTroubleshooting:"));
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(chalk8.dim(" Git is not installed or not in PATH."));
1962
- console.log(chalk8.dim(" Install git: https://git-scm.com/downloads"));
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(chalk8.dim(" GitHub authentication is required for private repositories."));
1965
- console.log(chalk8.dim(" 1. Check auth status: gh auth status"));
1966
- console.log(chalk8.dim(" 2. Login if needed: gh auth login"));
1967
- console.log(chalk8.dim(" 3. Or set GITHUB_TOKEN environment variable"));
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(chalk8.dim(" Permission denied accessing repository files."));
1970
- console.log(chalk8.dim(" 1. Check file/directory permissions"));
1971
- console.log(chalk8.dim(" 2. Ensure you have access to the repository"));
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(chalk8.dim(` Repository not found: ${config.organization}/${config.codex_repository || "codex"}`));
1974
- console.log(chalk8.dim(" 1. Verify the repository exists on GitHub"));
1975
- console.log(chalk8.dim(" 2. Check organization and repository names in config"));
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(chalk8.dim(" 1. Ensure git is installed: git --version"));
1978
- console.log(chalk8.dim(" 2. Check GitHub auth: gh auth status"));
1979
- console.log(chalk8.dim(` 3. Verify repo exists: ${config.organization}/${config.codex_repository || "codex"}`));
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(chalk8.yellow("No files to sync."));
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(chalk8.bold("Sync Plan\n"));
2053
- console.log(` Project: ${chalk8.cyan(projectName)}`);
2054
- console.log(` Organization: ${chalk8.cyan(config.organization)}`);
2055
- console.log(` Environment: ${chalk8.cyan(options.env)} (${targetBranch})`);
2056
- console.log(` Direction: ${chalk8.cyan(direction)}`);
2057
- console.log(` Files: ${chalk8.cyan(plan.totalFiles.toString())}`);
2058
- console.log(` Total size: ${chalk8.cyan(formatBytes(plan.totalBytes))}`);
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: ${chalk8.dim(formatDuration(plan.estimatedTime))}`);
2009
+ console.log(` Est. time: ${chalk7.dim(formatDuration(plan.estimatedTime))}`);
2061
2010
  }
2062
2011
  if (routingScan) {
2063
2012
  console.log("");
2064
- console.log(chalk8.bold("Routing Statistics\n"));
2065
- console.log(` Scanned: ${chalk8.cyan(routingScan.stats.totalScanned.toString())} files`);
2066
- console.log(` Matched: ${chalk8.cyan(routingScan.stats.totalMatched.toString())} files`);
2067
- console.log(` Source projects: ${chalk8.cyan(routingScan.stats.sourceProjects.length.toString())}`);
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(chalk8.dim(` ${routingScan.stats.sourceProjects.slice(0, 5).join(", ")}`));
2018
+ console.log(chalk7.dim(` ${routingScan.stats.sourceProjects.slice(0, 5).join(", ")}`));
2070
2019
  if (routingScan.stats.sourceProjects.length > 5) {
2071
- console.log(chalk8.dim(` ... and ${routingScan.stats.sourceProjects.length - 5} more`));
2020
+ console.log(chalk7.dim(` ... and ${routingScan.stats.sourceProjects.length - 5} more`));
2072
2021
  }
2073
2022
  }
2074
- console.log(` Scan time: ${chalk8.dim(formatDuration(routingScan.stats.durationMs))}`);
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(chalk8.yellow(`\u26A0 ${plan.conflicts.length} conflicts detected:`));
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(chalk8.yellow(` \u2022 ${conflict.path}`));
2029
+ console.log(chalk7.yellow(` \u2022 ${conflict.path}`));
2081
2030
  }
2082
2031
  if (plan.conflicts.length > 5) {
2083
- console.log(chalk8.dim(` ... and ${plan.conflicts.length - 5} more`));
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(chalk8.dim(`${plan.skipped.length} files skipped (no changes)`));
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(chalk8.blue("Dry run - would sync:\n"));
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" ? chalk8.green : file.operation === "update" ? chalk8.yellow : chalk8.dim;
2045
+ const opColor = file.operation === "create" ? chalk7.green : file.operation === "update" ? chalk7.yellow : chalk7.dim;
2097
2046
  console.log(
2098
- chalk8.dim(` ${arrow}`),
2047
+ chalk7.dim(` ${arrow}`),
2099
2048
  opColor(file.operation.padEnd(7)),
2100
2049
  file.path,
2101
- chalk8.dim(`(${formatBytes(file.size || 0)})`)
2050
+ chalk7.dim(`(${formatBytes(file.size || 0)})`)
2102
2051
  );
2103
2052
  }
2104
2053
  if (plan.files.length > 10) {
2105
- console.log(chalk8.dim(` ... and ${plan.files.length - 10} more files`));
2054
+ console.log(chalk7.dim(` ... and ${plan.files.length - 10} more files`));
2106
2055
  }
2107
- console.log(chalk8.dim(`
2056
+ console.log(chalk7.dim(`
2108
2057
  Total: ${plan.totalFiles} files (${formatBytes(plan.totalBytes)})`));
2109
- console.log(chalk8.dim("Run without --dry-run to execute sync."));
2058
+ console.log(chalk7.dim("Run without --dry-run to execute sync."));
2110
2059
  return;
2111
2060
  }
2112
- console.log(chalk8.blue("Syncing...\n"));
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(chalk8.green(`\u2713 Sync completed successfully`));
2119
- console.log(chalk8.dim(` Synced: ${result.synced} files`));
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(chalk8.dim(` Skipped: ${result.skipped} files`));
2070
+ console.log(chalk7.dim(` Skipped: ${result.skipped} files`));
2122
2071
  }
2123
- console.log(chalk8.dim(` Duration: ${formatDuration(duration)}`));
2072
+ console.log(chalk7.dim(` Duration: ${formatDuration(duration)}`));
2124
2073
  } else {
2125
- console.log(chalk8.yellow(`\u26A0 Sync completed with errors`));
2126
- console.log(chalk8.green(` Synced: ${result.synced} files`));
2127
- console.log(chalk8.red(` Failed: ${result.failed} files`));
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(chalk8.dim(` Skipped: ${result.skipped} files`));
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(chalk8.red("Errors:"));
2082
+ console.log(chalk7.red("Errors:"));
2134
2083
  for (const error of result.errors.slice(0, 5)) {
2135
- console.log(chalk8.red(` \u2022 ${error.path}: ${error.error}`));
2084
+ console.log(chalk7.red(` \u2022 ${error.path}: ${error.error}`));
2136
2085
  }
2137
2086
  if (result.errors.length > 5) {
2138
- console.log(chalk8.dim(` ... and ${result.errors.length - 5} more errors`));
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(chalk8.red("Error:"), error.message);
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(chalk8.yellow("No types found."));
2144
+ console.log(chalk7.yellow("No types found."));
2196
2145
  return;
2197
2146
  }
2198
- console.log(chalk8.bold("Artifact Types\n"));
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(chalk8.bold("Built-in Types"));
2203
- console.log(chalk8.dim("\u2500".repeat(70)));
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(` ${chalk8.cyan(type.name.padEnd(12))} ${patternStr.padEnd(30)} ${chalk8.dim(`TTL: ${formatTtl(type.defaultTtl)}`)}`);
2207
- console.log(` ${chalk8.dim(" ".repeat(12) + type.description)}`);
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(chalk8.bold("Custom Types"));
2213
- console.log(chalk8.dim("\u2500".repeat(70)));
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(` ${chalk8.green(type.name.padEnd(12))} ${patternStr.padEnd(30)} ${chalk8.dim(`TTL: ${formatTtl(type.defaultTtl)}`)}`);
2217
- console.log(` ${chalk8.dim(" ".repeat(12) + type.description)}`);
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(chalk8.dim(`Total: ${types.length} types (${builtinTypes.length} built-in, ${customTypes.length} custom)`));
2170
+ console.log(chalk7.dim(`Total: ${types.length} types (${builtinTypes.length} built-in, ${customTypes.length} custom)`));
2222
2171
  } catch (error) {
2223
- console.error(chalk8.red("Error:"), error.message);
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(chalk8.red("Error:"), `Type "${name}" not found.`);
2247
- console.log(chalk8.dim('Run "fractary codex types list" to see available types.'));
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 ? chalk8.cyan : chalk8.green;
2267
- console.log(chalk8.bold(`Type: ${nameColor(name)}
2215
+ const nameColor = isBuiltin ? chalk7.cyan : chalk7.green;
2216
+ console.log(chalk7.bold(`Type: ${nameColor(name)}
2268
2217
  `));
2269
- console.log(` ${chalk8.dim("Source:")} ${isBuiltin ? "Built-in" : "Custom"}`);
2270
- console.log(` ${chalk8.dim("Description:")} ${type.description}`);
2271
- console.log(` ${chalk8.dim("TTL:")} ${formatTtl2(type.defaultTtl)} (${type.defaultTtl} seconds)`);
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(chalk8.bold("Patterns"));
2222
+ console.log(chalk7.bold("Patterns"));
2274
2223
  for (const pattern of type.patterns) {
2275
- console.log(` ${chalk8.dim("\u2022")} ${pattern}`);
2224
+ console.log(` ${chalk7.dim("\u2022")} ${pattern}`);
2276
2225
  }
2277
2226
  if (type.archiveAfterDays !== null) {
2278
2227
  console.log("");
2279
- console.log(chalk8.bold("Archive Settings"));
2280
- console.log(` ${chalk8.dim("After:")} ${type.archiveAfterDays} days`);
2281
- console.log(` ${chalk8.dim("Storage:")} ${type.archiveStorage || "not set"}`);
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(chalk8.bold("Sync Patterns"));
2234
+ console.log(chalk7.bold("Sync Patterns"));
2286
2235
  for (const pattern of type.syncPatterns) {
2287
- console.log(` ${chalk8.dim("\u2022")} ${pattern}`);
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(chalk8.bold("Exclude Patterns"));
2241
+ console.log(chalk7.bold("Exclude Patterns"));
2293
2242
  for (const pattern of type.excludePatterns) {
2294
- console.log(` ${chalk8.dim("\u2022")} ${pattern}`);
2243
+ console.log(` ${chalk7.dim("\u2022")} ${pattern}`);
2295
2244
  }
2296
2245
  }
2297
2246
  } catch (error) {
2298
- console.error(chalk8.red("Error:"), error.message);
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(chalk8.red("Error:"), "Invalid type name.");
2343
- console.log(chalk8.dim("Type name must be lowercase, start with a letter, and contain only letters, numbers, and hyphens."));
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(chalk8.red("Error:"), `Cannot override built-in type "${name}".`);
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(chalk8.dim("Built-in types: " + builtinNames.join(", ")));
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(chalk8.red("Error:"), `Custom type "${name}" already exists.`);
2356
- console.log(chalk8.dim('Use "fractary codex types remove" first to remove it.'));
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(chalk8.red("Error:"), "Invalid TTL format.");
2364
- console.log(chalk8.dim("Expected format: <number><unit> where unit is s (seconds), m (minutes), h (hours), or d (days)"));
2365
- console.log(chalk8.dim("Examples: 30m, 24h, 7d"));
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(chalk8.green("\u2713"), `Added custom type "${chalk8.cyan(name)}"`);
2346
+ console.log(chalk7.green("\u2713"), `Added custom type "${chalk7.cyan(name)}"`);
2398
2347
  console.log("");
2399
- console.log(` ${chalk8.dim("Pattern:")} ${options.pattern}`);
2400
- console.log(` ${chalk8.dim("TTL:")} ${formatTtl3(ttlSeconds)} (${ttlSeconds} seconds)`);
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(` ${chalk8.dim("Description:")} ${options.description}`);
2351
+ console.log(` ${chalk7.dim("Description:")} ${options.description}`);
2403
2352
  }
2404
2353
  console.log("");
2405
- console.log(chalk8.dim("Note: Custom type will be available on next CLI invocation."));
2354
+ console.log(chalk7.dim("Note: Custom type will be available on next CLI invocation."));
2406
2355
  } catch (error) {
2407
- console.error(chalk8.red("Error:"), error.message);
2356
+ console.error(chalk7.red("Error:"), error.message);
2408
2357
  if (error.message.includes("Failed to load configuration")) {
2409
- console.log(chalk8.dim('\nRun "fractary codex init" to create a configuration.'));
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(chalk8.red("Error:"), `Cannot remove built-in type "${name}".`);
2428
- console.log(chalk8.dim("Built-in types are permanent and cannot be removed."));
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(chalk8.red("Error:"), `Custom type "${name}" not found.`);
2433
- console.log(chalk8.dim('Run "fractary codex types list --custom-only" to see custom types.'));
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(chalk8.red("Error:"), `Custom type "${name}" not found in configuration.`);
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(chalk8.green("\u2713"), `Removed custom type "${chalk8.cyan(name)}"`);
2413
+ console.log(chalk7.green("\u2713"), `Removed custom type "${chalk7.cyan(name)}"`);
2465
2414
  console.log("");
2466
- console.log(chalk8.dim("Removed configuration:"));
2467
- console.log(` ${chalk8.dim("Pattern:")} ${typeInfo.patterns.join(", ")}`);
2468
- console.log(` ${chalk8.dim("Description:")} ${typeInfo.description}`);
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(chalk8.dim("Note: Custom type will be removed on next CLI invocation."));
2419
+ console.log(chalk7.dim("Note: Custom type will be removed on next CLI invocation."));
2471
2420
  } catch (error) {
2472
- console.error(chalk8.red("Error:"), error.message);
2421
+ console.error(chalk7.red("Error:"), error.message);
2473
2422
  if (error.message.includes("Failed to load configuration")) {
2474
- console.log(chalk8.dim('\nRun "fractary codex init" to create a configuration.'));
2423
+ console.log(chalk7.dim('\nRun "fractary codex init" to create a configuration.'));
2475
2424
  }
2476
2425
  process.exit(1);
2477
2426
  }