@clossys/launcher 0.3.1 → 0.5.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 (290) hide show
  1. package/README.md +1373 -60
  2. package/contracts/conversation-contract.md +2 -2
  3. package/contracts/product-ci-workflow.yml +74 -0
  4. package/contracts/repository-inventory.json +53 -0
  5. package/dist/admission-fixture.d.ts +168 -0
  6. package/dist/admission-fixture.d.ts.map +1 -0
  7. package/dist/admission-fixture.js +467 -0
  8. package/dist/admission-fixture.js.map +1 -0
  9. package/dist/admission.d.ts +124 -0
  10. package/dist/admission.d.ts.map +1 -0
  11. package/dist/admission.js +804 -0
  12. package/dist/admission.js.map +1 -0
  13. package/dist/agents-guide.d.ts +9 -0
  14. package/dist/agents-guide.d.ts.map +1 -0
  15. package/dist/agents-guide.js +26 -0
  16. package/dist/agents-guide.js.map +1 -0
  17. package/dist/apply-command-options.check.d.ts +12 -0
  18. package/dist/apply-command-options.check.d.ts.map +1 -0
  19. package/dist/apply-command-options.check.js +20 -0
  20. package/dist/apply-command-options.check.js.map +1 -0
  21. package/dist/apply-plan-cli.d.ts +39 -1
  22. package/dist/apply-plan-cli.d.ts.map +1 -1
  23. package/dist/apply-plan-cli.js +432 -15
  24. package/dist/apply-plan-cli.js.map +1 -1
  25. package/dist/apply-plan.d.ts +46 -59
  26. package/dist/apply-plan.d.ts.map +1 -1
  27. package/dist/apply-plan.js +112 -97
  28. package/dist/apply-plan.js.map +1 -1
  29. package/dist/apply-step-fixture.d.ts +87 -0
  30. package/dist/apply-step-fixture.d.ts.map +1 -0
  31. package/dist/apply-step-fixture.js +199 -0
  32. package/dist/apply-step-fixture.js.map +1 -0
  33. package/dist/apply-store.d.ts +93 -0
  34. package/dist/apply-store.d.ts.map +1 -0
  35. package/dist/apply-store.js +625 -0
  36. package/dist/apply-store.js.map +1 -0
  37. package/dist/approval-sheet.d.ts +21 -0
  38. package/dist/approval-sheet.d.ts.map +1 -0
  39. package/dist/approval-sheet.js +163 -0
  40. package/dist/approval-sheet.js.map +1 -0
  41. package/dist/body-command.d.ts +42 -0
  42. package/dist/body-command.d.ts.map +1 -0
  43. package/dist/body-command.js +143 -0
  44. package/dist/body-command.js.map +1 -0
  45. package/dist/change-set-contract.d.ts +403 -0
  46. package/dist/change-set-contract.d.ts.map +1 -0
  47. package/dist/change-set-contract.js +781 -0
  48. package/dist/change-set-contract.js.map +1 -0
  49. package/dist/change-set-digest.d.ts +28 -0
  50. package/dist/change-set-digest.d.ts.map +1 -0
  51. package/dist/change-set-digest.js +65 -0
  52. package/dist/change-set-digest.js.map +1 -0
  53. package/dist/check-cli.d.ts.map +1 -1
  54. package/dist/check-cli.js +14 -3
  55. package/dist/check-cli.js.map +1 -1
  56. package/dist/cli.d.ts +17 -6
  57. package/dist/cli.d.ts.map +1 -1
  58. package/dist/cli.js +84 -23
  59. package/dist/cli.js.map +1 -1
  60. package/dist/core.d.ts +79 -22
  61. package/dist/core.d.ts.map +1 -1
  62. package/dist/core.js +843 -268
  63. package/dist/core.js.map +1 -1
  64. package/dist/dry-materialize.d.ts +63 -0
  65. package/dist/dry-materialize.d.ts.map +1 -0
  66. package/dist/dry-materialize.js +330 -0
  67. package/dist/dry-materialize.js.map +1 -0
  68. package/dist/existing-declaration-adoption.check.d.ts +2 -0
  69. package/dist/existing-declaration-adoption.check.d.ts.map +1 -0
  70. package/dist/existing-declaration-adoption.check.js +10 -0
  71. package/dist/existing-declaration-adoption.check.js.map +1 -0
  72. package/dist/generated/contract-schema.generated.d.ts +97 -0
  73. package/dist/generated/contract-schema.generated.d.ts.map +1 -0
  74. package/dist/generated/contract-schema.generated.js +496 -0
  75. package/dist/generated/contract-schema.generated.js.map +1 -0
  76. package/dist/generated/package-scope.generated.d.ts +6 -0
  77. package/dist/generated/package-scope.generated.d.ts.map +1 -0
  78. package/dist/generated/package-scope.generated.js +10 -0
  79. package/dist/generated/package-scope.generated.js.map +1 -0
  80. package/dist/generated/plan-contracts.generated.d.ts +3 -0
  81. package/dist/generated/plan-contracts.generated.d.ts.map +1 -0
  82. package/dist/generated/plan-contracts.generated.js +3101 -0
  83. package/dist/generated/plan-contracts.generated.js.map +1 -0
  84. package/dist/host.d.ts.map +1 -1
  85. package/dist/host.js +11 -0
  86. package/dist/host.js.map +1 -1
  87. package/dist/identity.d.ts +15 -0
  88. package/dist/identity.d.ts.map +1 -0
  89. package/dist/identity.js +48 -0
  90. package/dist/identity.js.map +1 -0
  91. package/dist/index.d.ts +35 -5
  92. package/dist/index.d.ts.map +1 -1
  93. package/dist/index.js +19 -2
  94. package/dist/index.js.map +1 -1
  95. package/dist/inventory-adoption.d.ts +24 -5
  96. package/dist/inventory-adoption.d.ts.map +1 -1
  97. package/dist/inventory-adoption.js +70 -25
  98. package/dist/inventory-adoption.js.map +1 -1
  99. package/dist/inventory-choice.d.ts +40 -0
  100. package/dist/inventory-choice.d.ts.map +1 -0
  101. package/dist/inventory-choice.js +156 -0
  102. package/dist/inventory-choice.js.map +1 -0
  103. package/dist/inventory-contract.d.ts +89 -0
  104. package/dist/inventory-contract.d.ts.map +1 -0
  105. package/dist/inventory-contract.js +121 -0
  106. package/dist/inventory-contract.js.map +1 -0
  107. package/dist/key-editor.d.ts +30 -0
  108. package/dist/key-editor.d.ts.map +1 -0
  109. package/dist/key-editor.js +445 -0
  110. package/dist/key-editor.js.map +1 -0
  111. package/dist/ledger-contract.d.ts +190 -0
  112. package/dist/ledger-contract.d.ts.map +1 -0
  113. package/dist/ledger-contract.js +555 -0
  114. package/dist/ledger-contract.js.map +1 -0
  115. package/dist/ledger-trust.d.ts +90 -0
  116. package/dist/ledger-trust.d.ts.map +1 -0
  117. package/dist/ledger-trust.js +203 -0
  118. package/dist/ledger-trust.js.map +1 -0
  119. package/dist/lockfile-invariants.d.ts +48 -0
  120. package/dist/lockfile-invariants.d.ts.map +1 -0
  121. package/dist/lockfile-invariants.js +375 -0
  122. package/dist/lockfile-invariants.js.map +1 -0
  123. package/dist/lockfile-readers.d.ts +72 -0
  124. package/dist/lockfile-readers.d.ts.map +1 -0
  125. package/dist/lockfile-readers.js +713 -0
  126. package/dist/lockfile-readers.js.map +1 -0
  127. package/dist/lockfile-regen.d.ts +106 -0
  128. package/dist/lockfile-regen.d.ts.map +1 -0
  129. package/dist/lockfile-regen.js +760 -0
  130. package/dist/lockfile-regen.js.map +1 -0
  131. package/dist/lockfile-tool-env.d.ts +29 -0
  132. package/dist/lockfile-tool-env.d.ts.map +1 -0
  133. package/dist/lockfile-tool-env.js +111 -0
  134. package/dist/lockfile-tool-env.js.map +1 -0
  135. package/dist/materialize.d.ts +113 -0
  136. package/dist/materialize.d.ts.map +1 -0
  137. package/dist/materialize.js +881 -0
  138. package/dist/materialize.js.map +1 -0
  139. package/dist/observe-repository.d.ts +90 -0
  140. package/dist/observe-repository.d.ts.map +1 -0
  141. package/dist/observe-repository.js +1367 -0
  142. package/dist/observe-repository.js.map +1 -0
  143. package/dist/plan-bundle-setup-fixture.d.ts +68 -0
  144. package/dist/plan-bundle-setup-fixture.d.ts.map +1 -0
  145. package/dist/plan-bundle-setup-fixture.js +167 -0
  146. package/dist/plan-bundle-setup-fixture.js.map +1 -0
  147. package/dist/plan-bundle.d.ts +256 -0
  148. package/dist/plan-bundle.d.ts.map +1 -0
  149. package/dist/plan-bundle.js +882 -0
  150. package/dist/plan-bundle.js.map +1 -0
  151. package/dist/plan-command.d.ts +29 -0
  152. package/dist/plan-command.d.ts.map +1 -0
  153. package/dist/plan-command.js +523 -0
  154. package/dist/plan-command.js.map +1 -0
  155. package/dist/plan-contract.d.ts +153 -0
  156. package/dist/plan-contract.d.ts.map +1 -0
  157. package/dist/plan-contract.js +61 -0
  158. package/dist/plan-contract.js.map +1 -0
  159. package/dist/plan-digest.d.ts +25 -0
  160. package/dist/plan-digest.d.ts.map +1 -0
  161. package/dist/plan-digest.js +106 -0
  162. package/dist/plan-digest.js.map +1 -0
  163. package/dist/plan-rules.d.ts +23 -0
  164. package/dist/plan-rules.d.ts.map +1 -0
  165. package/dist/plan-rules.js +177 -0
  166. package/dist/plan-rules.js.map +1 -0
  167. package/dist/planned-bundle.d.ts +20 -0
  168. package/dist/planned-bundle.d.ts.map +1 -0
  169. package/dist/planned-bundle.js +191 -0
  170. package/dist/planned-bundle.js.map +1 -0
  171. package/dist/product-repository.d.ts +4 -0
  172. package/dist/product-repository.d.ts.map +1 -1
  173. package/dist/product-repository.js +9 -1
  174. package/dist/product-repository.js.map +1 -1
  175. package/dist/provenance-gate.d.ts +48 -0
  176. package/dist/provenance-gate.d.ts.map +1 -0
  177. package/dist/provenance-gate.js +324 -0
  178. package/dist/provenance-gate.js.map +1 -0
  179. package/dist/pull-request-body.d.ts +45 -0
  180. package/dist/pull-request-body.d.ts.map +1 -0
  181. package/dist/pull-request-body.js +232 -0
  182. package/dist/pull-request-body.js.map +1 -0
  183. package/dist/registry-snapshot.d.ts +141 -0
  184. package/dist/registry-snapshot.d.ts.map +1 -0
  185. package/dist/registry-snapshot.js +483 -0
  186. package/dist/registry-snapshot.js.map +1 -0
  187. package/dist/release-age-edit.d.ts +52 -0
  188. package/dist/release-age-edit.d.ts.map +1 -0
  189. package/dist/release-age-edit.js +413 -0
  190. package/dist/release-age-edit.js.map +1 -0
  191. package/dist/root-entries.d.ts +36 -0
  192. package/dist/root-entries.d.ts.map +1 -0
  193. package/dist/root-entries.js +80 -0
  194. package/dist/root-entries.js.map +1 -0
  195. package/dist/setup-template-scripts.d.ts +36 -0
  196. package/dist/setup-template-scripts.d.ts.map +1 -0
  197. package/dist/setup-template-scripts.js +568 -0
  198. package/dist/setup-template-scripts.js.map +1 -0
  199. package/dist/setup-templates.d.ts +55 -0
  200. package/dist/setup-templates.d.ts.map +1 -0
  201. package/dist/setup-templates.js +438 -0
  202. package/dist/setup-templates.js.map +1 -0
  203. package/dist/skills.d.ts +34 -1
  204. package/dist/skills.d.ts.map +1 -1
  205. package/dist/skills.js +129 -17
  206. package/dist/skills.js.map +1 -1
  207. package/dist/status.d.ts +63 -0
  208. package/dist/status.d.ts.map +1 -0
  209. package/dist/status.js +539 -0
  210. package/dist/status.js.map +1 -0
  211. package/dist/types.d.ts +151 -13
  212. package/dist/types.d.ts.map +1 -1
  213. package/package.json +4 -4
  214. package/skeleton/README.md +14 -9
  215. package/skeleton/package.json +2 -1
  216. package/skill/SKILL.md +23 -7
  217. package/skill-catalogue/advisor/SKILL.md +59 -6
  218. package/skill-catalogue/architect/SKILL.md +2 -2
  219. package/skill-catalogue/bouncer/SKILL.md +2 -2
  220. package/skill-catalogue/builder/SKILL.md +2 -2
  221. package/skill-catalogue/butler/SKILL.md +2 -2
  222. package/skill-catalogue/controller/SKILL.md +2 -2
  223. package/skill-catalogue/customer/SKILL.md +2 -2
  224. package/skill-catalogue/designer/SKILL.md +4 -2
  225. package/skill-catalogue/giver/SKILL.md +2 -2
  226. package/skill-catalogue/influencer/SKILL.md +2 -2
  227. package/skill-catalogue/inspector/SKILL.md +2 -2
  228. package/skill-catalogue/integrator/SKILL.md +2 -2
  229. package/skill-catalogue/keeper/SKILL.md +2 -2
  230. package/skill-catalogue/launcher/SKILL.md +23 -7
  231. package/skill-catalogue/locksmith/SKILL.md +2 -2
  232. package/skill-catalogue/messenger/SKILL.md +2 -2
  233. package/skill-catalogue/observer/SKILL.md +2 -2
  234. package/skill-catalogue/publisher/SKILL.md +2 -2
  235. package/skill-catalogue/starter/SKILL.md +3 -2
  236. package/skill-catalogue/strategist/SKILL.md +12 -4
  237. package/skill-catalogue/writer/SKILL.md +2 -2
  238. package/src/admission-fixture.ts +585 -0
  239. package/src/admission.ts +819 -0
  240. package/src/agents-guide.ts +29 -0
  241. package/src/apply-command-options.check.ts +27 -0
  242. package/src/apply-plan-cli.ts +454 -14
  243. package/src/apply-plan.ts +112 -124
  244. package/src/apply-step-fixture.ts +236 -0
  245. package/src/apply-store.ts +584 -0
  246. package/src/approval-sheet.ts +170 -0
  247. package/src/body-command.ts +162 -0
  248. package/src/change-set-contract.ts +987 -0
  249. package/src/change-set-digest.ts +70 -0
  250. package/src/check-cli.ts +14 -3
  251. package/src/cli.ts +90 -22
  252. package/src/core.ts +973 -275
  253. package/src/dry-materialize.ts +353 -0
  254. package/src/existing-declaration-adoption.check.ts +12 -0
  255. package/src/generated/contract-schema.generated.ts +520 -0
  256. package/src/generated/package-scope.generated.ts +10 -0
  257. package/src/generated/plan-contracts.generated.ts +3101 -0
  258. package/src/host.ts +10 -0
  259. package/src/identity.ts +51 -0
  260. package/src/index.ts +74 -3
  261. package/src/inventory-adoption.ts +107 -29
  262. package/src/inventory-choice.ts +172 -0
  263. package/src/inventory-contract.ts +166 -0
  264. package/src/key-editor.ts +446 -0
  265. package/src/ledger-contract.ts +660 -0
  266. package/src/ledger-trust.ts +272 -0
  267. package/src/lockfile-invariants.ts +421 -0
  268. package/src/lockfile-readers.ts +749 -0
  269. package/src/lockfile-regen.ts +851 -0
  270. package/src/lockfile-tool-env.ts +131 -0
  271. package/src/materialize.ts +915 -0
  272. package/src/observe-repository.ts +1365 -0
  273. package/src/plan-bundle-setup-fixture.ts +200 -0
  274. package/src/plan-bundle.ts +1014 -0
  275. package/src/plan-command.ts +532 -0
  276. package/src/plan-contract.ts +179 -0
  277. package/src/plan-digest.ts +102 -0
  278. package/src/plan-rules.ts +188 -0
  279. package/src/planned-bundle.ts +211 -0
  280. package/src/product-repository.ts +10 -1
  281. package/src/provenance-gate.ts +352 -0
  282. package/src/pull-request-body.ts +261 -0
  283. package/src/registry-snapshot.ts +534 -0
  284. package/src/release-age-edit.ts +430 -0
  285. package/src/root-entries.ts +81 -0
  286. package/src/setup-template-scripts.ts +580 -0
  287. package/src/setup-templates.ts +479 -0
  288. package/src/skills.ts +161 -18
  289. package/src/status.ts +557 -0
  290. package/src/types.ts +148 -13
