@fuzdev/fuz_gitops 0.77.0 → 0.78.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 (94) hide show
  1. package/README.md +5 -5
  2. package/dist/ModulesDetail.svelte +1 -1
  3. package/dist/PageFooter.svelte +2 -2
  4. package/dist/PageHeader.svelte +1 -1
  5. package/dist/PageHeader.svelte.d.ts +1 -1
  6. package/dist/ReposTable.svelte +1 -1
  7. package/dist/ReposTree.svelte +1 -1
  8. package/dist/cargo_toml.d.ts +33 -0
  9. package/dist/cargo_toml.d.ts.map +1 -0
  10. package/dist/cargo_toml.js +74 -0
  11. package/dist/changeset_generator.d.ts +1 -1
  12. package/dist/changeset_reader.d.ts +1 -1
  13. package/dist/dependency_graph.d.ts +2 -2
  14. package/dist/dependency_graph.js +4 -4
  15. package/dist/dependency_updater.d.ts +1 -1
  16. package/dist/fetch_repo_data.d.ts +2 -2
  17. package/dist/fetch_repo_data.js +1 -1
  18. package/dist/fs_fetch_value_cache.d.ts +1 -1
  19. package/dist/fs_fetch_value_cache.js +3 -3
  20. package/dist/git_operations.d.ts +1 -1
  21. package/dist/git_operations.js +2 -2
  22. package/dist/github.d.ts +2 -2
  23. package/dist/github.js +1 -1
  24. package/dist/github_helpers.js +1 -1
  25. package/dist/gitops_analyze.task.d.ts.map +1 -1
  26. package/dist/gitops_analyze.task.js +15 -8
  27. package/dist/gitops_config.d.ts +2 -2
  28. package/dist/gitops_config.js +1 -1
  29. package/dist/gitops_run.task.js +2 -2
  30. package/dist/gitops_sync.task.js +4 -4
  31. package/dist/gitops_task_helpers.d.ts +1 -1
  32. package/dist/gitops_task_helpers.js +1 -1
  33. package/dist/graph_validation.d.ts +2 -2
  34. package/dist/graph_validation.d.ts.map +1 -1
  35. package/dist/graph_validation.js +3 -1
  36. package/dist/local_repo.d.ts +17 -3
  37. package/dist/local_repo.d.ts.map +1 -1
  38. package/dist/local_repo.js +54 -6
  39. package/dist/log_helpers.d.ts +1 -1
  40. package/dist/multi_repo_publisher.d.ts +3 -3
  41. package/dist/multi_repo_publisher.d.ts.map +1 -1
  42. package/dist/multi_repo_publisher.js +5 -1
  43. package/dist/npm_registry.d.ts +1 -1
  44. package/dist/npm_registry.js +2 -2
  45. package/dist/operations.d.ts +4 -4
  46. package/dist/operations_defaults.js +4 -4
  47. package/dist/output_helpers.d.ts +1 -1
  48. package/dist/preflight_checks.d.ts +1 -1
  49. package/dist/preflight_checks.js +1 -1
  50. package/dist/publish_steps.js +1 -1
  51. package/dist/publishing_plan.d.ts +3 -3
  52. package/dist/publishing_plan.d.ts.map +1 -1
  53. package/dist/publishing_plan.js +11 -1
  54. package/dist/publishing_plan_logging.d.ts +1 -1
  55. package/dist/repo.svelte.d.ts +5 -5
  56. package/dist/repo.svelte.js +2 -2
  57. package/package.json +6 -6
  58. package/src/lib/cargo_toml.ts +82 -0
  59. package/src/lib/changeset_generator.ts +6 -6
  60. package/src/lib/changeset_reader.ts +3 -3
  61. package/src/lib/config_reconcile.ts +1 -1
  62. package/src/lib/dependency_graph.ts +5 -5
  63. package/src/lib/dependency_updater.ts +7 -7
  64. package/src/lib/fetch_repo_data.ts +6 -6
  65. package/src/lib/fs_fetch_value_cache.ts +3 -3
  66. package/src/lib/git_operations.ts +2 -2
  67. package/src/lib/github.ts +2 -2
  68. package/src/lib/github_helpers.ts +3 -3
  69. package/src/lib/gitops_analyze.task.ts +26 -18
  70. package/src/lib/gitops_config.ts +4 -4
  71. package/src/lib/gitops_plan.task.ts +4 -4
  72. package/src/lib/gitops_publish.task.ts +9 -9
  73. package/src/lib/gitops_run.task.ts +4 -4
  74. package/src/lib/gitops_sync.task.ts +8 -8
  75. package/src/lib/gitops_task_helpers.ts +7 -7
  76. package/src/lib/gitops_validate.task.ts +7 -7
  77. package/src/lib/graph_validation.ts +5 -4
  78. package/src/lib/local_repo.ts +81 -15
  79. package/src/lib/log_helpers.ts +2 -2
  80. package/src/lib/multi_repo_publisher.ts +15 -11
  81. package/src/lib/npm_registry.ts +3 -3
  82. package/src/lib/operations.ts +9 -9
  83. package/src/lib/operations_defaults.ts +9 -9
  84. package/src/lib/output_helpers.ts +1 -1
  85. package/src/lib/preflight_checks.ts +6 -6
  86. package/src/lib/publish_gate.ts +2 -2
  87. package/src/lib/publish_steps.ts +3 -3
  88. package/src/lib/publishing_event_handler.ts +1 -1
  89. package/src/lib/publishing_plan.ts +22 -10
  90. package/src/lib/publishing_plan_helpers.ts +3 -3
  91. package/src/lib/publishing_plan_logging.ts +2 -2
  92. package/src/lib/repo.svelte.ts +7 -7
  93. package/src/lib/repo_ops.ts +3 -3
  94. package/src/lib/resolved_gitops_config.ts +2 -2
