diff --git a/README.md b/README.md index 1dbace6..dc97a62 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ brew install instructa/tap/switchloom ### npm ```sh -npm install --global switchloom@0.3.1 +npm install --global switchloom@0.3.2 ``` Both channels install the branded `switchloom` command and the compatibility @@ -42,7 +42,7 @@ the browser. After choosing a provider and team, open the provider onboarding flow, run the copied apply command from the target repository, then run doctor: ```sh -npx switchloom@0.3.1 apply --recipe 'sw1_...' --repository . +npx switchloom@0.3.2 apply --recipe 'sw1_...' --repository . npx switchloom doctor codex ``` @@ -71,7 +71,7 @@ apply when setup depends on a locally installed host CLI. ## Current Status -The v0.3.1 public CLI compiles independently and hard-cuts maintainer-only +The v0.3.2 public CLI compiles independently and hard-cuts maintainer-only evaluation, catalog, registry, and live-verification operations from the public command surface. @@ -104,7 +104,7 @@ pnpm site:dev ``` The website setup contract is the provider onboarding flow: the copied -`npx switchloom@0.3.1 apply --recipe 'sw1_...' --repository .` command runs the +`npx switchloom@0.3.2 apply --recipe 'sw1_...' --repository .` command runs the CLI-owned preview and confirmation before writing repository-local artifacts, and the provider-specific doctor command verifies the resulting host setup. @@ -131,11 +131,11 @@ pnpm security:check ## Releases Releases are created only through the repository-owned script. Prepare and -commit a bracketed changelog section such as `## [0.3.1]`, then run: +commit a bracketed changelog section such as `## [0.3.2]`, then run: ```sh -RELEASE_DRY_RUN=1 scripts/release.sh 0.3.1 "Codex 0.145 native V2 compatibility" -scripts/release.sh 0.3.1 "Codex 0.145 native V2 compatibility" +RELEASE_DRY_RUN=1 scripts/release.sh 0.3.2 "Multi-agent generator and Codex V2 catalog" +scripts/release.sh 0.3.2 "Multi-agent generator and Codex V2 catalog" ``` The script requires a clean, synchronized `main`, runs the complete local diff --git a/website/src/lib/generator.test.ts b/website/src/lib/generator.test.ts index b4e6a49..ab03b92 100644 --- a/website/src/lib/generator.test.ts +++ b/website/src/lib/generator.test.ts @@ -1,6 +1,8 @@ import { describe, expect, it } from "vitest"; -import { applyPreset, canRenderParentRecommendation, changeHost, CHILD_ROLE_IDS, choosePreset, createConfig, createPresetSelection, HOST_IDS, hostCatalogFrom, isChildRoleId, isPresetDirty, isPrimaryRecommendationId, lifecycleCommands, markPresetCustom, parentRecommendationEffortCopy, PRESETS, primaryRecommendation, PRIMARY_RECOMMENDATION_ID, recipeApplyCommand, removeChildRole, resetRolesToPreset, ROLE_IDS, selectedChildRoleIds, setEffort, setIntegration, setModel, setRoles, setupConfigToml, setupRecipe, setupSpec, setupSummary, setupTransportFrom } from "./generator"; +import packageMetadata from "../../../package.json"; + +import { applyPreset, canRenderParentRecommendation, changeHost, CHILD_ROLE_IDS, choosePreset, createConfig, createPresetSelection, HOST_IDS, hostCatalogFrom, isChildRoleId, isPresetDirty, isPrimaryRecommendationId, lifecycleCommands, markPresetCustom, parentRecommendationEffortCopy, PRESETS, primaryRecommendation, PRIMARY_RECOMMENDATION_ID, recipeApplyCommand, removeChildRole, resetRolesToPreset, ROLE_IDS, selectedChildRoleIds, setEffort, setIntegration, setModel, setRoles, setupConfigToml, setupRecipe, setupSpec, setupSummary, setupTransportFrom, SWITCHLOOM_VERSION } from "./generator"; const generatedCatalog = { setupContract: { @@ -63,6 +65,10 @@ const generatedCatalog = { const hostCatalog = hostCatalogFrom(generatedCatalog); describe("Switchloom generator", () => { + it("derives the pinned CLI version from package metadata", () => { + expect(SWITCHLOOM_VERSION).toBe(packageMetadata.version); + }); + it("splits the primary recommendation id from generated child role ids", () => { expect(PRIMARY_RECOMMENDATION_ID).toBe("orchestrator"); expect(CHILD_ROLE_IDS).toEqual(["implementer", "reviewer", "verifier"]); @@ -413,7 +419,7 @@ describe("Switchloom generator", () => { const recipe = setupRecipe(config, hostCatalog, transport.recipePrefix); expect(recipe).toMatch(/^sw1_[A-Za-z0-9_-]+$/); const command = recipeApplyCommand(config, hostCatalog, transport.recipePrefix); - expect(command).toMatch(/^npx switchloom@0\.3\.1 apply --recipe 'sw1_[A-Za-z0-9_-]+' --repository \.$/); + expect(command).toBe(`npx switchloom@${SWITCHLOOM_VERSION} apply --recipe '${recipe}' --repository .`); const toml = setupConfigToml(config, hostCatalog); expect(toml).toContain('host = "codex-openai"'); expect(toml).toContain('integration = "standalone"'); @@ -428,7 +434,7 @@ describe("Switchloom generator", () => { it("shows the full CLI lifecycle without claiming custom setup verification", () => { const commands = lifecycleCommands(createConfig("cursor"), hostCatalog); expect(commands.map((entry) => entry.command)).toEqual([ - "npm install -g switchloom@0.3.1", + `npm install -g switchloom@${SWITCHLOOM_VERSION}`, expect.stringMatching(/^switchloom preview --recipe 'sw1_/), expect.stringMatching(/^switchloom apply --recipe 'sw1_/), "switchloom doctor cursor", diff --git a/website/src/lib/generator.ts b/website/src/lib/generator.ts index c738bd7..3a8ad46 100644 --- a/website/src/lib/generator.ts +++ b/website/src/lib/generator.ts @@ -1,9 +1,11 @@ +import packageMetadata from "../../../package.json"; + export const PRIMARY_RECOMMENDATION_ID = "orchestrator" as const; export const CHILD_ROLE_IDS = ["implementer", "reviewer", "verifier"] as const; export const ROLE_IDS = [PRIMARY_RECOMMENDATION_ID, ...CHILD_ROLE_IDS] as const; export const HOST_IDS = ["codex", "cursor", "claude-code", "opencode", "pi"] as const; export const PRESET_IDS = ["light", "balanced", "high"] as const; -export const SWITCHLOOM_VERSION = "0.3.1"; +export const SWITCHLOOM_VERSION = packageMetadata.version; export type PrimaryRecommendationId = typeof PRIMARY_RECOMMENDATION_ID; export type ChildRoleId = (typeof CHILD_ROLE_IDS)[number]; diff --git a/website/src/lib/onboarding.test.ts b/website/src/lib/onboarding.test.ts index 62f2748..62fc50c 100644 --- a/website/src/lib/onboarding.test.ts +++ b/website/src/lib/onboarding.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from "vitest"; -import { HOST_IDS } from "./generator"; +import { HOST_IDS, SWITCHLOOM_VERSION } from "./generator"; import { PROVIDER_ONBOARDING, providerOnboarding } from "./onboarding"; describe("provider onboarding templates", () => { @@ -19,7 +19,7 @@ describe("provider onboarding templates", () => { }); it("injects the exact generated recipe command without mutating provider copy", () => { - const command = "npx switchloom@0.3.1 apply --recipe 'sw1_example' --repository ."; + const command = `npx switchloom@${SWITCHLOOM_VERSION} apply --recipe 'sw1_example' --repository .`; const onboarding = providerOnboarding("codex", command); expect(onboarding.steps.find((step) => step.id === "install")?.command).toBe(command); diff --git a/website/src/lib/website-cli-parity.test.ts b/website/src/lib/website-cli-parity.test.ts index badf58c..3cd891b 100644 --- a/website/src/lib/website-cli-parity.test.ts +++ b/website/src/lib/website-cli-parity.test.ts @@ -21,6 +21,7 @@ import { setupRecipe, setupTransportFrom, shellQuote, + SWITCHLOOM_VERSION, } from "./generator"; import type { ChildRoleId, GeneratorConfig } from "./generator"; @@ -222,7 +223,7 @@ describe("website SetupSpec to CLI parity", () => { const command = recipeApplyCommand(config, hostCatalog, setupTransport.recipePrefix); const recipe = command.match(/--recipe '([^']+)'/)?.[1]; expect(recipe).toBeTruthy(); - expect(command).toBe(`npx switchloom@0.3.1 apply --recipe ${shellQuote(recipe!)} --repository .`); + expect(command).toBe(`npx switchloom@${SWITCHLOOM_VERSION} apply --recipe ${shellQuote(recipe!)} --repository .`); const { repository } = await tempRepo("switchloom-website-standalone-"); const preview = report(run(["preview", "--recipe", recipe!, "--repository", repository]));