crewx 0.8.1 → 0.8.2-rc.1

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 (106) hide show
  1. package/README.md +268 -268
  2. package/bin/cli-commands.js +34 -0
  3. package/bin/crewx-lib.js +213 -108
  4. package/bin/crewx-ui.js +83 -83
  5. package/bin/crewx.js +219 -147
  6. package/bin/launcher-flags.js +29 -0
  7. package/bin/package.json +1 -1
  8. package/dist/assets/{MarketPage-Dwsg6K-B.js → MarketPage-njRHlSSN.js} +1 -1
  9. package/dist/assets/{PromptTab-DVKc7hJY.js → PromptTab-CNyClpEe.js} +1 -1
  10. package/dist/assets/{_baseUniq-wjlVo2E6.js → _baseUniq-CGNNUfN7.js} +1 -1
  11. package/dist/assets/{arc-BfPgRtzW.js → arc-BEN-1A69.js} +1 -1
  12. package/dist/assets/{architectureDiagram-Q4EWVU46-ewcueFAG.js → architectureDiagram-Q4EWVU46-fAPvGzXk.js} +1 -1
  13. package/dist/assets/{blockDiagram-DXYQGD6D-TxlbbvKn.js → blockDiagram-DXYQGD6D-BWrb7uua.js} +1 -1
  14. package/dist/assets/{c4Diagram-AHTNJAMY-C1lT_bl_.js → c4Diagram-AHTNJAMY-CbnLz81q.js} +1 -1
  15. package/dist/assets/channel-uEnl63Ym.js +1 -0
  16. package/dist/assets/chatgpt-logo-dark.svg +15 -15
  17. package/dist/assets/chatgpt-logo.svg +15 -15
  18. package/dist/assets/{chunk-4BX2VUAB-C41j2mCL.js → chunk-4BX2VUAB-BopMVv1Q.js} +1 -1
  19. package/dist/assets/{chunk-4TB4RGXK-HNNsUbz0.js → chunk-4TB4RGXK-Axjc-DMR.js} +1 -1
  20. package/dist/assets/{chunk-55IACEB6-qtCgO0r2.js → chunk-55IACEB6-BVzu25a2.js} +1 -1
  21. package/dist/assets/{chunk-EDXVE4YY-BSnDYtsd.js → chunk-EDXVE4YY-Csh0IKkY.js} +1 -1
  22. package/dist/assets/{chunk-FMBD7UC4-DyHRLQqX.js → chunk-FMBD7UC4-D3yW6Ykv.js} +1 -1
  23. package/dist/assets/{chunk-OYMX7WX6-CCjfi6WS.js → chunk-OYMX7WX6-CDzLbKmY.js} +1 -1
  24. package/dist/assets/{chunk-QZHKN3VN-COLty8kd.js → chunk-QZHKN3VN-CqYP7txP.js} +1 -1
  25. package/dist/assets/{chunk-YZCP3GAM-CHUUnGeN.js → chunk-YZCP3GAM-CIz2ApJG.js} +1 -1
  26. package/dist/assets/classDiagram-6PBFFD2Q-CU98S3yn.js +1 -0
  27. package/dist/assets/classDiagram-v2-HSJHXN6E-CU98S3yn.js +1 -0
  28. package/dist/assets/clone-D3Eqsbb8.js +1 -0
  29. package/dist/assets/{cose-bilkent-S5V4N54A-CSip-V2g.js → cose-bilkent-S5V4N54A-DgVG9_nb.js} +1 -1
  30. package/dist/assets/{dagre-KV5264BT-DkdpnWhv.js → dagre-KV5264BT-DnNIMI1A.js} +1 -1
  31. package/dist/assets/{diagram-5BDNPKRD-PH4qc6PV.js → diagram-5BDNPKRD-asGr2q6a.js} +1 -1
  32. package/dist/assets/{diagram-G4DWMVQ6-Cg5xZcjx.js → diagram-G4DWMVQ6-hwyZkwNx.js} +1 -1
  33. package/dist/assets/{diagram-MMDJMWI5-soKmeTCW.js → diagram-MMDJMWI5-BJbIxezj.js} +1 -1
  34. package/dist/assets/{diagram-TYMM5635-Daq5Mihu.js → diagram-TYMM5635-JB2YJBVu.js} +1 -1
  35. package/dist/assets/{erDiagram-SMLLAGMA-kr2OtY0Y.js → erDiagram-SMLLAGMA-i1KkUgG6.js} +1 -1
  36. package/dist/assets/{flowDiagram-DWJPFMVM-DQZCb8gm.js → flowDiagram-DWJPFMVM-62cwXjLB.js} +1 -1
  37. package/dist/assets/{ganttDiagram-T4ZO3ILL-BHkn485T.js → ganttDiagram-T4ZO3ILL-BDhku_zz.js} +1 -1
  38. package/dist/assets/{gitGraphDiagram-UUTBAWPF-FaCyYFmC.js → gitGraphDiagram-UUTBAWPF-DkHe0Kwk.js} +1 -1
  39. package/dist/assets/{graph-BVJlrP6V.js → graph-BnMMHCuQ.js} +1 -1
  40. package/dist/assets/{infoDiagram-42DDH7IO-DJOWkKdM.js → infoDiagram-42DDH7IO-V7zg8GAV.js} +1 -1
  41. package/dist/assets/{ishikawaDiagram-UXIWVN3A-VfpvNaIf.js → ishikawaDiagram-UXIWVN3A-CTtEO2wl.js} +1 -1
  42. package/dist/assets/{journeyDiagram-VCZTEJTY-CPzsak-v.js → journeyDiagram-VCZTEJTY-NxQMTN2m.js} +1 -1
  43. package/dist/assets/{kanban-definition-6JOO6SKY-DFqLDBU0.js → kanban-definition-6JOO6SKY-BHBrmGg3.js} +1 -1
  44. package/dist/assets/{layout-CCSbNPHm.js → layout-DutU1eng.js} +1 -1
  45. package/dist/assets/{linear-C4T7PCKE.js → linear-Czvrvocq.js} +1 -1
  46. package/dist/assets/{main-CELBpK6r.js → main-D0PuDE6-.js} +230 -226
  47. package/dist/assets/{min-CGQNEYGh.js → min-CI38XtLs.js} +1 -1
  48. package/dist/assets/{mindmap-definition-QFDTVHPH-AuU1EqwS.js → mindmap-definition-QFDTVHPH-CbFeHoxp.js} +1 -1
  49. package/dist/assets/{pieDiagram-DEJITSTG-CopkCZwp.js → pieDiagram-DEJITSTG-MV4uB5yA.js} +1 -1
  50. package/dist/assets/{quadrantDiagram-34T5L4WZ-lMKrSv_t.js → quadrantDiagram-34T5L4WZ-D0a8e2mx.js} +1 -1
  51. package/dist/assets/{requirementDiagram-MS252O5E-dWUpHOFb.js → requirementDiagram-MS252O5E-CeTlv4na.js} +1 -1
  52. package/dist/assets/{sankeyDiagram-XADWPNL6-C8UQx9Bb.js → sankeyDiagram-XADWPNL6-D1E3xq9q.js} +1 -1
  53. package/dist/assets/{sequenceDiagram-FGHM5R23-CUVNIItJ.js → sequenceDiagram-FGHM5R23-BO1RXtYs.js} +1 -1
  54. package/dist/assets/{stateDiagram-FHFEXIEX-Ct0GamGl.js → stateDiagram-FHFEXIEX-AhFKkuPE.js} +1 -1
  55. package/dist/assets/stateDiagram-v2-QKLJ7IA2-gv2g1MYi.js +1 -0
  56. package/dist/assets/{timeline-definition-GMOUNBTQ-ul8Po7f7.js → timeline-definition-GMOUNBTQ-BMVxUhID.js} +1 -1
  57. package/dist/assets/{vennDiagram-DHZGUBPP-B4AOWQnP.js → vennDiagram-DHZGUBPP-YFiJZns6.js} +1 -1
  58. package/dist/assets/{wardley-RL74JXVD-Dr7Wp3AJ.js → wardley-RL74JXVD-JlCdJekg.js} +1 -1
  59. package/dist/assets/{wardleyDiagram-NUSXRM2D-Ck70faXX.js → wardleyDiagram-NUSXRM2D-BLn2PZq9.js} +1 -1
  60. package/dist/assets/{xychartDiagram-5P7HB3ND-Bsy5-cNt.js → xychartDiagram-5P7HB3ND-DNOUK9or.js} +1 -1
  61. package/dist/index.html +12 -12
  62. package/dist-electron/main.js +153 -116
  63. package/dist-electron/overlay.js +102 -65
  64. package/dist-electron/package.json +1 -0
  65. package/dist-electron/preload.js +8 -8
  66. package/dist-server/bootstrap/crewx-server.js +19 -10
  67. package/dist-server/repository/box.repository.js +20 -20
  68. package/dist-server/repository/project.repository.js +13 -13
  69. package/dist-server/repository/request-log.repository.js +10 -10
  70. package/dist-server/repository/task.repository.js +72 -72
  71. package/dist-server/repository/thread.repository.js +57 -57
  72. package/package.json +6 -6
  73. package/packages/cli/dist/bootstrap/crewx-cli.js +12 -0
  74. package/packages/cli/dist/commands/agent.js +23 -23
  75. package/packages/cli/dist/commands/init.js +19 -19
  76. package/packages/cli/dist/commands/parse-common-flags.d.ts +19 -3
  77. package/packages/cli/dist/commands/parse-common-flags.js +46 -6
  78. package/packages/cli/dist/commands/registry.d.ts +13 -0
  79. package/packages/cli/dist/commands/registry.js +29 -0
  80. package/packages/cli/dist/commands/task-db.js +7 -7
  81. package/packages/cli/dist/examples/deny-secrets-plugin.d.ts +22 -0
  82. package/packages/cli/dist/examples/deny-secrets-plugin.js +40 -0
  83. package/packages/cli/dist/main.js +134 -68
  84. package/packages/cli/dist/plugins/examples/echo-hook.d.ts +24 -0
  85. package/packages/cli/dist/plugins/examples/echo-hook.js +60 -0
  86. package/packages/cli/dist/plugins/examples/verify-echo-hook.d.ts +8 -0
  87. package/packages/cli/dist/plugins/examples/verify-echo-hook.js +47 -0
  88. package/packages/cli/dist/plugins/sqlite-tracing.d.ts +11 -0
  89. package/packages/cli/dist/plugins/sqlite-tracing.js +19 -0
  90. package/packages/cli/dist/schema/tasks.d.ts +7 -0
  91. package/packages/cli/dist/schema/tasks.js +48 -0
  92. package/packages/cli/package.json +52 -52
  93. package/scripts/build-manual.mjs +266 -266
  94. package/scripts/emit-dist-server-package-json.mjs +7 -7
  95. package/scripts/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  96. package/scripts/postinstall.mjs +44 -44
  97. package/scripts/smoke-tarball.mjs +285 -285
  98. package/scripts/snapshot-msg-list.sh +52 -52
  99. package/server.js +167 -164
  100. package/dist/assets/channel-BP4PNMmz.js +0 -1
  101. package/dist/assets/classDiagram-6PBFFD2Q-Upr3UAcM.js +0 -1
  102. package/dist/assets/classDiagram-v2-HSJHXN6E-Upr3UAcM.js +0 -1
  103. package/dist/assets/clone-B8BP7ReZ.js +0 -1
  104. package/dist/assets/stateDiagram-v2-QKLJ7IA2-CFBLQDEx.js +0 -1
  105. package/dist-server/domain/task/dto/project-usage.dto.js +0 -38
  106. package/dist-server/domain/thread/dto/send-message.dto.js +0 -10
