commandmate 0.1.6 → 0.1.8

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 (54) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-path-routes-manifest.json +1 -1
  3. package/.next/build-manifest.json +2 -2
  4. package/.next/cache/.tsbuildinfo +1 -1
  5. package/.next/cache/config.json +3 -3
  6. package/.next/cache/webpack/client-production/0.pack +0 -0
  7. package/.next/cache/webpack/client-production/1.pack +0 -0
  8. package/.next/cache/webpack/client-production/2.pack +0 -0
  9. package/.next/cache/webpack/client-production/index.pack +0 -0
  10. package/.next/cache/webpack/client-production/index.pack.old +0 -0
  11. package/.next/cache/webpack/edge-server-production/0.pack +0 -0
  12. package/.next/cache/webpack/edge-server-production/index.pack +0 -0
  13. package/.next/cache/webpack/server-production/0.pack +0 -0
  14. package/.next/cache/webpack/server-production/index.pack +0 -0
  15. package/.next/next-server.js.nft.json +1 -1
  16. package/.next/prerender-manifest.json +1 -1
  17. package/.next/server/app/_not-found.html +1 -1
  18. package/.next/server/app/_not-found.rsc +1 -1
  19. package/.next/server/app/index.html +1 -1
  20. package/.next/server/app/index.rsc +1 -1
  21. package/.next/server/app-paths-manifest.json +7 -7
  22. package/.next/server/functions-config-manifest.json +1 -1
  23. package/.next/server/middleware-manifest.json +5 -5
  24. package/.next/server/pages/404.html +1 -1
  25. package/.next/server/pages/500.html +1 -1
  26. package/.next/server/server-reference-manifest.json +1 -1
  27. package/.next/trace +5 -5
  28. package/dist/cli/commands/init.d.ts +1 -0
  29. package/dist/cli/commands/init.d.ts.map +1 -1
  30. package/dist/cli/commands/init.js +143 -27
  31. package/dist/cli/commands/start.d.ts +2 -0
  32. package/dist/cli/commands/start.d.ts.map +1 -1
  33. package/dist/cli/commands/start.js +10 -8
  34. package/dist/cli/commands/status.d.ts +2 -0
  35. package/dist/cli/commands/status.d.ts.map +1 -1
  36. package/dist/cli/commands/status.js +11 -4
  37. package/dist/cli/commands/stop.d.ts +2 -0
  38. package/dist/cli/commands/stop.d.ts.map +1 -1
  39. package/dist/cli/commands/stop.js +7 -4
  40. package/dist/cli/types/index.d.ts +26 -0
  41. package/dist/cli/types/index.d.ts.map +1 -1
  42. package/dist/cli/types/index.js +14 -0
  43. package/dist/cli/utils/daemon.d.ts +3 -0
  44. package/dist/cli/utils/daemon.d.ts.map +1 -1
  45. package/dist/cli/utils/daemon.js +34 -2
  46. package/dist/cli/utils/env-setup.d.ts +43 -0
  47. package/dist/cli/utils/env-setup.d.ts.map +1 -1
  48. package/dist/cli/utils/env-setup.js +98 -1
  49. package/dist/cli/utils/prompt.d.ts +68 -0
  50. package/dist/cli/utils/prompt.d.ts.map +1 -0
  51. package/dist/cli/utils/prompt.js +208 -0
  52. package/package.json +2 -1
  53. /package/.next/static/{pQTquVjewvoJa7BML07ip → KtDmF-FzoCLvoKXEcXyU-}/_buildManifest.js +0 -0
  54. /package/.next/static/{pQTquVjewvoJa7BML07ip → KtDmF-FzoCLvoKXEcXyU-}/_ssgManifest.js +0 -0
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * Init Command
3
3
  * Issue #96: npm install CLI support
4
+ * Issue #119: Interactive init support
4
5
  * Initialize CommandMate configuration
5
6
  */
6
7
  import { InitOptions } from '../types';
@@ -1 +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"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,WAAW,EAAuB,MAAM,UAAU,CAAC;AAuI5D;;GAEG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAyIrE"}
@@ -2,18 +2,120 @@
2
2
  /**
3
3
  * Init Command
4
4
  * Issue #96: npm install CLI support
5
+ * Issue #119: Interactive init support
5
6
  * Initialize CommandMate configuration
6
7
  */
