VIBN Frontend for Coolify deployment
This commit is contained in:
487
prompts/foundation.md
Normal file
487
prompts/foundation.md
Normal file
@@ -0,0 +1,487 @@
|
||||
Prompt to paste into Cursor for Sonnet
|
||||
You are helping me implement a clean, provider-agnostic AI foundation for a product called Vibn.
|
||||
|
||||
Vibn’s job:
|
||||
- Pull a product idea out of a founder’s head
|
||||
- Turn it into a structured product model
|
||||
- Derive an MVP plan and marketing model from that
|
||||
|
||||
Runtime requirement:
|
||||
- The *runtime* “Vibn agent” will use **Gemini 2.5 Pro** as the LLM.
|
||||
- The architecture must be **model-agnostic**, so we can later add GPT / Claude if we want.
|
||||
- Right now, you (Claude Sonnet in Cursor) are only a **coding assistant**, not part of the runtime.
|
||||
|
||||
I want you to design and implement the following foundation inside this repo.
|
||||
|
||||
==================================================
|
||||
🏛 1. HIGH-LEVEL ARCHITECTURE
|
||||
==================================================
|
||||
|
||||
We want a simple, explicit architecture with four core concepts:
|
||||
|
||||
1. Project – a single product idea
|
||||
2. Knowledge base – all raw materials for a project (notes, chats, docs, etc.)
|
||||
3. Canonical Product Model – the structured representation of the product
|
||||
4. Derived artifacts – MVP plan and Marketing model
|
||||
|
||||
Plus:
|
||||
|
||||
- A small pipeline that goes:
|
||||
1) knowledge → product insights
|
||||
2) product insights → canonical model
|
||||
3) canonical model → MVP plan
|
||||
4) canonical model → marketing model
|
||||
|
||||
- A provider-agnostic **LlmClient** that can talk to Gemini now and later GPT/Sonnet.
|
||||
|
||||
Use the existing stack / frameworks in this repo (TypeScript / Next / Prisma / etc. as appropriate).
|
||||
|
||||
|
||||
==================================================
|
||||
🧱 2. DATA MODEL TO IMPLEMENT
|
||||
==================================================
|
||||
|
||||
Please implement or adapt the following data model (adjust names to match repo conventions).
|
||||
|
||||
### 2.1 Project
|
||||
|
||||
Represents one product idea.
|
||||
|
||||
TypeScript shape:
|
||||
|
||||
```ts
|
||||
export type Phase =
|
||||
| "collector" // collecting knowledge
|
||||
| "analyzed" // product_insights written
|
||||
| "vision_ready" // canonical product model written
|
||||
| "mvp_ready" // mvp_plan written
|
||||
| "marketing_ready"; // marketing_model written
|
||||
|
||||
export interface Project {
|
||||
id: string;
|
||||
ownerId: string;
|
||||
name: string;
|
||||
description: string | null;
|
||||
currentPhase: Phase;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
|
||||
Create or align an existing database table with this shape (Prisma, SQL, or whatever ORM we use).
|
||||
|
||||
2.2 Knowledge base (all user raw materials)
|
||||
|
||||
All docs, past chats, notes, specs, etc. roll into a single table.
|
||||
|
||||
export type SourceType =
|
||||
| "user_chat"
|
||||
| "imported_chat"
|
||||
| "doc"
|
||||
| "note"
|
||||
| "spec"
|
||||
| "research"
|
||||
| "other";
|
||||
|
||||
export interface KnowledgeItem {
|
||||
id: string;
|
||||
projectId: string;
|
||||
sourceType: SourceType;
|
||||
title: string | null;
|
||||
content: string; // normalized text
|
||||
sourceMeta: {
|
||||
origin?: "chatgpt" | "notion" | "github" | "file_upload" | "manual";
|
||||
url?: string;
|
||||
filename?: string;
|
||||
createdAtOriginal?: string;
|
||||
};
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
|
||||
Implement a knowledge_items table (or equivalent) and any necessary migration.
|
||||
|
||||
2.3 Canonical Product Model (central brain)
|
||||
|
||||
This is the single source of truth for the product’s understanding in the system.
|
||||
|
||||
export interface CanonicalProductModel {
|
||||
projectId: string; // PK/FK to Project.id
|
||||
|
||||
basics: {
|
||||
productName: string | null;
|
||||
oneLiner: string | null;
|
||||
};
|
||||
|
||||
users: {
|
||||
primaryUser: string | null;
|
||||
userSegments: Array<{
|
||||
id: string;
|
||||
description: string;
|
||||
jobsToBeDone: string[];
|
||||
context: string | null;
|
||||
}>;
|
||||
};
|
||||
|
||||
problemSpace: {
|
||||
primaryProblem: string | null;
|
||||
secondaryProblems: string[];
|
||||
currentAlternatives: string[];
|
||||
pains: string[];
|
||||
};
|
||||
|
||||
solutionSpace: {
|
||||
coreSolution: string | null;
|
||||
keyFeatures: string[];
|
||||
differentiators: string[];
|
||||
constraints: string[];
|
||||
};
|
||||
|
||||
business: {
|
||||
valueProposition: string | null;
|
||||
whyNow: string | null;
|
||||
roughPricingIdeas: string[];
|
||||
};
|
||||
|
||||
meta: {
|
||||
lastUpdatedFromExtraction: string | null; // ISO date
|
||||
lastManualEditAt: string | null; // ISO date
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Store this as a single row per project, with a JSON column if we’re using a relational DB. Name could be product_model or canonical_product_model.
|
||||
|
||||
2.4 Product Insights (evidence layer)
|
||||
|
||||
This is the “extracted signals” from raw knowledge.
|
||||
|
||||
export interface ProductInsights {
|
||||
projectId: string;
|
||||
|
||||
problems: Array<{ id: string; description: string; evidence: string[] }>;
|
||||
users: Array<{ id: string; description: string; evidence: string[] }>;
|
||||
desires: Array<{ id: string; description: string; evidence: string[] }>;
|
||||
features: Array<{ id: string; description: string; evidence: string[] }>;
|
||||
constraints: Array<{ id: string; description: string; evidence: string[] }>;
|
||||
competitors: Array<{ id: string; description: string; evidence: string[] }>;
|
||||
|
||||
uncertainties: Array<{ id: string; description: string; relatedTo?: string }>;
|
||||
missingInformation: Array<{ id: string; question: string }>;
|
||||
|
||||
lastRunAt: string; // ISO date
|
||||
modelUsed: "gemini" | "gpt" | "sonnet";
|
||||
}
|
||||
|
||||
|
||||
Again: one row per project, as JSON.
|
||||
|
||||
2.5 MVP Plan (derived from canonical model)
|
||||
export interface MvpPlan {
|
||||
projectId: string;
|
||||
|
||||
guidingPrinciples: string[];
|
||||
coreUserFlows: Array<{
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
steps: string[];
|
||||
successCriteria: string[];
|
||||
}>;
|
||||
coreFeatures: Array<{
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
userFlowIds: string[];
|
||||
}>;
|
||||
supportingFeatures: Array<{
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
}>;
|
||||
outOfScope: Array<{
|
||||
id: string;
|
||||
description: string;
|
||||
reasonDeferred: string;
|
||||
}>;
|
||||
|
||||
lastRunAt: string; // ISO date
|
||||
modelUsed: "gemini" | "gpt" | "sonnet";
|
||||
}
|
||||
|
||||
2.6 Marketing Model (also derived from canonical model)
|
||||
export interface MarketingModel {
|
||||
projectId: string;
|
||||
|
||||
icp: {
|
||||
summary: string;
|
||||
segments: Array<{
|
||||
id: string;
|
||||
description: string;
|
||||
jobsToBeDone: string[];
|
||||
keyPains: string[];
|
||||
buyingTriggers: string[];
|
||||
}>;
|
||||
};
|
||||
|
||||
positioning: {
|
||||
category: string;
|
||||
targetAudience: string;
|
||||
primaryBenefit: string;
|
||||
reasonsToBelieve: string[];
|
||||
};
|
||||
|
||||
messaging: {
|
||||
hero: {
|
||||
headline: string;
|
||||
subheadline: string;
|
||||
primaryCta: string;
|
||||
bullets: string[];
|
||||
};
|
||||
sections: Array<{
|
||||
id: string;
|
||||
title: string;
|
||||
body: string;
|
||||
bullets: string[];
|
||||
}>;
|
||||
};
|
||||
|
||||
launchIdeas: {
|
||||
initialChannels: string[];
|
||||
angles: string[];
|
||||
exampleCampaigns: string[];
|
||||
};
|
||||
|
||||
lastRunAt: string; // ISO
|
||||
modelUsed: "gemini" | "gpt" | "sonnet";
|
||||
}
|
||||
|
||||
|
||||
Please create appropriate types in something like /lib/ai/types.ts (or adapt to existing file) and DB schema/migrations to persist these models.
|
||||
|
||||
==================================================
|
||||
🤖 3. LLM CLIENT ABSTRACTION (WITH GEMINI RUNTIME)
|
||||
|
||||
Implement a small, provider-agnostic LLM client.
|
||||
|
||||
3.1 Interface
|
||||
|
||||
Create something like /lib/ai/llm-client.ts:
|
||||
|
||||
export type LlmModel = "gemini" | "gpt" | "sonnet";
|
||||
|
||||
export interface LlmMessage {
|
||||
role: "system" | "user" | "assistant";
|
||||
content: string;
|
||||
}
|
||||
|
||||
export interface StructuredCallArgs<TOutput> {
|
||||
model: LlmModel;
|
||||
systemPrompt: string;
|
||||
messages: LlmMessage[];
|
||||
schema: import("zod").ZodSchema<TOutput>;
|
||||
temperature?: number;
|
||||
}
|
||||
|
||||
export interface LlmClient {
|
||||
structuredCall<TOutput>(args: StructuredCallArgs<TOutput>): Promise<TOutput>;
|
||||
}
|
||||
|
||||
3.2 Gemini implementation (runtime)
|
||||
|
||||
Implement a GeminiLlmClient that:
|
||||
|
||||
Ignores other models for now (only supports model: "gemini").
|
||||
|
||||
Uses the existing Gemini 2.5 Pro client in this repo.
|
||||
|
||||
Requests JSON / structured responses if the API supports it (e.g., response_mime_type: "application/json").
|
||||
|
||||
Validates the result against the provided Zod schema.
|
||||
|
||||
On parse/validation error:
|
||||
|
||||
Optionally retry once with a “fix your JSON” system hint.
|
||||
|
||||
Otherwise throw a well-typed error.
|
||||
|
||||
Wire this into where we currently call Gemini so that future GPT/Sonnet support only touches this layer.
|
||||
|
||||
==================================================
|
||||
🧠 4. AGENT FUNCTIONS / PIPELINE
|
||||
|
||||
Create a small pipeline that uses the LlmClient to transform data through four steps.
|
||||
|
||||
Place them in something like /lib/ai/agents/:
|
||||
|
||||
extractorAgent – knowledge → ProductInsights
|
||||
|
||||
productModelAgent – ProductInsights → CanonicalProductModel
|
||||
|
||||
mvpAgent – CanonicalProductModel → MvpPlan
|
||||
|
||||
marketingAgent – CanonicalProductModel → MarketingModel
|
||||
|
||||
4.1 extractorAgent
|
||||
|
||||
Signature:
|
||||
|
||||
export async function extractorAgent(
|
||||
knowledge: KnowledgeItem[],
|
||||
llm: LlmClient
|
||||
): Promise<ProductInsights>
|
||||
|
||||
|
||||
Behavior:
|
||||
|
||||
Serialize the knowledge array to JSON.
|
||||
|
||||
Use a clear system prompt that says: “You are a Product Insight Extraction Agent. Read the knowledge items and output only JSON matching this schema: (ProductInsights).”
|
||||
|
||||
Call llm.structuredCall<ProductInsights>({ model: "gemini", ... }).
|
||||
|
||||
Return the validated result.
|
||||
|
||||
4.2 productModelAgent
|
||||
|
||||
Signature:
|
||||
|
||||
export async function productModelAgent(
|
||||
insights: ProductInsights,
|
||||
existingModel: CanonicalProductModel | null,
|
||||
llm: LlmClient
|
||||
): Promise<CanonicalProductModel>
|
||||
|
||||
|
||||
Behavior:
|
||||
|
||||
Prompt: “You are a Product Model Builder. Given product insights, create or refine the canonical product model JSON matching this schema…”
|
||||
|
||||
If existingModel is present, include it in the prompt and ask the model to refine rather than start from scratch.
|
||||
|
||||
Use structuredCall with the CanonicalProductModel schema.
|
||||
|
||||
4.3 mvpAgent
|
||||
|
||||
Signature:
|
||||
|
||||
export async function mvpAgent(
|
||||
model: CanonicalProductModel,
|
||||
llm: LlmClient
|
||||
): Promise<MvpPlan>
|
||||
|
||||
|
||||
Behavior:
|
||||
|
||||
Prompt: “You are an MVP Planner. Given this canonical product model, produce the smallest sellable V1 plan as JSON matching the MvpPlan schema…”
|
||||
|
||||
Uses structuredCall and returns MvpPlan.
|
||||
|
||||
4.4 marketingAgent
|
||||
|
||||
Signature:
|
||||
|
||||
export async function marketingAgent(
|
||||
model: CanonicalProductModel,
|
||||
llm: LlmClient
|
||||
): Promise<MarketingModel>
|
||||
|
||||
|
||||
Behavior:
|
||||
|
||||
Prompt: “You are a Marketing Strategist. Given this canonical product model, produce an ICP + positioning + messaging + launch ideas as JSON matching the MarketingModel schema…”
|
||||
|
||||
Uses structuredCall and returns MarketingModel.
|
||||
|
||||
==================================================
|
||||
🔀 5. ORCHESTRATOR / PIPELINE RUNNER
|
||||
|
||||
Create a small pipeline runner, e.g. /lib/ai/pipeline.ts:
|
||||
|
||||
export async function runFullPipeline(projectId: string, llm: LlmClient) {
|
||||
const project = await loadProject(projectId);
|
||||
const knowledge = await loadKnowledgeItems(projectId);
|
||||
const current = await loadAllModels(projectId); // insights, canonical, mvp, marketing
|
||||
|
||||
// 1) knowledge -> insights
|
||||
const insights = await extractorAgent(knowledge, llm);
|
||||
await saveProductInsights(projectId, insights);
|
||||
await updateProjectPhase(projectId, "analyzed");
|
||||
|
||||
// 2) insights -> canonical product model
|
||||
const canonical = await productModelAgent(
|
||||
insights,
|
||||
current.canonicalProductModel ?? null,
|
||||
llm
|
||||
);
|
||||
await saveCanonicalProductModel(projectId, canonical);
|
||||
await updateProjectPhase(projectId, "vision_ready");
|
||||
|
||||
// 3) canonical -> MVP
|
||||
const mvp = await mvpAgent(canonical, llm);
|
||||
await saveMvpPlan(projectId, mvp);
|
||||
await updateProjectPhase(projectId, "mvp_ready");
|
||||
|
||||
// 4) canonical -> marketing
|
||||
const marketing = await marketingAgent(canonical, llm);
|
||||
await saveMarketingModel(projectId, marketing);
|
||||
await updateProjectPhase(projectId, "marketing_ready");
|
||||
|
||||
return { insights, canonical, mvp, marketing };
|
||||
}
|
||||
|
||||
|
||||
Please implement the helper functions (loadProject, loadKnowledgeItems, saveProductInsights, etc.) against whatever DB / ORM we use.
|
||||
|
||||
==================================================
|
||||
🌐 6. API ENDPOINTS
|
||||
|
||||
Implement or refactor API routes so that:
|
||||
|
||||
POST /api/projects
|
||||
|
||||
Creates a new project.
|
||||
|
||||
Sets currentPhase = "collector".
|
||||
|
||||
GET /api/projects/:id
|
||||
|
||||
Returns project and which artifacts exist (hasInsights, hasProductModel, hasMvp, hasMarketing).
|
||||
|
||||
GET /api/projects/:id/knowledge and POST /api/projects/:id/knowledge
|
||||
|
||||
Manage KnowledgeItems (list and add).
|
||||
|
||||
POST /api/projects/:id/run-pipeline
|
||||
|
||||
Calls runFullPipeline(projectId, llmClient).
|
||||
|
||||
Returns the updated artifacts + project phase.
|
||||
|
||||
GET /api/projects/:id/artifacts
|
||||
|
||||
Returns { productInsights, canonicalProductModel, mvpPlan, marketingModel }.
|
||||
|
||||
You may reuse existing routes where it makes sense; the important thing is that the data model and pipeline above exist and are wired to Gemini via the LlmClient abstraction.
|
||||
|
||||
==================================================
|
||||
✅ 7. HOW TO PROCEED
|
||||
|
||||
Scan the repo and see what already exists that overlaps with this design.
|
||||
|
||||
Propose a mapping (which existing files/types you’ll reuse vs replace).
|
||||
|
||||
Implement the data model (types + DB schema) and LlmClient abstraction.
|
||||
|
||||
Implement the four agents and the runFullPipeline function.
|
||||
|
||||
Hook up the API endpoints.
|
||||
|
||||
Keep changes incremental and explain major decisions as code comments.
|
||||
|
||||
Throughout, remember:
|
||||
|
||||
At runtime, the Vibn agent uses Gemini 2.5 Pro via our LlmClient.
|
||||
|
||||
You (Sonnet in Cursor) are here to design and write the code, not to be the runtime model
|
||||
Reference in New Issue
Block a user