@kenkaiiii/ggcoder 4.8.2 → 4.8.4

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 (45) hide show
  1. package/dist/core/prompt-commands.d.ts.map +1 -1
  2. package/dist/core/prompt-commands.js +20 -7
  3. package/dist/core/prompt-commands.js.map +1 -1
  4. package/dist/ui/App.d.ts +16 -0
  5. package/dist/ui/App.d.ts.map +1 -1
  6. package/dist/ui/App.js +53 -16
  7. package/dist/ui/App.js.map +1 -1
  8. package/dist/ui/atomic-flush-regression.test.d.ts +2 -0
  9. package/dist/ui/atomic-flush-regression.test.d.ts.map +1 -0
  10. package/dist/ui/atomic-flush-regression.test.js +218 -0
  11. package/dist/ui/atomic-flush-regression.test.js.map +1 -0
  12. package/dist/ui/components/AssistantMessage.test.js +25 -0
  13. package/dist/ui/components/AssistantMessage.test.js.map +1 -1
  14. package/dist/ui/components/Markdown.d.ts.map +1 -1
  15. package/dist/ui/components/Markdown.js +9 -1
  16. package/dist/ui/components/Markdown.js.map +1 -1
  17. package/dist/ui/footer-jump-regression.test.js +56 -9
  18. package/dist/ui/footer-jump-regression.test.js.map +1 -1
  19. package/dist/ui/frame-clip-regression.test.d.ts +2 -0
  20. package/dist/ui/frame-clip-regression.test.d.ts.map +1 -0
  21. package/dist/ui/frame-clip-regression.test.js +215 -0
  22. package/dist/ui/frame-clip-regression.test.js.map +1 -0
  23. package/dist/ui/hooks/useTranscriptHistory.d.ts +9 -1
  24. package/dist/ui/hooks/useTranscriptHistory.d.ts.map +1 -1
  25. package/dist/ui/hooks/useTranscriptHistory.js +34 -19
  26. package/dist/ui/hooks/useTranscriptHistory.js.map +1 -1
  27. package/dist/ui/live-item-flush.d.ts +21 -0
  28. package/dist/ui/live-item-flush.d.ts.map +1 -1
  29. package/dist/ui/live-item-flush.js +35 -0
  30. package/dist/ui/live-item-flush.js.map +1 -1
  31. package/dist/ui/live-item-flush.test.js +72 -1
  32. package/dist/ui/live-item-flush.test.js.map +1 -1
  33. package/dist/ui/render.d.ts.map +1 -1
  34. package/dist/ui/render.js +126 -1
  35. package/dist/ui/render.js.map +1 -1
  36. package/dist/ui/startup-banner-order.test.d.ts +2 -0
  37. package/dist/ui/startup-banner-order.test.d.ts.map +1 -0
  38. package/dist/ui/startup-banner-order.test.js +105 -0
  39. package/dist/ui/startup-banner-order.test.js.map +1 -0
  40. package/dist/ui/streaming-flush-bounce.test.js +41 -20
  41. package/dist/ui/streaming-flush-bounce.test.js.map +1 -1
  42. package/dist/ui/testing/screen-recorder.d.ts.map +1 -1
  43. package/dist/ui/testing/screen-recorder.js +11 -1
  44. package/dist/ui/testing/screen-recorder.js.map +1 -1
  45. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"file":"prompt-commands.d.ts","sourceRoot":"","sources":["../../src/core/prompt-commands.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,eAAe,EAAE,aAAa,EAylB1C,CAAC;AAEF,gDAAgD;AAChD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAExE"}
