commandmate 0.1.10 → 0.1.11

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 (139) hide show
  1. package/.env.example +8 -3
  2. package/.next/BUILD_ID +1 -1
  3. package/.next/app-build-manifest.json +11 -11
  4. package/.next/app-path-routes-manifest.json +1 -1
  5. package/.next/build-manifest.json +2 -2
  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/server/app/_not-found/page_client-reference-manifest.js +1 -1
  20. package/.next/server/app/_not-found.html +1 -1
  21. package/.next/server/app/_not-found.rsc +1 -1
  22. package/.next/server/app/api/external-apps/[id]/health/route.js +11 -12
  23. package/.next/server/app/api/external-apps/[id]/route.js +14 -15
  24. package/.next/server/app/api/external-apps/route.js +12 -13
  25. package/.next/server/app/api/hooks/claude-done/route.js +1 -1
  26. package/.next/server/app/api/repositories/clone/[jobId]/route.js +1 -1
  27. package/.next/server/app/api/repositories/clone/route.js +1 -1
  28. package/.next/server/app/api/repositories/route.js +1 -1
  29. package/.next/server/app/api/repositories/scan/route.js +1 -1
  30. package/.next/server/app/api/repositories/sync/route.js +1 -1
  31. package/.next/server/app/api/slash-commands.body +1 -1
  32. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js +1 -1
  33. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js.nft.json +1 -1
  34. package/.next/server/app/api/worktrees/[id]/cli-tool/route.js +1 -1
  35. package/.next/server/app/api/worktrees/[id]/current-output/route.js +1 -1
  36. package/.next/server/app/api/worktrees/[id]/files/[...path]/route.js +1 -1
  37. package/.next/server/app/api/worktrees/[id]/interrupt/route.js +1 -1
  38. package/.next/server/app/api/worktrees/[id]/kill-session/route.js +1 -1
  39. package/.next/server/app/api/worktrees/[id]/logs/[filename]/route.js +1 -1
  40. package/.next/server/app/api/worktrees/[id]/logs/route.js +7 -7
  41. package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route.js +1 -1
  42. package/.next/server/app/api/worktrees/[id]/memos/route.js +1 -1
  43. package/.next/server/app/api/worktrees/[id]/messages/route.js +1 -1
  44. package/.next/server/app/api/worktrees/[id]/prompt-response/route.js +1 -1
  45. package/.next/server/app/api/worktrees/[id]/respond/route.js +1 -1
  46. package/.next/server/app/api/worktrees/[id]/route.js +1 -1
  47. package/.next/server/app/api/worktrees/[id]/search/route.js +1 -1
  48. package/.next/server/app/api/worktrees/[id]/send/route.js +1 -1
  49. package/.next/server/app/api/worktrees/[id]/slash-commands/route.js +1 -1
  50. package/.next/server/app/api/worktrees/[id]/start-polling/route.js +1 -1
  51. package/.next/server/app/api/worktrees/[id]/tree/[...path]/route.js +1 -1
  52. package/.next/server/app/api/worktrees/[id]/tree/route.js +1 -1
  53. package/.next/server/app/api/worktrees/[id]/upload/[...path]/route.js +1 -1
  54. package/.next/server/app/api/worktrees/[id]/viewed/route.js +1 -1
  55. package/.next/server/app/api/worktrees/route.js +1 -1
  56. package/.next/server/app/index.html +2 -2
  57. package/.next/server/app/index.rsc +2 -2
  58. package/.next/server/app/page_client-reference-manifest.js +1 -1
  59. package/.next/server/app/proxy/[...path]/route.js +12 -13
  60. package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -1
  61. package/.next/server/app/worktrees/[id]/page.js +3 -3
  62. package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -1
  63. package/.next/server/app/worktrees/[id]/simple-terminal/page_client-reference-manifest.js +1 -1
  64. package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
  65. package/.next/server/app-paths-manifest.json +10 -10
  66. package/.next/server/chunks/1318.js +4 -4
  67. package/.next/server/chunks/1528.js +1 -1
  68. package/.next/server/chunks/7425.js +97 -48
  69. package/.next/server/chunks/9723.js +1 -1
  70. package/.next/server/functions-config-manifest.json +1 -1
  71. package/.next/server/middleware-manifest.json +5 -5
  72. package/.next/server/pages/404.html +1 -1
  73. package/.next/server/pages/500.html +1 -1
  74. package/.next/server/server-reference-manifest.json +1 -1
  75. package/.next/server/src/middleware.js +2 -2
  76. package/.next/server/src/middleware.js.map +1 -1
  77. package/.next/static/chunks/app/worktrees/[id]/page-720605c2fb074444.js +1 -0
  78. package/.next/trace +5 -5
  79. package/dist/cli/commands/init.d.ts.map +1 -1
  80. package/dist/cli/commands/init.js +6 -4
  81. package/dist/cli/commands/start.d.ts +2 -0
  82. package/dist/cli/commands/start.d.ts.map +1 -1
  83. package/dist/cli/commands/start.js +64 -17
  84. package/dist/cli/commands/status.d.ts +4 -1
  85. package/dist/cli/commands/status.d.ts.map +1 -1
  86. package/dist/cli/commands/status.js +95 -6
  87. package/dist/cli/commands/stop.d.ts +2 -0
  88. package/dist/cli/commands/stop.d.ts.map +1 -1
  89. package/dist/cli/commands/stop.js +27 -10
  90. package/dist/cli/index.js +16 -2
  91. package/dist/cli/types/index.d.ts +20 -0
  92. package/dist/cli/types/index.d.ts.map +1 -1
  93. package/dist/cli/utils/daemon-factory.d.ts +105 -0
  94. package/dist/cli/utils/daemon-factory.d.ts.map +1 -0
  95. package/dist/cli/utils/daemon-factory.js +117 -0
  96. package/dist/cli/utils/daemon.d.ts.map +1 -1
  97. package/dist/cli/utils/daemon.js +4 -0
  98. package/dist/cli/utils/env-setup.d.ts +24 -12
  99. package/dist/cli/utils/env-setup.d.ts.map +1 -1
  100. package/dist/cli/utils/env-setup.js +64 -43
  101. package/dist/cli/utils/input-validators.d.ts +103 -0
  102. package/dist/cli/utils/input-validators.d.ts.map +1 -0
  103. package/dist/cli/utils/input-validators.js +163 -0
  104. package/dist/cli/utils/install-context.d.ts +53 -0
  105. package/dist/cli/utils/install-context.d.ts.map +1 -0
  106. package/dist/cli/utils/install-context.js +96 -0
  107. package/dist/cli/utils/pid-manager.d.ts +34 -0
  108. package/dist/cli/utils/pid-manager.d.ts.map +1 -1
  109. package/dist/cli/utils/pid-manager.js +43 -0
  110. package/dist/cli/utils/port-allocator.d.ts +108 -0
  111. package/dist/cli/utils/port-allocator.d.ts.map +1 -0
  112. package/dist/cli/utils/port-allocator.js +166 -0
  113. package/dist/cli/utils/resource-resolvers.d.ts +92 -0
  114. package/dist/cli/utils/resource-resolvers.d.ts.map +1 -0
  115. package/dist/cli/utils/resource-resolvers.js +175 -0
  116. package/dist/cli/utils/worktree-detector.d.ts +82 -0
  117. package/dist/cli/utils/worktree-detector.d.ts.map +1 -0
  118. package/dist/cli/utils/worktree-detector.js +221 -0
  119. package/dist/lib/errors.d.ts +111 -0
  120. package/dist/lib/errors.d.ts.map +1 -0
  121. package/dist/lib/errors.js +153 -0
  122. package/dist/server/server.js +3 -0
  123. package/dist/server/src/cli/utils/install-context.js +96 -0
  124. package/dist/server/src/config/system-directories.js +40 -0
  125. package/dist/server/src/lib/auto-yes-manager.js +325 -0
  126. package/dist/server/src/lib/auto-yes-resolver.js +34 -0
  127. package/dist/server/src/lib/cli-patterns.js +6 -1
  128. package/dist/server/src/lib/db-instance.js +12 -2
  129. package/dist/server/src/lib/db-migrations.js +68 -1
  130. package/dist/server/src/lib/db-path-resolver.js +99 -0
  131. package/dist/server/src/lib/db.js +21 -0
  132. package/dist/server/src/lib/env.js +52 -3
  133. package/dist/server/src/lib/worktrees.js +36 -1
  134. package/dist/server/src/types/external-apps.js +20 -0
  135. package/package.json +1 -1
  136. package/.next/static/chunks/app/worktrees/[id]/page-aea2d5e7e28955be.js +0 -1
  137. /package/.next/static/chunks/app/{page-96a8aa2ec30a44e9.js → page-fe35d61f14b90a51.js} +0 -0
  138. /package/.next/static/{8o5rUyZun0GklIHWDgkmv → gRNW5YXY43KqCKbCdaJoJ}/_buildManifest.js +0 -0
  139. /package/.next/static/{8o5rUyZun0GklIHWDgkmv → gRNW5YXY43KqCKbCdaJoJ}/_ssgManifest.js +0 -0