package/src/types.ts CHANGED
@@ -21,8 +21,18 @@ export interface WorkspaceHost {
21
21
  isDirectory(path: string): boolean;
22
22
  /** True when path exists and is a symlink (lstat; does not follow). Missing path is false. */
23
23
  isSymlink(path: string): boolean;
24
+ /** Decodes a file as UTF-8 text. Missing or unreadable is null. Not for contract documents: invalid bytes are silently replaced. */
24
25
  readText(path: string): string | null;
26
+ /**
27
+ * A file's exact bytes, never decoded. Missing or unreadable is null. Every
28
+ * inventory document is read this way and handed to the shared strict
29
+ * reader, so bytes that are not valid UTF-8 are refused rather than
30
+ * silently replaced with U+FFFD before anything checks them (#1179).
31
+ */
32
+ readBytes(path: string): Uint8Array | null;
25
33
  writeText(path: string, contents: string): void;
34
+ /** Writes these exact bytes, so a copied document stays byte-identical. */
35
+ writeBytes(path: string, contents: Uint8Array): void;
26
36
  mkdirp(path: string): void;
27
37
  /** Creates a relative symlink at linkPath pointing at relativeTarget (directory link). */
28
38
  symlink(relativeTarget: string, linkPath: string): void;
@@ -75,18 +85,29 @@ export interface SkillsManifestSummary {
75
85
  }
76
86
 
77
87
  export interface InventoryObservation {
78
- readonly status: "missing" | "empty" | "populated";
88
+ /**
89
+ * "invalid" means a document was found but does not conform to the
90
+ * inventory schema (bad JSON, wrong shape, an unrecognized field, or a
91
+ * duplicate repository id) -- distinct from "empty" (a well-formed,
92
+ * zero-entry document) so a malformed document is reported, never
93
+ * silently treated as if it were merely empty.
94
+ */
95
+ readonly status: "missing" | "empty" | "populated" | "invalid";
79
96
  readonly count: number;
97
+ /** Present only when status is "invalid"; names the offending field. */
98
+ readonly reason?: string;
80
99
  }
81
100
 
82
- /** A package.json dependency bucket scanned for the advisor pin. */
101
+ /** A package.json dependency bucket scanned for the hub engine pins. */
83
102
  export type DependencyBucket = "dependencies" | "devDependencies" | "optionalDependencies" | "peerDependencies";
84
103
 
85
- /** Staleness verdict for one pinned advisor version against the live registry version. */
104
+ /** Staleness verdict for one pinned engine version against the live registry version. */
86
105
  export type PinGrade = "stale" | "current" | "indeterminate";
87
106
 
88
- /** One graded advisor pin in one dependency bucket. */
107
+ /** One graded hub engine pin (`@clossys/advisor` or `@clossys/integrator`) in one dependency bucket. */
89
108
  export interface PinFinding {
109
+ /** The engine package this finding grades. */
110
+ readonly package: string;
90
111
  readonly bucket: DependencyBucket;
91
112
  readonly pinned: string;
92
113
  readonly grade: PinGrade;
@@ -107,20 +128,59 @@ export interface InventoryValidationReport {
107
128
  readonly note?: string;
108
129
  }
109
130
 
131
+ /** Where one hub engine is pinned, by dependency bucket, and its live registry version when known. */
132
+ export interface HubEnginePin {
133
+ readonly dependencies?: string;
134
+ readonly devDependencies?: string;
135
+ readonly optionalDependencies?: string;
136
+ readonly peerDependencies?: string;
137
+ readonly live?: string;
138
+ }
139
+
140
+ /** One change a run made to a hub engine pin in the hub's `package.json`. */
141
+ export interface EnginePinChange {
142
+ /** The engine package: `@clossys/advisor` or `@clossys/integrator`. */
143
+ readonly package: string;
144
+ /** The version pinned before the run; absent when the engine was not pinned at all. */
145
+ readonly from?: string;
146
+ /** The version pinned in `devDependencies` after the run. */
147
+ readonly to: string;
148
+ /** The dependency bucket the pin was moved out of, when it was not in `devDependencies`. */
149
+ readonly movedFrom?: DependencyBucket;
150
+ }
151
+
152
+ /**
153
+ * The hub's lockfile does not resolve its engine pins yet (`kind`
154
+ * `engine-pins-changed-install-needed`): the hub's package manager install
155
+ * has to run, and `package.json` be committed together with the lockfile,
156
+ * before a frozen install (`npm ci`, `pnpm install --frozen-lockfile`,
157
+ * `yarn install --immutable`) accepts the hub again. Marks the report degraded.
158
+ */
159
+ export interface EngineInstallFinding {
160
+ readonly kind: "engine-pins-changed-install-needed";
161
+ /** The lockfile found in the hub, e.g. `package-lock.json`. */
162
+ readonly lockfile: string;
163
+ /** The install command for that lockfile's package manager, e.g. `npm install`. */
164
+ readonly command: string;
165
+ /** The engines the lockfile does not resolve at their pinned version, or, for a lockfile Launcher does not read, the engines this run changed. */
166
+ readonly packages: readonly string[];
167
+ readonly note: string;
168
+ }
169
+
110
170
  /** Read-only pin and inventory report after adopt or resume. Never uninstalls. */
111
171
  export interface HubHealthReport {
112
172
  readonly marker: "present" | "missing";
113
173
  readonly inventory: InventoryObservation;
114
- readonly advisorPin: {
115
- readonly dependencies?: string;
116
- readonly devDependencies?: string;
117
- readonly optionalDependencies?: string;
118
- readonly peerDependencies?: string;
119
- readonly live?: string;
120
- };
174
+ readonly advisorPin: HubEnginePin;
175
+ readonly integratorPin: HubEnginePin;
176
+ /** True when either engine is pinned in more than one dependency bucket. */
121
177
  readonly dualPin: boolean;
122
178
  readonly extraClossys: readonly string[];
123
179
  readonly pinFindings: readonly PinFinding[];
180
+ /** Present when this run changed a hub engine pin in `package.json`: what changed, and the one next step (install, then commit `package.json` with its lockfile). */
181
+ readonly enginePins?: { readonly changed: readonly EnginePinChange[]; readonly nextStep: string };
182
+ /** Present when a lockfile in the hub does not resolve the engine pins yet; marks the report degraded. */
183
+ readonly installNeeded?: EngineInstallFinding;
124
184
  readonly degraded: boolean;
125
185
  /** Coding-agent hosts this apply found already linked for skill discovery here, recorded before compose ran (#1180). Always present after apply. */
126
186
  readonly linkedHosts?: readonly DiscoveredHost[];
@@ -129,9 +189,33 @@ export interface HubHealthReport {
129
189
  readonly skillComposition?: {
130
190
  readonly composed: readonly string[];
131
191
  readonly skipped: readonly { readonly packageDir: string; readonly note: string }[];
192
+ /** The checkouts this run composed skills into: the hub. */
132
193
  readonly rosterTargets?: readonly string[];
133
- readonly rosterSkipped?: readonly { readonly inventoryId: string; readonly note: string }[];
194
+ /**
195
+ * Each inventoried repository other than the hub, with what this run found
196
+ * for it (for example, a checkout beside the hub whose team arrives only
197
+ * once it is staffed in an approved plan, with that plan's setup pull
198
+ * request). Report-only: a hub run never writes into one, and no entry
199
+ * marks the report degraded. `inventoryId` is already a stored-inventory
200
+ * position label (e.g. `repositories[0] in the stored inventory`), never
201
+ * the raw id: this whole report is JSON-dumped into the apply message
202
+ * (see `formatHubHealth`'s `health:` line), so a raw id kept here would
203
+ * still reach that message even though no prose line built from it names
204
+ * the id either.
205
+ */
206
+ readonly siblings?: readonly { readonly inventoryId: string; readonly note: string }[];
134
207
  readonly retired?: readonly string[];
208
+ /**
209
+ * Composed skills in the hub left exactly as found because their on-disk
210
+ * content is not provably what Launcher last wrote (#1473). Any entry
211
+ * marks the report degraded.
212
+ */
213
+ readonly preserved?: readonly {
214
+ readonly packageDir: string;
215
+ readonly action: "rewrite" | "retire";
216
+ readonly path: string;
217
+ readonly note: string;
218
+ }[];
135
219
  };
136
220
  /** Present only on the run that performed the `.clossys/` -> `clossys/.state/` migration. */
137
221
  readonly migration?: { readonly status: "migrated"; readonly from: string; readonly to: string };
@@ -168,6 +252,8 @@ export interface WorkspaceObservation {
168
252
  readonly envOwner?: string;
169
253
  readonly remoteDefaultHub?: { readonly owner: string; readonly repository: string };
170
254
  readonly advisorVersion?: string;
255
+ /** The public `@clossys/integrator` registry version, read the same way as `advisorVersion`. */
256
+ readonly integratorVersion?: string;
171
257
  readonly ghAvailable: boolean;
172
258
  readonly gitAvailable: boolean;
173
259
  }
@@ -178,18 +264,50 @@ export interface WorkspacePlanCreate {
178
264
  readonly repository: string;
179
265
  readonly directory: string;
180
266
  readonly advisorVersion: string;
267
+ readonly integratorVersion: string;
181
268
  }
182
269
 
270
+ /**
271
+ * What `launcher --repositories` does to the hub inventory (#1179): write
272
+ * the chosen repositories, or leave an inventory that already lists exactly
273
+ * those repositories as it is. Decided by `resolveChosenInventory()`.
274
+ */
275
+ export type ChosenInventory =
276
+ | { readonly kind: "unchanged"; readonly count: number }
277
+ | {
278
+ readonly kind: "write";
279
+ /** The exact document text to write to `clossys/.state/inventory.json` (a generated hub path, not shipped in this package), already validated against the inventory contract. */
280
+ readonly document: string;
281
+ /** Repositories in the written document. */
282
+ readonly count: number;
283
+ /** Repositories the inventory listed before; 0 when there was none, it was empty, or it failed its contract. */
284
+ readonly previousCount: number;
285
+ /** Chosen ids the previous inventory did not list. Never put in a message text; see `addedPositions`. */
286
+ readonly added: readonly string[];
287
+ /** Previous ids the choice leaves out. Never put in a message text; see `removedPositions`. */
288
+ readonly removed: readonly string[];
289
+ /** Each `added` id's 0-based position in the `--repositories` argument, in the same order as `added`. What a message names instead of the id. */
290
+ readonly addedPositions: readonly number[];
291
+ /** Each `removed` id's 0-based position in the stored inventory's own `repositories` array, in the same order as `removed`. What a message names instead of the id. */
292
+ readonly removedPositions: readonly number[];
293
+ /** What the write replaces: nothing (no inventory, or an empty one), a differing valid inventory, or one that failed its contract. The last two happen only with an explicit replace approval. */
294
+ readonly replaced: "nothing" | "differing" | "invalid";
295
+ };
296
+
183
297
  export interface WorkspacePlanResume {
184
298
  readonly action: "resume";
185
299
  readonly owner: string;
186
300
  readonly repository: string;
187
301
  readonly directory: string;
188
302
  readonly clone: boolean;
189
- /** Live registry Advisor version, when observeWorkspace could read one. Used only to grade health. */
303
+ /** Live registry Advisor version, when observeWorkspace could read one. Apply pins it in the hub and grades health against it. */
190
304
  readonly advisorVersion?: string;
305
+ /** Live registry Integrator version, when observeWorkspace could read one. Apply pins it in the hub and grades health against it. */
306
+ readonly integratorVersion?: string;
191
307
  /** Set when the hub marker was found only at the legacy `.clossys/` path; apply migrates it. */
192
308
  readonly migrateFrom?: "legacy";
309
+ /** Set by `--repositories`: the inventory apply writes before it composes skills, or confirms is unchanged. */
310
+ readonly chosenInventory?: ChosenInventory;
193
311
  }
194
312
 
195
313
  export interface WorkspacePlanAdopt {
@@ -198,10 +316,27 @@ export interface WorkspacePlanAdopt {
198
316
  readonly repository: string;
199
317
  readonly directory: string;
200
318
  readonly advisorVersion: string;
319
+ readonly integratorVersion: string;
201
320
  /** Absolute path of a populated inventory document to copy. Absent when cwd already has one. */
202
321
  readonly inventorySource?: string;
203
322
  /** Merged repository ids (on-disk first, then new ids from --inventory) written when both sources are populated. */
204
323
  readonly mergedInventoryIds?: readonly string[];
324
+ /**
325
+ * The merged entries themselves (each entry's `packages` kept), in the same order as `mergedInventoryIds` (#1334).
326
+ * Apply writes them when the plan carries no `mergedInventoryDocument`.
327
+ */
328
+ readonly mergedInventoryRepositories?: readonly { readonly id: string; readonly packages?: unknown }[];
329
+ /**
330
+ * The merged inventory document to write, when both sources are populated: every kept entry whole, its `packages`
331
+ * included, each repository once by Launcher's one identity rule (#1179) -- `mergedInventoryRepositories`, rendered.
332
+ * Preferred over `mergedInventoryRepositories` and `mergedInventoryIds`, which a hand-built plan may still carry
333
+ * without it; with ids alone, each id is written without packages.
334
+ */
335
+ readonly mergedInventoryDocument?: string;
336
+ /** Set when `inventorySource` is about to replace an on-disk inventory that failed schema validation, so the apply message can say it was replaced rather than merely written (#1334). */
337
+ readonly replacesInvalidInventory?: boolean;
338
+ /** Set by `--repositories`: the inventory apply writes, or confirms is unchanged (#1179). */
339
+ readonly chosenInventory?: ChosenInventory;
205
340
  }
206
341
 
207
342
  export type WorkspacePlan = WorkspacePlanCreate | WorkspacePlanResume | WorkspacePlanAdopt;