@aiaiaichain/agent 0.1.6 → 0.1.7

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 (121) hide show
  1. package/dist/api/ExtensionAPI.d.ts +0 -1
  2. package/dist/api/ExtensionAPI.js +3 -7
  3. package/dist/api/Registry.d.ts +0 -1
  4. package/dist/api/Registry.js +54 -57
  5. package/dist/cli.d.ts +0 -1
  6. package/dist/cli.js +683 -686
  7. package/dist/core/AgentDir.d.ts +1 -1
  8. package/dist/core/AgentDir.js +45 -39
  9. package/dist/core/ChainConfig.d.ts +0 -1
  10. package/dist/core/ChainConfig.js +51 -55
  11. package/dist/core/EnvLoader.d.ts +4 -1
  12. package/dist/core/EnvLoader.js +97 -84
  13. package/dist/core/SystemMonitor.d.ts +0 -1
  14. package/dist/core/SystemMonitor.js +72 -85
  15. package/dist/index.d.ts +0 -1
  16. package/dist/index.js +19 -26
  17. package/dist/loader.d.ts +0 -1
  18. package/dist/loader.js +64 -67
  19. package/dist/mcp/entry.d.ts +0 -1
  20. package/dist/mcp/entry.js +3 -6
  21. package/dist/mcp/server.d.ts +0 -1
  22. package/dist/mcp/server.js +152 -156
  23. package/dist/models/CostTracker.d.ts +0 -1
  24. package/dist/models/CostTracker.js +58 -61
  25. package/dist/models/ModelRegistry.d.ts +0 -1
  26. package/dist/models/ModelRegistry.js +195 -155
  27. package/dist/providers/ProviderRegistry.d.ts +0 -1
  28. package/dist/providers/ProviderRegistry.js +33 -36
  29. package/dist/runner/AgentRunner.d.ts +0 -1
  30. package/dist/runner/AgentRunner.js +180 -184
  31. package/dist/runner/ModelClient.d.ts +0 -1
  32. package/dist/runner/ModelClient.js +133 -134
  33. package/dist/runner/SwarmRouter.d.ts +0 -1
  34. package/dist/runner/SwarmRouter.js +18 -22
  35. package/dist/runner/ToolDispatcher.d.ts +0 -1
  36. package/dist/runner/ToolDispatcher.js +30 -33
  37. package/dist/scheduler/AgentScheduler.d.ts +0 -1
  38. package/dist/scheduler/AgentScheduler.js +99 -103
  39. package/dist/session/ContextStore.d.ts +1 -1
  40. package/dist/session/ContextStore.js +76 -78
  41. package/dist/session/GoalManager.d.ts +0 -1
  42. package/dist/session/GoalManager.js +96 -100
  43. package/dist/session/MemoryStore.d.ts +2 -1
  44. package/dist/session/MemoryStore.js +108 -87
  45. package/dist/session/SessionManager.d.ts +5 -4
  46. package/dist/session/SessionManager.js +83 -62
  47. package/dist/session/SessionStore.d.ts +0 -1
  48. package/dist/session/SessionStore.js +112 -116
  49. package/dist/setup/SetupWizard.d.ts +0 -1
  50. package/dist/setup/SetupWizard.js +61 -64
  51. package/dist/tools/CrossTools.d.ts +0 -1
  52. package/dist/tools/CrossTools.js +140 -144
  53. package/dist/tools/GmgnIntegration.d.ts +0 -1
  54. package/dist/tools/GmgnIntegration.js +220 -230
  55. package/dist/tools/MarketSentiment.d.ts +0 -1
  56. package/dist/tools/MarketSentiment.js +213 -195
  57. package/dist/tools/NewsSentiment.d.ts +0 -1
  58. package/dist/tools/NewsSentiment.js +126 -130
  59. package/dist/tools/PriceFeed.d.ts +6 -1
  60. package/dist/tools/PriceFeed.js +201 -133
  61. package/dist/tools/TechnicalAnalysis.d.ts +1 -2
  62. package/dist/tools/TechnicalAnalysis.js +248 -216
  63. package/dist/tools/TechnicalAnalysis.worker.d.ts +25 -0
  64. package/dist/tools/TechnicalAnalysis.worker.js +92 -0
  65. package/dist/tools/TokenCalendar.d.ts +0 -1
  66. package/dist/tools/TokenCalendar.js +63 -68
  67. package/dist/tools/TokenSecurityScanner.d.ts +0 -1
  68. package/dist/tools/TokenSecurityScanner.js +93 -96
  69. package/dist/tools/TransactionSim.d.ts +0 -1
  70. package/dist/tools/TransactionSim.js +65 -71
  71. package/dist/tui/App.d.ts +0 -1
  72. package/dist/tui/App.js +895 -824
  73. package/dist/tui/ModelSelector.d.ts +0 -1
  74. package/dist/tui/ModelSelector.js +46 -49
  75. package/dist/tui/REPL.d.ts +0 -1
  76. package/dist/tui/REPL.js +222 -210
  77. package/dist/tui/Sparkline.d.ts +0 -1
  78. package/dist/tui/Sparkline.js +36 -37
  79. package/dist/tui/StatusBar.d.ts +0 -1
  80. package/dist/tui/StatusBar.js +9 -10
  81. package/dist/tui/ThemePresets.d.ts +0 -1
  82. package/dist/tui/ThemePresets.js +99 -103
  83. package/dist/tui/theme.d.ts +0 -1
  84. package/dist/tui/theme.js +50 -31
  85. package/dist/util/clipboard.d.ts +0 -1
  86. package/dist/util/clipboard.js +16 -20
  87. package/dist/util/commandSuggest.d.ts +0 -1
  88. package/dist/util/commandSuggest.js +34 -38
  89. package/dist/util/confirmation.d.ts +0 -1
  90. package/dist/util/confirmation.js +8 -11
  91. package/dist/util/errorHandler.d.ts +0 -1
  92. package/dist/util/errorHandler.js +20 -23
  93. package/dist/util/errors.d.ts +59 -0
  94. package/dist/util/errors.js +93 -0
  95. package/dist/util/logger.d.ts +0 -1
  96. package/dist/util/logger.js +30 -33
  97. package/dist/util/processManager.d.ts +0 -1
  98. package/dist/util/processManager.js +33 -36
  99. package/dist/util/resilientFetch.d.ts +6 -1
  100. package/dist/util/resilientFetch.js +134 -80
  101. package/dist/util/responseCache.d.ts +0 -1
  102. package/dist/util/responseCache.js +36 -45
  103. package/dist/util/rpc.d.ts +16 -0
  104. package/dist/util/rpc.js +69 -0
  105. package/dist/util/safeLog.d.ts +0 -1
  106. package/dist/util/safeLog.js +52 -53
  107. package/dist/util/scheduler.d.ts +0 -1
  108. package/dist/util/scheduler.js +53 -58
  109. package/dist/util/webhooks.d.ts +0 -1
  110. package/dist/util/webhooks.js +54 -58
  111. package/dist/wallet/ActionFeed.d.ts +0 -1
  112. package/dist/wallet/ActionFeed.js +189 -200
  113. package/dist/wallet/AgentWallet.d.ts +7 -8
  114. package/dist/wallet/AgentWallet.js +117 -144
  115. package/dist/wallet/ProfitTracker.d.ts +0 -1
  116. package/dist/wallet/ProfitTracker.js +71 -74
  117. package/package.json +11 -6
  118. package/scripts/build-esbuild.mjs +40 -0
  119. package/scripts/bundle-dts.mjs +58 -0
  120. package/scripts/minify.mjs +44 -0
  121. package/scripts/postinstall.js +27 -0