@@ -1,7 +1,7 @@
1
- import {ensure_end} from '@fuzdev/fuz_util/string.js';
1
+ import {ensure_end} from '@fuzdev/fuz_util/string.ts';
2
2
 
3
- import type {GithubPullRequest} from './github.js';
4
- import type {Repo} from './repo.svelte.js';
3
+ import type {GithubPullRequest} from './github.ts';
4
+ import type {Repo} from './repo.svelte.ts';
5
5
 
6
6
  export type FilterPullRequest = (pull_request: GithubPullRequest, repo: Repo) => boolean;
7
7
 
@@ -1,19 +1,19 @@
1
1
  import type {Task} from '@fuzdev/gro';
2
2
  import {z} from 'zod';
3
3
  import {styleText as st} from 'node:util';
4
- import type {Logger} from '@fuzdev/fuz_util/log.js';
4
+ import type {Logger} from '@fuzdev/fuz_util/log.ts';
5
5
 
6
- import {get_gitops_ready} from './gitops_task_helpers.js';
7
- import type {DependencyGraph} from './dependency_graph.js';
8
- import type {LocalRepo} from './local_repo.js';
9
- import {analyze_repos, type DependencyAnalysis} from './graph_validation.js';
6
+ import {get_gitops_ready} from './gitops_task_helpers.ts';
7
+ import type {DependencyGraph} from './dependency_graph.ts';
8
+ import {repo_is_npm} from './local_repo.ts';
9
+ import {analyze_repos, type DependencyAnalysis} from './graph_validation.ts';
10
10
  import {
11
11
  format_wildcard_dependencies,
12
12
  format_dev_cycles,
13
13
  format_production_cycles,
14
- } from './log_helpers.js';
15
- import {format_and_output, type OutputFormatters} from './output_helpers.js';
16
- import {GITOPS_CONFIG_PATH_DEFAULT} from './gitops_constants.js';
14
+ } from './log_helpers.ts';
15
+ import {format_and_output, type OutputFormatters} from './output_helpers.ts';
16
+ import {GITOPS_CONFIG_PATH_DEFAULT} from './gitops_constants.ts';
17
17
 
18
18
  /** @nodocs */
