replicas-cli 0.3.123 → 0.3.125

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 (2) hide show
  1. package/dist/index.cjs +64 -10
  2. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -24988,6 +24988,12 @@ var computeExecRequestSchema = external_exports.object({
24988
24988
  env: computeEnvSchema.optional(),
24989
24989
  detach: external_exports.boolean().optional()
24990
24990
  });
24991
+ var computeUploadRequestSchema = external_exports.object({
24992
+ size: external_exports.number().int().min(1).max(COMPUTE_SANDBOX_LIMITS.maxTransferBytes)
24993
+ });
24994
+ var computeTransferPathSchema = external_exports.object({
24995
+ path: external_exports.string().min(1).max(4096).optional()
24996
+ });
24991
24997
 
24992
24998
  // ../shared/src/default-skills/replicas-agent/abilities/gpu.ts
24993
24999
  var SECTION6 = `### GPU sandboxes
@@ -28731,7 +28737,7 @@ var headlessAgentRequestSchema = external_exports.object({
28731
28737
  });
28732
28738
 
28733
28739
  // ../shared/src/cli-version.ts
28734
- var CLI_VERSION = "0.3.123";
28740
+ var CLI_VERSION = "0.3.125";
28735
28741
 
28736
28742
  // ../shared/src/version.ts
28737
28743
  function compareVersions(v1, v2) {
@@ -33842,6 +33848,12 @@ var import_chalk27 = __toESM(require("chalk"));
33842
33848
 
33843
33849
  // src/lib/agent-api.ts
33844
33850
  var ENGINE_PORT = process.env.REPLICAS_ENGINE_PORT || "3737";
33851
+ var AgentRequestError = class extends Error {
33852
+ constructor(message2, status) {
33853
+ super(message2);
33854
+ this.status = status;
33855
+ }
33856
+ };
33845
33857
  async function agentFetch(path8, options) {
33846
33858
  return (await agentRequest(path8, options)).json();
33847
33859
  }
@@ -33869,7 +33881,7 @@ async function agentRequest(path8, options) {
33869
33881
  });
33870
33882
  if (!response.ok) {
33871
33883
  const error51 = await response.json().catch(() => ({ error: "Request failed" }));
33872
- throw new Error(error51.error || `Request failed with status ${response.status}`);
33884
+ throw new AgentRequestError(error51.error || `Request failed with status ${response.status}`, response.status);
33873
33885
  }
33874
33886
  return response;
33875
33887
  }
@@ -34246,7 +34258,9 @@ async function mediaGifCommand(input, options) {
34246
34258
  // src/commands/gpu.ts
34247
34259
  var import_chalk28 = __toESM(require("chalk"));
34248
34260
  var import_node_child_process2 = require("child_process");
34261
+ var import_node_crypto2 = require("crypto");
34249
34262
  var import_node_fs2 = require("fs");
34263
+ var import_node_os2 = require("os");
34250
34264
  var import_node_path2 = require("path");
34251
34265
  var import_node_stream = require("stream");
34252
34266
  var import_promises = require("stream/promises");
@@ -34406,6 +34420,9 @@ function archive(localPath) {
34406
34420
  child.stdin.end(files.map((file2) => `${file2}\0`).join(""));
34407
34421
  return child;
34408
34422
  }
34423
+ function mustStream(error51) {
34424
+ return error51 instanceof AgentRequestError && (error51.status === 409 || error51.status === 404);
34425
+ }
34409
34426
  async function push(sandboxId, localPath, remotePath) {
34410
34427
  const tar = archive(localPath);
34411
34428
  let stderr = "";
@@ -34413,11 +34430,40 @@ async function push(sandboxId, localPath, remotePath) {
34413
34430
  stderr += chunk.toString();
34414
34431
  });
34415
34432
  const exited = new Promise((done) => tar.on("close", done));
34416
- await agentRequest(`${BASE}/${sandboxId}/files?path=${encodeURIComponent(remotePath)}`, {
34417
- method: "PUT",
34418
- body: import_node_stream.Readable.toWeb(tar.stdout)
34419
- });
34420
- if (await exited !== 0) throw new Error(`Archiving ${localPath} failed: ${stderr.trim()}`);
34433
+ const pathQuery = `?path=${encodeURIComponent(remotePath)}`;
34434
+ const archivePath = (0, import_node_path2.join)((0, import_node_os2.tmpdir)(), `replicas-push-${(0, import_node_crypto2.randomUUID)()}.tgz`);
34435
+ try {
34436
+ await (0, import_promises.pipeline)(tar.stdout, (0, import_node_fs2.createWriteStream)(archivePath, { mode: 384 }));
34437
+ if (await exited !== 0) throw new Error(`Archiving ${localPath} failed: ${stderr.trim()}`);
34438
+ try {
34439
+ const size = (0, import_node_fs2.statSync)(archivePath).size;
34440
+ const { uploadId, uploadUrl } = await agentFetch(`${BASE}/${sandboxId}/uploads`, {
34441
+ method: "POST",
34442
+ body: { size }
34443
+ });
34444
+ const chunks = (0, import_node_fs2.createReadStream)(archivePath)[Symbol.asyncIterator]();
34445
+ const upload = {
34446
+ method: "PUT",
34447
+ headers: { "content-type": "application/gzip", "content-length": String(size) },
34448
+ body: new ReadableStream({
34449
+ async pull(controller) {
34450
+ const { done, value } = await chunks.next();
34451
+ if (done) controller.close();
34452
+ else controller.enqueue(value);
34453
+ }
34454
+ }),
34455
+ duplex: "half"
34456
+ };
34457
+ const uploaded = await fetch(uploadUrl, upload);
34458
+ if (!uploaded.ok) throw new Error(`Uploading ${localPath} failed (${uploaded.status})`);
34459
+ await agentRequest(`${BASE}/${sandboxId}/uploads/${uploadId}/extract`, { method: "POST", body: { path: remotePath } });
34460
+ } catch (error51) {
34461
+ if (!mustStream(error51)) throw error51;
34462
+ await agentRequest(`${BASE}/${sandboxId}/files${pathQuery}`, { method: "PUT", body: import_node_stream.Readable.toWeb((0, import_node_fs2.createReadStream)(archivePath)) });
34463
+ }
34464
+ } finally {
34465
+ (0, import_node_fs2.rmSync)(archivePath, { force: true });
34466
+ }
34421
34467
  }
34422
34468
  async function gpuPushCommand(localPath = ".", remotePath = COMPUTE_SANDBOX_WORKDIR, options = {}) {
34423
34469
  const sandboxId = await resolveSandboxId(options);
@@ -34425,7 +34471,15 @@ async function gpuPushCommand(localPath = ".", remotePath = COMPUTE_SANDBOX_WORK
34425
34471
  outputSuccess(`Copied ${localPath} to ${remotePath} in ${sandboxId}`);
34426
34472
  }
34427
34473
  async function pull(sandboxId, remotePath, localPath) {
34428
- const response = await agentRequest(`${BASE}/${sandboxId}/files?path=${encodeURIComponent(remotePath)}`);
34474
+ let response;
34475
+ try {
34476
+ const { downloadUrl } = await agentFetch(`${BASE}/${sandboxId}/downloads`, { method: "POST", body: { path: remotePath } });
34477
+ response = await fetch(downloadUrl);
34478
+ } catch (error51) {
34479
+ if (!mustStream(error51)) throw error51;
34480
+ response = await agentRequest(`${BASE}/${sandboxId}/files?path=${encodeURIComponent(remotePath)}`);
34481
+ }
34482
+ if (!response.ok || !response.body) throw new Error(`Downloading ${remotePath} failed (${response.status})`);
34429
34483
  (0, import_node_fs2.mkdirSync)(localPath, { recursive: true });
34430
34484
  const tar = (0, import_node_child_process2.spawn)("tar", ["-xzf", "-", "-C", localPath], { stdio: ["pipe", "ignore", "pipe"] });
34431
34485
  let stderr = "";
@@ -34575,9 +34629,9 @@ async function slackThreadSwitchCommand(workspace, options) {
34575
34629
  var import_chalk31 = __toESM(require("chalk"));
34576
34630
  var import_node_child_process3 = require("child_process");
34577
34631
  var import_node_fs5 = require("fs");
34578
- var import_node_os2 = require("os");
34632
+ var import_node_os3 = require("os");
34579
34633
  var import_node_path4 = require("path");
34580
- var SERVICES_DIR = (0, import_node_path4.join)((0, import_node_os2.homedir)(), ".replicas", "services");
34634
+ var SERVICES_DIR = (0, import_node_path4.join)((0, import_node_os3.homedir)(), ".replicas", "services");
34581
34635
  var NAME_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/;
34582
34636
  function isValidServiceName(name) {
34583
34637
  return NAME_PATTERN.test(name);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-cli",
3
- "version": "0.3.123",
3
+ "version": "0.3.125",
4
4
  "description": "CLI for managing Replicas workspaces - SSH into cloud dev environments with automatic port forwarding",
5
5
  "main": "dist/index.cjs",
6
6
  "bin": {