@fuzdev/fuz_gitops 0.77.0 → 0.78.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 (162) hide show
  1. package/README.md +25 -5
  2. package/dist/ModulesDetail.svelte +14 -12
  3. package/dist/ModulesDetail.svelte.d.ts.map +1 -1
  4. package/dist/ModulesNav.svelte +6 -6
  5. package/dist/ModulesNav.svelte.d.ts.map +1 -1
  6. package/dist/ModulesPage.svelte +2 -2
  7. package/dist/ModulesPage.svelte.d.ts.map +1 -1
  8. package/dist/PageFooter.svelte +2 -2
  9. package/dist/PageHeader.svelte +5 -5
  10. package/dist/PageHeader.svelte.d.ts +1 -1
  11. package/dist/PageHeader.svelte.d.ts.map +1 -1
  12. package/dist/PullRequestsDetail.svelte +25 -17
  13. package/dist/PullRequestsDetail.svelte.d.ts.map +1 -1
  14. package/dist/PullRequestsPage.svelte +3 -3
  15. package/dist/PullRequestsPage.svelte.d.ts.map +1 -1
  16. package/dist/ReposTable.svelte +24 -15
  17. package/dist/ReposTable.svelte.d.ts.map +1 -1
  18. package/dist/ReposTree.svelte +8 -6
  19. package/dist/ReposTree.svelte.d.ts.map +1 -1
  20. package/dist/ReposTreeNav.svelte +10 -11
  21. package/dist/ReposTreeNav.svelte.d.ts.map +1 -1
  22. package/dist/TablePage.svelte +2 -2
  23. package/dist/TablePage.svelte.d.ts.map +1 -1
  24. package/dist/TreeItemPage.svelte +2 -2
  25. package/dist/TreeItemPage.svelte.d.ts.map +1 -1
  26. package/dist/TreePage.svelte +2 -2
  27. package/dist/TreePage.svelte.d.ts.map +1 -1
  28. package/dist/cargo_toml.d.ts +33 -0
  29. package/dist/cargo_toml.d.ts.map +1 -0
  30. package/dist/cargo_toml.js +74 -0
  31. package/dist/changeset_generator.d.ts +1 -1
  32. package/dist/changeset_generator.d.ts.map +1 -1
  33. package/dist/changeset_generator.js +2 -2
  34. package/dist/changeset_reader.d.ts +1 -1
  35. package/dist/changeset_reader.d.ts.map +1 -1
  36. package/dist/changeset_reader.js +3 -3
  37. package/dist/config_reconcile.d.ts.map +1 -1
  38. package/dist/config_reconcile.js +6 -2
  39. package/dist/dependency_graph.d.ts +2 -2
  40. package/dist/dependency_graph.d.ts.map +1 -1
  41. package/dist/dependency_graph.js +9 -9
  42. package/dist/dependency_updater.d.ts +1 -1
  43. package/dist/dependency_updater.d.ts.map +1 -1
  44. package/dist/dependency_updater.js +8 -8
  45. package/dist/fetch_repo_data.d.ts +2 -2
  46. package/dist/fetch_repo_data.d.ts.map +1 -1
  47. package/dist/fetch_repo_data.js +4 -4
  48. package/dist/fs_fetch_value_cache.d.ts +1 -1
  49. package/dist/fs_fetch_value_cache.d.ts.map +1 -1
  50. package/dist/fs_fetch_value_cache.js +5 -5
  51. package/dist/git_operations.d.ts +1 -1
  52. package/dist/git_operations.d.ts.map +1 -1
  53. package/dist/git_operations.js +2 -2
  54. package/dist/github.d.ts +2 -2
  55. package/dist/github.d.ts.map +1 -1
  56. package/dist/github.js +7 -7
  57. package/dist/github_helpers.d.ts.map +1 -1
  58. package/dist/github_helpers.js +1 -1
  59. package/dist/gitops_analyze.task.d.ts.map +1 -1
  60. package/dist/gitops_analyze.task.js +21 -14
  61. package/dist/gitops_config.d.ts +2 -2
  62. package/dist/gitops_config.d.ts.map +1 -1
  63. package/dist/gitops_config.js +5 -5
  64. package/dist/gitops_plan.task.d.ts.map +1 -1
  65. package/dist/gitops_plan.task.js +8 -8
  66. package/dist/gitops_publish.task.d.ts.map +1 -1
  67. package/dist/gitops_publish.task.js +15 -12
  68. package/dist/gitops_run.task.d.ts.map +1 -1
  69. package/dist/gitops_run.task.js +10 -10
  70. package/dist/gitops_sync.task.d.ts.map +1 -1
  71. package/dist/gitops_sync.task.js +15 -13
  72. package/dist/gitops_task_helpers.d.ts +1 -1
  73. package/dist/gitops_task_helpers.d.ts.map +1 -1
  74. package/dist/gitops_task_helpers.js +4 -4
  75. package/dist/gitops_validate.task.d.ts.map +1 -1
  76. package/dist/gitops_validate.task.js +14 -14
  77. package/dist/graph_validation.d.ts +2 -2
  78. package/dist/graph_validation.d.ts.map +1 -1
  79. package/dist/graph_validation.js +5 -3
  80. package/dist/local_repo.d.ts +21 -7
  81. package/dist/local_repo.d.ts.map +1 -1
  82. package/dist/local_repo.js +64 -16
  83. package/dist/log_helpers.d.ts +1 -1
  84. package/dist/log_helpers.d.ts.map +1 -1
  85. package/dist/multi_repo_publisher.d.ts +3 -3
  86. package/dist/multi_repo_publisher.d.ts.map +1 -1
  87. package/dist/multi_repo_publisher.js +24 -20
  88. package/dist/npm_registry.d.ts +1 -1
  89. package/dist/npm_registry.d.ts.map +1 -1
  90. package/dist/npm_registry.js +4 -4
  91. package/dist/operations.d.ts +4 -4
  92. package/dist/operations.d.ts.map +1 -1
  93. package/dist/operations_defaults.d.ts.map +1 -1
  94. package/dist/operations_defaults.js +16 -16
  95. package/dist/output_helpers.d.ts +1 -1
  96. package/dist/output_helpers.d.ts.map +1 -1
  97. package/dist/preflight_checks.d.ts +2 -2
  98. package/dist/preflight_checks.d.ts.map +1 -1
  99. package/dist/preflight_checks.js +5 -5
  100. package/dist/publish_gate.d.ts.map +1 -1
  101. package/dist/publish_steps.d.ts.map +1 -1
  102. package/dist/publish_steps.js +4 -4
  103. package/dist/publishing_event.d.ts.map +1 -1
  104. package/dist/publishing_event.js +16 -14
  105. package/dist/publishing_event_handler.d.ts.map +1 -1
  106. package/dist/publishing_event_handler.js +6 -6
  107. package/dist/publishing_plan.d.ts +3 -3
  108. package/dist/publishing_plan.d.ts.map +1 -1
  109. package/dist/publishing_plan.js +25 -15
  110. package/dist/publishing_plan_helpers.d.ts.map +1 -1
  111. package/dist/publishing_plan_helpers.js +3 -3
  112. package/dist/publishing_plan_logging.d.ts +1 -1
  113. package/dist/publishing_plan_logging.d.ts.map +1 -1
  114. package/dist/publishing_plan_logging.js +2 -2
  115. package/dist/repo.svelte.d.ts +5 -5
  116. package/dist/repo.svelte.d.ts.map +1 -1
  117. package/dist/repo.svelte.js +2 -2
  118. package/dist/repo_ops.js +2 -2
  119. package/dist/resolved_gitops_config.d.ts.map +1 -1
  120. package/dist/resolved_gitops_config.js +1 -1
  121. package/dist/version_utils.js +1 -1
  122. package/package.json +16 -15
  123. package/src/lib/cargo_toml.ts +82 -0
  124. package/src/lib/changeset_generator.ts +20 -20
  125. package/src/lib/changeset_reader.ts +18 -18
  126. package/src/lib/ci_reconcile.ts +5 -5
  127. package/src/lib/config_reconcile.ts +8 -4
  128. package/src/lib/dependency_graph.ts +28 -28
  129. package/src/lib/dependency_updater.ts +30 -30
  130. package/src/lib/fetch_repo_data.ts +11 -11
  131. package/src/lib/fs_fetch_value_cache.ts +14 -10
  132. package/src/lib/git_operations.ts +31 -31
  133. package/src/lib/github.ts +19 -19
  134. package/src/lib/github_helpers.ts +6 -6
  135. package/src/lib/gitops_analyze.task.ts +56 -48
  136. package/src/lib/gitops_config.ts +14 -14
  137. package/src/lib/gitops_plan.task.ts +32 -32
  138. package/src/lib/gitops_publish.task.ts +52 -49
  139. package/src/lib/gitops_run.task.ts +29 -29
  140. package/src/lib/gitops_sync.task.ts +39 -30
  141. package/src/lib/gitops_task_helpers.ts +21 -21
  142. package/src/lib/gitops_validate.task.ts +38 -38
  143. package/src/lib/graph_validation.ts +14 -13
  144. package/src/lib/local_repo.ts +130 -64
  145. package/src/lib/log_helpers.ts +15 -15
  146. package/src/lib/multi_repo_publisher.ts +75 -74
  147. package/src/lib/npm_registry.ts +13 -13
  148. package/src/lib/operations.ts +50 -39
  149. package/src/lib/operations_defaults.ts +108 -106
  150. package/src/lib/output_helpers.ts +4 -4
  151. package/src/lib/preflight_checks.ts +28 -28
  152. package/src/lib/publish_gate.ts +7 -9
  153. package/src/lib/publish_steps.ts +15 -15
  154. package/src/lib/publishing_event.ts +22 -20
  155. package/src/lib/publishing_event_handler.ts +8 -8
  156. package/src/lib/publishing_plan.ts +69 -57
  157. package/src/lib/publishing_plan_helpers.ts +16 -12
  158. package/src/lib/publishing_plan_logging.ts +23 -23
  159. package/src/lib/repo.svelte.ts +8 -8
  160. package/src/lib/repo_ops.ts +12 -12
  161. package/src/lib/resolved_gitops_config.ts +5 -5
  162. package/src/lib/version_utils.ts +3 -3