@@ -15,4 +15,3 @@ export interface ModelSelectorProps {
15
15
  }
16
16
  export declare function ModelSelector({ models, currentModelId, onSelect, onCancel, initialQuery }: ModelSelectorProps): React.JSX.Element;
17
17
  export {};
18
- //# sourceMappingURL=ModelSelector.d.ts.map
@@ -1,59 +1,56 @@
1
1
  import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
- /**
3
- * ModelSelector — interactive model picker overlay.
4
- */
2
+
5
3
  import { useState, useCallback, useEffect, useMemo } from "react";
6
4
  import { Box, Text, useInput } from "ink";
7
5
  import TextInput from "ink-text-input";
8
6
  import { AIAIAI_COLORS } from "./theme.js";
9
7
  const VISIBLE_COUNT = 10;
10
8
  function fuzzyFilter(items, query) {
11
- const q = query.toLowerCase().trim();
12
- if (!q)
13
- return items;
14
- return items.filter((item) => {
15
- const hay = `${item.id} ${item.tier}`.toLowerCase();
16
- return hay.includes(q);
17
- });
9
+ const q = query.toLowerCase().trim();
10
+ if (!q)
11
+ return items;
12
+ return items.filter((item) => {
13
+ const hay = `${item.id} ${item.tier}`.toLowerCase();
14
+ return hay.includes(q);
15
+ });
18
16
  }
