@tritard/waterbrother 0.12.0 → 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/cli.js +49 -13
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tritard/waterbrother",
3
- "version": "0.12.0",
3
+ "version": "0.12.1",
4
4
  "description": "Waterbrother: Grok-powered coding CLI with local tools, sessions, operator modes, and approval controls",
5
5
  "type": "module",
6
6
  "bin": {
package/src/cli.js CHANGED
@@ -5012,10 +5012,33 @@ async function promptLoop(agent, session, context) {
5012
5012
  // Product builder intake: detect "I want a recipe app" in any mode
5013
5013
  if (detectProductRequest(line)) {
5014
5014
  const intent = parseProductIntent(line);
5015
- const spinner = createProgressSpinner("understanding your product...");
5016
5015
 
5016
+ // Multi-turn brief intake — ask the right questions
5017
+ const questions = [
5018
+ { key: "type", prompt: "Web app or mobile? [web]", default: intent.type || "web" },
5019
+ { key: "audience", prompt: "Who is this for?", default: "" },
5020
+ { key: "taste", prompt: "Visual style? (e.g. clean, bold, minimal, playful) [clean and modern]", default: "clean and modern" },
5021
+ { key: "deploy", prompt: "Deploy where? (vercel, netlify, github-pages) [vercel]", default: "vercel" }
5022
+ ];
5023
+
5024
+ const answers = { type: intent.type || "web", audience: "", taste: "clean and modern", deploy: "vercel" };
5025
+
5026
+ console.log(`\n${bold("Let's scope this out.")}`);
5027
+
5028
+ for (const q of questions) {
5029
+ try {
5030
+ const raw = await promptLine(` ${q.prompt} `, { input: process.stdin, output: process.stdout });
5031
+ const answer = raw.trim();
5032
+ if (answer) answers[q.key] = answer;
5033
+ else answers[q.key] = q.default;
5034
+ } catch {
5035
+ answers[q.key] = q.default;
5036
+ }
5037
+ }
5038
+
5039
+ // Now use the LLM to generate the full brief with user context
5040
+ const spinner = createProgressSpinner("building your blueprint...");
5017
5041
  try {
5018
- // Ask the model to extract product details via structured JSON
5019
5042
  const { createJsonCompletion } = await import("./grok-client.js");
5020
5043
  const model = context.runtime.plannerModel || agent.getModel();
5021
5044
  const completion = await createJsonCompletion({
@@ -5023,19 +5046,16 @@ async function promptLoop(agent, session, context) {
5023
5046
  baseUrl: context.runtime.baseUrl,
5024
5047
  model,
5025
5048
  messages: [
5026
- { role: "system", content: `You are a product strategist. Extract a product brief from the user's request. Respond with JSON only:
5049
+ { role: "system", content: `You are a product strategist. Given the user's request and answers, create a product brief. Respond with JSON only:
5027
5050
  {
5028
5051
  "name": "short product name",
5029
5052
  "description": "one-sentence description",
5030
- "audience": "who is this for",
5031
- "type": "web|mobile|api|cli|desktop",
5032
- "surfaces": ["Landing", "Login", "Dashboard", "Settings"],
5053
+ "surfaces": ["Landing", "Login", "Dashboard"],
5033
5054
  "stack": { "framework": "Next.js", "styling": "Tailwind", "backend": "Supabase", "auth": "email", "deploy": "Vercel" },
5034
- "taste": "visual style in 3-5 words",
5035
5055
  "features": ["feature 1", "feature 2"]
5036
5056
  }
5037
- Infer reasonable defaults. Keep it practical.` },
5038
- { role: "user", content: line }
5057
+ Be concrete about surfaces — name actual pages/flows. Infer features from the request.` },
5058
+ { role: "user", content: `Request: ${line}\nType: ${answers.type}\nAudience: ${answers.audience}\nStyle: ${answers.taste}\nDeploy: ${answers.deploy}` }
5039
5059
  ],
5040
5060
  temperature: 0.3
5041
5061
  });
@@ -5048,8 +5068,8 @@ Infer reasonable defaults. Keep it practical.` },
5048
5068
  const product = createProduct({
5049
5069
  name: brief.name || intent.name || "My Product",
5050
5070
  description: brief.description || line,
5051
- audience: brief.audience || "",
5052
- type: brief.type || intent.type
5071
+ audience: answers.audience,
5072
+ type: answers.type
5053
5073
  });
5054
5074
 
5055
5075
  // Apply template if detected
@@ -5058,11 +5078,12 @@ Infer reasonable defaults. Keep it practical.` },
5058
5078
  applyTemplate(product, templateType);
5059
5079
  }
5060
5080
 
5061
- // Fill in details from the brief (overrides template defaults)
5081
+ // Fill in from brief + answers
5062
5082
  if (brief.stack) {
5063
5083
  product.stack = { ...product.stack, ...brief.stack };
5064
5084
  }
5065
- if (brief.taste) product.qualityBar.taste = brief.taste;
5085
+ product.stack.deploy = answers.deploy;
5086
+ product.qualityBar.taste = answers.taste;
5066
5087
  if (Array.isArray(brief.surfaces)) {
5067
5088
  for (const s of brief.surfaces) {
5068
5089
  addSurface(product, { name: s, type: "page", status: "planned" });
@@ -5186,6 +5207,21 @@ Infer reasonable defaults. Keep it practical.` },
5186
5207
  return true;
5187
5208
  }
5188
5209
 
5210
+ // Mode transitions: builder ↔ cockpit
5211
+ if (/^(show me the code|show code|view code|drop into code|engineering mode|cockpit)$/.test(lower)) {
5212
+ agent.setExperienceMode("expert");
5213
+ console.log("switched to expert mode — cockpit active");
5214
+ console.log(dim("use /feature to start a structured task, or type what to work on"));
5215
+ updatePanel();
5216
+ return true;
5217
+ }
5218
+ if (/^(back to builder|builder mode|just build|product mode|guide mode)$/.test(lower)) {
5219
+ agent.setExperienceMode("guide");
5220
+ console.log("switched to guide mode — product builder active");
5221
+ console.log(generateBlueprint(product));
5222
+ return true;
5223
+ }
5224
+
5189
5225
  if (/^(adjust|change|modify)$/.test(lower)) {
5190
5226
  console.log(generateBlueprint(product));
5191
5227
  console.log("\nDescribe what to adjust (e.g. 'add a settings page' or 'change auth to Google')");