commandmate 0.1.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 (44) hide show
  1. package/.env.example +64 -0
  2. package/LICENSE +21 -0
  3. package/README.md +148 -0
  4. package/bin/commandmate.js +7 -0
  5. package/dist/cli/commands/init.d.ts +11 -0
  6. package/dist/cli/commands/init.d.ts.map +1 -0
  7. package/dist/cli/commands/init.js +126 -0
  8. package/dist/cli/commands/start.d.ts +11 -0
  9. package/dist/cli/commands/start.d.ts.map +1 -0
  10. package/dist/cli/commands/start.js +117 -0
  11. package/dist/cli/commands/status.d.ts +10 -0
  12. package/dist/cli/commands/status.d.ts.map +1 -0
  13. package/dist/cli/commands/status.js +55 -0
  14. package/dist/cli/commands/stop.d.ts +11 -0
  15. package/dist/cli/commands/stop.d.ts.map +1 -0
  16. package/dist/cli/commands/stop.js +82 -0
  17. package/dist/cli/config/cli-dependencies.d.ts +23 -0
  18. package/dist/cli/config/cli-dependencies.d.ts.map +1 -0
  19. package/dist/cli/config/cli-dependencies.js +65 -0
  20. package/dist/cli/index.d.ts +6 -0
  21. package/dist/cli/index.d.ts.map +1 -0
  22. package/dist/cli/index.js +64 -0
  23. package/dist/cli/types/index.d.ts +124 -0
  24. package/dist/cli/types/index.d.ts.map +1 -0
  25. package/dist/cli/types/index.js +20 -0
  26. package/dist/cli/utils/daemon.d.ts +39 -0
  27. package/dist/cli/utils/daemon.d.ts.map +1 -0
  28. package/dist/cli/utils/daemon.js +141 -0
  29. package/dist/cli/utils/env-setup.d.ts +62 -0
  30. package/dist/cli/utils/env-setup.d.ts.map +1 -0
  31. package/dist/cli/utils/env-setup.js +157 -0
  32. package/dist/cli/utils/logger.d.ts +48 -0
  33. package/dist/cli/utils/logger.d.ts.map +1 -0
  34. package/dist/cli/utils/logger.js +99 -0
  35. package/dist/cli/utils/pid-manager.d.ts +42 -0
  36. package/dist/cli/utils/pid-manager.d.ts.map +1 -0
  37. package/dist/cli/utils/pid-manager.js +111 -0
  38. package/dist/cli/utils/preflight.d.ts +34 -0
  39. package/dist/cli/utils/preflight.d.ts.map +1 -0
  40. package/dist/cli/utils/preflight.js +129 -0
  41. package/dist/cli/utils/security-logger.d.ts +29 -0
  42. package/dist/cli/utils/security-logger.d.ts.map +1 -0
  43. package/dist/cli/utils/security-logger.js +53 -0
  44. package/package.json +78 -0
