@1presence/bridge 0.1.6 → 0.1.8
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/README.md +0 -12
- package/dist/auth.js +4 -5
- package/dist/claude.js +11 -1
- package/dist/index.js +23 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -35,18 +35,6 @@ rm ~/.1presence/auth.json
|
|
|
35
35
|
|
|
36
36
|
The next run will prompt you to sign in again. If authentication fails (e.g. an expired token), the bridge clears credentials automatically and exits with an error.
|
|
37
37
|
|
|
38
|
-
## Environment
|
|
39
|
-
|
|
40
|
-
| Variable | Default | Description |
|
|
41
|
-
|---|---|---|
|
|
42
|
-
| `BRIDGE_GATEWAY_URL` | `https://api.1presence.com` | Override for self-hosted or local dev |
|
|
43
|
-
|
|
44
|
-
## Local development
|
|
45
|
-
|
|
46
|
-
```bash
|
|
47
|
-
BRIDGE_GATEWAY_URL=http://localhost:8080 npx @1presence/bridge
|
|
48
|
-
```
|
|
49
|
-
|
|
50
38
|
## Troubleshooting
|
|
51
39
|
|
|
52
40
|
**`claude CLI not found`** — Install Claude Code from [claude.ai/code](https://claude.ai/code) and make sure the `claude` command is on your PATH.
|
package/dist/auth.js
CHANGED
|
@@ -67,7 +67,7 @@ function openBrowser(url) {
|
|
|
67
67
|
console.error('Could not open browser automatically. Please open this URL manually:\n' + url);
|
|
68
68
|
});
|
|
69
69
|
}
|
|
70
|
-
function runBrowserAuthFlow(gatewayUrl) {
|
|
70
|
+
function runBrowserAuthFlow(gatewayUrl, pwaUrl) {
|
|
71
71
|
return new Promise((resolve, reject) => {
|
|
72
72
|
const server = (0, http_1.createServer)((req, res) => {
|
|
73
73
|
// CORS headers so the PWA (https) can POST to http://localhost
|
|
@@ -114,8 +114,7 @@ function runBrowserAuthFlow(gatewayUrl) {
|
|
|
114
114
|
});
|
|
115
115
|
server.listen(0, '127.0.0.1', () => {
|
|
116
116
|
const { port } = server.address();
|
|
117
|
-
const
|
|
118
|
-
const authUrl = `${base}/cli-auth?port=${port}`;
|
|
117
|
+
const authUrl = `${pwaUrl.replace(/\/$/, '')}/cli-auth?port=${port}`;
|
|
119
118
|
console.log('\nOpening browser for sign-in…');
|
|
120
119
|
console.log(`If the browser doesn't open, visit:\n ${authUrl}\n`);
|
|
121
120
|
openBrowser(authUrl);
|
|
@@ -127,12 +126,12 @@ function runBrowserAuthFlow(gatewayUrl) {
|
|
|
127
126
|
});
|
|
128
127
|
}
|
|
129
128
|
// ─── Public API ───────────────────────────────────────────────────────────────
|
|
130
|
-
async function getValidAuth(gatewayUrl) {
|
|
129
|
+
async function getValidAuth(gatewayUrl, pwaUrl) {
|
|
131
130
|
const cached = loadCachedAuth();
|
|
132
131
|
if (cached)
|
|
133
132
|
return cached;
|
|
134
133
|
console.log('Sign-in required.');
|
|
135
|
-
const auth = await runBrowserAuthFlow(gatewayUrl);
|
|
134
|
+
const auth = await runBrowserAuthFlow(gatewayUrl, pwaUrl);
|
|
136
135
|
saveCachedAuth(auth);
|
|
137
136
|
return auth;
|
|
138
137
|
}
|
package/dist/claude.js
CHANGED
|
@@ -31,6 +31,8 @@ function spawnClaude(params) {
|
|
|
31
31
|
active.set(conversationId, proc);
|
|
32
32
|
let sessionIdExtracted = false;
|
|
33
33
|
let messageCount = 0;
|
|
34
|
+
let costUsd = 0;
|
|
35
|
+
let usage = null;
|
|
34
36
|
let buffer = '';
|
|
35
37
|
proc.stdout.on('data', (chunk) => {
|
|
36
38
|
buffer += chunk.toString('utf-8');
|
|
@@ -59,6 +61,14 @@ function spawnClaude(params) {
|
|
|
59
61
|
// Count complete assistant turns
|
|
60
62
|
if (type === 'assistant')
|
|
61
63
|
messageCount++;
|
|
64
|
+
// Extract cost + usage from the final result event
|
|
65
|
+
if (type === 'result') {
|
|
66
|
+
if (typeof event['cost_usd'] === 'number')
|
|
67
|
+
costUsd = event['cost_usd'];
|
|
68
|
+
const u = event['usage'];
|
|
69
|
+
if (u)
|
|
70
|
+
usage = { input_tokens: u['input_tokens'] ?? 0, output_tokens: u['output_tokens'] ?? 0 };
|
|
71
|
+
}
|
|
62
72
|
onEvent(event);
|
|
63
73
|
}
|
|
64
74
|
});
|
|
@@ -81,7 +91,7 @@ function spawnClaude(params) {
|
|
|
81
91
|
onError(`claude exited with code ${code}`);
|
|
82
92
|
}
|
|
83
93
|
else {
|
|
84
|
-
onDone(messageCount);
|
|
94
|
+
onDone(messageCount, costUsd, usage);
|
|
85
95
|
}
|
|
86
96
|
});
|
|
87
97
|
proc.on('error', (err) => {
|
package/dist/index.js
CHANGED
|
@@ -10,10 +10,13 @@ const os_1 = require("os");
|
|
|
10
10
|
const path_1 = require("path");
|
|
11
11
|
const auth_1 = require("./auth");
|
|
12
12
|
const claude_1 = require("./claude");
|
|
13
|
+
const package_json_1 = require("../package.json");
|
|
13
14
|
// ─── Config ───────────────────────────────────────────────────────────────────
|
|
14
15
|
const GATEWAY_URL = process.env.BRIDGE_GATEWAY_URL ?? 'https://api.1presence.com';
|
|
15
16
|
const GATEWAY_WS = GATEWAY_URL.replace(/^https?:/, 'wss:').replace(/\/$/, '') + '/bridge';
|
|
16
17
|
const GATEWAY_HTTP = GATEWAY_URL.replace(/^wss?:/, 'https:').replace(/\/$/, '');
|
|
18
|
+
// PWA hosts the /cli-auth sign-in page; strip 'api.' subdomain to derive it from gateway URL
|
|
19
|
+
const PWA_URL = process.env.BRIDGE_PWA_URL ?? GATEWAY_HTTP.replace('://api.', '://');
|
|
17
20
|
// ─── In-memory state ──────────────────────────────────────────────────────────
|
|
18
21
|
let currentAuth = null;
|
|
19
22
|
// ─── Vault file fetch ─────────────────────────────────────────────────────────
|
|
@@ -72,23 +75,38 @@ function connect(auth, retryDelay = 1000) {
|
|
|
72
75
|
if (msg.type !== 'message' || !msg.conversationId || !msg.text)
|
|
73
76
|
return;
|
|
74
77
|
const { conversationId, text, sessionId } = msg;
|
|
78
|
+
const ts = new Date().toLocaleTimeString();
|
|
79
|
+
const preview = text.length > 80 ? text.slice(0, 80) + '…' : text;
|
|
80
|
+
console.log(`[${ts}] ▶ ${preview}`);
|
|
81
|
+
let responding = false;
|
|
75
82
|
(0, claude_1.spawnClaude)({
|
|
76
83
|
conversationId,
|
|
77
84
|
presenceSessionId: sessionId ?? null,
|
|
78
85
|
text,
|
|
79
86
|
uid: auth.uid,
|
|
80
87
|
onEvent: (event) => {
|
|
88
|
+
if (!responding && event['type'] === 'assistant') {
|
|
89
|
+
responding = true;
|
|
90
|
+
console.log(`[${new Date().toLocaleTimeString()}] ◐ responding…`);
|
|
91
|
+
}
|
|
81
92
|
if (ws.readyState === ws_1.default.OPEN) {
|
|
82
93
|
ws.send(JSON.stringify({ type: 'stream', conversationId, event }));
|
|
83
94
|
}
|
|
84
95
|
},
|
|
85
|
-
onDone: (messageCount) => {
|
|
96
|
+
onDone: (messageCount, costUsd, usage) => {
|
|
97
|
+
const parts = [];
|
|
98
|
+
if (usage)
|
|
99
|
+
parts.push(`in:${usage.input_tokens} out:${usage.output_tokens}`);
|
|
100
|
+
if (costUsd > 0)
|
|
101
|
+
parts.push(`$${costUsd.toFixed(4)}`);
|
|
102
|
+
const suffix = parts.length ? ` (${parts.join(' ')})` : '';
|
|
103
|
+
console.log(`[${new Date().toLocaleTimeString()}] ✓ done${suffix}`);
|
|
86
104
|
if (ws.readyState === ws_1.default.OPEN) {
|
|
87
|
-
ws.send(JSON.stringify({ type: 'done', conversationId, messageCount, costUsd
|
|
105
|
+
ws.send(JSON.stringify({ type: 'done', conversationId, messageCount, costUsd }));
|
|
88
106
|
}
|
|
89
107
|
},
|
|
90
108
|
onError: (message) => {
|
|
91
|
-
console.error(`[
|
|
109
|
+
console.error(`[${new Date().toLocaleTimeString()}] ✗ ${message}`);
|
|
92
110
|
if (ws.readyState === ws_1.default.OPEN) {
|
|
93
111
|
ws.send(JSON.stringify({ type: 'error', conversationId, message }));
|
|
94
112
|
}
|
|
@@ -123,9 +141,9 @@ function connect(auth, retryDelay = 1000) {
|
|
|
123
141
|
}
|
|
124
142
|
// ─── Main ─────────────────────────────────────────────────────────────────────
|
|
125
143
|
async function main() {
|
|
126
|
-
console.log(
|
|
144
|
+
console.log(`1Presence Bridge v${package_json_1.version}\n`);
|
|
127
145
|
// Auth
|
|
128
|
-
const auth = await (0, auth_1.getValidAuth)(GATEWAY_HTTP);
|
|
146
|
+
const auth = await (0, auth_1.getValidAuth)(GATEWAY_HTTP, PWA_URL);
|
|
129
147
|
currentAuth = auth;
|
|
130
148
|
// Write system prompt + MCP config
|
|
131
149
|
process.stdout.write('Setting up…');
|