clisbot 0.1.15 → 0.1.17

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.
@@ -194,7 +194,7 @@
194
194
  "!"
195
195
  ]
196
196
  },
197
- "streaming": "all",
197
+ "streaming": "off",
198
198
  "response": "final",
199
199
  "responseMode": "message-tool",
200
200
  "additionalMessageMode": "steer",
@@ -240,7 +240,7 @@
240
240
  "!"
241
241
  ]
242
242
  },
243
- "streaming": "all",
243
+ "streaming": "off",
244
244
  "response": "final",
245
245
  "responseMode": "message-tool",
246
246
  "additionalMessageMode": "steer",
package/dist/main.js CHANGED
@@ -60073,15 +60073,12 @@ var telegramSchema = exports_external.object({
60073
60073
  allowBots: exports_external.boolean().default(false),
60074
60074
  groupPolicy: slackConversationPolicySchema.default("allowlist"),
60075
60075
  defaultAgentId: exports_external.string().default("default"),
60076
- privilegeCommands: privilegeCommandsSchema.default({
60077
- enabled: false,
60078
- allowUsers: []
60079
- }),
60076
+ privilegeCommands: privilegeCommandsSchema.optional(),
60080
60077
  commandPrefixes: commandPrefixesSchema.default({
60081
60078
  slash: ["::", "\\"],
60082
60079
  bash: ["!"]
60083
60080
  }),
60084
- streaming: slackStreamingSchema.default("all"),
60081
+ streaming: slackStreamingSchema.default("off"),
60085
60082
  response: slackResponseSchema.default("final"),
60086
60083
  responseMode: channelResponseModeSchema.default("message-tool"),
60087
60084
  additionalMessageMode: channelAdditionalMessageModeSchema.default("steer"),
@@ -60151,15 +60148,12 @@ var slackSchema = exports_external.object({
60151
60148
  channelPolicy: slackConversationPolicySchema.default("allowlist"),
60152
60149
  groupPolicy: slackConversationPolicySchema.default("allowlist"),
60153
60150
  defaultAgentId: exports_external.string().default("default"),
60154
- privilegeCommands: privilegeCommandsSchema.default({
60155
- enabled: false,
60156
- allowUsers: []
60157
- }),
60151
+ privilegeCommands: privilegeCommandsSchema.optional(),
60158
60152
  commandPrefixes: commandPrefixesSchema.default({
60159
60153
  slash: ["::", "\\"],
60160
60154
  bash: ["!"]
60161
60155
  }),
60162
- streaming: slackStreamingSchema.default("all"),
60156
+ streaming: slackStreamingSchema.default("off"),
60163
60157
  response: slackResponseSchema.default("final"),
60164
60158
  responseMode: channelResponseModeSchema.default("message-tool"),
60165
60159
  additionalMessageMode: channelAdditionalMessageModeSchema.default("steer"),
@@ -60310,7 +60304,7 @@ var clisbotConfigSchema = exports_external.object({
60310
60304
  slash: ["::", "\\"],
60311
60305
  bash: ["!"]
60312
60306
  },
60313
- streaming: "all",
60307
+ streaming: "off",
60314
60308
  response: "final",
60315
60309
  responseMode: "message-tool",
60316
60310
  additionalMessageMode: "steer",
@@ -60627,7 +60621,7 @@ function renderDefaultConfigTemplate(options = {}) {
60627
60621
  slash: ["::", "\\"],
60628
60622
  bash: ["!"]
60629
60623
  },
60630
- streaming: "all",
60624
+ streaming: "off",
60631
60625
  response: "final",
60632
60626
  responseMode: "message-tool",
60633
60627
  additionalMessageMode: "steer",
@@ -60668,7 +60662,7 @@ function renderDefaultConfigTemplate(options = {}) {
60668
60662
  slash: ["::", "\\"],
60669
60663
  bash: ["!"]
60670
60664
  },
60671
- streaming: "all",
60665
+ streaming: "off",
60672
60666
  response: "final",
60673
60667
  responseMode: "message-tool",
60674
60668
  additionalMessageMode: "steer",
@@ -60716,26 +60710,16 @@ async function readEditableConfig(configPath = getDefaultConfigPath()) {
60716
60710
  async function writeEditableConfig(configPath, config) {
60717
60711
  const expandedConfigPath = expandHomePath(configPath);
60718
60712
  await ensureDir2(dirname4(expandedConfigPath));
60719
- const nextConfig = stripLegacyPrivilegeCommands({
60713
+ const nextConfig = {
60720
60714
  ...config,
60721
60715
  meta: {
60722
60716
  ...config.meta,
60723
60717
  lastTouchedAt: new Date().toISOString()
60724
60718
  }
60725
- });
60719
+ };
60726
60720
  await writeTextFile(expandedConfigPath, `${JSON.stringify(nextConfig, null, 2)}
60727
60721
  `);
60728
60722
  }
60729
- function stripLegacyPrivilegeCommands(value) {
60730
- if (Array.isArray(value)) {
60731
- return value.map((entry) => stripLegacyPrivilegeCommands(entry));
60732
- }
60733
- if (!value || typeof value !== "object") {
60734
- return value;
60735
- }
60736
- const nextEntries = Object.entries(value).filter(([key]) => key !== "privilegeCommands").map(([key, entry]) => [key, stripLegacyPrivilegeCommands(entry)]);
60737
- return Object.fromEntries(nextEntries);
60738
- }
60739
60723
 
60740
60724
  // src/agents/bootstrap.ts
60741
60725
  import { fileURLToPath as fileURLToPath2 } from "node:url";
@@ -61850,6 +61834,10 @@ function getExecutableNames(command) {
61850
61834
  // src/runners/tmux/client.ts
61851
61835
  var MAIN_WINDOW_NAME = "main";
61852
61836
  var TMUX_NOT_FOUND_CODE = "ENOENT";
61837
+ var TMUX_SERVER_DEFAULTS = [
61838
+ ["exit-empty", "off"],
61839
+ ["destroy-unattached", "off"]
61840
+ ];
61853
61841
 
61854
61842
  class TmuxClient {
61855
61843
  socketPath;
@@ -61909,6 +61897,14 @@ class TmuxClient {
61909
61897
  ${result.stdout}`.trim();
61910
61898
  return !output.includes("no server running");
61911
61899
  }
61900
+ async ensureServerDefaults() {
61901
+ if (!await this.isServerRunning()) {
61902
+ return;
61903
+ }
61904
+ for (const [name, value] of TMUX_SERVER_DEFAULTS) {
61905
+ await this.execOrThrow(["set-option", "-g", name, value]);
61906
+ }
61907
+ }
61912
61908
  async newSession(params) {
61913
61909
  await this.execOrThrow([
61914
61910
  "new-session",
@@ -61921,6 +61917,7 @@ ${result.stdout}`.trim();
61921
61917
  params.cwd,
61922
61918
  params.command
61923
61919
  ]);
61920
+ await this.ensureServerDefaults();
61924
61921
  await this.freezeWindowName(`${params.sessionName}:${MAIN_WINDOW_NAME}`);
61925
61922
  }
61926
61923
  async newWindow(params) {
@@ -64184,7 +64181,7 @@ ${params.text}
64184
64181
  }
64185
64182
  function renderAgentPromptInstruction(params) {
64186
64183
  const messageToolMode = (params.responseMode ?? "message-tool") === "message-tool";
64187
- const progressAllowed = messageToolMode && (params.streaming ?? "all") !== "off";
64184
+ const progressAllowed = messageToolMode && (params.streaming ?? "off") === "off";
64188
64185
  const lines = [
64189
64186
  `[${renderPromptTimestamp()}] ${renderIdentitySummary(params.identity)}`,
64190
64187
  "",
@@ -64281,7 +64278,7 @@ function buildReplyCommand(params) {
64281
64278
  }
64282
64279
  lines.push(" --final \\");
64283
64280
  lines.push(' --message "$(cat <<\\__CLISBOT_MESSAGE__');
64284
- lines.push("<short progress update>");
64281
+ lines.push("<user-facing reply>");
64285
64282
  lines.push("__CLISBOT_MESSAGE__");
64286
64283
  lines.push(')" \\');
64287
64284
  lines.push(" [--media /absolute/path/to/file]");
@@ -64295,7 +64292,7 @@ function buildReplyCommand(params) {
64295
64292
  }
64296
64293
  lines.push(" --final \\");
64297
64294
  lines.push(' --message "$(cat <<\\__CLISBOT_MESSAGE__');
64298
- lines.push("<short progress update>");
64295
+ lines.push("<user-facing reply>");
64299
64296
  lines.push("__CLISBOT_MESSAGE__");
64300
64297
  lines.push(')" \\');
64301
64298
  lines.push(" [--media /absolute/path/to/file]");
@@ -64947,11 +64944,50 @@ function extractScrolledAppend(previous, current) {
64947
64944
  }
64948
64945
  return "";
64949
64946
  }
64947
+ function deriveRunningInteractionText(previousSnapshot, currentSnapshot) {
64948
+ const previous = cleanInteractionSnapshot(previousSnapshot);
64949
+ const current = cleanInteractionSnapshot(currentSnapshot);
64950
+ if (!current || current === previous) {
64951
+ return "";
64952
+ }
64953
+ if (!previous) {
64954
+ return current;
64955
+ }
64956
+ return extractScrolledAppend(previous, current);
64957
+ }
64950
64958
  function deriveInteractionText(initialSnapshot, currentSnapshot) {
64951
64959
  const previous = cleanInteractionSnapshot(initialSnapshot);
64952
64960
  const current = cleanInteractionSnapshot(currentSnapshot);
64953
64961
  return extractScrolledAppend(previous, current) || diffText(previous, current);
64954
64962
  }
64963
+ function appendInteractionText(currentBody, nextDelta) {
64964
+ const trimmedCurrent = currentBody.trim();
64965
+ const trimmedDelta = nextDelta.trim();
64966
+ if (!trimmedDelta) {
64967
+ return trimmedCurrent;
64968
+ }
64969
+ if (!trimmedCurrent) {
64970
+ return trimmedDelta;
64971
+ }
64972
+ const currentLines = trimmedCurrent.split(`
64973
+ `);
64974
+ const deltaLines = trimmedDelta.split(`
64975
+ `);
64976
+ const maxOverlap = Math.min(currentLines.length, deltaLines.length, 8);
64977
+ let overlap = 0;
64978
+ for (let size = maxOverlap;size > 0; size -= 1) {
64979
+ const currentSuffix = currentLines.slice(currentLines.length - size).join(`
64980
+ `);
64981
+ const deltaPrefix = deltaLines.slice(0, size).join(`
64982
+ `);
64983
+ if (currentSuffix === deltaPrefix) {
64984
+ overlap = size;
64985
+ break;
64986
+ }
64987
+ }
64988
+ return [...currentLines, ...deltaLines.slice(overlap)].join(`
64989
+ `).trim();
64990
+ }
64955
64991
  function truncateTail(raw, maxChars) {
64956
64992
  if (raw.length <= maxChars) {
64957
64993
  return raw;
@@ -65729,6 +65765,9 @@ class RunnerSessionService {
65729
65765
  await ensureRunnerExitRecordDir(this.loadedConfig.stateDir, resolved.sessionName);
65730
65766
  const existing = await this.sessionState.getEntry(resolved.sessionKey);
65731
65767
  const serverRunning = await this.tmux.isServerRunning();
65768
+ if (serverRunning) {
65769
+ await this.tmux.ensureServerDefaults();
65770
+ }
65732
65771
  if (serverRunning && await this.tmux.hasSession(resolved.sessionName)) {
65733
65772
  logLatencyDebug("ensure-session-ready-existing-session", timingContext, {
65734
65773
  hasStoredSessionId: Boolean(existing?.sessionId)
@@ -66022,7 +66061,7 @@ async function monitorTmuxRun(params) {
66022
66061
  let previousSnapshot = params.initialSnapshot;
66023
66062
  let lastChangeAt = Date.now();
66024
66063
  let sawChange = false;
66025
- let lastVisibleSnapshot = "";
66064
+ let cumulativeInteractionSnapshot = "";
66026
66065
  let detachedNotified = params.detachedAlready;
66027
66066
  let firstMeaningfulDeltaLogged = false;
66028
66067
  if (params.prompt) {
@@ -66048,12 +66087,14 @@ async function monitorTmuxRun(params) {
66048
66087
  const snapshot = normalizePaneText(await params.tmux.capturePane(params.sessionName, params.captureLines));
66049
66088
  const now = Date.now();
66050
66089
  if (snapshot !== previousSnapshot) {
66090
+ const priorSnapshot = previousSnapshot;
66051
66091
  lastChangeAt = now;
66052
66092
  previousSnapshot = snapshot;
66053
- const interactionSnapshot = deriveInteractionText(params.initialSnapshot, snapshot);
66054
- if (interactionSnapshot && interactionSnapshot !== lastVisibleSnapshot) {
66093
+ const interactionDelta = deriveRunningInteractionText(priorSnapshot, snapshot);
66094
+ const nextInteractionSnapshot = appendInteractionText(cumulativeInteractionSnapshot, interactionDelta);
66095
+ if (nextInteractionSnapshot && nextInteractionSnapshot !== cumulativeInteractionSnapshot) {
66055
66096
  sawChange = true;
66056
- lastVisibleSnapshot = interactionSnapshot;
66097
+ cumulativeInteractionSnapshot = nextInteractionSnapshot;
66057
66098
  if (!firstMeaningfulDeltaLogged) {
66058
66099
  firstMeaningfulDeltaLogged = true;
66059
66100
  logLatencyDebug("tmux-first-meaningful-delta", params.timingContext, {
@@ -66062,7 +66103,7 @@ async function monitorTmuxRun(params) {
66062
66103
  });
66063
66104
  }
66064
66105
  await params.onRunning({
66065
- snapshot: interactionSnapshot,
66106
+ snapshot: cumulativeInteractionSnapshot,
66066
66107
  fullSnapshot: snapshot,
66067
66108
  initialSnapshot: params.initialSnapshot
66068
66109
  });
@@ -66071,14 +66112,14 @@ async function monitorTmuxRun(params) {
66071
66112
  if (!detachedNotified && now - params.startedAt >= params.maxRuntimeMs) {
66072
66113
  detachedNotified = true;
66073
66114
  await params.onDetached({
66074
- snapshot: deriveInteractionText(params.initialSnapshot, previousSnapshot),
66115
+ snapshot: cumulativeInteractionSnapshot || deriveInteractionText(params.initialSnapshot, previousSnapshot),
66075
66116
  fullSnapshot: previousSnapshot,
66076
66117
  initialSnapshot: params.initialSnapshot
66077
66118
  });
66078
66119
  }
66079
66120
  if (sawChange && now - lastChangeAt >= params.idleTimeoutMs) {
66080
66121
  await params.onCompleted({
66081
- snapshot: deriveInteractionText(params.initialSnapshot, previousSnapshot),
66122
+ snapshot: cumulativeInteractionSnapshot || deriveInteractionText(params.initialSnapshot, previousSnapshot),
66082
66123
  fullSnapshot: previousSnapshot,
66083
66124
  initialSnapshot: params.initialSnapshot
66084
66125
  });
@@ -66086,7 +66127,7 @@ async function monitorTmuxRun(params) {
66086
66127
  }
66087
66128
  if (!sawChange && now - params.startedAt >= params.noOutputTimeoutMs) {
66088
66129
  await params.onTimeout({
66089
- snapshot: deriveInteractionText(params.initialSnapshot, previousSnapshot),
66130
+ snapshot: cumulativeInteractionSnapshot || deriveInteractionText(params.initialSnapshot, previousSnapshot),
66090
66131
  fullSnapshot: previousSnapshot,
66091
66132
  initialSnapshot: params.initialSnapshot
66092
66133
  });
@@ -67402,18 +67443,6 @@ function parseAgentCommand(text, options = {}) {
67402
67443
  source: "slash"
67403
67444
  };
67404
67445
  }
67405
- if (lowered === "queue-list" || lowered === "queuelist") {
67406
- return {
67407
- type: "control",
67408
- name: "queue-list"
67409
- };
67410
- }
67411
- if (lowered === "queue-clear" || lowered === "queueclear") {
67412
- return {
67413
- type: "control",
67414
- name: "queue-clear"
67415
- };
67416
- }
67417
67446
  if (lowered === "loop") {
67418
67447
  const loopText = withoutSlash.slice(command.length).trim();
67419
67448
  const loweredLoopText = loopText.toLowerCase();
@@ -67461,9 +67490,37 @@ function parseAgentCommand(text, options = {}) {
67461
67490
  };
67462
67491
  }
67463
67492
  if (lowered === "queue" || lowered === "q") {
67493
+ const queueText = withoutSlash.slice(command.length).trim();
67494
+ const normalizedQueueText = queueText.toLowerCase();
67495
+ if (lowered === "queue") {
67496
+ if (normalizedQueueText === "list") {
67497
+ return {
67498
+ type: "control",
67499
+ name: "queue-list"
67500
+ };
67501
+ }
67502
+ if (normalizedQueueText === "clear") {
67503
+ return {
67504
+ type: "control",
67505
+ name: "queue-clear"
67506
+ };
67507
+ }
67508
+ }
67464
67509
  return {
67465
67510
  type: "queue",
67466
- text: withoutSlash.slice(command.length).trim()
67511
+ text: queueText
67512
+ };
67513
+ }
67514
+ if (lowered === "queue-list" || lowered === "queuelist") {
67515
+ return {
67516
+ type: "control",
67517
+ name: "queue-list"
67518
+ };
67519
+ }
67520
+ if (lowered === "queue-clear" || lowered === "queueclear") {
67521
+ return {
67522
+ type: "control",
67523
+ name: "queue-clear"
67467
67524
  };
67468
67525
  }
67469
67526
  if (lowered === "steer" || lowered === "s") {
@@ -67511,11 +67568,7 @@ function renderAgentControlSlashHelp() {
67511
67568
  "- `/followup mention-only`: require explicit mention for each later turn",
67512
67569
  "- `/followup pause`: stop passive follow-up until the next explicit mention",
67513
67570
  "- `/followup resume`: clear the runtime override and restore config defaults",
67514
- "- `/streaming status`: show the configured streaming mode for this surface",
67515
- "- `/streaming on`: enable streaming for this surface using the current `all` preview behavior",
67516
- "- `/streaming off`: disable surface streaming previews for this surface",
67517
- "- `/streaming latest`: prefer the latest preview shape for this surface",
67518
- "- `/streaming all`: retain the full current preview shape for this surface",
67571
+ "- `/streaming status|on|off|latest|all`: show or change streaming mode for this surface",
67519
67572
  "- `/responsemode status`: show the configured response mode for this surface",
67520
67573
  "- `/responsemode capture-pane`: settle replies from captured pane output for this surface",
67521
67574
  "- `/responsemode message-tool`: expect the agent to reply through `clisbot message send` for this surface",
@@ -67524,8 +67577,8 @@ function renderAgentControlSlashHelp() {
67524
67577
  "- `/additionalmessagemode queue`: queue later user messages behind the active run for this surface",
67525
67578
  "- `/queue <message>` or `\\q <message>`: enqueue a later message behind the active run and let clisbot deliver it in order",
67526
67579
  "- `/steer <message>` or `\\s <message>`: inject a steering message into the active run immediately",
67527
- "- `/queue-list`: show queued messages that have not started yet",
67528
- "- `/queue-clear`: clear queued messages that have not started yet",
67580
+ "- `/queue list`: show queued messages that have not started yet",
67581
+ "- `/queue clear`: clear queued messages that have not started yet",
67529
67582
  ...renderLoopHelpLines(),
67530
67583
  "- `/bash` followed by a shell command: requires `shellExecute` on the resolved agent role",
67531
67584
  "- shortcut prefixes such as `!` run bash only when the resolved agent role allows `shellExecute`",
@@ -67703,7 +67756,7 @@ function renderRouteStatusMessage(params) {
67703
67756
  lines.push(`- \`${loop.id}\` ${renderLoopStatusSchedule(loop)} remaining \`${loop.remainingRuns}\` nextRunAt \`${new Date(loop.nextRunAt).toISOString()}\``);
67704
67757
  }
67705
67758
  }
67706
- lines.push("", "Useful commands:", "- `/help`", "- `/whoami`", "- `/status`", "- `/attach`, `/detach`, `/watch every 30s`", "- `/followup status`", "- `/streaming status`", "- `/responsemode status`", "- `/additionalmessagemode status`", "- `/loop status`, `/loop cancel`, `/loop cancel <id>`", "- `/queue <message>`, `/steer <message>`", "- `/queue-list`, `/queue-clear`", params.route.verbose === "off" ? "- `/transcript` disabled on this route (`verbose: off`)" : "- `/transcript` enabled on this route (`verbose: minimal`)", "- `/bash` requires `shellExecute`");
67759
+ lines.push("", "Useful commands:", "- `/help`", "- `/whoami`", "- `/status`", "- `/attach`, `/detach`, `/watch every 30s`", "- `/followup status`", "- `/streaming status|on|off|latest|all`", "- `/responsemode status`", "- `/additionalmessagemode status`", "- `/loop status`, `/loop cancel`, `/loop cancel <id>`", "- `/queue <message>`, `/steer <message>`", "- `/queue list`, `/queue clear`", params.route.verbose === "off" ? "- `/transcript` disabled on this route (`verbose: off`)" : "- `/transcript` enabled on this route (`verbose: minimal`)", "- `/bash` requires `shellExecute`");
67707
67760
  return lines.join(`
67708
67761
  `);
67709
67762
  }
@@ -67941,7 +67994,7 @@ async function executePromptDelivery(params) {
67941
67994
  let finalReplyRecorded = false;
67942
67995
  let loggedFirstRunningUpdate = false;
67943
67996
  let activePreviewStartedAt;
67944
- let lastFrozenPreviewText;
67997
+ let messageToolPreviewHandedOff = false;
67945
67998
  const paneManagedDelivery = params.route.responseMode === "capture-pane" || params.forceQueuedDelivery === true;
67946
67999
  const messageToolPreview = params.route.responseMode === "message-tool" && params.forceQueuedDelivery !== true && params.route.streaming !== "off";
67947
68000
  const previewEnabled = params.route.streaming !== "off" && (paneManagedDelivery || messageToolPreview);
@@ -67977,11 +68030,12 @@ async function executePromptDelivery(params) {
67977
68030
  renderedState = undefined;
67978
68031
  activePreviewStartedAt = undefined;
67979
68032
  }
67980
- function resetPreviewBoundary() {
67981
- lastFrozenPreviewText = renderedState?.text ?? lastFrozenPreviewText;
67982
- responseChunks = [];
67983
- renderedState = undefined;
67984
- activePreviewStartedAt = undefined;
68033
+ async function handoffMessageToolPreview() {
68034
+ if (messageToolPreviewHandedOff) {
68035
+ return;
68036
+ }
68037
+ messageToolPreviewHandedOff = true;
68038
+ await clearResponseText();
67985
68039
  }
67986
68040
  async function getMessageToolRuntimeSignals() {
67987
68041
  if (params.route.responseMode !== "message-tool" || params.forceQueuedDelivery === true) {
@@ -68035,13 +68089,12 @@ async function executePromptDelivery(params) {
68035
68089
  }
68036
68090
  await (renderChain = renderChain.then(async () => {
68037
68091
  const signals = await getMessageToolRuntimeSignals();
68038
- if (messageToolPreview && typeof activePreviewStartedAt === "number" && typeof signals.messageToolFinalReplyAt === "number" && signals.messageToolFinalReplyAt >= activePreviewStartedAt) {
68039
- lastFrozenPreviewText = renderedState?.text ?? lastFrozenPreviewText;
68040
- activePreviewStartedAt = undefined;
68092
+ if (messageToolPreview && typeof activePreviewStartedAt === "number" && (typeof signals.messageToolFinalReplyAt === "number" && signals.messageToolFinalReplyAt >= activePreviewStartedAt || typeof signals.lastMessageToolReplyAt === "number" && signals.lastMessageToolReplyAt >= activePreviewStartedAt)) {
68093
+ await handoffMessageToolPreview();
68041
68094
  return;
68042
68095
  }
68043
- if (messageToolPreview && typeof activePreviewStartedAt === "number" && typeof signals.lastMessageToolReplyAt === "number" && signals.lastMessageToolReplyAt >= activePreviewStartedAt) {
68044
- resetPreviewBoundary();
68096
+ if (messageToolPreview) {
68097
+ return;
68045
68098
  }
68046
68099
  const nextState2 = buildRenderedMessageState({
68047
68100
  platform: params.identity.platform,
@@ -68057,9 +68110,6 @@ async function executePromptDelivery(params) {
68057
68110
  if (renderedState?.text === nextState2.text) {
68058
68111
  return;
68059
68112
  }
68060
- if (!renderedState && lastFrozenPreviewText === nextState2.text) {
68061
- return;
68062
- }
68063
68113
  const postedNew2 = await renderResponseText(nextState2.text);
68064
68114
  if (postedNew2) {
68065
68115
  await recordVisibleReply("reply", "channel");
@@ -68107,6 +68157,9 @@ async function executePromptDelivery(params) {
68107
68157
  }
68108
68158
  const finalResult = await result;
68109
68159
  await renderChain;
68160
+ if (!paneManagedDelivery && messageToolPreviewHandedOff) {
68161
+ return;
68162
+ }
68110
68163
  const nextState = buildRenderedMessageState({
68111
68164
  platform: params.identity.platform,
68112
68165
  status: finalResult.status,
@@ -68152,6 +68205,21 @@ async function executePromptDelivery(params) {
68152
68205
  if (finalResult.status === "completed") {
68153
68206
  return;
68154
68207
  }
68208
+ if (messageToolPreview && responseChunks.length > 0) {
68209
+ const postedNew2 = await renderResponseText(renderPlatformInteraction({
68210
+ platform: params.identity.platform,
68211
+ status: finalResult.status,
68212
+ content: "",
68213
+ maxChars: Number.POSITIVE_INFINITY,
68214
+ note: finalResult.note,
68215
+ allowTranscriptInspection: allowTranscriptInspectionForRoute(params.route),
68216
+ responsePolicy: params.route.response
68217
+ }));
68218
+ if (postedNew2) {
68219
+ await recordVisibleReply("reply", "channel");
68220
+ }
68221
+ return;
68222
+ }
68155
68223
  if (params.route.streaming === "off" || responseChunks.length === 0) {
68156
68224
  const postedNew2 = await renderResponseText(renderPlatformInteraction({
68157
68225
  platform: params.identity.platform,
@@ -68921,7 +68989,10 @@ function resolvePrivilegeCommands(rootConfig, override) {
68921
68989
 
68922
68990
  // src/channels/route-policy.ts
68923
68991
  function buildSharedChannelRoute(params) {
68924
- const privilegeCommands = resolvePrivilegeCommands(params.channelConfig.privilegeCommands, params.route?.privilegeCommands);
68992
+ const privilegeCommands = resolvePrivilegeCommands(params.channelConfig.privilegeCommands ?? {
68993
+ enabled: false,
68994
+ allowUsers: []
68995
+ }, params.route?.privilegeCommands);
68925
68996
  const agentId = params.route?.agentId ?? resolveTopLevelBoundAgentId(params.loadedConfig, {
68926
68997
  channel: params.channel,
68927
68998
  accountId: params.accountId
@@ -71271,8 +71342,10 @@ var TELEGRAM_FULL_COMMANDS = [
71271
71342
  { command: "followup", description: "Show or change follow-up mode" },
71272
71343
  { command: "streaming", description: "Show or change streaming mode" },
71273
71344
  { command: "responsemode", description: "Show or change response mode" },
71345
+ { command: "additionalmessagemode", description: "Show or change later-message mode" },
71274
71346
  { command: "queue", description: "Queue a later message behind the active run" },
71275
71347
  { command: "steer", description: "Steer the active run immediately" },
71348
+ { command: "loop", description: "Show or manage loops for this route" },
71276
71349
  { command: "bash", description: "Run bash in the agent workspace" }
71277
71350
  ];
71278
71351
  var TELEGRAM_STARTUP_CONFLICT_MAX_WAIT_MS = 6000;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clisbot",
3
- "version": "0.1.15",
3
+ "version": "0.1.17",
4
4
  "private": false,
5
5
  "description": "Chat surfaces for durable AI coding agents running in tmux",
6
6
  "license": "MIT",