@@ -0,0 +1,163 @@
1
+ "use strict";
2
+ /**
3
+ * Input Validators
4
+ * Issue #136: Phase 1 - Foundation
5
+ *
6
+ * Provides input validation functions for worktree-related operations.
7
+ * These validators are critical for security (command injection prevention).
8
+ *
9
+ * @module input-validators
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.MAX_BRANCH_NAME_LENGTH = exports.BRANCH_NAME_PATTERN = exports.MAX_ISSUE_NO = void 0;
13
+ exports.validateIssueNo = validateIssueNo;
14
+ exports.validateBranchName = validateBranchName;
15
+ exports.validatePortNumber = validatePortNumber;
16
+ exports.isValidIssueNo = isValidIssueNo;
17
+ exports.validateIssueNoResult = validateIssueNoResult;
18
+ exports.isValidBranchName = isValidBranchName;
19
+ /**
20
+ * Maximum allowed issue number (2^31 - 1)
21
+ * NTH-SEC-002: Prevent integer overflow
22
+ */
23
+ exports.MAX_ISSUE_NO = 2147483647;
24
+ /**
25
+ * Branch name whitelist pattern
26
+ * MF-SEC-001: Only allow safe characters to prevent command injection
27
+ * Allowed: a-z, A-Z, 0-9, underscore, hyphen, forward slash
28
+ */
29
+ exports.BRANCH_NAME_PATTERN = /^[a-zA-Z0-9_/-]+$/;
30
+ /**
31
+ * Maximum branch name length
32
+ * Prevents DoS via overly long input
33
+ */
34
+ exports.MAX_BRANCH_NAME_LENGTH = 255;
35
+ /**
36
+ * Validate issue number
37
+ * SEC-001: Strict positive integer validation
38
+ *
39
+ * @param issueNo - The issue number to validate
40
+ * @throws Error with code 'INVALID_ISSUE_NO' if not a valid integer
41
+ * @throws Error with code 'ISSUE_NO_OUT_OF_RANGE' if out of range
42
+ *
43
+ * @example
44
+ * ```typescript
45
+ * validateIssueNo(135); // OK
46
+ * validateIssueNo('135'); // throws INVALID_ISSUE_NO
47
+ * validateIssueNo(-1); // throws ISSUE_NO_OUT_OF_RANGE
48
+ * ```
49
+ */
50
+ function validateIssueNo(issueNo) {
51
+ if (typeof issueNo !== 'number' ||
52
+ !Number.isInteger(issueNo) ||
53
+ !Number.isFinite(issueNo)) {
54
+ throw new Error('INVALID_ISSUE_NO');
55
+ }
56
+ if (issueNo <= 0 || issueNo > exports.MAX_ISSUE_NO) {
57
+ throw new Error('ISSUE_NO_OUT_OF_RANGE');
58
+ }
59
+ }
60
+ /**
61
+ * Validate branch name
62
+ * MF-SEC-001: Whitelist validation to prevent command injection
63
+ *
64
+ * @param branchName - The branch name to validate
65
+ * @throws Error with code 'INVALID_BRANCH_NAME' if contains invalid characters
66
+ * @throws Error with code 'BRANCH_NAME_TOO_LONG' if exceeds max length
67
+ *
68
+ * @example
69
+ * ```typescript
70
+ * validateBranchName('feature/136-worktree'); // OK
71
+ * validateBranchName('feature`rm -rf /`'); // throws INVALID_BRANCH_NAME
72
+ * ```
73
+ */
74
+ function validateBranchName(branchName) {
75
+ if (!branchName || !exports.BRANCH_NAME_PATTERN.test(branchName)) {
76
+ throw new Error('INVALID_BRANCH_NAME');
77
+ }
78
+ if (branchName.length > exports.MAX_BRANCH_NAME_LENGTH) {
79
+ throw new Error('BRANCH_NAME_TOO_LONG');
80
+ }
81
+ }
82
+ /**
83
+ * Validate port number
84
+ * SEC-003: Port validation for worktree servers
85
+ *
86
+ * @param port - The port number to validate
87
+ * @param minPort - Minimum allowed port (default: 1024, non-privileged)
88
+ * @param maxPort - Maximum allowed port (default: 65535)
89
+ * @throws Error with code 'INVALID_PORT' if not a valid port number
90
+ *
91
+ * @example
92
+ * ```typescript
93
+ * validatePortNumber(3001); // OK
94
+ * validatePortNumber(80); // throws INVALID_PORT (privileged)
95
+ * ```
96
+ */
97
+ function validatePortNumber(port, minPort = 1024, maxPort = 65535) {
98
+ if (typeof port !== 'number' ||
99
+ !Number.isInteger(port) ||
100
+ !Number.isFinite(port)) {
101
+ throw new Error('INVALID_PORT');
102
+ }
103
+ if (port < minPort || port > maxPort) {
104
+ throw new Error('INVALID_PORT');
105
+ }
106
+ }
107
+ /**
108
+ * Type guard for checking if a value is a valid issue number
109
+ *
110
+ * @param value - Value to check
111
+ * @returns true if value is a valid issue number
112
+ */
113
+ function isValidIssueNo(value) {
114
+ try {
115
+ validateIssueNo(value);
116
+ return true;
117
+ }
118
+ catch {
119
+ return false;
120
+ }
121
+ }
122
+ /**
123
+ * Validate issue number and return result (for CLI commands)
124
+ * Issue #136: CLI-friendly validation that returns result instead of throwing
125
+ *
126
+ * @param issueNo - The issue number to validate
127
+ * @returns Validation result with error message if invalid
128
+ */
129
+ function validateIssueNoResult(issueNo) {
130
+ try {
131
+ validateIssueNo(issueNo);
132
+ return { valid: true };
133
+ }
134
+ catch (error) {
135
+ const message = error instanceof Error ? error.message : String(error);
136
+ switch (message) {
137
+ case 'INVALID_ISSUE_NO':
138
+ return { valid: false, error: 'Issue number must be a positive integer' };
139
+ case 'ISSUE_NO_OUT_OF_RANGE':
140
+ return { valid: false, error: `Issue number must be between 1 and ${exports.MAX_ISSUE_NO}` };
141
+ default:
142
+ return { valid: false, error: 'Invalid issue number' };
143
+ }
144
+ }
145
+ }
146
+ /**
147
+ * Type guard for checking if a value is a valid branch name
148
+ *
149
+ * @param value - Value to check
150
+ * @returns true if value is a valid branch name
151
+ */
152
+ function isValidBranchName(value) {
153
+ if (typeof value !== 'string') {
154
+ return false;
155
+ }
156
+ try {
157
+ validateBranchName(value);
158
+ return true;
159
+ }
160
+ catch {
161
+ return false;
162
+ }
163
+ }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Install Context Utility
3
+ * Issue #136: DRY refactoring - extract common install detection functions
4
+ *
5
+ * This module provides centralized functions for detecting the install type
6
+ * (global vs local npm install) and resolving configuration directories.
7
+ *
8
+ * Extracted from env-setup.ts to solve circular import issues and follow DRY principle.
9
+ *
10
+ * @module install-context
11
+ */
12
+ /**
13
+ * Check if running as global npm package
14
+ * Issue #119: Determine .env location based on install type
15
+ * Issue #136: Extracted to avoid circular imports
16
+ *
17
+ * @returns true if running as global npm package
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * if (isGlobalInstall()) {
22
+ * // Use ~/.commandmate for config
23
+ * } else {
24
+ * // Use current working directory
25
+ * }
26
+ * ```
27
+ */
28
+ export declare function isGlobalInstall(): boolean;
29
+ /**
30
+ * Get the config directory path
31
+ * Issue #119: Returns ~/.commandmate for global, cwd for local
32
+ * Issue #125: Added symlink resolution for security (path traversal protection)
33
+ * Issue #136: Extracted to avoid circular imports
34
+ *
35
+ * @returns Path to config directory (absolute, with symlinks resolved)
36
+ * @throws Error if config directory resolves outside home directory (for global install)
37
+ *
38
+ * @example
39
+ * ```typescript
40
+ * const configDir = getConfigDir();
41
+ * // Global: /Users/username/.commandmate
42
+ * // Local: /path/to/project (resolved from symlinks)
43
+ * ```
44
+ */
45
+ export declare function getConfigDir(): string;
46
+ /**
47
+ * Ensure the config directory exists with proper permissions
48
+ * Issue #136: Utility for creating config directory if needed
49
+ *
50
+ * @returns Path to config directory (created if needed)
51
+ */
52
+ export declare function ensureConfigDir(): string;
53
+ //# sourceMappingURL=install-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-context.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/install-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAYzC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAqBrC;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAUxC"}
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ /**
3
+ * Install Context Utility
4
+ * Issue #136: DRY refactoring - extract common install detection functions
5
+ *
6
+ * This module provides centralized functions for detecting the install type
7
+ * (global vs local npm install) and resolving configuration directories.
8
+ *
9
+ * Extracted from env-setup.ts to solve circular import issues and follow DRY principle.
10
+ *
11
+ * @module install-context
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.isGlobalInstall = isGlobalInstall;
15
+ exports.getConfigDir = getConfigDir;
16
+ exports.ensureConfigDir = ensureConfigDir;
17
+ const fs_1 = require("fs");
18
+ const path_1 = require("path");
19
+ const os_1 = require("os");
20
+ /**
21
+ * Check if running as global npm package
22
+ * Issue #119: Determine .env location based on install type
23
+ * Issue #136: Extracted to avoid circular imports
24
+ *
25
+ * @returns true if running as global npm package
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * if (isGlobalInstall()) {
30
+ * // Use ~/.commandmate for config
31
+ * } else {
32
+ * // Use current working directory
33
+ * }
34
+ * ```
35
+ */
36
+ function isGlobalInstall() {
37
+ // Check if running from global node_modules
38
+ // Global installs typically have paths like:
39
+ // - /usr/local/lib/node_modules/
40
+ // - /Users/xxx/.npm-global/lib/node_modules/
41
+ // - C:\Users\xxx\AppData\Roaming\npm\node_modules\
42
+ const currentPath = (0, path_1.dirname)(__dirname);
43
+ return (currentPath.includes('/lib/node_modules/') ||
44
+ currentPath.includes('\\node_modules\\') ||
45
+ currentPath.includes('/node_modules/commandmate'));
46
+ }
47
+ /**
48
+ * Get the config directory path
49
+ * Issue #119: Returns ~/.commandmate for global, cwd for local
50
+ * Issue #125: Added symlink resolution for security (path traversal protection)
51
+ * Issue #136: Extracted to avoid circular imports
52
+ *
53
+ * @returns Path to config directory (absolute, with symlinks resolved)
54
+ * @throws Error if config directory resolves outside home directory (for global install)
55
+ *
56
+ * @example
57
+ * ```typescript
58
+ * const configDir = getConfigDir();
59
+ * // Global: /Users/username/.commandmate
60
+ * // Local: /path/to/project (resolved from symlinks)
61
+ * ```
62
+ */
63
+ function getConfigDir() {
64
+ if (isGlobalInstall()) {
65
+ const configDir = (0, path_1.join)((0, os_1.homedir)(), '.commandmate');
66
+ // Verify config directory is within home directory (security check)
67
+ // Only validate if the directory exists (it may not exist yet during init)
68
+ if ((0, fs_1.existsSync)(configDir)) {
69
+ const realPath = (0, fs_1.realpathSync)(configDir);
70
+ const realHome = (0, fs_1.realpathSync)((0, os_1.homedir)());
71
+ if (!realPath.startsWith(realHome)) {
72
+ throw new Error(`Security error: Config directory ${configDir} is outside home directory`);
73
+ }
74
+ return realPath;
75
+ }
76
+ return configDir;
77
+ }
78
+ // Local install - resolve symlinks in cwd
79
+ const cwd = process.cwd();
80
+ return (0, fs_1.realpathSync)(cwd);
81
+ }
82
+ /**
83
+ * Ensure the config directory exists with proper permissions
84
+ * Issue #136: Utility for creating config directory if needed
85
+ *
86
+ * @returns Path to config directory (created if needed)
87
+ */
88
+ function ensureConfigDir() {
89
+ const configDir = isGlobalInstall()
90
+ ? (0, path_1.join)((0, os_1.homedir)(), '.commandmate')
91
+ : process.cwd();
92
+ if (!(0, fs_1.existsSync)(configDir)) {
93
+ (0, fs_1.mkdirSync)(configDir, { recursive: true, mode: 0o700 });
94
+ }
95
+ return getConfigDir();
96
+ }
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * PID File Manager
3
3
  * Issue #96: npm install CLI support
