episoda 0.2.66 → 0.2.68
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 +91 -14
- package/dist/daemon/daemon-process.js.map +1 -1
- package/dist/index.js +33 -16
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -2592,9 +2592,12 @@ var require_auth = __commonJS({
|
|
|
2592
2592
|
}
|
|
2593
2593
|
}
|
|
2594
2594
|
if (process.env.EPISODA_ACCESS_TOKEN) {
|
|
2595
|
+
const expiresAtEnv = process.env.EPISODA_ACCESS_TOKEN_EXPIRES_AT;
|
|
2596
|
+
const expires_at = expiresAtEnv ? parseInt(expiresAtEnv, 10) : void 0;
|
|
2595
2597
|
return {
|
|
2596
2598
|
access_token: process.env.EPISODA_ACCESS_TOKEN,
|
|
2597
2599
|
refresh_token: process.env.EPISODA_REFRESH_TOKEN,
|
|
2600
|
+
expires_at,
|
|
2598
2601
|
api_url: process.env.EPISODA_API_URL || "https://episoda.dev",
|
|
2599
2602
|
project_id: process.env.EPISODA_PROJECT_ID || "",
|
|
2600
2603
|
user_id: process.env.EPISODA_USER_ID || "",
|
|
@@ -2727,7 +2730,7 @@ var require_package = __commonJS({
|
|
|
2727
2730
|
"package.json"(exports2, module2) {
|
|
2728
2731
|
module2.exports = {
|
|
2729
2732
|
name: "episoda",
|
|
2730
|
-
version: "0.2.
|
|
2733
|
+
version: "0.2.68",
|
|
2731
2734
|
description: "CLI tool for Episoda local development workflow orchestration",
|
|
2732
2735
|
main: "dist/index.js",
|
|
2733
2736
|
types: "dist/index.d.ts",
|
|
@@ -8899,6 +8902,23 @@ var Daemon = class _Daemon {
|
|
|
8899
8902
|
console.log(`[Daemon] EP949: Received token refresh for ${projectId}`);
|
|
8900
8903
|
client.updateToken(tokenMsg.accessToken);
|
|
8901
8904
|
});
|
|
8905
|
+
client.on("machine_uuid_update", async (message) => {
|
|
8906
|
+
const uuidMsg = message;
|
|
8907
|
+
if (uuidMsg.machineUuid) {
|
|
8908
|
+
this.machineUuid = uuidMsg.machineUuid;
|
|
8909
|
+
console.log(`[Daemon] EP1095: Machine UUID updated: ${this.machineUuid}`);
|
|
8910
|
+
await this.cacheMachineUuid(uuidMsg.machineUuid);
|
|
8911
|
+
this.syncMachineProjectPath(projectId, projectPath).catch((err) => {
|
|
8912
|
+
console.warn("[Daemon] EP1095: Deferred project path sync failed:", err.message);
|
|
8913
|
+
});
|
|
8914
|
+
const connection2 = this.connections.get(projectPath);
|
|
8915
|
+
if (connection2) {
|
|
8916
|
+
this.reconcileWorktrees(projectId, projectPath, connection2.client).catch((err) => {
|
|
8917
|
+
console.warn("[Daemon] EP1095: Deferred reconciliation failed:", err.message);
|
|
8918
|
+
});
|
|
8919
|
+
}
|
|
8920
|
+
}
|
|
8921
|
+
});
|
|
8902
8922
|
client.on("disconnected", (event) => {
|
|
8903
8923
|
const disconnectEvent = event;
|
|
8904
8924
|
console.log(`[Daemon] Connection closed for ${projectId}: code=${disconnectEvent.code}, willReconnect=${disconnectEvent.willReconnect}`);
|
|
@@ -8981,12 +9001,47 @@ var Daemon = class _Daemon {
|
|
|
8981
9001
|
process.on("SIGTERM", () => shutdownHandler("SIGTERM"));
|
|
8982
9002
|
process.on("SIGINT", () => shutdownHandler("SIGINT"));
|
|
8983
9003
|
}
|
|
9004
|
+
/**
|
|
9005
|
+
* EP1095: Get git directory and working directory for a project path
|
|
9006
|
+
* Handles both traditional (.git directory) and worktree (.bare directory) structures
|
|
9007
|
+
* Returns { gitDir, workDir } where:
|
|
9008
|
+
* - gitDir: The --git-dir value to use with git commands
|
|
9009
|
+
* - workDir: The directory to run git commands in (cwd)
|
|
9010
|
+
*/
|
|
9011
|
+
getGitDirs(projectPath) {
|
|
9012
|
+
const bareDir = path19.join(projectPath, ".bare");
|
|
9013
|
+
const gitPath = path19.join(projectPath, ".git");
|
|
9014
|
+
if (fs18.existsSync(bareDir) && fs18.statSync(bareDir).isDirectory()) {
|
|
9015
|
+
return { gitDir: bareDir, workDir: projectPath };
|
|
9016
|
+
}
|
|
9017
|
+
if (fs18.existsSync(gitPath) && fs18.statSync(gitPath).isDirectory()) {
|
|
9018
|
+
return { gitDir: null, workDir: projectPath };
|
|
9019
|
+
}
|
|
9020
|
+
if (fs18.existsSync(gitPath) && fs18.statSync(gitPath).isFile()) {
|
|
9021
|
+
return { gitDir: null, workDir: projectPath };
|
|
9022
|
+
}
|
|
9023
|
+
const entries = fs18.readdirSync(projectPath, { withFileTypes: true });
|
|
9024
|
+
for (const entry of entries) {
|
|
9025
|
+
if (entry.isDirectory() && entry.name.startsWith("EP")) {
|
|
9026
|
+
const worktreePath = path19.join(projectPath, entry.name);
|
|
9027
|
+
const worktreeGit = path19.join(worktreePath, ".git");
|
|
9028
|
+
if (fs18.existsSync(worktreeGit)) {
|
|
9029
|
+
return { gitDir: null, workDir: worktreePath };
|
|
9030
|
+
}
|
|
9031
|
+
}
|
|
9032
|
+
}
|
|
9033
|
+
if (fs18.existsSync(bareDir)) {
|
|
9034
|
+
return { gitDir: bareDir, workDir: projectPath };
|
|
9035
|
+
}
|
|
9036
|
+
return { gitDir: null, workDir: projectPath };
|
|
9037
|
+
}
|
|
8984
9038
|
/**
|
|
8985
9039
|
* EP595: Configure git with user and workspace ID for post-checkout hook
|
|
8986
9040
|
* EP655: Added machineId for device isolation in multi-device environments
|
|
8987
9041
|
* EP725: Added projectId for main branch badge tracking
|
|
8988
9042
|
* EP726: Added machineUuid (UUID) for unified device identification
|
|
8989
9043
|
* EP1091: Renamed deviceId param to machineUuid for consistency
|
|
9044
|
+
* EP1095: Added worktree structure support (uses .bare as gitDir)
|
|
8990
9045
|
*
|
|
8991
9046
|
* This stores the IDs in .git/config so the post-checkout hook can
|
|
8992
9047
|
* update module.checkout_* fields when git operations happen from terminal.
|
|
@@ -8994,29 +9049,31 @@ var Daemon = class _Daemon {
|
|
|
8994
9049
|
async configureGitUser(projectPath, userId, workspaceId, machineId, projectId, machineUuid) {
|
|
8995
9050
|
try {
|
|
8996
9051
|
const { execSync: execSync9 } = await import("child_process");
|
|
8997
|
-
|
|
8998
|
-
|
|
9052
|
+
const { gitDir, workDir } = this.getGitDirs(projectPath);
|
|
9053
|
+
const gitCmd = gitDir ? `git --git-dir="${gitDir}"` : "git";
|
|
9054
|
+
execSync9(`${gitCmd} config episoda.userId ${userId}`, {
|
|
9055
|
+
cwd: workDir,
|
|
8999
9056
|
encoding: "utf8",
|
|
9000
9057
|
stdio: "pipe"
|
|
9001
9058
|
});
|
|
9002
|
-
execSync9(
|
|
9003
|
-
cwd:
|
|
9059
|
+
execSync9(`${gitCmd} config episoda.workspaceId ${workspaceId}`, {
|
|
9060
|
+
cwd: workDir,
|
|
9004
9061
|
encoding: "utf8",
|
|
9005
9062
|
stdio: "pipe"
|
|
9006
9063
|
});
|
|
9007
|
-
execSync9(
|
|
9008
|
-
cwd:
|
|
9064
|
+
execSync9(`${gitCmd} config episoda.machineId ${machineId}`, {
|
|
9065
|
+
cwd: workDir,
|
|
9009
9066
|
encoding: "utf8",
|
|
9010
9067
|
stdio: "pipe"
|
|
9011
9068
|
});
|
|
9012
|
-
execSync9(
|
|
9013
|
-
cwd:
|
|
9069
|
+
execSync9(`${gitCmd} config episoda.projectId ${projectId}`, {
|
|
9070
|
+
cwd: workDir,
|
|
9014
9071
|
encoding: "utf8",
|
|
9015
9072
|
stdio: "pipe"
|
|
9016
9073
|
});
|
|
9017
9074
|
if (machineUuid) {
|
|
9018
|
-
execSync9(
|
|
9019
|
-
cwd:
|
|
9075
|
+
execSync9(`${gitCmd} config episoda.deviceId ${machineUuid}`, {
|
|
9076
|
+
cwd: workDir,
|
|
9020
9077
|
encoding: "utf8",
|
|
9021
9078
|
stdio: "pipe"
|
|
9022
9079
|
});
|
|
@@ -9028,6 +9085,7 @@ var Daemon = class _Daemon {
|
|
|
9028
9085
|
}
|
|
9029
9086
|
/**
|
|
9030
9087
|
* EP610: Install git hooks from bundled files
|
|
9088
|
+
* EP1095: Added worktree structure support (hooks in .bare/hooks)
|
|
9031
9089
|
*
|
|
9032
9090
|
* Installs post-checkout and pre-commit hooks to enable:
|
|
9033
9091
|
* - Branch tracking (post-checkout updates module.checkout_* fields)
|
|
@@ -9035,10 +9093,29 @@ var Daemon = class _Daemon {
|
|
|
9035
9093
|
*/
|
|
9036
9094
|
async installGitHooks(projectPath) {
|
|
9037
9095
|
const hooks = ["post-checkout", "pre-commit", "post-commit"];
|
|
9038
|
-
|
|
9096
|
+
let hooksDir;
|
|
9097
|
+
const bareHooksDir = path19.join(projectPath, ".bare", "hooks");
|
|
9098
|
+
const gitHooksDir = path19.join(projectPath, ".git", "hooks");
|
|
9099
|
+
if (fs18.existsSync(bareHooksDir)) {
|
|
9100
|
+
hooksDir = bareHooksDir;
|
|
9101
|
+
} else if (fs18.existsSync(gitHooksDir) && fs18.statSync(path19.join(projectPath, ".git")).isDirectory()) {
|
|
9102
|
+
hooksDir = gitHooksDir;
|
|
9103
|
+
} else {
|
|
9104
|
+
const parentBareHooks = path19.join(projectPath, "..", ".bare", "hooks");
|
|
9105
|
+
if (fs18.existsSync(parentBareHooks)) {
|
|
9106
|
+
hooksDir = parentBareHooks;
|
|
9107
|
+
} else {
|
|
9108
|
+
console.warn(`[Daemon] Hooks directory not found for: ${projectPath}`);
|
|
9109
|
+
return;
|
|
9110
|
+
}
|
|
9111
|
+
}
|
|
9039
9112
|
if (!fs18.existsSync(hooksDir)) {
|
|
9040
|
-
|
|
9041
|
-
|
|
9113
|
+
try {
|
|
9114
|
+
fs18.mkdirSync(hooksDir, { recursive: true });
|
|
9115
|
+
} catch (error) {
|
|
9116
|
+
console.warn(`[Daemon] Hooks directory not found and could not create: ${hooksDir}`);
|
|
9117
|
+
return;
|
|
9118
|
+
}
|
|
9042
9119
|
}
|
|
9043
9120
|
for (const hookName of hooks) {
|
|
9044
9121
|
try {
|