@fractary/codex 0.5.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -2864,16 +2864,24 @@ async function scanCodexWithRouting(options) {
2864
2864
  continue;
2865
2865
  }
2866
2866
  const content = await storage.readText(fullPath);
2867
- const parseResult = parseMetadata(content, { strict: false });
2868
- if (!matchFromCodexPattern2 && skipNoFrontmatter && Object.keys(parseResult.metadata).length === 0) {
2869
- totalSkipped++;
2870
- continue;
2871
- }
2872
2867
  const sourceProject = extractProjectFromPath(filePath, org);
2873
2868
  let shouldSync = false;
2869
+ let parseResult = null;
2870
+ const useFrontmatter = options.routing?.use_frontmatter === true;
2874
2871
  if (matchFromCodexPattern2 && expandedFromCodexPatterns && expandedFromCodexPatterns.length > 0) {
2875
2872
  shouldSync = matchFromCodexPattern2(filePath, expandedFromCodexPatterns, targetProject);
2876
- } else {
2873
+ parseResult = parseMetadata(content, { strict: false });
2874
+ } else if (useFrontmatter) {
2875
+ parseResult = parseMetadata(content, { strict: false });
2876
+ if (parseResult.metadata.codex_sync_include) {
2877
+ console.warn(
2878
+ `[DEPRECATION] File ${filePath} uses codex_sync_include frontmatter. This feature will be removed in v1.0. Use config.yaml patterns instead.`
2879
+ );
2880
+ }
2881
+ if (skipNoFrontmatter && Object.keys(parseResult.metadata).length === 0) {
2882
+ totalSkipped++;
2883
+ continue;
2884
+ }
2877
2885
  shouldSync = shouldSyncToRepo({
2878
2886
  filePath,
2879
2887
  fileMetadata: parseResult.metadata,
@@ -2881,6 +2889,9 @@ async function scanCodexWithRouting(options) {
2881
2889
  sourceRepo: sourceProject,
2882
2890
  rules
2883
2891
  });
2892
+ } else {
2893
+ totalSkipped++;
2894
+ continue;
2884
2895
  }
2885
2896
  if (shouldSync) {
2886
2897
  const buffer = Buffer.from(content);
@@ -2890,7 +2901,7 @@ async function scanCodexWithRouting(options) {
2890
2901
  size: buffer.length,
2891
2902
  mtime: stats.mtimeMs,
2892
2903
  hash,
2893
- metadata: parseResult.metadata,
2904
+ metadata: parseResult?.metadata ?? {},
2894
2905
  sourceProject
2895
2906
  });
2896
2907
  sourceProjectsSet.add(sourceProject);
@@ -2973,6 +2984,30 @@ var SyncManager = class {
2973
2984
  };
2974
2985
  this.manifestPath = options.manifestPath ?? ".fractary/codex-sync-manifest.json";
2975
2986
  }
2987
+ /**
2988
+ * Resolve from_codex include patterns (v0.7.0+)
2989
+ *
2990
+ * Supports both new format (from_codex.include) and legacy format (default_from_codex).
2991
+ * New format takes precedence.
2992
+ */
2993
+ resolveFromCodexPatterns() {
2994
+ if (this.config.from_codex?.include) {
2995
+ return this.config.from_codex.include;
2996
+ }
2997
+ return this.config.default_from_codex || [];
2998
+ }
2999
+ /**
3000
+ * Resolve to_codex include patterns (v0.7.0+)
3001
+ *
3002
+ * Supports both new format (to_codex.include) and legacy format (default_to_codex).
3003
+ * New format takes precedence.
3004
+ */
3005
+ resolveToCodexPatterns() {
3006
+ if (this.config.to_codex?.include) {
3007
+ return this.config.to_codex.include;
3008
+ }
3009
+ return this.config.default_to_codex || [];
3010
+ }
2976
3011
  /**
2977
3012
  * Load the sync manifest
2978
3013
  */
