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;
@@ -43599,6 +43599,19 @@ App state does NOT live in this folder \u2014 it is stored in the pane database
43599
43599
  - submitTurn(sessionId, prompt) - send a prompt to a session
43600
43600
  - onTurnCompleted(callback) - callback(event, { turnId, response }) when a turn ends
43601
43601
  - 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)
43602
+ - 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
43603
+ - 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)
43604
+
43605
+ ## Links and navigation
43606
+
43607
+ The app runs in a sandboxed frame. Never navigate the frame itself
43608
+ (location.href = ...): the page would replace the app, and most sites
43609
+ refuse to be framed.
43610
+ - external pages: a plain <a href="https://..."> link opens in a new
43611
+ browser tab (target="_blank" works too); from code use
43612
+ AgentPane.openUrl(url)
43613
+ - sessions: AgentPane.openSession(id), e.g. a "session" link next to a
43614
+ job row (ids come from createSession)
43602
43615
 
43603
43616
  ## Agent tool calls (manifest "tools")
43604
43617
 
@@ -43613,7 +43626,8 @@ Headless contract for apps that declare tools:
43613
43626
  - headless state is the instance of the CALLING session's workspace
43614
43627
  ('' = global when the caller has no known workspace); open tabs
43615
43628
  sync via onStateChanged
43616
- - createSession/submitTurn are not available in the headless runtime
43629
+ - createSession/submitTurn/openSession/openUrl are not available in the
43630
+ headless runtime
43617
43631
 
43618
43632
  If the app cannot load headless (broken app.js, no handler), the pane
43619
43633
  falls back to relaying calls into the OPEN app iframe \u2014 the app must be
@@ -43665,6 +43679,13 @@ function readState(id) {
43665
43679
  return { pinned: false, data: null };
43666
43680
  }
43667
43681
  }
43682
+ function isRegularFile(p) {
43683
+ try {
43684
+ return fs.statSync(p).isFile();
43685
+ } catch {
43686
+ return false;
43687
+ }
43688
+ }
43668
43689
  var watcher = null;
43669
43690
  var pendingChanges = /* @__PURE__ */ new Map();
43670
43691
  var HOT_RELOAD_DEBOUNCE_MS = 250;
