@vibedeckx/linux-x64 0.3.20 → 0.3.21

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 +192 -61
  2. package/package.json +1 -1
package/dist/bin.js CHANGED
@@ -205496,9 +205496,17 @@ var PROPOSE_SCHEDULE_DESCRIPTION = [
205496
205496
  "itself and this call does not wait for the user. Say you have SUGGESTED a scheduled check",
205497
205497
  "(never that you created one) and continue.",
205498
205498
  "",
205499
+ "Give EXACTLY ONE of `prompt` or `command`:",
205500
+ "- `command` runs a shell command in the project directory. Prefer it when the check is",
205501
+ " mechanical and its output speaks for itself (a test suite, a health request, a disk",
205502
+ " check). It is cheaper and its result is unambiguous.",
205503
+ "- `prompt` starts a fresh agent. Use it when the check needs judgement \u2014 reading logs,",
205504
+ " comparing behaviour, deciding whether something counts as a regression.",
205505
+ "",
205499
205506
  "`prompt` must be self-contained: the scheduled run is a fresh agent with none of this",
205500
205507
  "conversation's context. Spell out what to check, how to tell pass from fail, and what to",
205501
- "write in the report when something regressed.",
205508
+ "write in the report when something regressed. A `command` should likewise be non-interactive",
205509
+ "and exit non-zero when the check fails.",
205502
205510
  "",
205503
205511
  "Project, execution target and branch are taken from this session \u2014 do not describe them here."
205504
205512
  ].join("\n");
@@ -205507,15 +205515,16 @@ var PROPOSE_SCHEDULE_INPUT_SCHEMA = {
205507
205515
  properties: {
205508
205516
  name: { type: "string", description: 'Short label for the scheduled check, e.g. "Watch nightly build flakiness"' },
205509
205517
  cron_expr: { type: "string", description: '5-field cron expression, e.g. "0 9 * * *" for every day at 09:00' },
205510
- prompt: { type: "string", description: "Self-contained instructions for the scheduled agent run" },
205518
+ prompt: { type: "string", description: "Self-contained instructions for a scheduled agent run. Give this OR command, not both." },
205519
+ command: { type: "string", description: 'Non-interactive shell command to run for the check, e.g. "pnpm test --run flaky". Give this OR prompt, not both.' },
205511
205520
  timezone: { type: "string", description: `Optional IANA timezone for the cron expression, e.g. "Asia/Shanghai". Defaults to the user's browser timezone.` }
205512
205521
  },
205513
- required: ["name", "cron_expr", "prompt"]
205522
+ required: ["name", "cron_expr"]
205514
205523
  };
205515
205524
  var PROPOSE_SCHEDULE_ACK = "Proposal shown to the user as a confirmation card. Nothing has been created yet \u2014 the user decides whether to accept it, outside this conversation. Tell the user you SUGGESTED a scheduled check and that they can confirm it on the card above.";
205516
205525
  var NAME_MAX = 200;
205517
205526
  var CRON_MAX = 200;
205518
- var PROMPT_MAX = 2e4;
205527
+ var CONTENT_MAX = 2e4;
205519
205528
  var TIMEZONE_MAX = 100;
205520
205529
  var str = (value) => typeof value === "string" ? value.trim() : null;
