@fractary/codex-cli 0.9.0 → 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 +338 -386
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +337 -385
- 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
|
}
|
|
@@ -990,6 +990,105 @@ async function initializeUnifiedConfig(configPath, organization, project, option
|
|
|
990
990
|
};
|
|
991
991
|
}
|
|
992
992
|
|
|
993
|
+
// src/config/gitignore-utils.ts
|
|
994
|
+
init_esm_shims();
|
|
995
|
+
var DEFAULT_FRACTARY_GITIGNORE = `# .fractary/.gitignore
|
|
996
|
+
# This file is managed by multiple plugins - each plugin manages its own section
|
|
997
|
+
|
|
998
|
+
# ===== fractary-codex (managed) =====
|
|
999
|
+
codex/cache/
|
|
1000
|
+
# ===== end fractary-codex =====
|
|
1001
|
+
`;
|
|
1002
|
+
async function readFractaryGitignore(projectRoot) {
|
|
1003
|
+
const gitignorePath = path5.join(projectRoot, ".fractary", ".gitignore");
|
|
1004
|
+
try {
|
|
1005
|
+
return await fs.readFile(gitignorePath, "utf-8");
|
|
1006
|
+
} catch (error) {
|
|
1007
|
+
if (error.code === "ENOENT") {
|
|
1008
|
+
return null;
|
|
1009
|
+
}
|
|
1010
|
+
throw error;
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
async function writeFractaryGitignore(projectRoot, content) {
|
|
1014
|
+
const gitignorePath = path5.join(projectRoot, ".fractary", ".gitignore");
|
|
1015
|
+
await fs.mkdir(path5.join(projectRoot, ".fractary"), { recursive: true });
|
|
1016
|
+
await fs.writeFile(gitignorePath, content, "utf-8");
|
|
1017
|
+
}
|
|
1018
|
+
function normalizeCachePath(cachePath) {
|
|
1019
|
+
let normalized = cachePath.replace(/\\/g, "/");
|
|
1020
|
+
normalized = normalized.replace(/^\.fractary\//, "");
|
|
1021
|
+
if (!normalized.endsWith("/")) {
|
|
1022
|
+
normalized += "/";
|
|
1023
|
+
}
|
|
1024
|
+
return normalized;
|
|
1025
|
+
}
|
|
1026
|
+
function isCachePathIgnored(gitignoreContent, cachePath) {
|
|
1027
|
+
const normalized = normalizeCachePath(cachePath);
|
|
1028
|
+
const lines = gitignoreContent.split("\n").map((l) => l.trim());
|
|
1029
|
+
return lines.some((line) => {
|
|
1030
|
+
if (line.startsWith("#") || line === "") return false;
|
|
1031
|
+
let normalizedLine = line.replace(/\\/g, "/");
|
|
1032
|
+
if (!normalizedLine.endsWith("/")) {
|
|
1033
|
+
normalizedLine += "/";
|
|
1034
|
+
}
|
|
1035
|
+
return normalizedLine === normalized;
|
|
1036
|
+
});
|
|
1037
|
+
}
|
|
1038
|
+
function addCachePathToGitignore(gitignoreContent, cachePath, comment) {
|
|
1039
|
+
const normalized = normalizeCachePath(cachePath);
|
|
1040
|
+
if (isCachePathIgnored(gitignoreContent, cachePath)) {
|
|
1041
|
+
return gitignoreContent;
|
|
1042
|
+
}
|
|
1043
|
+
let addition = "";
|
|
1044
|
+
{
|
|
1045
|
+
addition += `
|
|
1046
|
+
# ${comment}
|
|
1047
|
+
`;
|
|
1048
|
+
}
|
|
1049
|
+
addition += normalized + "\n";
|
|
1050
|
+
return gitignoreContent.trimEnd() + addition;
|
|
1051
|
+
}
|
|
1052
|
+
async function ensureCachePathIgnored(projectRoot, cachePath) {
|
|
1053
|
+
const gitignorePath = path5.join(projectRoot, ".fractary", ".gitignore");
|
|
1054
|
+
let relativeCachePath = cachePath;
|
|
1055
|
+
if (path5.isAbsolute(cachePath)) {
|
|
1056
|
+
relativeCachePath = path5.relative(path5.join(projectRoot, ".fractary"), cachePath);
|
|
1057
|
+
}
|
|
1058
|
+
relativeCachePath = normalizeCachePath(relativeCachePath);
|
|
1059
|
+
let content = await readFractaryGitignore(projectRoot);
|
|
1060
|
+
const gitignoreExists = content !== null;
|
|
1061
|
+
if (!gitignoreExists) {
|
|
1062
|
+
content = DEFAULT_FRACTARY_GITIGNORE;
|
|
1063
|
+
if (!isCachePathIgnored(content, relativeCachePath)) {
|
|
1064
|
+
content = addCachePathToGitignore(content, relativeCachePath, "Custom cache directory");
|
|
1065
|
+
}
|
|
1066
|
+
await writeFractaryGitignore(projectRoot, content);
|
|
1067
|
+
return {
|
|
1068
|
+
created: true,
|
|
1069
|
+
updated: false,
|
|
1070
|
+
alreadyIgnored: false,
|
|
1071
|
+
gitignorePath
|
|
1072
|
+
};
|
|
1073
|
+
}
|
|
1074
|
+
if (isCachePathIgnored(content, relativeCachePath)) {
|
|
1075
|
+
return {
|
|
1076
|
+
created: false,
|
|
1077
|
+
updated: false,
|
|
1078
|
+
alreadyIgnored: true,
|
|
1079
|
+
gitignorePath
|
|
1080
|
+
};
|
|
1081
|
+
}
|
|
1082
|
+
content = addCachePathToGitignore(content, relativeCachePath, "Custom cache directory");
|
|
1083
|
+
await writeFractaryGitignore(projectRoot, content);
|
|
1084
|
+
return {
|
|
1085
|
+
created: false,
|
|
1086
|
+
updated: true,
|
|
1087
|
+
alreadyIgnored: false,
|
|
1088
|
+
gitignorePath
|
|
1089
|
+
};
|
|
1090
|
+
}
|
|
1091
|
+
|
|
993
1092
|
// src/commands/config/init.ts
|
|
994
1093
|
async function getOrgFromGitRemote() {
|
|
995
1094
|
try {
|
|
@@ -1014,7 +1113,7 @@ function initCommand() {
|
|
|
1014
1113
|
const cmd = new Command("init");
|
|
1015
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) => {
|
|
1016
1115
|
try {
|
|
1017
|
-
console.log(
|
|
1116
|
+
console.log(chalk7.blue("Initializing unified Fractary configuration...\n"));
|
|
1018
1117
|
let org = options.org;
|
|
1019
1118
|
if (!org) {
|
|
1020
1119
|
org = await getOrgFromGitRemote();
|
|
@@ -1030,23 +1129,23 @@ function initCommand() {
|
|
|
1030
1129
|
}
|
|
1031
1130
|
if (!org) {
|
|
1032
1131
|
org = path5.basename(process.cwd()).split("-")[0] || "default";
|
|
1033
|
-
console.log(
|
|
1034
|
-
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"));
|
|
1035
1134
|
} else {
|
|
1036
|
-
console.log(
|
|
1135
|
+
console.log(chalk7.dim(`Organization: ${chalk7.cyan(org)}
|
|
1037
1136
|
`));
|
|
1038
1137
|
}
|
|
1039
1138
|
let project = options.project;
|
|
1040
1139
|
if (!project) {
|
|
1041
1140
|
project = path5.basename(process.cwd());
|
|
1042
|
-
console.log(
|
|
1141
|
+
console.log(chalk7.dim(`Project: ${chalk7.cyan(project)}
|
|
1043
1142
|
`));
|
|
1044
1143
|
}
|
|
1045
1144
|
const configPath = path5.join(process.cwd(), ".fractary", "config.yaml");
|
|
1046
1145
|
const configExists = await fileExists(configPath);
|
|
1047
1146
|
if (configExists && !options.force) {
|
|
1048
|
-
console.log(
|
|
1049
|
-
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"));
|
|
1050
1149
|
}
|
|
1051
1150
|
console.log("Creating directory structure...");
|
|
1052
1151
|
const dirs = [
|
|
@@ -1058,7 +1157,15 @@ function initCommand() {
|
|
|
1058
1157
|
];
|
|
1059
1158
|
for (const dir of dirs) {
|
|
1060
1159
|
await fs.mkdir(path5.join(process.cwd(), dir), { recursive: true });
|
|
1061
|
-
console.log(
|
|
1160
|
+
console.log(chalk7.green("\u2713"), chalk7.dim(dir + "/"));
|
|
1161
|
+
}
|
|
1162
|
+
const gitignoreResult = await ensureCachePathIgnored(process.cwd(), ".fractary/codex/cache");
|
|
1163
|
+
if (gitignoreResult.created) {
|
|
1164
|
+
console.log(chalk7.green("\u2713"), chalk7.dim(".fractary/.gitignore (created)"));
|
|
1165
|
+
} else if (gitignoreResult.updated) {
|
|
1166
|
+
console.log(chalk7.green("\u2713"), chalk7.dim(".fractary/.gitignore (updated)"));
|
|
1167
|
+
} else {
|
|
1168
|
+
console.log(chalk7.green("\u2713"), chalk7.dim(".fractary/.gitignore (exists)"));
|
|
1062
1169
|
}
|
|
1063
1170
|
console.log("\nInitializing configuration...");
|
|
1064
1171
|
const result = await initializeUnifiedConfig(
|
|
@@ -1068,182 +1175,28 @@ function initCommand() {
|
|
|
1068
1175
|
{ force: options.force }
|
|
1069
1176
|
);
|
|
1070
1177
|
if (result.created) {
|
|
1071
|
-
console.log(
|
|
1178
|
+
console.log(chalk7.green("\u2713"), chalk7.dim(".fractary/config.yaml (created)"));
|
|
1072
1179
|
} else if (result.merged) {
|
|
1073
|
-
console.log(
|
|
1074
|
-
}
|
|
1075
|
-
console.log(
|
|
1076
|
-
console.log(
|
|
1077
|
-
console.log(
|
|
1078
|
-
console.log(
|
|
1079
|
-
console.log(
|
|
1080
|
-
console.log(
|
|
1081
|
-
console.log(
|
|
1082
|
-
console.log(
|
|
1083
|
-
console.log(
|
|
1084
|
-
console.log(
|
|
1085
|
-
console.log(
|
|
1086
|
-
console.log(
|
|
1087
|
-
console.log(
|
|
1088
|
-
console.log(
|
|
1089
|
-
console.log(
|
|
1090
|
-
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"));
|
|
1091
1198
|
} catch (error) {
|
|
1092
|
-
console.error(
|
|
1093
|
-
process.exit(1);
|
|
1094
|
-
}
|
|
1095
|
-
});
|
|
1096
|
-
return cmd;
|
|
1097
|
-
}
|
|
1098
|
-
|
|
1099
|
-
// src/commands/config/migrate.ts
|
|
1100
|
-
init_esm_shims();
|
|
1101
|
-
init_migrate_config();
|
|
1102
|
-
async function fileExists2(filePath) {
|
|
1103
|
-
try {
|
|
1104
|
-
await fs.access(filePath);
|
|
1105
|
-
return true;
|
|
1106
|
-
} catch {
|
|
1107
|
-
return false;
|
|
1108
|
-
}
|
|
1109
|
-
}
|
|
1110
|
-
async function readFileContent(filePath) {
|
|
1111
|
-
return fs.readFile(filePath, "utf-8");
|
|
1112
|
-
}
|
|
1113
|
-
function migrateCommand() {
|
|
1114
|
-
const cmd = new Command("migrate");
|
|
1115
|
-
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) => {
|
|
1116
|
-
try {
|
|
1117
|
-
const legacyConfigPath = path5.join(process.cwd(), ".fractary", "plugins", "codex", "config.json");
|
|
1118
|
-
const newConfigPath = path5.join(process.cwd(), ".fractary", "codex", "config.yaml");
|
|
1119
|
-
if (!await fileExists2(legacyConfigPath)) {
|
|
1120
|
-
if (options.json) {
|
|
1121
|
-
console.log(JSON.stringify({
|
|
1122
|
-
status: "no_config",
|
|
1123
|
-
message: "No legacy configuration file found",
|
|
1124
|
-
path: legacyConfigPath
|
|
1125
|
-
}));
|
|
1126
|
-
} else {
|
|
1127
|
-
console.log(chalk8.yellow("\u26A0 No legacy configuration file found."));
|
|
1128
|
-
console.log(chalk8.dim(` Expected: ${legacyConfigPath}`));
|
|
1129
|
-
console.log(chalk8.dim('\nRun "fractary codex init" to create a new v3.0 YAML configuration.'));
|
|
1130
|
-
}
|
|
1131
|
-
return;
|
|
1132
|
-
}
|
|
1133
|
-
if (await fileExists2(newConfigPath) && !options.dryRun) {
|
|
1134
|
-
if (options.json) {
|
|
1135
|
-
console.log(JSON.stringify({
|
|
1136
|
-
status: "already_migrated",
|
|
1137
|
-
message: "YAML configuration already exists",
|
|
1138
|
-
path: newConfigPath
|
|
1139
|
-
}));
|
|
1140
|
-
} else {
|
|
1141
|
-
console.log(chalk8.yellow("\u26A0 YAML configuration already exists."));
|
|
1142
|
-
console.log(chalk8.dim(` Path: ${newConfigPath}`));
|
|
1143
|
-
console.log(chalk8.dim('\nUse "fractary codex init --force" to recreate.'));
|
|
1144
|
-
}
|
|
1145
|
-
return;
|
|
1146
|
-
}
|
|
1147
|
-
const legacyContent = await readFileContent(legacyConfigPath);
|
|
1148
|
-
let legacyConfig;
|
|
1149
|
-
try {
|
|
1150
|
-
legacyConfig = JSON.parse(legacyContent);
|
|
1151
|
-
} catch {
|
|
1152
|
-
console.error(chalk8.red("Error:"), "Invalid JSON in legacy config file.");
|
|
1153
|
-
process.exit(1);
|
|
1154
|
-
}
|
|
1155
|
-
if (!options.json && !options.dryRun) {
|
|
1156
|
-
console.log(chalk8.blue("Migrating Codex configuration to v3.0 YAML format...\n"));
|
|
1157
|
-
}
|
|
1158
|
-
const migrationResult = await migrateConfig(
|
|
1159
|
-
legacyConfigPath,
|
|
1160
|
-
{
|
|
1161
|
-
createBackup: options.backup !== false,
|
|
1162
|
-
backupSuffix: (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")
|
|
1163
|
-
}
|
|
1164
|
-
);
|
|
1165
|
-
if (!options.json) {
|
|
1166
|
-
console.log(chalk8.bold("Legacy Configuration:"));
|
|
1167
|
-
console.log(chalk8.dim(` Path: ${legacyConfigPath}`));
|
|
1168
|
-
console.log(chalk8.dim(` Organization: ${legacyConfig.organization || legacyConfig.organizationSlug || "unknown"}`));
|
|
1169
|
-
console.log("");
|
|
1170
|
-
console.log(chalk8.bold("Migration Changes:"));
|
|
1171
|
-
console.log(chalk8.green(" + Format: JSON \u2192 YAML"));
|
|
1172
|
-
console.log(chalk8.green(" + Location: .fractary/plugins/codex/ \u2192 .fractary/"));
|
|
1173
|
-
console.log(chalk8.green(" + File: config.json \u2192 codex.yaml"));
|
|
1174
|
-
console.log(chalk8.green(" + Storage: Multi-provider configuration"));
|
|
1175
|
-
console.log(chalk8.green(" + Cache: Modern cache management"));
|
|
1176
|
-
console.log(chalk8.green(" + Types: Custom type registry"));
|
|
1177
|
-
if (migrationResult.warnings.length > 0) {
|
|
1178
|
-
console.log("");
|
|
1179
|
-
console.log(chalk8.yellow("Warnings:"));
|
|
1180
|
-
for (const warning of migrationResult.warnings) {
|
|
1181
|
-
console.log(chalk8.yellow(" \u26A0"), chalk8.dim(warning));
|
|
1182
|
-
}
|
|
1183
|
-
}
|
|
1184
|
-
console.log("");
|
|
1185
|
-
if (options.dryRun) {
|
|
1186
|
-
console.log(chalk8.blue("Dry run - no changes made."));
|
|
1187
|
-
console.log(chalk8.dim("Run without --dry-run to execute migration."));
|
|
1188
|
-
return;
|
|
1189
|
-
}
|
|
1190
|
-
}
|
|
1191
|
-
if (options.json) {
|
|
1192
|
-
const output = {
|
|
1193
|
-
status: options.dryRun ? "migration_ready" : "migrated",
|
|
1194
|
-
dryRun: options.dryRun || false,
|
|
1195
|
-
legacyConfig: {
|
|
1196
|
-
path: legacyConfigPath,
|
|
1197
|
-
organization: legacyConfig.organization || legacyConfig.organizationSlug
|
|
1198
|
-
},
|
|
1199
|
-
newConfig: {
|
|
1200
|
-
path: newConfigPath,
|
|
1201
|
-
organization: migrationResult.yamlConfig.organization
|
|
1202
|
-
},
|
|
1203
|
-
warnings: migrationResult.warnings,
|
|
1204
|
-
backupPath: migrationResult.backupPath
|
|
1205
|
-
};
|
|
1206
|
-
console.log(JSON.stringify(output, null, 2));
|
|
1207
|
-
if (options.dryRun) {
|
|
1208
|
-
return;
|
|
1209
|
-
}
|
|
1210
|
-
}
|
|
1211
|
-
if (!options.dryRun) {
|
|
1212
|
-
await writeYamlConfig(migrationResult.yamlConfig, newConfigPath);
|
|
1213
|
-
const cacheDir = path5.join(process.cwd(), ".codex-cache");
|
|
1214
|
-
await fs.mkdir(cacheDir, { recursive: true });
|
|
1215
|
-
if (!options.json) {
|
|
1216
|
-
console.log(chalk8.green("\u2713"), "YAML configuration created");
|
|
1217
|
-
console.log(chalk8.green("\u2713"), "Cache directory initialized");
|
|
1218
|
-
if (migrationResult.backupPath) {
|
|
1219
|
-
console.log(chalk8.green("\u2713"), "Legacy config backed up");
|
|
1220
|
-
}
|
|
1221
|
-
console.log("");
|
|
1222
|
-
console.log(chalk8.bold("New Configuration:"));
|
|
1223
|
-
console.log(chalk8.dim(` Path: ${newConfigPath}`));
|
|
1224
|
-
console.log(chalk8.dim(` Organization: ${migrationResult.yamlConfig.organization}`));
|
|
1225
|
-
console.log(chalk8.dim(` Cache: ${migrationResult.yamlConfig.cacheDir || ".codex-cache"}`));
|
|
1226
|
-
console.log(chalk8.dim(` Storage Providers: ${migrationResult.yamlConfig.storage?.length || 0}`));
|
|
1227
|
-
console.log("");
|
|
1228
|
-
console.log(chalk8.bold("Next Steps:"));
|
|
1229
|
-
console.log(chalk8.dim(" 1. Review the new configuration: .fractary/codex/config.yaml"));
|
|
1230
|
-
console.log(chalk8.dim(' 2. Set your GitHub token: export GITHUB_TOKEN="your_token"'));
|
|
1231
|
-
console.log(chalk8.dim(" 3. Test fetching: fractary codex fetch codex://org/project/path"));
|
|
1232
|
-
if (migrationResult.backupPath) {
|
|
1233
|
-
console.log("");
|
|
1234
|
-
console.log(chalk8.dim(`Backup saved: ${path5.basename(migrationResult.backupPath)}`));
|
|
1235
|
-
}
|
|
1236
|
-
}
|
|
1237
|
-
}
|
|
1238
|
-
} catch (error) {
|
|
1239
|
-
if (options.json) {
|
|
1240
|
-
console.log(JSON.stringify({
|
|
1241
|
-
status: "error",
|
|
1242
|
-
message: error.message
|
|
1243
|
-
}));
|
|
1244
|
-
} else {
|
|
1245
|
-
console.error(chalk8.red("Error:"), error.message);
|
|
1246
|
-
}
|
|
1199
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
1247
1200
|
process.exit(1);
|
|
1248
1201
|
}
|
|
1249
1202
|
});
|
|
@@ -1255,7 +1208,6 @@ function configCommand() {
|
|
|
1255
1208
|
const cmd = new Command("config");
|
|
1256
1209
|
cmd.description("Manage configuration");
|
|
1257
1210
|
cmd.addCommand(initCommand());
|
|
1258
|
-
cmd.addCommand(migrateCommand());
|
|
1259
1211
|
return cmd;
|
|
1260
1212
|
}
|
|
1261
1213
|
|
|
@@ -1279,8 +1231,8 @@ function cacheListCommand() {
|
|
|
1279
1231
|
if (options.json) {
|
|
1280
1232
|
console.log(JSON.stringify({ entries: 0, message: "Cache is empty" }));
|
|
1281
1233
|
} else {
|
|
1282
|
-
console.log(
|
|
1283
|
-
console.log(
|
|
1234
|
+
console.log(chalk7.yellow("Cache is empty."));
|
|
1235
|
+
console.log(chalk7.dim("Fetch some documents to populate the cache."));
|
|
1284
1236
|
}
|
|
1285
1237
|
return;
|
|
1286
1238
|
}
|
|
@@ -1294,25 +1246,25 @@ function cacheListCommand() {
|
|
|
1294
1246
|
}, null, 2));
|
|
1295
1247
|
return;
|
|
1296
1248
|
}
|
|
1297
|
-
console.log(
|
|
1298
|
-
console.log(
|
|
1299
|
-
console.log(` Total: ${
|
|
1300
|
-
console.log(` Fresh: ${
|
|
1301
|
-
console.log(` Stale: ${stats.staleCount > 0 ?
|
|
1302
|
-
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`);
|
|
1303
1255
|
console.log("");
|
|
1304
|
-
console.log(
|
|
1305
|
-
console.log(` Total size: ${
|
|
1256
|
+
console.log(chalk7.bold("Storage:"));
|
|
1257
|
+
console.log(` Total size: ${chalk7.cyan(formatSize(stats.totalSize))}`);
|
|
1306
1258
|
console.log("");
|
|
1307
1259
|
const healthPercent = stats.entryCount > 0 ? stats.freshCount / stats.entryCount * 100 : 100;
|
|
1308
|
-
const healthColor = healthPercent > 80 ?
|
|
1260
|
+
const healthColor = healthPercent > 80 ? chalk7.green : healthPercent > 50 ? chalk7.yellow : chalk7.red;
|
|
1309
1261
|
console.log(`Cache health: ${healthColor(`${healthPercent.toFixed(0)}% fresh`)}`);
|
|
1310
1262
|
console.log("");
|
|
1311
|
-
console.log(
|
|
1312
|
-
console.log(
|
|
1313
|
-
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.'));
|
|
1314
1266
|
} catch (error) {
|
|
1315
|
-
console.error(
|
|
1267
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
1316
1268
|
process.exit(1);
|
|
1317
1269
|
}
|
|
1318
1270
|
});
|
|
@@ -1328,7 +1280,7 @@ function cacheClearCommand() {
|
|
|
1328
1280
|
const client = await getClient();
|
|
1329
1281
|
const statsBefore = await client.getCacheStats();
|
|
1330
1282
|
if (statsBefore.entryCount === 0) {
|
|
1331
|
-
console.log(
|
|
1283
|
+
console.log(chalk7.yellow("Cache is already empty. Nothing to clear."));
|
|
1332
1284
|
return;
|
|
1333
1285
|
}
|
|
1334
1286
|
let pattern;
|
|
@@ -1337,45 +1289,45 @@ function cacheClearCommand() {
|
|
|
1337
1289
|
} else if (options.pattern) {
|
|
1338
1290
|
pattern = options.pattern;
|
|
1339
1291
|
} else {
|
|
1340
|
-
console.log(
|
|
1341
|
-
console.log(
|
|
1342
|
-
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/*")'));
|
|
1343
1295
|
console.log("");
|
|
1344
|
-
console.log(
|
|
1345
|
-
console.log(
|
|
1346
|
-
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/*"'));
|
|
1347
1299
|
return;
|
|
1348
1300
|
}
|
|
1349
1301
|
if (options.dryRun) {
|
|
1350
|
-
console.log(
|
|
1302
|
+
console.log(chalk7.blue("Dry run - would clear:\n"));
|
|
1351
1303
|
if (pattern) {
|
|
1352
|
-
console.log(
|
|
1353
|
-
console.log(
|
|
1304
|
+
console.log(chalk7.dim(` Pattern: ${pattern}`));
|
|
1305
|
+
console.log(chalk7.dim(` This would invalidate matching cache entries`));
|
|
1354
1306
|
} else {
|
|
1355
|
-
console.log(
|
|
1307
|
+
console.log(chalk7.dim(` All cache entries (${statsBefore.entryCount} entries)`));
|
|
1356
1308
|
}
|
|
1357
|
-
console.log(
|
|
1309
|
+
console.log(chalk7.dim(`
|
|
1358
1310
|
Total size: ${formatSize2(statsBefore.totalSize)}`));
|
|
1359
1311
|
return;
|
|
1360
1312
|
}
|
|
1361
1313
|
if (pattern) {
|
|
1362
|
-
console.log(
|
|
1314
|
+
console.log(chalk7.blue(`Clearing cache entries matching pattern: ${pattern}
|
|
1363
1315
|
`));
|
|
1364
1316
|
await client.invalidateCache(pattern);
|
|
1365
1317
|
} else {
|
|
1366
|
-
console.log(
|
|
1318
|
+
console.log(chalk7.blue(`Clearing entire cache (${statsBefore.entryCount} entries)...
|
|
1367
1319
|
`));
|
|
1368
1320
|
await client.invalidateCache();
|
|
1369
1321
|
}
|
|
1370
1322
|
const statsAfter = await client.getCacheStats();
|
|
1371
1323
|
const entriesCleared = statsBefore.entryCount - statsAfter.entryCount;
|
|
1372
1324
|
const sizeFreed = statsBefore.totalSize - statsAfter.totalSize;
|
|
1373
|
-
console.log(
|
|
1325
|
+
console.log(chalk7.green(`\u2713 Cleared ${entriesCleared} entries (${formatSize2(sizeFreed)} freed)`));
|
|
1374
1326
|
if (statsAfter.entryCount > 0) {
|
|
1375
|
-
console.log(
|
|
1327
|
+
console.log(chalk7.dim(` Remaining: ${statsAfter.entryCount} entries (${formatSize2(statsAfter.totalSize)})`));
|
|
1376
1328
|
}
|
|
1377
1329
|
} catch (error) {
|
|
1378
|
-
console.error(
|
|
1330
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
1379
1331
|
process.exit(1);
|
|
1380
1332
|
}
|
|
1381
1333
|
});
|
|
@@ -1404,25 +1356,25 @@ function cacheStatsCommand() {
|
|
|
1404
1356
|
console.log(JSON.stringify(stats, null, 2));
|
|
1405
1357
|
return;
|
|
1406
1358
|
}
|
|
1407
|
-
console.log(
|
|
1408
|
-
console.log(
|
|
1409
|
-
console.log(` Total entries: ${
|
|
1410
|
-
console.log(` Total size: ${
|
|
1411
|
-
console.log(` Fresh entries: ${
|
|
1412
|
-
console.log(` Stale entries: ${stats.staleCount > 0 ?
|
|
1413
|
-
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")}`);
|
|
1414
1366
|
console.log("");
|
|
1415
1367
|
const healthPercent = stats.entryCount > 0 ? stats.freshCount / stats.entryCount * 100 : 100;
|
|
1416
|
-
const healthColor = healthPercent > 80 ?
|
|
1368
|
+
const healthColor = healthPercent > 80 ? chalk7.green : healthPercent > 50 ? chalk7.yellow : chalk7.red;
|
|
1417
1369
|
console.log(`Cache health: ${healthColor(`${healthPercent.toFixed(0)}% fresh`)}`);
|
|
1418
1370
|
if (stats.expiredCount > 0) {
|
|
1419
|
-
console.log(
|
|
1371
|
+
console.log(chalk7.dim('\nRun "fractary codex cache clear --pattern <pattern>" to clean up entries.'));
|
|
1420
1372
|
}
|
|
1421
1373
|
if (stats.entryCount === 0) {
|
|
1422
|
-
console.log(
|
|
1374
|
+
console.log(chalk7.dim("\nNo cached entries. Fetch some documents to populate the cache."));
|
|
1423
1375
|
}
|
|
1424
1376
|
} catch (error) {
|
|
1425
|
-
console.error(
|
|
1377
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
1426
1378
|
process.exit(1);
|
|
1427
1379
|
}
|
|
1428
1380
|
});
|
|
@@ -1432,7 +1384,7 @@ function cacheStatsCommand() {
|
|
|
1432
1384
|
// src/commands/cache/health.ts
|
|
1433
1385
|
init_esm_shims();
|
|
1434
1386
|
init_migrate_config();
|
|
1435
|
-
async function
|
|
1387
|
+
async function fileExists2(filePath) {
|
|
1436
1388
|
try {
|
|
1437
1389
|
await fs.access(filePath);
|
|
1438
1390
|
return true;
|
|
@@ -1441,11 +1393,11 @@ async function fileExists3(filePath) {
|
|
|
1441
1393
|
}
|
|
1442
1394
|
}
|
|
1443
1395
|
async function checkConfiguration() {
|
|
1444
|
-
const configPath = path5.join(process.cwd(), ".fractary", "
|
|
1396
|
+
const configPath = path5.join(process.cwd(), ".fractary", "config.yaml");
|
|
1445
1397
|
const legacyConfigPath = path5.join(process.cwd(), ".fractary", "plugins", "codex", "config.json");
|
|
1446
1398
|
try {
|
|
1447
|
-
if (!await
|
|
1448
|
-
if (await
|
|
1399
|
+
if (!await fileExists2(configPath)) {
|
|
1400
|
+
if (await fileExists2(legacyConfigPath)) {
|
|
1449
1401
|
return {
|
|
1450
1402
|
name: "Configuration",
|
|
1451
1403
|
status: "warn",
|
|
@@ -1549,7 +1501,7 @@ async function checkCache() {
|
|
|
1549
1501
|
}
|
|
1550
1502
|
}
|
|
1551
1503
|
async function checkStorage() {
|
|
1552
|
-
const configPath = path5.join(process.cwd(), ".fractary", "
|
|
1504
|
+
const configPath = path5.join(process.cwd(), ".fractary", "config.yaml");
|
|
1553
1505
|
try {
|
|
1554
1506
|
const config = await readYamlConfig(configPath);
|
|
1555
1507
|
const providers = config.storage || [];
|
|
@@ -1558,7 +1510,7 @@ async function checkStorage() {
|
|
|
1558
1510
|
name: "Storage",
|
|
1559
1511
|
status: "warn",
|
|
1560
1512
|
message: "No storage providers configured",
|
|
1561
|
-
details: "Configure at least one provider in .fractary/
|
|
1513
|
+
details: "Configure at least one provider in .fractary/config.yaml"
|
|
1562
1514
|
};
|
|
1563
1515
|
}
|
|
1564
1516
|
const providerTypes = providers.map((p) => p.type).join(", ");
|
|
@@ -1639,32 +1591,32 @@ function healthCommand() {
|
|
|
1639
1591
|
}, null, 2));
|
|
1640
1592
|
return;
|
|
1641
1593
|
}
|
|
1642
|
-
console.log(
|
|
1594
|
+
console.log(chalk7.bold("Codex Health Check\n"));
|
|
1643
1595
|
for (const check of checks) {
|
|
1644
|
-
const icon = check.status === "pass" ?
|
|
1645
|
-
const statusColor = check.status === "pass" ?
|
|
1646
|
-
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)}`);
|
|
1647
1599
|
console.log(` ${statusColor(check.message)}`);
|
|
1648
1600
|
if (check.details) {
|
|
1649
|
-
console.log(` ${
|
|
1601
|
+
console.log(` ${chalk7.dim(check.details)}`);
|
|
1650
1602
|
}
|
|
1651
1603
|
console.log("");
|
|
1652
1604
|
}
|
|
1653
|
-
console.log(
|
|
1654
|
-
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");
|
|
1655
1607
|
console.log(`Status: ${overallStatus}`);
|
|
1656
|
-
console.log(
|
|
1608
|
+
console.log(chalk7.dim(`${passed} passed, ${warned} warnings, ${failed} failed`));
|
|
1657
1609
|
if (failed > 0 || warned > 0) {
|
|
1658
1610
|
console.log("");
|
|
1659
|
-
console.log(
|
|
1660
|
-
console.log(
|
|
1661
|
-
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"));
|
|
1662
1614
|
}
|
|
1663
1615
|
if (failed > 0) {
|
|
1664
1616
|
process.exit(1);
|
|
1665
1617
|
}
|
|
1666
1618
|
} catch (error) {
|
|
1667
|
-
console.error(
|
|
1619
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
1668
1620
|
process.exit(1);
|
|
1669
1621
|
}
|
|
1670
1622
|
});
|
|
@@ -1712,8 +1664,8 @@ function syncCommand() {
|
|
|
1712
1664
|
try {
|
|
1713
1665
|
config = await readYamlConfig(configPath);
|
|
1714
1666
|
} catch (error) {
|
|
1715
|
-
console.error(
|
|
1716
|
-
console.log(
|
|
1667
|
+
console.error(chalk7.red("Error:"), "Codex not initialized.");
|
|
1668
|
+
console.log(chalk7.dim('Run "fractary codex init" first.'));
|
|
1717
1669
|
process.exit(1);
|
|
1718
1670
|
}
|
|
1719
1671
|
const { createSyncManager, createLocalStorage, detectCurrentProject } = await import('@fractary/codex');
|
|
@@ -1723,14 +1675,14 @@ function syncCommand() {
|
|
|
1723
1675
|
projectName = detected.project || void 0;
|
|
1724
1676
|
}
|
|
1725
1677
|
if (!projectName) {
|
|
1726
|
-
console.error(
|
|
1727
|
-
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."));
|
|
1728
1680
|
process.exit(1);
|
|
1729
1681
|
}
|
|
1730
1682
|
const validDirections = ["to-codex", "from-codex", "bidirectional"];
|
|
1731
1683
|
if (!validDirections.includes(options.direction)) {
|
|
1732
|
-
console.error(
|
|
1733
|
-
console.log(
|
|
1684
|
+
console.error(chalk7.red("Error:"), `Invalid direction: ${options.direction}`);
|
|
1685
|
+
console.log(chalk7.dim("Valid options: to-codex, from-codex, bidirectional"));
|
|
1734
1686
|
process.exit(1);
|
|
1735
1687
|
}
|
|
1736
1688
|
const direction = options.direction;
|
|
@@ -1787,7 +1739,7 @@ function syncCommand() {
|
|
|
1787
1739
|
});
|
|
1788
1740
|
matches.forEach((match) => matchedFilePaths.add(match));
|
|
1789
1741
|
} catch (error) {
|
|
1790
|
-
console.error(
|
|
1742
|
+
console.error(chalk7.yellow(`Warning: Invalid pattern "${pattern}": ${error.message}`));
|
|
1791
1743
|
}
|
|
1792
1744
|
}
|
|
1793
1745
|
const targetFiles = await Promise.all(
|
|
@@ -1815,14 +1767,14 @@ function syncCommand() {
|
|
|
1815
1767
|
try {
|
|
1816
1768
|
const { ensureCodexCloned: ensureCodexCloned2 } = await Promise.resolve().then(() => (init_codex_repository(), codex_repository_exports));
|
|
1817
1769
|
if (!options.json) {
|
|
1818
|
-
console.log(
|
|
1770
|
+
console.log(chalk7.blue("\u2139 Cloning/updating codex repository..."));
|
|
1819
1771
|
}
|
|
1820
1772
|
codexRepoPath = await ensureCodexCloned2(config, {
|
|
1821
1773
|
branch: targetBranch
|
|
1822
1774
|
});
|
|
1823
1775
|
if (!options.json) {
|
|
1824
|
-
console.log(
|
|
1825
|
-
console.log(
|
|
1776
|
+
console.log(chalk7.dim(` Codex cloned to: ${codexRepoPath}`));
|
|
1777
|
+
console.log(chalk7.dim(" Scanning for files routing to this project...\n"));
|
|
1826
1778
|
} else {
|
|
1827
1779
|
console.log(JSON.stringify({
|
|
1828
1780
|
info: "Routing-aware sync: cloned codex repository and scanning for files targeting this project",
|
|
@@ -1830,29 +1782,29 @@ function syncCommand() {
|
|
|
1830
1782
|
}, null, 2));
|
|
1831
1783
|
}
|
|
1832
1784
|
} catch (error) {
|
|
1833
|
-
console.error(
|
|
1834
|
-
console.error(
|
|
1835
|
-
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:"));
|
|
1836
1788
|
if (error.message.includes("Git command not found")) {
|
|
1837
|
-
console.log(
|
|
1838
|
-
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"));
|
|
1839
1791
|
} else if (error.message.includes("authentication failed") || error.message.includes("Authentication failed")) {
|
|
1840
|
-
console.log(
|
|
1841
|
-
console.log(
|
|
1842
|
-
console.log(
|
|
1843
|
-
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"));
|
|
1844
1796
|
} else if (error.message.includes("Permission denied")) {
|
|
1845
|
-
console.log(
|
|
1846
|
-
console.log(
|
|
1847
|
-
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"));
|
|
1848
1800
|
} else if (error.message.includes("not found") || error.message.includes("does not exist")) {
|
|
1849
|
-
console.log(
|
|
1850
|
-
console.log(
|
|
1851
|
-
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"));
|
|
1852
1804
|
} else {
|
|
1853
|
-
console.log(
|
|
1854
|
-
console.log(
|
|
1855
|
-
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"}`));
|
|
1856
1808
|
}
|
|
1857
1809
|
process.exit(1);
|
|
1858
1810
|
}
|
|
@@ -1882,7 +1834,7 @@ function syncCommand() {
|
|
|
1882
1834
|
synced: 0
|
|
1883
1835
|
}, null, 2));
|
|
1884
1836
|
} else {
|
|
1885
|
-
console.log(
|
|
1837
|
+
console.log(chalk7.yellow("No files to sync."));
|
|
1886
1838
|
}
|
|
1887
1839
|
return;
|
|
1888
1840
|
}
|
|
@@ -1925,98 +1877,98 @@ function syncCommand() {
|
|
|
1925
1877
|
}, null, 2));
|
|
1926
1878
|
return;
|
|
1927
1879
|
}
|
|
1928
|
-
console.log(
|
|
1929
|
-
console.log(` Project: ${
|
|
1930
|
-
console.log(` Organization: ${
|
|
1931
|
-
console.log(` Environment: ${
|
|
1932
|
-
console.log(` Direction: ${
|
|
1933
|
-
console.log(` Files: ${
|
|
1934
|
-
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))}`);
|
|
1935
1887
|
if (plan.estimatedTime) {
|
|
1936
|
-
console.log(` Est. time: ${
|
|
1888
|
+
console.log(` Est. time: ${chalk7.dim(formatDuration(plan.estimatedTime))}`);
|
|
1937
1889
|
}
|
|
1938
1890
|
if (routingScan) {
|
|
1939
1891
|
console.log("");
|
|
1940
|
-
console.log(
|
|
1941
|
-
console.log(` Scanned: ${
|
|
1942
|
-
console.log(` Matched: ${
|
|
1943
|
-
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())}`);
|
|
1944
1896
|
if (routingScan.stats.sourceProjects.length > 0) {
|
|
1945
|
-
console.log(
|
|
1897
|
+
console.log(chalk7.dim(` ${routingScan.stats.sourceProjects.slice(0, 5).join(", ")}`));
|
|
1946
1898
|
if (routingScan.stats.sourceProjects.length > 5) {
|
|
1947
|
-
console.log(
|
|
1899
|
+
console.log(chalk7.dim(` ... and ${routingScan.stats.sourceProjects.length - 5} more`));
|
|
1948
1900
|
}
|
|
1949
1901
|
}
|
|
1950
|
-
console.log(` Scan time: ${
|
|
1902
|
+
console.log(` Scan time: ${chalk7.dim(formatDuration(routingScan.stats.durationMs))}`);
|
|
1951
1903
|
}
|
|
1952
1904
|
console.log("");
|
|
1953
1905
|
if (plan.conflicts.length > 0) {
|
|
1954
|
-
console.log(
|
|
1906
|
+
console.log(chalk7.yellow(`\u26A0 ${plan.conflicts.length} conflicts detected:`));
|
|
1955
1907
|
for (const conflict of plan.conflicts.slice(0, 5)) {
|
|
1956
|
-
console.log(
|
|
1908
|
+
console.log(chalk7.yellow(` \u2022 ${conflict.path}`));
|
|
1957
1909
|
}
|
|
1958
1910
|
if (plan.conflicts.length > 5) {
|
|
1959
|
-
console.log(
|
|
1911
|
+
console.log(chalk7.dim(` ... and ${plan.conflicts.length - 5} more`));
|
|
1960
1912
|
}
|
|
1961
1913
|
console.log("");
|
|
1962
1914
|
}
|
|
1963
1915
|
if (plan.skipped.length > 0) {
|
|
1964
|
-
console.log(
|
|
1916
|
+
console.log(chalk7.dim(`${plan.skipped.length} files skipped (no changes)`));
|
|
1965
1917
|
console.log("");
|
|
1966
1918
|
}
|
|
1967
1919
|
if (options.dryRun) {
|
|
1968
|
-
console.log(
|
|
1920
|
+
console.log(chalk7.blue("Dry run - would sync:\n"));
|
|
1969
1921
|
const filesToShow = plan.files.slice(0, 10);
|
|
1970
1922
|
for (const file of filesToShow) {
|
|
1971
1923
|
const arrow = direction === "to-codex" ? "\u2192" : direction === "from-codex" ? "\u2190" : "\u2194";
|
|
1972
|
-
const opColor = file.operation === "create" ?
|
|
1924
|
+
const opColor = file.operation === "create" ? chalk7.green : file.operation === "update" ? chalk7.yellow : chalk7.dim;
|
|
1973
1925
|
console.log(
|
|
1974
|
-
|
|
1926
|
+
chalk7.dim(` ${arrow}`),
|
|
1975
1927
|
opColor(file.operation.padEnd(7)),
|
|
1976
1928
|
file.path,
|
|
1977
|
-
|
|
1929
|
+
chalk7.dim(`(${formatBytes(file.size || 0)})`)
|
|
1978
1930
|
);
|
|
1979
1931
|
}
|
|
1980
1932
|
if (plan.files.length > 10) {
|
|
1981
|
-
console.log(
|
|
1933
|
+
console.log(chalk7.dim(` ... and ${plan.files.length - 10} more files`));
|
|
1982
1934
|
}
|
|
1983
|
-
console.log(
|
|
1935
|
+
console.log(chalk7.dim(`
|
|
1984
1936
|
Total: ${plan.totalFiles} files (${formatBytes(plan.totalBytes)})`));
|
|
1985
|
-
console.log(
|
|
1937
|
+
console.log(chalk7.dim("Run without --dry-run to execute sync."));
|
|
1986
1938
|
return;
|
|
1987
1939
|
}
|
|
1988
|
-
console.log(
|
|
1940
|
+
console.log(chalk7.blue("Syncing...\n"));
|
|
1989
1941
|
const startTime = Date.now();
|
|
1990
1942
|
const result = await syncManager.executePlan(plan, syncOptions);
|
|
1991
1943
|
const duration = Date.now() - startTime;
|
|
1992
1944
|
console.log("");
|
|
1993
1945
|
if (result.success) {
|
|
1994
|
-
console.log(
|
|
1995
|
-
console.log(
|
|
1946
|
+
console.log(chalk7.green(`\u2713 Sync completed successfully`));
|
|
1947
|
+
console.log(chalk7.dim(` Synced: ${result.synced} files`));
|
|
1996
1948
|
if (result.skipped > 0) {
|
|
1997
|
-
console.log(
|
|
1949
|
+
console.log(chalk7.dim(` Skipped: ${result.skipped} files`));
|
|
1998
1950
|
}
|
|
1999
|
-
console.log(
|
|
1951
|
+
console.log(chalk7.dim(` Duration: ${formatDuration(duration)}`));
|
|
2000
1952
|
} else {
|
|
2001
|
-
console.log(
|
|
2002
|
-
console.log(
|
|
2003
|
-
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`));
|
|
2004
1956
|
if (result.skipped > 0) {
|
|
2005
|
-
console.log(
|
|
1957
|
+
console.log(chalk7.dim(` Skipped: ${result.skipped} files`));
|
|
2006
1958
|
}
|
|
2007
1959
|
if (result.errors.length > 0) {
|
|
2008
1960
|
console.log("");
|
|
2009
|
-
console.log(
|
|
1961
|
+
console.log(chalk7.red("Errors:"));
|
|
2010
1962
|
for (const error of result.errors.slice(0, 5)) {
|
|
2011
|
-
console.log(
|
|
1963
|
+
console.log(chalk7.red(` \u2022 ${error.path}: ${error.error}`));
|
|
2012
1964
|
}
|
|
2013
1965
|
if (result.errors.length > 5) {
|
|
2014
|
-
console.log(
|
|
1966
|
+
console.log(chalk7.dim(` ... and ${result.errors.length - 5} more errors`));
|
|
2015
1967
|
}
|
|
2016
1968
|
}
|
|
2017
1969
|
}
|
|
2018
1970
|
} catch (error) {
|
|
2019
|
-
console.error(
|
|
1971
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
2020
1972
|
process.exit(1);
|
|
2021
1973
|
}
|
|
2022
1974
|
});
|
|
@@ -2068,35 +2020,35 @@ function typesListCommand() {
|
|
|
2068
2020
|
return;
|
|
2069
2021
|
}
|
|
2070
2022
|
if (types.length === 0) {
|
|
2071
|
-
console.log(
|
|
2023
|
+
console.log(chalk7.yellow("No types found."));
|
|
2072
2024
|
return;
|
|
2073
2025
|
}
|
|
2074
|
-
console.log(
|
|
2026
|
+
console.log(chalk7.bold("Artifact Types\n"));
|
|
2075
2027
|
const builtinTypes = types.filter((t) => registry.isBuiltIn(t.name));
|
|
2076
2028
|
const customTypes = types.filter((t) => !registry.isBuiltIn(t.name));
|
|
2077
2029
|
if (builtinTypes.length > 0 && !options.customOnly) {
|
|
2078
|
-
console.log(
|
|
2079
|
-
console.log(
|
|
2030
|
+
console.log(chalk7.bold("Built-in Types"));
|
|
2031
|
+
console.log(chalk7.dim("\u2500".repeat(70)));
|
|
2080
2032
|
for (const type of builtinTypes) {
|
|
2081
2033
|
const patternStr = type.patterns[0] || "";
|
|
2082
|
-
console.log(` ${
|
|
2083
|
-
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)}`);
|
|
2084
2036
|
}
|
|
2085
2037
|
console.log("");
|
|
2086
2038
|
}
|
|
2087
2039
|
if (customTypes.length > 0 && !options.builtinOnly) {
|
|
2088
|
-
console.log(
|
|
2089
|
-
console.log(
|
|
2040
|
+
console.log(chalk7.bold("Custom Types"));
|
|
2041
|
+
console.log(chalk7.dim("\u2500".repeat(70)));
|
|
2090
2042
|
for (const type of customTypes) {
|
|
2091
2043
|
const patternStr = type.patterns[0] || "";
|
|
2092
|
-
console.log(` ${
|
|
2093
|
-
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)}`);
|
|
2094
2046
|
}
|
|
2095
2047
|
console.log("");
|
|
2096
2048
|
}
|
|
2097
|
-
console.log(
|
|
2049
|
+
console.log(chalk7.dim(`Total: ${types.length} types (${builtinTypes.length} built-in, ${customTypes.length} custom)`));
|
|
2098
2050
|
} catch (error) {
|
|
2099
|
-
console.error(
|
|
2051
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
2100
2052
|
process.exit(1);
|
|
2101
2053
|
}
|
|
2102
2054
|
});
|
|
@@ -2119,8 +2071,8 @@ function typesShowCommand() {
|
|
|
2119
2071
|
const registry = client.getTypeRegistry();
|
|
2120
2072
|
const type = registry.get(name);
|
|
2121
2073
|
if (!type) {
|
|
2122
|
-
console.error(
|
|
2123
|
-
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.'));
|
|
2124
2076
|
process.exit(1);
|
|
2125
2077
|
}
|
|
2126
2078
|
const isBuiltin = registry.isBuiltIn(name);
|
|
@@ -2139,39 +2091,39 @@ function typesShowCommand() {
|
|
|
2139
2091
|
}, null, 2));
|
|
2140
2092
|
return;
|
|
2141
2093
|
}
|
|
2142
|
-
const nameColor = isBuiltin ?
|
|
2143
|
-
console.log(
|
|
2094
|
+
const nameColor = isBuiltin ? chalk7.cyan : chalk7.green;
|
|
2095
|
+
console.log(chalk7.bold(`Type: ${nameColor(name)}
|
|
2144
2096
|
`));
|
|
2145
|
-
console.log(` ${
|
|
2146
|
-
console.log(` ${
|
|
2147
|
-
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)`);
|
|
2148
2100
|
console.log("");
|
|
2149
|
-
console.log(
|
|
2101
|
+
console.log(chalk7.bold("Patterns"));
|
|
2150
2102
|
for (const pattern of type.patterns) {
|
|
2151
|
-
console.log(` ${
|
|
2103
|
+
console.log(` ${chalk7.dim("\u2022")} ${pattern}`);
|
|
2152
2104
|
}
|
|
2153
2105
|
if (type.archiveAfterDays !== null) {
|
|
2154
2106
|
console.log("");
|
|
2155
|
-
console.log(
|
|
2156
|
-
console.log(` ${
|
|
2157
|
-
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"}`);
|
|
2158
2110
|
}
|
|
2159
2111
|
if (type.syncPatterns && type.syncPatterns.length > 0) {
|
|
2160
2112
|
console.log("");
|
|
2161
|
-
console.log(
|
|
2113
|
+
console.log(chalk7.bold("Sync Patterns"));
|
|
2162
2114
|
for (const pattern of type.syncPatterns) {
|
|
2163
|
-
console.log(` ${
|
|
2115
|
+
console.log(` ${chalk7.dim("\u2022")} ${pattern}`);
|
|
2164
2116
|
}
|
|
2165
2117
|
}
|
|
2166
2118
|
if (type.excludePatterns && type.excludePatterns.length > 0) {
|
|
2167
2119
|
console.log("");
|
|
2168
|
-
console.log(
|
|
2120
|
+
console.log(chalk7.bold("Exclude Patterns"));
|
|
2169
2121
|
for (const pattern of type.excludePatterns) {
|
|
2170
|
-
console.log(` ${
|
|
2122
|
+
console.log(` ${chalk7.dim("\u2022")} ${pattern}`);
|
|
2171
2123
|
}
|
|
2172
2124
|
}
|
|
2173
2125
|
} catch (error) {
|
|
2174
|
-
console.error(
|
|
2126
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
2175
2127
|
process.exit(1);
|
|
2176
2128
|
}
|
|
2177
2129
|
});
|
|
@@ -2215,30 +2167,30 @@ function typesAddCommand() {
|
|
|
2215
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) => {
|
|
2216
2168
|
try {
|
|
2217
2169
|
if (!isValidTypeName(name)) {
|
|
2218
|
-
console.error(
|
|
2219
|
-
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."));
|
|
2220
2172
|
process.exit(1);
|
|
2221
2173
|
}
|
|
2222
2174
|
const client = await getClient();
|
|
2223
2175
|
const registry = client.getTypeRegistry();
|
|
2224
2176
|
if (registry.isBuiltIn(name)) {
|
|
2225
|
-
console.error(
|
|
2177
|
+
console.error(chalk7.red("Error:"), `Cannot override built-in type "${name}".`);
|
|
2226
2178
|
const builtinNames = registry.list().filter((t) => registry.isBuiltIn(t.name)).map((t) => t.name);
|
|
2227
|
-
console.log(
|
|
2179
|
+
console.log(chalk7.dim("Built-in types: " + builtinNames.join(", ")));
|
|
2228
2180
|
process.exit(1);
|
|
2229
2181
|
}
|
|
2230
2182
|
if (registry.has(name)) {
|
|
2231
|
-
console.error(
|
|
2232
|
-
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.'));
|
|
2233
2185
|
process.exit(1);
|
|
2234
2186
|
}
|
|
2235
2187
|
let ttlSeconds;
|
|
2236
2188
|
try {
|
|
2237
2189
|
ttlSeconds = parseTtl(options.ttl);
|
|
2238
2190
|
} catch {
|
|
2239
|
-
console.error(
|
|
2240
|
-
console.log(
|
|
2241
|
-
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"));
|
|
2242
2194
|
process.exit(1);
|
|
2243
2195
|
}
|
|
2244
2196
|
const configPath = path5.join(process.cwd(), ".fractary", "codex", "config.yaml");
|
|
@@ -2270,19 +2222,19 @@ function typesAddCommand() {
|
|
|
2270
2222
|
}, null, 2));
|
|
2271
2223
|
return;
|
|
2272
2224
|
}
|
|
2273
|
-
console.log(
|
|
2225
|
+
console.log(chalk7.green("\u2713"), `Added custom type "${chalk7.cyan(name)}"`);
|
|
2274
2226
|
console.log("");
|
|
2275
|
-
console.log(` ${
|
|
2276
|
-
console.log(` ${
|
|
2227
|
+
console.log(` ${chalk7.dim("Pattern:")} ${options.pattern}`);
|
|
2228
|
+
console.log(` ${chalk7.dim("TTL:")} ${formatTtl3(ttlSeconds)} (${ttlSeconds} seconds)`);
|
|
2277
2229
|
if (options.description) {
|
|
2278
|
-
console.log(` ${
|
|
2230
|
+
console.log(` ${chalk7.dim("Description:")} ${options.description}`);
|
|
2279
2231
|
}
|
|
2280
2232
|
console.log("");
|
|
2281
|
-
console.log(
|
|
2233
|
+
console.log(chalk7.dim("Note: Custom type will be available on next CLI invocation."));
|
|
2282
2234
|
} catch (error) {
|
|
2283
|
-
console.error(
|
|
2235
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
2284
2236
|
if (error.message.includes("Failed to load configuration")) {
|
|
2285
|
-
console.log(
|
|
2237
|
+
console.log(chalk7.dim('\nRun "fractary codex init" to create a configuration.'));
|
|
2286
2238
|
}
|
|
2287
2239
|
process.exit(1);
|
|
2288
2240
|
}
|
|
@@ -2300,20 +2252,20 @@ function typesRemoveCommand() {
|
|
|
2300
2252
|
const client = await getClient();
|
|
2301
2253
|
const registry = client.getTypeRegistry();
|
|
2302
2254
|
if (registry.isBuiltIn(name)) {
|
|
2303
|
-
console.error(
|
|
2304
|
-
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."));
|
|
2305
2257
|
process.exit(1);
|
|
2306
2258
|
}
|
|
2307
2259
|
if (!registry.has(name)) {
|
|
2308
|
-
console.error(
|
|
2309
|
-
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.'));
|
|
2310
2262
|
process.exit(1);
|
|
2311
2263
|
}
|
|
2312
2264
|
const typeInfo = registry.get(name);
|
|
2313
2265
|
const configPath = path5.join(process.cwd(), ".fractary", "codex", "config.yaml");
|
|
2314
2266
|
const config = await readYamlConfig(configPath);
|
|
2315
2267
|
if (!config.types?.custom?.[name]) {
|
|
2316
|
-
console.error(
|
|
2268
|
+
console.error(chalk7.red("Error:"), `Custom type "${name}" not found in configuration.`);
|
|
2317
2269
|
process.exit(1);
|
|
2318
2270
|
}
|
|
2319
2271
|
delete config.types.custom[name];
|
|
@@ -2337,17 +2289,17 @@ function typesRemoveCommand() {
|
|
|
2337
2289
|
}, null, 2));
|
|
2338
2290
|
return;
|
|
2339
2291
|
}
|
|
2340
|
-
console.log(
|
|
2292
|
+
console.log(chalk7.green("\u2713"), `Removed custom type "${chalk7.cyan(name)}"`);
|
|
2341
2293
|
console.log("");
|
|
2342
|
-
console.log(
|
|
2343
|
-
console.log(` ${
|
|
2344
|
-
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}`);
|
|
2345
2297
|
console.log("");
|
|
2346
|
-
console.log(
|
|
2298
|
+
console.log(chalk7.dim("Note: Custom type will be removed on next CLI invocation."));
|
|
2347
2299
|
} catch (error) {
|
|
2348
|
-
console.error(
|
|
2300
|
+
console.error(chalk7.red("Error:"), error.message);
|
|
2349
2301
|
if (error.message.includes("Failed to load configuration")) {
|
|
2350
|
-
console.log(
|
|
2302
|
+
console.log(chalk7.dim('\nRun "fractary codex init" to create a configuration.'));
|
|
2351
2303
|
}
|
|
2352
2304
|
process.exit(1);
|
|
2353
2305
|
}
|