@clossys/launcher 0.1.1 → 0.1.2

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.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,23 @@ All notable changes to this package are documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.1.2] - 2026-09-19
9
+
10
+ ### Fixed
11
+
12
+ - 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.
13
+ - 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".
14
+ - 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.
15
+ - 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.
16
+ - 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.
17
+
18
+ ### Added
19
+
20
+ - 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.
21
+ - Pin and extra-`@clossys/*` scans now cover `optionalDependencies` and `peerDependencies` in addition to `dependencies` and `devDependencies`.
22
+ - `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.
23
+ - `launcher-check` forwards `cwd.hub`, so a captured existing-hub observation grades as resume instead of mis-grading as adopt.
24
+
8
25
  ## [0.1.1] - 2026-09-19
9
26
 
10
27
  ### Fixed
package/README.md CHANGED
@@ -8,6 +8,21 @@ The hub inventories where Foundry packages are installed and coordinates
8
8
  engagement. It is not a product application and does not receive a dump of
9
9
  the catalogue.
10
10
 
11
+ ## Health report and staleness
12
+
13
+ After create, resume, or appoint — and on every resume — the command prints
14
+ a read-only health report. It scans all four dependency buckets
15
+ (`dependencies`, `devDependencies`, `optionalDependencies`,
16
+ `peerDependencies`) for the Advisor pin and for extra `@clossys/*` names.
17
+ When the live registry version is known, each pin is graded against it: a
18
+ pin older than live is a `stale pin` finding and marks the report
19
+ **degraded**. Exit stays 0 on resume (the report is advisory); adopt prints
20
+ the same report and an unparseable pin-versus-live comparison is noted as
21
+ indeterminate rather than stale. `checkInventoryEntries()` additionally
22
+ validates hub inventory ids read-only, marking ids whose repository no
23
+ longer resolves (skipped with a note when `gh` is unavailable).
24
+
25
+
11
26
  ## Install
12
27
 
13
28
  The get-started command is the package name:
@@ -22,7 +37,7 @@ mapping for `@clossys`. Pin an exact version once you depend on the library
22
37
  API:
23
38
 
24
39
  ```bash
25
- npm install --save-dev --save-exact @clossys/launcher@0.1.1
40
+ npm install --save-dev --save-exact @clossys/launcher@0.1.2
26
41
  ```
27
42
 
28
43
  ## How to run it
@@ -38,8 +53,8 @@ silent fallback.
38
53
  | Current directory | What happens |
39
54
  | --- | --- |
40
55
  | Empty | Creates `{owner}/workspace` from the in-package skeleton, or clones that hub if it already exists. |
41
- | Already a hub (generated marker; packed template `skeleton/.clossys/workspace.json`) | Resumes. No new repository. |
42
- | Any other GitHub repository you control | Appoints it as the account hub. Keeps the existing name and files. Writes the hub marker. Leaves an existing `@clossys/advisor` pin in whichever bucket it already occupies; pins live Advisor in `devDependencies` only when missing. Refuses if 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. Does not rewrite the lockfile or dump the catalogue. Prints a read-only health report. |
56
+ | Already a hub (generated marker; packed template `skeleton/.clossys/workspace.json`) | Resumes. No new repository. `--inventory` here is refused with a pointer to the appointed hub's own `.clossys/inventory.json`. |
57
+ | Any other GitHub repository you control | Appoints it as the account hub. Keeps the existing name and files. Refuses when the working tree has uncommitted changes (`git status --porcelain` non-empty) — the refusal names the offending remote host when the origin is not on github.com. Refuses when `CLOSSYS_OWNER` names a different account than the repository's github.com origin owner. Writes the hub marker. Leaves an existing `@clossys/advisor` pin in whichever bucket it already occupies; pins live Advisor in `devDependencies` only when missing. Refuses if 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 — or, when the on-disk inventory is already populated and `--inventory` is also supplied, merges the two by repository id (on-disk order first, new ids appended, first occurrence of an id wins). Does not rewrite the lockfile or dump the catalogue. Prints a read-only health report. |
43
58
 
44
59
  It does not have to be a brand-new exclusive repository, and it does not
45
60
  have to already match a Foundry layout. Informal "workspace-looking" trees
@@ -68,7 +83,7 @@ Exit codes preserve the ternary:
68
83
  | Exit | State | Meaning |
69
84
  | --- | --- | --- |
70
85
  | `0` | `satisfied` | Created, resumed, or appointed the hub. The message includes a read-only health report. |
71
- | `1` | `violated` | Known refusal: not GitHub, not empty, missing appoint inventory, or the supplier tree. |
86
+ | `1` | `violated` | Known refusal: not GitHub, not empty, missing appoint inventory, the supplier tree, uncommitted changes in the appoint tree, or a `CLOSSYS_OWNER` that disagrees with the origin owner. |
72
87
  | `2` | `indeterminate` | Missing `gh`, unreadable registry pin, or an owner that could not be inferred. |
73
88
 
74
89
  `launcher-check` grades a captured observation JSON through `planWorkspace` and does not create a hub. Same ternary: 0 is a create/resume/adopt plan, 1 is a known refusal, 2 could not run or could not decide. Appoint grades as a plan only when the observation already records a populated inventory; `--inventory` is a live CLI flag, not a check-cli input.
@@ -85,10 +100,12 @@ Exit codes preserve the ternary:
85
100
  | `inspectInventory()` | Classifies inventory JSON as missing, empty, or populated. |
86
101
  | `reportHubHealth()` | Read-only pin and inventory report. Does not install or uninstall. |
87
102
  | `formatHubHealth()` | Human lines plus a `health:` JSON line for the same report. |
103
+ | `hasAdvisorPin()` | True when a manifest already pins Advisor in any dependency bucket. |
104
+ | `checkInventoryEntries()` | Read-only inventory id validation through `gh repo view` (batched; skips with a note when `gh` is unavailable). |
88
105
  | `DEFAULT_REPOSITORY_NAME` | Default new-hub repository name (`workspace`). Used only when creating, never when appointing. |
89
106
  | `WORKSPACE_MARKER_REL` | Relative path of the hub marker. |
90
107
  | `WORKSPACE_INVENTORY_REL` | Relative path of the hub inventory. |
91
- | `CommandResult` / `CwdObservation` / `HubDocument` / `HubHealthReport` / `InventoryObservation` / `WorkspaceApplyResult` / `WorkspaceDecision` / `WorkspaceHost` / `WorkspaceObservation` / `WorkspacePlan` / `WorkspaceRefusal` / `WorkspaceState` | Typed host, observation, plan, health, and outcome contracts. |
108
+ | `CommandResult` / `CwdObservation` / `DependencyBucket` / `HubDocument` / `HubHealthReport` / `InventoryObservation` / `InventoryValidationEntry` / `InventoryValidationReport` / `PinFinding` / `PinGrade` / `WorkspaceApplyResult` / `WorkspaceDecision` / `WorkspaceHost` / `WorkspaceObservation` / `WorkspacePlan` / `WorkspaceRefusal` / `WorkspaceState` | Typed host, observation, plan, health, and outcome contracts. |
92
109
 
93
110
  ## Why this is not Advisor, Starter, Builder, installer, creator, or a connector
94
111
 
@@ -1 +1 @@
1
- {"version":3,"file":"check-cli.d.ts","sourceRoot":"","sources":["../src/check-cli.ts"],"names":[],"mappings":";AAKA,OAAO,KAAK,EAIV,aAAa,EACb,oBAAoB,EACrB,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,WAAW,uSAM0B,CAAC;AAEnD,qBAAa,uBAAwB,SAAQ,KAAK;CAAG;AAiDrD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,oBAAoB,CAsBrE;AAMD,uEAAuE;AACvE,wBAAgB,YAAY,IAAI,aAAa,CAmB5C;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAK7F;AAED,wBAAgB,SAAS,CACvB,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,EAClC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,EAChC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAC/B,MAAM,CA4BR"}
1
+ {"version":3,"file":"check-cli.d.ts","sourceRoot":"","sources":["../src/check-cli.ts"],"names":[],"mappings":";AAKA,OAAO,KAAK,EAIV,aAAa,EACb,oBAAoB,EACrB,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,WAAW,uSAM0B,CAAC;AAEnD,qBAAa,uBAAwB,SAAQ,KAAK;CAAG;AAqDrD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,oBAAoB,CAsBrE;AAMD,uEAAuE;AACvE,wBAAgB,YAAY,IAAI,aAAa,CAmB5C;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAK7F;AAED,wBAAgB,SAAS,CACvB,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,EAClC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,EAChC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAC/B,MAAM,CA4BR"}
package/dist/check-cli.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import { readFileSync } from "node:fs";
3
3
  import { resolve } from "node:path";
4
4
  import { isDirectInvocation } from "./cli.js";
5
- import { planWorkspace } from "./core.js";
5
+ import { isHubDocument, planWorkspace } from "./core.js";
6
6
  export const CHECK_USAGE = `Usage: launcher-check --input <observation.json>
7
7
 
8
8
  Grade a captured workspace observation through planWorkspace. This bin does
@@ -45,6 +45,9 @@ function parseCwd(value) {
45
45
  if (value.githubRepository !== undefined && !isText(value.githubRepository)) {
46
46
  throw new LauncherCheckInputError("observation.cwd.githubRepository must be a string");
47
47
  }
48
+ if (value.hub !== undefined && !isHubDocument(value.hub)) {
49
+ throw new LauncherCheckInputError("observation.cwd.hub must be a v1 account-hub marker (schemaVersion, kind, owner, repository)");
50
+ }
48
51
  const inventory = parseInventoryObservation(value.inventory);
49
52
  return {
50
53
  absolutePath: value.absolutePath,
@@ -53,6 +56,7 @@ function parseCwd(value) {
53
56
  looksLikeFoundry: value.looksLikeFoundry,
54
57
  ...(isText(value.githubOwner) ? { githubOwner: value.githubOwner } : {}),
55
58
  ...(isText(value.githubRepository) ? { githubRepository: value.githubRepository } : {}),
59
+ ...(isHubDocument(value.hub) ? { hub: value.hub } : {}),
56
60
  ...(inventory === undefined ? {} : { inventory }),
57
61
  };
58
62
  }
@@ -1 +1 @@
1
- {"version":3,"file":"check-cli.js","sourceRoot":"","sources":["../src/check-cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"check-cli.js","sourceRoot":"","sources":["../src/check-cli.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,eAAO,MAAM,KAAK,uyBAiBiD,CAAC;AAEpE,qBAAa,kBAAmB,SAAQ,KAAK;CAAG;AAMhD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,CAKpG;AAED,4FAA4F;AAC5F,wBAAgB,IAAI,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CA4B/F;AAYD,+FAA+F;AAC/F,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAO3F"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,eAAO,MAAM,KAAK,uyBAiBiD,CAAC;AAEpE,qBAAa,kBAAmB,SAAQ,KAAK;CAAG;AAMhD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,CAKpG;AAED,4FAA4F;AAC5F,wBAAgB,IAAI,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAgC/F;AAYD,+FAA+F;AAC/F,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAO3F"}
package/dist/cli.js CHANGED
@@ -57,7 +57,12 @@ export function main(argv, host, skeletonRoot) {
57
57
  return exitCodeFor(decision.state);
58
58
  }
59
59
  if (parsed.inventoryPath !== undefined && decision.action !== "adopt") {
60
- console.error("launcher: --inventory is only valid when appointing a GitHub repository");
60
+ if (decision.action === "resume") {
61
+ console.error("launcher: this hub is already appointed; edit .clossys/inventory.json to change its inventory");
62
+ }
63
+ else {
64
+ console.error("launcher: --inventory is only valid when appointing a GitHub repository");
65
+ }
61
66
  return 1;
62
67
  }
63
68
  const result = applyWorkspacePlan(host, decision, skeletonRoot);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
package/dist/core.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { HubDocument, HubHealthReport, InventoryObservation, WorkspaceApplyResult, WorkspaceDecision, WorkspaceHost, WorkspaceObservation, WorkspacePlan } from "./types.js";
1
+ import type { HubDocument, HubHealthReport, InventoryObservation, InventoryValidationReport, WorkspaceApplyResult, WorkspaceDecision, WorkspaceHost, WorkspaceObservation, WorkspacePlan } from "./types.js";
2
2
  export declare const DEFAULT_REPOSITORY_NAME = "workspace";
3
3
  export declare const WORKSPACE_MARKER_REL = ".clossys/workspace.json";
4
4
  export declare const WORKSPACE_INVENTORY_REL = ".clossys/inventory.json";
@@ -15,14 +15,27 @@ export declare function parseGitHubRemote(url: string): {
15
15
  export declare function isHubDocument(value: unknown): value is HubDocument;
16
16
  /** Classifies a generated hub inventory (packed template skeleton/.clossys/inventory.json; the generated path does not ship) without inventing repositories. */
