@vibedeckx/linux-x64 0.3.26 → 0.3.27

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.
Files changed (2) hide show
  1. package/dist/bin.js +132 -15
  2. package/package.json +1 -1
package/dist/bin.js CHANGED
@@ -186425,6 +186425,10 @@ var createRemoteServerRepos = (kdb, _h) => ({
186425
186425
  ]).where("project_remotes.project_id", "=", projectId).orderBy("project_remotes.sort_order", "asc").orderBy("project_remotes.id", "asc").execute();
186426
186426
  return rows.map(mapProjectRemoteWithServer);
186427
186427
  },
186428
+ listProjectIdsByServer: async (remoteServerId) => {
186429
+ const rows = await kdb.selectFrom("project_remotes").select("project_id").distinct().where("remote_server_id", "=", remoteServerId).execute();
186430
+ return rows.map((r) => r.project_id);
186431
+ },
186428
186432
  getByProjectAndServer: async (projectId, remoteServerId) => {
186429
186433
  const row = await kdb.selectFrom("project_remotes").innerJoin("remote_servers", "remote_servers.id", "project_remotes.remote_server_id").select([
186430
186434
  "project_remotes.id",
@@ -207274,8 +207278,10 @@ var ClaudeCodeProvider = class {
207274
207278
  if (systemMsg.subtype === BACKGROUND_TASKS_CHANGED_SUBTYPE) {
207275
207279
  const tasks = msg.tasks;
207276
207280
  if (!Array.isArray(tasks)) return [];
207277
- const taskIds = tasks.map((t) => t.task_id).filter((id) => typeof id === "string");
207278
- return [{ type: "task_list_changed", taskIds }];
207281
+ const parsed = tasks.flatMap(
207282
+ (t) => typeof t.task_id === "string" ? [{ taskId: t.task_id, taskType: t.task_type, description: t.description }] : []
207283
+ );
207284
+ return [{ type: "task_list_changed", tasks: parsed }];
207279
207285
  }
207280
207286
  if (systemMsg.subtype === INIT_SUBTYPE) {
207281
207287
  const nativeId = msg.session_id;
@@ -229445,7 +229451,7 @@ var ResidentProcessLimitError = class extends Error {
229445
229451
  var COMPLETION_GRACE_MS = 1500;
229446
229452
  var TurnCompletionLedger = class {
229447
229453
  /** Live background tasks by harness task_id (same id may restart). */
229448
- tasks = /* @__PURE__ */ new Set();
229454
+ tasks = /* @__PURE__ */ new Map();
229449
229455
  /** Held completion candidate — the latest success result, if any. */
229450
229456
  pending = null;
229451
229457
  /** Bumped whenever the candidate changes; stale grace timers no-op. */
@@ -229462,8 +229468,12 @@ var TurnCompletionLedger = class {
229462
229468
  get hasPendingCompletion() {
229463
229469
  return this.pending !== null;
229464
229470
  }
229465
- taskStarted(taskId) {
229466
- this.tasks.add(taskId);
229471
+ /** Live tasks in first-seen order — the payload the UI renders. */
229472
+ get backgroundTasks() {
229473
+ return [...this.tasks.values()];
229474
+ }
229475
+ taskStarted(task, now3) {
229476
+ this.upsert(task, this.tasks.get(task.taskId), now3);
229467
229477
  this.sawBackgroundActivity = true;
229468
229478
  return this.rearmIfHeld();
229469
229479
  }
@@ -229473,9 +229483,13 @@ var TurnCompletionLedger = class {
229473
229483
  return this.rearmIfHeld();
229474
229484
  }
229475
229485
  /** Authoritative snapshot from `system/background_tasks_changed`. */
229476
- taskListChanged(taskIds) {
229477
- this.tasks = new Set(taskIds);
229478
- if (taskIds.length > 0) this.sawBackgroundActivity = true;
229486
+ taskListChanged(tasks, now3) {
229487
+ const previous = this.tasks;
229488
+ this.tasks = /* @__PURE__ */ new Map();
229489
+ for (const task of tasks) {
229490
+ this.upsert(task, previous.get(task.taskId), now3);
229491
+ }
229492
+ if (tasks.length > 0) this.sawBackgroundActivity = true;
229479
229493
  return this.rearmIfHeld();
229480
229494
  }
229481
229495
  /**
@@ -229561,6 +229575,21 @@ var TurnCompletionLedger = class {
229561
229575
  if (this.tasks.size > 0) return { kind: "cancel" };
229562
229576
  return { kind: "schedule", generation: this.generation };
229563
229577
  }
229578
+ /**
229579
+ * Merge a descriptor into the live set, keeping the earliest `startedAt` and
229580
+ * any label already known: `task_started` carries a description that the
229581
+ * snapshot for the same task may omit, and the two arrive in either order.
229582
+ * `known` comes from the caller: a snapshot resync rebuilds the map, so the
229583
+ * prior entry is no longer reachable through `this.tasks`.
229584
+ */
229585
+ upsert(task, known, now3) {
229586
+ this.tasks.set(task.taskId, {
229587
+ taskId: task.taskId,
229588
+ taskType: task.taskType ?? known?.taskType,
229589
+ description: task.description ?? known?.description,
229590
+ startedAt: known?.startedAt ?? now3
229591
+ });
229592
+ }
229564
229593
  commitHeld() {
229565
229594
  const payload = this.pending;
229566
229595
  this.pending = null;
@@ -230226,6 +230255,7 @@ var AgentSessionManager = class {
230226
230255
  if (action.kind === "commit") {
230227
230256
  await this.commitCompletion(session, action.payload);
230228
230257
  }
230258
+ this.broadcastBackgroundTasks(session);
230229
230259
  if (code !== 0 && !spawnFailed && !session.producedOutput) {
230230
230260
  try {
230231
230261
  await this.pushEntry(session.id, {
@@ -230332,12 +230362,27 @@ var AgentSessionManager = class {
230332
230362
  resetCompletion(session) {
230333
230363
  this.clearGraceTimer(session);
230334
230364
  session.completion.reset();
230365
+ this.broadcastBackgroundTasks(session);
230335
230366
  }
230336
230367
  /**
230337
230368
  * The single place completion side effects run. Fired by processAgentEvent
230338
230369
  * for turns with no background activity (zero delay), by the grace timer
230339
230370
  * for held candidates, and by the close handler on a clean process exit.
230340
230371
  */
230372
+ /**
230373
+ * Push the live background-task set to every subscriber. Called on each
230374
+ * lifecycle event rather than diffed: the set is tiny and the harness
230375
+ * already only speaks on change, so a plain snapshot keeps the client
230376
+ * stateless (no patch application, no ordering assumptions).
230377
+ */
230378
+ broadcastBackgroundTasks(session) {
230379
+ this.broadcastRaw(session.id, {
230380
+ backgroundTasks: {
230381
+ tasks: session.completion.backgroundTasks,
230382
+ turnParked: session.completion.hasPendingCompletion
230383
+ }
230384
+ });
230385
+ }
230341
230386
  async commitCompletion(session, payload) {
230342
230387
  const sessionId = session.id;
230343
230388
  console.log(`[AgentSession] taskCompleted: sessionId=${sessionId}, eventBus=${!!this.eventBus}, projectId=${session.projectId}, branch=${session.branch}`);
@@ -230346,6 +230391,7 @@ var AgentSessionManager = class {
230346
230391
  await this.storage.agentSessions.markCompleted(sessionId, completedAt);
230347
230392
  }
230348
230393
  const turnEndEntryIndex = await this.endActiveTurn(session, "completed");
230394
+ this.broadcastBackgroundTasks(session);
230349
230395
  const summaryText = extractLastAssistantText(session.store.entries);
230350
230396
  this.broadcastRaw(sessionId, {
230351
230397
  taskCompleted: {
@@ -230526,19 +230572,26 @@ var AgentSessionManager = class {
230526
230572
  // no auto-resume behind it, and cancelling on it would drop the
230527
230573
  // completion entirely.
230528
230574
  case "task_started":
230529
- this.applyCompletionTimerAction(session, session.completion.taskStarted(event.taskId));
230575
+ this.applyCompletionTimerAction(session, session.completion.taskStarted({
230576
+ taskId: event.taskId,
230577
+ taskType: event.taskType,
230578
+ description: event.description
230579
+ }, timestamp));
230530
230580
  session.taskStartedThisTurn++;
230581
+ this.broadcastBackgroundTasks(session);
230531
230582
  console.log(`[AgentSession] Background task started: ${event.taskId} (${event.taskType ?? "?"}) \u2014 ${session.completion.pendingTaskCount} pending in ${sessionId}`);
230532
230583
  break;
230533
230584
  case "task_finished":
230534
230585
  this.applyCompletionTimerAction(session, session.completion.taskFinished(event.taskId));
230586
+ this.broadcastBackgroundTasks(session);
230535
230587
  console.log(`[AgentSession] Background task finished: ${event.taskId} (${event.status ?? "?"}) \u2014 ${session.completion.pendingTaskCount} pending in ${sessionId}`);
230536
230588
  break;
230537
230589
  // Authoritative running-task snapshot from the CLI — resyncs the ledger
230538
230590
  // so add/delete drift in the started/finished pairs can't accumulate.
230539
230591
  case "task_list_changed":
230540
- this.applyCompletionTimerAction(session, session.completion.taskListChanged(event.taskIds));
230541
- console.log(`[AgentSession] Background task snapshot: [${event.taskIds.join(", ")}] in ${sessionId}`);
230592
+ this.applyCompletionTimerAction(session, session.completion.taskListChanged(event.tasks, timestamp));
230593
+ this.broadcastBackgroundTasks(session);
230594
+ console.log(`[AgentSession] Background task snapshot: [${event.tasks.map((t) => t.taskId).join(", ")}] in ${sessionId}`);
230542
230595
  break;
230543
230596
  // Handled above (cancels a grace-held completion); no store entry.
230544
230597
  case "turn_started":
@@ -230609,6 +230662,7 @@ var AgentSessionManager = class {
230609
230662
  console.log(`[AgentSession] result after background-task activity \u2014 holding completion for ${this.completionGraceMs}ms grace (session=${sessionId})`);
230610
230663
  }
230611
230664
  this.applyCompletionTimerAction(session, action);
230665
+ this.broadcastBackgroundTasks(session);
230612
230666
  }
230613
230667
  }
230614
230668
  break;
@@ -230941,6 +230995,13 @@ var AgentSessionManager = class {
230941
230995
  ws.send(JSON.stringify({ Ready: true, historyEpoch: session.historyEpoch }));
230942
230996
  const statusPatch = ConversationPatch.updateStatus(session.status);
230943
230997
  ws.send(JSON.stringify({ JsonPatch: statusPatch }));
230998
+ const tasksMsg = {
230999
+ backgroundTasks: {
231000
+ tasks: session.completion.backgroundTasks,
231001
+ turnParked: session.completion.hasPendingCompletion
231002
+ }
231003
+ };
231004
+ ws.send(JSON.stringify(tasksMsg));
230944
231005
  return () => {
230945
231006
  session.subscribers.delete(ws);
230946
231007
  };
@@ -231228,6 +231289,7 @@ var AgentSessionManager = class {
231228
231289
  session.process = null;
231229
231290
  this.killProcess(proc);
231230
231291
  this.emitProcessAlive(session, false);
231292
+ this.resetCompletion(session);
231231
231293
  if (!session.skipDb) {
231232
231294
  await this.storage.agentSessions.deleteEntries(sessionId);
231233
231295
  session.historyEpoch = await this.storage.agentSessions.incrementHistoryEpoch(sessionId);
@@ -233597,6 +233659,9 @@ function connectPersistentRemoteWs(sessionId, remoteInfo, cache2, reverseConnect
233597
233659
  );
233598
233660
  }
233599
233661
  }
233662
+ } else if ("backgroundTasks" in parsed) {
233663
+ cache2.setBackgroundTasks(sessionId, raw);
233664
+ cache2.broadcast(sessionId, raw);
233600
233665
  } else if ("error" in parsed) {
233601
233666
  cache2.setSessionStatus(sessionId, "error");
233602
233667
  cache2.appendMessage(sessionId, raw, false);
@@ -239414,6 +239479,8 @@ function selfReportSection(report) {
239414
239479
  ].join("\n");
239415
239480
  }
239416
239481
  var VERDICT_INSTRUCTIONS = [
239482
+ "\nThe bar for blocking: a real defect that is worth fixing \u2014 wrong behavior, a case a user or caller will actually hit, a security or data-loss risk, or a missing test for logic that matters. Report those plainly; do not soften a real problem because the fix is inconvenient.",
239483
+ "Not blocking: over-engineering \u2014 speculative hardening, defenses against inputs this code cannot receive, abstractions or configurability for cases nobody has asked for, or a rewrite in your preferred style. When the fix would add more complexity than the problem it prevents is worth, it is a non-blocking note at most.",
239417
239484
  "\nEnd your final message with:",
239418
239485
  "1. Verdict \u2014 exactly one of: ship / needs-changes / cannot-verify. Use cannot-verify when you could not gather enough evidence to judge, rather than guessing.",
239419
239486
  "2. Blocking findings \u2014 what must change before shipping, each specific and actionable (say explicitly when there are none).",
@@ -240101,7 +240168,8 @@ var RemotePatchCache = class {
240101
240168
  latestEntryIndex: null,
240102
240169
  lastTurnEndEntryIndex: null,
240103
240170
  coverage: null,
240104
- sessionStatus: null
240171
+ sessionStatus: null,
240172
+ backgroundTasks: null
240105
240173
  };
240106
240174
  this.cache.set(sessionId, entry);
240107
240175
  }
@@ -240149,6 +240217,7 @@ var RemotePatchCache = class {
240149
240217
  if (metadata.lastTurnEnd !== null) lastTurnEndEntryIndex = Math.max(lastTurnEndEntryIndex ?? -1, metadata.lastTurnEnd);
240150
240218
  }
240151
240219
  const sessionStatus = existing?.sessionStatus ?? null;
240220
+ const backgroundTasks = existing?.backgroundTasks ?? null;
240152
240221
  const coverage = existing?.coverage ?? null;
240153
240222
  this.cache.set(sessionId, {
240154
240223
  messages,
@@ -240164,7 +240233,8 @@ var RemotePatchCache = class {
240164
240233
  latestEntryIndex,
240165
240234
  lastTurnEndEntryIndex,
240166
240235
  coverage,
240167
- sessionStatus
240236
+ sessionStatus,
240237
+ backgroundTasks
240168
240238
  });
240169
240239
  }
240170
240240
  /**
@@ -240229,6 +240299,7 @@ var RemotePatchCache = class {
240229
240299
  entry.historyEpoch = epoch;
240230
240300
  entry.latestEntryIndex = null;
240231
240301
  entry.lastTurnEndEntryIndex = null;
240302
+ entry.backgroundTasks = null;
240232
240303
  entry.coverage = { epoch, start: 0 };
240233
240304
  }
240234
240305
  setLastTurnEndEntryIndex(sessionId, index) {
@@ -240237,6 +240308,10 @@ var RemotePatchCache = class {
240237
240308
  setSessionStatus(sessionId, status) {
240238
240309
  this.getOrCreate(sessionId).sessionStatus = status;
240239
240310
  }
240311
+ /** Last-value store for the live background-task snapshot (see CacheEntry). */
240312
+ setBackgroundTasks(sessionId, raw) {
240313
+ this.getOrCreate(sessionId).backgroundTasks = raw;
240314
+ }
240240
240315
  /** Store a persistent remote WebSocket connection. */
240241
240316
  setRemoteWs(sessionId, ws) {
240242
240317
  const entry = this.getOrCreate(sessionId);
@@ -243265,6 +243340,13 @@ var sharedServices = async (fastify2, opts) => {
243265
243340
  reverseConnectManager.setStatusChangeHandler((remoteServerId, status) => {
243266
243341
  void (async () => {
243267
243342
  await opts.storage.remoteServers.updateStatus(remoteServerId, status);
243343
+ try {
243344
+ for (const projectId of await opts.storage.projectRemotes.listProjectIdsByServer(remoteServerId)) {
243345
+ eventBus.emit({ type: "remote-server:status", projectId, remoteServerId, status });
243346
+ }
243347
+ } catch (err) {
243348
+ console.error(`[SharedServices] remote-server:status fan-out failed for ${remoteServerId}:`, err);
243349
+ }
243268
243350
  if (status === "online") {
243269
243351
  const machineId = reverseConnectManager.getMachineId(remoteServerId);
243270
243352
  await restoreRemoteExecutorsForServer(remoteServerId, machineId);
@@ -251877,6 +251959,12 @@ var routes23 = async (fastify2) => {
251877
251959
  socket.send(JSON.stringify({ Ready: true, historyEpoch: cacheEntry.historyEpoch ?? void 0 }));
251878
251960
  } catch {
251879
251961
  }
251962
+ if (cacheEntry.backgroundTasks !== null) {
251963
+ try {
251964
+ socket.send(cacheEntry.backgroundTasks);
251965
+ } catch {
251966
+ }
251967
+ }
251880
251968
  if (cacheEntry.finished) {
251881
251969
  try {
251882
251970
  socket.send(JSON.stringify({ finished: true }));
@@ -252264,6 +252352,11 @@ var routes25 = async (fastify2) => {
252264
252352
  "Access-Control-Allow-Origin": "*"
252265
252353
  });
252266
252354
  reply.raw.write(":ok\n\n");
252355
+ reply.raw.write(
252356
+ `data: ${JSON.stringify({ type: "hello", ...fastify2.uiBuildId ? { uiBuildId: fastify2.uiBuildId } : {} })}
252357
+
252358
+ `
252359
+ );
252267
252360
  const unsubscribe = fastify2.eventBus.subscribe((event) => {
252268
252361
  void (async () => {
252269
252362
  if (userId !== null && !await fastify2.storage.projects.getById(event.projectId, userId)) {
@@ -258633,6 +258726,8 @@ var REMOTE_ID_PROP = {
258633
258726
  };
258634
258727
  var CROSS_REMOTE_MCP_INSTRUCTIONS = [
258635
258728
  "Use these tools when the task requires inspecting or operating another remote machine, or using an MCP server reachable from that remote.",
258729
+ "Treat a machine or host name in the user's request (for example, 'look at the ubuntu machine') as an explicit target signal, not as a request to inspect the current local workspace. Call `list_accessible_remotes` and match the user's wording against the returned remote names and ids before reading files or running local commands.",
258730
+ "If exactly one accessible remote matches the named machine, perform the requested work on that remote. If multiple remotes match, or the wording could reasonably refer to either the local machine or a remote, ask the user which target they mean before operating. If no remote matches, say so instead of silently falling back to local.",
258636
258731
  "Cross-remote can discover accessible machines, inspect files, directories, paths, and processes, run commands on exec-tier remotes, and persistently use MCP servers reachable from those remotes. Available operations depend on the remote's access tier, online state, and worker capabilities.",
258637
258732
  "Call `list_accessible_remotes` first to discover the remote id, access tier, online state, and whether its MCP broker is supported.",
258638
258733
  "For a remote MCP server, call `remote_mcp_open` once, use the returned tool schemas and handle for repeated `remote_mcp_call` calls, then call `remote_mcp_close` when the work is complete. Do not reopen the MCP server for every tool call.",
@@ -258643,7 +258738,7 @@ var CROSS_REMOTE_MCP_INSTRUCTIONS = [
258643
258738
  var TOOLS = [
258644
258739
  {
258645
258740
  name: "list_accessible_remotes",
258646
- description: "List the remote machines this agent may access, with their access tier and online status.",
258741
+ description: "List remote machines this agent may access, including their names, ids, access tiers, and online status. Call this before acting whenever the user names or otherwise identifies a machine/host, so the request is routed to the intended target instead of the current local machine.",
258647
258742
  inputSchema: { type: "object", properties: {}, additionalProperties: false }
258648
258743
  },
258649
258744
  {
@@ -259996,6 +260091,12 @@ function registerTraceContext(server) {
259996
260091
 
259997
260092
  // src/server.ts
259998
260093
  var API_KEY2 = process.env.VIBEDECKX_API_KEY || void 0;
260094
+ function staticCacheControl(filePath) {
260095
+ const p2 = filePath.replace(/\\/g, "/");
260096
+ if (p2.includes("/_next/static/")) return "public, max-age=31536000, immutable";
260097
+ if (p2.endsWith(".html") || p2.endsWith(".txt")) return "no-cache";
260098
+ return "public, max-age=86400";
260099
+ }
259999
260100
  function requireAuth(req, reply) {
260000
260101
  const server = req.server;
260001
260102
  if (!server.authEnabled) return void 0;
@@ -260045,6 +260146,14 @@ var createServer = async (opts) => {
260045
260146
  "./ui"
260046
260147
  );
260047
260148
  const UI_ROOT = opts.uiRoot !== void 0 ? opts.uiRoot : fs5.existsSync(bakedUiRoot) ? bakedUiRoot : null;
260149
+ let uiBuildId;
260150
+ if (UI_ROOT) {
260151
+ try {
260152
+ const parsed = JSON.parse(fs5.readFileSync(path19.join(UI_ROOT, "build-id.json"), "utf8"));
260153
+ if (typeof parsed.buildId === "string" && parsed.buildId) uiBuildId = parsed.buildId;
260154
+ } catch {
260155
+ }
260156
+ }
260048
260157
  const server = (0, import_fastify.default)({
260049
260158
  maxParamLength: 500,
260050
260159
  bodyLimit: 16 * 1024 * 1024,
@@ -260071,6 +260180,7 @@ var createServer = async (opts) => {
260071
260180
  console.log(`[WS-RAW] HTTP upgrade event: ${redactUrlForLog(req.url)}`);
260072
260181
  });
260073
260182
  server.decorate("authEnabled", authEnabled);
260183
+ server.decorate("uiBuildId", uiBuildId);
260074
260184
  server.decorate("noLocalProjects", noLocalProjects);
260075
260185
  registerTraceContext(server);
260076
260186
  server.addHook("onRequest", (req, reply, done) => {
@@ -260185,7 +260295,14 @@ var createServer = async (opts) => {
260185
260295
  if (UI_ROOT) {
260186
260296
  server.register(import_static.fastifyStatic, {
260187
260297
  root: UI_ROOT,
260188
- wildcard: false
260298
+ wildcard: false,
260299
+ // Cache policy is ours, not send's default (`public, max-age=0`): with no
260300
+ // origin Cache-Control, Cloudflare was stamping a 4h TTL on every asset
260301
+ // and every reload re-downloaded ~1.2MB of content-hashed chunks.
260302
+ cacheControl: false,
260303
+ setHeaders: (res, filePath) => {
260304
+ res.setHeader("Cache-Control", staticCacheControl(filePath));
260305
+ }
260189
260306
  });
260190
260307
  }
260191
260308
  server.addHook("onError", (req, _reply, error48, done) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibedeckx/linux-x64",
3
- "version": "0.3.26",
3
+ "version": "0.3.27",
4
4
  "description": "Vibedeckx platform binaries for Linux x64",
5
5
  "os": [
6
6
  "linux"