@songsid/agend 2.2.0-beta.15 → 2.2.0-beta.16

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.
@@ -855,6 +855,9 @@ export declare class FleetManager implements FleetContext, LifecycleContext, Arc
855
855
  /** #1218: the Log tab's on-demand service — made on first use; with `web.log_tab` off it answers off and does nothing. */
856
856
  private logService;
857
857
  private get log();
858
+ /** Board 003648ac: a web /compact followed to its end, from the transcript the Log reads (none: nothing to follow). */
859
+ private compactWatchService;
860
+ private get compactWatch();
858
861
  /** #1218: GET /ui/steps — an instance's steps, read on demand (null: no such instance). */
859
862
  logSteps(name: string, q: LogQuery): Promise<LogAnswer | null>;
860
863
  /**
@@ -194,6 +194,7 @@ import { GENERAL_PAUSE_ERROR, isGeneralInstance } from "./general-instance.js";
194
194
  import { buildOrgChart } from "./web-org.js";
195
195
  import { CacheService, WINDOWS } from "./cache-service.js";
196
196
  import { runWebCommand } from "./web-commands.js";
197
+ import { CompactWatch, launchIdentity } from "./compact-watch.js";
197
198
  import { claudeConfigDirFor, claudeProjectKey } from "./backend/claude-code.js";
198
199
  import { sharedRolloutIndex } from "./rollout-index.js";
199
200
  import { mayUseTool, resolveToolSet, scheduleOpRefusal, toolForIpcType, toolRefusedMessage, } from "./tool-permissions.js";
@@ -2811,6 +2812,24 @@ export class FleetManager {
2811
2812
  emit: (event, data) => this.emitSseEvent(event, data),
2812
2813
  });
2813
2814
  }
2815
+ /** Board 003648ac: a web /compact followed to its end, from the transcript the Log reads (none: nothing to follow). */
2816
+ compactWatchService = null;
2817
+ get compactWatch() {
2818
+ return this.compactWatchService ??= new CompactWatch({
2819
+ source: (name) => { const src = this.logSource(name); return { path: src.path, format: src.format }; },
2820
+ // The launch that runs it now (the same value the daemon sends with raw_paste_written).
2821
+ owner: (name) => {
2822
+ const daemon = this.lifecycle.daemons.get(name);
2823
+ try {
2824
+ return daemon ? launchIdentity(daemon.getInteractionSnapshot().owner) : null;
2825
+ }
2826
+ catch {
2827
+ return null;
2828
+ }
2829
+ },
2830
+ changed: () => this.emitSseEvent("status", this.getUiStatus()),
2831
+ });
2832
+ }
2814
2833
  /** #1218: GET /ui/steps — an instance's steps, read on demand (null: no such instance). */
2815
2834
  logSteps(name, q) { return this.log.steps(name, q); }
