computesdk 1.12.1 → 1.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1388,10 +1388,15 @@ var Server = class {
1388
1388
  this.stopHandler = handlers.stop;
1389
1389
  this.restartHandler = handlers.restart;
1390
1390
  this.updateStatusHandler = handlers.updateStatus;
1391
+ this.logsHandler = handlers.logs;
1391
1392
  }
1392
1393
  /**
1393
1394
  * Start a new managed server with optional supervisor settings
1394
1395
  *
1396
+ * **Install Phase:**
1397
+ * If `install` is provided, it runs blocking before `start` (e.g., "npm install").
1398
+ * The server status will be `installing` during this phase.
1399
+ *
1395
1400
  * **Restart Policies:**
1396
1401
  * - `never` (default): No automatic restart on exit
1397
1402
  * - `on-failure`: Restart only on non-zero exit code
@@ -1409,14 +1414,15 @@ var Server = class {
1409
1414
  * // Basic server
1410
1415
  * const server = await sandbox.server.start({
1411
1416
  * slug: 'web',
1412
- * command: 'npm run dev',
1417
+ * start: 'npm run dev',
1413
1418
  * path: '/app',
1414
1419
  * });
1415
1420
  *
1416
- * // With supervisor settings
1421
+ * // With install command
1417
1422
  * const server = await sandbox.server.start({
1418
1423
  * slug: 'api',
1419
- * command: 'node server.js',
1424
+ * install: 'npm install',
1425
+ * start: 'node server.js',
1420
1426
  * environment: { NODE_ENV: 'production' },
1421
1427
  * restart_policy: 'always',
1422
1428
  * max_restarts: 0, // unlimited
@@ -1468,6 +1474,29 @@ var Server = class {
1468
1474
  async updateStatus(slug, status) {
1469
1475
  await this.updateStatusHandler(slug, status);
1470
1476
  }
1477
+ /**
1478
+ * Retrieve captured output (logs) for a managed server
1479
+ * @param slug - The server slug
1480
+ * @param options - Options for log retrieval
1481
+ * @returns Server logs info
1482
+ *
1483
+ * @example
1484
+ * ```typescript
1485
+ * // Get combined logs (default)
1486
+ * const logs = await sandbox.server.logs('api');
1487
+ * console.log(logs.logs);
1488
+ *
1489
+ * // Get only stdout
1490
+ * const stdout = await sandbox.server.logs('api', { stream: 'stdout' });
1491
+ *
1492
+ * // Get only stderr
1493
+ * const stderr = await sandbox.server.logs('api', { stream: 'stderr' });
1494
+ * ```
1495
+ */
1496
+ async logs(slug, options) {
1497
+ const response = await this.logsHandler(slug, options);
1498
+ return response.data;
1499
+ }
1471
1500
  };
1472
1501
 
1473
1502
  // src/client/resources/watcher.ts
@@ -1898,6 +1927,88 @@ var Child = class {
1898
1927
  }
1899
1928
  };
1900
1929
 
