repoburg 1.3.260 → 1.3.262

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.
@@ -16108,20 +16108,20 @@ var require_resolve = __commonJS({
16108
16108
  return false;
16109
16109
  }
16110
16110
  function countKeys(schema) {
16111
- let count = 0;
16111
+ let count2 = 0;
16112
16112
  for (const key in schema) {
16113
16113
  if (key === "$ref")
16114
16114
  return Infinity;
16115
- count++;
16115
+ count2++;
16116
16116
  if (SIMPLE_INLINED.has(key))
16117
16117
  continue;
16118
16118
  if (typeof schema[key] == "object") {
16119
- (0, util_1.eachItem)(schema[key], (sch) => count += countKeys(sch));
16119
+ (0, util_1.eachItem)(schema[key], (sch) => count2 += countKeys(sch));
16120
16120
  }
16121
- if (count === Infinity)
16121
+ if (count2 === Infinity)
16122
16122
  return Infinity;
16123
16123
  }
16124
- return count;
16124
+ return count2;
16125
16125
  }
16126
16126
  function getFullPath(resolver, id = "", normalize) {
16127
16127
  if (normalize !== false)
@@ -19319,8 +19319,8 @@ var require_contains = __commonJS({
19319
19319
  cxt.result(valid, () => cxt.reset());
19320
19320
  function validateItemsWithCount() {
19321
19321
  const schValid = gen.name("_valid");
19322
- const count = gen.let("count", 0);
19323
- validateItems(schValid, () => gen.if(schValid, () => checkLimits(count)));
19322
+ const count2 = gen.let("count", 0);
19323
+ validateItems(schValid, () => gen.if(schValid, () => checkLimits(count2)));
19324
19324
  }
19325
19325
  function validateItems(_valid, block) {
19326
19326
  gen.forRange("i", 0, len, (i) => {
@@ -19333,16 +19333,16 @@ var require_contains = __commonJS({
19333
19333
  block();
19334
19334
  });
19335
19335
  }
19336
- function checkLimits(count) {
19337
- gen.code((0, codegen_1._)`${count}++`);
19336
+ function checkLimits(count2) {
19337
+ gen.code((0, codegen_1._)`${count2}++`);
19338
19338
  if (max === void 0) {
19339
- gen.if((0, codegen_1._)`${count} >= ${min}`, () => gen.assign(valid, true).break());
19339
+ gen.if((0, codegen_1._)`${count2} >= ${min}`, () => gen.assign(valid, true).break());
19340
19340
  } else {
19341
- gen.if((0, codegen_1._)`${count} > ${max}`, () => gen.assign(valid, false).break());
19341
+ gen.if((0, codegen_1._)`${count2} > ${max}`, () => gen.assign(valid, false).break());
19342
19342
  if (min === 1)
19343
19343
  gen.assign(valid, true);
19344
19344
  else
19345
- gen.if((0, codegen_1._)`${count} >= ${min}`, () => gen.assign(valid, true));
19345
+ gen.if((0, codegen_1._)`${count2} >= ${min}`, () => gen.assign(valid, true));
19346
19346
  }
19347
19347
  }
19348
19348
  }
@@ -21689,9 +21689,9 @@ var require_parseJson = __commonJS({
21689
21689
  pos++;
21690
21690
  } else if (c === "u") {
21691
21691
  pos++;
21692
- let count = 4;
21692
+ let count2 = 4;
21693
21693
  let code = 0;
21694
- while (count--) {
21694
+ while (count2--) {
21695
21695
  code <<= 4;
21696
21696
  c = s[pos];
21697
21697
  if (c === void 0) {
@@ -36953,7 +36953,7 @@ var require_fastify_plugin = __commonJS({
36953
36953
  "use strict";
36954
36954
  var getPluginName = require_getPluginName();
36955
36955
  var toCamelCase = require_toCamelCase();
36956
- var count = 0;
36956
+ var count2 = 0;
36957
36957
  function plugin(fn, options = {}) {
36958
36958
  let autoName = false;
36959
36959
  if (fn.default !== void 0) {
@@ -36977,7 +36977,7 @@ var require_fastify_plugin = __commonJS({
36977
36977
  }
36978
36978
  if (!options.name) {
36979
36979
  autoName = true;
36980
- options.name = getPluginName(fn) + "-auto-" + count++;
36980
+ options.name = getPluginName(fn) + "-auto-" + count2++;
36981
36981
  }
36982
36982
  fn[Symbol.for("skip-override")] = options.encapsulate !== true;
36983
36983
  fn[Symbol.for("fastify.display-name")] = options.name;
@@ -43612,6 +43612,19 @@ App state does NOT live in this folder \u2014 it is stored in the pane database
43612
43612
  - submitTurn(sessionId, prompt) - send a prompt to a session
43613
43613
  - onTurnCompleted(callback) - callback(event, { turnId, response }) when a turn ends
43614
43614
  - onToolCall(callback) - callback({ callId, name, tool, args }) when the AGENT calls one of the manifest tools (name and tool carry the same tool name); answer with resolveToolCall(callId, result)
43615
+ - openSession(sessionId) - show that session in the pane (the view switches to its conversation); works only while the app is on screen, so call it from a click handler
43616
+ - openUrl(url) - open an absolute http(s) URL in a new browser tab; call it from a click handler (popup blockers allow tabs opened by a click)
43617
+
43618
+ ## Links and navigation
43619
+
43620
+ The app runs in a sandboxed frame. Never navigate the frame itself
43621
+ (location.href = ...): the page would replace the app, and most sites
43622
+ refuse to be framed.
43623
+ - external pages: a plain <a href="https://..."> link opens in a new
43624
+ browser tab (target="_blank" works too); from code use
43625
+ AgentPane.openUrl(url)
43626
+ - sessions: AgentPane.openSession(id), e.g. a "session" link next to a
43627
+ job row (ids come from createSession)
43615
43628
 
43616
43629
  ## Agent tool calls (manifest "tools")
43617
43630
 
@@ -43626,7 +43639,8 @@ Headless contract for apps that declare tools:
43626
43639
  - headless state is the instance of the CALLING session's workspace
43627
43640
  ('' = global when the caller has no known workspace); open tabs
43628
43641
  sync via onStateChanged
43629
- - createSession/submitTurn are not available in the headless runtime
43642
+ - createSession/submitTurn/openSession/openUrl are not available in the
43643
+ headless runtime
43630
43644
 
43631
43645
  If the app cannot load headless (broken app.js, no handler), the pane
43632
43646
  falls back to relaying calls into the OPEN app iframe \u2014 the app must be
@@ -43678,6 +43692,13 @@ function readState(id) {
43678
43692
  return { pinned: false, data: null };
43679
43693
  }
43680
43694
  }
43695
+ function isRegularFile(p) {
43696
+ try {
43697
+ return fs.statSync(p).isFile();
43698
+ } catch {
43699
+ return false;
43700
+ }
43701
+ }
43681
43702
  var watcher = null;
43682
43703
  var pendingChanges = /* @__PURE__ */ new Map();
43683
43704
  var HOT_RELOAD_DEBOUNCE_MS = 250;
@@ -43692,6 +43713,7 @@ function startAppsWatch(onAppChange) {
43692
43713
  const appId = segs[0];
43693
43714
  const file = segs[segs.length - 1];
43694
43715
  if (!appId || appId === path3.basename(root) || !APP_ID_RE.test(appId) || file === "state.json") return;
43716
+ if (segs.length === 1 && isRegularFile(path3.join(root, appId))) return;
43695
43717
  const timer = pendingChanges.get(appId);
43696
43718
  if (timer) clearTimeout(timer);
43697
43719
  pendingChanges.set(
@@ -43795,6 +43817,12 @@ declare const AgentPane: {
43795
43817
  onToolCall(cb: (payload: AgentPaneToolCallPayload) => void): void;
43796
43818
  onStateChanged(cb: (payload: unknown) => void): void;
43797
43819
  resolveToolCall(callId: string, result?: unknown): Promise<{ ok: boolean }>;
43820
+ /** Show a session in the pane (switches the view to its conversation).
43821
+ * Only works while the app is on screen: call it from a click handler. */
43822
+ openSession(sessionId: string): Promise<{ ok: boolean }>;
43823
+ /** Open an absolute http(s) URL in a new browser tab. Call it from a click
43824
+ * handler: popup blockers allow tabs opened by a user gesture. */
43825
+ openUrl(url: string): Promise<{ ok: boolean }>;
43798
43826
  };
43799
43827
  `;
43800
43828
  var cache = /* @__PURE__ */ new Map();
@@ -44046,6 +44074,8 @@ function getHeadlessToolHandler(appId, workspace = "") {
44046
44074
  // UI-flow APIs are intentionally unavailable headless.
44047
44075
  createSession: () => Promise.reject(new Error("createSession is not available in the headless runtime")),
44048
44076
  submitTurn: () => Promise.reject(new Error("submitTurn is not available in the headless runtime")),
44077
+ openSession: () => Promise.reject(new Error("openSession is not available in the headless runtime")),
44078
+ openUrl: () => Promise.reject(new Error("openUrl is not available in the headless runtime")),
44049
44079
  onTurnCompleted: () => {
44050
44080
  },
44051
44081
  onTurnDelta: () => {
@@ -44230,6 +44260,7 @@ var SKELETON_TS = `// Skeleton mini app (TypeScript). window.AgentPane is the ty
44230
44260
  // getState() / setState(data) persistent state (survives reloads)
44231
44261
  // createSession / submitTurn talk to an agent session
44232
44262
  // onTurnCompleted / onToolCall react to agent events
44263
+ // openSession / openUrl show a session / open a page in a new tab
44233
44264
  interface Ui {
44234
44265
  ready: boolean;
44235
44266
  data: Record<string, unknown>;
@@ -45447,6 +45478,100 @@ var EFFORT_LABELS2 = {
45447
45478
  max: "Max"
45448
45479
  };
45449
45480
 
45481
+ // src/claude/claude-context.ts
45482
+ function count(n) {
45483
+ return typeof n === "number" && Number.isFinite(n) ? n : 0;
45484
+ }
45485
+ function lastMessageIteration(iterations) {
45486
+ if (!Array.isArray(iterations)) return null;
45487
+ for (let i = iterations.length - 1; i >= 0; i--) {
45488
+ const it = iterations[i];
45489
+ if (!it || typeof it !== "object") continue;
45490
+ if ((it.type === "message" || it.type === "fallback_message") && typeof it.input_tokens === "number") return it;
45491
+ }
45492
+ return null;
45493
+ }
45494
+ function contextTokensFromUsage(usage) {
45495
+ if (!usage || typeof usage !== "object") return null;
45496
+ const u = lastMessageIteration(usage.iterations) ?? usage;
45497
+ const read = count(u.input_tokens) + count(u.cache_creation_input_tokens) + count(u.cache_read_input_tokens);
45498
+ if (read <= 0) return null;
45499
+ return read + count(u.output_tokens);
45500
+ }
45501
+ function counterOf(entry) {
45502
+ if (!entry.context) {
45503
+ entry.context = {
45504
+ window: null,
45505
+ autoCompactThreshold: null,
45506
+ tokens: null,
45507
+ measured: false,
45508
+ apiMessageId: null,
45509
+ seq: 0,
45510
+ windowRequested: false,
45511
+ lastPublished: null
45512
+ };
45513
+ }
45514
+ return entry.context;
45515
+ }
45516
+ function publish(entry, sessionId, db2) {
45517
+ const ctx = counterOf(entry);
45518
+ if (ctx.tokens === null) return;
45519
+ if (!ctx.window) {
45520
+ if (!ctx.windowRequested) void refreshContext(entry, sessionId, db2);
45521
+ return;
45522
+ }
45523
+ const usage = {
45524
+ totalTokens: ctx.tokens,
45525
+ contextWindow: ctx.window,
45526
+ percentage: Math.round(ctx.tokens / ctx.window * 100),
45527
+ ...ctx.autoCompactThreshold ? { autoCompactThreshold: ctx.autoCompactThreshold } : {}
45528
+ };
45529
+ const json = JSON.stringify(usage);
45530
+ if (json === ctx.lastPublished) return;
45531
+ ctx.lastPublished = json;
45532
+ broadcast("turn:contextUsage", { sessionId, ...usage });
45533
+ db2.prepare("UPDATE sessions SET context_usage = ? WHERE id = ?").run(json, sessionId);
45534
+ }
45535
+ function recordApiUsage(entry, sessionId, db2, apiMessageId, usage) {
45536
+ if (entry.threadId) return;
45537
+ const tokens = contextTokensFromUsage(usage);
45538
+ if (tokens === null) return;
45539
+ const ctx = counterOf(entry);
45540
+ const id = apiMessageId ?? ctx.apiMessageId;
45541
+ if (ctx.measured && id !== null && id === ctx.apiMessageId && ctx.tokens !== null && tokens <= ctx.tokens) return;
45542
+ ctx.apiMessageId = id;
45543
+ ctx.tokens = tokens;
45544
+ ctx.measured = true;
45545
+ ctx.seq++;
45546
+ publish(entry, sessionId, db2);
45547
+ }
45548
+ function resetContext(entry, sessionId, db2) {
45549
+ if (entry.threadId) return;
45550
+ const ctx = counterOf(entry);
45551
+ ctx.tokens = null;
45552
+ ctx.measured = false;
45553
+ ctx.apiMessageId = null;
45554
+ ctx.seq++;
45555
+ void refreshContext(entry, sessionId, db2);
45556
+ }
45557
+ async function refreshContext(entry, sessionId, db2) {
45558
+ if (entry.threadId) return;
45559
+ const ctx = counterOf(entry);
45560
+ ctx.windowRequested = true;
45561
+ const seq = ctx.seq;
45562
+ try {
45563
+ const snap = await entry.query.getContextUsage({ detail: "summary" });
45564
+ if (snap.maxTokens > 0) {
45565
+ ctx.window = snap.maxTokens;
45566
+ ctx.autoCompactThreshold = snap.isAutoCompactEnabled && snap.autoCompactThreshold && snap.autoCompactThreshold > 0 ? snap.autoCompactThreshold : null;
45567
+ }
45568
+ if (ctx.seq === seq && !ctx.measured && snap.totalTokens > 0) ctx.tokens = snap.totalTokens;
45569
+ } catch {
45570
+ return;
45571
+ }
45572
+ publish(entry, sessionId, db2);
45573
+ }
45574
+
45450
45575
  // src/claude/claude-provider.ts
45451
45576
  var PromptQueue = class {
45452
45577
  buffer = [];
@@ -45705,6 +45830,7 @@ async function handleMessage(message, sessionId, turnId, entry, db2) {
45705
45830
  turnId,
45706
45831
  db2
45707
45832
  );
45833
+ resetContext(entry, sessionId, db2);
45708
45834
  } else if (sub === "task_started") {
45709
45835
  handleTaskStarted(
45710
45836
  message,
@@ -45741,7 +45867,7 @@ async function handleMessage(message, sessionId, turnId, entry, db2) {
45741
45867
  break;
45742
45868
  }
45743
45869
  case "assistant": {
45744
- handleAssistantMessage(message, sessionId, turnId, db2);
45870
+ handleAssistantMessage(message, sessionId, turnId, entry, db2);
45745
45871
  break;
45746
45872
  }
45747
45873
  case "user": {
@@ -45749,19 +45875,23 @@ async function handleMessage(message, sessionId, turnId, entry, db2) {
45749
45875
  break;
45750
45876
  }
45751
45877
  case "stream_event": {
45752
- handleStreamEvent(message, sessionId, turnId);
45878
+ handleStreamEvent(message, sessionId, turnId, entry, db2);
45753
45879
  break;
45754
45880
  }
45755
45881
  case "result": {
45756
45882
  handleResultMessage(message, sessionId, turnId, entry, db2);
45757
45883
  break;
45758
45884
  }
45885
+ case "conversation_reset": {
45886
+ resetContext(entry, sessionId, db2);
45887
+ break;
45888
+ }
45759
45889
  default:
45760
45890
  break;
45761
45891
  }
45762
45892
  }
45763
45893
  var TOOL_CALL_TYPES = /* @__PURE__ */ new Set(["command_execution", "file_change", "mcp_tool_call"]);
45764
- function handleAssistantMessage(message, sessionId, turnId, db2) {
45894
+ function handleAssistantMessage(message, sessionId, turnId, entry, db2) {
45765
45895
  const messageId = message.uuid;
45766
45896
  const parentToolUseId = message.parent_tool_use_id ?? null;
45767
45897
  if (parentToolUseId) {
@@ -45771,6 +45901,9 @@ function handleAssistantMessage(message, sessionId, turnId, db2) {
45771
45901
  db2.prepare("UPDATE turns SET external_turn_id = ?, updated_at = ? WHERE id = ?").run(messageId, nowExt2, turnId);
45772
45902
  return;
45773
45903
  }
45904
+ if (message.message?.model !== "<synthetic>") {
45905
+ recordApiUsage(entry, sessionId, db2, message.message?.id ?? null, message.message?.usage);
45906
+ }
45774
45907
  const content = message.message.content;
45775
45908
  const anthropicMsgId = message.message?.id ?? messageId;
45776
45909
  const thinkingTexts = thinkingAccumulator.get(messageId);
@@ -45827,12 +45960,19 @@ function handleUserMessage(message, sessionId, turnId, db2) {
45827
45960
  );
45828
45961
  }
45829
45962
  }
45830
- function handleStreamEvent(message, sessionId, turnId) {
45963
+ function handleStreamEvent(message, sessionId, turnId, entry, db2) {
45831
45964
  const rawEvent = message.event;
45832
45965
  const parentToolUseId = message.parent_tool_use_id ?? null;
45833
45966
  if (rawEvent.type === "message_start" && rawEvent.message?.id && !parentToolUseId) {
45834
45967
  streamingMessageIds.set(turnId, rawEvent.message.id);
45835
45968
  }
45969
+ if (!parentToolUseId) {
45970
+ if (rawEvent.type === "message_start" && rawEvent.message?.id) {
45971
+ recordApiUsage(entry, sessionId, db2, rawEvent.message.id, rawEvent.message.usage);
45972
+ } else if (rawEvent.type === "message_delta") {
45973
+ recordApiUsage(entry, sessionId, db2, null, rawEvent.usage);
45974
+ }
45975
+ }
45836
45976
  const delta = mapPartialDelta(message.event);
45837
45977
  if (!delta) return;
45838
45978
  if (parentToolUseId) return;
@@ -46011,24 +46151,7 @@ async function handleResultMessage(message, sessionId, turnId, entry, db2) {
46011
46151
  const now = (/* @__PURE__ */ new Date()).toISOString();
46012
46152
  db2.prepare("UPDATE turns SET token_usage = ?, updated_at = ? WHERE id = ?").run(JSON.stringify(usage), now, turnId);
46013
46153
  broadcast("turn:tokenUsage", { sessionId, turnId, usage });
46014
- try {
46015
- const ctx = await entry.query.getContextUsage();
46016
- if (ctx.totalTokens > 0 && ctx.maxTokens > 0) {
46017
- const contextUsage = {
46018
- totalTokens: ctx.totalTokens,
46019
- contextWindow: ctx.maxTokens,
46020
- percentage: Math.round(ctx.percentage)
46021
- };
46022
- broadcast("turn:contextUsage", { sessionId, ...contextUsage });
46023
- const cuNow = (/* @__PURE__ */ new Date()).toISOString();
46024
- db2.prepare("UPDATE sessions SET context_usage = ?, updated_at = ? WHERE id = ?").run(
46025
- JSON.stringify(contextUsage),
46026
- cuNow,
46027
- sessionId
46028
- );
46029
- }
46030
- } catch {
46031
- }
46154
+ await refreshContext(entry, sessionId, db2);
46032
46155
  completeTurn(db2, sessionId, turnId, usage);
46033
46156
  } else {
46034
46157
  const errorMsg = message.errors?.join("; ") ?? "Claude turn failed";
@@ -46188,6 +46311,7 @@ async function setModel(sessionId, model) {
46188
46311
  const entry = sessionMap2.get(sessionId);
46189
46312
  if (!entry) return;
46190
46313
  await entry.query.setModel(model);
46314
+ void refreshContext(entry, sessionId, getDb());
46191
46315
  }
46192
46316
  async function stopTask(sessionId, taskId) {
46193
46317
  const entry = sessionMap2.get(sessionId);