replicas-engine 0.1.173 → 0.1.175
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/src/index.js +223 -20
- package/package.json +1 -1
package/dist/src/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { serve } from "@hono/node-server";
|
|
|
5
5
|
import { Hono as Hono2 } from "hono";
|
|
6
6
|
import { readFile as readFile14 } from "fs/promises";
|
|
7
7
|
import { execSync as execSync2 } from "child_process";
|
|
8
|
-
import { randomUUID as
|
|
8
|
+
import { randomUUID as randomUUID6 } from "crypto";
|
|
9
9
|
|
|
10
10
|
// src/managers/github-token-manager.ts
|
|
11
11
|
import { promises as fs } from "fs";
|
|
@@ -375,7 +375,7 @@ function parseReplicasConfigString(content, filename) {
|
|
|
375
375
|
}
|
|
376
376
|
|
|
377
377
|
// ../shared/src/engine/environment.ts
|
|
378
|
-
var DAYTONA_SNAPSHOT_ID = "
|
|
378
|
+
var DAYTONA_SNAPSHOT_ID = "15-05-2026-royal-york-v20";
|
|
379
379
|
|
|
380
380
|
// ../shared/src/engine/types.ts
|
|
381
381
|
var DEFAULT_CHAT_TITLES = {
|
|
@@ -2077,12 +2077,13 @@ import { existsSync as existsSync7 } from "fs";
|
|
|
2077
2077
|
import { appendFile as appendFile5, mkdir as mkdir10, readFile as readFile8, rm, writeFile as writeFile8 } from "fs/promises";
|
|
2078
2078
|
import { homedir as homedir9 } from "os";
|
|
2079
2079
|
import { join as join12 } from "path";
|
|
2080
|
-
import { randomUUID as
|
|
2080
|
+
import { randomUUID as randomUUID5 } from "crypto";
|
|
2081
2081
|
|
|
2082
2082
|
// src/managers/claude-manager.ts
|
|
2083
2083
|
import {
|
|
2084
2084
|
query
|
|
2085
2085
|
} from "@anthropic-ai/claude-agent-sdk";
|
|
2086
|
+
import { randomUUID as randomUUID3 } from "crypto";
|
|
2086
2087
|
import { join as join10 } from "path";
|
|
2087
2088
|
import { mkdir as mkdir8, appendFile as appendFile4 } from "fs/promises";
|
|
2088
2089
|
import { homedir as homedir7 } from "os";
|
|
@@ -2940,6 +2941,82 @@ var PromptStream = class {
|
|
|
2940
2941
|
function isLinearThoughtEvent(event) {
|
|
2941
2942
|
return event.content.type === "thought";
|
|
2942
2943
|
}
|
|
2944
|
+
var INTERACTIVE_TOOL_NAMES = ["AskUserQuestion", "ExitPlanMode"];
|
|
2945
|
+
var TOOL_INPUT_HANDLERS = {
|
|
2946
|
+
ExitPlanMode: {
|
|
2947
|
+
getRequest: () => ({
|
|
2948
|
+
options: [
|
|
2949
|
+
{ id: "approve", label: "Start implementing", variant: "primary" },
|
|
2950
|
+
{ id: "deny", label: "Keep planning", variant: "secondary" }
|
|
2951
|
+
]
|
|
2952
|
+
}),
|
|
2953
|
+
resolve: (selectionId, input) => {
|
|
2954
|
+
if (selectionId === "approve") {
|
|
2955
|
+
return { result: { behavior: "allow", updatedInput: input }, summary: "Start implementing" };
|
|
2956
|
+
}
|
|
2957
|
+
return { result: { behavior: "deny", message: "User declined to exit plan mode." }, summary: "Keep planning" };
|
|
2958
|
+
}
|
|
2959
|
+
},
|
|
2960
|
+
AskUserQuestion: {
|
|
2961
|
+
getRequest: (input) => {
|
|
2962
|
+
const questions = Array.isArray(input.questions) ? input.questions : [];
|
|
2963
|
+
return {
|
|
2964
|
+
questions: questions.map((q, qi) => ({
|
|
2965
|
+
id: String(qi),
|
|
2966
|
+
prompt: q.question,
|
|
2967
|
+
multiSelect: Boolean(q.multiSelect),
|
|
2968
|
+
options: (q.options ?? []).map((opt, oi) => ({
|
|
2969
|
+
id: String(oi),
|
|
2970
|
+
label: opt.label,
|
|
2971
|
+
description: opt.description,
|
|
2972
|
+
preview: opt.preview
|
|
2973
|
+
}))
|
|
2974
|
+
}))
|
|
2975
|
+
};
|
|
2976
|
+
},
|
|
2977
|
+
resolve: (selectionId, input) => {
|
|
2978
|
+
if (selectionId === "declined") {
|
|
2979
|
+
return {
|
|
2980
|
+
result: { behavior: "deny", message: "User declined to answer questions." },
|
|
2981
|
+
summary: "Declined to answer"
|
|
2982
|
+
};
|
|
2983
|
+
}
|
|
2984
|
+
let parsed;
|
|
2985
|
+
try {
|
|
2986
|
+
parsed = JSON.parse(selectionId);
|
|
2987
|
+
} catch {
|
|
2988
|
+
return {
|
|
2989
|
+
result: { behavior: "deny", message: "Invalid selection payload." }
|
|
2990
|
+
};
|
|
2991
|
+
}
|
|
2992
|
+
const questions = Array.isArray(input.questions) ? input.questions : [];
|
|
2993
|
+
const answers = {};
|
|
2994
|
+
const summaryParts = [];
|
|
2995
|
+
for (let qi = 0; qi < questions.length; qi++) {
|
|
2996
|
+
const q = questions[qi];
|
|
2997
|
+
const entry = parsed[String(qi)];
|
|
2998
|
+
if (!entry) continue;
|
|
2999
|
+
let answer = null;
|
|
3000
|
+
if (typeof entry.custom === "string" && entry.custom.trim()) {
|
|
3001
|
+
answer = entry.custom.trim();
|
|
3002
|
+
} else if (Array.isArray(entry.options) && entry.options.length > 0) {
|
|
3003
|
+
const labels = entry.options.map((idx) => q.options[Number(idx)]?.label).filter((l) => Boolean(l));
|
|
3004
|
+
if (labels.length > 0) {
|
|
3005
|
+
answer = labels.join(", ");
|
|
3006
|
+
}
|
|
3007
|
+
}
|
|
3008
|
+
if (answer) {
|
|
3009
|
+
answers[q.question] = answer;
|
|
3010
|
+
summaryParts.push(`${q.question}: ${answer}`);
|
|
3011
|
+
}
|
|
3012
|
+
}
|
|
3013
|
+
return {
|
|
3014
|
+
result: { behavior: "allow", updatedInput: { ...input, answers } },
|
|
3015
|
+
summary: summaryParts.join(" \u2022 ")
|
|
3016
|
+
};
|
|
3017
|
+
}
|
|
3018
|
+
}
|
|
3019
|
+
};
|
|
2943
3020
|
var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
2944
3021
|
historyFile;
|
|
2945
3022
|
sessionId = null;
|
|
@@ -2951,6 +3028,8 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
2951
3028
|
mcpServersConfig;
|
|
2952
3029
|
envOverrides;
|
|
2953
3030
|
disallowedToolsOverride;
|
|
3031
|
+
/** Active tool-input requests keyed by requestId; resolved when the user selects an option. */
|
|
3032
|
+
pendingToolInputs = /* @__PURE__ */ new Map();
|
|
2954
3033
|
constructor(options) {
|
|
2955
3034
|
super(options);
|
|
2956
3035
|
this.historyFile = options.historyFilePath ?? join10(homedir7(), ".replicas", "claude", "history.jsonl");
|
|
@@ -2967,6 +3046,96 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
2967
3046
|
if (this.activeQuery) {
|
|
2968
3047
|
await this.activeQuery.interrupt();
|
|
2969
3048
|
}
|
|
3049
|
+
await this.abortAllPendingToolInputs();
|
|
3050
|
+
}
|
|
3051
|
+
async abortAllPendingToolInputs() {
|
|
3052
|
+
const pending = Array.from(this.pendingToolInputs.values());
|
|
3053
|
+
this.pendingToolInputs.clear();
|
|
3054
|
+
for (const entry of pending) {
|
|
3055
|
+
entry.resolve({ behavior: "deny", message: "Turn interrupted" });
|
|
3056
|
+
await this.emitToolInputEvent("replicas-tool-input-resolved", {
|
|
3057
|
+
requestId: entry.requestId,
|
|
3058
|
+
toolUseId: entry.toolUseId,
|
|
3059
|
+
toolName: entry.toolName,
|
|
3060
|
+
selectionId: "aborted"
|
|
3061
|
+
});
|
|
3062
|
+
}
|
|
3063
|
+
}
|
|
3064
|
+
async respondToToolInput(requestId, selectionId) {
|
|
3065
|
+
const pending = this.pendingToolInputs.get(requestId);
|
|
3066
|
+
if (!pending) {
|
|
3067
|
+
return false;
|
|
3068
|
+
}
|
|
3069
|
+
this.pendingToolInputs.delete(requestId);
|
|
3070
|
+
const resolution = pending.handler.resolve(selectionId, pending.input);
|
|
3071
|
+
pending.resolve(resolution.result);
|
|
3072
|
+
await this.emitToolInputEvent("replicas-tool-input-resolved", {
|
|
3073
|
+
requestId,
|
|
3074
|
+
toolUseId: pending.toolUseId,
|
|
3075
|
+
toolName: pending.toolName,
|
|
3076
|
+
selectionId,
|
|
3077
|
+
...resolution.summary ? { selectionSummary: resolution.summary } : {}
|
|
3078
|
+
});
|
|
3079
|
+
return true;
|
|
3080
|
+
}
|
|
3081
|
+
async emitToolInputEvent(type, payload) {
|
|
3082
|
+
const event = {
|
|
3083
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3084
|
+
type,
|
|
3085
|
+
payload: { ...payload, parent_tool_use_id: null }
|
|
3086
|
+
};
|
|
3087
|
+
await appendFile4(this.historyFile, JSON.stringify(event) + "\n", "utf-8");
|
|
3088
|
+
this.onEvent(event);
|
|
3089
|
+
}
|
|
3090
|
+
buildCanUseTool() {
|
|
3091
|
+
return async (toolName, input, options) => {
|
|
3092
|
+
const handler = TOOL_INPUT_HANDLERS[toolName];
|
|
3093
|
+
if (!handler) {
|
|
3094
|
+
return { behavior: "allow" };
|
|
3095
|
+
}
|
|
3096
|
+
const requestId = randomUUID3();
|
|
3097
|
+
const toolUseId = options.toolUseID;
|
|
3098
|
+
const { options: requestOptions, questions: requestQuestions } = handler.getRequest(input);
|
|
3099
|
+
const result = await new Promise((resolve3) => {
|
|
3100
|
+
this.pendingToolInputs.set(requestId, {
|
|
3101
|
+
requestId,
|
|
3102
|
+
toolUseId,
|
|
3103
|
+
toolName,
|
|
3104
|
+
input,
|
|
3105
|
+
handler,
|
|
3106
|
+
resolve: resolve3
|
|
3107
|
+
});
|
|
3108
|
+
const onAbort = () => {
|
|
3109
|
+
const pending = this.pendingToolInputs.get(requestId);
|
|
3110
|
+
if (!pending) return;
|
|
3111
|
+
this.pendingToolInputs.delete(requestId);
|
|
3112
|
+
pending.resolve({ behavior: "deny", message: "Aborted." });
|
|
3113
|
+
this.emitToolInputEvent("replicas-tool-input-resolved", {
|
|
3114
|
+
requestId: pending.requestId,
|
|
3115
|
+
toolUseId: pending.toolUseId,
|
|
3116
|
+
toolName: pending.toolName,
|
|
3117
|
+
selectionId: "aborted"
|
|
3118
|
+
}).catch((err) => {
|
|
3119
|
+
console.error("[ClaudeManager] Failed to emit resolved event on abort:", err);
|
|
3120
|
+
});
|
|
3121
|
+
};
|
|
3122
|
+
if (options.signal.aborted) {
|
|
3123
|
+
onAbort();
|
|
3124
|
+
return;
|
|
3125
|
+
}
|
|
3126
|
+
options.signal.addEventListener("abort", onAbort, { once: true });
|
|
3127
|
+
this.emitToolInputEvent("replicas-tool-input-request", {
|
|
3128
|
+
requestId,
|
|
3129
|
+
toolUseId,
|
|
3130
|
+
toolName,
|
|
3131
|
+
...requestOptions ? { options: requestOptions } : {},
|
|
3132
|
+
...requestQuestions ? { questions: requestQuestions } : {}
|
|
3133
|
+
}).catch((err) => {
|
|
3134
|
+
console.error("[ClaudeManager] Failed to emit tool-input request event:", err);
|
|
3135
|
+
});
|
|
3136
|
+
});
|
|
3137
|
+
return result;
|
|
3138
|
+
};
|
|
2970
3139
|
}
|
|
2971
3140
|
/**
|
|
2972
3141
|
* Internal method that actually processes the message.
|
|
@@ -2997,7 +3166,8 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
2997
3166
|
customInstructions,
|
|
2998
3167
|
images,
|
|
2999
3168
|
permissionMode,
|
|
3000
|
-
thinkingLevel
|
|
3169
|
+
thinkingLevel,
|
|
3170
|
+
enableInteractiveTools
|
|
3001
3171
|
} = request;
|
|
3002
3172
|
const linearSessionId = ENGINE_ENV.LINEAR_SESSION_ID;
|
|
3003
3173
|
if (!message || !message.trim()) {
|
|
@@ -3045,6 +3215,10 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
3045
3215
|
};
|
|
3046
3216
|
const queryEnv = buildClaudeAgentEnv(this.envOverrides);
|
|
3047
3217
|
const resolvedModel = normalizeClaudeModel(model) || CLAUDE_OPUS_1M_MODEL;
|
|
3218
|
+
const disallowedTools = [
|
|
3219
|
+
...this.disallowedToolsOverride ?? [],
|
|
3220
|
+
...enableInteractiveTools ? [] : INTERACTIVE_TOOL_NAMES
|
|
3221
|
+
];
|
|
3048
3222
|
const response = query({
|
|
3049
3223
|
prompt: promptStream,
|
|
3050
3224
|
options: {
|
|
@@ -3053,13 +3227,14 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
3053
3227
|
permissionMode: permissionMode === "read" ? "plan" : "bypassPermissions",
|
|
3054
3228
|
allowDangerouslySkipPermissions: permissionMode !== "read",
|
|
3055
3229
|
...this.toolsOverride ? { tools: this.toolsOverride } : {},
|
|
3056
|
-
disallowedTools
|
|
3230
|
+
...disallowedTools.length > 0 ? { disallowedTools } : {},
|
|
3057
3231
|
settingSources: ["user", "project", "local"],
|
|
3058
3232
|
systemPrompt,
|
|
3059
3233
|
...this.mcpServersConfig ? { mcpServers: this.mcpServersConfig } : {},
|
|
3060
3234
|
env: queryEnv,
|
|
3061
3235
|
model: resolvedModel,
|
|
3062
|
-
...thinkingLevel ? { effort: thinkingLevel } : {}
|
|
3236
|
+
...thinkingLevel ? { effort: thinkingLevel } : {},
|
|
3237
|
+
canUseTool: this.buildCanUseTool()
|
|
3063
3238
|
}
|
|
3064
3239
|
});
|
|
3065
3240
|
this.activeQuery = response;
|
|
@@ -3229,7 +3404,7 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
3229
3404
|
|
|
3230
3405
|
// src/managers/codex-manager.ts
|
|
3231
3406
|
import { Codex } from "@openai/codex-sdk";
|
|
3232
|
-
import { randomUUID as
|
|
3407
|
+
import { randomUUID as randomUUID4 } from "crypto";
|
|
3233
3408
|
import { readdir as readdir3, stat as stat2, writeFile as writeFile7, mkdir as mkdir9, readFile as readFile7 } from "fs/promises";
|
|
3234
3409
|
import { existsSync as existsSync6 } from "fs";
|
|
3235
3410
|
import { join as join11 } from "path";
|
|
@@ -3412,7 +3587,7 @@ var CodexManager = class extends CodingAgentManager {
|
|
|
3412
3587
|
const tempPaths = [];
|
|
3413
3588
|
for (const image of images) {
|
|
3414
3589
|
const ext = image.source.media_type.split("/")[1] || "png";
|
|
3415
|
-
const filename = `img_${
|
|
3590
|
+
const filename = `img_${randomUUID4()}.${ext}`;
|
|
3416
3591
|
const filepath = join11(this.tempImageDir, filename);
|
|
3417
3592
|
const buffer = Buffer.from(image.source.data, "base64");
|
|
3418
3593
|
await writeFile7(filepath, buffer);
|
|
@@ -4387,7 +4562,7 @@ var ChatService = class {
|
|
|
4387
4562
|
throw new ChatNotFoundError(parentChatId);
|
|
4388
4563
|
}
|
|
4389
4564
|
const persisted = {
|
|
4390
|
-
id:
|
|
4565
|
+
id: randomUUID5(),
|
|
4391
4566
|
provider: request.provider,
|
|
4392
4567
|
title,
|
|
4393
4568
|
createdAt: now,
|
|
@@ -4509,6 +4684,13 @@ var ChatService = class {
|
|
|
4509
4684
|
queue: chat.provider.getQueue()
|
|
4510
4685
|
};
|
|
4511
4686
|
}
|
|
4687
|
+
async respondToToolInput(chatId, requestId, selectionId) {
|
|
4688
|
+
const chat = this.requireChat(chatId);
|
|
4689
|
+
if (!chat.provider.respondToToolInput) {
|
|
4690
|
+
return false;
|
|
4691
|
+
}
|
|
4692
|
+
return chat.provider.respondToToolInput(requestId, selectionId);
|
|
4693
|
+
}
|
|
4512
4694
|
async deleteChat(chatId) {
|
|
4513
4695
|
const chat = this.requireChat(chatId);
|
|
4514
4696
|
if (chat.persisted.title === DEFAULT_CHAT_TITLES[chat.persisted.provider]) {
|
|
@@ -4733,7 +4915,7 @@ var ChatService = class {
|
|
|
4733
4915
|
}
|
|
4734
4916
|
async publish(input) {
|
|
4735
4917
|
const event = {
|
|
4736
|
-
id:
|
|
4918
|
+
id: randomUUID5(),
|
|
4737
4919
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4738
4920
|
...input
|
|
4739
4921
|
};
|
|
@@ -5506,10 +5688,15 @@ var sendMessageSchema = z2.object({
|
|
|
5506
5688
|
])
|
|
5507
5689
|
})).optional(),
|
|
5508
5690
|
thinkingLevel: z2.enum(["low", "medium", "high", "max"]).optional(),
|
|
5691
|
+
enableInteractiveTools: z2.boolean().optional(),
|
|
5509
5692
|
senderUserId: z2.string().optional(),
|
|
5510
5693
|
senderEmail: z2.string().optional(),
|
|
5511
5694
|
senderDisplayName: z2.string().optional()
|
|
5512
5695
|
});
|
|
5696
|
+
var respondToolInputSchema = z2.object({
|
|
5697
|
+
requestId: z2.string().min(1),
|
|
5698
|
+
selectionId: z2.string().min(1)
|
|
5699
|
+
});
|
|
5513
5700
|
function jsonError(message, details) {
|
|
5514
5701
|
return { error: message, details };
|
|
5515
5702
|
}
|
|
@@ -5708,6 +5895,22 @@ function createV1Routes(deps) {
|
|
|
5708
5895
|
return c.json(jsonError("Failed to reorder queue", error instanceof Error ? error.message : "Unknown error"), 500);
|
|
5709
5896
|
}
|
|
5710
5897
|
});
|
|
5898
|
+
app2.post("/chats/:chatId/tool-input", async (c) => {
|
|
5899
|
+
try {
|
|
5900
|
+
const body = respondToolInputSchema.parse(await c.req.json());
|
|
5901
|
+
const resolved = await deps.chatService.respondToToolInput(
|
|
5902
|
+
c.req.param("chatId"),
|
|
5903
|
+
body.requestId,
|
|
5904
|
+
body.selectionId
|
|
5905
|
+
);
|
|
5906
|
+
return c.json({ resolved });
|
|
5907
|
+
} catch (error) {
|
|
5908
|
+
if (error instanceof ChatNotFoundError) {
|
|
5909
|
+
return c.json(jsonError("Failed to resolve tool input", error.message), 404);
|
|
5910
|
+
}
|
|
5911
|
+
return c.json(jsonError("Failed to resolve tool input", error instanceof Error ? error.message : "Unknown error"), 400);
|
|
5912
|
+
}
|
|
5913
|
+
});
|
|
5711
5914
|
app2.get("/repos", async (c) => {
|
|
5712
5915
|
const includeDiffs = c.req.query("includeDiffs") === "true";
|
|
5713
5916
|
const repos = await gitService.listRepos({ includeDiffs });
|
|
@@ -6170,7 +6373,7 @@ function startStatusBroadcaster() {
|
|
|
6170
6373
|
if (serialized !== previousRepoStatus) {
|
|
6171
6374
|
previousRepoStatus = serialized;
|
|
6172
6375
|
eventService.publish({
|
|
6173
|
-
id:
|
|
6376
|
+
id: randomUUID6(),
|
|
6174
6377
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6175
6378
|
type: "repo.status.changed",
|
|
6176
6379
|
payload: { repos }
|
|
@@ -6190,7 +6393,7 @@ function startStatusBroadcaster() {
|
|
|
6190
6393
|
if (engineStatusJson !== previousEngineStatus) {
|
|
6191
6394
|
previousEngineStatus = engineStatusJson;
|
|
6192
6395
|
eventService.publish({
|
|
6193
|
-
id:
|
|
6396
|
+
id: randomUUID6(),
|
|
6194
6397
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6195
6398
|
type: "engine.status.changed",
|
|
6196
6399
|
payload: { status: engineStatus }
|
|
@@ -6211,7 +6414,7 @@ function startStatusBroadcaster() {
|
|
|
6211
6414
|
previousHookStatus = hookSnapshot;
|
|
6212
6415
|
if (!lastHooksRunning && hooksRunning) {
|
|
6213
6416
|
eventService.publish({
|
|
6214
|
-
id:
|
|
6417
|
+
id: randomUUID6(),
|
|
6215
6418
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6216
6419
|
type: "hooks.started",
|
|
6217
6420
|
payload: { running: true, completed: false }
|
|
@@ -6220,7 +6423,7 @@ function startStatusBroadcaster() {
|
|
|
6220
6423
|
}
|
|
6221
6424
|
if (hooksRunning) {
|
|
6222
6425
|
eventService.publish({
|
|
6223
|
-
id:
|
|
6426
|
+
id: randomUUID6(),
|
|
6224
6427
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6225
6428
|
type: "hooks.progress",
|
|
6226
6429
|
payload: { running: true, completed: false }
|
|
@@ -6229,7 +6432,7 @@ function startStatusBroadcaster() {
|
|
|
6229
6432
|
}
|
|
6230
6433
|
if (lastHooksRunning && !hooksRunning && hooksCompleted && !hooksFailed) {
|
|
6231
6434
|
eventService.publish({
|
|
6232
|
-
id:
|
|
6435
|
+
id: randomUUID6(),
|
|
6233
6436
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6234
6437
|
type: "hooks.completed",
|
|
6235
6438
|
payload: { running: false, completed: true }
|
|
@@ -6238,7 +6441,7 @@ function startStatusBroadcaster() {
|
|
|
6238
6441
|
}
|
|
6239
6442
|
if (lastHooksRunning && !hooksRunning && hooksFailed) {
|
|
6240
6443
|
eventService.publish({
|
|
6241
|
-
id:
|
|
6444
|
+
id: randomUUID6(),
|
|
6242
6445
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6243
6446
|
type: "hooks.failed",
|
|
6244
6447
|
payload: { running: false, completed: hooksCompleted }
|
|
@@ -6246,7 +6449,7 @@ function startStatusBroadcaster() {
|
|
|
6246
6449
|
});
|
|
6247
6450
|
}
|
|
6248
6451
|
eventService.publish({
|
|
6249
|
-
id:
|
|
6452
|
+
id: randomUUID6(),
|
|
6250
6453
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6251
6454
|
type: "hooks.status",
|
|
6252
6455
|
payload: {
|
|
@@ -6287,20 +6490,20 @@ serve(
|
|
|
6287
6490
|
}
|
|
6288
6491
|
const repos = await gitService.listRepos();
|
|
6289
6492
|
await eventService.publish({
|
|
6290
|
-
id:
|
|
6493
|
+
id: randomUUID6(),
|
|
6291
6494
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6292
6495
|
type: "repo.discovered",
|
|
6293
6496
|
payload: { repos }
|
|
6294
6497
|
});
|
|
6295
6498
|
const repoStatuses = await gitService.listRepos();
|
|
6296
6499
|
await eventService.publish({
|
|
6297
|
-
id:
|
|
6500
|
+
id: randomUUID6(),
|
|
6298
6501
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6299
6502
|
type: "repo.status.changed",
|
|
6300
6503
|
payload: { repos: repoStatuses }
|
|
6301
6504
|
});
|
|
6302
6505
|
await eventService.publish({
|
|
6303
|
-
id:
|
|
6506
|
+
id: randomUUID6(),
|
|
6304
6507
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6305
6508
|
type: "engine.ready",
|
|
6306
6509
|
payload: { version: "v1" }
|