@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.
- package/dist/bin.js +192 -61
- 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
|
|
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"
|
|
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
|
|
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
|
-
|
|
205530
|
-
if (prompt
|
|
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,
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
*
|
|
239714
|
+
* Handle a user message sent directly to a review participant.
|
|
239665
239715
|
*
|
|
239666
|
-
* Reviewer 分流:向 reviewer
|
|
239667
|
-
*
|
|
239668
|
-
*
|
|
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
|
|
239674
|
-
* caught and swallowed
|
|
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
|
-
|
|
239687
|
-
|
|
239688
|
-
|
|
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:
|
|
244429
|
+
const { execFileSync: execFileSync8 } = await import("child_process");
|
|
244390
244430
|
try {
|
|
244391
|
-
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
245105
|
+
const { execFileSync: execFileSync8 } = await import("child_process");
|
|
245000
245106
|
try {
|
|
245001
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
245298
|
+
import { execFileSync as execFileSync5 } from "child_process";
|
|
245193
245299
|
var MAX_BUFFER3 = 10 * 1024 * 1024;
|
|
245194
245300
|
function git3(cwd, args) {
|
|
245195
|
-
return
|
|
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
|
|
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
|
-
|
|
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
|
|
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") {
|