@pentoshi/clai 3.8.12 → 3.8.16

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 (72) hide show
  1. package/dist/agent/compaction-summary.d.ts +6 -1
  2. package/dist/agent/compaction-summary.js +11 -19
  3. package/dist/agent/compaction-summary.js.map +1 -1
  4. package/dist/agent/context-manager.d.ts +12 -0
  5. package/dist/agent/context-manager.js +15 -1
  6. package/dist/agent/context-manager.js.map +1 -1
  7. package/dist/agent/plan-implement-compact.d.ts +40 -0
  8. package/dist/agent/plan-implement-compact.js +78 -0
  9. package/dist/agent/plan-implement-compact.js.map +1 -0
  10. package/dist/agent/plan-mode-reminders.d.ts +42 -0
  11. package/dist/agent/plan-mode-reminders.js +61 -0
  12. package/dist/agent/plan-mode-reminders.js.map +1 -0
  13. package/dist/agent/runner.js +37 -8
  14. package/dist/agent/runner.js.map +1 -1
  15. package/dist/app/controllers/session-compact-helper.d.ts +9 -0
  16. package/dist/app/controllers/session-compact-helper.js +36 -0
  17. package/dist/app/controllers/session-compact-helper.js.map +1 -0
  18. package/dist/app/controllers/session-controller.d.ts +7 -1
  19. package/dist/app/controllers/session-controller.js +12 -39
  20. package/dist/app/controllers/session-controller.js.map +1 -1
  21. package/dist/prompts/embedded.js +1 -1
  22. package/dist/prompts/embedded.js.map +1 -1
  23. package/dist/prompts/index.d.ts +1 -1
  24. package/dist/prompts/index.js +16 -11
  25. package/dist/prompts/index.js.map +1 -1
  26. package/dist/prompts/system.agent.md +5 -1
  27. package/dist/store/history.js +7 -3
  28. package/dist/store/history.js.map +1 -1
  29. package/dist/tui-v2/app/App.js +28 -14
  30. package/dist/tui-v2/app/App.js.map +1 -1
  31. package/dist/tui-v2/app/commands/picker-commands.js +25 -9
  32. package/dist/tui-v2/app/commands/picker-commands.js.map +1 -1
  33. package/dist/tui-v2/app/plan-lifecycle.js +59 -0
  34. package/dist/tui-v2/app/plan-lifecycle.js.map +1 -1
  35. package/dist/tui-v2/bootstrap/composition-root.js +13 -3
  36. package/dist/tui-v2/bootstrap/composition-root.js.map +1 -1
  37. package/dist/tui-v2/components/modal/prompt-actions-modal.d.ts +4 -3
  38. package/dist/tui-v2/components/modal/prompt-actions-modal.js +61 -31
  39. package/dist/tui-v2/components/modal/prompt-actions-modal.js.map +1 -1
  40. package/dist/tui-v2/components/plan/plan-pane-anim.d.ts +38 -0
  41. package/dist/tui-v2/components/plan/plan-pane-anim.js +64 -0
  42. package/dist/tui-v2/components/plan/plan-pane-anim.js.map +1 -0
  43. package/dist/tui-v2/components/plan/use-pane-presence.d.ts +9 -0
  44. package/dist/tui-v2/components/plan/use-pane-presence.js +54 -0
  45. package/dist/tui-v2/components/plan/use-pane-presence.js.map +1 -0
  46. package/dist/tui-v2/components/toast/toast-anim.d.ts +31 -0
  47. package/dist/tui-v2/components/toast/toast-anim.js +43 -0
  48. package/dist/tui-v2/components/toast/toast-anim.js.map +1 -0
  49. package/dist/tui-v2/components/toast/toast-host.d.ts +4 -5
  50. package/dist/tui-v2/components/toast/toast-host.js +61 -32
  51. package/dist/tui-v2/components/toast/toast-host.js.map +1 -1
  52. package/dist/tui-v2/components/transcript/tool-card.js +3 -1
  53. package/dist/tui-v2/components/transcript/tool-card.js.map +1 -1
  54. package/dist/tui-v2/controllers/toast-controller.d.ts +15 -5
  55. package/dist/tui-v2/controllers/toast-controller.js +18 -6
  56. package/dist/tui-v2/controllers/toast-controller.js.map +1 -1
  57. package/dist/tui-v2/motion/ease.d.ts +9 -0
  58. package/dist/tui-v2/motion/ease.js +22 -0
  59. package/dist/tui-v2/motion/ease.js.map +1 -0
  60. package/dist/tui-v2/notify.d.ts +3 -3
  61. package/dist/tui-v2/notify.js +3 -3
  62. package/dist/tui-v2/rendering/prompt-preview.d.ts +10 -0
  63. package/dist/tui-v2/rendering/prompt-preview.js +32 -0
  64. package/dist/tui-v2/rendering/prompt-preview.js.map +1 -0
  65. package/dist/tui-v2/rendering/theme.d.ts +5 -0
  66. package/dist/tui-v2/rendering/theme.js +4 -0
  67. package/dist/tui-v2/rendering/theme.js.map +1 -1
  68. package/dist/tui-v2/state/transcript-reducer.js +3 -1
  69. package/dist/tui-v2/state/transcript-reducer.js.map +1 -1
  70. package/dist/version.generated.d.ts +2 -2
  71. package/dist/version.generated.js +2 -2
  72. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"composition-root.js","sourceRoot":"","sources":["../../../src/tui-v2/bootstrap/composition-root.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"composition-root.js","sourceRoot":"","sources":["../../../src/tui-v2/bootstrap/composition-root.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,11 @@
1
1
  /** @jsxImportSource @opentui/react */
2
2
  /**
3
3
  * Actions for a user prompt row (copy / resend). Opened by clicking a prompt
4
- * bubble in the transcript. Centered card with a fixed max width so it never
5
- * stretches edge-to-edge on wide terminals.
4
+ * bubble in the transcript. Centered card with a fixed max width; long prompts
5
+ * soft-wrap to the card and scroll inside a fixed-height body (never paint past
6
+ * the border).
6
7
  */
7
- import type { ReactNode } from "react";
8
+ import { type ReactNode } from "react";
8
9
  import type { AppServices } from "../../bootstrap/composition-root.js";
9
10
  import type { PromptActionsRequest } from "../../controllers/overlay-controller.js";
10
11
  import type { Theme } from "../../rendering/theme.js";
@@ -1,37 +1,31 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "@opentui/react/jsx-runtime";
2
+ /** @jsxImportSource @opentui/react */
3
+ /**
4
+ * Actions for a user prompt row (copy / resend). Opened by clicking a prompt
5
+ * bubble in the transcript. Centered card with a fixed max width; long prompts
6
+ * soft-wrap to the card and scroll inside a fixed-height body (never paint past
7
+ * the border).
8
+ */
9
+ import { useMemo, useRef } from "react";
2
10
  import { useKeyboard, useTerminalDimensions } from "@opentui/react";
3
11
  import { chordFromKeyEvent } from "../../actions/chord-from-key.js";
4
- function clipPrompt(text, maxLines, maxCols) {
5
- const lines = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n").split("\n");
6
- const wrapped = [];
7
- for (const line of lines) {
8
- if (line.length === 0) {
9
- wrapped.push("");
10
- continue;
11
- }
12
- for (let i = 0; i < line.length; i += maxCols) {
13
- wrapped.push(line.slice(i, i + maxCols));
14
- if (wrapped.length >= maxLines)
15
- break;
16
- }
17
- if (wrapped.length >= maxLines)
18
- break;
19
- }
20
- if (wrapped.length > maxLines || text.length > maxLines * maxCols) {
21
- const kept = wrapped.slice(0, maxLines);
22
- const last = kept[kept.length - 1] ?? "";
23
- kept[kept.length - 1] = last.length > 1 ? `${last.slice(0, -1)}…` : "…";
24
- return kept.join("\n");
25
- }
26
- return wrapped.join("\n");
27
- }
12
+ import { preparePromptPreview } from "../../rendering/prompt-preview.js";
13
+ const HIDDEN_SCROLLBARS = {
14
+ visible: false,
15
+ showArrows: false,
16
+ };
28
17
  export function PromptActionsModal(props) {
29
18
  const { services, theme, request } = props;
30
19
  const { width: termWidth, height: termHeight } = useTerminalDimensions();
31
- const cardWidth = Math.min(72, Math.max(40, Math.floor(termWidth * 0.55)));
32
- const bodyCols = Math.max(20, cardWidth - 4);
33
- const bodyMaxLines = Math.max(4, Math.min(12, Math.floor(termHeight * 0.35)));
34
- const preview = clipPrompt(request.prompt, bodyMaxLines, bodyCols);
20
+ const scrollRef = useRef(null);
21
+ // Leave room for host padding + border; never claim more than ~55% of cols.
22
+ const cardWidth = Math.min(72, Math.max(36, Math.floor(termWidth * 0.55)));
23
+ // Inner body columns: card − border(2) padding(2) − inner border(2) − pad(2).
24
+ const bodyCols = Math.max(16, cardWidth - 8);
25
+ // Header + buttons + chrome ≈ 8 rows; body takes the rest up to 40% of term.
26
+ const bodyMaxLines = Math.max(6, Math.min(16, Math.floor(termHeight * 0.4)));
27
+ const bodyHeight = bodyMaxLines + 2; // +2 for inner border rows
28
+ const preview = useMemo(() => preparePromptPreview(request.prompt, bodyCols, bodyMaxLines), [request.prompt, bodyCols, bodyMaxLines]);
35
29
  const copy = () => {
36
30
  services.overlay.close();
37
31
  void services.ports.clipboard.writeText(request.prompt);
@@ -43,6 +37,10 @@ export function PromptActionsModal(props) {
43
37
  const close = () => {
44
38
  services.overlay.close();
45
39
  };
40
+ const openFull = () => {
41
+ services.overlay.close();
42
+ services.overlay.openPager("Prompt", request.prompt, undefined, undefined, "plain");
43
+ };
46
44
  useKeyboard((key) => {
47
45
  if (key.eventType === "release")
48
46
  return;
@@ -51,30 +49,62 @@ export function PromptActionsModal(props) {
51
49
  copy();
52
50
  else if (chord === "r" || chord === "enter")
53
51
  resend();
52
+ else if (chord === "p" || chord === "o")
53
+ openFull();
54
54
  else if (chord === "escape")
55
55
  close();
56
+ else if (chord === "up" || chord === "k") {
57
+ scrollRef.current?.scrollBy(-1);
58
+ }
59
+ else if (chord === "down" || chord === "j") {
60
+ scrollRef.current?.scrollBy(1);
61
+ }
56
62
  else
57
63
  return;
58
64
  key.preventDefault();
59
65
  });
66
+ const meta = preview.truncated || preview.totalLines > preview.lines.length
67
+ ? `showing ${preview.lines.length}/${preview.totalLines} lines · p:full`
68
+ : preview.totalLines > 1
69
+ ? `${preview.totalLines} lines`
70
+ : "";
60
71
  return (_jsxs("box", { border: true, borderStyle: "rounded", title: " Prompt ", titleAlignment: "center", style: {
61
72
  flexDirection: "column",
62
73
  width: cardWidth,
63
- maxHeight: Math.max(10, Math.floor(termHeight * 0.7)),
74
+ // Cap total card height so host centering never clips action buttons.
75
+ maxHeight: Math.max(12, Math.floor(termHeight * 0.75)),
64
76
  borderColor: theme.userBorder,
65
77
  backgroundColor: theme.statusBackground,
66
78
  paddingLeft: 1,
67
79
  paddingRight: 1,
68
80
  paddingTop: 1,
69
81
  paddingBottom: 1,
70
- }, children: [_jsxs("box", { style: { flexDirection: "row", marginBottom: 1 }, children: [_jsx("text", { content: " YOU ", style: { fg: theme.white, bg: theme.prompt } }), _jsx("text", { content: " actions for this message", style: { fg: theme.muted } })] }), _jsx("box", { border: true, borderStyle: "rounded", style: {
82
+ flexShrink: 0,
83
+ }, children: [_jsxs("box", { style: { flexDirection: "row", marginBottom: 1, width: "100%" }, children: [_jsx("text", { content: " YOU ", style: { fg: theme.white, bg: theme.prompt } }), _jsx("text", { content: " actions for this message", style: { fg: theme.muted } })] }), _jsx("box", { border: true, borderStyle: "rounded", style: {
71
84
  flexDirection: "column",
72
85
  width: "100%",
86
+ height: bodyHeight,
87
+ maxHeight: bodyHeight,
73
88
  borderColor: theme.chipIndigo,
74
89
  backgroundColor: theme.background,
75
90
  paddingLeft: 1,
76
91
  paddingRight: 1,
77
92
  marginBottom: 1,
78
- }, children: _jsx("text", { style: { fg: theme.foreground }, children: preview || " " }) }), _jsxs("box", { style: { flexDirection: "row", justifyContent: "flex-start", width: "100%" }, children: [_jsx("text", { content: " c:copy ", style: { fg: theme.white, bg: theme.chipTeal }, onMouseDown: copy }), _jsx("text", { content: " " }), _jsx("text", { content: " r:resend ", style: { fg: theme.white, bg: theme.mode }, onMouseDown: resend }), _jsx("text", { content: " " }), _jsx("text", { content: " esc:close ", style: { fg: theme.white, bg: theme.chipIndigo }, onMouseDown: close })] })] }));
93
+ flexShrink: 0,
94
+ overflow: "hidden",
95
+ }, children: _jsx("scrollbox", { ref: scrollRef, scrollY: true, scrollX: false, stickyScroll: false, scrollbarOptions: HIDDEN_SCROLLBARS, verticalScrollbarOptions: HIDDEN_SCROLLBARS, horizontalScrollbarOptions: HIDDEN_SCROLLBARS, style: {
96
+ flexGrow: 1,
97
+ width: "100%",
98
+ height: Math.max(1, bodyMaxLines),
99
+ }, children: preview.lines.map((line, i) => (_jsx("text", { content: line.length > 0 ? line : " ", selectable: true, wrapMode: "none", style: {
100
+ fg: theme.foreground,
101
+ height: 1,
102
+ width: bodyCols,
103
+ } }, i))) }) }), meta ? (_jsx("text", { content: meta, style: { fg: theme.muted, height: 1, marginBottom: 0 } })) : null, _jsxs("box", { style: {
104
+ flexDirection: "row",
105
+ justifyContent: "flex-start",
106
+ width: "100%",
107
+ flexShrink: 0,
108
+ }, children: [_jsx("text", { content: " c:copy ", style: { fg: theme.white, bg: theme.chipTeal }, onMouseDown: copy }), _jsx("text", { content: " " }), _jsx("text", { content: " r:resend ", style: { fg: theme.white, bg: theme.mode }, onMouseDown: resend }), _jsx("text", { content: " " }), _jsx("text", { content: " p:full ", style: { fg: theme.white, bg: theme.chip }, onMouseDown: openFull }), _jsx("text", { content: " " }), _jsx("text", { content: " esc:close ", style: { fg: theme.white, bg: theme.chipIndigo }, onMouseDown: close })] })] }));
79
109
  }
