episoda 0.2.22 → 0.2.24
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 +101 -33
- package/dist/daemon/daemon-process.js.map +1 -1
- package/dist/index.js +93 -57
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -537,6 +537,24 @@ var require_git_executor = __commonJS({
|
|
|
537
537
|
* Execute status command
|
|
538
538
|
*/
|
|
539
539
|
async executeStatus(cwd, options) {
|
|
540
|
+
try {
|
|
541
|
+
const isBareResult = await execAsync2("git rev-parse --is-bare-repository", { cwd, timeout: 5e3 });
|
|
542
|
+
if (isBareResult.stdout.trim() === "true") {
|
|
543
|
+
const headResult = await execAsync2("git symbolic-ref --short HEAD", { cwd, timeout: 5e3 });
|
|
544
|
+
const branchName = headResult.stdout.trim();
|
|
545
|
+
return {
|
|
546
|
+
success: true,
|
|
547
|
+
output: `## ${branchName}`,
|
|
548
|
+
details: {
|
|
549
|
+
uncommittedFiles: [],
|
|
550
|
+
// No working tree in bare repo
|
|
551
|
+
branchName,
|
|
552
|
+
currentBranch: branchName
|
|
553
|
+
}
|
|
554
|
+
};
|
|
555
|
+
}
|
|
556
|
+
} catch {
|
|
557
|
+
}
|
|
540
558
|
const result = await this.runGitCommand(["status", "--porcelain", "-b"], cwd, options);
|
|
541
559
|
if (result.success && result.output) {
|
|
542
560
|
const statusInfo = (0, git_parser_1.parseGitStatus)(result.output);
|
|
@@ -1868,7 +1886,6 @@ var require_git_executor = __commonJS({
|
|
|
1868
1886
|
const fs14 = await Promise.resolve().then(() => __importStar(require("fs"))).then((m) => m.promises);
|
|
1869
1887
|
const path15 = await Promise.resolve().then(() => __importStar(require("path")));
|
|
1870
1888
|
let currentPath = cwd;
|
|
1871
|
-
let worktreeMode = false;
|
|
1872
1889
|
let projectPath = cwd;
|
|
1873
1890
|
let bareRepoPath;
|
|
1874
1891
|
for (let i = 0; i < 10; i++) {
|
|
@@ -1877,7 +1894,6 @@ var require_git_executor = __commonJS({
|
|
|
1877
1894
|
try {
|
|
1878
1895
|
await fs14.access(bareDir);
|
|
1879
1896
|
await fs14.access(episodaDir);
|
|
1880
|
-
worktreeMode = true;
|
|
1881
1897
|
projectPath = currentPath;
|
|
1882
1898
|
bareRepoPath = bareDir;
|
|
1883
1899
|
break;
|
|
@@ -1891,9 +1907,8 @@ var require_git_executor = __commonJS({
|
|
|
1891
1907
|
}
|
|
1892
1908
|
return {
|
|
1893
1909
|
success: true,
|
|
1894
|
-
output:
|
|
1910
|
+
output: bareRepoPath ? "Episoda project" : "Git repository",
|
|
1895
1911
|
details: {
|
|
1896
|
-
worktreeMode,
|
|
1897
1912
|
projectPath,
|
|
1898
1913
|
bareRepoPath
|
|
1899
1914
|
}
|
|
@@ -2681,7 +2696,7 @@ var require_package = __commonJS({
|
|
|
2681
2696
|
"package.json"(exports2, module2) {
|
|
2682
2697
|
module2.exports = {
|
|
2683
2698
|
name: "episoda",
|
|
2684
|
-
version: "0.2.
|
|
2699
|
+
version: "0.2.23",
|
|
2685
2700
|
description: "CLI tool for Episoda local development workflow orchestration",
|
|
2686
2701
|
main: "dist/index.js",
|
|
2687
2702
|
types: "dist/index.d.ts",
|
|
@@ -2883,9 +2898,6 @@ function addProject(projectId, projectPath, options) {
|
|
|
2883
2898
|
if (existingByPath) {
|
|
2884
2899
|
existingByPath.id = projectId;
|
|
2885
2900
|
existingByPath.last_active = now;
|
|
2886
|
-
if (options?.worktreeMode !== void 0) {
|
|
2887
|
-
existingByPath.worktreeMode = options.worktreeMode;
|
|
2888
|
-
}
|
|
2889
2901
|
if (options?.bareRepoPath) {
|
|
2890
2902
|
existingByPath.bareRepoPath = options.bareRepoPath;
|
|
2891
2903
|
}
|
|
@@ -2905,8 +2917,7 @@ function addProject(projectId, projectPath, options) {
|
|
|
2905
2917
|
name: projectName,
|
|
2906
2918
|
added_at: now,
|
|
2907
2919
|
last_active: now,
|
|
2908
|
-
//
|
|
2909
|
-
worktreeMode: options?.worktreeMode,
|
|
2920
|
+
// EP971: Bare repo path for worktree architecture
|
|
2910
2921
|
bareRepoPath: options?.bareRepoPath
|
|
2911
2922
|
};
|
|
2912
2923
|
data.projects.push(newProject);
|
|
@@ -5447,7 +5458,8 @@ var WorktreeManager = class _WorktreeManager {
|
|
|
5447
5458
|
}
|
|
5448
5459
|
/**
|
|
5449
5460
|
* Initialize worktree manager from existing project root
|
|
5450
|
-
*
|
|
5461
|
+
* EP971: All projects use worktree architecture
|
|
5462
|
+
* @returns true if valid project, false otherwise
|
|
5451
5463
|
*/
|
|
5452
5464
|
async initialize() {
|
|
5453
5465
|
if (!fs11.existsSync(this.bareRepoPath)) {
|
|
@@ -5458,7 +5470,7 @@ var WorktreeManager = class _WorktreeManager {
|
|
|
5458
5470
|
}
|
|
5459
5471
|
try {
|
|
5460
5472
|
const config = this.readConfig();
|
|
5461
|
-
return config
|
|
5473
|
+
return config !== null;
|
|
5462
5474
|
} catch {
|
|
5463
5475
|
return false;
|
|
5464
5476
|
}
|
|
@@ -5483,7 +5495,6 @@ var WorktreeManager = class _WorktreeManager {
|
|
|
5483
5495
|
workspaceSlug,
|
|
5484
5496
|
projectSlug,
|
|
5485
5497
|
bareRepoPath: manager.bareRepoPath,
|
|
5486
|
-
worktreeMode: true,
|
|
5487
5498
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5488
5499
|
worktrees: []
|
|
5489
5500
|
};
|
|
@@ -6163,6 +6174,28 @@ async function fetchWithAuth(url, options = {}, retryOnUnauthorized = true) {
|
|
|
6163
6174
|
}
|
|
6164
6175
|
return response;
|
|
6165
6176
|
}
|
|
6177
|
+
async function fetchEnvVars() {
|
|
6178
|
+
try {
|
|
6179
|
+
const config = await (0, import_core10.loadConfig)();
|
|
6180
|
+
if (!config?.project_id) {
|
|
6181
|
+
console.warn("[Daemon] EP973: No project_id in config, cannot fetch env vars");
|
|
6182
|
+
return {};
|
|
6183
|
+
}
|
|
6184
|
+
const apiUrl = config.api_url || "https://episoda.dev";
|
|
6185
|
+
const response = await fetchWithAuth(`${apiUrl}/api/cli/env-vars`);
|
|
6186
|
+
if (!response.ok) {
|
|
6187
|
+
console.warn(`[Daemon] EP973: Failed to fetch env vars: ${response.status}`);
|
|
6188
|
+
return {};
|
|
6189
|
+
}
|
|
6190
|
+
const data = await response.json();
|
|
6191
|
+
const envVars = data.env_vars || {};
|
|
6192
|
+
console.log(`[Daemon] EP973: Fetched ${Object.keys(envVars).length} env vars from server`);
|
|
6193
|
+
return envVars;
|
|
6194
|
+
} catch (error) {
|
|
6195
|
+
console.warn("[Daemon] EP973: Error fetching env vars:", error instanceof Error ? error.message : error);
|
|
6196
|
+
return {};
|
|
6197
|
+
}
|
|
6198
|
+
}
|
|
6166
6199
|
var Daemon = class _Daemon {
|
|
6167
6200
|
// 60 seconds
|
|
6168
6201
|
constructor() {
|
|
@@ -6569,9 +6602,12 @@ var Daemon = class _Daemon {
|
|
|
6569
6602
|
client.updateActivity();
|
|
6570
6603
|
try {
|
|
6571
6604
|
const gitCmd = message.command;
|
|
6572
|
-
const
|
|
6605
|
+
const bareRepoPath = path14.join(projectPath, ".bare");
|
|
6606
|
+
const cwd = gitCmd.worktreePath || bareRepoPath;
|
|
6573
6607
|
if (gitCmd.worktreePath) {
|
|
6574
|
-
console.log(`[Daemon]
|
|
6608
|
+
console.log(`[Daemon] Routing command to worktree: ${gitCmd.worktreePath}`);
|
|
6609
|
+
} else {
|
|
6610
|
+
console.log(`[Daemon] Running git command in bare repo: ${bareRepoPath}`);
|
|
6575
6611
|
}
|
|
6576
6612
|
const result = await gitExecutor.execute(gitCmd, {
|
|
6577
6613
|
cwd
|
|
@@ -6674,7 +6710,27 @@ var Daemon = class _Daemon {
|
|
|
6674
6710
|
const tunnelManager = getTunnelManager();
|
|
6675
6711
|
let result;
|
|
6676
6712
|
if (cmd.action === "start") {
|
|
6677
|
-
const
|
|
6713
|
+
const worktree = await getWorktreeInfoForModule(cmd.moduleUid);
|
|
6714
|
+
if (!worktree) {
|
|
6715
|
+
console.error(`[Daemon] EP973: Cannot resolve worktree path for ${cmd.moduleUid}`);
|
|
6716
|
+
await client.send({
|
|
6717
|
+
type: "tunnel_result",
|
|
6718
|
+
commandId: message.id,
|
|
6719
|
+
result: { success: false, error: "Cannot resolve worktree path - missing config slugs" }
|
|
6720
|
+
});
|
|
6721
|
+
return;
|
|
6722
|
+
}
|
|
6723
|
+
if (!worktree.exists) {
|
|
6724
|
+
console.error(`[Daemon] EP973: Worktree not found at ${worktree.path}`);
|
|
6725
|
+
await client.send({
|
|
6726
|
+
type: "tunnel_result",
|
|
6727
|
+
commandId: message.id,
|
|
6728
|
+
result: { success: false, error: `Worktree not found at ${worktree.path}` }
|
|
6729
|
+
});
|
|
6730
|
+
return;
|
|
6731
|
+
}
|
|
6732
|
+
console.log(`[Daemon] EP973: Using worktree path ${worktree.path} for ${cmd.moduleUid}`);
|
|
6733
|
+
const port = cmd.port || detectDevPort(worktree.path);
|
|
6678
6734
|
const previewUrl = `https://${cmd.moduleUid.toLowerCase()}-${cmd.projectUid.toLowerCase()}.episoda.site`;
|
|
6679
6735
|
const reportTunnelStatus = async (data) => {
|
|
6680
6736
|
const config2 = await (0, import_core10.loadConfig)();
|
|
@@ -6709,8 +6765,10 @@ var Daemon = class _Daemon {
|
|
|
6709
6765
|
});
|
|
6710
6766
|
try {
|
|
6711
6767
|
await tunnelManager.initialize();
|
|
6712
|
-
|
|
6713
|
-
const
|
|
6768
|
+
const devConfig = await (0, import_core10.loadConfig)();
|
|
6769
|
+
const devServerScript = devConfig?.project_settings?.worktree_dev_server_script;
|
|
6770
|
+
console.log(`[Daemon] EP973: Ensuring dev server is running in ${worktree.path} on port ${port}...`);
|
|
6771
|
+
const devServerResult = await ensureDevServer(worktree.path, port, cmd.moduleUid, devServerScript);
|
|
6714
6772
|
if (!devServerResult.success) {
|
|
6715
6773
|
const errorMsg2 = `Dev server failed to start: ${devServerResult.error}`;
|
|
6716
6774
|
console.error(`[Daemon] ${errorMsg2}`);
|
|
@@ -7041,17 +7099,18 @@ var Daemon = class _Daemon {
|
|
|
7041
7099
|
}
|
|
7042
7100
|
const worktreeConfig = await (0, import_core10.loadConfig)();
|
|
7043
7101
|
const setupConfig = worktreeConfig?.project_settings;
|
|
7044
|
-
const
|
|
7102
|
+
const envVars = await fetchEnvVars();
|
|
7103
|
+
const hasEnvVars = Object.keys(envVars).length > 0;
|
|
7045
7104
|
if (setupConfig?.worktree_copy_files?.length || setupConfig?.worktree_setup_script || hasEnvVars) {
|
|
7046
7105
|
console.log(`[Daemon] EP959: Starting async worktree setup for ${moduleUid}`);
|
|
7047
7106
|
await worktreeManager.updateWorktreeStatus(moduleUid, "pending");
|
|
7048
7107
|
this.runWorktreeSetupAsync(
|
|
7049
7108
|
moduleUid,
|
|
7050
7109
|
worktreeManager,
|
|
7051
|
-
setupConfig
|
|
7052
|
-
setupConfig
|
|
7110
|
+
setupConfig?.worktree_copy_files || [],
|
|
7111
|
+
setupConfig?.worktree_setup_script,
|
|
7053
7112
|
worktree.path,
|
|
7054
|
-
|
|
7113
|
+
envVars
|
|
7055
7114
|
).then(() => {
|
|
7056
7115
|
console.log(`[Daemon] EP959: Setup complete for ${moduleUid}, starting tunnel`);
|
|
7057
7116
|
this.startTunnelForModule(moduleUid, worktree.path);
|
|
@@ -7345,22 +7404,31 @@ var Daemon = class _Daemon {
|
|
|
7345
7404
|
const data = await response.json();
|
|
7346
7405
|
const serverSettings = data.settings;
|
|
7347
7406
|
if (serverSettings) {
|
|
7348
|
-
const
|
|
7407
|
+
const projectSlug = data.project_slug || config.project_slug;
|
|
7408
|
+
const workspaceSlug = data.workspace_slug || config.workspace_slug;
|
|
7409
|
+
if (data.project_slug && !config.project_slug) {
|
|
7410
|
+
console.log(`[Daemon] EP973: Synced project_slug: ${data.project_slug}`);
|
|
7411
|
+
}
|
|
7412
|
+
if (data.workspace_slug && !config.workspace_slug) {
|
|
7413
|
+
console.log(`[Daemon] EP973: Synced workspace_slug: ${data.workspace_slug}`);
|
|
7414
|
+
}
|
|
7349
7415
|
const updatedConfig = {
|
|
7350
7416
|
...config,
|
|
7417
|
+
// EP973: Include synced slugs
|
|
7418
|
+
project_slug: projectSlug,
|
|
7419
|
+
workspace_slug: workspaceSlug,
|
|
7351
7420
|
project_settings: {
|
|
7352
7421
|
...config.project_settings,
|
|
7353
7422
|
worktree_setup_script: serverSettings.worktree_setup_script,
|
|
7354
7423
|
worktree_cleanup_script: serverSettings.worktree_cleanup_script,
|
|
7355
7424
|
worktree_dev_server_script: serverSettings.worktree_dev_server_script,
|
|
7356
|
-
worktree_env_vars: envVars,
|
|
7357
7425
|
// Keep deprecated field for backward compatibility
|
|
7358
7426
|
worktree_copy_files: serverSettings.worktree_copy_files,
|
|
7359
7427
|
cached_at: Date.now()
|
|
7360
7428
|
}
|
|
7361
7429
|
};
|
|
7362
7430
|
await (0, import_core10.saveConfig)(updatedConfig);
|
|
7363
|
-
console.log(`[Daemon]
|
|
7431
|
+
console.log(`[Daemon] EP973: Project settings synced (slugs: ${projectSlug}/${workspaceSlug})`);
|
|
7364
7432
|
}
|
|
7365
7433
|
} catch (error) {
|
|
7366
7434
|
console.warn("[Daemon] EP964: Failed to sync project settings:", error instanceof Error ? error.message : error);
|
|
@@ -7937,14 +8005,13 @@ var Daemon = class _Daemon {
|
|
|
7937
8005
|
} catch (e) {
|
|
7938
8006
|
console.warn(`[Daemon] EP833: Failed to fetch module details for project lookup`);
|
|
7939
8007
|
}
|
|
7940
|
-
const
|
|
7941
|
-
|
|
7942
|
-
|
|
7943
|
-
|
|
7944
|
-
console.warn(`[Daemon] EP833: Could not find project ${projectId}, using fallback`);
|
|
8008
|
+
const worktree = await getWorktreeInfoForModule(moduleUid);
|
|
8009
|
+
if (!worktree) {
|
|
8010
|
+
console.error(`[Daemon] EP973: Cannot resolve worktree path for ${moduleUid} - missing config slugs`);
|
|
8011
|
+
return;
|
|
7945
8012
|
}
|
|
7946
|
-
if (!
|
|
7947
|
-
console.error(`[Daemon]
|
|
8013
|
+
if (!worktree.exists) {
|
|
8014
|
+
console.error(`[Daemon] EP973: Worktree not found at ${worktree.path}`);
|
|
7948
8015
|
return;
|
|
7949
8016
|
}
|
|
7950
8017
|
const { isPortInUse: isPortInUse2 } = await Promise.resolve().then(() => (init_port_check(), port_check_exports));
|
|
@@ -7956,7 +8023,8 @@ var Daemon = class _Daemon {
|
|
|
7956
8023
|
await killProcessOnPort(port);
|
|
7957
8024
|
}
|
|
7958
8025
|
}
|
|
7959
|
-
const
|
|
8026
|
+
const devServerScript = config.project_settings?.worktree_dev_server_script;
|
|
8027
|
+
const startResult2 = await ensureDevServer(worktree.path, port, moduleUid, devServerScript);
|
|
7960
8028
|
if (!startResult2.success) {
|
|
7961
8029
|
console.error(`[Daemon] EP932: Failed to start dev server: ${startResult2.error}`);
|
|
7962
8030
|
return;
|