@@ -43679,6 +43700,7 @@ function startAppsWatch(onAppChange) {
43679
43700
  const appId = segs[0];
43680
43701
  const file = segs[segs.length - 1];
43681
43702
  if (!appId || appId === path3.basename(root) || !APP_ID_RE.test(appId) || file === "state.json") return;
43703
+ if (segs.length === 1 && isRegularFile(path3.join(root, appId))) return;
43682
43704
  const timer = pendingChanges.get(appId);
43683
43705
  if (timer) clearTimeout(timer);
43684
43706
  pendingChanges.set(
@@ -43782,6 +43804,12 @@ declare const AgentPane: {
43782
43804
  onToolCall(cb: (payload: AgentPaneToolCallPayload) => void): void;
43783
43805
  onStateChanged(cb: (payload: unknown) => void): void;
43784
43806
  resolveToolCall(callId: string, result?: unknown): Promise<{ ok: boolean }>;
43807
+ /** Show a session in the pane (switches the view to its conversation).
43808
+ * Only works while the app is on screen: call it from a click handler. */
43809
+ openSession(sessionId: string): Promise<{ ok: boolean }>;
43810
+ /** Open an absolute http(s) URL in a new browser tab. Call it from a click
43811
+ * handler: popup blockers allow tabs opened by a user gesture. */
43812
+ openUrl(url: string): Promise<{ ok: boolean }>;
43785
43813
  };
43786
43814
  `;
43787
43815
  var cache = /* @__PURE__ */ new Map();
@@ -44033,6 +44061,8 @@ function getHeadlessToolHandler(appId, workspace = "") {
44033
44061
  // UI-flow APIs are intentionally unavailable headless.
44034
44062
  createSession: () => Promise.reject(new Error("createSession is not available in the headless runtime")),
44035
44063
  submitTurn: () => Promise.reject(new Error("submitTurn is not available in the headless runtime")),
44064
+ openSession: () => Promise.reject(new Error("openSession is not available in the headless runtime")),
44065
+ openUrl: () => Promise.reject(new Error("openUrl is not available in the headless runtime")),
44036
44066
  onTurnCompleted: () => {
44037
44067
  },
44038
44068
  onTurnDelta: () => {
@@ -44217,6 +44247,7 @@ var SKELETON_TS = `// Skeleton mini app (TypeScript). window.AgentPane is the ty
44217
44247
  // getState() / setState(data) persistent state (survives reloads)
44218
44248
  // createSession / submitTurn talk to an agent session
44219
44249
  // onTurnCompleted / onToolCall react to agent events
44250
+ // openSession / openUrl show a session / open a page in a new tab
44220
44251
  interface Ui {
44221
44252
  ready: boolean;
44222
44253
  data: Record<string, unknown>;
@@ -45434,6 +45465,100 @@ var EFFORT_LABELS2 = {
45434
45465
  max: "Max"
45435
45466
  };
45436
45467
 
45468
+ // src/claude/claude-context.ts
45469
+ function count(n) {
45470
+ return typeof n === "number" && Number.isFinite(n) ? n : 0;
45471
+ }
45472
+ function lastMessageIteration(iterations) {
45473
+ if (!Array.isArray(iterations)) return null;
45474
+ for (let i = iterations.length - 1; i >= 0; i--) {
45475
+ const it = iterations[i];
45476
+ if (!it || typeof it !== "object") continue;
45477
+ if ((it.type === "message" || it.type === "fallback_message") && typeof it.input_tokens === "number") return it;
45478
+ }
45479
+ return null;
45480
+ }
45481
+ function contextTokensFromUsage(usage) {
45482
+ if (!usage || typeof usage !== "object") return null;
45483
+ const u = lastMessageIteration(usage.iterations) ?? usage;
45484
+ const read = count(u.input_tokens) + count(u.cache_creation_input_tokens) + count(u.cache_read_input_tokens);
45485
+ if (read <= 0) return null;
45486
+ return read + count(u.output_tokens);
45487
+ }
45488
+ function counterOf(entry) {
45489
+ if (!entry.context) {
45490
+ entry.context = {
45491
+ window: null,
45492
+ autoCompactThreshold: null,
45493
+ tokens: null,
45494
+ measured: false,
45495
+ apiMessageId: null,
45496
+ seq: 0,
45497
+ windowRequested: false,
45498
+ lastPublished: null
45499
+ };
45500
+ }
45501
+ return entry.context;
45502
+ }
45503
+ function publish(entry, sessionId, db2) {
45504
+ const ctx = counterOf(entry);
45505
+ if (ctx.tokens === null) return;
45506
+ if (!ctx.window) {
45507
+ if (!ctx.windowRequested) void refreshContext(entry, sessionId, db2);
45508
+ return;
45509
+ }
45510
+ const usage = {
45511
+ totalTokens: ctx.tokens,
45512
+ contextWindow: ctx.window,
45513
+ percentage: Math.round(ctx.tokens / ctx.window * 100),
45514
+ ...ctx.autoCompactThreshold ? { autoCompactThreshold: ctx.autoCompactThreshold } : {}
45515
+ };
45516
+ const json = JSON.stringify(usage);
45517
+ if (json === ctx.lastPublished) return;
45518
+ ctx.lastPublished = json;
45519
+ broadcast("turn:contextUsage", { sessionId, ...usage });
45520
+ db2.prepare("UPDATE sessions SET context_usage = ? WHERE id = ?").run(json, sessionId);
45521
+ }
45522
+ function recordApiUsage(entry, sessionId, db2, apiMessageId, usage) {
45523
+ if (entry.threadId) return;
45524
+ const tokens = contextTokensFromUsage(usage);
45525
+ if (tokens === null) return;
45526
+ const ctx = counterOf(entry);
45527
+ const id = apiMessageId ?? ctx.apiMessageId;
45528
+ if (ctx.measured && id !== null && id === ctx.apiMessageId && ctx.tokens !== null && tokens <= ctx.tokens) return;
45529
+ ctx.apiMessageId = id;
45530
+ ctx.tokens = tokens;
45531
+ ctx.measured = true;
45532
+ ctx.seq++;
45533
+ publish(entry, sessionId, db2);
45534
+ }
45535
+ function resetContext(entry, sessionId, db2) {
45536
+ if (entry.threadId) return;
45537
+ const ctx = counterOf(entry);
45538
+ ctx.tokens = null;
45539
+ ctx.measured = false;
45540
+ ctx.apiMessageId = null;
45541
+ ctx.seq++;
45542
+ void refreshContext(entry, sessionId, db2);
45543
+ }
45544
+ async function refreshContext(entry, sessionId, db2) {
45545
+ if (entry.threadId) return;
45546
+ const ctx = counterOf(entry);
45547
+ ctx.windowRequested = true;
45548
+ const seq = ctx.seq;
45549
+ try {
45550
+ const snap = await entry.query.getContextUsage({ detail: "summary" });
45551
+ if (snap.maxTokens > 0) {
45552
+ ctx.window = snap.maxTokens;
45553
+ ctx.autoCompactThreshold = snap.isAutoCompactEnabled && snap.autoCompactThreshold && snap.autoCompactThreshold > 0 ? snap.autoCompactThreshold : null;
45554
+ }
45555
+ if (ctx.seq === seq && !ctx.measured && snap.totalTokens > 0) ctx.tokens = snap.totalTokens;
45556
+ } catch {
45557
+ return;
45558
+ }
45559
+ publish(entry, sessionId, db2);
45560
+ }
45561
+
45437
45562
  // src/claude/claude-provider.ts
45438
45563
  var PromptQueue = class {
45439
45564
  buffer = [];
@@ -45692,6 +45817,7 @@ async function handleMessage(message, sessionId, turnId, entry, db2) {
45692
45817
  turnId,
45693
45818
  db2
45694
45819
  );
45820
+ resetContext(entry, sessionId, db2);
45695
45821
  } else if (sub === "task_started") {
45696
45822
  handleTaskStarted(
45697
45823
  message,
@@ -45728,7 +45854,7 @@ async function handleMessage(message, sessionId, turnId, entry, db2) {
45728
45854
  break;
45729
45855
  }
45730
45856
  case "assistant": {
45731
- handleAssistantMessage(message, sessionId, turnId, db2);
45857
+ handleAssistantMessage(message, sessionId, turnId, entry, db2);
45732
45858
  break;
45733
45859
  }
45734
45860
  case "user": {
@@ -45736,19 +45862,23 @@ async function handleMessage(message, sessionId, turnId, entry, db2) {
45736
45862
  break;
45737
45863
  }
45738
45864
  case "stream_event": {
45739
- handleStreamEvent(message, sessionId, turnId);
45865
+ handleStreamEvent(message, sessionId, turnId, entry, db2);
45740
45866
  break;
45741
45867
  }
45742
45868
  case "result": {
45743
45869
  handleResultMessage(message, sessionId, turnId, entry, db2);
45744
45870
  break;
45745
45871
  }
45872
+ case "conversation_reset": {
45873
+ resetContext(entry, sessionId, db2);
45874
+ break;
45875
+ }
45746
45876
  default:
45747
45877
  break;
45748
45878
  }
45749
45879
  }
45750
45880
  var TOOL_CALL_TYPES = /* @__PURE__ */ new Set(["command_execution", "file_change", "mcp_tool_call"]);
45751
- function handleAssistantMessage(message, sessionId, turnId, db2) {
45881
+ function handleAssistantMessage(message, sessionId, turnId, entry, db2) {
45752
45882
  const messageId = message.uuid;
45753
45883
  const parentToolUseId = message.parent_tool_use_id ?? null;
45754
45884
  if (parentToolUseId) {
@@ -45758,6 +45888,9 @@ function handleAssistantMessage(message, sessionId, turnId, db2) {
45758
45888
  db2.prepare("UPDATE turns SET external_turn_id = ?, updated_at = ? WHERE id = ?").run(messageId, nowExt2, turnId);
45759
45889
  return;
45760
45890
  }
45891
+ if (message.message?.model !== "<synthetic>") {
45892
+ recordApiUsage(entry, sessionId, db2, message.message?.id ?? null, message.message?.usage);
45893
+ }
45761
45894
  const content = message.message.content;
45762
45895
  const anthropicMsgId = message.message?.id ?? messageId;
45763
45896
  const thinkingTexts = thinkingAccumulator.get(messageId);
@@ -45814,12 +45947,19 @@ function handleUserMessage(message, sessionId, turnId, db2) {
45814
45947
  );
45815
45948
  }
45816
45949
  }
45817
- function handleStreamEvent(message, sessionId, turnId) {
45950
+ function handleStreamEvent(message, sessionId, turnId, entry, db2) {
45818
45951
  const rawEvent = message.event;
45819
45952
  const parentToolUseId = message.parent_tool_use_id ?? null;
45820
45953
  if (rawEvent.type === "message_start" && rawEvent.message?.id && !parentToolUseId) {
45821
45954
  streamingMessageIds.set(turnId, rawEvent.message.id);
45822
45955
  }
45956
+ if (!parentToolUseId) {
45957
+ if (rawEvent.type === "message_start" && rawEvent.message?.id) {
45958
+ recordApiUsage(entry, sessionId, db2, rawEvent.message.id, rawEvent.message.usage);
45959
+ } else if (rawEvent.type === "message_delta") {
45960
+ recordApiUsage(entry, sessionId, db2, null, rawEvent.usage);
45961
+ }
45962
+ }
45823
45963
  const delta = mapPartialDelta(message.event);
45824
45964
  if (!delta) return;
45825
45965
  if (parentToolUseId) return;
@@ -45998,24 +46138,7 @@ async function handleResultMessage(message, sessionId, turnId, entry, db2) {
45998
46138
  const now = (/* @__PURE__ */ new Date()).toISOString();
45999
46139
  db2.prepare("UPDATE turns SET token_usage = ?, updated_at = ? WHERE id = ?").run(JSON.stringify(usage), now, turnId);
46000
46140
  broadcast("turn:tokenUsage", { sessionId, turnId, usage });
46001
- try {
46002
- const ctx = await entry.query.getContextUsage();
46003
- if (ctx.totalTokens > 0 && ctx.maxTokens > 0) {
46004
- const contextUsage = {
46005
- totalTokens: ctx.totalTokens,
46006
- contextWindow: ctx.maxTokens,
46007
- percentage: Math.round(ctx.percentage)
46008
- };
46009
- broadcast("turn:contextUsage", { sessionId, ...contextUsage });
46010
- const cuNow = (/* @__PURE__ */ new Date()).toISOString();
46011
- db2.prepare("UPDATE sessions SET context_usage = ?, updated_at = ? WHERE id = ?").run(
46012
- JSON.stringify(contextUsage),
46013
- cuNow,
46014
- sessionId
46015
- );
46016
- }
46017
- } catch {
46018
- }
46141
+ await refreshContext(entry, sessionId, db2);
46019
46142
  completeTurn(db2, sessionId, turnId, usage);
46020
46143
  } else {
46021
46144
  const errorMsg = message.errors?.join("; ") ?? "Claude turn failed";
@@ -46175,6 +46298,7 @@ async function setModel(sessionId, model) {
46175
46298
  const entry = sessionMap2.get(sessionId);
46176
46299
  if (!entry) return;
46177
46300
  await entry.query.setModel(model);
46301
+ void refreshContext(entry, sessionId, getDb());
46178
46302
  }
46179
46303
  async function stopTask(sessionId, taskId) {
46180
46304
  const entry = sessionMap2.get(sessionId);