clisbot 0.1.53-beta.2 → 0.1.53-beta.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.
Files changed (2) hide show
  1. package/dist/main.js +45 -65
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -84887,7 +84887,7 @@ function renderLoopsHelp(channel) {
84887
84887
  " - if runtime is stopped, recurring loops activate on the next `clisbot start`",
84888
84888
  " - global `cancel --all` clears the whole app; scoped `cancel --all` clears one routed session",
84889
84889
  ` - \`cancel --all ${LOOP_APP_FLAG}\` is accepted only with a scoped session target, matching \`/loop cancel --all ${LOOP_APP_FLAG}\``,
84890
- " - one-shot count loops run synchronously in the CLI; durable one-shot prompts use `clisbot queues`",
84890
+ " - one-shot count loops reserve all iterations immediately as durable queue items for the routed session",
84891
84891
  " - wall-clock loop timezone resolves from `--timezone`, route/topic, agent, bot, app timezone, then legacy defaults, then host",
84892
84892
  " - calendar loops freeze the resolved effective timezone at creation time; if timing looks wrong, run `clisbot timezone get` first and inspect agent or route timezone only for scoped overrides"
84893
84893
  ].join(`
@@ -84924,7 +84924,8 @@ function renderLoopsCreateHelp(channel) {
84924
84924
  " - create without `--sender` fails by design",
84925
84925
  " - the `--sender` platform must match `--channel`",
84926
84926
  " - recurring CLI-created loops persist creator metadata into the session store",
84927
- " - CLI-created loop prompts inherit the normal clisbot prompt config unless `--progress <count>` is provided"
84927
+ " - CLI-created loop prompts inherit the normal clisbot prompt config unless `--progress <count>` is provided",
84928
+ " - count/times loops reserve their iterations immediately as durable queue items and do not create recurring loop records"
84928
84929
  ].join(`
84929
84930
  `);
84930
84931
  }
@@ -85047,7 +85048,6 @@ async function getScopedLoopCounts(params) {
85047
85048
  }
85048
85049
 
85049
85050
  // src/control/commands/loops-cli.ts
85050
- var LOOP_BUSY_RETRY_MS = 250;
85051
85051
  var LOOP_CONFIRM_FLAG = "--confirm";
85052
85052
  var LOOP_PROGRESS_FLAG = "--progress";
85053
85053
  var LOOP_SENDER_FLAG = "--sender";
@@ -85190,52 +85190,37 @@ async function cancelScopedLoops(state, args, addressing) {
85190
85190
  }
85191
85191
  await cancelOneScopedLoop(state, context, sessionLoops, targetLoopId);
85192
85192
  }
85193
- async function waitForSessionIdle(agentService, target) {
85194
- while (true) {
85195
- try {
85196
- const runtime = await agentService.getSessionRuntime(target);
85197
- if (runtime.state !== "running") {
85198
- return;
85199
- }
85200
- } catch {
85201
- return;
85202
- }
85203
- await sleep(LOOP_BUSY_RETRY_MS);
85204
- }
85193
+ function createCountLoopQueueItem(params) {
85194
+ return createStoredQueueItem({
85195
+ promptText: params.promptText,
85196
+ protectedControlMutationRule: resolveProtectedControlMutationRule(params.state, params.request.context.sessionTarget.agentId, params.request.creator),
85197
+ promptSummary: summarizeLoopPrompt(params.request.resolvedPrompt.text, params.request.resolvedPrompt.maintenancePrompt),
85198
+ createdBy: params.request.creator.providerId,
85199
+ sender: params.request.creator,
85200
+ surfaceBinding: buildStoredSurfaceBinding({
85201
+ ...params.request.context.identity,
85202
+ botId: params.request.context.botId
85203
+ })
85204
+ });
85205
85205
  }
85206
- async function executeCountLoop(params) {
85207
- const agentService = new AgentService(params.state.loadedConfig);
85208
- const builtPrompt = params.context.buildLoopPromptText(params.promptText, params.progressMessages == null ? undefined : {
85209
- maxProgressMessagesOverride: params.progressMessages
85206
+ async function createCountLoopQueueItems(state, request, count) {
85207
+ const context = request.deliveryContext ?? request.context;
85208
+ const builtPrompt = context.buildLoopPromptText(request.resolvedPrompt.text, request.progressMessages == null ? undefined : {
85209
+ maxProgressMessagesOverride: request.progressMessages
85210
85210
  });
85211
+ for (let index = 0;index < count; index += 1) {
85212
+ await state.sessionState.setQueuedItem(request.resolvedTarget, createCountLoopQueueItem({
85213
+ request,
85214
+ state,
85215
+ promptText: builtPrompt
85216
+ }));
85217
+ }
85211
85218
  console.log(renderLoopStartedMessage({
85212
85219
  mode: "times",
85213
- count: params.count,
85214
- maintenancePrompt: params.maintenancePrompt
85220
+ count,
85221
+ maintenancePrompt: request.resolvedPrompt.maintenancePrompt
85215
85222
  }));
85216
- try {
85217
- for (let index = 0;index < params.count; index += 1) {
85218
- while (true) {
85219
- await waitForSessionIdle(agentService, params.context.sessionTarget);
85220
- try {
85221
- await agentService.enqueuePrompt(params.context.sessionTarget, builtPrompt, {
85222
- onUpdate: () => {
85223
- return;
85224
- }
85225
- }).result;
85226
- break;
85227
- } catch (error) {
85228
- if (!(error instanceof ActiveRunInProgressError)) {
85229
- throw error;
85230
- }
85231
- await sleep(LOOP_BUSY_RETRY_MS);
85232
- }
85233
- }
85234
- }
85235
- } finally {
85236
- await agentService.stop();
85237
- }
85238
- console.log(`Completed ${params.count} iteration${params.count === 1 ? "" : "s"}.`);
85223
+ console.log(`Queued ${count} iteration${count === 1 ? "" : "s"} for \`${context.sessionTarget.sessionKey}\`.`);
85239
85224
  }