19
17
  export function ModelSelector({ models, currentModelId, onSelect, onCancel, initialQuery = "" }) {
20
- const [query, setQuery] = useState(initialQuery);
21
- const [selectedIndex, setSelectedIndex] = useState(0);
22
- const filtered = useMemo(() => fuzzyFilter(models, query), [models, query]);
23
- useEffect(() => {
24
- setSelectedIndex((prev) => Math.min(prev, Math.max(0, filtered.length - 1)));
25
- }, [filtered.length]);
26
- const handleSubmit = useCallback(() => {
27
- const selected = filtered[selectedIndex];
28
- if (selected)
29
- onSelect(selected.id);
30
- }, [filtered, selectedIndex, onSelect]);
31
- useInput((input, key) => {
32
- if (key.escape) {
33
- onCancel();
34
- return;
35
- }
36
- if (key.upArrow) {
37
- setSelectedIndex(i => Math.max(0, i - 1));
38
- return;
39
- }
40
- if (key.downArrow) {
41
- setSelectedIndex(i => Math.min(filtered.length - 1, i + 1));
42
- return;
43
- }
44
- if (key.return) {
45
- handleSubmit();
46
- return;
47
- }
48
- });
49
- const start = Math.max(0, Math.min(selectedIndex - Math.floor(VISIBLE_COUNT / 2), filtered.length - VISIBLE_COUNT));
50
- const visible = filtered.slice(start, start + VISIBLE_COUNT);
51
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: AIAIAI_COLORS.accent, paddingX: 1, children: [_jsxs(Text, { color: AIAIAI_COLORS.accent, bold: true, children: ["Select Model (", filtered.length, ")"] }), _jsxs(Box, { children: [_jsx(Text, { color: AIAIAI_COLORS.muted, children: "filter: " }), _jsx(TextInput, { value: query, onChange: setQuery, placeholder: "type to filter\u2026" })] }), _jsxs(Box, { flexDirection: "column", marginTop: 1, children: [visible.map((m, i) => {
52
- const realIdx = start + i;
53
- const isSelected = realIdx === selectedIndex;
54
- const isCurrent = m.id === currentModelId;
55
- const tierIcon = { orchestrator: "⭐", analyst: "🔬", worker: "⚡", free: "🆓" }[m.tier] ?? "•";
56
- return (_jsxs(Text, { color: isSelected ? AIAIAI_COLORS.accent : AIAIAI_COLORS.muted, bold: isSelected, children: [isSelected ? "› " : " ", tierIcon, " ", m.id, isCurrent ? " (current)" : ""] }, m.id));
57
- }), filtered.length === 0 && _jsx(Text, { color: AIAIAI_COLORS.muted, children: "No models match." })] }), _jsx(Text, { color: AIAIAI_COLORS.dim, children: "\u2191\u2193 navigate \u00B7 Enter select \u00B7 Esc cancel" })] }));
18
+ const [query, setQuery] = useState(initialQuery);
19
+ const [selectedIndex, setSelectedIndex] = useState(0);
20
+ const filtered = useMemo(() => fuzzyFilter(models, query), [models, query]);
21
+ useEffect(() => {
22
+ setSelectedIndex((prev) => Math.min(prev, Math.max(0, filtered.length - 1)));
23
+ }, [filtered.length]);
24
+ const handleSubmit = useCallback(() => {
25
+ const selected = filtered[selectedIndex];
26
+ if (selected)
27
+ onSelect(selected.id);
28
+ }, [filtered, selectedIndex, onSelect]);
29
+ useInput((input, key) => {
30
+ if (key.escape) {
31
+ onCancel();
32
+ return;
33
+ }
34
+ if (key.upArrow) {
35
+ setSelectedIndex(i => Math.max(0, i - 1));
36
+ return;
37
+ }
38
+ if (key.downArrow) {
39
+ setSelectedIndex(i => Math.min(filtered.length - 1, i + 1));
40
+ return;
41
+ }
42
+ if (key.return) {
43
+ handleSubmit();
44
+ return;
45
+ }
46
+ });
47
+ const start = Math.max(0, Math.min(selectedIndex - Math.floor(VISIBLE_COUNT / 2), filtered.length - VISIBLE_COUNT));
48
+ const visible = filtered.slice(start, start + VISIBLE_COUNT);
49
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: AIAIAI_COLORS.accent, paddingX: 1, children: [_jsxs(Text, { color: AIAIAI_COLORS.accent, bold: true, children: ["Select Model (", filtered.length, ")"] }), _jsxs(Box, { children: [_jsx(Text, { color: AIAIAI_COLORS.muted, children: "filter: " }), _jsx(TextInput, { value: query, onChange: setQuery, placeholder: "type to filter\u2026" })] }), _jsxs(Box, { flexDirection: "column", marginTop: 1, children: [visible.map((m, i) => {
50
+ const realIdx = start + i;
51
+ const isSelected = realIdx === selectedIndex;
52
+ const isCurrent = m.id === currentModelId;
53
+ const tierIcon = { orchestrator: "⭐", analyst: "🔬", worker: "⚡", free: "🆓" }[m.tier] ?? "•";
54
+ return (_jsxs(Text, { color: isSelected ? AIAIAI_COLORS.accent : AIAIAI_COLORS.muted, bold: isSelected, children: [isSelected ? "› " : " ", tierIcon, " ", m.id, isCurrent ? " (current)" : ""] }, m.id));
55
+ }), filtered.length === 0 && _jsx(Text, { color: AIAIAI_COLORS.muted, children: "No models match." })] }), _jsx(Text, { color: AIAIAI_COLORS.dim, children: "\u2191\u2193 navigate \u00B7 Enter select \u00B7 Esc cancel" })] }));
58
56
  }
59
- //# sourceMappingURL=ModelSelector.js.map
@@ -20,4 +20,3 @@ export interface REPLProps {
20
20
  disabled?: boolean;
21
21
  }
22
22
  export declare function REPL({ messages, streamingText, toolRunning, onSubmit, onAbort, disabled }: REPLProps): React.JSX.Element;