@@ -3042,8 +3077,8 @@ var SyncManager = class {
3042
3077
  async createPlan(_org, _project, sourceDir, targetFiles, options) {
3043
3078
  let sourceFiles = await this.listLocalFiles(sourceDir);
3044
3079
  if (options?.direction === "to-codex") {
3045
- const toCodexPatterns = this.config.to_codex || this.config.default_to_codex;
3046
- if (toCodexPatterns) {
3080
+ const toCodexPatterns = this.resolveToCodexPatterns();
3081
+ if (toCodexPatterns.length > 0) {
3047
3082
  const { matchToCodexPattern: matchToCodexPattern2 } = await Promise.resolve().then(() => (init_directional_patterns(), directional_patterns_exports));
3048
3083
  sourceFiles = sourceFiles.filter(
3049
3084
  (file) => matchToCodexPattern2(file.path, toCodexPatterns)
@@ -3087,7 +3122,7 @@ var SyncManager = class {
3087
3122
  * ```
3088
3123
  */
3089
3124
  async createRoutingAwarePlan(org, project, codexDir, options) {
3090
- const fromCodexPatterns = this.config.from_codex || this.config.default_from_codex;
3125
+ const fromCodexPatterns = this.resolveFromCodexPatterns();
3091
3126
  const routingScan = await scanCodexWithRouting({
3092
3127
  codexDir,
3093
3128
  targetProject: project,
@@ -3095,8 +3130,9 @@ var SyncManager = class {
3095
3130
  rules: void 0,
3096
3131
  // Use default routing rules (preventSelfSync, preventCodexSync, etc.)
3097
3132
  storage: this.localStorage,
3098
- fromCodexPatterns
3099
- // Use directional patterns if configured
3133
+ fromCodexPatterns: fromCodexPatterns.length > 0 ? fromCodexPatterns : void 0,
3134
+ routing: this.config.routing
3135
+ // Pass routing config for frontmatter control
3100
3136
  });
3101
3137
  const sourceFiles = routingScan.files.map((rf) => ({
3102
3138
  path: rf.path,
@@ -3115,16 +3151,19 @@ var SyncManager = class {
3115
3151
  };
3116
3152
  const plan = createSyncPlan(sourceFiles, targetFiles, planOptions, this.config);
3117
3153
  plan.estimatedTime = estimateSyncTime(plan);
3154
+ plan.source = codexDir;
3155
+ plan.target = ".fractary/codex/cache";
3118
3156
  return {
3119
3157
  ...plan,
3120
3158
  routingScan
3121
3159
  };
3122
3160
  }
3123
3161
  /**
3124
- * Execute a sync plan (dry run)
3162
+ * Execute a sync plan
3125
3163
  *
3126
- * In a real implementation, this would actually copy files.
3127
- * For the SDK, we provide the plan and let consumers execute.
3164
+ * Copies files from source to target based on the plan.
3165
+ * For from-codex syncs, files are copied to .fractary/codex/cache/ preserving full paths.
3166
+ * For to-codex syncs, files are copied to the codex repository.
3128
3167
  */
3129
3168
  async executePlan(plan, options) {
3130
3169
  const startTime = Date.now();
@@ -3150,7 +3189,30 @@ var SyncManager = class {
3150
3189
  if (options?.onProgress) {
3151
3190
  options.onProgress(i + 1, plan.totalFiles, file.path);
3152
3191
  }
3153
- synced++;
3192
+ if (file.operation === "create" || file.operation === "update") {
3193
+ const sourcePath = `${plan.source}/${file.path}`;
3194
+ const targetPath = `${plan.target}/${file.path}`;
3195
+ const fs4 = await import('fs/promises');
3196
+ const path6 = await import('path');
3197
+ const targetDir = path6.dirname(targetPath);
3198
+ await fs4.mkdir(targetDir, { recursive: true });
3199
+ await fs4.copyFile(sourcePath, targetPath);
3200
+ synced++;
3201
+ } else if (file.operation === "delete") {
3202
+ const targetPath = `${plan.target}/${file.path}`;
3203
+ const fs4 = await import('fs/promises');
3204
+ try {
3205
+ await fs4.unlink(targetPath);
3206
+ synced++;
3207
+ } catch (error) {
3208
+ if (error.code !== "ENOENT") {
3209
+ throw error;
3210
+ }
3211
+ synced++;
3212
+ }
3213
+ } else {
3214
+ synced++;
3215
+ }
3154
3216
  } catch (error) {
3155
3217
  failed++;
3156
3218
  errors.push({