chatroom-cli 1.117.5 → 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;
|
|
@@ -112333,9 +112678,10 @@ var init_convex_agent_config_gateway = __esm(() => {
|
|
|
112333
112678
|
model: exports_external.string(),
|
|
112334
112679
|
workingDir: exports_external.string(),
|
|
112335
112680
|
status: exports_external.enum(WorkspaceAgentConfigInboxStatus),
|
|
112336
|
-
createdAt: exports_external.number()
|
|
112681
|
+
createdAt: exports_external.number(),
|
|
112682
|
+
processedAt: exports_external.number().optional()
|
|
112337
112683
|
});
|
|
112338
|
-
agentConfigInboxEventSchema = agentConfigInboxRowSchema.transform(({ _id: eventId, ...row }) => ({ ...row, eventId }));
|
|
112684
|
+
agentConfigInboxEventSchema = agentConfigInboxRowSchema.transform(({ _id: eventId, processedAt: _processedAt, ...row }) => ({ ...row, eventId }));
|
|
112339
112685
|
});
|
|
112340
112686
|
|
|
112341
112687
|
// src/daemon/services/chatroom-workspace-configuration-service/service/agent-config-registry.ts
|
|
@@ -112616,6 +112962,7 @@ function assembleDaemonSessionInit(args2) {
|
|
|
112616
112962
|
convexUrl,
|
|
112617
112963
|
backend: deps.backend,
|
|
112618
112964
|
configurationService: agentConfigRegistry,
|
|
112965
|
+
handoffRepository: createTaskHandoffRepository(resolveTaskHandoffRepositoryPath(machineId)),
|
|
112619
112966
|
logEvent: activeLogEvent ?? (async () => {
|
|
112620
112967
|
return;
|
|
112621
112968
|
})
|
|
@@ -112656,9 +113003,6 @@ class NetworkRetryError {
|
|
|
112656
113003
|
this.attempt = attempt;
|
|
112657
113004
|
}
|
|
112658
113005
|
}
|
|
112659
|
-
function getActiveLogSink() {
|
|
112660
|
-
return activeLogSink;
|
|
112661
|
-
}
|
|
112662
113006
|
async function initDaemon(options = {}) {
|
|
112663
113007
|
activeLogSink = options.logSink;
|
|
112664
113008
|
activeLogEvent = options.logEvent;
|
|
@@ -112859,6 +113203,7 @@ var init_init_daemon = __esm(() => {
|
|
|
112859
113203
|
init_daemon_startup_log();
|
|
112860
113204
|
init_orphan_tracker();
|
|
112861
113205
|
init_output_store();
|
|
113206
|
+
init_task_handoff_repository_path();
|
|
112862
113207
|
init_pid();
|
|
112863
113208
|
init_storage();
|
|
112864
113209
|
init_client2();
|
|
@@ -112873,6 +113218,7 @@ var init_init_daemon = __esm(() => {
|
|
|
112873
113218
|
init_agent_process_service2();
|
|
112874
113219
|
init_chatroom_workspace_configuration_service();
|
|
112875
113220
|
init_service_interfaces();
|
|
113221
|
+
init_task_service2();
|
|
112876
113222
|
AUTH_WAIT_TIMEOUT_MS = 5 * 60 * 1000;
|
|
112877
113223
|
initDaemonEffect = exports_Effect.gen(function* () {
|
|
112878
113224
|
const lockAcquired = yield* exports_Effect.tryPromise({
|
|
@@ -117227,16 +117573,16 @@ var MAX_NAME_LENGTH = 256;
|
|
|
117227
117573
|
|
|
117228
117574
|
// src/infrastructure/services/workspace/workspace-resolver.ts
|
|
117229
117575
|
import { readFile as readFile7, readdir, stat as stat4 } from "node:fs/promises";
|
|
117230
|
-
import { join as
|
|
117576
|
+
import { join as join23, basename, resolve as resolve4 } from "node:path";
|
|
117231
117577
|
async function resolveGlobPatternStar(rootDir, cleaned) {
|
|
117232
|
-
const parentDir =
|
|
117578
|
+
const parentDir = join23(rootDir, cleaned.slice(0, -2));
|
|
117233
117579
|
try {
|
|
117234
117580
|
const entries2 = await readdir(parentDir, { withFileTypes: true });
|
|
117235
117581
|
const dirs = [];
|
|
117236
117582
|
for (const entry of entries2) {
|
|
117237
117583
|
if (!entry.isDirectory())
|
|
117238
117584
|
continue;
|
|
117239
|
-
const dirPath =
|
|
117585
|
+
const dirPath = join23(parentDir, entry.name);
|
|
117240
117586
|
if (resolve4(dirPath).startsWith(resolve4(rootDir))) {
|
|
117241
117587
|
dirs.push(dirPath);
|
|
117242
117588
|
}
|
|
@@ -117247,7 +117593,7 @@ async function resolveGlobPatternStar(rootDir, cleaned) {
|
|
|
117247
117593
|
}
|
|
117248
117594
|
}
|
|
117249
117595
|
async function resolveLiteralPath(rootDir, cleaned) {
|
|
117250
|
-
const dir =
|
|
117596
|
+
const dir = join23(rootDir, cleaned);
|
|
117251
117597
|
try {
|
|
117252
117598
|
if (!resolve4(dir).startsWith(resolve4(rootDir)))
|
|
117253
117599
|
return [];
|
|
@@ -117267,7 +117613,7 @@ async function resolveGlobPattern(rootDir, pattern) {
|
|
|
117267
117613
|
}
|
|
117268
117614
|
async function readPackageJson(dir) {
|
|
117269
117615
|
try {
|
|
117270
|
-
const content = await readFile7(
|
|
117616
|
+
const content = await readFile7(join23(dir, "package.json"), "utf-8");
|
|
117271
117617
|
const pkg = JSON.parse(content);
|
|
117272
117618
|
return {
|
|
117273
117619
|
name: pkg.name || basename(dir),
|
|
@@ -117279,7 +117625,7 @@ async function readPackageJson(dir) {
|
|
|
117279
117625
|
}
|
|
117280
117626
|
async function readPnpmWorkspacePatterns(rootDir) {
|
|
117281
117627
|
try {
|
|
117282
|
-
const content = await readFile7(
|
|
117628
|
+
const content = await readFile7(join23(rootDir, "pnpm-workspace.yaml"), "utf-8");
|
|
117283
117629
|
const patterns = [];
|
|
117284
117630
|
let inPackages = false;
|
|
117285
117631
|
for (const line of content.split(`
|
|
@@ -117306,7 +117652,7 @@ async function readPnpmWorkspacePatterns(rootDir) {
|
|
|
117306
117652
|
}
|
|
117307
117653
|
async function readPackageJsonWorkspacePatterns(rootDir) {
|
|
117308
117654
|
try {
|
|
117309
|
-
const content = await readFile7(
|
|
117655
|
+
const content = await readFile7(join23(rootDir, "package.json"), "utf-8");
|
|
117310
117656
|
const pkg = JSON.parse(content);
|
|
117311
117657
|
if (!pkg.workspaces)
|
|
117312
117658
|
return [];
|
|
@@ -117355,11 +117701,11 @@ var init_workspace_resolver = () => {};
|
|
|
117355
117701
|
|
|
117356
117702
|
// src/infrastructure/services/workspace/command-discovery.ts
|
|
117357
117703
|
import { access as access2, readFile as readFile8 } from "node:fs/promises";
|
|
117358
|
-
import { join as
|
|
117704
|
+
import { join as join24, relative, basename as basename2 } from "node:path";
|
|
117359
117705
|
async function detectPackageManager(workingDir) {
|
|
117360
117706
|
for (const { file: file2, manager } of LOCKFILE_MAP) {
|
|
117361
117707
|
try {
|
|
117362
|
-
await access2(
|
|
117708
|
+
await access2(join24(workingDir, file2));
|
|
117363
117709
|
return manager;
|
|
117364
117710
|
} catch {}
|
|
117365
117711
|
}
|
|
@@ -117428,7 +117774,7 @@ function collectRootScriptCommands(scripts, pm, scriptPrefix, rootSw) {
|
|
|
117428
117774
|
}
|
|
117429
117775
|
async function readRootPackageJson(workingDir, pm, scriptPrefix) {
|
|
117430
117776
|
let rootPackageName = basename2(workingDir);
|
|
117431
|
-
const pkg = await readJsonFile(
|
|
117777
|
+
const pkg = await readJsonFile(join24(workingDir, "package.json"), "root package.json");
|
|
117432
117778
|
if (!pkg)
|
|
117433
117779
|
return { commands: [], rootPackageName };
|
|
117434
117780
|
if (pkg.name)
|
|
@@ -117444,7 +117790,7 @@ async function readRootPackageJson(workingDir, pm, scriptPrefix) {
|
|
|
117444
117790
|
}
|
|
117445
117791
|
async function readTurboJson(workingDir, _turboPrefix, _rootSubWorkspace) {
|
|
117446
117792
|
const turboTaskNames = [];
|
|
117447
|
-
const turbo = await readJsonFile(
|
|
117793
|
+
const turbo = await readJsonFile(join24(workingDir, "turbo.json"), "turbo.json");
|
|
117448
117794
|
if (!turbo?.tasks || typeof turbo.tasks !== "object")
|
|
117449
117795
|
return turboTaskNames;
|
|
117450
117796
|
for (const taskName of Object.keys(turbo.tasks)) {
|
|
@@ -117457,7 +117803,7 @@ async function readTurboJson(workingDir, _turboPrefix, _rootSubWorkspace) {
|
|
|
117457
117803
|
async function readDenoJson(workingDir) {
|
|
117458
117804
|
const commands = [];
|
|
117459
117805
|
for (const fileName of ["deno.json", "deno.jsonc"]) {
|
|
117460
|
-
const deno = await readJsonFile(
|
|
117806
|
+
const deno = await readJsonFile(join24(workingDir, fileName), fileName);
|
|
117461
117807
|
if (!deno?.tasks || typeof deno.tasks !== "object")
|
|
117462
117808
|
continue;
|
|
117463
117809
|
const pkgName = deno.name ?? basename2(workingDir);
|
|
@@ -117480,7 +117826,7 @@ async function readMakefile(workingDir) {
|
|
|
117480
117826
|
const commands = [];
|
|
117481
117827
|
for (const fileName of ["Makefile", "makefile"]) {
|
|
117482
117828
|
try {
|
|
117483
|
-
const content = await readFile8(
|
|
117829
|
+
const content = await readFile8(join24(workingDir, fileName), "utf-8");
|
|
117484
117830
|
const targets = parseMakefileTargets(content);
|
|
117485
117831
|
if (targets.length === 0)
|
|
117486
117832
|
continue;
|
|
@@ -118055,7 +118401,7 @@ async function runRestartOrchestrator(deps, event) {
|
|
|
118055
118401
|
const { chatroomId, role } = event;
|
|
118056
118402
|
markRestartOrchestratorInFlight(chatroomId, role, event.correlationId);
|
|
118057
118403
|
try {
|
|
118058
|
-
|
|
118404
|
+
await deps.nativeDelivery.handleAgentRestart({ chatroomId, role });
|
|
118059
118405
|
await emitPhase(deps, event, "reset");
|
|
118060
118406
|
await emitPhase(deps, event, "spawn");
|
|
118061
118407
|
const spawnResult = await deps.runSerializedForAgent({ chatroomId, role, workingDir: event.workingDir }, { timeoutMs: HARNESS_SESSION_READY_TIMEOUT_MS }, async (ops, context5) => {
|
|
@@ -118116,7 +118462,6 @@ var init_restart_orchestrator = __esm(() => {
|
|
|
118116
118462
|
init_api3();
|
|
118117
118463
|
init_convex_error();
|
|
118118
118464
|
init_execution_kind();
|
|
118119
|
-
init_service_interfaces();
|
|
118120
118465
|
});
|
|
118121
118466
|
|
|
118122
118467
|
// src/daemon/entry/bridge/agent-control-bridge.ts
|
|
@@ -118271,19 +118616,6 @@ async function startAgent2(deps, input) {
|
|
|
118271
118616
|
});
|
|
118272
118617
|
}
|
|
118273
118618
|
|
|
118274
|
-
// src/daemon/entry/enhancer/enhancer-drain-registry.ts
|
|
118275
|
-
function setEnhancerDrainHandler(fn2) {
|
|
118276
|
-
drainFn = fn2;
|
|
118277
|
-
}
|
|
118278
|
-
async function drainPendingEnhancerJobsIfRegistered() {
|
|
118279
|
-
if (drainFn)
|
|
118280
|
-
await drainFn();
|
|
118281
|
-
}
|
|
118282
|
-
function clearEnhancerDrainHandlerForTests() {
|
|
118283
|
-
drainFn = null;
|
|
118284
|
-
}
|
|
118285
|
-
var drainFn = null;
|
|
118286
|
-
|
|
118287
118619
|
// src/daemon/entry/events/agent/on-request-start-agent.ts
|
|
118288
118620
|
var onRequestStartAgentEffect = (event) => exports_Effect.gen(function* () {
|
|
118289
118621
|
const processManagerService = yield* DaemonAgentProcessManagerCommandService;
|
|
@@ -118300,7 +118632,6 @@ var onRequestStartAgentEffect = (event) => exports_Effect.gen(function* () {
|
|
|
118300
118632
|
deadline: event.deadline,
|
|
118301
118633
|
wantResume: event.wantResume
|
|
118302
118634
|
});
|
|
118303
|
-
await drainPendingEnhancerJobsIfRegistered();
|
|
118304
118635
|
});
|
|
118305
118636
|
});
|
|
118306
118637
|
var init_on_request_start_agent = __esm(() => {
|
|
@@ -118636,435 +118967,19 @@ async function dispatchCommandInboundEvent(event) {
|
|
|
118636
118967
|
}
|
|
118637
118968
|
var handler2;
|
|
118638
118969
|
|
|
118639
|
-
// src/daemon/entry/
|
|
118640
|
-
|
|
118641
|
-
|
|
118642
|
-
// src/daemon/entry/enhancer/enhancer-log.ts
|
|
118643
|
-
function formatEnhancerLogLine(message) {
|
|
118644
|
-
const trimmed = message.trimEnd();
|
|
118645
|
-
if (trimmed.startsWith(ENHANCER_LOG_PREFIX))
|
|
118646
|
-
return trimmed;
|
|
118647
|
-
return `${ENHANCER_LOG_PREFIX} ${trimmed}`;
|
|
118648
|
-
}
|
|
118649
|
-
function createEnhancerLogWriter(logSink, context5, clock4 = () => Date.now()) {
|
|
118650
|
-
return {
|
|
118651
|
-
write(message) {
|
|
118652
|
-
const formatted = formatEnhancerLogLine(message);
|
|
118653
|
-
logSink?.write({
|
|
118654
|
-
timestamp: clock4(),
|
|
118655
|
-
level: "info",
|
|
118656
|
-
source: `harness:${context5.harness}`,
|
|
118657
|
-
stream: "stdout",
|
|
118658
|
-
message: formatted,
|
|
118659
|
-
metadata: {
|
|
118660
|
-
chatroomId: context5.chatroomId,
|
|
118661
|
-
role: ENHANCER_AGENT_ROLE,
|
|
118662
|
-
harness: context5.harness,
|
|
118663
|
-
...context5.pid !== undefined ? { pid: context5.pid } : {}
|
|
118664
|
-
}
|
|
118665
|
-
});
|
|
118666
|
-
}
|
|
118667
|
-
};
|
|
118668
|
-
}
|
|
118669
|
-
var ENHANCER_LOG_PREFIX = "[enhancer]";
|
|
118670
|
-
var init_enhancer_log = () => {};
|
|
118671
|
-
|
|
118672
|
-
// src/daemon/entry/enhancer/enhancer-spawn-registry.ts
|
|
118673
|
-
function registerEnhancerSpawn(handle) {
|
|
118674
|
-
const handles = byChatroom.get(handle.chatroomId) ?? new Set;
|
|
118675
|
-
handles.add(handle);
|
|
118676
|
-
byChatroom.set(handle.chatroomId, handles);
|
|
118677
|
-
}
|
|
118678
|
-
function unregisterEnhancerSpawn(handle) {
|
|
118679
|
-
const handles = byChatroom.get(handle.chatroomId);
|
|
118680
|
-
if (!handles)
|
|
118681
|
-
return;
|
|
118682
|
-
handles.delete(handle);
|
|
118683
|
-
if (handles.size === 0)
|
|
118684
|
-
byChatroom.delete(handle.chatroomId);
|
|
118685
|
-
}
|
|
118686
|
-
async function abortEnhancerSpawnsForChatroom(chatroomId) {
|
|
118687
|
-
const handles = byChatroom.get(chatroomId);
|
|
118688
|
-
if (!handles)
|
|
118689
|
-
return;
|
|
118690
|
-
await Promise.all([...handles].map(async (handle) => {
|
|
118691
|
-
handle.abort();
|
|
118692
|
-
await handle.stopProcess().catch(() => {
|
|
118693
|
-
return;
|
|
118694
|
-
});
|
|
118695
|
-
}));
|
|
118696
|
-
}
|
|
118697
|
-
var byChatroom;
|
|
118698
|
-
var init_enhancer_spawn_registry = __esm(() => {
|
|
118699
|
-
byChatroom = new Map;
|
|
118700
|
-
});
|
|
118701
|
-
|
|
118702
|
-
// src/daemon/entry/enhancer/job-outcome-subscription.ts
|
|
118703
|
-
function subscribeToEnhancerJobOutcome(args2) {
|
|
118704
|
-
let currentState = null;
|
|
118705
|
-
let resolveOutcome = null;
|
|
118706
|
-
let rejectOutcome = null;
|
|
118707
|
-
let stopped = false;
|
|
118708
|
-
const outcome = new Promise((resolve5, reject) => {
|
|
118709
|
-
resolveOutcome = resolve5;
|
|
118710
|
-
rejectOutcome = reject;
|
|
118711
|
-
});
|
|
118712
|
-
const unsub = args2.wsClient.onUpdate(api.web.enhancer.index.getJobOutcome, {
|
|
118713
|
-
sessionId: args2.sessionId,
|
|
118714
|
-
chatroomId: args2.chatroomId,
|
|
118715
|
-
jobId: args2.jobId
|
|
118716
|
-
}, (state) => {
|
|
118717
|
-
if (stopped)
|
|
118718
|
-
return;
|
|
118719
|
-
if (!state) {
|
|
118720
|
-
rejectOutcome?.(new Error("Enhancer job not found"));
|
|
118721
|
-
resolveOutcome = null;
|
|
118722
|
-
rejectOutcome = null;
|
|
118723
|
-
return;
|
|
118724
|
-
}
|
|
118725
|
-
currentState = state;
|
|
118726
|
-
if (state.status === "complete" || state.status === "failed" || state.status === "cancelled") {
|
|
118727
|
-
resolveOutcome?.(state);
|
|
118728
|
-
resolveOutcome = null;
|
|
118729
|
-
rejectOutcome = null;
|
|
118730
|
-
}
|
|
118731
|
-
}, (error51) => {
|
|
118732
|
-
if (stopped)
|
|
118733
|
-
return;
|
|
118734
|
-
rejectOutcome?.(error51);
|
|
118735
|
-
resolveOutcome = null;
|
|
118736
|
-
rejectOutcome = null;
|
|
118737
|
-
});
|
|
118738
|
-
return {
|
|
118739
|
-
outcome,
|
|
118740
|
-
getCurrentState: () => currentState,
|
|
118741
|
-
stop: () => {
|
|
118742
|
-
if (stopped)
|
|
118743
|
-
return;
|
|
118744
|
-
stopped = true;
|
|
118745
|
-
unsub();
|
|
118746
|
-
resolveOutcome = null;
|
|
118747
|
-
rejectOutcome = null;
|
|
118748
|
-
}
|
|
118749
|
-
};
|
|
118750
|
-
}
|
|
118751
|
-
var init_job_outcome_subscription = __esm(() => {
|
|
118752
|
-
init_api3();
|
|
118753
|
-
});
|
|
118754
|
-
|
|
118755
|
-
// src/daemon/entry/enhancer/wait-for-enhancer-job.ts
|
|
118756
|
-
async function waitForEnhancerJobResolution(params) {
|
|
118757
|
-
const { sessionId, chatroomId, jobId, wsClient: wsClient2, onFailure, onSalvageComplete, log: log4, signal } = params;
|
|
118758
|
-
const writeLog = (message) => log4?.write(message);
|
|
118759
|
-
let outcome = null;
|
|
118760
|
-
let salvagedText = "";
|
|
118761
|
-
let agentEndTimer = null;
|
|
118762
|
-
let resolveWait = null;
|
|
118763
|
-
const waitPromise = new Promise((resolve5) => {
|
|
118764
|
-
resolveWait = resolve5;
|
|
118765
|
-
});
|
|
118766
|
-
const subscription = subscribeToEnhancerJobOutcome({
|
|
118767
|
-
wsClient: wsClient2,
|
|
118768
|
-
sessionId,
|
|
118769
|
-
chatroomId,
|
|
118770
|
-
jobId
|
|
118771
|
-
});
|
|
118772
|
-
const finish = (resolution) => {
|
|
118773
|
-
if (outcome)
|
|
118774
|
-
return;
|
|
118775
|
-
outcome = resolution;
|
|
118776
|
-
resolveWait?.();
|
|
118777
|
-
resolveWait = null;
|
|
118778
|
-
};
|
|
118779
|
-
const onAbort = () => finish("aborted");
|
|
118780
|
-
if (signal?.aborted)
|
|
118781
|
-
onAbort();
|
|
118782
|
-
else
|
|
118783
|
-
signal?.addEventListener("abort", onAbort, { once: true });
|
|
118784
|
-
const failAfterAgentEnd = () => {
|
|
118785
|
-
writeLog("agent_end: turn ended without complete — failing terminal");
|
|
118786
|
-
onFailure("Agent exited without completing enhancer job", true);
|
|
118787
|
-
finish("failed");
|
|
118788
|
-
};
|
|
118789
|
-
subscription.outcome.then((state) => {
|
|
118790
|
-
if (outcome)
|
|
118791
|
-
return;
|
|
118792
|
-
const resolution = state.status === "complete" ? "complete" : "failed";
|
|
118793
|
-
if (resolution === "complete")
|
|
118794
|
-
writeLog(`completed job=${jobId}`);
|
|
118795
|
-
finish(resolution);
|
|
118796
|
-
}).catch((error51) => {
|
|
118797
|
-
if (outcome)
|
|
118798
|
-
return;
|
|
118799
|
-
writeLog(`enhancer outcome subscription failed: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
118800
|
-
onFailure("Enhancer job outcome subscription failed", false);
|
|
118801
|
-
finish("failed");
|
|
118802
|
-
});
|
|
118803
|
-
params.onAssistantText?.((text) => {
|
|
118804
|
-
salvagedText += text;
|
|
118805
|
-
});
|
|
118806
|
-
params.onAgentEnd?.(() => {
|
|
118807
|
-
if (outcome)
|
|
118808
|
-
return;
|
|
118809
|
-
agentEndTimer = setTimeout(() => {
|
|
118810
|
-
if (outcome)
|
|
118811
|
-
return;
|
|
118812
|
-
const state = subscription.getCurrentState();
|
|
118813
|
-
if (state?.status === "complete") {
|
|
118814
|
-
finish("complete");
|
|
118815
|
-
return;
|
|
118816
|
-
}
|
|
118817
|
-
if (state?.status !== "running") {
|
|
118818
|
-
failAfterAgentEnd();
|
|
118819
|
-
return;
|
|
118820
|
-
}
|
|
118821
|
-
const trimmed = salvagedText.trim();
|
|
118822
|
-
if (!trimmed || !onSalvageComplete) {
|
|
118823
|
-
failAfterAgentEnd();
|
|
118824
|
-
return;
|
|
118825
|
-
}
|
|
118826
|
-
onSalvageComplete(trimmed).catch(() => {
|
|
118827
|
-
failAfterAgentEnd();
|
|
118828
|
-
});
|
|
118829
|
-
}, ENHANCER_AGENT_END_GRACE_MS);
|
|
118830
|
-
});
|
|
118831
|
-
params.onExit(() => {
|
|
118832
|
-
if (outcome)
|
|
118833
|
-
return;
|
|
118834
|
-
onFailure("Agent process exited without completing enhancer job", false);
|
|
118835
|
-
finish("failed");
|
|
118836
|
-
});
|
|
118837
|
-
await waitPromise;
|
|
118838
|
-
if (agentEndTimer)
|
|
118839
|
-
clearTimeout(agentEndTimer);
|
|
118840
|
-
subscription.stop();
|
|
118841
|
-
signal?.removeEventListener("abort", onAbort);
|
|
118842
|
-
return outcome ?? "failed";
|
|
118843
|
-
}
|
|
118844
|
-
var init_wait_for_enhancer_job = __esm(() => {
|
|
118845
|
-
init_job_outcome_subscription();
|
|
118846
|
-
});
|
|
118847
|
-
|
|
118848
|
-
// src/daemon/entry/enhancer-inbound-registry.ts
|
|
118849
|
-
function registerEnhancerInboundHandler(h) {
|
|
118970
|
+
// src/daemon/entry/file-inbound-registry.ts
|
|
118971
|
+
function registerFileInboundHandler(h) {
|
|
118850
118972
|
handler3 = h;
|
|
118851
118973
|
}
|
|
118852
|
-
function
|
|
118974
|
+
function unregisterFileInboundHandler() {
|
|
118853
118975
|
handler3 = undefined;
|
|
118854
118976
|
}
|
|
118855
|
-
async function
|
|
118977
|
+
async function dispatchFileInboundEvent(event) {
|
|
118856
118978
|
if (handler3)
|
|
118857
118979
|
await handler3(event);
|
|
118858
118980
|
}
|
|
118859
118981
|
var handler3;
|
|
118860
118982
|
|
|
118861
|
-
// src/daemon/entry/enhancer/job-subscriber.ts
|
|
118862
|
-
async function processEnhancerJobForSpawn(sessionId, machineId, convexUrl, wsClient2, backend2, agentServices, job, inFlight2, logSink) {
|
|
118863
|
-
if (inFlight2.has(job.jobId))
|
|
118864
|
-
return;
|
|
118865
|
-
if (isChatroomStopScopeActive(job.chatroomId))
|
|
118866
|
-
return;
|
|
118867
|
-
inFlight2.add(job.jobId);
|
|
118868
|
-
let claimed = false;
|
|
118869
|
-
let chatroomId = job.chatroomId;
|
|
118870
|
-
let jobId = job.jobId;
|
|
118871
|
-
let spawnResult = null;
|
|
118872
|
-
let service4 = null;
|
|
118873
|
-
let abortController = null;
|
|
118874
|
-
let spawnHandle = null;
|
|
118875
|
-
let agentEndSeen = false;
|
|
118876
|
-
let resolveAgentEnd;
|
|
118877
|
-
let agentEndPromise = Promise.resolve();
|
|
118878
|
-
let log4 = createEnhancerLogWriter(logSink, {
|
|
118879
|
-
chatroomId: job.chatroomId,
|
|
118880
|
-
harness: "unknown"
|
|
118881
|
-
});
|
|
118882
|
-
try {
|
|
118883
|
-
const claim = await backend2.mutation(api.daemon.enhancer.index.claimForSpawn, {
|
|
118884
|
-
sessionId,
|
|
118885
|
-
jobId: job.jobId,
|
|
118886
|
-
machineId
|
|
118887
|
-
});
|
|
118888
|
-
if (!claim.claimed)
|
|
118889
|
-
return;
|
|
118890
|
-
claimed = true;
|
|
118891
|
-
log4.write(`claimed job=${job.jobId} chatroom=${job.chatroomId}`);
|
|
118892
|
-
const payload = await backend2.query(api.daemon.enhancer.index.getTaskDeliveryForJob, {
|
|
118893
|
-
sessionId,
|
|
118894
|
-
jobId: job.jobId,
|
|
118895
|
-
convexUrl
|
|
118896
|
-
});
|
|
118897
|
-
chatroomId = payload.chatroomId;
|
|
118898
|
-
jobId = payload.jobId;
|
|
118899
|
-
log4 = createEnhancerLogWriter(logSink, {
|
|
118900
|
-
chatroomId: payload.chatroomId,
|
|
118901
|
-
harness: payload.agentHarness,
|
|
118902
|
-
pid: undefined
|
|
118903
|
-
});
|
|
118904
|
-
log4.write(`spawning harness=${payload.agentHarness} model=${payload.model} job=${payload.jobId}`);
|
|
118905
|
-
service4 = agentServices.get(payload.agentHarness) ?? null;
|
|
118906
|
-
if (!service4) {
|
|
118907
|
-
await backend2.mutation(api.web.enhancer.index.recordAttemptFailure, {
|
|
118908
|
-
sessionId,
|
|
118909
|
-
chatroomId: payload.chatroomId,
|
|
118910
|
-
jobId: payload.jobId,
|
|
118911
|
-
error: `Harness ${payload.agentHarness} not available on machine`
|
|
118912
|
-
});
|
|
118913
|
-
return;
|
|
118914
|
-
}
|
|
118915
|
-
const spawned = await service4.spawn({
|
|
118916
|
-
workingDir: payload.workingDir,
|
|
118917
|
-
prompt: createSpawnPrompt(payload.taskDeliveryOutput),
|
|
118918
|
-
systemPrompt: payload.systemPrompt,
|
|
118919
|
-
model: payload.model,
|
|
118920
|
-
context: {
|
|
118921
|
-
machineId,
|
|
118922
|
-
chatroomId: payload.chatroomId,
|
|
118923
|
-
role: ENHANCER_AGENT_ROLE
|
|
118924
|
-
},
|
|
118925
|
-
resolvedConvexUrl: convexUrl
|
|
118926
|
-
});
|
|
118927
|
-
spawnResult = spawned;
|
|
118928
|
-
abortController = new AbortController;
|
|
118929
|
-
spawnHandle = {
|
|
118930
|
-
jobId: payload.jobId,
|
|
118931
|
-
chatroomId: payload.chatroomId,
|
|
118932
|
-
abort: () => abortController?.abort(),
|
|
118933
|
-
stopProcess: async () => {
|
|
118934
|
-
await service4?.stop(spawned.pid);
|
|
118935
|
-
}
|
|
118936
|
-
};
|
|
118937
|
-
registerEnhancerSpawn(spawnHandle);
|
|
118938
|
-
log4 = createEnhancerLogWriter(logSink, {
|
|
118939
|
-
chatroomId: payload.chatroomId,
|
|
118940
|
-
harness: payload.agentHarness,
|
|
118941
|
-
pid: spawned.pid
|
|
118942
|
-
});
|
|
118943
|
-
spawned.onLogLine?.((line) => {
|
|
118944
|
-
log4.write(line);
|
|
118945
|
-
});
|
|
118946
|
-
agentEndPromise = new Promise((resolve5) => {
|
|
118947
|
-
resolveAgentEnd = resolve5;
|
|
118948
|
-
});
|
|
118949
|
-
spawned.onAgentEnd?.(() => {
|
|
118950
|
-
if (agentEndSeen)
|
|
118951
|
-
return;
|
|
118952
|
-
agentEndSeen = true;
|
|
118953
|
-
resolveAgentEnd?.();
|
|
118954
|
-
});
|
|
118955
|
-
await waitForEnhancerJobResolution({
|
|
118956
|
-
sessionId,
|
|
118957
|
-
chatroomId: payload.chatroomId,
|
|
118958
|
-
jobId: payload.jobId,
|
|
118959
|
-
wsClient: wsClient2,
|
|
118960
|
-
log: log4,
|
|
118961
|
-
onAssistantText: spawned.onAssistantText ? (cb) => spawned.onAssistantText?.(cb) : undefined,
|
|
118962
|
-
onAgentEnd: spawned.onAgentEnd ? (cb) => spawned.onAgentEnd?.(cb) : undefined,
|
|
118963
|
-
onExit: (cb) => spawned.onExit(() => cb()),
|
|
118964
|
-
onSalvageComplete: async (content) => {
|
|
118965
|
-
await backend2.mutation(api.web.enhancer.index.complete, {
|
|
118966
|
-
sessionId,
|
|
118967
|
-
chatroomId: payload.chatroomId,
|
|
118968
|
-
jobId: payload.jobId,
|
|
118969
|
-
enhancedContent: content
|
|
118970
|
-
});
|
|
118971
|
-
},
|
|
118972
|
-
onFailure: async (error51, forceTerminal) => {
|
|
118973
|
-
await backend2.mutation(api.web.enhancer.index.recordAttemptFailure, {
|
|
118974
|
-
sessionId,
|
|
118975
|
-
chatroomId: payload.chatroomId,
|
|
118976
|
-
jobId: payload.jobId,
|
|
118977
|
-
error: error51,
|
|
118978
|
-
...forceTerminal ? { forceTerminal: true } : {}
|
|
118979
|
-
});
|
|
118980
|
-
},
|
|
118981
|
-
signal: abortController.signal
|
|
118982
|
-
});
|
|
118983
|
-
if (!abortController.signal.aborted)
|
|
118984
|
-
log4.write(`completed job=${jobId}`);
|
|
118985
|
-
} catch (err) {
|
|
118986
|
-
log4.write(`error: ${err instanceof Error ? err.message : String(err)}`);
|
|
118987
|
-
if (claimed) {
|
|
118988
|
-
await backend2.mutation(api.web.enhancer.index.recordAttemptFailure, {
|
|
118989
|
-
sessionId,
|
|
118990
|
-
chatroomId,
|
|
118991
|
-
jobId,
|
|
118992
|
-
error: err instanceof Error ? err.message : String(err)
|
|
118993
|
-
});
|
|
118994
|
-
}
|
|
118995
|
-
} finally {
|
|
118996
|
-
inFlight2.delete(job.jobId);
|
|
118997
|
-
if (spawnHandle)
|
|
118998
|
-
unregisterEnhancerSpawn(spawnHandle);
|
|
118999
|
-
if (spawnResult && service4) {
|
|
119000
|
-
if (!agentEndSeen)
|
|
119001
|
-
await Promise.race([
|
|
119002
|
-
agentEndPromise,
|
|
119003
|
-
new Promise((resolve5) => setTimeout(resolve5, ENHANCER_AGENT_END_GRACE_MS))
|
|
119004
|
-
]);
|
|
119005
|
-
try {
|
|
119006
|
-
await service4.stop(spawnResult.pid);
|
|
119007
|
-
} catch {}
|
|
119008
|
-
}
|
|
119009
|
-
}
|
|
119010
|
-
}
|
|
119011
|
-
function processEnhancerJobs(sessionId, machineId, convexUrl, wsClient2, backend2, agentServices, jobs, inFlight2, logSink) {
|
|
119012
|
-
for (const job of jobs ?? []) {
|
|
119013
|
-
processEnhancerJobForSpawn(sessionId, machineId, convexUrl, wsClient2, backend2, agentServices, job, inFlight2, logSink);
|
|
119014
|
-
}
|
|
119015
|
-
}
|
|
119016
|
-
async function drainPendingEnhancerJobs(sessionId, machineId, convexUrl, wsClient2, backend2, agentServices, inFlight2, logSink) {
|
|
119017
|
-
const jobs = await backend2.query(api.daemon.enhancer.index.pendingForMachine, {
|
|
119018
|
-
sessionId,
|
|
119019
|
-
machineId
|
|
119020
|
-
});
|
|
119021
|
-
if (!jobs?.length)
|
|
119022
|
-
return;
|
|
119023
|
-
processEnhancerJobs(sessionId, machineId, convexUrl, wsClient2, backend2, agentServices, jobs, inFlight2, logSink);
|
|
119024
|
-
}
|
|
119025
|
-
function startEnhancerJobSubscriber(sessionId, machineId, convexUrl, wsClient2, backend2, agentServices, logSink) {
|
|
119026
|
-
const inFlight2 = new Set;
|
|
119027
|
-
registerEnhancerInboundHandler(async () => {
|
|
119028
|
-
await drainPendingEnhancerJobs(sessionId, machineId, convexUrl, wsClient2, backend2, agentServices, inFlight2, logSink);
|
|
119029
|
-
});
|
|
119030
|
-
setEnhancerDrainHandler(() => drainPendingEnhancerJobs(sessionId, machineId, convexUrl, wsClient2, backend2, agentServices, inFlight2, logSink));
|
|
119031
|
-
return {
|
|
119032
|
-
stop: () => {
|
|
119033
|
-
unregisterEnhancerInboundHandler();
|
|
119034
|
-
clearEnhancerDrainHandlerForTests();
|
|
119035
|
-
},
|
|
119036
|
-
drainPendingEnhancerJobs: () => drainPendingEnhancerJobs(sessionId, machineId, convexUrl, wsClient2, backend2, agentServices, inFlight2, logSink)
|
|
119037
|
-
};
|
|
119038
|
-
}
|
|
119039
|
-
var init_job_subscriber = __esm(() => {
|
|
119040
|
-
init_enhancer_log();
|
|
119041
|
-
init_enhancer_spawn_registry();
|
|
119042
|
-
init_wait_for_enhancer_job();
|
|
119043
|
-
init_api3();
|
|
119044
|
-
init_service_interfaces();
|
|
119045
|
-
});
|
|
119046
|
-
|
|
119047
|
-
// src/daemon/entry/enhancer/start-subscriptions.ts
|
|
119048
|
-
function startEnhancerSubscriptions(sessionId, machineId, convexUrl, wsClient2, backend2, agentServices, logSink) {
|
|
119049
|
-
return startEnhancerJobSubscriber(sessionId, machineId, convexUrl, wsClient2, backend2, agentServices, logSink);
|
|
119050
|
-
}
|
|
119051
|
-
var init_start_subscriptions2 = __esm(() => {
|
|
119052
|
-
init_job_subscriber();
|
|
119053
|
-
});
|
|
119054
|
-
|
|
119055
|
-
// src/daemon/entry/file-inbound-registry.ts
|
|
119056
|
-
function registerFileInboundHandler(h) {
|
|
119057
|
-
handler4 = h;
|
|
119058
|
-
}
|
|
119059
|
-
function unregisterFileInboundHandler() {
|
|
119060
|
-
handler4 = undefined;
|
|
119061
|
-
}
|
|
119062
|
-
async function dispatchFileInboundEvent(event) {
|
|
119063
|
-
if (handler4)
|
|
119064
|
-
await handler4(event);
|
|
119065
|
-
}
|
|
119066
|
-
var handler4;
|
|
119067
|
-
|
|
119068
118983
|
// src/daemon/entry/files/file-content-classifier.ts
|
|
119069
118984
|
function extensionOf(path3) {
|
|
119070
118985
|
const lastDot = path3.lastIndexOf(".");
|
|
@@ -119183,7 +119098,7 @@ var init_assert_registered_working_dir = __esm(() => {
|
|
|
119183
119098
|
|
|
119184
119099
|
// src/infrastructure/services/workspace/workspace-path-security.ts
|
|
119185
119100
|
import { realpath } from "node:fs/promises";
|
|
119186
|
-
import { dirname as
|
|
119101
|
+
import { dirname as dirname12, isAbsolute, relative as relative2, resolve as resolve5, sep } from "node:path";
|
|
119187
119102
|
import { gunzipSync } from "node:zlib";
|
|
119188
119103
|
function validateRelativePathSegments(filePath) {
|
|
119189
119104
|
if (filePath.includes("\x00"))
|
|
@@ -119211,7 +119126,7 @@ function assertContained(workspaceRoot, targetPath) {
|
|
|
119211
119126
|
return { ok: true };
|
|
119212
119127
|
}
|
|
119213
119128
|
async function resolveNonExistentTarget(workspaceRoot, candidate) {
|
|
119214
|
-
let current =
|
|
119129
|
+
let current = dirname12(candidate);
|
|
119215
119130
|
for (;; ) {
|
|
119216
119131
|
try {
|
|
119217
119132
|
const ancestorReal = await realpath(current);
|
|
@@ -119229,7 +119144,7 @@ async function resolveNonExistentTarget(workspaceRoot, candidate) {
|
|
|
119229
119144
|
if (code2 !== "ENOENT") {
|
|
119230
119145
|
return { ok: false, error: "Invalid file path" };
|
|
119231
119146
|
}
|
|
119232
|
-
const parent =
|
|
119147
|
+
const parent = dirname12(current);
|
|
119233
119148
|
if (parent === current) {
|
|
119234
119149
|
return { ok: false, error: "Path escapes workspace" };
|
|
119235
119150
|
}
|
|
@@ -120033,16 +119948,16 @@ var require_ignore = __commonJS((exports, module) => {
|
|
|
120033
119948
|
// src/infrastructure/services/workspace/workspace-ignore.ts
|
|
120034
119949
|
import { promises as fsPromises } from "node:fs";
|
|
120035
119950
|
import { readFile as readFile10 } from "node:fs/promises";
|
|
120036
|
-
import { homedir as
|
|
119951
|
+
import { homedir as homedir10 } from "node:os";
|
|
120037
119952
|
import path3 from "node:path";
|
|
120038
119953
|
function normalizeRelativePath(relativePath) {
|
|
120039
119954
|
return relativePath.replace(/\\/g, "/").replace(/^\.?\//, "").replace(/\/+$/, "");
|
|
120040
119955
|
}
|
|
120041
119956
|
function expandUserPath(filePath) {
|
|
120042
119957
|
if (filePath === "~")
|
|
120043
|
-
return
|
|
119958
|
+
return homedir10();
|
|
120044
119959
|
if (filePath.startsWith("~/"))
|
|
120045
|
-
return path3.join(
|
|
119960
|
+
return path3.join(homedir10(), filePath.slice(2));
|
|
120046
119961
|
return filePath;
|
|
120047
119962
|
}
|
|
120048
119963
|
function readExcludesFileFromGitconfig(content) {
|
|
@@ -120073,11 +119988,11 @@ async function readGitconfigExcludesFilePath(configPath) {
|
|
|
120073
119988
|
return path3.isAbsolute(raw) ? expandUserPath(raw) : path3.resolve(path3.dirname(configPath), raw);
|
|
120074
119989
|
}
|
|
120075
119990
|
async function resolveGitExtraExcludeFilePaths(rootDir) {
|
|
120076
|
-
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");
|
|
120077
119992
|
const localConfig = path3.join(rootDir, ".git", "config");
|
|
120078
119993
|
let excludesFile = await readGitconfigExcludesFilePath(localConfig) ?? await readGitconfigExcludesFilePath(globalConfig2);
|
|
120079
119994
|
if (!excludesFile) {
|
|
120080
|
-
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");
|
|
120081
119996
|
}
|
|
120082
119997
|
const candidates = [excludesFile, path3.join(rootDir, ".git", "info", "exclude")];
|
|
120083
119998
|
const existing = [];
|
|
@@ -121213,9 +121128,9 @@ class NodeFsHandler {
|
|
|
121213
121128
|
if (this.fsw.closed) {
|
|
121214
121129
|
return;
|
|
121215
121130
|
}
|
|
121216
|
-
const
|
|
121131
|
+
const dirname14 = sp.dirname(file2);
|
|
121217
121132
|
const basename4 = sp.basename(file2);
|
|
121218
|
-
const parent = this.fsw._getWatchedDir(
|
|
121133
|
+
const parent = this.fsw._getWatchedDir(dirname14);
|
|
121219
121134
|
let prevStats = stats;
|
|
121220
121135
|
if (parent.has(basename4))
|
|
121221
121136
|
return;
|
|
@@ -121242,7 +121157,7 @@ class NodeFsHandler {
|
|
|
121242
121157
|
prevStats = newStats2;
|
|
121243
121158
|
}
|
|
121244
121159
|
} catch (error51) {
|
|
121245
|
-
this.fsw._remove(
|
|
121160
|
+
this.fsw._remove(dirname14, basename4);
|
|
121246
121161
|
}
|
|
121247
121162
|
} else if (parent.has(basename4)) {
|
|
121248
121163
|
const at = newStats.atimeMs;
|
|
@@ -122631,8 +122546,8 @@ function diffPathIndexes(previous, next4) {
|
|
|
122631
122546
|
// src/infrastructure/services/workspace/workspace-sync-state.ts
|
|
122632
122547
|
import { createHash as createHash7, randomUUID as randomUUID12 } from "node:crypto";
|
|
122633
122548
|
import * as fs11 from "node:fs/promises";
|
|
122634
|
-
import { homedir as
|
|
122635
|
-
import { join as
|
|
122549
|
+
import { homedir as homedir11 } from "node:os";
|
|
122550
|
+
import { join as join27 } from "node:path";
|
|
122636
122551
|
function workspaceKeyFor(workingDir) {
|
|
122637
122552
|
const normalized = normalizeWorkingDirForLookup(workingDir);
|
|
122638
122553
|
return createHash7("sha256").update(normalized).digest("hex").slice(0, 16);
|
|
@@ -122646,10 +122561,10 @@ function buildPathIndex(entries2) {
|
|
|
122646
122561
|
}
|
|
122647
122562
|
function manifestPath(machineId, workingDir) {
|
|
122648
122563
|
const key = workspaceKeyFor(workingDir);
|
|
122649
|
-
return
|
|
122564
|
+
return join27(SYNC_STATE_DIR, machineId, key, "manifest.json");
|
|
122650
122565
|
}
|
|
122651
122566
|
async function ensureDir(filePath) {
|
|
122652
|
-
await fs11.mkdir(
|
|
122567
|
+
await fs11.mkdir(join27(filePath, ".."), { recursive: true, mode: 448 });
|
|
122653
122568
|
}
|
|
122654
122569
|
async function loadWorkspaceSyncManifest(machineId, workingDir) {
|
|
122655
122570
|
try {
|
|
@@ -122709,7 +122624,7 @@ function entriesFromPathIndex(paths) {
|
|
|
122709
122624
|
}
|
|
122710
122625
|
var SYNC_STATE_VERSION = "2", SYNC_STATE_DIR;
|
|
122711
122626
|
var init_workspace_sync_state = __esm(() => {
|
|
122712
|
-
SYNC_STATE_DIR =
|
|
122627
|
+
SYNC_STATE_DIR = join27(homedir11(), ".chatroom", "sync-state");
|
|
122713
122628
|
});
|
|
122714
122629
|
|
|
122715
122630
|
// src/infrastructure/services/workspace/workspace-file-tree-coordinator.ts
|
|
@@ -123087,12 +123002,12 @@ var init_durable_coalescing_state_schema = __esm(() => {
|
|
|
123087
123002
|
});
|
|
123088
123003
|
|
|
123089
123004
|
// src/daemon/infrastructure/outbox/lib/durable-coalescing-state-store.ts
|
|
123090
|
-
import { mkdirSync as
|
|
123091
|
-
import { dirname as
|
|
123092
|
-
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";
|
|
123093
123008
|
function openDurableCoalescingStateStore(path8) {
|
|
123094
|
-
|
|
123095
|
-
const db = new
|
|
123009
|
+
mkdirSync9(dirname15(path8), { recursive: true });
|
|
123010
|
+
const db = new DatabaseSync4(path8);
|
|
123096
123011
|
for (const sql of DURABLE_COALESCING_STATE_MIGRATIONS)
|
|
123097
123012
|
db.exec(sql);
|
|
123098
123013
|
db.prepare("UPDATE coalescing_outbox_entries SET status='pending' WHERE status='in_flight'").run();
|
|
@@ -124080,7 +123995,7 @@ var init_file_write_request_priority = __esm(() => {
|
|
|
124080
123995
|
|
|
124081
123996
|
// src/daemon/entry/files/file-write-fulfillment.ts
|
|
124082
123997
|
import { access as access4, mkdir as mkdir10, rename as rename4, rm as rm4, writeFile as writeFile10 } from "node:fs/promises";
|
|
124083
|
-
import { dirname as
|
|
123998
|
+
import { dirname as dirname16 } from "node:path";
|
|
124084
123999
|
function isTerminalFileWriteError(errorMessage) {
|
|
124085
124000
|
const terminalMessages = new Set([
|
|
124086
124001
|
"Invalid file path",
|
|
@@ -124179,7 +124094,7 @@ async function validateWriteOperation(operation, absolutePath) {
|
|
|
124179
124094
|
}
|
|
124180
124095
|
async function writePayloadToDisk(absolutePath, operation, content) {
|
|
124181
124096
|
if (operation === "create") {
|
|
124182
|
-
await mkdir10(
|
|
124097
|
+
await mkdir10(dirname16(absolutePath), { recursive: true });
|
|
124183
124098
|
await writeFile10(absolutePath, content, { flag: "wx" });
|
|
124184
124099
|
return;
|
|
124185
124100
|
}
|
|
@@ -124257,7 +124172,7 @@ async function fulfillOneFileWriteRequest(session2, request2) {
|
|
|
124257
124172
|
});
|
|
124258
124173
|
return;
|
|
124259
124174
|
}
|
|
124260
|
-
await mkdir10(
|
|
124175
|
+
await mkdir10(dirname16(targetResolved.absolutePath), { recursive: true });
|
|
124261
124176
|
await rename4(resolved.absolutePath, targetResolved.absolutePath);
|
|
124262
124177
|
await completeWriteRequest(session2, claimed._id, claimed.revision, { status: "done" });
|
|
124263
124178
|
const elapsed4 = Date.now() - startTime;
|
|
@@ -125332,16 +125247,16 @@ var init_workspace_list_subscription = __esm(() => {
|
|
|
125332
125247
|
|
|
125333
125248
|
// src/daemon/entry/workspace-git-inbound-registry.ts
|
|
125334
125249
|
function registerWorkspaceGitInboundHandler(h) {
|
|
125335
|
-
|
|
125250
|
+
handler4 = h;
|
|
125336
125251
|
}
|
|
125337
125252
|
function unregisterWorkspaceGitInboundHandler() {
|
|
125338
|
-
|
|
125253
|
+
handler4 = undefined;
|
|
125339
125254
|
}
|
|
125340
125255
|
async function dispatchWorkspaceGitInboundEvent(event) {
|
|
125341
|
-
if (
|
|
125342
|
-
await
|
|
125256
|
+
if (handler4)
|
|
125257
|
+
await handler4(event);
|
|
125343
125258
|
}
|
|
125344
|
-
var
|
|
125259
|
+
var handler4;
|
|
125345
125260
|
|
|
125346
125261
|
// src/events/lifecycle/on-daemon-shutdown.ts
|
|
125347
125262
|
var onDaemonShutdownEffect;
|
|
@@ -125359,6 +125274,19 @@ var init_on_daemon_shutdown = __esm(() => {
|
|
|
125359
125274
|
const activeAgents = agentPm.listActive();
|
|
125360
125275
|
if (activeAgents.length > 0) {
|
|
125361
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
|
+
});
|
|
125362
125290
|
let totalStopped = 0;
|
|
125363
125291
|
let totalFailed = 0;
|
|
125364
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(() => {
|
|
@@ -125388,7 +125316,6 @@ function createDaemonRuntime(deps) {
|
|
|
125388
125316
|
let workspaceListSubscriptionHandle = null;
|
|
125389
125317
|
let logObserverSubscriptionHandle = null;
|
|
125390
125318
|
let agenticQueryWorkerHandle = null;
|
|
125391
|
-
let enhancerWorkerHandle = null;
|
|
125392
125319
|
let taskInboxHandle = null;
|
|
125393
125320
|
let agentConfigRegistryHandle = null;
|
|
125394
125321
|
const activeSessions = new Map;
|
|
@@ -125429,7 +125356,6 @@ function createDaemonRuntime(deps) {
|
|
|
125429
125356
|
taskInboxHandle?.stop();
|
|
125430
125357
|
logObserverSubscriptionHandle?.stop();
|
|
125431
125358
|
agenticQueryWorkerHandle?.stop();
|
|
125432
|
-
enhancerWorkerHandle?.stop();
|
|
125433
125359
|
};
|
|
125434
125360
|
const shutdown = async () => {
|
|
125435
125361
|
if (isShuttingDown)
|
|
@@ -125547,7 +125473,6 @@ function createDaemonRuntime(deps) {
|
|
|
125547
125473
|
backend: session2.backend,
|
|
125548
125474
|
convexUrl: session2.convexUrl
|
|
125549
125475
|
}, activeSessions, harnesses);
|
|
125550
|
-
enhancerWorkerHandle = startEnhancerSubscriptions(session2.sessionId, session2.machineId, session2.convexUrl, deps.wsClient, session2.backend, session2.agentServices, getActiveLogSink());
|
|
125551
125476
|
console.log(`
|
|
125552
125477
|
Listening for commands...`);
|
|
125553
125478
|
console.log(`Press Ctrl+C to stop
|
|
@@ -125584,7 +125509,6 @@ var init_daemon_runtime = __esm(() => {
|
|
|
125584
125509
|
init_start_subscriptions();
|
|
125585
125510
|
init_command_dispatch();
|
|
125586
125511
|
init_daemon_services();
|
|
125587
|
-
init_start_subscriptions2();
|
|
125588
125512
|
init_file_content_subscription();
|
|
125589
125513
|
init_file_tree_subscription();
|
|
125590
125514
|
init_file_write_subscription();
|
|
@@ -125592,7 +125516,6 @@ var init_daemon_runtime = __esm(() => {
|
|
|
125592
125516
|
init_orphan_tracker();
|
|
125593
125517
|
init_command_run_subscription();
|
|
125594
125518
|
init_log_observer_sync();
|
|
125595
|
-
init_init_daemon();
|
|
125596
125519
|
init_task_inbox_runtime();
|
|
125597
125520
|
init_git_subscription();
|
|
125598
125521
|
init_api3();
|
|
@@ -125635,21 +125558,6 @@ function createCommandRouterDeps() {
|
|
|
125635
125558
|
}
|
|
125636
125559
|
var init_command_bridge = () => {};
|
|
125637
125560
|
|
|
125638
|
-
// src/daemon/domain/usecase/process-enhancer-job.ts
|
|
125639
|
-
async function processEnhancerJobInbound(deps, event) {
|
|
125640
|
-
await deps.dispatchInbound(event);
|
|
125641
|
-
}
|
|
125642
|
-
|
|
125643
|
-
// src/daemon/entry/bridge/enhancer-bridge.ts
|
|
125644
|
-
function createEnhancerRouterDeps() {
|
|
125645
|
-
return {
|
|
125646
|
-
deliverInbound: async (event) => {
|
|
125647
|
-
await processEnhancerJobInbound({ dispatchInbound: dispatchEnhancerInboundEvent }, event);
|
|
125648
|
-
}
|
|
125649
|
-
};
|
|
125650
|
-
}
|
|
125651
|
-
var init_enhancer_bridge = () => {};
|
|
125652
|
-
|
|
125653
125561
|
// src/daemon/domain/usecase/fulfill-file-content-request.ts
|
|
125654
125562
|
async function fulfillFileContentRequest(deps, event) {
|
|
125655
125563
|
await deps.dispatchInbound(event);
|
|
@@ -125719,14 +125627,12 @@ function createDefaultEventRouterDeps() {
|
|
|
125719
125627
|
command: createCommandRouterDeps(),
|
|
125720
125628
|
workspaceGit: createWorkspaceGitRouterDeps(),
|
|
125721
125629
|
file: createFileRouterDeps(),
|
|
125722
|
-
agenticQuery: createAgenticQueryRouterDeps()
|
|
125723
|
-
enhancer: createEnhancerRouterDeps()
|
|
125630
|
+
agenticQuery: createAgenticQueryRouterDeps()
|
|
125724
125631
|
};
|
|
125725
125632
|
}
|
|
125726
125633
|
var init_default_router_deps = __esm(() => {
|
|
125727
125634
|
init_agentic_query_bridge();
|
|
125728
125635
|
init_command_bridge();
|
|
125729
|
-
init_enhancer_bridge();
|
|
125730
125636
|
init_file_bridge();
|
|
125731
125637
|
init_workspace_git_bridge();
|
|
125732
125638
|
});
|
|
@@ -126007,7 +125913,6 @@ async function executeChatroomStopCommand(args2) {
|
|
|
126007
125913
|
args2.apm.markStopIntent(args2.chatroomId, args2.role, "user.stop", undefined, args2.workingDir);
|
|
126008
125914
|
else if (!args2.workingDir) {
|
|
126009
125915
|
args2.apm.markChatroomStopIntent(args2.chatroomId, "user.stop");
|
|
126010
|
-
await abortEnhancerSpawnsForChatroom(args2.chatroomId);
|
|
126011
125916
|
}
|
|
126012
125917
|
const confirmedDeps = args2.apm.getConfirmedStopAdapterDeps();
|
|
126013
125918
|
const targets = await args2.apm.discoverStopTargets(args2.chatroomId);
|
|
@@ -126040,15 +125945,14 @@ async function executeChatroomStopCommand(args2) {
|
|
|
126040
125945
|
}
|
|
126041
125946
|
var init_execute_chatroom_stop_command = __esm(() => {
|
|
126042
125947
|
init_reliability();
|
|
126043
|
-
init_enhancer_spawn_registry();
|
|
126044
125948
|
init_agent_process_service2();
|
|
126045
125949
|
});
|
|
126046
125950
|
|
|
126047
125951
|
// src/daemon/entry/persistence-path.ts
|
|
126048
|
-
import { homedir as
|
|
126049
|
-
import { join as
|
|
125952
|
+
import { homedir as homedir12 } from "node:os";
|
|
125953
|
+
import { join as join28 } from "node:path";
|
|
126050
125954
|
function resolvePersistenceDbPath(machineId) {
|
|
126051
|
-
return
|
|
125955
|
+
return join28(homedir12(), ".chatroom", "daemon", machineId, "events.sqlite");
|
|
126052
125956
|
}
|
|
126053
125957
|
var init_persistence_path = () => {};
|
|
126054
125958
|
|
|
@@ -126066,13 +125970,6 @@ async function handleCommandInbound(deps, event) {
|
|
|
126066
125970
|
}
|
|
126067
125971
|
}
|
|
126068
125972
|
|
|
126069
|
-
// src/daemon/domain/usecase/handle-enhancer-inbound.ts
|
|
126070
|
-
async function handleEnhancerInbound(deps, event) {
|
|
126071
|
-
if (deps.deliverInbound) {
|
|
126072
|
-
await deps.deliverInbound(event);
|
|
126073
|
-
}
|
|
126074
|
-
}
|
|
126075
|
-
|
|
126076
125973
|
// src/daemon/domain/usecase/handle-file-inbound.ts
|
|
126077
125974
|
async function handleFileInbound(deps, event) {
|
|
126078
125975
|
if (deps.deliverInbound) {
|
|
@@ -126108,9 +126005,6 @@ async function routeInboundEvent(deps, event) {
|
|
|
126108
126005
|
case "agentic-query.prompt":
|
|
126109
126006
|
await handleAgenticQueryInbound(deps.agenticQuery, event);
|
|
126110
126007
|
break;
|
|
126111
|
-
case "enhancer.job-assigned":
|
|
126112
|
-
await handleEnhancerInbound(deps.enhancer, event);
|
|
126113
|
-
break;
|
|
126114
126008
|
default:
|
|
126115
126009
|
}
|
|
126116
126010
|
}
|
|
@@ -126218,80 +126112,6 @@ var init_command_run = __esm(() => {
|
|
|
126218
126112
|
init_api3();
|
|
126219
126113
|
});
|
|
126220
126114
|
|
|
126221
|
-
// src/daemon/infrastructure/convex/subscribers/enhancer-job.ts
|
|
126222
|
-
function startEnhancerJobSubscriber2(deps, onEvent) {
|
|
126223
|
-
const seen = new Set;
|
|
126224
|
-
const watchers = new Map;
|
|
126225
|
-
let stopped = false;
|
|
126226
|
-
let refreshInFlight = false;
|
|
126227
|
-
const onPendingJobs = (jobs) => {
|
|
126228
|
-
if (!jobs?.length)
|
|
126229
|
-
return;
|
|
126230
|
-
for (const job of jobs) {
|
|
126231
|
-
if (job == null || typeof job !== "object" || !("jobId" in job))
|
|
126232
|
-
continue;
|
|
126233
|
-
if (seen.has(job.jobId))
|
|
126234
|
-
continue;
|
|
126235
|
-
seen.add(job.jobId);
|
|
126236
|
-
onEvent({ type: "enhancer.job-assigned", jobId: job.jobId });
|
|
126237
|
-
}
|
|
126238
|
-
};
|
|
126239
|
-
const onError3 = (err) => {
|
|
126240
|
-
console.warn(`[daemon] enhancer-job subscriber error: ${err instanceof Error ? err.message : String(err)}`);
|
|
126241
|
-
};
|
|
126242
|
-
const watchChatroom = (chatroomId) => {
|
|
126243
|
-
if (watchers.has(chatroomId) || stopped)
|
|
126244
|
-
return;
|
|
126245
|
-
const unsub = deps.wsClient.onUpdate(api.daemon.enhancer.index.pendingForChatroom, {
|
|
126246
|
-
sessionId: deps.sessionId,
|
|
126247
|
-
machineId: deps.machineId,
|
|
126248
|
-
chatroomId
|
|
126249
|
-
}, onPendingJobs, onError3);
|
|
126250
|
-
watchers.set(chatroomId, unsub);
|
|
126251
|
-
};
|
|
126252
|
-
const refreshChatrooms = async () => {
|
|
126253
|
-
if (refreshInFlight)
|
|
126254
|
-
return;
|
|
126255
|
-
refreshInFlight = true;
|
|
126256
|
-
try {
|
|
126257
|
-
const workspaces = await deps.wsClient.query(api.workspaces.listWorkspacesForMachine, {
|
|
126258
|
-
sessionId: deps.sessionId,
|
|
126259
|
-
machineId: deps.machineId
|
|
126260
|
-
});
|
|
126261
|
-
if (stopped)
|
|
126262
|
-
return;
|
|
126263
|
-
const roomIds = [
|
|
126264
|
-
...new Set((workspaces ?? []).map((ws) => ws.chatroomId))
|
|
126265
|
-
];
|
|
126266
|
-
for (const [roomId, unsub] of watchers) {
|
|
126267
|
-
if (!roomIds.includes(roomId)) {
|
|
126268
|
-
unsub();
|
|
126269
|
-
watchers.delete(roomId);
|
|
126270
|
-
}
|
|
126271
|
-
}
|
|
126272
|
-
for (const roomId of roomIds)
|
|
126273
|
-
watchChatroom(roomId);
|
|
126274
|
-
} catch (error51) {
|
|
126275
|
-
console.warn(`[daemon] enhancer-job room refresh failed: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
126276
|
-
} finally {
|
|
126277
|
-
refreshInFlight = false;
|
|
126278
|
-
}
|
|
126279
|
-
};
|
|
126280
|
-
refreshChatrooms();
|
|
126281
|
-
return {
|
|
126282
|
-
async stop() {
|
|
126283
|
-
stopped = true;
|
|
126284
|
-
for (const unsub of watchers.values())
|
|
126285
|
-
unsub();
|
|
126286
|
-
watchers.clear();
|
|
126287
|
-
},
|
|
126288
|
-
refreshChatrooms
|
|
126289
|
-
};
|
|
126290
|
-
}
|
|
126291
|
-
var init_enhancer_job = __esm(() => {
|
|
126292
|
-
init_api3();
|
|
126293
|
-
});
|
|
126294
|
-
|
|
126295
126115
|
// src/daemon/infrastructure/convex/subscribers/pending-file-request-dedup.ts
|
|
126296
126116
|
function pendingConvexId(req) {
|
|
126297
126117
|
if (req._id == null)
|
|
@@ -126608,7 +126428,6 @@ function startAllSubscribers(deps) {
|
|
|
126608
126428
|
const onEvent = (event) => {
|
|
126609
126429
|
routeInboundEvent(deps.router, event);
|
|
126610
126430
|
};
|
|
126611
|
-
const enhancerJob = startEnhancerJobSubscriber2(deps, onEvent);
|
|
126612
126431
|
const gitRequest = startGitRequestSubscriber(deps, onEvent);
|
|
126613
126432
|
const machineCommands = startMachineCommandInboxSubscriber(deps, async (claimed) => {
|
|
126614
126433
|
if (claimed.type === "agent.stop") {
|
|
@@ -126639,8 +126458,7 @@ function startAllSubscribers(deps) {
|
|
|
126639
126458
|
fileContent.stop(),
|
|
126640
126459
|
fileWrite.stop(),
|
|
126641
126460
|
agenticQuerySession.stop(),
|
|
126642
|
-
agenticQueryPrompt.stop()
|
|
126643
|
-
enhancerJob.stop()
|
|
126461
|
+
agenticQueryPrompt.stop()
|
|
126644
126462
|
]);
|
|
126645
126463
|
}
|
|
126646
126464
|
};
|
|
@@ -126650,7 +126468,6 @@ var init_subscriber_registry = __esm(() => {
|
|
|
126650
126468
|
init_agentic_query_prompt();
|
|
126651
126469
|
init_agentic_query_session();
|
|
126652
126470
|
init_command_run();
|
|
126653
|
-
init_enhancer_job();
|
|
126654
126471
|
init_file_content_request();
|
|
126655
126472
|
init_file_tree_release_request();
|
|
126656
126473
|
init_file_tree_request();
|
|
@@ -126699,12 +126516,12 @@ var init_schema = __esm(() => {
|
|
|
126699
126516
|
});
|
|
126700
126517
|
|
|
126701
126518
|
// src/daemon/infrastructure/persistence/open-database.ts
|
|
126702
|
-
import { mkdirSync as
|
|
126703
|
-
import { dirname as
|
|
126704
|
-
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";
|
|
126705
126522
|
function openDatabase(dbPath) {
|
|
126706
|
-
|
|
126707
|
-
const db = new
|
|
126523
|
+
mkdirSync10(dirname17(dbPath), { recursive: true });
|
|
126524
|
+
const db = new DatabaseSync5(dbPath);
|
|
126708
126525
|
for (const sql of MIGRATIONS2) {
|
|
126709
126526
|
db.exec(sql);
|
|
126710
126527
|
}
|
|
@@ -134199,19 +134016,19 @@ function routeRequest(req, res, deps) {
|
|
|
134199
134016
|
|
|
134200
134017
|
// src/daemon/local-web/server/serve-static.ts
|
|
134201
134018
|
import { existsSync as existsSync10, readFileSync as readFileSync11 } from "node:fs";
|
|
134202
|
-
import { dirname as
|
|
134019
|
+
import { dirname as dirname18, join as join29 } from "node:path";
|
|
134203
134020
|
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
134204
134021
|
function clientDistCandidates(here) {
|
|
134205
134022
|
return [
|
|
134206
|
-
|
|
134207
|
-
|
|
134208
|
-
|
|
134023
|
+
join29(here, "client/build"),
|
|
134024
|
+
join29(here, "../client/build"),
|
|
134025
|
+
join29(here, "../src/daemon/local-web/client/build")
|
|
134209
134026
|
];
|
|
134210
134027
|
}
|
|
134211
|
-
function resolveClientDistDir(here =
|
|
134028
|
+
function resolveClientDistDir(here = dirname18(fileURLToPath7(import.meta.url))) {
|
|
134212
134029
|
const candidates = clientDistCandidates(here);
|
|
134213
134030
|
for (const dir of candidates) {
|
|
134214
|
-
if (existsSync10(
|
|
134031
|
+
if (existsSync10(join29(dir, "index.html")))
|
|
134215
134032
|
return dir;
|
|
134216
134033
|
}
|
|
134217
134034
|
return candidates[0];
|
|
@@ -134224,7 +134041,7 @@ function tryServeStatic(req, res, distDir) {
|
|
|
134224
134041
|
return false;
|
|
134225
134042
|
}
|
|
134226
134043
|
const safePath = pathname === "/" ? "/index.html" : pathname;
|
|
134227
|
-
const filePath =
|
|
134044
|
+
const filePath = join29(distDir, safePath);
|
|
134228
134045
|
if (!filePath.startsWith(distDir)) {
|
|
134229
134046
|
res.writeHead(403);
|
|
134230
134047
|
res.end();
|
|
@@ -134241,7 +134058,7 @@ function tryServeStatic(req, res, distDir) {
|
|
|
134241
134058
|
}
|
|
134242
134059
|
return true;
|
|
134243
134060
|
}
|
|
134244
|
-
const indexPath =
|
|
134061
|
+
const indexPath = join29(distDir, "index.html");
|
|
134245
134062
|
if (existsSync10(indexPath)) {
|
|
134246
134063
|
res.writeHead(200, { "Content-Type": "text/html" });
|
|
134247
134064
|
if (req.method === "HEAD") {
|
|
@@ -134290,6 +134107,14 @@ function normalizeError(err) {
|
|
|
134290
134107
|
details: err.flatten()
|
|
134291
134108
|
};
|
|
134292
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
|
+
}
|
|
134293
134118
|
if (err instanceof Error) {
|
|
134294
134119
|
const code2 = "code" in err && typeof err.code === "string" ? err.code : "internal_error";
|
|
134295
134120
|
if (code2 === "not_found" || code2 === "validation_error" || code2 === "unauthorized") {
|
|
@@ -134300,6 +134125,7 @@ function normalizeError(err) {
|
|
|
134300
134125
|
return { code: "internal_error", message: "Unknown error" };
|
|
134301
134126
|
}
|
|
134302
134127
|
var init_normalize_error = __esm(() => {
|
|
134128
|
+
init_values();
|
|
134303
134129
|
init_zod();
|
|
134304
134130
|
});
|
|
134305
134131
|
|
|
@@ -134430,6 +134256,16 @@ function extractAck(args2) {
|
|
|
134430
134256
|
}
|
|
134431
134257
|
return { payload: args2[0], ack: undefined };
|
|
134432
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
|
+
}
|
|
134433
134269
|
function registerSocketHandlers(io2, deps) {
|
|
134434
134270
|
const logHistory = deps.logRepo ? createLogHistoryUseCase({ reader: deps.logRepo }) : undefined;
|
|
134435
134271
|
const eventStreamHistory = deps.logRepo ? createEventStreamHistoryUseCase({ reader: deps.logRepo }) : undefined;
|
|
@@ -134449,13 +134285,22 @@ function registerSocketHandlers(io2, deps) {
|
|
|
134449
134285
|
callAck(ack, { ok: false, error: normalizeError(err) });
|
|
134450
134286
|
}
|
|
134451
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
|
+
});
|
|
134452
134299
|
socket.on("daemon.debug.state", async (...args2) => {
|
|
134453
134300
|
const { payload, ack } = extractAck(args2);
|
|
134454
134301
|
try {
|
|
134455
|
-
|
|
134456
|
-
|
|
134457
|
-
const { chatroomId } = debugStateInputSchema.parse(payload ?? {});
|
|
134458
|
-
callAck(ack, { ok: true, data: await deps.debugState(chatroomId) });
|
|
134302
|
+
const data = await resolveDebugStatePayload(deps, payload);
|
|
134303
|
+
callAck(ack, { ok: true, data });
|
|
134459
134304
|
} catch (err) {
|
|
134460
134305
|
callAck(ack, { ok: false, error: normalizeError(err) });
|
|
134461
134306
|
}
|
|
@@ -134639,7 +134484,8 @@ async function startLocalWebServer(config4, deps = {}) {
|
|
|
134639
134484
|
eventStreamHub: deps.eventStreamHub,
|
|
134640
134485
|
backend: deps.backend,
|
|
134641
134486
|
sessionId: deps.sessionId,
|
|
134642
|
-
debugState: deps.debugState
|
|
134487
|
+
debugState: deps.debugState,
|
|
134488
|
+
cliGateway: deps.cliGateway
|
|
134643
134489
|
});
|
|
134644
134490
|
return {
|
|
134645
134491
|
port: boundPort,
|
|
@@ -134695,6 +134541,80 @@ function createLogStreamHub() {
|
|
|
134695
134541
|
};
|
|
134696
134542
|
}
|
|
134697
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
|
+
|
|
134698
134618
|
// src/daemon/entry/start-daemon.ts
|
|
134699
134619
|
async function startDaemon() {
|
|
134700
134620
|
let resolveBoundPort;
|
|
@@ -134729,6 +134649,11 @@ async function startDaemon() {
|
|
|
134729
134649
|
logEvent: init2.logEvent
|
|
134730
134650
|
});
|
|
134731
134651
|
const localWebPort = resolveLocalWebPort();
|
|
134652
|
+
const cliGateway = createCliGatewayService({
|
|
134653
|
+
backend: init2.backend,
|
|
134654
|
+
port: localWebPort,
|
|
134655
|
+
taskService: init2.taskService
|
|
134656
|
+
});
|
|
134732
134657
|
const debugState = async (chatroomId) => {
|
|
134733
134658
|
const persisted = await loadDaemonState(init2.machineId);
|
|
134734
134659
|
const persistedAgents = Object.fromEntries(Object.entries(persisted?.agents ?? {}).filter(([key]) => key.startsWith(`${chatroomId}/`)));
|
|
@@ -134786,7 +134711,8 @@ async function startDaemon() {
|
|
|
134786
134711
|
eventStreamHub,
|
|
134787
134712
|
backend: init2.backend,
|
|
134788
134713
|
sessionId: init2.sessionId,
|
|
134789
|
-
debugState
|
|
134714
|
+
debugState,
|
|
134715
|
+
cliGateway
|
|
134790
134716
|
});
|
|
134791
134717
|
resolveBoundPort(localWeb.port);
|
|
134792
134718
|
const subscribers = startAllSubscribers({
|
|
@@ -134847,6 +134773,7 @@ var init_start_daemon = __esm(() => {
|
|
|
134847
134773
|
init_log_repository();
|
|
134848
134774
|
init_socket3();
|
|
134849
134775
|
init_create_local_web_server();
|
|
134776
|
+
init_cli_gateway_service();
|
|
134850
134777
|
});
|
|
134851
134778
|
|
|
134852
134779
|
// src/commands/machine/daemon-start/index.ts
|
|
@@ -136103,4 +136030,4 @@ program2.hook("preAction", async (_thisCommand, actionCommand) => {
|
|
|
136103
136030
|
});
|
|
136104
136031
|
program2.parse();
|
|
136105
136032
|
|
|
136106
|
-
//# debugId=
|
|
136033
|
+
//# debugId=CB5CA35B81D3EFBC64756E2164756E21
|