@@ -8,17 +8,17 @@
8
8
  * @module
9
9
  */
10
10
 
11
- import type {BumpType} from './version_utils.js';
12
- import type {PublishingPlan, VersionChange} from './publishing_plan.js';
13
- import {UnreachableError} from '@fuzdev/fuz_util/error.js';
11
+ import type { BumpType } from './version_utils.ts';
12
+ import type { PublishingPlan, VersionChange } from './publishing_plan.ts';
13
+ import { UnreachableError } from '@fuzdev/fuz_util/error.ts';
14
14
 
15
15
  /** How a package's version bump arises in the plan. */
16
16
  export type PublishStepVia = 'changeset' | 'auto_changeset' | 'escalation';
17
17
 
18
18
  /** One ordered side-effect a wetrun would perform. */
19
19
  export type PublishStep =
20
- | {kind: 'publish'; repo: string; from: string; to: string; bump: BumpType; via: PublishStepVia}
21
- | {kind: 'npm_wait'; repo: string; version: string}
20
+ | { kind: 'publish'; repo: string; from: string; to: string; bump: BumpType; via: PublishStepVia }
21
+ | { kind: 'npm_wait'; repo: string; version: string }
22
22
  | {
23
23
  kind: 'dependency_update';
24
24
  dependent: string;
@@ -27,8 +27,8 @@ export type PublishStep =
27
27
  dep_type: 'prod' | 'peer';
28
28
  creates_changeset: boolean;
29
29
  }
