bdy 1.23.4-dev-target-commands → 1.23.4-dev
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/distTs/README.md +181 -0
- package/distTs/package.json +1 -3
- package/distTs/src/agent/agent.js +35 -2
- package/distTs/src/agent/manager.js +11 -0
- package/distTs/src/agent/system.js +6 -1
- package/distTs/src/api/client.js +0 -156
- package/distTs/src/cliIndex.js +0 -4
- package/distTs/src/command/artifact/list.js +6 -1
- package/distTs/src/command/distro/route/update.js +1 -1
- package/distTs/src/command/distro/update.js +9 -9
- package/distTs/src/command/project/get.js +18 -0
- package/distTs/src/command/project/set.js +31 -0
- package/distTs/src/command/sandbox/get/yaml.js +30 -0
- package/distTs/src/command/vt/scrape.js +193 -0
- package/distTs/src/input.js +0 -54
- package/distTs/src/texts.js +8 -196
- package/distTs/src/utils.js +7 -16
- package/package.json +1 -3
- package/distTs/detect-rules.json +0 -351
- package/distTs/src/command/environment/create.js +0 -70
- package/distTs/src/command/environment/delete.js +0 -29
- package/distTs/src/command/environment/get.js +0 -48
- package/distTs/src/command/environment/list.js +0 -44
- package/distTs/src/command/environment/resolve.js +0 -22
- package/distTs/src/command/environment/update.js +0 -59
- package/distTs/src/command/environment.js +0 -20
- package/distTs/src/command/pipeline/run/apply.js +0 -62
- package/distTs/src/command/target/create.js +0 -33
- package/distTs/src/command/target/delete.js +0 -30
- package/distTs/src/command/target/exec/command.js +0 -65
- package/distTs/src/command/target/exec/kill.js +0 -25
- package/distTs/src/command/target/exec/list.js +0 -54
- package/distTs/src/command/target/exec/logs.js +0 -25
- package/distTs/src/command/target/exec/status.js +0 -41
- package/distTs/src/command/target/exec.js +0 -24
- package/distTs/src/command/target/get.js +0 -62
- package/distTs/src/command/target/list.js +0 -48
- package/distTs/src/command/target/scope.js +0 -60
- package/distTs/src/command/target/update.js +0 -31
- package/distTs/src/command/target.js +0 -22
- package/distTs/src/command/yaml/actions/detect.js +0 -268
- package/distTs/src/command/yaml/actions/info.js +0 -56
- package/distTs/src/command/yaml/actions/list.js +0 -70
- package/distTs/src/command/yaml/actions/schema.js +0 -104
- package/distTs/src/command/yaml/actions.js +0 -13
- package/distTs/src/command/yaml/agents.js +0 -88
- package/distTs/src/command/yaml/cache.js +0 -98
- package/distTs/src/command/yaml/init.js +0 -110
- package/distTs/src/command/yaml/pipeline.js +0 -42
- package/distTs/src/command/yaml/render.js +0 -83
- package/distTs/src/command/yaml/schemaUtils.js +0 -139
- package/distTs/src/command/yaml/validate.js +0 -259
- package/distTs/src/command/yaml.js +0 -18
- package/distTs/src/diskCache.js +0 -82
package/distTs/README.md
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
# Buddy CLI (`bdy`)
|
|
2
|
+
|
|
3
|
+
Work seamlessly with [Buddy](https://buddy.works) from the command line.
|
|
4
|
+
|
|
5
|
+
`bdy` is Buddy's official command-line interface for managing CI/CD pipelines, agents, tests, artifacts, sandboxes, distributions, and more — straight from your terminal.
|
|
6
|
+
|
|
7
|
+
📚 Full documentation: https://buddy.works/docs/cli/getting-started
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
### npm (recommended)
|
|
12
|
+
|
|
13
|
+
Requires Node.js 14+.
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# macOS / Linux
|
|
17
|
+
sudo npm i -g bdy
|
|
18
|
+
|
|
19
|
+
# Windows
|
|
20
|
+
npm i -g bdy
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Homebrew (macOS)
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
brew tap buddy/bdy
|
|
27
|
+
brew install bdy
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### APT (Linux x64 / ARM64)
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
sudo apt-get update && sudo apt-get install -y software-properties-common
|
|
34
|
+
sudo gpg --homedir /tmp --no-default-keyring --keyring /usr/share/keyrings/buddy.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys eb39332e766364ca6220e8dc631c5a16310cc0ad
|
|
35
|
+
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/buddy.gpg] https://es.buddy.works/bdy/apt-repo prod main" | sudo tee /etc/apt/sources.list.d/buddy.list > /dev/null
|
|
36
|
+
sudo apt-get update && sudo apt-get install -y bdy
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
> On ARM64, replace `arch=amd64` with `arch=arm64` in the `echo` command above.
|
|
40
|
+
|
|
41
|
+
### Chocolatey (Windows)
|
|
42
|
+
|
|
43
|
+
```powershell
|
|
44
|
+
choco install bdy --pre
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Direct download
|
|
48
|
+
|
|
49
|
+
Prebuilt binaries are available for macOS (Apple Silicon), Linux (x64/ARM64), and Windows (x64) on the [installation page](https://buddy.works/docs/cli/getting-started).
|
|
50
|
+
|
|
51
|
+
### Verify & update
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
bdy version # show current and latest version
|
|
55
|
+
sudo npm i -g bdy # update (or use your package manager's upgrade command)
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Authentication
|
|
59
|
+
|
|
60
|
+
A [Buddy account](https://buddy.works) is required to use the CLI.
|
|
61
|
+
|
|
62
|
+
Log in interactively:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
bdy login
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
New to Buddy? Create an account from the CLI:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
bdy register
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Linking a project
|
|
75
|
+
|
|
76
|
+
Once logged in, link a directory to a Buddy project:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
mkdir my-proj
|
|
80
|
+
cd my-proj
|
|
81
|
+
bdy proj link
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
After linking, every `bdy` command run from this directory is executed against the linked project — no need to pass the project name each time.
|
|
85
|
+
|
|
86
|
+
Check who you're logged in as, or log out:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
bdy whoami
|
|
90
|
+
bdy logout
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Tokens & non-interactive login
|
|
94
|
+
|
|
95
|
+
For CI/CD pipelines and non-browser environments, authenticate with a [personal access token](https://buddy.works/docs/api/getting-started/oauth2/personal-access-token):
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
bdy login --token <token>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
The login command accepts the following options:
|
|
102
|
+
|
|
103
|
+
| Option | Description | Environment variable |
|
|
104
|
+
| --- | --- | --- |
|
|
105
|
+
| `--token <token>` | Personal access token | `BUDDY_TOKEN` |
|
|
106
|
+
| `--api <url>` | API URL for On-Premises installations | `BUDDY_API_ENDPOINT` |
|
|
107
|
+
| `--region <region>` | Region: `us`, `eu`, or `as` | `BUDDY_REGION` |
|
|
108
|
+
| `-w, --workspace <domain>` | Workspace URL handle | `BUDDY_WORKSPACE` |
|
|
109
|
+
|
|
110
|
+
Each option can be supplied as a flag or via its environment variable — handy for pipelines and headless setups:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
export BUDDY_TOKEN=<token>
|
|
114
|
+
export BUDDY_WORKSPACE=<your-workspace>
|
|
115
|
+
bdy login
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Agent integration (plugin & skills)
|
|
119
|
+
|
|
120
|
+
The [Buddy Plugin](https://github.com/buddy/buddy-plugin) lets coding agents deploy applications, expose local services, and manage infrastructure on Buddy. It bundles a consolidated skill covering sandboxes, artifacts, tunnels, domains, distributions, and pipelines, plus two commands:
|
|
121
|
+
|
|
122
|
+
- `/deploy [name] [path]` — deploy a static site or server application
|
|
123
|
+
- `/expose [port]` — open a tunnel to a locally running service
|
|
124
|
+
|
|
125
|
+
Make sure the CLI is installed first (`sudo npm install -g bdy`), then:
|
|
126
|
+
|
|
127
|
+
**Claude Code** — install the plugin (commands + skills):
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
claude plugin marketplace add buddy/buddy-plugin
|
|
131
|
+
claude plugin install buddy@buddy-plugin
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**Other agents** — install the skills only:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
npx skills add buddy/buddy-plugin
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Then authenticate and link your project:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
bdy login
|
|
144
|
+
cd your-project
|
|
145
|
+
bdy proj link
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
The plugin auto-detects your project type: static sites generate versioned artifacts with public URLs, while server applications deploy to sandboxes with HTTPS endpoints. Monorepos can deploy multiple applications, each getting its own URL and endpoint.
|
|
149
|
+
|
|
150
|
+
## Commands
|
|
151
|
+
|
|
152
|
+
| Command | Description |
|
|
153
|
+
| --- | --- |
|
|
154
|
+
| `bdy login` / `sign-in` | Log in to Buddy |
|
|
155
|
+
| `bdy register` / `sign-up` | Register a new Buddy account |
|
|
156
|
+
| `bdy whoami` | Check login information |
|
|
157
|
+
| `bdy logout` | Log out from Buddy |
|
|
158
|
+
| `bdy workspace` / `ws` | Manage workspaces |
|
|
159
|
+
| `bdy project` / `proj` | Manage projects |
|
|
160
|
+
| `bdy pipeline` / `pip` | Interact with the pipeline service |
|
|
161
|
+
| `bdy artifact` / `art` | Interact with the artifact service |
|
|
162
|
+
| `bdy sandbox` / `sb` | Interact with sandboxes |
|
|
163
|
+
| `bdy agent` | Install and run `bdy` as an OS service (Windows, macOS, Linux) |
|
|
164
|
+
| `bdy tunnel` | Manage tunnel configuration |
|
|
165
|
+
| `bdy crawl` | Manage web crawls (Markdown, HTML, PNG/JPEG screenshots; suite linking) |
|
|
166
|
+
| `bdy tests` | Manage unit tests and visual regression (Storybook, URL captures, runners) |
|
|
167
|
+
| `bdy domain` | Manage zones used in distribution routes |
|
|
168
|
+
| `bdy distro` | Manage distributions |
|
|
169
|
+
| `bdy api` | Contact the Buddy API directly |
|
|
170
|
+
| `bdy update` / `version` | Show version and update the CLI |
|
|
171
|
+
|
|
172
|
+
Run any command with `-h` / `--help` for detailed usage:
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
bdy --help
|
|
176
|
+
bdy pipeline --help
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Feedback
|
|
180
|
+
|
|
181
|
+
Found a bug or have a feature request? Let us know through [Buddy support](https://buddy.works/support) or the [documentation](https://buddy.works/docs/cli/getting-started).
|
package/distTs/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bdy",
|
|
3
3
|
"preferGlobal": false,
|
|
4
|
-
"version": "1.23.4-dev
|
|
4
|
+
"version": "1.23.4-dev",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"homepage": "https://buddy.works/docs/cli",
|
|
@@ -27,8 +27,6 @@
|
|
|
27
27
|
"e2e:tunnel": "vitest run --config e2e/vitest.config.ts e2e/modules/tunnel/",
|
|
28
28
|
"e2e:agent": "vitest run --config e2e/vitest.config.ts e2e/modules/agent/",
|
|
29
29
|
"e2e:distro": "vitest run --config e2e/vitest.config.ts e2e/modules/distro/",
|
|
30
|
-
"e2e:target": "vitest run --config e2e/vitest.config.ts e2e/modules/target/",
|
|
31
|
-
"e2e:environment": "vitest run --config e2e/vitest.config.ts e2e/modules/environment/",
|
|
32
30
|
"unit": "vitest run --config vitest.config.ts"
|
|
33
31
|
},
|
|
34
32
|
"files": [
|
|
@@ -25,6 +25,7 @@ class Agent extends events_1.default {
|
|
|
25
25
|
api;
|
|
26
26
|
socket;
|
|
27
27
|
manager;
|
|
28
|
+
updateStatusExpiry;
|
|
28
29
|
onRefresh;
|
|
29
30
|
constructor(id, host, token, service, target, tunneling, proxy, tags, api, disabled) {
|
|
30
31
|
super();
|
|
@@ -41,6 +42,7 @@ class Agent extends events_1.default {
|
|
|
41
42
|
this.tunnelsUpdating = false;
|
|
42
43
|
this.api = api;
|
|
43
44
|
this.manager = null;
|
|
45
|
+
this.updateStatusExpiry = null;
|
|
44
46
|
this.onRefresh = null;
|
|
45
47
|
this.socket = new client_1.default(host, id, token);
|
|
46
48
|
this.socket.on(tunnel_1.TUNNEL_SOCKET_EVENT.FETCH_SUCCESS, (data) => this._onSocketFetch(data));
|
|
@@ -56,6 +58,10 @@ class Agent extends events_1.default {
|
|
|
56
58
|
this.socket.destroy();
|
|
57
59
|
this.socket = null;
|
|
58
60
|
}
|
|
61
|
+
// Would fire on a socket that is already gone
|
|
62
|
+
if (this.updateStatusExpiry)
|
|
63
|
+
clearTimeout(this.updateStatusExpiry);
|
|
64
|
+
this.updateStatusExpiry = null;
|
|
59
65
|
this.manager = null;
|
|
60
66
|
this.onRefresh = null;
|
|
61
67
|
this.api = null;
|
|
@@ -260,8 +266,35 @@ class Agent extends events_1.default {
|
|
|
260
266
|
// previous value in place, which is why the front reads STARTED on an offline agent as
|
|
261
267
|
// an unknown outcome rather than as an update still running.
|
|
262
268
|
reportUpdateStatus(status) {
|
|
263
|
-
if (this.socket)
|
|
264
|
-
|
|
269
|
+
if (!this.socket)
|
|
270
|
+
return;
|
|
271
|
+
this.socket.setPendingAction(status);
|
|
272
|
+
this.expireUpdateStatusIn(status);
|
|
273
|
+
}
|
|
274
|
+
// Takes the outcome back off the record after a while, so it reads as the confirmation
|
|
275
|
+
// it is rather than as a standing fact about the agent. Done here rather than by hiding
|
|
276
|
+
// it in the front because nothing on the record dates the write: the only timestamps a
|
|
277
|
+
// front could compare against are the agent's boot time and its heartbeat, and neither
|
|
278
|
+
// is when this happened.
|
|
279
|
+
//
|
|
280
|
+
// A timer is sound for this where it would not be for the update itself: the process
|
|
281
|
+
// that reports an outcome is the one still running, so nothing has to survive a restart
|
|
282
|
+
// - and if it dies first, the next start() sends an empty action anyway.
|
|
283
|
+
expireUpdateStatusIn(status) {
|
|
284
|
+
if (this.updateStatusExpiry)
|
|
285
|
+
clearTimeout(this.updateStatusExpiry);
|
|
286
|
+
this.updateStatusExpiry = null;
|
|
287
|
+
// STARTED is not an outcome. It is what stays behind when a restart never lands, and
|
|
288
|
+
// clearing it would turn the one state the front can flag as unknown into silence.
|
|
289
|
+
if (status === tunnel_1.TUNNEL_AGENT_UPDATE_STATUS.STARTED)
|
|
290
|
+
return;
|
|
291
|
+
this.updateStatusExpiry = setTimeout(() => {
|
|
292
|
+
this.updateStatusExpiry = null;
|
|
293
|
+
this.ackAction();
|
|
294
|
+
}, utils_1.AGENT_UPDATE_STATUS_TTL_MS);
|
|
295
|
+
// A foreground tunnel reporting UNSUPPORTED exits as soon as it has acked, and must
|
|
296
|
+
// not be held open for the rest of the window just to tidy up after itself
|
|
297
|
+
this.updateStatusExpiry.unref();
|
|
265
298
|
}
|
|
266
299
|
// For a status with no ack to ride on - STARTED, reported while the download is still
|
|
267
300
|
// running. Passes null so that if the status has somehow already gone out, this does
|
|
@@ -141,6 +141,11 @@ class AgentManagerClass {
|
|
|
141
141
|
// Every path that gives up reports why as well as acking: the ack alone clears the
|
|
142
142
|
// request, which on the front is indistinguishable from an update that never ran.
|
|
143
143
|
const report = (status) => {
|
|
144
|
+
// Except when the agent is going away. There is nothing left to tell, and the write
|
|
145
|
+
// would land on top of the DELETE this process has not finished acting on - which
|
|
146
|
+
// is also how the swap below reports being cut short by one.
|
|
147
|
+
if (this.exiting)
|
|
148
|
+
return;
|
|
144
149
|
this.agent?.reportUpdateStatus(status);
|
|
145
150
|
return this.agent?.ackAction();
|
|
146
151
|
};
|
|
@@ -540,6 +545,12 @@ class AgentManagerClass {
|
|
|
540
545
|
}
|
|
541
546
|
async disableAgentAndExit(txt) {
|
|
542
547
|
logger_1.default.error(txt);
|
|
548
|
+
// Set before the first await, not just before the exit: uninstalling and unregistering
|
|
549
|
+
// both take a while, and a remote update arriving in that window would otherwise start
|
|
550
|
+
// downloading a release for an agent that is being taken apart - and could rename the
|
|
551
|
+
// new binary into place after the files it lives among have been removed. The update
|
|
552
|
+
// path already refuses to start while this is set.
|
|
553
|
+
this.exiting = true;
|
|
543
554
|
try {
|
|
544
555
|
await this.system.uninstall();
|
|
545
556
|
}
|
|
@@ -407,7 +407,12 @@ class AgentSystem {
|
|
|
407
407
|
// Last check before touching the live binary. The download and the smoke test take
|
|
408
408
|
// long enough for an uninstall to have run in the meantime, and finishing the swap
|
|
409
409
|
// then would put a binary back for an agent that is deliberately gone.
|
|
410
|
-
|
|
410
|
+
//
|
|
411
|
+
// The config file alone is not enough to tell: an uninstall removes it only after
|
|
412
|
+
// stopping the service and unregistering, so a delete that is under way still looks
|
|
413
|
+
// like a live install from here for as long as those take. The flag is set before
|
|
414
|
+
// any of that starts.
|
|
415
|
+
if (!(0, node_fs_1.existsSync)(this.getSystemConfigPath()) || manager_1.default.exiting) {
|
|
411
416
|
throw new Error(texts_1.LOG_AGENT_UPDATE_UNINSTALLED);
|
|
412
417
|
}
|
|
413
418
|
(0, node_fs_1.rmSync)(backup, { force: true });
|
package/distTs/src/api/client.js
CHANGED
|
@@ -563,162 +563,6 @@ class ApiClient {
|
|
|
563
563
|
q.project = project;
|
|
564
564
|
return await this.getResourceByIdentifier(workspace, q);
|
|
565
565
|
}
|
|
566
|
-
// Target methods
|
|
567
|
-
targetScopeQuery(scope) {
|
|
568
|
-
const query = {};
|
|
569
|
-
if (scope.project)
|
|
570
|
-
query.project_name = scope.project;
|
|
571
|
-
if (scope.pipelineId)
|
|
572
|
-
query.pipeline_id = scope.pipelineId.toString();
|
|
573
|
-
if (scope.environmentId)
|
|
574
|
-
query.environment_id = scope.environmentId;
|
|
575
|
-
return query;
|
|
576
|
-
}
|
|
577
|
-
async getTargets(workspace, filters = {}) {
|
|
578
|
-
return await this.request({
|
|
579
|
-
method: 'GET',
|
|
580
|
-
path: `/workspaces/${encodeURIComponent(workspace)}/targets`,
|
|
581
|
-
query: this.targetScopeQuery(filters),
|
|
582
|
-
parseResponseBody: true,
|
|
583
|
-
});
|
|
584
|
-
}
|
|
585
|
-
async getTarget(workspace, targetId) {
|
|
586
|
-
return await this.request({
|
|
587
|
-
method: 'GET',
|
|
588
|
-
path: `/workspaces/${encodeURIComponent(workspace)}/targets/${encodeURIComponent(targetId)}`,
|
|
589
|
-
parseResponseBody: true,
|
|
590
|
-
});
|
|
591
|
-
}
|
|
592
|
-
async createTargetByYaml(workspace, scope, body) {
|
|
593
|
-
return await this.request({
|
|
594
|
-
method: 'POST',
|
|
595
|
-
path: `/workspaces/${encodeURIComponent(workspace)}/targets/yaml`,
|
|
596
|
-
query: this.targetScopeQuery(scope),
|
|
597
|
-
body,
|
|
598
|
-
parseResponseBody: true,
|
|
599
|
-
});
|
|
600
|
-
}
|
|
601
|
-
async updateTargetByYaml(workspace, targetId, body) {
|
|
602
|
-
return await this.request({
|
|
603
|
-
method: 'PATCH',
|
|
604
|
-
path: `/workspaces/${encodeURIComponent(workspace)}/targets/${encodeURIComponent(targetId)}/yaml`,
|
|
605
|
-
body,
|
|
606
|
-
parseResponseBody: true,
|
|
607
|
-
});
|
|
608
|
-
}
|
|
609
|
-
async deleteTarget(workspace, targetId) {
|
|
610
|
-
return await this.request({
|
|
611
|
-
method: 'DELETE',
|
|
612
|
-
path: `/workspaces/${encodeURIComponent(workspace)}/targets/${encodeURIComponent(targetId)}`,
|
|
613
|
-
parseResponseBody: false,
|
|
614
|
-
});
|
|
615
|
-
}
|
|
616
|
-
async executeTargetCommand(workspace, targetId, body) {
|
|
617
|
-
return await this.request({
|
|
618
|
-
method: 'POST',
|
|
619
|
-
path: `/workspaces/${encodeURIComponent(workspace)}/targets/${encodeURIComponent(targetId)}/execs`,
|
|
620
|
-
body,
|
|
621
|
-
parseResponseBody: true,
|
|
622
|
-
});
|
|
623
|
-
}
|
|
624
|
-
async getTargetExecs(workspace, targetId, limit) {
|
|
625
|
-
const query = {};
|
|
626
|
-
if (limit)
|
|
627
|
-
query.limit = limit.toString();
|
|
628
|
-
return await this.request({
|
|
629
|
-
method: 'GET',
|
|
630
|
-
path: `/workspaces/${encodeURIComponent(workspace)}/targets/${encodeURIComponent(targetId)}/execs`,
|
|
631
|
-
query,
|
|
632
|
-
parseResponseBody: true,
|
|
633
|
-
});
|
|
634
|
-
}
|
|
635
|
-
async getTargetExec(workspace, execId, wait) {
|
|
636
|
-
const query = {};
|
|
637
|
-
if (wait)
|
|
638
|
-
query.wait = wait.toString();
|
|
639
|
-
return await this.request({
|
|
640
|
-
method: 'GET',
|
|
641
|
-
path: `/workspaces/${encodeURIComponent(workspace)}/targets/execs/${encodeURIComponent(execId)}`,
|
|
642
|
-
query,
|
|
643
|
-
parseResponseBody: true,
|
|
644
|
-
});
|
|
645
|
-
}
|
|
646
|
-
async cancelTargetExec(workspace, execId) {
|
|
647
|
-
return await this.request({
|
|
648
|
-
method: 'DELETE',
|
|
649
|
-
path: `/workspaces/${encodeURIComponent(workspace)}/targets/execs/${encodeURIComponent(execId)}`,
|
|
650
|
-
parseResponseBody: false,
|
|
651
|
-
});
|
|
652
|
-
}
|
|
653
|
-
async getTargetExecLog(workspace, execId, offset, limit) {
|
|
654
|
-
const query = {};
|
|
655
|
-
if (offset)
|
|
656
|
-
query.offset = offset.toString();
|
|
657
|
-
if (limit)
|
|
658
|
-
query.limit = limit.toString();
|
|
659
|
-
return await this.request({
|
|
660
|
-
method: 'GET',
|
|
661
|
-
path: `/workspaces/${encodeURIComponent(workspace)}/targets/execs/${encodeURIComponent(execId)}/log`,
|
|
662
|
-
query,
|
|
663
|
-
parseResponseBody: true,
|
|
664
|
-
});
|
|
665
|
-
}
|
|
666
|
-
async getTargetByIdentifier(workspace, identifier, line = {}) {
|
|
667
|
-
return await this.getResourceByIdentifier(workspace, {
|
|
668
|
-
target: identifier,
|
|
669
|
-
...line,
|
|
670
|
-
});
|
|
671
|
-
}
|
|
672
|
-
// Environment methods
|
|
673
|
-
async getEnvironments(workspace, project) {
|
|
674
|
-
const query = {};
|
|
675
|
-
if (project)
|
|
676
|
-
query.project_name = project;
|
|
677
|
-
return await this.request({
|
|
678
|
-
method: 'GET',
|
|
679
|
-
path: `/workspaces/${encodeURIComponent(workspace)}/environments`,
|
|
680
|
-
query,
|
|
681
|
-
parseResponseBody: true,
|
|
682
|
-
});
|
|
683
|
-
}
|
|
684
|
-
async getEnvironment(workspace, environmentId) {
|
|
685
|
-
return await this.request({
|
|
686
|
-
method: 'GET',
|
|
687
|
-
path: `/workspaces/${encodeURIComponent(workspace)}/environments/${encodeURIComponent(environmentId)}`,
|
|
688
|
-
parseResponseBody: true,
|
|
689
|
-
});
|
|
690
|
-
}
|
|
691
|
-
async createEnvironment(workspace, body) {
|
|
692
|
-
return await this.request({
|
|
693
|
-
method: 'POST',
|
|
694
|
-
path: `/workspaces/${encodeURIComponent(workspace)}/environments`,
|
|
695
|
-
body,
|
|
696
|
-
parseResponseBody: true,
|
|
697
|
-
});
|
|
698
|
-
}
|
|
699
|
-
async updateEnvironment(workspace, environmentId, body) {
|
|
700
|
-
return await this.request({
|
|
701
|
-
method: 'PATCH',
|
|
702
|
-
path: `/workspaces/${encodeURIComponent(workspace)}/environments/${encodeURIComponent(environmentId)}`,
|
|
703
|
-
body,
|
|
704
|
-
parseResponseBody: true,
|
|
705
|
-
});
|
|
706
|
-
}
|
|
707
|
-
async deleteEnvironment(workspace, environmentId) {
|
|
708
|
-
return await this.request({
|
|
709
|
-
method: 'DELETE',
|
|
710
|
-
path: `/workspaces/${encodeURIComponent(workspace)}/environments/${encodeURIComponent(environmentId)}`,
|
|
711
|
-
parseResponseBody: false,
|
|
712
|
-
});
|
|
713
|
-
}
|
|
714
|
-
async getEnvironmentByIdentifier(workspace, identifier, project) {
|
|
715
|
-
const q = {
|
|
716
|
-
environment: identifier,
|
|
717
|
-
};
|
|
718
|
-
if (project)
|
|
719
|
-
q.project = project;
|
|
720
|
-
return await this.getResourceByIdentifier(workspace, q);
|
|
721
|
-
}
|
|
722
566
|
// Sandbox methods
|
|
723
567
|
async createSandbox(workspace, project, body) {
|
|
724
568
|
return await this.request({
|
package/distTs/src/cliIndex.js
CHANGED
|
@@ -24,8 +24,6 @@ const artifact_1 = __importDefault(require("./command/artifact"));
|
|
|
24
24
|
const api_1 = __importDefault(require("./command/api"));
|
|
25
25
|
const domain_1 = __importDefault(require("./command/domain"));
|
|
26
26
|
const distro_1 = __importDefault(require("./command/distro"));
|
|
27
|
-
const target_1 = __importDefault(require("./command/target"));
|
|
28
|
-
const environment_1 = __importDefault(require("./command/environment"));
|
|
29
27
|
const register_1 = __importDefault(require("./command/register"));
|
|
30
28
|
const mcp_1 = __importDefault(require("./command/mcp"));
|
|
31
29
|
function cliIndex() {
|
|
@@ -49,8 +47,6 @@ function cliIndex() {
|
|
|
49
47
|
program.addCommand(sandbox_1.default);
|
|
50
48
|
program.addCommand(domain_1.default);
|
|
51
49
|
program.addCommand(distro_1.default);
|
|
52
|
-
program.addCommand(target_1.default);
|
|
53
|
-
program.addCommand(environment_1.default);
|
|
54
50
|
program.addCommand(login_1.default);
|
|
55
51
|
program.addCommand(register_1.default);
|
|
56
52
|
program.addCommand(whoami_1.default);
|
|
@@ -22,7 +22,10 @@ commandArtifactList.action(async (options) => {
|
|
|
22
22
|
const response = await client.getArtifacts(workspace, scope === distro_1.SCOPE.PROJECT ? project : null);
|
|
23
23
|
const artifacts = response.artifacts || [];
|
|
24
24
|
if (options.format === 'json') {
|
|
25
|
-
|
|
25
|
+
const filtered = scope === distro_1.SCOPE.PROJECT
|
|
26
|
+
? artifacts.filter((a) => a.scope !== distro_1.SCOPE.WORKSPACE)
|
|
27
|
+
: artifacts;
|
|
28
|
+
output_1.default.json(filtered);
|
|
26
29
|
}
|
|
27
30
|
else {
|
|
28
31
|
if (artifacts.length === 0) {
|
|
@@ -30,6 +33,8 @@ commandArtifactList.action(async (options) => {
|
|
|
30
33
|
}
|
|
31
34
|
const data = [['NAME', 'IDENTIFIER', 'TYPE', 'URL']];
|
|
32
35
|
for (const artifact of artifacts) {
|
|
36
|
+
if (scope === distro_1.SCOPE.PROJECT && artifact.scope === distro_1.SCOPE.WORKSPACE)
|
|
37
|
+
continue;
|
|
33
38
|
data.push([
|
|
34
39
|
artifact.name,
|
|
35
40
|
artifact.identifier,
|
|
@@ -77,7 +77,7 @@ commandDistroRouteUpdate.action(async (identifier, routeId, options) => {
|
|
|
77
77
|
changed = true;
|
|
78
78
|
}
|
|
79
79
|
if (!changed) {
|
|
80
|
-
output_1.default.exitError(texts_1.
|
|
80
|
+
output_1.default.exitError(texts_1.ERR_COMMAND_ROUTE_NO_UPDATE);
|
|
81
81
|
}
|
|
82
82
|
const result = await client.updateRoute(workspace, scope === distro_1.SCOPE.PROJECT ? project : null, data.distribution_id, routeId, body);
|
|
83
83
|
output_1.default.id(result.id);
|
|
@@ -27,6 +27,14 @@ commandDistroUpdate.action(async (identifier, options) => {
|
|
|
27
27
|
const workspace = input_1.default.restApiWorkspace(options.workspace);
|
|
28
28
|
const project = input_1.default.restApiProject(options.project, true);
|
|
29
29
|
const scope = input_1.default.scope(project, options.scope);
|
|
30
|
+
const client = input_1.default.restApiTokenClient();
|
|
31
|
+
const data = await client.getDistributionByIdentifier(workspace, scope === distro_1.SCOPE.PROJECT ? project : null, identifier);
|
|
32
|
+
if (!data || !data.domain) {
|
|
33
|
+
output_1.default.exitError(texts_1.ERR_WORKSPACE_NOT_FOUND);
|
|
34
|
+
}
|
|
35
|
+
if (!data || !data.distribution_id) {
|
|
36
|
+
output_1.default.exitError(texts_1.ERR_COMMAND_DISTRO_NOT_FOUND);
|
|
37
|
+
}
|
|
30
38
|
const body = {};
|
|
31
39
|
let changed = false;
|
|
32
40
|
if (options.name) {
|
|
@@ -46,15 +54,7 @@ commandDistroUpdate.action(async (identifier, options) => {
|
|
|
46
54
|
changed = true;
|
|
47
55
|
}
|
|
48
56
|
if (!changed) {
|
|
49
|
-
output_1.default.exitError(texts_1.
|
|
50
|
-
}
|
|
51
|
-
const client = input_1.default.restApiTokenClient();
|
|
52
|
-
const data = await client.getDistributionByIdentifier(workspace, scope === distro_1.SCOPE.PROJECT ? project : null, identifier);
|
|
53
|
-
if (!data || !data.domain) {
|
|
54
|
-
output_1.default.exitError(texts_1.ERR_WORKSPACE_NOT_FOUND);
|
|
55
|
-
}
|
|
56
|
-
if (!data || !data.distribution_id) {
|
|
57
|
-
output_1.default.exitError(texts_1.ERR_COMMAND_DISTRO_NOT_FOUND);
|
|
57
|
+
output_1.default.exitError(texts_1.ERR_COMMAND_DISTRO_NO_UPDATE);
|
|
58
58
|
}
|
|
59
59
|
const result = await client.updateDistribution(workspace, scope === distro_1.SCOPE.PROJECT ? project : null, data.distribution_id, body);
|
|
60
60
|
output_1.default.identifier(result.identifier);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const cfg_1 = __importDefault(require("../../tunnel/cfg"));
|
|
7
|
+
const output_1 = __importDefault(require("../../output"));
|
|
8
|
+
const texts_1 = require("../../texts");
|
|
9
|
+
const utils_1 = require("../../utils");
|
|
10
|
+
const commandProjectGet = (0, utils_1.newCommand)('get', texts_1.DESC_COMMAND_PROJECT_GET);
|
|
11
|
+
commandProjectGet.action(async () => {
|
|
12
|
+
const project = cfg_1.default.getProject();
|
|
13
|
+
if (!project) {
|
|
14
|
+
output_1.default.exitError(texts_1.TXT_PROJECT_NONE);
|
|
15
|
+
}
|
|
16
|
+
output_1.default.exitNormal(project);
|
|
17
|
+
});
|
|
18
|
+
exports.default = commandProjectGet;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const cfg_1 = __importDefault(require("../../tunnel/cfg"));
|
|
7
|
+
const output_1 = __importDefault(require("../../output"));
|
|
8
|
+
const texts_1 = require("../../texts");
|
|
9
|
+
const utils_1 = require("../../utils");
|
|
10
|
+
const input_1 = __importDefault(require("../../input"));
|
|
11
|
+
const commandProjectSet = (0, utils_1.newCommand)('set', texts_1.DESC_COMMAND_PROJECT_SET);
|
|
12
|
+
commandProjectSet.option('-w, --workspace <domain>', texts_1.OPTION_REST_API_WORKSPACE);
|
|
13
|
+
commandProjectSet.argument('[project]', texts_1.ARG_COMMAND_PROJECT_NAME);
|
|
14
|
+
commandProjectSet.action(async (project, options) => {
|
|
15
|
+
output_1.default.handleSignals();
|
|
16
|
+
const workspace = input_1.default.restApiWorkspace(options.workspace);
|
|
17
|
+
const client = input_1.default.restApiTokenClient();
|
|
18
|
+
if (project) {
|
|
19
|
+
await client.getProject(workspace, project);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
const response = await client.getProjects(workspace);
|
|
23
|
+
project = await output_1.default.selectProject(response.projects);
|
|
24
|
+
}
|
|
25
|
+
cfg_1.default.setProject(project);
|
|
26
|
+
if (!project)
|
|
27
|
+
output_1.default.exitSuccess(texts_1.TXT_PROJECT_SET_CLEARED);
|
|
28
|
+
else
|
|
29
|
+
output_1.default.exitSuccess((0, texts_1.TXT_PROJECT_SET_SUCCESS)(project));
|
|
30
|
+
});
|
|
31
|
+
exports.default = commandProjectSet;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const utils_1 = require("../../../utils");
|
|
7
|
+
const texts_1 = require("../../../texts");
|
|
8
|
+
const input_1 = __importDefault(require("../../../input"));
|
|
9
|
+
const output_1 = __importDefault(require("../../../output"));
|
|
10
|
+
const commandSandboxGetYaml = (0, utils_1.newCommand)('yaml', texts_1.DESC_COMMAND_SANDBOX_GET_YAML);
|
|
11
|
+
commandSandboxGetYaml.hideVersionUpdate = true;
|
|
12
|
+
commandSandboxGetYaml.alias('yml');
|
|
13
|
+
commandSandboxGetYaml.option('-w, --workspace <domain>', texts_1.OPTION_REST_API_WORKSPACE);
|
|
14
|
+
commandSandboxGetYaml.option('-p, --project <name>', texts_1.OPTION_REST_API_PROJECT);
|
|
15
|
+
commandSandboxGetYaml.argument('<identifier>', texts_1.OPTION_SANDBOX_IDENTIFIER);
|
|
16
|
+
commandSandboxGetYaml.action(async (identifier, options) => {
|
|
17
|
+
const workspace = input_1.default.restApiWorkspace(options.workspace);
|
|
18
|
+
const project = input_1.default.restApiProject(options.project);
|
|
19
|
+
const client = input_1.default.restApiTokenClient();
|
|
20
|
+
let result = await client.listSandboxes(workspace, project);
|
|
21
|
+
const sandboxes = result.sandboxes || [];
|
|
22
|
+
const found = sandboxes.find((s) => s.identifier === identifier);
|
|
23
|
+
if (!found) {
|
|
24
|
+
output_1.default.exitError(texts_1.ERR_SANDBOX_NOT_FOUND);
|
|
25
|
+
}
|
|
26
|
+
const sandboxId = found.id;
|
|
27
|
+
result = await client.getSandboxYaml(workspace, sandboxId);
|
|
28
|
+
output_1.default.exitNormal(Buffer.from(result.yaml, 'base64').toString('utf8'));
|
|
29
|
+
});
|
|
30
|
+
exports.default = commandSandboxGetYaml;
|