clisbot 0.1.51 → 0.1.52
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 +10 -8
- package/dist/main.js +67 -16
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -69,8 +69,8 @@ It is not just a tmux bridge with chat glued on top. `clisbot` treats Slack and
|
|
|
69
69
|
### I Just Want To Know What Changed Recently
|
|
70
70
|
|
|
71
71
|
- start with [Recent Release Highlights](#recent-release-highlights)
|
|
72
|
-
- then read [v0.1.
|
|
73
|
-
[v0.1.
|
|
72
|
+
- then read [v0.1.52 Release Notes](docs/releases/v0.1.52.md) or the
|
|
73
|
+
[v0.1.52 Release Guide](docs/updates/releases/v0.1.52-release-guide.md)
|
|
74
74
|
|
|
75
75
|
## Why I Built This
|
|
76
76
|
|
|
@@ -89,7 +89,7 @@ The challenge is not whether AI is useful. It is how to make it work at enterpri
|
|
|
89
89
|
- Team-first by design, with `AGENTS`, `USER`, and `MEMORY` context bootstrapping shaped for shared team reality instead of only personal solo-assistant flows.
|
|
90
90
|
- Shared-surface permission control is a first-class feature: a bot can be in a team group but still answer only the specific people you allow there, while sensitive control actions stay behind explicit auth roles and permissions.
|
|
91
91
|
- Useful for coding, operations, teamwork, and general assistant work, with fast chat controls such as `!<command>`, `/bash <command>`, `/queue`, `/loop`, `/streaming`, and `/mention`.
|
|
92
|
-
- New in the `v0.1.50` to `v0.1.
|
|
92
|
+
- New in the `v0.1.50` to `v0.1.52` stable line: the AI-native control experience is much better, the default runner startup window is now 60 seconds, and stale old startup-delay pins no longer silently keep upgraded installs on shorter timeouts.
|
|
93
93
|
|
|
94
94
|
## Who This Fits Best
|
|
95
95
|
|
|
@@ -185,12 +185,12 @@ Next steps:
|
|
|
185
185
|
- `clisbot` also has a smart autopairing path to reduce first-run friction. If
|
|
186
186
|
you send the bot a DM within the first 30 minutes, you can usually claim the
|
|
187
187
|
owner role immediately and start using it without a separate pairing round.
|
|
188
|
-
- New from the current `v0.1.50` to `v0.1.
|
|
188
|
+
- New from the current `v0.1.50` to `v0.1.52` stable line: the AI-native operator experience is much stronger. You
|
|
189
189
|
can increasingly ask the bot through chat to explain how to use it, update
|
|
190
190
|
itself and summarize what's new, help onboard you, create or add a new bot or
|
|
191
191
|
agent, or set up loops and schedules for recurring work instead of relying
|
|
192
192
|
only on slash commands.
|
|
193
|
-
- Existing configs from any version before `0.1.50` still update directly on first run when you install `v0.1.
|
|
193
|
+
- Existing configs from any version before `0.1.50` still update directly on first run when you install `v0.1.52`. clisbot writes a backup first under `~/.clisbot/backups/`, then rewrites the config to the current `0.1.50` schema shape.
|
|
194
194
|
- Shared Slack channels, Slack groups, Telegram groups, and Telegram topics are a separate gate: normal users need an explicit route such as `group:<id>` or `topic:<chatId>:<topicId>` before the bot will talk there. Legacy Slack `channel:<id>` input still works for compatibility.
|
|
195
195
|
- After a shared surface is admitted, per-surface sender control comes from the bot's default shared rule `groups["*"]` plus any route-local `allowUsers` or `blockUsers`.
|
|
196
196
|
- With that permission model, a bot can be added to a team group but still be
|
|
@@ -237,6 +237,7 @@ What happens next:
|
|
|
237
237
|
|
|
238
238
|
## Recent Release Highlights
|
|
239
239
|
|
|
240
|
+
- `v0.1.52`: clarifies shared-route setup so `routes add ...` clearly means “use the agent currently assigned to that bot by default,” and prunes stale short `startupDelayMs` overrides so upgraded installs can actually inherit the newer 60-second startup default.
|
|
240
241
|
- `v0.1.51`: raises the default runner startup window to 60 seconds across the
|
|
241
242
|
standard CLI families and the shared runner fallback, so slower fresh launches
|
|
242
243
|
are less likely to fail before the first prompt can be submitted.
|
|
@@ -271,6 +272,7 @@ Read the full notes here:
|
|
|
271
272
|
|
|
272
273
|
- [CHANGELOG.md](CHANGELOG.md)
|
|
273
274
|
- [Release Notes Index](docs/releases/README.md)
|
|
275
|
+
- [v0.1.52 Release Notes](docs/releases/v0.1.52.md)
|
|
274
276
|
- [v0.1.51 Release Notes](docs/releases/v0.1.51.md)
|
|
275
277
|
- [v0.1.50 Release Notes](docs/releases/v0.1.50.md)
|
|
276
278
|
- [v0.1.43 Release Notes](docs/releases/v0.1.43.md)
|
|
@@ -306,9 +308,9 @@ Update note for existing installs:
|
|
|
306
308
|
- Older installs before `v0.1.50` now update directly on first run with a
|
|
307
309
|
backup written first, so most people can update and restart without a manual
|
|
308
310
|
migration pass.
|
|
309
|
-
- `v0.1.
|
|
310
|
-
schema bump;
|
|
311
|
-
|
|
311
|
+
- `v0.1.52` keeps that direct-upgrade path and does not introduce a new config
|
|
312
|
+
schema bump; it also cleans up stale short startup-delay overrides that would
|
|
313
|
+
otherwise keep some upgraded installs on older timeout behavior.
|
|
312
314
|
- After you are on the `v0.1.50` schema line, future upgrades should feel much
|
|
313
315
|
more AI-native:
|
|
314
316
|
in many cases you can simply ask the bot to update `clisbot` to the latest
|
package/dist/main.js
CHANGED
|
@@ -62223,6 +62223,7 @@ function assertNoLegacyPrivilegeCommands(value, path = "root") {
|
|
|
62223
62223
|
import { basename, dirname as dirname4, join as join5 } from "node:path";
|
|
62224
62224
|
|
|
62225
62225
|
// src/config/persisted-config.ts
|
|
62226
|
+
var MIN_PERSISTED_AGENT_STARTUP_DELAY_MS = 30000;
|
|
62226
62227
|
var defaultOwnedRunnerFields = {
|
|
62227
62228
|
codex: ["startupDelayMs", "startupReadyPattern"],
|
|
62228
62229
|
gemini: [
|
|
@@ -62265,9 +62266,22 @@ function deleteIfEmpty(owner, key) {
|
|
|
62265
62266
|
function defaultRunner(toolId) {
|
|
62266
62267
|
return buildRunnerFromToolTemplate(toolId, DEFAULT_AGENT_TOOL_TEMPLATES[toolId], undefined);
|
|
62267
62268
|
}
|
|
62269
|
+
function isStaleStartupDelay(value) {
|
|
62270
|
+
return typeof value === "number" && Number.isInteger(value) && value > 0 && value < MIN_PERSISTED_AGENT_STARTUP_DELAY_MS;
|
|
62271
|
+
}
|
|
62272
|
+
function deleteStaleStartupDelay(owner) {
|
|
62273
|
+
if (!owner || !isStaleStartupDelay(owner.startupDelayMs)) {
|
|
62274
|
+
return false;
|
|
62275
|
+
}
|
|
62276
|
+
delete owner.startupDelayMs;
|
|
62277
|
+
return true;
|
|
62278
|
+
}
|
|
62268
62279
|
function pruneDefaultOwnedFields(params) {
|
|
62269
62280
|
const defaults = defaultRunner(params.toolId);
|
|
62270
62281
|
for (const field of defaultOwnedRunnerFields[params.toolId] ?? []) {
|
|
62282
|
+
if (field === "startupDelayMs" && deleteStaleStartupDelay(params.target)) {
|
|
62283
|
+
continue;
|
|
62284
|
+
}
|
|
62271
62285
|
if (params.force || Object.hasOwn(params.target, field) && areJsonEqual(params.target[field], defaults[field])) {
|
|
62272
62286
|
delete params.target[field];
|
|
62273
62287
|
}
|
|
@@ -62279,6 +62293,7 @@ function pruneAgentRunnerOverride(runner, cli) {
|
|
|
62279
62293
|
return;
|
|
62280
62294
|
}
|
|
62281
62295
|
const defaults = defaultRunner(toolId);
|
|
62296
|
+
deleteStaleStartupDelay(runner);
|
|
62282
62297
|
for (const field of [
|
|
62283
62298
|
"command",
|
|
62284
62299
|
"args",
|
|
@@ -62296,6 +62311,14 @@ function pruneAgentRunnerOverride(runner, cli) {
|
|
|
62296
62311
|
}
|
|
62297
62312
|
}
|
|
62298
62313
|
}
|
|
62314
|
+
function pruneAgentRunnerDefaultOverride(runner) {
|
|
62315
|
+
const defaults = runner.defaults;
|
|
62316
|
+
if (!isRecord5(defaults)) {
|
|
62317
|
+
return;
|
|
62318
|
+
}
|
|
62319
|
+
deleteStaleStartupDelay(defaults);
|
|
62320
|
+
deleteIfEmpty(runner, "defaults");
|
|
62321
|
+
}
|
|
62299
62322
|
function pruneRunnerDefaults(config, forceRunnerStartupDefaults) {
|
|
62300
62323
|
const runner = nestedRecord(config, ["agents", "defaults", "runner"]);
|
|
62301
62324
|
if (!runner) {
|
|
@@ -62304,6 +62327,9 @@ function pruneRunnerDefaults(config, forceRunnerStartupDefaults) {
|
|
|
62304
62327
|
const runnerDefaults = runner.defaults;
|
|
62305
62328
|
if (isRecord5(runnerDefaults)) {
|
|
62306
62329
|
for (const [field, defaultValue] of Object.entries(defaultOwnedRunnerDefaultFields)) {
|
|
62330
|
+
if (field === "startupDelayMs" && deleteStaleStartupDelay(runnerDefaults)) {
|
|
62331
|
+
continue;
|
|
62332
|
+
}
|
|
62307
62333
|
if (forceRunnerStartupDefaults || Object.hasOwn(runnerDefaults, field) && areJsonEqual(runnerDefaults[field], defaultValue)) {
|
|
62308
62334
|
delete runnerDefaults[field];
|
|
62309
62335
|
}
|
|
@@ -62329,6 +62355,7 @@ function pruneAgentOverrides(config) {
|
|
|
62329
62355
|
if (!isRecord5(agent) || !isRecord5(agent.runner)) {
|
|
62330
62356
|
continue;
|
|
62331
62357
|
}
|
|
62358
|
+
pruneAgentRunnerDefaultOverride(agent.runner);
|
|
62332
62359
|
const cli = typeof agent.cli === "string" ? inferAgentCliToolId(agent.cli) ?? undefined : undefined;
|
|
62333
62360
|
pruneAgentRunnerOverride(agent.runner, cli);
|
|
62334
62361
|
deleteIfEmpty(agent, "runner");
|
|
@@ -62386,15 +62413,34 @@ function pruneCurrentSchemaStartupDefaults(config) {
|
|
|
62386
62413
|
const defaults = isRecord6(agents?.defaults) ? agents.defaults : undefined;
|
|
62387
62414
|
const runner = isRecord6(defaults?.runner) ? defaults.runner : undefined;
|
|
62388
62415
|
const runnerDefaults = isRecord6(runner?.defaults) ? runner.defaults : undefined;
|
|
62389
|
-
const
|
|
62416
|
+
const familyRunners = ["codex", "claude", "gemini"].map((family) => isRecord6(runner?.[family]) ? runner[family] : undefined);
|
|
62417
|
+
const agentList = Array.isArray(agents?.list) ? agents.list : [];
|
|
62390
62418
|
let pruned = false;
|
|
62391
|
-
if (runnerDefaults
|
|
62392
|
-
delete runnerDefaults.startupDelayMs;
|
|
62419
|
+
if (deleteStaleStartupDelay(runnerDefaults)) {
|
|
62393
62420
|
pruned = true;
|
|
62394
62421
|
}
|
|
62395
|
-
|
|
62396
|
-
|
|
62397
|
-
|
|
62422
|
+
for (const familyRunner of familyRunners) {
|
|
62423
|
+
if (deleteStaleStartupDelay(familyRunner)) {
|
|
62424
|
+
pruned = true;
|
|
62425
|
+
}
|
|
62426
|
+
}
|
|
62427
|
+
for (const agent of agentList) {
|
|
62428
|
+
if (!isRecord6(agent) || !isRecord6(agent.runner)) {
|
|
62429
|
+
continue;
|
|
62430
|
+
}
|
|
62431
|
+
if (deleteStaleStartupDelay(agent.runner)) {
|
|
62432
|
+
pruned = true;
|
|
62433
|
+
}
|
|
62434
|
+
const runnerDefaultsOverride = isRecord6(agent.runner.defaults) ? agent.runner.defaults : undefined;
|
|
62435
|
+
if (deleteStaleStartupDelay(runnerDefaultsOverride)) {
|
|
62436
|
+
if (runnerDefaultsOverride && Object.keys(runnerDefaultsOverride).length === 0) {
|
|
62437
|
+
delete agent.runner.defaults;
|
|
62438
|
+
}
|
|
62439
|
+
if (Object.keys(agent.runner).length === 0) {
|
|
62440
|
+
delete agent.runner;
|
|
62441
|
+
}
|
|
62442
|
+
pruned = true;
|
|
62443
|
+
}
|
|
62398
62444
|
}
|
|
62399
62445
|
if (pruned) {
|
|
62400
62446
|
nextConfig.meta = {
|
|
@@ -75477,8 +75523,11 @@ function renderSlackRouteChoiceMessage(params) {
|
|
|
75477
75523
|
return [
|
|
75478
75524
|
"clisbot: this Slack channel is not configured yet.",
|
|
75479
75525
|
"",
|
|
75480
|
-
"Ask the bot owner to do
|
|
75526
|
+
"Ask the bot owner to do this first:",
|
|
75481
75527
|
`- ${renderCliCommand(`routes add --channel slack group:${params.channelId} --bot default`, { inline: true })}`,
|
|
75528
|
+
" This channel will use the agent currently assigned to this bot by default.",
|
|
75529
|
+
"",
|
|
75530
|
+
"Only if this channel should use a different agent than the one currently assigned to this bot by default:",
|
|
75482
75531
|
`- ${renderCliCommand(`routes set-agent --channel slack group:${params.channelId} --bot default --agent <id>`, { inline: true })}`,
|
|
75483
75532
|
"",
|
|
75484
75533
|
`After that, ${botReference} and send \`\\start\`, \`\\status\`, or \`\\mention\` here.`
|
|
@@ -78538,16 +78587,17 @@ function renderTelegramRouteChoiceMessage(params) {
|
|
|
78538
78587
|
const lines = [
|
|
78539
78588
|
topicId != null ? "clisbot: this Telegram topic is not configured yet." : "clisbot: this Telegram group is not configured yet.",
|
|
78540
78589
|
"",
|
|
78541
|
-
"Ask the bot owner to
|
|
78590
|
+
"Ask the bot owner to do this first:",
|
|
78542
78591
|
"",
|
|
78543
|
-
"Add the whole group
|
|
78592
|
+
"Add the whole group route:",
|
|
78544
78593
|
renderCliCommand(`routes add --channel telegram group:${chatId} --bot default`, { inline: true }),
|
|
78594
|
+
"That group will use the agent currently assigned to that bot by default.",
|
|
78545
78595
|
"",
|
|
78546
|
-
"
|
|
78596
|
+
"Only if that group should use a different agent than the one currently assigned to that bot by default:",
|
|
78547
78597
|
renderCliCommand(`routes set-agent --channel telegram group:${chatId} --bot default --agent <id>`, { inline: true })
|
|
78548
78598
|
];
|
|
78549
78599
|
if (topicId != null) {
|
|
78550
|
-
lines.push("", "Or
|
|
78600
|
+
lines.push("", "Or add only this topic route:", renderCliCommand(`routes add --channel telegram topic:${chatId}:${topicId} --bot default`, { inline: true }), "That topic will use the agent currently assigned to that bot by default.", "", "Only if this topic should use a different agent than the one currently assigned to that bot by default:", renderCliCommand(`routes set-agent --channel telegram topic:${chatId}:${topicId} --bot default --agent <id>`, { inline: true }));
|
|
78551
78601
|
}
|
|
78552
78602
|
if (params.includeConfigPath) {
|
|
78553
78603
|
lines.push("", topicId != null ? `Config path: \`bots.telegram.default.groups."${chatId}".topics."${topicId}"\`` : `Config path: \`bots.telegram.default.groups."${chatId}"\``);
|
|
@@ -84868,8 +84918,8 @@ function appendChannelNextStepLines(lines, summary, prefix = "") {
|
|
|
84868
84918
|
lines.push(`${prefix}- DM the Slack bot first to confirm it responds normally`);
|
|
84869
84919
|
}
|
|
84870
84920
|
lines.push(`${prefix}- after DM works, add the bot to the target Slack channel or Telegram group/topic`);
|
|
84871
|
-
lines.push(`${prefix}- add the route with ${renderCliCommand("routes add --channel slack group:<channelId> --bot default", { inline: true })} or ${renderCliCommand("routes add --channel telegram group:<chatId> --bot default", { inline: true })}`);
|
|
84872
|
-
lines.push(`${prefix}-
|
|
84921
|
+
lines.push(`${prefix}- add the route with ${renderCliCommand("routes add --channel slack group:<channelId> --bot default", { inline: true })} or ${renderCliCommand("routes add --channel telegram group:<chatId> --bot default", { inline: true })}; that route uses the agent currently assigned to that bot by default`);
|
|
84922
|
+
lines.push(`${prefix}- only if you want a different agent there than the one currently assigned to that bot by default, bind it with ${renderCliCommand("routes set-agent --channel slack group:<channelId> --bot default --agent <id>", { inline: true })} or ${renderCliCommand("routes set-agent --channel telegram group:<chatId> --bot default --agent <id>", { inline: true })}`);
|
|
84873
84923
|
if (telegramEnabled) {
|
|
84874
84924
|
lines.push(`${prefix}- Telegram: send \`/start\` in the target DM, group, or topic to get onboarding or pairing guidance`);
|
|
84875
84925
|
}
|
|
@@ -85013,9 +85063,9 @@ function appendChannelSetupNote(lines, summary, channel, prefix) {
|
|
|
85013
85063
|
lines.push(`${prefix} dms: ${channel.directMessagesEnabled ? `enabled (${channel.directMessagesPolicy})` : "disabled"}`);
|
|
85014
85064
|
lines.push(`${prefix} sharedDefault: ${channel.sharedDefaultPolicy ?? "n/a"}`);
|
|
85015
85065
|
lines.push(`${prefix} add group: ${renderCliCommand("routes add --channel telegram group:<chatId> --bot default", { inline: true })}`);
|
|
85016
|
-
lines.push(`${prefix}
|
|
85066
|
+
lines.push(`${prefix} route uses the agent currently assigned to that bot by default`);
|
|
85017
85067
|
lines.push(`${prefix} add topic: ${renderCliCommand("routes add --channel telegram topic:<chatId>:<topicId> --bot default", { inline: true })}`);
|
|
85018
|
-
lines.push(`${prefix}
|
|
85068
|
+
lines.push(`${prefix} optional agent override if that surface should use a different agent than the one currently assigned to that bot by default: ${renderCliCommand("routes set-agent --channel telegram group:<chatId> --bot default --agent <id>", { inline: true })} or ${renderCliCommand("routes set-agent --channel telegram topic:<chatId>:<topicId> --bot default --agent <id>", { inline: true })}`);
|
|
85019
85069
|
lines.push(`${prefix} adjust later: ${renderPrivilegedChatHint(summary, "run in-chat commands here")}`);
|
|
85020
85070
|
return;
|
|
85021
85071
|
}
|
|
@@ -85023,7 +85073,8 @@ function appendChannelSetupNote(lines, summary, channel, prefix) {
|
|
|
85023
85073
|
lines.push(`${prefix} dms: ${channel.directMessagesEnabled ? `enabled (${channel.directMessagesPolicy})` : "disabled"}`);
|
|
85024
85074
|
lines.push(`${prefix} sharedDefault: ${channel.sharedDefaultPolicy ?? "n/a"}`);
|
|
85025
85075
|
lines.push(`${prefix} add group: ${renderCliCommand("routes add --channel slack group:<channelId> --bot default", { inline: true })}`);
|
|
85026
|
-
lines.push(`${prefix}
|
|
85076
|
+
lines.push(`${prefix} route uses the agent currently assigned to that bot by default`);
|
|
85077
|
+
lines.push(`${prefix} optional agent override if that route should use a different agent than the one currently assigned to that bot by default: ${renderCliCommand("routes set-agent --channel slack group:<channelId> --bot default --agent <id>", { inline: true })}`);
|
|
85027
85078
|
lines.push(`${prefix} adjust later: ${renderPrivilegedChatHint(summary, "run in-chat commands here")}`);
|
|
85028
85079
|
}
|
|
85029
85080
|
function appendBootstrapGuidance(lines, summary) {
|