80
110
  //# sourceMappingURL=prompt-actions-modal.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"prompt-actions-modal.js","sourceRoot":"","sources":["../../../../src/tui-v2/components/modal/prompt-actions-modal.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prompt-actions-modal.js","sourceRoot":"","sources":["../../../../src/tui-v2/components/modal/prompt-actions-modal.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Pure task-pane motion math — snappy enter/exit (faster than toasts).
3
+ *
4
+ * Open: slide in (~120ms ease-out)
5
+ * Close: slide out (~100ms ease-in), then unmount
6
+ */
7
+ /** Slide-in duration — a bit snappier than toast (200ms). */
8
+ export declare const PLAN_PANE_ENTER_MS = 120;
9
+ /** Slide-out duration — slightly faster than enter so hide feels instant. */
10
+ export declare const PLAN_PANE_EXIT_MS = 100;
11
+ export type PaneAnimPhase = "enter" | "open" | "exit" | "closed";
12
+ export interface PaneAnimState {
13
+ readonly phase: PaneAnimPhase;
14
+ /** 0 = fully hidden, 1 = fully shown. */
15
+ readonly progress: number;
16
+ /** Keep the pane in the tree during enter/open/exit. */
17
+ readonly mounted: boolean;
18
+ }
19
+ /**
20
+ * Progress for a known phase + age within that phase.
21
+ */
22
+ export declare function paneProgress(phase: PaneAnimPhase, ageMs: number, enterMs?: number, exitMs?: number): number;
23
+ export declare function paneMounted(phase: PaneAnimPhase): boolean;
24
+ /**
25
+ * Overlay placement: slide from above the viewport to restTop.
26
+ * @param progress 0..1 visibility
27
+ * @param restTop resting top row when fully open
28
+ * @param paneHeight box height (for off-screen start)
29
+ */
30
+ export declare function paneSlideTop(progress: number, restTop: number, paneHeight: number): number;
31
+ /**
32
+ * Split placement: grow/shrink width with progress.
33
+ */
34
+ export declare function paneSlideWidth(progress: number, fullWidth: number): number;
35
+ /**
36
+ * Whether the enter/exit phase has finished and should advance.
37
+ */
38
+ export declare function panePhaseComplete(phase: PaneAnimPhase, ageMs: number, enterMs?: number, exitMs?: number): PaneAnimPhase | null;
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Pure task-pane motion math — snappy enter/exit (faster than toasts).
3
+ *
4
+ * Open: slide in (~120ms ease-out)
5
+ * Close: slide out (~100ms ease-in), then unmount
6
+ */
7
+ import { easeInCubic, easeOutCubic, clamp01 } from "../../motion/ease.js";
8
+ /** Slide-in duration — a bit snappier than toast (200ms). */
9
+ export const PLAN_PANE_ENTER_MS = 120;
10
+ /** Slide-out duration — slightly faster than enter so hide feels instant. */
11
+ export const PLAN_PANE_EXIT_MS = 100;
12
+ /**
13
+ * Progress for a known phase + age within that phase.
14
+ */
15
+ export function paneProgress(phase, ageMs, enterMs = PLAN_PANE_ENTER_MS, exitMs = PLAN_PANE_EXIT_MS) {
16
+ const age = Math.max(0, ageMs);
17
+ switch (phase) {
18
+ case "closed":
19
+ return 0;
20
+ case "open":
21
+ return 1;
22
+ case "enter":
23
+ return easeOutCubic(clamp01(age / Math.max(1, enterMs)));
24
+ case "exit":
25
+ return 1 - easeInCubic(clamp01(age / Math.max(1, exitMs)));
26
+ default:
27
+ return 0;
28
+ }
29
+ }
30
+ export function paneMounted(phase) {
31
+ return phase !== "closed";
32
+ }
33
+ /**
34
+ * Overlay placement: slide from above the viewport to restTop.
35
+ * @param progress 0..1 visibility
36
+ * @param restTop resting top row when fully open
37
+ * @param paneHeight box height (for off-screen start)
38
+ */
39
+ export function paneSlideTop(progress, restTop, paneHeight) {
40
+ const p = clamp01(progress);
41
+ const hiddenTop = -Math.max(1, paneHeight);
42
+ return Math.round(hiddenTop + (restTop - hiddenTop) * p);
43
+ }
44
+ /**
45
+ * Split placement: grow/shrink width with progress.
46
+ */
47
+ export function paneSlideWidth(progress, fullWidth) {
48
+ const p = clamp01(progress);
49
+ if (p <= 0)
50
+ return 0;
51
+ return Math.max(1, Math.round(fullWidth * p));
52
+ }
53
+ /**
54
+ * Whether the enter/exit phase has finished and should advance.
55
+ */
56
+ export function panePhaseComplete(phase, ageMs, enterMs = PLAN_PANE_ENTER_MS, exitMs = PLAN_PANE_EXIT_MS) {
57
+ const age = Math.max(0, ageMs);
58
+ if (phase === "enter" && age >= enterMs)
59
+ return "open";
60
+ if (phase === "exit" && age >= exitMs)
61
+ return "closed";
62
+ return null;
63
+ }
64
+ //# sourceMappingURL=plan-pane-anim.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-pane-anim.js","sourceRoot":"","sources":["../../../../src/tui-v2/components/plan/plan-pane-anim.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAE1E,6DAA6D;AAC7D,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,CAAC;AACtC,6EAA6E;AAC7E,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAYrC;;GAEG;AACH,MAAM,UAAU,YAAY,CAC1B,KAAoB,EACpB,KAAa,EACb,UAAkB,kBAAkB,EACpC,SAAiB,iBAAiB;IAElC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAC/B,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,QAAQ;YACX,OAAO,CAAC,CAAC;QACX,KAAK,MAAM;YACT,OAAO,CAAC,CAAC;QACX,KAAK,OAAO;YACV,OAAO,YAAY,CAAC,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;QAC3D,KAAK,MAAM;YACT,OAAO,CAAC,GAAG,WAAW,CAAC,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;QAC7D;YACE,OAAO,CAAC,CAAC;IACb,CAAC;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAoB;IAC9C,OAAO,KAAK,KAAK,QAAQ,CAAC;AAC5B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAC1B,QAAgB,EAChB,OAAe,EACf,UAAkB;IAElB,MAAM,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC5B,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;IAC3C,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,QAAgB,EAAE,SAAiB;IAChE,MAAM,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC5B,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IACrB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC;AAChD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAC/B,KAAoB,EACpB,KAAa,EACb,UAAkB,kBAAkB,EACpC,SAAiB,iBAAiB;IAElC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAC/B,IAAI,KAAK,KAAK,OAAO,IAAI,GAAG,IAAI,OAAO;QAAE,OAAO,MAAM,CAAC;IACvD,IAAI,KAAK,KAAK,MAAM,IAAI,GAAG,IAAI,MAAM;QAAE,OAAO,QAAQ,CAAC;IACvD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Keep a pane mounted through enter/exit so OpenTUI can paint slide motion.
3
+ */
4
+ import { type PaneAnimState } from "./plan-pane-anim.js";
5
+ /**
6
+ * Drive enter → open → exit → closed from a boolean `open` request.
7
+ * Snappy timing (~120ms in / ~100ms out) with ease curves in paneProgress.
8
+ */
9
+ export declare function usePanePresence(open: boolean): PaneAnimState;
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Keep a pane mounted through enter/exit so OpenTUI can paint slide motion.
3
+ */
4
+ import { useEffect, useState } from "react";
5
+ import { PLAN_PANE_ENTER_MS, PLAN_PANE_EXIT_MS, paneMounted, panePhaseComplete, paneProgress, } from "./plan-pane-anim.js";
6
+ const TICK_MS = 33;
7
+ /**
8
+ * Drive enter → open → exit → closed from a boolean `open` request.
9
+ * Snappy timing (~120ms in / ~100ms out) with ease curves in paneProgress.
10
+ */
11
+ export function usePanePresence(open) {
12
+ const [phase, setPhase] = useState(() => open ? "enter" : "closed");
13
+ const [phaseAt, setPhaseAt] = useState(() => Date.now());
14
+ const [now, setNow] = useState(() => Date.now());
15
+ // Respond to open/close requests.
16
+ useEffect(() => {
17
+ if (open) {
18
+ if (phase === "closed" || phase === "exit") {
19
+ setPhase("enter");
20
+ setPhaseAt(Date.now());
21
+ setNow(Date.now());
22
+ }
23
+ }
24
+ else if (phase === "open" || phase === "enter") {
25
+ setPhase("exit");
26
+ setPhaseAt(Date.now());
27
+ setNow(Date.now());
28
+ }
29
+ }, [open, phase]);
30
+ // Tick during enter/exit; promote phase when the segment completes.
31
+ useEffect(() => {
32
+ if (phase !== "enter" && phase !== "exit")
33
+ return;
34
+ const id = setInterval(() => {
35
+ const t = Date.now();
36
+ setNow(t);
37
+ const next = panePhaseComplete(phase, t - phaseAt, PLAN_PANE_ENTER_MS, PLAN_PANE_EXIT_MS);
38
+ if (next) {
39
+ setPhase(next);
40
+ setPhaseAt(t);
41
+ }
42
+ }, TICK_MS);
43
+ id.unref?.();
44
+ return () => clearInterval(id);
45
+ }, [phase, phaseAt]);
46
+ const age = now - phaseAt;
47
+ const progress = paneProgress(phase, age, PLAN_PANE_ENTER_MS, PLAN_PANE_EXIT_MS);
48
+ return {
49
+ phase,
50
+ progress,
51
+ mounted: paneMounted(phase),
52
+ };
53
+ }
54
+ //# sourceMappingURL=use-pane-presence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-pane-presence.js","sourceRoot":"","sources":["../../../../src/tui-v2/components/plan/use-pane-presence.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,WAAW,EACX,iBAAiB,EACjB,YAAY,GAGb,MAAM,qBAAqB,CAAC;AAE7B,MAAM,OAAO,GAAG,EAAE,CAAC;AAEnB;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,IAAa;IAC3C,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAgB,GAAG,EAAE,CACrD,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAC1B,CAAC;IACF,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IACzD,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAEjD,kCAAkC;IAClC,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;gBAC3C,QAAQ,CAAC,OAAO,CAAC,CAAC;gBAClB,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;gBACvB,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;YACrB,CAAC;QACH,CAAC;aAAM,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;YACjD,QAAQ,CAAC,MAAM,CAAC,CAAC;YACjB,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;YACvB,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QACrB,CAAC;IACH,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;IAElB,oEAAoE;IACpE,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,MAAM;YAAE,OAAO;QAClD,MAAM,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE;YAC1B,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACrB,MAAM,CAAC,CAAC,CAAC,CAAC;YACV,MAAM,IAAI,GAAG,iBAAiB,CAC5B,KAAK,EACL,CAAC,GAAG,OAAO,EACX,kBAAkB,EAClB,iBAAiB,CAClB,CAAC;YACF,IAAI,IAAI,EAAE,CAAC;gBACT,QAAQ,CAAC,IAAI,CAAC,CAAC;gBACf,UAAU,CAAC,CAAC,CAAC,CAAC;YAChB,CAAC;QACH,CAAC,EAAE,OAAO,CAAC,CAAC;QACX,EAAwC,CAAC,KAAK,EAAE,EAAE,CAAC;QACpD,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;IACjC,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;IAErB,MAAM,GAAG,GAAG,GAAG,GAAG,OAAO,CAAC;IAC1B,MAAM,QAAQ,GAAG,YAAY,CAC3B,KAAK,EACL,GAAG,EACH,kBAAkB,EAClB,iBAAiB,CAClB,CAAC;IAEF,OAAO;QACL,KAAK;QACL,QAAQ;QACR,OAAO,EAAE,WAAW,CAAC,KAAK,CAAC;KAC5B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Pure toast motion math — slide in from top-center, hold, slide out.
3
+ * Terminal UIs animate by discrete row steps; ease curves keep it smooth-ish.
4
+ */
5
+ export { easeInCubic, easeOutCubic } from "../../motion/ease.js";
6
+ /**
7
+ * Outer box height (includes border rows) — keep in sync with host.
8
+ * 4 = top border + content row + bottom border (slightly compact, bold label).
9
+ * Surface fill is on the outer box so grey covers the full interior only.
10
+ */
11
+ export declare const TOAST_BOX_HEIGHT = 4;
12
+ /** Resting top row when fully visible (1 = just under terminal top edge). */
13
+ export declare const TOAST_REST_TOP = 1;
14
+ /** Off-screen top when fully hidden above the viewport. */
15
+ export declare const TOAST_HIDDEN_TOP: number;
16
+ export type ToastAnimPhase = "enter" | "hold" | "exit" | "gone";
17
+ export interface ToastAnimState {
18
+ readonly phase: ToastAnimPhase;
19
+ /** Absolute top row for absolute positioning. */
20
+ readonly top: number;
21
+ /**
22
+ * 0..1 visibility for optional dimming (1 = fully shown).
23
+ * Terminal cannot fade alpha; host may map low values to DIM.
24
+ */
25
+ readonly visibility: number;
26
+ }
27
+ /**
28
+ * Compute motion for a toast at `ageMs` since createdAt.
29
+ * @param holdMs time at rest (item.durationMs)
30
+ */
31
+ export declare function toastAnimAt(ageMs: number, holdMs: number): ToastAnimState;
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Pure toast motion math — slide in from top-center, hold, slide out.
3
+ * Terminal UIs animate by discrete row steps; ease curves keep it smooth-ish.
4
+ */
5
+ import { TOAST_ENTER_MS, TOAST_EXIT_MS, } from "../../controllers/toast-controller.js";
6
+ import { easeInCubic, easeOutCubic } from "../../motion/ease.js";
7
+ export { easeInCubic, easeOutCubic } from "../../motion/ease.js";
8
+ /**
9
+ * Outer box height (includes border rows) — keep in sync with host.
10
+ * 4 = top border + content row + bottom border (slightly compact, bold label).
11
+ * Surface fill is on the outer box so grey covers the full interior only.
12
+ */
13
+ export const TOAST_BOX_HEIGHT = 4;
14
+ /** Resting top row when fully visible (1 = just under terminal top edge). */
15
+ export const TOAST_REST_TOP = 1;
16
+ /** Off-screen top when fully hidden above the viewport. */
17
+ export const TOAST_HIDDEN_TOP = -TOAST_BOX_HEIGHT;
18
+ /**
19
+ * Compute motion for a toast at `ageMs` since createdAt.
20
+ * @param holdMs time at rest (item.durationMs)
21
+ */
22
+ export function toastAnimAt(ageMs, holdMs) {
23
+ const age = Math.max(0, ageMs);
24
+ const hold = Math.max(0, holdMs);
25
+ const enterEnd = TOAST_ENTER_MS;
26
+ const holdEnd = enterEnd + hold;
27
+ const exitEnd = holdEnd + TOAST_EXIT_MS;
28
+ if (age < enterEnd) {
29
+ const p = easeOutCubic(age / Math.max(1, TOAST_ENTER_MS));
30
+ const top = Math.round(TOAST_HIDDEN_TOP + (TOAST_REST_TOP - TOAST_HIDDEN_TOP) * p);
31
+ return { phase: "enter", top, visibility: p };
32
+ }
33
+ if (age < holdEnd) {
34
+ return { phase: "hold", top: TOAST_REST_TOP, visibility: 1 };
35
+ }
36
+ if (age < exitEnd) {
37
+ const p = easeInCubic((age - holdEnd) / Math.max(1, TOAST_EXIT_MS));
38
+ const top = Math.round(TOAST_REST_TOP + (TOAST_HIDDEN_TOP - TOAST_REST_TOP) * p);
39
+ return { phase: "exit", top, visibility: 1 - p };
40
+ }
41
+ return { phase: "gone", top: TOAST_HIDDEN_TOP, visibility: 0 };
42
+ }
43
+ //# sourceMappingURL=toast-anim.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toast-anim.js","sourceRoot":"","sources":["../../../../src/tui-v2/components/toast/toast-anim.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,cAAc,EACd,aAAa,GACd,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEjE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEjE;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAElC,6EAA6E;AAC7E,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC;AAEhC,2DAA2D;AAC3D,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,gBAAgB,CAAC;AAelD;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa,EAAE,MAAc;IACvD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IACjC,MAAM,QAAQ,GAAG,cAAc,CAAC;IAChC,MAAM,OAAO,GAAG,QAAQ,GAAG,IAAI,CAAC;IAChC,MAAM,OAAO,GAAG,OAAO,GAAG,aAAa,CAAC;IAExC,IAAI,GAAG,GAAG,QAAQ,EAAE,CAAC;QACnB,MAAM,CAAC,GAAG,YAAY,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC;QAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CACpB,gBAAgB,GAAG,CAAC,cAAc,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAC3D,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;IAChD,CAAC;IACD,IAAI,GAAG,GAAG,OAAO,EAAE,CAAC;QAClB,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,cAAc,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;IAC/D,CAAC;IACD,IAAI,GAAG,GAAG,OAAO,EAAE,CAAC;QAClB,MAAM,CAAC,GAAG,WAAW,CAAC,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC;QACpE,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CACpB,cAAc,GAAG,CAAC,gBAAgB,GAAG,cAAc,CAAC,GAAG,CAAC,CACzD,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;IACnD,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,gBAAgB,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;AACjE,CAAC"}
@@ -1,12 +1,11 @@
1
1
  /** @jsxImportSource @opentui/react */
