@clossys/launcher 0.1.5 → 0.3.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.
- package/CHANGELOG.md +67 -0
- package/README.md +209 -20
- package/contracts/conversation-contract.md +40 -0
- package/dist/apply-plan-cli.d.ts +7 -0
- package/dist/apply-plan-cli.d.ts.map +1 -0
- package/dist/apply-plan-cli.js +96 -0
- package/dist/apply-plan-cli.js.map +1 -0
- package/dist/apply-plan.d.ts +79 -0
- package/dist/apply-plan.d.ts.map +1 -0
- package/dist/apply-plan.js +129 -0
- package/dist/apply-plan.js.map +1 -0
- package/dist/check-cli.d.ts.map +1 -1
- package/dist/check-cli.js +3 -0
- package/dist/check-cli.js.map +1 -1
- package/dist/cli.d.ts +2 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +37 -11
- package/dist/cli.js.map +1 -1
- package/dist/contract.d.ts +28 -0
- package/dist/contract.d.ts.map +1 -0
- package/dist/contract.js +78 -0
- package/dist/contract.js.map +1 -0
- package/dist/core.d.ts +38 -6
- package/dist/core.d.ts.map +1 -1
- package/dist/core.js +289 -42
- package/dist/core.js.map +1 -1
- package/dist/doctor-cli.d.ts +4 -0
- package/dist/doctor-cli.d.ts.map +1 -0
- package/dist/doctor-cli.js +32 -0
- package/dist/doctor-cli.js.map +1 -0
- package/dist/doctor.d.ts +28 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +68 -0
- package/dist/doctor.js.map +1 -0
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +3 -0
- package/dist/host.js.map +1 -1
- package/dist/hosts.d.ts +14 -0
- package/dist/hosts.d.ts.map +1 -0
- package/dist/hosts.js +61 -0
- package/dist/hosts.js.map +1 -0
- package/dist/index.d.ts +15 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/inventory-adoption.d.ts +20 -0
- package/dist/inventory-adoption.d.ts.map +1 -0
- package/dist/inventory-adoption.js +67 -0
- package/dist/inventory-adoption.js.map +1 -0
- package/dist/manifest.d.ts +20 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +106 -0
- package/dist/manifest.js.map +1 -0
- package/dist/model-profile.d.ts +46 -0
- package/dist/model-profile.d.ts.map +1 -0
- package/dist/model-profile.js +98 -0
- package/dist/model-profile.js.map +1 -0
- package/dist/product-repository.d.ts +26 -0
- package/dist/product-repository.d.ts.map +1 -0
- package/dist/product-repository.js +49 -0
- package/dist/product-repository.js.map +1 -0
- package/dist/skills.d.ts +20 -1
- package/dist/skills.d.ts.map +1 -1
- package/dist/skills.js +98 -7
- package/dist/skills.js.map +1 -1
- package/dist/types.d.ts +57 -1
- package/dist/types.d.ts.map +1 -1
- package/model-profiles/claude-code.json +10 -0
- package/model-profiles/codex.json +10 -0
- package/model-profiles/cursor.json +10 -0
- package/package.json +9 -4
- package/skeleton/README.md +5 -0
- package/skeleton/package.json +1 -1
- package/skill/SKILL.md +53 -0
- package/skill-catalogue/advisor/SKILL.md +3 -1
- package/skill-catalogue/controller/SKILL.md +8 -0
- package/skill-catalogue/customer/SKILL.md +92 -0
- package/skill-catalogue/designer/SKILL.md +18 -2
- package/skill-catalogue/inspector/SKILL.md +1 -1
- package/skill-catalogue/publisher/SKILL.md +17 -3
- package/skill-catalogue/strategist/SKILL.md +37 -3
- package/skill-catalogue/writer/SKILL.md +7 -2
- package/src/apply-plan-cli.ts +94 -0
- package/src/apply-plan.ts +172 -0
- package/src/check-cli.ts +3 -0
- package/src/cli.ts +45 -10
- package/src/contract.ts +81 -0
- package/src/core.ts +337 -37
- package/src/doctor-cli.ts +33 -0
- package/src/doctor.ts +145 -0
- package/src/host.ts +3 -0
- package/src/hosts.ts +79 -0
- package/src/index.ts +33 -0
- package/src/inventory-adoption.ts +85 -0
- package/src/manifest.ts +103 -0
- package/src/model-profile.ts +148 -0
- package/src/product-repository.ts +73 -0
- package/src/skills.ts +113 -8
- package/src/types.ts +58 -1
- /package/skeleton/{.clossys → clossys/.state}/inventory.json +0 -0
- /package/skeleton/{.clossys → clossys/.state}/workspace.json +0 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// Adopt an existing repository inventory instead of creating a second one
|
|
2
|
+
// (#1216). An account that already keeps a repository inventory in its own
|
|
3
|
+
// control plane becomes the source of truth when the hub marker declares
|
|
4
|
+
// it. Launcher writes only what that inventory lacks (a later apply step,
|
|
5
|
+
// not this module) and reports drift instead of silently merging.
|
|
6
|
+
function isRecord(value) {
|
|
7
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8
|
+
}
|
|
9
|
+
/** Reads a foundry-shaped inventory document's repository ids. Malformed or missing is null, never []. */
|
|
10
|
+
function readForeignIds(host, path) {
|
|
11
|
+
const raw = host.readText(path);
|
|
12
|
+
if (raw === null)
|
|
13
|
+
return null;
|
|
14
|
+
let parsed;
|
|
15
|
+
try {
|
|
16
|
+
parsed = JSON.parse(raw);
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
if (!isRecord(parsed) || parsed.schemaVersion !== 1 || !Array.isArray(parsed.repositories))
|
|
22
|
+
return null;
|
|
23
|
+
const ids = [];
|
|
24
|
+
for (const entry of parsed.repositories) {
|
|
25
|
+
if (isRecord(entry) && typeof entry.id === "string" && entry.id.trim() !== "")
|
|
26
|
+
ids.push(entry.id);
|
|
27
|
+
}
|
|
28
|
+
return ids;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Compares the declared external inventory against the launcher-written
|
|
32
|
+
* inventory at `directory/launcherInventoryRelPath`. Read-only -- callers
|
|
33
|
+
* decide whether and how to write the reconciled set, as an explicit,
|
|
34
|
+
* approved apply step (same #1045 pattern as clone-on-approval).
|
|
35
|
+
*/
|
|
36
|
+
export function reportInventoryDrift(host, directory, declaration, launcherInventoryRelPath) {
|
|
37
|
+
if (declaration === undefined) {
|
|
38
|
+
return { status: "no-external-source", externalOnly: [], launcherOnly: [], agreeing: [] };
|
|
39
|
+
}
|
|
40
|
+
if (declaration.shape === "custom") {
|
|
41
|
+
return {
|
|
42
|
+
status: "indeterminate",
|
|
43
|
+
externalOnly: [],
|
|
44
|
+
launcherOnly: [],
|
|
45
|
+
agreeing: [],
|
|
46
|
+
note: `externalInventory at ${declaration.path} declares shape "custom"; launcher has no mapping for a non-foundry inventory shape yet and will not guess one. Reconcile by hand or file the mapping gap.`,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
const externalIds = readForeignIds(host, declaration.path);
|
|
50
|
+
if (externalIds === null) {
|
|
51
|
+
return {
|
|
52
|
+
status: "indeterminate",
|
|
53
|
+
externalOnly: [],
|
|
54
|
+
launcherOnly: [],
|
|
55
|
+
agreeing: [],
|
|
56
|
+
note: `externalInventory at ${declaration.path} could not be read as a populated schemaVersion:1 inventory document.`,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
const launcherIds = readForeignIds(host, `${directory}/${launcherInventoryRelPath}`) ?? [];
|
|
60
|
+
const externalSet = new Set(externalIds);
|
|
61
|
+
const launcherSet = new Set(launcherIds);
|
|
62
|
+
const externalOnly = externalIds.filter((id) => !launcherSet.has(id));
|
|
63
|
+
const launcherOnly = launcherIds.filter((id) => !externalSet.has(id));
|
|
64
|
+
const agreeing = externalIds.filter((id) => launcherSet.has(id));
|
|
65
|
+
return { status: "reconciled", externalOnly, launcherOnly, agreeing };
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=inventory-adoption.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inventory-adoption.js","sourceRoot":"","sources":["../src/inventory-adoption.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { SkillManifestDocument, SkillsManifestSummary, WorkspaceHost } from "./types.js";
|
|
2
|
+
/** sha256 hex digest of a skill's final composed content (post contract injection). */
|
|
3
|
+
export declare function sha256Hex(content: string): string;
|
|
4
|
+
/** Parses `clossys/.state/skills.json`. An unreadable or malformed document is treated as absent. */
|
|
5
|
+
export declare function parseSkillManifest(raw: string | null): SkillManifestDocument | undefined;
|
|
6
|
+
export declare function serializeSkillManifest(document: SkillManifestDocument): string;
|
|
7
|
+
/**
|
|
8
|
+
* Freshness summary for the health report: "N skills out of date, M
|
|
9
|
+
* retired". `stale` counts catalogue-sourced entries whose recorded version
|
|
10
|
+
* is older than `liveLauncherVersion` (a client running an old launcher
|
|
11
|
+
* carries a catalogue only as fresh as that release, #1033) — unknown or
|
|
12
|
+
* unparseable versions are never counted stale. `retiredThisRun` is supplied
|
|
13
|
+
* by the composition step that just ran; a read-only inspection (no
|
|
14
|
+
* composition) reports 0 retired, which is correct — retirement is a
|
|
15
|
+
* this-run event, not a property of the manifest at rest.
|
|
16
|
+
*/
|
|
17
|
+
export declare function summarizeSkillsManifest(manifest: SkillManifestDocument | undefined, liveLauncherVersion: string | undefined, retiredThisRun: readonly string[]): SkillsManifestSummary;
|
|
18
|
+
/** Reads `installed` version from `<composeTargetDirectory>/node_modules/@clossys/<pkg>/package.json`. */
|
|
19
|
+
export declare function readInstalledVersion(host: WorkspaceHost, composeTargetDirectory: string, packageDir: string): string | undefined;
|
|
20
|
+
//# sourceMappingURL=manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAsB,qBAAqB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAMlH,uFAAuF;AACvF,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEjD;AAoBD,qGAAqG;AACrG,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,qBAAqB,GAAG,SAAS,CA4BxF;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,qBAAqB,GAAG,MAAM,CAE9E;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,qBAAqB,GAAG,SAAS,EAC3C,mBAAmB,EAAE,MAAM,GAAG,SAAS,EACvC,cAAc,EAAE,SAAS,MAAM,EAAE,GAChC,qBAAqB,CASvB;AAED,0GAA0G;AAC1G,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAUhI"}
|
package/dist/manifest.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
function isRecord(value) {
|
|
4
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5
|
+
}
|
|
6
|
+
/** sha256 hex digest of a skill's final composed content (post contract injection). */
|
|
7
|
+
export function sha256Hex(content) {
|
|
8
|
+
return createHash("sha256").update(content, "utf8").digest("hex");
|
|
9
|
+
}
|
|
10
|
+
/** Tiny semver-ish compare, duplicated from core.ts to keep this module dependency-free within the package. */
|
|
11
|
+
function compareVersions(a, b) {
|
|
12
|
+
const parse = (version) => {
|
|
13
|
+
const match = version.trim().match(/^v?(\d+)\.(\d+)\.(\d+)$/);
|
|
14
|
+
return match ? [Number(match[1]), Number(match[2]), Number(match[3])] : null;
|
|
15
|
+
};
|
|
16
|
+
const left = parse(a);
|
|
17
|
+
const right = parse(b);
|
|
18
|
+
if (!left || !right)
|
|
19
|
+
return null;
|
|
20
|
+
for (let index = 0; index < 3; index += 1) {
|
|
21
|
+
const l = left[index] ?? 0;
|
|
22
|
+
const r = right[index] ?? 0;
|
|
23
|
+
if (l < r)
|
|
24
|
+
return -1;
|
|
25
|
+
if (l > r)
|
|
26
|
+
return 1;
|
|
27
|
+
}
|
|
28
|
+
return 0;
|
|
29
|
+
}
|
|
30
|
+
/** Parses `clossys/.state/skills.json`. An unreadable or malformed document is treated as absent. */
|
|
31
|
+
export function parseSkillManifest(raw) {
|
|
32
|
+
if (raw === null)
|
|
33
|
+
return undefined;
|
|
34
|
+
let parsed;
|
|
35
|
+
try {
|
|
36
|
+
parsed = JSON.parse(raw);
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
if (!isRecord(parsed) || parsed.schemaVersion !== 1 || !Array.isArray(parsed.skills))
|
|
42
|
+
return undefined;
|
|
43
|
+
const skills = [];
|
|
44
|
+
for (const entry of parsed.skills) {
|
|
45
|
+
if (!isRecord(entry))
|
|
46
|
+
continue;
|
|
47
|
+
const { name, source, sha256 } = entry;
|
|
48
|
+
if (typeof name !== "string" || name.trim() === "")
|
|
49
|
+
continue;
|
|
50
|
+
if (source !== "installed" && source !== "catalogue")
|
|
51
|
+
continue;
|
|
52
|
+
if (typeof sha256 !== "string" || sha256.trim() === "")
|
|
53
|
+
continue;
|
|
54
|
+
skills.push({
|
|
55
|
+
name,
|
|
56
|
+
source,
|
|
57
|
+
sha256,
|
|
58
|
+
...(typeof entry.version === "string" && entry.version.trim() !== "" ? { version: entry.version } : {}),
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
schemaVersion: 1,
|
|
63
|
+
generatedAt: typeof parsed.generatedAt === "string" ? parsed.generatedAt : "",
|
|
64
|
+
skills,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
export function serializeSkillManifest(document) {
|
|
68
|
+
return `${JSON.stringify(document, null, 2)}\n`;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Freshness summary for the health report: "N skills out of date, M
|
|
72
|
+
* retired". `stale` counts catalogue-sourced entries whose recorded version
|
|
73
|
+
* is older than `liveLauncherVersion` (a client running an old launcher
|
|
74
|
+
* carries a catalogue only as fresh as that release, #1033) — unknown or
|
|
75
|
+
* unparseable versions are never counted stale. `retiredThisRun` is supplied
|
|
76
|
+
* by the composition step that just ran; a read-only inspection (no
|
|
77
|
+
* composition) reports 0 retired, which is correct — retirement is a
|
|
78
|
+
* this-run event, not a property of the manifest at rest.
|
|
79
|
+
*/
|
|
80
|
+
export function summarizeSkillsManifest(manifest, liveLauncherVersion, retiredThisRun) {
|
|
81
|
+
if (manifest === undefined) {
|
|
82
|
+
return { status: "missing", total: 0, stale: 0, retired: retiredThisRun.length };
|
|
83
|
+
}
|
|
84
|
+
const stale = manifest.skills.filter((entry) => {
|
|
85
|
+
if (entry.source !== "catalogue" || liveLauncherVersion === undefined || entry.version === undefined)
|
|
86
|
+
return false;
|
|
87
|
+
return compareVersions(entry.version, liveLauncherVersion) === -1;
|
|
88
|
+
}).length;
|
|
89
|
+
return { status: "present", total: manifest.skills.length, stale, retired: retiredThisRun.length };
|
|
90
|
+
}
|
|
91
|
+
/** Reads `installed` version from `<composeTargetDirectory>/node_modules/@clossys/<pkg>/package.json`. */
|
|
92
|
+
export function readInstalledVersion(host, composeTargetDirectory, packageDir) {
|
|
93
|
+
const raw = host.readText(join(composeTargetDirectory, "node_modules", "@clossys", packageDir, "package.json"));
|
|
94
|
+
if (raw === null)
|
|
95
|
+
return undefined;
|
|
96
|
+
try {
|
|
97
|
+
const parsed = JSON.parse(raw);
|
|
98
|
+
if (isRecord(parsed) && typeof parsed.version === "string" && parsed.version.trim() !== "")
|
|
99
|
+
return parsed.version;
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
/* unreadable manifest; no version */
|
|
103
|
+
}
|
|
104
|
+
return undefined;
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export type ReasoningTier = "light" | "standard" | "deep";
|
|
2
|
+
export type BudgetPreference = "cost-conscious" | "balanced" | "max-quality";
|
|
3
|
+
export type SupportedHost = "claude-code" | "codex" | "cursor";
|
|
4
|
+
export interface HostTierMapping {
|
|
5
|
+
/** The model this host runs for this tier under a "balanced" preference. */
|
|
6
|
+
readonly balanced: string;
|
|
7
|
+
/** Cheaper substitute under "cost-conscious", when one exists for this tier. Absent means "balanced" is already the floor. */
|
|
8
|
+
readonly costConscious?: string;
|
|
9
|
+
/** Stronger substitute under "max-quality", when one exists for this tier. */
|
|
10
|
+
readonly maxQuality?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface HostModelProfile {
|
|
13
|
+
readonly schemaVersion: 1;
|
|
14
|
+
readonly host: SupportedHost;
|
|
15
|
+
/** ISO date this mapping was last verified against that host's real current models. */
|
|
16
|
+
readonly verifiedAt: string;
|
|
17
|
+
readonly tiers: Readonly<Record<ReasoningTier, HostTierMapping>>;
|
|
18
|
+
}
|
|
19
|
+
export interface PreferencesDocument {
|
|
20
|
+
readonly schemaVersion: 1;
|
|
21
|
+
readonly budget: BudgetPreference;
|
|
22
|
+
}
|
|
23
|
+
export interface ModelResolution {
|
|
24
|
+
readonly tier: ReasoningTier;
|
|
25
|
+
readonly host: SupportedHost;
|
|
26
|
+
readonly model: string;
|
|
27
|
+
/** True when a hard floor tier was requested but this host/preference combination could not clear it -- reported, never silently substituted. */
|
|
28
|
+
readonly belowFloor: boolean;
|
|
29
|
+
}
|
|
30
|
+
/** Parses clossys/preferences.json. Absent or malformed defaults to "balanced" -- a missing preference is not a floor violation. */
|
|
31
|
+
export declare function parsePreferences(raw: string | null): PreferencesDocument;
|
|
32
|
+
/**
|
|
33
|
+
* Resolves a step's demanded tier to a real model name for one host, under
|
|
34
|
+
* one budget preference, respecting an optional hard floor tier.
|
|
35
|
+
*/
|
|
36
|
+
export declare function resolveModelForTier(profile: HostModelProfile, tier: ReasoningTier, budget: BudgetPreference, floorTier?: ReasoningTier): ModelResolution;
|
|
37
|
+
/**
|
|
38
|
+
* Reads a packed `model-profiles/<host>.json` file from the launcher
|
|
39
|
+
* package root. Returns undefined -- never throws, never guesses a
|
|
40
|
+
* fallback profile -- when the file is absent or malformed, matching this
|
|
41
|
+
* package's read-only, fail-closed pattern for every other packed
|
|
42
|
+
* artifact (manifest.ts's parseSkillManifest is the sibling to model this
|
|
43
|
+
* on).
|
|
44
|
+
*/
|
|
45
|
+
export declare function readHostModelProfile(readText: (path: string) => string | null, launcherPackageRoot: string, host: SupportedHost): HostModelProfile | undefined;
|
|
46
|
+
//# sourceMappingURL=model-profile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-profile.d.ts","sourceRoot":"","sources":["../src/model-profile.ts"],"names":[],"mappings":"AAgBA,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,UAAU,GAAG,MAAM,CAAC;AAC1D,MAAM,MAAM,gBAAgB,GAAG,gBAAgB,GAAG,UAAU,GAAG,aAAa,CAAC;AAC7E,MAAM,MAAM,aAAa,GAAG,aAAa,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE/D,MAAM,WAAW,eAAe;IAC9B,4EAA4E;IAC5E,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,8HAA8H;IAC9H,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,8EAA8E;IAC9E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,uFAAuF;IACvF,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,aAAa,EAAE,eAAe,CAAC,CAAC,CAAC;CAClE;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;CACnC;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,iJAAiJ;IACjJ,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;CAC9B;AAQD,oIAAoI;AACpI,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,mBAAmB,CAgBxE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,gBAAgB,EACzB,IAAI,EAAE,aAAa,EACnB,MAAM,EAAE,gBAAgB,EACxB,SAAS,CAAC,EAAE,aAAa,GACxB,eAAe,CAUjB;AAYD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,EACzC,mBAAmB,EAAE,MAAM,EAC3B,IAAI,EAAE,aAAa,GAClB,gBAAgB,GAAG,SAAS,CA6B9B"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// Model guidance (#1219, Launcher side). Owner decision: packages declare
|
|
2
|
+
// WHAT a step demands (a reasoning tier), never model names. Three layers:
|
|
3
|
+
// 1. Step demands -- each package's own loop matrix (#1197, not built here).
|
|
4
|
+
// 2. Tier-to-model profile -- PER HOST, shipped by Launcher, dated and
|
|
5
|
+
// re-verified, so a model change reaches clients in one launcher
|
|
6
|
+
// release rather than a bump of every package.
|
|
7
|
+
// 3. User preference -- cost-conscious / balanced / max-quality, asked
|
|
8
|
+
// once by Advisor, stored in clossys/preferences.json (Advisor's file
|
|
9
|
+
// to write; this module only reads it to resolve a tier to a model).
|
|
10
|
+
//
|
|
11
|
+
// Floors are hard where the verdict depends on it (Customer's keep):
|
|
12
|
+
// resolveModelForTier never silently drops below a caller-supplied floor;
|
|
13
|
+
// it reports belowFloor so the composed skill can say so plainly.
|
|
14
|
+
import { join } from "node:path";
|
|
15
|
+
function isRecord(value) {
|
|
16
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17
|
+
}
|
|
18
|
+
const TIER_ORDER = ["light", "standard", "deep"];
|
|
19
|
+
/** Parses clossys/preferences.json. Absent or malformed defaults to "balanced" -- a missing preference is not a floor violation. */
|
|
20
|
+
export function parsePreferences(raw) {
|
|
21
|
+
if (raw !== null) {
|
|
22
|
+
try {
|
|
23
|
+
const parsed = JSON.parse(raw);
|
|
24
|
+
if (isRecord(parsed) &&
|
|
25
|
+
parsed.schemaVersion === 1 &&
|
|
26
|
+
(parsed.budget === "cost-conscious" || parsed.budget === "balanced" || parsed.budget === "max-quality")) {
|
|
27
|
+
return { schemaVersion: 1, budget: parsed.budget };
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
/* falls through to the default below */
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return { schemaVersion: 1, budget: "balanced" };
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Resolves a step's demanded tier to a real model name for one host, under
|
|
38
|
+
* one budget preference, respecting an optional hard floor tier.
|
|
39
|
+
*/
|
|
40
|
+
export function resolveModelForTier(profile, tier, budget, floorTier) {
|
|
41
|
+
const mapping = profile.tiers[tier];
|
|
42
|
+
const model = budget === "cost-conscious"
|
|
43
|
+
? (mapping.costConscious ?? mapping.balanced)
|
|
44
|
+
: budget === "max-quality"
|
|
45
|
+
? (mapping.maxQuality ?? mapping.balanced)
|
|
46
|
+
: mapping.balanced;
|
|
47
|
+
const belowFloor = floorTier !== undefined && TIER_ORDER.indexOf(tier) < TIER_ORDER.indexOf(floorTier);
|
|
48
|
+
return { tier, host: profile.host, model, belowFloor };
|
|
49
|
+
}
|
|
50
|
+
function isTierMapping(value) {
|
|
51
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
52
|
+
return false;
|
|
53
|
+
const record = value;
|
|
54
|
+
return (typeof record.balanced === "string" &&
|
|
55
|
+
(record.costConscious === undefined || typeof record.costConscious === "string") &&
|
|
56
|
+
(record.maxQuality === undefined || typeof record.maxQuality === "string"));
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Reads a packed `model-profiles/<host>.json` file from the launcher
|
|
60
|
+
* package root. Returns undefined -- never throws, never guesses a
|
|
61
|
+
* fallback profile -- when the file is absent or malformed, matching this
|
|
62
|
+
* package's read-only, fail-closed pattern for every other packed
|
|
63
|
+
* artifact (manifest.ts's parseSkillManifest is the sibling to model this
|
|
64
|
+
* on).
|
|
65
|
+
*/
|
|
66
|
+
export function readHostModelProfile(readText, launcherPackageRoot, host) {
|
|
67
|
+
const raw = readText(join(launcherPackageRoot, "model-profiles", `${host}.json`));
|
|
68
|
+
if (raw === null)
|
|
69
|
+
return undefined;
|
|
70
|
+
let parsed;
|
|
71
|
+
try {
|
|
72
|
+
parsed = JSON.parse(raw);
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
if (typeof parsed !== "object" ||
|
|
78
|
+
parsed === null ||
|
|
79
|
+
Array.isArray(parsed) ||
|
|
80
|
+
parsed.schemaVersion !== 1 ||
|
|
81
|
+
parsed.host !== host ||
|
|
82
|
+
typeof parsed.verifiedAt !== "string") {
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
const tiersRaw = parsed.tiers;
|
|
86
|
+
if (typeof tiersRaw !== "object" || tiersRaw === null || Array.isArray(tiersRaw))
|
|
87
|
+
return undefined;
|
|
88
|
+
const tiers = tiersRaw;
|
|
89
|
+
if (!isTierMapping(tiers.light) || !isTierMapping(tiers.standard) || !isTierMapping(tiers.deep))
|
|
90
|
+
return undefined;
|
|
91
|
+
return {
|
|
92
|
+
schemaVersion: 1,
|
|
93
|
+
host,
|
|
94
|
+
verifiedAt: parsed.verifiedAt,
|
|
95
|
+
tiers: { light: tiers.light, standard: tiers.standard, deep: tiers.deep },
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=model-profile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-profile.js","sourceRoot":"","sources":["../src/model-profile.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { WorkspaceHost } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* One check from this repository's own docs/contracts/product-repository-layout.json `cloudSessionBootstrap` list (that contract file does not ship in the published package).
|
|
4
|
+
* Read-only: verifies a product repository has what a cloud agent session
|
|
5
|
+
* (browser plus GitHub only, no local setup) needs to install and run the
|
|
6
|
+
* team, without foundry's own heavy governance gates.
|
|
7
|
+
*/
|
|
8
|
+
export interface CloudBootstrapCheck {
|
|
9
|
+
readonly id: "package-manifest" | "agents-pointer" | "hub-marker";
|
|
10
|
+
readonly label: string;
|
|
11
|
+
readonly satisfied: boolean;
|
|
12
|
+
readonly note?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface CloudBootstrapReport {
|
|
15
|
+
readonly schemaVersion: 1;
|
|
16
|
+
readonly checks: readonly CloudBootstrapCheck[];
|
|
17
|
+
readonly ready: boolean;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Runs the three product-repository-layout.json cloudSessionBootstrap checks
|
|
21
|
+
* against `directory`. Never mutates anything, never runs `npm ci` itself
|
|
22
|
+
* -- it checks that the manifest and lockfile are BOTH present, which is
|
|
23
|
+
* the precondition a real `npm ci` needs, not a substitute for running it.
|
|
24
|
+
*/
|
|
25
|
+
export declare function checkCloudSessionBootstrap(host: WorkspaceHost, directory: string): CloudBootstrapReport;
|
|
26
|
+
//# sourceMappingURL=product-repository.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"product-repository.d.ts","sourceRoot":"","sources":["../src/product-repository.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,EAAE,kBAAkB,GAAG,gBAAgB,GAAG,YAAY,CAAC;IAClE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAChD,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB;AAOD;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,GAAG,oBAAoB,CAuCvG"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
const PACKAGE_JSON_REL = "package.json";
|
|
3
|
+
const PACKAGE_LOCK_REL = "package-lock.json";
|
|
4
|
+
const AGENTS_MD_REL = "AGENTS.md";
|
|
5
|
+
const HUB_MARKER_REL = join("clossys", ".state", "workspace.json");
|
|
6
|
+
/**
|
|
7
|
+
* Runs the three product-repository-layout.json cloudSessionBootstrap checks
|
|
8
|
+
* against `directory`. Never mutates anything, never runs `npm ci` itself
|
|
9
|
+
* -- it checks that the manifest and lockfile are BOTH present, which is
|
|
10
|
+
* the precondition a real `npm ci` needs, not a substitute for running it.
|
|
11
|
+
*/
|
|
12
|
+
export function checkCloudSessionBootstrap(host, directory) {
|
|
13
|
+
const hasManifest = host.exists(join(directory, PACKAGE_JSON_REL));
|
|
14
|
+
const hasLock = host.exists(join(directory, PACKAGE_LOCK_REL));
|
|
15
|
+
const manifestCheck = {
|
|
16
|
+
id: "package-manifest",
|
|
17
|
+
label: "package.json and package-lock.json are both present",
|
|
18
|
+
satisfied: hasManifest && hasLock,
|
|
19
|
+
...(hasManifest && hasLock
|
|
20
|
+
? {}
|
|
21
|
+
: {
|
|
22
|
+
note: !hasManifest && !hasLock
|
|
23
|
+
? "Neither package.json nor package-lock.json exists yet."
|
|
24
|
+
: !hasManifest
|
|
25
|
+
? "package-lock.json exists but package.json does not."
|
|
26
|
+
: "package.json exists but package-lock.json does not -- npm ci needs both.",
|
|
27
|
+
}),
|
|
28
|
+
};
|
|
29
|
+
const agentsRaw = host.readText(join(directory, AGENTS_MD_REL));
|
|
30
|
+
const agentsPointsAtClossys = agentsRaw !== null && agentsRaw.includes("clossys/");
|
|
31
|
+
const agentsCheck = {
|
|
32
|
+
id: "agents-pointer",
|
|
33
|
+
label: "AGENTS.md exists at the repository root and points at clossys/",
|
|
34
|
+
satisfied: agentsPointsAtClossys,
|
|
35
|
+
...(agentsPointsAtClossys
|
|
36
|
+
? {}
|
|
37
|
+
: { note: agentsRaw === null ? "AGENTS.md does not exist at the repository root." : "AGENTS.md exists but does not mention clossys/." }),
|
|
38
|
+
};
|
|
39
|
+
const hasHubMarker = host.exists(join(directory, HUB_MARKER_REL));
|
|
40
|
+
const markerCheck = {
|
|
41
|
+
id: "hub-marker",
|
|
42
|
+
label: "clossys/.state/workspace.json (the hub marker) is present",
|
|
43
|
+
satisfied: hasHubMarker,
|
|
44
|
+
...(hasHubMarker ? {} : { note: "clossys/.state/workspace.json does not exist yet." }),
|
|
45
|
+
};
|
|
46
|
+
const checks = [manifestCheck, agentsCheck, markerCheck];
|
|
47
|
+
return { schemaVersion: 1, checks, ready: checks.every((check) => check.satisfied) };
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=product-repository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"product-repository.js","sourceRoot":"","sources":["../src/product-repository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAsBjC,MAAM,gBAAgB,GAAG,cAAc,CAAC;AACxC,MAAM,gBAAgB,GAAG,mBAAmB,CAAC;AAC7C,MAAM,aAAa,GAAG,WAAW,CAAC;AAClC,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,gBAAgB,CAAC,CAAC;AAEnE;;;;;GAKG;AACH,MAAM,UAAU,0BAA0B,CAAC,IAAmB,EAAE,SAAiB;IAC/E,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC,CAAC;IACnE,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAC/D,MAAM,aAAa,GAAwB;QACzC,EAAE,EAAE,kBAAkB;QACtB,KAAK,EAAE,qDAAqD;QAC5D,SAAS,EAAE,WAAW,IAAI,OAAO;QACjC,GAAG,CAAC,WAAW,IAAI,OAAO;YACxB,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC;gBACE,IAAI,EAAE,CAAC,WAAW,IAAI,CAAC,OAAO;oBAC5B,CAAC,CAAC,wDAAwD;oBAC1D,CAAC,CAAC,CAAC,WAAW;wBACZ,CAAC,CAAC,qDAAqD;wBACvD,CAAC,CAAC,0EAA0E;aACjF,CAAC;KACP,CAAC;IAEF,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC;IAChE,MAAM,qBAAqB,GAAG,SAAS,KAAK,IAAI,IAAI,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IACnF,MAAM,WAAW,GAAwB;QACvC,EAAE,EAAE,gBAAgB;QACpB,KAAK,EAAE,gEAAgE;QACvE,SAAS,EAAE,qBAAqB;QAChC,GAAG,CAAC,qBAAqB;YACvB,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,kDAAkD,CAAC,CAAC,CAAC,iDAAiD,EAAE,CAAC;KAC3I,CAAC;IAEF,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC,CAAC;IAClE,MAAM,WAAW,GAAwB;QACvC,EAAE,EAAE,YAAY;QAChB,KAAK,EAAE,2DAA2D;QAClE,SAAS,EAAE,YAAY;QACvB,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,mDAAmD,EAAE,CAAC;KACvF,CAAC;IAEF,MAAM,MAAM,GAAG,CAAC,aAAa,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;IACzD,OAAO,EAAE,aAAa,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;AACvF,CAAC"}
|
package/dist/skills.d.ts
CHANGED
|
@@ -5,16 +5,35 @@ export interface SkillCompositionResult {
|
|
|
5
5
|
readonly packageDir: string;
|
|
6
6
|
readonly note: string;
|
|
7
7
|
}[];
|
|
8
|
+
readonly rosterTargets?: readonly string[];
|
|
9
|
+
readonly rosterSkipped?: readonly {
|
|
10
|
+
readonly inventoryId: string;
|
|
11
|
+
readonly note: string;
|
|
12
|
+
}[];
|
|
13
|
+
/** Skills pruned this run: present in the directory's previous manifest, absent from this run's composed set. */
|
|
14
|
+
readonly retired: readonly string[];
|
|
8
15
|
}
|
|
9
16
|
export interface ComposeSkillsOptions {
|
|
10
17
|
readonly skillCatalogueRoot?: string;
|
|
11
18
|
readonly launcherPackageRoot: string;
|
|
19
|
+
/** Overrides where the packed conversation contract is read from (tests). */
|
|
20
|
+
readonly contractPath?: string;
|
|
12
21
|
}
|
|
22
|
+
export declare const DISCOVERY_PREFIXES: readonly [".cursor/skills", ".claude/skills"];
|
|
23
|
+
export declare const SKILLS_MANIFEST_REL: string;
|
|
13
24
|
/** Package directory names that have a resolvable skill source in the catalogue or monorepo. */
|
|
14
25
|
export declare function listSkillPackageCandidates(host: WorkspaceHost, options: ComposeSkillsOptions): string[];
|
|
15
26
|
/**
|
|
16
27
|
* Writes `.agents/skills/clossys-<pkg>/SKILL.md` and host discovery links for every
|
|
17
|
-
* catalogue package
|
|
28
|
+
* catalogue package, with the shared conversation contract (#1182) injected in place
|
|
29
|
+
* of each skill's own `## How we work together` / `## One question at a time`
|
|
30
|
+
* sections. Missing sources are skipped with notes; the hub apply continues.
|
|
31
|
+
*
|
|
32
|
+
* Also writes `clossys/.state/skills.json` (#1183): source, version, and content
|
|
33
|
+
* digest per composed skill. A skill named in this directory's *previous* manifest
|
|
34
|
+
* but not composed this run is retired — its composed output is pruned and it is
|
|
35
|
+
* dropped from the new manifest. Never touches a skill this directory's manifest
|
|
36
|
+
* did not itself write.
|
|
18
37
|
*/
|
|
19
38
|
export declare function composeSkills(host: WorkspaceHost, directory: string, options: ComposeSkillsOptions): SkillCompositionResult;
|
|
20
39
|
//# sourceMappingURL=skills.d.ts.map
|
package/dist/skills.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../src/skills.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../src/skills.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAsB,aAAa,EAAE,MAAM,YAAY,CAAC;AAEpE,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,OAAO,EAAE,SAAS;QAAE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACpF,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS;QAAE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5F,iHAAiH;IACjH,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,6EAA6E;IAC7E,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,eAAO,MAAM,kBAAkB,+CAAgD,CAAC;AAEhF,eAAO,MAAM,mBAAmB,QAA2C,CAAC;AA8E5E,gGAAgG;AAChG,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,oBAAoB,GAAG,MAAM,EAAE,CAqBvG;AA0CD;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,aAAa,EACnB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,oBAAoB,GAC5B,sBAAsB,CA2CxB"}
|