19
19
  export const Args = z.strictObject({
@@ -50,12 +50,24 @@ export const task: Task<Args> = {
50
50
  // Get repos ready (without downloading); read the working tree as-is unless `--sync`
51
51
  const {local_repos} = await get_gitops_ready({config, dir, download: false, sync, log});
52
52
 
53
+ // Only npm packages form the dependency graph; note any non-npm repos (e.g. cargo)
54
+ // that are excluded so the omission isn't silent.
55
+ const non_npm_repos = local_repos.filter((r) => !repo_is_npm(r));
56
+ if (non_npm_repos.length > 0) {
57
+ log.info(
58
+ st(
59
+ 'dim',
60
+ `excluding ${non_npm_repos.length} non-npm repo(s) from analysis (dashboard-only): ` +
61
+ non_npm_repos.map((r) => r.library.name).join(', '),
62
+ ),
63
+ );
64
+ }
65
+
53
66
  // Build the dependency graph and analyze cycles/wildcards (tolerating cycles)
54
67
  const {graph, analysis, publishing_order} = analyze_repos(local_repos);
55
68
 
56
69
  // Format and output using output_helpers
57
70
  const data = {
58
- repos: local_repos,
59
71
  graph,
60
72
  analysis,
61
73
  publishing_order,
@@ -67,7 +79,6 @@ export const task: Task<Args> = {
67
79
 
68
80
  // Data type for analysis output
69
81
  interface AnalysisData {
70
- repos: Array<LocalRepo>;
71
82
  graph: DependencyGraph;
72
83
  analysis: DependencyAnalysis;
73
84
  publishing_order: Array<string> | null;
@@ -76,9 +87,8 @@ interface AnalysisData {
76
87
  // Create formatters for output_helpers
77
88
  const create_formatters = (): OutputFormatters<AnalysisData> => ({
78
89
  json: (data) => format_json(data.graph, data.analysis, data.publishing_order),
79
- markdown: (data) => format_markdown(data.repos, data.graph, data.analysis, data.publishing_order),
80
- stdout: (data, log) =>
81
- format_stdout(data.repos, data.graph, data.analysis, data.publishing_order, log),
90
+ markdown: (data) => format_markdown(data.graph, data.analysis, data.publishing_order),
91
+ stdout: (data, log) => format_stdout(data.graph, data.analysis, data.publishing_order, log),
82
92
  });
83
93
 
84
94
  // Helper to calculate common statistics
@@ -109,7 +119,6 @@ const format_json = (
109
119
  };
110
120
 
111
121
  const format_markdown = (
112
- repos: Array<LocalRepo>,
113
122
  graph: DependencyGraph,
114
123
  analysis: DependencyAnalysis,
115
124
  publishing_order: Array<string> | null,
@@ -120,7 +129,7 @@ const format_markdown = (
120
129
  const {total_deps, internal_deps} = calculate_stats(graph);
121
130
 
122
131
  lines.push('', '## Summary', '');
123
- lines.push(`- **Total packages**: ${repos.length}`);
132
+ lines.push(`- **Total packages**: ${graph.nodes.size}`);
124
133
  lines.push(`- **Total dependencies**: ${total_deps}`);
125
134
  lines.push(`- **Internal dependencies**: ${internal_deps}`);
126
135
  lines.push(`- **Wildcard dependencies**: ${analysis.wildcard_deps.length}`);
@@ -185,13 +194,12 @@ const format_markdown = (
185
194
  };
186
195
 
187
196
  const format_stdout = (
188
- repos: Array<LocalRepo>,
189
197
  graph: DependencyGraph,
190
198
  analysis: DependencyAnalysis,
191
199
  publishing_order: Array<string> | null,
192
200
  log: Logger,
193
201
  ): void => {
194
- log.info(st('cyan', `📊 Analyzing ${repos.length} repositories...`));
202
+ log.info(st('cyan', `📊 Analyzing ${graph.nodes.size} repositories...`));
195
203
 
196
204
  // Publishing order
197
205
  if (publishing_order) {
@@ -248,7 +256,7 @@ const format_stdout = (
248
256
 
249
257
  log.info('');
250
258
  log.info(st('cyan', 'Summary:'));
251
- log.info(` Total packages: ${repos.length}`);
259
+ log.info(` Total packages: ${graph.nodes.size}`);
252
260
  log.info(` Total dependencies: ${total_deps}`);
253
261
  log.info(` Internal dependencies: ${internal_deps}`);
254
262
  log.info(` Wildcard dependencies: ${analysis.wildcard_deps.length}`);
@@ -11,12 +11,12 @@
11
11
  * @module
12
12
  */
13
13
 
14
- import type {Url} from '@fuzdev/fuz_util/url.js';
14
+ import type {Url} from '@fuzdev/fuz_util/url.ts';
15
15
  import {existsSync} from 'node:fs';
16
- import {strip_end} from '@fuzdev/fuz_util/string.js';
17
- import type {GitBranch} from '@fuzdev/fuz_util/git.js';
16
+ import {strip_end} from '@fuzdev/fuz_util/string.ts';
17
+ import type {GitBranch} from '@fuzdev/fuz_util/git.ts';
18
18
 
19
- import {DEFAULT_REPOS_DIR} from './paths.js';
19
+ import {DEFAULT_REPOS_DIR} from './paths.ts';
20
20
 
21
21
  export interface GitopsConfig {
22
22
  repos: Array<GitopsRepoConfig>;
@@ -2,15 +2,15 @@ import type {Task} from '@fuzdev/gro';
2
2
  import {z} from 'zod';
3
3
  import {styleText as st} from 'node:util';
4
4
 
5
- import {get_gitops_ready} from './gitops_task_helpers.js';
5
+ import {get_gitops_ready} from './gitops_task_helpers.ts';
6
6
  import {
7
7
  generate_publishing_plan,
8
8
  log_publishing_plan,
9
9
  type PublishingPlan,
10
10
  type LogPlanOptions,
11
- } from './publishing_plan.js';
12
- import {format_and_output, type OutputFormatters} from './output_helpers.js';
13
- import {GITOPS_CONFIG_PATH_DEFAULT} from './gitops_constants.js';
11
+ } from './publishing_plan.ts';
12
+ import {format_and_output, type OutputFormatters} from './output_helpers.ts';
13
+ import {GITOPS_CONFIG_PATH_DEFAULT} from './gitops_constants.ts';
14
14
 
15
15
  /** @nodocs */
16
16
  export const Args = z.strictObject({
@@ -1,21 +1,21 @@
1
1
  import type {Task} from '@fuzdev/gro';
2
- import type {Logger} from '@fuzdev/fuz_util/log.js';
2
+ import type {Logger} from '@fuzdev/fuz_util/log.ts';
3
3
  import {z} from 'zod';
4
4
  import {createInterface} from 'node:readline/promises';
5
5
  import {styleText as st} from 'node:util';
6
6
 
7
- import {get_gitops_ready} from './gitops_task_helpers.js';
7
+ import {get_gitops_ready} from './gitops_task_helpers.ts';
8
8
  import {
9
9
  execute_publishing_plan,
10
10
  type PublishingOptions,
11
11
  type PublishingResult,
12
- } from './multi_repo_publisher.js';
13
- import {stdout_handler} from './publishing_event_handler.js';
14
- import {generate_publishing_plan, log_publishing_plan} from './publishing_plan.js';
15
- import {derive_publish_steps, format_publish_steps, type PublishStep} from './publish_steps.js';
16
- import {decide_publish_gate, publish_run_failed} from './publish_gate.js';
17
- import {format_and_output, type OutputFormatters} from './output_helpers.js';
18
- import {GITOPS_CONFIG_PATH_DEFAULT, GITOPS_NPM_WAIT_TIMEOUT_DEFAULT} from './gitops_constants.js';
12
+ } from './multi_repo_publisher.ts';
13
+ import {stdout_handler} from './publishing_event_handler.ts';
14
+ import {generate_publishing_plan, log_publishing_plan} from './publishing_plan.ts';
15
+ import {derive_publish_steps, format_publish_steps, type PublishStep} from './publish_steps.ts';
16
+ import {decide_publish_gate, publish_run_failed} from './publish_gate.ts';
17
+ import {format_and_output, type OutputFormatters} from './output_helpers.ts';
18
+ import {GITOPS_CONFIG_PATH_DEFAULT, GITOPS_NPM_WAIT_TIMEOUT_DEFAULT} from './gitops_constants.ts';
19
19
 
20
20
  /** @nodocs */
21
21
  export const Args = z.strictObject({
@@ -1,13 +1,13 @@
1
1
  import {TaskError, type Task} from '@fuzdev/gro';
2
2
  import {z} from 'zod';
3
- import {map_concurrent_settled} from '@fuzdev/fuz_util/async.js';
4
- import {spawn_out} from '@fuzdev/fuz_util/process.js';
3
+ import {map_concurrent_settled} from '@fuzdev/fuz_util/async.ts';
4
+ import {spawn_out} from '@fuzdev/fuz_util/process.ts';
5
5
  import {writeFile} from 'node:fs/promises';
6
6
  import {styleText as st} from 'node:util';
7
7
  import {resolve} from 'node:path';
8
8
 
9
- import {get_repo_paths} from './repo_ops.js';
10
- import {GITOPS_CONCURRENCY_DEFAULT, GITOPS_CONFIG_PATH_DEFAULT} from './gitops_constants.js';
9
+ import {get_repo_paths} from './repo_ops.ts';
10
+ import {GITOPS_CONCURRENCY_DEFAULT, GITOPS_CONFIG_PATH_DEFAULT} from './gitops_constants.ts';
11
11
 
12
12
  export const Args = z.strictObject({
13
13
  // Positional rest args (gro convention) so `gro gitops_run "npm test"` works;
@@ -1,18 +1,18 @@
1
1
  import {TaskError, type Task} from '@fuzdev/gro';
2
2
  import {z} from 'zod';
3
3
  import {readFile, writeFile} from 'node:fs/promises';
4
- import {format_file} from '@fuzdev/gro/format_file.js';
4
+ import {format_file} from '@fuzdev/gro/format_file.ts';
5
5
  import {basename, resolve} from 'node:path';
6
- import {print_path} from '@fuzdev/gro/paths.js';
7
- import {load_from_env} from '@fuzdev/gro/env.js';
8
- import {package_json_load} from '@fuzdev/gro/package_json.js';
6
+ import {print_path} from '@fuzdev/gro/paths.ts';
7
+ import {load_from_env} from '@fuzdev/gro/env.ts';
8
+ import {package_json_load} from '@fuzdev/gro/package_json.ts';
9
9
  import {existsSync} from 'node:fs';
10
10
  import {compactReplacer} from 'svelte-docinfo';
11
11
 
12
- import {fetch_repo_data} from './fetch_repo_data.js';
13
- import {create_fs_fetch_value_cache} from './fs_fetch_value_cache.js';
14
- import {get_gitops_ready} from './gitops_task_helpers.js';
15
- import {GITOPS_CONFIG_PATH_DEFAULT} from './gitops_constants.js';
12
+ import {fetch_repo_data} from './fetch_repo_data.ts';
13
+ import {create_fs_fetch_value_cache} from './fs_fetch_value_cache.ts';
14
+ import {get_gitops_ready} from './gitops_task_helpers.ts';
15
+ import {GITOPS_CONFIG_PATH_DEFAULT} from './gitops_constants.ts';
16
16
 
17
17
  // TODO add flag to ignore or invalidate cache -- no-cache? clean?
18
18
 
@@ -19,14 +19,14 @@
19
19
  import {TaskError} from '@fuzdev/gro';
20
20
  import {styleText as st} from 'node:util';
21
21
  import {resolve, dirname} from 'node:path';
22
- import {print_path} from '@fuzdev/gro/paths.js';
23
- import type {Logger} from '@fuzdev/fuz_util/log.js';
22
+ import {print_path} from '@fuzdev/gro/paths.ts';
23
+ import type {Logger} from '@fuzdev/fuz_util/log.ts';
24
24
 
25
- import {load_gitops_config, type GitopsConfig} from './gitops_config.js';
26
- import {local_repos_load, local_repos_ensure, type LocalRepo} from './local_repo.js';
27
- import {resolve_gitops_config} from './resolved_gitops_config.js';
28
- import {DEFAULT_REPOS_DIR} from './paths.js';
29
- import type {GitOperations, NpmOperations} from './operations.js';
25
+ import {load_gitops_config, type GitopsConfig} from './gitops_config.ts';
26
+ import {local_repos_load, local_repos_ensure, type LocalRepo} from './local_repo.ts';
27
+ import {resolve_gitops_config} from './resolved_gitops_config.ts';
28
+ import {DEFAULT_REPOS_DIR} from './paths.ts';
29
+ import type {GitOperations, NpmOperations} from './operations.ts';
30
30
 
31
31
  export interface GetGitopsReadyOptions {
32
32
  config: string;
@@ -2,17 +2,17 @@ import type {Task} from '@fuzdev/gro';
2
2
  import {z} from 'zod';
3
3
  import {styleText as st} from 'node:util';
4
4
 
5
- import {get_gitops_ready} from './gitops_task_helpers.js';
6
- import {analyze_repos, type DependencyAnalysis} from './graph_validation.js';
5
+ import {get_gitops_ready} from './gitops_task_helpers.ts';
6
+ import {analyze_repos, type DependencyAnalysis} from './graph_validation.ts';
7
7
  import {
8
8
  generate_publishing_plan,
9
9
  log_publishing_plan,
10
10
  type PublishingPlan,
11
- } from './publishing_plan.js';
12
- import {execute_publishing_plan, type PublishingOptions} from './multi_repo_publisher.js';
13
- import {log_dependency_analysis} from './log_helpers.js';
14
- import {GITOPS_CONFIG_PATH_DEFAULT} from './gitops_constants.js';
15
- import {reconcile_ci, repo_has_workflows} from './ci_reconcile.js';
11
+ } from './publishing_plan.ts';
12
+ import {execute_publishing_plan, type PublishingOptions} from './multi_repo_publisher.ts';
13
+ import {log_dependency_analysis} from './log_helpers.ts';
14
+ import {GITOPS_CONFIG_PATH_DEFAULT} from './gitops_constants.ts';
15
+ import {reconcile_ci, repo_has_workflows} from './ci_reconcile.ts';
16
16
 
17
17
  /** @nodocs */
18
18
  export const Args = z.strictObject({
@@ -13,12 +13,12 @@
13
13
  * @module
14
14
  */
15
15
 
16
- import type {Logger} from '@fuzdev/fuz_util/log.js';
16
+ import type {Logger} from '@fuzdev/fuz_util/log.ts';
17
17
  import {TaskError} from '@fuzdev/gro';
18
18
  import {styleText as st} from 'node:util';
19
19
 
20
- import {DependencyGraph, DependencyGraphBuilder} from './dependency_graph.js';
21
- import type {LocalRepo} from './local_repo.js';
20
+ import {DependencyGraph, DependencyGraphBuilder} from './dependency_graph.ts';
21
+ import {repo_is_npm, type LocalRepo} from './local_repo.ts';
22
22
 
23
23
  export interface GraphValidationResult {
24
24
  graph: DependencyGraph;
@@ -127,7 +127,8 @@ export interface RepoAnalysis {
127
127
  * (no `log`) to avoid emitting a redundant "Analyzing dependencies" line.
128
128
  */
129
129
  export const analyze_repos = (repos: Array<LocalRepo>): RepoAnalysis => {
130
- const {graph, publishing_order: order} = validate_dependency_graph(repos, {
130
+ // Only npm packages form the dependency graph; non-npm repos (e.g. cargo) are excluded.
131
+ const {graph, publishing_order: order} = validate_dependency_graph(repos.filter(repo_is_npm), {
131
132
  throw_on_prod_cycles: false, // report, don't throw
132
133
  log_cycles: false, // callers format their own cycle output
133
134
  log_order: false,
@@ -1,26 +1,36 @@
1
- import {strip_end} from '@fuzdev/fuz_util/string.js';
2
- import type {LibraryJson} from '@fuzdev/fuz_util/library_json.js';
3
- import type {PackageJson} from '@fuzdev/fuz_util/package_json.js';
4
- import {Library} from '@fuzdev/fuz_ui/library.svelte.js';
1
+ import {strip_end} from '@fuzdev/fuz_util/string.ts';
2
+ import {to_error_message} from '@fuzdev/fuz_util/error.ts';
3
+ import {library_json_from_modules, type LibraryJson} from '@fuzdev/fuz_util/library_json.ts';
4
+ import type {PackageJson} from '@fuzdev/fuz_util/package_json.ts';
5
+ import {Library} from '@fuzdev/fuz_ui/library.svelte.ts';
5
6
  import {existsSync} from 'node:fs';
6
7
  import {join} from 'node:path';
7
8
  import {TaskError} from '@fuzdev/gro';
8
- import {library_load_from_repo} from '@fuzdev/gro/library_load.js';
9
- import type {Logger} from '@fuzdev/fuz_util/log.js';
10
- import {spawn_out} from '@fuzdev/fuz_util/process.js';
11
- import {map_concurrent_settled} from '@fuzdev/fuz_util/async.js';
12
- import type {GitOperations, NpmOperations} from './operations.js';
13
- import {default_git_operations, default_npm_operations} from './operations_defaults.js';
14
-
15
- import type {GitopsConfig, GitopsRepoConfig} from './gitops_config.js';
16
- import type {ResolvedGitopsConfig} from './resolved_gitops_config.js';
17
- import {GITOPS_CONCURRENCY_DEFAULT} from './gitops_constants.js';
9
+ import {library_load_from_repo} from '@fuzdev/gro/library_load.ts';
10
+ import type {Logger} from '@fuzdev/fuz_util/log.ts';
11
+ import {spawn_out} from '@fuzdev/fuz_util/process.ts';
12
+ import {map_concurrent_settled} from '@fuzdev/fuz_util/async.ts';
13
+ import type {GitOperations, NpmOperations} from './operations.ts';
14
+ import {default_git_operations, default_npm_operations} from './operations_defaults.ts';
15
+
16
+ import type {GitopsConfig, GitopsRepoConfig} from './gitops_config.ts';
17
+ import type {ResolvedGitopsConfig} from './resolved_gitops_config.ts';
18
+ import {GITOPS_CONCURRENCY_DEFAULT} from './gitops_constants.ts';
19
+ import {cargo_toml_load} from './cargo_toml.ts';
18
20
 
19
21
  /**
20
22
  * Fully loaded local repo with `Library` and extracted dependency data.
21
23
  * Does not extend `LocalRepoPath` - `Library` is source of truth for name/repo_url/etc.
22
24
  */
23
25
  export interface LocalRepo {
26
+ /**
27
+ * Which packaging ecosystem the repo belongs to. `npm` repos (with a
28
+ * `package.json`) take part in the changeset publishing cascade; `cargo` repos
29
+ * (a Rust `Cargo.toml`, no `package.json`) are dashboard-only — fetched and
30
+ * rendered like any repo but excluded from publishing/analysis. See
31
+ * `repo_is_npm`.
32
+ */
33
+ kind: 'npm' | 'cargo';
24
34
  library: Library;
25
35
  /** The repo's full `package.json` (with `dependencies`/`devDependencies`). */
26
36
  package_json: PackageJson;
@@ -210,13 +220,21 @@ export const local_repo_load = async ({
210
220
  }
211
221
  }
212
222
 
223
+ // A repo with no `package.json` but a Rust `Cargo.toml` isn't an npm package and can't be
224
+ // analyzed as a library. Load it as a dashboard-only `cargo` repo (CI, PRs, identity) that
225
+ // publishing/analysis skips. Anything else falls through to the npm loader below, whose
226
+ // error covers a genuinely missing or unreadable manifest.
227
+ if (!existsSync(join(repo_dir, 'package.json')) && existsSync(join(repo_dir, 'Cargo.toml'))) {
228
+ return local_repo_load_cargo({local_repo_path});
229
+ }
230
+
213
231
  // Load library metadata via svelte-docinfo analysis (cached under `.gro/library.json`).
214
232
  let library_json: LibraryJson;
215
233
  let package_json: PackageJson;
216
234
  try {
217
235
  ({library_json, package_json} = await library_load_from_repo(repo_dir, {log: _log}));
218
236
  } catch (err) {
219
- const message = err instanceof Error ? err.message : String(err);
237
+ const message = to_error_message(err);
220
238
  _log?.warn(
221
239
  `Failed to load library metadata for repo "${repo_name}" in ${repo_dir}: ${message}`,
222
240
  );
@@ -227,6 +245,7 @@ export const local_repo_load = async ({
227
245
  const library = new Library(library_json);
228
246
 
229
247
  const local_repo: LocalRepo = {
248
+ kind: 'npm',
230
249
  library,
231
250
  package_json,
232
251
  repo_dir,
@@ -248,6 +267,53 @@ export const local_repo_load = async ({
248
267
  return local_repo;
249
268
  };
250
269
 
270
+ /**
271
+ * Whether a repo is an npm package and so participates in publishing and
272
+ * dependency analysis. Non-npm repos (e.g. Rust `cargo` repos) are still synced
273
+ * and rendered on the dashboard, but excluded from the changeset cascade.
274
+ */
275
+ export const repo_is_npm = (repo: LocalRepo): boolean => repo.kind === 'npm';
276
+
277
+ /**
278
+ * Loads a non-npm Rust repo as a dashboard-only `LocalRepo`. It has no
279
+ * `package.json`, so there's no `svelte-docinfo` analysis and no npm dependency
280
+ * graph — a lightweight `Library` is synthesized from the repo's `Cargo.toml`
281
+ * (best-effort name/version/description) and its configured repo URL, which is
282
+ * what the dashboard renders (CI status, PRs, identity). Marked `private` so it
283
+ * never reads as an npm publish target, and tagged `cargo` so the publishing and
284
+ * analysis paths skip it (see `repo_is_npm`).
285
+ */
286
+ const local_repo_load_cargo = async ({
287
+ local_repo_path,
288
+ }: {
289
+ local_repo_path: LocalRepoPath;
290
+ }): Promise<LocalRepo> => {
291
+ const {repo_config, repo_dir, repo_name, repo_url, repo_git_ssh_url} = local_repo_path;
292
+
293
+ const cargo = await cargo_toml_load(repo_dir);
294
+
295
+ // A Cargo workspace root has no `name`, so fall back to the repo name parsed from
296
+ // the URL; the config's `repo_url` is the authoritative `repository`.
297
+ const package_json: PackageJson = {
298
+ name: cargo?.name ?? repo_name,
299
+ version: cargo?.version ?? '0.0.0',
300
+ repository: cargo?.repository ?? repo_url,
301
+ private: true,
302
+ ...(cargo?.description ? {description: cargo.description} : null),
303
+ };
304
+
305
+ const library = new Library(library_json_from_modules(package_json, []));
306
+
307
+ return {
308
+ kind: 'cargo',
309
+ library,
310
+ package_json,
311
+ repo_dir,
312
+ repo_git_ssh_url,
313
+ repo_config,
314
+ };
315
+ };
316
+
251
317
  export const local_repos_ensure = async ({
252
318
  resolved_config,
253
319
  repos_dir,
@@ -1,7 +1,7 @@
1
- import type {Logger} from '@fuzdev/fuz_util/log.js';
1
+ import type {Logger} from '@fuzdev/fuz_util/log.ts';
2
2
  import {styleText as st} from 'node:util';
3
3
 
4
- import type {DependencyGraphBuilder} from './dependency_graph.js';
4
+ import type {DependencyGraphBuilder} from './dependency_graph.ts';
5
5
 
6
6
  /**
7
7
  * Formats wildcard dependencies as styled strings.
@@ -1,30 +1,30 @@
1
- import type {Logger} from '@fuzdev/fuz_util/log.js';
1
+ import type {Logger} from '@fuzdev/fuz_util/log.ts';
2
2
  import {TaskError} from '@fuzdev/gro';
3
3
  import {join} from 'node:path';
4
4
  import {styleText as st} from 'node:util';
5
5
 
6
- import type {LocalRepo} from './local_repo.js';
7
- import {update_package_json, type VersionStrategy} from './dependency_updater.js';
6
+ import {repo_is_npm, type LocalRepo} from './local_repo.ts';
7
+ import {update_package_json, type VersionStrategy} from './dependency_updater.ts';
8
8
  import {
9
9
  generate_publishing_plan,
10
10
  type VersionChange,
11
11
  type DependencyUpdate,
12
12
  type PublishingPlan,
13
- } from './publishing_plan.js';
14
- import type {PreflightOptions} from './preflight_checks.js';
15
- import type {GitopsOperations} from './operations.js';
16
- import {default_gitops_operations} from './operations_defaults.js';
17
- import {GITOPS_NPM_WAIT_TIMEOUT_DEFAULT} from './gitops_constants.js';
13
+ } from './publishing_plan.ts';
14
+ import type {PreflightOptions} from './preflight_checks.ts';
15
+ import type {GitopsOperations} from './operations.ts';
16
+ import {default_gitops_operations} from './operations_defaults.ts';
17
+ import {GITOPS_NPM_WAIT_TIMEOUT_DEFAULT} from './gitops_constants.ts';
18
18
  import {
19
19
  type PublishingEvent,
20
20
  type PublishingRunSummary,
21
21
  summarize_events,
22
- } from './publishing_event.js';
22
+ } from './publishing_event.ts';
23
23
  import {
24
24
  type PublishingEventHandler,
25
25
  capture_handler,
26
26
  multi_handler,
27
- } from './publishing_event_handler.js';
27
+ } from './publishing_event_handler.ts';
28
28
 
29
29
  export interface PublishingOptions {
30
30
  wetrun: boolean;
@@ -83,13 +83,17 @@ export const publish_repos = async (
83
83
  * `ok: false`. This is the single error gate — `--no-plan` can't bypass it.
84
84
  */
85
85
  export const execute_publishing_plan = async (
86
- repos: Array<LocalRepo>,
86
+ all_repos: Array<LocalRepo>,
87
87
  plan: PublishingPlan,
88
88
  options: PublishingOptions,
89
89
  ): Promise<PublishingResult> => {
90
90
  const start_time = Date.now();
91
91
  const {wetrun, log, ops = default_gitops_operations} = options;
92
92
 
93
+ // Only npm repos publish; drop any non-npm repos (e.g. cargo) so preflight and the
94
+ // executor's name lookup never touch them. The plan already excludes them too.
95
+ const repos = all_repos.filter(repo_is_npm);
96
+
93
97
  // Fail loud on an incomplete plan. Executing one with errors would silently skip the
94
98
  // affected packages. A wetrun aborts before touching npm or git; a dry run proceeds
95
99
  // (no side effects) but the result is not ok (see the summary below).
@@ -1,6 +1,6 @@
1
- import type {Logger} from '@fuzdev/fuz_util/log.js';
2
- import {spawn_out} from '@fuzdev/fuz_util/process.js';
3
- import {wait} from '@fuzdev/fuz_util/async.js';
1
+ import type {Logger} from '@fuzdev/fuz_util/log.ts';
2
+ import {spawn_out} from '@fuzdev/fuz_util/process.ts';
3
+ import {wait} from '@fuzdev/fuz_util/async.ts';
4
4
  import {styleText as st} from 'node:util';
5
5
 
6
6
  export interface WaitOptions {
@@ -34,14 +34,14 @@
34
34
  * @module
35
35
  */
36
36
 
37
- import type {Result} from '@fuzdev/fuz_util/result.js';
38
- import type {FsError} from '@fuzdev/fuz_util/fs.js';
39
- import type {Logger} from '@fuzdev/fuz_util/log.js';
40
- import type {LocalRepo} from './local_repo.js';
41
- import type {ChangesetInfo} from './changeset_reader.js';
42
- import type {BumpType} from './version_utils.js';
43
- import type {PreflightOptions, PreflightResult} from './preflight_checks.js';
44
- import type {WaitOptions} from './npm_registry.js';
37
+ import type {Result} from '@fuzdev/fuz_util/result.ts';
38
+ import type {FsError} from '@fuzdev/fuz_util/fs.ts';
39
+ import type {Logger} from '@fuzdev/fuz_util/log.ts';
40
+ import type {LocalRepo} from './local_repo.ts';
41
+ import type {ChangesetInfo} from './changeset_reader.ts';
42
+ import type {BumpType} from './version_utils.ts';
43
+ import type {PreflightOptions, PreflightResult} from './preflight_checks.ts';
44
+ import type {WaitOptions} from './npm_registry.ts';
45
45
 
46
46
  /**
47
47
  * Changeset operations for reading and predicting versions from `.changeset/*.md` files.
@@ -293,7 +293,7 @@ export interface PreflightOperations {
293
293
  *
294
294
  * Errors are typed via `FsError` (`not_found | permission_denied |
295
295
  * already_exists | io_error`) so callers can branch on `kind` instead of
296
- * regex-matching `message`. See `@fuzdev/fuz_util/fs.js`.
296
+ * regex-matching `message`. See `@fuzdev/fuz_util/fs.ts`.
297
297
  */
298
298
  export interface FsOperations {
299
299
  /**
@@ -7,15 +7,15 @@
7
7
  * @module
8
8
  */
9
9
 
10
- import {spawn_out} from '@fuzdev/fuz_util/process.js';
10
+ import {spawn_out} from '@fuzdev/fuz_util/process.ts';
11
11
  import {readFile, writeFile, mkdir, stat} from 'node:fs/promises';
12
- import {git_checkout, type GitBranch, type GitOrigin} from '@fuzdev/fuz_util/git.js';
13
- import {fs_classify_error} from '@fuzdev/fuz_util/fs.js';
14
- import {EMPTY_OBJECT} from '@fuzdev/fuz_util/object.js';
12
+ import {git_checkout, type GitBranch, type GitOrigin} from '@fuzdev/fuz_util/git.ts';
13
+ import {fs_classify_error} from '@fuzdev/fuz_util/fs.ts';
14
+ import {EMPTY_OBJECT} from '@fuzdev/fuz_util/object.ts';
15
15
 
16
- import {has_changesets, read_changesets, predict_next_version} from './changeset_reader.js';
17
- import {wait_for_package} from './npm_registry.js';
18
- import {run_preflight_checks} from './preflight_checks.js';
16
+ import {has_changesets, read_changesets, predict_next_version} from './changeset_reader.ts';
17
+ import {wait_for_package} from './npm_registry.ts';
18
+ import {run_preflight_checks} from './preflight_checks.ts';
19
19
  import {
20
20
  git_add,
21
21
  git_commit,
@@ -32,7 +32,7 @@ import {
32
32
  git_current_commit_hash_required,
33
33
  git_check_clean_workspace_as_boolean,
34
34
  git_has_remote,
35
- } from './git_operations.js';
35
+ } from './git_operations.ts';
36
36
  import type {
37
37
  ChangesetOperations,
38
38
  GitOperations,
@@ -42,7 +42,7 @@ import type {
42
42
  FsOperations,
43
43
  BuildOperations,
44
44
  GitopsOperations,
45
- } from './operations.js';
45
+ } from './operations.ts';
46
46
 
47
47
  /** Wrap an async function that returns a value */
48
48
  const wrap_with_value = async <T>(
@@ -1,4 +1,4 @@
1
- import type {Logger} from '@fuzdev/fuz_util/log.js';
1
+ import type {Logger} from '@fuzdev/fuz_util/log.ts';
2
2
  import {writeFile} from 'node:fs/promises';
3
3
 
4
4
  export type OutputFormat = 'stdout' | 'json' | 'markdown';
@@ -1,21 +1,21 @@
1
- import type {Logger} from '@fuzdev/fuz_util/log.js';
2
- import type {Result} from '@fuzdev/fuz_util/result.js';
3
- import {spawn_out} from '@fuzdev/fuz_util/process.js';
1
+ import type {Logger} from '@fuzdev/fuz_util/log.ts';
2
+ import type {Result} from '@fuzdev/fuz_util/result.ts';
3
+ import {spawn_out} from '@fuzdev/fuz_util/process.ts';
4
4
  import {styleText as st} from 'node:util';
5
5
 
6
- import type {LocalRepo} from './local_repo.js';
6
+ import type {LocalRepo} from './local_repo.ts';
7
7
  import type {
8
8
  GitOperations,
9
9
  NpmOperations,
10
10
  BuildOperations,
11
11
  ChangesetOperations,
12
- } from './operations.js';
12
+ } from './operations.ts';
13
13
  import {
14
14
  default_git_operations,
15
15
  default_npm_operations,
16
16
  default_build_operations,
17
17
  default_changeset_operations,
18
- } from './operations_defaults.js';
18
+ } from './operations_defaults.ts';
19
19
 
20
20
  export interface PreflightOptions {
21
21
  skip_changesets?: boolean;