@1presence/bridge 0.36.0 → 0.38.0

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.
package/dist/claude.js CHANGED
@@ -93,6 +93,10 @@ function summariseHistoryBlock(block) {
93
93
  if (block.type === 'tool_use') {
94
94
  return `→ ${block.name} ${formatPayload(block.input)}`;
95
95
  }
96
+ if (block.type === 'image') {
97
+ const bytes = Math.floor((block.source?.data?.length ?? 0) * 0.75);
98
+ return `🖼 image (${block.source?.media_type ?? 'unknown'}, ~${bytes} bytes)`;
99
+ }
96
100
  // tool_result
97
101
  const body = typeof block.content === 'string'
98
102
  ? block.content
package/dist/index.js CHANGED
@@ -14,6 +14,7 @@ const config_1 = require("./config");
14
14
  const update_1 = require("./update");
15
15
  const accumulator_1 = require("./accumulator");
16
16
  const outbox_1 = require("./outbox");
17
+ const timer_1 = require("./timer");
17
18
  const package_json_1 = require("../package.json");
18
19
  // Published tarballs don't ship src/, so this fires only when running the
19
20
  // dist build from a live workspace checkout. Catches the trap where editing
@@ -149,6 +150,7 @@ async function handleMessage(conversationId, text, sessionId, history, auth, vau
149
150
  // If it's already invalid, MCP calls will 401 mid-turn — fail fast instead.
150
151
  if (!(0, auth_1.isTokenValid)(auth.token)) {
151
152
  const message = 'Authentication expired and refresh failed — please restart the bridge to sign in again.';
153
+ (0, timer_1.stopTurnTimer)();
152
154
  console.error(`[bridge] ${message} (${err.message})`);
153
155
  if (currentWs?.readyState === ws_1.default.OPEN) {
154
156
  currentWs.send(JSON.stringify({ type: 'error', conversationId, message }));
@@ -169,6 +171,7 @@ async function handleMessage(conversationId, text, sessionId, history, auth, vau
169
171
  }
170
172
  catch (err) {
171
173
  const message = `System prompt refresh failed: ${err.message}`;
174
+ (0, timer_1.stopTurnTimer)();
172
175
  console.error(`[${new Date().toLocaleTimeString()}] ✗ ${message}`);
173
176
  if (currentWs?.readyState === ws_1.default.OPEN) {
174
177
  currentWs.send(JSON.stringify({ type: 'error', conversationId, message }));
@@ -253,12 +256,13 @@ async function handleMessage(conversationId, text, sessionId, history, auth, vau
253
256
  }
254
257
  },
255
258
  onDone: (messageCount, costUsd, usage, model) => {
256
- const parts = [];
259
+ const elapsed = (0, timer_1.stopTurnTimer)();
260
+ const parts = [(0, timer_1.formatElapsed)(elapsed)];
257
261
  if (usage)
258
262
  parts.push(`in:${usage.input_tokens} out:${usage.output_tokens}`);
259
263
  const costStr = costUsd === 0 ? '$0.0000 (plan usage)' : `$${costUsd.toFixed(4)}`;
260
264
  parts.push(costStr);
261
- const suffix = parts.length ? ` ${parts.join(' ')}` : '';
265
+ const suffix = ` ${parts.join(' ')}`;
262
266
  console.log(`[${new Date().toLocaleTimeString()}] ✓ done${suffix}`);
263
267
  const mapped = toBridgeUsage(usage);
264
268
  if (currentWs?.readyState === ws_1.default.OPEN) {
@@ -275,7 +279,8 @@ async function handleMessage(conversationId, text, sessionId, history, auth, vau
275
279
  void finalizeAndPost(buildSpoolRecord(mapped, model));
276
280
  },
277
281
  onError: (message, usage, model) => {
278
- console.error(`[${new Date().toLocaleTimeString()}] ✗ ${message}`);
282
+ const elapsed = (0, timer_1.stopTurnTimer)();
283
+ console.error(`[${new Date().toLocaleTimeString()}] ✗ ${message} (${(0, timer_1.formatElapsed)(elapsed)})`);
279
284
  const mapped = toBridgeUsage(usage);
280
285
  if (currentWs?.readyState === ws_1.default.OPEN) {
281
286
  currentWs.send(JSON.stringify({
@@ -401,7 +406,9 @@ function connect(auth, retryDelay = 1000) {
401
406
  const ts = new Date().toLocaleTimeString();
402
407
  const hist = Array.isArray(history) ? history : [];
403
408
  console.log(`[${ts}] ▶ ${text}${hist.length ? ` (history: ${hist.length} turn${hist.length === 1 ? '' : 's'})` : ''}`);
409
+ (0, timer_1.startTurnTimer)();
404
410
  handleMessage(conversationId, text, sessionId ?? null, hist, auth, vaultFileOpen, clientCapabilities, syncedFolders, agentSlug).catch((err) => {
411
+ (0, timer_1.stopTurnTimer)();
405
412
  console.error(`[bridge] handleMessage error: ${err.message}`);
406
413
  });
407
414
  });
package/dist/timer.js ADDED
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ // Live elapsed-time indicator for the active turn. Writes `\r\x1b[K⏱ Xs`
3
+ // once per second; wraps console.log/error/warn so that any other output
4
+ // clears the timer line before printing, then redraws the timer on the new
5
+ // bottom line. Idempotent — stop is safe to call multiple times.
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.formatElapsed = formatElapsed;
8
+ exports.startTurnTimer = startTurnTimer;
9
+ exports.stopTurnTimer = stopTurnTimer;
10
+ let intervalId = null;
11
+ let startedAt = 0;
12
+ let originalLog = null;
13
+ let originalError = null;
14
+ let originalWarn = null;
15
+ function clearLine() {
16
+ process.stdout.write('\r\x1b[K');
17
+ }
18
+ function draw() {
19
+ const elapsedSec = Math.floor((Date.now() - startedAt) / 1000);
20
+ process.stdout.write(`\r\x1b[K⏱ ${formatElapsed(elapsedSec)}`);
21
+ }
22
+ function formatElapsed(seconds) {
23
+ if (seconds < 60)
24
+ return `${seconds}s`;
25
+ const m = Math.floor(seconds / 60);
26
+ const s = seconds % 60;
27
+ return `${m}m ${s.toString().padStart(2, '0')}s`;
28
+ }
29
+ function startTurnTimer() {
30
+ if (intervalId !== null)
31
+ return;
32
+ startedAt = Date.now();
33
+ originalLog = console.log;
34
+ originalError = console.error;
35
+ originalWarn = console.warn;
36
+ console.log = (...args) => { clearLine(); originalLog(...args); draw(); };
37
+ console.error = (...args) => { clearLine(); originalError(...args); draw(); };
38
+ console.warn = (...args) => { clearLine(); originalWarn(...args); draw(); };
39
+ draw();
40
+ intervalId = setInterval(draw, 1000);
41
+ }
42
+ function stopTurnTimer() {
43
+ if (intervalId === null)
44
+ return 0;
45
+ clearInterval(intervalId);
46
+ intervalId = null;
47
+ clearLine();
48
+ if (originalLog)
49
+ console.log = originalLog;
50
+ if (originalError)
51
+ console.error = originalError;
52
+ if (originalWarn)
53
+ console.warn = originalWarn;
54
+ originalLog = originalError = originalWarn = null;
55
+ return Math.floor((Date.now() - startedAt) / 1000);
56
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@1presence/bridge",
3
- "version": "0.36.0",
3
+ "version": "0.38.0",
4
4
  "description": "Run 1Presence on your Mac and use your Claude.ai Pro subscription from any device",
5
5
  "bin": {
6
6
  "1presence-bridge": "dist/index.js"