@episoda/cli 0.2.158 → 0.2.160
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 +198 -76
- package/dist/daemon/daemon-process.js.map +1 -1
- package/dist/index.js +217 -85
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1653,10 +1653,6 @@ var require_git_executor = __commonJS({
|
|
|
1653
1653
|
};
|
|
1654
1654
|
} catch {
|
|
1655
1655
|
}
|
|
1656
|
-
try {
|
|
1657
|
-
await this.runGitCommand(["fetch", "--all", "--prune"], cwd, options);
|
|
1658
|
-
} catch {
|
|
1659
|
-
}
|
|
1660
1656
|
const args = ["worktree", "add"];
|
|
1661
1657
|
if (command.detach) {
|
|
1662
1658
|
args.push("--detach", command.path);
|
|
@@ -2913,7 +2909,7 @@ var require_package = __commonJS({
|
|
|
2913
2909
|
"package.json"(exports2, module2) {
|
|
2914
2910
|
module2.exports = {
|
|
2915
2911
|
name: "@episoda/cli",
|
|
2916
|
-
version: "0.2.
|
|
2912
|
+
version: "0.2.160",
|
|
2917
2913
|
description: "CLI tool for Episoda local development workflow orchestration",
|
|
2918
2914
|
main: "dist/index.js",
|
|
2919
2915
|
types: "dist/index.d.ts",
|
|
@@ -6414,6 +6410,24 @@ var path10 = __toESM(require("path"));
|
|
|
6414
6410
|
var fs9 = __toESM(require("fs"));
|
|
6415
6411
|
var os4 = __toESM(require("os"));
|
|
6416
6412
|
var import_core8 = __toESM(require_dist());
|
|
6413
|
+
|
|
6414
|
+
// src/utils/github-token.ts
|
|
6415
|
+
var INVALID_GITHUB_TOKEN_LITERALS = /* @__PURE__ */ new Set([
|
|
6416
|
+
"${GITHUB_PERSONAL_ACCESS_TOKEN}",
|
|
6417
|
+
"undefined",
|
|
6418
|
+
"null",
|
|
6419
|
+
'""',
|
|
6420
|
+
"''"
|
|
6421
|
+
]);
|
|
6422
|
+
function sanitizeGithubToken(token) {
|
|
6423
|
+
if (token === void 0) return "";
|
|
6424
|
+
const trimmed = token.trim();
|
|
6425
|
+
if (!trimmed) return "";
|
|
6426
|
+
if (INVALID_GITHUB_TOKEN_LITERALS.has(trimmed)) return "";
|
|
6427
|
+
return trimmed;
|
|
6428
|
+
}
|
|
6429
|
+
|
|
6430
|
+
// src/agent/mcp-server-configurator.ts
|
|
6417
6431
|
var McpServerConfigurator = class {
|
|
6418
6432
|
// ---------------------------------------------------------------------------
|
|
6419
6433
|
// MCP Auth Resolution
|
|
@@ -6483,10 +6497,10 @@ var McpServerConfigurator = class {
|
|
|
6483
6497
|
}
|
|
6484
6498
|
servers.push({
|
|
6485
6499
|
name: "github",
|
|
6486
|
-
command: "
|
|
6500
|
+
command: "bash scripts/github-mcp-server.sh"
|
|
6487
6501
|
});
|
|
6488
|
-
if (!session.credentials.githubToken) {
|
|
6489
|
-
console.warn(
|
|
6502
|
+
if (!sanitizeGithubToken(session.credentials.githubToken)) {
|
|
6503
|
+
console.warn('[McpServerConfigurator] EP1377: GitHub MCP registered without token \u2014 GitHub tools may fail with "Requires authentication"');
|
|
6490
6504
|
} else {
|
|
6491
6505
|
console.log("[McpServerConfigurator] EP1251: GitHub MCP server registered");
|
|
6492
6506
|
}
|
|
@@ -7373,9 +7387,10 @@ ${message}`;
|
|
|
7373
7387
|
if (sessionToken) {
|
|
7374
7388
|
episodaMcpEnv.EPISODA_SESSION_TOKEN = sessionToken;
|
|
7375
7389
|
}
|
|
7390
|
+
const githubToken = sanitizeGithubToken(session.credentials.githubToken);
|
|
7376
7391
|
const githubMcpEnv = {
|
|
7377
7392
|
...baseEnv,
|
|
7378
|
-
GITHUB_PERSONAL_ACCESS_TOKEN:
|
|
7393
|
+
GITHUB_PERSONAL_ACCESS_TOKEN: githubToken
|
|
7379
7394
|
};
|
|
7380
7395
|
for (const mcpServer of mcpServersToRegister) {
|
|
7381
7396
|
const parts = mcpServer.command.split(" ");
|
|
@@ -7510,10 +7525,7 @@ ${message}`;
|
|
|
7510
7525
|
const args2 = parts.slice(1);
|
|
7511
7526
|
let env;
|
|
7512
7527
|
if (server.name === "github") {
|
|
7513
|
-
env = {
|
|
7514
|
-
...baseEnv,
|
|
7515
|
-
GITHUB_PERSONAL_ACCESS_TOKEN: session.credentials.githubToken || ""
|
|
7516
|
-
};
|
|
7528
|
+
env = { ...baseEnv };
|
|
7517
7529
|
} else {
|
|
7518
7530
|
env = {
|
|
7519
7531
|
...baseEnv,
|
|
@@ -7633,9 +7645,10 @@ ${message}`;
|
|
|
7633
7645
|
console.warn("[AgentManager] EP1287: No session token available for MCP servers");
|
|
7634
7646
|
}
|
|
7635
7647
|
}
|
|
7636
|
-
|
|
7637
|
-
|
|
7638
|
-
|
|
7648
|
+
const processGithubToken = sanitizeGithubToken(session.credentials.githubToken);
|
|
7649
|
+
if (processGithubToken) {
|
|
7650
|
+
envVars.GITHUB_PERSONAL_ACCESS_TOKEN = processGithubToken;
|
|
7651
|
+
console.log("[AgentManager] EP1377: Set GITHUB_PERSONAL_ACCESS_TOKEN for GitHub MCP");
|
|
7639
7652
|
}
|
|
7640
7653
|
if (useApiKey && session.credentials.apiKey) {
|
|
7641
7654
|
if (provider === "codex") {
|
|
@@ -8159,6 +8172,7 @@ var AgentCommandQueue = class {
|
|
|
8159
8172
|
// src/daemon/worktree-manager.ts
|
|
8160
8173
|
var fs11 = __toESM(require("fs"));
|
|
8161
8174
|
var path12 = __toESM(require("path"));
|
|
8175
|
+
var import_child_process11 = require("child_process");
|
|
8162
8176
|
var import_core10 = __toESM(require_dist());
|
|
8163
8177
|
function validateModuleUid(moduleUid) {
|
|
8164
8178
|
if (!moduleUid || typeof moduleUid !== "string" || !moduleUid.trim()) {
|
|
@@ -8175,6 +8189,38 @@ function validateModuleUid(moduleUid) {
|
|
|
8175
8189
|
}
|
|
8176
8190
|
return true;
|
|
8177
8191
|
}
|
|
8192
|
+
function isValidDefaultBranchName(name) {
|
|
8193
|
+
if (!name || typeof name !== "string") return false;
|
|
8194
|
+
const trimmed = name.trim();
|
|
8195
|
+
if (trimmed !== name) return false;
|
|
8196
|
+
if (name.length > 255) return false;
|
|
8197
|
+
if (name.startsWith("-")) return false;
|
|
8198
|
+
if (name.startsWith("/")) return false;
|
|
8199
|
+
if (name.endsWith("/")) return false;
|
|
8200
|
+
if (name.endsWith(".")) return false;
|
|
8201
|
+
if (name.endsWith(".lock")) return false;
|
|
8202
|
+
if (name.includes("..")) return false;
|
|
8203
|
+
if (name.includes("@{")) return false;
|
|
8204
|
+
if (name.includes("//")) return false;
|
|
8205
|
+
if (name.includes("\\")) return false;
|
|
8206
|
+
if (/[ ~^:?*\[\]\s]/.test(name)) return false;
|
|
8207
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9._/-]*$/.test(name)) return false;
|
|
8208
|
+
return true;
|
|
8209
|
+
}
|
|
8210
|
+
function runGit(args, cwd, timeoutMs) {
|
|
8211
|
+
const res = (0, import_child_process11.spawnSync)("git", args, {
|
|
8212
|
+
cwd,
|
|
8213
|
+
encoding: "utf-8",
|
|
8214
|
+
timeout: timeoutMs,
|
|
8215
|
+
windowsHide: true,
|
|
8216
|
+
shell: false
|
|
8217
|
+
});
|
|
8218
|
+
return {
|
|
8219
|
+
success: res.status === 0,
|
|
8220
|
+
stdout: (res.stdout || "").toString(),
|
|
8221
|
+
stderr: (res.stderr || "").toString()
|
|
8222
|
+
};
|
|
8223
|
+
}
|
|
8178
8224
|
var WorktreeManager = class _WorktreeManager {
|
|
8179
8225
|
constructor(projectRoot) {
|
|
8180
8226
|
// ============================================================
|
|
@@ -8232,22 +8278,24 @@ var WorktreeManager = class _WorktreeManager {
|
|
|
8232
8278
|
*/
|
|
8233
8279
|
async ensureFetchRefspecConfigured() {
|
|
8234
8280
|
try {
|
|
8235
|
-
const { execSync: execSync10 } = require("child_process");
|
|
8236
8281
|
let fetchRefspec = null;
|
|
8237
8282
|
try {
|
|
8238
|
-
|
|
8239
|
-
|
|
8240
|
-
|
|
8241
|
-
|
|
8242
|
-
}).trim();
|
|
8283
|
+
const res = runGit(["config", "--get", "remote.origin.fetch"], this.bareRepoPath, 5e3);
|
|
8284
|
+
if (res.success) {
|
|
8285
|
+
fetchRefspec = res.stdout.trim();
|
|
8286
|
+
}
|
|
8243
8287
|
} catch {
|
|
8244
8288
|
}
|
|
8245
8289
|
if (!fetchRefspec) {
|
|
8246
8290
|
console.log("[WorktreeManager] EP1014: Configuring missing fetch refspec for bare repo");
|
|
8247
|
-
|
|
8248
|
-
|
|
8249
|
-
|
|
8250
|
-
|
|
8291
|
+
const setRes = runGit(
|
|
8292
|
+
["config", "remote.origin.fetch", "+refs/heads/*:refs/remotes/origin/*"],
|
|
8293
|
+
this.bareRepoPath,
|
|
8294
|
+
5e3
|
|
8295
|
+
);
|
|
8296
|
+
if (!setRes.success) {
|
|
8297
|
+
throw new Error(setRes.stderr || "Failed to configure fetch refspec");
|
|
8298
|
+
}
|
|
8251
8299
|
console.log("[WorktreeManager] EP1014: Fetch refspec configured successfully");
|
|
8252
8300
|
}
|
|
8253
8301
|
} catch (error) {
|
|
@@ -8280,11 +8328,44 @@ var WorktreeManager = class _WorktreeManager {
|
|
|
8280
8328
|
manager.writeConfig(config);
|
|
8281
8329
|
return manager;
|
|
8282
8330
|
}
|
|
8331
|
+
/**
|
|
8332
|
+
* EP1373: Resolve the default branch name using a 3-level fallback:
|
|
8333
|
+
* 1. Explicit defaultBranch parameter (from project GitHub config)
|
|
8334
|
+
* 2. Git-derived: refs/remotes/origin/HEAD symbolic-ref target
|
|
8335
|
+
* 3. Final fallback: 'main' (with warning)
|
|
8336
|
+
*/
|
|
8337
|
+
async resolveDefaultBranch(explicitDefault) {
|
|
8338
|
+
if (explicitDefault) {
|
|
8339
|
+
if (isValidDefaultBranchName(explicitDefault)) {
|
|
8340
|
+
return explicitDefault;
|
|
8341
|
+
}
|
|
8342
|
+
console.warn(`[WorktreeManager] EP1373: Invalid defaultBranch provided ("${explicitDefault}"), ignoring`);
|
|
8343
|
+
}
|
|
8344
|
+
try {
|
|
8345
|
+
const res = runGit(["symbolic-ref", "refs/remotes/origin/HEAD"], this.bareRepoPath, 5e3);
|
|
8346
|
+
if (!res.success) {
|
|
8347
|
+
throw new Error(res.stderr || "symbolic-ref failed");
|
|
8348
|
+
}
|
|
8349
|
+
const symref = res.stdout.trim();
|
|
8350
|
+
const match = symref.match(/^refs\/remotes\/origin\/(.+)$/);
|
|
8351
|
+
if (match && match[1]) {
|
|
8352
|
+
const derived = match[1];
|
|
8353
|
+
if (isValidDefaultBranchName(derived)) {
|
|
8354
|
+
return derived;
|
|
8355
|
+
}
|
|
8356
|
+
console.warn(`[WorktreeManager] EP1373: Derived default branch from origin/HEAD is invalid ("${derived}"), ignoring`);
|
|
8357
|
+
}
|
|
8358
|
+
} catch {
|
|
8359
|
+
}
|
|
8360
|
+
console.warn('[WorktreeManager] EP1373: Could not resolve default branch, falling back to "main"');
|
|
8361
|
+
return "main";
|
|
8362
|
+
}
|
|
8283
8363
|
/**
|
|
8284
8364
|
* Create a worktree for a module
|
|
8285
8365
|
* The entire operation is locked to prevent race conditions
|
|
8366
|
+
* EP1373: Added defaultBranch parameter for explicit default branch resolution
|
|
8286
8367
|
*/
|
|
8287
|
-
async createWorktree(moduleUid, branchName, createBranch = false) {
|
|
8368
|
+
async createWorktree(moduleUid, branchName, createBranch = false, defaultBranch, correlationId) {
|
|
8288
8369
|
if (!validateModuleUid(moduleUid)) {
|
|
8289
8370
|
return {
|
|
8290
8371
|
success: false,
|
|
@@ -8350,25 +8431,63 @@ var WorktreeManager = class _WorktreeManager {
|
|
|
8350
8431
|
console.warn("[WorktreeManager] EP1265: Failed to prune worktrees (continuing):", pruneResult.output);
|
|
8351
8432
|
}
|
|
8352
8433
|
}
|
|
8353
|
-
const
|
|
8354
|
-
|
|
8355
|
-
|
|
8356
|
-
|
|
8357
|
-
|
|
8358
|
-
|
|
8359
|
-
|
|
8360
|
-
|
|
8361
|
-
|
|
8362
|
-
|
|
8363
|
-
};
|
|
8434
|
+
const resolvedDefault = await this.resolveDefaultBranch(defaultBranch);
|
|
8435
|
+
let shouldCreateBranch = createBranch;
|
|
8436
|
+
let startPoint;
|
|
8437
|
+
if (createBranch) {
|
|
8438
|
+
const managerFetchStartMs = Date.now();
|
|
8439
|
+
const fetchResult = await this.gitExecutor.execute({
|
|
8440
|
+
action: "fetch",
|
|
8441
|
+
remote: "origin",
|
|
8442
|
+
branch: `+refs/heads/${resolvedDefault}:refs/remotes/origin/${resolvedDefault}`
|
|
8443
|
+
}, { cwd: this.bareRepoPath });
|
|
8444
|
+
console.log(`[WorktreeManager] EP1373: manager_fetch phase=manager_fetch durationMs=${Date.now() - managerFetchStartMs} moduleUid=${moduleUid} correlationId=${correlationId || "none"} defaultBranch=${resolvedDefault} success=${fetchResult.success}`);
|
|
8445
|
+
if (!fetchResult.success) {
|
|
8446
|
+
console.error("[worktree-manager] Failed to fetch from origin:", fetchResult.output);
|
|
8447
|
+
return {
|
|
8448
|
+
success: false,
|
|
8449
|
+
error: "Failed to fetch latest refs from origin. Cannot create worktree with stale refs."
|
|
8450
|
+
};
|
|
8451
|
+
}
|
|
8452
|
+
startPoint = `origin/${resolvedDefault}`;
|
|
8453
|
+
} else {
|
|
8454
|
+
const existingBranchFetchStartMs = Date.now();
|
|
8455
|
+
const branchFetchResult = await this.gitExecutor.execute({
|
|
8456
|
+
action: "fetch",
|
|
8457
|
+
remote: "origin",
|
|
8458
|
+
branch: `+refs/heads/${branchName}:refs/remotes/origin/${branchName}`
|
|
8459
|
+
}, { cwd: this.bareRepoPath });
|
|
8460
|
+
console.log(`[WorktreeManager] EP1373: existing_branch_fetch phase=existing_branch_fetch durationMs=${Date.now() - existingBranchFetchStartMs} moduleUid=${moduleUid} correlationId=${correlationId || "none"} branch=${branchName} success=${branchFetchResult.success}`);
|
|
8461
|
+
const localBranchExists = runGit(
|
|
8462
|
+
["show-ref", "--verify", `refs/heads/${branchName}`],
|
|
8463
|
+
this.bareRepoPath,
|
|
8464
|
+
5e3
|
|
8465
|
+
).success;
|
|
8466
|
+
const remoteBranchExists = runGit(
|
|
8467
|
+
["show-ref", "--verify", `refs/remotes/origin/${branchName}`],
|
|
8468
|
+
this.bareRepoPath,
|
|
8469
|
+
5e3
|
|
8470
|
+
).success;
|
|
8471
|
+
if (!localBranchExists && remoteBranchExists) {
|
|
8472
|
+
shouldCreateBranch = true;
|
|
8473
|
+
startPoint = `origin/${branchName}`;
|
|
8474
|
+
console.log(`[WorktreeManager] EP1373: remote_only_branch phase=remote_only_branch moduleUid=${moduleUid} correlationId=${correlationId || "none"} branch=${branchName}`);
|
|
8475
|
+
} else if (!localBranchExists && !remoteBranchExists) {
|
|
8476
|
+
return {
|
|
8477
|
+
success: false,
|
|
8478
|
+
error: `Branch "${branchName}" not found locally or on origin`
|
|
8479
|
+
};
|
|
8480
|
+
}
|
|
8364
8481
|
}
|
|
8482
|
+
const gitWorktreeAddStartMs = Date.now();
|
|
8365
8483
|
const result = await this.gitExecutor.execute({
|
|
8366
8484
|
action: "worktree_add",
|
|
8367
8485
|
path: worktreePath,
|
|
8368
8486
|
branch: branchName,
|
|
8369
|
-
create:
|
|
8370
|
-
startPoint
|
|
8487
|
+
create: shouldCreateBranch,
|
|
8488
|
+
startPoint
|
|
8371
8489
|
}, { cwd: this.bareRepoPath });
|
|
8490
|
+
console.log(`[WorktreeManager] EP1373: git_worktree_add phase=git_worktree_add durationMs=${Date.now() - gitWorktreeAddStartMs} moduleUid=${moduleUid} correlationId=${correlationId || "none"} success=${result.success}`);
|
|
8372
8491
|
if (!result.success) {
|
|
8373
8492
|
return {
|
|
8374
8493
|
success: false,
|
|
@@ -10009,7 +10128,7 @@ async function handleFileMkdir(command, projectPath) {
|
|
|
10009
10128
|
}
|
|
10010
10129
|
|
|
10011
10130
|
// src/daemon/handlers/exec-handler.ts
|
|
10012
|
-
var
|
|
10131
|
+
var import_child_process12 = require("child_process");
|
|
10013
10132
|
var DEFAULT_TIMEOUT = 3e4;
|
|
10014
10133
|
var MAX_TIMEOUT = 3e5;
|
|
10015
10134
|
async function handleExec(command, projectPath) {
|
|
@@ -10031,7 +10150,7 @@ async function handleExec(command, projectPath) {
|
|
|
10031
10150
|
resolve4(result);
|
|
10032
10151
|
};
|
|
10033
10152
|
try {
|
|
10034
|
-
const proc = (0,
|
|
10153
|
+
const proc = (0, import_child_process12.spawn)(cmd, {
|
|
10035
10154
|
shell: true,
|
|
10036
10155
|
cwd,
|
|
10037
10156
|
env: { ...process.env, ...env },
|
|
@@ -10095,7 +10214,7 @@ async function handleExec(command, projectPath) {
|
|
|
10095
10214
|
var path23 = __toESM(require("path"));
|
|
10096
10215
|
var fs22 = __toESM(require("fs"));
|
|
10097
10216
|
var os10 = __toESM(require("os"));
|
|
10098
|
-
var
|
|
10217
|
+
var import_child_process15 = require("child_process");
|
|
10099
10218
|
var import_util2 = require("util");
|
|
10100
10219
|
|
|
10101
10220
|
// src/preview/types.ts
|
|
@@ -10122,7 +10241,7 @@ var import_events3 = require("events");
|
|
|
10122
10241
|
var import_fs = require("fs");
|
|
10123
10242
|
|
|
10124
10243
|
// src/preview/dev-server-runner.ts
|
|
10125
|
-
var
|
|
10244
|
+
var import_child_process14 = require("child_process");
|
|
10126
10245
|
var http = __toESM(require("http"));
|
|
10127
10246
|
var fs20 = __toESM(require("fs"));
|
|
10128
10247
|
var path21 = __toESM(require("path"));
|
|
@@ -10260,7 +10379,7 @@ No cached values available as fallback.`
|
|
|
10260
10379
|
var fs19 = __toESM(require("fs"));
|
|
10261
10380
|
var path20 = __toESM(require("path"));
|
|
10262
10381
|
var os9 = __toESM(require("os"));
|
|
10263
|
-
var
|
|
10382
|
+
var import_child_process13 = require("child_process");
|
|
10264
10383
|
var DEV_SERVER_REGISTRY_DIR = path20.join(os9.homedir(), ".episoda", "dev-servers");
|
|
10265
10384
|
var DevServerRegistry = class {
|
|
10266
10385
|
constructor() {
|
|
@@ -10415,7 +10534,7 @@ var DevServerRegistry = class {
|
|
|
10415
10534
|
*/
|
|
10416
10535
|
getProcessCwd(pid) {
|
|
10417
10536
|
try {
|
|
10418
|
-
const output = (0,
|
|
10537
|
+
const output = (0, import_child_process13.execSync)(`lsof -p ${pid} -Fn | grep ^n | grep cwd | head -1`, {
|
|
10419
10538
|
encoding: "utf8",
|
|
10420
10539
|
timeout: 5e3
|
|
10421
10540
|
}).trim();
|
|
@@ -10440,7 +10559,7 @@ var DevServerRegistry = class {
|
|
|
10440
10559
|
findProcessesInWorktree(worktreePath) {
|
|
10441
10560
|
const pids = [];
|
|
10442
10561
|
try {
|
|
10443
|
-
const output = (0,
|
|
10562
|
+
const output = (0, import_child_process13.execSync)(
|
|
10444
10563
|
`lsof -c node -c next | grep "${worktreePath}" | awk '{print $2}' | sort -u`,
|
|
10445
10564
|
{ encoding: "utf8", timeout: 5e3 }
|
|
10446
10565
|
).trim();
|
|
@@ -10501,7 +10620,7 @@ var DevServerRegistry = class {
|
|
|
10501
10620
|
*/
|
|
10502
10621
|
findProcessesOnPort(port) {
|
|
10503
10622
|
try {
|
|
10504
|
-
const output = (0,
|
|
10623
|
+
const output = (0, import_child_process13.execSync)(`lsof -ti:${port} 2>/dev/null || true`, { encoding: "utf8" }).trim();
|
|
10505
10624
|
if (!output) {
|
|
10506
10625
|
return [];
|
|
10507
10626
|
}
|
|
@@ -10755,7 +10874,7 @@ var DevServerRunner = class extends import_events2.EventEmitter {
|
|
|
10755
10874
|
*/
|
|
10756
10875
|
async killProcessOnPort(port) {
|
|
10757
10876
|
try {
|
|
10758
|
-
const result = (0,
|
|
10877
|
+
const result = (0, import_child_process14.execSync)(`lsof -ti:${port} 2>/dev/null || true`, { encoding: "utf8" }).trim();
|
|
10759
10878
|
if (!result) {
|
|
10760
10879
|
return true;
|
|
10761
10880
|
}
|
|
@@ -10763,15 +10882,15 @@ var DevServerRunner = class extends import_events2.EventEmitter {
|
|
|
10763
10882
|
console.log(`[DevServerRunner] Found ${pids.length} process(es) on port ${port}`);
|
|
10764
10883
|
for (const pid of pids) {
|
|
10765
10884
|
try {
|
|
10766
|
-
(0,
|
|
10885
|
+
(0, import_child_process14.execSync)(`kill -15 ${pid} 2>/dev/null || true`);
|
|
10767
10886
|
} catch {
|
|
10768
10887
|
}
|
|
10769
10888
|
}
|
|
10770
10889
|
await this.wait(1e3);
|
|
10771
10890
|
for (const pid of pids) {
|
|
10772
10891
|
try {
|
|
10773
|
-
(0,
|
|
10774
|
-
(0,
|
|
10892
|
+
(0, import_child_process14.execSync)(`kill -0 ${pid} 2>/dev/null`);
|
|
10893
|
+
(0, import_child_process14.execSync)(`kill -9 ${pid} 2>/dev/null || true`);
|
|
10775
10894
|
} catch {
|
|
10776
10895
|
}
|
|
10777
10896
|
}
|
|
@@ -10820,7 +10939,7 @@ var DevServerRunner = class extends import_events2.EventEmitter {
|
|
|
10820
10939
|
PORT: String(port),
|
|
10821
10940
|
NODE_OPTIONS: enhancedNodeOptions
|
|
10822
10941
|
};
|
|
10823
|
-
const proc = (0,
|
|
10942
|
+
const proc = (0, import_child_process14.spawn)(cmd, args, {
|
|
10824
10943
|
cwd: projectPath,
|
|
10825
10944
|
env: mergedEnv,
|
|
10826
10945
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -11621,7 +11740,7 @@ async function getConfigForApi() {
|
|
|
11621
11740
|
}
|
|
11622
11741
|
return (0, import_core13.loadConfig)();
|
|
11623
11742
|
}
|
|
11624
|
-
var execAsync2 = (0, import_util2.promisify)(
|
|
11743
|
+
var execAsync2 = (0, import_util2.promisify)(import_child_process15.exec);
|
|
11625
11744
|
function persistWorkspaceProjectContext(workspaceSlug, projectSlug, projectId) {
|
|
11626
11745
|
if (process.env.EPISODA_MODE !== "cloud") {
|
|
11627
11746
|
return;
|
|
@@ -11694,8 +11813,11 @@ async function handleWorktreeCreate(request2) {
|
|
|
11694
11813
|
envVars,
|
|
11695
11814
|
setupScript,
|
|
11696
11815
|
// EP1229: detachedHead removed - planning worktrees no longer exist
|
|
11697
|
-
moduleType
|
|
11816
|
+
moduleType,
|
|
11817
|
+
defaultBranch,
|
|
11818
|
+
correlationId
|
|
11698
11819
|
} = request2;
|
|
11820
|
+
const worktreeStartMs = Date.now();
|
|
11699
11821
|
console.log(`[Worktree] K1273: Creating worktree for ${moduleUid}`);
|
|
11700
11822
|
console.log(`[Worktree] Project: ${projectSlug}`);
|
|
11701
11823
|
console.log(`[Worktree] Branch: ${branchName} (create: ${createBranch})`);
|
|
@@ -11739,12 +11861,7 @@ async function handleWorktreeCreate(request2) {
|
|
|
11739
11861
|
};
|
|
11740
11862
|
}
|
|
11741
11863
|
} else {
|
|
11742
|
-
console.log(`[Worktree]
|
|
11743
|
-
try {
|
|
11744
|
-
await execAsync2(`git -C "${bareRepoPath}" fetch origin --prune`, { env: gitEnv });
|
|
11745
|
-
} catch (fetchError) {
|
|
11746
|
-
console.warn(`[Worktree] K1273: Fetch failed (continuing anyway): ${fetchError.message}`);
|
|
11747
|
-
}
|
|
11864
|
+
console.log(`[Worktree] EP1373: Project exists, skipping handler-level fetch (manager handles narrow fetch)`);
|
|
11748
11865
|
}
|
|
11749
11866
|
const manager = new WorktreeManager(projectPath);
|
|
11750
11867
|
const initialized2 = await manager.initialize();
|
|
@@ -11754,7 +11871,8 @@ async function handleWorktreeCreate(request2) {
|
|
|
11754
11871
|
error: `Failed to initialize WorktreeManager at ${projectPath}`
|
|
11755
11872
|
};
|
|
11756
11873
|
}
|
|
11757
|
-
const
|
|
11874
|
+
const worktreeAddStartMs = Date.now();
|
|
11875
|
+
const result = await manager.createWorktree(moduleUid, branchName, createBranch, defaultBranch, correlationId);
|
|
11758
11876
|
if (!result.success) {
|
|
11759
11877
|
return {
|
|
11760
11878
|
success: false,
|
|
@@ -11762,6 +11880,7 @@ async function handleWorktreeCreate(request2) {
|
|
|
11762
11880
|
};
|
|
11763
11881
|
}
|
|
11764
11882
|
const worktreePath = result.worktreePath;
|
|
11883
|
+
console.log(`[Worktree] EP1373: worktree_add phase=worktree_add durationMs=${Date.now() - worktreeAddStartMs} moduleUid=${moduleUid} correlationId=${correlationId || "none"}`);
|
|
11765
11884
|
console.log(`[Worktree] EP1143: Worktree created at ${worktreePath}`);
|
|
11766
11885
|
const config = await getConfigForApi();
|
|
11767
11886
|
let finalStatus = "ready";
|
|
@@ -11793,6 +11912,7 @@ ${buildCmd}` : buildCmd;
|
|
|
11793
11912
|
}
|
|
11794
11913
|
}
|
|
11795
11914
|
if (effectiveSetupScript) {
|
|
11915
|
+
const setupStartMs = Date.now();
|
|
11796
11916
|
await manager.updateWorktreeStatus(moduleUid, "setup");
|
|
11797
11917
|
if (config?.access_token) {
|
|
11798
11918
|
await updateWorktree(config, {
|
|
@@ -11805,6 +11925,7 @@ ${buildCmd}` : buildCmd;
|
|
|
11805
11925
|
}
|
|
11806
11926
|
console.log(`[Worktree] EP1143: Running setup script...`);
|
|
11807
11927
|
const scriptResult = await manager.runSetupScript(moduleUid, effectiveSetupScript);
|
|
11928
|
+
console.log(`[Worktree] EP1373: setup_script phase=worktree_setup durationMs=${Date.now() - setupStartMs} moduleUid=${moduleUid} correlationId=${correlationId || "none"} success=${scriptResult.success}`);
|
|
11808
11929
|
if (!scriptResult.success) {
|
|
11809
11930
|
console.error(`[Worktree] EP1143: Setup script failed: ${scriptResult.error}`);
|
|
11810
11931
|
await manager.updateWorktreeStatus(moduleUid, "error", scriptResult.error);
|
|
@@ -11864,6 +11985,7 @@ ${buildCmd}` : buildCmd;
|
|
|
11864
11985
|
console.error(`[Worktree] EP1143: Failed to update worktrees table: ${apiError.message}`);
|
|
11865
11986
|
}
|
|
11866
11987
|
}
|
|
11988
|
+
console.log(`[Worktree] EP1373: worktree_create_total phase=worktree_create_total durationMs=${Date.now() - worktreeStartMs} moduleUid=${moduleUid} correlationId=${correlationId || "none"} status=${finalStatus}`);
|
|
11867
11989
|
console.log(`[Worktree] EP1143: Worktree ready for ${moduleUid}`);
|
|
11868
11990
|
return {
|
|
11869
11991
|
success: true,
|
|
@@ -12166,7 +12288,7 @@ async function handleProjectSetup(params) {
|
|
|
12166
12288
|
}
|
|
12167
12289
|
|
|
12168
12290
|
// src/utils/dev-server.ts
|
|
12169
|
-
var
|
|
12291
|
+
var import_child_process16 = require("child_process");
|
|
12170
12292
|
var import_core14 = __toESM(require_dist());
|
|
12171
12293
|
var fs24 = __toESM(require("fs"));
|
|
12172
12294
|
var path25 = __toESM(require("path"));
|
|
@@ -12215,7 +12337,7 @@ function writeToLog(logPath, line, isError = false) {
|
|
|
12215
12337
|
}
|
|
12216
12338
|
async function killProcessOnPort(port) {
|
|
12217
12339
|
try {
|
|
12218
|
-
const result = (0,
|
|
12340
|
+
const result = (0, import_child_process16.execSync)(`lsof -ti:${port} 2>/dev/null || true`, { encoding: "utf8" }).trim();
|
|
12219
12341
|
if (!result) {
|
|
12220
12342
|
console.log(`[DevServer] EP929: No process found on port ${port}`);
|
|
12221
12343
|
return true;
|
|
@@ -12224,7 +12346,7 @@ async function killProcessOnPort(port) {
|
|
|
12224
12346
|
console.log(`[DevServer] EP929: Found ${pids.length} process(es) on port ${port}: ${pids.join(", ")}`);
|
|
12225
12347
|
for (const pid of pids) {
|
|
12226
12348
|
try {
|
|
12227
|
-
(0,
|
|
12349
|
+
(0, import_child_process16.execSync)(`kill -15 ${pid} 2>/dev/null || true`, { encoding: "utf8" });
|
|
12228
12350
|
console.log(`[DevServer] EP929: Sent SIGTERM to PID ${pid}`);
|
|
12229
12351
|
} catch {
|
|
12230
12352
|
}
|
|
@@ -12232,8 +12354,8 @@ async function killProcessOnPort(port) {
|
|
|
12232
12354
|
await new Promise((resolve4) => setTimeout(resolve4, 1e3));
|
|
12233
12355
|
for (const pid of pids) {
|
|
12234
12356
|
try {
|
|
12235
|
-
(0,
|
|
12236
|
-
(0,
|
|
12357
|
+
(0, import_child_process16.execSync)(`kill -0 ${pid} 2>/dev/null`, { encoding: "utf8" });
|
|
12358
|
+
(0, import_child_process16.execSync)(`kill -9 ${pid} 2>/dev/null || true`, { encoding: "utf8" });
|
|
12237
12359
|
console.log(`[DevServer] EP929: Force killed PID ${pid}`);
|
|
12238
12360
|
} catch {
|
|
12239
12361
|
}
|
|
@@ -12284,7 +12406,7 @@ function spawnDevServerProcess(projectPath, port, moduleUid, logPath, customComm
|
|
|
12284
12406
|
if (injectedCount > 0) {
|
|
12285
12407
|
console.log(`[DevServer] EP998: Injecting ${injectedCount} env vars from database`);
|
|
12286
12408
|
}
|
|
12287
|
-
const devProcess = (0,
|
|
12409
|
+
const devProcess = (0, import_child_process16.spawn)(cmd, args, {
|
|
12288
12410
|
cwd: projectPath,
|
|
12289
12411
|
env: mergedEnv,
|
|
12290
12412
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -12732,11 +12854,11 @@ var IPCRouter = class {
|
|
|
12732
12854
|
// src/daemon/update-manager.ts
|
|
12733
12855
|
var fs25 = __toESM(require("fs"));
|
|
12734
12856
|
var path26 = __toESM(require("path"));
|
|
12735
|
-
var
|
|
12857
|
+
var import_child_process18 = require("child_process");
|
|
12736
12858
|
var import_core17 = __toESM(require_dist());
|
|
12737
12859
|
|
|
12738
12860
|
// src/utils/update-checker.ts
|
|
12739
|
-
var
|
|
12861
|
+
var import_child_process17 = require("child_process");
|
|
12740
12862
|
var semver = __toESM(require("semver"));
|
|
12741
12863
|
|
|
12742
12864
|
// src/ipc/ipc-client.ts
|
|
@@ -12747,7 +12869,7 @@ var PACKAGE_NAME = "@episoda/cli";
|
|
|
12747
12869
|
var NPM_REGISTRY = "https://registry.npmjs.org";
|
|
12748
12870
|
function isFileLinkedInstall() {
|
|
12749
12871
|
try {
|
|
12750
|
-
const output = (0,
|
|
12872
|
+
const output = (0, import_child_process17.execSync)(`npm list -g ${PACKAGE_NAME} --json`, {
|
|
12751
12873
|
stdio: ["pipe", "pipe", "pipe"],
|
|
12752
12874
|
timeout: 1e4
|
|
12753
12875
|
}).toString();
|
|
@@ -12791,7 +12913,7 @@ async function checkForUpdates(currentVersion) {
|
|
|
12791
12913
|
}
|
|
12792
12914
|
function performSyncUpdate(targetVersion) {
|
|
12793
12915
|
try {
|
|
12794
|
-
(0,
|
|
12916
|
+
(0, import_child_process17.execSync)(`npm install -g ${PACKAGE_NAME}@${targetVersion}`, {
|
|
12795
12917
|
stdio: ["pipe", "pipe", "pipe"],
|
|
12796
12918
|
timeout: 12e4
|
|
12797
12919
|
// 2 minute timeout
|
|
@@ -12806,7 +12928,7 @@ function performSyncUpdate(targetVersion) {
|
|
|
12806
12928
|
}
|
|
12807
12929
|
function getInstalledVersion() {
|
|
12808
12930
|
try {
|
|
12809
|
-
const output = (0,
|
|
12931
|
+
const output = (0, import_child_process17.execSync)(`npm list -g ${PACKAGE_NAME} --json`, {
|
|
12810
12932
|
stdio: ["pipe", "pipe", "pipe"],
|
|
12811
12933
|
timeout: 1e4
|
|
12812
12934
|
}).toString();
|
|
@@ -12941,7 +13063,7 @@ var UpdateManager = class _UpdateManager {
|
|
|
12941
13063
|
const configDir = (0, import_core17.getConfigDir)();
|
|
12942
13064
|
const logPath = path26.join(configDir, "daemon.log");
|
|
12943
13065
|
const logFd = fs25.openSync(logPath, "a");
|
|
12944
|
-
const child = (0,
|
|
13066
|
+
const child = (0, import_child_process18.spawn)("node", [this.daemonEntryFile], {
|
|
12945
13067
|
detached: true,
|
|
12946
13068
|
stdio: ["ignore", logFd, logFd],
|
|
12947
13069
|
env: { ...process.env, EPISODA_DAEMON_MODE: "1" }
|
|
@@ -14244,9 +14366,9 @@ var Daemon = class _Daemon {
|
|
|
14244
14366
|
});
|
|
14245
14367
|
if (!process.env.EPISODA_CONTAINER_ID) {
|
|
14246
14368
|
if (process.env.GITHUB_PERSONAL_ACCESS_TOKEN) {
|
|
14247
|
-
console.log("[Daemon]
|
|
14369
|
+
console.log("[Daemon] EP1377: GITHUB_PERSONAL_ACCESS_TOKEN is set in environment");
|
|
14248
14370
|
} else {
|
|
14249
|
-
console.
|
|
14371
|
+
console.log("[Daemon] EP1377: GITHUB_PERSONAL_ACCESS_TOKEN not set in daemon env (OK - daemon sessions inject token via credentials, local CLI uses scripts/github-mcp-server.sh)");
|
|
14250
14372
|
}
|
|
14251
14373
|
}
|
|
14252
14374
|
this.updateManager.checkOnStartup();
|