2816
2835
  /**
@@ -7257,6 +7276,11 @@ export class FleetManager {
7257
7276
  });
7258
7277
  }
7259
7278
  }
7279
+ else if (msg.type === "raw_paste_written") {
7280
+ // Board 003648ac: a web /compact's paste reached the pane (or never will): its watch starts, or ends as lost.
7281
+ if (typeof msg.id === "string")
7282
+ this.compactWatchService?.pasted(name, msg.id, msg.outcome === "written", { owner: msg.owner, checkpoint: msg.checkpoint });
7283
+ }
7260
7284
  else if (msg.type === "runtime_switch_result") {
7261
7285
  // #1690: what our own runtime /model came to (the daemon answered claude's "Switch model?" or saw the result).
7262
7286
  const waiter = typeof msg.id === "string" ? this.runtimeSwitchWaiters.get(msg.id) : undefined;
@@ -10259,6 +10283,7 @@ export class FleetManager {
10259
10283
  // must not be shown the old one's conversation, and deleted names must not pile up.
10260
10284
  this.webChatHistory.forget(name);
10261
10285
  this.webFiles.forget(name);
10286
+ this.compactWatchService?.forget(name);
10262
10287
  // #1664: and it is nobody's favorite any more (every device sees that at its next status frame).
10263
10288
  try {
10264
10289
  this.webPrefs.forgetInstance(name);
@@ -12666,7 +12691,22 @@ export class FleetManager {
12666
12691
  return this.classicChannels?.getChannelIdByInstance(instance) !== undefined ? "classic" : null;
12667
12692
  },
12668
12693
  ctx: (instance) => this.topicCommands.getCtxText(instance),
12669
- compact: (instance, instructions) => this.topicCommands.sendCompact(instance, instructions),
12694
+ // Board 003648ac: a watch for the paste, armed when the daemon says it was written (raw_paste_written); one
12695
+ // for a command that was not handed over is dropped.
12696
+ compact: async (instance, instructions) => {
12697
+ let watch = null;
12698
+ try {
12699
+ const r = this.topicCommands.compactInstance(instance, instructions, () => (watch = this.compactWatch.begin(instance)));
12700
+ if (!r.sent && watch)
12701
+ this.compactWatch.cancel(instance, watch);
12702
+ return { ...r, watch: r.sent ? watch : null };
12703
+ }
12704
+ catch (err) {
12705
+ if (watch)
12706
+ this.compactWatch.cancel(instance, watch);
12707
+ throw err;
12708
+ }
12709
+ },
12670
12710
  applyModel: (instance, name) => this.applyModel(instance, name),
12671
12711
  modelChoices: choicesFromCache,
12672
12712
  applyEffort: (instance, level) => this.applyEffort(instance, level),
@@ -12740,7 +12780,8 @@ export class FleetManager {
12740
12780
  // sendClear sends its first IPC synchronously: no await separates this check from the effect.
12741
12781
  if (this.shuttingDown || !entry.fence())
12742
12782
  return { status: 409, text: t("menu.click_stale") };
12743
- return { status: 200, text: await this.topicCommands.sendClear(instance) };
12783
+ const r = this.topicCommands.clearInstance(instance);
12784
+ return r.sent ? { status: 200, text: r.text, sent: true } : { status: 409, text: r.text };
12744
12785
  },
12745
12786
  t: (key, ...args) => t(key, ...args),
12746
12787
  }, input, opts);
@@ -17320,6 +17361,7 @@ Plus the operational skills (fleet-health, instance-lifecycle, scheduling, sessi
17320
17361
  this.eventLogPruneTimer = null;
17321
17362
  }
17322
17363
  this.logService?.unwatchAll(); // #1218: a Log's watch timers end with the fleet
17364
+ this.compactWatchService?.stopAll();
17323
17365
  if (this.outboxPruneTimer) {
17324
17366
  clearInterval(this.outboxPruneTimer);
17325
17367
  this.outboxPruneTimer = null;
@@ -19972,6 +20014,7 @@ Plus the operational skills (fleet-health, instance-lifecycle, scheduling, sessi
19972
20014
  const effort = (effortStrategy === "unsupported" || isAgy) ? null : effortResolved.effort;
19973
20015
  const effort_source = (effortStrategy === "unsupported" || isAgy) ? null : effortResolved.source;
19974
20016
  const identity = resolveInstanceIdentity({ cfg: this.fleetConfig?.instances[name], classic: classicRooms.get(name), profile: profiles.get(name) });
20017
+ const compact = this.compactWatchService?.view(name) ?? null;
19975
20018
  let image;
19976
20019
  try {
19977
20020
  image = this.webIdentityImage(name, identity.display_name, profiles.get(name)?.avatar_path, bots);
@@ -19999,6 +20042,8 @@ Plus the operational skills (fleet-health, instance-lifecycle, scheduling, sessi
19999
20042
  effort,
20000
20043
  effort_source,
20001
20044
  ...this.instancePresentation(name),
20045
+ // Board 003648ac: the last web /compact, while it runs and briefly after (the chat's card follows it).
20046
+ ...(compact ? { compact } : {}),
20002
20047
  };
20003
20048
  });
20004
20049
  return {