4
+ * Issue #136: Phase 2 - Task 2.4 - Added factory functions for Issue number support
4
5
  * SF-1: SRP - Separated from daemon.ts for single responsibility
5
6
  * MF-SEC-2: TOCTOU protection with O_EXCL atomic writes
6
7
  */
@@ -39,4 +40,37 @@ export declare class PidManager {
39
40
  */
40
41
  isProcessRunning(): boolean;
41
42
  }
43
+ /**
44
+ * Factory function to create PidManager instance
45
+ * Issue #136: Uses PidPathResolver for path resolution
46
+ *
47
+ * @param issueNo - Optional issue number for worktree-specific PID
48
+ * @returns PidManager instance
49
+ *
50
+ * @example
51
+ * ```typescript
52
+ * // Main server PID manager
53
+ * const mainManager = createPidManager();
54
+ *
55
+ * // Worktree-specific PID manager
56
+ * const issueManager = createPidManager(135);
57
+ * ```
58
+ */
59
+ export declare function createPidManager(issueNo?: number): PidManager;
60
+ /**
61
+ * Factory function to create PidManager for a specific issue
62
+ * Issue #136: Convenience function for worktree PID management
63
+ *
64
+ * @param issueNo - Issue number
65
+ * @returns PidManager instance for the specified issue
66
+ *
67
+ * @example
68
+ * ```typescript
69
+ * const manager = createIssuePidManager(135);
70
+ * if (manager.isProcessRunning()) {
71
+ * console.log('Worktree server for issue #135 is running');
72
+ * }
73
+ * ```
74
+ */
75
+ export declare function createIssuePidManager(issueNo: number): PidManager;
42
76
  //# sourceMappingURL=pid-manager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pid-manager.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/pid-manager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH;;GAEG;AACH,qBAAa,UAAU;IACT,OAAO,CAAC,QAAQ,CAAC,WAAW;gBAAX,WAAW,EAAE,MAAM;IAEhD;;OAEG;IACH,MAAM,IAAI,OAAO;IAIjB;;;OAGG;IACH,OAAO,IAAI,MAAM,GAAG,IAAI;IAmBxB;;;;;;OAMG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAwB9B;;OAEG;IACH,SAAS,IAAI,IAAI;IAUjB;;;;;OAKG;IACH,gBAAgB,IAAI,OAAO;CAmB5B"}
