@tenux/cli 0.0.14 → 0.0.16

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.
@@ -90,6 +90,9 @@ var Relay = class {
90
90
  channel = null;
91
91
  handlers = /* @__PURE__ */ new Map();
92
92
  deviceId;
93
+ pollTimer = null;
94
+ processing = false;
95
+ // guard against overlapping poll + realtime
93
96
  constructor(supabase) {
94
97
  this.supabase = supabase;
95
98
  this.deviceId = loadConfig().deviceId;
@@ -123,11 +126,16 @@ var Relay = class {
123
126
  console.log(chalk.green("\u2713"), "Listening for commands");
124
127
  }
125
128
  });
129
+ this.pollTimer = setInterval(() => this.processPending(), 5e3);
126
130
  }
127
131
  /**
128
132
  * Stop listening.
129
133
  */
130
134
  async stop() {
135
+ if (this.pollTimer) {
136
+ clearInterval(this.pollTimer);
137
+ this.pollTimer = null;
138
+ }
131
139
  if (this.channel) {
132
140
  await this.supabase.removeChannel(this.channel);
133
141
  this.channel = null;
@@ -137,21 +145,28 @@ var Relay = class {
137
145
  * Process any commands that arrived while the agent was offline.
138
146
  */
139
147
  async processPending() {
140
- const { data: pending } = await this.supabase.from("commands").select("*").eq("device_id", this.deviceId).eq("status", "pending").order("created_at", { ascending: true });
141
- if (pending && pending.length > 0) {
142
- console.log(
143
- chalk.yellow("\u26A1"),
144
- `Processing ${pending.length} pending command(s)`
145
- );
146
- for (const cmd of pending) {
147
- await this.dispatch(cmd);
148
+ if (this.processing) return;
149
+ this.processing = true;
150
+ try {
151
+ const { data: pending } = await this.supabase.from("commands").select("*").eq("device_id", this.deviceId).eq("status", "pending").order("created_at", { ascending: true });
152
+ if (pending && pending.length > 0) {
153
+ console.log(
154
+ chalk.yellow("\u26A1"),
155
+ `Processing ${pending.length} pending command(s)`
156
+ );
157
+ for (const cmd of pending) {
158
+ await this.dispatch(cmd);
159
+ }
148
160
  }
161
+ } catch {
149
162
  }
163
+ this.processing = false;
150
164
  }
151
165
  /**
152
166
  * Dispatch a command to the appropriate handler.
153
167
  */
154
168
  async dispatch(command) {
169
+ if (command.status !== "pending") return;
155
170
  const handler = this.handlers.get(command.type);
156
171
  if (!handler) {
157
172
  console.log(
@@ -253,6 +268,7 @@ async function handleClaudeQuery(command, supabase) {
253
268
  proc.stdin.end();
254
269
  let seq = 0;
255
270
  let capturedSessionId = null;
271
+ const userId = command.user_id;
256
272
  let batch = [];
257
273
  const batchInterval = 100;
258
274
  const flushBatch = async () => {
@@ -279,6 +295,7 @@ async function handleClaudeQuery(command, supabase) {
279
295
  }
280
296
  batch.push({
281
297
  command_id: command.id,
298
+ user_id: userId,
282
299
  seq: seq++,
283
300
  type: event.type || "assistant",
284
301
  data: event
@@ -286,6 +303,7 @@ async function handleClaudeQuery(command, supabase) {
286
303
  } catch {
287
304
  batch.push({
288
305
  command_id: command.id,
306
+ user_id: userId,
289
307
  seq: seq++,
290
308
  type: "stdout",
291
309
  data: { text: line }
@@ -299,6 +317,7 @@ async function handleClaudeQuery(command, supabase) {
299
317
  stderrText += text;
300
318
  batch.push({
301
319
  command_id: command.id,
320
+ user_id: userId,
302
321
  seq: seq++,
303
322
  type: "stderr",
304
323
  data: { text }
@@ -309,6 +328,7 @@ async function handleClaudeQuery(command, supabase) {
309
328
  if (buffer.trim()) {
310
329
  batch.push({
311
330
  command_id: command.id,
331
+ user_id: userId,
312
332
  seq: seq++,
313
333
  type: "stdout",
314
334
  data: { text: buffer }
@@ -316,6 +336,7 @@ async function handleClaudeQuery(command, supabase) {
316
336
  }
317
337
  batch.push({
318
338
  command_id: command.id,
339
+ user_id: userId,
319
340
  seq: seq++,
320
341
  type: "done",
321
342
  data: { exit_code: exitCode }
package/dist/cli.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  loadConfig,
10
10
  saveConfig,
11
11
  updateConfig
12
- } from "./chunk-JN3TO63A.js";
12
+ } from "./chunk-MB4X6UQJ.js";
13
13
 
14
14
  // src/cli.ts
15
15
  import { Command } from "commander";
package/dist/index.d.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  import { SupabaseClient } from '@supabase/supabase-js';
2
2
 
3
3
  /**
4
- * Relay — Supabase Realtime subscription for incoming commands.
4
+ * Relay — Listens for incoming commands via Supabase.
5
5
  *
6
- * Listens to INSERT events on the `commands` table filtered by device_id.
7
- * Dispatches each command to the appropriate handler.
6
+ * Uses Realtime subscription (when available) AND polling fallback (every 5s)
7
+ * to ensure commands are always picked up, even when Realtime is unreliable.
8
8
  */
9
9
 
10
10
  interface Command {
@@ -24,6 +24,8 @@ declare class Relay {
24
24
  private channel;
25
25
  private handlers;
26
26
  private deviceId;
27
+ private pollTimer;
28
+ private processing;
27
29
  constructor(supabase: SupabaseClient);
28
30
  /**
29
31
  * Register a handler for a command type (e.g., "git.clone", "claude.query").
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  resetSupabase,
8
8
  saveConfig,
9
9
  updateConfig
10
- } from "./chunk-JN3TO63A.js";
10
+ } from "./chunk-MB4X6UQJ.js";
11
11
  export {
12
12
  Relay,
13
13
  configExists,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tenux/cli",
3
- "version": "0.0.14",
3
+ "version": "0.0.16",
4
4
  "description": "Tenux — mobile-first IDE for 10x engineering",
5
5
  "author": "Antelogic LLC",
6
6
  "license": "MIT",