23
- //# sourceMappingURL=REPL.d.ts.map
package/dist/tui/REPL.js CHANGED
@@ -1,222 +1,234 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- /**
3
- * REPL scrolling message history + feature-rich input box.
4
- * Supports: multi-line (Shift+Enter), command history (↑/↓), tab completion.
5
- */
6
- import { useState, useCallback, useRef } from "react";
2
+
3
+ import React, { useState, useCallback, useRef } from "react";
7
4
  import { Box, Text, useStdout, useInput } from "ink";
8
5
  import { AIAIAI_COLORS } from "./theme.js";
9
6
  const MAX_VISIBLE = 40;
10
7
  const MAX_HISTORY = 100;
11
- // ── Command completions ─────────────────────────────────────────────────────
8
+
9
+ const timeCache = new Map();
10
+ function formatTime(ts) {
11
+ const cached = timeCache.get(ts);
12
+ if (cached)
13
+ return cached;
14
+ const s = new Date(ts).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
15
+ timeCache.set(ts, s);
16
+
17
+ if (timeCache.size > 500) {
18
+ const first = timeCache.keys().next().value;
19
+ if (first !== undefined)
20
+ timeCache.delete(first);
21
+ }
22
+ return s;
23
+ }
24
+
12
25
  const COMMANDS = [
13
- "token info", "token security", "token holders", "token traders",
14
- "track kol", "track smartmoney", "track follow-wallet",
15
- "market kline", "market trending", "market trenches", "market signal",
16
- "watch", "unwatch", "watchlist", "alerts", "alert above", "alert below",
17
- "compare",
18
- "price", "news", "models", "cost", "model", "clear",
19
- "wallet", "deposit", "burn", "actions", "activity", "fees",
20
- "keys", "providers", "goals", "goal add", "goal done", "goal list",
21
- "schedule", "sessions", "resume", "memory", "update", "gmgn", "help",
22
- "exit", "quit",
26
+ "token info", "token security", "token holders", "token traders",
27
+ "track kol", "track smartmoney", "track follow-wallet",
28
+ "market kline", "market trending", "market trenches", "market signal",
29
+ "watch", "unwatch", "watchlist", "alerts", "alert above", "alert below",
30
+ "compare",
31
+ "price", "news", "models", "cost", "model", "clear",
32
+ "wallet", "deposit", "burn", "actions", "activity", "fees",
33
+ "keys", "providers", "goals", "goal add", "goal done", "goal list",
34
+ "schedule", "sessions", "resume", "memory", "update", "gmgn", "help",
35
+ "exit", "quit",
23
36
  ];
