@jellyos/agent 0.1.1

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 (59) hide show
  1. package/README.md +375 -0
  2. package/bin/jellyagent +31 -0
  3. package/dist/api/ExtensionAPI.d.ts +92 -0
  4. package/dist/api/ExtensionAPI.d.ts.map +1 -0
  5. package/dist/api/ExtensionAPI.js +15 -0
  6. package/dist/api/ExtensionAPI.js.map +1 -0
  7. package/dist/api/Registry.d.ts +54 -0
  8. package/dist/api/Registry.d.ts.map +1 -0
  9. package/dist/api/Registry.js +101 -0
  10. package/dist/api/Registry.js.map +1 -0
  11. package/dist/cli.d.ts +6 -0
  12. package/dist/cli.d.ts.map +1 -0
  13. package/dist/cli.js +134 -0
  14. package/dist/cli.js.map +1 -0
  15. package/dist/index.d.ts +18 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +24 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/loader.d.ts +23 -0
  20. package/dist/loader.d.ts.map +1 -0
  21. package/dist/loader.js +84 -0
  22. package/dist/loader.js.map +1 -0
  23. package/dist/runner/AgentRunner.d.ts +66 -0
  24. package/dist/runner/AgentRunner.d.ts.map +1 -0
  25. package/dist/runner/AgentRunner.js +179 -0
  26. package/dist/runner/AgentRunner.js.map +1 -0
  27. package/dist/runner/ModelClient.d.ts +77 -0
  28. package/dist/runner/ModelClient.d.ts.map +1 -0
  29. package/dist/runner/ModelClient.js +224 -0
  30. package/dist/runner/ModelClient.js.map +1 -0
  31. package/dist/runner/SwarmRouter.d.ts +58 -0
  32. package/dist/runner/SwarmRouter.d.ts.map +1 -0
  33. package/dist/runner/SwarmRouter.js +153 -0
  34. package/dist/runner/SwarmRouter.js.map +1 -0
  35. package/dist/runner/ToolDispatcher.d.ts +19 -0
  36. package/dist/runner/ToolDispatcher.d.ts.map +1 -0
  37. package/dist/runner/ToolDispatcher.js +64 -0
  38. package/dist/runner/ToolDispatcher.js.map +1 -0
  39. package/dist/session/SessionManager.d.ts +23 -0
  40. package/dist/session/SessionManager.d.ts.map +1 -0
  41. package/dist/session/SessionManager.js +50 -0
  42. package/dist/session/SessionManager.js.map +1 -0
  43. package/dist/tui/App.d.ts +18 -0
  44. package/dist/tui/App.d.ts.map +1 -0
  45. package/dist/tui/App.js +188 -0
  46. package/dist/tui/App.js.map +1 -0
  47. package/dist/tui/REPL.d.ts +22 -0
  48. package/dist/tui/REPL.d.ts.map +1 -0
  49. package/dist/tui/REPL.js +46 -0
  50. package/dist/tui/REPL.js.map +1 -0
  51. package/dist/tui/StatusBar.d.ts +16 -0
  52. package/dist/tui/StatusBar.d.ts.map +1 -0
  53. package/dist/tui/StatusBar.js +15 -0
  54. package/dist/tui/StatusBar.js.map +1 -0
  55. package/dist/tui/theme.d.ts +30 -0
  56. package/dist/tui/theme.d.ts.map +1 -0
  57. package/dist/tui/theme.js +41 -0
  58. package/dist/tui/theme.js.map +1 -0
  59. package/package.json +59 -0