@@ -1,52 +1,52 @@
1
- #!/bin/bash
2
- # MSG.LIST 스냅샷 캡처 스크립트
3
- # 사용법: ./scripts/snapshot-msg-list.sh <threadId> [interval_sec] [logsTail]
4
- #
5
- # 에이전트에게 메시지를 보낸 뒤 이 스크립트를 돌리면
6
- # running → completed 전 과정의 API 응답이 타임스탬프별로 저장됨.
7
-
8
- THREAD_ID="${1:?threadId를 입력하세요}"
9
- INTERVAL="${2:-3}"
10
- LOGS_TAIL="${3:-3}"
11
- BASE_URL="http://localhost:8150/api/v1"
12
-
13
- OUTDIR="snapshots/${THREAD_ID}"
14
- mkdir -p "$OUTDIR"
15
-
16
- SEQ=0
17
- PREV_HASH=""
18
-
19
- echo "📸 MSG.LIST 스냅샷 캡처 시작"
20
- echo " Thread: $THREAD_ID"
21
- echo " Interval: ${INTERVAL}s"
22
- echo " logsTail: $LOGS_TAIL"
23
- echo " 출력: $OUTDIR/"
24
- echo " Ctrl+C로 중지"
25
- echo ""
26
-
27
- while true; do
28
- TIMESTAMP=$(date +%Y%m%d_%H%M%S)
29
- RESPONSE=$(curl -s "${BASE_URL}/threads/${THREAD_ID}/messages?logsTail=${LOGS_TAIL}")
30
-
31
- # 응답이 비어있으면 스킵
32
- if [ -z "$RESPONSE" ]; then
33
- echo "⚠️ [$TIMESTAMP] 빈 응답 — 서버 확인 필요"
34
- sleep "$INTERVAL"
35
- continue
36
- fi
37
-
38
- # 이전 스냅샷과 비교 (중복 제거)
39
- CURR_HASH=$(echo "$RESPONSE" | shasum -a 256 | cut -d' ' -f1)
40
-
41
- if [ "$CURR_HASH" = "$PREV_HASH" ]; then
42
- echo " [$TIMESTAMP] (변화 없음 — 스킵)"
43
- else
44
- SEQ=$((SEQ + 1))
45
- FILENAME=$(printf "%03d_%s.json" "$SEQ" "$TIMESTAMP")
46
- echo "$RESPONSE" | python3 -m json.tool > "${OUTDIR}/${FILENAME}"
47
- echo "✅ [$TIMESTAMP] → ${FILENAME} ($(echo "$RESPONSE" | wc -c | tr -d ' ') bytes)"
48
- PREV_HASH="$CURR_HASH"
49
- fi
50
-
51
- sleep "$INTERVAL"
52
- done
1
+ #!/bin/bash
2
+ # MSG.LIST 스냅샷 캡처 스크립트
3
+ # 사용법: ./scripts/snapshot-msg-list.sh <threadId> [interval_sec] [logsTail]
4
+ #
5
+ # 에이전트에게 메시지를 보낸 뒤 이 스크립트를 돌리면
6
+ # running → completed 전 과정의 API 응답이 타임스탬프별로 저장됨.
7
+
8
+ THREAD_ID="${1:?threadId를 입력하세요}"
9
+ INTERVAL="${2:-3}"
10
+ LOGS_TAIL="${3:-3}"
11
+ BASE_URL="http://localhost:8150/api/v1"
12
+
13
+ OUTDIR="snapshots/${THREAD_ID}"
14
+ mkdir -p "$OUTDIR"
15
+
16
+ SEQ=0
17
+ PREV_HASH=""
18
+
19
+ echo "📸 MSG.LIST 스냅샷 캡처 시작"
20
+ echo " Thread: $THREAD_ID"
21
+ echo " Interval: ${INTERVAL}s"
22
+ echo " logsTail: $LOGS_TAIL"
23
+ echo " 출력: $OUTDIR/"
24
+ echo " Ctrl+C로 중지"
25
+ echo ""
26
+
27
+ while true; do
28
+ TIMESTAMP=$(date +%Y%m%d_%H%M%S)
29
+ RESPONSE=$(curl -s "${BASE_URL}/threads/${THREAD_ID}/messages?logsTail=${LOGS_TAIL}")
30
+
31
+ # 응답이 비어있으면 스킵
32
+ if [ -z "$RESPONSE" ]; then
33
+ echo "⚠️ [$TIMESTAMP] 빈 응답 — 서버 확인 필요"
34
+ sleep "$INTERVAL"
35
+ continue
36
+ fi
37
+
38
+ # 이전 스냅샷과 비교 (중복 제거)
39
+ CURR_HASH=$(echo "$RESPONSE" | shasum -a 256 | cut -d' ' -f1)
40
+
41
+ if [ "$CURR_HASH" = "$PREV_HASH" ]; then
42
+ echo " [$TIMESTAMP] (변화 없음 — 스킵)"
43
+ else
44
+ SEQ=$((SEQ + 1))
45
+ FILENAME=$(printf "%03d_%s.json" "$SEQ" "$TIMESTAMP")
46
+ echo "$RESPONSE" | python3 -m json.tool > "${OUTDIR}/${FILENAME}"
47
+ echo "✅ [$TIMESTAMP] → ${FILENAME} ($(echo "$RESPONSE" | wc -c | tr -d ' ') bytes)"
48
+ PREV_HASH="$CURR_HASH"
49
+ fi
50
+
51
+ sleep "$INTERVAL"
52
+ done
package/server.js CHANGED
@@ -1,164 +1,167 @@
1
- #!/usr/bin/env node
2
- const { spawn } = require('child_process');
3
- const { join } = require('path');
4
- const { mkdtempSync, writeFileSync, chmodSync, rmSync, existsSync } = require('fs');
5
- const { tmpdir, platform } = require('os');
6
-
7
- // Resolve path to the CLI engine (packages/cli/dist/main.js)
8
- const cliMainPath = join(__dirname, 'packages', 'cli', 'dist', 'main.js');
9
-
10
- // --- Shared: CLI proxy setup ---
11
- // Creates a temp proxy script so child processes can resolve `crewx` in PATH
12
- const PROXY_DIR = mkdtempSync(join(tmpdir(), 'crewx-proxy-'));
13
- const nodeBin = process.execPath;
14
- const serverScript = process.argv[1];
15
-
16
- function setupCliProxy() {
17
- if (platform() === 'win32') {
18
- const cmdPath = join(PROXY_DIR, 'crewx.cmd');
19
- writeFileSync(cmdPath, `@echo off\r\n"${nodeBin}" "${serverScript}" cli %*\r\n`);
20
- } else {
21
- const shPath = join(PROXY_DIR, 'crewx');
22
- writeFileSync(shPath, `#!/bin/sh\nexec "${nodeBin}" "${serverScript}" cli "$@"\n`);
23
- chmodSync(shPath, 0o755);
24
- }
25
- }
26
-
27
- function cleanupCliProxy() {
28
- try {
29
- if (existsSync(PROXY_DIR)) {
30
- rmSync(PROXY_DIR, { recursive: true, force: true });
31
- }
32
- } catch {
33
- // Ignore cleanup errors on exit
34
- }
35
- }
36
-
37
- setupCliProxy();
38
- const envPATH = `${PROXY_DIR}${platform() === 'win32' ? ';' : ':'}${process.env.PATH || ''}`;
39
-
40
- // --- CLI Subcommand Mode ---
41
- // When invoked as `crewx cli <args...>`, forward to packages/cli directly
42
- const args = process.argv.slice(2);
43
- if (args[0] === 'cli') {
44
- const cliArgs = args.slice(1);
45
- const child = spawn(process.execPath, [cliMainPath, ...cliArgs], {
46
- stdio: 'inherit',
47
- env: { ...process.env, PATH: envPATH },
48
- });
49
- child.on('exit', (code) => { cleanupCliProxy(); process.exit(code || 0); });
50
- child.on('error', (err) => {
51
- console.error('Failed to run CLI:', err);
52
- cleanupCliProxy();
53
- process.exit(1);
54
- });
55
- process.on('exit', () => cleanupCliProxy());
56
- } else {
57
- // --- Normal server mode ---
58
-
59
- const PORT = process.env.PORT || 8150;
60
- const OPEN_CMD = platform() === 'darwin' ? 'open' : platform() === 'win32' ? 'start' : 'xdg-open';
61
-
62
- // Graceful shutdown handler
63
- let server;
64
- function shutdown(signal) {
65
- console.log(`\nReceived ${signal}, shutting down gracefully...`);
66
- if (server && !server.killed) {
67
- server.kill('SIGTERM');
68
- }
69
- cleanupCliProxy();
70
- // Give server time to cleanup, then force exit
71
- setTimeout(() => {
72
- process.exit(0);
73
- }, 1000);
74
- }
75
-
76
- // Start NestJS server with proxy PATH injected
77
- // tsc outputs to dist-server/ (rootDir: src/server in tsconfig.server.json)
78
- const distServerPath = join(__dirname, 'dist-server', 'main.js');
79
- const devServerPath = join(__dirname, 'src', 'server', 'main.ts');
80
- const serverEnv = {
81
- ...process.env,
82
- PORT: String(PORT),
83
- SERVE_STATIC: 'true',
84
- PATH: envPATH,
85
- };
86
-
87
- if (existsSync(distServerPath)) {
88
- server = spawn('node', [distServerPath], {
89
- env: serverEnv,
90
- stdio: ['ignore', 'pipe', 'inherit'],
91
- });
92
- } else if (existsSync(devServerPath)) {
93
- // NestJS requires emitDecoratorMetadata for DI — tsx (esbuild) doesn't emit it.
94
- // Use `nest start` which respects tsconfig and emits decorator metadata correctly.
95
- // --watch intentionally omitted: nest's internal restart triggers server.on('exit')
96
- // handler (line ~124), terminating the whole process. Use `npm run dev:server` for watch.
97
- const nestBin = join(__dirname, 'node_modules', '.bin', 'nest');
98
- if (existsSync(nestBin)) {
99
- server = spawn(nestBin, ['start'], {
100
- env: serverEnv,
101
- stdio: ['ignore', 'pipe', 'inherit'],
102
- });
103
- } else {
104
- console.error('❌ NestJS CLI not found. Run `npm install` first.');
105
- cleanupCliProxy();
106
- process.exit(1);
107
- }
108
- } else {
109
- console.error('❌ Server not found. Run `npm run build:server` first.');
110
- cleanupCliProxy();
111
- process.exit(1);
112
- }
113
-
114
- // Open browser when server is ready (detect startup message from stdout).
115
- // Fallback: open after 30s if no ready message detected.
116
- let browserOpened = false;
117
- const READY_PATTERNS = [/running on/i, /Nest application successfully started/i, /listening on/i];
118
-
119
- function openBrowser() {
120
- if (browserOpened) return;
121
- browserOpened = true;
122
- clearTimeout(fallbackTimer);
123
- const url = `http://localhost:${PORT}`;
124
- console.log(`Opening browser: ${url}`);
125
- spawn(OPEN_CMD, [url], { shell: true });
126
- }
127
-
128
- const fallbackTimer = setTimeout(() => {
129
- openBrowser();
130
- }, 30_000);
131
-
132
- if (server.stdout) {
133
- server.stdout.on('data', (chunk) => {
134
- process.stdout.write(chunk);
135
- if (!browserOpened) {
136
- const text = chunk.toString();
137
- if (READY_PATTERNS.some((re) => re.test(text))) {
138
- openBrowser();
139
- }
140
- }
141
- });
142
- }
143
-
144
- server.on('error', (err) => {
145
- console.error('Failed to start server:', err);
146
- cleanupCliProxy();
147
- process.exit(1);
148
- });
149
-
150
- server.on('exit', (code, signal) => {
151
- if (signal) {
152
- console.log(`Server exited with signal ${signal}`);
153
- } else if (code !== 0) {
154
- console.log(`Server exited with code ${code}`);
155
- }
156
- cleanupCliProxy();
157
- process.exit(code || 0);
158
- });
159
-
160
- // Handle signals
161
- process.on('SIGINT', () => shutdown('SIGINT'));
162
- process.on('SIGTERM', () => shutdown('SIGTERM'));
163
- process.on('exit', () => cleanupCliProxy());
164
- }
1
+ #!/usr/bin/env node
2
+ const { spawn } = require('child_process');
3
+ const { join } = require('path');
4
+ const { mkdtempSync, writeFileSync, chmodSync, rmSync, existsSync } = require('fs');
5
+ const { tmpdir, platform } = require('os');
6
+
7
+ // Resolve path to the CLI engine (packages/cli/dist/main.js)
8
+ const cliMainPath = join(__dirname, 'packages', 'cli', 'dist', 'main.js');
9
+
10
+ // --- Shared: CLI proxy setup ---
11
+ // Creates a temp proxy script so child processes can resolve `crewx` in PATH
12
+ const PROXY_DIR = mkdtempSync(join(tmpdir(), 'crewx-proxy-'));
13
+ const nodeBin = process.execPath;
14
+ const serverScript = process.argv[1];
15
+
16
+ function setupCliProxy() {
17
+ if (platform() === 'win32') {
18
+ const cmdPath = join(PROXY_DIR, 'crewx.cmd');
19
+ writeFileSync(cmdPath, `@echo off\r\n"${nodeBin}" "${serverScript}" cli %*\r\n`);
20
+ } else {
21
+ const shPath = join(PROXY_DIR, 'crewx');
22
+ writeFileSync(shPath, `#!/bin/sh\nexec "${nodeBin}" "${serverScript}" cli "$@"\n`);
23
+ chmodSync(shPath, 0o755);
24
+ }
25
+ }
26
+
27
+ function cleanupCliProxy() {
28
+ try {
29
+ if (existsSync(PROXY_DIR)) {
30
+ rmSync(PROXY_DIR, { recursive: true, force: true });
31
+ }
32
+ } catch {
33
+ // Ignore cleanup errors on exit
34
+ }
35
+ }
36
+
37
+ setupCliProxy();
38
+ const envPATH = `${PROXY_DIR}${platform() === 'win32' ? ';' : ':'}${process.env.PATH || ''}`;
39
+
40
+ // --- CLI Subcommand Mode ---
41
+ // When invoked as `crewx cli <args...>`, forward to packages/cli directly
42
+ const args = process.argv.slice(2);
43
+ if (args[0] === 'cli') {
44
+ const cliArgs = args.slice(1);
45
+ const child = spawn(process.execPath, [cliMainPath, ...cliArgs], {
46
+ stdio: 'inherit',
47
+ env: { ...process.env, PATH: envPATH },
48
+ });
49
+ child.on('exit', (code) => { cleanupCliProxy(); process.exit(code || 0); });
50
+ child.on('error', (err) => {
51
+ console.error('Failed to run CLI:', err);
52
+ cleanupCliProxy();
53
+ process.exit(1);
54
+ });
55
+ process.on('exit', () => cleanupCliProxy());
56
+ } else {
57
+ // --- Normal server mode ---
58
+
59
+ const PORT = process.env.PORT || 8150;
60
+ const OPEN_CMD = platform() === 'darwin' ? 'open' : platform() === 'win32' ? 'start' : 'xdg-open';
61
+
62
+ // Graceful shutdown handler
63
+ let server;
64
+ function shutdown(signal) {
65
+ console.log(`\nReceived ${signal}, shutting down gracefully...`);
66
+ if (server && !server.killed) {
67
+ server.kill('SIGTERM');
68
+ }
69
+ cleanupCliProxy();
70
+ // Give server time to cleanup, then force exit
71
+ setTimeout(() => {
72
+ process.exit(0);
73
+ }, 1000);
74
+ }
75
+
76
+ // Start NestJS server with proxy PATH injected
77
+ // tsc outputs to dist-server/ (rootDir: src/server in tsconfig.server.json)
78
+ const distServerPath = join(__dirname, 'dist-server', 'main.js');
79
+ const devServerPath = join(__dirname, 'src', 'server', 'main.ts');
80
+ const serverEnv = {
81
+ ...process.env,
82
+ PORT: String(PORT),
83
+ SERVE_STATIC: 'true',
84
+ PATH: envPATH,
85
+ };
86
+
87
+ if (existsSync(distServerPath)) {
88
+ server = spawn('node', [distServerPath], {
89
+ env: serverEnv,
90
+ stdio: ['ignore', 'pipe', 'inherit'],
91
+ });
92
+ } else if (existsSync(devServerPath)) {
93
+ // NestJS requires emitDecoratorMetadata for DI — tsx (esbuild) doesn't emit it.
94
+ // Use `nest start` which respects tsconfig and emits decorator metadata correctly.
95
+ // --watch intentionally omitted: nest's internal restart triggers server.on('exit')
96
+ // handler (line ~124), terminating the whole process. Use `npm run dev:server` for watch.
97
+ const nestBin = join(__dirname, 'node_modules', '.bin', 'nest');
98
+ if (existsSync(nestBin)) {
99
+ server = spawn(nestBin, ['start'], {
100
+ env: serverEnv,
101
+ stdio: ['ignore', 'pipe', 'inherit'],
102
+ });
103
+ } else {
104
+ console.error('❌ NestJS CLI not found. Run `npm install` first.');
105
+ cleanupCliProxy();
106
+ process.exit(1);
107
+ }
108
+ } else {
109
+ console.error('❌ Server not found. Run `npm run build:server` first.');
110
+ cleanupCliProxy();
111
+ process.exit(1);
112
+ }
113
+
114
+ // Open browser only when explicitly requested via CREWX_OPEN_BROWSER=1.
115
+ // bin/crewx.js sets this env only for the default `crewx` (no-args) route;
116
+ // `crewx serve [--no-open]` never sets it, so the browser stays closed.
117
+ const shouldOpenBrowser = process.env.CREWX_OPEN_BROWSER === '1';
118
+ let browserOpened = false;
119
+ let fallbackTimer;
120
+ const READY_PATTERNS = [/running on/i, /Nest application successfully started/i, /listening on/i];
121
+
122
+ function openBrowser() {
123
+ if (browserOpened) return;
124
+ browserOpened = true;
125
+ if (fallbackTimer) clearTimeout(fallbackTimer);
126
+ const url = `http://localhost:${PORT}`;
127
+ console.log(`Opening browser: ${url}`);
128
+ spawn(OPEN_CMD, [url], { shell: true });
129
+ }
130
+
131
+ if (shouldOpenBrowser) {
132
+ fallbackTimer = setTimeout(openBrowser, 30_000);
133
+ }
134
+
135
+ if (server.stdout) {
136
+ server.stdout.on('data', (chunk) => {
137
+ process.stdout.write(chunk);
138
+ if (shouldOpenBrowser && !browserOpened) {
139
+ const text = chunk.toString();
140
+ if (READY_PATTERNS.some((re) => re.test(text))) {
141
+ openBrowser();
142
+ }
143
+ }
144
+ });
145
+ }
146
+
147
+ server.on('error', (err) => {
148
+ console.error('Failed to start server:', err);
149
+ cleanupCliProxy();
150
+ process.exit(1);
151
+ });
152
+
153
+ server.on('exit', (code, signal) => {
154
+ if (signal) {
155
+ console.log(`Server exited with signal ${signal}`);
156
+ } else if (code !== 0) {
157
+ console.log(`Server exited with code ${code}`);
158
+ }
159
+ cleanupCliProxy();
160
+ process.exit(code || 0);
161
+ });
162
+
163
+ // Handle signals
164
+ process.on('SIGINT', () => shutdown('SIGINT'));
165
+ process.on('SIGTERM', () => shutdown('SIGTERM'));
166
+ process.on('exit', () => cleanupCliProxy());
167
+ }
@@ -1 +0,0 @@
1
- import{aq as o,ar as n}from"./main-CELBpK6r.js";const t=(r,a)=>o.lang.round(n.parse(r)[a]);export{t as c};
@@ -1 +0,0 @@
1
- import{s as a,c as s,a as e,C as t}from"./chunk-4TB4RGXK-HNNsUbz0.js";import{_ as i}from"./main-CELBpK6r.js";import"./chunk-FMBD7UC4-DyHRLQqX.js";import"./chunk-YZCP3GAM-CHUUnGeN.js";import"./chunk-55IACEB6-qtCgO0r2.js";import"./chunk-EDXVE4YY-BSnDYtsd.js";var u={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{u as diagram};
@@ -1 +0,0 @@
1
- import{s as a,c as s,a as e,C as t}from"./chunk-4TB4RGXK-HNNsUbz0.js";import{_ as i}from"./main-CELBpK6r.js";import"./chunk-FMBD7UC4-DyHRLQqX.js";import"./chunk-YZCP3GAM-CHUUnGeN.js";import"./chunk-55IACEB6-qtCgO0r2.js";import"./chunk-EDXVE4YY-BSnDYtsd.js";var u={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{u as diagram};
@@ -1 +0,0 @@
1
- import{b as r}from"./graph-BVJlrP6V.js";var e=4;function a(o){return r(o,e)}export{a as c};
@@ -1 +0,0 @@
1
- import{s as t,b as r,a,S as s}from"./chunk-OYMX7WX6-CCjfi6WS.js";import{_ as i}from"./main-CELBpK6r.js";import"./chunk-55IACEB6-qtCgO0r2.js";import"./chunk-EDXVE4YY-BSnDYtsd.js";var l={parser:a,get db(){return new s(2)},renderer:r,styles:t,init:i(e=>{e.state||(e.state={}),e.state.arrowMarkerAbsolute=e.arrowMarkerAbsolute},"init")};export{l as diagram};
@@ -1,38 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ProjectUsageSummaryResponseDto = exports.ProjectUsageDto = void 0;
4
- /**
5
- * Phase 5: Per-project usage aggregation DTO.
6
- *
7
- * Returned by GET /tasks/project-usage (getProjectUsageSummary).
8
- * Each entry represents one project's cumulative usage across all tasks
9
- * stored in the centralised traces.db.
10
- *
11
- * Security: project_id is the first 16 hex chars of SHA-256(projectPath).
12
- * The raw path is NEVER exposed.
13
- */
14
- class ProjectUsageDto {
15
- /** Opaque 16-char hex identifier (SHA-256[:16] of the project's absolute path) */
16
- project_id;
17
- /** Human-readable display name (basename of project dir or git remote name) */
18
- project_name;
19
- /** Total input tokens across all tasks in this project */
20
- input_tokens;
21
- /** Total output tokens across all tasks in this project */
22
- output_tokens;
23
- /** Total cost in USD across all tasks in this project */
24
- cost_usd;
25
- /** Number of tasks recorded for this project */
26
- task_count;
27
- }
28
- exports.ProjectUsageDto = ProjectUsageDto;
29
- /**
30
- * Response wrapper for the project usage summary endpoint.
31
- */
32
- class ProjectUsageSummaryResponseDto {
33
- /** Per-project breakdown, sorted by cost_usd descending */
34
- projects;
35
- /** Grand totals across all projects (for the global tier calculation) */
36
- totals;
37
- }
38
- exports.ProjectUsageSummaryResponseDto = ProjectUsageSummaryResponseDto;
@@ -1,10 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SendMessageDto = void 0;
4
- // THD004: Body for sending a message to a thread
5
- class SendMessageDto {
6
- message;
7
- agent;
8
- title; // optional thread title (used on first message)
9
- }
10
- exports.SendMessageDto = SendMessageDto;