30
- | {kind: 'dev_dep_update'; repo: string; dependency: string; to: string}
31
- | {kind: 'deploy'; repo: string; builds: boolean};
30
+ | { kind: 'dev_dep_update'; repo: string; dependency: string; to: string }
31
+ | { kind: 'deploy'; repo: string; builds: boolean };
32
32
 
33
33
  export interface DerivePublishStepsOptions {
34
34
  /** Include the deploy phase (the publisher only deploys with `--deploy`). */
@@ -51,11 +51,11 @@ const step_via = (change: VersionChange): PublishStepVia =>
51
51
  */
52
52
  export const derive_publish_steps = (
53
53
  plan: PublishingPlan,
54
- options: DerivePublishStepsOptions = {},
54
+ options: DerivePublishStepsOptions = {}
55
55
  ): Array<PublishStep> => {
56
- const {deploy = false} = options;
56
+ const { deploy = false } = options;
57
57
  const changes: Map<string, VersionChange> = new Map(
58
- plan.version_changes.map((vc) => [vc.package_name, vc]),
58
+ plan.version_changes.map((vc) => [vc.package_name, vc])
59
59
  );
60
60
 
61
61
  const steps: Array<PublishStep> = [];
@@ -72,9 +72,9 @@ export const derive_publish_steps = (
72
72
  from: change.from,
73
73
  to: change.to,
74
74
  bump: change.bump_type,
75
- via: step_via(change),
75
+ via: step_via(change)
76
76
  });
77
- steps.push({kind: 'npm_wait', repo, version: change.to});
77
+ steps.push({ kind: 'npm_wait', repo, version: change.to });
78
78
  changed.add(repo);
79
79
 
80
80
  // Prod/peer dependents are rewritten right after this publishes. A dependent that
@@ -92,7 +92,7 @@ export const derive_publish_steps = (
92
92
  dependency: repo,
93
93
  to: change.to,
94
94
  dep_type: update.type === 'peerDependencies' ? 'peer' : 'prod',
95
- creates_changeset: republishes,
95
+ creates_changeset: republishes
96
96
  });
97
97
  changed.add(update.dependent_package);
98
98
  }
@@ -109,7 +109,7 @@ export const derive_publish_steps = (
109
109
  kind: 'dev_dep_update',
110
110
  repo: update.dependent_package,
111
111
  dependency: update.updated_dependency,
112
- to: dep_change.to,
112
+ to: dep_change.to
113
113
  });
114
114
  changed.add(update.dependent_package);
115
115
  }
