@ai-support-agent/cli 0.3.0 → 0.3.1-beta.0
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/ansible/callback_plugins/json.py +146 -0
- package/ansible/callback_plugins/tests/test_json_callback.py +171 -0
- package/ansible/playbook.yml +52 -0
- package/ansible/roles/database/tasks/main.yml +121 -0
- package/ansible/roles/dns_tls/tasks/main.yml +75 -0
- package/ansible/roles/dns_tls/templates/Caddyfile.j2 +4 -0
- package/ansible/roles/docker/tasks/main.yml +51 -0
- package/ansible/roles/os_init/tasks/main.yml +61 -0
- package/ansible/roles/web_server/tasks/main.yml +47 -0
- package/dist/api-client.d.ts +26 -1
- package/dist/api-client.d.ts.map +1 -1
- package/dist/api-client.js +40 -0
- package/dist/api-client.js.map +1 -1
- package/dist/commands/chat-executor.js +1 -1
- package/dist/commands/chat-executor.js.map +1 -1
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +14 -0
- package/dist/commands/index.js.map +1 -1
- package/dist/constants.d.ts +3 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +7 -0
- package/dist/constants.js.map +1 -1
- package/dist/mcp/config-writer.d.ts +24 -1
- package/dist/mcp/config-writer.d.ts.map +1 -1
- package/dist/mcp/config-writer.js +27 -2
- package/dist/mcp/config-writer.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +4 -0
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools/send-slack-file.d.ts +5 -0
- package/dist/mcp/tools/send-slack-file.d.ts.map +1 -0
- package/dist/mcp/tools/send-slack-file.js +22 -0
- package/dist/mcp/tools/send-slack-file.js.map +1 -0
- package/dist/mcp/tools/update-system-knowledge.d.ts +29 -0
- package/dist/mcp/tools/update-system-knowledge.d.ts.map +1 -0
- package/dist/mcp/tools/update-system-knowledge.js +63 -0
- package/dist/mcp/tools/update-system-knowledge.js.map +1 -0
- package/dist/oneshot-runner.d.ts.map +1 -1
- package/dist/oneshot-runner.js +5 -2
- package/dist/oneshot-runner.js.map +1 -1
- package/dist/server-setup/known-hosts-store.d.ts +16 -0
- package/dist/server-setup/known-hosts-store.d.ts.map +1 -0
- package/dist/server-setup/known-hosts-store.js +89 -0
- package/dist/server-setup/known-hosts-store.js.map +1 -0
- package/dist/server-setup/server-setup-runner.d.ts +27 -0
- package/dist/server-setup/server-setup-runner.d.ts.map +1 -0
- package/dist/server-setup/server-setup-runner.js +576 -0
- package/dist/server-setup/server-setup-runner.js.map +1 -0
- package/dist/types/command.d.ts +5 -1
- package/dist/types/command.d.ts.map +1 -1
- package/dist/types/command.js.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/server-setup.d.ts +30 -0
- package/dist/types/server-setup.d.ts.map +1 -0
- package/dist/types/server-setup.js +12 -0
- package/dist/types/server-setup.js.map +1 -0
- package/dist/types/tool-output.d.ts +71 -0
- package/dist/types/tool-output.d.ts.map +1 -1
- package/docker/Dockerfile +30 -1
- package/package.json +2 -1
|
@@ -0,0 +1,576 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Runner for the `server_setup_exec` command.
|
|
4
|
+
*
|
|
5
|
+
* Fetches the target host's SSH private key Just-In-Time from the API,
|
|
6
|
+
* writes it to a process-local temp directory, runs the bundled Ansible
|
|
7
|
+
* playbook (`ansible/playbook.yml`) against it, and — critically — always
|
|
8
|
+
* removes the temp directory (private key included) afterwards, whether the
|
|
9
|
+
* run succeeded or failed. See admin-docs `docs/features/server-setup.md`
|
|
10
|
+
* ("秘密鍵の受け渡し設計") for the full design and its security rationale.
|
|
11
|
+
*
|
|
12
|
+
* SECURITY: the SSH private key must never be logged, and the temp
|
|
13
|
+
* directory holding it must never survive past this function's execution.
|
|
14
|
+
*/
|
|
15
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
18
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
19
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
20
|
+
}
|
|
21
|
+
Object.defineProperty(o, k2, desc);
|
|
22
|
+
}) : (function(o, m, k, k2) {
|
|
23
|
+
if (k2 === undefined) k2 = k;
|
|
24
|
+
o[k2] = m[k];
|
|
25
|
+
}));
|
|
26
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
27
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
28
|
+
}) : function(o, v) {
|
|
29
|
+
o["default"] = v;
|
|
30
|
+
});
|
|
31
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
32
|
+
var ownKeys = function(o) {
|
|
33
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
34
|
+
var ar = [];
|
|
35
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
36
|
+
return ar;
|
|
37
|
+
};
|
|
38
|
+
return ownKeys(o);
|
|
39
|
+
};
|
|
40
|
+
return function (mod) {
|
|
41
|
+
if (mod && mod.__esModule) return mod;
|
|
42
|
+
var result = {};
|
|
43
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
44
|
+
__setModuleDefault(result, mod);
|
|
45
|
+
return result;
|
|
46
|
+
};
|
|
47
|
+
})();
|
|
48
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
49
|
+
exports.runServerSetup = runServerSetup;
|
|
50
|
+
const child_process_1 = require("child_process");
|
|
51
|
+
const fs_1 = require("fs");
|
|
52
|
+
const os = __importStar(require("os"));
|
|
53
|
+
const path = __importStar(require("path"));
|
|
54
|
+
const logger_1 = require("../logger");
|
|
55
|
+
const types_1 = require("../types");
|
|
56
|
+
const utils_1 = require("../utils");
|
|
57
|
+
const known_hosts_store_1 = require("./known-hosts-store");
|
|
58
|
+
/** stepType values supported by the bundled Ansible roles (MVP scope). */
|
|
59
|
+
const ALLOWED_STEP_TYPES = new Set([
|
|
60
|
+
'os_init',
|
|
61
|
+
'docker',
|
|
62
|
+
'web_server',
|
|
63
|
+
'database',
|
|
64
|
+
'dns_tls',
|
|
65
|
+
]);
|
|
66
|
+
/**
|
|
67
|
+
* Allow-list of `params` keys accepted per `stepType`, matching exactly the
|
|
68
|
+
* Jinja variables each bundled role (`ansible/roles/<stepType>/tasks/main.yml`)
|
|
69
|
+
* reads. All `steps[].params` entries are merged into a single
|
|
70
|
+
* `extra-vars.json` passed as `ansible-playbook -e @extra-vars.json`.
|
|
71
|
+
* extra-vars has the *highest* variable precedence in Ansible — higher than
|
|
72
|
+
* inventory vars — so without this allow-list a caller could smuggle in an
|
|
73
|
+
* Ansible "magic variable" (e.g. `ansible_connection: "local"`,
|
|
74
|
+
* `ansible_host`, `ansible_ssh_private_key_file`) as a step param and
|
|
75
|
+
* redirect the whole `become: true` playbook run onto the agent host itself
|
|
76
|
+
* instead of the intended target (see `isReservedOrMagicParamKey` for the
|
|
77
|
+
* belt-and-suspenders check that also blocks any `ansible_`-prefixed key
|
|
78
|
+
* regardless of this table).
|
|
79
|
+
*/
|
|
80
|
+
const ALLOWED_STEP_PARAMS = {
|
|
81
|
+
os_init: new Set(),
|
|
82
|
+
docker: new Set(),
|
|
83
|
+
web_server: new Set(['web_server_type']),
|
|
84
|
+
database: new Set(['db_type', 'db_root_password']),
|
|
85
|
+
dns_tls: new Set(['domain']),
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Enum-valued `params` keys: the bundled Ansible roles branch on these with a
|
|
89
|
+
* plain string `when: x == 'y'` comparison (see `ansible/roles/database` and
|
|
90
|
+
* `ansible/roles/web_server`), so a typo'd or otherwise-unrecognized value
|
|
91
|
+
* (wrong case, extra whitespace, an unsupported db engine, ...) matches
|
|
92
|
+
* *none* of the role's `when` conditions. Every task in that role is then
|
|
93
|
+
* silently skipped, `ansible-playbook` still exits 0, and — without this
|
|
94
|
+
* check — `runServerSetup` would report the step as a `successResult` even
|
|
95
|
+
* though nothing was actually installed. Rejecting unrecognized values here,
|
|
96
|
+
* before the command ever runs, turns that silent no-op into an explicit
|
|
97
|
+
* validation error. `ansible/roles/database/tasks/main.yml` and
|
|
98
|
+
* `ansible/roles/web_server/tasks/main.yml` also `assert` these same values
|
|
99
|
+
* as a second, independent safety net in case this allow-list and the
|
|
100
|
+
* Ansible roles ever drift apart.
|
|
101
|
+
*/
|
|
102
|
+
const STEP_PARAM_ENUM_VALUES = {
|
|
103
|
+
db_type: new Set(['mysql', 'postgresql']),
|
|
104
|
+
web_server_type: new Set(['nginx', 'apache']),
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* `params` key that MUST be present for a given `stepType` (stepTypes not
|
|
108
|
+
* listed here, e.g. `os_init`/`docker`, have no required param). Without
|
|
109
|
+
* this, a step whose param *key* is entirely absent — e.g.
|
|
110
|
+
* `{ stepType: 'database', params: {} }` — passes every other check (there
|
|
111
|
+
* is no value at all to validate against `STEP_PARAM_ENUM_VALUES`) and
|
|
112
|
+
* reaches the bundled Ansible role, where every task is gated on
|
|
113
|
+
* `db_type == '...'`/`db_type is defined`
|
|
114
|
+
* (`ansible/roles/database/tasks/main.yml`), so *all* of them silently skip
|
|
115
|
+
* while `ansible-playbook` still exits 0 — `runServerSetup` would then
|
|
116
|
+
* report the step as a `successResult` despite installing nothing. Rejecting
|
|
117
|
+
* the missing key here, before the command ever runs, closes that gap the
|
|
118
|
+
* same way `STEP_PARAM_ENUM_VALUES` closes it for a recognized-but-invalid
|
|
119
|
+
* value.
|
|
120
|
+
*/
|
|
121
|
+
const REQUIRED_STEP_PARAMS = {
|
|
122
|
+
database: 'db_type',
|
|
123
|
+
web_server: 'web_server_type',
|
|
124
|
+
dns_tls: 'domain',
|
|
125
|
+
};
|
|
126
|
+
/**
|
|
127
|
+
* Ansible "magic variables" / other reserved names that must never be
|
|
128
|
+
* settable via `steps[].params`, no matter what `ALLOWED_STEP_PARAMS` says
|
|
129
|
+
* for a given stepType. This is deliberately conservative and checked
|
|
130
|
+
* independently of the per-stepType allow-list above.
|
|
131
|
+
*/
|
|
132
|
+
const RESERVED_PARAM_KEYS = new Set([
|
|
133
|
+
'hostvars',
|
|
134
|
+
'groups',
|
|
135
|
+
'group_names',
|
|
136
|
+
'environment',
|
|
137
|
+
'omit',
|
|
138
|
+
'inventory_hostname',
|
|
139
|
+
'inventory_hostname_short',
|
|
140
|
+
'inventory_dir',
|
|
141
|
+
'inventory_file',
|
|
142
|
+
'playbook_dir',
|
|
143
|
+
'play_hosts',
|
|
144
|
+
'role_name',
|
|
145
|
+
'role_names',
|
|
146
|
+
'role_path',
|
|
147
|
+
]);
|
|
148
|
+
/** True if `key` is an Ansible magic variable / connection-control name that must never be caller-controlled. */
|
|
149
|
+
function isReservedOrMagicParamKey(key) {
|
|
150
|
+
return key.startsWith('ansible_') || RESERVED_PARAM_KEYS.has(key);
|
|
151
|
+
}
|
|
152
|
+
/** Cap on buffered ansible-playbook stdout/stderr to avoid unbounded memory growth. */
|
|
153
|
+
const ANSIBLE_MAX_BUFFER_BYTES = 20 * 1024 * 1024;
|
|
154
|
+
/**
|
|
155
|
+
* Hard wall-clock cap on the whole `ansible-playbook` invocation (all
|
|
156
|
+
* requested steps together). Without this, a hung target host (unreachable
|
|
157
|
+
* SSH, an apt/dpkg lock held forever, etc.) would leave `runServerSetup`
|
|
158
|
+
* pending forever: the resident agent's `processing` flag would stay stuck
|
|
159
|
+
* and the temp directory holding the SSH private key would remain on disk
|
|
160
|
+
* indefinitely. 30 minutes comfortably covers `os_init`'s `apt dist-upgrade`
|
|
161
|
+
* (the slowest single step) plus every other role in one run.
|
|
162
|
+
*/
|
|
163
|
+
const ANSIBLE_TIMEOUT_MS = 30 * 60 * 1000;
|
|
164
|
+
function validatePayload(p) {
|
|
165
|
+
const executionId = typeof p?.executionId === 'string' && p.executionId ? p.executionId : null;
|
|
166
|
+
if (!executionId)
|
|
167
|
+
return 'executionId is required for server_setup_exec';
|
|
168
|
+
const sshHostId = typeof p?.sshHostId === 'string' && p.sshHostId ? p.sshHostId : null;
|
|
169
|
+
if (!sshHostId)
|
|
170
|
+
return 'sshHostId is required for server_setup_exec';
|
|
171
|
+
if (!Array.isArray(p?.steps) || p.steps.length === 0) {
|
|
172
|
+
return 'steps (non-empty array) is required for server_setup_exec';
|
|
173
|
+
}
|
|
174
|
+
const steps = [];
|
|
175
|
+
for (let i = 0; i < p.steps.length; i++) {
|
|
176
|
+
const raw = p.steps[i];
|
|
177
|
+
if (typeof raw !== 'object' || raw === null) {
|
|
178
|
+
return `steps[${i}] must be an object`;
|
|
179
|
+
}
|
|
180
|
+
const stepType = raw.stepType;
|
|
181
|
+
if (typeof stepType !== 'string' || !ALLOWED_STEP_TYPES.has(stepType)) {
|
|
182
|
+
return `steps[${i}].stepType must be one of: ${[...ALLOWED_STEP_TYPES].join(', ')}`;
|
|
183
|
+
}
|
|
184
|
+
const rawParams = raw.params ?? {};
|
|
185
|
+
if (typeof rawParams !== 'object' || rawParams === null || Array.isArray(rawParams)) {
|
|
186
|
+
return `steps[${i}].params must be an object`;
|
|
187
|
+
}
|
|
188
|
+
const allowedParams = ALLOWED_STEP_PARAMS[stepType];
|
|
189
|
+
const params = {};
|
|
190
|
+
for (const [key, value] of Object.entries(rawParams)) {
|
|
191
|
+
if (typeof value !== 'string') {
|
|
192
|
+
return `steps[${i}].params.${key} must be a string`;
|
|
193
|
+
}
|
|
194
|
+
// Checked before the per-stepType allow-list so that a magic-variable
|
|
195
|
+
// key is rejected with an unambiguous reason even if a future
|
|
196
|
+
// ALLOWED_STEP_PARAMS entry were mistakenly made too permissive.
|
|
197
|
+
if (isReservedOrMagicParamKey(key)) {
|
|
198
|
+
return `steps[${i}].params.${key} is not allowed (reserved Ansible variable name)`;
|
|
199
|
+
}
|
|
200
|
+
if (!allowedParams.has(key)) {
|
|
201
|
+
return `steps[${i}].params.${key} is not an allowed parameter for stepType '${stepType}'`;
|
|
202
|
+
}
|
|
203
|
+
const enumValues = STEP_PARAM_ENUM_VALUES[key];
|
|
204
|
+
if (enumValues && !enumValues.has(value)) {
|
|
205
|
+
return `steps[${i}].params.${key} must be one of: ${[...enumValues].join(', ')} (got ${JSON.stringify(value)})`;
|
|
206
|
+
}
|
|
207
|
+
params[key] = value;
|
|
208
|
+
}
|
|
209
|
+
const requiredParam = REQUIRED_STEP_PARAMS[stepType];
|
|
210
|
+
if (requiredParam && !(requiredParam in params)) {
|
|
211
|
+
return `steps[${i}].params.${requiredParam} is required for stepType '${stepType}'`;
|
|
212
|
+
}
|
|
213
|
+
steps.push({ stepType: stepType, params });
|
|
214
|
+
}
|
|
215
|
+
return { executionId, sshHostId, steps };
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Resolve the directory containing the bundled `playbook.yml` and roles.
|
|
219
|
+
* At runtime `__dirname` is `dist/server-setup` (npm-installed) or
|
|
220
|
+
* `src/server-setup` (ts-node dev); the package root is two levels up in
|
|
221
|
+
* both cases — the same depth used by `getDockerContextDir()` in
|
|
222
|
+
* `src/docker/dockerfile-path.ts`.
|
|
223
|
+
*/
|
|
224
|
+
function resolveAnsibleDir() {
|
|
225
|
+
return path.join(__dirname, '..', '..', 'ansible');
|
|
226
|
+
}
|
|
227
|
+
function resolvePlaybookPath() {
|
|
228
|
+
const playbookPath = path.join(resolveAnsibleDir(), 'playbook.yml');
|
|
229
|
+
if (!(0, fs_1.existsSync)(playbookPath)) {
|
|
230
|
+
throw new Error(`Ansible playbook not found: ${playbookPath}`);
|
|
231
|
+
}
|
|
232
|
+
return playbookPath;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Plain hostname or dotted-decimal IPv4 address: letters/digits/hyphens/dots
|
|
236
|
+
* only — no whitespace, quotes, `=`, or other characters that could be
|
|
237
|
+
* (mis)parsed as an extra inventory variable assignment.
|
|
238
|
+
*/
|
|
239
|
+
const HOSTNAME_RE = /^[A-Za-z0-9](?:[A-Za-z0-9.-]*[A-Za-z0-9])?$/;
|
|
240
|
+
/** Portable username: letters/digits/underscore/hyphen only. */
|
|
241
|
+
const USERNAME_RE = /^[A-Za-z0-9_-]+$/;
|
|
242
|
+
/**
|
|
243
|
+
* Reject a fetched SSH credential whose hostname/username/port isn't a
|
|
244
|
+
* plain, unambiguous value. Without this, a hostname or username containing
|
|
245
|
+
* e.g. a space or an embedded `ansible_connection=local` could — once
|
|
246
|
+
* written into the inventory — be parsed as *additional* inventory
|
|
247
|
+
* variables for the host, redirecting the `become: true` playbook run away
|
|
248
|
+
* from the intended target.
|
|
249
|
+
*/
|
|
250
|
+
function validateSshCredential(credential) {
|
|
251
|
+
if (!HOSTNAME_RE.test(credential.hostname)) {
|
|
252
|
+
return `SSH credential hostname is not a valid hostname/IP address: ${JSON.stringify(credential.hostname)}`;
|
|
253
|
+
}
|
|
254
|
+
if (!USERNAME_RE.test(credential.username)) {
|
|
255
|
+
return `SSH credential username contains disallowed characters: ${JSON.stringify(credential.username)}`;
|
|
256
|
+
}
|
|
257
|
+
if (!Number.isInteger(credential.port) || credential.port < 1 || credential.port > 65535) {
|
|
258
|
+
return `SSH credential port is out of range: ${JSON.stringify(credential.port)}`;
|
|
259
|
+
}
|
|
260
|
+
return null;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Build a minimal single-host Ansible inventory as JSON — written with a
|
|
264
|
+
* `.yml` extension because plain JSON is valid YAML, so ansible-core's
|
|
265
|
+
* bundled `yaml` inventory plugin (which matches by extension) parses it
|
|
266
|
+
* unambiguously. This avoids the previous hand-built INI line, where an
|
|
267
|
+
* unvalidated hostname/username containing whitespace or `key=value` text
|
|
268
|
+
* could have been parsed as extra `ansible_*` inventory variables.
|
|
269
|
+
*
|
|
270
|
+
* `StrictHostKeyChecking=accept-new` (TOFU): the host key is trusted and
|
|
271
|
+
* recorded on first connection, but a *later* run against the same
|
|
272
|
+
* `credential.hostname` with a *different* key is rejected — unlike the
|
|
273
|
+
* previous `StrictHostKeyChecking=no`, which accepted any key on every
|
|
274
|
+
* connection and made a DNS/route hijack of the target silently forward the
|
|
275
|
+
* private key and `extra-vars.json` (which may include `db_root_password`)
|
|
276
|
+
* to an attacker-controlled host.
|
|
277
|
+
*/
|
|
278
|
+
function buildInventory(credential, keyPath, knownHostsPath) {
|
|
279
|
+
const commonArgs = `-o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=${knownHostsPath}`;
|
|
280
|
+
const inventory = {
|
|
281
|
+
target: {
|
|
282
|
+
hosts: {
|
|
283
|
+
[credential.hostname]: {
|
|
284
|
+
ansible_host: credential.hostname,
|
|
285
|
+
ansible_port: credential.port,
|
|
286
|
+
ansible_user: credential.username,
|
|
287
|
+
ansible_ssh_private_key_file: keyPath,
|
|
288
|
+
ansible_ssh_common_args: commonArgs,
|
|
289
|
+
},
|
|
290
|
+
},
|
|
291
|
+
},
|
|
292
|
+
};
|
|
293
|
+
return JSON.stringify(inventory);
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Run `ansible-playbook` via execFile (never a shell) so step params
|
|
297
|
+
* (which flow into `-e @extra-vars.json`, not shell arguments) cannot be
|
|
298
|
+
* used for shell injection. Resolves rather than rejects on a non-zero exit
|
|
299
|
+
* so callers can still parse the JSON callback output that was produced
|
|
300
|
+
* before the failure. A hard `timeout` (see `ANSIBLE_TIMEOUT_MS`) guards
|
|
301
|
+
* against a hung target host or a stuck apt/dpkg lock leaving this promise
|
|
302
|
+
* (and the caller's temp dir / private key) pending forever.
|
|
303
|
+
*/
|
|
304
|
+
function runAnsiblePlaybook(args, env) {
|
|
305
|
+
return new Promise((resolve) => {
|
|
306
|
+
(0, child_process_1.execFile)('ansible-playbook', args, { env, maxBuffer: ANSIBLE_MAX_BUFFER_BYTES, timeout: ANSIBLE_TIMEOUT_MS }, (error, stdout, stderr) => {
|
|
307
|
+
const stdoutStr = stdout ? stdout.toString() : '';
|
|
308
|
+
const stderrStr = stderr ? stderr.toString() : '';
|
|
309
|
+
if (!error) {
|
|
310
|
+
resolve({ code: 0, stdout: stdoutStr, stderr: stderrStr, timedOut: false, spawnError: null });
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
const err = error;
|
|
314
|
+
// Node sets `killed: true` (with the `killSignal`, SIGTERM by
|
|
315
|
+
// default) when execFile's own `timeout` option fires.
|
|
316
|
+
const timedOut = err.killed === true;
|
|
317
|
+
const numericCode = typeof err.code === 'number' ? err.code : null;
|
|
318
|
+
// A non-numeric `code` (e.g. the string 'ENOENT'/'EACCES') combined
|
|
319
|
+
// with no captured output at all means execFile failed to spawn the
|
|
320
|
+
// process — as opposed to the process starting and exiting non-zero.
|
|
321
|
+
const spawnError = !timedOut && numericCode === null && !stdoutStr && !stderrStr ? (0, utils_1.getErrorMessage)(error) : null;
|
|
322
|
+
resolve({
|
|
323
|
+
code: numericCode ?? 1,
|
|
324
|
+
stdout: stdoutStr,
|
|
325
|
+
stderr: stderrStr,
|
|
326
|
+
timedOut,
|
|
327
|
+
spawnError,
|
|
328
|
+
});
|
|
329
|
+
});
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Parse the `ansible-playbook --stdout-callback=json`-style output into one
|
|
334
|
+
* result per requested step, plus any failure messages from task groups
|
|
335
|
+
* outside the requested steps (see `ParsedAnsibleOutput.unmatchedFailureMessages`).
|
|
336
|
+
* Task names in the bundled roles are prefixed `"<stepType> : <description>"`
|
|
337
|
+
* (see `ansible/roles/<name>/tasks/main.yml`) so task outcomes can be
|
|
338
|
+
* grouped back to the step that produced them.
|
|
339
|
+
*/
|
|
340
|
+
function parseAnsibleOutput(steps, rawOutput) {
|
|
341
|
+
let parsed = null;
|
|
342
|
+
let outputUnparseable = false;
|
|
343
|
+
if (!rawOutput || !rawOutput.trim()) {
|
|
344
|
+
outputUnparseable = true;
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
try {
|
|
348
|
+
parsed = JSON.parse(rawOutput);
|
|
349
|
+
}
|
|
350
|
+
catch {
|
|
351
|
+
parsed = null;
|
|
352
|
+
outputUnparseable = true;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
const resultsByStep = new Map();
|
|
356
|
+
for (const play of parsed?.plays ?? []) {
|
|
357
|
+
for (const task of play.tasks ?? []) {
|
|
358
|
+
const name = task.task?.name ?? '';
|
|
359
|
+
const stepType = name.split(':')[0]?.trim();
|
|
360
|
+
if (!stepType)
|
|
361
|
+
continue;
|
|
362
|
+
const hostResults = Object.values(task.hosts ?? {});
|
|
363
|
+
const existing = resultsByStep.get(stepType) ?? [];
|
|
364
|
+
resultsByStep.set(stepType, existing.concat(hostResults));
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
const requestedStepTypes = new Set(steps.map((step) => step.stepType));
|
|
368
|
+
const unmatchedFailureMessages = [];
|
|
369
|
+
for (const [groupName, results] of resultsByStep.entries()) {
|
|
370
|
+
if (requestedStepTypes.has(groupName))
|
|
371
|
+
continue;
|
|
372
|
+
for (const r of results) {
|
|
373
|
+
if (r.failed !== true)
|
|
374
|
+
continue;
|
|
375
|
+
const reason = r.msg ?? (r.unreachable === true ? 'host unreachable' : `${groupName} failed`);
|
|
376
|
+
unmatchedFailureMessages.push(`${groupName}: ${reason}`);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
const stepResults = steps.map((step) => {
|
|
380
|
+
const results = resultsByStep.get(step.stepType) ?? [];
|
|
381
|
+
const failedResult = results.find((r) => r.failed === true);
|
|
382
|
+
if (failedResult) {
|
|
383
|
+
return {
|
|
384
|
+
stepType: step.stepType,
|
|
385
|
+
status: 'failed',
|
|
386
|
+
changed: results.some((r) => r.changed === true),
|
|
387
|
+
message: failedResult.msg ?? `${step.stepType} failed`,
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
if (results.length === 0) {
|
|
391
|
+
return {
|
|
392
|
+
stepType: step.stepType,
|
|
393
|
+
status: 'skipped',
|
|
394
|
+
changed: false,
|
|
395
|
+
message: `No task output found for ${step.stepType}`,
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
if (results.every((r) => r.skipped === true)) {
|
|
399
|
+
return { stepType: step.stepType, status: 'skipped', changed: false, message: `${step.stepType} skipped` };
|
|
400
|
+
}
|
|
401
|
+
return {
|
|
402
|
+
stepType: step.stepType,
|
|
403
|
+
status: 'ok',
|
|
404
|
+
changed: results.some((r) => r.changed === true),
|
|
405
|
+
message: `${step.stepType} completed`,
|
|
406
|
+
};
|
|
407
|
+
});
|
|
408
|
+
const missingStepTypes = outputUnparseable
|
|
409
|
+
? []
|
|
410
|
+
: steps.map((step) => step.stepType).filter((stepType) => !resultsByStep.has(stepType));
|
|
411
|
+
return { stepResults, unmatchedFailureMessages, outputUnparseable, missingStepTypes };
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* Execute a `server_setup_exec` command: fetch the SSH credential, run the
|
|
415
|
+
* bundled playbook, and report per-step results. The temp directory holding
|
|
416
|
+
* the private key is always removed, on every exit path.
|
|
417
|
+
*/
|
|
418
|
+
async function runServerSetup(payload, ctx) {
|
|
419
|
+
const validated = validatePayload(payload);
|
|
420
|
+
if (typeof validated === 'string') {
|
|
421
|
+
return (0, types_1.errorResult)(validated);
|
|
422
|
+
}
|
|
423
|
+
let credential;
|
|
424
|
+
try {
|
|
425
|
+
credential = await ctx.client.getServerSetupSshCredential(ctx.commandId, ctx.agentId ?? '');
|
|
426
|
+
}
|
|
427
|
+
catch (error) {
|
|
428
|
+
return (0, types_1.errorResult)(`Failed to fetch SSH credential: ${(0, utils_1.getErrorMessage)(error)}`);
|
|
429
|
+
}
|
|
430
|
+
const credentialError = validateSshCredential(credential);
|
|
431
|
+
if (credentialError) {
|
|
432
|
+
return (0, types_1.errorResult)(credentialError);
|
|
433
|
+
}
|
|
434
|
+
let playbookPath;
|
|
435
|
+
try {
|
|
436
|
+
playbookPath = resolvePlaybookPath();
|
|
437
|
+
}
|
|
438
|
+
catch (error) {
|
|
439
|
+
return (0, types_1.errorResult)((0, utils_1.getErrorMessage)(error));
|
|
440
|
+
}
|
|
441
|
+
// Persistent (not per-run) known_hosts file, namespaced by tenant + SSH
|
|
442
|
+
// host, so `StrictHostKeyChecking=accept-new` (TOFU) actually detects a
|
|
443
|
+
// host key change across runs instead of trusting every run as a "first
|
|
444
|
+
// use" — see known-hosts-store.ts's doc comment. Resolved before the temp
|
|
445
|
+
// dir is created so a failure here (e.g. an unwritable config dir) never
|
|
446
|
+
// leaves a private-key-holding temp dir behind.
|
|
447
|
+
let knownHostsPath;
|
|
448
|
+
try {
|
|
449
|
+
knownHostsPath = (0, known_hosts_store_1.resolveKnownHostsPath)(ctx.client.getTenantCode(), validated.sshHostId);
|
|
450
|
+
}
|
|
451
|
+
catch (error) {
|
|
452
|
+
return (0, types_1.errorResult)(`Failed to resolve known_hosts file: ${(0, utils_1.getErrorMessage)(error)}`);
|
|
453
|
+
}
|
|
454
|
+
const tmpDir = (0, fs_1.mkdtempSync)(path.join(os.tmpdir(), 'ss-'));
|
|
455
|
+
// Every exit path below assigns `result` (in the `try` body or the `catch`
|
|
456
|
+
// clause), but keep a safe default so TypeScript's definite-assignment
|
|
457
|
+
// analysis (and any future refactor that adds an early path) can't leave
|
|
458
|
+
// it unset by the time `finally` reads it.
|
|
459
|
+
let result = (0, types_1.errorResult)('server_setup_exec: no result was produced');
|
|
460
|
+
try {
|
|
461
|
+
result = await (async () => {
|
|
462
|
+
const keyPath = path.join(tmpDir, 'id_rsa');
|
|
463
|
+
// 0600: only the current user may read/write the private key.
|
|
464
|
+
(0, fs_1.writeFileSync)(keyPath, credential.privateKey, { mode: 0o600 });
|
|
465
|
+
// Written with a .yml extension (JSON is valid YAML) so ansible-core's
|
|
466
|
+
// bundled `yaml` inventory plugin — matched by file extension — parses
|
|
467
|
+
// it unambiguously; see buildInventory's doc comment.
|
|
468
|
+
const inventoryPath = path.join(tmpDir, 'inventory.yml');
|
|
469
|
+
(0, fs_1.writeFileSync)(inventoryPath, buildInventory(credential, keyPath, knownHostsPath));
|
|
470
|
+
const extraVars = {};
|
|
471
|
+
for (const step of validated.steps) {
|
|
472
|
+
Object.assign(extraVars, step.params);
|
|
473
|
+
}
|
|
474
|
+
const extraVarsPath = path.join(tmpDir, 'extra-vars.json');
|
|
475
|
+
// 0600: extra-vars.json may carry db_root_password in plaintext —
|
|
476
|
+
// same permission level as the private key and known_hosts file in
|
|
477
|
+
// this directory.
|
|
478
|
+
(0, fs_1.writeFileSync)(extraVarsPath, JSON.stringify(extraVars), { mode: 0o600 });
|
|
479
|
+
const tags = validated.steps.map((s) => s.stepType).join(',');
|
|
480
|
+
const args = ['-i', inventoryPath, playbookPath, '--tags', tags, '-e', `@${extraVarsPath}`];
|
|
481
|
+
logger_1.logger.info(`[server-setup] Running ansible-playbook: executionId=${validated.executionId} tags=${tags}`);
|
|
482
|
+
const { code, stdout, stderr, timedOut, spawnError } = await runAnsiblePlaybook(args, {
|
|
483
|
+
...process.env,
|
|
484
|
+
ANSIBLE_STDOUT_CALLBACK: 'json',
|
|
485
|
+
});
|
|
486
|
+
if (timedOut) {
|
|
487
|
+
logger_1.logger.error(`[server-setup] ansible-playbook timed out after ${ANSIBLE_TIMEOUT_MS}ms: executionId=${validated.executionId}`);
|
|
488
|
+
return (0, types_1.errorResult)(`ansible-playbook execution timed out after ${Math.floor(ANSIBLE_TIMEOUT_MS / 1000)}s`);
|
|
489
|
+
}
|
|
490
|
+
if (spawnError) {
|
|
491
|
+
// The process never started (e.g. `ansible-playbook` missing from
|
|
492
|
+
// PATH or not executable) — there is no `--tags`-scoped task output
|
|
493
|
+
// to parse, so `stepResults` is deliberately omitted rather than
|
|
494
|
+
// reported as "skipped", which would misleadingly read as an
|
|
495
|
+
// intentional tag-based skip instead of an environment failure.
|
|
496
|
+
logger_1.logger.error(`[server-setup] Failed to start ansible-playbook: ${spawnError}`);
|
|
497
|
+
return (0, types_1.errorResult)(`Failed to start ansible-playbook: ${spawnError}`);
|
|
498
|
+
}
|
|
499
|
+
const { stepResults, unmatchedFailureMessages, outputUnparseable, missingStepTypes } = parseAnsibleOutput(validated.steps, stdout);
|
|
500
|
+
if (code !== 0) {
|
|
501
|
+
const detail = stderr ? stderr.substring(0, 2000) : '';
|
|
502
|
+
// Surfaces failures from task groups outside the requested steps —
|
|
503
|
+
// e.g. the `precheck` "Unsupported OS" fail or an unreachable host —
|
|
504
|
+
// which would otherwise never reach the caller: every requested
|
|
505
|
+
// step would just show up as "skipped: No task output found",
|
|
506
|
+
// silently discarding the actual reason the whole run failed.
|
|
507
|
+
const unmatchedDetail = unmatchedFailureMessages.length ? ` | ${unmatchedFailureMessages.join('; ')}` : '';
|
|
508
|
+
logger_1.logger.error(`[server-setup] ansible-playbook exited with code ${code}`);
|
|
509
|
+
return (0, types_1.errorResult)(`ansible-playbook exited with code ${code}${detail ? `: ${detail}` : ''}${unmatchedDetail}`, { stepResults });
|
|
510
|
+
}
|
|
511
|
+
// Reaching here means ansible-playbook exited 0 — but a `0` exit code
|
|
512
|
+
// alone is not sufficient evidence that the requested steps actually
|
|
513
|
+
// ran (see ParsedAnsibleOutput's `outputUnparseable`/`missingStepTypes`
|
|
514
|
+
// doc comments): a stdout callback that silently failed to load, an
|
|
515
|
+
// ansible-core output-format change, or a tag/task-name mismatch would
|
|
516
|
+
// otherwise all be reported as a quiet successResult. Both checks are
|
|
517
|
+
// deliberately evaluated regardless of the (here, always-0) exit code,
|
|
518
|
+
// so this fail-closed behavior does not silently regress if a future
|
|
519
|
+
// change moves either check earlier.
|
|
520
|
+
if (outputUnparseable) {
|
|
521
|
+
logger_1.logger.error(`[server-setup] ansible-playbook exited 0 but stdout was ${stdout.trim() ? 'not valid JSON' : 'empty'}: executionId=${validated.executionId}`);
|
|
522
|
+
return (0, types_1.errorResult)(`ansible-playbook exited 0 but its stdout ${stdout.trim() ? 'could not be parsed as JSON' : 'was empty'} — unable to confirm any requested step actually ran (json stdout callback not loaded, or an unexpected ansible-core output format)`);
|
|
523
|
+
}
|
|
524
|
+
if (missingStepTypes.length > 0) {
|
|
525
|
+
logger_1.logger.error(`[server-setup] ansible-playbook exited 0 but produced no task output for: ${missingStepTypes.join(', ')}: executionId=${validated.executionId}`);
|
|
526
|
+
return (0, types_1.errorResult)(`ansible-playbook exited 0 but produced no task output for requested step(s): ${missingStepTypes.join(', ')} — treating the run as failed rather than silently reporting success`, { stepResults });
|
|
527
|
+
}
|
|
528
|
+
logger_1.logger.success(`[server-setup] Completed: executionId=${validated.executionId}`);
|
|
529
|
+
return (0, types_1.successResult)({ stepResults });
|
|
530
|
+
})();
|
|
531
|
+
}
|
|
532
|
+
catch (error) {
|
|
533
|
+
result = (0, types_1.errorResult)(`Server setup execution failed: ${(0, utils_1.getErrorMessage)(error)}`);
|
|
534
|
+
}
|
|
535
|
+
finally {
|
|
536
|
+
// Must run on every exit path (success, failed step, thrown error): the
|
|
537
|
+
// private key must never remain on disk after this function returns.
|
|
538
|
+
// The removal itself is best-effort-logged rather than left to throw
|
|
539
|
+
// silently past the function's return: an rmSync failure here would
|
|
540
|
+
// otherwise leave the private key (and extra-vars.json's
|
|
541
|
+
// db_root_password) on disk with no signal to the caller — see
|
|
542
|
+
// `attachCleanupFailure`, which folds this into `result` below.
|
|
543
|
+
try {
|
|
544
|
+
(0, fs_1.rmSync)(tmpDir, { recursive: true, force: true });
|
|
545
|
+
}
|
|
546
|
+
catch (cleanupError) {
|
|
547
|
+
const message = (0, utils_1.getErrorMessage)(cleanupError);
|
|
548
|
+
logger_1.logger.error(`[server-setup] Failed to remove temp dir ${tmpDir}: ${message}`);
|
|
549
|
+
result = attachCleanupFailure(result, tmpDir);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
return result;
|
|
553
|
+
}
|
|
554
|
+
/**
|
|
555
|
+
* Fold a failed best-effort removal of the temp dir (SSH private key and
|
|
556
|
+
* extra-vars.json, which may contain `db_root_password`) into the command
|
|
557
|
+
* result.
|
|
558
|
+
*
|
|
559
|
+
* Design choice: rather than adding a `cleanupFailed: true` flag buried
|
|
560
|
+
* inside an otherwise-`success: true` result's `data` — which a caller that
|
|
561
|
+
* only checks the top-level `success` flag would silently miss — this
|
|
562
|
+
* deliberately turns the *whole* command result into a failure, regardless
|
|
563
|
+
* of whether the ansible-playbook run itself succeeded. Leaving secret
|
|
564
|
+
* material behind on disk is a security incident in its own right; masking
|
|
565
|
+
* that behind an otherwise-green result risks it going unnoticed and
|
|
566
|
+
* unremediated, which is a worse outcome than an ansible run that
|
|
567
|
+
* technically "succeeded" being reported as failed.
|
|
568
|
+
*/
|
|
569
|
+
function attachCleanupFailure(result, tmpDir) {
|
|
570
|
+
const note = `Failed to remove temp dir ${tmpDir} after server setup execution; it may still contain the SSH private key and db_root_password — manual cleanup of that directory is required.`;
|
|
571
|
+
if (result.success) {
|
|
572
|
+
return (0, types_1.errorResult)(note, result.data);
|
|
573
|
+
}
|
|
574
|
+
return (0, types_1.errorResult)(`${result.error} | ${note}`, result.data);
|
|
575
|
+
}
|
|
576
|
+
//# sourceMappingURL=server-setup-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-setup-runner.js","sourceRoot":"","sources":["../../src/server-setup/server-setup-runner.ts"],"names":[],"mappings":"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"}
|
package/dist/types/command.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ChatPayload } from './chat';
|
|
2
2
|
import type { EcsLaunchPayload, EcsStopPayload } from './ecs';
|
|
3
|
-
|
|
3
|
+
import type { ServerSetupExecPayload } from './server-setup';
|
|
4
|
+
export type AgentCommandType = 'execute_command' | 'file_read' | 'file_write' | 'file_list' | 'file_rename' | 'file_delete' | 'file_mkdir' | 'process_list' | 'process_kill' | 'chat' | 'chat_cancel' | 'setup' | 'config_sync' | 'reboot' | 'update' | 'e2e_test' | 'e2e_script_fix' | 'sync_repository' | 'ecs_launch' | 'ecs_stop' | 'server_setup_exec';
|
|
4
5
|
export type AgentCommandStatus = 'PENDING' | 'RUNNING' | 'COMPLETED' | 'FAILED' | 'TIMEOUT';
|
|
5
6
|
export interface AgentCommand {
|
|
6
7
|
commandId: string;
|
|
@@ -143,5 +144,8 @@ export type CommandDispatch = {
|
|
|
143
144
|
} | {
|
|
144
145
|
type: 'ecs_stop';
|
|
145
146
|
payload: EcsStopPayload;
|
|
147
|
+
} | {
|
|
148
|
+
type: 'server_setup_exec';
|
|
149
|
+
payload: ServerSetupExecPayload;
|
|
146
150
|
};
|
|
147
151
|
//# sourceMappingURL=command.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/types/command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AACzC,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/types/command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AACzC,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,OAAO,CAAA;AAC7D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAA;AAE5D,MAAM,MAAM,gBAAgB,GACxB,iBAAiB,GACjB,WAAW,GACX,YAAY,GACZ,WAAW,GACX,aAAa,GACb,aAAa,GACb,YAAY,GACZ,cAAc,GACd,cAAc,GACd,MAAM,GACN,aAAa,GACb,OAAO,GACP,aAAa,GACb,QAAQ,GACR,QAAQ,GACR,UAAU,GACV,gBAAgB,GAChB,iBAAiB,GACjB,YAAY,GACZ,UAAU,GACV,mBAAmB,CAAA;AAEvB,MAAM,MAAM,kBAAkB,GAC1B,SAAS,GACT,SAAS,GACT,WAAW,GACX,QAAQ,GACR,SAAS,CAAA;AAEb,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,gBAAgB,CAAA;IACtB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAChC,MAAM,EAAE,kBAAkB,CAAA;IAC1B,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,gBAAgB,CAAA;IACtB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAChC;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,CAAA;AAErD,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,aAAa,CAE1D;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,aAAa,CAExE;AAMD,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,GAAG,CAAC,EAAE,OAAO,CAAA;CACd;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAC5B;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,eAAe,CAAC,EAAE,OAAO,CAAA;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,kEAAkE;IAClE,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAED,MAAM,WAAW,qBAAqB;IACpC,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAGD,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,OAAO,EAAE,mBAAmB,CAAA;CAAE,GACzD;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,eAAe,CAAA;CAAE,GAC/C;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,gBAAgB,CAAA;CAAE,GACjD;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,eAAe,CAAA;CAAE,GAC/C;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE,iBAAiB,CAAA;CAAE,GACnD;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE,iBAAiB,CAAA;CAAE,GACnD;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,gBAAgB,CAAA;CAAE,GACjD;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;CAAE,GACxD;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,OAAO,EAAE,kBAAkB,CAAA;CAAE,GACrD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,WAAW,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE,iBAAiB,CAAA;CAAE,GACnD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;CAAE,GACjD;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;CAAE,GACvD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;CAAE,GAClD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;CAAE,GAClD;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,cAAc,CAAA;CAAE,GAC7C;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,OAAO,EAAE,mBAAmB,CAAA;CAAE,GACxD;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,OAAO,EAAE,qBAAqB,CAAA;CAAE,GAC3D;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,gBAAgB,CAAA;CAAE,GACjD;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,cAAc,CAAA;CAAE,GAC7C;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,OAAO,EAAE,sBAAsB,CAAA;CAAE,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command.js","sourceRoot":"","sources":["../../src/types/command.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"command.js","sourceRoot":"","sources":["../../src/types/command.ts"],"names":[],"mappings":";;AAoDA,sCAEC;AAED,kCAEC;AAND,SAAgB,aAAa,CAAC,IAAa;IACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAA;AAChC,CAAC;AAED,SAAgB,WAAW,CAAC,KAAa,EAAE,IAAc;IACvD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,IAAI,KAAK,SAAS,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,CAAA;AACvE,CAAC"}
|