commandmate 0.1.12 → 0.2.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 (163) hide show
  1. package/.env.example +4 -9
  2. package/.next/BUILD_ID +1 -1
  3. package/.next/app-build-manifest.json +24 -24
  4. package/.next/app-path-routes-manifest.json +1 -1
  5. package/.next/build-manifest.json +7 -7
  6. package/.next/cache/.tsbuildinfo +1 -1
  7. package/.next/cache/config.json +3 -3
  8. package/.next/cache/webpack/client-production/0.pack +0 -0
  9. package/.next/cache/webpack/client-production/1.pack +0 -0
  10. package/.next/cache/webpack/client-production/2.pack +0 -0
  11. package/.next/cache/webpack/client-production/index.pack +0 -0
  12. package/.next/cache/webpack/client-production/index.pack.old +0 -0
  13. package/.next/cache/webpack/edge-server-production/0.pack +0 -0
  14. package/.next/cache/webpack/edge-server-production/index.pack +0 -0
  15. package/.next/cache/webpack/server-production/0.pack +0 -0
  16. package/.next/cache/webpack/server-production/index.pack +0 -0
  17. package/.next/next-server.js.nft.json +1 -1
  18. package/.next/prerender-manifest.json +1 -1
  19. package/.next/react-loadable-manifest.json +7 -7
  20. package/.next/required-server-files.json +1 -1
  21. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  22. package/.next/server/app/_not-found.html +1 -1
  23. package/.next/server/app/_not-found.rsc +2 -2
  24. package/.next/server/app/api/hooks/claude-done/route.js +1 -19
  25. package/.next/server/app/api/hooks/claude-done/route.js.nft.json +1 -1
  26. package/.next/server/app/api/repositories/clone/[jobId]/route.js +1 -1
  27. package/.next/server/app/api/repositories/clone/[jobId]/route.js.nft.json +1 -1
  28. package/.next/server/app/api/repositories/clone/route.js +1 -1
  29. package/.next/server/app/api/repositories/clone/route.js.nft.json +1 -1
  30. package/.next/server/app/api/repositories/excluded/route.js +36 -0
  31. package/.next/server/app/api/repositories/excluded/route.js.nft.json +1 -0
  32. package/.next/server/app/api/repositories/excluded.body +1 -0
  33. package/.next/server/app/api/repositories/excluded.meta +1 -0
  34. package/.next/server/app/api/repositories/restore/route.js +36 -0
  35. package/.next/server/app/api/repositories/restore/route.js.nft.json +1 -0
  36. package/.next/server/app/api/repositories/route.js +36 -1
  37. package/.next/server/app/api/repositories/route.js.nft.json +1 -1
  38. package/.next/server/app/api/repositories/scan/route.js +1 -1
  39. package/.next/server/app/api/repositories/sync/route.js +36 -1
  40. package/.next/server/app/api/slash-commands/route.js +1 -1
  41. package/.next/server/app/api/slash-commands.body +1 -1
  42. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js +1 -1
  43. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js.nft.json +1 -1
  44. package/.next/server/app/api/worktrees/[id]/capture/route.js +2 -2
  45. package/.next/server/app/api/worktrees/[id]/current-output/route.js +1 -1
  46. package/.next/server/app/api/worktrees/[id]/current-output/route.js.nft.json +1 -1
  47. package/.next/server/app/api/worktrees/[id]/interrupt/route.js +1 -1
  48. package/.next/server/app/api/worktrees/[id]/interrupt/route.js.nft.json +1 -1
  49. package/.next/server/app/api/worktrees/[id]/kill-session/route.js +1 -1
  50. package/.next/server/app/api/worktrees/[id]/kill-session/route.js.nft.json +1 -1
  51. package/.next/server/app/api/worktrees/[id]/logs/[filename]/route.js +1 -1
  52. package/.next/server/app/api/worktrees/[id]/logs/route.js +1 -1
  53. package/.next/server/app/api/worktrees/[id]/prompt-response/route.js +1 -1
  54. package/.next/server/app/api/worktrees/[id]/prompt-response/route.js.nft.json +1 -1
  55. package/.next/server/app/api/worktrees/[id]/respond/route.js +1 -1
  56. package/.next/server/app/api/worktrees/[id]/respond/route.js.nft.json +1 -1
  57. package/.next/server/app/api/worktrees/[id]/route.js +1 -1
  58. package/.next/server/app/api/worktrees/[id]/route.js.nft.json +1 -1
  59. package/.next/server/app/api/worktrees/[id]/search/route.js +1 -1
  60. package/.next/server/app/api/worktrees/[id]/send/route.js +1 -1
  61. package/.next/server/app/api/worktrees/[id]/send/route.js.nft.json +1 -1
  62. package/.next/server/app/api/worktrees/[id]/slash-commands/route.js +1 -1
  63. package/.next/server/app/api/worktrees/[id]/start-polling/route.js +1 -1
  64. package/.next/server/app/api/worktrees/[id]/start-polling/route.js.nft.json +1 -1
  65. package/.next/server/app/api/worktrees/[id]/terminal/route.js +1 -1
  66. package/.next/server/app/api/worktrees/route.js +1 -1
  67. package/.next/server/app/api/worktrees/route.js.nft.json +1 -1
  68. package/.next/server/app/index.html +2 -2
  69. package/.next/server/app/index.rsc +3 -3
  70. package/.next/server/app/page.js +7 -7
  71. package/.next/server/app/page.js.nft.json +1 -1
  72. package/.next/server/app/page_client-reference-manifest.js +1 -1
  73. package/.next/server/app/proxy/[...path]/route.js +2 -2
  74. package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -1
  75. package/.next/server/app/worktrees/[id]/page.js +4 -4
  76. package/.next/server/app/worktrees/[id]/page.js.nft.json +1 -1
  77. package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -1
  78. package/.next/server/app/worktrees/[id]/simple-terminal/page_client-reference-manifest.js +1 -1
  79. package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
  80. package/.next/server/app-paths-manifest.json +10 -8
  81. package/.next/server/chunks/5488.js +36 -0
  82. package/.next/server/chunks/6550.js +1 -1
  83. package/.next/server/chunks/7425.js +53 -50
  84. package/.next/server/chunks/7536.js +1 -0
  85. package/.next/server/chunks/8174.js +23 -0
  86. package/.next/server/chunks/9367.js +19 -0
  87. package/.next/server/middleware-build-manifest.js +1 -1
  88. package/.next/server/middleware-manifest.json +2 -28
  89. package/.next/server/middleware-react-loadable-manifest.js +1 -1
  90. package/.next/server/pages/404.html +1 -1
  91. package/.next/server/pages/500.html +1 -1
  92. package/.next/server/server-reference-manifest.json +1 -1
  93. package/.next/static/chunks/4327.740cc7fe2d0b5049.js +60 -0
  94. package/.next/static/chunks/4343-ebe884a2a80eb033.js +1 -0
  95. package/.next/static/chunks/6568-38a33aa67d82e12b.js +1 -0
  96. package/.next/static/chunks/816-c254f4e2406e696a.js +1 -0
  97. package/.next/static/chunks/app/layout-4804cfba519283cf.js +1 -0
  98. package/.next/static/chunks/app/page-3926224c4cdf315b.js +1 -0
  99. package/.next/static/chunks/app/worktrees/[id]/page-8bd88bdc29607413.js +1 -0
  100. package/.next/static/chunks/main-b6d727aa9248d4f2.js +1 -0
  101. package/.next/static/chunks/{webpack-3fc79fab9bb738d7.js → webpack-4f85dcef6279c6ee.js} +1 -1
  102. package/.next/static/css/28be35e4727ae7ef.css +3 -0
  103. package/.next/trace +5 -5
  104. package/.next/types/app/api/repositories/excluded/route.ts +343 -0
  105. package/.next/types/app/api/repositories/restore/route.ts +343 -0
  106. package/README.md +2 -2
  107. package/dist/cli/commands/init.d.ts.map +1 -1
  108. package/dist/cli/commands/init.js +2 -13
  109. package/dist/cli/commands/start.d.ts.map +1 -1
  110. package/dist/cli/commands/start.js +3 -7
  111. package/dist/cli/config/security-messages.d.ts +11 -0
  112. package/dist/cli/config/security-messages.d.ts.map +1 -0
  113. package/dist/cli/config/security-messages.js +29 -0
  114. package/dist/cli/types/index.d.ts +0 -1
  115. package/dist/cli/types/index.d.ts.map +1 -1
  116. package/dist/cli/utils/daemon.d.ts.map +1 -1
  117. package/dist/cli/utils/daemon.js +3 -7
  118. package/dist/cli/utils/env-setup.d.ts +0 -4
  119. package/dist/cli/utils/env-setup.d.ts.map +1 -1
  120. package/dist/cli/utils/env-setup.js +0 -14
  121. package/dist/cli/utils/security-logger.d.ts.map +1 -1
  122. package/dist/cli/utils/security-logger.js +1 -2
  123. package/dist/server/server.js +25 -2
  124. package/dist/server/src/lib/auto-yes-manager.js +100 -11
  125. package/dist/server/src/lib/claude-poller.js +341 -0
  126. package/dist/server/src/lib/claude-session.js +48 -19
  127. package/dist/server/src/lib/cli-patterns.js +69 -6
  128. package/dist/server/src/lib/cli-tools/base.js +7 -1
  129. package/dist/server/src/lib/cli-tools/codex.js +14 -2
  130. package/dist/server/src/lib/cli-tools/manager.js +27 -0
  131. package/dist/server/src/lib/cli-tools/types.js +7 -0
  132. package/dist/server/src/lib/cli-tools/validation.js +41 -0
  133. package/dist/server/src/lib/db-repository.js +482 -0
  134. package/dist/server/src/lib/db.js +23 -0
  135. package/dist/server/src/lib/env.js +0 -17
  136. package/dist/server/src/lib/logger.js +0 -4
  137. package/dist/server/src/lib/prompt-detector.js +297 -109
  138. package/dist/server/src/lib/response-poller.js +73 -27
  139. package/dist/server/src/lib/tmux.js +48 -0
  140. package/dist/server/src/lib/ws-server.js +12 -1
  141. package/dist/server/src/types/sidebar.js +16 -31
  142. package/dist/server/src/types/slash-commands.js +2 -0
  143. package/package.json +1 -1
  144. package/.next/server/chunks/1318.js +0 -29
  145. package/.next/server/chunks/2597.js +0 -1
  146. package/.next/server/chunks/2648.js +0 -1
  147. package/.next/server/chunks/9703.js +0 -31
  148. package/.next/server/chunks/9723.js +0 -19
  149. package/.next/server/edge-runtime-webpack.js +0 -2
  150. package/.next/server/edge-runtime-webpack.js.map +0 -1
  151. package/.next/server/src/middleware.js +0 -14
  152. package/.next/server/src/middleware.js.map +0 -1
  153. package/.next/static/chunks/2853-d11a80b03c9a1640.js +0 -1
  154. package/.next/static/chunks/4327.3b84aa049900fdeb.js +0 -60
  155. package/.next/static/chunks/816-7e340dad784be28c.js +0 -1
  156. package/.next/static/chunks/9365-733d8c05712d2888.js +0 -1
  157. package/.next/static/chunks/app/layout-37e55f11dcc8b1bf.js +0 -1
  158. package/.next/static/chunks/app/page-fe35d61f14b90a51.js +0 -1
  159. package/.next/static/chunks/app/worktrees/[id]/page-58fcf2e63c056743.js +0 -1
  160. package/.next/static/chunks/main-a960f4a5e1a2f598.js +0 -1
  161. package/.next/static/css/376b339640084689.css +0 -3
  162. /package/.next/static/{564GHwluX5xIv9qpqLJV2 → oUD-A998xeBoez6zsrTH3}/_buildManifest.js +0 -0
  163. /package/.next/static/{564GHwluX5xIv9qpqLJV2 → oUD-A998xeBoez6zsrTH3}/_ssgManifest.js +0 -0
