episoda 0.2.63 → 0.2.65
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/daemon/daemon-process.js +51 -43
- package/dist/daemon/daemon-process.js.map +1 -1
- package/dist/index.js +14 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -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.65",
|
|
2730
2730
|
description: "CLI tool for Episoda local development workflow orchestration",
|
|
2731
2731
|
main: "dist/index.js",
|
|
2732
2732
|
types: "dist/index.d.ts",
|
|
@@ -8007,8 +8007,8 @@ var Daemon = class _Daemon {
|
|
|
8007
8007
|
// 60 seconds
|
|
8008
8008
|
constructor() {
|
|
8009
8009
|
this.machineId = "";
|
|
8010
|
-
this.
|
|
8011
|
-
//
|
|
8010
|
+
this.machineUuid = null;
|
|
8011
|
+
// EP1091: Renamed from deviceId for platform terminology alignment
|
|
8012
8012
|
this.deviceName = null;
|
|
8013
8013
|
// EP661: Cached device name from server
|
|
8014
8014
|
this.flyMachineId = null;
|
|
@@ -8067,9 +8067,9 @@ var Daemon = class _Daemon {
|
|
|
8067
8067
|
this.machineId = await getMachineId();
|
|
8068
8068
|
console.log(`[Daemon] Machine ID: ${this.machineId}`);
|
|
8069
8069
|
const config = await (0, import_core12.loadConfig)();
|
|
8070
|
-
if (config?.device_id) {
|
|
8071
|
-
this.
|
|
8072
|
-
console.log(`[Daemon] Loaded cached
|
|
8070
|
+
if (config?.machine_uuid || config?.device_id) {
|
|
8071
|
+
this.machineUuid = config.machine_uuid || config.device_id || null;
|
|
8072
|
+
console.log(`[Daemon] Loaded cached Machine UUID: ${this.machineUuid}`);
|
|
8073
8073
|
}
|
|
8074
8074
|
await this.ipcServer.start();
|
|
8075
8075
|
console.log("[Daemon] IPC server started");
|
|
@@ -8121,8 +8121,10 @@ var Daemon = class _Daemon {
|
|
|
8121
8121
|
return {
|
|
8122
8122
|
running: true,
|
|
8123
8123
|
machineId: this.machineId,
|
|
8124
|
-
|
|
8125
|
-
//
|
|
8124
|
+
machineUuid: this.machineUuid,
|
|
8125
|
+
// EP1091: New preferred field name
|
|
8126
|
+
deviceId: this.machineUuid,
|
|
8127
|
+
// EP726: Kept for backward compatibility
|
|
8126
8128
|
hostname: os8.hostname(),
|
|
8127
8129
|
platform: os8.platform(),
|
|
8128
8130
|
arch: os8.arch(),
|
|
@@ -8834,18 +8836,19 @@ var Daemon = class _Daemon {
|
|
|
8834
8836
|
this.liveConnections.add(projectPath);
|
|
8835
8837
|
this.pendingConnections.delete(projectPath);
|
|
8836
8838
|
const authMessage = message;
|
|
8839
|
+
const effectiveMachineUuid = authMessage.machineUuid || authMessage.deviceId;
|
|
8837
8840
|
if (authMessage.userId && authMessage.workspaceId) {
|
|
8838
|
-
await this.configureGitUser(projectPath, authMessage.userId, authMessage.workspaceId, this.machineId, projectId,
|
|
8841
|
+
await this.configureGitUser(projectPath, authMessage.userId, authMessage.workspaceId, this.machineId, projectId, effectiveMachineUuid);
|
|
8839
8842
|
await this.installGitHooks(projectPath);
|
|
8840
8843
|
}
|
|
8841
8844
|
if (authMessage.deviceName) {
|
|
8842
8845
|
this.deviceName = authMessage.deviceName;
|
|
8843
8846
|
console.log(`[Daemon] Device name: ${this.deviceName}`);
|
|
8844
8847
|
}
|
|
8845
|
-
if (
|
|
8846
|
-
this.
|
|
8847
|
-
console.log(`[Daemon]
|
|
8848
|
-
await this.
|
|
8848
|
+
if (effectiveMachineUuid) {
|
|
8849
|
+
this.machineUuid = effectiveMachineUuid;
|
|
8850
|
+
console.log(`[Daemon] Machine UUID: ${this.machineUuid}`);
|
|
8851
|
+
await this.cacheMachineUuid(effectiveMachineUuid);
|
|
8849
8852
|
}
|
|
8850
8853
|
if (authMessage.flyMachineId) {
|
|
8851
8854
|
this.flyMachineId = authMessage.flyMachineId;
|
|
@@ -8867,9 +8870,6 @@ var Daemon = class _Daemon {
|
|
|
8867
8870
|
this.reconcileWorktrees(projectId, projectPath, client).catch((err) => {
|
|
8868
8871
|
console.warn("[Daemon] EP1003: Reconciliation report failed:", err.message);
|
|
8869
8872
|
});
|
|
8870
|
-
this.reconcilePendingCleanups(projectId, projectPath).catch((err) => {
|
|
8871
|
-
console.warn("[Daemon] EP1047: Cleanup queue reconciliation failed:", err.message);
|
|
8872
|
-
});
|
|
8873
8873
|
});
|
|
8874
8874
|
client.on("module_state_changed", async (message) => {
|
|
8875
8875
|
if (message.type === "module_state_changed") {
|
|
@@ -8879,7 +8879,7 @@ var Daemon = class _Daemon {
|
|
|
8879
8879
|
console.log(`[Daemon] EP1003: State change for non-local module ${moduleUid} (mode: ${devMode || "unknown"})`);
|
|
8880
8880
|
return;
|
|
8881
8881
|
}
|
|
8882
|
-
if (checkoutMachineId && checkoutMachineId !== this.
|
|
8882
|
+
if (checkoutMachineId && checkoutMachineId !== this.machineUuid) {
|
|
8883
8883
|
console.log(`[Daemon] EP1003: State change for ${moduleUid} handled by different machine: ${checkoutMachineId}`);
|
|
8884
8884
|
return;
|
|
8885
8885
|
}
|
|
@@ -8984,12 +8984,13 @@ var Daemon = class _Daemon {
|
|
|
8984
8984
|
* EP595: Configure git with user and workspace ID for post-checkout hook
|
|
8985
8985
|
* EP655: Added machineId for device isolation in multi-device environments
|
|
8986
8986
|
* EP725: Added projectId for main branch badge tracking
|
|
8987
|
-
* EP726: Added
|
|
8987
|
+
* EP726: Added machineUuid (UUID) for unified device identification
|
|
8988
|
+
* EP1091: Renamed deviceId param to machineUuid for consistency
|
|
8988
8989
|
*
|
|
8989
8990
|
* This stores the IDs in .git/config so the post-checkout hook can
|
|
8990
8991
|
* update module.checkout_* fields when git operations happen from terminal.
|
|
8991
8992
|
*/
|
|
8992
|
-
async configureGitUser(projectPath, userId, workspaceId, machineId, projectId,
|
|
8993
|
+
async configureGitUser(projectPath, userId, workspaceId, machineId, projectId, machineUuid) {
|
|
8993
8994
|
try {
|
|
8994
8995
|
const { execSync: execSync9 } = await import("child_process");
|
|
8995
8996
|
execSync9(`git config episoda.userId ${userId}`, {
|
|
@@ -9012,14 +9013,14 @@ var Daemon = class _Daemon {
|
|
|
9012
9013
|
encoding: "utf8",
|
|
9013
9014
|
stdio: "pipe"
|
|
9014
9015
|
});
|
|
9015
|
-
if (
|
|
9016
|
-
execSync9(`git config episoda.deviceId ${
|
|
9016
|
+
if (machineUuid) {
|
|
9017
|
+
execSync9(`git config episoda.deviceId ${machineUuid}`, {
|
|
9017
9018
|
cwd: projectPath,
|
|
9018
9019
|
encoding: "utf8",
|
|
9019
9020
|
stdio: "pipe"
|
|
9020
9021
|
});
|
|
9021
9022
|
}
|
|
9022
|
-
console.log(`[Daemon] Configured git for project: episoda.userId=${userId}, machineId=${machineId}, projectId=${projectId}${
|
|
9023
|
+
console.log(`[Daemon] Configured git for project: episoda.userId=${userId}, machineId=${machineId}, projectId=${projectId}${machineUuid ? `, machineUuid=${machineUuid}` : ""}`);
|
|
9023
9024
|
} catch (error) {
|
|
9024
9025
|
console.warn(`[Daemon] Failed to configure git user for ${projectPath}:`, error instanceof Error ? error.message : error);
|
|
9025
9026
|
}
|
|
@@ -9061,30 +9062,34 @@ var Daemon = class _Daemon {
|
|
|
9061
9062
|
}
|
|
9062
9063
|
}
|
|
9063
9064
|
/**
|
|
9064
|
-
* EP726: Cache
|
|
9065
|
+
* EP726: Cache machine UUID to config file
|
|
9066
|
+
* EP1091: Renamed from cacheDeviceId, writes machine_uuid (new) and device_id (backward compat)
|
|
9065
9067
|
*
|
|
9066
|
-
* Persists the
|
|
9068
|
+
* Persists the machine UUID received from the server so it's available
|
|
9067
9069
|
* on daemon restart without needing to re-register the device.
|
|
9068
9070
|
*/
|
|
9069
|
-
async
|
|
9071
|
+
async cacheMachineUuid(machineUuid) {
|
|
9070
9072
|
try {
|
|
9071
9073
|
const config = await (0, import_core12.loadConfig)();
|
|
9072
9074
|
if (!config) {
|
|
9073
|
-
console.warn("[Daemon] Cannot cache
|
|
9075
|
+
console.warn("[Daemon] Cannot cache machine UUID - no config found");
|
|
9074
9076
|
return;
|
|
9075
9077
|
}
|
|
9076
|
-
if (config.
|
|
9078
|
+
if (config.machine_uuid === machineUuid) {
|
|
9077
9079
|
return;
|
|
9078
9080
|
}
|
|
9079
9081
|
const updatedConfig = {
|
|
9080
9082
|
...config,
|
|
9081
|
-
|
|
9083
|
+
machine_uuid: machineUuid,
|
|
9084
|
+
// EP1091: New preferred field
|
|
9085
|
+
device_id: machineUuid,
|
|
9086
|
+
// Backward compatibility
|
|
9082
9087
|
machine_id: this.machineId
|
|
9083
9088
|
};
|
|
9084
9089
|
await (0, import_core12.saveConfig)(updatedConfig);
|
|
9085
|
-
console.log(`[Daemon] Cached
|
|
9090
|
+
console.log(`[Daemon] Cached machine UUID to config: ${machineUuid}`);
|
|
9086
9091
|
} catch (error) {
|
|
9087
|
-
console.warn("[Daemon] Failed to cache
|
|
9092
|
+
console.warn("[Daemon] Failed to cache machine UUID:", error instanceof Error ? error.message : error);
|
|
9088
9093
|
}
|
|
9089
9094
|
}
|
|
9090
9095
|
/**
|
|
@@ -9145,14 +9150,14 @@ var Daemon = class _Daemon {
|
|
|
9145
9150
|
*/
|
|
9146
9151
|
async syncMachineProjectPath(projectId, projectPath) {
|
|
9147
9152
|
try {
|
|
9148
|
-
if (!this.
|
|
9149
|
-
console.warn("[Daemon] EP995: Cannot sync project path -
|
|
9153
|
+
if (!this.machineUuid) {
|
|
9154
|
+
console.warn("[Daemon] EP995: Cannot sync project path - machineUuid not available");
|
|
9150
9155
|
return;
|
|
9151
9156
|
}
|
|
9152
9157
|
const config = await (0, import_core12.loadConfig)();
|
|
9153
9158
|
if (!config) return;
|
|
9154
9159
|
const apiUrl = config.api_url || "https://episoda.dev";
|
|
9155
|
-
const response = await fetchWithAuth(`${apiUrl}/api/account/machines/${this.
|
|
9160
|
+
const response = await fetchWithAuth(`${apiUrl}/api/account/machines/${this.machineUuid}`, {
|
|
9156
9161
|
method: "PATCH",
|
|
9157
9162
|
headers: {
|
|
9158
9163
|
"Content-Type": "application/json"
|
|
@@ -9233,8 +9238,8 @@ var Daemon = class _Daemon {
|
|
|
9233
9238
|
async reconcileWorktrees(projectId, projectPath, client) {
|
|
9234
9239
|
console.log(`[Daemon] EP1003: Starting reconciliation report for project ${projectId}`);
|
|
9235
9240
|
try {
|
|
9236
|
-
if (!this.
|
|
9237
|
-
console.log("[Daemon] EP1003: Cannot reconcile -
|
|
9241
|
+
if (!this.machineUuid) {
|
|
9242
|
+
console.log("[Daemon] EP1003: Cannot reconcile - machineUuid not available yet");
|
|
9238
9243
|
return;
|
|
9239
9244
|
}
|
|
9240
9245
|
const config = await (0, import_core12.loadConfig)();
|
|
@@ -9245,7 +9250,7 @@ var Daemon = class _Daemon {
|
|
|
9245
9250
|
let modulesResponse;
|
|
9246
9251
|
try {
|
|
9247
9252
|
modulesResponse = await fetchWithAuth(
|
|
9248
|
-
`${apiUrl}/api/modules?state=doing,review&dev_mode=local&checkout_machine_id=${this.
|
|
9253
|
+
`${apiUrl}/api/modules?state=doing,review&dev_mode=local&checkout_machine_id=${this.machineUuid}&project_id=${projectId}`,
|
|
9249
9254
|
{ signal: controller.signal }
|
|
9250
9255
|
);
|
|
9251
9256
|
} finally {
|
|
@@ -9294,7 +9299,7 @@ var Daemon = class _Daemon {
|
|
|
9294
9299
|
}
|
|
9295
9300
|
const report = {
|
|
9296
9301
|
projectId,
|
|
9297
|
-
machineId: this.
|
|
9302
|
+
machineId: this.machineUuid,
|
|
9298
9303
|
modules: moduleStatuses,
|
|
9299
9304
|
orphanTunnels: orphanTunnels.length > 0 ? orphanTunnels : void 0
|
|
9300
9305
|
};
|
|
@@ -9315,8 +9320,11 @@ var Daemon = class _Daemon {
|
|
|
9315
9320
|
/**
|
|
9316
9321
|
* EP1047: Process pending cleanup queue entries for this machine
|
|
9317
9322
|
*
|
|
9318
|
-
*
|
|
9319
|
-
*
|
|
9323
|
+
* @deprecated EP1091: No longer called on connect. Server-side cron now processes
|
|
9324
|
+
* the cleanup queue and sends WebSocket commands to connected daemons. This is
|
|
9325
|
+
* more reliable than daemon-side polling since it works even if daemon stays connected.
|
|
9326
|
+
*
|
|
9327
|
+
* Kept for potential manual invocation or debugging purposes.
|
|
9320
9328
|
*
|
|
9321
9329
|
* Flow:
|
|
9322
9330
|
* 1. Query server for pending cleanup tasks for this machine
|
|
@@ -9324,11 +9332,11 @@ var Daemon = class _Daemon {
|
|
|
9324
9332
|
* 3. Report success/failure back to server
|
|
9325
9333
|
*/
|
|
9326
9334
|
async reconcilePendingCleanups(projectId, projectPath) {
|
|
9327
|
-
if (!this.
|
|
9328
|
-
console.log("[Daemon] EP1047: Cannot reconcile cleanups -
|
|
9335
|
+
if (!this.machineUuid) {
|
|
9336
|
+
console.log("[Daemon] EP1047: Cannot reconcile cleanups - machineUuid not available yet");
|
|
9329
9337
|
return;
|
|
9330
9338
|
}
|
|
9331
|
-
console.log(`[Daemon] EP1047: Checking for pending cleanup tasks for machine ${this.
|
|
9339
|
+
console.log(`[Daemon] EP1047: Checking for pending cleanup tasks for machine ${this.machineUuid}`);
|
|
9332
9340
|
try {
|
|
9333
9341
|
const config = await (0, import_core12.loadConfig)();
|
|
9334
9342
|
if (!config) {
|
|
@@ -9341,7 +9349,7 @@ var Daemon = class _Daemon {
|
|
|
9341
9349
|
let response;
|
|
9342
9350
|
try {
|
|
9343
9351
|
response = await fetchWithAuth(
|
|
9344
|
-
`${apiUrl}/api/cli/background-ops?machine_id=${this.
|
|
9352
|
+
`${apiUrl}/api/cli/background-ops?machine_id=${this.machineUuid}`,
|
|
9345
9353
|
{ signal: controller.signal }
|
|
9346
9354
|
);
|
|
9347
9355
|
} finally {
|