17
17
  export declare function inspectInventory(raw: string | null): InventoryObservation;
18
+ /** True when the tree already pins Advisor in some bucket, so adopt would not need a new version. */
19
+ export declare function hasAdvisorPin(manifest: unknown): boolean;
18
20
  /** Collects GitHub owner, cwd shape, default-hub presence, and the public Advisor pin. */
19
21
  export declare function observeWorkspace(host: WorkspaceHost): WorkspaceObservation;
20
22
  export declare function planWorkspace(observation: WorkspaceObservation, host: WorkspaceHost, options?: {
21
23
  inventoryPath?: string;
22
24
  }): WorkspaceDecision;
23
- /** Read-only pin and inventory report. Does not install or uninstall. */
25
+ /**
26
+ * Read-only pin and inventory report. Does not install or uninstall. Scans all
27
+ * four dependency buckets; grades each pinned advisor version against the live
28
+ * registry version, marking a pin older than live as a stale-pin finding and a
29
+ * degraded report.
30
+ */
24
31
  export declare function reportHubHealth(host: WorkspaceHost, directory: string, liveAdvisorVersion?: string): HubHealthReport;
25
32
  export declare function formatHubHealth(report: HubHealthReport): string;
33
+ /**
34
+ * Read-only inventory validation: runs `gh repo view --json name` for each
35
+ * repository id, batched. Tolerates a missing or failing `gh` by skipping with
36
+ * a note; marks ids whose check fails as unknown. Never mutates the inventory.
37
+ */
38
+ export declare function checkInventoryEntries(host: WorkspaceHost, directory: string): InventoryValidationReport;
26
39
  /** Applies a create, resume, or adopt plan through the host. Resume does not write. */
