@vibedeckx/linux-x64 0.2.4 → 0.2.6

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 +278 -26
  2. package/package.json +1 -1
package/dist/bin.js CHANGED
@@ -224066,6 +224066,7 @@ var AgentSessionManager = class {
224066
224066
  capacityQueue = Promise.resolve();
224067
224067
  /** Grace window before committing a held completion (injectable for tests). */
224068
224068
  completionGraceMs;
224069
+ workflowSuppressionCheck = null;
224069
224070
  constructor(storage, opts) {
224070
224071
  this.storage = storage;
224071
224072
  this.completionGraceMs = opts?.completionGraceMs ?? COMPLETION_GRACE_MS;
@@ -224073,6 +224074,15 @@ var AgentSessionManager = class {
224073
224074
  setEventBus(eventBus) {
224074
224075
  this.eventBus = eventBus;
224075
224076
  }
224077
+ /**
224078
+ * Injected by shared-services: lets commitCompletion mark taskCompleted WS
224079
+ * frames whose completion the local WorkflowEngine claims (reviewer
224080
+ * sessions of active runs). A front server bridging this frame must not
224081
+ * wake its commander for it (spec §Phase 1.5 抑制协调).
224082
+ */
224083
+ setWorkflowSuppressionCheck(check2) {
224084
+ this.workflowSuppressionCheck = check2;
224085
+ }
224076
224086
  /**
224077
224087
  * Broadcast a freshly-generated title on the global event bus so the sidebar
224078
224088
  * (`useResidentSessions`) updates regardless of which workspace is currently
@@ -224151,6 +224161,20 @@ var AgentSessionManager = class {
224151
224161
  this.titleResolved.add(sessionId);
224152
224162
  return true;
224153
224163
  }
224164
+ /**
224165
+ * Write a caller-determined final title and claim the one-shot slot so the
224166
+ * AI title generator never fires for this session — same pattern as the
224167
+ * Branch path's "Branch - <source title>". The slot is claimed before the
224168
+ * DB write: even if the write fails, a degraded placeholder title beats an
224169
+ * AI title racing in over the caller's intent.
224170
+ */
224171
+ async setFinalSessionTitle(sessionId, title) {
224172
+ this.markTitleResolved(sessionId);
224173
+ await this.storage.agentSessions.updateTitle(sessionId, title);
224174
+ this.broadcastRaw(sessionId, { titleUpdated: { title } });
224175
+ const session = this.sessions.get(sessionId);
224176
+ if (session) this.emitSessionTitle(session.projectId, session.branch, sessionId, title);
224177
+ }
224154
224178
  isProcessAlive(session) {
224155
224179
  return !!session.process && session.process.exitCode === null && !session.dormant;
224156
224180
  }
@@ -224576,7 +224600,9 @@ var AgentSessionManager = class {
224576
224600
  cost_usd: payload.cost_usd,
224577
224601
  input_tokens: payload.input_tokens,
224578
224602
  output_tokens: payload.output_tokens,
224579
- summaryText
224603
+ summaryText,
224604
+ turnEndEntryIndex: turnEndEntryIndex ?? void 0,
224605
+ workflowSuppressed: this.workflowSuppressionCheck?.(sessionId) || void 0
224580
224606
  }
224581
224607
  });
224582
224608
  this.eventBus?.emit({
@@ -225067,6 +225093,14 @@ ${details}`;
225067
225093
  getRawMessages(sessionId) {
225068
225094
  return this.sessions.get(sessionId)?.store.entries ?? [];
225069
225095
  }
225096
+ /**
225097
+ * Public wrapper over broadcastRaw for the WorkflowEngine: mirror a raw WS
225098
+ * frame to a session's stream subscribers (a front server subscribed to
225099
+ * this stream relies on it for run-transition delivery — spec §Phase 1.5).
225100
+ */
225101
+ broadcastRawToSession(sessionId, payload) {
225102
+ this.broadcastRaw(sessionId, payload);
225103
+ }
225070
225104
  /**
225071
225105
  * Get session info
225072
225106
  */
@@ -225966,6 +226000,40 @@ function statusEventFromRemotePatch(parsed, sessionId, remoteInfo) {
225966
226000
  status: content
225967
226001
  };
225968
226002
  }
226003
+ function taskCompletedEventFromRemoteFrame(parsed, sessionId, remoteInfo) {
226004
+ if (!("taskCompleted" in parsed)) return null;
226005
+ const tc = parsed.taskCompleted;
226006
+ return {
226007
+ type: "session:taskCompleted",
226008
+ projectId: projectIdFromRemoteSessionId(sessionId, remoteInfo),
226009
+ branch: remoteInfo.branch ?? null,
226010
+ sessionId,
226011
+ duration_ms: tc?.duration_ms,
226012
+ cost_usd: tc?.cost_usd,
226013
+ input_tokens: tc?.input_tokens,
226014
+ output_tokens: tc?.output_tokens,
226015
+ summaryText: tc?.summaryText,
226016
+ turnEndEntryIndex: tc?.turnEndEntryIndex,
226017
+ workflowSuppressed: tc?.workflowSuppressed === true ? true : void 0
226018
+ };
226019
+ }
226020
+ function mapRemoteRun(run2, remoteServerId, projectId) {
226021
+ const prefix = `remote-${remoteServerId}-${projectId}-`;
226022
+ return {
226023
+ ...run2,
226024
+ id: `${prefix}${run2.id}`,
226025
+ project_id: projectId,
226026
+ source_session_id: `${prefix}${run2.source_session_id}`,
226027
+ reviewer_session_id: run2.reviewer_session_id ? `${prefix}${run2.reviewer_session_id}` : null
226028
+ };
226029
+ }
226030
+ function runUpdatedEventFromRemoteFrame(parsed, sessionId, remoteInfo) {
226031
+ if (!("workflowRunUpdated" in parsed)) return null;
226032
+ const bare = parsed.workflowRunUpdated;
226033
+ const projectId = projectIdFromRemoteSessionId(sessionId, remoteInfo);
226034
+ const run2 = mapRemoteRun(bare, remoteInfo.remoteServerId, projectId);
226035
+ return { type: "workflow:run-updated", projectId, branch: run2.branch, run: run2 };
226036
+ }
225969
226037
 
225970
226038
  // src/remote-agent-sessions.ts
225971
226039
  async function createRemoteAgentSession(deps, params) {
@@ -226079,7 +226147,7 @@ function connectPersistentRemoteWs(sessionId, remoteInfo, cache2, wsOptions, rev
226079
226147
  const raw = data.toString();
226080
226148
  const parsed = tryParseWsMessage(raw);
226081
226149
  if (!parsed) return;
226082
- const kind = "JsonPatch" in parsed ? "JsonPatch" : "finished" in parsed ? "finished" : "taskCompleted" in parsed ? "taskCompleted" : "processAlive" in parsed ? "processAlive" : "branchActivity" in parsed ? "branchActivity" : "Ready" in parsed ? "Ready" : "error" in parsed ? "error" : "other";
226150
+ const kind = "JsonPatch" in parsed ? "JsonPatch" : "finished" in parsed ? "finished" : "taskCompleted" in parsed ? "taskCompleted" : "workflowRunUpdated" in parsed ? "workflowRunUpdated" : "processAlive" in parsed ? "processAlive" : "branchActivity" in parsed ? "branchActivity" : "Ready" in parsed ? "Ready" : "error" in parsed ? "error" : "other";
226083
226151
  if (kind === "JsonPatch") {
226084
226152
  const ops = parsed.JsonPatch;
226085
226153
  const statusOp = ops.find((o) => o.path === "/status");
@@ -226108,25 +226176,20 @@ function connectPersistentRemoteWs(sessionId, remoteInfo, cache2, wsOptions, rev
226108
226176
  cache2.appendMessage(sessionId, raw, false);
226109
226177
  cache2.broadcast(sessionId, raw);
226110
226178
  if (eventBus) {
226111
- const tc = parsed.taskCompleted;
226112
- const projectId = projectIdFromRemoteSessionId(sessionId, remoteInfo);
226113
- const branch = remoteInfo.branch ?? null;
226114
- eventBus.emit({
226115
- type: "session:taskCompleted",
226116
- projectId,
226117
- branch,
226118
- sessionId,
226119
- duration_ms: tc?.duration_ms,
226120
- cost_usd: tc?.cost_usd,
226121
- input_tokens: tc?.input_tokens,
226122
- output_tokens: tc?.output_tokens,
226123
- summaryText: tc?.summaryText
226124
- });
226125
- agentSessionManager?.emitBranchActivityIfChanged(
226126
- projectId,
226127
- branch,
226128
- { activity: "completed", since: Date.now(), sessionId }
226129
- );
226179
+ const evt = taskCompletedEventFromRemoteFrame(parsed, sessionId, remoteInfo);
226180
+ if (evt) {
226181
+ eventBus.emit(evt);
226182
+ agentSessionManager?.emitBranchActivityIfChanged(evt.projectId, evt.branch, {
226183
+ activity: "completed",
226184
+ since: Date.now(),
226185
+ sessionId
226186
+ });
226187
+ }
226188
+ }
226189
+ } else if ("workflowRunUpdated" in parsed) {
226190
+ if (eventBus) {
226191
+ const evt = runUpdatedEventFromRemoteFrame(parsed, sessionId, remoteInfo);
226192
+ if (evt) eventBus.emit(evt);
226130
226193
  }
226131
226194
  } else if ("processAlive" in parsed) {
226132
226195
  cache2.broadcast(sessionId, raw);
@@ -226497,7 +226560,7 @@ var ChatSessionManager = class {
226497
226560
  }
226498
226561
  handleSessionTaskCompleted(event) {
226499
226562
  try {
226500
- if (this.workflowEngine?.shouldSuppressAgentEvent(event.sessionId)) return;
226563
+ if (event.workflowSuppressed || this.workflowEngine?.shouldSuppressAgentEvent(event.sessionId)) return;
226501
226564
  const key = `${event.projectId}:${event.branch ?? ""}`;
226502
226565
  console.log(`[ChatSession] handleSessionTaskCompleted: key=${key}, sessionIndex keys=[${[...this.sessionIndex.keys()].join(", ")}]`);
226503
226566
  const sessionId = this.sessionIndex.get(key);
@@ -228783,11 +228846,16 @@ var WorkflowEngine = class {
228783
228846
  opts.project.path,
228784
228847
  false,
228785
228848
  "plan",
228786
- "claude-code",
228849
+ opts.reviewerAgentType ?? "claude-code",
228787
228850
  true
228788
228851
  );
228852
+ const taskContext = extractTaskContextBefore(entries, turnEndIndex);
228853
+ await this.agentOps.setFinalSessionTitle(
228854
+ reviewerId,
228855
+ `Review - ${sourceSession?.title || (taskContext ? snippetTitle(taskContext) : null) || "Conversation"}`
228856
+ ).catch((err) => console.warn(`[WorkflowEngine] failed to set reviewer title for ${reviewerId}:`, err));
228789
228857
  const prompt = buildReviewerPrompt({
228790
- taskContext: extractTaskContextBefore(entries, turnEndIndex),
228858
+ taskContext,
228791
228859
  reviewFocus: opts.reviewFocus ?? null,
228792
228860
  target
228793
228861
  });
@@ -228930,6 +228998,9 @@ var WorkflowEngine = class {
228930
228998
  }
228931
228999
  emitRunUpdated(run2) {
228932
229000
  this.eventBus?.emit({ type: "workflow:run-updated", projectId: run2.project_id, branch: run2.branch, run: run2 });
229001
+ for (const sid of [run2.source_session_id, run2.reviewer_session_id]) {
229002
+ if (sid) this.agentOps.broadcastRawToSession?.(sid, { workflowRunUpdated: run2 });
229003
+ }
228933
229004
  }
228934
229005
  };
228935
229006
 
@@ -230833,6 +230904,7 @@ var sharedServices = async (fastify2, opts) => {
230833
230904
  await workflowEngine.init();
230834
230905
  fastify2.decorate("workflowEngine", workflowEngine);
230835
230906
  chatSessionManager.setWorkflowEngine(workflowEngine);
230907
+ agentSessionManager.setWorkflowSuppressionCheck((sessionId) => workflowEngine.shouldSuppressAgentEvent(sessionId));
230836
230908
  chatSessionManager.setEventBus(eventBus);
230837
230909
  chatSessionManager.setRemoteExecutorMonitor(remoteExecutorMonitor);
230838
230910
  processManager.setEventBus(eventBus);
@@ -235837,6 +235909,11 @@ var command_routes_default = (0, import_fastify_plugin18.default)(routes17, { na
235837
235909
 
235838
235910
  // src/routes/workflow-run-routes.ts
235839
235911
  var import_fastify_plugin19 = __toESM(require_plugin2(), 1);
235912
+ var REVIEWER_AGENT_TYPES = /* @__PURE__ */ new Set(["claude-code", "codex"]);
235913
+ function parseReviewerAgentType(raw) {
235914
+ if (raw === void 0) return void 0;
235915
+ return typeof raw === "string" && REVIEWER_AGENT_TYPES.has(raw) ? raw : null;
235916
+ }
235840
235917
  function errStatus(err) {
235841
235918
  if (!(err instanceof WorkflowError)) return null;
235842
235919
  switch (err.code) {
@@ -235857,12 +235934,98 @@ function errStatus(err) {
235857
235934
  }
235858
235935
  }
235859
235936
  async function routes18(fastify2) {
235937
+ const remoteRunMap = /* @__PURE__ */ new Map();
235938
+ const TERMINAL_RUN_STATUSES = /* @__PURE__ */ new Set(["completed", "cancelled", "failed"]);
235939
+ const trackRemoteRun = (localRun, info) => {
235940
+ if (TERMINAL_RUN_STATUSES.has(localRun.status)) remoteRunMap.delete(localRun.id);
235941
+ else remoteRunMap.set(localRun.id, info);
235942
+ };
235943
+ const proxyAuto = (info, method, apiPath, body) => proxyToRemoteAuto(info.remoteServerId, info.remoteUrl, info.remoteApiKey, method, apiPath, body, {
235944
+ reverseConnectManager: fastify2.reverseConnectManager
235945
+ });
235946
+ const sendProxyFailure = (reply, result) => reply.code(proxyStatus(result)).send(
235947
+ result.status === 0 ? { error: `Remote proxy failed: ${result.errorCode || "unknown"}` } : result.data
235948
+ );
235949
+ const resolveRemoteRun = async (runId, userId) => {
235950
+ const info = remoteRunMap.get(runId);
235951
+ if (!info) return null;
235952
+ const project = await fastify2.storage.projects.getById(info.projectId, userId);
235953
+ if (!project) return null;
235954
+ return info;
235955
+ };
235860
235956
  fastify2.post("/api/workflow-runs", async (req, reply) => {
235861
235957
  const userId = requireAuth(req, reply);
235862
235958
  if (userId === null) return;
235863
235959
  const { projectId, branch, sourceSessionId, reviewFocus, sourceTurnEndIndex } = req.body ?? {};
235864
235960
  if (!projectId || !sourceSessionId) return reply.code(400).send({ error: "projectId and sourceSessionId are required" });
235865
- if (sourceSessionId.startsWith("remote-")) return reply.code(400).send({ error: "Remote sessions are not supported in ad-hoc review yet" });
235961
+ const reviewerAgentType = parseReviewerAgentType(req.body?.reviewerAgentType);
235962
+ if (reviewerAgentType === null) return reply.code(400).send({ error: "reviewerAgentType must be one of: claude-code, codex" });
235963
+ if (sourceSessionId.startsWith("remote-")) {
235964
+ const remoteInfo = fastify2.remoteSessionMap.get(sourceSessionId);
235965
+ if (!remoteInfo) return reply.code(404).send({ error: "Session not found" });
235966
+ const derivedProjectId = projectIdFromRemoteSessionId(sourceSessionId, remoteInfo);
235967
+ if (derivedProjectId !== projectId) return reply.code(404).send({ error: "Session not found" });
235968
+ const remoteProject = await fastify2.storage.projects.getById(projectId, userId);
235969
+ if (!remoteProject) return reply.code(404).send({ error: "Project not found" });
235970
+ const result = await proxyAuto(remoteInfo, "POST", "/api/path/workflow-runs", {
235971
+ sourceSessionId: remoteInfo.remoteSessionId,
235972
+ reviewFocus,
235973
+ sourceTurnEndIndex,
235974
+ reviewerAgentType
235975
+ });
235976
+ if (!result.ok) return sendProxyFailure(reply, result);
235977
+ const bareRun = result.data.run;
235978
+ const localRun = mapRemoteRun(bareRun, remoteInfo.remoteServerId, projectId);
235979
+ trackRemoteRun(localRun, {
235980
+ remoteServerId: remoteInfo.remoteServerId,
235981
+ remoteUrl: remoteInfo.remoteUrl,
235982
+ remoteApiKey: remoteInfo.remoteApiKey,
235983
+ bareRunId: bareRun.id,
235984
+ projectId
235985
+ });
235986
+ if (bareRun.reviewer_session_id && localRun.reviewer_session_id) {
235987
+ const reviewerInfo = {
235988
+ remoteServerId: remoteInfo.remoteServerId,
235989
+ remoteUrl: remoteInfo.remoteUrl,
235990
+ remoteApiKey: remoteInfo.remoteApiKey,
235991
+ remoteSessionId: bareRun.reviewer_session_id,
235992
+ branch: bareRun.branch
235993
+ };
235994
+ fastify2.remoteSessionMap.set(localRun.reviewer_session_id, reviewerInfo);
235995
+ await fastify2.storage.remoteSessionMappings.upsert(
235996
+ localRun.reviewer_session_id,
235997
+ projectId,
235998
+ remoteInfo.remoteServerId,
235999
+ bareRun.reviewer_session_id,
236000
+ bareRun.branch
236001
+ );
236002
+ ensureRemoteAgentStream(localRun.reviewer_session_id, {
236003
+ remoteSessionMap: fastify2.remoteSessionMap,
236004
+ remotePatchCache: fastify2.remotePatchCache,
236005
+ reverseConnectManager: fastify2.reverseConnectManager,
236006
+ eventBus: fastify2.eventBus,
236007
+ agentSessionManager: fastify2.agentSessionManager
236008
+ });
236009
+ fastify2.eventBus.emit({
236010
+ type: "session:process",
236011
+ projectId,
236012
+ branch: bareRun.branch,
236013
+ sessionId: localRun.reviewer_session_id,
236014
+ alive: true
236015
+ });
236016
+ fastify2.eventBus.emit({
236017
+ type: "session:status",
236018
+ projectId,
236019
+ branch: bareRun.branch,
236020
+ sessionId: localRun.reviewer_session_id,
236021
+ status: "running"
236022
+ });
236023
+ fastify2.agentSessionManager.markTitleResolved(localRun.reviewer_session_id);
236024
+ await fastify2.storage.remoteSessionMappings.markTitleResolved(localRun.reviewer_session_id);
236025
+ }
236026
+ fastify2.eventBus.emit({ type: "workflow:run-updated", projectId, branch: bareRun.branch, run: localRun });
236027
+ return reply.code(201).send({ run: localRun });
236028
+ }
235866
236029
  const project = await fastify2.storage.projects.getById(projectId, userId);
235867
236030
  if (!project) return reply.code(404).send({ error: "Project not found" });
235868
236031
  if (!project.path) return reply.code(400).send({ error: "Project has no local path (remote-only projects are not supported yet)" });
@@ -235880,7 +236043,8 @@ async function routes18(fastify2) {
235880
236043
  branch: runBranch,
235881
236044
  sourceSessionId,
235882
236045
  reviewFocus,
235883
- sourceTurnEndIndex
236046
+ sourceTurnEndIndex,
236047
+ reviewerAgentType
235884
236048
  });
235885
236049
  return reply.code(201).send({ run: run2 });
235886
236050
  } catch (err) {
@@ -235898,6 +236062,27 @@ async function routes18(fastify2) {
235898
236062
  if (!projectId) return reply.code(400).send({ error: "projectId is required" });
235899
236063
  const project = await fastify2.storage.projects.getById(projectId, userId);
235900
236064
  if (!project) return reply.code(404).send({ error: "Project not found" });
236065
+ if (project.agent_mode && project.agent_mode !== "local") {
236066
+ const remoteConfig = await fastify2.storage.projectRemotes.getByProjectAndServer(projectId, project.agent_mode);
236067
+ if (remoteConfig) {
236068
+ const q = new URLSearchParams({ path: remoteConfig.remote_path ?? "" });
236069
+ if (branch) q.set("branch", branch);
236070
+ const info = {
236071
+ remoteServerId: project.agent_mode,
236072
+ remoteUrl: remoteConfig.server_url ?? "",
236073
+ remoteApiKey: remoteConfig.server_api_key || ""
236074
+ };
236075
+ const result = await proxyAuto(info, "GET", `/api/path/workflow-runs?${q}`);
236076
+ if (!result.ok) return sendProxyFailure(reply, result);
236077
+ const bareRuns = result.data.runs ?? [];
236078
+ const runs2 = bareRuns.map((r) => {
236079
+ const mapped = mapRemoteRun(r, info.remoteServerId, projectId);
236080
+ trackRemoteRun(mapped, { ...info, bareRunId: r.id, projectId });
236081
+ return mapped;
236082
+ });
236083
+ return reply.send({ runs: runs2 });
236084
+ }
236085
+ }
235901
236086
  const runs = await fastify2.storage.workflowRuns.getActive(projectId, branch ?? null);
235902
236087
  return reply.send({ runs });
235903
236088
  }
@@ -235905,6 +236090,15 @@ async function routes18(fastify2) {
235905
236090
  fastify2.get("/api/workflow-runs/:id", async (req, reply) => {
235906
236091
  const userId = requireAuth(req, reply);
235907
236092
  if (userId === null) return;
236093
+ if (req.params.id.startsWith("remote-")) {
236094
+ const info = await resolveRemoteRun(req.params.id, userId);
236095
+ if (!info) return reply.code(404).send({ error: "Run not found" });
236096
+ const result = await proxyAuto(info, "GET", `/api/workflow-runs/${info.bareRunId}`);
236097
+ if (!result.ok) return sendProxyFailure(reply, result);
236098
+ const localRun = mapRemoteRun(result.data.run, info.remoteServerId, info.projectId);
236099
+ trackRemoteRun(localRun, info);
236100
+ return reply.send({ run: localRun });
236101
+ }
235908
236102
  const run2 = await fastify2.storage.workflowRuns.getById(req.params.id);
235909
236103
  if (!run2) return reply.code(404).send({ error: "Run not found" });
235910
236104
  const project = await fastify2.storage.projects.getById(run2.project_id, userId);
@@ -235916,6 +236110,16 @@ async function routes18(fastify2) {
235916
236110
  async (req, reply) => {
235917
236111
  const userId = requireAuth(req, reply);
235918
236112
  if (userId === null) return;
236113
+ if (req.params.id.startsWith("remote-")) {
236114
+ const info = await resolveRemoteRun(req.params.id, userId);
236115
+ if (!info) return reply.code(404).send({ error: "Run not found" });
236116
+ const result = await proxyAuto(info, "POST", `/api/workflow-runs/${info.bareRunId}/gate`, req.body ?? {});
236117
+ if (!result.ok) return sendProxyFailure(reply, result);
236118
+ const localRun = mapRemoteRun(result.data.run, info.remoteServerId, info.projectId);
236119
+ trackRemoteRun(localRun, info);
236120
+ fastify2.eventBus.emit({ type: "workflow:run-updated", projectId: info.projectId, branch: localRun.branch, run: localRun });
236121
+ return reply.send({ run: localRun });
236122
+ }
235919
236123
  const existing = await fastify2.storage.workflowRuns.getById(req.params.id);
235920
236124
  if (!existing) return reply.code(404).send({ error: "Run not found" });
235921
236125
  const project = await fastify2.storage.projects.getById(existing.project_id, userId);
@@ -235941,6 +236145,16 @@ async function routes18(fastify2) {
235941
236145
  fastify2.post("/api/workflow-runs/:id/cancel", async (req, reply) => {
235942
236146
  const userId = requireAuth(req, reply);
235943
236147
  if (userId === null) return;
236148
+ if (req.params.id.startsWith("remote-")) {
236149
+ const info = await resolveRemoteRun(req.params.id, userId);
236150
+ if (!info) return reply.code(404).send({ error: "Run not found" });
236151
+ const result = await proxyAuto(info, "POST", `/api/workflow-runs/${info.bareRunId}/cancel`);
236152
+ if (!result.ok) return sendProxyFailure(reply, result);
236153
+ const localRun = mapRemoteRun(result.data.run, info.remoteServerId, info.projectId);
236154
+ trackRemoteRun(localRun, info);
236155
+ fastify2.eventBus.emit({ type: "workflow:run-updated", projectId: info.projectId, branch: localRun.branch, run: localRun });
236156
+ return reply.send({ run: localRun });
236157
+ }
235944
236158
  const existing = await fastify2.storage.workflowRuns.getById(req.params.id);
235945
236159
  if (!existing) return reply.code(404).send({ error: "Run not found" });
235946
236160
  const project = await fastify2.storage.projects.getById(existing.project_id, userId);
@@ -235954,6 +236168,44 @@ async function routes18(fastify2) {
235954
236168
  throw err;
235955
236169
  }
235956
236170
  });
236171
+ fastify2.post("/api/path/workflow-runs", async (req, reply) => {
236172
+ const userId = requireAuth(req, reply);
236173
+ if (userId === null) return;
236174
+ const { sourceSessionId, reviewFocus, sourceTurnEndIndex } = req.body ?? {};
236175
+ if (!sourceSessionId) return reply.code(400).send({ error: "sourceSessionId is required" });
236176
+ const reviewerAgentType = parseReviewerAgentType(req.body?.reviewerAgentType);
236177
+ if (reviewerAgentType === null) return reply.code(400).send({ error: "reviewerAgentType must be one of: claude-code, codex" });
236178
+ const sourceSession = await fastify2.storage.agentSessions.getById(sourceSessionId);
236179
+ if (!sourceSession) return reply.code(404).send({ error: "Session not found" });
236180
+ const project = await fastify2.storage.projects.getById(sourceSession.project_id);
236181
+ if (!project) return reply.code(404).send({ error: "Session not found" });
236182
+ if (!project.path) return reply.code(400).send({ error: "Project has no local path" });
236183
+ try {
236184
+ const run2 = await fastify2.workflowEngine.startAdhocReview({
236185
+ project: { id: project.id, path: project.path },
236186
+ branch: sourceSession.branch || null,
236187
+ sourceSessionId,
236188
+ reviewFocus,
236189
+ sourceTurnEndIndex,
236190
+ reviewerAgentType
236191
+ });
236192
+ return reply.code(201).send({ run: run2 });
236193
+ } catch (err) {
236194
+ const status = errStatus(err);
236195
+ if (status) return reply.code(status).send({ error: err.message });
236196
+ throw err;
236197
+ }
236198
+ });
236199
+ fastify2.get("/api/path/workflow-runs", async (req, reply) => {
236200
+ const userId = requireAuth(req, reply);
236201
+ if (userId === null) return;
236202
+ const { path: projectPath, branch } = req.query;
236203
+ if (!projectPath) return reply.code(400).send({ error: "path is required" });
236204
+ const project = await fastify2.storage.projects.getByPath(projectPath) ?? await fastify2.storage.projects.getById(`path:${projectPath}`);
236205
+ if (!project) return reply.send({ runs: [] });
236206
+ const runs = await fastify2.storage.workflowRuns.getActive(project.id, branch || null);
236207
+ return reply.send({ runs });
236208
+ });
235957
236209
  }
235958
236210
  var workflow_run_routes_default = (0, import_fastify_plugin19.default)(routes18, { name: "workflow-run-routes" });
235959
236211
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibedeckx/linux-x64",
3
- "version": "0.2.4",
3
+ "version": "0.2.6",
4
4
  "description": "Vibedeckx platform binaries for Linux x64",
5
5
  "os": [
6
6
  "linux"