@fuzdev/fuz_gitops 0.67.0 → 0.69.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.
Files changed (89) hide show
  1. package/dist/ModulesDetail.svelte +14 -14
  2. package/dist/ModulesNav.svelte +2 -2
  3. package/dist/PageFooter.svelte +1 -1
  4. package/dist/ReposTable.svelte +1 -1
  5. package/dist/ReposTree.svelte +6 -6
  6. package/dist/ReposTreeNav.svelte +1 -1
  7. package/dist/TablePage.svelte +1 -7
  8. package/dist/TreeItemPage.svelte +3 -3
  9. package/dist/TreePage.svelte +3 -3
  10. package/dist/changeset_generator.d.ts +4 -4
  11. package/dist/changeset_generator.js +5 -5
  12. package/dist/changeset_reader.d.ts +6 -4
  13. package/dist/changeset_reader.d.ts.map +1 -1
  14. package/dist/changeset_reader.js +7 -5
  15. package/dist/dependency_graph.d.ts +3 -3
  16. package/dist/dependency_graph.js +3 -3
  17. package/dist/dependency_updater.d.ts +4 -4
  18. package/dist/dependency_updater.js +5 -5
  19. package/dist/fetch_repo_data.d.ts +4 -4
  20. package/dist/fetch_repo_data.d.ts.map +1 -1
  21. package/dist/fetch_repo_data.js +4 -5
  22. package/dist/fs_fetch_value_cache.d.ts +4 -4
  23. package/dist/fs_fetch_value_cache.js +4 -4
  24. package/dist/git_operations.d.ts +5 -5
  25. package/dist/git_operations.d.ts.map +1 -1
  26. package/dist/git_operations.js +18 -18
  27. package/dist/github.d.ts +1 -1
  28. package/dist/gitops_plan.task.d.ts +3 -3
  29. package/dist/gitops_plan.task.js +3 -3
  30. package/dist/gitops_run.task.js +1 -1
  31. package/dist/gitops_task_helpers.d.ts +5 -5
  32. package/dist/gitops_task_helpers.js +5 -5
  33. package/dist/graph_validation.d.ts +5 -5
  34. package/dist/graph_validation.js +5 -5
  35. package/dist/local_repo.d.ts +6 -6
  36. package/dist/local_repo.js +12 -9
  37. package/dist/multi_repo_publisher.d.ts.map +1 -1
  38. package/dist/multi_repo_publisher.js +4 -4
  39. package/dist/npm_install_helpers.d.ts +3 -3
  40. package/dist/npm_install_helpers.js +3 -3
  41. package/dist/npm_registry.d.ts +4 -4
  42. package/dist/npm_registry.js +5 -6
  43. package/dist/operations.d.ts +19 -17
  44. package/dist/operations.d.ts.map +1 -1
  45. package/dist/operations.js +1 -1
  46. package/dist/operations_defaults.d.ts.map +1 -1
  47. package/dist/operations_defaults.js +49 -14
  48. package/dist/output_helpers.d.ts +2 -2
  49. package/dist/output_helpers.js +2 -2
  50. package/dist/paths.d.ts +1 -1
  51. package/dist/paths.js +1 -1
  52. package/dist/preflight_checks.d.ts +2 -2
  53. package/dist/preflight_checks.js +7 -7
  54. package/dist/publishing_plan.js +4 -4
  55. package/dist/publishing_plan_helpers.d.ts +1 -1
  56. package/dist/publishing_plan_helpers.js +1 -1
  57. package/dist/repo.svelte.d.ts +3 -3
  58. package/dist/repo.svelte.js +2 -2
  59. package/dist/repo_ops.d.ts +6 -6
  60. package/dist/repo_ops.js +7 -7
  61. package/dist/version_utils.d.ts +2 -2
  62. package/dist/version_utils.js +2 -2
  63. package/package.json +18 -16
  64. package/src/lib/changeset_generator.ts +5 -5
  65. package/src/lib/changeset_reader.ts +7 -5
  66. package/src/lib/dependency_graph.ts +3 -3
  67. package/src/lib/dependency_updater.ts +5 -5
  68. package/src/lib/fetch_repo_data.ts +4 -6
  69. package/src/lib/fs_fetch_value_cache.ts +4 -4
  70. package/src/lib/git_operations.ts +32 -18
  71. package/src/lib/github.ts +1 -1
  72. package/src/lib/gitops_plan.task.ts +3 -3
  73. package/src/lib/gitops_run.task.ts +1 -1
  74. package/src/lib/gitops_task_helpers.ts +5 -5
  75. package/src/lib/graph_validation.ts +5 -5
  76. package/src/lib/local_repo.ts +18 -11
  77. package/src/lib/multi_repo_publisher.ts +4 -6
  78. package/src/lib/npm_install_helpers.ts +3 -3
  79. package/src/lib/npm_registry.ts +6 -6
  80. package/src/lib/operations.ts +19 -17
  81. package/src/lib/operations_defaults.ts +47 -16
  82. package/src/lib/output_helpers.ts +2 -2
  83. package/src/lib/paths.ts +1 -1
  84. package/src/lib/preflight_checks.ts +7 -7
  85. package/src/lib/publishing_plan.ts +4 -4
  86. package/src/lib/publishing_plan_helpers.ts +1 -1
  87. package/src/lib/repo.svelte.ts +3 -3
  88. package/src/lib/repo_ops.ts +7 -7
  89. package/src/lib/version_utils.ts +2 -2