2
2
  /**
3
- * Notification toasts — top-right stack.
3
+ * Notification toasts — top-center, slide in / hold / slide out.
4
4
  *
5
- * Heavy aqua frame (composer `inputBorder`) + yellowish prompt-boundary text
6
- * (`userBorder`). Outer shell draws only the frame on the app background;
7
- * inner box holds the whitish surface so fill never paints outside the border.
5
+ * Heavy aqua frame + yellowish prompt-boundary text. Motion is discrete row
6
+ * steps (terminal); ease curves + 30fps tick keep it feeling smooth.
8
7
  */
9
- import type { ReactNode } from "react";
8
+ import { type ReactNode } from "react";
10
9
  import type { ToastController } from "../../controllers/toast-controller.js";
11
10
  import type { Theme } from "../../rendering/theme.js";
12
11
  export interface ToastHostProps {
@@ -1,13 +1,22 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment } from "@opentui/react/jsx-runtime";
2
+ /** @jsxImportSource @opentui/react */
3
+ /**
4
+ * Notification toasts — top-center, slide in / hold / slide out.
5
+ *
6
+ * Heavy aqua frame + yellowish prompt-boundary text. Motion is discrete row
7
+ * steps (terminal); ease curves + 30fps tick keep it feeling smooth.
8
+ */
9
+ import { useEffect, useState } from "react";
2
10
  import { TextAttributes } from "@opentui/core";