package/.env.example ADDED
@@ -0,0 +1,64 @@
1
+ # CommandMate Environment Configuration
2
+ # Copy this file to .env and fill in your values
3
+
4
+ # ===================================
5
+ # Server Configuration
6
+ # ===================================
7
+
8
+ # Root directory for worktree scanning
9
+ # This is the base directory that contains your git worktrees
10
+ CM_ROOT_DIR=/path/to/your/worktrees
11
+
12
+ # Server port (default: 3000)
13
+ CM_PORT=3000
14
+
15
+ # Bind address
16
+ # - 127.0.0.1: Localhost only (development, no auth required)
17
+ # - 0.0.0.0: All interfaces (production, auth required)
18
+ CM_BIND=127.0.0.1
19
+
20
+ # ===================================
21
+ # Security
22
+ # ===================================
23
+
24
+ # Authentication token for API access
25
+ # Required when CM_BIND=0.0.0.0
26
+ # Optional when CM_BIND=127.0.0.1
27
+ # Generate a secure random token:
28
+ # openssl rand -hex 32
29
+ CM_AUTH_TOKEN=your-secret-token-here
30
+
31
+ # ===================================
32
+ # Database
33
+ # ===================================
34
+
35
+ # SQLite database file path (default: ./data/db.sqlite)
36
+ CM_DB_PATH=./data/db.sqlite
37
+ # Legacy: DATABASE_PATH is also supported
38
+ # DATABASE_PATH=./data/db.sqlite
39
+
40
+ # ===================================
41
+ # Logging
42
+ # ===================================
43
+
44
+ # Log level: debug | info | warn | error
45
+ # Development default: debug
46
+ # Production default: info
47
+ CM_LOG_LEVEL=debug
48
+
49
+ # Log output format: json | text
50
+ # json: Structured logs (production, log analysis tools)
51
+ # text: Human-readable format (development)
52
+ CM_LOG_FORMAT=text
53
+
54
+ # ===================================
55
+ # Legacy Environment Variables (Deprecated)
56
+ # The following MCBD_* variables are deprecated and will be removed in a future version.
57
+ # Use CM_* variables instead. Fallback is supported for backwards compatibility.
58
+ # ===================================
59
+ # MCBD_ROOT_DIR=/path/to/your/worktrees
60
+ # MCBD_PORT=3000
61
+ # MCBD_BIND=127.0.0.1
62
+ # MCBD_AUTH_TOKEN=your-secret-token-here
63
+ # MCBD_LOG_LEVEL=debug
64
+ # MCBD_LOG_FORMAT=text
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Kewton
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,148 @@
1
+ # CommandMate
2
+
3
+ > 「入力待ちを見逃さない、開発の相棒。」
4
+ > 「軽量。その場で完結。Claude Codeを、どこからでも動かす。」
5
+
6
+ ![PC表示](./docs/images/screenshot-desktop.png)
7
+
8
+ ## これは何か
9
+
10
+ Git worktree ごとに Claude Code セッションを管理し、ブラウザから指示を送れる開発コンパニオンツールです。
11
+
12
+ 通勤中・育児中・昼休み――メールに返信する感覚で「次の指示」を出し、個人開発を前に進められます。
13
+
14
+ ## 何ではないか
15
+
16
+ - ターミナルの代替ではありません。Claude Code を**補完**するツールです
17
+ - CLI の全機能を再現するものではなく、「入力待ち/未確認を見逃さず、すぐ指示を出す」ことに特化しています
18
+
19
+ ## 想定ユーザー
20
+
21
+ Claude Code での開発経験があり、本業の傍らで個人開発を続けたい方。
22
+
23
+ ## 主な機能
24
+
25
+ - **入力待ち/未確認検知** — サイドバーでリアルタイムにステータス表示(idle/ready/running/waiting)
26
+ - **ブラウザから指示送信** — スマホ・PCどちらからでもメッセージUIで操作
27
+ - **実行履歴・メモ** — ブランチごとの会話履歴を保持、メモ機能付き
28
+ - **Markdownログビューア** — Claude の詳細出力をMarkdownで閲覧
29
+ - **ファイルビュー** — ワークツリー内のファイルをブラウザから確認
30
+ - **Auto Yes モード** — 確認ダイアログ付きで自動承認を制御
31
+ - **リポジトリ削除** — 不要になったリポジトリをアプリ管理から解除(実ファイルは削除しません)
32
+ - **クローンURL登録** — HTTPS/SSH URLを指定してリポジトリをクローン・登録
33
+ - **Claude Code 特化** — Claude Code セッションの管理に最適化
34
+ - **レスポンシブUI** — デスクトップは2カラム、モバイルはタブベースで最適表示
35
+
36
+ ### ワークツリー詳細画面(Message / Console / History)
37
+
38
+ | PC表示 | スマホ(History) | スマホ(Terminal) |
39
+ |--------|-------------------|-------------------|
40
+ | ![PC - ワークツリー詳細](./docs/images/screenshot-worktree-desktop.png) | ![スマホ - History](./docs/images/screenshot-worktree-mobile.png) | ![スマホ - Terminal](./docs/images/screenshot-worktree-mobile-terminal.png) |
41
+
42
+ ### トップ画面(スマホ)
43
+
44
+ ![スマホ表示](./docs/images/screenshot-mobile.png)
45
+
46
+ ## Quick Start
47
+
48
+ ### 前提条件
49
+
50
+ - macOS / Linux(tmux 依存のため Windows は非対応)
51
+ - Node.js v20+、npm、git、tmux、openssl
52
+ - Claude CLI(CLAUDE_HOOKS_STOP 対応)
53
+
54
+ ### CLIコマンドによるセットアップ(推奨)
55
+
56
+ ```bash
57
+ # グローバルインストール
58
+ npm install -g commandmate
59
+
60
+ # 初期化(依存関係チェック、.env作成、DB初期化)
61
+ commandmate init
62
+
63
+ # サーバー起動
64
+ commandmate start
65
+ ```
66
+
67
+ ブラウザで http://localhost:3000 にアクセスしてください。
68
+
69
+ #### CLIコマンド一覧
70
+
71
+ | コマンド | 説明 |
72
+ |---------|------|
73
+ | `commandmate --version` | バージョン表示 |
74
+ | `commandmate init` | 初期化(対話形式で設定) |
75
+ | `commandmate init --defaults` | デフォルト値で初期化(非対話) |
76
+ | `commandmate start` | サーバー起動(フォアグラウンド) |
77
+ | `commandmate start --dev` | 開発モードで起動 |
78
+ | `commandmate start --daemon` | バックグラウンドで起動 |
79
+ | `commandmate stop` | サーバー停止 |
80
+ | `commandmate status` | サーバー状態確認 |
81
+
82
+ ### シェルスクリプトによるセットアップ(レガシー)
83
+
84
+ > **Note**: シェルスクリプトは非推奨です。CLIコマンドの使用を推奨します。
85
+
86
+ ```bash
87
+ git clone https://github.com/Kewton/CommandMate.git
88
+ cd CommandMate
89
+ ./scripts/setup.sh # 依存チェック、環境設定、ビルド、起動まで自動実行
90
+ ```
91
+
92
+ ### 手動セットアップ(カスタマイズしたい場合)
93
+
94
+ ```bash
95
+ git clone https://github.com/Kewton/CommandMate.git
96
+ cd CommandMate
97
+ ./scripts/preflight-check.sh # 依存チェック
98
+ npm install
99
+ ./scripts/setup-env.sh # 対話式で .env を生成
100
+ npm run db:init
101
+ npm run build
102
+ npm start
103
+ ```
104
+
105
+ スマホから利用する場合は `commandmate init` または `./scripts/setup-env.sh` で外部アクセスを有効にすると、`CM_BIND=0.0.0.0` と `CM_AUTH_TOKEN` が自動設定されます。同一LAN内から `http://<PCのIP>:3000` にアクセスします。
106
+
107
+ > **Note**: 旧名称の環境変数(`MCBD_*`)も後方互換性のためサポートされていますが、新名称(`CM_*`)の使用を推奨します。
108
+
109
+ ## FAQ
110
+
111
+ **Q: どこまでローカルで動く?**
112
+ A: アプリ本体・DB・セッションはすべてローカルで完結します。外部通信は Claude CLI 自体の API 呼び出しのみです。
113
+
114
+ **Q: 外出先からスマホでアクセスするには?**
115
+ A: Cloudflare Tunnel などのトンネリングサービスを活用することで利用できます。室内であればローカル PC と同じ Wi-Fi に接続するだけでスマホから利用可能です。
116
+
117
+ **Q: Claude Code の権限はどうなる?**
118
+ A: Claude Code 自体の権限設定がそのまま適用されます。本ツールが権限を拡張することはありません。詳しくは [Trust & Safety](./docs/TRUST_AND_SAFETY.md) を参照してください。
119
+
120
+ **Q: Windows で使える?**
121
+ A: 現時点では非対応です。tmux に依存しているため macOS / Linux が必要です。WSL2 上での動作は未検証です。
122
+
123
+ **Q: Claude Code 以外の CLI ツールに対応している?**
124
+ A: 現時点では Claude Code のみ対応しています。
125
+
126
+ **Q: 複数人で使える?**
127
+ A: 現時点では個人利用を想定しています。複数人での同時利用は未対応です。
128
+
129
+ ## ドキュメント
130
+
131
+ | ドキュメント | 説明 |
132
+ |-------------|------|
133
+ | [コンセプト](./docs/concept.md) | ビジョンと解決する課題 |
134
+ | [アーキテクチャ](./docs/architecture.md) | システム設計 |
135
+ | [デプロイガイド](./docs/DEPLOYMENT.md) | 本番環境構築手順 |
136
+ | [移行ガイド](./docs/migration-to-commandmate.md) | MyCodeBranchDesk からの移行手順 |
137
+ | [UI/UXガイド](./docs/UI_UX_GUIDE.md) | UI実装の詳細 |
138
+ | [Webアプリ操作ガイド](./docs/user-guide/webapp-guide.md) | Webアプリの基本操作 |
139
+ | [クイックスタート](./docs/user-guide/quick-start.md) | Claude Codeコマンドの使い方 |
140
+ | [Trust & Safety](./docs/TRUST_AND_SAFETY.md) | セキュリティと権限の考え方 |
141
+
142
+ ## Contributing
143
+
144
+ バグ報告・機能提案・ドキュメント改善を歓迎します。詳しくは [CONTRIBUTING.md](./CONTRIBUTING.md) を参照してください。
145
+
146
+ ## License
147
+
148
+ [MIT License](./LICENSE) - Copyright (c) 2026 Kewton
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CommandMate CLI Entry Point
4
+ * Issue #96: npm install CLI support
5
+ */
6
+
7
+ require('../dist/cli/index.js');
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Init Command
3
+ * Issue #96: npm install CLI support
4
+ * Initialize CommandMate configuration
5
+ */
6
+ import { InitOptions } from '../types';
7
+ /**
8
+ * Execute init command
9
+ */
10
+ export declare function initCommand(options: InitOptions): Promise<void>;
11
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,WAAW,EAAuB,MAAM,UAAU,CAAC;AAQ5D;;GAEG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA0HrE"}
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ /**
3
+ * Init Command
4
+ * Issue #96: npm install CLI support
5
+ * Initialize CommandMate configuration
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.initCommand = initCommand;
9
+ const path_1 = require("path");
10
+ const os_1 = require("os");
11
+ const types_1 = require("../types");
12
+ const logger_1 = require("../utils/logger");
13
+ const preflight_1 = require("../utils/preflight");
14
+ const env_setup_1 = require("../utils/env-setup");
15
+ const security_logger_1 = require("../utils/security-logger");
16
+ const logger = new logger_1.CLILogger();
17
+ /**
18
+ * Execute init command
19
+ */
20
+ async function initCommand(options) {
21
+ try {
22
+ logger.header('CommandMate Init');
23
+ logger.blank();
24
+ // Step 1: Preflight checks
25
+ logger.info('Checking system dependencies...');
26
+ const preflightChecker = new preflight_1.PreflightChecker();
27
+ const preflightResult = await preflightChecker.checkAll();
28
+ // Display results
29
+ for (const result of preflightResult.results) {
30
+ if (result.status === 'ok') {
31
+ logger.success(`${result.name}: ${result.version || 'OK'}`);
32
+ }
33
+ else if (result.status === 'missing') {
34
+ logger.error(`${result.name}: Not found`);
35
+ logger.info(` ${preflight_1.PreflightChecker.getInstallHint(result.name)}`);
36
+ }
37
+ else if (result.status === 'version_mismatch') {
38
+ logger.warn(`${result.name}: ${result.version} (minimum required version not met)`);
39
+ }
40
+ }
41
+ if (!preflightResult.success) {
42
+ logger.blank();
43
+ logger.error('Required dependencies are missing. Please install them and try again.');
44
+ (0, security_logger_1.logSecurityEvent)({
45
+ timestamp: new Date().toISOString(),
46
+ command: 'init',
47
+ action: 'failure',
48
+ details: 'Preflight check failed',
49
+ });
50
+ process.exit(types_1.ExitCode.DEPENDENCY_ERROR);
51
+ return;
52
+ }
53
+ logger.blank();
54
+ logger.success('All required dependencies found');
55
+ logger.blank();
56
+ // Step 2: Setup environment
57
+ const envSetup = new env_setup_1.EnvSetup();
58
+ // Create configuration
59
+ const config = {
60
+ CM_ROOT_DIR: options.defaults
61
+ ? (0, path_1.join)((0, os_1.homedir)(), 'repos')
62
+ : (0, env_setup_1.sanitizePath)(process.env.CM_ROOT_DIR || (0, path_1.join)((0, os_1.homedir)(), 'repos')),
63
+ CM_PORT: env_setup_1.ENV_DEFAULTS.CM_PORT,
64
+ CM_BIND: env_setup_1.ENV_DEFAULTS.CM_BIND,
65
+ CM_DB_PATH: env_setup_1.ENV_DEFAULTS.CM_DB_PATH,
66
+ CM_LOG_LEVEL: env_setup_1.ENV_DEFAULTS.CM_LOG_LEVEL,
67
+ CM_LOG_FORMAT: env_setup_1.ENV_DEFAULTS.CM_LOG_FORMAT,
68
+ };
69
+ // Validate configuration
70
+ const validationResult = envSetup.validateConfig(config);
71
+ if (!validationResult.valid) {
72
+ logger.error('Configuration validation failed:');
73
+ for (const error of validationResult.errors) {
74
+ logger.error(` - ${error}`);
75
+ }
76
+ (0, security_logger_1.logSecurityEvent)({
77
+ timestamp: new Date().toISOString(),
78
+ command: 'init',
79
+ action: 'failure',
80
+ details: `Validation failed: ${validationResult.errors.join(', ')}`,
81
+ });
82
+ process.exit(types_1.ExitCode.CONFIG_ERROR);
83
+ return;
84
+ }
85
+ // Backup existing .env if force mode
86
+ if (options.force) {
87
+ const backupPath = await envSetup.backupExisting();
88
+ if (backupPath) {
89
+ logger.info(`Backed up existing .env to ${backupPath}`);
90
+ }
91
+ }
92
+ // Create .env file
93
+ logger.info('Creating .env file...');
94
+ await envSetup.createEnvFile(config, { force: options.force });
95
+ logger.success('.env file created');
96
+ // Step 3: Initialize database
97
+ logger.info('Initializing database...');
98
+ // Note: Database initialization is handled by the server on startup
99
+ logger.success('Database will be initialized on first server start');
100
+ logger.blank();
101
+ logger.success('CommandMate initialized successfully!');
102
+ logger.blank();
103
+ logger.info('Next steps:');
104
+ logger.info(' 1. Edit .env to customize your configuration');
105
+ logger.info(' 2. Run "commandmate start" to start the server');
106
+ logger.blank();
107
+ (0, security_logger_1.logSecurityEvent)({
108
+ timestamp: new Date().toISOString(),
109
+ command: 'init',
110
+ action: 'success',
111
+ details: 'Configuration initialized',
112
+ });
113
+ process.exit(types_1.ExitCode.SUCCESS);
114
+ }
115
+ catch (error) {
116
+ const message = error instanceof Error ? error.message : String(error);
117
+ logger.error(`Initialization failed: ${message}`);
118
+ (0, security_logger_1.logSecurityEvent)({
119
+ timestamp: new Date().toISOString(),
120
+ command: 'init',
121
+ action: 'failure',
122
+ details: message,
123
+ });
124
+ process.exit(types_1.ExitCode.UNEXPECTED_ERROR);
125
+ }
126
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Start Command
3
+ * Issue #96: npm install CLI support
4
+ * Start CommandMate server
5
+ */
6
+ import { StartOptions } from '../types';
7
+ /**
8
+ * Execute start command
9
+ */
10
+ export declare function startCommand(options: StartOptions): Promise<void>;
11
+ //# sourceMappingURL=start.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/start.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,YAAY,EAAY,MAAM,UAAU,CAAC;AAQlD;;GAEG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAoHvE"}
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ /**
3
+ * Start Command
4
+ * Issue #96: npm install CLI support
5
+ * Start CommandMate server
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.startCommand = startCommand;
9
+ const fs_1 = require("fs");
10
+ const child_process_1 = require("child_process");
11
+ const path_1 = require("path");
12
+ const types_1 = require("../types");
13
+ const logger_1 = require("../utils/logger");
14
+ const daemon_1 = require("../utils/daemon");
15
+ const security_logger_1 = require("../utils/security-logger");
16
+ const logger = new logger_1.CLILogger();
17
+ const PID_FILE = (0, path_1.join)(process.cwd(), '.commandmate.pid');
18
+ /**
19
+ * Execute start command
20
+ */
21
+ async function startCommand(options) {
22
+ try {
23
+ // Check for .env file
24
+ const envPath = (0, path_1.join)(process.cwd(), '.env');
25
+ if (!(0, fs_1.existsSync)(envPath)) {
26
+ logger.error('.env file not found');
27
+ logger.info('Run "commandmate init" to create a configuration file');
28
+ process.exit(types_1.ExitCode.CONFIG_ERROR);
29
+ return;
30
+ }
31
+ const daemonManager = new daemon_1.DaemonManager(PID_FILE);
32
+ // Daemon mode
33
+ if (options.daemon) {
34
+ // Check if already running
35
+ if (await daemonManager.isRunning()) {
36
+ const status = await daemonManager.getStatus();
37
+ logger.error(`Server is already running (PID: ${status?.pid})`);
38
+ process.exit(types_1.ExitCode.START_FAILED);
39
+ return;
40
+ }
41
+ logger.info('Starting server in background...');
42
+ try {
43
+ const pid = await daemonManager.start({
44
+ dev: options.dev,
45
+ port: options.port,
46
+ });
47
+ logger.success(`Server started in background (PID: ${pid})`);
48
+ const port = options.port || parseInt(process.env.CM_PORT || '3000', 10);
49
+ const bind = process.env.CM_BIND || '127.0.0.1';
50
+ const url = `http://${bind === '0.0.0.0' ? '127.0.0.1' : bind}:${port}`;
51
+ logger.info(`URL: ${url}`);
52
+ (0, security_logger_1.logSecurityEvent)({
53
+ timestamp: new Date().toISOString(),
54
+ command: 'start',
55
+ action: 'success',
56
+ details: `Daemon started (PID: ${pid})`,
57
+ });
58
+ process.exit(types_1.ExitCode.SUCCESS);
59
+ }
60
+ catch (error) {
61
+ const message = error instanceof Error ? error.message : String(error);
62
+ logger.error(`Failed to start daemon: ${message}`);
63
+ (0, security_logger_1.logSecurityEvent)({
64
+ timestamp: new Date().toISOString(),
65
+ command: 'start',
66
+ action: 'failure',
67
+ details: message,
68
+ });
69
+ process.exit(types_1.ExitCode.START_FAILED);
70
+ }
71
+ return;
72
+ }
73
+ // Foreground mode (default)
74
+ const npmScript = options.dev ? 'dev' : 'start';
75
+ logger.info(`Starting server in foreground (${options.dev ? 'development' : 'production'} mode)...`);
76
+ const env = { ...process.env };
77
+ if (options.port) {
78
+ env.CM_PORT = String(options.port);
79
+ }
80
+ const child = (0, child_process_1.spawn)('npm', ['run', npmScript], {
81
+ cwd: process.cwd(),
82
+ env,
83
+ stdio: 'inherit',
84
+ });
85
+ child.on('error', (err) => {
86
+ logger.error(`Failed to start server: ${err.message}`);
87
+ (0, security_logger_1.logSecurityEvent)({
88
+ timestamp: new Date().toISOString(),
89
+ command: 'start',
90
+ action: 'failure',
91
+ details: err.message,
92
+ });
93
+ process.exit(types_1.ExitCode.START_FAILED);
94
+ });
95
+ child.on('close', (code) => {
96
+ const exitCode = code ?? 0;
97
+ (0, security_logger_1.logSecurityEvent)({
98
+ timestamp: new Date().toISOString(),
99
+ command: 'start',
100
+ action: exitCode === 0 ? 'success' : 'failure',
101
+ details: `Server exited with code ${exitCode}`,
102
+ });
103
+ process.exit(exitCode);
104
+ });
105
+ }
106
+ catch (error) {
107
+ const message = error instanceof Error ? error.message : String(error);
108
+ logger.error(`Start failed: ${message}`);
109
+ (0, security_logger_1.logSecurityEvent)({
110
+ timestamp: new Date().toISOString(),
111
+ command: 'start',
112
+ action: 'failure',
113
+ details: message,
114
+ });
115
+ process.exit(types_1.ExitCode.UNEXPECTED_ERROR);
116
+ }
117
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Status Command
3
+ * Issue #96: npm install CLI support
4
+ * Display CommandMate server status
5
+ */
6
+ /**
7
+ * Execute status command
8
+ */
9
+ export declare function statusCommand(): Promise<void>;
10
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAUH;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CA6CnD"}
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ /**
3
+ * Status Command
4
+ * Issue #96: npm install CLI support
5
+ * Display CommandMate server status
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.statusCommand = statusCommand;
9
+ const path_1 = require("path");
10
+ const types_1 = require("../types");
11
+ const logger_1 = require("../utils/logger");
12
+ const daemon_1 = require("../utils/daemon");
13
+ const logger = new logger_1.CLILogger();
14
+ const PID_FILE = (0, path_1.join)(process.cwd(), '.commandmate.pid');
15
+ /**
16
+ * Execute status command
17
+ */
18
+ async function statusCommand() {
19
+ try {
20
+ const daemonManager = new daemon_1.DaemonManager(PID_FILE);
21
+ const status = await daemonManager.getStatus();
22
+ console.log('');
23
+ console.log('CommandMate Status');
24
+ console.log('==================');
25
+ if (status === null) {
26
+ console.log('Status: Stopped (no PID file)');
27
+ process.exit(types_1.ExitCode.SUCCESS);
28
+ return;
29
+ }
30
+ if (!status.running) {
31
+ console.log('Status: Not running (stale PID file)');
32
+ console.log('');
33
+ console.log('Run "commandmate start" to start the server');
34
+ process.exit(types_1.ExitCode.SUCCESS);
35
+ return;
36
+ }
37
+ console.log(`Status: Running (PID: ${status.pid})`);
38
+ if (status.port) {
39
+ console.log(`Port: ${status.port}`);
40
+ }
41
+ if (status.uptime !== undefined) {
42
+ console.log(`Uptime: ${logger_1.CLILogger.formatDuration(status.uptime)}`);
43
+ }
44
+ if (status.url) {
45
+ console.log(`URL: ${status.url}`);
46
+ }
47
+ console.log('');
48
+ process.exit(types_1.ExitCode.SUCCESS);
49
+ }
50
+ catch (error) {
51
+ const message = error instanceof Error ? error.message : String(error);
52
+ logger.error(`Status check failed: ${message}`);
53
+ process.exit(types_1.ExitCode.UNEXPECTED_ERROR);
54
+ }
55
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Stop Command
3
+ * Issue #96: npm install CLI support
4
+ * Stop CommandMate server
5
+ */
6
+ import { StopOptions } from '../types';
7
+ /**
8
+ * Execute stop command
9
+ */
10
+ export declare function stopCommand(options: StopOptions): Promise<void>;
11
+ //# sourceMappingURL=stop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stop.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/stop.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,WAAW,EAAY,MAAM,UAAU,CAAC;AAQjD;;GAEG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAuErE"}