claudedesk 1.0.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 (182) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +431 -0
  3. package/config/repos.example.json +128 -0
  4. package/config/settings.example.json +64 -0
  5. package/config/skills/code-review.md +76 -0
  6. package/config/skills/full-check.md +26 -0
  7. package/config/skills/lint-fix.md +23 -0
  8. package/dist/api/agent-routes.d.ts +2 -0
  9. package/dist/api/agent-routes.d.ts.map +1 -0
  10. package/dist/api/agent-routes.js +251 -0
  11. package/dist/api/agent-routes.js.map +1 -0
  12. package/dist/api/app-routes.d.ts +2 -0
  13. package/dist/api/app-routes.d.ts.map +1 -0
  14. package/dist/api/app-routes.js +150 -0
  15. package/dist/api/app-routes.js.map +1 -0
  16. package/dist/api/docker-routes.d.ts +2 -0
  17. package/dist/api/docker-routes.d.ts.map +1 -0
  18. package/dist/api/docker-routes.js +167 -0
  19. package/dist/api/docker-routes.js.map +1 -0
  20. package/dist/api/middleware.d.ts +6 -0
  21. package/dist/api/middleware.d.ts.map +1 -0
  22. package/dist/api/middleware.js +293 -0
  23. package/dist/api/middleware.js.map +1 -0
  24. package/dist/api/pin-auth.d.ts +65 -0
  25. package/dist/api/pin-auth.d.ts.map +1 -0
  26. package/dist/api/pin-auth.js +218 -0
  27. package/dist/api/pin-auth.js.map +1 -0
  28. package/dist/api/routes.d.ts +2 -0
  29. package/dist/api/routes.d.ts.map +1 -0
  30. package/dist/api/routes.js +473 -0
  31. package/dist/api/routes.js.map +1 -0
  32. package/dist/api/settings-routes.d.ts +2 -0
  33. package/dist/api/settings-routes.d.ts.map +1 -0
  34. package/dist/api/settings-routes.js +570 -0
  35. package/dist/api/settings-routes.js.map +1 -0
  36. package/dist/api/skill-routes.d.ts +2 -0
  37. package/dist/api/skill-routes.d.ts.map +1 -0
  38. package/dist/api/skill-routes.js +88 -0
  39. package/dist/api/skill-routes.js.map +1 -0
  40. package/dist/api/terminal-routes.d.ts +2 -0
  41. package/dist/api/terminal-routes.d.ts.map +1 -0
  42. package/dist/api/terminal-routes.js +3524 -0
  43. package/dist/api/terminal-routes.js.map +1 -0
  44. package/dist/api/tunnel-routes.d.ts +2 -0
  45. package/dist/api/tunnel-routes.d.ts.map +1 -0
  46. package/dist/api/tunnel-routes.js +196 -0
  47. package/dist/api/tunnel-routes.js.map +1 -0
  48. package/dist/api/workspace-routes.d.ts +3 -0
  49. package/dist/api/workspace-routes.d.ts.map +1 -0
  50. package/dist/api/workspace-routes.js +649 -0
  51. package/dist/api/workspace-routes.js.map +1 -0
  52. package/dist/cli.d.ts +3 -0
  53. package/dist/cli.d.ts.map +1 -0
  54. package/dist/cli.js +276 -0
  55. package/dist/cli.js.map +1 -0
  56. package/dist/client/assets/index-B4r0njGe.js +780 -0
  57. package/dist/client/assets/index-CY_9MyE0.css +1 -0
  58. package/dist/client/favicon.svg +5 -0
  59. package/dist/client/icons/icon-192.svg +5 -0
  60. package/dist/client/icons/icon-512.svg +5 -0
  61. package/dist/client/icons/logo-with-message.png +0 -0
  62. package/dist/client/icons/logo.png +0 -0
  63. package/dist/client/index.html +25 -0
  64. package/dist/client/manifest.json +62 -0
  65. package/dist/client/sw.js +243 -0
  66. package/dist/config/agent-usage.d.ts +34 -0
  67. package/dist/config/agent-usage.d.ts.map +1 -0
  68. package/dist/config/agent-usage.js +87 -0
  69. package/dist/config/agent-usage.js.map +1 -0
  70. package/dist/config/repos.d.ts +34 -0
  71. package/dist/config/repos.d.ts.map +1 -0
  72. package/dist/config/repos.js +412 -0
  73. package/dist/config/repos.js.map +1 -0
  74. package/dist/config/settings.d.ts +634 -0
  75. package/dist/config/settings.d.ts.map +1 -0
  76. package/dist/config/settings.js +459 -0
  77. package/dist/config/settings.js.map +1 -0
  78. package/dist/config/skills.d.ts +18 -0
  79. package/dist/config/skills.d.ts.map +1 -0
  80. package/dist/config/skills.js +174 -0
  81. package/dist/config/skills.js.map +1 -0
  82. package/dist/config/workspaces.d.ts +961 -0
  83. package/dist/config/workspaces.d.ts.map +1 -0
  84. package/dist/config/workspaces.js +482 -0
  85. package/dist/config/workspaces.js.map +1 -0
  86. package/dist/core/app-manager.d.ts +85 -0
  87. package/dist/core/app-manager.d.ts.map +1 -0
  88. package/dist/core/app-manager.js +447 -0
  89. package/dist/core/app-manager.js.map +1 -0
  90. package/dist/core/claude-invoker.d.ts +49 -0
  91. package/dist/core/claude-invoker.d.ts.map +1 -0
  92. package/dist/core/claude-invoker.js +583 -0
  93. package/dist/core/claude-invoker.js.map +1 -0
  94. package/dist/core/claude-session-reader.d.ts +25 -0
  95. package/dist/core/claude-session-reader.d.ts.map +1 -0
  96. package/dist/core/claude-session-reader.js +184 -0
  97. package/dist/core/claude-session-reader.js.map +1 -0
  98. package/dist/core/claude-usage-query.d.ts +78 -0
  99. package/dist/core/claude-usage-query.d.ts.map +1 -0
  100. package/dist/core/claude-usage-query.js +294 -0
  101. package/dist/core/claude-usage-query.js.map +1 -0
  102. package/dist/core/git-credential-helper.d.ts +57 -0
  103. package/dist/core/git-credential-helper.d.ts.map +1 -0
  104. package/dist/core/git-credential-helper.js +176 -0
  105. package/dist/core/git-credential-helper.js.map +1 -0
  106. package/dist/core/git-sandbox.d.ts +135 -0
  107. package/dist/core/git-sandbox.d.ts.map +1 -0
  108. package/dist/core/git-sandbox.js +907 -0
  109. package/dist/core/git-sandbox.js.map +1 -0
  110. package/dist/core/github-integration.d.ts +66 -0
  111. package/dist/core/github-integration.d.ts.map +1 -0
  112. package/dist/core/github-integration.js +350 -0
  113. package/dist/core/github-integration.js.map +1 -0
  114. package/dist/core/github-oauth.d.ts +88 -0
  115. package/dist/core/github-oauth.d.ts.map +1 -0
  116. package/dist/core/github-oauth.js +244 -0
  117. package/dist/core/github-oauth.js.map +1 -0
  118. package/dist/core/gitlab-integration.d.ts +66 -0
  119. package/dist/core/gitlab-integration.d.ts.map +1 -0
  120. package/dist/core/gitlab-integration.js +353 -0
  121. package/dist/core/gitlab-integration.js.map +1 -0
  122. package/dist/core/gitlab-oauth.d.ts +100 -0
  123. package/dist/core/gitlab-oauth.d.ts.map +1 -0
  124. package/dist/core/gitlab-oauth.js +366 -0
  125. package/dist/core/gitlab-oauth.js.map +1 -0
  126. package/dist/core/insights-extractor.d.ts +68 -0
  127. package/dist/core/insights-extractor.d.ts.map +1 -0
  128. package/dist/core/insights-extractor.js +402 -0
  129. package/dist/core/insights-extractor.js.map +1 -0
  130. package/dist/core/logger.d.ts +27 -0
  131. package/dist/core/logger.d.ts.map +1 -0
  132. package/dist/core/logger.js +70 -0
  133. package/dist/core/logger.js.map +1 -0
  134. package/dist/core/process-runner.d.ts +27 -0
  135. package/dist/core/process-runner.d.ts.map +1 -0
  136. package/dist/core/process-runner.js +147 -0
  137. package/dist/core/process-runner.js.map +1 -0
  138. package/dist/core/project-detector.d.ts +30 -0
  139. package/dist/core/project-detector.d.ts.map +1 -0
  140. package/dist/core/project-detector.js +482 -0
  141. package/dist/core/project-detector.js.map +1 -0
  142. package/dist/core/qr-generator.d.ts +18 -0
  143. package/dist/core/qr-generator.d.ts.map +1 -0
  144. package/dist/core/qr-generator.js +61 -0
  145. package/dist/core/qr-generator.js.map +1 -0
  146. package/dist/core/remote-tunnel-manager.d.ts +59 -0
  147. package/dist/core/remote-tunnel-manager.d.ts.map +1 -0
  148. package/dist/core/remote-tunnel-manager.js +235 -0
  149. package/dist/core/remote-tunnel-manager.js.map +1 -0
  150. package/dist/core/shared-docker-manager.d.ts +41 -0
  151. package/dist/core/shared-docker-manager.d.ts.map +1 -0
  152. package/dist/core/shared-docker-manager.js +409 -0
  153. package/dist/core/shared-docker-manager.js.map +1 -0
  154. package/dist/core/skill-executor.d.ts +25 -0
  155. package/dist/core/skill-executor.d.ts.map +1 -0
  156. package/dist/core/skill-executor.js +171 -0
  157. package/dist/core/skill-executor.js.map +1 -0
  158. package/dist/core/terminal-session.d.ts +149 -0
  159. package/dist/core/terminal-session.d.ts.map +1 -0
  160. package/dist/core/terminal-session.js +2340 -0
  161. package/dist/core/terminal-session.js.map +1 -0
  162. package/dist/core/tunnel-manager.d.ts +35 -0
  163. package/dist/core/tunnel-manager.d.ts.map +1 -0
  164. package/dist/core/tunnel-manager.js +137 -0
  165. package/dist/core/tunnel-manager.js.map +1 -0
  166. package/dist/core/usage-manager.d.ts +57 -0
  167. package/dist/core/usage-manager.d.ts.map +1 -0
  168. package/dist/core/usage-manager.js +363 -0
  169. package/dist/core/usage-manager.js.map +1 -0
  170. package/dist/core/ws-manager.d.ts +39 -0
  171. package/dist/core/ws-manager.d.ts.map +1 -0
  172. package/dist/core/ws-manager.js +190 -0
  173. package/dist/core/ws-manager.js.map +1 -0
  174. package/dist/index.d.ts +7 -0
  175. package/dist/index.d.ts.map +1 -0
  176. package/dist/index.js +229 -0
  177. package/dist/index.js.map +1 -0
  178. package/dist/types.d.ts +868 -0
  179. package/dist/types.d.ts.map +1 -0
  180. package/dist/types.js +119 -0
  181. package/dist/types.js.map +1 -0
  182. package/package.json +96 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-usage.js","sourceRoot":"","sources":["../../src/config/agent-usage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import { RepoConfig } from '../types.js';