7
8
  Object.defineProperty(exports, "__esModule", { value: true });
8
9
  exports.initCommand = initCommand;
9
- const path_1 = require("path");
10
+ const fs_1 = require("fs");
10
11
  const os_1 = require("os");
11
12
  const types_1 = require("../types");
12
13
  const logger_1 = require("../utils/logger");
13
14
  const preflight_1 = require("../utils/preflight");
14
15
  const env_setup_1 = require("../utils/env-setup");
16
+ const prompt_1 = require("../utils/prompt");
15
17
  const security_logger_1 = require("../utils/security-logger");
16
18
  const logger = new logger_1.CLILogger();
19
+ /**
20
+ * Create default configuration (non-interactive mode)
21
+ */
22
+ function createDefaultConfig() {
23
+ return {
24
+ CM_ROOT_DIR: (0, env_setup_1.sanitizePath)(process.env.CM_ROOT_DIR || env_setup_1.DEFAULT_ROOT_DIR),
25
+ CM_PORT: env_setup_1.ENV_DEFAULTS.CM_PORT,
26
+ CM_BIND: env_setup_1.ENV_DEFAULTS.CM_BIND,
27
+ CM_DB_PATH: env_setup_1.ENV_DEFAULTS.CM_DB_PATH,
28
+ CM_LOG_LEVEL: env_setup_1.ENV_DEFAULTS.CM_LOG_LEVEL,
29
+ CM_LOG_FORMAT: env_setup_1.ENV_DEFAULTS.CM_LOG_FORMAT,
30
+ };
31
+ }
32
+ /**
33
+ * Prompt user for configuration (interactive mode)
34
+ * Issue #119: Interactive init support
35
+ */
36
+ async function promptForConfig() {
37
+ logger.info('--- Required Settings ---');
38
+ logger.blank();
39
+ // CM_ROOT_DIR
40
+ const rootDirInput = await (0, prompt_1.prompt)('Repository root directory (CM_ROOT_DIR)', {
41
+ default: env_setup_1.DEFAULT_ROOT_DIR.replace((0, os_1.homedir)(), '~'),
42
+ });
43
+ const rootDir = (0, prompt_1.resolvePath)(rootDirInput || env_setup_1.DEFAULT_ROOT_DIR);
44
+ // Check if path exists
45
+ if (!(0, fs_1.existsSync)(rootDir)) {
46
+ logger.warn(`Directory does not exist: ${rootDir}`);
47
+ const createDir = await (0, prompt_1.confirm)('Directory will be validated when adding repositories. Continue?', {
48
+ default: true,
49
+ });
50
+ if (!createDir) {
51
+ throw new Error('Setup cancelled by user');
52
+ }
53
+ }
54
+ logger.blank();
55
+ logger.info('--- Server Settings ---');
56
+ logger.blank();
57
+ // CM_PORT
58
+ const portInput = await (0, prompt_1.prompt)('Server port (CM_PORT)', {
59
+ default: String(env_setup_1.ENV_DEFAULTS.CM_PORT),
60
+ validate: prompt_1.validatePort,
61
+ });
62
+ const port = parseInt(portInput || String(env_setup_1.ENV_DEFAULTS.CM_PORT), 10);
63
+ // External access
64
+ const enableExternal = await (0, prompt_1.confirm)('Enable external access (bind to 0.0.0.0)?', {
65
+ default: false,
66
+ });
67
+ let bind = env_setup_1.ENV_DEFAULTS.CM_BIND;
68
+ let authToken;
69
+ if (enableExternal) {
70
+ bind = '0.0.0.0';
71
+ const envSetup = new env_setup_1.EnvSetup();
72
+ authToken = envSetup.generateAuthToken();
73
+ logger.blank();
74
+ logger.success('External access enabled');
75
+ logger.info(` Bind address: 0.0.0.0`);
76
+ logger.info(` Auth token generated: ${authToken.substring(0, 8)}...`);
77
+ }
78
+ // CM_DB_PATH
79
+ const dbPathInput = await (0, prompt_1.prompt)('Database path (CM_DB_PATH)', {
80
+ default: env_setup_1.ENV_DEFAULTS.CM_DB_PATH,
81
+ });
82
+ const dbPath = dbPathInput || env_setup_1.ENV_DEFAULTS.CM_DB_PATH;
83
+ return {
84
+ CM_ROOT_DIR: rootDir,
85
+ CM_PORT: port,
86
+ CM_BIND: bind,
87
+ CM_AUTH_TOKEN: authToken,
88
+ CM_DB_PATH: dbPath,
89
+ CM_LOG_LEVEL: env_setup_1.ENV_DEFAULTS.CM_LOG_LEVEL,
90
+ CM_LOG_FORMAT: env_setup_1.ENV_DEFAULTS.CM_LOG_FORMAT,
91
+ };
92
+ }
93
+ /**
94
+ * Display configuration summary
95
+ * Issue #119: Show settings after configuration
96
+ */
97
+ function displayConfigSummary(config, envPath) {
98
+ logger.blank();
99
+ logger.info('==================================');
100
+ logger.info('Configuration Summary');
101
+ logger.info('==================================');
102
+ logger.blank();
103
+ logger.info(` CM_ROOT_DIR: ${config.CM_ROOT_DIR}`);
104
+ logger.info(` CM_PORT: ${config.CM_PORT}`);
105
+ logger.info(` CM_BIND: ${config.CM_BIND}`);
106
+ if (config.CM_AUTH_TOKEN) {
107
+ logger.info(` CM_AUTH_TOKEN: ${config.CM_AUTH_TOKEN.substring(0, 8)}... (generated)`);
108
+ }
109
+ logger.info(` CM_DB_PATH: ${config.CM_DB_PATH}`);
110
+ logger.blank();
111
+ logger.info(` Config file: ${envPath}`);
112
+ logger.blank();
113
+ if (config.CM_AUTH_TOKEN) {
114
+ logger.warn('IMPORTANT: Save your auth token securely!');
115
+ logger.info(` Token: ${config.CM_AUTH_TOKEN}`);
116
+ logger.blank();
117
+ }
118
+ }
17
119
  /**
18
120
  * Execute init command
19
121
  */