27
40
  export declare function applyWorkspacePlan(host: WorkspaceHost, plan: WorkspacePlan, skeletonRoot: string): WorkspaceApplyResult;
28
41
  export declare function skeletonRootFromModule(moduleUrl: string): string;
@@ -1 +1 @@
1
- {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAGV,WAAW,EACX,eAAe,EACf,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,EACjB,aAAa,EACb,oBAAoB,EACpB,aAAa,EAGd,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,uBAAuB,cAAc,CAAC;AACnD,eAAO,MAAM,oBAAoB,4BAA4B,CAAC;AAC9D,eAAO,MAAM,uBAAuB,4BAA4B,CAAC;AACjE,eAAO,MAAM,eAAe,qBAAqB,CAAC;AAYlD,+EAA+E;AAC/E,eAAO,MAAM,kBAAkB,waAW9B,CAAC;AAEF,eAAO,MAAM,kBAAkB,iBAC9B,CAAC;AAoBF,8DAA8D;AAC9D,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAqB3F;AAED,yDAAyD;AACzD,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,WAAW,CASlE;AAaD,gKAAgK;AAChK,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,oBAAoB,CAYzE;AAkCD,0FAA0F;AAC1F,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,aAAa,GAAG,oBAAoB,CA4D1E;AAiDD,wBAAgB,aAAa,CAC3B,WAAW,EAAE,oBAAoB,EACjC,IAAI,EAAE,aAAa,EACnB,OAAO,GAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAA;CAAO,GACvC,iBAAiB,CAiEnB;AA2HD,yEAAyE;AACzE,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,kBAAkB,CAAC,EAAE,MAAM,GAAG,eAAe,CA2BpH;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAiB/D;AAgBD,uFAAuF;AACvF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,GAAG,oBAAoB,CAsCvH;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEhE"}
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAIV,WAAW,EACX,eAAe,EACf,oBAAoB,EAEpB,yBAAyB,EAEzB,oBAAoB,EACpB,iBAAiB,EACjB,aAAa,EACb,oBAAoB,EACpB,aAAa,EAGd,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,uBAAuB,cAAc,CAAC;AACnD,eAAO,MAAM,oBAAoB,4BAA4B,CAAC;AAC9D,eAAO,MAAM,uBAAuB,4BAA4B,CAAC;AACjE,eAAO,MAAM,eAAe,qBAAqB,CAAC;AAmBlD,+EAA+E;AAC/E,eAAO,MAAM,kBAAkB,waAW9B,CAAC;AAEF,eAAO,MAAM,kBAAkB,iBAC9B,CAAC;AAoBF,8DAA8D;AAC9D,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAqB3F;AA8BD,yDAAyD;AACzD,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,WAAW,CASlE;AAaD,gKAAgK;AAChK,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,oBAAoB,CAYzE;AAkCD,qGAAqG;AACrG,wBAAgB,aAAa,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAGxD;AAED,0FAA0F;AAC1F,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,aAAa,GAAG,oBAAoB,CAiE1E;AAwFD,wBAAgB,aAAa,CAC3B,WAAW,EAAE,oBAAoB,EACjC,IAAI,EAAE,aAAa,EACnB,OAAO,GAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAA;CAAO,GACvC,iBAAiB,CAgFnB;AAyJD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,kBAAkB,CAAC,EAAE,MAAM,GAAG,eAAe,CA0CpH;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAyB/D;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,GAAG,yBAAyB,CA4BvG;AAgBD,uFAAuF;AACvF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,GAAG,oBAAoB,CAsCvH;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEhE"}
package/dist/core.js CHANGED
@@ -4,6 +4,12 @@ export const DEFAULT_REPOSITORY_NAME = "workspace";
4
4
  export const WORKSPACE_MARKER_REL = ".clossys/workspace.json";
5
5
  export const WORKSPACE_INVENTORY_REL = ".clossys/inventory.json";
6
6
  export const ADVISOR_PACKAGE = "@clossys/advisor";
7
+ const DEPENDENCY_BUCKETS = [
8
+ "dependencies",
9
+ "devDependencies",
10
+ "optionalDependencies",
11
+ "peerDependencies",
12
+ ];
7
13
  const OWNER = /^[A-Za-z0-9](?:[A-Za-z0-9-]{0,37}[A-Za-z0-9])?$/;
8
14
  const REPO = /^[A-Za-z0-9._-]+$/;
9
15
  const SKELETON_FILES = [
@@ -70,6 +76,37 @@ export function parseGitHubRemote(url) {
70
76
  return null;
71
77
  }
72
78
  }
79
+ function readJson(host, path) {
80
+ const raw = host.readText(path);
81
+ if (raw === null)
82
+ return undefined;
83
+ try {
84
+ return JSON.parse(raw);
85
+ }
86
+ catch {
87
+ return undefined;
88
+ }
89
+ }
90
+ /** Tiny semver-ish compare of `a` versus `b`: -1 older, 0 equal, 1 newer. Unparseable versions are indeterminate (null). */
91
+ function compareVersions(a, b) {
92
+ const parse = (version) => {
93
+ const match = version.trim().match(/^v?(\d+)\.(\d+)\.(\d+)$/);
94
+ return match ? [Number(match[1]), Number(match[2]), Number(match[3])] : null;
95
+ };
96
+ const left = parse(a);
97
+ const right = parse(b);
98
+ if (!left || !right)
99
+ return null;
100
+ for (let index = 0; index < 3; index += 1) {
101
+ const l = left[index] ?? 0;
102
+ const r = right[index] ?? 0;
103
+ if (l < r)
104
+ return -1;
105
+ if (l > r)
106
+ return 1;
107
+ }
108
+ return 0;
109
+ }
73
110
  /** True when the marker is a v1 account-hub document. */
74
111
  export function isHubDocument(value) {
75
112
  if (!isRecord(value) || value.schemaVersion !== 1 || value.kind !== "account-hub")
@@ -144,6 +181,12 @@ function commandAvailable(host, command) {
144
181
  const result = host.run(command, ["--version"]);
145
182
  return result.status === 0;
146
183
  }
184
+ /** True when the tree already pins Advisor in some bucket, so adopt would not need a new version. */
185
+ export function hasAdvisorPin(manifest) {
186
+ if (!isRecord(manifest))
187
+ return false;
188
+ return DEPENDENCY_BUCKETS.some((bucket) => clossysNames(manifest[bucket], new Set()) !== undefined);
189
+ }
147
190
  /** Collects GitHub owner, cwd shape, default-hub presence, and the public Advisor pin. */
148
191
  export function observeWorkspace(host) {
149
192
  const cwd = host.cwd;
@@ -184,10 +227,15 @@ export function observeWorkspace(host) {
184
227
  if (viewed.status === 0)
185
228
  remoteDefaultHub = { owner: ownerGuess, repository: DEFAULT_REPOSITORY_NAME };
186
229
  }
187
- const viewedAdvisor = host.run("npm", ["view", ADVISOR_PACKAGE, "version"]);
188
- const version = viewedAdvisor.stdout.trim();
189
- if (viewedAdvisor.status === 0 && /^\d+\.\d+\.\d+$/.test(version))
190
- advisorVersion = version;
230
+ // Skip the registry read when the tree already pins Advisor in some bucket:
231
+ // adopt leaves an existing pin alone, so no live version is needed to plan it.
232
+ const manifestPinsAdvisor = hasAdvisorPin(readJson(host, join(cwd, "package.json")));
233
+ if (!manifestPinsAdvisor) {
234
+ const viewedAdvisor = host.run("npm", ["view", ADVISOR_PACKAGE, "version"]);
235
+ const version = viewedAdvisor.stdout.trim();
236
+ if (viewedAdvisor.status === 0 && /^\d+\.\d+\.\d+$/.test(version))
237
+ advisorVersion = version;
238
+ }
191
239
  const cwdObservation = {
192
240
  absolutePath: cwd,
193
241
  empty: isEffectivelyEmpty(entries),
@@ -230,22 +278,74 @@ function resolveOwner(observation, host) {
230
278
  * Decides create, resume, or adopt from a cwd observation.
231
279
  * Appointing means: run this from the GitHub repository that should own the hub.
232
280
  */
281
+ function readInventoryRepositories(host, source, label) {
282
+ const raw = host.readText(source);
283
+ if (raw === null)
284
+ return [];
285
+ try {
286
+ const parsed = JSON.parse(raw);
287
+ if (!isRecord(parsed) || !Array.isArray(parsed.repositories))
288
+ return [];
289
+ return parsed.repositories.map((entry) => {
290
+ if (isRecord(entry) && isText(entry.id))
291
+ return entry.id.trim();
292
+ return "";
293
+ });
294
+ }
295
+ catch {
296
+ throw new Error(`${label} is not readable inventory JSON (schemaVersion 1, repositories array)`);
297
+ }
298
+ }
299
+ /**
300
+ * Resolves which repositories the adopt plan inventories. When the on-disk hub
301
+ * inventory is populated AND --inventory is supplied, the two are merged by id:
302
+ * on-disk entries keep their order, ids not already on disk are appended in
303
+ * supplied-file order, and the first occurrence of an id wins; the plan carries
304
+ * the merged ids for applyWorkspacePlan to write. When both are empty or
305
+ * missing, adopt refuses rather than appointing an inventory-less hub.
306
+ */
233
307
  function resolveAdoptInventory(host, cwd, inventoryPath) {
234
- if (cwd.inventory?.status === "populated")
235
- return {};
236
308
  const trimmed = inventoryPath?.trim();
237
- if (!trimmed) {
309
+ const onDiskPopulated = cwd.inventory?.status === "populated";
310
+ if (!onDiskPopulated && !trimmed) {
238
311
  return refuse("violated", "appointing requires a populated generated hub inventory (packed template skeleton/.clossys/inventory.json; the generated path does not ship), or --inventory <path> to a populated inventory document");
239
312
  }
313
+ if (!trimmed)
314
+ return {};
240
315
  const resolved = resolve(cwd.absolutePath, trimmed);
241
316
  const imported = inspectInventory(host.readText(resolved));
242
317
  if (imported.status !== "populated") {
243
318
  return refuse("violated", "--inventory must point at a populated inventory document (schemaVersion 1, nonempty repositories)");
244
319
  }
245
- return { inventorySource: resolved };
320
+ if (!onDiskPopulated)
321
+ return { inventorySource: resolved };
322
+ const merged = [];
323
+ const seen = new Set();
324
+ for (const id of readInventoryRepositories(host, join(cwd.absolutePath, WORKSPACE_INVENTORY_REL), "the on-disk hub inventory")) {
325
+ if (id !== "" && !seen.has(id)) {
326
+ seen.add(id);
327
+ merged.push(id);
328
+ }
329
+ }
330
+ for (const id of readInventoryRepositories(host, resolved, "--inventory")) {
331
+ if (id !== "" && !seen.has(id)) {
332
+ seen.add(id);
333
+ merged.push(id);
334
+ }
335
+ }
336
+ return { mergedInventoryIds: merged };
246
337
  }
247
338
  export function planWorkspace(observation, host, options = {}) {
248
339
  const { cwd } = observation;
340
+ const envOwner = observation.envOwner ?? (host.env.CLOSSYS_OWNER?.trim() || undefined);
341
+ if (envOwner !== undefined &&
342
+ !cwd.looksLikeFoundry &&
343
+ cwd.hub === undefined &&
344
+ cwd.git &&
345
+ cwd.githubOwner !== undefined &&
346
+ cwd.githubOwner !== envOwner) {
347
+ return refuse("violated", `CLOSSYS_OWNER is "${envOwner}" but the github.com origin here is owned by "${cwd.githubOwner}"; refusing to appoint a marker for the wrong account`);
348
+ }
249
349
  if (cwd.looksLikeFoundry) {
250
350
  return refuse("violated", "refusing to scaffold a hub inside the Foundry supplier tree; run from the GitHub repository you want to appoint, or from an empty directory");
251
351
  }
@@ -272,6 +372,7 @@ export function planWorkspace(observation, host, options = {}) {
272
372
  directory: cwd.absolutePath,
273
373
  advisorVersion: observation.advisorVersion,
274
374
  ...(imported.inventorySource === undefined ? {} : { inventorySource: imported.inventorySource }),
375
+ ...(imported.mergedInventoryIds === undefined ? {} : { mergedInventoryIds: imported.mergedInventoryIds }),
275
376
  };
276
377
  }
277
378
  if (cwd.git) {
@@ -364,9 +465,8 @@ function mergeAdvisorPin(host, directory, skeletonRoot, advisorVersion, reposito
364
465
  throw new Error("existing package.json is unreadable JSON");
365
466
  }
366
467
  const extra = new Set();
367
- const inDependencies = clossysNames(manifest.dependencies, extra);
368
- const inDevDependencies = clossysNames(manifest.devDependencies, extra);
369
- if (inDependencies !== undefined || inDevDependencies !== undefined)
468
+ const pinnedSomewhere = DEPENDENCY_BUCKETS.some((bucket) => clossysNames(manifest[bucket], extra) !== undefined);
469
+ if (pinnedSomewhere)
370
470
  return;
371
471
  const devDependencies = isRecord(manifest.devDependencies) ? { ...manifest.devDependencies } : {};
372
472
  devDependencies[ADVISOR_PACKAGE] = advisorVersion;
@@ -383,7 +483,28 @@ function copySkeleton(host, skeletonRoot, plan) {
383
483
  writeSkeletonFile(host, plan.directory, "AGENTS.md", CONSUMER_AGENTS_MD);
384
484
  writeSkeletonFile(host, plan.directory, "CLAUDE.md", CONSUMER_CLAUDE_MD);
385
485
  }
486
+ /** Refuses adopt when the working tree has uncommitted changes; names a non-github.com remote host. */
487
+ function assertCleanTree(host, directory) {
488
+ const status = host.run("git", ["status", "--porcelain"], { cwd: directory });
489
+ if (status.status === 0 && status.stdout.trim() !== "") {
490
+ const origin = host.run("git", ["remote", "get-url", "origin"], { cwd: directory }).stdout.trim();
491
+ let where = "this checkout";
492
+ if (origin !== "") {
493
+ try {
494
+ const parsed = new URL(origin);
495
+ if (parsed.protocol === "ssh:" || parsed.protocol === "https:" || parsed.protocol === "http:") {
496
+ where = `the repository on ${parsed.hostname}`;
497
+ }
498
+ }
499
+ catch {
500
+ /* ssh form or unparsable; keep the generic host */
501
+ }
502
+ }
503
+ throw new Error(`${where} has uncommitted changes (git status --porcelain is nonempty); commit or stash them before appointing it as the account hub`);
504
+ }
505
+ }
386
506
  function adoptHubFiles(host, skeletonRoot, plan) {
507
+ assertCleanTree(host, plan.directory);
387
508
  const marker = {
388
509
  schemaVersion: 1,
389
510
  kind: "account-hub",
@@ -391,7 +512,11 @@ function adoptHubFiles(host, skeletonRoot, plan) {
391
512
  repository: `${plan.owner}/${plan.repository}`,
392
513
  };
393
514
  writeSkeletonFile(host, plan.directory, WORKSPACE_MARKER_REL, `${JSON.stringify(marker, null, 2)}\n`);
394
- if ("inventorySource" in plan && typeof plan.inventorySource === "string") {
515
+ if ("mergedInventoryIds" in plan && Array.isArray(plan.mergedInventoryIds)) {
516
+ const document = { schemaVersion: 1, repositories: plan.mergedInventoryIds.map((id) => ({ id })) };
517
+ writeSkeletonFile(host, plan.directory, WORKSPACE_INVENTORY_REL, `${JSON.stringify(document, null, 2)}\n`);
518
+ }
519
+ else if ("inventorySource" in plan && typeof plan.inventorySource === "string") {
395
520
  const raw = host.readText(plan.inventorySource);
396
521
  if (raw === null || inspectInventory(raw).status !== "populated") {
397
522
  throw new Error("inventory source is not a populated inventory document");
@@ -421,55 +546,116 @@ function requireZero(result, label) {
421
546
  throw new Error(`${label} failed (${result.status}): ${result.stderr.trim() || result.stdout.trim() || "no output"}`);
422
547
  }
423
548
  }
424
- /** Read-only pin and inventory report. Does not install or uninstall. */
549
+ /**
550
+ * Read-only pin and inventory report. Does not install or uninstall. Scans all
551
+ * four dependency buckets; grades each pinned advisor version against the live
552
+ * registry version, marking a pin older than live as a stale-pin finding and a
553
+ * degraded report.
554
+ */
425
555
  export function reportHubHealth(host, directory, liveAdvisorVersion) {
426
556
  const extra = new Set();
427
- let dependencies;
428
- let devDependencies;
557
+ const pins = {};
429
558
  const manifestRaw = host.readText(join(directory, "package.json"));
430
559
  if (manifestRaw !== null) {
431
560
  try {
432
561
  const parsed = JSON.parse(manifestRaw);
433
562
  if (isRecord(parsed)) {
434
- dependencies = clossysNames(parsed.dependencies, extra);
435
- devDependencies = clossysNames(parsed.devDependencies, extra);
563
+ for (const bucket of DEPENDENCY_BUCKETS) {
564
+ const pin = clossysNames(parsed[bucket], extra);
565
+ if (pin !== undefined)
566
+ pins[bucket] = pin;
567
+ }
436
568
  }
437
569
  }
438
570
  catch {
439
571
  /* unreadable manifest is reported as missing pins */
440
572
  }
441
573
  }
574
+ const pinFindings = Object.entries(pins).flatMap(([bucket, pinned]) => {
575
+ if (liveAdvisorVersion === undefined)
576
+ return [];
577
+ const comparison = compareVersions(pinned, liveAdvisorVersion);
578
+ if (comparison === null) {
579
+ return [{ bucket: bucket, pinned, grade: "indeterminate", note: `cannot compare ${pinned} with live ${liveAdvisorVersion}` }];
580
+ }
581
+ return comparison < 0
582
+ ? [{ bucket: bucket, pinned, grade: "stale", note: `pinned ${pinned} is older than live ${liveAdvisorVersion}` }]
583
+ : [];
584
+ });
442
585
  return {
443
586
  marker: readHub(host, directory) === undefined ? "missing" : "present",
444
587
  inventory: inspectInventory(host.readText(join(directory, WORKSPACE_INVENTORY_REL))),
445
588
  advisorPin: {
446
- ...(dependencies === undefined ? {} : { dependencies }),
447
- ...(devDependencies === undefined ? {} : { devDependencies }),
589
+ ...(pins.dependencies === undefined ? {} : { dependencies: pins.dependencies }),
590
+ ...(pins.devDependencies === undefined ? {} : { devDependencies: pins.devDependencies }),
591
+ ...(pins.optionalDependencies === undefined ? {} : { optionalDependencies: pins.optionalDependencies }),
592
+ ...(pins.peerDependencies === undefined ? {} : { peerDependencies: pins.peerDependencies }),
448
593
  ...(liveAdvisorVersion === undefined ? {} : { live: liveAdvisorVersion }),
449
594
  },
450
- dualPin: dependencies !== undefined && devDependencies !== undefined,
595
+ dualPin: Object.values(pins).filter((value) => value !== undefined).length > 1,
451
596
  extraClossys: [...extra].sort(),
597
+ pinFindings,
598
+ degraded: pinFindings.some((finding) => finding.grade === "stale"),
452
599
  };
453
600
  }
454
601
  export function formatHubHealth(report) {
455
602
  const pinParts = [];
456
- if (report.advisorPin.dependencies !== undefined)
457
- pinParts.push(`dependencies ${report.advisorPin.dependencies}`);
458
- if (report.advisorPin.devDependencies !== undefined)
459
- pinParts.push(`devDependencies ${report.advisorPin.devDependencies}`);
603
+ for (const bucket of DEPENDENCY_BUCKETS) {
604
+ const pinned = report.advisorPin[bucket];
605
+ if (pinned !== undefined)
606
+ pinParts.push(`${bucket} ${pinned}`);
607
+ }
460
608
  const pin = pinParts.length === 0 ? "missing" : pinParts.join(" and ");
461
609
  const live = report.advisorPin.live === undefined ? "" : `; live ${report.advisorPin.live}`;
462
610
  const extra = report.extraClossys.length === 0 ? "none" : report.extraClossys.join(", ");
463
611
  const inventory = report.inventory.status === "populated" ? `populated (${report.inventory.count})` : report.inventory.status;
612
+ const findings = report.pinFindings.map((finding) => finding.note !== undefined ? `${finding.bucket} ${finding.note}` : `${finding.bucket} ${finding.grade}`);
613
+ const findingLine = findings.length === 0 ? "none" : findings.join("; ");
464
614
  return [
465
615
  `hub marker: ${report.marker}`,
466
616
  `inventory: ${inventory}`,
467
617
  `advisor pin: ${pin}${live}`,
468
618
  `dual pin: ${report.dualPin ? "yes" : "no"}`,
469
619
  `extra @clossys/*: ${extra}`,
620
+ `pin findings: ${findingLine}`,
621
+ `degraded: ${report.degraded ? "yes" : "no"}`,
470
622
  `health: ${JSON.stringify(report)}`,
471
623
  ].join("\n");
472
624
  }
625
+ /**
626
+ * Read-only inventory validation: runs `gh repo view --json name` for each
627
+ * repository id, batched. Tolerates a missing or failing `gh` by skipping with
628
+ * a note; marks ids whose check fails as unknown. Never mutates the inventory.
629
+ */
630
+ export function checkInventoryEntries(host, directory) {
631
+ const raw = host.readText(join(directory, WORKSPACE_INVENTORY_REL));
632
+ const observation = inspectInventory(raw);
633
+ if (observation.status !== "populated") {
634
+ return { entries: [], skipped: true, note: `inventory is ${observation.status}; nothing to validate` };
635
+ }
636
+ const available = commandAvailable(host, "gh");
637
+ if (!available) {
638
+ return { entries: [], skipped: true, note: "`gh` is unavailable; inventory ids were not validated" };
639
+ }
640
+ const ids = readInventoryRepositories(host, join(directory, WORKSPACE_INVENTORY_REL), "the hub inventory").filter((id) => id !== "");
641
+ const batch = 20;
642
+ const entries = [];
643
+ for (let index = 0; index < ids.length; index += batch) {
644
+ for (const id of ids.slice(index, index + batch)) {
645
+ const viewed = host.run("gh", ["repo", "view", id, "--json", "name"]);
646
+ if (viewed.status === 0) {
647
+ entries.push({ id, known: true });
648
+ }
649
+ else if (viewed.status === 127 || (viewed.status === null && viewed.stderr.includes("ENOENT"))) {
650
+ entries.push({ id, known: null, note: "`gh` unavailable; not checked" });
651
+ }
652
+ else {
653
+ entries.push({ id, known: false, note: "`gh repo view` failed; the repository may not exist" });
654
+ }
655
+ }
656
+ }
657
+ return { entries, skipped: false };
658
+ }
473
659
  function withHealth(host, directory, headline, liveAdvisorVersion) {
474
660
  const health = reportHubHealth(host, directory, liveAdvisorVersion);
475
661
  return {