@sofer_agent/cli 0.7.1 → 0.7.2

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/dist/bin.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { agentPaths } from "@sofer_agent/core";
3
3
  import { chatCommand } from "./chat.js";
4
- import { daemonStart, daemonStop } from "./daemon.js";
4
+ import { daemonLogs, daemonRestart, daemonRun, daemonStart, daemonStatus, daemonStop } from "./daemon.js";
5
5
  import { infoCommand } from "./info.js";
6
6
  import { initCommand } from "./init.js";
7
7
  import { telegramCommand } from "./telegram-start.js";
@@ -12,8 +12,12 @@ function printHelp() {
12
12
  sofer --resume <id> resume a previous session
13
13
  sofer init interactive setup — mint agent + provision memory
14
14
  sofer info print on-chain agent state
15
- sofer daemon start start persistent background agent
16
- sofer daemon stop stop the background agent
15
+ sofer daemon run start daemon in foreground
16
+ sofer daemon start start daemon in background (fork)
17
+ sofer daemon stop stop the daemon
18
+ sofer daemon restart stop + start
19
+ sofer daemon status show PID, uptime, socket
20
+ sofer daemon logs tail daemon logs
17
21
  sofer telegram start the Telegram bot
18
22
  sofer help show this help
19
23
 
@@ -42,12 +46,29 @@ async function main() {
42
46
  break;
43
47
  case "daemon": {
44
48
  const sub = args[1];
45
- if (sub === "start")
46
- await daemonStart();
47
- else if (sub === "stop")
48
- await daemonStop();
49
- else
50
- console.error("usage: sofer daemon <start|stop>");
49
+ switch (sub) {
50
+ case "run":
51
+ await daemonRun();
52
+ break;
53
+ case "start":
54
+ await daemonStart();
55
+ break;
56
+ case "stop":
57
+ await daemonStop();
58
+ break;
59
+ case "restart":
60
+ await daemonRestart();
61
+ break;
62
+ case "status":
63
+ await daemonStatus();
64
+ break;
65
+ case "logs":
66
+ await daemonLogs();
67
+ break;
68
+ default:
69
+ console.error("usage: sofer daemon <run|start|stop|restart|status|logs>");
70
+ break;
71
+ }
51
72
  break;
52
73
  }
53
74
  case "help":
package/dist/bin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,SAAS,SAAS;IAChB,OAAO,CAAC,GAAG,CACT;;;;;;;;;;;;6BAYyB,UAAU,CAAC,IAAI;gDACI,CAC7C,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAChE,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC;IAE9B,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,MAAM,CAAC;QACZ,KAAK,UAAU;YACb,MAAM,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;YACnD,MAAM;QACR,KAAK,MAAM;YACT,MAAM,WAAW,EAAE,CAAC;YACpB,MAAM;QACR,KAAK,MAAM;YACT,MAAM,WAAW,EAAE,CAAC;YACpB,MAAM;QACR,KAAK,UAAU;YACb,MAAM,eAAe,EAAE,CAAC;YACxB,MAAM;QACR,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;YACpB,IAAI,GAAG,KAAK,OAAO;gBAAE,MAAM,WAAW,EAAE,CAAC;iBACpC,IAAI,GAAG,KAAK,MAAM;gBAAE,MAAM,UAAU,EAAE,CAAC;;gBACvC,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;YACvD,MAAM;QACR,CAAC;QACD,KAAK,MAAM,CAAC;QACZ,KAAK,IAAI,CAAC;QACV,KAAK,QAAQ;YACX,SAAS,EAAE,CAAC;YACZ,MAAM;QACR;YACE,OAAO,CAAC,KAAK,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAAC;YAC3C,SAAS,EAAE,CAAC;YACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;IACjB,MAAM,GAAG,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACvD,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,IACE,GAAG,CAAC,QAAQ,CAAC,sBAAsB,CAAC;QACpC,GAAG,CAAC,QAAQ,CAAC,mBAAmB,CAAC;QACjC,GAAG,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAChC,CAAC;QACD,OAAO,CAAC,KAAK,CACX,qEAAqE,UAAU,CAAC,IAAI,KAAK,CAC1F,CAAC;IACJ,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC1G,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,SAAS,SAAS;IAChB,OAAO,CAAC,GAAG,CACT;;;;;;;;;;;;;;;;6BAgByB,UAAU,CAAC,IAAI;gDACI,CAC7C,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAChE,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC;IAE9B,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,MAAM,CAAC;QACZ,KAAK,UAAU;YACb,MAAM,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;YACnD,MAAM;QACR,KAAK,MAAM;YACT,MAAM,WAAW,EAAE,CAAC;YACpB,MAAM;QACR,KAAK,MAAM;YACT,MAAM,WAAW,EAAE,CAAC;YACpB,MAAM;QACR,KAAK,UAAU;YACb,MAAM,eAAe,EAAE,CAAC;YACxB,MAAM;QACR,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;YACpB,QAAQ,GAAG,EAAE,CAAC;gBACZ,KAAK,KAAK;oBAAE,MAAM,SAAS,EAAE,CAAC;oBAAC,MAAM;gBACrC,KAAK,OAAO;oBAAE,MAAM,WAAW,EAAE,CAAC;oBAAC,MAAM;gBACzC,KAAK,MAAM;oBAAE,MAAM,UAAU,EAAE,CAAC;oBAAC,MAAM;gBACvC,KAAK,SAAS;oBAAE,MAAM,aAAa,EAAE,CAAC;oBAAC,MAAM;gBAC7C,KAAK,QAAQ;oBAAE,MAAM,YAAY,EAAE,CAAC;oBAAC,MAAM;gBAC3C,KAAK,MAAM;oBAAE,MAAM,UAAU,EAAE,CAAC;oBAAC,MAAM;gBACvC;oBAAS,OAAO,CAAC,KAAK,CAAC,0DAA0D,CAAC,CAAC;oBAAC,MAAM;YAC5F,CAAC;YACD,MAAM;QACR,CAAC;QACD,KAAK,MAAM,CAAC;QACZ,KAAK,IAAI,CAAC;QACV,KAAK,QAAQ;YACX,SAAS,EAAE,CAAC;YACZ,MAAM;QACR;YACE,OAAO,CAAC,KAAK,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAAC;YAC3C,SAAS,EAAE,CAAC;YACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;IACjB,MAAM,GAAG,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACvD,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,IACE,GAAG,CAAC,QAAQ,CAAC,sBAAsB,CAAC;QACpC,GAAG,CAAC,QAAQ,CAAC,mBAAmB,CAAC;QACjC,GAAG,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAChC,CAAC;QACD,OAAO,CAAC,KAAK,CACX,qEAAqE,UAAU,CAAC,IAAI,KAAK,CAC1F,CAAC;IACJ,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
package/dist/daemon.d.ts CHANGED
@@ -1,3 +1,7 @@
1
- export declare function daemonStop(): Promise<void>;
1
+ export declare function daemonRun(): Promise<void>;
2
2
  export declare function daemonStart(): Promise<void>;
3
+ export declare function daemonStop(): Promise<void>;
4
+ export declare function daemonStatus(): Promise<void>;
5
+ export declare function daemonRestart(): Promise<void>;
6
+ export declare function daemonLogs(tail?: number, follow?: boolean): Promise<void>;
3
7
  //# sourceMappingURL=daemon.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"AA2CA,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAKhD;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAuLjD"}
1
+ {"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"AAwCA,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAM/C;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAqBjD;AAED,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAKhD;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAoBlD;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAInD;AAED,wBAAsB,UAAU,CAAC,IAAI,SAAK,EAAE,MAAM,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBzE"}
package/dist/daemon.js CHANGED
@@ -1,12 +1,13 @@
1
1
  import { createServer } from "node:http";
2
- import { chmodSync, existsSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
2
+ import { chmodSync, existsSync, readFileSync, statSync, unlinkSync, writeFileSync } from "node:fs";
3
3
  import { join } from "node:path";
4
- import { agentPaths, decryptWithKey, loadConfig, readSecret, shortAgentId, SoferAgent, } from "@sofer_agent/core";
4
+ import { spawn } from "node:child_process";
5
+ import { agentPaths, decryptWithKey, loadConfig, readSecret, SoferAgent, } from "@sofer_agent/core";
5
6
  import { TelegramListener } from "@sofer_agent/plugin-telegram";
6
7
  import { loadSecrets } from "./env.js";
7
8
  const LOCK_FILE = join(agentPaths.root, "daemon.lock");
8
9
  const SOCK_PATH = join(agentPaths.root, "daemon.sock");
9
- // ── Process lock ──────────────────────────────────────────────────────────
10
+ const LOG_FILE = join(agentPaths.root, "daemon.log");
10
11
  function acquireLock() {
11
12
  try {
12
13
  if (existsSync(LOCK_FILE)) {
@@ -32,7 +33,34 @@ function releaseLock() {
32
33
  catch { /* */ }
33
34
  }
34
35
  let state = "bootstrapping";
35
- // ── Main ──────────────────────────────────────────────────────────────────
36
+ // ── Commands ─────────────────────────────────────────────────────────────
37
+ export async function daemonRun() {
38
+ if (!acquireLock()) {
39
+ console.error("Daemon already running. Use `sofer daemon stop` first.");
40
+ process.exit(1);
41
+ }
42
+ await runServer();
43
+ }
44
+ export async function daemonStart() {
45
+ if (!acquireLock()) {
46
+ console.error("Daemon already running. Use `sofer daemon stop` first.");
47
+ process.exit(1);
48
+ }
49
+ releaseLock(); // let the child take the lock
50
+ const logFd = existsSync(LOG_FILE)
51
+ ? require("node:fs").openSync(LOG_FILE, "a")
52
+ : require("node:fs").openSync(LOG_FILE, "w");
53
+ const execPath = process.argv[1] ?? process.execPath;
54
+ const child = spawn(process.execPath, [...process.execArgv, execPath, "daemon", "run"], {
55
+ detached: true,
56
+ stdio: ["ignore", logFd, logFd],
57
+ env: { ...process.env },
58
+ });
59
+ child.unref();
60
+ console.log(`[daemon] started (PID ${child.pid})`);
61
+ console.log(` socket: ${SOCK_PATH}`);
62
+ console.log(` logs: ${LOG_FILE}`);
63
+ }
36
64
  export async function daemonStop() {
37
65
  if (!existsSync(LOCK_FILE)) {
38
66
  console.log("No daemon running.");
@@ -41,21 +69,75 @@ export async function daemonStop() {
41
69
  const pid = Number(readFileSync(LOCK_FILE, "utf8").trim());
42
70
  try {
43
71
  process.kill(pid, "SIGTERM");
44
- console.log(`Sent stop to PID ${pid}.`);
72
+ console.log(`Stopped daemon (PID ${pid}).`);
45
73
  }
46
74
  catch {
47
75
  console.log("Stale lock. Cleaning up.");
48
76
  releaseLock();
49
77
  }
50
78
  }
51
- export async function daemonStart() {
52
- if (!acquireLock()) {
53
- console.error("Daemon already running (lock exists). Use `sofer daemon stop` first.");
54
- process.exit(1);
79
+ export async function daemonStatus() {
80
+ if (!existsSync(LOCK_FILE)) {
81
+ console.log("Daemon not running.");
82
+ return;
83
+ }
84
+ const pid = Number(readFileSync(LOCK_FILE, "utf8").trim());
85
+ let alive = false;
86
+ try {
87
+ process.kill(pid, 0);
88
+ alive = true;
55
89
  }
90
+ catch { /* dead */ }
91
+ if (!alive) {
92
+ console.log("Daemon not running (stale lock).");
93
+ return;
94
+ }
95
+ let uptime = "unknown";
96
+ try {
97
+ const stat = statSync(LOCK_FILE);
98
+ const sec = Math.floor((Date.now() - stat.mtimeMs) / 1000);
99
+ uptime = sec < 60 ? `${sec}s` : sec < 3600 ? `${Math.floor(sec / 60)}m` : `${Math.floor(sec / 3600)}h`;
100
+ }
101
+ catch { /* */ }
102
+ console.log(` PID: ${pid}`);
103
+ console.log(` Status: running`);
104
+ console.log(` Uptime: ${uptime}`);
105
+ console.log(` Socket: ${SOCK_PATH}`);
106
+ console.log(` Lock: ${LOCK_FILE}`);
107
+ console.log(` Logs: ${LOG_FILE}`);
108
+ }
109
+ export async function daemonRestart() {
110
+ await daemonStop();
111
+ await new Promise((r) => setTimeout(r, 500));
112
+ await daemonStart();
113
+ }
114
+ export async function daemonLogs(tail = 50, follow = false) {
115
+ if (!existsSync(LOG_FILE)) {
116
+ console.log("No daemon logs found.");
117
+ return;
118
+ }
119
+ const lines = readFileSync(LOG_FILE, "utf8").split("\n").filter(Boolean);
120
+ const recent = lines.slice(-tail);
121
+ console.log(recent.join("\n"));
122
+ if (follow) {
123
+ const { watchFile } = require("node:fs");
124
+ let count = lines.length;
125
+ watchFile(LOG_FILE, () => {
126
+ const all = readFileSync(LOG_FILE, "utf8").split("\n").filter(Boolean);
127
+ for (let i = count; i < all.length; i++) {
128
+ console.log(all[i]);
129
+ }
130
+ count = all.length;
131
+ });
132
+ // Keep alive
133
+ await new Promise(() => { });
134
+ }
135
+ }
136
+ // ── Server (shared by run + start) ───────────────────────────────────────
137
+ async function runServer() {
56
138
  const secrets = loadSecrets();
57
139
  if (!secrets.suiSecretKey || !secrets.anthropicApiKey) {
58
- console.error("Missing secrets. Run `sofer init` first.");
140
+ console.error("[daemon] missing secrets. Run `sofer init` first.");
59
141
  process.exit(1);
60
142
  }
61
143
  console.log("[daemon] bootstrapping…");
@@ -68,20 +150,17 @@ export async function daemonStart() {
68
150
  });
69
151
  }
70
152
  catch (e) {
71
- console.error("[daemon] failed to create agent:", e.message);
153
+ console.error("[daemon] failed:", e.message);
72
154
  releaseLock();
73
155
  process.exit(1);
74
156
  }
75
- // SSE clients
76
157
  let sseId = 0;
77
158
  const sseClients = new Set();
78
159
  function broadcast(event, data) {
79
160
  const payload = JSON.stringify(data);
80
- for (const c of sseClients) {
161
+ for (const c of sseClients)
81
162
  c.res.write(`event: ${event}\ndata: ${payload}\n\n`);
82
- }
83
163
  }
84
- // ── HTTP server ────────────────────────────────────────────────────────
85
164
  const server = createServer(async (req, res) => {
86
165
  res.setHeader("Access-Control-Allow-Origin", "*");
87
166
  if (req.method === "OPTIONS") {
@@ -89,39 +168,30 @@ export async function daemonStart() {
89
168
  return;
90
169
  }
91
170
  const url = req.url ?? "/";
92
- // GET /healthz
93
- if (req.method === "GET" && url === "/healthz") {
94
- res.writeHead(200, { "content-type": "application/json" });
95
- res.end(JSON.stringify({ status: state, agent: agent.address.slice(0, 10), network: config.network }));
171
+ if (url === "/healthz") {
172
+ res.writeHead(200).end(JSON.stringify({ status: state, agent: agent.address.slice(0, 10), network: config.network }));
96
173
  return;
97
174
  }
98
- // GET /events (SSE)
99
- if (req.method === "GET" && url === "/events") {
100
- res.writeHead(200, {
101
- "content-type": "text/event-stream",
102
- "cache-control": "no-cache",
103
- connection: "keep-alive",
104
- });
175
+ if (url === "/events") {
176
+ res.writeHead(200, { "content-type": "text/event-stream", "cache-control": "no-cache", connection: "keep-alive" });
105
177
  const client = { id: ++sseId, res };
106
178
  sseClients.add(client);
107
179
  res.write(`data: ${JSON.stringify({ event: "connected", agent: agent.address })}\n\n`);
108
180
  req.on("close", () => sseClients.delete(client));
109
181
  return;
110
182
  }
111
- // POST /chat
112
183
  if (req.method === "POST" && url === "/chat") {
113
184
  const body = await readBody(req);
114
185
  try {
115
186
  const { message } = JSON.parse(body);
116
187
  if (!message) {
117
- res.writeHead(400).end("missing message");
188
+ res.writeHead(400).end();
118
189
  return;
119
190
  }
120
191
  broadcast("thinking", { status: "thinking" });
121
192
  const { text } = await agent.chat(message);
122
193
  broadcast("response", { text });
123
194
  broadcast("idle", { status: "idle" });
124
- res.writeHead(200, { "content-type": "application/json" });
125
195
  res.end(JSON.stringify({ text }));
126
196
  }
127
197
  catch (e) {
@@ -130,10 +200,7 @@ export async function daemonStart() {
130
200
  }
131
201
  return;
132
202
  }
133
- // POST /sync — force memory flush
134
203
  if (req.method === "POST" && url === "/sync") {
135
- broadcast("sync", { status: "syncing" });
136
- // Memory is already persisted via JSONL; trigger a fresh agent state read
137
204
  try {
138
205
  const bal = await agent.getBalance();
139
206
  broadcast("sync", { status: "done", balance: (Number(bal) / 1e9).toFixed(4) });
@@ -144,22 +211,13 @@ export async function daemonStart() {
144
211
  }
145
212
  return;
146
213
  }
147
- // GET /status
148
- if (req.method === "GET" && url === "/status") {
149
- res.writeHead(200, { "content-type": "application/json" });
150
- res.end(JSON.stringify({
151
- state,
152
- agent: agent.address,
153
- name: agent.name,
154
- network: config.network,
155
- tokens: agent.usage.tokens,
156
- cost: agent.usage.costUsd.toFixed(6),
157
- }));
214
+ if (url === "/status") {
215
+ res.end(JSON.stringify({ state, agent: agent.address, name: agent.name, network: config.network, tokens: agent.usage.tokens, cost: agent.usage.costUsd.toFixed(6) }));
158
216
  return;
159
217
  }
160
- res.writeHead(404).end("not found");
218
+ res.writeHead(404).end();
161
219
  });
162
- // ── Telegram ───────────────────────────────────────────────────────────
220
+ // Telegram
163
221
  const tgPath = `${agentPaths.root}/telegram.enc`;
164
222
  const tgEnc = readSecret(tgPath);
165
223
  let tgListener = null;
@@ -168,11 +226,7 @@ export async function daemonStart() {
168
226
  const raw = decryptWithKey(secrets.suiSecretKey, tgEnc);
169
227
  if (raw) {
170
228
  const tgConfig = JSON.parse(raw);
171
- tgListener = new TelegramListener({
172
- botToken: tgConfig.botToken,
173
- allowedUserIds: tgConfig.allowedUserIds,
174
- agentName: agent.name.toLowerCase(),
175
- });
229
+ tgListener = new TelegramListener({ botToken: tgConfig.botToken, allowedUserIds: tgConfig.allowedUserIds, agentName: agent.name.toLowerCase() });
176
230
  tgListener.onDispatch(async (input) => {
177
231
  broadcast("tg-message", { from: input.displayName, text: input.text.slice(0, 200) });
178
232
  const { text } = await agent.chat(input.text);
@@ -181,39 +235,33 @@ export async function daemonStart() {
181
235
  });
182
236
  }
183
237
  }
184
- catch { /* skip */ }
238
+ catch { /* */ }
185
239
  }
186
- // ── Bind ───────────────────────────────────────────────────────────────
187
240
  const PORT = Number(process.env.SOFER_DAEMON_PORT ?? 4242);
188
- // Try Unix socket first, fall back to TCP
189
241
  try {
190
242
  if (existsSync(SOCK_PATH))
191
243
  unlinkSync(SOCK_PATH);
192
244
  server.listen(SOCK_PATH, () => {
193
245
  chmodSync(SOCK_PATH, 0o600);
194
246
  state = "ready";
195
- console.log(`[daemon] ready — unix socket ${SOCK_PATH}`);
196
- console.log(`[daemon] agent: ${agent.address.slice(0, 10)}… network: ${config.network}`);
197
- if (tgListener) {
198
- console.log("[daemon] telegram: starting bot…");
247
+ console.log(`[daemon] ready — ${SOCK_PATH}`);
248
+ console.log(`[daemon] agent: ${agent.address.slice(0, 10)}… ${config.network}`);
249
+ if (tgListener)
199
250
  tgListener.start().catch((e) => console.error("[daemon] telegram:", e.message));
200
- }
201
251
  });
202
252
  }
203
253
  catch {
204
254
  server.listen(PORT, () => {
205
255
  state = "ready";
206
- console.log(`[daemon] ready — tcp port ${PORT} (SOFER_DAEMON_PORT)`);
207
- console.log(`[daemon] agent: ${agent.address.slice(0, 10)}… network: ${config.network}`);
208
- if (tgListener) {
256
+ console.log(`[daemon] ready — tcp :${PORT}`);
257
+ console.log(`[daemon] agent: ${agent.address.slice(0, 10)}… ${config.network}`);
258
+ if (tgListener)
209
259
  tgListener.start().catch((e) => console.error("[daemon] telegram:", e.message));
210
- }
211
260
  });
212
261
  }
213
- // ── Shutdown ───────────────────────────────────────────────────────────
214
262
  const shutdown = async () => {
215
263
  state = "shutting_down";
216
- console.log("\n[daemon] shutting down…");
264
+ console.log("[daemon] shutting down…");
217
265
  if (tgListener)
218
266
  await tgListener.stop().catch(() => { });
219
267
  server.close();
@@ -231,7 +279,7 @@ export async function daemonStart() {
231
279
  function readBody(req) {
232
280
  return new Promise((resolve) => {
233
281
  let data = "";
234
- req.on("data", (chunk) => { data += chunk; });
282
+ req.on("data", (c) => { data += c; });
235
283
  req.on("end", () => resolve(data));
236
284
  });
237
285
  }
@@ -1 +1 @@
1
- {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sofer_agent/cli",
3
- "version": "0.7.1",
3
+ "version": "0.7.2",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "sofer": "./bin/sofer"
package/src/bin.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { agentPaths } from "@sofer_agent/core";
3
3
  import { chatCommand } from "./chat.js";
4
- import { daemonStart, daemonStop } from "./daemon.js";
4
+ import { daemonLogs, daemonRestart, daemonRun, daemonStart, daemonStatus, daemonStop } from "./daemon.js";
5
5
  import { infoCommand } from "./info.js";
6
6
  import { initCommand } from "./init.js";
7
7
  import { telegramCommand } from "./telegram-start.js";
@@ -14,8 +14,12 @@ function printHelp(): void {
14
14
  sofer --resume <id> resume a previous session
15
15
  sofer init interactive setup — mint agent + provision memory
16
16
  sofer info print on-chain agent state
17
- sofer daemon start start persistent background agent
18
- sofer daemon stop stop the background agent
17
+ sofer daemon run start daemon in foreground
18
+ sofer daemon start start daemon in background (fork)
19
+ sofer daemon stop stop the daemon
20
+ sofer daemon restart stop + start
21
+ sofer daemon status show PID, uptime, socket
22
+ sofer daemon logs tail daemon logs
19
23
  sofer telegram start the Telegram bot
20
24
  sofer help show this help
21
25
 
@@ -47,9 +51,15 @@ async function main(): Promise<void> {
47
51
  break;
48
52
  case "daemon": {
49
53
  const sub = args[1];
50
- if (sub === "start") await daemonStart();
51
- else if (sub === "stop") await daemonStop();
52
- else console.error("usage: sofer daemon <start|stop>");
54
+ switch (sub) {
55
+ case "run": await daemonRun(); break;
56
+ case "start": await daemonStart(); break;
57
+ case "stop": await daemonStop(); break;
58
+ case "restart": await daemonRestart(); break;
59
+ case "status": await daemonStatus(); break;
60
+ case "logs": await daemonLogs(); break;
61
+ default: console.error("usage: sofer daemon <run|start|stop|restart|status|logs>"); break;
62
+ }
53
63
  break;
54
64
  }
55
65
  case "help":
package/src/daemon.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  import { createServer, type IncomingMessage, type ServerResponse } from "node:http";
2
- import { chmodSync, existsSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
2
+ import { chmodSync, existsSync, readFileSync, statSync, unlinkSync, writeFileSync } from "node:fs";
3
3
  import { join } from "node:path";
4
+ import { spawn } from "node:child_process";
4
5
  import {
5
6
  agentPaths,
6
7
  decryptWithKey,
7
8
  loadConfig,
8
9
  readSecret,
9
- shortAgentId,
10
10
  SoferAgent,
11
11
  } from "@sofer_agent/core";
12
12
  import { TelegramListener } from "@sofer_agent/plugin-telegram";
@@ -14,11 +14,10 @@ import { loadSecrets } from "./env.js";
14
14
 
15
15
  const LOCK_FILE = join(agentPaths.root, "daemon.lock");
16
16
  const SOCK_PATH = join(agentPaths.root, "daemon.sock");
17
+ const LOG_FILE = join(agentPaths.root, "daemon.log");
17
18
 
18
19
  interface SSEClient { id: number; res: ServerResponse; }
19
20
 
20
- // ── Process lock ──────────────────────────────────────────────────────────
21
-
22
21
  function acquireLock(): boolean {
23
22
  try {
24
23
  if (existsSync(LOCK_FILE)) {
@@ -34,29 +33,104 @@ function releaseLock(): void {
34
33
  try { if (existsSync(LOCK_FILE)) unlinkSync(LOCK_FILE); } catch { /* */ }
35
34
  }
36
35
 
37
- // ── State machine ─────────────────────────────────────────────────────────
38
-
39
36
  type DaemonState = "bootstrapping" | "ready" | "shutting_down";
40
37
  let state: DaemonState = "bootstrapping";
41
38
 
42
- // ── Main ──────────────────────────────────────────────────────────────────
39
+ // ── Commands ─────────────────────────────────────────────────────────────
40
+
41
+ export async function daemonRun(): Promise<void> {
42
+ if (!acquireLock()) {
43
+ console.error("Daemon already running. Use `sofer daemon stop` first.");
44
+ process.exit(1);
45
+ }
46
+ await runServer();
47
+ }
48
+
49
+ export async function daemonStart(): Promise<void> {
50
+ if (!acquireLock()) {
51
+ console.error("Daemon already running. Use `sofer daemon stop` first.");
52
+ process.exit(1);
53
+ }
54
+ releaseLock(); // let the child take the lock
55
+
56
+ const logFd = existsSync(LOG_FILE)
57
+ ? require("node:fs").openSync(LOG_FILE, "a")
58
+ : require("node:fs").openSync(LOG_FILE, "w");
59
+
60
+ const execPath = process.argv[1] ?? process.execPath;
61
+ const child = spawn(process.execPath, [...process.execArgv, execPath, "daemon", "run"], {
62
+ detached: true,
63
+ stdio: ["ignore", logFd, logFd] as const,
64
+ env: { ...process.env },
65
+ });
66
+ child.unref();
67
+ console.log(`[daemon] started (PID ${child.pid})`);
68
+ console.log(` socket: ${SOCK_PATH}`);
69
+ console.log(` logs: ${LOG_FILE}`);
70
+ }
43
71
 
44
72
  export async function daemonStop(): Promise<void> {
45
73
  if (!existsSync(LOCK_FILE)) { console.log("No daemon running."); return; }
46
74
  const pid = Number(readFileSync(LOCK_FILE, "utf8").trim());
47
- try { process.kill(pid, "SIGTERM"); console.log(`Sent stop to PID ${pid}.`); }
75
+ try { process.kill(pid, "SIGTERM"); console.log(`Stopped daemon (PID ${pid}).`); }
48
76
  catch { console.log("Stale lock. Cleaning up."); releaseLock(); }
49
77
  }
50
78
 
51
- export async function daemonStart(): Promise<void> {
52
- if (!acquireLock()) {
53
- console.error("Daemon already running (lock exists). Use `sofer daemon stop` first.");
54
- process.exit(1);
79
+ export async function daemonStatus(): Promise<void> {
80
+ if (!existsSync(LOCK_FILE)) { console.log("Daemon not running."); return; }
81
+ const pid = Number(readFileSync(LOCK_FILE, "utf8").trim());
82
+ let alive = false;
83
+ try { process.kill(pid, 0); alive = true; } catch { /* dead */ }
84
+ if (!alive) { console.log("Daemon not running (stale lock)."); return; }
85
+
86
+ let uptime = "unknown";
87
+ try {
88
+ const stat = statSync(LOCK_FILE);
89
+ const sec = Math.floor((Date.now() - stat.mtimeMs) / 1000);
90
+ uptime = sec < 60 ? `${sec}s` : sec < 3600 ? `${Math.floor(sec / 60)}m` : `${Math.floor(sec / 3600)}h`;
91
+ } catch { /* */ }
92
+
93
+ console.log(` PID: ${pid}`);
94
+ console.log(` Status: running`);
95
+ console.log(` Uptime: ${uptime}`);
96
+ console.log(` Socket: ${SOCK_PATH}`);
97
+ console.log(` Lock: ${LOCK_FILE}`);
98
+ console.log(` Logs: ${LOG_FILE}`);
99
+ }
100
+
101
+ export async function daemonRestart(): Promise<void> {
102
+ await daemonStop();
103
+ await new Promise((r) => setTimeout(r, 500));
104
+ await daemonStart();
105
+ }
106
+
107
+ export async function daemonLogs(tail = 50, follow = false): Promise<void> {
108
+ if (!existsSync(LOG_FILE)) { console.log("No daemon logs found."); return; }
109
+ const lines = readFileSync(LOG_FILE, "utf8").split("\n").filter(Boolean);
110
+ const recent = lines.slice(-tail);
111
+ console.log(recent.join("\n"));
112
+
113
+ if (follow) {
114
+ const { watchFile } = require("node:fs") as typeof import("node:fs");
115
+ let count = lines.length;
116
+ watchFile(LOG_FILE, () => {
117
+ const all = readFileSync(LOG_FILE, "utf8").split("\n").filter(Boolean);
118
+ for (let i = count; i < all.length; i++) {
119
+ console.log(all[i]);
120
+ }
121
+ count = all.length;
122
+ });
123
+ // Keep alive
124
+ await new Promise(() => {});
55
125
  }
126
+ }
127
+
128
+ // ── Server (shared by run + start) ───────────────────────────────────────
56
129
 
130
+ async function runServer(): Promise<void> {
57
131
  const secrets = loadSecrets();
58
132
  if (!secrets.suiSecretKey || !secrets.anthropicApiKey) {
59
- console.error("Missing secrets. Run `sofer init` first.");
133
+ console.error("[daemon] missing secrets. Run `sofer init` first.");
60
134
  process.exit(1);
61
135
  }
62
136
 
@@ -69,62 +143,45 @@ export async function daemonStart(): Promise<void> {
69
143
  anthropicApiKey: secrets.anthropicApiKey,
70
144
  });
71
145
  } catch (e) {
72
- console.error("[daemon] failed to create agent:", (e as Error).message);
146
+ console.error("[daemon] failed:", (e as Error).message);
73
147
  releaseLock();
74
148
  process.exit(1);
75
149
  }
76
150
 
77
- // SSE clients
78
151
  let sseId = 0;
79
152
  const sseClients = new Set<SSEClient>();
80
153
 
81
154
  function broadcast(event: string, data: Record<string, unknown>): void {
82
155
  const payload = JSON.stringify(data);
83
- for (const c of sseClients) {
84
- c.res.write(`event: ${event}\ndata: ${payload}\n\n`);
85
- }
156
+ for (const c of sseClients) c.res.write(`event: ${event}\ndata: ${payload}\n\n`);
86
157
  }
87
158
 
88
- // ── HTTP server ────────────────────────────────────────────────────────
89
-
90
- const server = createServer(async (req: IncomingMessage, res: ServerResponse) => {
159
+ const server = createServer(async (req, res) => {
91
160
  res.setHeader("Access-Control-Allow-Origin", "*");
92
161
  if (req.method === "OPTIONS") { res.writeHead(204).end(); return; }
93
-
94
162
  const url = req.url ?? "/";
95
163
 
96
- // GET /healthz
97
- if (req.method === "GET" && url === "/healthz") {
98
- res.writeHead(200, { "content-type": "application/json" });
99
- res.end(JSON.stringify({ status: state, agent: agent.address.slice(0, 10), network: config.network }));
164
+ if (url === "/healthz") {
165
+ res.writeHead(200).end(JSON.stringify({ status: state, agent: agent.address.slice(0, 10), network: config.network }));
100
166
  return;
101
167
  }
102
-
103
- // GET /events (SSE)
104
- if (req.method === "GET" && url === "/events") {
105
- res.writeHead(200, {
106
- "content-type": "text/event-stream",
107
- "cache-control": "no-cache",
108
- connection: "keep-alive",
109
- });
168
+ if (url === "/events") {
169
+ res.writeHead(200, { "content-type": "text/event-stream", "cache-control": "no-cache", connection: "keep-alive" });
110
170
  const client: SSEClient = { id: ++sseId, res };
111
171
  sseClients.add(client);
112
172
  res.write(`data: ${JSON.stringify({ event: "connected", agent: agent.address })}\n\n`);
113
173
  req.on("close", () => sseClients.delete(client));
114
174
  return;
115
175
  }
116
-
117
- // POST /chat
118
176
  if (req.method === "POST" && url === "/chat") {
119
177
  const body = await readBody(req);
120
178
  try {
121
179
  const { message } = JSON.parse(body);
122
- if (!message) { res.writeHead(400).end("missing message"); return; }
180
+ if (!message) { res.writeHead(400).end(); return; }
123
181
  broadcast("thinking", { status: "thinking" });
124
182
  const { text } = await agent.chat(message);
125
183
  broadcast("response", { text });
126
184
  broadcast("idle", { status: "idle" });
127
- res.writeHead(200, { "content-type": "application/json" });
128
185
  res.end(JSON.stringify({ text }));
129
186
  } catch (e) {
130
187
  broadcast("error", { error: (e as Error).message });
@@ -132,40 +189,22 @@ export async function daemonStart(): Promise<void> {
132
189
  }
133
190
  return;
134
191
  }
135
-
136
- // POST /sync — force memory flush
137
192
  if (req.method === "POST" && url === "/sync") {
138
- broadcast("sync", { status: "syncing" });
139
- // Memory is already persisted via JSONL; trigger a fresh agent state read
140
193
  try {
141
194
  const bal = await agent.getBalance();
142
195
  broadcast("sync", { status: "done", balance: (Number(bal) / 1e9).toFixed(4) });
143
196
  res.writeHead(200).end("synced");
144
- } catch (e) {
145
- res.writeHead(500).end((e as Error).message);
146
- }
197
+ } catch (e) { res.writeHead(500).end((e as Error).message); }
147
198
  return;
148
199
  }
149
-
150
- // GET /status
151
- if (req.method === "GET" && url === "/status") {
152
- res.writeHead(200, { "content-type": "application/json" });
153
- res.end(JSON.stringify({
154
- state,
155
- agent: agent.address,
156
- name: agent.name,
157
- network: config.network,
158
- tokens: agent.usage.tokens,
159
- cost: agent.usage.costUsd.toFixed(6),
160
- }));
200
+ if (url === "/status") {
201
+ res.end(JSON.stringify({ state, agent: agent.address, name: agent.name, network: config.network, tokens: agent.usage.tokens, cost: agent.usage.costUsd.toFixed(6) }));
161
202
  return;
162
203
  }
163
-
164
- res.writeHead(404).end("not found");
204
+ res.writeHead(404).end();
165
205
  });
166
206
 
167
- // ── Telegram ───────────────────────────────────────────────────────────
168
-
207
+ // Telegram
169
208
  const tgPath = `${agentPaths.root}/telegram.enc`;
170
209
  const tgEnc = readSecret(tgPath);
171
210
  let tgListener: TelegramListener | null = null;
@@ -174,11 +213,7 @@ export async function daemonStart(): Promise<void> {
174
213
  const raw = decryptWithKey(secrets.suiSecretKey, tgEnc);
175
214
  if (raw) {
176
215
  const tgConfig = JSON.parse(raw) as { botToken: string; allowedUserIds: number[] };
177
- tgListener = new TelegramListener({
178
- botToken: tgConfig.botToken,
179
- allowedUserIds: tgConfig.allowedUserIds,
180
- agentName: agent.name.toLowerCase(),
181
- });
216
+ tgListener = new TelegramListener({ botToken: tgConfig.botToken, allowedUserIds: tgConfig.allowedUserIds, agentName: agent.name.toLowerCase() });
182
217
  tgListener.onDispatch(async (input) => {
183
218
  broadcast("tg-message", { from: input.displayName, text: input.text.slice(0, 200) });
184
219
  const { text } = await agent.chat(input.text);
@@ -186,49 +221,37 @@ export async function daemonStart(): Promise<void> {
186
221
  return text;
187
222
  });
188
223
  }
189
- } catch { /* skip */ }
224
+ } catch { /* */ }
190
225
  }
191
226
 
192
- // ── Bind ───────────────────────────────────────────────────────────────
193
-
194
227
  const PORT = Number(process.env.SOFER_DAEMON_PORT ?? 4242);
195
-
196
- // Try Unix socket first, fall back to TCP
197
228
  try {
198
229
  if (existsSync(SOCK_PATH)) unlinkSync(SOCK_PATH);
199
230
  server.listen(SOCK_PATH, () => {
200
231
  chmodSync(SOCK_PATH, 0o600);
201
232
  state = "ready";
202
- console.log(`[daemon] ready — unix socket ${SOCK_PATH}`);
203
- console.log(`[daemon] agent: ${agent.address.slice(0, 10)}… network: ${config.network}`);
204
- if (tgListener) {
205
- console.log("[daemon] telegram: starting bot…");
206
- tgListener.start().catch((e) => console.error("[daemon] telegram:", e.message));
207
- }
233
+ console.log(`[daemon] ready — ${SOCK_PATH}`);
234
+ console.log(`[daemon] agent: ${agent.address.slice(0, 10)}… ${config.network}`);
235
+ if (tgListener) tgListener.start().catch((e) => console.error("[daemon] telegram:", e.message));
208
236
  });
209
237
  } catch {
210
238
  server.listen(PORT, () => {
211
239
  state = "ready";
212
- console.log(`[daemon] ready — tcp port ${PORT} (SOFER_DAEMON_PORT)`);
213
- console.log(`[daemon] agent: ${agent.address.slice(0, 10)}… network: ${config.network}`);
214
- if (tgListener) {
215
- tgListener.start().catch((e) => console.error("[daemon] telegram:", e.message));
216
- }
240
+ console.log(`[daemon] ready — tcp :${PORT}`);
241
+ console.log(`[daemon] agent: ${agent.address.slice(0, 10)}… ${config.network}`);
242
+ if (tgListener) tgListener.start().catch((e) => console.error("[daemon] telegram:", e.message));
217
243
  });
218
244
  }
219
245
 
220
- // ── Shutdown ───────────────────────────────────────────────────────────
221
-
222
246
  const shutdown = async () => {
223
247
  state = "shutting_down";
224
- console.log("\n[daemon] shutting down…");
248
+ console.log("[daemon] shutting down…");
225
249
  if (tgListener) await tgListener.stop().catch(() => {});
226
250
  server.close();
227
251
  releaseLock();
228
252
  try { if (existsSync(SOCK_PATH)) unlinkSync(SOCK_PATH); } catch { /* */ }
229
253
  process.exit(0);
230
254
  };
231
-
232
255
  process.on("SIGINT", shutdown);
233
256
  process.on("SIGTERM", shutdown);
234
257
  }
@@ -236,7 +259,7 @@ export async function daemonStart(): Promise<void> {
236
259
  function readBody(req: IncomingMessage): Promise<string> {
237
260
  return new Promise((resolve) => {
238
261
  let data = "";
239
- req.on("data", (chunk) => { data += chunk; });
262
+ req.on("data", (c) => { data += c; });
240
263
  req.on("end", () => resolve(data));
241
264
  });
242
265
  }