@@ -0,0 +1,23 @@
1
+ /**
2
+ * SessionManager — manages conversation history, compaction, and persistence.
3
+ *
4
+ * History is kept in memory. If it exceeds MAX_TOKENS worth of rough char count,
5
+ * it compacts by summarizing the oldest messages (keeps system + last N turns).
6
+ */
7
+ import type { Message } from "../runner/ModelClient.js";
8
+ export declare class SessionManager {
9
+ private history;
10
+ private systemPrompt;
11
+ setSystemPrompt(prompt: string): void;
12
+ getSystemPrompt(): string;
13
+ addMessage(msg: Message): void;
14
+ addMessages(msgs: Message[]): void;
15
+ /** Returns messages ready to send to the model — system prompt prepended */
16
+ getMessages(): Message[];
17
+ /** Full raw history (no system) */
18
+ getHistory(): Message[];
19
+ clear(): void;
20
+ private buildSystemContent;
21
+ private maybeCompact;
22
+ }
23
+ //# sourceMappingURL=SessionManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SessionManager.d.ts","sourceRoot":"","sources":["../../src/session/SessionManager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAKxD,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,YAAY,CAAY;IAEhC,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAIrC,eAAe,IAAI,MAAM;IAIzB,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI;IAK9B,WAAW,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAKlC,4EAA4E;IAC5E,WAAW,IAAI,OAAO,EAAE;IAKxB,mCAAmC;IACnC,UAAU,IAAI,OAAO,EAAE;IAIvB,KAAK,IAAI,IAAI;IAIb,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,YAAY;CAUrB"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * SessionManager — manages conversation history, compaction, and persistence.
3
+ *
4
+ * History is kept in memory. If it exceeds MAX_TOKENS worth of rough char count,
5
+ * it compacts by summarizing the oldest messages (keeps system + last N turns).
6
+ */
7
+ const MAX_HISTORY_CHARS = 80_000; // ~20k tokens rough estimate
8
+ const KEEP_RECENT = 20; // always keep last N messages after compaction
9
+ export class SessionManager {
10
+ history = [];
11
+ systemPrompt = "";
12
+ setSystemPrompt(prompt) {
13
+ this.systemPrompt = prompt;
14
+ }
15
+ getSystemPrompt() {
16
+ return this.systemPrompt;
17
+ }
18
+ addMessage(msg) {
19
+ this.history.push(msg);
20
+ this.maybeCompact();
21
+ }
22
+ addMessages(msgs) {
23
+ for (const m of msgs)
24
+ this.history.push(m);
25
+ this.maybeCompact();
26
+ }
27
+ /** Returns messages ready to send to the model — system prompt prepended */
28
+ getMessages() {
29
+ const sys = { role: "system", content: this.buildSystemContent() };
30
+ return [sys, ...this.history];
31
+ }
32
+ /** Full raw history (no system) */
33
+ getHistory() {
34
+ return [...this.history];
35
+ }
36
+ clear() {
37
+ this.history = [];
38
+ }
39
+ buildSystemContent() {
40
+ return this.systemPrompt || "You are JellyOS, an AI trading agent.";
41
+ }
42
+ maybeCompact() {
43
+ const totalChars = this.history.reduce((n, m) => n + (typeof m.content === "string" ? m.content.length : 0), 0);
44
+ if (totalChars <= MAX_HISTORY_CHARS)
45
+ return;
46
+ // Keep the last KEEP_RECENT messages, drop the rest
47
+ this.history = this.history.slice(-KEEP_RECENT);
48
+ }
49
+ }
50
+ //# sourceMappingURL=SessionManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SessionManager.js","sourceRoot":"","sources":["../../src/session/SessionManager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,iBAAiB,GAAG,MAAM,CAAC,CAAG,6BAA6B;AACjE,MAAM,WAAW,GAAS,EAAE,CAAC,CAAQ,+CAA+C;AAEpF,MAAM,OAAO,cAAc;IACjB,OAAO,GAAc,EAAE,CAAC;IACxB,YAAY,GAAS,EAAE,CAAC;IAEhC,eAAe,CAAC,MAAc;QAC5B,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC;IAC7B,CAAC;IAED,eAAe;QACb,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED,UAAU,CAAC,GAAY;QACrB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACvB,IAAI,CAAC,YAAY,EAAE,CAAC;IACtB,CAAC;IAED,WAAW,CAAC,IAAe;QACzB,KAAK,MAAM,CAAC,IAAI,IAAI;YAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3C,IAAI,CAAC,YAAY,EAAE,CAAC;IACtB,CAAC;IAED,4EAA4E;IAC5E,WAAW;QACT,MAAM,GAAG,GAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,kBAAkB,EAAE,EAAE,CAAC;QAC5E,OAAO,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;IAED,mCAAmC;IACnC,UAAU;QACR,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;IAED,KAAK;QACH,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;IACpB,CAAC;IAEO,kBAAkB;QACxB,OAAO,IAAI,CAAC,YAAY,IAAI,uCAAuC,CAAC;IACtE,CAAC;IAEO,YAAY;QAClB,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CACpC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EACpE,CAAC,CACF,CAAC;QACF,IAAI,UAAU,IAAI,iBAAiB;YAAE,OAAO;QAE5C,oDAAoD;QACpD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,CAAC;IAClD,CAAC;CACF"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * App — root Ink component.
3
+ * Wires StatusBar + REPL + AgentRunner. Passes live setStatus/notify callbacks
4
+ * to the extension API so Pi compat calls (ui.setStatus, ui.notify) update the TUI.
5
+ */
6
+ import { Registry } from "../api/Registry.js";
7
+ export interface AppProps {
8
+ registry: Registry;
9
+ systemPrompt?: string;
10
+ effectLevel?: string;
11
+ chain?: string;
12
+ /** Notifier callback injected before mount so it's ready when session_start fires */
13
+ onNotifyReady?: (fn: (msg: string) => void) => void;
14
+ /** Status updater callback injected before mount */
15
+ onStatusReady?: (fn: (key: string, val: string) => void) => void;
16
+ }
17
+ export declare function App({ registry, systemPrompt, effectLevel: initialEffect, chain: initialChain, onNotifyReady, onStatusReady, }: AppProps): import("react/jsx-runtime").JSX.Element;
18
+ //# sourceMappingURL=App.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/tui/App.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,OAAO,EAAE,QAAQ,EAAE,MAAU,oBAAoB,CAAC;AAMlD,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAK,QAAQ,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAQ,MAAM,CAAC;IACrB,qFAAqF;IACrF,aAAa,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,KAAK,IAAI,CAAC;IACpD,oDAAoD;IACpD,aAAa,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,KAAK,IAAI,CAAC;CAClE;AAKD,wBAAgB,GAAG,CAAC,EAClB,QAAQ,EACR,YAAY,EACZ,WAAW,EAAE,aAAwB,EACrC,KAAK,EAAQ,YAA0B,EACvC,aAAa,EACb,aAAa,GACd,EAAE,QAAQ,2CAwMV"}
@@ -0,0 +1,188 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * App — root Ink component.
4
+ * Wires StatusBar + REPL + AgentRunner. Passes live setStatus/notify callbacks
5
+ * to the extension API so Pi compat calls (ui.setStatus, ui.notify) update the TUI.
6
+ */
7
+ import { useState, useCallback, useEffect, useRef } from "react";
8
+ import { Box, useApp, useInput } from "ink";
9
+ import { StatusBar } from "./StatusBar.js";
10
+ import { REPL } from "./REPL.js";
11
+ import { makeTheme, T } from "./theme.js";
12
+ import { AgentRunner } from "../runner/AgentRunner.js";
13
+ import { SessionManager } from "../session/SessionManager.js";
14
+ import { resolveModelConfig } from "../runner/ModelClient.js";
15
+ let _msgIdCounter = 0;
16
+ function nextId() { return String(++_msgIdCounter); }
17
+ export function App({ registry, systemPrompt, effectLevel: initialEffect = "normal", chain: initialChain = "ethereum", onNotifyReady, onStatusReady, }) {
18
+ const { exit } = useApp();
19
+ const [messages, setMessages] = useState([]);
20
+ const [streaming, setStreaming] = useState("");
21
+ const [toolRunning, setToolRunning] = useState(null);
22
+ const [disabled, setDisabled] = useState(false);
23
+ const [vaultLocked, setVaultLocked] = useState(true);
24
+ const [effectLevel, setEffectLevel] = useState(initialEffect);
25
+ const [chain, setChain] = useState(initialChain);
26
+ const [statusBadges, setStatusBadges] = useState({});
27
+ const runnerRef = useRef(null);
28
+ const sessionRef = useRef(null);
29
+ const sessionCtxRef = useRef(null);
30
+ const theme = makeTheme();
31
+ let modelName = "no-model";
32
+ try {
33
+ modelName = resolveModelConfig().model;
34
+ }
35
+ catch { /* shown via banner */ }
36
+ // ── Push helpers ─────────────────────────────────────────────────────────
37
+ const push = useCallback((msg) => {
38
+ setMessages(prev => [...prev, { ...msg, id: nextId(), ts: Date.now() }]);
39
+ }, []);
40
+ const notify = useCallback((content) => {
41
+ push({ role: "notify", content });
42
+ }, [push]);
43
+ const setStatus = useCallback((key, value) => {
44
+ setStatusBadges(prev => ({ ...prev, [key]: value }));
45
+ // Mirror vault lock state when extension calls setStatus("vault", ...)
46
+ if (key === "vault") {
47
+ setVaultLocked(!value.includes("🔓") && !value.includes("unlocked"));
48
+ }
49
+ if (key === "chain" || key === "active_chain")
50
+ setChain(value);
51
+ if (key === "effect_level")
52
+ setEffectLevel(value);
53
+ }, []);
54
+ // ── Build UIContext that extension commands can call ──────────────────────
55
+ const uiCtx = {
56
+ notify,
57
+ setStatus,
58
+ setTheme(_name) { },
59
+ setHeader(_factory) { },
60
+ theme,
61
+ };
62
+ // ── Wire live callbacks BEFORE session_start fires ────────────────────────
63
+ useEffect(() => {
64
+ onNotifyReady?.(notify);
65
+ onStatusReady?.(setStatus);
66
+ }, [notify, setStatus, onNotifyReady, onStatusReady]);
67
+ // ── Boot: fire session_start ──────────────────────────────────────────────
68
+ useEffect(() => {
69
+ const session = new SessionManager();
70
+ session.setSystemPrompt(registry.getSystemPrompt() || systemPrompt ||
71
+ "You are JellyOS, an autonomous AI trading agent.");
72
+ sessionRef.current = session;
73
+ const sessionCtx = {
74
+ ui: uiCtx,
75
+ hasUI: true,
76
+ config: {
77
+ OPENROUTER_API_KEY: process.env.OPENROUTER_API_KEY,
78
+ ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY,
79
+ ALCHEMY_KEY: process.env.ALCHEMY_KEY,
80
+ DEFAULT_MODEL: process.env.DEFAULT_MODEL,
81
+ },
82
+ };
83
+ sessionCtxRef.current = sessionCtx;
84
+ registry.fireHook("session_start", sessionCtx).then(() => {
85
+ push({ role: "system", content: T.muted("Session started. Type a message or /help.") });
86
+ });
87
+ const runner = new AgentRunner(registry, session, (event) => {
88
+ if (event.type === "text_delta") {
89
+ setStreaming(prev => prev + event.text);
90
+ }
91
+ else if (event.type === "tool_start") {
92
+ setToolRunning(event.name);
93
+ }
94
+ else if (event.type === "tool_done") {
95
+ setToolRunning(null);
96
+ push({
97
+ role: "tool",
98
+ content: event.result,
99
+ toolName: event.name,
100
+ isError: event.isError,
101
+ });
102
+ }
103
+ else if (event.type === "turn_done") {
104
+ setDisabled(false);
105
+ setToolRunning(null);
106
+ setStreaming(prev => {
107
+ if (prev.trim())
108
+ push({ role: "assistant", content: prev });
109
+ return "";
110
+ });
111
+ }
112
+ else if (event.type === "error") {
113
+ setDisabled(false);
114
+ setToolRunning(null);
115
+ setStreaming("");
116
+ notify(T.error(`Error: ${event.message}`));
117
+ }
118
+ }, sessionCtx);
119
+ runnerRef.current = runner;
120
+ return () => {
121
+ if (sessionCtxRef.current) {
122
+ registry.fireHook("session_end", sessionCtxRef.current).catch(() => { });
123
+ }
124
+ };
125
+ // eslint-disable-next-line react-hooks/exhaustive-deps
126
+ }, []);
127
+ // ── Live /effect → runner reconfiguration ────────────────────────────────
128
+ useEffect(() => {
129
+ runnerRef.current?.setEffectLevel(effectLevel);
130
+ }, [effectLevel]);
131
+ // ── Ctrl-C ────────────────────────────────────────────────────────────────
132
+ useInput((_input, key) => {
133
+ if (key.ctrl && _input === "c") {
134
+ push({ role: "system", content: T.muted("Goodbye 🪼") });
135
+ setTimeout(exit, 200);
136
+ }
137
+ });
138
+ // ── Input handler ─────────────────────────────────────────────────────────
139
+ const handleSubmit = useCallback(async (raw) => {
140
+ const input = raw.trim();
141
+ if (!input)
142
+ return;
143
+ if (input.startsWith("/")) {
144
+ const [cmd, ...rest] = input.slice(1).split(" ");
145
+ const args = rest.join(" ");
146
+ if (cmd === "exit" || cmd === "quit") {
147
+ push({ role: "system", content: T.muted("Goodbye 🪼") });
148
+ setTimeout(exit, 200);
149
+ return;
150
+ }
151
+ if (cmd === "help") {
152
+ const lines = registry.listCommands().map(([n, d]) => T.accent(`/${n}`.padEnd(16)) + " " + d.description);
153
+ notify("Available commands:\n\n" + lines.join("\n"));
154
+ return;
155
+ }
156
+ const def = registry.getCommand(cmd);
157
+ if (!def) {
158
+ notify(T.error(`Unknown command: /${cmd}\nType /help to list all commands.`));
159
+ return;
160
+ }
161
+ try {
162
+ await def.handler(args, { ui: uiCtx });
163
+ }
164
+ catch (e) {
165
+ notify(T.error(`Command error: ${e.message}`));
166
+ }
167
+ return;
168
+ }
169
+ if (!runnerRef.current) {
170
+ notify(T.error("Agent not ready"));
171
+ return;
172
+ }
173
+ push({ role: "user", content: input });
174
+ setDisabled(true);
175
+ setStreaming("");
176
+ try {
177
+ await runnerRef.current.run(input);
178
+ }
179
+ catch (e) {
180
+ setDisabled(false);
181
+ notify(T.error(`Runner error: ${e.message}`));
182
+ }
183
+ }, [registry, exit, push, notify, uiCtx]);
184
+ // Build status line from all active badges
185
+ const statusLine = Object.values(statusBadges).join(" ") || null;
186
+ return (_jsxs(Box, { flexDirection: "column", height: "100%", children: [_jsx(StatusBar, { model: modelName, chain: chain, vaultLocked: vaultLocked, effectLevel: effectLevel, toolRunning: toolRunning, connected: true, statusLine: statusLine }), _jsx(REPL, { messages: messages, streamingText: streaming, toolRunning: toolRunning, onSubmit: handleSubmit, disabled: disabled })] }));
187
+ }
188
+ //# sourceMappingURL=App.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"App.js","sourceRoot":"","sources":["../../src/tui/App.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * REPL — scrolling message history + bottom input box.
3
+ * Renders assistant text, tool calls, tool results, and user messages.
4
+ */
5
+ export type MessageRole = "user" | "assistant" | "tool" | "system" | "notify";
6
+ export interface ChatMessage {
7
+ id: string;
8
+ role: MessageRole;
9
+ content: string;
10
+ toolName?: string;
11
+ isError?: boolean;
12
+ ts: number;
13
+ }
14
+ export interface REPLProps {
15
+ messages: ChatMessage[];
16
+ streamingText: string;
17
+ toolRunning: string | null;
18
+ onSubmit(input: string): void;
19
+ disabled: boolean;
20
+ }
21
+ export declare function REPL({ messages, streamingText, toolRunning, onSubmit, disabled }: REPLProps): import("react/jsx-runtime").JSX.Element;
22
+ //# sourceMappingURL=REPL.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"REPL.d.ts","sourceRoot":"","sources":["../../src/tui/REPL.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE9E,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAO,MAAM,CAAC;IAChB,IAAI,EAAK,WAAW,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAG,OAAO,CAAC;IACnB,EAAE,EAAO,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAK,WAAW,EAAE,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAI,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,EAAK,OAAO,CAAC;CACtB;AA+DD,wBAAgB,IAAI,CAAC,EAAE,QAAQ,EAAE,aAAa,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,SAAS,2CA4D3F"}
@@ -0,0 +1,46 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * REPL — scrolling message history + bottom input box.
4
+ * Renders assistant text, tool calls, tool results, and user messages.
5
+ */
6
+ import { useState, useCallback } from "react";
7
+ import { Box, Text, useStdout } from "ink";
8
+ import TextInput from "ink-text-input";
9
+ import { JELLY_COLORS } from "./theme.js";
10
+ const MAX_VISIBLE = 40;
11
+ function MessageLine({ msg }) {
12
+ const time = new Date(msg.ts).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
13
+ if (msg.role === "user") {
14
+ return (_jsxs(Box, { flexDirection: "row", gap: 1, marginTop: 1, children: [_jsx(Text, { color: JELLY_COLORS.muted, children: time }), _jsx(Text, { color: JELLY_COLORS.accent, bold: true, children: "you " }), _jsx(Text, { wrap: "wrap", children: msg.content })] }));
15
+ }
16
+ if (msg.role === "assistant") {
17
+ return (_jsxs(Box, { flexDirection: "row", gap: 1, marginTop: 1, children: [_jsx(Text, { color: JELLY_COLORS.muted, children: time }), _jsx(Text, { color: JELLY_COLORS.header, bold: true, children: "\uD83E\uDEBC " }), _jsx(Text, { wrap: "wrap", children: msg.content })] }));
18
+ }
19
+ if (msg.role === "tool") {
20
+ const icon = msg.isError ? "✗" : "✓";
21
+ const col = msg.isError ? JELLY_COLORS.error : JELLY_COLORS.success;
22
+ return (_jsxs(Box, { flexDirection: "row", gap: 1, marginY: 0, children: [_jsx(Text, { color: JELLY_COLORS.muted, children: time }), _jsxs(Text, { color: col, children: [icon, " ", msg.toolName ?? "tool"] }), msg.content.length < 120
23
+ ? _jsxs(Text, { color: JELLY_COLORS.muted, wrap: "wrap", children: [" ", msg.content] })
24
+ : _jsxs(Text, { color: JELLY_COLORS.muted, children: [" (", msg.content.length, " chars)"] })] }));
25
+ }
26
+ if (msg.role === "notify") {
27
+ return (_jsx(Box, { borderStyle: "round", borderColor: JELLY_COLORS.accent, marginY: 1, paddingX: 1, children: _jsx(Text, { wrap: "wrap", children: msg.content }) }));
28
+ }
29
+ // system messages — dimmed
30
+ return (_jsx(Box, { flexDirection: "row", gap: 1, children: _jsx(Text, { color: JELLY_COLORS.dim, wrap: "wrap", children: msg.content }) }));
31
+ }
32
+ export function REPL({ messages, streamingText, toolRunning, onSubmit, disabled }) {
33
+ const [input, setInput] = useState("");
34
+ const { stdout } = useStdout();
35
+ const termWidth = stdout?.columns ?? 80;
36
+ const handleSubmit = useCallback((val) => {
37
+ const trimmed = val.trim();
38
+ if (!trimmed || disabled)
39
+ return;
40
+ setInput("");
41
+ onSubmit(trimmed);
42
+ }, [onSubmit, disabled]);
43
+ const visible = messages.slice(-MAX_VISIBLE);
44
+ return (_jsxs(Box, { flexDirection: "column", width: termWidth, 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: JELLY_COLORS.muted, children: " " }), _jsx(Text, { color: JELLY_COLORS.header, bold: true, children: "\uD83E\uDEBC " }), _jsx(Text, { wrap: "wrap", children: streamingText })] })), toolRunning && (_jsx(Box, { flexDirection: "row", gap: 1, marginTop: 1, children: _jsxs(Text, { color: JELLY_COLORS.warn, children: ["\u2699 running ", toolRunning, "\u2026"] }) }))] }), _jsxs(Box, { borderStyle: "round", borderColor: disabled ? JELLY_COLORS.dim : JELLY_COLORS.accent, paddingX: 1, marginTop: 1, children: [_jsx(Text, { color: JELLY_COLORS.accent, children: "\u203A " }), _jsx(TextInput, { value: input, onChange: setInput, onSubmit: handleSubmit, placeholder: disabled ? "thinking…" : "message or /command" })] }), _jsx(Box, { paddingX: 2, children: _jsx(Text, { color: JELLY_COLORS.dim, children: "/help \u00B7 /status \u00B7 /vault \u00B7 /wallets \u00B7 /panic \u00B7 Tab to complete \u00B7 Ctrl-C to exit" }) })] }));
45
+ }
46
+ //# sourceMappingURL=REPL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"REPL.js","sourceRoot":"","sources":["../../src/tui/REPL.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * StatusBar — single line at the top of the TUI showing live agent state.
3
+ * Also displays status badges set by the extension via ui.setStatus().
4
+ */
5
+ export interface StatusBarProps {
6
+ model: string;
7
+ chain: string;
8
+ vaultLocked: boolean;
9
+ effectLevel: string;
10
+ toolRunning: string | null;
11
+ connected: boolean;
12
+ /** Extension-set status badges (joined with spaces) */
13
+ statusLine?: string | null;
14
+ }
15
+ export declare function StatusBar({ model, chain, vaultLocked, effectLevel, toolRunning, connected, statusLine, }: StatusBarProps): import("react/jsx-runtime").JSX.Element;
16
+ //# sourceMappingURL=StatusBar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StatusBar.d.ts","sourceRoot":"","sources":["../../src/tui/StatusBar.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAS,MAAM,CAAC;IACrB,KAAK,EAAS,MAAM,CAAC;IACrB,WAAW,EAAG,OAAO,CAAC;IACtB,WAAW,EAAG,MAAM,CAAC;IACrB,WAAW,EAAG,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAK,OAAO,CAAC;IACtB,uDAAuD;IACvD,UAAU,CAAC,EAAG,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,wBAAgB,SAAS,CAAC,EACxB,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,GAC3E,EAAE,cAAc,2CAsChB"}
@@ -0,0 +1,15 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ import { JELLY_COLORS } from "./theme.js";
4
+ export function StatusBar({ model, chain, vaultLocked, effectLevel, toolRunning, connected, statusLine, }) {
5
+ const vaultIcon = vaultLocked ? "🔒" : "🔓";
6
+ const chainShort = chain.slice(0, 8);
7
+ const modelShort = model.split("/").pop()?.slice(0, 18) ?? model.slice(0, 18);
8
+ const effectIcon = { eco: "🌿", normal: "⚡", turbo: "🚀", max: "🌊" }[effectLevel] ?? "⚡";
9
+ return (_jsxs(Box, { borderStyle: "single", borderColor: JELLY_COLORS.dim, paddingX: 1, flexDirection: "row", justifyContent: "space-between", children: [_jsxs(Box, { gap: 2, children: [_jsx(Text, { color: JELLY_COLORS.accent, bold: true, children: "\uD83E\uDEBC JellyOS" }), _jsx(Text, { color: JELLY_COLORS.muted, children: modelShort })] }), _jsx(Box, { children: toolRunning
10
+ ? _jsxs(Text, { color: JELLY_COLORS.warn, children: ["\u2699 ", toolRunning] })
11
+ : statusLine
12
+ ? _jsx(Text, { color: JELLY_COLORS.success, children: statusLine })
13
+ : _jsx(Text, { color: JELLY_COLORS.muted, children: connected ? "ready" : "connecting…" }) }), _jsxs(Box, { gap: 2, children: [_jsx(Text, { color: JELLY_COLORS.muted, children: chainShort }), _jsx(Text, { children: vaultIcon }), _jsxs(Text, { color: JELLY_COLORS.header, children: [effectIcon, " ", effectLevel] })] })] }));
14
+ }
15
+ //# sourceMappingURL=StatusBar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StatusBar.js","sourceRoot":"","sources":["../../src/tui/StatusBar.tsx"],"names":[],"mappings":";AAMA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAa1C,MAAM,UAAU,SAAS,CAAC,EACxB,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,GAC3D;IACf,MAAM,SAAS,GAAI,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IAC7C,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACrC,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC9E,MAAM,UAAU,GAAI,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAA6B,CAAC,WAAW,CAAC,IAAI,GAAG,CAAC;IAEtH,OAAO,CACL,MAAC,GAAG,IACF,WAAW,EAAC,QAAQ,EACpB,WAAW,EAAE,YAAY,CAAC,GAAG,EAC7B,QAAQ,EAAE,CAAC,EACX,aAAa,EAAC,KAAK,EACnB,cAAc,EAAC,eAAe,aAG9B,MAAC,GAAG,IAAC,GAAG,EAAE,CAAC,aACT,KAAC,IAAI,IAAC,KAAK,EAAE,YAAY,CAAC,MAAM,EAAE,IAAI,2CAAkB,EACxD,KAAC,IAAI,IAAC,KAAK,EAAE,YAAY,CAAC,KAAK,YAAG,UAAU,GAAQ,IAChD,EAGN,KAAC,GAAG,cACD,WAAW;oBACV,CAAC,CAAC,MAAC,IAAI,IAAC,KAAK,EAAE,YAAY,CAAC,IAAI,wBAAK,WAAW,IAAQ;oBACxD,CAAC,CAAC,UAAU;wBACV,CAAC,CAAC,KAAC,IAAI,IAAC,KAAK,EAAE,YAAY,CAAC,OAAO,YAAG,UAAU,GAAQ;wBACxD,CAAC,CAAC,KAAC,IAAI,IAAC,KAAK,EAAE,YAAY,CAAC,KAAK,YAAG,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,GAAQ,GAE/E,EAGN,MAAC,GAAG,IAAC,GAAG,EAAE,CAAC,aACT,KAAC,IAAI,IAAC,KAAK,EAAE,YAAY,CAAC,KAAK,YAAG,UAAU,GAAQ,EACpD,KAAC,IAAI,cAAE,SAAS,GAAQ,EACxB,MAAC,IAAI,IAAC,KAAK,EAAE,YAAY,CAAC,MAAM,aAAG,UAAU,OAAG,WAAW,IAAQ,IAC/D,IACF,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * JellyOS colour theme — maps semantic names to chalk/ANSI colours.
3
+ * Exported as a ThemeContext-compatible object so it can be passed into
4
+ * extension command handlers via ctx.ui.theme.
5
+ */
6
+ import type { ThemeContext } from "../api/ExtensionAPI.js";
7
+ export declare const JELLY_COLORS: {
8
+ readonly accent: "#00e5ff";
9
+ readonly success: "#69ff94";
10
+ readonly error: "#ff5370";
11
+ readonly warn: "#ffcb6b";
12
+ readonly muted: "#546e7a";
13
+ readonly header: "#c792ea";
14
+ readonly dim: "#37474f";
15
+ };
16
+ export type JellyColor = keyof typeof JELLY_COLORS;
17
+ export declare function makeTheme(): ThemeContext;
18
+ /** Convenience — themed prefix for agent output lines */
19
+ export declare const theme: ThemeContext;
20
+ export declare const T: {
21
+ accent: (s: string) => string;
22
+ success: (s: string) => string;
23
+ error: (s: string) => string;
24
+ warn: (s: string) => string;
25
+ muted: (s: string) => string;
26
+ header: (s: string) => string;
27
+ dim: (s: string) => string;
28
+ bold: (s: string) => string;
29
+ };
30
+ //# sourceMappingURL=theme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../src/tui/theme.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE3D,eAAO,MAAM,YAAY;;;;;;;;CAQf,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,MAAM,OAAO,YAAY,CAAC;AAEnD,wBAAgB,SAAS,IAAI,YAAY,CAWxC;AAED,yDAAyD;AACzD,eAAO,MAAM,KAAK,cAAc,CAAC;AAEjC,eAAO,MAAM,CAAC;gBACC,MAAM;iBACN,MAAM;eACN,MAAM;cACN,MAAM;eACN,MAAM;gBACN,MAAM;aACN,MAAM;cACN,MAAM;CACpB,CAAC"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * JellyOS colour theme — maps semantic names to chalk/ANSI colours.
3
+ * Exported as a ThemeContext-compatible object so it can be passed into
4
+ * extension command handlers via ctx.ui.theme.
5
+ */
6
+ import chalk from "chalk";
7
+ export const JELLY_COLORS = {
8
+ accent: "#00e5ff", // cyan-aqua — jelly signature
9
+ success: "#69ff94", // soft green
10
+ error: "#ff5370", // coral red
11
+ warn: "#ffcb6b", // amber
12
+ muted: "#546e7a", // slate grey
13
+ header: "#c792ea", // soft purple
14
+ dim: "#37474f", // dark slate
15
+ };
16
+ export function makeTheme() {
17
+ return {
18
+ fg(color, text) {
19
+ const hex = JELLY_COLORS[color] ?? color;
20
+ try {
21
+ return chalk.hex(hex)(text);
22
+ }
23
+ catch {
24
+ return text;
25
+ }
26
+ },
27
+ };
28
+ }
29
+ /** Convenience — themed prefix for agent output lines */
30
+ export const theme = makeTheme();
31
+ export const T = {
32
+ accent: (s) => chalk.hex(JELLY_COLORS.accent)(s),
33
+ success: (s) => chalk.hex(JELLY_COLORS.success)(s),
34
+ error: (s) => chalk.hex(JELLY_COLORS.error)(s),
35
+ warn: (s) => chalk.hex(JELLY_COLORS.warn)(s),
36
+ muted: (s) => chalk.hex(JELLY_COLORS.muted)(s),
37
+ header: (s) => chalk.hex(JELLY_COLORS.header)(s),
38
+ dim: (s) => chalk.hex(JELLY_COLORS.dim)(s),
39
+ bold: (s) => chalk.bold(s),
40
+ };
41
+ //# sourceMappingURL=theme.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.js","sourceRoot":"","sources":["../../src/tui/theme.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,MAAM,EAAG,SAAS,EAAI,8BAA8B;IACpD,OAAO,EAAE,SAAS,EAAI,aAAa;IACnC,KAAK,EAAI,SAAS,EAAI,YAAY;IAClC,IAAI,EAAK,SAAS,EAAI,QAAQ;IAC9B,KAAK,EAAI,SAAS,EAAI,aAAa;IACnC,MAAM,EAAG,SAAS,EAAI,cAAc;IACpC,GAAG,EAAM,SAAS,EAAI,aAAa;CAC3B,CAAC;AAIX,MAAM,UAAU,SAAS;IACvB,OAAO;QACL,EAAE,CAAC,KAAa,EAAE,IAAY;YAC5B,MAAM,GAAG,GAAG,YAAY,CAAC,KAAmB,CAAC,IAAI,KAAK,CAAC;YACvD,IAAI,CAAC;gBACH,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;YAC9B,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED,yDAAyD;AACzD,MAAM,CAAC,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;AAEjC,MAAM,CAAC,MAAM,CAAC,GAAG;IACf,MAAM,EAAG,CAAC,CAAS,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACzD,OAAO,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC1D,KAAK,EAAI,CAAC,CAAS,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACxD,IAAI,EAAK,CAAC,CAAS,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACvD,KAAK,EAAI,CAAC,CAAS,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACxD,MAAM,EAAG,CAAC,CAAS,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACzD,GAAG,EAAM,CAAC,CAAS,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACtD,IAAI,EAAK,CAAC,CAAS,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;CACtC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "@jellyos/agent",
3
+ "version": "0.1.1",
4
+ "description": "JellyOS — standalone AI trading agent. Runs locally, no server required.",
5
+ "author": "JellyChain",
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "main": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "import": "./dist/index.js",
13
+ "types": "./dist/index.d.ts"
14
+ }
15
+ },
16
+ "bin": {
17
+ "jellyos": "./bin/jellyagent",
18
+ "jellyagent": "./bin/jellyagent"
19
+ },
20
+ "scripts": {
21
+ "build": "npx tsc",
22
+ "build:watch": "tsc --watch",
23
+ "dev": "tsx src/cli.ts",
24
+ "start": "node dist/cli.js",
25
+ "type-check": "tsc --noEmit",
26
+ "prepublishOnly": "npm run build"
27
+ },
28
+ "dependencies": {
29
+ "@sinclair/typebox": "^0.32.0",
30
+ "chalk": "^5.3.0",
31
+ "dotenv": "^16.4.5",
32
+ "ink": "^5.0.1",
33
+ "ink-text-input": "^6.0.0",
34
+ "react": "^18.3.1",
35
+ "tsx": "^4.15.0"
36
+ },
37
+ "devDependencies": {
38
+ "@types/node": "^20.19.41",
39
+ "@types/react": "^18.3.29",
40
+ "typescript": "^5.9.3"
41
+ },
42
+ "engines": {
43
+ "node": ">=20.0.0"
44
+ },
45
+ "keywords": [
46
+ "ai",
47
+ "agent",
48
+ "trading",
49
+ "blockchain",
50
+ "terminal",
51
+ "cli",
52
+ "jellyos"
53
+ ],
54
+ "files": [
55
+ "dist",
56
+ "bin",
57
+ "README.md"
58
+ ]
59
+ }