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,288 @@
1
+ "use strict";
2
+ /**
3
+ * Dev Server Wrapper
4
+ *
5
+ * This module wraps the user's dev server command and keeps it running
6
+ * while maintaining the WebSocket connection to episoda.dev
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.DevServerWrapper = void 0;
10
+ exports.wrapDevServer = wrapDevServer;
11
+ exports.stopDevServer = stopDevServer;
12
+ const child_process_1 = require("child_process");
13
+ const core_1 = require("./core");
14
+ const output_1 = require("./output");
15
+ /**
16
+ * DevServerWrapper class manages the dev server process and WebSocket connection
17
+ */
18
+ class DevServerWrapper {
19
+ constructor(options) {
20
+ this.restartCount = 0;
21
+ this.shuttingDown = false;
22
+ this.command = options.command;
23
+ this.cwd = options.cwd || process.cwd();
24
+ this.autoRestart = options.autoRestart ?? false;
25
+ this.wsUrl = options.wsUrl;
26
+ this.token = options.token;
27
+ this.projectId = options.projectId;
28
+ this.userId = options.userId;
29
+ this.workspaceId = options.workspaceId;
30
+ this.apiUrl = options.apiUrl;
31
+ this.connectionOnlyMode = !options.command || options.command.length === 0;
32
+ this.gitExecutor = new core_1.GitExecutor();
33
+ }
34
+ /**
35
+ * Start the dev server and WebSocket connection
36
+ */
37
+ async start() {
38
+ // Set up signal handlers for graceful shutdown
39
+ this.setupSignalHandlers();
40
+ // Start WebSocket connection (if credentials provided)
41
+ if (this.wsUrl && this.token) {
42
+ await this.connectWebSocket();
43
+ }
44
+ // Start dev server (skip if in connection-only mode)
45
+ if (!this.connectionOnlyMode && this.command) {
46
+ await this.startDevServer();
47
+ }
48
+ else if (this.connectionOnlyMode) {
49
+ output_1.status.info('Running in connection-only mode (no dev server wrapped)');
50
+ output_1.status.info('Connection will be maintained until you press Ctrl+C');
51
+ output_1.status.info('');
52
+ }
53
+ }
54
+ /**
55
+ * Start the dev server process
56
+ */
57
+ async startDevServer() {
58
+ if (!this.command || this.command.length === 0) {
59
+ throw new Error('No command provided to start dev server');
60
+ }
61
+ output_1.status.info(`Starting dev server: ${this.command.join(' ')}`);
62
+ this.devProcess = (0, child_process_1.spawn)(this.command[0], this.command.slice(1), {
63
+ cwd: this.cwd,
64
+ stdio: ['inherit', 'inherit', 'inherit'], // Forward all stdio
65
+ shell: true
66
+ });
67
+ // Track process events
68
+ this.devProcess.on('exit', (code, signal) => {
69
+ if (this.shuttingDown) {
70
+ output_1.status.info('Dev server stopped');
71
+ return;
72
+ }
73
+ if (code === 0) {
74
+ output_1.status.success('Dev server exited successfully');
75
+ }
76
+ else {
77
+ output_1.status.error(`Dev server exited with code ${code}${signal ? ` (signal: ${signal})` : ''}`);
78
+ }
79
+ // Auto-restart if enabled
80
+ if (this.autoRestart && !this.shuttingDown) {
81
+ this.restartCount++;
82
+ output_1.status.info(`Auto-restarting dev server (attempt ${this.restartCount})...`);
83
+ setTimeout(() => {
84
+ this.startDevServer();
85
+ }, 2000); // Wait 2 seconds before restart
86
+ }
87
+ });
88
+ this.devProcess.on('error', (error) => {
89
+ output_1.status.error(`Dev server error: ${error.message}`);
90
+ });
91
+ }
92
+ /**
93
+ * Connect to episoda.dev WebSocket
94
+ */
95
+ async connectWebSocket() {
96
+ if (!this.wsUrl || !this.token) {
97
+ output_1.status.debug('WebSocket credentials not provided, skipping connection');
98
+ return;
99
+ }
100
+ try {
101
+ output_1.status.info('Connecting to episoda.dev...');
102
+ this.wsClient = new core_1.EpisodaClient();
103
+ // Set up event handlers BEFORE connecting
104
+ this.wsClient.on('command', async (event) => {
105
+ if (event.type === 'command') {
106
+ // Type narrowing: event is { type: 'command'; id: string; command: GitCommand }
107
+ const { id, command } = event;
108
+ await this.handleGitCommand(id, command);
109
+ }
110
+ });
111
+ this.wsClient.on('ping', async () => {
112
+ // Ping handled automatically by client
113
+ output_1.status.debug('Received ping from server');
114
+ });
115
+ this.wsClient.on('error', (event) => {
116
+ if (event.type === 'error') {
117
+ // Type narrowing: event is { type: 'error'; code: string; message: string }
118
+ const { message: errMsg } = event;
119
+ output_1.status.error(`WebSocket error: ${errMsg}`);
120
+ }
121
+ });
122
+ // Connect to server
123
+ await this.wsClient.connect(this.wsUrl, this.token);
124
+ output_1.status.success(`Connected to episoda.dev${this.projectId ? ` (${this.projectId})` : ''}`);
125
+ }
126
+ catch (error) {
127
+ output_1.status.warning(`Failed to connect to episoda.dev: ${error instanceof Error ? error.message : String(error)}`);
128
+ output_1.status.info('Dev server will continue running without cloud connection');
129
+ }
130
+ }
131
+ /**
132
+ * Handle git command from server
133
+ */
134
+ async handleGitCommand(commandId, command) {
135
+ try {
136
+ // Log the command
137
+ const commandStr = this.formatGitCommand(command);
138
+ (0, output_1.printGitCommand)(commandStr);
139
+ // Execute git command
140
+ const result = await this.gitExecutor.execute(command, {
141
+ cwd: this.cwd
142
+ });
143
+ // Print result
144
+ console.log((0, output_1.formatResult)(result));
145
+ // Send result back to server
146
+ if (this.wsClient) {
147
+ await this.wsClient.send({
148
+ type: 'result',
149
+ commandId,
150
+ result
151
+ });
152
+ }
153
+ }
154
+ catch (error) {
155
+ output_1.status.error(`Failed to execute git command: ${error instanceof Error ? error.message : String(error)}`);
156
+ // Send error result to server
157
+ if (this.wsClient) {
158
+ await this.wsClient.send({
159
+ type: 'result',
160
+ commandId,
161
+ result: {
162
+ success: false,
163
+ error: 'UNKNOWN_ERROR',
164
+ output: error instanceof Error ? error.message : String(error)
165
+ }
166
+ });
167
+ }
168
+ }
169
+ }
170
+ /**
171
+ * Format git command for display
172
+ */
173
+ formatGitCommand(command) {
174
+ switch (command.action) {
175
+ case 'checkout':
176
+ return `git checkout ${command.create ? '-b ' : ''}${command.branch}`;
177
+ case 'create_branch':
178
+ return `git checkout -b ${command.branch}${command.from ? ` ${command.from}` : ''}`;
179
+ case 'commit':
180
+ return `git commit -m "${command.message}"${command.files ? ` ${command.files.join(' ')}` : ''}`;
181
+ case 'push':
182
+ return `git push${command.force ? ' --force' : ''}${command.setUpstream ? ' -u origin ' : ' '}${command.branch}`;
183
+ case 'status':
184
+ return 'git status';
185
+ case 'pull':
186
+ return `git pull${command.branch ? ` origin ${command.branch}` : ''}`;
187
+ case 'delete_branch':
188
+ return `git branch ${command.force ? '-D' : '-d'} ${command.branch}`;
189
+ default:
190
+ return 'git (unknown command)';
191
+ }
192
+ }
193
+ /**
194
+ * Set up signal handlers for graceful shutdown
195
+ */
196
+ setupSignalHandlers() {
197
+ const shutdown = async () => {
198
+ await this.shutdown();
199
+ process.exit(0);
200
+ };
201
+ process.on('SIGINT', shutdown);
202
+ process.on('SIGTERM', shutdown);
203
+ }
204
+ /**
205
+ * Gracefully shutdown dev server and WebSocket
206
+ */
207
+ async shutdown() {
208
+ if (this.shuttingDown) {
209
+ return;
210
+ }
211
+ this.shuttingDown = true;
212
+ output_1.status.info('Shutting down...');
213
+ // Disconnect WebSocket
214
+ if (this.wsClient) {
215
+ try {
216
+ await this.wsClient.disconnect();
217
+ output_1.status.debug('WebSocket disconnected');
218
+ }
219
+ catch (error) {
220
+ output_1.status.debug(`WebSocket disconnect error: ${error}`);
221
+ }
222
+ }
223
+ // Stop dev server
224
+ if (this.devProcess && !this.devProcess.killed) {
225
+ try {
226
+ this.devProcess.kill('SIGTERM');
227
+ // Wait up to 5 seconds for graceful shutdown
228
+ await new Promise((resolve) => {
229
+ const timeout = setTimeout(() => {
230
+ if (this.devProcess && !this.devProcess.killed) {
231
+ output_1.status.warning('Force killing dev server...');
232
+ this.devProcess.kill('SIGKILL');
233
+ }
234
+ resolve();
235
+ }, 5000);
236
+ this.devProcess?.on('exit', () => {
237
+ clearTimeout(timeout);
238
+ resolve();
239
+ });
240
+ });
241
+ }
242
+ catch (error) {
243
+ output_1.status.debug(`Dev server shutdown error: ${error}`);
244
+ }
245
+ }
246
+ output_1.status.success('Shutdown complete');
247
+ }
248
+ /**
249
+ * Get current status
250
+ */
251
+ getStatus() {
252
+ return {
253
+ running: this.connectionOnlyMode ? true : (this.devProcess !== undefined && !this.devProcess.killed),
254
+ pid: this.devProcess?.pid,
255
+ command: this.command || [],
256
+ restartCount: this.restartCount,
257
+ connectedToCloud: this.wsClient?.getStatus().connected || false
258
+ };
259
+ }
260
+ }
261
+ exports.DevServerWrapper = DevServerWrapper;
262
+ /**
263
+ * Wrap and run a dev server command
264
+ * @param command - Command to run (e.g., ["npm", "start"])
265
+ * @param options - Additional options
266
+ */
267
+ async function wrapDevServer(command, options) {
268
+ const wrapper = new DevServerWrapper({
269
+ command,
270
+ ...options
271
+ });
272
+ await wrapper.start();
273
+ return wrapper;
274
+ }
275
+ /**
276
+ * Global wrapper instance for tracking
277
+ */
278
+ let globalWrapper = null;
279
+ /**
280
+ * Stop the wrapped dev server
281
+ */
282
+ async function stopDevServer() {
283
+ if (globalWrapper) {
284
+ await globalWrapper.shutdown();
285
+ globalWrapper = null;
286
+ }
287
+ }
288
+ //# sourceMappingURL=dev-wrapper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev-wrapper.js","sourceRoot":"","sources":["../src/dev-wrapper.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Framework Detection
3
+ *
4
+ * Detects the framework/stack based on project files and suggests
5
+ * appropriate dev server command.
6
+ */
7
+ export interface FrameworkDetection {
8
+ framework: string;
9
+ command: string[];
10
+ confidence: 'high' | 'medium' | 'low';
11
+ detectedFrom: string;
12
+ }
13
+ /**
14
+ * Detect framework from project files
15
+ * @param cwd - Working directory to search (defaults to process.cwd())
16
+ * @returns Detection result or null if no framework detected
17
+ */
18
+ export declare function detectFramework(cwd?: string): Promise<FrameworkDetection | null>;
19
+ /**
20
+ * Suggest command based on user-provided command or auto-detection
21
+ * @param providedCommand - Command provided by user (e.g., ["npm", "run", "dev"])
22
+ * @param cwd - Working directory
23
+ * @returns Final command to use
24
+ */
25
+ export declare function resolveDevCommand(providedCommand: string[] | null, cwd?: string): Promise<{
26
+ command: string[];
27
+ detection: FrameworkDetection | null;
28
+ }>;
29
+ //# sourceMappingURL=framework-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"framework-detector.d.ts","sourceRoot":"","sources":["../src/framework-detector.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAA;IACrC,YAAY,EAAE,MAAM,CAAA;CACrB;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAqNrG;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,eAAe,EAAE,MAAM,EAAE,GAAG,IAAI,EAChC,GAAG,GAAE,MAAsB,GAC1B,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,SAAS,EAAE,kBAAkB,GAAG,IAAI,CAAA;CAAE,CAAC,CAsBtE"}
@@ -0,0 +1,276 @@
1
+ "use strict";
2
+ /**
3
+ * Framework Detection
4
+ *
5
+ * Detects the framework/stack based on project files and suggests
6
+ * appropriate dev server command.
7
+ */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
20
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
21
+ }) : function(o, v) {
22
+ o["default"] = v;
23
+ });
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.detectFramework = detectFramework;
43
+ exports.resolveDevCommand = resolveDevCommand;
44
+ const fs = __importStar(require("fs"));
45
+ const path = __importStar(require("path"));
46
+ /**
47
+ * Detect framework from project files
48
+ * @param cwd - Working directory to search (defaults to process.cwd())
49
+ * @returns Detection result or null if no framework detected
50
+ */
51
+ async function detectFramework(cwd = process.cwd()) {
52
+ // Check for package.json (Node.js projects)
53
+ const packageJsonPath = path.join(cwd, 'package.json');
54
+ if (fs.existsSync(packageJsonPath)) {
55
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
56
+ // Check scripts first
57
+ const scripts = packageJson.scripts || {};
58
+ // Next.js detection
59
+ if (packageJson.dependencies?.next || packageJson.devDependencies?.next) {
60
+ if (scripts.dev) {
61
+ return {
62
+ framework: 'Next.js',
63
+ command: ['npm', 'run', 'dev'],
64
+ confidence: 'high',
65
+ detectedFrom: 'package.json (next dependency + dev script)'
66
+ };
67
+ }
68
+ return {
69
+ framework: 'Next.js',
70
+ command: ['npx', 'next', 'dev'],
71
+ confidence: 'medium',
72
+ detectedFrom: 'package.json (next dependency)'
73
+ };
74
+ }
75
+ // React (Create React App, Vite, etc.)
76
+ if (packageJson.dependencies?.react || packageJson.devDependencies?.react) {
77
+ if (scripts.dev) {
78
+ return {
79
+ framework: 'React',
80
+ command: ['npm', 'run', 'dev'],
81
+ confidence: 'high',
82
+ detectedFrom: 'package.json (react + dev script)'
83
+ };
84
+ }
85
+ if (scripts.start) {
86
+ return {
87
+ framework: 'React',
88
+ command: ['npm', 'start'],
89
+ confidence: 'high',
90
+ detectedFrom: 'package.json (react + start script)'
91
+ };
92
+ }
93
+ }
94
+ // Express
95
+ if (packageJson.dependencies?.express) {
96
+ if (scripts.dev) {
97
+ return {
98
+ framework: 'Express',
99
+ command: ['npm', 'run', 'dev'],
100
+ confidence: 'high',
101
+ detectedFrom: 'package.json (express + dev script)'
102
+ };
103
+ }
104
+ if (scripts.start) {
105
+ return {
106
+ framework: 'Express',
107
+ command: ['npm', 'start'],
108
+ confidence: 'medium',
109
+ detectedFrom: 'package.json (express + start script)'
110
+ };
111
+ }
112
+ }
113
+ // Vue
114
+ if (packageJson.dependencies?.vue || packageJson.devDependencies?.vue) {
115
+ if (scripts.dev) {
116
+ return {
117
+ framework: 'Vue',
118
+ command: ['npm', 'run', 'dev'],
119
+ confidence: 'high',
120
+ detectedFrom: 'package.json (vue + dev script)'
121
+ };
122
+ }
123
+ if (scripts.serve) {
124
+ return {
125
+ framework: 'Vue',
126
+ command: ['npm', 'run', 'serve'],
127
+ confidence: 'high',
128
+ detectedFrom: 'package.json (vue + serve script)'
129
+ };
130
+ }
131
+ }
132
+ // Generic Node.js (fallback)
133
+ if (scripts.dev) {
134
+ return {
135
+ framework: 'Node.js',
136
+ command: ['npm', 'run', 'dev'],
137
+ confidence: 'medium',
138
+ detectedFrom: 'package.json (dev script)'
139
+ };
140
+ }
141
+ if (scripts.start) {
142
+ return {
143
+ framework: 'Node.js',
144
+ command: ['npm', 'start'],
145
+ confidence: 'low',
146
+ detectedFrom: 'package.json (start script)'
147
+ };
148
+ }
149
+ }
150
+ // Check for requirements.txt (Python projects)
151
+ const requirementsPath = path.join(cwd, 'requirements.txt');
152
+ if (fs.existsSync(requirementsPath)) {
153
+ const requirements = fs.readFileSync(requirementsPath, 'utf-8');
154
+ // Django
155
+ if (requirements.includes('Django') || requirements.includes('django')) {
156
+ const managePy = path.join(cwd, 'manage.py');
157
+ if (fs.existsSync(managePy)) {
158
+ return {
159
+ framework: 'Django',
160
+ command: ['python', 'manage.py', 'runserver'],
161
+ confidence: 'high',
162
+ detectedFrom: 'requirements.txt (Django) + manage.py'
163
+ };
164
+ }
165
+ return {
166
+ framework: 'Django',
167
+ command: ['python', 'manage.py', 'runserver'],
168
+ confidence: 'medium',
169
+ detectedFrom: 'requirements.txt (Django)'
170
+ };
171
+ }
172
+ // Flask
173
+ if (requirements.includes('Flask') || requirements.includes('flask')) {
174
+ // Look for common Flask app files
175
+ const appFiles = ['app.py', 'application.py', 'wsgi.py'];
176
+ for (const file of appFiles) {
177
+ if (fs.existsSync(path.join(cwd, file))) {
178
+ return {
179
+ framework: 'Flask',
180
+ command: ['flask', 'run'],
181
+ confidence: 'high',
182
+ detectedFrom: `requirements.txt (Flask) + ${file}`
183
+ };
184
+ }
185
+ }
186
+ return {
187
+ framework: 'Flask',
188
+ command: ['flask', 'run'],
189
+ confidence: 'medium',
190
+ detectedFrom: 'requirements.txt (Flask)'
191
+ };
192
+ }
193
+ // FastAPI / Uvicorn
194
+ if (requirements.includes('fastapi') || requirements.includes('uvicorn')) {
195
+ return {
196
+ framework: 'FastAPI',
197
+ command: ['uvicorn', 'main:app', '--reload'],
198
+ confidence: 'medium',
199
+ detectedFrom: 'requirements.txt (fastapi/uvicorn)'
200
+ };
201
+ }
202
+ }
203
+ // Check for Gemfile (Ruby projects)
204
+ const gemfilePath = path.join(cwd, 'Gemfile');
205
+ if (fs.existsSync(gemfilePath)) {
206
+ const gemfile = fs.readFileSync(gemfilePath, 'utf-8');
207
+ // Rails
208
+ if (gemfile.includes('rails')) {
209
+ return {
210
+ framework: 'Rails',
211
+ command: ['rails', 'server'],
212
+ confidence: 'high',
213
+ detectedFrom: 'Gemfile (rails)'
214
+ };
215
+ }
216
+ // Sinatra
217
+ if (gemfile.includes('sinatra')) {
218
+ return {
219
+ framework: 'Sinatra',
220
+ command: ['ruby', 'app.rb'],
221
+ confidence: 'medium',
222
+ detectedFrom: 'Gemfile (sinatra)'
223
+ };
224
+ }
225
+ }
226
+ // Check for go.mod (Go projects)
227
+ const goModPath = path.join(cwd, 'go.mod');
228
+ if (fs.existsSync(goModPath)) {
229
+ return {
230
+ framework: 'Go',
231
+ command: ['go', 'run', '.'],
232
+ confidence: 'medium',
233
+ detectedFrom: 'go.mod'
234
+ };
235
+ }
236
+ // Check for Cargo.toml (Rust projects)
237
+ const cargoTomlPath = path.join(cwd, 'Cargo.toml');
238
+ if (fs.existsSync(cargoTomlPath)) {
239
+ return {
240
+ framework: 'Rust',
241
+ command: ['cargo', 'run'],
242
+ confidence: 'medium',
243
+ detectedFrom: 'Cargo.toml'
244
+ };
245
+ }
246
+ // No framework detected
247
+ return null;
248
+ }
249
+ /**
250
+ * Suggest command based on user-provided command or auto-detection
251
+ * @param providedCommand - Command provided by user (e.g., ["npm", "run", "dev"])
252
+ * @param cwd - Working directory
253
+ * @returns Final command to use
254
+ */
255
+ async function resolveDevCommand(providedCommand, cwd = process.cwd()) {
256
+ // If user provided command, use it as-is
257
+ if (providedCommand && providedCommand.length > 0) {
258
+ return { command: providedCommand, detection: null };
259
+ }
260
+ // Auto-detect framework
261
+ const detection = await detectFramework(cwd);
262
+ if (detection) {
263
+ return { command: detection.command, detection };
264
+ }
265
+ // No detection - default to npm run dev
266
+ return {
267
+ command: ['npm', 'run', 'dev'],
268
+ detection: {
269
+ framework: 'Unknown',
270
+ command: ['npm', 'run', 'dev'],
271
+ confidence: 'low',
272
+ detectedFrom: 'default fallback'
273
+ }
274
+ };
275
+ }
276
+ //# sourceMappingURL=framework-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"framework-detector.js","sourceRoot":"","sources":["../src/framework-detector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * EP548/EP612: Git Credential Helper Script Generator
3
+ *
4
+ * This module generates the git credential helper script that is installed
5
+ * during `episoda auth`. The script is called by git when credentials are needed.
6
+ *
7
+ * The generated script:
8
+ * 1. Detects the environment (local vs cloud)
9
+ * 2. Calls GET /api/git/credentials with appropriate auth
10
+ * 3. Returns credentials in git credential protocol format
11
+ * 4. Caches tokens locally (5 min TTL) to avoid API calls on every git operation
12
+ *
13
+ * EP612: Removed jq dependency - uses pure bash JSON parsing
14
+ */
15
+ /**
16
+ * Generate the credential helper script content
17
+ *
18
+ * The script needs to:
19
+ * - Be standalone (no external dependencies - just bash and curl)
20
+ * - Work with curl (available on all platforms)
21
+ * - Handle both local (OAuth) and cloud (machine ID) auth
22
+ * - Cache tokens to avoid hitting API on every git operation
23
+ */
24
+ export declare function generateCredentialHelperScript(apiUrl: string): string;
25
+ /**
26
+ * Get the content of the credential helper for embedding in the CLI
27
+ */
28
+ export declare const CREDENTIAL_HELPER_SCRIPT: string;
29
+ //# sourceMappingURL=git-credential-helper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-credential-helper.d.ts","sourceRoot":"","sources":["../../src/git-helpers/git-credential-helper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH;;;;;;;;GAQG;AACH,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CA4TrE;AAED;;GAEG;AACH,eAAO,MAAM,wBAAwB,QAAwD,CAAA"}