24
37
  function getCompletions(prefix) {
25
- if (!prefix || prefix === "/")
26
- return COMMANDS.map(c => `/${c}`);
27
- const p = prefix.startsWith("/") ? prefix.slice(1) : prefix;
28
- return COMMANDS.filter(c => c.startsWith(p)).map(c => `/${c}`);
29
- }
30
- // ── Message components ──────────────────────────────────────────────────────
31
- function MessageLine({ msg }) {
32
- const time = new Date(msg.ts).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
33
- if (msg.role === "user") {
34
- return (_jsxs(Box, { flexDirection: "row", gap: 1, marginTop: 1, children: [_jsx(Text, { color: AIAIAI_COLORS.muted, children: time }), _jsx(Text, { color: AIAIAI_COLORS.accent, bold: true, children: "you " }), _jsx(Text, { wrap: "wrap", children: msg.content })] }));
35
- }
36
- if (msg.role === "assistant") {
37
- return (_jsxs(Box, { flexDirection: "row", gap: 1, marginTop: 1, children: [_jsx(Text, { color: AIAIAI_COLORS.muted, children: time }), _jsx(Text, { color: AIAIAI_COLORS.header, bold: true, children: "\uD83E\uDD16 " }), _jsx(Text, { wrap: "wrap", children: msg.content })] }));
38
- }
39
- if (msg.role === "tool") {
40
- const icon = msg.isError ? "✗" : "✓";
41
- const col = msg.isError ? AIAIAI_COLORS.error : AIAIAI_COLORS.success;
42
- const isLong = msg.content.length > 120;
43
- return (_jsxs(Box, { flexDirection: "column", marginY: 0, children: [_jsxs(Box, { flexDirection: "row", gap: 1, children: [_jsx(Text, { color: AIAIAI_COLORS.muted, children: time }), _jsxs(Text, { color: col, children: [icon, " ", msg.toolName ?? "tool"] }), isLong && _jsxs(Text, { color: AIAIAI_COLORS.dim, children: [" (", msg.content.length, " chars)"] })] }), !isLong && (_jsx(Box, { marginLeft: 6, children: _jsx(Text, { color: AIAIAI_COLORS.muted, wrap: "wrap", children: msg.content }) }))] }));
44
- }
45
- if (msg.role === "notify") {
46
- return (_jsx(Box, { borderStyle: "round", borderColor: AIAIAI_COLORS.accent, marginY: 1, paddingX: 1, children: _jsx(Text, { wrap: "wrap", children: msg.content }) }));
47
- }
48
- // system — dimmed
49
- return (_jsx(Box, { flexDirection: "row", gap: 1, children: _jsx(Text, { color: AIAIAI_COLORS.dim, wrap: "wrap", children: msg.content }) }));
38
+ if (!prefix || prefix === "/")
39
+ return COMMANDS.map(c => `/${c}`);
40
+ const p = prefix.startsWith("/") ? prefix.slice(1) : prefix;
41
+ return COMMANDS.filter(c => c.startsWith(p)).map(c => `/${c}`);
42
+ }
43
+
44
+ const MessageLine = React.memo(function MessageLine({ msg }) {
45
+ const time = formatTime(msg.ts);
46
+ if (msg.role === "user") {
47
+ return (_jsxs(Box, { flexDirection: "row", gap: 1, marginTop: 1, children: [_jsx(Text, { color: AIAIAI_COLORS.muted, children: time }), _jsx(Text, { color: AIAIAI_COLORS.accent, bold: true, children: "you " }), _jsx(Text, { wrap: "wrap", children: msg.content })] }));
48
+ }
49
+ if (msg.role === "assistant") {
50
+ return (_jsxs(Box, { flexDirection: "row", gap: 1, marginTop: 1, children: [_jsx(Text, { color: AIAIAI_COLORS.muted, children: time }), _jsx(Text, { color: AIAIAI_COLORS.header, bold: true, children: "\uD83E\uDD16 " }), _jsx(Text, { wrap: "wrap", children: msg.content })] }));
50
51
  }
52
+ if (msg.role === "tool") {
53
+ const icon = msg.isError ? "✗" : "✓";
54
+ const col = msg.isError ? AIAIAI_COLORS.error : AIAIAI_COLORS.success;
55
+ const isLong = msg.content.length > 120;
56
+ return (_jsxs(Box, { flexDirection: "column", marginY: 0, children: [_jsxs(Box, { flexDirection: "row", gap: 1, children: [_jsx(Text, { color: AIAIAI_COLORS.muted, children: time }), _jsxs(Text, { color: col, children: [icon, " ", msg.toolName ?? "tool"] }), isLong && _jsxs(Text, { color: AIAIAI_COLORS.dim, children: [" (", msg.content.length, " chars)"] })] }), !isLong && (_jsx(Box, { marginLeft: 6, children: _jsx(Text, { color: AIAIAI_COLORS.muted, wrap: "wrap", children: msg.content }) }))] }));
57
+ }
58
+ if (msg.role === "notify") {
59
+ return (_jsx(Box, { borderStyle: "round", borderColor: AIAIAI_COLORS.accent, marginY: 1, paddingX: 1, children: _jsx(Text, { wrap: "wrap", children: msg.content }) }));
60
+ }
61
+
62
+ return (_jsx(Box, { flexDirection: "row", gap: 1, children: _jsx(Text, { color: AIAIAI_COLORS.dim, wrap: "wrap", children: msg.content }) }));
63
+ });
51
64
  function InputBox({ value, onChange, onSubmit, disabled, onAbort }) {
52
- const [cursor, setCursor] = useState(value.length);
53
- const [history, setHistory] = useState([]);
54
- const [historyIdx, setHistoryIdx] = useState(-1);
55
- const [completions, setCompletions] = useState([]);
56
- const [completionIdx, setCompletionIdx] = useState(-1);
57
- const [showCompletions, setShowCompletions] = useState(false);
58
- const valueRef = useRef(value);
59
- const cursorRef = useRef(cursor);
60
- valueRef.current = value;
61
- cursorRef.current = cursor;
62
- // Messages scroll handled by Ink container
63
- const insertAtCursor = useCallback((text) => {
64
- const before = valueRef.current.slice(0, cursorRef.current);
65
- const after = valueRef.current.slice(cursorRef.current);
66
- const newVal = before + text + after;
67
- onChange(newVal);
68
- setCursor(cursorRef.current + text.length);
69
- }, [onChange]);
70
- const doSubmit = useCallback(() => {
71
- const val = valueRef.current;
72
- if (!val.trim() || disabled)
73
- return;
74
- setHistory(prev => [val, ...prev].slice(0, MAX_HISTORY));
75
- setHistoryIdx(-1);
76
- setShowCompletions(false);
77
- onChange("");
78
- setCursor(0);
79
- onSubmit(val);
80
- }, [disabled, onChange, onSubmit]);
81
- useInput((input, key) => {
82
- // Always handle Escape for abort
83
- if (key.escape) {
84
- if (disabled) {
85
- onAbort();
86
- return;
87
- }
88
- setShowCompletions(false);
89
- return;
90
- }
91
- if (disabled)
92
- return;
93
- // Tab completion
94
- if (key.tab) {
95
- const val = valueRef.current;
96
- if (!showCompletions) {
97
- // Check only when typing a command
98
- if (val.startsWith("/") && val.length > 0) {
99
- const comps = getCompletions(val);
100
- if (comps.length === 1 && comps[0] !== val) {
101
- // Auto-complete if only one match
102
- onChange(comps[0] + " ");
103
- setCursor(comps[0].length + 1);
104
- return;
105
- }
106
- if (comps.length > 0) {
107
- setCompletions(comps);
108
- setCompletionIdx(0);
109
- setShowCompletions(true);
110
- return;
111
- }
112
- }
113
- return;
114
- }
115
- // Cycle through completions
116
- if (completions.length > 0) {
117
- const nextIdx = (completionIdx + 1) % completions.length;
118
- setCompletionIdx(nextIdx);
119
- // Show the completion
120
- const comp = completions[nextIdx];
121
- onChange(comp + " ");
122
- setCursor(comp.length + 1);
123
- }
124
- return;
125
- }
126
- // Close completions on any other key
127
- if (showCompletions)
128
- setShowCompletions(false);
129
- // Enter submits
130
- if (key.return) {
131
- // Shift+Enter = new line, Enter = submit
132
- if (input === "\r" && !key.shift) {
133
- doSubmit();
134
- return;
135
- }
136
- // Shift+Enter inserts newline
137
- if (key.shift || input === "\u0003") {
138
- insertAtCursor("\n");
139
- return;
140
- }
141
- }
142
- // History navigation (↑/↓)
143
- if (key.upArrow) {
144
- if (history.length === 0)
145
- return;
146
- const newIdx = historyIdx < history.length - 1 ? historyIdx + 1 : historyIdx;
147
- setHistoryIdx(newIdx);
148
- onChange(history[newIdx]);
149
- setCursor(history[newIdx].length);
150
- return;
151
- }
152
- if (key.downArrow) {
153
- if (historyIdx <= 0) {
154
- setHistoryIdx(-1);
155
- onChange("");
156
- setCursor(0);
157
- return;
158
- }
159
- const newIdx = historyIdx - 1;
160
- setHistoryIdx(newIdx);
161
- onChange(history[newIdx]);
162
- setCursor(history[newIdx].length);
163
- return;
164
- }
165
- // Left/right arrow — update cursor tracking
166
- if (key.leftArrow) {
167
- setCursor(Math.max(0, cursorRef.current - 1));
168
- return;
169
- }
170
- if (key.rightArrow) {
171
- setCursor(Math.min(valueRef.current.length, cursorRef.current + 1));
172
- return;
173
- }
174
- // Backspace
175
- if (key.backspace || key.delete) {
176
- if (cursorRef.current <= 0)
177
- return;
178
- const before = valueRef.current.slice(0, cursorRef.current - 1);
179
- const after = valueRef.current.slice(cursorRef.current);
180
- onChange(before + after);
181
- setCursor(cursorRef.current - 1);
182
- return;
183
- }
184
- // Printable character
185
- if (input && input.length === 1 && input.charCodeAt(0) >= 32) {
186
- insertAtCursor(input);
187
- return;
188
- }
189
- });
190
- const placeholder = disabled ? "thinking…" : "message or /command";
191
- const displayValue = value || placeholder;
192
- const inputLines = displayValue.split("\n");
193
- const inputHeight = Math.min(inputLines.length, 5); // max 5 visible lines
194
- return (_jsxs(Box, { flexDirection: "column", children: [showCompletions && completions.length > 0 && (_jsxs(Box, { borderStyle: "single", borderColor: AIAIAI_COLORS.accent, paddingX: 1, flexDirection: "column", marginBottom: 0, children: [completions.slice(0, 8).map((c, i) => (_jsxs(Text, { color: i === completionIdx ? AIAIAI_COLORS.accent : AIAIAI_COLORS.muted, bold: i === completionIdx, children: [i === completionIdx ? "▸ " : " ", c] }, c))), completions.length > 8 && (_jsxs(Text, { color: AIAIAI_COLORS.dim, children: [" \u2026", completions.length - 8, " more"] }))] })), _jsx(Box, { borderStyle: "round", borderColor: disabled ? AIAIAI_COLORS.dim : AIAIAI_COLORS.accent, paddingX: 1, paddingY: inputHeight > 1 ? 0 : 0, flexDirection: "column", marginTop: 1, children: _jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: AIAIAI_COLORS.accent, bold: true, children: "\u203A " }), _jsx(Box, { flexDirection: "column", flexGrow: 1, children: value ? (
195
- // Show actual input with cursor
196
- inputLines.slice(0, 5).map((line, i) => {
197
- const isCursorLine = i === Math.min(cursorRef.current, inputLines.length - 1);
198
- const cursorCol = isCursorLine
199
- ? cursorRef.current - inputLines.slice(0, i).join("\n").length - (i > 0 ? 1 : 0)
200
- : line.length;
201
- const cursorColClamped = Math.min(cursorCol, line.length);
202
- const before = line.slice(0, cursorColClamped);
203
- const at = line[cursorColClamped] || " ";
204
- const after = line.slice(cursorColClamped + 1);
205
- return (_jsxs(Text, { wrap: "truncate-end", children: [before, _jsx(Text, { inverse: true, children: at }), after] }, i));
206
- })) : (_jsx(Text, { color: AIAIAI_COLORS.dim, children: placeholder })) })] }) })] }));
65
+ const [cursor, setCursor] = useState(value.length);
66
+ const [history, setHistory] = useState([]);
67
+ const [historyIdx, setHistoryIdx] = useState(-1);
68
+ const [completions, setCompletions] = useState([]);
69
+ const [completionIdx, setCompletionIdx] = useState(-1);
70
+ const [showCompletions, setShowCompletions] = useState(false);
71
+ const valueRef = useRef(value);
72
+ const cursorRef = useRef(cursor);
73
+ valueRef.current = value;
74
+ cursorRef.current = cursor;
75
+
76
+ const insertAtCursor = useCallback((text) => {
77
+ const before = valueRef.current.slice(0, cursorRef.current);
78
+ const after = valueRef.current.slice(cursorRef.current);
79
+ const newVal = before + text + after;
80
+ onChange(newVal);
81
+ setCursor(cursorRef.current + text.length);
82
+ }, [onChange]);
83
+ const doSubmit = useCallback(() => {
84
+ const val = valueRef.current;
85
+ if (!val.trim() || disabled)
86
+ return;
87
+ setHistory(prev => [val, ...prev].slice(0, MAX_HISTORY));
88
+ setHistoryIdx(-1);
89
+ setShowCompletions(false);
90
+ onChange("");
91
+ setCursor(0);
92
+ onSubmit(val);
93
+ }, [disabled, onChange, onSubmit]);
94
+ useInput((input, key) => {
95
+
96
+ if (key.escape) {
97
+ if (disabled) {
98
+ onAbort();
99
+ return;
100
+ }
101
+ setShowCompletions(false);
102
+ return;
103
+ }
104
+ if (disabled)
105
+ return;
106
+
107
+ if (key.tab) {
108
+ const val = valueRef.current;
109
+ if (!showCompletions) {
110
+
111
+ if (val.startsWith("/") && val.length > 0) {
112
+ const comps = getCompletions(val);
113
+ if (comps.length === 1 && comps[0] !== val) {
114
+
115
+ onChange(comps[0] + " ");
116
+ setCursor(comps[0].length + 1);
117
+ return;
118
+ }
119
+ if (comps.length > 0) {
120
+ setCompletions(comps);
121
+ setCompletionIdx(0);
122
+ setShowCompletions(true);
123
+ return;
124
+ }
125
+ }
126
+ return;
127
+ }
128
+
129
+ if (completions.length > 0) {
130
+ const nextIdx = (completionIdx + 1) % completions.length;
131
+ setCompletionIdx(nextIdx);
132
+
133
+ const comp = completions[nextIdx];
134
+ onChange(comp + " ");
135
+ setCursor(comp.length + 1);
136
+ }
137
+ return;
138
+ }
139
+
140
+ if (showCompletions)
141
+ setShowCompletions(false);
142
+
143
+ if (key.return) {
144
+
145
+ if (input === "\r" && !key.shift) {
146
+ doSubmit();
147
+ return;
148
+ }
149
+
150
+ if (key.shift || input === "\u0003") {
151
+ insertAtCursor("\n");
152
+ return;
153
+ }
154
+ }
155
+
156
+ if (key.upArrow) {
157
+ if (history.length === 0)
158
+ return;
159
+ const newIdx = historyIdx < history.length - 1 ? historyIdx + 1 : historyIdx;
160
+ setHistoryIdx(newIdx);
161
+ onChange(history[newIdx]);
162
+ setCursor(history[newIdx].length);
163
+ return;
164
+ }
165
+ if (key.downArrow) {
166
+ if (historyIdx <= 0) {
167
+ setHistoryIdx(-1);
168
+ onChange("");
169
+ setCursor(0);
170
+ return;
171
+ }
172
+ const newIdx = historyIdx - 1;
173
+ setHistoryIdx(newIdx);
174
+ onChange(history[newIdx]);
175
+ setCursor(history[newIdx].length);
176
+ return;
177
+ }
178
+
179
+ if (key.leftArrow) {
180
+ setCursor(Math.max(0, cursorRef.current - 1));
181
+ return;
182
+ }
183
+ if (key.rightArrow) {
184
+ setCursor(Math.min(valueRef.current.length, cursorRef.current + 1));
185
+ return;
186
+ }
187
+
188
+ if (key.backspace || key.delete) {
189
+ if (cursorRef.current <= 0)
190
+ return;
191
+ const before = valueRef.current.slice(0, cursorRef.current - 1);
192
+ const after = valueRef.current.slice(cursorRef.current);
193
+ onChange(before + after);
194
+ setCursor(cursorRef.current - 1);
195
+ return;
196
+ }
197
+
198
+ if (input && input.length === 1 && input.charCodeAt(0) >= 32) {
199
+ insertAtCursor(input);
200
+ return;
201
+ }
202
+ });
203
+ const placeholder = disabled ? "thinking…" : "message or /command";
204
+ const displayValue = value || placeholder;
205
+ const inputLines = displayValue.split("\n");
206
+ const inputHeight = Math.min(inputLines.length, 5);
207
+ return (_jsxs(Box, { flexDirection: "column", children: [showCompletions && completions.length > 0 && (_jsxs(Box, { borderStyle: "single", borderColor: AIAIAI_COLORS.accent, paddingX: 1, flexDirection: "column", marginBottom: 0, children: [completions.slice(0, 8).map((c, i) => (_jsxs(Text, { color: i === completionIdx ? AIAIAI_COLORS.accent : AIAIAI_COLORS.muted, bold: i === completionIdx, children: [i === completionIdx ? "▸ " : " ", c] }, c))), completions.length > 8 && (_jsxs(Text, { color: AIAIAI_COLORS.dim, children: [" \u2026", completions.length - 8, " more"] }))] })), _jsx(Box, { borderStyle: "round", borderColor: disabled ? AIAIAI_COLORS.dim : AIAIAI_COLORS.accent, paddingX: 1, paddingY: inputHeight > 1 ? 0 : 0, flexDirection: "column", marginTop: 1, children: _jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: AIAIAI_COLORS.accent, bold: true, children: "\u203A " }), _jsx(Box, { flexDirection: "column", flexGrow: 1, children: value ? (
208
+
209
+ inputLines.slice(0, 5).map((line, i) => {
210
+ const isCursorLine = i === Math.min(cursorRef.current, inputLines.length - 1);
211
+ const cursorCol = isCursorLine
212
+ ? cursorRef.current - inputLines.slice(0, i).join("\n").length - (i > 0 ? 1 : 0)
213
+ : line.length;
214
+ const cursorColClamped = Math.min(cursorCol, line.length);
215
+ const before = line.slice(0, cursorColClamped);
216
+ const at = line[cursorColClamped] || " ";
217
+ const after = line.slice(cursorColClamped + 1);
218
+ return (_jsxs(Text, { wrap: "truncate-end", children: [before, _jsx(Text, { inverse: true, children: at }), after] }, i));
219
+ })) : (_jsx(Text, { color: AIAIAI_COLORS.dim, children: placeholder })) })] }) })] }));
207
220
  }
