@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.cjs CHANGED
@@ -4,7 +4,7 @@ var micromatch3 = require('micromatch');
4
4
  var path3 = require('path');
5
5
  var child_process = require('child_process');
6
6
  var zod = require('zod');
7
- var yaml = require('js-yaml');
7
+ var yaml2 = require('js-yaml');
8
8
  var fs3 = require('fs/promises');
9
9
  var util = require('util');
10
10
 
@@ -30,7 +30,7 @@ function _interopNamespace(e) {
30
30
 
31
31
  var micromatch3__default = /*#__PURE__*/_interopDefault(micromatch3);
32
32
  var path3__namespace = /*#__PURE__*/_interopNamespace(path3);
33
- var yaml__default = /*#__PURE__*/_interopDefault(yaml);
33
+ var yaml2__namespace = /*#__PURE__*/_interopNamespace(yaml2);
34
34
  var fs3__namespace = /*#__PURE__*/_interopNamespace(fs3);
35
35
 
36
36
  var __defProp = Object.defineProperty;
@@ -88,11 +88,14 @@ function matchToCodexPattern(filePath, patterns) {
88
88
  }
89
89
  return patterns.some((pattern) => matchPattern(pattern, filePath));
90
90
  }
91
- function matchFromCodexPattern(codexFilePath, patterns, targetProject) {
91
+ function matchFromCodexPattern(codexFilePath, patterns, targetProject, options) {
92
92
  if (!patterns || patterns.length === 0) {
93
93
  return false;
94
94
  }
95
95
  return patterns.some((pattern) => {
96
+ if (pattern.startsWith(CODEX_URI_PREFIX2)) {
97
+ return matchCodexUri(pattern, codexFilePath, targetProject, options);
98
+ }
96
99
  if (pattern.startsWith("projects/")) {
97
100
  return matchPattern(pattern, codexFilePath);
98
101
  }
@@ -110,6 +113,21 @@ function matchFromCodexPattern(codexFilePath, patterns, targetProject) {
110
113
  }
111
114
  });
112
115
  }
116
+ function matchCodexUri(uriPattern, codexFilePath, targetProject, options) {
117
+ let withoutPrefix = uriPattern.slice(CODEX_URI_PREFIX2.length);
118
+ withoutPrefix = withoutPrefix.replace(/{org}/g, options?.org || "").replace(/{project}/g, targetProject).replace(/{codex_repo}/g, options?.codexRepo || "");
119
+ const parts = withoutPrefix.split("/");
120
+ if (parts.length < 2) {
121
+ return false;
122
+ }
123
+ const project = parts[1];
124
+ const pathPattern = parts.slice(2).join("/");
125
+ if (!project) {
126
+ return false;
127
+ }
128
+ const fullPattern = pathPattern ? `projects/${project}/${pathPattern}` : `projects/${project}/**`;
129
+ return matchPattern(fullPattern, codexFilePath);
130
+ }
113
131
  function extractProjectFromCodexPath(codexFilePath) {
114
132
  const firstSlashIndex = codexFilePath.indexOf("/");
115
133
  if (firstSlashIndex === -1) {
@@ -124,15 +142,26 @@ function getRelativePath(codexFilePath) {
124
142
  }
125
143
  return codexFilePath.substring(firstSlashIndex + 1);
126
144
  }
127
- function expandPlaceholders(patterns, targetProject) {
145
+ function expandPlaceholders(patterns, targetProject, options) {
128
146
  if (!patterns) {
129
147
  return patterns;
130
148
  }
131
- return patterns.map((pattern) => pattern.replace(/{project}/g, targetProject));
149
+ return patterns.map((pattern) => {
150
+ let expanded = pattern.replace(/{project}/g, targetProject);
151
+ if (options?.org) {
152
+ expanded = expanded.replace(/{org}/g, options.org);
153
+ }
154
+ if (options?.codexRepo) {
155
+ expanded = expanded.replace(/{codex_repo}/g, options.codexRepo);
156
+ }
157
+ return expanded;
158
+ });
132
159
  }
160
+ var CODEX_URI_PREFIX2;
133
161
  var init_directional_patterns = __esm({
134
162
  "src/sync/directional-patterns.ts"() {
135
163
  init_matcher();
164
+ CODEX_URI_PREFIX2 = "codex://";
136
165
  }
137
166
  });
138
167
 
@@ -1017,7 +1046,7 @@ function parseMetadata(content, options = {}) {
1017
1046
  const rawFrontmatter = frontmatterMatch[1];
1018
1047
  const documentContent = frontmatterMatch[2];
1019
1048
  try {
1020
- const parsed = yaml__default.default.load(rawFrontmatter);
1049
+ const parsed = yaml2__namespace.default.load(rawFrontmatter);
1021
1050
  const normalized = normalizeLegacyMetadata(parsed);
1022
1051
  const metadata = strict ? MetadataSchema.parse(normalized) : MetadataSchema.safeParse(normalized).data || {};
1023
1052
  return {
@@ -3530,6 +3559,7 @@ async function scanCodexWithRouting(options) {
3530
3559
  codexDir,
3531
3560
  targetProject,
3532
3561
  org,
3562
+ codexRepo,
3533
3563
  rules,
3534
3564
  storage,
3535
3565
  skipNoFrontmatter = false,
@@ -3548,7 +3578,10 @@ async function scanCodexWithRouting(options) {
3548
3578
  if (fromCodexPatterns && fromCodexPatterns.length > 0) {
3549
3579
  const module = await Promise.resolve().then(() => (init_directional_patterns(), directional_patterns_exports));
3550
3580
  matchFromCodexPattern2 = module.matchFromCodexPattern;
3551
- expandedFromCodexPatterns = module.expandPlaceholders(fromCodexPatterns, targetProject);
3581
+ expandedFromCodexPatterns = module.expandPlaceholders(fromCodexPatterns, targetProject, {
3582
+ org,
3583
+ codexRepo
3584
+ });
3552
3585
  }
3553
3586
  const allFiles = await listAllFilesRecursive(codexDir);
3554
3587
  for (const filePath of allFiles) {
@@ -3570,7 +3603,10 @@ async function scanCodexWithRouting(options) {
3570
3603
  let parseResult = null;
3571
3604
  const useFrontmatter = options.routing?.use_frontmatter === true;
3572
3605
  if (matchFromCodexPattern2 && expandedFromCodexPatterns && expandedFromCodexPatterns.length > 0) {
3573
- shouldSync = matchFromCodexPattern2(filePath, expandedFromCodexPatterns, targetProject);
3606
+ shouldSync = matchFromCodexPattern2(filePath, expandedFromCodexPatterns, targetProject, {
3607
+ org,
3608
+ codexRepo
3609
+ });
3574
3610
  parseResult = parseMetadata(content, { strict: false });
3575
3611
  } else if (useFrontmatter) {
3576
3612
  parseResult = parseMetadata(content, { strict: false });
@@ -3851,6 +3887,8 @@ var SyncManager = class {
3851
3887
  codexDir,
3852
3888
  targetProject: project,
3853
3889
  org,
3890
+ codexRepo: options?.codexRepo,
3891
+ // For codex:// URI {codex_repo} placeholder
3854
3892
  rules: void 0,
3855
3893
  // Use default routing rules (preventSelfSync, preventCodexSync, etc.)
3856
3894
  storage: this.localStorage,
@@ -3916,17 +3954,17 @@ var SyncManager = class {
3916
3954
  if (file.operation === "create" || file.operation === "update") {
3917
3955
  const sourcePath = `${plan.source}/${file.path}`;
3918
3956
  const targetPath = `${plan.target}/${file.path}`;
3919
- const fs5 = await import('fs/promises');
3957
+ const fs6 = await import('fs/promises');
3920
3958
  const path7 = await import('path');
3921
3959
  const targetDir = path7.dirname(targetPath);
3922
- await fs5.mkdir(targetDir, { recursive: true });
3923
- await fs5.copyFile(sourcePath, targetPath);
3960
+ await fs6.mkdir(targetDir, { recursive: true });
3961
+ await fs6.copyFile(sourcePath, targetPath);
3924
3962
  synced++;
3925
3963
  } else if (file.operation === "delete") {
3926
3964
  const targetPath = `${plan.target}/${file.path}`;
3927
- const fs5 = await import('fs/promises');
3965
+ const fs6 = await import('fs/promises');
3928
3966
  try {
3929
- await fs5.unlink(targetPath);
3967
+ await fs6.unlink(targetPath);
3930
3968
  synced++;
3931
3969
  } catch (error) {
3932
3970
  if (error.code !== "ENOENT") {
@@ -4931,6 +4969,176 @@ function generateReferenceMigrationSummary(results) {
4931
4969
  return lines.join("\n");
4932
4970
  }
4933
4971
 
4972
+ // src/core/env/index.ts
4973
+ function expandEnvVars(value, options = {}) {
4974
+ const env = options.env ?? process.env;
4975
+ return value.replace(/\$\{([^}]+)\}/g, (match, varName) => {
4976
+ const envValue = env[varName];
4977
+ if (envValue === void 0) {
4978
+ if (options.warnOnMissing) {
4979
+ console.warn(`Warning: Environment variable ${varName} is not set`);
4980
+ }
4981
+ if (options.onMissing) {
4982
+ options.onMissing(varName);
4983
+ }
4984
+ return match;
4985
+ }
4986
+ return envValue;
4987
+ });
4988
+ }
4989
+ function expandEnvVarsInConfig(config, options = {}) {
4990
+ if (typeof config === "string") {
4991
+ return expandEnvVars(config, options);
4992
+ }
4993
+ if (Array.isArray(config)) {
4994
+ return config.map((item) => expandEnvVarsInConfig(item, options));
4995
+ }
4996
+ if (config !== null && typeof config === "object") {
4997
+ const result = {};
4998
+ for (const [key, value] of Object.entries(config)) {
4999
+ result[key] = expandEnvVarsInConfig(value, options);
5000
+ }
5001
+ return result;
5002
+ }
5003
+ return config;
5004
+ }
5005
+ function hasEnvVars(value) {
5006
+ return /\$\{[^}]+\}/.test(value);
5007
+ }
5008
+ function extractEnvVarNames(value) {
5009
+ const matches = value.matchAll(/\$\{([^}]+)\}/g);
5010
+ const names = [];
5011
+ for (const match of matches) {
5012
+ if (match[1]) {
5013
+ names.push(match[1]);
5014
+ }
5015
+ }
5016
+ return names;
5017
+ }
5018
+ async function readCodexConfig(configPath, options = {}) {
5019
+ const content = await fs3__namespace.readFile(configPath, "utf-8");
5020
+ const rawConfig = yaml2__namespace.load(content);
5021
+ let config;
5022
+ if (rawConfig?.codex && typeof rawConfig.codex === "object") {
5023
+ config = rawConfig.codex;
5024
+ } else {
5025
+ config = rawConfig;
5026
+ }
5027
+ if (!config.organization) {
5028
+ throw new Error("Invalid config: organization is required");
5029
+ }
5030
+ if (options.expandEnv !== false) {
5031
+ const envOptions = {
5032
+ env: options.env,
5033
+ warnOnMissing: options.warnOnMissingEnv
5034
+ };
5035
+ config = expandEnvVarsInConfig(config, envOptions);
5036
+ }
5037
+ return config;
5038
+ }
5039
+ async function readUnifiedConfig(configPath, options = {}) {
5040
+ const content = await fs3__namespace.readFile(configPath, "utf-8");
5041
+ let config = yaml2__namespace.load(content);
5042
+ if (options.expandEnv !== false) {
5043
+ const envOptions = {
5044
+ env: options.env,
5045
+ warnOnMissing: options.warnOnMissingEnv
5046
+ };
5047
+ config = expandEnvVarsInConfig(config, envOptions);
5048
+ }
5049
+ return config;
5050
+ }
5051
+ function isUnifiedConfig(config) {
5052
+ if (config === null || typeof config !== "object") {
5053
+ return false;
5054
+ }
5055
+ const maybeUnified = config;
5056
+ return "codex" in maybeUnified && maybeUnified.codex !== null && typeof maybeUnified.codex === "object";
5057
+ }
5058
+
5059
+ // src/core/utils/index.ts
5060
+ var DURATION_MULTIPLIERS = {
5061
+ s: 1,
5062
+ // seconds
5063
+ m: 60,
5064
+ // minutes
5065
+ h: 3600,
5066
+ // hours
5067
+ d: 86400,
5068
+ // days
5069
+ w: 604800,
5070
+ // weeks (7 days)
5071
+ M: 2592e3,
5072
+ // months (30 days)
5073
+ y: 31536e3
5074
+ // years (365 days)
5075
+ };
5076
+ var SIZE_MULTIPLIERS = {
5077
+ B: 1,
5078
+ KB: 1024,
5079
+ MB: 1024 * 1024,
5080
+ GB: 1024 * 1024 * 1024,
5081
+ TB: 1024 * 1024 * 1024 * 1024
5082
+ };
5083
+ function parseDuration(duration) {
5084
+ if (typeof duration === "number") {
5085
+ return duration;
5086
+ }
5087
+ const match = duration.match(/^(\d+(?:\.\d+)?)\s*([smhdwMy])$/);
5088
+ if (!match || !match[1] || !match[2]) {
5089
+ throw new Error(`Invalid duration format: ${duration}. Use format like "1h", "7d", "1M"`);
5090
+ }
5091
+ const valueStr = match[1];
5092
+ const unit = match[2];
5093
+ const value = parseFloat(valueStr);
5094
+ const multiplier = DURATION_MULTIPLIERS[unit];
5095
+ if (multiplier === void 0) {
5096
+ throw new Error(`Unknown duration unit: ${unit}`);
5097
+ }
5098
+ return Math.round(value * multiplier);
5099
+ }
5100
+ function parseSize(size) {
5101
+ if (typeof size === "number") {
5102
+ return size;
5103
+ }
5104
+ const match = size.match(/^(\d+(?:\.\d+)?)\s*(B|KB|MB|GB|TB)$/i);
5105
+ if (!match || !match[1] || !match[2]) {
5106
+ throw new Error(`Invalid size format: ${size}. Use format like "100MB", "1GB"`);
5107
+ }
5108
+ const valueStr = match[1];
5109
+ const unit = match[2];
5110
+ const value = parseFloat(valueStr);
5111
+ const multiplier = SIZE_MULTIPLIERS[unit.toUpperCase()];
5112
+ if (multiplier === void 0) {
5113
+ throw new Error(`Unknown size unit: ${unit}`);
5114
+ }
5115
+ return Math.round(value * multiplier);
5116
+ }
5117
+ function formatBytes2(bytes) {
5118
+ if (bytes < 1024) return `${bytes} B`;
5119
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
5120
+ if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
5121
+ return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;
5122
+ }
5123
+ function formatDuration(ms) {
5124
+ if (ms < 1e3) return `${ms}ms`;
5125
+ if (ms < 6e4) return `${(ms / 1e3).toFixed(1)}s`;
5126
+ if (ms < 36e5) return `${(ms / 6e4).toFixed(1)}m`;
5127
+ return `${(ms / 36e5).toFixed(1)}h`;
5128
+ }
5129
+ function formatSeconds(seconds) {
5130
+ if (seconds < 60) return `${seconds}s`;
5131
+ if (seconds < 3600) return `${(seconds / 60).toFixed(1)}m`;
5132
+ if (seconds < 86400) return `${(seconds / 3600).toFixed(1)}h`;
5133
+ return `${(seconds / 86400).toFixed(1)}d`;
5134
+ }
5135
+ function isValidDuration(value) {
5136
+ return /^\d+(?:\.\d+)?\s*[smhdwMy]$/.test(value);
5137
+ }
5138
+ function isValidSize(value) {
5139
+ return /^\d+(?:\.\d+)?\s*(B|KB|MB|GB|TB)$/i.test(value);
5140
+ }
5141
+
4934
5142
  exports.AutoSyncPatternSchema = AutoSyncPatternSchema;
4935
5143
  exports.BUILT_IN_TYPES = BUILT_IN_TYPES;
4936
5144
  exports.CODEX_URI_PREFIX = CODEX_URI_PREFIX;
@@ -4996,7 +5204,10 @@ exports.evaluatePaths = evaluatePaths;
4996
5204
  exports.evaluatePatterns = evaluatePatterns;
4997
5205
  exports.evaluatePermission = evaluatePermission;
4998
5206
  exports.evaluatePermissions = evaluatePermissions;
5207
+ exports.expandEnvVars = expandEnvVars;
5208
+ exports.expandEnvVarsInConfig = expandEnvVarsInConfig;
4999
5209
  exports.extendType = extendType;
5210
+ exports.extractEnvVarNames = extractEnvVarNames;
5000
5211
  exports.extractOrgFromRepoName = extractOrgFromRepoName;
5001
5212
  exports.extractRawFrontmatter = extractRawFrontmatter;
5002
5213
  exports.filterByPatterns = filterByPatterns;
@@ -5004,7 +5215,10 @@ exports.filterByPermission = filterByPermission;
5004
5215
  exports.filterPlanOperations = filterPlanOperations;
5005
5216
  exports.filterSyncablePaths = filterSyncablePaths;
5006
5217
  exports.findLegacyReferences = findLegacyReferences;
5218
+ exports.formatBytes = formatBytes2;
5219
+ exports.formatDuration = formatDuration;
5007
5220
  exports.formatPlanSummary = formatPlanSummary;
5221
+ exports.formatSeconds = formatSeconds;
5008
5222
  exports.generateMigrationReport = generateMigrationReport;
5009
5223
  exports.generateReferenceMigrationSummary = generateReferenceMigrationSummary;
5010
5224
  exports.getBuiltInType = getBuiltInType;
@@ -5028,6 +5242,7 @@ exports.getRelativeCachePath = getRelativeCachePath;
5028
5242
  exports.getRemainingTtl = getRemainingTtl;
5029
5243
  exports.getTargetRepos = getTargetRepos;
5030
5244
  exports.hasContentChanged = hasContentChanged;
5245
+ exports.hasEnvVars = hasEnvVars;
5031
5246
  exports.hasFrontmatter = hasFrontmatter;
5032
5247
  exports.hasLegacyReferences = hasLegacyReferences;
5033
5248
  exports.hasPermissionLevel = hasPermission;
@@ -5039,6 +5254,9 @@ exports.isLegacyConfig = isLegacyConfig;
5039
5254
  exports.isLegacyReference = isLegacyReference;
5040
5255
  exports.isModernConfig = isModernConfig;
5041
5256
  exports.isPermissionAllowed = isAllowed;
5257
+ exports.isUnifiedConfig = isUnifiedConfig;
5258
+ exports.isValidDuration = isValidDuration;
5259
+ exports.isValidSize = isValidSize;
5042
5260
  exports.isValidUri = isValidUri;
5043
5261
  exports.levelGrants = levelGrants;
5044
5262
  exports.loadConfig = loadConfig;
@@ -5054,9 +5272,13 @@ exports.migrateFileReferences = migrateFileReferences;
5054
5272
  exports.minLevel = minLevel;
5055
5273
  exports.needsMigration = needsMigration;
5056
5274
  exports.parseCustomDestination = parseCustomDestination;
5275
+ exports.parseDuration = parseDuration;
5057
5276
  exports.parseMetadata = parseMetadata;
5058
5277
  exports.parseReference = parseReference;
5278
+ exports.parseSize = parseSize;
5059
5279
  exports.parseTtl = parseTtl;
5280
+ exports.readCodexConfig = readCodexConfig;
5281
+ exports.readUnifiedConfig = readUnifiedConfig;
5060
5282
  exports.resolveOrganization = resolveOrganization;
5061
5283
  exports.resolveReference = resolveReference;
5062
5284
  exports.resolveReferences = resolveReferences;