@daocloud-cli/dce 0.1.0-rc.7
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/README.md +267 -0
- package/checksums.txt +4 -0
- package/package.json +32 -0
- package/scripts/install.js +145 -0
- package/scripts/run.js +30 -0
package/README.md
ADDED
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
# daocloud-skills
|
|
2
|
+
|
|
3
|
+
A generated CLI and AI skill package for DaoCloud Enterprise (DCE). It wraps the DCE REST API into a `dce` command-line tool and bundles a companion skill for AI agents.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
- **`dce`** — a CLI generated from DCE OpenAPI specs (global-management, container-management). Supports API discovery, search, and execution with built-in auth management.
|
|
8
|
+
- **`skills/dce`** — an AI agent skill that teaches agents how to use `dce` safely.
|
|
9
|
+
|
|
10
|
+
Currently supported products:
|
|
11
|
+
|
|
12
|
+
| Module | Description |
|
|
13
|
+
|---|---|
|
|
14
|
+
| `global-management` | Global Management — users, groups, workspaces, roles, audit |
|
|
15
|
+
| `container-management` | Container Management — clusters, namespaces, workloads, storage |
|
|
16
|
+
| `insight` | Insight — observability, metrics, alerting, and related operations |
|
|
17
|
+
|
|
18
|
+
## Prerequisites
|
|
19
|
+
|
|
20
|
+
- Go 1.25+
|
|
21
|
+
- Git (for spec sync)
|
|
22
|
+
- Docker with [buildx](https://docs.docker.com/buildx/working-with-buildx/) (for container image builds)
|
|
23
|
+
|
|
24
|
+
## Quick Start
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# Sync OpenAPI specs and regenerate code
|
|
28
|
+
make bootstrap
|
|
29
|
+
|
|
30
|
+
# Build dce
|
|
31
|
+
make build
|
|
32
|
+
|
|
33
|
+
# Install dce and symlink skill for local development
|
|
34
|
+
make dev
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The `make dev` target installs `dce` to `/usr/local/bin` and symlinks `skills/dce` into `~/.agents/skills/dce` for live local development in an AI agent runtime.
|
|
38
|
+
|
|
39
|
+
## Install the Skill
|
|
40
|
+
|
|
41
|
+
Install the `dce` skill globally:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npx skills add daocloud/daocloud-skills -g
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
For non-interactive installs, add confirmation flags:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
npx -y skills add daocloud/daocloud-skills -g -y
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The `-g` flag installs the skill into the selected agent's user-level skills directory, so it is available across projects. Omit `-g` if you want to install the skill only for the current project.
|
|
54
|
+
|
|
55
|
+
This installs the skill only. The skill helps an AI agent use `dce`, but it does not install the `dce` CLI. Install the CLI separately before running DCE operations.
|
|
56
|
+
|
|
57
|
+
### Install for a Specific Agent
|
|
58
|
+
|
|
59
|
+
Use `--agent` to install the `dce` skill for a specific AI coding agent. Common client targets include:
|
|
60
|
+
|
|
61
|
+
**Claude Code**
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
npx skills add daocloud/daocloud-skills -g --skill dce --agent claude-code
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**Codex**
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
npx skills add daocloud/daocloud-skills -g --skill dce --agent codex
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**Cursor**
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
npx skills add daocloud/daocloud-skills -g --skill dce --agent cursor
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Use `--agent` more than once to install the same skill into multiple agents:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
npx skills add daocloud/daocloud-skills -g \
|
|
83
|
+
--skill dce \
|
|
84
|
+
--agent claude-code \
|
|
85
|
+
--agent codex \
|
|
86
|
+
--agent cursor
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
This installs the skill from the repository's default branch. To inspect available skills before installing:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
npx skills add daocloud/daocloud-skills --list
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
To uninstall the global `dce` skill, use `remove` with the same agent target:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
npx skills remove -g dce --agent codex
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
After installation, open a new agent session and ask it to use the `dce` skill for DCE operations, for example:
|
|
102
|
+
|
|
103
|
+
```text
|
|
104
|
+
Use the dce skill to list DCE clusters.
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Install the CLI
|
|
108
|
+
|
|
109
|
+
The recommended way is via npm:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
npm install -g @daocloud-cli/dce
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Or run on demand without a global install:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
npx @daocloud-cli/dce --help
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
The npm package downloads the matching prebuilt binary from GitHub Releases on install and verifies it against `checksums.txt`. Supported platforms: `darwin`/`linux` on `amd64`/`arm64`, Node.js >= 16.
|
|
122
|
+
|
|
123
|
+
Alternatively, download a prebuilt archive from GitHub Releases directly:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
VERSION=v0.1.0-rc.6
|
|
127
|
+
OS=darwin
|
|
128
|
+
ARCH=amd64
|
|
129
|
+
PKG="dce-${VERSION}-${OS}-${ARCH}"
|
|
130
|
+
|
|
131
|
+
curl -fL "https://github.com/DaoCloud/daocloud-skills/releases/download/${VERSION}/${PKG}.tar.gz" -o dce.tar.gz
|
|
132
|
+
tar -xzf dce.tar.gz
|
|
133
|
+
sudo install -m 0755 "${PKG}/dce" /usr/local/bin/dce
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Use `OS=darwin` for macOS and `OS=linux` for Linux. Use `ARCH=arm64` for Apple Silicon or ARM64 Linux, and `ARCH=amd64` for Intel macOS or x86_64 Linux.
|
|
137
|
+
|
|
138
|
+
Verify the CLI is available:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
dce --help
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
For source builds from this repository:
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
make build
|
|
148
|
+
sudo cp bin/dce /usr/local/bin/dce
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
For local development, use `make dev` to build the CLI, copy it to `/usr/local/bin/dce`, and symlink the local skill directory:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
make dev
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Usage
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
# Log in to a DCE instance
|
|
161
|
+
dce auth login --hostname https://<dce-host>
|
|
162
|
+
|
|
163
|
+
# Browse available commands
|
|
164
|
+
dce commands --json
|
|
165
|
+
|
|
166
|
+
# Search for a command by intent
|
|
167
|
+
dce search "list clusters" --json
|
|
168
|
+
|
|
169
|
+
# Inspect a command before executing
|
|
170
|
+
dce commands show container-management cluster list-clusters --json
|
|
171
|
+
|
|
172
|
+
# Execute a command
|
|
173
|
+
dce container-management cluster list-clusters -o json
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## Container Image
|
|
177
|
+
|
|
178
|
+
The image bundles the `dce` binary and the `skills/dce` directory under `/app/`, intended for use as a Kubernetes init container to distribute the tooling into a shared volume.
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
# Build multi-arch image locally
|
|
182
|
+
make image
|
|
183
|
+
|
|
184
|
+
# Build and push to registry
|
|
185
|
+
make image-push IMAGE_REPO=registry.example.com/dce IMAGE_TAG=v1.0.0
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Default values: `IMAGE_REPO=daocloud/dce`, `IMAGE_TAG=latest`.
|
|
189
|
+
|
|
190
|
+
### Init Container Example
|
|
191
|
+
|
|
192
|
+
```yaml
|
|
193
|
+
initContainers:
|
|
194
|
+
- name: install-dce
|
|
195
|
+
image: daocloud/dce:latest
|
|
196
|
+
command:
|
|
197
|
+
- sh
|
|
198
|
+
- -c
|
|
199
|
+
- |
|
|
200
|
+
cp /app/dce /target/bin/dce
|
|
201
|
+
cp -r /app/skills/dce /target/.agents/skills/dce
|
|
202
|
+
volumeMounts:
|
|
203
|
+
- name: tools
|
|
204
|
+
mountPath: /target
|
|
205
|
+
|
|
206
|
+
volumes:
|
|
207
|
+
- name: tools
|
|
208
|
+
emptyDir: {}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
After the init container completes, the shared volume contains:
|
|
212
|
+
|
|
213
|
+
- `/target/bin/dce` — CLI binary
|
|
214
|
+
- `/target/.agents/skills/dce/` — AI agent skill
|
|
215
|
+
|
|
216
|
+
## Development
|
|
217
|
+
|
|
218
|
+
| Target | Description |
|
|
219
|
+
|---|---|
|
|
220
|
+
| `make bootstrap` | Sync specs + regenerate all code |
|
|
221
|
+
| `make specsync` | Pull latest OpenAPI specs from upstream |
|
|
222
|
+
| `make codegen` | Regenerate Go code and skill references from specs |
|
|
223
|
+
| `make sync-one SOURCE=<name>` | Sync and regenerate a single source (e.g. `ghippo`) |
|
|
224
|
+
| `make build` | Build `bin/dce` |
|
|
225
|
+
| `make image` | Build multi-arch image locally (`linux/amd64`, `linux/arm64`) |
|
|
226
|
+
| `make image-push` | Build and push multi-arch image to registry |
|
|
227
|
+
| `make dev` | Build, install, and symlink skill for local debugging |
|
|
228
|
+
| `make dev-clean` | Remove installed binary and skill symlink |
|
|
229
|
+
| `make clean` | Remove `.cache` and `bin` |
|
|
230
|
+
|
|
231
|
+
## Project Structure
|
|
232
|
+
|
|
233
|
+
```
|
|
234
|
+
.
|
|
235
|
+
├── cli.yaml # CLI name and auth config
|
|
236
|
+
├── specs/sources.yaml # OpenAPI source definitions (pinned commits)
|
|
237
|
+
├── internal/
|
|
238
|
+
│ ├── generated/ # Generated Go command modules (do not edit)
|
|
239
|
+
│ └── overlay/ # Per-source field overrides for codegen
|
|
240
|
+
├── skills/dce/ # AI agent skill (SKILL.md + references)
|
|
241
|
+
├── docs/ # Developer guides
|
|
242
|
+
├── cmd/dce/main.go # CLI entrypoint
|
|
243
|
+
└── doc.go # Embeds cli.yaml for use by main
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## Guides
|
|
247
|
+
|
|
248
|
+
- [Adding a new product](docs/add-new-product.md) — step-by-step guide for onboarding a new DCE product (spec source, overlay, codegen, verification)
|
|
249
|
+
|
|
250
|
+
## How It Works
|
|
251
|
+
|
|
252
|
+
1. **`specsync`** clones the pinned commit of `daocloud-api-docs` and extracts the OpenAPI JSON files into `.cache/specs-sync/`.
|
|
253
|
+
2. **`codegen`** reads each spec, applies the overlay from `internal/overlay/<source>.yaml`, and emits:
|
|
254
|
+
- Go cobra subcommands under `internal/generated/<source>/`
|
|
255
|
+
- A command index at `skills/dce/references/modules/<source>.md`
|
|
256
|
+
- An updated `internal/generated/modules_gen.go` that mounts all modules
|
|
257
|
+
3. **`go build`** compiles everything into a single static binary `bin/dce`.
|
|
258
|
+
|
|
259
|
+
Overlay files are the only place where human-maintained configuration lives — everything else is generated and should not be edited by hand.
|
|
260
|
+
|
|
261
|
+
## Updating a Pinned Spec
|
|
262
|
+
|
|
263
|
+
Update the `pinned_tag` for the relevant source in `specs/sources.yaml`, then run:
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
make sync-one SOURCE=<name>
|
|
267
|
+
```
|
package/checksums.txt
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
a324997b6acdb1fd01a92e31d024f62bac979e10d0c5057fe19ad3639eec67fe dce-v0.1.0-rc.7-darwin-amd64.tar.gz
|
|
2
|
+
89214cdfa1f66b34a961932bc2ad55645b5247d742f8a85dd7780f7954facb36 dce-v0.1.0-rc.7-darwin-arm64.tar.gz
|
|
3
|
+
d65367f8ad0d133815914cbdb36fe1b0b46930cf1fabae280b189395014aa5d1 dce-v0.1.0-rc.7-linux-amd64.tar.gz
|
|
4
|
+
60c09746187eaf0f865761e7a36ac8cab6a07c1619b37f652b4897c32c93ca0a dce-v0.1.0-rc.7-linux-arm64.tar.gz
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@daocloud-cli/dce",
|
|
3
|
+
"version": "0.1.0-rc.7",
|
|
4
|
+
"description": "DaoCloud dce CLI",
|
|
5
|
+
"bin": {
|
|
6
|
+
"dce": "scripts/run.js"
|
|
7
|
+
},
|
|
8
|
+
"scripts": {
|
|
9
|
+
"postinstall": "node scripts/install.js"
|
|
10
|
+
},
|
|
11
|
+
"os": [
|
|
12
|
+
"darwin",
|
|
13
|
+
"linux"
|
|
14
|
+
],
|
|
15
|
+
"cpu": [
|
|
16
|
+
"x64",
|
|
17
|
+
"arm64"
|
|
18
|
+
],
|
|
19
|
+
"engines": {
|
|
20
|
+
"node": ">=16"
|
|
21
|
+
},
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "git+https://github.com/DaoCloud/daocloud-skills.git"
|
|
25
|
+
},
|
|
26
|
+
"license": "Apache-2.0",
|
|
27
|
+
"files": [
|
|
28
|
+
"scripts/install.js",
|
|
29
|
+
"scripts/run.js",
|
|
30
|
+
"checksums.txt"
|
|
31
|
+
]
|
|
32
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
const { execFileSync } = require("child_process");
|
|
4
|
+
const os = require("os");
|
|
5
|
+
const crypto = require("crypto");
|
|
6
|
+
|
|
7
|
+
const VERSION = require("../package.json").version;
|
|
8
|
+
const REPO = "DaoCloud/daocloud-skills";
|
|
9
|
+
const NAME = "dce";
|
|
10
|
+
const ALLOWED_HOSTS = new Set([
|
|
11
|
+
"github.com",
|
|
12
|
+
"objects.githubusercontent.com",
|
|
13
|
+
]);
|
|
14
|
+
|
|
15
|
+
const PLATFORM_MAP = {
|
|
16
|
+
darwin: "darwin",
|
|
17
|
+
linux: "linux",
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const ARCH_MAP = {
|
|
21
|
+
x64: "amd64",
|
|
22
|
+
arm64: "arm64",
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const platform = PLATFORM_MAP[process.platform];
|
|
26
|
+
const arch = ARCH_MAP[process.arch];
|
|
27
|
+
|
|
28
|
+
const TAG = `v${VERSION}`;
|
|
29
|
+
const PKG_NAME = `${NAME}-${TAG}-${platform}-${arch}`;
|
|
30
|
+
const archiveName = `${PKG_NAME}.tar.gz`;
|
|
31
|
+
const GITHUB_URL = `https://github.com/${REPO}/releases/download/${TAG}/${archiveName}`;
|
|
32
|
+
|
|
33
|
+
const pkgRoot = path.join(__dirname, "..");
|
|
34
|
+
const binDir = path.join(pkgRoot, "bin");
|
|
35
|
+
const dest = path.join(binDir, NAME);
|
|
36
|
+
|
|
37
|
+
function assertAllowedHost(url) {
|
|
38
|
+
const { hostname } = new URL(url);
|
|
39
|
+
if (!ALLOWED_HOSTS.has(hostname)) {
|
|
40
|
+
throw new Error(`Download host not allowed: ${hostname}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function download(url, destPath) {
|
|
45
|
+
assertAllowedHost(url);
|
|
46
|
+
execFileSync(
|
|
47
|
+
"curl",
|
|
48
|
+
[
|
|
49
|
+
"--fail", "--location", "--silent", "--show-error",
|
|
50
|
+
"--connect-timeout", "10", "--max-time", "120",
|
|
51
|
+
"--max-redirs", "3",
|
|
52
|
+
"--output", destPath,
|
|
53
|
+
url,
|
|
54
|
+
],
|
|
55
|
+
{ stdio: ["ignore", "ignore", "pipe"] }
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function getExpectedChecksum(name) {
|
|
60
|
+
const checksumsPath = path.join(pkgRoot, "checksums.txt");
|
|
61
|
+
if (!fs.existsSync(checksumsPath)) {
|
|
62
|
+
throw new Error(
|
|
63
|
+
"[SECURITY] checksums.txt not found; refusing to install without integrity verification"
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
const content = fs.readFileSync(checksumsPath, "utf8");
|
|
67
|
+
for (const line of content.split("\n")) {
|
|
68
|
+
const trimmed = line.trim();
|
|
69
|
+
if (!trimmed) continue;
|
|
70
|
+
const idx = trimmed.indexOf(" ");
|
|
71
|
+
if (idx === -1) continue;
|
|
72
|
+
const hash = trimmed.slice(0, idx);
|
|
73
|
+
const entry = trimmed.slice(idx + 2);
|
|
74
|
+
if (entry === name) return hash;
|
|
75
|
+
}
|
|
76
|
+
throw new Error(`Checksum entry not found for ${name}`);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function verifyChecksum(archivePath, expectedHash) {
|
|
80
|
+
const hash = crypto.createHash("sha256");
|
|
81
|
+
const fd = fs.openSync(archivePath, "r");
|
|
82
|
+
try {
|
|
83
|
+
const buf = Buffer.alloc(64 * 1024);
|
|
84
|
+
let bytesRead;
|
|
85
|
+
while ((bytesRead = fs.readSync(fd, buf, 0, buf.length, null)) > 0) {
|
|
86
|
+
hash.update(buf.subarray(0, bytesRead));
|
|
87
|
+
}
|
|
88
|
+
} finally {
|
|
89
|
+
fs.closeSync(fd);
|
|
90
|
+
}
|
|
91
|
+
const actual = hash.digest("hex");
|
|
92
|
+
if (actual.toLowerCase() !== expectedHash.toLowerCase()) {
|
|
93
|
+
throw new Error(
|
|
94
|
+
`[SECURITY] Checksum mismatch for ${path.basename(archivePath)}: expected ${expectedHash} but got ${actual}`
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function install() {
|
|
100
|
+
fs.mkdirSync(binDir, { recursive: true });
|
|
101
|
+
|
|
102
|
+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), `${NAME}-`));
|
|
103
|
+
const archivePath = path.join(tmpDir, archiveName);
|
|
104
|
+
|
|
105
|
+
try {
|
|
106
|
+
download(GITHUB_URL, archivePath);
|
|
107
|
+
|
|
108
|
+
const expected = getExpectedChecksum(archiveName);
|
|
109
|
+
verifyChecksum(archivePath, expected);
|
|
110
|
+
|
|
111
|
+
execFileSync("tar", ["-xzf", archivePath, "-C", tmpDir], { stdio: "ignore" });
|
|
112
|
+
|
|
113
|
+
const extractedRoot = path.join(tmpDir, PKG_NAME);
|
|
114
|
+
const extractedBinary = path.join(extractedRoot, NAME);
|
|
115
|
+
|
|
116
|
+
fs.copyFileSync(extractedBinary, dest);
|
|
117
|
+
fs.chmodSync(dest, 0o755);
|
|
118
|
+
|
|
119
|
+
console.log(`${NAME} ${TAG} installed successfully`);
|
|
120
|
+
} finally {
|
|
121
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (require.main === module) {
|
|
126
|
+
if (!platform || !arch) {
|
|
127
|
+
console.error(`Unsupported platform: ${process.platform}-${process.arch}`);
|
|
128
|
+
process.exit(1);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Under `npx`, postinstall fires but the binary is not yet needed —
|
|
132
|
+
// run.js triggers install() on demand with DCE_RUN=1 set.
|
|
133
|
+
const isNpxPostinstall =
|
|
134
|
+
process.env.npm_command === "exec" && !process.env.DCE_RUN;
|
|
135
|
+
if (isNpxPostinstall) process.exit(0);
|
|
136
|
+
|
|
137
|
+
try {
|
|
138
|
+
install();
|
|
139
|
+
} catch (err) {
|
|
140
|
+
console.error(`Failed to install ${NAME}:`, err.message);
|
|
141
|
+
process.exit(1);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
module.exports = { getExpectedChecksum, verifyChecksum, assertAllowedHost };
|
package/scripts/run.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { execFileSync } = require("child_process");
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
|
|
7
|
+
const bin = path.join(__dirname, "..", "bin", "dce");
|
|
8
|
+
const args = process.argv.slice(2);
|
|
9
|
+
|
|
10
|
+
if (!fs.existsSync(bin)) {
|
|
11
|
+
try {
|
|
12
|
+
execFileSync(process.execPath, [path.join(__dirname, "install.js")], {
|
|
13
|
+
stdio: "inherit",
|
|
14
|
+
env: { ...process.env, DCE_RUN: "true" },
|
|
15
|
+
});
|
|
16
|
+
} catch (_) {
|
|
17
|
+
console.error(
|
|
18
|
+
`\nFailed to auto-install dce binary.\n` +
|
|
19
|
+
`Run the install script manually:\n` +
|
|
20
|
+
` node "${path.join(__dirname, "install.js")}"\n`
|
|
21
|
+
);
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
execFileSync(bin, args, { stdio: "inherit" });
|
|
28
|
+
} catch (e) {
|
|
29
|
+
process.exit(e.status || 1);
|
|
30
|
+
}
|