@vibedeckx/linux-x64 0.2.4 → 0.2.5

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 +227 -23
  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
@@ -224576,7 +224586,9 @@ var AgentSessionManager = class {
224576
224586
  cost_usd: payload.cost_usd,
224577
224587
  input_tokens: payload.input_tokens,
224578
224588
  output_tokens: payload.output_tokens,
224579
- summaryText
224589
+ summaryText,
224590
+ turnEndEntryIndex: turnEndEntryIndex ?? void 0,
224591
+ workflowSuppressed: this.workflowSuppressionCheck?.(sessionId) || void 0
224580
224592
  }
224581
224593
  });
224582
224594
  this.eventBus?.emit({
@@ -225067,6 +225079,14 @@ ${details}`;
225067
225079
  getRawMessages(sessionId) {
225068
225080
  return this.sessions.get(sessionId)?.store.entries ?? [];
225069
225081
  }
225082
+ /**
225083
+ * Public wrapper over broadcastRaw for the WorkflowEngine: mirror a raw WS
225084
+ * frame to a session's stream subscribers (a front server subscribed to
225085
+ * this stream relies on it for run-transition delivery — spec §Phase 1.5).
225086
+ */
225087
+ broadcastRawToSession(sessionId, payload) {
225088
+ this.broadcastRaw(sessionId, payload);
225089
+ }
225070
225090
  /**
225071
225091
  * Get session info
225072
225092
  */
@@ -225966,6 +225986,40 @@ function statusEventFromRemotePatch(parsed, sessionId, remoteInfo) {
225966
225986
  status: content
225967
225987
  };
225968
225988
  }
225989
+ function taskCompletedEventFromRemoteFrame(parsed, sessionId, remoteInfo) {
225990
+ if (!("taskCompleted" in parsed)) return null;
225991
+ const tc = parsed.taskCompleted;
225992
+ return {
225993
+ type: "session:taskCompleted",
225994
+ projectId: projectIdFromRemoteSessionId(sessionId, remoteInfo),
225995
+ branch: remoteInfo.branch ?? null,
225996
+ sessionId,
225997
+ duration_ms: tc?.duration_ms,
225998
+ cost_usd: tc?.cost_usd,
225999
+ input_tokens: tc?.input_tokens,
226000
+ output_tokens: tc?.output_tokens,
226001
+ summaryText: tc?.summaryText,
226002
+ turnEndEntryIndex: tc?.turnEndEntryIndex,
226003
+ workflowSuppressed: tc?.workflowSuppressed === true ? true : void 0
226004
+ };
226005
+ }
226006
+ function mapRemoteRun(run2, remoteServerId, projectId) {
226007
+ const prefix = `remote-${remoteServerId}-${projectId}-`;
226008
+ return {
226009
+ ...run2,
226010
+ id: `${prefix}${run2.id}`,
226011
+ project_id: projectId,
226012
+ source_session_id: `${prefix}${run2.source_session_id}`,
226013
+ reviewer_session_id: run2.reviewer_session_id ? `${prefix}${run2.reviewer_session_id}` : null
226014
+ };
226015
+ }
226016
+ function runUpdatedEventFromRemoteFrame(parsed, sessionId, remoteInfo) {
226017
+ if (!("workflowRunUpdated" in parsed)) return null;
226018
+ const bare = parsed.workflowRunUpdated;
226019
+ const projectId = projectIdFromRemoteSessionId(sessionId, remoteInfo);
226020
+ const run2 = mapRemoteRun(bare, remoteInfo.remoteServerId, projectId);
226021
+ return { type: "workflow:run-updated", projectId, branch: run2.branch, run: run2 };
226022
+ }
225969
226023
 
225970
226024
  // src/remote-agent-sessions.ts
225971
226025
  async function createRemoteAgentSession(deps, params) {
@@ -226079,7 +226133,7 @@ function connectPersistentRemoteWs(sessionId, remoteInfo, cache2, wsOptions, rev
226079
226133
  const raw = data.toString();
226080
226134
  const parsed = tryParseWsMessage(raw);
226081
226135
  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";
226136
+ 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
226137
  if (kind === "JsonPatch") {
226084
226138
  const ops = parsed.JsonPatch;
226085
226139
  const statusOp = ops.find((o) => o.path === "/status");
@@ -226108,25 +226162,20 @@ function connectPersistentRemoteWs(sessionId, remoteInfo, cache2, wsOptions, rev
226108
226162
  cache2.appendMessage(sessionId, raw, false);
226109
226163
  cache2.broadcast(sessionId, raw);
226110
226164
  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
- );
226165
+ const evt = taskCompletedEventFromRemoteFrame(parsed, sessionId, remoteInfo);
226166
+ if (evt) {
226167
+ eventBus.emit(evt);
226168
+ agentSessionManager?.emitBranchActivityIfChanged(evt.projectId, evt.branch, {
226169
+ activity: "completed",
226170
+ since: Date.now(),
226171
+ sessionId
226172
+ });
226173
+ }
226174
+ }
226175
+ } else if ("workflowRunUpdated" in parsed) {
226176
+ if (eventBus) {
226177
+ const evt = runUpdatedEventFromRemoteFrame(parsed, sessionId, remoteInfo);
226178
+ if (evt) eventBus.emit(evt);
226130
226179
  }
226131
226180
  } else if ("processAlive" in parsed) {
226132
226181
  cache2.broadcast(sessionId, raw);
@@ -226497,7 +226546,7 @@ var ChatSessionManager = class {
226497
226546
  }
226498
226547
  handleSessionTaskCompleted(event) {
226499
226548
  try {
226500
- if (this.workflowEngine?.shouldSuppressAgentEvent(event.sessionId)) return;
226549
+ if (event.workflowSuppressed || this.workflowEngine?.shouldSuppressAgentEvent(event.sessionId)) return;
226501
226550
  const key = `${event.projectId}:${event.branch ?? ""}`;
226502
226551
  console.log(`[ChatSession] handleSessionTaskCompleted: key=${key}, sessionIndex keys=[${[...this.sessionIndex.keys()].join(", ")}]`);
226503
226552
  const sessionId = this.sessionIndex.get(key);
@@ -228930,6 +228979,9 @@ var WorkflowEngine = class {
228930
228979
  }
228931
228980
  emitRunUpdated(run2) {
228932
228981
  this.eventBus?.emit({ type: "workflow:run-updated", projectId: run2.project_id, branch: run2.branch, run: run2 });
228982
+ for (const sid of [run2.source_session_id, run2.reviewer_session_id]) {
228983
+ if (sid) this.agentOps.broadcastRawToSession?.(sid, { workflowRunUpdated: run2 });
228984
+ }
228933
228985
  }
228934
228986
  };
228935
228987
 
@@ -230833,6 +230885,7 @@ var sharedServices = async (fastify2, opts) => {
230833
230885
  await workflowEngine.init();
230834
230886
  fastify2.decorate("workflowEngine", workflowEngine);
230835
230887
  chatSessionManager.setWorkflowEngine(workflowEngine);
230888
+ agentSessionManager.setWorkflowSuppressionCheck((sessionId) => workflowEngine.shouldSuppressAgentEvent(sessionId));
230836
230889
  chatSessionManager.setEventBus(eventBus);
230837
230890
  chatSessionManager.setRemoteExecutorMonitor(remoteExecutorMonitor);
230838
230891
  processManager.setEventBus(eventBus);
@@ -235857,12 +235910,78 @@ function errStatus(err) {
235857
235910
  }
235858
235911
  }
235859
235912
  async function routes18(fastify2) {
235913
+ const remoteRunMap = /* @__PURE__ */ new Map();
235914
+ const TERMINAL_RUN_STATUSES = /* @__PURE__ */ new Set(["completed", "cancelled", "failed"]);
235915
+ const trackRemoteRun = (localRun, info) => {
235916
+ if (TERMINAL_RUN_STATUSES.has(localRun.status)) remoteRunMap.delete(localRun.id);
235917
+ else remoteRunMap.set(localRun.id, info);
235918
+ };
235919
+ const proxyAuto = (info, method, apiPath, body) => proxyToRemoteAuto(info.remoteServerId, info.remoteUrl, info.remoteApiKey, method, apiPath, body, {
235920
+ reverseConnectManager: fastify2.reverseConnectManager
235921
+ });
235922
+ const sendProxyFailure = (reply, result) => reply.code(proxyStatus(result)).send(
235923
+ result.status === 0 ? { error: `Remote proxy failed: ${result.errorCode || "unknown"}` } : result.data
235924
+ );
235925
+ const resolveRemoteRun = async (runId, userId) => {
235926
+ const info = remoteRunMap.get(runId);
235927
+ if (!info) return null;
235928
+ const project = await fastify2.storage.projects.getById(info.projectId, userId);
235929
+ if (!project) return null;
235930
+ return info;
235931
+ };
235860
235932
  fastify2.post("/api/workflow-runs", async (req, reply) => {
235861
235933
  const userId = requireAuth(req, reply);
235862
235934
  if (userId === null) return;
235863
235935
  const { projectId, branch, sourceSessionId, reviewFocus, sourceTurnEndIndex } = req.body ?? {};
235864
235936
  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" });
235937
+ if (sourceSessionId.startsWith("remote-")) {
235938
+ const remoteInfo = fastify2.remoteSessionMap.get(sourceSessionId);
235939
+ if (!remoteInfo) return reply.code(404).send({ error: "Session not found" });
235940
+ const derivedProjectId = projectIdFromRemoteSessionId(sourceSessionId, remoteInfo);
235941
+ if (derivedProjectId !== projectId) return reply.code(404).send({ error: "Session not found" });
235942
+ const remoteProject = await fastify2.storage.projects.getById(projectId, userId);
235943
+ if (!remoteProject) return reply.code(404).send({ error: "Project not found" });
235944
+ const result = await proxyAuto(remoteInfo, "POST", "/api/path/workflow-runs", {
235945
+ sourceSessionId: remoteInfo.remoteSessionId,
235946
+ reviewFocus,
235947
+ sourceTurnEndIndex
235948
+ });
235949
+ if (!result.ok) return sendProxyFailure(reply, result);
235950
+ const bareRun = result.data.run;
235951
+ const localRun = mapRemoteRun(bareRun, remoteInfo.remoteServerId, projectId);
235952
+ trackRemoteRun(localRun, {
235953
+ remoteServerId: remoteInfo.remoteServerId,
235954
+ remoteUrl: remoteInfo.remoteUrl,
235955
+ remoteApiKey: remoteInfo.remoteApiKey,
235956
+ bareRunId: bareRun.id,
235957
+ projectId
235958
+ });
235959
+ if (bareRun.reviewer_session_id && localRun.reviewer_session_id) {
235960
+ fastify2.remoteSessionMap.set(localRun.reviewer_session_id, {
235961
+ remoteServerId: remoteInfo.remoteServerId,
235962
+ remoteUrl: remoteInfo.remoteUrl,
235963
+ remoteApiKey: remoteInfo.remoteApiKey,
235964
+ remoteSessionId: bareRun.reviewer_session_id,
235965
+ branch: bareRun.branch
235966
+ });
235967
+ await fastify2.storage.remoteSessionMappings.upsert(
235968
+ localRun.reviewer_session_id,
235969
+ projectId,
235970
+ remoteInfo.remoteServerId,
235971
+ bareRun.reviewer_session_id,
235972
+ bareRun.branch
235973
+ );
235974
+ ensureRemoteAgentStream(localRun.reviewer_session_id, {
235975
+ remoteSessionMap: fastify2.remoteSessionMap,
235976
+ remotePatchCache: fastify2.remotePatchCache,
235977
+ reverseConnectManager: fastify2.reverseConnectManager,
235978
+ eventBus: fastify2.eventBus,
235979
+ agentSessionManager: fastify2.agentSessionManager
235980
+ });
235981
+ }
235982
+ fastify2.eventBus.emit({ type: "workflow:run-updated", projectId, branch: bareRun.branch, run: localRun });
235983
+ return reply.code(201).send({ run: localRun });
235984
+ }
235866
235985
  const project = await fastify2.storage.projects.getById(projectId, userId);
235867
235986
  if (!project) return reply.code(404).send({ error: "Project not found" });
235868
235987
  if (!project.path) return reply.code(400).send({ error: "Project has no local path (remote-only projects are not supported yet)" });
@@ -235898,6 +236017,27 @@ async function routes18(fastify2) {
235898
236017
  if (!projectId) return reply.code(400).send({ error: "projectId is required" });
235899
236018
  const project = await fastify2.storage.projects.getById(projectId, userId);
235900
236019
  if (!project) return reply.code(404).send({ error: "Project not found" });
236020
+ if (project.agent_mode && project.agent_mode !== "local") {
236021
+ const remoteConfig = await fastify2.storage.projectRemotes.getByProjectAndServer(projectId, project.agent_mode);
236022
+ if (remoteConfig) {
236023
+ const q = new URLSearchParams({ path: remoteConfig.remote_path ?? "" });
236024
+ if (branch) q.set("branch", branch);
236025
+ const info = {
236026
+ remoteServerId: project.agent_mode,
236027
+ remoteUrl: remoteConfig.server_url ?? "",
236028
+ remoteApiKey: remoteConfig.server_api_key || ""
236029
+ };
236030
+ const result = await proxyAuto(info, "GET", `/api/path/workflow-runs?${q}`);
236031
+ if (!result.ok) return sendProxyFailure(reply, result);
236032
+ const bareRuns = result.data.runs ?? [];
236033
+ const runs2 = bareRuns.map((r) => {
236034
+ const mapped = mapRemoteRun(r, info.remoteServerId, projectId);
236035
+ trackRemoteRun(mapped, { ...info, bareRunId: r.id, projectId });
236036
+ return mapped;
236037
+ });
236038
+ return reply.send({ runs: runs2 });
236039
+ }
236040
+ }
235901
236041
  const runs = await fastify2.storage.workflowRuns.getActive(projectId, branch ?? null);
235902
236042
  return reply.send({ runs });
235903
236043
  }
@@ -235905,6 +236045,15 @@ async function routes18(fastify2) {
235905
236045
  fastify2.get("/api/workflow-runs/:id", async (req, reply) => {
235906
236046
  const userId = requireAuth(req, reply);
235907
236047
  if (userId === null) return;
236048
+ if (req.params.id.startsWith("remote-")) {
236049
+ const info = await resolveRemoteRun(req.params.id, userId);
236050
+ if (!info) return reply.code(404).send({ error: "Run not found" });
236051
+ const result = await proxyAuto(info, "GET", `/api/workflow-runs/${info.bareRunId}`);
236052
+ if (!result.ok) return sendProxyFailure(reply, result);
236053
+ const localRun = mapRemoteRun(result.data.run, info.remoteServerId, info.projectId);
236054
+ trackRemoteRun(localRun, info);
236055
+ return reply.send({ run: localRun });
236056
+ }
235908
236057
  const run2 = await fastify2.storage.workflowRuns.getById(req.params.id);
235909
236058
  if (!run2) return reply.code(404).send({ error: "Run not found" });
235910
236059
  const project = await fastify2.storage.projects.getById(run2.project_id, userId);
@@ -235916,6 +236065,16 @@ async function routes18(fastify2) {
235916
236065
  async (req, reply) => {
235917
236066
  const userId = requireAuth(req, reply);
235918
236067
  if (userId === null) return;
236068
+ if (req.params.id.startsWith("remote-")) {
236069
+ const info = await resolveRemoteRun(req.params.id, userId);
236070
+ if (!info) return reply.code(404).send({ error: "Run not found" });
236071
+ const result = await proxyAuto(info, "POST", `/api/workflow-runs/${info.bareRunId}/gate`, req.body ?? {});
236072
+ if (!result.ok) return sendProxyFailure(reply, result);
236073
+ const localRun = mapRemoteRun(result.data.run, info.remoteServerId, info.projectId);
236074
+ trackRemoteRun(localRun, info);
236075
+ fastify2.eventBus.emit({ type: "workflow:run-updated", projectId: info.projectId, branch: localRun.branch, run: localRun });
236076
+ return reply.send({ run: localRun });
236077
+ }
235919
236078
  const existing = await fastify2.storage.workflowRuns.getById(req.params.id);
235920
236079
  if (!existing) return reply.code(404).send({ error: "Run not found" });
235921
236080
  const project = await fastify2.storage.projects.getById(existing.project_id, userId);
@@ -235941,6 +236100,16 @@ async function routes18(fastify2) {
235941
236100
  fastify2.post("/api/workflow-runs/:id/cancel", async (req, reply) => {
235942
236101
  const userId = requireAuth(req, reply);
235943
236102
  if (userId === null) return;
236103
+ if (req.params.id.startsWith("remote-")) {
236104
+ const info = await resolveRemoteRun(req.params.id, userId);
236105
+ if (!info) return reply.code(404).send({ error: "Run not found" });
236106
+ const result = await proxyAuto(info, "POST", `/api/workflow-runs/${info.bareRunId}/cancel`);
236107
+ if (!result.ok) return sendProxyFailure(reply, result);
236108
+ const localRun = mapRemoteRun(result.data.run, info.remoteServerId, info.projectId);
236109
+ trackRemoteRun(localRun, info);
236110
+ fastify2.eventBus.emit({ type: "workflow:run-updated", projectId: info.projectId, branch: localRun.branch, run: localRun });
236111
+ return reply.send({ run: localRun });
236112
+ }
235944
236113
  const existing = await fastify2.storage.workflowRuns.getById(req.params.id);
235945
236114
  if (!existing) return reply.code(404).send({ error: "Run not found" });
235946
236115
  const project = await fastify2.storage.projects.getById(existing.project_id, userId);
@@ -235954,6 +236123,41 @@ async function routes18(fastify2) {
235954
236123
  throw err;
235955
236124
  }
235956
236125
  });
236126
+ fastify2.post("/api/path/workflow-runs", async (req, reply) => {
236127
+ const userId = requireAuth(req, reply);
236128
+ if (userId === null) return;
236129
+ const { sourceSessionId, reviewFocus, sourceTurnEndIndex } = req.body ?? {};
236130
+ if (!sourceSessionId) return reply.code(400).send({ error: "sourceSessionId is required" });
236131
+ const sourceSession = await fastify2.storage.agentSessions.getById(sourceSessionId);
236132
+ if (!sourceSession) return reply.code(404).send({ error: "Session not found" });
236133
+ const project = await fastify2.storage.projects.getById(sourceSession.project_id);
236134
+ if (!project) return reply.code(404).send({ error: "Session not found" });
236135
+ if (!project.path) return reply.code(400).send({ error: "Project has no local path" });
236136
+ try {
236137
+ const run2 = await fastify2.workflowEngine.startAdhocReview({
236138
+ project: { id: project.id, path: project.path },
236139
+ branch: sourceSession.branch || null,
236140
+ sourceSessionId,
236141
+ reviewFocus,
236142
+ sourceTurnEndIndex
236143
+ });
236144
+ return reply.code(201).send({ run: run2 });
236145
+ } catch (err) {
236146
+ const status = errStatus(err);
236147
+ if (status) return reply.code(status).send({ error: err.message });
236148
+ throw err;
236149
+ }
236150
+ });
236151
+ fastify2.get("/api/path/workflow-runs", async (req, reply) => {
236152
+ const userId = requireAuth(req, reply);
236153
+ if (userId === null) return;
236154
+ const { path: projectPath, branch } = req.query;
236155
+ if (!projectPath) return reply.code(400).send({ error: "path is required" });
236156
+ const project = await fastify2.storage.projects.getByPath(projectPath) ?? await fastify2.storage.projects.getById(`path:${projectPath}`);
236157
+ if (!project) return reply.send({ runs: [] });
236158
+ const runs = await fastify2.storage.workflowRuns.getActive(project.id, branch || null);
236159
+ return reply.send({ runs });
236160
+ });
235957
236161
  }
235958
236162
  var workflow_run_routes_default = (0, import_fastify_plugin19.default)(routes18, { name: "workflow-run-routes" });
235959
236163
 
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.5",
4
4
  "description": "Vibedeckx platform binaries for Linux x64",
5
5
  "os": [
6
6
  "linux"