@tritard/waterbrother 0.16.163 → 0.16.165

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tritard/waterbrother",
3
- "version": "0.16.163",
3
+ "version": "0.16.165",
4
4
  "description": "Waterbrother: bring-your-own-model coding CLI with local tools, sessions, operator modes, and approval controls",
5
5
  "type": "module",
6
6
  "bin": {
package/src/cli.js CHANGED
@@ -60,6 +60,7 @@ import { scanForInitiatives, formatInitiatives, buildInitiativeFixPrompt } from
60
60
  import { formatPlanForDisplay } from "./planner.js";
61
61
  import { categorizeError, formatErrorForUser, retryWithBackoff, isDoomLoop } from "./errors.js";
62
62
  import { parseCharterFromGoal, runExperimentLoop, formatExperimentSummary, gitReturnToBranch } from "./experiment.js";
63
+ import { gameInit, gameDesign, gameScaffold, gameImplement, gameStatus, gameNext, gameLoop } from "./game-pipeline.js";
63
64
  import {
64
65
  buildSelfAwarenessManifest,
65
66
  buildSelfAwarenessMemoryBlock,
@@ -253,7 +254,15 @@ const INTERACTIVE_COMMANDS = [
253
254
  { name: "/evolve approve <id>", description: "Approve a pending evolution proposal" },
254
255
  { name: "/evolve reject <id>", description: "Reject a pending evolution proposal" },
255
256
  { name: "/evolve revert <id>", description: "Revert an applied evolution patch" },
256
- { name: "/evolve history", description: "Show full evolution history with score deltas" }
257
+ { name: "/evolve history", description: "Show full evolution history with score deltas" },
258
+ { name: "/game init <description>", description: "Start a new game project" },
259
+ { name: "/game design [guidance]", description: "Generate or refine the game design document" },
260
+ { name: "/game scaffold", description: "Create project structure and scaffolding (deterministic)" },
261
+ { name: "/game implement [target]", description: "Build next step in current slice" },
262
+ { name: "/game status", description: "Show game workspace state" },
263
+ { name: "/game next", description: "Show the single best next action" },
264
+ { name: "/game advance", description: "Advance to the next slice (if current is complete)" },
265
+ { name: "/game loop", description: "Autopilot — status, next, execute with confirmation" }
257
266
  ];
258
267
 
259
268
  const AGENT_PROFILES = ["coder", "designer", "reviewer", "planner"];
@@ -10822,6 +10831,115 @@ Be concrete about surfaces — name actual pages/flows. Choose the best stack fo
10822
10831
  continue;
10823
10832
  }
10824
10833
 
10834
+ // ─── /game commands ────────────────────────────────────────
10835
+ if (line === "/game" || line.startsWith("/game ")) {
10836
+ const gameArgs = line.replace("/game", "").trim();
10837
+ const subCmd = gameArgs.split(/\s+/)[0] || "";
10838
+ const subArgs = gameArgs.slice(subCmd.length).trim();
10839
+ const gameCtx = {
10840
+ cwd: context.cwd,
10841
+ apiKey: context.runtime.apiKey,
10842
+ baseUrl: context.runtime.baseUrl,
10843
+ model: context.runtime.plannerModel || agent.getModel(),
10844
+ agent
10845
+ };
10846
+
10847
+ try {
10848
+ if (subCmd === "init") {
10849
+ if (!subArgs) { console.log("Usage: /game init <description>"); continue; }
10850
+ const spinner = createProgressSpinner("initializing game...");
10851
+ const result = await gameInit(subArgs, gameCtx);
10852
+ spinner.stop();
10853
+ console.log(result.display);
10854
+
10855
+ } else if (subCmd === "design") {
10856
+ const spinner = createProgressSpinner("generating game design...");
10857
+ const result = await gameDesign(gameCtx, subArgs || "");
10858
+ spinner.stop();
10859
+ console.log(result.display);
10860
+
10861
+ } else if (subCmd === "scaffold") {
10862
+ const result = await gameScaffold(gameCtx, (msg) => console.log(` ${msg}`));
10863
+ console.log(result.display);
10864
+
10865
+ } else if (subCmd === "implement") {
10866
+ const result = await gameImplement(gameCtx, subArgs || null, (msg) => console.log(` ${msg}`));
10867
+ console.log(result.display);
10868
+
10869
+ } else if (subCmd === "status") {
10870
+ const result = await gameStatus(gameCtx);
10871
+ console.log(result.display);
10872
+
10873
+ } else if (subCmd === "next") {
10874
+ if (subArgs === "--advance") {
10875
+ // Explicit slice advancement
10876
+ const { loadWorkspace: ldws, saveWorkspace: svws, advanceSlice: advsl } = await import("./game-workspace.js");
10877
+ const wsAdv = await ldws(gameCtx.cwd);
10878
+ if (!wsAdv) { console.log("No game workspace."); continue; }
10879
+ const advResult = advsl(wsAdv);
10880
+ if (advResult.advanced) {
10881
+ await svws(gameCtx.cwd, wsAdv);
10882
+ console.log(`Slice complete: ${advResult.completedSlice}`);
10883
+ console.log(`Next slice: ${advResult.nextSlice || "all done — ship it"}`);
10884
+ } else {
10885
+ console.log(`Cannot advance: ${advResult.reason}`);
10886
+ if (advResult.unmet) {
10887
+ for (const u of advResult.unmet) console.log(` o ${u}`);
10888
+ }
10889
+ }
10890
+ } else {
10891
+ const result = await gameNext(gameCtx);
10892
+ console.log(result.display);
10893
+ }
10894
+
10895
+ } else if (subCmd === "advance") {
10896
+ // Direct /game advance command
10897
+ const { loadWorkspace: ldws, saveWorkspace: svws, advanceSlice: advsl } = await import("./game-workspace.js");
10898
+ const wsAdv = await ldws(gameCtx.cwd);
10899
+ if (!wsAdv) { console.log("No game workspace."); continue; }
10900
+ const advResult = advsl(wsAdv);
10901
+ if (advResult.advanced) {
10902
+ await svws(gameCtx.cwd, wsAdv);
10903
+ console.log(`Slice complete: ${advResult.completedSlice}`);
10904
+ console.log(`Next slice: ${advResult.nextSlice || "all done — ship it"}`);
10905
+ } else {
10906
+ console.log(`Cannot advance: ${advResult.reason}`);
10907
+ if (advResult.unmet) {
10908
+ for (const u of advResult.unmet) console.log(` o ${u}`);
10909
+ }
10910
+ }
10911
+
10912
+ } else if (subCmd === "loop") {
10913
+ console.log("Starting game loop — autopilot with checkpoints.\n");
10914
+ const result = await gameLoop(gameCtx, {
10915
+ onProgress(msg) { console.log(msg); },
10916
+ async confirm(msg) {
10917
+ try {
10918
+ return await promptYesNo(msg, { input: process.stdin, output: process.stdout });
10919
+ } catch {
10920
+ return false;
10921
+ }
10922
+ }
10923
+ });
10924
+ console.log(`\nLoop completed: ${result.iterations} iterations.`);
10925
+
10926
+ } else {
10927
+ console.log("Game commands:");
10928
+ console.log(" /game init <description> Start a new game project");
10929
+ console.log(" /game design [guidance] Generate game design document");
10930
+ console.log(" /game scaffold Create project structure");
10931
+ console.log(" /game implement [target] Build next step");
10932
+ console.log(" /game status Show workspace state");
10933
+ console.log(" /game next Best next action");
10934
+ console.log(" /game advance Advance to next slice");
10935
+ console.log(" /game loop Autopilot with checkpoints");
10936
+ }
10937
+ } catch (error) {
10938
+ console.log(`game error: ${error instanceof Error ? error.message : String(error)}`);
10939
+ }
10940
+ continue;
10941
+ }
10942
+
10825
10943
  if (line === "/accept") {
10826
10944
  const task = context.runtime.activeTask;
10827
10945
  if (!task) { console.log("no active task"); continue; }