@fractary/codex 0.11.2 → 0.12.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -3,7 +3,8 @@ import * as path3 from 'path';
3
3
  import path3__default from 'path';
4
4
  import { execFile, execSync } from 'child_process';
5
5
  import { z } from 'zod';
6
- import yaml from 'js-yaml';
6
+ import * as yaml2 from 'js-yaml';
7
+ import yaml2__default from 'js-yaml';
7
8
  import * as fs3 from 'fs/promises';
8
9
  import fs3__default from 'fs/promises';
9
10
  import { promisify } from 'util';
@@ -63,11 +64,14 @@ function matchToCodexPattern(filePath, patterns) {
63
64
  }
64
65
  return patterns.some((pattern) => matchPattern(pattern, filePath));
65
66
  }
66
- function matchFromCodexPattern(codexFilePath, patterns, targetProject) {
67
+ function matchFromCodexPattern(codexFilePath, patterns, targetProject, options) {
67
68
  if (!patterns || patterns.length === 0) {
68
69
  return false;
69
70
  }
70
71
  return patterns.some((pattern) => {
72
+ if (pattern.startsWith(CODEX_URI_PREFIX2)) {
73
+ return matchCodexUri(pattern, codexFilePath, targetProject, options);
74
+ }
71
75
  if (pattern.startsWith("projects/")) {
72
76
  return matchPattern(pattern, codexFilePath);
73
77
  }
@@ -85,6 +89,21 @@ function matchFromCodexPattern(codexFilePath, patterns, targetProject) {
85
89
  }
86
90
  });
87
91
  }
92
+ function matchCodexUri(uriPattern, codexFilePath, targetProject, options) {
93
+ let withoutPrefix = uriPattern.slice(CODEX_URI_PREFIX2.length);
94
+ withoutPrefix = withoutPrefix.replace(/{org}/g, options?.org || "").replace(/{project}/g, targetProject).replace(/{codex_repo}/g, options?.codexRepo || "");
95
+ const parts = withoutPrefix.split("/");
96
+ if (parts.length < 2) {
97
+ return false;
98
+ }
99
+ const project = parts[1];
100
+ const pathPattern = parts.slice(2).join("/");
101
+ if (!project) {
102
+ return false;
103
+ }
104
+ const fullPattern = pathPattern ? `projects/${project}/${pathPattern}` : `projects/${project}/**`;
105
+ return matchPattern(fullPattern, codexFilePath);
106
+ }
88
107
  function extractProjectFromCodexPath(codexFilePath) {
89
108
  const firstSlashIndex = codexFilePath.indexOf("/");
90
109
  if (firstSlashIndex === -1) {
@@ -99,15 +118,26 @@ function getRelativePath(codexFilePath) {
99
118
  }
100
119
  return codexFilePath.substring(firstSlashIndex + 1);
101
120
  }
102
- function expandPlaceholders(patterns, targetProject) {
121
+ function expandPlaceholders(patterns, targetProject, options) {
103
122
  if (!patterns) {
104
123
  return patterns;
105
124
  }
106
- return patterns.map((pattern) => pattern.replace(/{project}/g, targetProject));
125
+ return patterns.map((pattern) => {
126
+ let expanded = pattern.replace(/{project}/g, targetProject);
127
+ if (options?.org) {
128
+ expanded = expanded.replace(/{org}/g, options.org);
129
+ }
130
+ if (options?.codexRepo) {
131
+ expanded = expanded.replace(/{codex_repo}/g, options.codexRepo);
132
+ }
133
+ return expanded;
134
+ });
107
135
  }
136
+ var CODEX_URI_PREFIX2;
108
137
  var init_directional_patterns = __esm({
109
138
  "src/sync/directional-patterns.ts"() {
110
139
  init_matcher();
140
+ CODEX_URI_PREFIX2 = "codex://";
111
141
  }
112
142
  });
113
143
 
@@ -992,7 +1022,7 @@ function parseMetadata(content, options = {}) {
992
1022
  const rawFrontmatter = frontmatterMatch[1];
993
1023
  const documentContent = frontmatterMatch[2];
994
1024
  try {
995
- const parsed = yaml.load(rawFrontmatter);
1025
+ const parsed = yaml2__default.load(rawFrontmatter);
996
1026
  const normalized = normalizeLegacyMetadata(parsed);
997
1027
  const metadata = strict ? MetadataSchema.parse(normalized) : MetadataSchema.safeParse(normalized).data || {};
998
1028
  return {
@@ -3505,6 +3535,7 @@ async function scanCodexWithRouting(options) {
3505
3535
  codexDir,
3506
3536
  targetProject,
3507
3537
  org,
3538
+ codexRepo,
3508
3539
  rules,
3509
3540
  storage,
3510
3541
  skipNoFrontmatter = false,
@@ -3523,7 +3554,10 @@ async function scanCodexWithRouting(options) {
3523
3554
  if (fromCodexPatterns && fromCodexPatterns.length > 0) {
3524
3555
  const module = await Promise.resolve().then(() => (init_directional_patterns(), directional_patterns_exports));
3525
3556
  matchFromCodexPattern2 = module.matchFromCodexPattern;
3526
- expandedFromCodexPatterns = module.expandPlaceholders(fromCodexPatterns, targetProject);
3557
+ expandedFromCodexPatterns = module.expandPlaceholders(fromCodexPatterns, targetProject, {
3558
+ org,
3559
+ codexRepo
3560
+ });
3527
3561
  }
3528
3562
  const allFiles = await listAllFilesRecursive(codexDir);
3529
3563
  for (const filePath of allFiles) {
@@ -3545,7 +3579,10 @@ async function scanCodexWithRouting(options) {
3545
3579
  let parseResult = null;
3546
3580
  const useFrontmatter = options.routing?.use_frontmatter === true;
3547
3581
  if (matchFromCodexPattern2 && expandedFromCodexPatterns && expandedFromCodexPatterns.length > 0) {
3548
- shouldSync = matchFromCodexPattern2(filePath, expandedFromCodexPatterns, targetProject);
3582
+ shouldSync = matchFromCodexPattern2(filePath, expandedFromCodexPatterns, targetProject, {
3583
+ org,
3584
+ codexRepo
3585
+ });
3549
3586
  parseResult = parseMetadata(content, { strict: false });
3550
3587
  } else if (useFrontmatter) {
3551
3588
  parseResult = parseMetadata(content, { strict: false });
@@ -3826,6 +3863,8 @@ var SyncManager = class {
3826
3863
  codexDir,
3827
3864
  targetProject: project,
3828
3865
  org,
3866
+ codexRepo: options?.codexRepo,
3867
+ // For codex:// URI {codex_repo} placeholder
3829
3868
  rules: void 0,
3830
3869
  // Use default routing rules (preventSelfSync, preventCodexSync, etc.)
3831
3870
  storage: this.localStorage,
@@ -3891,17 +3930,17 @@ var SyncManager = class {
3891
3930
  if (file.operation === "create" || file.operation === "update") {
3892
3931
  const sourcePath = `${plan.source}/${file.path}`;
3893
3932
  const targetPath = `${plan.target}/${file.path}`;
3894
- const fs5 = await import('fs/promises');
3933
+ const fs6 = await import('fs/promises');
3895
3934
  const path7 = await import('path');
3896
3935
  const targetDir = path7.dirname(targetPath);
3897
- await fs5.mkdir(targetDir, { recursive: true });
3898
- await fs5.copyFile(sourcePath, targetPath);
3936
+ await fs6.mkdir(targetDir, { recursive: true });
3937
+ await fs6.copyFile(sourcePath, targetPath);
3899
3938
  synced++;
3900
3939
  } else if (file.operation === "delete") {
3901
3940
  const targetPath = `${plan.target}/${file.path}`;
3902
- const fs5 = await import('fs/promises');
3941
+ const fs6 = await import('fs/promises');
3903
3942
  try {
3904
- await fs5.unlink(targetPath);
3943
+ await fs6.unlink(targetPath);
3905
3944
  synced++;
3906
3945
  } catch (error) {
3907
3946
  if (error.code !== "ENOENT") {
@@ -4906,6 +4945,176 @@ function generateReferenceMigrationSummary(results) {
4906
4945
  return lines.join("\n");
4907
4946
  }
4908
4947
 
4909
- export { AutoSyncPatternSchema, BUILT_IN_TYPES, CODEX_URI_PREFIX, CacheManager, CachePersistence, CodexConfigSchema, CodexError, CommonRules, ConfigurationError, CustomTypeSchema, DEFAULT_CACHE_DIR, DEFAULT_FETCH_OPTIONS, DEFAULT_MIGRATION_OPTIONS, DEFAULT_PERMISSION_CONFIG, DEFAULT_SYNC_CONFIG, DEFAULT_TYPE, FilePluginFileNotFoundError, FilePluginStorage, GitHubStorage, HttpStorage, LEGACY_PATTERNS, LEGACY_REF_PREFIX, LocalStorage, MetadataSchema, PERMISSION_LEVEL_ORDER, PermissionDeniedError, PermissionManager, StorageManager, SyncManager, SyncRulesSchema, TTL, TypeRegistry, TypesConfigSchema, ValidationError, buildUri, calculateCachePath, calculateContentHash, convertLegacyReference, convertLegacyReferences, convertToUri, createCacheEntry, createCacheManager, createCachePersistence, createDefaultRegistry, createEmptyModernConfig, createEmptySyncPlan, createGitHubStorage, createHttpStorage, createLocalStorage, createPermissionManager, createRule, createRulesFromPatterns, createStorageManager, createSyncManager, createSyncPlan, deserializeCacheEntry, detectContentType, detectCurrentProject, detectVersion, estimateSyncTime, evaluatePath, evaluatePaths, evaluatePatterns, evaluatePermission, evaluatePermissions, extendType, extractOrgFromRepoName, extractRawFrontmatter, filterByPatterns, filterByPermission, filterPlanOperations, filterSyncablePaths, findLegacyReferences, formatPlanSummary, generateMigrationReport, generateReferenceMigrationSummary, getBuiltInType, getBuiltInTypeNames, getCacheEntryAge, getCacheEntryStatus, getCurrentContext, getCustomSyncDestinations, getDefaultCacheManager, getDefaultConfig, getDefaultDirectories, getDefaultPermissionManager, getDefaultRules, getDefaultStorageManager, getDirectory, getExtension, getFilename, getMigrationRequirements, getPlanStats, getRelativeCachePath, getRemainingTtl, getTargetRepos, hasContentChanged, hasFrontmatter, hasLegacyReferences, hasPermission as hasPermissionLevel, isBuiltInType, isCacheEntryFresh, isCacheEntryValid, isCurrentProjectUri, isLegacyConfig, isLegacyReference, isModernConfig, isAllowed as isPermissionAllowed, isValidUri, levelGrants, loadConfig, loadCustomTypes, matchAnyPattern, matchPattern, maxLevel, mergeFetchOptions, mergeRules, mergeTypes, migrateConfig, migrateFileReferences, minLevel, needsMigration, parseCustomDestination, parseMetadata, parseReference, parseTtl, resolveOrganization, resolveReference, resolveReferences, ruleMatchesAction, ruleMatchesContext, ruleMatchesPath, sanitizePath, serializeCacheEntry, setDefaultCacheManager, setDefaultPermissionManager, setDefaultStorageManager, shouldSyncToRepo, summarizeEvaluations, touchCacheEntry, validateCustomTypes, validateMetadata, validateMigratedConfig, validateOrg, validatePath, validateRules2 as validatePermissionRules, validateProject, validateRules, validateUri };
4948
+ // src/core/env/index.ts
4949
+ function expandEnvVars(value, options = {}) {
4950
+ const env = options.env ?? process.env;
4951
+ return value.replace(/\$\{([^}]+)\}/g, (match, varName) => {
4952
+ const envValue = env[varName];
4953
+ if (envValue === void 0) {
4954
+ if (options.warnOnMissing) {
4955
+ console.warn(`Warning: Environment variable ${varName} is not set`);
4956
+ }
4957
+ if (options.onMissing) {
4958
+ options.onMissing(varName);
4959
+ }
4960
+ return match;
4961
+ }
4962
+ return envValue;
4963
+ });
4964
+ }
4965
+ function expandEnvVarsInConfig(config, options = {}) {
4966
+ if (typeof config === "string") {
4967
+ return expandEnvVars(config, options);
4968
+ }
4969
+ if (Array.isArray(config)) {
4970
+ return config.map((item) => expandEnvVarsInConfig(item, options));
4971
+ }
4972
+ if (config !== null && typeof config === "object") {
4973
+ const result = {};
4974
+ for (const [key, value] of Object.entries(config)) {
4975
+ result[key] = expandEnvVarsInConfig(value, options);
4976
+ }
4977
+ return result;
4978
+ }
4979
+ return config;
4980
+ }
4981
+ function hasEnvVars(value) {
4982
+ return /\$\{[^}]+\}/.test(value);
4983
+ }
4984
+ function extractEnvVarNames(value) {
4985
+ const matches = value.matchAll(/\$\{([^}]+)\}/g);
4986
+ const names = [];
4987
+ for (const match of matches) {
4988
+ if (match[1]) {
4989
+ names.push(match[1]);
4990
+ }
4991
+ }
4992
+ return names;
4993
+ }
4994
+ async function readCodexConfig(configPath, options = {}) {
4995
+ const content = await fs3.readFile(configPath, "utf-8");
4996
+ const rawConfig = yaml2.load(content);
4997
+ let config;
4998
+ if (rawConfig?.codex && typeof rawConfig.codex === "object") {
4999
+ config = rawConfig.codex;
5000
+ } else {
5001
+ config = rawConfig;
5002
+ }
5003
+ if (!config.organization) {
5004
+ throw new Error("Invalid config: organization is required");
5005
+ }
5006
+ if (options.expandEnv !== false) {
5007
+ const envOptions = {
5008
+ env: options.env,
5009
+ warnOnMissing: options.warnOnMissingEnv
5010
+ };
5011
+ config = expandEnvVarsInConfig(config, envOptions);
5012
+ }
5013
+ return config;
5014
+ }
5015
+ async function readUnifiedConfig(configPath, options = {}) {
5016
+ const content = await fs3.readFile(configPath, "utf-8");
5017
+ let config = yaml2.load(content);
5018
+ if (options.expandEnv !== false) {
5019
+ const envOptions = {
5020
+ env: options.env,
5021
+ warnOnMissing: options.warnOnMissingEnv
5022
+ };
5023
+ config = expandEnvVarsInConfig(config, envOptions);
5024
+ }
5025
+ return config;
5026
+ }
5027
+ function isUnifiedConfig(config) {
5028
+ if (config === null || typeof config !== "object") {
5029
+ return false;
5030
+ }
5031
+ const maybeUnified = config;
5032
+ return "codex" in maybeUnified && maybeUnified.codex !== null && typeof maybeUnified.codex === "object";
5033
+ }
5034
+
5035
+ // src/core/utils/index.ts
5036
+ var DURATION_MULTIPLIERS = {
5037
+ s: 1,
5038
+ // seconds
5039
+ m: 60,
5040
+ // minutes
5041
+ h: 3600,
5042
+ // hours
5043
+ d: 86400,
5044
+ // days
5045
+ w: 604800,
5046
+ // weeks (7 days)
5047
+ M: 2592e3,
5048
+ // months (30 days)
5049
+ y: 31536e3
5050
+ // years (365 days)
5051
+ };
5052
+ var SIZE_MULTIPLIERS = {
5053
+ B: 1,
5054
+ KB: 1024,
5055
+ MB: 1024 * 1024,
5056
+ GB: 1024 * 1024 * 1024,
5057
+ TB: 1024 * 1024 * 1024 * 1024
5058
+ };
5059
+ function parseDuration(duration) {
5060
+ if (typeof duration === "number") {
5061
+ return duration;
5062
+ }
5063
+ const match = duration.match(/^(\d+(?:\.\d+)?)\s*([smhdwMy])$/);
5064
+ if (!match || !match[1] || !match[2]) {
5065
+ throw new Error(`Invalid duration format: ${duration}. Use format like "1h", "7d", "1M"`);
5066
+ }
5067
+ const valueStr = match[1];
5068
+ const unit = match[2];
5069
+ const value = parseFloat(valueStr);
5070
+ const multiplier = DURATION_MULTIPLIERS[unit];
5071
+ if (multiplier === void 0) {
5072
+ throw new Error(`Unknown duration unit: ${unit}`);
5073
+ }
5074
+ return Math.round(value * multiplier);
5075
+ }
5076
+ function parseSize(size) {
5077
+ if (typeof size === "number") {
5078
+ return size;
5079
+ }
5080
+ const match = size.match(/^(\d+(?:\.\d+)?)\s*(B|KB|MB|GB|TB)$/i);
5081
+ if (!match || !match[1] || !match[2]) {
5082
+ throw new Error(`Invalid size format: ${size}. Use format like "100MB", "1GB"`);
5083
+ }
5084
+ const valueStr = match[1];
5085
+ const unit = match[2];
5086
+ const value = parseFloat(valueStr);
5087
+ const multiplier = SIZE_MULTIPLIERS[unit.toUpperCase()];
5088
+ if (multiplier === void 0) {
5089
+ throw new Error(`Unknown size unit: ${unit}`);
5090
+ }
5091
+ return Math.round(value * multiplier);
5092
+ }
5093
+ function formatBytes2(bytes) {
5094
+ if (bytes < 1024) return `${bytes} B`;
5095
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
5096
+ if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
5097
+ return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;
5098
+ }
5099
+ function formatDuration(ms) {
5100
+ if (ms < 1e3) return `${ms}ms`;
5101
+ if (ms < 6e4) return `${(ms / 1e3).toFixed(1)}s`;
5102
+ if (ms < 36e5) return `${(ms / 6e4).toFixed(1)}m`;
5103
+ return `${(ms / 36e5).toFixed(1)}h`;
5104
+ }
5105
+ function formatSeconds(seconds) {
5106
+ if (seconds < 60) return `${seconds}s`;
5107
+ if (seconds < 3600) return `${(seconds / 60).toFixed(1)}m`;
5108
+ if (seconds < 86400) return `${(seconds / 3600).toFixed(1)}h`;
5109
+ return `${(seconds / 86400).toFixed(1)}d`;
5110
+ }
5111
+ function isValidDuration(value) {
5112
+ return /^\d+(?:\.\d+)?\s*[smhdwMy]$/.test(value);
5113
+ }
5114
+ function isValidSize(value) {
5115
+ return /^\d+(?:\.\d+)?\s*(B|KB|MB|GB|TB)$/i.test(value);
5116
+ }
5117
+
5118
+ export { AutoSyncPatternSchema, BUILT_IN_TYPES, CODEX_URI_PREFIX, CacheManager, CachePersistence, CodexConfigSchema, CodexError, CommonRules, ConfigurationError, CustomTypeSchema, DEFAULT_CACHE_DIR, DEFAULT_FETCH_OPTIONS, DEFAULT_MIGRATION_OPTIONS, DEFAULT_PERMISSION_CONFIG, DEFAULT_SYNC_CONFIG, DEFAULT_TYPE, FilePluginFileNotFoundError, FilePluginStorage, GitHubStorage, HttpStorage, LEGACY_PATTERNS, LEGACY_REF_PREFIX, LocalStorage, MetadataSchema, PERMISSION_LEVEL_ORDER, PermissionDeniedError, PermissionManager, StorageManager, SyncManager, SyncRulesSchema, TTL, TypeRegistry, TypesConfigSchema, ValidationError, buildUri, calculateCachePath, calculateContentHash, convertLegacyReference, convertLegacyReferences, convertToUri, createCacheEntry, createCacheManager, createCachePersistence, createDefaultRegistry, createEmptyModernConfig, createEmptySyncPlan, createGitHubStorage, createHttpStorage, createLocalStorage, createPermissionManager, createRule, createRulesFromPatterns, createStorageManager, createSyncManager, createSyncPlan, deserializeCacheEntry, detectContentType, detectCurrentProject, detectVersion, estimateSyncTime, evaluatePath, evaluatePaths, evaluatePatterns, evaluatePermission, evaluatePermissions, expandEnvVars, expandEnvVarsInConfig, extendType, extractEnvVarNames, extractOrgFromRepoName, extractRawFrontmatter, filterByPatterns, filterByPermission, filterPlanOperations, filterSyncablePaths, findLegacyReferences, formatBytes2 as formatBytes, formatDuration, formatPlanSummary, formatSeconds, generateMigrationReport, generateReferenceMigrationSummary, getBuiltInType, getBuiltInTypeNames, getCacheEntryAge, getCacheEntryStatus, getCurrentContext, getCustomSyncDestinations, getDefaultCacheManager, getDefaultConfig, getDefaultDirectories, getDefaultPermissionManager, getDefaultRules, getDefaultStorageManager, getDirectory, getExtension, getFilename, getMigrationRequirements, getPlanStats, getRelativeCachePath, getRemainingTtl, getTargetRepos, hasContentChanged, hasEnvVars, hasFrontmatter, hasLegacyReferences, hasPermission as hasPermissionLevel, isBuiltInType, isCacheEntryFresh, isCacheEntryValid, isCurrentProjectUri, isLegacyConfig, isLegacyReference, isModernConfig, isAllowed as isPermissionAllowed, isUnifiedConfig, isValidDuration, isValidSize, isValidUri, levelGrants, loadConfig, loadCustomTypes, matchAnyPattern, matchPattern, maxLevel, mergeFetchOptions, mergeRules, mergeTypes, migrateConfig, migrateFileReferences, minLevel, needsMigration, parseCustomDestination, parseDuration, parseMetadata, parseReference, parseSize, parseTtl, readCodexConfig, readUnifiedConfig, resolveOrganization, resolveReference, resolveReferences, ruleMatchesAction, ruleMatchesContext, ruleMatchesPath, sanitizePath, serializeCacheEntry, setDefaultCacheManager, setDefaultPermissionManager, setDefaultStorageManager, shouldSyncToRepo, summarizeEvaluations, touchCacheEntry, validateCustomTypes, validateMetadata, validateMigratedConfig, validateOrg, validatePath, validateRules2 as validatePermissionRules, validateProject, validateRules, validateUri };
4910
5119
  //# sourceMappingURL=index.js.map
4911
5120
  //# sourceMappingURL=index.js.map