@astroanywhere/agent 0.1.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 (203) hide show
  1. package/LICENSE +76 -0
  2. package/README.md +178 -0
  3. package/dist/cli.d.ts +15 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +401 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/commands/index.d.ts +9 -0
  8. package/dist/commands/index.d.ts.map +1 -0
  9. package/dist/commands/index.js +9 -0
  10. package/dist/commands/index.js.map +1 -0
  11. package/dist/commands/mcp.d.ts +16 -0
  12. package/dist/commands/mcp.d.ts.map +1 -0
  13. package/dist/commands/mcp.js +19 -0
  14. package/dist/commands/mcp.js.map +1 -0
  15. package/dist/commands/setup.d.ts +20 -0
  16. package/dist/commands/setup.d.ts.map +1 -0
  17. package/dist/commands/setup.js +585 -0
  18. package/dist/commands/setup.js.map +1 -0
  19. package/dist/commands/start.d.ts +16 -0
  20. package/dist/commands/start.d.ts.map +1 -0
  21. package/dist/commands/start.js +638 -0
  22. package/dist/commands/start.js.map +1 -0
  23. package/dist/commands/status.d.ts +5 -0
  24. package/dist/commands/status.d.ts.map +1 -0
  25. package/dist/commands/status.js +63 -0
  26. package/dist/commands/status.js.map +1 -0
  27. package/dist/commands/stop.d.ts +5 -0
  28. package/dist/commands/stop.d.ts.map +1 -0
  29. package/dist/commands/stop.js +85 -0
  30. package/dist/commands/stop.js.map +1 -0
  31. package/dist/execution/direct-strategy.d.ts +18 -0
  32. package/dist/execution/direct-strategy.d.ts.map +1 -0
  33. package/dist/execution/direct-strategy.js +156 -0
  34. package/dist/execution/direct-strategy.js.map +1 -0
  35. package/dist/execution/docker-strategy.d.ts +26 -0
  36. package/dist/execution/docker-strategy.d.ts.map +1 -0
  37. package/dist/execution/docker-strategy.js +222 -0
  38. package/dist/execution/docker-strategy.js.map +1 -0
  39. package/dist/execution/index.d.ts +14 -0
  40. package/dist/execution/index.d.ts.map +1 -0
  41. package/dist/execution/index.js +13 -0
  42. package/dist/execution/index.js.map +1 -0
  43. package/dist/execution/kubernetes-exec-strategy.d.ts +23 -0
  44. package/dist/execution/kubernetes-exec-strategy.d.ts.map +1 -0
  45. package/dist/execution/kubernetes-exec-strategy.js +232 -0
  46. package/dist/execution/kubernetes-exec-strategy.js.map +1 -0
  47. package/dist/execution/registry.d.ts +41 -0
  48. package/dist/execution/registry.d.ts.map +1 -0
  49. package/dist/execution/registry.js +84 -0
  50. package/dist/execution/registry.js.map +1 -0
  51. package/dist/execution/slurm-strategy.d.ts +22 -0
  52. package/dist/execution/slurm-strategy.d.ts.map +1 -0
  53. package/dist/execution/slurm-strategy.js +219 -0
  54. package/dist/execution/slurm-strategy.js.map +1 -0
  55. package/dist/execution/types.d.ts +72 -0
  56. package/dist/execution/types.d.ts.map +1 -0
  57. package/dist/execution/types.js +10 -0
  58. package/dist/execution/types.js.map +1 -0
  59. package/dist/index.d.ts +22 -0
  60. package/dist/index.d.ts.map +1 -0
  61. package/dist/index.js +22 -0
  62. package/dist/index.js.map +1 -0
  63. package/dist/lib/api-client.d.ts +35 -0
  64. package/dist/lib/api-client.d.ts.map +1 -0
  65. package/dist/lib/api-client.js +126 -0
  66. package/dist/lib/api-client.js.map +1 -0
  67. package/dist/lib/config.d.ts +174 -0
  68. package/dist/lib/config.d.ts.map +1 -0
  69. package/dist/lib/config.js +399 -0
  70. package/dist/lib/config.js.map +1 -0
  71. package/dist/lib/copy-worktree.d.ts +73 -0
  72. package/dist/lib/copy-worktree.d.ts.map +1 -0
  73. package/dist/lib/copy-worktree.js +374 -0
  74. package/dist/lib/copy-worktree.js.map +1 -0
  75. package/dist/lib/git-pr.d.ts +63 -0
  76. package/dist/lib/git-pr.d.ts.map +1 -0
  77. package/dist/lib/git-pr.js +224 -0
  78. package/dist/lib/git-pr.js.map +1 -0
  79. package/dist/lib/hardware-id.d.ts +25 -0
  80. package/dist/lib/hardware-id.d.ts.map +1 -0
  81. package/dist/lib/hardware-id.js +186 -0
  82. package/dist/lib/hardware-id.js.map +1 -0
  83. package/dist/lib/hpc-context.d.ts +35 -0
  84. package/dist/lib/hpc-context.d.ts.map +1 -0
  85. package/dist/lib/hpc-context.js +167 -0
  86. package/dist/lib/hpc-context.js.map +1 -0
  87. package/dist/lib/prompt-templates.d.ts +195 -0
  88. package/dist/lib/prompt-templates.d.ts.map +1 -0
  89. package/dist/lib/prompt-templates.js +353 -0
  90. package/dist/lib/prompt-templates.js.map +1 -0
  91. package/dist/lib/providers.d.ts +27 -0
  92. package/dist/lib/providers.d.ts.map +1 -0
  93. package/dist/lib/providers.js +372 -0
  94. package/dist/lib/providers.js.map +1 -0
  95. package/dist/lib/repo-context.d.ts +18 -0
  96. package/dist/lib/repo-context.d.ts.map +1 -0
  97. package/dist/lib/repo-context.js +61 -0
  98. package/dist/lib/repo-context.js.map +1 -0
  99. package/dist/lib/repo-utils.d.ts +35 -0
  100. package/dist/lib/repo-utils.d.ts.map +1 -0
  101. package/dist/lib/repo-utils.js +222 -0
  102. package/dist/lib/repo-utils.js.map +1 -0
  103. package/dist/lib/resources.d.ts +17 -0
  104. package/dist/lib/resources.d.ts.map +1 -0
  105. package/dist/lib/resources.js +227 -0
  106. package/dist/lib/resources.js.map +1 -0
  107. package/dist/lib/slurm-detect.d.ts +15 -0
  108. package/dist/lib/slurm-detect.d.ts.map +1 -0
  109. package/dist/lib/slurm-detect.js +148 -0
  110. package/dist/lib/slurm-detect.js.map +1 -0
  111. package/dist/lib/slurm-executor.d.ts +70 -0
  112. package/dist/lib/slurm-executor.d.ts.map +1 -0
  113. package/dist/lib/slurm-executor.js +402 -0
  114. package/dist/lib/slurm-executor.js.map +1 -0
  115. package/dist/lib/slurm-job-monitor.d.ts +52 -0
  116. package/dist/lib/slurm-job-monitor.d.ts.map +1 -0
  117. package/dist/lib/slurm-job-monitor.js +212 -0
  118. package/dist/lib/slurm-job-monitor.js.map +1 -0
  119. package/dist/lib/ssh-discovery.d.ts +17 -0
  120. package/dist/lib/ssh-discovery.d.ts.map +1 -0
  121. package/dist/lib/ssh-discovery.js +287 -0
  122. package/dist/lib/ssh-discovery.js.map +1 -0
  123. package/dist/lib/ssh-installer.d.ts +69 -0
  124. package/dist/lib/ssh-installer.d.ts.map +1 -0
  125. package/dist/lib/ssh-installer.js +230 -0
  126. package/dist/lib/ssh-installer.js.map +1 -0
  127. package/dist/lib/streaming-prompt.d.ts +48 -0
  128. package/dist/lib/streaming-prompt.d.ts.map +1 -0
  129. package/dist/lib/streaming-prompt.js +91 -0
  130. package/dist/lib/streaming-prompt.js.map +1 -0
  131. package/dist/lib/task-executor.d.ts +114 -0
  132. package/dist/lib/task-executor.d.ts.map +1 -0
  133. package/dist/lib/task-executor.js +753 -0
  134. package/dist/lib/task-executor.js.map +1 -0
  135. package/dist/lib/websocket-client.d.ts +200 -0
  136. package/dist/lib/websocket-client.d.ts.map +1 -0
  137. package/dist/lib/websocket-client.js +781 -0
  138. package/dist/lib/websocket-client.js.map +1 -0
  139. package/dist/lib/workdir-safety.d.ts +63 -0
  140. package/dist/lib/workdir-safety.d.ts.map +1 -0
  141. package/dist/lib/workdir-safety.js +247 -0
  142. package/dist/lib/workdir-safety.js.map +1 -0
  143. package/dist/lib/worktree-include.d.ts +14 -0
  144. package/dist/lib/worktree-include.d.ts.map +1 -0
  145. package/dist/lib/worktree-include.js +68 -0
  146. package/dist/lib/worktree-include.js.map +1 -0
  147. package/dist/lib/worktree-setup.d.ts +18 -0
  148. package/dist/lib/worktree-setup.d.ts.map +1 -0
  149. package/dist/lib/worktree-setup.js +60 -0
  150. package/dist/lib/worktree-setup.js.map +1 -0
  151. package/dist/lib/worktree.d.ts +37 -0
  152. package/dist/lib/worktree.d.ts.map +1 -0
  153. package/dist/lib/worktree.js +411 -0
  154. package/dist/lib/worktree.js.map +1 -0
  155. package/dist/mcp/index.d.ts +8 -0
  156. package/dist/mcp/index.d.ts.map +1 -0
  157. package/dist/mcp/index.js +8 -0
  158. package/dist/mcp/index.js.map +1 -0
  159. package/dist/mcp/server.d.ts +45 -0
  160. package/dist/mcp/server.d.ts.map +1 -0
  161. package/dist/mcp/server.js +153 -0
  162. package/dist/mcp/server.js.map +1 -0
  163. package/dist/mcp/session-bridge.d.ts +87 -0
  164. package/dist/mcp/session-bridge.d.ts.map +1 -0
  165. package/dist/mcp/session-bridge.js +317 -0
  166. package/dist/mcp/session-bridge.js.map +1 -0
  167. package/dist/mcp/tools.d.ts +70 -0
  168. package/dist/mcp/tools.d.ts.map +1 -0
  169. package/dist/mcp/tools.js +234 -0
  170. package/dist/mcp/tools.js.map +1 -0
  171. package/dist/mcp/types.d.ts +197 -0
  172. package/dist/mcp/types.d.ts.map +1 -0
  173. package/dist/mcp/types.js +16 -0
  174. package/dist/mcp/types.js.map +1 -0
  175. package/dist/providers/base-adapter.d.ts +56 -0
  176. package/dist/providers/base-adapter.d.ts.map +1 -0
  177. package/dist/providers/base-adapter.js +5 -0
  178. package/dist/providers/base-adapter.js.map +1 -0
  179. package/dist/providers/claude-code-adapter.d.ts +27 -0
  180. package/dist/providers/claude-code-adapter.d.ts.map +1 -0
  181. package/dist/providers/claude-code-adapter.js +298 -0
  182. package/dist/providers/claude-code-adapter.js.map +1 -0
  183. package/dist/providers/claude-sdk-adapter.d.ts +60 -0
  184. package/dist/providers/claude-sdk-adapter.d.ts.map +1 -0
  185. package/dist/providers/claude-sdk-adapter.js +632 -0
  186. package/dist/providers/claude-sdk-adapter.js.map +1 -0
  187. package/dist/providers/codex-adapter.d.ts +21 -0
  188. package/dist/providers/codex-adapter.d.ts.map +1 -0
  189. package/dist/providers/codex-adapter.js +197 -0
  190. package/dist/providers/codex-adapter.js.map +1 -0
  191. package/dist/providers/index.d.ts +26 -0
  192. package/dist/providers/index.d.ts.map +1 -0
  193. package/dist/providers/index.js +58 -0
  194. package/dist/providers/index.js.map +1 -0
  195. package/dist/providers/slurm-adapter.d.ts +26 -0
  196. package/dist/providers/slurm-adapter.d.ts.map +1 -0
  197. package/dist/providers/slurm-adapter.js +146 -0
  198. package/dist/providers/slurm-adapter.js.map +1 -0
  199. package/dist/types.d.ts +592 -0
  200. package/dist/types.d.ts.map +1 -0
  201. package/dist/types.js +5 -0
  202. package/dist/types.js.map +1 -0
  203. package/package.json +77 -0
