stashes 0.2.1 → 0.2.3

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.
@@ -1 +1 @@
1
- {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"AAMA,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;CACf;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAmCrF"}
1
+ {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"AAOA,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;CACf;AAaD,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA8CrF"}
@@ -11,35 +11,151 @@ export async function startCommand(path, options) {
11
11
  console.log(' ╚═╝ ╩ ╩ ╩╚═╝╩ ╩╚═╝╚═╝');
12
12
  console.log('');
13
13
  const detected = detectFramework(projectPath);
14
- const devPort = parseInt(options.devPort || String(detected.devPort), 10);
14
+ const preferredPort = parseInt(options.devPort || String(detected.devPort), 10);
15
15
  console.log(` Project: ${projectPath}`);
16
16
  console.log(` Framework: ${detected.framework}`);
17
- console.log(` Dev server: http://localhost:${devPort}`);
18
- const isDevRunning = await checkPort(devPort);
19
- if (!isDevRunning) {
20
- console.log('');
21
- console.log(` ! Your dev server is not running on port ${devPort}`);
22
- console.log(` Start it with: ${detected.devCommand}`);
23
- }
24
- const result = await startServer(projectPath, devPort, requestedPort);
17
+ // Start or reuse the dev server
18
+ const devServer = await ensureDevServer(projectPath, preferredPort, detected.devCommand);
19
+ console.log(` Dev server: http://localhost:${devServer.port}`);
20
+ const result = await startServer(projectPath, devServer.port, requestedPort);
25
21
  console.log(` Stashes: http://localhost:${result.port}`);
26
22
  if (result.port !== requestedPort) {
27
23
  console.log(` (port ${requestedPort} was in use, using ${result.port})`);
28
24
  }
29
25
  console.log('');
26
+ // Clean up managed dev server on exit
27
+ if (devServer.managedByUs && devServer.process) {
28
+ const cleanup = () => {
29
+ try {
30
+ devServer.process?.kill();
31
+ }
32
+ catch {
33
+ // Process may already be dead
34
+ }
35
+ };
36
+ const onSignal = () => { cleanup(); process.exit(0); };
37
+ process.once('SIGINT', onSignal);
38
+ process.once('SIGTERM', onSignal);
39
+ }
30
40
  if (options.open !== false) {
31
41
  await open(`http://localhost:${result.port}`);
32
42
  }
33
43
  }