@@ -53,19 +155,30 @@ async function initCommand(options) {
53
155
  logger.blank();
54
156
  logger.success('All required dependencies found');
55
157
  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
- };
158
+ // Step 2: Get environment path
159
+ const envPath = (0, env_setup_1.getEnvPath)();
160
+ const envSetup = new env_setup_1.EnvSetup(envPath);
161
+ // Backup existing .env if force mode
162
+ if (options.force) {
163
+ const backupPath = await envSetup.backupExisting();
164
+ if (backupPath) {
165
+ logger.info(`Backed up existing .env to ${backupPath}`);
166
+ }
167
+ }
168
+ // Step 3: Create configuration
169
+ let config;
170
+ // Determine if interactive mode should be used
171
+ // Use interactive mode if:
172
+ // - Not using --defaults flag
173
+ // - Running in a TTY (interactive terminal)
174
+ const useInteractive = !options.defaults && (0, prompt_1.isInteractive)();
175
+ if (useInteractive) {
176
+ config = await promptForConfig();
177
+ (0, prompt_1.closeReadline)(); // Close readline after prompts
178
+ }
179
+ else {
180
+ config = createDefaultConfig();
181
+ }
69
182
  // Validate configuration
70
183
  const validationResult = envSetup.validateConfig(config);
71
184
  if (!validationResult.valid) {
@@ -82,37 +195,40 @@ async function initCommand(options) {
82
195
  process.exit(types_1.ExitCode.CONFIG_ERROR);
83
196
  return;
84
197
  }
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
198
+ // Step 4: Create .env file
199
+ logger.blank();
200
+ logger.info('--- Generating .env ---');
201
+ logger.blank();
93
202
  logger.info('Creating .env file...');
94
203
  await envSetup.createEnvFile(config, { force: options.force });
95
204
  logger.success('.env file created');
96
- // Step 3: Initialize database
205
+ // Step 5: Initialize database message
97
206
  logger.info('Initializing database...');
98
207
  // Note: Database initialization is handled by the server on startup
99
208
  logger.success('Database will be initialized on first server start');
100
- logger.blank();
209
+ // Display configuration summary
210
+ displayConfigSummary(config, envPath);
101
211
  logger.success('CommandMate initialized successfully!');
102
212
  logger.blank();
103
213
  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');
214
+ if (!useInteractive) {
215
+ logger.info(' 1. Edit .env to customize your configuration');
216
+ logger.info(' 2. Run "commandmate start" to start the server');
217
+ }
218
+ else {
219
+ logger.info(' 1. Run "commandmate start" to start the server');
220
+ }
106
221
  logger.blank();
107
222
  (0, security_logger_1.logSecurityEvent)({
108
223
  timestamp: new Date().toISOString(),
109
224
  command: 'init',
110
225
  action: 'success',
111
- details: 'Configuration initialized',
226
+ details: `Configuration initialized (interactive: ${useInteractive})`,
112
227
  });
113
228
  process.exit(types_1.ExitCode.SUCCESS);
114
229
  }