1
+ {"version":3,"file":"pid-manager.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/pid-manager.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAaH;;GAEG;AACH,qBAAa,UAAU;IACT,OAAO,CAAC,QAAQ,CAAC,WAAW;gBAAX,WAAW,EAAE,MAAM;IAEhD;;OAEG;IACH,MAAM,IAAI,OAAO;IAIjB;;;OAGG;IACH,OAAO,IAAI,MAAM,GAAG,IAAI;IAmBxB;;;;;;OAMG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAwB9B;;OAEG;IACH,SAAS,IAAI,IAAI;IAUjB;;;;;OAKG;IACH,gBAAgB,IAAI,OAAO;CAmB5B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,UAAU,CAI7D;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,CAEjE"}
@@ -2,12 +2,16 @@
2
2
  /**
3
3
  * PID File Manager
4
4
  * Issue #96: npm install CLI support
5
+ * Issue #136: Phase 2 - Task 2.4 - Added factory functions for Issue number support
5
6
  * SF-1: SRP - Separated from daemon.ts for single responsibility
6
7
  * MF-SEC-2: TOCTOU protection with O_EXCL atomic writes
7
8
  */
8
9
  Object.defineProperty(exports, "__esModule", { value: true });
9
10
  exports.PidManager = void 0;
11
+ exports.createPidManager = createPidManager;
12
+ exports.createIssuePidManager = createIssuePidManager;
10
13
  const fs_1 = require("fs");
