@clossys/launcher 0.3.0 → 0.4.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 (286) hide show
  1. package/README.md +1328 -60
  2. package/contracts/conversation-contract.md +2 -1
  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 +453 -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 +799 -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 +157 -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 +381 -0
  46. package/dist/change-set-contract.d.ts.map +1 -0
  47. package/dist/change-set-contract.js +738 -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/generated/contract-schema.generated.d.ts +97 -0
  69. package/dist/generated/contract-schema.generated.d.ts.map +1 -0
  70. package/dist/generated/contract-schema.generated.js +496 -0
  71. package/dist/generated/contract-schema.generated.js.map +1 -0
  72. package/dist/generated/package-scope.generated.d.ts +6 -0
  73. package/dist/generated/package-scope.generated.d.ts.map +1 -0
  74. package/dist/generated/package-scope.generated.js +10 -0
  75. package/dist/generated/package-scope.generated.js.map +1 -0
  76. package/dist/generated/plan-contracts.generated.d.ts +3 -0
  77. package/dist/generated/plan-contracts.generated.d.ts.map +1 -0
  78. package/dist/generated/plan-contracts.generated.js +2840 -0
  79. package/dist/generated/plan-contracts.generated.js.map +1 -0
  80. package/dist/host.d.ts.map +1 -1
  81. package/dist/host.js +11 -0
  82. package/dist/host.js.map +1 -1
  83. package/dist/identity.d.ts +15 -0
  84. package/dist/identity.d.ts.map +1 -0
  85. package/dist/identity.js +48 -0
  86. package/dist/identity.js.map +1 -0
  87. package/dist/index.d.ts +34 -5
  88. package/dist/index.d.ts.map +1 -1
  89. package/dist/index.js +19 -2
  90. package/dist/index.js.map +1 -1
  91. package/dist/inventory-adoption.d.ts +24 -5
  92. package/dist/inventory-adoption.d.ts.map +1 -1
  93. package/dist/inventory-adoption.js +70 -25
  94. package/dist/inventory-adoption.js.map +1 -1
  95. package/dist/inventory-choice.d.ts +40 -0
  96. package/dist/inventory-choice.d.ts.map +1 -0
  97. package/dist/inventory-choice.js +156 -0
  98. package/dist/inventory-choice.js.map +1 -0
  99. package/dist/inventory-contract.d.ts +89 -0
  100. package/dist/inventory-contract.d.ts.map +1 -0
  101. package/dist/inventory-contract.js +121 -0
  102. package/dist/inventory-contract.js.map +1 -0
  103. package/dist/key-editor.d.ts +30 -0
  104. package/dist/key-editor.d.ts.map +1 -0
  105. package/dist/key-editor.js +445 -0
  106. package/dist/key-editor.js.map +1 -0
  107. package/dist/ledger-contract.d.ts +187 -0
  108. package/dist/ledger-contract.d.ts.map +1 -0
  109. package/dist/ledger-contract.js +532 -0
  110. package/dist/ledger-contract.js.map +1 -0
  111. package/dist/ledger-trust.d.ts +90 -0
  112. package/dist/ledger-trust.d.ts.map +1 -0
  113. package/dist/ledger-trust.js +198 -0
  114. package/dist/ledger-trust.js.map +1 -0
  115. package/dist/lockfile-invariants.d.ts +48 -0
  116. package/dist/lockfile-invariants.d.ts.map +1 -0
  117. package/dist/lockfile-invariants.js +375 -0
  118. package/dist/lockfile-invariants.js.map +1 -0
  119. package/dist/lockfile-readers.d.ts +72 -0
  120. package/dist/lockfile-readers.d.ts.map +1 -0
  121. package/dist/lockfile-readers.js +713 -0
  122. package/dist/lockfile-readers.js.map +1 -0
  123. package/dist/lockfile-regen.d.ts +106 -0
  124. package/dist/lockfile-regen.d.ts.map +1 -0
  125. package/dist/lockfile-regen.js +760 -0
  126. package/dist/lockfile-regen.js.map +1 -0
  127. package/dist/lockfile-tool-env.d.ts +29 -0
  128. package/dist/lockfile-tool-env.d.ts.map +1 -0
  129. package/dist/lockfile-tool-env.js +111 -0
  130. package/dist/lockfile-tool-env.js.map +1 -0
  131. package/dist/materialize.d.ts +113 -0
  132. package/dist/materialize.d.ts.map +1 -0
  133. package/dist/materialize.js +840 -0
  134. package/dist/materialize.js.map +1 -0
  135. package/dist/observe-repository.d.ts +90 -0
  136. package/dist/observe-repository.d.ts.map +1 -0
  137. package/dist/observe-repository.js +1367 -0
  138. package/dist/observe-repository.js.map +1 -0
  139. package/dist/plan-bundle-setup-fixture.d.ts +68 -0
  140. package/dist/plan-bundle-setup-fixture.d.ts.map +1 -0
  141. package/dist/plan-bundle-setup-fixture.js +167 -0
  142. package/dist/plan-bundle-setup-fixture.js.map +1 -0
  143. package/dist/plan-bundle.d.ts +250 -0
  144. package/dist/plan-bundle.d.ts.map +1 -0
  145. package/dist/plan-bundle.js +827 -0
  146. package/dist/plan-bundle.js.map +1 -0
  147. package/dist/plan-command.d.ts +29 -0
  148. package/dist/plan-command.d.ts.map +1 -0
  149. package/dist/plan-command.js +493 -0
  150. package/dist/plan-command.js.map +1 -0
  151. package/dist/plan-contract.d.ts +153 -0
  152. package/dist/plan-contract.d.ts.map +1 -0
  153. package/dist/plan-contract.js +61 -0
  154. package/dist/plan-contract.js.map +1 -0
  155. package/dist/plan-digest.d.ts +25 -0
  156. package/dist/plan-digest.d.ts.map +1 -0
  157. package/dist/plan-digest.js +106 -0
  158. package/dist/plan-digest.js.map +1 -0
  159. package/dist/plan-rules.d.ts +23 -0
  160. package/dist/plan-rules.d.ts.map +1 -0
  161. package/dist/plan-rules.js +177 -0
  162. package/dist/plan-rules.js.map +1 -0
  163. package/dist/planned-bundle.d.ts +20 -0
  164. package/dist/planned-bundle.d.ts.map +1 -0
  165. package/dist/planned-bundle.js +191 -0
  166. package/dist/planned-bundle.js.map +1 -0
  167. package/dist/product-repository.d.ts +4 -0
  168. package/dist/product-repository.d.ts.map +1 -1
  169. package/dist/product-repository.js +9 -1
  170. package/dist/product-repository.js.map +1 -1
  171. package/dist/provenance-gate.d.ts +48 -0
  172. package/dist/provenance-gate.d.ts.map +1 -0
  173. package/dist/provenance-gate.js +324 -0
  174. package/dist/provenance-gate.js.map +1 -0
  175. package/dist/pull-request-body.d.ts +45 -0
  176. package/dist/pull-request-body.d.ts.map +1 -0
  177. package/dist/pull-request-body.js +232 -0
  178. package/dist/pull-request-body.js.map +1 -0
  179. package/dist/registry-snapshot.d.ts +141 -0
  180. package/dist/registry-snapshot.d.ts.map +1 -0
  181. package/dist/registry-snapshot.js +483 -0
  182. package/dist/registry-snapshot.js.map +1 -0
  183. package/dist/release-age-edit.d.ts +52 -0
  184. package/dist/release-age-edit.d.ts.map +1 -0
  185. package/dist/release-age-edit.js +413 -0
  186. package/dist/release-age-edit.js.map +1 -0
  187. package/dist/root-entries.d.ts +36 -0
  188. package/dist/root-entries.d.ts.map +1 -0
  189. package/dist/root-entries.js +80 -0
  190. package/dist/root-entries.js.map +1 -0
  191. package/dist/setup-template-scripts.d.ts +34 -0
  192. package/dist/setup-template-scripts.d.ts.map +1 -0
  193. package/dist/setup-template-scripts.js +557 -0
  194. package/dist/setup-template-scripts.js.map +1 -0
  195. package/dist/setup-templates.d.ts +54 -0
  196. package/dist/setup-templates.d.ts.map +1 -0
  197. package/dist/setup-templates.js +427 -0
  198. package/dist/setup-templates.js.map +1 -0
  199. package/dist/skills.d.ts +34 -1
  200. package/dist/skills.d.ts.map +1 -1
  201. package/dist/skills.js +129 -17
  202. package/dist/skills.js.map +1 -1
  203. package/dist/status.d.ts +63 -0
  204. package/dist/status.d.ts.map +1 -0
  205. package/dist/status.js +539 -0
  206. package/dist/status.js.map +1 -0
  207. package/dist/types.d.ts +151 -13
  208. package/dist/types.d.ts.map +1 -1
  209. package/package.json +4 -5
  210. package/skeleton/README.md +14 -9
  211. package/skeleton/package.json +2 -1
  212. package/skill/SKILL.md +20 -16
  213. package/skill-catalogue/advisor/SKILL.md +100 -11
  214. package/skill-catalogue/architect/SKILL.md +2 -13
  215. package/skill-catalogue/bouncer/SKILL.md +2 -13
  216. package/skill-catalogue/builder/SKILL.md +2 -13
  217. package/skill-catalogue/butler/SKILL.md +2 -13
  218. package/skill-catalogue/controller/SKILL.md +2 -13
  219. package/skill-catalogue/customer/SKILL.md +4 -13
  220. package/skill-catalogue/designer/SKILL.md +9 -14
  221. package/skill-catalogue/giver/SKILL.md +2 -13
  222. package/skill-catalogue/influencer/SKILL.md +2 -13
  223. package/skill-catalogue/inspector/SKILL.md +2 -13
  224. package/skill-catalogue/integrator/SKILL.md +2 -13
  225. package/skill-catalogue/keeper/SKILL.md +2 -13
  226. package/skill-catalogue/launcher/SKILL.md +20 -16
  227. package/skill-catalogue/locksmith/SKILL.md +2 -13
  228. package/skill-catalogue/messenger/SKILL.md +2 -13
  229. package/skill-catalogue/observer/SKILL.md +2 -13
  230. package/skill-catalogue/publisher/SKILL.md +11 -17
  231. package/skill-catalogue/starter/SKILL.md +3 -13
  232. package/skill-catalogue/strategist/SKILL.md +14 -17
  233. package/skill-catalogue/writer/SKILL.md +7 -14
  234. package/src/admission-fixture.ts +572 -0
  235. package/src/admission.ts +816 -0
  236. package/src/agents-guide.ts +29 -0
  237. package/src/apply-command-options.check.ts +27 -0
  238. package/src/apply-plan-cli.ts +454 -14
  239. package/src/apply-plan.ts +112 -124
  240. package/src/apply-step-fixture.ts +236 -0
  241. package/src/apply-store.ts +584 -0
  242. package/src/approval-sheet.ts +164 -0
  243. package/src/body-command.ts +162 -0
  244. package/src/change-set-contract.ts +937 -0
  245. package/src/change-set-digest.ts +70 -0
  246. package/src/check-cli.ts +14 -3
  247. package/src/cli.ts +90 -22
  248. package/src/core.ts +973 -275
  249. package/src/dry-materialize.ts +353 -0
  250. package/src/generated/contract-schema.generated.ts +520 -0
  251. package/src/generated/package-scope.generated.ts +10 -0
  252. package/src/generated/plan-contracts.generated.ts +2840 -0
  253. package/src/host.ts +10 -0
  254. package/src/identity.ts +51 -0
  255. package/src/index.ts +72 -3
  256. package/src/inventory-adoption.ts +107 -29
  257. package/src/inventory-choice.ts +172 -0
  258. package/src/inventory-contract.ts +166 -0
  259. package/src/key-editor.ts +446 -0
  260. package/src/ledger-contract.ts +637 -0
  261. package/src/ledger-trust.ts +267 -0
  262. package/src/lockfile-invariants.ts +421 -0
  263. package/src/lockfile-readers.ts +749 -0
  264. package/src/lockfile-regen.ts +851 -0
  265. package/src/lockfile-tool-env.ts +131 -0
  266. package/src/materialize.ts +886 -0
  267. package/src/observe-repository.ts +1365 -0
  268. package/src/plan-bundle-setup-fixture.ts +200 -0
  269. package/src/plan-bundle.ts +964 -0
  270. package/src/plan-command.ts +509 -0
  271. package/src/plan-contract.ts +179 -0
  272. package/src/plan-digest.ts +102 -0
  273. package/src/plan-rules.ts +188 -0
  274. package/src/planned-bundle.ts +211 -0
  275. package/src/product-repository.ts +10 -1
  276. package/src/provenance-gate.ts +352 -0
  277. package/src/pull-request-body.ts +261 -0
  278. package/src/registry-snapshot.ts +534 -0
  279. package/src/release-age-edit.ts +430 -0
  280. package/src/root-entries.ts +81 -0
  281. package/src/setup-template-scripts.ts +571 -0
  282. package/src/setup-templates.ts +471 -0
  283. package/src/skills.ts +161 -18
  284. package/src/status.ts +557 -0
  285. package/src/types.ts +148 -13
  286. package/CHANGELOG.md +0 -131
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;
package/CHANGELOG.md DELETED
@@ -1,131 +0,0 @@
1
- # Changelog
2
-
3
- All notable changes to this package are documented in this file.
4
-
5
- The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
- and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
-
8
- ## [0.3.0] - 2026-09-22
9
-
10
- ### Added
11
-
12
- - The product repository standard (#1215), recorded in this repository's own docs/contracts/product-repository-layout.json (not shipped in the published package) -- `apps/*`, workspace wiring, agent pointers, and CI, extending the consumer layout. `checkCloudSessionBootstrap()` verifies the three checks a cloud agent session (browser plus GitHub only, no local setup) needs before it can install and run the team in a product repository.
13
- - `launcher-doctor`: a read-only command that checks git, the GitHub command-line tool, sign-in, Node.js, and npm, and names the first missing prerequisite in plain language with the one next action to take -- never a dump of everything at once (#1220).
14
- - Adopts an existing repository inventory instead of writing a second, diverging one, when the hub marker declares an `externalInventory`. `reportInventoryDrift()` runs automatically on every `launcher` create, resume, or appoint and prints the result in hub health output -- external-only, launcher-only, and agreeing repository ids, all three even when one is empty -- instead of silently merging them (#1216).
15
- - `--clone-missing`, an explicit, non-default flag on `launcher` that clones inventoried repositories not yet sitting beside the hub (#1179), reversing the previous no-clone default for exactly this one approved action. Plain invocation is unchanged: still report-only by default.
16
- - Every `launcher` create, resume, or appoint records which coding-agent hosts a directory could already discover skills through -- read before that same run composes skills and stamps every host's discovery path -- into `clossys/.state/hosts.json`, for the hub and every sibling clone (#1180). Codex is detected by the presence of `.agents/skills` itself -- verified against Codex's own documentation, which reads repository skills from that path directly and needs no separate discovery symlink the way Claude Code and Cursor do.
17
- - Ships a per-host model profile (`model-profiles/<host>.json`) mapping the fixed reasoning tiers (`light` / `standard` / `deep`) to that host's current models, and reads `clossys/preferences.json`'s budget stance to resolve within it (#1219). Packages never name a model; only this profile does.
18
- - `launcher-apply-plan`: validates an approved `clossys/advisor/plan.json` and an `EngagementBrief`-shaped `clossys/brief.json` against the "Plan file contract" recorded on issue #1175, then writes the brief into a staffed repository byte-identically (#1178, #1176). Multi-repository orchestration (branch creation, exact package installs, Starter's caller workflow, opening one pull request per repository) is deferred -- see the package README's "Applying an approved plan" section for why.
19
-
20
- ### Changed
21
-
22
- - `README.md`: documents the new commands and exports, and updates the "does not clone" line to describe the new explicit `--clone-missing` exception.
23
-
24
- ### Fixed
25
-
26
- - `detectLinkedHosts()` (#1180) and `reportInventoryDrift()` (#1216) are now called from the real `launcher` command path (`applyWorkspacePlan`, via `composeSkillRoster` / `finishHubApply`) on every create, resume, and appoint, instead of existing only as library functions nothing called. Per independent review at f2a50de707f8682c6885592f2910425c2e5a0b5f: neither had a reachable call site, so no client-run command actually recorded a linked host or reported inventory drift despite the PR body and this changelog describing both as delivered behavior.
27
-
28
- ## [0.2.0] - 2026-09-22
29
-
30
- ### Added
31
-
32
- - Scaffolds one visible `clossys/` folder per repository: a generated `README.md` index of active roles at the root of `clossys/`, and `clossys/.state/` for machine files (hub marker, inventory, and the new skills manifest).
33
- - Writes `clossys/.state/skills.json` on every apply: each composed skill's source (`installed` or `catalogue`), version, and a content digest. The health report states how many composed skills are out of date against the live `@clossys/launcher` version and how many were retired this run; retirement removes only a skill this directory's own previous manifest listed, never one launcher did not write.
34
- - Packs the shared conversation contract at build time and injects it into every composed skill in place of that skill's own "how we work together" and "one question at a time" sections, at the same position. No package edit is needed for this to take effect.
35
-
36
- ### Changed
37
-
38
- - Moves its own hub marker and inventory from the hidden `.clossys/` to the visible `clossys/.state/`; the packed skeleton template moves with it. Resume detects a hub still on the legacy path and migrates it automatically, reporting the move in the health report. A hub with a marker at both paths is graded `indeterminate` and launcher refuses rather than merging them silently.
39
- - Adds a `.gitignore` entry for generated run output under `clossys/**/.generated/`. Approved records, proof, and machine state are still committed, never ignored.
40
-
41
- ## [0.1.8] - 2026-09-21
42
-
43
- ### Added
44
-
45
- - Ships the packed Agent Skill in the tarball (`files` includes `skill`).
46
-
47
- ### Fixed
48
-
49
- - Skill compose prefers each checkout's installed `@clossys/<package>/skill/SKILL.md` when present, then falls back to the packed catalogue or sibling source.
50
- - Apply marks hub health degraded when the skill roster skips inventoried targets; missing per-package catalogue sources remain notes only.
51
-
52
- ## [0.1.7] - 2026-09-20
53
-
54
- ### Changed
55
-
56
- - Packed skill catalogue now carries pre-auth fold gates, the exceptional-keep brief that ships with `@clossys/designer` (synthetic user, not the doer, the sealer, or a QA contractor), and expression-wave skills that treat 3 as the floor not done.
57
-
58
- ## [0.1.6] - 2026-09-20
59
-
60
- ### Changed
61
-
62
- - Appoint now pins live `@clossys/advisor` in `devDependencies` only. It relocates a pin left in another bucket and overwrites a frozen version. A dedicated `{owner}/workspace` hub is named `@owner/workspace`; an appointed product keeps its package name.
63
- - Observe always reads the public Advisor version, including when a pin already exists, so appoint can write the live pin and resume can grade it.
64
- - Health is degraded when Advisor is missing, dual-pinned, or present outside `devDependencies`, not only when the pin is older than live.
65
- - New-hub skeleton package name is `@owner/workspace`.
66
- - New-hub `AGENTS.md` tells the coding agent to speak to a founder in
67
- ordinary sentences: where we are, what to do next, what we will not
68
- do, and whether anything is saved to git. Machine identifiers stay
69
- out of the default voice.
70
-
71
- ### Fixed
72
-
73
- - Resume health now receives the live Advisor version from observe, so a stale or misplaced pin is visible on every resume instead of only after a fresh appoint.
74
-
75
- ## [0.1.5] - 2026-09-20
76
-
77
- ### Fixed
78
-
79
- - Discovery compose skips a `.claude/skills` or `.cursor/skills` path that is already a symlink so it cannot replace composed `SKILL.md`.
80
-
81
- ## [0.1.4] - 2026-09-19
82
-
83
- ### Added
84
-
85
- - Hub apply composes the full `clossys-*` skill tree under `.agents/skills/` on create, appoint, and resume, reading bodies from the packed skill catalogue (built at `npm run build` from each package's skill source) or from a sibling checkout. Missing sources are skipped with a health note; apply continues.
86
- - The same roster is composed into every inventoried repository clone beside the hub (resolved from the generated hub inventory and confirmed with `git remote get-url origin`); the health report lists targets and skipped ids. Sister checkouts get optional canned `AGENTS.md` only when missing or still the generated sister text.
87
- - Apply writes host discovery links under `.cursor/skills/` and `.claude/skills/` pointing at the composed skills in the hub and each resolved clone.
88
- - Packed Agent Skill `clossys-launcher` so a coding agent can be invoked as `@clossys-launcher`.
89
-
90
- ### Changed
91
-
92
- - Resume refreshes composed skills and replaces stale generated `AGENTS.md` when it still tells founders to use `npx` to continue the conversation; customized `AGENTS.md` files are left alone.
93
- - Founder-facing hub guidance (`CONSUMER_AGENTS_MD`, skeleton README) now states the same `@clossys-*` team is available in every inventoried checkout; `@clossys-advisor` is the hiring check; `npx @clossys/launcher` refreshes voices on clones beside the hub.
94
-
95
- ## [0.1.2] - 2026-09-19
96
-
97
- ### Fixed
98
-
99
- - Appoint merges `--inventory` into a populated on-disk hub inventory instead of silently discarding the supplied document: repositories are unioned by id (on-disk order first, new ids appended in supplied order, first occurrence of an id wins) and the merged document is written to `.clossys/inventory.json` (that on-disk path does not ship with this package). The both-empty refusal is unchanged.
100
- - Resume with `--inventory` now refuses with "hub already appointed; edit `.clossys/inventory.json`" (that on-disk path does not ship with this package) instead of the misleading "--inventory is only valid when appointing".
101
- - Appoint refuses as `violated` when `CLOSSYS_OWNER` names a different account than the repository's github.com origin owner, naming both values; the marker is no longer written for the wrong account.
102
- - Appoint no longer requires a readable npm registry when the tree already pins `@clossys/advisor` in any dependency bucket (no new version would be needed); the indeterminate refusal only fires when a version is actually required.
103
- - Appoint refuses as `violated` when `git status --porcelain` is non-empty, before writing anything; when the origin is not on github.com the refusal names the remote host.
104
-
105
- ### Added
106
-
107
- - Health report grades each Advisor pin against the live registry version (internal semver compare, no new dependencies): pin older than live is a `stale pin` finding and marks the report degraded; equal pins pass; unparseable comparisons are noted as indeterminate. Exit stays 0 on resume; adopt prints the same report.
108
- - Pin and extra-`@clossys/*` scans now cover `optionalDependencies` and `peerDependencies` in addition to `dependencies` and `devDependencies`.
109
- - `checkInventoryEntries()`: read-only validation of hub inventory repository ids through batched `gh repo view --json name`, marking unknown ids in the report and skipping with a note when `gh` is absent. Never mutates the inventory.
110
- - `launcher-check` forwards `cwd.hub`, so a captured existing-hub observation grades as resume instead of mis-grading as adopt.
111
-
112
- ## [0.1.1] - 2026-09-19
113
-
114
- ### Fixed
115
-
116
- - Appoint leaves an existing `@clossys/advisor` pin in whichever bucket it already occupies. It no longer dual-pins or overwrites a frozen version with the live registry version.
117
- - Appoint refuses when the generated hub inventory is missing or empty (packed template `skeleton/.clossys/inventory.json`; that generated path does not ship), unless `--inventory <path>` supplies a populated document. Create may still write an empty inventory. Resume does not invent one.
118
-
119
- ### Added
120
-
121
- - Read-only health report after create, resume, and appoint: hub marker, inventory classification, Advisor pin location and version versus live, dual pin, extra `@clossys/*` names. Does not uninstall.
122
-
123
- ## [0.1.0] - 2026-09-18
124
-
125
- ### Added
126
-
127
- - `npx @clossys/launcher` as the single get-started command.
128
- - In-package hub skeleton (not a Foundry fork) copied into a GitHub repository.
129
- - Create a new `{owner}/workspace` hub, resume an existing hub, or adopt the current GitHub repository as the account hub.
130
- - Owner inference from `gh` and git remotes, with an interactive picker only when more than one GitHub owner is visible.
131
- - `launcher-check --input` grades a captured observation without creating a hub, so qualification can prove the 0/1/2 ternary.