3
11
  import { useToastState } from "../../state/use-toast.js";
12
+ import { TOAST_BOX_HEIGHT, toastAnimAt, } from "./toast-anim.js";
4
13
  /** Soft elevated surface — slight whitish shade on near-black. */
5
14
  const TOAST_SURFACE_DARK = "#1c2028";
6
15
  const TOAST_SURFACE_LIGHT = "#f4f5f7";
7
- /** Outer box height (includes heavy border rows). */
8
- const TOAST_HEIGHT = 5;
9
- /** Gap between stacked toasts. */
10
- const TOAST_STRIDE = 6;
16
+ /** Vertical gap between stacked toasts at rest. */
17
+ const TOAST_STACK_GAP = 1;
18
+ /** Animation repaint interval (~30 fps). */
19
+ const TICK_MS = 33;
11
20
  function toastSurface(theme) {
12
21
  const bg = theme.background.toLowerCase();
13
22
  const isDark = bg.startsWith("#0") ||
@@ -29,55 +38,75 @@ function levelGlyph(level) {
29
38
  }
30
39
  }
31
40
  function ToastPill(props) {
32
- const { item, theme, top, left, width } = props;
41
+ const { item, theme, top, left, width, visibility } = props;
42
+ if (visibility <= 0.02)
43
+ return null;
33
44
  const surface = toastSurface(theme);
34
- // Aqua chrome (composer) + yellowish user-prompt boundary text.
35
45
  const border = theme.inputBorder;
36
46
  const textFg = theme.userBorder;
47
+ // Compact bold label — surface is on the outer box only (no text bg so
48
+ // fill never paints past border glyphs in OpenTUI).
37
49
  const label = `${levelGlyph(item.level)} ${item.message}`;
38
- return (_jsx("box", { border: true, borderStyle: "heavy", style: {
50
+ // Approximate “fade” with DIM when sliding in/out — always keep BOLD.
51
+ const dim = visibility < 0.85;
52
+ return (_jsx("box", { border: true, borderStyle: "rounded", style: {
39
53
  position: "absolute",
40
54
  top,
41
55
  left,
42
56
  width,
43
- height: TOAST_HEIGHT,
57
+ height: TOAST_BOX_HEIGHT,
44
58
  zIndex: 1000,
45
59
  borderColor: border,
46
- backgroundColor: theme.background,
47
- flexDirection: "column",
48
- paddingLeft: 0,
49
- paddingRight: 0,
60
+ backgroundColor: surface,
61
+ flexDirection: "row",
62
+ alignItems: "center",
63
+ justifyContent: "center",
64
+ paddingLeft: 2,
65
+ paddingRight: 2,
50
66
  paddingTop: 0,
51
67
  paddingBottom: 0,
52
- }, children: _jsx("box", { style: {
53
- flexGrow: 1,
54
- width: "100%",
55
- minHeight: 1,
56
- backgroundColor: surface,
57
- flexDirection: "row",
58
- alignItems: "center",
59
- justifyContent: "center",
60
- paddingLeft: 2,
61
- paddingRight: 2,
62
- }, children: _jsx("text", { selectable: false, content: label, style: {
63
- fg: textFg,
64
- attributes: TextAttributes.BOLD,
65
- } }) }) }));
68
+ }, children: _jsx("text", { selectable: false, content: label, style: {
69
+ fg: textFg,
70
+ attributes: dim
71
+ ? TextAttributes.BOLD | TextAttributes.DIM
72
+ : TextAttributes.BOLD,
73
+ } }) }));
66
74
  }
