@elyun/bylane 1.24.0 → 1.26.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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/cli.js +35 -17
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elyun/bylane",
3
- "version": "1.24.0",
3
+ "version": "1.26.0",
4
4
  "description": "Frontend development harness for Claude Code",
5
5
  "type": "module",
6
6
  "bin": {
package/src/cli.js CHANGED
@@ -256,32 +256,50 @@ if (command === 'install') {
256
256
  respond.on('exit', onExit)
257
257
  }
258
258
  } else if (subCmd === 'stop') {
259
- const mode = resolveLoopMode()
260
- if (mode === 'tmux') {
259
+ let stopped = false
260
+
261
+ // 1) tmux 세션 종료 시도 (모드 무관)
262
+ if (isTmuxSessionAlive(sessionName)) {
261
263
  stopTmuxLoops(sessionName)
262
- } else {
263
- // process 모드: state에서 PID를 읽어 종료
264
- const { readState } = await import('./state.js')
265
- for (const loopName of ['review-loop', 'respond-loop']) {
266
- const state = readState(loopName)
267
- if (state?.pid) {
268
- try {
269
- process.kill(state.pid, 'SIGTERM')
270
- console.log(` ${loopName} (PID: ${state.pid}) 종료`)
271
- } catch {
272
- console.log(` ${loopName} (PID: ${state.pid}) 이미 종료됨`)
273
- }
264
+ stopped = true
265
+ }
266
+
267
+ // 2) process 모드 PID 종료 시도 (모드 무관)
268
+ const { readState, writeState } = await import('./state.js')
269
+ for (const loopName of ['review-loop', 'respond-loop']) {
270
+ const state = readState(loopName)
271
+ if (!state?.pid) continue
272
+ const pid = Number(state.pid)
273
+ let alive = false
274
+ try { process.kill(pid, 0); alive = true } catch {}
275
+
276
+ if (alive) {
277
+ try {
278
+ process.kill(pid, 'SIGTERM')
279
+ console.log(` ${loopName} (PID: ${pid}) 종료`)
280
+ } catch {
281
+ console.log(` ${loopName} (PID: ${pid}) 종료 실패`)
274
282
  }
283
+ } else {
284
+ console.log(` ${loopName} (PID: ${pid}) 이미 종료됨 — 상태 정리`)
275
285
  }
286
+ writeState(loopName, { ...state, status: 'stopped', stoppedAt: new Date().toISOString() })
287
+ stopped = true
288
+ }
289
+
290
+ if (!stopped) {
291
+ console.log(' 실행 중인 루프가 없습니다.')
276
292
  }
277
293
  } else if (subCmd === 'status') {
278
294
  const alive = isTmuxSessionAlive(sessionName)
279
295
  const { readState } = await import('./state.js')
280
296
  const reviewState = readState('review-loop')
281
297
  const respondState = readState('respond-loop')
282
- console.log(`\n tmux 세션 (${sessionName}): ${alive ? '실행 중' : '없음'}`)
283
- console.log(` review-loop: ${reviewState?.status ?? 'unknown'}`)
284
- console.log(` respond-loop: ${respondState?.status ?? 'unknown'}\n`)
298
+ const mode = resolveLoopMode()
299
+ console.log(`\n 모드: ${mode}`)
300
+ console.log(` tmux 세션 (${sessionName}): ${alive ? '실행 중' : '없음'}`)
301
+ console.log(` review-loop: ${reviewState?.status ?? 'unknown'}${reviewState?.pid ? ` (PID: ${reviewState.pid})` : ''}`)
302
+ console.log(` respond-loop: ${respondState?.status ?? 'unknown'}${respondState?.pid ? ` (PID: ${respondState.pid})` : ''}\n`)
285
303
  } else {
286
304
  console.error('사용법: bylane loop <start|stop|status>')
287
305
  process.exit(1)