replicas-cli 0.2.28 → 0.2.30
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 +244 -378
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -34,9 +34,9 @@ __export(index_exports, {
|
|
|
34
34
|
CLI_VERSION: () => CLI_VERSION
|
|
35
35
|
});
|
|
36
36
|
module.exports = __toCommonJS(index_exports);
|
|
37
|
-
var
|
|
37
|
+
var import_config15 = require("dotenv/config");
|
|
38
38
|
var import_commander = require("commander");
|
|
39
|
-
var
|
|
39
|
+
var import_chalk17 = __toESM(require("chalk"));
|
|
40
40
|
|
|
41
41
|
// src/commands/login.ts
|
|
42
42
|
var import_http = __toESM(require("http"));
|
|
@@ -507,44 +507,14 @@ async function whoamiCommand() {
|
|
|
507
507
|
var import_chalk5 = __toESM(require("chalk"));
|
|
508
508
|
|
|
509
509
|
// src/lib/ssh.ts
|
|
510
|
-
var import_fs2 = __toESM(require("fs"));
|
|
511
|
-
var import_path2 = __toESM(require("path"));
|
|
512
510
|
var import_child_process = require("child_process");
|
|
513
|
-
var
|
|
514
|
-
function
|
|
515
|
-
if (!import_fs2.default.existsSync(SSH_KEYS_DIR)) {
|
|
516
|
-
import_fs2.default.mkdirSync(SSH_KEYS_DIR, { recursive: true, mode: 448 });
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
function getSSHKeyPath(sshKeyId) {
|
|
520
|
-
return import_path2.default.join(SSH_KEYS_DIR, `${sshKeyId}.pem`);
|
|
521
|
-
}
|
|
522
|
-
async function getSSHKey(sshKeyId) {
|
|
523
|
-
const keyPath = getSSHKeyPath(sshKeyId);
|
|
524
|
-
if (import_fs2.default.existsSync(keyPath)) {
|
|
525
|
-
return import_fs2.default.readFileSync(keyPath, "utf-8");
|
|
526
|
-
}
|
|
527
|
-
const response = await orgAuthenticatedFetch(
|
|
528
|
-
`/v1/keys/${sshKeyId}?includePrivateKey=true`
|
|
529
|
-
);
|
|
530
|
-
if (!response.privateKey) {
|
|
531
|
-
throw new Error("Failed to retrieve private key from server");
|
|
532
|
-
}
|
|
533
|
-
ensureSSHKeysDir();
|
|
534
|
-
import_fs2.default.writeFileSync(keyPath, response.privateKey, { mode: 384 });
|
|
535
|
-
return response.privateKey;
|
|
536
|
-
}
|
|
537
|
-
async function scpCopyFile(privateKeyPath, localPath, remotePath, remoteHost) {
|
|
511
|
+
var SSH_OPTIONS = ["-o", "StrictHostKeyChecking=no", "-o", "UserKnownHostsFile=/dev/null"];
|
|
512
|
+
async function scpCopyFile(token, host, localPath, remotePath) {
|
|
538
513
|
return new Promise((resolve, reject) => {
|
|
539
514
|
const scp = (0, import_child_process.spawn)("scp", [
|
|
540
|
-
|
|
541
|
-
privateKeyPath,
|
|
542
|
-
"-o",
|
|
543
|
-
"StrictHostKeyChecking=no",
|
|
544
|
-
"-o",
|
|
545
|
-
"UserKnownHostsFile=/dev/null",
|
|
515
|
+
...SSH_OPTIONS,
|
|
546
516
|
localPath,
|
|
547
|
-
|
|
517
|
+
`${token}@${host}:${remotePath}`
|
|
548
518
|
], {
|
|
549
519
|
stdio: "inherit"
|
|
550
520
|
});
|
|
@@ -558,24 +528,17 @@ async function scpCopyFile(privateKeyPath, localPath, remotePath, remoteHost) {
|
|
|
558
528
|
scp.on("error", reject);
|
|
559
529
|
});
|
|
560
530
|
}
|
|
561
|
-
async function connectSSH(
|
|
531
|
+
async function connectSSH(token, host, portMappings) {
|
|
562
532
|
return new Promise((resolve, reject) => {
|
|
563
|
-
const sshArgs = [
|
|
564
|
-
"-i",
|
|
565
|
-
privateKeyPath,
|
|
566
|
-
"-o",
|
|
567
|
-
"StrictHostKeyChecking=no",
|
|
568
|
-
"-o",
|
|
569
|
-
"UserKnownHostsFile=/dev/null"
|
|
570
|
-
];
|
|
533
|
+
const sshArgs = [...SSH_OPTIONS];
|
|
571
534
|
for (const [remotePort, localPort] of portMappings) {
|
|
572
535
|
sshArgs.push("-L", `${localPort}:localhost:${remotePort}`);
|
|
573
536
|
}
|
|
574
|
-
sshArgs.push(
|
|
537
|
+
sshArgs.push(`${token}@${host}`);
|
|
575
538
|
const ssh = (0, import_child_process.spawn)("ssh", sshArgs, {
|
|
576
539
|
stdio: "inherit"
|
|
577
540
|
});
|
|
578
|
-
ssh.on("close", (
|
|
541
|
+
ssh.on("close", () => {
|
|
579
542
|
resolve();
|
|
580
543
|
});
|
|
581
544
|
ssh.on("error", reject);
|
|
@@ -585,12 +548,10 @@ async function connectSSH(privateKeyPath, remoteHost, portMappings) {
|
|
|
585
548
|
// src/lib/workspace-connection.ts
|
|
586
549
|
var import_chalk4 = __toESM(require("chalk"));
|
|
587
550
|
var import_prompts = __toESM(require("prompts"));
|
|
588
|
-
var import_path5 = __toESM(require("path"));
|
|
589
|
-
var import_fs4 = __toESM(require("fs"));
|
|
590
551
|
|
|
591
552
|
// src/lib/git.ts
|
|
592
553
|
var import_child_process2 = require("child_process");
|
|
593
|
-
var
|
|
554
|
+
var import_path2 = __toESM(require("path"));
|
|
594
555
|
function getGitRoot() {
|
|
595
556
|
try {
|
|
596
557
|
const root = (0, import_child_process2.execSync)("git rev-parse --show-toplevel", {
|
|
@@ -604,7 +565,7 @@ function getGitRoot() {
|
|
|
604
565
|
}
|
|
605
566
|
function getGitRepoName() {
|
|
606
567
|
const root = getGitRoot();
|
|
607
|
-
return
|
|
568
|
+
return import_path2.default.basename(root);
|
|
608
569
|
}
|
|
609
570
|
function isInsideGitRepo() {
|
|
610
571
|
try {
|
|
@@ -619,16 +580,16 @@ function isInsideGitRepo() {
|
|
|
619
580
|
}
|
|
620
581
|
|
|
621
582
|
// src/lib/replicas-config.ts
|
|
622
|
-
var
|
|
623
|
-
var
|
|
583
|
+
var import_fs2 = __toESM(require("fs"));
|
|
584
|
+
var import_path3 = __toESM(require("path"));
|
|
624
585
|
function readReplicasConfig() {
|
|
625
586
|
try {
|
|
626
587
|
const gitRoot = getGitRoot();
|
|
627
|
-
const configPath =
|
|
628
|
-
if (!
|
|
588
|
+
const configPath = import_path3.default.join(gitRoot, "replicas.json");
|
|
589
|
+
if (!import_fs2.default.existsSync(configPath)) {
|
|
629
590
|
return null;
|
|
630
591
|
}
|
|
631
|
-
const data =
|
|
592
|
+
const data = import_fs2.default.readFileSync(configPath, "utf-8");
|
|
632
593
|
const config2 = JSON.parse(data);
|
|
633
594
|
if (config2.copy && !Array.isArray(config2.copy)) {
|
|
634
595
|
throw new Error('Invalid replicas.json: "copy" must be an array of file paths');
|
|
@@ -658,8 +619,8 @@ function validateCopyFiles(copyFiles) {
|
|
|
658
619
|
const valid = [];
|
|
659
620
|
const invalid = [];
|
|
660
621
|
for (const file of copyFiles) {
|
|
661
|
-
const fullPath =
|
|
662
|
-
if (
|
|
622
|
+
const fullPath = import_path3.default.join(gitRoot, file);
|
|
623
|
+
if (import_fs2.default.existsSync(fullPath)) {
|
|
663
624
|
valid.push(file);
|
|
664
625
|
} else {
|
|
665
626
|
invalid.push(file);
|
|
@@ -669,7 +630,7 @@ function validateCopyFiles(copyFiles) {
|
|
|
669
630
|
}
|
|
670
631
|
function getAbsoluteCopyPath(relativePath) {
|
|
671
632
|
const gitRoot = getGitRoot();
|
|
672
|
-
return
|
|
633
|
+
return import_path3.default.join(gitRoot, relativePath);
|
|
673
634
|
}
|
|
674
635
|
|
|
675
636
|
// src/lib/ports.ts
|
|
@@ -733,7 +694,7 @@ Found ${response.workspaces.length} workspaces matching "${workspaceName}":`));
|
|
|
733
694
|
choices: response.workspaces.map((ws) => ({
|
|
734
695
|
title: `${ws.name} (${ws.status || "unknown"})`,
|
|
735
696
|
value: ws.id,
|
|
736
|
-
description: `
|
|
697
|
+
description: `Status: ${ws.status || "unknown"}`
|
|
737
698
|
}))
|
|
738
699
|
});
|
|
739
700
|
if (!selectResponse.workspaceId) {
|
|
@@ -743,21 +704,18 @@ Found ${response.workspaces.length} workspaces matching "${workspaceName}":`));
|
|
|
743
704
|
}
|
|
744
705
|
console.log(import_chalk4.default.green(`
|
|
745
706
|
\u2713 Selected workspace: ${selectedWorkspace.name}`));
|
|
746
|
-
console.log(import_chalk4.default.gray(` IP: ${selectedWorkspace.ipv4_address}`));
|
|
747
707
|
console.log(import_chalk4.default.gray(` Status: ${selectedWorkspace.status || "unknown"}`));
|
|
748
708
|
if (selectedWorkspace.status === "sleeping") {
|
|
749
709
|
throw new Error(
|
|
750
710
|
"Workspace is currently sleeping. Please wake it up in the dashboard at https://replicas.dev before connecting."
|
|
751
711
|
);
|
|
752
712
|
}
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
import_fs4.default.writeFileSync(keyPath, privateKey, { mode: 384 });
|
|
760
|
-
console.log(import_chalk4.default.green("\u2713 SSH key ready"));
|
|
713
|
+
console.log(import_chalk4.default.blue("\nRequesting SSH access token..."));
|
|
714
|
+
const tokenResponse = await orgAuthenticatedFetch(
|
|
715
|
+
`/v1/workspaces/${selectedWorkspace.id}/ssh-token`,
|
|
716
|
+
{ method: "POST" }
|
|
717
|
+
);
|
|
718
|
+
console.log(import_chalk4.default.green("\u2713 SSH token received"));
|
|
761
719
|
let repoName = null;
|
|
762
720
|
if (options.copy) {
|
|
763
721
|
if (!isInsideGitRepo()) {
|
|
@@ -781,7 +739,7 @@ Warning: ${invalid.length} file(s) not found locally:`));
|
|
|
781
739
|
const remotePath = `/home/ubuntu/workspaces/${repoName}/${file}`;
|
|
782
740
|
console.log(import_chalk4.default.gray(` Copying ${file}...`));
|
|
783
741
|
try {
|
|
784
|
-
await scpCopyFile(
|
|
742
|
+
await scpCopyFile(tokenResponse.token, tokenResponse.host, localPath, remotePath);
|
|
785
743
|
console.log(import_chalk4.default.green(` \u2713 ${file}`));
|
|
786
744
|
} catch (error) {
|
|
787
745
|
console.log(import_chalk4.default.red(` \u2717 Failed to copy ${file}: ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
@@ -813,7 +771,8 @@ Warning: ${invalid.length} file(s) not found locally:`));
|
|
|
813
771
|
console.log(import_chalk4.default.green("\u2713 Port forwarding configured"));
|
|
814
772
|
return {
|
|
815
773
|
workspace: selectedWorkspace,
|
|
816
|
-
|
|
774
|
+
sshToken: tokenResponse.token,
|
|
775
|
+
sshHost: tokenResponse.host,
|
|
817
776
|
portMappings,
|
|
818
777
|
repoName
|
|
819
778
|
};
|
|
@@ -826,17 +785,13 @@ async function connectCommand(workspaceName, options) {
|
|
|
826
785
|
process.exit(1);
|
|
827
786
|
}
|
|
828
787
|
try {
|
|
829
|
-
const { workspace,
|
|
788
|
+
const { workspace, sshToken, sshHost, portMappings } = await prepareWorkspaceConnection(
|
|
830
789
|
workspaceName,
|
|
831
790
|
options
|
|
832
791
|
);
|
|
833
792
|
console.log(import_chalk5.default.blue(`
|
|
834
793
|
Connecting to ${workspace.name}...`));
|
|
835
|
-
|
|
836
|
-
for (const [remotePort, localPort] of portMappings) {
|
|
837
|
-
sshCommand += ` -L ${localPort}:localhost:${remotePort}`;
|
|
838
|
-
}
|
|
839
|
-
sshCommand += ` ubuntu@${workspace.ipv4_address}`;
|
|
794
|
+
const sshCommand = `ssh ${sshToken}@${sshHost}`;
|
|
840
795
|
console.log(import_chalk5.default.gray(`SSH command: ${sshCommand}`));
|
|
841
796
|
if (portMappings.size > 0) {
|
|
842
797
|
console.log(import_chalk5.default.cyan("\nPort forwarding active:"));
|
|
@@ -845,7 +800,7 @@ Connecting to ${workspace.name}...`));
|
|
|
845
800
|
}
|
|
846
801
|
}
|
|
847
802
|
console.log(import_chalk5.default.gray("\nPress Ctrl+D to disconnect.\n"));
|
|
848
|
-
await connectSSH(
|
|
803
|
+
await connectSSH(sshToken, sshHost, portMappings);
|
|
849
804
|
console.log(import_chalk5.default.green("\n\u2713 Disconnected from workspace.\n"));
|
|
850
805
|
} catch (error) {
|
|
851
806
|
console.error(import_chalk5.default.red(`
|
|
@@ -859,28 +814,28 @@ var import_chalk6 = __toESM(require("chalk"));
|
|
|
859
814
|
var import_child_process4 = require("child_process");
|
|
860
815
|
|
|
861
816
|
// src/lib/ssh-config.ts
|
|
862
|
-
var
|
|
863
|
-
var
|
|
817
|
+
var import_fs3 = __toESM(require("fs"));
|
|
818
|
+
var import_path4 = __toESM(require("path"));
|
|
864
819
|
var import_os2 = __toESM(require("os"));
|
|
865
|
-
var SSH_CONFIG_PATH =
|
|
820
|
+
var SSH_CONFIG_PATH = import_path4.default.join(import_os2.default.homedir(), ".ssh", "config");
|
|
866
821
|
var REPLICAS_MARKER_START = "# === REPLICAS CLI MANAGED ENTRY START ===";
|
|
867
822
|
var REPLICAS_MARKER_END = "# === REPLICAS CLI MANAGED ENTRY END ===";
|
|
868
823
|
function ensureSSHDir() {
|
|
869
|
-
const sshDir =
|
|
870
|
-
if (!
|
|
871
|
-
|
|
824
|
+
const sshDir = import_path4.default.join(import_os2.default.homedir(), ".ssh");
|
|
825
|
+
if (!import_fs3.default.existsSync(sshDir)) {
|
|
826
|
+
import_fs3.default.mkdirSync(sshDir, { recursive: true, mode: 448 });
|
|
872
827
|
}
|
|
873
828
|
}
|
|
874
829
|
function readSSHConfig() {
|
|
875
830
|
ensureSSHDir();
|
|
876
|
-
if (!
|
|
831
|
+
if (!import_fs3.default.existsSync(SSH_CONFIG_PATH)) {
|
|
877
832
|
return "";
|
|
878
833
|
}
|
|
879
|
-
return
|
|
834
|
+
return import_fs3.default.readFileSync(SSH_CONFIG_PATH, "utf-8");
|
|
880
835
|
}
|
|
881
836
|
function writeSSHConfig(content) {
|
|
882
837
|
ensureSSHDir();
|
|
883
|
-
|
|
838
|
+
import_fs3.default.writeFileSync(SSH_CONFIG_PATH, content, { mode: 384 });
|
|
884
839
|
}
|
|
885
840
|
function generateConfigBlock(entry) {
|
|
886
841
|
const lines = [
|
|
@@ -888,7 +843,6 @@ function generateConfigBlock(entry) {
|
|
|
888
843
|
`Host ${entry.host}`,
|
|
889
844
|
` HostName ${entry.hostname}`,
|
|
890
845
|
` User ${entry.user}`,
|
|
891
|
-
` IdentityFile ${entry.identityFile}`,
|
|
892
846
|
` StrictHostKeyChecking no`,
|
|
893
847
|
` UserKnownHostsFile /dev/null`
|
|
894
848
|
];
|
|
@@ -949,7 +903,7 @@ async function codeCommand(workspaceName, options) {
|
|
|
949
903
|
process.exit(1);
|
|
950
904
|
}
|
|
951
905
|
try {
|
|
952
|
-
const { workspace,
|
|
906
|
+
const { workspace, sshToken, sshHost, portMappings, repoName } = await prepareWorkspaceConnection(
|
|
953
907
|
workspaceName,
|
|
954
908
|
options
|
|
955
909
|
);
|
|
@@ -957,9 +911,8 @@ async function codeCommand(workspaceName, options) {
|
|
|
957
911
|
console.log(import_chalk6.default.blue("\nConfiguring SSH connection..."));
|
|
958
912
|
addOrUpdateSSHConfigEntry({
|
|
959
913
|
host: hostAlias,
|
|
960
|
-
hostname:
|
|
961
|
-
user:
|
|
962
|
-
identityFile: sshKeyPath,
|
|
914
|
+
hostname: sshHost,
|
|
915
|
+
user: sshToken,
|
|
963
916
|
portForwards: portMappings
|
|
964
917
|
});
|
|
965
918
|
console.log(import_chalk6.default.green(`\u2713 SSH config entry created: ${hostAlias}`));
|
|
@@ -975,6 +928,8 @@ Opening ${ideCommand} for workspace ${workspace.name}...`));
|
|
|
975
928
|
console.log(import_chalk6.default.cyan(` \u2022 localhost:${localPort} \u2192 workspace:${remotePort}`));
|
|
976
929
|
}
|
|
977
930
|
}
|
|
931
|
+
console.log(import_chalk6.default.yellow(`
|
|
932
|
+
Note: SSH tokens expire after 3 hours. Run this command again to refresh.`));
|
|
978
933
|
const ide = (0, import_child_process4.spawn)(ideCommand, [
|
|
979
934
|
"--remote",
|
|
980
935
|
`ssh-remote+${hostAlias}`,
|
|
@@ -1595,75 +1550,10 @@ async function claudeAuthCommand(options = {}) {
|
|
|
1595
1550
|
}
|
|
1596
1551
|
}
|
|
1597
1552
|
|
|
1598
|
-
// src/commands/dev-sync.ts
|
|
1599
|
-
var import_chalk13 = __toESM(require("chalk"));
|
|
1600
|
-
var import_child_process5 = require("child_process");
|
|
1601
|
-
var import_path7 = __toESM(require("path"));
|
|
1602
|
-
async function devSyncCommand(workspaceName) {
|
|
1603
|
-
if (!isAuthenticated()) {
|
|
1604
|
-
console.log(import_chalk13.default.red('Not logged in. Please run "replicas login" first.'));
|
|
1605
|
-
process.exit(1);
|
|
1606
|
-
}
|
|
1607
|
-
try {
|
|
1608
|
-
const { workspace, sshKeyPath } = await prepareWorkspaceConnection(workspaceName, {});
|
|
1609
|
-
if (!workspace.ipv4_address) {
|
|
1610
|
-
throw new Error("Workspace does not have an IP address");
|
|
1611
|
-
}
|
|
1612
|
-
console.log(import_chalk13.default.blue(`
|
|
1613
|
-
Syncing engine to ${workspace.name}...`));
|
|
1614
|
-
const scriptPath = import_path7.default.resolve(__dirname, "../../../engine/scripts/dev-sync.sh");
|
|
1615
|
-
const devSync = (0, import_child_process5.spawn)(scriptPath, [
|
|
1616
|
-
"--ip",
|
|
1617
|
-
workspace.ipv4_address,
|
|
1618
|
-
"--key",
|
|
1619
|
-
sshKeyPath
|
|
1620
|
-
], {
|
|
1621
|
-
stdio: "inherit",
|
|
1622
|
-
shell: true
|
|
1623
|
-
});
|
|
1624
|
-
await new Promise((resolve, reject) => {
|
|
1625
|
-
devSync.on("close", (code) => {
|
|
1626
|
-
if (code === 0) {
|
|
1627
|
-
resolve();
|
|
1628
|
-
} else {
|
|
1629
|
-
reject(new Error(`dev-sync script exited with code ${code}`));
|
|
1630
|
-
}
|
|
1631
|
-
});
|
|
1632
|
-
devSync.on("error", (error) => {
|
|
1633
|
-
reject(error);
|
|
1634
|
-
});
|
|
1635
|
-
});
|
|
1636
|
-
console.log(import_chalk13.default.green("\n\u2713 Engine synced successfully.\n"));
|
|
1637
|
-
console.log(import_chalk13.default.blue("Viewing logs (Ctrl+C to exit)...\n"));
|
|
1638
|
-
const logs = (0, import_child_process5.spawn)("ssh", [
|
|
1639
|
-
"-i",
|
|
1640
|
-
sshKeyPath,
|
|
1641
|
-
`ubuntu@${workspace.ipv4_address}`,
|
|
1642
|
-
"sudo journalctl -fu replicas-engine"
|
|
1643
|
-
], {
|
|
1644
|
-
stdio: "inherit"
|
|
1645
|
-
});
|
|
1646
|
-
process.on("SIGINT", () => {
|
|
1647
|
-
logs.kill("SIGTERM");
|
|
1648
|
-
console.log(import_chalk13.default.green("\n\n\u2713 Disconnected from logs.\n"));
|
|
1649
|
-
process.exit(0);
|
|
1650
|
-
});
|
|
1651
|
-
await new Promise((resolve) => {
|
|
1652
|
-
logs.on("close", () => {
|
|
1653
|
-
resolve();
|
|
1654
|
-
});
|
|
1655
|
-
});
|
|
1656
|
-
} catch (error) {
|
|
1657
|
-
console.error(import_chalk13.default.red(`
|
|
1658
|
-
Error: ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
1659
|
-
process.exit(1);
|
|
1660
|
-
}
|
|
1661
|
-
}
|
|
1662
|
-
|
|
1663
1553
|
// src/commands/init.ts
|
|
1664
|
-
var
|
|
1665
|
-
var
|
|
1666
|
-
var
|
|
1554
|
+
var import_chalk13 = __toESM(require("chalk"));
|
|
1555
|
+
var import_fs4 = __toESM(require("fs"));
|
|
1556
|
+
var import_path5 = __toESM(require("path"));
|
|
1667
1557
|
var REPLICAS_CONFIG_FILENAME = "replicas.json";
|
|
1668
1558
|
function getDefaultConfig() {
|
|
1669
1559
|
return {
|
|
@@ -1677,34 +1567,34 @@ function getDefaultConfig() {
|
|
|
1677
1567
|
};
|
|
1678
1568
|
}
|
|
1679
1569
|
function initCommand(options) {
|
|
1680
|
-
const configPath =
|
|
1681
|
-
if (
|
|
1570
|
+
const configPath = import_path5.default.join(process.cwd(), REPLICAS_CONFIG_FILENAME);
|
|
1571
|
+
if (import_fs4.default.existsSync(configPath) && !options.force) {
|
|
1682
1572
|
console.log(
|
|
1683
|
-
|
|
1573
|
+
import_chalk13.default.yellow(
|
|
1684
1574
|
`${REPLICAS_CONFIG_FILENAME} already exists in this directory.`
|
|
1685
1575
|
)
|
|
1686
1576
|
);
|
|
1687
|
-
console.log(
|
|
1577
|
+
console.log(import_chalk13.default.gray("Use --force to overwrite the existing file."));
|
|
1688
1578
|
return;
|
|
1689
1579
|
}
|
|
1690
1580
|
const defaultConfig = getDefaultConfig();
|
|
1691
1581
|
const configContent = JSON.stringify(defaultConfig, null, 2);
|
|
1692
1582
|
try {
|
|
1693
|
-
|
|
1694
|
-
console.log(
|
|
1583
|
+
import_fs4.default.writeFileSync(configPath, configContent + "\n", "utf-8");
|
|
1584
|
+
console.log(import_chalk13.default.green(`\u2713 Created ${REPLICAS_CONFIG_FILENAME}`));
|
|
1695
1585
|
console.log("");
|
|
1696
|
-
console.log(
|
|
1586
|
+
console.log(import_chalk13.default.gray("Configuration options:"));
|
|
1697
1587
|
console.log(
|
|
1698
|
-
|
|
1588
|
+
import_chalk13.default.gray(' copy - Files to sync to the workspace (e.g., [".env"])')
|
|
1699
1589
|
);
|
|
1700
1590
|
console.log(
|
|
1701
|
-
|
|
1591
|
+
import_chalk13.default.gray(" ports - Ports to forward from the workspace (e.g., [3000, 8080])")
|
|
1702
1592
|
);
|
|
1703
1593
|
console.log(
|
|
1704
|
-
|
|
1594
|
+
import_chalk13.default.gray(" systemPrompt - Custom instructions for AI coding assistants")
|
|
1705
1595
|
);
|
|
1706
1596
|
console.log(
|
|
1707
|
-
|
|
1597
|
+
import_chalk13.default.gray(" startHook - Commands to run on workspace startup")
|
|
1708
1598
|
);
|
|
1709
1599
|
} catch (error) {
|
|
1710
1600
|
throw new Error(
|
|
@@ -1714,7 +1604,7 @@ function initCommand(options) {
|
|
|
1714
1604
|
}
|
|
1715
1605
|
|
|
1716
1606
|
// src/lib/version-check.ts
|
|
1717
|
-
var
|
|
1607
|
+
var import_chalk14 = __toESM(require("chalk"));
|
|
1718
1608
|
var MONOLITH_URL2 = process.env.REPLICAS_MONOLITH_URL || "https://api.replicas.dev";
|
|
1719
1609
|
var VERSION_CHECK_TIMEOUT = 2e3;
|
|
1720
1610
|
function compareVersions(v1, v2) {
|
|
@@ -1740,9 +1630,9 @@ async function checkForUpdates(currentVersion) {
|
|
|
1740
1630
|
const data = await response.json();
|
|
1741
1631
|
const latestVersion = data.version;
|
|
1742
1632
|
if (compareVersions(latestVersion, currentVersion) > 0) {
|
|
1743
|
-
console.error(
|
|
1633
|
+
console.error(import_chalk14.default.gray(`
|
|
1744
1634
|
Update available: ${currentVersion} \u2192 ${latestVersion}`));
|
|
1745
|
-
console.error(
|
|
1635
|
+
console.error(import_chalk14.default.gray(`Run: npm i -g replicas-cli@latest
|
|
1746
1636
|
`));
|
|
1747
1637
|
}
|
|
1748
1638
|
} catch {
|
|
@@ -1750,9 +1640,17 @@ Update available: ${currentVersion} \u2192 ${latestVersion}`));
|
|
|
1750
1640
|
}
|
|
1751
1641
|
|
|
1752
1642
|
// src/commands/replica.ts
|
|
1753
|
-
var
|
|
1643
|
+
var import_chalk15 = __toESM(require("chalk"));
|
|
1754
1644
|
var import_prompts3 = __toESM(require("prompts"));
|
|
1755
1645
|
|
|
1646
|
+
// ../shared/src/sandbox.ts
|
|
1647
|
+
var SANDBOX_LIFECYCLE = {
|
|
1648
|
+
AUTO_STOP_MINUTES: 60,
|
|
1649
|
+
AUTO_ARCHIVE_MINUTES: 60 * 24 * 7,
|
|
1650
|
+
AUTO_DELETE_MINUTES: -1,
|
|
1651
|
+
SSH_TOKEN_EXPIRATION_MINUTES: 3 * 60
|
|
1652
|
+
};
|
|
1653
|
+
|
|
1756
1654
|
// ../shared/src/display-message/parsers/codex-parser.ts
|
|
1757
1655
|
function safeJsonParse(str, fallback) {
|
|
1758
1656
|
try {
|
|
@@ -1764,8 +1662,12 @@ function safeJsonParse(str, fallback) {
|
|
|
1764
1662
|
function getStatusFromExitCode(exitCode) {
|
|
1765
1663
|
return exitCode === 0 ? "completed" : "failed";
|
|
1766
1664
|
}
|
|
1767
|
-
function
|
|
1768
|
-
|
|
1665
|
+
function parseShellOutput(raw) {
|
|
1666
|
+
const exitCodeMatch = raw.match(/^Exit code: (\d+)/);
|
|
1667
|
+
const exitCode = exitCodeMatch ? parseInt(exitCodeMatch[1], 10) : 0;
|
|
1668
|
+
const outputIndex = raw.indexOf("Output:\n");
|
|
1669
|
+
const output = outputIndex >= 0 ? raw.slice(outputIndex + "Output:\n".length) : raw;
|
|
1670
|
+
return { exitCode, output };
|
|
1769
1671
|
}
|
|
1770
1672
|
function parsePatch(input) {
|
|
1771
1673
|
const operations = [];
|
|
@@ -1822,11 +1724,12 @@ function parsePatch(input) {
|
|
|
1822
1724
|
}
|
|
1823
1725
|
function parseCodexEvents(events) {
|
|
1824
1726
|
const messages = [];
|
|
1727
|
+
const pendingCommands = /* @__PURE__ */ new Map();
|
|
1825
1728
|
const pendingPatches = /* @__PURE__ */ new Map();
|
|
1826
|
-
events.forEach((event) => {
|
|
1729
|
+
events.forEach((event, eventIndex) => {
|
|
1827
1730
|
if (event.type === "event_msg" && event.payload?.type === "user_message") {
|
|
1828
1731
|
messages.push({
|
|
1829
|
-
id: `user-${event.timestamp}`,
|
|
1732
|
+
id: `user-${event.timestamp}-${eventIndex}`,
|
|
1830
1733
|
type: "user",
|
|
1831
1734
|
content: event.payload.message || "",
|
|
1832
1735
|
timestamp: event.timestamp
|
|
@@ -1834,7 +1737,7 @@ function parseCodexEvents(events) {
|
|
|
1834
1737
|
}
|
|
1835
1738
|
if (event.type === "event_msg" && event.payload?.type === "agent_reasoning") {
|
|
1836
1739
|
messages.push({
|
|
1837
|
-
id: `reasoning-${event.timestamp}-${messages.length}`,
|
|
1740
|
+
id: `reasoning-${event.timestamp}-${eventIndex}-${messages.length}`,
|
|
1838
1741
|
type: "reasoning",
|
|
1839
1742
|
content: event.payload.text || "",
|
|
1840
1743
|
status: "completed",
|
|
@@ -1848,38 +1751,40 @@ function parseCodexEvents(events) {
|
|
|
1848
1751
|
const textContent = content.filter((c) => c.type === "output_text").map((c) => c.text || "").join("\n");
|
|
1849
1752
|
if (textContent) {
|
|
1850
1753
|
messages.push({
|
|
1851
|
-
id: `agent-${event.timestamp}`,
|
|
1754
|
+
id: `agent-${event.timestamp}-${eventIndex}`,
|
|
1852
1755
|
type: "agent",
|
|
1853
1756
|
content: textContent,
|
|
1854
1757
|
timestamp: event.timestamp
|
|
1855
1758
|
});
|
|
1856
1759
|
}
|
|
1857
1760
|
}
|
|
1858
|
-
if (payloadType === "function_call" && event.payload?.name === "shell") {
|
|
1761
|
+
if (payloadType === "function_call" && (event.payload?.name === "shell" || event.payload?.name === "shell_command")) {
|
|
1762
|
+
const callId = event.payload.call_id;
|
|
1859
1763
|
const args = safeJsonParse(event.payload.arguments || "{}", {});
|
|
1860
1764
|
const command = Array.isArray(args.command) ? args.command.join(" ") : args.command || "";
|
|
1861
|
-
|
|
1862
|
-
id: `command-${
|
|
1765
|
+
const msg = {
|
|
1766
|
+
id: `command-${callId || "no-call-id"}-${eventIndex}`,
|
|
1863
1767
|
type: "command",
|
|
1864
1768
|
command,
|
|
1865
1769
|
output: "",
|
|
1866
|
-
// Will be filled by function_call_output
|
|
1867
1770
|
status: "in_progress",
|
|
1868
1771
|
timestamp: event.timestamp
|
|
1869
|
-
}
|
|
1772
|
+
};
|
|
1773
|
+
messages.push(msg);
|
|
1774
|
+
if (callId) {
|
|
1775
|
+
pendingCommands.set(callId, msg);
|
|
1776
|
+
}
|
|
1870
1777
|
}
|
|
1871
1778
|
if (payloadType === "function_call_output") {
|
|
1872
|
-
const
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
)
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
commandMsg.status = getStatusFromExitCode(output.metadata?.exit_code);
|
|
1882
|
-
}
|
|
1779
|
+
const callId = event.payload.call_id;
|
|
1780
|
+
const rawOutput = event.payload.output || "";
|
|
1781
|
+
const commandMsg = callId ? pendingCommands.get(callId) : void 0;
|
|
1782
|
+
if (commandMsg) {
|
|
1783
|
+
const { exitCode, output } = parseShellOutput(rawOutput);
|
|
1784
|
+
commandMsg.output = output;
|
|
1785
|
+
commandMsg.exitCode = exitCode;
|
|
1786
|
+
commandMsg.status = getStatusFromExitCode(exitCode);
|
|
1787
|
+
pendingCommands.delete(callId);
|
|
1883
1788
|
}
|
|
1884
1789
|
}
|
|
1885
1790
|
if (payloadType === "custom_tool_call") {
|
|
@@ -1892,7 +1797,7 @@ function parseCodexEvents(events) {
|
|
|
1892
1797
|
pendingPatches.set(callId, { input, status, timestamp: event.timestamp, operations });
|
|
1893
1798
|
} else {
|
|
1894
1799
|
messages.push({
|
|
1895
|
-
id: `toolcall-${event.timestamp}`,
|
|
1800
|
+
id: `toolcall-${event.timestamp}-${eventIndex}`,
|
|
1896
1801
|
type: "tool_call",
|
|
1897
1802
|
server: "custom",
|
|
1898
1803
|
tool: name,
|
|
@@ -1910,7 +1815,7 @@ function parseCodexEvents(events) {
|
|
|
1910
1815
|
const pendingPatch = pendingPatches.get(callId);
|
|
1911
1816
|
if (pendingPatch) {
|
|
1912
1817
|
messages.push({
|
|
1913
|
-
id: `patch-${pendingPatch.timestamp}`,
|
|
1818
|
+
id: `patch-${pendingPatch.timestamp}-${eventIndex}`,
|
|
1914
1819
|
type: "patch",
|
|
1915
1820
|
operations: pendingPatch.operations,
|
|
1916
1821
|
output: output.output || "",
|
|
@@ -1920,7 +1825,7 @@ function parseCodexEvents(events) {
|
|
|
1920
1825
|
});
|
|
1921
1826
|
pendingPatches.delete(callId);
|
|
1922
1827
|
} else {
|
|
1923
|
-
const toolCallMsg =
|
|
1828
|
+
const toolCallMsg = messages.findLast((m) => m.type === "tool_call");
|
|
1924
1829
|
if (toolCallMsg) {
|
|
1925
1830
|
toolCallMsg.status = getStatusFromExitCode(output.metadata?.exit_code);
|
|
1926
1831
|
}
|
|
@@ -1937,7 +1842,7 @@ function parseCodexEvents(events) {
|
|
|
1937
1842
|
completed: item.status === "completed"
|
|
1938
1843
|
}));
|
|
1939
1844
|
messages.push({
|
|
1940
|
-
id: `todo-${event.timestamp}`,
|
|
1845
|
+
id: `todo-${event.timestamp}-${eventIndex}`,
|
|
1941
1846
|
type: "todo_list",
|
|
1942
1847
|
items: todoItems,
|
|
1943
1848
|
status: "completed",
|
|
@@ -2181,12 +2086,9 @@ function formatDate(dateString) {
|
|
|
2181
2086
|
function formatStatus(status) {
|
|
2182
2087
|
switch (status) {
|
|
2183
2088
|
case "active":
|
|
2184
|
-
return
|
|
2185
|
-
case "booting":
|
|
2186
|
-
case "initializing":
|
|
2187
|
-
return import_chalk16.default.yellow(status);
|
|
2089
|
+
return import_chalk15.default.green(status);
|
|
2188
2090
|
case "sleeping":
|
|
2189
|
-
return
|
|
2091
|
+
return import_chalk15.default.gray(status);
|
|
2190
2092
|
default:
|
|
2191
2093
|
return status;
|
|
2192
2094
|
}
|
|
@@ -2199,87 +2101,87 @@ function formatDisplayMessage(message) {
|
|
|
2199
2101
|
const time = new Date(message.timestamp).toLocaleTimeString();
|
|
2200
2102
|
switch (message.type) {
|
|
2201
2103
|
case "user":
|
|
2202
|
-
console.log(
|
|
2104
|
+
console.log(import_chalk15.default.blue(`
|
|
2203
2105
|
[${time}] USER:`));
|
|
2204
|
-
console.log(
|
|
2106
|
+
console.log(import_chalk15.default.white(` ${truncate(message.content, 500)}`));
|
|
2205
2107
|
break;
|
|
2206
2108
|
case "agent":
|
|
2207
|
-
console.log(
|
|
2109
|
+
console.log(import_chalk15.default.green(`
|
|
2208
2110
|
[${time}] ASSISTANT:`));
|
|
2209
|
-
console.log(
|
|
2111
|
+
console.log(import_chalk15.default.white(` ${truncate(message.content, 500)}`));
|
|
2210
2112
|
break;
|
|
2211
2113
|
case "reasoning":
|
|
2212
|
-
console.log(
|
|
2114
|
+
console.log(import_chalk15.default.gray(`
|
|
2213
2115
|
[${time}] THINKING:`));
|
|
2214
|
-
console.log(
|
|
2116
|
+
console.log(import_chalk15.default.gray(` ${truncate(message.content, 300)}`));
|
|
2215
2117
|
break;
|
|
2216
2118
|
case "command":
|
|
2217
|
-
console.log(
|
|
2119
|
+
console.log(import_chalk15.default.magenta(`
|
|
2218
2120
|
[${time}] COMMAND:`));
|
|
2219
|
-
console.log(
|
|
2121
|
+
console.log(import_chalk15.default.white(` $ ${message.command}`));
|
|
2220
2122
|
if (message.output) {
|
|
2221
|
-
console.log(
|
|
2123
|
+
console.log(import_chalk15.default.gray(` ${truncate(message.output, 200)}`));
|
|
2222
2124
|
}
|
|
2223
2125
|
if (message.exitCode !== void 0) {
|
|
2224
|
-
const exitColor = message.exitCode === 0 ?
|
|
2126
|
+
const exitColor = message.exitCode === 0 ? import_chalk15.default.green : import_chalk15.default.red;
|
|
2225
2127
|
console.log(exitColor(` Exit code: ${message.exitCode}`));
|
|
2226
2128
|
}
|
|
2227
2129
|
break;
|
|
2228
2130
|
case "file_change":
|
|
2229
|
-
console.log(
|
|
2131
|
+
console.log(import_chalk15.default.yellow(`
|
|
2230
2132
|
[${time}] FILE CHANGES:`));
|
|
2231
2133
|
for (const change of message.changes) {
|
|
2232
2134
|
const icon = change.kind === "add" ? "+" : change.kind === "delete" ? "-" : "~";
|
|
2233
|
-
const color = change.kind === "add" ?
|
|
2135
|
+
const color = change.kind === "add" ? import_chalk15.default.green : change.kind === "delete" ? import_chalk15.default.red : import_chalk15.default.yellow;
|
|
2234
2136
|
console.log(color(` ${icon} ${change.path}`));
|
|
2235
2137
|
}
|
|
2236
2138
|
break;
|
|
2237
2139
|
case "patch":
|
|
2238
|
-
console.log(
|
|
2140
|
+
console.log(import_chalk15.default.yellow(`
|
|
2239
2141
|
[${time}] PATCH:`));
|
|
2240
2142
|
for (const op of message.operations) {
|
|
2241
2143
|
const icon = op.action === "add" ? "+" : op.action === "delete" ? "-" : "~";
|
|
2242
|
-
const color = op.action === "add" ?
|
|
2144
|
+
const color = op.action === "add" ? import_chalk15.default.green : op.action === "delete" ? import_chalk15.default.red : import_chalk15.default.yellow;
|
|
2243
2145
|
console.log(color(` ${icon} ${op.path}`));
|
|
2244
2146
|
}
|
|
2245
2147
|
break;
|
|
2246
2148
|
case "tool_call":
|
|
2247
|
-
console.log(
|
|
2149
|
+
console.log(import_chalk15.default.cyan(`
|
|
2248
2150
|
[${time}] TOOL: ${message.tool}`));
|
|
2249
2151
|
if (message.output) {
|
|
2250
|
-
console.log(
|
|
2152
|
+
console.log(import_chalk15.default.gray(` ${truncate(message.output, 200)}`));
|
|
2251
2153
|
}
|
|
2252
2154
|
break;
|
|
2253
2155
|
case "web_search":
|
|
2254
|
-
console.log(
|
|
2156
|
+
console.log(import_chalk15.default.cyan(`
|
|
2255
2157
|
[${time}] WEB SEARCH:`));
|
|
2256
|
-
console.log(
|
|
2158
|
+
console.log(import_chalk15.default.white(` "${message.query}"`));
|
|
2257
2159
|
break;
|
|
2258
2160
|
case "todo_list":
|
|
2259
|
-
console.log(
|
|
2161
|
+
console.log(import_chalk15.default.blue(`
|
|
2260
2162
|
[${time}] PLAN:`));
|
|
2261
2163
|
for (const item of message.items) {
|
|
2262
|
-
const icon = item.completed ?
|
|
2164
|
+
const icon = item.completed ? import_chalk15.default.green("[x]") : import_chalk15.default.gray("[ ]");
|
|
2263
2165
|
console.log(` ${icon} ${item.text}`);
|
|
2264
2166
|
}
|
|
2265
2167
|
break;
|
|
2266
2168
|
case "subagent":
|
|
2267
|
-
console.log(
|
|
2169
|
+
console.log(import_chalk15.default.magenta(`
|
|
2268
2170
|
[${time}] SUBAGENT: ${message.description}`));
|
|
2269
2171
|
if (message.output) {
|
|
2270
|
-
console.log(
|
|
2172
|
+
console.log(import_chalk15.default.gray(` ${truncate(message.output, 200)}`));
|
|
2271
2173
|
}
|
|
2272
2174
|
break;
|
|
2273
2175
|
case "error":
|
|
2274
|
-
console.log(
|
|
2176
|
+
console.log(import_chalk15.default.red(`
|
|
2275
2177
|
[${time}] ERROR:`));
|
|
2276
|
-
console.log(
|
|
2178
|
+
console.log(import_chalk15.default.red(` ${message.message}`));
|
|
2277
2179
|
break;
|
|
2278
2180
|
}
|
|
2279
2181
|
}
|
|
2280
2182
|
async function replicaListCommand(options) {
|
|
2281
2183
|
if (!isAuthenticated()) {
|
|
2282
|
-
console.log(
|
|
2184
|
+
console.log(import_chalk15.default.red('Not logged in. Please run "replicas login" first.'));
|
|
2283
2185
|
process.exit(1);
|
|
2284
2186
|
}
|
|
2285
2187
|
try {
|
|
@@ -2291,96 +2193,94 @@ async function replicaListCommand(options) {
|
|
|
2291
2193
|
`/v1/replica${query ? "?" + query : ""}`
|
|
2292
2194
|
);
|
|
2293
2195
|
if (response.replicas.length === 0) {
|
|
2294
|
-
console.log(
|
|
2196
|
+
console.log(import_chalk15.default.yellow("\nNo replicas found.\n"));
|
|
2295
2197
|
return;
|
|
2296
2198
|
}
|
|
2297
|
-
console.log(
|
|
2199
|
+
console.log(import_chalk15.default.green(`
|
|
2298
2200
|
Replicas (Page ${response.page} of ${response.totalPages}, Total: ${response.total}):
|
|
2299
2201
|
`));
|
|
2300
2202
|
for (const replica of response.replicas) {
|
|
2301
|
-
console.log(
|
|
2302
|
-
console.log(
|
|
2303
|
-
if (replica.
|
|
2304
|
-
console.log(
|
|
2203
|
+
console.log(import_chalk15.default.white(` ${replica.name}`));
|
|
2204
|
+
console.log(import_chalk15.default.gray(` ID: ${replica.id}`));
|
|
2205
|
+
if (replica.repositories.length > 0) {
|
|
2206
|
+
console.log(import_chalk15.default.gray(` Repositories: ${replica.repositories.map((repository) => repository.name).join(", ")}`));
|
|
2305
2207
|
}
|
|
2306
|
-
console.log(
|
|
2307
|
-
console.log(
|
|
2308
|
-
console.log(import_chalk16.default.gray(` Created: ${formatDate(replica.created_at)}`));
|
|
2208
|
+
console.log(import_chalk15.default.gray(` Status: ${formatStatus(replica.status)}`));
|
|
2209
|
+
console.log(import_chalk15.default.gray(` Created: ${formatDate(replica.created_at)}`));
|
|
2309
2210
|
if (replica.pull_requests && replica.pull_requests.length > 0) {
|
|
2310
|
-
console.log(
|
|
2211
|
+
console.log(import_chalk15.default.gray(` Pull Requests:`));
|
|
2311
2212
|
for (const pr of replica.pull_requests) {
|
|
2312
|
-
console.log(
|
|
2213
|
+
console.log(import_chalk15.default.cyan(` - ${pr.repository} #${pr.number}: ${pr.url}`));
|
|
2313
2214
|
}
|
|
2314
2215
|
}
|
|
2315
2216
|
console.log();
|
|
2316
2217
|
}
|
|
2317
2218
|
} catch (error) {
|
|
2318
|
-
console.error(
|
|
2219
|
+
console.error(import_chalk15.default.red(`Error: ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
2319
2220
|
process.exit(1);
|
|
2320
2221
|
}
|
|
2321
2222
|
}
|
|
2322
2223
|
async function replicaGetCommand(id) {
|
|
2323
2224
|
if (!isAuthenticated()) {
|
|
2324
|
-
console.log(
|
|
2225
|
+
console.log(import_chalk15.default.red('Not logged in. Please run "replicas login" first.'));
|
|
2325
2226
|
process.exit(1);
|
|
2326
2227
|
}
|
|
2327
2228
|
try {
|
|
2328
2229
|
const response = await orgAuthenticatedFetch(`/v1/replica/${id}`);
|
|
2329
2230
|
const replica = response.replica;
|
|
2330
|
-
console.log(
|
|
2231
|
+
console.log(import_chalk15.default.green(`
|
|
2331
2232
|
Replica: ${replica.name}
|
|
2332
2233
|
`));
|
|
2333
|
-
console.log(
|
|
2334
|
-
if (replica.
|
|
2335
|
-
console.log(
|
|
2234
|
+
console.log(import_chalk15.default.gray(` ID: ${replica.id}`));
|
|
2235
|
+
if (replica.repositories.length > 0) {
|
|
2236
|
+
console.log(import_chalk15.default.gray(` Repositories: ${replica.repositories.map((repository) => repository.name).join(", ")}`));
|
|
2336
2237
|
}
|
|
2337
|
-
console.log(
|
|
2338
|
-
console.log(
|
|
2339
|
-
console.log(import_chalk16.default.gray(` Created: ${formatDate(replica.created_at)}`));
|
|
2238
|
+
console.log(import_chalk15.default.gray(` Status: ${formatStatus(replica.status)}`));
|
|
2239
|
+
console.log(import_chalk15.default.gray(` Created: ${formatDate(replica.created_at)}`));
|
|
2340
2240
|
if (replica.waking) {
|
|
2341
|
-
console.log(
|
|
2241
|
+
console.log(import_chalk15.default.yellow("\n Workspace is waking from sleep. Retry in 30-90 seconds for full details.\n"));
|
|
2342
2242
|
} else {
|
|
2343
2243
|
if (replica.coding_agent) {
|
|
2344
|
-
console.log(
|
|
2345
|
-
}
|
|
2346
|
-
if (replica.branch) {
|
|
2347
|
-
console.log(import_chalk16.default.gray(` Branch: ${replica.branch}`));
|
|
2244
|
+
console.log(import_chalk15.default.gray(` Coding Agent: ${replica.coding_agent}`));
|
|
2348
2245
|
}
|
|
2349
|
-
if (replica.
|
|
2350
|
-
console.log(
|
|
2246
|
+
if (replica.repository_statuses && replica.repository_statuses.length > 0) {
|
|
2247
|
+
console.log(import_chalk15.default.gray(" Repository Statuses:"));
|
|
2248
|
+
for (const repositoryStatus of replica.repository_statuses) {
|
|
2249
|
+
const changeText = repositoryStatus.git_diff ? ` (${import_chalk15.default.green(`+${repositoryStatus.git_diff.added}`)} / ${import_chalk15.default.red(`-${repositoryStatus.git_diff.removed}`)})` : "";
|
|
2250
|
+
console.log(import_chalk15.default.gray(` - ${repositoryStatus.repository}: ${repositoryStatus.branch || "unknown"}${changeText}`));
|
|
2251
|
+
}
|
|
2351
2252
|
}
|
|
2352
2253
|
}
|
|
2353
2254
|
if (replica.pull_requests && replica.pull_requests.length > 0) {
|
|
2354
|
-
console.log(
|
|
2255
|
+
console.log(import_chalk15.default.gray(` Pull Requests:`));
|
|
2355
2256
|
for (const pr of replica.pull_requests) {
|
|
2356
|
-
console.log(
|
|
2257
|
+
console.log(import_chalk15.default.cyan(` - ${pr.repository} #${pr.number}: ${pr.url}`));
|
|
2357
2258
|
}
|
|
2358
2259
|
}
|
|
2359
2260
|
console.log();
|
|
2360
2261
|
} catch (error) {
|
|
2361
|
-
console.error(
|
|
2262
|
+
console.error(import_chalk15.default.red(`Error: ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
2362
2263
|
process.exit(1);
|
|
2363
2264
|
}
|
|
2364
2265
|
}
|
|
2365
2266
|
async function replicaCreateCommand(name, options) {
|
|
2366
2267
|
if (!isAuthenticated()) {
|
|
2367
|
-
console.log(
|
|
2268
|
+
console.log(import_chalk15.default.red('Not logged in. Please run "replicas login" first.'));
|
|
2368
2269
|
process.exit(1);
|
|
2369
2270
|
}
|
|
2370
2271
|
try {
|
|
2371
2272
|
const repoResponse = await orgAuthenticatedFetch("/v1/repositories");
|
|
2372
2273
|
const repositories = repoResponse.repositories;
|
|
2373
2274
|
if (repositories.length === 0) {
|
|
2374
|
-
console.log(
|
|
2275
|
+
console.log(import_chalk15.default.red("No repositories found. Please add a repository first."));
|
|
2375
2276
|
process.exit(1);
|
|
2376
2277
|
}
|
|
2377
2278
|
let replicaName = name;
|
|
2378
2279
|
let message = options.message;
|
|
2379
|
-
let
|
|
2380
|
-
let instanceType = options.instanceType;
|
|
2280
|
+
let selectedRepositories = options.repositories?.split(",").map((repository) => repository.trim()).filter((repository) => repository.length > 0);
|
|
2381
2281
|
let codingAgent = options.agent;
|
|
2382
2282
|
if (replicaName && /\s/.test(replicaName)) {
|
|
2383
|
-
console.log(
|
|
2283
|
+
console.log(import_chalk15.default.red("Replica name cannot contain spaces."));
|
|
2384
2284
|
process.exit(1);
|
|
2385
2285
|
}
|
|
2386
2286
|
if (!replicaName) {
|
|
@@ -2395,27 +2295,28 @@ async function replicaCreateCommand(name, options) {
|
|
|
2395
2295
|
}
|
|
2396
2296
|
});
|
|
2397
2297
|
if (!response2.name) {
|
|
2398
|
-
console.log(
|
|
2298
|
+
console.log(import_chalk15.default.yellow("\nCancelled."));
|
|
2399
2299
|
return;
|
|
2400
2300
|
}
|
|
2401
2301
|
replicaName = response2.name;
|
|
2402
2302
|
}
|
|
2403
|
-
if (!
|
|
2303
|
+
if (!selectedRepositories || selectedRepositories.length === 0) {
|
|
2404
2304
|
const response2 = await (0, import_prompts3.default)({
|
|
2405
|
-
type: "
|
|
2406
|
-
name: "
|
|
2407
|
-
message: "Select
|
|
2305
|
+
type: "multiselect",
|
|
2306
|
+
name: "repositories",
|
|
2307
|
+
message: "Select repositories:",
|
|
2408
2308
|
choices: repositories.map((repo) => ({
|
|
2409
2309
|
title: repo.name,
|
|
2410
2310
|
value: repo.name,
|
|
2411
2311
|
description: repo.url
|
|
2412
|
-
}))
|
|
2312
|
+
})),
|
|
2313
|
+
min: 1
|
|
2413
2314
|
});
|
|
2414
|
-
if (!response2.
|
|
2415
|
-
console.log(
|
|
2315
|
+
if (!response2.repositories || response2.repositories.length === 0) {
|
|
2316
|
+
console.log(import_chalk15.default.yellow("\nCancelled."));
|
|
2416
2317
|
return;
|
|
2417
2318
|
}
|
|
2418
|
-
|
|
2319
|
+
selectedRepositories = response2.repositories;
|
|
2419
2320
|
}
|
|
2420
2321
|
if (!message) {
|
|
2421
2322
|
const response2 = await (0, import_prompts3.default)({
|
|
@@ -2425,29 +2326,11 @@ async function replicaCreateCommand(name, options) {
|
|
|
2425
2326
|
validate: (value) => value.trim() ? true : "Message is required"
|
|
2426
2327
|
});
|
|
2427
2328
|
if (!response2.message) {
|
|
2428
|
-
console.log(
|
|
2329
|
+
console.log(import_chalk15.default.yellow("\nCancelled."));
|
|
2429
2330
|
return;
|
|
2430
2331
|
}
|
|
2431
2332
|
message = response2.message;
|
|
2432
2333
|
}
|
|
2433
|
-
if (!instanceType) {
|
|
2434
|
-
const response2 = await (0, import_prompts3.default)({
|
|
2435
|
-
type: "select",
|
|
2436
|
-
name: "instanceType",
|
|
2437
|
-
message: "Select instance type:",
|
|
2438
|
-
choices: [
|
|
2439
|
-
{ title: "Standard (2 vCPU, 4GB RAM)", value: "standard" },
|
|
2440
|
-
{ title: "Large (2 vCPU, 8GB RAM)", value: "large" },
|
|
2441
|
-
{ title: "Power (4 vCPU, 16GB RAM)", value: "power" }
|
|
2442
|
-
],
|
|
2443
|
-
initial: 0
|
|
2444
|
-
});
|
|
2445
|
-
if (!response2.instanceType) {
|
|
2446
|
-
console.log(import_chalk16.default.yellow("\nCancelled."));
|
|
2447
|
-
return;
|
|
2448
|
-
}
|
|
2449
|
-
instanceType = response2.instanceType;
|
|
2450
|
-
}
|
|
2451
2334
|
if (!codingAgent) {
|
|
2452
2335
|
const response2 = await (0, import_prompts3.default)({
|
|
2453
2336
|
type: "select",
|
|
@@ -2460,46 +2343,43 @@ async function replicaCreateCommand(name, options) {
|
|
|
2460
2343
|
initial: 0
|
|
2461
2344
|
});
|
|
2462
2345
|
if (!response2.agent) {
|
|
2463
|
-
console.log(
|
|
2346
|
+
console.log(import_chalk15.default.yellow("\nCancelled."));
|
|
2464
2347
|
return;
|
|
2465
2348
|
}
|
|
2466
2349
|
codingAgent = response2.agent;
|
|
2467
2350
|
}
|
|
2468
|
-
if (!instanceType || !["standard", "large", "power"].includes(instanceType)) {
|
|
2469
|
-
console.log(import_chalk16.default.red(`Invalid instance type: ${instanceType}. Must be one of: standard, large, power`));
|
|
2470
|
-
process.exit(1);
|
|
2471
|
-
}
|
|
2472
2351
|
if (!codingAgent || !["claude", "codex"].includes(codingAgent)) {
|
|
2473
|
-
console.log(
|
|
2352
|
+
console.log(import_chalk15.default.red(`Invalid coding agent: ${codingAgent}. Must be one of: claude, codex`));
|
|
2474
2353
|
process.exit(1);
|
|
2475
2354
|
}
|
|
2476
2355
|
const body = {
|
|
2477
2356
|
name: replicaName,
|
|
2478
2357
|
message,
|
|
2479
|
-
|
|
2480
|
-
instance_type: instanceType,
|
|
2358
|
+
repositories: selectedRepositories,
|
|
2481
2359
|
coding_agent: codingAgent
|
|
2482
2360
|
};
|
|
2483
|
-
console.log(
|
|
2361
|
+
console.log(import_chalk15.default.gray("\nCreating replica..."));
|
|
2484
2362
|
const response = await orgAuthenticatedFetch("/v1/replica", {
|
|
2485
2363
|
method: "POST",
|
|
2486
2364
|
body
|
|
2487
2365
|
});
|
|
2488
2366
|
const replica = response.replica;
|
|
2489
|
-
console.log(
|
|
2367
|
+
console.log(import_chalk15.default.green(`
|
|
2490
2368
|
Created replica: ${replica.name}`));
|
|
2491
|
-
console.log(
|
|
2492
|
-
console.log(
|
|
2493
|
-
|
|
2369
|
+
console.log(import_chalk15.default.gray(` ID: ${replica.id}`));
|
|
2370
|
+
console.log(import_chalk15.default.gray(` Status: ${formatStatus(replica.status)}`));
|
|
2371
|
+
if (replica.repositories.length > 0) {
|
|
2372
|
+
console.log(import_chalk15.default.gray(` Repositories: ${replica.repositories.map((repository) => repository.name).join(", ")}`));
|
|
2373
|
+
}
|
|
2494
2374
|
console.log();
|
|
2495
2375
|
} catch (error) {
|
|
2496
|
-
console.error(
|
|
2376
|
+
console.error(import_chalk15.default.red(`Error: ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
2497
2377
|
process.exit(1);
|
|
2498
2378
|
}
|
|
2499
2379
|
}
|
|
2500
2380
|
async function replicaSendCommand(id, options) {
|
|
2501
2381
|
if (!isAuthenticated()) {
|
|
2502
|
-
console.log(
|
|
2382
|
+
console.log(import_chalk15.default.red('Not logged in. Please run "replicas login" first.'));
|
|
2503
2383
|
process.exit(1);
|
|
2504
2384
|
}
|
|
2505
2385
|
try {
|
|
@@ -2512,7 +2392,7 @@ async function replicaSendCommand(id, options) {
|
|
|
2512
2392
|
validate: (value) => value.trim() ? true : "Message is required"
|
|
2513
2393
|
});
|
|
2514
2394
|
if (!response2.message) {
|
|
2515
|
-
console.log(
|
|
2395
|
+
console.log(import_chalk15.default.yellow("\nCancelled."));
|
|
2516
2396
|
return;
|
|
2517
2397
|
}
|
|
2518
2398
|
message = response2.message;
|
|
@@ -2522,7 +2402,7 @@ async function replicaSendCommand(id, options) {
|
|
|
2522
2402
|
};
|
|
2523
2403
|
if (options.agent) {
|
|
2524
2404
|
if (!["claude", "codex"].includes(options.agent)) {
|
|
2525
|
-
console.log(
|
|
2405
|
+
console.log(import_chalk15.default.red(`Invalid coding agent: ${options.agent}. Must be one of: claude, codex`));
|
|
2526
2406
|
process.exit(1);
|
|
2527
2407
|
}
|
|
2528
2408
|
body.coding_agent = options.agent;
|
|
@@ -2534,21 +2414,21 @@ async function replicaSendCommand(id, options) {
|
|
|
2534
2414
|
body
|
|
2535
2415
|
}
|
|
2536
2416
|
);
|
|
2537
|
-
const statusColor = response.status === "sent" ?
|
|
2417
|
+
const statusColor = response.status === "sent" ? import_chalk15.default.green : import_chalk15.default.yellow;
|
|
2538
2418
|
console.log(statusColor(`
|
|
2539
2419
|
Message ${response.status}`));
|
|
2540
2420
|
if (response.position !== void 0 && response.position > 0) {
|
|
2541
|
-
console.log(
|
|
2421
|
+
console.log(import_chalk15.default.gray(` Queue position: ${response.position}`));
|
|
2542
2422
|
}
|
|
2543
2423
|
console.log();
|
|
2544
2424
|
} catch (error) {
|
|
2545
|
-
console.error(
|
|
2425
|
+
console.error(import_chalk15.default.red(`Error: ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
2546
2426
|
process.exit(1);
|
|
2547
2427
|
}
|
|
2548
2428
|
}
|
|
2549
2429
|
async function replicaDeleteCommand(id, options) {
|
|
2550
2430
|
if (!isAuthenticated()) {
|
|
2551
|
-
console.log(
|
|
2431
|
+
console.log(import_chalk15.default.red('Not logged in. Please run "replicas login" first.'));
|
|
2552
2432
|
process.exit(1);
|
|
2553
2433
|
}
|
|
2554
2434
|
try {
|
|
@@ -2560,24 +2440,24 @@ async function replicaDeleteCommand(id, options) {
|
|
|
2560
2440
|
initial: false
|
|
2561
2441
|
});
|
|
2562
2442
|
if (!response.confirm) {
|
|
2563
|
-
console.log(
|
|
2443
|
+
console.log(import_chalk15.default.yellow("\nCancelled."));
|
|
2564
2444
|
return;
|
|
2565
2445
|
}
|
|
2566
2446
|
}
|
|
2567
2447
|
await orgAuthenticatedFetch(`/v1/replica/${id}`, {
|
|
2568
2448
|
method: "DELETE"
|
|
2569
2449
|
});
|
|
2570
|
-
console.log(
|
|
2450
|
+
console.log(import_chalk15.default.green(`
|
|
2571
2451
|
Replica ${id} deleted.
|
|
2572
2452
|
`));
|
|
2573
2453
|
} catch (error) {
|
|
2574
|
-
console.error(
|
|
2454
|
+
console.error(import_chalk15.default.red(`Error: ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
2575
2455
|
process.exit(1);
|
|
2576
2456
|
}
|
|
2577
2457
|
}
|
|
2578
2458
|
async function replicaReadCommand(id, options) {
|
|
2579
2459
|
if (!isAuthenticated()) {
|
|
2580
|
-
console.log(
|
|
2460
|
+
console.log(import_chalk15.default.red('Not logged in. Please run "replicas login" first.'));
|
|
2581
2461
|
process.exit(1);
|
|
2582
2462
|
}
|
|
2583
2463
|
try {
|
|
@@ -2589,79 +2469,79 @@ async function replicaReadCommand(id, options) {
|
|
|
2589
2469
|
`/v1/replica/${id}/read${query ? "?" + query : ""}`
|
|
2590
2470
|
);
|
|
2591
2471
|
if (response.waking) {
|
|
2592
|
-
console.log(
|
|
2472
|
+
console.log(import_chalk15.default.yellow("\nWorkspace is waking from sleep. Retry in 30-90 seconds.\n"));
|
|
2593
2473
|
return;
|
|
2594
2474
|
}
|
|
2595
|
-
console.log(
|
|
2475
|
+
console.log(import_chalk15.default.green(`
|
|
2596
2476
|
Conversation History
|
|
2597
2477
|
`));
|
|
2598
2478
|
if (response.coding_agent) {
|
|
2599
|
-
console.log(
|
|
2479
|
+
console.log(import_chalk15.default.gray(` Agent: ${response.coding_agent}`));
|
|
2600
2480
|
}
|
|
2601
2481
|
if (response.thread_id) {
|
|
2602
|
-
console.log(
|
|
2482
|
+
console.log(import_chalk15.default.gray(` Thread ID: ${response.thread_id}`));
|
|
2603
2483
|
}
|
|
2604
|
-
console.log(
|
|
2605
|
-
console.log(
|
|
2484
|
+
console.log(import_chalk15.default.gray(` Total Events: ${response.total}`));
|
|
2485
|
+
console.log(import_chalk15.default.gray(` Showing: ${response.events.length} events`));
|
|
2606
2486
|
if (response.hasMore) {
|
|
2607
|
-
console.log(
|
|
2487
|
+
console.log(import_chalk15.default.gray(` Has More: yes (use --offset to paginate)`));
|
|
2608
2488
|
}
|
|
2609
2489
|
console.log();
|
|
2610
2490
|
if (response.events.length === 0) {
|
|
2611
|
-
console.log(
|
|
2491
|
+
console.log(import_chalk15.default.yellow(" No events found.\n"));
|
|
2612
2492
|
return;
|
|
2613
2493
|
}
|
|
2614
|
-
console.log(
|
|
2494
|
+
console.log(import_chalk15.default.gray("-".repeat(60)));
|
|
2615
2495
|
const agentType = response.coding_agent || "claude";
|
|
2616
2496
|
const displayMessages = parseAgentEvents(response.events, agentType);
|
|
2617
2497
|
for (const message of displayMessages) {
|
|
2618
2498
|
formatDisplayMessage(message);
|
|
2619
2499
|
}
|
|
2620
|
-
console.log(
|
|
2500
|
+
console.log(import_chalk15.default.gray("\n" + "-".repeat(60)));
|
|
2621
2501
|
console.log();
|
|
2622
2502
|
} catch (error) {
|
|
2623
|
-
console.error(
|
|
2503
|
+
console.error(import_chalk15.default.red(`Error: ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
2624
2504
|
process.exit(1);
|
|
2625
2505
|
}
|
|
2626
2506
|
}
|
|
2627
2507
|
|
|
2628
2508
|
// src/commands/repositories.ts
|
|
2629
|
-
var
|
|
2509
|
+
var import_chalk16 = __toESM(require("chalk"));
|
|
2630
2510
|
function formatDate2(dateString) {
|
|
2631
2511
|
return new Date(dateString).toLocaleString();
|
|
2632
2512
|
}
|
|
2633
2513
|
async function repositoriesListCommand() {
|
|
2634
2514
|
if (!isAuthenticated()) {
|
|
2635
|
-
console.log(
|
|
2515
|
+
console.log(import_chalk16.default.red('Not logged in. Please run "replicas login" first.'));
|
|
2636
2516
|
process.exit(1);
|
|
2637
2517
|
}
|
|
2638
2518
|
try {
|
|
2639
2519
|
const response = await orgAuthenticatedFetch("/v1/repositories");
|
|
2640
2520
|
if (response.repositories.length === 0) {
|
|
2641
|
-
console.log(
|
|
2521
|
+
console.log(import_chalk16.default.yellow("\nNo repositories found.\n"));
|
|
2642
2522
|
return;
|
|
2643
2523
|
}
|
|
2644
|
-
console.log(
|
|
2524
|
+
console.log(import_chalk16.default.green(`
|
|
2645
2525
|
Repositories (${response.repositories.length}):
|
|
2646
2526
|
`));
|
|
2647
2527
|
for (const repo of response.repositories) {
|
|
2648
|
-
console.log(
|
|
2649
|
-
console.log(
|
|
2650
|
-
console.log(
|
|
2651
|
-
console.log(
|
|
2528
|
+
console.log(import_chalk16.default.white(` ${repo.name}`));
|
|
2529
|
+
console.log(import_chalk16.default.gray(` URL: ${repo.url}`));
|
|
2530
|
+
console.log(import_chalk16.default.gray(` Default Branch: ${repo.default_branch}`));
|
|
2531
|
+
console.log(import_chalk16.default.gray(` Created: ${formatDate2(repo.created_at)}`));
|
|
2652
2532
|
if (repo.github_repository_id) {
|
|
2653
|
-
console.log(
|
|
2533
|
+
console.log(import_chalk16.default.gray(` GitHub ID: ${repo.github_repository_id}`));
|
|
2654
2534
|
}
|
|
2655
2535
|
console.log();
|
|
2656
2536
|
}
|
|
2657
2537
|
} catch (error) {
|
|
2658
|
-
console.error(
|
|
2538
|
+
console.error(import_chalk16.default.red(`Error: ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
2659
2539
|
process.exit(1);
|
|
2660
2540
|
}
|
|
2661
2541
|
}
|
|
2662
2542
|
|
|
2663
2543
|
// src/index.ts
|
|
2664
|
-
var CLI_VERSION = "0.2.
|
|
2544
|
+
var CLI_VERSION = "0.2.30";
|
|
2665
2545
|
var program = new import_commander.Command();
|
|
2666
2546
|
program.name("replicas").description("CLI for managing Replicas workspaces").version(CLI_VERSION);
|
|
2667
2547
|
program.command("login").description("Authenticate with your Replicas account").action(async () => {
|
|
@@ -2669,7 +2549,7 @@ program.command("login").description("Authenticate with your Replicas account").
|
|
|
2669
2549
|
await loginCommand();
|
|
2670
2550
|
} catch (error) {
|
|
2671
2551
|
if (error instanceof Error) {
|
|
2672
|
-
console.error(
|
|
2552
|
+
console.error(import_chalk17.default.red(`
|
|
2673
2553
|
\u2717 ${error.message}
|
|
2674
2554
|
`));
|
|
2675
2555
|
}
|
|
@@ -2681,7 +2561,7 @@ program.command("init").description("Create a replicas.json configuration file")
|
|
|
2681
2561
|
initCommand(options);
|
|
2682
2562
|
} catch (error) {
|
|
2683
2563
|
if (error instanceof Error) {
|
|
2684
|
-
console.error(
|
|
2564
|
+
console.error(import_chalk17.default.red(`
|
|
2685
2565
|
\u2717 ${error.message}
|
|
2686
2566
|
`));
|
|
2687
2567
|
}
|
|
@@ -2693,7 +2573,7 @@ program.command("logout").description("Clear stored credentials").action(() => {
|
|
|
2693
2573
|
logoutCommand();
|
|
2694
2574
|
} catch (error) {
|
|
2695
2575
|
if (error instanceof Error) {
|
|
2696
|
-
console.error(
|
|
2576
|
+
console.error(import_chalk17.default.red(`
|
|
2697
2577
|
\u2717 ${error.message}
|
|
2698
2578
|
`));
|
|
2699
2579
|
}
|
|
@@ -2705,7 +2585,7 @@ program.command("whoami").description("Display current authenticated user").acti
|
|
|
2705
2585
|
await whoamiCommand();
|
|
2706
2586
|
} catch (error) {
|
|
2707
2587
|
if (error instanceof Error) {
|
|
2708
|
-
console.error(
|
|
2588
|
+
console.error(import_chalk17.default.red(`
|
|
2709
2589
|
\u2717 ${error.message}
|
|
2710
2590
|
`));
|
|
2711
2591
|
}
|
|
@@ -2717,7 +2597,7 @@ program.command("tools").description("List tools available on the Replicas Machi
|
|
|
2717
2597
|
await toolsCommand();
|
|
2718
2598
|
} catch (error) {
|
|
2719
2599
|
if (error instanceof Error) {
|
|
2720
|
-
console.error(
|
|
2600
|
+
console.error(import_chalk17.default.red(`
|
|
2721
2601
|
\u2717 ${error.message}
|
|
2722
2602
|
`));
|
|
2723
2603
|
}
|
|
@@ -2729,7 +2609,7 @@ program.command("codex-auth").description("Authenticate Replicas with your Codex
|
|
|
2729
2609
|
await codexAuthCommand(options);
|
|
2730
2610
|
} catch (error) {
|
|
2731
2611
|
if (error instanceof Error) {
|
|
2732
|
-
console.error(
|
|
2612
|
+
console.error(import_chalk17.default.red(`
|
|
2733
2613
|
\u2717 ${error.message}
|
|
2734
2614
|
`));
|
|
2735
2615
|
}
|
|
@@ -2741,7 +2621,7 @@ program.command("claude-auth").description("Authenticate Replicas with your Clau
|
|
|
2741
2621
|
await claudeAuthCommand(options);
|
|
2742
2622
|
} catch (error) {
|
|
2743
2623
|
if (error instanceof Error) {
|
|
2744
|
-
console.error(
|
|
2624
|
+
console.error(import_chalk17.default.red(`
|
|
2745
2625
|
\u2717 ${error.message}
|
|
2746
2626
|
`));
|
|
2747
2627
|
}
|
|
@@ -2754,7 +2634,7 @@ org.command("switch").description("Switch to a different organization").action(a
|
|
|
2754
2634
|
await orgSwitchCommand();
|
|
2755
2635
|
} catch (error) {
|
|
2756
2636
|
if (error instanceof Error) {
|
|
2757
|
-
console.error(
|
|
2637
|
+
console.error(import_chalk17.default.red(`
|
|
2758
2638
|
\u2717 ${error.message}
|
|
2759
2639
|
`));
|
|
2760
2640
|
}
|
|
@@ -2766,7 +2646,7 @@ org.action(async () => {
|
|
|
2766
2646
|
await orgCommand();
|
|
2767
2647
|
} catch (error) {
|
|
2768
2648
|
if (error instanceof Error) {
|
|
2769
|
-
console.error(
|
|
2649
|
+
console.error(import_chalk17.default.red(`
|
|
2770
2650
|
\u2717 ${error.message}
|
|
2771
2651
|
`));
|
|
2772
2652
|
}
|
|
@@ -2778,7 +2658,7 @@ program.command("connect <workspace-name>").description("Connect to a workspace
|
|
|
2778
2658
|
await connectCommand(workspaceName, options);
|
|
2779
2659
|
} catch (error) {
|
|
2780
2660
|
if (error instanceof Error) {
|
|
2781
|
-
console.error(
|
|
2661
|
+
console.error(import_chalk17.default.red(`
|
|
2782
2662
|
\u2717 ${error.message}
|
|
2783
2663
|
`));
|
|
2784
2664
|
}
|
|
@@ -2790,34 +2670,20 @@ program.command("code <workspace-name>").description("Open a workspace in VSCode
|
|
|
2790
2670
|
await codeCommand(workspaceName, options);
|
|
2791
2671
|
} catch (error) {
|
|
2792
2672
|
if (error instanceof Error) {
|
|
2793
|
-
console.error(
|
|
2673
|
+
console.error(import_chalk17.default.red(`
|
|
2794
2674
|
\u2717 ${error.message}
|
|
2795
2675
|
`));
|
|
2796
2676
|
}
|
|
2797
2677
|
process.exit(1);
|
|
2798
2678
|
}
|
|
2799
2679
|
});
|
|
2800
|
-
if (process.env.ENABLE_DEV_SYNC_COMMAND === "true") {
|
|
2801
|
-
program.command("dev-sync <workspace-name>").description("[Dev] Sync local engine to workspace VM").action(async (workspaceName) => {
|
|
2802
|
-
try {
|
|
2803
|
-
await devSyncCommand(workspaceName);
|
|
2804
|
-
} catch (error) {
|
|
2805
|
-
if (error instanceof Error) {
|
|
2806
|
-
console.error(import_chalk18.default.red(`
|
|
2807
|
-
\u2717 ${error.message}
|
|
2808
|
-
`));
|
|
2809
|
-
}
|
|
2810
|
-
process.exit(1);
|
|
2811
|
-
}
|
|
2812
|
-
});
|
|
2813
|
-
}
|
|
2814
2680
|
var config = program.command("config").description("Manage CLI configuration");
|
|
2815
2681
|
config.command("get <key>").description("Get a configuration value").action(async (key) => {
|
|
2816
2682
|
try {
|
|
2817
2683
|
await configGetCommand(key);
|
|
2818
2684
|
} catch (error) {
|
|
2819
2685
|
if (error instanceof Error) {
|
|
2820
|
-
console.error(
|
|
2686
|
+
console.error(import_chalk17.default.red(`
|
|
2821
2687
|
\u2717 ${error.message}
|
|
2822
2688
|
`));
|
|
2823
2689
|
}
|
|
@@ -2829,7 +2695,7 @@ config.command("set <key> <value>").description("Set a configuration value").act
|
|
|
2829
2695
|
await configSetCommand(key, value);
|
|
2830
2696
|
} catch (error) {
|
|
2831
2697
|
if (error instanceof Error) {
|
|
2832
|
-
console.error(
|
|
2698
|
+
console.error(import_chalk17.default.red(`
|
|
2833
2699
|
\u2717 ${error.message}
|
|
2834
2700
|
`));
|
|
2835
2701
|
}
|
|
@@ -2841,7 +2707,7 @@ config.command("list").description("List all configuration values").action(async
|
|
|
2841
2707
|
await configListCommand();
|
|
2842
2708
|
} catch (error) {
|
|
2843
2709
|
if (error instanceof Error) {
|
|
2844
|
-
console.error(
|
|
2710
|
+
console.error(import_chalk17.default.red(`
|
|
2845
2711
|
\u2717 ${error.message}
|
|
2846
2712
|
`));
|
|
2847
2713
|
}
|
|
@@ -2853,7 +2719,7 @@ program.command("list").description("List all replicas").option("-p, --page <pag
|
|
|
2853
2719
|
await replicaListCommand(options);
|
|
2854
2720
|
} catch (error) {
|
|
2855
2721
|
if (error instanceof Error) {
|
|
2856
|
-
console.error(
|
|
2722
|
+
console.error(import_chalk17.default.red(`
|
|
2857
2723
|
\u2717 ${error.message}
|
|
2858
2724
|
`));
|
|
2859
2725
|
}
|
|
@@ -2865,19 +2731,19 @@ program.command("get <id>").description("Get replica details by ID").action(asyn
|
|
|
2865
2731
|
await replicaGetCommand(id);
|
|
2866
2732
|
} catch (error) {
|
|
2867
2733
|
if (error instanceof Error) {
|
|
2868
|
-
console.error(
|
|
2734
|
+
console.error(import_chalk17.default.red(`
|
|
2869
2735
|
\u2717 ${error.message}
|
|
2870
2736
|
`));
|
|
2871
2737
|
}
|
|
2872
2738
|
process.exit(1);
|
|
2873
2739
|
}
|
|
2874
2740
|
});
|
|
2875
|
-
program.command("create [name]").description("Create a new replica").option("-m, --message <message>", "Initial message for the replica").option("-r, --
|
|
2741
|
+
program.command("create [name]").description("Create a new replica").option("-m, --message <message>", "Initial message for the replica").option("-r, --repositories <repositories>", "Comma-separated repository names").option("-a, --agent <agent>", "Coding agent (claude, codex)").action(async (name, options) => {
|
|
2876
2742
|
try {
|
|
2877
2743
|
await replicaCreateCommand(name, options);
|
|
2878
2744
|
} catch (error) {
|
|
2879
2745
|
if (error instanceof Error) {
|
|
2880
|
-
console.error(
|
|
2746
|
+
console.error(import_chalk17.default.red(`
|
|
2881
2747
|
\u2717 ${error.message}
|
|
2882
2748
|
`));
|
|
2883
2749
|
}
|
|
@@ -2889,7 +2755,7 @@ program.command("send <id>").description("Send a message to a replica").option("
|
|
|
2889
2755
|
await replicaSendCommand(id, options);
|
|
2890
2756
|
} catch (error) {
|
|
2891
2757
|
if (error instanceof Error) {
|
|
2892
|
-
console.error(
|
|
2758
|
+
console.error(import_chalk17.default.red(`
|
|
2893
2759
|
\u2717 ${error.message}
|
|
2894
2760
|
`));
|
|
2895
2761
|
}
|
|
@@ -2901,7 +2767,7 @@ program.command("delete <id>").description("Delete a replica").option("-f, --for
|
|
|
2901
2767
|
await replicaDeleteCommand(id, options);
|
|
2902
2768
|
} catch (error) {
|
|
2903
2769
|
if (error instanceof Error) {
|
|
2904
|
-
console.error(
|
|
2770
|
+
console.error(import_chalk17.default.red(`
|
|
2905
2771
|
\u2717 ${error.message}
|
|
2906
2772
|
`));
|
|
2907
2773
|
}
|
|
@@ -2913,7 +2779,7 @@ program.command("read <id>").description("Read conversation history of a replica
|
|
|
2913
2779
|
await replicaReadCommand(id, options);
|
|
2914
2780
|
} catch (error) {
|
|
2915
2781
|
if (error instanceof Error) {
|
|
2916
|
-
console.error(
|
|
2782
|
+
console.error(import_chalk17.default.red(`
|
|
2917
2783
|
\u2717 ${error.message}
|
|
2918
2784
|
`));
|
|
2919
2785
|
}
|
|
@@ -2926,7 +2792,7 @@ repos.command("list").description("List all repositories").action(async () => {
|
|
|
2926
2792
|
await repositoriesListCommand();
|
|
2927
2793
|
} catch (error) {
|
|
2928
2794
|
if (error instanceof Error) {
|
|
2929
|
-
console.error(
|
|
2795
|
+
console.error(import_chalk17.default.red(`
|
|
2930
2796
|
\u2717 ${error.message}
|
|
2931
2797
|
`));
|
|
2932
2798
|
}
|
|
@@ -2938,7 +2804,7 @@ repos.action(async () => {
|
|
|
2938
2804
|
await repositoriesListCommand();
|
|
2939
2805
|
} catch (error) {
|
|
2940
2806
|
if (error instanceof Error) {
|
|
2941
|
-
console.error(
|
|
2807
|
+
console.error(import_chalk17.default.red(`
|
|
2942
2808
|
\u2717 ${error.message}
|
|
2943
2809
|
`));
|
|
2944
2810
|
}
|