chatroom-cli 1.117.6 → 1.118.0
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/index.js
CHANGED
|
@@ -26981,6 +26981,16 @@ var init_backend = __esm(() => {
|
|
|
26981
26981
|
};
|
|
26982
26982
|
});
|
|
26983
26983
|
|
|
26984
|
+
// src/infrastructure/services/cli-gateway.ts
|
|
26985
|
+
var CliGatewayService, CliGatewayServiceLive = (gateway) => exports_Layer.succeed(CliGatewayService, {
|
|
26986
|
+
handoff: (args2) => gateway.handoff(args2)
|
|
26987
|
+
});
|
|
26988
|
+
var init_cli_gateway = __esm(() => {
|
|
26989
|
+
init_esm();
|
|
26990
|
+
CliGatewayService = class CliGatewayService extends exports_Context.Tag("CliGatewayService")() {
|
|
26991
|
+
};
|
|
26992
|
+
});
|
|
26993
|
+
|
|
26984
26994
|
// src/infrastructure/services/session.ts
|
|
26985
26995
|
var SessionService, SessionServiceLive = (ops) => exports_Layer.succeed(SessionService, {
|
|
26986
26996
|
getSessionId: () => exports_Effect.promise(() => ops.getSessionId()),
|
|
@@ -26995,7 +27005,12 @@ var init_session = __esm(() => {
|
|
|
26995
27005
|
|
|
26996
27006
|
// src/infrastructure/services/command-effect-helpers.ts
|
|
26997
27007
|
function commandServicesLayerFromDeps(deps) {
|
|
26998
|
-
|
|
27008
|
+
const gateway = deps.gateway ?? {
|
|
27009
|
+
handoff: async () => {
|
|
27010
|
+
throw new Error("CLI gateway is unavailable");
|
|
27011
|
+
}
|
|
27012
|
+
};
|
|
27013
|
+
return exports_Layer.mergeAll(CliGatewayServiceLive(gateway), BackendServiceLive({
|
|
26999
27014
|
query: deps.backend.query,
|
|
27000
27015
|
mutation: deps.backend.mutation,
|
|
27001
27016
|
...deps.backend.action ? { action: deps.backend.action } : {}
|
|
@@ -27017,6 +27032,17 @@ function requireSessionIdEffect(fail11) {
|
|
|
27017
27032
|
return sessionId;
|
|
27018
27033
|
});
|
|
27019
27034
|
}
|
|
27035
|
+
function requireSessionForChatroomEffect(params) {
|
|
27036
|
+
return exports_Effect.gen(function* () {
|
|
27037
|
+
const sessionId = yield* requireSessionIdEffect(({ convexUrl, otherUrls }) => ({
|
|
27038
|
+
_tag: "NotAuthenticated",
|
|
27039
|
+
convexUrl,
|
|
27040
|
+
otherUrls
|
|
27041
|
+
}));
|
|
27042
|
+
yield* validateChatroomIdEffect(params.chatroomId, (id3) => ({ _tag: "InvalidChatroomId", id: id3 }));
|
|
27043
|
+
return sessionId;
|
|
27044
|
+
});
|
|
27045
|
+
}
|
|
27020
27046
|
function validateChatroomIdEffect(chatroomId, fail11) {
|
|
27021
27047
|
const valid = typeof chatroomId === "string" && chatroomId.length >= 20 && chatroomId.length <= 40;
|
|
27022
27048
|
return valid ? exports_Effect.void : exports_Effect.fail(fail11(chatroomId));
|
|
@@ -27024,6 +27050,7 @@ function validateChatroomIdEffect(chatroomId, fail11) {
|
|
|
27024
27050
|
var init_command_effect_helpers = __esm(() => {
|
|
27025
27051
|
init_esm();
|
|
27026
27052
|
init_backend();
|
|
27053
|
+
init_cli_gateway();
|
|
27027
27054
|
init_session();
|
|
27028
27055
|
});
|
|
27029
27056
|
|
|
@@ -27081,6 +27108,7 @@ var init_process = __esm(() => {
|
|
|
27081
27108
|
// src/infrastructure/services/index.ts
|
|
27082
27109
|
var init_services = __esm(() => {
|
|
27083
27110
|
init_backend();
|
|
27111
|
+
init_cli_gateway();
|
|
27084
27112
|
init_command_effect_helpers();
|
|
27085
27113
|
init_clock2();
|
|
27086
27114
|
init_fs();
|
|
@@ -28334,7 +28362,8 @@ function createAgentProcessManagerService(deps) {
|
|
|
28334
28362
|
resumeTurnForSlot: (input) => deps.execution.resumeTurnForSlot(input),
|
|
28335
28363
|
subscribeAgentTurnEnded: (handler) => deps.execution.subscribeAgentTurnEnded(handler),
|
|
28336
28364
|
subscribeAgentStarted: (handler) => deps.execution.subscribeAgentStarted(handler),
|
|
28337
|
-
subscribeAgentSessionLost: (handler) => deps.execution.subscribeAgentSessionLost(handler)
|
|
28365
|
+
subscribeAgentSessionLost: (handler) => deps.execution.subscribeAgentSessionLost(handler),
|
|
28366
|
+
subscribeAgentTurnProgress: (handler) => deps.execution.subscribeAgentTurnProgress(handler)
|
|
28338
28367
|
};
|
|
28339
28368
|
}
|
|
28340
28369
|
var NATIVE_DELIVERY_SLOT_WAIT_MS = 120000, SLOT_CHANGE_POLL_MS = 100;
|
|
@@ -44651,29 +44680,24 @@ async function emitNativeWaitingAfterSpawn(ctx, harness, opts) {
|
|
|
44651
44680
|
return false;
|
|
44652
44681
|
}
|
|
44653
44682
|
}
|
|
44654
|
-
function fireTokenActivity(
|
|
44683
|
+
function fireTokenActivity(onTurnProgress, chatroomId, role, now, lastReportedTokenAt, throttleMs) {
|
|
44655
44684
|
const t = now();
|
|
44656
44685
|
if (lastReportedTokenAt.value === 0 || t - lastReportedTokenAt.value >= throttleMs) {
|
|
44657
44686
|
lastReportedTokenAt.value = t;
|
|
44658
|
-
|
|
44659
|
-
sessionId,
|
|
44660
|
-
chatroomId,
|
|
44661
|
-
role
|
|
44662
|
-
}).catch(() => {});
|
|
44687
|
+
onTurnProgress({ chatroomId, role });
|
|
44663
44688
|
}
|
|
44664
44689
|
}
|
|
44665
44690
|
function wireTokenActivityReporting(opts) {
|
|
44666
44691
|
if (!isTeamAgentRole(opts.role))
|
|
44667
44692
|
return;
|
|
44693
|
+
const onTurnProgress = opts.onTurnProgress;
|
|
44694
|
+
if (!onTurnProgress)
|
|
44695
|
+
return;
|
|
44668
44696
|
if (opts.activityEmitter) {
|
|
44669
44697
|
opts.activityEmitter.onActivity((signal) => {
|
|
44670
44698
|
if (signal.kind !== "progress" || !signal.isFirstForTurn)
|
|
44671
44699
|
return;
|
|
44672
|
-
opts.
|
|
44673
|
-
sessionId: opts.sessionId,
|
|
44674
|
-
chatroomId: opts.chatroomId,
|
|
44675
|
-
role: opts.role
|
|
44676
|
-
}).catch(() => {});
|
|
44700
|
+
onTurnProgress({ chatroomId: opts.chatroomId, role: opts.role });
|
|
44677
44701
|
});
|
|
44678
44702
|
return;
|
|
44679
44703
|
}
|
|
@@ -44684,13 +44708,12 @@ function wireTokenActivityReporting(opts) {
|
|
|
44684
44708
|
if (!register)
|
|
44685
44709
|
return;
|
|
44686
44710
|
register(() => {
|
|
44687
|
-
fireTokenActivity(
|
|
44711
|
+
fireTokenActivity(onTurnProgress, opts.chatroomId, opts.role, now, lastReportedTokenAt, throttleMs);
|
|
44688
44712
|
});
|
|
44689
44713
|
}
|
|
44690
44714
|
var NATIVE_TOKEN_ACTIVITY_THROTTLE_MS = 30000;
|
|
44691
44715
|
var init_native_spawn_presence = __esm(() => {
|
|
44692
44716
|
init_types();
|
|
44693
|
-
init_api3();
|
|
44694
44717
|
init_agent_lifecycle_fact();
|
|
44695
44718
|
init_execution_kind();
|
|
44696
44719
|
});
|
|
@@ -44713,6 +44736,7 @@ class AgentProcessManager {
|
|
|
44713
44736
|
exitRetryQueue = [];
|
|
44714
44737
|
exitRetryTimer = null;
|
|
44715
44738
|
agentTurnEndedHandlers = new Set;
|
|
44739
|
+
agentTurnProgressHandlers = new Set;
|
|
44716
44740
|
agentTurnEndedSequence = 0;
|
|
44717
44741
|
agentStartedHandlers = new Set;
|
|
44718
44742
|
agentSessionLostHandlers = new Set;
|
|
@@ -44800,6 +44824,19 @@ class AgentProcessManager {
|
|
|
44800
44824
|
this.agentSessionLostHandlers.add(handler);
|
|
44801
44825
|
return () => this.agentSessionLostHandlers.delete(handler);
|
|
44802
44826
|
}
|
|
44827
|
+
subscribeAgentTurnProgress(handler) {
|
|
44828
|
+
this.agentTurnProgressHandlers.add(handler);
|
|
44829
|
+
return () => this.agentTurnProgressHandlers.delete(handler);
|
|
44830
|
+
}
|
|
44831
|
+
emitAgentTurnProgress(event) {
|
|
44832
|
+
for (const handler of this.agentTurnProgressHandlers) {
|
|
44833
|
+
try {
|
|
44834
|
+
handler(event);
|
|
44835
|
+
} catch (error51) {
|
|
44836
|
+
console.warn(`[AgentProcessManager] turn-progress handler failed for ${event.role}@${event.chatroomId}: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
44837
|
+
}
|
|
44838
|
+
}
|
|
44839
|
+
}
|
|
44803
44840
|
clearSlotRuntimeState(slot) {
|
|
44804
44841
|
slot.state = AGENT_SLOT_STATE.IDLE;
|
|
44805
44842
|
slot.pid = undefined;
|
|
@@ -45719,13 +45756,12 @@ class AgentProcessManager {
|
|
|
45719
45756
|
});
|
|
45720
45757
|
}
|
|
45721
45758
|
wireTokenActivityReporting({
|
|
45722
|
-
backend: this.deps.backend,
|
|
45723
|
-
sessionId: this.deps.sessionId,
|
|
45724
45759
|
chatroomId: opts.chatroomId,
|
|
45725
45760
|
role: opts.role,
|
|
45726
45761
|
spawnResult,
|
|
45727
45762
|
now: () => this.deps.clock.now(),
|
|
45728
|
-
activityEmitter: spawnResult.activityEmitter
|
|
45763
|
+
activityEmitter: spawnResult.activityEmitter,
|
|
45764
|
+
onTurnProgress: (event) => this.emitAgentTurnProgress(event)
|
|
45729
45765
|
});
|
|
45730
45766
|
}
|
|
45731
45767
|
async finalizeRunningSlot(key, slot, opts, spawnResult, wantResume) {
|
|
@@ -45742,7 +45778,7 @@ class AgentProcessManager {
|
|
|
45742
45778
|
await this.emitNativeWaiting(opts.chatroomId, opts.role, opts.agentHarness);
|
|
45743
45779
|
if (getHarnessCapabilities(opts.agentHarness).supportsNativeIntegration) {
|
|
45744
45780
|
for (const handler of this.agentStartedHandlers) {
|
|
45745
|
-
handler({ chatroomId: opts.chatroomId, role: opts.role }).catch((error51) => {
|
|
45781
|
+
handler({ chatroomId: opts.chatroomId, role: opts.role, reason: opts.reason }).catch((error51) => {
|
|
45746
45782
|
console.warn(`[AgentProcessManager] native delivery after start failed for ${opts.role}@${opts.chatroomId}: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
45747
45783
|
});
|
|
45748
45784
|
}
|
|
@@ -46941,6 +46977,8 @@ function createConvexNativeTaskDeliveryGateway(backend2) {
|
|
|
46941
46977
|
deliveryKind: "native_inject"
|
|
46942
46978
|
});
|
|
46943
46979
|
},
|
|
46980
|
+
readTask: async (args2) => await backend2.mutation(api.tasks.readTask, args2),
|
|
46981
|
+
markReceiptStarted: async (args2) => await backend2.mutation(api.taskDeliveryReceipts.markStarted, args2),
|
|
46944
46982
|
joinWaitingParticipant: async (args2) => {
|
|
46945
46983
|
await backend2.mutation(api.participants.join, {
|
|
46946
46984
|
...args2,
|
|
@@ -46987,6 +47025,7 @@ var init_convex_native_task_delivery_gateway = __esm(() => {
|
|
|
46987
47025
|
// src/daemon/services/task-service/service/task-service.ts
|
|
46988
47026
|
function createTaskService(deps) {
|
|
46989
47027
|
const gateway = createConvexNativeTaskDeliveryGateway(deps.backend);
|
|
47028
|
+
const handoffRepository = deps.handoffRepository;
|
|
46990
47029
|
const taskInboxState = new TaskInboxState;
|
|
46991
47030
|
const listeners = new Set;
|
|
46992
47031
|
let stopInboxWatch;
|
|
@@ -46996,6 +47035,120 @@ function createTaskService(deps) {
|
|
|
46996
47035
|
const scheduledEventIds = new Set;
|
|
46997
47036
|
const deliveredEventIds = new Set;
|
|
46998
47037
|
const taskChains = new Map;
|
|
47038
|
+
const maxBootstrapSweepFailures = 3;
|
|
47039
|
+
let bootstrapSweepPending = true;
|
|
47040
|
+
let bootstrapSweepFailures = 0;
|
|
47041
|
+
let bootstrapSweepInFlight = false;
|
|
47042
|
+
let bootstrapSweepPromise;
|
|
47043
|
+
const REDIVERY_ATTEMPT_CAP = 3;
|
|
47044
|
+
const turnEndAttemptCounts = new Map;
|
|
47045
|
+
const redeliveryExhaustedKeys = new Set;
|
|
47046
|
+
const redeliveryKey = (chatroomId, role, taskId) => `${chatroomId}:${role.toLowerCase()}:${taskId}`;
|
|
47047
|
+
const recordUncoveredTurnEnd = async (args2) => {
|
|
47048
|
+
const key = redeliveryKey(args2.chatroomId, args2.role, args2.taskId);
|
|
47049
|
+
if (redeliveryExhaustedKeys.has(key))
|
|
47050
|
+
return { exceeded: true };
|
|
47051
|
+
const attempts = (turnEndAttemptCounts.get(key) ?? 0) + 1;
|
|
47052
|
+
turnEndAttemptCounts.set(key, attempts);
|
|
47053
|
+
if (attempts < REDIVERY_ATTEMPT_CAP)
|
|
47054
|
+
return { exceeded: false };
|
|
47055
|
+
redeliveryExhaustedKeys.add(key);
|
|
47056
|
+
try {
|
|
47057
|
+
await gateway.recordDeliveryFailure({
|
|
47058
|
+
sessionId: deps.sessionId,
|
|
47059
|
+
machineId: deps.machineId,
|
|
47060
|
+
taskId: args2.taskId,
|
|
47061
|
+
reason: "redelivery_exhausted"
|
|
47062
|
+
});
|
|
47063
|
+
} catch (error51) {
|
|
47064
|
+
console.warn(`[TaskService] redelivery-exhausted failure record failed chatroom=${args2.chatroomId} role=${args2.role} task=${args2.taskId}: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
47065
|
+
}
|
|
47066
|
+
console.log(`[NativeDelivery:redelivery-exhausted] chatroom=${args2.chatroomId} role=${args2.role} task=${args2.taskId} attempts=${attempts} — release/redelivery stopped; agent restart (user.start) resets`);
|
|
47067
|
+
return { exceeded: true };
|
|
47068
|
+
};
|
|
47069
|
+
const isRedeliveryExhausted = (args2) => redeliveryExhaustedKeys.has(redeliveryKey(args2.chatroomId, args2.role, args2.taskId));
|
|
47070
|
+
const clearRedeliveryTrackingForTask = (chatroomId, role, taskId) => {
|
|
47071
|
+
const key = redeliveryKey(chatroomId, role, taskId);
|
|
47072
|
+
turnEndAttemptCounts.delete(key);
|
|
47073
|
+
redeliveryExhaustedKeys.delete(key);
|
|
47074
|
+
};
|
|
47075
|
+
const sweepUncoveredInProgressTasks = async () => {
|
|
47076
|
+
let released = 0;
|
|
47077
|
+
let failures3 = 0;
|
|
47078
|
+
for (const task of taskInboxState.listAll()) {
|
|
47079
|
+
if (task.status !== "in_progress")
|
|
47080
|
+
continue;
|
|
47081
|
+
try {
|
|
47082
|
+
const handoff = await handoffRepository.getLatest(task.chatroomId, task.agentConfig.role);
|
|
47083
|
+
if (handoff?.taskIds.includes(task.taskId))
|
|
47084
|
+
continue;
|
|
47085
|
+
const result = await gateway.releaseTaskAfterTurnFailure({
|
|
47086
|
+
sessionId: deps.sessionId,
|
|
47087
|
+
chatroomId: task.chatroomId,
|
|
47088
|
+
role: task.agentConfig.role,
|
|
47089
|
+
taskId: task.taskId
|
|
47090
|
+
});
|
|
47091
|
+
taskInboxState.markStatus(task.chatroomId, task.agentConfig.role, task.taskId, result.status, result.updatedAt);
|
|
47092
|
+
released += 1;
|
|
47093
|
+
} catch (error51) {
|
|
47094
|
+
failures3 += 1;
|
|
47095
|
+
console.warn(`[TaskService] bootstrap task release failed chatroom=${task.chatroomId} task=${task.taskId}: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
47096
|
+
}
|
|
47097
|
+
}
|
|
47098
|
+
if (failures3 > 0)
|
|
47099
|
+
throw new Error(`${failures3} bootstrap task release(s) failed`);
|
|
47100
|
+
return released;
|
|
47101
|
+
};
|
|
47102
|
+
const releaseTask = async (args2) => {
|
|
47103
|
+
const result = await gateway.releaseTaskAfterTurnFailure({
|
|
47104
|
+
sessionId: deps.sessionId,
|
|
47105
|
+
chatroomId: args2.chatroomId,
|
|
47106
|
+
role: args2.role,
|
|
47107
|
+
taskId: args2.taskId
|
|
47108
|
+
});
|
|
47109
|
+
taskInboxState.markStatus(args2.chatroomId, args2.role, args2.taskId, result.status, result.updatedAt);
|
|
47110
|
+
const currentTask = taskInboxState.getForRole(args2.chatroomId, args2.role, args2.taskId);
|
|
47111
|
+
if (currentTask?.status === "pending") {
|
|
47112
|
+
pendingTaskReconciliationWatcher.watch(currentTask);
|
|
47113
|
+
} else {
|
|
47114
|
+
pendingTaskReconciliationWatcher.clear(args2.chatroomId, args2.role, args2.taskId);
|
|
47115
|
+
}
|
|
47116
|
+
return result;
|
|
47117
|
+
};
|
|
47118
|
+
const clearRoleRedeliveryTracking = (chatroomId, role) => {
|
|
47119
|
+
const prefix = `${chatroomId}:${role.toLowerCase()}:`;
|
|
47120
|
+
for (const key of [...turnEndAttemptCounts.keys()]) {
|
|
47121
|
+
if (key.startsWith(prefix))
|
|
47122
|
+
turnEndAttemptCounts.delete(key);
|
|
47123
|
+
}
|
|
47124
|
+
for (const key of [...redeliveryExhaustedKeys]) {
|
|
47125
|
+
if (key.startsWith(prefix))
|
|
47126
|
+
redeliveryExhaustedKeys.delete(key);
|
|
47127
|
+
}
|
|
47128
|
+
};
|
|
47129
|
+
const runBootstrapSweep = () => {
|
|
47130
|
+
if (!bootstrapSweepPending)
|
|
47131
|
+
return Promise.resolve();
|
|
47132
|
+
if (bootstrapSweepInFlight)
|
|
47133
|
+
return bootstrapSweepPromise ?? Promise.resolve();
|
|
47134
|
+
bootstrapSweepInFlight = true;
|
|
47135
|
+
bootstrapSweepPromise = sweepUncoveredInProgressTasks().then(() => {
|
|
47136
|
+
bootstrapSweepPending = false;
|
|
47137
|
+
bootstrapSweepFailures = 0;
|
|
47138
|
+
}).catch((error51) => {
|
|
47139
|
+
bootstrapSweepFailures += 1;
|
|
47140
|
+
if (bootstrapSweepFailures >= maxBootstrapSweepFailures) {
|
|
47141
|
+
bootstrapSweepPending = false;
|
|
47142
|
+
console.warn("[TaskService] bootstrap sweep giving up after 3 failed attempts");
|
|
47143
|
+
} else {
|
|
47144
|
+
console.warn(`[TaskService] bootstrap sweep failed (attempt ${bootstrapSweepFailures}/3): ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
47145
|
+
}
|
|
47146
|
+
}).finally(() => {
|
|
47147
|
+
bootstrapSweepInFlight = false;
|
|
47148
|
+
bootstrapSweepPromise = undefined;
|
|
47149
|
+
});
|
|
47150
|
+
return bootstrapSweepPromise;
|
|
47151
|
+
};
|
|
46999
47152
|
const notifyForDelivery = async (notification) => {
|
|
47000
47153
|
const results = await Promise.all([...listeners].map((listener) => Promise.resolve(listener(notification))));
|
|
47001
47154
|
return {
|
|
@@ -47009,8 +47162,12 @@ function createTaskService(deps) {
|
|
|
47009
47162
|
const applyInboxEvent = (event) => {
|
|
47010
47163
|
if (event.eventType === "task_deleted" /* TaskDeleted */ || event.task.status === "completed") {
|
|
47011
47164
|
taskInboxState.remove(event.chatroomId, event.role, event.taskId, event.task.updatedAt);
|
|
47165
|
+
clearRedeliveryTrackingForTask(event.chatroomId, event.role, event.taskId);
|
|
47012
47166
|
return "handled";
|
|
47013
47167
|
}
|
|
47168
|
+
if (event.eventType === "task_assigned" /* TaskAssigned */) {
|
|
47169
|
+
clearRedeliveryTrackingForTask(event.chatroomId, event.role, event.taskId);
|
|
47170
|
+
}
|
|
47014
47171
|
return taskInboxState.upsert([
|
|
47015
47172
|
{
|
|
47016
47173
|
taskId: event.task.taskId,
|
|
@@ -47119,6 +47276,7 @@ function createTaskService(deps) {
|
|
|
47119
47276
|
});
|
|
47120
47277
|
const reconcileTaskStatuses = (tasks) => {
|
|
47121
47278
|
taskInboxState.reconcileStatuses(tasks);
|
|
47279
|
+
runBootstrapSweep();
|
|
47122
47280
|
for (const task of tasks) {
|
|
47123
47281
|
if (task.status === "pending" || task.status === "acknowledged") {
|
|
47124
47282
|
pendingTaskReconciliationWatcher.watch(task);
|
|
@@ -47158,7 +47316,9 @@ function createTaskService(deps) {
|
|
|
47158
47316
|
machineId: deps.machineId
|
|
47159
47317
|
});
|
|
47160
47318
|
reconcileTaskStatuses(statusTasks);
|
|
47319
|
+
await runBootstrapSweep();
|
|
47161
47320
|
} catch (error51) {
|
|
47321
|
+
bootstrapSweepPending = true;
|
|
47162
47322
|
console.warn("[TaskService] task-status bootstrap failed:", error51);
|
|
47163
47323
|
}
|
|
47164
47324
|
if (wsClient2 && !stopInboxWatch) {
|
|
@@ -47193,26 +47353,47 @@ function createTaskService(deps) {
|
|
|
47193
47353
|
acknowledgementRetryWatcher.stop();
|
|
47194
47354
|
pendingTaskReconciliationWatcher.stop();
|
|
47195
47355
|
taskChains.clear();
|
|
47356
|
+
handoffRepository.close();
|
|
47196
47357
|
},
|
|
47197
47358
|
listTasksForRole: (chatroomId, role) => taskInboxState.listForRole(chatroomId, role),
|
|
47198
47359
|
listAllTasks: () => taskInboxState.listAll(),
|
|
47199
47360
|
debugState: (chatroomId) => buildTaskServiceDebugState({ taskInboxState, chatroomId }),
|
|
47200
47361
|
taskInboxState,
|
|
47201
|
-
|
|
47202
|
-
|
|
47203
|
-
|
|
47204
|
-
|
|
47205
|
-
|
|
47206
|
-
|
|
47207
|
-
|
|
47208
|
-
taskInboxState.
|
|
47209
|
-
|
|
47210
|
-
|
|
47211
|
-
|
|
47212
|
-
|
|
47213
|
-
|
|
47362
|
+
recordHandoffOutcome: async ({
|
|
47363
|
+
chatroomId,
|
|
47364
|
+
role,
|
|
47365
|
+
targetRole,
|
|
47366
|
+
nextTask,
|
|
47367
|
+
taskIds: providedTaskIds
|
|
47368
|
+
}) => {
|
|
47369
|
+
const taskIds = providedTaskIds ?? taskInboxState.listForRole(chatroomId, role).filter((task) => task.status === "acknowledged" || task.status === "in_progress").map((task) => task.taskId);
|
|
47370
|
+
await handoffRepository.record({
|
|
47371
|
+
chatroomId,
|
|
47372
|
+
role,
|
|
47373
|
+
taskIds,
|
|
47374
|
+
...nextTask?.taskId ? { nextTaskId: nextTask.taskId } : {},
|
|
47375
|
+
targetRole,
|
|
47376
|
+
handedOffAt: Date.now()
|
|
47377
|
+
});
|
|
47378
|
+
const now = Date.now();
|
|
47379
|
+
for (const taskId of taskIds)
|
|
47380
|
+
taskInboxState.remove(chatroomId, role, taskId, now);
|
|
47381
|
+
if (nextTask)
|
|
47382
|
+
taskInboxState.upsert([nextTask]);
|
|
47383
|
+
},
|
|
47384
|
+
getLatestHandoff: (chatroomId, role) => handoffRepository.getLatest(chatroomId, role),
|
|
47385
|
+
sweepUncoveredInProgressTasks,
|
|
47386
|
+
releaseTaskAfterTurnFailure: (args2) => releaseTask(args2),
|
|
47387
|
+
handleAgentRestart: async ({ chatroomId, role }) => {
|
|
47388
|
+
clearRoleRedeliveryTracking(chatroomId, role);
|
|
47389
|
+
const inFlightTasks = taskInboxState.listForRole(chatroomId, role).filter((task) => task.status === "acknowledged" || task.status === "in_progress");
|
|
47390
|
+
for (const task of inFlightTasks) {
|
|
47391
|
+
try {
|
|
47392
|
+
await releaseTask({ chatroomId, role, taskId: task.taskId });
|
|
47393
|
+
} catch (error51) {
|
|
47394
|
+
console.warn(`[TaskService] agent-restart release failed chatroom=${chatroomId} role=${role} task=${task.taskId}: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
47395
|
+
}
|
|
47214
47396
|
}
|
|
47215
|
-
return result;
|
|
47216
47397
|
},
|
|
47217
47398
|
loadAssignedTaskForAction: async ({ chatroomId, role, taskId }) => {
|
|
47218
47399
|
const task = await gateway.loadAssignedTaskForAction({
|
|
@@ -47223,6 +47404,27 @@ function createTaskService(deps) {
|
|
|
47223
47404
|
});
|
|
47224
47405
|
return task?.chatroomId === chatroomId ? task : null;
|
|
47225
47406
|
},
|
|
47407
|
+
handleAgentTurnProgress: async ({ chatroomId, role, taskId }) => {
|
|
47408
|
+
const task = taskInboxState.getForRole(chatroomId, role, taskId);
|
|
47409
|
+
if (!task)
|
|
47410
|
+
return;
|
|
47411
|
+
if (task.status !== "acknowledged" && task.status !== "in_progress")
|
|
47412
|
+
return;
|
|
47413
|
+
if (task.status === "acknowledged") {
|
|
47414
|
+
try {
|
|
47415
|
+
await gateway.readTask({ sessionId: deps.sessionId, chatroomId, role, taskId });
|
|
47416
|
+
taskInboxState.markStatus(chatroomId, role, taskId, "in_progress", Date.now());
|
|
47417
|
+
} catch (error51) {
|
|
47418
|
+
console.warn(`[TaskService] turn-progress read failed chatroom=${chatroomId} role=${role} task=${taskId}: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
47419
|
+
return;
|
|
47420
|
+
}
|
|
47421
|
+
}
|
|
47422
|
+
try {
|
|
47423
|
+
await gateway.markReceiptStarted({ sessionId: deps.sessionId, chatroomId, role, taskId });
|
|
47424
|
+
} catch (error51) {
|
|
47425
|
+
console.warn(`[TaskService] turn-progress receipt mark failed chatroom=${chatroomId} role=${role} task=${taskId}: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
47426
|
+
}
|
|
47427
|
+
},
|
|
47226
47428
|
recordDeliveryFailure: ({ taskId, reason }) => gateway.recordDeliveryFailure({
|
|
47227
47429
|
sessionId: deps.sessionId,
|
|
47228
47430
|
machineId: deps.machineId,
|
|
@@ -47234,7 +47436,12 @@ function createTaskService(deps) {
|
|
|
47234
47436
|
machineId: deps.machineId,
|
|
47235
47437
|
taskId,
|
|
47236
47438
|
...expectedReason ? { expectedReason } : {}
|
|
47237
|
-
})
|
|
47439
|
+
}),
|
|
47440
|
+
recordUncoveredTurnEnd,
|
|
47441
|
+
isRedeliveryExhausted,
|
|
47442
|
+
clearRedeliveryTracking: ({ chatroomId, role }) => {
|
|
47443
|
+
clearRoleRedeliveryTracking(chatroomId, role);
|
|
47444
|
+
}
|
|
47238
47445
|
};
|
|
47239
47446
|
return service4;
|
|
47240
47447
|
}
|
|
@@ -47247,6 +47454,63 @@ var init_task_service = __esm(() => {
|
|
|
47247
47454
|
init_convex_native_task_delivery_gateway();
|
|
47248
47455
|
});
|
|
47249
47456
|
|
|
47457
|
+
// src/daemon/services/task-service/infrastructure/repository/task-handoff-repository.ts
|
|
47458
|
+
import { mkdirSync as mkdirSync2 } from "node:fs";
|
|
47459
|
+
import { dirname as dirname2 } from "node:path";
|
|
47460
|
+
import { DatabaseSync } from "node:sqlite";
|
|
47461
|
+
function normalizeRole(role) {
|
|
47462
|
+
return role.toLowerCase();
|
|
47463
|
+
}
|
|
47464
|
+
function mapRow(row) {
|
|
47465
|
+
const taskIds = JSON.parse(row.task_ids_json);
|
|
47466
|
+
if (!Array.isArray(taskIds) || !taskIds.every((taskId) => typeof taskId === "string")) {
|
|
47467
|
+
throw new Error("Invalid task handoff task_ids_json");
|
|
47468
|
+
}
|
|
47469
|
+
return {
|
|
47470
|
+
chatroomId: row.chatroom_id,
|
|
47471
|
+
role: row.role,
|
|
47472
|
+
taskIds,
|
|
47473
|
+
...row.next_task_id ? { nextTaskId: row.next_task_id } : {},
|
|
47474
|
+
targetRole: row.target_role,
|
|
47475
|
+
handedOffAt: row.handed_off_at
|
|
47476
|
+
};
|
|
47477
|
+
}
|
|
47478
|
+
function createTaskHandoffRepository(dbPath) {
|
|
47479
|
+
mkdirSync2(dirname2(dbPath), { recursive: true });
|
|
47480
|
+
const db = new DatabaseSync(dbPath);
|
|
47481
|
+
db.exec(`
|
|
47482
|
+
CREATE TABLE IF NOT EXISTS task_handoffs (
|
|
47483
|
+
chatroom_id TEXT NOT NULL,
|
|
47484
|
+
role TEXT NOT NULL,
|
|
47485
|
+
task_ids_json TEXT NOT NULL,
|
|
47486
|
+
next_task_id TEXT,
|
|
47487
|
+
target_role TEXT NOT NULL,
|
|
47488
|
+
handed_off_at INTEGER NOT NULL,
|
|
47489
|
+
PRIMARY KEY (chatroom_id, role)
|
|
47490
|
+
)
|
|
47491
|
+
`);
|
|
47492
|
+
return {
|
|
47493
|
+
async record(record2) {
|
|
47494
|
+
db.prepare(`INSERT INTO task_handoffs
|
|
47495
|
+
(chatroom_id, role, task_ids_json, next_task_id, target_role, handed_off_at)
|
|
47496
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
47497
|
+
ON CONFLICT(chatroom_id, role) DO UPDATE SET
|
|
47498
|
+
task_ids_json = excluded.task_ids_json,
|
|
47499
|
+
next_task_id = excluded.next_task_id,
|
|
47500
|
+
target_role = excluded.target_role,
|
|
47501
|
+
handed_off_at = excluded.handed_off_at`).run(record2.chatroomId, normalizeRole(record2.role), JSON.stringify(record2.taskIds), record2.nextTaskId ?? null, record2.targetRole, record2.handedOffAt);
|
|
47502
|
+
},
|
|
47503
|
+
async getLatest(chatroomId, role) {
|
|
47504
|
+
const row = db.prepare("SELECT chatroom_id, role, task_ids_json, next_task_id, target_role, handed_off_at FROM task_handoffs WHERE chatroom_id = ? AND role = ?").get(chatroomId, normalizeRole(role));
|
|
47505
|
+
return row ? mapRow(row) : null;
|
|
47506
|
+
},
|
|
47507
|
+
close() {
|
|
47508
|
+
db.close();
|
|
47509
|
+
}
|
|
47510
|
+
};
|
|
47511
|
+
}
|
|
47512
|
+
var init_task_handoff_repository = () => {};
|
|
47513
|
+
|
|
47250
47514
|
// src/daemon/services/task-service/infrastructure/adapters/daemon-audit-port.ts
|
|
47251
47515
|
function createDaemonAuditPort(logEvent) {
|
|
47252
47516
|
return { emit: (event) => logDaemonAuditEvent(logEvent, event) };
|
|
@@ -47279,6 +47543,9 @@ function decideNextDelivery(tasks, context5) {
|
|
|
47279
47543
|
if (!context5.isNativeHarness(context5.agentConfig.agentHarness)) {
|
|
47280
47544
|
return { kind: "failed", taskId: task.taskId, reason: "unsupported_harness" };
|
|
47281
47545
|
}
|
|
47546
|
+
if (context5.isRedeliveryExhausted(task.taskId)) {
|
|
47547
|
+
return { kind: "deduplicated", reason: "redelivery_exhausted", taskId: task.taskId };
|
|
47548
|
+
}
|
|
47282
47549
|
const blockReason = context5.explainNativeDeliveryBlock(task);
|
|
47283
47550
|
if (blockReason === "acknowledged_wrong_role") {
|
|
47284
47551
|
return { kind: "failed", taskId: task.taskId, reason: "assigned_elsewhere" };
|
|
@@ -47394,7 +47661,8 @@ class NativeTaskDeliveryCoordinator {
|
|
|
47394
47661
|
agentConfig,
|
|
47395
47662
|
configState,
|
|
47396
47663
|
isNativeHarness: taskService.isNativeHarness,
|
|
47397
|
-
explainNativeDeliveryBlock: taskService.explainNativeDeliveryBlock
|
|
47664
|
+
explainNativeDeliveryBlock: taskService.explainNativeDeliveryBlock,
|
|
47665
|
+
isRedeliveryExhausted: (taskId) => taskService.isRedeliveryExhausted({ chatroomId: firstTask.chatroomId, role, taskId })
|
|
47398
47666
|
});
|
|
47399
47667
|
const attemptId = `${Date.now()}-${firstTask.taskId}`;
|
|
47400
47668
|
const decisionReason = "reason" in decision ? decision.reason : undefined;
|
|
@@ -47465,6 +47733,7 @@ var init_task_service2 = __esm(() => {
|
|
|
47465
47733
|
init_native_task_injector_logic();
|
|
47466
47734
|
init_task_service();
|
|
47467
47735
|
init_convex_native_task_delivery_gateway();
|
|
47736
|
+
init_task_handoff_repository();
|
|
47468
47737
|
init_daemon_audit_port();
|
|
47469
47738
|
init_native_task_delivery_coordinator();
|
|
47470
47739
|
});
|
|
@@ -47567,6 +47836,7 @@ class AgentWorkManager {
|
|
|
47567
47836
|
unsubscribeAgentTurnEnded;
|
|
47568
47837
|
unsubscribeAgentStarted;
|
|
47569
47838
|
unsubscribeAgentSessionLost;
|
|
47839
|
+
unsubscribeAgentTurnProgress;
|
|
47570
47840
|
reconcileStates = new Map;
|
|
47571
47841
|
unsubscribeTaskService;
|
|
47572
47842
|
nativeTaskDeliveryQueue;
|
|
@@ -47599,16 +47869,33 @@ class AgentWorkManager {
|
|
|
47599
47869
|
releaseTaskAfterTurnFailure: deps.taskService.releaseTaskAfterTurnFailure,
|
|
47600
47870
|
recordDeliveryFailure: deps.taskService.recordDeliveryFailure,
|
|
47601
47871
|
clearDeliveryFailure: deps.taskService.clearDeliveryFailure,
|
|
47872
|
+
recordUncoveredTurnEnd: deps.taskService.recordUncoveredTurnEnd,
|
|
47873
|
+
isRedeliveryExhausted: deps.taskService.isRedeliveryExhausted,
|
|
47874
|
+
clearRedeliveryTracking: deps.taskService.clearRedeliveryTracking,
|
|
47602
47875
|
loadAssignedTaskForAction: deps.taskService.loadAssignedTaskForAction,
|
|
47603
47876
|
deliverNativeTask: (task, harnessSessionId, onTaskDelivered) => this.nativeTaskDeliveryQueue.enqueue({ task, harnessSessionId, onTaskDelivered })
|
|
47604
47877
|
};
|
|
47605
47878
|
this.unsubscribeAgentTurnEnded = deps.agentMgr.subscribeAgentTurnEnded((event) => this.handleAgentTurnEnded(event));
|
|
47606
47879
|
this.unsubscribeAgentStarted = deps.agentMgr.subscribeAgentStarted((event) => this.handleAgentStarted(event));
|
|
47607
47880
|
this.unsubscribeAgentSessionLost = deps.agentMgr.subscribeAgentSessionLost((event) => this.handleAgentSessionLost(event));
|
|
47881
|
+
this.unsubscribeAgentTurnProgress = deps.agentMgr.subscribeAgentTurnProgress((event) => {
|
|
47882
|
+
const activeTask = this.deps.agentTaskState.get(event);
|
|
47883
|
+
if (!activeTask)
|
|
47884
|
+
return;
|
|
47885
|
+
this.deps.taskService.handleAgentTurnProgress({ ...event, taskId: activeTask.taskId }).catch((error51) => {
|
|
47886
|
+
console.warn(`[AgentProcessManager] turn-progress handling failed for ${event.role}@${event.chatroomId}: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
47887
|
+
});
|
|
47888
|
+
});
|
|
47608
47889
|
this.unsubscribeTaskService = deps.taskService.subscribe((notification) => this.handleTaskServiceNotification(notification));
|
|
47609
47890
|
}
|
|
47610
47891
|
async handleAgentStarted(event) {
|
|
47611
47892
|
this.deps.agentTaskState.clear({ chatroomId: event.chatroomId, role: event.role });
|
|
47893
|
+
if (event.reason === "user.start") {
|
|
47894
|
+
this.deps.taskService.clearRedeliveryTracking({
|
|
47895
|
+
chatroomId: event.chatroomId,
|
|
47896
|
+
role: event.role
|
|
47897
|
+
});
|
|
47898
|
+
}
|
|
47612
47899
|
await this.requestReconcile({
|
|
47613
47900
|
chatroomId: event.chatroomId,
|
|
47614
47901
|
role: event.role,
|
|
@@ -47626,24 +47913,43 @@ class AgentWorkManager {
|
|
|
47626
47913
|
console.warn(`[NativeDelivery:failure] role=${event.role} chatroom=${event.chatroomId} operation=session-loss-reconcile error=${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
47627
47914
|
});
|
|
47628
47915
|
}
|
|
47916
|
+
async recoverTaskAfterUncoveredTurnEnd(event, activeTask, phase) {
|
|
47917
|
+
const { chatroomId, role } = event;
|
|
47918
|
+
const { exceeded } = await this.deps.taskService.recordUncoveredTurnEnd({
|
|
47919
|
+
chatroomId,
|
|
47920
|
+
role,
|
|
47921
|
+
taskId: activeTask.taskId
|
|
47922
|
+
});
|
|
47923
|
+
if (exceeded)
|
|
47924
|
+
return "exceeded";
|
|
47925
|
+
try {
|
|
47926
|
+
await this.deps.taskService.releaseTaskAfterTurnFailure({
|
|
47927
|
+
chatroomId,
|
|
47928
|
+
role,
|
|
47929
|
+
taskId: activeTask.taskId
|
|
47930
|
+
});
|
|
47931
|
+
} catch (error51) {
|
|
47932
|
+
console.error(`[NativeDelivery:${phase}-recovery-error] chatroom=${chatroomId} role=${role} task=${activeTask.taskId} turn=${event.completion.turnId} error=${error51 instanceof Error ? error51.stack ?? error51.message : String(error51)}`);
|
|
47933
|
+
return "recovery-failed";
|
|
47934
|
+
}
|
|
47935
|
+
return "released";
|
|
47936
|
+
}
|
|
47629
47937
|
async handleAgentTurnEnded(event) {
|
|
47630
47938
|
const completion = event.completion;
|
|
47631
47939
|
if (completion.status !== "completed") {
|
|
47632
|
-
const
|
|
47940
|
+
const activeTask2 = this.deps.agentTaskState.get({
|
|
47633
47941
|
chatroomId: event.chatroomId,
|
|
47634
47942
|
role: event.role
|
|
47635
47943
|
});
|
|
47636
47944
|
const errorDetail = completion.error;
|
|
47637
|
-
console.error(`[NativeDelivery:turn-failed] chatroom=${event.chatroomId} role=${event.role} task=${
|
|
47638
|
-
if (
|
|
47639
|
-
|
|
47640
|
-
|
|
47641
|
-
|
|
47642
|
-
|
|
47643
|
-
|
|
47644
|
-
|
|
47645
|
-
} catch (error51) {
|
|
47646
|
-
console.error(`[NativeDelivery:turn-failed-recovery-error] chatroom=${event.chatroomId} role=${event.role} task=${activeTask.taskId} turn=${completion.turnId} error=${error51 instanceof Error ? error51.stack ?? error51.message : String(error51)}`);
|
|
47945
|
+
console.error(`[NativeDelivery:turn-failed] chatroom=${event.chatroomId} role=${event.role} task=${activeTask2?.taskId ?? "none"} turn=${completion.turnId} status=${completion.status} source=${completion.source} error=${errorDetail ?? "none"}`);
|
|
47946
|
+
if (activeTask2) {
|
|
47947
|
+
const recovery = await this.recoverTaskAfterUncoveredTurnEnd(event, activeTask2, "turn-failed");
|
|
47948
|
+
if (recovery === "exceeded") {
|
|
47949
|
+
this.deps.agentTaskState.clear({ chatroomId: event.chatroomId, role: event.role });
|
|
47950
|
+
return { kind: "release-slot" };
|
|
47951
|
+
}
|
|
47952
|
+
if (recovery === "recovery-failed") {
|
|
47647
47953
|
return { kind: "hold-slot", reason: "task-recovery-failed" };
|
|
47648
47954
|
}
|
|
47649
47955
|
this.deps.agentTaskState.clear({ chatroomId: event.chatroomId, role: event.role });
|
|
@@ -47652,7 +47958,7 @@ class AgentWorkManager {
|
|
|
47652
47958
|
kind: "turn_failed",
|
|
47653
47959
|
chatroomId: event.chatroomId,
|
|
47654
47960
|
role: event.role,
|
|
47655
|
-
...
|
|
47961
|
+
...activeTask2?.taskId ? { taskId: activeTask2.taskId } : {},
|
|
47656
47962
|
...event.slot.harnessSessionId ? { harnessSessionId: event.slot.harnessSessionId } : {},
|
|
47657
47963
|
turnId: completion.turnId,
|
|
47658
47964
|
status: completion.status,
|
|
@@ -47672,6 +47978,19 @@ class AgentWorkManager {
|
|
|
47672
47978
|
}
|
|
47673
47979
|
return { kind: "release-slot" };
|
|
47674
47980
|
}
|
|
47981
|
+
const activeTask = this.deps.agentTaskState.get({
|
|
47982
|
+
chatroomId: event.chatroomId,
|
|
47983
|
+
role: event.role
|
|
47984
|
+
});
|
|
47985
|
+
if (activeTask) {
|
|
47986
|
+
const handoff = await this.deps.taskService.getLatestHandoff(event.chatroomId, event.role);
|
|
47987
|
+
if (!handoff?.taskIds.includes(activeTask.taskId)) {
|
|
47988
|
+
const recovery = await this.recoverTaskAfterUncoveredTurnEnd(event, activeTask, "turn-ended");
|
|
47989
|
+
if (recovery === "recovery-failed") {
|
|
47990
|
+
return { kind: "hold-slot", reason: "task-recovery-failed" };
|
|
47991
|
+
}
|
|
47992
|
+
}
|
|
47993
|
+
}
|
|
47675
47994
|
this.deps.agentTaskState.clear({ chatroomId: event.chatroomId, role: event.role });
|
|
47676
47995
|
try {
|
|
47677
47996
|
await this.deps.lifecycleOutbox.enqueue(buildAgentStatusFact({
|
|
@@ -47696,6 +48015,7 @@ class AgentWorkManager {
|
|
|
47696
48015
|
this.unsubscribeAgentTurnEnded();
|
|
47697
48016
|
this.unsubscribeAgentStarted();
|
|
47698
48017
|
this.unsubscribeAgentSessionLost();
|
|
48018
|
+
this.unsubscribeAgentTurnProgress();
|
|
47699
48019
|
this.unsubscribeTaskService?.();
|
|
47700
48020
|
this.unsubscribeTaskService = undefined;
|
|
47701
48021
|
this.nativeTaskDeliveryQueue.stop();
|
|
@@ -47809,6 +48129,11 @@ class AgentWorkManager {
|
|
|
47809
48129
|
});
|
|
47810
48130
|
return delivered;
|
|
47811
48131
|
}
|
|
48132
|
+
async handleAgentRestart(args2) {
|
|
48133
|
+
resetRoleDeliveryState(args2.chatroomId, args2.role);
|
|
48134
|
+
this.deps.agentTaskState.clear(args2);
|
|
48135
|
+
await this.deps.taskService.handleAgentRestart(args2);
|
|
48136
|
+
}
|
|
47812
48137
|
async requestReconcileForTasks(tasks, source) {
|
|
47813
48138
|
const roles = new Set(tasks.map((snapshot) => `${snapshot.chatroomId}:${snapshot.agentConfig.role.toLowerCase()}`));
|
|
47814
48139
|
await Promise.all([...roles].map((key) => {
|
|
@@ -47844,6 +48169,7 @@ var init_agent_work_manager = __esm(() => {
|
|
|
47844
48169
|
init_native_task_injector_logic();
|
|
47845
48170
|
init_convex_native_task_delivery_gateway();
|
|
47846
48171
|
init_daemon_audit_port();
|
|
48172
|
+
init_native_task_delivery_coordinator();
|
|
47847
48173
|
init_task_delivery_processor();
|
|
47848
48174
|
init_native_task_injector();
|
|
47849
48175
|
});
|
|
@@ -50852,12 +51178,12 @@ var init_model_provider = () => {};
|
|
|
50852
51178
|
// src/daemon/infrastructure/local/harness/services/cursor-sdk/cursor-sdk-package.ts
|
|
50853
51179
|
import { existsSync as existsSync2, readFileSync as readFileSync4 } from "node:fs";
|
|
50854
51180
|
import { createRequire as createRequire3 } from "node:module";
|
|
50855
|
-
import { dirname as
|
|
51181
|
+
import { dirname as dirname3, join as join8 } from "node:path";
|
|
50856
51182
|
import { fileURLToPath as fileURLToPath2, pathToFileURL } from "node:url";
|
|
50857
51183
|
function resolveChatroomCliRoot(moduleRef = import.meta.url) {
|
|
50858
51184
|
const filePath = moduleRef.startsWith("file:") ? fileURLToPath2(moduleRef) : moduleRef;
|
|
50859
|
-
let dir =
|
|
50860
|
-
while (dir !==
|
|
51185
|
+
let dir = dirname3(filePath);
|
|
51186
|
+
while (dir !== dirname3(dir)) {
|
|
50861
51187
|
const packageJsonPath = join8(dir, "package.json");
|
|
50862
51188
|
if (existsSync2(packageJsonPath)) {
|
|
50863
51189
|
const pkg = JSON.parse(readFileSync4(packageJsonPath, "utf8"));
|
|
@@ -50865,7 +51191,7 @@ function resolveChatroomCliRoot(moduleRef = import.meta.url) {
|
|
|
50865
51191
|
return dir;
|
|
50866
51192
|
}
|
|
50867
51193
|
}
|
|
50868
|
-
dir =
|
|
51194
|
+
dir = dirname3(dir);
|
|
50869
51195
|
}
|
|
50870
51196
|
throw new CursorSdkPackageError(`Could not locate chatroom-cli package root while resolving @cursor/sdk. ${REINSTALL_HINT}`);
|
|
50871
51197
|
}
|
|
@@ -50880,7 +51206,7 @@ function readPinnedSdkVersion(chatroomCliRoot) {
|
|
|
50880
51206
|
return match17[1];
|
|
50881
51207
|
}
|
|
50882
51208
|
function readInstalledSdkVersion(entryPath) {
|
|
50883
|
-
const packageJsonPath = join8(
|
|
51209
|
+
const packageJsonPath = join8(dirname3(entryPath), "..", "..", "package.json");
|
|
50884
51210
|
const pkg = JSON.parse(readFileSync4(packageJsonPath, "utf8"));
|
|
50885
51211
|
return pkg.version;
|
|
50886
51212
|
}
|
|
@@ -51781,12 +52107,12 @@ var init_claude = __esm(() => {
|
|
|
51781
52107
|
// src/daemon/infrastructure/local/harness/services/claude-sdk/claude-sdk-package.ts
|
|
51782
52108
|
import { existsSync as existsSync3, readFileSync as readFileSync5 } from "node:fs";
|
|
51783
52109
|
import { createRequire as createRequire4 } from "node:module";
|
|
51784
|
-
import { dirname as
|
|
52110
|
+
import { dirname as dirname4, join as join9 } from "node:path";
|
|
51785
52111
|
import { fileURLToPath as fileURLToPath3, pathToFileURL as pathToFileURL2 } from "node:url";
|
|
51786
52112
|
function resolveChatroomCliRoot2(moduleRef = import.meta.url) {
|
|
51787
52113
|
const filePath = moduleRef.startsWith("file:") ? fileURLToPath3(moduleRef) : moduleRef;
|
|
51788
|
-
let dir =
|
|
51789
|
-
while (dir !==
|
|
52114
|
+
let dir = dirname4(filePath);
|
|
52115
|
+
while (dir !== dirname4(dir)) {
|
|
51790
52116
|
const packageJsonPath = join9(dir, "package.json");
|
|
51791
52117
|
if (existsSync3(packageJsonPath)) {
|
|
51792
52118
|
const pkg = JSON.parse(readFileSync5(packageJsonPath, "utf8"));
|
|
@@ -51794,7 +52120,7 @@ function resolveChatroomCliRoot2(moduleRef = import.meta.url) {
|
|
|
51794
52120
|
return dir;
|
|
51795
52121
|
}
|
|
51796
52122
|
}
|
|
51797
|
-
dir =
|
|
52123
|
+
dir = dirname4(dir);
|
|
51798
52124
|
}
|
|
51799
52125
|
throw new ClaudeSdkPackageError(`Could not locate chatroom-cli package root while resolving ${CLAUDE_AGENT_SDK_PKG}. ${REINSTALL_HINT2}`);
|
|
51800
52126
|
}
|
|
@@ -51809,7 +52135,7 @@ function readPinnedSdkVersion2(chatroomCliRoot) {
|
|
|
51809
52135
|
return match17[1];
|
|
51810
52136
|
}
|
|
51811
52137
|
function readInstalledSdkVersion2(entryPath) {
|
|
51812
|
-
const packageJsonPath = join9(
|
|
52138
|
+
const packageJsonPath = join9(dirname4(entryPath), "package.json");
|
|
51813
52139
|
const pkg = JSON.parse(readFileSync5(packageJsonPath, "utf8"));
|
|
51814
52140
|
return pkg.version;
|
|
51815
52141
|
}
|
|
@@ -51835,7 +52161,7 @@ function resolveNativeCliBinaryPath(sdkEntryPath) {
|
|
|
51835
52161
|
const binaryName = process.platform === "win32" ? "claude.exe" : "claude";
|
|
51836
52162
|
let pkgDir;
|
|
51837
52163
|
try {
|
|
51838
|
-
pkgDir =
|
|
52164
|
+
pkgDir = dirname4(require3.resolve(`${platformPkg}/package.json`));
|
|
51839
52165
|
} catch {
|
|
51840
52166
|
throw new ClaudeSdkPackageError(`Native CLI binary package ${platformPkg} is not installed. ${REINSTALL_HINT2}`);
|
|
51841
52167
|
}
|
|
@@ -52771,12 +53097,12 @@ var init_codex_sdk_model_variants = __esm(() => {
|
|
|
52771
53097
|
// src/daemon/infrastructure/local/harness/services/codex-sdk/codex-sdk-package.ts
|
|
52772
53098
|
import { existsSync as existsSync4, readFileSync as readFileSync6, realpathSync, statSync } from "node:fs";
|
|
52773
53099
|
import { createRequire as createRequire5 } from "node:module";
|
|
52774
|
-
import { dirname as
|
|
53100
|
+
import { dirname as dirname5, join as join10 } from "node:path";
|
|
52775
53101
|
import { fileURLToPath as fileURLToPath4, pathToFileURL as pathToFileURL3 } from "node:url";
|
|
52776
53102
|
function resolveChatroomCliRoot3(moduleRef = import.meta.url) {
|
|
52777
53103
|
const filePath = moduleRef.startsWith("file:") ? fileURLToPath4(moduleRef) : moduleRef;
|
|
52778
|
-
let dir =
|
|
52779
|
-
while (dir !==
|
|
53104
|
+
let dir = dirname5(filePath);
|
|
53105
|
+
while (dir !== dirname5(dir)) {
|
|
52780
53106
|
const packageJsonPath = join10(dir, "package.json");
|
|
52781
53107
|
if (existsSync4(packageJsonPath)) {
|
|
52782
53108
|
const pkg = JSON.parse(readFileSync6(packageJsonPath, "utf8"));
|
|
@@ -52784,7 +53110,7 @@ function resolveChatroomCliRoot3(moduleRef = import.meta.url) {
|
|
|
52784
53110
|
return dir;
|
|
52785
53111
|
}
|
|
52786
53112
|
}
|
|
52787
|
-
dir =
|
|
53113
|
+
dir = dirname5(dir);
|
|
52788
53114
|
}
|
|
52789
53115
|
throw new CodexSdkPackageError(`Could not locate chatroom-cli package root while resolving @openai/codex-sdk. ${REINSTALL_HINT3}`);
|
|
52790
53116
|
}
|
|
@@ -52851,7 +53177,7 @@ function addPlatformPackageJsonCandidate(candidates, candidate) {
|
|
|
52851
53177
|
}
|
|
52852
53178
|
function resolvePlatformPackageJsonCandidates(platformPkg, chatroomCliRoot, codexPackageJson, chatroomRequire, codexRequire) {
|
|
52853
53179
|
const candidates = [];
|
|
52854
|
-
const codexPackageDir = realpathSync(
|
|
53180
|
+
const codexPackageDir = realpathSync(dirname5(codexPackageJson));
|
|
52855
53181
|
const platformPkgBaseName = platformPkg.includes("/") ? platformPkg.slice(platformPkg.indexOf("/") + 1) : platformPkg;
|
|
52856
53182
|
try {
|
|
52857
53183
|
addPlatformPackageJsonCandidate(candidates, codexRequire.resolve(`${platformPkg}/package.json`));
|
|
@@ -52895,7 +53221,7 @@ function resolveCodexExecutablePath(moduleRef = import.meta.url) {
|
|
|
52895
53221
|
throw new CodexSdkPackageError(`Native Codex CLI package ${platformPkg} is not installed. Ensure ${CODEX_NPM_NAME} is installed with optional dependencies. ${REINSTALL_HINT3}`);
|
|
52896
53222
|
}
|
|
52897
53223
|
for (const platformPackageJson of platformPackageJsonCandidates) {
|
|
52898
|
-
const vendorRoot = join10(
|
|
53224
|
+
const vendorRoot = join10(dirname5(platformPackageJson), "vendor");
|
|
52899
53225
|
const binaryPath = resolveNativeCodexBinary(vendorRoot, targetTriple, codexBinaryName);
|
|
52900
53226
|
if (binaryPath) {
|
|
52901
53227
|
return binaryPath;
|
|
@@ -52911,7 +53237,7 @@ async function importBundledCodexSdk(moduleRef = import.meta.url) {
|
|
|
52911
53237
|
if (installedVersion !== pinnedVersion) {
|
|
52912
53238
|
throw new CodexSdkPackageError(`@openai/codex-sdk@${installedVersion} does not match chatroom-cli pin (${pinnedVersion}). ${REINSTALL_HINT3}`);
|
|
52913
53239
|
}
|
|
52914
|
-
const distEntryPath = join10(
|
|
53240
|
+
const distEntryPath = join10(dirname5(packageJsonPath), "dist", "index.js");
|
|
52915
53241
|
if (!existsSync4(distEntryPath)) {
|
|
52916
53242
|
throw new CodexSdkPackageError(`@openai/codex-sdk entry file is missing: ${distEntryPath}. ${REINSTALL_HINT3}`);
|
|
52917
53243
|
}
|
|
@@ -55022,9 +55348,9 @@ var init_session_event_forwarder = __esm(() => {
|
|
|
55022
55348
|
});
|
|
55023
55349
|
|
|
55024
55350
|
// src/daemon/infrastructure/local/harness/services/opencode-sdk/session-metadata-store.ts
|
|
55025
|
-
import { existsSync as existsSync5, mkdirSync as
|
|
55351
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync7, writeFileSync as writeFileSync2 } from "node:fs";
|
|
55026
55352
|
import { homedir as homedir3 } from "node:os";
|
|
55027
|
-
import { dirname as
|
|
55353
|
+
import { dirname as dirname6, join as join11 } from "node:path";
|
|
55028
55354
|
|
|
55029
55355
|
class FileSessionMetadataStore {
|
|
55030
55356
|
filePath;
|
|
@@ -55041,9 +55367,9 @@ class FileSessionMetadataStore {
|
|
|
55041
55367
|
}
|
|
55042
55368
|
save(sessions) {
|
|
55043
55369
|
try {
|
|
55044
|
-
const dir =
|
|
55370
|
+
const dir = dirname6(this.filePath);
|
|
55045
55371
|
if (!existsSync5(dir)) {
|
|
55046
|
-
|
|
55372
|
+
mkdirSync3(dir, { recursive: true });
|
|
55047
55373
|
}
|
|
55048
55374
|
writeFileSync2(this.filePath, JSON.stringify(sessions, null, 2));
|
|
55049
55375
|
} catch {}
|
|
@@ -55591,12 +55917,12 @@ var init_opencode_sdk = __esm(() => {
|
|
|
55591
55917
|
|
|
55592
55918
|
// src/daemon/infrastructure/local/harness/services/pi-sdk/pi-sdk-package.ts
|
|
55593
55919
|
import { existsSync as existsSync6, readFileSync as readFileSync8 } from "node:fs";
|
|
55594
|
-
import { dirname as
|
|
55920
|
+
import { dirname as dirname7, join as join12 } from "node:path";
|
|
55595
55921
|
import { fileURLToPath as fileURLToPath5, pathToFileURL as pathToFileURL4 } from "node:url";
|
|
55596
55922
|
function resolveChatroomCliRoot4(moduleRef = import.meta.url) {
|
|
55597
55923
|
const filePath = moduleRef.startsWith("file:") ? fileURLToPath5(moduleRef) : moduleRef;
|
|
55598
|
-
let dir =
|
|
55599
|
-
while (dir !==
|
|
55924
|
+
let dir = dirname7(filePath);
|
|
55925
|
+
while (dir !== dirname7(dir)) {
|
|
55600
55926
|
const packageJsonPath = join12(dir, "package.json");
|
|
55601
55927
|
if (existsSync6(packageJsonPath)) {
|
|
55602
55928
|
const pkg = JSON.parse(readFileSync8(packageJsonPath, "utf8"));
|
|
@@ -55604,7 +55930,7 @@ function resolveChatroomCliRoot4(moduleRef = import.meta.url) {
|
|
|
55604
55930
|
return dir;
|
|
55605
55931
|
}
|
|
55606
55932
|
}
|
|
55607
|
-
dir =
|
|
55933
|
+
dir = dirname7(dir);
|
|
55608
55934
|
}
|
|
55609
55935
|
throw new PiSdkPackageError(`Could not locate chatroom-cli package root while resolving ${PI_CODING_AGENT_PKG}. ${REINSTALL_HINT4}`);
|
|
55610
55936
|
}
|
|
@@ -55619,18 +55945,18 @@ function readPinnedSdkVersion4(chatroomCliRoot) {
|
|
|
55619
55945
|
return match17[1];
|
|
55620
55946
|
}
|
|
55621
55947
|
function readInstalledSdkVersion4(entryPath) {
|
|
55622
|
-
const packageJsonPath = join12(
|
|
55948
|
+
const packageJsonPath = join12(dirname7(entryPath), "..", "package.json");
|
|
55623
55949
|
const pkg = JSON.parse(readFileSync8(packageJsonPath, "utf8"));
|
|
55624
55950
|
return pkg.version;
|
|
55625
55951
|
}
|
|
55626
55952
|
function resolvePiSdkEntryPathFromNodeModules(chatroomCliRoot) {
|
|
55627
55953
|
let dir = chatroomCliRoot;
|
|
55628
|
-
while (dir !==
|
|
55954
|
+
while (dir !== dirname7(dir)) {
|
|
55629
55955
|
const entryPath = join12(dir, "node_modules", PI_CODING_AGENT_PKG, "dist", "index.js");
|
|
55630
55956
|
if (existsSync6(entryPath)) {
|
|
55631
55957
|
return entryPath;
|
|
55632
55958
|
}
|
|
55633
|
-
dir =
|
|
55959
|
+
dir = dirname7(dir);
|
|
55634
55960
|
}
|
|
55635
55961
|
return;
|
|
55636
55962
|
}
|
|
@@ -63776,15 +64102,35 @@ async function requestLocalDaemon(port, event, payload) {
|
|
|
63776
64102
|
socket.connect();
|
|
63777
64103
|
});
|
|
63778
64104
|
const response = await socket.timeout(1e4).emitWithAck(event, payload);
|
|
63779
|
-
if (!response.ok)
|
|
63780
|
-
throw
|
|
64105
|
+
if (!response.ok) {
|
|
64106
|
+
throw toLocalDaemonServerError(response, event);
|
|
64107
|
+
}
|
|
63781
64108
|
return response.data;
|
|
63782
64109
|
} finally {
|
|
63783
64110
|
socket.disconnect();
|
|
63784
64111
|
}
|
|
63785
64112
|
}
|
|
64113
|
+
function toLocalDaemonServerError(response, event) {
|
|
64114
|
+
const error51 = response.error ?? {};
|
|
64115
|
+
return new LocalDaemonServerError({
|
|
64116
|
+
message: error51.message ?? `Daemon request failed: ${event}`,
|
|
64117
|
+
code: error51.code,
|
|
64118
|
+
details: error51.details
|
|
64119
|
+
});
|
|
64120
|
+
}
|
|
64121
|
+
var LocalDaemonServerError;
|
|
63786
64122
|
var init_local_daemon = __esm(() => {
|
|
63787
64123
|
init_esm_debug3();
|
|
64124
|
+
LocalDaemonServerError = class LocalDaemonServerError extends Error {
|
|
64125
|
+
code;
|
|
64126
|
+
details;
|
|
64127
|
+
constructor(error51) {
|
|
64128
|
+
super(error51.message ?? "Daemon request failed");
|
|
64129
|
+
this.name = "LocalDaemonServerError";
|
|
64130
|
+
this.code = error51.code;
|
|
64131
|
+
this.details = error51.details;
|
|
64132
|
+
}
|
|
64133
|
+
};
|
|
63788
64134
|
});
|
|
63789
64135
|
|
|
63790
64136
|
// src/daemon/entry/resolve-local-web-port.ts
|
|
@@ -63996,12 +64342,12 @@ var init_log_schema = __esm(() => {
|
|
|
63996
64342
|
});
|
|
63997
64343
|
|
|
63998
64344
|
// src/infrastructure/log-server/open-log-database.ts
|
|
63999
|
-
import { mkdirSync as
|
|
64000
|
-
import { dirname as
|
|
64001
|
-
import { DatabaseSync } from "node:sqlite";
|
|
64345
|
+
import { mkdirSync as mkdirSync4 } from "node:fs";
|
|
64346
|
+
import { dirname as dirname8 } from "node:path";
|
|
64347
|
+
import { DatabaseSync as DatabaseSync2 } from "node:sqlite";
|
|
64002
64348
|
function openLogDatabase(dbPath) {
|
|
64003
|
-
|
|
64004
|
-
const db = new
|
|
64349
|
+
mkdirSync4(dirname8(dbPath), { recursive: true });
|
|
64350
|
+
const db = new DatabaseSync2(dbPath);
|
|
64005
64351
|
db.exec("PRAGMA journal_mode = WAL");
|
|
64006
64352
|
db.exec("PRAGMA busy_timeout = 5000");
|
|
64007
64353
|
db.exec("PRAGMA synchronous = NORMAL");
|
|
@@ -64190,7 +64536,7 @@ var init_daemon_process_scan = __esm(() => {
|
|
|
64190
64536
|
|
|
64191
64537
|
// src/commands/machine/pid.ts
|
|
64192
64538
|
import { createHash as createHash2 } from "node:crypto";
|
|
64193
|
-
import { existsSync as existsSync8, readFileSync as readFileSync10, writeFileSync as writeFileSync3, unlinkSync as unlinkSync2, mkdirSync as
|
|
64539
|
+
import { existsSync as existsSync8, readFileSync as readFileSync10, writeFileSync as writeFileSync3, unlinkSync as unlinkSync2, mkdirSync as mkdirSync5 } from "node:fs";
|
|
64194
64540
|
import { homedir as homedir7 } from "node:os";
|
|
64195
64541
|
import { join as join16 } from "node:path";
|
|
64196
64542
|
function getUrlHash2() {
|
|
@@ -64202,7 +64548,7 @@ function getPidFileName() {
|
|
|
64202
64548
|
}
|
|
64203
64549
|
function ensureChatroomDir2() {
|
|
64204
64550
|
if (!existsSync8(CHATROOM_DIR3)) {
|
|
64205
|
-
|
|
64551
|
+
mkdirSync5(CHATROOM_DIR3, { recursive: true, mode: 448 });
|
|
64206
64552
|
}
|
|
64207
64553
|
}
|
|
64208
64554
|
function getPidFilePath() {
|
|
@@ -77212,11 +77558,11 @@ var init_pdfium_renderer = __esm(() => {
|
|
|
77212
77558
|
|
|
77213
77559
|
// ../../node_modules/.pnpm/@llamaindex+liteparse@1.5.3/node_modules/@llamaindex/liteparse/dist/src/engines/pdf/pdfjsImporter.js
|
|
77214
77560
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
77215
|
-
import { dirname as
|
|
77561
|
+
import { dirname as dirname9 } from "node:path";
|
|
77216
77562
|
async function importPdfJs() {
|
|
77217
77563
|
const pdfUrl = new URL("../../vendor/pdfjs/pdf.mjs", import.meta.url);
|
|
77218
77564
|
const pdfjs = await import(pdfUrl.href);
|
|
77219
|
-
const dirPath =
|
|
77565
|
+
const dirPath = dirname9(fileURLToPath6(pdfUrl));
|
|
77220
77566
|
return {
|
|
77221
77567
|
fn: pdfjs.getDocument,
|
|
77222
77568
|
dir: dirPath
|
|
@@ -98865,9 +99211,9 @@ function applyMarkupTags(markup, text) {
|
|
|
98865
99211
|
}
|
|
98866
99212
|
|
|
98867
99213
|
// ../../node_modules/.pnpm/@llamaindex+liteparse@1.5.3/node_modules/@llamaindex/liteparse/dist/src/processing/gridDebugLogger.js
|
|
98868
|
-
import { mkdirSync as
|
|
99214
|
+
import { mkdirSync as mkdirSync6, writeFileSync as writeFileSync4 } from "fs";
|
|
98869
99215
|
import { mkdir as mkdir4, writeFile as writeFile5 } from "fs/promises";
|
|
98870
|
-
import { dirname as
|
|
99216
|
+
import { dirname as dirname10 } from "path";
|
|
98871
99217
|
|
|
98872
99218
|
class GridDebugLogger {
|
|
98873
99219
|
config;
|
|
@@ -99194,14 +99540,14 @@ class GridDebugLogger {
|
|
|
99194
99540
|
flushSync() {
|
|
99195
99541
|
if (!this.config.outputPath || this.entries.length === 0)
|
|
99196
99542
|
return;
|
|
99197
|
-
|
|
99543
|
+
mkdirSync6(dirname10(this.config.outputPath), { recursive: true });
|
|
99198
99544
|
writeFileSync4(this.config.outputPath, this.formatEntries(), "utf-8");
|
|
99199
99545
|
this.entries = [];
|
|
99200
99546
|
}
|
|
99201
99547
|
async flush() {
|
|
99202
99548
|
if (!this.config.outputPath || this.entries.length === 0)
|
|
99203
99549
|
return;
|
|
99204
|
-
await mkdir4(
|
|
99550
|
+
await mkdir4(dirname10(this.config.outputPath), { recursive: true });
|
|
99205
99551
|
await writeFile5(this.config.outputPath, this.formatEntries(), "utf-8");
|
|
99206
99552
|
this.entries = [];
|
|
99207
99553
|
}
|
|
@@ -99252,7 +99598,7 @@ var init_gridDebugLogger = __esm(() => {
|
|
|
99252
99598
|
});
|
|
99253
99599
|
|
|
99254
99600
|
// ../../node_modules/.pnpm/@llamaindex+liteparse@1.5.3/node_modules/@llamaindex/liteparse/dist/src/processing/gridVisualizer.js
|
|
99255
|
-
import { mkdirSync as
|
|
99601
|
+
import { mkdirSync as mkdirSync7 } from "fs";
|
|
99256
99602
|
function escapeXml(s) {
|
|
99257
99603
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
99258
99604
|
}
|
|
@@ -99362,7 +99708,7 @@ async function renderGridVisualization(data, outputPath) {
|
|
|
99362
99708
|
}).composite([{ input: svgBuffer, top: 0, left: 0 }]).png({ compressionLevel: 6 }).toFile(outputPath);
|
|
99363
99709
|
}
|
|
99364
99710
|
async function renderAllVisualizations(pages, outputDir) {
|
|
99365
|
-
|
|
99711
|
+
mkdirSync7(outputDir, { recursive: true });
|
|
99366
99712
|
const paths = [];
|
|
99367
99713
|
for (const page of pages) {
|
|
99368
99714
|
const filePath = `${outputDir}/page-${page.pageNum}-grid.png`;
|
|
@@ -107065,6 +107411,9 @@ function getFrontendDesignUxFlowChecklistBlock() {
|
|
|
107065
107411
|
- **Interaction affordance:** pointer cursor (or project equivalent) on clickable elements
|
|
107066
107412
|
- **Safeguards:** confirmation before destructive actions; bulk operations confirmed with scope summary`;
|
|
107067
107413
|
}
|
|
107414
|
+
function getFrontendDesignUxTriggerDescription() {
|
|
107415
|
+
return "when the user request involves user interface changes";
|
|
107416
|
+
}
|
|
107068
107417
|
|
|
107069
107418
|
// ../../services/backend/prompts/utils/enhancer-feedback-template-body.ts
|
|
107070
107419
|
function getEnhancerFeedbackTemplateBody() {
|
|
@@ -107927,31 +108276,8 @@ function formatDecodeError(error51) {
|
|
|
107927
108276
|
return message;
|
|
107928
108277
|
}
|
|
107929
108278
|
|
|
107930
|
-
// ../../services/backend/prompts/
|
|
107931
|
-
|
|
107932
|
-
return getHandoffTurnEndGuidance(nextRole);
|
|
107933
|
-
}
|
|
107934
|
-
function getHandoffTurnEndGuidance(nextRole) {
|
|
107935
|
-
const lines = [
|
|
107936
|
-
"",
|
|
107937
|
-
"**Handoff complete. End your turn now — stop tool calls. The system will send you a message when further action is required.**"
|
|
107938
|
-
];
|
|
107939
|
-
if (nextRole.toLowerCase() === "user") {
|
|
107940
|
-
lines.push("The system delivers the next chatroom task when the user sends one.");
|
|
107941
|
-
} else {
|
|
107942
|
-
lines.push(`The system delivers \`${nextRole}\`'s handback when they finish — do not poll \`messages download\` while waiting. For history reconstruction tasks, \`messages download\` is the correct tool.`);
|
|
107943
|
-
}
|
|
107944
|
-
return lines.join(`
|
|
107945
|
-
`);
|
|
107946
|
-
}
|
|
107947
|
-
function getNativeEnhancerRequestTurnEndGuidance() {
|
|
107948
|
-
return [
|
|
107949
|
-
"",
|
|
107950
|
-
"**Handoff complete. End your turn now — stop tool calls. The system will send you a message when further action is required.**",
|
|
107951
|
-
"Do **not** wait for enhancer input, poll, or monitor the enhancer job in this turn. The system delivers independent planning input as your next task when analysis completes."
|
|
107952
|
-
].join(`
|
|
107953
|
-
`);
|
|
107954
|
-
}
|
|
108279
|
+
// ../../services/backend/prompts/config/agent-general-knowledge.ts
|
|
108280
|
+
var init_agent_general_knowledge = () => {};
|
|
107955
108281
|
// ../../services/backend/prompts/sections/activated-skills.ts
|
|
107956
108282
|
var init_activated_skills = () => {};
|
|
107957
108283
|
|
|
@@ -108062,6 +108388,74 @@ var init_general_knowledge = __esm(() => {
|
|
|
108062
108388
|
init_utils3();
|
|
108063
108389
|
});
|
|
108064
108390
|
|
|
108391
|
+
// ../../services/backend/prompts/enhancer/system-prompt.ts
|
|
108392
|
+
var ENHANCER_ROLE_CONTRACT_LINES;
|
|
108393
|
+
var init_system_prompt = __esm(() => {
|
|
108394
|
+
init_stdin_heredoc();
|
|
108395
|
+
init_agent_general_knowledge();
|
|
108396
|
+
init_general_knowledge();
|
|
108397
|
+
ENHANCER_ROLE_CONTRACT_LINES = [
|
|
108398
|
+
"You are a single-turn, memoryless **design advisor**. Produce a high-intelligence first design for the user request; you are not an implementer.",
|
|
108399
|
+
"",
|
|
108400
|
+
"## Your role",
|
|
108401
|
+
"- Recover the authoritative user request and relevant history before analysis.",
|
|
108402
|
+
"- Inspect the repository and closely related files to understand existing patterns, constraints, and likely change surfaces.",
|
|
108403
|
+
"- Return **one** complete recommended design — not multiple options. The entry point verifies and delegates.",
|
|
108404
|
+
"- Complete frontend and data/query design sections at code granularity before implementation sequencing.",
|
|
108405
|
+
"- Use <additional-context> from the forwarded request as the entry point's goal; verify against downloaded history and repository evidence.",
|
|
108406
|
+
"- <user-message> is authoritative for what the user said; do not treat <additional-context> as a substitute.",
|
|
108407
|
+
"- Give concrete, evidence-backed design input with repo-relative file references and targeted code snippets when useful.",
|
|
108408
|
+
"- In <handoff-proofs>, complete **Proof of Principles** for how this design satisfies each quality principle.",
|
|
108409
|
+
"- Keep the user request as the north star. Tighten within its scope; do not invent requirements.",
|
|
108410
|
+
"- Your output becomes the first planning input to the stateful team entry point, which owns persistent memory, the ongoing plan, and execution.",
|
|
108411
|
+
"",
|
|
108412
|
+
`## Frontend design (${getFrontendDesignUxTriggerDescription()})`,
|
|
108413
|
+
"- Complete <handoff-frontend-design> with flows, per-flow UX quality checklist, component specs, and layout at code granularity.",
|
|
108414
|
+
"- Ground patterns in repository evidence — cite existing components; recommend one when multiple exist.",
|
|
108415
|
+
'- Write "Not Applicable." for the entire section when no UI changes are involved.',
|
|
108416
|
+
"",
|
|
108417
|
+
"## Large or multi-surface revisions",
|
|
108418
|
+
"- When the request involves refactoring, consolidation, or consistency across many surfaces, note in implementation sequence that the entry point should run `chatroom skill activate defragmentation` before delegating slices.",
|
|
108419
|
+
"",
|
|
108420
|
+
"## Data and query design (when persistence or query patterns change)",
|
|
108421
|
+
"- Complete <handoff-data-design> with schema, indexes, and query patterns within project limits.",
|
|
108422
|
+
'- Write "Not Applicable." for the entire section when no persistence changes are involved.',
|
|
108423
|
+
"",
|
|
108424
|
+
"## What you must NOT do",
|
|
108425
|
+
"- Do NOT implement changes, spawn subagents, or expand scope.",
|
|
108426
|
+
"- Do NOT propose multiple alternative approaches — one recommended design only.",
|
|
108427
|
+
"- Do NOT produce generic advice. Tie findings to user messages, repository evidence, and named files.",
|
|
108428
|
+
"- Do NOT treat <forwarded-request> as the only source of context; download message history first.",
|
|
108429
|
+
"- Output must match <output-template>. **Recommended implementation sequence** and **Files touched** are the last sections."
|
|
108430
|
+
];
|
|
108431
|
+
});
|
|
108432
|
+
|
|
108433
|
+
// ../../services/backend/prompts/native/session-continuity.ts
|
|
108434
|
+
function getNativeHandoffTurnEndGuidance(nextRole) {
|
|
108435
|
+
return getHandoffTurnEndGuidance(nextRole);
|
|
108436
|
+
}
|
|
108437
|
+
function getHandoffTurnEndGuidance(nextRole) {
|
|
108438
|
+
const lines = [
|
|
108439
|
+
"",
|
|
108440
|
+
"**Handoff complete. End your turn now — stop tool calls. The system will send you a message when further action is required.**"
|
|
108441
|
+
];
|
|
108442
|
+
if (nextRole.toLowerCase() === "user") {
|
|
108443
|
+
lines.push("The system delivers the next chatroom task when the user sends one.");
|
|
108444
|
+
} else {
|
|
108445
|
+
lines.push(`The system delivers \`${nextRole}\`'s handback when they finish — do not poll \`messages download\` while waiting. For history reconstruction tasks, \`messages download\` is the correct tool.`);
|
|
108446
|
+
}
|
|
108447
|
+
return lines.join(`
|
|
108448
|
+
`);
|
|
108449
|
+
}
|
|
108450
|
+
function getNativeEnhancerRequestTurnEndGuidance() {
|
|
108451
|
+
return [
|
|
108452
|
+
"",
|
|
108453
|
+
"**Handoff complete. End your turn now — stop tool calls. The system will send you a message when further action is required.**",
|
|
108454
|
+
"Do **not** wait for enhancer input, poll, or monitor the enhancer job in this turn. The system delivers independent planning input as your next task when analysis completes."
|
|
108455
|
+
].join(`
|
|
108456
|
+
`);
|
|
108457
|
+
}
|
|
108458
|
+
|
|
108065
108459
|
// ../../services/backend/prompts/cli/handoff/command.ts
|
|
108066
108460
|
var init_command3 = __esm(() => {
|
|
108067
108461
|
init_stdin_heredoc();
|
|
@@ -108098,18 +108492,6 @@ var init_builder2 = __esm(() => {
|
|
|
108098
108492
|
init_sections();
|
|
108099
108493
|
});
|
|
108100
108494
|
|
|
108101
|
-
// ../../services/backend/prompts/enhancer/history-retrieval.ts
|
|
108102
|
-
var init_history_retrieval = __esm(() => {
|
|
108103
|
-
init_guidance();
|
|
108104
|
-
});
|
|
108105
|
-
|
|
108106
|
-
// ../../services/backend/prompts/cli/roles/enhancer.ts
|
|
108107
|
-
var init_enhancer3 = __esm(() => {
|
|
108108
|
-
init_history_retrieval();
|
|
108109
|
-
init_env();
|
|
108110
|
-
init_sections();
|
|
108111
|
-
});
|
|
108112
|
-
|
|
108113
108495
|
// ../../services/backend/prompts/cli/roles/planner.ts
|
|
108114
108496
|
var init_planner2 = __esm(() => {
|
|
108115
108497
|
init_env();
|
|
@@ -108127,12 +108509,18 @@ var init_solo2 = __esm(() => {
|
|
|
108127
108509
|
init_sections();
|
|
108128
108510
|
});
|
|
108129
108511
|
|
|
108130
|
-
// ../../services/backend/prompts/
|
|
108512
|
+
// ../../services/backend/prompts/teams/solo/prompts/fromContext.ts
|
|
108131
108513
|
var init_fromContext = __esm(() => {
|
|
108514
|
+
init_solo2();
|
|
108515
|
+
});
|
|
108516
|
+
|
|
108517
|
+
// ../../services/backend/prompts/cli/roles/fromContext.ts
|
|
108518
|
+
var init_fromContext2 = __esm(() => {
|
|
108132
108519
|
init_builder2();
|
|
108133
|
-
init_enhancer3();
|
|
108134
108520
|
init_planner2();
|
|
108135
|
-
|
|
108521
|
+
init_system_prompt();
|
|
108522
|
+
init_fromContext();
|
|
108523
|
+
init_utils3();
|
|
108136
108524
|
});
|
|
108137
108525
|
|
|
108138
108526
|
// ../../services/backend/prompts/teams/duo/prompts/builder.ts
|
|
@@ -108147,20 +108535,15 @@ var init_planner3 = __esm(() => {
|
|
|
108147
108535
|
});
|
|
108148
108536
|
|
|
108149
108537
|
// ../../services/backend/prompts/teams/duo/prompts/fromContext.ts
|
|
108150
|
-
var
|
|
108538
|
+
var init_fromContext3 = __esm(() => {
|
|
108151
108539
|
init_builder3();
|
|
108152
108540
|
init_planner3();
|
|
108153
108541
|
});
|
|
108154
|
-
|
|
108155
|
-
// ../../services/backend/prompts/teams/solo/prompts/fromContext.ts
|
|
108156
|
-
var init_fromContext3 = __esm(() => {
|
|
108157
|
-
init_solo2();
|
|
108158
|
-
});
|
|
108159
108542
|
// ../../services/backend/prompts/selector-context.ts
|
|
108160
108543
|
var init_selector_context = __esm(() => {
|
|
108161
|
-
init_fromContext();
|
|
108162
108544
|
init_fromContext2();
|
|
108163
108545
|
init_fromContext3();
|
|
108546
|
+
init_fromContext();
|
|
108164
108547
|
});
|
|
108165
108548
|
|
|
108166
108549
|
// ../../services/backend/prompts/sections/role-guidance.ts
|
|
@@ -108177,12 +108560,14 @@ var init_role_identity = __esm(() => {
|
|
|
108177
108560
|
});
|
|
108178
108561
|
|
|
108179
108562
|
// ../../services/backend/prompts/native/system-prompt.ts
|
|
108180
|
-
var
|
|
108563
|
+
var init_system_prompt2 = __esm(() => {
|
|
108564
|
+
init_system_prompt();
|
|
108181
108565
|
init_commands_reference();
|
|
108182
108566
|
init_general_knowledge();
|
|
108183
108567
|
init_role_guidance();
|
|
108184
108568
|
init_role_identity();
|
|
108185
108569
|
init_selector_context();
|
|
108570
|
+
init_utils3();
|
|
108186
108571
|
});
|
|
108187
108572
|
|
|
108188
108573
|
// ../../services/backend/prompts/native/task-started-content.ts
|
|
@@ -108265,6 +108650,7 @@ var init_generator = __esm(() => {
|
|
|
108265
108650
|
init_command();
|
|
108266
108651
|
init_reminder();
|
|
108267
108652
|
init_system_prompt();
|
|
108653
|
+
init_system_prompt2();
|
|
108268
108654
|
init_classification_guide();
|
|
108269
108655
|
init_commands_reference();
|
|
108270
108656
|
init_general_knowledge();
|
|
@@ -108280,6 +108666,21 @@ var init_generator = __esm(() => {
|
|
|
108280
108666
|
init_review_guidelines();
|
|
108281
108667
|
});
|
|
108282
108668
|
|
|
108669
|
+
// src/infrastructure/cli-gateway/local-handoff-gateway.ts
|
|
108670
|
+
function createLocalHandoffGateway() {
|
|
108671
|
+
return {
|
|
108672
|
+
handoff: (args2) => requestLocalDaemon(resolveLocalWebPort(), "cli.handoff", args2).catch((error51) => {
|
|
108673
|
+
if (error51 instanceof LocalDaemonServerError)
|
|
108674
|
+
throw error51;
|
|
108675
|
+
throw new Error(`CLI gateway unavailable. Start the Chatroom daemon and retry. ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
108676
|
+
})
|
|
108677
|
+
};
|
|
108678
|
+
}
|
|
108679
|
+
var init_local_handoff_gateway = __esm(() => {
|
|
108680
|
+
init_local_daemon();
|
|
108681
|
+
init_resolve_local_web_port();
|
|
108682
|
+
});
|
|
108683
|
+
|
|
108283
108684
|
// src/infrastructure/deps/create-convex-command-deps.ts
|
|
108284
108685
|
async function createConvexCommandDeps() {
|
|
108285
108686
|
const client4 = await getConvexClient();
|
|
@@ -108305,7 +108706,8 @@ __export(exports_handoff, {
|
|
|
108305
108706
|
handoff: () => handoff
|
|
108306
108707
|
});
|
|
108307
108708
|
async function createDefaultDeps10() {
|
|
108308
|
-
|
|
108709
|
+
const deps = await createConvexCommandDeps();
|
|
108710
|
+
return { backend: deps.backend, gateway: createLocalHandoffGateway(), session: deps.session };
|
|
108309
108711
|
}
|
|
108310
108712
|
function handleHandoffError(err) {
|
|
108311
108713
|
return exports_Effect.sync(() => {
|
|
@@ -108376,27 +108778,24 @@ async function handoff(chatroomId, options, deps) {
|
|
|
108376
108778
|
}
|
|
108377
108779
|
var handoffEffect = (chatroomId, options) => exports_Effect.gen(function* () {
|
|
108378
108780
|
const session2 = yield* SessionService;
|
|
108379
|
-
const
|
|
108781
|
+
const gateway = yield* CliGatewayService;
|
|
108380
108782
|
const { role, message, nextRole } = options;
|
|
108381
|
-
const sessionId = yield*
|
|
108382
|
-
|
|
108383
|
-
|
|
108384
|
-
|
|
108385
|
-
|
|
108386
|
-
|
|
108387
|
-
|
|
108388
|
-
|
|
108389
|
-
|
|
108390
|
-
|
|
108391
|
-
sessionId,
|
|
108392
|
-
chatroomId,
|
|
108393
|
-
senderRole: role,
|
|
108394
|
-
content: message,
|
|
108395
|
-
targetRole: nextRole
|
|
108783
|
+
const sessionId = yield* requireSessionForChatroomEffect({ chatroomId });
|
|
108784
|
+
const result = yield* exports_Effect.tryPromise({
|
|
108785
|
+
try: () => gateway.handoff({
|
|
108786
|
+
sessionId,
|
|
108787
|
+
chatroomId,
|
|
108788
|
+
senderRole: role,
|
|
108789
|
+
content: message,
|
|
108790
|
+
targetRole: nextRole
|
|
108791
|
+
}),
|
|
108792
|
+
catch: (cause3) => cause3 instanceof Error ? cause3 : new Error(String(cause3))
|
|
108396
108793
|
}).pipe(exports_Effect.mapError((cause3) => {
|
|
108397
108794
|
let errorData;
|
|
108398
108795
|
if (cause3 instanceof ConvexError) {
|
|
108399
108796
|
errorData = cause3.data;
|
|
108797
|
+
} else if (cause3 instanceof LocalDaemonServerError && cause3.details) {
|
|
108798
|
+
errorData = cause3.details;
|
|
108400
108799
|
}
|
|
108401
108800
|
return { _tag: "HandoffFailed", cause: cause3, errorData };
|
|
108402
108801
|
}));
|
|
@@ -108422,7 +108821,8 @@ var init_handoff = __esm(() => {
|
|
|
108422
108821
|
init_generator();
|
|
108423
108822
|
init_values();
|
|
108424
108823
|
init_esm();
|
|
108425
|
-
|
|
108824
|
+
init_local_daemon();
|
|
108825
|
+
init_local_handoff_gateway();
|
|
108426
108826
|
init_create_convex_command_deps();
|
|
108427
108827
|
init_services();
|
|
108428
108828
|
init_error_formatting();
|
|
@@ -109711,15 +110111,7 @@ async function activateSkill(chatroomId, skillId, options, deps) {
|
|
|
109711
110111
|
}
|
|
109712
110112
|
var listSkillsEffect = (chatroomId, _options) => exports_Effect.gen(function* () {
|
|
109713
110113
|
const backend2 = yield* BackendService;
|
|
109714
|
-
const sessionId = yield*
|
|
109715
|
-
_tag: "NotAuthenticated",
|
|
109716
|
-
convexUrl: a.convexUrl,
|
|
109717
|
-
otherUrls: a.otherUrls
|
|
109718
|
-
}));
|
|
109719
|
-
yield* validateChatroomIdEffect(chatroomId, (id3) => ({
|
|
109720
|
-
_tag: "InvalidChatroomId",
|
|
109721
|
-
id: id3
|
|
109722
|
-
}));
|
|
110114
|
+
const sessionId = yield* requireSessionForChatroomEffect({ chatroomId });
|
|
109723
110115
|
const skills = yield* backend2.query(api.skills.list, {
|
|
109724
110116
|
sessionId,
|
|
109725
110117
|
chatroomId
|
|
@@ -109739,15 +110131,7 @@ var listSkillsEffect = (chatroomId, _options) => exports_Effect.gen(function* ()
|
|
|
109739
110131
|
}), activateSkillEffect = (chatroomId, skillId, options) => exports_Effect.gen(function* () {
|
|
109740
110132
|
const session2 = yield* SessionService;
|
|
109741
110133
|
const backend2 = yield* BackendService;
|
|
109742
|
-
const sessionId = yield*
|
|
109743
|
-
_tag: "NotAuthenticated",
|
|
109744
|
-
convexUrl: a.convexUrl,
|
|
109745
|
-
otherUrls: a.otherUrls
|
|
109746
|
-
}));
|
|
109747
|
-
yield* validateChatroomIdEffect(chatroomId, (id3) => ({
|
|
109748
|
-
_tag: "InvalidChatroomId",
|
|
109749
|
-
id: id3
|
|
109750
|
-
}));
|
|
110134
|
+
const sessionId = yield* requireSessionForChatroomEffect({ chatroomId });
|
|
109751
110135
|
const convexUrl = yield* session2.getConvexUrl();
|
|
109752
110136
|
const result = yield* backend2.mutation(api.skills.activate, {
|
|
109753
110137
|
sessionId,
|
|
@@ -110163,15 +110547,7 @@ var PAGE_SIZE = 50, SINCE_PAGE_SIZE = 500, ABSOLUTE_MAX = 5000, DEFAULT_LIMIT =
|
|
|
110163
110547
|
}), downloadMessagesEffect = (chatroomId, options) => exports_Effect.gen(function* () {
|
|
110164
110548
|
const backend2 = yield* BackendService;
|
|
110165
110549
|
const fs11 = yield* MessagesFsService;
|
|
110166
|
-
const sessionId = yield*
|
|
110167
|
-
_tag: "NotAuthenticated",
|
|
110168
|
-
convexUrl: a.convexUrl,
|
|
110169
|
-
otherUrls: a.otherUrls
|
|
110170
|
-
}));
|
|
110171
|
-
yield* validateChatroomIdEffect(chatroomId, (id3) => ({
|
|
110172
|
-
_tag: "InvalidChatroomId",
|
|
110173
|
-
id: id3
|
|
110174
|
-
}));
|
|
110550
|
+
const sessionId = yield* requireSessionForChatroomEffect({ chatroomId });
|
|
110175
110551
|
const format4 = options.format ?? "linear";
|
|
110176
110552
|
const maxDownload = parseLimit(options.limit);
|
|
110177
110553
|
const outputDir = options.outputDir ?? resolveDownloadOutputDir(format4);
|
|
@@ -110442,15 +110818,7 @@ async function listSinceMessage(chatroomId, options, deps) {
|
|
|
110442
110818
|
}
|
|
110443
110819
|
var listBySenderRoleEffect = (chatroomId, options) => exports_Effect.gen(function* () {
|
|
110444
110820
|
const backend2 = yield* BackendService;
|
|
110445
|
-
const sessionId = yield*
|
|
110446
|
-
_tag: "NotAuthenticated",
|
|
110447
|
-
convexUrl: a.convexUrl,
|
|
110448
|
-
otherUrls: a.otherUrls
|
|
110449
|
-
}));
|
|
110450
|
-
yield* validateChatroomIdEffect(chatroomId, (id3) => ({
|
|
110451
|
-
_tag: "InvalidChatroomId",
|
|
110452
|
-
id: id3
|
|
110453
|
-
}));
|
|
110821
|
+
const sessionId = yield* requireSessionForChatroomEffect({ chatroomId });
|
|
110454
110822
|
const messages = yield* backend2.query(api.messages.listBySenderRole, {
|
|
110455
110823
|
sessionId,
|
|
110456
110824
|
chatroomId,
|
|
@@ -110485,15 +110853,7 @@ var listBySenderRoleEffect = (chatroomId, options) => exports_Effect.gen(functio
|
|
|
110485
110853
|
});
|
|
110486
110854
|
}), listSinceMessageEffect = (chatroomId, options) => exports_Effect.gen(function* () {
|
|
110487
110855
|
const backend2 = yield* BackendService;
|
|
110488
|
-
const sessionId = yield*
|
|
110489
|
-
_tag: "NotAuthenticated",
|
|
110490
|
-
convexUrl: a.convexUrl,
|
|
110491
|
-
otherUrls: a.otherUrls
|
|
110492
|
-
}));
|
|
110493
|
-
yield* validateChatroomIdEffect(chatroomId, (id3) => ({
|
|
110494
|
-
_tag: "InvalidChatroomId",
|
|
110495
|
-
id: id3
|
|
110496
|
-
}));
|
|
110856
|
+
const sessionId = yield* requireSessionForChatroomEffect({ chatroomId });
|
|
110497
110857
|
const messages = yield* backend2.query(api.messages.listSinceMessage, {
|
|
110498
110858
|
sessionId,
|
|
110499
110859
|
chatroomId,
|
|
@@ -110960,15 +111320,7 @@ async function viewManyArtifacts(chatroomId, options, deps) {
|
|
|
110960
111320
|
}
|
|
110961
111321
|
var createArtifactEffect = (chatroomId, options) => exports_Effect.gen(function* () {
|
|
110962
111322
|
const backend2 = yield* BackendService;
|
|
110963
|
-
const sessionId = yield*
|
|
110964
|
-
_tag: "NotAuthenticated",
|
|
110965
|
-
convexUrl: a.convexUrl,
|
|
110966
|
-
otherUrls: a.otherUrls
|
|
110967
|
-
}));
|
|
110968
|
-
yield* validateChatroomIdEffect(chatroomId, (id3) => ({
|
|
110969
|
-
_tag: "InvalidChatroomId",
|
|
110970
|
-
id: id3
|
|
110971
|
-
}));
|
|
111323
|
+
const sessionId = yield* requireSessionForChatroomEffect({ chatroomId });
|
|
110972
111324
|
if (!options.fromFile.endsWith(".md")) {
|
|
110973
111325
|
return yield* exports_Effect.fail({
|
|
110974
111326
|
_tag: "InvalidFileExtension",
|
|
@@ -111006,15 +111358,7 @@ var createArtifactEffect = (chatroomId, options) => exports_Effect.gen(function*
|
|
|
111006
111358
|
return artifactId;
|
|
111007
111359
|
}), viewArtifactEffect = (chatroomId, options) => exports_Effect.gen(function* () {
|
|
111008
111360
|
const backend2 = yield* BackendService;
|
|
111009
|
-
const sessionId = yield*
|
|
111010
|
-
_tag: "NotAuthenticated",
|
|
111011
|
-
convexUrl: a.convexUrl,
|
|
111012
|
-
otherUrls: a.otherUrls
|
|
111013
|
-
}));
|
|
111014
|
-
yield* validateChatroomIdEffect(chatroomId, (id3) => ({
|
|
111015
|
-
_tag: "InvalidChatroomId",
|
|
111016
|
-
id: id3
|
|
111017
|
-
}));
|
|
111361
|
+
const sessionId = yield* requireSessionForChatroomEffect({ chatroomId });
|
|
111018
111362
|
const artifact = yield* backend2.query(api.artifacts.get, {
|
|
111019
111363
|
sessionId,
|
|
111020
111364
|
artifactId: options.artifactId
|
|
@@ -111040,15 +111384,7 @@ var createArtifactEffect = (chatroomId, options) => exports_Effect.gen(function*
|
|
|
111040
111384
|
});
|
|
111041
111385
|
}), viewManyArtifactsEffect = (chatroomId, options) => exports_Effect.gen(function* () {
|
|
111042
111386
|
const backend2 = yield* BackendService;
|
|
111043
|
-
const sessionId = yield*
|
|
111044
|
-
_tag: "NotAuthenticated",
|
|
111045
|
-
convexUrl: a.convexUrl,
|
|
111046
|
-
otherUrls: a.otherUrls
|
|
111047
|
-
}));
|
|
111048
|
-
yield* validateChatroomIdEffect(chatroomId, (id3) => ({
|
|
111049
|
-
_tag: "InvalidChatroomId",
|
|
111050
|
-
id: id3
|
|
111051
|
-
}));
|
|
111387
|
+
const sessionId = yield* requireSessionForChatroomEffect({ chatroomId });
|
|
111052
111388
|
if (options.artifactIds.length === 0) {
|
|
111053
111389
|
return yield* exports_Effect.fail({ _tag: "NoArtifactIds" });
|
|
111054
111390
|
}
|
|
@@ -111446,12 +111782,12 @@ var init_durable_fifo_queue_schema = __esm(() => {
|
|
|
111446
111782
|
});
|
|
111447
111783
|
|
|
111448
111784
|
// src/daemon/infrastructure/outbox/lib/durable-fifo-queue-store.ts
|
|
111449
|
-
import { mkdirSync as
|
|
111450
|
-
import { dirname as
|
|
111451
|
-
import { DatabaseSync as
|
|
111785
|
+
import { mkdirSync as mkdirSync8 } from "node:fs";
|
|
111786
|
+
import { dirname as dirname11 } from "node:path";
|
|
111787
|
+
import { DatabaseSync as DatabaseSync3 } from "node:sqlite";
|
|
111452
111788
|
function openDurableFifoQueueStore(dbPath) {
|
|
111453
|
-
|
|
111454
|
-
const db = new
|
|
111789
|
+
mkdirSync8(dirname11(dbPath), { recursive: true });
|
|
111790
|
+
const db = new DatabaseSync3(dbPath);
|
|
111455
111791
|
for (const sql of DURABLE_FIFO_QUEUE_MIGRATIONS)
|
|
111456
111792
|
db.exec(sql);
|
|
111457
111793
|
db.prepare("UPDATE fifo_outbox_entries SET status='pending', updated_at=? WHERE status='in_flight'").run(Date.now());
|
|
@@ -111868,7 +112204,8 @@ var AgentLifecycleOutboxService, AgentLifecycleOutboxServiceLive = (registry3, m
|
|
|
111868
112204
|
resumeTurnForSlot: (args2) => exports_Effect.promise(() => mgr.resumeTurnForSlot(args2)),
|
|
111869
112205
|
subscribeAgentTurnEnded: (handler) => processManagerService.subscribeAgentTurnEnded(handler),
|
|
111870
112206
|
subscribeAgentStarted: (handler) => processManagerService.subscribeAgentStarted(handler),
|
|
111871
|
-
subscribeAgentSessionLost: (handler) => processManagerService.subscribeAgentSessionLost(handler)
|
|
112207
|
+
subscribeAgentSessionLost: (handler) => processManagerService.subscribeAgentSessionLost(handler),
|
|
112208
|
+
subscribeAgentTurnProgress: (handler) => processManagerService.subscribeAgentTurnProgress(handler)
|
|
111872
112209
|
}), DaemonAgentProcessManagerCommandService, DaemonAgentProcessManagerCommandServiceLive = (service4) => exports_Layer.succeed(DaemonAgentProcessManagerCommandService, service4), DaemonSessionService, DaemonMutableStateService;
|
|
111873
112210
|
var init_daemon_services = __esm(() => {
|
|
111874
112211
|
init_esm();
|
|
@@ -112162,6 +112499,14 @@ var init_output_store = __esm(() => {
|
|
|
112162
112499
|
RUN_ID_RE = /^[a-z0-9]+$/i;
|
|
112163
112500
|
});
|
|
112164
112501
|
|
|
112502
|
+
// src/daemon/entry/task-handoff-repository-path.ts
|
|
112503
|
+
import { homedir as homedir9 } from "node:os";
|
|
112504
|
+
import { join as join22 } from "node:path";
|
|
112505
|
+
function resolveTaskHandoffRepositoryPath(machineId) {
|
|
112506
|
+
return join22(homedir9(), ".chatroom", "daemon", machineId, "task-handoffs.sqlite");
|
|
112507
|
+
}
|
|
112508
|
+
var init_task_handoff_repository_path = () => {};
|
|
112509
|
+
|
|
112165
112510
|
// src/infrastructure/services/harness-spawning/rate-limiter.ts
|
|
112166
112511
|
class SpawnRateLimiter {
|
|
112167
112512
|
config;
|
|
@@ -112617,6 +112962,7 @@ function assembleDaemonSessionInit(args2) {
|
|
|
112617
112962
|
convexUrl,
|
|
112618
112963
|
backend: deps.backend,
|
|
112619
112964
|
configurationService: agentConfigRegistry,
|
|
112965
|
+
handoffRepository: createTaskHandoffRepository(resolveTaskHandoffRepositoryPath(machineId)),
|
|
112620
112966
|
logEvent: activeLogEvent ?? (async () => {
|
|
112621
112967
|
return;
|
|
112622
112968
|
})
|
|
@@ -112657,9 +113003,6 @@ class NetworkRetryError {
|
|
|
112657
113003
|
this.attempt = attempt;
|
|
112658
113004
|
}
|
|
112659
113005
|
}
|
|
112660
|
-
function getActiveLogSink() {
|
|
112661
|
-
return activeLogSink;
|
|
112662
|
-
}
|
|
112663
113006
|
async function initDaemon(options = {}) {
|
|
112664
113007
|
activeLogSink = options.logSink;
|
|
112665
113008
|
activeLogEvent = options.logEvent;
|
|
@@ -112860,6 +113203,7 @@ var init_init_daemon = __esm(() => {
|
|
|
112860
113203
|
init_daemon_startup_log();
|
|
112861
113204
|
init_orphan_tracker();
|
|
112862
113205
|
init_output_store();
|
|
113206
|
+
init_task_handoff_repository_path();
|
|
112863
113207
|
init_pid();
|
|
112864
113208
|
init_storage();
|
|
112865
113209
|
init_client2();
|
|
@@ -112874,6 +113218,7 @@ var init_init_daemon = __esm(() => {
|
|
|
112874
113218
|
init_agent_process_service2();
|
|
112875
113219
|
init_chatroom_workspace_configuration_service();
|
|
112876
113220
|
init_service_interfaces();
|
|
113221
|
+
init_task_service2();
|
|
112877
113222
|
AUTH_WAIT_TIMEOUT_MS = 5 * 60 * 1000;
|
|
112878
113223
|
initDaemonEffect = exports_Effect.gen(function* () {
|
|
112879
113224
|
const lockAcquired = yield* exports_Effect.tryPromise({
|
|
@@ -117228,16 +117573,16 @@ var MAX_NAME_LENGTH = 256;
|
|
|
117228
117573
|
|
|
117229
117574
|
// src/infrastructure/services/workspace/workspace-resolver.ts
|
|
117230
117575
|
import { readFile as readFile7, readdir, stat as stat4 } from "node:fs/promises";
|
|
117231
|
-
import { join as
|
|
117576
|
+
import { join as join23, basename, resolve as resolve4 } from "node:path";
|
|
117232
117577
|
async function resolveGlobPatternStar(rootDir, cleaned) {
|
|
117233
|
-
const parentDir =
|
|
117578
|
+
const parentDir = join23(rootDir, cleaned.slice(0, -2));
|
|
117234
117579
|
try {
|
|
117235
117580
|
const entries2 = await readdir(parentDir, { withFileTypes: true });
|
|
117236
117581
|
const dirs = [];
|
|
117237
117582
|
for (const entry of entries2) {
|
|
117238
117583
|
if (!entry.isDirectory())
|
|
117239
117584
|
continue;
|
|
117240
|
-
const dirPath =
|
|
117585
|
+
const dirPath = join23(parentDir, entry.name);
|
|
117241
117586
|
if (resolve4(dirPath).startsWith(resolve4(rootDir))) {
|
|
117242
117587
|
dirs.push(dirPath);
|
|
117243
117588
|
}
|
|
@@ -117248,7 +117593,7 @@ async function resolveGlobPatternStar(rootDir, cleaned) {
|
|
|
117248
117593
|
}
|
|
117249
117594
|
}
|
|
117250
117595
|
async function resolveLiteralPath(rootDir, cleaned) {
|
|
117251
|
-
const dir =
|
|
117596
|
+
const dir = join23(rootDir, cleaned);
|
|
117252
117597
|
try {
|
|
117253
117598
|
if (!resolve4(dir).startsWith(resolve4(rootDir)))
|
|
117254
117599
|
return [];
|
|
@@ -117268,7 +117613,7 @@ async function resolveGlobPattern(rootDir, pattern) {
|
|
|
117268
117613
|
}
|
|
117269
117614
|
async function readPackageJson(dir) {
|
|
117270
117615
|
try {
|
|
117271
|
-
const content = await readFile7(
|
|
117616
|
+
const content = await readFile7(join23(dir, "package.json"), "utf-8");
|
|
117272
117617
|
const pkg = JSON.parse(content);
|
|
117273
117618
|
return {
|
|
117274
117619
|
name: pkg.name || basename(dir),
|
|
@@ -117280,7 +117625,7 @@ async function readPackageJson(dir) {
|
|
|
117280
117625
|
}
|
|
117281
117626
|
async function readPnpmWorkspacePatterns(rootDir) {
|
|
117282
117627
|
try {
|
|
117283
|
-
const content = await readFile7(
|
|
117628
|
+
const content = await readFile7(join23(rootDir, "pnpm-workspace.yaml"), "utf-8");
|
|
117284
117629
|
const patterns = [];
|
|
117285
117630
|
let inPackages = false;
|
|
117286
117631
|
for (const line of content.split(`
|
|
@@ -117307,7 +117652,7 @@ async function readPnpmWorkspacePatterns(rootDir) {
|
|
|
117307
117652
|
}
|
|
117308
117653
|
async function readPackageJsonWorkspacePatterns(rootDir) {
|
|
117309
117654
|
try {
|
|
117310
|
-
const content = await readFile7(
|
|
117655
|
+
const content = await readFile7(join23(rootDir, "package.json"), "utf-8");
|
|
117311
117656
|
const pkg = JSON.parse(content);
|
|
117312
117657
|
if (!pkg.workspaces)
|
|
117313
117658
|
return [];
|
|
@@ -117356,11 +117701,11 @@ var init_workspace_resolver = () => {};
|
|
|
117356
117701
|
|
|
117357
117702
|
// src/infrastructure/services/workspace/command-discovery.ts
|
|
117358
117703
|
import { access as access2, readFile as readFile8 } from "node:fs/promises";
|
|
117359
|
-
import { join as
|
|
117704
|
+
import { join as join24, relative, basename as basename2 } from "node:path";
|
|
117360
117705
|
async function detectPackageManager(workingDir) {
|
|
117361
117706
|
for (const { file: file2, manager } of LOCKFILE_MAP) {
|
|
117362
117707
|
try {
|
|
117363
|
-
await access2(
|
|
117708
|
+
await access2(join24(workingDir, file2));
|
|
117364
117709
|
return manager;
|
|
117365
117710
|
} catch {}
|
|
117366
117711
|
}
|
|
@@ -117429,7 +117774,7 @@ function collectRootScriptCommands(scripts, pm, scriptPrefix, rootSw) {
|
|
|
117429
117774
|
}
|
|
117430
117775
|
async function readRootPackageJson(workingDir, pm, scriptPrefix) {
|
|
117431
117776
|
let rootPackageName = basename2(workingDir);
|
|
117432
|
-
const pkg = await readJsonFile(
|
|
117777
|
+
const pkg = await readJsonFile(join24(workingDir, "package.json"), "root package.json");
|
|
117433
117778
|
if (!pkg)
|
|
117434
117779
|
return { commands: [], rootPackageName };
|
|
117435
117780
|
if (pkg.name)
|
|
@@ -117445,7 +117790,7 @@ async function readRootPackageJson(workingDir, pm, scriptPrefix) {
|
|
|
117445
117790
|
}
|
|
117446
117791
|
async function readTurboJson(workingDir, _turboPrefix, _rootSubWorkspace) {
|
|
117447
117792
|
const turboTaskNames = [];
|
|
117448
|
-
const turbo = await readJsonFile(
|
|
117793
|
+
const turbo = await readJsonFile(join24(workingDir, "turbo.json"), "turbo.json");
|
|
117449
117794
|
if (!turbo?.tasks || typeof turbo.tasks !== "object")
|
|
117450
117795
|
return turboTaskNames;
|
|
117451
117796
|
for (const taskName of Object.keys(turbo.tasks)) {
|
|
@@ -117458,7 +117803,7 @@ async function readTurboJson(workingDir, _turboPrefix, _rootSubWorkspace) {
|
|
|
117458
117803
|
async function readDenoJson(workingDir) {
|
|
117459
117804
|
const commands = [];
|
|
117460
117805
|
for (const fileName of ["deno.json", "deno.jsonc"]) {
|
|
117461
|
-
const deno = await readJsonFile(
|
|
117806
|
+
const deno = await readJsonFile(join24(workingDir, fileName), fileName);
|
|
117462
117807
|
if (!deno?.tasks || typeof deno.tasks !== "object")
|
|
117463
117808
|
continue;
|
|
117464
117809
|
const pkgName = deno.name ?? basename2(workingDir);
|
|
@@ -117481,7 +117826,7 @@ async function readMakefile(workingDir) {
|
|
|
117481
117826
|
const commands = [];
|
|
117482
117827
|
for (const fileName of ["Makefile", "makefile"]) {
|
|
117483
117828
|
try {
|
|
117484
|
-
const content = await readFile8(
|
|
117829
|
+
const content = await readFile8(join24(workingDir, fileName), "utf-8");
|
|
117485
117830
|
const targets = parseMakefileTargets(content);
|
|
117486
117831
|
if (targets.length === 0)
|
|
117487
117832
|
continue;
|
|
@@ -118056,7 +118401,7 @@ async function runRestartOrchestrator(deps, event) {
|
|
|
118056
118401
|
const { chatroomId, role } = event;
|
|
118057
118402
|
markRestartOrchestratorInFlight(chatroomId, role, event.correlationId);
|
|
118058
118403
|
try {
|
|
118059
|
-
|
|
118404
|
+
await deps.nativeDelivery.handleAgentRestart({ chatroomId, role });
|
|
118060
118405
|
await emitPhase(deps, event, "reset");
|
|
118061
118406
|
await emitPhase(deps, event, "spawn");
|
|
118062
118407
|
const spawnResult = await deps.runSerializedForAgent({ chatroomId, role, workingDir: event.workingDir }, { timeoutMs: HARNESS_SESSION_READY_TIMEOUT_MS }, async (ops, context5) => {
|
|
@@ -118117,7 +118462,6 @@ var init_restart_orchestrator = __esm(() => {
|
|
|
118117
118462
|
init_api3();
|
|
118118
118463
|
init_convex_error();
|
|
118119
118464
|
init_execution_kind();
|
|
118120
|
-
init_service_interfaces();
|
|
118121
118465
|
});
|
|
118122
118466
|
|
|
118123
118467
|
// src/daemon/entry/bridge/agent-control-bridge.ts
|
|
@@ -118272,19 +118616,6 @@ async function startAgent2(deps, input) {
|
|
|
118272
118616
|
});
|
|
118273
118617
|
}
|
|
118274
118618
|
|
|
118275
|
-
// src/daemon/entry/enhancer/enhancer-drain-registry.ts
|
|
118276
|
-
function setEnhancerDrainHandler(fn2) {
|
|
118277
|
-
drainFn = fn2;
|
|
118278
|
-
}
|
|
118279
|
-
async function drainPendingEnhancerJobsIfRegistered() {
|
|
118280
|
-
if (drainFn)
|
|
118281
|
-
await drainFn();
|
|
118282
|
-
}
|
|
118283
|
-
function clearEnhancerDrainHandlerForTests() {
|
|
118284
|
-
drainFn = null;
|
|
118285
|
-
}
|
|
118286
|
-
var drainFn = null;
|
|
118287
|
-
|
|
118288
118619
|
// src/daemon/entry/events/agent/on-request-start-agent.ts
|
|
118289
118620
|
var onRequestStartAgentEffect = (event) => exports_Effect.gen(function* () {
|
|
118290
118621
|
const processManagerService = yield* DaemonAgentProcessManagerCommandService;
|
|
@@ -118301,7 +118632,6 @@ var onRequestStartAgentEffect = (event) => exports_Effect.gen(function* () {
|
|
|
118301
118632
|
deadline: event.deadline,
|
|
118302
118633
|
wantResume: event.wantResume
|
|
118303
118634
|
});
|
|
118304
|
-
await drainPendingEnhancerJobsIfRegistered();
|
|
118305
118635
|
});
|
|
118306
118636
|
});
|
|
118307
118637
|
var init_on_request_start_agent = __esm(() => {
|
|
@@ -118637,435 +118967,19 @@ async function dispatchCommandInboundEvent(event) {
|
|
|
118637
118967
|
}
|
|
118638
118968
|
var handler2;
|
|
118639
118969
|
|
|
118640
|
-
// src/daemon/entry/
|
|
118641
|
-
|
|
118642
|
-
|
|
118643
|
-
// src/daemon/entry/enhancer/enhancer-log.ts
|
|
118644
|
-
function formatEnhancerLogLine(message) {
|
|
118645
|
-
const trimmed = message.trimEnd();
|
|
118646
|
-
if (trimmed.startsWith(ENHANCER_LOG_PREFIX))
|
|
118647
|
-
return trimmed;
|
|
118648
|
-
return `${ENHANCER_LOG_PREFIX} ${trimmed}`;
|
|
118649
|
-
}
|
|
118650
|
-
function createEnhancerLogWriter(logSink, context5, clock4 = () => Date.now()) {
|
|
118651
|
-
return {
|
|
118652
|
-
write(message) {
|
|
118653
|
-
const formatted = formatEnhancerLogLine(message);
|
|
118654
|
-
logSink?.write({
|
|
118655
|
-
timestamp: clock4(),
|
|
118656
|
-
level: "info",
|
|
118657
|
-
source: `harness:${context5.harness}`,
|
|
118658
|
-
stream: "stdout",
|
|
118659
|
-
message: formatted,
|
|
118660
|
-
metadata: {
|
|
118661
|
-
chatroomId: context5.chatroomId,
|
|
118662
|
-
role: ENHANCER_AGENT_ROLE,
|
|
118663
|
-
harness: context5.harness,
|
|
118664
|
-
...context5.pid !== undefined ? { pid: context5.pid } : {}
|
|
118665
|
-
}
|
|
118666
|
-
});
|
|
118667
|
-
}
|
|
118668
|
-
};
|
|
118669
|
-
}
|
|
118670
|
-
var ENHANCER_LOG_PREFIX = "[enhancer]";
|
|
118671
|
-
var init_enhancer_log = () => {};
|
|
118672
|
-
|
|
118673
|
-
// src/daemon/entry/enhancer/enhancer-spawn-registry.ts
|
|
118674
|
-
function registerEnhancerSpawn(handle) {
|
|
118675
|
-
const handles = byChatroom.get(handle.chatroomId) ?? new Set;
|
|
118676
|
-
handles.add(handle);
|
|
118677
|
-
byChatroom.set(handle.chatroomId, handles);
|
|
118678
|
-
}
|
|
118679
|
-
function unregisterEnhancerSpawn(handle) {
|
|
118680
|
-
const handles = byChatroom.get(handle.chatroomId);
|
|
118681
|
-
if (!handles)
|
|
118682
|
-
return;
|
|
118683
|
-
handles.delete(handle);
|
|
118684
|
-
if (handles.size === 0)
|
|
118685
|
-
byChatroom.delete(handle.chatroomId);
|
|
118686
|
-
}
|
|
118687
|
-
async function abortEnhancerSpawnsForChatroom(chatroomId) {
|
|
118688
|
-
const handles = byChatroom.get(chatroomId);
|
|
118689
|
-
if (!handles)
|
|
118690
|
-
return;
|
|
118691
|
-
await Promise.all([...handles].map(async (handle) => {
|
|
118692
|
-
handle.abort();
|
|
118693
|
-
await handle.stopProcess().catch(() => {
|
|
118694
|
-
return;
|
|
118695
|
-
});
|
|
118696
|
-
}));
|
|
118697
|
-
}
|
|
118698
|
-
var byChatroom;
|
|
118699
|
-
var init_enhancer_spawn_registry = __esm(() => {
|
|
118700
|
-
byChatroom = new Map;
|
|
118701
|
-
});
|
|
118702
|
-
|
|
118703
|
-
// src/daemon/entry/enhancer/job-outcome-subscription.ts
|
|
118704
|
-
function subscribeToEnhancerJobOutcome(args2) {
|
|
118705
|
-
let currentState = null;
|
|
118706
|
-
let resolveOutcome = null;
|
|
118707
|
-
let rejectOutcome = null;
|
|
118708
|
-
let stopped = false;
|
|
118709
|
-
const outcome = new Promise((resolve5, reject) => {
|
|
118710
|
-
resolveOutcome = resolve5;
|
|
118711
|
-
rejectOutcome = reject;
|
|
118712
|
-
});
|
|
118713
|
-
const unsub = args2.wsClient.onUpdate(api.web.enhancer.index.getJobOutcome, {
|
|
118714
|
-
sessionId: args2.sessionId,
|
|
118715
|
-
chatroomId: args2.chatroomId,
|
|
118716
|
-
jobId: args2.jobId
|
|
118717
|
-
}, (state) => {
|
|
118718
|
-
if (stopped)
|
|
118719
|
-
return;
|
|
118720
|
-
if (!state) {
|
|
118721
|
-
rejectOutcome?.(new Error("Enhancer job not found"));
|
|
118722
|
-
resolveOutcome = null;
|
|
118723
|
-
rejectOutcome = null;
|
|
118724
|
-
return;
|
|
118725
|
-
}
|
|
118726
|
-
currentState = state;
|
|
118727
|
-
if (state.status === "complete" || state.status === "failed" || state.status === "cancelled") {
|
|
118728
|
-
resolveOutcome?.(state);
|
|
118729
|
-
resolveOutcome = null;
|
|
118730
|
-
rejectOutcome = null;
|
|
118731
|
-
}
|
|
118732
|
-
}, (error51) => {
|
|
118733
|
-
if (stopped)
|
|
118734
|
-
return;
|
|
118735
|
-
rejectOutcome?.(error51);
|
|
118736
|
-
resolveOutcome = null;
|
|
118737
|
-
rejectOutcome = null;
|
|
118738
|
-
});
|
|
118739
|
-
return {
|
|
118740
|
-
outcome,
|
|
118741
|
-
getCurrentState: () => currentState,
|
|
118742
|
-
stop: () => {
|
|
118743
|
-
if (stopped)
|
|
118744
|
-
return;
|
|
118745
|
-
stopped = true;
|
|
118746
|
-
unsub();
|
|
118747
|
-
resolveOutcome = null;
|
|
118748
|
-
rejectOutcome = null;
|
|
118749
|
-
}
|
|
118750
|
-
};
|
|
118751
|
-
}
|
|
118752
|
-
var init_job_outcome_subscription = __esm(() => {
|
|
118753
|
-
init_api3();
|
|
118754
|
-
});
|
|
118755
|
-
|
|
118756
|
-
// src/daemon/entry/enhancer/wait-for-enhancer-job.ts
|
|
118757
|
-
async function waitForEnhancerJobResolution(params) {
|
|
118758
|
-
const { sessionId, chatroomId, jobId, wsClient: wsClient2, onFailure, onSalvageComplete, log: log4, signal } = params;
|
|
118759
|
-
const writeLog = (message) => log4?.write(message);
|
|
118760
|
-
let outcome = null;
|
|
118761
|
-
let salvagedText = "";
|
|
118762
|
-
let agentEndTimer = null;
|
|
118763
|
-
let resolveWait = null;
|
|
118764
|
-
const waitPromise = new Promise((resolve5) => {
|
|
118765
|
-
resolveWait = resolve5;
|
|
118766
|
-
});
|
|
118767
|
-
const subscription = subscribeToEnhancerJobOutcome({
|
|
118768
|
-
wsClient: wsClient2,
|
|
118769
|
-
sessionId,
|
|
118770
|
-
chatroomId,
|
|
118771
|
-
jobId
|
|
118772
|
-
});
|
|
118773
|
-
const finish = (resolution) => {
|
|
118774
|
-
if (outcome)
|
|
118775
|
-
return;
|
|
118776
|
-
outcome = resolution;
|
|
118777
|
-
resolveWait?.();
|
|
118778
|
-
resolveWait = null;
|
|
118779
|
-
};
|
|
118780
|
-
const onAbort = () => finish("aborted");
|
|
118781
|
-
if (signal?.aborted)
|
|
118782
|
-
onAbort();
|
|
118783
|
-
else
|
|
118784
|
-
signal?.addEventListener("abort", onAbort, { once: true });
|
|
118785
|
-
const failAfterAgentEnd = () => {
|
|
118786
|
-
writeLog("agent_end: turn ended without complete — failing terminal");
|
|
118787
|
-
onFailure("Agent exited without completing enhancer job", true);
|
|
118788
|
-
finish("failed");
|
|
118789
|
-
};
|
|
118790
|
-
subscription.outcome.then((state) => {
|
|
118791
|
-
if (outcome)
|
|
118792
|
-
return;
|
|
118793
|
-
const resolution = state.status === "complete" ? "complete" : "failed";
|
|
118794
|
-
if (resolution === "complete")
|
|
118795
|
-
writeLog(`completed job=${jobId}`);
|
|
118796
|
-
finish(resolution);
|
|
118797
|
-
}).catch((error51) => {
|
|
118798
|
-
if (outcome)
|
|
118799
|
-
return;
|
|
118800
|
-
writeLog(`enhancer outcome subscription failed: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
118801
|
-
onFailure("Enhancer job outcome subscription failed", false);
|
|
118802
|
-
finish("failed");
|
|
118803
|
-
});
|
|
118804
|
-
params.onAssistantText?.((text) => {
|
|
118805
|
-
salvagedText += text;
|
|
118806
|
-
});
|
|
118807
|
-
params.onAgentEnd?.(() => {
|
|
118808
|
-
if (outcome)
|
|
118809
|
-
return;
|
|
118810
|
-
agentEndTimer = setTimeout(() => {
|
|
118811
|
-
if (outcome)
|
|
118812
|
-
return;
|
|
118813
|
-
const state = subscription.getCurrentState();
|
|
118814
|
-
if (state?.status === "complete") {
|
|
118815
|
-
finish("complete");
|
|
118816
|
-
return;
|
|
118817
|
-
}
|
|
118818
|
-
if (state?.status !== "running") {
|
|
118819
|
-
failAfterAgentEnd();
|
|
118820
|
-
return;
|
|
118821
|
-
}
|
|
118822
|
-
const trimmed = salvagedText.trim();
|
|
118823
|
-
if (!trimmed || !onSalvageComplete) {
|
|
118824
|
-
failAfterAgentEnd();
|
|
118825
|
-
return;
|
|
118826
|
-
}
|
|
118827
|
-
onSalvageComplete(trimmed).catch(() => {
|
|
118828
|
-
failAfterAgentEnd();
|
|
118829
|
-
});
|
|
118830
|
-
}, ENHANCER_AGENT_END_GRACE_MS);
|
|
118831
|
-
});
|
|
118832
|
-
params.onExit(() => {
|
|
118833
|
-
if (outcome)
|
|
118834
|
-
return;
|
|
118835
|
-
onFailure("Agent process exited without completing enhancer job", false);
|
|
118836
|
-
finish("failed");
|
|
118837
|
-
});
|
|
118838
|
-
await waitPromise;
|
|
118839
|
-
if (agentEndTimer)
|
|
118840
|
-
clearTimeout(agentEndTimer);
|
|
118841
|
-
subscription.stop();
|
|
118842
|
-
signal?.removeEventListener("abort", onAbort);
|
|
118843
|
-
return outcome ?? "failed";
|
|
118844
|
-
}
|
|
118845
|
-
var init_wait_for_enhancer_job = __esm(() => {
|
|
118846
|
-
init_job_outcome_subscription();
|
|
118847
|
-
});
|
|
118848
|
-
|
|
118849
|
-
// src/daemon/entry/enhancer-inbound-registry.ts
|
|
118850
|
-
function registerEnhancerInboundHandler(h) {
|
|
118970
|
+
// src/daemon/entry/file-inbound-registry.ts
|
|
118971
|
+
function registerFileInboundHandler(h) {
|
|
118851
118972
|
handler3 = h;
|
|
118852
118973
|
}
|
|
118853
|
-
function
|
|
118974
|
+
function unregisterFileInboundHandler() {
|
|
118854
118975
|
handler3 = undefined;
|
|
118855
118976
|
}
|
|
118856
|
-
async function
|
|
118977
|
+
async function dispatchFileInboundEvent(event) {
|
|
118857
118978
|
if (handler3)
|
|
118858
118979
|
await handler3(event);
|
|
118859
118980
|
}
|
|
118860
118981
|
var handler3;
|
|
118861
118982
|
|
|
118862
|
-
// src/daemon/entry/enhancer/job-subscriber.ts
|
|
118863
|
-
async function processEnhancerJobForSpawn(sessionId, machineId, convexUrl, wsClient2, backend2, agentServices, job, inFlight2, logSink) {
|
|
118864
|
-
if (inFlight2.has(job.jobId))
|
|
118865
|
-
return;
|
|
118866
|
-
if (isChatroomStopScopeActive(job.chatroomId))
|
|
118867
|
-
return;
|
|
118868
|
-
inFlight2.add(job.jobId);
|
|
118869
|
-
let claimed = false;
|
|
118870
|
-
let chatroomId = job.chatroomId;
|
|
118871
|
-
let jobId = job.jobId;
|
|
118872
|
-
let spawnResult = null;
|
|
118873
|
-
let service4 = null;
|
|
118874
|
-
let abortController = null;
|
|
118875
|
-
let spawnHandle = null;
|
|
118876
|
-
let agentEndSeen = false;
|
|
118877
|
-
let resolveAgentEnd;
|
|
118878
|
-
let agentEndPromise = Promise.resolve();
|
|
118879
|
-
let log4 = createEnhancerLogWriter(logSink, {
|
|
118880
|
-
chatroomId: job.chatroomId,
|
|
118881
|
-
harness: "unknown"
|
|
118882
|
-
});
|
|
118883
|
-
try {
|
|
118884
|
-
const claim = await backend2.mutation(api.daemon.enhancer.index.claimForSpawn, {
|
|
118885
|
-
sessionId,
|
|
118886
|
-
jobId: job.jobId,
|
|
118887
|
-
machineId
|
|
118888
|
-
});
|
|
118889
|
-
if (!claim.claimed)
|
|
118890
|
-
return;
|
|
118891
|
-
claimed = true;
|
|
118892
|
-
log4.write(`claimed job=${job.jobId} chatroom=${job.chatroomId}`);
|
|
118893
|
-
const payload = await backend2.query(api.daemon.enhancer.index.getTaskDeliveryForJob, {
|
|
118894
|
-
sessionId,
|
|
118895
|
-
jobId: job.jobId,
|
|
118896
|
-
convexUrl
|
|
118897
|
-
});
|
|
118898
|
-
chatroomId = payload.chatroomId;
|
|
118899
|
-
jobId = payload.jobId;
|
|
118900
|
-
log4 = createEnhancerLogWriter(logSink, {
|
|
118901
|
-
chatroomId: payload.chatroomId,
|
|
118902
|
-
harness: payload.agentHarness,
|
|
118903
|
-
pid: undefined
|
|
118904
|
-
});
|
|
118905
|
-
log4.write(`spawning harness=${payload.agentHarness} model=${payload.model} job=${payload.jobId}`);
|
|
118906
|
-
service4 = agentServices.get(payload.agentHarness) ?? null;
|
|
118907
|
-
if (!service4) {
|
|
118908
|
-
await backend2.mutation(api.web.enhancer.index.recordAttemptFailure, {
|
|
118909
|
-
sessionId,
|
|
118910
|
-
chatroomId: payload.chatroomId,
|
|
118911
|
-
jobId: payload.jobId,
|
|
118912
|
-
error: `Harness ${payload.agentHarness} not available on machine`
|
|
118913
|
-
});
|
|
118914
|
-
return;
|
|
118915
|
-
}
|
|
118916
|
-
const spawned = await service4.spawn({
|
|
118917
|
-
workingDir: payload.workingDir,
|
|
118918
|
-
prompt: createSpawnPrompt(payload.taskDeliveryOutput),
|
|
118919
|
-
systemPrompt: payload.systemPrompt,
|
|
118920
|
-
model: payload.model,
|
|
118921
|
-
context: {
|
|
118922
|
-
machineId,
|
|
118923
|
-
chatroomId: payload.chatroomId,
|
|
118924
|
-
role: ENHANCER_AGENT_ROLE
|
|
118925
|
-
},
|
|
118926
|
-
resolvedConvexUrl: convexUrl
|
|
118927
|
-
});
|
|
118928
|
-
spawnResult = spawned;
|
|
118929
|
-
abortController = new AbortController;
|
|
118930
|
-
spawnHandle = {
|
|
118931
|
-
jobId: payload.jobId,
|
|
118932
|
-
chatroomId: payload.chatroomId,
|
|
118933
|
-
abort: () => abortController?.abort(),
|
|
118934
|
-
stopProcess: async () => {
|
|
118935
|
-
await service4?.stop(spawned.pid);
|
|
118936
|
-
}
|
|
118937
|
-
};
|
|
118938
|
-
registerEnhancerSpawn(spawnHandle);
|
|
118939
|
-
log4 = createEnhancerLogWriter(logSink, {
|
|
118940
|
-
chatroomId: payload.chatroomId,
|
|
118941
|
-
harness: payload.agentHarness,
|
|
118942
|
-
pid: spawned.pid
|
|
118943
|
-
});
|
|
118944
|
-
spawned.onLogLine?.((line) => {
|
|
118945
|
-
log4.write(line);
|
|
118946
|
-
});
|
|
118947
|
-
agentEndPromise = new Promise((resolve5) => {
|
|
118948
|
-
resolveAgentEnd = resolve5;
|
|
118949
|
-
});
|
|
118950
|
-
spawned.onAgentEnd?.(() => {
|
|
118951
|
-
if (agentEndSeen)
|
|
118952
|
-
return;
|
|
118953
|
-
agentEndSeen = true;
|
|
118954
|
-
resolveAgentEnd?.();
|
|
118955
|
-
});
|
|
118956
|
-
await waitForEnhancerJobResolution({
|
|
118957
|
-
sessionId,
|
|
118958
|
-
chatroomId: payload.chatroomId,
|
|
118959
|
-
jobId: payload.jobId,
|
|
118960
|
-
wsClient: wsClient2,
|
|
118961
|
-
log: log4,
|
|
118962
|
-
onAssistantText: spawned.onAssistantText ? (cb) => spawned.onAssistantText?.(cb) : undefined,
|
|
118963
|
-
onAgentEnd: spawned.onAgentEnd ? (cb) => spawned.onAgentEnd?.(cb) : undefined,
|
|
118964
|
-
onExit: (cb) => spawned.onExit(() => cb()),
|
|
118965
|
-
onSalvageComplete: async (content) => {
|
|
118966
|
-
await backend2.mutation(api.web.enhancer.index.complete, {
|
|
118967
|
-
sessionId,
|
|
118968
|
-
chatroomId: payload.chatroomId,
|
|
118969
|
-
jobId: payload.jobId,
|
|
118970
|
-
enhancedContent: content
|
|
118971
|
-
});
|
|
118972
|
-
},
|
|
118973
|
-
onFailure: async (error51, forceTerminal) => {
|
|
118974
|
-
await backend2.mutation(api.web.enhancer.index.recordAttemptFailure, {
|
|
118975
|
-
sessionId,
|
|
118976
|
-
chatroomId: payload.chatroomId,
|
|
118977
|
-
jobId: payload.jobId,
|
|
118978
|
-
error: error51,
|
|
118979
|
-
...forceTerminal ? { forceTerminal: true } : {}
|
|
118980
|
-
});
|
|
118981
|
-
},
|
|
118982
|
-
signal: abortController.signal
|
|
118983
|
-
});
|
|
118984
|
-
if (!abortController.signal.aborted)
|
|
118985
|
-
log4.write(`completed job=${jobId}`);
|
|
118986
|
-
} catch (err) {
|
|
118987
|
-
log4.write(`error: ${err instanceof Error ? err.message : String(err)}`);
|
|
118988
|
-
if (claimed) {
|
|
118989
|
-
await backend2.mutation(api.web.enhancer.index.recordAttemptFailure, {
|
|
118990
|
-
sessionId,
|
|
118991
|
-
chatroomId,
|
|
118992
|
-
jobId,
|
|
118993
|
-
error: err instanceof Error ? err.message : String(err)
|
|
118994
|
-
});
|
|
118995
|
-
}
|
|
118996
|
-
} finally {
|
|
118997
|
-
inFlight2.delete(job.jobId);
|
|
118998
|
-
if (spawnHandle)
|
|
118999
|
-
unregisterEnhancerSpawn(spawnHandle);
|
|
119000
|
-
if (spawnResult && service4) {
|
|
119001
|
-
if (!agentEndSeen)
|
|
119002
|
-
await Promise.race([
|
|
119003
|
-
agentEndPromise,
|
|
119004
|
-
new Promise((resolve5) => setTimeout(resolve5, ENHANCER_AGENT_END_GRACE_MS))
|
|
119005
|
-
]);
|
|
119006
|
-
try {
|
|
119007
|
-
await service4.stop(spawnResult.pid);
|
|
119008
|
-
} catch {}
|
|
119009
|
-
}
|
|
119010
|
-
}
|
|
119011
|
-
}
|
|
119012
|
-
function processEnhancerJobs(sessionId, machineId, convexUrl, wsClient2, backend2, agentServices, jobs, inFlight2, logSink) {
|
|
119013
|
-
for (const job of jobs ?? []) {
|
|
119014
|
-
processEnhancerJobForSpawn(sessionId, machineId, convexUrl, wsClient2, backend2, agentServices, job, inFlight2, logSink);
|
|
119015
|
-
}
|
|
119016
|
-
}
|
|
119017
|
-
async function drainPendingEnhancerJobs(sessionId, machineId, convexUrl, wsClient2, backend2, agentServices, inFlight2, logSink) {
|
|
119018
|
-
const jobs = await backend2.query(api.daemon.enhancer.index.pendingForMachine, {
|
|
119019
|
-
sessionId,
|
|
119020
|
-
machineId
|
|
119021
|
-
});
|
|
119022
|
-
if (!jobs?.length)
|
|
119023
|
-
return;
|
|
119024
|
-
processEnhancerJobs(sessionId, machineId, convexUrl, wsClient2, backend2, agentServices, jobs, inFlight2, logSink);
|
|
119025
|
-
}
|
|
119026
|
-
function startEnhancerJobSubscriber(sessionId, machineId, convexUrl, wsClient2, backend2, agentServices, logSink) {
|
|
119027
|
-
const inFlight2 = new Set;
|
|
119028
|
-
registerEnhancerInboundHandler(async () => {
|
|
119029
|
-
await drainPendingEnhancerJobs(sessionId, machineId, convexUrl, wsClient2, backend2, agentServices, inFlight2, logSink);
|
|
119030
|
-
});
|
|
119031
|
-
setEnhancerDrainHandler(() => drainPendingEnhancerJobs(sessionId, machineId, convexUrl, wsClient2, backend2, agentServices, inFlight2, logSink));
|
|
119032
|
-
return {
|
|
119033
|
-
stop: () => {
|
|
119034
|
-
unregisterEnhancerInboundHandler();
|
|
119035
|
-
clearEnhancerDrainHandlerForTests();
|
|
119036
|
-
},
|
|
119037
|
-
drainPendingEnhancerJobs: () => drainPendingEnhancerJobs(sessionId, machineId, convexUrl, wsClient2, backend2, agentServices, inFlight2, logSink)
|
|
119038
|
-
};
|
|
119039
|
-
}
|
|
119040
|
-
var init_job_subscriber = __esm(() => {
|
|
119041
|
-
init_enhancer_log();
|
|
119042
|
-
init_enhancer_spawn_registry();
|
|
119043
|
-
init_wait_for_enhancer_job();
|
|
119044
|
-
init_api3();
|
|
119045
|
-
init_service_interfaces();
|
|
119046
|
-
});
|
|
119047
|
-
|
|
119048
|
-
// src/daemon/entry/enhancer/start-subscriptions.ts
|
|
119049
|
-
function startEnhancerSubscriptions(sessionId, machineId, convexUrl, wsClient2, backend2, agentServices, logSink) {
|
|
119050
|
-
return startEnhancerJobSubscriber(sessionId, machineId, convexUrl, wsClient2, backend2, agentServices, logSink);
|
|
119051
|
-
}
|
|
119052
|
-
var init_start_subscriptions2 = __esm(() => {
|
|
119053
|
-
init_job_subscriber();
|
|
119054
|
-
});
|
|
119055
|
-
|
|
119056
|
-
// src/daemon/entry/file-inbound-registry.ts
|
|
119057
|
-
function registerFileInboundHandler(h) {
|
|
119058
|
-
handler4 = h;
|
|
119059
|
-
}
|
|
119060
|
-
function unregisterFileInboundHandler() {
|
|
119061
|
-
handler4 = undefined;
|
|
119062
|
-
}
|
|
119063
|
-
async function dispatchFileInboundEvent(event) {
|
|
119064
|
-
if (handler4)
|
|
119065
|
-
await handler4(event);
|
|
119066
|
-
}
|
|
119067
|
-
var handler4;
|
|
119068
|
-
|
|
119069
118983
|
// src/daemon/entry/files/file-content-classifier.ts
|
|
119070
118984
|
function extensionOf(path3) {
|
|
119071
118985
|
const lastDot = path3.lastIndexOf(".");
|
|
@@ -119184,7 +119098,7 @@ var init_assert_registered_working_dir = __esm(() => {
|
|
|
119184
119098
|
|
|
119185
119099
|
// src/infrastructure/services/workspace/workspace-path-security.ts
|
|
119186
119100
|
import { realpath } from "node:fs/promises";
|
|
119187
|
-
import { dirname as
|
|
119101
|
+
import { dirname as dirname12, isAbsolute, relative as relative2, resolve as resolve5, sep } from "node:path";
|
|
119188
119102
|
import { gunzipSync } from "node:zlib";
|
|
119189
119103
|
function validateRelativePathSegments(filePath) {
|
|
119190
119104
|
if (filePath.includes("\x00"))
|
|
@@ -119212,7 +119126,7 @@ function assertContained(workspaceRoot, targetPath) {
|
|
|
119212
119126
|
return { ok: true };
|
|
119213
119127
|
}
|
|
119214
119128
|
async function resolveNonExistentTarget(workspaceRoot, candidate) {
|
|
119215
|
-
let current =
|
|
119129
|
+
let current = dirname12(candidate);
|
|
119216
119130
|
for (;; ) {
|
|
119217
119131
|
try {
|
|
119218
119132
|
const ancestorReal = await realpath(current);
|
|
@@ -119230,7 +119144,7 @@ async function resolveNonExistentTarget(workspaceRoot, candidate) {
|
|
|
119230
119144
|
if (code2 !== "ENOENT") {
|
|
119231
119145
|
return { ok: false, error: "Invalid file path" };
|
|
119232
119146
|
}
|
|
119233
|
-
const parent =
|
|
119147
|
+
const parent = dirname12(current);
|
|
119234
119148
|
if (parent === current) {
|
|
119235
119149
|
return { ok: false, error: "Path escapes workspace" };
|
|
119236
119150
|
}
|
|
@@ -120034,16 +119948,16 @@ var require_ignore = __commonJS((exports, module) => {
|
|
|
120034
119948
|
// src/infrastructure/services/workspace/workspace-ignore.ts
|
|
120035
119949
|
import { promises as fsPromises } from "node:fs";
|
|
120036
119950
|
import { readFile as readFile10 } from "node:fs/promises";
|
|
120037
|
-
import { homedir as
|
|
119951
|
+
import { homedir as homedir10 } from "node:os";
|
|
120038
119952
|
import path3 from "node:path";
|
|
120039
119953
|
function normalizeRelativePath(relativePath) {
|
|
120040
119954
|
return relativePath.replace(/\\/g, "/").replace(/^\.?\//, "").replace(/\/+$/, "");
|
|
120041
119955
|
}
|
|
120042
119956
|
function expandUserPath(filePath) {
|
|
120043
119957
|
if (filePath === "~")
|
|
120044
|
-
return
|
|
119958
|
+
return homedir10();
|
|
120045
119959
|
if (filePath.startsWith("~/"))
|
|
120046
|
-
return path3.join(
|
|
119960
|
+
return path3.join(homedir10(), filePath.slice(2));
|
|
120047
119961
|
return filePath;
|
|
120048
119962
|
}
|
|
120049
119963
|
function readExcludesFileFromGitconfig(content) {
|
|
@@ -120074,11 +119988,11 @@ async function readGitconfigExcludesFilePath(configPath) {
|
|
|
120074
119988
|
return path3.isAbsolute(raw) ? expandUserPath(raw) : path3.resolve(path3.dirname(configPath), raw);
|
|
120075
119989
|
}
|
|
120076
119990
|
async function resolveGitExtraExcludeFilePaths(rootDir) {
|
|
120077
|
-
const globalConfig2 = process.env.GIT_CONFIG_GLOBAL?.length ? process.env.GIT_CONFIG_GLOBAL : path3.join(
|
|
119991
|
+
const globalConfig2 = process.env.GIT_CONFIG_GLOBAL?.length ? process.env.GIT_CONFIG_GLOBAL : path3.join(homedir10(), ".gitconfig");
|
|
120078
119992
|
const localConfig = path3.join(rootDir, ".git", "config");
|
|
120079
119993
|
let excludesFile = await readGitconfigExcludesFilePath(localConfig) ?? await readGitconfigExcludesFilePath(globalConfig2);
|
|
120080
119994
|
if (!excludesFile) {
|
|
120081
|
-
excludesFile = path3.join(process.env.XDG_CONFIG_HOME?.length ? process.env.XDG_CONFIG_HOME : path3.join(
|
|
119995
|
+
excludesFile = path3.join(process.env.XDG_CONFIG_HOME?.length ? process.env.XDG_CONFIG_HOME : path3.join(homedir10(), ".config"), "git", "ignore");
|
|
120082
119996
|
}
|
|
120083
119997
|
const candidates = [excludesFile, path3.join(rootDir, ".git", "info", "exclude")];
|
|
120084
119998
|
const existing = [];
|
|
@@ -121214,9 +121128,9 @@ class NodeFsHandler {
|
|
|
121214
121128
|
if (this.fsw.closed) {
|
|
121215
121129
|
return;
|
|
121216
121130
|
}
|
|
121217
|
-
const
|
|
121131
|
+
const dirname14 = sp.dirname(file2);
|
|
121218
121132
|
const basename4 = sp.basename(file2);
|
|
121219
|
-
const parent = this.fsw._getWatchedDir(
|
|
121133
|
+
const parent = this.fsw._getWatchedDir(dirname14);
|
|
121220
121134
|
let prevStats = stats;
|
|
121221
121135
|
if (parent.has(basename4))
|
|
121222
121136
|
return;
|
|
@@ -121243,7 +121157,7 @@ class NodeFsHandler {
|
|
|
121243
121157
|
prevStats = newStats2;
|
|
121244
121158
|
}
|
|
121245
121159
|
} catch (error51) {
|
|
121246
|
-
this.fsw._remove(
|
|
121160
|
+
this.fsw._remove(dirname14, basename4);
|
|
121247
121161
|
}
|
|
121248
121162
|
} else if (parent.has(basename4)) {
|
|
121249
121163
|
const at = newStats.atimeMs;
|
|
@@ -122632,8 +122546,8 @@ function diffPathIndexes(previous, next4) {
|
|
|
122632
122546
|
// src/infrastructure/services/workspace/workspace-sync-state.ts
|
|
122633
122547
|
import { createHash as createHash7, randomUUID as randomUUID12 } from "node:crypto";
|
|
122634
122548
|
import * as fs11 from "node:fs/promises";
|
|
122635
|
-
import { homedir as
|
|
122636
|
-
import { join as
|
|
122549
|
+
import { homedir as homedir11 } from "node:os";
|
|
122550
|
+
import { join as join27 } from "node:path";
|
|
122637
122551
|
function workspaceKeyFor(workingDir) {
|
|
122638
122552
|
const normalized = normalizeWorkingDirForLookup(workingDir);
|
|
122639
122553
|
return createHash7("sha256").update(normalized).digest("hex").slice(0, 16);
|
|
@@ -122647,10 +122561,10 @@ function buildPathIndex(entries2) {
|
|
|
122647
122561
|
}
|
|
122648
122562
|
function manifestPath(machineId, workingDir) {
|
|
122649
122563
|
const key = workspaceKeyFor(workingDir);
|
|
122650
|
-
return
|
|
122564
|
+
return join27(SYNC_STATE_DIR, machineId, key, "manifest.json");
|
|
122651
122565
|
}
|
|
122652
122566
|
async function ensureDir(filePath) {
|
|
122653
|
-
await fs11.mkdir(
|
|
122567
|
+
await fs11.mkdir(join27(filePath, ".."), { recursive: true, mode: 448 });
|
|
122654
122568
|
}
|
|
122655
122569
|
async function loadWorkspaceSyncManifest(machineId, workingDir) {
|
|
122656
122570
|
try {
|
|
@@ -122710,7 +122624,7 @@ function entriesFromPathIndex(paths) {
|
|
|
122710
122624
|
}
|
|
122711
122625
|
var SYNC_STATE_VERSION = "2", SYNC_STATE_DIR;
|
|
122712
122626
|
var init_workspace_sync_state = __esm(() => {
|
|
122713
|
-
SYNC_STATE_DIR =
|
|
122627
|
+
SYNC_STATE_DIR = join27(homedir11(), ".chatroom", "sync-state");
|
|
122714
122628
|
});
|
|
122715
122629
|
|
|
122716
122630
|
// src/infrastructure/services/workspace/workspace-file-tree-coordinator.ts
|
|
@@ -123088,12 +123002,12 @@ var init_durable_coalescing_state_schema = __esm(() => {
|
|
|
123088
123002
|
});
|
|
123089
123003
|
|
|
123090
123004
|
// src/daemon/infrastructure/outbox/lib/durable-coalescing-state-store.ts
|
|
123091
|
-
import { mkdirSync as
|
|
123092
|
-
import { dirname as
|
|
123093
|
-
import { DatabaseSync as
|
|
123005
|
+
import { mkdirSync as mkdirSync9 } from "node:fs";
|
|
123006
|
+
import { dirname as dirname15 } from "node:path";
|
|
123007
|
+
import { DatabaseSync as DatabaseSync4 } from "node:sqlite";
|
|
123094
123008
|
function openDurableCoalescingStateStore(path8) {
|
|
123095
|
-
|
|
123096
|
-
const db = new
|
|
123009
|
+
mkdirSync9(dirname15(path8), { recursive: true });
|
|
123010
|
+
const db = new DatabaseSync4(path8);
|
|
123097
123011
|
for (const sql of DURABLE_COALESCING_STATE_MIGRATIONS)
|
|
123098
123012
|
db.exec(sql);
|
|
123099
123013
|
db.prepare("UPDATE coalescing_outbox_entries SET status='pending' WHERE status='in_flight'").run();
|
|
@@ -124081,7 +123995,7 @@ var init_file_write_request_priority = __esm(() => {
|
|
|
124081
123995
|
|
|
124082
123996
|
// src/daemon/entry/files/file-write-fulfillment.ts
|
|
124083
123997
|
import { access as access4, mkdir as mkdir10, rename as rename4, rm as rm4, writeFile as writeFile10 } from "node:fs/promises";
|
|
124084
|
-
import { dirname as
|
|
123998
|
+
import { dirname as dirname16 } from "node:path";
|
|
124085
123999
|
function isTerminalFileWriteError(errorMessage) {
|
|
124086
124000
|
const terminalMessages = new Set([
|
|
124087
124001
|
"Invalid file path",
|
|
@@ -124180,7 +124094,7 @@ async function validateWriteOperation(operation, absolutePath) {
|
|
|
124180
124094
|
}
|
|
124181
124095
|
async function writePayloadToDisk(absolutePath, operation, content) {
|
|
124182
124096
|
if (operation === "create") {
|
|
124183
|
-
await mkdir10(
|
|
124097
|
+
await mkdir10(dirname16(absolutePath), { recursive: true });
|
|
124184
124098
|
await writeFile10(absolutePath, content, { flag: "wx" });
|
|
124185
124099
|
return;
|
|
124186
124100
|
}
|
|
@@ -124258,7 +124172,7 @@ async function fulfillOneFileWriteRequest(session2, request2) {
|
|
|
124258
124172
|
});
|
|
124259
124173
|
return;
|
|
124260
124174
|
}
|
|
124261
|
-
await mkdir10(
|
|
124175
|
+
await mkdir10(dirname16(targetResolved.absolutePath), { recursive: true });
|
|
124262
124176
|
await rename4(resolved.absolutePath, targetResolved.absolutePath);
|
|
124263
124177
|
await completeWriteRequest(session2, claimed._id, claimed.revision, { status: "done" });
|
|
124264
124178
|
const elapsed4 = Date.now() - startTime;
|
|
@@ -125333,16 +125247,16 @@ var init_workspace_list_subscription = __esm(() => {
|
|
|
125333
125247
|
|
|
125334
125248
|
// src/daemon/entry/workspace-git-inbound-registry.ts
|
|
125335
125249
|
function registerWorkspaceGitInboundHandler(h) {
|
|
125336
|
-
|
|
125250
|
+
handler4 = h;
|
|
125337
125251
|
}
|
|
125338
125252
|
function unregisterWorkspaceGitInboundHandler() {
|
|
125339
|
-
|
|
125253
|
+
handler4 = undefined;
|
|
125340
125254
|
}
|
|
125341
125255
|
async function dispatchWorkspaceGitInboundEvent(event) {
|
|
125342
|
-
if (
|
|
125343
|
-
await
|
|
125256
|
+
if (handler4)
|
|
125257
|
+
await handler4(event);
|
|
125344
125258
|
}
|
|
125345
|
-
var
|
|
125259
|
+
var handler4;
|
|
125346
125260
|
|
|
125347
125261
|
// src/events/lifecycle/on-daemon-shutdown.ts
|
|
125348
125262
|
var onDaemonShutdownEffect;
|
|
@@ -125360,6 +125274,19 @@ var init_on_daemon_shutdown = __esm(() => {
|
|
|
125360
125274
|
const activeAgents = agentPm.listActive();
|
|
125361
125275
|
if (activeAgents.length > 0) {
|
|
125362
125276
|
console.log(`[${formatTimestamp()}] Stopping ${activeAgents.length} agent(s) locally...`);
|
|
125277
|
+
yield* exports_Effect.promise(async () => {
|
|
125278
|
+
try {
|
|
125279
|
+
const tasksReleased = await session2.backend.mutation(api.daemon.taskStatus.releaseMachineTasks, {
|
|
125280
|
+
sessionId: session2.sessionId,
|
|
125281
|
+
machineId: session2.machineId
|
|
125282
|
+
});
|
|
125283
|
+
if (tasksReleased > 0) {
|
|
125284
|
+
console.log(`[${formatTimestamp()}] Released ${tasksReleased} in-flight task(s) to pending`);
|
|
125285
|
+
}
|
|
125286
|
+
} catch (error51) {
|
|
125287
|
+
console.log(`[${formatTimestamp()}] ⚠️ Failed to release in-flight tasks on shutdown: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
125288
|
+
}
|
|
125289
|
+
});
|
|
125363
125290
|
let totalStopped = 0;
|
|
125364
125291
|
let totalFailed = 0;
|
|
125365
125292
|
yield* exports_Effect.all(activeAgents.map(({ chatroomId, role }) => exports_Effect.promise(() => agentPm.stopAgent({ chatroomId, role, reason: "daemon.shutdown" })).pipe(exports_Effect.tap(() => exports_Effect.sync(() => {
|
|
@@ -125389,7 +125316,6 @@ function createDaemonRuntime(deps) {
|
|
|
125389
125316
|
let workspaceListSubscriptionHandle = null;
|
|
125390
125317
|
let logObserverSubscriptionHandle = null;
|
|
125391
125318
|
let agenticQueryWorkerHandle = null;
|
|
125392
|
-
let enhancerWorkerHandle = null;
|
|
125393
125319
|
let taskInboxHandle = null;
|
|
125394
125320
|
let agentConfigRegistryHandle = null;
|
|
125395
125321
|
const activeSessions = new Map;
|
|
@@ -125430,7 +125356,6 @@ function createDaemonRuntime(deps) {
|
|
|
125430
125356
|
taskInboxHandle?.stop();
|
|
125431
125357
|
logObserverSubscriptionHandle?.stop();
|
|
125432
125358
|
agenticQueryWorkerHandle?.stop();
|
|
125433
|
-
enhancerWorkerHandle?.stop();
|
|
125434
125359
|
};
|
|
125435
125360
|
const shutdown = async () => {
|
|
125436
125361
|
if (isShuttingDown)
|
|
@@ -125548,7 +125473,6 @@ function createDaemonRuntime(deps) {
|
|
|
125548
125473
|
backend: session2.backend,
|
|
125549
125474
|
convexUrl: session2.convexUrl
|
|
125550
125475
|
}, activeSessions, harnesses);
|
|
125551
|
-
enhancerWorkerHandle = startEnhancerSubscriptions(session2.sessionId, session2.machineId, session2.convexUrl, deps.wsClient, session2.backend, session2.agentServices, getActiveLogSink());
|
|
125552
125476
|
console.log(`
|
|
125553
125477
|
Listening for commands...`);
|
|
125554
125478
|
console.log(`Press Ctrl+C to stop
|
|
@@ -125585,7 +125509,6 @@ var init_daemon_runtime = __esm(() => {
|
|
|
125585
125509
|
init_start_subscriptions();
|
|
125586
125510
|
init_command_dispatch();
|
|
125587
125511
|
init_daemon_services();
|
|
125588
|
-
init_start_subscriptions2();
|
|
125589
125512
|
init_file_content_subscription();
|
|
125590
125513
|
init_file_tree_subscription();
|
|
125591
125514
|
init_file_write_subscription();
|
|
@@ -125593,7 +125516,6 @@ var init_daemon_runtime = __esm(() => {
|
|
|
125593
125516
|
init_orphan_tracker();
|
|
125594
125517
|
init_command_run_subscription();
|
|
125595
125518
|
init_log_observer_sync();
|
|
125596
|
-
init_init_daemon();
|
|
125597
125519
|
init_task_inbox_runtime();
|
|
125598
125520
|
init_git_subscription();
|
|
125599
125521
|
init_api3();
|
|
@@ -125636,21 +125558,6 @@ function createCommandRouterDeps() {
|
|
|
125636
125558
|
}
|
|
125637
125559
|
var init_command_bridge = () => {};
|
|
125638
125560
|
|
|
125639
|
-
// src/daemon/domain/usecase/process-enhancer-job.ts
|
|
125640
|
-
async function processEnhancerJobInbound(deps, event) {
|
|
125641
|
-
await deps.dispatchInbound(event);
|
|
125642
|
-
}
|
|
125643
|
-
|
|
125644
|
-
// src/daemon/entry/bridge/enhancer-bridge.ts
|
|
125645
|
-
function createEnhancerRouterDeps() {
|
|
125646
|
-
return {
|
|
125647
|
-
deliverInbound: async (event) => {
|
|
125648
|
-
await processEnhancerJobInbound({ dispatchInbound: dispatchEnhancerInboundEvent }, event);
|
|
125649
|
-
}
|
|
125650
|
-
};
|
|
125651
|
-
}
|
|
125652
|
-
var init_enhancer_bridge = () => {};
|
|
125653
|
-
|
|
125654
125561
|
// src/daemon/domain/usecase/fulfill-file-content-request.ts
|
|
125655
125562
|
async function fulfillFileContentRequest(deps, event) {
|
|
125656
125563
|
await deps.dispatchInbound(event);
|
|
@@ -125720,14 +125627,12 @@ function createDefaultEventRouterDeps() {
|
|
|
125720
125627
|
command: createCommandRouterDeps(),
|
|
125721
125628
|
workspaceGit: createWorkspaceGitRouterDeps(),
|
|
125722
125629
|
file: createFileRouterDeps(),
|
|
125723
|
-
agenticQuery: createAgenticQueryRouterDeps()
|
|
125724
|
-
enhancer: createEnhancerRouterDeps()
|
|
125630
|
+
agenticQuery: createAgenticQueryRouterDeps()
|
|
125725
125631
|
};
|
|
125726
125632
|
}
|
|
125727
125633
|
var init_default_router_deps = __esm(() => {
|
|
125728
125634
|
init_agentic_query_bridge();
|
|
125729
125635
|
init_command_bridge();
|
|
125730
|
-
init_enhancer_bridge();
|
|
125731
125636
|
init_file_bridge();
|
|
125732
125637
|
init_workspace_git_bridge();
|
|
125733
125638
|
});
|
|
@@ -126008,7 +125913,6 @@ async function executeChatroomStopCommand(args2) {
|
|
|
126008
125913
|
args2.apm.markStopIntent(args2.chatroomId, args2.role, "user.stop", undefined, args2.workingDir);
|
|
126009
125914
|
else if (!args2.workingDir) {
|
|
126010
125915
|
args2.apm.markChatroomStopIntent(args2.chatroomId, "user.stop");
|
|
126011
|
-
await abortEnhancerSpawnsForChatroom(args2.chatroomId);
|
|
126012
125916
|
}
|
|
126013
125917
|
const confirmedDeps = args2.apm.getConfirmedStopAdapterDeps();
|
|
126014
125918
|
const targets = await args2.apm.discoverStopTargets(args2.chatroomId);
|
|
@@ -126041,15 +125945,14 @@ async function executeChatroomStopCommand(args2) {
|
|
|
126041
125945
|
}
|
|
126042
125946
|
var init_execute_chatroom_stop_command = __esm(() => {
|
|
126043
125947
|
init_reliability();
|
|
126044
|
-
init_enhancer_spawn_registry();
|
|
126045
125948
|
init_agent_process_service2();
|
|
126046
125949
|
});
|
|
126047
125950
|
|
|
126048
125951
|
// src/daemon/entry/persistence-path.ts
|
|
126049
|
-
import { homedir as
|
|
126050
|
-
import { join as
|
|
125952
|
+
import { homedir as homedir12 } from "node:os";
|
|
125953
|
+
import { join as join28 } from "node:path";
|
|
126051
125954
|
function resolvePersistenceDbPath(machineId) {
|
|
126052
|
-
return
|
|
125955
|
+
return join28(homedir12(), ".chatroom", "daemon", machineId, "events.sqlite");
|
|
126053
125956
|
}
|
|
126054
125957
|
var init_persistence_path = () => {};
|
|
126055
125958
|
|
|
@@ -126067,13 +125970,6 @@ async function handleCommandInbound(deps, event) {
|
|
|
126067
125970
|
}
|
|
126068
125971
|
}
|
|
126069
125972
|
|
|
126070
|
-
// src/daemon/domain/usecase/handle-enhancer-inbound.ts
|
|
126071
|
-
async function handleEnhancerInbound(deps, event) {
|
|
126072
|
-
if (deps.deliverInbound) {
|
|
126073
|
-
await deps.deliverInbound(event);
|
|
126074
|
-
}
|
|
126075
|
-
}
|
|
126076
|
-
|
|
126077
125973
|
// src/daemon/domain/usecase/handle-file-inbound.ts
|
|
126078
125974
|
async function handleFileInbound(deps, event) {
|
|
126079
125975
|
if (deps.deliverInbound) {
|
|
@@ -126109,9 +126005,6 @@ async function routeInboundEvent(deps, event) {
|
|
|
126109
126005
|
case "agentic-query.prompt":
|
|
126110
126006
|
await handleAgenticQueryInbound(deps.agenticQuery, event);
|
|
126111
126007
|
break;
|
|
126112
|
-
case "enhancer.job-assigned":
|
|
126113
|
-
await handleEnhancerInbound(deps.enhancer, event);
|
|
126114
|
-
break;
|
|
126115
126008
|
default:
|
|
126116
126009
|
}
|
|
126117
126010
|
}
|
|
@@ -126219,80 +126112,6 @@ var init_command_run = __esm(() => {
|
|
|
126219
126112
|
init_api3();
|
|
126220
126113
|
});
|
|
126221
126114
|
|
|
126222
|
-
// src/daemon/infrastructure/convex/subscribers/enhancer-job.ts
|
|
126223
|
-
function startEnhancerJobSubscriber2(deps, onEvent) {
|
|
126224
|
-
const seen = new Set;
|
|
126225
|
-
const watchers = new Map;
|
|
126226
|
-
let stopped = false;
|
|
126227
|
-
let refreshInFlight = false;
|
|
126228
|
-
const onPendingJobs = (jobs) => {
|
|
126229
|
-
if (!jobs?.length)
|
|
126230
|
-
return;
|
|
126231
|
-
for (const job of jobs) {
|
|
126232
|
-
if (job == null || typeof job !== "object" || !("jobId" in job))
|
|
126233
|
-
continue;
|
|
126234
|
-
if (seen.has(job.jobId))
|
|
126235
|
-
continue;
|
|
126236
|
-
seen.add(job.jobId);
|
|
126237
|
-
onEvent({ type: "enhancer.job-assigned", jobId: job.jobId });
|
|
126238
|
-
}
|
|
126239
|
-
};
|
|
126240
|
-
const onError3 = (err) => {
|
|
126241
|
-
console.warn(`[daemon] enhancer-job subscriber error: ${err instanceof Error ? err.message : String(err)}`);
|
|
126242
|
-
};
|
|
126243
|
-
const watchChatroom = (chatroomId) => {
|
|
126244
|
-
if (watchers.has(chatroomId) || stopped)
|
|
126245
|
-
return;
|
|
126246
|
-
const unsub = deps.wsClient.onUpdate(api.daemon.enhancer.index.pendingForChatroom, {
|
|
126247
|
-
sessionId: deps.sessionId,
|
|
126248
|
-
machineId: deps.machineId,
|
|
126249
|
-
chatroomId
|
|
126250
|
-
}, onPendingJobs, onError3);
|
|
126251
|
-
watchers.set(chatroomId, unsub);
|
|
126252
|
-
};
|
|
126253
|
-
const refreshChatrooms = async () => {
|
|
126254
|
-
if (refreshInFlight)
|
|
126255
|
-
return;
|
|
126256
|
-
refreshInFlight = true;
|
|
126257
|
-
try {
|
|
126258
|
-
const workspaces = await deps.wsClient.query(api.workspaces.listWorkspacesForMachine, {
|
|
126259
|
-
sessionId: deps.sessionId,
|
|
126260
|
-
machineId: deps.machineId
|
|
126261
|
-
});
|
|
126262
|
-
if (stopped)
|
|
126263
|
-
return;
|
|
126264
|
-
const roomIds = [
|
|
126265
|
-
...new Set((workspaces ?? []).map((ws) => ws.chatroomId))
|
|
126266
|
-
];
|
|
126267
|
-
for (const [roomId, unsub] of watchers) {
|
|
126268
|
-
if (!roomIds.includes(roomId)) {
|
|
126269
|
-
unsub();
|
|
126270
|
-
watchers.delete(roomId);
|
|
126271
|
-
}
|
|
126272
|
-
}
|
|
126273
|
-
for (const roomId of roomIds)
|
|
126274
|
-
watchChatroom(roomId);
|
|
126275
|
-
} catch (error51) {
|
|
126276
|
-
console.warn(`[daemon] enhancer-job room refresh failed: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
126277
|
-
} finally {
|
|
126278
|
-
refreshInFlight = false;
|
|
126279
|
-
}
|
|
126280
|
-
};
|
|
126281
|
-
refreshChatrooms();
|
|
126282
|
-
return {
|
|
126283
|
-
async stop() {
|
|
126284
|
-
stopped = true;
|
|
126285
|
-
for (const unsub of watchers.values())
|
|
126286
|
-
unsub();
|
|
126287
|
-
watchers.clear();
|
|
126288
|
-
},
|
|
126289
|
-
refreshChatrooms
|
|
126290
|
-
};
|
|
126291
|
-
}
|
|
126292
|
-
var init_enhancer_job = __esm(() => {
|
|
126293
|
-
init_api3();
|
|
126294
|
-
});
|
|
126295
|
-
|
|
126296
126115
|
// src/daemon/infrastructure/convex/subscribers/pending-file-request-dedup.ts
|
|
126297
126116
|
function pendingConvexId(req) {
|
|
126298
126117
|
if (req._id == null)
|
|
@@ -126609,7 +126428,6 @@ function startAllSubscribers(deps) {
|
|
|
126609
126428
|
const onEvent = (event) => {
|
|
126610
126429
|
routeInboundEvent(deps.router, event);
|
|
126611
126430
|
};
|
|
126612
|
-
const enhancerJob = startEnhancerJobSubscriber2(deps, onEvent);
|
|
126613
126431
|
const gitRequest = startGitRequestSubscriber(deps, onEvent);
|
|
126614
126432
|
const machineCommands = startMachineCommandInboxSubscriber(deps, async (claimed) => {
|
|
126615
126433
|
if (claimed.type === "agent.stop") {
|
|
@@ -126640,8 +126458,7 @@ function startAllSubscribers(deps) {
|
|
|
126640
126458
|
fileContent.stop(),
|
|
126641
126459
|
fileWrite.stop(),
|
|
126642
126460
|
agenticQuerySession.stop(),
|
|
126643
|
-
agenticQueryPrompt.stop()
|
|
126644
|
-
enhancerJob.stop()
|
|
126461
|
+
agenticQueryPrompt.stop()
|
|
126645
126462
|
]);
|
|
126646
126463
|
}
|
|
126647
126464
|
};
|
|
@@ -126651,7 +126468,6 @@ var init_subscriber_registry = __esm(() => {
|
|
|
126651
126468
|
init_agentic_query_prompt();
|
|
126652
126469
|
init_agentic_query_session();
|
|
126653
126470
|
init_command_run();
|
|
126654
|
-
init_enhancer_job();
|
|
126655
126471
|
init_file_content_request();
|
|
126656
126472
|
init_file_tree_release_request();
|
|
126657
126473
|
init_file_tree_request();
|
|
@@ -126700,12 +126516,12 @@ var init_schema = __esm(() => {
|
|
|
126700
126516
|
});
|
|
126701
126517
|
|
|
126702
126518
|
// src/daemon/infrastructure/persistence/open-database.ts
|
|
126703
|
-
import { mkdirSync as
|
|
126704
|
-
import { dirname as
|
|
126705
|
-
import { DatabaseSync as
|
|
126519
|
+
import { mkdirSync as mkdirSync10 } from "node:fs";
|
|
126520
|
+
import { dirname as dirname17 } from "node:path";
|
|
126521
|
+
import { DatabaseSync as DatabaseSync5 } from "node:sqlite";
|
|
126706
126522
|
function openDatabase(dbPath) {
|
|
126707
|
-
|
|
126708
|
-
const db = new
|
|
126523
|
+
mkdirSync10(dirname17(dbPath), { recursive: true });
|
|
126524
|
+
const db = new DatabaseSync5(dbPath);
|
|
126709
126525
|
for (const sql of MIGRATIONS2) {
|
|
126710
126526
|
db.exec(sql);
|
|
126711
126527
|
}
|
|
@@ -134200,19 +134016,19 @@ function routeRequest(req, res, deps) {
|
|
|
134200
134016
|
|
|
134201
134017
|
// src/daemon/local-web/server/serve-static.ts
|
|
134202
134018
|
import { existsSync as existsSync10, readFileSync as readFileSync11 } from "node:fs";
|
|
134203
|
-
import { dirname as
|
|
134019
|
+
import { dirname as dirname18, join as join29 } from "node:path";
|
|
134204
134020
|
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
134205
134021
|
function clientDistCandidates(here) {
|
|
134206
134022
|
return [
|
|
134207
|
-
|
|
134208
|
-
|
|
134209
|
-
|
|
134023
|
+
join29(here, "client/build"),
|
|
134024
|
+
join29(here, "../client/build"),
|
|
134025
|
+
join29(here, "../src/daemon/local-web/client/build")
|
|
134210
134026
|
];
|
|
134211
134027
|
}
|
|
134212
|
-
function resolveClientDistDir(here =
|
|
134028
|
+
function resolveClientDistDir(here = dirname18(fileURLToPath7(import.meta.url))) {
|
|
134213
134029
|
const candidates = clientDistCandidates(here);
|
|
134214
134030
|
for (const dir of candidates) {
|
|
134215
|
-
if (existsSync10(
|
|
134031
|
+
if (existsSync10(join29(dir, "index.html")))
|
|
134216
134032
|
return dir;
|
|
134217
134033
|
}
|
|
134218
134034
|
return candidates[0];
|
|
@@ -134225,7 +134041,7 @@ function tryServeStatic(req, res, distDir) {
|
|
|
134225
134041
|
return false;
|
|
134226
134042
|
}
|
|
134227
134043
|
const safePath = pathname === "/" ? "/index.html" : pathname;
|
|
134228
|
-
const filePath =
|
|
134044
|
+
const filePath = join29(distDir, safePath);
|
|
134229
134045
|
if (!filePath.startsWith(distDir)) {
|
|
134230
134046
|
res.writeHead(403);
|
|
134231
134047
|
res.end();
|
|
@@ -134242,7 +134058,7 @@ function tryServeStatic(req, res, distDir) {
|
|
|
134242
134058
|
}
|
|
134243
134059
|
return true;
|
|
134244
134060
|
}
|
|
134245
|
-
const indexPath =
|
|
134061
|
+
const indexPath = join29(distDir, "index.html");
|
|
134246
134062
|
if (existsSync10(indexPath)) {
|
|
134247
134063
|
res.writeHead(200, { "Content-Type": "text/html" });
|
|
134248
134064
|
if (req.method === "HEAD") {
|
|
@@ -134291,6 +134107,14 @@ function normalizeError(err) {
|
|
|
134291
134107
|
details: err.flatten()
|
|
134292
134108
|
};
|
|
134293
134109
|
}
|
|
134110
|
+
if (err instanceof ConvexError) {
|
|
134111
|
+
const data = err.data;
|
|
134112
|
+
return {
|
|
134113
|
+
code: data.code ?? "internal_error",
|
|
134114
|
+
message: data.message ?? err.message,
|
|
134115
|
+
details: err.data
|
|
134116
|
+
};
|
|
134117
|
+
}
|
|
134294
134118
|
if (err instanceof Error) {
|
|
134295
134119
|
const code2 = "code" in err && typeof err.code === "string" ? err.code : "internal_error";
|
|
134296
134120
|
if (code2 === "not_found" || code2 === "validation_error" || code2 === "unauthorized") {
|
|
@@ -134301,6 +134125,7 @@ function normalizeError(err) {
|
|
|
134301
134125
|
return { code: "internal_error", message: "Unknown error" };
|
|
134302
134126
|
}
|
|
134303
134127
|
var init_normalize_error = __esm(() => {
|
|
134128
|
+
init_values();
|
|
134304
134129
|
init_zod();
|
|
134305
134130
|
});
|
|
134306
134131
|
|
|
@@ -134431,6 +134256,16 @@ function extractAck(args2) {
|
|
|
134431
134256
|
}
|
|
134432
134257
|
return { payload: args2[0], ack: undefined };
|
|
134433
134258
|
}
|
|
134259
|
+
async function resolveDebugStatePayload(deps, payload) {
|
|
134260
|
+
if (!deps.debugState)
|
|
134261
|
+
throw new Error("daemon debug state is not configured");
|
|
134262
|
+
const { chatroomId } = debugStateInputSchema.parse(payload ?? {});
|
|
134263
|
+
const data = await deps.debugState(chatroomId);
|
|
134264
|
+
if (data && typeof data === "object" && deps.cliGateway) {
|
|
134265
|
+
data.cliGateway = deps.cliGateway.debugState();
|
|
134266
|
+
}
|
|
134267
|
+
return data;
|
|
134268
|
+
}
|
|
134434
134269
|
function registerSocketHandlers(io2, deps) {
|
|
134435
134270
|
const logHistory = deps.logRepo ? createLogHistoryUseCase({ reader: deps.logRepo }) : undefined;
|
|
134436
134271
|
const eventStreamHistory = deps.logRepo ? createEventStreamHistoryUseCase({ reader: deps.logRepo }) : undefined;
|
|
@@ -134450,13 +134285,22 @@ function registerSocketHandlers(io2, deps) {
|
|
|
134450
134285
|
callAck(ack, { ok: false, error: normalizeError(err) });
|
|
134451
134286
|
}
|
|
134452
134287
|
});
|
|
134288
|
+
socket.on("cli.handoff", async (...args2) => {
|
|
134289
|
+
const { payload, ack } = extractAck(args2);
|
|
134290
|
+
try {
|
|
134291
|
+
if (!deps.cliGateway)
|
|
134292
|
+
throw new Error("CLI gateway is not configured");
|
|
134293
|
+
const data = await deps.cliGateway.handoff(payload);
|
|
134294
|
+
callAck(ack, { ok: true, data });
|
|
134295
|
+
} catch (err) {
|
|
134296
|
+
callAck(ack, { ok: false, error: normalizeError(err) });
|
|
134297
|
+
}
|
|
134298
|
+
});
|
|
134453
134299
|
socket.on("daemon.debug.state", async (...args2) => {
|
|
134454
134300
|
const { payload, ack } = extractAck(args2);
|
|
134455
134301
|
try {
|
|
134456
|
-
|
|
134457
|
-
|
|
134458
|
-
const { chatroomId } = debugStateInputSchema.parse(payload ?? {});
|
|
134459
|
-
callAck(ack, { ok: true, data: await deps.debugState(chatroomId) });
|
|
134302
|
+
const data = await resolveDebugStatePayload(deps, payload);
|
|
134303
|
+
callAck(ack, { ok: true, data });
|
|
134460
134304
|
} catch (err) {
|
|
134461
134305
|
callAck(ack, { ok: false, error: normalizeError(err) });
|
|
134462
134306
|
}
|
|
@@ -134640,7 +134484,8 @@ async function startLocalWebServer(config4, deps = {}) {
|
|
|
134640
134484
|
eventStreamHub: deps.eventStreamHub,
|
|
134641
134485
|
backend: deps.backend,
|
|
134642
134486
|
sessionId: deps.sessionId,
|
|
134643
|
-
debugState: deps.debugState
|
|
134487
|
+
debugState: deps.debugState,
|
|
134488
|
+
cliGateway: deps.cliGateway
|
|
134644
134489
|
});
|
|
134645
134490
|
return {
|
|
134646
134491
|
port: boundPort,
|
|
@@ -134696,6 +134541,80 @@ function createLogStreamHub() {
|
|
|
134696
134541
|
};
|
|
134697
134542
|
}
|
|
134698
134543
|
|
|
134544
|
+
// src/daemon/services/cli-gateway-service/index.ts
|
|
134545
|
+
function createCliGatewayService(deps) {
|
|
134546
|
+
const logs2 = [];
|
|
134547
|
+
const writeLog = (message) => {
|
|
134548
|
+
logs2.push({ timestamp: Date.now(), message });
|
|
134549
|
+
if (logs2.length > 100)
|
|
134550
|
+
logs2.shift();
|
|
134551
|
+
(deps.log ?? console.log)(`[CliGateway:${message}]`);
|
|
134552
|
+
};
|
|
134553
|
+
return {
|
|
134554
|
+
handoff: async (args2) => {
|
|
134555
|
+
writeLog(`request handoff chatroom=${args2.chatroomId} role=${args2.senderRole}`);
|
|
134556
|
+
const taskIdsBeforeCommit = getActiveTaskIdsForRole(deps, args2);
|
|
134557
|
+
const result = await commitHandoffMutation(deps, args2, writeLog);
|
|
134558
|
+
writeLog(`backend result success=${result.success}`);
|
|
134559
|
+
if (result.success) {
|
|
134560
|
+
await syncTaskServiceAfterHandoff(deps, args2, result, taskIdsBeforeCommit, writeLog);
|
|
134561
|
+
}
|
|
134562
|
+
return result;
|
|
134563
|
+
},
|
|
134564
|
+
debugState: () => ({ port: deps.port, logs: [...logs2] })
|
|
134565
|
+
};
|
|
134566
|
+
}
|
|
134567
|
+
function getActiveTaskIdsForRole(deps, args2) {
|
|
134568
|
+
return deps.taskService.listTasksForRole?.(args2.chatroomId, args2.senderRole).filter((task) => task.status === "acknowledged" || task.status === "in_progress").map((task) => task.taskId) ?? [];
|
|
134569
|
+
}
|
|
134570
|
+
async function commitHandoffMutation(deps, args2, writeLog) {
|
|
134571
|
+
try {
|
|
134572
|
+
return await deps.backend.mutation(api.messages.handoff, args2);
|
|
134573
|
+
} catch (error51) {
|
|
134574
|
+
writeLog(`backend failure=${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
134575
|
+
throw error51;
|
|
134576
|
+
}
|
|
134577
|
+
}
|
|
134578
|
+
async function syncTaskServiceAfterHandoff(deps, args2, result, taskIdsBeforeCommit, writeLog) {
|
|
134579
|
+
try {
|
|
134580
|
+
const nextTask = await adoptNextHandoffTask(deps, args2, result);
|
|
134581
|
+
await deps.taskService.recordHandoffOutcome({
|
|
134582
|
+
chatroomId: args2.chatroomId,
|
|
134583
|
+
role: args2.senderRole,
|
|
134584
|
+
targetRole: args2.targetRole,
|
|
134585
|
+
nextTask,
|
|
134586
|
+
taskIds: taskIdsBeforeCommit
|
|
134587
|
+
});
|
|
134588
|
+
writeLog(`task-service updated chatroom=${args2.chatroomId} role=${args2.senderRole}` + (nextTask ? ` adopted=${nextTask.taskId}` : ""));
|
|
134589
|
+
} catch (error51) {
|
|
134590
|
+
writeLog(`post-commit sync failure chatroom=${args2.chatroomId} error=${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
134591
|
+
await recordFallbackHandoffOutcome(deps, args2, writeLog);
|
|
134592
|
+
}
|
|
134593
|
+
}
|
|
134594
|
+
async function adoptNextHandoffTask(deps, args2, result) {
|
|
134595
|
+
if (!result.newTaskId || args2.targetRole.toLowerCase() === "user")
|
|
134596
|
+
return;
|
|
134597
|
+
return await deps.taskService.loadAssignedTaskForAction({
|
|
134598
|
+
chatroomId: args2.chatroomId,
|
|
134599
|
+
role: args2.targetRole,
|
|
134600
|
+
taskId: result.newTaskId
|
|
134601
|
+
}) ?? undefined;
|
|
134602
|
+
}
|
|
134603
|
+
async function recordFallbackHandoffOutcome(deps, args2, writeLog) {
|
|
134604
|
+
try {
|
|
134605
|
+
await deps.taskService.recordHandoffOutcome({
|
|
134606
|
+
chatroomId: args2.chatroomId,
|
|
134607
|
+
role: args2.senderRole,
|
|
134608
|
+
targetRole: args2.targetRole
|
|
134609
|
+
});
|
|
134610
|
+
} catch (cleanupError) {
|
|
134611
|
+
writeLog(`post-commit cleanup failure chatroom=${args2.chatroomId} error=${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}`);
|
|
134612
|
+
}
|
|
134613
|
+
}
|
|
134614
|
+
var init_cli_gateway_service = __esm(() => {
|
|
134615
|
+
init_api3();
|
|
134616
|
+
});
|
|
134617
|
+
|
|
134699
134618
|
// src/daemon/entry/start-daemon.ts
|
|
134700
134619
|
async function startDaemon() {
|
|
134701
134620
|
let resolveBoundPort;
|
|
@@ -134730,6 +134649,11 @@ async function startDaemon() {
|
|
|
134730
134649
|
logEvent: init2.logEvent
|
|
134731
134650
|
});
|
|
134732
134651
|
const localWebPort = resolveLocalWebPort();
|
|
134652
|
+
const cliGateway = createCliGatewayService({
|
|
134653
|
+
backend: init2.backend,
|
|
134654
|
+
port: localWebPort,
|
|
134655
|
+
taskService: init2.taskService
|
|
134656
|
+
});
|
|
134733
134657
|
const debugState = async (chatroomId) => {
|
|
134734
134658
|
const persisted = await loadDaemonState(init2.machineId);
|
|
134735
134659
|
const persistedAgents = Object.fromEntries(Object.entries(persisted?.agents ?? {}).filter(([key]) => key.startsWith(`${chatroomId}/`)));
|
|
@@ -134787,7 +134711,8 @@ async function startDaemon() {
|
|
|
134787
134711
|
eventStreamHub,
|
|
134788
134712
|
backend: init2.backend,
|
|
134789
134713
|
sessionId: init2.sessionId,
|
|
134790
|
-
debugState
|
|
134714
|
+
debugState,
|
|
134715
|
+
cliGateway
|
|
134791
134716
|
});
|
|
134792
134717
|
resolveBoundPort(localWeb.port);
|
|
134793
134718
|
const subscribers = startAllSubscribers({
|
|
@@ -134848,6 +134773,7 @@ var init_start_daemon = __esm(() => {
|
|
|
134848
134773
|
init_log_repository();
|
|
134849
134774
|
init_socket3();
|
|
134850
134775
|
init_create_local_web_server();
|
|
134776
|
+
init_cli_gateway_service();
|
|
134851
134777
|
});
|
|
134852
134778
|
|
|
134853
134779
|
// src/commands/machine/daemon-start/index.ts
|
|
@@ -136104,4 +136030,4 @@ program2.hook("preAction", async (_thisCommand, actionCommand) => {
|
|
|
136104
136030
|
});
|
|
136105
136031
|
program2.parse();
|
|
136106
136032
|
|
|
136107
|
-
//# debugId=
|
|
136033
|
+
//# debugId=CB5CA35B81D3EFBC64756E2164756E21
|