@@ -15,6 +15,7 @@ const preflight_1 = require("../utils/preflight");
15
15
  const env_setup_1 = require("../utils/env-setup");
16
16
  const prompt_1 = require("../utils/prompt");
17
17
  const security_logger_1 = require("../utils/security-logger");
18
+ const security_messages_1 = require("../config/security-messages");
18
19
  const logger = new logger_1.CLILogger();
19
20
  /**
20
21
  * Create default configuration (non-interactive mode)
@@ -66,15 +67,12 @@ async function promptForConfig() {
66
67
  default: false,
67
68
  });
68
69
  let bind = env_setup_1.ENV_DEFAULTS.CM_BIND;
69
- let authToken;
70
70
  if (enableExternal) {
71
71
  bind = '0.0.0.0';
72
- const envSetup = new env_setup_1.EnvSetup();
73
- authToken = envSetup.generateAuthToken();
74
72
  logger.blank();
75
73
  logger.success('External access enabled');
76
74
  logger.info(` Bind address: 0.0.0.0`);
77
- logger.info(` Auth token generated: ${authToken.substring(0, 8)}...`);
75
+ console.log(security_messages_1.REVERSE_PROXY_WARNING);
78
76
  }
79
77
  // CM_DB_PATH - Issue #135: Use getDefaultDbPath() for absolute path
80
78
  const defaultDbPath = (0, env_setup_1.getDefaultDbPath)();
@@ -86,7 +84,6 @@ async function promptForConfig() {
86
84
  CM_ROOT_DIR: rootDir,
87
85
  CM_PORT: port,
88
86
  CM_BIND: bind,
89
- CM_AUTH_TOKEN: authToken,
90
87
  CM_DB_PATH: dbPath,
91
88
  CM_LOG_LEVEL: env_setup_1.ENV_DEFAULTS.CM_LOG_LEVEL,
92
89
  CM_LOG_FORMAT: env_setup_1.ENV_DEFAULTS.CM_LOG_FORMAT,
@@ -105,18 +102,10 @@ function displayConfigSummary(config, envPath) {
105
102
  logger.info(` CM_ROOT_DIR: ${config.CM_ROOT_DIR}`);
106
103
  logger.info(` CM_PORT: ${config.CM_PORT}`);
107
104
  logger.info(` CM_BIND: ${config.CM_BIND}`);
108
- if (config.CM_AUTH_TOKEN) {
109
- logger.info(` CM_AUTH_TOKEN: ${config.CM_AUTH_TOKEN.substring(0, 8)}... (generated)`);
110
- }
111
105
  logger.info(` CM_DB_PATH: ${config.CM_DB_PATH}`);
112
106
  logger.blank();
113
107
  logger.info(` Config file: ${envPath}`);
114
108
  logger.blank();
115
- if (config.CM_AUTH_TOKEN) {
116
- logger.warn('IMPORTANT: Save your auth token securely!');
117
- logger.info(` Token: ${config.CM_AUTH_TOKEN}`);
118
- logger.blank();
119
- }
120
109
  }
121
110
  /**
122
111
  * Execute init command
@@ -1 +1 @@
1
- {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/start.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,EAAE,YAAY,EAA6B,MAAM,UAAU,CAAC;AAYnE;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAoMvE"}
1
+ {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/start.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,EAAE,YAAY,EAA6B,MAAM,UAAU,CAAC;AAanE;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA8LvE"}
@@ -17,6 +17,7 @@ const daemon_1 = require("../utils/daemon");
17
17
  const security_logger_1 = require("../utils/security-logger");
18
18
  const paths_1 = require("../utils/paths");
19
19
  const env_setup_1 = require("../utils/env-setup");
20
+ const security_messages_1 = require("../config/security-messages");
20
21
  const input_validators_1 = require("../utils/input-validators");
21
22
  const port_allocator_1 = require("../utils/port-allocator");
22
23
  const resource_resolvers_1 = require("../utils/resource-resolvers");
@@ -139,15 +140,10 @@ async function startCommand(options) {
139
140
  if (dbPath) {
140
141
  env.CM_DB_PATH = dbPath;
141
142
  }
142
- // Issue #125: Security warnings for external access
143
+ // Issue #179: Security warning for external access - recommend reverse proxy
143
144
  const bindAddress = env.CM_BIND || '127.0.0.1';
144
- const authToken = env.CM_AUTH_TOKEN;
145
145
  if (bindAddress === '0.0.0.0') {
146
- logger.warn('WARNING: Server is accessible from external networks (CM_BIND=0.0.0.0)');
147
- if (!authToken) {
148
- logger.warn('SECURITY WARNING: No authentication token configured. External access is not recommended without CM_AUTH_TOKEN.');
149
- logger.info('Run "commandmate init" to configure a secure authentication token.');
150
- }
146
+ console.log(security_messages_1.REVERSE_PROXY_WARNING);
151
147
  }
152
148
  // Use package installation directory, not current working directory
153
149
  const packageRoot = (0, paths_1.getPackageRoot)();
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Security Messages
3
+ * Issue #179: Reverse proxy authentication recommendation
4
+ * Shared warning constants for CLI commands (DRY principle)
5
+ */
6
+ /**
7
+ * Warning message displayed when CM_BIND=0.0.0.0
8
+ * Used by: init.ts, start.ts, daemon.ts
9
+ */
10
+ export declare const REVERSE_PROXY_WARNING = "\n\u001B[1m\u001B[31mWARNING: Server is exposed to external networks without authentication\u001B[0m\n\nExposing the server without reverse proxy authentication\nis a serious security risk.\n\n\u001B[1mRisks:\u001B[0m\n File read/write/delete and command execution\n become accessible to third parties.\n\n\u001B[1mRecommended authentication methods:\u001B[0m\n - Nginx + Basic Auth\n - Cloudflare Access\n - Tailscale\n\nDetails: https://github.com/Kewton/CommandMate/blob/main/docs/security-guide.md\n";
11
+ //# sourceMappingURL=security-messages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-messages.d.ts","sourceRoot":"","sources":["../../../src/cli/config/security-messages.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;GAGG;AACH,eAAO,MAAM,qBAAqB,igBAgBjC,CAAC"}
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ /**
3
+ * Security Messages
4
+ * Issue #179: Reverse proxy authentication recommendation
5
+ * Shared warning constants for CLI commands (DRY principle)
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.REVERSE_PROXY_WARNING = void 0;
9
+ /**
10
+ * Warning message displayed when CM_BIND=0.0.0.0
11
+ * Used by: init.ts, start.ts, daemon.ts
12
+ */
13
+ exports.REVERSE_PROXY_WARNING = `
14
+ \x1b[1m\x1b[31mWARNING: Server is exposed to external networks without authentication\x1b[0m
15
+
16
+ Exposing the server without reverse proxy authentication
17
+ is a serious security risk.
18
+
19
+ \x1b[1mRisks:\x1b[0m
20
+ File read/write/delete and command execution
21
+ become accessible to third parties.
22
+
23
+ \x1b[1mRecommended authentication methods:\x1b[0m
24
+ - Nginx + Basic Auth
25
+ - Cloudflare Access
26
+ - Tailscale
27
+
28
+ Details: https://github.com/Kewton/CommandMate/blob/main/docs/security-guide.md
29
+ `;
@@ -120,7 +120,6 @@ export interface EnvConfig {
120
120
  CM_ROOT_DIR: string;
121
121
  CM_PORT: number;
122
122
  CM_BIND: string;
123
- CM_AUTH_TOKEN?: string;
124
123
  CM_DB_PATH: string;
125
124
  CM_LOG_LEVEL: string;
126
125
  CM_LOG_FORMAT: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/types/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/types/index.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
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;IAmFnD;;;;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;AAOtD;;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;IA6EnD;;;;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"}
@@ -12,6 +12,7 @@ const dotenv_1 = require("dotenv");
12
12
  const pid_manager_1 = require("./pid-manager");
13
13
  const paths_1 = require("./paths");
14
14
  const env_setup_1 = require("./env-setup");
15
+ const security_messages_1 = require("../config/security-messages");
15
16
  const logger_1 = require("./logger");
16
17
  /**
17
18
  * Daemon manager for background server process
@@ -60,16 +61,11 @@ class DaemonManager {
60
61
  if (options.dbPath) {
61
62
  env.CM_DB_PATH = options.dbPath;
62
63
  }
63
- // Issue #125: Security warnings for external access (Stage 4 review: MF-2)
64
+ // Issue #179: Security warning for external access - recommend reverse proxy
64
65
  const bindAddress = env.CM_BIND || '127.0.0.1';
65
- const authToken = env.CM_AUTH_TOKEN;
66
66
  const port = env.CM_PORT || '3000';
67
67
  if (bindAddress === '0.0.0.0') {
68
- this.logger.warn('WARNING: Server is accessible from external networks (CM_BIND=0.0.0.0)');
69
- if (!authToken) {
70
- this.logger.warn('SECURITY WARNING: No authentication token configured. External access is not recommended without CM_AUTH_TOKEN.');
71
- this.logger.info('Run "commandmate init" to configure a secure authentication token.');
72
- }
68
+ console.log(security_messages_1.REVERSE_PROXY_WARNING);
73
69
  }
74
70
  // Log startup with accurate settings (Stage 4 review: MF-2)
75
71
  this.logger.info(`Starting server at http://${bindAddress}:${port}`);
@@ -105,10 +105,6 @@ export declare class EnvSetup {
105
105
  * Backup existing .env file
106
106
  */
107
107
  backupExisting(): Promise<string | null>;
108
- /**
109
- * Generate secure authentication token
110
- */
111
- generateAuthToken(): string;
112
108
  /**
113
109
  * Validate configuration
114
110
  */
@@ -1 +1 @@
1
- {"version":3,"file":"env-setup.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/env-setup.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAaH,OAAO,EACL,SAAS,EACT,eAAe,EACf,gBAAgB,EACjB,MAAM,UAAU,CAAC;AASlB,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAElE;;;;;;GAMG;AACH,eAAO,MAAM,YAAY;;;;;CAMf,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,gBAAgB,QAA2B,CAAC;AAEzD;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAOzC;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAwBnD;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,CASpF;AAKD;;;;;GAKG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAGnC;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAYvD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGnD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGlD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMlD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAUpD;AAED;;GAEG;AACH,qBAAa,QAAQ;IACnB,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,CAAC,EAAE,MAAM;IAI5B;;;OAGG;IACG,aAAa,CACjB,MAAM,EAAE,SAAS,EACjB,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,IAAI,CAAC;IAiChB;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAY9C;;OAEG;IACH,iBAAiB,IAAI,MAAM;IAI3B;;OAEG;IACH,cAAc,CAAC,MAAM,EAAE,SAAS,GAAG,gBAAgB;CAoCpD"}
1
+ {"version":3,"file":"env-setup.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/env-setup.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,OAAO,EACL,SAAS,EACT,eAAe,EACf,gBAAgB,EACjB,MAAM,UAAU,CAAC;AASlB,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAElE;;;;;;GAMG;AACH,eAAO,MAAM,YAAY;;;;;CAMf,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,gBAAgB,QAA2B,CAAC;AAEzD;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAOzC;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAwBnD;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,CASpF;AAKD;;;;;GAKG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAGnC;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAYvD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGnD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGlD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMlD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAUpD;AAED;;GAEG;AACH,qBAAa,QAAQ;IACnB,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,CAAC,EAAE,MAAM;IAI5B;;;OAGG;IACG,aAAa,CACjB,MAAM,EAAE,SAAS,EACjB,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,IAAI,CAAC;IA6BhB;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAY9C;;OAEG;IACH,cAAc,CAAC,MAAM,EAAE,SAAS,GAAG,gBAAgB;CA+BpD"}
@@ -18,7 +18,6 @@ exports.validatePort = validatePort;
18
18
  exports.escapeEnvValue = escapeEnvValue;
19
19
  const fs_1 = require("fs");
20
20
  const path_1 = require("path");
21
- const crypto_1 = require("crypto");
22
21
  const os_1 = require("os");
23
22
  // Issue #136: Import from install-context.ts to avoid circular imports
24
23
  // Re-export for backward compatibility
@@ -210,9 +209,6 @@ class EnvSetup {
210
209
  `CM_LOG_LEVEL=${config.CM_LOG_LEVEL}`,
211
210
  `CM_LOG_FORMAT=${config.CM_LOG_FORMAT}`,
212
211
  ];
213
- if (config.CM_AUTH_TOKEN) {
214
- lines.push(`CM_AUTH_TOKEN=${config.CM_AUTH_TOKEN}`);
215
- }
216
212
  lines.push('');
217
213
  const content = lines.join('\n');
218
214
  // Write with secure permissions
@@ -232,12 +228,6 @@ class EnvSetup {
232
228
  (0, fs_1.copyFileSync)(this.envPath, backupPath);
233
229
  return backupPath;
234
230
  }
235
- /**
236
- * Generate secure authentication token
237
- */
238
- generateAuthToken() {
239
- return (0, crypto_1.randomBytes)(32).toString('hex');
240
- }
241
231
  /**
242
232
  * Validate configuration
243
233
  */
@@ -252,10 +242,6 @@ class EnvSetup {
252
242
  if (!validBinds.includes(config.CM_BIND)) {
253
243
  errors.push(`Invalid bind address: must be one of ${validBinds.join(', ')}`);
254
244
  }
255
- // Require auth token for external access
256
- if (config.CM_BIND === '0.0.0.0' && !config.CM_AUTH_TOKEN) {
257
- errors.push('auth token is required when binding to 0.0.0.0');
258
- }
259
245
  // Validate log level
260
246
  const validLogLevels = ['debug', 'info', 'warn', 'error'];
261
247
  if (!validLogLevels.includes(config.CM_LOG_LEVEL)) {
@@ -1 +1 @@
1
- {"version":3,"file":"security-logger.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/security-logger.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,oBAAoB;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,oBAAoB;IACpB,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;IAC1C,yBAAyB;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAaD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAU3D;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAc/E"}
1
+ {"version":3,"file":"security-logger.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/security-logger.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,oBAAoB;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,oBAAoB;IACpB,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;IAC1C,yBAAyB;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAaD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAU3D;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAY/E"}
@@ -43,9 +43,8 @@ function maskSensitiveData(input) {
43
43
  if (!input) {
44
44
  return input;
45
45
  }
46
- // Mask CM_AUTH_TOKEN values
47
- let result = input.replace(/CM_AUTH_TOKEN=\S+/g, 'CM_AUTH_TOKEN=***masked***');
48
46
  // Mask any token-like strings (12+ hex/alphanumeric characters after "token:")
47
+ let result = input;
49
48
  result = result.replace(/(?:token|Token)[:\s]+([a-zA-Z0-9]{12,})/gi, (_match, token) => {
50
49
  return _match.replace(token, '***');
51
50
  });
@@ -37,6 +37,8 @@ const response_poller_1 = require("./src/lib/response-poller");
37
37
  const auto_yes_manager_1 = require("./src/lib/auto-yes-manager");
38
38
  const db_migrations_1 = require("./src/lib/db-migrations");
39
39
  const env_1 = require("./src/lib/env");
40
+ const db_repository_1 = require("./src/lib/db-repository");
41
+ const db_1 = require("./src/lib/db");
40
42
  const dev = process.env.NODE_ENV !== 'production';
41
43
  const hostname = (0, env_1.getEnvByKey)('CM_BIND') || '127.0.0.1';
42
44
  const port = parseInt((0, env_1.getEnvByKey)('CM_PORT') || '3000', 10);
@@ -76,8 +78,29 @@ app.prepare().then(() => {
76
78
  repositoryPaths.forEach((path, i) => {
77
79
  console.log(` ${i + 1}. ${path}`);
78
80
  });
79
- // Scan all repositories
80
- const worktrees = await (0, worktrees_1.scanMultipleRepositories)(repositoryPaths);
81
+ // Issue #202: Register environment variable repositories and filter out excluded ones
82
+ // registerAndFilterRepositories() encapsulates the ordering constraint:
83
+ // registration MUST happen before filtering (see design policy Section 4)
84
+ const { filteredPaths, excludedPaths, excludedCount } = (0, db_repository_1.registerAndFilterRepositories)(db, repositoryPaths);
85
+ if (excludedCount > 0) {
86
+ console.log(`Excluded repositories: ${excludedCount}, Active repositories: ${filteredPaths.length}`);
87
+ // SF-SEC-003: Log excluded repository paths for audit/troubleshooting
88
+ excludedPaths.forEach(p => {
89
+ console.log(` [excluded] ${p}`);
90
+ });
91
+ // Issue #202: Remove worktrees of excluded repositories from DB
92
+ // Without this, worktree records remain in DB and appear in the UI
93
+ for (const excludedPath of excludedPaths) {
94
+ const resolvedPath = (0, db_repository_1.resolveRepositoryPath)(excludedPath);
95
+ const worktreeIds = (0, db_1.getWorktreeIdsByRepository)(db, resolvedPath);
96
+ if (worktreeIds.length > 0) {
97
+ const result = (0, db_1.deleteWorktreesByIds)(db, worktreeIds);
98
+ console.log(` Removed ${result.deletedCount} worktree(s) from excluded repository: ${resolvedPath}`);
99
+ }
100
+ }
101
+ }
102
+ // Scan filtered repositories (excluded repos are skipped)
103
+ const worktrees = await (0, worktrees_1.scanMultipleRepositories)(filteredPaths);
81
104
  // Sync to database
82
105
  (0, worktrees_1.syncWorktreesToDB)(db, worktrees);
83
106
  console.log(`✓ Total: ${worktrees.length} worktree(s) synced to database`);
@@ -9,7 +9,7 @@
9
9
  * auto-yes responses when browser tabs are in background.
10
10
  */
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.MAX_CONCURRENT_POLLERS = exports.MAX_CONSECUTIVE_ERRORS = exports.MAX_BACKOFF_MS = exports.POLLING_INTERVAL_MS = void 0;
12
+ exports.THINKING_CHECK_LINE_COUNT = exports.MAX_CONCURRENT_POLLERS = exports.MAX_CONSECUTIVE_ERRORS = exports.MAX_BACKOFF_MS = exports.POLLING_INTERVAL_MS = void 0;
13
13
  exports.isValidWorktreeId = isValidWorktreeId;
14
14
  exports.calculateBackoffInterval = calculateBackoffInterval;
15
15
  exports.isAutoYesExpired = isAutoYesExpired;
@@ -41,6 +41,16 @@ exports.MAX_CONSECUTIVE_ERRORS = 5;
41
41
  exports.MAX_CONCURRENT_POLLERS = 50;
42
42
  /** Timeout duration: 1 hour in milliseconds */
43
43
  const AUTO_YES_TIMEOUT_MS = 3600000;
44
+ /**
45
+ * Number of lines from the end to check for thinking indicators (Issue #191)
46
+ * Matches detectPrompt()'s multiple_choice scan range (50 lines in prompt-detector.ts)
47
+ * to ensure Issue #161 Layer 1 defense covers the same scope as prompt detection.
48
+ *
49
+ * IMPORTANT: This value is semantically coupled to the hardcoded 50 in
50
+ * prompt-detector.ts detectMultipleChoicePrompt() (L268: Math.max(0, lines.length - 50)).
51
+ * See SF-001 in Stage 1 review. A cross-reference test validates this coupling.
52
+ */
53
+ exports.THINKING_CHECK_LINE_COUNT = 50;
44
54
  /** Worktree ID validation pattern (security: prevent command injection) */
45
55
  const WORKTREE_ID_PATTERN = /^[a-zA-Z0-9_-]+$/;
46
56
  /** In-memory storage for auto-yes states (globalThis for hot reload persistence) */
@@ -205,32 +215,111 @@ async function pollAutoYes(worktreeId, cliToolId) {
205
215
  try {
206
216
  // 1. Capture tmux output
207
217
  const output = await (0, cli_session_1.captureSessionOutput)(worktreeId, cliToolId, 5000);
208
- // 2. Strip ANSI codes and detect prompt
218
+ // 2. Strip ANSI codes
209
219
  const cleanOutput = (0, cli_patterns_1.stripAnsi)(output);
210
- const promptDetection = (0, prompt_detector_1.detectPrompt)(cleanOutput);
220
+ // 2.5. Skip prompt detection during thinking state (Issue #161, Layer 1)
221
+ // This prevents false positive detection of numbered lists in CLI output
222
+ // while Claude is actively processing (thinking/planning).
223
+ //
224
+ // Issue #191: Apply windowing to detectThinking() to prevent stale thinking
225
+ // summary lines (e.g., "· Simmering…") from blocking prompt detection.
226
+ // Window size matches detectPrompt()'s multiple_choice scan range (50 lines).
227
+ //
228
+ // Safety: Claude CLI does not emit prompts during thinking, so narrowing
229
+ // the window cannot cause false auto-responses (see IA-003 in design doc).
230
+ //
231
+ // Processing order: stripAnsi -> split -> slice -> join
232
+ // stripAnsi is applied BEFORE split to ensure ANSI escape sequences spanning
233
+ // line boundaries do not affect line counting (IA-002).
234
+ //
235
+ // Boundary case: if buffer has fewer than 50 lines, slice(-50) returns the
236
+ // entire array (Array.prototype.slice specification), which is safe degradation
237
+ // equivalent to pre-fix behavior (IA-001).
238
+ const recentLines = cleanOutput.split('\n').slice(-exports.THINKING_CHECK_LINE_COUNT).join('\n');
239
+ if ((0, cli_patterns_1.detectThinking)(cliToolId, recentLines)) {
240
+ scheduleNextPoll(worktreeId, cliToolId);
241
+ return;
242
+ }
243
+ // 3. Detect prompt
244
+ const promptOptions = (0, cli_patterns_1.buildDetectPromptOptions)(cliToolId);
245
+ const promptDetection = (0, prompt_detector_1.detectPrompt)(cleanOutput, promptOptions);
211
246
  if (!promptDetection.isPrompt || !promptDetection.promptData) {
212
247
  // No prompt detected, schedule next poll
213
248
  scheduleNextPoll(worktreeId, cliToolId);
214
249
  return;
215
250
  }
216
- // 3. Resolve auto answer
251
+ // 4. Resolve auto answer
217
252
  const answer = (0, auto_yes_resolver_1.resolveAutoAnswer)(promptDetection.promptData);
218
253
  if (answer === null) {
219
254
  // Cannot auto-answer this prompt
220
255
  scheduleNextPoll(worktreeId, cliToolId);
221
256
  return;
222
257
  }
223
- // 4. Send answer to tmux
258
+ // 5. Send answer to tmux
224
259
  const manager = manager_1.CLIToolManager.getInstance();
225
260
  const cliTool = manager.getTool(cliToolId);
226
261
  const sessionName = cliTool.getSessionName(worktreeId);
227
- // Send answer followed by Enter
228
- await (0, tmux_1.sendKeys)(sessionName, answer, false);
229
- await new Promise(resolve => setTimeout(resolve, 100));
230
- await (0, tmux_1.sendKeys)(sessionName, '', true);
231
- // 5. Update timestamp
262
+ // Issue #193: Claude Code AskUserQuestion uses cursor-based navigation
263
+ // (Arrow/Space/Enter), not number input. Detect multi-choice and send
264
+ // appropriate key sequence instead of typing the number.
265
+ const isClaudeMultiChoice = cliToolId === 'claude'
266
+ && promptDetection.promptData?.type === 'multiple_choice'
267
+ && /^\d+$/.test(answer);
268
+ if (isClaudeMultiChoice && promptDetection.promptData?.type === 'multiple_choice') {
269
+ const targetNum = parseInt(answer, 10);
270
+ const mcOptions = promptDetection.promptData.options;
271
+ const defaultOption = mcOptions.find(o => o.isDefault);
272
+ const defaultNum = defaultOption?.number ?? 1;
273
+ const offset = targetNum - defaultNum;
274
+ // Detect multi-select (checkbox) prompts by checking for [ ] in option labels.
275
+ const isMultiSelect = mcOptions.some(o => /^\[[ x]\] /.test(o.label));
276
+ if (isMultiSelect) {
277
+ // Multi-select: toggle checkbox, then navigate to "Next" and submit
278
+ const checkboxCount = mcOptions.filter(o => /^\[[ x]\] /.test(o.label)).length;
279
+ const keys = [];
280
+ // 1. Navigate to target option
281
+ if (offset > 0) {
282
+ for (let i = 0; i < offset; i++)
283
+ keys.push('Down');
284
+ }
285
+ else if (offset < 0) {
286
+ for (let i = 0; i < Math.abs(offset); i++)
287
+ keys.push('Up');
288
+ }
289
+ // 2. Space to toggle checkbox
290
+ keys.push('Space');
291
+ // 3. Navigate to "Next" button (positioned right after all checkbox options)
292
+ const downToNext = checkboxCount - targetNum + 1;
293
+ for (let i = 0; i < downToNext; i++)
294
+ keys.push('Down');
295
+ // 4. Enter to submit
296
+ keys.push('Enter');
297
+ await (0, tmux_1.sendSpecialKeys)(sessionName, keys);
298
+ }
299
+ else {
300
+ // Single-select: navigate and Enter to select
301
+ const keys = [];
302
+ if (offset > 0) {
303
+ for (let i = 0; i < offset; i++)
304
+ keys.push('Down');
305
+ }
306
+ else if (offset < 0) {
307
+ for (let i = 0; i < Math.abs(offset); i++)
308
+ keys.push('Up');
309
+ }
310
+ keys.push('Enter');
311
+ await (0, tmux_1.sendSpecialKeys)(sessionName, keys);
312
+ }
313
+ }
314
+ else {
315
+ // Standard CLI prompt: send text + Enter (y/n, Approve?, etc.)
316
+ await (0, tmux_1.sendKeys)(sessionName, answer, false);
317
+ await new Promise(resolve => setTimeout(resolve, 100));
318
+ await (0, tmux_1.sendKeys)(sessionName, '', true);
319
+ }
320
+ // 6. Update timestamp
232
321
  updateLastServerResponseTimestamp(worktreeId, Date.now());
233
- // 6. Reset error count on success
322
+ // 7. Reset error count on success
234
323
  resetErrorCount(worktreeId);
235
324
  // Log success (without sensitive content)
236
325
  console.info(`[Auto-Yes Poller] Sent response for worktree: ${worktreeId}`);