@aspruyt/xfg 3.13.1 → 4.0.1

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.
Files changed (190) hide show
  1. package/README.md +1 -4
  2. package/dist/cli/index.d.ts +1 -4
  3. package/dist/cli/index.js +0 -2
  4. package/dist/cli/program.js +7 -14
  5. package/dist/cli/{settings/results-collector.d.ts → results-collector.d.ts} +1 -1
  6. package/dist/cli/{settings/results-collector.js → results-collector.js} +2 -1
  7. package/dist/cli/settings-report-builder.d.ts +1 -3
  8. package/dist/cli/sync-command.d.ts +3 -26
  9. package/dist/cli/sync-command.js +312 -179
  10. package/dist/cli/types.d.ts +68 -41
  11. package/dist/cli/types.js +1 -12
  12. package/dist/config/errors.d.ts +9 -0
  13. package/dist/config/errors.js +11 -0
  14. package/dist/config/file-reference-resolver.d.ts +2 -1
  15. package/dist/config/file-reference-resolver.js +10 -8
  16. package/dist/config/formatter.d.ts +3 -2
  17. package/dist/config/index.d.ts +4 -6
  18. package/dist/config/index.js +4 -8
  19. package/dist/config/loader.js +4 -2
  20. package/dist/config/merge.d.ts +0 -9
  21. package/dist/config/merge.js +2 -7
  22. package/dist/config/normalizer.d.ts +4 -0
  23. package/dist/config/normalizer.js +61 -110
  24. package/dist/config/types.d.ts +15 -19
  25. package/dist/config/types.js +1 -1
  26. package/dist/config/validator.d.ts +0 -9
  27. package/dist/config/validator.js +297 -391
  28. package/dist/config/validators/file-validator.d.ts +2 -8
  29. package/dist/config/validators/file-validator.js +6 -17
  30. package/dist/config/validators/index.d.ts +3 -3
  31. package/dist/config/validators/index.js +3 -3
  32. package/dist/config/validators/repo-settings-validator.d.ts +0 -6
  33. package/dist/config/validators/repo-settings-validator.js +9 -9
  34. package/dist/config/validators/ruleset-validator.d.ts +0 -14
  35. package/dist/config/validators/ruleset-validator.js +28 -28
  36. package/dist/index.d.ts +2 -2
  37. package/dist/index.js +1 -1
  38. package/dist/lifecycle/ado-migration-source.js +2 -1
  39. package/dist/lifecycle/github-lifecycle-provider.d.ts +15 -5
  40. package/dist/lifecycle/github-lifecycle-provider.js +101 -81
  41. package/dist/lifecycle/index.d.ts +2 -6
  42. package/dist/lifecycle/index.js +0 -4
  43. package/dist/lifecycle/lifecycle-formatter.d.ts +2 -1
  44. package/dist/lifecycle/lifecycle-formatter.js +4 -0
  45. package/dist/lifecycle/lifecycle-helpers.d.ts +3 -2
  46. package/dist/lifecycle/repo-lifecycle-manager.js +4 -11
  47. package/dist/lifecycle/types.d.ts +0 -8
  48. package/dist/output/github-summary.d.ts +5 -0
  49. package/dist/output/github-summary.js +9 -2
  50. package/dist/output/index.d.ts +2 -2
  51. package/dist/output/index.js +1 -1
  52. package/dist/output/lifecycle-report.js +5 -23
  53. package/dist/output/settings-report.d.ts +14 -3
  54. package/dist/output/settings-report.js +137 -197
  55. package/dist/output/summary-utils.d.ts +1 -1
  56. package/dist/output/summary-utils.js +2 -1
  57. package/dist/output/sync-report.js +5 -8
  58. package/dist/output/unified-summary.d.ts +2 -1
  59. package/dist/output/unified-summary.js +71 -133
  60. package/dist/settings/base-processor.d.ts +67 -0
  61. package/dist/settings/base-processor.js +91 -0
  62. package/dist/settings/index.d.ts +4 -3
  63. package/dist/settings/index.js +3 -3
  64. package/dist/settings/labels/converter.d.ts +2 -1
  65. package/dist/settings/labels/diff.d.ts +2 -2
  66. package/dist/settings/labels/diff.js +15 -19
  67. package/dist/settings/labels/github-labels-strategy.d.ts +9 -18
  68. package/dist/settings/labels/github-labels-strategy.js +17 -73
  69. package/dist/settings/labels/index.d.ts +2 -6
  70. package/dist/settings/labels/index.js +1 -9
  71. package/dist/settings/labels/processor.d.ts +6 -40
  72. package/dist/settings/labels/processor.js +62 -165
  73. package/dist/settings/labels/types.d.ts +5 -8
  74. package/dist/settings/repo-settings/formatter.d.ts +2 -2
  75. package/dist/settings/repo-settings/formatter.js +6 -6
  76. package/dist/settings/repo-settings/github-repo-settings-strategy.d.ts +11 -12
  77. package/dist/settings/repo-settings/github-repo-settings-strategy.js +32 -79
  78. package/dist/settings/repo-settings/index.d.ts +2 -5
  79. package/dist/settings/repo-settings/index.js +1 -9
  80. package/dist/settings/repo-settings/processor.d.ts +6 -27
  81. package/dist/settings/repo-settings/processor.js +51 -104
  82. package/dist/settings/repo-settings/types.d.ts +7 -9
  83. package/dist/settings/rulesets/diff-algorithm.d.ts +0 -4
  84. package/dist/settings/rulesets/diff-algorithm.js +1 -10
  85. package/dist/settings/rulesets/diff.d.ts +3 -3
  86. package/dist/settings/rulesets/diff.js +8 -29
  87. package/dist/settings/rulesets/formatter.d.ts +1 -3
  88. package/dist/settings/rulesets/formatter.js +1 -8
  89. package/dist/settings/rulesets/github-ruleset-strategy.d.ts +11 -51
  90. package/dist/settings/rulesets/github-ruleset-strategy.js +24 -85
  91. package/dist/settings/rulesets/index.d.ts +3 -6
  92. package/dist/settings/rulesets/index.js +5 -9
  93. package/dist/settings/rulesets/processor.d.ts +8 -43
  94. package/dist/settings/rulesets/processor.js +58 -166
  95. package/dist/settings/rulesets/types.d.ts +35 -6
  96. package/dist/shared/command-executor.d.ts +2 -22
  97. package/dist/shared/command-executor.js +8 -7
  98. package/dist/shared/env.d.ts +0 -8
  99. package/dist/shared/env.js +14 -70
  100. package/dist/shared/file-status.d.ts +2 -0
  101. package/dist/shared/file-status.js +13 -0
  102. package/dist/shared/gh-api-utils.d.ts +46 -0
  103. package/dist/shared/gh-api-utils.js +107 -0
  104. package/dist/shared/index.d.ts +5 -5
  105. package/dist/shared/index.js +3 -3
  106. package/dist/shared/interpolation-engine.d.ts +31 -0
  107. package/dist/shared/interpolation-engine.js +50 -0
  108. package/dist/shared/logger.d.ts +3 -7
  109. package/dist/shared/logger.js +4 -1
  110. package/dist/shared/repo-detector.d.ts +17 -2
  111. package/dist/shared/repo-detector.js +27 -0
  112. package/dist/shared/retry-utils.d.ts +9 -17
  113. package/dist/shared/retry-utils.js +22 -28
  114. package/dist/shared/sanitize-utils.d.ts +0 -7
  115. package/dist/shared/sanitize-utils.js +0 -7
  116. package/dist/shared/shell-utils.d.ts +1 -0
  117. package/dist/shared/shell-utils.js +3 -0
  118. package/dist/shared/string-utils.d.ts +4 -0
  119. package/dist/shared/string-utils.js +6 -0
  120. package/dist/shared/type-guards.d.ts +17 -0
  121. package/dist/shared/type-guards.js +26 -0
  122. package/dist/shared/workspace-utils.d.ts +0 -4
  123. package/dist/shared/workspace-utils.js +0 -4
  124. package/dist/{sync → shared}/xfg-template.d.ts +3 -2
  125. package/dist/{sync → shared}/xfg-template.js +13 -54
  126. package/dist/sync/auth-options-builder.d.ts +4 -5
  127. package/dist/sync/auth-options-builder.js +15 -26
  128. package/dist/sync/branch-manager.d.ts +5 -0
  129. package/dist/sync/branch-manager.js +12 -10
  130. package/dist/sync/commit-push-manager.d.ts +1 -1
  131. package/dist/sync/commit-push-manager.js +22 -18
  132. package/dist/sync/diff-utils.d.ts +4 -9
  133. package/dist/sync/diff-utils.js +2 -19
  134. package/dist/sync/file-sync-orchestrator.js +9 -8
  135. package/dist/sync/file-writer.d.ts +2 -1
  136. package/dist/sync/file-writer.js +3 -6
  137. package/dist/sync/index.d.ts +2 -16
  138. package/dist/sync/index.js +0 -20
  139. package/dist/sync/manifest-manager.d.ts +4 -0
  140. package/dist/sync/manifest-manager.js +5 -1
  141. package/dist/sync/manifest.d.ts +11 -84
  142. package/dist/sync/manifest.js +50 -215
  143. package/dist/sync/pr-merge-handler.d.ts +2 -6
  144. package/dist/sync/pr-merge-handler.js +6 -3
  145. package/dist/sync/repository-processor.d.ts +2 -8
  146. package/dist/sync/repository-processor.js +21 -63
  147. package/dist/sync/repository-session.js +5 -14
  148. package/dist/sync/sync-workflow.js +31 -38
  149. package/dist/sync/types.d.ts +43 -182
  150. package/dist/vcs/authenticated-git-ops.d.ts +27 -70
  151. package/dist/vcs/authenticated-git-ops.js +70 -96
  152. package/dist/vcs/azure-pr-strategy.d.ts +6 -4
  153. package/dist/vcs/azure-pr-strategy.js +34 -82
  154. package/dist/vcs/branch-utils.d.ts +6 -0
  155. package/dist/vcs/branch-utils.js +29 -0
  156. package/dist/vcs/commit-strategy-selector.d.ts +5 -0
  157. package/dist/vcs/commit-strategy-selector.js +10 -0
  158. package/dist/vcs/git-commit-strategy.js +1 -2
  159. package/dist/vcs/git-ops.d.ts +15 -59
  160. package/dist/vcs/git-ops.js +46 -110
  161. package/dist/vcs/github-app-token-manager.d.ts +0 -6
  162. package/dist/vcs/github-app-token-manager.js +5 -12
  163. package/dist/vcs/github-pr-strategy.d.ts +5 -5
  164. package/dist/vcs/github-pr-strategy.js +44 -122
  165. package/dist/vcs/gitlab-pr-strategy.d.ts +6 -4
  166. package/dist/vcs/gitlab-pr-strategy.js +39 -87
  167. package/dist/vcs/graphql-commit-strategy.d.ts +3 -4
  168. package/dist/vcs/graphql-commit-strategy.js +45 -63
  169. package/dist/vcs/index.d.ts +3 -16
  170. package/dist/vcs/index.js +2 -33
  171. package/dist/vcs/pr-creator.d.ts +9 -9
  172. package/dist/vcs/pr-creator.js +11 -10
  173. package/dist/vcs/pr-strategy-factory.d.ts +5 -0
  174. package/dist/vcs/pr-strategy-factory.js +17 -0
  175. package/dist/vcs/pr-strategy.d.ts +13 -26
  176. package/dist/vcs/pr-strategy.js +20 -25
  177. package/dist/vcs/types.d.ts +87 -21
  178. package/package.json +2 -1
  179. package/dist/cli/settings/lifecycle-checks.d.ts +0 -11
  180. package/dist/cli/settings/lifecycle-checks.js +0 -64
  181. package/dist/cli/settings/process-labels.d.ts +0 -9
  182. package/dist/cli/settings/process-labels.js +0 -125
  183. package/dist/cli/settings/process-repo-settings.d.ts +0 -9
  184. package/dist/cli/settings/process-repo-settings.js +0 -80
  185. package/dist/cli/settings/process-rulesets.d.ts +0 -9
  186. package/dist/cli/settings/process-rulesets.js +0 -118
  187. package/dist/cli/settings-command.d.ts +0 -11
  188. package/dist/cli/settings-command.js +0 -90
  189. package/dist/sync/manifest-strategy.d.ts +0 -21
  190. package/dist/sync/manifest-strategy.js +0 -67