@@ -117,7 +117,7 @@ export const derive_publish_steps = (
117
117
  // Phase 3: deploy every changed repo (only with --deploy). Each builds fresh.
118
118
  if (deploy) {
119
119
  for (const repo of changed) {
120
- steps.push({kind: 'deploy', repo, builds: true});
120
+ steps.push({ kind: 'deploy', repo, builds: true });
121
121
  }
122
122
  }
123
123
 
@@ -14,7 +14,7 @@
14
14
  * @module
15
15
  */
16
16
 
17
- import {z} from 'zod';
17
+ import { z } from 'zod';
18
18
 
19
19
  /**
20
20
  * Coarse triage classification for a failed package. Lets consumers branch on
@@ -30,17 +30,17 @@ export const PublishingErrorCode = z.enum([
30
30
  // invariant violation, distinct from an ordinary publish failure (see fail-loud
31
31
  // drift detection in `multi_repo_publisher.ts`)
32
32
  'drift',
33
- 'other',
33
+ 'other'
34
34
  ]);
35
35
  export type PublishingErrorCode = z.infer<typeof PublishingErrorCode>;
36
36
 
37
37
  /** Tallied outcome of a publishing run, derived from its events via `summarize_events`. */
38
38
  export const PublishingRunSummary = z.strictObject({
39
- total: z.number().meta({description: 'packages in the publishing order (the candidate set)'}),
40
- published: z.number().meta({description: 'packages published (or, in a dry run, predicted)'}),
39
+ total: z.number().meta({ description: 'packages in the publishing order (the candidate set)' }),
40
+ published: z.number().meta({ description: 'packages published (or, in a dry run, predicted)' }),
41
41
  failed: z.number(),
42
42
  skipped: z.number(),
43
- duration: z.number().meta({description: 'wall-clock duration in milliseconds'}),
43
+ duration: z.number().meta({ description: 'wall-clock duration in milliseconds' })
44
44
  });
45
45
  export type PublishingRunSummary = z.infer<typeof PublishingRunSummary>;
46
46
 
@@ -51,13 +51,15 @@ export type PublishingRunSummary = z.infer<typeof PublishingRunSummary>;
51
51
  export const PublishingEvent = z.discriminatedUnion('event', [
52
52
  z.strictObject({
53
53
  event: z.literal('run_started'),
54
- wetrun: z.boolean().meta({description: 'false means every package_completed is a prediction'}),
55
- total: z.number(),
54
+ wetrun: z
55
+ .boolean()
56
+ .meta({ description: 'false means every package_completed is a prediction' }),
57
+ total: z.number()
56
58
  }),
57
59
  z.strictObject({
58
60
  event: z.literal('package_skipped'),
59
61
  name: z.string(),
60
- reason: z.string(),
62
+ reason: z.string()
61
63
  }),
62
64
  z.strictObject({
63
65
  event: z.literal('package_completed'),
@@ -67,19 +69,19 @@ export const PublishingEvent = z.discriminatedUnion('event', [
67
69
  // mirrors `BumpType` from `version_utils.ts`; inline so the event schema is self-contained
68
70
  bump_type: z.enum(['major', 'minor', 'patch']),
69
71
  breaking: z.boolean(),
70
- commit: z.string().meta({description: "'simulated' in a dry run, otherwise the commit hash"}),
71
- tag: z.string(),
72
+ commit: z.string().meta({ description: "'simulated' in a dry run, otherwise the commit hash" }),
73
+ tag: z.string()
72
74
  }),
73
75
  z.strictObject({
74
76
  event: z.literal('npm_waited'),
75
77
  name: z.string(),
76
- version: z.string().meta({description: 'the version waited on after publishing'}),
78
+ version: z.string().meta({ description: 'the version waited on after publishing' })
77
79
  }),
78
80
  z.strictObject({
79
81
  event: z.literal('package_failed'),
80
82
  name: z.string(),
81
83
  error: z.string(),
82
- code: PublishingErrorCode,
84
+ code: PublishingErrorCode
83
85
  }),
84
86
  z.strictObject({
85
87
  event: z.literal('dependency_updated'),
@@ -91,25 +93,25 @@ export const PublishingEvent = z.discriminatedUnion('event', [
91
93
  dep_type: z.enum(['prod', 'peer', 'dev']),
92
94
  // true when the update creates an auto-changeset (a publishable dependent republishes);
93
95
  // false for dev-dep updates and update-only leaves (private dependents never publish).
94
- creates_changeset: z.boolean(),
96
+ creates_changeset: z.boolean()
95
97
  }),
96
98
  z.strictObject({
97
99
  event: z.literal('deploy_started'),
98
- name: z.string(),
100
+ name: z.string()
99
101
  }),
100
102
  z.strictObject({
101
103
  event: z.literal('deploy_completed'),
102
- name: z.string(),
104
+ name: z.string()
103
105
  }),
104
106
  z.strictObject({
105
107
  event: z.literal('deploy_failed'),
106
108
  name: z.string(),
107
- error: z.string(),
109
+ error: z.string()
108
110
  }),
109
111
  z.strictObject({
110
112
  event: z.literal('run_finished'),
111
- summary: PublishingRunSummary,
112
- }),
113
+ summary: PublishingRunSummary
114
+ })
113
115
  ]);
114
116
  export type PublishingEvent = z.infer<typeof PublishingEvent>;
115
117
 
@@ -123,7 +125,7 @@ export type PublishingEvent = z.infer<typeof PublishingEvent>;
123
125
  */
124
126
  export const summarize_events = (
125
127
  events: Array<PublishingEvent>,
126
- duration: number,
128
+ duration: number
127
129
  ): PublishingRunSummary => {
128
130
  let total = 0;
129
131
  let published = 0;
@@ -147,5 +149,5 @@ export const summarize_events = (
147
149
  break;
148
150
  }
149
151
  }
150
- return {total, published, failed, skipped, duration};
152
+ return { total, published, failed, skipped, duration };
151
153
  };
@@ -9,7 +9,7 @@
9
9
  * @module
10
10
  */
11
11
 
12
- import type {PublishingEvent} from './publishing_event.js';
12
+ import type { PublishingEvent } from './publishing_event.ts';
13
13
 
14
14
  /** A sink for publishing events. */
15
15
  export interface PublishingEventHandler {
@@ -23,7 +23,7 @@ export interface CapturingEventHandler extends PublishingEventHandler {
23
23
 
24
24
  /** Drops every event. The default when no handler is supplied. */
25
25
  export const null_handler = (): PublishingEventHandler => ({
26
- emit: () => {},
26
+ emit: () => {}
27
27
  });
28
28
 
29
29
  /** Collects events in memory. Used to build the run report and in tests. */
@@ -33,7 +33,7 @@ export const capture_handler = (): CapturingEventHandler => {
33
33
  events,
34
34
  emit: (event) => {
35
35
  events.push(event);
36
- },
36
+ }
37
37
  };
38
38
  };
39
39
 
@@ -48,7 +48,7 @@ export const stdout_handler = (): PublishingEventHandler => ({
48
48
  } catch {
49
49
  // best-effort: a logging sink must never fail a run
50
50
  }
51
- },
51
+ }
52
52
  });
