@jellyos/agent 0.1.8 → 0.2.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/bin/jellyos-mcp +0 -0
- package/dist/cli.js +11 -1
- package/dist/loader.js +21 -1
- package/dist/session/MemoryStore.js +4 -3
- package/dist/tui/App.js +8 -10
- package/dist/util/safeLog.d.ts +3 -0
- package/dist/util/safeLog.js +21 -0
- package/package.json +4 -1
package/bin/jellyos-mcp
CHANGED
|
File without changes
|
package/dist/cli.js
CHANGED
|
@@ -12,6 +12,7 @@ import { Registry } from "./api/Registry.js";
|
|
|
12
12
|
import { loadExtension } from "./loader.js";
|
|
13
13
|
import { App } from "./tui/App.js";
|
|
14
14
|
import { T } from "./tui/theme.js";
|
|
15
|
+
import { wireNotify, safeLog } from "./util/safeLog.js";
|
|
15
16
|
import { modelRegistry } from "./models/ModelRegistry.js";
|
|
16
17
|
import { CostTracker } from "./models/CostTracker.js";
|
|
17
18
|
import { AgentRunner } from "./runner/AgentRunner.js";
|
|
@@ -212,10 +213,19 @@ else {
|
|
|
212
213
|
chain,
|
|
213
214
|
modelReg: modelRegistry,
|
|
214
215
|
costTracker,
|
|
215
|
-
onNotifyReady: (fn) => { _notifyFn = fn; },
|
|
216
|
+
onNotifyReady: (fn) => { _notifyFn = fn; wireNotify(fn); },
|
|
216
217
|
onStatusReady: (fn) => { _setStatusFn = fn; },
|
|
217
218
|
onModelSelectorReady: (fn) => { _showModelSelectorFn = fn; },
|
|
218
219
|
}), { exitOnCtrlC: false });
|
|
220
|
+
// Ink owns the terminal from this point on. Any console.log/error/warn
|
|
221
|
+
// writes raw bytes to stdout, bypassing Ink's rendering buffer. Ink's
|
|
222
|
+
// cursor-up calculation becomes wrong → stacked border lines.
|
|
223
|
+
// NOTE: process.stdout.write is intentionally NOT patched — Ink uses it
|
|
224
|
+
// for every render frame; intercepting it globally would break Ink output.
|
|
225
|
+
process.prependListener("SIGWINCH", () => { process.stdout.write("\x1B[2J\x1B[H"); });
|
|
226
|
+
console.log = safeLog;
|
|
227
|
+
console.error = safeLog;
|
|
228
|
+
console.warn = safeLog;
|
|
219
229
|
})();
|
|
220
230
|
} // end headless else
|
|
221
231
|
//# sourceMappingURL=cli.js.map
|
package/dist/loader.js
CHANGED
|
@@ -80,6 +80,26 @@ export async function loadExtension(extensionPath, registry, opts = {}) {
|
|
|
80
80
|
if (typeof fn !== "function") {
|
|
81
81
|
throw new Error(`Extension must export a default function. Got: ${typeof fn} from ${abs}`);
|
|
82
82
|
}
|
|
83
|
-
|
|
83
|
+
// Intercept console.log/error/warn during extension load so that any
|
|
84
|
+
// stray prints in the extension (e.g. loadSkills logging) are routed
|
|
85
|
+
// through ui.notify instead of raw stdout writes that corrupt the TUI.
|
|
86
|
+
const _origLog = console.log;
|
|
87
|
+
const _origError = console.error;
|
|
88
|
+
const _origWarn = console.warn;
|
|
89
|
+
const _extLog = (...args) => {
|
|
90
|
+
const msg = args.map(a => (typeof a === "string" ? a : String(a))).join(" ");
|
|
91
|
+
ui.notify(msg);
|
|
92
|
+
};
|
|
93
|
+
console.log = _extLog;
|
|
94
|
+
console.error = _extLog;
|
|
95
|
+
console.warn = _extLog;
|
|
96
|
+
try {
|
|
97
|
+
await fn(api);
|
|
98
|
+
}
|
|
99
|
+
finally {
|
|
100
|
+
console.log = _origLog;
|
|
101
|
+
console.error = _origError;
|
|
102
|
+
console.warn = _origWarn;
|
|
103
|
+
}
|
|
84
104
|
}
|
|
85
105
|
//# sourceMappingURL=loader.js.map
|
|
@@ -12,6 +12,8 @@ import { mkdirSync } from "node:fs";
|
|
|
12
12
|
import { join } from "node:path";
|
|
13
13
|
import { homedir } from "node:os";
|
|
14
14
|
const JELLY_HOME = process.env.JELLYOS_HOME ?? join(homedir(), ".jelly");
|
|
15
|
+
import { createRequire } from "module";
|
|
16
|
+
const cjsRequire = createRequire(import.meta.url);
|
|
15
17
|
export class MemoryStore {
|
|
16
18
|
db = null;
|
|
17
19
|
available = false;
|
|
@@ -22,8 +24,7 @@ export class MemoryStore {
|
|
|
22
24
|
try {
|
|
23
25
|
// node:sqlite is available in Node 22+ (experimental) and Node 24 (stable)
|
|
24
26
|
// We import it dynamically to avoid a hard crash on older Node versions
|
|
25
|
-
|
|
26
|
-
const sqlite = require("node:sqlite");
|
|
27
|
+
const sqlite = cjsRequire("node:sqlite");
|
|
27
28
|
mkdirSync(JELLY_HOME, { recursive: true });
|
|
28
29
|
this.db = new sqlite.DatabaseSync(join(JELLY_HOME, "memory.db"));
|
|
29
30
|
this.db.exec(`
|
|
@@ -33,7 +34,7 @@ export class MemoryStore {
|
|
|
33
34
|
role TEXT NOT NULL,
|
|
34
35
|
content TEXT NOT NULL,
|
|
35
36
|
tokens INTEGER DEFAULT 0,
|
|
36
|
-
|
|
37
|
+
ts INTEGER NOT NULL,
|
|
37
38
|
tags TEXT DEFAULT '[]'
|
|
38
39
|
);
|
|
39
40
|
CREATE INDEX IF NOT EXISTS idx_session ON messages(sessionId);
|
package/dist/tui/App.js
CHANGED
|
@@ -6,6 +6,10 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
6
6
|
*/
|
|
7
7
|
import { useState, useCallback, useEffect, useRef, useMemo } from "react";
|
|
8
8
|
import { Box, Text, useApp, useInput } from "ink";
|
|
9
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
|
10
|
+
import { join } from "node:path";
|
|
11
|
+
import { homedir } from "node:os";
|
|
12
|
+
import { Type } from "@sinclair/typebox";
|
|
9
13
|
import { StatusBar } from "./StatusBar.js";
|
|
10
14
|
import { REPL } from "./REPL.js";
|
|
11
15
|
import { ModelSelector } from "./ModelSelector.js";
|
|
@@ -161,8 +165,8 @@ export function App({ registry, systemPrompt, effectLevel: initialEffect = "norm
|
|
|
161
165
|
registry.addTool({ name: "get_defi_tvl", label: "DeFi TVL", description: "DeFiLlama TVL by chain or all chains.", parameters: defiTvlParams, execute: (id, p) => getDefiTvlTool(id, p) });
|
|
162
166
|
registry.addTool({ name: "get_solana_stats", label: "Solana Stats", description: "Solana network TPS and health.", parameters: solanaStatsParams, execute: () => getSolanaStatsTool() });
|
|
163
167
|
// #31: Ephemeral task context
|
|
164
|
-
registry.addTool({ name: "read_task_context", label: "Read Task Context", description: "Read saved task context from a previous multi-step operation.", parameters:
|
|
165
|
-
registry.addTool({ name: "list_tasks", label: "List Tasks", description: "List active and recent task context folders.", parameters:
|
|
168
|
+
registry.addTool({ name: "read_task_context", label: "Read Task Context", description: "Read saved task context from a previous multi-step operation.", parameters: Type.Object({ taskId: Type.String({ description: "Task ID from a previous task reference" }) }), execute: (id, p) => contextStore.readContextTool(id, p) });
|
|
169
|
+
registry.addTool({ name: "list_tasks", label: "List Tasks", description: "List active and recent task context folders.", parameters: Type.Object({}), execute: () => contextStore.listTasksTool() });
|
|
166
170
|
// #12: Goal management
|
|
167
171
|
registry.addTool({ name: "set_goal", label: "Set Goal", description: "Set a persistent cross-session goal for the agent to monitor.", parameters: goalManager.setGoalParams, execute: (id, p) => goalManager.setGoalTool(id, p) });
|
|
168
172
|
registry.addTool({ name: "complete_goal", label: "Complete Goal", description: "Mark a goal as completed.", parameters: goalManager.completeGoalParams, execute: (id, p) => goalManager.completeGoalTool(id, p) });
|
|
@@ -223,13 +227,10 @@ export function App({ registry, systemPrompt, effectLevel: initialEffect = "norm
|
|
|
223
227
|
}
|
|
224
228
|
// Read rotation slots from context.json
|
|
225
229
|
try {
|
|
226
|
-
const { existsSync: exists, readFileSync: read } = require("node:fs");
|
|
227
|
-
const { join } = require("node:path");
|
|
228
|
-
const { homedir } = require("node:os");
|
|
229
230
|
const JELLY_HOME = process.env.JELLYOS_HOME ?? join(homedir(), ".jelly");
|
|
230
231
|
const ctxPath = join(JELLY_HOME, "context.json");
|
|
231
|
-
if (
|
|
232
|
-
const store = JSON.parse(
|
|
232
|
+
if (existsSync(ctxPath)) {
|
|
233
|
+
const store = JSON.parse(readFileSync(ctxPath, "utf-8"));
|
|
233
234
|
if (store.rotationSlots)
|
|
234
235
|
setRotationSlots(store.rotationSlots);
|
|
235
236
|
}
|
|
@@ -510,9 +511,6 @@ export function App({ registry, systemPrompt, effectLevel: initialEffect = "norm
|
|
|
510
511
|
const handleModelSelect = useCallback((modelId) => {
|
|
511
512
|
setShowModelSelector(false);
|
|
512
513
|
try {
|
|
513
|
-
const { writeFileSync, readFileSync, existsSync, mkdirSync } = require("node:fs");
|
|
514
|
-
const { join } = require("node:path");
|
|
515
|
-
const { homedir } = require("node:os");
|
|
516
514
|
const JELLY_HOME = process.env.JELLYOS_HOME ?? join(homedir(), ".jelly");
|
|
517
515
|
const envFile = join(JELLY_HOME, ".env");
|
|
518
516
|
mkdirSync(JELLY_HOME, { recursive: true });
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { appendFileSync, mkdirSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
const JELLY_HOME = process.env.JELLYOS_HOME ?? join(homedir(), ".jelly");
|
|
5
|
+
const DEBUG_LOG = join(JELLY_HOME, "debug.log");
|
|
6
|
+
let _notifyFn = null;
|
|
7
|
+
export function wireNotify(fn) { _notifyFn = fn; }
|
|
8
|
+
export function safeLog(...args) {
|
|
9
|
+
const msg = args.map(a => (typeof a === "string" ? a : String(a))).join(" ");
|
|
10
|
+
if (_notifyFn) {
|
|
11
|
+
_notifyFn(msg);
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
try {
|
|
15
|
+
mkdirSync(JELLY_HOME, { recursive: true });
|
|
16
|
+
appendFileSync(DEBUG_LOG, `[${new Date().toISOString()}] ${msg}\n`);
|
|
17
|
+
}
|
|
18
|
+
catch { /* non-fatal */ }
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=safeLog.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jellyos/agent",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "JellyOS — standalone AI trading agent. Runs locally, no server required.",
|
|
5
5
|
"author": "JellyChain",
|
|
6
6
|
"license": "MIT",
|
|
@@ -18,6 +18,9 @@
|
|
|
18
18
|
"jellyagent": "./bin/jellyagent",
|
|
19
19
|
"jellyos-mcp": "./bin/jellyos-mcp"
|
|
20
20
|
},
|
|
21
|
+
"publishConfig": {
|
|
22
|
+
"access": "public"
|
|
23
|
+
},
|
|
21
24
|
"scripts": {
|
|
22
25
|
"build": "npx tsc",
|
|
23
26
|
"build:watch": "tsc --watch",
|