clisbot 0.1.39 → 0.1.40

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.
Files changed (3) hide show
  1. package/README.md +28 -0
  2. package/dist/main.js +59 -13
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -76,6 +76,7 @@ Need the step-by-step setup docs instead of the shortest path?
76
76
 
77
77
  - Telegram: [Telegram Bot Setup](docs/user-guide/telegram-setup.md)
78
78
  - Slack: [Slack App Setup](docs/user-guide/slack-setup.md)
79
+ - Release notes: [CHANGELOG.md](CHANGELOG.md) and [docs/releases/](docs/releases/README.md)
79
80
  - Slack app manifest template: [app-manifest.json](templates/slack/default/app-manifest.json)
80
81
  - Slack app manifest guide: [app-manifest-guide.md](templates/slack/default/app-manifest-guide.md)
81
82
 
@@ -88,6 +89,20 @@ What happens next:
88
89
  - fresh bootstrap only enables the channels you name explicitly
89
90
  - after the persisted first run, later restarts can use plain `clisbot start`
90
91
 
92
+ ## Big Upgrades In v0.1.39
93
+
94
+ - Much better native Slack and Telegram rendering, so replies are easier to read and feel far less like pasted terminal output.
95
+ - A much cleaner first-run path, with a clearer bot-first setup story and better setup docs.
96
+ - Stronger pairing, auth, and safer shared-channel behavior by default.
97
+ - More trustworthy long-running work, with better attach, detach, recovery, and operator visibility.
98
+ - Real recurring automation with `/loop`.
99
+
100
+ Read the full notes here:
101
+
102
+ - [CHANGELOG.md](CHANGELOG.md)
103
+ - [Release Notes Index](docs/releases/README.md)
104
+ - [v0.1.39 Release Notes](docs/releases/v0.1.39.md)
105
+
91
106
  If you prefer Slack first:
92
107
 
93
108
  ```bash
@@ -113,6 +128,19 @@ bun run start --cli codex --bot-type personal --telegram-bot-token <your-telegra
113
128
 
114
129
  Repo-local `bun run start|stop|restart|status|logs|init|pairing` is pinned by `.env` to `CLISBOT_HOME=~/.clisbot-dev`, so local testing does not accidentally reuse your main `~/.clisbot` runtime.
115
130
 
131
+ Upgrade note for existing installs:
132
+
133
+ - `v0.1.39` includes breaking changes in config shape and in the main CLI command surface.
134
+ - If you already run an older install, ask Codex or Claude in this repo to update your current config before upgrading.
135
+ - The upgrade itself is still simple:
136
+
137
+ ```bash
138
+ clisbot stop
139
+ npm install -g clisbot
140
+ clisbot start
141
+ clisbot --version
142
+ ```
143
+
116
144
  First conversation path:
117
145
 
118
146
  - send a DM to the bot in Slack or Telegram
package/dist/main.js CHANGED
@@ -4,25 +4,43 @@ var __getProtoOf = Object.getPrototypeOf;
4
4
  var __defProp = Object.defineProperty;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ function __accessProp(key) {
8
+ return this[key];
9
+ }
10
+ var __toESMCache_node;
11
+ var __toESMCache_esm;
7
12
  var __toESM = (mod, isNodeMode, target) => {
13
+ var canCache = mod != null && typeof mod === "object";
14
+ if (canCache) {
15
+ var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
16
+ var cached = cache.get(mod);
17
+ if (cached)
18
+ return cached;
19
+ }
8
20
  target = mod != null ? __create(__getProtoOf(mod)) : {};
9
21
  const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
10
22
  for (let key of __getOwnPropNames(mod))
11
23
  if (!__hasOwnProp.call(to, key))
12
24
  __defProp(to, key, {
13
- get: () => mod[key],
25
+ get: __accessProp.bind(mod, key),
14
26
  enumerable: true
15
27
  });
28
+ if (canCache)
29
+ cache.set(mod, to);
16
30
  return to;
17
31
  };
18
32
  var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
33
+ var __returnValue = (v) => v;
34
+ function __exportSetter(name, newValue) {
35
+ this[name] = __returnValue.bind(null, newValue);
36
+ }
19
37
  var __export = (target, all) => {
20
38
  for (var name in all)
21
39
  __defProp(target, name, {
22
40
  get: all[name],
23
41
  enumerable: true,
24
42
  configurable: true,
25
- set: (newValue) => all[name] = () => newValue
43
+ set: __exportSetter.bind(all, name)
26
44
  });
27
45
  };
28
46
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
@@ -65977,7 +65995,7 @@ function deriveBoundedRunningRewritePreview(params) {
65977
65995
  }
65978
65996
  const changedLines = currentLines.slice(prefix, currentLines.length - suffix);
65979
65997
  if (changedLines.length === 0) {
65980
- return current;
65998
+ return current === previous ? current : "";
65981
65999
  }
65982
66000
  if (changedLines.length <= maxLines) {
65983
66001
  return changedLines.join(`
@@ -67315,7 +67333,8 @@ var FIRST_OUTPUT_POLL_INTERVAL_MS = 250;
67315
67333
  var RUNNING_REWRITE_PREVIEW_MAX_LINES = 8;