53
53
 
54
54
  /** Fans an event out to every handler in order. */
@@ -57,7 +57,7 @@ export const multi_handler = (handlers: Array<PublishingEventHandler>): Publishi
57
57
  for (const handler of handlers) {
58
58
  handler.emit(event);
59
59
  }
60
- },
60
+ }
61
61
  });
62
62
 
63
63
  /**
@@ -68,11 +68,11 @@ export const multi_handler = (handlers: Array<PublishingEventHandler>): Publishi
68
68
  */
69
69
  export const masking_handler = (
70
70
  inner: PublishingEventHandler,
71
- mask: (event: PublishingEvent) => PublishingEvent = mask_secrets,
71
+ mask: (event: PublishingEvent) => PublishingEvent = mask_secrets
72
72
  ): PublishingEventHandler => ({
73
73
  emit: (event) => {
74
74
  inner.emit(mask(event));
75
- },
75
+ }
76
76
  });
77
77
 
78
78
  // Minimal redaction rules: npm auth tokens (bare or registry-scoped), `SECRET_*`
@@ -81,7 +81,7 @@ export const masking_handler = (
81
81
  const SECRET_RULES: Array<readonly [RegExp, string]> = [
82
82
  [/((?:\/\/[^\s:]+:)?_authToken\s*=\s*)\S+/gi, '$1[redacted]'],
83
83
  [/(SECRET_[A-Z0-9_]+\s*[=:]\s*)\S+/g, '$1[redacted]'],
84
- [/(npm_[A-Za-z0-9]{4})[A-Za-z0-9]{12,}/g, '$1[redacted]'],
84
+ [/(npm_[A-Za-z0-9]{4})[A-Za-z0-9]{12,}/g, '$1[redacted]']
85
85
  ];
86
86
 
87
87
  /** Redacts known secret shapes from a string. */
@@ -1,25 +1,25 @@
1
- import type {Logger} from '@fuzdev/fuz_util/log.js';
2
- import {styleText as st} from 'node:util';
1
+ import type { Logger } from '@fuzdev/fuz_util/log.ts';
2
+ import { styleText as st } from 'node:util';
3
3
 
4
- import type {LocalRepo} from './local_repo.js';
5
- import {validate_dependency_graph} from './graph_validation.js';
4
+ import { repo_is_npm, type LocalRepo } from './local_repo.ts';
5
+ import { validate_dependency_graph } from './graph_validation.ts';
6
6
  import {
7
7
  type BumpType,
8
8
  is_breaking_change,
9
9
  compare_bump_types,
10
- calculate_next_version,
11
- } from './version_utils.js';
12
- import type {ChangesetOperations} from './operations.js';
13
- import {default_changeset_operations} from './operations_defaults.js';
14
- import {GITOPS_MAX_ITERATIONS_DEFAULT} from './gitops_constants.js';
15
- import type {DependencyGraph} from './dependency_graph.ts';
10
+ calculate_next_version
11
+ } from './version_utils.ts';
12
+ import type { ChangesetOperations } from './operations.ts';
13
+ import { default_changeset_operations } from './operations_defaults.ts';
14
+ import { GITOPS_MAX_ITERATIONS_DEFAULT } from './gitops_constants.ts';
15
+ import type { DependencyGraph } from './dependency_graph.ts';
16
16
  import {
17
17
  calculate_dependency_updates,
18
- get_required_bump_for_dependencies,
19
- } from './publishing_plan_helpers.js';
18
+ get_required_bump_for_dependencies
19
+ } from './publishing_plan_helpers.ts';
20
20
 
21
21
  // Re-export logging functions
22
- export {log_publishing_plan, type LogPlanOptions} from './publishing_plan_logging.js';
22
+ export { log_publishing_plan, type LogPlanOptions } from './publishing_plan_logging.ts';
23
23
 
