@zergai/cyberdeck 0.1.0-beta.1
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/COMMERCIAL-LICENSING.md +27 -0
- package/LICENSE.md +375 -0
- package/NOTICE +17 -0
- package/README.md +284 -0
- package/THIRD_PARTY_NOTICES.md +14 -0
- package/dist/automation.js +161 -0
- package/dist/client.js +493 -0
- package/dist/commands/auth.js +193 -0
- package/dist/commands/automation.js +164 -0
- package/dist/commands/decks.js +310 -0
- package/dist/commands/fleet.js +393 -0
- package/dist/commands/oracle.js +143 -0
- package/dist/commands/portfolio.js +19 -0
- package/dist/commands/scenarios.js +207 -0
- package/dist/commands/sdk.js +229 -0
- package/dist/commands/workbench.js +225 -0
- package/dist/config.js +48 -0
- package/dist/fleet.js +88 -0
- package/dist/index.js +43 -0
- package/dist/portfolio.js +148 -0
- package/dist/runtime.js +165 -0
- package/dist/vendors.js +65 -0
- package/package.json +51 -0
package/README.md
ADDED
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
# zerg-cyberdeck
|
|
2
|
+
|
|
3
|
+
> **License notice:** This package is source-available, not open source. Free
|
|
4
|
+
> company use is limited to purpose-bound evaluation. Commercial development,
|
|
5
|
+
> ongoing company engineering, customer work, and other Commercial Use require
|
|
6
|
+
> a separate commercial license. By exercising a permission in the package
|
|
7
|
+
> [license](./LICENSE.md), you accept its conditions; a separate signed agreement
|
|
8
|
+
> controls any commercial rights.
|
|
9
|
+
|
|
10
|
+
`zerg-cyberdeck` installs the `zcd` command-line client for Zerg CyberDeck. It
|
|
11
|
+
manages workspace-scoped clone decks, checks running clone and Zerg services,
|
|
12
|
+
and asks the CyberDeck server to run its deployed SDK/API conformance suites.
|
|
13
|
+
|
|
14
|
+
This beta requires Node.js 22 or later.
|
|
15
|
+
|
|
16
|
+
## Install
|
|
17
|
+
|
|
18
|
+
The ZergAI organization distribution is `@zergai/cyberdeck@next`. After the
|
|
19
|
+
scoped release is published, use `npm install --global @zergai/cyberdeck@next`.
|
|
20
|
+
It provides the same `zcd` command and license as the legacy package below.
|
|
21
|
+
Install only one distribution globally because both provide `zcd`.
|
|
22
|
+
|
|
23
|
+
Until the first stable release, install the `next` channel:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install --global zerg-cyberdeck@next
|
|
27
|
+
zcd --version
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Sign in
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
zcd login
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The CLI prints a short user code and opens the CyberDeck authorization page.
|
|
37
|
+
Sign in through the normal browser flow, choose one of your workspaces, and
|
|
38
|
+
approve the device. The resulting 30-day personal token is bound to that
|
|
39
|
+
workspace and stored in a mode-`0600` config file.
|
|
40
|
+
|
|
41
|
+
Useful alternatives:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
zcd login --url https://your-cyberdeck.example --workspace "Blue Team"
|
|
45
|
+
zcd whoami
|
|
46
|
+
zcd logout
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
For non-interactive automation, set `ZERGCYBERDECK_TOKEN` to an independently
|
|
50
|
+
issued scoped token. `ZERGCYBERDECK_BASE_URL` changes the server, and
|
|
51
|
+
`ZERGCYBERDECK_CONFIG_DIR` isolates the local config directory.
|
|
52
|
+
|
|
53
|
+
## Common commands
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# The server is authoritative for available targets and conformance support.
|
|
57
|
+
zcd catalog
|
|
58
|
+
|
|
59
|
+
# Create a deck and start explicitly selected clones.
|
|
60
|
+
zcd up --clones zlunk,zokta --name "SDK check"
|
|
61
|
+
|
|
62
|
+
# Or create every unique target from the authoritative server catalog. Clone
|
|
63
|
+
# starts are admitted through one durable, bounded server operation.
|
|
64
|
+
zcd up --all --name "Full connector range"
|
|
65
|
+
|
|
66
|
+
zcd ls
|
|
67
|
+
zcd status --deck <deck-id>
|
|
68
|
+
zcd diagnose --deck <deck-id> --tail 100
|
|
69
|
+
zcd check --deck <deck-id>
|
|
70
|
+
zcd seed --deck <deck-id> --reset
|
|
71
|
+
|
|
72
|
+
# Start and poll server-side SDK/API conformance; reports remain local.
|
|
73
|
+
zcd sdk --deck <deck-id> --vendor zlunk
|
|
74
|
+
|
|
75
|
+
zcd down --deck <deck-id> --yes
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Scenarios and templates
|
|
79
|
+
|
|
80
|
+
The `scenario` command manages the same workspace-scoped, versioned definitions
|
|
81
|
+
as the CyberDeck workbench. Draft updates use optimistic versions, and published
|
|
82
|
+
revisions remain immutable.
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
# Read the runnable scenario library and one canonical YAML draft.
|
|
86
|
+
zcd scenario list --json
|
|
87
|
+
zcd scenario show --id <scenario-id> --json
|
|
88
|
+
|
|
89
|
+
# Create, update, and publish a scenario from a local YAML document.
|
|
90
|
+
zcd scenario create --file scenario.yaml --json
|
|
91
|
+
zcd scenario update --id <scenario-id> --expected-version 1 --file scenario.yaml --json
|
|
92
|
+
zcd scenario publish --id <scenario-id> --expected-version 2 --json
|
|
93
|
+
|
|
94
|
+
# Manage reusable drill and company-template libraries through the same API.
|
|
95
|
+
zcd scenario list --kind drill-template --json
|
|
96
|
+
zcd scenario create --kind company-template --file company-template.yaml --json
|
|
97
|
+
|
|
98
|
+
# Lifecycle-admin operations are explicit and recoverable.
|
|
99
|
+
zcd scenario delete --id <scenario-id> --yes --json
|
|
100
|
+
zcd scenario restore --id <scenario-id> --json
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
`zcd up` removes duplicate target IDs while preserving first-seen order. It
|
|
104
|
+
preflights the selected clones and submits one idempotent fleet operation
|
|
105
|
+
instead of sending an unbounded burst of individual start requests. A blocked
|
|
106
|
+
control plane leaves the new deck intact for inspection and exits with code 2.
|
|
107
|
+
|
|
108
|
+
`zcd sdk --clones ...` may provision the clones you name. Review the selection
|
|
109
|
+
and the target CyberDeck before running it; clone environments consume compute.
|
|
110
|
+
The CLI does not bundle vendor SDKs or a local conformance runner.
|
|
111
|
+
|
|
112
|
+
## Automation and clone discovery
|
|
113
|
+
|
|
114
|
+
Inventory commands retain their human-readable output by default and expose a
|
|
115
|
+
stable, versioned form for scripts:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
zcd catalog --json
|
|
119
|
+
zcd ls --json
|
|
120
|
+
zcd ls --deck <deck-id> --json
|
|
121
|
+
zcd status --deck <deck-id> --json
|
|
122
|
+
zcd diagnose --deck <deck-id> --json
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Each JSON document has `"schemaVersion": 1`. Catalog targets may advertise a
|
|
126
|
+
non-secret `managedCredential` descriptor with its purpose, authorization
|
|
127
|
+
scheme/header, and display label. The purpose distinguishes vendor API tokens,
|
|
128
|
+
official SDK tokens, and application-console credentials without exposing the
|
|
129
|
+
credential itself. Older CyberDeck servers that omit this descriptor remain
|
|
130
|
+
supported.
|
|
131
|
+
|
|
132
|
+
Inspect one deployment by a unique vendor name or exact clone UUID:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
zcd inspect --deck <deck-id> --clone zlunk
|
|
136
|
+
zcd inspect --deck <deck-id> --clone <clone-uuid> --json
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
The inspection includes normalized runtime URLs and status, published Zerg
|
|
140
|
+
module fields, artifact qualification, and the non-secret credential hint. If
|
|
141
|
+
a deck contains multiple clones of the same vendor, pass a clone UUID.
|
|
142
|
+
|
|
143
|
+
Export the current canonical `GET /__sim/export` snapshot from one running
|
|
144
|
+
clone without handling its private simulation-control credential:
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
# Print a stable, schema-versioned envelope to stdout.
|
|
148
|
+
zcd dump --deck <deck-id> --clone zentinel-one
|
|
149
|
+
|
|
150
|
+
# Or write it to a mode-0600 JSON file.
|
|
151
|
+
zcd dump --deck <deck-id> --clone <clone-uuid> --out ./zentinel-one.json
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
The response includes the clone and deck identity, capture time, source byte
|
|
155
|
+
count, a canonical SHA-256 data hash, and the clone-native snapshot. The Deck
|
|
156
|
+
server scopes the request to the active workspace, fences the live deployment
|
|
157
|
+
generation, and never returns the runtime URL or simulation-control token.
|
|
158
|
+
|
|
159
|
+
## Review-gated QA oracles
|
|
160
|
+
|
|
161
|
+
An oracle set preserves the human-authored question and query separately from
|
|
162
|
+
the connector parameters that Codex proposes. Proposed parameters cannot be
|
|
163
|
+
executed until a reviewer approves them, and synthesized answers have a second
|
|
164
|
+
review gate before the baseline can be sealed.
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
# The draft JSON contains one immutable scenario-run or clone-dump subject and
|
|
168
|
+
# 1-100 questions. Each question carries 1-16 authored connector queries.
|
|
169
|
+
zcd oracle create --deck <deck-id> --file ./oracle-draft.json --json
|
|
170
|
+
|
|
171
|
+
# Codex runs in text-only mode and may only propose schema-valid parameters.
|
|
172
|
+
zcd oracle materialize --deck <deck-id> --id <oracle-id> --json
|
|
173
|
+
|
|
174
|
+
# Inspect the current immutable version, then submit a reviewed document with
|
|
175
|
+
# optimistic concurrency. Later execution/answer events use the same command.
|
|
176
|
+
zcd oracle show --deck <deck-id> --id <oracle-id> --json
|
|
177
|
+
zcd oracle transition --deck <deck-id> --id <oracle-id> \
|
|
178
|
+
--expected-version 3 --event approve_parameters --file ./reviewed.json --json
|
|
179
|
+
|
|
180
|
+
zcd oracle list --deck <deck-id> --json
|
|
181
|
+
zcd oracle export --deck <deck-id> --id <oracle-id> --out ./oracle.json
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
The server stores every version as a content-addressed immutable object and
|
|
185
|
+
keeps only its opaque object reference, byte count, content type, and SHA-256
|
|
186
|
+
digest in the database. `oracle export` writes a mode-`0600` file. The exported
|
|
187
|
+
artifact includes the stable oracle ID/version and public metadata but never an
|
|
188
|
+
object-storage key, connector credential, or simulation-control token.
|
|
189
|
+
|
|
190
|
+
Credential disclosure is a separate, explicit write-authorized POST action:
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
zcd credentials --deck <deck-id> --clone zlunk
|
|
194
|
+
zcd credentials --deck <deck-id> --clone zentinel-one
|
|
195
|
+
zcd credentials --deck <deck-id> --clone <clone-uuid> --json
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Successful credential output contains a secret and should not be logged.
|
|
199
|
+
Credential and runtime error payloads are redacted from stderr so a malformed
|
|
200
|
+
or failed server response cannot echo a token through CLI diagnostics.
|
|
201
|
+
|
|
202
|
+
## Fleet diagnostics and recovery
|
|
203
|
+
|
|
204
|
+
`status` and `diagnose` use the observational diagnostics API. Reading them
|
|
205
|
+
does not register routes, update clone rows, or otherwise reconcile runtime
|
|
206
|
+
state. Every clone receives an ordered result envelope even when an upstream
|
|
207
|
+
provider is unavailable.
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
# Inspect the entire deck or one clone. Vendor names must be unique in a deck;
|
|
211
|
+
# an exact clone UUID is always unambiguous.
|
|
212
|
+
zcd diagnose --deck <deck-id>
|
|
213
|
+
zcd diagnose --deck <deck-id> --clone zlunk --tail 200 --json
|
|
214
|
+
|
|
215
|
+
# Read logs without revealing clone credentials.
|
|
216
|
+
zcd logs --deck <deck-id> --clone zlunk --tail 200
|
|
217
|
+
zcd logs --deck <deck-id> --clone <clone-uuid> \
|
|
218
|
+
--since 2026-07-27T19:00:00.000Z --json
|
|
219
|
+
|
|
220
|
+
# Check admission separately, or start all/failed/one clone.
|
|
221
|
+
zcd preflight --deck <deck-id> --all
|
|
222
|
+
zcd start --deck <deck-id> --failed --wait --json
|
|
223
|
+
zcd start --deck <deck-id> --clone zlunk
|
|
224
|
+
|
|
225
|
+
# Recovery actions are bounded and return a result for every selected clone.
|
|
226
|
+
zcd stop --deck <deck-id> --all --json
|
|
227
|
+
zcd reset --deck <deck-id> --clone zlunk
|
|
228
|
+
zcd restart-runtime --deck <deck-id> --failed --wait
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
`restart-runtime` performs a controlled stop, waits for the observational
|
|
232
|
+
status to become stopped, and then submits a new durable start operation.
|
|
233
|
+
|
|
234
|
+
Fleet operation history is available independently of the current clone
|
|
235
|
+
projection:
|
|
236
|
+
|
|
237
|
+
```bash
|
|
238
|
+
zcd operations --deck <deck-id> --limit 20
|
|
239
|
+
zcd operation --deck <deck-id> --run <run-id> --json
|
|
240
|
+
zcd operation --deck <deck-id> --run <run-id> --retry-failed --wait
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
CLI exit codes are stable for automation:
|
|
244
|
+
|
|
245
|
+
- `0`: the command completed without clone failures.
|
|
246
|
+
- `1`: one or more clone actions or operation items failed.
|
|
247
|
+
- `2`: platform readiness blocked admission; no start operation was created.
|
|
248
|
+
|
|
249
|
+
Run `zcd <command> --help` for all options.
|
|
250
|
+
|
|
251
|
+
## Licensing
|
|
252
|
+
|
|
253
|
+
This package is source-available, not open source. Purpose-limited evaluation
|
|
254
|
+
and the specified personal, educational, research, and nonprofit uses are
|
|
255
|
+
available under the
|
|
256
|
+
[Zerg Source Available License 1.0](./LICENSE.md). Commercial production,
|
|
257
|
+
commercial development, for-profit internal use, managed services,
|
|
258
|
+
governmental operational use, and competing general-purpose platforms require
|
|
259
|
+
a separate signed license. See
|
|
260
|
+
[commercial licensing](./COMMERCIAL-LICENSING.md) or contact
|
|
261
|
+
licensing@zergai.com.
|
|
262
|
+
|
|
263
|
+
Third-party software remains under its own terms; see
|
|
264
|
+
[THIRD_PARTY_NOTICES.md](./THIRD_PARTY_NOTICES.md).
|
|
265
|
+
# Scenario execution and evidence
|
|
266
|
+
|
|
267
|
+
Use the same run API as the web workbench. A custom scenario must be published;
|
|
268
|
+
the server binds the run to its immutable revision and rechecks clone readiness.
|
|
269
|
+
|
|
270
|
+
```sh
|
|
271
|
+
zcd scenario run --deck <deck-id> --scenario <catalog-or-definition-id> --json
|
|
272
|
+
zcd scenario run --deck <deck-id> --scenario <id> --capture-evidence --reset-targets --seed repro-1 --json
|
|
273
|
+
zcd scenario runs --deck <deck-id> --json
|
|
274
|
+
zcd scenario run-show --deck <deck-id> --run <run-id> --json
|
|
275
|
+
zcd scenario run-control --deck <deck-id> --run <run-id> --action pause --json
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
Simulation-only is the default. **`--reset-targets` authorizes clearing existing
|
|
279
|
+
data on all running scenario targets**; capture will refuse without it. Server
|
|
280
|
+
preflight checks storage and compatible deployments before reset. The launch
|
|
281
|
+
response is provisioning, not execution success or evidence readiness. Keep its
|
|
282
|
+
exact run ID/URL; inspect `run-show` for execution, artifact status, expiry, and
|
|
283
|
+
authorized download URLs. Evaluator access remains enforced by the server.
|
|
284
|
+
Control commands request a state change; inspect the run to confirm it happened.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Third-Party Notices for zerg-cyberdeck
|
|
2
|
+
|
|
3
|
+
`zerg-cyberdeck` uses the following direct runtime dependencies. They are not
|
|
4
|
+
licensed under the Zerg Source Available License 1.0 and remain governed by
|
|
5
|
+
their own terms and copyright notices.
|
|
6
|
+
|
|
7
|
+
| Component | Requested version | License | Project |
|
|
8
|
+
| --- | --- | --- | --- |
|
|
9
|
+
| Commander.js (`commander`) | `^12.1.0` | MIT | <https://github.com/tj/commander.js> |
|
|
10
|
+
| Socket.IO client (`socket.io-client`) | `^4.8.1` | MIT | <https://github.com/socketio/socket.io> |
|
|
11
|
+
|
|
12
|
+
The dependency installation may include transitive packages. Their package
|
|
13
|
+
distributions contain the authoritative notices and license texts for those
|
|
14
|
+
components. Nothing in this file changes any third-party license.
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
const CLONE_UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
2
|
+
export function normalizeCatalogForJson(catalog) {
|
|
3
|
+
return {
|
|
4
|
+
schemaVersion: 1,
|
|
5
|
+
targets: catalog.targets.map(target => ({
|
|
6
|
+
...target,
|
|
7
|
+
managedCredential: target.managedCredential ?? null,
|
|
8
|
+
})),
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export function deckSummary(deck) {
|
|
12
|
+
return {
|
|
13
|
+
id: deck.id,
|
|
14
|
+
name: deck.name,
|
|
15
|
+
slug: deck.slug,
|
|
16
|
+
status: deck.status ?? null,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export function cloneSummary(clone) {
|
|
20
|
+
return {
|
|
21
|
+
id: clone.id,
|
|
22
|
+
vendor: clone.vendor,
|
|
23
|
+
name: clone.name,
|
|
24
|
+
status: clone.status,
|
|
25
|
+
zergId: clone.zerg_id,
|
|
26
|
+
serviceUrl: clone.service_url,
|
|
27
|
+
deckRouteSlug: clone.deck_route_slug,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export function resolveCloneSelector(deck, selector) {
|
|
31
|
+
const value = selector.trim();
|
|
32
|
+
const clones = deck.clones ?? [];
|
|
33
|
+
if (!value) {
|
|
34
|
+
throw new Error('--clone must name a vendor or clone UUID.');
|
|
35
|
+
}
|
|
36
|
+
if (CLONE_UUID.test(value)) {
|
|
37
|
+
const exact = clones.find(clone => clone.id.toLowerCase() === value.toLowerCase());
|
|
38
|
+
if (exact)
|
|
39
|
+
return exact;
|
|
40
|
+
throw new Error(`Clone UUID '${value}' was not found in deck ${deck.id}.`);
|
|
41
|
+
}
|
|
42
|
+
const vendor = value.toLowerCase();
|
|
43
|
+
const matches = clones.filter(clone => clone.vendor.toLowerCase() === vendor);
|
|
44
|
+
if (matches.length === 0) {
|
|
45
|
+
throw new Error(`Clone selector '${value}' did not match a clone in deck ${deck.id}. `
|
|
46
|
+
+ `Run \`zcd ls --deck ${deck.id}\` to list clone UUIDs.`);
|
|
47
|
+
}
|
|
48
|
+
if (matches.length > 1) {
|
|
49
|
+
const ids = matches.map(clone => clone.id).join(', ');
|
|
50
|
+
throw new Error(`Clone vendor '${vendor}' is ambiguous in deck ${deck.id}. `
|
|
51
|
+
+ `Matching clone IDs: ${ids}. Pass a clone UUID.`);
|
|
52
|
+
}
|
|
53
|
+
return matches[0];
|
|
54
|
+
}
|
|
55
|
+
export function catalogTarget(catalog, vendor) {
|
|
56
|
+
return catalog.targets.find(target => target.id === vendor);
|
|
57
|
+
}
|
|
58
|
+
export function explicitlyUnsupportedCredential(target) {
|
|
59
|
+
return (target !== undefined
|
|
60
|
+
&& Object.hasOwn(target, 'managedCredential')
|
|
61
|
+
&& target.managedCredential === null);
|
|
62
|
+
}
|
|
63
|
+
const PUBLISHED_CREDENTIAL_FIELDS = new Set([
|
|
64
|
+
'connector_credential_label',
|
|
65
|
+
'connector_credential_header',
|
|
66
|
+
'connector_credential_scheme',
|
|
67
|
+
'connector_credential',
|
|
68
|
+
]);
|
|
69
|
+
export function publishedCredentialFromRuntime(vendor, runtime) {
|
|
70
|
+
const candidates = [];
|
|
71
|
+
for (const module of runtime.publishedModules ?? []) {
|
|
72
|
+
const credentialFields = module.fields.filter(field => (PUBLISHED_CREDENTIAL_FIELDS.has(field.name)));
|
|
73
|
+
if (credentialFields.length !== PUBLISHED_CREDENTIAL_FIELDS.size
|
|
74
|
+
|| new Set(credentialFields.map(field => field.name)).size
|
|
75
|
+
!== PUBLISHED_CREDENTIAL_FIELDS.size)
|
|
76
|
+
continue;
|
|
77
|
+
const fields = new Map(credentialFields.map(field => [field.name, field]));
|
|
78
|
+
const label = publishedString(fields.get('connector_credential_label'), 'text', 256);
|
|
79
|
+
const header = publishedString(fields.get('connector_credential_header'), 'text', 128);
|
|
80
|
+
const scheme = publishedScheme(fields.get('connector_credential_scheme'));
|
|
81
|
+
const token = publishedString(fields.get('connector_credential'), 'code', 2_048);
|
|
82
|
+
if (!label || !header || scheme === null || !token)
|
|
83
|
+
continue;
|
|
84
|
+
if (!/^[A-Za-z0-9-]+$/.test(header)
|
|
85
|
+
|| (scheme !== ''
|
|
86
|
+
&& !/^[A-Za-z][A-Za-z0-9._~-]*$/.test(scheme))
|
|
87
|
+
|| (scheme === '' && header.toLowerCase() === 'authorization'))
|
|
88
|
+
continue;
|
|
89
|
+
candidates.push({
|
|
90
|
+
label,
|
|
91
|
+
credential: {
|
|
92
|
+
schemaVersion: 1,
|
|
93
|
+
vendor,
|
|
94
|
+
authentication: {
|
|
95
|
+
type: 'token',
|
|
96
|
+
scheme,
|
|
97
|
+
header,
|
|
98
|
+
token,
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
return candidates.length === 1 ? candidates[0] : null;
|
|
104
|
+
}
|
|
105
|
+
function publishedScheme(field) {
|
|
106
|
+
if (!field
|
|
107
|
+
|| !field.available
|
|
108
|
+
|| field.kind !== 'text'
|
|
109
|
+
|| typeof field.value !== 'string')
|
|
110
|
+
return null;
|
|
111
|
+
const value = field.value;
|
|
112
|
+
return (value === value.trim()
|
|
113
|
+
&& value.length <= 64
|
|
114
|
+
&& !/[\u0000-\u001f\u007f]/u.test(value)) ? value : null;
|
|
115
|
+
}
|
|
116
|
+
function publishedString(field, kind, maxLength) {
|
|
117
|
+
if (!field
|
|
118
|
+
|| !field.available
|
|
119
|
+
|| field.kind !== kind
|
|
120
|
+
|| typeof field.value !== 'string')
|
|
121
|
+
return '';
|
|
122
|
+
const value = field.value;
|
|
123
|
+
return (value === value.trim()
|
|
124
|
+
&& value
|
|
125
|
+
&& value.length <= maxLength
|
|
126
|
+
&& !/[\u0000-\u001f\u007f]/u.test(value)) ? value : '';
|
|
127
|
+
}
|
|
128
|
+
function optionalRuntimeValue(value, fallback) {
|
|
129
|
+
return value === undefined ? fallback : value;
|
|
130
|
+
}
|
|
131
|
+
export function inspectClone(deck, clone, runtime, target) {
|
|
132
|
+
return {
|
|
133
|
+
schemaVersion: 1,
|
|
134
|
+
deck: deckSummary(deck),
|
|
135
|
+
clone: cloneSummary(clone),
|
|
136
|
+
managedCredential: target?.managedCredential ?? null,
|
|
137
|
+
runtime: {
|
|
138
|
+
provisioned: runtime.provisioned ?? clone.zerg_id !== null,
|
|
139
|
+
zergId: optionalRuntimeValue(runtime.zergId, clone.zerg_id),
|
|
140
|
+
status: runtime.status ?? clone.status,
|
|
141
|
+
cloneStatus: runtime.cloneStatus ?? clone.status,
|
|
142
|
+
deployPhase: runtime.deployPhase ?? null,
|
|
143
|
+
serviceUrl: optionalRuntimeValue(runtime.serviceUrl, clone.service_url),
|
|
144
|
+
socketUrl: runtime.socketUrl ?? null,
|
|
145
|
+
mirrorUrl: runtime.mirrorUrl ?? null,
|
|
146
|
+
errorMessage: runtime.errorMessage ?? null,
|
|
147
|
+
zergCloudUrl: runtime.zergCloudUrl ?? null,
|
|
148
|
+
zstackRunUrl: runtime.zstackRunUrl ?? null,
|
|
149
|
+
flyAppName: runtime.flyAppName ?? null,
|
|
150
|
+
flyAppUrl: runtime.flyAppUrl ?? null,
|
|
151
|
+
updatedAt: runtime.updatedAt ?? null,
|
|
152
|
+
},
|
|
153
|
+
publications: {
|
|
154
|
+
status: runtime.publicationStatus ?? 'none',
|
|
155
|
+
error: runtime.publicationError ?? null,
|
|
156
|
+
modules: runtime.publishedModules ?? [],
|
|
157
|
+
},
|
|
158
|
+
qualification: runtime.qualification ?? null,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=automation.js.map
|