episoda 0.2.56 → 0.2.57
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.
|
@@ -2726,7 +2726,7 @@ var require_package = __commonJS({
|
|
|
2726
2726
|
"package.json"(exports2, module2) {
|
|
2727
2727
|
module2.exports = {
|
|
2728
2728
|
name: "episoda",
|
|
2729
|
-
version: "0.2.
|
|
2729
|
+
version: "0.2.57",
|
|
2730
2730
|
description: "CLI tool for Episoda local development workflow orchestration",
|
|
2731
2731
|
main: "dist/index.js",
|
|
2732
2732
|
types: "dist/index.d.ts",
|
|
@@ -8787,6 +8787,9 @@ var Daemon = class _Daemon {
|
|
|
8787
8787
|
this.reconcileWorktrees(projectId, projectPath, client).catch((err) => {
|
|
8788
8788
|
console.warn("[Daemon] EP1003: Reconciliation report failed:", err.message);
|
|
8789
8789
|
});
|
|
8790
|
+
this.reconcilePendingCleanups(projectId, projectPath).catch((err) => {
|
|
8791
|
+
console.warn("[Daemon] EP1047: Cleanup queue reconciliation failed:", err.message);
|
|
8792
|
+
});
|
|
8790
8793
|
});
|
|
8791
8794
|
client.on("module_state_changed", async (message) => {
|
|
8792
8795
|
if (message.type === "module_state_changed") {
|
|
@@ -9229,6 +9232,117 @@ var Daemon = class _Daemon {
|
|
|
9229
9232
|
// EP1025: Removed cleanupModuleWorktree - was dead code (never called).
|
|
9230
9233
|
// Worktree cleanup is handled by server's cleanupWorktreeAsync which sends
|
|
9231
9234
|
// worktree_remove command via WebSocket, handled by GitExecutor.executeWorktreeRemove.
|
|
9235
|
+
/**
|
|
9236
|
+
* EP1047: Process pending cleanup queue entries for this machine
|
|
9237
|
+
*
|
|
9238
|
+
* On daemon startup/reconnect, fetch pending worktree cleanup tasks from the queue
|
|
9239
|
+
* and process them. This catches any cleanups missed while the daemon was offline.
|
|
9240
|
+
*
|
|
9241
|
+
* Flow:
|
|
9242
|
+
* 1. Query server for pending cleanup tasks for this machine
|
|
9243
|
+
* 2. For each task, attempt worktree removal
|
|
9244
|
+
* 3. Report success/failure back to server
|
|
9245
|
+
*/
|
|
9246
|
+
async reconcilePendingCleanups(projectId, projectPath) {
|
|
9247
|
+
if (!this.deviceId) {
|
|
9248
|
+
console.log("[Daemon] EP1047: Cannot reconcile cleanups - deviceId not available yet");
|
|
9249
|
+
return;
|
|
9250
|
+
}
|
|
9251
|
+
console.log(`[Daemon] EP1047: Checking for pending cleanup tasks for machine ${this.deviceId}`);
|
|
9252
|
+
try {
|
|
9253
|
+
const config = await (0, import_core12.loadConfig)();
|
|
9254
|
+
if (!config) {
|
|
9255
|
+
console.log("[Daemon] EP1047: No config loaded, skipping cleanup reconciliation");
|
|
9256
|
+
return;
|
|
9257
|
+
}
|
|
9258
|
+
const apiUrl = config.api_url || "https://episoda.dev";
|
|
9259
|
+
const controller = new AbortController();
|
|
9260
|
+
const timeoutId = setTimeout(() => controller.abort(), 1e4);
|
|
9261
|
+
let response;
|
|
9262
|
+
try {
|
|
9263
|
+
response = await fetchWithAuth(
|
|
9264
|
+
`${apiUrl}/api/cli/cleanup-queue?machine_id=${this.deviceId}`,
|
|
9265
|
+
{ signal: controller.signal }
|
|
9266
|
+
);
|
|
9267
|
+
} finally {
|
|
9268
|
+
clearTimeout(timeoutId);
|
|
9269
|
+
}
|
|
9270
|
+
if (!response.ok) {
|
|
9271
|
+
console.warn(`[Daemon] EP1047: Failed to fetch cleanup tasks: ${response.status}`);
|
|
9272
|
+
return;
|
|
9273
|
+
}
|
|
9274
|
+
const data = await response.json();
|
|
9275
|
+
const tasks = data.data?.tasks || [];
|
|
9276
|
+
if (tasks.length === 0) {
|
|
9277
|
+
console.log("[Daemon] EP1047: No pending cleanup tasks");
|
|
9278
|
+
return;
|
|
9279
|
+
}
|
|
9280
|
+
console.log(`[Daemon] EP1047: Processing ${tasks.length} pending cleanup task(s)`);
|
|
9281
|
+
const projectRoot = await findProjectRoot(projectPath);
|
|
9282
|
+
if (!projectRoot) {
|
|
9283
|
+
console.warn("[Daemon] EP1047: Could not find project root, skipping cleanup reconciliation");
|
|
9284
|
+
return;
|
|
9285
|
+
}
|
|
9286
|
+
const worktreeManager = new WorktreeManager(projectRoot);
|
|
9287
|
+
if (!await worktreeManager.initialize()) {
|
|
9288
|
+
console.warn("[Daemon] EP1047: Failed to initialize worktree manager");
|
|
9289
|
+
return;
|
|
9290
|
+
}
|
|
9291
|
+
for (const task of tasks) {
|
|
9292
|
+
const moduleUid = task.payload.module_uid || task.target_id;
|
|
9293
|
+
console.log(`[Daemon] EP1047: Processing cleanup for ${moduleUid} (task ${task.id})`);
|
|
9294
|
+
try {
|
|
9295
|
+
const result = await worktreeManager.removeWorktree(moduleUid, true);
|
|
9296
|
+
if (result.success) {
|
|
9297
|
+
console.log(`[Daemon] EP1047: Successfully cleaned up worktree for ${moduleUid}`);
|
|
9298
|
+
await this.reportCleanupResult(apiUrl, task.id, "complete");
|
|
9299
|
+
} else {
|
|
9300
|
+
if (result.error?.includes("not found") || result.error?.includes("No worktree found")) {
|
|
9301
|
+
console.log(`[Daemon] EP1047: Worktree ${moduleUid} already removed, marking complete`);
|
|
9302
|
+
await this.reportCleanupResult(apiUrl, task.id, "complete");
|
|
9303
|
+
} else {
|
|
9304
|
+
console.warn(`[Daemon] EP1047: Cleanup failed for ${moduleUid}: ${result.error}`);
|
|
9305
|
+
await this.reportCleanupResult(apiUrl, task.id, "retry", {
|
|
9306
|
+
code: "CLEANUP_ERROR",
|
|
9307
|
+
message: result.error || "Unknown error"
|
|
9308
|
+
});
|
|
9309
|
+
}
|
|
9310
|
+
}
|
|
9311
|
+
} catch (error) {
|
|
9312
|
+
console.error(`[Daemon] EP1047: Error processing cleanup for ${moduleUid}:`, error.message);
|
|
9313
|
+
await this.reportCleanupResult(apiUrl, task.id, "retry", {
|
|
9314
|
+
code: "CLEANUP_EXCEPTION",
|
|
9315
|
+
message: error.message
|
|
9316
|
+
});
|
|
9317
|
+
}
|
|
9318
|
+
}
|
|
9319
|
+
console.log("[Daemon] EP1047: Cleanup reconciliation complete");
|
|
9320
|
+
} catch (error) {
|
|
9321
|
+
console.error("[Daemon] EP1047: Cleanup reconciliation error:", error instanceof Error ? error.message : error);
|
|
9322
|
+
throw error;
|
|
9323
|
+
}
|
|
9324
|
+
}
|
|
9325
|
+
/**
|
|
9326
|
+
* EP1047: Report cleanup task result to server
|
|
9327
|
+
*/
|
|
9328
|
+
async reportCleanupResult(apiUrl, taskId, action, error) {
|
|
9329
|
+
try {
|
|
9330
|
+
const response = await fetchWithAuth(`${apiUrl}/api/cli/cleanup-queue`, {
|
|
9331
|
+
method: "POST",
|
|
9332
|
+
headers: { "Content-Type": "application/json" },
|
|
9333
|
+
body: JSON.stringify({
|
|
9334
|
+
task_id: taskId,
|
|
9335
|
+
action,
|
|
9336
|
+
error
|
|
9337
|
+
})
|
|
9338
|
+
});
|
|
9339
|
+
if (!response.ok) {
|
|
9340
|
+
console.warn(`[Daemon] EP1047: Failed to report cleanup result: ${response.status}`);
|
|
9341
|
+
}
|
|
9342
|
+
} catch (err) {
|
|
9343
|
+
console.warn(`[Daemon] EP1047: Error reporting cleanup result: ${err.message}`);
|
|
9344
|
+
}
|
|
9345
|
+
}
|
|
9232
9346
|
/**
|
|
9233
9347
|
* EP1002: Handle worktree_setup command from server
|
|
9234
9348
|
* This provides a unified setup flow for both local and cloud environments.
|