episoda 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/dist/commands/auth.d.ts +22 -0
  2. package/dist/commands/auth.d.ts.map +1 -0
  3. package/dist/commands/auth.js +384 -0
  4. package/dist/commands/auth.js.map +1 -0
  5. package/dist/commands/dev.d.ts +20 -0
  6. package/dist/commands/dev.d.ts.map +1 -0
  7. package/dist/commands/dev.js +305 -0
  8. package/dist/commands/dev.js.map +1 -0
  9. package/dist/commands/status.d.ts +9 -0
  10. package/dist/commands/status.d.ts.map +1 -0
  11. package/dist/commands/status.js +75 -0
  12. package/dist/commands/status.js.map +1 -0
  13. package/dist/commands/stop.d.ts +17 -0
  14. package/dist/commands/stop.d.ts.map +1 -0
  15. package/dist/commands/stop.js +81 -0
  16. package/dist/commands/stop.js.map +1 -0
  17. package/dist/core/auth.d.ts +26 -0
  18. package/dist/core/auth.d.ts.map +1 -0
  19. package/dist/core/auth.js +113 -0
  20. package/dist/core/auth.js.map +1 -0
  21. package/dist/core/command-protocol.d.ts +262 -0
  22. package/dist/core/command-protocol.d.ts.map +1 -0
  23. package/dist/core/command-protocol.js +13 -0
  24. package/dist/core/command-protocol.js.map +1 -0
  25. package/dist/core/connection-manager.d.ts +58 -0
  26. package/dist/core/connection-manager.d.ts.map +1 -0
  27. package/dist/core/connection-manager.js +215 -0
  28. package/dist/core/connection-manager.js.map +1 -0
  29. package/dist/core/errors.d.ts +18 -0
  30. package/dist/core/errors.d.ts.map +1 -0
  31. package/dist/core/errors.js +55 -0
  32. package/dist/core/errors.js.map +1 -0
  33. package/dist/core/git-executor.d.ts +157 -0
  34. package/dist/core/git-executor.d.ts.map +1 -0
  35. package/dist/core/git-executor.js +1605 -0
  36. package/dist/core/git-executor.js.map +1 -0
  37. package/dist/core/git-parser.d.ts +40 -0
  38. package/dist/core/git-parser.d.ts.map +1 -0
  39. package/dist/core/git-parser.js +194 -0
  40. package/dist/core/git-parser.js.map +1 -0
  41. package/dist/core/git-validator.d.ts +42 -0
  42. package/dist/core/git-validator.d.ts.map +1 -0
  43. package/dist/core/git-validator.js +102 -0
  44. package/dist/core/git-validator.js.map +1 -0
  45. package/dist/core/index.d.ts +17 -0
  46. package/dist/core/index.d.ts.map +1 -0
  47. package/dist/core/index.js +41 -0
  48. package/dist/core/index.js.map +1 -0
  49. package/dist/core/version.d.ts +9 -0
  50. package/dist/core/version.d.ts.map +1 -0
  51. package/dist/core/version.js +19 -0
  52. package/dist/core/version.js.map +1 -0
  53. package/dist/core/websocket-client.d.ts +122 -0
  54. package/dist/core/websocket-client.d.ts.map +1 -0
  55. package/dist/core/websocket-client.js +438 -0
  56. package/dist/core/websocket-client.js.map +1 -0
  57. package/dist/daemon/daemon-manager.d.ts +71 -0
  58. package/dist/daemon/daemon-manager.d.ts.map +1 -0
  59. package/dist/daemon/daemon-manager.js +289 -0
  60. package/dist/daemon/daemon-manager.js.map +1 -0
  61. package/dist/daemon/daemon-process.d.ts +13 -0
  62. package/dist/daemon/daemon-process.d.ts.map +1 -0
  63. package/dist/daemon/daemon-process.js +608 -0
  64. package/dist/daemon/daemon-process.js.map +1 -0
  65. package/dist/daemon/machine-id.d.ts +36 -0
  66. package/dist/daemon/machine-id.d.ts.map +1 -0
  67. package/dist/daemon/machine-id.js +195 -0
  68. package/dist/daemon/machine-id.js.map +1 -0
  69. package/dist/daemon/project-tracker.d.ts +92 -0
  70. package/dist/daemon/project-tracker.d.ts.map +1 -0
  71. package/dist/daemon/project-tracker.js +259 -0
  72. package/dist/daemon/project-tracker.js.map +1 -0
  73. package/dist/dev-wrapper.d.ts +88 -0
  74. package/dist/dev-wrapper.d.ts.map +1 -0
  75. package/dist/dev-wrapper.js +288 -0
  76. package/dist/dev-wrapper.js.map +1 -0
  77. package/dist/framework-detector.d.ts +29 -0
  78. package/dist/framework-detector.d.ts.map +1 -0
  79. package/dist/framework-detector.js +276 -0
  80. package/dist/framework-detector.js.map +1 -0
  81. package/dist/git-helpers/git-credential-helper.d.ts +29 -0
  82. package/dist/git-helpers/git-credential-helper.d.ts.map +1 -0
  83. package/dist/git-helpers/git-credential-helper.js +349 -0
  84. package/dist/git-helpers/git-credential-helper.js.map +1 -0
  85. package/dist/hooks/post-checkout +296 -0
  86. package/dist/hooks/pre-commit +139 -0
  87. package/dist/index.d.ts +8 -0
  88. package/dist/index.d.ts.map +1 -0
  89. package/dist/index.js +102 -0
  90. package/dist/index.js.map +1 -0
  91. package/dist/ipc/ipc-client.d.ts +95 -0
  92. package/dist/ipc/ipc-client.d.ts.map +1 -0
  93. package/dist/ipc/ipc-client.js +204 -0
  94. package/dist/ipc/ipc-client.js.map +1 -0
  95. package/dist/ipc/ipc-server.d.ts +55 -0
  96. package/dist/ipc/ipc-server.d.ts.map +1 -0
  97. package/dist/ipc/ipc-server.js +177 -0
  98. package/dist/ipc/ipc-server.js.map +1 -0
  99. package/dist/output.d.ts +48 -0
  100. package/dist/output.d.ts.map +1 -0
  101. package/dist/output.js +129 -0
  102. package/dist/output.js.map +1 -0
  103. package/dist/utils/port-check.d.ts +15 -0
  104. package/dist/utils/port-check.d.ts.map +1 -0
  105. package/dist/utils/port-check.js +79 -0
  106. package/dist/utils/port-check.js.map +1 -0
  107. package/dist/utils/update-checker.d.ts +23 -0
  108. package/dist/utils/update-checker.d.ts.map +1 -0
  109. package/dist/utils/update-checker.js +95 -0
  110. package/dist/utils/update-checker.js.map +1 -0
  111. package/package.json +51 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"machine-id.d.ts","sourceRoot":"","sources":["../../src/daemon/machine-id.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AASH;;;;;;;GAOG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CA+BpD;AAkFD;;;;;;;GAOG;AACH,wBAAgB,cAAc,IAAI,IAAI,CASrC"}
