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.
- package/dist/commands/auth.d.ts +22 -0
- package/dist/commands/auth.d.ts.map +1 -0
- package/dist/commands/auth.js +384 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/dev.d.ts +20 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +305 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/status.d.ts +9 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +75 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/stop.d.ts +17 -0
- package/dist/commands/stop.d.ts.map +1 -0
- package/dist/commands/stop.js +81 -0
- package/dist/commands/stop.js.map +1 -0
- package/dist/core/auth.d.ts +26 -0
- package/dist/core/auth.d.ts.map +1 -0
- package/dist/core/auth.js +113 -0
- package/dist/core/auth.js.map +1 -0
- package/dist/core/command-protocol.d.ts +262 -0
- package/dist/core/command-protocol.d.ts.map +1 -0
- package/dist/core/command-protocol.js +13 -0
- package/dist/core/command-protocol.js.map +1 -0
- package/dist/core/connection-manager.d.ts +58 -0
- package/dist/core/connection-manager.d.ts.map +1 -0
- package/dist/core/connection-manager.js +215 -0
- package/dist/core/connection-manager.js.map +1 -0
- package/dist/core/errors.d.ts +18 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +55 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/git-executor.d.ts +157 -0
- package/dist/core/git-executor.d.ts.map +1 -0
- package/dist/core/git-executor.js +1605 -0
- package/dist/core/git-executor.js.map +1 -0
- package/dist/core/git-parser.d.ts +40 -0
- package/dist/core/git-parser.d.ts.map +1 -0
- package/dist/core/git-parser.js +194 -0
- package/dist/core/git-parser.js.map +1 -0
- package/dist/core/git-validator.d.ts +42 -0
- package/dist/core/git-validator.d.ts.map +1 -0
- package/dist/core/git-validator.js +102 -0
- package/dist/core/git-validator.js.map +1 -0
- package/dist/core/index.d.ts +17 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +41 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/version.d.ts +9 -0
- package/dist/core/version.d.ts.map +1 -0
- package/dist/core/version.js +19 -0
- package/dist/core/version.js.map +1 -0
- package/dist/core/websocket-client.d.ts +122 -0
- package/dist/core/websocket-client.d.ts.map +1 -0
- package/dist/core/websocket-client.js +438 -0
- package/dist/core/websocket-client.js.map +1 -0
- package/dist/daemon/daemon-manager.d.ts +71 -0
- package/dist/daemon/daemon-manager.d.ts.map +1 -0
- package/dist/daemon/daemon-manager.js +289 -0
- package/dist/daemon/daemon-manager.js.map +1 -0
- package/dist/daemon/daemon-process.d.ts +13 -0
- package/dist/daemon/daemon-process.d.ts.map +1 -0
- package/dist/daemon/daemon-process.js +608 -0
- package/dist/daemon/daemon-process.js.map +1 -0
- package/dist/daemon/machine-id.d.ts +36 -0
- package/dist/daemon/machine-id.d.ts.map +1 -0
- package/dist/daemon/machine-id.js +195 -0
- package/dist/daemon/machine-id.js.map +1 -0
- package/dist/daemon/project-tracker.d.ts +92 -0
- package/dist/daemon/project-tracker.d.ts.map +1 -0
- package/dist/daemon/project-tracker.js +259 -0
- package/dist/daemon/project-tracker.js.map +1 -0
- package/dist/dev-wrapper.d.ts +88 -0
- package/dist/dev-wrapper.d.ts.map +1 -0
- package/dist/dev-wrapper.js +288 -0
- package/dist/dev-wrapper.js.map +1 -0
- package/dist/framework-detector.d.ts +29 -0
- package/dist/framework-detector.d.ts.map +1 -0
- package/dist/framework-detector.js +276 -0
- package/dist/framework-detector.js.map +1 -0
- package/dist/git-helpers/git-credential-helper.d.ts +29 -0
- package/dist/git-helpers/git-credential-helper.d.ts.map +1 -0
- package/dist/git-helpers/git-credential-helper.js +349 -0
- package/dist/git-helpers/git-credential-helper.js.map +1 -0
- package/dist/hooks/post-checkout +296 -0
- package/dist/hooks/pre-commit +139 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +102 -0
- package/dist/index.js.map +1 -0
- package/dist/ipc/ipc-client.d.ts +95 -0
- package/dist/ipc/ipc-client.d.ts.map +1 -0
- package/dist/ipc/ipc-client.js +204 -0
- package/dist/ipc/ipc-client.js.map +1 -0
- package/dist/ipc/ipc-server.d.ts +55 -0
- package/dist/ipc/ipc-server.d.ts.map +1 -0
- package/dist/ipc/ipc-server.js +177 -0
- package/dist/ipc/ipc-server.js.map +1 -0
- package/dist/output.d.ts +48 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +129 -0
- package/dist/output.js.map +1 -0
- package/dist/utils/port-check.d.ts +15 -0
- package/dist/utils/port-check.d.ts.map +1 -0
- package/dist/utils/port-check.js +79 -0
- package/dist/utils/port-check.js.map +1 -0
- package/dist/utils/update-checker.d.ts +23 -0
- package/dist/utils/update-checker.d.ts.map +1 -0
- package/dist/utils/update-checker.js +95 -0
- package/dist/utils/update-checker.js.map +1 -0
- 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"}
|