replicas-cli 0.2.135 → 0.2.137
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.mjs
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
MEDIA_KINDS,
|
|
6
6
|
REPLICAS_CONFIG_FILENAMES,
|
|
7
7
|
SANDBOX_PATHS,
|
|
8
|
+
canCallOrgApi,
|
|
8
9
|
deleteConfig,
|
|
9
10
|
getCurrentUser,
|
|
10
11
|
getIdeCommand,
|
|
@@ -19,13 +20,13 @@ import {
|
|
|
19
20
|
setIdeCommand,
|
|
20
21
|
setOrganizationId,
|
|
21
22
|
writeConfig
|
|
22
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-IJZUILJP.mjs";
|
|
23
24
|
import "./chunk-FFDYI4OH.mjs";
|
|
24
25
|
|
|
25
26
|
// src/index.ts
|
|
26
27
|
import "dotenv/config";
|
|
27
28
|
import { Command } from "commander";
|
|
28
|
-
import
|
|
29
|
+
import chalk21 from "chalk";
|
|
29
30
|
|
|
30
31
|
// src/commands/login.ts
|
|
31
32
|
import http from "http";
|
|
@@ -34,29 +35,16 @@ import open from "open";
|
|
|
34
35
|
import chalk from "chalk";
|
|
35
36
|
|
|
36
37
|
// src/lib/api.ts
|
|
37
|
-
var MONOLITH_URL = process.env.REPLICAS_MONOLITH_URL || "https://api.
|
|
38
|
+
var MONOLITH_URL = process.env.REPLICAS_MONOLITH_URL || "https://api.tryreplicas.com";
|
|
38
39
|
async function authenticatedFetch(url, options) {
|
|
39
40
|
const token = await getValidToken();
|
|
40
41
|
if (!token) {
|
|
41
42
|
throw new Error("No access token available");
|
|
42
43
|
}
|
|
43
|
-
|
|
44
|
+
return apiFetch(url, {
|
|
44
45
|
"Authorization": `Bearer ${token}`,
|
|
45
|
-
"Content-Type": "application/json",
|
|
46
46
|
...options?.headers || {}
|
|
47
|
-
};
|
|
48
|
-
const absoluteUrl = `${MONOLITH_URL}${url}`;
|
|
49
|
-
const requestInit = {
|
|
50
|
-
...options,
|
|
51
|
-
headers,
|
|
52
|
-
body: options?.body !== void 0 ? JSON.stringify(options.body) : void 0
|
|
53
|
-
};
|
|
54
|
-
const response = await fetchWithRedirects(absoluteUrl, requestInit);
|
|
55
|
-
if (!response.ok) {
|
|
56
|
-
const error = await response.json().catch(() => ({ error: "Request failed" }));
|
|
57
|
-
throw new Error(error.error || `Request failed with status ${response.status}`);
|
|
58
|
-
}
|
|
59
|
-
return response.json();
|
|
47
|
+
}, options);
|
|
60
48
|
}
|
|
61
49
|
var REDIRECT_STATUSES = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
|
|
62
50
|
var MAX_REDIRECTS = 5;
|
|
@@ -82,23 +70,40 @@ async function fetchWithRedirects(url, init, attempt = 0) {
|
|
|
82
70
|
return response;
|
|
83
71
|
}
|
|
84
72
|
async function orgAuthenticatedFetch(url, options) {
|
|
85
|
-
|
|
86
|
-
const
|
|
87
|
-
if (
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
73
|
+
let bearer;
|
|
74
|
+
const extraHeaders = {};
|
|
75
|
+
if (isAgentMode()) {
|
|
76
|
+
const agent = readAgentConfig();
|
|
77
|
+
if (!agent) {
|
|
78
|
+
throw new Error("Agent mode config is incomplete");
|
|
79
|
+
}
|
|
80
|
+
bearer = agent.engine_secret;
|
|
81
|
+
extraHeaders["X-Workspace-Id"] = agent.workspace_id;
|
|
82
|
+
} else {
|
|
83
|
+
bearer = await getValidToken();
|
|
84
|
+
const organizationId = getOrganizationId();
|
|
85
|
+
if (!organizationId) {
|
|
86
|
+
throw new Error(
|
|
87
|
+
'No organization selected. Please run "replicas org switch" to select an organization.'
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
extraHeaders["Replicas-Org-Id"] = organizationId;
|
|
91
91
|
}
|
|
92
|
-
|
|
93
|
-
"Authorization": `Bearer ${
|
|
94
|
-
|
|
95
|
-
"Replicas-Org-Id": organizationId,
|
|
92
|
+
return apiFetch(url, {
|
|
93
|
+
"Authorization": `Bearer ${bearer}`,
|
|
94
|
+
...extraHeaders,
|
|
96
95
|
...options?.headers || {}
|
|
96
|
+
}, options);
|
|
97
|
+
}
|
|
98
|
+
async function apiFetch(url, headers, options) {
|
|
99
|
+
const requestHeaders = {
|
|
100
|
+
"Content-Type": "application/json",
|
|
101
|
+
...headers
|
|
97
102
|
};
|
|
98
103
|
const absoluteUrl = `${MONOLITH_URL}${url}`;
|
|
99
104
|
const requestInit = {
|
|
100
105
|
...options,
|
|
101
|
-
headers,
|
|
106
|
+
headers: requestHeaders,
|
|
102
107
|
body: options?.body !== void 0 ? JSON.stringify(options.body) : void 0
|
|
103
108
|
};
|
|
104
109
|
const response = await fetchWithRedirects(absoluteUrl, requestInit);
|
|
@@ -135,7 +140,7 @@ async function ensureOrganization() {
|
|
|
135
140
|
}
|
|
136
141
|
|
|
137
142
|
// src/commands/login.ts
|
|
138
|
-
var WEB_APP_URL = process.env.REPLICAS_WEB_URL || "https://
|
|
143
|
+
var WEB_APP_URL = process.env.REPLICAS_WEB_URL || "https://tryreplicas.com";
|
|
139
144
|
function generateState() {
|
|
140
145
|
return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
|
|
141
146
|
}
|
|
@@ -339,6 +344,20 @@ function logoutCommand() {
|
|
|
339
344
|
// src/commands/whoami.ts
|
|
340
345
|
import chalk3 from "chalk";
|
|
341
346
|
async function whoamiCommand() {
|
|
347
|
+
if (isAgentMode()) {
|
|
348
|
+
const agent = readAgentConfig();
|
|
349
|
+
if (!agent) {
|
|
350
|
+
console.log(chalk3.red("Agent mode config is incomplete."));
|
|
351
|
+
process.exit(1);
|
|
352
|
+
}
|
|
353
|
+
console.log(chalk3.blue("\nWorkspace identity:"));
|
|
354
|
+
console.log(chalk3.gray(` Workspace ID: ${agent.workspace_id}`));
|
|
355
|
+
if (agent.organization_id) {
|
|
356
|
+
console.log(chalk3.gray(` Organization ID: ${agent.organization_id}`));
|
|
357
|
+
}
|
|
358
|
+
console.log();
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
342
361
|
if (!isAuthenticated()) {
|
|
343
362
|
console.log(chalk3.yellow("You are not logged in."));
|
|
344
363
|
console.log(chalk3.gray('Run "replicas login" to authenticate.'));
|
|
@@ -453,7 +472,7 @@ Found ${response.workspaces.length} workspaces matching "${workspaceName}":`));
|
|
|
453
472
|
console.log(chalk4.gray(` Status: ${selectedWorkspace.status || "unknown"}`));
|
|
454
473
|
if (selectedWorkspace.status === "sleeping") {
|
|
455
474
|
throw new Error(
|
|
456
|
-
"Workspace is currently sleeping. Wake it using `replicas app` (press w on a sleeping workspace) or visit https://
|
|
475
|
+
"Workspace is currently sleeping. Wake it using `replicas app` (press w on a sleeping workspace) or visit https://tryreplicas.com"
|
|
457
476
|
);
|
|
458
477
|
}
|
|
459
478
|
console.log(chalk4.blue("\nRequesting SSH access token..."));
|
|
@@ -808,7 +827,7 @@ var AUTHORIZATION_ENDPOINT = "https://auth.openai.com/oauth/authorize";
|
|
|
808
827
|
var TOKEN_ENDPOINT = "https://auth.openai.com/oauth/token";
|
|
809
828
|
var CALLBACK_PORT = 1455;
|
|
810
829
|
var CALLBACK_PATH = "/auth/callback";
|
|
811
|
-
var WEB_APP_URL2 = process.env.REPLICAS_WEB_URL || "https://
|
|
830
|
+
var WEB_APP_URL2 = process.env.REPLICAS_WEB_URL || "https://tryreplicas.com";
|
|
812
831
|
function buildAuthorizationUrl(codeChallenge, state) {
|
|
813
832
|
const redirectUri = `http://localhost:${CALLBACK_PORT}${CALLBACK_PATH}`;
|
|
814
833
|
const params = new URLSearchParams({
|
|
@@ -1171,7 +1190,7 @@ function getDefaultConfig() {
|
|
|
1171
1190
|
}
|
|
1172
1191
|
function getDefaultYamlContent() {
|
|
1173
1192
|
return `# Replicas workspace configuration
|
|
1174
|
-
# See: https://docs.
|
|
1193
|
+
# See: https://docs.tryreplicas.com/features/workspaces/repository-configuration
|
|
1175
1194
|
|
|
1176
1195
|
systemPrompt: |
|
|
1177
1196
|
Add custom instructions for coding agents here.
|
|
@@ -1241,7 +1260,7 @@ function initCommand(options) {
|
|
|
1241
1260
|
|
|
1242
1261
|
// src/lib/version-check.ts
|
|
1243
1262
|
import chalk13 from "chalk";
|
|
1244
|
-
var MONOLITH_URL2 = process.env.REPLICAS_MONOLITH_URL || "https://api.
|
|
1263
|
+
var MONOLITH_URL2 = process.env.REPLICAS_MONOLITH_URL || "https://api.tryreplicas.com";
|
|
1245
1264
|
var VERSION_CHECK_TIMEOUT = 2e3;
|
|
1246
1265
|
function compareVersions(v1, v2) {
|
|
1247
1266
|
const parts1 = v1.split(".").map(Number);
|
|
@@ -1268,7 +1287,7 @@ async function checkForUpdates(currentVersion) {
|
|
|
1268
1287
|
if (compareVersions(latestVersion, currentVersion) > 0) {
|
|
1269
1288
|
console.error(chalk13.yellow(`
|
|
1270
1289
|
Update available: ${currentVersion} \u2192 ${latestVersion}`));
|
|
1271
|
-
console.error(chalk13.cyan(`Run: curl -fsSL https://
|
|
1290
|
+
console.error(chalk13.cyan(`Run: curl -fsSL https://tryreplicas.com/install.sh | bash
|
|
1272
1291
|
`));
|
|
1273
1292
|
}
|
|
1274
1293
|
} catch {
|
|
@@ -1705,46 +1724,51 @@ Conversation History
|
|
|
1705
1724
|
}
|
|
1706
1725
|
|
|
1707
1726
|
// src/commands/repositories.ts
|
|
1727
|
+
import chalk16 from "chalk";
|
|
1728
|
+
|
|
1729
|
+
// src/lib/command-utils.ts
|
|
1708
1730
|
import chalk15 from "chalk";
|
|
1709
1731
|
function formatDate2(dateString) {
|
|
1710
1732
|
return new Date(dateString).toLocaleString();
|
|
1711
1733
|
}
|
|
1712
|
-
|
|
1713
|
-
if (!
|
|
1734
|
+
function ensureOrgApiAuthenticated() {
|
|
1735
|
+
if (!canCallOrgApi()) {
|
|
1714
1736
|
console.log(chalk15.red('Not logged in. Please run "replicas login" first.'));
|
|
1715
1737
|
process.exit(1);
|
|
1716
1738
|
}
|
|
1739
|
+
}
|
|
1740
|
+
|
|
1741
|
+
// src/commands/repositories.ts
|
|
1742
|
+
async function repositoriesListCommand() {
|
|
1743
|
+
ensureOrgApiAuthenticated();
|
|
1717
1744
|
try {
|
|
1718
1745
|
const response = await orgAuthenticatedFetch("/v1/repositories");
|
|
1719
1746
|
if (response.repositories.length === 0) {
|
|
1720
|
-
console.log(
|
|
1747
|
+
console.log(chalk16.yellow("\nNo repositories found.\n"));
|
|
1721
1748
|
return;
|
|
1722
1749
|
}
|
|
1723
|
-
console.log(
|
|
1750
|
+
console.log(chalk16.green(`
|
|
1724
1751
|
Repositories (${response.repositories.length}):
|
|
1725
1752
|
`));
|
|
1726
1753
|
for (const repo of response.repositories) {
|
|
1727
|
-
console.log(
|
|
1728
|
-
console.log(
|
|
1729
|
-
console.log(
|
|
1730
|
-
console.log(
|
|
1754
|
+
console.log(chalk16.white(` ${repo.name}`));
|
|
1755
|
+
console.log(chalk16.gray(` URL: ${repo.url}`));
|
|
1756
|
+
console.log(chalk16.gray(` Default Branch: ${repo.default_branch}`));
|
|
1757
|
+
console.log(chalk16.gray(` Created: ${formatDate2(repo.created_at)}`));
|
|
1731
1758
|
if (repo.github_repository_id) {
|
|
1732
|
-
console.log(
|
|
1759
|
+
console.log(chalk16.gray(` GitHub ID: ${repo.github_repository_id}`));
|
|
1733
1760
|
}
|
|
1734
1761
|
console.log();
|
|
1735
1762
|
}
|
|
1736
1763
|
} catch (error) {
|
|
1737
|
-
console.error(
|
|
1764
|
+
console.error(chalk16.red(`Error: ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
1738
1765
|
process.exit(1);
|
|
1739
1766
|
}
|
|
1740
1767
|
}
|
|
1741
1768
|
|
|
1742
1769
|
// src/commands/automation.ts
|
|
1743
|
-
import
|
|
1770
|
+
import chalk17 from "chalk";
|
|
1744
1771
|
import prompts4 from "prompts";
|
|
1745
|
-
function formatDate3(dateString) {
|
|
1746
|
-
return new Date(dateString).toLocaleString();
|
|
1747
|
-
}
|
|
1748
1772
|
function formatTrigger(trigger) {
|
|
1749
1773
|
if (trigger.type === "cron") {
|
|
1750
1774
|
const config2 = trigger.config;
|
|
@@ -1765,43 +1789,37 @@ function truncate2(text, maxLength) {
|
|
|
1765
1789
|
function resolveSelectableEnvironmentId(envInput, selectableEnvs) {
|
|
1766
1790
|
const env = selectableEnvs.find((e) => e.name === envInput || e.id === envInput);
|
|
1767
1791
|
if (!env) {
|
|
1768
|
-
console.log(
|
|
1792
|
+
console.log(chalk17.red(`Environment not found: ${envInput}`));
|
|
1769
1793
|
const available = selectableEnvs.map((e) => e.name).join(", ");
|
|
1770
|
-
console.log(
|
|
1794
|
+
console.log(chalk17.gray(`Available: ${available || "(none)"}`));
|
|
1771
1795
|
process.exit(1);
|
|
1772
1796
|
}
|
|
1773
1797
|
return env.id;
|
|
1774
1798
|
}
|
|
1775
1799
|
function printAutomation(automation2) {
|
|
1776
|
-
console.log(
|
|
1777
|
-
console.log(
|
|
1800
|
+
console.log(chalk17.white(` ${automation2.name}`));
|
|
1801
|
+
console.log(chalk17.gray(` ID: ${automation2.id}`));
|
|
1778
1802
|
if (automation2.description) {
|
|
1779
|
-
console.log(
|
|
1803
|
+
console.log(chalk17.gray(` Description: ${automation2.description}`));
|
|
1780
1804
|
}
|
|
1781
|
-
console.log(
|
|
1805
|
+
console.log(chalk17.gray(` Enabled: ${automation2.enabled ? chalk17.green("yes") : chalk17.red("no")}`));
|
|
1782
1806
|
if (automation2.triggers.length > 0) {
|
|
1783
|
-
console.log(
|
|
1807
|
+
console.log(chalk17.gray(` Triggers: ${automation2.triggers.map(formatTrigger).join(", ")}`));
|
|
1784
1808
|
}
|
|
1785
|
-
console.log(
|
|
1809
|
+
console.log(chalk17.gray(` Prompt: ${truncate2(automation2.prompt, 80)}`));
|
|
1786
1810
|
if (automation2.cron_next_fire_at) {
|
|
1787
|
-
console.log(
|
|
1811
|
+
console.log(chalk17.gray(` Next Run: ${formatDate2(automation2.cron_next_fire_at)}`));
|
|
1788
1812
|
}
|
|
1789
1813
|
if (automation2.workspace_lifecycle_policy && automation2.workspace_lifecycle_policy !== "default") {
|
|
1790
1814
|
const lifecycle = automation2.workspace_lifecycle_policy === "delete_after_inactivity" ? `delete_after_inactivity (${automation2.workspace_auto_stop_minutes ?? 30}m)` : automation2.workspace_lifecycle_policy;
|
|
1791
|
-
console.log(
|
|
1815
|
+
console.log(chalk17.gray(` Lifecycle: ${lifecycle}`));
|
|
1792
1816
|
}
|
|
1793
|
-
console.log(
|
|
1794
|
-
console.log(
|
|
1817
|
+
console.log(chalk17.gray(` Created: ${formatDate2(automation2.created_at)}`));
|
|
1818
|
+
console.log(chalk17.gray(` Updated: ${formatDate2(automation2.updated_at)}`));
|
|
1795
1819
|
console.log();
|
|
1796
1820
|
}
|
|
1797
|
-
function ensureAuthenticated() {
|
|
1798
|
-
if (!isAuthenticated()) {
|
|
1799
|
-
console.log(chalk16.red('Not logged in. Please run "replicas login" first.'));
|
|
1800
|
-
process.exit(1);
|
|
1801
|
-
}
|
|
1802
|
-
}
|
|
1803
1821
|
async function automationListCommand(options) {
|
|
1804
|
-
|
|
1822
|
+
ensureOrgApiAuthenticated();
|
|
1805
1823
|
try {
|
|
1806
1824
|
const params = new URLSearchParams();
|
|
1807
1825
|
if (options.page) params.set("page", options.page);
|
|
@@ -1811,61 +1829,61 @@ async function automationListCommand(options) {
|
|
|
1811
1829
|
`/v1/automations${query ? "?" + query : ""}`
|
|
1812
1830
|
);
|
|
1813
1831
|
if (response.automations.length === 0) {
|
|
1814
|
-
console.log(
|
|
1832
|
+
console.log(chalk17.yellow("\nNo automations found.\n"));
|
|
1815
1833
|
return;
|
|
1816
1834
|
}
|
|
1817
|
-
console.log(
|
|
1835
|
+
console.log(chalk17.green(`
|
|
1818
1836
|
Automations (Page ${response.page} of ${response.totalPages}, Total: ${response.total}):
|
|
1819
1837
|
`));
|
|
1820
1838
|
for (const automation2 of response.automations) {
|
|
1821
1839
|
printAutomation(automation2);
|
|
1822
1840
|
}
|
|
1823
1841
|
} catch (error) {
|
|
1824
|
-
console.error(
|
|
1842
|
+
console.error(chalk17.red(`Error: ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
1825
1843
|
process.exit(1);
|
|
1826
1844
|
}
|
|
1827
1845
|
}
|
|
1828
1846
|
async function automationGetCommand(id) {
|
|
1829
|
-
|
|
1847
|
+
ensureOrgApiAuthenticated();
|
|
1830
1848
|
try {
|
|
1831
1849
|
const response = await orgAuthenticatedFetch(`/v1/automations/${id}`);
|
|
1832
1850
|
const automation2 = response.automation;
|
|
1833
|
-
console.log(
|
|
1851
|
+
console.log(chalk17.green(`
|
|
1834
1852
|
Automation: ${automation2.name}
|
|
1835
1853
|
`));
|
|
1836
|
-
console.log(
|
|
1854
|
+
console.log(chalk17.gray(` ID: ${automation2.id}`));
|
|
1837
1855
|
if (automation2.description) {
|
|
1838
|
-
console.log(
|
|
1856
|
+
console.log(chalk17.gray(` Description: ${automation2.description}`));
|
|
1839
1857
|
}
|
|
1840
|
-
console.log(
|
|
1858
|
+
console.log(chalk17.gray(` Enabled: ${automation2.enabled ? chalk17.green("yes") : chalk17.red("no")}`));
|
|
1841
1859
|
if (automation2.triggers.length > 0) {
|
|
1842
|
-
console.log(
|
|
1860
|
+
console.log(chalk17.gray(` Triggers:`));
|
|
1843
1861
|
for (const trigger of automation2.triggers) {
|
|
1844
|
-
console.log(
|
|
1862
|
+
console.log(chalk17.gray(` - ${formatTrigger(trigger)}`));
|
|
1845
1863
|
}
|
|
1846
1864
|
}
|
|
1847
|
-
console.log(
|
|
1848
|
-
console.log(
|
|
1865
|
+
console.log(chalk17.gray(` Prompt: ${automation2.prompt}`));
|
|
1866
|
+
console.log(chalk17.gray(` Environment: ${automation2.environment_id}`));
|
|
1849
1867
|
if (automation2.cron_expression) {
|
|
1850
|
-
console.log(
|
|
1868
|
+
console.log(chalk17.gray(` Cron: ${automation2.cron_expression}`));
|
|
1851
1869
|
}
|
|
1852
1870
|
if (automation2.cron_timezone) {
|
|
1853
|
-
console.log(
|
|
1871
|
+
console.log(chalk17.gray(` Timezone: ${automation2.cron_timezone}`));
|
|
1854
1872
|
}
|
|
1855
1873
|
if (automation2.cron_next_fire_at) {
|
|
1856
|
-
console.log(
|
|
1874
|
+
console.log(chalk17.gray(` Next Run: ${formatDate2(automation2.cron_next_fire_at)}`));
|
|
1857
1875
|
}
|
|
1858
1876
|
if (automation2.workspace_lifecycle_policy) {
|
|
1859
|
-
console.log(
|
|
1877
|
+
console.log(chalk17.gray(` Lifecycle Policy: ${automation2.workspace_lifecycle_policy}`));
|
|
1860
1878
|
}
|
|
1861
1879
|
if (automation2.workspace_auto_stop_minutes) {
|
|
1862
|
-
console.log(
|
|
1880
|
+
console.log(chalk17.gray(` Auto-stop: ${automation2.workspace_auto_stop_minutes} minutes`));
|
|
1863
1881
|
}
|
|
1864
|
-
console.log(
|
|
1865
|
-
console.log(
|
|
1882
|
+
console.log(chalk17.gray(` Created: ${formatDate2(automation2.created_at)}`));
|
|
1883
|
+
console.log(chalk17.gray(` Updated: ${formatDate2(automation2.updated_at)}`));
|
|
1866
1884
|
console.log();
|
|
1867
1885
|
} catch (error) {
|
|
1868
|
-
console.error(
|
|
1886
|
+
console.error(chalk17.red(`Error: ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
1869
1887
|
process.exit(1);
|
|
1870
1888
|
}
|
|
1871
1889
|
}
|
|
@@ -1943,21 +1961,21 @@ async function promptForTriggers(repositories) {
|
|
|
1943
1961
|
return triggers;
|
|
1944
1962
|
}
|
|
1945
1963
|
async function automationCreateCommand(name, options) {
|
|
1946
|
-
|
|
1964
|
+
ensureOrgApiAuthenticated();
|
|
1947
1965
|
const validLifecycles = ["default", "delete_when_done", "delete_after_inactivity"];
|
|
1948
1966
|
if (options.lifecycle && !validLifecycles.includes(options.lifecycle)) {
|
|
1949
|
-
console.log(
|
|
1950
|
-
console.log(
|
|
1967
|
+
console.log(chalk17.red(`Invalid lifecycle policy: ${options.lifecycle}`));
|
|
1968
|
+
console.log(chalk17.gray(`Valid options: ${validLifecycles.join(", ")}`));
|
|
1951
1969
|
process.exit(1);
|
|
1952
1970
|
}
|
|
1953
1971
|
if (options.autoStopMinutes && options.lifecycle !== "delete_after_inactivity") {
|
|
1954
|
-
console.log(
|
|
1972
|
+
console.log(chalk17.red("--auto-stop-minutes requires --lifecycle delete_after_inactivity"));
|
|
1955
1973
|
process.exit(1);
|
|
1956
1974
|
}
|
|
1957
1975
|
if (options.autoStopMinutes) {
|
|
1958
1976
|
const minutes = parseInt(options.autoStopMinutes, 10);
|
|
1959
1977
|
if (isNaN(minutes) || minutes < 3 || minutes > 1440) {
|
|
1960
|
-
console.log(
|
|
1978
|
+
console.log(chalk17.red("--auto-stop-minutes must be between 3 and 1440"));
|
|
1961
1979
|
process.exit(1);
|
|
1962
1980
|
}
|
|
1963
1981
|
}
|
|
@@ -1966,7 +1984,7 @@ async function automationCreateCommand(name, options) {
|
|
|
1966
1984
|
const allEnvs = envResponse.environments;
|
|
1967
1985
|
const selectableEnvs = allEnvs.filter((env) => !env.is_global);
|
|
1968
1986
|
if (selectableEnvs.length === 0) {
|
|
1969
|
-
console.log(
|
|
1987
|
+
console.log(chalk17.red("No environments found. Please create an environment first."));
|
|
1970
1988
|
process.exit(1);
|
|
1971
1989
|
}
|
|
1972
1990
|
const repoResponse = await orgAuthenticatedFetch("/v1/repositories");
|
|
@@ -1980,7 +1998,7 @@ async function automationCreateCommand(name, options) {
|
|
|
1980
1998
|
validate: (value) => value.trim() ? true : "Name is required"
|
|
1981
1999
|
});
|
|
1982
2000
|
if (!response2.name) {
|
|
1983
|
-
console.log(
|
|
2001
|
+
console.log(chalk17.yellow("\nCancelled."));
|
|
1984
2002
|
return;
|
|
1985
2003
|
}
|
|
1986
2004
|
automationName = response2.name;
|
|
@@ -1994,7 +2012,7 @@ async function automationCreateCommand(name, options) {
|
|
|
1994
2012
|
validate: (value) => value.trim() ? true : "Prompt is required"
|
|
1995
2013
|
});
|
|
1996
2014
|
if (!response2.prompt) {
|
|
1997
|
-
console.log(
|
|
2015
|
+
console.log(chalk17.yellow("\nCancelled."));
|
|
1998
2016
|
return;
|
|
1999
2017
|
}
|
|
2000
2018
|
automationPrompt = response2.prompt;
|
|
@@ -2014,7 +2032,7 @@ async function automationCreateCommand(name, options) {
|
|
|
2014
2032
|
}))
|
|
2015
2033
|
});
|
|
2016
2034
|
if (!envResponse2.env) {
|
|
2017
|
-
console.log(
|
|
2035
|
+
console.log(chalk17.yellow("\nCancelled."));
|
|
2018
2036
|
return;
|
|
2019
2037
|
}
|
|
2020
2038
|
selectedEnvironmentId = envResponse2.env;
|
|
@@ -2037,8 +2055,8 @@ async function automationCreateCommand(name, options) {
|
|
|
2037
2055
|
for (const repoName of repoNames) {
|
|
2038
2056
|
const repo = repositories.find((r) => r.name === repoName);
|
|
2039
2057
|
if (!repo) {
|
|
2040
|
-
console.log(
|
|
2041
|
-
console.log(
|
|
2058
|
+
console.log(chalk17.red(`Repository not found for trigger filter: ${repoName}`));
|
|
2059
|
+
console.log(chalk17.gray(`Available: ${repositories.map((r) => r.name).join(", ")}`));
|
|
2042
2060
|
process.exit(1);
|
|
2043
2061
|
}
|
|
2044
2062
|
githubRepoIds.push(repo.id);
|
|
@@ -2055,7 +2073,7 @@ async function automationCreateCommand(name, options) {
|
|
|
2055
2073
|
if (triggers.length === 0) {
|
|
2056
2074
|
triggers = await promptForTriggers(repositories.map((r) => ({ id: r.id, name: r.name })));
|
|
2057
2075
|
if (triggers.length === 0) {
|
|
2058
|
-
console.log(
|
|
2076
|
+
console.log(chalk17.red("At least one trigger is required."));
|
|
2059
2077
|
process.exit(1);
|
|
2060
2078
|
}
|
|
2061
2079
|
}
|
|
@@ -2068,44 +2086,44 @@ async function automationCreateCommand(name, options) {
|
|
|
2068
2086
|
...options.lifecycle ? { workspace_lifecycle_policy: options.lifecycle } : {},
|
|
2069
2087
|
...options.autoStopMinutes ? { workspace_auto_stop_minutes: parseInt(options.autoStopMinutes, 10) } : {}
|
|
2070
2088
|
};
|
|
2071
|
-
console.log(
|
|
2089
|
+
console.log(chalk17.gray("\nCreating automation..."));
|
|
2072
2090
|
const response = await orgAuthenticatedFetch("/v1/automations", {
|
|
2073
2091
|
method: "POST",
|
|
2074
2092
|
body
|
|
2075
2093
|
});
|
|
2076
2094
|
const automation2 = response.automation;
|
|
2077
|
-
console.log(
|
|
2095
|
+
console.log(chalk17.green(`
|
|
2078
2096
|
Created automation: ${automation2.name}`));
|
|
2079
|
-
console.log(
|
|
2080
|
-
console.log(
|
|
2097
|
+
console.log(chalk17.gray(` ID: ${automation2.id}`));
|
|
2098
|
+
console.log(chalk17.gray(` Enabled: ${automation2.enabled ? "yes" : "no"}`));
|
|
2081
2099
|
if (automation2.triggers.length > 0) {
|
|
2082
|
-
console.log(
|
|
2100
|
+
console.log(chalk17.gray(` Triggers: ${automation2.triggers.map(formatTrigger).join(", ")}`));
|
|
2083
2101
|
}
|
|
2084
2102
|
if (automation2.cron_next_fire_at) {
|
|
2085
|
-
console.log(
|
|
2103
|
+
console.log(chalk17.gray(` Next Run: ${formatDate2(automation2.cron_next_fire_at)}`));
|
|
2086
2104
|
}
|
|
2087
2105
|
console.log();
|
|
2088
2106
|
} catch (error) {
|
|
2089
|
-
console.error(
|
|
2107
|
+
console.error(chalk17.red(`Error: ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
2090
2108
|
process.exit(1);
|
|
2091
2109
|
}
|
|
2092
2110
|
}
|
|
2093
2111
|
async function automationEditCommand(id, options) {
|
|
2094
|
-
|
|
2112
|
+
ensureOrgApiAuthenticated();
|
|
2095
2113
|
const validLifecycles = ["default", "delete_when_done", "delete_after_inactivity"];
|
|
2096
2114
|
if (options.lifecycle && !validLifecycles.includes(options.lifecycle)) {
|
|
2097
|
-
console.log(
|
|
2098
|
-
console.log(
|
|
2115
|
+
console.log(chalk17.red(`Invalid lifecycle policy: ${options.lifecycle}`));
|
|
2116
|
+
console.log(chalk17.gray(`Valid options: ${validLifecycles.join(", ")}`));
|
|
2099
2117
|
process.exit(1);
|
|
2100
2118
|
}
|
|
2101
2119
|
if (options.autoStopMinutes && options.lifecycle !== "delete_after_inactivity") {
|
|
2102
|
-
console.log(
|
|
2120
|
+
console.log(chalk17.red("--auto-stop-minutes requires --lifecycle delete_after_inactivity"));
|
|
2103
2121
|
process.exit(1);
|
|
2104
2122
|
}
|
|
2105
2123
|
if (options.autoStopMinutes) {
|
|
2106
2124
|
const minutes = parseInt(options.autoStopMinutes, 10);
|
|
2107
2125
|
if (isNaN(minutes) || minutes < 3 || minutes > 1440) {
|
|
2108
|
-
console.log(
|
|
2126
|
+
console.log(chalk17.red("--auto-stop-minutes must be between 3 and 1440"));
|
|
2109
2127
|
process.exit(1);
|
|
2110
2128
|
}
|
|
2111
2129
|
}
|
|
@@ -2179,8 +2197,8 @@ async function automationEditCommand(id, options) {
|
|
|
2179
2197
|
for (const repoName of repoNames) {
|
|
2180
2198
|
const repo = repoResponse.repositories.find((r) => r.name === repoName);
|
|
2181
2199
|
if (!repo) {
|
|
2182
|
-
console.log(
|
|
2183
|
-
console.log(
|
|
2200
|
+
console.log(chalk17.red(`Repository not found for trigger filter: ${repoName}`));
|
|
2201
|
+
console.log(chalk17.gray(`Available: ${repoResponse.repositories.map((r) => r.name).join(", ")}`));
|
|
2184
2202
|
process.exit(1);
|
|
2185
2203
|
}
|
|
2186
2204
|
githubRepoIds.push(repo.id);
|
|
@@ -2212,41 +2230,41 @@ async function automationEditCommand(id, options) {
|
|
|
2212
2230
|
}
|
|
2213
2231
|
}
|
|
2214
2232
|
if (Object.keys(body).length === 0) {
|
|
2215
|
-
console.log(
|
|
2233
|
+
console.log(chalk17.yellow("\nNo changes made.\n"));
|
|
2216
2234
|
return;
|
|
2217
2235
|
}
|
|
2218
|
-
console.log(
|
|
2236
|
+
console.log(chalk17.gray("\nUpdating automation..."));
|
|
2219
2237
|
const response = await orgAuthenticatedFetch(`/v1/automations/${id}`, {
|
|
2220
2238
|
method: "PATCH",
|
|
2221
2239
|
body
|
|
2222
2240
|
});
|
|
2223
2241
|
const automation2 = response.automation;
|
|
2224
|
-
console.log(
|
|
2242
|
+
console.log(chalk17.green(`
|
|
2225
2243
|
Updated automation: ${automation2.name}`));
|
|
2226
|
-
console.log(
|
|
2227
|
-
console.log(
|
|
2244
|
+
console.log(chalk17.gray(` ID: ${automation2.id}`));
|
|
2245
|
+
console.log(chalk17.gray(` Enabled: ${automation2.enabled ? "yes" : "no"}`));
|
|
2228
2246
|
if (automation2.triggers.length > 0) {
|
|
2229
|
-
console.log(
|
|
2247
|
+
console.log(chalk17.gray(` Triggers: ${automation2.triggers.map(formatTrigger).join(", ")}`));
|
|
2230
2248
|
}
|
|
2231
2249
|
console.log();
|
|
2232
2250
|
} catch (error) {
|
|
2233
|
-
console.error(
|
|
2251
|
+
console.error(chalk17.red(`Error: ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
2234
2252
|
process.exit(1);
|
|
2235
2253
|
}
|
|
2236
2254
|
}
|
|
2237
2255
|
async function automationRunCommand(id) {
|
|
2238
|
-
|
|
2256
|
+
ensureOrgApiAuthenticated();
|
|
2239
2257
|
try {
|
|
2240
2258
|
const existing = await orgAuthenticatedFetch(`/v1/automations/${id}`);
|
|
2241
2259
|
const automation2 = existing.automation;
|
|
2242
2260
|
const hasCronTrigger = automation2.triggers.some((t) => t.type === "cron");
|
|
2243
2261
|
if (!hasCronTrigger) {
|
|
2244
|
-
console.log(
|
|
2245
|
-
console.log(
|
|
2262
|
+
console.log(chalk17.red("\nManual run is only allowed for automations with a cron trigger."));
|
|
2263
|
+
console.log(chalk17.gray(`This automation has triggers: ${automation2.triggers.map(formatTrigger).join(", ")}`));
|
|
2246
2264
|
console.log();
|
|
2247
2265
|
process.exit(1);
|
|
2248
2266
|
}
|
|
2249
|
-
console.log(
|
|
2267
|
+
console.log(chalk17.gray(`
|
|
2250
2268
|
Triggering automation "${automation2.name}"...`));
|
|
2251
2269
|
const response = await orgAuthenticatedFetch(
|
|
2252
2270
|
`/v1/automations/${id}/trigger`,
|
|
@@ -2256,25 +2274,25 @@ Triggering automation "${automation2.name}"...`));
|
|
|
2256
2274
|
}
|
|
2257
2275
|
);
|
|
2258
2276
|
if (!response.execution_id) {
|
|
2259
|
-
console.log(
|
|
2277
|
+
console.log(chalk17.red(`
|
|
2260
2278
|
Automation trigger returned no execution ID. The automation may not have started.`));
|
|
2261
2279
|
console.log();
|
|
2262
2280
|
process.exit(1);
|
|
2263
2281
|
}
|
|
2264
|
-
console.log(
|
|
2282
|
+
console.log(chalk17.green(`
|
|
2265
2283
|
Automation triggered successfully.`));
|
|
2266
|
-
console.log(
|
|
2284
|
+
console.log(chalk17.gray(` Execution ID: ${response.execution_id}`));
|
|
2267
2285
|
if (response.workspace_id) {
|
|
2268
|
-
console.log(
|
|
2286
|
+
console.log(chalk17.gray(` Workspace ID: ${response.workspace_id}`));
|
|
2269
2287
|
}
|
|
2270
2288
|
console.log();
|
|
2271
2289
|
} catch (error) {
|
|
2272
|
-
console.error(
|
|
2290
|
+
console.error(chalk17.red(`Error: ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
2273
2291
|
process.exit(1);
|
|
2274
2292
|
}
|
|
2275
2293
|
}
|
|
2276
2294
|
async function automationDeleteCommand(id, options) {
|
|
2277
|
-
|
|
2295
|
+
ensureOrgApiAuthenticated();
|
|
2278
2296
|
try {
|
|
2279
2297
|
const existing = await orgAuthenticatedFetch(`/v1/automations/${id}`);
|
|
2280
2298
|
const automationName = existing.automation.name;
|
|
@@ -2286,27 +2304,27 @@ async function automationDeleteCommand(id, options) {
|
|
|
2286
2304
|
initial: false
|
|
2287
2305
|
});
|
|
2288
2306
|
if (!response.confirm) {
|
|
2289
|
-
console.log(
|
|
2307
|
+
console.log(chalk17.yellow("\nCancelled."));
|
|
2290
2308
|
return;
|
|
2291
2309
|
}
|
|
2292
2310
|
}
|
|
2293
2311
|
await orgAuthenticatedFetch(`/v1/automations/${id}`, {
|
|
2294
2312
|
method: "DELETE"
|
|
2295
2313
|
});
|
|
2296
|
-
console.log(
|
|
2314
|
+
console.log(chalk17.green(`
|
|
2297
2315
|
Automation "${automationName}" (${id}) deleted.
|
|
2298
2316
|
`));
|
|
2299
2317
|
} catch (error) {
|
|
2300
|
-
console.error(
|
|
2318
|
+
console.error(chalk17.red(`Error: ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
2301
2319
|
process.exit(1);
|
|
2302
2320
|
}
|
|
2303
2321
|
}
|
|
2304
2322
|
|
|
2305
2323
|
// src/commands/preview.ts
|
|
2306
|
-
import
|
|
2324
|
+
import chalk18 from "chalk";
|
|
2307
2325
|
|
|
2308
2326
|
// src/lib/agent-api.ts
|
|
2309
|
-
var MONOLITH_URL3 = process.env.MONOLITH_URL || process.env.REPLICAS_MONOLITH_URL || "https://api.
|
|
2327
|
+
var MONOLITH_URL3 = process.env.MONOLITH_URL || process.env.REPLICAS_MONOLITH_URL || "https://api.tryreplicas.com";
|
|
2310
2328
|
var ENGINE_PORT = process.env.REPLICAS_ENGINE_PORT || "3737";
|
|
2311
2329
|
async function agentFetch(path5, options) {
|
|
2312
2330
|
const config2 = readAgentConfig();
|
|
@@ -2393,11 +2411,11 @@ async function previewListCommand(workspaceId) {
|
|
|
2393
2411
|
`/v1/workspaces/${workspaceId}/previews`
|
|
2394
2412
|
);
|
|
2395
2413
|
if (result.previews.length === 0) {
|
|
2396
|
-
console.log(
|
|
2414
|
+
console.log(chalk18.dim("No active previews"));
|
|
2397
2415
|
return;
|
|
2398
2416
|
}
|
|
2399
2417
|
for (const preview2 of result.previews) {
|
|
2400
|
-
console.log(` ${
|
|
2418
|
+
console.log(` ${chalk18.cyan(String(preview2.port))} \u2192 ${chalk18.underline(preview2.publicUrl)}`);
|
|
2401
2419
|
}
|
|
2402
2420
|
}
|
|
2403
2421
|
}
|
|
@@ -2410,7 +2428,7 @@ async function previewAddCommand(workspaceId, options) {
|
|
|
2410
2428
|
body: { port: portNum, authenticated: options.authenticated ?? false }
|
|
2411
2429
|
}
|
|
2412
2430
|
);
|
|
2413
|
-
console.log(
|
|
2431
|
+
console.log(chalk18.green(`Preview created: ${result.preview.publicUrl}`));
|
|
2414
2432
|
}
|
|
2415
2433
|
async function previewDeleteCommand(port) {
|
|
2416
2434
|
const portNum = parsePort(port);
|
|
@@ -2425,13 +2443,13 @@ async function previewRemoveCommand(workspaceId, options) {
|
|
|
2425
2443
|
`/v1/workspaces/${workspaceId}/previews/${portNum}`,
|
|
2426
2444
|
{ method: "DELETE" }
|
|
2427
2445
|
);
|
|
2428
|
-
console.log(
|
|
2446
|
+
console.log(chalk18.green(`Preview deleted on port ${portNum}`));
|
|
2429
2447
|
}
|
|
2430
2448
|
|
|
2431
2449
|
// src/commands/media.ts
|
|
2432
2450
|
import fs3 from "fs";
|
|
2433
2451
|
import path4 from "path";
|
|
2434
|
-
var MONOLITH_URL4 = process.env.MONOLITH_URL || process.env.REPLICAS_MONOLITH_URL || "https://api.
|
|
2452
|
+
var MONOLITH_URL4 = process.env.MONOLITH_URL || process.env.REPLICAS_MONOLITH_URL || "https://api.tryreplicas.com";
|
|
2435
2453
|
var EXT_INFO = {
|
|
2436
2454
|
png: { kind: MEDIA_KIND.IMAGE, contentType: "image/png" },
|
|
2437
2455
|
jpg: { kind: MEDIA_KIND.IMAGE, contentType: "image/jpeg" },
|
|
@@ -2522,7 +2540,7 @@ async function mediaListCommand(options) {
|
|
|
2522
2540
|
}
|
|
2523
2541
|
|
|
2524
2542
|
// src/commands/interactive.ts
|
|
2525
|
-
import
|
|
2543
|
+
import chalk19 from "chalk";
|
|
2526
2544
|
async function interactiveCommand() {
|
|
2527
2545
|
if (!isAuthenticated()) {
|
|
2528
2546
|
throw new Error(
|
|
@@ -2535,13 +2553,382 @@ async function interactiveCommand() {
|
|
|
2535
2553
|
'No organization selected. Please run "replicas org switch" to select an organization.'
|
|
2536
2554
|
);
|
|
2537
2555
|
}
|
|
2538
|
-
console.log(
|
|
2539
|
-
const { launchInteractive } = await import("./interactive-
|
|
2556
|
+
console.log(chalk19.gray("Starting interactive mode..."));
|
|
2557
|
+
const { launchInteractive } = await import("./interactive-6AXMMYQN.mjs");
|
|
2540
2558
|
await launchInteractive();
|
|
2541
2559
|
}
|
|
2542
2560
|
|
|
2561
|
+
// src/commands/environment.ts
|
|
2562
|
+
import fs4 from "fs";
|
|
2563
|
+
import chalk20 from "chalk";
|
|
2564
|
+
import prompts5 from "prompts";
|
|
2565
|
+
var UUID_RE = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
|
|
2566
|
+
function maskValue(value) {
|
|
2567
|
+
if (value.length <= 4) return "\u2022\u2022\u2022\u2022";
|
|
2568
|
+
return `${value.slice(0, 2)}${"\u2022".repeat(Math.min(value.length - 4, 12))}${value.slice(-2)} (${value.length} chars)`;
|
|
2569
|
+
}
|
|
2570
|
+
async function resolveEnvironmentId(input) {
|
|
2571
|
+
if (input === "global") return "global";
|
|
2572
|
+
if (UUID_RE.test(input)) return input;
|
|
2573
|
+
const response = await orgAuthenticatedFetch("/v1/environments");
|
|
2574
|
+
const env = response.environments.find((e) => e.name === input);
|
|
2575
|
+
if (!env) {
|
|
2576
|
+
console.log(chalk20.red(`Environment not found: ${input}`));
|
|
2577
|
+
const available = response.environments.map((e) => e.name).join(", ");
|
|
2578
|
+
console.log(chalk20.gray(`Available: ${available || "(none)"}`));
|
|
2579
|
+
process.exit(1);
|
|
2580
|
+
}
|
|
2581
|
+
return env.id;
|
|
2582
|
+
}
|
|
2583
|
+
function printEnvironment(env) {
|
|
2584
|
+
console.log(chalk20.white(` ${env.name}${env.is_global ? chalk20.gray(" (global)") : ""}`));
|
|
2585
|
+
console.log(chalk20.gray(` ID: ${env.id}`));
|
|
2586
|
+
if (env.description) {
|
|
2587
|
+
console.log(chalk20.gray(` Description: ${env.description}`));
|
|
2588
|
+
}
|
|
2589
|
+
if (env.repository_id) {
|
|
2590
|
+
console.log(chalk20.gray(` Repository: ${env.repository_id}`));
|
|
2591
|
+
} else if (env.repository_set_id) {
|
|
2592
|
+
console.log(chalk20.gray(` Repository Set: ${env.repository_set_id}`));
|
|
2593
|
+
}
|
|
2594
|
+
if (env.variable_count !== void 0) {
|
|
2595
|
+
console.log(chalk20.gray(` Variables: ${env.variable_count}, Files: ${env.file_count ?? 0}, Skills: ${env.skill_count ?? 0}, MCPs: ${env.mcp_count ?? 0}`));
|
|
2596
|
+
}
|
|
2597
|
+
console.log(chalk20.gray(` Updated: ${formatDate2(env.updated_at)}`));
|
|
2598
|
+
console.log();
|
|
2599
|
+
}
|
|
2600
|
+
async function environmentListCommand() {
|
|
2601
|
+
ensureOrgApiAuthenticated();
|
|
2602
|
+
const response = await orgAuthenticatedFetch("/v1/environments");
|
|
2603
|
+
if (response.environments.length === 0) {
|
|
2604
|
+
console.log(chalk20.yellow("\nNo environments found.\n"));
|
|
2605
|
+
return;
|
|
2606
|
+
}
|
|
2607
|
+
console.log(chalk20.green(`
|
|
2608
|
+
Environments (${response.environments.length}):
|
|
2609
|
+
`));
|
|
2610
|
+
for (const env of response.environments) {
|
|
2611
|
+
printEnvironment(env);
|
|
2612
|
+
}
|
|
2613
|
+
}
|
|
2614
|
+
async function environmentGetCommand(idOrName) {
|
|
2615
|
+
ensureOrgApiAuthenticated();
|
|
2616
|
+
const id = await resolveEnvironmentId(idOrName);
|
|
2617
|
+
const response = await orgAuthenticatedFetch(`/v1/environments/${id}`);
|
|
2618
|
+
console.log(chalk20.green(`
|
|
2619
|
+
Environment: ${response.environment.name}
|
|
2620
|
+
`));
|
|
2621
|
+
printEnvironment(response.environment);
|
|
2622
|
+
}
|
|
2623
|
+
async function environmentCreateCommand(name, options) {
|
|
2624
|
+
ensureOrgApiAuthenticated();
|
|
2625
|
+
let envName = name;
|
|
2626
|
+
if (!envName) {
|
|
2627
|
+
const r = await prompts5({
|
|
2628
|
+
type: "text",
|
|
2629
|
+
name: "name",
|
|
2630
|
+
message: "Environment name:",
|
|
2631
|
+
validate: (v) => v.trim() ? true : "Name is required"
|
|
2632
|
+
});
|
|
2633
|
+
if (!r.name) {
|
|
2634
|
+
console.log(chalk20.yellow("\nCancelled."));
|
|
2635
|
+
return;
|
|
2636
|
+
}
|
|
2637
|
+
envName = r.name;
|
|
2638
|
+
}
|
|
2639
|
+
let repositoryId = null;
|
|
2640
|
+
if (options.repository) {
|
|
2641
|
+
if (UUID_RE.test(options.repository)) {
|
|
2642
|
+
repositoryId = options.repository;
|
|
2643
|
+
} else {
|
|
2644
|
+
const repos2 = await orgAuthenticatedFetch("/v1/repositories");
|
|
2645
|
+
const repo = repos2.repositories.find((r) => r.name === options.repository);
|
|
2646
|
+
if (!repo) {
|
|
2647
|
+
console.log(chalk20.red(`Repository not found: ${options.repository}`));
|
|
2648
|
+
console.log(chalk20.gray(`Available: ${repos2.repositories.map((r) => r.name).join(", ")}`));
|
|
2649
|
+
process.exit(1);
|
|
2650
|
+
}
|
|
2651
|
+
repositoryId = repo.id;
|
|
2652
|
+
}
|
|
2653
|
+
} else {
|
|
2654
|
+
const repos2 = await orgAuthenticatedFetch("/v1/repositories");
|
|
2655
|
+
if (repos2.repositories.length > 0) {
|
|
2656
|
+
const r = await prompts5({
|
|
2657
|
+
type: "select",
|
|
2658
|
+
name: "repo",
|
|
2659
|
+
message: "Bind to repository (esc to skip):",
|
|
2660
|
+
choices: [
|
|
2661
|
+
...repos2.repositories.map((repo) => ({ title: repo.name, value: repo.id })),
|
|
2662
|
+
{ title: "(no binding)", value: "" }
|
|
2663
|
+
]
|
|
2664
|
+
});
|
|
2665
|
+
if (r.repo) repositoryId = r.repo;
|
|
2666
|
+
}
|
|
2667
|
+
}
|
|
2668
|
+
const body = {
|
|
2669
|
+
name: envName,
|
|
2670
|
+
description: options.description ?? null,
|
|
2671
|
+
repository_id: repositoryId,
|
|
2672
|
+
system_prompt: options.systemPrompt ?? null
|
|
2673
|
+
};
|
|
2674
|
+
const response = await orgAuthenticatedFetch("/v1/environments", {
|
|
2675
|
+
method: "POST",
|
|
2676
|
+
body
|
|
2677
|
+
});
|
|
2678
|
+
console.log(chalk20.green(`
|
|
2679
|
+
Created environment: ${response.environment.name}`));
|
|
2680
|
+
console.log(chalk20.gray(` ID: ${response.environment.id}
|
|
2681
|
+
`));
|
|
2682
|
+
}
|
|
2683
|
+
async function environmentEditCommand(idOrName, options) {
|
|
2684
|
+
ensureOrgApiAuthenticated();
|
|
2685
|
+
const id = await resolveEnvironmentId(idOrName);
|
|
2686
|
+
const body = {};
|
|
2687
|
+
if (options.name !== void 0) body.name = options.name;
|
|
2688
|
+
if (options.description !== void 0) body.description = options.description;
|
|
2689
|
+
if (options.systemPrompt !== void 0) body.system_prompt = options.systemPrompt;
|
|
2690
|
+
if (options.repository !== void 0) {
|
|
2691
|
+
if (options.repository === "" || options.repository === "null") {
|
|
2692
|
+
body.repository_id = null;
|
|
2693
|
+
} else if (UUID_RE.test(options.repository)) {
|
|
2694
|
+
body.repository_id = options.repository;
|
|
2695
|
+
} else {
|
|
2696
|
+
const repos2 = await orgAuthenticatedFetch("/v1/repositories");
|
|
2697
|
+
const repo = repos2.repositories.find((r) => r.name === options.repository);
|
|
2698
|
+
if (!repo) {
|
|
2699
|
+
console.log(chalk20.red(`Repository not found: ${options.repository}`));
|
|
2700
|
+
process.exit(1);
|
|
2701
|
+
}
|
|
2702
|
+
body.repository_id = repo.id;
|
|
2703
|
+
}
|
|
2704
|
+
}
|
|
2705
|
+
if (Object.keys(body).length === 0) {
|
|
2706
|
+
console.log(chalk20.yellow("\nNo changes specified. Pass --name, --description, --repository, or --system-prompt."));
|
|
2707
|
+
return;
|
|
2708
|
+
}
|
|
2709
|
+
const response = await orgAuthenticatedFetch(`/v1/environments/${id}`, {
|
|
2710
|
+
method: "PATCH",
|
|
2711
|
+
body
|
|
2712
|
+
});
|
|
2713
|
+
console.log(chalk20.green(`
|
|
2714
|
+
Updated environment: ${response.environment.name}
|
|
2715
|
+
`));
|
|
2716
|
+
}
|
|
2717
|
+
async function environmentDeleteCommand(idOrName, options) {
|
|
2718
|
+
ensureOrgApiAuthenticated();
|
|
2719
|
+
const id = await resolveEnvironmentId(idOrName);
|
|
2720
|
+
if (!options.force) {
|
|
2721
|
+
const r = await prompts5({
|
|
2722
|
+
type: "confirm",
|
|
2723
|
+
name: "confirm",
|
|
2724
|
+
message: `Delete environment ${idOrName}?`,
|
|
2725
|
+
initial: false
|
|
2726
|
+
});
|
|
2727
|
+
if (!r.confirm) {
|
|
2728
|
+
console.log(chalk20.yellow("\nCancelled."));
|
|
2729
|
+
return;
|
|
2730
|
+
}
|
|
2731
|
+
}
|
|
2732
|
+
await orgAuthenticatedFetch(`/v1/environments/${id}`, { method: "DELETE" });
|
|
2733
|
+
console.log(chalk20.green(`
|
|
2734
|
+
Deleted environment ${idOrName}.
|
|
2735
|
+
`));
|
|
2736
|
+
}
|
|
2737
|
+
function printVariable(v, reveal) {
|
|
2738
|
+
console.log(chalk20.white(` ${v.key}`));
|
|
2739
|
+
console.log(chalk20.gray(` ID: ${v.id}`));
|
|
2740
|
+
console.log(chalk20.gray(` Value: ${reveal ? v.value : maskValue(v.value)}`));
|
|
2741
|
+
console.log(chalk20.gray(` Updated: ${formatDate2(v.updated_at)}`));
|
|
2742
|
+
console.log();
|
|
2743
|
+
}
|
|
2744
|
+
async function envVarsListCommand(envIdOrName, options) {
|
|
2745
|
+
ensureOrgApiAuthenticated();
|
|
2746
|
+
const id = await resolveEnvironmentId(envIdOrName);
|
|
2747
|
+
const response = await orgAuthenticatedFetch(
|
|
2748
|
+
`/v1/environments/${id}/variables`
|
|
2749
|
+
);
|
|
2750
|
+
if (response.environment_variables.length === 0) {
|
|
2751
|
+
console.log(chalk20.yellow("\nNo variables.\n"));
|
|
2752
|
+
return;
|
|
2753
|
+
}
|
|
2754
|
+
console.log(chalk20.green(`
|
|
2755
|
+
Variables (${response.environment_variables.length}):
|
|
2756
|
+
`));
|
|
2757
|
+
if (!options.reveal) {
|
|
2758
|
+
console.log(chalk20.gray(" Values are masked. Pass --reveal to show full values.\n"));
|
|
2759
|
+
}
|
|
2760
|
+
for (const v of response.environment_variables) printVariable(v, !!options.reveal);
|
|
2761
|
+
}
|
|
2762
|
+
async function envVarsSetCommand(envIdOrName, key, value) {
|
|
2763
|
+
ensureOrgApiAuthenticated();
|
|
2764
|
+
const id = await resolveEnvironmentId(envIdOrName);
|
|
2765
|
+
const existing = await orgAuthenticatedFetch(
|
|
2766
|
+
`/v1/environments/${id}/variables`
|
|
2767
|
+
);
|
|
2768
|
+
const match = existing.environment_variables.find((v) => v.key === key);
|
|
2769
|
+
if (match) {
|
|
2770
|
+
const body2 = { value };
|
|
2771
|
+
const response2 = await orgAuthenticatedFetch(
|
|
2772
|
+
`/v1/environments/${id}/variables/${match.id}`,
|
|
2773
|
+
{ method: "PATCH", body: body2 }
|
|
2774
|
+
);
|
|
2775
|
+
console.log(chalk20.green(`
|
|
2776
|
+
Updated variable ${response2.environment_variable.key}.
|
|
2777
|
+
`));
|
|
2778
|
+
return;
|
|
2779
|
+
}
|
|
2780
|
+
const body = {
|
|
2781
|
+
environment_id: id,
|
|
2782
|
+
key,
|
|
2783
|
+
value
|
|
2784
|
+
};
|
|
2785
|
+
const response = await orgAuthenticatedFetch(
|
|
2786
|
+
`/v1/environments/${id}/variables`,
|
|
2787
|
+
{ method: "POST", body }
|
|
2788
|
+
);
|
|
2789
|
+
console.log(chalk20.green(`
|
|
2790
|
+
Created variable ${response.environment_variable.key}.
|
|
2791
|
+
`));
|
|
2792
|
+
}
|
|
2793
|
+
async function envVarsDeleteCommand(envIdOrName, keyOrId, options) {
|
|
2794
|
+
ensureOrgApiAuthenticated();
|
|
2795
|
+
const id = await resolveEnvironmentId(envIdOrName);
|
|
2796
|
+
let variableId = keyOrId;
|
|
2797
|
+
if (!UUID_RE.test(keyOrId)) {
|
|
2798
|
+
const existing = await orgAuthenticatedFetch(
|
|
2799
|
+
`/v1/environments/${id}/variables`
|
|
2800
|
+
);
|
|
2801
|
+
const match = existing.environment_variables.find((v) => v.key === keyOrId);
|
|
2802
|
+
if (!match) {
|
|
2803
|
+
console.log(chalk20.red(`Variable not found: ${keyOrId}`));
|
|
2804
|
+
process.exit(1);
|
|
2805
|
+
}
|
|
2806
|
+
variableId = match.id;
|
|
2807
|
+
}
|
|
2808
|
+
if (!options.force) {
|
|
2809
|
+
const r = await prompts5({
|
|
2810
|
+
type: "confirm",
|
|
2811
|
+
name: "confirm",
|
|
2812
|
+
message: `Delete variable ${keyOrId}?`,
|
|
2813
|
+
initial: false
|
|
2814
|
+
});
|
|
2815
|
+
if (!r.confirm) {
|
|
2816
|
+
console.log(chalk20.yellow("\nCancelled."));
|
|
2817
|
+
return;
|
|
2818
|
+
}
|
|
2819
|
+
}
|
|
2820
|
+
await orgAuthenticatedFetch(`/v1/environments/${id}/variables/${variableId}`, {
|
|
2821
|
+
method: "DELETE"
|
|
2822
|
+
});
|
|
2823
|
+
console.log(chalk20.green(`
|
|
2824
|
+
Deleted variable ${keyOrId}.
|
|
2825
|
+
`));
|
|
2826
|
+
}
|
|
2827
|
+
function printFile(f) {
|
|
2828
|
+
console.log(chalk20.white(` ${f.path}`));
|
|
2829
|
+
console.log(chalk20.gray(` ID: ${f.id}`));
|
|
2830
|
+
console.log(chalk20.gray(` Name: ${f.name}`));
|
|
2831
|
+
console.log(chalk20.gray(` Size: ${f.content.length} bytes`));
|
|
2832
|
+
console.log(chalk20.gray(` Updated: ${formatDate2(f.updated_at)}`));
|
|
2833
|
+
console.log();
|
|
2834
|
+
}
|
|
2835
|
+
async function envFilesListCommand(envIdOrName) {
|
|
2836
|
+
ensureOrgApiAuthenticated();
|
|
2837
|
+
const id = await resolveEnvironmentId(envIdOrName);
|
|
2838
|
+
const response = await orgAuthenticatedFetch(
|
|
2839
|
+
`/v1/environments/${id}/files`
|
|
2840
|
+
);
|
|
2841
|
+
if (response.environment_files.length === 0) {
|
|
2842
|
+
console.log(chalk20.yellow("\nNo files.\n"));
|
|
2843
|
+
return;
|
|
2844
|
+
}
|
|
2845
|
+
console.log(chalk20.green(`
|
|
2846
|
+
Files (${response.environment_files.length}):
|
|
2847
|
+
`));
|
|
2848
|
+
for (const f of response.environment_files) printFile(f);
|
|
2849
|
+
}
|
|
2850
|
+
function readFileContent(options) {
|
|
2851
|
+
if (options.file) {
|
|
2852
|
+
if (!fs4.existsSync(options.file)) {
|
|
2853
|
+
throw new Error(`Local file not found: ${options.file}`);
|
|
2854
|
+
}
|
|
2855
|
+
return fs4.readFileSync(options.file, "utf-8");
|
|
2856
|
+
}
|
|
2857
|
+
if (options.content !== void 0) return options.content;
|
|
2858
|
+
throw new Error('Pass either --content "..." or --file <local-path>');
|
|
2859
|
+
}
|
|
2860
|
+
async function envFilesSetCommand(envIdOrName, destinationPath, options) {
|
|
2861
|
+
ensureOrgApiAuthenticated();
|
|
2862
|
+
const id = await resolveEnvironmentId(envIdOrName);
|
|
2863
|
+
const content = readFileContent(options);
|
|
2864
|
+
const existing = await orgAuthenticatedFetch(
|
|
2865
|
+
`/v1/environments/${id}/files`
|
|
2866
|
+
);
|
|
2867
|
+
const match = existing.environment_files.find((f) => f.path === destinationPath);
|
|
2868
|
+
const fallbackName = destinationPath.split("/").pop() || destinationPath;
|
|
2869
|
+
const name = options.name ?? match?.name ?? fallbackName;
|
|
2870
|
+
if (match) {
|
|
2871
|
+
const body2 = { name, path: destinationPath, content };
|
|
2872
|
+
const response2 = await orgAuthenticatedFetch(
|
|
2873
|
+
`/v1/environments/${id}/files/${match.id}`,
|
|
2874
|
+
{ method: "PATCH", body: body2 }
|
|
2875
|
+
);
|
|
2876
|
+
console.log(chalk20.green(`
|
|
2877
|
+
Updated file ${response2.environment_file.path}.
|
|
2878
|
+
`));
|
|
2879
|
+
return;
|
|
2880
|
+
}
|
|
2881
|
+
const body = {
|
|
2882
|
+
environment_id: id,
|
|
2883
|
+
name,
|
|
2884
|
+
path: destinationPath,
|
|
2885
|
+
content
|
|
2886
|
+
};
|
|
2887
|
+
const response = await orgAuthenticatedFetch(
|
|
2888
|
+
`/v1/environments/${id}/files`,
|
|
2889
|
+
{ method: "POST", body }
|
|
2890
|
+
);
|
|
2891
|
+
console.log(chalk20.green(`
|
|
2892
|
+
Created file ${response.environment_file.path}.
|
|
2893
|
+
`));
|
|
2894
|
+
}
|
|
2895
|
+
async function envFilesDeleteCommand(envIdOrName, pathOrId, options) {
|
|
2896
|
+
ensureOrgApiAuthenticated();
|
|
2897
|
+
const id = await resolveEnvironmentId(envIdOrName);
|
|
2898
|
+
let fileId = pathOrId;
|
|
2899
|
+
if (!UUID_RE.test(pathOrId)) {
|
|
2900
|
+
const existing = await orgAuthenticatedFetch(
|
|
2901
|
+
`/v1/environments/${id}/files`
|
|
2902
|
+
);
|
|
2903
|
+
const match = existing.environment_files.find((f) => f.path === pathOrId);
|
|
2904
|
+
if (!match) {
|
|
2905
|
+
console.log(chalk20.red(`File not found: ${pathOrId}`));
|
|
2906
|
+
process.exit(1);
|
|
2907
|
+
}
|
|
2908
|
+
fileId = match.id;
|
|
2909
|
+
}
|
|
2910
|
+
if (!options.force) {
|
|
2911
|
+
const r = await prompts5({
|
|
2912
|
+
type: "confirm",
|
|
2913
|
+
name: "confirm",
|
|
2914
|
+
message: `Delete file ${pathOrId}?`,
|
|
2915
|
+
initial: false
|
|
2916
|
+
});
|
|
2917
|
+
if (!r.confirm) {
|
|
2918
|
+
console.log(chalk20.yellow("\nCancelled."));
|
|
2919
|
+
return;
|
|
2920
|
+
}
|
|
2921
|
+
}
|
|
2922
|
+
await orgAuthenticatedFetch(`/v1/environments/${id}/files/${fileId}`, {
|
|
2923
|
+
method: "DELETE"
|
|
2924
|
+
});
|
|
2925
|
+
console.log(chalk20.green(`
|
|
2926
|
+
Deleted file ${pathOrId}.
|
|
2927
|
+
`));
|
|
2928
|
+
}
|
|
2929
|
+
|
|
2543
2930
|
// src/index.ts
|
|
2544
|
-
var CLI_VERSION = "0.2.
|
|
2931
|
+
var CLI_VERSION = "0.2.137";
|
|
2545
2932
|
var program = new Command();
|
|
2546
2933
|
program.name("replicas").description("CLI for managing Replicas workspaces").version(CLI_VERSION);
|
|
2547
2934
|
program.command("login").description("Authenticate with your Replicas account").action(async () => {
|
|
@@ -2549,7 +2936,7 @@ program.command("login").description("Authenticate with your Replicas account").
|
|
|
2549
2936
|
await loginCommand();
|
|
2550
2937
|
} catch (error) {
|
|
2551
2938
|
if (error instanceof Error) {
|
|
2552
|
-
console.error(
|
|
2939
|
+
console.error(chalk21.red(`
|
|
2553
2940
|
\u2717 ${error.message}
|
|
2554
2941
|
`));
|
|
2555
2942
|
}
|
|
@@ -2561,7 +2948,7 @@ program.command("init").description("Create a replicas.json or replicas.yaml con
|
|
|
2561
2948
|
initCommand(options);
|
|
2562
2949
|
} catch (error) {
|
|
2563
2950
|
if (error instanceof Error) {
|
|
2564
|
-
console.error(
|
|
2951
|
+
console.error(chalk21.red(`
|
|
2565
2952
|
\u2717 ${error.message}
|
|
2566
2953
|
`));
|
|
2567
2954
|
}
|
|
@@ -2573,7 +2960,7 @@ program.command("logout").description("Clear stored credentials").action(() => {
|
|
|
2573
2960
|
logoutCommand();
|
|
2574
2961
|
} catch (error) {
|
|
2575
2962
|
if (error instanceof Error) {
|
|
2576
|
-
console.error(
|
|
2963
|
+
console.error(chalk21.red(`
|
|
2577
2964
|
\u2717 ${error.message}
|
|
2578
2965
|
`));
|
|
2579
2966
|
}
|
|
@@ -2585,7 +2972,7 @@ program.command("whoami").description("Display current authenticated user").acti
|
|
|
2585
2972
|
await whoamiCommand();
|
|
2586
2973
|
} catch (error) {
|
|
2587
2974
|
if (error instanceof Error) {
|
|
2588
|
-
console.error(
|
|
2975
|
+
console.error(chalk21.red(`
|
|
2589
2976
|
\u2717 ${error.message}
|
|
2590
2977
|
`));
|
|
2591
2978
|
}
|
|
@@ -2597,7 +2984,7 @@ program.command("codex-auth").description("Authenticate Replicas with your Codex
|
|
|
2597
2984
|
await codexAuthCommand(options);
|
|
2598
2985
|
} catch (error) {
|
|
2599
2986
|
if (error instanceof Error) {
|
|
2600
|
-
console.error(
|
|
2987
|
+
console.error(chalk21.red(`
|
|
2601
2988
|
\u2717 ${error.message}
|
|
2602
2989
|
`));
|
|
2603
2990
|
}
|
|
@@ -2609,7 +2996,7 @@ program.command("claude-auth").description("Authenticate Replicas with your Clau
|
|
|
2609
2996
|
await claudeAuthCommand(options);
|
|
2610
2997
|
} catch (error) {
|
|
2611
2998
|
if (error instanceof Error) {
|
|
2612
|
-
console.error(
|
|
2999
|
+
console.error(chalk21.red(`
|
|
2613
3000
|
\u2717 ${error.message}
|
|
2614
3001
|
`));
|
|
2615
3002
|
}
|
|
@@ -2622,7 +3009,7 @@ org.command("switch").description("Switch to a different organization").action(a
|
|
|
2622
3009
|
await orgSwitchCommand();
|
|
2623
3010
|
} catch (error) {
|
|
2624
3011
|
if (error instanceof Error) {
|
|
2625
|
-
console.error(
|
|
3012
|
+
console.error(chalk21.red(`
|
|
2626
3013
|
\u2717 ${error.message}
|
|
2627
3014
|
`));
|
|
2628
3015
|
}
|
|
@@ -2634,7 +3021,7 @@ org.action(async () => {
|
|
|
2634
3021
|
await orgCommand();
|
|
2635
3022
|
} catch (error) {
|
|
2636
3023
|
if (error instanceof Error) {
|
|
2637
|
-
console.error(
|
|
3024
|
+
console.error(chalk21.red(`
|
|
2638
3025
|
\u2717 ${error.message}
|
|
2639
3026
|
`));
|
|
2640
3027
|
}
|
|
@@ -2646,7 +3033,7 @@ program.command("connect <workspace-name>").description("Connect to a workspace
|
|
|
2646
3033
|
await connectCommand(workspaceName);
|
|
2647
3034
|
} catch (error) {
|
|
2648
3035
|
if (error instanceof Error) {
|
|
2649
|
-
console.error(
|
|
3036
|
+
console.error(chalk21.red(`
|
|
2650
3037
|
\u2717 ${error.message}
|
|
2651
3038
|
`));
|
|
2652
3039
|
}
|
|
@@ -2658,7 +3045,7 @@ program.command("code <workspace-name>").description("Open a workspace in VSCode
|
|
|
2658
3045
|
await codeCommand(workspaceName);
|
|
2659
3046
|
} catch (error) {
|
|
2660
3047
|
if (error instanceof Error) {
|
|
2661
|
-
console.error(
|
|
3048
|
+
console.error(chalk21.red(`
|
|
2662
3049
|
\u2717 ${error.message}
|
|
2663
3050
|
`));
|
|
2664
3051
|
}
|
|
@@ -2671,7 +3058,7 @@ config.command("get <key>").description("Get a configuration value").action(asyn
|
|
|
2671
3058
|
await configGetCommand(key);
|
|
2672
3059
|
} catch (error) {
|
|
2673
3060
|
if (error instanceof Error) {
|
|
2674
|
-
console.error(
|
|
3061
|
+
console.error(chalk21.red(`
|
|
2675
3062
|
\u2717 ${error.message}
|
|
2676
3063
|
`));
|
|
2677
3064
|
}
|
|
@@ -2683,7 +3070,7 @@ config.command("set <key> <value>").description("Set a configuration value").act
|
|
|
2683
3070
|
await configSetCommand(key, value);
|
|
2684
3071
|
} catch (error) {
|
|
2685
3072
|
if (error instanceof Error) {
|
|
2686
|
-
console.error(
|
|
3073
|
+
console.error(chalk21.red(`
|
|
2687
3074
|
\u2717 ${error.message}
|
|
2688
3075
|
`));
|
|
2689
3076
|
}
|
|
@@ -2695,7 +3082,7 @@ config.command("list").description("List all configuration values").action(async
|
|
|
2695
3082
|
await configListCommand();
|
|
2696
3083
|
} catch (error) {
|
|
2697
3084
|
if (error instanceof Error) {
|
|
2698
|
-
console.error(
|
|
3085
|
+
console.error(chalk21.red(`
|
|
2699
3086
|
\u2717 ${error.message}
|
|
2700
3087
|
`));
|
|
2701
3088
|
}
|
|
@@ -2707,7 +3094,7 @@ program.command("list").description("List all replicas").option("-p, --page <pag
|
|
|
2707
3094
|
await replicaListCommand(options);
|
|
2708
3095
|
} catch (error) {
|
|
2709
3096
|
if (error instanceof Error) {
|
|
2710
|
-
console.error(
|
|
3097
|
+
console.error(chalk21.red(`
|
|
2711
3098
|
\u2717 ${error.message}
|
|
2712
3099
|
`));
|
|
2713
3100
|
}
|
|
@@ -2719,7 +3106,7 @@ program.command("get <id>").description("Get replica details by ID").action(asyn
|
|
|
2719
3106
|
await replicaGetCommand(id);
|
|
2720
3107
|
} catch (error) {
|
|
2721
3108
|
if (error instanceof Error) {
|
|
2722
|
-
console.error(
|
|
3109
|
+
console.error(chalk21.red(`
|
|
2723
3110
|
\u2717 ${error.message}
|
|
2724
3111
|
`));
|
|
2725
3112
|
}
|
|
@@ -2731,7 +3118,7 @@ program.command("create [name]").description("Create a new replica").option("-m,
|
|
|
2731
3118
|
await replicaCreateCommand(name, options);
|
|
2732
3119
|
} catch (error) {
|
|
2733
3120
|
if (error instanceof Error) {
|
|
2734
|
-
console.error(
|
|
3121
|
+
console.error(chalk21.red(`
|
|
2735
3122
|
\u2717 ${error.message}
|
|
2736
3123
|
`));
|
|
2737
3124
|
}
|
|
@@ -2743,7 +3130,7 @@ program.command("send <id>").description("Send a message to a replica").option("
|
|
|
2743
3130
|
await replicaSendCommand(id, options);
|
|
2744
3131
|
} catch (error) {
|
|
2745
3132
|
if (error instanceof Error) {
|
|
2746
|
-
console.error(
|
|
3133
|
+
console.error(chalk21.red(`
|
|
2747
3134
|
\u2717 ${error.message}
|
|
2748
3135
|
`));
|
|
2749
3136
|
}
|
|
@@ -2755,7 +3142,7 @@ program.command("delete <id>").description("Delete a replica").option("-f, --for
|
|
|
2755
3142
|
await replicaDeleteCommand(id, options);
|
|
2756
3143
|
} catch (error) {
|
|
2757
3144
|
if (error instanceof Error) {
|
|
2758
|
-
console.error(
|
|
3145
|
+
console.error(chalk21.red(`
|
|
2759
3146
|
\u2717 ${error.message}
|
|
2760
3147
|
`));
|
|
2761
3148
|
}
|
|
@@ -2767,7 +3154,7 @@ program.command("read <id>").description("Read conversation history of a replica
|
|
|
2767
3154
|
await replicaReadCommand(id, options);
|
|
2768
3155
|
} catch (error) {
|
|
2769
3156
|
if (error instanceof Error) {
|
|
2770
|
-
console.error(
|
|
3157
|
+
console.error(chalk21.red(`
|
|
2771
3158
|
\u2717 ${error.message}
|
|
2772
3159
|
`));
|
|
2773
3160
|
}
|
|
@@ -2780,7 +3167,7 @@ automation.command("list").description("List all automations").option("-p, --pag
|
|
|
2780
3167
|
await automationListCommand(options);
|
|
2781
3168
|
} catch (error) {
|
|
2782
3169
|
if (error instanceof Error) {
|
|
2783
|
-
console.error(
|
|
3170
|
+
console.error(chalk21.red(`
|
|
2784
3171
|
\u2717 ${error.message}
|
|
2785
3172
|
`));
|
|
2786
3173
|
}
|
|
@@ -2792,7 +3179,7 @@ automation.command("get <id>").description("Get automation details by ID").actio
|
|
|
2792
3179
|
await automationGetCommand(id);
|
|
2793
3180
|
} catch (error) {
|
|
2794
3181
|
if (error instanceof Error) {
|
|
2795
|
-
console.error(
|
|
3182
|
+
console.error(chalk21.red(`
|
|
2796
3183
|
\u2717 ${error.message}
|
|
2797
3184
|
`));
|
|
2798
3185
|
}
|
|
@@ -2807,7 +3194,7 @@ automation.command("create [name]").description("Create a new automation").optio
|
|
|
2807
3194
|
});
|
|
2808
3195
|
} catch (error) {
|
|
2809
3196
|
if (error instanceof Error) {
|
|
2810
|
-
console.error(
|
|
3197
|
+
console.error(chalk21.red(`
|
|
2811
3198
|
\u2717 ${error.message}
|
|
2812
3199
|
`));
|
|
2813
3200
|
}
|
|
@@ -2819,7 +3206,7 @@ automation.command("edit <id>").description("Edit an existing automation").optio
|
|
|
2819
3206
|
await automationEditCommand(id, options);
|
|
2820
3207
|
} catch (error) {
|
|
2821
3208
|
if (error instanceof Error) {
|
|
2822
|
-
console.error(
|
|
3209
|
+
console.error(chalk21.red(`
|
|
2823
3210
|
\u2717 ${error.message}
|
|
2824
3211
|
`));
|
|
2825
3212
|
}
|
|
@@ -2831,7 +3218,7 @@ automation.command("run <id>").description("Manually trigger an automation (cron
|
|
|
2831
3218
|
await automationRunCommand(id);
|
|
2832
3219
|
} catch (error) {
|
|
2833
3220
|
if (error instanceof Error) {
|
|
2834
|
-
console.error(
|
|
3221
|
+
console.error(chalk21.red(`
|
|
2835
3222
|
\u2717 ${error.message}
|
|
2836
3223
|
`));
|
|
2837
3224
|
}
|
|
@@ -2843,7 +3230,7 @@ automation.command("delete <id>").description("Delete an automation").option("-f
|
|
|
2843
3230
|
await automationDeleteCommand(id, options);
|
|
2844
3231
|
} catch (error) {
|
|
2845
3232
|
if (error instanceof Error) {
|
|
2846
|
-
console.error(
|
|
3233
|
+
console.error(chalk21.red(`
|
|
2847
3234
|
\u2717 ${error.message}
|
|
2848
3235
|
`));
|
|
2849
3236
|
}
|
|
@@ -2855,7 +3242,7 @@ automation.action(async () => {
|
|
|
2855
3242
|
await automationListCommand({});
|
|
2856
3243
|
} catch (error) {
|
|
2857
3244
|
if (error instanceof Error) {
|
|
2858
|
-
console.error(
|
|
3245
|
+
console.error(chalk21.red(`
|
|
2859
3246
|
\u2717 ${error.message}
|
|
2860
3247
|
`));
|
|
2861
3248
|
}
|
|
@@ -2868,7 +3255,7 @@ repos.command("list").description("List all repositories").action(async () => {
|
|
|
2868
3255
|
await repositoriesListCommand();
|
|
2869
3256
|
} catch (error) {
|
|
2870
3257
|
if (error instanceof Error) {
|
|
2871
|
-
console.error(
|
|
3258
|
+
console.error(chalk21.red(`
|
|
2872
3259
|
\u2717 ${error.message}
|
|
2873
3260
|
`));
|
|
2874
3261
|
}
|
|
@@ -2880,7 +3267,154 @@ repos.action(async () => {
|
|
|
2880
3267
|
await repositoriesListCommand();
|
|
2881
3268
|
} catch (error) {
|
|
2882
3269
|
if (error instanceof Error) {
|
|
2883
|
-
console.error(
|
|
3270
|
+
console.error(chalk21.red(`
|
|
3271
|
+
\u2717 ${error.message}
|
|
3272
|
+
`));
|
|
3273
|
+
}
|
|
3274
|
+
process.exit(1);
|
|
3275
|
+
}
|
|
3276
|
+
});
|
|
3277
|
+
var environment = program.command("environment").alias("env").description("Manage environments (org-scoped templates that back workspaces)");
|
|
3278
|
+
environment.command("list").description("List all environments").action(async () => {
|
|
3279
|
+
try {
|
|
3280
|
+
await environmentListCommand();
|
|
3281
|
+
} catch (error) {
|
|
3282
|
+
if (error instanceof Error) {
|
|
3283
|
+
console.error(chalk21.red(`
|
|
3284
|
+
\u2717 ${error.message}
|
|
3285
|
+
`));
|
|
3286
|
+
}
|
|
3287
|
+
process.exit(1);
|
|
3288
|
+
}
|
|
3289
|
+
});
|
|
3290
|
+
environment.command("get <id-or-name>").description('Get an environment by ID or name (use "global" for the global env)').action(async (idOrName) => {
|
|
3291
|
+
try {
|
|
3292
|
+
await environmentGetCommand(idOrName);
|
|
3293
|
+
} catch (error) {
|
|
3294
|
+
if (error instanceof Error) {
|
|
3295
|
+
console.error(chalk21.red(`
|
|
3296
|
+
\u2717 ${error.message}
|
|
3297
|
+
`));
|
|
3298
|
+
}
|
|
3299
|
+
process.exit(1);
|
|
3300
|
+
}
|
|
3301
|
+
});
|
|
3302
|
+
environment.command("create [name]").description("Create a new environment").option("-d, --description <description>", "Environment description").option("-r, --repository <name-or-id>", "Bind to a repository (by name or ID)").option("--system-prompt <prompt>", "System prompt for agents started in this environment").action(async (name, options) => {
|
|
3303
|
+
try {
|
|
3304
|
+
await environmentCreateCommand(name, options);
|
|
3305
|
+
} catch (error) {
|
|
3306
|
+
if (error instanceof Error) {
|
|
3307
|
+
console.error(chalk21.red(`
|
|
3308
|
+
\u2717 ${error.message}
|
|
3309
|
+
`));
|
|
3310
|
+
}
|
|
3311
|
+
process.exit(1);
|
|
3312
|
+
}
|
|
3313
|
+
});
|
|
3314
|
+
environment.command("edit <id-or-name>").description("Edit an environment").option("-n, --name <name>", "New name").option("-d, --description <description>", "New description").option("-r, --repository <name-or-id>", "Repository binding (pass empty string to unbind)").option("--system-prompt <prompt>", "System prompt").action(async (idOrName, options) => {
|
|
3315
|
+
try {
|
|
3316
|
+
await environmentEditCommand(idOrName, options);
|
|
3317
|
+
} catch (error) {
|
|
3318
|
+
if (error instanceof Error) {
|
|
3319
|
+
console.error(chalk21.red(`
|
|
3320
|
+
\u2717 ${error.message}
|
|
3321
|
+
`));
|
|
3322
|
+
}
|
|
3323
|
+
process.exit(1);
|
|
3324
|
+
}
|
|
3325
|
+
});
|
|
3326
|
+
environment.command("delete <id-or-name>").description("Delete an environment").option("-f, --force", "Skip confirmation prompt").action(async (idOrName, options) => {
|
|
3327
|
+
try {
|
|
3328
|
+
await environmentDeleteCommand(idOrName, options);
|
|
3329
|
+
} catch (error) {
|
|
3330
|
+
if (error instanceof Error) {
|
|
3331
|
+
console.error(chalk21.red(`
|
|
3332
|
+
\u2717 ${error.message}
|
|
3333
|
+
`));
|
|
3334
|
+
}
|
|
3335
|
+
process.exit(1);
|
|
3336
|
+
}
|
|
3337
|
+
});
|
|
3338
|
+
var envVars = environment.command("vars").description("Manage environment variables");
|
|
3339
|
+
envVars.command("list <env>").description("List variables in an environment (values masked by default)").option("--reveal", "Show full variable values instead of masking them").action(async (env, options) => {
|
|
3340
|
+
try {
|
|
3341
|
+
await envVarsListCommand(env, options);
|
|
3342
|
+
} catch (error) {
|
|
3343
|
+
if (error instanceof Error) {
|
|
3344
|
+
console.error(chalk21.red(`
|
|
3345
|
+
\u2717 ${error.message}
|
|
3346
|
+
`));
|
|
3347
|
+
}
|
|
3348
|
+
process.exit(1);
|
|
3349
|
+
}
|
|
3350
|
+
});
|
|
3351
|
+
envVars.command("set <env> <key> <value>").description("Create or update a variable").action(async (env, key, value) => {
|
|
3352
|
+
try {
|
|
3353
|
+
await envVarsSetCommand(env, key, value);
|
|
3354
|
+
} catch (error) {
|
|
3355
|
+
if (error instanceof Error) {
|
|
3356
|
+
console.error(chalk21.red(`
|
|
3357
|
+
\u2717 ${error.message}
|
|
3358
|
+
`));
|
|
3359
|
+
}
|
|
3360
|
+
process.exit(1);
|
|
3361
|
+
}
|
|
3362
|
+
});
|
|
3363
|
+
envVars.command("delete <env> <key-or-id>").description("Delete a variable by key or ID").option("-f, --force", "Skip confirmation prompt").action(async (env, keyOrId, options) => {
|
|
3364
|
+
try {
|
|
3365
|
+
await envVarsDeleteCommand(env, keyOrId, options);
|
|
3366
|
+
} catch (error) {
|
|
3367
|
+
if (error instanceof Error) {
|
|
3368
|
+
console.error(chalk21.red(`
|
|
3369
|
+
\u2717 ${error.message}
|
|
3370
|
+
`));
|
|
3371
|
+
}
|
|
3372
|
+
process.exit(1);
|
|
3373
|
+
}
|
|
3374
|
+
});
|
|
3375
|
+
var envFiles = environment.command("files").description("Manage environment files (mounted into workspaces at workspace start)");
|
|
3376
|
+
envFiles.command("list <env>").description("List files in an environment").action(async (env) => {
|
|
3377
|
+
try {
|
|
3378
|
+
await envFilesListCommand(env);
|
|
3379
|
+
} catch (error) {
|
|
3380
|
+
if (error instanceof Error) {
|
|
3381
|
+
console.error(chalk21.red(`
|
|
3382
|
+
\u2717 ${error.message}
|
|
3383
|
+
`));
|
|
3384
|
+
}
|
|
3385
|
+
process.exit(1);
|
|
3386
|
+
}
|
|
3387
|
+
});
|
|
3388
|
+
envFiles.command("set <env> <destination-path>").description("Create or update a file at <destination-path> inside the workspace").option("-c, --content <content>", "Inline file content").option("-f, --file <local-path>", "Read content from a local file").option("-n, --name <name>", "Display name (defaults to basename of destination path)").action(async (env, destinationPath, options) => {
|
|
3389
|
+
try {
|
|
3390
|
+
await envFilesSetCommand(env, destinationPath, options);
|
|
3391
|
+
} catch (error) {
|
|
3392
|
+
if (error instanceof Error) {
|
|
3393
|
+
console.error(chalk21.red(`
|
|
3394
|
+
\u2717 ${error.message}
|
|
3395
|
+
`));
|
|
3396
|
+
}
|
|
3397
|
+
process.exit(1);
|
|
3398
|
+
}
|
|
3399
|
+
});
|
|
3400
|
+
envFiles.command("delete <env> <path-or-id>").description("Delete a file by destination path or ID").option("-f, --force", "Skip confirmation prompt").action(async (env, pathOrId, options) => {
|
|
3401
|
+
try {
|
|
3402
|
+
await envFilesDeleteCommand(env, pathOrId, options);
|
|
3403
|
+
} catch (error) {
|
|
3404
|
+
if (error instanceof Error) {
|
|
3405
|
+
console.error(chalk21.red(`
|
|
3406
|
+
\u2717 ${error.message}
|
|
3407
|
+
`));
|
|
3408
|
+
}
|
|
3409
|
+
process.exit(1);
|
|
3410
|
+
}
|
|
3411
|
+
});
|
|
3412
|
+
environment.action(async () => {
|
|
3413
|
+
try {
|
|
3414
|
+
await environmentListCommand();
|
|
3415
|
+
} catch (error) {
|
|
3416
|
+
if (error instanceof Error) {
|
|
3417
|
+
console.error(chalk21.red(`
|
|
2884
3418
|
\u2717 ${error.message}
|
|
2885
3419
|
`));
|
|
2886
3420
|
}
|
|
@@ -2892,7 +3426,7 @@ program.command("interact").alias("i").description("Launch the interactive termi
|
|
|
2892
3426
|
await interactiveCommand();
|
|
2893
3427
|
} catch (error) {
|
|
2894
3428
|
if (error instanceof Error) {
|
|
2895
|
-
console.error(
|
|
3429
|
+
console.error(chalk21.red(`
|
|
2896
3430
|
\u2717 ${error.message}
|
|
2897
3431
|
`));
|
|
2898
3432
|
}
|
|
@@ -2943,7 +3477,7 @@ if (isAgentMode()) {
|
|
|
2943
3477
|
await previewAddCommand(workspaceId, options);
|
|
2944
3478
|
} catch (error) {
|
|
2945
3479
|
if (error instanceof Error) {
|
|
2946
|
-
console.error(
|
|
3480
|
+
console.error(chalk21.red(`
|
|
2947
3481
|
\u2717 ${error.message}
|
|
2948
3482
|
`));
|
|
2949
3483
|
}
|
|
@@ -2955,7 +3489,7 @@ if (isAgentMode()) {
|
|
|
2955
3489
|
await previewListCommand(workspaceId);
|
|
2956
3490
|
} catch (error) {
|
|
2957
3491
|
if (error instanceof Error) {
|
|
2958
|
-
console.error(
|
|
3492
|
+
console.error(chalk21.red(`
|
|
2959
3493
|
\u2717 ${error.message}
|
|
2960
3494
|
`));
|
|
2961
3495
|
}
|
|
@@ -2967,7 +3501,7 @@ if (isAgentMode()) {
|
|
|
2967
3501
|
await previewRemoveCommand(workspaceId, options);
|
|
2968
3502
|
} catch (error) {
|
|
2969
3503
|
if (error instanceof Error) {
|
|
2970
|
-
console.error(
|
|
3504
|
+
console.error(chalk21.red(`
|
|
2971
3505
|
\u2717 ${error.message}
|
|
2972
3506
|
`));
|
|
2973
3507
|
}
|
|
@@ -2982,7 +3516,7 @@ if (isAgentMode()) {
|
|
|
2982
3516
|
await mediaUploadCommand(files, options);
|
|
2983
3517
|
} catch (error) {
|
|
2984
3518
|
if (error instanceof Error) {
|
|
2985
|
-
console.error(
|
|
3519
|
+
console.error(chalk21.red(`
|
|
2986
3520
|
\u2717 ${error.message}
|
|
2987
3521
|
`));
|
|
2988
3522
|
}
|
|
@@ -2994,14 +3528,23 @@ if (isAgentMode()) {
|
|
|
2994
3528
|
await mediaListCommand(options);
|
|
2995
3529
|
} catch (error) {
|
|
2996
3530
|
if (error instanceof Error) {
|
|
2997
|
-
console.error(
|
|
3531
|
+
console.error(chalk21.red(`
|
|
2998
3532
|
\u2717 ${error.message}
|
|
2999
3533
|
`));
|
|
3000
3534
|
}
|
|
3001
3535
|
process.exit(1);
|
|
3002
3536
|
}
|
|
3003
3537
|
});
|
|
3004
|
-
const allowed = /* @__PURE__ */ new Set([
|
|
3538
|
+
const allowed = /* @__PURE__ */ new Set([
|
|
3539
|
+
"init",
|
|
3540
|
+
"whoami",
|
|
3541
|
+
"connect",
|
|
3542
|
+
"preview",
|
|
3543
|
+
"media",
|
|
3544
|
+
"automation",
|
|
3545
|
+
"repos",
|
|
3546
|
+
"environment"
|
|
3547
|
+
]);
|
|
3005
3548
|
const kept = program.commands.filter((cmd) => allowed.has(cmd.name()));
|
|
3006
3549
|
const cmds = program.commands;
|
|
3007
3550
|
cmds.length = 0;
|