spudmobile-bridge 1.0.0 → 1.0.2

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/index.js CHANGED
@@ -61,6 +61,7 @@ async function main() {
61
61
  const isActive = await bridge.isPairActive(config.pairId);
62
62
  if (isActive) {
63
63
  console.log(`✅ Using saved pair: ${config.pairId}`);
64
+ await bridge.resolveUserId();
64
65
  }
65
66
  else {
66
67
  console.log('⚠️ Saved pair is no longer active. Re-pairing...');
@@ -137,6 +138,10 @@ async function startOperations() {
137
138
  }
138
139
  // Start presence heartbeat
139
140
  bridge.startPresenceHeartbeat();
141
+ // Send Connection established message so iOS app shows Connected
142
+ const projectName = config.projectPath?.split('/').filter(Boolean).pop() || 'unknown';
143
+ await bridge.sendSystemMessage(`SYSTEM: Connection established | workspace:${projectName}`);
144
+ console.log('📱 Sent Connection established to iOS');
140
145
  // Process any pending messages
141
146
  const pending = await bridge.getPendingMessages();
142
147
  if (pending.length > 0) {
@@ -26,6 +26,7 @@ export declare class SupabaseBridge {
26
26
  private deviceId;
27
27
  pairId: string | null;
28
28
  sessionId: string | null;
29
+ userId: string | null;
29
30
  constructor(config: BridgeConfig);
30
31
  /**
31
32
  * Create a new session, deactivating any old sessions for this pair
@@ -61,6 +62,14 @@ export declare class SupabaseBridge {
61
62
  * Activate a device pair using the pair code from callback
62
63
  */
63
64
  activatePair(pairCode: string): Promise<string>;
65
+ /**
66
+ * Resolve the iOS user's device ID (user_id) from the paired device
67
+ */
68
+ resolveUserId(): Promise<string | null>;
69
+ /**
70
+ * Send a SYSTEM message to the messages table (Connection established / terminated)
71
+ */
72
+ sendSystemMessage(content: string): Promise<void>;
64
73
  /**
65
74
  * Subscribe to new user messages for processing
66
75
  */
package/dist/supabase.js CHANGED
@@ -10,6 +10,7 @@ export class SupabaseBridge {
10
10
  deviceId;
11
11
  pairId;
12
12
  sessionId = null;
13
+ userId = null;
13
14
  constructor(config) {
14
15
  this.config = config;
15
16
  this.client = createClient(config.supabaseUrl, config.supabaseAnonKey);
@@ -170,12 +171,29 @@ export class SupabaseBridge {
170
171
  * Activate a device pair using the pair code from callback
171
172
  */
172
173
  async activatePair(pairCode) {
173
- const { data: pair, error: findError } = await this.client
174
+ // Try finding by pair_code first (8-char hex codes)
175
+ let pair = null;
176
+ const { data: byCode } = await this.client
174
177
  .from('device_pairs')
175
178
  .select('id')
176
179
  .eq('pair_code', pairCode)
177
180
  .single();
178
- if (findError || !pair) {
181
+ if (byCode) {
182
+ pair = byCode;
183
+ }
184
+ else {
185
+ // Fallback: the token might be ios_device_id (UUID from the connect edge function)
186
+ const { data: byDevice } = await this.client
187
+ .from('device_pairs')
188
+ .select('id')
189
+ .ilike('ios_device_id', pairCode)
190
+ .eq('is_active', true)
191
+ .order('created_at', { ascending: false })
192
+ .limit(1)
193
+ .single();
194
+ pair = byDevice;
195
+ }
196
+ if (!pair) {
179
197
  throw new Error(`Pair not found for code: ${pairCode}`);
180
198
  }
181
199
  const { error: updateError } = await this.client
@@ -191,8 +209,50 @@ export class SupabaseBridge {
191
209
  }
192
210
  this.pairId = pair.id;
193
211
  saveConfig({ pairId: pair.id, pairCode });
212
+ // Resolve the iOS user_id from the pair
213
+ await this.resolveUserId();
194
214
  return pair.id;
195
215
  }
216
+ /**
217
+ * Resolve the iOS user's device ID (user_id) from the paired device
218
+ */
219
+ async resolveUserId() {
220
+ if (!this.pairId)
221
+ return null;
222
+ const { data, error } = await this.client
223
+ .from('device_pairs')
224
+ .select('ios_device_id')
225
+ .eq('id', this.pairId)
226
+ .single();
227
+ if (error || !data?.ios_device_id) {
228
+ console.error('⚠️ Could not resolve iOS user_id:', error?.message);
229
+ return null;
230
+ }
231
+ this.userId = data.ios_device_id?.toLowerCase() ?? null;
232
+ if (this.userId)
233
+ console.log(`👤 Resolved iOS user_id: ${this.userId.slice(0, 8)}…`);
234
+ return this.userId;
235
+ }
236
+ /**
237
+ * Send a SYSTEM message to the messages table (Connection established / terminated)
238
+ */
239
+ async sendSystemMessage(content) {
240
+ const { error } = await this.client
241
+ .from('messages')
242
+ .insert({
243
+ role: 'agent',
244
+ content,
245
+ status: 'completed',
246
+ client_type: 'spudmobile',
247
+ pair_id: this.pairId,
248
+ session_id: this.sessionId,
249
+ user_id: this.userId,
250
+ sender: 'macOS',
251
+ });
252
+ if (error) {
253
+ console.error('Failed to send system message:', error.message);
254
+ }
255
+ }
196
256
  /**
197
257
  * Subscribe to new user messages for processing
198
258
  */
@@ -289,6 +349,7 @@ export class SupabaseBridge {
289
349
  client_type: 'spudmobile',
290
350
  pair_id: this.pairId,
291
351
  session_id: this.sessionId,
352
+ user_id: this.userId,
292
353
  sender: 'macOS',
293
354
  parent_message_id: parentMessageId,
294
355
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spudmobile-bridge",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Bridge between OpenAI Codex CLI and SpudMobile iOS app via Supabase",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",