67316
67334
  async function monitorTmuxRun(params) {
67317
67335
  let previousSnapshot = params.initialSnapshot;
67318
- let previousRunningSnapshot = "";
67336
+ let previousRunningTruth = "";
67337
+ let previousRenderedRunningSnapshot = "";
67319
67338
  let lastPaneChangeAt = params.startedAt;
67320
67339
  let sawActivity = false;
67321
67340
  let sawPaneChange = false;
@@ -67358,15 +67377,17 @@ async function monitorTmuxRun(params) {
67358
67377
  const currentRunningSnapshot = deriveRunningInteractionSnapshot(snapshot);
67359
67378
  const baselineRunningSnapshot = deriveInteractionText(params.initialSnapshot, snapshot) || currentRunningSnapshot;
67360
67379
  const runningDelta = priorSnapshot ? deriveRunningInteractionText(priorSnapshot, snapshot) : currentRunningSnapshot;
67361
- const shouldReplaceRunningSnapshot = paneChanged && !runningDelta && Boolean(baselineRunningSnapshot) && baselineRunningSnapshot !== previousRunningSnapshot;
67362
- const runningSnapshot = runningDelta ? previousRunningSnapshot ? appendInteractionText(previousRunningSnapshot, runningDelta) : runningDelta : shouldReplaceRunningSnapshot ? deriveBoundedRunningRewritePreview({
67363
- previousSnapshot: previousRunningSnapshot,
67364
- snapshot: baselineRunningSnapshot,
67380
+ const shouldReplaceRunningSnapshot = paneChanged && !runningDelta && Boolean(baselineRunningSnapshot) && baselineRunningSnapshot !== previousRunningTruth;
67381
+ const nextRunningTruth = runningDelta ? previousRunningTruth ? appendInteractionText(previousRunningTruth, runningDelta) : runningDelta : shouldReplaceRunningSnapshot ? baselineRunningSnapshot : previousRunningTruth;
67382
+ const runningSnapshot = runningDelta ? nextRunningTruth : shouldReplaceRunningSnapshot ? deriveBoundedRunningRewritePreview({
67383
+ previousSnapshot: previousRunningTruth,
67384
+ snapshot: nextRunningTruth,
67365
67385
  maxLines: RUNNING_REWRITE_PREVIEW_MAX_LINES
67366
67386
  }) : "";
67367
67387
  previousSnapshot = snapshot;
67368
- if (runningSnapshot && runningSnapshot !== previousRunningSnapshot) {
67369
- previousRunningSnapshot = runningSnapshot;
67388
+ previousRunningTruth = nextRunningTruth;
67389
+ if (runningSnapshot && runningSnapshot !== previousRenderedRunningSnapshot) {
67390
+ previousRenderedRunningSnapshot = runningSnapshot;
67370
67391
  sawActivity = true;
67371
67392
  if (!firstMeaningfulDeltaLogged) {
67372
67393
  firstMeaningfulDeltaLogged = true;
@@ -67384,7 +67405,7 @@ async function monitorTmuxRun(params) {
67384
67405
  if (!detachedNotified && now - params.startedAt >= params.maxRuntimeMs) {
67385
67406
  detachedNotified = true;
67386
67407
  await params.onDetached({
67387
- snapshot: previousRunningSnapshot || deriveInteractionText(params.initialSnapshot, snapshot),
67408
+ snapshot: previousRenderedRunningSnapshot || previousRunningTruth || deriveInteractionText(params.initialSnapshot, snapshot),
67388
67409
  fullSnapshot: previousSnapshot,
67389
67410
  initialSnapshot: params.initialSnapshot
67390
67411
  });
@@ -69263,9 +69284,12 @@ async function executePromptDelivery(params) {
69263
69284
  console.error("message-tool preview monitor failed", error);
69264
69285
  });
69265
69286
  }
69266
- async function waitForMessageToolFinalReply() {
69267
- const deadline = Date.now() + MESSAGE_TOOL_FINAL_GRACE_WINDOW_MS;
69287
+ async function waitForMessageToolFinalReply(params2 = {}) {
69288
+ const deadline = params2.deadlineAt ?? Date.now() + MESSAGE_TOOL_FINAL_GRACE_WINDOW_MS;
69268
69289
  while (true) {
69290
+ if (params2.stopWhen?.()) {
69291
+ return false;
69292
+ }
69269
69293
  const signals = await getMessageToolRuntimeSignals();
69270
69294
  const toolFinalSeen = typeof signals.messageToolFinalReplyAt === "number" && Number.isFinite(signals.messageToolFinalReplyAt);
69271
69295
  if (toolFinalSeen) {
@@ -69436,6 +69460,28 @@ async function executePromptDelivery(params) {
69436
69460
  body: ""
69437
69461
  };
69438
69462
  }
69463
+ const returnOnToolFinal = params.route.responseMode === "message-tool" && params.forceQueuedDelivery !== true;
69464
+ let stopEarlyToolFinalWait = false;
69465
+ const earlyToolFinalOutcome = returnOnToolFinal ? await Promise.race([
69466
+ result.then(() => "result", () => "result"),
69467
+ waitForMessageToolFinalReply({
69468
+ deadlineAt: Number.POSITIVE_INFINITY,
69469
+ stopWhen: () => stopEarlyToolFinalWait
69470
+ }).then((seen) => seen ? "tool-final" : "result")
69471
+ ]) : "result";
69472
+ stopEarlyToolFinalWait = true;
69473
+ if (earlyToolFinalOutcome === "tool-final") {
69474
+ await renderChain;
69475
+ if (messageToolPreview && responseChunks.length > 0) {
69476
+ await handoffMessageToolPreview();
69477
+ } else if (params.route.response === "final") {
69478
+ await clearResponseText();
69479
+ }
69480
+ result.catch((error) => {
69481
+ console.error("message-tool run settled after the channel already observed a final reply", error);
69482
+ });
69483
+ return;
69484
+ }
69439
69485
  const finalResult = await result;
69440
69486
  await renderChain;
69441
69487
  await maybeRenderQueueStartNotification();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clisbot",
3
- "version": "0.1.39",
3
+ "version": "0.1.40",
4
4
  "private": false,
5
5
  "description": "Chat surfaces for durable AI coding agents running in tmux",
6
6
  "license": "MIT",