34
- async function checkPort(port) {
44
+ /** Ensure a dev server is running for the project. Starts one if needed. */
45
+ async function ensureDevServer(projectPath, preferredPort, devCommand) {
46
+ const portStatus = await checkPortOwnership(preferredPort, projectPath);
47
+ if (portStatus.status === 'ours') {
48
+ console.log(` Dev server already running on port ${preferredPort}, reusing`);
49
+ return { process: null, port: preferredPort, managedByUs: false };
50
+ }
51
+ let targetPort = preferredPort;
52
+ if (portStatus.status === 'foreign') {
53
+ targetPort = await findFreePort(preferredPort);
54
+ console.log(` Port ${preferredPort} in use by another app, starting dev server on port ${targetPort}`);
55
+ }
56
+ else {
57
+ console.log(` Starting dev server: ${devCommand} (port ${targetPort})`);
58
+ }
59
+ const devProcess = Bun.spawn({
60
+ cmd: ['sh', '-c', devCommand],
61
+ cwd: projectPath,
62
+ stdin: 'ignore',
63
+ stdout: 'inherit',
64
+ stderr: 'inherit',
65
+ env: { ...Bun.env, PORT: String(targetPort), BROWSER: 'none' },
66
+ });
67
+ await waitForPort(targetPort, 60_000, devProcess);
68
+ return { process: devProcess, port: targetPort, managedByUs: true };
69
+ }
70
+ /** Check who owns a port: free, our project, or a foreign process */
71
+ async function checkPortOwnership(port, projectPath) {
35
72
  try {
36
- const response = await fetch(`http://localhost:${port}`, {
37
- signal: AbortSignal.timeout(2000),
73
+ const pidResult = Bun.spawnSync({
74
+ cmd: ['lsof', '-ti', `:${port}`],
75
+ stdout: 'pipe',
76
+ stderr: 'pipe',
38
77
  });
39
- return response.ok || response.status < 500;
78
+ const pidOutput = pidResult.stdout.toString().trim();
79
+ if (!pidOutput)
80
+ return { status: 'free' };
81
+ // Check all PIDs on this port (IPv4/IPv6 or parent/worker)
82
+ const pids = [...new Set(pidOutput.split('\n').map(p => p.trim()).filter(Boolean))];
83
+ if (pids.length === 0)
84
+ return { status: 'free' };
85
+ const normalizedProjectPath = resolve(projectPath);
86
+ for (const pid of pids) {
87
+ const cwd = getProcessCwd(pid);
88
+ if (cwd && resolve(cwd) === normalizedProjectPath) {
89
+ return { status: 'ours' };
90
+ }
91
+ }
92
+ // Port is occupied but no process matched our project
93
+ return { status: 'foreign' };
40
94
  }
41
95
  catch {
42
- return false;
96
+ // lsof not available or failed — assume port is free
97
+ return { status: 'free' };
98
+ }
99
+ }
100
+ /** Get the working directory of a process by PID */
101
+ function getProcessCwd(pid) {
102
+ try {
103
+ const result = Bun.spawnSync({
104
+ cmd: ['lsof', '-p', pid, '-Fn'],
105
+ stdout: 'pipe',
106
+ stderr: 'pipe',
107
+ });
108
+ const lines = result.stdout.toString().split('\n');
109
+ let foundCwd = false;
110
+ for (const line of lines) {
111
+ if (line === 'fcwd') {
112
+ foundCwd = true;
113
+ continue;
114
+ }
115
+ if (foundCwd && line.startsWith('n')) {
116
+ return line.slice(1); // Remove the 'n' prefix
117
+ }
118
+ if (foundCwd) {
119
+ foundCwd = false;
120
+ }
121
+ }
122
+ return null;
123
+ }
124
+ catch {
125
+ return null;
126
+ }
127
+ }
128
+ /** Find the next free port starting from the given port */
129
+ async function findFreePort(startPort) {
130
+ for (let port = startPort + 1; port < startPort + 100; port++) {
131
+ try {
132
+ const server = Bun.serve({ port, fetch: () => new Response('') });
133
+ server.stop(true);
134
+ return port;
135
+ }
136
+ catch {
137
+ continue;
138
+ }
139
+ }
140
+ throw new Error(`No free port found in range ${startPort + 1}-${startPort + 100}`);
141
+ }
142
+ /** Poll a port until it responds with a non-5xx status */
143
+ async function waitForPort(port, timeout, proc) {
144
+ const start = Date.now();
145
+ while (Date.now() - start < timeout) {
146
+ if (proc && proc.exitCode !== null) {
147
+ throw new Error(`Dev server exited with code ${proc.exitCode} before becoming ready`);
148
+ }
149
+ try {
150
+ const res = await fetch(`http://localhost:${port}`, { signal: AbortSignal.timeout(2000) });
151
+ if (res.ok || res.status < 500)
152
+ return;
153
+ }
154
+ catch {
155
+ // Not ready yet
156
+ }
157
+ await new Promise((r) => setTimeout(r, 1000));
43
158
  }
159
+ throw new Error(`Dev server on port ${port} not ready within ${timeout / 1000}s`);
44
160
  }
45
161
  //# sourceMappingURL=start.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AASpE,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAY,EAAE,OAAqB;IACpE,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC;IACzC,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAEjD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IACvC,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IACvC,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IACvC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,MAAM,QAAQ,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;IAC9C,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;IAE1E,OAAO,CAAC,GAAG,CAAC,iBAAiB,WAAW,EAAE,CAAC,CAAC;IAC5C,OAAO,CAAC,GAAG,CAAC,iBAAiB,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC;IACnD,OAAO,CAAC,GAAG,CAAC,kCAAkC,OAAO,EAAE,CAAC,CAAC;IAEzD,MAAM,YAAY,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,CAAC;IAC9C,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,8CAA8C,OAAO,EAAE,CAAC,CAAC;QACrE,OAAO,CAAC,GAAG,CAAC,sBAAsB,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,WAAW,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;IAEtE,OAAO,CAAC,GAAG,CAAC,kCAAkC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IAC7D,IAAI,MAAM,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,WAAW,aAAa,sBAAsB,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QAC3B,MAAM,IAAI,CAAC,oBAAoB,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC;AACH,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,IAAY;IACnC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,oBAAoB,IAAI,EAAE,EAAE;YACvD,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC;SAClC,CAAC,CAAC;QACH,OAAO,QAAQ,CAAC,EAAE,IAAI,QAAQ,CAAC,MAAM,GAAG,GAAG,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"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"}