@helmai/cli 1.0.10 → 1.0.13

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.
@@ -0,0 +1,24 @@
1
+ interface FileEntry {
2
+ path: string;
3
+ type: string;
4
+ name: string;
5
+ }
6
+ interface DirectorySummary {
7
+ type: string;
8
+ count: number;
9
+ files: string[];
10
+ }
11
+ export interface CodebaseMap {
12
+ scanned_at: string;
13
+ file_count: number;
14
+ directories: Record<string, DirectorySummary>;
15
+ key_files: FileEntry[];
16
+ entry_points: Record<string, string>;
17
+ }
18
+ export declare function scanCodebase(cwd: string): CodebaseMap;
19
+ /**
20
+ * Generate a compact text summary suitable for prompt injection
21
+ */
22
+ export declare function generateStructureSummary(map: CodebaseMap): string;
23
+ export {};
24
+ //# sourceMappingURL=codebase-scan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codebase-scan.d.ts","sourceRoot":"","sources":["../../src/lib/codebase-scan.ts"],"names":[],"mappings":"AAGA,UAAU,SAAS;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,gBAAgB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC9C,SAAS,EAAE,SAAS,EAAE,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC;AA2FD,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CA+ErD;AA6CD;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,WAAW,GAAG,MAAM,CA4DjE"}
@@ -0,0 +1,346 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.scanCodebase = scanCodebase;
37
+ exports.generateStructureSummary = generateStructureSummary;
38
+ const fs = __importStar(require("fs"));
39
+ const path = __importStar(require("path"));
40
+ const IGNORE_DIRS = new Set([
41
+ 'node_modules', 'vendor', 'dist', '.git', '.helm', '.idea', '.vscode',
42
+ 'storage', 'bootstrap/cache', 'public/build', 'public/hot', '.next',
43
+ '__pycache__', '.nuxt', '.output', 'coverage', '.turbo',
44
+ ]);
45
+ const IGNORE_EXTENSIONS = new Set([
46
+ '.lock', '.map', '.min.js', '.min.css', '.ico', '.png', '.jpg', '.jpeg',
47
+ '.gif', '.svg', '.woff', '.woff2', '.ttf', '.eot', '.mp4', '.webm',
48
+ '.pdf', '.zip', '.tar', '.gz',
49
+ ]);
50
+ const FILE_TYPE_MAP = {
51
+ '.php': (filePath, name) => {
52
+ if (filePath.includes('/Models/'))
53
+ return 'model';
54
+ if (filePath.includes('/Controllers/'))
55
+ return 'controller';
56
+ if (filePath.includes('/Actions/'))
57
+ return 'action';
58
+ if (filePath.includes('/Requests/'))
59
+ return 'form-request';
60
+ if (filePath.includes('/Middleware/'))
61
+ return 'middleware';
62
+ if (filePath.includes('/Policies/'))
63
+ return 'policy';
64
+ if (filePath.includes('/Providers/'))
65
+ return 'provider';
66
+ if (filePath.includes('/Commands/'))
67
+ return 'command';
68
+ if (filePath.includes('/Jobs/'))
69
+ return 'job';
70
+ if (filePath.includes('/Events/'))
71
+ return 'event';
72
+ if (filePath.includes('/Listeners/'))
73
+ return 'listener';
74
+ if (filePath.includes('/Mail/'))
75
+ return 'mail';
76
+ if (filePath.includes('/Notifications/'))
77
+ return 'notification';
78
+ if (filePath.includes('/Resources/') && filePath.includes('Filament'))
79
+ return 'filament-resource';
80
+ if (filePath.includes('database/migrations/'))
81
+ return 'migration';
82
+ if (filePath.includes('database/factories/'))
83
+ return 'factory';
84
+ if (filePath.includes('database/seeders/'))
85
+ return 'seeder';
86
+ if (filePath.includes('tests/'))
87
+ return 'test';
88
+ if (filePath.includes('routes/'))
89
+ return 'route';
90
+ if (filePath.includes('config/'))
91
+ return 'config';
92
+ return 'php';
93
+ },
94
+ '.ts': (filePath) => {
95
+ if (filePath.includes('/pages/'))
96
+ return 'page';
97
+ if (filePath.includes('/components/'))
98
+ return 'component';
99
+ if (filePath.includes('/layouts/'))
100
+ return 'layout';
101
+ if (filePath.includes('/hooks/'))
102
+ return 'hook';
103
+ if (filePath.includes('/types'))
104
+ return 'types';
105
+ if (filePath.includes('/lib/') || filePath.includes('/utils/'))
106
+ return 'utility';
107
+ return 'typescript';
108
+ },
109
+ '.tsx': (filePath) => {
110
+ if (filePath.includes('/pages/'))
111
+ return 'page';
112
+ if (filePath.includes('/components/'))
113
+ return 'component';
114
+ if (filePath.includes('/layouts/'))
115
+ return 'layout';
116
+ return 'react-component';
117
+ },
118
+ '.vue': () => 'vue-component',
119
+ '.blade.php': (filePath) => {
120
+ if (filePath.includes('/components/'))
121
+ return 'blade-component';
122
+ if (filePath.includes('/layouts/'))
123
+ return 'blade-layout';
124
+ return 'blade-view';
125
+ },
126
+ '.json': (filePath, name) => {
127
+ if (name === 'package.json')
128
+ return 'package-config';
129
+ if (name === 'composer.json')
130
+ return 'package-config';
131
+ if (name === 'tsconfig.json')
132
+ return 'config';
133
+ return null; // skip most json
134
+ },
135
+ '.md': (_, name) => {
136
+ if (['README.md', 'CLAUDE.md', 'AGENTS.md'].includes(name))
137
+ return 'documentation';
138
+ return null;
139
+ },
140
+ '.yaml': () => 'config',
141
+ '.yml': () => 'config',
142
+ '.env': () => null, // never index env files
143
+ };
144
+ function getFileType(filePath, name) {
145
+ // Check blade.php first (compound extension)
146
+ if (name.endsWith('.blade.php')) {
147
+ return FILE_TYPE_MAP['.blade.php']?.(filePath, name) ?? null;
148
+ }
149
+ const ext = path.extname(name).toLowerCase();
150
+ if (IGNORE_EXTENSIONS.has(ext))
151
+ return null;
152
+ const classifier = FILE_TYPE_MAP[ext];
153
+ if (classifier)
154
+ return classifier(filePath, name);
155
+ // Skip unknown extensions
156
+ return null;
157
+ }
158
+ function scanCodebase(cwd) {
159
+ const files = [];
160
+ const dirSummaries = {};
161
+ const entryPoints = {};
162
+ let fileCount = 0;
163
+ // Load .gitignore patterns for basic filtering
164
+ const gitignorePatterns = loadGitignorePatterns(cwd);
165
+ function walk(dir, depth) {
166
+ if (depth > 8)
167
+ return; // don't go too deep
168
+ let entries;
169
+ try {
170
+ entries = fs.readdirSync(dir, { withFileTypes: true });
171
+ }
172
+ catch {
173
+ return;
174
+ }
175
+ for (const entry of entries) {
176
+ const fullPath = path.join(dir, entry.name);
177
+ const relativePath = path.relative(cwd, fullPath);
178
+ if (entry.isDirectory()) {
179
+ if (IGNORE_DIRS.has(entry.name))
180
+ continue;
181
+ if (entry.name.startsWith('.') && entry.name !== '.github')
182
+ continue;
183
+ if (gitignorePatterns.some(p => matchesPattern(relativePath, p)))
184
+ continue;
185
+ walk(fullPath, depth + 1);
186
+ }
187
+ else if (entry.isFile()) {
188
+ const type = getFileType(relativePath, entry.name);
189
+ if (!type)
190
+ continue;
191
+ fileCount++;
192
+ const nameWithoutExt = entry.name.replace(/\.(php|ts|tsx|vue|blade\.php)$/, '');
193
+ files.push({
194
+ path: relativePath,
195
+ type,
196
+ name: nameWithoutExt,
197
+ });
198
+ // Group by directory
199
+ const dirKey = path.dirname(relativePath);
200
+ if (!dirSummaries[dirKey]) {
201
+ dirSummaries[dirKey] = { type, count: 0, files: [] };
202
+ }
203
+ dirSummaries[dirKey].count++;
204
+ if (dirSummaries[dirKey].files.length < 20) {
205
+ dirSummaries[dirKey].files.push(nameWithoutExt);
206
+ }
207
+ }
208
+ }
209
+ }
210
+ walk(cwd, 0);
211
+ // Detect entry points
212
+ const routeFiles = ['routes/web.php', 'routes/api.php', 'routes/console.php', 'routes/channels.php'];
213
+ for (const rf of routeFiles) {
214
+ if (fs.existsSync(path.join(cwd, rf))) {
215
+ entryPoints[rf] = rf.replace('routes/', '').replace('.php', '') + ' routes';
216
+ }
217
+ }
218
+ const configFiles = ['config/app.php', 'config/helm.php', 'config/ai.php', 'config/auth.php'];
219
+ for (const cf of configFiles) {
220
+ if (fs.existsSync(path.join(cwd, cf))) {
221
+ entryPoints[cf] = path.basename(cf, '.php') + ' config';
222
+ }
223
+ }
224
+ return {
225
+ scanned_at: new Date().toISOString(),
226
+ file_count: fileCount,
227
+ directories: consolidateDirectories(dirSummaries),
228
+ key_files: files,
229
+ entry_points: entryPoints,
230
+ };
231
+ }
232
+ /**
233
+ * Consolidate directories into meaningful groups (e.g. app/Models instead of listing each subdirectory)
234
+ */
235
+ function consolidateDirectories(dirs) {
236
+ const consolidated = {};
237
+ // Group by meaningful parent directories
238
+ const groups = {};
239
+ for (const [dir, summary] of Object.entries(dirs)) {
240
+ // Find the meaningful parent (2-3 levels deep)
241
+ const parts = dir.split(path.sep);
242
+ let groupKey;
243
+ if (parts.length <= 2) {
244
+ groupKey = dir;
245
+ }
246
+ else if (parts[0] === 'app' || parts[0] === 'resources' || parts[0] === 'database' || parts[0] === 'tests') {
247
+ groupKey = parts.slice(0, Math.min(parts.length, 3)).join('/');
248
+ }
249
+ else {
250
+ groupKey = parts.slice(0, 2).join('/');
251
+ }
252
+ if (!groups[groupKey]) {
253
+ groups[groupKey] = { type: summary.type, count: 0, files: [] };
254
+ }
255
+ groups[groupKey].count += summary.count;
256
+ for (const f of summary.files) {
257
+ if (groups[groupKey].files.length < 20) {
258
+ groups[groupKey].files.push(f);
259
+ }
260
+ }
261
+ }
262
+ // Only keep directories with files
263
+ for (const [dir, summary] of Object.entries(groups)) {
264
+ if (summary.count > 0) {
265
+ consolidated[dir] = summary;
266
+ }
267
+ }
268
+ return consolidated;
269
+ }
270
+ /**
271
+ * Generate a compact text summary suitable for prompt injection
272
+ */
273
+ function generateStructureSummary(map) {
274
+ const lines = [];
275
+ // Group key files by type for a compact overview
276
+ const byType = {};
277
+ for (const file of map.key_files) {
278
+ if (!byType[file.type])
279
+ byType[file.type] = [];
280
+ byType[file.type].push(file.name);
281
+ }
282
+ // Display order and labels
283
+ const typeLabels = {
284
+ 'model': 'Models',
285
+ 'controller': 'Controllers',
286
+ 'action': 'Actions',
287
+ 'form-request': 'Form Requests',
288
+ 'middleware': 'Middleware',
289
+ 'policy': 'Policies',
290
+ 'command': 'Commands',
291
+ 'job': 'Jobs',
292
+ 'migration': 'Migrations',
293
+ 'factory': 'Factories',
294
+ 'test': 'Tests',
295
+ 'page': 'Pages',
296
+ 'component': 'Components',
297
+ 'react-component': 'React Components',
298
+ 'layout': 'Layouts',
299
+ 'route': 'Routes',
300
+ 'config': 'Config',
301
+ 'filament-resource': 'Filament Resources',
302
+ };
303
+ const displayOrder = [
304
+ 'model', 'controller', 'action', 'form-request', 'middleware', 'policy',
305
+ 'command', 'job', 'page', 'component', 'react-component', 'layout',
306
+ 'test', 'migration', 'factory', 'filament-resource', 'route', 'config',
307
+ ];
308
+ for (const type of displayOrder) {
309
+ const names = byType[type];
310
+ if (!names || names.length === 0)
311
+ continue;
312
+ const label = typeLabels[type] || type;
313
+ const dedupedNames = [...new Set(names)];
314
+ const display = dedupedNames.length > 8
315
+ ? dedupedNames.slice(0, 8).join(', ') + ` (+${dedupedNames.length - 8} more)`
316
+ : dedupedNames.join(', ');
317
+ lines.push(`- **${label}** (${dedupedNames.length}): ${display}`);
318
+ }
319
+ // Entry points
320
+ if (Object.keys(map.entry_points).length > 0) {
321
+ const eps = Object.entries(map.entry_points).map(([p, label]) => `${p} (${label})`).join(', ');
322
+ lines.push(`- **Entry Points**: ${eps}`);
323
+ }
324
+ lines.push(`- **Total indexed files**: ${map.file_count}`);
325
+ return lines.join('\n');
326
+ }
327
+ function loadGitignorePatterns(cwd) {
328
+ const gitignorePath = path.join(cwd, '.gitignore');
329
+ if (!fs.existsSync(gitignorePath))
330
+ return [];
331
+ try {
332
+ return fs.readFileSync(gitignorePath, 'utf-8')
333
+ .split('\n')
334
+ .map(l => l.trim())
335
+ .filter(l => l && !l.startsWith('#'));
336
+ }
337
+ catch {
338
+ return [];
339
+ }
340
+ }
341
+ function matchesPattern(filePath, pattern) {
342
+ // Simple pattern matching (not full glob, just prefix/directory matching)
343
+ const cleanPattern = pattern.replace(/^\//, '').replace(/\/$/, '');
344
+ return filePath.startsWith(cleanPattern + '/') || filePath === cleanPattern;
345
+ }
346
+ //# sourceMappingURL=codebase-scan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codebase-scan.js","sourceRoot":"","sources":["../../src/lib/codebase-scan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ export interface ConcurrentSessionInfo {
2
+ count: number;
3
+ sessions: Array<{
4
+ session_id: string;
5
+ branch: string | null;
6
+ user: string | null;
7
+ ide: string | null;
8
+ age_seconds: number;
9
+ }>;
10
+ }
11
+ /**
12
+ * Write a heartbeat for this session. Called on every inject.
13
+ */
14
+ export declare function writeSessionHeartbeat(cwd: string, sessionId: string, branch: string | null): void;
15
+ /**
16
+ * Check for other active sessions on the same project.
17
+ * Returns info about concurrent sessions (excluding this one).
18
+ */
19
+ export declare function detectConcurrentSessions(cwd: string, currentSessionId: string): ConcurrentSessionInfo | null;
20
+ /**
21
+ * Mark a session as finished (called by capture hook).
22
+ * Doesn't delete immediately — just updates the heartbeat so the timeout handles cleanup.
23
+ */
24
+ export declare function clearSessionHeartbeat(cwd: string, sessionId: string): void;
25
+ //# sourceMappingURL=concurrent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"concurrent.d.ts","sourceRoot":"","sources":["../../src/lib/concurrent.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,KAAK,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;QACpB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC,CAAC;CACJ;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GAAG,IAAI,GACpB,IAAI,CAyBN;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,MAAM,EACX,gBAAgB,EAAE,MAAM,GACvB,qBAAqB,GAAG,IAAI,CA0D9B;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAU1E"}
@@ -0,0 +1,206 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.writeSessionHeartbeat = writeSessionHeartbeat;
37
+ exports.detectConcurrentSessions = detectConcurrentSessions;
38
+ exports.clearSessionHeartbeat = clearSessionHeartbeat;
39
+ const fs = __importStar(require("fs"));
40
+ const path = __importStar(require("path"));
41
+ const SESSION_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes — session is "active" if heartbeat is within this window
42
+ /**
43
+ * Write a heartbeat for this session. Called on every inject.
44
+ */
45
+ function writeSessionHeartbeat(cwd, sessionId, branch) {
46
+ const sessionsDir = path.join(cwd, '.helm', 'sessions');
47
+ try {
48
+ if (!fs.existsSync(sessionsDir)) {
49
+ fs.mkdirSync(sessionsDir, { recursive: true });
50
+ }
51
+ const heartbeat = {
52
+ session_id: sessionId,
53
+ pid: process.pid,
54
+ branch,
55
+ user: getGitUser(cwd),
56
+ ide: detectCurrentIDE(),
57
+ started_at: getExistingStartTime(sessionsDir, sessionId) ?? new Date().toISOString(),
58
+ last_heartbeat: new Date().toISOString(),
59
+ };
60
+ fs.writeFileSync(path.join(sessionsDir, `${sessionId}.json`), JSON.stringify(heartbeat, null, 2));
61
+ }
62
+ catch {
63
+ // Never break injection for heartbeat
64
+ }
65
+ }
66
+ /**
67
+ * Check for other active sessions on the same project.
68
+ * Returns info about concurrent sessions (excluding this one).
69
+ */
70
+ function detectConcurrentSessions(cwd, currentSessionId) {
71
+ const sessionsDir = path.join(cwd, '.helm', 'sessions');
72
+ if (!fs.existsSync(sessionsDir)) {
73
+ return null;
74
+ }
75
+ try {
76
+ const now = Date.now();
77
+ const files = fs.readdirSync(sessionsDir).filter(f => f.endsWith('.json'));
78
+ const activeSessions = [];
79
+ for (const file of files) {
80
+ const filePath = path.join(sessionsDir, file);
81
+ try {
82
+ const raw = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
83
+ // Skip our own session
84
+ if (raw.session_id === currentSessionId)
85
+ continue;
86
+ const lastHeartbeat = new Date(raw.last_heartbeat).getTime();
87
+ const elapsed = now - lastHeartbeat;
88
+ // Check if session is still active (heartbeat within timeout)
89
+ if (elapsed < SESSION_TIMEOUT_MS) {
90
+ // Double-check: is the process still running?
91
+ if (isProcessAlive(raw.pid)) {
92
+ activeSessions.push({
93
+ session_id: raw.session_id,
94
+ branch: raw.branch,
95
+ user: raw.user,
96
+ ide: raw.ide,
97
+ age_seconds: Math.round(elapsed / 1000),
98
+ });
99
+ }
100
+ else {
101
+ // Process is dead — clean up stale heartbeat
102
+ try {
103
+ fs.unlinkSync(filePath);
104
+ }
105
+ catch { /* ignore */ }
106
+ }
107
+ }
108
+ else {
109
+ // Heartbeat is too old — clean up
110
+ try {
111
+ fs.unlinkSync(filePath);
112
+ }
113
+ catch { /* ignore */ }
114
+ }
115
+ }
116
+ catch {
117
+ // Corrupt file — remove it
118
+ try {
119
+ fs.unlinkSync(filePath);
120
+ }
121
+ catch { /* ignore */ }
122
+ }
123
+ }
124
+ if (activeSessions.length === 0)
125
+ return null;
126
+ return {
127
+ count: activeSessions.length,
128
+ sessions: activeSessions,
129
+ };
130
+ }
131
+ catch {
132
+ return null;
133
+ }
134
+ }
135
+ /**
136
+ * Mark a session as finished (called by capture hook).
137
+ * Doesn't delete immediately — just updates the heartbeat so the timeout handles cleanup.
138
+ */
139
+ function clearSessionHeartbeat(cwd, sessionId) {
140
+ const filePath = path.join(cwd, '.helm', 'sessions', `${sessionId}.json`);
141
+ try {
142
+ if (fs.existsSync(filePath)) {
143
+ fs.unlinkSync(filePath);
144
+ }
145
+ }
146
+ catch {
147
+ // ignore
148
+ }
149
+ }
150
+ function getGitUser(cwd) {
151
+ try {
152
+ const { execSync } = require('child_process');
153
+ return execSync('git config user.name', { cwd, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim() || null;
154
+ }
155
+ catch {
156
+ return null;
157
+ }
158
+ }
159
+ function detectCurrentIDE() {
160
+ // Check common environment variables set by IDEs
161
+ if (process.env.CURSOR_TRACE_DIR || process.env.CURSOR_CHANNEL)
162
+ return 'Cursor';
163
+ if (process.env.CLAUDE_CODE)
164
+ return 'Claude Code';
165
+ if (process.env.TERM_PROGRAM === 'vscode')
166
+ return 'VS Code';
167
+ // Check parent process name (best-effort)
168
+ try {
169
+ const { execSync } = require('child_process');
170
+ const ppid = process.ppid;
171
+ const parentName = execSync(`ps -p ${ppid} -o comm=`, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
172
+ if (parentName.includes('cursor'))
173
+ return 'Cursor';
174
+ if (parentName.includes('claude'))
175
+ return 'Claude Code';
176
+ if (parentName.includes('code'))
177
+ return 'VS Code';
178
+ }
179
+ catch {
180
+ // ignore
181
+ }
182
+ return null;
183
+ }
184
+ function getExistingStartTime(sessionsDir, sessionId) {
185
+ try {
186
+ const filePath = path.join(sessionsDir, `${sessionId}.json`);
187
+ if (fs.existsSync(filePath)) {
188
+ const raw = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
189
+ return raw.started_at;
190
+ }
191
+ }
192
+ catch {
193
+ // ignore
194
+ }
195
+ return null;
196
+ }
197
+ function isProcessAlive(pid) {
198
+ try {
199
+ process.kill(pid, 0); // signal 0 = just check if process exists
200
+ return true;
201
+ }
202
+ catch {
203
+ return false;
204
+ }
205
+ }
206
+ //# sourceMappingURL=concurrent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"concurrent.js","sourceRoot":"","sources":["../../src/lib/concurrent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export interface OnboardingProgress {
2
+ prompt_count: number;
3
+ stage_id: 'trust' | 'coach' | 'autonomy' | 'replicate' | 'personalize' | null;
4
+ stage_title: string | null;
5
+ stage_instruction: string | null;
6
+ }
7
+ export declare function trackOnboardingProgress(cwd: string): OnboardingProgress;
8
+ //# sourceMappingURL=onboarding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"onboarding.d.ts","sourceRoot":"","sources":["../../src/lib/onboarding.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,OAAO,GAAG,OAAO,GAAG,UAAU,GAAG,WAAW,GAAG,aAAa,GAAG,IAAI,CAAC;IAC9E,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAOD,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,kBAAkB,CA+BvE"}