1930
+ // src/client/resources/overlay.ts
1931
+ var Overlay = class {
1932
+ constructor(handlers) {
1933
+ this.createHandler = handlers.create;
1934
+ this.listHandler = handlers.list;
1935
+ this.retrieveHandler = handlers.retrieve;
1936
+ this.destroyHandler = handlers.destroy;
1937
+ }
1938
+ /**
1939
+ * Create a new overlay from a template directory
1940
+ *
1941
+ * The overlay copies files from the source directory into the target path
1942
+ * for better isolation. Heavy directories (node_modules, .venv, etc.) are
1943
+ * copied in the background. Use the `ignore` option to exclude files/directories.
1944
+ *
1945
+ * @param options - Overlay creation options
1946
+ * @param options.source - Absolute path to source directory
1947
+ * @param options.target - Relative path in sandbox
1948
+ * @param options.ignore - Glob patterns to ignore (e.g., ["node_modules", "*.log"])
1949
+ * @returns Overlay info with copy status
1950
+ */
1951
+ async create(options) {
1952
+ const response = await this.createHandler(options);
1953
+ return this.toOverlayInfo(response);
1954
+ }
1955
+ /**
1956
+ * List all overlays for the current sandbox
1957
+ * @returns Array of overlay info
1958
+ */
1959
+ async list() {
1960
+ const response = await this.listHandler();
1961
+ return response.overlays.map((o) => this.toOverlayInfo(o));
1962
+ }
1963
+ /**
1964
+ * Retrieve a specific overlay by ID
1965
+ *
1966
+ * Useful for polling the copy status of an overlay.
1967
+ *
1968
+ * @param id - Overlay ID
1969
+ * @returns Overlay info
1970
+ */
1971
+ async retrieve(id) {
1972
+ const response = await this.retrieveHandler(id);
1973
+ return this.toOverlayInfo(response);
1974
+ }
1975
+ /**
1976
+ * Destroy (delete) an overlay
1977
+ * @param id - Overlay ID
1978
+ */
1979
+ async destroy(id) {
1980
+ return this.destroyHandler(id);
1981
+ }
1982
+ /**
1983
+ * Convert API response to OverlayInfo
1984
+ */
1985
+ toOverlayInfo(response) {
1986
+ return {
1987
+ id: response.id,
1988
+ source: response.source,
1989
+ target: response.target,
1990
+ createdAt: response.created_at,
1991
+ stats: {
1992
+ copiedFiles: response.stats.copied_files,
1993
+ copiedDirs: response.stats.copied_dirs,
1994
+ skipped: response.stats.skipped
1995
+ },
1996
+ copyStatus: this.validateCopyStatus(response.copy_status),
1997
+ copyError: response.copy_error
1998
+ };
1999
+ }
2000
+ /**
2001
+ * Validate and return copy status, defaulting to 'pending' for unknown values
2002
+ */
2003
+ validateCopyStatus(status) {
2004
+ const validStatuses = ["pending", "in_progress", "complete", "failed"];
2005
+ if (validStatuses.includes(status)) {
2006
+ return status;
2007
+ }
2008
+ return "pending";
2009
+ }
2010
+ };
2011
+
1901
2012
  // src/client/types.ts
1902
2013
  var CommandExitError = class extends Error {
1903
2014
  constructor(result) {
@@ -1992,7 +2103,13 @@ var Sandbox = class {
1992
2103
  },
1993
2104
  remove: async (path) => {
1994
2105
  await this.deleteFile(path);
1995
- }
2106
+ },
2107
+ overlay: new Overlay({
2108
+ create: async (options) => this.createOverlay(options),
2109
+ list: async () => this.listOverlays(),
2110
+ retrieve: async (id) => this.getOverlay(id),
2111
+ destroy: async (id) => this.deleteOverlay(id)
2112
+ })
1996
2113
  };
1997
2114
  this.terminal = new Terminal({
1998
2115
  create: async (options) => this.createTerminal(options),
@@ -2037,7 +2154,8 @@ var Sandbox = class {
2037
2154
  restart: async (slug) => this.restartServer(slug),
2038
2155
  updateStatus: async (slug, status) => {
2039
2156
  await this.updateServerStatus(slug, status);
2040
- }
2157
+ },
2158
+ logs: async (slug, options) => this.getServerLogs(slug, options)
2041
2159
  });
