freeturtle 0.1.24 → 0.1.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -20
- package/dist/bin/freeturtle.js +26 -2
- package/dist/bin/freeturtle.js.map +1 -1
- package/dist/src/alpha.d.ts +7 -0
- package/dist/src/alpha.js +10 -0
- package/dist/src/alpha.js.map +1 -0
- package/dist/src/channels/telegram.d.ts +2 -2
- package/dist/src/channels/telegram.js +40 -0
- package/dist/src/channels/telegram.js.map +1 -1
- package/dist/src/channels/types.d.ts +7 -1
- package/dist/src/cli/install-service.js +10 -4
- package/dist/src/cli/install-service.js.map +1 -1
- package/dist/src/cli/update.js +16 -4
- package/dist/src/cli/update.js.map +1 -1
- package/dist/src/config.d.ts +5 -0
- package/dist/src/config.js +9 -0
- package/dist/src/config.js.map +1 -1
- package/dist/src/daemon.d.ts +2 -0
- package/dist/src/daemon.js +69 -12
- package/dist/src/daemon.js.map +1 -1
- package/dist/src/heartbeat.d.ts +2 -0
- package/dist/src/heartbeat.js +26 -3
- package/dist/src/heartbeat.js.map +1 -1
- package/dist/src/llm.d.ts +1 -1
- package/dist/src/llm.js +25 -6
- package/dist/src/llm.js.map +1 -1
- package/dist/src/modules/onchain/chains.d.ts +4 -4
- package/dist/src/modules/onchain/chains.js +5 -1
- package/dist/src/modules/onchain/chains.js.map +1 -1
- package/dist/src/modules/onchain/index.d.ts +1 -0
- package/dist/src/modules/onchain/index.js +69 -14
- package/dist/src/modules/onchain/index.js.map +1 -1
- package/dist/src/modules/onchain/wallet/cdp.d.ts +2 -0
- package/dist/src/modules/onchain/wallet/cdp.js +23 -0
- package/dist/src/modules/onchain/wallet/cdp.js.map +1 -0
- package/dist/src/modules/onchain/wallet/index.d.ts +3 -0
- package/dist/src/modules/onchain/wallet/index.js +15 -0
- package/dist/src/modules/onchain/wallet/index.js.map +1 -0
- package/dist/src/modules/onchain/wallet/private-key.d.ts +2 -0
- package/dist/src/modules/onchain/wallet/private-key.js +10 -0
- package/dist/src/modules/onchain/wallet/private-key.js.map +1 -0
- package/dist/src/modules/onchain/wallet/types.d.ts +6 -0
- package/dist/src/modules/onchain/wallet/types.js +2 -0
- package/dist/src/modules/onchain/wallet/types.js.map +1 -0
- package/dist/src/runner.d.ts +1 -1
- package/dist/src/runner.js +2 -2
- package/dist/src/runner.js.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -2,13 +2,38 @@
|
|
|
2
2
|
|
|
3
3
|
An open-source framework for deploying autonomous AI CEOs that run onchain businesses.
|
|
4
4
|
|
|
5
|
+
FreeTurtle gives you an AI agent that operates as your project's CEO — it posts to Farcaster, responds to mentions, writes strategy briefs, manages GitHub repos, queries databases, and chats with you via Telegram. It reads smart contracts, tracks wallet balances, and performs onchain actions: creating bounty tasks via a TaskBoard contract, funding them with ETH, reviewing submissions, and paying contributors — all autonomously. Everything it knows and does is stored as readable files (Markdown and JSON) that both you and the agent can edit. You define its identity, voice, and goals in a single `soul.md` file, set up cron schedules and tool access in `config.md`, and let it run. It modifies itself when you ask, requires your approval for anything destructive, and logs every action to an audit trail.
|
|
6
|
+
|
|
7
|
+
> **Beta software.** FreeTurtle is under active development. Expect bugs, breaking changes, and rough edges. If you run into issues, please open a GitHub issue or reach out directly.
|
|
8
|
+
|
|
9
|
+
## Contact
|
|
10
|
+
|
|
11
|
+
- **X:** [@mattleefc](https://x.com/mattleefc)
|
|
12
|
+
- **Farcaster:** [@mattlee](https://warpcast.com/mattlee)
|
|
13
|
+
|
|
5
14
|
## Getting Started
|
|
6
15
|
|
|
7
16
|
### 1. Set Up a Server
|
|
8
17
|
|
|
9
|
-
|
|
18
|
+
FreeTurtle is a long-running daemon — it needs a machine that stays on 24/7.
|
|
19
|
+
|
|
20
|
+
#### Local (recommended for getting started)
|
|
21
|
+
|
|
22
|
+
Run FreeTurtle on hardware you already own. No cloud account needed, no ongoing costs, and your data stays on your machine.
|
|
10
23
|
|
|
11
|
-
|
|
24
|
+
- **Your existing Mac or Linux machine** — just leave it running. Works great for testing or if your machine is always on.
|
|
25
|
+
- **Raspberry Pi** — a $35-80 single-board computer that runs headless, draws ~5W of power, and is perfect for always-on daemons. A Pi 4 (4GB+) or Pi 5 handles FreeTurtle easily. Install the 64-bit Raspberry Pi OS Lite, plug in ethernet, and SSH in.
|
|
26
|
+
- **Any old laptop or desktop** — install Ubuntu Server and repurpose it as a dedicated FreeTurtle box.
|
|
27
|
+
|
|
28
|
+
#### Cloud
|
|
29
|
+
|
|
30
|
+
If you want something accessible from anywhere without keeping a local machine running:
|
|
31
|
+
|
|
32
|
+
- **[Oracle Cloud](docs/oracle-cloud-setup.md)** — 2 CPUs, 12 GB RAM, always free ARM instance. Our [setup guide](docs/oracle-cloud-setup.md) walks through everything from account creation to SSH.
|
|
33
|
+
- **[Railway](https://railway.app)** — deploy from a repo or Dockerfile, easy scaling, free trial available.
|
|
34
|
+
- **[Fly.io](https://fly.io)** — runs containers close to users globally, generous free tier.
|
|
35
|
+
- **[DigitalOcean](https://digitalocean.com)** — straightforward VPS starting at $4/mo.
|
|
36
|
+
- **[Hostinger](https://hostinger.com)** — budget-friendly VPS plans.
|
|
12
37
|
|
|
13
38
|
### 2. Create Accounts for Your CEO
|
|
14
39
|
|
|
@@ -17,7 +42,7 @@ Before running init, create a separate identity for your CEO:
|
|
|
17
42
|
- **Google account** — use it to sign up for everything below
|
|
18
43
|
- **Farcaster** — the account your CEO will post from
|
|
19
44
|
- **Neynar** — API access for Farcaster (sign up at [dev.neynar.com](https://dev.neynar.com))
|
|
20
|
-
- **GitHub**
|
|
45
|
+
- **GitHub** — if your CEO will manage repos, give it its own account
|
|
21
46
|
|
|
22
47
|
The CEO is effectively a team member who needs its own accounts.
|
|
23
48
|
|
|
@@ -38,7 +63,7 @@ freeturtle init
|
|
|
38
63
|
# Start the daemon
|
|
39
64
|
freeturtle start
|
|
40
65
|
|
|
41
|
-
# Keep it running after reboot (Linux)
|
|
66
|
+
# Keep it running after reboot (macOS or Linux)
|
|
42
67
|
freeturtle install-service
|
|
43
68
|
```
|
|
44
69
|
|
|
@@ -55,20 +80,6 @@ The quickest path:
|
|
|
55
80
|
|
|
56
81
|
See the [Oracle Cloud setup guide](docs/oracle-cloud-setup.md#setting-up-webhooks-farcaster-mentionsreplies) for full instructions.
|
|
57
82
|
|
|
58
|
-
## What It Does
|
|
59
|
-
|
|
60
|
-
FreeTurtle gives you an autonomous AI CEO that:
|
|
61
|
-
|
|
62
|
-
- **Modifies itself** — updates its own identity, voice, goals, config, and memory when you ask
|
|
63
|
-
- **Posts to Farcaster** on a schedule (or on demand)
|
|
64
|
-
- **Listens for mentions** via webhooks and auto-replies
|
|
65
|
-
- **Chats with you** via Terminal or Telegram
|
|
66
|
-
- **Writes strategy briefs** weekly
|
|
67
|
-
- **Queries databases** (read-only Postgres)
|
|
68
|
-
- **Creates GitHub issues, writes code and submits pull requests**
|
|
69
|
-
- **Reads onchain data** (balances, contracts, transactions on Base)
|
|
70
|
-
- **Stores identity and memory** as readable Markdown and JSON files
|
|
71
|
-
|
|
72
83
|
## How It Works
|
|
73
84
|
|
|
74
85
|
FreeTurtle is a Node.js daemon that mostly sleeps and wakes up when:
|
|
@@ -137,8 +148,9 @@ freeturtle webhooks # Set up Neynar webhooks (mentions, replies, watche
|
|
|
137
148
|
freeturtle approvals # List pending approval requests
|
|
138
149
|
freeturtle approve <id> # Approve a pending action
|
|
139
150
|
freeturtle reject <id> # Reject a pending action
|
|
151
|
+
freeturtle health # Verify daemon is healthy
|
|
140
152
|
freeturtle update # Update to the latest version
|
|
141
|
-
freeturtle install-service # Install as a
|
|
153
|
+
freeturtle install-service # Install as a system service (launchd on macOS, systemd on Linux)
|
|
142
154
|
```
|
|
143
155
|
|
|
144
156
|
## Modules
|
|
@@ -424,7 +436,7 @@ Your `.env` file contains API keys and tokens. FreeTurtle automatically sets it
|
|
|
424
436
|
|
|
425
437
|
### Cloud Provider Access
|
|
426
438
|
|
|
427
|
-
Your cloud provider (Oracle,
|
|
439
|
+
Your cloud provider (Oracle, Railway, Fly.io, DigitalOcean, etc.) has full access to the underlying infrastructure — they can technically read any file on your VM. This is true of all cloud computing and is covered by their terms of service. For most use cases this is fine. If this is unacceptable for your threat model, run FreeTurtle on hardware you physically control (e.g. a Raspberry Pi or a spare laptop).
|
|
428
440
|
|
|
429
441
|
## The Two-Turtle Vision (v0.2)
|
|
430
442
|
|
package/dist/bin/freeturtle.js
CHANGED
|
@@ -15,14 +15,14 @@ const program = new Command();
|
|
|
15
15
|
program
|
|
16
16
|
.name("freeturtle")
|
|
17
17
|
.description("An open-source framework for deploying autonomous AI CEOs that run onchain businesses.")
|
|
18
|
-
.version("0.1.
|
|
18
|
+
.version("0.1.26");
|
|
19
19
|
program
|
|
20
20
|
.command("hello")
|
|
21
21
|
.description("Verify the CLI is working")
|
|
22
22
|
.action(() => {
|
|
23
23
|
console.log(" \x1b[38;2;94;255;164m _____ ____\x1b[0m");
|
|
24
24
|
console.log(" \x1b[38;2;94;255;164m/ \\ | o |\x1b[0m");
|
|
25
|
-
console.log(" \x1b[38;2;94;255;164m| |/ ___\\|\x1b[0m FreeTurtle v0.1.
|
|
25
|
+
console.log(" \x1b[38;2;94;255;164m| |/ ___\\|\x1b[0m FreeTurtle v0.1.26");
|
|
26
26
|
console.log(" \x1b[38;2;94;255;164m|_________/\x1b[0m");
|
|
27
27
|
console.log(" \x1b[38;2;94;255;164m|_|_| |_|_|\x1b[0m");
|
|
28
28
|
});
|
|
@@ -66,6 +66,30 @@ program
|
|
|
66
66
|
process.exit(1);
|
|
67
67
|
}
|
|
68
68
|
});
|
|
69
|
+
program
|
|
70
|
+
.command("health")
|
|
71
|
+
.description("Check daemon health")
|
|
72
|
+
.option("--dir <path>", "Workspace directory", DEFAULT_DIR)
|
|
73
|
+
.action(async (opts) => {
|
|
74
|
+
try {
|
|
75
|
+
const { ipcRequest } = await import("../src/cli/status.js");
|
|
76
|
+
const response = await ipcRequest(join(opts.dir, "daemon.sock"), "health");
|
|
77
|
+
const health = JSON.parse(response);
|
|
78
|
+
const color = health.status === "ok" ? "\x1b[32m" : "\x1b[31m";
|
|
79
|
+
console.log(`\n ${color}${health.status.toUpperCase()}\x1b[0m\n`);
|
|
80
|
+
console.log(` PID ${health.pid}`);
|
|
81
|
+
console.log(` Uptime ${Math.round(health.uptime)}s`);
|
|
82
|
+
console.log(` Memory ${health.memoryMB} MB`);
|
|
83
|
+
console.log(` Runner ${health.runner ? "ready" : "not initialized"}`);
|
|
84
|
+
console.log(` Channels ${health.channels.join(", ") || "none"}`);
|
|
85
|
+
console.log(` Heartbeat ${health.heartbeat ? "active" : "off"}`);
|
|
86
|
+
console.log();
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
console.error(err instanceof Error ? err.message : err);
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
69
93
|
program
|
|
70
94
|
.command("send <message>")
|
|
71
95
|
.description("Send a message to the running CEO")
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"freeturtle.js","sourceRoot":"","sources":["../../bin/freeturtle.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"freeturtle.js","sourceRoot":"","sources":["../../bin/freeturtle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Alpha feature gate.
|
|
3
|
+
*
|
|
4
|
+
* Set FREETURTLE_ALPHA=true in .env to enable experimental features.
|
|
5
|
+
*/
|
|
6
|
+
export function isAlpha() {
|
|
7
|
+
return process.env.FREETURTLE_ALPHA === "true";
|
|
8
|
+
}
|
|
9
|
+
export const ALPHA_REQUIRED_MSG = "This feature requires FREETURTLE_ALPHA=true in .env";
|
|
10
|
+
//# sourceMappingURL=alpha.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alpha.js","sourceRoot":"","sources":["../../src/alpha.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,UAAU,OAAO;IACrB,OAAO,OAAO,CAAC,GAAG,CAAC,gBAAgB,KAAK,MAAM,CAAC;AACjD,CAAC;AAED,MAAM,CAAC,MAAM,kBAAkB,GAC7B,qDAAqD,CAAC"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type { Channel } from "./types.js";
|
|
1
|
+
import type { Channel, MessageImage } from "./types.js";
|
|
2
2
|
export declare class TelegramChannel implements Channel {
|
|
3
3
|
name: string;
|
|
4
4
|
private bot;
|
|
5
5
|
private ownerId;
|
|
6
6
|
constructor(token: string, ownerId: number);
|
|
7
|
-
start(onMessage: (text: string) => Promise<string>): Promise<void>;
|
|
7
|
+
start(onMessage: (text: string, images?: MessageImage[]) => Promise<string>): Promise<void>;
|
|
8
8
|
send(text: string): Promise<void>;
|
|
9
9
|
stop(): Promise<void>;
|
|
10
10
|
}
|
|
@@ -8,6 +8,46 @@ export class TelegramChannel {
|
|
|
8
8
|
this.ownerId = ownerId;
|
|
9
9
|
}
|
|
10
10
|
async start(onMessage) {
|
|
11
|
+
// Handle photo messages
|
|
12
|
+
this.bot.on("message:photo", async (ctx) => {
|
|
13
|
+
const senderId = ctx.from?.id;
|
|
14
|
+
if (senderId !== this.ownerId) {
|
|
15
|
+
await ctx.reply("Sorry, I only talk to my founder.");
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
// Get the largest photo (last in array)
|
|
20
|
+
const photos = ctx.message.photo;
|
|
21
|
+
const largest = photos[photos.length - 1];
|
|
22
|
+
const file = await ctx.api.getFile(largest.file_id);
|
|
23
|
+
// Download the file as a buffer
|
|
24
|
+
const url = `https://api.telegram.org/file/bot${this.bot.token}/${file.file_path}`;
|
|
25
|
+
const res = await fetch(url);
|
|
26
|
+
if (!res.ok)
|
|
27
|
+
throw new Error(`Failed to download photo: ${res.status}`);
|
|
28
|
+
const buffer = Buffer.from(await res.arrayBuffer());
|
|
29
|
+
const base64 = buffer.toString("base64");
|
|
30
|
+
// Determine media type from file extension
|
|
31
|
+
const ext = file.file_path?.split(".").pop()?.toLowerCase() ?? "jpg";
|
|
32
|
+
const mimeMap = {
|
|
33
|
+
jpg: "image/jpeg",
|
|
34
|
+
jpeg: "image/jpeg",
|
|
35
|
+
png: "image/png",
|
|
36
|
+
gif: "image/gif",
|
|
37
|
+
webp: "image/webp",
|
|
38
|
+
};
|
|
39
|
+
const mediaType = mimeMap[ext] ?? "image/jpeg";
|
|
40
|
+
const caption = ctx.message.caption ?? "What's in this image?";
|
|
41
|
+
const images = [{ data: base64, mediaType }];
|
|
42
|
+
const response = await onMessage(caption, images);
|
|
43
|
+
await ctx.reply(response);
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
const msg = err instanceof Error ? err.message : "Unknown error";
|
|
47
|
+
await ctx.reply(`Error: ${msg}`);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
// Handle text messages
|
|
11
51
|
this.bot.on("message:text", async (ctx) => {
|
|
12
52
|
const senderId = ctx.from?.id;
|
|
13
53
|
if (senderId !== this.ownerId) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"telegram.js","sourceRoot":"","sources":["../../../src/channels/telegram.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAG7B,MAAM,OAAO,eAAe;IAC1B,IAAI,GAAG,UAAU,CAAC;IACV,GAAG,CAAM;IACT,OAAO,CAAS;IAExB,YAAY,KAAa,EAAE,OAAe;QACxC,IAAI,CAAC,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;QAC1B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"telegram.js","sourceRoot":"","sources":["../../../src/channels/telegram.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,12 @@
|
|
|
1
|
+
export interface MessageImage {
|
|
2
|
+
/** Base64-encoded image data */
|
|
3
|
+
data: string;
|
|
4
|
+
/** MIME type, e.g. "image/jpeg" */
|
|
5
|
+
mediaType: string;
|
|
6
|
+
}
|
|
1
7
|
export interface Channel {
|
|
2
8
|
name: string;
|
|
3
|
-
start(onMessage: (text: string) => Promise<string>): Promise<void>;
|
|
9
|
+
start(onMessage: (text: string, images?: MessageImage[]) => Promise<string>): Promise<void>;
|
|
4
10
|
send(text: string): Promise<void>;
|
|
5
11
|
stop(): Promise<void>;
|
|
6
12
|
}
|
|
@@ -12,7 +12,10 @@ Description=FreeTurtle AI CEO
|
|
|
12
12
|
After=network.target
|
|
13
13
|
|
|
14
14
|
[Service]
|
|
15
|
+
Type=notify
|
|
16
|
+
NotifyAccess=all
|
|
15
17
|
ExecStart=${nodePath} ${freeturtleBin} start --dir ${dir}
|
|
18
|
+
WatchdogSec=90
|
|
16
19
|
Restart=always
|
|
17
20
|
RestartSec=10
|
|
18
21
|
Environment=NODE_ENV=production
|
|
@@ -68,10 +71,13 @@ function getLaunchdPlist(dir) {
|
|
|
68
71
|
<true/>
|
|
69
72
|
|
|
70
73
|
<key>KeepAlive</key>
|
|
71
|
-
<
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
</
|
|
74
|
+
<true/>
|
|
75
|
+
|
|
76
|
+
<key>ThrottleInterval</key>
|
|
77
|
+
<integer>30</integer>
|
|
78
|
+
|
|
79
|
+
<key>ExitTimeOut</key>
|
|
80
|
+
<integer>15</integer>
|
|
75
81
|
|
|
76
82
|
<key>StandardOutPath</key>
|
|
77
83
|
<string>${logDir}/stdout.log</string>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install-service.js","sourceRoot":"","sources":["../../../src/cli/install-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,MAAM,YAAY,GAAG,YAAY,CAAC;AAElC,2EAA2E;AAE3E,SAAS,cAAc,CAAC,GAAW;IACjC,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACtE,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,yBAAyB,CAAC,CAAC,CAAC;IAEpF,OAAO
|
|
1
|
+
{"version":3,"file":"install-service.js","sourceRoot":"","sources":["../../../src/cli/install-service.ts"],"names":[],"mappings":"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"}
|
package/dist/src/cli/update.js
CHANGED
|
@@ -54,10 +54,22 @@ function stopDaemon(pid) {
|
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
function startDaemon(dir) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
// Resolve the freeturtle binary from the *newly installed* version, not the
|
|
58
|
+
// currently-running process. `which freeturtle` always returns the global
|
|
59
|
+
// bin shim, which now points to the updated package.
|
|
60
|
+
let bin;
|
|
61
|
+
try {
|
|
62
|
+
bin = execSync("which freeturtle", { encoding: "utf-8" }).trim();
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// Fallback: try resolving relative to this file (pre-update path)
|
|
66
|
+
bin = join(__dirname, "../../bin/freeturtle.js");
|
|
67
|
+
}
|
|
68
|
+
// Use spawn(…, { detached: true }) via nohup + shell to ensure the child
|
|
69
|
+
// survives after this process exits. execSync with & is unreliable because
|
|
70
|
+
// the backgrounded child can be killed when the parent shell exits.
|
|
71
|
+
const escaped = dir.replace(/'/g, "'\\''");
|
|
72
|
+
execSync(`nohup ${bin} start --dir '${escaped}' </dev/null >/dev/null 2>&1 &`, {
|
|
61
73
|
shell: "/bin/sh",
|
|
62
74
|
});
|
|
63
75
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../../src/cli/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,SAAS,oBAAoB;IAC3B,8BAA8B;IAC9B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,QAAQ,CAAC,qCAAqC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;QACpF,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC;YAAE,OAAO,MAAM,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC,CAAC,cAAc,CAAC,CAAC;IAE1B,8BAA8B;IAC9B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,QAAQ,CAAC,8BAA8B,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;QAC7E,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC;YAAE,OAAO,MAAM,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC,CAAC,cAAc,CAAC,CAAC;IAE1B,iBAAiB;IACjB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,YAAY,CAAC,GAAW;IAC/B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;QACxC,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC9D,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAC9B,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,wBAAwB;QAC9C,OAAO,GAAG,CAAC;IACb,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,GAAW;IAC7B,OAAO,CAAC,GAAG,CAAC,wBAAwB,GAAG,MAAM,CAAC,CAAC;IAC/C,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAE7B,8CAA8C;IAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC;IACrC,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YACrB,QAAQ,CAAC,WAAW,CAAC,CAAC;QACxB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,iBAAiB;QAC3B,CAAC;IACH,CAAC;IACD,8BAA8B;IAC9B,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,eAAe;IACjB,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,GAAW;IAC9B,
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../../src/cli/update.ts"],"names":[],"mappings":"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"}
|
package/dist/src/config.d.ts
CHANGED
|
@@ -13,6 +13,10 @@ export interface ModuleConfig {
|
|
|
13
13
|
enabled: boolean;
|
|
14
14
|
[key: string]: string | boolean;
|
|
15
15
|
}
|
|
16
|
+
export interface HeartbeatConfig {
|
|
17
|
+
enabled: boolean;
|
|
18
|
+
interval_minutes: number;
|
|
19
|
+
}
|
|
16
20
|
export interface FreeTurtleConfig {
|
|
17
21
|
llm: {
|
|
18
22
|
provider: string;
|
|
@@ -23,6 +27,7 @@ export interface FreeTurtleConfig {
|
|
|
23
27
|
oauth_token_env?: string;
|
|
24
28
|
[key: string]: string | number | undefined;
|
|
25
29
|
};
|
|
30
|
+
heartbeat: HeartbeatConfig;
|
|
26
31
|
cron: Record<string, CronTask>;
|
|
27
32
|
channels: Record<string, ChannelConfig>;
|
|
28
33
|
modules: Record<string, ModuleConfig>;
|
package/dist/src/config.js
CHANGED
|
@@ -19,6 +19,7 @@ function parseConfig(raw) {
|
|
|
19
19
|
const policyRaw = {};
|
|
20
20
|
const config = {
|
|
21
21
|
llm: { provider: "claude_api", model: "claude-sonnet-4-5", max_tokens: 4096 },
|
|
22
|
+
heartbeat: { enabled: true, interval_minutes: 30 },
|
|
22
23
|
cron: {},
|
|
23
24
|
channels: {},
|
|
24
25
|
modules: {},
|
|
@@ -55,6 +56,14 @@ function parseConfig(raw) {
|
|
|
55
56
|
config.llm[key] = value;
|
|
56
57
|
}
|
|
57
58
|
}
|
|
59
|
+
else if (currentSection === "heartbeat") {
|
|
60
|
+
if (key === "enabled") {
|
|
61
|
+
config.heartbeat.enabled = value === "true";
|
|
62
|
+
}
|
|
63
|
+
else if (key === "interval_minutes") {
|
|
64
|
+
config.heartbeat.interval_minutes = parseInt(value, 10);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
58
67
|
else if (currentSection === "cron" && currentSubSection) {
|
|
59
68
|
if (!config.cron[currentSubSection]) {
|
|
60
69
|
config.cron[currentSubSection] = { schedule: "", prompt: "" };
|
package/dist/src/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAqB,WAAW,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAqB,WAAW,EAAE,MAAM,aAAa,CAAC;AAyC7D,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAW;IAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IAC1C,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,IAAI,GAAG,YAAY,KAAK,IAAI,MAAM,IAAI,GAAG,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC9F,MAAM,IAAI,KAAK,CAAC,0BAA0B,UAAU,wCAAwC,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;QAChH,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;IACD,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,WAAW,CAAC,GAAW;IAC9B,MAAM,SAAS,GAAqD,EAAE,CAAC;IAEvE,MAAM,MAAM,GAAqB;QAC/B,GAAG,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE,IAAI,EAAE;QAC7E,SAAS,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE,EAAE;QAClD,IAAI,EAAE,EAAE;QACR,QAAQ,EAAE,EAAE;QACZ,OAAO,EAAE,EAAE;QACX,MAAM,EAAE,SAAoC,EAAE,oBAAoB;KACnE,CAAC;IAEF,IAAI,cAAc,GAAkB,IAAI,CAAC;IACzC,IAAI,iBAAiB,GAAkB,IAAI,CAAC;IAE5C,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAE5B,oBAAoB;QACpB,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAChD,IAAI,YAAY,EAAE,CAAC;YACjB,cAAc,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;YAC/C,iBAAiB,GAAG,IAAI,CAAC;YACzB,SAAS;QACX,CAAC;QAED,wBAAwB;QACxB,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QAC7C,IAAI,QAAQ,EAAE,CAAC;YACb,iBAAiB,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;YAC9C,SAAS;QACX,CAAC;QAED,eAAe;QACf,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;QAClD,IAAI,CAAC,OAAO,IAAI,CAAC,cAAc;YAAE,SAAS;QAE1C,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QACvB,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAEhC,IAAI,cAAc,KAAK,KAAK,EAAE,CAAC;YAC7B,IAAI,GAAG,KAAK,YAAY,EAAE,CAAC;gBACzB,MAAM,CAAC,GAAG,CAAC,UAAU,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAC9C,CAAC;iBAAM,CAAC;gBACL,MAAM,CAAC,GAAuC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YAC/D,CAAC;QACH,CAAC;aAAM,IAAI,cAAc,KAAK,WAAW,EAAE,CAAC;YAC1C,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;gBACtB,MAAM,CAAC,SAAS,CAAC,OAAO,GAAG,KAAK,KAAK,MAAM,CAAC;YAC9C,CAAC;iBAAM,IAAI,GAAG,KAAK,kBAAkB,EAAE,CAAC;gBACtC,MAAM,CAAC,SAAS,CAAC,gBAAgB,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAC1D,CAAC;QACH,CAAC;aAAM,IAAI,cAAc,KAAK,MAAM,IAAI,iBAAiB,EAAE,CAAC;YAC1D,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,EAAE,CAAC;gBACpC,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;YAChE,CAAC;YACA,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAA4B,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QAC1E,CAAC;aAAM,IAAI,cAAc,KAAK,UAAU,IAAI,iBAAiB,EAAE,CAAC;YAC9D,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC;gBACxC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;YAC1D,CAAC;YACD,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QAC9D,CAAC;aAAM,IAAI,cAAc,KAAK,SAAS,IAAI,iBAAiB,EAAE,CAAC;YAC7D,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,CAAC;gBACvC,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;YACzD,CAAC;YACD,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QAC7D,CAAC;aAAM,IAAI,cAAc,KAAK,QAAQ,IAAI,iBAAiB,EAAE,CAAC;YAC5D,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,EAAE,CAAC;gBAClC,SAAS,CAAC,iBAAiB,CAAC,GAAG,EAAE,CAAC;YACpC,CAAC;YACD,SAAS,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;IAED,MAAM,CAAC,MAAM,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC;IACvC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,UAAU,CAAC,KAAa;IAC/B,IAAI,KAAK,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IAClC,IAAI,KAAK,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC;IACpC,OAAO,KAAK,CAAC;AACf,CAAC"}
|
package/dist/src/daemon.d.ts
CHANGED
|
@@ -11,6 +11,8 @@ export declare class FreeTurtleDaemon {
|
|
|
11
11
|
private runner?;
|
|
12
12
|
private ipcServer?;
|
|
13
13
|
private webhookServer?;
|
|
14
|
+
private shuttingDown;
|
|
15
|
+
private watchdogTimer?;
|
|
14
16
|
constructor(dir: string, options?: DaemonOptions);
|
|
15
17
|
start(): Promise<void>;
|
|
16
18
|
stop(): Promise<void>;
|
package/dist/src/daemon.js
CHANGED
|
@@ -15,6 +15,9 @@ import { createLogger } from "./logger.js";
|
|
|
15
15
|
import { refreshOpenAIAccessToken } from "./oauth/openai.js";
|
|
16
16
|
import { loadOpenAICodexProfile, saveOpenAICodexProfile, } from "./oauth/store.js";
|
|
17
17
|
function isTransientNetworkError(err) {
|
|
18
|
+
// AbortError from fetch() during shutdown
|
|
19
|
+
if (err.name === "AbortError")
|
|
20
|
+
return true;
|
|
18
21
|
const msg = err.message.toLowerCase();
|
|
19
22
|
const cause = err.cause instanceof Error ? err.cause.message.toLowerCase() : "";
|
|
20
23
|
const patterns = [
|
|
@@ -39,6 +42,8 @@ export class FreeTurtleDaemon {
|
|
|
39
42
|
runner;
|
|
40
43
|
ipcServer;
|
|
41
44
|
webhookServer;
|
|
45
|
+
shuttingDown = false;
|
|
46
|
+
watchdogTimer;
|
|
42
47
|
constructor(dir, options = {}) {
|
|
43
48
|
this.dir = dir;
|
|
44
49
|
this.options = options;
|
|
@@ -105,19 +110,25 @@ export class FreeTurtleDaemon {
|
|
|
105
110
|
this.scheduler.start();
|
|
106
111
|
}
|
|
107
112
|
// Start heartbeat — send alerts to all active channels
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
113
|
+
if (config.heartbeat.enabled) {
|
|
114
|
+
this.heartbeat = new Heartbeat(this.runner, this.logger, {
|
|
115
|
+
intervalMs: config.heartbeat.interval_minutes * 60 * 1000,
|
|
116
|
+
onAlert: (msg) => {
|
|
117
|
+
for (const ch of this.channels) {
|
|
118
|
+
ch.send(msg).catch((err) => {
|
|
119
|
+
this.logger.error(`Failed to send alert via ${ch.name}: ${err}`);
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
this.heartbeat.start();
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
this.logger.info("Heartbeat disabled in config");
|
|
128
|
+
}
|
|
118
129
|
// Start channels
|
|
119
|
-
const onMessage = async (text) => {
|
|
120
|
-
return this.runner.runMessage(text, "channel");
|
|
130
|
+
const onMessage = async (text, images) => {
|
|
131
|
+
return this.runner.runMessage(text, "channel", images);
|
|
121
132
|
};
|
|
122
133
|
if (this.options.chat) {
|
|
123
134
|
const terminal = new TerminalChannel();
|
|
@@ -164,6 +175,7 @@ export class FreeTurtleDaemon {
|
|
|
164
175
|
await this.startIpc();
|
|
165
176
|
// Signal handlers
|
|
166
177
|
const shutdown = async () => {
|
|
178
|
+
this.shuttingDown = true;
|
|
167
179
|
this.logger.info("Shutting down...");
|
|
168
180
|
await this.stop();
|
|
169
181
|
process.exit(0);
|
|
@@ -171,6 +183,9 @@ export class FreeTurtleDaemon {
|
|
|
171
183
|
process.on("SIGINT", () => { shutdown().catch((e) => this.logger.error(`Shutdown error: ${e}`)); });
|
|
172
184
|
process.on("SIGTERM", () => { shutdown().catch((e) => this.logger.error(`Shutdown error: ${e}`)); });
|
|
173
185
|
process.on("uncaughtException", (err) => {
|
|
186
|
+
// Suppress all errors during shutdown (pending fetches, torn-down resources)
|
|
187
|
+
if (this.shuttingDown)
|
|
188
|
+
return;
|
|
174
189
|
if (isTransientNetworkError(err)) {
|
|
175
190
|
this.logger.warn(`Transient network error (ignored): ${err.message}`);
|
|
176
191
|
return;
|
|
@@ -178,6 +193,8 @@ export class FreeTurtleDaemon {
|
|
|
178
193
|
this.logger.error(`Uncaught exception: ${err.message}`);
|
|
179
194
|
});
|
|
180
195
|
process.on("unhandledRejection", (reason) => {
|
|
196
|
+
if (this.shuttingDown)
|
|
197
|
+
return;
|
|
181
198
|
const err = reason instanceof Error ? reason : new Error(String(reason));
|
|
182
199
|
if (isTransientNetworkError(err)) {
|
|
183
200
|
this.logger.warn(`Transient network error (ignored): ${err.message}`);
|
|
@@ -209,10 +226,34 @@ export class FreeTurtleDaemon {
|
|
|
209
226
|
\x1b[2mfreeturtle send "message" — talk to your CEO\x1b[0m
|
|
210
227
|
\x1b[2mfreeturtle start --chat — interactive mode\x1b[0m
|
|
211
228
|
\x1b[2mfreeturtle status — check on things\x1b[0m
|
|
229
|
+
\x1b[2mfreeturtle health — verify daemon is healthy\x1b[0m
|
|
212
230
|
\x1b[2mCtrl+C — stop\x1b[0m
|
|
213
231
|
`);
|
|
232
|
+
// systemd watchdog integration (Linux only)
|
|
233
|
+
// Sends READY=1 on startup and WATCHDOG=1 every 30s via the NOTIFY_SOCKET.
|
|
234
|
+
// WatchdogSec=90 in the unit file means 3 missed pings trigger a restart.
|
|
235
|
+
if (process.platform === "linux" && process.env.NOTIFY_SOCKET) {
|
|
236
|
+
try {
|
|
237
|
+
const notifySocket = process.env.NOTIFY_SOCKET;
|
|
238
|
+
const sendSdNotify = (msg) => {
|
|
239
|
+
const conn = net.createConnection({ path: notifySocket }, () => {
|
|
240
|
+
conn.end(msg);
|
|
241
|
+
});
|
|
242
|
+
conn.on("error", () => { }); // ignore errors
|
|
243
|
+
};
|
|
244
|
+
sendSdNotify("READY=1");
|
|
245
|
+
this.watchdogTimer = setInterval(() => sendSdNotify("WATCHDOG=1"), 30_000);
|
|
246
|
+
this.watchdogTimer.unref();
|
|
247
|
+
this.logger.info("systemd watchdog active (30s interval)");
|
|
248
|
+
}
|
|
249
|
+
catch {
|
|
250
|
+
this.logger.warn("Failed to initialize systemd watchdog");
|
|
251
|
+
}
|
|
252
|
+
}
|
|
214
253
|
}
|
|
215
254
|
async stop() {
|
|
255
|
+
if (this.watchdogTimer)
|
|
256
|
+
clearInterval(this.watchdogTimer);
|
|
216
257
|
this.scheduler?.stop();
|
|
217
258
|
this.heartbeat?.stop();
|
|
218
259
|
for (const ch of this.channels) {
|
|
@@ -274,6 +315,22 @@ export class FreeTurtleDaemon {
|
|
|
274
315
|
};
|
|
275
316
|
return JSON.stringify(status, null, 2);
|
|
276
317
|
}
|
|
318
|
+
if (command === "health") {
|
|
319
|
+
const health = {
|
|
320
|
+
status: "ok",
|
|
321
|
+
pid: process.pid,
|
|
322
|
+
uptime: process.uptime(),
|
|
323
|
+
memoryMB: Math.round(process.memoryUsage().rss / 1024 / 1024),
|
|
324
|
+
runner: !!this.runner,
|
|
325
|
+
channels: this.channels.map((c) => c.name),
|
|
326
|
+
scheduler: this.scheduler?.getStatus() ?? null,
|
|
327
|
+
heartbeat: !!this.heartbeat,
|
|
328
|
+
timestamp: new Date().toISOString(),
|
|
329
|
+
};
|
|
330
|
+
if (!this.runner)
|
|
331
|
+
health.status = "degraded";
|
|
332
|
+
return JSON.stringify(health, null, 2);
|
|
333
|
+
}
|
|
277
334
|
if (command.startsWith("send ")) {
|
|
278
335
|
const message = command.slice(5);
|
|
279
336
|
if (!this.runner)
|