File size: 9,437 Bytes
391c43e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 | import type { InterviewTemplate } from './types';
/** Built-in interview templates. The format is data, so user-authored templates can slot in later. */
const UNDERSTAND_COMPANY: InterviewTemplate = {
id: 'understand-company',
title: 'Understand a company',
description: 'Build a profile of a company β what it does, who it serves, and its brand β to inform later work.',
artifacts: [{ path: '/.interviews/company-profile.md', description: 'The company profile' }],
items: [
{
id: 'identity',
elicit: "The company's name and a one-line description of what it does.",
completion: [{ type: 'judge', criteria: 'The /.interviews/company-profile.md artifact states the company name and a clear description of what it does.', description: 'Name and description recorded' }],
},
{
id: 'audience',
elicit: 'Who the company serves β its target customers or audience.',
completion: [{ type: 'judge', criteria: 'The company-profile artifact describes the target audience or customers.', description: 'Audience recorded' }],
},
{
id: 'offerings',
elicit: 'The main products or services the company offers.',
completion: [{ type: 'judge', criteria: 'The company-profile artifact lists the main products or services.', description: 'Offerings recorded' }],
},
{
id: 'brand',
elicit: "The brand's tone and any visual identity (colors, fonts). If they have a logo, ask them to add it to the project, then confirm it with ls.",
completion: [{ type: 'judge', criteria: 'The company-profile artifact describes the brand tone or visual identity, and notes the logo status (present at a path, or none).', description: 'Brand and logo status recorded' }],
},
{
id: 'assets',
required: false,
elicit: 'Any existing assets already in the project (logo, images, copy) β check with ls and note what is present.',
completion: [{ type: 'judge', criteria: 'The company-profile artifact notes any existing project assets (or states there are none).', description: 'Existing assets noted' }],
},
],
handoff: {
label: 'Build a site from this',
prompt: 'Build a website for this company using the profile in /.interviews/company-profile.md.',
mode: 'code',
},
};
const PLAN_FEATURE: InterviewTemplate = {
id: 'plan-feature',
title: 'Plan a feature',
description: 'Turn a feature idea into a clear, buildable spec through a few focused questions.',
artifacts: [{ path: '/.interviews/feature-plan.md', description: 'The feature spec' }],
items: [
{
id: 'summary',
elicit: 'What the feature is and the problem it solves.',
completion: [{ type: 'judge', criteria: 'The /.interviews/feature-plan.md artifact describes what the feature is and the problem it solves.', description: 'Feature and problem recorded' }],
},
{
id: 'users',
elicit: 'Who uses the feature and the primary user flow.',
completion: [{ type: 'judge', criteria: 'The feature-plan artifact describes who uses it and the primary user flow.', description: 'Users and flow recorded' }],
},
{
id: 'scope',
elicit: "What's in scope for a first version and what is explicitly out of scope.",
completion: [{ type: 'judge', criteria: 'The feature-plan artifact states both what is in scope for v1 and what is out of scope.', description: 'Scope recorded' }],
},
{
id: 'acceptance',
elicit: "Acceptance criteria β how you'll know the feature is done.",
completion: [{ type: 'judge', criteria: 'The feature-plan artifact lists concrete acceptance criteria.', description: 'Acceptance criteria recorded' }],
},
],
handoff: {
label: 'Implement this plan',
prompt: 'Implement the feature spec in /.interviews/feature-plan.md.',
mode: 'code',
},
};
const PLAN_WEBSITE: InterviewTemplate = {
id: 'plan-website',
title: 'Plan a website',
description: 'Turn an idea into a buildable plan for a site β its purpose, audience, pages, and the action it should drive.',
artifacts: [{ path: '/.interviews/site-plan.md', description: 'The site plan' }],
items: [
{
id: 'purpose',
elicit: "The site's purpose β what it's for, and the single most important thing a visitor should do or take away. (Glance at the project first; if something already exists, plan around it.)",
completion: [{ type: 'judge', criteria: 'The /.interviews/site-plan.md artifact states the purpose of the site and its primary goal.', description: 'Purpose recorded' }],
},
{
id: 'audience',
elicit: 'Who the site is for β its primary visitors.',
completion: [{ type: 'judge', criteria: 'The site-plan artifact describes the target audience or visitors.', description: 'Audience recorded' }],
},
{
id: 'pages',
elicit: 'The pages or main sections the site needs (for example: home, about, services, contact).',
completion: [{ type: 'judge', criteria: 'The site-plan artifact lists the pages or main sections the site needs.', description: 'Pages recorded' }],
},
{
id: 'action',
elicit: 'The primary action you want visitors to take β the main call-to-action or conversion.',
completion: [{ type: 'judge', criteria: 'The site-plan artifact states the primary call-to-action or conversion goal.', description: 'Primary action recorded' }],
},
{
id: 'content',
required: false,
elicit: 'Any content, copy, or assets you already have β check the project with ls β and what still needs to be created.',
completion: [{ type: 'judge', criteria: 'The site-plan artifact notes existing content/assets in the project and what still needs creating (or states there is none yet).', description: 'Content/assets noted' }],
},
],
handoff: {
label: 'Build this site',
prompt: 'Build the website described in /.interviews/site-plan.md.',
mode: 'code',
},
};
const PREPARE_PUBLISH: InterviewTemplate = {
id: 'prepare-publish',
title: 'Get ready to publish',
description: 'Check a site over before going live β domain, SEO basics, and readiness β grounded in what is actually in the project.',
artifacts: [{ path: '/.interviews/publish-checklist.md', description: 'The publish checklist' }],
items: [
{
id: 'destination',
elicit: 'Where this will live β a custom domain, or the default hosting URL. Note it even if undecided.',
completion: [{ type: 'judge', criteria: 'The /.interviews/publish-checklist.md artifact records the intended domain or hosting URL (or notes it is undecided).', description: 'Destination recorded' }],
},
{
id: 'identity',
elicit: 'The site title and a one-line description for search engines and link previews.',
completion: [{ type: 'judge', criteria: 'The publish-checklist artifact records the site title and a meta description.', description: 'Title and description recorded' }],
},
{
id: 'seo-basics',
elicit: 'Check the SEO basics: read the HTML and verify there is a <title>, a meta description, and a favicon. Note what is present and what is missing.',
completion: [{ type: 'judge', criteria: 'The publish-checklist artifact reports the state of the page title, meta description, and favicon based on the actual project files.', description: 'SEO basics checked against the project' }],
},
{
id: 'audience-keywords',
required: false,
elicit: 'Who the site targets and any keywords or search terms it should rank for.',
completion: [{ type: 'judge', criteria: 'The publish-checklist artifact notes the target audience and any keywords (or states there are none).', description: 'Audience/keywords noted' }],
},
{
id: 'readiness',
elicit: 'Look for obvious gaps before publishing β read the project for broken internal links, placeholder content, or empty pages β and list anything to fix.',
completion: [{ type: 'judge', criteria: 'The publish-checklist artifact lists publish-readiness gaps found by inspecting the project (broken links, placeholder content, empty pages), or confirms there are none.', description: 'Readiness gaps listed from the project' }],
},
],
handoff: {
label: 'Fix and prepare for publish',
prompt: 'Apply the publish-readiness fixes listed in /.interviews/publish-checklist.md β SEO title and meta description, favicon, and any gaps noted.',
mode: 'code',
},
};
export const BUILT_IN_INTERVIEWS: InterviewTemplate[] = [UNDERSTAND_COMPANY, PLAN_WEBSITE, PLAN_FEATURE, PREPARE_PUBLISH];
export function isBuiltInInterviewTemplateId(id: string): boolean {
return BUILT_IN_INTERVIEWS.some(t => t.id === id);
}
export function listInterviewTemplates(): InterviewTemplate[] {
return BUILT_IN_INTERVIEWS;
}
export function getInterviewTemplate(id: string): InterviewTemplate | undefined {
return BUILT_IN_INTERVIEWS.find(t => t.id === id);
}
/** Filters templates by a case-insensitive match on title or description. Empty query returns all. */
export function filterInterviewTemplates(templates: InterviewTemplate[], query: string): InterviewTemplate[] {
const q = query.trim().toLowerCase();
if (!q) return templates;
return templates.filter(
t => t.title.toLowerCase().includes(q) || t.description.toLowerCase().includes(q)
);
}
|