Skip to content

Commit d477b02

Browse files
committed
fix(web): preserve explicit skill routing
1 parent 4eacda5 commit d477b02

2 files changed

Lines changed: 59 additions & 4 deletions

File tree

apps/web/src/components/HomeView.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2779,10 +2779,10 @@ export function HomeView({
27792779
// route through the default design router; in Ask mode they stay plain
27802780
// chat conversations with no hidden router plugin.
27812781
const resolvedSkillId = submittedActive ? null : activeSkill?.id ?? null;
2782-
const routedPluginId =
2783-
sessionMode === 'design'
2784-
? submittedActive?.record.id ?? DEFAULT_UNSELECTED_SCENARIO_PLUGIN_ID
2785-
: submittedActive?.record.id ?? null;
2782+
const routedPluginId = submittedActive?.record.id
2783+
?? (sessionMode === 'design' && !resolvedSkillId
2784+
? DEFAULT_UNSELECTED_SCENARIO_PLUGIN_ID
2785+
: null);
27862786
// The example-prompt override is a one-shot marker. Decide whether to
27872787
// send it now, but defer spending the marker until the create is
27882788
// accepted — a rejected attempt stays retryable and must resend it.

apps/web/tests/components/HomeView.prefill.test.tsx

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import { act } from 'react';
44
import { cleanup, fireEvent, render, screen, waitFor, within } from '@testing-library/react';
55
import { afterEach, describe, expect, it, vi } from 'vitest';
6+
import type { SkillSummary } from '@open-design/contracts';
67

78
vi.mock('../../src/components/home-hero/PlaceholderCarousel', () => ({
89
PlaceholderCarousel: () => null,
@@ -25,6 +26,7 @@ import { requestHomeChip } from '../../src/runtime/home-intent';
2526
import {
2627
createPluginAuthoringHandoff,
2728
createPluginUseHandoff,
29+
createSkillUseHandoff,
2830
PLUGIN_AUTHORING_DEFAULT_GOAL,
2931
PLUGIN_AUTHORING_PROMPT,
3032
} from '../../src/components/home-hero/plugin-authoring';
@@ -139,6 +141,21 @@ const HIDDEN_DEFAULT_PLUGIN = {
139141
},
140142
};
141143

144+
const INDUSTRIAL_PRODUCT_DESIGN_SKILL: SkillSummary = {
145+
id: 'industrial-product-design',
146+
name: 'Industrial Product Design',
147+
description: 'Generate evidence-aware industrial product design directions.',
148+
triggers: ['industrial design'],
149+
mode: 'design-system',
150+
previewType: 'markdown',
151+
designSystemRequired: false,
152+
defaultFor: [],
153+
upstream: null,
154+
hasBody: true,
155+
examplePrompt: 'Develop three industrial design directions for an air purifier.',
156+
aggregatesExamples: false,
157+
};
158+
142159
// The Prototype chip binds to the bundled `example-web-prototype`
143160
// plugin (which ships its own seed + layouts + checklist) instead of
144161
// the generic od-new-generation router. Mirror that here so the
@@ -933,6 +950,44 @@ describe('HomeView prompt handoff', () => {
933950
}));
934951
});
935952

953+
it('submits an explicitly selected skill without the hidden default plugin', async () => {
954+
const fetchMock = vi.fn<typeof fetch>(async (url) => {
955+
if (typeof url === 'string' && url === '/api/plugins') {
956+
return new Response(JSON.stringify({ plugins: [HIDDEN_DEFAULT_PLUGIN] }), {
957+
status: 200,
958+
headers: { 'content-type': 'application/json' },
959+
});
960+
}
961+
throw new Error(`unexpected fetch ${url}`);
962+
});
963+
vi.stubGlobal('fetch', fetchMock);
964+
const onSubmit = vi.fn();
965+
966+
render(
967+
<HomeView
968+
projects={[]}
969+
skills={[INDUSTRIAL_PRODUCT_DESIGN_SKILL]}
970+
onSubmit={onSubmit}
971+
onOpenProject={() => undefined}
972+
onViewAllProjects={() => undefined}
973+
promptHandoff={createSkillUseHandoff(12, INDUSTRIAL_PRODUCT_DESIGN_SKILL)}
974+
/>,
975+
);
976+
977+
await waitFor(() => {
978+
expect(screen.getByTestId('home-hero-active-skill').textContent)
979+
.toContain('Industrial Product Design');
980+
});
981+
fireEvent.click(screen.getByTestId('home-hero-submit'));
982+
983+
expect(onSubmit).toHaveBeenCalledWith(expect.objectContaining({
984+
prompt: 'Develop three industrial design directions for an air purifier.',
985+
pluginId: null,
986+
skillId: 'industrial-product-design',
987+
appliedPluginSnapshotId: null,
988+
}));
989+
});
990+
936991
it('falls back to od-new-generation when od-plugin-authoring is not registered yet', async () => {
937992
const fetchMock = vi.fn<typeof fetch>(async (url) => {
938993
if (typeof url === 'string' && url === '/api/plugins') {

0 commit comments

Comments
 (0)