@agentick/tui 0.4.0 → 0.6.0
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/README.md +202 -20
- package/dist/commands-context.d.ts +10 -0
- package/dist/commands-context.d.ts.map +1 -0
- package/dist/commands-context.js +10 -0
- package/dist/commands-context.js.map +1 -0
- package/dist/commands.d.ts +30 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/commands.js +163 -0
- package/dist/commands.js.map +1 -0
- package/dist/components/CompletionPicker.d.ts +12 -0
- package/dist/components/CompletionPicker.d.ts.map +1 -0
- package/dist/components/CompletionPicker.js +41 -0
- package/dist/components/CompletionPicker.js.map +1 -0
- package/dist/components/DiffView.d.ts +21 -0
- package/dist/components/DiffView.d.ts.map +1 -0
- package/dist/components/DiffView.js +94 -0
- package/dist/components/DiffView.js.map +1 -0
- package/dist/components/ErrorDisplay.d.ts +6 -6
- package/dist/components/ErrorDisplay.d.ts.map +1 -1
- package/dist/components/ErrorDisplay.js +6 -8
- package/dist/components/ErrorDisplay.js.map +1 -1
- package/dist/components/InputBar.d.ts +8 -7
- package/dist/components/InputBar.d.ts.map +1 -1
- package/dist/components/InputBar.js +7 -13
- package/dist/components/InputBar.js.map +1 -1
- package/dist/components/MessageList.d.ts +11 -5
- package/dist/components/MessageList.d.ts.map +1 -1
- package/dist/components/MessageList.js +37 -44
- package/dist/components/MessageList.js.map +1 -1
- package/dist/components/RichTextInput.d.ts +14 -0
- package/dist/components/RichTextInput.d.ts.map +1 -0
- package/dist/components/RichTextInput.js +24 -0
- package/dist/components/RichTextInput.js.map +1 -0
- package/dist/components/ToolCallIndicator.d.ts.map +1 -1
- package/dist/components/ToolCallIndicator.js +12 -5
- package/dist/components/ToolCallIndicator.js.map +1 -1
- package/dist/components/ToolConfirmationPrompt.d.ts +9 -6
- package/dist/components/ToolConfirmationPrompt.d.ts.map +1 -1
- package/dist/components/ToolConfirmationPrompt.js +18 -19
- package/dist/components/ToolConfirmationPrompt.js.map +1 -1
- package/dist/components/status-bar/DefaultStatusBar.d.ts +20 -0
- package/dist/components/status-bar/DefaultStatusBar.d.ts.map +1 -0
- package/dist/components/status-bar/DefaultStatusBar.js +11 -0
- package/dist/components/status-bar/DefaultStatusBar.js.map +1 -0
- package/dist/components/status-bar/StatusBar.d.ts +22 -0
- package/dist/components/status-bar/StatusBar.d.ts.map +1 -0
- package/dist/components/status-bar/StatusBar.js +16 -0
- package/dist/components/status-bar/StatusBar.js.map +1 -0
- package/dist/components/status-bar/StatusBarRight.d.ts +12 -0
- package/dist/components/status-bar/StatusBarRight.d.ts.map +1 -0
- package/dist/components/status-bar/StatusBarRight.js +29 -0
- package/dist/components/status-bar/StatusBarRight.js.map +1 -0
- package/dist/components/status-bar/context.d.ts +27 -0
- package/dist/components/status-bar/context.d.ts.map +1 -0
- package/dist/components/status-bar/context.js +18 -0
- package/dist/components/status-bar/context.js.map +1 -0
- package/dist/components/status-bar/index.d.ts +5 -0
- package/dist/components/status-bar/index.d.ts.map +1 -0
- package/dist/components/status-bar/index.js +5 -0
- package/dist/components/status-bar/index.js.map +1 -0
- package/dist/components/status-bar/widgets/BrandLabel.d.ts +8 -0
- package/dist/components/status-bar/widgets/BrandLabel.d.ts.map +1 -0
- package/dist/components/status-bar/widgets/BrandLabel.js +6 -0
- package/dist/components/status-bar/widgets/BrandLabel.js.map +1 -0
- package/dist/components/status-bar/widgets/ContextUtilization.d.ts +11 -0
- package/dist/components/status-bar/widgets/ContextUtilization.d.ts.map +1 -0
- package/dist/components/status-bar/widgets/ContextUtilization.js +12 -0
- package/dist/components/status-bar/widgets/ContextUtilization.js.map +1 -0
- package/dist/components/status-bar/widgets/KeyboardHints.d.ts +16 -0
- package/dist/components/status-bar/widgets/KeyboardHints.d.ts.map +1 -0
- package/dist/components/status-bar/widgets/KeyboardHints.js +25 -0
- package/dist/components/status-bar/widgets/KeyboardHints.js.map +1 -0
- package/dist/components/status-bar/widgets/ModelInfo.d.ts +7 -0
- package/dist/components/status-bar/widgets/ModelInfo.d.ts.map +1 -0
- package/dist/components/status-bar/widgets/ModelInfo.js +10 -0
- package/dist/components/status-bar/widgets/ModelInfo.js.map +1 -0
- package/dist/components/status-bar/widgets/Separator.d.ts +7 -0
- package/dist/components/status-bar/widgets/Separator.d.ts.map +1 -0
- package/dist/components/status-bar/widgets/Separator.js +6 -0
- package/dist/components/status-bar/widgets/Separator.js.map +1 -0
- package/dist/components/status-bar/widgets/StateIndicator.d.ts +12 -0
- package/dist/components/status-bar/widgets/StateIndicator.d.ts.map +1 -0
- package/dist/components/status-bar/widgets/StateIndicator.js +21 -0
- package/dist/components/status-bar/widgets/StateIndicator.js.map +1 -0
- package/dist/components/status-bar/widgets/TickCount.d.ts +9 -0
- package/dist/components/status-bar/widgets/TickCount.d.ts.map +1 -0
- package/dist/components/status-bar/widgets/TickCount.js +11 -0
- package/dist/components/status-bar/widgets/TickCount.js.map +1 -0
- package/dist/components/status-bar/widgets/TokenCount.d.ts +12 -0
- package/dist/components/status-bar/widgets/TokenCount.d.ts.map +1 -0
- package/dist/components/status-bar/widgets/TokenCount.js +28 -0
- package/dist/components/status-bar/widgets/TokenCount.js.map +1 -0
- package/dist/components/status-bar/widgets/index.d.ts +9 -0
- package/dist/components/status-bar/widgets/index.d.ts.map +1 -0
- package/dist/components/status-bar/widgets/index.js +9 -0
- package/dist/components/status-bar/widgets/index.js.map +1 -0
- package/dist/create-tui.d.ts +17 -6
- package/dist/create-tui.d.ts.map +1 -1
- package/dist/create-tui.js +14 -3
- package/dist/create-tui.js.map +1 -1
- package/dist/hooks/use-double-ctrl-c.d.ts +5 -0
- package/dist/hooks/use-double-ctrl-c.d.ts.map +1 -0
- package/dist/hooks/use-double-ctrl-c.js +32 -0
- package/dist/hooks/use-double-ctrl-c.js.map +1 -0
- package/dist/hooks/use-line-editor.d.ts +26 -0
- package/dist/hooks/use-line-editor.d.ts.map +1 -0
- package/dist/hooks/use-line-editor.js +63 -0
- package/dist/hooks/use-line-editor.js.map +1 -0
- package/dist/index.d.ts +14 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -1
- package/dist/input-utils.d.ts +15 -0
- package/dist/input-utils.d.ts.map +1 -0
- package/dist/input-utils.js +29 -0
- package/dist/input-utils.js.map +1 -0
- package/dist/rendering/content-block.d.ts +12 -0
- package/dist/rendering/content-block.d.ts.map +1 -0
- package/dist/rendering/content-block.js +82 -0
- package/dist/rendering/content-block.js.map +1 -0
- package/dist/rendering/index.d.ts +5 -0
- package/dist/rendering/index.d.ts.map +1 -0
- package/dist/rendering/index.js +5 -0
- package/dist/rendering/index.js.map +1 -0
- package/dist/rendering/markdown.d.ts +14 -0
- package/dist/rendering/markdown.d.ts.map +1 -0
- package/dist/rendering/markdown.js +61 -0
- package/dist/rendering/markdown.js.map +1 -0
- package/dist/rendering/message.d.ts +25 -0
- package/dist/rendering/message.d.ts.map +1 -0
- package/dist/rendering/message.js +54 -0
- package/dist/rendering/message.js.map +1 -0
- package/dist/rendering/theme.d.ts +37 -0
- package/dist/rendering/theme.d.ts.map +1 -0
- package/dist/rendering/theme.js +49 -0
- package/dist/rendering/theme.js.map +1 -0
- package/dist/ui/chat.d.ts +26 -4
- package/dist/ui/chat.d.ts.map +1 -1
- package/dist/ui/chat.js +91 -68
- package/dist/ui/chat.js.map +1 -1
- package/package.json +11 -6
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TUI color theme — consistent palette for terminal rendering.
|
|
3
|
+
*
|
|
4
|
+
* Uses chalk for ANSI color output. All colors are defined here so the
|
|
5
|
+
* palette can be adjusted in one place.
|
|
6
|
+
*
|
|
7
|
+
* Brand color: emerald green (#34d399 / #10b981).
|
|
8
|
+
*/
|
|
9
|
+
export declare const theme: {
|
|
10
|
+
user: import("chalk").ChalkInstance;
|
|
11
|
+
assistant: import("chalk").ChalkInstance;
|
|
12
|
+
system: import("chalk").ChalkInstance;
|
|
13
|
+
heading: import("chalk").ChalkInstance;
|
|
14
|
+
firstHeading: import("chalk").ChalkInstance;
|
|
15
|
+
strong: import("chalk").ChalkInstance;
|
|
16
|
+
em: import("chalk").ChalkInstance;
|
|
17
|
+
codespan: import("chalk").ChalkInstance;
|
|
18
|
+
blockquote: import("chalk").ChalkInstance;
|
|
19
|
+
hr: import("chalk").ChalkInstance;
|
|
20
|
+
link: import("chalk").ChalkInstance;
|
|
21
|
+
href: import("chalk").ChalkInstance;
|
|
22
|
+
toolName: import("chalk").ChalkInstance;
|
|
23
|
+
toolDuration: import("chalk").ChalkInstance;
|
|
24
|
+
toolSymbol: import("chalk").ChalkInstance;
|
|
25
|
+
error: import("chalk").ChalkInstance;
|
|
26
|
+
errorLabel: import("chalk").ChalkInstance;
|
|
27
|
+
success: import("chalk").ChalkInstance;
|
|
28
|
+
dim: import("chalk").ChalkInstance;
|
|
29
|
+
label: import("chalk").ChalkInstance;
|
|
30
|
+
reasoning: import("chalk").ChalkInstance;
|
|
31
|
+
border: import("chalk").ChalkInstance;
|
|
32
|
+
separator: import("chalk").ChalkInstance;
|
|
33
|
+
muted: import("chalk").ChalkInstance;
|
|
34
|
+
};
|
|
35
|
+
/** Format a duration in ms to a human-readable string */
|
|
36
|
+
export declare function formatDuration(ms: number): string;
|
|
37
|
+
//# sourceMappingURL=theme.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../src/rendering/theme.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAQH,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;CAgCjB,CAAC;AAEF,yDAAyD;AACzD,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAGjD"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TUI color theme — consistent palette for terminal rendering.
|
|
3
|
+
*
|
|
4
|
+
* Uses chalk for ANSI color output. All colors are defined here so the
|
|
5
|
+
* palette can be adjusted in one place.
|
|
6
|
+
*
|
|
7
|
+
* Brand color: emerald green (#34d399 / #10b981).
|
|
8
|
+
*/
|
|
9
|
+
import chalk from "chalk";
|
|
10
|
+
const brand = chalk.hex("#34d399"); // emerald-300 — works on light and dark terminals
|
|
11
|
+
const brandBold = brand.bold;
|
|
12
|
+
const brandDim = chalk.hex("#065f46"); // emerald-900 — subtle borders, structural chrome
|
|
13
|
+
export const theme = {
|
|
14
|
+
// ── Roles ───────────────────────────────────────────────────────────────
|
|
15
|
+
user: brandBold,
|
|
16
|
+
assistant: brandBold,
|
|
17
|
+
system: chalk.gray,
|
|
18
|
+
// ── Markdown elements ──────────────────────────────────────────────────
|
|
19
|
+
heading: brandBold,
|
|
20
|
+
firstHeading: brandBold,
|
|
21
|
+
strong: chalk.bold,
|
|
22
|
+
em: chalk.italic,
|
|
23
|
+
codespan: chalk.hex("#fbbf24"), // amber
|
|
24
|
+
blockquote: chalk.gray.italic,
|
|
25
|
+
hr: brand,
|
|
26
|
+
link: brand.underline,
|
|
27
|
+
href: brand,
|
|
28
|
+
// ── Content blocks ─────────────────────────────────────────────────────
|
|
29
|
+
toolName: chalk.hex("#fbbf24").bold, // amber
|
|
30
|
+
toolDuration: chalk.gray,
|
|
31
|
+
toolSymbol: brand,
|
|
32
|
+
error: chalk.red,
|
|
33
|
+
errorLabel: chalk.red.bold,
|
|
34
|
+
success: chalk.green,
|
|
35
|
+
dim: chalk.gray,
|
|
36
|
+
label: chalk.gray,
|
|
37
|
+
reasoning: chalk.gray.italic,
|
|
38
|
+
// ── Structural ─────────────────────────────────────────────────────────
|
|
39
|
+
border: brandDim,
|
|
40
|
+
separator: brandDim,
|
|
41
|
+
muted: chalk.dim,
|
|
42
|
+
};
|
|
43
|
+
/** Format a duration in ms to a human-readable string */
|
|
44
|
+
export function formatDuration(ms) {
|
|
45
|
+
if (ms < 1000)
|
|
46
|
+
return `${ms}ms`;
|
|
47
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=theme.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.js","sourceRoot":"","sources":["../../src/rendering/theme.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,kDAAkD;AACtF,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC;AAC7B,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,kDAAkD;AAEzF,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,2EAA2E;IAC3E,IAAI,EAAE,SAAS;IACf,SAAS,EAAE,SAAS;IACpB,MAAM,EAAE,KAAK,CAAC,IAAI;IAElB,0EAA0E;IAC1E,OAAO,EAAE,SAAS;IAClB,YAAY,EAAE,SAAS;IACvB,MAAM,EAAE,KAAK,CAAC,IAAI;IAClB,EAAE,EAAE,KAAK,CAAC,MAAM;IAChB,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,QAAQ;IACxC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM;IAC7B,EAAE,EAAE,KAAK;IACT,IAAI,EAAE,KAAK,CAAC,SAAS;IACrB,IAAI,EAAE,KAAK;IAEX,0EAA0E;IAC1E,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,QAAQ;IAC7C,YAAY,EAAE,KAAK,CAAC,IAAI;IACxB,UAAU,EAAE,KAAK;IACjB,KAAK,EAAE,KAAK,CAAC,GAAG;IAChB,UAAU,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI;IAC1B,OAAO,EAAE,KAAK,CAAC,KAAK;IACpB,GAAG,EAAE,KAAK,CAAC,IAAI;IACf,KAAK,EAAE,KAAK,CAAC,IAAI;IACjB,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM;IAE5B,0EAA0E;IAC1E,MAAM,EAAE,QAAQ;IAChB,SAAS,EAAE,QAAQ;IACnB,KAAK,EAAE,KAAK,CAAC,GAAG;CACjB,CAAC;AAEF,yDAAyD;AACzD,MAAM,UAAU,cAAc,CAAC,EAAU;IACvC,IAAI,EAAE,GAAG,IAAI;QAAE,OAAO,GAAG,EAAE,IAAI,CAAC;IAChC,OAAO,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;AACtC,CAAC"}
|
package/dist/ui/chat.d.ts
CHANGED
|
@@ -1,18 +1,40 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Chat — default TUI layout.
|
|
2
|
+
* Chat — default TUI layout and single input orchestrator.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Uses useChat with renderMode: "block" — content blocks appear as they
|
|
5
|
+
* complete, while StreamingMessage shows token-by-token text for the
|
|
6
|
+
* current block being streamed.
|
|
6
7
|
*
|
|
7
8
|
* State machine: idle → streaming → (confirming_tool → streaming) → idle
|
|
8
9
|
* Ctrl+C behavior depends on state:
|
|
9
10
|
* - idle: exit the process
|
|
10
11
|
* - streaming: abort current execution
|
|
11
12
|
* - confirming_tool: reject tool, return to streaming
|
|
13
|
+
*
|
|
14
|
+
* Input routing priority:
|
|
15
|
+
* 1. Ctrl+C → always handled (abort/exit/reject based on state)
|
|
16
|
+
* 2. confirming_tool → Y/N/A keys via handleConfirmationKey
|
|
17
|
+
* 3. error displayed → any key dismisses
|
|
18
|
+
* 4. idle → editor.handleInput
|
|
12
19
|
*/
|
|
20
|
+
import type { ReactNode } from "react";
|
|
21
|
+
import type { ChatMode } from "@agentick/client";
|
|
22
|
+
export interface ChatStatusBarState {
|
|
23
|
+
mode: ChatMode;
|
|
24
|
+
isExecuting: boolean;
|
|
25
|
+
sessionId: string;
|
|
26
|
+
}
|
|
13
27
|
interface ChatProps {
|
|
14
28
|
sessionId: string;
|
|
29
|
+
/**
|
|
30
|
+
* Status bar configuration:
|
|
31
|
+
* - `false`: no status bar
|
|
32
|
+
* - `ReactNode`: custom static status bar
|
|
33
|
+
* - `(state) => ReactNode`: render prop with chat state
|
|
34
|
+
* - `undefined` (default): `<DefaultStatusBar>` wired to chat state
|
|
35
|
+
*/
|
|
36
|
+
statusBar?: false | ReactNode | ((state: ChatStatusBarState) => ReactNode);
|
|
15
37
|
}
|
|
16
|
-
export declare function Chat({ sessionId }: ChatProps): import("react/jsx-runtime").JSX.Element;
|
|
38
|
+
export declare function Chat({ sessionId, statusBar }: ChatProps): import("react/jsx-runtime").JSX.Element;
|
|
17
39
|
export {};
|
|
18
40
|
//# sourceMappingURL=chat.d.ts.map
|
package/dist/ui/chat.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/ui/chat.tsx"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/ui/chat.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAmBjD,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,QAAQ,CAAC;IACf,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,SAAS;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,KAAK,GAAG,SAAS,GAAG,CAAC,CAAC,KAAK,EAAE,kBAAkB,KAAK,SAAS,CAAC,CAAC;CAC5E;AAED,wBAAgB,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,SAAS,2CA8IvD"}
|
package/dist/ui/chat.js
CHANGED
|
@@ -1,97 +1,120 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
/**
|
|
3
|
-
* Chat — default TUI layout.
|
|
3
|
+
* Chat — default TUI layout and single input orchestrator.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* Uses useChat with renderMode: "block" — content blocks appear as they
|
|
6
|
+
* complete, while StreamingMessage shows token-by-token text for the
|
|
7
|
+
* current block being streamed.
|
|
7
8
|
*
|
|
8
9
|
* State machine: idle → streaming → (confirming_tool → streaming) → idle
|
|
9
10
|
* Ctrl+C behavior depends on state:
|
|
10
11
|
* - idle: exit the process
|
|
11
12
|
* - streaming: abort current execution
|
|
12
13
|
* - confirming_tool: reject tool, return to streaming
|
|
14
|
+
*
|
|
15
|
+
* Input routing priority:
|
|
16
|
+
* 1. Ctrl+C → always handled (abort/exit/reject based on state)
|
|
17
|
+
* 2. confirming_tool → Y/N/A keys via handleConfirmationKey
|
|
18
|
+
* 3. error displayed → any key dismisses
|
|
19
|
+
* 4. idle → editor.handleInput
|
|
13
20
|
*/
|
|
14
|
-
import { useCallback, useEffect, useState } from "react";
|
|
15
|
-
import { Box,
|
|
16
|
-
import {
|
|
21
|
+
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
22
|
+
import { Box, useApp, useInput } from "ink";
|
|
23
|
+
import { useChat } from "@agentick/react";
|
|
17
24
|
import { MessageList } from "../components/MessageList.js";
|
|
18
25
|
import { StreamingMessage } from "../components/StreamingMessage.js";
|
|
19
26
|
import { ToolCallIndicator } from "../components/ToolCallIndicator.js";
|
|
20
27
|
import { ToolConfirmationPrompt } from "../components/ToolConfirmationPrompt.js";
|
|
21
28
|
import { ErrorDisplay } from "../components/ErrorDisplay.js";
|
|
22
29
|
import { InputBar } from "../components/InputBar.js";
|
|
23
|
-
|
|
30
|
+
import { CompletionPicker } from "../components/CompletionPicker.js";
|
|
31
|
+
import { DefaultStatusBar } from "../components/status-bar/DefaultStatusBar.js";
|
|
32
|
+
import { useSlashCommands, helpCommand, exitCommand, createCommandCompletionSource, } from "../commands.js";
|
|
33
|
+
import { useCommandsConfig } from "../commands-context.js";
|
|
34
|
+
import { useLineEditor } from "../hooks/use-line-editor.js";
|
|
35
|
+
import { handleConfirmationKey } from "../input-utils.js";
|
|
36
|
+
export function Chat({ sessionId, statusBar }) {
|
|
24
37
|
const { exit } = useApp();
|
|
25
|
-
const {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const [toolConfirmation, setToolConfirmation] = useState(null);
|
|
29
|
-
const [error, setError] = useState(null);
|
|
30
|
-
// Sync streaming state → chatState (unless we're in confirming_tool, which takes priority)
|
|
31
|
-
useEffect(() => {
|
|
32
|
-
if (isStreaming && chatState === "idle") {
|
|
33
|
-
setChatState("streaming");
|
|
34
|
-
setError(null); // Clear previous errors on new execution
|
|
35
|
-
}
|
|
36
|
-
else if (!isStreaming && chatState === "streaming") {
|
|
37
|
-
setChatState("idle");
|
|
38
|
-
}
|
|
39
|
-
}, [isStreaming, chatState]);
|
|
40
|
-
// Register tool confirmation handler
|
|
41
|
-
useEffect(() => {
|
|
42
|
-
if (!accessor)
|
|
43
|
-
return;
|
|
44
|
-
return accessor.onToolConfirmation((request, respond) => {
|
|
45
|
-
setToolConfirmation({ request, respond });
|
|
46
|
-
setChatState("confirming_tool");
|
|
47
|
-
});
|
|
48
|
-
}, [accessor]);
|
|
49
|
-
// Ctrl+C handling
|
|
50
|
-
useInput((_input, key) => {
|
|
51
|
-
if (!key.ctrl || _input !== "c")
|
|
52
|
-
return;
|
|
53
|
-
if (chatState === "idle") {
|
|
54
|
-
exit();
|
|
55
|
-
}
|
|
56
|
-
else if (chatState === "streaming") {
|
|
57
|
-
abort();
|
|
58
|
-
setChatState("idle");
|
|
59
|
-
}
|
|
60
|
-
else if (chatState === "confirming_tool" && toolConfirmation) {
|
|
61
|
-
toolConfirmation.respond({ approved: false, reason: "cancelled by user" });
|
|
62
|
-
setToolConfirmation(null);
|
|
63
|
-
setChatState("streaming");
|
|
64
|
-
}
|
|
38
|
+
const { messages, chatMode, toolConfirmation, isExecuting, error, submit, abort, respondToConfirmation, } = useChat({
|
|
39
|
+
sessionId,
|
|
40
|
+
renderMode: "block",
|
|
65
41
|
});
|
|
42
|
+
// StreamingMessage still uses useStreamingText for live token display
|
|
43
|
+
// const { isStreaming } = useStreamingText();
|
|
44
|
+
const [dismissedError, setDismissedError] = useState(false);
|
|
45
|
+
// Track the error identity so dismissal resets on new errors
|
|
46
|
+
const displayError = error && !dismissedError ? error.message : null;
|
|
47
|
+
const configCommands = useCommandsConfig();
|
|
48
|
+
const commandCtx = useMemo(() => ({ sessionId, send: (text) => submit(text), abort, output: console.log }), [sessionId, submit, abort]);
|
|
49
|
+
const { dispatch, commands } = useSlashCommands([...configCommands, helpCommand(), exitCommand(exit)], commandCtx);
|
|
66
50
|
const handleSubmit = useCallback((text) => {
|
|
67
|
-
if (text
|
|
68
|
-
|
|
51
|
+
if (dispatch(text))
|
|
52
|
+
return;
|
|
53
|
+
setDismissedError(false);
|
|
54
|
+
submit(text);
|
|
55
|
+
}, [dispatch, submit]);
|
|
56
|
+
const handleToolConfirmationResponse = useCallback((response) => {
|
|
57
|
+
respondToConfirmation(response);
|
|
58
|
+
}, [respondToConfirmation]);
|
|
59
|
+
const handleErrorDismiss = useCallback(() => {
|
|
60
|
+
setDismissedError(true);
|
|
61
|
+
}, []);
|
|
62
|
+
// Chat owns the line editor directly
|
|
63
|
+
const editor = useLineEditor({ onSubmit: handleSubmit });
|
|
64
|
+
// Register "/" command completion source
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
return editor.editor.registerCompletion(createCommandCompletionSource(commands));
|
|
67
|
+
}, [editor.editor, commands]);
|
|
68
|
+
// Single centralized input handler — all keystrokes route through here
|
|
69
|
+
useInput((input, key) => {
|
|
70
|
+
// 1. Ctrl+C → always handled
|
|
71
|
+
if (key.ctrl && input === "c") {
|
|
72
|
+
if (chatMode === "idle") {
|
|
73
|
+
exit();
|
|
74
|
+
}
|
|
75
|
+
else if (chatMode === "streaming") {
|
|
76
|
+
abort();
|
|
77
|
+
}
|
|
78
|
+
else if (chatMode === "confirming_tool" && toolConfirmation) {
|
|
79
|
+
respondToConfirmation({ approved: false, reason: "cancelled by user" });
|
|
80
|
+
}
|
|
69
81
|
return;
|
|
70
82
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
83
|
+
// 2. Tool confirmation → Y/N/A
|
|
84
|
+
if (chatMode === "confirming_tool" && toolConfirmation) {
|
|
85
|
+
handleConfirmationKey(input, handleToolConfirmationResponse);
|
|
86
|
+
return;
|
|
74
87
|
}
|
|
75
|
-
|
|
76
|
-
|
|
88
|
+
// 3. Error displayed → any key dismisses
|
|
89
|
+
if (displayError && chatMode === "idle") {
|
|
90
|
+
handleErrorDismiss();
|
|
91
|
+
return;
|
|
77
92
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
toolConfirmation.respond(response);
|
|
82
|
-
setToolConfirmation(null);
|
|
83
|
-
setChatState("streaming");
|
|
93
|
+
// 4. Idle → route to editor
|
|
94
|
+
if (chatMode === "idle") {
|
|
95
|
+
editor.handleInput(input, key);
|
|
84
96
|
}
|
|
85
|
-
}
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
}, []);
|
|
89
|
-
const isInputDisabled = chatState !== "idle";
|
|
90
|
-
const placeholder = chatState === "streaming"
|
|
97
|
+
});
|
|
98
|
+
const isInputActive = chatMode === "idle";
|
|
99
|
+
const placeholder = chatMode === "streaming"
|
|
91
100
|
? "Waiting for response... (Ctrl+C to abort)"
|
|
92
|
-
:
|
|
101
|
+
: chatMode === "confirming_tool"
|
|
93
102
|
? "Confirm or reject the tool above..."
|
|
94
103
|
: undefined;
|
|
95
|
-
|
|
104
|
+
// Resolve status bar content
|
|
105
|
+
let statusBarContent;
|
|
106
|
+
if (statusBar === false) {
|
|
107
|
+
statusBarContent = null;
|
|
108
|
+
}
|
|
109
|
+
else if (typeof statusBar === "function") {
|
|
110
|
+
statusBarContent = statusBar({ mode: chatMode, isExecuting, sessionId });
|
|
111
|
+
}
|
|
112
|
+
else if (statusBar !== undefined) {
|
|
113
|
+
statusBarContent = statusBar;
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
statusBarContent = (_jsx(DefaultStatusBar, { sessionId: sessionId, mode: chatMode, isExecuting: isExecuting }));
|
|
117
|
+
}
|
|
118
|
+
return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(MessageList, { messages: messages, isExecuting: isExecuting }), _jsx(StreamingMessage, {}), _jsx(ToolCallIndicator, { sessionId: sessionId }), chatMode === "confirming_tool" && toolConfirmation && (_jsx(ToolConfirmationPrompt, { request: toolConfirmation.request })), _jsx(ErrorDisplay, { error: displayError, showDismissHint: !!displayError && chatMode === "idle" }), editor.completion && _jsx(CompletionPicker, { completion: editor.completion }), _jsx(Box, { marginTop: 1, children: _jsx(InputBar, { value: editor.value, cursor: editor.cursor, isActive: isInputActive, placeholder: placeholder }) }), statusBarContent] }));
|
|
96
119
|
}
|
|
97
120
|
//# sourceMappingURL=chat.js.map
|
package/dist/ui/chat.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat.js","sourceRoot":"","sources":["../../src/ui/chat.tsx"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"chat.js","sourceRoot":"","sources":["../../src/ui/chat.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentick/tui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Terminal UI for Agentick agents using Ink",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent",
|
|
@@ -34,18 +34,23 @@
|
|
|
34
34
|
"access": "public"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
+
"chalk": "^5.6.2",
|
|
37
38
|
"eventsource": "^2.0.2",
|
|
38
39
|
"ink": "^5.1.0",
|
|
39
40
|
"ink-spinner": "^5.0.0",
|
|
40
41
|
"ink-text-input": "^6.0.0",
|
|
42
|
+
"marked": "^15.0.12",
|
|
43
|
+
"marked-terminal": "^7.3.0",
|
|
41
44
|
"react": "^19.0.0",
|
|
42
|
-
"@agentick/client": "0.
|
|
43
|
-
"@agentick/core": "0.
|
|
44
|
-
"@agentick/react": "0.
|
|
45
|
-
"@agentick/shared": "0.
|
|
45
|
+
"@agentick/client": "0.5.0",
|
|
46
|
+
"@agentick/core": "0.6.0",
|
|
47
|
+
"@agentick/react": "0.5.0",
|
|
48
|
+
"@agentick/shared": "0.6.0"
|
|
46
49
|
},
|
|
47
50
|
"devDependencies": {
|
|
51
|
+
"@testing-library/react": "^16.3.2",
|
|
48
52
|
"@types/eventsource": "^1.1.15",
|
|
53
|
+
"@types/marked-terminal": "^6.1.1",
|
|
49
54
|
"@types/react": "^19.2.13",
|
|
50
55
|
"ink-testing-library": "^4.0.0",
|
|
51
56
|
"typescript": "^5.7.3",
|
|
@@ -55,7 +60,7 @@
|
|
|
55
60
|
"build": "tsc -p tsconfig.build.json",
|
|
56
61
|
"dev": "tsc --watch",
|
|
57
62
|
"typecheck": "tsc -p tsconfig.build.json --noEmit",
|
|
58
|
-
"clean": "rm -rf dist",
|
|
63
|
+
"clean": "rm -rf dist tsconfig.build.tsbuildinfo",
|
|
59
64
|
"lint": "oxlint src/",
|
|
60
65
|
"format:check": "oxfmt --check src/",
|
|
61
66
|
"start": "tsx --tsconfig tsconfig.json src/bin.ts",
|