dev-prism 0.4.0 → 0.7.0

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.
Files changed (98) hide show
  1. package/README.md +180 -131
  2. package/bin/dev-prism.js +77 -97
  3. package/dist/{chunk-7YGOMAJG.js → chunk-3CIXBEXK.js} +22 -28
  4. package/dist/chunk-AHC6CD7F.js +92 -0
  5. package/dist/chunk-FQTS57VO.js +64 -0
  6. package/dist/chunk-GWQPK7MZ.js +50 -0
  7. package/dist/chunk-HDGBJGIH.js +55 -0
  8. package/dist/chunk-ILICQAU7.js +60 -0
  9. package/dist/chunk-IWZN6P6M.js +155 -0
  10. package/dist/chunk-KP56QH72.js +133 -0
  11. package/dist/{chunk-Y3GR6XK7.js → chunk-NJAITOCG.js} +3 -13
  12. package/dist/{chunk-25WQHUYW.js → chunk-TSNFAXVQ.js} +5 -12
  13. package/dist/chunk-VAPRJUC7.js +67 -0
  14. package/dist/chunk-VL56YPMK.js +45 -0
  15. package/dist/commands/claude.js +1 -1
  16. package/dist/commands/create.d.ts +1 -4
  17. package/dist/commands/create.js +5 -7
  18. package/dist/commands/destroy.d.ts +1 -1
  19. package/dist/commands/destroy.js +4 -5
  20. package/dist/commands/env.d.ts +7 -0
  21. package/dist/commands/env.js +9 -0
  22. package/dist/commands/info.js +4 -2
  23. package/dist/commands/list.d.ts +1 -3
  24. package/dist/commands/list.js +2 -5
  25. package/dist/commands/prune.d.ts +1 -1
  26. package/dist/commands/prune.js +2 -5
  27. package/dist/commands/with-env.d.ts +3 -0
  28. package/dist/commands/with-env.js +9 -0
  29. package/dist/index.d.ts +9 -12
  30. package/dist/index.js +58 -56
  31. package/dist/lib/config.d.ts +4 -7
  32. package/dist/lib/config.js +1 -3
  33. package/dist/lib/db.d.ts +26 -0
  34. package/dist/lib/db.js +28 -0
  35. package/dist/lib/env.d.ts +7 -5
  36. package/dist/lib/env.js +9 -9
  37. package/dist/lib/worktree.d.ts +2 -3
  38. package/dist/lib/worktree.js +1 -3
  39. package/package.json +8 -8
  40. package/dist/chunk-35SHBLIZ.js +0 -69
  41. package/dist/chunk-3ATDGV4Y.js +0 -22
  42. package/dist/chunk-3MSC3CGG.js +0 -78
  43. package/dist/chunk-3NW2OWIU.js +0 -78
  44. package/dist/chunk-3TRRZEFR.js +0 -38
  45. package/dist/chunk-4UNCSJRM.js +0 -70
  46. package/dist/chunk-5KDDYO6Y.js +0 -168
  47. package/dist/chunk-63II3EL4.js +0 -98
  48. package/dist/chunk-6YMQTISJ.js +0 -84
  49. package/dist/chunk-AOM6BONB.js +0 -98
  50. package/dist/chunk-AW2FJGXA.js +0 -38
  51. package/dist/chunk-C4WLIOBR.js +0 -67
  52. package/dist/chunk-D6QWWXZD.js +0 -49
  53. package/dist/chunk-FKTFCSU7.js +0 -78
  54. package/dist/chunk-GBN67HYD.js +0 -57
  55. package/dist/chunk-GKXXK2ZH.js +0 -203
  56. package/dist/chunk-GWDGC2OE.js +0 -116
  57. package/dist/chunk-H4HPDIY3.js +0 -95
  58. package/dist/chunk-HCCZKLC4.js +0 -64
  59. package/dist/chunk-HZUN6NRB.js +0 -70
  60. package/dist/chunk-J36LRUXM.js +0 -60
  61. package/dist/chunk-JHR4WADC.js +0 -200
  62. package/dist/chunk-JIU574KX.js +0 -41
  63. package/dist/chunk-KZJE62TK.js +0 -203
  64. package/dist/chunk-LDK6QMR6.js +0 -67
  65. package/dist/chunk-LEHA65A7.js +0 -59
  66. package/dist/chunk-LNIOSGC4.js +0 -78
  67. package/dist/chunk-LOVO4P3Y.js +0 -41
  68. package/dist/chunk-NNVP5F6I.js +0 -77
  69. package/dist/chunk-OL25TBYX.js +0 -67
  70. package/dist/chunk-P3ETW2KK.js +0 -166
  71. package/dist/chunk-PJKUD2N2.js +0 -22
  72. package/dist/chunk-PKC2ZED2.js +0 -168
  73. package/dist/chunk-PS76Q3HD.js +0 -168
  74. package/dist/chunk-QSG5CXPX.js +0 -171
  75. package/dist/chunk-QUMZI5KK.js +0 -98
  76. package/dist/chunk-RC2AUYZ7.js +0 -49
  77. package/dist/chunk-SMFAL2VP.js +0 -69
  78. package/dist/chunk-SSQ7XBY2.js +0 -30
  79. package/dist/chunk-SUMJLXT7.js +0 -30
  80. package/dist/chunk-UHI2QJFI.js +0 -200
  81. package/dist/chunk-VR3QWHHB.js +0 -57
  82. package/dist/chunk-X5A6H4Q7.js +0 -70
  83. package/dist/chunk-X6FHBEAS.js +0 -200
  84. package/dist/chunk-XUWQUDLT.js +0 -67
  85. package/dist/commands/logs.d.ts +0 -8
  86. package/dist/commands/logs.js +0 -8
  87. package/dist/commands/start.d.ts +0 -7
  88. package/dist/commands/start.js +0 -9
  89. package/dist/commands/stop-all.d.ts +0 -3
  90. package/dist/commands/stop-all.js +0 -9
  91. package/dist/commands/stop.d.ts +0 -3
  92. package/dist/commands/stop.js +0 -7
  93. package/dist/lib/docker.d.ts +0 -12
  94. package/dist/lib/docker.js +0 -14
  95. package/dist/lib/ports.d.ts +0 -6
  96. package/dist/lib/ports.js +0 -8
  97. package/dist/lib/store.d.ts +0 -46
  98. package/dist/lib/store.js +0 -6