2042
2160
  this.watcher = new Watcher({
2043
2161
  create: async (path, options) => this.createWatcher(path, options),
@@ -2477,6 +2595,63 @@ API request failed (${response.status}): ${error}`
2477
2595
  });
2478
2596
  }
2479
2597
  // ============================================================================
2598
+ // Filesystem Overlays
2599
+ // ============================================================================
2600
+ /**
2601
+ * Create a new filesystem overlay from a template directory
2602
+ *
2603
+ * Overlays enable instant sandbox setup by symlinking template files first,
2604
+ * then copying heavy directories (node_modules, .venv, etc.) in the background.
2605
+ *
2606
+ * @param options - Overlay creation options
2607
+ * @param options.source - Absolute path to source directory (template)
2608
+ * @param options.target - Relative path in sandbox where overlay will be mounted
2609
+ * @returns Overlay response with copy status
2610
+ *
2611
+ * @example
2612
+ * ```typescript
2613
+ * // Prefer using sandbox.filesystem.overlay.create() for camelCase response
2614
+ * const overlay = await sandbox.filesystem.overlay.create({
2615
+ * source: '/templates/nextjs',
2616
+ * target: 'project',
2617
+ * });
2618
+ * console.log(overlay.copyStatus); // 'pending' | 'in_progress' | 'complete' | 'failed'
2619
+ * ```
2620
+ */
2621
+ async createOverlay(options) {
2622
+ return this.request("/filesystem/overlays", {
2623
+ method: "POST",
2624
+ body: JSON.stringify(options)
2625
+ });
2626
+ }
2627
+ /**
2628
+ * List all filesystem overlays for the current sandbox
2629
+ * @returns List of overlays with their copy status
2630
+ */
2631
+ async listOverlays() {
2632
+ return this.request("/filesystem/overlays");
2633
+ }
2634
+ /**
2635
+ * Get a specific filesystem overlay by ID
2636
+ *
2637
+ * Useful for polling the copy status of an overlay.
2638
+ *
2639
+ * @param id - Overlay ID
2640
+ * @returns Overlay details with current copy status
2641
+ */
2642
+ async getOverlay(id) {
2643
+ return this.request(`/filesystem/overlays/${id}`);
2644
+ }
2645
+ /**
2646
+ * Delete a filesystem overlay
2647
+ * @param id - Overlay ID
2648
+ */
2649
+ async deleteOverlay(id) {
2650
+ return this.request(`/filesystem/overlays/${id}`, {
2651
+ method: "DELETE"
2652
+ });
2653
+ }
2654
+ // ============================================================================
2480
2655
  // Terminal Management
2481
2656
  // ============================================================================
2482
2657
  /**
@@ -2825,7 +3000,8 @@ API request failed (${response.status}): ${error}`
2825
3000
  *
2826
3001
  * @param options - Server configuration
2827
3002
  * @param options.slug - Unique server identifier
2828
- * @param options.command - Command to start the server
3003
+ * @param options.install - Install command (optional, runs blocking before start, e.g., "npm install")
3004
+ * @param options.start - Command to start the server (e.g., "npm run dev")
2829
3005
  * @param options.path - Working directory (optional)
2830
3006
  * @param options.env_file - Path to .env file relative to path (optional)
2831
3007
  * @param options.environment - Inline environment variables (merged with env_file if both provided)
@@ -2839,14 +3015,15 @@ API request failed (${response.status}): ${error}`
2839
3015
  * // Basic server
2840
3016
  * await sandbox.startServer({
2841
3017
  * slug: 'web',
2842
- * command: 'npm run dev',
3018
+ * start: 'npm run dev',
2843
3019
  * path: '/app',
2844
3020
  * });
2845
3021
  *
2846
- * // With supervisor settings
3022
+ * // With install command and supervisor settings
2847
3023
  * await sandbox.startServer({
2848
3024
  * slug: 'api',
2849
- * command: 'node server.js',
3025
+ * install: 'npm install',
3026
+ * start: 'node server.js',
2850
3027
  * path: '/app',
2851
3028
  * environment: { NODE_ENV: 'production', PORT: '3000' },
2852
3029
  * restart_policy: 'on-failure',
@@ -2893,6 +3070,21 @@ API request failed (${response.status}): ${error}`
2893
3070
  }
2894
3071
  );
2895
3072
  }
3073
+ /**
3074
+ * Get logs for a managed server
3075
+ * @param slug - Server slug
3076
+ * @param options - Options for log retrieval
3077
+ */
3078
+ async getServerLogs(slug, options) {
3079
+ const params = new URLSearchParams();
3080
+ if (options?.stream) {
3081
+ params.set("stream", options.stream);
3082
+ }
3083
+ const queryString = params.toString();
3084
+ return this.request(
3085
+ `/servers/${encodeURIComponent(slug)}/logs${queryString ? `?${queryString}` : ""}`
3086
+ );
3087
+ }
2896
3088
  /**
2897
3089
  * Update server status (internal use)
2898
3090
  * @param slug - Server slug
@@ -3174,7 +3366,9 @@ var PROVIDER_HEADERS = {
3174
3366
  tokenSecret: "X-Modal-Token-Secret"
3175
3367
  },
3176
3368
  railway: {
3177
- apiToken: "X-Railway-API-Token"
3369
+ apiToken: "X-Railway-API-Key",
3370
+ projectId: "X-Railway-Project-ID",
3371
+ environmentId: "X-Railway-Environment-ID"
3178
3372
  },
3179
3373
  daytona: {
3180
3374
  apiKey: "X-Daytona-API-Key"