@fractary/codex-cli 0.9.1 → 0.10.0
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 +235 -407
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +234 -406
- 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
|
}
|
|
@@ -999,7 +999,6 @@ var DEFAULT_FRACTARY_GITIGNORE = `# .fractary/.gitignore
|
|
|
999
999
|
codex/cache/
|
|
1000
1000
|
# ===== end fractary-codex =====
|
|
1001
1001
|
`;
|
|
1002
|
-
var DEFAULT_CACHE_DIR = "codex/cache/";
|
|
1003
1002
|
async function readFractaryGitignore(projectRoot) {
|
|
1004
1003
|
const gitignorePath = path5.join(projectRoot, ".fractary", ".gitignore");
|
|
1005
1004
|
try {
|
|
@@ -1114,7 +1113,7 @@ function initCommand() {
|
|
|
1114
1113
|
const cmd = new Command("init");
|
|
1115
1114
|
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) => {
|
|
1116
1115
|
try {
|
|
1117
|
-
console.log(
|
|
1116
|
+
console.log(chalk7.blue("Initializing unified Fractary configuration...\n"));
|
|
1118
1117
|
let org = options.org;
|
|
1119
1118
|
if (!org) {
|
|
1120
1119
|
org = await getOrgFromGitRemote();
|
|
@@ -1130,23 +1129,23 @@ function initCommand() {
|
|
|
1130
1129
|
}
|
|
1131
1130
|
if (!org) {
|
|
1132
1131
|
org = path5.basename(process.cwd()).split("-")[0] || "default";
|
|
1133
|
-
console.log(
|
|
1134
|
-
console.log(
|
|
1132
|
+
console.log(chalk7.yellow(`\u26A0 Could not detect organization, using: ${org}`));
|
|
1133
|
+
console.log(chalk7.dim(" Use --org <slug> to specify explicitly\n"));
|
|
1135
1134
|
} else {
|
|
1136
|
-
console.log(
|
|
1135
|
+
console.log(chalk7.dim(`Organization: ${chalk7.cyan(org)}
|
|
1137
1136
|
`));
|
|
1138
1137
|
}
|
|
1139
1138
|
let project = options.project;
|
|
1140
1139
|
if (!project) {
|
|
1141
1140
|
project = path5.basename(process.cwd());
|
|
1142
|
-
console.log(
|
|
1141
|
+
console.log(chalk7.dim(`Project: ${chalk7.cyan(project)}
|
|
1143
1142
|
`));
|
|
1144
1143
|
}
|
|
1145
1144
|
const configPath = path5.join(process.cwd(), ".fractary", "config.yaml");
|
|
1146
1145
|
const configExists = await fileExists(configPath);
|
|
1147
1146
|
if (configExists && !options.force) {
|
|
1148
|
-
console.log(
|
|
1149
|
-
console.log(
|
|
1147
|
+
console.log(chalk7.yellow(`\u26A0 Configuration already exists at .fractary/config.yaml`));
|
|
1148
|
+
console.log(chalk7.dim("Merging with existing configuration...\n"));
|
|
1150
1149
|
}
|
|
1151
1150
|
console.log("Creating directory structure...");
|
|
1152
1151
|
const dirs = [
|
|
@@ -1158,15 +1157,15 @@ function initCommand() {
|
|
|
1158
1157
|
];
|
|
1159
1158
|
for (const dir of dirs) {
|
|
1160
1159
|
await fs.mkdir(path5.join(process.cwd(), dir), { recursive: true });
|
|
1161
|
-
console.log(
|
|
1160
|
+
console.log(chalk7.green("\u2713"), chalk7.dim(dir + "/"));
|
|
1162
1161
|
}
|
|
1163
1162
|
const gitignoreResult = await ensureCachePathIgnored(process.cwd(), ".fractary/codex/cache");
|
|
1164
1163
|
if (gitignoreResult.created) {
|
|
1165
|
-
console.log(
|
|
1164
|
+
console.log(chalk7.green("\u2713"), chalk7.dim(".fractary/.gitignore (created)"));
|
|
1166
1165
|
} else if (gitignoreResult.updated) {
|
|
1167
|
-
console.log(
|
|
1166
|
+
console.log(chalk7.green("\u2713"), chalk7.dim(".fractary/.gitignore (updated)"));
|
|
1168
1167
|
} else {
|
|
1169
|
-
console.log(
|
|
1168
|
+
console.log(chalk7.green("\u2713"), chalk7.dim(".fractary/.gitignore (exists)"));
|
|
1170
1169
|
}
|
|
1171
1170
|
console.log("\nInitializing configuration...");
|
|
1172
1171
|
const result = await initializeUnifiedConfig(
|
|
@@ -1176,198 +1175,28 @@ function initCommand() {
|
|
|
1176
1175
|
{ force: options.force }
|
|
1177
1176
|
);
|
|
1178
1177
|
if (result.created) {
|
|
1179
|
-
console.log(
|
|
1178
|
+
console.log(chalk7.green("\u2713"), chalk7.dim(".fractary/config.yaml (created)"));
|
|
1180
1179
|
} 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(
|
|
1180
|
+
console.log(chalk7.green("\u2713"), chalk7.dim(".fractary/config.yaml (merged with existing)"));
|
|
1181
|
+
}
|
|
1182
|
+
console.log(chalk7.green("\n\u2713 Unified configuration initialized successfully!\n"));
|
|
1183
|
+
console.log(chalk7.bold("Configuration:"));
|
|
1184
|
+
console.log(chalk7.dim(` Organization: ${org}`));
|
|
1185
|
+
console.log(chalk7.dim(` Project: ${project}`));
|
|
1186
|
+
console.log(chalk7.dim(` Config: .fractary/config.yaml`));
|
|
1187
|
+
console.log(chalk7.bold("\nFile plugin sources:"));
|
|
1188
|
+
console.log(chalk7.dim(" - specs: .fractary/specs/ \u2192 S3"));
|
|
1189
|
+
console.log(chalk7.dim(" - logs: .fractary/logs/ \u2192 S3"));
|
|
1190
|
+
console.log(chalk7.bold("\nCodex plugin:"));
|
|
1191
|
+
console.log(chalk7.dim(" - Cache: .fractary/codex/cache/"));
|
|
1192
|
+
console.log(chalk7.dim(" - Dependencies: (none configured)"));
|
|
1193
|
+
console.log(chalk7.bold("\nNext steps:"));
|
|
1194
|
+
console.log(chalk7.dim(" 1. Configure AWS credentials for S3 access"));
|
|
1195
|
+
console.log(chalk7.dim(" 2. Edit .fractary/config.yaml to add external project dependencies"));
|
|
1196
|
+
console.log(chalk7.dim(" 3. Access current project files: codex://specs/SPEC-001.md"));
|
|
1197
|
+
console.log(chalk7.dim(" 4. Access external projects: codex://org/project/docs/README.md"));
|
|
1199
1198
|
} catch (error) {
|
|
1200
|
-
console.error(
|
|
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
|
-
}
|
|
1362
|
-
} 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
|
-
}
|
|
1199
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
1371
1200
|
process.exit(1);
|
|
1372
1201
|
}
|
|
1373
1202
|
});
|
|
@@ -1379,7 +1208,6 @@ function configCommand() {
|
|
|
1379
1208
|
const cmd = new Command("config");
|
|
1380
1209
|
cmd.description("Manage configuration");
|
|
1381
1210
|
cmd.addCommand(initCommand());
|
|
1382
|
-
cmd.addCommand(migrateCommand());
|
|
1383
1211
|
return cmd;
|
|
1384
1212
|
}
|
|
1385
1213
|
|
|
@@ -1403,8 +1231,8 @@ function cacheListCommand() {
|
|
|
1403
1231
|
if (options.json) {
|
|
1404
1232
|
console.log(JSON.stringify({ entries: 0, message: "Cache is empty" }));
|
|
1405
1233
|
} else {
|
|
1406
|
-
console.log(
|
|
1407
|
-
console.log(
|
|
1234
|
+
console.log(chalk7.yellow("Cache is empty."));
|
|
1235
|
+
console.log(chalk7.dim("Fetch some documents to populate the cache."));
|
|
1408
1236
|
}
|
|
1409
1237
|
return;
|
|
1410
1238
|
}
|
|
@@ -1418,25 +1246,25 @@ function cacheListCommand() {
|
|
|
1418
1246
|
}, null, 2));
|
|
1419
1247
|
return;
|
|
1420
1248
|
}
|
|
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 ?
|
|
1249
|
+
console.log(chalk7.bold("Cache Overview\n"));
|
|
1250
|
+
console.log(chalk7.bold("Entries:"));
|
|
1251
|
+
console.log(` Total: ${chalk7.cyan(stats.entryCount.toString())} entries`);
|
|
1252
|
+
console.log(` Fresh: ${chalk7.green(stats.freshCount.toString())} entries`);
|
|
1253
|
+
console.log(` Stale: ${stats.staleCount > 0 ? chalk7.yellow(stats.staleCount.toString()) : chalk7.dim("0")} entries`);
|
|
1254
|
+
console.log(` Expired: ${stats.expiredCount > 0 ? chalk7.red(stats.expiredCount.toString()) : chalk7.dim("0")} entries`);
|
|
1427
1255
|
console.log("");
|
|
1428
|
-
console.log(
|
|
1429
|
-
console.log(` Total size: ${
|
|
1256
|
+
console.log(chalk7.bold("Storage:"));
|
|
1257
|
+
console.log(` Total size: ${chalk7.cyan(formatSize(stats.totalSize))}`);
|
|
1430
1258
|
console.log("");
|
|
1431
1259
|
const healthPercent = stats.entryCount > 0 ? stats.freshCount / stats.entryCount * 100 : 100;
|
|
1432
|
-
const healthColor = healthPercent > 80 ?
|
|
1260
|
+
const healthColor = healthPercent > 80 ? chalk7.green : healthPercent > 50 ? chalk7.yellow : chalk7.red;
|
|
1433
1261
|
console.log(`Cache health: ${healthColor(`${healthPercent.toFixed(0)}% fresh`)}`);
|
|
1434
1262
|
console.log("");
|
|
1435
|
-
console.log(
|
|
1436
|
-
console.log(
|
|
1437
|
-
console.log(
|
|
1263
|
+
console.log(chalk7.dim("Note: Individual cache entries are managed by the SDK."));
|
|
1264
|
+
console.log(chalk7.dim('Use "fractary codex cache stats" for detailed statistics.'));
|
|
1265
|
+
console.log(chalk7.dim('Use "fractary codex cache clear" to clear cache entries.'));
|
|
1438
1266
|
} catch (error) {
|
|
1439
|
-
console.error(
|
|
1267
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
1440
1268
|
process.exit(1);
|
|
1441
1269
|
}
|
|
1442
1270
|
});
|
|
@@ -1452,7 +1280,7 @@ function cacheClearCommand() {
|
|
|
1452
1280
|
const client = await getClient();
|
|
1453
1281
|
const statsBefore = await client.getCacheStats();
|
|
1454
1282
|
if (statsBefore.entryCount === 0) {
|
|
1455
|
-
console.log(
|
|
1283
|
+
console.log(chalk7.yellow("Cache is already empty. Nothing to clear."));
|
|
1456
1284
|
return;
|
|
1457
1285
|
}
|
|
1458
1286
|
let pattern;
|
|
@@ -1461,45 +1289,45 @@ function cacheClearCommand() {
|
|
|
1461
1289
|
} else if (options.pattern) {
|
|
1462
1290
|
pattern = options.pattern;
|
|
1463
1291
|
} else {
|
|
1464
|
-
console.log(
|
|
1465
|
-
console.log(
|
|
1466
|
-
console.log(
|
|
1292
|
+
console.log(chalk7.yellow("Please specify what to clear:"));
|
|
1293
|
+
console.log(chalk7.dim(" --all Clear entire cache"));
|
|
1294
|
+
console.log(chalk7.dim(' --pattern Clear entries matching pattern (e.g., "codex://fractary/*")'));
|
|
1467
1295
|
console.log("");
|
|
1468
|
-
console.log(
|
|
1469
|
-
console.log(
|
|
1470
|
-
console.log(
|
|
1296
|
+
console.log(chalk7.dim("Examples:"));
|
|
1297
|
+
console.log(chalk7.dim(" fractary codex cache clear --all"));
|
|
1298
|
+
console.log(chalk7.dim(' fractary codex cache clear --pattern "codex://fractary/cli/*"'));
|
|
1471
1299
|
return;
|
|
1472
1300
|
}
|
|
1473
1301
|
if (options.dryRun) {
|
|
1474
|
-
console.log(
|
|
1302
|
+
console.log(chalk7.blue("Dry run - would clear:\n"));
|
|
1475
1303
|
if (pattern) {
|
|
1476
|
-
console.log(
|
|
1477
|
-
console.log(
|
|
1304
|
+
console.log(chalk7.dim(` Pattern: ${pattern}`));
|
|
1305
|
+
console.log(chalk7.dim(` This would invalidate matching cache entries`));
|
|
1478
1306
|
} else {
|
|
1479
|
-
console.log(
|
|
1307
|
+
console.log(chalk7.dim(` All cache entries (${statsBefore.entryCount} entries)`));
|
|
1480
1308
|
}
|
|
1481
|
-
console.log(
|
|
1309
|
+
console.log(chalk7.dim(`
|
|
1482
1310
|
Total size: ${formatSize2(statsBefore.totalSize)}`));
|
|
1483
1311
|
return;
|
|
1484
1312
|
}
|
|
1485
1313
|
if (pattern) {
|
|
1486
|
-
console.log(
|
|
1314
|
+
console.log(chalk7.blue(`Clearing cache entries matching pattern: ${pattern}
|
|
1487
1315
|
`));
|
|
1488
1316
|
await client.invalidateCache(pattern);
|
|
1489
1317
|
} else {
|
|
1490
|
-
console.log(
|
|
1318
|
+
console.log(chalk7.blue(`Clearing entire cache (${statsBefore.entryCount} entries)...
|
|
1491
1319
|
`));
|
|
1492
1320
|
await client.invalidateCache();
|
|
1493
1321
|
}
|
|
1494
1322
|
const statsAfter = await client.getCacheStats();
|
|
1495
1323
|
const entriesCleared = statsBefore.entryCount - statsAfter.entryCount;
|
|
1496
1324
|
const sizeFreed = statsBefore.totalSize - statsAfter.totalSize;
|
|
1497
|
-
console.log(
|
|
1325
|
+
console.log(chalk7.green(`\u2713 Cleared ${entriesCleared} entries (${formatSize2(sizeFreed)} freed)`));
|
|
1498
1326
|
if (statsAfter.entryCount > 0) {
|
|
1499
|
-
console.log(
|
|
1327
|
+
console.log(chalk7.dim(` Remaining: ${statsAfter.entryCount} entries (${formatSize2(statsAfter.totalSize)})`));
|
|
1500
1328
|
}
|
|
1501
1329
|
} catch (error) {
|
|
1502
|
-
console.error(
|
|
1330
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
1503
1331
|
process.exit(1);
|
|
1504
1332
|
}
|
|
1505
1333
|
});
|
|
@@ -1528,25 +1356,25 @@ function cacheStatsCommand() {
|
|
|
1528
1356
|
console.log(JSON.stringify(stats, null, 2));
|
|
1529
1357
|
return;
|
|
1530
1358
|
}
|
|
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 ?
|
|
1359
|
+
console.log(chalk7.bold("Cache Statistics\n"));
|
|
1360
|
+
console.log(chalk7.bold("Overview"));
|
|
1361
|
+
console.log(` Total entries: ${chalk7.cyan(stats.entryCount.toString())}`);
|
|
1362
|
+
console.log(` Total size: ${chalk7.cyan(formatSize3(stats.totalSize))}`);
|
|
1363
|
+
console.log(` Fresh entries: ${chalk7.green(stats.freshCount.toString())}`);
|
|
1364
|
+
console.log(` Stale entries: ${stats.staleCount > 0 ? chalk7.yellow(stats.staleCount.toString()) : chalk7.dim("0")}`);
|
|
1365
|
+
console.log(` Expired entries: ${stats.expiredCount > 0 ? chalk7.red(stats.expiredCount.toString()) : chalk7.dim("0")}`);
|
|
1538
1366
|
console.log("");
|
|
1539
1367
|
const healthPercent = stats.entryCount > 0 ? stats.freshCount / stats.entryCount * 100 : 100;
|
|
1540
|
-
const healthColor = healthPercent > 80 ?
|
|
1368
|
+
const healthColor = healthPercent > 80 ? chalk7.green : healthPercent > 50 ? chalk7.yellow : chalk7.red;
|
|
1541
1369
|
console.log(`Cache health: ${healthColor(`${healthPercent.toFixed(0)}% fresh`)}`);
|
|
1542
1370
|
if (stats.expiredCount > 0) {
|
|
1543
|
-
console.log(
|
|
1371
|
+
console.log(chalk7.dim('\nRun "fractary codex cache clear --pattern <pattern>" to clean up entries.'));
|
|
1544
1372
|
}
|
|
1545
1373
|
if (stats.entryCount === 0) {
|
|
1546
|
-
console.log(
|
|
1374
|
+
console.log(chalk7.dim("\nNo cached entries. Fetch some documents to populate the cache."));
|
|
1547
1375
|
}
|
|
1548
1376
|
} catch (error) {
|
|
1549
|
-
console.error(
|
|
1377
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
1550
1378
|
process.exit(1);
|
|
1551
1379
|
}
|
|
1552
1380
|
});
|
|
@@ -1556,7 +1384,7 @@ function cacheStatsCommand() {
|
|
|
1556
1384
|
// src/commands/cache/health.ts
|
|
1557
1385
|
init_esm_shims();
|
|
1558
1386
|
init_migrate_config();
|
|
1559
|
-
async function
|
|
1387
|
+
async function fileExists2(filePath) {
|
|
1560
1388
|
try {
|
|
1561
1389
|
await fs.access(filePath);
|
|
1562
1390
|
return true;
|
|
@@ -1565,11 +1393,11 @@ async function fileExists3(filePath) {
|
|
|
1565
1393
|
}
|
|
1566
1394
|
}
|
|
1567
1395
|
async function checkConfiguration() {
|
|
1568
|
-
const configPath = path5.join(process.cwd(), ".fractary", "
|
|
1396
|
+
const configPath = path5.join(process.cwd(), ".fractary", "config.yaml");
|
|
1569
1397
|
const legacyConfigPath = path5.join(process.cwd(), ".fractary", "plugins", "codex", "config.json");
|
|
1570
1398
|
try {
|
|
1571
|
-
if (!await
|
|
1572
|
-
if (await
|
|
1399
|
+
if (!await fileExists2(configPath)) {
|
|
1400
|
+
if (await fileExists2(legacyConfigPath)) {
|
|
1573
1401
|
return {
|
|
1574
1402
|
name: "Configuration",
|
|
1575
1403
|
status: "warn",
|
|
@@ -1673,7 +1501,7 @@ async function checkCache() {
|
|
|
1673
1501
|
}
|
|
1674
1502
|
}
|
|
1675
1503
|
async function checkStorage() {
|
|
1676
|
-
const configPath = path5.join(process.cwd(), ".fractary", "
|
|
1504
|
+
const configPath = path5.join(process.cwd(), ".fractary", "config.yaml");
|
|
1677
1505
|
try {
|
|
1678
1506
|
const config = await readYamlConfig(configPath);
|
|
1679
1507
|
const providers = config.storage || [];
|
|
@@ -1682,7 +1510,7 @@ async function checkStorage() {
|
|
|
1682
1510
|
name: "Storage",
|
|
1683
1511
|
status: "warn",
|
|
1684
1512
|
message: "No storage providers configured",
|
|
1685
|
-
details: "Configure at least one provider in .fractary/
|
|
1513
|
+
details: "Configure at least one provider in .fractary/config.yaml"
|
|
1686
1514
|
};
|
|
1687
1515
|
}
|
|
1688
1516
|
const providerTypes = providers.map((p) => p.type).join(", ");
|
|
@@ -1763,32 +1591,32 @@ function healthCommand() {
|
|
|
1763
1591
|
}, null, 2));
|
|
1764
1592
|
return;
|
|
1765
1593
|
}
|
|
1766
|
-
console.log(
|
|
1594
|
+
console.log(chalk7.bold("Codex Health Check\n"));
|
|
1767
1595
|
for (const check of checks) {
|
|
1768
|
-
const icon = check.status === "pass" ?
|
|
1769
|
-
const statusColor = check.status === "pass" ?
|
|
1770
|
-
console.log(`${icon} ${
|
|
1596
|
+
const icon = check.status === "pass" ? chalk7.green("\u2713") : check.status === "warn" ? chalk7.yellow("\u26A0") : chalk7.red("\u2717");
|
|
1597
|
+
const statusColor = check.status === "pass" ? chalk7.green : check.status === "warn" ? chalk7.yellow : chalk7.red;
|
|
1598
|
+
console.log(`${icon} ${chalk7.bold(check.name)}`);
|
|
1771
1599
|
console.log(` ${statusColor(check.message)}`);
|
|
1772
1600
|
if (check.details) {
|
|
1773
|
-
console.log(` ${
|
|
1601
|
+
console.log(` ${chalk7.dim(check.details)}`);
|
|
1774
1602
|
}
|
|
1775
1603
|
console.log("");
|
|
1776
1604
|
}
|
|
1777
|
-
console.log(
|
|
1778
|
-
const overallStatus = failed > 0 ?
|
|
1605
|
+
console.log(chalk7.dim("\u2500".repeat(60)));
|
|
1606
|
+
const overallStatus = failed > 0 ? chalk7.red("UNHEALTHY") : warned > 0 ? chalk7.yellow("DEGRADED") : chalk7.green("HEALTHY");
|
|
1779
1607
|
console.log(`Status: ${overallStatus}`);
|
|
1780
|
-
console.log(
|
|
1608
|
+
console.log(chalk7.dim(`${passed} passed, ${warned} warnings, ${failed} failed`));
|
|
1781
1609
|
if (failed > 0 || warned > 0) {
|
|
1782
1610
|
console.log("");
|
|
1783
|
-
console.log(
|
|
1784
|
-
console.log(
|
|
1785
|
-
console.log(
|
|
1611
|
+
console.log(chalk7.dim("Run checks individually for more details:"));
|
|
1612
|
+
console.log(chalk7.dim(" fractary codex cache stats"));
|
|
1613
|
+
console.log(chalk7.dim(" fractary codex types list"));
|
|
1786
1614
|
}
|
|
1787
1615
|
if (failed > 0) {
|
|
1788
1616
|
process.exit(1);
|
|
1789
1617
|
}
|
|
1790
1618
|
} catch (error) {
|
|
1791
|
-
console.error(
|
|
1619
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
1792
1620
|
process.exit(1);
|
|
1793
1621
|
}
|
|
1794
1622
|
});
|
|
@@ -1836,8 +1664,8 @@ function syncCommand() {
|
|
|
1836
1664
|
try {
|
|
1837
1665
|
config = await readYamlConfig(configPath);
|
|
1838
1666
|
} catch (error) {
|
|
1839
|
-
console.error(
|
|
1840
|
-
console.log(
|
|
1667
|
+
console.error(chalk7.red("Error:"), "Codex not initialized.");
|
|
1668
|
+
console.log(chalk7.dim('Run "fractary codex init" first.'));
|
|
1841
1669
|
process.exit(1);
|
|
1842
1670
|
}
|
|
1843
1671
|
const { createSyncManager, createLocalStorage, detectCurrentProject } = await import('@fractary/codex');
|
|
@@ -1847,14 +1675,14 @@ function syncCommand() {
|
|
|
1847
1675
|
projectName = detected.project || void 0;
|
|
1848
1676
|
}
|
|
1849
1677
|
if (!projectName) {
|
|
1850
|
-
console.error(
|
|
1851
|
-
console.log(
|
|
1678
|
+
console.error(chalk7.red("Error:"), "Could not determine project name.");
|
|
1679
|
+
console.log(chalk7.dim("Provide project name as argument or run from a git repository."));
|
|
1852
1680
|
process.exit(1);
|
|
1853
1681
|
}
|
|
1854
1682
|
const validDirections = ["to-codex", "from-codex", "bidirectional"];
|
|
1855
1683
|
if (!validDirections.includes(options.direction)) {
|
|
1856
|
-
console.error(
|
|
1857
|
-
console.log(
|
|
1684
|
+
console.error(chalk7.red("Error:"), `Invalid direction: ${options.direction}`);
|
|
1685
|
+
console.log(chalk7.dim("Valid options: to-codex, from-codex, bidirectional"));
|
|
1858
1686
|
process.exit(1);
|
|
1859
1687
|
}
|
|
1860
1688
|
const direction = options.direction;
|
|
@@ -1911,13 +1739,13 @@ function syncCommand() {
|
|
|
1911
1739
|
});
|
|
1912
1740
|
matches.forEach((match) => matchedFilePaths.add(match));
|
|
1913
1741
|
} catch (error) {
|
|
1914
|
-
console.error(
|
|
1742
|
+
console.error(chalk7.yellow(`Warning: Invalid pattern "${pattern}": ${error.message}`));
|
|
1915
1743
|
}
|
|
1916
1744
|
}
|
|
1917
1745
|
const targetFiles = await Promise.all(
|
|
1918
1746
|
Array.from(matchedFilePaths).map(async (filePath) => {
|
|
1919
1747
|
const fullPath = path5.join(sourceDir, filePath);
|
|
1920
|
-
const stats = await import('fs/promises').then((
|
|
1748
|
+
const stats = await import('fs/promises').then((fs8) => fs8.stat(fullPath));
|
|
1921
1749
|
return {
|
|
1922
1750
|
path: filePath,
|
|
1923
1751
|
size: stats.size,
|
|
@@ -1939,14 +1767,14 @@ function syncCommand() {
|
|
|
1939
1767
|
try {
|
|
1940
1768
|
const { ensureCodexCloned: ensureCodexCloned2 } = await Promise.resolve().then(() => (init_codex_repository(), codex_repository_exports));
|
|
1941
1769
|
if (!options.json) {
|
|
1942
|
-
console.log(
|
|
1770
|
+
console.log(chalk7.blue("\u2139 Cloning/updating codex repository..."));
|
|
1943
1771
|
}
|
|
1944
1772
|
codexRepoPath = await ensureCodexCloned2(config, {
|
|
1945
1773
|
branch: targetBranch
|
|
1946
1774
|
});
|
|
1947
1775
|
if (!options.json) {
|
|
1948
|
-
console.log(
|
|
1949
|
-
console.log(
|
|
1776
|
+
console.log(chalk7.dim(` Codex cloned to: ${codexRepoPath}`));
|
|
1777
|
+
console.log(chalk7.dim(" Scanning for files routing to this project...\n"));
|
|
1950
1778
|
} else {
|
|
1951
1779
|
console.log(JSON.stringify({
|
|
1952
1780
|
info: "Routing-aware sync: cloned codex repository and scanning for files targeting this project",
|
|
@@ -1954,29 +1782,29 @@ function syncCommand() {
|
|
|
1954
1782
|
}, null, 2));
|
|
1955
1783
|
}
|
|
1956
1784
|
} catch (error) {
|
|
1957
|
-
console.error(
|
|
1958
|
-
console.error(
|
|
1959
|
-
console.log(
|
|
1785
|
+
console.error(chalk7.red("Error:"), "Failed to clone codex repository");
|
|
1786
|
+
console.error(chalk7.dim(` ${error.message}`));
|
|
1787
|
+
console.log(chalk7.yellow("\nTroubleshooting:"));
|
|
1960
1788
|
if (error.message.includes("Git command not found")) {
|
|
1961
|
-
console.log(
|
|
1962
|
-
console.log(
|
|
1789
|
+
console.log(chalk7.dim(" Git is not installed or not in PATH."));
|
|
1790
|
+
console.log(chalk7.dim(" Install git: https://git-scm.com/downloads"));
|
|
1963
1791
|
} else if (error.message.includes("authentication failed") || error.message.includes("Authentication failed")) {
|
|
1964
|
-
console.log(
|
|
1965
|
-
console.log(
|
|
1966
|
-
console.log(
|
|
1967
|
-
console.log(
|
|
1792
|
+
console.log(chalk7.dim(" GitHub authentication is required for private repositories."));
|
|
1793
|
+
console.log(chalk7.dim(" 1. Check auth status: gh auth status"));
|
|
1794
|
+
console.log(chalk7.dim(" 2. Login if needed: gh auth login"));
|
|
1795
|
+
console.log(chalk7.dim(" 3. Or set GITHUB_TOKEN environment variable"));
|
|
1968
1796
|
} else if (error.message.includes("Permission denied")) {
|
|
1969
|
-
console.log(
|
|
1970
|
-
console.log(
|
|
1971
|
-
console.log(
|
|
1797
|
+
console.log(chalk7.dim(" Permission denied accessing repository files."));
|
|
1798
|
+
console.log(chalk7.dim(" 1. Check file/directory permissions"));
|
|
1799
|
+
console.log(chalk7.dim(" 2. Ensure you have access to the repository"));
|
|
1972
1800
|
} else if (error.message.includes("not found") || error.message.includes("does not exist")) {
|
|
1973
|
-
console.log(
|
|
1974
|
-
console.log(
|
|
1975
|
-
console.log(
|
|
1801
|
+
console.log(chalk7.dim(` Repository not found: ${config.organization}/${config.codex_repository || "codex"}`));
|
|
1802
|
+
console.log(chalk7.dim(" 1. Verify the repository exists on GitHub"));
|
|
1803
|
+
console.log(chalk7.dim(" 2. Check organization and repository names in config"));
|
|
1976
1804
|
} else {
|
|
1977
|
-
console.log(
|
|
1978
|
-
console.log(
|
|
1979
|
-
console.log(
|
|
1805
|
+
console.log(chalk7.dim(" 1. Ensure git is installed: git --version"));
|
|
1806
|
+
console.log(chalk7.dim(" 2. Check GitHub auth: gh auth status"));
|
|
1807
|
+
console.log(chalk7.dim(` 3. Verify repo exists: ${config.organization}/${config.codex_repository || "codex"}`));
|
|
1980
1808
|
}
|
|
1981
1809
|
process.exit(1);
|
|
1982
1810
|
}
|
|
@@ -2006,7 +1834,7 @@ function syncCommand() {
|
|
|
2006
1834
|
synced: 0
|
|
2007
1835
|
}, null, 2));
|
|
2008
1836
|
} else {
|
|
2009
|
-
console.log(
|
|
1837
|
+
console.log(chalk7.yellow("No files to sync."));
|
|
2010
1838
|
}
|
|
2011
1839
|
return;
|
|
2012
1840
|
}
|
|
@@ -2049,98 +1877,98 @@ function syncCommand() {
|
|
|
2049
1877
|
}, null, 2));
|
|
2050
1878
|
return;
|
|
2051
1879
|
}
|
|
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: ${
|
|
1880
|
+
console.log(chalk7.bold("Sync Plan\n"));
|
|
1881
|
+
console.log(` Project: ${chalk7.cyan(projectName)}`);
|
|
1882
|
+
console.log(` Organization: ${chalk7.cyan(config.organization)}`);
|
|
1883
|
+
console.log(` Environment: ${chalk7.cyan(options.env)} (${targetBranch})`);
|
|
1884
|
+
console.log(` Direction: ${chalk7.cyan(direction)}`);
|
|
1885
|
+
console.log(` Files: ${chalk7.cyan(plan.totalFiles.toString())}`);
|
|
1886
|
+
console.log(` Total size: ${chalk7.cyan(formatBytes(plan.totalBytes))}`);
|
|
2059
1887
|
if (plan.estimatedTime) {
|
|
2060
|
-
console.log(` Est. time: ${
|
|
1888
|
+
console.log(` Est. time: ${chalk7.dim(formatDuration(plan.estimatedTime))}`);
|
|
2061
1889
|
}
|
|
2062
1890
|
if (routingScan) {
|
|
2063
1891
|
console.log("");
|
|
2064
|
-
console.log(
|
|
2065
|
-
console.log(` Scanned: ${
|
|
2066
|
-
console.log(` Matched: ${
|
|
2067
|
-
console.log(` Source projects: ${
|
|
1892
|
+
console.log(chalk7.bold("Routing Statistics\n"));
|
|
1893
|
+
console.log(` Scanned: ${chalk7.cyan(routingScan.stats.totalScanned.toString())} files`);
|
|
1894
|
+
console.log(` Matched: ${chalk7.cyan(routingScan.stats.totalMatched.toString())} files`);
|
|
1895
|
+
console.log(` Source projects: ${chalk7.cyan(routingScan.stats.sourceProjects.length.toString())}`);
|
|
2068
1896
|
if (routingScan.stats.sourceProjects.length > 0) {
|
|
2069
|
-
console.log(
|
|
1897
|
+
console.log(chalk7.dim(` ${routingScan.stats.sourceProjects.slice(0, 5).join(", ")}`));
|
|
2070
1898
|
if (routingScan.stats.sourceProjects.length > 5) {
|
|
2071
|
-
console.log(
|
|
1899
|
+
console.log(chalk7.dim(` ... and ${routingScan.stats.sourceProjects.length - 5} more`));
|
|
2072
1900
|
}
|
|
2073
1901
|
}
|
|
2074
|
-
console.log(` Scan time: ${
|
|
1902
|
+
console.log(` Scan time: ${chalk7.dim(formatDuration(routingScan.stats.durationMs))}`);
|
|
2075
1903
|
}
|
|
2076
1904
|
console.log("");
|
|
2077
1905
|
if (plan.conflicts.length > 0) {
|
|
2078
|
-
console.log(
|
|
1906
|
+
console.log(chalk7.yellow(`\u26A0 ${plan.conflicts.length} conflicts detected:`));
|
|
2079
1907
|
for (const conflict of plan.conflicts.slice(0, 5)) {
|
|
2080
|
-
console.log(
|
|
1908
|
+
console.log(chalk7.yellow(` \u2022 ${conflict.path}`));
|
|
2081
1909
|
}
|
|
2082
1910
|
if (plan.conflicts.length > 5) {
|
|
2083
|
-
console.log(
|
|
1911
|
+
console.log(chalk7.dim(` ... and ${plan.conflicts.length - 5} more`));
|
|
2084
1912
|
}
|
|
2085
1913
|
console.log("");
|
|
2086
1914
|
}
|
|
2087
1915
|
if (plan.skipped.length > 0) {
|
|
2088
|
-
console.log(
|
|
1916
|
+
console.log(chalk7.dim(`${plan.skipped.length} files skipped (no changes)`));
|
|
2089
1917
|
console.log("");
|
|
2090
1918
|
}
|
|
2091
1919
|
if (options.dryRun) {
|
|
2092
|
-
console.log(
|
|
1920
|
+
console.log(chalk7.blue("Dry run - would sync:\n"));
|
|
2093
1921
|
const filesToShow = plan.files.slice(0, 10);
|
|
2094
1922
|
for (const file of filesToShow) {
|
|
2095
1923
|
const arrow = direction === "to-codex" ? "\u2192" : direction === "from-codex" ? "\u2190" : "\u2194";
|
|
2096
|
-
const opColor = file.operation === "create" ?
|
|
1924
|
+
const opColor = file.operation === "create" ? chalk7.green : file.operation === "update" ? chalk7.yellow : chalk7.dim;
|
|
2097
1925
|
console.log(
|
|
2098
|
-
|
|
1926
|
+
chalk7.dim(` ${arrow}`),
|
|
2099
1927
|
opColor(file.operation.padEnd(7)),
|
|
2100
1928
|
file.path,
|
|
2101
|
-
|
|
1929
|
+
chalk7.dim(`(${formatBytes(file.size || 0)})`)
|
|
2102
1930
|
);
|
|
2103
1931
|
}
|
|
2104
1932
|
if (plan.files.length > 10) {
|
|
2105
|
-
console.log(
|
|
1933
|
+
console.log(chalk7.dim(` ... and ${plan.files.length - 10} more files`));
|
|
2106
1934
|
}
|
|
2107
|
-
console.log(
|
|
1935
|
+
console.log(chalk7.dim(`
|
|
2108
1936
|
Total: ${plan.totalFiles} files (${formatBytes(plan.totalBytes)})`));
|
|
2109
|
-
console.log(
|
|
1937
|
+
console.log(chalk7.dim("Run without --dry-run to execute sync."));
|
|
2110
1938
|
return;
|
|
2111
1939
|
}
|
|
2112
|
-
console.log(
|
|
1940
|
+
console.log(chalk7.blue("Syncing...\n"));
|
|
2113
1941
|
const startTime = Date.now();
|
|
2114
1942
|
const result = await syncManager.executePlan(plan, syncOptions);
|
|
2115
1943
|
const duration = Date.now() - startTime;
|
|
2116
1944
|
console.log("");
|
|
2117
1945
|
if (result.success) {
|
|
2118
|
-
console.log(
|
|
2119
|
-
console.log(
|
|
1946
|
+
console.log(chalk7.green(`\u2713 Sync completed successfully`));
|
|
1947
|
+
console.log(chalk7.dim(` Synced: ${result.synced} files`));
|
|
2120
1948
|
if (result.skipped > 0) {
|
|
2121
|
-
console.log(
|
|
1949
|
+
console.log(chalk7.dim(` Skipped: ${result.skipped} files`));
|
|
2122
1950
|
}
|
|
2123
|
-
console.log(
|
|
1951
|
+
console.log(chalk7.dim(` Duration: ${formatDuration(duration)}`));
|
|
2124
1952
|
} else {
|
|
2125
|
-
console.log(
|
|
2126
|
-
console.log(
|
|
2127
|
-
console.log(
|
|
1953
|
+
console.log(chalk7.yellow(`\u26A0 Sync completed with errors`));
|
|
1954
|
+
console.log(chalk7.green(` Synced: ${result.synced} files`));
|
|
1955
|
+
console.log(chalk7.red(` Failed: ${result.failed} files`));
|
|
2128
1956
|
if (result.skipped > 0) {
|
|
2129
|
-
console.log(
|
|
1957
|
+
console.log(chalk7.dim(` Skipped: ${result.skipped} files`));
|
|
2130
1958
|
}
|
|
2131
1959
|
if (result.errors.length > 0) {
|
|
2132
1960
|
console.log("");
|
|
2133
|
-
console.log(
|
|
1961
|
+
console.log(chalk7.red("Errors:"));
|
|
2134
1962
|
for (const error of result.errors.slice(0, 5)) {
|
|
2135
|
-
console.log(
|
|
1963
|
+
console.log(chalk7.red(` \u2022 ${error.path}: ${error.error}`));
|
|
2136
1964
|
}
|
|
2137
1965
|
if (result.errors.length > 5) {
|
|
2138
|
-
console.log(
|
|
1966
|
+
console.log(chalk7.dim(` ... and ${result.errors.length - 5} more errors`));
|
|
2139
1967
|
}
|
|
2140
1968
|
}
|
|
2141
1969
|
}
|
|
2142
1970
|
} catch (error) {
|
|
2143
|
-
console.error(
|
|
1971
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
2144
1972
|
process.exit(1);
|
|
2145
1973
|
}
|
|
2146
1974
|
});
|
|
@@ -2192,35 +2020,35 @@ function typesListCommand() {
|
|
|
2192
2020
|
return;
|
|
2193
2021
|
}
|
|
2194
2022
|
if (types.length === 0) {
|
|
2195
|
-
console.log(
|
|
2023
|
+
console.log(chalk7.yellow("No types found."));
|
|
2196
2024
|
return;
|
|
2197
2025
|
}
|
|
2198
|
-
console.log(
|
|
2026
|
+
console.log(chalk7.bold("Artifact Types\n"));
|
|
2199
2027
|
const builtinTypes = types.filter((t) => registry.isBuiltIn(t.name));
|
|
2200
2028
|
const customTypes = types.filter((t) => !registry.isBuiltIn(t.name));
|
|
2201
2029
|
if (builtinTypes.length > 0 && !options.customOnly) {
|
|
2202
|
-
console.log(
|
|
2203
|
-
console.log(
|
|
2030
|
+
console.log(chalk7.bold("Built-in Types"));
|
|
2031
|
+
console.log(chalk7.dim("\u2500".repeat(70)));
|
|
2204
2032
|
for (const type of builtinTypes) {
|
|
2205
2033
|
const patternStr = type.patterns[0] || "";
|
|
2206
|
-
console.log(` ${
|
|
2207
|
-
console.log(` ${
|
|
2034
|
+
console.log(` ${chalk7.cyan(type.name.padEnd(12))} ${patternStr.padEnd(30)} ${chalk7.dim(`TTL: ${formatTtl(type.defaultTtl)}`)}`);
|
|
2035
|
+
console.log(` ${chalk7.dim(" ".repeat(12) + type.description)}`);
|
|
2208
2036
|
}
|
|
2209
2037
|
console.log("");
|
|
2210
2038
|
}
|
|
2211
2039
|
if (customTypes.length > 0 && !options.builtinOnly) {
|
|
2212
|
-
console.log(
|
|
2213
|
-
console.log(
|
|
2040
|
+
console.log(chalk7.bold("Custom Types"));
|
|
2041
|
+
console.log(chalk7.dim("\u2500".repeat(70)));
|
|
2214
2042
|
for (const type of customTypes) {
|
|
2215
2043
|
const patternStr = type.patterns[0] || "";
|
|
2216
|
-
console.log(` ${
|
|
2217
|
-
console.log(` ${
|
|
2044
|
+
console.log(` ${chalk7.green(type.name.padEnd(12))} ${patternStr.padEnd(30)} ${chalk7.dim(`TTL: ${formatTtl(type.defaultTtl)}`)}`);
|
|
2045
|
+
console.log(` ${chalk7.dim(" ".repeat(12) + type.description)}`);
|
|
2218
2046
|
}
|
|
2219
2047
|
console.log("");
|
|
2220
2048
|
}
|
|
2221
|
-
console.log(
|
|
2049
|
+
console.log(chalk7.dim(`Total: ${types.length} types (${builtinTypes.length} built-in, ${customTypes.length} custom)`));
|
|
2222
2050
|
} catch (error) {
|
|
2223
|
-
console.error(
|
|
2051
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
2224
2052
|
process.exit(1);
|
|
2225
2053
|
}
|
|
2226
2054
|
});
|
|
@@ -2243,8 +2071,8 @@ function typesShowCommand() {
|
|
|
2243
2071
|
const registry = client.getTypeRegistry();
|
|
2244
2072
|
const type = registry.get(name);
|
|
2245
2073
|
if (!type) {
|
|
2246
|
-
console.error(
|
|
2247
|
-
console.log(
|
|
2074
|
+
console.error(chalk7.red("Error:"), `Type "${name}" not found.`);
|
|
2075
|
+
console.log(chalk7.dim('Run "fractary codex types list" to see available types.'));
|
|
2248
2076
|
process.exit(1);
|
|
2249
2077
|
}
|
|
2250
2078
|
const isBuiltin = registry.isBuiltIn(name);
|
|
@@ -2263,39 +2091,39 @@ function typesShowCommand() {
|
|
|
2263
2091
|
}, null, 2));
|
|
2264
2092
|
return;
|
|
2265
2093
|
}
|
|
2266
|
-
const nameColor = isBuiltin ?
|
|
2267
|
-
console.log(
|
|
2094
|
+
const nameColor = isBuiltin ? chalk7.cyan : chalk7.green;
|
|
2095
|
+
console.log(chalk7.bold(`Type: ${nameColor(name)}
|
|
2268
2096
|
`));
|
|
2269
|
-
console.log(` ${
|
|
2270
|
-
console.log(` ${
|
|
2271
|
-
console.log(` ${
|
|
2097
|
+
console.log(` ${chalk7.dim("Source:")} ${isBuiltin ? "Built-in" : "Custom"}`);
|
|
2098
|
+
console.log(` ${chalk7.dim("Description:")} ${type.description}`);
|
|
2099
|
+
console.log(` ${chalk7.dim("TTL:")} ${formatTtl2(type.defaultTtl)} (${type.defaultTtl} seconds)`);
|
|
2272
2100
|
console.log("");
|
|
2273
|
-
console.log(
|
|
2101
|
+
console.log(chalk7.bold("Patterns"));
|
|
2274
2102
|
for (const pattern of type.patterns) {
|
|
2275
|
-
console.log(` ${
|
|
2103
|
+
console.log(` ${chalk7.dim("\u2022")} ${pattern}`);
|
|
2276
2104
|
}
|
|
2277
2105
|
if (type.archiveAfterDays !== null) {
|
|
2278
2106
|
console.log("");
|
|
2279
|
-
console.log(
|
|
2280
|
-
console.log(` ${
|
|
2281
|
-
console.log(` ${
|
|
2107
|
+
console.log(chalk7.bold("Archive Settings"));
|
|
2108
|
+
console.log(` ${chalk7.dim("After:")} ${type.archiveAfterDays} days`);
|
|
2109
|
+
console.log(` ${chalk7.dim("Storage:")} ${type.archiveStorage || "not set"}`);
|
|
2282
2110
|
}
|
|
2283
2111
|
if (type.syncPatterns && type.syncPatterns.length > 0) {
|
|
2284
2112
|
console.log("");
|
|
2285
|
-
console.log(
|
|
2113
|
+
console.log(chalk7.bold("Sync Patterns"));
|
|
2286
2114
|
for (const pattern of type.syncPatterns) {
|
|
2287
|
-
console.log(` ${
|
|
2115
|
+
console.log(` ${chalk7.dim("\u2022")} ${pattern}`);
|
|
2288
2116
|
}
|
|
2289
2117
|
}
|
|
2290
2118
|
if (type.excludePatterns && type.excludePatterns.length > 0) {
|
|
2291
2119
|
console.log("");
|
|
2292
|
-
console.log(
|
|
2120
|
+
console.log(chalk7.bold("Exclude Patterns"));
|
|
2293
2121
|
for (const pattern of type.excludePatterns) {
|
|
2294
|
-
console.log(` ${
|
|
2122
|
+
console.log(` ${chalk7.dim("\u2022")} ${pattern}`);
|
|
2295
2123
|
}
|
|
2296
2124
|
}
|
|
2297
2125
|
} catch (error) {
|
|
2298
|
-
console.error(
|
|
2126
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
2299
2127
|
process.exit(1);
|
|
2300
2128
|
}
|
|
2301
2129
|
});
|
|
@@ -2339,30 +2167,30 @@ function typesAddCommand() {
|
|
|
2339
2167
|
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
2168
|
try {
|
|
2341
2169
|
if (!isValidTypeName(name)) {
|
|
2342
|
-
console.error(
|
|
2343
|
-
console.log(
|
|
2170
|
+
console.error(chalk7.red("Error:"), "Invalid type name.");
|
|
2171
|
+
console.log(chalk7.dim("Type name must be lowercase, start with a letter, and contain only letters, numbers, and hyphens."));
|
|
2344
2172
|
process.exit(1);
|
|
2345
2173
|
}
|
|
2346
2174
|
const client = await getClient();
|
|
2347
2175
|
const registry = client.getTypeRegistry();
|
|
2348
2176
|
if (registry.isBuiltIn(name)) {
|
|
2349
|
-
console.error(
|
|
2177
|
+
console.error(chalk7.red("Error:"), `Cannot override built-in type "${name}".`);
|
|
2350
2178
|
const builtinNames = registry.list().filter((t) => registry.isBuiltIn(t.name)).map((t) => t.name);
|
|
2351
|
-
console.log(
|
|
2179
|
+
console.log(chalk7.dim("Built-in types: " + builtinNames.join(", ")));
|
|
2352
2180
|
process.exit(1);
|
|
2353
2181
|
}
|
|
2354
2182
|
if (registry.has(name)) {
|
|
2355
|
-
console.error(
|
|
2356
|
-
console.log(
|
|
2183
|
+
console.error(chalk7.red("Error:"), `Custom type "${name}" already exists.`);
|
|
2184
|
+
console.log(chalk7.dim('Use "fractary codex types remove" first to remove it.'));
|
|
2357
2185
|
process.exit(1);
|
|
2358
2186
|
}
|
|
2359
2187
|
let ttlSeconds;
|
|
2360
2188
|
try {
|
|
2361
2189
|
ttlSeconds = parseTtl(options.ttl);
|
|
2362
2190
|
} catch {
|
|
2363
|
-
console.error(
|
|
2364
|
-
console.log(
|
|
2365
|
-
console.log(
|
|
2191
|
+
console.error(chalk7.red("Error:"), "Invalid TTL format.");
|
|
2192
|
+
console.log(chalk7.dim("Expected format: <number><unit> where unit is s (seconds), m (minutes), h (hours), or d (days)"));
|
|
2193
|
+
console.log(chalk7.dim("Examples: 30m, 24h, 7d"));
|
|
2366
2194
|
process.exit(1);
|
|
2367
2195
|
}
|
|
2368
2196
|
const configPath = path5.join(process.cwd(), ".fractary", "codex", "config.yaml");
|
|
@@ -2394,19 +2222,19 @@ function typesAddCommand() {
|
|
|
2394
2222
|
}, null, 2));
|
|
2395
2223
|
return;
|
|
2396
2224
|
}
|
|
2397
|
-
console.log(
|
|
2225
|
+
console.log(chalk7.green("\u2713"), `Added custom type "${chalk7.cyan(name)}"`);
|
|
2398
2226
|
console.log("");
|
|
2399
|
-
console.log(` ${
|
|
2400
|
-
console.log(` ${
|
|
2227
|
+
console.log(` ${chalk7.dim("Pattern:")} ${options.pattern}`);
|
|
2228
|
+
console.log(` ${chalk7.dim("TTL:")} ${formatTtl3(ttlSeconds)} (${ttlSeconds} seconds)`);
|
|
2401
2229
|
if (options.description) {
|
|
2402
|
-
console.log(` ${
|
|
2230
|
+
console.log(` ${chalk7.dim("Description:")} ${options.description}`);
|
|
2403
2231
|
}
|
|
2404
2232
|
console.log("");
|
|
2405
|
-
console.log(
|
|
2233
|
+
console.log(chalk7.dim("Note: Custom type will be available on next CLI invocation."));
|
|
2406
2234
|
} catch (error) {
|
|
2407
|
-
console.error(
|
|
2235
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
2408
2236
|
if (error.message.includes("Failed to load configuration")) {
|
|
2409
|
-
console.log(
|
|
2237
|
+
console.log(chalk7.dim('\nRun "fractary codex init" to create a configuration.'));
|
|
2410
2238
|
}
|
|
2411
2239
|
process.exit(1);
|
|
2412
2240
|
}
|
|
@@ -2424,20 +2252,20 @@ function typesRemoveCommand() {
|
|
|
2424
2252
|
const client = await getClient();
|
|
2425
2253
|
const registry = client.getTypeRegistry();
|
|
2426
2254
|
if (registry.isBuiltIn(name)) {
|
|
2427
|
-
console.error(
|
|
2428
|
-
console.log(
|
|
2255
|
+
console.error(chalk7.red("Error:"), `Cannot remove built-in type "${name}".`);
|
|
2256
|
+
console.log(chalk7.dim("Built-in types are permanent and cannot be removed."));
|
|
2429
2257
|
process.exit(1);
|
|
2430
2258
|
}
|
|
2431
2259
|
if (!registry.has(name)) {
|
|
2432
|
-
console.error(
|
|
2433
|
-
console.log(
|
|
2260
|
+
console.error(chalk7.red("Error:"), `Custom type "${name}" not found.`);
|
|
2261
|
+
console.log(chalk7.dim('Run "fractary codex types list --custom-only" to see custom types.'));
|
|
2434
2262
|
process.exit(1);
|
|
2435
2263
|
}
|
|
2436
2264
|
const typeInfo = registry.get(name);
|
|
2437
2265
|
const configPath = path5.join(process.cwd(), ".fractary", "codex", "config.yaml");
|
|
2438
2266
|
const config = await readYamlConfig(configPath);
|
|
2439
2267
|
if (!config.types?.custom?.[name]) {
|
|
2440
|
-
console.error(
|
|
2268
|
+
console.error(chalk7.red("Error:"), `Custom type "${name}" not found in configuration.`);
|
|
2441
2269
|
process.exit(1);
|
|
2442
2270
|
}
|
|
2443
2271
|
delete config.types.custom[name];
|
|
@@ -2461,17 +2289,17 @@ function typesRemoveCommand() {
|
|
|
2461
2289
|
}, null, 2));
|
|
2462
2290
|
return;
|
|
2463
2291
|
}
|
|
2464
|
-
console.log(
|
|
2292
|
+
console.log(chalk7.green("\u2713"), `Removed custom type "${chalk7.cyan(name)}"`);
|
|
2465
2293
|
console.log("");
|
|
2466
|
-
console.log(
|
|
2467
|
-
console.log(` ${
|
|
2468
|
-
console.log(` ${
|
|
2294
|
+
console.log(chalk7.dim("Removed configuration:"));
|
|
2295
|
+
console.log(` ${chalk7.dim("Pattern:")} ${typeInfo.patterns.join(", ")}`);
|
|
2296
|
+
console.log(` ${chalk7.dim("Description:")} ${typeInfo.description}`);
|
|
2469
2297
|
console.log("");
|
|
2470
|
-
console.log(
|
|
2298
|
+
console.log(chalk7.dim("Note: Custom type will be removed on next CLI invocation."));
|
|
2471
2299
|
} catch (error) {
|
|
2472
|
-
console.error(
|
|
2300
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
2473
2301
|
if (error.message.includes("Failed to load configuration")) {
|
|
2474
|
-
console.log(
|
|
2302
|
+
console.log(chalk7.dim('\nRun "fractary codex init" to create a configuration.'));
|
|
2475
2303
|
}
|
|
2476
2304
|
process.exit(1);
|
|
2477
2305
|
}
|