@@ -1,166 +0,0 @@
1
- import {
2
- calculatePorts,
3
- formatPortsTable
4
- } from "./chunk-PJKUD2N2.js";
5
- import {
6
- createWorktree,
7
- findNextSessionId,
8
- generateDefaultBranchName
9
- } from "./chunk-GWDGC2OE.js";
10
- import {
11
- getSessionDir,
12
- getSessionsDir,
13
- loadConfig
14
- } from "./chunk-25WQHUYW.js";
15
- import {
16
- logs,
17
- up
18
- } from "./chunk-GBN67HYD.js";
19
- import {
20
- writeAppEnvFiles,
21
- writeEnvFile
22
- } from "./chunk-LEHA65A7.js";
23
-
24
- // src/commands/create.ts
25
- import { existsSync, mkdirSync, copyFileSync, readFileSync, writeFileSync } from "fs";
26
- import { basename, join } from "path";
27
- import chalk from "chalk";
28
- import { execa } from "execa";
29
- function updateEnvDatabaseUrl(envPath, newDbUrl) {
30
- if (!existsSync(envPath)) return;
31
- let content = readFileSync(envPath, "utf-8");
32
- if (content.includes("DATABASE_URL=")) {
33
- content = content.replace(/^DATABASE_URL=.*/m, `DATABASE_URL=${newDbUrl}`);
34
- } else {
35
- content += `
36
- DATABASE_URL=${newDbUrl}
37
- `;
38
- }
39
- writeFileSync(envPath, content);
40
- }
41
- async function createSession(projectRoot, sessionId, options) {
42
- const config = await loadConfig(projectRoot);
43
- const sessionsDir = getSessionsDir(config, projectRoot);
44
- if (!sessionId) {
45
- sessionId = await findNextSessionId(projectRoot, sessionsDir);
46
- console.log(chalk.gray(`Auto-assigned session ID: ${sessionId}`));
47
- }
48
- if (!/^\d{3}$/.test(sessionId)) {
49
- console.error(chalk.red("Error: Session ID must be exactly 3 digits (001-999)"));
50
- process.exit(1);
51
- }
52
- const inPlace = options.inPlace ?? false;
53
- const branchName = options.branch || generateDefaultBranchName(sessionId);
54
- const mode = options.mode || "docker";
55
- console.log(chalk.blue(`Creating session ${sessionId} (${mode} mode${inPlace ? ", in-place" : ""})...`));
56
- if (!inPlace) {
57
- console.log(chalk.gray(`Branch: ${branchName}`));
58
- }
59
- const ports = calculatePorts(config, sessionId);
60
- console.log(chalk.gray("\nPorts:"));
61
- console.log(chalk.gray(formatPortsTable(ports)));
62
- let sessionDir;
63
- if (inPlace) {
64
- sessionDir = projectRoot;
65
- console.log(chalk.blue("\nUsing current directory (in-place mode)..."));
66
- console.log(chalk.green(` Directory: ${sessionDir}`));
67
- } else {
68
- if (!existsSync(sessionsDir)) {
69
- mkdirSync(sessionsDir, { recursive: true });
70
- }
71
- sessionDir = getSessionDir(config, projectRoot, sessionId);
72
- console.log(chalk.blue("\nCreating git worktree..."));
73
- await createWorktree(projectRoot, sessionDir, branchName);
74
- console.log(chalk.green(` Created: ${sessionDir}`));
75
- const sessionDbUrl = `postgresql://postgres:postgres@localhost:${ports.POSTGRES_PORT}/postgres`;
76
- const envFilesToCopy = config.envFiles ?? [];
77
- for (const envFile of envFilesToCopy) {
78
- const srcPath = join(projectRoot, envFile);
79
- const destPath = join(sessionDir, envFile);
80
- if (existsSync(srcPath)) {
81
- copyFileSync(srcPath, destPath);
82
- updateEnvDatabaseUrl(destPath, sessionDbUrl);
83
- console.log(chalk.green(` Copied: ${envFile} (updated DATABASE_URL)`));
84
- }
85
- }
86
- }
87
- console.log(chalk.blue("\nGenerating .env.session..."));
88
- const projectName = config.projectName ?? basename(projectRoot);
89
- const envPath = writeEnvFile(sessionDir, sessionId, ports, projectName);
90
- console.log(chalk.green(` Written: ${envPath}`));
91
- const appEnvFiles = writeAppEnvFiles(config, sessionDir, sessionId, ports);
92
- for (const file of appEnvFiles) {
93
- console.log(chalk.green(` Written: ${file}`));
94
- }
95
- console.log(chalk.blue("\nStarting Docker services..."));
96
- let profiles;
97
- if (mode === "docker") {
98
- const allApps = config.apps ?? [];
99
- const excludeApps = options.without ?? [];
100
- profiles = allApps.filter((app) => !excludeApps.includes(app));
101
- if (excludeApps.length > 0) {
102
- console.log(chalk.gray(` Excluding apps: ${excludeApps.join(", ")}`));
103
- }
104
- }
105
- await up({ cwd: sessionDir, profiles });
106
- console.log(chalk.blue("Waiting for services to be ready..."));
107
- await new Promise((resolve) => setTimeout(resolve, 3e3));
108
- if (config.setup.length > 0) {
109
- console.log(chalk.blue("\nRunning setup commands..."));
110
- const setupEnv = {
111
- ...process.env,
112
- SESSION_ID: sessionId,
113
- // Add DATABASE_URL for db commands
114
- DATABASE_URL: `postgresql://postgres:postgres@localhost:${ports.POSTGRES_PORT}/postgres`
115
- };
116
- for (const [name, port] of Object.entries(ports)) {
117
- setupEnv[name] = String(port);
118
- }
119
- for (const cmd of config.setup) {
120
- console.log(chalk.gray(` Running: ${cmd}`));
121
- const [command, ...args] = cmd.split(" ");
122
- try {
123
- await execa(command, args, {
124
- cwd: sessionDir,
125
- stdio: "inherit",
126
- env: setupEnv
127
- });
128
- } catch {
129
- console.warn(chalk.yellow(` Warning: Command failed: ${cmd}`));
130
- }
131
- }
132
- }
133
- console.log(chalk.green(`
134
- Session ${sessionId} ready!`));
135
- console.log(chalk.gray(`Directory: ${sessionDir}`));
136
- if (mode === "docker") {
137
- console.log(chalk.gray("\nDocker mode - all services in containers."));
138
- console.log(chalk.gray("View logs: docker compose -f docker-compose.session.yml logs -f"));
139
- } else {
140
- console.log(chalk.gray("\nNative mode - run apps with: pnpm dev"));
141
- }
142
- console.log(chalk.gray("\nPorts:"));
143
- for (const [name, port] of Object.entries(ports)) {
144
- console.log(chalk.cyan(` ${name}: ${port}`));
145
- }
146
- if (options.detach === false) {
147
- console.log(chalk.blue("\nStreaming logs (Ctrl+C to stop)..."));
148
- console.log(chalk.gray("\u2500".repeat(60)));
149
- try {
150
- await logs({ cwd: sessionDir, profiles });
151
- } catch (error) {
152
- const execaError = error;
153
- if (execaError.signal === "SIGINT") {
154
- console.log(chalk.gray("\n\u2500".repeat(60)));
155
- console.log(chalk.yellow("\nLog streaming stopped. Services are still running."));
156
- console.log(chalk.gray(`Resume logs: cd ${sessionDir} && docker compose -f docker-compose.session.yml --env-file .env.session logs -f`));
157
- } else {
158
- throw error;
159
- }
160
- }
161
- }
162
- }
163
-
164
- export {
165
- createSession
166
- };
@@ -1,22 +0,0 @@
1
- // src/lib/ports.ts
2
- function calculatePorts(config, sessionId) {
3
- const sessionNum = parseInt(sessionId, 10);
4
- const basePort = config.portBase + sessionNum * 100;
5
- const ports = {};
6
- for (const [name, offset] of Object.entries(config.ports)) {
7
- ports[name] = basePort + offset;
8
- }
9
- return ports;
10
- }
11
- function formatPortsTable(ports) {
12
- const lines = [];
13
- for (const [name, port] of Object.entries(ports)) {
14
- lines.push(` ${name}: ${port}`);
15
- }
16
- return lines.join("\n");
17
- }
18
-
19
- export {
20
- calculatePorts,
21
- formatPortsTable
22
- };
@@ -1,168 +0,0 @@
1
- import {
2
- calculatePorts,
3
- formatPortsTable
4
- } from "./chunk-PJKUD2N2.js";
5
- import {
6
- createWorktree,
7
- findNextSessionId,
8
- generateDefaultBranchName
9
- } from "./chunk-GWDGC2OE.js";
10
- import {
11
- getSessionDir,
12
- getSessionsDir,
13
- loadConfig
14
- } from "./chunk-25WQHUYW.js";
15
- import {
16
- logs,
17
- up
18
- } from "./chunk-VR3QWHHB.js";
19
- import {
20
- writeAppEnvFiles,
21
- writeEnvFile
22
- } from "./chunk-LEHA65A7.js";
23
-
24
- // src/commands/create.ts
25
- import { existsSync, mkdirSync, copyFileSync, readFileSync, writeFileSync } from "fs";
26
- import { basename, join } from "path";
27
- import chalk from "chalk";
28
- import { execa } from "execa";
29
- function updateEnvDatabaseUrl(envPath, newDbUrl) {
30
- if (!existsSync(envPath)) return;
31
- let content = readFileSync(envPath, "utf-8");
32
- if (content.includes("DATABASE_URL=")) {
33
- content = content.replace(/^DATABASE_URL=.*/m, `DATABASE_URL=${newDbUrl}`);
34
- } else {
35
- content += `
36
- DATABASE_URL=${newDbUrl}
37
- `;
38
- }
39
- writeFileSync(envPath, content);
40
- }
41
- async function createSession(projectRoot, sessionId, options) {
42
- const config = await loadConfig(projectRoot);
43
- const sessionsDir = getSessionsDir(config, projectRoot);
44
- if (!sessionId) {
45
- sessionId = await findNextSessionId(projectRoot, sessionsDir);
46
- console.log(chalk.gray(`Auto-assigned session ID: ${sessionId}`));
47
- }
48
- if (!/^\d{3}$/.test(sessionId)) {
49
- console.error(chalk.red("Error: Session ID must be exactly 3 digits (001-999)"));
50
- process.exit(1);
51
- }
52
- const inPlace = options.inPlace ?? false;
53
- const branchName = options.branch || generateDefaultBranchName(sessionId);
54
- const mode = options.mode || "docker";
55
- console.log(chalk.blue(`Creating session ${sessionId} (${mode} mode${inPlace ? ", in-place" : ""})...`));
56
- if (!inPlace) {
57
- console.log(chalk.gray(`Branch: ${branchName}`));
58
- }
59
- const ports = calculatePorts(config, sessionId);
60
- console.log(chalk.gray("\nPorts:"));
61
- console.log(chalk.gray(formatPortsTable(ports)));
62
- let sessionDir;
63
- if (inPlace) {
64
- sessionDir = projectRoot;
65
- console.log(chalk.blue("\nUsing current directory (in-place mode)..."));
66
- console.log(chalk.green(` Directory: ${sessionDir}`));
67
- } else {
68
- if (!existsSync(sessionsDir)) {
69
- mkdirSync(sessionsDir, { recursive: true });
70
- }
71
- sessionDir = getSessionDir(config, projectRoot, sessionId);
72
- console.log(chalk.blue("\nCreating git worktree..."));
73
- await createWorktree(projectRoot, sessionDir, branchName);
74
- console.log(chalk.green(` Created: ${sessionDir}`));
75
- const sessionDbUrl = `postgresql://postgres:postgres@localhost:${ports.POSTGRES_PORT}/postgres`;
76
- const envFilesToCopy = config.envFiles ?? [];
77
- for (const envFile of envFilesToCopy) {
78
- const srcPath = join(projectRoot, envFile);
79
- const destPath = join(sessionDir, envFile);
80
- if (existsSync(srcPath)) {
81
- copyFileSync(srcPath, destPath);
82
- updateEnvDatabaseUrl(destPath, sessionDbUrl);
83
- console.log(chalk.green(` Copied: ${envFile} (updated DATABASE_URL)`));
84
- }
85
- }
86
- }
87
- console.log(chalk.blue("\nGenerating .env.session..."));
88
- const projectName = config.projectName ?? basename(projectRoot);
89
- const envPath = writeEnvFile(sessionDir, sessionId, ports, projectName);
90
- console.log(chalk.green(` Written: ${envPath}`));
91
- const appEnvFiles = writeAppEnvFiles(config, sessionDir, sessionId, ports);
92
- for (const file of appEnvFiles) {
93
- console.log(chalk.green(` Written: ${file}`));
94
- }
95
- console.log(chalk.blue("\nStarting Docker services..."));
96
- let profiles;
97
- if (mode === "docker") {
98
- const allApps = config.apps ?? ["app", "web", "widget"];
99
- const excludeApps = options.without ?? [];
100
- profiles = allApps.filter((app) => !excludeApps.includes(app));
101
- if (excludeApps.length > 0) {
102
- console.log(chalk.gray(` Excluding apps: ${excludeApps.join(", ")}`));
103
- }
104
- }
105
- await up({ cwd: sessionDir, profiles });
106
- console.log(chalk.blue("Waiting for services to be ready..."));
107
- await new Promise((resolve) => setTimeout(resolve, 3e3));
108
- if (config.setup.length > 0) {
109
- console.log(chalk.blue("\nRunning setup commands..."));
110
- const setupEnv = {
111
- ...process.env,
112
- SESSION_ID: sessionId,
113
- // Add DATABASE_URL for db commands
114
- DATABASE_URL: `postgresql://postgres:postgres@localhost:${ports.POSTGRES_PORT}/postgres`
115
- };
116
- for (const [name, port] of Object.entries(ports)) {
117
- setupEnv[name] = String(port);
118
- }
119
- for (const cmd of config.setup) {
120
- console.log(chalk.gray(` Running: ${cmd}`));
121
- const [command, ...args] = cmd.split(" ");
122
- try {
123
- await execa(command, args, {
124
- cwd: sessionDir,
125
- stdio: "inherit",
126
- env: setupEnv
127
- });
128
- } catch {
129
- console.warn(chalk.yellow(` Warning: Command failed: ${cmd}`));
130
- }
131
- }
132
- }
133
- console.log(chalk.green(`
134
- Session ${sessionId} ready!`));
135
- console.log(chalk.gray(`Directory: ${sessionDir}`));
136
- if (mode === "docker") {
137
- console.log(chalk.gray("\nDocker mode - all services in containers."));
138
- console.log(chalk.gray("View logs: docker compose -f docker-compose.session.yml logs -f"));
139
- } else {
140
- console.log(chalk.gray("\nNative mode - run apps with: pnpm dev"));
141
- }
142
- console.log(chalk.gray("\nURLs:"));
143
- for (const [name, port] of Object.entries(ports)) {
144
- if (name.includes("APP") || name.includes("WEB") || name.includes("WIDGET")) {
145
- console.log(chalk.cyan(` ${name}: http://localhost:${port}`));
146
- }
147
- }
148
- if (options.detach === false) {
149
- console.log(chalk.blue("\nStreaming logs (Ctrl+C to stop)..."));
150
- console.log(chalk.gray("\u2500".repeat(60)));
151
- try {
152
- await logs({ cwd: sessionDir, profiles });
153
- } catch (error) {
154
- const execaError = error;
155
- if (execaError.signal === "SIGINT") {
156
- console.log(chalk.gray("\n\u2500".repeat(60)));
157
- console.log(chalk.yellow("\nLog streaming stopped. Services are still running."));
158
- console.log(chalk.gray(`Resume logs: cd ${sessionDir} && docker compose -f docker-compose.session.yml --env-file .env.session logs -f`));
159
- } else {
160
- throw error;
161
- }
162
- }
163
- }
164
- }
165
-
166
- export {
167
- createSession
168
- };
@@ -1,168 +0,0 @@
1
- import {
2
- calculatePorts,
3
- formatPortsTable
4
- } from "./chunk-PJKUD2N2.js";
5
- import {
6
- createWorktree,
7
- findNextSessionId,
8
- generateDefaultBranchName
9
- } from "./chunk-GWDGC2OE.js";
10
- import {
11
- getSessionDir,
12
- getSessionsDir,
13
- loadConfig
14
- } from "./chunk-25WQHUYW.js";
15
- import {
16
- logs,
17
- up
18
- } from "./chunk-GBN67HYD.js";
19
- import {
20
- writeAppEnvFiles,
21
- writeEnvFile
22
- } from "./chunk-LEHA65A7.js";
23
-
24
- // src/commands/create.ts
25
- import { existsSync, mkdirSync, copyFileSync, readFileSync, writeFileSync } from "fs";
26
- import { basename, join } from "path";
27
- import chalk from "chalk";
28
- import { execa } from "execa";
29
- function updateEnvDatabaseUrl(envPath, newDbUrl) {
30
- if (!existsSync(envPath)) return;
31
- let content = readFileSync(envPath, "utf-8");
32
- if (content.includes("DATABASE_URL=")) {
33
- content = content.replace(/^DATABASE_URL=.*/m, `DATABASE_URL=${newDbUrl}`);
34
- } else {
35
- content += `
36
- DATABASE_URL=${newDbUrl}
37
- `;
38
- }
39
- writeFileSync(envPath, content);
40
- }
41
- async function createSession(projectRoot, sessionId, options) {
42
- const config = await loadConfig(projectRoot);
43
- const sessionsDir = getSessionsDir(config, projectRoot);
44
- if (!sessionId) {
45
- sessionId = await findNextSessionId(projectRoot, sessionsDir);
46
- console.log(chalk.gray(`Auto-assigned session ID: ${sessionId}`));
47
- }
48
- if (!/^\d{3}$/.test(sessionId)) {
49
- console.error(chalk.red("Error: Session ID must be exactly 3 digits (001-999)"));
50
- process.exit(1);
51
- }
52
- const inPlace = options.inPlace ?? false;
53
- const branchName = options.branch || generateDefaultBranchName(sessionId);
54
- const mode = options.mode || "docker";
55
- console.log(chalk.blue(`Creating session ${sessionId} (${mode} mode${inPlace ? ", in-place" : ""})...`));
56
- if (!inPlace) {
57
- console.log(chalk.gray(`Branch: ${branchName}`));
58
- }
59
- const ports = calculatePorts(config, sessionId);
60
- console.log(chalk.gray("\nPorts:"));
61
- console.log(chalk.gray(formatPortsTable(ports)));
62
- let sessionDir;
63
- if (inPlace) {
64
- sessionDir = projectRoot;
65
- console.log(chalk.blue("\nUsing current directory (in-place mode)..."));
66
- console.log(chalk.green(` Directory: ${sessionDir}`));
67
- } else {
68
- if (!existsSync(sessionsDir)) {
69
- mkdirSync(sessionsDir, { recursive: true });
70
- }
71
- sessionDir = getSessionDir(config, projectRoot, sessionId);
72
- console.log(chalk.blue("\nCreating git worktree..."));
73
- await createWorktree(projectRoot, sessionDir, branchName);
74
- console.log(chalk.green(` Created: ${sessionDir}`));
75
- const sessionDbUrl = `postgresql://postgres:postgres@localhost:${ports.POSTGRES_PORT}/postgres`;
76
- const envFilesToCopy = config.envFiles ?? [];
77
- for (const envFile of envFilesToCopy) {
78
- const srcPath = join(projectRoot, envFile);
79
- const destPath = join(sessionDir, envFile);
80
- if (existsSync(srcPath)) {
81
- copyFileSync(srcPath, destPath);
82
- updateEnvDatabaseUrl(destPath, sessionDbUrl);
83
- console.log(chalk.green(` Copied: ${envFile} (updated DATABASE_URL)`));
84
- }
85
- }
86
- }
87
- console.log(chalk.blue("\nGenerating .env.session..."));
88
- const projectName = config.projectName ?? basename(projectRoot);
89
- const envPath = writeEnvFile(sessionDir, sessionId, ports, projectName);
90
- console.log(chalk.green(` Written: ${envPath}`));
91
- const appEnvFiles = writeAppEnvFiles(config, sessionDir, sessionId, ports);
92
- for (const file of appEnvFiles) {
93
- console.log(chalk.green(` Written: ${file}`));
94
- }
95
- console.log(chalk.blue("\nStarting Docker services..."));
96
- let profiles;
97
- if (mode === "docker") {
98
- const allApps = config.apps ?? [];
99
- const excludeApps = options.without ?? [];
100
- profiles = allApps.filter((app) => !excludeApps.includes(app));
101
- if (excludeApps.length > 0) {
102
- console.log(chalk.gray(` Excluding apps: ${excludeApps.join(", ")}`));
103
- }
104
- }
105
- await up({ cwd: sessionDir, profiles });
106
- console.log(chalk.blue("Waiting for services to be ready..."));
107
- await new Promise((resolve) => setTimeout(resolve, 3e3));
108
- if (config.setup.length > 0) {
109
- console.log(chalk.blue("\nRunning setup commands..."));
110
- const setupEnv = {
111
- ...process.env,
112
- SESSION_ID: sessionId,
113
- // Add DATABASE_URL for db commands
114
- DATABASE_URL: `postgresql://postgres:postgres@localhost:${ports.POSTGRES_PORT}/postgres`
115
- };
116
- for (const [name, port] of Object.entries(ports)) {
117
- setupEnv[name] = String(port);
118
- }
119
- for (const cmd of config.setup) {
120
- console.log(chalk.gray(` Running: ${cmd}`));
121
- const [command, ...args] = cmd.split(" ");
122
- try {
123
- await execa(command, args, {
124
- cwd: sessionDir,
125
- stdio: "inherit",
126
- env: setupEnv
127
- });
128
- } catch {
129
- console.warn(chalk.yellow(` Warning: Command failed: ${cmd}`));
130
- }
131
- }
132
- }
133
- console.log(chalk.green(`
134
- Session ${sessionId} ready!`));
135
- console.log(chalk.gray(`Directory: ${sessionDir}`));
136
- if (mode === "docker") {
137
- console.log(chalk.gray("\nDocker mode - all services in containers."));
138
- console.log(chalk.gray("View logs: docker compose -f docker-compose.session.yml logs -f"));
139
- } else {
140
- console.log(chalk.gray("\nNative mode - run apps with: pnpm dev"));
141
- }
142
- console.log(chalk.gray("\nURLs:"));
143
- for (const [name, port] of Object.entries(ports)) {
144
- if (name.includes("APP") || name.includes("WEB") || name.includes("WIDGET")) {
145
- console.log(chalk.cyan(` ${name}: http://localhost:${port}`));
146
- }
147
- }
148
- if (options.detach === false) {
149
- console.log(chalk.blue("\nStreaming logs (Ctrl+C to stop)..."));
150
- console.log(chalk.gray("\u2500".repeat(60)));
151
- try {
152
- await logs({ cwd: sessionDir, profiles });
153
- } catch (error) {
154
- const execaError = error;
155
- if (execaError.signal === "SIGINT") {
156
- console.log(chalk.gray("\n\u2500".repeat(60)));
157
- console.log(chalk.yellow("\nLog streaming stopped. Services are still running."));
158
- console.log(chalk.gray(`Resume logs: cd ${sessionDir} && docker compose -f docker-compose.session.yml --env-file .env.session logs -f`));
159
- } else {
160
- throw error;
161
- }
162
- }
163
- }
164
- }
165
-
166
- export {
167
- createSession
168
- };
@@ -1,171 +0,0 @@
1
- import {
2
- calculatePorts,
3
- formatPortsTable
4
- } from "./chunk-PJKUD2N2.js";
5
- import {
6
- createWorktree,
7
- findNextSessionId,
8
- generateDefaultBranchName
9
- } from "./chunk-GWDGC2OE.js";
10
- import {
11
- getSessionDir,
12
- getSessionsDir,
13
- loadConfig
14
- } from "./chunk-25WQHUYW.js";
15
- import {
16
- logs,
17
- up
18
- } from "./chunk-VR3QWHHB.js";
19
- import {
20
- writeAppEnvFiles,
21
- writeEnvFile
22
- } from "./chunk-LEHA65A7.js";
23
-
24
- // src/commands/create.ts
25
- import { existsSync, mkdirSync, copyFileSync, readFileSync, writeFileSync } from "fs";
26
- import { basename, join } from "path";
27
- import chalk from "chalk";
28
- import { execa } from "execa";
29
- function updateEnvDatabaseUrl(envPath, newDbUrl) {
30
- if (!existsSync(envPath)) return;
31
- let content = readFileSync(envPath, "utf-8");
32
- if (content.includes("DATABASE_URL=")) {
33
- content = content.replace(/^DATABASE_URL=.*/m, `DATABASE_URL=${newDbUrl}`);
34
- } else {
35
- content += `
36
- DATABASE_URL=${newDbUrl}
37
- `;
38
- }
39
- writeFileSync(envPath, content);
40
- }
41
- async function createSession(projectRoot, sessionId, options) {
42
- const config = await loadConfig(projectRoot);
43
- const sessionsDir = getSessionsDir(config, projectRoot);
44
- if (!sessionId) {
45
- sessionId = await findNextSessionId(projectRoot, sessionsDir);
46
- console.log(chalk.gray(`Auto-assigned session ID: ${sessionId}`));
47
- }
48
- if (!/^\d{3}$/.test(sessionId)) {
49
- console.error(chalk.red("Error: Session ID must be exactly 3 digits (001-999)"));
50
- process.exit(1);
51
- }
52
- const inPlace = options.inPlace ?? false;
53
- const branchName = options.branch || generateDefaultBranchName(sessionId);
54
- const mode = options.mode || "docker";
55
- console.log(chalk.blue(`Creating session ${sessionId} (${mode} mode${inPlace ? ", in-place" : ""})...`));
56
- if (!inPlace) {
57
- console.log(chalk.gray(`Branch: ${branchName}`));
58
- }
59
- const ports = calculatePorts(config, sessionId);
60
- console.log(chalk.gray("\nPorts:"));
61
- console.log(chalk.gray(formatPortsTable(ports)));
62
- let sessionDir;
63
- if (inPlace) {
64
- sessionDir = projectRoot;
65
- console.log(chalk.blue("\nUsing current directory (in-place mode)..."));
66
- console.log(chalk.green(` Directory: ${sessionDir}`));
67
- } else {
68
- if (!existsSync(sessionsDir)) {
69
- mkdirSync(sessionsDir, { recursive: true });
70
- }
71
- sessionDir = getSessionDir(config, projectRoot, sessionId);
72
- console.log(chalk.blue("\nCreating git worktree..."));
73
- await createWorktree(projectRoot, sessionDir, branchName);
74
- console.log(chalk.green(` Created: ${sessionDir}`));
75
- const sessionDbUrl = `postgresql://postgres:postgres@localhost:${ports.POSTGRES_PORT}/postgres`;
76
- const envFilesToCopy = [
77
- "apps/convas-app/.env",
78
- "packages/convas-db/.env"
79
- ];
80
- for (const envFile of envFilesToCopy) {
81
- const srcPath = join(projectRoot, envFile);
82
- const destPath = join(sessionDir, envFile);
83
- if (existsSync(srcPath)) {
84
- copyFileSync(srcPath, destPath);
85
- updateEnvDatabaseUrl(destPath, sessionDbUrl);
86
- console.log(chalk.green(` Copied: ${envFile} (updated DATABASE_URL)`));
87
- }
88
- }
89
- }
90
- console.log(chalk.blue("\nGenerating .env.session..."));
91
- const projectName = config.projectName ?? basename(projectRoot);
92
- const envPath = writeEnvFile(sessionDir, sessionId, ports, projectName);
93
- console.log(chalk.green(` Written: ${envPath}`));
94
- const appEnvFiles = writeAppEnvFiles(config, sessionDir, sessionId, ports);
95
- for (const file of appEnvFiles) {
96
- console.log(chalk.green(` Written: ${file}`));
97
- }
98
- console.log(chalk.blue("\nStarting Docker services..."));
99
- let profiles;
100
- if (mode === "docker") {
101
- const allApps = config.apps ?? ["app", "web", "widget"];
102
- const excludeApps = options.without ?? [];
103
- profiles = allApps.filter((app) => !excludeApps.includes(app));
104
- if (excludeApps.length > 0) {
105
- console.log(chalk.gray(` Excluding apps: ${excludeApps.join(", ")}`));
106
- }
107
- }
108
- await up({ cwd: sessionDir, profiles });
109
- console.log(chalk.blue("Waiting for services to be ready..."));
110
- await new Promise((resolve) => setTimeout(resolve, 3e3));
111
- if (config.setup.length > 0) {
112
- console.log(chalk.blue("\nRunning setup commands..."));
113
- const setupEnv = {
114
- ...process.env,
115
- SESSION_ID: sessionId,
116
- // Add DATABASE_URL for db commands
117
- DATABASE_URL: `postgresql://postgres:postgres@localhost:${ports.POSTGRES_PORT}/postgres`
118
- };
119
- for (const [name, port] of Object.entries(ports)) {
120
- setupEnv[name] = String(port);
121
- }
122
- for (const cmd of config.setup) {
123
- console.log(chalk.gray(` Running: ${cmd}`));
124
- const [command, ...args] = cmd.split(" ");
125
- try {
126
- await execa(command, args, {
127
- cwd: sessionDir,
128
- stdio: "inherit",
129
- env: setupEnv
130
- });
131
- } catch {
132
- console.warn(chalk.yellow(` Warning: Command failed: ${cmd}`));
133
- }
134
- }
135
- }
136
- console.log(chalk.green(`
137
- Session ${sessionId} ready!`));
138
- console.log(chalk.gray(`Directory: ${sessionDir}`));
139
- if (mode === "docker") {
140
- console.log(chalk.gray("\nDocker mode - all services in containers."));
141
- console.log(chalk.gray("View logs: docker compose -f docker-compose.session.yml logs -f"));
142
- } else {
143
- console.log(chalk.gray("\nNative mode - run apps with: pnpm dev"));
144
- }
145
- console.log(chalk.gray("\nURLs:"));
146
- for (const [name, port] of Object.entries(ports)) {
147
- if (name.includes("APP") || name.includes("WEB") || name.includes("WIDGET")) {
148
- console.log(chalk.cyan(` ${name}: http://localhost:${port}`));
149
- }
150
- }
151
- if (options.detach === false) {
152
- console.log(chalk.blue("\nStreaming logs (Ctrl+C to stop)..."));
153
- console.log(chalk.gray("\u2500".repeat(60)));
154
- try {
155
- await logs({ cwd: sessionDir, profiles });
156
- } catch (error) {
157
- const execaError = error;
158
- if (execaError.signal === "SIGINT") {
159
- console.log(chalk.gray("\n\u2500".repeat(60)));
160
- console.log(chalk.yellow("\nLog streaming stopped. Services are still running."));
161
- console.log(chalk.gray(`Resume logs: cd ${sessionDir} && docker compose -f docker-compose.session.yml --env-file .env.session logs -f`));
162
- } else {
163
- throw error;
164
- }
165
- }
166
- }
167
- }
168
-
169
- export {
170
- createSession
171
- };