@@ -0,0 +1,222 @@
1
+ /**
2
+ * Repo utilities for agent runner.
3
+ *
4
+ * Lightweight versions of the core repo setup logic (isGitRepo, getFileTree,
5
+ * getGitRemoteUrl) that run on remote machines. Skips .gitignore/CLAUDE.md
6
+ * generation since the repo already exists on the remote machine.
7
+ */
8
+ import { execFileSync, execSync } from 'node:child_process';
9
+ import { existsSync, mkdirSync, readFileSync } from 'node:fs';
10
+ import { homedir } from 'node:os';
11
+ import { join } from 'node:path';
12
+ export function isGitRepo(dir) {
13
+ try {
14
+ execFileSync('git', ['rev-parse', '--show-toplevel'], {
15
+ cwd: dir,
16
+ encoding: 'utf-8',
17
+ timeout: 5_000,
18
+ stdio: 'pipe',
19
+ });
20
+ return true;
21
+ }
22
+ catch {
23
+ return false;
24
+ }
25
+ }
26
+ export function getFileTree(dir) {
27
+ if (!existsSync(dir))
28
+ return [];
29
+ try {
30
+ const output = execFileSync('git', ['ls-files'], {
31
+ cwd: dir,
32
+ encoding: 'utf-8',
33
+ timeout: 10_000,
34
+ maxBuffer: 5 * 1024 * 1024,
35
+ });
36
+ return output.trim().split('\n').filter(Boolean);
37
+ }
38
+ catch {
39
+ return [];
40
+ }
41
+ }
42
+ export function getGitRemoteUrl(dir) {
43
+ try {
44
+ const url = execFileSync('git', ['remote', 'get-url', 'origin'], {
45
+ cwd: dir,
46
+ encoding: 'utf-8',
47
+ timeout: 5_000,
48
+ stdio: 'pipe',
49
+ }).trim();
50
+ return url || undefined;
51
+ }
52
+ catch {
53
+ return undefined;
54
+ }
55
+ }
56
+ const KEY_FILE_CAP = 15_000;
57
+ const PKG_FILE_CAP = 5_000;
58
+ /**
59
+ * Read key files from a directory for plan generation context.
60
+ * Returns capped contents of CLAUDE.md, README.md, and package metadata.
61
+ */
62
+ function readKeyFiles(dir) {
63
+ const result = {};
64
+ function readCapped(path, cap) {
65
+ if (!existsSync(path))
66
+ return undefined;
67
+ try {
68
+ const content = readFileSync(path, 'utf-8');
69
+ return content.length > cap ? content.slice(0, cap) + '\n\n[... truncated ...]' : content;
70
+ }
71
+ catch {
72
+ return undefined;
73
+ }
74
+ }
75
+ result.claudeMd = readCapped(join(dir, 'CLAUDE.md'), KEY_FILE_CAP);
76
+ result.readmeMd = readCapped(join(dir, 'README.md'), KEY_FILE_CAP) ?? readCapped(join(dir, 'readme.md'), KEY_FILE_CAP);
77
+ const packageFiles = ['package.json', 'pyproject.toml', 'Cargo.toml', 'go.mod'];
78
+ for (const pkg of packageFiles) {
79
+ const content = readCapped(join(dir, pkg), PKG_FILE_CAP);
80
+ if (content) {
81
+ result.packageInfo = `# ${pkg}\n${content}`;
82
+ break;
83
+ }
84
+ }
85
+ return result;
86
+ }
87
+ /**
88
+ * Extract repository name from a git URL.
89
+ * e.g., "git@github.com:user/repo.git" → "repo"
90
+ */
91
+ function extractRepoName(url) {
92
+ const parts = url.split('/');
93
+ const last = parts[parts.length - 1];
94
+ return last.replace(/\.git$/, '') || 'repo';
95
+ }
96
+ /**
97
+ * Clone a git repository to the specified target directory.
98
+ * If already cloned, fetch latest. Returns the local path.
99
+ *
100
+ * SECURITY: Uses execFileSync with git arguments to prevent command injection
101
+ */
102
+ function cloneRepository(repoUrl, targetDir) {
103
+ if (existsSync(join(targetDir, '.git'))) {
104
+ // Already cloned — fetch latest
105
+ try {
106
+ execFileSync('git', ['fetch', '--all'], {
107
+ cwd: targetDir,
108
+ stdio: 'ignore',
109
+ timeout: 30_000,
110
+ });
111
+ }
112
+ catch {
113
+ // Non-fatal: proceed with stale clone
114
+ }
115
+ }
116
+ else {
117
+ // Ensure parent directory exists
118
+ mkdirSync(join(targetDir, '..'), { recursive: true });
119
+ // Clone the repo using execFileSync to prevent command injection
120
+ execFileSync('git', ['clone', repoUrl, targetDir], {
121
+ stdio: 'ignore',
122
+ timeout: 120_000,
123
+ });
124
+ }
125
+ return targetDir;
126
+ }
127
+ /**
128
+ * Run repo setup locally on the agent runner's machine.
129
+ * Handles existing directories and cloning repos from URL.
130
+ */
131
+ export function localRepoSetup(options) {
132
+ const { workingDirectory, repository, projectId } = options;
133
+ // Case 1: No directory and no repository — create a fresh project dir
134
+ if (!workingDirectory && !repository) {
135
+ if (!projectId) {
136
+ return { success: false, error: 'Project ID is required when creating a new directory' };
137
+ }
138
+ try {
139
+ const dir = join(homedir(), '.astro', 'projects', projectId);
140
+ mkdirSync(dir, { recursive: true });
141
+ execSync('git init', { cwd: dir, stdio: 'ignore' });
142
+ execSync('git config user.name "Astro Agent" || true', { cwd: dir, stdio: 'ignore' });
143
+ execSync('git config user.email "agent@astro.local" || true', { cwd: dir, stdio: 'ignore' });
144
+ const fileTree = getFileTree(dir);
145
+ return {
146
+ success: true,
147
+ workingDirectory: dir,
148
+ fileTree,
149
+ };
150
+ }
151
+ catch (error) {
152
+ return { success: false, error: `Failed to create project directory: ${error instanceof Error ? error.message : String(error)}` };
153
+ }
154
+ }
155
+ // If repo URL + working directory, clone into the working directory
156
+ if (repository && workingDirectory) {
157
+ try {
158
+ const repoName = extractRepoName(repository);
159
+ const cloneTarget = join(workingDirectory, repoName);
160
+ const clonedDir = cloneRepository(repository, cloneTarget);
161
+ const fileTree = getFileTree(clonedDir);
162
+ const keyFiles = readKeyFiles(clonedDir);
163
+ return {
164
+ success: true,
165
+ workingDirectory: clonedDir,
166
+ fileTree,
167
+ repository,
168
+ keyFiles,
169
+ };
170
+ }
171
+ catch (error) {
172
+ return { success: false, error: `Failed to clone repository: ${error instanceof Error ? error.message : String(error)}` };
173
+ }
174
+ }
175
+ // If only a repo URL is provided (no working directory) — error
176
+ if (repository && !workingDirectory) {
177
+ return {
178
+ success: false,
179
+ error: 'Working directory required for git URL projects. Specify a local folder where the repository will be cloned.',
180
+ };
181
+ }
182
+ if (workingDirectory) {
183
+ if (!existsSync(workingDirectory)) {
184
+ // Directory doesn't exist — create it (non-git, direct mode)
185
+ try {
186
+ mkdirSync(workingDirectory, { recursive: true });
187
+ }
188
+ catch (mkdirError) {
189
+ return { success: false, error: `Failed to create directory: ${mkdirError instanceof Error ? mkdirError.message : String(mkdirError)}` };
190
+ }
191
+ return {
192
+ success: true,
193
+ workingDirectory,
194
+ fileTree: [],
195
+ needsGitInit: true,
196
+ };
197
+ }
198
+ if (isGitRepo(workingDirectory)) {
199
+ const fileTree = getFileTree(workingDirectory);
200
+ const detectedRepo = getGitRemoteUrl(workingDirectory);
201
+ const keyFiles = readKeyFiles(workingDirectory);
202
+ return {
203
+ success: true,
204
+ workingDirectory,
205
+ fileTree,
206
+ repository: detectedRepo,
207
+ keyFiles,
208
+ };
209
+ }
210
+ // Not a git repo — direct mode (per WORKSPACE_V2)
211
+ const keyFiles = readKeyFiles(workingDirectory);
212
+ return {
213
+ success: true,
214
+ workingDirectory,
215
+ fileTree: [],
216
+ needsGitInit: true,
217
+ keyFiles,
218
+ };
219
+ }
220
+ return { success: false, error: 'Unexpected state' };
221
+ }
222
+ //# sourceMappingURL=repo-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repo-utils.js","sourceRoot":"","sources":["../../src/lib/repo-utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Machine resource detection and reporting
3
+ */
4
+ import type { MachineResources } from '../types.js';
5
+ /**
6
+ * Get complete machine resource information
7
+ */
8
+ export declare function getMachineResources(): Promise<MachineResources>;
9
+ /**
10
+ * Format bytes to human-readable string
11
+ */
12
+ export declare function formatBytes(bytes: number): string;
13
+ /**
14
+ * Format resource summary for display
15
+ */
16
+ export declare function formatResourceSummary(resources: MachineResources): string;
17
+ //# sourceMappingURL=resources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resources.d.ts","sourceRoot":"","sources":["../../src/lib/resources.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,gBAAgB,EAAgC,MAAM,aAAa,CAAC;AA2MlF;;GAEG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAWrE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAWjD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,gBAAgB,GAAG,MAAM,CAiBzE"}
@@ -0,0 +1,227 @@
1
+ /**
2
+ * Machine resource detection and reporting
3
+ */
4
+ import os from 'node:os';
5
+ import { exec } from 'node:child_process';
6
+ import { promisify } from 'node:util';
7
+ const execAsync = promisify(exec);
8
+ /**
9
+ * Get CPU information
10
+ */
11
+ function getCpuInfo() {
12
+ const cpus = os.cpus();
13
+ const firstCpu = cpus[0];
14
+ const loadAvg = os.loadavg();
15
+ return {
16
+ model: firstCpu?.model ?? 'Unknown',
17
+ cores: cpus.length,
18
+ speed: firstCpu?.speed ?? 0,
19
+ loadAvg,
20
+ };
21
+ }
22
+ /**
23
+ * Get memory information
24
+ *
25
+ * On macOS, os.freemem() only counts truly free pages and ignores
26
+ * inactive/purgeable pages that the OS can reclaim instantly, causing
27
+ * memory to appear ~99% used. We parse vm_stat to get accurate numbers.
28
+ */
29
+ async function getMemoryInfo() {
30
+ const total = os.totalmem();
31
+ if (process.platform === 'darwin') {
32
+ try {
33
+ const { stdout } = await execAsync('vm_stat', { timeout: 5000 });
34
+ const pageMatch = stdout.match(/page size of (\d+) bytes/);
35
+ const pageSize = pageMatch ? parseInt(pageMatch[1]) : 16384;
36
+ const parse = (label) => {
37
+ const match = stdout.match(new RegExp(`${label}:\\s+(\\d+)`));
38
+ return match ? parseInt(match[1]) * pageSize : 0;
39
+ };
40
+ const free = parse('Pages free');
41
+ const inactive = parse('Pages inactive');
42
+ const purgeable = parse('Pages purgeable');
43
+ // Available = free + inactive + purgeable (all reclaimable by the OS)
44
+ const available = free + inactive + purgeable;
45
+ const used = total - available;
46
+ const usedPercent = (used / total) * 100;
47
+ return { total, free: available, used, usedPercent };
48
+ }
49
+ catch {
50
+ // Fall through to os.freemem()
51
+ }
52
+ }
53
+ const free = os.freemem();
54
+ const used = total - free;
55
+ const usedPercent = (used / total) * 100;
56
+ return { total, free, used, usedPercent };
57
+ }
58
+ /**
59
+ * Parse nvidia-smi output to get GPU information
60
+ */
61
+ function parseNvidiaSmiOutput(output) {
62
+ const gpus = [];
63
+ const lines = output.trim().split('\n');
64
+ for (const line of lines) {
65
+ const parts = line.split(', ');
66
+ if (parts.length >= 4) {
67
+ const [name, memoryTotal, memoryFree, utilization] = parts;
68
+ gpus.push({
69
+ name: name?.trim() ?? 'Unknown GPU',
70
+ vendor: 'NVIDIA',
71
+ memoryTotal: parseInt(memoryTotal ?? '0', 10) * 1024 * 1024, // MiB to bytes
72
+ memoryFree: parseInt(memoryFree ?? '0', 10) * 1024 * 1024,
73
+ utilization: parseInt(utilization ?? '0', 10),
74
+ });
75
+ }
76
+ }
77
+ return gpus;
78
+ }
79
+ /**
80
+ * Detect NVIDIA GPUs using nvidia-smi
81
+ */
82
+ async function detectNvidiaGpus() {
83
+ try {
84
+ const { stdout } = await execAsync('nvidia-smi --query-gpu=name,memory.total,memory.free,utilization.gpu --format=csv,noheader,nounits', { timeout: 5000 });
85
+ return parseNvidiaSmiOutput(stdout);
86
+ }
87
+ catch {
88
+ // nvidia-smi not available or failed
89
+ return [];
90
+ }
91
+ }
92
+ /**
93
+ * Detect AMD GPUs using rocm-smi
94
+ */
95
+ async function detectAmdGpus() {
96
+ try {
97
+ const { stdout } = await execAsync('rocm-smi --showproductname --showmeminfo vram --showuse', {
98
+ timeout: 5000,
99
+ });
100
+ // Parse rocm-smi output (format varies by version)
101
+ const gpus = [];
102
+ const lines = stdout.split('\n');
103
+ let currentGpu = { vendor: 'AMD' };
104
+ for (const line of lines) {
105
+ if (line.includes('GPU[')) {
106
+ if (currentGpu.name) {
107
+ gpus.push(currentGpu);
108
+ }
109
+ currentGpu = { vendor: 'AMD', memoryTotal: 0, memoryFree: 0, utilization: 0 };
110
+ }
111
+ if (line.includes('Card series:')) {
112
+ currentGpu.name = line.split(':')[1]?.trim() ?? 'AMD GPU';
113
+ }
114
+ if (line.includes('Total Memory')) {
115
+ const match = line.match(/(\d+)/);
116
+ if (match) {
117
+ currentGpu.memoryTotal = parseInt(match[1], 10) * 1024 * 1024;
118
+ }
119
+ }
120
+ if (line.includes('GPU use')) {
121
+ const match = line.match(/(\d+)/);
122
+ if (match) {
123
+ currentGpu.utilization = parseInt(match[1], 10);
124
+ }
125
+ }
126
+ }
127
+ if (currentGpu.name) {
128
+ gpus.push(currentGpu);
129
+ }
130
+ return gpus;
131
+ }
132
+ catch {
133
+ // rocm-smi not available or failed
134
+ return [];
135
+ }
136
+ }
137
+ /**
138
+ * Detect Apple Silicon GPUs (macOS only)
139
+ */
140
+ async function detectAppleGpus() {
141
+ if (os.platform() !== 'darwin') {
142
+ return [];
143
+ }
144
+ try {
145
+ const { stdout } = await execAsync('system_profiler SPDisplaysDataType -json', {
146
+ timeout: 5000,
147
+ });
148
+ const data = JSON.parse(stdout);
149
+ const displays = data?.SPDisplaysDataType ?? [];
150
+ const gpus = [];
151
+ for (const display of displays) {
152
+ const gpuName = display.sppci_model ?? display._name ?? 'Apple GPU';
153
+ const vramMatch = display.spdisplays_vram?.match(/(\d+)/);
154
+ const vramMB = vramMatch ? parseInt(vramMatch[1], 10) : 0;
155
+ gpus.push({
156
+ name: gpuName,
157
+ vendor: 'Apple',
158
+ memoryTotal: vramMB * 1024 * 1024,
159
+ memoryFree: 0, // Not available on macOS
160
+ utilization: 0, // Not easily available
161
+ });
162
+ }
163
+ return gpus;
164
+ }
165
+ catch {
166
+ return [];
167
+ }
168
+ }
169
+ /**
170
+ * Detect all GPUs on the system
171
+ */
172
+ async function getGpuInfo() {
173
+ // Try all GPU detection methods in parallel
174
+ const [nvidiaGpus, amdGpus, appleGpus] = await Promise.all([
175
+ detectNvidiaGpus(),
176
+ detectAmdGpus(),
177
+ detectAppleGpus(),
178
+ ]);
179
+ return [...nvidiaGpus, ...amdGpus, ...appleGpus];
180
+ }
181
+ /**
182
+ * Get complete machine resource information
183
+ */
184
+ export async function getMachineResources() {
185
+ const [gpu, memory] = await Promise.all([getGpuInfo(), getMemoryInfo()]);
186
+ return {
187
+ hostname: os.hostname(),
188
+ platform: os.platform(),
189
+ arch: os.arch(),
190
+ cpu: getCpuInfo(),
191
+ memory,
192
+ gpu,
193
+ };
194
+ }
195
+ /**
196
+ * Format bytes to human-readable string
197
+ */
198
+ export function formatBytes(bytes) {
199
+ const units = ['B', 'KB', 'MB', 'GB', 'TB'];
200
+ let unitIndex = 0;
201
+ let size = bytes;
202
+ while (size >= 1024 && unitIndex < units.length - 1) {
203
+ size /= 1024;
204
+ unitIndex++;
205
+ }
206
+ return `${size.toFixed(1)} ${units[unitIndex]}`;
207
+ }
208
+ /**
209
+ * Format resource summary for display
210
+ */
211
+ export function formatResourceSummary(resources) {
212
+ const lines = [];
213
+ lines.push(`Host: ${resources.hostname} (${resources.platform}/${resources.arch})`);
214
+ lines.push(`CPU: ${resources.cpu.model} (${resources.cpu.cores} cores @ ${resources.cpu.speed}MHz)`);
215
+ lines.push(`Memory: ${formatBytes(resources.memory.used)} / ${formatBytes(resources.memory.total)} (${resources.memory.usedPercent.toFixed(1)}% used)`);
216
+ if (resources.gpu.length > 0) {
217
+ for (const gpu of resources.gpu) {
218
+ const memUsed = gpu.memoryTotal - gpu.memoryFree;
219
+ lines.push(`GPU: ${gpu.name} - ${formatBytes(memUsed)} / ${formatBytes(gpu.memoryTotal)} (${gpu.utilization}% util)`);
220
+ }
221
+ }
222
+ else {
223
+ lines.push('GPU: None detected');
224
+ }
225
+ return lines.join('\n');
226
+ }
227
+ //# sourceMappingURL=resources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resources.js","sourceRoot":"","sources":["../../src/lib/resources.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Slurm Detection
3
+ *
4
+ * Detects Slurm installation and gathers cluster information.
5
+ */
6
+ import type { SlurmInfo, SlurmPartitionDetail } from '../types.js';
7
+ /**
8
+ * Detect Slurm and gather cluster information
9
+ */
10
+ export declare function detectSlurm(): Promise<SlurmInfo>;
11
+ /**
12
+ * Get detailed partition info
13
+ */
14
+ export declare function getPartitionInfo(): Promise<SlurmPartitionDetail[]>;
15
+ //# sourceMappingURL=slurm-detect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slurm-detect.d.ts","sourceRoot":"","sources":["../../src/lib/slurm-detect.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAInE;;GAEG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,SAAS,CAAC,CAuGtD;AAED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,oBAAoB,EAAE,CAAC,CA0CxE"}
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Slurm Detection
3
+ *
4
+ * Detects Slurm installation and gathers cluster information.
5
+ */
6
+ import { execFile } from 'node:child_process';
7
+ import { promisify } from 'node:util';
8
+ const execFileAsync = promisify(execFile);
9
+ /**
10
+ * Detect Slurm and gather cluster information
11
+ */
12
+ export async function detectSlurm() {
13
+ const info = {
14
+ available: false,
15
+ partitions: [],
16
+ accounts: [],
17
+ qosLevels: [],
18
+ };
19
+ // Check if sinfo is available
20
+ try {
21
+ await execFileAsync('which', ['sinfo'], { timeout: 5000 });
22
+ info.available = true;
23
+ }
24
+ catch {
25
+ return info;
26
+ }
27
+ // Get Slurm version
28
+ try {
29
+ const { stdout } = await execFileAsync('sinfo', ['--version'], { timeout: 5000 });
30
+ const match = stdout.match(/slurm\s+(\d+\.\d+\.\d+)/);
31
+ if (match) {
32
+ info.version = match[1];
33
+ }
34
+ }
35
+ catch {
36
+ // Version detection failed
37
+ }
38
+ // Get cluster name
39
+ try {
40
+ const { stdout: rawConfig } = await execFileAsync('scontrol', ['show', 'config'], { timeout: 10000 });
41
+ const stdout = rawConfig.split('\n').filter(l => l.includes('ClusterName')).join('\n');
42
+ const match = stdout.match(/ClusterName\s*=\s*(\S+)/);
43
+ if (match) {
44
+ info.clusterName = match[1];
45
+ }
46
+ }
47
+ catch {
48
+ // Cluster name detection failed
49
+ }
50
+ // Get partitions
51
+ try {
52
+ const { stdout } = await execFileAsync('sinfo', ['-h', '-o', '%P'], { timeout: 10000 });
53
+ info.partitions = stdout
54
+ .split('\n')
55
+ .map((line) => line.trim())
56
+ .filter((line) => line.length > 0)
57
+ .map((name) => {
58
+ const isDefault = name.endsWith('*');
59
+ const partitionName = name.replace('*', '');
60
+ if (isDefault) {
61
+ info.defaultPartition = partitionName;
62
+ }
63
+ return partitionName;
64
+ });
65
+ }
66
+ catch {
67
+ // Partition detection failed
68
+ }
69
+ // Get user accounts
70
+ try {
71
+ const username = process.env.USER || process.env.LOGNAME;
72
+ if (username && /^[a-zA-Z0-9._-]+$/.test(username)) {
73
+ const { stdout } = await execFileAsync('sacctmgr', ['-p', 'show', 'assoc', `user=${username}`, 'format=Account', '--noheader'], { timeout: 10000 });
74
+ info.accounts = [
75
+ ...new Set(stdout
76
+ .split('\n')
77
+ .map((line) => line.split('|')[0]?.trim())
78
+ .filter((a) => !!a && a.length > 0)),
79
+ ];
80
+ }
81
+ }
82
+ catch {
83
+ // Account detection failed
84
+ }
85
+ // Get QOS levels
86
+ try {
87
+ const username = process.env.USER || process.env.LOGNAME;
88
+ if (username && /^[a-zA-Z0-9._-]+$/.test(username)) {
89
+ const { stdout } = await execFileAsync('sacctmgr', ['-p', 'show', 'assoc', `user=${username}`, 'format=QOS', '--noheader'], { timeout: 10000 });
90
+ const qosSet = new Set();
91
+ stdout.split('\n').forEach((line) => {
92
+ const qos = line.split('|')[0]?.trim();
93
+ if (qos) {
94
+ qos.split(',').forEach((q) => {
95
+ if (q.trim())
96
+ qosSet.add(q.trim());
97
+ });
98
+ }
99
+ });
100
+ info.qosLevels = [...qosSet];
101
+ }
102
+ }
103
+ catch {
104
+ // QOS detection failed
105
+ }
106
+ return info;
107
+ }
108
+ /**
109
+ * Get detailed partition info
110
+ */
111
+ export async function getPartitionInfo() {
112
+ try {
113
+ const { stdout } = await execFileAsync('sinfo', ['-h', '-o', '%P|%a|%l|%D|%T|%f'], { timeout: 10000 });
114
+ const partitionMap = new Map();
115
+ stdout.split('\n').forEach((line) => {
116
+ const parts = line.split('|');
117
+ if (parts.length < 6)
118
+ return;
119
+ const [partitionRaw, , maxTime, nodesCount, nodeState, features] = parts;
120
+ const isDefault = partitionRaw?.endsWith('*') || false;
121
+ const name = partitionRaw?.replace('*', '') || '';
122
+ if (!name)
123
+ return;
124
+ let partition = partitionMap.get(name);
125
+ if (!partition) {
126
+ partition = {
127
+ name,
128
+ isDefault,
129
+ totalNodes: 0,
130
+ availableNodes: 0,
131
+ maxTime: maxTime !== '(null)' ? maxTime : undefined,
132
+ features: features !== '(null)' ? features?.split(',') || [] : [],
133
+ };
134
+ partitionMap.set(name, partition);
135
+ }
136
+ const count = parseInt(nodesCount || '0') || 0;
137
+ partition.totalNodes += count;
138
+ if (nodeState === 'idle' || nodeState === 'mixed') {
139
+ partition.availableNodes += count;
140
+ }
141
+ });
142
+ return Array.from(partitionMap.values());
143
+ }
144
+ catch {
145
+ return [];
146
+ }
147
+ }
148
+ //# sourceMappingURL=slurm-detect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slurm-detect.js","sourceRoot":"","sources":["../../src/lib/slurm-detect.ts"],"names":[],"mappings":"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"}