@@ -6,15 +6,15 @@
6
6
  *
7
7
  * @module
8
8
  */
9
- import { spawn, spawn_out } from '@fuzdev/fuz_util/process.js';
10
- import { readFile, writeFile, mkdir } from 'node:fs/promises';
11
- import { existsSync } from 'node:fs';
9
+ import { spawn_out } from '@fuzdev/fuz_util/process.js';
10
+ import { readFile, writeFile, mkdir, stat } from 'node:fs/promises';
12
11
  import { git_checkout } from '@fuzdev/fuz_util/git.js';
12
+ import { fs_classify_error } from '@fuzdev/fuz_util/fs.js';
13
13
  import { EMPTY_OBJECT } from '@fuzdev/fuz_util/object.js';
14
14
  import { has_changesets, read_changesets, predict_next_version } from './changeset_reader.js';
15
15
  import { wait_for_package, check_package_available } from './npm_registry.js';
16
16
  import { run_preflight_checks } from './preflight_checks.js';
17
- import { git_add, git_commit, git_add_and_commit, git_tag, git_push_tag, git_has_changes, git_get_changed_files, git_has_file_changed, git_stash, git_stash_pop, git_switch_branch, git_current_branch_name_required, git_current_commit_hash_required, git_check_clean_workspace_as_boolean, git_has_remote, } from './git_operations.js';
17
+ import { git_add, git_commit, git_add_and_commit, git_tag, git_push_tag, git_has_changes, git_list_uncommitted_files, git_has_file_changed, git_stash, git_stash_pop, git_switch_branch, git_current_branch_name_required, git_current_commit_hash_required, git_check_clean_workspace_as_boolean, git_has_remote, } from './git_operations.js';
18
18
  /** Wrap an async function that returns a value */
