@1presence/bridge 0.78.0 → 0.80.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 +62 -25
- package/dist/index.js +34 -32
- package/package.json +1 -1
package/dist/claude.js
CHANGED
|
@@ -41,10 +41,11 @@ export function paint(code, s) {
|
|
|
41
41
|
}
|
|
42
42
|
export const SECTION_COLORS = {
|
|
43
43
|
system: '35',
|
|
44
|
-
user: '
|
|
44
|
+
user: '33',
|
|
45
45
|
assistant: '32',
|
|
46
46
|
input: '36',
|
|
47
|
-
result: '
|
|
47
|
+
result: '90',
|
|
48
|
+
error: '31',
|
|
48
49
|
};
|
|
49
50
|
function debugBlock(label, colorCode, body) {
|
|
50
51
|
const rule = `── ${label} `.padEnd(64, '─');
|
|
@@ -117,6 +118,21 @@ function joinErrorDetail(...parts) {
|
|
|
117
118
|
const SDK_STDERR_ERROR_RE = /\b(error|exception|fail(?:ed|ure)?|invalid|unauthor|forbidden|refus|denied|40[0-9]|429|5\d\d|overloaded|rate.?limit)\b/i;
|
|
118
119
|
const REMOTE_MCP_SERVER_NAME = '1presence';
|
|
119
120
|
const MCP_SESSION_EXPIRED_RE = /session not found or expired|Error POSTing to endpoint \(HTTP 404\)/i;
|
|
121
|
+
const MCP_TRANSPORT_DEAD_RE = /SSE (?:stream|error)|not connected|connection (?:closed|error|reset|refused|dropped)|dropped connection|socket hang up|ECONNRESET|ECONNREFUSED|ETIMEDOUT|EPIPE|fetch failed|terminated|transport (?:closed|error)|request timed out|-32001|\(HTTP 50\d\)/i;
|
|
122
|
+
const OUTBOUND_NETWORK_TOOLS = new Set([
|
|
123
|
+
'mcp__1presence__web_fetch',
|
|
124
|
+
'mcp__1presence__web_search',
|
|
125
|
+
]);
|
|
126
|
+
export function shouldReconnectRemoteMcp(args) {
|
|
127
|
+
const { toolName, isError, text } = args;
|
|
128
|
+
if (MCP_SESSION_EXPIRED_RE.test(text))
|
|
129
|
+
return true;
|
|
130
|
+
if (!isError || !toolName.startsWith('mcp__1presence__'))
|
|
131
|
+
return false;
|
|
132
|
+
if (OUTBOUND_NETWORK_TOOLS.has(toolName))
|
|
133
|
+
return false;
|
|
134
|
+
return MCP_TRANSPORT_DEAD_RE.test(text);
|
|
135
|
+
}
|
|
120
136
|
function toolResultText(content) {
|
|
121
137
|
if (typeof content === 'string')
|
|
122
138
|
return content;
|
|
@@ -208,6 +224,11 @@ export function spawnClaude(params) {
|
|
|
208
224
|
}
|
|
209
225
|
else {
|
|
210
226
|
process.stderr.write(`[bridge] session ${presenceSessionId}\n`);
|
|
227
|
+
const prompt = text.replace(/\s+/g, ' ').trim();
|
|
228
|
+
if (prompt) {
|
|
229
|
+
const shown = prompt.length > 300 ? `${prompt.slice(0, 300)}…` : prompt;
|
|
230
|
+
process.stderr.write(paint(SECTION_COLORS.user, `[bridge] ▸ ${shown}`) + '\n');
|
|
231
|
+
}
|
|
211
232
|
}
|
|
212
233
|
void vaultFileOpen;
|
|
213
234
|
void clientCapabilities;
|
|
@@ -329,7 +350,7 @@ export function spawnClaude(params) {
|
|
|
329
350
|
if (blockText && TOOL_CALL_XML_RE.test(blockText)) {
|
|
330
351
|
const cleaned = stripToolCallXml(blockText);
|
|
331
352
|
if (cleaned !== blockText) {
|
|
332
|
-
process.stderr.write(paint(SECTION_COLORS.
|
|
353
|
+
process.stderr.write(paint(SECTION_COLORS.error, `[bridge] suppressed confabulated tool-call XML in assistant text`) + '\n');
|
|
333
354
|
block['text'] = cleaned;
|
|
334
355
|
blockText = cleaned;
|
|
335
356
|
}
|
|
@@ -343,7 +364,7 @@ export function spawnClaude(params) {
|
|
|
343
364
|
apiErrorText = blockText.trim();
|
|
344
365
|
if (isAuthFailure)
|
|
345
366
|
sawAuthFailure = true;
|
|
346
|
-
process.stderr.write(paint(SECTION_COLORS.
|
|
367
|
+
process.stderr.write(paint(SECTION_COLORS.error, `[bridge] ${blockText.replace(/\n+/g, ' ')}`) + '\n');
|
|
347
368
|
return false;
|
|
348
369
|
}
|
|
349
370
|
producedRealOutput = true;
|
|
@@ -361,22 +382,30 @@ export function spawnClaude(params) {
|
|
|
361
382
|
process.stderr.write('\n');
|
|
362
383
|
}
|
|
363
384
|
}
|
|
364
|
-
if (
|
|
385
|
+
if (type === 'user') {
|
|
365
386
|
const msg = event['message'];
|
|
366
387
|
const content = msg?.['content'];
|
|
367
388
|
if (Array.isArray(content)) {
|
|
368
389
|
for (const block of content) {
|
|
369
|
-
if (block['type']
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
390
|
+
if (block['type'] !== 'tool_result')
|
|
391
|
+
continue;
|
|
392
|
+
const id = block['tool_use_id'] ?? '';
|
|
393
|
+
const out = block['content'];
|
|
394
|
+
const name = toolNames.get(id) ?? id ?? 'result';
|
|
395
|
+
if (block['is_error']) {
|
|
396
|
+
const detail = toolResultText(out).replace(/\s+/g, ' ').trim();
|
|
397
|
+
const shown = detail.length > 400 ? `${detail.slice(0, 400)}…` : detail;
|
|
398
|
+
process.stderr.write(paint(SECTION_COLORS.error, `[bridge] ✗ tool error ← ${name}: ${shown || 'no detail'}`) + '\n');
|
|
399
|
+
}
|
|
400
|
+
if (!verbose && !debug)
|
|
401
|
+
continue;
|
|
402
|
+
const errFlag = block['is_error'] ? ' [error]' : '';
|
|
403
|
+
const bodyColor = block['is_error'] ? SECTION_COLORS.error : SECTION_COLORS.result;
|
|
404
|
+
if (debug) {
|
|
405
|
+
debugBlock(`result ← ${name}${errFlag}`, bodyColor, formatPayload(out));
|
|
406
|
+
}
|
|
407
|
+
else {
|
|
408
|
+
process.stderr.write(paint(bodyColor, `[bridge:verbose] ─── output ${name}${errFlag} ───\n${formatPayload(out)}\n[bridge:verbose] ─── end output ───`) + '\n');
|
|
380
409
|
}
|
|
381
410
|
}
|
|
382
411
|
}
|
|
@@ -393,7 +422,7 @@ export function spawnClaude(params) {
|
|
|
393
422
|
const detail = joinErrorDetail(event['result'], event['errors']);
|
|
394
423
|
apiErrorText = joinErrorDetail(apiErrorText, detail) || apiErrorText;
|
|
395
424
|
const subtype = event['subtype'] ? ` subtype=${event['subtype']}` : '';
|
|
396
|
-
process.stderr.write(paint(SECTION_COLORS.
|
|
425
|
+
process.stderr.write(paint(SECTION_COLORS.error, `[bridge] result error${status != null ? ` (${status})` : ''}${subtype}: ${apiErrorText || 'unknown'}`) + '\n');
|
|
397
426
|
if (!detail) {
|
|
398
427
|
let raw;
|
|
399
428
|
try {
|
|
@@ -402,7 +431,7 @@ export function spawnClaude(params) {
|
|
|
402
431
|
catch {
|
|
403
432
|
raw = String(event);
|
|
404
433
|
}
|
|
405
|
-
process.stderr.write(paint(SECTION_COLORS.
|
|
434
|
+
process.stderr.write(paint(SECTION_COLORS.error, `[bridge] result raw: ${raw.slice(0, 2000)}`) + '\n');
|
|
406
435
|
}
|
|
407
436
|
}
|
|
408
437
|
}
|
|
@@ -477,11 +506,11 @@ export function spawnClaude(params) {
|
|
|
477
506
|
return;
|
|
478
507
|
mcpReconnecting = true;
|
|
479
508
|
lastMcpReconnectAt = now;
|
|
480
|
-
process.stderr.write(paint(SECTION_COLORS.
|
|
509
|
+
process.stderr.write(paint(SECTION_COLORS.error, '[bridge] remote MCP connection lost — reconnecting and retrying') + '\n');
|
|
481
510
|
onNotice?.('Reconnecting to 1Presence tools…');
|
|
482
511
|
void q.reconnectMcpServer(REMOTE_MCP_SERVER_NAME)
|
|
483
512
|
.then(() => process.stderr.write(paint(SECTION_COLORS.result, '[bridge] remote MCP reconnected') + '\n'))
|
|
484
|
-
.catch((err) => process.stderr.write(paint(SECTION_COLORS.
|
|
513
|
+
.catch((err) => process.stderr.write(paint(SECTION_COLORS.error, `[bridge] remote MCP reconnect failed: ${err.message}`) + '\n'))
|
|
485
514
|
.finally(() => { mcpReconnecting = false; });
|
|
486
515
|
};
|
|
487
516
|
try {
|
|
@@ -500,7 +529,7 @@ export function spawnClaude(params) {
|
|
|
500
529
|
}
|
|
501
530
|
else if (subtype === 'api_retry') {
|
|
502
531
|
const r = m;
|
|
503
|
-
process.stderr.write(paint(SECTION_COLORS.
|
|
532
|
+
process.stderr.write(paint(SECTION_COLORS.error, `[bridge] api retry ${r.attempt ?? '?'}/${r.max_retries ?? '?'}${r.error_status != null ? ` (${r.error_status})` : ''}: ${r.error ?? 'unknown'}${r.retry_delay_ms != null ? `, next in ${r.retry_delay_ms}ms` : ''}`) + '\n');
|
|
504
533
|
const attempt = r.attempt ?? 0;
|
|
505
534
|
if (attempt >= 2 || (r.retry_delay_ms ?? 0) >= 2000) {
|
|
506
535
|
onNotice?.(formatRetryNotice(attempt, r.max_retries ?? 0, r.retry_delay_ms));
|
|
@@ -525,7 +554,7 @@ export function spawnClaude(params) {
|
|
|
525
554
|
const full = joinErrorDetail(`API Error: ${am.error}`, msgText, rid);
|
|
526
555
|
if (!apiErrorText || /^API Error: \w+$/.test(apiErrorText))
|
|
527
556
|
apiErrorText = full;
|
|
528
|
-
process.stderr.write(paint(SECTION_COLORS.
|
|
557
|
+
process.stderr.write(paint(SECTION_COLORS.error, `[bridge] assistant error: ${joinErrorDetail(am.error, msgText, rid)}`) + '\n');
|
|
529
558
|
break;
|
|
530
559
|
}
|
|
531
560
|
const event = { type: 'assistant', message: am.message, error: am.error };
|
|
@@ -540,8 +569,16 @@ export function spawnClaude(params) {
|
|
|
540
569
|
const content = um.message?.['content'];
|
|
541
570
|
if (Array.isArray(content)) {
|
|
542
571
|
for (const block of content) {
|
|
543
|
-
if (block
|
|
544
|
-
|
|
572
|
+
if (!block || typeof block !== 'object')
|
|
573
|
+
continue;
|
|
574
|
+
const b = block;
|
|
575
|
+
if (b['type'] !== 'tool_result')
|
|
576
|
+
continue;
|
|
577
|
+
if (shouldReconnectRemoteMcp({
|
|
578
|
+
toolName: toolNames.get(b['tool_use_id'] ?? '') ?? '',
|
|
579
|
+
isError: b['is_error'] === true,
|
|
580
|
+
text: toolResultText(b['content']),
|
|
581
|
+
})) {
|
|
545
582
|
maybeReconnectRemoteMcp(q);
|
|
546
583
|
break;
|
|
547
584
|
}
|
|
@@ -612,7 +649,7 @@ export function spawnClaude(params) {
|
|
|
612
649
|
return;
|
|
613
650
|
const message = err?.message ?? String(err);
|
|
614
651
|
const stack = err?.stack;
|
|
615
|
-
process.stderr.write(paint(SECTION_COLORS.
|
|
652
|
+
process.stderr.write(paint(SECTION_COLORS.error, `[bridge] query() threw: ${stack || message}`) + '\n');
|
|
616
653
|
if (/40[13]\b|unauthor|invalid (api key|authentication)|please run \/login/i.test(message)) {
|
|
617
654
|
sawAuthFailure = true;
|
|
618
655
|
}
|
package/dist/index.js
CHANGED
|
@@ -21,7 +21,7 @@ if (__dirname.endsWith('dist')) {
|
|
|
21
21
|
if (existsSync(srcDir)) {
|
|
22
22
|
const newest = (dir) => Math.max(...readdirSync(dir).map(f => statSync(join(dir, f)).mtimeMs));
|
|
23
23
|
if (newest(srcDir) > newest(__dirname)) {
|
|
24
|
-
console.error('Bridge dist is stale (src/ has been edited since last build). Run: npm run build');
|
|
24
|
+
console.error(paint(SECTION_COLORS.error, 'Bridge dist is stale (src/ has been edited since last build). Run: npm run build'));
|
|
25
25
|
process.exit(1);
|
|
26
26
|
}
|
|
27
27
|
}
|
|
@@ -205,7 +205,7 @@ async function handleDocReconRequest(req) {
|
|
|
205
205
|
mediaType = req.sourceContentType || 'application/pdf';
|
|
206
206
|
}
|
|
207
207
|
catch (err) {
|
|
208
|
-
console.error(`[bridge] doc_recon: download failed (reqId: ${req.reqId}): ${err.message}`);
|
|
208
|
+
console.error(paint(SECTION_COLORS.error, `[bridge] doc_recon: download failed (reqId: ${req.reqId}): ${err.message}`));
|
|
209
209
|
send({ type: 'doc_recon_response', reqId: req.reqId, error: `download failed: ${err.message}` });
|
|
210
210
|
return;
|
|
211
211
|
}
|
|
@@ -256,7 +256,7 @@ async function handleDocReconRequest(req) {
|
|
|
256
256
|
}
|
|
257
257
|
catch (err) {
|
|
258
258
|
if (!abort.signal.aborted) {
|
|
259
|
-
console.error(`[bridge] doc_recon: query failed (reqId: ${req.reqId}): ${err.message}`);
|
|
259
|
+
console.error(paint(SECTION_COLORS.error, `[bridge] doc_recon: query failed (reqId: ${req.reqId}): ${err.message}`));
|
|
260
260
|
send({ type: 'doc_recon_response', reqId: req.reqId, error: err.message });
|
|
261
261
|
}
|
|
262
262
|
}
|
|
@@ -275,7 +275,7 @@ async function handleMessage(conversationId, text, sessionId, history, auth, vau
|
|
|
275
275
|
if (!isTokenValid(auth.token)) {
|
|
276
276
|
const message = 'Authentication expired and refresh failed — please restart the bridge to sign in again.';
|
|
277
277
|
stopTurnTimer();
|
|
278
|
-
console.error(`[bridge] ${message} (${err.message})`);
|
|
278
|
+
console.error(paint(SECTION_COLORS.error, `[bridge] ${message} (${err.message})`));
|
|
279
279
|
if (currentWs?.readyState === WebSocket.OPEN) {
|
|
280
280
|
currentWs.send(JSON.stringify({ type: 'error', conversationId, message }));
|
|
281
281
|
}
|
|
@@ -289,7 +289,7 @@ async function handleMessage(conversationId, text, sessionId, history, auth, vau
|
|
|
289
289
|
catch (err) {
|
|
290
290
|
const message = `System prompt refresh failed: ${err.message}`;
|
|
291
291
|
stopTurnTimer();
|
|
292
|
-
console.error(`[${new Date().toLocaleTimeString()}] ✗ ${message}`);
|
|
292
|
+
console.error(paint(SECTION_COLORS.error, `[${new Date().toLocaleTimeString()}] ✗ ${message}`));
|
|
293
293
|
if (currentWs?.readyState === WebSocket.OPEN) {
|
|
294
294
|
currentWs.send(JSON.stringify({ type: 'error', conversationId, message }));
|
|
295
295
|
}
|
|
@@ -407,7 +407,7 @@ async function handleMessage(conversationId, text, sessionId, history, auth, vau
|
|
|
407
407
|
},
|
|
408
408
|
onError: (message, usage, model) => {
|
|
409
409
|
const elapsed = stopTurnTimer();
|
|
410
|
-
console.error(`[${new Date().toLocaleTimeString()}] ✗ ${message} (${formatElapsed(elapsed)})`);
|
|
410
|
+
console.error(paint(SECTION_COLORS.error, `[${new Date().toLocaleTimeString()}] ✗ ${message} (${formatElapsed(elapsed)})`));
|
|
411
411
|
const mapped = toBridgeUsage(usage);
|
|
412
412
|
if (currentWs?.readyState === WebSocket.OPEN) {
|
|
413
413
|
currentWs.send(JSON.stringify({
|
|
@@ -505,7 +505,7 @@ function connect(auth, retryDelay = 1000) {
|
|
|
505
505
|
}
|
|
506
506
|
catch (err) {
|
|
507
507
|
const preview = raw.toString().slice(0, 200);
|
|
508
|
-
console.error(`[bridge] failed to parse ws message as JSON: ${err.message} (raw: ${preview})`);
|
|
508
|
+
console.error(paint(SECTION_COLORS.error, `[bridge] failed to parse ws message as JSON: ${err.message} (raw: ${preview})`));
|
|
509
509
|
return;
|
|
510
510
|
}
|
|
511
511
|
if (msg.type === 'pong') {
|
|
@@ -525,7 +525,7 @@ function connect(auth, retryDelay = 1000) {
|
|
|
525
525
|
const req = msg;
|
|
526
526
|
if (req.reqId && req.systemPrompt && req.sourceUrl) {
|
|
527
527
|
handleDocReconRequest(req).catch((err) => {
|
|
528
|
-
console.error(`[bridge] doc_recon: unhandled error (reqId: ${req.reqId}): ${err.message}`);
|
|
528
|
+
console.error(paint(SECTION_COLORS.error, `[bridge] doc_recon: unhandled error (reqId: ${req.reqId}): ${err.message}`));
|
|
529
529
|
if (currentWs?.readyState === WebSocket.OPEN) {
|
|
530
530
|
currentWs.send(JSON.stringify({ type: 'doc_recon_response', reqId: req.reqId, error: err.message }));
|
|
531
531
|
}
|
|
@@ -542,13 +542,13 @@ function connect(auth, retryDelay = 1000) {
|
|
|
542
542
|
startTurnTimer();
|
|
543
543
|
handleMessage(conversationId, text, sessionId ?? null, hist, auth, vaultFileOpen, clientCapabilities, syncedFolders, agentSlug, model).catch((err) => {
|
|
544
544
|
stopTurnTimer();
|
|
545
|
-
console.error(`[bridge] handleMessage error: ${err.message}`);
|
|
545
|
+
console.error(paint(SECTION_COLORS.error, `[bridge] handleMessage error: ${err.message}`));
|
|
546
546
|
});
|
|
547
547
|
});
|
|
548
548
|
ws.on('close', (code) => {
|
|
549
549
|
stopPing();
|
|
550
550
|
if (code === 4003) {
|
|
551
|
-
console.error('Local Claude Code is not enabled for your account. To request access, email hello@1presence.com.');
|
|
551
|
+
console.error(paint(SECTION_COLORS.error, 'Local Claude Code is not enabled for your account. To request access, email hello@1presence.com.'));
|
|
552
552
|
process.exit(1);
|
|
553
553
|
}
|
|
554
554
|
if (code === 4004) {
|
|
@@ -564,9 +564,10 @@ function connect(auth, retryDelay = 1000) {
|
|
|
564
564
|
scheduleReconnect(code, retryDelay);
|
|
565
565
|
});
|
|
566
566
|
ws.on('error', (err) => {
|
|
567
|
-
console.error(`[bridge] ws error: ${err.message}`);
|
|
568
|
-
|
|
569
|
-
|
|
567
|
+
console.error(paint(SECTION_COLORS.error, `[bridge] ws error: ${err.message}`));
|
|
568
|
+
const wsStack = err.stack;
|
|
569
|
+
if (VERBOSE && wsStack)
|
|
570
|
+
console.error(paint(SECTION_COLORS.error, wsStack));
|
|
570
571
|
});
|
|
571
572
|
return ws;
|
|
572
573
|
}
|
|
@@ -586,21 +587,21 @@ function scheduleReconnect(closeCode, retryDelay) {
|
|
|
586
587
|
if (authFailure) {
|
|
587
588
|
authRejections++;
|
|
588
589
|
if (authRejections > MAX_AUTH_REJECTIONS) {
|
|
589
|
-
console.error('Authentication keeps being rejected even after refreshing — please restart the bridge to sign in again.');
|
|
590
|
+
console.error(paint(SECTION_COLORS.error, 'Authentication keeps being rejected even after refreshing — please restart the bridge to sign in again.'));
|
|
590
591
|
process.exit(1);
|
|
591
592
|
}
|
|
592
593
|
try {
|
|
593
594
|
const refreshed = await forceRefreshToken(currentAuth);
|
|
594
595
|
if (!refreshed) {
|
|
595
|
-
console.error('Authentication failed and no refresh token is available — please restart the bridge to sign in again.');
|
|
596
|
+
console.error(paint(SECTION_COLORS.error, 'Authentication failed and no refresh token is available — please restart the bridge to sign in again.'));
|
|
596
597
|
process.exit(1);
|
|
597
598
|
}
|
|
598
599
|
currentAuth = refreshed;
|
|
599
600
|
console.log(`[bridge] token refreshed (attempt ${authRejections}/${MAX_AUTH_REJECTIONS}) — reconnecting with a new token.`);
|
|
600
601
|
}
|
|
601
602
|
catch (err) {
|
|
602
|
-
console.error(`[bridge] token refresh failed: ${err.message}`);
|
|
603
|
-
console.error('Please restart the bridge to sign in again.');
|
|
603
|
+
console.error(paint(SECTION_COLORS.error, `[bridge] token refresh failed: ${err.message}`));
|
|
604
|
+
console.error(paint(SECTION_COLORS.error, 'Please restart the bridge to sign in again.'));
|
|
604
605
|
process.exit(1);
|
|
605
606
|
}
|
|
606
607
|
}
|
|
@@ -616,8 +617,8 @@ function scheduleReconnect(closeCode, retryDelay) {
|
|
|
616
617
|
await writeSetupFiles(currentAuth);
|
|
617
618
|
}
|
|
618
619
|
catch (err) {
|
|
619
|
-
console.error(`[bridge] reconnect setup failed: ${err.message}`);
|
|
620
|
-
console.error('[bridge] will retry connection anyway — system prompt may be stale until next refresh');
|
|
620
|
+
console.error(paint(SECTION_COLORS.error, `[bridge] reconnect setup failed: ${err.message}`));
|
|
621
|
+
console.error(paint(SECTION_COLORS.error, '[bridge] will retry connection anyway — system prompt may be stale until next refresh'));
|
|
621
622
|
}
|
|
622
623
|
connect(currentAuth, nextDelay);
|
|
623
624
|
}, delay);
|
|
@@ -632,7 +633,7 @@ async function ensureClaudeCodeLogin() {
|
|
|
632
633
|
console.log(paint(SECTION_COLORS.assistant, `✓ Claude Code signed in${who}${plan}`));
|
|
633
634
|
return;
|
|
634
635
|
}
|
|
635
|
-
console.log(paint(SECTION_COLORS.
|
|
636
|
+
console.log(paint(SECTION_COLORS.error, '\n⚠ Your local Claude Code isn’t signed in.'));
|
|
636
637
|
console.log(' Local Mode runs on your own Claude subscription — Claude Code has to be signed in on this machine, or every message will fail.');
|
|
637
638
|
if (!process.stdin.isTTY) {
|
|
638
639
|
console.log(' Not an interactive terminal, so I can’t prompt. Sign in with `claude auth login`, then start the bridge again.\n');
|
|
@@ -656,7 +657,7 @@ async function ensureClaudeCodeLogin() {
|
|
|
656
657
|
console.log(paint(SECTION_COLORS.assistant, `✓ Signed in${who} — continuing.\n`));
|
|
657
658
|
}
|
|
658
659
|
else {
|
|
659
|
-
console.log(paint(SECTION_COLORS.
|
|
660
|
+
console.log(paint(SECTION_COLORS.error, ' Still not signed in — starting anyway. Sign in any time and resend your message.\n'));
|
|
660
661
|
}
|
|
661
662
|
}
|
|
662
663
|
async function main() {
|
|
@@ -682,8 +683,8 @@ async function main() {
|
|
|
682
683
|
}
|
|
683
684
|
catch (err) {
|
|
684
685
|
process.stdout.write(' FAILED.\n');
|
|
685
|
-
console.error(`[bridge] setup failed: ${err.message}`);
|
|
686
|
-
console.error('[bridge] cannot start without a system prompt from the gateway. Check network, auth, and that the gateway is reachable.');
|
|
686
|
+
console.error(paint(SECTION_COLORS.error, `[bridge] setup failed: ${err.message}`));
|
|
687
|
+
console.error(paint(SECTION_COLORS.error, '[bridge] cannot start without a system prompt from the gateway. Check network, auth, and that the gateway is reachable.'));
|
|
687
688
|
process.exit(1);
|
|
688
689
|
}
|
|
689
690
|
process.stdout.write(' done.\n');
|
|
@@ -696,26 +697,27 @@ async function main() {
|
|
|
696
697
|
process.on('SIGINT', shutdown);
|
|
697
698
|
process.on('SIGTERM', shutdown);
|
|
698
699
|
process.on('uncaughtException', (err) => {
|
|
699
|
-
console.error(`[bridge] uncaughtException: ${err.message}`);
|
|
700
|
+
console.error(paint(SECTION_COLORS.error, `[bridge] uncaughtException: ${err.message}`));
|
|
700
701
|
if (err.stack)
|
|
701
|
-
console.error(err.stack);
|
|
702
|
+
console.error(paint(SECTION_COLORS.error, err.stack));
|
|
702
703
|
});
|
|
703
704
|
process.on('unhandledRejection', (reason) => {
|
|
704
705
|
const message = reason instanceof Error ? reason.message : String(reason);
|
|
705
706
|
const stack = reason instanceof Error ? reason.stack : undefined;
|
|
706
|
-
console.error(`[bridge] unhandledRejection: ${message}`);
|
|
707
|
+
console.error(paint(SECTION_COLORS.error, `[bridge] unhandledRejection: ${message}`));
|
|
707
708
|
if (stack)
|
|
708
|
-
console.error(stack);
|
|
709
|
+
console.error(paint(SECTION_COLORS.error, stack));
|
|
709
710
|
});
|
|
710
711
|
}
|
|
711
712
|
main().catch((err) => {
|
|
712
713
|
if (err instanceof AuthCancelledError) {
|
|
713
|
-
console.error(`\n${err.message}`);
|
|
714
|
-
console.error('Run `npx @1presence/bridge` again when you are ready to sign in.');
|
|
714
|
+
console.error(paint(SECTION_COLORS.error, `\n${err.message}`));
|
|
715
|
+
console.error(paint(SECTION_COLORS.error, 'Run `npx @1presence/bridge` again when you are ready to sign in.'));
|
|
715
716
|
process.exit(0);
|
|
716
717
|
}
|
|
717
|
-
console.error(
|
|
718
|
-
|
|
719
|
-
|
|
718
|
+
console.error(paint(SECTION_COLORS.error, `Fatal: ${err.message}`));
|
|
719
|
+
const fatalStack = err.stack;
|
|
720
|
+
if (fatalStack)
|
|
721
|
+
console.error(paint(SECTION_COLORS.error, fatalStack));
|
|
720
722
|
process.exit(1);
|
|
721
723
|
});
|