@@ -0,0 +1,195 @@
1
+ "use strict";
2
+ /**
3
+ * Machine ID generation and management
4
+ *
5
+ * Generates a stable machine identifier used for multi-machine connection tracking.
6
+ * Format: {hostname}-{hardware-uuid-prefix}
7
+ * Example: "Alans-MacBook-Pro-a3f2b1c4"
8
+ *
9
+ * EP731: Uses hardware UUID instead of random UUID to prevent duplicate device
10
+ * registrations when ~/.episoda syncs between devices via iCloud/Dropbox.
11
+ *
12
+ * Properties:
13
+ * - Stable across daemon restarts
14
+ * - Unique per PHYSICAL machine (uses hardware UUID)
15
+ * - Human-readable (includes hostname)
16
+ * - Survives OS reboots
17
+ * - Cannot sync between devices (hardware-based)
18
+ */
19
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
20
+ if (k2 === undefined) k2 = k;
21
+ var desc = Object.getOwnPropertyDescriptor(m, k);
22
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
23
+ desc = { enumerable: true, get: function() { return m[k]; } };
24
+ }
25
+ Object.defineProperty(o, k2, desc);
26
+ }) : (function(o, m, k, k2) {
27
+ if (k2 === undefined) k2 = k;
28
+ o[k2] = m[k];
29
+ }));
30
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
31
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
32
+ }) : function(o, v) {
33
+ o["default"] = v;
34
+ });
35
+ var __importStar = (this && this.__importStar) || (function () {
36
+ var ownKeys = function(o) {
37
+ ownKeys = Object.getOwnPropertyNames || function (o) {
38
+ var ar = [];
39
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
40
+ return ar;
41
+ };
42
+ return ownKeys(o);
43
+ };
44
+ return function (mod) {
45
+ if (mod && mod.__esModule) return mod;
46
+ var result = {};
47
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
48
+ __setModuleDefault(result, mod);
49
+ return result;
50
+ };
51
+ })();
52
+ Object.defineProperty(exports, "__esModule", { value: true });
53
+ exports.getMachineId = getMachineId;
54
+ exports.resetMachineId = resetMachineId;
55
+ const os = __importStar(require("os"));
56
+ const fs = __importStar(require("fs"));
57
+ const path = __importStar(require("path"));
58
+ const crypto = __importStar(require("crypto"));
59
+ const child_process_1 = require("child_process");
60
+ const core_1 = require("../core");
61
+ /**
62
+ * Get or generate machine ID
63
+ *
64
+ * Reads from config directory's machine-id if exists, otherwise generates new one
65
+ * and saves it for future use.
66
+ *
67
+ * @returns Machine ID string
68
+ */
69
+ async function getMachineId() {
70
+ const machineIdPath = path.join((0, core_1.getConfigDir)(), 'machine-id');
71
+ // Try to read existing machine ID
72
+ try {
73
+ if (fs.existsSync(machineIdPath)) {
74
+ const machineId = fs.readFileSync(machineIdPath, 'utf-8').trim();
75
+ if (machineId) {
76
+ return machineId;
77
+ }
78
+ }
79
+ }
80
+ catch (error) {
81
+ // File doesn't exist or can't be read, generate new one
82
+ }
83
+ // Generate new machine ID
84
+ const machineId = generateMachineId();
85
+ // Save to file
86
+ try {
87
+ const dir = path.dirname(machineIdPath);
88
+ if (!fs.existsSync(dir)) {
89
+ fs.mkdirSync(dir, { recursive: true });
90
+ }
91
+ fs.writeFileSync(machineIdPath, machineId, 'utf-8');
92
+ }
93
+ catch (error) {
94
+ console.error('Warning: Could not save machine ID to disk:', error);
95
+ // Continue anyway - machine ID will be regenerated next time
96
+ }
97
+ return machineId;
98
+ }
99
+ /**
100
+ * EP731: Get hardware UUID for the current machine
101
+ *
102
+ * Uses platform-specific methods to get a hardware identifier that is:
103
+ * - Unique per physical machine
104
+ * - Stable across reboots
105
+ * - Cannot sync between devices
106
+ *
107
+ * Falls back to random UUID if hardware UUID cannot be obtained.
108
+ *
109
+ * @returns Hardware UUID string
110
+ */
111
+ function getHardwareUUID() {
112
+ try {
113
+ if (process.platform === 'darwin') {
114
+ // macOS: Get IOPlatformUUID from ioreg
115
+ const output = (0, child_process_1.execSync)('ioreg -d2 -c IOPlatformExpertDevice | awk -F\\" \'/IOPlatformUUID/{print $(NF-1)}\'', { encoding: 'utf-8', timeout: 5000 }).trim();
116
+ if (output && output.length > 0) {
117
+ return output;
118
+ }
119
+ }
120
+ else if (process.platform === 'linux') {
121
+ // Linux: Read /etc/machine-id
122
+ if (fs.existsSync('/etc/machine-id')) {
123
+ const machineId = fs.readFileSync('/etc/machine-id', 'utf-8').trim();
124
+ if (machineId && machineId.length > 0) {
125
+ return machineId;
126
+ }
127
+ }
128
+ // Fallback: Try /var/lib/dbus/machine-id
129
+ if (fs.existsSync('/var/lib/dbus/machine-id')) {
130
+ const dbusId = fs.readFileSync('/var/lib/dbus/machine-id', 'utf-8').trim();
131
+ if (dbusId && dbusId.length > 0) {
132
+ return dbusId;
133
+ }
134
+ }
135
+ }
136
+ else if (process.platform === 'win32') {
137
+ // Windows: Get UUID from wmic
138
+ const output = (0, child_process_1.execSync)('wmic csproduct get uuid', {
139
+ encoding: 'utf-8',
140
+ timeout: 5000
141
+ });
142
+ const lines = output.trim().split('\n');
143
+ if (lines.length >= 2) {
144
+ const uuid = lines[1].trim();
145
+ if (uuid && uuid.length > 0 && uuid !== 'UUID') {
146
+ return uuid;
147
+ }
148
+ }
149
+ }
150
+ }
151
+ catch (error) {
152
+ // Hardware UUID retrieval failed, will fall back to random
153
+ console.warn('Could not get hardware UUID, using random fallback:', error);
154
+ }
155
+ // Fallback: Generate random UUID
156
+ return crypto.randomUUID();
157
+ }
158
+ /**
159
+ * Generate a new machine ID
160
+ *
161
+ * EP731: Uses hardware UUID instead of random UUID to ensure uniqueness
162
+ * per physical machine, even if ~/.episoda syncs between devices.
163
+ *
164
+ * Format: {hostname}-{8-char-hardware-uuid}
165
+ * Example: "Alans-MacBook-Pro-a3f2b1c4"
166
+ *
167
+ * @returns Generated machine ID
168
+ */
169
+ function generateMachineId() {
170
+ const hostname = os.hostname();
171
+ const hwUUID = getHardwareUUID();
172
+ // Take first 8 chars of hardware UUID (or hash it if it's a long UUID)
173
+ const shortId = hwUUID.replace(/-/g, '').slice(0, 8).toLowerCase();
174
+ return `${hostname}-${shortId}`;
175
+ }
176
+ /**
177
+ * Reset machine ID (force regeneration)
178
+ *
179
+ * Deletes the stored machine ID file, forcing a new ID to be generated
180
+ * on next getMachineId() call.
181
+ *
182
+ * Use case: Developer explicitly wants to change their machine identity
183
+ */
184
+ function resetMachineId() {
185
+ const machineIdPath = path.join((0, core_1.getConfigDir)(), 'machine-id');
186
+ try {
187
+ if (fs.existsSync(machineIdPath)) {
188
+ fs.unlinkSync(machineIdPath);
189
+ }
190
+ }
191
+ catch (error) {
192
+ throw new Error(`Failed to reset machine ID: ${error}`);
193
+ }
194
+ }
195
+ //# sourceMappingURL=machine-id.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"machine-id.js","sourceRoot":"","sources":["../../src/daemon/machine-id.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Project tracking for daemon
3
+ *
4
+ * Manages ~/.episoda/projects.json which tracks all projects
5
+ * the daemon is monitoring.
6
+ *
7
+ * Format:
8
+ * {
9
+ * "projects": [
10
+ * {
11
+ * "id": "proj_abc123",
12
+ * "path": "/Users/alan/Dev/my-project",
13
+ * "name": "my-project",
14
+ * "added_at": "2025-01-18T10:30:00.000Z",
15
+ * "last_active": "2025-01-18T12:45:00.000Z"
16
+ * }
17
+ * ]
18
+ * }
19
+ */
20
+ export interface TrackedProject {
21
+ id: string;
22
+ path: string;
23
+ name: string;
24
+ added_at: string;
25
+ last_active: string;
26
+ }
27
+ /**
28
+ * Add or update a project
29
+ *
30
+ * EP593: Now enforces one entry per projectId to prevent duplicate connections.
31
+ * When adding a project:
32
+ * - If same path exists, update last_active
33
+ * - If same projectId exists with different path, REPLACE the old entry
34
+ * (user wants git operations in the new directory)
35
+ * - Otherwise, add new project
36
+ *
37
+ * @param projectId Supabase project ID
38
+ * @param projectPath Absolute path to project
39
+ * @returns The tracked project
40
+ */
41
+ export declare function addProject(projectId: string, projectPath: string): TrackedProject;
42
+ /**
43
+ * Remove a project
44
+ *
45
+ * @param projectPath Absolute path to project
46
+ * @returns true if removed, false if not found
47
+ */
48
+ export declare function removeProject(projectPath: string): boolean;
49
+ /**
50
+ * Get a project by path
51
+ *
52
+ * @param projectPath Absolute path to project
53
+ * @returns Project if found, null otherwise
54
+ */
55
+ export declare function getProject(projectPath: string): TrackedProject | null;
56
+ /**
57
+ * Get a project by ID
58
+ *
59
+ * @param projectId Supabase project ID
60
+ * @returns Project if found, null otherwise
61
+ */
62
+ export declare function getProjectById(projectId: string): TrackedProject | null;
63
+ /**
64
+ * Get all tracked projects
65
+ *
66
+ * @returns Array of tracked projects
67
+ */
68
+ export declare function getAllProjects(): TrackedProject[];
69
+ /**
70
+ * Update last active timestamp for a project
71
+ *
72
+ * @param projectPath Absolute path to project
73
+ */
74
+ export declare function touchProject(projectPath: string): void;
75
+ /**
76
+ * Clean up stale projects
77
+ *
78
+ * Removes projects that:
79
+ * - Haven't been active in N days
80
+ * - Directory no longer exists
81
+ *
82
+ * @param maxAgeDays Maximum age in days (default: 30)
83
+ * @returns Number of projects removed
84
+ */
85
+ export declare function cleanupStaleProjects(maxAgeDays?: number): number;
86
+ /**
87
+ * Clear all projects
88
+ *
89
+ * USE WITH CAUTION - removes all tracked projects
90
+ */
91
+ export declare function clearAllProjects(): void;
92
+ //# sourceMappingURL=project-tracker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-tracker.d.ts","sourceRoot":"","sources":["../../src/daemon/project-tracker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAMH,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;CACpB;AA6DD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,cAAc,CAyCjF;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAY1D;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAGrE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAGvE;AAED;;;;GAIG;AACH,wBAAgB,cAAc,IAAI,cAAc,EAAE,CAGjD;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAQtD;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,GAAE,MAAW,GAAG,MAAM,CA2BpE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC"}
@@ -0,0 +1,259 @@
1
+ "use strict";
2
+ /**
3
+ * Project tracking for daemon
4
+ *
5
+ * Manages ~/.episoda/projects.json which tracks all projects
6
+ * the daemon is monitoring.
7
+ *
8
+ * Format:
9
+ * {
10
+ * "projects": [
11
+ * {
12
+ * "id": "proj_abc123",
13
+ * "path": "/Users/alan/Dev/my-project",
14
+ * "name": "my-project",
15
+ * "added_at": "2025-01-18T10:30:00.000Z",
16
+ * "last_active": "2025-01-18T12:45:00.000Z"
17
+ * }
18
+ * ]
19
+ * }
20
+ */
21
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
22
+ if (k2 === undefined) k2 = k;
23
+ var desc = Object.getOwnPropertyDescriptor(m, k);
24
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
25
+ desc = { enumerable: true, get: function() { return m[k]; } };
26
+ }
27
+ Object.defineProperty(o, k2, desc);
28
+ }) : (function(o, m, k, k2) {
29
+ if (k2 === undefined) k2 = k;
30
+ o[k2] = m[k];
31
+ }));
32
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
33
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
34
+ }) : function(o, v) {
35
+ o["default"] = v;
36
+ });
37
+ var __importStar = (this && this.__importStar) || (function () {
38
+ var ownKeys = function(o) {
39
+ ownKeys = Object.getOwnPropertyNames || function (o) {
40
+ var ar = [];
41
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
42
+ return ar;
43
+ };
44
+ return ownKeys(o);
45
+ };
46
+ return function (mod) {
47
+ if (mod && mod.__esModule) return mod;
48
+ var result = {};
49
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
50
+ __setModuleDefault(result, mod);
51
+ return result;
52
+ };
53
+ })();
54
+ Object.defineProperty(exports, "__esModule", { value: true });
55
+ exports.addProject = addProject;
56
+ exports.removeProject = removeProject;
57
+ exports.getProject = getProject;
58
+ exports.getProjectById = getProjectById;
59
+ exports.getAllProjects = getAllProjects;
60
+ exports.touchProject = touchProject;
61
+ exports.cleanupStaleProjects = cleanupStaleProjects;
62
+ exports.clearAllProjects = clearAllProjects;
63
+ const fs = __importStar(require("fs"));
64
+ const path = __importStar(require("path"));
65
+ const core_1 = require("../core");
66
+ /**
67
+ * Get path to projects.json file
68
+ */
69
+ function getProjectsFilePath() {
70
+ return path.join((0, core_1.getConfigDir)(), 'projects.json');
71
+ }
72
+ /**
73
+ * Read projects from file
74
+ *
75
+ * @returns Projects data, or empty list if file doesn't exist
76
+ */
77
+ function readProjects() {
78
+ const projectsPath = getProjectsFilePath();
79
+ try {
80
+ if (!fs.existsSync(projectsPath)) {
81
+ return { projects: [] };
82
+ }
83
+ const content = fs.readFileSync(projectsPath, 'utf-8');
84
+ const data = JSON.parse(content);
85
+ // Validate structure
86
+ if (!data.projects || !Array.isArray(data.projects)) {
87
+ console.warn('Invalid projects.json structure, resetting');
88
+ return { projects: [] };
89
+ }
90
+ return data;
91
+ }
92
+ catch (error) {
93
+ console.error('Error reading projects.json:', error);
94
+ return { projects: [] };
95
+ }
96
+ }
97
+ /**
98
+ * Write projects to file
99
+ */
100
+ function writeProjects(data) {
101
+ const projectsPath = getProjectsFilePath();
102
+ try {
103
+ // Ensure directory exists
104
+ const dir = path.dirname(projectsPath);
105
+ if (!fs.existsSync(dir)) {
106
+ fs.mkdirSync(dir, { recursive: true });
107
+ }
108
+ fs.writeFileSync(projectsPath, JSON.stringify(data, null, 2), 'utf-8');
109
+ }
110
+ catch (error) {
111
+ throw new Error(`Failed to write projects.json: ${error}`);
112
+ }
113
+ }
114
+ /**
115
+ * Add or update a project
116
+ *
117
+ * EP593: Now enforces one entry per projectId to prevent duplicate connections.
118
+ * When adding a project:
119
+ * - If same path exists, update last_active
120
+ * - If same projectId exists with different path, REPLACE the old entry
121
+ * (user wants git operations in the new directory)
122
+ * - Otherwise, add new project
123
+ *
124
+ * @param projectId Supabase project ID
125
+ * @param projectPath Absolute path to project
126
+ * @returns The tracked project
127
+ */
128
+ function addProject(projectId, projectPath) {
129
+ const data = readProjects();
130
+ const now = new Date().toISOString();
131
+ // Check if project already exists by path (exact match)
132
+ const existingByPath = data.projects.find(p => p.path === projectPath);
133
+ if (existingByPath) {
134
+ // Update existing project
135
+ existingByPath.id = projectId; // Update ID in case it changed
136
+ existingByPath.last_active = now;
137
+ writeProjects(data);
138
+ return existingByPath;
139
+ }
140
+ // EP593: Check if project exists by ID (different path)
141
+ // This prevents multiple entries for the same project from different directories
142
+ const existingByIdIndex = data.projects.findIndex(p => p.id === projectId);
143
+ if (existingByIdIndex !== -1) {
144
+ const existingById = data.projects[existingByIdIndex];
145
+ console.log(`[ProjectTracker] Replacing project entry: ${existingById.path} -> ${projectPath}`);
146
+ // Remove the old entry
147
+ data.projects.splice(existingByIdIndex, 1);
148
+ }
149
+ // Add new project
150
+ const projectName = path.basename(projectPath);
151
+ const newProject = {
152
+ id: projectId,
153
+ path: projectPath,
154
+ name: projectName,
155
+ added_at: now,
156
+ last_active: now,
157
+ };
158
+ data.projects.push(newProject);
159
+ writeProjects(data);
160
+ return newProject;
161
+ }
162
+ /**
163
+ * Remove a project
164
+ *
165
+ * @param projectPath Absolute path to project
166
+ * @returns true if removed, false if not found
167
+ */
168
+ function removeProject(projectPath) {
169
+ const data = readProjects();
170
+ const initialLength = data.projects.length;
171
+ data.projects = data.projects.filter(p => p.path !== projectPath);
172
+ if (data.projects.length < initialLength) {
173
+ writeProjects(data);
174
+ return true;
175
+ }
176
+ return false;
177
+ }
178
+ /**
179
+ * Get a project by path
180
+ *
181
+ * @param projectPath Absolute path to project
182
+ * @returns Project if found, null otherwise
183
+ */
184
+ function getProject(projectPath) {
185
+ const data = readProjects();
186
+ return data.projects.find(p => p.path === projectPath) || null;
187
+ }
188
+ /**
189
+ * Get a project by ID
190
+ *
191
+ * @param projectId Supabase project ID
192
+ * @returns Project if found, null otherwise
193
+ */
194
+ function getProjectById(projectId) {
195
+ const data = readProjects();
196
+ return data.projects.find(p => p.id === projectId) || null;
197
+ }
198
+ /**
199
+ * Get all tracked projects
200
+ *
201
+ * @returns Array of tracked projects
202
+ */
203
+ function getAllProjects() {
204
+ const data = readProjects();
205
+ return data.projects;
206
+ }
207
+ /**
208
+ * Update last active timestamp for a project
209
+ *
210
+ * @param projectPath Absolute path to project
211
+ */
212
+ function touchProject(projectPath) {
213
+ const data = readProjects();
214
+ const project = data.projects.find(p => p.path === projectPath);
215
+ if (project) {
216
+ project.last_active = new Date().toISOString();
217
+ writeProjects(data);
218
+ }
219
+ }
220
+ /**
221
+ * Clean up stale projects
222
+ *
223
+ * Removes projects that:
224
+ * - Haven't been active in N days
225
+ * - Directory no longer exists
226
+ *
227
+ * @param maxAgeDays Maximum age in days (default: 30)
228
+ * @returns Number of projects removed
229
+ */
230
+ function cleanupStaleProjects(maxAgeDays = 30) {
231
+ const data = readProjects();
232
+ const now = Date.now();
233
+ const maxAgeMs = maxAgeDays * 24 * 60 * 60 * 1000;
234
+ const initialLength = data.projects.length;
235
+ data.projects = data.projects.filter(project => {
236
+ // Check if directory still exists
237
+ if (!fs.existsSync(project.path)) {
238
+ return false;
239
+ }
240
+ // Check if too old
241
+ const lastActive = new Date(project.last_active).getTime();
242
+ const age = now - lastActive;
243
+ return age < maxAgeMs;
244
+ });
245
+ const removedCount = initialLength - data.projects.length;
246
+ if (removedCount > 0) {
247
+ writeProjects(data);
248
+ }
249
+ return removedCount;
250
+ }
251
+ /**
252
+ * Clear all projects
253
+ *
254
+ * USE WITH CAUTION - removes all tracked projects
255
+ */
256
+ function clearAllProjects() {
257
+ writeProjects({ projects: [] });
258
+ }
259
+ //# sourceMappingURL=project-tracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-tracker.js","sourceRoot":"","sources":["../../src/daemon/project-tracker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Dev Server Wrapper
3
+ *
4
+ * This module wraps the user's dev server command and keeps it running
5
+ * while maintaining the WebSocket connection to episoda.dev
6
+ */
7
+ export interface DevServerStatus {
8
+ running: boolean;
9
+ pid?: number;
10
+ command: string[];
11
+ restartCount: number;
12
+ connectedToCloud: boolean;
13
+ }
14
+ export interface DevWrapperOptions {
15
+ command?: string[];
16
+ cwd?: string;
17
+ autoRestart?: boolean;
18
+ wsUrl?: string;
19
+ token?: string;
20
+ projectId?: string;
21
+ userId?: string;
22
+ workspaceId?: string;
23
+ apiUrl?: string;
24
+ }
25
+ /**
26
+ * DevServerWrapper class manages the dev server process and WebSocket connection
27
+ */
28
+ export declare class DevServerWrapper {
29
+ private devProcess?;
30
+ private wsClient?;
31
+ private gitExecutor;
32
+ private command?;
33
+ private cwd;
34
+ private autoRestart;
35
+ private restartCount;
36
+ private shuttingDown;
37
+ private wsUrl?;
38
+ private token?;
39
+ private projectId?;
40
+ private userId?;
41
+ private workspaceId?;
42
+ private apiUrl?;
43
+ private connectionOnlyMode;
44
+ constructor(options: DevWrapperOptions);
45
+ /**
46
+ * Start the dev server and WebSocket connection
47
+ */
48
+ start(): Promise<void>;
49
+ /**
50
+ * Start the dev server process
51
+ */
52
+ private startDevServer;
53
+ /**
54
+ * Connect to episoda.dev WebSocket
55
+ */
56
+ private connectWebSocket;
57
+ /**
58
+ * Handle git command from server
59
+ */
60
+ private handleGitCommand;
61
+ /**
62
+ * Format git command for display
63
+ */
64
+ private formatGitCommand;
65
+ /**
66
+ * Set up signal handlers for graceful shutdown
67
+ */
68
+ private setupSignalHandlers;
69
+ /**
70
+ * Gracefully shutdown dev server and WebSocket
71
+ */
72
+ shutdown(): Promise<void>;
73
+ /**
74
+ * Get current status
75
+ */
76
+ getStatus(): DevServerStatus;
77
+ }
78
+ /**
79
+ * Wrap and run a dev server command
80
+ * @param command - Command to run (e.g., ["npm", "start"])
81
+ * @param options - Additional options
82
+ */
83
+ export declare function wrapDevServer(command: string[], options?: Partial<DevWrapperOptions>): Promise<DevServerWrapper>;
84
+ /**
85
+ * Stop the wrapped dev server
86
+ */
87
+ export declare function stopDevServer(): Promise<void>;
88
+ //# sourceMappingURL=dev-wrapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev-wrapper.d.ts","sourceRoot":"","sources":["../src/dev-wrapper.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAA;IAChB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,YAAY,EAAE,MAAM,CAAA;IACpB,gBAAgB,EAAE,OAAO,CAAA;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;GAEG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,UAAU,CAAC,CAAc;IACjC,OAAO,CAAC,QAAQ,CAAC,CAAe;IAChC,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,OAAO,CAAC,CAAU;IAC1B,OAAO,CAAC,GAAG,CAAQ;IACnB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,YAAY,CAAI;IACxB,OAAO,CAAC,YAAY,CAAQ;IAC5B,OAAO,CAAC,KAAK,CAAC,CAAQ;IACtB,OAAO,CAAC,KAAK,CAAC,CAAQ;IACtB,OAAO,CAAC,SAAS,CAAC,CAAQ;IAC1B,OAAO,CAAC,MAAM,CAAC,CAAQ;IACvB,OAAO,CAAC,WAAW,CAAC,CAAQ;IAC5B,OAAO,CAAC,MAAM,CAAC,CAAQ;IACvB,OAAO,CAAC,kBAAkB,CAAS;gBAEvB,OAAO,EAAE,iBAAiB;IActC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAmB5B;;OAEG;YACW,cAAc;IAyC5B;;OAEG;YACW,gBAAgB;IAyC9B;;OAEG;YACW,gBAAgB;IAwC9B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAqBxB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAU3B;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IA8C/B;;OAEG;IACH,SAAS,IAAI,eAAe;CAS7B;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,GACnC,OAAO,CAAC,gBAAgB,CAAC,CAQ3B;AAOD;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAKnD"}