115
230
  catch (error) {
231
+ (0, prompt_1.closeReadline)(); // Ensure readline is closed on error
116
232
  const message = error instanceof Error ? error.message : String(error);
117
233
  logger.error(`Initialization failed: ${message}`);
118
234
  (0, security_logger_1.logSecurityEvent)({
@@ -1,11 +1,13 @@
1
1
  /**
2
2
  * Start Command
3
3
  * Issue #96: npm install CLI support
4
+ * Issue #125: Use getEnvPath and getPidFilePath for correct path resolution
4
5
  * Start CommandMate server
5
6
  */
6
7
  import { StartOptions } from '../types';
7
8
  /**
8
9
  * Execute start command
10
+ * Issue #125: Use getEnvPath and getPidFilePath for correct path resolution
9
11
  */
10
12
  export declare function startCommand(options: StartOptions): Promise<void>;
11
13
  //# sourceMappingURL=start.d.ts.map
@@ -1 +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;AASlD;;GAEG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAuHvE"}
1
+ {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/start.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,YAAY,EAA6B,MAAM,UAAU,CAAC;AASnE;;;GAGG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAyHvE"}
@@ -2,34 +2,36 @@
2
2
  /**
3
3
  * Start Command
4
4
  * Issue #96: npm install CLI support
5
+ * Issue #125: Use getEnvPath and getPidFilePath for correct path resolution
5
6
  * Start CommandMate server
6
7
  */
7
8
  Object.defineProperty(exports, "__esModule", { value: true });
8
9
  exports.startCommand = startCommand;
9
10
  const fs_1 = require("fs");
10
11
  const child_process_1 = require("child_process");
11
- const path_1 = require("path");
12
12
  const types_1 = require("../types");
13
13
  const logger_1 = require("../utils/logger");
14
14
  const daemon_1 = require("../utils/daemon");
15
15
  const security_logger_1 = require("../utils/security-logger");
16
16
  const paths_1 = require("../utils/paths");
17
+ const env_setup_1 = require("../utils/env-setup");
17
18
  const logger = new logger_1.CLILogger();
18
- const PID_FILE = (0, path_1.join)(process.cwd(), '.commandmate.pid');
19
19
  /**
20
20
  * Execute start command
21
+ * Issue #125: Use getEnvPath and getPidFilePath for correct path resolution
21
22
  */
22
23
  async function startCommand(options) {
23
24
  try {
24
- // Check for .env file
25
- const envPath = (0, path_1.join)(process.cwd(), '.env');
25
+ // Issue #125: Check for .env file at correct location
26
+ const envPath = (0, env_setup_1.getEnvPath)();
27
+ const pidFilePath = (0, env_setup_1.getPidFilePath)();
26
28
  if (!(0, fs_1.existsSync)(envPath)) {
27
- logger.error('.env file not found');
29
+ logger.error(`.env file not found at ${envPath}`);
28
30
  logger.info('Run "commandmate init" to create a configuration file');
29
31
  process.exit(types_1.ExitCode.CONFIG_ERROR);
30
32
  return;
31
33
  }
32
- const daemonManager = new daemon_1.DaemonManager(PID_FILE);
34
+ const daemonManager = new daemon_1.DaemonManager(pidFilePath);
33
35
  // Daemon mode
34
36
  if (options.daemon) {
35
37
  // Check if already running
@@ -59,7 +61,7 @@ async function startCommand(options) {
59
61
  process.exit(types_1.ExitCode.SUCCESS);
60
62
  }
61
63
  catch (error) {
62
- const message = error instanceof Error ? error.message : String(error);
64
+ const message = (0, types_1.getErrorMessage)(error);
63
65
  logger.error(`Failed to start daemon: ${message}`);
64
66
  (0, security_logger_1.logSecurityEvent)({
65
67
  timestamp: new Date().toISOString(),
@@ -107,7 +109,7 @@ async function startCommand(options) {
107
109
  });
108
110
  }
109
111
  catch (error) {
110
- const message = error instanceof Error ? error.message : String(error);
112
+ const message = (0, types_1.getErrorMessage)(error);
111
113
  logger.error(`Start failed: ${message}`);
112
114
  (0, security_logger_1.logSecurityEvent)({
113
115
  timestamp: new Date().toISOString(),
@@ -1,10 +1,12 @@
1
1
  /**
2
2
  * Status Command
3
3
  * Issue #96: npm install CLI support
4
+ * Issue #125: Use getPidFilePath and load .env for correct settings display
4
5
  * Display CommandMate server status
5
6
  */
6
7
  /**
7
8
  * Execute status command
9
+ * Issue #125: Use getPidFilePath and load .env for correct settings display
8
10
  */
9
11
  export declare function statusCommand(): Promise<void>;
10
12
  //# sourceMappingURL=status.d.ts.map
@@ -1 +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"}
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH;;;GAGG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAoDnD"}
@@ -2,22 +2,29 @@
2
2
  /**
3
3
  * Status Command
4
4
  * Issue #96: npm install CLI support
5
+ * Issue #125: Use getPidFilePath and load .env for correct settings display
5
6
  * Display CommandMate server status
6
7
  */
7
8
  Object.defineProperty(exports, "__esModule", { value: true });
8
9
  exports.statusCommand = statusCommand;
9
- const path_1 = require("path");
10
+ const dotenv_1 = require("dotenv");
10
11
  const types_1 = require("../types");
11
12
  const logger_1 = require("../utils/logger");
12
13
  const daemon_1 = require("../utils/daemon");
14
+ const env_setup_1 = require("../utils/env-setup");
13
15
  const logger = new logger_1.CLILogger();
14
- const PID_FILE = (0, path_1.join)(process.cwd(), '.commandmate.pid');
15
16
  /**
16
17
  * Execute status command
18
+ * Issue #125: Use getPidFilePath and load .env for correct settings display
17
19
  */
18
20
  async function statusCommand() {
19
21
  try {
20
- const daemonManager = new daemon_1.DaemonManager(PID_FILE);
22
+ // Issue #125: Get PID file path and load .env for correct settings
23
+ const pidFilePath = (0, env_setup_1.getPidFilePath)();
24
+ const envPath = (0, env_setup_1.getEnvPath)();
25
+ // Load .env so getStatus() can access correct CM_PORT and CM_BIND values
26
+ (0, dotenv_1.config)({ path: envPath });
27
+ const daemonManager = new daemon_1.DaemonManager(pidFilePath);
21
28
  const status = await daemonManager.getStatus();
22
29
  console.log('');
23
30
  console.log('CommandMate Status');
@@ -48,7 +55,7 @@ async function statusCommand() {
48
55
  process.exit(types_1.ExitCode.SUCCESS);
49
56
  }
50
57
  catch (error) {
51
- const message = error instanceof Error ? error.message : String(error);
58
+ const message = (0, types_1.getErrorMessage)(error);
52
59
  logger.error(`Status check failed: ${message}`);
53
60
  process.exit(types_1.ExitCode.UNEXPECTED_ERROR);
54
61
  }
@@ -1,11 +1,13 @@
1
1
  /**
2
2
  * Stop Command
3
3
  * Issue #96: npm install CLI support
4
+ * Issue #125: Use getPidFilePath for correct path resolution
4
5
  * Stop CommandMate server
5
6
  */
6
7
  import { StopOptions } from '../types';
7
8
  /**
8
9
  * Execute stop command
10
+ * Issue #125: Use getPidFilePath for correct path resolution
9
11
  */
10
12
  export declare function stopCommand(options: StopOptions): Promise<void>;
11
13
  //# sourceMappingURL=stop.d.ts.map
@@ -1 +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"}
1
+ {"version":3,"file":"stop.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/stop.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAA6B,MAAM,UAAU,CAAC;AAQlE;;;GAGG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAyErE"}
@@ -2,23 +2,26 @@
2
2
  /**
3
3
  * Stop Command
4
4
  * Issue #96: npm install CLI support
5
+ * Issue #125: Use getPidFilePath for correct path resolution
5
6
  * Stop CommandMate server
6
7
  */
7
8
  Object.defineProperty(exports, "__esModule", { value: true });
8
9
  exports.stopCommand = stopCommand;
9
- const path_1 = require("path");
10
10
  const types_1 = require("../types");
11
11
  const logger_1 = require("../utils/logger");
12
12
  const daemon_1 = require("../utils/daemon");
13
13
  const security_logger_1 = require("../utils/security-logger");
14
+ const env_setup_1 = require("../utils/env-setup");
14
15
  const logger = new logger_1.CLILogger();
15
- const PID_FILE = (0, path_1.join)(process.cwd(), '.commandmate.pid');
16
16
  /**
17
17
  * Execute stop command
18
+ * Issue #125: Use getPidFilePath for correct path resolution
18
19
  */
19
20
  async function stopCommand(options) {
20
21
  try {
21
- const daemonManager = new daemon_1.DaemonManager(PID_FILE);
22
+ // Issue #125: Get PID file path from correct location
23
+ const pidFilePath = (0, env_setup_1.getPidFilePath)();
24
+ const daemonManager = new daemon_1.DaemonManager(pidFilePath);
22
25
  // Check if running
23
26
  if (!(await daemonManager.isRunning())) {
24
27
  const status = await daemonManager.getStatus();
@@ -69,7 +72,7 @@ async function stopCommand(options) {
69
72
  }
70
73
  }
71
74
  catch (error) {
72
- const message = error instanceof Error ? error.message : String(error);
75
+ const message = (0, types_1.getErrorMessage)(error);
73
76
  logger.error(`Stop failed: ${message}`);
74
77
  (0, security_logger_1.logSecurityEvent)({
75
78
  timestamp: new Date().toISOString(),
@@ -121,4 +121,30 @@ export interface ValidationResult {
121
121
  valid: boolean;
122
122
  errors: string[];
123
123
  }
124
+ /**
125
+ * Options for prompt function
126
+ * Issue #119: Interactive init support
127
+ */
128
+ export interface PromptOptions {
129
+ /** Default value if user presses Enter */
130
+ default?: string;
131
+ /** Validation function - returns error message or true if valid */
132
+ validate?: (input: string) => string | true;
133
+ }
134
+ /**
135
+ * Options for confirm function
136
+ * Issue #119: Interactive init support
137
+ */
138
+ export interface ConfirmOptions {
139
+ /** Default value if user presses Enter (true = Y, false = N) */
140
+ default?: boolean;
141
+ }
142
+ /**
143
+ * Extract error message from unknown error
144
+ * Issue #125: DRY - centralized error message extraction
145
+ *
146
+ * @param error - Unknown error object
147
+ * @returns Error message string
148
+ */
149
+ export declare function getErrorMessage(error: unknown): string;
124
150
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/types/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,oBAAY,QAAQ;IAClB,OAAO,IAAI;IACX,gBAAgB,IAAI;IACpB,YAAY,IAAI;IAChB,YAAY,IAAI;IAChB,WAAW,IAAI;IACf,gBAAgB,KAAK;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uCAAuC;IACvC,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,gCAAgC;IAChC,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,wBAAwB;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,2BAA2B;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,2BAA2B;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,oCAAoC;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,8BAA8B;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qCAAqC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,uBAAuB;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,8BAA8B;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,QAAQ,EAAE,OAAO,CAAC;IAClB,iCAAiC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,sBAAsB;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,mBAAmB;IACnB,MAAM,EAAE,IAAI,GAAG,SAAS,GAAG,kBAAkB,CAAC;IAC9C,sCAAsC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,sDAAsD;IACtD,OAAO,EAAE,OAAO,CAAC;IACjB,oCAAoC;IACpC,OAAO,EAAE,gBAAgB,EAAE,CAAC;CAC7B;AAED;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,oCAAoC;IACpC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,kDAAkD;IAClD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/types/index.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,7 @@
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.ExitCode = void 0;
8
+ exports.getErrorMessage = getErrorMessage;
8
9
  /**
9
10
  * Exit codes for CLI commands
10
11
  * NTH-4: DRY - centralized exit code definitions
@@ -18,3 +19,16 @@ var ExitCode;
18
19
  ExitCode[ExitCode["STOP_FAILED"] = 4] = "STOP_FAILED";
19
20
  ExitCode[ExitCode["UNEXPECTED_ERROR"] = 99] = "UNEXPECTED_ERROR";
20
21
  })(ExitCode || (exports.ExitCode = ExitCode = {}));
22
+ /**
23
+ * Extract error message from unknown error
24
+ * Issue #125: DRY - centralized error message extraction
25
+ *
26
+ * @param error - Unknown error object
27
+ * @returns Error message string
28
+ */
29
+ function getErrorMessage(error) {
30
+ if (error instanceof Error) {
31
+ return error.message;
32
+ }
33
+ return String(error);
34
+ }
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * Daemon Process Manager
3
3
  * Issue #96: npm install CLI support
4
+ * Issue #125: Added .env loading and security warnings
4
5
  * SF-1: SRP - Process management only (PID handling delegated to PidManager)
5
6
  */
6
7
  import { DaemonStatus, StartOptions } from '../types';
@@ -9,9 +10,11 @@ import { DaemonStatus, StartOptions } from '../types';
9
10
  */
10
11
  export declare class DaemonManager {
11
12
  private pidManager;
13
+ private logger;
12
14
  constructor(pidFilePath: string);
13
15
  /**
14
16
  * Start daemon process
17
+ * Issue #125: Load .env file and add security warnings
15
18
  * @returns Process ID of the started daemon
16
19
  * @throws Error if already running
17
20
  */
@@ -1 +1 @@
1
- {"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/daemon.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAItD;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,UAAU,CAAa;gBAEnB,WAAW,EAAE,MAAM;IAI/B;;;;OAIG;IACG,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IA8CnD;;;;OAIG;IACG,IAAI,CAAC,KAAK,GAAE,OAAe,GAAG,OAAO,CAAC,OAAO,CAAC;IA8BpD;;;OAGG;IACG,SAAS,IAAI,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IA6B/C;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IAInC;;OAEG;YACW,WAAW;CAiB1B"}
1
+ {"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/daemon.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAMtD;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,MAAM,CAAY;gBAEd,WAAW,EAAE,MAAM;IAK/B;;;;;OAKG;IACG,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IA8EnD;;;;OAIG;IACG,IAAI,CAAC,KAAK,GAAE,OAAe,GAAG,OAAO,CAAC,OAAO,CAAC;IA8BpD;;;OAGG;IACG,SAAS,IAAI,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IA6B/C;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IAInC;;OAEG;YACW,WAAW;CAiB1B"}
@@ -2,23 +2,30 @@
2
2
  /**
3
3
  * Daemon Process Manager
4
4
  * Issue #96: npm install CLI support
5
+ * Issue #125: Added .env loading and security warnings
5
6
  * SF-1: SRP - Process management only (PID handling delegated to PidManager)
6
7
  */
7
8
  Object.defineProperty(exports, "__esModule", { value: true });
8
9
  exports.DaemonManager = void 0;
9
10
  const child_process_1 = require("child_process");
11
+ const dotenv_1 = require("dotenv");
10
12
  const pid_manager_1 = require("./pid-manager");
11
13
  const paths_1 = require("./paths");
14
+ const env_setup_1 = require("./env-setup");
15
+ const logger_1 = require("./logger");
12
16
  /**
13
17
  * Daemon manager for background server process
14
18
  */
15
19
  class DaemonManager {
16
20
  pidManager;
21
+ logger;
17
22
  constructor(pidFilePath) {
18
23
  this.pidManager = new pid_manager_1.PidManager(pidFilePath);
24
+ this.logger = new logger_1.CLILogger();
19
25
  }
20
26
  /**
21
27
  * Start daemon process
28
+ * Issue #125: Load .env file and add security warnings
22
29
  * @returns Process ID of the started daemon
23
30
  * @throws Error if already running
24
31
  */
@@ -32,11 +39,36 @@ class DaemonManager {
32
39
  const npmScript = options.dev ? 'dev' : 'start';
33
40
  // Use package installation directory, not current working directory
34
41
  const packageRoot = (0, paths_1.getPackageRoot)();
35
- // Build environment
36
- const env = { ...process.env };
42
+ // Issue #125: Load .env file from correct location
43
+ const envPath = (0, env_setup_1.getEnvPath)();
44
+ const envResult = (0, dotenv_1.config)({ path: envPath });
45
+ // Handle .env loading errors with fallback (Stage 2 review: MF-2)
46
+ if (envResult.error) {
47
+ this.logger.warn(`Failed to load .env file at ${envPath}: ${envResult.error.message}`);
48
+ this.logger.info('Continuing with existing environment variables');
49
+ }
50
+ // Build environment by merging process.env with .env values
51
+ const env = {
52
+ ...process.env,
53
+ ...(envResult.parsed || {}),
54
+ };
55
+ // Command line options override .env values
37
56
  if (options.port) {
38
57
  env.CM_PORT = String(options.port);
39
58
  }
59
+ // Issue #125: Security warnings for external access (Stage 4 review: MF-2)
60
+ const bindAddress = env.CM_BIND || '127.0.0.1';
61
+ const authToken = env.CM_AUTH_TOKEN;
62
+ const port = env.CM_PORT || '3000';
63
+ if (bindAddress === '0.0.0.0') {
64
+ this.logger.warn('WARNING: Server is accessible from external networks (CM_BIND=0.0.0.0)');
65
+ if (!authToken) {
66
+ this.logger.warn('SECURITY WARNING: No authentication token configured. External access is not recommended without CM_AUTH_TOKEN.');
67
+ this.logger.info('Run "commandmate init" to configure a secure authentication token.');
68
+ }
69
+ }
70
+ // Log startup with accurate settings (Stage 4 review: MF-2)
71
+ this.logger.info(`Starting server at http://${bindAddress}:${port}`);
40
72
  // Spawn detached process
41
73
  const child = (0, child_process_1.spawn)('npm', ['run', npmScript], {
42
74
  cwd: packageRoot,
@@ -15,6 +15,49 @@ export declare const ENV_DEFAULTS: {
15
15
  readonly CM_LOG_LEVEL: "info";
16
16
  readonly CM_LOG_FORMAT: "text";
17
17
  };
18
+ /**
19
+ * Default root directory for worktrees
20
+ */
21
+ export declare const DEFAULT_ROOT_DIR: string;
22
+ /**
23
+ * Check if running as global npm package
24
+ * Issue #119: Determine .env location based on install type
25
+ *
26
+ * @returns true if running as global npm package
27
+ */
28
+ export declare function isGlobalInstall(): boolean;
29
+ /**
30
+ * Get the path to .env file based on install type
31
+ * Issue #119: Global install uses ~/.commandmate/, local uses cwd
32
+ *
33
+ * @returns Path to .env file
34
+ */
35
+ export declare function getEnvPath(): string;
36
+ /**
37
+ * Resolve path securely by resolving symlinks and verifying within allowed directory
38
+ * Issue #125: Path traversal protection (OWASP A01:2021 - Broken Access Control)
39
+ *
40
+ * @param targetPath - The path to resolve and verify
41
+ * @param allowedBaseDir - The base directory that targetPath must be within
42
+ * @returns The resolved real path
43
+ * @throws Error if path resolves outside allowed directory
44
+ */
45
+ export declare function resolveSecurePath(targetPath: string, allowedBaseDir: string): string;
46
+ /**
47
+ * Get the config directory path
48
+ * Issue #119: Returns ~/.commandmate for global, cwd for local
49
+ * Issue #125: Added symlink resolution for security (path traversal protection)
50
+ *
51
+ * @returns Path to config directory (absolute, with symlinks resolved)
52
+ */
53
+ export declare function getConfigDir(): string;
54
+ /**
55
+ * Get the PID file path based on install type
56
+ * Issue #125: DRY principle - centralized PID file path resolution
57
+ *
58
+ * @returns Path to PID file (uses getConfigDir for consistency)
59
+ */
60
+ export declare function getPidFilePath(): string;
18
61
  /**
19
62
  * Sanitize input by removing control characters
20
63
  * SF-SEC-3: Input sanitization