14
+ const resource_resolvers_1 = require("./resource-resolvers");
11
15
  /**
12
16
  * PID file manager for daemon process tracking
13
17
  */
@@ -109,3 +113,42 @@ class PidManager {
109
113
  }
110
114
  }
111
115
  exports.PidManager = PidManager;
116
+ /**
117
+ * Factory function to create PidManager instance
118
+ * Issue #136: Uses PidPathResolver for path resolution
119
+ *
120
+ * @param issueNo - Optional issue number for worktree-specific PID
121
+ * @returns PidManager instance
122
+ *
123
+ * @example
124
+ * ```typescript
125
+ * // Main server PID manager
126
+ * const mainManager = createPidManager();
127
+ *
128
+ * // Worktree-specific PID manager
129
+ * const issueManager = createPidManager(135);
130
+ * ```
131
+ */
132
+ function createPidManager(issueNo) {
133
+ const resolver = new resource_resolvers_1.PidPathResolver();
134
+ const pidPath = resolver.resolve(issueNo);
135
+ return new PidManager(pidPath);
136
+ }
137
+ /**
138
+ * Factory function to create PidManager for a specific issue
139
+ * Issue #136: Convenience function for worktree PID management
140
+ *
141
+ * @param issueNo - Issue number
142
+ * @returns PidManager instance for the specified issue
143
+ *
144
+ * @example
145
+ * ```typescript
146
+ * const manager = createIssuePidManager(135);
147
+ * if (manager.isProcessRunning()) {
148
+ * console.log('Worktree server for issue #135 is running');
149
+ * }
150
+ * ```
151
+ */
152
+ function createIssuePidManager(issueNo) {
153
+ return createPidManager(issueNo);
154
+ }
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Port Allocator
3
+ * Issue #136: Phase 1 - Foundation
4
+ *
5
+ * Provides automatic port allocation for worktree servers.
6
+ * SF-SEC-002: Implements MAX_WORKTREES limit to prevent port exhaustion attacks.
7
+ *
8
+ * @module port-allocator
9
+ */
10
+ /**
11
+ * Default port range for worktree servers
12
+ * Main server uses 3000, worktrees use 3001-3100
13
+ */
14
+ export declare const DEFAULT_PORT_RANGE: {
15
+ readonly min: 3001;
16
+ readonly max: 3100;
17
+ };
18
+ /**
19
+ * Maximum number of concurrent worktree servers
20
+ * SF-SEC-002: Prevents port exhaustion attacks
21
+ */
22
+ export declare const MAX_WORKTREES = 10;
23
+ /**
24
+ * Port range configuration
25
+ */
26
+ export interface PortRange {
27
+ min: number;
28
+ max: number;
29
+ }
30
+ /**
31
+ * Port allocator for managing worktree server ports
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * const allocator = new PortAllocator();
36
+ * const port = await allocator.findAvailablePort();
37
+ * allocator.markAllocated(port);
38
+ * // ... start server on port ...
39
+ * allocator.release(port);
40
+ * ```
41
+ */
42
+ export declare class PortAllocator {
43
+ private static instance;
44
+ private readonly range;
45
+ private readonly allocatedPorts;
46
+ private readonly issuePortMap;
47
+ constructor(range?: PortRange);
48
+ /**
49
+ * Get singleton instance
50
+ * Issue #136: Singleton pattern for CLI commands
51
+ */
52
+ static getInstance(): PortAllocator;
53
+ /**
54
+ * Allocate a port for a specific issue (synchronous, deterministic)
55
+ * Issue #136: Simple port allocation based on issue number
56
+ *
57
+ * @param issueNo - Issue number
58
+ * @returns Allocated port number
59
+ */
60
+ allocate(issueNo: number): number;
61
+ /**
62
+ * Find an available port in the configured range
63
+ *
64
+ * @returns Available port number
65
+ * @throws AppError with code PORT_EXHAUSTED if no ports available
66
+ * @throws AppError with code MAX_WORKTREES_EXCEEDED if limit reached
67
+ */
68
+ findAvailablePort(): Promise<number>;
69
+ /**
70
+ * Check if a specific port is available
71
+ *
72
+ * @param port - Port number to check
73
+ * @returns true if port is available
74
+ */
75
+ isPortAvailable(port: number): Promise<boolean>;
76
+ /**
77
+ * Mark a port as allocated
78
+ *
79
+ * @param port - Port number to mark as allocated
80
+ */
81
+ markAllocated(port: number): void;
82
+ /**
83
+ * Release an allocated port
84
+ *
85
+ * @param port - Port number to release
86
+ */
87
+ release(port: number): void;
88
+ /**
89
+ * Get the count of allocated ports
90
+ */
91
+ getAllocatedCount(): number;
92
+ /**
93
+ * Check if a port is currently allocated (in-memory tracking)
94
+ *
95
+ * @param port - Port number to check
96
+ * @returns true if port is allocated
97
+ */
98
+ isAllocated(port: number): boolean;
99
+ /**
100
+ * Get all allocated ports
101
+ */
102
+ getAllocatedPorts(): number[];
103
+ }
104
+ /**
105
+ * Create a port allocator with default settings
106
+ */
107
+ export declare function createPortAllocator(range?: PortRange): PortAllocator;
108
+ //# sourceMappingURL=port-allocator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"port-allocator.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/port-allocator.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH;;;GAGG;AACH,eAAO,MAAM,kBAAkB;;;CAGrB,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,aAAa,KAAK,CAAC;AAEhC;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA8B;IACrD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAY;IAClC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAc;IAC7C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsB;gBAEvC,KAAK,GAAE,SAA8B;IAMjD;;;OAGG;IACH,MAAM,CAAC,WAAW,IAAI,aAAa;IAOnC;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAcjC;;;;;;OAMG;IACG,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC;IA4B1C;;;;;OAKG;IACG,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAgBrD;;;;OAIG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIjC;;;;OAIG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI3B;;OAEG;IACH,iBAAiB,IAAI,MAAM;IAI3B;;;;;OAKG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIlC;;OAEG;IACH,iBAAiB,IAAI,MAAM,EAAE;CAG9B;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,CAAC,EAAE,SAAS,GAAG,aAAa,CAEpE"}