@tractorscorch/clank 1.5.7 → 1.5.9
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 +23 -0
- package/README.md +8 -2
- package/dist/index.js +38 -13
- package/dist/index.js.map +1 -1
- package/dist/web/index.html +27 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,29 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/).
|
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
+
## [1.5.9] — 2026-03-23
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
- **Workspace defaults to current directory** — the agent's workspace is now the directory you run `clank` from, not a hidden `%APPDATA%/Clank/workspace` folder. This means the agent works with your actual project files out of the box
|
|
13
|
+
- **Full file system access** — the path guard no longer blocks reads/writes outside the workspace. Clank is a dev tool and needs to access the full system. Added security notice to README recommending dedicated hardware
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
- **Telegram `/new` and `/reset` were no-ops** — these commands returned a "session started" message but never actually reset the session. The model kept its full conversation history. Now properly clears session store, context engine, and destroys the old engine instance
|
|
17
|
+
- **Security notice added to README** — recommends running Clank on dedicated hardware since it gives agents full system access
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## [1.5.8] — 2026-03-23
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
- **Collapsible thinking blocks** — model thinking/reasoning is now displayed in a separate clickable block above the response instead of being streamed into the message text. Click the "Thought" toggle to expand/collapse. Shows "Thinking..." while streaming, "Thought" when complete
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
- **Thinking events were disconnected** — the full thinking pipeline (provider → agent → gateway → frontend) was broken at 3 points: provider yielded thinking as text for local models, agent only emitted a one-shot start event without content, and gateway didn't forward thinking events to clients. All 3 fixed
|
|
28
|
+
- **Empty responses from thinking-only models** — when a model puts all output in `reasoning_content` with empty `content` (Qwen3.5), the thinking text is now used as the response instead of showing a blank message
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
9
32
|
## [1.5.7] — 2026-03-23
|
|
10
33
|
|
|
11
34
|
### Fixed
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
</p>
|
|
10
10
|
|
|
11
11
|
<p align="center">
|
|
12
|
-
<a href="https://github.com/ItsTrag1c/Clank/releases/latest"><img src="https://img.shields.io/badge/version-1.5.
|
|
12
|
+
<a href="https://github.com/ItsTrag1c/Clank/releases/latest"><img src="https://img.shields.io/badge/version-1.5.9-blue.svg" alt="Version" /></a>
|
|
13
13
|
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License" /></a>
|
|
14
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
15
|
<a href="https://github.com/ItsTrag1c/Clank/stargazers"><img src="https://img.shields.io/github/stars/ItsTrag1c/Clank.svg" alt="Stars" /></a>
|
|
@@ -75,7 +75,13 @@ That's it. Setup auto-detects your local models, configures the gateway, and get
|
|
|
75
75
|
| Platform | Download |
|
|
76
76
|
|----------|----------|
|
|
77
77
|
| **npm** (all platforms) | `npm install -g @tractorscorch/clank` |
|
|
78
|
-
| **macOS** (Apple Silicon) | [Clank_1.5.
|
|
78
|
+
| **macOS** (Apple Silicon) | [Clank_1.5.9_macos](https://github.com/ItsTrag1c/Clank/releases/latest/download/Clank_1.5.9_macos) |
|
|
79
|
+
|
|
80
|
+
## Security Notice
|
|
81
|
+
|
|
82
|
+
Clank is a **developer tool** that gives AI agents full access to your file system, shell, and connected services. The agent can read, write, and execute on your behalf.
|
|
83
|
+
|
|
84
|
+
**We strongly recommend running Clank on dedicated hardware** (a dev machine, VM, or container) rather than on a system with sensitive personal files, credentials, or accounts you don't want the agent to access. Treat it like giving someone SSH access to your box.
|
|
79
85
|
|
|
80
86
|
## Features
|
|
81
87
|
|
package/dist/index.js
CHANGED
|
@@ -934,6 +934,7 @@ var init_agent = __esm({
|
|
|
934
934
|
denylist: this.identity.tools?.deny
|
|
935
935
|
});
|
|
936
936
|
let iterationText = "";
|
|
937
|
+
let thinkingText = "";
|
|
937
938
|
const toolCalls = [];
|
|
938
939
|
let promptTokens = 0;
|
|
939
940
|
let outputTokens = 0;
|
|
@@ -942,6 +943,7 @@ var init_agent = __esm({
|
|
|
942
943
|
for (let attempt = 0; attempt < 2; attempt++) {
|
|
943
944
|
if (attempt > 0) {
|
|
944
945
|
iterationText = "";
|
|
946
|
+
thinkingText = "";
|
|
945
947
|
toolCalls.length = 0;
|
|
946
948
|
promptTokens = 0;
|
|
947
949
|
outputTokens = 0;
|
|
@@ -960,7 +962,8 @@ var init_agent = __esm({
|
|
|
960
962
|
this.emit("token", { content: event.content });
|
|
961
963
|
break;
|
|
962
964
|
case "thinking":
|
|
963
|
-
|
|
965
|
+
thinkingText += event.content;
|
|
966
|
+
this.emit("thinking", { content: event.content });
|
|
964
967
|
break;
|
|
965
968
|
case "tool_call":
|
|
966
969
|
toolCalls.push({
|
|
@@ -1005,6 +1008,10 @@ var init_agent = __esm({
|
|
|
1005
1008
|
contextPercent: Math.round(this.contextEngine.utilizationPercent())
|
|
1006
1009
|
});
|
|
1007
1010
|
if (toolCalls.length === 0) {
|
|
1011
|
+
if (!iterationText && thinkingText) {
|
|
1012
|
+
iterationText = thinkingText;
|
|
1013
|
+
this.emit("token", { content: iterationText });
|
|
1014
|
+
}
|
|
1008
1015
|
fullResponse = iterationText;
|
|
1009
1016
|
this.contextEngine.ingest({ role: "assistant", content: iterationText });
|
|
1010
1017
|
this.emit("response-end", { text: iterationText });
|
|
@@ -1037,6 +1044,7 @@ var init_agent = __esm({
|
|
|
1037
1044
|
this.emit("tool-start", { id: tc.id, name: tc.name, arguments: tc.arguments });
|
|
1038
1045
|
const toolCtx = {
|
|
1039
1046
|
projectRoot: this.identity.workspace,
|
|
1047
|
+
allowExternal: true,
|
|
1040
1048
|
autoApprove: this.autoApprove,
|
|
1041
1049
|
agentId: this.identity.id,
|
|
1042
1050
|
signal
|
|
@@ -2092,7 +2100,7 @@ function defaultConfig() {
|
|
|
2092
2100
|
agents: {
|
|
2093
2101
|
defaults: {
|
|
2094
2102
|
model: { primary: "ollama/qwen3.5" },
|
|
2095
|
-
workspace:
|
|
2103
|
+
workspace: process.cwd(),
|
|
2096
2104
|
toolTier: "auto",
|
|
2097
2105
|
temperature: 0.7
|
|
2098
2106
|
},
|
|
@@ -3112,11 +3120,7 @@ var init_openai = __esm({
|
|
|
3112
3120
|
}
|
|
3113
3121
|
if (choice?.delta?.reasoning_content) {
|
|
3114
3122
|
hasContent = true;
|
|
3115
|
-
|
|
3116
|
-
yield { type: "text", content: choice.delta.reasoning_content };
|
|
3117
|
-
} else {
|
|
3118
|
-
yield { type: "thinking", content: choice.delta.reasoning_content };
|
|
3119
|
-
}
|
|
3123
|
+
yield { type: "thinking", content: choice.delta.reasoning_content };
|
|
3120
3124
|
}
|
|
3121
3125
|
if (choice?.delta?.content) {
|
|
3122
3126
|
hasContent = true;
|
|
@@ -5694,9 +5698,15 @@ You can read this file with the read_file tool.`
|
|
|
5694
5698
|
return "Use /new to start a fresh session, or /reset to clear the current one.";
|
|
5695
5699
|
}
|
|
5696
5700
|
case "new":
|
|
5697
|
-
return "New session started. Send a message to begin.";
|
|
5698
5701
|
case "reset":
|
|
5699
|
-
|
|
5702
|
+
if (this.gateway) {
|
|
5703
|
+
await this.gateway.resetSession({
|
|
5704
|
+
channel: "telegram",
|
|
5705
|
+
peerId: chatId,
|
|
5706
|
+
peerKind: isGroup ? "group" : "dm"
|
|
5707
|
+
});
|
|
5708
|
+
}
|
|
5709
|
+
return command === "new" ? "New session started. Send a message to begin." : "Session reset. History cleared.";
|
|
5700
5710
|
case "model": {
|
|
5701
5711
|
const model = this.config?.agents?.defaults?.model?.primary || "unknown";
|
|
5702
5712
|
return `Current model: \`${model}\``;
|
|
@@ -6131,6 +6141,20 @@ var init_server = __esm({
|
|
|
6131
6141
|
}
|
|
6132
6142
|
}
|
|
6133
6143
|
}
|
|
6144
|
+
/**
|
|
6145
|
+
* Reset a session — clear its history and context.
|
|
6146
|
+
* Used by channel adapters (Telegram /new, /reset commands).
|
|
6147
|
+
*/
|
|
6148
|
+
async resetSession(context) {
|
|
6149
|
+
const sessionKey = deriveSessionKey(context);
|
|
6150
|
+
await this.sessionStore.reset(sessionKey);
|
|
6151
|
+
const engine = this.engines.get(sessionKey);
|
|
6152
|
+
if (engine) {
|
|
6153
|
+
engine.getContextEngine().clear();
|
|
6154
|
+
engine.destroy();
|
|
6155
|
+
this.engines.delete(sessionKey);
|
|
6156
|
+
}
|
|
6157
|
+
}
|
|
6134
6158
|
/**
|
|
6135
6159
|
* Handle an inbound message from any channel adapter.
|
|
6136
6160
|
* This is the main entry point for all non-WebSocket messages.
|
|
@@ -6242,7 +6266,7 @@ var init_server = __esm({
|
|
|
6242
6266
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
6243
6267
|
res.end(JSON.stringify({
|
|
6244
6268
|
status: "ok",
|
|
6245
|
-
version: "1.5.
|
|
6269
|
+
version: "1.5.9",
|
|
6246
6270
|
uptime: process.uptime(),
|
|
6247
6271
|
clients: this.clients.size,
|
|
6248
6272
|
agents: this.engines.size
|
|
@@ -6354,7 +6378,7 @@ var init_server = __esm({
|
|
|
6354
6378
|
const hello = {
|
|
6355
6379
|
type: "hello",
|
|
6356
6380
|
protocol: PROTOCOL_VERSION,
|
|
6357
|
-
version: "1.5.
|
|
6381
|
+
version: "1.5.9",
|
|
6358
6382
|
agents: this.config.agents.list.map((a) => ({
|
|
6359
6383
|
id: a.id,
|
|
6360
6384
|
name: a.name || a.id,
|
|
@@ -6619,6 +6643,7 @@ var init_server = __esm({
|
|
|
6619
6643
|
wireEngineEvents(engine, client) {
|
|
6620
6644
|
const eventMap = {
|
|
6621
6645
|
"token": "token",
|
|
6646
|
+
"thinking": "thinking",
|
|
6622
6647
|
"response-start": "response-start",
|
|
6623
6648
|
"response-end": "response-end",
|
|
6624
6649
|
"tool-start": "tool-start",
|
|
@@ -7749,7 +7774,7 @@ async function runTui(opts) {
|
|
|
7749
7774
|
ws.on("open", () => {
|
|
7750
7775
|
ws.send(JSON.stringify({
|
|
7751
7776
|
type: "connect",
|
|
7752
|
-
params: { auth: { token }, mode: "tui", version: "1.5.
|
|
7777
|
+
params: { auth: { token }, mode: "tui", version: "1.5.9" }
|
|
7753
7778
|
}));
|
|
7754
7779
|
});
|
|
7755
7780
|
ws.on("message", (data) => {
|
|
@@ -8178,7 +8203,7 @@ import { fileURLToPath as fileURLToPath5 } from "url";
|
|
|
8178
8203
|
import { dirname as dirname5, join as join19 } from "path";
|
|
8179
8204
|
var __filename3 = fileURLToPath5(import.meta.url);
|
|
8180
8205
|
var __dirname3 = dirname5(__filename3);
|
|
8181
|
-
var version = "1.5.
|
|
8206
|
+
var version = "1.5.9";
|
|
8182
8207
|
try {
|
|
8183
8208
|
const pkg = JSON.parse(readFileSync(join19(__dirname3, "..", "package.json"), "utf-8"));
|
|
8184
8209
|
version = pkg.version;
|