85240
85225
  function stripConfirmFlag(args) {
85241
85226
  return args.filter((arg) => arg !== LOOP_CONFIRM_FLAG);
@@ -85444,9 +85429,10 @@ function buildRecurringLoopCreateBase(state, request) {
85444
85429
  runtimeRunning: runtimeStatus.running
85445
85430
  }));
85446
85431
  }
85447
- function buildRecurringLoopPromptMetadata(request) {
85432
+ function buildRecurringLoopPromptMetadata(state, request) {
85448
85433
  return {
85449
85434
  promptText: request.resolvedPrompt.text,
85435
+ protectedControlMutationRule: resolveProtectedControlMutationRule(state, request.context.sessionTarget.agentId, request.creator),
85450
85436
  promptSummary: summarizeLoopPrompt(request.resolvedPrompt.text, request.resolvedPrompt.maintenancePrompt),
85451
85437
  promptSource: request.resolvedPrompt.maintenancePrompt ? "LOOP.md" : "custom",
85452
85438
  progressMessages: request.progressMessages,
@@ -85457,6 +85443,14 @@ function buildRecurringLoopPromptMetadata(request) {
85457
85443
  surfaceBinding: buildLoopSurfaceBinding2(request)
85458
85444
  };
85459
85445
  }
85446
+ function resolveProtectedControlMutationRule(state, agentId, sender) {
85447
+ const auth = resolvePrincipalAuth({
85448
+ config: state.loadedConfig.raw,
85449
+ agentId,
85450
+ principal: sender.senderId
85451
+ });
85452
+ return auth.mayManageProtectedResources ? undefined : DEFAULT_PROTECTED_CONTROL_RULE;
85453
+ }
85460
85454
  function buildRecurringLoopFirstRunNote(mode, runtimeRunning) {
85461
85455
  if (!runtimeRunning) {
85462
85456
  return "Runtime is not running, so this loop activates on the next `clisbot start`.";
@@ -85471,7 +85465,7 @@ async function createCalendarLoop(base) {
85471
85465
  if (parsed.mode !== "calendar") {
85472
85466
  return false;
85473
85467
  }
85474
- const metadata = buildRecurringLoopPromptMetadata(base.request);
85468
+ const metadata = buildRecurringLoopPromptMetadata(base.state, base.request);
85475
85469
  const timezone = resolveConfigTimezone({
85476
85470
  config: base.state.loadedConfig.raw,
85477
85471
  agentId: base.request.context.sessionTarget.agentId,
@@ -85549,7 +85543,7 @@ async function createIntervalLoop(base) {
85549
85543
  return;
85550
85544
  }
85551
85545
  const validation = requireValidIntervalLoop(parsed);
85552
- const metadata = buildRecurringLoopPromptMetadata(base.request);
85546
+ const metadata = buildRecurringLoopPromptMetadata(base.state, base.request);
85553
85547
  const loop = createStoredIntervalLoop({
85554
85548
  ...metadata,
85555
85549
  intervalMs: parsed.intervalMs,
@@ -85585,14 +85579,7 @@ async function createRecurringLoop(state, request) {
85585
85579
  async function createLoop(state, rawArgs, options = {}) {
85586
85580
  const request = await resolveLoopCreateRequest(state, rawArgs, options.explicitCreateSubcommand ?? false);
85587
85581
  if (request.parsed.mode === "times") {
85588
- await executeCountLoop({
85589
- state,
85590
- context: request.deliveryContext ?? request.context,
85591
- promptText: request.resolvedPrompt.text,
85592
- count: request.parsed.count,
85593
- maintenancePrompt: request.resolvedPrompt.maintenancePrompt,
85594
- progressMessages: request.progressMessages
85595
- });
85582
+ await createCountLoopQueueItems(state, request, request.parsed.count);
85596
85583
  return;
85597
85584
  }
85598
85585
  if (request.parsed.mode === "calendar" && !request.confirm && !await hasSuccessfulCalendarLoop(state)) {
@@ -86182,7 +86169,7 @@ function buildQueueSurfaceBinding(context) {
86182
86169
  botId: context.botId
86183
86170
  });
86184
86171
  }
86185
- function resolveProtectedControlMutationRule(state, agentId, sender) {
86172
+ function resolveProtectedControlMutationRule2(state, agentId, sender) {
86186
86173
  const auth = resolvePrincipalAuth({
86187
86174
  config: state.loadedConfig.raw,
86188
86175
  agentId,
@@ -86193,7 +86180,7 @@ function resolveProtectedControlMutationRule(state, agentId, sender) {
86193
86180
  function createQueueItemForContext(params) {
86194
86181
  return createStoredQueueItem({
86195
86182
  promptText: params.promptText,
86196
- protectedControlMutationRule: resolveProtectedControlMutationRule(params.state, params.context.sessionTarget.agentId, params.sender),
86183
+ protectedControlMutationRule: resolveProtectedControlMutationRule2(params.state, params.context.sessionTarget.agentId, params.sender),
86197
86184
  promptSummary: params.promptText,
86198
86185
  createdBy: params.sender.providerId,
86199
86186
  sender: params.sender,
@@ -87773,7 +87760,7 @@ function renderUpdateHelp() {
87773
87760
  ` 1. Migration index: ${GITHUB_RAW_BASE}/docs/migrations/index.md`,
87774
87761
  " If Manual action: required, follow its runbook. If none, continue.",
87775
87762
  ` 2. Update guide: ${GITHUB_RAW_BASE}/docs/updates/update-guide.md`,
87776
- " Use for target choice, install flow, verification, and wrong-publish recovery.",
87763
+ " Use for target choice, install flow, and verification.",
87777
87764
  ` 3. Release notes: ${GITHUB_RAW_BASE}/docs/releases/README.md`,
87778
87765
  " Use for the canonical version map and full version notes.",
87779
87766
  ` 4. Release guides: ${GITHUB_RAW_BASE}/docs/updates/README.md`,
@@ -87781,13 +87768,6 @@ function renderUpdateHelp() {
87781
87768
  " 5. Full docs: https://github.com/longbkit/clisbot/tree/main/docs",
87782
87769
  " Use for deep questions. If needed, fetch or clone docs and inspect relevant files.",
87783
87770
  "",
87784
- "Recovery:",
87785
- " - If a version was published by mistake, publish the corrected target or tag first.",
87786
- " - Then deprecate the wrong version.",
87787
- " - Start with `npm login` in an attached session.",
87788
- " - If npm returns a browser approval URL, keep that same session open and continue it after approval.",
87789
- " - If the write command still returns EOTP, ask the operator for a current OTP and rerun the exact command with --otp=<code>.",
87790
- "",
87791
87771
  "Rules:",
87792
87772
  " - Use npm dist-tags, not highest semver.",
87793
87773
  " - Stable/latest is default; beta only when the user asks.",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clisbot",
3
- "version": "0.1.53-beta.2",
3
+ "version": "0.1.53-beta.4",
4
4
  "private": false,
5
5
  "description": "Chat surfaces for durable AI coding agents running in tmux",
6
6
  "license": "MIT",