67
75
  export function ToastHost(props) {
68
76
  const { toast, theme, termWidth, termHeight } = props;
69
77
  const items = useToastState(toast);
78
+ const [now, setNow] = useState(() => Date.now());
79
+ // Drive enter/hold/exit motion while any toast is alive.
80
+ useEffect(() => {
81
+ if (items.length === 0)
82
+ return;
83
+ const id = setInterval(() => setNow(Date.now()), TICK_MS);
84
+ id.unref?.();
85
+ return () => clearInterval(id);
86
+ }, [items.length > 0]);
70
87
  if (items.length === 0)
71
88
  return null;
72
- const maxWidth = Math.min(56, Math.max(34, Math.floor(termWidth * 0.52)));
89
+ // Wide enough for full messages (up to controller cap); slightly compact.
90
+ const maxWidth = Math.min(64, Math.max(32, Math.floor(termWidth * 0.58)));
91
+ // Newest on top of stack (drawn first in reverse so later paint on top).
73
92
  const ordered = [...items].reverse();
74
- const maxStack = Math.max(1, Math.min(3, Math.floor((termHeight - 8) / TOAST_STRIDE)));
93
+ const maxStack = Math.max(1, Math.min(3, Math.floor((termHeight - 4) / (TOAST_BOX_HEIGHT + TOAST_STACK_GAP))));
75
94
  const visible = ordered.slice(0, maxStack);
76
95
  return (_jsx(_Fragment, { children: visible.map((item, index) => {
77
- const toastWidth = Math.min(maxWidth, Math.max(30, item.message.length + 10));
78
- const left = Math.max(0, termWidth - toastWidth - 2);
79
- const top = 1 + index * TOAST_STRIDE;
80
- return (_jsx(ToastPill, { item: item, theme: theme, top: top, left: left, width: toastWidth }, item.id));
96
+ // +8 for glyph, spaces, and border/pad — prefer full message width.
97
+ const toastWidth = Math.min(maxWidth, Math.max(32, item.message.length + 8));
98
+ // Top-center horizontally.
99
+ const left = Math.max(0, Math.floor((termWidth - toastWidth) / 2));
100
+ const anim = toastAnimAt(now - item.createdAt, item.durationMs);
101
+ if (anim.phase === "gone")
102
+ return null;
103
+ // Stack older toasts below the primary (rest) slot.
104
+ const stackOffset = index * (TOAST_BOX_HEIGHT + TOAST_STACK_GAP);
105
+ const top = anim.top + stackOffset;
106
+ // Skip if fully above the viewport after stack offset.
107
+ if (top + TOAST_BOX_HEIGHT < 0)
108
+ return null;
109
+ return (_jsx(ToastPill, { item: item, theme: theme, top: top, left: left, width: toastWidth, visibility: anim.visibility }, item.id));
81
110
  }) }));
82
111
  }
83
112
  //# sourceMappingURL=toast-host.js.map