@tractorscorch/clank 1.4.1 → 1.4.4
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/CHANGELOG.md +223 -205
- package/README.md +189 -172
- package/dist/index.js +36 -20
- package/dist/index.js.map +1 -1
- package/package.json +58 -58
package/README.md
CHANGED
|
@@ -1,172 +1,189 @@
|
|
|
1
|
-
<p align="center">
|
|
2
|
-
<img src="https://raw.githubusercontent.com/ItsTrag1c/Clank/main/docs/banner.png" alt="Clank" width="100%" />
|
|
3
|
-
</p>
|
|
4
|
-
|
|
5
|
-
<h1 align="center">Clank</h1>
|
|
6
|
-
|
|
7
|
-
<p align="center">
|
|
8
|
-
<b>Local-first AI agent gateway.</b> Open-source alternative to OpenClaw, optimized for local models.
|
|
9
|
-
</p>
|
|
10
|
-
|
|
11
|
-
<p align="center">
|
|
12
|
-
<a href="https://github.com/ItsTrag1c/Clank/releases/latest"><img src="https://img.shields.io/badge/version-1.
|
|
13
|
-
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License" /></a>
|
|
14
|
-
<a href="https://www.npmjs.com/package/@tractorscorch/clank"><img src="https://img.shields.io/npm/v/@tractorscorch/clank.svg" alt="npm" /></a>
|
|
15
|
-
<a href="https://github.com/ItsTrag1c/Clank/stargazers"><img src="https://img.shields.io/github/stars/ItsTrag1c/Clank.svg" alt="Stars" /></a>
|
|
16
|
-
</p>
|
|
17
|
-
|
|
18
|
-
<p align="center">
|
|
19
|
-
<a href="https://clanksuite.dev">Website</a> ·
|
|
20
|
-
<a href="https://github.com/ItsTrag1c/Clank/blob/main/docs/INSTALL.md">Install Guide</a> ·
|
|
21
|
-
<a href="https://github.com/ItsTrag1c/Clank/blob/main/docs/USER_GUIDE.md">User Guide</a> ·
|
|
22
|
-
<a href="https://github.com/ItsTrag1c/Clank/blob/main/CHANGELOG.md">Changelog</a> ·
|
|
23
|
-
<a href="https://x.com/ClankSuite">Twitter</a> ·
|
|
24
|
-
<a href="https://reddit.com/u/ClankSuite">Reddit</a>
|
|
25
|
-
</p>
|
|
26
|
-
|
|
27
|
-
---
|
|
28
|
-
|
|
29
|
-
## What is Clank?
|
|
30
|
-
|
|
31
|
-
Clank is a personal AI gateway — **one daemon, many frontends**. It connects your preferred interfaces (CLI, TUI, browser, Telegram, Discord) to AI agents running local or cloud models. All interfaces share sessions, memory, and agent state.
|
|
32
|
-
|
|
33
|
-
**Built for people who want the OpenClaw experience without the token costs.**
|
|
34
|
-
|
|
35
|
-
```
|
|
36
|
-
┌─────────────────────────────┐
|
|
37
|
-
│ Clank Gateway │
|
|
38
|
-
│ (single daemon) │
|
|
39
|
-
│ │
|
|
40
|
-
│ Agent Pool + Routing │
|
|
41
|
-
│ Sessions, Memory, Pipelines │
|
|
42
|
-
│ Cron, Tools, Plugins │
|
|
43
|
-
└──────────────┬───────────────┘
|
|
44
|
-
│
|
|
45
|
-
WebSocket + HTTP (port 18790)
|
|
46
|
-
│
|
|
47
|
-
┌──────────┬───────────┼───────────┬──────────┐
|
|
48
|
-
│ │ │ │ │
|
|
49
|
-
CLI Web UI Telegram Discord TUI
|
|
50
|
-
(direct) (browser) (bot) (bot) (terminal)
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
## Quick Start
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
clank
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
|
76
|
-
|
|
77
|
-
| **
|
|
78
|
-
| **
|
|
79
|
-
|
|
80
|
-
##
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
clank
|
|
105
|
-
clank
|
|
106
|
-
clank
|
|
107
|
-
clank
|
|
108
|
-
|
|
109
|
-
#
|
|
110
|
-
clank
|
|
111
|
-
clank
|
|
112
|
-
|
|
113
|
-
#
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
clank
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
-
|
|
168
|
-
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/ItsTrag1c/Clank/main/docs/banner.png" alt="Clank" width="100%" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">Clank</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<b>Local-first AI agent gateway.</b> Open-source alternative to OpenClaw, optimized for local models.
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<a href="https://github.com/ItsTrag1c/Clank/releases/latest"><img src="https://img.shields.io/badge/version-1.4.4-blue.svg" alt="Version" /></a>
|
|
13
|
+
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License" /></a>
|
|
14
|
+
<a href="https://www.npmjs.com/package/@tractorscorch/clank"><img src="https://img.shields.io/npm/v/@tractorscorch/clank.svg" alt="npm" /></a>
|
|
15
|
+
<a href="https://github.com/ItsTrag1c/Clank/stargazers"><img src="https://img.shields.io/github/stars/ItsTrag1c/Clank.svg" alt="Stars" /></a>
|
|
16
|
+
</p>
|
|
17
|
+
|
|
18
|
+
<p align="center">
|
|
19
|
+
<a href="https://clanksuite.dev">Website</a> ·
|
|
20
|
+
<a href="https://github.com/ItsTrag1c/Clank/blob/main/docs/INSTALL.md">Install Guide</a> ·
|
|
21
|
+
<a href="https://github.com/ItsTrag1c/Clank/blob/main/docs/USER_GUIDE.md">User Guide</a> ·
|
|
22
|
+
<a href="https://github.com/ItsTrag1c/Clank/blob/main/CHANGELOG.md">Changelog</a> ·
|
|
23
|
+
<a href="https://x.com/ClankSuite">Twitter</a> ·
|
|
24
|
+
<a href="https://reddit.com/u/ClankSuite">Reddit</a>
|
|
25
|
+
</p>
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## What is Clank?
|
|
30
|
+
|
|
31
|
+
Clank is a personal AI gateway — **one daemon, many frontends**. It connects your preferred interfaces (CLI, TUI, browser, Telegram, Discord) to AI agents running local or cloud models. All interfaces share sessions, memory, and agent state.
|
|
32
|
+
|
|
33
|
+
**Built for people who want the OpenClaw experience without the token costs.**
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
┌─────────────────────────────┐
|
|
37
|
+
│ Clank Gateway │
|
|
38
|
+
│ (single daemon) │
|
|
39
|
+
│ │
|
|
40
|
+
│ Agent Pool + Routing │
|
|
41
|
+
│ Sessions, Memory, Pipelines │
|
|
42
|
+
│ Cron, Tools, Plugins │
|
|
43
|
+
└──────────────┬───────────────┘
|
|
44
|
+
│
|
|
45
|
+
WebSocket + HTTP (port 18790)
|
|
46
|
+
│
|
|
47
|
+
┌──────────┬───────────┼───────────┬──────────┐
|
|
48
|
+
│ │ │ │ │
|
|
49
|
+
CLI Web UI Telegram Discord TUI
|
|
50
|
+
(direct) (browser) (bot) (bot) (terminal)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Quick Start
|
|
54
|
+
|
|
55
|
+
### npm (all platforms)
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
npm install -g @tractorscorch/clank
|
|
59
|
+
clank setup
|
|
60
|
+
clank
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### macOS (standalone binary)
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
curl -fsSL https://raw.githubusercontent.com/ItsTrag1c/Clank/main/install.sh | bash
|
|
67
|
+
clank setup
|
|
68
|
+
clank
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
That's it. Setup auto-detects your local models, configures the gateway, and gets you chatting in under 2 minutes. See the [full install guide](docs/INSTALL.md) for details.
|
|
72
|
+
|
|
73
|
+
### Downloads
|
|
74
|
+
|
|
75
|
+
| Platform | Download |
|
|
76
|
+
|----------|----------|
|
|
77
|
+
| **npm** (all platforms) | `npm install -g @tractorscorch/clank` |
|
|
78
|
+
| **macOS** (Apple Silicon) | [Clank_1.4.4_macos](https://github.com/ItsTrag1c/Clank/releases/latest/download/Clank_1.4.4_macos) |
|
|
79
|
+
|
|
80
|
+
## Features
|
|
81
|
+
|
|
82
|
+
| Feature | Description |
|
|
83
|
+
|---------|-------------|
|
|
84
|
+
| **Local-first** | Auto-detects Ollama, LM Studio, llama.cpp, vLLM. Cloud providers optional. |
|
|
85
|
+
| **Multi-agent** | Named agents with separate models, workspaces, tools, and routing. |
|
|
86
|
+
| **Multi-channel** | CLI, TUI, Web UI, Telegram, Discord — all equal, all share sessions. |
|
|
87
|
+
| **Self-configuring** | After setup, configure everything through conversation. |
|
|
88
|
+
| **18 tools** | File ops, bash, git, web search (Brave), plus 8 self-config tools. |
|
|
89
|
+
| **Web Control UI** | 8-panel dashboard: Chat, Agents, Sessions, Config, Pipelines, Cron, Logs, Channels. |
|
|
90
|
+
| **Pipeline orchestration** | Chain agents together for multi-step workflows. |
|
|
91
|
+
| **Plugin system** | Extend with custom tools, channels, and providers. 25+ hook types. |
|
|
92
|
+
| **Cron scheduler** | Recurring and one-shot scheduled agent tasks. |
|
|
93
|
+
| **Voice** | Cloud (ElevenLabs) or fully local (whisper.cpp + piper). |
|
|
94
|
+
| **Memory** | TF-IDF with decay scoring. Agent learns and remembers across sessions. |
|
|
95
|
+
| **Security** | AES-256-GCM encryption, SSRF protection, path containment, config redaction. |
|
|
96
|
+
|
|
97
|
+
## Commands
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
# Start — gateway + TUI (Telegram/Discord stay alive in background)
|
|
101
|
+
clank
|
|
102
|
+
|
|
103
|
+
# Chat interfaces
|
|
104
|
+
clank chat # Direct mode (no gateway needed)
|
|
105
|
+
clank chat --web # Auto-start gateway + open Web UI
|
|
106
|
+
clank tui # Rich TUI connected to gateway
|
|
107
|
+
clank dashboard # Open Web UI in browser
|
|
108
|
+
|
|
109
|
+
# Gateway
|
|
110
|
+
clank gateway start # Start in background
|
|
111
|
+
clank gateway stop # Stop
|
|
112
|
+
clank gateway status # Show status, clients, sessions
|
|
113
|
+
clank gateway restart # Restart
|
|
114
|
+
|
|
115
|
+
# Setup & diagnostics
|
|
116
|
+
clank setup # Onboarding wizard
|
|
117
|
+
clank fix # Diagnostics & auto-repair
|
|
118
|
+
|
|
119
|
+
# Model & agent management
|
|
120
|
+
clank models list # Detect + list models
|
|
121
|
+
clank models add # Add a provider (Anthropic, OpenAI, Google, Brave)
|
|
122
|
+
clank models test # Test connectivity
|
|
123
|
+
clank agents list # List agents
|
|
124
|
+
clank agents add # Create an agent
|
|
125
|
+
|
|
126
|
+
# Scheduled tasks
|
|
127
|
+
clank cron list # List jobs
|
|
128
|
+
clank cron add # Schedule a task
|
|
129
|
+
|
|
130
|
+
# System
|
|
131
|
+
clank daemon install # Auto-start at login (Windows/macOS/Linux)
|
|
132
|
+
clank channels # Channel status
|
|
133
|
+
clank uninstall # Remove everything
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Providers
|
|
137
|
+
|
|
138
|
+
| Provider | Type | How |
|
|
139
|
+
|----------|------|-----|
|
|
140
|
+
| **Ollama** | Local | Auto-detected at `localhost:11434` |
|
|
141
|
+
| **LM Studio** | Local | Auto-detected at `localhost:1234` |
|
|
142
|
+
| **llama.cpp** | Local | Auto-detected at `localhost:8080` |
|
|
143
|
+
| **vLLM** | Local | Auto-detected at `localhost:8000` |
|
|
144
|
+
| **Anthropic** | Cloud | API key via `clank setup` or config |
|
|
145
|
+
| **OpenAI** | Cloud | API key via `clank setup` or config |
|
|
146
|
+
| **Google Gemini** | Cloud | API key via `clank setup` or config |
|
|
147
|
+
|
|
148
|
+
Models without native tool calling automatically use prompt-based fallback — tools are injected into the system prompt and parsed from text output.
|
|
149
|
+
|
|
150
|
+
## Security
|
|
151
|
+
|
|
152
|
+
Clank is designed to be safe by default:
|
|
153
|
+
|
|
154
|
+
- **Workspace containment** — file tools blocked outside workspace
|
|
155
|
+
- **Bash protection** — 25-pattern blocklist for destructive commands
|
|
156
|
+
- **API key redaction** — keys never sent to LLM context
|
|
157
|
+
- **SSRF protection** — web_fetch blocks localhost, cloud metadata, internal hosts
|
|
158
|
+
- **Gateway auth** — token-based, auto-generated, localhost-only by default
|
|
159
|
+
- **Encryption** — AES-256-GCM for API keys at rest
|
|
160
|
+
|
|
161
|
+
See [SECURITY.md](SECURITY.md) for the full security model.
|
|
162
|
+
|
|
163
|
+
## Documentation
|
|
164
|
+
|
|
165
|
+
- **[Install Guide](docs/INSTALL.md)** — Detailed installation and setup instructions
|
|
166
|
+
- **[User Guide](docs/USER_GUIDE.md)** — How to use Clank day-to-day
|
|
167
|
+
- **[Changelog](CHANGELOG.md)** — Version history
|
|
168
|
+
- **[Privacy Policy](PRIVACY_POLICY.md)** — Data handling
|
|
169
|
+
- **[Security Policy](SECURITY.md)** — Security model and vulnerability reporting
|
|
170
|
+
|
|
171
|
+
## Links
|
|
172
|
+
|
|
173
|
+
| | |
|
|
174
|
+
|--|--|
|
|
175
|
+
| **Website** | [clanksuite.dev](https://clanksuite.dev) |
|
|
176
|
+
| **GitHub** | [ItsTrag1c/Clank](https://github.com/ItsTrag1c/Clank) |
|
|
177
|
+
| **npm** | [npmjs.com/package/@tractorscorch/clank](https://www.npmjs.com/package/@tractorscorch/clank) |
|
|
178
|
+
| **Twitter/X** | [@ClankSuite](https://x.com/ClankSuite) |
|
|
179
|
+
| **Reddit** | [u/ClankSuite](https://reddit.com/u/ClankSuite) |
|
|
180
|
+
| **Legacy** | [Clank-Legacy](https://github.com/ItsTrag1c/Clank-Legacy) (archived CLI v2.7.0 + Desktop v2.6.1) |
|
|
181
|
+
|
|
182
|
+
## Requirements
|
|
183
|
+
|
|
184
|
+
- Node.js 20+
|
|
185
|
+
- A local model server (Ollama recommended) or cloud API key
|
|
186
|
+
|
|
187
|
+
## License
|
|
188
|
+
|
|
189
|
+
MIT — see [LICENSE](LICENSE)
|
package/dist/index.js
CHANGED
|
@@ -764,6 +764,7 @@ var init_agent = __esm({
|
|
|
764
764
|
alwaysApproved = /* @__PURE__ */ new Set();
|
|
765
765
|
constructor(opts) {
|
|
766
766
|
super();
|
|
767
|
+
this.setMaxListeners(30);
|
|
767
768
|
this.identity = opts.identity;
|
|
768
769
|
this.toolRegistry = opts.toolRegistry;
|
|
769
770
|
this.sessionStore = opts.sessionStore;
|
|
@@ -4480,14 +4481,15 @@ async function runChat(opts) {
|
|
|
4480
4481
|
}
|
|
4481
4482
|
if (!gatewayRunning) {
|
|
4482
4483
|
console.log(dim("Starting gateway..."));
|
|
4483
|
-
const {
|
|
4484
|
+
const { spawn } = await import("child_process");
|
|
4484
4485
|
const { fileURLToPath: fileURLToPath6 } = await import("url");
|
|
4485
4486
|
const { dirname: dirname6, join: join20 } = await import("path");
|
|
4486
4487
|
const __filename4 = fileURLToPath6(import.meta.url);
|
|
4487
4488
|
const entryPoint = join20(dirname6(__filename4), "index.js");
|
|
4488
|
-
const child =
|
|
4489
|
+
const child = spawn(process.execPath, [entryPoint, "gateway", "start", "--foreground"], {
|
|
4489
4490
|
detached: true,
|
|
4490
|
-
stdio: "ignore"
|
|
4491
|
+
stdio: "ignore",
|
|
4492
|
+
windowsHide: true
|
|
4491
4493
|
});
|
|
4492
4494
|
child.unref();
|
|
4493
4495
|
for (let i = 0; i < 20; i++) {
|
|
@@ -4510,9 +4512,9 @@ async function runChat(opts) {
|
|
|
4510
4512
|
const url = `http://127.0.0.1:${port}/#token=${token}`;
|
|
4511
4513
|
console.log(dim(`Opening ${url}`));
|
|
4512
4514
|
const { platform: platform5 } = await import("os");
|
|
4513
|
-
const { exec
|
|
4515
|
+
const { exec } = await import("child_process");
|
|
4514
4516
|
const openCmd = platform5() === "win32" ? `start "" "${url}"` : platform5() === "darwin" ? `open "${url}"` : `xdg-open "${url}"`;
|
|
4515
|
-
|
|
4517
|
+
exec(openCmd);
|
|
4516
4518
|
console.log(green("Web UI opened in browser."));
|
|
4517
4519
|
return;
|
|
4518
4520
|
}
|
|
@@ -5226,6 +5228,7 @@ var init_telegram = __esm({
|
|
|
5226
5228
|
try {
|
|
5227
5229
|
await ctx.api.sendChatAction(chatId, "typing");
|
|
5228
5230
|
let streamMsgId = null;
|
|
5231
|
+
let sendingInitial = false;
|
|
5229
5232
|
let accumulated = "";
|
|
5230
5233
|
let lastEditTime = 0;
|
|
5231
5234
|
const EDIT_INTERVAL = 800;
|
|
@@ -5240,7 +5243,8 @@ var init_telegram = __esm({
|
|
|
5240
5243
|
onToken: (content) => {
|
|
5241
5244
|
accumulated += content;
|
|
5242
5245
|
const now = Date.now();
|
|
5243
|
-
if (!streamMsgId && accumulated.length > 20) {
|
|
5246
|
+
if (!streamMsgId && !sendingInitial && accumulated.length > 20) {
|
|
5247
|
+
sendingInitial = true;
|
|
5244
5248
|
bot.api.sendMessage(chatId, accumulated + " \u258D").then((sent) => {
|
|
5245
5249
|
streamMsgId = sent.message_id;
|
|
5246
5250
|
lastEditTime = now;
|
|
@@ -6053,7 +6057,7 @@ var init_server = __esm({
|
|
|
6053
6057
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
6054
6058
|
res.end(JSON.stringify({
|
|
6055
6059
|
status: "ok",
|
|
6056
|
-
version: "1.4.
|
|
6060
|
+
version: "1.4.4",
|
|
6057
6061
|
uptime: process.uptime(),
|
|
6058
6062
|
clients: this.clients.size,
|
|
6059
6063
|
agents: this.engines.size
|
|
@@ -6161,7 +6165,7 @@ var init_server = __esm({
|
|
|
6161
6165
|
const hello = {
|
|
6162
6166
|
type: "hello",
|
|
6163
6167
|
protocol: PROTOCOL_VERSION,
|
|
6164
|
-
version: "1.4.
|
|
6168
|
+
version: "1.4.4",
|
|
6165
6169
|
agents: this.config.agents.list.map((a) => ({
|
|
6166
6170
|
id: a.id,
|
|
6167
6171
|
name: a.name || a.id,
|
|
@@ -6360,6 +6364,13 @@ var init_server = __esm({
|
|
|
6360
6364
|
const recent = timestamps.filter((t) => now - t < this.RATE_LIMIT_WINDOW);
|
|
6361
6365
|
recent.push(now);
|
|
6362
6366
|
this.rateLimiter.set(sessionKey, recent);
|
|
6367
|
+
if (this.rateLimiter.size > 100) {
|
|
6368
|
+
for (const [key, ts] of this.rateLimiter) {
|
|
6369
|
+
if (ts.length === 0 || now - ts[ts.length - 1] > this.RATE_LIMIT_WINDOW * 2) {
|
|
6370
|
+
this.rateLimiter.delete(key);
|
|
6371
|
+
}
|
|
6372
|
+
}
|
|
6373
|
+
}
|
|
6363
6374
|
return recent.length > this.RATE_LIMIT_MAX;
|
|
6364
6375
|
}
|
|
6365
6376
|
/** Cancel current request for a client */
|
|
@@ -6445,7 +6456,6 @@ var init_server = __esm({
|
|
|
6445
6456
|
}
|
|
6446
6457
|
const confirmId = `confirm_${Date.now()}`;
|
|
6447
6458
|
this.sendEvent(client, "confirm-needed", { id: confirmId, actions });
|
|
6448
|
-
const timeout = setTimeout(() => resolve4(false), 3e4);
|
|
6449
6459
|
const resolveHandler = (raw) => {
|
|
6450
6460
|
const frame = parseFrame(raw.toString());
|
|
6451
6461
|
if (frame?.type === "req" && frame.method === "confirm.resolve") {
|
|
@@ -6458,6 +6468,10 @@ var init_server = __esm({
|
|
|
6458
6468
|
}
|
|
6459
6469
|
};
|
|
6460
6470
|
client.ws.on("message", resolveHandler);
|
|
6471
|
+
const timeout = setTimeout(() => {
|
|
6472
|
+
client.ws.removeListener("message", resolveHandler);
|
|
6473
|
+
resolve4(false);
|
|
6474
|
+
}, 3e4);
|
|
6461
6475
|
};
|
|
6462
6476
|
engine.on("confirm-needed", confirmListener);
|
|
6463
6477
|
listeners.push(["confirm-needed", confirmListener]);
|
|
@@ -6508,7 +6522,6 @@ __export(gateway_cmd_exports, {
|
|
|
6508
6522
|
gatewayStop: () => gatewayStop,
|
|
6509
6523
|
isGatewayRunning: () => isGatewayRunning
|
|
6510
6524
|
});
|
|
6511
|
-
import { fork } from "child_process";
|
|
6512
6525
|
import { writeFile as writeFile8, readFile as readFile12, unlink as unlink3 } from "fs/promises";
|
|
6513
6526
|
import { existsSync as existsSync9 } from "fs";
|
|
6514
6527
|
import { join as join15, dirname as dirname3 } from "path";
|
|
@@ -6570,15 +6583,18 @@ async function gatewayStartBackground() {
|
|
|
6570
6583
|
}
|
|
6571
6584
|
console.log(dim2(" Starting gateway in background..."));
|
|
6572
6585
|
const entryPoint = join15(dirname3(__filename2), "index.js");
|
|
6573
|
-
const logFile = join15(getConfigDir(), "logs", "gateway.log");
|
|
6574
6586
|
const { mkdir: mkdir7 } = await import("fs/promises");
|
|
6587
|
+
const { spawn } = await import("child_process");
|
|
6588
|
+
const { openSync } = await import("fs");
|
|
6575
6589
|
await mkdir7(join15(getConfigDir(), "logs"), { recursive: true });
|
|
6576
|
-
const
|
|
6590
|
+
const logFile = join15(getConfigDir(), "logs", "gateway.log");
|
|
6591
|
+
const logFd = openSync(logFile, "a");
|
|
6592
|
+
const child = spawn(process.execPath, [entryPoint, "gateway", "start", "--foreground"], {
|
|
6577
6593
|
detached: true,
|
|
6578
|
-
stdio: ["ignore",
|
|
6594
|
+
stdio: ["ignore", logFd, logFd],
|
|
6595
|
+
windowsHide: true
|
|
6579
6596
|
});
|
|
6580
6597
|
child.unref();
|
|
6581
|
-
child.disconnect();
|
|
6582
6598
|
for (let i = 0; i < 20; i++) {
|
|
6583
6599
|
await new Promise((r) => setTimeout(r, 500));
|
|
6584
6600
|
if (await isGatewayRunning(port)) {
|
|
@@ -7543,7 +7559,7 @@ async function runTui(opts) {
|
|
|
7543
7559
|
ws.on("open", () => {
|
|
7544
7560
|
ws.send(JSON.stringify({
|
|
7545
7561
|
type: "connect",
|
|
7546
|
-
params: { auth: { token }, mode: "tui", version: "1.4.
|
|
7562
|
+
params: { auth: { token }, mode: "tui", version: "1.4.4" }
|
|
7547
7563
|
}));
|
|
7548
7564
|
});
|
|
7549
7565
|
ws.on("message", (data) => {
|
|
@@ -7845,14 +7861,14 @@ async function runUpdate() {
|
|
|
7845
7861
|
}
|
|
7846
7862
|
console.log(dim9(" Pulling latest version..."));
|
|
7847
7863
|
try {
|
|
7848
|
-
const output = execSync2("npm install -g @tractorscorch/clank@latest", {
|
|
7864
|
+
const output = execSync2("npm install -g @tractorscorch/clank@latest --force", {
|
|
7849
7865
|
encoding: "utf-8",
|
|
7850
7866
|
timeout: 12e4
|
|
7851
7867
|
});
|
|
7852
7868
|
console.log(dim9(` ${output.trim()}`));
|
|
7853
7869
|
} catch (err) {
|
|
7854
7870
|
console.error(red6(` Update failed: ${err instanceof Error ? err.message : err}`));
|
|
7855
|
-
console.error(dim9(" Try manually: npm install -g @tractorscorch/clank@latest"));
|
|
7871
|
+
console.error(dim9(" Try manually: npm install -g @tractorscorch/clank@latest --force"));
|
|
7856
7872
|
return;
|
|
7857
7873
|
}
|
|
7858
7874
|
try {
|
|
@@ -7972,7 +7988,7 @@ import { fileURLToPath as fileURLToPath5 } from "url";
|
|
|
7972
7988
|
import { dirname as dirname5, join as join19 } from "path";
|
|
7973
7989
|
var __filename3 = fileURLToPath5(import.meta.url);
|
|
7974
7990
|
var __dirname3 = dirname5(__filename3);
|
|
7975
|
-
var version = "1.4.
|
|
7991
|
+
var version = "1.4.4";
|
|
7976
7992
|
try {
|
|
7977
7993
|
const pkg = JSON.parse(readFileSync(join19(__dirname3, "..", "package.json"), "utf-8"));
|
|
7978
7994
|
version = pkg.version;
|
|
@@ -8065,9 +8081,9 @@ program.command("dashboard").description("Open the Web UI in your browser").opti
|
|
|
8065
8081
|
`);
|
|
8066
8082
|
if (opts.open !== false) {
|
|
8067
8083
|
const { platform: platform5 } = await import("os");
|
|
8068
|
-
const { exec
|
|
8084
|
+
const { exec } = await import("child_process");
|
|
8069
8085
|
const cmd = platform5() === "win32" ? `start ${url}` : platform5() === "darwin" ? `open ${url}` : `xdg-open ${url}`;
|
|
8070
|
-
|
|
8086
|
+
exec(cmd);
|
|
8071
8087
|
}
|
|
8072
8088
|
});
|
|
8073
8089
|
var pipeline = program.command("pipeline").description("Manage agent pipelines");
|