Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions packages/cli/src/commands/conventions.integration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ describe("architecture and practices facets integration", () => {
// Facet order: process (select), architecture (select), practices (multiselect)
vi.mocked(clack.select)
.mockResolvedValueOnce("native-agents-md") // process
.mockResolvedValueOnce("__skip__"); // architecture: skip
.mockResolvedValueOnce("other"); // architecture: other
vi.mocked(clack.multiselect)
.mockResolvedValueOnce(["conventional-commits", "tdd-london"]) // practices
.mockResolvedValueOnce(["claude-code"]); // harnesses
Expand Down Expand Up @@ -182,7 +182,7 @@ describe("architecture and practices facets integration", () => {
// Facet order: process (select), architecture (select), practices (multiselect)
vi.mocked(clack.select)
.mockResolvedValueOnce("native-agents-md") // process
.mockResolvedValueOnce("__skip__"); // architecture: skip
.mockResolvedValueOnce("other"); // architecture: other
vi.mocked(clack.multiselect)
.mockResolvedValueOnce(["adr-nygard"])
.mockResolvedValueOnce(["claude-code"]); // harnesses
Expand All @@ -199,13 +199,13 @@ describe("architecture and practices facets integration", () => {
expect(adr).toContain("## Consequences");
});

it("skips both architecture and practices when none selected", async () => {
it("writes no .ade directory when architecture is other and no practices selected", async () => {
const catalog = getDefaultCatalog();

// Facet order: process (select), architecture (select), practices (multiselect)
vi.mocked(clack.select)
.mockResolvedValueOnce("native-agents-md") // process
.mockResolvedValueOnce("__skip__"); // architecture: skip
.mockResolvedValueOnce("other"); // architecture: other
vi.mocked(clack.multiselect)
.mockResolvedValueOnce([]) // practices: none
.mockResolvedValueOnce(["claude-code"]); // harnesses
Expand All @@ -215,9 +215,9 @@ describe("architecture and practices facets integration", () => {
// No .ade directory should exist
await expect(access(join(dir, ".ade"))).rejects.toThrow();

// config.yaml should not have architecture or practices keys
// config.yaml should have architecture: "other" but no practices key
const config = await readUserConfig(dir);
expect(config!.choices).not.toHaveProperty("architecture");
expect(config!.choices).toHaveProperty("architecture", "other");
expect(config!.choices).not.toHaveProperty("practices");
});

Expand All @@ -227,7 +227,7 @@ describe("architecture and practices facets integration", () => {
// Facet order: process (select), architecture (select), practices (multiselect)
vi.mocked(clack.select)
.mockResolvedValueOnce("native-agents-md") // process
.mockResolvedValueOnce("__skip__"); // architecture: skip
.mockResolvedValueOnce("other"); // architecture: other
vi.mocked(clack.multiselect)
.mockResolvedValueOnce(["tdd-london"])
.mockResolvedValueOnce(["claude-code"]); // harnesses
Expand Down
6 changes: 3 additions & 3 deletions packages/cli/src/commands/install.integration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ describe("install integration (real temp dir)", () => {
// Step 1: Run setup to create config.yaml + config.lock.yaml
vi.mocked(clack.select)
.mockResolvedValueOnce("codemcp-workflows") // process
.mockResolvedValueOnce("__skip__"); // architecture
.mockResolvedValueOnce("other"); // architecture
vi.mocked(clack.multiselect).mockResolvedValueOnce([]); // practices: none
await runSetup(dir, catalog);

Expand All @@ -73,7 +73,7 @@ describe("install integration (real temp dir)", () => {
// Setup first
vi.mocked(clack.select)
.mockResolvedValueOnce("codemcp-workflows") // process
.mockResolvedValueOnce("__skip__"); // architecture
.mockResolvedValueOnce("other"); // architecture
vi.mocked(clack.multiselect).mockResolvedValueOnce([]); // practices: none
await runSetup(dir, catalog);

Expand Down Expand Up @@ -102,7 +102,7 @@ describe("install integration (real temp dir)", () => {
// Setup with native-agents-md
vi.mocked(clack.select)
.mockResolvedValueOnce("native-agents-md") // process
.mockResolvedValueOnce("__skip__"); // architecture
.mockResolvedValueOnce("other"); // architecture
vi.mocked(clack.multiselect).mockResolvedValueOnce([]); // practices: none
await runSetup(dir, catalog);

Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/commands/knowledge.integration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ describe("knowledge integration", () => {

vi.mocked(clack.select)
.mockResolvedValueOnce("native-agents-md") // process
.mockResolvedValueOnce("__skip__"); // architecture: skip
.mockResolvedValueOnce("other"); // architecture: other
vi.mocked(clack.multiselect).mockResolvedValueOnce(["tdd-london"]); // practices: tdd-london has no docsets

await runSetup(dir, catalog);
Expand Down
26 changes: 19 additions & 7 deletions packages/cli/src/commands/setup.integration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,23 +45,29 @@ describe("setup integration (real temp dir)", () => {

vi.mocked(clack.select)
.mockResolvedValueOnce("codemcp-workflows") // process
.mockResolvedValueOnce("__skip__"); // architecture
.mockResolvedValueOnce("other"); // architecture
vi.mocked(clack.multiselect).mockResolvedValueOnce([]); // practices: none

await runSetup(dir, catalog);

// ── config.yaml ──────────────────────────────────────────────────────
const config = await readUserConfig(dir);
expect(config).not.toBeNull();
expect(config!.choices).toEqual({ process: "codemcp-workflows" });
expect(config!.choices).toEqual({
process: "codemcp-workflows",
architecture: "other"
});
// harnesses must NOT be in config.yaml — setup no longer selects them
expect(config).not.toHaveProperty("harnesses");

// ── config.lock.yaml ─────────────────────────────────────────────────
const lock = await readLockFile(dir);
expect(lock).not.toBeNull();
expect(lock!.version).toBe(1);
expect(lock!.choices).toEqual({ process: "codemcp-workflows" });
expect(lock!.choices).toEqual({
process: "codemcp-workflows",
architecture: "other"
});
expect(lock!.generated_at).toBeTruthy();
// harnesses must NOT be in the lock file
expect(lock).not.toHaveProperty("harnesses");
Expand All @@ -78,16 +84,22 @@ describe("setup integration (real temp dir)", () => {

vi.mocked(clack.select)
.mockResolvedValueOnce("native-agents-md") // process
.mockResolvedValueOnce("__skip__"); // architecture
.mockResolvedValueOnce("other"); // architecture
vi.mocked(clack.multiselect).mockResolvedValueOnce([]); // practices: none

await runSetup(dir, catalog);

const config = await readUserConfig(dir);
expect(config!.choices).toEqual({ process: "native-agents-md" });
expect(config!.choices).toEqual({
process: "native-agents-md",
architecture: "other"
});

const lock = await readLockFile(dir);
expect(lock!.choices).toEqual({ process: "native-agents-md" });
expect(lock!.choices).toEqual({
process: "native-agents-md",
architecture: "other"
});
expect(lock!.logical_config.instructions.length).toBeGreaterThan(0);
});

Expand All @@ -112,7 +124,7 @@ describe("setup integration (real temp dir)", () => {

vi.mocked(clack.select)
.mockResolvedValueOnce("codemcp-workflows") // process
.mockResolvedValueOnce("__skip__"); // architecture
.mockResolvedValueOnce("other"); // architecture
vi.mocked(clack.multiselect).mockResolvedValueOnce([]); // practices: none

await runSetup(dir, catalog);
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/commands/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ function promptSelect(
hint: o.description
}));

if (!facet.required) {
if (!facet.required && !facet.options.some((o) => o.id === "other")) {
options.push({ value: "__skip__", label: "Skip", hint: "" });
}

Expand Down
7 changes: 7 additions & 0 deletions packages/core/src/catalog/facets/architecture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,13 @@ export const architectureFacet: Facet = {
}
}
]
},
{
id: "other",
label: "Other",
description:
"Custom or unlisted architecture — no conventions will be applied",
recipe: []
}
]
};
Loading