208
221
  export function REPL({ messages, streamingText, toolRunning, onSubmit, onAbort, disabled }) {
209
- const [input, setInput] = useState("");
210
- const { stdout } = useStdout();
211
- const termWidth = (stdout?.columns ?? 80) - 2;
212
- const handleSubmit = useCallback((val) => {
213
- onSubmit(val);
214
- }, [onSubmit]);
215
- const handleAbort = useCallback(() => {
216
- onAbort?.();
217
- }, [onAbort]);
218
- // Scrolling: show last N messages
219
- const visible = messages.slice(-MAX_VISIBLE);
220
- return (_jsxs(Box, { flexDirection: "column", width: "100%", children: [_jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [visible.map(m => _jsx(MessageLine, { msg: m }, m.id)), streamingText && (_jsxs(Box, { flexDirection: "row", gap: 1, marginTop: 1, children: [_jsx(Text, { color: AIAIAI_COLORS.muted, children: " " }), _jsx(Text, { color: AIAIAI_COLORS.header, bold: true, children: "\uD83E\uDD16 " }), _jsx(Text, { wrap: "wrap", children: streamingText })] })), toolRunning && (_jsx(Box, { flexDirection: "row", gap: 1, marginTop: 1, children: _jsxs(Text, { color: AIAIAI_COLORS.warn, children: ["\u2699 running ", toolRunning, "\u2026"] }) }))] }), _jsx(InputBox, { value: input, onChange: setInput, onSubmit: handleSubmit, disabled: !!disabled, onAbort: handleAbort })] }));
221
- }
222
- //# sourceMappingURL=REPL.js.map
222
+ const [input, setInput] = useState("");
223
+ const { stdout } = useStdout();
224
+ const termWidth = (stdout?.columns ?? 80) - 2;
225
+ const handleSubmit = useCallback((val) => {
226
+ onSubmit(val);
227
+ }, [onSubmit]);
228
+ const handleAbort = useCallback(() => {
229
+ onAbort?.();
230
+ }, [onAbort]);
231
+
232
+ const visible = messages.slice(-MAX_VISIBLE);
233
+ return (_jsxs(Box, { flexDirection: "column", width: "100%", children: [_jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [visible.map(m => _jsx(MessageLine, { msg: m }, m.id)), streamingText && (_jsxs(Box, { flexDirection: "row", gap: 1, marginTop: 1, children: [_jsx(Text, { color: AIAIAI_COLORS.muted, children: " " }), _jsx(Text, { color: AIAIAI_COLORS.header, bold: true, children: "\uD83E\uDD16 " }), _jsx(Text, { wrap: "wrap", children: streamingText })] })), toolRunning && (_jsx(Box, { flexDirection: "row", gap: 1, marginTop: 1, children: _jsxs(Text, { color: AIAIAI_COLORS.warn, children: ["\u2699 running ", toolRunning, "\u2026"] }) }))] }), _jsx(InputBox, { value: input, onChange: setInput, onSubmit: handleSubmit, disabled: !!disabled, onAbort: handleAbort })] }));
234
+ }
@@ -18,4 +18,3 @@ export declare class PriceHistory {
18
18
  push(price: number): void;
19
19
  getData(): number[];
20
20
  }
21
- //# sourceMappingURL=Sparkline.d.ts.map