@clossys/launcher 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,27 @@
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.1.1] - 2026-09-19
9
+
10
+ ### Fixed
11
+
12
+ - 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.
13
+ - 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.
14
+
15
+ ### Added
16
+
17
+ - 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.
18
+
19
+ ## [0.1.0] - 2026-09-18
20
+
21
+ ### Added
22
+
23
+ - `npx @clossys/launcher` as the single get-started command.
24
+ - In-package hub skeleton (not a Foundry fork) copied into a GitHub repository.
25
+ - Create a new `{owner}/workspace` hub, resume an existing hub, or adopt the current GitHub repository as the account hub.
26
+ - Owner inference from `gh` and git remotes, with an interactive picker only when more than one GitHub owner is visible.
27
+ - `launcher-check --input` grades a captured observation without creating a hub, so qualification can prove the 0/1/2 ternary.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Clossys
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,132 @@
1
+ # Foundry Launcher
2
+
3
+ Foundry Launcher (`@clossys/launcher`) is executable tooling
4
+ that makes one GitHub repository the account workspace hub. It is not a role
5
+ and does not claim adoption, grounding, or closure.
6
+
7
+ The hub inventories where Foundry packages are installed and coordinates
8
+ engagement. It is not a product application and does not receive a dump of
9
+ the catalogue.
10
+
11
+ ## Install
12
+
13
+ The get-started command is the package name:
14
+
15
+ ```bash
16
+ npx @clossys/launcher
17
+ ```
18
+
19
+ Public npm reads are credentialless. Packages publish to
20
+ `https://registry.npmjs.org`. Do not add a token or private registry
21
+ mapping for `@clossys`. Pin an exact version once you depend on the library
22
+ API:
23
+
24
+ ```bash
25
+ npm install --save-dev --save-exact @clossys/launcher@0.1.1
26
+ ```
27
+
28
+ ## How to run it
29
+
30
+ There is no `--org` flag. Owner is inferred from authenticated `gh` and from
31
+ the current git remote. If more than one GitHub owner is visible, the
32
+ command asks which one should hold the hub. Non-interactive runs may set
33
+ `CLOSSYS_OWNER`.
34
+
35
+ GitHub-only. A GitLab, self-hosted, or other remote is a refusal, not a
36
+ silent fallback.
37
+
38
+ | Current directory | What happens |
39
+ | --- | --- |
40
+ | 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. |
43
+
44
+ It does not have to be a brand-new exclusive repository, and it does not
45
+ have to already match a Foundry layout. Informal "workspace-looking" trees
46
+ are appointed by writing the hub contract, not assumed to be hubs already.
47
+ Product applications may be appointed: they become the hub **and** remain
48
+ the product. Sister repositories still pin their own roles. Appoint does
49
+ not install packages.
50
+
51
+ Do not run this inside the Foundry supplier tree.
52
+
53
+ Open the resulting folder in your coding agent. Advisor stays read-only
54
+ until you approve a next action. The same command resumes later.
55
+
56
+ ## CLI
57
+
58
+ ```bash
59
+ launcher
60
+ launcher --inventory path/to/inventory.json
61
+ launcher --help
62
+ launcher-check --help
63
+ launcher-check --input observation.json
64
+ ```
65
+
66
+ Exit codes preserve the ternary:
67
+
68
+ | Exit | State | Meaning |
69
+ | --- | --- | --- |
70
+ | `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. |
72
+ | `2` | `indeterminate` | Missing `gh`, unreadable registry pin, or an owner that could not be inferred. |
73
+
74
+ `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.
75
+
76
+ ## API
77
+
78
+ | Export | Description |
79
+ | --- | --- |
80
+ | `planWorkspace()` | Decides create, resume, or adopt from a cwd observation. Optional `{ inventoryPath }` is the only way to appoint without a populated on-disk inventory. |
81
+ | `applyWorkspacePlan()` | Copies the in-package skeleton or hub marker through a host port and returns a `WorkspaceApplyResult` with health. Resume does not write. |
82
+ | `observeWorkspace()` | Reads `gh`, git remotes, cwd, inventory classification, and the public Advisor version. |
83
+ | `parseGitHubRemote()` | Parses a github.com remote and rejects any other host. |
84
+ | `isHubDocument()` | Type guard for the generated hub marker (packed template: `skeleton/.clossys/workspace.json`). |
85
+ | `inspectInventory()` | Classifies inventory JSON as missing, empty, or populated. |
86
+ | `reportHubHealth()` | Read-only pin and inventory report. Does not install or uninstall. |
87
+ | `formatHubHealth()` | Human lines plus a `health:` JSON line for the same report. |
88
+ | `DEFAULT_REPOSITORY_NAME` | Default new-hub repository name (`workspace`). Used only when creating, never when appointing. |
89
+ | `WORKSPACE_MARKER_REL` | Relative path of the hub marker. |
90
+ | `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. |
92
+
93
+ ## Why this is not Advisor, Starter, Builder, installer, creator, or a connector
94
+
95
+ Advisor is the engagement engine: it grades evidence and names a next
96
+ action. It has no GitHub I/O, and must not grow any. A remote chat
97
+ connector is a separately deployed product surface for that engine, not a
98
+ repo scaffolder.
99
+
100
+ Starter (`@clossys/starter`) is the protected-base **activation** gate.
101
+ Its only v1 subcommand is `decide`. It joins a pull-request snapshot to
102
+ fixed install evidence, Advisor readiness, and one target CLI. It refuses
103
+ commands, shell, and caller-selected paths. That is why get-started is not
104
+ `npx @clossys/starter`: a no-argument Starter invocation that created a
105
+ GitHub repository would be a contract break, and stuffing `gh repo create`
106
+ into `foundry-starter decide` would be the same defect. Starter starts the
107
+ trusted-base **loop in CI**, after a hub and a workflow already exist. It
108
+ does not start the human.
109
+
110
+ Builder realizes declared live state later in operating control. A new
111
+ hub has no declared topology yet.
112
+
113
+ This package is not named installer: an install is not adoption, Starter
114
+ already owns install-evidence joins, and the hub must not dump the
115
+ catalogue. It is not named creator: that reads as a role. Launcher is the
116
+ get-started bin that puts a hub on disk so a coding agent can open it.
117
+
118
+ This package exists because `npx` runs a **package name**. Step 0 is a
119
+ bin and a skeleton, not a role. It stays executable tooling so Starter's
120
+ `decide` contract, Advisor's engine boundary, and Builder's loop stay
121
+ intact.
122
+
123
+ ## Requirements
124
+
125
+ Node.js 20+, ESM, GitHub `gh`, and no runtime dependencies. Creating a new
126
+ hub needs permission to create a private repository under the inferred
127
+ owner. Appointing uses the current checkout and does not create a second
128
+ repository.
129
+
130
+ ## Licence
131
+
132
+ MIT.
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ import type { WorkspaceHost, WorkspaceObservation } from "./types.js";
3
+ export declare const CHECK_USAGE = "Usage: launcher-check --input <observation.json>\n\nGrade a captured workspace observation through planWorkspace. This bin does\nnot create, resume, or appoint a hub.\n\nExit codes: 0 = a create, resume, or adopt plan, 1 = a known refusal,\n2 = indeterminate or the input could not be read.";
4
+ export declare class LauncherCheckInputError extends Error {
5
+ }
6
+ export declare function parseObservation(value: unknown): WorkspaceObservation;
7
+ /** Host used only for owner prompting. Grading never creates a hub. */
8
+ export declare function planningHost(): WorkspaceHost;
9
+ export declare function parseCheckArgs(argv: readonly string[]): {
10
+ help: boolean;
11
+ inputPath?: string;
12
+ };
13
+ export declare function checkMain(argv: readonly string[], readText: (path: string) => string, writeOut: (text: string) => void, writeErr: (text: string) => void): number;
14
+ //# sourceMappingURL=check-cli.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,161 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync } from "node:fs";
3
+ import { resolve } from "node:path";
4
+ import { isDirectInvocation } from "./cli.js";
5
+ import { planWorkspace } from "./core.js";
6
+ export const CHECK_USAGE = `Usage: launcher-check --input <observation.json>
7
+
8
+ Grade a captured workspace observation through planWorkspace. This bin does
9
+ not create, resume, or appoint a hub.
10
+
11
+ Exit codes: 0 = a create, resume, or adopt plan, 1 = a known refusal,
12
+ 2 = indeterminate or the input could not be read.`;
13
+ export class LauncherCheckInputError extends Error {
14
+ }
15
+ function isRecord(value) {
16
+ return typeof value === "object" && value !== null && !Array.isArray(value);
17
+ }
18
+ function isText(value) {
19
+ return typeof value === "string" && value.trim() !== "";
20
+ }
21
+ function parseInventoryObservation(value) {
22
+ if (value === undefined)
23
+ return undefined;
24
+ if (!isRecord(value)) {
25
+ throw new LauncherCheckInputError("observation.cwd.inventory must be an object");
26
+ }
27
+ if (value.status !== "missing" && value.status !== "empty" && value.status !== "populated") {
28
+ throw new LauncherCheckInputError("observation.cwd.inventory.status must be missing, empty, or populated");
29
+ }
30
+ if (typeof value.count !== "number" || !Number.isInteger(value.count) || value.count < 0) {
31
+ throw new LauncherCheckInputError("observation.cwd.inventory.count must be a nonnegative integer");
32
+ }
33
+ return { status: value.status, count: value.count };
34
+ }
35
+ function parseCwd(value) {
36
+ if (!isRecord(value) || !isText(value.absolutePath)) {
37
+ throw new LauncherCheckInputError("observation.cwd.absolutePath must be a nonempty string");
38
+ }
39
+ if (typeof value.empty !== "boolean" || typeof value.git !== "boolean" || typeof value.looksLikeFoundry !== "boolean") {
40
+ throw new LauncherCheckInputError("observation.cwd must declare empty, git, and looksLikeFoundry booleans");
41
+ }
42
+ if (value.githubOwner !== undefined && !isText(value.githubOwner)) {
43
+ throw new LauncherCheckInputError("observation.cwd.githubOwner must be a string");
44
+ }
45
+ if (value.githubRepository !== undefined && !isText(value.githubRepository)) {
46
+ throw new LauncherCheckInputError("observation.cwd.githubRepository must be a string");
47
+ }
48
+ const inventory = parseInventoryObservation(value.inventory);
49
+ return {
50
+ absolutePath: value.absolutePath,
51
+ empty: value.empty,
52
+ git: value.git,
53
+ looksLikeFoundry: value.looksLikeFoundry,
54
+ ...(isText(value.githubOwner) ? { githubOwner: value.githubOwner } : {}),
55
+ ...(isText(value.githubRepository) ? { githubRepository: value.githubRepository } : {}),
56
+ ...(inventory === undefined ? {} : { inventory }),
57
+ };
58
+ }
59
+ export function parseObservation(value) {
60
+ if (!isRecord(value))
61
+ throw new LauncherCheckInputError("observation must be a JSON object");
62
+ if (!Array.isArray(value.ownerCandidates) || value.ownerCandidates.some((item) => typeof item !== "string")) {
63
+ throw new LauncherCheckInputError("observation.ownerCandidates must be an array of strings");
64
+ }
65
+ if (typeof value.ghAvailable !== "boolean" || typeof value.gitAvailable !== "boolean") {
66
+ throw new LauncherCheckInputError("observation must declare ghAvailable and gitAvailable booleans");
67
+ }
68
+ if (value.envOwner !== undefined && !isText(value.envOwner)) {
69
+ throw new LauncherCheckInputError("observation.envOwner must be a string");
70
+ }
71
+ if (value.advisorVersion !== undefined && !isText(value.advisorVersion)) {
72
+ throw new LauncherCheckInputError("observation.advisorVersion must be a string");
73
+ }
74
+ return {
75
+ cwd: parseCwd(value.cwd),
76
+ ownerCandidates: value.ownerCandidates,
77
+ ghAvailable: value.ghAvailable,
78
+ gitAvailable: value.gitAvailable,
79
+ ...(isText(value.envOwner) ? { envOwner: value.envOwner } : {}),
80
+ ...(isText(value.advisorVersion) ? { advisorVersion: value.advisorVersion } : {}),
81
+ };
82
+ }
83
+ function unused() {
84
+ return { status: 1, stdout: "", stderr: "launcher-check does not run host commands" };
85
+ }
86
+ /** Host used only for owner prompting. Grading never creates a hub. */
87
+ export function planningHost() {
88
+ return {
89
+ cwd: "/",
90
+ env: {},
91
+ isTTY: false,
92
+ now: () => "1970-01-01T00:00:00.000Z",
93
+ exists: () => false,
94
+ isDirectory: () => false,
95
+ readText: () => null,
96
+ writeText: () => {
97
+ throw new Error("launcher-check does not write");
98
+ },
99
+ mkdirp: () => {
100
+ throw new Error("launcher-check does not write");
101
+ },
102
+ readDir: () => [],
103
+ run: () => unused(),
104
+ prompt: () => null,
105
+ };
106
+ }
107
+ export function parseCheckArgs(argv) {
108
+ if (argv.length === 0)
109
+ return { help: true };
110
+ if (argv.length === 1 && (argv[0] === "--help" || argv[0] === "-h"))
111
+ return { help: true };
112
+ if (argv.length === 2 && argv[0] === "--input" && argv[1])
113
+ return { help: false, inputPath: argv[1] };
114
+ throw new LauncherCheckInputError("expected --input <observation.json>, or --help");
115
+ }
116
+ export function checkMain(argv, readText, writeOut, writeErr) {
117
+ const parsed = parseCheckArgs(argv);
118
+ if (parsed.help) {
119
+ writeOut(`${CHECK_USAGE}\n`);
120
+ return 0;
121
+ }
122
+ const inputPath = parsed.inputPath;
123
+ if (inputPath === undefined)
124
+ throw new LauncherCheckInputError("expected --input <observation.json>");
125
+ let raw;
126
+ try {
127
+ raw = readText(resolve(inputPath));
128
+ }
129
+ catch {
130
+ throw new LauncherCheckInputError(`cannot read ${inputPath}`);
131
+ }
132
+ let parsedJson;
133
+ try {
134
+ parsedJson = JSON.parse(raw);
135
+ }
136
+ catch {
137
+ throw new LauncherCheckInputError(`${inputPath} is not JSON`);
138
+ }
139
+ const observation = parseObservation(parsedJson);
140
+ const decision = planWorkspace(observation, planningHost());
141
+ if (decision.action === "refuse") {
142
+ writeErr(`launcher-check: ${decision.message}\n`);
143
+ return decision.state === "violated" ? 1 : 2;
144
+ }
145
+ writeOut(`${JSON.stringify({ action: decision.action, owner: decision.owner, repository: decision.repository })}\n`);
146
+ return 0;
147
+ }
148
+ if (isDirectInvocation(import.meta.url, process.argv[1])) {
149
+ try {
150
+ process.exitCode = checkMain(process.argv.slice(2), (path) => readFileSync(path, "utf8"), (text) => {
151
+ process.stdout.write(text);
152
+ }, (text) => {
153
+ process.stderr.write(text);
154
+ });
155
+ }
156
+ catch (cause) {
157
+ process.stderr.write(`launcher-check: ${cause instanceof Error ? cause.message : String(cause)}\n`);
158
+ process.exitCode = 2;
159
+ }
160
+ }
161
+ //# sourceMappingURL=check-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-cli.js","sourceRoot":"","sources":["../src/check-cli.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ import type { WorkspaceHost } from "./types.js";
3
+ export declare const USAGE = "Usage: launcher [--inventory <path>]\n\nCreate, resume, or appoint a GitHub repository as the account workspace hub.\n\nRun from an empty directory to create {owner}/workspace. Run from an existing\nhub to resume. Run from any GitHub repository you want to own the account-level\nhub to appoint it \u2014 it does not have to be a new exclusive repo, and it keeps\nits current name and files.\n\nAppointing requires a populated generated hub inventory (packed template\nskeleton/.clossys/inventory.json; the generated path does not ship), or\n--inventory <path> pointing at one. Resume does not write. Create may write\nan empty inventory.\n\nGitHub-only. Owner is inferred from `gh` and git remotes. Public npm reads\nneed no token.\n\nExit codes: 0 = satisfied, 1 = a known refusal, 2 = indeterminate.";
4
+ export declare class LauncherInputError extends Error {
5
+ }
6
+ export declare function parseLauncherArgs(argv: readonly string[]): {
7
+ help: boolean;
8
+ inventoryPath?: string;
9
+ };
10
+ /** Testable CLI dispatcher. Unknown arguments throw; the executable maps them to exit 2. */
11
+ export declare function main(argv: readonly string[], host: WorkspaceHost, skeletonRoot: string): number;
12
+ /** Resolves an npm/POSIX bin symlink before deciding whether this module is the entrypoint. */
13
+ export declare function isDirectInvocation(moduleUrl: string, argvPath: string | undefined): boolean;
14
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +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"}
package/dist/cli.js ADDED
@@ -0,0 +1,90 @@
1
+ #!/usr/bin/env node
2
+ import { realpathSync } from "node:fs";
3
+ import { resolve } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { applyWorkspacePlan, observeWorkspace, planWorkspace, skeletonRootFromModule } from "./core.js";
6
+ import { createNodeHost } from "./host.js";
7
+ export const USAGE = `Usage: launcher [--inventory <path>]
8
+
9
+ Create, resume, or appoint a GitHub repository as the account workspace hub.
10
+
11
+ Run from an empty directory to create {owner}/workspace. Run from an existing
12
+ hub to resume. Run from any GitHub repository you want to own the account-level
13
+ hub to appoint it — it does not have to be a new exclusive repo, and it keeps
14
+ its current name and files.
15
+
16
+ Appointing requires a populated generated hub inventory (packed template
17
+ skeleton/.clossys/inventory.json; the generated path does not ship), or
18
+ --inventory <path> pointing at one. Resume does not write. Create may write
19
+ an empty inventory.
20
+
21
+ GitHub-only. Owner is inferred from \`gh\` and git remotes. Public npm reads
22
+ need no token.
23
+
24
+ Exit codes: 0 = satisfied, 1 = a known refusal, 2 = indeterminate.`;
25
+ export class LauncherInputError extends Error {
26
+ }
27
+ function exitCodeFor(state) {
28
+ return state === "satisfied" ? 0 : state === "violated" ? 1 : 2;
29
+ }
30
+ export function parseLauncherArgs(argv) {
31
+ if (argv.length === 1 && (argv[0] === "--help" || argv[0] === "-h"))
32
+ return { help: true };
33
+ if (argv.length === 0)
34
+ return { help: false };
35
+ if (argv.length === 2 && argv[0] === "--inventory" && argv[1])
36
+ return { help: false, inventoryPath: argv[1] };
37
+ throw new LauncherInputError("launcher takes no arguments except optional --inventory <path>; run it from the directory to create or appoint");
38
+ }
39
+ /** Testable CLI dispatcher. Unknown arguments throw; the executable maps them to exit 2. */
40
+ export function main(argv, host, skeletonRoot) {
41
+ const parsed = parseLauncherArgs(argv);
42
+ if (parsed.help) {
43
+ console.log(USAGE);
44
+ return 0;
45
+ }
46
+ const observation = observeWorkspace(host);
47
+ if (!observation.cwd.empty &&
48
+ !observation.cwd.git &&
49
+ observation.cwd.hub === undefined &&
50
+ !observation.cwd.looksLikeFoundry) {
51
+ console.log(USAGE);
52
+ return 0;
53
+ }
54
+ const decision = planWorkspace(observation, host, { inventoryPath: parsed.inventoryPath });
55
+ if (decision.action === "refuse") {
56
+ console.error(`launcher: ${decision.message}`);
57
+ return exitCodeFor(decision.state);
58
+ }
59
+ if (parsed.inventoryPath !== undefined && decision.action !== "adopt") {
60
+ console.error("launcher: --inventory is only valid when appointing a GitHub repository");
61
+ return 1;
62
+ }
63
+ const result = applyWorkspacePlan(host, decision, skeletonRoot);
64
+ console.log(result.message);
65
+ return 0;
66
+ }
67
+ function run() {
68
+ try {
69
+ const host = createNodeHost();
70
+ process.exitCode = main(process.argv.slice(2), host, skeletonRootFromModule(import.meta.url));
71
+ }
72
+ catch (cause) {
73
+ console.error(`launcher: ${cause instanceof Error ? cause.message : String(cause)}`);
74
+ process.exitCode = 2;
75
+ }
76
+ }
77
+ /** Resolves an npm/POSIX bin symlink before deciding whether this module is the entrypoint. */
78
+ export function isDirectInvocation(moduleUrl, argvPath) {
79
+ if (argvPath === undefined)
80
+ return false;
81
+ try {
82
+ return realpathSync(fileURLToPath(moduleUrl)) === realpathSync(resolve(argvPath));
83
+ }
84
+ catch {
85
+ return false;
86
+ }
87
+ }
88
+ if (isDirectInvocation(import.meta.url, process.argv[1]))
89
+ run();
90
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AACxG,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAG3C,MAAM,CAAC,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;;;mEAiB8C,CAAC;AAEpE,MAAM,OAAO,kBAAmB,SAAQ,KAAK;CAAG;AAEhD,SAAS,WAAW,CAAC,KAAiD;IACpE,OAAO,KAAK,KAAK,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAuB;IACvD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAC3F,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IAC9C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,aAAa,IAAI,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9G,MAAM,IAAI,kBAAkB,CAAC,gHAAgH,CAAC,CAAC;AACjJ,CAAC;AAED,4FAA4F;AAC5F,MAAM,UAAU,IAAI,CAAC,IAAuB,EAAE,IAAmB,EAAE,YAAoB;IACrF,MAAM,MAAM,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACvC,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnB,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,WAAW,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC3C,IACE,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK;QACtB,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG;QACpB,WAAW,CAAC,GAAG,CAAC,GAAG,KAAK,SAAS;QACjC,CAAC,WAAW,CAAC,GAAG,CAAC,gBAAgB,EACjC,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnB,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,QAAQ,GAAG,aAAa,CAAC,WAAW,EAAE,IAAI,EAAE,EAAE,aAAa,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC;IAC3F,IAAI,QAAQ,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QACjC,OAAO,CAAC,KAAK,CAAC,aAAa,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;QAC/C,OAAO,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC;IACD,IAAI,MAAM,CAAC,aAAa,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;QACtE,OAAO,CAAC,KAAK,CAAC,yEAAyE,CAAC,CAAC;QACzF,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,MAAM,GAAG,kBAAkB,CAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;IAChE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC5B,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,GAAG;IACV,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,cAAc,EAAE,CAAC;QAC9B,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,sBAAsB,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAChG,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,aAAa,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACrF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC;AACH,CAAC;AAED,+FAA+F;AAC/F,MAAM,UAAU,kBAAkB,CAAC,SAAiB,EAAE,QAA4B;IAChF,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACzC,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,KAAK,YAAY,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IACpF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,IAAI,kBAAkB,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAAE,GAAG,EAAE,CAAC"}
package/dist/core.d.ts ADDED
@@ -0,0 +1,29 @@
1
+ import type { HubDocument, HubHealthReport, InventoryObservation, WorkspaceApplyResult, WorkspaceDecision, WorkspaceHost, WorkspaceObservation, WorkspacePlan } from "./types.js";
2
+ export declare const DEFAULT_REPOSITORY_NAME = "workspace";
3
+ export declare const WORKSPACE_MARKER_REL = ".clossys/workspace.json";
4
+ export declare const WORKSPACE_INVENTORY_REL = ".clossys/inventory.json";
5
+ export declare const ADVISOR_PACKAGE = "@clossys/advisor";
6
+ /** Written at generate time so this package never ships a nested AGENTS.md. */
7
+ export declare const CONSUMER_AGENTS_MD = "# Account workspace\n\nThis repository is the account hub for Foundry packages. It inventories\nwhere packages are installed and coordinates engagement. It is not a\nproduct application and does not need the whole catalogue installed here.\n\nOpen this folder in your coding agent. Advisor is read-only until you\napprove a next action.\n\nRun `npx @clossys/launcher` again to resume. Public npm reads\nneed no token.\n";
8
+ export declare const CONSUMER_CLAUDE_MD = "@AGENTS.md\n";
9
+ /** Parses a GitHub git remote. Any other host is rejected. */
10
+ export declare function parseGitHubRemote(url: string): {
11
+ owner: string;
12
+ repository: string;
13
+ } | null;
14
+ /** True when the marker is a v1 account-hub document. */
15
+ export declare function isHubDocument(value: unknown): value is HubDocument;
16
+ /** Classifies a generated hub inventory (packed template skeleton/.clossys/inventory.json; the generated path does not ship) without inventing repositories. */
17
+ export declare function inspectInventory(raw: string | null): InventoryObservation;
18
+ /** Collects GitHub owner, cwd shape, default-hub presence, and the public Advisor pin. */
19
+ export declare function observeWorkspace(host: WorkspaceHost): WorkspaceObservation;
20
+ export declare function planWorkspace(observation: WorkspaceObservation, host: WorkspaceHost, options?: {
21
+ inventoryPath?: string;
22
+ }): WorkspaceDecision;
23
+ /** Read-only pin and inventory report. Does not install or uninstall. */
24
+ export declare function reportHubHealth(host: WorkspaceHost, directory: string, liveAdvisorVersion?: string): HubHealthReport;
25
+ export declare function formatHubHealth(report: HubHealthReport): string;
26
+ /** Applies a create, resume, or adopt plan through the host. Resume does not write. */
27
+ export declare function applyWorkspacePlan(host: WorkspaceHost, plan: WorkspacePlan, skeletonRoot: string): WorkspaceApplyResult;
28
+ export declare function skeletonRootFromModule(moduleUrl: string): string;
29
+ //# sourceMappingURL=core.d.ts.map
@@ -0,0 +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"}