1
+ {"version":3,"file":"prompt-commands.d.ts","sourceRoot":"","sources":["../../src/core/prompt-commands.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,eAAe,EAAE,aAAa,EAsmB1C,CAAC;AAEF,gDAAgD;AAChD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAExE"}
@@ -342,7 +342,7 @@ End your reply with this exact notice so the user doesn't miss it:
342
342
  name: "setup-commit",
343
343
  aliases: [],
344
344
  description: "Generate a /commit command",
345
- prompt: `Detect the project type and generate a /commit command that enforces quality checks before committing.
345
+ prompt: `Detect the project type and generate a /commit command that enforces quality checks and an agent code review before committing.
346
346
 
347
347
  ## Step 1: Detect Project and Extract Commands
348
348
 
@@ -361,7 +361,7 @@ Create the directory \`.gg/commands/\` if it doesn't exist, then write \`.gg/com
361
361
  \`\`\`markdown
362
362
  ---
363
363
  name: commit
364
- description: Run checks, commit with AI message, and push
364
+ description: Run checks, agent code review, commit with AI message, and push
365
365
  ---
366
366
 
367
367
  1. Run quality checks:
@@ -370,24 +370,37 @@ description: Run checks, commit with AI message, and push
370
370
 
371
371
  2. Review changes: run git status and git diff --staged and git diff
372
372
 
373
- 3. Stage relevant files with git add (specific files, not -A)
373
+ 3. Fast review gate: spawn ONE subagent with the full diff. Instructions: review ONLY
374
+ the diff for real bugs, regressions, leftover debug code, and unintended changes.
375
+ Score each issue 0-100 confidence (pre-existing issues and stylistic nitpicks = false
376
+ positives, score low). Report ONLY issues with confidence >= 80, with file:line and a
377
+ one-line fix. If none, reply "CLEAR". This is a last check, not a deep audit - be fast.
374
378
 
375
- 4. Generate a commit message:
379
+ 4. If CLEAR: proceed straight to step 5 and push WITHOUT asking the user anything.
380
+ If issues >= 80 were reported: STOP, show the issues, and ask exactly:
381
+ "Want me to fix this first, or commit and push anyway?
382
+ A) Fix it first, then commit & push
383
+ B) Commit & push anyway"
384
+ On A: fix, re-run step 1, then continue (no re-review). On B: continue as-is.
385
+
386
+ 5. Stage relevant files with git add (specific files, not -A)
387
+
388
+ 6. Generate a commit message:
376
389
  - Start with verb (Add/Update/Fix/Remove/Refactor)
377
390
  - Be specific and concise, one line preferred
378
391
 
379
- 5. Commit and push:
392
+ 7. Commit AND push in one go - never pause for confirmation here:
380
393
  git commit -m "your generated message"
381
394
  git push
382
395
  \`\`\`
383
396
 
384
397
  Replace [PROJECT-SPECIFIC LINT/TYPECHECK COMMANDS] with the actual commands.
385
398
 
386
- Keep the command file under 20 lines.
399
+ Keep the command file under 30 lines.
387
400
 
388
401
  ## Step 3: Confirm
389
402
 
390
- Report that /commit is now available with quality checks and AI-generated commit messages, and mention which local scripts/docs verified the commands.`,
403
+ Report that /commit is now available with quality checks, an agent code review gate, and AI-generated commit messages, and mention which local scripts/docs verified the commands.`,
391
404
  },
392
405
  {
393
406
  name: "compare",
@@ -1 +1 @@
1
- {"version":3,"file":"prompt-commands.js","sourceRoot":"","sources":["../../src/core/prompt-commands.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,MAAM,CAAC,MAAM,eAAe,GAAoB;IAC9C;QACE,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,EAAE;QACX,WAAW,EAAE,mCAAmC;QAChD,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0KA4E8J;KACvK;IACD;QACE,IAAI,EAAE,cAAc;QACpB,OAAO,EAAE,CAAC,IAAI,CAAC;QACf,WAAW,EAAE,8BAA8B;QAC3C,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qEAsLyD;KAClE;IACD;QACE,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,EAAE;QACX,WAAW,EAAE,+CAA+C;QAC5D,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2MA2D+L;KACxM;IACD;QACE,IAAI,EAAE,cAAc;QACpB,OAAO,EAAE,EAAE;QACX,WAAW,EAAE,4BAA4B;QACzC,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uJA6C2I;KACpJ;IACD;QACE,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,EAAE;QACX,WAAW,EAAE,yBAAyB;QACtC,MAAM,EAAE;;;;;;;;;;;;;;;iFAeqE;KAC9E;IACD;QACE,IAAI,EAAE,cAAc;QACpB,OAAO,EAAE,EAAE;QACX,WAAW,EAAE,yBAAyB;QACtC,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gLA6FoK;KAC7K;IACD;QACE,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,CAAC,eAAe,CAAC;QAC1B,WAAW,EAAE,qBAAqB;QAClC,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6JAwFiJ;KAC1J;CACF,CAAC;AAEF,gDAAgD;AAChD,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,IAAI,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;AACxF,CAAC"}
1
+ {"version":3,"file":"prompt-commands.js","sourceRoot":"","sources":["../../src/core/prompt-commands.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,MAAM,CAAC,MAAM,eAAe,GAAoB;IAC9C;QACE,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,EAAE;QACX,WAAW,EAAE,mCAAmC;QAChD,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0KA4E8J;KACvK;IACD;QACE,IAAI,EAAE,cAAc;QACpB,OAAO,EAAE,CAAC,IAAI,CAAC;QACf,WAAW,EAAE,8BAA8B;QAC3C,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qEAsLyD;KAClE;IACD;QACE,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,EAAE;QACX,WAAW,EAAE,+CAA+C;QAC5D,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2MA2D+L;KACxM;IACD;QACE,IAAI,EAAE,cAAc;QACpB,OAAO,EAAE,EAAE;QACX,WAAW,EAAE,4BAA4B;QACzC,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mLA0DuK;KAChL;IACD;QACE,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,EAAE;QACX,WAAW,EAAE,yBAAyB;QACtC,MAAM,EAAE;;;;;;;;;;;;;;;iFAeqE;KAC9E;IACD;QACE,IAAI,EAAE,cAAc;QACpB,OAAO,EAAE,EAAE;QACX,WAAW,EAAE,yBAAyB;QACtC,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gLA6FoK;KAC7K;IACD;QACE,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,CAAC,eAAe,CAAC;QAC1B,WAAW,EAAE,qBAAqB;QAClC,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6JAwFiJ;KAC1J;CACF,CAAC;AAEF,gDAAgD;AAChD,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,IAAI,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;AACxF,CAAC"}
package/dist/ui/App.d.ts CHANGED
@@ -65,6 +65,22 @@ export interface AppProps {
65
65
  onExitPlan?: (planPath: string) => Promise<string>;
66
66
  };
67
67
  terminalHistoryPrinter?: TerminalHistoryPrinter;
68
+ /**
69
+ * Wired by `renderApp`. Queues raw bytes through the patched Ink
70
+ * `insertBeforeFrame` so finalized transcript rows are folded atomically
71
+ * into the next frame write (erase old frame + scrollback bytes + new frame
72
+ * in one synchronized write). This is what keeps the footer pinned when
73
+ * flushed rows leave the live frame. Falls back to a raw stdout write when
74
+ * the patched API is unavailable.
75
+ */
76
+ enqueueHistoryWrite?: (data: string) => void;
77
+ /**
78
+ * Wired by `renderApp`. Enables/disables the patched Ink bottom-anchor pad
79
+ * creation. On while the agent runs (footer must not jump as the tool panel
80
+ * and status rows churn); off at idle so symmetric UI shrink (slash menu
81
+ * close, input collapse) lets the footer return up without leaving pads.
82
+ */
83
+ setFrameAnchorActive?: (active: boolean) => void;
68
84
  /**
69
85
  * When true, the UI runs in the alternate-screen fullscreen viewport: the
70
86
  * transcript is rendered inside Ink as a bounded, app-scrolled region above a
@@ -1 +1 @@
1
- {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/ui/App.tsx"],"names":[],"mappings":"AAqBA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,KAAK,aAAa,EAEnB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAcrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAwBjE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAkB,eAAe,EAAe,MAAM,6BAA6B,CAAC;AAEhG,OAAO,EAOL,KAAK,QAAQ,EACd,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAY3D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAQpE,OAAO,EAIL,KAAK,UAAU,EAChB,MAAM,uBAAuB,CAAC;AAS/B,OAAO,EAOL,KAAK,YAAY,EAClB,MAAM,sBAAsB,CAAC;AAY9B,OAAO,KAAK,EACV,aAAa,EAYd,MAAM,gBAAgB,CAAC;AAExB,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAOnE,YAAY,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,+BAA+B,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC/F,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EACL,6BAA6B,EAC7B,oBAAoB,EACpB,8BAA8B,EAC9B,mBAAmB,EACnB,gCAAgC,EAChC,qBAAqB,EACrB,+BAA+B,EAC/B,mCAAmC,EACnC,kCAAkC,EAClC,uCAAuC,EACvC,wCAAwC,EACxC,gCAAgC,GACjC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,sBAAsB,EACtB,YAAY,EACZ,kBAAkB,EAClB,kCAAkC,GACnC,MAAM,mBAAmB,CAAC;AAiB3B,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC3D,iBAAiB,CAAC,EAAE,QAAQ,EAAE,CAAC;IAC/B,qBAAqB,CAAC,EAAE,MAAM,CAC5B,MAAM,EACN;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAClF,CAAC;IACF,cAAc,CAAC,EAAE,aAAa,EAAE,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,WAAW,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IACnC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;IACjB,qEAAqE;IACrE,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,kBAAkB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,EAAE,CAAC;IAClD;+EAC2E;IAC3E,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,SAAS,CAAC;IAC/C,sBAAsB,CAAC,EAAE,MAAM,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IACpD,aAAa,CAAC,EAAE;QACd,WAAW,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QACxD,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;KACpD,CAAC;IACF,sBAAsB,CAAC,EAAE,sBAAsB,CAAC;IAChD;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE;QACnB,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;QACrB,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;QAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;QACvB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,aAAa,CAAC,EAAE;YACd,MAAM,EAAE,MAAM,CAAC;YACf,QAAQ,CAAC,EAAE,MAAM,CAAC;YAClB,SAAS,CAAC,EAAE;gBAAE,KAAK,EAAE,UAAU,GAAG,UAAU,GAAG,WAAW,CAAC;gBAAC,MAAM,CAAC,EAAE,MAAM,CAAA;aAAE,CAAC;SAC/E,CAAC;KACH,KAAK,IAAI,CAAC;IACX;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE;QAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,QAAQ,CAAC;QACpB,QAAQ,CAAC,EAAE,aAAa,CAAC;KAC1B,KAAK,IAAI,CAAC;IACX;;;;;OAKG;IACH,YAAY,CAAC,EAAE;QACb,QAAQ,EAAE,OAAO,EAAE,CAAC;QACpB,OAAO,EAAE,aAAa,EAAE,CAAC;QACzB,SAAS,CAAC,EAAE,aAAa,EAAE,CAAC;QAC5B,UAAU,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;QAC/B,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,SAAS,EAAE,QAAQ,EAAE,CAAC;QACtB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,qBAAqB,EAAE,OAAO,CAAC;QAC/B,OAAO,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,IAAI,CAAC;QACjE,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,aAAa,CAAC,EAAE;YACd,MAAM,EAAE,MAAM,CAAC;YACf,QAAQ,CAAC,EAAE,MAAM,CAAC;YAClB,SAAS,CAAC,EAAE;gBAAE,KAAK,EAAE,UAAU,GAAG,UAAU,GAAG,WAAW,CAAC;gBAAC,MAAM,CAAC,EAAE,MAAM,CAAA;aAAE,CAAC;SAC/E,CAAC;QACF,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,YAAY,CAAC,EAAE,YAAY,CAAC;QAC5B,kBAAkB,CAAC,EAAE,OAAO,CAAC;KAC9B,CAAC;CACH;AAuBD,wBAAgB,GAAG,CAAC,KAAK,EAAE,QAAQ,2CA8yFlC"}
1
+ {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/ui/App.tsx"],"names":[],"mappings":"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"}
package/dist/ui/App.js CHANGED
@@ -37,7 +37,7 @@ import { detectVerifyCommands } from "../core/verify-commands.js";
37
37
  import { RewindOverlay } from "./components/RewindOverlay.js";
38
38
  import { extractPlanSteps, findCompletedMarkers, markStepsCompleted, rebasePlanSteps, segmentDisplayText, stripDoneMarkers, } from "../utils/plan-steps.js";
39
39
  import { getAllMcpServers } from "../core/mcp/index.js";
40
- import { trimFlushedItems, flushOnTurnText, flushOnTurnEnd, flushOverflow, } from "./live-item-flush.js";
40
+ import { trimFlushedItems, flushOnTurnText, flushOnTurnEnd, flushOverflow, countOversizedFlushItems, } from "./live-item-flush.js";
41
41
  import { splitAssistantStreamingText, estimateRenderedRows, } from "./utils/assistant-stream-split.js";
42
42
  import { getNextPendingTask, markTaskInProgress } from "../core/tasks-store.js";
43
43
  import { buildUserContentWithAttachments } from "./prompt-routing.js";
@@ -97,6 +97,11 @@ export function App(props) {
97
97
  const switchTheme = useSetTheme();
98
98
  const { write: writeStdout } = useStdout();
99
99
  const { columns, rows } = useTerminalSize();
100
+ // Layout snapshot readable from agent-event callbacks (whose deps must stay
101
+ // stable). `liveAreaRows` is filled in by an effect after the chat layout is
102
+ // measured further down; 0 means "not measured yet" and disables the
103
+ // oversized-item flush below.
104
+ const liveLayoutRef = useRef({ columns, liveAreaRows: 0 });
100
105
  // Hoisted before terminal title hook so it can reference them
101
106
  const [lastUserMessage, setLastUserMessage] = useState("");
102
107
  // Bumped on every prompt submit; the fullscreen transcript scroll controller
@@ -269,6 +274,9 @@ export function App(props) {
269
274
  // accumulating in React state (still flushed + persisted) without any
270
275
  // stdout writes. The legacy scrollback path keeps the printer.
271
276
  terminalHistoryPrinter: props.fullscreen ? undefined : props.terminalHistoryPrinter,
277
+ // Atomic scrollback enqueue — only meaningful on the legacy scrollback
278
+ // path (fullscreen drops the printer entirely, so nothing is written).
279
+ enqueueStdout: props.fullscreen ? undefined : props.enqueueHistoryWrite,
272
280
  terminalHistoryContext: {
273
281
  theme,
274
282
  columns,
@@ -791,8 +799,23 @@ export function App(props) {
791
799
  const flushablePrev = prev.filter((item) => item.kind !== "assistant");
792
800
  if (flushablePrev.length > 0)
793
801
  queueFlush(flushablePrev);
802
+ // Finalized items taller than the live area can't stay pinned:
803
+ // streaming-time clamping no longer applies, so Ink would only
804
+ // paint the frame's bottom rows and the top of the response (e.g.
805
+ // a table header) would be invisible until the next turn's flush.
806
+ // The check is cumulative over the WHOLE pinned set (previously
807
+ // pinned assistant items + this turn's, which [DONE:N]
808
+ // segmentation can split into several): flush the leading prefix
809
+ // so the remaining suffix fits, preserving transcript order. The
810
+ // transcript-history layout effect removes the flushed ids from
811
+ // the live frame after printing.
812
+ const pinned = [...assistantItems, ...nextItems];
813
+ const layout = liveLayoutRef.current;
814
+ const oversizedCount = countOversizedFlushItems(pinned, (itemText) => estimateRenderedRows(itemText, layout.columns), layout.liveAreaRows);
815
+ if (oversizedCount > 0)
816
+ queueFlush(pinned.slice(0, oversizedCount));
794
817
  streamedAssistantFlushRef.current = { flushedChars: 0, text: "" };
795
- return [...assistantItems, ...nextItems];
818
+ return pinned;
796
819
  });
797
820
  }, [queueFlush]),
798
821
  onToolStart: useCallback((toolCallId, name, args, stream) => {
@@ -1439,6 +1462,22 @@ export function App(props) {
1439
1462
  return () => clearTimeout(timer);
1440
1463
  }
1441
1464
  }, [agentLoop.isRunning, sessionStore, props.resetUI]);
1465
+ // Bottom-anchor gating: pad creation on while the agent runs, off at idle.
1466
+ // The idle transition is delayed 500ms so the finalization commits (done
1467
+ // status swap, live-item clear, deferred flushes) all land while the anchor
1468
+ // still protects them; only then does idle UI (slash menu open/close, input
1469
+ // grow/shrink) regain natural symmetric footer movement.
1470
+ const setFrameAnchorActive = props.setFrameAnchorActive;
1471
+ useEffect(() => {
1472
+ if (!setFrameAnchorActive)
1473
+ return;
1474
+ if (agentLoop.isRunning) {
1475
+ setFrameAnchorActive(true);
1476
+ return;
1477
+ }
1478
+ const timer = setTimeout(() => setFrameAnchorActive(false), 500);
1479
+ return () => clearTimeout(timer);
1480
+ }, [agentLoop.isRunning, setFrameAnchorActive]);
1442
1481
  const showSessionSummaryAndExit = useCallback(() => {
1443
1482
  const summary = buildSessionSummary({
1444
1483
  stats: sessionStatsRef.current,
@@ -2166,17 +2205,19 @@ export function App(props) {
2166
2205
  taskBarExpanded,
2167
2206
  liveToolFeedCount: liveToolFeed.length,
2168
2207
  });
2208
+ useEffect(() => {
2209
+ liveLayoutRef.current = { columns, liveAreaRows: measuredLiveAreaRows };
2210
+ }, [columns, measuredLiveAreaRows]);
2169
2211
  const isPixelView = overlay === "pixel";
2170
2212
  const hasLiveAssistantItem = liveItems.some((item) => item.kind === "assistant");
2171
2213
  const rawVisibleStreamingText = hasLiveAssistantItem ? "" : agentLoop.streamingText;
2172
- // Compute the prospective paragraph flush DURING render so the live frame
2173
- // immediately drops the prefix that is about to be written to scrollback.
2174
- // The queueFlush below runs in an effect (after paint), so if the live text
2175
- // were sliced only by the already-committed `flushedChars`, the just-flushed
2176
- // paragraph would render BOTH in scrollback and live for one frame that
2177
- // transient extra height is what shoves the footer up and then back down on
2178
- // every chunk boundary. Slicing by the prospective flush here keeps the live
2179
- // frame height monotonic, so the footer never bounces.
2214
+ // The live text is sliced by the COMMITTED `flushedChars` only. When the
2215
+ // flush effect below queues a paragraph, queueFlush enqueues the rendered
2216
+ // bytes through the patched Ink `insertBeforeFrame` (passive no terminal
2217
+ // write) and the generation bump re-renders with the advanced flushedChars;
2218
+ // that commit's single frame write is `erase tall frame + paragraph bytes +
2219
+ // shorter frame`, so no frame ever shows the paragraph in both scrollback
2220
+ // and the live region, and the footer never bounces.
2180
2221
  const alreadyFlushedChars = streamedAssistantFlushRef.current.flushedChars;
2181
2222
  // Retry-safety gate: don't commit streamed paragraphs to permanent scrollback
2182
2223
  // while the text is still small enough to live entirely in the live region.
@@ -2194,10 +2235,6 @@ export function App(props) {
2194
2235
  ? estimateRenderedRows(rawVisibleStreamingText.slice(alreadyFlushedChars), columns)
2195
2236
  : 0;
2196
2237
  const shouldFlushStreamedText = alreadyFlushedChars > 0 || unflushedStreamingRows > measuredLiveAreaRows;
2197
- const pendingFlushChars = rawVisibleStreamingText && shouldFlushStreamedText
2198
- ? splitAssistantStreamingText(rawVisibleStreamingText.slice(alreadyFlushedChars)).flushedText
2199
- .length
2200
- : 0;
2201
2238
  useEffect(() => {
2202
2239
  if (!rawVisibleStreamingText) {
2203
2240
  streamedAssistantFlushRef.current = { flushedChars: 0, text: "" };
@@ -2235,7 +2272,7 @@ export function App(props) {
2235
2272
  text: rawVisibleStreamingText,
2236
2273
  };
2237
2274
  }, [rawVisibleStreamingText, shouldFlushStreamedText, queueFlush]);
2238
- const visibleStreamingText = stripDoneMarkers(rawVisibleStreamingText.slice(alreadyFlushedChars + pendingFlushChars));
2275
+ const visibleStreamingText = stripDoneMarkers(rawVisibleStreamingText.slice(alreadyFlushedChars));
2239
2276
  const lastLiveItem = liveItems.at(-1);
2240
2277
  // For spacing decisions, the previous row is the last item that actually
2241
2278
  // RENDERS. Panel-replaced tool items (now shown only in the LiveToolPanel)
@@ -2268,7 +2305,7 @@ export function App(props) {
2268
2305
  // When earlier paragraphs of THIS response were already flushed to scrollback
2269
2306
  // mid-stream, the live remainder is the next paragraph — re-insert the blank
2270
2307
  // line that separated them so the live tail lines up with the flushed history.
2271
- const streamingContinuesFlushed = alreadyFlushedChars + pendingFlushChars > 0;
2308
+ const streamingContinuesFlushed = alreadyFlushedChars > 0;
2272
2309
  // ── Fullscreen alt-screen transcript ───────────────────
2273
2310
  // Flatten history + live items + in-flight streaming into the flat ANSI line
2274
2311
  // buffer the viewport renders. Reuses the same serializer the legacy