@tritard/waterbrother 0.14.13 → 0.14.15

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 +45 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tritard/waterbrother",
3
- "version": "0.14.13",
3
+ "version": "0.14.15",
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
@@ -5357,7 +5357,8 @@ Be concrete about surfaces — name actual pages/flows. Choose the best stack fo
5357
5357
  }
5358
5358
 
5359
5359
  // Product builder actions: "build", "deploy", "adjust", "show surfaces"
5360
- const product = context.runtime.product || await loadProduct(context.cwd);
5360
+ // Only active in standard/guide mode — expert mode uses the cockpit
5361
+ const product = (currentMode !== "expert") ? (context.runtime.product || await loadProduct(context.cwd)) : null;
5361
5362
  if (product) {
5362
5363
  context.runtime.product = product;
5363
5364
  const lower = line.trim().toLowerCase();
@@ -5614,6 +5615,49 @@ Be concrete about surfaces — name actual pages/flows. Choose the best stack fo
5614
5615
  }
5615
5616
 
5616
5617
  const routed = routeNaturalInput(line, { task: context.runtime.activeTask });
5618
+
5619
+ // Sticky passes: when an active task is in a decision/review state and input
5620
+ // doesn't match a known command, keep the user in context instead of dropping to chat
5621
+ if ((!routed || routed.kind === "none" || routed.kind === "chat") && currentMode === "expert") {
5622
+ const stickyTask = context.runtime.activeTask;
5623
+ if (stickyTask) {
5624
+ const lower = line.trim().toLowerCase();
5625
+
5626
+ // In decision-ready: free-form input = re-decide with the feedback as new constraint
5627
+ if (stickyTask.state === "decision-ready") {
5628
+ const newGoal = stickyTask.goal ? `${stickyTask.goal}. Additional requirement: ${line}` : line;
5629
+ try {
5630
+ await runNaturalDecision({ task: stickyTask, goal: newGoal, invent: false });
5631
+ } catch (error) {
5632
+ console.log(error instanceof Error ? error.message : String(error));
5633
+ }
5634
+ return true;
5635
+ }
5636
+
5637
+ // In build-ready: free-form input = adjust the approach then build
5638
+ if (stickyTask.state === "build-ready") {
5639
+ if (/\b(but|also|and|with|without|instead|actually|change|different)\b/i.test(lower)) {
5640
+ // Feedback on chosen option — re-decide with constraint
5641
+ const newGoal = stickyTask.goal ? `${stickyTask.goal}. Constraint: ${line}` : line;
5642
+ try {
5643
+ await runNaturalDecision({ task: stickyTask, goal: newGoal, invent: false });
5644
+ } catch (error) {
5645
+ console.log(error instanceof Error ? error.message : String(error));
5646
+ }
5647
+ return true;
5648
+ }
5649
+ }
5650
+
5651
+ // In review-ready: free-form input = feedback on the review
5652
+ if (stickyTask.state === "review-ready") {
5653
+ const receipt = context.runtime.lastReceipt;
5654
+ const concerns = latestReviewConcerns(receipt);
5655
+ const prompt = `User feedback on the build: ${line}. ${concerns.length > 0 ? `Previous concerns: ${concerns.join("; ")}` : ""}`;
5656
+ return { rewrittenLine: `/build ${prompt}` };
5657
+ }
5658
+ }
5659
+ }
5660
+
5617
5661
  if (!routed || routed.kind === "none" || routed.kind === "chat") return false;
5618
5662
 
5619
5663
  try {