24
24
  export interface VersionChange {
25
25
  package_name: string;
@@ -45,7 +45,7 @@ export interface DependencyUpdate {
45
45
  // Verbose data types for diagnostic output
46
46
  export interface VerboseChangesetDetail {
47
47
  package_name: string;
48
- files: Array<{filename: string; bump_type: BumpType; summary: string}>;
48
+ files: Array<{ filename: string; bump_type: BumpType; summary: string }>;
49
49
  }
50
50
 
51
51
  export interface VerboseIterationPackage {
@@ -67,14 +67,14 @@ export interface VerboseIteration {
67
67
 
68
68
  export interface VerbosePropagationChain {
69
69
  source: string;
70
- chain: Array<{pkg: string; dep_type: 'prod' | 'peer'; action: string}>;
70
+ chain: Array<{ pkg: string; dep_type: 'prod' | 'peer'; action: string }>;
71
71
  }
72
72
 
73
73
  export interface VerboseGraphSummary {
74
74
  package_count: number;
75
75
  internal_dep_count: number;
76
- prod_peer_edges: Array<{from: string; to: string; type: 'prod' | 'peer'}>;
77
- dev_edges: Array<{from: string; to: string}>;
76
+ prod_peer_edges: Array<{ from: string; to: string; type: 'prod' | 'peer' }>;
77
+ dev_edges: Array<{ from: string; to: string }>;
78
78
  prod_cycle_count: number;
79
79
  dev_cycle_count: number;
80
80
  }
@@ -110,16 +110,28 @@ export interface GeneratePlanOptions {
110
110
  * Uses fixed-point iteration to resolve transitive cascades.
111
111
  */
112
112
  export const generate_publishing_plan = async (
113
- repos: Array<LocalRepo>,
114
- options: GeneratePlanOptions = {},
113
+ all_repos: Array<LocalRepo>,
114
+ options: GeneratePlanOptions = {}
115
115
  ): Promise<PublishingPlan> => {
116
- const {log, ops = default_changeset_operations, verbose} = options;
116
+ const { log, ops = default_changeset_operations, verbose } = options;
117
117
  log?.info(st('cyan', 'Generating publishing plan...'));
118
118
 
119
119
  const warnings: Array<string> = [];
120
120
  const info: Array<string> = []; // Informational status (not warnings)
121
121
  const errors: Array<string> = [];
122
122
 
123
+ // Publishing concerns only npm packages. Non-npm repos (e.g. Rust cargo repos) are
124
+ // loaded for the dashboard but have no npm identity in the changeset cascade — drop them
125
+ // before building the graph so they never appear in the plan or publishing order.
126
+ const non_npm_repos = all_repos.filter((r) => !repo_is_npm(r));
127
+ if (non_npm_repos.length > 0) {
128
+ info.push(
129
+ `Excluded ${non_npm_repos.length} non-npm repo(s) from publishing: ` +
130
+ non_npm_repos.map((r) => r.library.name).join(', ')
131
+ );
132
+ }
133
+ const repos = all_repos.filter(repo_is_npm);
134
+
123
135
  // Verbose data collection
124
136
  const verbose_changeset_details: Array<VerboseChangesetDetail> = [];
125
137
  const verbose_iterations: Array<VerboseIteration> = [];
@@ -134,7 +146,7 @@ export const generate_publishing_plan = async (
134
146
  const validation = validate_dependency_graph(repos, {
135
147
  throw_on_prod_cycles: false, // Collect errors instead of throwing
136
148
  log_cycles: false, // We'll handle our own error collection
137
- log_order: false, // Plan generation doesn't need to log order
149
+ log_order: false // Plan generation doesn't need to log order
138
150
  });
139
151
  publishing_order = validation.publishing_order;
140
152
  production_cycles = validation.production_cycles;
@@ -154,7 +166,7 @@ export const generate_publishing_plan = async (
154
166
  breaking_cascades: new Map(),
155
167
  warnings,
156
168
  info,
157
- errors,
169
+ errors
158
170
  };
159
171
  }
160
172
 
@@ -168,7 +180,7 @@ export const generate_publishing_plan = async (
168
180
  // Dev cycles are shown in gitops_analyze, not repeated here
169
181
  if (dev_cycles.length > 0) {
170
182
  info.push(
171
- `${dev_cycles.length} dev dependency cycle(s) detected (normal, shown in gitops_analyze)`,
183
+ `${dev_cycles.length} dev dependency cycle(s) detected (normal, shown in gitops_analyze)`
172
184
  );
173
185
  }
174
186
 
@@ -186,7 +198,7 @@ export const generate_publishing_plan = async (
186
198
  // the topological order. Flag a private package that carries a changeset, since that
187
199
  // changeset can't be published.
188
200
  if (repo.package_json.private) {
189
- const private_has_changesets = await ops.has_changesets({repo});
201
+ const private_has_changesets = await ops.has_changesets({ repo });
190
202
  if (private_has_changesets.ok && private_has_changesets.value) {
191
203
  warnings.push(`${pkg_name} is private — its changeset(s) will not be published`);
192
204
  }
@@ -194,7 +206,7 @@ export const generate_publishing_plan = async (
194
206
  }
195
207
 
196
208
  // Check for changesets
197
- const has_result = await ops.has_changesets({repo});
209
+ const has_result = await ops.has_changesets({ repo });
198
210
 
199
211
  if (!has_result.ok) {
200
212
  errors.push(`Failed to check changesets for ${pkg_name}: ${has_result.message}`);
@@ -203,7 +215,7 @@ export const generate_publishing_plan = async (
203
215
 
204
216
  if (has_result.value) {
205
217
  // Predict version from changesets
206
- const prediction = await ops.predict_next_version({repo, log});
218
+ const prediction = await ops.predict_next_version({ repo, log });
207
219
 
208
220
  if (!prediction) {
209
221
  // No changesets found - this shouldn't happen since has_changesets returned true
@@ -217,7 +229,7 @@ export const generate_publishing_plan = async (
217
229
 
218
230
  // Capture changeset details for verbose output
219
231
  if (verbose) {
220
- const changesets_result = await ops.read_changesets({repo, log});
232
+ const changesets_result = await ops.read_changesets({ repo, log });
221
233
  if (changesets_result.ok) {
222
234
  const files = changesets_result.value
223
235
  .filter((cs) => cs.packages.some((p) => p.name === pkg_name))
@@ -226,11 +238,11 @@ export const generate_publishing_plan = async (
226
238
  return {
227
239
  filename: cs.filename,
228
240
  bump_type: pkg_entry?.bump_type || prediction.bump_type,
229
- summary: cs.summary,
241
+ summary: cs.summary
230
242
  };
231
243
  });
232
244
  if (files.length > 0) {
233
- verbose_changeset_details.push({package_name: pkg_name, files});
245
+ verbose_changeset_details.push({ package_name: pkg_name, files });
234
246
  }
235
247
  }
236
248
  }
@@ -251,7 +263,7 @@ export const generate_publishing_plan = async (
251
263
  to: prediction.version,
252
264
  bump_type: prediction.bump_type,
253
265
  breaking: is_breaking,
254
- has_changesets: true,
266
+ has_changesets: true
255
267
  });
256
268
  }
257
269
  }
@@ -272,10 +284,10 @@ export const generate_publishing_plan = async (
272
284
 
273
285
  // Recalculate dependency updates based on current predicted versions
274
286
  // (breaking_cascades not needed during iteration, only calculated at the end)
275
- const {dependency_updates} = calculate_dependency_updates(
287
+ const { dependency_updates } = calculate_dependency_updates(
276
288
  repos,
277
289
  predicted_versions,
278
- breaking_packages,
290
+ breaking_packages
279
291
  );
280
292
 
281
293
  // Process packages to check for bump escalation and auto-generated changesets
@@ -290,7 +302,7 @@ export const generate_publishing_plan = async (
290
302
  const required_bump = get_required_bump_for_dependencies(
291
303
  repo,
292
304
  dependency_updates,
293
- breaking_packages,
305
+ breaking_packages
294
306
  );
295
307
 
296
308
  // Find triggering dependency for verbose output
@@ -300,7 +312,7 @@ export const generate_publishing_plan = async (
300
312
  (u) =>
301
313
  u.dependent_package === pkg_name &&
302
314
  (u.type === 'dependencies' || u.type === 'peerDependencies') &&
303
- breaking_packages.has(u.updated_dependency),
315
+ breaking_packages.has(u.updated_dependency)
304
316
  );
305
317
  if (relevant_updates.length > 0) {
306
318
  triggering_dep = `${relevant_updates[0]!.updated_dependency} BREAKING`;
@@ -325,7 +337,7 @@ export const generate_publishing_plan = async (
325
337
  // Capture verbose data before updating
326
338
  if (verbose) {
327
339
  const changeset_detail = verbose_changeset_details.find(
328
- (d) => d.package_name === pkg_name,
340
+ (d) => d.package_name === pkg_name
329
341
  );
330
342
  verbose_iteration_packages.push({
331
343
  name: pkg_name,
@@ -335,7 +347,7 @@ export const generate_publishing_plan = async (
335
347
  triggering_dep,
336
348
  action: 'escalation',
337
349
  version_to: new_version,
338
- is_breaking: is_breaking_change(old_version, required_bump),
350
+ is_breaking: is_breaking_change(old_version, required_bump)
339
351
  });
340
352
  }
341
353
 
@@ -376,7 +388,7 @@ export const generate_publishing_plan = async (
376
388
  triggering_dep,
377
389
  action: 'auto_changeset',
378
390
  version_to: new_version,
379
- is_breaking,
391
+ is_breaking
380
392
  });
381
393
  }
382
394
 
@@ -391,7 +403,7 @@ export const generate_publishing_plan = async (
391
403
  bump_type: required_bump,
392
404
  breaking: is_breaking,
393
405
  has_changesets: false,
394
- will_generate_changeset: true,
406
+ will_generate_changeset: true
395
407
  });
396
408
 
397
409
  // Update predicted versions
@@ -405,7 +417,7 @@ export const generate_publishing_plan = async (
405
417
  verbose_iterations.push({
406
418
  iteration,
407
419
  packages: verbose_iteration_packages,
408
- new_changes: verbose_new_changes,
420
+ new_changes: verbose_new_changes
409
421
  });
410
422
  }
411
423
  }
@@ -416,10 +428,10 @@ export const generate_publishing_plan = async (
416
428
  const pending_packages: Array<string> = [];
417
429
 
418
430
  // Recalculate one more time to see what's pending
419
- const {dependency_updates: pending_updates} = calculate_dependency_updates(
431
+ const { dependency_updates: pending_updates } = calculate_dependency_updates(
420
432
  repos,
421
433
  predicted_versions,
422
- breaking_packages,
434
+ breaking_packages
423
435
  );
424
436
 
425
437
  for (const repo of repos) {
@@ -428,7 +440,7 @@ export const generate_publishing_plan = async (
428
440
  const required_bump = get_required_bump_for_dependencies(
429
441
  repo,
430
442
  pending_updates,
431
- breaking_packages,
443
+ breaking_packages
432
444
  );
433
445
 
434
446
  // Check if this package would need processing
@@ -450,22 +462,22 @@ export const generate_publishing_plan = async (
450
462
  warnings.push(
451
463
  `Reached maximum iterations (${GITOPS_MAX_ITERATIONS_DEFAULT}) without full convergence - ` +
452
464
  `${pending_count} package(s) may still need processing: ${pending_packages.join(', ')}. ` +
453
- `Estimated ${estimated_iterations} more iteration(s) needed.`,
465
+ `Estimated ${estimated_iterations} more iteration(s) needed.`
454
466
  );
455
467
  }
456
468
 
457
469
  // Final dependency updates calculation after convergence
458
- const {dependency_updates, breaking_cascades} = calculate_dependency_updates(
470
+ const { dependency_updates, breaking_cascades } = calculate_dependency_updates(
459
471
  repos,
460
472
  predicted_versions,
461
- breaking_packages,
473
+ breaking_packages
462
474
  );
463
475
 
464
476
  // Identify packages with no changes
465
477
  for (const repo of repos) {
466
478
  const has_version_change = version_changes.some((vc) => vc.package_name === repo.library.name);
467
479
  if (!has_version_change) {
468
- const has_result = await ops.has_changesets({repo});
480
+ const has_result = await ops.has_changesets({ repo });
469
481
  if (has_result.ok && !has_result.value) {
470
482
  info.push(repo.library.name);
471
483
  }
@@ -478,11 +490,11 @@ export const generate_publishing_plan = async (
478
490
  // Build propagation chains from breaking_cascades
479
491
  const propagation_chains: Array<VerbosePropagationChain> = [];
480
492
  for (const [source, affected] of breaking_cascades) {
481
- const chain: Array<{pkg: string; dep_type: 'prod' | 'peer'; action: string}> = [];
493
+ const chain: Array<{ pkg: string; dep_type: 'prod' | 'peer'; action: string }> = [];
482
494
  for (const pkg of affected) {
483
495
  // Determine dep type and action
484
496
  const update = dependency_updates.find(
485
- (u) => u.dependent_package === pkg && u.updated_dependency === source,
497
+ (u) => u.dependent_package === pkg && u.updated_dependency === source
486
498
  );
487
499
  const dep_type: 'prod' | 'peer' = update?.type === 'peerDependencies' ? 'peer' : 'prod';
488
500
  const version_change = version_changes.find((vc) => vc.package_name === pkg);
@@ -492,16 +504,16 @@ export const generate_publishing_plan = async (
492
504
  } else if (version_change?.needs_bump_escalation) {
493
505
  action = 'bump escalation';
494
506
  }
495
- chain.push({pkg, dep_type, action});
507
+ chain.push({ pkg, dep_type, action });
496
508
  }
497
509
  if (chain.length > 0) {
498
- propagation_chains.push({source, chain});
510
+ propagation_chains.push({ source, chain });
499
511
  }
500
512
  }
501
513
 
502
514
  // Build graph summary
503
- const prod_peer_edges: Array<{from: string; to: string; type: 'prod' | 'peer'}> = [];
504
- const dev_edges: Array<{from: string; to: string}> = [];
515
+ const prod_peer_edges: Array<{ from: string; to: string; type: 'prod' | 'peer' }> = [];
516
+ const dev_edges: Array<{ from: string; to: string }> = [];
505
517
  let internal_dep_count = 0;
506
518
 
507
519
  for (const [pkg_name, node] of graph.nodes) {
@@ -510,12 +522,12 @@ export const generate_publishing_plan = async (
510
522
  if (graph.nodes.has(dep_name)) {
511
523
  internal_dep_count++;
512
524
  if (spec.type === 'dev') {
513
- dev_edges.push({from: pkg_name, to: dep_name});
525
+ dev_edges.push({ from: pkg_name, to: dep_name });
514
526
  } else {
515
527
  prod_peer_edges.push({
516
528
  from: pkg_name,
517
529
  to: dep_name,
518
- type: spec.type === 'peer' ? 'peer' : 'prod',
530
+ type: spec.type === 'peer' ? 'peer' : 'prod'
519
531
  });
520
532
  }
521
533
  }
@@ -532,9 +544,9 @@ export const generate_publishing_plan = async (
532
544
  prod_peer_edges,
533
545
  dev_edges,
534
546
  prod_cycle_count: production_cycles.length,
535
- dev_cycle_count: dev_cycles.length,
547
+ dev_cycle_count: dev_cycles.length
536
548
  },
537
- total_iterations: iteration,
549
+ total_iterations: iteration
538
550
  };
539
551
  }
540
552
 
@@ -546,6 +558,6 @@ export const generate_publishing_plan = async (
546
558
  warnings,
547
559
  info,
548
560
  errors,
549
- verbose_data,
561
+ verbose_data
550
562
  };
551
563
  };