@fractary/codex-cli 0.10.14 → 0.10.16
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 +11 -15
- package/dist/cli.cjs +181 -534
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +176 -529
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
5
|
-
var
|
|
6
|
-
var
|
|
4
|
+
var fs4 = require('fs/promises');
|
|
5
|
+
var path2 = require('path');
|
|
6
|
+
var yaml = require('js-yaml');
|
|
7
7
|
var codex = require('@fractary/codex');
|
|
8
8
|
var os = require('os');
|
|
9
9
|
var child_process = require('child_process');
|
|
@@ -33,9 +33,9 @@ function _interopNamespace(e) {
|
|
|
33
33
|
return Object.freeze(n);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
var
|
|
37
|
-
var
|
|
38
|
-
var
|
|
36
|
+
var fs4__namespace = /*#__PURE__*/_interopNamespace(fs4);
|
|
37
|
+
var path2__namespace = /*#__PURE__*/_interopNamespace(path2);
|
|
38
|
+
var yaml__namespace = /*#__PURE__*/_interopNamespace(yaml);
|
|
39
39
|
var os__namespace = /*#__PURE__*/_interopNamespace(os);
|
|
40
40
|
var chalk7__default = /*#__PURE__*/_interopDefault(chalk7);
|
|
41
41
|
var crypto__namespace = /*#__PURE__*/_interopNamespace(crypto);
|
|
@@ -76,7 +76,7 @@ __export(migrate_config_exports, {
|
|
|
76
76
|
});
|
|
77
77
|
async function isLegacyConfig(configPath) {
|
|
78
78
|
try {
|
|
79
|
-
const content = await
|
|
79
|
+
const content = await fs4__namespace.readFile(configPath, "utf-8");
|
|
80
80
|
const config = JSON.parse(content);
|
|
81
81
|
return config.version === "3.0" || config.organizationSlug !== void 0 || config.directories !== void 0 || config.rules !== void 0;
|
|
82
82
|
} catch {
|
|
@@ -86,13 +86,13 @@ async function isLegacyConfig(configPath) {
|
|
|
86
86
|
async function migrateConfig(legacyConfigPath, options) {
|
|
87
87
|
const warnings = [];
|
|
88
88
|
try {
|
|
89
|
-
const content = await
|
|
89
|
+
const content = await fs4__namespace.readFile(legacyConfigPath, "utf-8");
|
|
90
90
|
const legacy = JSON.parse(content);
|
|
91
91
|
let backupPath;
|
|
92
92
|
if (options?.createBackup !== false) {
|
|
93
93
|
const suffix = options?.backupSuffix || (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
94
94
|
backupPath = `${legacyConfigPath}.backup-${suffix}`;
|
|
95
|
-
await
|
|
95
|
+
await fs4__namespace.writeFile(backupPath, content, "utf-8");
|
|
96
96
|
}
|
|
97
97
|
const yamlConfig = {
|
|
98
98
|
organization: legacy.organization || legacy.organizationSlug || "default"
|
|
@@ -194,15 +194,15 @@ async function migrateConfig(legacyConfigPath, options) {
|
|
|
194
194
|
}
|
|
195
195
|
}
|
|
196
196
|
async function writeYamlConfig(config, outputPath) {
|
|
197
|
-
const dir =
|
|
198
|
-
await
|
|
199
|
-
const yamlContent =
|
|
197
|
+
const dir = path2__namespace.dirname(outputPath);
|
|
198
|
+
await fs4__namespace.mkdir(dir, { recursive: true });
|
|
199
|
+
const yamlContent = yaml__namespace.dump(config, {
|
|
200
200
|
indent: 2,
|
|
201
201
|
lineWidth: 80,
|
|
202
202
|
noRefs: true,
|
|
203
203
|
sortKeys: false
|
|
204
204
|
});
|
|
205
|
-
await
|
|
205
|
+
await fs4__namespace.writeFile(outputPath, yamlContent, "utf-8");
|
|
206
206
|
}
|
|
207
207
|
function getDefaultYamlConfig(organization) {
|
|
208
208
|
return {
|
|
@@ -330,14 +330,14 @@ var init_codex_client = __esm({
|
|
|
330
330
|
const { readYamlConfig } = await Promise.resolve().then(() => (init_migrate_config(), migrate_config_exports));
|
|
331
331
|
const { resolveEnvVarsInConfig } = await Promise.resolve().then(() => (init_config_types(), config_types_exports));
|
|
332
332
|
try {
|
|
333
|
-
const configPath =
|
|
333
|
+
const configPath = path2__namespace.join(process.cwd(), ".fractary", "config.yaml");
|
|
334
334
|
let config;
|
|
335
335
|
try {
|
|
336
336
|
config = await readYamlConfig(configPath);
|
|
337
337
|
config = resolveEnvVarsInConfig(config);
|
|
338
338
|
} catch (error) {
|
|
339
339
|
throw new ConfigurationError2(
|
|
340
|
-
`Failed to load configuration from ${configPath}. Run "fractary
|
|
340
|
+
`Failed to load configuration from ${configPath}. Run "fractary-codex configure" to create a configuration.`
|
|
341
341
|
);
|
|
342
342
|
}
|
|
343
343
|
const organization = options?.organizationSlug || config.organization;
|
|
@@ -600,7 +600,7 @@ function getTempCodexPath(config) {
|
|
|
600
600
|
const codexRepo = config.codex_repo || "codex";
|
|
601
601
|
const sanitizedOrg = sanitizePathComponent(config.organization);
|
|
602
602
|
const sanitizedRepo = sanitizePathComponent(codexRepo);
|
|
603
|
-
return
|
|
603
|
+
return path2__namespace.join(
|
|
604
604
|
os__namespace.tmpdir(),
|
|
605
605
|
"fractary-codex-clone",
|
|
606
606
|
`${sanitizedOrg}-${sanitizedRepo}-${process.pid}`
|
|
@@ -608,8 +608,8 @@ function getTempCodexPath(config) {
|
|
|
608
608
|
}
|
|
609
609
|
async function isValidGitRepo(repoPath) {
|
|
610
610
|
try {
|
|
611
|
-
const gitDir =
|
|
612
|
-
const stats = await
|
|
611
|
+
const gitDir = path2__namespace.join(repoPath, ".git");
|
|
612
|
+
const stats = await fs4__namespace.stat(gitDir);
|
|
613
613
|
return stats.isDirectory();
|
|
614
614
|
} catch {
|
|
615
615
|
return false;
|
|
@@ -641,8 +641,8 @@ async function execGit(repoPath, args) {
|
|
|
641
641
|
}
|
|
642
642
|
}
|
|
643
643
|
async function gitClone(url, targetPath, options) {
|
|
644
|
-
const parentDir =
|
|
645
|
-
await
|
|
644
|
+
const parentDir = path2__namespace.dirname(targetPath);
|
|
645
|
+
await fs4__namespace.mkdir(parentDir, { recursive: true });
|
|
646
646
|
const args = ["clone"];
|
|
647
647
|
if (options?.depth) {
|
|
648
648
|
if (!Number.isInteger(options.depth) || options.depth <= 0) {
|
|
@@ -689,12 +689,12 @@ async function ensureCodexCloned(config, options) {
|
|
|
689
689
|
} catch (error) {
|
|
690
690
|
console.warn(`Failed to update existing clone: ${error.message}`);
|
|
691
691
|
console.warn(`Removing and cloning fresh...`);
|
|
692
|
-
await
|
|
692
|
+
await fs4__namespace.rm(tempPath, { recursive: true, force: true });
|
|
693
693
|
}
|
|
694
694
|
}
|
|
695
695
|
const repoUrl = getCodexRepoUrl(config);
|
|
696
696
|
try {
|
|
697
|
-
await
|
|
697
|
+
await fs4__namespace.rm(tempPath, { recursive: true, force: true });
|
|
698
698
|
} catch (error) {
|
|
699
699
|
console.warn(`Could not remove existing directory ${tempPath}: ${error.message}`);
|
|
700
700
|
}
|
|
@@ -714,100 +714,6 @@ var init_codex_repository = __esm({
|
|
|
714
714
|
// src/cli.ts
|
|
715
715
|
init_cjs_shims();
|
|
716
716
|
|
|
717
|
-
// src/commands/document/index.ts
|
|
718
|
-
init_cjs_shims();
|
|
719
|
-
|
|
720
|
-
// src/commands/document/fetch.ts
|
|
721
|
-
init_cjs_shims();
|
|
722
|
-
|
|
723
|
-
// src/client/get-client.ts
|
|
724
|
-
init_cjs_shims();
|
|
725
|
-
var clientInstance = null;
|
|
726
|
-
async function getClient(options) {
|
|
727
|
-
if (!clientInstance) {
|
|
728
|
-
const { CodexClient: CodexClient2 } = await Promise.resolve().then(() => (init_codex_client(), codex_client_exports));
|
|
729
|
-
clientInstance = await CodexClient2.create(options);
|
|
730
|
-
}
|
|
731
|
-
return clientInstance;
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
// src/commands/document/fetch.ts
|
|
735
|
-
function hashContent(content) {
|
|
736
|
-
return crypto__namespace.createHash("sha256").update(content).digest("hex").slice(0, 16);
|
|
737
|
-
}
|
|
738
|
-
function fetchCommand() {
|
|
739
|
-
const cmd = new commander.Command("fetch");
|
|
740
|
-
cmd.description("Fetch a document by codex:// URI reference").argument("<uri>", "Codex URI (e.g., codex://org/project/docs/file.md)").option("--bypass-cache", "Skip cache and fetch directly from source").option("--ttl <seconds>", "Override default TTL (in seconds)", parseInt).option("--json", "Output as JSON with metadata").option("--output <file>", "Write content to file instead of stdout").action(async (uri, options) => {
|
|
741
|
-
try {
|
|
742
|
-
const { validateUri } = await import('@fractary/codex');
|
|
743
|
-
if (!validateUri(uri)) {
|
|
744
|
-
console.error(chalk7__default.default.red("Error: Invalid URI format"));
|
|
745
|
-
console.log(chalk7__default.default.dim("Expected: codex://org/project/path/to/file.md"));
|
|
746
|
-
console.log(chalk7__default.default.dim("Example: codex://fractary/codex/docs/api.md"));
|
|
747
|
-
process.exit(1);
|
|
748
|
-
}
|
|
749
|
-
const client = await getClient();
|
|
750
|
-
if (!options.json && !options.bypassCache) {
|
|
751
|
-
console.error(chalk7__default.default.dim(`Fetching ${uri}...`));
|
|
752
|
-
}
|
|
753
|
-
const result = await client.fetch(uri, {
|
|
754
|
-
bypassCache: options.bypassCache,
|
|
755
|
-
ttl: options.ttl
|
|
756
|
-
});
|
|
757
|
-
if (options.json) {
|
|
758
|
-
const output = {
|
|
759
|
-
uri,
|
|
760
|
-
content: result.content.toString("utf-8"),
|
|
761
|
-
metadata: {
|
|
762
|
-
fromCache: result.fromCache,
|
|
763
|
-
fetchedAt: result.metadata?.fetchedAt,
|
|
764
|
-
expiresAt: result.metadata?.expiresAt,
|
|
765
|
-
contentLength: result.metadata?.contentLength || result.content.length,
|
|
766
|
-
contentHash: hashContent(result.content)
|
|
767
|
-
}
|
|
768
|
-
};
|
|
769
|
-
console.log(JSON.stringify(output, null, 2));
|
|
770
|
-
} else if (options.output) {
|
|
771
|
-
await fs__namespace.writeFile(options.output, result.content);
|
|
772
|
-
console.log(chalk7__default.default.green("\u2713"), `Written to ${options.output}`);
|
|
773
|
-
console.log(chalk7__default.default.dim(` Size: ${result.content.length} bytes`));
|
|
774
|
-
if (result.fromCache) {
|
|
775
|
-
console.log(chalk7__default.default.dim(" Source: cache"));
|
|
776
|
-
} else {
|
|
777
|
-
console.log(chalk7__default.default.dim(" Source: storage"));
|
|
778
|
-
}
|
|
779
|
-
} else {
|
|
780
|
-
if (result.fromCache && !options.bypassCache) {
|
|
781
|
-
console.error(chalk7__default.default.green("\u2713"), chalk7__default.default.dim("from cache\n"));
|
|
782
|
-
} else {
|
|
783
|
-
console.error(chalk7__default.default.green("\u2713"), chalk7__default.default.dim("fetched\n"));
|
|
784
|
-
}
|
|
785
|
-
console.log(result.content.toString("utf-8"));
|
|
786
|
-
}
|
|
787
|
-
} catch (error) {
|
|
788
|
-
console.error(chalk7__default.default.red("Error:"), error.message);
|
|
789
|
-
if (error.message.includes("Failed to load configuration")) {
|
|
790
|
-
console.log(chalk7__default.default.dim('\nRun "fractary codex init" to create a configuration.'));
|
|
791
|
-
} else if (error.message.includes("GITHUB_TOKEN")) {
|
|
792
|
-
console.log(chalk7__default.default.dim('\nSet your GitHub token: export GITHUB_TOKEN="your_token"'));
|
|
793
|
-
} else if (error.message.includes("not found") || error.message.includes("404")) {
|
|
794
|
-
console.log(chalk7__default.default.dim("\nThe document may not exist or you may not have access."));
|
|
795
|
-
console.log(chalk7__default.default.dim("Check the URI and ensure your storage providers are configured correctly."));
|
|
796
|
-
}
|
|
797
|
-
process.exit(1);
|
|
798
|
-
}
|
|
799
|
-
});
|
|
800
|
-
return cmd;
|
|
801
|
-
}
|
|
802
|
-
|
|
803
|
-
// src/commands/document/index.ts
|
|
804
|
-
function documentCommand() {
|
|
805
|
-
const cmd = new commander.Command("document");
|
|
806
|
-
cmd.description("Manage document operations");
|
|
807
|
-
cmd.addCommand(fetchCommand());
|
|
808
|
-
return cmd;
|
|
809
|
-
}
|
|
810
|
-
|
|
811
717
|
// src/commands/config/index.ts
|
|
812
718
|
init_cjs_shims();
|
|
813
719
|
|
|
@@ -875,8 +781,8 @@ function getDefaultUnifiedConfig(organization, project, codexRepo) {
|
|
|
875
781
|
}
|
|
876
782
|
async function readUnifiedConfig(configPath) {
|
|
877
783
|
try {
|
|
878
|
-
const content = await
|
|
879
|
-
const config =
|
|
784
|
+
const content = await fs4__namespace.readFile(configPath, "utf-8");
|
|
785
|
+
const config = yaml__namespace.load(content);
|
|
880
786
|
return config;
|
|
881
787
|
} catch (error) {
|
|
882
788
|
if (error.code === "ENOENT") {
|
|
@@ -886,15 +792,15 @@ async function readUnifiedConfig(configPath) {
|
|
|
886
792
|
}
|
|
887
793
|
}
|
|
888
794
|
async function writeUnifiedConfig(config, outputPath) {
|
|
889
|
-
const dir =
|
|
890
|
-
await
|
|
891
|
-
const yamlContent =
|
|
795
|
+
const dir = path2__namespace.dirname(outputPath);
|
|
796
|
+
await fs4__namespace.mkdir(dir, { recursive: true });
|
|
797
|
+
const yamlContent = yaml__namespace.dump(config, {
|
|
892
798
|
indent: 2,
|
|
893
799
|
lineWidth: 120,
|
|
894
800
|
noRefs: true,
|
|
895
801
|
sortKeys: false
|
|
896
802
|
});
|
|
897
|
-
await
|
|
803
|
+
await fs4__namespace.writeFile(outputPath, yamlContent, "utf-8");
|
|
898
804
|
}
|
|
899
805
|
function mergeUnifiedConfigs(existing, updates) {
|
|
900
806
|
const merged = {};
|
|
@@ -952,9 +858,9 @@ codex/cache/
|
|
|
952
858
|
# ===== end fractary-codex =====
|
|
953
859
|
`;
|
|
954
860
|
async function readFractaryGitignore(projectRoot) {
|
|
955
|
-
const gitignorePath =
|
|
861
|
+
const gitignorePath = path2__namespace.join(projectRoot, ".fractary", ".gitignore");
|
|
956
862
|
try {
|
|
957
|
-
return await
|
|
863
|
+
return await fs4__namespace.readFile(gitignorePath, "utf-8");
|
|
958
864
|
} catch (error) {
|
|
959
865
|
if (error.code === "ENOENT") {
|
|
960
866
|
return null;
|
|
@@ -963,9 +869,9 @@ async function readFractaryGitignore(projectRoot) {
|
|
|
963
869
|
}
|
|
964
870
|
}
|
|
965
871
|
async function writeFractaryGitignore(projectRoot, content) {
|
|
966
|
-
const gitignorePath =
|
|
967
|
-
await
|
|
968
|
-
await
|
|
872
|
+
const gitignorePath = path2__namespace.join(projectRoot, ".fractary", ".gitignore");
|
|
873
|
+
await fs4__namespace.mkdir(path2__namespace.join(projectRoot, ".fractary"), { recursive: true });
|
|
874
|
+
await fs4__namespace.writeFile(gitignorePath, content, "utf-8");
|
|
969
875
|
}
|
|
970
876
|
function normalizeCachePath(cachePath) {
|
|
971
877
|
let normalized = cachePath.replace(/\\/g, "/");
|
|
@@ -1002,10 +908,10 @@ function addCachePathToGitignore(gitignoreContent, cachePath, comment) {
|
|
|
1002
908
|
return gitignoreContent.trimEnd() + addition;
|
|
1003
909
|
}
|
|
1004
910
|
async function ensureCachePathIgnored(projectRoot, cachePath) {
|
|
1005
|
-
const gitignorePath =
|
|
911
|
+
const gitignorePath = path2__namespace.join(projectRoot, ".fractary", ".gitignore");
|
|
1006
912
|
let relativeCachePath = cachePath;
|
|
1007
|
-
if (
|
|
1008
|
-
relativeCachePath =
|
|
913
|
+
if (path2__namespace.isAbsolute(cachePath)) {
|
|
914
|
+
relativeCachePath = path2__namespace.relative(path2__namespace.join(projectRoot, ".fractary"), cachePath);
|
|
1009
915
|
}
|
|
1010
916
|
relativeCachePath = normalizeCachePath(relativeCachePath);
|
|
1011
917
|
let content = await readFractaryGitignore(projectRoot);
|
|
@@ -1123,27 +1029,27 @@ async function discoverCodexRepo(org) {
|
|
|
1123
1029
|
}
|
|
1124
1030
|
async function fileExists(filePath) {
|
|
1125
1031
|
try {
|
|
1126
|
-
await
|
|
1032
|
+
await fs4__namespace.access(filePath);
|
|
1127
1033
|
return true;
|
|
1128
1034
|
} catch {
|
|
1129
1035
|
return false;
|
|
1130
1036
|
}
|
|
1131
1037
|
}
|
|
1132
1038
|
async function installMcpServer(projectRoot, configPath = ".fractary/config.yaml", options = {}) {
|
|
1133
|
-
const mcpJsonPath =
|
|
1039
|
+
const mcpJsonPath = path2__namespace.join(projectRoot, ".mcp.json");
|
|
1134
1040
|
const { backup = true } = options;
|
|
1135
1041
|
let existingConfig = { mcpServers: {} };
|
|
1136
1042
|
let backupPath;
|
|
1137
1043
|
let migrated = false;
|
|
1138
1044
|
if (await fileExists(mcpJsonPath)) {
|
|
1139
1045
|
try {
|
|
1140
|
-
const content = await
|
|
1046
|
+
const content = await fs4__namespace.readFile(mcpJsonPath, "utf-8");
|
|
1141
1047
|
existingConfig = JSON.parse(content);
|
|
1142
1048
|
if (backup) {
|
|
1143
1049
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "").slice(0, 18);
|
|
1144
1050
|
const suffix = Math.random().toString(36).substring(2, 6);
|
|
1145
1051
|
backupPath = `${mcpJsonPath}.backup.${timestamp}-${suffix}`;
|
|
1146
|
-
await
|
|
1052
|
+
await fs4__namespace.writeFile(backupPath, content);
|
|
1147
1053
|
}
|
|
1148
1054
|
} catch {
|
|
1149
1055
|
console.log(chalk7__default.default.yellow("\u26A0 Warning: .mcp.json contains invalid JSON, starting fresh"));
|
|
@@ -1173,7 +1079,7 @@ async function installMcpServer(projectRoot, configPath = ".fractary/config.yaml
|
|
|
1173
1079
|
command: "npx",
|
|
1174
1080
|
args: ["-y", "@fractary/codex-mcp", "--config", configPath]
|
|
1175
1081
|
};
|
|
1176
|
-
await
|
|
1082
|
+
await fs4__namespace.writeFile(
|
|
1177
1083
|
mcpJsonPath,
|
|
1178
1084
|
JSON.stringify(existingConfig, null, 2) + "\n"
|
|
1179
1085
|
);
|
|
@@ -1184,8 +1090,8 @@ async function installMcpServer(projectRoot, configPath = ".fractary/config.yaml
|
|
|
1184
1090
|
backupPath
|
|
1185
1091
|
};
|
|
1186
1092
|
}
|
|
1187
|
-
function
|
|
1188
|
-
const cmd = new commander.Command("
|
|
1093
|
+
function configureCommand() {
|
|
1094
|
+
const cmd = new commander.Command("configure");
|
|
1189
1095
|
cmd.description("Initialize unified Fractary configuration (.fractary/config.yaml)").option("--org <slug>", 'Organization slug (e.g., "fractary")').option("--project <name>", "Project name (default: derived from directory)").option("--codex-repo <name>", 'Codex repository name (e.g., "codex.fractary.com")').option("--force", "Overwrite existing configuration").option("--no-mcp", "Skip MCP server installation").action(async (options) => {
|
|
1190
1096
|
try {
|
|
1191
1097
|
console.log(chalk7__default.default.blue("Initializing unified Fractary configuration...\n"));
|
|
@@ -1197,13 +1103,13 @@ function initCommand() {
|
|
|
1197
1103
|
try {
|
|
1198
1104
|
const { resolveOrganization } = await import('@fractary/codex');
|
|
1199
1105
|
org = resolveOrganization({
|
|
1200
|
-
repoName:
|
|
1106
|
+
repoName: path2__namespace.basename(process.cwd())
|
|
1201
1107
|
});
|
|
1202
1108
|
} catch {
|
|
1203
1109
|
}
|
|
1204
1110
|
}
|
|
1205
1111
|
if (!org) {
|
|
1206
|
-
org =
|
|
1112
|
+
org = path2__namespace.basename(process.cwd()).split("-")[0] || "default";
|
|
1207
1113
|
console.log(chalk7__default.default.yellow(`\u26A0 Could not detect organization, using: ${org}`));
|
|
1208
1114
|
console.log(chalk7__default.default.dim(" Use --org <slug> to specify explicitly\n"));
|
|
1209
1115
|
} else {
|
|
@@ -1218,7 +1124,7 @@ function initCommand() {
|
|
|
1218
1124
|
}
|
|
1219
1125
|
let project = options.project;
|
|
1220
1126
|
if (!project) {
|
|
1221
|
-
project =
|
|
1127
|
+
project = path2__namespace.basename(process.cwd());
|
|
1222
1128
|
console.log(chalk7__default.default.dim(`Project: ${chalk7__default.default.cyan(project)}
|
|
1223
1129
|
`));
|
|
1224
1130
|
}
|
|
@@ -1259,7 +1165,7 @@ function initCommand() {
|
|
|
1259
1165
|
console.log(chalk7__default.default.dim(` Using default: ${chalk7__default.default.cyan(codexRepo)}
|
|
1260
1166
|
`));
|
|
1261
1167
|
}
|
|
1262
|
-
const configPath =
|
|
1168
|
+
const configPath = path2__namespace.join(process.cwd(), ".fractary", "config.yaml");
|
|
1263
1169
|
const configExists = await fileExists(configPath);
|
|
1264
1170
|
if (configExists && !options.force) {
|
|
1265
1171
|
console.log(chalk7__default.default.yellow(`\u26A0 Configuration already exists at .fractary/config.yaml`));
|
|
@@ -1274,7 +1180,7 @@ function initCommand() {
|
|
|
1274
1180
|
".fractary/codex/cache"
|
|
1275
1181
|
];
|
|
1276
1182
|
for (const dir of dirs) {
|
|
1277
|
-
await
|
|
1183
|
+
await fs4__namespace.mkdir(path2__namespace.join(process.cwd(), dir), { recursive: true });
|
|
1278
1184
|
console.log(chalk7__default.default.green("\u2713"), chalk7__default.default.dim(dir + "/"));
|
|
1279
1185
|
}
|
|
1280
1186
|
const gitignoreResult = await ensureCachePathIgnored(process.cwd(), ".fractary/codex/cache");
|
|
@@ -1306,7 +1212,7 @@ function initCommand() {
|
|
|
1306
1212
|
} else if (mcpResult.migrated) {
|
|
1307
1213
|
console.log(chalk7__default.default.green("\u2713"), chalk7__default.default.dim(".mcp.json (migrated from old format)"));
|
|
1308
1214
|
if (mcpResult.backupPath) {
|
|
1309
|
-
console.log(chalk7__default.default.dim(` Backup: ${
|
|
1215
|
+
console.log(chalk7__default.default.dim(` Backup: ${path2__namespace.basename(mcpResult.backupPath)}`));
|
|
1310
1216
|
}
|
|
1311
1217
|
} else if (mcpResult.installed) {
|
|
1312
1218
|
console.log(chalk7__default.default.green("\u2713"), chalk7__default.default.dim(".mcp.json (created)"));
|
|
@@ -1344,11 +1250,89 @@ function initCommand() {
|
|
|
1344
1250
|
return cmd;
|
|
1345
1251
|
}
|
|
1346
1252
|
|
|
1347
|
-
// src/commands/
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1253
|
+
// src/commands/document/index.ts
|
|
1254
|
+
init_cjs_shims();
|
|
1255
|
+
|
|
1256
|
+
// src/commands/document/fetch.ts
|
|
1257
|
+
init_cjs_shims();
|
|
1258
|
+
|
|
1259
|
+
// src/client/get-client.ts
|
|
1260
|
+
init_cjs_shims();
|
|
1261
|
+
var clientInstance = null;
|
|
1262
|
+
async function getClient(options) {
|
|
1263
|
+
if (!clientInstance) {
|
|
1264
|
+
const { CodexClient: CodexClient2 } = await Promise.resolve().then(() => (init_codex_client(), codex_client_exports));
|
|
1265
|
+
clientInstance = await CodexClient2.create(options);
|
|
1266
|
+
}
|
|
1267
|
+
return clientInstance;
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
// src/commands/document/fetch.ts
|
|
1271
|
+
function hashContent(content) {
|
|
1272
|
+
return crypto__namespace.createHash("sha256").update(content).digest("hex").slice(0, 16);
|
|
1273
|
+
}
|
|
1274
|
+
function documentFetchCommand() {
|
|
1275
|
+
const cmd = new commander.Command("document-fetch");
|
|
1276
|
+
cmd.description("Fetch a document by codex:// URI reference").argument("<uri>", "Codex URI (e.g., codex://org/project/docs/file.md)").option("--bypass-cache", "Skip cache and fetch directly from source").option("--ttl <seconds>", "Override default TTL (in seconds)", parseInt).option("--json", "Output as JSON with metadata").option("--output <file>", "Write content to file instead of stdout").action(async (uri, options) => {
|
|
1277
|
+
try {
|
|
1278
|
+
const { validateUri } = await import('@fractary/codex');
|
|
1279
|
+
if (!validateUri(uri)) {
|
|
1280
|
+
console.error(chalk7__default.default.red("Error: Invalid URI format"));
|
|
1281
|
+
console.log(chalk7__default.default.dim("Expected: codex://org/project/path/to/file.md"));
|
|
1282
|
+
console.log(chalk7__default.default.dim("Example: codex://fractary/codex/docs/api.md"));
|
|
1283
|
+
process.exit(1);
|
|
1284
|
+
}
|
|
1285
|
+
const client = await getClient();
|
|
1286
|
+
if (!options.json && !options.bypassCache) {
|
|
1287
|
+
console.error(chalk7__default.default.dim(`Fetching ${uri}...`));
|
|
1288
|
+
}
|
|
1289
|
+
const result = await client.fetch(uri, {
|
|
1290
|
+
bypassCache: options.bypassCache,
|
|
1291
|
+
ttl: options.ttl
|
|
1292
|
+
});
|
|
1293
|
+
if (options.json) {
|
|
1294
|
+
const output = {
|
|
1295
|
+
uri,
|
|
1296
|
+
content: result.content.toString("utf-8"),
|
|
1297
|
+
metadata: {
|
|
1298
|
+
fromCache: result.fromCache,
|
|
1299
|
+
fetchedAt: result.metadata?.fetchedAt,
|
|
1300
|
+
expiresAt: result.metadata?.expiresAt,
|
|
1301
|
+
contentLength: result.metadata?.contentLength || result.content.length,
|
|
1302
|
+
contentHash: hashContent(result.content)
|
|
1303
|
+
}
|
|
1304
|
+
};
|
|
1305
|
+
console.log(JSON.stringify(output, null, 2));
|
|
1306
|
+
} else if (options.output) {
|
|
1307
|
+
await fs4__namespace.writeFile(options.output, result.content);
|
|
1308
|
+
console.log(chalk7__default.default.green("\u2713"), `Written to ${options.output}`);
|
|
1309
|
+
console.log(chalk7__default.default.dim(` Size: ${result.content.length} bytes`));
|
|
1310
|
+
if (result.fromCache) {
|
|
1311
|
+
console.log(chalk7__default.default.dim(" Source: cache"));
|
|
1312
|
+
} else {
|
|
1313
|
+
console.log(chalk7__default.default.dim(" Source: storage"));
|
|
1314
|
+
}
|
|
1315
|
+
} else {
|
|
1316
|
+
if (result.fromCache && !options.bypassCache) {
|
|
1317
|
+
console.error(chalk7__default.default.green("\u2713"), chalk7__default.default.dim("from cache\n"));
|
|
1318
|
+
} else {
|
|
1319
|
+
console.error(chalk7__default.default.green("\u2713"), chalk7__default.default.dim("fetched\n"));
|
|
1320
|
+
}
|
|
1321
|
+
console.log(result.content.toString("utf-8"));
|
|
1322
|
+
}
|
|
1323
|
+
} catch (error) {
|
|
1324
|
+
console.error(chalk7__default.default.red("Error:"), error.message);
|
|
1325
|
+
if (error.message.includes("Failed to load configuration")) {
|
|
1326
|
+
console.log(chalk7__default.default.dim('\nRun "fractary-codex configure" to create a configuration.'));
|
|
1327
|
+
} else if (error.message.includes("GITHUB_TOKEN")) {
|
|
1328
|
+
console.log(chalk7__default.default.dim('\nSet your GitHub token: export GITHUB_TOKEN="your_token"'));
|
|
1329
|
+
} else if (error.message.includes("not found") || error.message.includes("404")) {
|
|
1330
|
+
console.log(chalk7__default.default.dim("\nThe document may not exist or you may not have access."));
|
|
1331
|
+
console.log(chalk7__default.default.dim("Check the URI and ensure your storage providers are configured correctly."));
|
|
1332
|
+
}
|
|
1333
|
+
process.exit(1);
|
|
1334
|
+
}
|
|
1335
|
+
});
|
|
1352
1336
|
return cmd;
|
|
1353
1337
|
}
|
|
1354
1338
|
|
|
@@ -1363,7 +1347,7 @@ function formatSize(bytes) {
|
|
|
1363
1347
|
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
1364
1348
|
}
|
|
1365
1349
|
function cacheListCommand() {
|
|
1366
|
-
const cmd = new commander.Command("list");
|
|
1350
|
+
const cmd = new commander.Command("cache-list");
|
|
1367
1351
|
cmd.description("List cache information").option("--json", "Output as JSON").action(async (options) => {
|
|
1368
1352
|
try {
|
|
1369
1353
|
const client = await getClient();
|
|
@@ -1402,8 +1386,8 @@ function cacheListCommand() {
|
|
|
1402
1386
|
console.log(`Cache health: ${healthColor(`${healthPercent.toFixed(0)}% fresh`)}`);
|
|
1403
1387
|
console.log("");
|
|
1404
1388
|
console.log(chalk7__default.default.dim("Note: Individual cache entries are managed by the SDK."));
|
|
1405
|
-
console.log(chalk7__default.default.dim('Use "fractary
|
|
1406
|
-
console.log(chalk7__default.default.dim('Use "fractary
|
|
1389
|
+
console.log(chalk7__default.default.dim('Use "fractary-codex cache-stats" for detailed statistics.'));
|
|
1390
|
+
console.log(chalk7__default.default.dim('Use "fractary-codex cache-clear" to clear cache entries.'));
|
|
1407
1391
|
} catch (error) {
|
|
1408
1392
|
console.error(chalk7__default.default.red("Error:"), error.message);
|
|
1409
1393
|
process.exit(1);
|
|
@@ -1415,7 +1399,7 @@ function cacheListCommand() {
|
|
|
1415
1399
|
// src/commands/cache/clear.ts
|
|
1416
1400
|
init_cjs_shims();
|
|
1417
1401
|
function cacheClearCommand() {
|
|
1418
|
-
const cmd = new commander.Command("clear");
|
|
1402
|
+
const cmd = new commander.Command("cache-clear");
|
|
1419
1403
|
cmd.description("Clear cache entries").option("--all", "Clear entire cache").option("--pattern <glob>", 'Clear entries matching URI pattern (e.g., "codex://fractary/*")').option("--dry-run", "Show what would be cleared without actually clearing").action(async (options) => {
|
|
1420
1404
|
try {
|
|
1421
1405
|
const client = await getClient();
|
|
@@ -1435,8 +1419,8 @@ function cacheClearCommand() {
|
|
|
1435
1419
|
console.log(chalk7__default.default.dim(' --pattern Clear entries matching pattern (e.g., "codex://fractary/*")'));
|
|
1436
1420
|
console.log("");
|
|
1437
1421
|
console.log(chalk7__default.default.dim("Examples:"));
|
|
1438
|
-
console.log(chalk7__default.default.dim(" fractary
|
|
1439
|
-
console.log(chalk7__default.default.dim(' fractary
|
|
1422
|
+
console.log(chalk7__default.default.dim(" fractary-codex cache-clear --all"));
|
|
1423
|
+
console.log(chalk7__default.default.dim(' fractary-codex cache-clear --pattern "codex://fractary/cli/*"'));
|
|
1440
1424
|
return;
|
|
1441
1425
|
}
|
|
1442
1426
|
if (options.dryRun) {
|
|
@@ -1488,7 +1472,7 @@ function formatSize3(bytes) {
|
|
|
1488
1472
|
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
1489
1473
|
}
|
|
1490
1474
|
function cacheStatsCommand() {
|
|
1491
|
-
const cmd = new commander.Command("stats");
|
|
1475
|
+
const cmd = new commander.Command("cache-stats");
|
|
1492
1476
|
cmd.description("Display cache statistics").option("--json", "Output as JSON").action(async (options) => {
|
|
1493
1477
|
try {
|
|
1494
1478
|
const client = await getClient();
|
|
@@ -1509,7 +1493,7 @@ function cacheStatsCommand() {
|
|
|
1509
1493
|
const healthColor = healthPercent > 80 ? chalk7__default.default.green : healthPercent > 50 ? chalk7__default.default.yellow : chalk7__default.default.red;
|
|
1510
1494
|
console.log(`Cache health: ${healthColor(`${healthPercent.toFixed(0)}% fresh`)}`);
|
|
1511
1495
|
if (stats.expiredCount > 0) {
|
|
1512
|
-
console.log(chalk7__default.default.dim('\nRun "fractary
|
|
1496
|
+
console.log(chalk7__default.default.dim('\nRun "fractary-codex cache-clear --pattern <pattern>" to clean up entries.'));
|
|
1513
1497
|
}
|
|
1514
1498
|
if (stats.entryCount === 0) {
|
|
1515
1499
|
console.log(chalk7__default.default.dim("\nNo cached entries. Fetch some documents to populate the cache."));
|
|
@@ -1527,15 +1511,15 @@ init_cjs_shims();
|
|
|
1527
1511
|
init_migrate_config();
|
|
1528
1512
|
async function fileExists2(filePath) {
|
|
1529
1513
|
try {
|
|
1530
|
-
await
|
|
1514
|
+
await fs4__namespace.access(filePath);
|
|
1531
1515
|
return true;
|
|
1532
1516
|
} catch {
|
|
1533
1517
|
return false;
|
|
1534
1518
|
}
|
|
1535
1519
|
}
|
|
1536
1520
|
async function checkConfiguration() {
|
|
1537
|
-
const configPath =
|
|
1538
|
-
const legacyConfigPath =
|
|
1521
|
+
const configPath = path2__namespace.join(process.cwd(), ".fractary", "config.yaml");
|
|
1522
|
+
const legacyConfigPath = path2__namespace.join(process.cwd(), ".fractary", "plugins", "codex", "config.json");
|
|
1539
1523
|
try {
|
|
1540
1524
|
if (!await fileExists2(configPath)) {
|
|
1541
1525
|
if (await fileExists2(legacyConfigPath)) {
|
|
@@ -1543,14 +1527,14 @@ async function checkConfiguration() {
|
|
|
1543
1527
|
name: "Configuration",
|
|
1544
1528
|
status: "warn",
|
|
1545
1529
|
message: "Legacy JSON configuration detected",
|
|
1546
|
-
details:
|
|
1530
|
+
details: "Migration from legacy JSON format may be required"
|
|
1547
1531
|
};
|
|
1548
1532
|
}
|
|
1549
1533
|
return {
|
|
1550
1534
|
name: "Configuration",
|
|
1551
1535
|
status: "fail",
|
|
1552
1536
|
message: "No configuration found",
|
|
1553
|
-
details: 'Run "fractary
|
|
1537
|
+
details: 'Run "fractary-codex configure" to create configuration'
|
|
1554
1538
|
};
|
|
1555
1539
|
}
|
|
1556
1540
|
const config = await codex.readCodexConfig(configPath);
|
|
@@ -1642,7 +1626,7 @@ async function checkCache() {
|
|
|
1642
1626
|
}
|
|
1643
1627
|
}
|
|
1644
1628
|
async function checkStorage() {
|
|
1645
|
-
const configPath =
|
|
1629
|
+
const configPath = path2__namespace.join(process.cwd(), ".fractary", "config.yaml");
|
|
1646
1630
|
try {
|
|
1647
1631
|
const config = await codex.readCodexConfig(configPath);
|
|
1648
1632
|
const providers = config.storage || [];
|
|
@@ -1706,8 +1690,8 @@ function formatSize4(bytes) {
|
|
|
1706
1690
|
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
1707
1691
|
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
1708
1692
|
}
|
|
1709
|
-
function
|
|
1710
|
-
const cmd = new commander.Command("health");
|
|
1693
|
+
function cacheHealthCommand() {
|
|
1694
|
+
const cmd = new commander.Command("cache-health");
|
|
1711
1695
|
cmd.description("Run diagnostics on codex setup").option("--json", "Output as JSON").action(async (options) => {
|
|
1712
1696
|
try {
|
|
1713
1697
|
const checks = [];
|
|
@@ -1750,8 +1734,7 @@ function healthCommand() {
|
|
|
1750
1734
|
if (failed > 0 || warned > 0) {
|
|
1751
1735
|
console.log("");
|
|
1752
1736
|
console.log(chalk7__default.default.dim("Run checks individually for more details:"));
|
|
1753
|
-
console.log(chalk7__default.default.dim(" fractary
|
|
1754
|
-
console.log(chalk7__default.default.dim(" fractary codex types list"));
|
|
1737
|
+
console.log(chalk7__default.default.dim(" fractary-codex cache-stats"));
|
|
1755
1738
|
}
|
|
1756
1739
|
if (failed > 0) {
|
|
1757
1740
|
process.exit(1);
|
|
@@ -1764,17 +1747,6 @@ function healthCommand() {
|
|
|
1764
1747
|
return cmd;
|
|
1765
1748
|
}
|
|
1766
1749
|
|
|
1767
|
-
// src/commands/cache/index.ts
|
|
1768
|
-
function cacheCommand() {
|
|
1769
|
-
const cmd = new commander.Command("cache");
|
|
1770
|
-
cmd.description("Manage the codex document cache");
|
|
1771
|
-
cmd.addCommand(cacheListCommand());
|
|
1772
|
-
cmd.addCommand(cacheClearCommand());
|
|
1773
|
-
cmd.addCommand(cacheStatsCommand());
|
|
1774
|
-
cmd.addCommand(healthCommand());
|
|
1775
|
-
return cmd;
|
|
1776
|
-
}
|
|
1777
|
-
|
|
1778
1750
|
// src/commands/sync.ts
|
|
1779
1751
|
init_cjs_shims();
|
|
1780
1752
|
init_migrate_config();
|
|
@@ -1798,15 +1770,15 @@ function formatDuration(ms) {
|
|
|
1798
1770
|
}
|
|
1799
1771
|
function syncCommand() {
|
|
1800
1772
|
const cmd = new commander.Command("sync");
|
|
1801
|
-
cmd.description("Sync single project with codex repository").argument("[name]", "Project name (auto-detected if not provided)").option("--env <env>", "Target environment (dev/test/staging/prod)", "prod").option("--dry-run", "Show what would sync without executing").option("--direction <dir>", "Sync direction (to-codex/from-codex/bidirectional)", "bidirectional").option("--include <pattern>", "Include files matching pattern (can be used multiple times)", (val, prev) => prev.concat([val]), []).option("--exclude <pattern>", "Exclude files matching pattern (can be used multiple times)", (val, prev) => prev.concat([val]), []).option("--force", "Force sync without checking timestamps").option("--json", "Output as JSON").action(async (name, options) => {
|
|
1773
|
+
cmd.description("Sync single project with codex repository").argument("[name]", "Project name (auto-detected if not provided)").option("--env <env>", "Target environment (dev/test/staging/prod)", "prod").option("--dry-run", "Show what would sync without executing").option("--direction <dir>", "Sync direction (to-codex/from-codex/bidirectional)", "bidirectional").option("--include <pattern>", "Include files matching pattern (can be used multiple times)", (val, prev) => prev.concat([val]), []).option("--exclude <pattern>", "Exclude files matching pattern (can be used multiple times)", (val, prev) => prev.concat([val]), []).option("--force", "Force sync without checking timestamps").option("--json", "Output as JSON").option("--work-id <id>", "GitHub issue number or URL to scope sync to").action(async (name, options) => {
|
|
1802
1774
|
try {
|
|
1803
|
-
const configPath =
|
|
1775
|
+
const configPath = path2__namespace.join(process.cwd(), ".fractary", "config.yaml");
|
|
1804
1776
|
let config;
|
|
1805
1777
|
try {
|
|
1806
1778
|
config = await codex.readCodexConfig(configPath);
|
|
1807
1779
|
} catch (error) {
|
|
1808
1780
|
console.error(chalk7__default.default.red("Error:"), "Codex not initialized.");
|
|
1809
|
-
console.log(chalk7__default.default.dim('Run "fractary
|
|
1781
|
+
console.log(chalk7__default.default.dim('Run "fractary-codex configure" first.'));
|
|
1810
1782
|
process.exit(1);
|
|
1811
1783
|
}
|
|
1812
1784
|
const { createSyncManager, createLocalStorage, detectCurrentProject } = await import('@fractary/codex');
|
|
@@ -1837,7 +1809,7 @@ function syncCommand() {
|
|
|
1837
1809
|
const syncManager = createSyncManager({
|
|
1838
1810
|
localStorage,
|
|
1839
1811
|
config: config.sync,
|
|
1840
|
-
manifestPath:
|
|
1812
|
+
manifestPath: path2__namespace.join(process.cwd(), ".fractary", ".codex-sync-manifest.json")
|
|
1841
1813
|
});
|
|
1842
1814
|
const defaultToCodexPatterns = [
|
|
1843
1815
|
"docs/**/*.md",
|
|
@@ -1872,7 +1844,7 @@ function syncCommand() {
|
|
|
1872
1844
|
}
|
|
1873
1845
|
const targetFiles = await Promise.all(
|
|
1874
1846
|
Array.from(matchedFilePaths).map(async (filePath) => {
|
|
1875
|
-
const fullPath =
|
|
1847
|
+
const fullPath = path2__namespace.join(sourceDir, filePath);
|
|
1876
1848
|
const stats = await import('fs/promises').then((fs8) => fs8.stat(fullPath));
|
|
1877
1849
|
return {
|
|
1878
1850
|
path: filePath,
|
|
@@ -1975,15 +1947,18 @@ function syncCommand() {
|
|
|
1975
1947
|
syncOptions
|
|
1976
1948
|
);
|
|
1977
1949
|
plan.source = sourceDir;
|
|
1978
|
-
plan.target =
|
|
1950
|
+
plan.target = path2__namespace.join(codexRepoPath, "projects", projectName);
|
|
1979
1951
|
}
|
|
1980
1952
|
if (plan.totalFiles === 0) {
|
|
1981
1953
|
if (options.json) {
|
|
1982
1954
|
console.log(JSON.stringify({
|
|
1983
1955
|
project: projectName,
|
|
1984
1956
|
organization: config.organization,
|
|
1957
|
+
workId: options.workId || null,
|
|
1985
1958
|
files: [],
|
|
1986
|
-
synced: 0
|
|
1959
|
+
synced: 0,
|
|
1960
|
+
status: "success",
|
|
1961
|
+
message: "No files to sync"
|
|
1987
1962
|
}, null, 2));
|
|
1988
1963
|
} else {
|
|
1989
1964
|
console.log(chalk7__default.default.yellow("No files to sync."));
|
|
@@ -1998,6 +1973,7 @@ function syncCommand() {
|
|
|
1998
1973
|
branch: targetBranch,
|
|
1999
1974
|
direction,
|
|
2000
1975
|
dryRun: options.dryRun || false,
|
|
1976
|
+
workId: options.workId || null,
|
|
2001
1977
|
plan: {
|
|
2002
1978
|
totalFiles: plan.totalFiles,
|
|
2003
1979
|
totalBytes: plan.totalBytes,
|
|
@@ -2012,12 +1988,24 @@ function syncCommand() {
|
|
|
2012
1988
|
}))
|
|
2013
1989
|
};
|
|
2014
1990
|
if (options.dryRun) {
|
|
2015
|
-
console.log(JSON.stringify(
|
|
1991
|
+
console.log(JSON.stringify({
|
|
1992
|
+
...output,
|
|
1993
|
+
status: "success"
|
|
1994
|
+
}, null, 2));
|
|
2016
1995
|
return;
|
|
2017
1996
|
}
|
|
2018
1997
|
const result2 = await syncManager.executePlan(plan, syncOptions);
|
|
1998
|
+
let status;
|
|
1999
|
+
if (!result2.success && result2.synced === 0) {
|
|
2000
|
+
status = "failure";
|
|
2001
|
+
} else if (!result2.success || result2.failed > 0 || plan.conflicts.length > 0) {
|
|
2002
|
+
status = "warning";
|
|
2003
|
+
} else {
|
|
2004
|
+
status = "success";
|
|
2005
|
+
}
|
|
2019
2006
|
console.log(JSON.stringify({
|
|
2020
2007
|
...output,
|
|
2008
|
+
status,
|
|
2021
2009
|
result: {
|
|
2022
2010
|
success: result2.success,
|
|
2023
2011
|
synced: result2.synced,
|
|
@@ -2151,361 +2139,20 @@ Total: ${plan.totalFiles} files (${formatBytes(plan.totalBytes)})`));
|
|
|
2151
2139
|
});
|
|
2152
2140
|
return cmd;
|
|
2153
2141
|
}
|
|
2154
|
-
|
|
2155
|
-
// src/commands/types/index.ts
|
|
2156
|
-
init_cjs_shims();
|
|
2157
|
-
|
|
2158
|
-
// src/commands/types/list.ts
|
|
2159
|
-
init_cjs_shims();
|
|
2160
|
-
function formatTtl(seconds) {
|
|
2161
|
-
if (seconds < 60) return `${seconds}s`;
|
|
2162
|
-
if (seconds < 3600) return `${Math.floor(seconds / 60)}m`;
|
|
2163
|
-
if (seconds < 86400) return `${Math.floor(seconds / 3600)}h`;
|
|
2164
|
-
return `${Math.floor(seconds / 86400)}d`;
|
|
2165
|
-
}
|
|
2166
|
-
function typesListCommand() {
|
|
2167
|
-
const cmd = new commander.Command("list");
|
|
2168
|
-
cmd.description("List all artifact types").option("--json", "Output as JSON").option("--custom-only", "Show only custom types").option("--builtin-only", "Show only built-in types").action(async (options) => {
|
|
2169
|
-
try {
|
|
2170
|
-
const client = await getClient();
|
|
2171
|
-
const registry = client.getTypeRegistry();
|
|
2172
|
-
const allTypes = registry.list();
|
|
2173
|
-
let types = allTypes;
|
|
2174
|
-
if (options.customOnly) {
|
|
2175
|
-
types = allTypes.filter((t) => !registry.isBuiltIn(t.name));
|
|
2176
|
-
} else if (options.builtinOnly) {
|
|
2177
|
-
types = allTypes.filter((t) => registry.isBuiltIn(t.name));
|
|
2178
|
-
}
|
|
2179
|
-
if (options.json) {
|
|
2180
|
-
const builtinCount = types.filter((t) => registry.isBuiltIn(t.name)).length;
|
|
2181
|
-
const customCount = types.length - builtinCount;
|
|
2182
|
-
console.log(JSON.stringify({
|
|
2183
|
-
count: types.length,
|
|
2184
|
-
builtinCount,
|
|
2185
|
-
customCount,
|
|
2186
|
-
types: types.map((t) => ({
|
|
2187
|
-
name: t.name,
|
|
2188
|
-
description: t.description,
|
|
2189
|
-
patterns: t.patterns,
|
|
2190
|
-
defaultTtl: t.defaultTtl,
|
|
2191
|
-
ttl: formatTtl(t.defaultTtl),
|
|
2192
|
-
builtin: registry.isBuiltIn(t.name),
|
|
2193
|
-
archiveAfterDays: t.archiveAfterDays,
|
|
2194
|
-
archiveStorage: t.archiveStorage
|
|
2195
|
-
}))
|
|
2196
|
-
}, null, 2));
|
|
2197
|
-
return;
|
|
2198
|
-
}
|
|
2199
|
-
if (types.length === 0) {
|
|
2200
|
-
console.log(chalk7__default.default.yellow("No types found."));
|
|
2201
|
-
return;
|
|
2202
|
-
}
|
|
2203
|
-
console.log(chalk7__default.default.bold("Artifact Types\n"));
|
|
2204
|
-
const builtinTypes = types.filter((t) => registry.isBuiltIn(t.name));
|
|
2205
|
-
const customTypes = types.filter((t) => !registry.isBuiltIn(t.name));
|
|
2206
|
-
if (builtinTypes.length > 0 && !options.customOnly) {
|
|
2207
|
-
console.log(chalk7__default.default.bold("Built-in Types"));
|
|
2208
|
-
console.log(chalk7__default.default.dim("\u2500".repeat(70)));
|
|
2209
|
-
for (const type of builtinTypes) {
|
|
2210
|
-
const patternStr = type.patterns[0] || "";
|
|
2211
|
-
console.log(` ${chalk7__default.default.cyan(type.name.padEnd(12))} ${patternStr.padEnd(30)} ${chalk7__default.default.dim(`TTL: ${formatTtl(type.defaultTtl)}`)}`);
|
|
2212
|
-
console.log(` ${chalk7__default.default.dim(" ".repeat(12) + type.description)}`);
|
|
2213
|
-
}
|
|
2214
|
-
console.log("");
|
|
2215
|
-
}
|
|
2216
|
-
if (customTypes.length > 0 && !options.builtinOnly) {
|
|
2217
|
-
console.log(chalk7__default.default.bold("Custom Types"));
|
|
2218
|
-
console.log(chalk7__default.default.dim("\u2500".repeat(70)));
|
|
2219
|
-
for (const type of customTypes) {
|
|
2220
|
-
const patternStr = type.patterns[0] || "";
|
|
2221
|
-
console.log(` ${chalk7__default.default.green(type.name.padEnd(12))} ${patternStr.padEnd(30)} ${chalk7__default.default.dim(`TTL: ${formatTtl(type.defaultTtl)}`)}`);
|
|
2222
|
-
console.log(` ${chalk7__default.default.dim(" ".repeat(12) + type.description)}`);
|
|
2223
|
-
}
|
|
2224
|
-
console.log("");
|
|
2225
|
-
}
|
|
2226
|
-
console.log(chalk7__default.default.dim(`Total: ${types.length} types (${builtinTypes.length} built-in, ${customTypes.length} custom)`));
|
|
2227
|
-
} catch (error) {
|
|
2228
|
-
console.error(chalk7__default.default.red("Error:"), error.message);
|
|
2229
|
-
process.exit(1);
|
|
2230
|
-
}
|
|
2231
|
-
});
|
|
2232
|
-
return cmd;
|
|
2233
|
-
}
|
|
2234
|
-
|
|
2235
|
-
// src/commands/types/show.ts
|
|
2236
|
-
init_cjs_shims();
|
|
2237
|
-
function formatTtl2(seconds) {
|
|
2238
|
-
if (seconds < 60) return `${seconds}s`;
|
|
2239
|
-
if (seconds < 3600) return `${Math.floor(seconds / 60)}m`;
|
|
2240
|
-
if (seconds < 86400) return `${Math.floor(seconds / 3600)}h`;
|
|
2241
|
-
return `${Math.floor(seconds / 86400)}d`;
|
|
2242
|
-
}
|
|
2243
|
-
function typesShowCommand() {
|
|
2244
|
-
const cmd = new commander.Command("show");
|
|
2245
|
-
cmd.description("Show details for a specific type").argument("<name>", "Type name").option("--json", "Output as JSON").action(async (name, options) => {
|
|
2246
|
-
try {
|
|
2247
|
-
const client = await getClient();
|
|
2248
|
-
const registry = client.getTypeRegistry();
|
|
2249
|
-
const type = registry.get(name);
|
|
2250
|
-
if (!type) {
|
|
2251
|
-
console.error(chalk7__default.default.red("Error:"), `Type "${name}" not found.`);
|
|
2252
|
-
console.log(chalk7__default.default.dim('Run "fractary codex types list" to see available types.'));
|
|
2253
|
-
process.exit(1);
|
|
2254
|
-
}
|
|
2255
|
-
const isBuiltin = registry.isBuiltIn(name);
|
|
2256
|
-
if (options.json) {
|
|
2257
|
-
console.log(JSON.stringify({
|
|
2258
|
-
name: type.name,
|
|
2259
|
-
builtin: isBuiltin,
|
|
2260
|
-
description: type.description,
|
|
2261
|
-
patterns: type.patterns,
|
|
2262
|
-
defaultTtl: type.defaultTtl,
|
|
2263
|
-
ttl: formatTtl2(type.defaultTtl),
|
|
2264
|
-
archiveAfterDays: type.archiveAfterDays,
|
|
2265
|
-
archiveStorage: type.archiveStorage,
|
|
2266
|
-
syncPatterns: type.syncPatterns,
|
|
2267
|
-
excludePatterns: type.excludePatterns
|
|
2268
|
-
}, null, 2));
|
|
2269
|
-
return;
|
|
2270
|
-
}
|
|
2271
|
-
const nameColor = isBuiltin ? chalk7__default.default.cyan : chalk7__default.default.green;
|
|
2272
|
-
console.log(chalk7__default.default.bold(`Type: ${nameColor(name)}
|
|
2273
|
-
`));
|
|
2274
|
-
console.log(` ${chalk7__default.default.dim("Source:")} ${isBuiltin ? "Built-in" : "Custom"}`);
|
|
2275
|
-
console.log(` ${chalk7__default.default.dim("Description:")} ${type.description}`);
|
|
2276
|
-
console.log(` ${chalk7__default.default.dim("TTL:")} ${formatTtl2(type.defaultTtl)} (${type.defaultTtl} seconds)`);
|
|
2277
|
-
console.log("");
|
|
2278
|
-
console.log(chalk7__default.default.bold("Patterns"));
|
|
2279
|
-
for (const pattern of type.patterns) {
|
|
2280
|
-
console.log(` ${chalk7__default.default.dim("\u2022")} ${pattern}`);
|
|
2281
|
-
}
|
|
2282
|
-
if (type.archiveAfterDays !== null) {
|
|
2283
|
-
console.log("");
|
|
2284
|
-
console.log(chalk7__default.default.bold("Archive Settings"));
|
|
2285
|
-
console.log(` ${chalk7__default.default.dim("After:")} ${type.archiveAfterDays} days`);
|
|
2286
|
-
console.log(` ${chalk7__default.default.dim("Storage:")} ${type.archiveStorage || "not set"}`);
|
|
2287
|
-
}
|
|
2288
|
-
if (type.syncPatterns && type.syncPatterns.length > 0) {
|
|
2289
|
-
console.log("");
|
|
2290
|
-
console.log(chalk7__default.default.bold("Sync Patterns"));
|
|
2291
|
-
for (const pattern of type.syncPatterns) {
|
|
2292
|
-
console.log(` ${chalk7__default.default.dim("\u2022")} ${pattern}`);
|
|
2293
|
-
}
|
|
2294
|
-
}
|
|
2295
|
-
if (type.excludePatterns && type.excludePatterns.length > 0) {
|
|
2296
|
-
console.log("");
|
|
2297
|
-
console.log(chalk7__default.default.bold("Exclude Patterns"));
|
|
2298
|
-
for (const pattern of type.excludePatterns) {
|
|
2299
|
-
console.log(` ${chalk7__default.default.dim("\u2022")} ${pattern}`);
|
|
2300
|
-
}
|
|
2301
|
-
}
|
|
2302
|
-
} catch (error) {
|
|
2303
|
-
console.error(chalk7__default.default.red("Error:"), error.message);
|
|
2304
|
-
process.exit(1);
|
|
2305
|
-
}
|
|
2306
|
-
});
|
|
2307
|
-
return cmd;
|
|
2308
|
-
}
|
|
2309
|
-
|
|
2310
|
-
// src/commands/types/add.ts
|
|
2311
|
-
init_cjs_shims();
|
|
2312
|
-
init_migrate_config();
|
|
2313
|
-
function isValidTypeName(name) {
|
|
2314
|
-
return /^[a-z][a-z0-9-]*$/.test(name);
|
|
2315
|
-
}
|
|
2316
|
-
function parseTtl(ttl) {
|
|
2317
|
-
const match = ttl.match(/^(\d+)([smhd])$/);
|
|
2318
|
-
if (!match) {
|
|
2319
|
-
throw new Error("Invalid TTL format");
|
|
2320
|
-
}
|
|
2321
|
-
const value = parseInt(match[1], 10);
|
|
2322
|
-
const unit = match[2];
|
|
2323
|
-
switch (unit) {
|
|
2324
|
-
case "s":
|
|
2325
|
-
return value;
|
|
2326
|
-
case "m":
|
|
2327
|
-
return value * 60;
|
|
2328
|
-
case "h":
|
|
2329
|
-
return value * 3600;
|
|
2330
|
-
case "d":
|
|
2331
|
-
return value * 86400;
|
|
2332
|
-
default:
|
|
2333
|
-
throw new Error("Unknown TTL unit");
|
|
2334
|
-
}
|
|
2335
|
-
}
|
|
2336
|
-
function formatTtl3(seconds) {
|
|
2337
|
-
if (seconds < 60) return `${seconds}s`;
|
|
2338
|
-
if (seconds < 3600) return `${Math.floor(seconds / 60)}m`;
|
|
2339
|
-
if (seconds < 86400) return `${Math.floor(seconds / 3600)}h`;
|
|
2340
|
-
return `${Math.floor(seconds / 86400)}d`;
|
|
2341
|
-
}
|
|
2342
|
-
function typesAddCommand() {
|
|
2343
|
-
const cmd = new commander.Command("add");
|
|
2344
|
-
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) => {
|
|
2345
|
-
try {
|
|
2346
|
-
if (!isValidTypeName(name)) {
|
|
2347
|
-
console.error(chalk7__default.default.red("Error:"), "Invalid type name.");
|
|
2348
|
-
console.log(chalk7__default.default.dim("Type name must be lowercase, start with a letter, and contain only letters, numbers, and hyphens."));
|
|
2349
|
-
process.exit(1);
|
|
2350
|
-
}
|
|
2351
|
-
const client = await getClient();
|
|
2352
|
-
const registry = client.getTypeRegistry();
|
|
2353
|
-
if (registry.isBuiltIn(name)) {
|
|
2354
|
-
console.error(chalk7__default.default.red("Error:"), `Cannot override built-in type "${name}".`);
|
|
2355
|
-
const builtinNames = registry.list().filter((t) => registry.isBuiltIn(t.name)).map((t) => t.name);
|
|
2356
|
-
console.log(chalk7__default.default.dim("Built-in types: " + builtinNames.join(", ")));
|
|
2357
|
-
process.exit(1);
|
|
2358
|
-
}
|
|
2359
|
-
if (registry.has(name)) {
|
|
2360
|
-
console.error(chalk7__default.default.red("Error:"), `Custom type "${name}" already exists.`);
|
|
2361
|
-
console.log(chalk7__default.default.dim('Use "fractary codex types remove" first to remove it.'));
|
|
2362
|
-
process.exit(1);
|
|
2363
|
-
}
|
|
2364
|
-
let ttlSeconds;
|
|
2365
|
-
try {
|
|
2366
|
-
ttlSeconds = parseTtl(options.ttl);
|
|
2367
|
-
} catch {
|
|
2368
|
-
console.error(chalk7__default.default.red("Error:"), "Invalid TTL format.");
|
|
2369
|
-
console.log(chalk7__default.default.dim("Expected format: <number><unit> where unit is s (seconds), m (minutes), h (hours), or d (days)"));
|
|
2370
|
-
console.log(chalk7__default.default.dim("Examples: 30m, 24h, 7d"));
|
|
2371
|
-
process.exit(1);
|
|
2372
|
-
}
|
|
2373
|
-
const configPath = path4__namespace.join(process.cwd(), ".fractary", "config.yaml");
|
|
2374
|
-
const config = await codex.readCodexConfig(configPath);
|
|
2375
|
-
if (!config.types) {
|
|
2376
|
-
config.types = { custom: {} };
|
|
2377
|
-
}
|
|
2378
|
-
if (!config.types.custom) {
|
|
2379
|
-
config.types.custom = {};
|
|
2380
|
-
}
|
|
2381
|
-
config.types.custom[name] = {
|
|
2382
|
-
description: options.description || `Custom type: ${name}`,
|
|
2383
|
-
patterns: [options.pattern],
|
|
2384
|
-
defaultTtl: ttlSeconds
|
|
2385
|
-
};
|
|
2386
|
-
await writeYamlConfig(config, configPath);
|
|
2387
|
-
if (options.json) {
|
|
2388
|
-
console.log(JSON.stringify({
|
|
2389
|
-
success: true,
|
|
2390
|
-
type: {
|
|
2391
|
-
name,
|
|
2392
|
-
description: config.types.custom[name].description,
|
|
2393
|
-
patterns: config.types.custom[name].patterns,
|
|
2394
|
-
defaultTtl: ttlSeconds,
|
|
2395
|
-
ttl: formatTtl3(ttlSeconds),
|
|
2396
|
-
builtin: false
|
|
2397
|
-
},
|
|
2398
|
-
message: "Custom type added successfully. Changes will take effect on next CLI invocation."
|
|
2399
|
-
}, null, 2));
|
|
2400
|
-
return;
|
|
2401
|
-
}
|
|
2402
|
-
console.log(chalk7__default.default.green("\u2713"), `Added custom type "${chalk7__default.default.cyan(name)}"`);
|
|
2403
|
-
console.log("");
|
|
2404
|
-
console.log(` ${chalk7__default.default.dim("Pattern:")} ${options.pattern}`);
|
|
2405
|
-
console.log(` ${chalk7__default.default.dim("TTL:")} ${formatTtl3(ttlSeconds)} (${ttlSeconds} seconds)`);
|
|
2406
|
-
if (options.description) {
|
|
2407
|
-
console.log(` ${chalk7__default.default.dim("Description:")} ${options.description}`);
|
|
2408
|
-
}
|
|
2409
|
-
console.log("");
|
|
2410
|
-
console.log(chalk7__default.default.dim("Note: Custom type will be available on next CLI invocation."));
|
|
2411
|
-
} catch (error) {
|
|
2412
|
-
console.error(chalk7__default.default.red("Error:"), error.message);
|
|
2413
|
-
if (error.message.includes("Failed to load configuration")) {
|
|
2414
|
-
console.log(chalk7__default.default.dim('\nRun "fractary codex init" to create a configuration.'));
|
|
2415
|
-
}
|
|
2416
|
-
process.exit(1);
|
|
2417
|
-
}
|
|
2418
|
-
});
|
|
2419
|
-
return cmd;
|
|
2420
|
-
}
|
|
2421
|
-
|
|
2422
|
-
// src/commands/types/remove.ts
|
|
2423
|
-
init_cjs_shims();
|
|
2424
|
-
init_migrate_config();
|
|
2425
|
-
function typesRemoveCommand() {
|
|
2426
|
-
const cmd = new commander.Command("remove");
|
|
2427
|
-
cmd.description("Remove a custom artifact type").argument("<name>", "Type name to remove").option("--json", "Output as JSON").option("--force", "Skip confirmation").action(async (name, options) => {
|
|
2428
|
-
try {
|
|
2429
|
-
const client = await getClient();
|
|
2430
|
-
const registry = client.getTypeRegistry();
|
|
2431
|
-
if (registry.isBuiltIn(name)) {
|
|
2432
|
-
console.error(chalk7__default.default.red("Error:"), `Cannot remove built-in type "${name}".`);
|
|
2433
|
-
console.log(chalk7__default.default.dim("Built-in types are permanent and cannot be removed."));
|
|
2434
|
-
process.exit(1);
|
|
2435
|
-
}
|
|
2436
|
-
if (!registry.has(name)) {
|
|
2437
|
-
console.error(chalk7__default.default.red("Error:"), `Custom type "${name}" not found.`);
|
|
2438
|
-
console.log(chalk7__default.default.dim('Run "fractary codex types list --custom-only" to see custom types.'));
|
|
2439
|
-
process.exit(1);
|
|
2440
|
-
}
|
|
2441
|
-
const typeInfo = registry.get(name);
|
|
2442
|
-
const configPath = path4__namespace.join(process.cwd(), ".fractary", "config.yaml");
|
|
2443
|
-
const config = await codex.readCodexConfig(configPath);
|
|
2444
|
-
if (!config.types?.custom?.[name]) {
|
|
2445
|
-
console.error(chalk7__default.default.red("Error:"), `Custom type "${name}" not found in configuration.`);
|
|
2446
|
-
process.exit(1);
|
|
2447
|
-
}
|
|
2448
|
-
delete config.types.custom[name];
|
|
2449
|
-
if (Object.keys(config.types.custom).length === 0) {
|
|
2450
|
-
delete config.types.custom;
|
|
2451
|
-
}
|
|
2452
|
-
if (config.types && Object.keys(config.types).length === 0) {
|
|
2453
|
-
delete config.types;
|
|
2454
|
-
}
|
|
2455
|
-
await writeYamlConfig(config, configPath);
|
|
2456
|
-
if (options.json) {
|
|
2457
|
-
console.log(JSON.stringify({
|
|
2458
|
-
success: true,
|
|
2459
|
-
removed: {
|
|
2460
|
-
name: typeInfo.name,
|
|
2461
|
-
description: typeInfo.description,
|
|
2462
|
-
patterns: typeInfo.patterns,
|
|
2463
|
-
defaultTtl: typeInfo.defaultTtl
|
|
2464
|
-
},
|
|
2465
|
-
message: "Custom type removed successfully. Changes will take effect on next CLI invocation."
|
|
2466
|
-
}, null, 2));
|
|
2467
|
-
return;
|
|
2468
|
-
}
|
|
2469
|
-
console.log(chalk7__default.default.green("\u2713"), `Removed custom type "${chalk7__default.default.cyan(name)}"`);
|
|
2470
|
-
console.log("");
|
|
2471
|
-
console.log(chalk7__default.default.dim("Removed configuration:"));
|
|
2472
|
-
console.log(` ${chalk7__default.default.dim("Pattern:")} ${typeInfo.patterns.join(", ")}`);
|
|
2473
|
-
console.log(` ${chalk7__default.default.dim("Description:")} ${typeInfo.description}`);
|
|
2474
|
-
console.log("");
|
|
2475
|
-
console.log(chalk7__default.default.dim("Note: Custom type will be removed on next CLI invocation."));
|
|
2476
|
-
} catch (error) {
|
|
2477
|
-
console.error(chalk7__default.default.red("Error:"), error.message);
|
|
2478
|
-
if (error.message.includes("Failed to load configuration")) {
|
|
2479
|
-
console.log(chalk7__default.default.dim('\nRun "fractary codex init" to create a configuration.'));
|
|
2480
|
-
}
|
|
2481
|
-
process.exit(1);
|
|
2482
|
-
}
|
|
2483
|
-
});
|
|
2484
|
-
return cmd;
|
|
2485
|
-
}
|
|
2486
|
-
|
|
2487
|
-
// src/commands/types/index.ts
|
|
2488
|
-
function typesCommand() {
|
|
2489
|
-
const cmd = new commander.Command("types");
|
|
2490
|
-
cmd.description("Manage artifact type registry");
|
|
2491
|
-
cmd.addCommand(typesListCommand());
|
|
2492
|
-
cmd.addCommand(typesShowCommand());
|
|
2493
|
-
cmd.addCommand(typesAddCommand());
|
|
2494
|
-
cmd.addCommand(typesRemoveCommand());
|
|
2495
|
-
return cmd;
|
|
2496
|
-
}
|
|
2497
2142
|
var __filename2 = url.fileURLToPath(importMetaUrl);
|
|
2498
|
-
var __dirname$1 =
|
|
2499
|
-
var packageJson = JSON.parse(fs.readFileSync(
|
|
2143
|
+
var __dirname$1 = path2.dirname(__filename2);
|
|
2144
|
+
var packageJson = JSON.parse(fs.readFileSync(path2.join(__dirname$1, "../package.json"), "utf-8"));
|
|
2500
2145
|
var VERSION = packageJson.version;
|
|
2501
2146
|
function createCLI() {
|
|
2502
2147
|
const program = new commander.Command("fractary-codex");
|
|
2503
2148
|
program.description("Centralized knowledge management and distribution for AI agents").version(VERSION);
|
|
2504
|
-
program.addCommand(
|
|
2505
|
-
program.addCommand(
|
|
2506
|
-
program.addCommand(
|
|
2149
|
+
program.addCommand(configureCommand());
|
|
2150
|
+
program.addCommand(documentFetchCommand());
|
|
2151
|
+
program.addCommand(cacheListCommand());
|
|
2152
|
+
program.addCommand(cacheClearCommand());
|
|
2153
|
+
program.addCommand(cacheStatsCommand());
|
|
2154
|
+
program.addCommand(cacheHealthCommand());
|
|
2507
2155
|
program.addCommand(syncCommand());
|
|
2508
|
-
program.addCommand(typesCommand());
|
|
2509
2156
|
return program;
|
|
2510
2157
|
}
|
|
2511
2158
|
async function main() {
|