19
19
  const wrap_with_value = async (fn) => {
20
20
  try {
@@ -79,7 +79,18 @@ export const default_git_operations = {
79
79
  },
80
80
  pull: async (options) => {
81
81
  const { origin, branch, cwd } = options ?? EMPTY_OBJECT;
82
- return wrap_void(() => spawn('git', ['pull', origin || 'origin', branch || ''], cwd ? { cwd } : undefined));
82
+ try {
83
+ const spawned = await spawn_out('git', ['pull', origin || 'origin', branch || ''], cwd ? { cwd } : undefined);
84
+ if (spawned.result.ok) {
85
+ return { ok: true };
86
+ }
87
+ else {
88
+ return { ok: false, message: spawned.stderr || 'Pull failed' };
89
+ }
90
+ }
91
+ catch (error) {
92
+ return { ok: false, message: String(error) };
93
+ }
83
94
  },
84
95
  switch_branch: async (options) => {
85
96
  const { branch, pull, cwd } = options;
@@ -106,9 +117,9 @@ export const default_git_operations = {
106
117
  const { cwd } = options ?? EMPTY_OBJECT;
107
118
  return wrap_with_value(() => git_has_changes(cwd ? { cwd } : undefined));
108
119
  },
109
- get_changed_files: async (options) => {
120
+ list_uncommitted_files: async (options) => {
110
121
  const { cwd } = options ?? EMPTY_OBJECT;
111
- return wrap_with_value(() => git_get_changed_files(cwd ? { cwd } : undefined));
122
+ return wrap_with_value(() => git_list_uncommitted_files(cwd ? { cwd } : undefined));
112
123
  },
113
124
  // Tagging
114
125
  tag: async (options) => {
@@ -136,9 +147,9 @@ export const default_git_operations = {
136
147
  };
137
148
  export const default_process_operations = {
138
149
  spawn: async (options) => {
139
- const { cmd, args, spawn_options } = options;
150
+ const { cmd, args, cwd } = options;
140
151
  try {
141
- const spawned = await spawn_out(cmd, args, spawn_options);
152
+ const spawned = await spawn_out(cmd, args, cwd ? { cwd } : undefined);
142
153
  if (spawned.result.ok) {
143
154
  return {
144
155
  ok: true,
@@ -239,18 +250,42 @@ export const default_preflight_operations = {
239
250
  export const default_fs_operations = {
240
251
  readFile: async (options) => {
241
252
  const { path, encoding } = options;
242
- return wrap_with_value(() => readFile(path, encoding));
253
+ try {
254
+ const value = await readFile(path, encoding);
255
+ return { ok: true, value };
256
+ }
257
+ catch (error) {
258
+ return { ok: false, ...fs_classify_error(error) };
259
+ }
243
260
  },
244
261
  writeFile: async (options) => {
245
262
  const { path, content } = options;
246
- return wrap_void(() => writeFile(path, content));
263
+ try {
264
+ await writeFile(path, content);
265
+ return { ok: true };
266
+ }
267
+ catch (error) {
268
+ return { ok: false, ...fs_classify_error(error) };
269
+ }
247
270
  },
248
271
  mkdir: async (options) => {
249
272
  const { path, recursive } = options;
250
- return wrap_void(() => mkdir(path, { recursive }));
273
+ try {
274
+ await mkdir(path, { recursive });
275
+ return { ok: true };
276
+ }
277
+ catch (error) {
278
+ return { ok: false, ...fs_classify_error(error) };
279
+ }
251
280
  },
252
- exists: (options) => {
253
- return existsSync(options.path);
281
+ exists: async (options) => {
282
+ try {
283
+ await stat(options.path);
284
+ return true;
285
+ }
286
+ catch {
287
+ return false;
288
+ }
254
289
  },
255
290
  };
256
291
  export const default_build_operations = {
@@ -17,11 +17,11 @@ export interface OutputFormatters<T> {
17
17
  * Formats data and outputs to file or stdout based on options.
18
18
  *
19
19
  * Supports three formats:
20
- * - stdout: Uses logger for colored/styled output (cannot use with --outfile)
20
+ * - stdout: Uses logger for colored/styled output (cannot use with `--outfile`)
21
21
  * - json: Stringified JSON
22
22
  * - markdown: Formatted markdown text
23
23
  *
24
- * @throws {Error} if stdout format used with outfile, or if logger missing for stdout
24
+ * @throws {Error} if stdout format used with `outfile`, or if logger missing for stdout
25
25
  */
26
26
  export declare const format_and_output: <T>(data: T, formatters: OutputFormatters<T>, options: OutputOptions) => Promise<void>;
27
27
  //# sourceMappingURL=output_helpers.d.ts.map
@@ -3,11 +3,11 @@ import { writeFile } from 'node:fs/promises';
3
3
  * Formats data and outputs to file or stdout based on options.
4
4
  *
5
5
  * Supports three formats:
6
- * - stdout: Uses logger for colored/styled output (cannot use with --outfile)
6
+ * - stdout: Uses logger for colored/styled output (cannot use with `--outfile`)
7
7
  * - json: Stringified JSON
8
8
  * - markdown: Formatted markdown text
9
9
  *
10
- * @throws {Error} if stdout format used with outfile, or if logger missing for stdout
10
+ * @throws {Error} if stdout format used with `outfile`, or if logger missing for stdout
11
11
  */
12
12
  export const format_and_output = async (data, formatters, options) => {
13
13
  const { format, outfile, log } = options;
package/dist/paths.d.ts CHANGED
@@ -5,7 +5,7 @@ export declare const GITOPS_OUTPUT_DIR = ".gro/fuz_gitops";
5
5
  /**
6
6
  * Default repos directory relative to gitops config file.
7
7
  * Resolves to the parent of the directory with the config
8
- * (e.g., ~/dev/repo/gitops.config.ts resolves to ~/dev/).
8
+ * (e.g., `~/dev/repo/gitops.config.ts` resolves to `~/dev/`).
9
9
  */
10
10
  export declare const DEFAULT_REPOS_DIR = "..";
11
11
  //# sourceMappingURL=paths.d.ts.map
package/dist/paths.js CHANGED
@@ -5,6 +5,6 @@ export const GITOPS_OUTPUT_DIR = '.gro/fuz_gitops';
5
5
  /**
6
6
  * Default repos directory relative to gitops config file.
7
7
  * Resolves to the parent of the directory with the config
8
- * (e.g., ~/dev/repo/gitops.config.ts resolves to ~/dev/).
8
+ * (e.g., `~/dev/repo/gitops.config.ts` resolves to `~/dev/`).
9
9
  */
10
10
  export const DEFAULT_REPOS_DIR = '..';
@@ -32,7 +32,7 @@ export interface RunPreflightChecksOptions {
32
32
  * Performs comprehensive pre-flight validation:
33
33
  * - Clean workspaces (100% clean required - no uncommitted changes)
34
34
  * - Correct branch (usually main)
35
- * - Changesets present (unless skip_changesets=true)
35
+ * - Changesets present (unless `skip_changesets`=true)
36
36
  * - Builds successful (fail-fast to prevent broken state)
37
37
  * - Git remote reachability
38
38
  * - NPM authentication with username
@@ -41,7 +41,7 @@ export interface RunPreflightChecksOptions {
41
41
  * Build validation runs BEFORE any publishing to prevent the scenario where
42
42
  * version is bumped but build fails, leaving repo in broken state.
43
43
  *
44
- * @returns result with ok=false if any errors, plus warnings and detailed status
44
+ * @returns result with `ok`=false if any errors, plus warnings and detailed status
45
45
  */
46
46
  export declare const run_preflight_checks: ({ repos, preflight_options, git_ops, npm_ops, build_ops, changeset_ops, }: RunPreflightChecksOptions) => Promise<PreflightResult>;
47
47
  //# sourceMappingURL=preflight_checks.d.ts.map
@@ -7,7 +7,7 @@ import { default_git_operations, default_npm_operations, default_build_operation
7
7
  * Performs comprehensive pre-flight validation:
8
8
  * - Clean workspaces (100% clean required - no uncommitted changes)
9
9
  * - Correct branch (usually main)
10
- * - Changesets present (unless skip_changesets=true)
10
+ * - Changesets present (unless `skip_changesets`=true)
11
11
  * - Builds successful (fail-fast to prevent broken state)
12
12
  * - Git remote reachability
13
13
  * - NPM authentication with username
@@ -16,7 +16,7 @@ import { default_git_operations, default_npm_operations, default_build_operation
16
16
  * Build validation runs BEFORE any publishing to prevent the scenario where
17
17
  * version is bumped but build fails, leaving repo in broken state.
18
18
  *
19
- * @returns result with ok=false if any errors, plus warnings and detailed status
19
+ * @returns result with `ok`=false if any errors, plus warnings and detailed status
20
20
  */
21
21
  export const run_preflight_checks = async ({ repos, preflight_options = {}, git_ops = default_git_operations, npm_ops = default_npm_operations, build_ops = default_build_operations, changeset_ops = default_changeset_operations, }) => {
22
22
  const { skip_changesets = false, skip_build_validation = false, required_branch = 'main', check_remote = true, estimate_time = true, log, } = preflight_options;
@@ -30,14 +30,14 @@ export const run_preflight_checks = async ({ repos, preflight_options = {}, git_
30
30
  // 1. Check clean workspaces - must be 100% clean before publishing
31
31
  log?.info(' Checking workspace cleanliness...');
32
32
  for (const repo of repos) {
33
- const clean_result = await git_ops.check_clean_workspace({ cwd: repo.repo_dir }); // eslint-disable-line no-await-in-loop
33
+ const clean_result = await git_ops.check_clean_workspace({ cwd: repo.repo_dir });
34
34
  if (!clean_result.ok) {
35
35
  errors.push(`${repo.library.name} failed workspace check: ${clean_result.message}`);
36
36
  continue;
37
37
  }
38
38
  if (!clean_result.value) {
39
39
  // Get list of changed files for better error message
40
- const files_result = await git_ops.get_changed_files({ cwd: repo.repo_dir }); // eslint-disable-line no-await-in-loop
40
+ const files_result = await git_ops.list_uncommitted_files({ cwd: repo.repo_dir });
41
41
  if (files_result.ok) {
42
42
  // No filtering - workspace must be 100% clean
43
43
  const unexpected_files = files_result.value;
@@ -53,7 +53,7 @@ export const run_preflight_checks = async ({ repos, preflight_options = {}, git_
53
53
  // 2. Check correct branch
54
54
  log?.info(` Checking branches (expecting ${required_branch})...`);
55
55
  for (const repo of repos) {
56
- const branch_result = await git_ops.current_branch_name({ cwd: repo.repo_dir }); // eslint-disable-line no-await-in-loop
56
+ const branch_result = await git_ops.current_branch_name({ cwd: repo.repo_dir });
57
57
  if (!branch_result.ok) {
58
58
  errors.push(`${repo.library.name} failed branch check: ${branch_result.message}`);
59
59
  continue;
@@ -66,7 +66,7 @@ export const run_preflight_checks = async ({ repos, preflight_options = {}, git_
66
66
  if (!skip_changesets) {
67
67
  log?.info(' Checking for changesets...');
68
68
  for (const repo of repos) {
69
- const has_result = await changeset_ops.has_changesets({ repo }); // eslint-disable-line no-await-in-loop
69
+ const has_result = await changeset_ops.has_changesets({ repo });
70
70
  if (!has_result.ok) {
71
71
  errors.push(`${repo.library.name} failed changeset check: ${has_result.message}`);
72
72
  continue;
@@ -90,7 +90,7 @@ export const run_preflight_checks = async ({ repos, preflight_options = {}, git_
90
90
  for (let i = 0; i < repos_to_build.length; i++) {
91
91
  const repo = repos_to_build[i];
92
92
  log?.info(st('dim', ` [${i + 1}/${repos_to_build.length}] Building ${repo.library.name}...`));
93
- const build_result = await build_ops.build_package({ repo, log }); // eslint-disable-line no-await-in-loop
93
+ const build_result = await build_ops.build_package({ repo, log });
94
94
  if (!build_result.ok) {
95
95
  errors.push(`${repo.library.name} failed to build: ${build_result.output || build_result.message || 'unknown error'}`);
96
96
  }
@@ -71,14 +71,14 @@ export const generate_publishing_plan = async (repos, options = {}) => {
71
71
  if (!repo)
72
72
  continue;
73
73
  // Check for changesets
74
- const has_result = await ops.has_changesets({ repo }); // eslint-disable-line no-await-in-loop
74
+ const has_result = await ops.has_changesets({ repo });
75
75
  if (!has_result.ok) {
76
76
  errors.push(`Failed to check changesets for ${pkg_name}: ${has_result.message}`);
77
77
  continue;
78
78
  }
79
79
  if (has_result.value) {
80
80
  // Predict version from changesets
81
- const prediction = await ops.predict_next_version({ repo, log }); // eslint-disable-line no-await-in-loop
81
+ const prediction = await ops.predict_next_version({ repo, log });
82
82
  if (!prediction) {
83
83
  // No changesets found - this shouldn't happen since has_changesets returned true
84
84
  continue;
@@ -89,7 +89,7 @@ export const generate_publishing_plan = async (repos, options = {}) => {
89
89
  }
90
90
  // Capture changeset details for verbose output
91
91
  if (verbose) {
92
- const changesets_result = await ops.read_changesets({ repo, log }); // eslint-disable-line no-await-in-loop
92
+ const changesets_result = await ops.read_changesets({ repo, log });
93
93
  if (changesets_result.ok) {
94
94
  const files = changesets_result.value
95
95
  .filter((cs) => cs.packages.some((p) => p.name === pkg_name))
@@ -272,7 +272,7 @@ export const generate_publishing_plan = async (repos, options = {}) => {
272
272
  for (const repo of repos) {
273
273
  const has_version_change = version_changes.some((vc) => vc.package_name === repo.library.name);
274
274
  if (!has_version_change) {
275
- const has_result = await ops.has_changesets({ repo }); // eslint-disable-line no-await-in-loop
275
+ const has_result = await ops.has_changesets({ repo });
276
276
  if (has_result.ok && !has_result.value) {
277
277
  info.push(repo.library.name);
278
278
  }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Helper functions for publishing plan calculations.
3
3
  *
4
- * Extracted from publishing_plan.ts to reduce file size.
4
+ * Extracted from `publishing_plan.ts` to reduce file size.
5
5
  *
6
6
  * @module
7
7
  */
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Helper functions for publishing plan calculations.
3
3
  *
4
- * Extracted from publishing_plan.ts to reduce file size.
4
+ * Extracted from `publishing_plan.ts` to reduce file size.
5
5
  *
6
6
  * @module
7
7
  */
@@ -6,7 +6,7 @@ import { Library } from '@fuzdev/fuz_ui/library.svelte.js';
6
6
  import type { Module } from '@fuzdev/fuz_ui/module.svelte.js';
7
7
  import { GithubCheckRunsItem, type GithubPullRequest } from './github.js';
8
8
  /**
9
- * Serialized repo data as stored in repos.ts (JSON).
9
+ * Serialized repo data as stored in `repos.ts` (JSON).
10
10
  */
11
11
  export interface RepoJson {
12
12
  library_json: LibraryJson;
@@ -14,9 +14,9 @@ export interface RepoJson {
14
14
  pull_requests: Array<GithubPullRequest> | null;
15
15
  }
16
16
  /**
17
- * Runtime repo with Library composition for package metadata.
17
+ * Runtime repo with `Library` composition for package metadata.
18
18
  *
19
- * Wraps a Library instance and adds GitHub-specific data (CI status, PRs).
19
+ * Wraps a `Library` instance and adds GitHub-specific data (CI status, PRs).
20
20
  * Convenience getters delegate to `this.library.*` for common properties.
21
21
  */
22
22
  export declare class Repo {
@@ -2,9 +2,9 @@ import { create_context } from '@fuzdev/fuz_ui/context_helpers.js';
2
2
  import { Library } from '@fuzdev/fuz_ui/library.svelte.js';
3
3
  import { GithubCheckRunsItem } from './github.js';
4
4
  /**
5
- * Runtime repo with Library composition for package metadata.
5
+ * Runtime repo with `Library` composition for package metadata.
6
6
  *
7
- * Wraps a Library instance and adds GitHub-specific data (CI status, PRs).
7
+ * Wraps a `Library` instance and adds GitHub-specific data (CI status, PRs).
8
8
  * Convenience getters delegate to `this.library.*` for common properties.
9
9
  */
10
10
  export class Repo {
@@ -6,7 +6,7 @@
6
6
  * - Walking files in repos with sensible exclusions
7
7
  * - Common exclusion patterns for node/svelte projects
8
8
  *
9
- * For full git sync/clone functionality, use `get_gitops_ready()` from gitops_task_helpers.
9
+ * For full git sync/clone functionality, use `get_gitops_ready()` from `gitops_task_helpers`.
10
10
  *
11
11
  * @module
12
12
  */
@@ -35,8 +35,8 @@ export interface RepoPath {
35
35
  * Get repo paths from gitops config without full git sync.
36
36
  * Lighter weight than `get_gitops_ready()` - just resolves paths.
37
37
  *
38
- * @param config_path Path to gitops.config.ts (defaults to ./gitops.config.ts)
39
- * @returns Array of repo info with name, path, and url
38
+ * @param config_path - path to `gitops.config.ts` (defaults to `./gitops.config.ts`)
39
+ * @returns array of repo info with name, path, and url
40
40
  */
41
41
  export declare const get_repo_paths: (config_path?: string) => Promise<Array<RepoPath>>;
42
42
  /**
@@ -47,12 +47,12 @@ export declare const should_exclude_path: (file_path: string, options?: WalkOpti
47
47
  * Walk files in a directory, respecting common exclusions.
48
48
  * Yields absolute paths to files (and optionally directories).
49
49
  *
50
- * @param dir Directory to walk
51
- * @param options Walk options for exclusions and filtering
50
+ * @param dir - directory to walk
51
+ * @param options - walk options for exclusions and filtering
52
52
  */
53
53
  export declare function walk_repo_files(dir: string, options?: WalkOptions): AsyncGenerator<string, void, undefined>;
54
54
  /**
55
- * Collect all files from walk_repo_files into an array.
55
+ * Collect all files from `walk_repo_files` into an array.
56
56
  * Convenience function for when you need all paths upfront.
57
57
  */
58
58
  export declare const collect_repo_files: (dir: string, options?: WalkOptions) => Promise<Array<string>>;
package/dist/repo_ops.js CHANGED
@@ -6,7 +6,7 @@
6
6
  * - Walking files in repos with sensible exclusions
7
7
  * - Common exclusion patterns for node/svelte projects
8
8
  *
9
- * For full git sync/clone functionality, use `get_gitops_ready()` from gitops_task_helpers.
9
+ * For full git sync/clone functionality, use `get_gitops_ready()` from `gitops_task_helpers`.
10
10
  *
11
11
  * @module
12
12
  */
@@ -59,8 +59,8 @@ export const DEFAULT_EXCLUDE_EXTENSIONS = [
59
59
  * Get repo paths from gitops config without full git sync.
60
60
  * Lighter weight than `get_gitops_ready()` - just resolves paths.
61
61
  *
62
- * @param config_path Path to gitops.config.ts (defaults to ./gitops.config.ts)
63
- * @returns Array of repo info with name, path, and url
62
+ * @param config_path - path to `gitops.config.ts` (defaults to `./gitops.config.ts`)
63
+ * @returns array of repo info with name, path, and url
64
64
  */
65
65
  export const get_repo_paths = async (config_path) => {
66
66
  const resolved_config_path = resolve(config_path ?? GITOPS_CONFIG_PATH_DEFAULT);
@@ -115,8 +115,8 @@ export const should_exclude_path = (file_path, options) => {
115
115
  * Walk files in a directory, respecting common exclusions.
116
116
  * Yields absolute paths to files (and optionally directories).
117
117
  *
118
- * @param dir Directory to walk
119
- * @param options Walk options for exclusions and filtering
118
+ * @param dir - directory to walk
119
+ * @param options - walk options for exclusions and filtering
120
120
  */
121
121
  export async function* walk_repo_files(dir, options) {
122
122
  const max_file_size = options?.max_file_size ?? 10 * 1024 * 1024;
@@ -144,7 +144,7 @@ export async function* walk_repo_files(dir, options) {
144
144
  else if (entry.isFile()) {
145
145
  // Check file size
146
146
  try {
147
- const file_stat = await stat(full_path); // eslint-disable-line no-await-in-loop
147
+ const file_stat = await stat(full_path);
148
148
  if (file_stat.size <= max_file_size) {
149
149
  yield full_path;
150
150
  }
@@ -158,7 +158,7 @@ export async function* walk_repo_files(dir, options) {
158
158
  yield* walk(dir);
159
159
  }
160
160
  /**
161
- * Collect all files from walk_repo_files into an array.
161
+ * Collect all files from `walk_repo_files` into an array.
162
162
  * Convenience function for when you need all paths upfront.
163
163
  */
164
164
  export const collect_repo_files = async (dir, options) => {
@@ -12,7 +12,7 @@ export declare const get_version_prefix: (version: string) => string;
12
12
  * Normalizes version string for comparison.
13
13
  *
14
14
  * Strips prefixes (^, ~, >=) to get bare version number.
15
- * Handles wildcards as-is. Used by needs_update to compare versions.
15
+ * Handles wildcards as-is. Used by `needs_update` to compare versions.
16
16
  *
17
17
  * @example
18
18
  * ```ts
@@ -39,7 +39,7 @@ export declare const needs_update: (current: string, new_version: string) => boo
39
39
  *
40
40
  * This preserves user intent while handling wildcard replacements sensibly.
41
41
  *
42
- * @param default_strategy prefix to use when no existing prefix found
42
+ * @param default_strategy - prefix to use when no existing prefix found
43
43
  */
44
44
  export declare const get_update_prefix: (current_version: string, default_strategy?: "^" | "~" | "" | ">=") => string;
45
45
  /**
@@ -19,7 +19,7 @@ export const get_version_prefix = (version) => {
19
19
  * Normalizes version string for comparison.
20
20
  *
21
21
  * Strips prefixes (^, ~, >=) to get bare version number.
22
- * Handles wildcards as-is. Used by needs_update to compare versions.
22
+ * Handles wildcards as-is. Used by `needs_update` to compare versions.
23
23
  *
24
24
  * @example
25
25
  * ```ts
@@ -64,7 +64,7 @@ export const needs_update = (current, new_version) => {
64
64
  *
65
65
  * This preserves user intent while handling wildcard replacements sensibly.
66
66
  *
67
- * @param default_strategy prefix to use when no existing prefix found
67
+ * @param default_strategy - prefix to use when no existing prefix found
68
68
  */
69
69
  export const get_update_prefix = (current_version, default_strategy = '^') => {
70
70
  // Use caret for wildcard replacements
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fuzdev/fuz_gitops",
3
- "version": "0.67.0",
3
+ "version": "0.69.0",
4
4
  "description": "a tool for managing many repos",
5
5
  "glyph": "🪄",
6
6
  "logo": "logo.svg",
@@ -29,25 +29,26 @@
29
29
  "node": ">=22.15"
30
30
  },
31
31
  "peerDependencies": {
32
- "@fuzdev/fuz_css": ">=0.53.0",
33
- "@fuzdev/fuz_ui": ">=0.184.0",
34
- "@fuzdev/fuz_util": ">=0.52.0",
35
- "@fuzdev/gro": ">=0.195.0",
32
+ "@fuzdev/fuz_css": ">=0.56.0",
33
+ "@fuzdev/fuz_ui": ">=0.190.0",
34
+ "@fuzdev/fuz_util": ">=0.57.0",
35
+ "@fuzdev/gro": ">=0.197.0",
36
36
  "@sveltejs/kit": "^2",
37
37
  "svelte": "^5",
38
- "zod": "^4.1.13"
38
+ "zod": "^4.3.6"
39
39
  },
40
40
  "devDependencies": {
41
41
  "@changesets/changelog-git": "^0.2.1",
42
42
  "@fuzdev/fuz_code": "^0.45.1",
43
- "@fuzdev/fuz_css": "^0.53.0",
44
- "@fuzdev/fuz_ui": "^0.185.0",
45
- "@fuzdev/fuz_util": "^0.52.0",
46
- "@fuzdev/gro": "^0.195.0",
43
+ "@fuzdev/fuz_css": "^0.58.0",
44
+ "@fuzdev/fuz_ui": "^0.191.4",
45
+ "@fuzdev/fuz_util": "^0.57.0",
46
+ "@fuzdev/gro": "^0.198.0",
47
47
  "@jridgewell/trace-mapping": "^0.3.31",
48
- "@ryanatkn/eslint-config": "^0.9.0",
48
+ "@ryanatkn/eslint-config": "^0.11.0",
49
+ "@sveltejs/acorn-typescript": "^1.0.9",
49
50
  "@sveltejs/adapter-static": "^3.0.10",
50
- "@sveltejs/kit": "^2.50.1",
51
+ "@sveltejs/kit": "^2.57.0",
51
52
  "@sveltejs/package": "^2.5.7",
52
53
  "@sveltejs/vite-plugin-svelte": "^6.2.4",
53
54
  "@types/estree": "^1.0.8",
@@ -58,13 +59,14 @@
58
59
  "esm-env": "^1.2.2",
59
60
  "magic-string": "^0.30.21",
60
61
  "prettier": "^3.7.4",
61
- "prettier-plugin-svelte": "^3.4.1",
62
- "svelte": "^5.49.1",
63
- "svelte-check": "^4.3.6",
64
- "svelte2tsx": "^0.7.47",
62
+ "prettier-plugin-svelte": "^3.5.1",
63
+ "svelte": "^5.55.2",
64
+ "svelte-check": "^4.4.5",
65
+ "svelte2tsx": "^0.7.52",
65
66
  "tslib": "^2.8.1",
66
67
  "typescript": "^5.9.3",
67
68
  "typescript-eslint": "^8.48.1",
69
+ "vite": "^7.3.1",
68
70
  "vitest": "^4.0.15",
69
71
  "zimmerframe": "^1.1.4",
70
72
  "zod": "^4.3.6"
@@ -36,7 +36,7 @@ export const create_changeset_for_dependency_updates = async (
36
36
  const changesets_dir = join(repo.repo_dir, '.changeset');
37
37
 
38
38
  // Ensure .changeset directory exists
39
- if (!fs_ops.exists({path: changesets_dir})) {
39
+ if (!(await fs_ops.exists({path: changesets_dir}))) {
40
40
  const mkdir_result = await fs_ops.mkdir({path: changesets_dir, recursive: true});
41
41
  if (!mkdir_result.ok) {
42
42
  throw new Error(`Failed to create .changeset directory: ${mkdir_result.message}`);
@@ -95,10 +95,10 @@ const calculate_required_bump = (
95
95
  * and categorized list of breaking vs regular updates. Output format
96
96
  * matches changesets CLI for consistency.
97
97
  *
98
- * @param package_name package receiving the dependency updates
99
- * @param updates list of dependency changes with version info
100
- * @param bump_type required bump type (calculated from breaking changes)
101
- * @returns markdown content ready to write to .changeset/*.md file
98
+ * @param package_name - package receiving the dependency updates
99
+ * @param updates - list of dependency changes with version info
100
+ * @param bump_type - required bump type (calculated from breaking changes)
101
+ * @returns markdown content ready to write to `.changeset/*.md` file
102
102
  */
103
103
  export const generate_changeset_content = (
104
104
  package_name: string,
@@ -30,15 +30,17 @@ export interface ChangesetInfo {
30
30
  * Returns null if format is invalid or no packages found.
31
31
  *
32
32
  * Expected format:
33
+ * ```
33
34
  * ---
34
35
  * "package-name": patch
35
36
  * "@scope/package": minor
36
37
  * ---
37
38
  *
38
39
  * Summary of changes
40
+ * ```
39
41
  *
40
- * @param content changeset markdown with YAML frontmatter
41
- * @param filename optional filename for error reporting context
42
+ * @param content - changeset markdown with YAML frontmatter
43
+ * @param filename - optional filename for error reporting context
42
44
  * @returns parsed changeset info or null if invalid format
43
45
  */
44
46
  export const parse_changeset_content = (
@@ -116,7 +118,7 @@ export const read_changesets = async (
116
118
 
117
119
  for (const file of changeset_files) {
118
120
  const filepath = join(changesets_dir, file);
119
- const changeset = await parse_changeset_file(filepath, log); // eslint-disable-line no-await-in-loop
121
+ const changeset = await parse_changeset_file(filepath, log);
120
122
  if (changeset) {
121
123
  changesets.push(changeset);
122
124
  }
@@ -161,8 +163,8 @@ export const determine_bump_from_changesets = (
161
163
  * Checks if a repo has any changeset files (excluding README.md).
162
164
  *
163
165
  * Used by preflight checks and publishing workflow to determine which packages
164
- * need to be published. Returns false if .changeset directory doesn't exist
165
- * or contains only README.md.
166
+ * need to be published. Returns false if `.changeset` directory doesn't exist
167
+ * or contains only `README.md`.
166
168
  *
167
169
  * @returns true if repo has unpublished changesets
168
170
  */
@@ -127,8 +127,8 @@ export class DependencyGraph {
127
127
  * Delegates to `@fuzdev/fuz_util/sort.js` for the sorting algorithm.
128
128
  * Throws if cycles detected.
129
129
  *
130
- * @param exclude_dev if true, excludes dev dependencies to break cycles.
131
- * Publishing uses exclude_dev=true to handle circular dev deps.
130
+ * @param exclude_dev - if true, excludes dev dependencies to break cycles
131
+ * Publishing uses `exclude_dev`=true to handle circular dev deps.
132
132
  * @returns array of package names in dependency order (dependencies before dependents)
133
133
  * @throws {Error} if circular dependencies detected in included dependency types
134
134
  */
@@ -158,7 +158,7 @@ export class DependencyGraph {
158
158
  * Uses DFS traversal with recursion stack to identify back edges.
159
159
  * Deduplicates cycles using sorted cycle keys.
160
160
  *
161
- * @returns object with production_cycles (errors) and dev_cycles (info)
161
+ * @returns object with `production_cycles` (errors) and `dev_cycles` (info)
162
162
  */
163
163
  detect_cycles_by_type(): {
164
164
  production_cycles: Array<Array<string>>;
@@ -22,13 +22,13 @@ export interface UpdatePackageJsonOptions {
22
22
  }
23
23
 
24
24
  /**
25
- * Updates package.json dependencies and creates changeset if needed.
25
+ * Updates `package.json` dependencies and creates changeset if needed.
26
26
  *
27
27
  * Workflow:
28
28
  * 1. Updates all dependency types (dependencies, devDependencies, peerDependencies)
29
- * 2. Writes updated package.json with tabs formatting
30
- * 3. Creates auto-changeset if published_versions provided (for transitive updates)
31
- * 4. Commits both package.json and changeset with standard message
29
+ * 2. Writes updated `package.json` with tabs formatting
30
+ * 3. Creates auto-changeset if `published_versions` provided (for transitive updates)
31
+ * 4. Commits both `package.json` and changeset with standard message
32
32
  *
33
33
  * Uses version strategy to determine prefix (exact, caret, tilde) while preserving
34
34
  * existing prefixes when possible.
@@ -226,7 +226,7 @@ export const update_all_repos = async (
226
226
  if (updates.size === 0) continue;
227
227
 
228
228
  try {
229
- await update_package_json(repo, updates, {strategy, log, git_ops, fs_ops}); // eslint-disable-line no-await-in-loop
229
+ await update_package_json(repo, updates, {strategy, log, git_ops, fs_ops});
230
230
  updated_count++;
231
231
  log?.info(` Updated ${updates.size} dependencies in ${repo.library.name}`);
232
232
  } catch (error) {