@@ -1,27 +1,10 @@
1
1
  import chalk from "chalk";
2
- /**
3
- * Determines file status based on existence and change detection.
4
- */
2
+ export { formatStatusBadge } from "../shared/file-status.js";
5
3
  export function getFileStatus(exists, changed) {
6
4
  if (!exists)
7
5
  return "NEW";
8
6
  return changed ? "MODIFIED" : "UNCHANGED";
9
7
  }
10
- /**
11
- * Format a status badge with appropriate color.
12
- */
13
- export function formatStatusBadge(status) {
14
- switch (status) {
15
- case "NEW":
16
- return chalk.green("[NEW]");
17
- case "MODIFIED":
18
- return chalk.yellow("[MODIFIED]");
19
- case "UNCHANGED":
20
- return chalk.gray("[UNCHANGED]");
21
- case "DELETED":
22
- return chalk.red("[DELETED]");
23
- }
24
- }
25
8
  /**
26
9
  * Format a single diff line with appropriate color.
27
10
  */
@@ -38,7 +21,7 @@ export function formatDiffLine(line) {
38
21
  * Generate a unified diff between old and new content.
39
22
  * Returns an array of formatted diff lines.
40
23
  */
41
- export function generateDiff(oldContent, newContent, fileName, contextLines = 3) {
24
+ export function generateDiff(oldContent, newContent, _fileName, contextLines = 3) {
42
25
  const oldLines = oldContent ? oldContent.split("\n") : [];
43
26
  const newLines = newContent.split("\n");
44
27
  // For new files, show all lines as additions
@@ -10,21 +10,22 @@ export class FileSyncOrchestrator {
10
10
  this.log = log;
11
11
  }
12
12
  async sync(repoConfig, repoInfo, session, options) {
13
- const { workDir, dryRun, noDelete, configId } = options;
14
- // Write files
13
+ const { workDir, configId } = options;
14
+ const dryRun = options.dryRun ?? false;
15
+ const noDelete = options.noDelete ?? false;
15
16
  const { fileChanges, diffStats } = await this.fileWriter.writeFiles(repoConfig.files, {
16
17
  repoInfo,
17
18
  baseBranch: session.baseBranch,
18
19
  workDir,
19
- dryRun: dryRun ?? false,
20
- noDelete: noDelete ?? false,
20
+ dryRun,
21
+ noDelete,
21
22
  configId,
23
+ isGraphQLCommitMode: options.isGraphQLCommitMode,
22
24
  }, { gitOps: session.gitOps, log: this.log });
23
- // Handle orphans
24
- const existingManifest = loadManifest(workDir);
25
+ const existingManifest = loadManifest(workDir, this.log);
25
26
  const filesWithDeleteOrphaned = new Map(repoConfig.files.map((f) => [f.fileName, f.deleteOrphaned]));
26
27
  const { manifest: newManifest, filesToDelete } = this.manifestManager.processOrphans(workDir, configId, filesWithDeleteOrphaned);
27
- await this.manifestManager.deleteOrphans(filesToDelete, { dryRun: dryRun ?? false, noDelete: noDelete ?? false }, { gitOps: session.gitOps, log: this.log, fileChanges });
28
+ await this.manifestManager.deleteOrphans(filesToDelete, { dryRun: dryRun, noDelete: noDelete }, { gitOps: session.gitOps, log: this.log, fileChanges });
28
29
  // Update diff stats for deletions in dry-run
29
30
  if (dryRun && filesToDelete.length > 0 && !noDelete) {
30
31
  for (const fileName of filesToDelete) {
@@ -34,7 +35,7 @@ export class FileSyncOrchestrator {
34
35
  }
35
36
  }
36
37
  // Save manifest
37
- this.manifestManager.saveUpdatedManifest(workDir, newManifest, existingManifest, dryRun ?? false, fileChanges);
38
+ this.manifestManager.saveUpdatedManifest(workDir, newManifest, existingManifest, dryRun, fileChanges);
38
39
  // Show diff summary in dry-run
39
40
  if (dryRun) {
40
41
  this.log.diffSummary(diffStats.newCount, diffStats.modifiedCount, diffStats.unchangedCount, diffStats.deletedCount);
@@ -5,7 +5,7 @@ import type { IFileWriter, FileWriteContext, FileWriterDeps, FileWriteAllResult
5
5
  * .sh files are auto-executable unless explicit executable: false is set.
6
6
  * Non-.sh files are executable only if executable: true is explicitly set.
7
7
  */
8
- export declare function shouldBeExecutable(file: FileContent): boolean;
8
+ declare function shouldBeExecutable(file: FileContent): boolean;
9
9
  /**
10
10
  * Handles file writing, template interpolation, and executable permissions.
11
11
  */
@@ -16,3 +16,4 @@ export declare class FileWriter implements IFileWriter {
16
16
  static shouldBeExecutable: typeof shouldBeExecutable;
17
17
  writeFiles(files: FileContent[], ctx: FileWriteContext, deps: FileWriterDeps): Promise<FileWriteAllResult>;
18
18
  }
19
+ export {};
@@ -1,15 +1,14 @@
1
1
  import { existsSync } from "node:fs";
2
2
  import { join } from "node:path";
3
3
  import { convertContentToString } from "../config/formatter.js";
4
- import { interpolateXfgContent } from "./xfg-template.js";
4
+ import { interpolateXfgContent } from "../shared/xfg-template.js";
5
5
  import { getFileStatus, generateDiff, createDiffStats, incrementDiffStats, } from "./diff-utils.js";
6
- import { hasGitHubAppCredentials } from "../vcs/commit-strategy-selector.js";
7
6
  /**
8
7
  * Determines if a file should be marked as executable.
9
8
  * .sh files are auto-executable unless explicit executable: false is set.
10
9
  * Non-.sh files are executable only if executable: true is explicitly set.
11
10
  */
12
- export function shouldBeExecutable(file) {
11
+ function shouldBeExecutable(file) {
13
12
  const isShellScript = file.fileName.endsWith(".sh");
14
13
  if (file.executable !== undefined) {
15
14
  // Explicit setting takes precedence
@@ -31,7 +30,6 @@ export class FileWriter {
31
30
  const { gitOps, log } = deps;
32
31
  const fileChanges = new Map();
33
32
  const diffStats = createDiffStats();
34
- // Step 1: Process each file
35
33
  for (const file of files) {
36
34
  const filePath = join(workDir, file.fileName);
37
35
  const fileExistsLocal = existsSync(filePath);
@@ -86,14 +84,13 @@ export class FileWriter {
86
84
  gitOps.writeFile(file.fileName, fileContent);
87
85
  }
88
86
  }
89
- // Step 2: Set executable permissions (skip skipped files)
90
87
  for (const file of files) {
91
88
  const tracked = fileChanges.get(file.fileName);
92
89
  if (tracked?.action === "skip") {
93
90
  continue;
94
91
  }
95
92
  if (shouldBeExecutable(file)) {
96
- if (tracked?.action === "create" && hasGitHubAppCredentials()) {
93
+ if (tracked?.action === "create" && ctx.isGraphQLCommitMode) {
97
94
  log.warn(`${file.fileName}: GitHub App commits cannot set executable mode on new files. ` +
98
95
  `The file will be created as non-executable (100644). ` +
99
96
  `See: https://anthony-spruyt.github.io/xfg/examples/executable-files/`);
@@ -1,17 +1,3 @@
1
- export { FileWriter, shouldBeExecutable } from "./file-writer.js";
2
- export { ManifestManager } from "./manifest-manager.js";
3
- export { BranchManager } from "./branch-manager.js";
4
- export { AuthOptionsBuilder } from "./auth-options-builder.js";
5
- export { RepositorySession } from "./repository-session.js";
6
- export { CommitPushManager } from "./commit-push-manager.js";
7
- export { formatCommitMessage } from "./commit-message.js";
8
- export { FileSyncOrchestrator } from "./file-sync-orchestrator.js";
9
- export { PRMergeHandler } from "./pr-merge-handler.js";
10
- export { FileSyncStrategy } from "./file-sync-strategy.js";
11
- export { ManifestStrategy, type ManifestUpdateParams, } from "./manifest-strategy.js";
12
- export { SyncWorkflow } from "./sync-workflow.js";
13
- export type { IFileWriter, FileWriteContext, FileWriterDeps, FileWriteAllResult, FileWriteResult, IManifestManager, OrphanProcessResult, OrphanDeleteOptions, OrphanDeleteDeps, IBranchManager, BranchSetupOptions, IAuthOptionsBuilder, AuthResult, IRepositorySession, SessionOptions, SessionContext, ICommitPushManager, CommitPushOptions, CommitPushResult, GitOpsFactory, IRepositoryProcessor, ProcessorOptions, ProcessorResult, FileChangeDetail, IFileSyncOrchestrator, FileSyncResult, IPRMergeHandler, PRHandlerOptions, WorkResult, IWorkStrategy, ISyncWorkflow, } from "./types.js";
1
+ export type { DiffStats } from "./diff-utils.js";
2
+ export type { GitOpsFactory, IAuthOptionsBuilder, IBranchManager, ICommitPushManager, IFileSyncOrchestrator, IPRMergeHandler, IRepositoryProcessor, IRepositorySession, ISyncWorkflow, IWorkStrategy, ProcessorResult, SessionContext, WorkResult, } from "./types.js";
14
3
  export { RepositoryProcessor } from "./repository-processor.js";
15
- export { createEmptyManifest, loadManifest, saveManifest, getManagedFiles, getManagedRulesets, getManagedLabels, updateManifest, updateManifestRulesets, updateManifestLabels, MANIFEST_FILENAME, type XfgManifest, type XfgManifestConfigEntry, } from "./manifest.js";
16
- export { getFileStatus, formatStatusBadge, formatDiffLine, generateDiff, createDiffStats, incrementDiffStats, type FileStatus, type DiffStats, } from "./diff-utils.js";
17
- export { interpolateXfgContent, type XfgTemplateContext, type XfgInterpolationOptions, } from "./xfg-template.js";
@@ -1,21 +1 @@
1
- export { FileWriter, shouldBeExecutable } from "./file-writer.js";
2
- export { ManifestManager } from "./manifest-manager.js";
3
- export { BranchManager } from "./branch-manager.js";
4
- export { AuthOptionsBuilder } from "./auth-options-builder.js";
5
- export { RepositorySession } from "./repository-session.js";
6
- export { CommitPushManager } from "./commit-push-manager.js";
7
- export { formatCommitMessage } from "./commit-message.js";
8
- export { FileSyncOrchestrator } from "./file-sync-orchestrator.js";
9
- export { PRMergeHandler } from "./pr-merge-handler.js";
10
- // Strategy pattern components
11
- export { FileSyncStrategy } from "./file-sync-strategy.js";
12
- export { ManifestStrategy, } from "./manifest-strategy.js";
13
- export { SyncWorkflow } from "./sync-workflow.js";
14
- // Repository processor
15
1
  export { RepositoryProcessor } from "./repository-processor.js";
16
- // Manifest handling
17
- export { createEmptyManifest, loadManifest, saveManifest, getManagedFiles, getManagedRulesets, getManagedLabels, updateManifest, updateManifestRulesets, updateManifestLabels, MANIFEST_FILENAME, } from "./manifest.js";
18
- // Diff utilities
19
- export { getFileStatus, formatStatusBadge, formatDiffLine, generateDiff, createDiffStats, incrementDiffStats, } from "./diff-utils.js";
20
- // XFG templating
21
- export { interpolateXfgContent, } from "./xfg-template.js";
@@ -4,6 +4,10 @@ import type { IManifestManager, OrphanProcessResult, OrphanDeleteOptions, Orphan
4
4
  * Handles manifest loading, saving, and orphan detection.
5
5
  */
6
6
  export declare class ManifestManager implements IManifestManager {
7
+ private readonly log?;
8
+ constructor(log?: {
9
+ debug(msg: string): void;
10
+ } | undefined);
7
11
  processOrphans(workDir: string, configId: string, filesWithDeleteOrphaned: Map<string, boolean | undefined>): OrphanProcessResult;
8
12
  deleteOrphans(filesToDelete: string[], options: OrphanDeleteOptions, deps: OrphanDeleteDeps): Promise<void>;
9
13
  saveUpdatedManifest(workDir: string, manifest: XfgManifest, existingManifest: XfgManifest | null, dryRun: boolean, fileChanges: Map<string, FileWriteResult>): void;
@@ -5,8 +5,12 @@ import { loadManifest, saveManifest, updateManifest, MANIFEST_FILENAME, } from "
5
5
  * Handles manifest loading, saving, and orphan detection.
6
6
  */
7
7
  export class ManifestManager {
8
+ log;
9
+ constructor(log) {
10
+ this.log = log;
11
+ }
8
12
  processOrphans(workDir, configId, filesWithDeleteOrphaned) {
9
- const existingManifest = loadManifest(workDir);
13
+ const existingManifest = loadManifest(workDir, this.log);
10
14
  const { manifest, filesToDelete } = updateManifest(existingManifest, configId, filesWithDeleteOrphaned);
11
15
  return { manifest, filesToDelete };
12
16
  }
@@ -1,106 +1,33 @@
1
1
  export declare const MANIFEST_FILENAME = ".xfg.json";
2
2
  export interface XfgManifestConfigEntry {
3
3
  files?: string[];
4
- rulesets?: string[];
5
- labels?: string[];
6
4
  }
7
5
  export interface XfgManifest {
8
- version: 3;
6
+ version: 4;
9
7
  configs: Record<string, XfgManifestConfigEntry>;
10
8
  }
11
- /**
12
- * Creates an empty manifest with the current version.
13
- */
14
9
  export declare function createEmptyManifest(): XfgManifest;
15
10
  /**
16
- * Loads the xfg manifest from a repository's working directory.
17
- * Returns null if the manifest file doesn't exist or is v1 format.
18
- *
19
- * V1 manifests are treated as non-existent because they lack the config ID
20
- * namespace required for multi-config support. The next run will create
21
- * a fresh v3 manifest.
22
- *
23
- * V2 manifests are automatically migrated to V3 format.
24
- *
25
- * @param workDir - The repository working directory
26
- * @returns The manifest or null if not found or incompatible
11
+ * Loads and migrates manifest from workDir. V1 returns null (no config-ID namespace);
12
+ * V2/V3 are auto-migrated to V4.
27
13
  */
28
- export declare function loadManifest(workDir: string): XfgManifest | null;
14
+ export declare function loadManifest(workDir: string, log?: {
15
+ debug(msg: string): void;
16
+ }): XfgManifest | null;
29
17
  /**
30
18
  * Parses manifest content from a string (e.g., fetched from a remote API).
31
19
  * Handles V2→V3 migration, returns null for V1/unknown/invalid formats.
32
20
  */
33
- export declare function parseManifestContent(content: string): XfgManifest | null;
34
- /**
35
- * Saves the xfg manifest to a repository's working directory.
36
- *
37
- * @param workDir - The repository working directory
38
- * @param manifest - The manifest to save
39
- */
21
+ export declare function parseManifestContent(content: string, log?: {
22
+ debug(msg: string): void;
23
+ }): XfgManifest | null;
40
24
  export declare function saveManifest(workDir: string, manifest: XfgManifest): void;
41
- /**
42
- * Gets the list of managed files for a specific config from a manifest.
43
- * Returns an empty array if the manifest is null or the config isn't found.
44
- *
45
- * @param manifest - The manifest or null
46
- * @param configId - The config ID to get files for
47
- * @returns Array of managed file names for the given config
48
- */
49
25
  export declare function getManagedFiles(manifest: XfgManifest | null, configId: string): string[];
50
26
  /**
51
- * Gets the list of managed rulesets for a specific config from a manifest.
52
- * Returns an empty array if the manifest is null or the config isn't found.
53
- *
54
- * @param manifest - The manifest or null
55
- * @param configId - The config ID to get rulesets for
56
- * @returns Array of managed ruleset names for the given config
57
- */
58
- export declare function getManagedRulesets(manifest: XfgManifest | null, configId: string): string[];
59
- /**
60
- * Gets the list of managed labels for a specific config from a manifest.
61
- * Returns an empty array if the manifest is null or the config isn't found.
62
- */
63
- export declare function getManagedLabels(manifest: XfgManifest | null, configId: string): string[];
64
- /**
65
- * Updates the manifest with the current set of files that have deleteOrphaned enabled
66
- * for a specific config. Only modifies that config's files namespace - other configs are untouched.
67
- *
68
- * Files with deleteOrphaned: true are added to managedFiles.
69
- * Files with deleteOrphaned: false (explicit) are removed from managedFiles.
70
- * Files not in the config but in managedFiles for this configId are candidates for deletion.
71
- *
72
- * @param manifest - The existing manifest (or null for new repos)
73
- * @param configId - The config ID to update
74
- * @param filesWithDeleteOrphaned - Map of fileName to deleteOrphaned value (true/false/undefined)
75
- * @returns Updated manifest and list of files to delete
27
+ * Updates manifest tracking for a config. Files with deleteOrphaned: true are tracked;
28
+ * files previously tracked but no longer in config are returned as filesToDelete.
76
29
  */
77
30
  export declare function updateManifest(manifest: XfgManifest | null, configId: string, filesWithDeleteOrphaned: Map<string, boolean | undefined>): {
78
31
  manifest: XfgManifest;
79
32
  filesToDelete: string[];
80
33
  };
81
- /**
82
- * Updates the manifest with the current set of rulesets that have deleteOrphaned enabled
83
- * for a specific config. Only modifies that config's rulesets namespace - other configs are untouched.
84
- *
85
- * @param manifest - The existing manifest (or null for new repos)
86
- * @param configId - The config ID to update
87
- * @param rulesetsWithDeleteOrphaned - Map of ruleset name to deleteOrphaned value (true/false/undefined)
88
- * @returns Updated manifest and list of rulesets to delete
89
- */
90
- export declare function updateManifestRulesets(manifest: XfgManifest | null, configId: string, rulesetsWithDeleteOrphaned: Map<string, boolean | undefined>): {
91
- manifest: XfgManifest;
92
- rulesetsToDelete: string[];
93
- };
94
- /**
95
- * Updates the manifest with the current set of labels that have deleteOrphaned enabled
96
- * for a specific config. Only modifies that config's labels namespace - other configs are untouched.
97
- *
98
- * @param manifest - The existing manifest (or null for new repos)
99
- * @param configId - The config ID to update
100
- * @param labelsWithDeleteOrphaned - Map of label name to deleteOrphaned value (true/false/undefined)
101
- * @returns Updated manifest and list of labels to delete
102
- */
103
- export declare function updateManifestLabels(manifest: XfgManifest | null, configId: string, labelsWithDeleteOrphaned: Map<string, boolean | undefined>): {
104
- manifest: XfgManifest;
105
- labelsToDelete: string[];
106
- };