2
+ export declare class RepoRegistry {
3
+ private repos;
4
+ private allowedBasePaths;
5
+ private scanPaths;
6
+ private manualRepos;
7
+ private branchPrefix?;
8
+ constructor();
9
+ private load;
10
+ private scanForRepos;
11
+ private scanSinglePath;
12
+ private generateRepoConfig;
13
+ private mergeWithWorkspaceConfig;
14
+ private createDefaultConfig;
15
+ private validateRepoPath;
16
+ get(id: string): RepoConfig | undefined;
17
+ getAll(): RepoConfig[];
18
+ getBranchPrefix(): string | undefined;
19
+ add(repo: RepoConfig): void;
20
+ remove(id: string): boolean;
21
+ private save;
22
+ private isAutoDiscovered;
23
+ reload(): void;
24
+ getScanPaths(): string[];
25
+ getRepoCategory(repoPath: string): 'work-github' | 'personal-github' | 'local';
26
+ addScanPath(scanPath: string): {
27
+ addedRepos: string[];
28
+ scanPath: string;
29
+ };
30
+ removeScanPath(scanPath: string): boolean;
31
+ private saveConfig;
32
+ }
33
+ export declare const repoRegistry: RepoRegistry;
34
+ //# sourceMappingURL=repos.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repos.d.ts","sourceRoot":"","sources":["../../src/config/repos.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,UAAU,EAAoB,MAAM,aAAa,CAAC;AAkB3D,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAsC;IACnD,OAAO,CAAC,gBAAgB,CAAW;IACnC,OAAO,CAAC,SAAS,CAAW;IAC5B,OAAO,CAAC,WAAW,CAAoB;IACvC,OAAO,CAAC,YAAY,CAAC,CAAS;;IAQ9B,OAAO,CAAC,IAAI;IA0CZ,OAAO,CAAC,YAAY;IA6BpB,OAAO,CAAC,cAAc;IAgEtB,OAAO,CAAC,kBAAkB;IA8F1B,OAAO,CAAC,wBAAwB;IA8BhC,OAAO,CAAC,mBAAmB;IAS3B,OAAO,CAAC,gBAAgB;IAiBxB,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAIvC,MAAM,IAAI,UAAU,EAAE;IAItB,eAAe,IAAI,MAAM,GAAG,SAAS;IAIrC,GAAG,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI;IAO3B,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAQ3B,OAAO,CAAC,IAAI;IAeZ,OAAO,CAAC,gBAAgB;IAOxB,MAAM,IAAI,IAAI;IAMd,YAAY,IAAI,MAAM,EAAE;IAKxB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,GAAG,iBAAiB,GAAG,OAAO;IAqB9E,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG;QAAE,UAAU,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE;IA2CzE,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAgCzC,OAAO,CAAC,UAAU;CAQnB;AAED,eAAO,MAAM,YAAY,cAAqB,CAAC"}
@@ -0,0 +1,412 @@
1
+ import { readFileSync, existsSync, writeFileSync, readdirSync, statSync } from 'fs';
2
+ import { join, normalize, sep } from 'path';
3
+ import { homedir } from 'os';
4
+ import { z } from 'zod';
5
+ import { RepoConfigSchema } from '../types.js';
6
+ import { workspaceManager } from './workspaces.js';
7
+ const CONFIG_PATH = join(process.cwd(), 'config', 'repos.json');
8
+ // Allowlisted base paths for repos (platform-agnostic)
9
+ const ALLOWED_BASE_PATHS = [
10
+ join(homedir(), 'claudedesk', 'repos'),
11
+ join(homedir(), 'repositories'),
12
+ ];
13
+ const ReposFileSchema = z.object({
14
+ repos: z.array(RepoConfigSchema),
15
+ allowedBasePaths: z.array(z.string()).optional(),
16
+ scanPaths: z.array(z.string()).optional(),
17
+ branchPrefix: z.string().optional(),
18
+ });
19
+ export class RepoRegistry {
20
+ repos = new Map();
21
+ allowedBasePaths;
22
+ scanPaths;
23
+ manualRepos = [];
24
+ branchPrefix;
25
+ constructor() {
26
+ this.allowedBasePaths = ALLOWED_BASE_PATHS;
27
+ this.scanPaths = [];
28
+ this.load();
29
+ }
30
+ load() {
31
+ console.log('[RepoRegistry] load() called');
32
+ if (!existsSync(CONFIG_PATH)) {
33
+ console.log('[RepoRegistry] Creating default config');
34
+ this.createDefaultConfig();
35
+ }
36
+ try {
37
+ const content = readFileSync(CONFIG_PATH, 'utf-8');
38
+ console.log('[RepoRegistry] Config file loaded');
39
+ const parsed = ReposFileSchema.parse(JSON.parse(content));
40
+ console.log('[RepoRegistry] Config parsed, repos in file:', parsed.repos.length);
41
+ if (parsed.allowedBasePaths) {
42
+ this.allowedBasePaths = parsed.allowedBasePaths;
43
+ }
44
+ if (parsed.scanPaths) {
45
+ this.scanPaths = parsed.scanPaths;
46
+ console.log('[RepoRegistry] Loaded scanPaths:', this.scanPaths);
47
+ }
48
+ if (parsed.branchPrefix) {
49
+ this.branchPrefix = parsed.branchPrefix;
50
+ }
51
+ // Load manually configured repos
52
+ this.manualRepos = parsed.repos;
53
+ for (const repo of parsed.repos) {
54
+ this.validateRepoPath(repo.path);
55
+ this.repos.set(repo.id, repo);
56
+ }
57
+ console.log('[RepoRegistry] Manual repos loaded:', this.manualRepos.length);
58
+ // Auto-discover repos from scan paths
59
+ this.scanForRepos();
60
+ }
61
+ catch (error) {
62
+ console.error('[RepoRegistry] Failed to load repos config:', error);
63
+ throw new Error(`Failed to load repos config: ${error}`);
64
+ }
65
+ }
66
+ scanForRepos() {
67
+ console.log('[RepoRegistry] scanForRepos() called');
68
+ console.log('[RepoRegistry] Legacy scanPaths:', this.scanPaths);
69
+ // First, scan legacy scan paths (for backwards compatibility)
70
+ for (const scanPath of this.scanPaths) {
71
+ console.log(`[RepoRegistry] Scanning legacy path: ${scanPath}`);
72
+ this.scanSinglePath(scanPath);
73
+ }
74
+ console.log('[RepoRegistry] After legacy scan, repos:', this.repos.size);
75
+ // Then, scan workspace paths
76
+ const workspaces = workspaceManager.getAll();
77
+ console.log('[RepoRegistry] Workspaces found:', workspaces.length, workspaces.map(w => w.id));
78
+ for (const workspace of workspaces) {
79
+ console.log(`[RepoRegistry] Scanning workspace ${workspace.id} path: ${workspace.scanPath}`);
80
+ if (workspace.scanPath && existsSync(workspace.scanPath)) {
81
+ this.scanSinglePath(workspace.scanPath, workspace.id);
82
+ }
83
+ else {
84
+ console.log(`[RepoRegistry] Skipping workspace ${workspace.id} - path doesn't exist or is empty`);
85
+ }
86
+ }
87
+ console.log('[RepoRegistry] Final repo count:', this.repos.size);
88
+ console.log('[RepoRegistry] Repo IDs:', Array.from(this.repos.keys()));
89
+ }
90
+ scanSinglePath(scanPath, workspaceId) {
91
+ console.log(`[RepoRegistry] scanSinglePath(${scanPath}, ${workspaceId})`);
92
+ if (!existsSync(scanPath)) {
93
+ console.warn(`[RepoRegistry] Scan path does not exist: ${scanPath}`);
94
+ return;
95
+ }
96
+ try {
97
+ const entries = readdirSync(scanPath);
98
+ console.log(`[RepoRegistry] Found ${entries.length} entries in ${scanPath}`);
99
+ for (const entry of entries) {
100
+ const fullPath = join(scanPath, entry);
101
+ // Skip if not a directory
102
+ if (!statSync(fullPath).isDirectory())
103
+ continue;
104
+ // Skip if already manually configured
105
+ const existingRepo = Array.from(this.repos.values()).find(r => r.path.toLowerCase() === fullPath.toLowerCase());
106
+ if (existingRepo) {
107
+ console.log(`[RepoRegistry] ${entry}: Already exists, updating workspaceId to ${workspaceId}`);
108
+ // Update workspaceId if discovered from a workspace
109
+ if (workspaceId && !existingRepo.workspaceId) {
110
+ existingRepo.workspaceId = workspaceId;
111
+ }
112
+ // Apply workspace config override to existing repo
113
+ if (workspaceId) {
114
+ const merged = this.mergeWithWorkspaceConfig(existingRepo, workspaceId);
115
+ existingRepo.proof = merged.proof;
116
+ existingRepo.port = merged.port;
117
+ existingRepo.commands = merged.commands;
118
+ }
119
+ continue;
120
+ }
121
+ // Check if it's a valid repo (has .git or package.json)
122
+ const hasGit = existsSync(join(fullPath, '.git'));
123
+ const hasPackageJson = existsSync(join(fullPath, 'package.json'));
124
+ if (!hasGit && !hasPackageJson) {
125
+ console.log(`[RepoRegistry] ${entry}: Skipping (no .git or package.json)`);
126
+ continue;
127
+ }
128
+ console.log(`[RepoRegistry] ${entry}: Generating config (git=${hasGit}, pkg=${hasPackageJson})`);
129
+ // Auto-generate repo config
130
+ let repoConfig = this.generateRepoConfig(fullPath, entry, workspaceId);
131
+ if (repoConfig) {
132
+ // Merge with workspace config overrides if available
133
+ if (workspaceId) {
134
+ repoConfig = this.mergeWithWorkspaceConfig(repoConfig, workspaceId);
135
+ }
136
+ console.log(`[RepoRegistry] ${entry}: Added with workspaceId=${repoConfig.workspaceId}`);
137
+ this.repos.set(repoConfig.id, repoConfig);
138
+ }
139
+ }
140
+ }
141
+ catch (error) {
142
+ console.error(`[RepoRegistry] Failed to scan ${scanPath}:`, error);
143
+ }
144
+ }
145
+ generateRepoConfig(repoPath, dirName, workspaceId) {
146
+ const id = dirName.toLowerCase().replace(/[^a-z0-9-]/g, '-');
147
+ // Detect project type and generate appropriate config
148
+ const hasPackageJson = existsSync(join(repoPath, 'package.json'));
149
+ const hasCargoToml = existsSync(join(repoPath, 'Cargo.toml'));
150
+ const hasPyProject = existsSync(join(repoPath, 'pyproject.toml')) || existsSync(join(repoPath, 'setup.py'));
151
+ const hasGoMod = existsSync(join(repoPath, 'go.mod'));
152
+ let commands = {};
153
+ let proof = { mode: 'cli', cli: { command: 'echo "No proof configured"' } };
154
+ let port;
155
+ if (hasPackageJson) {
156
+ // Read package.json for scripts
157
+ try {
158
+ const pkg = JSON.parse(readFileSync(join(repoPath, 'package.json'), 'utf-8'));
159
+ const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
160
+ commands = {
161
+ install: 'npm install',
162
+ build: pkg.scripts?.build ? 'npm run build' : undefined,
163
+ test: pkg.scripts?.test && pkg.scripts.test !== 'echo "Error: no test specified" && exit 1' ? 'npm test' : undefined,
164
+ run: pkg.scripts?.dev ? 'npm run dev' : (pkg.scripts?.start ? 'npm start' : undefined),
165
+ };
166
+ // Detect port and proof mode based on framework
167
+ if (pkg.scripts?.dev || pkg.scripts?.start) {
168
+ // Check if it's a frontend framework (use web proof with screenshot)
169
+ const isFrontend = allDeps['vite'] || allDeps['next'] || allDeps['react-scripts'] ||
170
+ allDeps['react'] || allDeps['vue'] || allDeps['svelte'] ||
171
+ allDeps['@angular/core'];
172
+ // Check if it's a backend API framework (use api health check)
173
+ const isBackend = allDeps['express'] || allDeps['fastify'] || allDeps['@nestjs/core'] ||
174
+ allDeps['koa'] || allDeps['hapi'] || allDeps['restify'];
175
+ // Vite uses port 5173 by default
176
+ if (allDeps['vite']) {
177
+ port = 5173;
178
+ }
179
+ // Next.js uses port 3000
180
+ else if (allDeps['next']) {
181
+ port = 3000;
182
+ }
183
+ // Create React App uses port 3000
184
+ else if (allDeps['react-scripts']) {
185
+ port = 3000;
186
+ }
187
+ // Default to 3000
188
+ else {
189
+ port = 3000;
190
+ }
191
+ // Use web proof for frontend apps (takes screenshot), api proof for backends
192
+ if (isFrontend && !isBackend) {
193
+ proof = { mode: 'web', web: { url: `http://localhost:${port}` } };
194
+ }
195
+ else {
196
+ proof = { mode: 'api', api: { healthUrl: `http://localhost:${port}`, timeout: 30000 } };
197
+ }
198
+ }
199
+ }
200
+ catch {
201
+ commands = { install: 'npm install' };
202
+ }
203
+ }
204
+ else if (hasCargoToml) {
205
+ commands = {
206
+ build: 'cargo build',
207
+ test: 'cargo test',
208
+ run: 'cargo run',
209
+ };
210
+ }
211
+ else if (hasPyProject) {
212
+ commands = {
213
+ install: 'pip install -e .',
214
+ test: 'pytest',
215
+ run: 'python -m ' + id.replace(/-/g, '_'),
216
+ };
217
+ }
218
+ else if (hasGoMod) {
219
+ commands = {
220
+ build: 'go build',
221
+ test: 'go test ./...',
222
+ run: 'go run .',
223
+ };
224
+ }
225
+ return {
226
+ id,
227
+ path: repoPath,
228
+ commands,
229
+ proof,
230
+ port,
231
+ workspaceId,
232
+ };
233
+ }
234
+ mergeWithWorkspaceConfig(repo, workspaceId) {
235
+ const workspace = workspaceManager.get(workspaceId);
236
+ const override = workspace?.repoConfigs?.[repo.id];
237
+ if (!override)
238
+ return repo;
239
+ console.log(`[RepoRegistry] Applying workspace config override for ${repo.id}`);
240
+ // Merge proof config, ensuring timeout has a default if api mode is used
241
+ let mergedProof = repo.proof;
242
+ if (override.proof) {
243
+ mergedProof = {
244
+ ...override.proof,
245
+ api: override.proof.api ? {
246
+ ...override.proof.api,
247
+ timeout: override.proof.api.timeout ?? 30000,
248
+ } : undefined,
249
+ };
250
+ }
251
+ return {
252
+ ...repo,
253
+ proof: mergedProof,
254
+ port: override.port ?? repo.port,
255
+ commands: override.commands
256
+ ? { ...repo.commands, ...override.commands }
257
+ : repo.commands,
258
+ };
259
+ }
260
+ createDefaultConfig() {
261
+ const defaultConfig = {
262
+ allowedBasePaths: ALLOWED_BASE_PATHS,
263
+ scanPaths: [],
264
+ repos: [],
265
+ };
266
+ writeFileSync(CONFIG_PATH, JSON.stringify(defaultConfig, null, 2));
267
+ }
268
+ validateRepoPath(repoPath) {
269
+ const normalizedPath = normalize(repoPath);
270
+ // Check both allowedBasePaths and scanPaths
271
+ const allAllowedPaths = [...this.allowedBasePaths, ...this.scanPaths];
272
+ const isAllowed = allAllowedPaths.some(basePath => normalizedPath.toLowerCase().startsWith(normalize(basePath).toLowerCase()));
273
+ if (!isAllowed) {
274
+ throw new Error(`Repo path "${repoPath}" is not under an allowed base path. ` +
275
+ `Allowed: ${allAllowedPaths.join(', ')}`);
276
+ }
277
+ }
278
+ get(id) {
279
+ return this.repos.get(id);
280
+ }
281
+ getAll() {
282
+ return Array.from(this.repos.values());
283
+ }
284
+ getBranchPrefix() {
285
+ return this.branchPrefix;
286
+ }
287
+ add(repo) {
288
+ const validated = RepoConfigSchema.parse(repo);
289
+ this.validateRepoPath(validated.path);
290
+ this.repos.set(validated.id, validated);
291
+ this.save();
292
+ }
293
+ remove(id) {
294
+ const deleted = this.repos.delete(id);
295
+ if (deleted) {
296
+ this.save();
297
+ }
298
+ return deleted;
299
+ }
300
+ save() {
301
+ // Only save manually configured repos, not auto-discovered ones
302
+ const manualRepoIds = new Set(this.manualRepos.map(r => r.id));
303
+ const reposToSave = Array.from(this.repos.values()).filter(r => manualRepoIds.has(r.id) || !this.isAutoDiscovered(r.path));
304
+ const config = {
305
+ allowedBasePaths: this.allowedBasePaths,
306
+ scanPaths: this.scanPaths,
307
+ repos: reposToSave,
308
+ };
309
+ writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2));
310
+ }
311
+ isAutoDiscovered(repoPath) {
312
+ return this.scanPaths.some(scanPath => repoPath.toLowerCase().startsWith(scanPath.toLowerCase()));
313
+ }
314
+ // Reload repos (useful after adding new scan paths)
315
+ reload() {
316
+ this.repos.clear();
317
+ this.load();
318
+ }
319
+ // Get current scan paths
320
+ getScanPaths() {
321
+ return [...this.scanPaths];
322
+ }
323
+ // Determine repo category based on folder path
324
+ getRepoCategory(repoPath) {
325
+ const normalizedPath = normalize(repoPath).toLowerCase();
326
+ // Check which scan path this repo falls under
327
+ for (const scanPath of this.scanPaths) {
328
+ const normalizedScanPath = normalize(scanPath).toLowerCase();
329
+ if (normalizedPath.startsWith(normalizedScanPath)) {
330
+ // Determine category from scan path name
331
+ if (normalizedScanPath.includes(`${sep}work`)) {
332
+ return 'work-github';
333
+ }
334
+ else if (normalizedScanPath.includes(`${sep}personal`)) {
335
+ return 'personal-github';
336
+ }
337
+ }
338
+ }
339
+ // Default to local if not in any known scan path
340
+ return 'local';
341
+ }
342
+ // Add a scan path and discover repos
343
+ addScanPath(scanPath) {
344
+ // Normalize path and remove trailing separator
345
+ const normalizedPath = normalize(scanPath).replace(new RegExp(`${sep.replace(/\\/g, '\\\\')}$`), '');
346
+ // Check if path exists
347
+ if (!existsSync(normalizedPath)) {
348
+ throw new Error(`Path does not exist: ${normalizedPath}`);
349
+ }
350
+ // Check if it's a directory
351
+ if (!statSync(normalizedPath).isDirectory()) {
352
+ throw new Error(`Path is not a directory: ${normalizedPath}`);
353
+ }
354
+ // Check if already added
355
+ if (this.scanPaths.some(p => p.toLowerCase() === normalizedPath.toLowerCase())) {
356
+ // Just rescan and return
357
+ const beforeCount = this.repos.size;
358
+ this.scanForRepos();
359
+ const addedRepos = Array.from(this.repos.values())
360
+ .filter(r => r.path.toLowerCase().startsWith(normalizedPath.toLowerCase()))
361
+ .map(r => r.id);
362
+ return { addedRepos, scanPath: normalizedPath };
363
+ }
364
+ // Add to scan paths
365
+ this.scanPaths.push(normalizedPath);
366
+ // Scan for repos in this path
367
+ const reposBefore = new Set(this.repos.keys());
368
+ this.scanForRepos();
369
+ const reposAfter = new Set(this.repos.keys());
370
+ // Find newly added repos
371
+ const addedRepos = Array.from(reposAfter).filter(id => !reposBefore.has(id));
372
+ // Save config
373
+ this.saveConfig();
374
+ return { addedRepos, scanPath: normalizedPath };
375
+ }
376
+ // Remove a scan path
377
+ removeScanPath(scanPath) {
378
+ const normalizedPath = normalize(scanPath).replace(new RegExp(`${sep.replace(/\\/g, '\\\\')}$`), '');
379
+ const index = this.scanPaths.findIndex(p => p.toLowerCase() === normalizedPath.toLowerCase());
380
+ if (index === -1) {
381
+ return false;
382
+ }
383
+ // Remove the scan path
384
+ this.scanPaths.splice(index, 1);
385
+ // Remove repos that were discovered from this path
386
+ const reposToRemove = [];
387
+ for (const [id, repo] of this.repos) {
388
+ if (repo.path.toLowerCase().startsWith(normalizedPath.toLowerCase())) {
389
+ // Only remove if it was auto-discovered (not manually configured)
390
+ if (!this.manualRepos.some(r => r.id === id)) {
391
+ reposToRemove.push(id);
392
+ }
393
+ }
394
+ }
395
+ for (const id of reposToRemove) {
396
+ this.repos.delete(id);
397
+ }
398
+ // Save config
399
+ this.saveConfig();
400
+ return true;
401
+ }
402
+ saveConfig() {
403
+ const config = {
404
+ allowedBasePaths: this.allowedBasePaths,
405
+ scanPaths: this.scanPaths,
406
+ repos: this.manualRepos,
407
+ };
408
+ writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2));
409
+ }
410
+ }
411
+ export const repoRegistry = new RepoRegistry();
412
+ //# sourceMappingURL=repos.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repos.js","sourceRoot":"","sources":["../../src/config/repos.ts"],"names":[],"mappings":"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"}