@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.
- package/dist/bin.js +278 -26
- 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
|
|
226112
|
-
|
|
226113
|
-
|
|
226114
|
-
|
|
226115
|
-
|
|
226116
|
-
|
|
226117
|
-
|
|
226118
|
-
|
|
226119
|
-
|
|
226120
|
-
|
|
226121
|
-
|
|
226122
|
-
|
|
226123
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|