205521
205530
  function parseProposeScheduleArgs(args) {
@@ -205525,14 +205534,20 @@ function parseProposeScheduleArgs(args) {
205525
205534
  const cronExpr = str(args.cron_expr);
205526
205535
  if (!cronExpr) return { ok: false, error: "cron_expr is required" };
205527
205536
  if (cronExpr.length > CRON_MAX) return { ok: false, error: `cron_expr must be at most ${CRON_MAX} characters` };
205528
- const prompt = typeof args.prompt === "string" ? args.prompt : null;
205529
- if (!prompt?.trim()) return { ok: false, error: "prompt is required" };
205530
- if (prompt.length > PROMPT_MAX) return { ok: false, error: `prompt must be at most ${PROMPT_MAX} characters` };
205537
+ const prompt = typeof args.prompt === "string" && args.prompt.trim() ? args.prompt : null;
205538
+ const command = typeof args.command === "string" && args.command.trim() ? args.command : null;
205539
+ if (prompt && command) return { ok: false, error: "give either prompt or command, not both" };
205540
+ if (!prompt && !command) return { ok: false, error: "either prompt or command is required" };
205541
+ const run_type = prompt ? "prompt" : "command";
205542
+ const content = prompt ?? command;
205543
+ if (content.length > CONTENT_MAX) {
205544
+ return { ok: false, error: `${run_type} must be at most ${CONTENT_MAX} characters` };
205545
+ }
205531
205546
  const timezone = str(args.timezone) ?? void 0;
205532
205547
  if (timezone && timezone.length > TIMEZONE_MAX) {
205533
205548
  return { ok: false, error: `timezone must be at most ${TIMEZONE_MAX} characters` };
205534
205549
  }
205535
- return { ok: true, value: { name: name25, cron_expr: cronExpr, prompt, ...timezone ? { timezone } : {} } };
205550
+ return { ok: true, value: { name: name25, cron_expr: cronExpr, run_type, content, ...timezone ? { timezone } : {} } };
205536
205551
  }
205537
205552
  var PROPOSE_SCHEDULE_ALIASES = new Set(
205538
205553
  [
@@ -207825,7 +207840,7 @@ var EntryTracker = class {
207825
207840
  // src/utils/worktree-paths.ts
207826
207841
  import path7 from "path";
207827
207842
  import { createHash } from "crypto";
207828
- import { execSync } from "child_process";
207843
+ import { execSync, execFileSync as execFileSync2 } from "child_process";
207829
207844
  var WORKTREE_BASE_DIR = "/var/tmp/vibedeckx/worktrees";
207830
207845
  var WORKTREE_LIST_TTL_MS = 1e4;
207831
207846
  var worktreeListCache = /* @__PURE__ */ new Map();
@@ -208030,6 +208045,41 @@ async function anchorRootWorkspaceBranch(storage, projectId, projectPath, observ
208030
208045
  });
208031
208046
  return { anchored: true, expectedBranch: rootEntry.branch };
208032
208047
  }
208048
+ function localBranchExists(projectPath, branch) {
208049
+ try {
208050
+ execFileSync2("git", ["show-ref", "--verify", "--quiet", `refs/heads/${branch}`], {
208051
+ cwd: projectPath,
208052
+ encoding: "utf-8",
208053
+ stdio: ["pipe", "pipe", "pipe"]
208054
+ });
208055
+ return true;
208056
+ } catch {
208057
+ return false;
208058
+ }
208059
+ }
208060
+ async function setRootWorkspaceAnchor(storage, projectId, projectPath, branch) {
208061
+ invalidateWorktreeListCache(projectPath);
208062
+ const entries = readWorktreeListTolerant(projectPath);
208063
+ const rootEntry = entries[0];
208064
+ if (!rootEntry || !localBranchExists(projectPath, branch)) {
208065
+ return { anchored: false, reason: rootEntry ? "unknown-branch" : "not-a-repository" };
208066
+ }
208067
+ const registered = await storage.workspaceRegistry.listByProject(projectId, "local");
208068
+ const takenByWorkspace = registered.some((row) => row.workspace.branch !== "" && row.workspace.branch === branch);
208069
+ const takenByWorktree = entries.slice(1).some((entry) => entry.branch === branch);
208070
+ if (takenByWorkspace || takenByWorktree) {
208071
+ return { anchored: false, reason: "branch-is-another-workspace" };
208072
+ }
208073
+ await storage.workspaceRegistry.registerReadyCheckout({
208074
+ projectId,
208075
+ branch: "",
208076
+ // The main-workspace identity sentinel; never the branch name.
208077
+ targetId: "local",
208078
+ worktreePath: rootEntry.path,
208079
+ expectedBranch: branch
208080
+ });
208081
+ return { anchored: true, expectedBranch: branch };
208082
+ }
208033
208083
 
208034
208084
  // ../../node_modules/.pnpm/@ai-sdk+provider@3.0.8/node_modules/@ai-sdk/provider/dist/index.mjs
208035
208085
  var marker = "vercel.ai.error";
@@ -228952,11 +229002,11 @@ async function generateSessionTitle(storage, userMessage, userId) {
228952
229002
  }
228953
229003
 
228954
229004
  // src/utils/review-snapshot.ts
228955
- import { execFileSync as execFileSync2 } from "child_process";
229005
+ import { execFileSync as execFileSync3 } from "child_process";
228956
229006
  var MAX_BUFFER = 10 * 1024 * 1024;
228957
229007
  var ABSENT = "absent";
228958
229008
  function git(cwd, args, input) {
228959
- return execFileSync2("git", args, {
229009
+ return execFileSync3("git", args, {
228960
229010
  cwd,
228961
229011
  encoding: "utf-8",
228962
229012
  maxBuffer: MAX_BUFFER,
@@ -238964,11 +239014,11 @@ var ProjectChatManager = class {
238964
239014
  import { randomUUID as randomUUID6 } from "crypto";
238965
239015
 
238966
239016
  // src/utils/review-target.ts
238967
- import { execFileSync as execFileSync3 } from "child_process";
239017
+ import { execFileSync as execFileSync4 } from "child_process";
238968
239018
  import { createHash as createHash3 } from "crypto";
238969
239019
  var MAX_BUFFER2 = 10 * 1024 * 1024;
238970
239020
  function git2(cwd, args) {
238971
- return execFileSync3("git", args, {
239021
+ return execFileSync4("git", args, {
238972
239022
  cwd,
238973
239023
  encoding: "utf-8",
238974
239024
  maxBuffer: MAX_BUFFER2,
@@ -239661,33 +239711,27 @@ var WorkflowEngine = class {
239661
239711
  return updated;
239662
239712
  }
239663
239713
  /**
239664
- * Human takeover (spec §3.4): user sent a message directly to a run session.
239714
+ * Handle a user message sent directly to a review participant.
239665
239715
  *
239666
- * Reviewer 分流:向 reviewer 发消息不再是接管——它开启一轮讨论,把 run
239667
- * 移入 `discussing`(gate 收起),等待显式的 requestFinalVerdict 重新出稿。
239668
- * 只有向 source session 发消息才算接管,结束 run
239716
+ * Reviewer 分流:向 reviewer 发消息会开启一轮讨论,把 run 移入
239717
+ * `discussing`(gate 收起),等待显式的 requestFinalVerdict 重新出稿。
239718
+ * source session 发消息不改变 review run:review 针对启动时捕获的
239719
+ * 快照继续独立运行,只有显式取消操作才会结束它。
239669
239720
  *
239670
239721
  * Never-throws contract: this is called inline from the agent-session
239671
239722
  * `/message` route BEFORE the user's message is delivered
239672
239723
  * (agentOps.sendUserMessage). A throw here would abort delivery of that
239673
- * message, so this method must never throw any error from cancelRun is
239674
- * caught and swallowed, never rethrown. `bad-state` is the expected case:
239675
- * it means the run is mid-send (approveFeedback's own CAS holds it in
239676
- * `sending_feedback`), a transient race, so we just log and let the
239677
- * takeover no-op; the run resolves on its own via approveFeedback's
239678
- * completion/rollback. Any other error is unexpected but still swallowed
239679
- * to honor the contract, with a louder log so it isn't silently lost.
239724
+ * message, so this method must never throw. Storage errors from the reviewer
239725
+ * transition are caught and swallowed so they cannot block message delivery.
239680
239726
  */
239681
239727
  async handleExternalUserMessage(sessionId) {
239682
239728
  const p2 = this.participants.get(sessionId);
239683
239729
  if (!p2) return;
239684
239730
  if (p2.role === "reviewer") {
239685
239731
  try {
239686
- const moved = await this.storage.workflowRuns.transition(p2.runId, "waiting_feedback", "discussing", { error: null }) || await this.storage.workflowRuns.transition(p2.runId, "waiting_reviewer", "discussing", { error: null });
239687
- if (moved) {
239688
- const updated = await this.storage.workflowRuns.getById(p2.runId);
239689
- if (updated) this.emitRunUpdated(updated);
239690
- }
239732
+ await this.storage.workflowRuns.transition(p2.runId, "waiting_feedback", "discussing", { error: null }) || await this.storage.workflowRuns.transition(p2.runId, "waiting_reviewer", "discussing", { error: null });
239733
+ const updated = await this.storage.workflowRuns.getById(p2.runId);
239734
+ if (updated) this.emitRunUpdated(updated);
239691
239735
  } catch (err) {
239692
239736
  console.error(
239693
239737
  `[WorkflowEngine] handleExternalUserMessage: failed moving run ${p2.runId} to discussing; swallowed to honor never-throws contract`,
@@ -239696,20 +239740,6 @@ var WorkflowEngine = class {
239696
239740
  }
239697
239741
  return;
239698
239742
  }
239699
- try {
239700
- await this.cancelRun(p2.runId, "\u7528\u6237\u63A5\u7BA1\uFF1A\u76F4\u63A5\u5411 source session \u53D1\u9001\u4E86\u6D88\u606F\uFF0Creview \u5DF2\u7ED3\u675F\u3002");
239701
- } catch (err) {
239702
- if (err instanceof WorkflowError && err.code === "bad-state") {
239703
- console.warn(
239704
- `[WorkflowEngine] handleExternalUserMessage: run ${p2.runId} is mid-send (sending_feedback); skipping takeover cancel`
239705
- );
239706
- } else {
239707
- console.error(
239708
- `[WorkflowEngine] handleExternalUserMessage: unexpected error cancelling run ${p2.runId}; swallowed to honor never-throws contract`,
239709
- err
239710
- );
239711
- }
239712
- }
239713
239743
  }
239714
239744
  emitRunUpdated(run2) {
239715
239745
  this.eventBus?.emit({ type: "workflow:run-updated", projectId: run2.project_id, branch: run2.branch, run: run2 });
@@ -244281,6 +244311,16 @@ async function getRemoteConfig(fastify2, project) {
244281
244311
  const all = await getAllRemoteConfigs(fastify2, project);
244282
244312
  return all.length > 0 ? all[0] : null;
244283
244313
  }
244314
+ function anchorFailure(reason, branch) {
244315
+ switch (reason) {
244316
+ case "unknown-branch":
244317
+ return { code: 400, error: `Branch '${branch}' does not exist in this repository` };
244318
+ case "branch-is-another-workspace":
244319
+ return { code: 409, error: `'${branch}' already has its own workspace` };
244320
+ case "not-a-repository":
244321
+ return { code: 400, error: "The main workspace is not a Git repository" };
244322
+ }
244323
+ }
244284
244324
  async function ensurePathProject(fastify2, projectPath) {
244285
244325
  const projectId = await ensurePathProjectId(fastify2, projectPath);
244286
244326
  const project = await fastify2.storage.projects.getById(projectId);
@@ -244386,9 +244426,9 @@ var routes8 = async (fastify2) => {
244386
244426
  console.log(`[worktree] ${requestId} Creating: branch=${trimmedBranch}, base=${startPoint}, path=${projectPath}`);
244387
244427
  let pendingCheckoutId = null;
244388
244428
  try {
244389
- const { execFileSync: execFileSync7 } = await import("child_process");
244429
+ const { execFileSync: execFileSync8 } = await import("child_process");
244390
244430
  try {
244391
- execFileSync7("git", ["rev-parse", "--verify", `refs/heads/${trimmedBranch}`], {
244431
+ execFileSync8("git", ["rev-parse", "--verify", `refs/heads/${trimmedBranch}`], {
244392
244432
  cwd: projectPath,
244393
244433
  encoding: "utf-8",
244394
244434
  stdio: ["pipe", "pipe", "pipe"]
@@ -244407,7 +244447,7 @@ var routes8 = async (fastify2) => {
244407
244447
  });
244408
244448
  pendingCheckoutId = pending.checkout.id;
244409
244449
  await mkdir4(getWorktreeBaseForProject(projectPath), { recursive: true });
244410
- execFileSync7("git", ["worktree", "add", "-b", trimmedBranch, worktreeAbsolutePath, startPoint], {
244450
+ execFileSync8("git", ["worktree", "add", "-b", trimmedBranch, worktreeAbsolutePath, startPoint], {
244411
244451
  cwd: projectPath,
244412
244452
  encoding: "utf-8",
244413
244453
  stdio: ["pipe", "pipe", "pipe"]
@@ -244443,7 +244483,7 @@ var routes8 = async (fastify2) => {
244443
244483
  }
244444
244484
  let worktreeRemoved = false;
244445
244485
  try {
244446
- const { execSync: execSync2, execFileSync: execFileSync7 } = await import("child_process");
244486
+ const { execSync: execSync2, execFileSync: execFileSync8 } = await import("child_process");
244447
244487
  const worktreeAbsPath = resolveWorktreePath(projectPath, branch);
244448
244488
  try {
244449
244489
  const statusOutput = execSync2("git status --porcelain", {
@@ -244473,7 +244513,7 @@ var routes8 = async (fastify2) => {
244473
244513
  if (match2) branchToDelete = match2.branch;
244474
244514
  } catch {
244475
244515
  }
244476
- execFileSync7("git", ["worktree", "remove", worktreeAbsPath], {
244516
+ execFileSync8("git", ["worktree", "remove", worktreeAbsPath], {
244477
244517
  cwd: projectPath,
244478
244518
  encoding: "utf-8",
244479
244519
  stdio: ["pipe", "pipe", "pipe"]
@@ -244482,7 +244522,7 @@ var routes8 = async (fastify2) => {
244482
244522
  invalidateWorktreeListCache(projectPath);
244483
244523
  if (branchToDelete) {
244484
244524
  try {
244485
- execFileSync7("git", ["branch", "-d", branchToDelete], {
244525
+ execFileSync8("git", ["branch", "-d", branchToDelete], {
244486
244526
  cwd: projectPath,
244487
244527
  encoding: "utf-8",
244488
244528
  stdio: ["pipe", "pipe", "pipe"]
@@ -244524,6 +244564,24 @@ var routes8 = async (fastify2) => {
244524
244564
  return reply.code(500).send({ error: `Failed to anchor workspace: ${errorMessage}` });
244525
244565
  }
244526
244566
  });
244567
+ fastify2.post("/api/path/worktrees/anchor-branch", async (req, reply) => {
244568
+ const { path: projectPath, branch } = req.body ?? {};
244569
+ if (!projectPath || !branch) {
244570
+ return reply.code(400).send({ error: "Path and branch are required" });
244571
+ }
244572
+ try {
244573
+ const project = await ensurePathProject(fastify2, projectPath);
244574
+ const result = await setRootWorkspaceAnchor(fastify2.storage, project.id, projectPath, branch);
244575
+ if (!result.anchored) {
244576
+ const failure = anchorFailure(result.reason, branch);
244577
+ return reply.code(failure.code).send({ error: failure.error });
244578
+ }
244579
+ return reply.code(200).send({ expectedBranch: result.expectedBranch });
244580
+ } catch (error48) {
244581
+ const errorMessage = error48 instanceof Error ? error48.message : "Unknown error";
244582
+ return reply.code(500).send({ error: `Failed to anchor workspace: ${errorMessage}` });
244583
+ }
244584
+ });
244527
244585
  fastify2.get("/api/projects/:id/worktrees", async (req, reply) => {
244528
244586
  const userId = requireUserFacingUserId(req, reply);
244529
244587
  if (userId === null) return;
@@ -244624,6 +244682,54 @@ var routes8 = async (fastify2) => {
244624
244682
  return reply.code(500).send({ error: `Failed to anchor workspace: ${errorMessage}` });
244625
244683
  }
244626
244684
  });
244685
+ fastify2.post("/api/projects/:id/worktrees/anchor-branch", async (req, reply) => {
244686
+ const userId = requireUserFacingUserId(req, reply);
244687
+ if (userId === null) return;
244688
+ const project = await fastify2.storage.projects.getById(req.params.id, userId);
244689
+ if (!project) {
244690
+ return reply.code(404).send({ error: "Project not found" });
244691
+ }
244692
+ const branch = req.body?.branch;
244693
+ if (!branch) return reply.code(400).send({ error: "Branch is required" });
244694
+ const requestedTarget = req.body.target ?? "local";
244695
+ let remoteConfig;
244696
+ if (requestedTarget === "local") {
244697
+ remoteConfig = project.path ? null : await getRemoteConfig(fastify2, project);
244698
+ } else {
244699
+ const targetRemote = await fastify2.storage.projectRemotes.getByProjectAndServer(project.id, requestedTarget);
244700
+ if (!targetRemote) return reply.code(400).send({ error: "Unknown remote target" });
244701
+ remoteConfig = { serverId: targetRemote.remote_server_id, remotePath: targetRemote.remote_path };
244702
+ }
244703
+ if (remoteConfig) {
244704
+ const result = await proxyToRemoteAuto(
244705
+ remoteConfig.serverId,
244706
+ "POST",
244707
+ "/api/path/worktrees/anchor-branch",
244708
+ { path: remoteConfig.remotePath, branch },
244709
+ { reverseConnectManager: fastify2.reverseConnectManager }
244710
+ );
244711
+ if (result.status === 404) {
244712
+ return reply.code(501).send({
244713
+ error: "This remote worker is too old to change a workspace branch. Update it and try again."
244714
+ });
244715
+ }
244716
+ return reply.code(proxyStatus(result)).send(result.data);
244717
+ }
244718
+ if (!project.path) {
244719
+ return reply.code(400).send({ error: "Project has no local path" });
244720
+ }
244721
+ try {
244722
+ const result = await setRootWorkspaceAnchor(fastify2.storage, project.id, project.path, branch);
244723
+ if (!result.anchored) {
244724
+ const failure = anchorFailure(result.reason, branch);
244725
+ return reply.code(failure.code).send({ error: failure.error });
244726
+ }
244727
+ return reply.code(200).send({ expectedBranch: result.expectedBranch });
244728
+ } catch (error48) {
244729
+ const errorMessage = error48 instanceof Error ? error48.message : "Unknown error";
244730
+ return reply.code(500).send({ error: `Failed to anchor workspace: ${errorMessage}` });
244731
+ }
244732
+ });
244627
244733
  fastify2.get("/api/projects/:id/branches", async (req, reply) => {
244628
244734
  const userId = requireUserFacingUserId(req, reply);
244629
244735
  if (userId === null) return;
@@ -244760,7 +244866,7 @@ var routes8 = async (fastify2) => {
244760
244866
  return reply.code(400).send({ error: "Project has no local path" });
244761
244867
  }
244762
244868
  const deleteLocal = async () => {
244763
- const { execSync: execSync2, execFileSync: execFileSync7 } = await import("child_process");
244869
+ const { execSync: execSync2, execFileSync: execFileSync8 } = await import("child_process");
244764
244870
  const worktreeAbsPath = resolveWorktreePath(project.path, branch);
244765
244871
  const registered = await fastify2.storage.workspaceRegistry.getByProjectBranch(project.id, branch, "local");
244766
244872
  if (registered) {
@@ -244792,7 +244898,7 @@ var routes8 = async (fastify2) => {
244792
244898
  if (match2) branchToDelete = match2.branch;
244793
244899
  } catch {
244794
244900
  }
244795
- execFileSync7("git", ["worktree", "remove", worktreeAbsPath], {
244901
+ execFileSync8("git", ["worktree", "remove", worktreeAbsPath], {
244796
244902
  cwd: project.path,
244797
244903
  encoding: "utf-8",
244798
244904
  stdio: ["pipe", "pipe", "pipe"]
@@ -244801,7 +244907,7 @@ var routes8 = async (fastify2) => {
244801
244907
  invalidateWorktreeListCache(project.path);
244802
244908
  if (branchToDelete) {
244803
244909
  try {
244804
- execFileSync7("git", ["branch", "-d", branchToDelete], {
244910
+ execFileSync8("git", ["branch", "-d", branchToDelete], {
244805
244911
  cwd: project.path,
244806
244912
  encoding: "utf-8",
244807
244913
  stdio: ["pipe", "pipe", "pipe"]
@@ -244996,9 +245102,9 @@ var routes8 = async (fastify2) => {
244996
245102
  return reply.code(201).send({ worktree: { branch: trimmedBranch }, results: results2 });
244997
245103
  }
244998
245104
  const createLocal = async () => {
244999
- const { execFileSync: execFileSync7 } = await import("child_process");
245105
+ const { execFileSync: execFileSync8 } = await import("child_process");
245000
245106
  try {
245001
- execFileSync7("git", ["rev-parse", "--verify", `refs/heads/${trimmedBranch}`], {
245107
+ execFileSync8("git", ["rev-parse", "--verify", `refs/heads/${trimmedBranch}`], {
245002
245108
  cwd: project.path,
245003
245109
  encoding: "utf-8",
245004
245110
  stdio: ["pipe", "pipe", "pipe"]
@@ -245017,7 +245123,7 @@ var routes8 = async (fastify2) => {
245017
245123
  });
245018
245124
  try {
245019
245125
  await mkdir4(getWorktreeBaseForProject(project.path), { recursive: true });
245020
- execFileSync7("git", ["worktree", "add", "-b", trimmedBranch, worktreeAbsolutePath, localStartPoint], {
245126
+ execFileSync8("git", ["worktree", "add", "-b", trimmedBranch, worktreeAbsolutePath, localStartPoint], {
245021
245127
  cwd: project.path,
245022
245128
  encoding: "utf-8",
245023
245129
  stdio: ["pipe", "pipe", "pipe"]
@@ -245096,7 +245202,7 @@ var worktree_routes_default = (0, import_fastify_plugin9.default)(routes8, { nam
245096
245202
  var import_fastify_plugin10 = __toESM(require_plugin2(), 1);
245097
245203
  import path12 from "path";
245098
245204
  import { readFileSync as readFileSync4 } from "fs";
245099
- import { execFileSync as execFileSync5 } from "child_process";
245205
+ import { execFileSync as execFileSync6 } from "child_process";
245100
245206
 
245101
245207
  // src/utils/diff-parser.ts
245102
245208
  function parseDiffOutput(diffOutput) {
@@ -245189,10 +245295,10 @@ function parseDiffOutput(diffOutput) {
245189
245295
  }
245190
245296
 
245191
245297
  // src/merge-status.ts
245192
- import { execFileSync as execFileSync4 } from "child_process";
245298
+ import { execFileSync as execFileSync5 } from "child_process";
245193
245299
  var MAX_BUFFER3 = 10 * 1024 * 1024;
245194
245300
  function git3(cwd, args) {
245195
- return execFileSync4("git", args, {
245301
+ return execFileSync5("git", args, {
245196
245302
  cwd,
245197
245303
  encoding: "utf-8",
245198
245304
  maxBuffer: MAX_BUFFER3,
@@ -245345,7 +245451,7 @@ function buildDiffFallbackCommand(commit) {
245345
245451
  return `git show ${commit} --format="" --no-color`;
245346
245452
  }
245347
245453
  function runCompareToDiff(cwd, compareTo) {
245348
- return execFileSync5("git", ["diff", `${compareTo}...HEAD`, "--no-color"], {
245454
+ return execFileSync6("git", ["diff", `${compareTo}...HEAD`, "--no-color"], {
245349
245455
  cwd,
245350
245456
  encoding: "utf-8",
245351
245457
  maxBuffer: 10 * 1024 * 1024
@@ -253275,7 +253381,16 @@ var routes32 = async (fastify2) => {
253275
253381
  source
253276
253382
  });
253277
253383
  await fastify2.scheduler.reschedule(schedule.id);
253278
- return reply.code(schedule.id === newId ? 201 : 200).send({ schedule });
253384
+ const created = schedule.id === newId;
253385
+ if (created) {
253386
+ fastify2.eventBus.emit({
253387
+ type: "schedule:changed",
253388
+ projectId: req.params.projectId,
253389
+ scheduleId: schedule.id,
253390
+ change: "created"
253391
+ });
253392
+ }
253393
+ return reply.code(created ? 201 : 200).send({ schedule });
253279
253394
  }
253280
253395
  );
253281
253396
  fastify2.put(
@@ -253320,6 +253435,12 @@ var routes32 = async (fastify2) => {
253320
253435
  target: b2.target
253321
253436
  });
253322
253437
  await fastify2.scheduler.reschedule(req.params.id);
253438
+ fastify2.eventBus.emit({
253439
+ type: "schedule:changed",
253440
+ projectId: existing.project_id,
253441
+ scheduleId: req.params.id,
253442
+ change: "updated"
253443
+ });
253323
253444
  return reply.code(200).send({ schedule });
253324
253445
  }
253325
253446
  );
@@ -253332,6 +253453,12 @@ var routes32 = async (fastify2) => {
253332
253453
  if (!existing) return;
253333
253454
  fastify2.scheduler.unschedule(req.params.id);
253334
253455
  await fastify2.storage.scheduledTasks.delete(req.params.id);
253456
+ fastify2.eventBus.emit({
253457
+ type: "schedule:changed",
253458
+ projectId: existing.project_id,
253459
+ scheduleId: req.params.id,
253460
+ change: "deleted"
253461
+ });
253335
253462
  return reply.code(204).send();
253336
253463
  }
253337
253464
  );
@@ -254461,6 +254588,10 @@ var WORKER_CAPABILITIES = {
254461
254588
  // Additive: a worker below 0.3.13 404s it and the hub answers 501 with an
254462
254589
  // "update the worker" message instead of proxying the failure through.
254463
254590
  "http:POST /api/path/worktrees/anchor": { since: "0.3.13", summary: "\u91CD\u951A\u4E3B\u5DE5\u4F5C\u533A\u5206\u652F" },
254591
+ // Additive: a worker below 0.3.21 404s it and the hub answers 501 with an
254592
+ // "update the worker" message. Deliberately not folded into /anchor, whose
254593
+ // live-branch guard would reject the very case this serves.
254594
+ "http:POST /api/path/worktrees/anchor-branch": { since: "0.3.21", summary: "\u6539\u4E3B\u5DE5\u4F5C\u533A\u951A\u70B9\u5230\u6307\u5B9A\u5206\u652F" },
254464
254595
  "http:GET /api/path/branches": { since: "0.2.0", summary: "\u5206\u652F\u5217\u8868" },
254465
254596
  "http:GET /api/path/branches/activity": { since: "0.2.0", summary: "\u5206\u652F\u6D3B\u52A8\u6982\u89C8" },
254466
254597
  "http:POST /api/path/branches/merge-status": { since: "0.2.0", summary: "\u5206\u652F\u5408\u5E76\u72B6\u6001\u68C0\u6D4B" },
@@ -255858,7 +255989,7 @@ async function defaultBrowserId() {
255858
255989
  // ../../node_modules/.pnpm/run-applescript@7.1.0/node_modules/run-applescript/index.js
255859
255990
  import process6 from "node:process";
255860
255991
  import { promisify as promisify5 } from "node:util";
255861
- import { execFile as execFile4, execFileSync as execFileSync6 } from "node:child_process";
255992
+ import { execFile as execFile4, execFileSync as execFileSync7 } from "node:child_process";
255862
255993
  var execFileAsync4 = promisify5(execFile4);
255863
255994
  async function runAppleScript(script, { humanReadableOutput = true, signal } = {}) {
255864
255995
  if (process6.platform !== "darwin") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibedeckx/linux-x64",
3
- "version": "0.3.20",
3
+ "version": "0.3.21",
4
4
  "description": "Vibedeckx platform binaries for Linux x64",
5
5
  "os": [
6
6
  "linux"